-
Notifications
You must be signed in to change notification settings - Fork 415
Placement move primitive refactoring assignment 2 #2653
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Placement move primitive refactoring assignment 2 #2653
Conversation
inet_cost, proposed_net_cost, and bb_updated_before grouped in a struct. bb_updated_before renamed to bb_update_status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @robluo , I agree with this change over using inheritance. I left some comments to improve the PR.
/** | ||
* @brief This class is used to hide control flows needed to distinguish 2d and 3d placement | ||
*/ | ||
class BB2D3DControlFlow { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The classes and structs defined in this file are polluting the namespace. They either need to be put in the anonymous namespace or made static.
Although it may sound crazy, in the future (in a completely separate cpp file) someone may make a TSInfo struct (they just happen to use the same name) and they will get awful linker errors. Whenever a class/struct/function are declared in a cpp file they should be made static / put in the anonymous namespace to prevent this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can put all the functions in net_cost_handler
into a separate namespace. We are also following the same practice for router lookahead utilities. If you think this is a standard practice, we can at least enforce it for the new code being added to VTR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be enforced for new code. and It does not have to be a separate namespace; it need only be static / put in the anonymous namespace. This is common practice for very very large code bases where polluting the global space can be a real problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For file scope variables, static makes sense. For struct / class definitions: probably put in anonymous namespace if you want to hide them.
void set_ts_bb_coord(const ClusterNetId& net_id); | ||
void set_ts_edge(const ClusterNetId& net_id); | ||
}; | ||
static BB2D3DControlFlow bb_2d_3d_control_flow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not like the name of this class. I would use something like "BBManipulator" or something. Ideally you want to write code in a way that is extensible and self explanatory. BB2D3DControlFlow tells me "There is a problem with the control flow between 2D and 3D BB, and I made this class to encapsulate it" (which honestly is what we are doing), but I would recommend changing the name to something that says "This is a class that will manipulate the BB (whether it is 2D or 3D or any D in the future)".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well put :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BBUpdater? Or BBandCostUpdater
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
@@ -88,14 +94,33 @@ static vtr::vector<ClusterNetId, NetUpdateState> bb_updated_before; // [0...clus | |||
* layer_ts_bb_coord_new are used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also mention: layer_sink_pin_count is only used in the layer bounding box case.
Add @brief at the start of this.
/** | ||
* @brief This class is used to hide control flows needed to distinguish 2d and 3d placement | ||
*/ | ||
class BB2D3DControlFlow { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For file scope variables, static makes sense. For struct / class definitions: probably put in anonymous namespace if you want to hide them.
void set_ts_bb_coord(const ClusterNetId& net_id); | ||
void set_ts_edge(const ClusterNetId& net_id); | ||
}; | ||
static BB2D3DControlFlow bb_2d_3d_control_flow; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BBUpdater? Or BBandCostUpdater
ts_info.layer_ts_bb_coord_new.resize(num_nets, std::vector<t_2D_bb>(num_layers, t_2D_bb())); | ||
} | ||
|
||
/*This initialize the whole matrix to OPEN which is an invalid value*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: intializes
void BB2D3DControlFlow::init(size_t num_nets, bool cube_bb_in) { | ||
const int num_layers = g_vpr_ctx.device().grid.get_num_layers(); | ||
|
||
cube_bb = cube_bb_in; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could comment: we'll use either the 3D BB or per layer BB data structures, but not both.
} | ||
|
||
/*This initialize the whole matrix to OPEN which is an invalid value*/ | ||
ts_info.ts_layer_sink_pin_count.resize({num_nets, size_t(num_layers)}, OPEN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this one is only used for per layer BB, so it should be moved inside the if statement.
ts_info.ts_bb_edge_new.resize(num_nets, t_bb()); | ||
ts_info.ts_bb_coord_new.resize(num_nets, t_bb()); | ||
} else { | ||
VTR_ASSERT_SAFE(!cube_bb); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion, but usually I don't write asserts that check the else is the opposite of the if condition.
auto& cluster_ctx = g_vpr_ctx.clustering(); | ||
if(cube_bb) | ||
return cluster_ctx.clb_nlist.pin_type(blk_pin) == PinType::DRIVER; | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can do the if part all the time and it is simpler. If so, we can just get rid of the routine.
|
||
t_physical_tile_type_ptr blk_type = physical_tile_type(blk); | ||
int pin_width_offset = blk_type->pin_width_offset[iblk_pin]; | ||
int pin_height_offset = blk_type->pin_height_offset[iblk_pin]; | ||
bool is_driver = bb_2d_3d_control_flow.is_driver(blk_type, blk_pin); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could leave the function if you like it, but I think only the if part is needed (no else).
*/ | ||
void update_move_nets(int num_nets_affected, | ||
const bool cube_bb); | ||
void update_move_nets(int num_nets_affected); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need num_nets_affected? Can be deleted.
In placement, we use two methods to update the bounding box: the 3D bounding box (also used for 2D architecture) and the per-layer bounding box. When a swap happens, multiple variables are updated, indicated by the
ts
(temporary swap) prefix. We can put all these variables into a class. Since only a subset is used depending on the bounding box type, you can examine how these variables are updated throughout the file and write methods for this class to update the appropriate ones.After some discussion, it was decided to not use inheritance or the type eraser due to potential performance degradation and the lack of readability. In this PR, the control flow that decides 3d or 2d placement are wrapped into a class.