Skip to content

Commit 6acba95

Browse files
committed
Merge branch 'master' into SimdCartesianPartition and performance optimize
1. Use `ReshapedArray` rather than `reshape` to make high-dimension cases with small size faster.
1 parent e2a373b commit 6acba95

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

base/multidimensional.jl

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -591,16 +591,14 @@ module IteratorsMD
591591
CartesianIndices(intersect.(a.indices, b.indices))
592592

593593
# Views of reshaped CartesianIndices are used for partitions — ensure these are fast
594-
const CartesianPartition{T<:CartesianIndex, P<:CartesianIndices, R<:ReshapedArray{T,1,P}} = SubArray{T,1,R,<:Tuple{AbstractUnitRange{Int}},false}
595-
eltype(::Type{PartitionIterator{T}}) where {T<:ReshapedArrayLF} = SubArray{eltype(T), 1, T, Tuple{UnitRange{Int}}, true}
596-
eltype(::Type{PartitionIterator{T}}) where {T<:ReshapedArray} = SubArray{eltype(T), 1, T, Tuple{UnitRange{Int}}, false}
594+
const CartesianPartition{T<:CartesianIndex, P<:CartesianIndices, R<:ReshapedArray{T,1,P}} = SubArray{T,1,R,<:Tuple{AbstractUnitRange{Int}}}
595+
eltype(::Type{PartitionIterator{T}}) where {T<:ReshapedArray} = SubArray{eltype(T), 1, T, Tuple{UnitRange{Int}}, IndexStyle(T) == IndexLinear()}
597596
Iterators.IteratorEltype(::Type{<:PartitionIterator{T}}) where {T<:ReshapedArray} = Iterators.IteratorEltype(T)
598597

599598
eltype(::Type{PartitionIterator{T}}) where {T<:OneTo} = UnitRange{eltype(T)}
600599
eltype(::Type{PartitionIterator{T}}) where {T<:Union{UnitRange, StepRange, StepRangeLen, LinRange}} = T
601600
Iterators.IteratorEltype(::Type{<:PartitionIterator{T}}) where {T<:Union{OneTo, UnitRange, StepRange, StepRangeLen, LinRange}} = Iterators.IteratorEltype(T)
602601

603-
604602
@inline function iterate(iter::CartesianPartition)
605603
isempty(iter) && return nothing
606604
f = first(iter)
@@ -612,19 +610,26 @@ module IteratorsMD
612610
return I, (I, n+1)
613611
end
614612

615-
@inline function _splitlinear(piter::CartesianIndices, oiter::CartesianIndices, i::Int)
616-
ci = Base._to_subscript_indices(piter, i)
617-
ci[1], Base._to_linear_index(oiter, tail(ci)...)
618-
end
619613
@inline function simd_outer_range(iter::CartesianPartition)
620-
# In general, the CartesianPartition might start and stop in the middle of the outer
614+
# CartesianPartition might start and stop in the middle of the outer
621615
# dimensions, thus the outer range itself is a CartesianPartition.
622616
piter = iter.parent.parent
623617
ax1, oiter = split(piter, Val(1))
624618
vindʷ = only(iter.indices)
619+
@inline function _splitlinear(piter::CartesianIndices, oiter::CartesianIndices, i::Int)
620+
ci = Base._to_subscript_indices(piter, i)
621+
ci[1], Base._to_linear_index(oiter, tail(ci)...)
622+
end
625623
fl, vl = _splitlinear(piter, oiter, first(vindʷ))
626624
fr, vr = _splitlinear(piter, oiter, last(vindʷ))
627-
outer = @inbounds view(oiter, vl:vr)
625+
@inline function _view(oiter::CartesianIndices, ind::AbstractUnitRange)
626+
# we dont have #40344 for 1.6 and 1.7, force this return a CartesianIndices{1}
627+
ndims(oiter) == 1 && return @inbounds CartesianIndices((oiter.indices[1][ind],))
628+
# there's no need to make outer range fast-indexable
629+
oiter′ = ReshapedArray(oiter, (length(oiter),), ())
630+
@inbounds view(oiter′, ind)
631+
end
632+
outer = _view(oiter, vl:vr)
628633
# Use Generator to make inner loop branchless
629634
@inline function genouter(i::Int, I::CartesianIndex)
630635
l = i == 1 ? fl : firstindex(ax1)

0 commit comments

Comments
 (0)