| 456 | } |
| 457 | |
| 458 | string GetStatsStringFromRunMetadata(const RunMetadata& run_metadata, |
| 459 | bool verbosity) { |
| 460 | // TODO(dyoon): print out other stats as needed. |
| 461 | std::ostringstream output; |
| 462 | |
| 463 | // Tensor size histogram: |
| 464 | // if verbosity, it outputs per-device histogram, |
| 465 | // otherwise, only per-class histogram. |
| 466 | std::unordered_map<string, TensorSizeHistogram> device_to_hist_map; |
| 467 | const auto& step_stats = run_metadata.step_stats(); |
| 468 | for (const auto& dev_stat : step_stats.dev_stats()) { |
| 469 | const auto& device_name = dev_stat.device(); |
| 470 | auto& hist = device_to_hist_map[device_name]; |
| 471 | for (const auto& node_stat : dev_stat.node_stats()) { |
| 472 | for (const auto& node_output : node_stat.output()) { |
| 473 | // TODO(dyoon): Calculate tensor size from tensor_description's dtype |
| 474 | // and shape, instead of using optional allocation_description. |
| 475 | const auto size = node_output.tensor_description() |
| 476 | .allocation_description() |
| 477 | .allocated_bytes(); |
| 478 | hist.Add(size); |
| 479 | } |
| 480 | } |
| 481 | } |
| 482 | if (verbosity) { |
| 483 | output << "\n"; |
| 484 | output << "Per device tensor size histogram.\n"; |
| 485 | } |
| 486 | |
| 487 | std::unordered_map<string, TensorSizeHistogram> device_class_to_hist_map; |
| 488 | for (const auto& device_hist : device_to_hist_map) { |
| 489 | const auto& device_name = device_hist.first; |
| 490 | const auto& hist = device_hist.second; |
| 491 | if (verbosity) { |
| 492 | output << "Device: " << device_name << "\n" << hist.ToString() << "\n"; |
| 493 | } |
| 494 | const auto device_class = GetDeviceClass(device_name); |
| 495 | auto it = device_class_to_hist_map.find(device_class); |
| 496 | if (it == device_class_to_hist_map.end()) { |
| 497 | device_class_to_hist_map.emplace(device_class, TensorSizeHistogram(hist)); |
| 498 | } else { |
| 499 | it->second.Merge(hist); |
| 500 | } |
| 501 | } |
| 502 | output << "\n"; |
| 503 | output << "Aggregated per device / channel type tensor size histogram:\n"; |
| 504 | for (const auto& device_hist : device_class_to_hist_map) { |
| 505 | const auto& device_name = device_hist.first; |
| 506 | const auto& hist = device_hist.second; |
| 507 | output << "Device: " << device_name << "\n" << hist.ToString() << "\n"; |
| 508 | } |
| 509 | output << "\n"; |
| 510 | |
| 511 | return output.str(); |
| 512 | } |
| 513 | |
| 514 | } // end namespace grappler |
| 515 | } // end namespace tensorflow |
no test coverage detected