update with PG info

This commit is contained in:
liulixinkerry 2023-04-27 15:25:07 +08:00
parent a0e5b23cf7
commit 59ff5693e4
8 changed files with 84 additions and 9 deletions

View File

@ -66,6 +66,7 @@ void bindGPDatabase(pybind11::module& m) {
.def("hyperedge_info_tensor", &gp::GPDatabase::getHyperedgeInfoTensor, py::return_value_policy::move) .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("node2pin_info_tensor", &gp::GPDatabase::getNode2PinInfoTensor, py::return_value_policy::move)
.def("region_info_tensor", &gp::GPDatabase::getRegionInfoTensor, 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_cpos", &gp::GPDatabase::applyNodeCPos)
.def("apply_node_lpos", &gp::GPDatabase::applyNodeLPos) .def("apply_node_lpos", &gp::GPDatabase::applyNodeLPos)
.def("write_placement", &gp::GPDatabase::writePlacement); .def("write_placement", &gp::GPDatabase::writePlacement);

View File

@ -562,6 +562,42 @@ std::vector<torch::Tensor> GPDatabase::getRegionInfoTensor() {
return {node_id2region_id, region_boxes, region_boxes_end}; 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) { void GPDatabase::applyOneNodeOrient(int node_id) {
auto& node = nodes[node_id]; auto& node = nodes[node_id];
int rowId; int rowId;

View File

@ -217,6 +217,7 @@ public:
std::vector<torch::Tensor> getHyperedgeInfoTensor(); // hyperedge_index, hyperedge_list, hyperedge_list_end 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> 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> 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 applyOneNodeOrient(int node_id);
void applyNodeCPos(torch::Tensor node_cpos); void applyNodeCPos(torch::Tensor node_cpos);
void applyNodeLPos(torch::Tensor node_lpos); void applyNodeLPos(torch::Tensor node_lpos);

View File

@ -20,7 +20,8 @@ torch::Tensor dp_route_opt(torch::Tensor node_lpos_init_,
float site_width, float site_width,
float row_height, float row_height,
std::shared_ptr<db::Database> rawdb_, 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 // We found that placing cells under M2 SNet will easily cause DRVs
// this function will shift cells outside the SNet within an acceptable range // this function will shift cells outside the SNet within an acceptable range
db::Database& rawdb = *rawdb_; db::Database& rawdb = *rawdb_;
@ -226,7 +227,7 @@ torch::Tensor dp_route_opt(torch::Tensor node_lpos_init_,
float displaceL = dieHX; float displaceL = dieHX;
doMoveL = doMoveL && (snetLx > dieLX); doMoveL = doMoveL && (snetLx > dieLX);
if (doMoveL && blank_width_l < src_width_l) { if (doMoveL && blank_width_l < src_width_l) {
for (ptrOffsetL = -1; ptrOffsetL >= -5; ptrOffsetL--) { for (ptrOffsetL = -1; ptrOffsetL >= -K; ptrOffsetL--) {
int targetPtr = cellPtrL + ptrOffsetL; int targetPtr = cellPtrL + ptrOffsetL;
if (targetPtr >= 0) { if (targetPtr >= 0) {
auto [node_id1, node_lx1, node_hx1] = currBin2cells[targetPtr]; 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; int ptrOffsetR = 0;
doMoveR = doMoveR && (snetHx < dieHX); doMoveR = doMoveR && (snetHx < dieHX);
if (doMoveR && blank_width_r < src_width_r) { if (doMoveR && blank_width_r < src_width_r) {
for (ptrOffsetR = 1; ptrOffsetR <= 5; ptrOffsetR++) { for (ptrOffsetR = 1; ptrOffsetR <= K; ptrOffsetR++) {
int targetPtr = cellPtrR + ptrOffsetR; int targetPtr = cellPtrR + ptrOffsetR;
if (targetPtr < currBin2cells.size()) { if (targetPtr < currBin2cells.size()) {
auto [node_id1, node_lx1, node_hx1] = currBin2cells[targetPtr]; auto [node_id1, node_lx1, node_hx1] = currBin2cells[targetPtr];

4
data/README.md Normal file
View 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
```

View File

@ -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): 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) # NOTE: we suppose M1's prefer routing direction is 0 (horizontal)
if ps.enable_route and gpdb.m1direction() == 0: if ps.enable_route and gpdb.m1direction() == 0:
func_name = "routedp" func_name = "PA-Refine"
logger.info("Start running %s" % func_name) logger.info("Start running %s" % func_name)
start_time = time.time() start_time = time.time()
node_pos_bk = node_pos.clone() 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() dieHX = die_info[1].item()
dieLY = die_info[2].item() dieLY = die_info[2].item()
dieHY = die_info[3].item() dieHY = die_info[3].item()
K = 5
new_node_lpos = routedp.dp_route_opt( new_node_lpos = routedp.dp_route_opt(
node_lpos, node_size, dieLX, dieHX, dieLY, dieHY, 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 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) node_pos[mov_lhs:mov_rhs].data.copy_(new_mov_cpos)

View File

@ -5,7 +5,7 @@ from .core import WAWirelengthLossAndHPWL
from .calculator import calc_grad 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 lhs, rhs = data.fixed_index
device = data.node_size.get_device() device = data.node_size.get_device()
dtype = data.node_size.dtype 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, (data.num_bin_x, data.num_bin_y), device=device, dtype=dtype,
) )
if lhs == rhs: if lhs == rhs:
data.init_density_map = zeros_density_map
return zeros_density_map return zeros_density_map
# get fix nodes which are located inside die # get fix nodes which are located inside die
node_pos = data.node_pos[lhs:rhs] 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.") logger.warning("Some bins in init_density_map are overflow. Clamp them.")
if (init_density_map < 0).sum() > 0: if (init_density_map < 0).sum() > 0:
logger.error("init_density_map has negative value. Please check.") 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) init_density_map.clamp_(min=0.0, max=1.0).mul_(args.target_density)
if args.use_route_force or args.use_cell_inflate: 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] _, fix_rhs, _ = data.node_type_indices[2]
_, iopin_rhs, _ = data.node_type_indices[3] _, iopin_rhs, _ = data.node_type_indices[3]
if fix_rhs != iopin_rhs: 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_pos = data.node_pos[fix_rhs:iopin_rhs]
iopin_size = data.node_size[fix_rhs:iopin_rhs] iopin_size = data.node_size[fix_rhs:iopin_rhs]
iopin_weight = iopin_size.new_ones(iopin_size.shape[0]) 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_density_map = density_map_cuda.forward_naive(
iopin_pos, iopin_size, iopin_weight, data.unit_len, zeros_density_map, 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, data.num_bin_x, data.num_bin_y, iopin_pos.shape[0], -1.0, -1.0, 1e-4, False,

View File

@ -27,7 +27,7 @@ def run_placement_main_nesterov(args, logger):
logger.info(data.node_type_indices) 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)) # 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() data.init_filler()
mov_lhs, mov_rhs = data.movable_index mov_lhs, mov_rhs = data.movable_index
mov_node_pos, mov_node_size, expand_ratio = data.get_mov_node_info() mov_node_pos, mov_node_size, expand_ratio = data.get_mov_node_info()