From 93f3ca3c9b175b12c31bb5944d6373d3786de8ca Mon Sep 17 00:00:00 2001 From: hanqing Date: Tue, 25 Oct 2022 12:13:17 -0500 Subject: [PATCH 1/2] support running DP in circuit training --- dreamplace/Params.py | 67 ++++++++++++++++++++++++++++++++++++++++ dreamplace/PlaceDB.py | 70 +++++++++++++++++++++++++----------------- dreamplace/params.json | 4 +++ 3 files changed, 113 insertions(+), 28 deletions(-) diff --git a/dreamplace/Params.py b/dreamplace/Params.py index fea87584..2d73c9aa 100644 --- a/dreamplace/Params.py +++ b/dreamplace/Params.py @@ -169,3 +169,70 @@ def solution_file_suffix(self): return "def" else: # Bookshelf return "pl" + +def get_bin_size(width, height, num_bins=128*128): + """ + @brief find the power two bin size closest to the canvas ratio. + """ + num_bins_x = math.sqrt(num_bins * width / height) + num_bins_x = int(math.pow(2, round(math.log(num_bins_x) / math.log(2)))) + num_bins_x = max(min(num_bins_x, num_bins), 1) # constrain num_bins_x between 1 and num_bins + num_bins_y = int(num_bins / num_bins_x) + + return num_bins_x, num_bins_y + +def get_dreamplace_params( + iteration, + target_density, + learning_rate, + canvas_width=None, + canvas_height=None, + num_bins_x=None, + num_bins_y=None, + gpu=False, + result_dir='results', + legalize_flag=False, + stop_overflow=0.1, + routability_opt_flag=False): + """" + @brief return the parameters to config Dreamplace in circuit training. + """ + params = Params() + params.use_dp_for_circuit_training = True + + # set number of bins + if num_bins_x and num_bins_y: + params.num_bins_x = num_bins_x + params.num_bins_y = num_bins_y + elif canvas_width and canvas_height: + # extract #bins from canvas info + params.num_bins_x, params.num_bins_y = get_bin_size(canvas_width, + canvas_height) + else: + num_bins_x = 128 + num_bins_y = 128 + + params.global_place_stages = [{ + 'num_bins_x': params.num_bins_x, + 'num_bins_y': params.num_bins_y, + 'iteration': iteration, + 'learning_rate': learning_rate, + 'wirelength': 'weighted_average', + 'optimizer': 'nesterov', + }] + params.legalize_flag = legalize_flag + params.detailed_place_flag = False + params.target_density = target_density + params.density_weight = 8e-5 + params.gpu = gpu + params.result_dir = result_dir + params.stop_overflow = stop_overflow + + # disable regioning + params.regioning = False + + # routability related flag + params.routability_opt_flag = routability_opt_flag + params.adjust_nctugr_area_flag = False + + return params diff --git a/dreamplace/PlaceDB.py b/dreamplace/PlaceDB.py index 8fec3e3d..4b6c962f 100644 --- a/dreamplace/PlaceDB.py +++ b/dreamplace/PlaceDB.py @@ -87,6 +87,11 @@ def __init__(self): self.bin_size_y = None self.num_bins_x = None self.num_bins_y = None + + # add bin center and non movable macros info for circuit training + self.bin_center_x = None + self.bin_center_y = None + self.num_non_movable_macros = None self.num_movable_pins = None @@ -439,25 +444,26 @@ def print_row(self, row_id): """ logging.debug("row %d %s" % (row_id, self.rows[row_id])) - #def flatten_nested_map(self, net2pin_map): - # """ - # @brief flatten an array of array to two arrays like CSV format - # @param net2pin_map array of array - # @return a pair of (elements, cumulative column indices of the beginning element of each row) - # """ - # # flat netpin map, length of #pins - # flat_net2pin_map = np.zeros(len(pin2net_map), dtype=np.int32) - # # starting index in netpin map for each net, length of #nets+1, the last entry is #pins - # flat_net2pin_start_map = np.zeros(len(net2pin_map)+1, dtype=np.int32) - # count = 0 - # for i in range(len(net2pin_map)): - # flat_net2pin_map[count:count+len(net2pin_map[i])] = net2pin_map[i] - # flat_net2pin_start_map[i] = count - # count += len(net2pin_map[i]) - # assert flat_net2pin_map[-1] != 0 - # flat_net2pin_start_map[len(net2pin_map)] = len(pin2net_map) - - # return flat_net2pin_map, flat_net2pin_start_map + ## add this func for circuit training. + def flatten_nested_map(self, pin2net_map, net2pin_map): + """ + @brief flatten an array of array to two arrays like CSV format + @param net2pin_map array of array + @return a pair of (elements, cumulative column indices of the beginning element of each row) + """ + # flat netpin map, length of #pins + flat_net2pin_map = np.zeros(len(pin2net_map), dtype=np.int32) + # starting index in netpin map for each net, length of #nets+1, the last entry is #pins + flat_net2pin_start_map = np.zeros(len(net2pin_map)+1, dtype=np.int32) + count = 0 + for i in range(len(net2pin_map)): + flat_net2pin_map[count:count+len(net2pin_map[i])] = net2pin_map[i] + flat_net2pin_start_map[i] = count + count += len(net2pin_map[i]) + assert flat_net2pin_map[-1] != 0 + flat_net2pin_start_map[len(net2pin_map)] = len(pin2net_map) + + return flat_net2pin_map, flat_net2pin_start_map def read(self, params): """ @@ -582,7 +588,9 @@ def __call__(self, params): """ tt = time.time() - self.read(params) + # circuit training will not read local design. + if not params.use_dp_for_circuit_training: + self.read(params) self.initialize(params) logging.info("reading benchmark takes %g seconds" % (time.time()-tt)) @@ -679,14 +687,17 @@ def initialize(self, params): # shift and scale # adjust shift_factor and scale_factor if not set - params.shift_factor[0] = self.xl - params.shift_factor[1] = self.yl - logging.info("set shift_factor = (%g, %g), as original row bbox = (%g, %g, %g, %g)" - % (params.shift_factor[0], params.shift_factor[1], self.xl, self.yl, self.xh, self.yh)) - if params.scale_factor == 0.0 or self.site_width != 1.0: - params.scale_factor = 1.0 / self.site_width - logging.info("set scale_factor = %g, as site_width = %g" % (params.scale_factor, self.site_width)) - self.scale(params.shift_factor, params.scale_factor) + if not params.use_dp_for_circuit_training: + params.shift_factor[0] = self.xl + params.shift_factor[1] = self.yl + logging.info("set shift_factor = (%g, %g), as original row bbox = (%g, %g, %g, %g)" + % (params.shift_factor[0], params.shift_factor[1], self.xl, self.yl, self.xh, self.yh)) + if params.scale_factor == 0.0 or self.site_width != 1.0: + params.scale_factor = 1.0 / self.site_width + logging.info("set scale_factor = %g, as site_width = %g" % (params.scale_factor, self.site_width)) + self.scale(params.shift_factor, params.scale_factor) + else: + params.scale_factor = 1.0 content = """ ================================= Benchmark Statistics ================================= @@ -711,6 +722,9 @@ def initialize(self, params): # set bin size self.bin_size_x = (self.xh - self.xl) / self.num_bins_x self.bin_size_y = (self.yh - self.yl) / self.num_bins_y + #set bin center + self.bin_center_x = self.bin_centers(self.xl, self.xh, self.bin_size_x) + self.bin_center_y = self.bin_centers(self.yl, self.yh, self.bin_size_y) content += "num_bins = %dx%d, bin sizes = %gx%g\n" % (self.num_bins_x, self.num_bins_y, self.bin_size_x / self.row_height, self.bin_size_y / self.row_height) diff --git a/dreamplace/params.json b/dreamplace/params.json index 32931d9f..0fbb5ef3 100644 --- a/dreamplace/params.json +++ b/dreamplace/params.json @@ -219,5 +219,9 @@ "deterministic_flag" : { "descripton" : "whether require run-to-run determinism, may have efficiency overhead", "default" : 0 + }, +"use_dp_for_circuit_training" : { + "descripton" : "whether use Dreamplace for circuit training", + "default" : 0 } } From 6a69a02f5220094048d1d48f679def3622437585 Mon Sep 17 00:00:00 2001 From: hanqing Date: Tue, 29 Nov 2022 14:49:21 -0600 Subject: [PATCH 2/2] address comments --- dreamplace/Params.py | 2 +- dreamplace/PlaceDB.py | 10 ++-------- dreamplace/params.json | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/dreamplace/Params.py b/dreamplace/Params.py index 2d73c9aa..5db053d4 100644 --- a/dreamplace/Params.py +++ b/dreamplace/Params.py @@ -198,7 +198,7 @@ def get_dreamplace_params( @brief return the parameters to config Dreamplace in circuit training. """ params = Params() - params.use_dp_for_circuit_training = True + params.circuit_training_mode = True # set number of bins if num_bins_x and num_bins_y: diff --git a/dreamplace/PlaceDB.py b/dreamplace/PlaceDB.py index 4b6c962f..4abb7f4e 100644 --- a/dreamplace/PlaceDB.py +++ b/dreamplace/PlaceDB.py @@ -88,9 +88,6 @@ def __init__(self): self.num_bins_x = None self.num_bins_y = None - # add bin center and non movable macros info for circuit training - self.bin_center_x = None - self.bin_center_y = None self.num_non_movable_macros = None self.num_movable_pins = None @@ -589,7 +586,7 @@ def __call__(self, params): tt = time.time() # circuit training will not read local design. - if not params.use_dp_for_circuit_training: + if not params.circuit_training_mode: self.read(params) self.initialize(params) @@ -687,7 +684,7 @@ def initialize(self, params): # shift and scale # adjust shift_factor and scale_factor if not set - if not params.use_dp_for_circuit_training: + if not params.circuit_training_mode: params.shift_factor[0] = self.xl params.shift_factor[1] = self.yl logging.info("set shift_factor = (%g, %g), as original row bbox = (%g, %g, %g, %g)" @@ -722,9 +719,6 @@ def initialize(self, params): # set bin size self.bin_size_x = (self.xh - self.xl) / self.num_bins_x self.bin_size_y = (self.yh - self.yl) / self.num_bins_y - #set bin center - self.bin_center_x = self.bin_centers(self.xl, self.xh, self.bin_size_x) - self.bin_center_y = self.bin_centers(self.yl, self.yh, self.bin_size_y) content += "num_bins = %dx%d, bin sizes = %gx%g\n" % (self.num_bins_x, self.num_bins_y, self.bin_size_x / self.row_height, self.bin_size_y / self.row_height) diff --git a/dreamplace/params.json b/dreamplace/params.json index 0fbb5ef3..7bbe1ded 100644 --- a/dreamplace/params.json +++ b/dreamplace/params.json @@ -220,7 +220,7 @@ "descripton" : "whether require run-to-run determinism, may have efficiency overhead", "default" : 0 }, -"use_dp_for_circuit_training" : { +"circuit_training_mode" : { "descripton" : "whether use Dreamplace for circuit training", "default" : 0 }