NatLabRockies / NatLabRockies/ninterp
Channel subsetting for `Strategy*Multi`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 17
- Forks
- 13
- Avg merge
- 44m
- Merged PRs (30d)
- 2
Description
#19's multi-channel interpolate_into always evaluates every channel. A caller wanting
one channel out of many (the gluon from a 13-flavor PDF set, the green channel of an RGB
image) pays for all of them. Add a way to request a subset.
API changes
Additive, defaulted, so it does not disturb #19's required-method story. 2D shown:
/// Interpolate only the channels listed in `channels`, writing channel
/// `channels[i]` into `out[i]`. `out.len()` must equal `channels.len()`.
///
/// Default evaluates all channels into a scratch buffer and gathers. Override
/// when the strategy can skip the unrequested channels outright, which is every
/// strategy whose per-channel work is a lookup or blend against a shared locate
/// result, i.e. all of them in this crate.
fn interpolate_channels_into(
&self,
data: &InterpData2DMulti<D>,
point: &[D::Elem; 2],
channels: &[usize],
out: &mut [D::Elem],
) -> Result<(), InterpolateError> { /* default: evaluate all, gather */ }
Plus the batch equivalent, and a matching method on Interp2DMulti and
DynInterpolatorMulti. Out-of-range indices in channels are an error
(InterpolateError::Other, or a dedicated variant), not silently skipped.
Why not in #19
Purely additive on top of #19's trait, since the default body is expressible in terms of
the required interpolate_into. Splitting it keeps #19's reviewable surface to the
shared-grid mechanism itself.
But it should not drift far behind #19, because of an interaction worth stating
explicitly.
The duplication it resolves
Without subsetting, a consumer that has both single-channel and all-channel access
patterns has to choose:
Keep per-channel Interp2D and Interp2DMulti |
Interp2DMulti only |
|
|---|---|---|
| All-channel call | One locate, all channels | One locate, all channels |
| Single-channel call | One locate, one channel | One locate, all channels, discard n-1 |
| Grid axis storage | n_channels + 1 copies | 1 copy |
| Values storage | 2 copies | 1 copy |
Neither column is acceptable, and #19's memory win only materializes in the right-hand
one. Subsetting makes the right-hand column strictly better than the left on both axes.
#19's InterpData2DMulti::channel_view(k) is a partial escape hatch: it hands back an
InterpData2DViewed that a plain Strategy2D can interpolate against, giving
single-channel cost with single-copy storage. Two caveats keep it from closing this
issue:
- The view is strided, not contiguous (
values.index_axis(Axis(2), k)over a
channel-last layout has striden_channels). Any strategy reaching for
data.values.as_slice().unwrap()panics on it. That is not hypothetical: several of
QCDLab/neopdf's strategies do exactly that (LogChebyshevInterpolation's
Strategy1D/2D/3D/NDimpls,AlphaSCubicInterpolation). - It only covers exactly one channel, not an arbitrary subset or reordering.
Downstream motivation
QCDLab/neopdf's all-flavor evaluators take pid_slots: &[Option<usize>], an arbitrary
subset and permutation of channels, with None meaning "requested flavor absent from
this set, yield 0.0". The subset and permutation half is what this issue covers. The
None sentinel is PDF-domain logic and should stay in neopdf: it maps cleanly onto
partitioning the request before the call.
Both of its evaluation paths (InterleavedHermite::eval_allpids,
ChebyshevAllPids::eval_allpids) and both of its public entry points
(GridPDF::xfxq2_allpids, xfxq2_allpids_with_slots) thread pid_slots through, and
neopdf_pdf_xfxq2_allpids exposes it across the C ABI.
Dependencies
- #19: defines
Strategy*Multiandchannel_view. Must land first. - #45: the
_intoconvention these signatures follow.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the StrategyMulti trait and channel_view from #19, then read the _into convention from #45. Add the point and batch subset methods described for StrategyMulti, Interp2DMulti, and DynInterpolatorMulti, including out-of-range validation and default behavior. Done means arbitrary channel subsets and permutations work without changing the required-method story.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, data
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100