From b9da9dc1b9c02d0cecca664aa8fa88507bb1a2f4 Mon Sep 17 00:00:00 2001 From: nhz2 Date: Sun, 17 May 2026 22:31:54 -0400 Subject: [PATCH 1/2] pass through `nothing` strides --- src/adjtrans.jl | 24 ++++++++++++++++++++---- test/adjtrans.jl | 12 ++++++++++-- test/blas.jl | 20 +++++++++++++------- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/adjtrans.jl b/src/adjtrans.jl index 0501242c..eb43279b 100644 --- a/src/adjtrans.jl +++ b/src/adjtrans.jl @@ -368,11 +368,27 @@ convert(::Type{Adjoint{T,S}}, A::Adjoint) where {T,S} = Adjoint{T,S}(convert(S, convert(::Type{Transpose{T,S}}, A::Transpose) where {T,S} = Transpose{T,S}(convert(S, A.parent))::Transpose{T,S} # Strides and pointer for transposed strided arrays — but only if the elements are actually stored in memory -Base.strides(A::Adjoint{<:Real, <:AbstractVector}) = (stride(A.parent, 2), stride(A.parent, 1)) -Base.strides(A::Transpose{<:Any, <:AbstractVector}) = (stride(A.parent, 2), stride(A.parent, 1)) +function Base.strides(A::Adjoint{<:Real, <:AbstractVector}) + st = strides(A.parent) + isnothing(st) && return nothing + (st[1]*Int(length(A.parent)), st[1]) +end +function Base.strides(A::Transpose{<:Any, <:AbstractVector}) + st = strides(A.parent) + isnothing(st) && return nothing + (st[1]*Int(length(A.parent)), st[1]) +end # For matrices it's slightly faster to use reverse and avoid calling stride twice -Base.strides(A::Adjoint{<:Real, <:AbstractMatrix}) = reverse(strides(A.parent)) -Base.strides(A::Transpose{<:Any, <:AbstractMatrix}) = reverse(strides(A.parent)) +function Base.strides(A::Adjoint{<:Real, <:AbstractMatrix}) + st = strides(A.parent) + isnothing(st) && return nothing + reverse(st) +end +function Base.strides(A::Transpose{<:Any, <:AbstractMatrix}) + st = strides(A.parent) + isnothing(st) && return nothing + reverse(st) +end Base.cconvert(::Type{Ptr{T}}, A::Adjoint{<:Real, <:AbstractVecOrMat}) where {T} = Base.cconvert(Ptr{T}, A.parent) Base.cconvert(::Type{Ptr{T}}, A::Transpose{<:Any, <:AbstractVecOrMat}) where {T} = Base.cconvert(Ptr{T}, A.parent) diff --git a/test/adjtrans.jl b/test/adjtrans.jl index 3e040559..2966a1c2 100644 --- a/test/adjtrans.jl +++ b/test/adjtrans.jl @@ -571,6 +571,14 @@ end @test repr(transpose([1f0,2f0])) == "transpose(Float32[1.0, 2.0])" end +function test_no_strides(x) + @test try + strides(x) + catch e + e + end isa Union{MethodError, Nothing} +end + @testset "strided transposes" begin for t in (Adjoint, Transpose) @test strides(t(rand(3))) == (3, 1) @@ -583,8 +591,8 @@ end B = rand(3,1) @test pointer(t(B)) === pointer(B) end - @test_throws MethodError strides(Adjoint(rand(3) .+ rand(3).*im)) - @test_throws MethodError strides(Adjoint(rand(3, 2) .+ rand(3, 2).*im)) + test_no_strides(Adjoint(rand(3) .+ rand(3).*im)) + test_no_strides(Adjoint(rand(3, 2) .+ rand(3, 2).*im)) @test strides(Transpose(rand(3) .+ rand(3).*im)) == (3, 1) @test strides(Transpose(rand(3, 2) .+ rand(3, 2).*im)) == (3, 1) diff --git a/test/blas.jl b/test/blas.jl index 6cda7fbe..6d28da33 100644 --- a/test/blas.jl +++ b/test/blas.jl @@ -598,6 +598,14 @@ Base.cconvert(::Type{Ptr{T}}, A::WrappedArray{T}) where T = Base.cconvert(Ptr{T} Base.strides(A::WrappedArray) = strides(A.A) Base.elsize(::Type{WrappedArray{T,N}}) where {T,N} = Base.elsize(Array{T,N}) +function test_no_strides(x) + @test try + strides(x) + catch e + e + end isa Union{MethodError, Nothing} +end + @testset "strided interface adjtrans" begin x = WrappedArray([1, 2, 3, 4]) @test stride(x,1) == 1 @@ -617,20 +625,18 @@ Base.elsize(::Type{WrappedArray{T,N}}) where {T,N} = Base.elsize(Array{T,N}) y = WrappedArray([1+im, 2, 3, 4]) @test strides(transpose(y)) == (4,1) @test pointer(transpose(y)) == pointer(y) - @test_throws MethodError strides(y') + test_no_strides(y') @test_throws ErrorException pointer(y') B = WrappedArray([1+im 2; 3 4; 5 6]) @test strides(transpose(B)) == (3,1) @test pointer(transpose(B)) == pointer(B) - @test_throws MethodError strides(B') + test_no_strides(B') @test_throws ErrorException pointer(B') - @test_throws MethodError stride(1:5,0) - @test_throws MethodError stride(1:5,1) - @test_throws MethodError stride(1:5,2) - @test_throws MethodError strides(transpose(1:5)) - @test_throws MethodError strides((1:5)') + test_no_strides(1:5) + test_no_strides(transpose(1:5)) + test_no_strides((1:5)') @test_throws ErrorException pointer(transpose(1:5)) @test_throws ErrorException pointer((1:5)') end From b4af62a1489b0b5c340eedfa404bc54896b92ad5 Mon Sep 17 00:00:00 2001 From: nhz2 Date: Mon, 18 May 2026 15:00:49 -0400 Subject: [PATCH 2/2] define strides on transpose with Number eltype --- src/adjtrans.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/adjtrans.jl b/src/adjtrans.jl index eb43279b..3b7ded96 100644 --- a/src/adjtrans.jl +++ b/src/adjtrans.jl @@ -373,7 +373,7 @@ function Base.strides(A::Adjoint{<:Real, <:AbstractVector}) isnothing(st) && return nothing (st[1]*Int(length(A.parent)), st[1]) end -function Base.strides(A::Transpose{<:Any, <:AbstractVector}) +function Base.strides(A::Transpose{<:Number, <:AbstractVector}) st = strides(A.parent) isnothing(st) && return nothing (st[1]*Int(length(A.parent)), st[1]) @@ -384,7 +384,7 @@ function Base.strides(A::Adjoint{<:Real, <:AbstractMatrix}) isnothing(st) && return nothing reverse(st) end -function Base.strides(A::Transpose{<:Any, <:AbstractMatrix}) +function Base.strides(A::Transpose{<:Number, <:AbstractMatrix}) st = strides(A.parent) isnothing(st) && return nothing reverse(st)