From d685421a2f276f592a2233db4785b070678e675b Mon Sep 17 00:00:00 2001 From: liulixinkerry Date: Wed, 15 May 2024 17:05:07 +0800 Subject: [PATCH] fix numerical bug and update json mode --- cpp_to_py/gpudp/check/legality_check.cpp | 6 +++--- cpp_to_py/gpudp/lg/greedy_legalize.cpp | 8 ++++---- src/detail_placement.py | 14 ++++++++------ utils/get_design_params.py | 13 ++++++++++++- utils/setup_dataset.py | 3 +-- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/cpp_to_py/gpudp/check/legality_check.cpp b/cpp_to_py/gpudp/check/legality_check.cpp index 537e022..09f1671 100644 --- a/cpp_to_py/gpudp/check/legality_check.cpp +++ b/cpp_to_py/gpudp/check/legality_check.cpp @@ -51,7 +51,7 @@ bool siteAlignmentCheck(const float* x, float node_yl = y[i]; float row_id_f = (node_yl - yl) / row_height; - int row_id = floorDiv(node_yl - yl, row_height); + int row_id = floorDiv(node_yl - yl, row_height, 1e-3); float row_yl = yl + row_height * row_id; float row_yh = row_yl + row_height; @@ -186,8 +186,8 @@ bool overlapCheck(const float* x, // add a box to row auto addBox2Row = [&](int id, float bxl, float byl, float bxh, float byh) { - int row_idxl = floorDiv(byl - yl, row_height); - int row_idxh = ceilDiv(byh - yl, row_height); + int row_idxl = floorDiv(byl - yl, row_height, 1e-3); + int row_idxh = ceilDiv(byh - yl, row_height, 1e-3); row_idxl = std::max(row_idxl, 0); row_idxh = std::min(row_idxh, num_rows); diff --git a/cpp_to_py/gpudp/lg/greedy_legalize.cpp b/cpp_to_py/gpudp/lg/greedy_legalize.cpp index 2c363da..8b5ee39 100644 --- a/cpp_to_py/gpudp/lg/greedy_legalize.cpp +++ b/cpp_to_py/gpudp/lg/greedy_legalize.cpp @@ -89,10 +89,10 @@ void distributeFixedCells2Bins(const LegalizationData& db, for (int i = 0; i < num_nodes; i += 1) { if (db.is_dummy_fixed(i) || i >= num_movable_nodes) { int node_id = i; - int bin_id_xl = std::max((int)floorDiv(x[node_id] - xl, bin_size_x), 0); - int bin_id_xh = std::min((int)ceilDiv((x[node_id] + node_size_x[node_id] - xl), bin_size_x), num_bins_x); - int bin_id_yl = std::max((int)floorDiv(y[node_id] - yl, bin_size_y), 0); - int bin_id_yh = std::min((int)ceilDiv((y[node_id] + node_size_y[node_id] - yl), bin_size_y), num_bins_y); + int bin_id_xl = std::max((int)floorDiv(x[node_id] - xl, bin_size_x, 0), 0); + int bin_id_xh = std::min((int)ceilDiv((x[node_id] + node_size_x[node_id] - xl), bin_size_x, 0), num_bins_x); + int bin_id_yl = std::max((int)floorDiv(y[node_id] - yl, bin_size_y, 0), 0); + int bin_id_yh = std::min((int)ceilDiv((y[node_id] + node_size_y[node_id] - yl), bin_size_y, 0), num_bins_y); for (int bin_id_x = bin_id_xl; bin_id_x < bin_id_xh; ++bin_id_x) { for (int bin_id_y = bin_id_yl; bin_id_y < bin_id_yh; ++bin_id_y) { diff --git a/src/detail_placement.py b/src/detail_placement.py index c18ff91..7bbf370 100644 --- a/src/detail_placement.py +++ b/src/detail_placement.py @@ -326,15 +326,17 @@ def run_lg(node_pos: torch.Tensor, data: PlaceData, args, logger): num_bins_x, num_bins_y = 1, 64 if not is_high_util: gpudp.greedyLegalization(lg_rawdb, num_bins_x, num_bins_y, True) + logger.info("Start checking...") if is_high_util or not lg_rawdb.check(get_ori_scale_factor(data)): logger.warning("Check failed in Greedy Legalization. Re-try by Greedy + Filler Legalization.") - + # NOTE: this greedy legalization only legalizes movable connected cells logger.info("Start running Greedy Legalization...") gpudp.greedyLegalization(lg_rawdb, num_bins_x, num_bins_y, False) # NOTE: filler legalization only legalizes movable unconnected cells (fillers) logger.info("Start Filler Legalization...") gpudp.fillerLegalization(lg_rawdb) + logger.info("Start checking...") if not lg_rawdb.check(get_ori_scale_factor(data)): logger.error("Check failed in Greedy + Filler Legalization.") logger.info("Finish Greedy + Filler Legalization. Time: %.4f" % (time.time() - gl_time)) @@ -352,6 +354,7 @@ def run_lg(node_pos: torch.Tensor, data: PlaceData, args, logger): logger.info("Start running Abacus Legalization...") al_time = time.time() gpudp.abacusLegalization(lg_rawdb, num_bins_x, num_bins_y) + logger.info("Start checking...") if not lg_rawdb.check(get_ori_scale_factor(data)): logger.error("Check failed in Abacus Legalization") logger.info("Finish Abacus Legalization. Time: %.4f" % (time.time() - al_time)) @@ -401,8 +404,6 @@ def trace_ops(func, *args): def run_dp(node_pos: torch.Tensor, data: PlaceData, args, logger): # GPU Detailed Placement dp_rawdb = setup_detailed_rawdb(node_pos, False, data, args, logger) - # CPU Legality Check - check_rawdb = setup_detailed_rawdb(node_pos, True, data, args, logger) num_bins_x = data.num_bin_x num_bins_y = data.num_bin_y @@ -430,11 +431,12 @@ def run_dp(node_pos: torch.Tensor, data: PlaceData, args, logger): dp_rawdb.scale(scalar, False) # commit lpos for legality check torch.cuda.synchronize(node_pos.device) - check_rawdb.commit_from(dp_rawdb.get_curr_lposx().cpu(), dp_rawdb.get_curr_lposy().cpu()) - if not check_rawdb.check(get_ori_scale_factor(data)): + logger.info("Start checking...") + if not dp_rawdb.check(get_ori_scale_factor(data)): dp_rawdb.rollback() logger.error("Check failed in %s. Rollback to previous DP iteration." % func_name) return + logger.info("Check Pass. Commit solution...") # update dp_rawdb for next step dp_func and update the final solution dp_rawdb.commit() commit_to_node_pos(node_pos, data, dp_rawdb) @@ -450,7 +452,7 @@ def run_dp(node_pos: torch.Tensor, data: PlaceData, args, logger): if args.scale_design: node_pos /= data.die_scale - del check_rawdb, dp_rawdb + del dp_rawdb return node_pos diff --git a/utils/get_design_params.py b/utils/get_design_params.py index 83a9c7f..fdd3f92 100644 --- a/utils/get_design_params.py +++ b/utils/get_design_params.py @@ -187,7 +187,7 @@ def get_custom_design_params(args): return params -def get_custom_json_params(args): +def get_custom_json_params(args, logger): import json with open(args.custom_json, 'r') as f: params = json.load(f) @@ -197,4 +197,15 @@ def get_custom_json_params(args): raise ValueError("Cannot find 'design_name' in args.custom_path") args.dataset = params["benchmark"] args.design_name = params["design_name"] + if "lefs" in params.keys(): + logger.info("Detect json LEF/DEF mode. Please make sure that tech_lef are included first.") + lefs = params["lefs"] + for i in range(len(lefs)): + # Simple heuristic to find tech_lef (Only for ASAP7, Nangate45, Sky130, GF180) + if i == 0: + continue + if "tech" in lefs[i] or ".tlef" in lefs[i]: + lefs[i], lefs[0] = lefs[0], lefs[i] + break + params["lefs"] = lefs return params \ No newline at end of file diff --git a/utils/setup_dataset.py b/utils/setup_dataset.py index 2fe26bd..b4a0aa7 100644 --- a/utils/setup_dataset.py +++ b/utils/setup_dataset.py @@ -5,8 +5,7 @@ def find_design_params(args, logger, placement=None): if args.custom_path != "": params = get_custom_design_params(args) elif args.custom_json != "": - logger.info("Detect json mode. Please make sure that tech_lef are included first.") - params = get_custom_json_params(args) + params = get_custom_json_params(args, logger) else: params = get_single_design_params( args.dataset_root, args.dataset, args.design_name, placement