onnxruntime/core/providers/cpu/controlflow/scan_8.cc
// setup the loop state variables for each batch item
setup the loop state variables for each batch item
setup the loop state variables for each batch item
Status Scan8Impl::CreateLoopStateVariables(std::vector<std::vector<LoopStateVariable>>& batch_loop_state_variables) {
  std::vector<MLValueTensorSlicer<const MLValue>::Iterator> loop_state_input_iterators;
  loop_state_input_iterators.reserve(num_loop_state_variables_);
  for (int i = 0; i < num_loop_state_variables_; ++i) {
    const MLValue& mlvalue = GetSubgraphInputMLValue(context_, i);
    MLValue* p_mlvalue = context_.GetOutputMLValue(i);
    ORT_ENFORCE(p_mlvalue, "Output MLValue has not been created for loop state variable output ", i);
    loop_state_input_iterators.push_back(MLValueTensorSlicer<const MLValue>::Create(mlvalue).begin());
  }
  batch_loop_state_variables.clear();
  batch_loop_state_variables.resize(batch_size_);
  AllocatorPtr alloc;
  auto status = context_.GetTempSpaceAllocator(&alloc);
  ORT_RETURN_IF_ERROR(status);
  for (int64_t b = 0; b < batch_size_; ++b) {
    std::vector<LoopStateVariable>& variables = batch_loop_state_variables[b];
    variables.reserve(num_loop_state_variables_);
    for (int i = 0; i < num_loop_state_variables_; ++i) {
      auto& input_iter = loop_state_input_iterators[i];
      auto& output_iter = *output_iterators_[i];
      variables.push_back(LoopStateVariable(*input_iter, *output_iter, sequence_lens_[b], alloc));
      ++input_iter;
      ++output_iter;
    }
  }
  return status;
}
Status Scan8Impl :: CreateLoopStateVariables ( std :: vector < std :: vector < LoopStateVariable > > & batch_loop_state_variables ) { std :: vector < MLValueTensorSlicer < const MLValue > :: Iterator > loop_state_input_iterators ; loop_state_input_iterators . reserve ( num_loop_state_variables_ ) ; for ( int i = 0 ; i < num_loop_state_variables_ ; ++ i ) { const MLValue & mlvalue = GetSubgraphInputMLValue ( context_ , i ) ; MLValue * p_mlvalue = context_ . GetOutputMLValue ( i ) ; ORT_ENFORCE ( p_mlvalue , " " , i ) ; loop_state_input_iterators . push_back ( MLValueTensorSlicer < const MLValue > :: Create ( mlvalue ) . begin ( ) ) ; } batch_loop_state_variables . clear ( ) ; batch_loop_state_variables . resize ( batch_size_ ) ; AllocatorPtr alloc ; auto status = context_ . GetTempSpaceAllocator ( & alloc ) ; ORT_RETURN_IF_ERROR ( status ) ; for ( int64_t b = 0 ; b < batch_size_ ; ++ b ) { std :: vector < LoopStateVariable > & variables = batch_loop_state_variables [ b ] ; variables . reserve ( num_loop_state_variables_ ) ; for ( int i = 0 ; i < num_loop_state_variables_ ; ++ i ) { auto & input_iter = loop_state_input_iterators [ i ] ; auto & output_iter = * output_iterators_ [ i ] ; variables . push_back ( LoopStateVariable ( * input_iter , * output_iter , sequence_lens_ [ b ] , alloc ) ) ; ++ input_iter ; ++ output_iter ; } } return status ; }
setup the loop state variables for each batch item
setup the loop state variables for each batch item
// Setup loop state variables // 1. Slice the input/output loop state variable tensors provided to Scan into the per-batch-item chunks //    (slice on the first dimension which is the batch size). // 2. For each batch item, create the LoopStateVariable instances that can be used to pass state between //    each iteration of the subgraph. This minimizes copying of data during each iteration. // create the input and output slice iterator for each loop state variable. // setup the loop state variables for each batch row