benchmark.py 3.76 KB
Newer Older
yanyan's avatar
yanyan committed
1
2
3
4
5
import time
from pathlib import Path

import numpy as np
import torch
yanyan's avatar
yanyan committed
6
from torch import nn
yanyan's avatar
yanyan committed
7
8
9
10

import spconv
from spconv.utils import VoxelGeneratorV2

yanyan's avatar
yanyan committed
11
12

def waymo_data(batch_size=1):
yanyan's avatar
yanyan committed
13
14
    gen = VoxelGeneratorV2([0.1, 0.1, 0.1], [-80, -80, -2, 80, 80, 6], 1,
                           150000)
yanyan's avatar
yanyan committed
15
16
17
18
19
20
21
22
23
    data = np.load(Path(__file__).parent / "data" / "benchmark-pc.npz")
    pc = data["pc"]
    data = gen.generate(pc)
    voxels = data["voxels"].reshape(-1, 3)
    coors = data["coordinates"]
    N = coors.shape[0]
    coors = np.concatenate([np.full([N, 1], 0, coors.dtype), coors], axis=1)
    return voxels, coors, gen.grid_size

yanyan's avatar
yanyan committed
24

yanyan's avatar
yanyan committed
25
class Net(nn.Module):
yanyan's avatar
yanyan committed
26
    def __init__(self, shape, algo):
yanyan's avatar
yanyan committed
27
28
        super().__init__()
        self.net = spconv.SparseSequential(
yanyan's avatar
yanyan committed
29
30
            spconv.SubMConv3d(3, 64, 3, bias=False, indice_key="c0", algo=algo),
            spconv.SubMConv3d(64, 64, 3, bias=False, indice_key="c0", algo=algo),
yanyan's avatar
yanyan committed
31
32
33
            # nn.BatchNorm1d(32),
            # nn.ReLU(),
            spconv.SparseMaxPool3d(2, 2),
yanyan's avatar
yanyan committed
34
35
            spconv.SubMConv3d(64, 96, 3, bias=False, indice_key="c1", algo=algo),
            spconv.SubMConv3d(96, 96, 3, bias=False, indice_key="c1", algo=algo),
yanyan's avatar
yanyan committed
36
37
38
            # nn.BatchNorm1d(64),
            # nn.ReLU(),
            spconv.SparseMaxPool3d(2, 2),
yanyan's avatar
yanyan committed
39
40
            spconv.SubMConv3d(96, 128, 3, bias=False, indice_key="c2", algo=algo),
            spconv.SubMConv3d(128, 128, 3, bias=False, indice_key="c2", algo=algo),
yanyan's avatar
yanyan committed
41
42
43
            # nn.BatchNorm1d(128),
            # nn.ReLU(),
            spconv.SparseMaxPool3d(2, 2),
yanyan's avatar
yanyan committed
44
45
            spconv.SubMConv3d(128, 160, 3, bias=False, indice_key="c3", algo=algo),
            spconv.SubMConv3d(160, 160, 3, bias=False, indice_key="c3", algo=algo),
yanyan's avatar
yanyan committed
46
47
48
            # nn.BatchNorm1d(128),
            # nn.ReLU(),
            spconv.SparseMaxPool3d(2, 2),
yanyan's avatar
yanyan committed
49
50
            spconv.SubMConv3d(160, 192, 3, bias=False, indice_key="c4", algo=algo),
            spconv.SubMConv3d(192, 192, 3, bias=False, indice_key="c4", algo=algo),
yanyan's avatar
yanyan committed
51
52
53
            # nn.BatchNorm1d(128),
            # nn.ReLU(),
            spconv.SparseMaxPool3d(2, 2),
yanyan's avatar
yanyan committed
54
55
            spconv.SubMConv3d(192, 224, 3, bias=False, indice_key="c5", algo=algo),
            spconv.SubMConv3d(224, 224, 3, bias=False, indice_key="c5", algo=algo),
yanyan's avatar
yanyan committed
56
57
58
            # nn.BatchNorm1d(128),
            # nn.ReLU(),
            spconv.SparseMaxPool3d(2, 2),
yanyan's avatar
yanyan committed
59
60
            spconv.SubMConv3d(224, 256, 3, bias=False, indice_key="c6", algo=algo),
            spconv.SubMConv3d(256, 256, 3, bias=False, indice_key="c6", algo=algo),
yanyan's avatar
yanyan committed
61
62
        )
        max_batch_size = 1
yanyan's avatar
yanyan committed
63
        # grid (dense map) is used for indice generation. use pre-allocated grid can run faster.
yanyan's avatar
yanyan committed
64
65
        self.grid = torch.full([max_batch_size, *shape], -1,
                               dtype=torch.int32).cuda()
yanyan's avatar
yanyan committed
66
67
68
69
70
71
72
73
74
75
76
77
        # self.grid = None
        self.shape = shape

    def forward(self, features, coors, batch_size):
        x = spconv.SparseConvTensor(features, coors, self.shape, batch_size,
                                    self.grid)
        return self.net(x)


def main():
    voxels, coors, spatial_shape = waymo_data()
    voxels_th = torch.from_numpy(voxels).cuda().float()
yanyan's avatar
yanyan committed
78
    coors_th = torch.from_numpy(coors).cuda().int()
yanyan's avatar
yanyan committed
79
80
    algo = spconv.ConvAlgo.Native
    net = Net(spatial_shape[::-1], algo).cuda().eval().float()
yanyan's avatar
yanyan committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    print(coors_th.shape)
    out = net(voxels_th, coors_th, 1)
    print(out.spatial_shape)
    times = []
    with torch.no_grad():
        for i in range(20):
            torch.cuda.synchronize()
            t = time.time()
            out = net(voxels_th, coors_th, 1)
            torch.cuda.synchronize()
            times.append(time.time() - t)
    # print((net.grid == -1).float().sum(), net.grid.numel())
    # print("spconv time", time.time() - t)
    print("spconv time", np.mean(times[10:]))

yanyan's avatar
yanyan committed
96

yanyan's avatar
yanyan committed
97
if __name__ == "__main__":
yanyan's avatar
yanyan committed
98
    main()