| 268 | } |
| 269 | |
| 270 | void tf_parser::parse_graph(const tensorflow::GraphDef& graph) |
| 271 | { |
| 272 | nodes = get_nodes(graph, input_nodes); |
| 273 | for(auto&& input : input_nodes) |
| 274 | { |
| 275 | const std::string& name = input.name(); |
| 276 | attribute_map input_attrs = get_attributes(input); |
| 277 | shape::type_t shape_type = parse_type(input_attrs.at("dtype").type()); |
| 278 | std::vector<size_t> dims = parse_dims(input_attrs.at("shape").shape()); |
| 279 | |
| 280 | if(contains(map_input_dims, name)) |
| 281 | { |
| 282 | dims = map_input_dims.at(name); |
| 283 | } |
| 284 | else |
| 285 | { |
| 286 | if(is_nhwc and dims.size() >= 4) |
| 287 | { |
| 288 | this->reorder_data(dims); |
| 289 | } |
| 290 | std::transform(dims.begin(), dims.end(), dims.begin(), [&](auto dim) { |
| 291 | return static_cast<int>(dim) <= 0 ? batch_size : dim; |
| 292 | }); |
| 293 | } |
| 294 | |
| 295 | shape s = shape{shape_type, dims}; |
| 296 | instructions[name] = to_nhwc(mm->add_parameter(name, s)); |
| 297 | } |
| 298 | for(auto&& p : nodes) |
| 299 | { |
| 300 | this->parse_node(p.first); |
| 301 | } |
| 302 | if(mm->size() == 0) |
| 303 | return; |
| 304 | |
| 305 | // Needs to add a ret instruction at the end of |
| 306 | // the program |
| 307 | if(output_node_names.empty()) |
| 308 | { |
| 309 | output_node_names = find_outputs(); |
| 310 | } |
| 311 | |
| 312 | std::vector<instruction_ref> output_ins; |
| 313 | std::transform(output_node_names.begin(), |
| 314 | output_node_names.end(), |
| 315 | std::back_inserter(output_ins), |
| 316 | [&](const auto& output_name) { |
| 317 | if(not contains(instructions, output_name)) |
| 318 | MIGRAPHX_THROW("PARSE_TF: output name " + output_name + |
| 319 | " not found in graph!"); |
| 320 | return this->to_nchw(instructions[output_name]); |
| 321 | }); |
| 322 | mm->add_return(output_ins); |
| 323 | } |
| 324 | |
| 325 | void tf_parser::parse_node(const std::string& name) |
| 326 | { |
no test coverage detected