Caveats and stability notes¶
This page records user-visible constraints and stability boundaries.
For API stability levels, read Stability contract.
Coordinate order is stable¶
Coordinate rows are ordered as (batch, x, y, z). This is the canonical
internal and public order. Inputs using another convention should be converted
before constructing SparseTensor objects.
Coordinate value equality is not identity¶
Two tensors can contain equal coordinate rows but have different
CoordinateMapKey values. Cached relations are keyed by coordinate identity,
not by a late comparison of array contents. Use sparse alignment when combining
independently constructed tensors.
Active rows and capacity differ¶
Native coordinate builders may allocate a buffer larger than the active set.
Use active_rows to determine how many rows are valid. Treating every
allocated row as active can include uninitialized or padded coordinate rows in
later operations.
Dtype boundaries¶
Surface |
Supported dtype boundary |
Notes |
|---|---|---|
Metal coordinates |
|
Sparse convolution and pooling validate this before launch. |
Floating convolution |
|
Specialized Metal routes depend on dtype and channel count. |
Local pooling |
|
Sum, max, and average local pooling share this boundary. |
Point/voxel |
|
Native quantization and interpolation routes use this contract. |
Quantized weights |
int4/int8 packed in |
Scales/biases match feature dtype at execution. |
Global pooling requires batch metadata¶
Global pooling reduces to a dense (B, C) array. It requires
batch_counts because a sparse coordinate buffer alone does not encode empty
batches. Sum and average define empty-batch behavior; max rejects empty batches.
Internal routes are not public APIs¶
Kernel names, CSR view names, sorted implicit-GEMM views, TensorOps variants, and diagnostic reference routes are backend implementation details. They can be useful for debugging a failing run, but application code calls public operations and modules.
Entropy byte streams are provisional¶
Entropy helpers are public callables, but the exact encoded byte stream is not
yet a cross-version persistence format. If you store streams externally, record
the mlx-lattice version alongside them.
Quantization is storage-real, not fake quantization¶
QuantizedWeight stores packed int4/int8 data plus affine metadata. Supported
native routes consume packed storage. If you want the floating contract, call
dequantize_weight explicitly and use the floating operation.
Sparse performance depends on geometry¶
Sparse runtime is not determined by active row count alone. Important factors include edge count, kernel volume, channel count, coordinate pattern, sorted view availability, and whether the operation is relation-bound or arithmetic-bound. Report those fields with benchmark results.
Point/voxel maps are geometry-specific¶
A point-to-voxel map is tied to points, batch indices, voxel size, origin, voxel coordinates, and interpolation mode. Reusing a map after changing any of those inputs is a semantic error.