fix libtorch/python floating-point arith difference
This commit is contained in:
parent
50897f14dc
commit
46ab26791a
@ -226,24 +226,19 @@ bool overlapCheck(const float* x,
|
|||||||
// This will cause failure to detect some overlaps.
|
// This will cause failure to detect some overlaps.
|
||||||
// We need to remove the "small" fixed cell that is inside another.
|
// We need to remove the "small" fixed cell that is inside another.
|
||||||
if (!nodes_in_row.empty()) {
|
if (!nodes_in_row.empty()) {
|
||||||
std::vector<int> tmp_nodes;
|
for (int j = 1; j < nodes_in_row.size(); ++j) {
|
||||||
tmp_nodes.reserve(nodes_in_row.size());
|
|
||||||
tmp_nodes.push_back(nodes_in_row.front());
|
|
||||||
for (int j = 1, je = nodes_in_row.size(); j < je; ++j) {
|
|
||||||
int node_id1 = nodes_in_row.at(j - 1);
|
int node_id1 = nodes_in_row.at(j - 1);
|
||||||
int node_id2 = nodes_in_row.at(j);
|
int node_id2 = nodes_in_row.at(j);
|
||||||
// two fixed cells
|
// two fixed cells
|
||||||
if (node_id1 >= num_movable_nodes && node_id2 >= num_movable_nodes) {
|
if (node_id1 >= num_movable_nodes && node_id2 >= num_movable_nodes) {
|
||||||
float xh1 = getXH(node_id1);
|
float xh1 = getXH(node_id1);
|
||||||
float xh2 = getXH(node_id2);
|
float xh2 = getXH(node_id2);
|
||||||
if (xh1 < xh2) {
|
if (xh1 >= xh2 && !nodes_in_row.empty()) {
|
||||||
tmp_nodes.push_back(node_id2);
|
nodes_in_row.erase(nodes_in_row.begin() + j);
|
||||||
|
--j;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
tmp_nodes.push_back(node_id2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodes_in_row.swap(tmp_nodes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,21 +94,22 @@ bool DPTorchRawDB::check(float scale_factor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DPTorchRawDB::scale(float scale_factor, bool use_round) {
|
void DPTorchRawDB::scale(float scale_factor, bool use_round) {
|
||||||
|
torch::Tensor scalar_at = torch::tensor({scale_factor}, torch::dtype(torch::kFloat32).device(node_size.device()));
|
||||||
if (use_round) {
|
if (use_round) {
|
||||||
pin_rel_lpos.mul_(scale_factor);
|
pin_rel_lpos.mul_(scalar_at);
|
||||||
node_size.mul_(scale_factor).round_();
|
node_size.mul_(scalar_at).round_();
|
||||||
node_lpos_init.mul_(scale_factor).round_();
|
node_lpos_init.mul_(scalar_at).round_();
|
||||||
|
|
||||||
node_size_x.mul_(scale_factor).round_();
|
node_size_x.mul_(scalar_at).round_();
|
||||||
node_size_y.mul_(scale_factor).round_();
|
node_size_y.mul_(scalar_at).round_();
|
||||||
init_x.mul_(scale_factor).round_();
|
init_x.mul_(scalar_at).round_();
|
||||||
init_y.mul_(scale_factor).round_();
|
init_y.mul_(scalar_at).round_();
|
||||||
pin_offset_x.mul_(scale_factor).round_();
|
pin_offset_x.mul_(scalar_at).round_();
|
||||||
pin_offset_y.mul_(scale_factor).round_();
|
pin_offset_y.mul_(scalar_at).round_();
|
||||||
x.mul_(scale_factor).round_();
|
x.mul_(scalar_at).round_();
|
||||||
y.mul_(scale_factor).round_();
|
y.mul_(scalar_at).round_();
|
||||||
|
|
||||||
flat_region_boxes.mul_(scale_factor).round_();
|
flat_region_boxes.mul_(scalar_at).round_();
|
||||||
site_width = round(site_width * scale_factor);
|
site_width = round(site_width * scale_factor);
|
||||||
row_height = round(row_height * scale_factor);
|
row_height = round(row_height * scale_factor);
|
||||||
xl = round(xl * scale_factor);
|
xl = round(xl * scale_factor);
|
||||||
@ -117,20 +118,23 @@ void DPTorchRawDB::scale(float scale_factor, bool use_round) {
|
|||||||
yh = round(yh * scale_factor);
|
yh = round(yh * scale_factor);
|
||||||
} else {
|
} else {
|
||||||
float inv_scale_factor = std::round(1.0 / scale_factor);
|
float inv_scale_factor = std::round(1.0 / scale_factor);
|
||||||
pin_rel_lpos.div_(inv_scale_factor);
|
torch::Tensor inv_scalar_at =
|
||||||
node_size.div_(inv_scale_factor);
|
torch::tensor({inv_scale_factor}, torch::dtype(torch::kFloat32).device(node_size.device()));
|
||||||
node_lpos_init.div_(inv_scale_factor);
|
|
||||||
|
|
||||||
node_size_x.div_(inv_scale_factor);
|
pin_rel_lpos.div_(inv_scalar_at);
|
||||||
node_size_y.div_(inv_scale_factor);
|
node_size.div_(inv_scalar_at);
|
||||||
init_x.div_(inv_scale_factor);
|
node_lpos_init.div_(inv_scalar_at);
|
||||||
init_y.div_(inv_scale_factor);
|
|
||||||
pin_offset_x.div_(inv_scale_factor);
|
|
||||||
pin_offset_y.div_(inv_scale_factor);
|
|
||||||
x.div_(inv_scale_factor);
|
|
||||||
y.div_(inv_scale_factor);
|
|
||||||
|
|
||||||
flat_region_boxes.div_(inv_scale_factor);
|
node_size_x.div_(inv_scalar_at);
|
||||||
|
node_size_y.div_(inv_scalar_at);
|
||||||
|
init_x.div_(inv_scalar_at);
|
||||||
|
init_y.div_(inv_scalar_at);
|
||||||
|
pin_offset_x.div_(inv_scalar_at);
|
||||||
|
pin_offset_y.div_(inv_scalar_at);
|
||||||
|
x.div_(inv_scalar_at);
|
||||||
|
y.div_(inv_scalar_at);
|
||||||
|
|
||||||
|
flat_region_boxes.div_(inv_scalar_at);
|
||||||
site_width = site_width / inv_scale_factor;
|
site_width = site_width / inv_scale_factor;
|
||||||
row_height = row_height / inv_scale_factor;
|
row_height = row_height / inv_scale_factor;
|
||||||
xl = xl / inv_scale_factor;
|
xl = xl / inv_scale_factor;
|
||||||
|
|||||||
@ -274,12 +274,60 @@ public:
|
|||||||
return legal_flag;
|
return legal_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<int>> reorder_row_map(
|
||||||
|
const float* host_x, const float* host_y, const float* host_node_size_x, const float* host_node_size_y, std::vector<std::vector<int>>& row2node_map, int sort_coord) {
|
||||||
|
if (sort_coord < 0 || sort_coord > 2) sort_coord = 0;
|
||||||
|
|
||||||
|
std::vector<std::vector<int>> row2node_map_helper;
|
||||||
|
// copy row2node_map to row2node_map_helper
|
||||||
|
row2node_map_helper.resize(row2node_map.size());
|
||||||
|
for (int i = 0; i < row2node_map.size(); ++i) {
|
||||||
|
row2node_map_helper[i] = row2node_map[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort according to right
|
||||||
|
for (int i = 0; i < row2node_map.size(); ++i) {
|
||||||
|
auto& row2nodes = row2node_map_helper[i];
|
||||||
|
if (!row2nodes.empty()) {
|
||||||
|
switch (sort_coord) {
|
||||||
|
case 0: // center
|
||||||
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
|
float x1 = host_x[node_id1] + host_node_size_x[node_id1] / 2;
|
||||||
|
float x2 = host_x[node_id2] + host_node_size_x[node_id2] / 2;
|
||||||
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 1: // left
|
||||||
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
|
float x1 = host_x[node_id1];
|
||||||
|
float x2 = host_x[node_id2];
|
||||||
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 2: // right
|
||||||
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
|
float x1 = host_x[node_id1] + host_node_size_x[node_id1];
|
||||||
|
float x2 = host_x[node_id2] + host_node_size_x[node_id2];
|
||||||
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return row2node_map_helper;
|
||||||
|
}
|
||||||
|
|
||||||
void make_row2node_map(const float* host_x,
|
void make_row2node_map(const float* host_x,
|
||||||
const float* host_y,
|
const float* host_y,
|
||||||
const float* host_node_size_x,
|
const float* host_node_size_x,
|
||||||
const float* host_node_size_y,
|
const float* host_node_size_y,
|
||||||
int host_num_nodes,
|
int host_num_nodes,
|
||||||
std::vector<std::vector<int>>& row2node_map) {
|
std::vector<std::vector<int>>& row2node_map,
|
||||||
|
int sort_coord = 0) {
|
||||||
|
if (sort_coord < 0 || sort_coord > 2) sort_coord = 0;
|
||||||
// distribute cells to rows
|
// distribute cells to rows
|
||||||
for (int i = 0; i < host_num_nodes; ++i) {
|
for (int i = 0; i < host_num_nodes; ++i) {
|
||||||
float node_yl = host_y[i];
|
float node_yl = host_y[i];
|
||||||
@ -312,10 +360,7 @@ public:
|
|||||||
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
});
|
});
|
||||||
if (!row2nodes.empty()) {
|
if (!row2nodes.empty()) {
|
||||||
std::vector<int> tmp_nodes;
|
for (int j = 1; j < row2nodes.size(); ++j) {
|
||||||
tmp_nodes.reserve(row2nodes.size());
|
|
||||||
tmp_nodes.push_back(row2nodes.front());
|
|
||||||
for (int j = 1, je = row2nodes.size(); j < je; ++j) {
|
|
||||||
int node_id1 = row2nodes.at(j - 1);
|
int node_id1 = row2nodes.at(j - 1);
|
||||||
int node_id2 = row2nodes.at(j);
|
int node_id2 = row2nodes.at(j);
|
||||||
// two fixed cells
|
// two fixed cells
|
||||||
@ -327,21 +372,39 @@ public:
|
|||||||
float xh1 = xl1 + width1;
|
float xh1 = xl1 + width1;
|
||||||
float xh2 = xl2 + width2;
|
float xh2 = xl2 + width2;
|
||||||
// only collect node_id2 if its right edge is righter than node_id1
|
// only collect node_id2 if its right edge is righter than node_id1
|
||||||
if (xh1 < xh2) {
|
if (xh1 >= xh2 && !row2nodes.empty()) {
|
||||||
tmp_nodes.push_back(node_id2);
|
row2nodes.erase(row2nodes.begin() + j);
|
||||||
|
--j;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
tmp_nodes.push_back(node_id2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row2nodes.swap(tmp_nodes);
|
|
||||||
|
|
||||||
// sort according to center
|
// sort according to center
|
||||||
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
switch (sort_coord) {
|
||||||
float x1 = host_x[node_id1] + host_node_size_x[node_id1] / 2;
|
case 0: // center
|
||||||
float x2 = host_x[node_id2] + host_node_size_x[node_id2] / 2;
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
float x1 = host_x[node_id1] + host_node_size_x[node_id1] / 2;
|
||||||
});
|
float x2 = host_x[node_id2] + host_node_size_x[node_id2] / 2;
|
||||||
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 1: // left
|
||||||
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
|
float x1 = host_x[node_id1];
|
||||||
|
float x2 = host_x[node_id2];
|
||||||
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 2: // right
|
||||||
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
|
float x1 = host_x[node_id1] + host_node_size_x[node_id1];
|
||||||
|
float x2 = host_x[node_id2] + host_node_size_x[node_id2];
|
||||||
|
return x1 < x2 || (x1 == x2 && node_id1 < node_id2);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,8 +415,12 @@ public:
|
|||||||
const float* host_node_size_y,
|
const float* host_node_size_y,
|
||||||
std::vector<std::vector<int>>& row2node_map,
|
std::vector<std::vector<int>>& row2node_map,
|
||||||
std::vector<RowMapIndex>& node2row_map,
|
std::vector<RowMapIndex>& node2row_map,
|
||||||
std::vector<Space<float>>& spaces) {
|
std::vector<Space<float>>& spaces,
|
||||||
make_row2node_map(host_x, host_y, host_node_size_x, host_node_size_y, num_nodes + 2, row2node_map);
|
int sort_coord = 0) {
|
||||||
|
make_row2node_map(host_x, host_y, host_node_size_x, host_node_size_y, num_nodes + 2, row2node_map, sort_coord);
|
||||||
|
|
||||||
|
// copy row2node_map to row2node_map_helper
|
||||||
|
std::vector<std::vector<int>> row2node_map_helper = reorder_row_map(host_x, host_y, host_node_size_x, host_node_size_y, row2node_map, sort_coord);
|
||||||
|
|
||||||
// construct node2row_map
|
// construct node2row_map
|
||||||
for (int i = 0; i < num_sites_y; ++i) {
|
for (int i = 0; i < num_sites_y; ++i) {
|
||||||
@ -373,7 +440,10 @@ public:
|
|||||||
int node_id = row2node_map[i][j];
|
int node_id = row2node_map[i][j];
|
||||||
if (node_id < num_movable_nodes) {
|
if (node_id < num_movable_nodes) {
|
||||||
assert(j);
|
assert(j);
|
||||||
int left_node_id = row2node_map[i][j - 1];
|
// int left_node_id = row2node_map[i][j - 1];
|
||||||
|
int j_helper = std::find(row2node_map_helper[i].begin(), row2node_map_helper[i].end(), node_id) - row2node_map_helper[i].begin();
|
||||||
|
int left_node_id = row2node_map[i][j_helper - 1];
|
||||||
|
|
||||||
spaces[node_id].xl = host_x[left_node_id] + host_node_size_x[left_node_id];
|
spaces[node_id].xl = host_x[left_node_id] + host_node_size_x[left_node_id];
|
||||||
assert(j + 1 < row2node_map[i].size());
|
assert(j + 1 < row2node_map[i].size());
|
||||||
int right_node_id = row2node_map[i][j + 1];
|
int right_node_id = row2node_map[i][j + 1];
|
||||||
|
|||||||
@ -911,7 +911,8 @@ void globalSwapCUDA(DPTorchRawDB& at_db, int num_bins_x, int num_bins_y, int bat
|
|||||||
host_node_size_y.data(),
|
host_node_size_y.data(),
|
||||||
host_row2node_map,
|
host_row2node_map,
|
||||||
host_node2row_map,
|
host_node2row_map,
|
||||||
host_spaces);
|
host_spaces,
|
||||||
|
1);
|
||||||
// distribute movable cells to bins on host, bin map is column-major
|
// distribute movable cells to bins on host, bin map is column-major
|
||||||
std::vector<std::vector<int>> host_bin2node_map(db.num_bins_x * db.num_bins_y);
|
std::vector<std::vector<int>> host_bin2node_map(db.num_bins_x * db.num_bins_y);
|
||||||
std::vector<BinMapIndex> host_node2bin_map(db.num_movable_nodes);
|
std::vector<BinMapIndex> host_node2bin_map(db.num_movable_nodes);
|
||||||
|
|||||||
@ -244,10 +244,7 @@ void make_row2node_map(const DetailedPlaceDBType& db,
|
|||||||
// This will cause failure to detect some overlaps.
|
// This will cause failure to detect some overlaps.
|
||||||
// We need to remove the "small" fixed cell that is inside another.
|
// We need to remove the "small" fixed cell that is inside another.
|
||||||
if (!row2nodes.empty()) {
|
if (!row2nodes.empty()) {
|
||||||
std::vector<int> tmp_nodes;
|
for (int j = 1; j < row2nodes.size(); ++j) {
|
||||||
tmp_nodes.reserve(row2nodes.size());
|
|
||||||
tmp_nodes.push_back(row2nodes.front());
|
|
||||||
for (int j = 1, je = row2nodes.size(); j < je; ++j) {
|
|
||||||
int node_id1 = row2nodes.at(j - 1);
|
int node_id1 = row2nodes.at(j - 1);
|
||||||
int node_id2 = row2nodes.at(j);
|
int node_id2 = row2nodes.at(j);
|
||||||
// two fixed cells
|
// two fixed cells
|
||||||
@ -259,14 +256,12 @@ void make_row2node_map(const DetailedPlaceDBType& db,
|
|||||||
typename DetailedPlaceDBType::type xh1 = xl1 + width1;
|
typename DetailedPlaceDBType::type xh1 = xl1 + width1;
|
||||||
typename DetailedPlaceDBType::type xh2 = xl2 + width2;
|
typename DetailedPlaceDBType::type xh2 = xl2 + width2;
|
||||||
// only collect node_id2 if its right edge is righter than node_id1
|
// only collect node_id2 if its right edge is righter than node_id1
|
||||||
if (xh1 < xh2) {
|
if (xh1 >= xh2 && !row2nodes.empty()) {
|
||||||
tmp_nodes.push_back(node_id2);
|
row2nodes.erase(row2nodes.begin() + j);
|
||||||
|
--j;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
tmp_nodes.push_back(node_id2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row2nodes.swap(tmp_nodes);
|
|
||||||
|
|
||||||
// sort according to center
|
// sort according to center
|
||||||
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
std::sort(row2nodes.begin(), row2nodes.end(), [&](int node_id1, int node_id2) {
|
||||||
@ -982,16 +977,17 @@ void kReorderCUDA(DPTorchRawDB& at_db, int num_bins_x, int num_bins_y, int K, in
|
|||||||
allocateCopyCpu(cpu_db.node_size_y, db.node_size_y, db.num_nodes, T);
|
allocateCopyCpu(cpu_db.node_size_y, db.node_size_y, db.num_nodes, T);
|
||||||
|
|
||||||
make_row2node_map(cpu_db, cpu_db.x, cpu_db.y, host_row2node_map, db.num_threads);
|
make_row2node_map(cpu_db, cpu_db.x, cpu_db.y, host_row2node_map, db.num_threads);
|
||||||
|
std::vector<std::vector<int>> host_row2node_map_left = db.reorder_row_map(cpu_db.x, cpu_db.y, cpu_db.node_size_x, cpu_db.node_size_y, host_row2node_map, 1);
|
||||||
host_node_space_x.resize(cpu_db.num_movable_nodes);
|
host_node_space_x.resize(cpu_db.num_movable_nodes);
|
||||||
for (int i = 0; i < cpu_db.num_sites_y; ++i) {
|
for (int i = 0; i < cpu_db.num_sites_y; ++i) {
|
||||||
for (unsigned int j = 0; j < host_row2node_map.at(i).size(); ++j) {
|
for (unsigned int j = 0; j < host_row2node_map_left.at(i).size(); ++j) {
|
||||||
int node_id = host_row2node_map[i][j];
|
int node_id = host_row2node_map_left[i][j];
|
||||||
if (node_id < db.num_movable_nodes) {
|
if (node_id < db.num_movable_nodes) {
|
||||||
auto& space = host_node_space_x[node_id];
|
auto& space = host_node_space_x[node_id];
|
||||||
T space_xl = cpu_db.x[node_id];
|
T space_xl = cpu_db.x[node_id];
|
||||||
T space_xh = cpu_db.xh;
|
T space_xh = cpu_db.xh;
|
||||||
if (j + 1 < host_row2node_map[i].size()) {
|
if (j + 1 < host_row2node_map_left[i].size()) {
|
||||||
int right_node_id = host_row2node_map[i][j + 1];
|
int right_node_id = host_row2node_map_left[i][j + 1];
|
||||||
space_xh = min(space_xh, cpu_db.x[right_node_id]);
|
space_xh = min(space_xh, cpu_db.x[right_node_id]);
|
||||||
}
|
}
|
||||||
space = space_xh - space_xl;
|
space = space_xh - space_xl;
|
||||||
|
|||||||
@ -145,40 +145,56 @@ void distributeBlanks2Bins(const float* x,
|
|||||||
|
|
||||||
bin_blanks.at(blank_bin_id).push_back(blank);
|
bin_blanks.at(blank_bin_id).push_back(blank);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<int>& cells = bin_fixed_cells.at(i);
|
for (int i = 0; i < num_bins_x * num_bins_y; i += 1) {
|
||||||
std::vector<Blank<float>>& blanks = bin_blanks.at(blank_bin_id);
|
int bin_id_x = i / num_bins_y;
|
||||||
|
int bin_id_y = i - bin_id_x * num_bins_y;
|
||||||
|
int blank_num_bins_per_bin = roundDiv(bin_size_y, blank_bin_size_y);
|
||||||
|
int blank_bin_id_yl = bin_id_y * blank_num_bins_per_bin;
|
||||||
|
int blank_bin_id_yh = std::min(blank_bin_id_yl + blank_num_bins_per_bin, blank_num_bins_y);
|
||||||
|
|
||||||
|
const std::vector<int>& cells = bin_fixed_cells.at(i);
|
||||||
|
|
||||||
for (unsigned int bi = 0; bi < blanks.size(); ++bi) {
|
for (unsigned int ci = 0; ci < cells.size(); ++ci) {
|
||||||
Blank<float>& blank = blanks.at(bi);
|
int node_id = cells.at(ci);
|
||||||
for (unsigned int ci = 0; ci < cells.size(); ++ci) {
|
float node_xl = x[node_id];
|
||||||
int node_id = cells.at(ci);
|
float node_yl = y[node_id];
|
||||||
float node_xl = x[node_id];
|
float node_xh = node_xl + node_size_x[node_id];
|
||||||
float node_yl = y[node_id];
|
float node_yh = node_yl + node_size_y[node_id];
|
||||||
float node_xh = node_xl + node_size_x[node_id];
|
|
||||||
float node_yh = node_yl + node_size_y[node_id];
|
|
||||||
|
|
||||||
if (node_yh > blank.yl && node_yl < blank.yh && node_xh > blank.xl &&
|
// int node_2_blank_bin_id_yl = std::max(floorDiv((node_yl - yl), blank_bin_size_y), blank_bin_id_yl);
|
||||||
node_xl < blank.xh) // overlap
|
// int node_2_blank_bin_id_yh = std::min(ceilDiv((node_yh - yl), blank_bin_size_y), blank_bin_id_yh);
|
||||||
|
|
||||||
|
int node_2_blank_bin_id_yl = std::max((node_yl - yl) / blank_bin_size_y, (float)blank_bin_id_yl);
|
||||||
|
int node_2_blank_bin_id_yh = std::min((int)ceil((node_yh - yl) / blank_bin_size_y), blank_bin_id_yh);
|
||||||
|
|
||||||
|
for (int blank_bin_id_y = node_2_blank_bin_id_yl; blank_bin_id_y < node_2_blank_bin_id_yh; ++blank_bin_id_y) {
|
||||||
|
int blank_bin_id = bin_id_x * blank_num_bins_y + blank_bin_id_y;
|
||||||
|
|
||||||
|
std::vector<Blank<float>>& blanks = bin_blanks.at(blank_bin_id);
|
||||||
|
|
||||||
|
for (unsigned int bi = 0; bi < blanks.size(); ++bi) {
|
||||||
|
Blank<float>& blank = blanks.at(bi);
|
||||||
|
if (blank.xh <= node_xl) continue;
|
||||||
|
if (blank.xl >= node_xh) break;
|
||||||
|
|
||||||
|
if (node_xl <= blank.xl && node_xh >= blank.xh) // erase
|
||||||
{
|
{
|
||||||
if (node_xl <= blank.xl && node_xh >= blank.xh) // erase
|
bin_blanks.at(blank_bin_id).erase(bin_blanks.at(blank_bin_id).begin() + bi);
|
||||||
{
|
--bi;
|
||||||
bin_blanks.at(blank_bin_id).erase(bin_blanks.at(blank_bin_id).begin() + bi);
|
} else if (node_xl <= blank.xl) { // one blank
|
||||||
--bi;
|
blank.xl = ceilDiv((node_xh - xl), site_width) * site_width + xl; // align blanks to sites
|
||||||
break;
|
} else if (node_xh >= blank.xh) { // one blank
|
||||||
} else if (node_xl <= blank.xl) { // one blank
|
blank.xh = floorDiv((node_xl - xl), site_width) * site_width + xl; // align blanks to sites
|
||||||
blank.xl = ceilDiv((node_xh - xl), site_width) * site_width + xl; // align blanks to sites
|
} else { // two blanks
|
||||||
} else if (node_xh >= blank.xh) { // one blank
|
Blank<float> new_blank = blank;
|
||||||
blank.xh = floorDiv((node_xl - xl), site_width) * site_width + xl; // align blanks to sites
|
blank.xh = floorDiv((node_xl - xl), site_width) * site_width + xl; // align blanks to sites
|
||||||
} else { // two blanks
|
new_blank.xl =
|
||||||
Blank<float> new_blank = blank;
|
floorDiv((node_xh - xl), site_width) * site_width + xl; // align blanks to sites
|
||||||
blank.xh = floorDiv((node_xl - xl), site_width) * site_width + xl; // align blanks to sites
|
bin_blanks.at(blank_bin_id).insert(bin_blanks.at(blank_bin_id).begin() + bi + 1, new_blank);
|
||||||
new_blank.xl =
|
--bi;
|
||||||
floorDiv((node_xh - xl), site_width) * site_width + xl; // align blanks to sites
|
|
||||||
bin_blanks.at(blank_bin_id).insert(bin_blanks.at(blank_bin_id).begin() + bi + 1, new_blank);
|
|
||||||
--bi;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
main.py
1
main.py
@ -50,6 +50,7 @@ def get_option():
|
|||||||
parser.add_argument('--visualize_cgmap', type=str2bool, default=False, help='visualize congestion map')
|
parser.add_argument('--visualize_cgmap', type=str2bool, default=False, help='visualize congestion map')
|
||||||
|
|
||||||
# detailed placement and evaluation
|
# detailed placement and evaluation
|
||||||
|
parser.add_argument('--legalization', type=str2bool, default=True, help='perform lg')
|
||||||
parser.add_argument('--detail_placement', type=str2bool, default=True, help='perform dp')
|
parser.add_argument('--detail_placement', type=str2bool, default=True, help='perform dp')
|
||||||
parser.add_argument('--dp_engine', type=str, default="default", help='choose dp engine')
|
parser.add_argument('--dp_engine', type=str, default="default", help='choose dp engine')
|
||||||
parser.add_argument('--eval_by_external', type=str2bool, default=False, help='eval dp sol by external binary')
|
parser.add_argument('--eval_by_external', type=str2bool, default=False, help='eval dp sol by external binary')
|
||||||
|
|||||||
@ -155,7 +155,11 @@ def setup_detailed_rawdb(
|
|||||||
# NOTE: we assume all legalized cells are on integer system
|
# NOTE: we assume all legalized cells are on integer system
|
||||||
# this step can avoid some potential floating-point precision errors
|
# this step can avoid some potential floating-point precision errors
|
||||||
_, floatmov_rhs, _ = data.node_type_indices[1]
|
_, floatmov_rhs, _ = data.node_type_indices[1]
|
||||||
inv_scalar = round(1.0 / get_ori_scale_factor(data))
|
inv_scalar = torch.tensor(
|
||||||
|
[round(1.0 / get_ori_scale_factor(data))],
|
||||||
|
dtype=torch.float32,
|
||||||
|
device=node_lpos.device
|
||||||
|
)
|
||||||
node_lpos[:floatmov_rhs].mul_(inv_scalar).round_().div_(inv_scalar)
|
node_lpos[:floatmov_rhs].mul_(inv_scalar).round_().div_(inv_scalar)
|
||||||
|
|
||||||
mov_lhs, mov_rhs = data.movable_index
|
mov_lhs, mov_rhs = data.movable_index
|
||||||
@ -466,7 +470,11 @@ def run_dp_route_opt(node_pos: torch.Tensor, gpdb, rawdb, ps, data: PlaceData, a
|
|||||||
), dim=0).cpu()
|
), dim=0).cpu()
|
||||||
# this step can avoid some potential floating-point precision errors
|
# this step can avoid some potential floating-point precision errors
|
||||||
_, floatmov_rhs, _ = data.node_type_indices[1]
|
_, floatmov_rhs, _ = data.node_type_indices[1]
|
||||||
inv_scalar = round(1.0 / get_ori_scale_factor(data))
|
inv_scalar = torch.tensor(
|
||||||
|
[round(1.0 / get_ori_scale_factor(data))],
|
||||||
|
dtype=torch.float32,
|
||||||
|
device=node_lpos.device
|
||||||
|
)
|
||||||
node_lpos[:floatmov_rhs].mul_(inv_scalar).round_().div_(inv_scalar)
|
node_lpos[:floatmov_rhs].mul_(inv_scalar).round_().div_(inv_scalar)
|
||||||
|
|
||||||
node_size = data.node_size.cpu()
|
node_size = data.node_size.cpu()
|
||||||
@ -626,7 +634,8 @@ def external_detail_placement(input_file, data: PlaceData, args, logger, eval_mo
|
|||||||
logger.info("Write detail placement in %s" % dp_out_file)
|
logger.info("Write detail placement in %s" % dp_out_file)
|
||||||
# del gpdb, rawdb
|
# del gpdb, rawdb
|
||||||
# logger.info("Evaluating detail placement result...")
|
# logger.info("Evaluating detail placement result...")
|
||||||
# data, rawdb, gpdb = load_dataset(args, logger, dp_out_file)
|
# params = find_design_params(args, logger, dp_out_file)
|
||||||
|
# data, rawdb, gpdb = load_dataset(args, logger, params)
|
||||||
# data = data.to(device).preprocess()
|
# data = data.to(device).preprocess()
|
||||||
# hpwl = get_obj_hpwl(data.node_pos, data, args).item()
|
# hpwl = get_obj_hpwl(data.node_pos, data, args).item()
|
||||||
# info = (iteration + 1, hpwl, data.design_name)
|
# info = (iteration + 1, hpwl, data.design_name)
|
||||||
@ -645,10 +654,12 @@ def default_detail_placement(node_pos, gpdb, rawdb, ps, data: PlaceData, args, l
|
|||||||
|
|
||||||
torch.cuda.synchronize(node_pos.device)
|
torch.cuda.synchronize(node_pos.device)
|
||||||
dp_start_time = time.time()
|
dp_start_time = time.time()
|
||||||
node_pos = run_lg(node_pos, data, args, logger)
|
if args.legalization:
|
||||||
|
node_pos = run_lg(node_pos, data, args, logger)
|
||||||
torch.cuda.synchronize(node_pos.device)
|
torch.cuda.synchronize(node_pos.device)
|
||||||
lg_end_time = time.time()
|
lg_end_time = time.time()
|
||||||
node_pos = run_dp(node_pos, data, args, logger)
|
if args.detail_placement:
|
||||||
|
node_pos = run_dp(node_pos, data, args, logger)
|
||||||
torch.cuda.synchronize(node_pos.device)
|
torch.cuda.synchronize(node_pos.device)
|
||||||
node_pos = run_dp_route_opt(node_pos, gpdb, rawdb, ps, data, args, logger)
|
node_pos = run_dp_route_opt(node_pos, gpdb, rawdb, ps, data, args, logger)
|
||||||
dp_end_time = time.time()
|
dp_end_time = time.time()
|
||||||
@ -687,8 +698,9 @@ def detail_placement_main(node_pos, gpdb, rawdb, ps, data: PlaceData, args, logg
|
|||||||
gp_out_file = gp_prefix + post_fix
|
gp_out_file = gp_prefix + post_fix
|
||||||
|
|
||||||
args.write_global_placement = False # we won't write GP solution anymore
|
args.write_global_placement = False # we won't write GP solution anymore
|
||||||
|
args.detail_placement = False if args.legalization is False else args.detail_placement
|
||||||
|
|
||||||
if args.detail_placement:
|
if args.detail_placement or args.legalization:
|
||||||
logger.info("------- Start DP -------")
|
logger.info("------- Start DP -------")
|
||||||
if args.dp_engine in ["ntuplace3", "ntuplace4dr", "rippledp"]:
|
if args.dp_engine in ["ntuplace3", "ntuplace4dr", "rippledp"]:
|
||||||
# use external engine to perform lg/dp and write solution
|
# use external engine to perform lg/dp and write solution
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user