Sparse Convolution
- class fvdb.ConvolutionPlan(_source_grid: GridBatch, _target_grid: GridBatch, _geometry: fvdb._fvdb_cpp.ConvolutionGeometry, _channel_pairs: tuple[tuple[int, int], ...], _transposed: bool, _backend: _MatmulBackend | _GatherScatterBackend | _PredGatherIGemmBackend, _transform_compatibility: ConvolutionTransformCompatibility, _topology_policy: ConvolutionTopologyPolicy, _topology_provenance: ConvolutionTopologyProvenance, _coverage_report_cache: _CoverageReportCache, _coverage_report_swapped: bool)[source]
A pre-configured plan for efficient sparse 3D convolution operations on
fvdb.GridBatch.ConvolutionPlanencapsulates all the configuration and optimization structures needed to perform sparse convolution operations efficiently. Like FFT plans in signal processing libraries, aConvolutionPlanrepresents a single direction of computation - either regular convolution or transposed convolution.The plan handles the complex sparse data structures and backend optimizations internally, allowing users to focus on the core convolution parameters: input/output channels, kernel size, stride, and the grid structure.
A plan stores one finite convolution relation. Componentwise, that relation is
fine_ijk = stride * coarse_ijk + tap_ijk - padding_before, wherepadding_before = floor((kernel_size - 1) / 2)and each zero-based tap satisfies0 <= tap_ijk[axis] < kernel_size[axis]. Generated plans use complete structural support; an explicit target restricts that relation. A transposed plan evaluates the same fine/coarse connectivity in the opposite direction and is not a value inverse. For an exact finite adjoint, usefrom_plan_transposed()rather than reconstructing a plan from grids.For framework portability, this index relation matches spconv and TorchSparse when they use
padding=(kernel_size - 1) // 2. MinkowskiEngine corner-anchors even kernels on[0, kernel_size), so porting an even-kernel topology from MinkowskiEngine shifts it byfloor((kernel_size - 1) / 2). fVDB’s complete policy also materializes uncropped boundary support: a full16^3input withkernel_size=stride=4produces a5^3coarse topology rather than4^3.Usage Pattern:
Create a plan using one of the
from_*class methods (seefrom_grid_batch()).Use the
execute()method to perform convolutions with different weights and data on the same grid structures.Reuse the same plan for multiple convolutions with the same configuration
Example Usage:
from fvdb import GridBatch, ConvolutionPlan # Create a grid batch my_grid_batch = GridBatch.from_ijk(...) # Create a plan for 3x3x3 convolution with stride 1 plan = ConvolutionPlan.from_grid_batch( kernel_size=3, stride=1, source_grid=my_grid_batch ) # execute convolution with different weights features = torch.randn(num_voxels, 32, device="cuda") weights = torch.randn(64, 32, 3, 3, 3, device="cuda") output = plan.execute(features, weights)
Note
Always create plans using the
from_*class methods, never call__init__directlyPlans are immutable once created
The same plan can be reused for multiple
execute()calls with different data/weightsChannel pairs can be specified at plan creation time for optimal backend selection
- property coverage_report: ConvolutionCoverageReport | None
Exact input/output rulebook degree diagnostics, when the backend has a rulebook.
- execute(data: Tensor, weights: Tensor) Tensor[source]
- execute(data: JaggedTensor, weights: Tensor) JaggedTensor
Execute this
ConvolutionPlanwith the input data and weights.This is the main method for performing convolution operations. It applies the convolution kernel to the sparse voxel data according to the plan’s pre-configured structure and optimizations.
If the source grid batch has size 1, then
datacan be atorch.Tensorwith shape(total_voxels, in_channels).If the source grid batch has size > 1, then
datashould be aJaggedTensorwith shape(batch_size, num_voxels_in_grid_b, in_channels).Note
The same plan can be reused with different weights and data
Channel pairs must match those specified during plan creation
The plan automatically handles the sparse structure and backend optimizations
For transposed convolution plans, this performs the transpose operation
- Parameters:
data (torch.Tensor | JaggedTensor) – Input voxel features. Can be either: (i)
torch.Tensorfor single grids: shape(total_voxels, in_channels)or (ii)JaggedTensorfor batches of grids: shape(batch_size, num_voxels_in_grid_b, in_channels)weights (torch.Tensor) – Convolution kernel weights with shape:
(out_channels, in_channels, kernel_size[0], kernel_size[1], kernel_size[2]). IdentityK=1, S=1plans also accept the compact shape(out_channels, in_channels).
- Returns:
output_features (torch.Tensor | JaggedTensor) – Convolved features with the same type as input: (i)
torch.Tensorwith shape(total_output_voxels, out_channels)for single grids or (ii)JaggedTensorwith shape(batch_size, output_voxels_per_grid, out_channels)for batches- Raises:
ValueError – If the channel pair
(in_channels, out_channels)from the weights is not supported by this plan’s channel_pairs configuration.
Example:
# Single grid example features = torch.randn(1000, 32, device="cuda") # 1000 voxels, 32 channels weights = torch.randn(64, 32, 3, 3, 3, device="cuda") # 32->64 channels, 3x3x3 kernel output = plan.execute(features, weights) # Shape: (output_voxels, 64) # Batched example batch_features = JaggedTensor(torch.randn(5, 1000, 32, device="cuda")) output = plan.execute(batch_features, weights) # Shape: (5, output_voxels, 64)
- classmethod from_grid_batch(kernel_size: Tensor | ndarray | int | float | integer | floating | Sequence[int | float | integer | floating] | Size, stride: Tensor | ndarray | int | float | integer | floating | Sequence[int | float | integer | floating] | Size, source_grid: GridBatch, target_grid: GridBatch | None = None, *, expert_config: dict[str, Any] = {'backend': 'default'}, channel_pairs: tuple[tuple[int, int], ...] = (), topology_policy: ConvolutionTopologyPolicy | None = None, strict_output_coverage: bool = False, acknowledge_incomplete_coverage: bool = False) ConvolutionPlan[source]
Create a
ConvolutionPlanfor convolution on batches of grids. i.e. convolution where the input and output domains are both of typefvdb.GridBatch.The plan returned by this method is optimized for running convolution on a batch of grids simultaneously and in parallel, which is more efficient than processing individual grids separately when you have a batch of data.
- Parameters:
kernel_size (NumericRank1) – Size of the convolution kernel. Can be a single int (cubic kernel) or a 3-element sequence for (x, y, z) dimensions.
stride (NumericRank1) – Convolution stride. Can be a single int or 3-element sequence.
source_grid (GridBatch) –
fvdb.GridBatchencoding the structure of the input domain.target_grid (GridBatch | None) –
fvdb.GridBatchencoding the structure of the output domain. IfNone, thetarget_gridis automatically computed based onkernel_sizeandstrideapplied tosource_grid.expert_config (dict[str, Any]) – Advanced configuration options (rarely needed by typical users).
channel_pairs (tuple[tuple[int, int], ...]) – Supported input/output channel combinations as tuples. Each tuple represents (input_channels, output_channels). e.g:
((32, 64), (64, 128))supports 32->64 and 64->128 convolutions. Defaults to_ANY_CHANNEL_PAIRS, which means any channel pairs are supported.topology_policy (ConvolutionTopologyPolicy | None) –
COMPLETEgenerates the complete structural support;RESTRICTEDrequirestarget_gridand restricts the relation to it. When omitted, the policy is inferred fromtarget_grid.strict_output_coverage (bool) – Reject explicit targets with degree-zero output rows.
acknowledge_incomplete_coverage (bool) – Suppress the once-per-geometry warning for stride residues that are intentionally not sampled.
- Returns:
convolution_plan (ConvolutionPlan) – Configured plan ready for
execute()operations.
Example:
# Create a batched grid grid_batch = GridBatch.from_points(...) # Create plan for 3x3x3 convolution on batched grids plan = ConvolutionPlan.from_grid_batch( kernel_size=3, stride=1, source_grid=grid_batch ) # execute to batched data batch_data = JaggedTensor(torch.randn(5, 1000, 8, device="cuda")) weights = torch.randn(16, 8, 3, 3, 3, device="cuda") output = plan.execute(batch_data, weights)
- classmethod from_grid_batch_transposed(kernel_size: Tensor | ndarray | int | float | integer | floating | Sequence[int | float | integer | floating] | Size, stride: Tensor | ndarray | int | float | integer | floating | Sequence[int | float | integer | floating] | Size, source_grid: GridBatch, target_grid: GridBatch | None = None, *, expert_config: dict[str, Any] = {'backend': 'default'}, channel_pairs: tuple[tuple[int, int], ...] = (), topology_policy: ConvolutionTopologyPolicy | None = None, strict_output_coverage: bool = False, acknowledge_incomplete_coverage: bool = False) ConvolutionPlan[source]
Create a
ConvolutionPlanfor transposed convolution on batches of grids. i.e. transposed convolution where the input and output domains are both of typefvdb.GridBatch.Transposed convolution is commonly used for decoder and generative operations. It evaluates the same fine/coarse graph in the opposite direction; it is not an inverse and need not recover an input or its topology.
Note
target_grid=NoneselectsCOMPLETEand generates the complete uncropped transposed support. An explicit target selectsRESTRICTEDand may contain zero-degree rows. This factory supports independently learned transpose weights; for the exact weighted adjoint of a particular plan, usefrom_plan_transposed()and passweight.transpose(0, 1).contiguous()at execution.- Parameters:
kernel_size (NumericMaxRank1) – Size of the convolution kernel. Can be a single int (cubic kernel) or a 3-element sequence for
(x, y, z)dimensions.stride – Convolution stride. Can be a single int or 3-element sequence.
source_grid (GridBatch) –
fvdb.GridBatchencoding the structure of the input domain.target_grid (GridBatch | None) –
fvdb.GridBatchencoding the structure of the output domain. IfNone, thetarget_gridis automatically computed based onkernel_sizeandstrideapplied tosource_grid.expert_config (dict[str, Any]) – Advanced configuration options (rarely needed by typical users).
channel_pairs (tuple[tuple[int, int], ...]) – Supported input/output channel combinations as tuples. Defaults to
_ANY_CHANNEL_PAIRS, which means any channel pairs are supported.topology_policy (ConvolutionTopologyPolicy | None) –
COMPLETEgenerates the complete structural support;RESTRICTEDrequirestarget_grid. When omitted, the policy is inferred fromtarget_grid.strict_output_coverage (bool) – Reject explicit targets with degree-zero output rows.
acknowledge_incomplete_coverage (bool) – Suppress the once-per-geometry warning for stride residues that are intentionally not sampled.
- Returns:
convolution_plan (ConvolutionPlan) – Configured plan ready for transposed convolution operations via
execute().
- classmethod from_plan_transposed(plan: ConvolutionPlan) ConvolutionPlan[source]
Create a transposed version of an existing
ConvolutionPlan.This method creates a new plan that performs the exact transpose operation of the given plan (i.e convolution becomes transposed convolution and vice versa). It swaps the source and target grids, reverses the stored finite edge set and channel pairs, and flips the transposed flag. It does not reconstruct topology from the swapped grids.
Note
This is useful when a paired layer must apply the exact finite adjoint connectivity of an existing plan. It is not an inverse and need not recover the original input.
- Parameters:
plan (ConvolutionPlan) – An existing
ConvolutionPlanto transpose.- Returns:
convolution_plan (ConvolutionPlan) – A new plan that performs the transpose of the input plan.
Example:
# Create forward plan forward_plan = ConvolutionPlan.from_grid_batch( kernel_size=3, stride=1, source_grid=input_grid_batch ) # Create the corresponding backward/transpose plan transposed_plan = ConvolutionPlan.from_plan_transposed(forward_plan)
- property geometry: fvdb._fvdb_cpp.ConvolutionGeometry
Canonical immutable geometry shared by this plan’s topology and executors.
- property has_fixed_topology: bool
Returns
Trueif the source and target grids have the same topology, meaning the same voxel structure.- Returns:
has_fixed_topology (bool) –
Trueif source and target grids are the same topology,Falseotherwise.
- property kernel_size: Tensor
Kernel dimensions in the canonical
torch_same_phasegeometry.
- property phase_policy: ConvolutionPhasePolicy
Kernel phase convention used by this plan.
- property source_grid_batch: GridBatch
Return the
fvdb.GridBatchrepresenting the source domain of the convolution. If the plan was created for a single grid, it is returned as a batch of size 1.- Returns:
source_grid_batch (GridBatch) – The source
fvdb.GridBatchof the convolution plan.
- property stride: Tensor
Stride dimensions in the canonical
torch_same_phasegeometry.
- property target_grid_batch: GridBatch
Return the
fvdb.GridBatchrepresenting the target domain of the convolution. If the plan was created for a single grid, it is returned as a batch of size 1.- Returns:
target_grid_batch (GridBatch) – The target
fvdb.GridBatchof the convolution plan.
- property topology_policy: ConvolutionTopologyPolicy
Resolved complete or restricted topology policy.
- property topology_provenance: ConvolutionTopologyProvenance
How this plan’s finite topology was obtained.
Exact transposes always use the stored finite edge set of their source plan and therefore have restricted policy.
- property transform_compatibility: ConvolutionTransformCompatibility
Validated fine/coarse transform compatibility diagnostic.
- valid_usage(in_channels: int, out_channels: int, kernel_size: Tensor | ndarray | int | float | integer | floating | Sequence[int | float | integer | floating] | Size, stride: Tensor | ndarray | int | float | integer | floating | Sequence[int | float | integer | floating] | Size, transposed: bool) bool[source]
Check if this
ConvolutionPlanis valid for the given usage. This method returnsTrueif the plan can apply a (transposed) convolution with the givenkernel_sizeandstridefromin_channelstoout_channels.- Parameters:
in_channels (int) – Number of input channels.
out_channels (int) – Number of output channels.
kernel_size (NumericMaxRank1) – Kernel size. Can be a single int or 3-element sequence.
stride (NumericMaxRank1) – Stride. Can be a single int or 3-element sequence.
transposed (bool) – Whether the plan is transposed.
- Returns:
is_valid (bool) –
Trueif the plan is valid for the given configuration,Falseotherwise.
- class fvdb.ConvolutionCoverageReport(input_row_count: int, output_row_count: int, input_zero_count: int, input_zero_fraction: float, input_degree_min: int, input_degree_max: int, input_degree_histogram: tuple[tuple[int, int], ...], output_zero_count: int, output_zero_fraction: float, output_degree_min: int, output_degree_max: int, output_degree_histogram: tuple[tuple[int, int], ...])[source]
Exact rulebook degree diagnostics for a finite convolution plan.
- input_degree_histogram: tuple[tuple[int, int], ...]
- input_degree_max: int
- input_degree_min: int
- input_row_count: int
- input_zero_count: int
- input_zero_fraction: float
- output_degree_histogram: tuple[tuple[int, int], ...]
- output_degree_max: int
- output_degree_min: int
- output_row_count: int
- output_zero_count: int
- output_zero_fraction: float
- class fvdb.ConvolutionTransformCompatibility(fine_grid_count: int, coarse_grid_count: int, same_batch_size: bool, same_device: bool, scale_compatible: bool, registration_integer: bool, registration_zero: bool, compatible: bool, registration_offset: Tensor | None)[source]
Compatibility of a plan’s normalized fine and coarse lattices.
Compatibility requires matching batch/device metadata,
h_coarse == stride * h_fine, and the canonical uniform registrationa == 0. Comparisons useatol=rtol=1e-6.- coarse_grid_count: int
- compatible: bool
- fine_grid_count: int
- registration_integer: bool
- registration_offset: Tensor | None
- registration_zero: bool
- same_batch_size: bool
- same_device: bool
- scale_compatible: bool
- class fvdb.ConvolutionCoverageWarning[source]
A convolution geometry leaves some stride residues structurally uncovered.
The warning is emitted once per
(kernel_size, stride)geometry for the lifetime of the process. Passacknowledge_incomplete_coverage=Truewhen constructing a plan to acknowledge and suppress it explicitly.