From b9e2e37c3cfc785a7883ba2b39682359134e4e17 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Mon, 5 Feb 2018 11:15:48 -0600 Subject: [PATCH] WIP --- base/abstractarray.jl | 27 +++++++++++++++------------ base/abstractarraymath.jl | 8 ++++---- base/array.jl | 11 ----------- base/bitset.jl | 8 ++++++-- base/deprecated.jl | 1 - base/multidimensional.jl | 13 ++++++------- test/arrayops.jl | 29 ++++++++++++++--------------- 7 files changed, 45 insertions(+), 52 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 5126b1347af1b..eea2011ce41cd 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1060,7 +1060,7 @@ get(A::AbstractArray, I::Dims, default) = checkbounds(Bool, A, I...) ? A[I...] : function get!(X::AbstractVector{T}, A::AbstractVector, I::Union{AbstractRange,AbstractVector{Int}}, default::T) where T # 1d is not linear indexing ind = findall(occursin(indices1(A)), I) - X[ind] = A[I[ind]] + X[ind] .= A[I[ind]] Xind = indices1(X) X[first(Xind):first(ind)-1] = default X[last(ind)+1:last(Xind)] = default @@ -1069,7 +1069,7 @@ end function get!(X::AbstractArray{T}, A::AbstractArray, I::Union{AbstractRange,AbstractVector{Int}}, default::T) where T # Linear indexing ind = findall(occursin(1:length(A)), I) - X[ind] = A[I[ind]] + X[ind] .= A[I[ind]] X[1:first(ind)-1] = default X[last(ind)+1:length(X)] = default X @@ -1080,7 +1080,7 @@ get(A::AbstractArray, I::AbstractRange, default) = get!(similar(A, typeof(defaul function get!(X::AbstractArray{T}, A::AbstractArray, I::RangeVecIntList, default::T) where T fill!(X, default) dst, src = indcopy(size(A), I) - X[dst...] = A[src...] + X[dst...] .= A[src...] X end @@ -1468,7 +1468,7 @@ function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMat.. if c-1+szj > nc throw(ArgumentError("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))")) end - out[r:r-1+szi, c:c-1+szj] = Aj + out[r:r-1+szi, c:c-1+szj] .= Aj c += szj end if c != nc+1 @@ -1808,9 +1808,9 @@ function mapslices(f, A::AbstractArray, dims::AbstractVector) end nextra = max(0, length(dims)-ndims(r1)) if eltype(Rsize) == Int - Rsize[dims] = [size(r1)..., ntuple(d->1, nextra)...] + Rsize[dims] .= [size(r1)..., ntuple(d->1, nextra)...] else - Rsize[dims] = [axes(r1)..., ntuple(d->OneTo(1), nextra)...] + Rsize[dims] .= [axes(r1)..., ntuple(d->OneTo(1), nextra)...] end R = similar(r1, tuple(Rsize...,)) @@ -1818,11 +1818,11 @@ function mapslices(f, A::AbstractArray, dims::AbstractVector) for d in dims ridx[d] = axes(R,d) end - - R[ridx...] = r1 + + concatenate_setindex!(R, r1, ridx...) nidx = length(otherdims) - indices = Iterators.drop(CartesianIndices(itershape), 1) + indices = Iterators.drop(CartesianIndices(itershape), 1) # skip the first element, we already handled it inner_mapslices!(safe_for_reuse, indices, nidx, idx, otherdims, ridx, Aslice, A, f, R) end @@ -1830,16 +1830,16 @@ end if safe_for_reuse # when f returns an array, R[ridx...] = f(Aslice) line copies elements, # so we can reuse Aslice - for I in indices # skip the first element, we already handled it + for I in indices replace_tuples!(nidx, idx, ridx, otherdims, I) _unsafe_getindex!(Aslice, A, idx...) - R[ridx...] = f(Aslice) + concatenate_setindex!(R, f(Aslice), ridx...) end else # we can't guarantee safety (#18524), so allocate new storage for each slice for I in indices replace_tuples!(nidx, idx, ridx, otherdims, I) - R[ridx...] = f(A[idx...]) + concatenate_setindex!(R, f(A[idx...]), ridx...) end end @@ -1852,6 +1852,9 @@ function replace_tuples!(nidx, idx, ridx, otherdims, I) end end +concatenate_setindex!(R, v, I...) = R[I...] = v +concatenate_setindex!(R, X::AbstractArray, I...) = R[I...] .= X + ## 1 argument diff --git a/base/abstractarraymath.jl b/base/abstractarraymath.jl index d5343c922d4e3..c871fcff5454d 100644 --- a/base/abstractarraymath.jl +++ b/base/abstractarraymath.jl @@ -275,7 +275,7 @@ function repmat(a::AbstractVecOrMat, m::Int, n::Int=1) R = d:d+p-1 for i=1:m c = (i-1)*o+1 - b[c:c+o-1, R] = a + b[c:c+o-1, R] .= a end end return b @@ -286,7 +286,7 @@ function repmat(a::AbstractVector, m::Int) b = similar(a, o*m) for i=1:m c = (i-1)*o+1 - b[c:c+o-1] = a + b[c:c+o-1] .= a end return b end @@ -371,7 +371,7 @@ cat_fill!(R, X::AbstractArray, inds) = fill!(view(R, inds...), X) # fill the first inner block if all(x -> x == 1, inner) - R[axes(A)...] = A + R[axes(A)...] .= A else inner_indices = [1:n for n in inner] for c in CartesianIndices(axes(A)) @@ -393,7 +393,7 @@ cat_fill!(R, X::AbstractArray, inds) = fill!(view(R, inds...), X) B = view(R, src_indices...) for j in 2:outer[i] dest_indices[i] = dest_indices[i] .+ inner_shape[i] - R[dest_indices...] = B + R[dest_indices...] .= B end src_indices[i] = dest_indices[i] = 1:shape[i] end diff --git a/base/array.jl b/base/array.jl index e1c3e3b124fb6..076c5aba78e1f 100644 --- a/base/array.jl +++ b/base/array.jl @@ -691,16 +691,6 @@ function setindex! end @eval setindex!(A::Array{T}, x, i1::Int, i2::Int, I::Int...) where {T} = (@_inline_meta; arrayset($(Expr(:boundscheck)), A, convert(T,x)::T, i1, i2, I...)) -# These are redundant with the abstract fallbacks but needed for bootstrap -function setindex!(A::Array, x, I::AbstractVector{Int}) - @_propagate_inbounds_meta - A === I && (I = copy(I)) - for i in I - A[i] = x - end - return A -end - # Faster contiguous setindex! with copyto! TODO: Transform to Broadcasts impls # function setindex!(A::Array{T}, X::Array{T}, I::UnitRange{Int}) where T # @_inline_meta @@ -721,7 +711,6 @@ end # end # return A # end - setindex!(A::Array, x::Number, ::Colon) = fill!(A, x) setindex!(A::Array{T, N}, x::Number, ::Vararg{Colon, N}) where {T, N} = fill!(A, x) diff --git a/base/bitset.jl b/base/bitset.jl index 84e9ecaff5523..c5a6e08636265 100644 --- a/base/bitset.jl +++ b/base/bitset.jl @@ -111,12 +111,16 @@ end @inline function _growend0!(b::Bits, nchunks::Int) len = length(b) _growend!(b, nchunks) - @inbounds b[len+1:end] = CHK0 # resize! gives dirty memory + for i in len+1:length(b) + @inbounds b[i] = CHK0 # resize! gives dirty memory + end end @inline function _growbeg0!(b::Bits, nchunks::Int) _growbeg!(b, nchunks) - @inbounds b[1:nchunks] = CHK0 + for i in 1:nchunks + @inbounds b[i] = CHK0 + end end function _matched_map!(f, s1::BitSet, s2::BitSet) diff --git a/base/deprecated.jl b/base/deprecated.jl index 57cc8e9564328..34132cfbc097b 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -586,7 +586,6 @@ end _unsafe_setindex!(::IndexStyle, A::AbstractArray, X::AbstractArray, I::Union{Real,AbstractArray}...) = deprecate_nonscalar_indexed_assignment!(A, X, I...) setindex!(B::BitArray, X::StridedArray, J0::Union{Colon,UnitRange{Int}}) = deprecate_nonscalar_indexed_assignment!(B, X, J0) setindex!(B::BitArray, X::StridedArray, I0::Union{Colon,UnitRange{Int}}, I::Union{Int,UnitRange{Int},Colon}...) = deprecate_nonscalar_indexed_assignment!(B, X, I0, I) -setindex!(A::Array, X::AbstractArray, I::AbstractVector{Int}) = deprecate_nonscalar_indexed_assignment!(A, X, I) # issue #22791 @deprecate select partialsort diff --git a/base/multidimensional.jl b/base/multidimensional.jl index e52f65bae6575..0027a8755fe09 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1452,8 +1452,7 @@ function copy_to_bitarray_chunks!(Bc::Vector{UInt64}, pos_d::Int, C::StridedArra end end -# These had been specializations on setindex! previously -# contiguous multidimensional indexing: if the first dimension is a range, +# contiguous multidimensional B[] .= indexing: if the first index is a range, # we can get some performance from using copy_chunks! function broadcast!(::typeof(identity), B::BitArray, X::StridedArray) size(B) == size(X) || return Broadcast._broadcast!(identity, B, X) @@ -1463,7 +1462,7 @@ end function broadcast!(::typeof(identity), V::SubArray{<:Any,<:Any,<:BitArray,<:Tuple{AbstractUnitRange}}, X::StridedArray) size(V) == size(X) || return Broadcast._broadcast!(identity, V, X) B = V.parent - I0 = V.indexes[1] + I0 = V.indices[1] l0 = length(I0) l0 == 0 && return B f0 = indexoffset(I0)+1 @@ -1471,13 +1470,13 @@ function broadcast!(::typeof(identity), V::SubArray{<:Any,<:Any,<:BitArray,<:Tup return B end @generated function broadcast!(::typeof(identity), - V::SubArray{<:Any,<:Any,<:BitArray,<:Tuple{AbstractUnitRange,Vararg{Union{AbstractUnitRange,Int}}}}, X::StridedArray) - N = length(I) + V::SubArray{<:Any,<:Any,<:BitArray,VI}, X::StridedArray) where VI<:Tuple{AbstractUnitRange,Vararg{Union{AbstractUnitRange,Int}}} + N = length(VI.parameters)-1 quote size(V) == size(X) || return Broadcast._broadcast!(identity, V, X) B = V.parent - I0 = V.indexes[1] - I = tail(V.indexes) + I0 = V.indices[1] + I = tail(V.indices) idxlens = @ncall $N index_lengths I0 d->I[d] isempty(X) && return B f0 = indexoffset(I0)+1 diff --git a/test/arrayops.jl b/test/arrayops.jl index cba3c620c6902..31da9fe21585b 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -335,7 +335,7 @@ end @test X[7:11] == [1:5;] X = get(A, (2:4, 9:-2:-13), 0) Xv = zeros(Int, 3, 12) - Xv[1:2, 2:5] = A[2:3, 7:-2:1] + Xv[1:2, 2:5] .= A[2:3, 7:-2:1] @test X == Xv X2 = get(A, Vector{Int}[[2:4;], [9:-2:-13;]], 0) @test X == X2 @@ -623,7 +623,7 @@ Base.hash(::HashCollision, h::UInt) = h # All rows and columns unique let A, B, C, D A = fill(1., 10, 10) - A[diagind(A)] = shuffle!([1:10;]) + A[diagind(A)] .= shuffle!([1:10;]) @test unique(A, 1) == A @test unique(A, 2) == A @@ -840,10 +840,10 @@ end T = reshape([1:4; 1:4; 5:8; 5:8], 2, 2, 4) @test R == T A = Array{Int}(uninitialized, 2, 2, 2) - A[:, :, 1] = [1 2; - 3 4] - A[:, :, 2] = [5 6; - 7 8] + A[:, :, 1] .= [1 2; + 3 4] + A[:, :, 2] .= [5 6; + 7 8] R = repeat(A, inner = (2, 2, 2), outer = (2, 2, 2)) @test R[1, 1, 1] == 1 @test R[2, 2, 2] == 1 @@ -908,9 +908,9 @@ end a = [1:5;] a[[true,false,true,false,true]] = 6 @test a == [6,2,6,4,6] - a[[true,false,true,false,true]] = [7,8,9] + a[[true,false,true,false,true]] .= [7,8,9] @test a == [7,2,8,4,9] - @test_throws DimensionMismatch (a[[true,false,true,false,true]] = [7,8,9,10]) + @test_throws DimensionMismatch (a[[true,false,true,false,true]] .= [7,8,9,10]) A = reshape(1:15, 3, 5) @test A[[true, false, true], [false, false, true, true, false]] == [7 10; 9 12] @test_throws BoundsError A[[true, false], [false, false, true, true, false]] @@ -918,12 +918,11 @@ end @test_throws BoundsError A[[true, false, true, true], [false, false, true, true, false]] @test_throws BoundsError A[[true, false, true], [false, false, true, true, false, true]] A = fill(1, 3, 5) - @test_throws DimensionMismatch A[2,[true, false, true, true, false]] = 2:5 - A[2,[true, false, true, true, false]] = 2:4 + @test_throws DimensionMismatch A[2,[true, false, true, true, false]] .= 2:5 + A[2,[true, false, true, true, false]] .= 2:4 @test A == [1 1 1 1 1; 2 1 3 4 1; 1 1 1 1 1] - @test_throws DimensionMismatch A[[true,false,true], 5] = [19] - @test_throws DimensionMismatch A[[true,false,true], 5] = 19:21 - A[[true,false,true], 5] = 7 + @test_throws DimensionMismatch A[[true,false,true], 5] .= 19:21 + A[[true,false,true], 5] .= 7 @test A == [1 1 1 1 7; 2 1 3 4 1; 1 1 1 1 7] B = cat(3, 1, 2, 3) @@ -1043,7 +1042,7 @@ end a[b] = 8 @test a == [8,3,8] end - +#= TODO: This is disabled until alias detection is incorporated @testset "assigning an array into itself" begin a = [1,3,5] b = [3,1,2] @@ -1053,7 +1052,7 @@ end a[a] = [4,5,6] @test a == [6,5,4] end - +=# @testset "lexicographic comparison" begin @test cmp([1.0], [1]) == 0 @test cmp([1], [1.0]) == 0