From b939fdf38663eabf2c6a23b912de7ebe71632f5d Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Tue, 26 Aug 2025 09:39:12 -0400 Subject: [PATCH 1/4] Graceful exit for transpose/adjoint on size 0 arrays --- src/host/linalg.jl | 2 ++ test/testsuite/linalg.jl | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/host/linalg.jl b/src/host/linalg.jl index 2282528e..2f6f15d7 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -35,6 +35,8 @@ LinearAlgebra.transpose!(B::AnyGPUArray, A::AnyGPUArray) = transpose_f!(transpos LinearAlgebra.adjoint!(B::AnyGPUArray, A::AnyGPUArray) = transpose_f!(adjoint, B, A) function transpose_f!(f, B::AnyGPUMatrix{T}, A::AnyGPUMatrix{T}) where T axes(B,1) == axes(A,2) && axes(B,2) == axes(A,1) || throw(DimensionMismatch(string(f))) + # array with size zero dimension + axes(A,1) == 1:0 || axes(A, 2) == 1:0 && return B @kernel function transpose_kernel!(B, A) idx = @index(Global, Cartesian) @inbounds B[idx[2], idx[1]] = f(A[idx[1], idx[2]]) diff --git a/test/testsuite/linalg.jl b/test/testsuite/linalg.jl index 5770c85f..7ecd61a9 100644 --- a/test/testsuite/linalg.jl +++ b/test/testsuite/linalg.jl @@ -4,10 +4,14 @@ @test compare(adjoint!, AT, rand(Float32, 32, 32), rand(Float32, 32, 32)) @test compare(adjoint!, AT, rand(Float32, 1, 32), rand(Float32, 32)) @test compare(adjoint!, AT, rand(Float32, 32), rand(Float32, 1, 32)) + @test compare(adjoint!, AT, rand(Float32, 32, 0), rand(Float32, 0, 32)) + @test compare(adjoint!, AT, rand(Float32, 0, 32), rand(Float32, 32, 0)) @test compare(transpose, AT, rand(Float32, 32, 32)) @test compare(transpose!, AT, rand(Float32, 32, 32), rand(Float32, 32, 32)) @test compare(transpose!, AT, rand(Float32, 1, 32), rand(Float32, 32)) @test compare(transpose!, AT, rand(Float32, 32), rand(Float32, 1, 32)) + @test compare(transpose!, AT, rand(Float32, 32, 0), rand(Float32, 0, 32)) + @test compare(transpose!, AT, rand(Float32, 0, 32), rand(Float32, 32, 0)) @test compare((x,y)->copyto!(x, adjoint(y)), AT, rand(Float32, 32, 32), rand(Float32, 32, 32)) @test compare((x,y)->copyto!(x, transpose(y)), AT, rand(Float32, 32, 32), rand(Float32, 32, 32)) @test compare(transpose!, AT, Array{Float32}(undef, 32, 32), rand(Float32, 32, 32)) From e5e1b33cfe83361b7610244d8aa1beaa95769ed8 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Wed, 27 Aug 2025 09:18:09 -0400 Subject: [PATCH 2/4] Fix for CUDA --- src/host/linalg.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/host/linalg.jl b/src/host/linalg.jl index 2f6f15d7..ffdc3553 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -14,6 +14,7 @@ function LinearAlgebra.transpose!(B::AbstractGPUMatrix, A::AbstractGPUVector) end function LinearAlgebra.adjoint!(B::AbstractGPUVector, A::AbstractGPUMatrix) axes(B,1) == axes(A,2) && axes(A,1) == 1:1 || throw(DimensionMismatch("adjoint")) + axes(A,1) == 1:0 || axes(A, 2) == 1:0 && return B @kernel function adjoint_kernel!(B, A) idx = @index(Global, Linear) @inbounds B[idx] = adjoint(A[1, idx]) @@ -23,6 +24,7 @@ function LinearAlgebra.adjoint!(B::AbstractGPUVector, A::AbstractGPUMatrix) end function LinearAlgebra.adjoint!(B::AbstractGPUMatrix, A::AbstractGPUVector) axes(B,2) == axes(A,1) && axes(B,1) == 1:1 || throw(DimensionMismatch("adjoint")) + axes(A,1) == 1:0 || axes(A, 2) == 1:0 && return B @kernel function adjoint_kernel!(B, A) idx = @index(Global, Linear) @inbounds B[1, idx] = adjoint(A[idx]) From 3696ccd9cd7fa98fd9339fc253b941a11f80b532 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Tue, 2 Sep 2025 04:36:54 -0400 Subject: [PATCH 3/4] Use length rather than axes --- src/host/linalg.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/linalg.jl b/src/host/linalg.jl index ffdc3553..37e93122 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -14,7 +14,7 @@ function LinearAlgebra.transpose!(B::AbstractGPUMatrix, A::AbstractGPUVector) end function LinearAlgebra.adjoint!(B::AbstractGPUVector, A::AbstractGPUMatrix) axes(B,1) == axes(A,2) && axes(A,1) == 1:1 || throw(DimensionMismatch("adjoint")) - axes(A,1) == 1:0 || axes(A, 2) == 1:0 && return B + length(A) == 0 && return B @kernel function adjoint_kernel!(B, A) idx = @index(Global, Linear) @inbounds B[idx] = adjoint(A[1, idx]) @@ -24,7 +24,7 @@ function LinearAlgebra.adjoint!(B::AbstractGPUVector, A::AbstractGPUMatrix) end function LinearAlgebra.adjoint!(B::AbstractGPUMatrix, A::AbstractGPUVector) axes(B,2) == axes(A,1) && axes(B,1) == 1:1 || throw(DimensionMismatch("adjoint")) - axes(A,1) == 1:0 || axes(A, 2) == 1:0 && return B + length(A) == 0 && return B @kernel function adjoint_kernel!(B, A) idx = @index(Global, Linear) @inbounds B[1, idx] = adjoint(A[idx]) @@ -38,7 +38,7 @@ LinearAlgebra.adjoint!(B::AnyGPUArray, A::AnyGPUArray) = transpose_f!(adjoint, B function transpose_f!(f, B::AnyGPUMatrix{T}, A::AnyGPUMatrix{T}) where T axes(B,1) == axes(A,2) && axes(B,2) == axes(A,1) || throw(DimensionMismatch(string(f))) # array with size zero dimension - axes(A,1) == 1:0 || axes(A, 2) == 1:0 && return B + length(A) == 0 && return B @kernel function transpose_kernel!(B, A) idx = @index(Global, Cartesian) @inbounds B[idx[2], idx[1]] = f(A[idx[1], idx[2]]) From bee0145896a364d435ae44544fe3c750dfe39f37 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Tue, 2 Sep 2025 05:07:28 -0400 Subject: [PATCH 4/4] use isempty --- src/host/linalg.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/host/linalg.jl b/src/host/linalg.jl index 37e93122..aa8806a3 100644 --- a/src/host/linalg.jl +++ b/src/host/linalg.jl @@ -14,7 +14,7 @@ function LinearAlgebra.transpose!(B::AbstractGPUMatrix, A::AbstractGPUVector) end function LinearAlgebra.adjoint!(B::AbstractGPUVector, A::AbstractGPUMatrix) axes(B,1) == axes(A,2) && axes(A,1) == 1:1 || throw(DimensionMismatch("adjoint")) - length(A) == 0 && return B + isempty(A) && return B @kernel function adjoint_kernel!(B, A) idx = @index(Global, Linear) @inbounds B[idx] = adjoint(A[1, idx]) @@ -24,7 +24,7 @@ function LinearAlgebra.adjoint!(B::AbstractGPUVector, A::AbstractGPUMatrix) end function LinearAlgebra.adjoint!(B::AbstractGPUMatrix, A::AbstractGPUVector) axes(B,2) == axes(A,1) && axes(B,1) == 1:1 || throw(DimensionMismatch("adjoint")) - length(A) == 0 && return B + isempty(A) && return B @kernel function adjoint_kernel!(B, A) idx = @index(Global, Linear) @inbounds B[1, idx] = adjoint(A[idx]) @@ -38,7 +38,7 @@ LinearAlgebra.adjoint!(B::AnyGPUArray, A::AnyGPUArray) = transpose_f!(adjoint, B function transpose_f!(f, B::AnyGPUMatrix{T}, A::AnyGPUMatrix{T}) where T axes(B,1) == axes(A,2) && axes(B,2) == axes(A,1) || throw(DimensionMismatch(string(f))) # array with size zero dimension - length(A) == 0 && return B + isempty(A) && return B @kernel function transpose_kernel!(B, A) idx = @index(Global, Cartesian) @inbounds B[idx[2], idx[1]] = f(A[idx[1], idx[2]])