def forward(self, pos): if self.initial_density_map is None: if self.num_terminals == 0: num_fixed_impacted_bins_x = 0 num_fixed_impacted_bins_y = 0 else: num_fixed_impacted_bins_x = ((self.node_size_x[self.num_movable_nodes:self.num_movable_nodes+self.num_terminals].max()+self.bin_size_x)/self.bin_size_x).ceil().clamp(max=self.num_bins_x) num_fixed_impacted_bins_y = ((self.node_size_y[self.num_movable_nodes:self.num_movable_nodes+self.num_terminals].max()+self.bin_size_y)/self.bin_size_y).ceil().clamp(max=self.num_bins_y) if pos.is_cuda: self.initial_density_map = electric_potential_cuda.fixed_density_map( pos.view(pos.numel()), self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y ) else: self.initial_density_map = electric_potential_cpp.fixed_density_map( pos.view(pos.numel()), self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y ) #plot(0, self.initial_density_map.clone().div(self.bin_size_x*self.bin_size_y).cpu().numpy(), self.padding, 'summary/initial_potential_map') # scale density of fixed macros self.initial_density_map.mul_(self.target_density) return ElectricOverflowFunction.apply( pos, self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.initial_density_map, self.target_density, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_filler_nodes, self.padding, self.padding_mask, self.num_bins_x, self.num_bins_y, self.num_movable_impacted_bins_x, self.num_movable_impacted_bins_y, self.num_filler_impacted_bins_x, self.num_filler_impacted_bins_y )
def compute_initial_density_map(self, pos): if self.num_terminals == 0: num_fixed_impacted_bins_x = 0 num_fixed_impacted_bins_y = 0 else: max_size_x = self.node_size_x[self.num_movable_nodes:self. num_movable_nodes + self.num_terminals].max() max_size_y = self.node_size_y[self.num_movable_nodes:self. num_movable_nodes + self.num_terminals].max() num_fixed_impacted_bins_x = ((max_size_x + self.bin_size_x) / self.bin_size_x).ceil().clamp( max=self.num_bins_x) num_fixed_impacted_bins_y = ((max_size_y + self.bin_size_y) / self.bin_size_y).ceil().clamp( max=self.num_bins_y) if pos.is_cuda: self.initial_density_map = electric_potential_cuda.fixed_density_map( pos, self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y, self.deterministic_flag) else: self.buf = torch.empty(self.num_threads * self.num_bins_x * self.num_bins_y, dtype=pos.dtype, device=pos.device) self.initial_density_map = electric_potential_cpp.fixed_density_map( pos, self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.buf, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y, self.num_threads) # scale density of fixed macros self.initial_density_map.mul_(self.target_density)
def forward(self, pos): if self.initial_density_map is None: if self.num_terminals == 0: num_fixed_impacted_bins_x = 0 num_fixed_impacted_bins_y = 0 else: num_fixed_impacted_bins_x = int(((self.node_size_x[self.num_movable_nodes:self.num_movable_nodes + self.num_terminals].max( ) + self.bin_size_x) / self.bin_size_x).ceil().clamp(max=self.num_bins_x)) num_fixed_impacted_bins_y = int(((self.node_size_y[self.num_movable_nodes:self.num_movable_nodes + self.num_terminals].max( ) + self.bin_size_y) / self.bin_size_y).ceil().clamp(max=self.num_bins_y)) if pos.is_cuda: self.initial_density_map = electric_potential_cuda.fixed_density_map( pos.view(pos.numel()), self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y ) else: self.buf = torch.empty(self.num_threads * self.num_bins_x * self.num_bins_y, dtype=pos.dtype, device=pos.device) self.initial_density_map = electric_potential_cpp.fixed_density_map( pos.view(pos.numel()), self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.buf, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y, self.num_threads ) # plot(0, self.initial_density_map.clone().div(self.bin_size_x*self.bin_size_y).cpu().numpy(), self.padding, 'summary/initial_potential_map') logger.info("fixed density map: average %g, max %g, bin area %g" % (self.initial_density_map.mean(), self.initial_density_map.max(), self.bin_size_x*self.bin_size_y)) # scale density of fixed macros self.initial_density_map.mul_(self.target_density) # expk M = self.num_bins_x N = self.num_bins_y self.exact_expkM = precompute_expk(M, dtype=pos.dtype, device=pos.device) self.exact_expkN = precompute_expk(N, dtype=pos.dtype, device=pos.device) # init dct2, idct2, idct_idxst, idxst_idct with expkM and expkN self.dct2 = dct.DCT2(self.exact_expkM, self.exact_expkN) if not self.fast_mode: self.idct2 = dct.IDCT2(self.exact_expkM, self.exact_expkN) self.idct_idxst = dct.IDCT_IDXST(self.exact_expkM, self.exact_expkN) self.idxst_idct = dct.IDXST_IDCT(self.exact_expkM, self.exact_expkN) # wu and wv wu = torch.arange(M, dtype=pos.dtype, device=pos.device).mul(2 * np.pi / M).view([M, 1]) # scale wv because the aspect ratio of a bin may not be 1 wv = torch.arange(N, dtype=pos.dtype, device=pos.device).mul(2 * np.pi / N).view([1, N]).mul_(self.bin_size_x / self.bin_size_y) wu2_plus_wv2 = wu.pow(2) + wv.pow(2) wu2_plus_wv2[0, 0] = 1.0 # avoid zero-division, it will be zeroed out self.inv_wu2_plus_wv2 = 1.0 / wu2_plus_wv2 self.inv_wu2_plus_wv2[0, 0] = 0.0 self.wu_by_wu2_plus_wv2_half = wu.mul(self.inv_wu2_plus_wv2).mul_(1./ 2) self.wv_by_wu2_plus_wv2_half = wv.mul(self.inv_wu2_plus_wv2).mul_(1./ 2) return ElectricPotentialFunction.apply( pos, self.node_size_x_clamped, self.node_size_y_clamped, self.offset_x, self.offset_y, self.ratio, self.bin_center_x, self.bin_center_y, self.initial_density_map, self.buf, self.target_density, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_filler_nodes, self.padding, self.padding_mask, self.num_bins_x, self.num_bins_y, self.num_movable_impacted_bins_x, self.num_movable_impacted_bins_y, self.num_filler_impacted_bins_x, self.num_filler_impacted_bins_y, self.sorted_node_map, self.exact_expkM, self.exact_expkN, self.inv_wu2_plus_wv2, self.wu_by_wu2_plus_wv2_half, self.wv_by_wu2_plus_wv2_half, self.dct2, self.idct2, self.idct_idxst, self.idxst_idct, self.fast_mode, self.num_threads )
def forward(self, pos): if self.initial_density_map is None: if self.num_terminals == 0: num_fixed_impacted_bins_x = 0 num_fixed_impacted_bins_y = 0 else: num_fixed_impacted_bins_x = int( ((self.node_size_x[ self.num_movable_nodes:self.num_movable_nodes + self.num_terminals].max() + self.bin_size_x) / self.bin_size_x).ceil().clamp(max=self.num_bins_x)) num_fixed_impacted_bins_y = int( ((self.node_size_y[ self.num_movable_nodes:self.num_movable_nodes + self.num_terminals].max() + self.bin_size_y) / self.bin_size_y).ceil().clamp(max=self.num_bins_y)) if pos.is_cuda: self.initial_density_map = electric_potential_cuda.fixed_density_map( pos.view(pos.numel()), self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y) else: self.initial_density_map = electric_potential_cpp.fixed_density_map( pos.view(pos.numel()), self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_terminals, self.num_bins_x, self.num_bins_y, num_fixed_impacted_bins_x, num_fixed_impacted_bins_y) #plot(0, self.initial_density_map.clone().div(self.bin_size_x*self.bin_size_y).cpu().numpy(), self.padding, 'summary/initial_potential_map') # scale density of fixed macros self.initial_density_map.mul_(self.target_density) # expk M = self.num_bins_x N = self.num_bins_y self.perm_M = discrete_spectral_transform.get_perm( M, dtype=torch.int64, device=pos.device) self.perm_N = discrete_spectral_transform.get_perm( N, dtype=torch.int64, device=pos.device) self.expk_M = discrete_spectral_transform.get_expk( M, dtype=pos.dtype, device=pos.device) self.expk_N = discrete_spectral_transform.get_expk( N, dtype=pos.dtype, device=pos.device) # wu and wv wu = torch.arange(M, dtype=pos.dtype, device=pos.device).mul( 2 * np.pi / M).view([M, 1]) # scale wv because the aspect ratio of a bin may not be 1 wv = torch.arange(N, dtype=pos.dtype, device=pos.device).mul(2 * np.pi / N).view( [1, N]).mul_(self.bin_size_x / self.bin_size_y) wu2_plus_wv2 = wu.pow(2) + wv.pow(2) wu2_plus_wv2[0, 0] = 1.0 # avoid zero-division, it will be zeroed out self.inv_wu2_plus_wv2_2X = 2.0 / wu2_plus_wv2 self.inv_wu2_plus_wv2_2X[0, 0] = 0.0 self.wu_by_wu2_plus_wv2_2X = wu.mul(self.inv_wu2_plus_wv2_2X) self.wv_by_wu2_plus_wv2_2X = wv.mul(self.inv_wu2_plus_wv2_2X) return ElectricPotentialFunction.apply( pos, self.node_size_x, self.node_size_y, self.bin_center_x, self.bin_center_y, self.initial_density_map, self.target_density, self.xl, self.yl, self.xh, self.yh, self.bin_size_x, self.bin_size_y, self.num_movable_nodes, self.num_filler_nodes, self.padding, self.padding_mask, self.num_bins_x, self.num_bins_y, self.num_movable_impacted_bins_x, self.num_movable_impacted_bins_y, self.num_filler_impacted_bins_x, self.num_filler_impacted_bins_y, self.perm_M, self.perm_N, self.expk_M, self.expk_N, self.inv_wu2_plus_wv2_2X, self.wu_by_wu2_plus_wv2_2X, self.wv_by_wu2_plus_wv2_2X, self.fast_mode)