Skip to content

Commit 85c9928

Browse files
authored
Merge pull request #2370 from verilog-to-routing/3d_track_to_track_conn
Support 3D Custom Switch Blocks
2 parents a342b67 + b681f8d commit 85c9928

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+49885
-677
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ tags
144144
#
145145
.vscode
146146
.history
147+
.cache
147148
#eclipse project
148149
.project
149150

@@ -153,4 +154,4 @@ tags
153154
.idea
154155
cmake-build-debug
155156
cmake-build-release
156-
/.metadata/
157+
/.metadata/

libs/libarchfpga/src/parse_switchblocks.cpp

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ static void parse_comma_separated_wire_points(const char* ch, std::vector<t_wire
6565
/* Parses the number of connections type */
6666
static void parse_num_conns(std::string num_conns, t_wireconn_inf& wireconn);
6767

68+
/* Set connection from_side and to_side for custom switch block pattern*/
69+
static void set_switch_func_type(SB_Side_Connection& conn, const char* func_type);
70+
6871
/* parse switch_override in wireconn */
6972
static void parse_switch_override(const char* switch_override, t_wireconn_inf& wireconn, const t_arch_switch_inf* switches, int num_switches);
7073

@@ -269,6 +272,70 @@ static void parse_num_conns(std::string num_conns, t_wireconn_inf& wireconn) {
269272
wireconn.num_conns_formula = num_conns;
270273
}
271274

275+
//set sides for a specific conn for custom switch block pattern
276+
static void set_switch_func_type(SB_Side_Connection& conn, const char* func_type) {
277+
if (0 == strcmp(func_type, "lt")) {
278+
conn.set_sides(LEFT, TOP);
279+
} else if (0 == strcmp(func_type, "lr")) {
280+
conn.set_sides(LEFT, RIGHT);
281+
} else if (0 == strcmp(func_type, "lb")) {
282+
conn.set_sides(LEFT, BOTTOM);
283+
} else if (0 == strcmp(func_type, "la")) {
284+
conn.set_sides(LEFT, ABOVE);
285+
} else if (0 == strcmp(func_type, "lu")) {
286+
conn.set_sides(LEFT, UNDER);
287+
} else if (0 == strcmp(func_type, "tl")) {
288+
conn.set_sides(TOP, LEFT);
289+
} else if (0 == strcmp(func_type, "tb")) {
290+
conn.set_sides(TOP, BOTTOM);
291+
} else if (0 == strcmp(func_type, "tr")) {
292+
conn.set_sides(TOP, RIGHT);
293+
} else if (0 == strcmp(func_type, "ta")) {
294+
conn.set_sides(TOP, ABOVE);
295+
} else if (0 == strcmp(func_type, "tu")) {
296+
conn.set_sides(TOP, UNDER);
297+
} else if (0 == strcmp(func_type, "rt")) {
298+
conn.set_sides(RIGHT, TOP);
299+
} else if (0 == strcmp(func_type, "rl")) {
300+
conn.set_sides(RIGHT, LEFT);
301+
} else if (0 == strcmp(func_type, "rb")) {
302+
conn.set_sides(RIGHT, BOTTOM);
303+
} else if (0 == strcmp(func_type, "ra")) {
304+
conn.set_sides(RIGHT, ABOVE);
305+
} else if (0 == strcmp(func_type, "ru")) {
306+
conn.set_sides(RIGHT, UNDER);
307+
} else if (0 == strcmp(func_type, "bl")) {
308+
conn.set_sides(BOTTOM, LEFT);
309+
} else if (0 == strcmp(func_type, "bt")) {
310+
conn.set_sides(BOTTOM, TOP);
311+
} else if (0 == strcmp(func_type, "br")) {
312+
conn.set_sides(BOTTOM, RIGHT);
313+
} else if (0 == strcmp(func_type, "ba")) {
314+
conn.set_sides(BOTTOM, ABOVE);
315+
} else if (0 == strcmp(func_type, "bu")) {
316+
conn.set_sides(BOTTOM, UNDER);
317+
} else if (0 == strcmp(func_type, "al")) {
318+
conn.set_sides(ABOVE, LEFT);
319+
} else if (0 == strcmp(func_type, "at")) {
320+
conn.set_sides(ABOVE, TOP);
321+
} else if (0 == strcmp(func_type, "ar")) {
322+
conn.set_sides(ABOVE, RIGHT);
323+
} else if (0 == strcmp(func_type, "ab")) {
324+
conn.set_sides(ABOVE, BOTTOM);
325+
} else if (0 == strcmp(func_type, "ul")) {
326+
conn.set_sides(UNDER, LEFT);
327+
} else if (0 == strcmp(func_type, "ut")) {
328+
conn.set_sides(UNDER, TOP);
329+
} else if (0 == strcmp(func_type, "ur")) {
330+
conn.set_sides(UNDER, RIGHT);
331+
} else if (0 == strcmp(func_type, "ub")) {
332+
conn.set_sides(UNDER, BOTTOM);
333+
} else {
334+
/* unknown permutation function */
335+
archfpga_throw(__FILE__, __LINE__, "Unknown permutation function specified: %s\n", func_type);
336+
}
337+
}
338+
272339
/* Loads permutation funcs specified under Node into t_switchblock_inf. Node should be
273340
* <switchfuncs> */
274341
void read_sb_switchfuncs(pugi::xml_node Node, t_switchblock_inf* sb, const pugiutil::loc_data& loc_data) {
@@ -300,34 +367,8 @@ void read_sb_switchfuncs(pugi::xml_node Node, t_switchblock_inf* sb, const pugiu
300367
func_formula = get_attribute(SubElem, "formula", loc_data).as_string(nullptr);
301368

302369
/* go through all the possible cases of func_type */
303-
if (0 == strcmp(func_type, "lt")) {
304-
conn.set_sides(LEFT, TOP);
305-
} else if (0 == strcmp(func_type, "lr")) {
306-
conn.set_sides(LEFT, RIGHT);
307-
} else if (0 == strcmp(func_type, "lb")) {
308-
conn.set_sides(LEFT, BOTTOM);
309-
} else if (0 == strcmp(func_type, "tl")) {
310-
conn.set_sides(TOP, LEFT);
311-
} else if (0 == strcmp(func_type, "tb")) {
312-
conn.set_sides(TOP, BOTTOM);
313-
} else if (0 == strcmp(func_type, "tr")) {
314-
conn.set_sides(TOP, RIGHT);
315-
} else if (0 == strcmp(func_type, "rt")) {
316-
conn.set_sides(RIGHT, TOP);
317-
} else if (0 == strcmp(func_type, "rl")) {
318-
conn.set_sides(RIGHT, LEFT);
319-
} else if (0 == strcmp(func_type, "rb")) {
320-
conn.set_sides(RIGHT, BOTTOM);
321-
} else if (0 == strcmp(func_type, "bl")) {
322-
conn.set_sides(BOTTOM, LEFT);
323-
} else if (0 == strcmp(func_type, "bt")) {
324-
conn.set_sides(BOTTOM, TOP);
325-
} else if (0 == strcmp(func_type, "br")) {
326-
conn.set_sides(BOTTOM, RIGHT);
327-
} else {
328-
/* unknown permutation function */
329-
archfpga_throw(__FILE__, __LINE__, "Unknown permutation function specified: %s\n", func_type);
330-
}
370+
set_switch_func_type(conn, func_type);
371+
331372
func_ptr = &(sb->permutation_map[conn]);
332373

333374
/* Here we load the specified switch function(s) */
@@ -404,8 +445,8 @@ static void check_bidir_switchblock(const t_permutation_map* permutation_map) {
404445
SB_Side_Connection conn;
405446

406447
/* iterate over all combinations of from_side -> to side */
407-
for (e_side from_side : {TOP, RIGHT, BOTTOM, LEFT}) {
408-
for (e_side to_side : {TOP, RIGHT, BOTTOM, LEFT}) {
448+
for (e_side from_side : TOTAL_2D_SIDES) {
449+
for (e_side to_side : TOTAL_2D_SIDES) {
409450
/* can't connect a switchblock side to itself */
410451
if (from_side == to_side) {
411452
continue;

libs/libarchfpga/src/physical_types.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,17 @@ enum e_side : unsigned char {
176176
RIGHT = 1,
177177
BOTTOM = 2,
178178
LEFT = 3,
179-
NUM_SIDES
179+
NUM_2D_SIDES = 4,
180+
ABOVE = 5,
181+
UNDER = 7,
182+
NUM_3D_SIDES = 6,
180183
};
181-
constexpr std::array<e_side, NUM_SIDES> SIDES = {{TOP, RIGHT, BOTTOM, LEFT}}; //Set of all side orientations
182-
constexpr std::array<const char*, NUM_SIDES> SIDE_STRING = {{"TOP", "RIGHT", "BOTTOM", "LEFT"}}; //String versions of side orientations
184+
185+
constexpr std::array<e_side, NUM_2D_SIDES> TOTAL_2D_SIDES = {{TOP, RIGHT, BOTTOM, LEFT}}; //Set of all side orientations
186+
constexpr std::array<const char*, NUM_2D_SIDES> TOTAL_2D_SIDE_STRINGS = {{"TOP", "RIGHT", "BOTTOM", "LEFT"}}; //String versions of side orientations
187+
188+
constexpr std::array<e_side, NUM_3D_SIDES> TOTAL_3D_SIDES = {{TOP, RIGHT, BOTTOM, LEFT, ABOVE, UNDER}}; //Set of all side orientations including different layers
189+
constexpr std::array<const char*, NUM_3D_SIDES> TOTAL_3D_SIDE_STRINGS = {{"TOP", "RIGHT", "BOTTOM", "LEFT", "ABOVE", "UNDER"}}; //String versions of side orientations including different layers
183190

184191
/* pin location distributions */
185192
enum class e_pin_location_distr {

libs/libarchfpga/src/read_fpga_interchange_arch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ struct ArchReader {
480480
type.pin_height_offset.resize(type.num_pins, 0);
481481

482482
type.pinloc.resize({1, 1, 4}, std::vector<bool>(type.num_pins, false));
483-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
483+
for (e_side side : TOTAL_2D_SIDES) {
484484
for (int pin = 0; pin < type.num_pins; pin++) {
485485
type.pinloc[0][0][side][pin] = true;
486486
type.pin_width_offset[pin] = 0;

libs/libarchfpga/src/read_xml_arch_file.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
579579
int num_sides = 4 * (type->width * type->height);
580580
int side_index = 0;
581581
int count = 0;
582-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
582+
for (e_side side : TOTAL_2D_SIDES) {
583583
for (int width = 0; width < type->width; ++width) {
584584
for (int height = 0; height < type->height; ++height) {
585585
for (int pin_offset = 0; pin_offset < (type->num_pins / num_sides) + 1; ++pin_offset) {
@@ -604,7 +604,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
604604
while (ipin < type->num_pins) {
605605
for (int width = 0; width < type->width; ++width) {
606606
for (int height = 0; height < type->height; ++height) {
607-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
607+
for (e_side side : TOTAL_2D_SIDES) {
608608
if (((width == 0 && side == LEFT)
609609
|| (height == type->height - 1 && side == TOP)
610610
|| (width == type->width - 1 && side == RIGHT)
@@ -645,7 +645,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
645645
while (ipin < input_pins.size()) {
646646
for (int width = 0; width < type->width; ++width) {
647647
for (int height = 0; height < type->height; ++height) {
648-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
648+
for (e_side side : TOTAL_2D_SIDES) {
649649
if (ipin < input_pins.size()) {
650650
//Pins still to allocate
651651

@@ -668,7 +668,7 @@ static void LoadPinLoc(pugi::xml_node Locations,
668668
while (ipin < output_pins.size()) {
669669
for (int width = 0; width < type->width; ++width) {
670670
for (int height = 0; height < type->height; ++height) {
671-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
671+
for (e_side side : TOTAL_2D_SIDES) {
672672
if (((width == 0 && side == LEFT)
673673
|| (height == type->height - 1 && side == TOP)
674674
|| (width == type->width - 1 && side == RIGHT)
@@ -699,8 +699,8 @@ static void LoadPinLoc(pugi::xml_node Locations,
699699
for (int layer = 0; layer < num_of_avail_layer; ++layer) {
700700
for (int width = 0; width < type->width; ++width) {
701701
for (int height = 0; height < type->height; ++height) {
702-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
703-
for (const auto& token : pin_locs->assignments[sub_tile_index][width][height][layer][side]) {
702+
for (e_side side : TOTAL_2D_SIDES) {
703+
for (auto token : pin_locs->assignments[sub_tile_index][width][height][layer][side]) {
704704
auto pin_range = ProcessPinString<t_sub_tile*>(Locations,
705705
&sub_tile,
706706
token.c_str(),
@@ -3393,9 +3393,9 @@ static void ProcessPinLocations(pugi::xml_node Locations,
33933393
for (int l = 0; l < num_of_avail_layer; ++l) {
33943394
for (int w = 0; w < PhysicalTileType->width; ++w) {
33953395
for (int h = 0; h < PhysicalTileType->height; ++h) {
3396-
for (e_side side : {TOP, RIGHT, BOTTOM, LEFT}) {
3397-
for (const auto& token : pin_locs->assignments[sub_tile_index][w][h][l][side]) {
3398-
InstPort inst_port(token);
3396+
for (e_side side : TOTAL_2D_SIDES) {
3397+
for (auto token : pin_locs->assignments[sub_tile_index][w][h][l][side]) {
3398+
InstPort inst_port(token.c_str());
33993399

34003400
//A pin specification should contain only the block name, and not any instance count information
34013401
if (inst_port.instance_low_index() != InstPort::UNSPECIFIED || inst_port.instance_high_index() != InstPort::UNSPECIFIED) {
@@ -4766,9 +4766,9 @@ static int find_switch_by_name(const t_arch& arch, const std::string& switch_nam
47664766
}
47674767

47684768
static e_side string_to_side(const std::string& side_str) {
4769-
e_side side = NUM_SIDES;
4769+
e_side side = NUM_2D_SIDES;
47704770
if (side_str.empty()) {
4771-
side = NUM_SIDES;
4771+
side = NUM_2D_SIDES;
47724772
} else if (side_str == "left") {
47734773
side = LEFT;
47744774
} else if (side_str == "right") {

libs/librrgraph/src/base/check_rr_graph.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,12 @@ void check_rr_graph(const RRGraphView& rr_graph,
280280
rr_graph.node_layer(rr_node)});
281281
std::string pin_name = block_type_pin_index_to_name(block_type, rr_graph.node_pin_num(rr_node), is_flat);
282282
/* Print error messages for all the sides that a node may appear */
283-
for (const e_side& node_side : SIDES) {
283+
for (const e_side& node_side : TOTAL_2D_SIDES) {
284284
if (!rr_graph.is_node_on_specific_side(rr_node, node_side)) {
285285
continue;
286286
}
287287
VTR_LOG_ERROR("in check_rr_graph: node %d (%s) at (%d,%d) block=%s side=%s pin=%s has no fanin.\n",
288-
inode, rr_graph.node_type_string(rr_node), rr_graph.node_xlow(rr_node), rr_graph.node_ylow(rr_node), block_type->name, SIDE_STRING[node_side], pin_name.c_str());
288+
inode, rr_graph.node_type_string(rr_node), rr_graph.node_xlow(rr_node), rr_graph.node_ylow(rr_node), block_type->name, TOTAL_2D_SIDE_STRINGS[node_side], pin_name.c_str());
289289
}
290290
}
291291
} else {
@@ -498,9 +498,13 @@ void check_rr_node(const RRGraphView& rr_graph,
498498
tracks_per_node = ((rr_type == CHANX) ? chan_width.x_list[ylow] : chan_width.y_list[xlow]);
499499
}
500500

501-
if (ptc_num >= nodes_per_chan) {
502-
VPR_ERROR(VPR_ERROR_ROUTE,
503-
"in check_rr_node: inode %d (type %d) has a ptc_num of %d.\n", inode, rr_type, ptc_num);
501+
//if a chanx/chany has length 0, it means it is used to connect different dice together
502+
//hence, the ptc number can be larger than nodes_per_chan
503+
if(xlow != xhigh || ylow != yhigh) {
504+
if (ptc_num >= nodes_per_chan) {
505+
VPR_ERROR(VPR_ERROR_ROUTE,
506+
"in check_rr_node: inode %d (type %d) has a ptc_num of %d.\n", inode, rr_type, ptc_num);
507+
}
504508
}
505509

506510
if (capacity != tracks_per_node) {

libs/librrgraph/src/base/rr_graph_builder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@ void RRGraphBuilder::add_node_to_all_locs(RRNodeId node) {
3939
case SOURCE:
4040
case SINK:
4141
case CHANY:
42-
node_lookup_.add_node(node,node_layer, ix, iy, node_type, node_ptc_num, SIDES[0]);
42+
node_lookup_.add_node(node, node_layer, ix, iy, node_type, node_ptc_num, TOTAL_2D_SIDES[0]);
4343
break;
4444
case CHANX:
4545
/* Currently need to swap x and y for CHANX because of chan, seg convention
4646
* TODO: Once the builders is reworked for use consistent (x, y) convention,
4747
* the following swapping can be removed
4848
*/
49-
node_lookup_.add_node(node,node_layer, iy, ix, node_type, node_ptc_num, SIDES[0]);
49+
node_lookup_.add_node(node, node_layer, iy, ix, node_type, node_ptc_num, TOTAL_2D_SIDES[0]);
5050
break;
5151
case OPIN:
5252
case IPIN:
53-
for (const e_side& side : SIDES) {
53+
for (const e_side& side : TOTAL_2D_SIDES) {
5454
if (node_storage_.is_node_on_specific_side(node, side)) {
5555
node_lookup_.add_node(node,node_layer, ix, iy, node_type, node_ptc_num, side);
5656
}

libs/librrgraph/src/base/rr_graph_obj.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ RRNodeId RRGraph::create_node(const t_rr_type& type) {
812812
node_ptc_nums_.push_back(-1);
813813
node_cost_indices_.push_back(-1);
814814
node_directions_.push_back(Direction::NONE);
815-
node_sides_.push_back(NUM_SIDES);
815+
node_sides_.push_back(NUM_2D_SIDES);
816816
node_Rs_.push_back(0.);
817817
node_Cs_.push_back(0.);
818818

@@ -1133,7 +1133,7 @@ void RRGraph::build_fast_node_lookup() const {
11331133
if (node_type(node) == OPIN || node_type(node) == IPIN) {
11341134
iside = node_side(node);
11351135
} else {
1136-
iside = NUM_SIDES;
1136+
iside = NUM_2D_SIDES;
11371137
}
11381138

11391139
if (iside >= node_lookup_[x][y][itype][ptc].size()) {

libs/librrgraph/src/base/rr_graph_obj.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ class RRGraph {
510510
/* Find the edges connecting two nodes */
511511
std::vector<RREdgeId> find_edges(const RRNodeId& src_node, const RRNodeId& sink_node) const;
512512
/* Find a node with given features from internal fast look-up */
513-
RRNodeId find_node(const short& x, const short& y, const t_rr_type& type, const int& ptc, const e_side& side = NUM_SIDES) const;
513+
RRNodeId find_node(const short& x, const short& y, const t_rr_type& type, const int& ptc, const e_side& side = NUM_2D_SIDES) const;
514514
/* Find the number of routing tracks in a routing channel with a given coordinate */
515515
short chan_num_tracks(const short& x, const short& y, const t_rr_type& type) const;
516516

@@ -828,7 +828,7 @@ class RRGraph {
828828
bool dirty_ = false;
829829

830830
/* Fast look-up to search a node by its type, coordinator and ptc_num
831-
* Indexing of fast look-up: [0..xmax][0..ymax][0..NUM_TYPES-1][0..ptc_max][0..NUM_SIDES-1]
831+
* Indexing of fast look-up: [0..xmax][0..ymax][0..NUM_TYPES-1][0..ptc_max][0..NUM_2D_SIDES-1]
832832
*/
833833
typedef std::vector<std::vector<std::vector<std::vector<std::vector<RRNodeId>>>>> NodeLookup;
834834
mutable NodeLookup node_lookup_;

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,13 +618,13 @@ const std::string& t_rr_graph_storage::node_direction_string(RRNodeId id) const
618618
}
619619

620620
const char* t_rr_graph_storage::node_side_string(RRNodeId id) const {
621-
for (const e_side& side : SIDES) {
621+
for (const e_side& side : TOTAL_2D_SIDES) {
622622
if (is_node_on_specific_side(id, side)) {
623-
return SIDE_STRING[side];
623+
return TOTAL_2D_SIDE_STRINGS[side];
624624
}
625625
}
626626
/* Not found, return an invalid string*/
627-
return SIDE_STRING[NUM_SIDES];
627+
return TOTAL_2D_SIDE_STRINGS[NUM_2D_SIDES];
628628
}
629629

630630
void t_rr_graph_storage::set_node_layer(RRNodeId id, short layer) {
@@ -771,10 +771,10 @@ void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) {
771771
if (node_type(id) != IPIN && node_type(id) != OPIN) {
772772
VTR_LOG_ERROR("Attempted to set RR node 'side' for non-channel type '%s'", node_type_string(id));
773773
}
774-
std::bitset<NUM_SIDES> side_bits = node_storage_[id].dir_side_.sides;
774+
std::bitset<NUM_2D_SIDES> side_bits = node_storage_[id].dir_side_.sides;
775775
side_bits[size_t(new_side)] = true;
776776
if (side_bits.to_ulong() > CHAR_MAX) {
777-
VTR_LOG_ERROR("Invalid side '%s' to be added to rr node %u", SIDE_STRING[new_side], size_t(id));
777+
VTR_LOG_ERROR("Invalid side '%s' to be added to rr node %u", TOTAL_2D_SIDE_STRINGS[new_side], size_t(id));
778778
}
779779
node_storage_[id].dir_side_.sides = static_cast<unsigned char>(side_bits.to_ulong());
780780
}

libs/librrgraph/src/base/rr_graph_storage.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class t_rr_graph_storage {
213213
* Developers can easily use the following codes with more flexibility
214214
*
215215
* if (rr_graph.is_node_on_specific_side(id, side)) {
216-
* const char* side_string = SIDE_STRING[side];
216+
* const char* side_string = TOTAL_2D_SIDE_STRINGS[side];
217217
* }
218218
*/
219219
const char* node_side_string(RRNodeId id) const;
@@ -769,7 +769,7 @@ class t_rr_graph_storage {
769769
rr_node_typename[node_data.type_]);
770770
}
771771
// Return a vector showing only the sides that the node appears
772-
std::bitset<NUM_SIDES> side_tt = node_storage[id].dir_side_.sides;
772+
std::bitset<NUM_2D_SIDES> side_tt = node_storage[id].dir_side_.sides;
773773
return side_tt[size_t(side)];
774774
}
775775

0 commit comments

Comments
 (0)