Skip to content

Commit 79b935c

Browse files
committed
added sparse and dense voxel cluster
1 parent ce9a53d commit 79b935c

File tree

9 files changed

+242
-132
lines changed

9 files changed

+242
-132
lines changed

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ SRC_DIR=torch_cluster/kernel
77
BUILD_DIR=torch_cluster/build
88

99
mkdir -p $BUILD_DIR
10-
nvcc -c -o $BUILD_DIR/kernel.so $SRC_DIR/kernel.cu -arch=sm_35 -Xcompiler -fPIC -shared -I$TORCH/lib/include/TH -I$TORCH/lib/include/THC -I$SRC_DIR
10+
$(which nvcc) -c -o $BUILD_DIR/kernel.so $SRC_DIR/kernel.cu -arch=sm_35 -Xcompiler -fPIC -shared -I$TORCH/lib/include/TH -I$TORCH/lib/include/THC -I$SRC_DIR

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from setuptools import setup, find_packages
44

5-
__version__ = '0.2.1'
5+
__version__ = '0.2.2'
66
url = 'https://github.com/rusty1s/pytorch_cluster'
77

88
install_requires = ['cffi', 'torch-unique']

test/dense_grid.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
[
2+
{
3+
"name": "One-dimensional positions without start/end",
4+
"position": [2, 16],
5+
"size": [5],
6+
"expected": [0, 2],
7+
"expected_C": 3
8+
},
9+
{
10+
"name": "Start parameter",
11+
"position": [2, 16],
12+
"size": [5],
13+
"start": 0,
14+
"expected": [0, 3],
15+
"expected_C": 4
16+
},
17+
{
18+
"name": "End parameter",
19+
"position": [2, 16],
20+
"size": [5],
21+
"start": 0,
22+
"end": 30,
23+
"expected": [0, 3],
24+
"expected_C": 6
25+
},
26+
{
27+
"name": "Two-dimensional positions",
28+
"position": [[0, 0], [11, 9], [2, 8], [2, 2], [8, 3]],
29+
"size": [5, 5],
30+
"expected": [0, 5, 1, 0, 2],
31+
"expected_C": 6
32+
},
33+
{
34+
"name": "Batch",
35+
"position": [[0, 0], [11, 9], [2, 8], [2, 2], [8, 3], [1, 1], [6, 6]],
36+
"size": [5, 5],
37+
"batch": [0, 0, 0, 0, 0, 1, 1],
38+
"expected": [0, 5, 1, 0, 2, 6, 9],
39+
"expected_C": 6
40+
}
41+
]
42+

test/sparse_grid.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[
2+
{
3+
"name": "One-dimensional positions",
4+
"position": [2, 16],
5+
"size": [5],
6+
"expected": [0, 1]
7+
},
8+
{
9+
"name": "Start parameter",
10+
"position": [2, 6],
11+
"size": [5],
12+
"start": 0,
13+
"expected": [0, 1]
14+
},
15+
{
16+
"name": "Consecutive cluster",
17+
"position": [0, 17, 2, 8, 3],
18+
"size": [5],
19+
"expected": [0, 2, 0, 1, 0]
20+
},
21+
{
22+
"name": "Two-dimensional positions",
23+
"position": [[0, 0], [11, 9], [2, 8], [2, 2], [8, 3]],
24+
"size": [5, 5],
25+
"expected": [0, 3, 1, 0, 2]
26+
},
27+
{
28+
"name": "Batch",
29+
"position": [[0, 0], [11, 9], [2, 8], [2, 2], [8, 3], [1, 1], [6, 6]],
30+
"size": [5, 5],
31+
"batch": [0, 0, 0, 0, 0, 1, 1],
32+
"expected": [0, 3, 1, 0, 2, 4, 5],
33+
"expected_batch": [0, 0, 0, 0, 1, 1]
34+
}
35+
]

test/test_dense_grid.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from os import path as osp
2+
from itertools import product
3+
4+
import pytest
5+
import json
6+
import torch
7+
from torch_cluster import dense_grid_cluster
8+
9+
from .utils import tensors, Tensor
10+
11+
f = open(osp.join(osp.dirname(__file__), 'dense_grid.json'), 'r')
12+
data = json.load(f)
13+
f.close()
14+
15+
16+
@pytest.mark.parametrize('tensor,i', product(tensors, range(len(data))))
17+
def test_dense_grid_cluster_cpu(tensor, i):
18+
position = Tensor(tensor, data[i]['position'])
19+
size = torch.LongTensor(data[i]['size'])
20+
batch = data[i].get('batch')
21+
batch = None if batch is None else torch.LongTensor(batch)
22+
start = data[i].get('start')
23+
end = data[i].get('end')
24+
expected = torch.LongTensor(data[i]['expected'])
25+
expected_C = data[i]['expected_C']
26+
27+
output = dense_grid_cluster(position, size, batch, start, end)
28+
assert output[0].tolist() == expected.tolist()
29+
assert output[1] == expected_C
30+
31+
32+
@pytest.mark.skipif(not torch.cuda.is_available(), reason='no CUDA')
33+
@pytest.mark.parametrize('tensor,i', product(tensors, range(len(data))))
34+
def test_dense_grid_cluster_gpu(tensor, i): # pragma: no cover
35+
position = Tensor(tensor, data[i]['position']).cuda()
36+
size = torch.cuda.LongTensor(data[i]['size'])
37+
batch = data[i].get('batch')
38+
batch = None if batch is None else torch.cuda.LongTensor(batch)
39+
start = data[i].get('start')
40+
end = data[i].get('end')
41+
expected = torch.LongTensor(data[i]['expected'])
42+
expected_C = data[i]['expected_C']
43+
44+
output = dense_grid_cluster(position, size, batch, start, end)
45+
assert output[0].cpu().tolist() == expected.tolist()
46+
assert output[1] == expected_C

test/test_grid.py

Lines changed: 0 additions & 104 deletions
This file was deleted.

test/test_sparse_grid.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from os import path as osp
2+
from itertools import product
3+
4+
import pytest
5+
import json
6+
import torch
7+
from torch_cluster import sparse_grid_cluster
8+
9+
from .utils import tensors, Tensor
10+
11+
f = open(osp.join(osp.dirname(__file__), 'sparse_grid.json'), 'r')
12+
data = json.load(f)
13+
f.close()
14+
15+
16+
@pytest.mark.parametrize('tensor,i', product(tensors, range(len(data))))
17+
def test_sparse_grid_cluster_cpu(tensor, i):
18+
position = Tensor(tensor, data[i]['position'])
19+
size = torch.LongTensor(data[i]['size'])
20+
batch = data[i].get('batch')
21+
start = data[i].get('start')
22+
expected = torch.LongTensor(data[i]['expected'])
23+
24+
if batch is None:
25+
output = sparse_grid_cluster(position, size, batch, start)
26+
assert output.tolist() == expected.tolist()
27+
else:
28+
batch = torch.LongTensor(batch)
29+
expected_batch = torch.LongTensor(data[i]['expected_batch'])
30+
output = sparse_grid_cluster(position, size, batch, start)
31+
assert output[0].tolist() == expected.tolist()
32+
assert output[1].tolist() == expected_batch.tolist()
33+
34+
35+
@pytest.mark.skipif(not torch.cuda.is_available(), reason='no CUDA')
36+
@pytest.mark.parametrize('tensor,i', product(tensors, range(len(data))))
37+
def test_sparse_grid_cluster_gpu(tensor, i): # pragma: no cover
38+
position = Tensor(tensor, data[i]['position']).cuda()
39+
size = torch.cuda.LongTensor(data[i]['size'])
40+
batch = data[i].get('batch')
41+
start = data[i].get('start')
42+
expected = torch.LongTensor(data[i]['expected'])
43+
44+
if batch is None:
45+
output = sparse_grid_cluster(position, size, batch, start)
46+
assert output.cpu().tolist() == expected.tolist()
47+
else:
48+
batch = torch.cuda.LongTensor(batch)
49+
expected_batch = torch.LongTensor(data[i]['expected_batch'])
50+
output = sparse_grid_cluster(position, size, batch, start)
51+
assert output[0].cpu().tolist() == expected.tolist()
52+
assert output[1].cpu().tolist() == expected_batch.tolist()

torch_cluster/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from .functions.grid import grid_cluster
1+
from .functions.grid import sparse_grid_cluster, dense_grid_cluster
22

3-
__version__ = '0.2.1'
3+
__version__ = '0.2.2'
44

5-
__all__ = ['grid_cluster', '__version__']
5+
__all__ = ['sparse_grid_cluster', 'dense_grid_cluster', '__version__']

0 commit comments

Comments
 (0)