bm_knn.py 5.37 KB
Newer Older
Justin Johnson's avatar
Justin Johnson committed
1
2
3
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.

from itertools import product
4

Justin Johnson's avatar
Justin Johnson committed
5
6
7
8
9
10
11
12
13
14
15
import torch
from fvcore.common.benchmark import benchmark
from pytorch3d import _C
from pytorch3d.ops.knn import _knn_points_idx_naive


def bm_knn() -> None:
    """ Entry point for the benchmark """
    benchmark_knn_cpu()
    benchmark_knn_cuda_vs_naive()
    benchmark_knn_cuda_versions()
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
16
    benchmark_knn_cuda_versions_ragged()
Justin Johnson's avatar
Justin Johnson committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32


def benchmark_knn_cuda_versions() -> None:
    # Compare our different KNN implementations,
    # and also compare against our existing 1-NN
    Ns = [1, 2]
    Ps = [4096, 16384]
    Ds = [3]
    Ks = [1, 4, 16, 64]
    versions = [0, 1, 2, 3]
    knn_kwargs, nn_kwargs = [], []
    for N, P, D, K, version in product(Ns, Ps, Ds, Ks, versions):
        if version == 2 and K > 32:
            continue
        if version == 3 and K > 4:
            continue
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
33
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K, "v": version})
Justin Johnson's avatar
Justin Johnson committed
34
    for N, P, D in product(Ns, Ps, Ds):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
35
        nn_kwargs.append({"N": N, "D": D, "P": P})
36
    benchmark(knn_cuda_with_init, "KNN_CUDA_VERSIONS", knn_kwargs, warmup_iters=1)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
37
    benchmark(nn_cuda_with_init, "NN_CUDA", nn_kwargs, warmup_iters=1)
Justin Johnson's avatar
Justin Johnson committed
38
39


Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def benchmark_knn_cuda_versions_ragged() -> None:
    # Compare our different KNN implementations,
    # and also compare against our existing 1-NN
    Ns = [8]
    Ps = [4096, 16384]
    Ds = [3]
    Ks = [1, 4, 16, 64]
    versions = [0, 1, 2, 3]
    knn_kwargs = []
    for N, P, D, K, version in product(Ns, Ps, Ds, Ks, versions):
        if version == 2 and K > 32:
            continue
        if version == 3 and K > 4:
            continue
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K, "v": version})
    benchmark(knn_cuda_with_init, "KNN_CUDA_COMPARISON", knn_kwargs, warmup_iters=1)
    benchmark(knn_cuda_ragged, "KNN_CUDA_RAGGED", knn_kwargs, warmup_iters=1)


Justin Johnson's avatar
Justin Johnson committed
59
60
61
62
63
64
65
66
def benchmark_knn_cuda_vs_naive() -> None:
    # Compare against naive pytorch version of KNN
    Ns = [1, 2, 4]
    Ps = [1024, 4096, 16384, 65536]
    Ds = [3]
    Ks = [1, 2, 4, 8, 16]
    knn_kwargs, naive_kwargs = [], []
    for N, P, D, K in product(Ns, Ps, Ds, Ks):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
67
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K})
Justin Johnson's avatar
Justin Johnson committed
68
        if P <= 4096:
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
69
            naive_kwargs.append({"N": N, "D": D, "P": P, "K": K})
Justin Johnson's avatar
Justin Johnson committed
70
    benchmark(
71
        knn_python_cuda_with_init, "KNN_CUDA_PYTHON", naive_kwargs, warmup_iters=1
Justin Johnson's avatar
Justin Johnson committed
72
    )
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
73
    benchmark(knn_cuda_with_init, "KNN_CUDA", knn_kwargs, warmup_iters=1)
Justin Johnson's avatar
Justin Johnson committed
74
75
76
77
78
79
80
81
82


def benchmark_knn_cpu() -> None:
    Ns = [1, 2]
    Ps = [256, 512]
    Ds = [3]
    Ks = [1, 2, 4]
    knn_kwargs, nn_kwargs = [], []
    for N, P, D, K in product(Ns, Ps, Ds, Ks):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
83
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K})
Justin Johnson's avatar
Justin Johnson committed
84
    for N, P, D in product(Ns, Ps, Ds):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
85
        nn_kwargs.append({"N": N, "D": D, "P": P})
86
    benchmark(knn_python_cpu_with_init, "KNN_CPU_PYTHON", knn_kwargs, warmup_iters=1)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
87
88
    benchmark(knn_cpu_with_init, "KNN_CPU_CPP", knn_kwargs, warmup_iters=1)
    benchmark(nn_cpu_with_init, "NN_CPU_CPP", nn_kwargs, warmup_iters=1)
Justin Johnson's avatar
Justin Johnson committed
89
90
91


def knn_cuda_with_init(N, D, P, K, v=-1):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
92
    device = torch.device("cuda:0")
Justin Johnson's avatar
Justin Johnson committed
93
94
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
95
96
    lengths = torch.full((N,), P, dtype=torch.int64, device=device)

Justin Johnson's avatar
Justin Johnson committed
97
98
99
    torch.cuda.synchronize()

    def knn():
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
        _C.knn_points_idx(x, y, lengths, lengths, K, v)
        torch.cuda.synchronize()

    return knn


def knn_cuda_ragged(N, D, P, K, v=-1):
    device = torch.device("cuda:0")
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
    lengths1 = torch.randint(P, size=(N,), device=device, dtype=torch.int64)
    lengths2 = torch.randint(P, size=(N,), device=device, dtype=torch.int64)
    torch.cuda.synchronize()

    def knn():
        _C.knn_points_idx(x, y, lengths1, lengths2, K, v)
Justin Johnson's avatar
Justin Johnson committed
116
117
118
119
120
121
        torch.cuda.synchronize()

    return knn


def knn_cpu_with_init(N, D, P, K):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
122
    device = torch.device("cpu")
Justin Johnson's avatar
Justin Johnson committed
123
124
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
125
    lengths = torch.full((N,), P, dtype=torch.int64, device=device)
Justin Johnson's avatar
Justin Johnson committed
126
127

    def knn():
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
128
        _C.knn_points_idx(x, y, lengths, lengths, K, -1)
Justin Johnson's avatar
Justin Johnson committed
129
130
131
132
133

    return knn


def knn_python_cuda_with_init(N, D, P, K):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
134
    device = torch.device("cuda")
Justin Johnson's avatar
Justin Johnson committed
135
136
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
137
138
    lengths = torch.full((N,), P, dtype=torch.int64, device=device)

Justin Johnson's avatar
Justin Johnson committed
139
140
141
    torch.cuda.synchronize()

    def knn():
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
142
        _knn_points_idx_naive(x, y, K=K, lengths1=lengths, lengths2=lengths)
Justin Johnson's avatar
Justin Johnson committed
143
144
145
146
147
148
        torch.cuda.synchronize()

    return knn


def knn_python_cpu_with_init(N, D, P, K):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
149
    device = torch.device("cpu")
Justin Johnson's avatar
Justin Johnson committed
150
151
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
152
    lengths = torch.full((N,), P, dtype=torch.int64, device=device)
Justin Johnson's avatar
Justin Johnson committed
153
154

    def knn():
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
155
        _knn_points_idx_naive(x, y, K=K, lengths1=lengths, lengths2=lengths)
Justin Johnson's avatar
Justin Johnson committed
156
157
158
159
160

    return knn


def nn_cuda_with_init(N, D, P):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
161
    device = torch.device("cuda")
Justin Johnson's avatar
Justin Johnson committed
162
163
164
165
166
167
168
169
170
171
172
173
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
    torch.cuda.synchronize()

    def knn():
        _C.nn_points_idx(x, y)
        torch.cuda.synchronize()

    return knn


def nn_cpu_with_init(N, D, P):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
174
    device = torch.device("cpu")
Justin Johnson's avatar
Justin Johnson committed
175
176
177
178
179
180
181
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)

    def knn():
        _C.nn_points_idx(x, y)

    return knn