Skip to content

add dims kwarg #247

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

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions src/mapreduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ end

# Implementation for special cases and if fallback breaks in future julia versions

for fname in [:sum, :prod, :all, :any, :minimum, :maximum]
@eval Base.$fname(v::AbstractDiskArray) = Base.$fname(identity, v::AbstractDiskArray)
@eval function Base.$fname(f::Function, v::AbstractDiskArray)
for (fname, _fname) in ((:sum, :_sum), (:prod, :_prod),
(:all, :_all), (:any, :_any),
(:minimum, :_minimum), (:maximum, :_maximum))
@eval Base.$fname(v::AbstractDiskArray; dims=:) = Base.$_fname(v, dims)
@eval Base.$fname(f::Function, v::AbstractDiskArray; dims=:) = Base.$_fname(f, v, dims)
@eval Base.$_fname(v::AbstractDiskArray, ::Colon) = Base.$_fname(identity, v, :)
@eval function Base.$_fname(f::Function, v::AbstractDiskArray, ::Colon)
$fname(eachchunk(v)) do chunk
$fname(f, v[chunk...])
end
Expand All @@ -66,3 +70,21 @@ function Base.count(f, v::AbstractDiskArray)
count(f, v[chunk...])
end
end

for (_fname, init, acum) in ((:_sum, :zero, :+), (:_prod, :one, :*),
(:_all, _->:true, :&), (:_any, _->:false, :|),
(:_maximum, :typemin, :max), (:_minimum, :typemax, :min))
@eval Base.$_fname(a::AbstractDiskArray, dims) = Base.$_fname(identity, a, dims)
@eval function Base.$_fname(f::Function, a::AbstractDiskArray, dims)
_dims = typeof(dims)<:Tuple ? [dims...] : typeof(dims)<:Number ? [dims] : dims
out_dims = [size(a)...]
out_dims[_dims] .= 1
Copy link
Collaborator

@rafaqz rafaqz Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out_dims = ntuple(Val{N}()) do i
    i in _dims ? 1 : size(a)[i]
end 

Something like this should be the same but type stable for splats. N needs a where N on the array ndims type parameter.

(actually the one below is more important as its in the loop, but theyre kind of the same)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a commit with this code. the out array is still type unstable. not sure how to fix that given it's eltype is calculated.

out = fill($init(eltype(a)), out_dims...)
for c in eachchunk(a)
out_c = [c...]
out_c[_dims] .= Ref(1:1)
out[out_c...] .= $acum.(out[out_c...], Base.$_fname(f, a[c...], dims))
Copy link
Collaborator

@rafaqz rafaqz Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments for each line would help for understanding the logic.

Also splatting a vector isn't type stable, maybe better to convert back to tuple and pass it through a function barrier before the loop? We actually know the length too so you could use ntuple to make it.

end
return out
end
end
21 changes: 21 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1059,3 +1059,24 @@ end
end
@test count(a) + count(!, a) == length(a)
end

@testset "dims kwarg" begin
a = ChunkedDiskArray(reshape(1:3*4*5, 3,4,5); chunksize=(2,3,4))
for fname in (:sum, :prod, :minimum, :maximum)
@test @eval $fname(a) == $fname(Array(a))
@test @eval $fname(a, dims=1) == $fname(Array(a), dims=1)
@test @eval $fname(a, dims=2) == $fname(Array(a), dims=2)
@test @eval $fname(a, dims=(1,2)) == $fname(Array(a), dims=(1,2))
@eval out = @capture_out @trace $fname($a) DiskArrays
@test occursin("DiskGenerator", out) == false
end
b = ChunkedDiskArray(reshape(1:3*4*5 .> 10, 3,4,5); chunksize=(2,3,4))
for fname in (:all, :any)
@test @eval $fname(b) == $fname(Array(b))
@test @eval $fname(b, dims=1) == $fname(Array(b), dims=1)
@test @eval $fname(b, dims=2) == $fname(Array(b), dims=2)
@test @eval $fname(b, dims=(1,2)) == $fname(Array(b), dims=(1,2))
@eval out = @capture_out @trace $fname($b) DiskArrays
@test occursin("DiskGenerator", out) == false
end
end
Loading