Current collected state Current
Observed since 20 Oct, 21:04 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Fast 3D affine transformations with trilinear interpolation using AVX2/AVX512 SIMD
Fast 3D affine transformations with trilinear interpolation using AVX2/AVX512 SIMD.
| Data Type | Throughput | Memory/Voxel | Speedup |
|---|---|---|---|
| f32 | 1.5 Gvoxels/s | 8 bytes | 1.0x |
| f16 | 1.2 Gvoxels/s | 4 bytes | - |
| u8 | 3.3 Gvoxels/s | 2 bytes | 2.2x |
Use u8 for image data (microscopy, CT, MRI) to get 2.2x faster processing with 4x less memory!
Benchmark on AMD Ryzen 9 9950X (32 threads):
| Volume | scipy | affiners f32 | affiners u8 | Speedup (f32) | Speedup (u8) |
|---|---|---|---|---|---|
| 512³ | 890 ms | 89 ms | 40 ms | 10x | 22x |
| 1024³ | 7.1 s | 710 ms | 320 ms | 10x | 22x |
pip install affine-rs
Or build from source:
pip install .
import numpy as np
import affiners
# Define transformation
matrix = np.array([
[1.0, 0.25, 0.01],
[0.0, 1.0, 0.0],
[0.0, -0.02, 1.0],
], dtype=np.float64)
offset = np.array([-10.0, -5.0, 8.0])
# Float32 data
input_f32 = np.random.rand(512, 512, 512).astype(np.float32)
output_f32 = affiners.affine_transform(input_f32, matrix, offset=offset)
# uint8 data (2.2x faster!)
input_u8 = np.random.randint(0, 256, (512, 512, 512), dtype=np.uint8)
output_u8 = affiners.affine_transform_u8(input_u8, matrix, offset=offset)
import affiners
print(affiners.__version__) # '0.1.0'
print(affiners.build_info())
# {'version': '0.1.0', 'simd': {'avx2': True, 'avx512f': True, ...},
# 'backend_f32': 'avx512', 'backend_u8': 'avx2', 'num_threads': 32, ...}
use ndarray::Array3;
use affiners::{affine_transform_3d_f32, affine_transform_3d_u8, AffineMatrix3D};
// Float32
let input_f32 = Array3::<f32>::zeros((100, 100, 100));
let matrix = AffineMatrix3D::identity();
let shift = [10.0, 20.0, 30.0];
let output_f32 = affine_transform_3d_f32(&input_f32.view(), &matrix, &shift, 0.0);
// uint8 (2.2x faster!)
let input_u8 = Array3::<u8>::zeros((100, 100, 100));
let output_u8 = affine_transform_3d_u8(&input_u8.view(), &matrix, &shift, 0);
| Function | Input Type | Description |
|---|---|---|
affine_transform(input, matrix, offset, cval) | float32 | Standard floating point |
affine_transform_f16(input, matrix, offset, cval) | float16 | Half precision (pass as .view(np.uint16)) |
affine_transform_u8(input, matrix, offset, cval) | uint8 | 2.2x faster, 4x less memory |
build_info() | - | Get version, SIMD features, and backend info |
input: 3D numpy array (C-contiguous)matrix: 3x3 transformation matrix (float64)offset: Translation vector [z, y, x] (optional, default: [0, 0, 0])cval: Constant value for out-of-bounds (default: 0)| Use Case | Recommended Type |
|---|---|
| Image data (CT, MRI, microscopy) | u8 - 2.2x faster |
| Scientific floating-point data | f32 |
| Reduced memory footprint | f16 or u8 |
| Maximum precision | f32 |
| Volume Size | f32 | u8 |
|---|---|---|
| 512³ | 1.1 GB | 0.3 GB |
| 1024³ | 8.6 GB | 2.1 GB |
| 2048³ | 68.7 GB | 17.2 GB |
target-cpu=native)BSD-3-Clause
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.0 | 4 Dec 2025 | 1 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 21:04 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:f596ed489dfe8ac98a9a5dfe78c213cca2749e485854f985301a65836a8f665d