ops
Tensor operations on packed batches: safe division, softmax, voxel hashing, interpolation, and decimation.
Functions:
-
safe_divide–Safely divide two tensors, returning a default value if the denominator is zero.
-
softmax–Apply softmax on a packed x tensor.
-
voxel_grid_fnv–FNV-1a 64-bit hash of integer voxel-grid coordinates. \((N, D) \to (N,)\).
-
first_permutation–Index of the first occurrence of each cluster id in a consecutive cluster tensor.
-
knn_interpolate–k-NN interpolation with inverse-distance weighting.
-
decimate_indices–Decimate indices from a packed batch index tensor.
-
decimate–Decimates each input tensor by the given factor.
-
pad_tail–Pad the tail of a tensor with a fill value.
-
offset_index–Offset per-element row indices into the packed row layout of a collated batch.
safe_divide
¶
Safely divide two tensors, returning a default value if the denominator is zero.
Note
If the inputs are not floating point numbers, they will be converted to floating point numbers (float32).
Parameters:
-
a(Tensor) –The numerator tensor.
-
b(Tensor) –The denominator tensor.
-
default(Union[float, Tensor], default:float('nan')) –The default value to return if the denominator is zero.
Returns:
-
Tensor–The result of the division.
Example
>>> safe_divide(torch.tensor([1.0, 2.0, 3.0]), torch.tensor([1.0, 0.0, 1.0]))
tensor([1., nan, 3.])
>>> safe_divide(torch.tensor([1.0, 2.0, 3.0]), torch.tensor([1.0, 0.0, 1.0]), default=0.0)
tensor([1., 0., 3.])
>>> safe_divide(torch.tensor([1, 2, 3]), torch.tensor([1, 0, 1]), default=torch.tensor([0, 0, 0]))
tensor([1., 0., 3.])
softmax
¶
Apply softmax on a packed x tensor.
The x tensor is expected to be of shape \((N, *)\),
where \(N\) is the number of nodes and \(*\) is the feature size.
The batch tensor must be of shape \((N,)\) and must be contiguous.
Note
This function is adapted from the torch_geometric package,
and requires the torch-scatter package.
Parameters:
-
x(Tensor) –The x tensor of shape \((N, *)\).
-
batch(Tensor) –The batch tensor of shape \((N,)\).
-
dim(int, default:0) –The dimension along which to apply the softmax.
Returns:
-
Tensor–The softmaxed tensor of shape \((N, *)\).
voxel_grid_fnv
¶
voxel_grid_fnv(
pos: Tensor,
size: float,
start: Optional[Tensor] = None,
*,
return_inverse: Literal[False] = False,
return_counts: Literal[False] = False,
) -> Tensor
voxel_grid_fnv(
pos: Tensor,
size: float,
start: Optional[Tensor] = None,
*,
return_inverse: Literal[True],
return_counts: Literal[False] = False,
) -> Tuple[Tensor, Tensor]
voxel_grid_fnv(
pos: Tensor,
size: float,
start: Optional[Tensor] = None,
*,
return_inverse: bool = False,
return_counts: bool = False,
) -> Union[Tensor, Tuple[Tensor, ...]]
FNV-1a 64-bit hash of integer voxel-grid coordinates. \((N, D) \to (N,)\).
Parameters:
-
pos(Tensor) –Point positions of shape \((N, D)\).
-
size(float) –Voxel side length in the same units as
pos. -
start(Optional[Tensor], default:None) –Optional voxel-grid origin. When
None, the grid origin is implicit via the internalpos_grid -= pos_grid.min(0)shift. -
return_inverse(bool, default:False) –If
True, also return the per-point consecutive voxel index in \([0, V)\), following the semantics oftorch.unique(..., return_inverse=True). -
return_counts(bool, default:False) –If
True, also return the per-voxel point count of shape \((V,)\).
Returns:
-
Union[Tensor, Tuple[Tensor, ...]]–hashedof shape \((N,)\) when both flags areFalse. Withreturn_inverse=Trueadds -
Union[Tensor, Tuple[Tensor, ...]]–inverseof shape \((N,)\); withreturn_counts=Trueaddscountof shape \((V,)\); both -
Union[Tensor, Tuple[Tensor, ...]]–flags enabled returns
(hashed, inverse, count).
first_permutation
¶
Index of the first occurrence of each cluster id in a consecutive cluster tensor.
The permutation returned by consecutive_cluster picks a backend-dependent representative per
cluster (the last occurrence on CPU, a nondeterministic one on CUDA). This helper always picks
the first occurrence, so tensor[first_permutation(cluster)] is deterministic across devices.
Parameters:
-
cluster(Tensor) –Consecutive cluster indices of shape \((N,)\) with values in \([0, V)\).
-
num_clusters(Optional[int], default:None) –Number of clusters \(V\). Inferred as
cluster.max() + 1whenNone.
Returns:
-
Tensor–Long tensor of shape \((V,)\) holding, per cluster id, the smallest index in
clusterwith that id.
knn_interpolate
¶
knn_interpolate(
x: Tensor,
pos_x: Tensor,
pos_y: Tensor,
batch_x: OptTensor = None,
batch_y: OptTensor = None,
k: int = 3,
num_workers: int = 1,
weighting: Literal["squared", "inverse"] = "squared",
eps: float = 1e-16,
) -> Tensor
k-NN interpolation with inverse-distance weighting.
From PointNet++: Deep Hierarchical Feature Learning on Point Sets in a Metric Space.
For each point \(y\) with position \(\mathbf{p}(y)\), its interpolated features \(\mathbf{f}(y)\) are given by
where \(\{ x_1, \ldots, x_k \}\) are the \(k\) nearest points to \(y\) and
the weights \(w(x_i)\) depend on the chosen weighting scheme:
"squared"(default,torch_geometricconvention): \(w(x_i) = 1 / d(\mathbf{p}(y), \mathbf{p}(x_i))^2\)"inverse"(PointNet++three_interpolationconvention): \(w(x_i) = 1 / d(\mathbf{p}(y), \mathbf{p}(x_i))\)
Note
Adapted from the torch_geometric package. Requires torch-cluster.
Parameters:
-
x(Tensor) –Node feature matrix \(\mathbf{X} \in \mathbb{R}^{N \times F}\).
-
pos_x(Tensor) –Node position matrix \(\in \mathbb{R}^{N \times d}\).
-
pos_y(Tensor) –Upsampled node position matrix \(\in \mathbb{R}^{M \times d}\).
-
batch_x(OptTensor, default:None) –Batch vector \(\mathbf{b_x} \in \{ 0, \ldots, B-1 \}^N\), assigning each node from \(\mathbf{X}\) to a specific example.
-
batch_y(OptTensor, default:None) –Batch vector \(\mathbf{b_y} \in \{ 0, \ldots, B-1 \}^M\), assigning each node from \(\mathbf{Y}\) to a specific example.
-
k(int, default:3) –Number of neighbors.
-
num_workers(int, default:1) –Number of workers for computation. Has no effect when
batch_xorbatch_yis notNone, or the input lies on GPU. -
weighting(Literal['squared', 'inverse'], default:'squared') –Weighting scheme for neighbors.
"squared"for \(1/d^2\) weights (torch_geometricdefault) or"inverse"for \(1/d\) weights (PointNet++ convention). -
eps(float, default:1e-16) –Small value to avoid division by zero.
Returns:
-
Tensor–Interpolated features \(\in \mathbb{R}^{M \times F}\).
decimate_indices
¶
decimate_indices(
batch: Tensor,
factor: float,
generator: Optional[Generator] = None,
) -> Tuple[Tensor, Tensor]
Decimate indices from a packed batch index tensor. This function will return the decimated indices by a given factor along with the decimated batch indices.
Note
This function is similar to the decimation_indices function in the torch-geometric package,
except that this function uses the batch tensor instead of the ptr tensor representation.
Parameters:
-
batch(Tensor) –The packed batch index tensor.
-
factor(float) –The factor to decimate the indices by.
-
generator(Optional[Generator], default:None) –The generator to use for the random permutation.
Returns:
-
Tuple[Tensor, Tensor]–The decimated indices and the decimated batch indices.
Examples:
decimate
¶
decimate(
tensors: Tuple[Tensor, ...],
batch: Tensor,
factor: int,
generator: Optional[Generator] = None,
) -> Tuple[Tuple[Tensor, ...], Tensor]
Decimates each input tensor by the given factor. This will return the decimated tensors along with the decimated batch indices.
Note
This function is similar to the decimate function introduced in the torch-geometric RandLANet example.
Parameters:
-
tensors(Tuple[Tensor, ...]) –A tuple of tensors to decimate.
-
batch(Tensor) –The batch tensor of shape \((N,)\).
-
factor(int) –The factor to decimate the tensors by.
-
generator(Optional[Generator], default:None) –The generator to use for the random permutation.
Returns:
-
Tuple[Tuple[Tensor, ...], Tensor]–A tuple of decimated tensors and the decimated batch indices.
Examples:
>>> tensors = (torch.randn(10, 3), torch.randn(10, 4))
>>> batch = torch.tensor([0, 1, 1, 1, 2, 2, 2, 2, 3, 3])
>>> decimate(tensors, batch, 2) # doctest: +SKIP
((tensor([[-1.4570, -0.1023, -0.5992],
[ 0.2408, 0.1325, 0.7642],
[-0.2104, -1.4391, 0.5214],
[ 1.6192, 1.4506, 0.2695],
[ 0.3488, 0.9676, -0.4657]]),
tensor([[-0.1933, 0.6526, -1.9006, 0.2286],
[ 1.2888, 0.0523, -1.5469, 0.7567],
[ 0.9442, -0.1849, 1.0608, 0.2083],
[ 0.4788, 1.3537, -0.1593, -0.4249],
[ 1.3065, 0.4598, 0.2618, -0.7599]])),
tensor([0, 1, 2, 2, 3]))
pad_tail
¶
Pad the tail of a tensor with a fill value.
Parameters:
-
tensor(Tensor) –The tensor to pad.
-
pad_size(int) –The size of the padding that will be added to the tail of the tensor.
-
dim(int) –The dimension along which to pad the tensor.
-
fill_value(float, default:0) –The value to fill the padding with.
Returns:
-
Tensor–The padded tensor.
Examples:
>>> tensor = torch.tensor([1, 2, 3])
>>> pad_tail(tensor, pad_size=2, dim=0, fill_value=0)
tensor([1, 2, 3, 0, 0])
>>> tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
>>> pad_tail(tensor, pad_size=2, dim=0, fill_value=0)
tensor([[1, 2, 3],
[4, 5, 6],
[0, 0, 0],
[0, 0, 0]])
>>> tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
>>> pad_tail(tensor, pad_size=2, dim=1, fill_value=0)
tensor([[1, 2, 3, 0, 0],
[4, 5, 6, 0, 0]])
offset_index
¶
Offset per-element row indices into the packed row layout of a collated batch.
collate concatenates a row map such as inverse or index as-is, so the entries of each batch element
still address that element's own rows. This shifts every entry by the number of rows of the elements
collated before it.
Parameters:
-
index(Tensor) –Per-element row indices.
-
index_batch(Tensor) –Batch index of each entry of
index, thebatch_<key>tensorcollateemits forcat_keys. -
batch(Tensor) –Batch index of the rows
indexaddresses (batchfor aninversemap,batch_origin_posfor anindexmap).
Returns:
-
Tensor–The offset row indices.
Shape
index: \((M,)\)index_batch: \((M,)\)batch: \((N,)\)- output: \((M,)\)