Skip to content

Commit 00ba5c0

Browse files
authored
Merge pull request #7806 from The-OpenROAD-Project-staging/gpl-hpwl-chart
Gpl hpwl chart
2 parents ed5f64d + 5b97275 commit 00ba5c0

8 files changed

Lines changed: 193 additions & 15 deletions

File tree

src/gpl/src/graphics.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@ Graphics::Graphics(utl::Logger* logger,
5555
logger_(logger),
5656
mode_(Nesterov)
5757
{
58-
gui::Gui::get()->registerRenderer(this);
58+
gui::Gui* gui = gui::Gui::get();
59+
gui->registerRenderer(this);
60+
61+
// Setup the chart
62+
chart_ = gui->addChart("GPL");
63+
chart_->setAxisLabel("Iteration", odb::horizontal);
64+
chart_->setAxisLabel("HPWL (μm)", odb::vertical);
65+
chart_->setAxisFormat("%d", odb::horizontal);
66+
chart_->setAxisFormat("%.2e", odb::vertical);
67+
5968
initHeatmap();
6069
if (inst) {
6170
for (size_t idx = 0; idx < nbc_->getGCells().size(); ++idx) {
@@ -226,7 +235,7 @@ void Graphics::drawSingleGCell(const GCell* gCell, gui::Painter& painter)
226235
}
227236

228237
// Highlight selection (highest priority)
229-
if (gCell == nbc_->getGCellByIndex(selected_)) {
238+
if (selected_ != kInvalidIndex && gCell == nbc_->getGCellByIndex(selected_)) {
230239
color = gui::Painter::kYellow;
231240
color.a = 180;
232241
}
@@ -293,7 +302,7 @@ void Graphics::drawNesterov(gui::Painter& painter)
293302
}
294303

295304
// Draw lines to neighbors
296-
if (nbc_->getGCellByIndex(selected_)) {
305+
if (selected_ != kInvalidIndex && nbc_->getGCellByIndex(selected_)) {
297306
painter.setPen(gui::Painter::kYellow, true);
298307
for (GPin* pin : nbc_->getGCellByIndex(selected_)->gPins()) {
299308
GNet* net = pin->gNet();
@@ -385,6 +394,24 @@ void Graphics::reportSelected()
385394
}
386395
}
387396

397+
void Graphics::addIter(const int iter)
398+
{
399+
odb::dbBlock* block = pbc_->db()->getChip()->getBlock();
400+
chart_->addPoint(iter, block->dbuToMicrons(nbc_->getHpwl()));
401+
}
402+
403+
void Graphics::addTimingDrivenIter(const int iter)
404+
{
405+
chart_->addVerticalMarker(iter, gui::Painter::kTurquoise);
406+
}
407+
408+
void Graphics::addRoutabilityIter(const int iter, const bool revert)
409+
{
410+
gui::Painter::Color color
411+
= revert ? gui::Painter::kRed : gui::Painter::kGreen;
412+
chart_->addVerticalMarker(iter, color);
413+
}
414+
388415
void Graphics::cellPlot(bool pause)
389416
{
390417
gui::Gui::get()->redraw();

src/gpl/src/graphics.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ class Graphics : public gui::Renderer, public gui::HeatMapDataSource
5454
// Draw the graphics; optionally pausing afterwards
5555
void cellPlot(bool pause = false);
5656

57+
// Update the chart for the current iter
58+
void addIter(int iter);
59+
void addTimingDrivenIter(int iter);
60+
void addRoutabilityIter(int iter, bool revert);
61+
5762
// Draw the MBFF mapping
5863
void mbffMapping(const LineSegs& segs);
5964
void mbffFlopClusters(const std::vector<odb::dbInst*>& ffs);
@@ -130,6 +135,7 @@ class Graphics : public gui::Renderer, public gui::HeatMapDataSource
130135
LineSegs mbff_edges_;
131136
std::vector<odb::dbInst*> mbff_cluster_;
132137
Mode mode_;
138+
gui::Chart* chart_{nullptr};
133139

134140
void initHeatmap();
135141
void drawNesterov(gui::Painter& painter);

src/gpl/src/nesterovPlace.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ int NesterovPlace::doNesterovPlace(int start_iter)
423423

424424
const int debug_start_iter = npVars_.debug_start_iter;
425425
if (graphics_ && (debug_start_iter == 0 || iter + 1 >= debug_start_iter)) {
426+
graphics_->addIter(iter);
426427
bool update
427428
= (iter == 0 || (iter + 1) % npVars_.debug_update_iterations == 0);
428429
if (update) {
@@ -520,6 +521,10 @@ int NesterovPlace::doNesterovPlace(int start_iter)
520521
// update db's instance location from current density coordinates
521522
updateDb();
522523

524+
if (graphics_) {
525+
graphics_->addTimingDrivenIter(iter);
526+
}
527+
523528
if (graphics_ && npVars_.debug_generate_images) {
524529
graphics_->saveLabeledImage(
525530
fmt::format("{}/timing_{:05d}_0.png", timing_driven_dir, iter),
@@ -814,6 +819,10 @@ int NesterovPlace::doNesterovPlace(int start_iter)
814819
is_routability_need_ = result.first;
815820
bool isRevertInitNeeded = result.second;
816821

822+
if (graphics_) {
823+
graphics_->addRoutabilityIter(iter, isRevertInitNeeded);
824+
}
825+
817826
// if routability is needed
818827
if (is_routability_need_ || isRevertInitNeeded) {
819828
// revert back the current density penality

src/gui/include/gui/gui.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,6 @@ class Painter
158158
static inline const Color kHighlight = kYellow;
159159
static inline const Color kPersistHighlight = kYellow;
160160

161-
Painter(Options* options, const odb::Rect& bounds, double pixels_per_dbu)
162-
: options_(options), bounds_(bounds), pixels_per_dbu_(pixels_per_dbu)
163-
{
164-
}
165161
virtual ~Painter() = default;
166162

167163
// Get the current pen color
@@ -280,6 +276,12 @@ class Painter
280276
Options* getOptions() { return options_; }
281277
const odb::Rect& getBounds() { return bounds_; }
282278

279+
protected:
280+
Painter(Options* options, const odb::Rect& bounds, double pixels_per_dbu)
281+
: options_(options), bounds_(bounds), pixels_per_dbu_(pixels_per_dbu)
282+
{
283+
}
284+
283285
private:
284286
Options* options_;
285287
const odb::Rect bounds_;
@@ -564,6 +566,25 @@ class SpectrumGenerator
564566
double scale_;
565567
};
566568

569+
class Chart
570+
{
571+
public:
572+
virtual ~Chart() = default;
573+
574+
virtual void setAxisLabel(const std::string& label,
575+
odb::Orientation2D orientation)
576+
= 0;
577+
virtual void setAxisFormat(const std::string& format,
578+
odb::Orientation2D orientation)
579+
= 0;
580+
virtual void addPoint(double x, double y) = 0;
581+
582+
virtual void addVerticalMarker(double x, const Painter::Color& color) = 0;
583+
584+
protected:
585+
Chart() = default;
586+
};
587+
567588
// This is the API for the rest of the program to interact with the
568589
// GUI. This class is accessed by the GUI implementation to interact
569590
// with the rest of the system. This class itself doesn't hold the
@@ -703,6 +724,8 @@ class Gui
703724
void removeNetTracks(odb::dbNet* net);
704725
void clearNetTracks();
705726

727+
Chart* addChart(const std::string& name);
728+
706729
// show/hide widgets
707730
void showWidget(const std::string& name, bool show);
708731

src/gui/src/chartsWidget.cpp

Lines changed: 108 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <QFrame>
88
#include <QHBoxLayout>
99
#include <QString>
10+
#include <QValueAxis>
1011
#include <QWidget>
1112
#include <QtCharts>
1213
#include <algorithm>
@@ -25,11 +26,93 @@
2526

2627
namespace gui {
2728

29+
class GuiChart : public Chart
30+
{
31+
public:
32+
GuiChart(QChart* chart);
33+
34+
void setAxisLabel(const std::string& label,
35+
odb::Orientation2D orientation) override;
36+
void setAxisFormat(const std::string& format,
37+
odb::Orientation2D orientation) override;
38+
void addPoint(double x, double y) override;
39+
40+
void addVerticalMarker(double x, const Painter::Color& color) override;
41+
42+
private:
43+
QChart* chart_;
44+
QLineSeries* series_;
45+
QValueAxis* x_axis_;
46+
QValueAxis* y_axis_;
47+
double x_min_{std::numeric_limits<double>::max()};
48+
double x_max_{std::numeric_limits<double>::lowest()};
49+
double y_min_{std::numeric_limits<double>::max()};
50+
double y_max_{std::numeric_limits<double>::lowest()};
51+
};
52+
53+
GuiChart::GuiChart(QChart* chart) : chart_(chart)
54+
{
55+
series_ = new QLineSeries();
56+
chart->addSeries(series_);
57+
chart->createDefaultAxes();
58+
59+
x_axis_ = qobject_cast<QValueAxis*>(chart_->axes(Qt::Horizontal).first());
60+
y_axis_ = qobject_cast<QValueAxis*>(chart_->axes(Qt::Vertical).first());
61+
}
62+
63+
void GuiChart::setAxisLabel(const std::string& label,
64+
odb::Orientation2D orientation)
65+
{
66+
QValueAxis* axis = (orientation == odb::horizontal) ? x_axis_ : y_axis_;
67+
axis->setTitleText(QString::fromStdString(label));
68+
}
69+
70+
void GuiChart::setAxisFormat(const std::string& format,
71+
odb::Orientation2D orientation)
72+
{
73+
QValueAxis* axis = (orientation == odb::horizontal) ? x_axis_ : y_axis_;
74+
axis->setLabelFormat(QString::fromStdString(format));
75+
}
76+
77+
void GuiChart::addPoint(const double x, const double y)
78+
{
79+
series_->append(x, y);
80+
x_min_ = std::min(x_min_, x);
81+
x_max_ = std::max(x_max_, x);
82+
y_min_ = std::min(y_min_, x);
83+
y_max_ = std::max(y_max_, y);
84+
85+
// Adjust the axes to match the data range
86+
x_axis_->setMin(x_min_);
87+
x_axis_->setMax(x_max_);
88+
y_axis_->setMin(y_min_);
89+
y_axis_->setMax(y_max_);
90+
}
91+
92+
void GuiChart::addVerticalMarker(const double x, const Painter::Color& color)
93+
{
94+
QLineSeries* vline = new QLineSeries();
95+
vline->append(x, y_axis_->min());
96+
vline->append(x, y_axis_->max());
97+
98+
QColor qt_color(color.r, color.g, color.b, color.a);
99+
vline->setPen(QPen(qt_color, 2, Qt::DashLine));
100+
101+
chart_->addSeries(vline);
102+
103+
// link to same axes
104+
vline->attachAxis(x_axis_);
105+
vline->attachAxis(y_axis_);
106+
}
107+
108+
//////////////////////////////////////////////////
109+
28110
ChartsWidget::ChartsWidget(QWidget* parent)
29111
: QDockWidget("Charts", parent),
30112
logger_(nullptr),
31113
sta_(nullptr),
32114
stagui_(nullptr),
115+
chart_tabs_(new QTabWidget(this)),
33116
mode_menu_(new QComboBox(this)),
34117
filters_menu_(new QComboBox(this)),
35118
display_(new HistogramView(this)),
@@ -39,29 +122,37 @@ ChartsWidget::ChartsWidget(QWidget* parent)
39122
label_(new QLabel(this))
40123
{
41124
setObjectName("charts_widget"); // for settings
125+
chart_tabs_->setTabBarAutoHide(true);
42126

43-
QWidget* container = new QWidget(this);
44127
QHBoxLayout* controls_layout = new QHBoxLayout;
45128
controls_layout->addWidget(label_);
46129

47-
QVBoxLayout* layout = new QVBoxLayout;
48-
QFrame* controls_frame = new QFrame;
49-
50-
controls_layout->insertWidget(0, mode_menu_);
130+
controls_layout->addWidget(mode_menu_);
51131
setModeMenu();
52-
controls_layout->insertWidget(1, filters_menu_);
132+
controls_layout->addWidget(filters_menu_);
53133
filters_menu_->hide();
54134
controls_layout->addWidget(refresh_filters_button_);
55135
refresh_filters_button_->hide();
56136
controls_layout->insertStretch(2);
57137

138+
QFrame* controls_frame = new QFrame;
58139
controls_frame->setLayout(controls_layout);
59140
controls_frame->setFrameShape(QFrame::StyledPanel);
60141
controls_frame->setFrameShadow(QFrame::Raised);
61142

62-
layout->addWidget(controls_frame);
63-
layout->addWidget(display_);
143+
QVBoxLayout* slack_layout = new QVBoxLayout;
144+
slack_layout->addWidget(controls_frame);
145+
slack_layout->addWidget(display_);
146+
147+
QWidget* slack_container = new QWidget(this);
148+
slack_container->setLayout(slack_layout);
149+
150+
chart_tabs_->addTab(slack_container, "Slack");
151+
152+
QVBoxLayout* layout = new QVBoxLayout;
153+
layout->addWidget(chart_tabs_);
64154

155+
QWidget* container = new QWidget(this);
65156
container->setLayout(layout);
66157

67158
connect(refresh_filters_button_,
@@ -81,6 +172,15 @@ ChartsWidget::ChartsWidget(QWidget* parent)
81172
setWidget(container);
82173
}
83174

175+
Chart* ChartsWidget::addChart(const std::string& name)
176+
{
177+
QChart* chart = new QChart;
178+
QChartView* view = new QChartView(chart);
179+
const int tab_index = chart_tabs_->addTab(view, QString::fromStdString(name));
180+
chart_tabs_->setCurrentIndex(tab_index);
181+
return new GuiChart(chart);
182+
}
183+
84184
void ChartsWidget::changeMode()
85185
{
86186
filters_menu_->clear();

src/gui/src/chartsWidget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class ChartsWidget : public QDockWidget
137137
const std::optional<int>& height_px);
138138

139139
Mode modeFromString(const std::string& mode) const;
140+
Chart* addChart(const std::string& name);
140141

141142
signals:
142143
void endPointsToReport(const std::set<const sta::Pin*>& report_pins,
@@ -164,6 +165,8 @@ class ChartsWidget : public QDockWidget
164165
sta::dbSta* sta_;
165166
std::unique_ptr<STAGuiInterface> stagui_;
166167

168+
QTabWidget* chart_tabs_;
169+
167170
QComboBox* mode_menu_;
168171
QComboBox* filters_menu_;
169172
HistogramView* display_;

src/gui/src/gui.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,11 @@ void Gui::addRouteGuides(odb::dbNet* net)
12631263
main_window->getLayoutTabs()->addRouteGuides(net);
12641264
}
12651265

1266+
Chart* Gui::addChart(const std::string& name)
1267+
{
1268+
return main_window->getChartsWidget()->addChart(name);
1269+
}
1270+
12661271
void Gui::removeRouteGuides(odb::dbNet* net)
12671272
{
12681273
main_window->getLayoutTabs()->removeRouteGuides(net);

src/gui/src/stub.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ std::string Gui::addLabel(int x,
225225
return "";
226226
}
227227

228+
Chart* Gui::addChart(const std::string& name)
229+
{
230+
return nullptr;
231+
}
232+
228233
void Gui::saveImage(const std::string& filename,
229234
const odb::Rect& region,
230235
int width_px,

0 commit comments

Comments
 (0)