tensorflow/compiler/aot/codegen.cc
// Generate methods for results (outputs).
Generate methods for results (outputs).
Generate methods for results ( outputs ) .
Status GenResultMethods(const tf2xla::Config& config,
                        const xla::ProgramShapeProto& ps, string* methods) {
  if (ps.result().element_type() != xla::TUPLE) {
    return errors::Internal("codegen requires the XLA result to be a tuple");
  }
  size_t num_results = ps.result().tuple_shapes_size();
  int readonly_variables = absl::c_count_if(
      config.variable(),
      [](const tf2xla::Variable& var) { return var.readonly(); });
  const int actual_num_results =
      config.fetch_size() + config.variable_size() - readonly_variables;
  if (actual_num_results != num_results) {
    return errors::InvalidArgument("mismatch between fetch_size(",
                                   config.fetch_size(), ")+variable_size(",
                                   config.variable_size(), ") and tuple_size(",
                                   ps.result().tuple_shapes_size(), ")");
  }
  for (int i = 0; i < config.fetch_size(); ++i) {
    std::vector<std::pair<string, string>> rewrites;
    TF_RETURN_IF_ERROR(AddRewritesForShape(
        i, xla::Shape(ps.result().tuple_shapes(i)), &rewrites));
    string code = R"(
  {{TYPE}}* result{{NAME}}_data() {
    return static_cast<{{TYPE}}*>(result_data({{I}}));
  }
  {{TYPE}}& result{{NAME}}({{DIM_VARS}}) {
    return (*static_cast<{{TYPE}}(*){{DIM_SIZES}}>(
        result_data({{I}}))){{INDICES}};
  }
  const {{TYPE}}* result{{NAME}}_data() const {
    return static_cast<const {{TYPE}}*>(result_data({{I}}));
  }
  const {{TYPE}}& result{{NAME}}({{DIM_VARS}}) const {
    return (*static_cast<const {{TYPE}}(*){{DIM_SIZES}}>(
        result_data({{I}}))){{INDICES}};
  }
  int result{{NAME}}_size() const {
    return {{COUNT}} * sizeof({{TYPE}});
  }
  int result{{NAME}}_count() const {
    return {{COUNT}};
  }
)";
    *methods += RewriteWithName(absl::StrCat(i), code, rewrites);
    if (!config.fetch(i).name().empty()) {
      *methods += RewriteWithName("_" + config.fetch(i).name(), code, rewrites);
    }
  }
  return Status::OK();
}
Status GenResultMethods ( const tf2xla :: Config & config , const xla :: ProgramShapeProto & ps , string * methods ) { if ( ps . result ( ) . element_type ( ) != xla :: TUPLE ) { return errors :: Internal ( " " ) ; } size_t num_results = ps . result ( ) . tuple_shapes_size ( ) ; int readonly_variables = absl :: c_count_if ( config . variable ( ) , [ ] ( const tf2xla :: Variable & var ) { return var . readonly ( ) ; } ) ; const int actual_num_results = config . fetch_size ( ) + config . variable_size ( ) - readonly_variables ; if ( actual_num_results != num_results ) { return errors :: InvalidArgument ( " " , config . fetch_size ( ) , " " , config . variable_size ( ) , " " , ps . result ( ) . tuple_shapes_size ( ) , " " ) ; } for ( int i = 0 ; i < config . fetch_size ( ) ; ++ i ) { std :: vector < std :: pair < string , string > > rewrites ; TF_RETURN_IF_ERROR ( AddRewritesForShape ( i , xla :: Shape ( ps . result ( ) . tuple_shapes ( i ) ) , & rewrites ) ) ; string code = R" ( 
  {{TYPE}}* result{{NAME}}_data() {
    return static_cast<{{TYPE}}*>(result_data({{I}}));
  }
  {{TYPE}}& result{{NAME}}({{DIM_VARS}}) {
    return (*static_cast<{{TYPE}}(*){{DIM_SIZES}}>(
        result_data({{I}}))){{INDICES}};
  }
  const {{TYPE}}* result{{NAME}}_data() const {
    return static_cast<const {{TYPE}}*>(result_data({{I}}));
  }
  const {{TYPE}}& result{{NAME}}({{DIM_VARS}}) const {
    return (*static_cast<const {{TYPE}}(*){{DIM_SIZES}}>(
        result_data({{I}}))){{INDICES}};
  }
  int result{{NAME}}_size() const {
    return {{COUNT}} * sizeof({{TYPE}});
  }
  int result{{NAME}}_count() const {
    return {{COUNT}};
  }
 ) " ; * methods += RewriteWithName ( absl :: StrCat ( i ) , code , rewrites ) ; if ( ! config . fetch ( i ) . name ( ) . empty ( ) ) { * methods += RewriteWithName ( " " + config . fetch ( i ) . name ( ) , code , rewrites ) ; } } return Status :: OK ( ) ; }
Generate methods for results (outputs).
Generate methods for results ( outputs ) .
// The XlaCompiler we use to build the xla computation always generates a // tuple result, and we rely on this to simplify code generation.