Skip to content

Commit dab0030

Browse files
committed
change name to NestedNetlistRouter
1 parent 70e434b commit dab0030

File tree

7 files changed

+69
-37
lines changed

7 files changed

+69
-37
lines changed

libs/libvtrutil/src/vtr_thread_pool.h

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,42 @@
1919

2020
namespace vtr {
2121

22+
/**
23+
* A thread pool for parallel task execution. It is a naive
24+
* implementation which uses a queue for each thread and assigns
25+
* tasks in a round robin fashion.
26+
*
27+
* Example usage:
28+
*
29+
* vtr::thread_pool pool(4);
30+
* pool.schedule_work([]{
31+
* // Task body
32+
* });
33+
* pool.wait_for_all(); // There's no API to wait for a single task
34+
*/
2235
class thread_pool {
2336
private:
37+
/* Thread-local data */
2438
struct ThreadData {
2539
std::thread thread;
40+
/* Per-thread task queue */
2641
std::queue<std::function<void()>> task_queue;
42+
43+
/* Threads wait on cv for a stop signal or a new task
44+
* queue_mutex is required for condition variable */
2745
std::mutex queue_mutex;
2846
std::condition_variable cv;
2947
bool stop = false;
30-
size_t thread_id;
31-
32-
ThreadData(size_t id) : thread_id(id) {}
3348
};
3449

50+
/* Container for thread-local data */
3551
std::vector<std::unique_ptr<ThreadData>> threads;
52+
/* Used for round-robin scheduling */
3653
std::atomic<size_t> next_thread{0};
37-
std::atomic<size_t> total_tasks_queued{0};
54+
/* Used for wait_for_all */
3855
std::atomic<size_t> active_tasks{0};
3956

40-
/* Condition variable for wait_for_all*/
57+
/* Condition variable for wait_for_all */
4158
std::mutex completion_mutex;
4259
std::condition_variable completion_cv;
4360

@@ -46,14 +63,15 @@ class thread_pool {
4663
threads.reserve(thread_count);
4764

4865
for (size_t i = 0; i < thread_count; i++) {
49-
auto thread_data = std::make_unique<ThreadData>(i);
66+
auto thread_data = std::make_unique<ThreadData>();
5067

5168
thread_data->thread = std::thread([&]() {
5269
ThreadData* td = thread_data.get();
5370

5471
while (true) {
5572
std::function<void()> task;
56-
{
73+
74+
{ /* Wait until a task is available or stop signal is received */
5775
std::unique_lock<std::mutex> lock(td->queue_mutex);
5876

5977
td->cv.wait(lock, [td]() {
@@ -64,6 +82,7 @@ class thread_pool {
6482
return;
6583
}
6684

85+
/* Fetch a task from the queue */
6786
task = std::move(td->task_queue.front());
6887
td->task_queue.pop();
6988
}
@@ -84,20 +103,19 @@ class thread_pool {
84103
/* Round-robin thread assignment */
85104
size_t thread_idx = (next_thread++) % threads.size();
86105
auto thread_data = threads[thread_idx].get();
87-
size_t task_id = ++total_tasks_queued;
88106

89-
auto task = [this, f = std::forward<F>(f), thread_id = thread_data->thread_id, task_id]() {
107+
auto task = [this, f = std::forward<F>(f)]() {
90108
vtr::Timer task_timer;
91109

92110
try {
93111
f();
94112
} catch (const std::exception& e) {
95-
VTR_LOG_ERROR("Thread %zu failed task %zu with error: %s\n",
96-
thread_id, task_id, e.what());
113+
VTR_LOG_ERROR("Thread %zu failed task with error: %s\n",
114+
std::this_thread::get_id(), e.what());
97115
throw;
98116
} catch (...) {
99-
VTR_LOG_ERROR("Thread %zu failed task %zu with unknown error\n",
100-
thread_id, task_id);
117+
VTR_LOG_ERROR("Thread %zu failed task with unknown error\n",
118+
std::this_thread::get_id());
101119
throw;
102120
}
103121

vpr/src/base/ShowSetup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ static void ShowRouterOpts(const t_router_opts& RouterOpts) {
254254

255255
VTR_LOG("RouterOpts.router_algorithm: ");
256256
switch (RouterOpts.router_algorithm) {
257-
case MIXED:
258-
VTR_LOG("MIXED\n");
257+
case NESTED:
258+
VTR_LOG("NESTED\n");
259259
break;
260260
case PARALLEL:
261261
VTR_LOG("PARALLEL\n");

vpr/src/base/read_options.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ struct ParseRoutePredictor {
171171
struct ParseRouterAlgorithm {
172172
ConvertedValue<e_router_algorithm> from_str(const std::string& str) {
173173
ConvertedValue<e_router_algorithm> conv_value;
174-
if (str == "mixed")
175-
conv_value.set_value(MIXED);
174+
if (str == "nested")
175+
conv_value.set_value(NESTED);
176176
else if (str == "parallel")
177177
conv_value.set_value(PARALLEL);
178178
else if (str == "parallel_decomp")
@@ -189,8 +189,8 @@ struct ParseRouterAlgorithm {
189189

190190
ConvertedValue<std::string> to_str(e_router_algorithm val) {
191191
ConvertedValue<std::string> conv_value;
192-
if (val == MIXED)
193-
conv_value.set_value("mixed");
192+
if (val == NESTED)
193+
conv_value.set_value("nested");
194194
else if (val == PARALLEL)
195195
conv_value.set_value("parallel");
196196
else if (val == PARALLEL_DECOMP)
@@ -2409,9 +2409,10 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
24092409
"Specifies the router algorithm to use.\n"
24102410
" * timing driven: focuses on routability and circuit speed [default]\n"
24112411
" * parallel: timing_driven with nets in different regions of the chip routed in parallel\n"
2412-
" * parallel_decomp: timing_driven with additional parallelism obtained by decomposing high-fanout nets, possibly reducing quality\n")
2412+
" * parallel_decomp: timing_driven with additional parallelism obtained by decomposing high-fanout nets, possibly reducing quality\n"
2413+
" * nested: parallel with parallelized path search\n")
24132414
.default_value("timing_driven")
2414-
.choices({"mixed","parallel", "parallel_decomp", "timing_driven"})
2415+
.choices({"nested","parallel", "parallel_decomp", "timing_driven"})
24152416
.show_in(argparse::ShowIn::HELP_ONLY);
24162417

24172418
route_grp.add_argument(args.min_incremental_reroute_fanout, "--min_incremental_reroute_fanout")

vpr/src/base/vpr_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,7 @@ struct t_ap_opts {
11861186
* read_rr_graph_name: stores the file name of the rr graph to be read by vpr */
11871187

11881188
enum e_router_algorithm {
1189-
MIXED,
1189+
NESTED,
11901190
PARALLEL,
11911191
PARALLEL_DECOMP,
11921192
TIMING_DRIVEN,

vpr/src/route/MixedNetlistRouter.h renamed to vpr/src/route/NestedNetlistRouter.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
/** @file Mixed case for NetlistRouter */
3+
/** @file Nested parallel case for NetlistRouter */
44
#include "netlist_routers.h"
55
#include "vtr_optional.h"
66
#include "vtr_thread_pool.h"
@@ -9,15 +9,21 @@
99
/* Add cmd line option for this later */
1010
constexpr int MAX_THREADS = 4;
1111

12-
/** Mixed impl for NetlistRouter.
12+
/** Nested parallel impl for NetlistRouter.
13+
*
14+
* Calls a parallel ConnectionRouter for route_net to extract even more parallelism.
15+
* The main reason why this is a different router instead of templating NetlistRouter
16+
* on ConnectionRouter is this router does not use TBB. The scheduling performance is
17+
* worse, but it can wait in individual tasks now (which is not possible with TBB).
18+
*
1319
* Holds enough context members to glue together ConnectionRouter and net routing functions,
1420
* such as \ref route_net. Keeps the members in thread-local storage where needed,
1521
* i.e. ConnectionRouters and RouteIterResults-es.
1622
* See \ref route_net. */
1723
template<typename HeapType>
18-
class MixedNetlistRouter : public NetlistRouter {
24+
class NestedNetlistRouter : public NetlistRouter {
1925
public:
20-
MixedNetlistRouter(
26+
NestedNetlistRouter(
2127
const Netlist<>& net_list,
2228
const RouterLookahead* router_lookahead,
2329
const t_router_opts& router_opts,
@@ -43,15 +49,18 @@ class MixedNetlistRouter : public NetlistRouter {
4349
, _choking_spots(choking_spots)
4450
, _is_flat(is_flat)
4551
, _thread_pool(MAX_THREADS) {}
46-
~MixedNetlistRouter() {}
52+
~NestedNetlistRouter() {}
4753

4854
/** Run a single iteration of netlist routing for this->_net_list. This usually means calling
4955
* \ref route_net for each net, which will handle other global updates.
5056
* \return RouteIterResults for this iteration. */
5157
RouteIterResults route_netlist(int itry, float pres_fac, float worst_neg_slack);
5258
/** Inform the PartitionTree of the nets with updated bounding boxes */
5359
void handle_bb_updated_nets(const std::vector<ParentNetId>& nets);
60+
61+
/** Set rcv_enabled for each ConnectionRouter this is managing */
5462
void set_rcv_enabled(bool x);
63+
/** Set timing_info for each ConnectionRouter this is managing */
5564
void set_timing_info(std::shared_ptr<SetupHoldTimingInfo> timing_info);
5665

5766
private:
@@ -95,13 +104,17 @@ class MixedNetlistRouter : public NetlistRouter {
95104
/** The partition tree. Holds the groups of nets for each partition */
96105
vtr::optional<PartitionTree> _tree;
97106

107+
/** Thread pool for parallel routing. See vtr_thread_pool.h for implementation */
98108
vtr::thread_pool _thread_pool;
99109

100-
/* Thread-local storage */
110+
/* Thread-local storage.
111+
* These are maps because thread::id is a random integer instead of 1, 2, ... */
101112
std::unordered_map<std::thread::id, ConnectionRouter<HeapType>> _routers_th;
102113
std::unordered_map<std::thread::id, RouteIterResults> _results_th;
103114
std::mutex _storage_mutex;
104115

116+
/** Get a thread-local ConnectionRouter. We lock the id->router lookup, but this is
117+
* accessed once per partition so the overhead should be small */
105118
ConnectionRouter<HeapType>& get_thread_router() {
106119
auto id = std::this_thread::get_id();
107120
std::lock_guard<std::mutex> lock(_storage_mutex);
@@ -118,4 +131,4 @@ class MixedNetlistRouter : public NetlistRouter {
118131
}
119132
};
120133

121-
#include "MixedNetlistRouter.tpp"
134+
#include "NestedNetlistRouter.tpp"

vpr/src/route/MixedNetlistRouter.tpp renamed to vpr/src/route/NestedNetlistRouter.tpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "vtr_time.h"
99

1010
template<typename HeapType>
11-
inline RouteIterResults MixedNetlistRouter<HeapType>::route_netlist(int itry, float pres_fac, float worst_neg_slack) {
11+
inline RouteIterResults NestedNetlistRouter<HeapType>::route_netlist(int itry, float pres_fac, float worst_neg_slack) {
1212
/* Reset results for each thread */
1313
for (auto& [_, results] : _results_th) {
1414
results = RouteIterResults();
@@ -50,7 +50,7 @@ inline RouteIterResults MixedNetlistRouter<HeapType>::route_netlist(int itry, fl
5050
}
5151

5252
template<typename HeapType>
53-
void MixedNetlistRouter<HeapType>::route_partition_tree_node(PartitionTreeNode& node) {
53+
void NestedNetlistRouter<HeapType>::route_partition_tree_node(PartitionTreeNode& node) {
5454
auto& route_ctx = g_vpr_ctx.mutable_routing();
5555

5656
/* node.nets is an unordered set, copy into vector to sort */
@@ -123,19 +123,19 @@ void MixedNetlistRouter<HeapType>::route_partition_tree_node(PartitionTreeNode&
123123
}
124124

125125
template<typename HeapType>
126-
void MixedNetlistRouter<HeapType>::handle_bb_updated_nets(const std::vector<ParentNetId>& nets) {
126+
void NestedNetlistRouter<HeapType>::handle_bb_updated_nets(const std::vector<ParentNetId>& nets) {
127127
VTR_ASSERT(_tree);
128128
_tree->update_nets(nets);
129129
}
130130

131131
template<typename HeapType>
132-
void MixedNetlistRouter<HeapType>::set_rcv_enabled(bool x) {
132+
void NestedNetlistRouter<HeapType>::set_rcv_enabled(bool x) {
133133
for (auto& [_, router] : _routers_th) {
134134
router.set_rcv_enabled(x);
135135
}
136136
}
137137

138138
template<typename HeapType>
139-
void MixedNetlistRouter<HeapType>::set_timing_info(std::shared_ptr<SetupHoldTimingInfo> timing_info) {
139+
void NestedNetlistRouter<HeapType>::set_timing_info(std::shared_ptr<SetupHoldTimingInfo> timing_info) {
140140
_timing_info = timing_info;
141141
}

vpr/src/route/netlist_routers.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class NetlistRouter {
7171

7272
/* Include the derived classes here to get the HeapType-templated impls */
7373
#include "SerialNetlistRouter.h"
74-
#include "MixedNetlistRouter.h"
74+
#include "NestedNetlistRouter.h"
7575
#ifdef VPR_USE_TBB
7676
# include "ParallelNetlistRouter.h"
7777
# include "DecompNetlistRouter.h"
@@ -105,8 +105,8 @@ inline std::unique_ptr<NetlistRouter> make_netlist_router_with_heap(
105105
routing_predictor,
106106
choking_spots,
107107
is_flat);
108-
} else if (router_opts.router_algorithm == e_router_algorithm::MIXED) {
109-
return std::make_unique<MixedNetlistRouter<HeapType>>(
108+
} else if (router_opts.router_algorithm == e_router_algorithm::NESTED) {
109+
return std::make_unique<NestedNetlistRouter<HeapType>>(
110110
net_list,
111111
router_lookahead,
112112
router_opts,

0 commit comments

Comments
 (0)