I have a question about the julia implementation of map
and broadcast
and its relation to eachindex
.
In map!
, as well as in a few other places, I find the pattern for (i,j) in zip(eachindex(dest),eachindex(A))
, i.e.
for (i,j) in zip(eachindex(dest),eachindex(A))
dest[i] = f(A[j])
end
Isn’t it the point of eachindex
to return an iterator that is suitable even for multiple arrays, i.e.
for I in eachindex(dest,A)
dest[I] = f(A[I])
end
With the current implementation, if both dest
and A
have IndexStyle( . ) == IndexCartesian
, two CartesianRange
iterators will have to run, and this necessarily brings along some overhead. In fact, ccopy!
uses the pattern RB, RA = eachindex(B), eachindex(A)
and then checks excplicitly wether RA==RB
in order to run the iterator only once.
Even if one of the two has IndexLinear
, I assume there is little benefit of using linear indices for one if the other is still indexed using cartesian indices. However, if there is some benefit to having linear indices for only one of the two, I would actually like even more if eachindex(dest,A)
returns an iterator that produces two separate indices, which could be the same or could be different, so that the above map!
implementation would become:
for (i,j) in eachindex(dest,A)
dest[i] = f(A[j])
end
I think this has several benefits. If both are sparse, the indices could visit all locations that are zero in either one of the two (or more) arrays.
My use case is to have two arrays which have a strided memory layout, but with strides that are not necessarily increasing (not column major), e.g. resulting from a lazy permutedims
. I have written a plain iterator that generates a cache efficient memory accessing pattern (i.e. by running first over some outer blocks and than over the indices within each block). Ideally, wrapping these strided arrays in a new Array
type, and extending eachindex
in this way, map
etc would work out of the box, but with the current map!
code this is not true.
And my final questions is, how does broadcast
fit in. broadcast
does not seem to be using eachindex
at all, though I am still studying the implementation. Some blog post about the implementation of the current broadcast mechanism might be nice/interesting.