Skip to content

Commit dc6e76a

Browse files
committed
[draw ap] ap draw working with the rest of the draw
No more segfault when clicking. Added after solve and after legalization draw.
1 parent 5319888 commit dc6e76a

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

vpr/src/analytical_place/global_placer.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include "atom_netlist.h"
2020
#include "device_grid.h"
2121
#include "draw.h"
22+
#ifndef NO_GRAPHICS
23+
#include "draw_global.h"
24+
#endif
2225
#include "flat_placement_bins.h"
2326
#include "flat_placement_density_manager.h"
2427
#include "globals.h"
@@ -353,6 +356,10 @@ PartialPlacement SimPLGlobalPlacer::place() {
353356
PartialPlacement best_p_placement(ap_netlist_);
354357
double best_ub_hpwl = std::numeric_limits<double>::max();
355358

359+
#ifndef NO_GRAPHICS
360+
get_draw_state_vars()->set_ap_partial_placement_ref(p_placement);
361+
update_screen(ScreenUpdatePriority::MAJOR, "AP starts", ANALYTICAL_PLACEMENT, nullptr);
362+
#endif
356363
// Run the global placer.
357364
for (size_t i = 0; i < max_num_iterations_; i++) {
358365
float iter_start_time = runtime_timer.elapsed_sec();
@@ -362,12 +369,22 @@ PartialPlacement SimPLGlobalPlacer::place() {
362369
solver_->solve(i, p_placement);
363370
float solver_end_time = runtime_timer.elapsed_sec();
364371
double lb_hpwl = p_placement.get_hpwl(ap_netlist_);
372+
#ifndef NO_GRAPHICS
373+
// Per iteration analytical solve display
374+
std::string iter_msg = vtr::string_fmt("AP Iteration %zu after analytical solve", i);
375+
update_screen(ScreenUpdatePriority::MAJOR, iter_msg.c_str(), ANALYTICAL_PLACEMENT, nullptr);
376+
#endif
365377

366378
// Run the legalizer.
367379
float legalizer_start_time = runtime_timer.elapsed_sec();
368380
partial_legalizer_->legalize(p_placement);
369381
float legalizer_end_time = runtime_timer.elapsed_sec();
370382
double ub_hpwl = p_placement.get_hpwl(ap_netlist_);
383+
#ifndef NO_GRAPHICS
384+
// Per iteration legalized display
385+
iter_msg = vtr::string_fmt("AP Iteration %zu after partial legalization", i);
386+
update_screen(ScreenUpdatePriority::MAJOR, iter_msg.c_str(), ANALYTICAL_PLACEMENT, nullptr);
387+
#endif
371388

372389
// Perform a timing update
373390
float timing_update_start_time = runtime_timer.elapsed_sec();
@@ -423,6 +440,8 @@ PartialPlacement SimPLGlobalPlacer::place() {
423440

424441
if (hpwl_relative_gap < target_hpwl_relative_gap_)
425442
break;
443+
444+
426445
}
427446

428447
// Update the setup slacks. This is performed down here (as well as being
@@ -451,7 +470,13 @@ PartialPlacement SimPLGlobalPlacer::place() {
451470
*density_manager_,
452471
pre_cluster_timing_manager_);
453472

473+
474+
#ifndef NO_GRAPHICS
475+
// Final display of the last iteration's placement
476+
get_draw_state_vars()->set_ap_partial_placement_ref(p_placement);
454477
update_screen(ScreenUpdatePriority::MAJOR, "Global Placement Complete", ANALYTICAL_PLACEMENT, nullptr);
478+
get_draw_state_vars()->clear_ap_partial_placement_ref();
479+
#endif
455480
// Return the placement from the final iteration.
456481
return best_p_placement;
457482
}

vpr/src/draw/draw.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cstring>
1717
#include <cmath>
1818
#include "draw.h"
19+
#include "draw_types.h"
1920
#include "timing_info.h"
2021
#include "physical_types.h"
2122

@@ -520,7 +521,19 @@ void set_initial_world() {
520521
}
521522

522523
void set_initial_world_ap() {
523-
initial_world = ezgl::rectangle({-1, -1}, {1, 1});
524+
constexpr float VISIBLE_MARGIN = 0.01f;
525+
const DeviceContext& device_ctx = g_vpr_ctx.device();
526+
527+
const size_t grid_w = device_ctx.grid.width();
528+
const size_t grid_h = device_ctx.grid.height();
529+
530+
531+
float draw_width = static_cast<float>(grid_w);
532+
float draw_height = static_cast<float>(grid_h);
533+
534+
initial_world = ezgl::rectangle(
535+
{-VISIBLE_MARGIN * draw_width, -VISIBLE_MARGIN * draw_height},
536+
{(1.f + VISIBLE_MARGIN) * draw_width, (1.f + VISIBLE_MARGIN) * draw_height});
524537
}
525538

526539
#ifndef NO_GRAPHICS
@@ -649,6 +662,11 @@ void act_on_mouse_press(ezgl::application* app, GdkEventButton* event, double x,
649662
* fanins and fanouts are highlighted when you click on a block *
650663
* attached to them. */
651664

665+
if (get_draw_state_vars()->pic_on_screen == ANALYTICAL_PLACEMENT) {
666+
// No selection in analytical placement mode yet
667+
return;
668+
}
669+
652670
/* Control + mouse click to select multiple nets. */
653671
if (!(event->state & GDK_CONTROL_MASK))
654672
deselect_all();

vpr/src/draw/draw_basic.cpp

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212

1313
#include "physical_types_util.h"
1414
#include "vtr_assert.h"
15-
#include "vtr_ndoffsetmatrix.h"
1615
#include "vtr_color_map.h"
1716

1817
#include "vpr_utils.h"
19-
#include "vpr_error.h"
2018

2119
#include "globals.h"
2220
#include "draw_color.h"
@@ -29,6 +27,7 @@
2927
#include "move_utils.h"
3028
#include "route_export.h"
3129
#include "tatum/report/TimingPathCollector.hpp"
30+
#include "partial_placement.h"
3231

3332
//To process key presses we need the X11 keysym definitions,
3433
//which are unavailable when building with MINGW
@@ -192,12 +191,57 @@ void drawplace(ezgl::renderer* g) {
192191
}
193192

194193
void draw_analytical_place(ezgl::renderer* g) {
195-
// Fill the entire visible world with green
196-
ezgl::rectangle vw = g->get_visible_world();
194+
// Draw a tightly packed view of the device grid using only device context info.
195+
t_draw_state* draw_state = get_draw_state_vars();
196+
const DeviceContext& device_ctx = g_vpr_ctx.device();
197+
197198
g->set_line_dash(ezgl::line_dash::none);
198199
g->set_line_width(0);
199-
g->set_color(ezgl::color(0, 180, 0)); // green fill
200-
g->fill_rectangle(vw);
200+
201+
int total_layers = device_ctx.grid.get_num_layers();
202+
for (int layer = 0; layer < total_layers; ++layer) {
203+
const auto& layer_disp = draw_state->draw_layer_display[layer];
204+
if (!layer_disp.visible) continue;
205+
206+
for (int x = 0; x < (int)device_ctx.grid.width(); ++x) {
207+
for (int y = 0; y < (int)device_ctx.grid.height(); ++y) {
208+
// Only draw at the root of a non-unit tile
209+
int w_off = device_ctx.grid.get_width_offset({x, y, layer});
210+
int h_off = device_ctx.grid.get_height_offset({x, y, layer});
211+
if (w_off > 0 || h_off > 0) continue;
212+
213+
t_physical_tile_type_ptr type = device_ctx.grid.get_physical_type({x, y, layer});
214+
if (type->capacity == 0) continue;
215+
216+
ezgl::point2d bl{static_cast<double>(x), static_cast<double>(y)};
217+
ezgl::point2d tr{static_cast<double>(x + type->width), static_cast<double>(y + type->height)};
218+
219+
ezgl::color fill_color = get_block_type_color(type);
220+
g->set_color(fill_color, layer_disp.alpha);
221+
g->fill_rectangle(bl, tr);
222+
223+
if (draw_state->draw_block_outlines) {
224+
g->set_color(ezgl::BLACK, layer_disp.alpha);
225+
g->draw_rectangle(bl, tr);
226+
}
227+
}
228+
}
229+
}
230+
231+
const double half_size = 0.05;
232+
233+
const PartialPlacement* ap_pp = draw_state->get_ap_partial_placement_ref();
234+
// The reference should be set in the beginning of analytial placement.
235+
VTR_ASSERT(ap_pp != nullptr);
236+
for (const auto& [blk_id, x] : ap_pp->block_x_locs.pairs()) {
237+
double y = ap_pp->block_y_locs[blk_id];
238+
239+
ezgl::point2d bl{x - half_size, y - half_size};
240+
ezgl::point2d tr{x + half_size, y + half_size};
241+
242+
g->set_color(ezgl::BLACK);
243+
g->fill_rectangle(bl, tr);
244+
}
201245
}
202246

203247
/* This routine draws the nets on the placement. The nets have not *

vpr/src/draw/draw_types.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ struct t_draw_layer_display {
166166
int alpha = 255;
167167
};
168168

169+
struct PartialPlacement;
170+
169171
/**
170172
* @brief Structure used to store variables related to highlighting/drawing
171173
*
@@ -405,6 +407,19 @@ struct t_draw_state {
405407
* @brief Stores a reference to NoC link bandwidth utilization to be used in the graphics codes.
406408
*/
407409
std::optional<std::reference_wrapper<const vtr::vector<NocLinkId, double>>> noc_link_bandwidth_usages_ref_;
410+
411+
/**
412+
* @brief Stores a temporary reference to the Analytical Placement partial placement (best placement).
413+
* @details This is set by the AP global placer just before drawing and cleared immediately after.
414+
* Only a reference is stored to avoid copying and lifetime issues.
415+
*/
416+
std::optional<std::reference_wrapper<const PartialPlacement>> ap_partial_placement_ref_;
417+
418+
public:
419+
// Set/clear/get the AP partial placement reference used during AP drawing
420+
void set_ap_partial_placement_ref(const PartialPlacement& p) { ap_partial_placement_ref_ = std::cref(p); }
421+
void clear_ap_partial_placement_ref() { ap_partial_placement_ref_.reset(); }
422+
const PartialPlacement* get_ap_partial_placement_ref() const { return ap_partial_placement_ref_ ? &ap_partial_placement_ref_->get() : nullptr; }
408423
};
409424

410425
/* For each cluster type, this structure stores drawing

0 commit comments

Comments
 (0)