Skip to content

Reduce with operators not known to commute in element order - #822

Open
maleadt wants to merge 1 commit into
mainfrom
tb/noncommutative
Open

maleadt wants to merge 1 commit into
mainfrom
tb/noncommutative

Conversation

@maleadt

@maleadt maleadt commented Oct 19, 2026

Copy link
Copy Markdown
Member

Fixes JuliaGPU/AcceleratedKernels.jl#164 (was JuliaGPU/CUDA.jl#1058) for GPUArrays users. Needs JuliaGPU/AcceleratedKernels.jl#165 and an AcceleratedKernels release (compat bumped to 0.5.8), hence draft.

Base's reductions keep elements in order, so mapreduce with a non-commutative operator must give the in-order result. AcceleratedKernels' default kernels assume commutativity. This passes commutative=false unless the operator is known to commute on the types involved:

  • +, *, add_sum and mul_prod on Base's number types;
  • max/min on reals;
  • &, | and xor on integers and Bool;
  • _extrema_rf;
  • this package's own reducers (findfirst/findlast on CartesianIndex, findmin/findmax, ==).

The package's own reducers become named functions so that they can be marked. istriu/istril now reduce with &.

The check looks at types as well as operators, because * on matrices or quaternions doesn't commute. Everything else takes the ordered kernels, which cost roughly 1.0x to 1.2x on large inputs.

A new reductions/order testsuite entry covers the issue's findmax-like example with ties, "last nonzero" and tuple matrix products, whole-array and along dims. 11 of its 19 tests fail with the old forwarding. It passes on CUDA and JLArrays.

AcceleratedKernels' reductions combine elements in any order, so a
non-commutative operator, such as one keeping the first of equal values,
gave wrong results on large arrays (JuliaGPU/AcceleratedKernels.jl#164,
was JuliaGPU/CUDA.jl#1058). Base keeps the elements in order, so pass
`commutative=false` to AcceleratedKernels (0.5.8) unless the operator is
known to commute on the types involved: Base's arithmetic, bitwise and
min/max operators on Base's number types, and this package's own
reducers, which become named so that they can be marked.
@maleadt
maleadt marked this pull request as ready for review October 23, 2026 13:45

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mapreduce still assumes commutative op

1 participant