Generate methods for results (outputs).
| 207 | |
| 208 | // Generate methods for results (outputs). |
| 209 | Status GenResultMethods(const tf2xla::Config& config, |
| 210 | const xla::ProgramShapeProto& ps, string* methods) { |
| 211 | if (ps.result().element_type() != xla::TUPLE) { |
| 212 | // The XlaCompiler we use to build the xla computation always generates a |
| 213 | // tuple result, and we rely on this to simplify code generation. |
| 214 | return errors::Internal("codegen requires the XLA result to be a tuple"); |
| 215 | } |
| 216 | size_t num_results = ps.result().tuple_shapes_size(); |
| 217 | int readonly_variables = absl::c_count_if( |
| 218 | config.variable(), |
| 219 | [](const tf2xla::Variable& var) { return var.readonly(); }); |
| 220 | if (config.fetch_size() + config.variable_size() - readonly_variables != |
| 221 | num_results) { |
| 222 | return errors::InvalidArgument("mismatch between fetch_size(", |
| 223 | config.fetch_size(), ")+variable_size(", |
| 224 | config.variable_size(), ") and tuple_size(", |
| 225 | ps.result().tuple_shapes_size(), ")"); |
| 226 | } |
| 227 | for (int i = 0; i < config.fetch_size(); ++i) { |
| 228 | std::vector<std::pair<string, string>> rewrites; |
| 229 | TF_RETURN_IF_ERROR(AddRewritesForShape( |
| 230 | i, xla::Shape(ps.result().tuple_shapes(i)), &rewrites)); |
| 231 | string code = R"( |
| 232 | {{TYPE}}* result{{NAME}}_data() { |
| 233 | return static_cast<{{TYPE}}*>(result_data({{I}})); |
| 234 | } |
| 235 | {{TYPE}}& result{{NAME}}({{DIM_VARS}}) { |
| 236 | return (*static_cast<{{TYPE}}(*){{DIM_SIZES}}>( |
| 237 | result_data({{I}}))){{INDICES}}; |
| 238 | } |
| 239 | const {{TYPE}}* result{{NAME}}_data() const { |
| 240 | return static_cast<const {{TYPE}}*>(result_data({{I}})); |
| 241 | } |
| 242 | const {{TYPE}}& result{{NAME}}({{DIM_VARS}}) const { |
| 243 | return (*static_cast<const {{TYPE}}(*){{DIM_SIZES}}>( |
| 244 | result_data({{I}}))){{INDICES}}; |
| 245 | } |
| 246 | )"; |
| 247 | *methods += RewriteWithName(absl::StrCat(i), code, rewrites); |
| 248 | if (!config.fetch(i).name().empty()) { |
| 249 | *methods += RewriteWithName("_" + config.fetch(i).name(), code, rewrites); |
| 250 | } |
| 251 | } |
| 252 | return Status::OK(); |
| 253 | } |
| 254 | |
| 255 | // Generate methods for variables. |
| 256 | Status GenVariableMethods(const tf2xla::Config& config, |
no test coverage detected