Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
torch-cluster
Commits
4607290c
Commit
4607290c
authored
Feb 18, 2020
by
rusty1s
Browse files
update
parent
5765a062
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
105 additions
and
90 deletions
+105
-90
setup.py
setup.py
+1
-1
test/utils.py
test/utils.py
+2
-8
torch_cluster/__init__.py
torch_cluster/__init__.py
+53
-15
torch_cluster/fps.py
torch_cluster/fps.py
+19
-22
torch_cluster/graclus.py
torch_cluster/graclus.py
+16
-22
torch_cluster/grid.py
torch_cluster/grid.py
+14
-22
No files found.
setup.py
View file @
4607290c
...
@@ -26,7 +26,6 @@ def get_extensions():
...
@@ -26,7 +26,6 @@ def get_extensions():
define_macros
+=
[(
'WITH_CUDA'
,
None
)]
define_macros
+=
[(
'WITH_CUDA'
,
None
)]
nvcc_flags
=
os
.
getenv
(
'NVCC_FLAGS'
,
''
)
nvcc_flags
=
os
.
getenv
(
'NVCC_FLAGS'
,
''
)
nvcc_flags
=
[]
if
nvcc_flags
==
''
else
nvcc_flags
.
split
(
' '
)
nvcc_flags
=
[]
if
nvcc_flags
==
''
else
nvcc_flags
.
split
(
' '
)
nvcc_flags
+=
[
'-arch=sm_35'
,
'--expt-relaxed-constexpr'
]
extra_compile_args
[
'nvcc'
]
=
nvcc_flags
extra_compile_args
[
'nvcc'
]
=
nvcc_flags
extensions_dir
=
osp
.
join
(
osp
.
dirname
(
osp
.
abspath
(
__file__
)),
'csrc'
)
extensions_dir
=
osp
.
join
(
osp
.
dirname
(
osp
.
abspath
(
__file__
)),
'csrc'
)
...
@@ -76,6 +75,7 @@ setup(
...
@@ -76,6 +75,7 @@ setup(
'cluster-algorithms'
,
'cluster-algorithms'
,
],
],
license
=
'MIT'
,
license
=
'MIT'
,
python_requires
=
'>=3.6'
,
install_requires
=
install_requires
,
install_requires
=
install_requires
,
setup_requires
=
setup_requires
,
setup_requires
=
setup_requires
,
tests_require
=
tests_require
,
tests_require
=
tests_require
,
...
...
test/utils.py
View file @
4607290c
import
torch
import
torch
from
torch.testing
import
get_all_dtypes
dtypes
=
get_all_dtypes
()
dtypes
.
remove
(
torch
.
half
)
dtypes
.
remove
(
torch
.
bool
)
if
hasattr
(
torch
,
'bfloat16'
):
dtypes
.
remove
(
torch
.
bfloat16
)
dtypes
=
[
torch
.
float
,
torch
.
double
,
torch
.
int
,
torch
.
long
]
grad_dtypes
=
[
torch
.
float
,
torch
.
double
]
grad_dtypes
=
[
torch
.
float
,
torch
.
double
]
devices
=
[
torch
.
device
(
'cpu'
)]
devices
=
[
torch
.
device
(
'cpu'
)]
if
torch
.
cuda
.
is_available
():
if
torch
.
cuda
.
is_available
():
devices
+=
[
torch
.
device
(
'cuda:{
}'
.
format
(
torch
.
cuda
.
current_device
()
)
)]
devices
+=
[
torch
.
device
(
f
'cuda:
{
torch
.
cuda
.
current_device
()
}
'
)]
def
tensor
(
x
,
dtype
,
device
):
def
tensor
(
x
,
dtype
,
device
):
...
...
torch_cluster/__init__.py
View file @
4607290c
from
.graclus
import
graclus_cluster
import
importlib
from
.grid
import
grid_cluster
import
os.path
as
osp
from
.fps
import
fps
from
.nearest
import
nearest
import
torch
from
.knn
import
knn
,
knn_graph
from
.radius
import
radius
,
radius_graph
from
.rw
import
random_walk
from
.sampler
import
neighbor_sampler
__version__
=
'1.5.0'
__version__
=
'1.5.0'
expected_torch_version
=
(
1
,
4
)
try
:
for
library
in
[
'_version'
,
'_grid'
,
'_graclus'
,
'_fps'
]:
torch
.
ops
.
load_library
(
importlib
.
machinery
.
PathFinder
().
find_spec
(
library
,
[
osp
.
dirname
(
__file__
)]).
origin
)
except
OSError
as
e
:
major
,
minor
=
[
int
(
x
)
for
x
in
torch
.
__version__
.
split
(
'.'
)[:
2
]]
t_major
,
t_minor
=
expected_torch_version
if
major
!=
t_major
or
(
major
==
t_major
and
minor
!=
t_minor
):
raise
RuntimeError
(
f
'Expected PyTorch version
{
t_major
}
.
{
t_minor
}
but found '
f
'version
{
major
}
.
{
minor
}
.'
)
raise
OSError
(
e
)
if
torch
.
version
.
cuda
is
not
None
:
# pragma: no cover
cuda_version
=
torch
.
ops
.
torch_sparse
.
cuda_version
()
if
cuda_version
==
-
1
:
major
=
minor
=
0
elif
cuda_version
<
10000
:
major
,
minor
=
int
(
str
(
cuda_version
)[
0
]),
int
(
str
(
cuda_version
)[
2
])
else
:
major
,
minor
=
int
(
str
(
cuda_version
)[
0
:
2
]),
int
(
str
(
cuda_version
)[
3
])
t_major
,
t_minor
=
[
int
(
x
)
for
x
in
torch
.
version
.
cuda
.
split
(
'.'
)]
if
t_major
!=
major
or
t_minor
!=
minor
:
raise
RuntimeError
(
f
'Detected that PyTorch and torch_cluster were compiled with '
f
'different CUDA versions. PyTorch has CUDA version '
f
'
{
t_major
}
.
{
t_minor
}
and torch_cluster has CUDA version '
f
'
{
major
}
.
{
minor
}
. Please reinstall the torch_cluster that '
f
'matches your PyTorch install.'
)
from
.graclus
import
graclus_cluster
# noqa
from
.grid
import
grid_cluster
# noqa
from
.fps
import
fps
# noqa
# from .nearest import nearest # noqa
# from .knn import knn, knn_graph # noqa
# from .radius import radius, radius_graph # noqa
# from .rw import random_walk # noqa
# from .sampler import neighbor_sampler # noqa
__all__
=
[
__all__
=
[
'graclus_cluster'
,
'graclus_cluster'
,
'grid_cluster'
,
'grid_cluster'
,
'fps'
,
'fps'
,
'nearest'
,
#
'nearest',
'knn'
,
#
'knn',
'knn_graph'
,
#
'knn_graph',
'radius'
,
#
'radius',
'radius_graph'
,
#
'radius_graph',
'random_walk'
,
#
'random_walk',
'neighbor_sampler'
,
#
'neighbor_sampler',
'__version__'
,
'__version__'
,
]
]
torch_cluster/fps.py
View file @
4607290c
import
torch
from
typing
import
Optional
import
torch_cluster.fps_cpu
if
torch
.
cuda
.
is_available
():
import
torch
import
torch_cluster.fps_cuda
def
fps
(
x
,
batch
=
None
,
ratio
=
0.5
,
random_start
=
True
):
@
torch
.
jit
.
script
def
fps
(
src
:
torch
.
Tensor
,
batch
:
Optional
[
torch
.
Tensor
]
=
None
,
ratio
:
float
=
0.5
,
random_start
:
bool
=
True
)
->
torch
.
Tensor
:
r
""""A sampling algorithm from the `"PointNet++: Deep Hierarchical Feature
r
""""A sampling algorithm from the `"PointNet++: Deep Hierarchical Feature
Learning on Point Sets in a Metric Space"
Learning on Point Sets in a Metric Space"
<https://arxiv.org/abs/1706.02413>`_ paper, which iteratively samples the
<https://arxiv.org/abs/1706.02413>`_ paper, which iteratively samples the
most distant point with regard to the rest points.
most distant point with regard to the rest points.
Args:
Args:
x
(Tensor):
Node
feature matrix
src
(Tensor):
Point
feature matrix
:math:`\mathbf{X} \in \mathbb{R}^{N \times F}`.
:math:`\mathbf{X} \in \mathbb{R}^{N \times F}`.
batch (LongTensor, optional): Batch vector
batch (LongTensor, optional): Batch vector
:math:`\mathbf{b} \in {\{ 0, \ldots, B-1\}}^N`, which assigns each
:math:`\mathbf{b} \in {\{ 0, \ldots, B-1\}}^N`, which assigns each
...
@@ -23,28 +23,25 @@ def fps(x, batch=None, ratio=0.5, random_start=True):
...
@@ -23,28 +23,25 @@ def fps(x, batch=None, ratio=0.5, random_start=True):
:rtype: :class:`LongTensor`
:rtype: :class:`LongTensor`
..
testsetup::
..
code-block:: python
import torch
import torch
from torch_cluster import fps
from torch_cluster import fps
.. testcode::
src = torch.Tensor([[-1, -1], [-1, 1], [1, -1], [1, 1]])
batch = torch.tensor([0, 0, 0, 0])
>>> x = torch.Tensor([[-1, -1], [-1, 1], [1, -1], [1, 1]])
index = fps(src, batch, ratio=0.5)
>>> batch = torch.tensor([0, 0, 0, 0])
>>> index = fps(x, batch, ratio=0.5)
"""
"""
if
batch
is
None
:
ptr
:
Optional
[
torch
.
Tensor
]
=
None
batch
=
x
.
new_zeros
(
x
.
size
(
0
),
dtype
=
torch
.
long
)
if
batch
is
not
None
:
assert
src
.
size
(
0
)
==
batch
.
size
(
0
)
batch_size
=
int
(
batch
.
max
())
+
1
x
=
x
.
view
(
-
1
,
1
)
if
x
.
dim
()
==
1
else
x
deg
=
src
.
new_zeros
(
batch_size
,
dtype
=
torch
.
long
)
deg
.
scatter_add_
(
0
,
batch
,
torch
.
ones_like
(
batch
))
assert
x
.
dim
()
==
2
and
batch
.
dim
()
==
1
ptr
=
src
.
new_zeros
(
batch_size
+
1
,
dtype
=
torch
.
long
)
assert
x
.
size
(
0
)
==
batch
.
size
(
0
)
deg
.
cumsum
(
0
,
out
=
ptr
[
1
:])
assert
ratio
>
0
and
ratio
<
1
if
x
.
is_cuda
:
return
torch
.
ops
.
torch_cluster
.
fps
(
src
,
ptr
,
ratio
,
random_start
)
return
torch_cluster
.
fps_cuda
.
fps
(
x
,
batch
,
ratio
,
random_start
)
else
:
return
torch_cluster
.
fps_cpu
.
fps
(
x
,
batch
,
ratio
,
random_start
)
torch_cluster/graclus.py
View file @
4607290c
import
torch
from
typing
import
Optional
import
torch_cluster.graclus_cpu
if
torch
.
cuda
.
is_available
():
import
torch
import
torch_cluster.graclus_cuda
def
graclus_cluster
(
row
,
col
,
weight
=
None
,
num_nodes
=
None
):
@
torch
.
jit
.
script
def
graclus_cluster
(
row
:
torch
.
Tensor
,
col
:
torch
.
Tensor
,
weight
:
Optional
[
torch
.
Tensor
]
=
None
,
num_nodes
:
Optional
[
int
]
=
None
)
->
torch
.
Tensor
:
"""A greedy clustering algorithm of picking an unmarked vertex and matching
"""A greedy clustering algorithm of picking an unmarked vertex and matching
it with one its unmarked neighbors (that maximizes its edge weight).
it with one its unmarked neighbors (that maximizes its edge weight).
...
@@ -17,25 +18,18 @@ def graclus_cluster(row, col, weight=None, num_nodes=None):
...
@@ -17,25 +18,18 @@ def graclus_cluster(row, col, weight=None, num_nodes=None):
:rtype: :class:`LongTensor`
:rtype: :class:`LongTensor`
Examples::
.. code-block:: python
import torch
from torch_cluster import graclus_cluster
>>>
row = torch.tensor([0, 1, 1, 2])
row = torch.tensor([0, 1, 1, 2])
>>>
col = torch.tensor([1, 0, 2, 1])
col = torch.tensor([1, 0, 2, 1])
>>>
weight = torch.Tensor([1, 1, 1, 1])
weight = torch.Tensor([1, 1, 1, 1])
>>>
cluster = graclus_cluster(row, col, weight)
cluster = graclus_cluster(row, col, weight)
"""
"""
if
num_nodes
is
None
:
if
num_nodes
is
None
:
num_nodes
=
max
(
row
.
max
().
item
(),
col
.
max
().
item
())
+
1
num_nodes
=
max
(
int
(
row
.
max
()),
int
(
col
.
max
()))
+
1
if
row
.
is_cuda
:
op
=
torch_cluster
.
graclus_cuda
else
:
op
=
torch_cluster
.
graclus_cpu
if
weight
is
None
:
cluster
=
op
.
graclus
(
row
,
col
,
num_nodes
)
else
:
cluster
=
op
.
weighted_graclus
(
row
,
col
,
weight
,
num_nodes
)
return
cluster
return
torch
.
ops
.
torch_cluster
.
graclus
(
row
,
col
,
weight
,
num_nodes
)
torch_cluster/grid.py
View file @
4607290c
import
torch
from
typing
import
Optional
import
torch_cluster.grid_cpu
if
torch
.
cuda
.
is_available
():
import
torch
import
torch_cluster.grid_cuda
def
grid_cluster
(
pos
,
size
,
start
=
None
,
end
=
None
):
@
torch
.
jit
.
script
def
grid_cluster
(
pos
:
torch
.
Tensor
,
size
:
torch
.
Tensor
,
start
:
Optional
[
torch
.
Tensor
]
=
None
,
end
:
Optional
[
torch
.
Tensor
]
=
None
)
->
torch
.
Tensor
:
"""A clustering algorithm, which overlays a regular grid of user-defined
"""A clustering algorithm, which overlays a regular grid of user-defined
size over a point cloud and clusters all points within a voxel.
size over a point cloud and clusters all points within a voxel.
...
@@ -19,22 +20,13 @@ def grid_cluster(pos, size, start=None, end=None):
...
@@ -19,22 +20,13 @@ def grid_cluster(pos, size, start=None, end=None):
:rtype: :class:`LongTensor`
:rtype: :class:`LongTensor`
Examples::
.. code-block:: python
>>> pos = torch.Tensor([[0, 0], [11, 9], [2, 8], [2, 2], [8, 3]])
>>> size = torch.Tensor([5, 5])
>>> cluster = grid_cluster(pos, size)
"""
pos
=
pos
.
unsqueeze
(
-
1
)
if
pos
.
dim
()
==
1
else
pos
import torch
start
=
pos
.
t
().
min
(
dim
=
1
)[
0
]
if
start
is
None
else
start
from torch_cluster import grid_cluster
end
=
pos
.
t
().
max
(
dim
=
1
)[
0
]
if
end
is
None
else
end
if
pos
.
is_cuda
:
pos = torch.Tensor([[0, 0], [11, 9], [2, 8], [2, 2], [8, 3]])
op
=
torch_cluster
.
grid_cuda
size = torch.Tensor([5, 5])
else
:
cluster = grid_cluster(pos, size)
op
=
torch_cluster
.
grid_cpu
"""
return
torch
.
ops
.
torch_cluster
.
grid
(
pos
,
size
,
start
,
end
)
cluster
=
op
.
grid
(
pos
,
size
,
start
,
end
)
return
cluster
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment