Skip to content

Commit

Permalink
Support a view of a matrix as a right-hand side b
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison committed Oct 17, 2022
1 parent 3c580a2 commit 48f40a6
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 40 deletions.
1 change: 1 addition & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ Krylov.ktypeof
Krylov.kzeros
Krylov.kones
Krylov.vector_to_matrix
Krylov.matrix_to_vector
```
34 changes: 29 additions & 5 deletions src/krylov_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,13 @@ function ktypeof(v::S) where S <: AbstractVector
end

function ktypeof(v::S) where S <: SubArray
return ktypeof(v.parent)
vp = v.parent
if isa(vp, DenseMatrix)
M = typeof(vp)
return matrix_to_vector(M) # view of a row or a column of a matrix
else
return ktypeof(vp) # view of a vector
end
end

"""
Expand All @@ -228,18 +234,36 @@ end
Return the dense matrix storage type `M` related to the dense vector storage type `S`.
"""
function vector_to_matrix(::Type{S}) where S <: DenseVector
V = hasproperty(S, :body) ? S.body : S
par = V.parameters
T = hasproperty(S, :body) ? S.body : S
par = T.parameters
npar = length(par)
(2 npar 3) || error("Type $S is not supported.")
if npar == 2
M = V.name.wrapper{par[1], 2}
M = T.name.wrapper{par[1], 2}
else
M = V.name.wrapper{par[1], 2, par[3]}
M = T.name.wrapper{par[1], 2, par[3]}
end
return M
end

"""
S = matrix_to_vector(M)
Return the dense vector storage type `S` related to the dense matrix storage type `M`.
"""
function matrix_to_vector(::Type{M}) where M <: DenseMatrix
T = hasproperty(M, :body) ? M.body : M
par = T.parameters
npar = length(par)
(2 npar 3) || error("Type $M is not supported.")
if npar == 2
S = T.name.wrapper{par[1], 1}
else
S = T.name.wrapper{par[1], 1, par[3]}
end
return S
end

"""
v = kzeros(S, n)
Expand Down
6 changes: 2 additions & 4 deletions test/gpu/amd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,8 @@ include("gpu.jl")
# Krylov.@kref!(n, x, y, c, s)
# end

@testset "vector_to_matrix" begin
S = ROCVector{FC}
M2 = Krylov.vector_to_matrix(S)
@test M2 == M
@testset "conversion -- $FC" begin
test_conversion(S, M)
end

ε = eps(T)
Expand Down
5 changes: 5 additions & 0 deletions test/gpu/gpu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ function test_solver(S, M)
solver = GmresSolver(n, n, memory, S)
solve!(solver, A, b) # Test that we don't have errors
end

function test_conversion(S, M)
@test Krylov.vector_to_matrix(S) == M
@test Krylov.vector_to_matrix(M) == S
end
6 changes: 2 additions & 4 deletions test/gpu/intel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,8 @@ end
# Krylov.@kref!(n, x, y, c, s)
# end

@testset "vector_to_matrix" begin
S = oneVector{FC}
M2 = Krylov.vector_to_matrix(S)
@test M2 == M
@testset "conversion -- $FC" begin
test_conversion(S, M)
end

ε = eps(T)
Expand Down
6 changes: 2 additions & 4 deletions test/gpu/metal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,8 @@ end
# Krylov.@kref!(n, x, y, c, s)
# end

@testset "vector_to_matrix" begin
S = MtlVector{FC}
M2 = Krylov.vector_to_matrix(S)
@test M2 == M
@testset "conversion -- $FC" begin
test_conversion(S, M)
end

ε = eps(T)
Expand Down
24 changes: 20 additions & 4 deletions test/gpu/nvidia.jl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ include("gpu.jl")

for FC in (Float32, Float64, ComplexF32, ComplexF64)
S = CuVector{FC}
V = CuSparseVector{FC}
M = CuMatrix{FC}
T = real(FC)
n = 10
Expand Down Expand Up @@ -144,10 +145,8 @@ include("gpu.jl")
Krylov.@kref!(n, x, y, c, s)
end

@testset "vector_to_matrix" begin
S = CuVector{FC}
M2 = Krylov.vector_to_matrix(S)
@test M2 == M
@testset "conversion -- $FC" begin
test_conversion(S, M)
end

ε = eps(T)
Expand Down Expand Up @@ -177,5 +176,22 @@ include("gpu.jl")
@testset "solver -- $FC" begin
test_solver(S, M)
end

@testset "ktypeof -- $FC" begin
dv = S(rand(FC, 10))
b = view(dv, 4:8)
@test Krylov.ktypeof(dv) <: S
@test Krylov.ktypeof(b) <: S

dm = M(rand(FC, 10, 10))
b = view(dm, :, 4:8)
@test Krylov.ktypeof(b) <: S

sv = V(sprand(FC, 10, 0.5))
b = view(sv, 4:8)
@test Krylov.ktypeof(sv) <: S
@test Krylov.ktypeof(b) <: S
end
end
end
end
43 changes: 24 additions & 19 deletions test/test_aux.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,25 +129,21 @@

@testset "ktypeof" begin
# test ktypeof
a = rand(Float32, 10)
b = view(a, 4:8)
@test Krylov.ktypeof(a) == Vector{Float32}
@test Krylov.ktypeof(b) == Vector{Float32}

a = rand(Float64, 10)
b = view(a, 4:8)
@test Krylov.ktypeof(a) == Vector{Float64}
@test Krylov.ktypeof(b) == Vector{Float64}

a = sprand(Float32, 10, 0.5)
b = view(a, 4:8)
@test Krylov.ktypeof(a) == Vector{Float32}
@test Krylov.ktypeof(b) == Vector{Float32}

a = sprand(Float64, 10, 0.5)
b = view(a, 4:8)
@test Krylov.ktypeof(a) == Vector{Float64}
@test Krylov.ktypeof(b) == Vector{Float64}
for FC in (Float32, Float64, ComplexF32, ComplexF64)
dv = rand(FC, 10)
b = view(dv, 4:8)
@test Krylov.ktypeof(dv) == Vector{FC}
@test Krylov.ktypeof(b) == Vector{FC}

dm = rand(FC, 10, 10)
b = view(dm, :, 4:8)
@test Krylov.ktypeof(b) == Vector{FC}

sv = sprand(FC, 10, 0.5)
b = view(sv, 4:8)
@test Krylov.ktypeof(sv) == Vector{FC}
@test Krylov.ktypeof(b) == Vector{FC}
end
end

@testset "vector_to_matrix" begin
Expand All @@ -159,6 +155,15 @@
end
end

@testset "matrix_to_vector" begin
# test matrix_to_vector
for FC in (Float32, Float64, ComplexF32, ComplexF64)
M = Matrix{FC}
S = Krylov.matrix_to_vector(M)
@test S == Vector{FC}
end
end

@testset "macros" begin
# test macros
for FC (Float16, Float32, Float64, ComplexF16, ComplexF32, ComplexF64)
Expand Down

0 comments on commit 48f40a6

Please sign in to comment.