From e9477beb5812aefec166be1f36588a587e14498d Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 7 Jan 2017 15:42:12 -0600 Subject: [PATCH 1/6] Simpler scalar indexing --- base/abstractarray.jl | 135 ++++++++++++------------------------------ test/TestHelpers.jl | 5 ++ 2 files changed, 42 insertions(+), 98 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index a1b45a4b65b91..b20c64b9a5d7d 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -829,65 +829,45 @@ error_if_canonical_indexing(::LinearIndexing, ::AbstractArray, ::Any...) = nothi _getindex(::LinearIndexing, A::AbstractArray, I...) = error("indexing $(typeof(A)) with types $(typeof(I)) is not supported") ## LinearFast Scalar indexing: canonical method is one Int -_getindex(::LinearFast, A::AbstractVector, i::Int) = (@_propagate_inbounds_meta; getindex(A, i)) -_getindex(::LinearFast, A::AbstractArray, i::Int) = (@_propagate_inbounds_meta; getindex(A, i)) -_getindex{T}(::LinearFast, A::AbstractArray{T,0}) = A[1] -function _getindex{T,N}(::LinearFast, A::AbstractArray{T,N}, I::Vararg{Int,N}) - # We must check bounds for sub2ind; so we can then use @inbounds +_getindex(::LinearFast, A::AbstractArray, i::Int) = (@_propagate_inbounds_meta; getindex(A, i)) +_getindex(::LinearFast, A::AbstractArray) = (@_propagate_inbounds_meta; getindex(A, _to_linear_index(A))) +function _getindex(::LinearFast, A::AbstractArray, I::Int...) @_inline_meta - @boundscheck checkbounds(A, I...) - @inbounds r = getindex(A, sub2ind(A, I...)) - r -end -function _getindex(::LinearFast, A::AbstractVector, I1::Int, I::Int...) - @_inline_meta - @boundscheck checkbounds(A, I1, I...) - @inbounds r = getindex(A, I1) - r -end -function _getindex(::LinearFast, A::AbstractArray, I::Int...) # TODO: DEPRECATE FOR #14770 - @_inline_meta - @boundscheck checkbounds(A, I...) - @inbounds r = getindex(A, sub2ind(A, I...)) + @boundscheck checkbounds(A, I...) # generally _to_linear_index requires bounds checking + @inbounds r = getindex(A, _to_linear_index(A, I...)) r end - +_to_linear_index(A::AbstractArray, i::Int) = i +_to_linear_index(A::AbstractVector, i::Int, I::Int...) = i # TODO: DEPRECATE FOR #14770 +_to_linear_index{T,N}(A::AbstractArray{T,N}, I::Vararg{Int,N}) = (@_inline_meta; sub2ind(A, I...)) +_to_linear_index(A::AbstractArray) = 1 # TODO: DEPRECATE FOR #14770 +_to_linear_index(A::AbstractArray, I::Int...) = (@_inline_meta; sub2ind(A, I...)) # TODO: DEPRECATE FOR #14770 ## LinearSlow Scalar indexing: Canonical method is full dimensionality of Ints -_getindex{T,N}(::LinearSlow, A::AbstractArray{T,N}, I::Vararg{Int, N}) = (@_propagate_inbounds_meta; getindex(A, I...)) -function _getindex(::LinearSlow, A::AbstractArray, i::Int) - # ind2sub requires all dimensions to be > 0; may as well just check bounds +_getindex(::LinearSlow, A::AbstractArray) = (@_propagate_inbounds_meta; getindex(A, _to_subscript_indices(A)...)) +function _getindex(::LinearSlow, A::AbstractArray, I::Int...) @_inline_meta - @boundscheck checkbounds(A, i) - @inbounds r = getindex(A, ind2sub(A, i)...) + @boundscheck checkbounds(A, I...) # generally _to_subscript_indices requires bounds checking + @inbounds r = getindex(A, _to_subscript_indices(A, I...)...) r end -@generated function _getindex{T,AN}(::LinearSlow, A::AbstractArray{T,AN}, I::Int...) # TODO: DEPRECATE FOR #14770 - N = length(I) - if N > AN - # Drop trailing ones - Isplat = Expr[:(I[$d]) for d = 1:AN] - Osplat = Expr[:(I[$d] == 1) for d = AN+1:N] - quote - @_propagate_inbounds_meta - @boundscheck (&)($(Osplat...)) || throw_boundserror(A, I) - getindex(A, $(Isplat...)) - end - else - # Expand the last index into the appropriate number of indices - Isplat = Expr[:(I[$d]) for d = 1:N-1] - sz = Expr(:tuple) - sz.args = Expr[:(size(A, $d)) for d=max(N,1):AN] - szcheck = Expr[:(size(A, $d) > 0) for d=max(N,1):AN] - last_idx = N > 0 ? :(I[$N]) : 1 - quote - # ind2sub requires all dimensions to be > 0: - @_propagate_inbounds_meta - @boundscheck (&)($(szcheck...)) || throw_boundserror(A, I) - getindex(A, $(Isplat...), ind2sub($sz, $last_idx)...) - end - end +_getindex{T,N}(::LinearSlow, A::AbstractArray{T,N}, I::Vararg{Int, N}) = (@_propagate_inbounds_meta; getindex(A, I...)) +_to_subscript_indices(A::AbstractArray, i::Int) = (@_inline_meta; _unsafe_ind2sub(A, i)) +_to_subscript_indices{T,N}(A::AbstractArray{T,N}) = (@_inline_meta; fill_to_length((), 1, Val{N})) # TODO: DEPRECATE FOR #14770 +_to_subscript_indices{T}(A::AbstractArray{T,0}) = () # TODO: REMOVE FOR #14770 +_to_subscript_indices{T}(A::AbstractArray{T,0}, i::Int) = () # TODO: REMOVE FOR #14770 +_to_subscript_indices{T}(A::AbstractArray{T,0}, I::Int...) = () # TODO: DEPRECATE FOR #14770 +function _to_subscript_indices{T,N}(A::AbstractArray{T,N}, I::Int...) # TODO: DEPRECATE FOR #14770 + @_inline_meta + J, _ = IteratorsMD.split(I, Val{N}) # (maybe) drop any trailing indices + sz = _remaining_size(J, size(A)) # compute trailing size (overlapping the final index) + (front(J)..., _unsafe_ind2sub(sz, last(J))...) # (maybe) extend the last index end +_to_subscript_indices{T,N}(A::AbstractArray{T,N}, I::Vararg{Int,N}) = I +_remaining_size(::Tuple{Any}, t::Tuple) = t +_remaining_size(h::Tuple, t::Tuple) = (@_inline_meta; _remaining_size(tail(h), tail(t))) +_unsafe_ind2sub(::Tuple{}, i) = () # ind2sub may throw(BoundsError()) in this case +_unsafe_ind2sub(sz, i) = (@_inline_meta; ind2sub(sz, i)) ## Setindex! is defined similarly. We first dispatch to an internal _setindex! # function that allows dispatch on array storage @@ -905,65 +885,24 @@ end _setindex!(::LinearIndexing, A::AbstractArray, v, I...) = error("indexing $(typeof(A)) with types $(typeof(I)) is not supported") ## LinearFast Scalar indexing -_setindex!(::LinearFast, A::AbstractVector, v, i::Int) = (@_propagate_inbounds_meta; setindex!(A, v, i)) _setindex!(::LinearFast, A::AbstractArray, v, i::Int) = (@_propagate_inbounds_meta; setindex!(A, v, i)) -_setindex!{T}(::LinearFast, A::AbstractArray{T,0}, v) = (@_propagate_inbounds_meta; setindex!(A, v, 1)) -function _setindex!{T,N}(::LinearFast, A::AbstractArray{T,N}, v, I::Vararg{Int,N}) - # We must check bounds for sub2ind; so we can then use @inbounds - @_inline_meta - @boundscheck checkbounds(A, I...) - @inbounds r = setindex!(A, v, sub2ind(A, I...)) - r -end -function _setindex!(::LinearFast, A::AbstractVector, v, I1::Int, I::Int...) - @_inline_meta - @boundscheck checkbounds(A, I1, I...) - @inbounds r = setindex!(A, v, I1) - r -end -function _setindex!(::LinearFast, A::AbstractArray, v, I::Int...) # TODO: DEPRECATE FOR #14770 +_setindex!(::LinearFast, A::AbstractArray, v) = (@_propagate_inbounds_meta; setindex!(A, v, _to_linear_index(A))) +function _setindex!(::LinearFast, A::AbstractArray, v, I::Int...) @_inline_meta @boundscheck checkbounds(A, I...) - @inbounds r = setindex!(A, v, sub2ind(A, I...)) + @inbounds r = setindex!(A, v, _to_linear_index(A, I...)) r end # LinearSlow Scalar indexing _setindex!{T,N}(::LinearSlow, A::AbstractArray{T,N}, v, I::Vararg{Int, N}) = (@_propagate_inbounds_meta; setindex!(A, v, I...)) -function _setindex!(::LinearSlow, A::AbstractArray, v, i::Int) - # ind2sub requires all dimensions to be > 0; may as well just check bounds +_setindex!(::LinearSlow, A::AbstractArray, v) = (@_propagate_inbounds_meta; setindex!(A, v, _to_subscript_indices(A)...)) +function _setindex!(::LinearSlow, A::AbstractArray, v, I::Int...) @_inline_meta - @boundscheck checkbounds(A, i) - @inbounds r = setindex!(A, v, ind2sub(A, i)...) + @boundscheck checkbounds(A, I...) + @inbounds r = setindex!(A, v, _to_subscript_indices(A, I...)...) r end -@generated function _setindex!{T,AN}(::LinearSlow, A::AbstractArray{T,AN}, v, I::Int...) # TODO: DEPRECATE FOR #14770 - N = length(I) - if N > AN - # Drop trailing ones - Isplat = Expr[:(I[$d]) for d = 1:AN] - Osplat = Expr[:(I[$d] == 1) for d = AN+1:N] - quote - # We only check the trailing ones, so just propagate @inbounds state - @_propagate_inbounds_meta - @boundscheck (&)($(Osplat...)) || throw_boundserror(A, I) - setindex!(A, v, $(Isplat...)) - end - else - # Expand the last index into the appropriate number of indices - Isplat = Expr[:(I[$d]) for d = 1:N-1] - sz = Expr(:tuple) - sz.args = Expr[:(size(A, $d)) for d=max(N,1):AN] - szcheck = Expr[:(size(A, $d) > 0) for d=max(N,1):AN] - last_idx = N > 0 ? :(I[$N]) : 1 - quote - # ind2sub requires all dimensions to be > 0: - @_propagate_inbounds_meta - @boundscheck (&)($(szcheck...)) || throw_boundserror(A, I) - setindex!(A, v, $(Isplat...), ind2sub($sz, $last_idx)...) - end - end -end ## get (getindex with a default value) ## diff --git a/test/TestHelpers.jl b/test/TestHelpers.jl index 4501468505ed3..9e1469c0684b2 100644 --- a/test/TestHelpers.jl +++ b/test/TestHelpers.jl @@ -132,6 +132,11 @@ end val end +# Add support for indexing into OffsetVectors with trailing 1s +# These are required because OffsetVectors don't support sub2ind +Base._to_linear_index(A::OffsetVector, I::Int...) = I[1] # TODO: REMOVE FOR #14770 +Base._to_linear_index(A::OffsetVector) = error("linear indexing is not defined for one-dimensional arrays") + # Computing a shifted index (subtracting the offset) offset{N}(offsets::NTuple{N,Int}, inds::NTuple{N,Int}) = _offset((), offsets, inds) _offset(out, ::Tuple{}, ::Tuple{}) = out From bc565e1e61561f916b3edcd27fb06553f1afa92f Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Mon, 9 Jan 2017 17:19:22 -0600 Subject: [PATCH 2/6] Prepare Array for deprecating generalized linear indexing --- base/array.jl | 19 ++++++++++++++----- base/multidimensional.jl | 5 +++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/base/array.jl b/base/array.jl index a4645f87103e0..8999eeb2d6fa6 100644 --- a/base/array.jl +++ b/base/array.jl @@ -447,9 +447,10 @@ done(a::Array,i) = (@_inline_meta; i == length(a)+1) ## Indexing: getindex ## -# This is more complicated than it needs to be in order to get Win64 through bootstrap getindex(A::Array, i1::Int) = arrayref(A, i1) -getindex(A::Array, i1::Int, i2::Int, I::Int...) = (@_inline_meta; arrayref(A, i1, i2, I...)) # TODO: REMOVE FOR #14770 +getindex{T}(A::Array{T,1}, i1::Int) = arrayref(A, i1) +getindex{T,N}(A::Array{T,N}, I::Vararg{Int,N}) = (@_inline_meta; arrayref(A, I...)) +getindex{T}(A::Array{T,0}) = (@_inline_meta; arrayref(A, 1)) # Faster contiguous indexing using copy! for UnitRange and Colon function getindex(A::Array, I::UnitRange{Int}) @@ -477,8 +478,15 @@ function getindex{S}(A::Array{S}, I::Range{Int}) end ## Indexing: setindex! ## -setindex!{T}(A::Array{T}, x, i1::Int) = arrayset(A, convert(T,x)::T, i1) -setindex!{T}(A::Array{T}, x, i1::Int, i2::Int, I::Int...) = (@_inline_meta; arrayset(A, convert(T,x)::T, i1, i2, I...)) # TODO: REMOVE FOR #14770 +setindex!{T}(A::Array{T}, x, i::Int) = arrayset(A, convert(T,x)::T, i) +setindex!{T}(A::Array{T,1}, x, i::Int) = arrayset(A, convert(T,x)::T, i) +setindex!{T,N}(A::Array{T,N}, x, I::Vararg{Int,N}) = (@_inline_meta; arrayset(A, convert(T,x)::T, I...)) +setindex!{T}(A::Array{T,0}, x) = (@_inline_meta; arrayset(A, convert(T,x)::T, 1)) + +# These are needed for ambiguity with a method in essentials.jl for bootstrap +setindex!(A::Array{Any,1}, x::ANY, i::Int) = arrayset(A, x, i) +setindex!(A::Array{Any,0}, x::ANY) = arrayset(A, x, 1) +setindex!{N}(A::Array{Any,N}, x::ANY, I::Vararg{Int,N}) = arrayset(A, x, I...) # These are redundant with the abstract fallbacks but needed for bootstrap function setindex!(A::Array, x, I::AbstractVector{Int}) @@ -525,7 +533,8 @@ function setindex!{T}(A::Array{T}, X::Array{T}, c::Colon) end setindex!(A::Array, x::Number, ::Colon) = fill!(A, x) -setindex!{T, N}(A::Array{T, N}, x::Number, ::Vararg{Colon, N}) = fill!(A, x) +# This causes a ton of ambiguities +# setindex!{T, N}(A::Array{T, N}, x::Number, ::Vararg{Colon, N}) = fill!(A, x) # efficiently grow an array diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 58d4570b3b6d1..25db93a013141 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -180,6 +180,11 @@ using .IteratorsMD A[to_indices(A, (i1, I...))...] @propagate_inbounds setindex!(A::Array, v, i1::Union{Integer, CartesianIndex}, I::Union{Integer, CartesianIndex}...) = (A[to_indices(A, (i1, I...))...] = v; A) +# But they may not expand to 1 or N indices; ensure the above doesn't shadow the general indexing fallbacks +@propagate_inbounds getindex{T}(A::Array{T}, i1::Int, I::Int...) = + _getindex(LinearFast(), A, i1, I...) +@propagate_inbounds setindex!{T}(A::Array{T}, v, i1::Int, I::Int...) = + _setindex!(LinearFast(), A, v, i1, I...) # Support indexing with an array of CartesianIndex{N}s # Here we try to consume N of the indices (if there are that many available) From 85f8b85cecb525973403200caebe117f33b5fce0 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 14 Jan 2017 12:48:12 -0600 Subject: [PATCH 3/6] Deprecate generalized linear indexing --- base/abstractarray.jl | 42 +++++++++++++++++++++++++++++----------- base/deprecated.jl | 22 +++++++++++++++++++-- base/multidimensional.jl | 9 ++++----- base/subarray.jl | 1 - 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index b20c64b9a5d7d..9551dfc9f0e8e 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -837,11 +837,22 @@ function _getindex(::LinearFast, A::AbstractArray, I::Int...) @inbounds r = getindex(A, _to_linear_index(A, I...)) r end +######################### TODO: MOVE TO DEPRECATED.JL ######################### +function _to_linear_index(A::AbstractArray) + depwarn("general linear indexing is deprecated; use reshape(A, Val{0}) before indexing", (:getindex, :setindex!, :view)) + 1 +end +function _to_linear_index(A::AbstractArray, I::Int...) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$(length(I))}) before indexing", (:getindex, :setindex!, :view)) + sub2ind(A, I...) +end +function _to_linear_index(A::AbstractArray, i::Int, I::Int...) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$(length(I))}) before indexing", (:getindex, :setindex!, :view)) + i +end +############################################################################### _to_linear_index(A::AbstractArray, i::Int) = i -_to_linear_index(A::AbstractVector, i::Int, I::Int...) = i # TODO: DEPRECATE FOR #14770 _to_linear_index{T,N}(A::AbstractArray{T,N}, I::Vararg{Int,N}) = (@_inline_meta; sub2ind(A, I...)) -_to_linear_index(A::AbstractArray) = 1 # TODO: DEPRECATE FOR #14770 -_to_linear_index(A::AbstractArray, I::Int...) = (@_inline_meta; sub2ind(A, I...)) # TODO: DEPRECATE FOR #14770 ## LinearSlow Scalar indexing: Canonical method is full dimensionality of Ints _getindex(::LinearSlow, A::AbstractArray) = (@_propagate_inbounds_meta; getindex(A, _to_subscript_indices(A)...)) @@ -852,20 +863,29 @@ function _getindex(::LinearSlow, A::AbstractArray, I::Int...) r end _getindex{T,N}(::LinearSlow, A::AbstractArray{T,N}, I::Vararg{Int, N}) = (@_propagate_inbounds_meta; getindex(A, I...)) -_to_subscript_indices(A::AbstractArray, i::Int) = (@_inline_meta; _unsafe_ind2sub(A, i)) -_to_subscript_indices{T,N}(A::AbstractArray{T,N}) = (@_inline_meta; fill_to_length((), 1, Val{N})) # TODO: DEPRECATE FOR #14770 -_to_subscript_indices{T}(A::AbstractArray{T,0}) = () # TODO: REMOVE FOR #14770 -_to_subscript_indices{T}(A::AbstractArray{T,0}, i::Int) = () # TODO: REMOVE FOR #14770 -_to_subscript_indices{T}(A::AbstractArray{T,0}, I::Int...) = () # TODO: DEPRECATE FOR #14770 -function _to_subscript_indices{T,N}(A::AbstractArray{T,N}, I::Int...) # TODO: DEPRECATE FOR #14770 - @_inline_meta + +######################### TODO: MOVE TO DEPRECATED.JL ######################### +function _to_subscript_indices{T,N}(A::AbstractArray{T,N}) + depwarn("general linear indexing is deprecated; use reshape(A, Val{0}) before indexing", (:getindex, :setindex!, :view)) + fill_to_length((), 1, Val{N}) +end +_to_subscript_indices{T}(A::AbstractArray{T,0}) = () # Ambiguity +_to_subscript_indices{T}(A::AbstractArray{T,0}, i::Int) = () # Ambiguity +function _to_subscript_indices{T}(A::AbstractArray{T,0}, I::Int...) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$(length(I))}) before indexing", (:getindex, :setindex!, :view)) + () +end +function _to_subscript_indices{T,N}(A::AbstractArray{T,N}, I::Int...) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$(length(I))}) before indexing", (:getindex, :setindex!, :view)) J, _ = IteratorsMD.split(I, Val{N}) # (maybe) drop any trailing indices sz = _remaining_size(J, size(A)) # compute trailing size (overlapping the final index) (front(J)..., _unsafe_ind2sub(sz, last(J))...) # (maybe) extend the last index end -_to_subscript_indices{T,N}(A::AbstractArray{T,N}, I::Vararg{Int,N}) = I _remaining_size(::Tuple{Any}, t::Tuple) = t _remaining_size(h::Tuple, t::Tuple) = (@_inline_meta; _remaining_size(tail(h), tail(t))) +############################################################################### +_to_subscript_indices(A::AbstractArray, i::Int) = (@_inline_meta; _unsafe_ind2sub(A, i)) +_to_subscript_indices{T,N}(A::AbstractArray{T,N}, I::Vararg{Int,N}) = I _unsafe_ind2sub(::Tuple{}, i) = () # ind2sub may throw(BoundsError()) in this case _unsafe_ind2sub(sz, i) = (@_inline_meta; ind2sub(sz, i)) diff --git a/base/deprecated.jl b/base/deprecated.jl index e80f7574373ea..873de36d2e726 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -73,7 +73,8 @@ function depwarn(msg, funcsym) nothing end -function firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol) +firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol) = firstcaller(bt, (funcsym,)) +function firstcaller(bt::Array{Ptr{Void},1}, funcsyms) # Identify the calling line i = 1 while i <= length(bt) @@ -83,7 +84,7 @@ function firstcaller(bt::Array{Ptr{Void},1}, funcsym::Symbol) if lkup === StackTraces.UNKNOWN continue end - if lkup.func == funcsym + if lkup.func in funcsyms @goto found end end @@ -1425,6 +1426,23 @@ function promote_array_type(F, R, S, T) _promote_array_type(F, R, S, T) end +# Deprecate generalized linear indexing +function __maybe_reshape{N}(::LinearSlow, A::AbstractArray, ::NTuple{N}) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$N}) before indexing", (:getindex, :setindex!, :view)) + reshape(A, Val{N}) +end +function __maybe_reshape{N}(::LinearFast, A::AbstractArray, ::NTuple{N}) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$N}) before indexing", (:getindex, :setindex!, :view)) + reshape(A, Val{N}) # Reshape isn't necessary, but do so to prevent depwarns everywhere +end +@inline __maybe_reshape{T,N}(::LinearFast, A::AbstractArray{T,N}, ::NTuple{N}) = A +@inline __maybe_reshape{T,N}(::LinearFast, A::AbstractArray{T,N}, ::NTuple{1}) = A +function _maybe_reshape_parent{N}(A::AbstractArray, ::NTuple{N, Bool}) + depwarn("general linear indexing is deprecated; use reshape(A, Val{$N}) before indexing", (:getindex, :setindex!, :view)) + reshape(A, Val{N}) +end + + # Deprecate manually vectorized abs2 methods in favor of compact broadcast syntax @deprecate abs2(x::AbstractSparseVector) abs2.(x) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 25db93a013141..cd7f1dbe97683 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -376,11 +376,10 @@ getindex(t::Tuple, I...) = getindex(t, IteratorsMD.flatten(I)...) end end # But we can speed up LinearSlow arrays by reshaping them to the appropriate dimensionality: -_maybe_reshape(::LinearFast, A::AbstractArray, I...) = A -_maybe_reshape(::LinearSlow, A::AbstractVector, I...) = A -@inline _maybe_reshape(::LinearSlow, A::AbstractArray, I...) = __maybe_reshape(A, index_ndims(I...)) -@inline __maybe_reshape{T,N}(A::AbstractArray{T,N}, ::NTuple{N}) = A -@inline __maybe_reshape{N}(A::AbstractArray, ::NTuple{N}) = reshape(A, Val{N}) +@inline _maybe_reshape(l::LinearIndexing, A::AbstractArray, I...) = __maybe_reshape(l, A, index_ndims(I...)) +@inline __maybe_reshape{T,N}(::LinearSlow, A::AbstractArray{T,N}, ::NTuple{N}) = A +@inline __maybe_reshape{T,N}(::LinearSlow, A::AbstractArray{T,N}, ::NTuple{1}) = reshape(A, Val{1}) +@inline __maybe_reshape{T,N}(::LinearFast, A::AbstractArray{T,N}, ::Any) = A @generated function _unsafe_getindex(::LinearIndexing, A::AbstractArray, I::Union{Real, AbstractArray}...) N = length(I) diff --git a/base/subarray.jl b/base/subarray.jl index 54af2bd3d2dc7..78ffac232bf5a 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -75,7 +75,6 @@ parentindexes(a::AbstractArray) = ntuple(i->OneTo(size(a,i)), ndims(a)) # can make the number of effective indices not equal to length(I). _maybe_reshape_parent(A::AbstractArray, ::NTuple{1, Bool}) = reshape(A, Val{1}) _maybe_reshape_parent{_,N}(A::AbstractArray{_,N}, ::NTuple{N, Bool}) = A -_maybe_reshape_parent{N}(A::AbstractArray, ::NTuple{N, Bool}) = reshape(A, Val{N}) # TODO: DEPRECATE FOR #14770 """ view(A, inds...) From 64ac6380ac26bfb4f3bfa5f438c367aa5a1a05da Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 14 Jan 2017 12:49:52 -0600 Subject: [PATCH 4/6] Fix deprecations in test/dict.jl --- test/dict.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/dict.jl b/test/dict.jl index 39882c49f6a39..9da6250a33dd9 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -526,7 +526,7 @@ import Base.== const global hashoffset = [UInt(190)] -Base.hash(s::MyString) = hash(s.str) + hashoffset[] +Base.hash(s::MyString) = hash(s.str) + hashoffset[1] Base.endof(s::MyString) = endof(s.str) Base.next(s::MyString, v::Int) = next(s.str, v) Base.isequal(a::MyString, b::MyString) = isequal(a.str, b.str) @@ -559,7 +559,7 @@ let badKeys = [ # Walk through all possible hash values (mod size of hash table) for offset = 0:1023 d2 = Dict{MyString,Int}() - hashoffset[] = offset + hashoffset[1] = offset for i = 1:length(badKeys) d2[MyString(badKeys[i])] = i end @@ -574,7 +574,7 @@ immutable MyInt <: Integer val::UInt end -Base.hash(v::MyInt) = v.val + hashoffset[] +Base.hash(v::MyInt) = v.val + hashoffset[1] Base.endof(v::MyInt) = endof(v.val) Base.next(v::MyInt, i::Int) = next(v.val, i) Base.isequal(a::MyInt, b::MyInt) = isequal(a.val, b.val) @@ -589,7 +589,7 @@ let badKeys = UInt16[0xb800,0xa501,0xcdff,0x6303,0xe40a,0xcf0e,0xf3df,0xae99,0x9 # Walk through all possible hash values (mod size of hash table) for offset = 0:1023 d2 = Dict{MyInt, Int}() - hashoffset[] = offset + hashoffset[1] = offset for i = 1:length(badKeys) d2[MyInt(badKeys[i])] = i end From 61ffd27bb8bbd21cec118bffb60274d1d809810f Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 14 Jan 2017 13:11:42 -0600 Subject: [PATCH 5/6] Fix deprecations in linalg/triangular.jl --- base/linalg/triangular.jl | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/base/linalg/triangular.jl b/base/linalg/triangular.jl index a0eda4499fdf6..75a3f931fd1de 100644 --- a/base/linalg/triangular.jl +++ b/base/linalg/triangular.jl @@ -1547,12 +1547,11 @@ for (f, g) in ((:A_mul_Bc, :A_mul_Bc!), (:A_mul_Bt, :A_mul_Bt!)) end end -for mat in (:AbstractVector, :AbstractMatrix) - ### Multiplication with triangle to the left and hence rhs cannot be transposed. for (f, g) in ((:*, :A_mul_B!), (:Ac_mul_B, :Ac_mul_B!), (:At_mul_B, :At_mul_B!)) @eval begin - function ($f)(A::AbstractTriangular, B::$mat) + ($f)(A::AbstractTriangular, B::AbstractVector) = ($f)(A, reshape(B, Val{2})) + function ($f)(A::AbstractTriangular, B::AbstractMatrix) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copy!(BB, B) @@ -1563,7 +1562,8 @@ end ### Left division with triangle to the left hence rhs cannot be transposed. No quotients. for (f, g) in ((:\, :A_ldiv_B!), (:Ac_ldiv_B, :Ac_ldiv_B!), (:At_ldiv_B, :At_ldiv_B!)) @eval begin - function ($f)(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::$mat) + ($f)(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::AbstractVector) = ($f)(A, reshape(B, Val{2})) + function ($f)(A::Union{UnitUpperTriangular,UnitLowerTriangular}, B::AbstractMatrix) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) BB = similar(B, TAB, size(B)) copy!(BB, B) @@ -1574,7 +1574,8 @@ end ### Left division with triangle to the left hence rhs cannot be transposed. Quotients. for (f, g) in ((:\, :A_ldiv_B!), (:Ac_ldiv_B, :Ac_ldiv_B!), (:At_ldiv_B, :At_ldiv_B!)) @eval begin - function ($f)(A::Union{UpperTriangular,LowerTriangular}, B::$mat) + ($f)(A::Union{UpperTriangular,LowerTriangular}, B::AbstractVector) = ($f)(A, reshape(B, Val{2})) + function ($f)(A::Union{UpperTriangular,LowerTriangular}, B::AbstractMatrix) TAB = typeof((zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B)))/one(eltype(A))) BB = similar(B, TAB, size(B)) copy!(BB, B) @@ -1585,7 +1586,8 @@ end ### Multiplication with triangle to the rigth and hence lhs cannot be transposed. for (f, g) in ((:*, :A_mul_B!), (:A_mul_Bc, :A_mul_Bc!), (:A_mul_Bt, :A_mul_Bt!)) @eval begin - function ($f)(A::$mat, B::AbstractTriangular) + ($f)(A::AbstractVector, B::AbstractTriangular) = ($f)(reshape(A, Val{2}), B) + function ($f)(A::AbstractMatrix, B::AbstractTriangular) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copy!(AA, A) @@ -1596,7 +1598,8 @@ end ### Right division with triangle to the right hence lhs cannot be transposed. No quotients. for (f, g) in ((:/, :A_rdiv_B!), (:A_rdiv_Bc, :A_rdiv_Bc!), (:A_rdiv_Bt, :A_rdiv_Bt!)) @eval begin - function ($f)(A::$mat, B::Union{UnitUpperTriangular, UnitLowerTriangular}) + ($f)(A::AbstractVector, B::Union{UnitUpperTriangular, UnitLowerTriangular}) = ($f)(reshape(A, Val{2}), B) + function ($f)(A::AbstractMatrix, B::Union{UnitUpperTriangular, UnitLowerTriangular}) TAB = typeof(zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B))) AA = similar(A, TAB, size(A)) copy!(AA, A) @@ -1608,7 +1611,8 @@ end ### Right division with triangle to the right hence lhs cannot be transposed. Quotients. for (f, g) in ((:/, :A_rdiv_B!), (:A_rdiv_Bc, :A_rdiv_Bc!), (:A_rdiv_Bt, :A_rdiv_Bt!)) @eval begin - function ($f)(A::$mat, B::Union{UpperTriangular,LowerTriangular}) + ($f)(A::AbstractVector, B::Union{UpperTriangular,LowerTriangular}) = ($f)(reshape(A, Val{2}), B) + function ($f)(A::AbstractMatrix, B::Union{UpperTriangular,LowerTriangular}) TAB = typeof((zero(eltype(A))*zero(eltype(B)) + zero(eltype(A))*zero(eltype(B)))/one(eltype(A))) AA = similar(A, TAB, size(A)) copy!(AA, A) @@ -1616,7 +1620,6 @@ for (f, g) in ((:/, :A_rdiv_B!), (:A_rdiv_Bc, :A_rdiv_Bc!), (:A_rdiv_Bt, :A_rdiv end end end -end # If these are not defined, they will fallback to the versions in matmul.jl # and dispatch to generic_matmatmul! which is very costly to compile. The methods From fa31b3897315252898694911d8c00c4eb23b7aa9 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 14 Jan 2017 17:29:53 -0600 Subject: [PATCH 6/6] [ci skip]