Skip to content
Merged
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
7 changes: 5 additions & 2 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3462,8 +3462,11 @@ function ith_all(i, as)
end

function map_n!(f::F, dest::AbstractArray, As) where F
idxs1 = LinearIndices(As[1])
@boundscheck LinearIndices(dest) == idxs1 && all(x -> LinearIndices(x) == idxs1, As)
idxs1 = eachindex(LinearIndices(As[1]))
@boundscheck begin
idxs1 = intersect(map(eachindex ∘ LinearIndices, As)...)
checkbounds(dest, idxs1)
end
for i = idxs1
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
idxs1 = eachindex(LinearIndices(As[1]))
@boundscheck begin
idxs1 = intersect(map(eachindex LinearIndices, As)...)
checkbounds(dest, idxs1)
end
for i = idxs1
idxs = mapreduce(LinearIndices, intersect, As)
checkbounds(dest, inds)
for i = idxs
  • I don't see why we need eachindex is here
  • We should only include bounds-check elision if benchmarks reveal that it makes a difference. In this case, we would also need to add @propagate_inbounds to map! to make it take effect.
  • I think that mapreduce(LinearIndices, intersect, As) is more elegant than intersect(map(LinearIndices, As)...), unless there is some performance reason to use the latter.
  • If always compute the intersection of indices then inds is a better name than inds1

Copy link
Member Author

@adienes adienes Nov 27, 2024

Choose a reason for hiding this comment

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

thank you for the comments!

the eachindex I added for the following reason

julia> mapreduce(LinearIndices, intersect, [A, B])
3-element Vector{Int64}:
 1
 2
 3

julia> mapreduce(eachindex ∘ LinearIndices, intersect, [A, B])
Base.OneTo(3)

so I figured that if we can hit fast-path intersection for ranges rather than collecting the indices we should. Another solution might be to add a fast intersect(::LinearIndices, ::LinearIndices) ?

the mapreduce formulation indeed looks nicer to me as well.

  • If always compute the intersection of indices then inds is a better name than inds1

Agreed! but I suppose we should decide if in the first place @inbounds should allow skipping the check and iterate through the indices of the first argument? I think this is a decision on semantics rather than implementation that I am not empowered to make. the docs should probably be updated if this is intended

Copy link
Member

Choose a reason for hiding this comment

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

the eachindex I added for the following reason

Good reason.

I suppose we should decide if in the first place @inbounds should allow skipping the check and iterate through the indices of the first argument?

@inbounds should never expose documented semantics that are otherwise not present. This is because you can't count on bounds checks being removed. For exmaple, Julia could be run with -check-bound=yes or the boundschecking might not be inlined into the callsite where @inbounds is present. In either case, the bounds checks will remain. Consequently I think the answer to that question is no: @inbounds should not change the semantics other than to skip bounds checks.

@inbounds I = ith_all(i, As)
val = f(I...)
Expand Down
3 changes: 3 additions & 0 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,9 @@ include("generic_map_tests.jl")
generic_map_tests(map, map!)
@test_throws ArgumentError map!(-, [1])

# Issue #30624
@test map!(+, [0,0,0], [1,2], [10,20,30], [100]) == [111,0,0]
Copy link
Member

Choose a reason for hiding this comment

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

Would you also add a test for #36235 (comment), please?


test_UInt_indexing(TestAbstractArray)
test_13315(TestAbstractArray)
test_checksquare()
Expand Down