| 437 | } |
| 438 | |
| 439 | string HloDotDumper::Header() { |
| 440 | constexpr char fmt[] = R"(digraph G { |
| 441 | rankdir = TB; |
| 442 | compound = true; |
| 443 | label = <<b>%s</b>>; |
| 444 | labelloc = t; |
| 445 | // Disable the tooltip. Interestingly, "" doesn't work! |
| 446 | tooltip = " "; |
| 447 | // DOT graphs accept a stylesheet as a URI. So naturally, an inline |
| 448 | // stylesheet is a data URI! |
| 449 | stylesheet=< |
| 450 | data:text/css, |
| 451 | @import url(https://fonts.googleapis.com/css?family=Roboto:400,700); |
| 452 | svg text { |
| 453 | font-family: 'Roboto'; |
| 454 | font-size: 12px; |
| 455 | } |
| 456 | |
| 457 | %s |
| 458 | > |
| 459 | |
| 460 | )"; |
| 461 | |
| 462 | VLOG(3) << "Generating Header"; |
| 463 | |
| 464 | string graph_label = |
| 465 | StrCat(label_, "<br/>Computation ", computation_->name()); |
| 466 | if (computation_->IsFusionComputation()) { |
| 467 | StrAppend(&graph_label, " (in fusion instruction ", |
| 468 | computation_->FusionInstruction()->name(), ")"); |
| 469 | } |
| 470 | if (profile_ != nullptr) { |
| 471 | auto cycles = profile_->total_cycles_executed(*computation_); |
| 472 | absl::StrAppendFormat(&graph_label, "<br/>total cycles = %d (%s)", cycles, |
| 473 | tensorflow::strings::HumanReadableNum(cycles)); |
| 474 | } |
| 475 | |
| 476 | // Create CSS rules that say, when you hover over the given node or cluster, |
| 477 | // turn the given edge the given color. |
| 478 | // |
| 479 | // We rely on a few properties of how graphviz generates SVGs: |
| 480 | // |
| 481 | // - Nodes are named "nodeN", where N corresponds to the 1-based index of |
| 482 | // the node in our DOT (i.e. the first node in the DOT is "node1", etc.). |
| 483 | // Edges are similarly named "edgeN", and clusters are named "clustN". |
| 484 | // - Nodes come before their in- and out-edges in the SVG. We need this |
| 485 | // because the "X ~ Y" CSS selector finds a sibling of X that *comes |
| 486 | // after X in the DOM* and matches Y. |
| 487 | std::vector<string> edge_css_rules; |
| 488 | const char* kBlue = "#1976d2"; |
| 489 | const char* kRed = "#d32f2f"; |
| 490 | for (const auto& kv : edge_ids_) { |
| 491 | const HloInstruction* from_node = kv.first.first; |
| 492 | const HloInstruction* to_node = kv.first.second; |
| 493 | int64 edge_id = kv.second; |
| 494 | |
| 495 | auto add_hover_css_rule = [&](string elem_type, int64 elem_id, |
| 496 | const char* color) { |
nothing calls this directly
no test coverage detected