Add or change an operation¶
An operation is more than a numerical function. A complete contribution aligns the headless implementation, registry contract, graph behavior, metadata, interactive inspection, export, examples, and tests.
Design first¶
Specify:
- scientific purpose and evidence for the method;
- input and output semantic types;
- axis and 2D/3D behavior;
- dtype/range behavior and empty/degenerate cases;
- metadata fields preserved, changed, inferred, or dropped;
- execution policy (
autoormanual) and cancellation/progress needs; - expected memory scaling;
- parameters, defaults, bounds, units, and invalid combinations.
Avoid adding a near-duplicate operation only to expand the node count. Prefer a clear focused node when a selector would hide materially different methods or parameter meanings.
Implementation checklist¶
- Add or revise the headless operation under
napari_vipp.core. - Register an
OperationSpecwith a stable ID, title, category, typed ports, parameters, execution policy, and stack-processing note. - Define static or dynamic outputs explicitly; test saved-workflow restoration when the number of ports depends on runtime data.
- Transform
ImageStateorTableStatedeliberately. - Keep Python export and batch execution aligned with interactive semantics, or reject unsupported graphs with a clear error.
- Add focused operation, pipeline, persistence, export, and UI tests in proportion to risk.
- Add a deterministic sample/example only when it teaches or validates a stable capability.
- Update the node reference, workflow guides, validation status, and release notes.
Add a CPU/GPU vertical slice¶
An accelerated function is not complete merely because it imports or runs on a GPU. For each public region:
- Keep the established CPU operation, defaults, axes, dtype, boundary, rounding, overflow, and error behavior authoritative.
- Declare a stable implementation/library/runtime identity and versioned parameter, workload, parity, memory, boundary, precision, progress, and cancellation policy IDs.
- Keep optional provider imports lazy so CPU-only plugin discovery, workflow loading, and execution remain safe without CUDA packages.
- Derive eligibility from detached exact workload facts. Reject unsupported dtypes, shapes, parameters, and environments visibly; never synthesize a cast or alter an authored parameter to pass admission.
- Define residency and every host boundary, including ordered inputs, multi-output behavior, and any exact typed host-table finalizer.
- Bound device memory conservatively and classify runtime OOM separately from availability, eligibility, parity, and other device faults.
- Report only synchronized progress checkpoints; make cancellation cooperative at those boundaries and prove cleanup after success, rejection, cancellation, error, OOM, and benchmarking.
- Carry exact implementation, environment, decision, fallback, memory, and cleanup provenance through interactive, batch, generated Python/CLI, and export execution.
- Promote only the reviewed region as a public provider. Public Custom and Prefer-GPU visibility require scientific and operational admission; Auto may use the reviewed public default without local timing. Normal execution may record successful, fallback-free completed full-pipeline wall time for compatible future Auto decisions. Accelerated-only history schedules one same-surface CPU exploration run; Auto never silently benchmarks multiple implementations or mixes incompatible timing surfaces. Prefer GPU bypasses only the CPU-speed gate and must never waive dtype, parameter, environment, dependency, or memory gates. Broader CPU behavior remains first-class and must not be described as a failed GPU feature.
Scientific tests¶
Test invariants with simple truth: uniform images, single objects, known geometries, explicit axes/scale, empty masks, boundary-touching objects, and small arrays. Numerical equality to the same underlying library call is useful but not independent validation of the scientific claim.
For multi-input operations test shape/axis incompatibility and port ordering. For tables test identity columns, units, missing values, and merge behavior—not only that a table object was returned.