Unverified Commit 184e3aac by Yucheng Wang Committed by GitHub

Merge pull request #33 from TILOS-AI-Institute/plc_client-open-source

Plc client open source runnable on CT + bug fix + CT flow setup guide
parents 5151c23e d0fcbbdc
......@@ -25,6 +25,18 @@ python -m Plc_client.plc_client_os_test --netlist ./Plc_client/test/ariane/netli
--smooth 2
```
You may uncomment any available tests and even run your own test dataset. We do not handle all corner cases since during RL placement, they are unlikely to occur. Our aim here is to reproduce Google's code as much as possible and be able to plug into Circuit Training Flow.
## How to run our code in Circuit Training?
Once you have downloaded Google's Circuit Training code, replace the environment.py with environment_ct.py (**you do need to change the name of the file**). Then, copy `plc_client_os.py` under the same directory (**you should not replace it with `plc_client.py` and should not change the name of the file**).
Since Force Directed Placer for the soft macros is not implemented yet, our code is essentially running Google's `plc_client.py` in parallel with our `plc_client_os.py` but extracting input from our code only except for soft macro positions. The memory usage will double and the runtime tends to be longer. However, with this "more open sourced" version of Circuit Training, we do see comparable training quality as using Google's API.
If you wish to find any discrepancies between these outputs, toggle `DEBUG` to `True` [here](https://github.com/TILOS-AI-Institute/MacroPlacement/blob/e634766f6aa53510c3fe8062896a6020f7ff18d1/CodeElements/Plc_client/environment_ct.py#L42) at the beginning of `environment_ct.py`. This will save all discrepancies into the corresponding folders.
## Implementation Details
For complete information on how the proxy cost is computed in our code, please refer to [Proxy Cost Documentation](https://tilos-ai-institute.github.io/MacroPlacement/Docs/ProxyCost/). Below is a quick overview of the formulation.
## HPWL Computation
Given a net $i$, its wirelength can be computed as the following:
......@@ -85,11 +97,8 @@ $$
Notice a smoothing range can be set for congestion. This is only applied to congestion due to net routing which by counting adjacent cells and adding the averaged congestion to these adjacent cells. More details are provided in the document above.
## Placement Util
**Disclaimer: We DO NOT own the content of placement_util_os.py. All rights belong to Google Authors. This is a modified version of placement_util.py and we are including in the repo for the sake of testing. Original Code can be viewed [here](https://github.com/google-research/circuit_training/blob/main/circuit_training/environment/placement_util.py)**.
## Observation Extractor
**Disclaimer: We DO NOT own the content of observation_extractor_os.py. All rights belong to Google Authors. This is a modified version of observation_extractor.py and we are including in the repo for the sake of testing. Original Code can be viewed [here](https://github.com/google-research/circuit_training/blob/main/circuit_training/environment/observation_extractor.py)**.
## DISCLAIMER
**We DO NOT own the original content of placement_util_os.py, observation_extractor_os.py, environment_os.py, environment_ct.py, coordinate_descent_placer.py. All rights belong to Google Authors. These are modified version of the original code and we are including in the repo for the sake of testing. Original Code can be viewed [here](https://github.com/google-research/circuit_training/blob/main/circuit_training/environment/placement_util.py)**.
......@@ -179,7 +179,7 @@ class ObservationExtractor(object):
sparse_adj_weight.append(weight)
edge_counts[i] += 1
edge_counts[j] += 1
features['sparse_adj_i'] = np.asarray(sparse_adj_i).astype(np.int32)
features['sparse_adj_j'] = np.asarray(sparse_adj_j).astype(np.int32)
features['sparse_adj_weight'] = np.asarray(sparse_adj_weight).astype(
......@@ -203,15 +203,12 @@ class ObservationExtractor(object):
def _get_clustered_port_locations(
self, grid_cell_index: int) -> Tuple[float, float]:
"""Returns clustered port locations.
This function returns an approximation location of the ports in a grid
cell. Depending on the cell location in the canvas, the approximation
differs.
Args:
grid_cell_index: The index of the grid cell where the cluster port is
located.
Returns:
A tuple of float: Approximate x, y location of the port cluster in the
grid cell in the same unit as canvas width and height (micron).
......@@ -403,4 +400,4 @@ class ObservationExtractor(object):
previous_node_index=previous_node_index,
current_node_index=current_node_index,
mask=mask))
return features
return features
\ No newline at end of file
......@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""A collection of non-prod utility functions for placement.
All the dependencies in this files should be non-prod.
"""
......@@ -80,11 +79,9 @@ def restore_macro_orientations(plc: plc_client.PlacementCost,
def extract_attribute_from_comments(attribute: str,
filenames: List[str]) -> Optional[str]:
"""Parses the files' comments section, tries to extract the attribute.
Args:
attribute: attribute to look for (case sensetive).
filenames: List of protobuf file or a plc file.
Returns:
Attribute name string, or None if not found.
"""
......@@ -134,10 +131,8 @@ def get_blockages_from_comments(
def extract_sizes_from_comments(
filenames: List[str]) -> Optional[Tuple[float, float, int, int]]:
"""Parses the file's comments section, tries to extract canvas/grid sizes.
Args:
filenames: A list of netlist (.pb.txt) or placement (.plc) files.
Returns:
Tuple of canvas_width, canvas_height, grid_cols, grid_rows
"""
......@@ -174,7 +169,6 @@ def extract_sizes_from_comments(
# done
def fix_port_coordinates(plc: plc_client.PlacementCost) -> None:
"""Find all ports and fix their coordinates.
Args:
plc: the placement cost object.
"""
......@@ -204,7 +198,6 @@ def create_placement_cost(
macro_vertical_routing_allocation: float = 51.79,
) -> plc_client.PlacementCost:
"""Creates a placement_cost object.
Args:
netlist_file: Path to the netlist proto text file.
init_placement: Path to the inital placement .plc file.
......@@ -218,7 +211,6 @@ def create_placement_cost(
vertical_routes_per_micron: Vertical route capacity per micros.
macro_horizontal_routing_allocation: Macro horizontal routing allocation.
macro_vertical_routing_allocation: Macro vertical routing allocation.
Returns:
A PlacementCost object.
"""
......@@ -272,10 +264,8 @@ def create_placement_cost(
def get_node_type_counts(plc: plc_client.PlacementCost) -> Dict[str, int]:
"""Returns number of each type of nodes in the netlist.
Args:
plc: the placement cost object.
Returns:
Number of each type of node in a dict.
"""
......@@ -391,7 +381,6 @@ def fd_placement_schedule(plc: plc_client.PlacementCost,
use_current_loc: bool = False,
move_macros: bool = False) -> None:
"""A placement schedule that uses force directed method.
Args:
plc: The plc object.
num_steps: Number of steps of the force-directed algorithm during each call.
......@@ -425,12 +414,10 @@ def get_ordered_node_indices(mode: str,
plc: plc_client.PlacementCost,
exclude_fixed_nodes: bool = True) -> List[int]:
"""Returns an ordering of node indices according to the specified mode.
Args:
mode: node ordering mode
plc: placement cost object
exclude_fixed_nodes: Whether fixed nodes should be excluded.
Returns:
Node indices sorted according to the mode.
"""
......@@ -465,10 +452,8 @@ def get_ordered_node_indices(mode: str,
def extract_parameters_from_comments(
filename: str) -> Tuple[float, float, int, int]:
"""Parses the file's comments section, tries to extract canvas/grid sizes.
Args:
filename: protobuf file or a plc file.
Returns:
Tuple of canvas_width, canvas_height, grid_cols, grid_rows
"""
......@@ -503,9 +488,7 @@ def extract_parameters_from_comments(
# done
def get_routing_resources() -> Dict[str, float]:
"""Currently we only use default parameter settings.
In the future, for specific project, the resources may need to be tuned.
Returns:
Routing resources.
"""
......@@ -703,7 +686,6 @@ def save_placement_with_info(plc: plc_client.PlacementCost,
Routes used by macros, hor : {hor_macro_alloc:.3f} ver : {ver_macro_alloc:.3f}
Smoothing factor : {smooth}
Use incremental cost : {incr_cost}
To view this file (most options are default):
viewer_binary\
--netlist_file {src_filename}\
......@@ -907,12 +889,10 @@ def grid_locations_near(plc: plc_client.PlacementCost,
def place_near(plc: plc_client.PlacementCost, node_index: int,
location: int) -> bool:
"""Places a node (legally) closest to the given location.
Args:
plc: placement_cost object.
node_index: index of a node.
location: target grid cell location. (row * num_cols + num_cols)
Returns:
True on success, False if this node was not placed on any grid legally.
"""
......@@ -983,7 +963,7 @@ def main():
NODE_XY_DICT = {}
for i in nodes_of_types(plc, ['MACRO', 'macro', 'STDCELL', 'PORT']):
NODE_XY_DICT[i] = (100, 100)
restore_node_xy_coordinates(plc, NODE_XY_DICT)
# print(get_node_xy_coordinates(plc))
......@@ -991,7 +971,7 @@ def main():
MACRO_ORIENTATION = {}
for i in nodes_of_types(plc, ['MACRO', 'macro']):
MACRO_ORIENTATION[i] = "S"
restore_macro_orientations(plc, MACRO_ORIENTATION)
# print(get_macro_orientations(plc))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment