bm_knn.py 3.82 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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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()


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
32
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K, "v": version})
Justin Johnson's avatar
Justin Johnson committed
33
    for N, P, D in product(Ns, Ps, Ds):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
34
        nn_kwargs.append({"N": N, "D": D, "P": P})
35
    benchmark(knn_cuda_with_init, "KNN_CUDA_VERSIONS", knn_kwargs, warmup_iters=1)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
36
    benchmark(nn_cuda_with_init, "NN_CUDA", nn_kwargs, warmup_iters=1)
Justin Johnson's avatar
Justin Johnson committed
37
38
39
40
41
42
43
44
45
46


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
47
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K})
Justin Johnson's avatar
Justin Johnson committed
48
        if P <= 4096:
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
49
            naive_kwargs.append({"N": N, "D": D, "P": P, "K": K})
Justin Johnson's avatar
Justin Johnson committed
50
    benchmark(
51
        knn_python_cuda_with_init, "KNN_CUDA_PYTHON", naive_kwargs, warmup_iters=1
Justin Johnson's avatar
Justin Johnson committed
52
    )
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
53
    benchmark(knn_cuda_with_init, "KNN_CUDA", knn_kwargs, warmup_iters=1)
Justin Johnson's avatar
Justin Johnson committed
54
55
56
57
58
59
60
61
62


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
63
        knn_kwargs.append({"N": N, "D": D, "P": P, "K": K})
Justin Johnson's avatar
Justin Johnson committed
64
    for N, P, D in product(Ns, Ps, Ds):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
65
        nn_kwargs.append({"N": N, "D": D, "P": P})
66
    benchmark(knn_python_cpu_with_init, "KNN_CPU_PYTHON", knn_kwargs, warmup_iters=1)
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
67
68
    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
69
70
71


def knn_cuda_with_init(N, D, P, K, v=-1):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
72
    device = torch.device("cuda:0")
Justin Johnson's avatar
Justin Johnson committed
73
74
75
76
77
78
79
80
81
82
83
84
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
    torch.cuda.synchronize()

    def knn():
        _C.knn_points_idx(x, y, K, v)
        torch.cuda.synchronize()

    return knn


def knn_cpu_with_init(N, D, P, K):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
85
    device = torch.device("cpu")
Justin Johnson's avatar
Justin Johnson committed
86
87
88
89
90
91
92
93
94
95
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)

    def knn():
        _C.knn_points_idx(x, y, K, 0)

    return knn


def knn_python_cuda_with_init(N, D, P, K):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
96
    device = torch.device("cuda")
Justin Johnson's avatar
Justin Johnson committed
97
98
99
100
101
102
103
104
105
106
107
108
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)
    torch.cuda.synchronize()

    def knn():
        _knn_points_idx_naive(x, y, K)
        torch.cuda.synchronize()

    return knn


def knn_python_cpu_with_init(N, D, P, K):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
109
    device = torch.device("cpu")
Justin Johnson's avatar
Justin Johnson committed
110
111
112
113
114
115
116
117
118
119
    x = torch.randn(N, P, D, device=device)
    y = torch.randn(N, P, D, device=device)

    def knn():
        _knn_points_idx_naive(x, y, K)

    return knn


def nn_cuda_with_init(N, D, P):
Jeremy Reizenstein's avatar
Jeremy Reizenstein committed
120
    device = torch.device("cuda")
Justin Johnson's avatar
Justin Johnson committed
121
122
123
124
125
126
127
128
129
130
131
132
    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
133
    device = torch.device("cpu")
Justin Johnson's avatar
Justin Johnson committed
134
135
136
137
138
139
140
    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