Description
This came up with the following comment in from #61 .
Users will often check for equal sizes in front of a loop, and eachindex will guarantee this as well
for I in eachindex(A,C) # checks for equivalent size endBecause eachindex isn't always appropriate (e.g., when you don't have exact correspondence between axes of the arrays), I think it'd be a good to have something like an eachindexalongaxis:
function mymatmulkernel!(C, A, B) @avx for m in eachindexalongaxis((C,A),(1,1)), n in eachindexalongaxis((C,B),(2,2)), k in eachindexalongaxis((A,B),(2,1)) C[m,n] += A[m,k] * B[k,n] end endwhere it checks sizes. eachindexalongaxis or each_index_along_axis doesn't really roll off > the tongue, and I don't know where such a function should live.
I'd also have to think a little more about how to use it and actually pass the information of > dimension equality (to be combined with density guarantees) to deduce stride-equality. The hacky way would be to just pattern match eachindex and eachindexalongindex in the macro, handling dimension equality through the expression, while handling density info based on types.
I'd like to propose the use of indices
for specifically retrieving the iterator that corresponds to each axis of an array. It would function like axes
but if there's any sort of other data associated with an axis it throws it away so there's a clear relationship between memory layout and and each dimension.
In practice it would look like this:
julia> indices(ones(2,3))
(Base.OneTo(2), Base.OneTo(3))
julia> indices(ones(2,3), 1)
Base.OneTo(2)
julia> indices(ones(2,3), 2)
Base.OneTo(3)
julia> indices(ones(2,3), ones(2,3), 2)
Base.OneTo(3)
julia> indices(ones(2,3), ones(2,2), 2)
ERROR: DimensionMismatch("all inputs to indices must have the same indices, got Base.OneTo(3) and Base.OneTo(2)")
In this case the first several examples are the same as if using axes
, but it helps for cases like those in AxisIndices.jl where each axis can have additional information (e.g., keys) associated with the indices. The last two examples would ensure that the iterator for each collection is the same along the second dimension.