Unverified Commit 83344f71 authored by Yan Yan's avatar Yan Yan Committed by GitHub
Browse files

Merge pull request #125 from Benzlxs/master

adding ConcaTable, JoinTable, Identity functions
parents 1d203af0 a403695b
...@@ -4,15 +4,9 @@ ...@@ -4,15 +4,9 @@
This is a spatially sparse convolution library like [SparseConvNet](https://github.com/facebookresearch/SparseConvNet) but faster and easy to read. This library provide sparse convolution/transposed, submanifold convolution, inverse convolution and sparse maxpool. This is a spatially sparse convolution library like [SparseConvNet](https://github.com/facebookresearch/SparseConvNet) but faster and easy to read. This library provide sparse convolution/transposed, submanifold convolution, inverse convolution and sparse maxpool.
The GPU Indice Generation algorithm is a unofficial implementation of paper [SECOND](http://www.mdpi.com/1424-8220/18/10/3337). That algorithm (don't include GPU SubM indice generation algorithm) may be protected by patent.
This project only support CUDA 9.0+ or CPU only. If you are using cuda 8.0, please update it to 9.0. 2020-5-2, we add ConcatTable, JoinTable, AddTable, and Identity function to build ResNet and Unet in this version of spconv.
This project only support tensors with spatial volume less than ```std::numeric_limits<int>::max()``` (~2e9). if someone really need very large space, open an issue.
## News:
2019-5-24: spconv v1.1 released, now indice generation will use hash table as default (CPU code only support hash table). you can use ```use_hash=False``` to use dense table when using CUDA. In addition, add CPU only build support.
## Docker: ## Docker:
......
# Copyright 2019 Yan Yan # Copyright 2019 Yan Yan
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
...@@ -23,6 +23,8 @@ from spconv.conv import SparseConvTranspose2d, SparseConvTranspose3d ...@@ -23,6 +23,8 @@ from spconv.conv import SparseConvTranspose2d, SparseConvTranspose3d
from spconv.conv import SparseInverseConv2d, SparseInverseConv3d from spconv.conv import SparseInverseConv2d, SparseInverseConv3d
from spconv.modules import SparseModule, SparseSequential from spconv.modules import SparseModule, SparseSequential
from spconv.pool import SparseMaxPool2d, SparseMaxPool3d from spconv.pool import SparseMaxPool2d, SparseMaxPool3d
from spconv.tables import ConcatTable, JoinTable, AddTable
from spconv.identity import Identity
from spconv import ops from spconv import ops
...@@ -55,7 +57,7 @@ class SparseConvTensor(object): ...@@ -55,7 +57,7 @@ class SparseConvTensor(object):
is very large. is very large.
""" """
self.features = features self.features = features
self.indices = indices self.indices = indices
if self.indices.dtype != torch.int32: if self.indices.dtype != torch.int32:
self.indices.int() self.indices.int()
self.spatial_shape = spatial_shape self.spatial_shape = spatial_shape
...@@ -69,7 +71,7 @@ class SparseConvTensor(object): ...@@ -69,7 +71,7 @@ class SparseConvTensor(object):
def find_indice_pair(self, key): def find_indice_pair(self, key):
if key is None: if key is None:
return None return None
if key in self.indice_dict: if key in self.indice_dict:
return self.indice_dict[key] return self.indice_dict[key]
return None return None
...@@ -100,4 +102,4 @@ class RemoveGrid(SparseModule): ...@@ -100,4 +102,4 @@ class RemoveGrid(SparseModule):
""" """
def forward(self, x: SparseConvTensor): def forward(self, x: SparseConvTensor):
x.grid = None x.grid = None
return x return x
\ No newline at end of file
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
from torch.nn import Module
class Identity(Module):
def forward(self, input):
return input
def input_spatial_size(self, out_size):
return out_size
...@@ -72,7 +72,7 @@ class SparseSequential(SparseModule): ...@@ -72,7 +72,7 @@ class SparseSequential(SparseModule):
('conv2', SparseConv2d(20,64,5)), ('conv2', SparseConv2d(20,64,5)),
('relu2', nn.ReLU()) ('relu2', nn.ReLU())
])) ]))
# Example of using Sequential with kwargs(python 3.6+) # Example of using Sequential with kwargs(python 3.6+)
model = SparseSequential( model = SparseSequential(
conv1=SparseConv2d(1,20,5), conv1=SparseConv2d(1,20,5),
...@@ -125,9 +125,12 @@ class SparseSequential(SparseModule): ...@@ -125,9 +125,12 @@ class SparseSequential(SparseModule):
def forward(self, input): def forward(self, input):
for k, module in self._modules.items(): for k, module in self._modules.items():
if is_spconv_module(module): # use SpConvTensor as input if is_spconv_module(module): # use SpConvTensor as input
assert isinstance(input, spconv.SparseConvTensor) if isinstance(input, list):
self._sparity_dict[k] = input.sparity input = module(input)
input = module(input) else:
assert isinstance(input, spconv.SparseConvTensor)
self._sparity_dict[k] = input.sparity
input = module(input)
else: else:
if isinstance(input, spconv.SparseConvTensor): if isinstance(input, spconv.SparseConvTensor):
if input.indices.shape[0] != 0: if input.indices.shape[0] != 0:
......
from torch.autograd import Function
#from torch.nn import Module
from spconv.modules import SparseModule
import spconv
import torch
class JoinTable(SparseModule):# Module):
def forward(self, input):
output = spconv.SparseConvTensor(
torch.cat([i.features for i in input],1), input[1].indices,
input[1].spatial_shape, input[0].batch_size )
output.indice_dict = input[1].indice_dict
output.grid = input[1].grid
return output
def input_spatial_size(self, out_size):
return out_size
class AddTable(SparseModule): # Module):
def forward(self, input):
output = spconv.SparseConvTensor(
sum([i.features for i in input]), input[1].indices,
input[1].spatial_shape, input[1].batch_size )
output.indice_dict = input[1].indice_dict
output.grid = input[1].grid
return output
def input_spatial_size(self, out_size):
return out_size
class ConcatTable(SparseModule): # Module):
def forward(self, input):
return [module(input) for module in self._modules.values()]
def add(self, module):
self._modules[str(len(self._modules))] = module
return self
def input_spatial_size(self, out_size):
return self._modules['0'].input_spatial_size(out_size)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment