From 8140a55ec88e42722fcac1acac66fb1cd1a347b4 Mon Sep 17 00:00:00 2001 From: naveenvenk17 Date: Sat, 9 May 2026 14:58:25 +0530 Subject: [PATCH 1/6] Fix headless GUI heatmap dumps Signed-off-by: naveenvenk17 --- src/gui/include/gui/gui.h | 1 + src/gui/src/gui.cpp | 18 ++++++++++++++++ src/gui/test/BUILD | 1 + src/gui/test/CMakeLists.txt | 1 + src/gui/test/dump_heatmap_headless.ok | 1 + src/gui/test/dump_heatmap_headless.tcl | 30 ++++++++++++++++++++++++++ 6 files changed, 52 insertions(+) create mode 100644 src/gui/test/dump_heatmap_headless.ok create mode 100644 src/gui/test/dump_heatmap_headless.tcl diff --git a/src/gui/include/gui/gui.h b/src/gui/include/gui/gui.h index 50cacc1ed55..823a517bdee 100644 --- a/src/gui/include/gui/gui.h +++ b/src/gui/include/gui/gui.h @@ -1060,6 +1060,7 @@ class Gui private: Gui(); + void syncHeatMapChips(); void registerDescriptor(const std::type_info& type, const Descriptor* descriptor); diff --git a/src/gui/src/gui.cpp b/src/gui/src/gui.cpp index 89f49e336b2..369cd48867d 100644 --- a/src/gui/src/gui.cpp +++ b/src/gui/src/gui.cpp @@ -1016,8 +1016,26 @@ void Gui::unregisterHeatMap(HeatMapDataSource* heatmap) heat_maps_.erase(heatmap); } +void Gui::syncHeatMapChips() +{ + if (hasUI() || db_ == nullptr) { + return; + } + + // Console and headless sessions do not receive MainWindow::setBlock(). + auto* chip = db_->getChip(); + for (auto* heat_map : heat_maps_) { + if (heat_map->getChip() != chip) { + heat_map->setChip(chip); + heat_map->destroyMap(); + } + } +} + HeatMapDataSource* Gui::getHeatMap(const std::string& name) { + syncHeatMapChips(); + HeatMapDataSource* source = nullptr; for (auto* heat_map : heat_maps_) { diff --git a/src/gui/test/BUILD b/src/gui/test/BUILD index d1285f47476..f20e0e82394 100644 --- a/src/gui/test/BUILD +++ b/src/gui/test/BUILD @@ -8,6 +8,7 @@ package(features = ["layering_check"]) # From CMakeLists.txt or_integration_tests(TESTS ALL_TESTS = [ + "dump_heatmap_headless", "supported", ] diff --git a/src/gui/test/CMakeLists.txt b/src/gui/test/CMakeLists.txt index f6cfbaa34f1..e101ffc3b8d 100644 --- a/src/gui/test/CMakeLists.txt +++ b/src/gui/test/CMakeLists.txt @@ -1,6 +1,7 @@ or_integration_tests( "gui" TESTS + dump_heatmap_headless supported ) diff --git a/src/gui/test/dump_heatmap_headless.ok b/src/gui/test/dump_heatmap_headless.ok new file mode 100644 index 00000000000..656dfc57d55 --- /dev/null +++ b/src/gui/test/dump_heatmap_headless.ok @@ -0,0 +1 @@ +Pass diff --git a/src/gui/test/dump_heatmap_headless.tcl b/src/gui/test/dump_heatmap_headless.tcl new file mode 100644 index 00000000000..33cb919a2f7 --- /dev/null +++ b/src/gui/test/dump_heatmap_headless.tcl @@ -0,0 +1,30 @@ +source "helpers.tcl" + +if { ![gui::supported] } { + puts "Pass" + exit +} + +suppress_message ODB 128 +suppress_message ODB 130 +suppress_message ODB 131 +suppress_message ODB 132 +suppress_message ODB 133 +suppress_message ODB 227 + +read_lef Nangate45/Nangate45.lef +read_def gcd_nangate45.def + +set heatmap_file [make_result_file dump_heatmap_headless.csv] +gui::dump_heatmap Placement $heatmap_file + +set heatmap [open $heatmap_file r] +set contents [read $heatmap] +close $heatmap + +if { [string first "value (%)" $contents] >= 0 \ + && [regexp -line {^[0-9.-]+,[0-9.-]+,[0-9.-]+,[0-9.-]+,} $contents] } { + puts "Pass" +} else { + puts "Fail" +} From 66f1357e8d88b5674776e91702048ec816dfdef0 Mon Sep 17 00:00:00 2001 From: naveenvenk17 Date: Sat, 9 May 2026 15:10:18 +0530 Subject: [PATCH 2/6] Sync headless heatmap enumeration Signed-off-by: naveenvenk17 --- src/gui/include/gui/gui.h | 2 +- src/gui/src/gui.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/include/gui/gui.h b/src/gui/include/gui/gui.h index 823a517bdee..1848b863ad9 100644 --- a/src/gui/include/gui/gui.h +++ b/src/gui/include/gui/gui.h @@ -1023,7 +1023,7 @@ class Gui void registerHeatMap(HeatMapDataSource* heatmap); void unregisterHeatMap(HeatMapDataSource* heatmap); - const std::set& getHeatMaps() { return heat_maps_; } + const std::set& getHeatMaps(); HeatMapDataSource* getHeatMap(const std::string& name); // returns the Gui singleton diff --git a/src/gui/src/gui.cpp b/src/gui/src/gui.cpp index 369cd48867d..8fafa360cf3 100644 --- a/src/gui/src/gui.cpp +++ b/src/gui/src/gui.cpp @@ -1032,6 +1032,12 @@ void Gui::syncHeatMapChips() } } +const std::set& Gui::getHeatMaps() +{ + syncHeatMapChips(); + return heat_maps_; +} + HeatMapDataSource* Gui::getHeatMap(const std::string& name) { syncHeatMapChips(); From e35b3b01d2faba647c324a93f1fc05ff81d0f219 Mon Sep 17 00:00:00 2001 From: naveenvenk17 Date: Sat, 9 May 2026 16:48:15 +0530 Subject: [PATCH 3/6] gui: fix headless heatmap test helper path Signed-off-by: naveenvenk17 --- src/gui/test/dump_heatmap_headless.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/test/dump_heatmap_headless.tcl b/src/gui/test/dump_heatmap_headless.tcl index 33cb919a2f7..cc53303f844 100644 --- a/src/gui/test/dump_heatmap_headless.tcl +++ b/src/gui/test/dump_heatmap_headless.tcl @@ -1,4 +1,4 @@ -source "helpers.tcl" +source [file join [file dirname [info script]] .. .. .. test helpers.tcl] if { ![gui::supported] } { puts "Pass" From 9e286620dc75c90216182d85a7e3cc58ef2172d7 Mon Sep 17 00:00:00 2001 From: naveenvenk17 Date: Sat, 9 May 2026 17:26:13 +0530 Subject: [PATCH 4/6] gui: fix headless heatmap test data paths Signed-off-by: naveenvenk17 --- src/gui/test/dump_heatmap_headless.tcl | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gui/test/dump_heatmap_headless.tcl b/src/gui/test/dump_heatmap_headless.tcl index cc53303f844..133d542a70d 100644 --- a/src/gui/test/dump_heatmap_headless.tcl +++ b/src/gui/test/dump_heatmap_headless.tcl @@ -1,4 +1,7 @@ -source [file join [file dirname [info script]] .. .. .. test helpers.tcl] +set script_dir [file dirname [info script]] +set openroad_test_dir [file normalize [file join $script_dir .. .. .. test]] + +source [file join $openroad_test_dir helpers.tcl] if { ![gui::supported] } { puts "Pass" @@ -12,8 +15,8 @@ suppress_message ODB 132 suppress_message ODB 133 suppress_message ODB 227 -read_lef Nangate45/Nangate45.lef -read_def gcd_nangate45.def +read_lef [file join $openroad_test_dir Nangate45 Nangate45.lef] +read_def [file join $openroad_test_dir gcd_nangate45.def] set heatmap_file [make_result_file dump_heatmap_headless.csv] gui::dump_heatmap Placement $heatmap_file @@ -22,8 +25,10 @@ set heatmap [open $heatmap_file r] set contents [read $heatmap] close $heatmap -if { [string first "value (%)" $contents] >= 0 \ - && [regexp -line {^[0-9.-]+,[0-9.-]+,[0-9.-]+,[0-9.-]+,} $contents] } { +if { + [string first "value (%)" $contents] >= 0 + && [regexp -line {^[0-9.-]+,[0-9.-]+,[0-9.-]+,[0-9.-]+,} $contents] +} { puts "Pass" } else { puts "Fail" From 56720dbf104afa990f4f1c8e42478d8a3c3df8c9 Mon Sep 17 00:00:00 2001 From: naveenvenk17 Date: Mon, 11 May 2026 15:54:47 +0530 Subject: [PATCH 5/6] gui: strengthen headless heatmap regression Signed-off-by: naveenvenk17 --- src/gui/test/BUILD | 18 ++++++++++- src/gui/test/CMakeLists.txt | 20 ++++++++++-- src/gui/test/dump_heatmap_headless.tcl | 4 +-- src/gui/test/heatmap_sync_test.cpp | 44 ++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 src/gui/test/heatmap_sync_test.cpp diff --git a/src/gui/test/BUILD b/src/gui/test/BUILD index f20e0e82394..f5438d67ea8 100644 --- a/src/gui/test/BUILD +++ b/src/gui/test/BUILD @@ -1,3 +1,4 @@ +load("@rules_cc//cc:cc_test.bzl", "cc_test") load("@rules_python//python:defs.bzl", "py_test") # SPDX-License-Identifier: BSD-3-Clause @@ -8,10 +9,13 @@ package(features = ["layering_check"]) # From CMakeLists.txt or_integration_tests(TESTS ALL_TESTS = [ - "dump_heatmap_headless", "supported", ] +# dump_heatmap_headless requires the full Qt GUI implementation. The default +# Bazel openroad binary links the stub GUI, so the equivalent Bazel regression is +# the C++ heatmap_sync_test against //src/gui:gui_qt_headless below. + filegroup( name = "test_resources", # overly broad glob, could be refined later, but @@ -55,3 +59,15 @@ doc_check_test( ], visibility = ["//visibility:public"], ) + +cc_test( + name = "heatmap_sync_test", + srcs = ["heatmap_sync_test.cpp"], + deps = [ + "//src/gui:gui_qt_headless", + "//src/odb", + "//src/utl", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) diff --git a/src/gui/test/CMakeLists.txt b/src/gui/test/CMakeLists.txt index e101ffc3b8d..d3ab3cd635f 100644 --- a/src/gui/test/CMakeLists.txt +++ b/src/gui/test/CMakeLists.txt @@ -1,7 +1,21 @@ +set(GUI_TESTS supported) + +if (Qt5_FOUND AND BUILD_GUI) + list(APPEND GUI_TESTS dump_heatmap_headless) + + add_executable(gui_heatmap_sync_test heatmap_sync_test.cpp) + target_link_libraries(gui_heatmap_sync_test + gui + odb + utl_lib + GTest::gtest + GTest::gtest_main + ) + gtest_discover_tests(gui_heatmap_sync_test) +endif() + or_integration_tests( "gui" TESTS - dump_heatmap_headless - supported + ${GUI_TESTS} ) - diff --git a/src/gui/test/dump_heatmap_headless.tcl b/src/gui/test/dump_heatmap_headless.tcl index 133d542a70d..5b4ed73dcdb 100644 --- a/src/gui/test/dump_heatmap_headless.tcl +++ b/src/gui/test/dump_heatmap_headless.tcl @@ -4,8 +4,8 @@ set openroad_test_dir [file normalize [file join $script_dir .. .. .. test]] source [file join $openroad_test_dir helpers.tcl] if { ![gui::supported] } { - puts "Pass" - exit + puts "Fail" + exit 1 } suppress_message ODB 128 diff --git a/src/gui/test/heatmap_sync_test.cpp b/src/gui/test/heatmap_sync_test.cpp new file mode 100644 index 00000000000..6809cb26c6a --- /dev/null +++ b/src/gui/test/heatmap_sync_test.cpp @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2026, The OpenROAD Authors + +#include "gui/gui.h" + +#include "gtest/gtest.h" +#include "gui/heatMap.h" +#include "odb/db.h" +#include "utl/Logger.h" + +namespace gui { +namespace { + +TEST(GuiHeatMapTest, HeadlessLookupSyncsSourcesToCurrentChip) +{ + utl::Logger logger; + odb::dbDatabase* db = odb::dbDatabase::create(); + ASSERT_NE(db, nullptr); + + Gui* gui = Gui::get(); + gui->init(db, nullptr, &logger); + + HeatMapDataSource* placement = gui->getHeatMap("Placement"); + ASSERT_NE(placement, nullptr); + EXPECT_EQ(nullptr, placement->getChip()); + + odb::dbTech* tech = odb::dbTech::create(db, "tech"); + ASSERT_NE(tech, nullptr); + odb::dbChip* chip = odb::dbChip::create(db, tech); + ASSERT_NE(chip, nullptr); + odb::dbBlock::create(chip, "top"); + + EXPECT_EQ(chip, db->getChip()); + EXPECT_EQ(chip, gui->getHeatMap("Placement")->getChip()); + + const auto& heat_maps = gui->getHeatMaps(); + ASSERT_FALSE(heat_maps.empty()); + for (auto* heat_map : heat_maps) { + EXPECT_EQ(chip, heat_map->getChip()); + } +} + +} // namespace +} // namespace gui From ba6d2b9995f61e8725f6b0b21ca5abdfafdcd699 Mon Sep 17 00:00:00 2001 From: naveenvenk17 Date: Mon, 11 May 2026 16:07:40 +0530 Subject: [PATCH 6/6] gui: format heatmap sync test Signed-off-by: naveenvenk17 --- src/gui/test/heatmap_sync_test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/test/heatmap_sync_test.cpp b/src/gui/test/heatmap_sync_test.cpp index 6809cb26c6a..48c79af6ea1 100644 --- a/src/gui/test/heatmap_sync_test.cpp +++ b/src/gui/test/heatmap_sync_test.cpp @@ -1,9 +1,8 @@ // SPDX-License-Identifier: BSD-3-Clause // Copyright (c) 2026, The OpenROAD Authors -#include "gui/gui.h" - #include "gtest/gtest.h" +#include "gui/gui.h" #include "gui/heatMap.h" #include "odb/db.h" #include "utl/Logger.h"