def build_rmst_wl(self, params, placedb, pin_pos_op, device): """ @brief compute rectilinear minimum spanning tree wirelength with flute @param params parameters @param placedb placement database @param pin_pos_op the op to compute pin locations according to cell locations @param device cpu or cuda """ # wirelength cost POWVFILE = os.path.abspath( os.path.join(os.path.dirname(__file__), "../../thirdparty/flute-3.1/POWV9.dat")) POSTFILE = os.path.abspath( os.path.join(os.path.dirname(__file__), "../../thirdparty/flute-3.1/POST9.dat")) print("POWVFILE = %s" % (POWVFILE)) print("POSTFILE = %s" % (POSTFILE)) wirelength_for_pin_op = rmst_wl.RMSTWL( flat_netpin=torch.from_numpy(placedb.flat_net2pin_map).to(device), netpin_start=torch.from_numpy( placedb.flat_net2pin_start_map).to(device), ignore_net_degree=params.ignore_net_degree, POWVFILE=POWVFILE, POSTFILE=POSTFILE) # wirelength for position def build_wirelength_op(pos): pin_pos = pin_pos_op(pos) wls = wirelength_for_pin_op(pin_pos.clone().cpu(), self.read_lut_flag) self.read_lut_flag = False return wls return build_wirelength_op
def test_rmst_wlRandom(self): dtype = np.float64 pin_pos = np.array( [[0.0, 0.0], [1.0, 2.0], [1.5, 0.2], [0.5, 3.1], [0.6, 1.1]], dtype=dtype) net2pin_map = np.array([np.array([0, 4]), np.array([1, 2, 3])]) pin_x = pin_pos[:, 0] pin_y = pin_pos[:, 1] # construct flat_net2pin_map and flat_net2pin_start_map # flat netpin map, length of #pins flat_net2pin_map = np.zeros(len(pin_pos), 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]) flat_net2pin_start_map[len(net2pin_map)] = len(pin_pos) print("flat_net2pin_map = ", flat_net2pin_map) print("flat_net2pin_start_map = ", flat_net2pin_start_map) # test cpu print(np.transpose(pin_pos)) pin_pos_var = Variable(torch.from_numpy(pin_pos)) print(pin_pos_var) # clone is very important, because the custom op cannot deep copy the data pin_pos_var = torch.t(pin_pos_var).contiguous() #pdb.set_trace() project_path = os.path.abspath( os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) POWVFILE = os.path.join(project_path, "thirdparty/flute/POWV9.dat") POSTFILE = os.path.join(project_path, "thirdparty/flute/POST9.dat") custom = rmst_wl.RMSTWL(torch.from_numpy(flat_net2pin_map), torch.from_numpy(flat_net2pin_start_map), torch.tensor(len(flat_net2pin_map)), POWVFILE=POWVFILE, POSTFILE=POSTFILE) rmst_wl_value = custom.forward(pin_pos_var, read_lut_flag=True) print("rmst_wl_value = ", rmst_wl_value.data.numpy()) rmst_wl_value = custom.forward(pin_pos_var, read_lut_flag=False) print("rmst_wl_value = ", rmst_wl_value.data.numpy())