Commit da3ae6a0 by Dinple

debugging on density + optimization

parent 46970f7b
......@@ -611,19 +611,21 @@ class PlacementCost(object):
macro = self.modules_w_pins[macro_idx]
macro_name = macro.get_name()
# Hard macro
if not self.is_node_soft_macro(macro_idx):
if macro_name in self.hard_macros_to_inpins.keys():
pin_names = self.hard_macros_to_inpins[macro_name]
else:
print("[ERROR UPDATE CONNECTION] MACRO not found")
exit(1)
# use is_node_soft_macro()
print("[ERROR UPDATE CONNECTION] MACRO pins not found")
continue
# Soft macro
elif self.is_node_soft_macro(macro_idx):
if macro_name in self.soft_macros_to_inpins.keys():
pin_names = self.soft_macros_to_inpins[macro_name]
else:
print("[ERROR UPDATE CONNECTION] MACRO not found")
exit(1)
print("[ERROR UPDATE CONNECTION] macro pins not found")
continue
for pin_name in pin_names:
pin = self.modules_w_pins[self.mod_name_to_indices[pin_name]]
......@@ -697,11 +699,14 @@ class PlacementCost(object):
if self.modules_w_pins[pin_idx].get_type() == 'PORT':
return self.modules_w_pins[pin_idx].get_pos()
else:
print("[ERROR PIN POSITION] Parent Node Not Found.")
exit(1)
# Parent node
ref_node = self.modules_w_pins[ref_node_idx]
ref_node_x, ref_node_y = ref_node.get_pos()
# Retrieve current pin node position
pin_node = self.modules_w_pins[pin_idx]
pin_node_x_offset, pin_node_y_offset = pin_node.get_offset()
......@@ -724,8 +729,9 @@ class PlacementCost(object):
# NOTE: connection only defined on PORT, soft/hard macro pins
if curr_type == "PORT" and mod.get_sink():
# add source position
x_coord.append(self.__get_pin_position(mod_idx)[0])
y_coord.append(self.__get_pin_position(mod_idx)[1])
x_coord.append(mod.get_pos()[0])
y_coord.append(mod.get_pos()[1])
# get sink
for sink_name in mod.get_sink():
for sink_pin in mod.get_sink()[sink_name]:
# retrieve indx in modules_w_pins
......@@ -881,16 +887,6 @@ class PlacementCost(object):
self.node_mask[ row - ver_pad:row + ver_pad + 1,
col - hor_pad:col + hor_pad + 1] = 0
def __unplace_node_mask(self, grid_cell_idx:int):
"""
private function: for updating node mask after unplacing a node
"""
row = grid_cell_idx // self.grid_col
col = grid_cell_idx % self.grid_col
assert row * self.grid_col + col == grid_cell_idx
pass
def __overlap_area(self, block_i, block_j, return_pos=False):
"""
private function: for computing block overlapping
......@@ -972,6 +968,8 @@ class PlacementCost(object):
self.grid_occupied[self.grid_col * r_i + c_i] += \
self.__overlap_area(grid_cell_block, module_block)
def get_grid_cells_density(self):
"""
......@@ -988,6 +986,11 @@ class PlacementCost(object):
for module_idx in (self.soft_macro_indices + self.hard_macro_indices):
# extract module information
module = self.modules_w_pins[module_idx]
# skipping unplaced module
if not module.get_placed_flag():
continue
module_h = module.get_height()
module_w = module.get_width()
module_x, module_y = module.get_pos()
......@@ -1714,8 +1717,10 @@ class PlacementCost(object):
def make_soft_macros_square(self):
"""
[IGNORE] THIS DOES NOT AFFECT DENSITY. SHOULD WE IMPLEMENT THIS AT ALL?
make soft macros as squares
"""
return
for mod_idx in self.soft_macro_indices:
mod = self.modules_w_pins[mod_idx]
mod_area = mod.get_width() * mod.get_height()
......@@ -2200,7 +2205,8 @@ class PlacementCost(object):
pass
def get_source_filename(self):
"""return netlist path
"""
return netlist path
"""
return self.netlist_file
......@@ -2211,20 +2217,18 @@ class PlacementCost(object):
self.blockages.append([minx, miny, maxx, maxy, blockage_rate])
def get_ref_node_id(self, node_idx=-1):
"""ref_node_id is used for macro_pins. Refers to the macro it belongs to.
"""
ref_node_id is used for macro_pins. Refers to the macro it belongs to.
"""
if node_idx != -1:
if node_idx in self.soft_macro_pin_indices:
pin = self.modules_w_pins[node_idx]
return self.mod_name_to_indices[pin.get_macro_name()]
elif node_idx in self.hard_macro_pin_indices:
if node_idx in self.soft_macro_pin_indices or node_idx in self.hard_macro_pin_indices:
pin = self.modules_w_pins[node_idx]
return self.mod_name_to_indices[pin.get_macro_name()]
return -1
def save_placement(self, filename, info=""):
"""
When writing out info line-by-line, add a "#" at front
When writing out info line-by-line, add a "#" at front
"""
with open(filename, 'w+') as f:
for line in info.split('\n'):
......@@ -2252,6 +2256,9 @@ class PlacementCost(object):
def display_canvas( self,
annotate=True,
amplify=False):
"""
Non-google function, For quick canvas view
"""
#define Matplotlib figure and axis
fig, ax = plt.subplots(figsize=(8,8), dpi=50)
......
......@@ -58,7 +58,6 @@ Example:
--smooth 2
$ python3 -m Plc_client.plc_client_os_test --netlist ./Plc_client/test/0P2M0m/netlist.pb.txt\
--plc ./Plc_client/test/0P2M0m/initial.plc\
--width 500\
--height 500\
--col 5\
......@@ -272,8 +271,8 @@ class PlacementCostTest():
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.make_soft_macros_square()
# self.plc_os.make_soft_macros_square()
self.plc.make_soft_macros_square()
self.plc_os.make_soft_macros_square()
# [IGNORE] create_blockage must be defined BEFORE set_canvas_size
# and set_placement_grid in order to be considered on the canvas
......@@ -285,28 +284,20 @@ class PlacementCostTest():
print(self.plc.set_use_incremental_cost(True))
print(self.plc_os.get_soft_macros_count())
# self.plc_os.display_canvas(annotate=False)
# HPWL
try:
assert int(self.plc_os.get_wirelength()) == int(self.plc.get_wirelength())
assert abs(self.plc.get_cost() - self.plc_os.get_cost()) <= 1e-3
print("#[INFO WIRELENGTH] Matched irelength cost -- GL {}, OS {}".format(
assert abs(self.plc.get_cost() - self.plc_os.get_cost()) <= 1e-2
print("#[INFO WIRELENGTH] Matched Wirelength cost -- GL {}, OS {}".format(
str(self.plc.get_cost()), self.plc_os.get_cost()))
except Exception as e:
print("[ERROR WIRELENGTH] Discrepancies found when computing wirelength -- GL {}, OS {}".format(
str(self.plc.get_cost()), self.plc_os.get_cost()))
soft_macro_indices = [
m for m in self.plc.get_macro_indices() if self.plc.is_node_soft_macro(m)
]
for mod_idx in soft_macro_indices:
self.plc_os.unplace_node(mod_idx)
self.plc.unplace_node(mod_idx)
print("GL WIRELENGTH: ", self.plc.get_wirelength())
print("OS WIRELENGTH: ", self.plc_os.get_wirelength())
# exit(1)
# self.plc_os.display_canvas(annotate=False)
exit(1)
# Density
try:
......@@ -326,7 +317,7 @@ class PlacementCostTest():
# NOTE: [IGNORE] grid-wise congestion not tested because
# miscellaneous implementation differences.
assert abs(self.plc.get_congestion_cost() -
self.plc_os.get_congestion_cost()) < 1e-3
self.plc_os.get_congestion_cost()) <= 1e-2
print("#[INFO CONGESTION] Matched congestion cost -- GL {}, OS {}".format(
str(self.plc.get_congestion_cost()), self.plc_os.get_congestion_cost()))
except Exception as e:
......@@ -340,6 +331,7 @@ class PlacementCostTest():
print(" +++++++++++++++++++++++++++++")
def test_miscellaneous(self):
print("****************** miscellaneous ******************")
# Google's Binary Executable
self.plc = plc_client.PlacementCost(self.NETLIST_PATH)
self.plc_os = plc_client_os.PlacementCost(netlist_file=self.NETLIST_PATH,
......@@ -362,7 +354,6 @@ class PlacementCostTest():
print(np.flip(np.array(self.plc_util.get_node_mask(0)).reshape(35, 33), axis=0))
print(np.flip(np.array(self.plc.get_node_mask(0)).reshape(35, 33), axis=0))
print("****************** miscellaneous ******************")
# self.plc.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
# self.plc.set_placement_grid(self.GRID_COL, self.GRID_ROW)
# self.plc_os.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
......@@ -382,6 +373,127 @@ class PlacementCostTest():
# print("can_place_node", self.plc.can_place_node(0, 1))
print("***************************************************")
def test_proxy_hpwl(self):
print("############################ TEST PROXY WIRELENGTH ############################")
# Google's Binary Executable
self.plc = plc_client.PlacementCost(self.NETLIST_PATH)
# Open-sourced Implementation
self.plc_os = plc_client_os.PlacementCost(netlist_file=self.NETLIST_PATH,
macro_macro_x_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:
print("#[PLC FILE FOUND] Loading info from .plc file")
self.plc_os.set_canvas_boundary_check(False)
self.plc_os.restore_placement(self.PLC_PATH,
ifInital=True,
ifValidate=True,
ifReadComment=False)
self.plc.set_canvas_boundary_check(False)
self.plc.restore_placement(self.PLC_PATH)
else:
print("#[PLC FILE MISSING] Using only netlist info")
self.plc.set_routes_per_micron(self.RPMH, self.RPMV)
self.plc_os.set_routes_per_micron(self.RPMH, self.RPMV)
self.plc.set_macro_routing_allocation(self.MARH, self.MARV)
self.plc_os.set_macro_routing_allocation(self.MARH, self.MARV)
self.plc.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_placement_grid(self.GRID_COL, self.GRID_ROW)
self.plc_os.set_canvas_size(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
self.plc_os.set_placement_grid(self.GRID_COL, self.GRID_ROW)
# HPWL
try:
assert int(self.plc_os.get_wirelength()) == int(self.plc.get_wirelength())
assert abs(self.plc.get_cost() - self.plc_os.get_cost()) <= 1e-2
print("#[INFO WIRELENGTH] Matched Wirelength cost -- GL {}, OS {}".format(
str(self.plc.get_cost()), self.plc_os.get_cost()))
except Exception as e:
print("[ERROR WIRELENGTH] Discrepancies found when computing wirelength -- GL {}, OS {}".format(
str(self.plc.get_cost()), self.plc_os.get_cost()))
# if remove all soft macros
# soft_macro_indices = [
# m for m in self.plc.get_macro_indices() if self.plc.is_node_soft_macro(m)
# ]
# for mod_idx in soft_macro_indices:
# self.plc_os.unplace_node(mod_idx)
# self.plc.unplace_node(mod_idx)
print("GL WIRELENGTH: ", self.plc.get_wirelength())
print("OS WIRELENGTH: ", self.plc_os.get_wirelength())
def test_proxy_density(self):
print("############################ TEST PROXY DENSITY ############################")
# Google's Binary Executable
self.plc = plc_client.PlacementCost(self.NETLIST_PATH)
# Open-sourced Implementation
self.plc_os = plc_client_os.PlacementCost(netlist_file=self.NETLIST_PATH,
macro_macro_x_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:
print("#[PLC FILE FOUND] Loading info from .plc file")
self.plc_os.set_canvas_boundary_check(False)
self.plc_os.restore_placement(self.PLC_PATH,
ifInital=True,
ifValidate=True,
ifReadComment=False)
self.plc.set_canvas_boundary_check(False)
self.plc.restore_placement(self.PLC_PATH)
else:
print("#[PLC FILE MISSING] Using only netlist info")
self.plc.set_routes_per_micron(self.RPMH, self.RPMV)
self.plc_os.set_routes_per_micron(self.RPMH, self.RPMV)
self.plc.set_macro_routing_allocation(self.MARH, self.MARV)
self.plc_os.set_macro_routing_allocation(self.MARH, self.MARV)
self.plc.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_placement_grid(self.GRID_COL, self.GRID_ROW)
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.make_soft_macros_square()
# self.plc_os.make_soft_macros_square()
# Density
try:
assert int(sum(self.plc_os.get_grid_cells_density())) == int(
sum(self.plc.get_grid_cells_density()))
assert int(self.plc_os.get_density_cost()) == int(
self.plc.get_density_cost())
print("#[INFO DENSITY] Matched density cost -- GL {}, OS {}".format(
str(self.plc.get_density_cost()), self.plc_os.get_density_cost()))
except Exception as e:
print("[ERROR DENSITY] Discrepancies found when computing density -- GL {}, OS {}".format(
str(self.plc.get_density_cost()), self.plc_os.get_density_cost()))
gl_density = self.plc.get_grid_cells_density()
os_density = self.plc_os.get_grid_cells_density()
for cell_idx, (gl_dens, os_des) in enumerate(zip(gl_density, os_density)):
print("PASS {}".format(str(cell_idx)) if abs(gl_dens - os_des) <= 1e-3 else "FAILED", gl_dens, os_des)
if cell_idx == 0:
break
self.plc_os.display_canvas(annotate=True, amplify=True)
def test_proxy_congestion(self):
# Google's API
self.plc = plc_client.PlacementCost(self.NETLIST_PATH)
......@@ -859,6 +971,7 @@ def main(args):
"""
# PCT.test_metadata()
PCT.test_proxy_cost()
# PCT.test_proxy_density()
# PCT.test_proxy_congestion()
# PCT.test_placement_util(keep_save_file=False)
# PCT.test_place_node()
......
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