| 323 | } |
| 324 | |
| 325 | void tf_parser::parse_node(const std::string& name) |
| 326 | { |
| 327 | if(instructions.count(name) == 0) |
| 328 | { |
| 329 | auto&& node = nodes.at(name); |
| 330 | if(not is_valid_op(node)) |
| 331 | return; |
| 332 | std::vector<instruction_ref> args; |
| 333 | for(auto&& input : node.input()) |
| 334 | { |
| 335 | // control dependencies (signified by ^ before the name) are ignored |
| 336 | if(contains(input, "^")) |
| 337 | continue; |
| 338 | std::string input_name = input; |
| 339 | // if input has trailing `:0` index then remove it |
| 340 | auto multi_out_idx = input.find(':'); |
| 341 | if(multi_out_idx != std::string::npos and input.substr(multi_out_idx + 1) == "0") |
| 342 | { |
| 343 | input_name = input.substr(0, multi_out_idx); |
| 344 | } |
| 345 | if(nodes.count(input_name) > 0) |
| 346 | { |
| 347 | // input was from a node with multiple outputs |
| 348 | if(contains(input_name, ':')) |
| 349 | { |
| 350 | input_name.resize(input.find(':')); |
| 351 | } |
| 352 | else |
| 353 | { |
| 354 | input_name = get_name(nodes.at(input_name)); |
| 355 | } |
| 356 | assert(name != input_name); |
| 357 | this->parse_node(input_name); |
| 358 | args.push_back(instructions.at(input_name)); |
| 359 | } |
| 360 | else |
| 361 | { |
| 362 | args.push_back(instructions.at(input_name)); |
| 363 | } |
| 364 | } |
| 365 | std::vector<instruction_ref> result; |
| 366 | if(ops.count(node.op()) == 0) |
| 367 | { |
| 368 | result.push_back(mm->add_instruction(op::unknown{node.op()}, args)); |
| 369 | } |
| 370 | else |
| 371 | { |
| 372 | result = ops[node.op()](*this, {get_attributes(node), node.op(), mm}, args); |
| 373 | } |
| 374 | assert(not result.empty()); |
| 375 | // First output has no ":" delimiter |
| 376 | instructions[name] = result.front(); |
| 377 | for(size_t i = 1; i < result.size(); i++) |
| 378 | { |
| 379 | instructions[name + ":" + std::to_string(i)] = result.at(i); |
| 380 | } |
| 381 | } |
| 382 | } |
no test coverage detected