Metadata-Version: 2.2
Name: serron
Version: 0.1.0
Summary:  Mathematical Morphology module for PyTorch (CUDA), providing differentiable operators and learnable network layers.
Keywords: cuda,pytorch,morphology
Author-Email: Vedran Hrabar <vedran.hrabar@outlook.com>
License: MIT
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Environment :: GPU
Classifier: Environment :: GPU :: NVIDIA CUDA
Classifier: Environment :: GPU :: NVIDIA CUDA :: 13
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: C++
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Project-URL: repository, https://github.com/vhrabar/serron
Project-URL: documentation, https://github.com/vhrabar/serron/wiki
Project-URL: Bug Tracker, https://github.com/vhrabar/serron/issues
Requires-Python: >=3.12
Requires-Dist: torch>=2.12
Description-Content-Type: text/markdown

# 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). A working CUDA-enabled PyTorch (`torch >= 2.12`) must already
be installed in the environment.

```bash
pip install serron
```

## Usage

> **Alpha:** the CUDA kernels are not wired up yet, so the operators below currently
> raise `NotImplementedError`.

Serron works on standard PyTorch tensors laid out as `(N, C, H, W)` and living on a CUDA
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:

```python
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.dilatation(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`, `dilatation`, `opening`, `closing`, `gradient`,
`top_hat`, `black_hat`.

### Structuring elements

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

```python
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`:

```python
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`.

## Building from source

Requires the CUDA 13.X toolkit (`nvcc`) and a matching `torch` build:

```bash
uv sync --package serron --no-dev --group build
uv build --package serron --wheel --no-build-isolation
```

## License

MIT

Copyright © 2026 Vedran Hrabar.
