Skip to main content

lanczos-triton

简体中文 · Installation · API · Algorithm · Benchmark

Lanczos Triton implements antialiased Lanczos-2 and Lanczos-3 image resizing as Triton GPU kernels. It provides a PyTorch tensor API and a reusable resizer for fixed-resolution image and video pipelines.

Both axes support integer and fractional scale ratios, including reduction, enlargement and mixed directions. Kernels retain the full Lanczos support and are compiled by Triton on first use. There are no pretrained weights or project-specific C++/CUDA extensions to build.

Capability What you get
Tensor API NCHW input, batch support, independently processed channels
Resampling Lanczos-2/3, half-pixel coordinates, antialiased reduction
Repeated processing Reusable geometry weights and optional device autotuning
Integration Contiguous float32 output on the input CUDA device
Inspectable implementation Triton source, independent numerical tests, benchmark tools

Qualitative illustration

Common input, Pillow float reference and actual Triton outputs for reduction and enlargement

Figure 1. A common input resized by independent per-channel Pillow float Lanczos and this implementation. The upper row reduces resolution; the lower row enlarges it. Dimensions are given as height × width. Outputs use Lanczos-3 and antialiased reduction, without sharpening or learned postprocessing.

Floating outputs are compared before display clipping. Panels use nearest-neighbor rendering and fit their respective axes; compare the reference and Triton panels at the same output dimensions. The illustration is not a ground-truth reconstruction benchmark.

Get started

Use Python 3.10+, Linux, an NVIDIA GPU and a compatible CUDA-enabled PyTorch build. Install PyTorch using its installation selector, then run this from the checkout:

python -m pip install -e .

The package requires PyTorch ≥2.6 and Triton ≥3.2. Keep their versions compatible; check torch.cuda.is_available() before use. The first call for a new kernel specialization includes JIT compilation.

Python

import torch
from lanczos_triton import resize

# Replace with your own finite floating-point NCHW image.
image = torch.rand(1, 3, 2160, 3840, device="cuda")
output = resize(image, (1537, 2731), a=3, antialias=True)
assert output.shape == (1, 3, 1537, 2731)
assert torch.isfinite(output).all()
Argument / contract Behavior
image Nonempty NCHW NVIDIA CUDA tensor; float16, bfloat16 or float32
size Positive integer (height, width) target dimensions
a=3 Lanczos support parameter; choose 2 or 3
antialias=True Widen the filter support on each shrinking axis
Output Same device, target size, contiguous float32; input unchanged

Noncontiguous inputs are accepted and copied to contiguous storage. Equal input/output dimensions return an independent float32 copy. Finite values are required, but the API does not scan for NaN/Inf and synchronize the GPU. Inputs requiring gradients are rejected; detach explicitly for inference.

Input and output values are not clipped or normalized. Lanczos has negative lobes and can overshoot near sharp edges; use output.clamp(0, 1) when that is appropriate for display. Each channel is processed independently, including alpha. Color-space conversion and alpha premultiplication belong to the calling pipeline.

Reuse weights across frames

from lanczos_triton import Resizer

resizer = Resizer(
    (2160, 3840),
    (1537, 2731),
    a=3,
    antialias=True,
    device=image.device,
    autotune=True,
)
output = resizer(image)

Resizer fixes the input/output height, width and device, while allowing different batches, channel counts and supported dtypes. It shares geometry weights, not mutable image buffers. autotune=False is the default; True benchmarks several equivalent launch configurations on first use. Report this startup cost separately from steady-state inference.

Calls support different CUDA streams; input production and output consumption still follow PyTorch stream synchronization rules. For CUDA Graphs, construct the resizer outside capture, warm up the exact shape/dtype and synchronize before capture. Keep the resizer and input alive for the graph's lifetime. This class is a callable utility, not an nn.Module or serialized model.

How it works

Lanczos-2/3 kernels and support widening for antialiased downsampling

Figure 2. (a) Lanczos-2 and Lanczos-3 reconstruction kernels. (b) Continuous Lanczos-3 kernels L(x/s)/s for scales s=1,3 illustrate support widening. Actual discrete weights are normalized separately at each output position, including image boundaries.

The one-dimensional kernel is L(t) = sinc(t) * sinc(t/a) for |t| < a, and zero elsewhere, where sinc(t) = sin(pi*t)/(pi*t) and sinc(0)=1. Two one-dimensional passes implement separable two-dimensional resampling.

Convention Definition
Pixel centers Output index j maps to (j + 0.5) * input_size / output_size - 0.5
Antialias scale s = max(input_size/output_size, 1); s=1 when disabled
Sample weight L((i-center)/s), normalized over valid input indices
Boundaries Exclude samples outside the image and renormalize remaining weights
Arithmetic Float32 weights, accumulation and intermediate images

Reduction expands the full sampling window. The implementation does not replace it with repeated smaller resizes or an area/bilinear prefilter. Coordinate calculation uses integer quotient/remainder decomposition to preserve local fractional positions at large image coordinates. Fused multiply-add and parallel reductions can change final rounding; bitwise agreement with other implementations is not promised.

The sampling conventions correspond to Pillow's floating single-channel Lanczos path. Pillow's uint8 path includes intermediate quantization/clipping and is not a strict floating-point reference. Disabling antialiasing changes the reduction filter and can produce aliasing.

Scale-aware execution

Workload Execution strategy
Identity / one unchanged axis Copy / filter only the changing axis
Windows up to 32 samples Unrolled sampling, horizontal row reuse, shared vertical row weights
Wider reduction windows Parallel, chunked reductions over every valid sample
Extreme reduction Bound support to available input; process it in chunks
Singleton width Reuse contiguous horizontal filtering for the vertical axis
Mixed / unequal axis scales Independent weights; choose the smaller intermediate image
Repeated geometry Reuse weights; optional autotuning changes layout, not the filter

Weights are stored by sample offset and output position for contiguous horizontal access. With horizontal-first execution, work is approximately N*C*(IH*OW*Kx + OH*OW*Ky). Memory includes the float32 intermediate and weight tables; noncontiguous input adds a contiguous copy. There is no global GPU weight cache. A Resizer owns its tables, whose reuse/freeing follows CUDA stream lifetimes and PyTorch's allocator.

Image sizes are limited by device memory and int32 element indexing capacity.

Run your own benchmarks

python -m pip install -e ".[test]"

# Validate 14 scale families from a 2160×3840 input, without timing.
python benchmarks/benchmark.py --suite --check-only

# Time ordinary calls and prepared/autotuned calls separately.
python benchmarks/benchmark.py --suite --autotune
python benchmarks/benchmark.py --input 2160 3840 --output 1537 2731 --dtype float16

# Warm CUDA Graph execution, excluding per-call Python dispatch.
python benchmarks/benchmark.py --input 1080 1920 --output 2160 3840 --autotune --timing graph

# Optional trusted local comparator exposing the same resize API.
python benchmarks/benchmark.py --compare /path/to/reference_lanczos.py

The suite covers integer/fractional enlargement and reduction, near-identity sizes, strong reduction, one-axis changes, both mixed directions and 1×1 output. Defaults are batch=1, RGB and float32. Use --help for batch, channels, dtype, antialiasing and timing options. Results print to stdout; no dataset is downloaded or result file written automatically.

Every Lanczos method first checks output shape and finiteness. Boundary and interior samples from the first batch/channel are compared against independent CPU float64 direct convolution. The test suite additionally checks complete small multichannel outputs, Pillow float references, large coordinates, constants, checkerboards, impulses, edges and chirps.

Timing reports warm median device latency. resize includes weight generation; prepared excludes construction and autotuning. Neither includes first JIT, image I/O or CPU/GPU transfers. CUDA event/graph timing is not end-to-end wall-clock latency. Keep GPU load and inputs consistent, and report cold-start costs separately. --alternatives adds PyTorch bicubic/bilinear as different filters; their timings do not establish a speedup over another Lanczos implementation.

Tests

python -m pip install -e ".[test]"
pytest -q tests/test_api.py  # CPU contracts
pytest -q                  # includes actual GPU tests when available

Independent floating references use atol=rtol=2e-5; tests also cover noncontiguous input, supported dtypes, streams, CUDA Graphs and autotuning. GPU tests skip on CPU-only machines.

License

MIT. See LICENSE. The documentation photograph has separate provenance in assets/README.md.

Publishing

Version tags automatically build and publish to PyPI after CI passes. See RELEASING.md for one-time Trusted Publisher setup and release steps.

Metadata

Release files for lanczos-triton 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lanczos-triton 0.1.0
File Size Uploaded
lanczos_triton-0.1.0.tar.gz 674.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lanczos-triton 0.1.0
File Interpreter ABI Platform
lanczos_triton-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 685.9 kB

Release files / lanczos_triton-0.1.0.tar.gz

Download URL lanczos_triton-0.1.0.tar.gz
Size 674.6 kB
Tags Source
SHA-256 checksum
How to use checksums
6db5a46f9538a18a62fcea82b497f8720b1e3d75ff3433357544cc8d66921050
BLAKE2b-256 checksum
How to use checksums
65d6b86e5fd60229ff2baab1d0d716b8bbd38b46eda9cd355770e7ffad1865fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / lanczos_triton-0.1.0-py3-none-any.whl

Download URL lanczos_triton-0.1.0-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
55ae95ca6e982666c06d4b511e2c8e4728915ad211a362d57ebf859e560d543b
BLAKE2b-256 checksum
How to use checksums
e80634fd6b83fa44349cd4f3241fad6562edf9da3292a608c67833612372d0a5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page