Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backports release 1.10 #53201

Merged
merged 6 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,20 @@ end
has_offset_axes(A, B, ...)

Return `true` if the indices of `A` start with something other than 1 along any axis.
If multiple arguments are passed, equivalent to `has_offset_axes(A) | has_offset_axes(B) | ...`.
If multiple arguments are passed, equivalent to `has_offset_axes(A) || has_offset_axes(B) || ...`.

See also [`require_one_based_indexing`](@ref).
"""
has_offset_axes() = false
has_offset_axes(A) = _any_tuple(x->Int(first(x))::Int != 1, false, axes(A)...)
has_offset_axes(A::AbstractVector) = Int(firstindex(A))::Int != 1 # improve performance of a common case (ranges)
# Use `_any_tuple` to avoid unneeded invoke.
# note: this could call `any` directly if the compiler can infer it
has_offset_axes(As...) = _any_tuple(has_offset_axes, false, As...)
has_offset_axes(::Colon) = false
has_offset_axes(::Array) = false
# note: this could call `any` directly if the compiler can infer it. We don't use _any_tuple
# here because it stops full elision in some cases (#49332) and we don't need handling of
# `missing` (has_offset_axes(A) always returns a Bool)
has_offset_axes(A, As...) = has_offset_axes(A) || has_offset_axes(As...)


"""
require_one_based_indexing(A::AbstractArray)
Expand Down
5 changes: 3 additions & 2 deletions base/threadingconstructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ maxthreadid() = Int(Core.Intrinsics.atomic_pointerref(cglobal(:jl_n_threads, Cin
"""
Threads.nthreads(:default | :interactive) -> Int

Get the current number of threads within the specified thread pool. The threads in default
have id numbers `1:nthreads(:default)`.
Get the current number of threads within the specified thread pool. The threads in `:interactive`
have id numbers `1:nthreads(:interactive)`, and the threads in `:default` have id numbers in
`nthreads(:interactive) .+ (1:nthreads(:default))`.

See also `BLAS.get_num_threads` and `BLAS.set_num_threads` in the [`LinearAlgebra`](@ref
man-linalg) standard library, and `nprocs()` in the [`Distributed`](@ref man-distributed)
Expand Down
28 changes: 14 additions & 14 deletions stdlib/LinearAlgebra/src/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -406,13 +406,13 @@ transpose(A::UnitLowerTriangular) = UnitUpperTriangular(transpose(A.data))
transpose(A::UnitUpperTriangular) = UnitLowerTriangular(transpose(A.data))

transpose!(A::LowerTriangular) = UpperTriangular(copytri!(A.data, 'L', false, true))
transpose!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L', false, true))
transpose!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L', false, false))
transpose!(A::UpperTriangular) = LowerTriangular(copytri!(A.data, 'U', false, true))
transpose!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U', false, true))
transpose!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U', false, false))
adjoint!(A::LowerTriangular) = UpperTriangular(copytri!(A.data, 'L' , true, true))
adjoint!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L' , true, true))
adjoint!(A::UnitLowerTriangular) = UnitUpperTriangular(copytri!(A.data, 'L' , true, false))
adjoint!(A::UpperTriangular) = LowerTriangular(copytri!(A.data, 'U' , true, true))
adjoint!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U' , true, true))
adjoint!(A::UnitUpperTriangular) = UnitLowerTriangular(copytri!(A.data, 'U' , true, false))

diag(A::LowerTriangular) = diag(A.data)
diag(A::UnitLowerTriangular) = fill(oneunit(eltype(A)), size(A,1))
Expand Down Expand Up @@ -471,7 +471,7 @@ end

function _triscale!(A::UpperTriangular, B::UpperTriangular, c::Number, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
for i = 1:j
@inbounds _modify!(_add, B.data[i,j] * c, A.data, (i,j))
Expand All @@ -481,8 +481,8 @@ function _triscale!(A::UpperTriangular, B::UpperTriangular, c::Number, _add)
end
function _triscale!(A::UpperTriangular, c::Number, B::UpperTriangular, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
for j = 1:n
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
for i = 1:j
@inbounds _modify!(_add, c * B.data[i,j], A.data, (i,j))
end
Expand All @@ -491,7 +491,7 @@ function _triscale!(A::UpperTriangular, c::Number, B::UpperTriangular, _add)
end
function _triscale!(A::UpperOrUnitUpperTriangular, B::UnitUpperTriangular, c::Number, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
@inbounds _modify!(_add, c, A, (j,j))
for i = 1:(j - 1)
Expand All @@ -502,7 +502,7 @@ function _triscale!(A::UpperOrUnitUpperTriangular, B::UnitUpperTriangular, c::Nu
end
function _triscale!(A::UpperOrUnitUpperTriangular, c::Number, B::UnitUpperTriangular, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
@inbounds _modify!(_add, c, A, (j,j))
for i = 1:(j - 1)
Expand All @@ -513,7 +513,7 @@ function _triscale!(A::UpperOrUnitUpperTriangular, c::Number, B::UnitUpperTriang
end
function _triscale!(A::LowerTriangular, B::LowerTriangular, c::Number, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
for i = j:n
@inbounds _modify!(_add, B.data[i,j] * c, A.data, (i,j))
Expand All @@ -523,8 +523,8 @@ function _triscale!(A::LowerTriangular, B::LowerTriangular, c::Number, _add)
end
function _triscale!(A::LowerTriangular, c::Number, B::LowerTriangular, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
for j = 1:n
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
for i = j:n
@inbounds _modify!(_add, c * B.data[i,j], A.data, (i,j))
end
Expand All @@ -533,7 +533,7 @@ function _triscale!(A::LowerTriangular, c::Number, B::LowerTriangular, _add)
end
function _triscale!(A::LowerOrUnitLowerTriangular, B::UnitLowerTriangular, c::Number, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
@inbounds _modify!(_add, c, A, (j,j))
for i = (j + 1):n
Expand All @@ -544,7 +544,7 @@ function _triscale!(A::LowerOrUnitLowerTriangular, B::UnitLowerTriangular, c::Nu
end
function _triscale!(A::LowerOrUnitLowerTriangular, c::Number, B::UnitLowerTriangular, _add)
n = checksquare(B)
iszero(_add.alpha) && return _rmul_or_fill!(C, _add.beta)
iszero(_add.alpha) && return _rmul_or_fill!(A, _add.beta)
for j = 1:n
@inbounds _modify!(_add, c, A, (j,j))
for i = (j + 1):n
Expand Down
15 changes: 14 additions & 1 deletion stdlib/LinearAlgebra/test/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ debug && println("Test basic type functionality")
@test LowerTriangular(randn(3, 3)) |> t -> [size(t, i) for i = 1:3] == [size(Matrix(t), i) for i = 1:3]

# The following test block tries to call all methods in base/linalg/triangular.jl in order for a combination of input element types. Keep the ordering when adding code.
for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFloat}, Int)
@testset for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFloat}, Int)
# Begin loop for first Triangular matrix
for (t1, uplo1) in ((UpperTriangular, :U),
(UnitUpperTriangular, :U),
Expand Down Expand Up @@ -239,6 +239,11 @@ for elty1 in (Float32, Float64, BigFloat, ComplexF32, ComplexF64, Complex{BigFlo
A2tmp = unitt(A1)
mul!(A1tmp, cr, A2tmp)
@test A1tmp == cr * A2tmp

A1tmp .= A1
@test mul!(A1tmp, A2tmp, cr, 0, 2) == 2A1
A1tmp .= A1
@test mul!(A1tmp, cr, A2tmp, 0, 2) == 2A1
else
A1tmp = copy(A1)
rmul!(A1tmp, ci)
Expand Down Expand Up @@ -866,4 +871,12 @@ end
end
end

@testset "transpose triangular diagonal" begin
M = Matrix{BigFloat}(undef, 2, 2);
M[1,2] = 3;
U = UnitUpperTriangular(M)
Ut = transpose(U)
@test transpose!(U) == Ut
end

end # module TestTriangular
31 changes: 28 additions & 3 deletions stdlib/Mmap/src/Mmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,43 @@ function mmap(io::IO,
mmaplen = (offset - offset_page) + len

file_desc = gethandle(io)
szfile = convert(Csize_t, len + offset)
requestedSizeLarger = false
if !(io isa Mmap.Anonymous)
@static if !Sys.isapple()
requestedSizeLarger = szfile > filesize(io)
end
end
# platform-specific mmapping
@static if Sys.isunix()
prot, flags, iswrite = settings(file_desc, shared)
iswrite && grow && grow!(io, offset, len)
if requestedSizeLarger
if iswrite
if grow
grow!(io, offset, len)
else
throw(ArgumentError("requested size $szfile larger than file size $(filesize(io)), but requested not to grow"))
end
else
throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions"))
end
end
@static if Sys.isapple()
iswrite && grow && grow!(io, offset, len)
end
# mmap the file
ptr = ccall(:jl_mmap, Ptr{Cvoid}, (Ptr{Cvoid}, Csize_t, Cint, Cint, RawFD, Int64),
C_NULL, mmaplen, prot, flags, file_desc, offset_page)
systemerror("memory mapping failed", reinterpret(Int, ptr) == -1)
else
name, readonly, create = settings(io)
szfile = convert(Csize_t, len + offset)
readonly && szfile > filesize(io) && throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions"))
if requestedSizeLarger
if readonly
throw(ArgumentError("unable to increase file size to $szfile due to read-only permissions"))
elseif !grow
throw(ArgumentError("requested size $szfile larger than file size $(filesize(io)), but requested not to grow"))
end
end
handle = create ? ccall(:CreateFileMappingW, stdcall, Ptr{Cvoid}, (OS_HANDLE, Ptr{Cvoid}, DWORD, DWORD, DWORD, Cwstring),
file_desc, C_NULL, readonly ? PAGE_READONLY : PAGE_READWRITE, szfile >> 32, szfile & typemax(UInt32), name) :
ccall(:OpenFileMappingW, stdcall, Ptr{Cvoid}, (DWORD, Cint, Cwstring),
Expand Down
53 changes: 46 additions & 7 deletions stdlib/REPL/src/REPLCompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,10 @@ function project_deps_get_completion_candidates(pkgstarts::String, project_file:
return Completion[PackageCompletion(name) for name in loading_candidates]
end

function complete_identifiers!(suggestions::Vector{Completion}, @nospecialize(ffunc::Function), context_module::Module, string::String, name::String, pos::Int, dotpos::Int, startpos::Int, comp_keywords=false)
function complete_identifiers!(suggestions::Vector{Completion}, @nospecialize(ffunc),
context_module::Module, string::String, name::String,
pos::Int, dotpos::Int, startpos::Int;
comp_keywords=false)
ex = nothing
if comp_keywords
append!(suggestions, complete_keyword(name))
Expand Down Expand Up @@ -1022,10 +1025,41 @@ function complete_identifiers!(suggestions::Vector{Completion}, @nospecialize(ff
if something(findlast(in(non_identifier_chars), s), 0) < something(findlast(isequal('.'), s), 0)
lookup_name, name = rsplit(s, ".", limit=2)
name = String(name)

ex = Meta.parse(lookup_name, raise=false, depwarn=false)
end
isexpr(ex, :incomplete) && (ex = nothing)
elseif isexpr(ex, (:using, :import))
arg1 = ex.args[1]
if isexpr(arg1, :.)
# We come here for cases like:
# - `string`: "using Mod1.Mod2.M"
# - `ex`: :(using Mod1.Mod2)
# - `name`: "M"
# Now we transform `ex` to `:(Mod1.Mod2)` to allow `complete_symbol` to
# complete for inner modules whose name starts with `M`.
# Note that `ffunc` is set to `module_filter` within `completions`
ex = nothing
firstdot = true
for arg = arg1.args
if arg === :.
# override `context_module` if multiple `.` accessors are used
if firstdot
firstdot = false
else
context_module = parentmodule(context_module)
end
elseif arg isa Symbol
if ex === nothing
ex = arg
else
ex = Expr(:., out, QuoteNode(arg))
end
else # invalid expression
ex = nothing
break
end
end
end
elseif isexpr(ex, :call) && length(ex.args) > 1
isinfix = s[end] != ')'
# A complete call expression that does not finish with ')' is an infix call.
Expand Down Expand Up @@ -1106,8 +1140,9 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
ok && return ret
startpos = first(varrange) + 4
dotpos = something(findprev(isequal('.'), string, first(varrange)-1), 0)
return complete_identifiers!(Completion[], ffunc, context_module, string,
string[startpos:pos], pos, dotpos, startpos)
name = string[startpos:pos]
return complete_identifiers!(Completion[], ffunc, context_module, string, name, pos,
dotpos, startpos)
elseif inc_tag === :cmd
# TODO: should this call shell_completions instead of partially reimplementing it?
let m = match(r"[\t\n\r\"`><=*?|]| (?!\\)", reverse(partial)) # fuzzy shell_parse in reverse
Expand Down Expand Up @@ -1255,16 +1290,20 @@ function completions(string::String, pos::Int, context_module::Module=Main, shif
end
end
end
ffunc = (mod,x)->(Base.isbindingresolved(mod, x) && isdefined(mod, x) && isa(getfield(mod, x), Module))
ffunc = module_filter
comp_keywords = false
end

startpos == 0 && (pos = -1)
dotpos < startpos && (dotpos = startpos - 1)
return complete_identifiers!(suggestions, ffunc, context_module, string,
name, pos, dotpos, startpos, comp_keywords)
return complete_identifiers!(suggestions, ffunc, context_module, string, name, pos,
dotpos, startpos;
comp_keywords)
end

module_filter(mod::Module, x::Symbol) =
Base.isbindingresolved(mod, x) && isdefined(mod, x) && isa(getglobal(mod, x), Module)

function shell_completions(string, pos)
# First parse everything up to the current position
scs = string[1:pos]
Expand Down
44 changes: 44 additions & 0 deletions stdlib/REPL/test/replcompletions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1939,3 +1939,47 @@ let s = "@issue51827 Base.ac"
@test res
@test "acquire" in c
end

# JuliaLang/julia#52922
let s = "using Base.Th"
c, r, res = test_complete_context(s)
@test res
@test "Threads" in c
end
let s = "using Base."
c, r, res = test_complete_context(s)
@test res
@test "BinaryPlatforms" in c
end
# test cases with the `.` accessor
module Issue52922
module Inner1
module Inner12 end
end
module Inner2 end
end
let s = "using .Iss"
c, r, res = test_complete_context(s)
@test res
@test "Issue52922" in c
end
let s = "using .Issue52922.Inn"
c, r, res = test_complete_context(s)
@test res
@test "Inner1" in c
end
let s = "using .Inner1.Inn"
c, r, res = test_complete_context(s, Issue52922)
@test res
@test "Inner12" in c
end
let s = "using ..Issue52922.Inn"
c, r, res = test_complete_context(s, Issue52922.Inner1)
@test res
@test "Inner2" in c
end
let s = "using ...Issue52922.Inn"
c, r, res = test_complete_context(s, Issue52922.Inner1.Inner12)
@test res
@test "Inner2" in c
end
4 changes: 4 additions & 0 deletions test/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1825,13 +1825,17 @@ end

@testset "type-based offset axes check" begin
a = randn(ComplexF64, 10)
b = randn(ComplexF64, 4, 4, 4, 4)
ta = reinterpret(Float64, a)
tb = reinterpret(Float64, view(a, 1:2:10))
tc = reinterpret(Float64, reshape(view(a, 1:3:10), 2, 2, 1))
td = view(b, :, :, 1, 1)
# Issue #44040
@test IRUtils.fully_eliminated(Base.require_one_based_indexing, Base.typesof(ta, tc))
@test IRUtils.fully_eliminated(Base.require_one_based_indexing, Base.typesof(tc, tc))
@test IRUtils.fully_eliminated(Base.require_one_based_indexing, Base.typesof(ta, tc, tb))
# Issue #49332
@test IRUtils.fully_eliminated(Base.require_one_based_indexing, Base.typesof(td, td, td))
# Ranges && CartesianIndices
@test IRUtils.fully_eliminated(Base.require_one_based_indexing, Base.typesof(1:10, Base.OneTo(10), 1.0:2.0, LinRange(1.0, 2.0, 2), 1:2:10, CartesianIndices((1:2:10, 1:2:10))))
# Remind us to call `any` in `Base.has_offset_axes` once our compiler is ready.
Expand Down