@ -24,21 +24,19 @@ include("Internals.jl")
###############################
###############################
mutable struct HYPREMatrix # <: AbstractMatrix{HYPRE_Complex}
mutable struct HYPREMatrix # <: AbstractMatrix{HYPRE_Complex}
#= c o n s t =# comm :: MPI . Comm
#= c o n s t =# ilower :: HYPRE_BigInt
#= c o n s t =# iupper :: HYPRE_BigInt
#= c o n s t =# jlower :: HYPRE_BigInt
#= c o n s t =# jupper :: HYPRE_BigInt
IJMatrix :: HYPRE_IJMatrix
IJMatrix :: HYPRE_IJMatrix
ParCSRMatrix :: HYPRE_ParCSRMatrix
ParCSRMatrix :: HYPRE_ParCSRMatrix
HYPREMatrix ( ) = new ( C_NULL , C_NULL )
end
end
mutable struct HYPREVector # <: AbstractVector{HYPRE_Complex}
function HYPREMatrix ( comm :: MPI . Comm , ilower :: Integer , iupper :: Integer ,
IJVector :: HYPRE_IJVector
jlower :: Integer = ilower , jupper :: Integer = iupper )
ParVector :: HYPRE_ParVector
HYPREVector ( ) = new ( C_NULL , C_NULL )
end
# Create a new IJMatrix, set the object type, prepare for setting values
function Internals . init_matrix ( comm :: MPI . Comm , ilower , iupper )
# Create the IJ matrix
# Create the IJ matrix
A = HYPREMatrix ( )
A = HYPREMatrix ( comm , ilower , iupper , jlower , jupper , C_NULL , C_NULL )
IJMatrixRef = Ref { HYPRE_IJMatrix } ( C_NULL )
IJMatrixRef = Ref { HYPRE_IJMatrix } ( C_NULL )
@check HYPRE_IJMatrixCreate ( comm , ilower , iupper , ilower , iupper , IJMatrixRef )
@check HYPRE_IJMatrixCreate ( comm , ilower , iupper , ilower , iupper , IJMatrixRef )
A . IJMatrix = IJMatrixRef [ ]
A . IJMatrix = IJMatrixRef [ ]
@ -51,21 +49,17 @@ function Internals.init_matrix(comm::MPI.Comm, ilower, iupper)
return A
return A
end
end
# Finalize the matrix and fetch the assembled matrix
mutable struct HYPREVector # <: AbstractVector{HYPRE_Complex}
# This should be called after setting all the values
#= c o n s t =# comm :: MPI . Comm
function Internals . assemble_matrix ( A :: HYPREMatrix )
#= c o n s t =# ilower :: HYPRE_BigInt
# Finalize after setting all values
#= c o n s t =# iupper :: HYPRE_BigInt
@check HYPRE_IJMatrixAssemble ( A . IJMatrix )
IJVector :: HYPRE_IJVector
# Fetch the assembled CSR matrix
ParVector :: HYPRE_ParVector
ParCSRMatrixRef = Ref { Ptr { Cvoid } } ( C_NULL )
@check HYPRE_IJMatrixGetObject ( A . IJMatrix , ParCSRMatrixRef )
A . ParCSRMatrix = convert ( Ptr { HYPRE_ParCSRMatrix } , ParCSRMatrixRef [ ] )
return A
end
end
function Internals . init_v ector( comm :: MPI . Comm , ilower , iupper )
function HYPREVector ( comm :: MPI . Comm , ilower :: Integer , iupper :: Integer )
# Create the IJ vector
# Create the IJ vector
b = HYPREVector ( )
b = HYPREVector ( comm , ilower , iupper , C_NULL , C_NULL )
b_ref = Ref { HYPRE_IJVector } ( C_NULL )
b_ref = Ref { HYPRE_IJVector } ( C_NULL )
@check HYPRE_IJVectorCreate ( comm , ilower , iupper , b_ref )
@check HYPRE_IJVectorCreate ( comm , ilower , iupper , b_ref )
b . IJVector = b_ref [ ]
b . IJVector = b_ref [ ]
@ -78,6 +72,18 @@ function Internals.init_vector(comm::MPI.Comm, ilower, iupper)
return b
return b
end
end
# Finalize the matrix and fetch the assembled matrix
# This should be called after setting all the values
function Internals . assemble_matrix ( A :: HYPREMatrix )
# Finalize after setting all values
@check HYPRE_IJMatrixAssemble ( A . IJMatrix )
# Fetch the assembled CSR matrix
ParCSRMatrixRef = Ref { Ptr { Cvoid } } ( C_NULL )
@check HYPRE_IJMatrixGetObject ( A . IJMatrix , ParCSRMatrixRef )
A . ParCSRMatrix = convert ( Ptr { HYPRE_ParCSRMatrix } , ParCSRMatrixRef [ ] )
return A
end
function Internals . assemble_vector ( b :: HYPREVector )
function Internals . assemble_vector ( b :: HYPREVector )
# Finalize after setting all values
# Finalize after setting all values
@check HYPRE_IJVectorAssemble ( b . IJVector )
@check HYPRE_IJVectorAssemble ( b . IJVector )
@ -89,27 +95,29 @@ function Internals.assemble_vector(b::HYPREVector)
end
end
function Internals . get_proc_rows ( b :: HYPREVector )
function Internals . get_proc_rows ( b :: HYPREVector )
jlower_ref = Ref { HYPRE_BigInt } ( )
# ilower_ref = Ref{HYPRE_BigInt}()
jupper_ref = Ref { HYPRE_BigInt } ( )
# iupper_ref = Ref{HYPRE_BigInt}()
@check HYPRE_IJVectorGetLocalRange ( b . IJVector , jlower_ref , jupper_ref )
# @check HYPRE_IJVectorGetLocalRange(b.IJVector, ilower_ref, iupper_ref)
jlower = jlower_ref [ ]
# ilower = ilower_ref[]
jupper = jupper_ref [ ]
# iupper = iupper_ref[]
return jlower , jupper
# return ilower, iupper
return b . ilower , b . iupper
end
end
function Internals . get_comm ( b :: HYPREVector )
function Internals . get_comm ( b :: HYPREVector )
# The MPI communicator is (currently) the first field of the struct:
# # The MPI communicator is (currently) the first field of the struct:
# https://github.com/hypre-space/hypre/blob/48de53e675af0e23baf61caa73d89fd9f478f453/src/IJ_mv/IJ_vector.h#L23
# # https://github.com/hypre-space/hypre/blob/48de53e675af0e23baf61caa73d89fd9f478f453/src/IJ_mv/IJ_vector.h#L23
# Fingers crossed this doesn't change!
# # Fingers crossed this doesn't change!
@assert b . IJVector != C_NULL
# @assert b.IJVector != C_NULL
comm = unsafe_load ( Ptr { MPI . Comm } ( b . IJVector ) )
# comm = unsafe_load(Ptr{MPI.Comm}(b.IJVector))
return comm
# return comm
return b . comm
end
end
function Base . zero ( b :: HYPREVector )
function Base . zero ( b :: HYPREVector )
jlower , jupper = Internals . get_proc_rows ( b )
jlower , jupper = Internals . get_proc_rows ( b )
comm = Internals . get_comm ( b )
comm = Internals . get_comm ( b )
x = Internals . init_v ector( comm , jlower , jupper )
x = HYPREV ector( comm , jlower , jupper )
# TODO All values 0 by default? Looks like it... Work in progress patch to hypre to
# TODO All values 0 by default? Looks like it... Work in progress patch to hypre to
# support IJVectorSetConstantValues analoguous to IJMatrixSetConstantValues.
# support IJVectorSetConstantValues analoguous to IJMatrixSetConstantValues.
nvalues = jupper - jlower + 1
nvalues = jupper - jlower + 1
@ -201,7 +209,7 @@ end
# TODO: Default to ilower = 1, iupper = size(B, 1)?
# TODO: Default to ilower = 1, iupper = size(B, 1)?
function HYPREMatrix ( B :: Union { SparseMatrixCSC , SparseMatrixCSR } , ilower , iupper , comm :: MPI . Comm = MPI . COMM_WORLD )
function HYPREMatrix ( B :: Union { SparseMatrixCSC , SparseMatrixCSR } , ilower , iupper , comm :: MPI . Comm = MPI . COMM_WORLD )
A = Internals . init_m atrix( comm , ilower , iupper )
A = HYPREM atrix( comm , ilower , iupper )
nrows , ncols , rows , cols , values = Internals . to_hypre_data ( B , ilower , iupper )
nrows , ncols , rows , cols , values = Internals . to_hypre_data ( B , ilower , iupper )
@check HYPRE_IJMatrixSetValues ( A . IJMatrix , nrows , ncols , rows , cols , values )
@check HYPRE_IJMatrixSetValues ( A . IJMatrix , nrows , ncols , rows , cols , values )
Internals . assemble_matrix ( A )
Internals . assemble_matrix ( A )
@ -222,7 +230,7 @@ end
# TODO: Default to ilower = 1, iupper = length(x)?
# TODO: Default to ilower = 1, iupper = length(x)?
function HYPREVector ( x :: Vector , ilower , iupper , comm = MPI . COMM_WORLD )
function HYPREVector ( x :: Vector , ilower , iupper , comm = MPI . COMM_WORLD )
b = Internals . init_v ector( comm , ilower , iupper )
b = HYPREV ector( comm , ilower , iupper )
nvalues , indices , values = Internals . to_hypre_data ( x , ilower , iupper )
nvalues , indices , values = Internals . to_hypre_data ( x , ilower , iupper )
@check HYPRE_IJVectorSetValues ( b . IJVector , nvalues , indices , values )
@check HYPRE_IJVectorSetValues ( b . IJVector , nvalues , indices , values )
Internals . assemble_vector ( b )
Internals . assemble_vector ( b )
@ -360,7 +368,7 @@ function HYPREMatrix(B::PSparseMatrix)
# Fetch rows owned by this process
# Fetch rows owned by this process
ilower , iupper = Internals . get_proc_rows ( B )
ilower , iupper = Internals . get_proc_rows ( B )
# Create the IJ matrix
# Create the IJ matrix
A = Internals . init_m atrix( comm , ilower , iupper )
A = HYPREM atrix( comm , ilower , iupper )
# Set all the values
# Set all the values
map_parts ( B . values , B . rows . partition , B . cols . partition ) do Bv , Br , Bc
map_parts ( B . values , B . rows . partition , B . cols . partition ) do Bv , Br , Bc
nrows , ncols , rows , cols , values = Internals . to_hypre_data ( Bv , Br , Bc )
nrows , ncols , rows , cols , values = Internals . to_hypre_data ( Bv , Br , Bc )
@ -382,7 +390,7 @@ function HYPREVector(v::PVector)
# Fetch rows owned by this process
# Fetch rows owned by this process
ilower , iupper = Internals . get_proc_rows ( v )
ilower , iupper = Internals . get_proc_rows ( v )
# Create the IJ vector
# Create the IJ vector
b = Internals . init_v ector( comm , ilower , iupper )
b = HYPREV ector( comm , ilower , iupper )
# Set all the values
# Set all the values
map_parts ( v . values , v . owned_values , v . rows . partition ) do _ , vo , vr
map_parts ( v . values , v . owned_values , v . rows . partition ) do _ , vo , vr
ilower_part = vr . lid_to_gid [ vr . oid_to_lid . start ]
ilower_part = vr . lid_to_gid [ vr . oid_to_lid . start ]