From 7759a05c0d5f0e43390c4f117c4f5ef2c4da7dda Mon Sep 17 00:00:00 2001 From: Tamme Claus Date: Tue, 28 Oct 2025 14:29:58 +0100 Subject: [PATCH 1/6] shortcut tril!, triu! and constructors from UniformScaling for empty matrices --- src/host/construction.jl | 6 ++++-- src/host/linalg.jl | 34 ++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/host/construction.jl b/src/host/construction.jl index 1a4d8f7b..9094a878 100644 --- a/src/host/construction.jl +++ b/src/host/construction.jl @@ -37,9 +37,10 @@ end function (T::Type{<: AnyGPUArray{U}})(s::UniformScaling, dims::Dims{2}) where {U} res = similar(T, dims) fill!(res, zero(U)) + if iszero(minimum(dims)) return res end kernel = identity_kernel(get_backend(res)) kernel(res, size(res, 1), s.λ; ndrange=minimum(dims)) - res + return res end (T::Type{<: AnyGPUArray})(s::UniformScaling{U}, dims::Dims{2}) where U = T{U}(s, dims) @@ -48,9 +49,10 @@ end function Base.copyto!(A::AbstractGPUMatrix{T}, s::UniformScaling) where T fill!(A, zero(T)) + if iszero(minimum(size(A))) return A end kernel = identity_kernel(get_backend(A)) kernel(A, size(A, 1), s.λ; ndrange=minimum(size(A))) - A + return A end function _one(unit::T, x::AbstractGPUMatrix) where {T} diff --git a/src/host/linalg.jl b/src/host/linalg.jl index bc910be4..128fdc6c 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -165,27 +165,29 @@ for T in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriang end function LinearAlgebra.tril!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T - @kernel function tril_kernel!(_A, _d) - I = @index(Global, Cartesian) - i, j = Tuple(I) - if i < j - _d - @inbounds _A[i, j] = zero(T) + if iszero(length(A)) return A end + @kernel function tril_kernel!(_A, _d) + I = @index(Global, Cartesian) + i, j = Tuple(I) + if i < j - _d + @inbounds _A[i, j] = zero(T) + end end - end - tril_kernel!(get_backend(A))(A, d; ndrange = size(A)) - return A + tril_kernel!(get_backend(A))(A, d; ndrange = size(A)) + return A end function LinearAlgebra.triu!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T - @kernel function triu_kernel!(_A, _d) - I = @index(Global, Cartesian) - i, j = Tuple(I) - if j < i + _d - @inbounds _A[i, j] = zero(T) + if iszero(length(A)) return A end + @kernel function triu_kernel!(_A, _d) + I = @index(Global, Cartesian) + i, j = Tuple(I) + if j < i + _d + @inbounds _A[i, j] = zero(T) + end end - end - triu_kernel!(get_backend(A))(A, d; ndrange = size(A)) - return A + triu_kernel!(get_backend(A))(A, d; ndrange = size(A)) + return A end # check if upper triangular starting from the kth superdiagonal. From b9dbacc3dd04961b6925528579c8b672ae8992ba Mon Sep 17 00:00:00 2001 From: Tamme Claus Date: Tue, 28 Oct 2025 14:30:10 +0100 Subject: [PATCH 2/6] add tests --- test/testsuite/construction.jl | 11 +++++++++++ test/testsuite/linalg.jl | 7 +++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/test/testsuite/construction.jl b/test/testsuite/construction.jl index ed42518b..22f3b0bf 100644 --- a/test/testsuite/construction.jl +++ b/test/testsuite/construction.jl @@ -188,6 +188,17 @@ @test Array(x1) ≈ x end + @testset "empty" begin + x = Matrix{T}(I, (0, 3)) + + x1 = AT{T, 2}(I, (0, 3)) + + @test Array(x1) ≈ x + + copyto!(x1, I) + @test Array(x1) ≈ x + end + @testset "JuliaGPU/GPUArrays.jl#439" begin x = AT{Float32}(I, 500, 300) y = Array{Float32}(I, 500, 300) diff --git a/test/testsuite/linalg.jl b/test/testsuite/linalg.jl index b042d940..db3de13c 100644 --- a/test/testsuite/linalg.jl +++ b/test/testsuite/linalg.jl @@ -309,8 +309,11 @@ @testset "$f! with diagonal $d" for (f, f!) in ((triu, triu!), (tril, tril!)), d in -2:2 - A = randn(Float32, 10, 10) - @test f(A, d) == Array(f!(AT(A), d)) + A = AT(randn(Float32, 10, 10)) + @test compare(f, AT, A) + + A_empty = AT(randn(Float32, 0, 0)) + @test compare(f, AT, A_empty) end end From 06c46ffb71afd899075eacf08db8cdfda8a872ad Mon Sep 17 00:00:00 2001 From: Tamme Claus Date: Tue, 28 Oct 2025 14:42:13 +0100 Subject: [PATCH 3/6] use `isempty` --- src/host/construction.jl | 2 +- src/host/linalg.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/construction.jl b/src/host/construction.jl index 9094a878..546c64ed 100644 --- a/src/host/construction.jl +++ b/src/host/construction.jl @@ -37,7 +37,7 @@ end function (T::Type{<: AnyGPUArray{U}})(s::UniformScaling, dims::Dims{2}) where {U} res = similar(T, dims) fill!(res, zero(U)) - if iszero(minimum(dims)) return res end + if isempty(res) return res end kernel = identity_kernel(get_backend(res)) kernel(res, size(res, 1), s.λ; ndrange=minimum(dims)) return res diff --git a/src/host/linalg.jl b/src/host/linalg.jl index 128fdc6c..a41dba10 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -165,7 +165,7 @@ for T in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriang end function LinearAlgebra.tril!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T - if iszero(length(A)) return A end + if isempty(A) return A end @kernel function tril_kernel!(_A, _d) I = @index(Global, Cartesian) i, j = Tuple(I) @@ -178,7 +178,7 @@ function LinearAlgebra.tril!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T end function LinearAlgebra.triu!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T - if iszero(length(A)) return A end + if isempty(A) return A end @kernel function triu_kernel!(_A, _d) I = @index(Global, Cartesian) i, j = Tuple(I) From 895036e78ca4b58e03226ac445da678c2bef9dbd Mon Sep 17 00:00:00 2001 From: Tamme Claus Date: Tue, 28 Oct 2025 14:48:29 +0100 Subject: [PATCH 4/6] test using compare --- test/testsuite/linalg.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testsuite/linalg.jl b/test/testsuite/linalg.jl index db3de13c..cd4d336d 100644 --- a/test/testsuite/linalg.jl +++ b/test/testsuite/linalg.jl @@ -307,12 +307,12 @@ @test_throws SingularException ldiv!(D, B) end - @testset "$f! with diagonal $d" for (f, f!) in ((triu, triu!), (tril, tril!)), + @testset "$f with diagonal $d" for f in (triu, triu!, tril, tril!), d in -2:2 - A = AT(randn(Float32, 10, 10)) + A = randn(Float32, 10, 10) @test compare(f, AT, A) - A_empty = AT(randn(Float32, 0, 0)) + A_empty = randn(Float32, 0, 0) @test compare(f, AT, A_empty) end end From 731e1d7f7a8e3811f0b88b6b2f213b4af156c8d3 Mon Sep 17 00:00:00 2001 From: Tamme Claus Date: Tue, 28 Oct 2025 15:28:16 +0100 Subject: [PATCH 5/6] apply suggestions & fix test --- src/host/construction.jl | 4 ++-- src/host/linalg.jl | 4 ++-- test/testsuite/construction.jl | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/host/construction.jl b/src/host/construction.jl index 546c64ed..a8da22d2 100644 --- a/src/host/construction.jl +++ b/src/host/construction.jl @@ -37,7 +37,7 @@ end function (T::Type{<: AnyGPUArray{U}})(s::UniformScaling, dims::Dims{2}) where {U} res = similar(T, dims) fill!(res, zero(U)) - if isempty(res) return res end + isempty(res) && return res kernel = identity_kernel(get_backend(res)) kernel(res, size(res, 1), s.λ; ndrange=minimum(dims)) return res @@ -49,7 +49,7 @@ end function Base.copyto!(A::AbstractGPUMatrix{T}, s::UniformScaling) where T fill!(A, zero(T)) - if iszero(minimum(size(A))) return A end + isempty(A) && return A kernel = identity_kernel(get_backend(A)) kernel(A, size(A, 1), s.λ; ndrange=minimum(size(A))) return A diff --git a/src/host/linalg.jl b/src/host/linalg.jl index a41dba10..801b2a29 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -165,7 +165,7 @@ for T in (UpperTriangular, LowerTriangular, UnitUpperTriangular, UnitLowerTriang end function LinearAlgebra.tril!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T - if isempty(A) return A end + isempty(A) && return A @kernel function tril_kernel!(_A, _d) I = @index(Global, Cartesian) i, j = Tuple(I) @@ -178,7 +178,7 @@ function LinearAlgebra.tril!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T end function LinearAlgebra.triu!(A::AbstractGPUMatrix{T}, d::Integer = 0) where T - if isempty(A) return A end + isempty(A) && return A @kernel function triu_kernel!(_A, _d) I = @index(Global, Cartesian) i, j = Tuple(I) diff --git a/test/testsuite/construction.jl b/test/testsuite/construction.jl index 22f3b0bf..0ed33933 100644 --- a/test/testsuite/construction.jl +++ b/test/testsuite/construction.jl @@ -189,12 +189,11 @@ end @testset "empty" begin - x = Matrix{T}(I, (0, 3)) - - x1 = AT{T, 2}(I, (0, 3)) + x = Matrix{Float32}(I, (0, 3)) + x1 = AT{Float32, 2}(I, (0, 3)) @test Array(x1) ≈ x - + copyto!(x1, I) @test Array(x1) ≈ x end From b99c833e5eef946fa66c8cc0b01da41da51fe6f6 Mon Sep 17 00:00:00 2001 From: Tamme Claus Date: Fri, 31 Oct 2025 10:14:21 +0100 Subject: [PATCH 6/6] Apply suggestions Co-authored-by: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> --- test/testsuite/linalg.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testsuite/linalg.jl b/test/testsuite/linalg.jl index cd4d336d..b4eea152 100644 --- a/test/testsuite/linalg.jl +++ b/test/testsuite/linalg.jl @@ -310,10 +310,10 @@ @testset "$f with diagonal $d" for f in (triu, triu!, tril, tril!), d in -2:2 A = randn(Float32, 10, 10) - @test compare(f, AT, A) + @test compare(f, AT, A, d) A_empty = randn(Float32, 0, 0) - @test compare(f, AT, A_empty) + @test compare(f, AT, A_empty, d) end end