Skip to content

Commit

Permalink
Merge pull request #41254 from JuliaLang/backports-release-1.7
Browse files Browse the repository at this point in the history
Backports for 1.7-beta2
  • Loading branch information
KristofferC authored Jun 18, 2021
2 parents a15fbbc + ed9fda2 commit 6ec3afe
Show file tree
Hide file tree
Showing 37 changed files with 317 additions and 213 deletions.
77 changes: 52 additions & 25 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1635,11 +1635,21 @@ cat_size(A::AbstractArray) = size(A)
cat_size(A, d) = 1
cat_size(A::AbstractArray, d) = size(A, d)

cat_length(::Any) = 1
cat_length(a::AbstractArray) = length(a)

cat_ndims(a) = 0
cat_ndims(a::AbstractArray) = ndims(a)

cat_indices(A, d) = OneTo(1)
cat_indices(A::AbstractArray, d) = axes(A, d)

cat_similar(A, ::Type{T}, shape) where T = Array{T}(undef, shape)
cat_similar(A::AbstractArray, ::Type{T}, shape) where T = similar(A, T, shape)
cat_similar(A, ::Type{T}, shape::Tuple) where T = Array{T}(undef, shape)
cat_similar(A, ::Type{T}, shape::Vector) where T = Array{T}(undef, shape...)
cat_similar(A::Array, ::Type{T}, shape::Tuple) where T = Array{T}(undef, shape)
cat_similar(A::Array, ::Type{T}, shape::Vector) where T = Array{T}(undef, shape...)
cat_similar(A::AbstractArray, T::Type, shape::Tuple) = similar(A, T, shape)
cat_similar(A::AbstractArray, T::Type, shape::Vector) = similar(A, T, shape...)

# These are for backwards compatibility (even though internal)
cat_shape(dims, shape::Tuple{Vararg{Int}}) = shape
Expand Down Expand Up @@ -2034,22 +2044,25 @@ function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T
T[rs...;]
end

# nd concatenation
## N-dimensional concatenation ##

"""
hvncat(dim::Int, row_first, values...)
hvncat(dims::Tuple{Vararg{Int}}, row_first, values...)
hvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)
Horizontal, vertical, and n-dimensional concatenation of many `values` in one call.
This function is called
for block matrix syntax. The first argument either specifies the shape of the concatenation,
similar to `hvcat`, as a tuple of tuples, or the dimensions that specify the key number of
elements along each axis, and is used to determine the output dimensions. The `dims` form
is more performant, and is used by default when the concatenation operation has the same
number of elements along each axis (e.g., [a b; c d;;; e f ; g h]). The `shape` form is used
when the number of elements along each axis is unbalanced (e.g., [a b ; c]). Unbalanced
syntax needs additional validation overhead.
This function is called for block matrix syntax. The first argument either specifies the
shape of the concatenation, similar to `hvcat`, as a tuple of tuples, or the dimensions that
specify the key number of elements along each axis, and is used to determine the output
dimensions. The `dims` form is more performant, and is used by default when the concatenation
operation has the same number of elements along each axis (e.g., [a b; c d;;; e f ; g h]).
The `shape` form is used when the number of elements along each axis is unbalanced
(e.g., [a b ; c]). Unbalanced syntax needs additional validation overhead. The `dim` form
is an optimization for concatenation along just one dimension. `row_first` indicates how
`values` are ordered. The meaning of the first and second elements of `shape` are also
swapped based on `row_first`.
# Examples
```jldoctest
Expand Down Expand Up @@ -2097,6 +2110,24 @@ julia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f)
[:, :, 2] =
4 5 6
```
# Examples for construction of the arguments:
[a b c ; d e f ;;;
g h i ; j k l ;;;
m n o ; p q r ;;;
s t u ; v w x]
=> dims = (2, 3, 4)
[a b ; c ;;; d ;;;;]
___ _ _
2 1 1 = elements in each row (2, 1, 1)
_______ _
3 1 = elements in each column (3, 1)
_____________
4 = elements in each 3d slice (4,)
_____________
4 = elements in each 4d slice (4,)
=> shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `rowfirst` = true
"""
hvncat(::Tuple{}, ::Bool) = []
hvncat(::Tuple{}, ::Bool, xs...) = []
Expand Down Expand Up @@ -2177,7 +2208,7 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N}
end
end

A = Array{T, nd}(undef, ntuple(d -> cat_size(as[1], d), N - 1)..., Ndim, ntuple(x -> 1, nd - N)...)
A = cat_similar(as[1], T, (ntuple(d -> size(as[1], d), N - 1)..., Ndim, ntuple(x -> 1, nd - N)...))
k = 1
for a as
for i eachindex(a)
Expand All @@ -2188,9 +2219,6 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N}
return A
end

cat_ndims(a) = 0
cat_ndims(a::AbstractArray) = ndims(a)

function _typed_hvncat(::Type{T}, ::Val{N}, as...) where {T, N}
# optimization for scalars and 1-length arrays that can be concatenated by copying them linearly
# into the destination
Expand Down Expand Up @@ -2257,12 +2285,12 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool,
elseif currentdims[d] < outdims[d] # dimension in progress
break
else # exceeded dimension
ArgumentError("argument $i has too many elements along axis $d") |> throw
throw(ArgumentError("argument $i has too many elements along axis $d"))
end
end
end
elseif currentdims[d1] > outdims[d1] # exceeded dimension
ArgumentError("argument $i has too many elements along axis $d1") |> throw
throw(ArgumentError("argument $i has too many elements along axis $d1"))
end
end

Expand All @@ -2276,7 +2304,7 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool,
len == outlen || ArgumentError("too many elements in arguments; expected $(outlen), got $(len)") |> throw

# copy into final array
A = Array{T, nd}(undef, outdims...)
A = cat_similar(as[1], T, outdims)
# @assert all(==(0), currentdims)
outdims .= 0
hvncat_fill!(A, currentdims, outdims, d1, d2, as)
Expand Down Expand Up @@ -2308,7 +2336,8 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
if d == 1 || i == 1 || wasstartblock
currentdims[d] += dsize
elseif dsize != cat_size(as[i - 1], ad)
ArgumentError("argument $i has a mismatched number of elements along axis $ad; expected $(cat_size(as[i - 1], ad)), got $dsize") |> throw
throw(ArgumentError("""argument $i has a mismatched number of elements along axis $ad; \
expected $(cat_size(as[i - 1], ad)), got $dsize"""))
end

wasstartblock = blockcounts[d] == 1 # remember for next dimension
Expand All @@ -2318,7 +2347,8 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
if outdims[d] == 0
outdims[d] = currentdims[d]
elseif outdims[d] != currentdims[d]
ArgumentError("argument $i has a mismatched number of elements along axis $ad; expected $(abs(outdims[d] - (currentdims[d] - dsize))), got $dsize") |> throw
throw(ArgumentError("""argument $i has a mismatched number of elements along axis $ad; \
expected $(abs(outdims[d] - (currentdims[d] - dsize))), got $dsize"""))
end
currentdims[d] = 0
blockcounts[d] = 0
Expand All @@ -2335,12 +2365,12 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
# @assert all(==(0), blockcounts)

# copy into final array
A = Array{T, nd}(undef, outdims...)
A = cat_similar(as[1], T, outdims)
hvncat_fill!(A, currentdims, blockcounts, d1, d2, as)
return A
end

function hvncat_fill!(A::Array{T, N}, scratch1::Vector{Int}, scratch2::Vector{Int}, d1::Int, d2::Int, as::Tuple{Vararg}) where {T, N}
function hvncat_fill!(A::AbstractArray{T, N}, scratch1::Vector{Int}, scratch2::Vector{Int}, d1::Int, d2::Int, as::Tuple{Vararg}) where {T, N}
outdims = size(A)
offsets = scratch1
inneroffsets = scratch2
Expand Down Expand Up @@ -2382,9 +2412,6 @@ end
Ai
end

cat_length(a::AbstractArray) = length(a)
cat_length(::Any) = 1

## Reductions and accumulates ##

function isequal(A::AbstractArray, B::AbstractArray)
Expand Down
9 changes: 6 additions & 3 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,10 @@ end

# Query whether the given intrinsic is nothrow

_iszero(x) = x === Intrinsics.xor_int(x, x)
_isneg1(x) = _iszero(Intrinsics.not_int(x))
_istypemin(x) = !_iszero(x) && Intrinsics.neg_int(x) === x

function intrinsic_nothrow(f::IntrinsicFunction, argtypes::Array{Any, 1})
# First check that we have the correct number of arguments
iidx = Int(reinterpret(Int32, f::IntrinsicFunction)) + 1
Expand All @@ -1594,11 +1598,10 @@ function intrinsic_nothrow(f::IntrinsicFunction, argtypes::Array{Any, 1})
return false
end
den_val = argtypes[2].val
den_val !== zero(typeof(den_val)) || return false
_iszero(den_val) && return false
f !== Intrinsics.checked_sdiv_int && return true
# Nothrow as long as we additionally don't do typemin(T)/-1
return den_val !== -1 || (isa(argtypes[1], Const) &&
argtypes[1].val !== typemin(typeof(den_val)))
return !_isneg1(den_val) || (isa(argtypes[1], Const) && !_istypemin(argtypes[1].val))
end
if f === Intrinsics.pointerref
# Nothrow as long as the types are ok. N.B.: dereferencability is not
Expand Down
12 changes: 9 additions & 3 deletions base/experimental.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,21 @@ method tables (e.g., using [`Core.Compiler.OverlayMethodTable`](@ref)).
"""
macro overlay(mt, def)
def = macroexpand(__module__, def) # to expand @inline, @generated, etc
if !isexpr(def, [:function, :(=)]) || !isexpr(def.args[1], :call)
if !isexpr(def, [:function, :(=)])
error("@overlay requires a function Expr")
end
if isexpr(def.args[1], :call)
def.args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1])
elseif isexpr(def.args[1], :where)
def.args[1].args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1].args[1])
else
error("@overlay requires a function Expr")
end
def.args[1].args[1] = Expr(:overlay, mt, def.args[1].args[1])
esc(def)
end

let new_mt(name::Symbol, mod::Module) = begin
ccall(:jl_check_top_level_effect, Cvoid, (Any, Cstring), mod, name)
ccall(:jl_check_top_level_effect, Cvoid, (Any, Cstring), mod, "@MethodTable")
ccall(:jl_new_method_table, Any, (Any, Any), name, mod)
end
@eval macro MethodTable(name::Symbol)
Expand Down
2 changes: 1 addition & 1 deletion base/expr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ function make_atomic(order, ex)
elseif isexpr(ex, :call, 3)
return make_atomic(order, ex.args[2], ex.args[1], ex.args[3])
elseif ex.head === :(=)
l, r = ex.args[1], ex.args[2]
l, r = ex.args[1], esc(ex.args[2])
if is_expr(l, :., 2)
ll, lr = esc(l.args[1]), esc(l.args[2])
return :(setproperty!($ll, $lr, $r, $order))
Expand Down
4 changes: 3 additions & 1 deletion base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,9 @@ function sum(r::AbstractRange{<:Real})
end

function _in_range(x, r::AbstractRange)
if step(r) == 0
if !isfinite(x)
return false
elseif iszero(step(r))
return !isempty(r) && first(r) == x
else
n = round(Integer, (x - first(r)) / step(r)) + 1
Expand Down
7 changes: 4 additions & 3 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@ unsafe_rational(num::T, den::T) where {T<:Integer} = unsafe_rational(T, num, den
unsafe_rational(num::Integer, den::Integer) = unsafe_rational(promote(num, den)...)

@noinline __throw_rational_argerror_typemin(T) = throw(ArgumentError("invalid rational: denominator can't be typemin($T)"))
function checked_den(num::T, den::T) where T<:Integer
function checked_den(::Type{T}, num::T, den::T) where T<:Integer
if signbit(den)
den = -den
signbit(den) && __throw_rational_argerror_typemin(T)
signbit(den) && __throw_rational_argerror_typemin(typeof(den))
num = -num
end
return unsafe_rational(T, num, den)
end
checked_den(num::T, den::T) where T<:Integer = checked_den(T, num, den)
checked_den(num::Integer, den::Integer) = checked_den(promote(num, den)...)

@noinline __throw_rational_argerror_zero(T) = throw(ArgumentError("invalid rational: zero($T)//zero($T)"))
function Rational{T}(num::Integer, den::Integer) where T<:Integer
iszero(den) && iszero(num) && __throw_rational_argerror_zero(T)
num, den = divgcd(num, den)
return checked_den(T(num), T(den))
return checked_den(T, T(num), T(den))
end

Rational(n::T, d::T) where {T<:Integer} = Rational{T}(n, d)
Expand Down
2 changes: 1 addition & 1 deletion base/strings/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ function _rsearchindex(s::AbstractVector{<:Union{Int8,UInt8}}, t::AbstractVector
n = length(t)
m = length(s)
k = Int(_k) - sentinel
k < 1 && throw(BoundsError(s, _k))
k < 0 && throw(BoundsError(s, _k))

if n == 0
return 0 <= k <= m ? max(k, 1) : sentinel
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
77b9bf19937476f9b2120dfbafc3322b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
c9079f0c2b4d6ad34eca479f4db14041ac04f0780feaa1b16de552e55ca862f0d56c9a50437304639b96777a2c941c4b7a5eb0ce23071a456126a5c2da23c2e1

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4c09536f4f769b23e88fee769f5a09bd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e409fa943a9683a129b80c78ef74572df316ed414dfc8c208f1500d0f07d4d41870d44654446e2c20d1b9ed11e62c4fc6107b6e5789939edbd049fc2aaf22f63
Loading

0 comments on commit 6ec3afe

Please sign in to comment.