tensorflow/lite/toco/graph_transformations/resolve_constant_gather.cc
// Resolves a constant Gather operation.
// This simply performs the gather and produces the output array with the
// appropriate values.
Resolves a constant Gather operation.
This simply performs the gather and produces the output array with the
appropriate values.
Resolves a constant Gather operation . This simply performs the gather and produces the output array with the appropriate values .
::tensorflow::Status ResolveConstantGather::Run(Model* model,
                                                std::size_t op_index,
                                                bool* modified) {
  *modified = false;
  auto it = model->operators.begin() + op_index;
  const auto* base_op = it->get();
  if (base_op->type != OperatorType::kGather) {
    return ::tensorflow::Status::OK();
  }
  const auto* op = static_cast<const GatherOperator*>(base_op);
  CHECK_GE(op->inputs.size(), 2);
  CHECK_EQ(op->outputs.size(), 1);
  auto& output_array = model->GetArray(op->outputs[0]);
  if (output_array.data_type == ArrayDataType::kNone) {
    return ::tensorflow::Status::OK();
  }
  if (!output_array.has_shape()) {
    return ::tensorflow::Status::OK();
  }
  if (!op->axis) {
    return ::tensorflow::Status::OK();
  }
  if (op->axis.value() != 0) {
    AddMessageF("%s has axis %d; only axis=0 is supported", LogName(*op),
                op->axis.value());
    return ::tensorflow::Status::OK();
  }
  if (!IsConstantParameterArray(*model, op->inputs[0]) ||
      !IsConstantParameterArray(*model, op->inputs[1])) {
    return ::tensorflow::Status::OK();
  }
  const Array& input_array = model->GetArray(op->inputs[0]);
  const Array& coords_array = model->GetArray(op->inputs[1]);
  CHECK(coords_array.data_type == ArrayDataType::kInt32)
      << "Only int32 indices are supported";
  if (input_array.minmax) {
    const auto& input_minmax = input_array.GetMinMax();
    auto& output_minmax = output_array.GetOrCreateMinMax();
    output_minmax.min = input_minmax.min;
    output_minmax.max = input_minmax.max;
  }
  CHECK(!output_array.buffer);
  switch (output_array.data_type) {
    case ArrayDataType::kFloat:
      Gather<ArrayDataType::kFloat>(input_array, coords_array, &output_array);
      break;
    case ArrayDataType::kUint8:
      Gather<ArrayDataType::kUint8>(input_array, coords_array, &output_array);
      break;
    case ArrayDataType::kInt32:
      Gather<ArrayDataType::kInt32>(input_array, coords_array, &output_array);
      break;
    case ArrayDataType::kInt64:
      Gather<ArrayDataType::kInt64>(input_array, coords_array, &output_array);
      break;
    case ArrayDataType::kComplex64:
      Gather<ArrayDataType::kComplex64>(input_array, coords_array,
                                        &output_array);
      break;
    default:
      LOG(FATAL) << "Unsupported data type given to Gather op with output \""
                 << op->outputs[0] << "\"";
      break;
  }
  DeleteOpAndArrays(model, op);
  *modified = true;
  return ::tensorflow::Status::OK();
}
:: tensorflow :: Status ResolveConstantGather :: Run ( Model * model , std :: size_t op_index , bool * modified ) { * modified = false ; auto it = model -> operators . begin ( ) + op_index ; const auto * base_op = it -> get ( ) ; if ( base_op -> type != OperatorType :: kGather ) { return :: tensorflow :: Status :: OK ( ) ; } const auto * op = static_cast < const GatherOperator * > ( base_op ) ; CHECK_GE ( op -> inputs . size ( ) , 2 ) ; CHECK_EQ ( op -> outputs . size ( ) , 1 ) ; auto & output_array = model -> GetArray ( op -> outputs [ 0 ] ) ; if ( output_array . data_type == ArrayDataType :: kNone ) { return :: tensorflow :: Status :: OK ( ) ; } if ( ! output_array . has_shape ( ) ) { return :: tensorflow :: Status :: OK ( ) ; } if ( ! op -> axis ) { return :: tensorflow :: Status :: OK ( ) ; } if ( op -> axis . value ( ) != 0 ) { AddMessageF ( " " , LogName ( * op ) , op -> axis . value ( ) ) ; return :: tensorflow :: Status :: OK ( ) ; } if ( ! IsConstantParameterArray ( * model , op -> inputs [ 0 ] ) || ! IsConstantParameterArray ( * model , op -> inputs [ 1 ] ) ) { return :: tensorflow :: Status :: OK ( ) ; } const Array & input_array = model -> GetArray ( op -> inputs [ 0 ] ) ; const Array & coords_array = model -> GetArray ( op -> inputs [ 1 ] ) ; CHECK ( coords_array . data_type == ArrayDataType :: kInt32 ) << " " ; if ( input_array . minmax ) { const auto & input_minmax = input_array . GetMinMax ( ) ; auto & output_minmax = output_array . GetOrCreateMinMax ( ) ; output_minmax . min = input_minmax . min ; output_minmax . max = input_minmax . max ; } CHECK ( ! output_array . buffer ) ; switch ( output_array . data_type ) { case ArrayDataType :: kFloat : Gather < ArrayDataType :: kFloat > ( input_array , coords_array , & output_array ) ; break ; case ArrayDataType :: kUint8 : Gather < ArrayDataType :: kUint8 > ( input_array , coords_array , & output_array ) ; break ; case ArrayDataType :: kInt32 : Gather < ArrayDataType :: kInt32 > ( input_array , coords_array , & output_array ) ; break ; case ArrayDataType :: kInt64 : Gather < ArrayDataType :: kInt64 > ( input_array , coords_array , & output_array ) ; break ; case ArrayDataType :: kComplex64 : Gather < ArrayDataType :: kComplex64 > ( input_array , coords_array , & output_array ) ; break ; default : LOG ( FATAL ) << " \" " << op -> outputs [ 0 ] << " \" " ; break ; } DeleteOpAndArrays ( model , op ) ; * modified = true ; return :: tensorflow :: Status :: OK ( ) ; }
Resolves a constant Gather operation.
Resolves a constant Gather operation .
// Yield until the output type has been set by PropagateArrayDataTypes. // Yield until the output shape has been set by PropagateFixedShapes. // Yield until axis has been set by ResolveGatherAttributes. // Only handling axis=0 for now. // We require constant inputs. // Copy min/max info if present. The ranges of the selected values may be // a subset of the original range but we want to ensure the quantization // params stay the same.