Skip to content

Commit 0f2f19b

Browse files
committed
Use Dijkstra to generate place delay matrix.
This avoids width * height A* runs, and is likely much faster and will return better results than the previous place delay matrix algorithm for larger graphs. Signed-off-by: Keith Rothman <[email protected]>
1 parent 9b13f5d commit 0f2f19b

File tree

1 file changed

+202
-38
lines changed

1 file changed

+202
-38
lines changed

vpr/src/place/timing_place_lookup.cpp

Lines changed: 202 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ static void generic_compute_matrix(
9090
bool measure_directconnect,
9191
const std::set<std::string>& allowed_types);
9292

93+
static void generic_compute_matrix_expand(
94+
const RouterDelayProfiler& route_profiler,
95+
vtr::Matrix<std::vector<float>>& matrix,
96+
int source_x,
97+
int source_y,
98+
int start_x,
99+
int start_y,
100+
int end_x,
101+
int end_y,
102+
const t_router_opts& router_opts,
103+
bool measure_directconnect,
104+
const std::set<std::string>& allowed_types);
105+
93106
static vtr::Matrix<float> compute_delta_delays(
94107
const RouterDelayProfiler& route_profiler,
95108
const t_placer_opts& palcer_opts,
@@ -340,6 +353,151 @@ static float route_connection_delay(
340353
return (net_delay_value);
341354
}
342355

356+
static void add_delay_to_matrix(
357+
vtr::Matrix<std::vector<float>>* matrix,
358+
int delta_x,
359+
int delta_y,
360+
float delay) {
361+
if ((*matrix)[delta_x][delta_y].size() == 1 && (*matrix)[delta_x][delta_y][0] == EMPTY_DELTA) {
362+
//Overwrite empty delta
363+
(*matrix)[delta_x][delta_y][0] = delay;
364+
} else {
365+
//Collect delta
366+
(*matrix)[delta_x][delta_y].push_back(delay);
367+
}
368+
}
369+
370+
static void generic_compute_matrix_expand(
371+
const RouterDelayProfiler& route_profiler,
372+
vtr::Matrix<std::vector<float>>& matrix,
373+
int source_x,
374+
int source_y,
375+
int start_x,
376+
int start_y,
377+
int end_x,
378+
int end_y,
379+
const t_router_opts& router_opts,
380+
bool measure_directconnect,
381+
const std::set<std::string>& allowed_types) {
382+
auto& device_ctx = g_vpr_ctx.device();
383+
384+
t_physical_tile_type_ptr src_type = device_ctx.grid[source_x][source_y].type;
385+
bool is_allowed_type = allowed_types.empty() || allowed_types.find(src_type->name) != allowed_types.end();
386+
if (src_type == device_ctx.EMPTY_PHYSICAL_TILE_TYPE || !is_allowed_type) {
387+
for (int sink_x = start_x; sink_x <= end_x; sink_x++) {
388+
for (int sink_y = start_y; sink_y <= end_y; sink_y++) {
389+
int delta_x = abs(sink_x - source_x);
390+
int delta_y = abs(sink_y - source_y);
391+
392+
if (matrix[delta_x][delta_y].empty()) {
393+
//Only set empty target if we don't already have a valid delta delay
394+
matrix[delta_x][delta_y].push_back(EMPTY_DELTA);
395+
#ifdef VERBOSE
396+
VTR_LOG("Computed delay: %12s delta: %d,%d (src: %d,%d sink: %d,%d)\n",
397+
"EMPTY",
398+
delta_x, delta_y,
399+
source_x, source_y,
400+
sink_x, sink_y);
401+
#endif
402+
}
403+
}
404+
}
405+
406+
return;
407+
}
408+
409+
vtr::Matrix<bool> found_matrix({matrix.dim_size(0), matrix.dim_size(1)}, false);
410+
411+
auto best_driver_ptcs = get_best_classes(DRIVER, device_ctx.grid[source_x][source_y].type);
412+
for (int driver_ptc : best_driver_ptcs) {
413+
VTR_ASSERT(driver_ptc != OPEN);
414+
int source_rr_node = get_rr_node_index(device_ctx.rr_node_indices, source_x, source_y, SOURCE, driver_ptc);
415+
auto delays = calculate_all_path_delays_from_rr_node(source_rr_node, router_opts);
416+
417+
bool path_to_all_sinks = true;
418+
for (int sink_x = start_x; sink_x <= end_x; sink_x++) {
419+
for (int sink_y = start_y; sink_y <= end_y; sink_y++) {
420+
int delta_x = abs(sink_x - source_x);
421+
int delta_y = abs(sink_y - source_y);
422+
423+
if (found_matrix[delta_x][delta_y]) {
424+
continue;
425+
}
426+
427+
t_physical_tile_type_ptr sink_type = device_ctx.grid[sink_x][sink_y].type;
428+
if (sink_type == device_ctx.EMPTY_PHYSICAL_TILE_TYPE) {
429+
if (matrix[delta_x][delta_y].empty()) {
430+
//Only set empty target if we don't already have a valid delta delay
431+
matrix[delta_x][delta_y].push_back(EMPTY_DELTA);
432+
#ifdef VERBOSE
433+
VTR_LOG("Computed delay: %12s delta: %d,%d (src: %d,%d sink: %d,%d)\n",
434+
"EMPTY",
435+
delta_x, delta_y,
436+
source_x, source_y,
437+
sink_x, sink_y);
438+
#endif
439+
found_matrix[delta_x][delta_y] = true;
440+
}
441+
} else {
442+
bool found_a_sink = false;
443+
auto best_sink_ptcs = get_best_classes(RECEIVER, device_ctx.grid[sink_x][sink_y].type);
444+
for (int sink_ptc : best_sink_ptcs) {
445+
VTR_ASSERT(sink_ptc != OPEN);
446+
447+
int sink_rr_node = get_rr_node_index(device_ctx.rr_node_indices, sink_x, sink_y, SINK, sink_ptc);
448+
449+
VTR_ASSERT(sink_rr_node != OPEN);
450+
451+
if (!measure_directconnect && directconnect_exists(source_rr_node, sink_rr_node)) {
452+
//Skip if we shouldn't measure direct connects and a direct connect exists
453+
continue;
454+
}
455+
456+
if (std::isnan(delays[sink_rr_node])) {
457+
// This sink was not found
458+
continue;
459+
}
460+
461+
#ifdef VERBOSE
462+
VTR_LOG("Computed delay: %12g delta: %d,%d (src: %d,%d sink: %d,%d)\n",
463+
delay,
464+
delta_x, delta_y,
465+
source_x, source_y,
466+
sink_x, sink_y);
467+
#endif
468+
found_matrix[delta_x][delta_y] = true;
469+
470+
add_delay_to_matrix(&matrix, delta_x, delta_y, delays[sink_rr_node]);
471+
472+
found_a_sink = true;
473+
break;
474+
}
475+
476+
if (!found_a_sink) {
477+
path_to_all_sinks = false;
478+
}
479+
}
480+
}
481+
}
482+
483+
if (path_to_all_sinks) {
484+
break;
485+
}
486+
}
487+
488+
for (int sink_x = start_x; sink_x <= end_x; sink_x++) {
489+
for (int sink_y = start_y; sink_y <= end_y; sink_y++) {
490+
int delta_x = abs(sink_x - source_x);
491+
int delta_y = abs(sink_y - source_y);
492+
if (!found_matrix[delta_x][delta_y]) {
493+
add_delay_to_matrix(&matrix, delta_x, delta_y, IMPOSSIBLE_DELTA);
494+
VTR_LOG_WARN("Unable to route between blocks at (%d,%d) and (%d,%d) to characterize delay (setting to %g)\n",
495+
source_x, source_y, sink_x, sink_y, IMPOSSIBLE_DELTA);
496+
}
497+
}
498+
}
499+
}
500+
343501
static void generic_compute_matrix(
344502
const RouterDelayProfiler& route_profiler,
345503
vtr::Matrix<std::vector<float>>& matrix,
@@ -426,8 +584,14 @@ static vtr::Matrix<float> compute_delta_delays(
426584

427585
size_t low_x = std::min(longest_length, mid_x);
428586
size_t low_y = std::min(longest_length, mid_y);
429-
size_t high_x = std::max(grid.width() - longest_length, mid_x);
430-
size_t high_y = std::max(grid.height() - longest_length, mid_y);
587+
size_t high_x = mid_x;
588+
size_t high_y = mid_y;
589+
if (longest_length <= grid.width()) {
590+
high_x = std::max(grid.width() - longest_length, mid_x);
591+
}
592+
if (longest_length <= grid.height()) {
593+
high_y = std::max(grid.height() - longest_length, mid_y);
594+
}
431595

432596
std::set<std::string> allowed_types;
433597
if (!placer_opts.allowed_tiles_for_delay_model.empty()) {
@@ -488,12 +652,12 @@ static vtr::Matrix<float> compute_delta_delays(
488652
#ifdef VERBOSE
489653
VTR_LOG("Computing from lower left edge (%d,%d):\n", x, y);
490654
#endif
491-
generic_compute_matrix(route_profiler, sampled_delta_delays,
492-
x, y,
493-
x, y,
494-
grid.width() - 1, grid.height() - 1,
495-
router_opts,
496-
measure_directconnect, allowed_types);
655+
generic_compute_matrix_expand(route_profiler, sampled_delta_delays,
656+
x, y,
657+
x, y,
658+
grid.width() - 1, grid.height() - 1,
659+
router_opts,
660+
measure_directconnect, allowed_types);
497661

498662
//Find the lowest x location on the bottom edge with a non-empty block
499663
src_type = nullptr;
@@ -517,60 +681,60 @@ static vtr::Matrix<float> compute_delta_delays(
517681
#ifdef VERBOSE
518682
VTR_LOG("Computing from left bottom edge (%d,%d):\n", x, y);
519683
#endif
520-
generic_compute_matrix(route_profiler, sampled_delta_delays,
521-
x, y,
522-
x, y,
523-
grid.width() - 1, grid.height() - 1,
524-
router_opts,
525-
measure_directconnect, allowed_types);
684+
generic_compute_matrix_expand(route_profiler, sampled_delta_delays,
685+
x, y,
686+
x, y,
687+
grid.width() - 1, grid.height() - 1,
688+
router_opts,
689+
measure_directconnect, allowed_types);
526690

527691
//Since the other delta delay values may have suffered from edge effects,
528692
//we recalculate deltas within regions B, C, E, F
529693
#ifdef VERBOSE
530694
VTR_LOG("Computing from low/low:\n");
531695
#endif
532-
generic_compute_matrix(route_profiler, sampled_delta_delays,
533-
low_x, low_y,
534-
low_x, low_y,
535-
grid.width() - 1, grid.height() - 1,
536-
router_opts,
537-
measure_directconnect, allowed_types);
696+
generic_compute_matrix_expand(route_profiler, sampled_delta_delays,
697+
low_x, low_y,
698+
low_x, low_y,
699+
grid.width() - 1, grid.height() - 1,
700+
router_opts,
701+
measure_directconnect, allowed_types);
538702

539703
//Since the other delta delay values may have suffered from edge effects,
540704
//we recalculate deltas within regions D, E, G, H
541705
#ifdef VERBOSE
542706
VTR_LOG("Computing from high/high:\n");
543707
#endif
544-
generic_compute_matrix(route_profiler, sampled_delta_delays,
545-
high_x, high_y,
546-
0, 0,
547-
high_x, high_y,
548-
router_opts,
549-
measure_directconnect, allowed_types);
708+
generic_compute_matrix_expand(route_profiler, sampled_delta_delays,
709+
high_x, high_y,
710+
0, 0,
711+
high_x, high_y,
712+
router_opts,
713+
measure_directconnect, allowed_types);
550714

551715
//Since the other delta delay values may have suffered from edge effects,
552716
//we recalculate deltas within regions A, B, D, E
553717
#ifdef VERBOSE
554718
VTR_LOG("Computing from high/low:\n");
555719
#endif
556-
generic_compute_matrix(route_profiler, sampled_delta_delays,
557-
high_x, low_y,
558-
0, low_y,
559-
high_x, grid.height() - 1,
560-
router_opts,
561-
measure_directconnect, allowed_types);
720+
generic_compute_matrix_expand(route_profiler, sampled_delta_delays,
721+
high_x, low_y,
722+
0, low_y,
723+
high_x, grid.height() - 1,
724+
router_opts,
725+
measure_directconnect, allowed_types);
562726

563727
//Since the other delta delay values may have suffered from edge effects,
564728
//we recalculate deltas within regions E, F, H, I
565729
#ifdef VERBOSE
566730
VTR_LOG("Computing from low/high:\n");
567731
#endif
568-
generic_compute_matrix(route_profiler, sampled_delta_delays,
569-
low_x, high_y,
570-
low_x, 0,
571-
grid.width() - 1, high_y,
572-
router_opts,
573-
measure_directconnect, allowed_types);
732+
generic_compute_matrix_expand(route_profiler, sampled_delta_delays,
733+
low_x, high_y,
734+
low_x, 0,
735+
grid.width() - 1, high_y,
736+
router_opts,
737+
measure_directconnect, allowed_types);
574738

575739
vtr::Matrix<float> delta_delays({grid.width(), grid.height()});
576740
for (size_t dx = 0; dx < sampled_delta_delays.dim_size(0); ++dx) {

0 commit comments

Comments
 (0)