Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mbauman committed Feb 5, 2018
1 parent a044494 commit b9e2e37
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 52 deletions.
27 changes: 15 additions & 12 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1808,38 +1808,38 @@ 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...,))

ridx = Any[map(first, axes(R))...]
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

@noinline function inner_mapslices!(safe_for_reuse, indices, nidx, idx, otherdims, ridx, Aslice, A, f, R)
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

Expand All @@ -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

Expand Down
8 changes: 4 additions & 4 deletions base/abstractarraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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))
Expand All @@ -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
Expand Down
11 changes: 0 additions & 11 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand Down
8 changes: 6 additions & 2 deletions base/bitset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 6 additions & 7 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -1463,21 +1462,21 @@ 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
copy_to_bitarray_chunks!(B.chunks, f0, X, 1, l0)
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
Expand Down
29 changes: 14 additions & 15 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -908,22 +908,21 @@ 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]]
@test_throws BoundsError A[[true, false, true], [false, true, true, false]]
@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)
Expand Down Expand Up @@ -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]
Expand All @@ -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
Expand Down

0 comments on commit b9e2e37

Please sign in to comment.