Module rast

rast — SIMD raster tile processing for Erlang.

Description

rast — SIMD raster tile processing for Erlang.

Public façade. Two layers live behind it:

1. Kernels (rast_nif) — bounded, per-tile, binary-first operations in Rust. Fused and typed: u16 source data is widened to f32 inside the kernel, and compound indices such as NDVI are computed in a single pass over the tile. 2. Orchestration (planned: rast_coordinator / rast_worker / rast_gdal) — bounded-memory, demand-driven tiling of a whole scene, with GDAL doing the windowed I/O.

Only layer 1 is implemented in this scaffold. Layer 2 functions return {error, not_implemented} and document the intended contract.

All vectors/tiles crossing this boundary are little-endian binaries, never Erlang lists — that is the whole point at raster scale (a single Sentinel-2 band is ~120 M pixels).

Data Types

f32_bin()

f32_bin() = binary()

little-endian IEEE-754 f32 samples

reason()

reason() = length_mismatch | odd_length | empty | not_implemented | term()

u16_bin()

u16_bin() = binary()

little-endian uint16 samples

Function Index

convolve_f32/6Valid 2-D cross-correlation of an f32 tile (SrcW × SrcH) with a KW × KH f32 kernel.
decode_u16/2Widen a u16 tile to an f32 tile, scaling each sample by Scale.
ndvi_f32/2NDVI of two f32 tiles (NIR, Red) → f32 tile, fused single pass.
ndvi_u16/2NDVI of two u16 tiles (NIR, Red) → f32 tile, fused single pass.
pad_replicate_f32/7Replicate-pad an f32 tile by Left/Top/Right/Bottom rows/cols.
process_band/3Process a whole scene through GDAL, tile-by-tile, under a fixed memory budget, writing a GeoTIFF result.
process_convolution/5Convolve a whole scene with a KW × KH f32 kernel, writing an f32 GeoTIFF.
process_tiles/3Generic bounded-memory tiling engine.
version/0

Function Details

convolve_f32/6

convolve_f32(Src::f32_bin(), SrcW::pos_integer(), SrcH::pos_integer(), Kernel::f32_bin(), KW::pos_integer(), KH::pos_integer()) -> {ok, f32_bin()} | {error, reason()}

Valid 2-D cross-correlation of an f32 tile (SrcW × SrcH) with a KW × KH f32 kernel. Output (SrcW-KW+1) × (SrcH-KH+1).

decode_u16/2

decode_u16(Data::u16_bin(), Scale::float()) -> {ok, f32_bin()} | {error, reason()}

Widen a u16 tile to an f32 tile, scaling each sample by Scale.

ndvi_f32/2

ndvi_f32(Nir::f32_bin(), Red::f32_bin()) -> {ok, f32_bin()} | {error, reason()}

NDVI of two f32 tiles (NIR, Red) → f32 tile, fused single pass.

ndvi_u16/2

ndvi_u16(Nir::u16_bin(), Red::u16_bin()) -> {ok, f32_bin()} | {error, reason()}

NDVI of two u16 tiles (NIR, Red) → f32 tile, fused single pass.

pad_replicate_f32/7

pad_replicate_f32(Src::f32_bin(), W::pos_integer(), H::pos_integer(), L::non_neg_integer(), T::non_neg_integer(), R::non_neg_integer(), B::non_neg_integer()) -> {ok, f32_bin()} | {error, reason()}

Replicate-pad an f32 tile by Left/Top/Right/Bottom rows/cols. Output (W+Left+Right) × (H+Top+Bottom).

process_band/3

process_band(Sources::[file:filename()], Dst::file:filename(), Opts::map()) -> {ok, file:filename()} | {error, reason()}

Process a whole scene through GDAL, tile-by-tile, under a fixed memory budget, writing a GeoTIFF result.

Sources :: [file:filename()] %% 1 for {decode,_}, 2 (NIR, Red) for ndvi Dst :: file:filename() %% output GeoTIFF path Opts :: #{op := ndvi | {decode, Scale :: float()}, tile => {W, H}, %% default {512, 512} workers => pos_integer()}

Reads windows via the GDAL bridge, runs the fused kernel per tile, and scatters results into the output; peak memory stays bounded by workers × tile_bytes (ARCHITECTURE.md §5). Requires GDAL — see rast_gdal.

process_convolution/5

process_convolution(Src::file:filename(), Dst::file:filename(), Kernel::f32_bin(), X4::{pos_integer(), pos_integer()}, Opts::map()) -> {ok, file:filename()} | {error, reason()}

Convolve a whole scene with a KW × KH f32 kernel, writing an f32 GeoTIFF. Each output tile reads a source window grown by the halo, so tiles compose without seams (ARCHITECTURE.md §5).

Src :: file:filename() %% UInt16 or Float32 single band Kernel :: f32_bin() %% KW*KH little-endian f32, row-major Opts :: #{tile => {W,H}, workers => pos_integer(), pad => clamp | valid} %% default clamp

pad => clamp (default): full-size W × H output; the apron at the scene border is synthesized by edge replication. pad => valid: no border synthesis, output shrinks to (W-KW+1) × (H-KH+1).

process_tiles/3

process_tiles(Tiles::[term()], Funs::rast_worker:funs(), Opts::map()) -> {ok, #{tiles := non_neg_integer(), workers := pos_integer()}} | {error, term()}

Generic bounded-memory tiling engine.

Drives a demand-driven worker pool over Tiles: each worker pulls a tile, reads it, runs the kernel, and writes the result, repeating until the tiles are exhausted. Peak memory is bounded by Workers × tile_bytes — no more than one tile is resident per worker (ARCHITECTURE.md §5).

This is the source-agnostic core: Funs injects the I/O so the same engine serves an in-memory source (tests) or the GDAL bridge (production).

Funs :: #{read := fun((Tile) -> {ok, binary()} | {error, term()}), kernel := fun((binary()) -> {ok, binary()} | {error, term()}), write := fun((Tile, binary()) -> ok | {error, term()})} Opts :: #{workers => pos_integer()} %% default: dirty CPU schedulers

version/0

version() -> binary()


Generated by EDoc