From 68306d4cb67aead3f5a24ec058e90797fb5a425f Mon Sep 17 00:00:00 2001 From: Rasmus Henningsson Date: Thu, 9 Jun 2022 16:17:08 +0200 Subject: [PATCH 1/4] Fix problems in Julia 1.7.x Julia 1.7.x introduced _goodbuffers and _checkbuffers but use them incorrectly for AbstractSparseArrays. This is fixed on 1.8, but we need a workaround in 1.7.x. Also fixed bug where copy(X'), copy(transpose(X)) and permutedims(X) didn't return ThreadedSparseMatrixCSC. --- src/ThreadedSparseArrays.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ThreadedSparseArrays.jl b/src/ThreadedSparseArrays.jl index 7aa9dee..a1d25a6 100644 --- a/src/ThreadedSparseArrays.jl +++ b/src/ThreadedSparseArrays.jl @@ -53,6 +53,16 @@ for f in [:rowvals, :nonzeros, :getcolptr] end +@static if v"1.7.0" <= VERSION < v"1.8.0-" + SparseArrays._goodbuffers(A::ThreadedSparseMatrixCSC) = SparseArrays._goodbuffers(A.A) + SparseArrays._checkbuffers(A::ThreadedSparseMatrixCSC) = SparseArrays._checkbuffers(A.A) +end + +Base.copy(A::Adjoint{<:Any,<:ThreadedSparseMatrixCSC}) = ThreadedSparseMatrixCSC(copy(A.parent.A')) +Base.copy(A::Transpose{<:Any,<:ThreadedSparseMatrixCSC}) = ThreadedSparseMatrixCSC(copy(transpose(A.parent.A))) +Base.permutedims(A::ThreadedSparseMatrixCSC, (a,b)) = ThreadedSparseMatrixCSC(permutedims(A.A, (a,b))) + + # sparse * sparse multiplications are not (currently) threaded, but we want to keep the return type for (T1,t1) in ((ThreadedSparseMatrixCSC,identity), (Adjoint{<:Any,<:ThreadedSparseMatrixCSC},adjoint), (Transpose{<:Any,<:ThreadedSparseMatrixCSC},transpose)) for (T2,t2) in ((ThreadedSparseMatrixCSC,identity), (Adjoint{<:Any,<:ThreadedSparseMatrixCSC},adjoint), (Transpose{<:Any,<:ThreadedSparseMatrixCSC},transpose)) From 3f59efccc9a43765451e8e412573bd7b6ac4dcad Mon Sep 17 00:00:00 2001 From: Rasmus Henningsson Date: Thu, 9 Jun 2022 16:22:53 +0200 Subject: [PATCH 2/4] Patch bump --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 951a6d0..4c21a9a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ThreadedSparseArrays" uuid = "59d54670-b8ac-4d81-ab7a-bb56233e17ab" authors = ["Stefanos Carlström "] -version = "0.2.1" +version = "0.2.2" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" From ae23ac5851b52a880db94c938f6411d065772c94 Mon Sep 17 00:00:00 2001 From: Rasmus Henningsson Date: Thu, 9 Jun 2022 16:49:57 +0200 Subject: [PATCH 3/4] Add missing cases for permutedims Simplify code by @eval loop for copy and permutedims. Add unit tests. --- src/ThreadedSparseArrays.jl | 8 +++++--- test/runtests.jl | 13 ++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ThreadedSparseArrays.jl b/src/ThreadedSparseArrays.jl index a1d25a6..bb81591 100644 --- a/src/ThreadedSparseArrays.jl +++ b/src/ThreadedSparseArrays.jl @@ -58,9 +58,11 @@ end SparseArrays._checkbuffers(A::ThreadedSparseMatrixCSC) = SparseArrays._checkbuffers(A.A) end -Base.copy(A::Adjoint{<:Any,<:ThreadedSparseMatrixCSC}) = ThreadedSparseMatrixCSC(copy(A.parent.A')) -Base.copy(A::Transpose{<:Any,<:ThreadedSparseMatrixCSC}) = ThreadedSparseMatrixCSC(copy(transpose(A.parent.A))) -Base.permutedims(A::ThreadedSparseMatrixCSC, (a,b)) = ThreadedSparseMatrixCSC(permutedims(A.A, (a,b))) +for (T,t) in ((ThreadedSparseMatrixCSC,identity), (Adjoint{<:Any,<:ThreadedSparseMatrixCSC},adjoint), (Transpose{<:Any,<:ThreadedSparseMatrixCSC},transpose)) + @eval Base.copy(A::$T) = ThreadedSparseMatrixCSC(copy($t($t(A).A))) + @eval Base.permutedims(A::$T, (a,b)) = ThreadedSparseMatrixCSC(permutedims($t($t(A).A), (a,b))) +end + # sparse * sparse multiplications are not (currently) threaded, but we want to keep the return type diff --git a/test/runtests.jl b/test/runtests.jl index 2053e06..9573fe4 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -66,7 +66,7 @@ rand_scalar(rng,::Type{T}) where T<:Complex = T(rand(rng,2 .^ (1:5)) + im*rand(r end - @testset "ReturnType" for op1 in [identity,adjoint,transpose], op2 in [identity,adjoint,transpose] + @testset "ReturnType_$(op1)_$(op2)" for op1 in [identity,adjoint,transpose], op2 in [identity,adjoint,transpose] rng = StableRNG(1234) A = rand_sparse(rng,Complex{Int64},10,10,0.4) B = rand_sparse(rng,Complex{Int64},10,10,0.4) @@ -82,6 +82,17 @@ rand_scalar(rng,::Type{T}) where T<:Complex = T(rand(rng,2 .^ (1:5)) + im*rand(r @test out == ref end + @testset "copy_$op" for op in [identity,adjoint,transpose] + rng = StableRNG(1234) + A = rand_sparse(rng,Complex{Int64},8,10,0.4) + out = copy(op(ThreadedSparseMatrixCSC(A))) + @test out isa ThreadedSparseMatrixCSC + @test out == op(A) + out = permutedims(op(ThreadedSparseMatrixCSC(A))) + @test out isa ThreadedSparseMatrixCSC + @test out == permutedims(op(A)) + end + N = 1000 n = 200 @testset "$T" for T in (ComplexF64, Complex{Int64}) From f60bd236185cdc9bab34598dcf673eab8b56e44e Mon Sep 17 00:00:00 2001 From: Rasmus Henningsson Date: Fri, 10 Jun 2022 08:28:24 +0200 Subject: [PATCH 4/4] Add unit test for converting to dense --- test/runtests.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 9573fe4..71283af 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -91,6 +91,10 @@ rand_scalar(rng,::Type{T}) where T<:Complex = T(rand(rng,2 .^ (1:5)) + im*rand(r out = permutedims(op(ThreadedSparseMatrixCSC(A))) @test out isa ThreadedSparseMatrixCSC @test out == permutedims(op(A)) + + out = convert(Matrix,op(ThreadedSparseMatrixCSC(A))) + @test out isa Matrix + @test out == op(A) end N = 1000