Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support specific mapreduce #301

Open
putianyi889 opened this issue Oct 18, 2023 · 2 comments
Open

Support specific mapreduce #301

putianyi889 opened this issue Oct 18, 2023 · 2 comments

Comments

@putianyi889
Copy link
Contributor

Since sum, maximum, etc. lower to mapreduce, it might be a better idea to support mapreduce(f, op, ::AbstractFill) for op at least in (:max, :min :+, :|, :&) to support maximum, minimum, sum, any and all.

Examples:

Base.mapreduce(f, ::typeof(max), A::Fill) = f(A.value)
Base.mapreduce(f, ::typeof(+), A::Fill) = length(A)*f(A.value)
@jishnub
Copy link
Member

jishnub commented Oct 19, 2023

Currently, these should be handled by

function Base._mapreduce_dim(f, op, ::Base._InitialValue, A::AbstractFill, ::Colon)
fval = f(getindex_value(A))
out = fval
for _ in 2:length(A)
out = op(out, fval)
end
out
end
function Base._mapreduce_dim(f, op, ::Base._InitialValue, A::AbstractFill, dims)
fval = f(getindex_value(A))
red = *(ntuple(d -> d in dims ? size(A,d) : 1, ndims(A))...)
out = fval
for _ in 2:red
out = op(out, fval)
end
Fill(out, ntuple(d -> d in dims ? Base.OneTo(1) : axes(A,d), ndims(A)))
end

but it might be better to specialize mapreduce instead of this internal function.

The loop seems elided already:

julia> f = Fill(3, 100_000);

julia> @btime maximum($f);
  2.944 ns (0 allocations: 0 bytes)

@putianyi889
Copy link
Contributor Author

maximum is achieved by https://github.com/JuliaArrays/FillArrays.jl/blob/master/src/FillArrays.jl#L558-L560

for op in (:maximum, :minimum)
    @eval $op(x::AbstractFill) = getindex_value(x)
end

Anyway, mapreduce currently is not specialized:

julia> C = Fill(1,10000000)
10000000-element Fill{Int64}, with entries equal to 1

julia> @time mapreduce(identity, max, C)
  0.000705 seconds (2 allocations: 64 bytes)
1

julia> C = Fill(1,100000000)
100000000-element Fill{Int64}, with entries equal to 1

julia> @time mapreduce(identity, max, C)
  0.006655 seconds (2 allocations: 64 bytes)
1

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

No branches or pull requests

2 participants