Commit fb061310 by Dinple

first version of density cost function (WIP)

parent 19d47bef
"""Open-Sourced PlacementCost client class.""" """Open-Sourced PlacementCost client class."""
import os, io import os, io
import re import re
import math
from typing import Text, Tuple from typing import Text, Tuple
from absl import logging from absl import logging
from collections import namedtuple
Block = namedtuple('Block', 'x_max y_max x_min y_min')
# FLAGS = flags.FLAG # FLAGS = flags.FLAG
...@@ -28,8 +32,8 @@ class PlacementCost(object): ...@@ -28,8 +32,8 @@ class PlacementCost(object):
self.block_name = netlist_file.rsplit('/', -1)[-2] self.block_name = netlist_file.rsplit('/', -1)[-2]
self.width = 0.0 self.width = 0.0
self.height = 0.0 self.height = 0.0
self.grid_col = 0 self.grid_col = 10
self.grid_row = 0 self.grid_row = 10
self.hroutes_per_micron = 0.0 self.hroutes_per_micron = 0.0
self.vroutes_per_micron = 0.0 self.vroutes_per_micron = 0.0
self.smooth_range = 0.0 self.smooth_range = 0.0
...@@ -423,8 +427,110 @@ class PlacementCost(object): ...@@ -423,8 +427,110 @@ class PlacementCost(object):
def get_congestion_cost(self) -> float: def get_congestion_cost(self) -> float:
return 0.0 return 0.0
def __get_grid_cell_location(self, x_pos, y_pos):
# private function for getting grid cell row/col ranging from 0...N
row = math.floor(y_pos / self.grid_height)
col = math.floor(x_pos / self.grid_width)
return row, col
def __overlap_area(self, block_i, block_j):
# private function for computing block overlapping
x_diff = min(block_i.x_max, block_j.x_max) - max(block_i.x_min, block_j.x_min)
y_diff = min(block_i.y_max, block_j.y_max) - max(block_i.y_min, block_j.y_min)
if x_diff >= 0 and y_diff >= 0:
return x_diff * y_diff
return 0.0
def __add_module_to_grid_cells(self, mod_x, mod_y, mod_w, mod_h):
# private function for add module to grid cells
# row/col ranging from 0...N
row, col = self.__get_grid_cell_location(mod_x, mod_y)
# Four corners
ur = (mod_x + (mod_w/2), mod_y + (mod_h/2))
br = (mod_x + (mod_w/2), mod_y - (mod_h/2))
ul = (mod_x - (mod_w/2), mod_y + (mod_h/2))
bl = (mod_x - (mod_w/2), mod_y - (mod_h/2))
# construct block based on current module
module_block = Block(
x_max=mod_x + (mod_w/2),
y_max=mod_y + (mod_h/2),
x_min=mod_x - (mod_w/2),
y_min=mod_y - (mod_h/2)
)
print(ur, br, ul, bl)
# Four corner grid cells
ur_row, ur_col = self.__get_grid_cell_location(*ur)
br_row, br_col = self.__get_grid_cell_location(*br)
ul_row, ul_col = self.__get_grid_cell_location(*ul)
bl_row, bl_col = self.__get_grid_cell_location(*bl)
for r_i in range(bl_row, ur_row + 1):
for c_i in range(bl_col, ur_col + 1):
# construct block based on current cell row/col
grid_cell_block = Block(
x_max=(r_i + 1) * self.grid_height,
y_max=(c_i + 1) * self.grid_width,
x_min= r_i * self.grid_height,
y_min=c_i * self.grid_width
)
self.grid_occupied[self.grid_row * r_i + c_i] += \
self.__overlap_area(grid_cell_block, module_block)
def get_grid_cells_density(self):
# by default grid row/col is 10/10
self.grid_width = float(self.width/self.grid_col)
self.grid_height = float(self.height/self.grid_row)
grid_area = self.grid_width * self.grid_height
self.grid_occupied = [0] * (self.grid_col * self.grid_row)
self.grid_cells = [0] * (self.grid_col * self.grid_row)
for module_idx in (self.soft_macro_indices + self.hard_macro_indices):
module = self.modules_w_pins[module_idx]
module_h = module.get_height()
module_w = module.get_width()
module_x, module_y = module.get_pos()
self.__add_module_to_grid_cells(
mod_x=module_x,
mod_y=module_y,
mod_h=module_h,
mod_w=module_w
)
for i, gcell in enumerate(self.grid_occupied):
self.grid_cells[i] = gcell / grid_area
return self.grid_cells
def get_density_cost(self) -> float: def get_density_cost(self) -> float:
pass # run get_grid_cells_density first
occupied_cells = sorted([gc for gc in self.grid_cells if gc != 0.0], reverse=True)
density_cost = 0.0
# take top 10%
density_cnt = math.floor(len(self.grid_cells) * 0.1)
density_cnt = min(density_cnt, 10)
# if grid cell smaller than 10, take the average over occupied cells
if len(self.grid_cells) < 10:
density_cost = float(sum(occupied_cells) / len(occupied_cells))
return 0.5 * density_cost
idx = 0
sum_density = 0
# take top 10%
while idx < density_cnt and idx < len(occupied_cells):
sum_density += occupied_cells[idx]
idx += 1
return 0.5 * float(sum_density / density_cnt)
def set_canvas_size(self, width:float, height:float) -> float: def set_canvas_size(self, width:float, height:float) -> float:
""" """
...@@ -805,6 +911,12 @@ class PlacementCost(object): ...@@ -805,6 +911,12 @@ class PlacementCost(object):
def get_area(self): def get_area(self):
return self.width * self.height return self.width * self.height
def get_height(self):
return self.height
def get_width(self):
return self.width
class SoftMacroPin: class SoftMacroPin:
def __init__(self, name, def __init__(self, name,
...@@ -919,6 +1031,12 @@ class PlacementCost(object): ...@@ -919,6 +1031,12 @@ class PlacementCost(object):
def get_area(self): def get_area(self):
return self.width * self.height return self.width * self.height
def get_height(self):
return self.height
def get_width(self):
return self.width
class HardMacroPin: class HardMacroPin:
def __init__(self, name, def __init__(self, name,
...@@ -980,3 +1098,32 @@ class PlacementCost(object): ...@@ -980,3 +1098,32 @@ class PlacementCost(object):
def get_type(self): def get_type(self):
return "MACRO_PIN" return "MACRO_PIN"
def main():
test_netlist_dir = './Plc_client/test/ariane'
netlist_file = os.path.join(test_netlist_dir,
'netlist.pb.txt')
plc = PlacementCost(netlist_file)
print(plc.get_block_name())
print("Area: ", plc.get_area())
print("Wirelength: ", plc.get_wirelength())
print("# HARD_MACROs : %d"%(plc.get_hard_macro_count()))
print("# HARD_MACRO_PINs : %d"%(plc.get_hard_macro_pin_count()))
print("# MACROs : %d"%(plc.get_hard_macro_count() + plc.get_soft_macro_count()))
print("# MACRO_PINs : %d"%(plc.get_hard_macro_pin_count() + plc.get_soft_macro_pin_count()))
print("# PORTs : %d"%(plc.get_port_count()))
print("# SOFT_MACROs : %d"%(plc.get_soft_macro_count()))
print("# SOFT_MACRO_PINs : %d"%(plc.get_soft_macro_pin_count()))
print("# STDCELLs : 0")
# print(adj[137])
# print(np.unique(adj))
print(plc.set_canvas_size(356.592, 356.640))
print(plc.set_placement_grid(35, 33))
print(plc.get_grid_cells_density())
print(plc.get_density_cost())
if __name__ == '__main__':
main()
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