Xplace_for_ICCAD/src/evaluator.py

67 lines
2.6 KiB
Python
Raw Normal View History

2022-10-20 22:46:17 +08:00
import torch
from .database import PlaceData
2023-04-06 13:34:26 +08:00
from .core import masked_scale_hpwl
from cpp_to_py import hpwl_cuda
2022-10-20 22:46:17 +08:00
2023-04-06 13:34:26 +08:00
def get_hpwl(data, pos):
# CUDA only
hpwl = hpwl_cuda.hpwl(pos, data.hyperedge_list, data.hyperedge_list_end)
return (
torch.round(hpwl * (data.die_scale / data.site_width)).sum(axis=1).unsqueeze(1)
)
2022-10-20 22:46:17 +08:00
2023-04-06 13:34:26 +08:00
def get_obj_hpwl(node_pos, data: PlaceData, args):
2022-10-20 22:46:17 +08:00
mov_lhs, mov_rhs = data.movable_index
fix_lhs, fix_rhs = data.fixed_connected_index
conn_node_pos = torch.cat([
node_pos[mov_lhs:mov_rhs], node_pos[fix_lhs:fix_rhs]
], dim=0)
2023-04-06 13:34:26 +08:00
with torch.no_grad():
pin_pos = hpwl_cuda.node_pos_to_pin_pos(
conn_node_pos, data.pin_id2node_id, data.pin_rel_cpos
)
hpwl = torch.sum(get_hpwl(data, pin_pos.detach()))
return hpwl
def get_obj_overflow(node_pos, density_map_layer, init_density_map, data: PlaceData, args):
mov_lhs, mov_rhs = data.movable_index
2022-10-20 22:46:17 +08:00
density_map = density_map_layer.get_density_map_naive(
node_pos[mov_lhs:mov_rhs], data.node_size[mov_lhs:mov_rhs], init_density_map
)
2023-04-06 13:34:26 +08:00
with torch.no_grad():
overflow_sum = ((density_map - args.target_density) * data.bin_area).clamp_(min=0.0).sum()
overflow = overflow_sum / data.total_mov_area_without_filler
return overflow
def evaluate_placement(node_pos, density_map_layer, init_density_map, data: PlaceData, args):
# NOTE: since some nets are masked in global placement, hpwl may
# underestimate, this function return the exact value of hpwl
# Original overflow calculation uses the clamp node size (expand ratio),
# this function uses the exact node size to evaluate the overflow
hpwl = get_obj_hpwl(node_pos, data, args)
overflow = get_obj_overflow(node_pos, density_map_layer, init_density_map, data, args)
2022-10-20 22:46:17 +08:00
return hpwl, overflow
def fast_evaluator(
mov_node_pos,
constraint_fn=None,
mov_node_size=None,
init_density_map=None,
density_map_layer=None,
conn_fix_node_pos=None,
ps=None,
data=None,
args=None,
):
mov_lhs, mov_rhs = data.movable_index
mov_node_pos = constraint_fn(mov_node_pos)
conn_node_pos = mov_node_pos[mov_lhs:mov_rhs, ...]
conn_node_pos = torch.cat([conn_node_pos, conn_fix_node_pos], dim=0)
masked_hpwl = masked_scale_hpwl(
conn_node_pos, data.pin_id2node_id, data.pin_rel_cpos,
data.hyperedge_list, data.hyperedge_list_end, data.net_mask, data.hpwl_scale
)
overflow = density_map_layer.direct_calc_overflow(
mov_node_pos, mov_node_size, init_density_map
)
return masked_hpwl, overflow