예제 #1
0
    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
예제 #2
0
    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())