Commit 3c1362f8 by Dinple

placement_util test done + updated plc_client_os

parent 7474f481
...@@ -44,7 +44,7 @@ def nodes_of_types(plc: plc_client.PlacementCost, ...@@ -44,7 +44,7 @@ def nodes_of_types(plc: plc_client.PlacementCost,
yield i yield i
i += 1 i += 1
# done
def get_node_xy_coordinates( def get_node_xy_coordinates(
plc: plc_client.PlacementCost) -> Dict[int, Tuple[float, float]]: plc: plc_client.PlacementCost) -> Dict[int, Tuple[float, float]]:
"""Returns all node x,y coordinates (canvas) in a dict.""" """Returns all node x,y coordinates (canvas) in a dict."""
...@@ -54,7 +54,7 @@ def get_node_xy_coordinates( ...@@ -54,7 +54,7 @@ def get_node_xy_coordinates(
node_coords[node_index] = plc.get_node_location(node_index) node_coords[node_index] = plc.get_node_location(node_index)
return node_coords return node_coords
# done
def get_macro_orientations(plc: plc_client.PlacementCost) -> Dict[int, int]: def get_macro_orientations(plc: plc_client.PlacementCost) -> Dict[int, int]:
"""Returns all macros' orientations in a dict.""" """Returns all macros' orientations in a dict."""
macro_orientations = dict() macro_orientations = dict()
...@@ -62,7 +62,7 @@ def get_macro_orientations(plc: plc_client.PlacementCost) -> Dict[int, int]: ...@@ -62,7 +62,7 @@ def get_macro_orientations(plc: plc_client.PlacementCost) -> Dict[int, int]:
macro_orientations[node_index] = plc.get_macro_orientation(node_index) macro_orientations[node_index] = plc.get_macro_orientation(node_index)
return macro_orientations return macro_orientations
# done
def restore_node_xy_coordinates( def restore_node_xy_coordinates(
plc: plc_client.PlacementCost, plc: plc_client.PlacementCost,
node_coords: Dict[int, Tuple[float, float]]) -> None: node_coords: Dict[int, Tuple[float, float]]) -> None:
...@@ -70,13 +70,13 @@ def restore_node_xy_coordinates( ...@@ -70,13 +70,13 @@ def restore_node_xy_coordinates(
if not plc.is_node_fixed(node_index): if not plc.is_node_fixed(node_index):
plc.update_node_coords(node_index, coords[0], coords[1]) plc.update_node_coords(node_index, coords[0], coords[1])
# done
def restore_macro_orientations(plc: plc_client.PlacementCost, def restore_macro_orientations(plc: plc_client.PlacementCost,
macro_orientations: Dict[int, int]) -> None: macro_orientations: Dict[int, int]) -> None:
for node_index, orientation in macro_orientations.items(): for node_index, orientation in macro_orientations.items():
plc.update_macro_orientation(node_index, orientation) plc.update_macro_orientation(node_index, orientation)
# # done
def extract_attribute_from_comments(attribute: str, def extract_attribute_from_comments(attribute: str,
filenames: List[str]) -> Optional[str]: filenames: List[str]) -> Optional[str]:
"""Parses the files' comments section, tries to extract the attribute. """Parses the files' comments section, tries to extract the attribute.
...@@ -104,7 +104,7 @@ def extract_attribute_from_comments(attribute: str, ...@@ -104,7 +104,7 @@ def extract_attribute_from_comments(attribute: str,
break break
return None return None
#done # done
def get_blockages_from_comments( def get_blockages_from_comments(
filenames: Union[str, List[str]]) -> Optional[List[List[float]]]: filenames: Union[str, List[str]]) -> Optional[List[List[float]]]:
"""Returns list of blockages if they exist in the file's comments section.""" """Returns list of blockages if they exist in the file's comments section."""
...@@ -171,7 +171,7 @@ def extract_sizes_from_comments( ...@@ -171,7 +171,7 @@ def extract_sizes_from_comments(
if canvas_width and canvas_height and grid_cols and grid_rows: if canvas_width and canvas_height and grid_cols and grid_rows:
return canvas_width, canvas_height, grid_cols, grid_rows return canvas_width, canvas_height, grid_cols, grid_rows
# done
def fix_port_coordinates(plc: plc_client.PlacementCost) -> None: def fix_port_coordinates(plc: plc_client.PlacementCost) -> None:
"""Find all ports and fix their coordinates. """Find all ports and fix their coordinates.
...@@ -182,12 +182,13 @@ def fix_port_coordinates(plc: plc_client.PlacementCost) -> None: ...@@ -182,12 +182,13 @@ def fix_port_coordinates(plc: plc_client.PlacementCost) -> None:
# print("node to fix:", node) # print("node to fix:", node)
plc.fix_node_coord(node) plc.fix_node_coord(node)
# done
# The routing capacities are calculated based on the public information about # The routing capacities are calculated based on the public information about
# 7nm technology (https://en.wikichip.org/wiki/7_nm_lithography_process) # 7nm technology (https://en.wikichip.org/wiki/7_nm_lithography_process)
# with an arbitary, yet reasonable, assumption of 18% of the tracks for # with an arbitary, yet reasonable, assumption of 18% of the tracks for
# the power grids. # the power grids.
def create_placement_cost( def create_placement_cost(
plc_client: None,
netlist_file: str, netlist_file: str,
init_placement: Optional[str] = None, init_placement: Optional[str] = None,
overlap_threshold: float = 4e-3, overlap_threshold: float = 4e-3,
...@@ -300,20 +301,21 @@ def get_node_type_counts(plc: plc_client.PlacementCost) -> Dict[str, int]: ...@@ -300,20 +301,21 @@ def get_node_type_counts(plc: plc_client.PlacementCost) -> Dict[str, int]:
counts['HARD_MACRO'] += 1 counts['HARD_MACRO'] += 1
if node_type == 'MACRO_PIN': if node_type == 'MACRO_PIN':
ref_id = plc.get_ref_node_id(node_index) ref_id = plc.get_ref_node_id(node_index)
# print("ref_id: ", ref_id)
if plc.is_node_soft_macro(ref_id): if plc.is_node_soft_macro(ref_id):
counts['SOFT_MACRO_PIN'] += 1 counts['SOFT_MACRO_PIN'] += 1
else: else:
counts['HARD_MACRO_PIN'] += 1 counts['HARD_MACRO_PIN'] += 1
return counts return counts
# done
def make_blockage_text(plc: plc_client.PlacementCost) -> str: def make_blockage_text(plc: plc_client.PlacementCost) -> str:
ret = '' ret = ''
for blockage in plc.get_blockages(): for blockage in plc.get_blockages():
ret += 'Blockage : {}\n'.format(' '.join([str(b) for b in blockage])) ret += 'Blockage : {}\n'.format(' '.join([str(b) for b in blockage]))
return ret return ret
# done
def save_placement(plc: plc_client.PlacementCost, def save_placement(plc: plc_client.PlacementCost,
filename: str, filename: str,
user_comments: str = '') -> None: user_comments: str = '') -> None:
...@@ -372,9 +374,12 @@ def save_placement(plc: plc_client.PlacementCost, ...@@ -372,9 +374,12 @@ def save_placement(plc: plc_client.PlacementCost,
if user_comments: if user_comments:
info += '\nUser comments:\n' + user_comments + '\n' info += '\nUser comments:\n' + user_comments + '\n'
info += '\nnode_index x y orientation fixed' info += '\nnode_index x y orientation fixed'
# print(info)
return plc.save_placement(filename, info) return plc.save_placement(filename, info)
# TODO: plc.optimize_stdcells
def fd_placement_schedule(plc: plc_client.PlacementCost, def fd_placement_schedule(plc: plc_client.PlacementCost,
num_steps: Tuple[int, ...] = (100, 100, 100), num_steps: Tuple[int, ...] = (100, 100, 100),
io_factor: float = 1.0, io_factor: float = 1.0,
...@@ -415,7 +420,7 @@ def fd_placement_schedule(plc: plc_client.PlacementCost, ...@@ -415,7 +420,7 @@ def fd_placement_schedule(plc: plc_client.PlacementCost,
log_scale_conns, use_sizes, io_factor, num_steps, log_scale_conns, use_sizes, io_factor, num_steps,
max_move_distance, attract_factor, repel_factor) max_move_distance, attract_factor, repel_factor)
# not tested
def get_ordered_node_indices(mode: str, def get_ordered_node_indices(mode: str,
plc: plc_client.PlacementCost, plc: plc_client.PlacementCost,
exclude_fixed_nodes: bool = True) -> List[int]: exclude_fixed_nodes: bool = True) -> List[int]:
...@@ -456,7 +461,7 @@ def get_ordered_node_indices(mode: str, ...@@ -456,7 +461,7 @@ def get_ordered_node_indices(mode: str,
ordered_indices = [m for m in ordered_indices if not plc.is_node_fixed(m)] ordered_indices = [m for m in ordered_indices if not plc.is_node_fixed(m)]
return ordered_indices return ordered_indices
# done
def extract_parameters_from_comments( def extract_parameters_from_comments(
filename: str) -> Tuple[float, float, int, int]: filename: str) -> Tuple[float, float, int, int]:
"""Parses the file's comments section, tries to extract canvas/grid sizes. """Parses the file's comments section, tries to extract canvas/grid sizes.
...@@ -476,6 +481,7 @@ def extract_parameters_from_comments( ...@@ -476,6 +481,7 @@ def extract_parameters_from_comments(
fp_re = re.search( fp_re = re.search(
r'FP bbox: \{([\d\.]+) ([\d\.]+)\} \{([\d\.]+) ([\d\.]+)\}', line) r'FP bbox: \{([\d\.]+) ([\d\.]+)\} \{([\d\.]+) ([\d\.]+)\}', line)
if fp_re: if fp_re:
# NOTE: first two argument contains origin coord but not used
canvas_width = float(fp_re.group(3)) canvas_width = float(fp_re.group(3))
canvas_height = float(fp_re.group(4)) canvas_height = float(fp_re.group(4))
continue continue
...@@ -494,7 +500,7 @@ def extract_parameters_from_comments( ...@@ -494,7 +500,7 @@ def extract_parameters_from_comments(
break break
return canvas_width, canvas_height, grid_cols, grid_rows return canvas_width, canvas_height, grid_cols, grid_rows
# done
def get_routing_resources() -> Dict[str, float]: def get_routing_resources() -> Dict[str, float]:
"""Currently we only use default parameter settings. """Currently we only use default parameter settings.
...@@ -512,6 +518,7 @@ def get_routing_resources() -> Dict[str, float]: ...@@ -512,6 +518,7 @@ def get_routing_resources() -> Dict[str, float]:
} }
# done
def nodes_of_types(plc: plc_client.PlacementCost, type_list: List[str]): def nodes_of_types(plc: plc_client.PlacementCost, type_list: List[str]):
"""Yields the index of a node of certain types.""" """Yields the index of a node of certain types."""
i = 0 i = 0
...@@ -523,7 +530,7 @@ def nodes_of_types(plc: plc_client.PlacementCost, type_list: List[str]): ...@@ -523,7 +530,7 @@ def nodes_of_types(plc: plc_client.PlacementCost, type_list: List[str]):
yield i yield i
i += 1 i += 1
# done
def num_nodes_of_type(plc, node_type): def num_nodes_of_type(plc, node_type):
"""Returns number of node of a particular type.""" """Returns number of node of a particular type."""
count = 0 count = 0
...@@ -532,6 +539,7 @@ def num_nodes_of_type(plc, node_type): ...@@ -532,6 +539,7 @@ def num_nodes_of_type(plc, node_type):
return count return count
# not tested
def extract_blockages_from_tcl(filename: str, def extract_blockages_from_tcl(filename: str,
block_name: str, block_name: str,
canvas_width: float, canvas_width: float,
...@@ -606,7 +614,7 @@ def extract_blockages_from_tcl(filename: str, ...@@ -606,7 +614,7 @@ def extract_blockages_from_tcl(filename: str,
index += 1 index += 1
return blockages return blockages
# done
def get_ascii_picture(vect: List[Any], def get_ascii_picture(vect: List[Any],
cols: int, cols: int,
rows: int, rows: int,
...@@ -636,7 +644,7 @@ def get_ascii_picture(vect: List[Any], ...@@ -636,7 +644,7 @@ def get_ascii_picture(vect: List[Any],
ret_str += ' -' + '-' * 2 * cols + '\n' ret_str += ' -' + '-' * 2 * cols + '\n'
return ret_str return ret_str
# done
def get_hard_macro_density_map(plc: plc_client.PlacementCost) -> List[float]: def get_hard_macro_density_map(plc: plc_client.PlacementCost) -> List[float]:
"""Returns the placement density map for hard macros only.""" """Returns the placement density map for hard macros only."""
# Unplaces all standard cells and soft macros, so that grid cell density # Unplaces all standard cells and soft macros, so that grid cell density
...@@ -660,7 +668,7 @@ def get_hard_macro_density_map(plc: plc_client.PlacementCost) -> List[float]: ...@@ -660,7 +668,7 @@ def get_hard_macro_density_map(plc: plc_client.PlacementCost) -> List[float]:
plc.set_canvas_boundary_check(check_boundary) plc.set_canvas_boundary_check(check_boundary)
return hard_macro_density return hard_macro_density
# done
def save_placement_with_info(plc: plc_client.PlacementCost, def save_placement_with_info(plc: plc_client.PlacementCost,
filename: str, filename: str,
user_comments: str = '') -> None: user_comments: str = '') -> None:
...@@ -755,8 +763,9 @@ def save_placement_with_info(plc: plc_client.PlacementCost, ...@@ -755,8 +763,9 @@ def save_placement_with_info(plc: plc_client.PlacementCost,
info += '\nnode_index x y orientation fixed' info += '\nnode_index x y orientation fixed'
return plc.save_placement(filename, info) return plc.save_placement(filename, info)
# done
def create_placement_cost_using_common_arguments( def create_placement_cost_using_common_arguments(
plc_client:None,
netlist_file: str, netlist_file: str,
init_placement: Optional[str] = None, init_placement: Optional[str] = None,
canvas_width: Optional[float] = None, canvas_width: Optional[float] = None,
...@@ -847,7 +856,7 @@ def create_placement_cost_using_common_arguments( ...@@ -847,7 +856,7 @@ def create_placement_cost_using_common_arguments(
return plc return plc
# done, but need verify
def get_node_locations(plc: plc_client.PlacementCost) -> Dict[int, int]: def get_node_locations(plc: plc_client.PlacementCost) -> Dict[int, int]:
"""Returns all node grid locations (macros and stdcells) in a dict.""" """Returns all node grid locations (macros and stdcells) in a dict."""
node_locations = dict() node_locations = dict()
...@@ -866,7 +875,7 @@ def get_node_ordering_by_size(plc: plc_client.PlacementCost) -> List[int]: ...@@ -866,7 +875,7 @@ def get_node_ordering_by_size(plc: plc_client.PlacementCost) -> List[int]:
node_areas[i] = w * h node_areas[i] = w * h
return sorted(node_areas, key=node_areas.get, reverse=True) return sorted(node_areas, key=node_areas.get, reverse=True)
# not tested
def grid_locations_near(plc: plc_client.PlacementCost, def grid_locations_near(plc: plc_client.PlacementCost,
start_grid_index: int) -> Iterator[int]: start_grid_index: int) -> Iterator[int]:
"""Yields node indices closest to the start_grid_index.""" """Yields node indices closest to the start_grid_index."""
...@@ -894,7 +903,7 @@ def grid_locations_near(plc: plc_client.PlacementCost, ...@@ -894,7 +903,7 @@ def grid_locations_near(plc: plc_client.PlacementCost,
continue continue
yield int(new_col + new_row * cols) yield int(new_col + new_row * cols)
# not tested
def place_near(plc: plc_client.PlacementCost, node_index: int, def place_near(plc: plc_client.PlacementCost, node_index: int,
location: int) -> bool: location: int) -> bool:
"""Places a node (legally) closest to the given location. """Places a node (legally) closest to the given location.
...@@ -913,7 +922,7 @@ def place_near(plc: plc_client.PlacementCost, node_index: int, ...@@ -913,7 +922,7 @@ def place_near(plc: plc_client.PlacementCost, node_index: int,
return True return True
return False return False
# not tested
def disconnect_high_fanout_nets(plc: plc_client.PlacementCost, def disconnect_high_fanout_nets(plc: plc_client.PlacementCost,
max_allowed_fanouts: int = 500) -> None: max_allowed_fanouts: int = 500) -> None:
high_fanout_nets = [] high_fanout_nets = []
...@@ -925,7 +934,7 @@ def disconnect_high_fanout_nets(plc: plc_client.PlacementCost, ...@@ -925,7 +934,7 @@ def disconnect_high_fanout_nets(plc: plc_client.PlacementCost,
high_fanout_nets.append(i) high_fanout_nets.append(i)
plc.disconnect_nets(high_fanout_nets) plc.disconnect_nets(high_fanout_nets)
# not tested
def legalize_placement(plc: plc_client.PlacementCost) -> bool: def legalize_placement(plc: plc_client.PlacementCost) -> bool:
"""Places the nodes to legal positions snapping to grid cells.""" """Places the nodes to legal positions snapping to grid cells."""
# Unplace all except i/o's. # Unplace all except i/o's.
...@@ -963,10 +972,44 @@ def main(): ...@@ -963,10 +972,44 @@ def main():
test_netlist_dir = './Plc_client/test/'+'ariane' test_netlist_dir = './Plc_client/test/'+'ariane'
netlist_file = os.path.join(test_netlist_dir,'netlist.pb.txt') netlist_file = os.path.join(test_netlist_dir,'netlist.pb.txt')
init_placement = os.path.join(test_netlist_dir,'initial.plc') init_placement = os.path.join(test_netlist_dir,'initial.plc')
plc = create_placement_cost(netlist_file=netlist_file, init_placement=init_placement) plc = create_placement_cost(plc_client=plc_client, netlist_file=netlist_file, init_placement=init_placement)
plc = create_placement_cost_using_common_arguments(netlist_file=netlist_file, init_placement=init_placement, # plc = create_placement_cost_using_common_arguments(netlist_file=netlist_file, init_placement=init_placement,
grid_cols=10, grid_rows=10, congestion_smooth_range=2.0, overlap_threshold=0.004, use_incremental_cost=False) # grid_cols=10, grid_rows=10, congestion_smooth_range=2.0, overlap_threshold=0.004, use_incremental_cost=False)
print(make_blockage_text(plc))
# save_placement(plc, "save_test", 'this is a comment')
# plc.nodes_of_types() # plc.nodes_of_types()
# node_xy_coordinates
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))
# macro_orientation
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))
fix_port_coordinates(plc)
# write out new plc
save_placement(plc, "save_test", 'this is a comment')
# needs more testing
print(get_node_locations(plc))
# num_nodes_of_type
print("num_nodes_of_type 'MACRO':", num_nodes_of_type(plc, "MACRO"))
# get_hard_macro_density_map
print("get_hard_macro_density_map: \n", get_hard_macro_density_map(plc))
print("get_hard_macro_density_map in ASCII: \n", get_ascii_picture(get_hard_macro_density_map(plc), *plc.get_grid_num_columns_rows()))
print()
if __name__ == '__main__': if __name__ == '__main__':
main() main()
\ No newline at end of file
"""Open-Sourced PlacementCost client class.""" """Open-Sourced PlacementCost client class."""
from ast import Assert
import os, io import os, io
from platform import node from platform import node
import re import re
...@@ -238,7 +239,7 @@ class PlacementCost(object): ...@@ -238,7 +239,7 @@ class PlacementCost(object):
# [MACRO_NAME]/[PIN_NAME] # [MACRO_NAME]/[PIN_NAME]
soft_macro_name = node_name.rsplit('/', 1)[0] soft_macro_name = node_name.rsplit('/', 1)[0]
# soft macro pin # soft macro pin
soft_macro_pin = self.SoftMacroPin(name=node_name, soft_macro_pin = self.SoftMacroPin(name=node_name,ref_id=None,
x = attr_dict['x'][1], x = attr_dict['x'][1],
y = attr_dict['y'][1], y = attr_dict['y'][1],
macro_name = attr_dict['macro_name'][1]) macro_name = attr_dict['macro_name'][1])
...@@ -290,7 +291,7 @@ class PlacementCost(object): ...@@ -290,7 +291,7 @@ class PlacementCost(object):
# [MACRO_NAME]/[PIN_NAME] # [MACRO_NAME]/[PIN_NAME]
hard_macro_name = node_name.rsplit('/', 1)[0] hard_macro_name = node_name.rsplit('/', 1)[0]
# hard macro pin # hard macro pin
hard_macro_pin = self.HardMacroPin(name=node_name, hard_macro_pin = self.HardMacroPin(name=node_name,ref_id=None,
x = attr_dict['x'][1], x = attr_dict['x'][1],
y = attr_dict['y'][1], y = attr_dict['y'][1],
x_offset = attr_dict['x_offset'][1], x_offset = attr_dict['x_offset'][1],
...@@ -562,18 +563,20 @@ class PlacementCost(object): ...@@ -562,18 +563,20 @@ class PlacementCost(object):
for macro_idx in (self.hard_macro_indices + self.soft_macro_indices): for macro_idx in (self.hard_macro_indices + self.soft_macro_indices):
macro = self.modules_w_pins[macro_idx] macro = self.modules_w_pins[macro_idx]
macro_name = macro.get_name() macro_name = macro.get_name()
macro_type = macro.get_type()
if macro_type == "MACRO": if not self.is_node_soft_macro(macro_idx):
if macro_name in self.hard_macros_to_inpins.keys(): if macro_name in self.hard_macros_to_inpins.keys():
pin_names = self.hard_macros_to_inpins[macro_name] pin_names = self.hard_macros_to_inpins[macro_name]
else: else:
return print("[ERROR UPDATE CONNECTION] MACRO not found")
elif macro_type == "macro": exit(1)
# use is_node_soft_macro()
elif self.is_node_soft_macro(macro_idx):
if macro_name in self.soft_macros_to_inpins.keys(): if macro_name in self.soft_macros_to_inpins.keys():
pin_names = self.soft_macros_to_inpins[macro_name] pin_names = self.soft_macros_to_inpins[macro_name]
else: else:
return print("[ERROR UPDATE CONNECTION] MACRO not found")
exit(1)
for pin_name in pin_names: for pin_name in pin_names:
pin = self.modules_w_pins[self.mod_name_to_indices[pin_name]] pin = self.modules_w_pins[self.mod_name_to_indices[pin_name]]
...@@ -581,7 +584,7 @@ class PlacementCost(object): ...@@ -581,7 +584,7 @@ class PlacementCost(object):
if inputs: if inputs:
for k in inputs.keys(): for k in inputs.keys():
if macro_type == "MACRO" or macro_type == "macro": if self.get_node_type(macro_idx) == "MACRO":
weight = pin.get_weight() weight = pin.get_weight()
macro.add_connections(inputs[k], weight) macro.add_connections(inputs[k], weight)
...@@ -647,7 +650,7 @@ class PlacementCost(object): ...@@ -647,7 +650,7 @@ class PlacementCost(object):
# retrieve location # retrieve location
x_coord.append(sink.get_pos()[0]) x_coord.append(sink.get_pos()[0])
y_coord.append(sink.get_pos()[1]) y_coord.append(sink.get_pos()[1])
elif curr_type == "macro_pin" or curr_type == "MACRO_PIN": elif curr_type == "MACRO_PIN":
# add source position # add source position
x_coord.append(mod.get_pos()[0]) x_coord.append(mod.get_pos()[0])
y_coord.append(mod.get_pos()[1]) y_coord.append(mod.get_pos()[1])
...@@ -733,6 +736,9 @@ class PlacementCost(object): ...@@ -733,6 +736,9 @@ class PlacementCost(object):
def get_congestion_cost(self): def get_congestion_cost(self):
#return max(self.get_H_congestion_cost(), self.get_V_congestion_cost()) #return max(self.get_H_congestion_cost(), self.get_V_congestion_cost())
# TODO need to test if cong is smaller than 5 # TODO need to test if cong is smaller than 5
if self.FLAG_UPDATE_CONGESTION:
self.get_routing()
return self.abu(self.V_routing_cong + self.H_routing_cong, 0.05) return self.abu(self.V_routing_cong + self.H_routing_cong, 0.05)
def __get_grid_cell_location(self, x_pos, y_pos): def __get_grid_cell_location(self, x_pos, y_pos):
...@@ -1292,7 +1298,6 @@ class PlacementCost(object): ...@@ -1292,7 +1298,6 @@ class PlacementCost(object):
self.FLAG_UPDATE_CONGESTION = False self.FLAG_UPDATE_CONGESTION = False
for mod in self.modules_w_pins: for mod in self.modules_w_pins:
norm_fact = 1.0
curr_type = mod.get_type() curr_type = mod.get_type()
# bounding box data structure # bounding box data structure
node_gcells = set() node_gcells = set()
...@@ -1314,7 +1319,7 @@ class PlacementCost(object): ...@@ -1314,7 +1319,7 @@ class PlacementCost(object):
# retrieve grid location # retrieve grid location
node_gcells.add(self.__get_grid_cell_location(*(sink.get_pos()))) node_gcells.add(self.__get_grid_cell_location(*(sink.get_pos())))
elif (curr_type == "macro_pin" or curr_type == "MACRO_PIN") and mod.get_sink(): elif curr_type == "MACRO_PIN" and mod.get_sink():
# add source position # add source position
node_gcells.add(self.__get_grid_cell_location(*(mod.get_pos()))) node_gcells.add(self.__get_grid_cell_location(*(mod.get_pos())))
source_gcell = self.__get_grid_cell_location(*(mod.get_pos())) source_gcell = self.__get_grid_cell_location(*(mod.get_pos()))
...@@ -1328,10 +1333,10 @@ class PlacementCost(object): ...@@ -1328,10 +1333,10 @@ class PlacementCost(object):
sink_idx = self.mod_name_to_indices[sink_name] sink_idx = self.mod_name_to_indices[sink_name]
# retrieve sink object # retrieve sink object
sink = self.modules_w_pins[sink_idx] sink = self.modules_w_pins[sink_idx]
# retrieve grid location # retrieve grid location
node_gcells.add(self.__get_grid_cell_location(*(sink.get_pos()))) node_gcells.add(self.__get_grid_cell_location(*(sink.get_pos())))
elif curr_type == "MACRO": elif curr_type == "MACRO" and self.is_node_hard_macro(self.mod_name_to_indices[mod.get_name()]):
module_h = mod.get_height() module_h = mod.get_height()
module_w = mod.get_width() module_w = mod.get_width()
module_x, module_y = mod.get_pos() module_x, module_y = mod.get_pos()
...@@ -1412,10 +1417,24 @@ class PlacementCost(object): ...@@ -1412,10 +1417,24 @@ class PlacementCost(object):
self.H_routing_cong = temp_H_routing_cong self.H_routing_cong = temp_H_routing_cong
def is_node_soft_macro(self, node_idx) -> bool: def is_node_soft_macro(self, node_idx) -> bool:
return self.get_node_type(node_idx) == "soft_macro" """
Return None or return ref_id
"""
try:
return node_idx in self.soft_macro_indices
except IndexError:
print("[ERROR INDEX OUT OF RANGE] Can not process index at {}".format(node_idx))
exit(0)
def is_node_hard_macro(self, node_idx) -> bool: def is_node_hard_macro(self, node_idx) -> bool:
return self.get_node_type(node_idx) == "hard_macro" """
Return None or return ref_id
"""
try:
return node_idx in self.hard_macro_indices
except IndexError:
print("[ERROR INDEX OUT OF RANGE] Can not process index at {}".format(node_idx))
exit(0)
def get_node_name(self, node_idx: int) -> str: def get_node_name(self, node_idx: int) -> str:
return self.indices_to_mod_name[node_idx] return self.indices_to_mod_name[node_idx]
...@@ -1440,7 +1459,7 @@ class PlacementCost(object): ...@@ -1440,7 +1459,7 @@ class PlacementCost(object):
def get_node_type(self, node_idx: int) -> str: def get_node_type(self, node_idx: int) -> str:
""" """
Return Vertical/Horizontal Macro Allocation Return node type
""" """
try: try:
return self.modules_w_pins[node_idx].get_type() return self.modules_w_pins[node_idx].get_type()
...@@ -1449,6 +1468,25 @@ class PlacementCost(object): ...@@ -1449,6 +1468,25 @@ class PlacementCost(object):
print("[INDEX OUT OF RANGE WARNING] Can not process index at {}".format(node_idx)) print("[INDEX OUT OF RANGE WARNING] Can not process index at {}".format(node_idx))
return None return None
def get_node_width_height(self, node_idx: int):
"""
Return node dimension
"""
mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR NODE FIXED] Found {}. Only 'MACRO', 'macro', 'STDCELL'".format(mod.get_type())
+"'PORT' are considered to be fixable nodes")
exit(1)
except Exception:
print("[ERROR NODE FIXED] Could not find module by node index")
exit(1)
return mod.get_width(), mod.get_height()
def make_soft_macros_square(self): def make_soft_macros_square(self):
pass pass
...@@ -1599,14 +1637,62 @@ class PlacementCost(object): ...@@ -1599,14 +1637,62 @@ class PlacementCost(object):
return macro_adj, sorted(cell_location) return macro_adj, sorted(cell_location)
def is_node_fixed(self): def is_node_fixed(self, node_idx: int):
pass mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR NODE FIXED] Found {}. Only 'MACRO', 'macro', 'STDCELL'".format(mod.get_type())
+"'PORT' are considered to be fixable nodes")
exit(1)
except Exception:
print("[ERROR NODE FIXED] Could not find module by node index")
exit(1)
return mod.get_fix_flag()
def optimize_stdcells(self): def optimize_stdcells(self):
pass pass
def update_node_coords(self): def update_node_coords(self, node_idx, x_pos, y_pos):
pass """
Update Node location if node is 'MACRO', 'macro', 'STDCELL', 'PORT'
"""
mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR NODE LOCATION] Found {}. Only 'MACRO', 'macro', 'STDCELL'".format(mod.get_type())
+"'PORT' are considered to be placable nodes")
exit(1)
except Exception:
print("[ERROR NODE LOCATION] Could not find module by node index")
exit(1)
mod.set_pos(x_pos, y_pos)
def update_macro_orientation(self, node_idx, orientation):
"""
Update macro orientation if node is 'MACRO', 'macro'
"""
mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro']
except AssertionError:
print("[ERROR MACRO ORIENTATION] Found {}. Only 'MACRO', 'macro'".format(mod.get_type())
+" are considered to be ORIENTED")
exit(1)
except Exception:
print("[ERROR MACRO ORIENTATION] Could not find module by node index")
exit(1)
mod.set_orientation(orientation)
def update_port_sides(self): def update_port_sides(self):
pass pass
...@@ -1615,31 +1701,110 @@ class PlacementCost(object): ...@@ -1615,31 +1701,110 @@ class PlacementCost(object):
pass pass
def get_node_location(self, node_idx): def get_node_location(self, node_idx):
pass """
Return Node location if node is 'MACRO', 'macro', 'STDCELL', 'PORT'
"""
mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR NODE LOCATION] Found {}. Only 'MACRO', 'macro', 'STDCELL'".format(mod.get_type())
+"'PORT' are considered to be placable nodes")
exit(1)
except Exception:
print("[ERROR NODE PLACED] Could not find module by node index")
exit(1)
return mod.get_pos()
def get_grid_cell_of_node(self, node_idx): def get_grid_cell_of_node(self, node_idx):
""" if grid_cell at grid crossing, break-tie to upper right """ if grid_cell at grid crossing, break-tie to upper right
""" """
return self.modules_w_pins(node_idx).get_location() mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro']
except AssertionError:
print("[ERROR NODE LOCATION] Found {}. Only 'MACRO', 'macro'".format(mod.get_type())
+" can be called")
exit(1)
except Exception:
print("[ERROR NODE LOCATION] Could not find module by node index")
exit(1)
row, col = self.__get_grid_cell_location(*mod.get_pos())
def update_macro_orientation(self, node_idx, orientation): return row * self.grid_col + col
pass
def get_macro_orientation(self): def get_macro_orientation(self, node_idx):
pass mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro']
except AssertionError:
print("[ERROR MACRO ORIENTATION] Found {}. Only 'MACRO', 'macro'".format(mod.get_type())
+" are considered to be ORIENTED")
exit(1)
except Exception:
print("[ERROR MACRO ORIENTATION] Could not find module by node index")
exit(1)
return mod.get_orientation()
def unfix_node_coord(self): def unfix_node_coord(self, node_idx):
"""In case plc is loaded with fixed macros
""" """
pass Unfix a module
"""
mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR UNFIX NODE] Found {}. Only 'MACRO', 'macro', 'STDCELL'".format(mod.get_type())
+"'PORT' are considered to be fixable nodes")
exit(1)
except Exception:
print("[ERROR UNFIX NODE] Could not find module by node index")
exit(1)
self.modules_w_pins[node_idx].set_fix_flag(False)
def fix_node_coord(self, node_idx): def fix_node_coord(self, node_idx):
"""
Fix a module
"""
mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR FIX NODE] Found {}. Only 'MACRO', 'macro', 'STDCELL'".format(mod.get_type())
+"'PORT' are considered to be fixable nodes")
exit(1)
except Exception:
print("[ERROR FIX NODE] Could not find module by node index")
exit(1)
self.modules_w_pins[node_idx].set_fix_flag(True) self.modules_w_pins[node_idx].set_fix_flag(True)
def unplace_all_nodes(self): def unplace_all_nodes(self):
pass pass
def place_node(self, node_idx, grid_cell_idx): def place_node(self, node_idx, grid_cell_idx):
mod = None
try:
mod = self.modules_w_pins[node_idx]
except AssertionError:
pass
except Exception:
pass
pass pass
def can_place_node(self, node_idx, grid_cell_idx): def can_place_node(self, node_idx, grid_cell_idx):
...@@ -1650,7 +1815,21 @@ class PlacementCost(object): ...@@ -1650,7 +1815,21 @@ class PlacementCost(object):
pass pass
def is_node_placed(self, node_idx): def is_node_placed(self, node_idx):
pass mod = None
try:
mod = self.modules_w_pins[node_idx]
assert mod.get_type() in ['MACRO', 'macro', 'STDCELL', 'PORT']
except AssertionError:
print("[ERROR NODE PLACED] Found {}. Only 'MACRO', 'STDCELL',".format(mod.get_type())
+"'PORT' are considered to be placable nodes")
exit(1)
except Exception:
print("[ERROR NODE PLACED] Could not find module by node index")
exit(1)
mod = self.modules_w_pins[node_idx]
return mod.get_placed_flag()
def disconnect_nets(self): def disconnect_nets(self):
pass pass
...@@ -1661,7 +1840,7 @@ class PlacementCost(object): ...@@ -1661,7 +1840,7 @@ class PlacementCost(object):
return self.netlist_file return self.netlist_file
def get_blockages(self): def get_blockages(self):
pass return self.blockages
def create_blockage(self, minx, miny, maxx, maxy, blockage_rate): def create_blockage(self, minx, miny, maxx, maxy, blockage_rate):
self.blockages.append([minx, miny, maxx, maxy, blockage_rate]) self.blockages.append([minx, miny, maxx, maxy, blockage_rate])
...@@ -1678,8 +1857,32 @@ class PlacementCost(object): ...@@ -1678,8 +1857,32 @@ class PlacementCost(object):
return self.mod_name_to_indices[pin.get_macro_name()] return self.mod_name_to_indices[pin.get_macro_name()]
return -1 return -1
def save_placement(self): def save_placement(self, filename, info):
pass """
When writing out info line-by-line, add a "#" at front
"""
with open(filename, 'w+') as f:
for line in info.split('\n'):
f.write("# " + line + '\n')
# if first, no \newline
HEADER = True
for mod_idx in sorted(self.hard_macro_indices + self.soft_macro_indices + self.port_indices):
# [node_index] [x] [y] [orientation] [fixed]
mod = self.modules_w_pins[mod_idx]
if HEADER:
f.write("{} {:g} {:g} {} {}".format(mod_idx,
*mod.get_pos(),
mod.get_orientation() if mod.get_orientation() else "-",
"1" if mod.get_fix_flag() else "0"))
HEADER = False
else:
f.write("\n{} {:g} {:g} {} {}".format(mod_idx,
*mod.get_pos(),
mod.get_orientation() if mod.get_orientation() else "-",
"1" if mod.get_fix_flag() else "0"))
def display_canvas( self, def display_canvas( self,
annotate=True, annotate=True,
...@@ -1740,9 +1943,14 @@ class PlacementCost(object): ...@@ -1740,9 +1943,14 @@ class PlacementCost(object):
self.connection = {} # [module_name] => edge degree self.connection = {} # [module_name] => edge degree
self.fix_flag = True self.fix_flag = True
self.placement = 0 # needs to be updated self.placement = 0 # needs to be updated
self.orientation = None
self.ifPlaced = True
def get_name(self): def get_name(self):
return self.name return self.name
def get_orientation(self):
return self.orientation
def add_connection(self, module_name): def add_connection(self, module_name):
# NOTE: assume PORT names does not contain slash # NOTE: assume PORT names does not contain slash
...@@ -1813,6 +2021,12 @@ class PlacementCost(object): ...@@ -1813,6 +2021,12 @@ class PlacementCost(object):
def get_fix_flag(self): def get_fix_flag(self):
return self.fix_flag return self.fix_flag
def set_placed_flag(self, ifPlaced):
self.ifPlaced = ifPlaced
def get_placed_flag(self):
return self.ifPlaced
class SoftMacro: class SoftMacro:
def __init__(self, name, width, height, x = 0.0, y = 0.0): def __init__(self, name, width, height, x = 0.0, y = 0.0):
self.name = name self.name = name
...@@ -1860,7 +2074,7 @@ class PlacementCost(object): ...@@ -1860,7 +2074,7 @@ class PlacementCost(object):
return self.x, self.y return self.x, self.y
def get_type(self): def get_type(self):
return "macro" return "MACRO"
def get_connection(self): def get_connection(self):
return self.connection return self.connection
...@@ -1892,11 +2106,18 @@ class PlacementCost(object): ...@@ -1892,11 +2106,18 @@ class PlacementCost(object):
def get_fix_flag(self): def get_fix_flag(self):
return self.fix_flag return self.fix_flag
def set_placed_flag(self, ifPlaced):
self.ifPlaced = ifPlaced
def get_placed_flag(self):
return self.ifPlaced
class SoftMacroPin: class SoftMacroPin:
def __init__( self, name, def __init__(self, name, ref_id,
x = 0.0, y = 0.0, x = 0.0, y = 0.0,
macro_name = "", weight = 1.0): macro_name = "", weight = 1.0):
self.name = name self.name = name
self.ref_id = ref_id
self.x = float(x) self.x = float(x)
self.y = float(y) self.y = float(y)
self.x_offset = 0.0 # not used self.x_offset = 0.0 # not used
...@@ -1908,6 +2129,12 @@ class PlacementCost(object): ...@@ -1908,6 +2129,12 @@ class PlacementCost(object):
def set_weight(self, weight): def set_weight(self, weight):
self.weight = weight self.weight = weight
def set_ref_id(self, ref_id):
self.ref_id = ref_id
def get_ref_id(self):
return self.ref_id
def get_weight(self): def get_weight(self):
return self.weight return self.weight
...@@ -1956,7 +2183,7 @@ class PlacementCost(object): ...@@ -1956,7 +2183,7 @@ class PlacementCost(object):
return self.weight return self.weight
def get_type(self): def get_type(self):
return "macro_pin" return "MACRO_PIN"
class HardMacro: class HardMacro:
def __init__(self, name, width, height, def __init__(self, name, width, height,
...@@ -2037,13 +2264,20 @@ class PlacementCost(object): ...@@ -2037,13 +2264,20 @@ class PlacementCost(object):
def get_fix_flag(self): def get_fix_flag(self):
return self.fix_flag return self.fix_flag
def set_placed_flag(self, ifPlaced):
self.ifPlaced = ifPlaced
def get_placed_flag(self):
return self.ifPlaced
class HardMacroPin: class HardMacroPin:
def __init__(self, name, def __init__(self, name, ref_id,
x = 0.0, y = 0.0, x = 0.0, y = 0.0,
x_offset = 0.0, y_offset = 0.0, x_offset = 0.0, y_offset = 0.0,
macro_name = "", weight = 1.0): macro_name = "", weight = 1.0):
self.name = name self.name = name
self.ref_id = ref_id
self.x = float(x) self.x = float(x)
self.y = float(y) self.y = float(y)
self.x_offset = float(x_offset) self.x_offset = float(x_offset)
...@@ -2053,6 +2287,12 @@ class PlacementCost(object): ...@@ -2053,6 +2287,12 @@ class PlacementCost(object):
self.sink = {} self.sink = {}
self.ifPlaced = True self.ifPlaced = True
def set_ref_id(self, ref_id):
self.ref_id = ref_id
def get_ref_id(self):
return self.ref_id
def set_weight(self, weight): def set_weight(self, weight):
self.weight = weight self.weight = weight
......
import numpy as np import numpy as np
import sys,os,traceback import sys,os,traceback
import argparse import argparse
import math import math,re
from absl import flags from absl import flags
from absl.flags import argparse_flags from absl.flags import argparse_flags
from absl import app from absl import app
from Plc_client import plc_client_os as plc_client_os from Plc_client import plc_client_os as plc_client_os
from Plc_client import placement_util_os as placement_util
try: try:
from Plc_client import plc_client as plc_client from Plc_client import plc_client as plc_client
except ImportError: except ImportError:
...@@ -28,10 +30,10 @@ Example: ...@@ -28,10 +30,10 @@ Example:
--height 356.640\ --height 356.640\
--col 35\ --col 35\
--row 33\ --row 33\
--rpmh 10\ --rpmh 70.330\
--rpmv 10\ --rpmv 74.510\
--marh 5\ --marh 51.790\
--marv 5\ --marv 51.790\
--smooth 2 --smooth 2
$ python3 -m Plc_client.plc_client_os_test --netlist ./Plc_client/test/ariane133/netlist.pb.txt\ $ python3 -m Plc_client.plc_client_os_test --netlist ./Plc_client/test/ariane133/netlist.pb.txt\
...@@ -100,7 +102,6 @@ class PlacementCostTest(): ...@@ -100,7 +102,6 @@ class PlacementCostTest():
self.MARV = marv self.MARV = marv
self.SMOOTH = smooth self.SMOOTH = smooth
def test_metadata(self): def test_metadata(self):
print("############################ TEST METADATA ############################") print("############################ TEST METADATA ############################")
# Google's Binary Executable # Google's Binary Executable
...@@ -211,6 +212,9 @@ class PlacementCostTest(): ...@@ -211,6 +212,9 @@ class PlacementCostTest():
self.plc_os = plc_client_os.PlacementCost(netlist_file=self.NETLIST_PATH, self.plc_os = plc_client_os.PlacementCost(netlist_file=self.NETLIST_PATH,
macro_macro_x_spacing = 50, macro_macro_x_spacing = 50,
macro_macro_y_spacing = 50) macro_macro_y_spacing = 50)
self.plc.get_overlap_threshold()
print("overlap_threshold default", self.plc.get_overlap_threshold())
if self.PLC_PATH: if self.PLC_PATH:
print("[PLC FILE FOUND] Loading info from .plc file") print("[PLC FILE FOUND] Loading info from .plc file")
...@@ -232,16 +236,16 @@ class PlacementCostTest(): ...@@ -232,16 +236,16 @@ class PlacementCostTest():
self.plc.set_congestion_smooth_range(self.SMOOTH) self.plc.set_congestion_smooth_range(self.SMOOTH)
self.plc_os.set_congestion_smooth_range(self.SMOOTH) self.plc_os.set_congestion_smooth_range(self.SMOOTH)
self.plc.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT) self.plc.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
self.plc.set_placement_grid(self.GRID_COL, self.GRID_ROW) self.plc.set_placement_grid(self.GRID_COL, self.GRID_ROW)
self.plc_os.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT) self.plc_os.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
self.plc_os.set_placement_grid(self.GRID_COL, self.GRID_ROW) self.plc_os.set_placement_grid(self.GRID_COL, self.GRID_ROW)
# TODO: [IGNORE] Setting blockage has no effect on proxy cost computation # TODO: [IGNORE] create_blockage must be defined BEFORE set_canvas_size and set_placement_grid in order to be considered on the canvas
if False: if False:
self.plc.create_blockage(0, 0, 400, 400, 1) self.plc.create_blockage(0.0, 100.0, 300.0, 300.0, 1.0)
self.plc.create_blockage(0, 0, 200, 200, 1) self.plc.create_blockage(300,0,500,200,1)
print(self.plc.get_blockages()) print(self.plc.get_blockages())
print(self.plc.make_soft_macros_square()) print(self.plc.make_soft_macros_square())
print(self.plc.set_use_incremental_cost(True)) print(self.plc.set_use_incremental_cost(True))
...@@ -257,7 +261,9 @@ class PlacementCostTest(): ...@@ -257,7 +261,9 @@ class PlacementCostTest():
# Density # Density
try: try:
print(self.plc_os.get_density_cost())
assert int(sum(self.plc_os.get_grid_cells_density())) == int(sum(self.plc.get_grid_cells_density())) assert int(sum(self.plc_os.get_grid_cells_density())) == int(sum(self.plc.get_grid_cells_density()))
print(self.plc_os.get_density_cost())
assert int(self.plc_os.get_density_cost()) == int(self.plc.get_density_cost()) assert int(self.plc_os.get_density_cost()) == int(self.plc.get_density_cost())
except Exception as e: except Exception as e:
print("[DENSITY ERROR] Discrepancies found when computing density -- {}, {}".format(str(self.plc.get_density_cost()), self.plc_os.get_density_cost())) print("[DENSITY ERROR] Discrepancies found when computing density -- {}, {}".format(str(self.plc.get_density_cost()), self.plc_os.get_density_cost()))
...@@ -265,8 +271,10 @@ class PlacementCostTest(): ...@@ -265,8 +271,10 @@ class PlacementCostTest():
# Congestion # Congestion
try: try:
print(self.plc_os.get_congestion_cost())
assert abs(sum(self.plc_os.get_horizontal_routing_congestion()) - sum(self.plc.get_horizontal_routing_congestion())) < 1e-3 assert abs(sum(self.plc_os.get_horizontal_routing_congestion()) - sum(self.plc.get_horizontal_routing_congestion())) < 1e-3
assert abs(sum(self.plc_os.get_vertical_routing_congestion()) - sum(self.plc.get_vertical_routing_congestion())) < 1e-3 assert abs(sum(self.plc_os.get_vertical_routing_congestion()) - sum(self.plc.get_vertical_routing_congestion())) < 1e-3
print(self.plc_os.get_congestion_cost())
assert abs(self.plc.get_congestion_cost() - self.plc_os.get_congestion_cost()) < 1e-3 assert abs(self.plc.get_congestion_cost() - self.plc_os.get_congestion_cost()) < 1e-3
except Exception as e: except Exception as e:
print("[CONGESTION ERROR] Discrepancies found when computing congestion -- {}".format(str(e))) print("[CONGESTION ERROR] Discrepancies found when computing congestion -- {}".format(str(e)))
...@@ -287,19 +295,19 @@ class PlacementCostTest(): ...@@ -287,19 +295,19 @@ class PlacementCostTest():
self.plc.set_placement_grid(self.GRID_COL, self.GRID_ROW) self.plc.set_placement_grid(self.GRID_COL, self.GRID_ROW)
self.plc_os.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT) self.plc_os.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
self.plc_os.set_placement_grid(self.GRID_COL, self.GRID_ROW) self.plc_os.set_placement_grid(self.GRID_COL, self.GRID_ROW)
NODE_IDX = 0 NODE_IDX = 22853
print("get_macro_indices", self.plc.get_macro_indices(), self.plc_os.get_macro_indices()) print("get_macro_indices", self.plc.get_macro_indices())
print("get_node_name", self.plc.get_node_name(NODE_IDX)) print("get_node_name", self.plc.get_node_name(NODE_IDX))
print("get_node_type", self.plc.get_node_type(NODE_IDX))
print("get_node_location", self.plc.get_node_location(NODE_IDX)) print("get_node_location", self.plc.get_node_location(NODE_IDX))
print("get_grid_cell_of_node", self.plc.get_grid_cell_of_node(NODE_IDX)) print("get_grid_cell_of_node", self.plc.get_grid_cell_of_node(NODE_IDX))
print("get_node_location", self.plc.get_node_location(NODE_IDX))
print("get_macro_orientation", self.plc.get_macro_orientation(NODE_IDX)) print("get_macro_orientation", self.plc.get_macro_orientation(NODE_IDX))
print("is_node_placed", self.plc.is_node_placed(NODE_IDX)) print("is_node_placed", self.plc.is_node_placed(NODE_IDX))
print("get_source_filename", self.plc.get_source_filename()) print("get_source_filename", self.plc.get_source_filename())
print("get_blockages", self.plc.get_blockages()) print("get_blockages", self.plc.get_blockages())
print("get_ref_node_id", self.plc.get_ref_node_id(NODE_IDX), self.plc.get_ref_node_id(NODE_IDX)) print("get_ref_node_id", self.plc.get_ref_node_id(NODE_IDX), self.plc.get_ref_node_id(NODE_IDX))
print("get_node_mask\n", np.array(self.plc.get_node_mask(NODE_IDX)).reshape((4,4))) # print("get_node_mask\n", np.array(self.plc.get_node_mask(NODE_IDX)).reshape((4,4)))
print("can_place_node", self.plc.can_place_node(0, 1)) # print("can_place_node", self.plc.can_place_node(0, 1))
print("***************************************************") print("***************************************************")
def test_proxy_congestion(self): def test_proxy_congestion(self):
...@@ -375,6 +383,87 @@ class PlacementCostTest(): ...@@ -375,6 +383,87 @@ class PlacementCostTest():
print("**************BY ENTRY DIFF") print("**************BY ENTRY DIFF")
print(temp_gl_h_mc[0][6], temp_os_h_mc[0][6]) print(temp_gl_h_mc[0][6], temp_os_h_mc[0][6])
def test_placement_util(self, keep_save_file=False):
"""
* Read same input, perturb placement and orientation, write to new .plc
"""
print("############################ TEST PLACEMENT UTIL ############################")
try:
assert self.PLC_PATH
except AssertionError:
print("[ERROR PLACEMENT UTIL TEST] Facilitate required .plc file")
self.plc_util = placement_util.create_placement_cost(
plc_client=plc_client,
netlist_file=self.NETLIST_PATH,
init_placement=self.PLC_PATH
)
self.plc_util_os = placement_util.create_placement_cost(
plc_client=plc_client_os,
netlist_file=self.NETLIST_PATH,
init_placement=self.PLC_PATH
)
# ********************** plc_client_os **********************
# node_xy_coordinates
# NODE_XY_DICT = {}
# for i in placement_util.nodes_of_types(self.plc_util_os, ['MACRO', 'STDCELL', 'PORT']):
# NODE_XY_DICT[i] = (100, 100)
# placement_util.restore_node_xy_coordinates(self.plc_util_os, NODE_XY_DICT)
# macro_orientation
MACRO_ORIENTATION = {}
for i in placement_util.nodes_of_types(self.plc_util_os, ['MACRO']):
MACRO_ORIENTATION[i] = "S"
placement_util.restore_macro_orientations(self.plc_util_os, MACRO_ORIENTATION)
# fix ports
placement_util.fix_port_coordinates(self.plc_util_os)
# write out new plc
placement_util.save_placement(self.plc_util_os, "save_test_os.plc", 'this is a comment')
# ********************** plc_client **********************
# # node_xy_coordinates
# NODE_XY_DICT = {}
# for i in placement_util.nodes_of_types(self.plc_util, ['MACRO', 'STDCELL', 'PORT']):
# NODE_XY_DICT[i] = (100, 100)
# placement_util.restore_node_xy_coordinates(self.plc_util, NODE_XY_DICT)
# macro_orientation
MACRO_ORIENTATION = {}
for i in placement_util.nodes_of_types(self.plc_util, ['MACRO']):
MACRO_ORIENTATION[i] = "S"
placement_util.restore_macro_orientations(self.plc_util, MACRO_ORIENTATION)
# fix ports
placement_util.fix_port_coordinates(self.plc_util)
# write out new plc
placement_util.save_placement(self.plc_util, "save_test_gl.plc", 'this is a comment')
print(" +++++++++++++++++++++++++++++++++")
print(" +++ TEST PLACEMENT UTIL: PASS +++")
print(" +++++++++++++++++++++++++++++++++")
# This is only for node information, line-by-line test
try:
with open('save_test_gl.plc') as f1, open('save_test_os.plc') as f2:
for idx, (line1, line2) in enumerate(zip(f1, f2)):
if line1.strip() != line2.strip():
if not re.match(r"(# )\w+", line1.strip()):
print("PLC MISMATCH (GL, OS)\n", line1.strip(), "\n", line2.strip())
raise AssertionError ("false")
except AssertionError:
print("[ERROR PLACEMENT UTIL] Saved PLC Discrepency found at line {}".format(str(idx)))
def test_environment(self):
pass
def parse_flags(argv): def parse_flags(argv):
parser = argparse_flags.ArgumentParser(description='An argparse + app.run example') parser = argparse_flags.ArgumentParser(description='An argparse + app.run example')
parser.add_argument("--netlist", required=True, parser.add_argument("--netlist", required=True,
...@@ -400,18 +489,36 @@ def parse_flags(argv): ...@@ -400,18 +489,36 @@ def parse_flags(argv):
parser.add_argument("--smooth", type=float, default=1, required=False, parser.add_argument("--smooth", type=float, default=1, required=False,
help="Grid row") help="Grid row")
return parser.parse_args(argv[1:]) return parser.parse_args(argv[1:])
def main(args): def main(args):
if args.plc: if args.plc:
PCT = PlacementCostTest(args.netlist, args.plc, args.width, args.height, PCT = PlacementCostTest(NETLIST_PATH=args.netlist,
args.col, args.row, args.rpmv, args.rpmv, PLC_PATH=args.plc,
args.marh, args.marv, args.smooth) width=args.width,
height=args.height,
column=args.col,
row=args.row,
rpmv=args.rpmv,
rpmh=args.rpmh,
marh=args.marh,
marv=args.marv,
smooth=args.smooth)
else: else:
PCT = PlacementCostTest(args.netlist, args.width, args.height, PCT = PlacementCostTest(NETLIST_PATH=args.netlist,
args.col, args.row, args.rpmv, args.rpmv, width=args.width,
args.marh, args.marv, args.smooth) height=args.height,
PCT.test_metadata() column=args.col,
row=args.row,
rpmv=args.rpmv,
rpmh=args.rpmh,
marh=args.marh,
marv=args.marv,
smooth=args.smooth)
# PCT.test_metadata()
PCT.test_proxy_cost() PCT.test_proxy_cost()
PCT.test_placement_util()
# PCT.test_miscellaneous()
if __name__ == '__main__': if __name__ == '__main__':
app.run(main, flags_parser=parse_flags) app.run(main, flags_parser=parse_flags)
\ No newline at end of file
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