ashvardanian / ashvardanian/NumKong

Feature: N-D lerp with broadcast weights for alpha blending

Open
#369 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
1.9k
Forks
130
Avg merge
18h 28m
Merged PRs (30d)
3

Description

## Workload

Per-pixel alpha blending is a common full-image operation:

```python
out = a + weight * (b - a)
```

AlbumentationsX uses this pattern for CopyPaste feathering and domain adaptation. `weight` can be a scalar, a channel vector, an `(H, W, 1)` alpha map, or a batch/volume alpha tensor. The current NumPy path reads and writes several full-size temporaries.

NumKong 7.7.0 `blend(a, b, alpha=..., beta=...)` covers scalar weights. `fma` accepts three vectors, but expressing `a + weight * (b - a)` still requires a full-size subtraction or complementary-weight temporary.

## Requested primitive

```python
out = nk.lerp(
a,
b,
weight,
out=None,
)
```

Equivalent result:

```python
out = a + weight * (b - a)
```

The implementation may use the numerically preferable equivalent for each dtype and ISA.

## Initial contract

- `float32` inputs and output first.
- Matching `a` and `b` shapes.
- Scalar or NumPy-broadcastable `weight`.
- HWC, NHWC/DHWC, and NDHWC in one call.
- Optional `out=` with documented aliasing for `out is a` and `out is b`.
- Preserve endpoint behavior for `weight == 0` and `weight == 1`.
- Document behavior for weights outside `[0, 1]`, NaN, infinity, and signed zero.
- Release the GIL.

An integer-output extension can follow with explicit rounding and saturation semantics.

## AlbumentationsX examples

CopyPaste feathering:

```python
alpha = alpha_2d[..., None].astype(np.float32)
out = nk.lerp(base_image, donor_image, alpha)
```

Domain adaptation:

```python
out = nk.lerp(image_float32, transformed_float32, weight)
```

## Benchmarks

Compare with:

- `a + weight * (b - a)`;
- `a * (1 - weight) + b * weight`;
- `cv2.addWeighted` for scalar weights;
- `nk.blend` for scalar weights;
- the proposed allocating and `out=` calls.

Use scalar, per-channel, dense alpha-map, and sparse/mostly-binary alpha distributions over HWC through NDHWC. Report time and peak temporary memory.

Related: #313, #315, and #366.

Contributor guide

Open the contributing guide

Research direction

Start by inspecting the existing nk.blend and fma implementations and the benchmark paths for scalar and broadcast operations. Compare the proposed lerp against the listed NumPy, cv2.addWeighted, and nk.blend baselines across HWC through NDHWC shapes. Done means float32 scalar or broadcastable weights, documented out= aliasing and edge cases, GIL release, and reported runtime and temporary-memory results.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, numpy, python
Domain
performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.