Skip to main content

Compact Hashing based radius search for pyTorch using C++/CUDA backends.

Project description

pyTorch Compact Radius

This repository contains an implementation of a compact hashing based neighborhood search for 1D, 2D and 3D data for pyTorch using a C++/CUDA backend. This code is designed for large scale problems, e.g., point clouds with $\gg 10^3$ points, e.g., for SPH simulations. For smaller problems other libraries, such as torch-cluster might be a more appropriate fit.

Requirements:

pyTorch >= 2.0

The module is built either just-in-time (this is what you get when you install it via pip directly) or pre-built for a variety of systems via conda or our website. Note that for MacOS based systems an external clang compiler installed via homebrew is required for openMP support.

Usage and Example

This has changed from previous versions

This package provices two primary functions radius and radiusSearch. radius is designed as a drop-in replacement of torch cluster's radius function, whereas radiusSearch is the preferred usage. Important: radius and radiusSearch return index pairs in flipped order!

To call the radiusSearch version we use a set of NamedTuples to make the calling conventions less error prone, these are:

class DomainDescription(NamedTuple):
    min: torch.Tensor
    max: torch.Tensor
    periodicity: Union[bool,torch.Tensor]
    dim: int

class PointCloud(NamedTuple):
    positions: torch.Tensor
    supports: Optional[torch.Tensor] = None

class SparseCOO(NamedTuple):
    row: torch.Tensor
    col: torch.Tensor

    numRows: torch.Tensor
    numCols: torch.Tensor
class SparseCSR(NamedTuple):
    indices: torch.Tensor
    indptr: torch.Tensor

    rowEntries: torch.Tensor

    numRows: torch.Tensor
    numCols: torch.Tensor

Based on these we can then construct an input set:

dim = 2
targetNumNeighbors = 32
nx = 32

minDomain = torch.tensor([-1] * dim, dtype = torch.float32, device = device)
maxDomain = torch.tensor([ 1] * dim, dtype = torch.float32, device = device)
periodicity = torch.tensor([periodic] * dim, device = device, dtype = torch.bool)

extent = maxDomain - minDomain
shortExtent = torch.min(extent, dim = 0)[0].item()
dx = (shortExtent / nx)
h = volumeToSupport(dx**dim, targetNumNeighbors, dim)

positions = []
for d in range(dim):
    positions.append(torch.linspace(minDomain[d] + dx / 2, maxDomain[d] - dx / 2, int((extent[d] - dx) / dx) + 1, device = device))
grid = torch.meshgrid(*positions, indexing = 'xy')
positions = torch.stack(grid, dim = -1).reshape(-1,dim).to(device)
supports = torch.ones(positions.shape[0], device = device) * h

domainDescription = DomainDescription(minDomain, maxDomain, periodicity, dim)
pointCloudX = PointCloud(positions, supports)

We can then call the radiusSearch method to compute the neighborhood in COO format:

adjacency = radiusSearch(pointCloudX, domain = domainDescription)

The radiusSearch method has some further options:

def radiusSearch( 
        queryPointCloud: PointCloud,
        referencePointCloud: Optional[PointCloud],
        supportOverride : Optional[float] = None,

        mode : str = 'gather',
        domain : Optional[DomainDescription] = None,
        hashMapLength = 4096,
        algorithm: str = 'naive',
        verbose: bool = False,
        format: str = 'coo',
        returnStructure : bool = False
        )
  • queryPointCloud contains the set of points that are related to the other set
  • referencePositions contains the reference set of points, i.e., the points for which relations are queried
  • support determines the cut-off radius for the radius search. This value is either a scalar float, i.e., every point has an identical cut-off radius, a single Tensor of size $n$ that contains a different cut-off radius for every point in queryPositions
  • mode determines the method used to compute the cut-off radius of point to point interactions. Options are (a) gather, which uses only the cut-off radius for the queryPositions, (b) scatter, which uses only the cut-off radius for the referencePositions and (c) symmetric, which uses the mean cut-off radius.
  • domainMin and domainMax are required for periodic neighborhood searches to define the coordinates at which point the positions wrap around
  • periodicity indicates if a periodic neighborhood search is to be performed as either a bool (applied to all dimensions) or a list of bools (one per dimension)
  • hashMapLength is used to determine the internal length of the hash map used in the compact data structure, should be close to $n_x$
  • verbose prints additional logging information on the console
  • returnStructure decides if the compact algorithm should return its datastructure for reuse in later searches
  • format decides if an adjacency description in COO or CSR format is returned

For the algorithm the following 4 options exist:

  • naive: This algorithm computes a dense distance matrix of size $n_x \times n_y \times d$ and performs the adjacency computations on this dense representation. This requires significant amounts of memory but is very straight forward and potentially differentiable. Complexity: $\mathcal{O}\left(n^2\right)$
  • cluster: This is a wrapper around torch_cluster's radius search and only available if that package is installed. Note that this algorithm does not support periodic neighbor searches and does not support non-uniform cut-off radii with a complexity of $\mathcal{O}\left(n^2\right)$. This algorithm is also limited to a fixed number of maximum neighbors ($256$).
  • small: This algorithm is similar to cluster in its implementation and computes an everything against everything distance on-the-fly, i.e., it does not require intermediate large storage, and first computes the number of neighbors per particle and then allocates the according memory. Accordingly, this approach is slower than cluster but more versatile. Complexity: $\mathcal{O}\left(n^2\right)$
  • compact: The primary algorithm of this library. This approach uses compact hashing and a cell-based datastructure to compute neighborhoods in $\mathcal{O}\left(n\log n\right)$. The idea is based on A parallel sph implementation on multi-core cpus and the GPU approach is based on Multi-Level Memory Structures for Simulating and Rendering SPH. Note that this implementation is not optimized for adaptive simulations.

Performance

If you want to evaluate the performance on your system simply run scripts/benchmark.py, which will generate a Benchmark.png for various numbers of point counts algorithms and dimensions.

Compute Performance on GPUs for small scale problems:

3090 A5000

CPU perforamnce:

Overall GPU based performance for larger scale problems:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

torchcompactradius-0.2.4.tar.gz (47.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

torchCompactRadius-0.2.4-py3-none-any.whl (61.7 kB view details)

Uploaded Python 3

File details

Details for the file torchcompactradius-0.2.4.tar.gz.

File metadata

  • Download URL: torchcompactradius-0.2.4.tar.gz
  • Upload date:
  • Size: 47.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.11

File hashes

Hashes for torchcompactradius-0.2.4.tar.gz
Algorithm Hash digest
SHA256 0a7a832ce9647a541fc8fec3f9092c8591ee85bc2e49921d9b7ca87de6590f76
MD5 c5b268df8ff171c903263877770bdedc
BLAKE2b-256 821c26a5a86e19f1c05d91ee3517720fdee04bf5e4d20eced22622dfd397f1cf

See more details on using hashes here.

File details

Details for the file torchCompactRadius-0.2.4-py3-none-any.whl.

File metadata

File hashes

Hashes for torchCompactRadius-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 c0197e71952ed081e504552c8516ed471da351825702681b8eeb944b59b789a1
MD5 dbab33e12ef569ed171dd7224a92ca93
BLAKE2b-256 25114b5d755e33bb81a68c17079162e47806824647c38cdac299ba738dffb18e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page