Expand description
Reductions and scans over a contiguous slice: sums, products, maximums and minimums, and their running versions. Each compiles inside rustymath once for each item type. A float sum or product may combine the items in any order, which lets its loop vectorize, so its last bits can differ from a sum taken item by item. Beside NaN, a float maximum or minimum gives NaN or the greatest or least of the items that aren’t NaN, and never any other number. Which of the two it gives can depend on the target and the loop. An empty slice gives -∞ or ∞. f16 items compute in f32. Their sum or product is an f32 total. An integer sum or product computes at i64, or at u64 for u64 items. Where it doesn’t fit, it wraps, and reports that it doesn’t fit, as the running versions do.
Structs§
- Alternated
- The right fold by the inverse of a reduction:
-forSum, and÷forScaledProducton floats andProducton complex numbers.x0 - (x1 - (x2 - …))is the sum of the items at even positions less the sum of those at odd positions, andx0 ÷ (x1 ÷ (x2 ÷ …))is the quotient of their products. A total holds that sum or quotient for the items folded so far, with whether their number is odd.steptakes an item at an odd position away, andmergetakes the later run’s total away where the earlier run’s count is odd, each throughInverse. Every fold that takes aReductionfolds it, asalong,fold_into,along_mappedandfold_piecesdo.Totalsstores its folds without the parity. - And
- The fold of integers by bitwise
&, and of Booleans byand. - Logical
- A function of two Booleans, held as its truth table:
Logical(t)givest[r][x]for the running resultrand the next itemx. Its scans run any such function. - Max
maxas aReduction. Its step on floats ismaximumof the item and the total, which a NaN item leaves unchanged. Every fold and scan starts at-∞, and AArch64’s and wasm’s vector folds keep the running result beside a NaN item, as that step does. So a NaN item changes no running result on any target, and a fold of NaN items alone gives-∞.- Maximum
maximumas a function object, which also takes integers and Booleans. The maximum of two Booleans is theiror.- Min
minas aReduction, asMaxismax, starting at∞.- Minimum
minimumas a function object, which also takes integers and Booleans. The minimum of two Booleans is theirand.- Or
- The fold of integers by bitwise
|, and of Booleans byor. - Product
prodas aReduction.- Scaled
- A product of floats held as
m × 2^e, a mantissamand a whole exponentekept apart, so that the product never leaves the normal floats however many items it takes. A step leaves the mantissa where it is while its magnitude stays inside 2^±511 (2^±63 inf32), half the floats’ exponents, so that the product of two mantissas stays normal, and moves the mantissa’s exponent intoeonce it leaves.normalsays whether every step so far was a nonzero normal float.ScaledProductfolds into it. The exponent sums exactly up to 2^53 inf64and 2^24 inf32, which a product that ends inside the floats’ range never nears. - Scaled
Product - The product of floats with its exponent kept apart, as
Scaledholds it, so that a running product can’t overflow or underflow where the whole product doesn’t. A step fails only where an item, or a step’s product, isn’t a nonzero normal float: on zeros, infinities and NaNs, on subnormals, and on items so large or small that a mantissa times them leaves the normal floats. The exact fold takes those.Alternatedfolds÷on floats by it. - Squares
- The sum of the squares of floats’ or complex numbers’ magnitudes as a
Reduction, with each square computed and totalled inf64, where anf32’s square neither overflows nor underflows. It folds the items themselves, with no buffer of squares. - Sum
sumas aReduction.- SumAs
- Sums of
Terms as aReduction, in the typeC, which the caller picks to hold every sum, so no step checks whether it fits: counts of the trues among Booleans, or sums of integers. - Total
- A compiled fold’s total over
itemsitems, as its 8-byte slot holds it: a float as an f64’s bits, an integer extended to 64 bits, and a Boolean as 0 or 1. - Xnor
- The fold of integers by bitwise XNOR,
!(a ^ b), and of Booleans by==: true where an even number of them are false. - Xor
- The fold of integers by bitwise
^, and of Booleans by!=: true where an odd number of them are true.
Enums§
- Direction
- Fold
Route - How a fold reads an array that a mapping lays over storage, as
fold_routechooses. - Part
- A block of an array that
fold_piecesfolds, as its producer hands it over: the block’s items, or the reduction’s total of itsnitems, where the items all lie in one lane along the last axis. - Picks
- The folds that
picksfinds the extremes of: windows of a width that slide along each lane, asslidingfolds them, each whole lane, asalongfolds it, or each lane’s running folds, asscan_alonggives them. - Piece
- Reduce
- A reduction by name: the tag by which a function object’s row names the reduction it folds by (
facts::Facts::fold,facts::Facts::truth), and by which a frontend’s block stages and compiled code fold.with_reduce!gives its type. - Seed
Constants§
- DIRECT
- The widest window that
slidingfolds directly, with one pass over each block of a lane for each of the window’s rows. Wider windows take van Herk-Gil-Werman. - RUN
- The shortest run of consecutive items that
along_mappedfolds where it lies. Each run costs its own call into the fold, so shorter runs fold faster copied a piece at a time. On one thread, folding runs of 128 floats in place took 9% less time than copying them, and runs of 64 took 15% more.
Traits§
- Inverse
- A reduction whose step can be undone, as
Alternatedfolds by it:Sumsubtracts, andScaledProductandProductdivide. An integer difference fits only withini64, a complex quotient only inside the normal range, and a float quotient only where no item, or product of the running mantissa and an item, leaves the normal floats. An alternated fold can then fail where the right fold taken item by item, or its exact result, would fit. - Reduction
- A reduction by
Sum,Product,ScaledProduct,Max,Min,And,Or,Xor,Xnor,SumAs,SquaresorAlternated, implemented inside rustymath once for each item type it takes.slicefolds a whole slice of consecutive items, in any order,mergecombines the folds of two neighbouring runs, andscangives the running folds.along,fold_intoandscan_alongfold along an axis whose items aren’t consecutive.SumandProducttake floats, integers and complex numbers.MaxandMintake floats, integers and Booleans,And,OrandXortake integers and Booleans,Xnortakes signed integers, bytes and Booleans,SumAstakes Booleans and integers,Squarestakes floats and complex numbers,ScaledProducttakes floats,Alternated<Sum>takes floats, integers and complex numbers,Alternated<ScaledProduct>takes floats, andAlternated<Product>takes complex numbers. Anf16reduction computes inf32. A sum or product off16s gives anf32total, for its caller to round once. A total that doesn’t fit its type fails, with its value wrapped to that type. - Tally
- An integer type that sums
Terms, wrapping where a sum doesn’t fit:u8,i16,i32ori64. A caller picks one that holds every sum it needs. A count of fewer than 256 Booleans fits a byte, which takes an eighth of the memory of ani64. - Term
- An item that sums into any
Tally: a Boolean, as 0 or 1, or an integer. - Totals
- A fold’s total as an item of a buffer: an
Elementstores itself, aScaledproduct stores its value, andAlternated’s total stores its fold without the parity of its count.
Functions§
- adjacent_
read ⚠ - Each item of
input, an array of shapedims, combined with the item one row before it along the middle axis, and each lane’s first row withseed’s item in its column, or kept as it is without a seed, as an inverse scan runs it.blockcombines the items of two equal slices, the earlier items first unlessflip, and gives the kind of any combination that failed: a formula’s loop over a block. A failure is an error where the read is checked. - along
- The folds by
Rof the lanes along the middle axis ofdata, an array of shape[outer, len, inner]held row by row: one fold for each of theouter × innerlanes, and whether every one fits. Where a lane along the last axis, or a group ofinnerlanes along another axis, fits in one piece offold_pieces, each lane folds whole. Runs of whole lanes or groups then split across threads asparallel::splitsplits a call. An array with too few rows to give each of this thread’sparallel::threadsa piece of [ROWS] rows splits by columns instead, where a row holds more than one unit: a run of lanes whose part of the array holds at least [PIECE] items. Each thread then reads part of every row. At 4 threads on an M5 Max,+⌿took 41% less time on 8×524288, which had folded on one thread, and 17% less on 64×65536 than split by rows. With more rows, a split by columns took more time than a split by rows: 33% more on 256×16384 and 66% more on 4000×9000. Otherwise the array folds asfold_piecesfolds it. - along_
mapped - Folds each lane of the array described by
mappingwithout gathering it. Returns totals, whether every integer total fits, and an optional mapping from those totals to result order. - boolean_
scan_ read - A Boolean-result scan with its raw seed and chunk carries read at the input’s numeric type.
- bounded_
scan - A sum scan of integers or Booleans, or with
negatea left scan by-of them, whose caller asks for totals inoutput’s dtype,i16ori32, wide enough for every stored item that the scan reads, whatever width the kernel computes at. The caller asks only where its bound on every running total fits that type. Each lane totals in it throughSumAs, wrapping.Nonefor any other request. - comparison_
scan - Appends a Boolean-valued scan of long consecutive lanes, keeping an unseeded lane’s first item as it is. Comparisons at carries 0 and 1 make independent two-state maps, whose packed words compose through
mapped. A failed speculative comparison leavesoutunchanged and declines, so the ordered runner checks only steps the scan actually takes. - extremes
- The least and the greatest item of
x, in one pass of comparisons and selects. For floats,minandmaxtake less time together, because their folds run AArch64’sfminandfmax. - fold_
into - Folds
block, the items from positionstarton of an array of shape[outer, len, inner]held row by row, intototals, the folds byRof the array’s lanes along its middle axis so far, which start atR::unit(). Gives whether every fold still fits. Along the last axis, a lane’s items are consecutive. Whole lanes fold asfold_rowsfolds them, and the pieces of a lane that a block boundary splits fold bysliceand join bymerge. Along any other axis, runs of whole rows fold as [step_rows] folds them, and a row that a block boundary splits steps item by item. - fold_
pieces - Folds an array of shape
[outer, len, inner]byRintototals, the folds of its lanes along the middle axis, and gives whether every fold fits.run(range, fold)produces the array’s items inrangein order, and hands each block of them tofoldwith the position of its first item, as aPart: the items, or their total. The array folds in one piece for each of this thread’sparallel::threads, each of at least [piece_size] items. On one thread it folds as one piece. A lane that one piece holds folds asfold_intofolds it, and a block’s total joins it as [fold_total] joins it. A lane that crosses pieces folds its part in each piece, and those folds merge. - fold_
route - The route of a fold along
axes, one axis or two, of the array ofshapethatmappinglays over storage. It slides wheresourcegives the shape of what the mapping reads and the array is windows alongaxes. Otherwise it reads through the mapping, unless the array keeps the items it gathers (keeps) andrereads_cheaplyis false, where it folds the kept items. A fold of every item takes no axes, never slides, and folds a block of storage from the array’s items (ArrayView::fold_itemsreads it in place). Python’s folds of views and basedpl’s folds of pending copies both choose here. - lanes_
scan - Appends the running results along each lane of
lenconsecutive items indatatoout, and gives whether every one fits:firstgives each lane’s first result, andstepeach later one from the one before. Lanes shorter than [SHORT_LANE] run [LANES] side by side (rows_scan). - max
- The greatest item of
x. - maximum
- The greater of x and y, as
maxgives the greatest item. Beside NaN, or where they’re equal, it gives y. A fold that passes its running result as y keeps it beside a NaN item. NumPy calls itmaximum. - min
- The least item of
x. - minimum
- The lesser of x and y, as
maximumgives the greater. NumPy calls itminimum. - negated_
scan - A left scan by
-, run as+’s scan (scan_along) of negated items (negated_cells). Floats and complex numbers, 16-bit floats in 32 bits as the ordered scan computes them, and integers and Booleans whose caller asks for totals ini16ori32(bounded_scan).Ok(false), withoutputunchanged, for other dtypes. - ordered_
scan ⚠ - Appends the ordered left scan of each lane of
[outer, len, inner]indatatoout, in the same layout: along the last axis bylane, one call for every lane, stepping fromseed’s item; along any other axis byblock, one call for each row, stepping the row before it, orseed’s row, by the row’s items. Without a seed, a lane’s first item or row is kept as it is. Gives the kind of the first step that failed. - picks
- The row of the first item that gives each fold by
Ralong the middle axis ofdata, an array of shape[outer, len, inner], for a reduction that picks one of its items, asMaxandMindo.ofchooses the folds, and the result lays out as their results do. Each row counts from the start of its lane. A fold whose items all leave it atR::unit(), as NaN items do for a float maximum, gives its first row. - prod
- The product of
x, 1 for an empty slice, and whether it fits. An integer product that doesn’t fit wraps. - rereads_
cheaply - Whether
along_mappedreads the array ofshapethatmappinglays over storage where it lies, with no copy: a block of storage, asMapping::blockfinds, or runs of at leastRUNitems. Elsewhere each read copies the array’s items a piece at a time, at about a gather’s cost, so a caller that will read the array again keeps a compact copy instead, as basedpl does for a pending copy that a name holds and the Python API does for a view that keeps what it gathers. - reverse_
rows - running
- How many independent running values a loop keeps, each of
sizebytes: a fold’s partial results, or a block of items under Horner’s rule. 32 measured faster on the Mac than 8 or 16 for items of up to 8 bytes. A 16-byte item, such as aComplex<f64>, keeps 16, because 32 fill every vector register, and a complex sum then took 1.7 times as long. In wasm, LLVM leaves 32 values of 8 bytes, or 16 of 16 bytes, in linear memory, where each step loads and stores them. It keeps half as many in locals. - scan_
along - Appends the running folds by
Ralong the middle axis ofdata, an array of shape[outer, len, inner]held row by row, toout, in the same layout. Whereseedis given, each lane’s first fold combinesseed’s item for its column, or its only item. Gives whether every fold fits. Lanes of consecutive items scan byReduction::short_laneswhere the reduction takes them, else byscan. Along any other axis, each row’s folds step the row before’s bychecked. - scan_
read - seed_
row - Cell
cell’sinnerseed items fromread: its one item in every column where it holds one, else the cell’s own row. - sliding
- The folds by
Rof each window ofwidthneighbouring rows along the middle axis ofdata, an array of shape[outer, len, inner]held row by row. The result has shape[outer, len - width + 1, inner], with whether every fold fits. Each fold combines its window’s items in order, except that a window as long as a lane of single items folds asalongfolds the lane. A window of at mostDIRECTrows folds directly. A wider one takes van Herk-Gil-Werman’s method: each lane splits into blocks ofwidthrows, and each window is the fold of one block’s suffix and the next block’s prefix, so an item costs the same whatever the width. - sliding_
2d - The folds by
Rof each window ofw1rows along axis 1 andw2rows along axis 3 ofdata, an array of shape[outer, len1, mid, len2, inner]held row by row. Windows start everye1positions along axis 1 and everye2along axis 3: every position for windows that slide, or every window’s width for windows that tile the axis, as pooling’s do. The result has shape[outer, c1, mid, c2, inner], wherec1andc2count the windows along each axis, with whether every fold fits. Each band ofw1rows folds into a buffer that stays in cache, and the windows along axis 3 fold from that buffer, sodatais read once. A window’s items fold along axis 1 and then along axis 3, which suits reductions that fold in any order.Nonefor a window wider thanDIRECTrows. - sum
- The sum of
x, 0 for an empty slice, and whether it fits. An integer sum that doesn’t fit wraps. - view_
picks picksof the items ofxat their own type, byMax, or byMinwheremaxis false.Nonefor complex numbers and characters, which have no order.