rstsr-core (feat): custom user reduction and cumulative scan functions - #111
Merged
Merged
Conversation
…ce_with_args) Expose the internal fold machinery as expert-level free functions over a new `OpReduceCustomAPI<T, TS, TO, D>` device trait: generic accumulator `TS` and output `TO`, user-provided init/fold/combine/finalize closures (`Send + Sync`; `combine` must be associative, documented). No `TensorAny` methods -- expert-level surface only. - `reduce_all(x, f_init, f, f_sum, f_out)` -> `TO` - `reduce_axes(x, axes, ...)` -> per-axis tensor (`AxesIndex::None` = whole) - `reduce_with_args(x, args, ...)` -> `ReduceArgs` (axes + keepdims) - fallible `_f` twins; docstring anchors are the non-fallible forms (`reduce_all` carries a "common reductions expressed via this function" table: sum/prod/mean/var/max/l2_norm/count_nonzero/all-any) - device impls: serial + rayon (the rayon auto_impl file is symlinked into device_faer, single source for both cfg contexts) Tests: parity vs `sum`, tuple-accumulator mean, keepdims, Lp-norm fold, non-numeric accumulators, zero-size; doc_draft twin; DeviceFaer runtime test. entry_row_cpu 329, faer lib 134, doc 189, clippy clean (default/rayon/faer). Co-authored-by: Claude Code <noreply@anthropic.com> Co-authored-by: glm-5.3 <service@zhipuai.cn>
Add the array-api cumulative functions (scan along a single axis; output
keeps the input shape, one larger along the scan axis with
`include_initial`):
- `rt::cumulative_sum` / `rt::cumulative_prod` (+ `_f`, `*_with_dtype`(+-f),
`TensorAny` methods) over `CumulativeArgs { axis, include_initial }`;
`axis = None` is only valid for 1-D input (array-api contract; the
`np.cumsum` flatten-on-None divergence is documented as intentional), 0-D
input is rejected; `dtype = None` keeps the input dtype (no
platform-integer widening; `*_with_dtype` is the anti-overflow path,
cast-per-element inside the scan)
- device traits `OpCumSumAPI`/`OpCumProdAPI` (`TOut = T`) and
`OpCumSumDtypeAPI`/`OpCumProdDtypeAPI` (explicit `TOut`)
- scan kernels `cumulative_cpu_serial` / `cumulative_cpu_rayon` in
rstsr-native-impl: per-line sequential fold seeded by the identity, scan
lines parallelized across the remaining axes; output keeps the input's
axis arrangement (K order, grown-axis probe via `Layout::new_unchecked`)
- device impls: serial + rayon (the rayon auto_impl file is symlinked into
device_faer, single source for both cfg contexts)
Tests: NumPy transcriptions (TestCumsum/TestCumprod `test_basic`,
`test_cumulative_include_initial`), custom args-overload / axis-None
contract / transposed-view / broadcast-axis / zero-size / with_dtype
anti-overflow cases; doc_draft twins (byte-identical Display asserts);
DeviceFaer runtime test incl. the parallel-branch path. Tracking rows +
two divergence entries (flatten-on-None, no auto-widening);
api_specification.md paragraph.
entry_row_cpu 341, faer lib 135, doc 194, clippy clean (default/rayon/faer).
Co-authored-by: Claude Code <noreply@anthropic.com>
Co-authored-by: glm-5.3 <service@zhipuai.cn>
DeviceFaer::default() follows the global default order, which is ColMajor under the col_major feature; the arange/into_shape fixture then fills column-major and the expected values shift. Pin RowMajor like the other order-dependent faer tests. Co-authored-by: Claude Code <noreply@anthropic.com> Co-authored-by: glm-5.3 <service@zhipuai.cn>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
New features
rt::reduce_all/rt::reduce_axes/rt::reduce_with_args(+_f): user-provided init/fold/combine/finalize closures over a newOpReduceCustomAPI<T, TS, TO, D>device trait, with generic accumulatorTSand outputTO(e.g. an Lp-norm or a multi-accumulator mean in one pass).rt::cumulative_sum/rt::cumulative_prod(+_f,*_with_dtype::<TOut>, andTensorAnymethods): array-api cumulative scans along a single axis, withCumulativeArgs { axis, include_initial }(include_initialprepends the identity value, growing the scan axis toM + 1).Details
Send + Sync;combinemust be associative — within one output cell elements fold in row-major order, but the combine tree shape is device-defined (parallel chunking on the rayon device). NoTensorAnymethods: expert-level surface only.reduce_all's docstring carries a "common reductions expressed via this function" table (sum/prod/mean/var/max/l2_norm/count_nonzero/all/any as fold spellings).axis = Noneis valid for 1-D input only (n-D raises;np.cumsum's flatten-on-Noneis a documented intentional divergence, matchingnumpy.cumulative_sum), 0-D input is rejected, anddtype = Nonekeeps the input dtype — NumPy/array-api's platform-integer widening is an intentional divergence;*_with_dtypecasts per element inside the scan (no materialized cast copy) for the anti-overflow use case.cumulative_cpu_serial/cumulative_cpu_rayoninrstsr-native-impl: per-line sequential fold, scan lines parallelized across the remaining axes; the output keeps the input's axis arrangement (K order). Rayon auto-impls stay shared withDeviceFaerthrough the existing symlink.api-doc-conventions: the anchor is about failure mode, not return type).test_basic,test_cumulative_include_initial, tracked innumpy_coverage.csvwith source hashes) plus custom args-overload / axis-contract / transposed-view / broadcast-axis / zero-size / with_dtype anti-overflow cases, doc-draft twins, and a DeviceFaer runtime test including the parallel-branch path; two divergence entries innumpy_differences.md. Gates: entry_row_cpu 341, lib (faer) 135, doc 194, clippy clean on default/rayon/faer.PR summarized by