Skip to content

Commit d6ee359

Browse files
authored
Merge branch 'master' into ChrisRackauckas-patch-1
2 parents 37d3b57 + 1fb77f5 commit d6ee359

File tree

14 files changed

+176
-42
lines changed

14 files changed

+176
-42
lines changed

.github/workflows/Downstream.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ jobs:
2222
- {user: SciML, repo: DiffEqBase.jl, group: Core}
2323
- {user: SciML, repo: DiffEqBase.jl, group: Downstream}
2424
- {user: SciML, repo: DiffEqBase.jl, group: Downstream2}
25-
- {user: SciML, repo: DiffEqSensitivity.jl, group: Core}
25+
- {user: SciML, repo: DiffEqSensitivity.jl, group: Core1}
26+
- {user: SciML, repo: DiffEqSensitivity.jl, group: Core2}
27+
- {user: SciML, repo: DiffEqSensitivity.jl, group: Core3}
28+
- {user: SciML, repo: DiffEqSensitivity.jl, group: Core4}
29+
- {user: SciML, repo: DiffEqSensitivity.jl, group: Core5}
2630
- {user: SciML, repo: OrdinaryDiffEq.jl, group: Core}
2731
- {user: SciML, repo: OrdinaryDiffEq.jl, group: Interface}
2832
- {user: SciML, repo: DelayDiffEq.jl, group: Interface}

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ArrayInterface"
22
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
3-
version = "6.0.14"
3+
version = "6.0.16"
44

55
[deps]
66
ArrayInterfaceCore = "30b0a656-2188-435a-8636-2ec0e6a096e2"

lib/ArrayInterfaceCore/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ArrayInterfaceCore"
22
uuid = "30b0a656-2188-435a-8636-2ec0e6a096e2"
3-
version = "0.1.10"
3+
version = "0.1.11"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

lib/ArrayInterfaceCore/src/ArrayInterfaceCore.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,20 @@ ndims_index(@nospecialize T::Type{<:Base.LogicalIndex}) = ndims(fieldtype(T, :ma
548548
ndims_index(T::Type) = 1
549549
ndims_index(@nospecialize(i)) = ndims_index(typeof(i))
550550

551+
"""
552+
ndims_shape(::Type{I}) -> Union{Int,Tuple{Vararg{Int}}}
553+
554+
Returns the number of dimension that are represented in shape of the returned array when
555+
indexing with an instance of `I`.
556+
"""
557+
ndims_shape(T::DataType) = ndims_index(T)
558+
ndims_shape(::Type{Colon}) = 1
559+
ndims_shape(T::Type{<:Base.AbstractCartesianIndex{N}}) where {N} = ntuple(zero, Val{N}())
560+
ndims_shape(@nospecialize T::Type{<:CartesianIndices}) = ntuple(one, Val{ndims(T)}())
561+
ndims_shape(@nospecialize T::Type{<:Number}) = 0
562+
ndims_shape(@nospecialize T::Type{<:AbstractArray}) = ndims(T)
563+
ndims_shape(x) = ndims_shape(typeof(x))
564+
551565
"""
552566
instances_do_not_alias(::Type{T}) -> Bool
553567

lib/ArrayInterfaceCore/test/runtests.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ end
268268
@test @inferred(ArrayInterfaceCore.ndims_index(1)) == 1
269269
end
270270

271+
@testset "ndims_shape" begin
272+
@test @inferred(ArrayInterfaceCore.ndims_shape(1)) === 0
273+
@test @inferred(ArrayInterfaceCore.ndims_shape(:)) === 1
274+
@test @inferred(ArrayInterfaceCore.ndims_shape(CartesianIndex(1, 2))) === (0, 0)
275+
@test @inferred(ArrayInterfaceCore.ndims_shape(CartesianIndices((2,2)))) === (1, 1)
276+
@test @inferred(ArrayInterfaceCore.ndims_shape([1 1])) === 2
277+
end
278+
271279
@testset "indices_do_not_alias" begin
272280
@test ArrayInterfaceCore.instances_do_not_alias(Float64)
273281
@test !ArrayInterfaceCore.instances_do_not_alias(Matrix{Float64})
@@ -285,4 +293,3 @@ end
285293
@test !ArrayInterfaceCore.indices_do_not_alias(typeof(view(fill(rand(4,4),4,4)', 2:3, 1:2)))
286294
@test !ArrayInterfaceCore.indices_do_not_alias(typeof(view(rand(4,4)', StepRangeLen(1,0,5), 1:2)))
287295
end
288-

lib/ArrayInterfaceOffsetArrays/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ArrayInterfaceOffsetArrays"
22
uuid = "015c0d05-e682-4f19-8f0a-679ce4c54826"
3-
version = "0.1.2"
3+
version = "0.1.5"
44

55
[deps]
66
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"

lib/ArrayInterfaceOffsetArrays/src/ArrayInterfaceOffsetArrays.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ end
2727
function ArrayInterface.axes_types(::Type{T}) where {T<:OffsetArrays.OffsetArray}
2828
Static.eachop_tuple(_offset_axis_type, Static.nstatic(Val(ndims(T))), ArrayInterface.parent_type(T))
2929
end
30+
ArrayInterface.strides(A::OffsetArray) = ArrayInterface.strides(parent(A))
3031
function ArrayInterface.known_offsets(::Type{A}) where {A<:OffsetArrays.OffsetArray}
3132
ntuple(identity -> nothing, Val(ndims(A)))
3233
end
@@ -44,5 +45,14 @@ end
4445
d = ArrayInterface.to_dims(A, dim)
4546
OffsetArrays.IdOffsetRange(ArrayInterface.axes(parent(A), d), relative_offsets(A, d))
4647
end
48+
function ArrayInterface.stride_rank(T::Type{<:OffsetArray})
49+
ArrayInterface.stride_rank(ArrayInterface.parent_type(T))
50+
end
51+
function ArrayInterface.dense_dims(T::Type{<:OffsetArray})
52+
ArrayInterface.dense_dims(ArrayInterface.parent_type(T))
53+
end
54+
function ArrayInterface.contiguous_axis(T::Type{<:OffsetArray})
55+
ArrayInterface.contiguous_axis(ArrayInterface.parent_type(T))
56+
end
4757

4858
end # module

lib/ArrayInterfaceOffsetArrays/test/runtests.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ Op = PermutedDimsArray(O,(3,1,2));
1111
@test @inferred(ArrayInterface.offsets(O)) === (4, 8, 11)
1212
@test @inferred(ArrayInterface.offsets(Op)) === (11, 4, 8)
1313

14+
@test @inferred(ArrayInterface.to_indices(O, (:, :, :))) == (4:6, 8:11, 11:15)
15+
@test @inferred(ArrayInterface.to_indices(Op, (:, :, :))) == (11:15, 4:6, 8:11)
16+
1417
@test @inferred(ArrayInterface.offsets((1,2,3))) === (StaticInt(1),)
1518
o = OffsetArray(vec(A), 8);
1619
@test @inferred(ArrayInterface.offset1(o)) === 9
@@ -29,3 +32,5 @@ o = OffsetArray(vec(A), 8);
2932
offset_view = @view OffsetArrays.centered(zeros(eltype(A), 5, 5))[:, begin]; # SubArray of OffsetArray
3033
@test @inferred(ArrayInterface.offsets(offset_view)) == (-2,)
3134

35+
B = OffsetArray(PermutedDimsArray(rand(2,3,4), (2,3,1)));
36+
@test @inferred(ArrayInterface.StrideIndex(B)) === ArrayInterface.StrideIndex{3, (2, 3, 1), 3}((2, 6, static(1)), (1, 1, 1))

src/axes.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,7 @@ struct LazyAxis{N,P} <: AbstractUnitRange{Int}
191191
end
192192

193193
@inline Base.parent(x::LazyAxis{N,P}) where {N,P} = axes(getfield(x, :parent), static(N))
194-
@inline function Base.parent(x::LazyAxis{:,P}) where {P}
195-
return eachindex(IndexLinear(), getfield(x, :parent))
196-
end
194+
@inline Base.parent(x::LazyAxis{:,P}) where {P} = eachindex(IndexLinear(), getfield(x, :parent))
197195

198196
@inline parent_type(::Type{LazyAxis{N,P}}) where {N,P} = axes_types(P, static(N))
199197
# TODO this approach to parent_type(::Type{LazyAxis{:}}) is a bit hacky. Something like
@@ -220,7 +218,7 @@ ArrayInterfaceCore.known_first(::Type{<:LazyAxis{N,P}}) where {N,P} = known_offs
220218
ArrayInterfaceCore.known_first(::Type{<:LazyAxis{:,P}}) where {P} = 1
221219
@inline function Base.first(x::LazyAxis{N})::Int where {N}
222220
if ArrayInterfaceCore.known_first(x) === nothing
223-
return Int(offsets(parent(x), StaticInt(N)))
221+
return Int(offsets(getfield(x, :parent), StaticInt(N)))
224222
else
225223
return Int(known_first(x))
226224
end
@@ -229,7 +227,8 @@ end
229227
ArrayInterfaceCore.known_last(::Type{LazyAxis{N,P}}) where {N,P} = known_last(axes_types(P, static(N)))
230228
ArrayInterfaceCore.known_last(::Type{LazyAxis{:,P}}) where {P} = known_length(P)
231229
Base.last(x::LazyAxis) = _last(known_last(x), x)
232-
_last(::Nothing, x) = last(parent(x))
230+
_last(::Nothing, x::LazyAxis{:}) = lastindex(getfield(x, :parent))
231+
_last(::Nothing, x::LazyAxis{N}) where {N} = lastindex(getfield(x, :parent), N)
233232
_last(N::Int, x) = N
234233

235234
known_length(::Type{<:LazyAxis{:,P}}) where {P} = known_length(P)
@@ -242,7 +241,9 @@ Base.axes1(x::LazyAxis) = x
242241
Base.axes(x::Slice{<:LazyAxis}) = (Base.axes1(x),)
243242
# assuming that lazy loaded params like dynamic length from `size(::Array, dim)` are going
244243
# be used again later with `Slice{LazyAxis}`, we quickly load indices
245-
Base.axes1(x::Slice{<:LazyAxis}) = indices(parent(x.indices))
244+
245+
Base.axes1(x::Slice{LazyAxis{N,A}}) where {N,A} = indices(getfield(x.indices, :parent), StaticInt(N))
246+
Base.axes1(x::Slice{LazyAxis{:,A}}) where {A} = indices(getfield(x.indices, :parent))
246247
Base.to_shape(x::LazyAxis) = Base.length(x)
247248

248249
@propagate_inbounds function Base.getindex(x::LazyAxis, i::CanonicalInt)

src/indexing.jl

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,14 @@ to_index(::MyIndexStyle, axis, arg) = ...
183183
"""
184184
to_index(x, i::Slice) = i
185185
to_index(x, ::Colon) = indices(x)
186+
to_index(::LinearIndices{0,Tuple{}}, ::Colon) = Slice(static(1):static(1))
187+
to_index(::CartesianIndices{0,Tuple{}}, ::Colon) = Slice(static(1):static(1))
186188
# logical indexing
187189
to_index(x, i::AbstractArray{Bool}) = LogicalIndex(i)
188190
to_index(x::LinearIndices, i::AbstractArray{Bool}) = LogicalIndex{Int}(i)
189191
# cartesian indexing
190192
@inline to_index(x, i::CartesianIndices{0}) = i
191-
@inline to_index(x, i::CartesianIndices) = axes(i)
193+
@inline to_index(x, i::CartesianIndices) = getfield(i, :indices)
192194
@inline to_index(x, i::CartesianIndex) = Tuple(i)
193195
@inline to_index(x, i::NDIndex) = Tuple(i)
194196
@inline to_index(x, i::AbstractArray{<:AbstractCartesianIndex}) = i
@@ -251,10 +253,10 @@ indices calling [`to_axis`](@ref).
251253
end
252254
end
253255
# drop this dimension
254-
to_axes(A, a::Tuple, i::Tuple{<:CanonicalInt,Vararg{Any}}) = to_axes(A, tail(a), tail(i))
256+
to_axes(A, a::Tuple, i::Tuple{<:CanonicalInt,Vararg{Any}}) = to_axes(A, _maybe_tail(a), tail(i))
255257
to_axes(A, a::Tuple, i::Tuple{I,Vararg{Any}}) where {I} = _to_axes(StaticInt(ndims_index(I)), A, a, i)
256258
function _to_axes(::StaticInt{1}, A, axs::Tuple, inds::Tuple)
257-
return (to_axis(first(axs), first(inds)), to_axes(A, tail(axs), tail(inds))...)
259+
return (to_axis(_maybe_first(axs), first(inds)), to_axes(A, _maybe_tail(axs), tail(inds))...)
258260
end
259261
@propagate_inbounds function _to_axes(::StaticInt{N}, A, axs::Tuple, inds::Tuple) where {N}
260262
axes_front, axes_tail = Base.IteratorsMD.split(axs, Val(N))
@@ -268,6 +270,11 @@ end
268270
to_axes(A, ::Tuple{Ax,Vararg{Any}}, ::Tuple{}) where {Ax} = ()
269271
to_axes(A, ::Tuple{}, ::Tuple{}) = ()
270272

273+
_maybe_first(::Tuple{}) = static(1):static(1)
274+
_maybe_first(t::Tuple) = first(t)
275+
_maybe_tail(::Tuple{}) = ()
276+
_maybe_tail(t::Tuple) = tail(t)
277+
271278
"""
272279
to_axis(old_axis, index) -> new_axis
273280
@@ -349,7 +356,9 @@ unsafe_getindex(A::Array, i::CanonicalInt) = Base.arrayref(false, A, Int(i))
349356
end
350357

351358
unsafe_getindex(A::LinearIndices, i::CanonicalInt) = Int(i)
352-
unsafe_getindex(A::CartesianIndices, i::CanonicalInt, ii::Vararg{CanonicalInt}) = CartesianIndex(i, ii...)
359+
unsafe_getindex(A::CartesianIndices{N}, ii::Vararg{CanonicalInt,N}) where {N} = CartesianIndex(ii...)
360+
unsafe_getindex(A::CartesianIndices, ii::Vararg{CanonicalInt}) =
361+
unsafe_getindex(A, Base.front(ii)...)
353362
unsafe_getindex(A::CartesianIndices, i::CanonicalInt) = @inbounds(A[i])
354363

355364
unsafe_getindex(A::ReshapedArray, i::CanonicalInt) = @inbounds(parent(A)[i])
@@ -378,18 +387,37 @@ function unsafe_get_collection(A, inds)
378387
end
379388
_ints2range(x::CanonicalInt) = x:x
380389
_ints2range(x::AbstractRange) = x
390+
# apply _ints2range to front N elements
391+
_ints2range_front(::Val{N}, ind, inds...) where {N} =
392+
(_ints2range(ind), _ints2range_front(Val(N - 1), inds...)...)
393+
_ints2range_front(::Val{0}, ind, inds...) = ()
394+
_ints2range_front(::Val{0}) = ()
395+
# get output shape with given indices
396+
_output_shape(::CanonicalInt, inds...) = _output_shape(inds...)
397+
_output_shape(ind::AbstractRange, inds...) = (length(ind), _output_shape(inds...)...)
398+
_output_shape(::CanonicalInt) = ()
399+
_output_shape(x::AbstractRange) = (length(x),)
381400
@inline function unsafe_get_collection(A::CartesianIndices{N}, inds) where {N}
382401
if (Base.length(inds) === 1 && N > 1) || stride_preserving_index(typeof(inds)) === False()
383402
return Base._getindex(IndexStyle(A), A, inds...)
384403
else
385-
return CartesianIndices(to_axes(A, _ints2range.(inds)))
404+
return reshape(
405+
CartesianIndices(_ints2range_front(Val(N), inds...)),
406+
_output_shape(inds...)
407+
)
386408
end
387409
end
410+
_known_first_isone(ind) = known_first(ind) !== nothing && isone(known_first(ind))
388411
@inline function unsafe_get_collection(A::LinearIndices{N}, inds) where {N}
389412
if Base.length(inds) === 1 && isone(_ndims_index(typeof(inds), static(1)))
390413
return @inbounds(eachindex(A)[first(inds)])
391-
elseif stride_preserving_index(typeof(inds)) === True()
392-
return LinearIndices(to_axes(A, _ints2range.(inds)))
414+
elseif stride_preserving_index(typeof(inds)) === True() &&
415+
reduce_tup(&, map(_known_first_isone, inds))
416+
# create a LinearIndices when first(ind) != 1 is imposable
417+
return reshape(
418+
LinearIndices(_ints2range_front(Val(N), inds...)),
419+
_output_shape(inds...)
420+
)
393421
else
394422
return Base._getindex(IndexStyle(A), A, inds...)
395423
end

0 commit comments

Comments
 (0)