update with PG info
This commit is contained in:
parent
a0e5b23cf7
commit
59ff5693e4
@ -66,6 +66,7 @@ void bindGPDatabase(pybind11::module& m) {
|
||||
.def("hyperedge_info_tensor", &gp::GPDatabase::getHyperedgeInfoTensor, py::return_value_policy::move)
|
||||
.def("node2pin_info_tensor", &gp::GPDatabase::getNode2PinInfoTensor, py::return_value_policy::move)
|
||||
.def("region_info_tensor", &gp::GPDatabase::getRegionInfoTensor, py::return_value_policy::move)
|
||||
.def("snet_info_tensor", &gp::GPDatabase::getSnetInfoTensor, py::return_value_policy::move)
|
||||
.def("apply_node_cpos", &gp::GPDatabase::applyNodeCPos)
|
||||
.def("apply_node_lpos", &gp::GPDatabase::applyNodeLPos)
|
||||
.def("write_placement", &gp::GPDatabase::writePlacement);
|
||||
|
||||
@ -562,6 +562,42 @@ std::vector<torch::Tensor> GPDatabase::getRegionInfoTensor() {
|
||||
return {node_id2region_id, region_boxes, region_boxes_end};
|
||||
}
|
||||
|
||||
std::vector<torch::Tensor> GPDatabase::getSnetInfoTensor() {
|
||||
auto options_int = torch::TensorOptions().dtype(torch::kInt64);
|
||||
|
||||
unsigned num_snetshapes = 0;
|
||||
for (size_t snetId = 0; snetId < database.snets.size(); snetId++) {
|
||||
db::SNet* snet = database.snets[snetId];
|
||||
for (size_t shapeIdx = 0; shapeIdx < snet->shapes.size(); shapeIdx++) {
|
||||
num_snetshapes++;
|
||||
}
|
||||
}
|
||||
|
||||
torch::Tensor snet_lpos = torch::zeros({num_snetshapes, 2});
|
||||
torch::Tensor snet_size = torch::zeros({num_snetshapes, 2});
|
||||
torch::Tensor snet_layer = torch::zeros({num_snetshapes}, options_int);
|
||||
|
||||
auto snet_lpos_a = snet_lpos.accessor<coord_type, 2>();
|
||||
auto snet_size_a = snet_size.accessor<coord_type, 2>();
|
||||
auto snet_layer_a = snet_layer.accessor<index_type, 1>();
|
||||
|
||||
int ptr = 0;
|
||||
for (size_t snetId = 0; snetId < database.snets.size(); snetId++) {
|
||||
db::SNet* snet = database.snets[snetId];
|
||||
for (size_t shapeIdx = 0; shapeIdx < snet->shapes.size(); shapeIdx++) {
|
||||
auto& shape = snet->shapes[shapeIdx];
|
||||
snet_lpos_a[ptr][0] = shape.lx;
|
||||
snet_lpos_a[ptr][1] = shape.ly;
|
||||
snet_size_a[ptr][0] = shape.hx - shape.lx;
|
||||
snet_size_a[ptr][1] = shape.hy - shape.ly;
|
||||
snet_layer_a[ptr] = shape.layer.rIndex;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
return {snet_lpos, snet_size, snet_layer};
|
||||
}
|
||||
|
||||
void GPDatabase::applyOneNodeOrient(int node_id) {
|
||||
auto& node = nodes[node_id];
|
||||
int rowId;
|
||||
|
||||
@ -217,6 +217,7 @@ public:
|
||||
std::vector<torch::Tensor> getHyperedgeInfoTensor(); // hyperedge_index, hyperedge_list, hyperedge_list_end
|
||||
std::vector<torch::Tensor> getNode2PinInfoTensor(); // node2pin_index, node2pin_list, node2pin_list_end
|
||||
std::vector<torch::Tensor> getRegionInfoTensor(); // node_id2region_id, region_boxes, region_boxes_end
|
||||
std::vector<torch::Tensor> getSnetInfoTensor(); // snet_lpos, snet_size, snet_layer (0 for M1, 1 for M2, ...)
|
||||
void applyOneNodeOrient(int node_id);
|
||||
void applyNodeCPos(torch::Tensor node_cpos);
|
||||
void applyNodeLPos(torch::Tensor node_lpos);
|
||||
|
||||
@ -20,7 +20,8 @@ torch::Tensor dp_route_opt(torch::Tensor node_lpos_init_,
|
||||
float site_width,
|
||||
float row_height,
|
||||
std::shared_ptr<db::Database> rawdb_,
|
||||
std::shared_ptr<gp::GPDatabase> gpdb_) {
|
||||
std::shared_ptr<gp::GPDatabase> gpdb_,
|
||||
int K) {
|
||||
// We found that placing cells under M2 SNet will easily cause DRVs
|
||||
// this function will shift cells outside the SNet within an acceptable range
|
||||
db::Database& rawdb = *rawdb_;
|
||||
@ -226,7 +227,7 @@ torch::Tensor dp_route_opt(torch::Tensor node_lpos_init_,
|
||||
float displaceL = dieHX;
|
||||
doMoveL = doMoveL && (snetLx > dieLX);
|
||||
if (doMoveL && blank_width_l < src_width_l) {
|
||||
for (ptrOffsetL = -1; ptrOffsetL >= -5; ptrOffsetL--) {
|
||||
for (ptrOffsetL = -1; ptrOffsetL >= -K; ptrOffsetL--) {
|
||||
int targetPtr = cellPtrL + ptrOffsetL;
|
||||
if (targetPtr >= 0) {
|
||||
auto [node_id1, node_lx1, node_hx1] = currBin2cells[targetPtr];
|
||||
@ -296,7 +297,7 @@ torch::Tensor dp_route_opt(torch::Tensor node_lpos_init_,
|
||||
int ptrOffsetR = 0;
|
||||
doMoveR = doMoveR && (snetHx < dieHX);
|
||||
if (doMoveR && blank_width_r < src_width_r) {
|
||||
for (ptrOffsetR = 1; ptrOffsetR <= 5; ptrOffsetR++) {
|
||||
for (ptrOffsetR = 1; ptrOffsetR <= K; ptrOffsetR++) {
|
||||
int targetPtr = cellPtrR + ptrOffsetR;
|
||||
if (targetPtr < currBin2cells.size()) {
|
||||
auto [node_id1, node_lx1, node_hx1] = currBin2cells[targetPtr];
|
||||
|
||||
4
data/README.md
Normal file
4
data/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
The following script will automatically download `ispd2005`, `ispd2015`, and `iccad2019` benchmarks in `./data/raw`. It also preprocesses `ispd2015` benchmark to fix some errors when routing them by Innovus®.
|
||||
```bash
|
||||
./download_data.sh
|
||||
```
|
||||
@ -422,7 +422,7 @@ def run_dp(node_pos: torch.Tensor, data: PlaceData, args, logger):
|
||||
def run_dp_route_opt(node_pos: torch.Tensor, gpdb, rawdb, ps, data: PlaceData, args, logger):
|
||||
# NOTE: we suppose M1's prefer routing direction is 0 (horizontal)
|
||||
if ps.enable_route and gpdb.m1direction() == 0:
|
||||
func_name = "routedp"
|
||||
func_name = "PA-Refine"
|
||||
logger.info("Start running %s" % func_name)
|
||||
start_time = time.time()
|
||||
node_pos_bk = node_pos.clone()
|
||||
@ -445,9 +445,10 @@ def run_dp_route_opt(node_pos: torch.Tensor, gpdb, rawdb, ps, data: PlaceData, a
|
||||
dieHX = die_info[1].item()
|
||||
dieLY = die_info[2].item()
|
||||
dieHY = die_info[3].item()
|
||||
K = 5
|
||||
new_node_lpos = routedp.dp_route_opt(
|
||||
node_lpos, node_size, dieLX, dieHX, dieLY, dieHY,
|
||||
site_width, row_height, rawdb, gpdb
|
||||
site_width, row_height, rawdb, gpdb, K
|
||||
)
|
||||
new_mov_cpos = new_node_lpos.to(node_pos.device)[mov_lhs:mov_rhs] + data.node_size[mov_lhs:mov_rhs] / 2
|
||||
node_pos[mov_lhs:mov_rhs].data.copy_(new_mov_cpos)
|
||||
|
||||
@ -5,7 +5,7 @@ from .core import WAWirelengthLossAndHPWL
|
||||
from .calculator import calc_grad
|
||||
|
||||
|
||||
def get_init_density_map(data: PlaceData, args, logger):
|
||||
def get_init_density_map(rawdb, gpdb, data: PlaceData, args, logger):
|
||||
lhs, rhs = data.fixed_index
|
||||
device = data.node_size.get_device()
|
||||
dtype = data.node_size.dtype
|
||||
@ -13,6 +13,7 @@ def get_init_density_map(data: PlaceData, args, logger):
|
||||
(data.num_bin_x, data.num_bin_y), device=device, dtype=dtype,
|
||||
)
|
||||
if lhs == rhs:
|
||||
data.init_density_map = zeros_density_map
|
||||
return zeros_density_map
|
||||
# get fix nodes which are located inside die
|
||||
node_pos = data.node_pos[lhs:rhs]
|
||||
@ -28,9 +29,40 @@ def get_init_density_map(data: PlaceData, args, logger):
|
||||
logger.warning("Some bins in init_density_map are overflow. Clamp them.")
|
||||
if (init_density_map < 0).sum() > 0:
|
||||
logger.error("init_density_map has negative value. Please check.")
|
||||
if args.use_route_force or args.use_cell_inflate:
|
||||
# reduce the cell density near the fixed macro
|
||||
init_density_map += density_map_cuda.forward_naive(
|
||||
node_pos, node_size * 1.025, node_weight, data.unit_len, zeros_density_map,
|
||||
data.num_bin_x, data.num_bin_y, node_pos.shape[0], -1.0, -1.0, 1e-4, False,
|
||||
args.deterministic
|
||||
).contiguous() * 0.5
|
||||
# consider snet as plaement blkg in density map to resolve M2 Vertical
|
||||
# SNet pin access problem
|
||||
if gpdb is not None and gpdb.m1direction() == 0:
|
||||
# TODO: only include snet density when util is small
|
||||
snet_lpos, snet_size, snet_layer = gpdb.snet_info_tensor()
|
||||
|
||||
snet_lpos = snet_lpos.to(device)
|
||||
snet_size = snet_size.to(device)
|
||||
snet_layer = snet_layer.to(device)
|
||||
m2_mask = snet_layer == 1
|
||||
snet_lpos = snet_lpos[m2_mask, :]
|
||||
snet_size = snet_size[m2_mask, :]
|
||||
snet_lpos -= data.die_shift
|
||||
snet_lpos /= data.die_scale
|
||||
snet_size /= data.die_scale
|
||||
|
||||
snet_pos = snet_lpos + snet_size / 2
|
||||
snet_weight = snet_size.new_ones(snet_size.shape[0])
|
||||
snet_density_map = density_map_cuda.forward_naive(
|
||||
snet_pos, snet_size, snet_weight, data.unit_len, zeros_density_map,
|
||||
data.num_bin_x, data.num_bin_y, snet_pos.shape[0], -1.0, -1.0, 1e-4, False,
|
||||
args.deterministic
|
||||
)
|
||||
init_density_map += snet_density_map.contiguous()
|
||||
init_density_map.clamp_(min=0.0, max=1.0).mul_(args.target_density)
|
||||
if args.use_route_force or args.use_cell_inflate:
|
||||
# enable route, inflate connected IOPins
|
||||
# inflate connected IOPins
|
||||
_, fix_rhs, _ = data.node_type_indices[2]
|
||||
_, iopin_rhs, _ = data.node_type_indices[3]
|
||||
if fix_rhs != iopin_rhs:
|
||||
@ -40,7 +72,6 @@ def get_init_density_map(data: PlaceData, args, logger):
|
||||
iopin_pos = data.node_pos[fix_rhs:iopin_rhs]
|
||||
iopin_size = data.node_size[fix_rhs:iopin_rhs]
|
||||
iopin_weight = iopin_size.new_ones(iopin_size.shape[0])
|
||||
row_height = data.row_height / data.site_width
|
||||
iopin_density_map = density_map_cuda.forward_naive(
|
||||
iopin_pos, iopin_size, iopin_weight, data.unit_len, zeros_density_map,
|
||||
data.num_bin_x, data.num_bin_y, iopin_pos.shape[0], -1.0, -1.0, 1e-4, False,
|
||||
|
||||
@ -27,7 +27,7 @@ def run_placement_main_nesterov(args, logger):
|
||||
logger.info(data.node_type_indices)
|
||||
# args.num_bin_x = args.num_bin_y = 2 ** math.ceil(math.log2(max(data.die_info).item() // 25))
|
||||
|
||||
init_density_map = get_init_density_map(data, args, logger)
|
||||
init_density_map = get_init_density_map(rawdb, gpdb, data, args, logger)
|
||||
data.init_filler()
|
||||
mov_lhs, mov_rhs = data.movable_index
|
||||
mov_node_pos, mov_node_size, expand_ratio = data.get_mov_node_info()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user