Skip to content

Commit

Permalink
Introduce a function barrier to mapslices (#22229)
Browse files Browse the repository at this point in the history
  • Loading branch information
bramtayl authored and timholy committed Jun 17, 2017
1 parent 88222a7 commit e2ef50f
Showing 1 changed file with 16 additions and 8 deletions.
24 changes: 16 additions & 8 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1829,29 +1829,37 @@ function mapslices(f, A::AbstractArray, dims::AbstractVector)
R[ridx...] = r1

nidx = length(otherdims)
indexes = Iterators.drop(CartesianRange(itershape), 1)
inner_mapslices!(safe_for_reuse, indexes, nidx, idx, otherdims, ridx, Aslice, A, f, R)
end

@noinline function inner_mapslices!(safe_for_reuse, indexes, nidx, idx, otherdims, ridx, Aslice, A, f, R)
if safe_for_reuse
# when f returns an array, R[ridx...] = f(Aslice) line copies elements,
# so we can reuse Aslice
for I in Iterators.drop(CartesianRange(itershape), 1) # skip the first element, we already handled it
for i in 1:nidx
idx[otherdims[i]] = ridx[otherdims[i]] = I.I[i]
end
for I in indexes # skip the first element, we already handled it
replace_tuples!(nidx, idx, ridx, otherdims, I)
_unsafe_getindex!(Aslice, A, idx...)
R[ridx...] = f(Aslice)
end
else
# we can't guarantee safety (#18524), so allocate new storage for each slice
for I in Iterators.drop(CartesianRange(itershape), 1)
for i in 1:nidx
idx[otherdims[i]] = ridx[otherdims[i]] = I.I[i]
end
for I in indexes
replace_tuples!(nidx, idx, ridx, otherdims, I)
R[ridx...] = f(A[idx...])
end
end

return R
end

function replace_tuples!(nidx, idx, ridx, otherdims, I)
for i in 1:nidx
idx[otherdims[i]] = ridx[otherdims[i]] = I.I[i]
end
end


## 1 argument

function map!(f::F, dest::AbstractArray, A::AbstractArray) where F
Expand Down

0 comments on commit e2ef50f

Please sign in to comment.