def test_ispd2005(design, algorithm, device_str): with gzip.open(design, "rb") as f: if sys.version_info[0] < 3: data_collections = pickle.load(f) else: data_collections = pickle.load(f, encoding='bytes') node_size_x = data_collections[0] node_size_y = data_collections[1] flat_net2pin_map = data_collections[2] flat_net2pin_start_map = data_collections[3] pin2net_map = data_collections[4] flat_node2pin_map = data_collections[5] flat_node2pin_start_map = data_collections[6] pin2node_map = data_collections[7] pin_offset_x = data_collections[8] pin_offset_y = data_collections[9] net_mask_ignore_large_degrees = data_collections[10] xl = data_collections[11] yl = data_collections[12] xh = data_collections[13] yh = data_collections[14] site_width = data_collections[15] row_height = data_collections[16] num_bins_x = data_collections[17] num_bins_y = data_collections[18] num_movable_nodes = data_collections[19] num_filler_nodes = data_collections[20] pos = data_collections[21] #net_mask = net_mask_ignore_large_degrees net_mask = np.ones_like(net_mask_ignore_large_degrees) for i in range(1, len(flat_net2pin_start_map)): degree = flat_net2pin_start_map[i] - flat_net2pin_start_map[i - 1] if degree > 100: net_mask[i - 1] = 0 net_mask = torch.from_numpy(net_mask) #max_node_degree = 0 #for i in range(1, len(flat_node2pin_start_map)): # if i <= num_movable_nodes: # max_node_degree = max(max_node_degree, flat_node2pin_start_map[i]-flat_node2pin_start_map[i-1]) #print("max node degree %d" % (max_node_degree)) device = torch.device(device_str) #if device.type == 'cuda': # num_bins_x = int(2**(math.ceil(np.log2(math.sqrt(num_movable_nodes / 512))))) # num_bins_y = num_bins_x print("bins %dx%d" % (num_bins_x, num_bins_y)) print("num_movable_nodes %d, num_nodes %d" % (num_movable_nodes, node_size_x.numel() - num_filler_nodes)) # test cpu/cuda custom = global_swap.GlobalSwap( node_size_x=node_size_x.float().to(device), node_size_y=node_size_y.float().to(device), flat_net2pin_map=flat_net2pin_map.to(device), flat_net2pin_start_map=flat_net2pin_start_map.to(device), pin2net_map=pin2net_map.to(device), flat_node2pin_map=flat_node2pin_map.to(device), flat_node2pin_start_map=flat_node2pin_start_map.to(device), pin2node_map=pin2node_map.to(device), pin_offset_x=pin_offset_x.float().to(device), pin_offset_y=pin_offset_y.float().to(device), net_mask=net_mask.to(device), xl=xl, yl=yl, xh=xh, yh=yh, site_width=site_width, row_height=row_height, num_bins_x=num_bins_x // 2, num_bins_y=num_bins_y // 2, num_movable_nodes=num_movable_nodes, num_filler_nodes=num_filler_nodes, batch_size=256, max_iters=2, algorithm=algorithm, num_threads=20) result = custom(pos.float().to(device))
def build_detailed_placement(self, params, placedb, data_collections, device): """ @brief detailed placement consisting of global swap and independent set matching @param params parameters @param placedb placement database @param data_collections a collection of all data and variables required for constructing the ops @param device cpu or cuda """ gs = global_swap.GlobalSwap( node_size_x=data_collections.node_size_x, node_size_y=data_collections.node_size_y, flat_region_boxes=data_collections.flat_region_boxes, flat_region_boxes_start=data_collections.flat_region_boxes_start, node2fence_region_map=data_collections.node2fence_region_map, flat_net2pin_map=data_collections.flat_net2pin_map, flat_net2pin_start_map=data_collections.flat_net2pin_start_map, pin2net_map=data_collections.pin2net_map, flat_node2pin_map=data_collections.flat_node2pin_map, flat_node2pin_start_map=data_collections.flat_node2pin_start_map, pin2node_map=data_collections.pin2node_map, pin_offset_x=data_collections.pin_offset_x, pin_offset_y=data_collections.pin_offset_y, net_mask=data_collections.net_mask_ignore_large_degrees, xl=placedb.xl, yl=placedb.yl, xh=placedb.xh, yh=placedb.yh, site_width=placedb.site_width, row_height=placedb.row_height, #num_bins_x=placedb.num_bins_x//16, num_bins_y=placedb.num_bins_y//16, num_bins_x=placedb.num_bins_x // 2, num_bins_y=placedb.num_bins_y // 2, num_movable_nodes=placedb.num_movable_nodes, num_terminal_NIs=placedb.num_terminal_NIs, num_filler_nodes=placedb.num_filler_nodes, batch_size=256, max_iters=2, algorithm='concurrent') kr = k_reorder.KReorder( node_size_x=data_collections.node_size_x, node_size_y=data_collections.node_size_y, flat_region_boxes=data_collections.flat_region_boxes, flat_region_boxes_start=data_collections.flat_region_boxes_start, node2fence_region_map=data_collections.node2fence_region_map, flat_net2pin_map=data_collections.flat_net2pin_map, flat_net2pin_start_map=data_collections.flat_net2pin_start_map, pin2net_map=data_collections.pin2net_map, flat_node2pin_map=data_collections.flat_node2pin_map, flat_node2pin_start_map=data_collections.flat_node2pin_start_map, pin2node_map=data_collections.pin2node_map, pin_offset_x=data_collections.pin_offset_x, pin_offset_y=data_collections.pin_offset_y, net_mask=data_collections.net_mask_ignore_large_degrees, xl=placedb.xl, yl=placedb.yl, xh=placedb.xh, yh=placedb.yh, site_width=placedb.site_width, row_height=placedb.row_height, num_bins_x=placedb.num_bins_x, num_bins_y=placedb.num_bins_y, num_movable_nodes=placedb.num_movable_nodes, num_terminal_NIs=placedb.num_terminal_NIs, num_filler_nodes=placedb.num_filler_nodes, K=4, max_iters=2) ism = independent_set_matching.IndependentSetMatching( node_size_x=data_collections.node_size_x, node_size_y=data_collections.node_size_y, flat_region_boxes=data_collections.flat_region_boxes, flat_region_boxes_start=data_collections.flat_region_boxes_start, node2fence_region_map=data_collections.node2fence_region_map, flat_net2pin_map=data_collections.flat_net2pin_map, flat_net2pin_start_map=data_collections.flat_net2pin_start_map, pin2net_map=data_collections.pin2net_map, flat_node2pin_map=data_collections.flat_node2pin_map, flat_node2pin_start_map=data_collections.flat_node2pin_start_map, pin2node_map=data_collections.pin2node_map, pin_offset_x=data_collections.pin_offset_x, pin_offset_y=data_collections.pin_offset_y, net_mask=data_collections.net_mask_ignore_large_degrees, xl=placedb.xl, yl=placedb.yl, xh=placedb.xh, yh=placedb.yh, site_width=placedb.site_width, row_height=placedb.row_height, num_bins_x=placedb.num_bins_x, num_bins_y=placedb.num_bins_y, num_movable_nodes=placedb.num_movable_nodes, num_terminal_NIs=placedb.num_terminal_NIs, num_filler_nodes=placedb.num_filler_nodes, batch_size=2048, set_size=128, max_iters=50, algorithm='concurrent') # wirelength for position def build_detailed_placement_op(pos): logging.info("Start ABCDPlace for refinement") pos1 = pos legal = self.op_collections.legality_check_op(pos1) logging.info("ABCDPlace input legal flag = %d" % (legal)) if not legal: return pos1 # integer factorization to prime numbers def prime_factorization(num): lt = [] while num != 1: for i in range(2, int(num + 1)): if num % i == 0: # i is a prime factor lt.append(i) num = num / i # get the quotient for further factorization break return lt # compute the scale factor for detailed placement # as the algorithms prefer integer coordinate systems scale_factor = params.scale_factor if params.scale_factor != 1.0: inv_scale_factor = int(round(1.0 / params.scale_factor)) prime_factors = prime_factorization(inv_scale_factor) target_inv_scale_factor = 1 for factor in prime_factors: if factor != 2 and factor != 5: target_inv_scale_factor = inv_scale_factor break scale_factor = 1.0 / target_inv_scale_factor logging.info("Deriving from system scale factor %g (1/%d)" % (params.scale_factor, inv_scale_factor)) logging.info( "Use scale factor %g (1/%d) for detailed placement" % (scale_factor, target_inv_scale_factor)) for i in range(1): pos1 = kr(pos1, scale_factor) legal = self.op_collections.legality_check_op(pos1) logging.info("K-Reorder legal flag = %d" % (legal)) if not legal: return pos1 pos1 = ism(pos1, scale_factor) legal = self.op_collections.legality_check_op(pos1) logging.info("Independent set matching legal flag = %d" % (legal)) if not legal: return pos1 pos1 = gs(pos1, scale_factor) legal = self.op_collections.legality_check_op(pos1) logging.info("Global swap legal flag = %d" % (legal)) if not legal: return pos1 pos1 = kr(pos1, scale_factor) legal = self.op_collections.legality_check_op(pos1) logging.info("K-Reorder legal flag = %d" % (legal)) if not legal: return pos1 return pos1 return build_detailed_placement_op
def test_random(self): dtype = np.float64 xx = np.array([1.0, 1.5, 3.0]).astype(dtype) yy = np.array([1.0, 3.0, 1.0]).astype(dtype) node_size_x = np.array([1.0, 2.0, 1.0]).astype(dtype) node_size_y = np.array([2.0, 2.0, 2.0]).astype(dtype) num_nodes = len(xx) net2pin_map = np.array([np.array([0, 4]), np.array([1, 2, 3])]) pin2net_map, flat_net2pin_map, flat_net2pin_start_map = flatten_2D_map( net2pin_map) node2pin_map = np.array( [np.array([0, 1]), np.array([2]), np.array([3, 4])]) pin2node_map, flat_node2pin_map, flat_node2pin_start_map = flatten_2D_map( node2pin_map) # net mask ignore_net_degree = 4 net_mask = np.ones(len(net2pin_map), dtype=np.uint8) for i in range(len(net2pin_map)): if len(net2pin_map[i]) >= ignore_net_degree: net_mask[i] = 0 # pin offset pin_offset_x = np.zeros(len(pin2net_map)) pin_offset_y = np.zeros(len(pin2net_map)) xl = 1.0 yl = 1.0 xh = 5.0 yh = 5.0 num_terminals = 0 num_terminal_NIs = 0 num_filler_nodes = 0 num_movable_nodes = len( xx) - num_terminals - num_terminal_NIs - num_filler_nodes site_width = 1 row_height = 2 num_bins_x = 2 num_bins_y = 2 batch_size = 32 print("flat_net2pin_map = ", flat_net2pin_map) print("flat_net2pin_start_map = ", flat_net2pin_start_map) print("flat_node2pin_map = ", flat_node2pin_map) print("flat_node2pin_start_map = ", flat_node2pin_start_map) plot( "initial.png", xx, yy, node_size_x, node_size_y, xl, yl, xh, yh, num_bins_x, num_bins_y, num_movable_nodes + num_terminals + num_terminal_NIs + num_filler_nodes, num_movable_nodes, num_movable_nodes + num_terminals + num_terminal_NIs, num_filler_nodes) # test cpu custom = global_swap.GlobalSwap( torch.from_numpy(node_size_x), torch.from_numpy(node_size_y), torch.from_numpy(flat_net2pin_map), torch.from_numpy(flat_net2pin_start_map), torch.from_numpy(pin2net_map), torch.from_numpy(flat_node2pin_map), torch.from_numpy(flat_node2pin_start_map), torch.from_numpy(pin2node_map), torch.from_numpy(pin_offset_x), torch.from_numpy(pin_offset_y), torch.from_numpy(net_mask), xl=xl, yl=yl, xh=xh, yh=yh, site_width=site_width, row_height=row_height, num_bins_x=num_bins_x, num_bins_y=num_bins_y, num_movable_nodes=num_movable_nodes, num_terminal_NIs=num_terminal_NIs, num_filler_nodes=num_filler_nodes, batch_size=batch_size) pos = Variable(torch.from_numpy(np.concatenate([xx, yy]))) result = custom(pos) print("initial result = ", np.concatenate([xx, yy])) print("custom_result = ", result) print("average displacement = %g" % (np.sum(np.absolute(result.numpy() - np.concatenate([xx, yy]))) / num_movable_nodes)) plot( "final.png", result.numpy()[0:len(xx)], result.numpy()[len(xx):], node_size_x, node_size_y, xl, yl, xh, yh, num_bins_x, num_bins_y, num_movable_nodes + num_terminals + num_terminal_NIs + num_filler_nodes, num_movable_nodes, num_movable_nodes + num_terminals + num_terminal_NIs, num_filler_nodes) # test cuda custom_cuda = global_swap.GlobalSwap( torch.from_numpy(node_size_x).cuda(), torch.from_numpy(node_size_y).cuda(), torch.from_numpy(flat_net2pin_map).cuda(), torch.from_numpy(flat_net2pin_start_map).cuda(), torch.from_numpy(pin2net_map).cuda(), torch.from_numpy(flat_node2pin_map).cuda(), torch.from_numpy(flat_node2pin_start_map).cuda(), torch.from_numpy(pin2node_map).cuda(), torch.from_numpy(pin_offset_x).cuda(), torch.from_numpy(pin_offset_y).cuda(), torch.from_numpy(net_mask).cuda(), xl=xl, yl=yl, xh=xh, yh=yh, site_width=site_width, row_height=row_height, num_bins_x=num_bins_x, num_bins_y=num_bins_y, num_movable_nodes=num_movable_nodes, num_terminal_NIs=num_terminal_NIs, num_filler_nodes=num_filler_nodes, batch_size=batch_size) pos = Variable(torch.from_numpy(np.concatenate([xx, yy]))).cuda() result_cuda = custom_cuda(pos) print("custom_result = ", result_cuda.data.cpu())
def build_detailed_placement(self, params, placedb, data_collections, device): """ @brief detailed placement consisting of global swap and independent set matching @param params parameters @param placedb placement database @param data_collections a collection of all data and variables required for constructing the ops @param device cpu or cuda """ gs = global_swap.GlobalSwap( node_size_x=data_collections.node_size_x, node_size_y=data_collections.node_size_y, flat_region_boxes=data_collections.flat_region_boxes, flat_region_boxes_start=data_collections.flat_region_boxes_start, node2fence_region_map=data_collections.node2fence_region_map, flat_net2pin_map=data_collections.flat_net2pin_map, flat_net2pin_start_map=data_collections.flat_net2pin_start_map, pin2net_map=data_collections.pin2net_map, flat_node2pin_map=data_collections.flat_node2pin_map, flat_node2pin_start_map=data_collections.flat_node2pin_start_map, pin2node_map=data_collections.pin2node_map, pin_offset_x=data_collections.pin_offset_x, pin_offset_y=data_collections.pin_offset_y, net_mask=data_collections.net_mask_ignore_large_degrees, xl=placedb.xl, yl=placedb.yl, xh=placedb.xh, yh=placedb.yh, site_width=placedb.site_width, row_height=placedb.row_height, #num_bins_x=placedb.num_bins_x//16, num_bins_y=placedb.num_bins_y//16, num_bins_x=placedb.num_bins_x // 2, num_bins_y=placedb.num_bins_y // 2, num_movable_nodes=placedb.num_movable_nodes, num_terminal_NIs=placedb.num_terminal_NIs, num_filler_nodes=placedb.num_filler_nodes, batch_size=256, max_iters=2, algorithm='concurrent', num_threads=params.num_threads) kr = k_reorder.KReorder( node_size_x=data_collections.node_size_x, node_size_y=data_collections.node_size_y, flat_region_boxes=data_collections.flat_region_boxes, flat_region_boxes_start=data_collections.flat_region_boxes_start, node2fence_region_map=data_collections.node2fence_region_map, flat_net2pin_map=data_collections.flat_net2pin_map, flat_net2pin_start_map=data_collections.flat_net2pin_start_map, pin2net_map=data_collections.pin2net_map, flat_node2pin_map=data_collections.flat_node2pin_map, flat_node2pin_start_map=data_collections.flat_node2pin_start_map, pin2node_map=data_collections.pin2node_map, pin_offset_x=data_collections.pin_offset_x, pin_offset_y=data_collections.pin_offset_y, net_mask=data_collections.net_mask_ignore_large_degrees, xl=placedb.xl, yl=placedb.yl, xh=placedb.xh, yh=placedb.yh, site_width=placedb.site_width, row_height=placedb.row_height, num_bins_x=placedb.num_bins_x, num_bins_y=placedb.num_bins_y, num_movable_nodes=placedb.num_movable_nodes, num_terminal_NIs=placedb.num_terminal_NIs, num_filler_nodes=placedb.num_filler_nodes, K=4, max_iters=2, num_threads=params.num_threads) ism = independent_set_matching.IndependentSetMatching( node_size_x=data_collections.node_size_x, node_size_y=data_collections.node_size_y, flat_region_boxes=data_collections.flat_region_boxes, flat_region_boxes_start=data_collections.flat_region_boxes_start, node2fence_region_map=data_collections.node2fence_region_map, flat_net2pin_map=data_collections.flat_net2pin_map, flat_net2pin_start_map=data_collections.flat_net2pin_start_map, pin2net_map=data_collections.pin2net_map, flat_node2pin_map=data_collections.flat_node2pin_map, flat_node2pin_start_map=data_collections.flat_node2pin_start_map, pin2node_map=data_collections.pin2node_map, pin_offset_x=data_collections.pin_offset_x, pin_offset_y=data_collections.pin_offset_y, net_mask=data_collections.net_mask_ignore_large_degrees, xl=placedb.xl, yl=placedb.yl, xh=placedb.xh, yh=placedb.yh, site_width=placedb.site_width, row_height=placedb.row_height, num_bins_x=placedb.num_bins_x, num_bins_y=placedb.num_bins_y, num_movable_nodes=placedb.num_movable_nodes, num_terminal_NIs=placedb.num_terminal_NIs, num_filler_nodes=placedb.num_filler_nodes, batch_size=2048, set_size=128, max_iters=50, algorithm='concurrent', num_threads=params.num_threads) # wirelength for position def build_detailed_placement_op(pos): logging.info("Start ABCDPlace for refinement") pos1 = pos for i in range(1): pos1 = kr(pos1) legal = self.op_collections.legality_check_op(pos1) logging.info("K-Reorder legal flag = %d" % (legal)) if not legal: return pos1 pos1 = ism(pos1) legal = self.op_collections.legality_check_op(pos1) logging.info("Independent set matching legal flag = %d" % (legal)) if not legal: return pos1 pos1 = gs(pos1) legal = self.op_collections.legality_check_op(pos1) logging.info("Global swap legal flag = %d" % (legal)) if not legal: return pos1 pos1 = kr(pos1) legal = self.op_collections.legality_check_op(pos1) logging.info("K-Reorder legal flag = %d" % (legal)) if not legal: return pos1 return pos1 return build_detailed_placement_op