Esempio n. 1
0
    def build_hpwl(self, params, placedb, data_collections, pin_pos_op,
                   device):
        """
        @brief compute half-perimeter wirelength 
        @param params parameters 
        @param placedb placement database 
        @param data_collections a collection of all data and variables required for constructing the ops 
        @param pin_pos_op the op to compute pin locations according to cell locations 
        @param device cpu or cuda 
        """

        wirelength_for_pin_op = hpwl.HPWL(
            flat_netpin=data_collections.flat_net2pin_map,
            netpin_start=data_collections.flat_net2pin_start_map,
            pin2net_map=data_collections.pin2net_map,
            net_weights=data_collections.net_weights,
            net_mask=data_collections.net_mask_all,
            algorithm='net-by-net',
            num_threads=params.num_threads)

        # wirelength for position
        def build_wirelength_op(pos):
            return wirelength_for_pin_op(pin_pos_op(pos))

        return build_wirelength_op
Esempio n. 2
0
    def test_hpwlRandom(self):
        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=np.float32)
        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)

        # construct pin2net_map
        pin2net_map = np.zeros(len(pin_pos), dtype=np.int32)
        for i in range(len(net2pin_map)):
            for pin_id in net2pin_map[i]:
                pin2net_map[pin_id] = i
        print("pin2net_map = ", pin2net_map)

        # net degrees
        net_degrees = np.array([len(net2pin) for net2pin in net2pin_map])
        net_mask = (net_degrees <= np.amax(net_degrees)).astype(np.uint8)
        print("net_mask = ", net_mask)

        golden_value = all_hpwl(pin_x, pin_y, net2pin_map)
        print("golden_value = ", golden_value)

        # 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()
        custom = hpwl.HPWL(
            flat_netpin=torch.from_numpy(flat_net2pin_map),
            netpin_start=torch.from_numpy(flat_net2pin_start_map),
            pin2net_map=torch.from_numpy(pin2net_map),
            net_mask=torch.from_numpy(net_mask),
            algorithm='net-by-net')
        hpwl_value = custom.forward(pin_pos_var)
        print("hpwl_value = ", hpwl_value.data.numpy())
        np.testing.assert_allclose(hpwl_value.data.numpy(), golden_value)

        # test gpu
        if torch.cuda.device_count():
            custom_cuda = hpwl.HPWL(
                flat_netpin=torch.from_numpy(flat_net2pin_map).cuda(),
                netpin_start=torch.from_numpy(flat_net2pin_start_map).cuda(),
                pin2net_map=torch.from_numpy(pin2net_map).cuda(),
                net_mask=torch.from_numpy(net_mask).cuda(),
                algorithm='net-by-net')
            hpwl_value = custom_cuda.forward(pin_pos_var.cuda())
            print("hpwl_value cuda = ", hpwl_value.data.cpu().numpy())
            np.testing.assert_allclose(hpwl_value.data.cpu().numpy(),
                                       golden_value)

        # test atomic cpu
        custom_atomic = hpwl.HPWL(
            flat_netpin=torch.from_numpy(flat_net2pin_map),
            netpin_start=torch.from_numpy(flat_net2pin_start_map),
            pin2net_map=torch.from_numpy(pin2net_map),
            net_mask=torch.from_numpy(net_mask),
            algorithm='atomic')
        hpwl_value = custom_atomic.forward(pin_pos_var)
        print("hpwl_value atomic = ", hpwl_value.data.numpy())
        np.testing.assert_allclose(hpwl_value.data.numpy(), golden_value)

        # test atomic gpu
        if torch.cuda.device_count():
            custom_cuda_atomic = hpwl.HPWL(
                flat_netpin=torch.from_numpy(flat_net2pin_map).cuda(),
                netpin_start=torch.from_numpy(flat_net2pin_start_map).cuda(),
                pin2net_map=torch.from_numpy(pin2net_map).cuda(),
                net_mask=torch.from_numpy(net_mask).cuda(),
                algorithm='atomic')
            hpwl_value = custom_cuda_atomic.forward(pin_pos_var.cuda())
            print("hpwl_value cuda atomic = ", hpwl_value.data.cpu().numpy())
            np.testing.assert_allclose(hpwl_value.data.cpu().numpy(),
                                       golden_value)