Skip to main content

Serron

Mathematical Morphology module for PyTorch (CUDA), providing differentiable operators and learnable network layers.

Install

Prebuilt wheels are published for CPython 3.12–3.14 on Linux (x86_64, aarch64) and Windows (x86_64).

pip install serron

The wheels are built against torch 2.14 and require it (torch>=2.14,<2.15): the torch C++ ABI changes between minor releases. They load on both CUDA and CPU-only torch builds; the CUDA kernels are only loaded when the installed torch has CUDA.

Usage

Serron works on standard PyTorch tensors laid out as (N, C, H, W) and living on a CUDA or CPU device.

Functional operators

Stateless operators live in serron.functional and are re-exported at the top level. Each takes an input tensor, a structuring element, and an optional border mode:

import torch
import serron
from serron import BorderMode
from serron import structuring_element as se

x = torch.rand(1, 1, 256, 256, device="cuda")
kernel = se.disk(3, device="cuda")

eroded = serron.erosion(x, kernel)
dilated = serron.dilation(x, kernel)
opened = serron.opening(x, kernel)
closed = serron.closing(x, kernel)

# Derived operators
grad = serron.gradient(x, kernel)  # dilate(x) - erode(x)
white = serron.top_hat(x, kernel)  # x - open(x)
black = serron.black_hat(x, kernel)  # close(x) - x

# Control border handling
eroded_reflect = serron.erosion(x, kernel, border=BorderMode.REFLECT)

Available operators: erosion, dilation, opening, closing, gradient, top_hat, black_hat, reconstruction_by_dilation, reconstruction_by_erosion.

Geodesic reconstruction

reconstruction_by_dilation floods a marker outwards until it settles, held down by a mask at every step; reconstruction_by_erosion is its dual. Both iterate the compiled erode / dilate ops to a fixed point and default to BorderMode.CONSTANT, which is the geodesic reading of the image boundary.

marker = torch.zeros_like(x)
marker[..., 128, 128] = x[..., 128, 128]

with torch.no_grad():  # no backward pass yet
    flooded = serron.reconstruction_by_dilation(marker, x, se.cross(3, device="cuda"))

The loop runs on the device, but its convergence test reads one flag back to the host every check_every steps (16 by default). Raise it to trade a few wasted steps for fewer syncs.

Structuring elements

serron.structuring_element builds common SE shapes on the requested device:

from serron import structuring_element as se

se.square(5, device="cuda")  # (5, 5) full square
se.cross(5, device="cuda")  # (5, 5) plus shape
se.disk(3, device="cuda")  # (7, 7) disk, radius 3
se.diamond(3, device="cuda")  # (7, 7) diamond, radius 3
se.from_tensor(my_weights)  # wrap an arbitrary 2-D tensor as a grayscale SE

Border modes

BorderMode controls how out-of-bounds neighbors are handled:

Mode Behavior
BorderMode.REPLICATE Repeat the edge value (default)
BorderMode.REFLECT Mirror across the edge
BorderMode.CONSTANT Pad with a constant

Learnable layers

serron also exposes torch.nn.Module layers with a learnable structuring element, so morphology can be trained end-to-end inside a network. Each layer takes the number of channels and a kernel_size:

import torch
from serron import Erosion2d, Dilation2d, Opening2d, Closing2d
from serron import BorderMode

layer = Erosion2d(channels=3, kernel_size=5, border=BorderMode.REPLICATE).cuda()

x = torch.rand(8, 3, 64, 64, device="cuda")
y = layer(x)  # forward pass; layer.weight is a trainable (C, k, k) SE
y.sum().backward()  # gradients flow into layer.weight

Available layers: Erosion2d, Dilation2d, Opening2d, Closing2d.

Implementation

Every operator picks one of a few kernels at call time. The structuring element and the device's shared memory decide which one.

Which path runs

Path Runs when Cost per output
Separable van Herk–Gil–Werman Flat SE and max(kH, kW) >= SERRON_SEPARABLE_MIN_K O(1) in the window length
Tiled 2-D Otherwise, when the halo tile and the SE fit in shared memory O(kH × kW)
Element-wise Otherwise; reads through global memory (CUDA only) O(kH × kW)

SERRON_SEPARABLE_MIN_K is the window length where the separable path takes over. It accepts any positive integer. The default differs per backend because it marks where the separable path starts beating the 2-D one, and that point is not the same on both: 11 on CUDA, 5 on CPU, where there is no tiled 2-D kernel to soften the kH × kW window.

The separable path

Splitting a flat kH × kW window into a 1 × kW row pass and a kH × 1 column pass already drops the per-pixel work from kH × kW to kH + kW, and the Van Herk–Gil–Werman algorithm drops it further to a constant three operations per ouput, no matter the sequence length.

On CUDA both scans sit in shared memory. A chunk at least a warp wide gets a warp to itself and the lanes cooperate through shuffles; anything shorter gets a single thread. On CPU the lines go through at::parallel_for.

Backward

Backward needs to know where the winning sample was, not just what it was, so its scans carry a (value, offset) pair rather than a bare value. Combining two of those keeps the lower offset on a tie, which is the rule the direct kernel gets from its strict-improvement loop — reproducing it exactly is what makes the two paths agree on which tap receives the gradient. The window is one pair-combine as before, so the search is O(1) in the window length on both the row and the column pass.

It splits on the same condition: a separable row and column argreduce for a flat SE at or above the threshold, and a direct recompute of the winning tap otherwise. The direct recompute stages its window in shared memory the same way the forward's tiled path does.

Benchmarks

Per-operator throughput and the cross-library comparison live in benchmarks/README.md.

Erosion with a flat SE, 8x3x512x512 float32 on an H100 PCIe (with Intel Xeon Platinum 8480+), in milliseconds:

k serron PyTorch Kornia CuPy SciPy (CPU)
7 0.30 0.42 2.80 0.20 159
31 0.23 5.46 41.87 0.58 151
63 0.31 21.48 OOM 1.05 144
127 0.25 81.03 OOM 2.00 142

Building from source

Clone repo

git clone git@github.com:vhrabar/serron.git
cd serron

Choosing a torch build

torch is pulled from a specific wheel index via mutually-exclusive extras. Pick the one matching your machine, plain uv sync (no extra) falls back to the default CUDA-enabled wheel from PyPI:

uv sync --extra cu132   # CUDA 13.2 build
uv sync --extra cpu     # CPU-only build

Building the wheel

Building the CUDA extension from source needs the CUDA 13.X toolkit (nvcc):

uv sync --package serron --no-dev --group build --extra cu132
uv build --package serron --wheel --no-build-isolation

On a GPU-less machine, sync the CPU torch build instead; the extension then builds C++ only (no nvcc required):

uv sync --package serron --no-dev --group build --extra cpu
uv build --package serron --wheel --no-build-isolation

License

MIT

Copyright © 2026 Vedran Hrabar.

Metadata

Release files for serron 0.4.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 serron 0.4.0
File Size Uploaded
serron-0.4.0.tar.gz 38.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for serron 0.4.0
File
serron-0.4.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details
serron-0.4.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 Details
serron-0.4.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ ARM64, Linux glibc 2.24+ ARM64 Details
serron-0.4.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
serron-0.4.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 Details
serron-0.4.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.24+ ARM64, Linux glibc 2.28+ ARM64 Details
serron-0.4.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
serron-0.4.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 Details
serron-0.4.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.24+ ARM64, Linux glibc 2.28+ ARM64 Details

Total release size: 310.7 MB

Release files / serron-0.4.0.tar.gz

Download URL serron-0.4.0.tar.gz
Size 38.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3dcc6d97f3fc6ed9c1e20b1cf6bf7a7b280c93b90dc3a0e31f89d61d1134a9af
BLAKE2b-256 checksum
How to use checksums
2c42ebaf85df3e8e103503fc2333e5a842d3ca18cdd75fbace34dee1000757d9
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp314-cp314-win_amd64.whl

Download URL serron-0.4.0-cp314-cp314-win_amd64.whl
Size 4.6 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
54a78364ab6a78d8ca7f29329bfe3b7b517d59d7f5d0a00799ec4193c1d92537
BLAKE2b-256 checksum
How to use checksums
f32858094ac95c28861c3622ac724a5ef8da1d8fbc67c85d27ce0f3dd6653532
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL serron-0.4.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 50.6 MB
Tags CPython 3.14 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
c254630417d1ef32eca38b8f360cf1eda91b6133eea38667f2502ca7e3f0dd29
BLAKE2b-256 checksum
How to use checksums
6d1f87aeaaced68f19d49b8622ac8fe29b3fd79ffa892ecb24c9dff3d4baf942
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL serron-0.4.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 48.3 MB
Tags CPython 3.14 Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
95fa0d9205f397b0a0be060a1d6d6d36959e20cd5c2dd4770afa60d77ab43faa
BLAKE2b-256 checksum
How to use checksums
31241429423beb0b9f4519b47c627c3f9181157f06a59aa482e3ef7af48202a8
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp313-cp313-win_amd64.whl

Download URL serron-0.4.0-cp313-cp313-win_amd64.whl
Size 4.6 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
d47063128d87e46bbedfc552227952bd7214dfa23184cf2e334b24faf83a0509
BLAKE2b-256 checksum
How to use checksums
3674ca24fb6030ebe0ab85dc8844bc8cb5746fe15c73b43c8ae2281e196cf07f
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL serron-0.4.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 50.6 MB
Tags CPython 3.13 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
b5df5e8237a3db10af75aa5b74c1c54bf5db82f86b75d1a82d9e73c30f8bfa71
BLAKE2b-256 checksum
How to use checksums
273c989c15242fbe2b513b49d144d50fd30f2c9b4f115b05f468f6696b5b620d
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL serron-0.4.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 48.3 MB
Tags CPython 3.13 Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
267200ac6e9459ef3646c94d562697ac1faca0f779ef77a6d8ad6e702ecc3e81
BLAKE2b-256 checksum
How to use checksums
d47473e19b3e75494c24a5b9ca2e5526a029fe1858145e0441cb43bd9032115e
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp312-cp312-win_amd64.whl

Download URL serron-0.4.0-cp312-cp312-win_amd64.whl
Size 4.6 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
b1bcb216df6e28b09a405f13103a7e18732f2ebbdd8e8c1bc9be216dc9fa194f
BLAKE2b-256 checksum
How to use checksums
895db117ccbca45104cef235a389dd4c9a7caf3418c77b91dfd2b19eeb32db9f
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL serron-0.4.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 50.6 MB
Tags CPython 3.12 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
5b25a5a398b1605ade054481ae4739a9799510988d8242bd9579fc32aa693819
BLAKE2b-256 checksum
How to use checksums
0cc0d67410bd54a2201ead77e7d5e62378353a09ef46d445166a7a667869b685
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 1, 2026.

Transparency log

Release files / serron-0.4.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

Download URL serron-0.4.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Size 48.3 MB
Tags CPython 3.12 Linux glibc 2.24+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
341b8068ec05b30816a819c770fd8d0d7e9f47db1d7f8ba8d9381d123c7db109
BLAKE2b-256 checksum
How to use checksums
2d6fc74eb86c730d66c7f15e63e53fcc17ed019e07d1e618c54f15442fc07bb1
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 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

4 release files

This release

0.4.0 This release

10 release files

0.3.1

10 release files

0.2.0

10 release files

0.1.1

10 release files

0.1.0

10 release files

0.0.1

10 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