From ffbb51f5f9f06a9ecc755d026a4e747ef2fd28d8 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Wed, 23 Mar 2022 15:00:02 +0100 Subject: [PATCH 01/40] new wrappers such as VecCopy, MatMultAdd etc --- src/PetscWrap.jl | 4 +++ src/fancy/mat.jl | 9 ++++++ src/fancy/vec.jl | 75 ++++++++++++++++++++++++++---------------------- src/mat.jl | 18 ++++++++++-- src/vec.jl | 65 ++++++++++++++++++++++++++++++++--------- 5 files changed, 122 insertions(+), 49 deletions(-) diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 2dc9b20..67e046b 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -48,6 +48,7 @@ export PetscVec, CVec, VecAssemble, VecAssemblyBegin, VecAssemblyEnd, + VecCopy, VecCreate, VecDestroy, VecDuplicate, @@ -56,6 +57,7 @@ export PetscVec, CVec, VecGetOwnershipRange, VecGetSize, VecRestoreArray, + VecScale, VecSetFromOptions, VecSetSizes, VecSetUp, @@ -80,6 +82,7 @@ export PetscMat, CMat, MatGetType, MatMPIAIJSetPreallocation, MatMult, + MatMultAdd, MatSeqAIJSetPreallocation, MatSetFromOptions, MatSetSizes, @@ -123,6 +126,7 @@ export create_composite_add, create_matrix, mat2file, preallocate!, + set_value!, set_values! include("fancy/ksp.jl") diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 0ddd4e7..0767d2b 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -87,6 +87,15 @@ function assemble!(mat::PetscMat, type::MatAssemblyType = MAT_FINAL_ASSEMBLY) MatAssemblyEnd(mat, type) end +""" + set_value!(mat::PetscMat, I, J, V, mode = ADD_VALUES) + +Set value of `mat` +`mat[i, j] = v`. +""" +set_value!(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode = ADD_VALUES) = MatSetValue(mat, i - 1, j - 1, v, mode) +set_value!(mat, i, j, v, mode = ADD_VALUES) = set_value!(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) + """ set_values!(mat::PetscMat, I, J, V, mode = ADD_VALUES) diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index 629a7cc..de2c504 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -1,4 +1,16 @@ +function Base.:*(x::PetscVec, alpha::Number) + y = VecCopy(x) + scale!(y, alpha) + return y +end +Base.:*(alpha::Number, vec::PetscVec) = vec * alpha + +function assemble!(vec::PetscVec) + VecAssemblyBegin(vec) + VecAssemblyEnd(vec) +end + """ create_vector(nrows, nrows_loc = PETSC_DECIDE) @@ -16,31 +28,10 @@ function create_vector(nrows, nrows_loc = PETSC_DECIDE; auto_setup = false, comm return vec end -Base.ndims(::Type{PetscVec}) = 1 - -""" - Base.setindex!(vec::PetscVec, value::Number, row::Integer) - -`row` must be in [1,size(vec)], i.e indexing starts at 1 (Julia). +destroy!(vec::PetscVec) = VecDestroy(vec) -# Implementation -For some unkwnown reason, calling `VecSetValue` fails. -""" -function Base.setindex!(vec::PetscVec, value::Number, row::Integer) - VecSetValues(vec, PetscInt[row .- 1], PetscScalar[value], INSERT_VALUES) -end - - -# This is stupid but I don't know how to do better yet -Base.setindex!(vec::PetscVec, values, rows) = VecSetValues(vec, collect(rows .- 1), values, INSERT_VALUES) - - -set_global_size!(vec::PetscVec, nrows) = VecSetSizes(vec, PETSC_DECIDE, nrows) -set_local_size!(vec::PetscVec, nrows) = VecSetSizes(vec, nrows, PETSC_DECIDE) - -set_from_options!(vec::PetscVec) = VecSetFromOptions(vec) - -set_up!(vec::PetscVec) = VecSetUp(vec) +duplicate(vec::PetscVec) = VecDuplicate(vec) +duplicate(vec::PetscVec, n::Int) = ntuple(i -> VecDuplicate(vec), n) """ get_range(vec::PetscVec) @@ -66,20 +57,36 @@ function get_urange(vec::PetscVec) return rstart+1:rend end +Base.ndims(::Type{PetscVec}) = 1 -# Discutable choice -Base.length(vec::PetscVec) = VecGetLocalSize(vec) -Base.size(vec::PetscVec) = (length(vec),) +scale!(vec::PetscVec, alpha::Number) = VecScale(vec, alpha) -function assemble!(vec::PetscVec) - VecAssemblyBegin(vec) - VecAssemblyEnd(vec) +""" + Base.setindex!(vec::PetscVec, value::Number, row::Integer) + +`row` must be in [1,size(vec)], i.e indexing starts at 1 (Julia). + +# Implementation +For some unkwnown reason, calling `VecSetValue` fails. +""" +function Base.setindex!(vec::PetscVec, value::Number, row::Integer) + VecSetValues(vec, PetscInt[row .- 1], PetscScalar[value], INSERT_VALUES) end -duplicate(vec::PetscVec) = VecDuplicate(vec) +# This is stupid but I don't know how to do better yet +Base.setindex!(vec::PetscVec, values, rows) = VecSetValues(vec, collect(rows .- 1), values, INSERT_VALUES) + +set_from_options!(vec::PetscVec) = VecSetFromOptions(vec) + +set_global_size!(vec::PetscVec, nrows) = VecSetSizes(vec, PETSC_DECIDE, nrows) +set_local_size!(vec::PetscVec, nrows) = VecSetSizes(vec, nrows, PETSC_DECIDE) + +set_up!(vec::PetscVec) = VecSetUp(vec) set_values!(vec::PetscVec, values) = VecSetValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) +Base.show(::IO, vec::PetscVec) = VecView(vec) + """ vec2array(vec::PetscVec) @@ -105,6 +112,6 @@ function vec2file(vec::PetscVec, filename::String, format::PetscViewerFormat = P destroy!(viewer) end -Base.show(::IO, vec::PetscVec) = VecView(vec) - -destroy!(vec::PetscVec) = VecDestroy(vec) \ No newline at end of file +# Discutable choice(s) +Base.length(vec::PetscVec) = VecGetLocalSize(vec) +Base.size(vec::PetscVec) = (length(vec),) \ No newline at end of file diff --git a/src/mat.jl b/src/mat.jl index b87b7c8..f25e47e 100644 --- a/src/mat.jl +++ b/src/mat.jl @@ -176,7 +176,7 @@ end MatGetType(mat::PetscMat) Wrapper to `MatGetType`. Return the matrix type as a string. See matrix types here: -https://petsc.org/release/docs/manualpages/Mat/MatType.html#MatType +https://petsc.org/release/docs/manualpages/Mat/MatType.html """ function MatGetType(mat::PetscMat) type = Ref{Cstring}() @@ -191,13 +191,27 @@ end """ MatMult(mat::PetscMat, x::PetscVec, y::PetscVec) -Wrapper to `MatMult` +Wrapper to `MatMult`. Computes `y = Ax` + +https://petsc.org/main/docs/manualpages/Mat/MatMult.html """ function MatMult(mat::PetscMat, x::PetscVec, y::PetscVec) error = ccall((:MatMult, libpetsc), PetscErrorCode, (CMat, CVec, CVec), mat, x, y) @assert iszero(error) end +""" + MatMultAdd(A::PetscMat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + +Wrapper to `MatMultAdd`. Computes `v3 = v2 + A * v1`. + +https://petsc.org/main/docs/manualpages/Mat/MatMultAdd.html +""" +function MatMultAdd(A::PetscMat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + error = ccall((:MatMultAdd, libpetsc), PetscErrorCode, (CMat, CVec, CVec, CVec), A, v1, v2, v3) + @assert iszero(error) +end + """ MatSetFromOptions(mat::PetscMat) diff --git a/src/vec.jl b/src/vec.jl index fbac20f..bda97f9 100644 --- a/src/vec.jl +++ b/src/vec.jl @@ -10,6 +10,29 @@ end # allows us to pass PetscVec objects directly into CVec ccall signatures Base.cconvert(::Type{CVec}, vec::PetscVec) = vec.ptr[] +""" + VecCopy(x::PetscVec, y::PetscVec) + +Wrapper to `VecCopy`. + +https://petsc.org/main/docs/manualpages/Vec/VecCopy.html +""" +function VecCopy(x::PetscVec, y::PetscVec) + error = ccall((:VecCopy, libpetsc), PetscErrorCode, (CVec, CVec), x, y) + @assert iszero(error) +end + +""" + VecCopy(x::PetscVec) + +Wrapper to `VecCopy`, expect that `y` is first obtained by `VecDuplicate` +""" +function VecCopy(x::PetscVec) + y = VecDuplicate(x) + VecCopy(x,y) + return y +end + """ VecCreate(comm::MPI.Comm, vec::PetscVec) @@ -22,6 +45,21 @@ function VecCreate(comm::MPI.Comm = MPI.COMM_WORLD) return vec end +""" + VecDuplicate(vec::PetscVec) + +Wrapper for VecDuplicate, except that it returns the new vector instead of taking it as an input. + +https://petsc.org/main/docs/manualpages/Vec/VecDuplicate.html +""" +function VecDuplicate(vec::PetscVec) + x = PetscVec(vec.comm) + error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), vec, x.ptr) + @assert iszero(error) + + return x +end + """ VecSetValue(vec::PetscVec, i::PetscInt, v::PetscScalar, mode::InsertMode = INSERT_VALUES) @@ -165,19 +203,6 @@ function VecAssemblyEnd(vec::PetscVec) @assert iszero(error) end -""" - VecDuplicate(vec::PetscVec) - -Wrapper for VecDuplicate, except that it returns the new vector instead of taking it as an input. -""" -function VecDuplicate(vec::PetscVec) - x = PetscVec(vec.comm) - error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), vec, x.ptr) - @assert iszero(error) - - return x -end - """ VecGetArray(vec::PetscVec, own = false) @@ -216,6 +241,20 @@ function VecRestoreArray(vec::PetscVec, array_ref) @assert iszero(error) end +""" + VecScale(vec::PetscVec, alpha::PetscScalar) + +Wrapper for `VecScale` + +https://petsc.org/main/docs/manualpages/Vec/VecScale.html +""" +function VecScale(vec::PetscVec, alpha::PetscScalar) + error = ccall((:VecScale, libpetsc), PetscErrorCode, (CVec, PetscScalar), vec, alpha) + @assert iszero(error) +end + +VecScale(vec::PetscVec, alpha::Number) = VecScale(vec, PetscScalar(alpha)) + """ VecView(vec::PetscVec, viewer::PetscViewer = PetscViewerStdWorld()) From fe2dd33826887aaf765ad76350dd6f2573c2a137 Mon Sep 17 00:00:00 2001 From: bmxam Date: Fri, 6 Jan 2023 15:27:59 +0100 Subject: [PATCH 02/40] Project.toml and doc with julia 1.8 --- .github/workflows/Documentation.yml | 6 +++--- Project.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml index 2d76bf2..3594060 100644 --- a/.github/workflows/Documentation.yml +++ b/.github/workflows/Documentation.yml @@ -4,7 +4,7 @@ on: push: branches: - master - tags: '*' + tags: "*" pull_request: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@latest with: - version: '1.5' + version: "1.8" - name: Install dependencies run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' - name: Build and deploy @@ -23,4 +23,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key DOC_DEPLOYMENT: true # Workaround to avoid finding PETSc location - run: julia --project=docs/ docs/make.jl \ No newline at end of file + run: julia --project=docs/ docs/make.jl diff --git a/Project.toml b/Project.toml index 49fb943..c651b7b 100644 --- a/Project.toml +++ b/Project.toml @@ -10,4 +10,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] MPI = "0.16, 0.17, 0.18, 0.19" -julia = "1.5" +julia = "1.5, 1.6, 1.7, 1.8" From e950a0c0967720637ff859d1263e4c88f16b6f04 Mon Sep 17 00:00:00 2001 From: bmxam Date: Fri, 6 Jan 2023 15:30:40 +0100 Subject: [PATCH 03/40] applied formatter --- example/linear_system.jl | 6 +- example/linear_system_fancy.jl | 8 +- src/PetscWrap.jl | 180 ++++++++++++++++----------------- src/const_arch_dep.jl | 8 +- src/const_arch_ind.jl | 74 +++++++------- src/fancy/mat.jl | 30 +++--- src/fancy/vec.jl | 8 +- src/fancy/viewer.jl | 2 +- src/init.jl | 12 +-- src/ksp.jl | 2 +- src/load.jl | 18 ++-- src/mat.jl | 33 +++--- src/viewer.jl | 10 +- test/linear_system.jl | 178 ++++++++++++++++---------------- test/linear_system_fancy.jl | 172 +++++++++++++++---------------- test/misc.jl | 100 +++++++++--------- test/runtests.jl | 2 +- 17 files changed, 424 insertions(+), 419 deletions(-) diff --git a/example/linear_system.jl b/example/linear_system.jl index 8670ad3..159720b 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -22,7 +22,7 @@ PetscInitialize() # Number of mesh points and mesh step n = 11 -Δx = 1. / (n - 1) +Δx = 1.0 / (n - 1) # Create a matrix and a vector (you can specify the MPI communicator if you want) A = MatCreate() @@ -54,11 +54,11 @@ VecSetValues(b, collect(b_start:b_end-1), 2 * ones(n_loc)) # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. A_start, A_end = MatGetOwnershipRange(A) for i in A_start:A_end-1 - MatSetValues(A, [i], [i-1, i], [-1. 1.] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) + MatSetValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) end # Set boundary condition (only the proc handling index `0` is acting) -(b_start == 0) && VecSetValue(b, 0, 0.) +(b_start == 0) && VecSetValue(b, 0, 0.0) # Assemble matrices MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY) diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index 5cb704b..9b59048 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -22,7 +22,7 @@ PetscInitialize() # Number of mesh points and mesh step n = 11 -Δx = 1. / (n - 1) +Δx = 1.0 / (n - 1) # Create a matrix of size `(n,n)` and a vector of size `(n)` A = create_matrix(n, n) @@ -49,11 +49,11 @@ b[b_start:b_end] = 2 * ones(n_loc) # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. A_start, A_end = get_range(A) for i in A_start:A_end - A[i, i-1:i] = [-1. 1.] / Δx + A[i, i-1:i] = [-1.0 1.0] / Δx end # Set boundary condition (only the proc handling index `1` is acting) -(b_start == 1) && (b[1] = 0.) +(b_start == 1) && (b[1] = 0.0) # Assemble matrice and vector assemble!(A) @@ -79,7 +79,7 @@ destroy!(b) destroy!(x) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: -M = create_matrix(3,3; auto_setup = true) +M = create_matrix(3, 3; auto_setup=true) M_start, M_end = get_range(M) I = [1, 1, 1, 2, 3] J = [1, 3, 1, 3, 2] diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 67e046b..b348481 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -9,14 +9,14 @@ using Libdl using MPI include("const_arch_ind.jl") -export PetscErrorCode, PETSC_DECIDE +export PetscErrorCode, PETSC_DECIDE # export all items of some enums for item in Iterators.flatten(( instances(InsertMode), instances(MatAssemblyType), instances(PetscViewerFormat), instances(PetscFileMode), - )) +)) @eval export $(Symbol(item)) end @@ -30,108 +30,108 @@ include("init.jl") export PetscInitialize, PetscFinalize include("viewer.jl") -export PetscViewer, CViewer, - PetscViewerASCIIOpen, - PetscViewerCreate, - PetscViewerDestroy, - PetscViewerFileSetMode, - PetscViewerFileSetName, - PetscViewerHDF5Open, - PetscViewerPopFormat, - PetscViewerPushFormat, - PetscViewerSetType, - PetscViewerStdWorld, - PetscViewerView +export PetscViewer, CViewer, + PetscViewerASCIIOpen, + PetscViewerCreate, + PetscViewerDestroy, + PetscViewerFileSetMode, + PetscViewerFileSetName, + PetscViewerHDF5Open, + PetscViewerPopFormat, + PetscViewerPushFormat, + PetscViewerSetType, + PetscViewerStdWorld, + PetscViewerView include("vec.jl") -export PetscVec, CVec, - VecAssemble, - VecAssemblyBegin, - VecAssemblyEnd, - VecCopy, - VecCreate, - VecDestroy, - VecDuplicate, - VecGetArray, - VecGetLocalSize, - VecGetOwnershipRange, - VecGetSize, - VecRestoreArray, - VecScale, - VecSetFromOptions, - VecSetSizes, - VecSetUp, - VecSetValue, - VecSetValues, - VecView +export PetscVec, CVec, + VecAssemble, + VecAssemblyBegin, + VecAssemblyEnd, + VecCopy, + VecCreate, + VecDestroy, + VecDuplicate, + VecGetArray, + VecGetLocalSize, + VecGetOwnershipRange, + VecGetSize, + VecRestoreArray, + VecScale, + VecSetFromOptions, + VecSetSizes, + VecSetUp, + VecSetValue, + VecSetValues, + VecView include("mat.jl") -export PetscMat, CMat, - MatAssemble, - MatAssemblyBegin, - MatAssemblyEnd, - MatCreate, - MatCreateComposite, - MatCreateDense, - MatCreateVecs, - MatDestroy, - MatGetLocalSize, - MatGetOwnershipRange, - MatGetOwnershipRangeColumn, - MatGetSize, - MatGetType, - MatMPIAIJSetPreallocation, - MatMult, - MatMultAdd, - MatSeqAIJSetPreallocation, - MatSetFromOptions, - MatSetSizes, - MatSetUp, - MatSetValue, - MatSetValues, - MatView +export PetscMat, CMat, + MatAssemble, + MatAssemblyBegin, + MatAssemblyEnd, + MatCreate, + MatCreateComposite, + MatCreateDense, + MatCreateVecs, + MatDestroy, + MatGetLocalSize, + MatGetOwnershipRange, + MatGetOwnershipRangeColumn, + MatGetSize, + MatGetType, + MatMPIAIJSetPreallocation, + MatMult, + MatMultAdd, + MatSeqAIJSetPreallocation, + MatSetFromOptions, + MatSetSizes, + MatSetUp, + MatSetValue, + MatSetValues, + MatView include("ksp.jl") -export PetscKSP, CKSP, - KSPCreate, - KSPDestroy, - KSPSetFromOptions, - KSPSetOperators, - KSPSetUp, - KSPSolve +export PetscKSP, CKSP, + KSPCreate, + KSPDestroy, + KSPSetFromOptions, + KSPSetOperators, + KSPSetUp, + KSPSolve # fancy include("fancy/viewer.jl") -export destroy!, - push_format!, - set_mode!, - set_name!, - set_type! +export destroy!, + push_format!, + set_mode!, + set_name!, + set_type! include("fancy/vec.jl") -export assemble!, - create_vector, - destroy!, - duplicate, - get_range, - get_urange, - set_local_size!, set_global_size!, - set_from_options!, - set_up!, - vec2array, - vec2file +export assemble!, + create_vector, + destroy!, + duplicate, + get_range, + get_urange, + set_local_size!, set_global_size!, + set_from_options!, + set_up!, + vec2array, + vec2file include("fancy/mat.jl") -export create_composite_add, - create_matrix, - mat2file, - preallocate!, - set_value!, - set_values! +export create_composite_add, + create_matrix, + mat2file, + preallocate!, + set_value!, + set_values! include("fancy/ksp.jl") -export create_ksp, - solve, solve!, - set_operators! +export create_ksp, + solve, solve!, + set_operators! end \ No newline at end of file diff --git a/src/const_arch_dep.jl b/src/const_arch_dep.jl index 7d174f2..8a89def 100644 --- a/src/const_arch_dep.jl +++ b/src/const_arch_dep.jl @@ -8,8 +8,8 @@ function DataTypeFromString(name::AbstractString) dtype_ref = Ref{PetscDataType}() found_ref = Ref{PetscBool}() ccall((:PetscDataTypeFromString, libpetsc), PetscErrorCode, - (Cstring, Ptr{PetscDataType}, Ptr{PetscBool}), - name, dtype_ref, found_ref) + (Cstring, Ptr{PetscDataType}, Ptr{PetscBool}), + name, dtype_ref, found_ref) @assert found_ref[] == PETSC_TRUE return dtype_ref[] end @@ -20,8 +20,8 @@ end function PetscDataTypeGetSize(dtype::PetscDataType) datasize_ref = Ref{Csize_t}() ccall((:PetscDataTypeGetSize, libpetsc), PetscErrorCode, - (PetscDataType, Ptr{Csize_t}), - dtype, datasize_ref) + (PetscDataType, Ptr{Csize_t}), + dtype, datasize_ref) return datasize_ref[] end diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index 2c5ea75..544391b 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -4,7 +4,7 @@ const PetscErrorCode = Cint const PETSC_DEFAULT = -2 -const PETSC_DECIDE = -1 +const PETSC_DECIDE = -1 """ Macro to automatically export all items of an enum @@ -14,34 +14,34 @@ macro exported_enum(name, args...) @enum($name, $(args...)) export $name $([:(export $arg) for arg in args]...) - end) + end) end @enum PetscBool PETSC_FALSE PETSC_TRUE @enum PetscDataType begin - PETSC_DATATYPE_UNKNOWN = 0 - PETSC_DOUBLE = 1 - PETSC_COMPLEX = 2 - PETSC_LONG = 3 - PETSC_SHORT = 4 - PETSC_FLOAT = 5 - PETSC_CHAR = 6 - PETSC_BIT_LOGICAL = 7 - PETSC_ENUM = 8 - PETSC_BOOL = 9 - PETSC_FLOAT128 = 10 - PETSC_OBJECT = 11 - PETSC_FUNCTION = 12 - PETSC_STRING = 13 - PETSC___FP16 = 14 - PETSC_STRUCT = 15 - PETSC_INT = 16 - PETSC_INT64 = 17 + PETSC_DATATYPE_UNKNOWN = 0 + PETSC_DOUBLE = 1 + PETSC_COMPLEX = 2 + PETSC_LONG = 3 + PETSC_SHORT = 4 + PETSC_FLOAT = 5 + PETSC_CHAR = 6 + PETSC_BIT_LOGICAL = 7 + PETSC_ENUM = 8 + PETSC_BOOL = 9 + PETSC_FLOAT128 = 10 + PETSC_OBJECT = 11 + PETSC_FUNCTION = 12 + PETSC_STRING = 13 + PETSC___FP16 = 14 + PETSC_STRUCT = 15 + PETSC_INT = 16 + PETSC_INT64 = 17 end -const Petsc64bitInt = Int64 +const Petsc64bitInt = Int64 const PetscLogDouble = Cdouble @enum InsertMode begin @@ -70,12 +70,12 @@ end end @enum MatFactorType begin - MAT_FACTOR_NONE = 0 - MAT_FACTOR_LU = 1 + MAT_FACTOR_NONE = 0 + MAT_FACTOR_LU = 1 MAT_FACTOR_CHOLESKY = 2 - MAT_FACTOR_ILU = 3 - MAT_FACTOR_ICC = 4 - MAT_FACTOR_ILUDT = 5 + MAT_FACTOR_ILU = 3 + MAT_FACTOR_ICC = 4 + MAT_FACTOR_ILUDT = 5 end @enum MatOption begin @@ -159,15 +159,15 @@ end end @enum MatOperation begin - MATOP_SET_VALUES=0 - MATOP_GET_ROW=1 - MATOP_RESTORE_ROW=2 - MATOP_MULT=3 - MATOP_MULT_ADD=4 - MATOP_MULT_TRANSPOSE=5 - MATOP_MULT_TRANSPOSE_ADD=6 - MATOP_SOLVE=7 - MATOP_SOLVE_ADD=8 - MATOP_SOLVE_TRANSPOSE=9 - MATOP_SOLVE_TRANSPOSE_ADD=10 + MATOP_SET_VALUES = 0 + MATOP_GET_ROW = 1 + MATOP_RESTORE_ROW = 2 + MATOP_MULT = 3 + MATOP_MULT_ADD = 4 + MATOP_MULT_TRANSPOSE = 5 + MATOP_MULT_TRANSPOSE_ADD = 6 + MATOP_SOLVE = 7 + MATOP_SOLVE_ADD = 8 + MATOP_SOLVE_TRANSPOSE = 9 + MATOP_SOLVE_TRANSPOSE_ADD = 10 end \ No newline at end of file diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 71ef7cc..216ca5f 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -5,12 +5,12 @@ For some unkwnown reason, calling `MatSetValue` fails. """ function Base.setindex!(mat::PetscMat, value::Number, row::Integer, col::Integer) - MatSetValues(mat, PetscInt[row - 1], PetscInt[col - 1], PetscScalar[value], INSERT_VALUES) + MatSetValues(mat, PetscInt[row-1], PetscInt[col-1], PetscScalar[value], INSERT_VALUES) end # This is stupid but I don't know how to do better yet -Base.setindex!(mat::PetscMat, values, row::Integer, cols) = MatSetValues(mat, [row-1], collect(cols) .- 1, values, INSERT_VALUES) -Base.setindex!(mat::PetscMat, values, rows, col::Integer) = MatSetValues(mat, collect(rows) .- 1, [col-1], values, INSERT_VALUES) +Base.setindex!(mat::PetscMat, values, row::Integer, cols) = MatSetValues(mat, [row - 1], collect(cols) .- 1, values, INSERT_VALUES) +Base.setindex!(mat::PetscMat, values, rows, col::Integer) = MatSetValues(mat, collect(rows) .- 1, [col - 1], values, INSERT_VALUES) Base.ndims(::Type{PetscMat}) = 2 @@ -21,7 +21,7 @@ Create a `PetscMat` matrix of global size `(nrows, ncols)`. Use `auto_setup = true` to immediatly call `set_from_options!` and `set_up!`. """ -function create_matrix(nrows, ncols, nrows_loc = PETSC_DECIDE, ncols_loc = PETSC_DECIDE; auto_setup = false, comm::MPI.Comm = MPI.COMM_WORLD) +function create_matrix(nrows, ncols, nrows_loc=PETSC_DECIDE, ncols_loc=PETSC_DECIDE; auto_setup=false, comm::MPI.Comm=MPI.COMM_WORLD) mat = MatCreate() MatSetSizes(mat::PetscMat, nrows_loc, ncols_loc, nrows, ncols) @@ -38,7 +38,7 @@ Wrapper to `MatCreateComposite` using the "alternative construction" from the PE function create_composite_add(matrices) N, M = MatGetSize(matrices[1]) n, m = MatGetLocalSize(matrices[1]) - mat = create_matrix(N, M, n, m; auto_setup = false, comm = matrices[1].comm) + mat = create_matrix(N, M, n, m; auto_setup=false, comm=matrices[1].comm) MatSetType(mat, "composite") for m in matrices MatCompositeAddMat(mat, m) @@ -82,7 +82,7 @@ end """ Wrapper to `MatAssemblyBegin` and `MatAssemblyEnd` successively. """ -function assemble!(mat::PetscMat, type::MatAssemblyType = MAT_FINAL_ASSEMBLY) +function assemble!(mat::PetscMat, type::MatAssemblyType=MAT_FINAL_ASSEMBLY) MatAssemblyBegin(mat, type) MatAssemblyEnd(mat, type) end @@ -93,8 +93,8 @@ end Set value of `mat` `mat[i, j] = v`. """ -set_value!(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode = ADD_VALUES) = MatSetValue(mat, i - 1, j - 1, v, mode) -set_value!(mat, i, j, v, mode = ADD_VALUES) = set_value!(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) +set_value!(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode=ADD_VALUES) = MatSetValue(mat, i - 1, j - 1, v, mode) +set_value!(mat, i, j, v, mode=ADD_VALUES) = set_value!(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) """ set_values!(mat::PetscMat, I, J, V, mode = ADD_VALUES) @@ -102,26 +102,26 @@ set_value!(mat, i, j, v, mode = ADD_VALUES) = set_value!(mat, PetscInt(i), Petsc Set values of `mat` in `SparseArrays` fashion : using COO format: `mat[I[k], J[k]] = V[k]`. """ -function set_values!(mat::PetscMat, I::Vector{PetscInt}, J::Vector{PetscInt}, V::Vector{PetscScalar}, mode = ADD_VALUES) - for (i,j,v) in zip(I, J, V) +function set_values!(mat::PetscMat, I::Vector{PetscInt}, J::Vector{PetscInt}, V::Vector{PetscScalar}, mode=ADD_VALUES) + for (i, j, v) in zip(I, J, V) MatSetValue(mat, i - PetscIntOne, j - PetscIntOne, v, mode) end end -set_values!(mat, I, J, V, mode = ADD_VALUES) = set_values!(mat, PetscInt.(I), PetscInt.(J), PetscScalar.(V), mode) +set_values!(mat, I, J, V, mode=ADD_VALUES) = set_values!(mat, PetscInt.(I), PetscInt.(J), PetscScalar.(V), mode) # Warning : cannot use Vector{Integer} because `[1, 2] isa Vector{Integer}` is `false` _preallocate!(mat::PetscMat, dnz::Integer, onz::Integer, ::Val{:mpiaij}) = MatMPIAIJSetPreallocation(mat, PetscInt(dnz), PetscInt(onz)) -_preallocate!(mat::PetscMat, d_nnz::Vector{I}, o_nnz::Vector{I}, ::Val{:mpiaij}) where I = MatMPIAIJSetPreallocation(mat, PetscInt(0), PetscInt.(d_nnz), PetscInt(0), PetscInt.(o_nnz)) +_preallocate!(mat::PetscMat, d_nnz::Vector{I}, o_nnz::Vector{I}, ::Val{:mpiaij}) where {I} = MatMPIAIJSetPreallocation(mat, PetscInt(0), PetscInt.(d_nnz), PetscInt(0), PetscInt.(o_nnz)) _preallocate!(mat::PetscMat, nz::Integer, ::Integer, ::Val{:seqaij}) = MatSeqAIJSetPreallocation(mat, PetscInt(nz)) -_preallocate!(mat::PetscMat, nnz::Vector{I}, ::Vector{I}, ::Val{:seqaij}) where I = MatSeqAIJSetPreallocation(mat, PetscInt(0), PetscInt.(nnz)) +_preallocate!(mat::PetscMat, nnz::Vector{I}, ::Vector{I}, ::Val{:seqaij}) where {I} = MatSeqAIJSetPreallocation(mat, PetscInt(0), PetscInt.(nnz)) """ preallocate!(mat::PetscMat, dnz, onz, warn::Bool = true) Dispatch preallocation according matrix type (seq or mpiaij for instance). TODO: should use kwargs. """ -function preallocate!(mat::PetscMat, dnz, onz, warn::Bool = true) +function preallocate!(mat::PetscMat, dnz, onz, warn::Bool=true) _preallocate!(mat, dnz, onz, Val(Symbol(MatGetType(mat)))) MatSetOption(mat, MAT_NEW_NONZERO_ALLOCATION_ERR, warn) end @@ -132,7 +132,7 @@ end Write a PetscMat to a file. """ -function mat2file(mat::PetscMat, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") +function mat2file(mat::PetscMat, filename::String, format::PetscViewerFormat=PETSC_VIEWER_ASCII_CSV, type::String="ascii") viewer = PetscViewer(mat.comm, filename, format, type) MatView(mat, viewer) destroy!(viewer) diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index f59c5d1..02ae3d6 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -16,7 +16,7 @@ end Create a `PetscVec` vector of global size `(nrows)`. """ -function create_vector(nrows, nrows_loc = PETSC_DECIDE; auto_setup = false, comm::MPI.Comm = MPI.COMM_WORLD) +function create_vector(nrows, nrows_loc=PETSC_DECIDE; auto_setup=false, comm::MPI.Comm=MPI.COMM_WORLD) vec = VecCreate(comm) VecSetSizes(vec::PetscVec, nrows_loc, nrows) @@ -70,7 +70,7 @@ scale!(vec::PetscVec, alpha::Number) = VecScale(vec, alpha) For some unkwnown reason, calling `VecSetValue` fails. """ function Base.setindex!(vec::PetscVec, value::Number, row::Integer) - VecSetValues(vec, PetscInt[row .- 1], PetscScalar[value], INSERT_VALUES) + VecSetValues(vec, PetscInt[row.-1], PetscScalar[value], INSERT_VALUES) end # This is stupid but I don't know how to do better yet @@ -90,7 +90,7 @@ Base.show(::IO, vec::PetscVec) = VecView(vec) """ Wrapper to `VecSetValues`, using julia 1-based indexing. """ -function set_values!(vec::PetscVec, rows::Vector{PetscInt}, values::Vector{PetscScalar}, mode::InsertMode = INSERT_VALUES) +function set_values!(vec::PetscVec, rows::Vector{PetscInt}, values::Vector{PetscScalar}, mode::InsertMode=INSERT_VALUES) VecSetValues(vec, rows .- PetscIntOne, values, mode) end @@ -113,7 +113,7 @@ end Write a PetscVec to a file. """ -function vec2file(vec::PetscVec, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") +function vec2file(vec::PetscVec, filename::String, format::PetscViewerFormat=PETSC_VIEWER_ASCII_CSV, type::String="ascii") viewer = PetscViewer(vec.comm, filename, format, type) VecView(vec, viewer) destroy!(viewer) diff --git a/src/fancy/viewer.jl b/src/fancy/viewer.jl index 3659e8c..a19ba00 100644 --- a/src/fancy/viewer.jl +++ b/src/fancy/viewer.jl @@ -8,7 +8,7 @@ const set_type! = PetscViewerSetType Constructor for a PetscViewer intended to read/write a matrix or a vector with the supplied type and format. """ -function PetscViewer(comm::MPI.Comm, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii", mode::PetscFileMode = FILE_MODE_WRITE) +function PetscViewer(comm::MPI.Comm, filename::String, format::PetscViewerFormat=PETSC_VIEWER_ASCII_CSV, type::String="ascii", mode::PetscFileMode=FILE_MODE_WRITE) viewer = PetscViewerCreate(comm) set_type!(viewer, type) set_mode!(viewer, FILE_MODE_WRITE) diff --git a/src/init.jl b/src/init.jl index 7764b09..a35a7f4 100644 --- a/src/init.jl +++ b/src/init.jl @@ -7,13 +7,13 @@ I don't know if I am supposed to use PetscInt or not... function PetscInitialize(args::Vector{String}, filename::String, help::String) args2 = ["julia"; args] nargs = Cint(length(args2)) - error = ccall( (:PetscInitializeNoPointers, libpetsc), - PetscErrorCode, - (Cint, + error = ccall((:PetscInitializeNoPointers, libpetsc), + PetscErrorCode, + (Cint, Ptr{Ptr{UInt8}}, Cstring, Cstring), - nargs, args2, filename, help + nargs, args2, filename, help ) @assert iszero(error) end @@ -39,7 +39,7 @@ arguments for PETSc (leading to a call to `PetscInitializeNoPointers`). Otherwise, if `cmd_line_args == false`, initialize PETSc without arguments (leading to a call to `PetscInitializeNoArguments`). """ -function PetscInitialize(cmd_line_args::Bool = true) +function PetscInitialize(cmd_line_args::Bool=true) if (cmd_line_args) PetscInitialize(ARGS) else @@ -52,6 +52,6 @@ end Wrapper to PetscFinalize """ function PetscFinalize() - error = ccall( (:PetscFinalize, libpetsc), PetscErrorCode, ()) + error = ccall((:PetscFinalize, libpetsc), PetscErrorCode, ()) @assert iszero(error) end \ No newline at end of file diff --git a/src/ksp.jl b/src/ksp.jl index 05c5013..4700736 100644 --- a/src/ksp.jl +++ b/src/ksp.jl @@ -15,7 +15,7 @@ Base.cconvert(::Type{CKSP}, ksp::PetscKSP) = ksp.ptr[] Wrapper for `KSPCreate` """ -function KSPCreate(comm::MPI.Comm = MPI.COMM_WORLD) +function KSPCreate(comm::MPI.Comm=MPI.COMM_WORLD) ksp = PetscKSP(comm) error = ccall((:KSPCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}), comm, ksp.ptr) @assert iszero(error) diff --git a/src/load.jl b/src/load.jl index be99133..bc3b861 100644 --- a/src/load.jl +++ b/src/load.jl @@ -2,28 +2,28 @@ Function from GridapPETSC to find PETSc lib location. """ function get_petsc_location() - PETSC_DIR = haskey(ENV,"PETSC_DIR") ? ENV["PETSC_DIR"] : "/usr/lib/petsc" - PETSC_ARCH = haskey(ENV,"PETSC_ARCH") ? ENV["PETSC_ARCH"] : "" + PETSC_DIR = haskey(ENV, "PETSC_DIR") ? ENV["PETSC_DIR"] : "/usr/lib/petsc" + PETSC_ARCH = haskey(ENV, "PETSC_ARCH") ? ENV["PETSC_ARCH"] : "" PETSC_LIB = "" # Check PETSC_DIR exists if isdir(PETSC_DIR) # Define default paths - PETSC_LIB_DIR = joinpath(PETSC_DIR,PETSC_ARCH,"lib") + PETSC_LIB_DIR = joinpath(PETSC_DIR, PETSC_ARCH, "lib") # Check PETSC_LIB (.../libpetsc.so or .../libpetsc_real.so file) exists - if isfile(joinpath(PETSC_LIB_DIR,"libpetsc.so")) - PETSC_LIB = joinpath(PETSC_LIB_DIR,"libpetsc.so") - elseif isfile(joinpath(PETSC_LIB_DIR,"libpetsc_real.so")) - PETSC_LIB = joinpath(PETSC_LIB_DIR,"libpetsc_real.so") + if isfile(joinpath(PETSC_LIB_DIR, "libpetsc.so")) + PETSC_LIB = joinpath(PETSC_LIB_DIR, "libpetsc.so") + elseif isfile(joinpath(PETSC_LIB_DIR, "libpetsc_real.so")) + PETSC_LIB = joinpath(PETSC_LIB_DIR, "libpetsc_real.so") end end # PETSc lib not found - if(length(PETSC_LIB) == 0) + if (length(PETSC_LIB) == 0) # Workaround for automerging on RegistryCI or doc deployment - if(haskey(ENV,"JULIA_REGISTRYCI_AUTOMERGE") || haskey(ENV, "DOC_DEPLOYMENT")) + if (haskey(ENV, "JULIA_REGISTRYCI_AUTOMERGE") || haskey(ENV, "DOC_DEPLOYMENT")) @warn "Setting fictive PETSc path because of RegistryCI or Doc deployment" PETSC_LIB = "JULIA_REGISTRYCI_AUTOMERGE" else diff --git a/src/mat.jl b/src/mat.jl index b07d591..6e3e10c 100644 --- a/src/mat.jl +++ b/src/mat.jl @@ -46,7 +46,7 @@ end Wrapper to `MatCreate` """ -function MatCreate(comm::MPI.Comm = MPI.COMM_WORLD) +function MatCreate(comm::MPI.Comm=MPI.COMM_WORLD) mat = PetscMat(comm) error = ccall((:MatCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CMat}), comm, mat.ptr) @assert iszero(error) @@ -68,10 +68,10 @@ function MatCreateDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N end function MatCreateDense(comm::MPI.Comm, - m::Integer = PETSC_DECIDE, - n::Integer = PETSC_DECIDE, - M::Integer = PETSC_DECIDE, - N::Integer = PETSC_DECIDE) + m::Integer=PETSC_DECIDE, + n::Integer=PETSC_DECIDE, + M::Integer=PETSC_DECIDE, + N::Integer=PETSC_DECIDE) return MatCreateDense(comm, PetscInt(m), PetscInt(n), PetscInt(M), PetscInt(N)) end @@ -85,7 +85,8 @@ function MatCreateVecs(mat::PetscMat, vecr::PetscVec, veci::PetscVec) end function MatCreateVecs(mat::PetscMat) - vecr = PetscVec(mat.comm); veci = PetscVec(mat.comm) + vecr = PetscVec(mat.comm) + veci = PetscVec(mat.comm) MatCreateVecs(mat, vecr, veci) return vecr, veci end @@ -229,10 +230,10 @@ Wrapper to MatSetSizes """ function MatSetSizes(mat::PetscMat, nrows_loc::PetscInt, ncols_loc::PetscInt, nrows_glo::PetscInt, ncols_glo::PetscInt) error = ccall((:MatSetSizes, libpetsc), - PetscErrorCode, - (CMat, PetscInt, PetscInt, PetscInt, PetscInt), - mat, nrows_loc, ncols_loc, nrows_glo, ncols_glo - ) + PetscErrorCode, + (CMat, PetscInt, PetscInt, PetscInt, PetscInt), + mat, nrows_loc, ncols_loc, nrows_glo, ncols_glo + ) @assert iszero(error) end @@ -320,9 +321,9 @@ function MatSetOption(mat::PetscMat, option::MatOption, value::Bool) end # Avoid allocating an array of size 1 for each call to MatSetValue -const _ivec = zeros(PetscInt,1) -const _jvec = zeros(PetscInt,1) -const _vvec = zeros(PetscScalar,1) +const _ivec = zeros(PetscInt, 1) +const _jvec = zeros(PetscInt, 1) +const _vvec = zeros(PetscScalar, 1) """ MatSetValue(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode::InsertMode) @@ -335,7 +336,9 @@ So this wrapper directly call MatSetValues (anyway, this is what is done in PETS """ function MatSetValue(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode::InsertMode) # Convert to arrays - _ivec[1] = i; _jvec[1] = j; _vvec[1] = v + _ivec[1] = i + _jvec[1] = j + _vvec[1] = v MatSetValues(mat, PetscIntOne, _ivec, PetscIntOne, _jvec, _vvec, mode) #MatSetValues(mat, PetscIntOne, [i], PetscIntOne, [j], [v], mode) @@ -370,7 +373,7 @@ end Wrapper to `MatView` """ -function MatView(mat::PetscMat, viewer::PetscViewer = PetscViewerStdWorld()) +function MatView(mat::PetscMat, viewer::PetscViewer=PetscViewerStdWorld()) error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) @assert iszero(error) end \ No newline at end of file diff --git a/src/viewer.jl b/src/viewer.jl index 02662fb..4671066 100644 --- a/src/viewer.jl +++ b/src/viewer.jl @@ -14,7 +14,7 @@ Base.cconvert(::Type{CViewer}, viewer::PetscViewer) = viewer.ptr[] Wrapper for `PetscViewerASCIIGetStdout` """ -function PetscViewerASCIIGetStdout(comm::MPI.Comm = MPI.COMM_WORLD) +function PetscViewerASCIIGetStdout(comm::MPI.Comm=MPI.COMM_WORLD) viewer = PetscViewer(comm) error = ccall((:PetscViewerASCIIGetStdout, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CViewer}), comm, viewer.ptr) @assert iszero(error) @@ -40,7 +40,7 @@ end Wrapper for `PetscViewerCreate` """ -function PetscViewerCreate(comm::MPI.Comm = MPI.COMM_WORLD) +function PetscViewerCreate(comm::MPI.Comm=MPI.COMM_WORLD) viewer = PetscViewer(comm) error = ccall((:PetscViewerCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CViewer}), comm, viewer.ptr) @assert iszero(error) @@ -56,7 +56,7 @@ Warning : from what I understand, all viewers must not be destroyed explicitely """ function PetscViewerDestroy(viewer::PetscViewer) - error = ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer}, ), viewer.ptr) + error = ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer},), viewer.ptr) @assert iszero(error) end @@ -85,7 +85,7 @@ end Wrapper for `PetscViewerFileSetMode` """ -function PetscViewerFileSetMode(viewer::PetscViewer, mode::PetscFileMode = FILE_MODE_WRITE) +function PetscViewerFileSetMode(viewer::PetscViewer, mode::PetscFileMode=FILE_MODE_WRITE) error = ccall((:PetscViewerFileSetMode, libpetsc), PetscErrorCode, (CViewer, PetscFileMode), viewer, mode) @assert iszero(error) end @@ -131,7 +131,7 @@ end Wrapper to `PetscViewerView` """ -function PetscViewerView(v::PetscViewer, viewer::PetscViewer = PetscViewerStdWorld()) +function PetscViewerView(v::PetscViewer, viewer::PetscViewer=PetscViewerStdWorld()) error = ccall((:PetscViewerView, libpetsc), PetscErrorCode, (CViewer, CViewer), v, viewer) @assert iszero(error) end \ No newline at end of file diff --git a/test/linear_system.jl b/test/linear_system.jl index f6c76e7..5bfb994 100644 --- a/test/linear_system.jl +++ b/test/linear_system.jl @@ -1,92 +1,92 @@ @testset "linear system" begin -# Only on one processor... - -# Import package -using PetscWrap - -# Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can -# also provide "command line arguments by defining them in a string, for instance -# `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in -# separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` -PetscInitialize() - -# Number of mesh points and mesh step -n = 11 -Δx = 1. / (n - 1) - -# Create a matrix and a vector -A = MatCreate() -b = VecCreate() - -# Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should -# set the number of preallocated non-zeros to increase performance. -MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) -VecSetSizes(b, PETSC_DECIDE, n) - -# We can then use command-line options to set our matrix/vectors. -MatSetFromOptions(A) -VecSetFromOptions(b) - -# Finish the set up -MatSetUp(A) -VecSetUp(b) - -# Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. -# As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor -# (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout -# the fancy version of this example for a more Julia-like convention. -b_start, b_end = VecGetOwnershipRange(b) - -# Now let's build the right hand side vector. Their are various ways to do this, this is just one. -n_loc = VecGetLocalSize(b) # Note that n_loc = b_end - b_start... -VecSetValues(b, collect(b_start:b_end-1), 2 * ones(n_loc)) - -# And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. -A_start, A_end = MatGetOwnershipRange(A) -for i in A_start:A_end-1 - MatSetValues(A, [i], [i-1, i], [-1. 1.] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) -end - -# Set boundary condition (only the proc handling index `0` is acting) -(b_start == 0) && VecSetValue(b, 0, 0.) - -# Assemble matrices -MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY) -VecAssemblyBegin(b) -MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY) -VecAssemblyEnd(b) - -# At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call -MatView(A) -VecView(b) - -# Set up the linear solver -ksp = KSPCreate() -KSPSetOperators(ksp, A, A) -KSPSetFromOptions(ksp) -KSPSetUp(ksp) - -# Solve the system. We first allocate the solution using the `VecDuplicate` method. -x = VecDuplicate(b) -KSPSolve(ksp, b, x) - -# Print the solution -VecView(x) - -# Access the solution (this part is under development), getting a Julia array; and then restore it -array, ref = VecGetArray(x) # do something with array -@test isapprox(array, range(0., 2.; length = n)) -VecRestoreArray(x, ref) - -# Free memory -MatDestroy(A) -VecDestroy(b) -VecDestroy(x) - -# Finalize Petsc -PetscFinalize() - -# Reach this point? -@test true + # Only on one processor... + + # Import package + using PetscWrap + + # Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can + # also provide "command line arguments by defining them in a string, for instance + # `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in + # separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` + PetscInitialize() + + # Number of mesh points and mesh step + n = 11 + Δx = 1.0 / (n - 1) + + # Create a matrix and a vector + A = MatCreate() + b = VecCreate() + + # Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should + # set the number of preallocated non-zeros to increase performance. + MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) + VecSetSizes(b, PETSC_DECIDE, n) + + # We can then use command-line options to set our matrix/vectors. + MatSetFromOptions(A) + VecSetFromOptions(b) + + # Finish the set up + MatSetUp(A) + VecSetUp(b) + + # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. + # As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor + # (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout + # the fancy version of this example for a more Julia-like convention. + b_start, b_end = VecGetOwnershipRange(b) + + # Now let's build the right hand side vector. Their are various ways to do this, this is just one. + n_loc = VecGetLocalSize(b) # Note that n_loc = b_end - b_start... + VecSetValues(b, collect(b_start:b_end-1), 2 * ones(n_loc)) + + # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. + A_start, A_end = MatGetOwnershipRange(A) + for i in A_start:A_end-1 + MatSetValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) + end + + # Set boundary condition (only the proc handling index `0` is acting) + (b_start == 0) && VecSetValue(b, 0, 0.0) + + # Assemble matrices + MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY) + VecAssemblyBegin(b) + MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY) + VecAssemblyEnd(b) + + # At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call + MatView(A) + VecView(b) + + # Set up the linear solver + ksp = KSPCreate() + KSPSetOperators(ksp, A, A) + KSPSetFromOptions(ksp) + KSPSetUp(ksp) + + # Solve the system. We first allocate the solution using the `VecDuplicate` method. + x = VecDuplicate(b) + KSPSolve(ksp, b, x) + + # Print the solution + VecView(x) + + # Access the solution (this part is under development), getting a Julia array; and then restore it + array, ref = VecGetArray(x) # do something with array + @test isapprox(array, range(0.0, 2.0; length=n)) + VecRestoreArray(x, ref) + + # Free memory + MatDestroy(A) + VecDestroy(b) + VecDestroy(x) + + # Finalize Petsc + PetscFinalize() + + # Reach this point? + @test true end diff --git a/test/linear_system_fancy.jl b/test/linear_system_fancy.jl index 206564a..4ab7f3a 100644 --- a/test/linear_system_fancy.jl +++ b/test/linear_system_fancy.jl @@ -1,89 +1,89 @@ @testset "linear system fancy" begin -# Only on one processor... - -# Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can -# also provide "command line arguments by defining them in a string, for instance -# `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in -# separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` -PetscInitialize() - -# Number of mesh points and mesh step -n = 11 -Δx = 1. / (n - 1) - -# Create a matrix of size `(n,n)` and a vector of size `(n)` -A = create_matrix(n, n) -b = create_vector(n) - -# We can then use command line options to set our matrix/vectors. -set_from_options!(A) -set_from_options!(b) - -# Finish the set up -set_up!(A) -set_up!(b) - -# Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. -# The `rstart, rend = get_range(*)` methods differ a little bit from PETSc API since the two integers it -# returns are the effective Julia range of rows handled by the local processor. If `n` is the total -# number of rows, then `rstart ∈ [1,n]` and `rend` is the last row handled by the local processor. -b_start, b_end = get_range(b) - -# Now let's build the right hand side vector. Their are various ways to do this, this is just one. -n_loc = length(b) ## Note that n_loc = b_end - b_start + 1... -b[b_start:b_end] = 2 * ones(n_loc) - -# And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. -A_start, A_end = get_range(A) -for i in A_start:A_end - A[i, i-1:i] = [-1. 1.] / Δx -end - -# Set boundary condition (only the proc handling index `1` is acting) -(b_start == 1) && (b[1] = 0.) - -# Assemble matrice and vector -assemble!(A) -assemble!(b) - -# Set up the linear solver -ksp = create_ksp(A) -set_from_options!(ksp) -set_up!(ksp) - -# Solve the system -x = solve(ksp, b) - -# Print the solution -@show x - -# Convert to Julia array -array = vec2array(x) -@test isapprox(array, range(0., 2.; length = n)) - -# Free memory -destroy!(A) -destroy!(b) -destroy!(x) - -# Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: -M = create_matrix(3,3; auto_setup = true) -M_start, M_end = get_range(M) -I = [1, 1, 1, 2, 3] -J = [1, 3, 1, 3, 2] -V = [1, 2, 3, 4, 5] -k = findall(x -> M_start <= x <= M_end, I) # just a stupid trick to allow this example to run in parallel -set_values!(M, I[k], J[k], V[k], ADD_VALUES) -assemble!(M) -@show M -destroy!(M) -# This is very convenient in sequential since you can fill the three vectors I, J, V in your code and decide only -# at the last moment if you'd like to use `SparseArrays` or `PetscMat`. - -# Finalize Petsc -PetscFinalize() - -# Reach this point? -@test true + # Only on one processor... + + # Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can + # also provide "command line arguments by defining them in a string, for instance + # `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in + # separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` + PetscInitialize() + + # Number of mesh points and mesh step + n = 11 + Δx = 1.0 / (n - 1) + + # Create a matrix of size `(n,n)` and a vector of size `(n)` + A = create_matrix(n, n) + b = create_vector(n) + + # We can then use command line options to set our matrix/vectors. + set_from_options!(A) + set_from_options!(b) + + # Finish the set up + set_up!(A) + set_up!(b) + + # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. + # The `rstart, rend = get_range(*)` methods differ a little bit from PETSc API since the two integers it + # returns are the effective Julia range of rows handled by the local processor. If `n` is the total + # number of rows, then `rstart ∈ [1,n]` and `rend` is the last row handled by the local processor. + b_start, b_end = get_range(b) + + # Now let's build the right hand side vector. Their are various ways to do this, this is just one. + n_loc = length(b) ## Note that n_loc = b_end - b_start + 1... + b[b_start:b_end] = 2 * ones(n_loc) + + # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. + A_start, A_end = get_range(A) + for i in A_start:A_end + A[i, i-1:i] = [-1.0 1.0] / Δx + end + + # Set boundary condition (only the proc handling index `1` is acting) + (b_start == 1) && (b[1] = 0.0) + + # Assemble matrice and vector + assemble!(A) + assemble!(b) + + # Set up the linear solver + ksp = create_ksp(A) + set_from_options!(ksp) + set_up!(ksp) + + # Solve the system + x = solve(ksp, b) + + # Print the solution + @show x + + # Convert to Julia array + array = vec2array(x) + @test isapprox(array, range(0.0, 2.0; length=n)) + + # Free memory + destroy!(A) + destroy!(b) + destroy!(x) + + # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: + M = create_matrix(3, 3; auto_setup=true) + M_start, M_end = get_range(M) + I = [1, 1, 1, 2, 3] + J = [1, 3, 1, 3, 2] + V = [1, 2, 3, 4, 5] + k = findall(x -> M_start <= x <= M_end, I) # just a stupid trick to allow this example to run in parallel + set_values!(M, I[k], J[k], V[k], ADD_VALUES) + assemble!(M) + @show M + destroy!(M) + # This is very convenient in sequential since you can fill the three vectors I, J, V in your code and decide only + # at the last moment if you'd like to use `SparseArrays` or `PetscMat`. + + # Finalize Petsc + PetscFinalize() + + # Reach this point? + @test true end diff --git a/test/misc.jl b/test/misc.jl index d7826ad..93a341f 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1,52 +1,54 @@ @testset "composite" begin -PetscInitialize() - -# Create two matrices -A = create_matrix(2, 2; auto_setup = true) -B = create_matrix(2, 2; auto_setup = true) - -# Fill - -# A -# 1 - -# 3 4 -A[1,1] = 1 -A[2,1] = 3 -A[2,2] = 4 - -# B -# 4 3 -# - 1 -B[1,1] = 4 -B[1,2] = 3 -B[2,2] = 1 - -# Assemble matrices -assemble!.((A,B)) - -# Create composite mat from A and B -# C -# 5 3 -# 3 5 -C = create_composite_add([A, B]) - -# Create vectors to check C (see below) -x1 = create_vector(2; auto_setup = true) -x2 = create_vector(2; auto_setup = true) -y = create_vector(2; auto_setup = true) -x1[1] = 1.; x1[2] = 0. -x2[1] = 0.; x2[2] = 1. -assemble!.((x1,x2,y)) - -# Check result by multiplying with test vectors -MatMult(C, x1, y) -@test vec2array(y) == [5., 3.] - -MatMult(C, x2, y) -@test vec2array(y) == [3., 5.] - -# Free memory -destroy!.((A, B, C, x1, x2, y)) -PetscFinalize() + PetscInitialize() + + # Create two matrices + A = create_matrix(2, 2; auto_setup=true) + B = create_matrix(2, 2; auto_setup=true) + + # Fill + + # A + # 1 - + # 3 4 + A[1, 1] = 1 + A[2, 1] = 3 + A[2, 2] = 4 + + # B + # 4 3 + # - 1 + B[1, 1] = 4 + B[1, 2] = 3 + B[2, 2] = 1 + + # Assemble matrices + assemble!.((A, B)) + + # Create composite mat from A and B + # C + # 5 3 + # 3 5 + C = create_composite_add([A, B]) + + # Create vectors to check C (see below) + x1 = create_vector(2; auto_setup=true) + x2 = create_vector(2; auto_setup=true) + y = create_vector(2; auto_setup=true) + x1[1] = 1.0 + x1[2] = 0.0 + x2[1] = 0.0 + x2[2] = 1.0 + assemble!.((x1, x2, y)) + + # Check result by multiplying with test vectors + MatMult(C, x1, y) + @test vec2array(y) == [5.0, 3.0] + + MatMult(C, x2, y) + @test vec2array(y) == [3.0, 5.0] + + # Free memory + destroy!.((A, B, C, x1, x2, y)) + PetscFinalize() end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index b6d8d19..6c897b7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,7 +6,7 @@ using Test # https://discourse.julialang.org/t/what-general-purpose-commands-do-you-usually-end-up-adding-to-your-projects/4889 @generated function compare_struct(x, y) if !isempty(fieldnames(x)) && x == y - mapreduce(n -> :(x.$n == y.$n), (a,b)->:($a && $b), fieldnames(x)) + mapreduce(n -> :(x.$n == y.$n), (a, b) -> :($a && $b), fieldnames(x)) else :(x == y) end From 85d630db63f4c58ddd70c5a29075d2f875720333 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 25 Mar 2023 21:36:02 +0100 Subject: [PATCH 04/40] wrapper to PetscInitialized --- src/PetscWrap.jl | 2 +- src/const_arch_ind.jl | 1 + src/init.jl | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index b348481..f912ea1 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -27,7 +27,7 @@ include("const_arch_dep.jl") export PetscReal, PetscScalar, PetscInt, PetscIntOne include("init.jl") -export PetscInitialize, PetscFinalize +export PetscInitialize, PetscInitialized, PetscFinalize include("viewer.jl") export PetscViewer, CViewer, diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index 544391b..7d76012 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -19,6 +19,7 @@ end @enum PetscBool PETSC_FALSE PETSC_TRUE +Base.Bool(x::PetscBool) = x == PETSC_TRUE @enum PetscDataType begin PETSC_DATATYPE_UNKNOWN = 0 diff --git a/src/init.jl b/src/init.jl index a35a7f4..82c8968 100644 --- a/src/init.jl +++ b/src/init.jl @@ -54,4 +54,14 @@ end function PetscFinalize() error = ccall((:PetscFinalize, libpetsc), PetscErrorCode, ()) @assert iszero(error) +end + +""" + Wrapper to PetscInitialized +""" +function PetscInitialized() + isInitialized = Ref{PetscBool}() + error = ccall((:PetscInitialized, libpetsc), PetscErrorCode, (Ref{PetscBool},), isInitialized) + @assert iszero(error) + return Bool(isInitialized[]) end \ No newline at end of file From ac8f567933ede83f7db849c92f2da324b3996b64 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 25 Mar 2023 22:00:46 +0100 Subject: [PATCH 05/40] wip on l2g + formatter --- .JuliaFormatter.toml | 22 ++++++++++++++++++ src/PetscWrap.jl | 41 +++++++++++++--------------------- src/const_arch_ind.jl | 6 +++++ src/local2global.jl | 52 +++++++++++++++++++++++++++++++++++++++++++ src/vec.jl | 8 +++++++ 5 files changed, 104 insertions(+), 25 deletions(-) create mode 100644 .JuliaFormatter.toml create mode 100644 src/local2global.jl diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml new file mode 100644 index 0000000..d4be17d --- /dev/null +++ b/.JuliaFormatter.toml @@ -0,0 +1,22 @@ +# https://github.com/domluna/JuliaFormatter.jl + +# Annotates fields in a type definitions with ::Any if no type annotation is provided +annotate_untyped_fields_with_any = false + +# Transforms a short function definition to a long function definition if the short +# function definition exceeds the maximum margin. +short_to_long_function_def = true + +# Transforms a long function definition to a short function definition if the short +# function definition does not exceed the maximum margin. +long_to_short_function_def = true + +# Format code docstrings with the same options used for the code source. +format_docstrings = true + +# If true, Markdown files are also formatted. Julia code blocks will be formatted +# in addition to the Markdown being normalized. +format_markdown = true + +# If true, whitespace is added for binary operations in indices +whitespace_ops_in_indices = true \ No newline at end of file diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index f912ea1..4f68fe4 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -30,7 +30,8 @@ include("init.jl") export PetscInitialize, PetscInitialized, PetscFinalize include("viewer.jl") -export PetscViewer, CViewer, +export PetscViewer, + CViewer, PetscViewerASCIIOpen, PetscViewerCreate, PetscViewerDestroy, @@ -43,8 +44,12 @@ export PetscViewer, CViewer, PetscViewerStdWorld, PetscViewerView +include("local2global.jl") +export ISLocalToGlobalMappingCreate, ISLocalToGlobalMappingDestroy + include("vec.jl") -export PetscVec, CVec, +export PetscVec, + CVec, VecAssemble, VecAssemblyBegin, VecAssemblyEnd, @@ -66,7 +71,8 @@ export PetscVec, CVec, VecView include("mat.jl") -export PetscMat, CMat, +export PetscMat, + CMat, MatAssemble, MatAssemblyBegin, MatAssemblyEnd, @@ -92,21 +98,12 @@ export PetscMat, CMat, MatView include("ksp.jl") -export PetscKSP, CKSP, - KSPCreate, - KSPDestroy, - KSPSetFromOptions, - KSPSetOperators, - KSPSetUp, - KSPSolve +export PetscKSP, + CKSP, KSPCreate, KSPDestroy, KSPSetFromOptions, KSPSetOperators, KSPSetUp, KSPSolve # fancy include("fancy/viewer.jl") -export destroy!, - push_format!, - set_mode!, - set_name!, - set_type! +export destroy!, push_format!, set_mode!, set_name!, set_type! include("fancy/vec.jl") export assemble!, @@ -115,23 +112,17 @@ export assemble!, duplicate, get_range, get_urange, - set_local_size!, set_global_size!, + set_local_size!, + set_global_size!, set_from_options!, set_up!, vec2array, vec2file include("fancy/mat.jl") -export create_composite_add, - create_matrix, - mat2file, - preallocate!, - set_value!, - set_values! +export create_composite_add, create_matrix, mat2file, preallocate!, set_value!, set_values! include("fancy/ksp.jl") -export create_ksp, - solve, solve!, - set_operators! +export create_ksp, solve, solve!, set_operators! end \ No newline at end of file diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index 7d76012..1d115b5 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -21,6 +21,12 @@ end @enum PetscBool PETSC_FALSE PETSC_TRUE Base.Bool(x::PetscBool) = x == PETSC_TRUE +@enum PetscCopyMode begin + PETSC_COPY_VALUES + PETSC_OWN_POINTER + PETSC_USE_POINTER +end + @enum PetscDataType begin PETSC_DATATYPE_UNKNOWN = 0 PETSC_DOUBLE = 1 diff --git a/src/local2global.jl b/src/local2global.jl new file mode 100644 index 0000000..9849a3d --- /dev/null +++ b/src/local2global.jl @@ -0,0 +1,52 @@ +const CISLocalToGlobalMapping = Ptr{Cvoid} + +struct ISLocalToGlobalMapping + ptr::Ref{CISLocalToGlobalMapping} + comm::MPI.Comm + + ISLocalToGlobalMapping(comm::MPI.Comm) = new(Ref{Ptr{Cvoid}}(), comm) +end + +# allows us to pass ISLocalToGlobalMapping objects directly into CISLocalToGlobalMapping ccall signatures +Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2g.ptr[] + + +function ISLocalToGlobalMappingCreate( + comm::MPI.Comm, + bs::PetscInt, + n::PetscInt, + indices::Vector{PetscInt}, + mode::PetscCopyMode, +) + l2g = ISLocalToGlobalMapping(comm) + error = ccall( + (:ISLocalToGlobalMappingCreate, libpetsc), + PetscErrorCode, + ( + MPI.MPI_Comm, + PetscInt, + PetscInt, + Ptr{PetscInt}, + PetscCopyMode, + Ptr{CISLocalToGlobalMapping}, + ), + comm, + bs, + n, + indices, + mode, + l2g, + ) + @assert iszero(error) + return l2g +end + +function ISLocalToGlobalMappingDestroy(l2g::ISLocalToGlobalMapping) + error = ccall( + (:ISLocalToGlobalMappingDestroy, libpetsc), + PetscErrorCode, + (Ptr{CISLocalToGlobalMapping},), + l2g.ptr, + ) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/vec.jl b/src/vec.jl index bda97f9..c9caa3f 100644 --- a/src/vec.jl +++ b/src/vec.jl @@ -276,4 +276,12 @@ function VecDestroy(vec::PetscVec) (Ptr{CVec},), vec.ptr) @assert iszero(error) +end + +function VecSetLocalToGlobalMapping(vec::PetscVec, l2g::ISLocalToGlobalMapping) + error = ccall( (:VecSetLocalToGlobalMapping, libpetsc), + PetscErrorCode, + (CVec,CISLocalToGlobalMapping), + vec, l2g) + @assert iszero(error) end \ No newline at end of file From f08cf63accc681d831ca6aa10383f0d40a059b4f Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 25 Mar 2023 22:08:45 +0100 Subject: [PATCH 06/40] conventions to be applied in futures versions --- README.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2102bec..6ee8fd6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ PetscWrap.jl is a parallel Julia wrapper for the (awesome) [PETSc](https://www.mcs.anl.gov/petsc/) library. It can be considered as a fork from the [GridapPetsc.jl](https://github.com/gridap/GridapPETSc.jl) and [Petsc.jl](https://github.com/JuliaParallel/PETSc.jl) projects : these two projects have extensively inspired this project, and some code has even been directly copied. The main differences with the two aformentionned projects are: + - parallel support : you can solve linear systems on multiple core with `mpirun -n 4 julia foo.jl`; - no dependance to other Julia packages except `MPI.jl`; - possibility to switch from one PETSc "arch" to another; @@ -14,27 +15,42 @@ The main differences with the two aformentionned projects are: Note that the primary objective of this project is to enable the wrapper of the SLEPc library through the [SlepcWrap.jl](https://github.com/bmxam/SlepcWrap.jl) project. ## How to install it + You must have installed the PETSc library on your computer and set the two following environment variables : `PETSC_DIR` and `PETSC_ARCH`. At run time, PetscWrap.jl looks for the `libpetsc.so` using these environment variables and "load" the library. To install the package, use the Julia package manager: + ```Julia pkg> add PetscWrap ``` + ## Contribute + Any contribution(s) and/or remark(s) are welcome! If you need a function that is not wrapped yet but you don't think you are capable of contributing, post an issue with a minimum working example. +Conventions to be applied in future versions ("fancy" stuff is not concerned): + +- all PETSc types should have the exact same name in Julia, but with the prefix `Petsc`. For instance : `Vec` becomes `PetscVec`. And `ISLocalToGlobalMapping` should be `PetscISLocalToGlobalMapping`. Alternatively, we could decide to avoid the `Petsc` prefix and not to export the names. Then the user could use something like `P.Vec` etc. +- all PETSc functions should have the exact same name in julia, without the prefix `Petsc`. Hence, functions will start with a capital letter : `VecCreate`, `MatDestroy` etc; +- all PETSc functions must have the same number of arguments in julia, except for out-of-place arguments. +- functions arguments must all be typed. Additional functions, without type or with fewer args, can be defined if the original version is present. + ## PETSc compat. + This version of PetscWrap.jl has been tested with petsc-3.13. Complex numbers are supported. ## How to use it + PETSc methods wrappers share the same name as their C equivalent : for instance `MatCreate` or `MatSetValue`. Furthermore, an optional "higher level" API, referred to as "fancy", is exposed : for instance `create_matrix` or `A[i,j] = v`). Note that this second way of manipulating PETSc will evolve according the package's author needs while the first one will try to follow PETSc official API. You will find examples of use by building the documentation: `julia PetscWrap.jl/docs/make.jl`. Here is one of the examples: + ### A first demo + This example serves as a test since this project doesn't have a "testing" procedure yet. In this example, -the equation ``u'(x) = 2`` with ``u(0) = 0`` is solved on the domain ``[0,1]`` using a backward finite +the equation `u'(x) = 2` with `u(0) = 0` is solved on the domain `[0,1]` using a backward finite difference scheme. In this example, PETSc classic method names are used. For more fancy names, check the fancy version. @@ -185,4 +201,4 @@ Finalize Petsc ```julia PetscFinalize() -``` \ No newline at end of file +``` From 2427dec71c1a7934d27dfa882dc421f57a352829 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 14:07:00 +0200 Subject: [PATCH 07/40] convention for KSP --- README.md | 6 ++-- src/KSP.jl | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ksp.jl | 73 ------------------------------------------- 3 files changed, 95 insertions(+), 76 deletions(-) create mode 100644 src/KSP.jl delete mode 100644 src/ksp.jl diff --git a/README.md b/README.md index 6ee8fd6..3b46d5a 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ Any contribution(s) and/or remark(s) are welcome! If you need a function that is Conventions to be applied in future versions ("fancy" stuff is not concerned): -- all PETSc types should have the exact same name in Julia, but with the prefix `Petsc`. For instance : `Vec` becomes `PetscVec`. And `ISLocalToGlobalMapping` should be `PetscISLocalToGlobalMapping`. Alternatively, we could decide to avoid the `Petsc` prefix and not to export the names. Then the user could use something like `P.Vec` etc. -- all PETSc functions should have the exact same name in julia, without the prefix `Petsc`. Hence, functions will start with a capital letter : `VecCreate`, `MatDestroy` etc; -- all PETSc functions must have the same number of arguments in julia, except for out-of-place arguments. +- all PETSc types should have the exact same name in Julia +- all PETSc functions should have the exact same name in julia, but without the type prefix, and with a lower case for the first letter. `VecSetValues` becomes `setValues`; +- all PETSc functions must have the same number of arguments and the same names in julia, except for out-of-place arguments. - functions arguments must all be typed. Additional functions, without type or with fewer args, can be defined if the original version is present. ## PETSc compat. diff --git a/src/KSP.jl b/src/KSP.jl new file mode 100644 index 0000000..713483a --- /dev/null +++ b/src/KSP.jl @@ -0,0 +1,92 @@ +const CKSP = Ptr{Cvoid} + +struct KSP + ptr::Ref{CKSP} + comm::MPI.Comm + + KSP(comm::MPI.Comm) = new(Ref{CKSP}(), comm) +end + +# allows us to pass KSP objects directly into CKSP ccall signatures +Base.cconvert(::Type{CKSP}, ksp::KSP) = ksp.ptr[] + +""" + create(::Type{KSP}, comm::MPI.Comm=MPI.COMM_WORLD) + +Wrapper for `KSPCreate` +https://petsc.org/release/docs/manualpages/KSP/KSPCreate/ +""" +function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) + ksp = KSP(comm) + error = ccall( + (:KSPCreate, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Ptr{CKSP}), + comm, + ksp.ptr, + ) + @assert iszero(error) + return ksp +end + +""" + destroy(ksp::KSP) + +Wrapper to `KSPDestroy` +https://petsc.org/release/docs/manualpages/KSP/KSPDestroy/ +""" +function destroy(ksp::KSP) + error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp.ptr) + @assert iszero(error) +end + +""" + setFromOptions(ksp::KSP) + +Wrapper to `KSPSetFromOptions` +https://petsc.org/release/docs/manualpages/KSP/KSPSetFromOptions/ +""" +function setFromOptions(ksp::KSP) + error = ccall((:KSPSetFromOptions, libpetsc), PetscErrorCode, (CKSP,), ksp) + @assert iszero(error) +end + +""" + setOperators(ksp::KSP, Amat::PetscMat, Pmat::PetscMat) + +Wrapper for `KSPSetOperators`` +https://petsc.org/release/docs/manualpages/KSP/KSPSetOperators/ +""" +function setOperators(ksp::KSP, Amat::PetscMat, Pmat::PetscMat) + error = ccall( + (:KSPSetOperators, libpetsc), + PetscErrorCode, + (CKSP, CMat, CMat), + ksp, + Amat, + Pmat, + ) + @assert iszero(error) +end + +""" + KSPSetUp(ksp::KSP) + +Wrapper to `KSPSetUp` +https://petsc.org/release/docs/manualpages/KSP/KSPSetUp/ +""" +function setUp(ksp::KSP) + error = ccall((:KSPSetUp, libpetsc), PetscErrorCode, (CKSP,), ksp) + @assert iszero(error) +end + +""" + solve(ksp::KSP, b::PetscVec, x::PetscVec) + +Wrapper for `KSPSolve` +https://petsc.org/release/docs/manualpages/KSP/KSPSolve/ +""" +function solve(ksp::KSP, b::PetscVec, x::PetscVec) + error = ccall((:KSPSolve, libpetsc), PetscErrorCode, (CKSP, CVec, CVec), ksp, b, x) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/ksp.jl b/src/ksp.jl deleted file mode 100644 index 4700736..0000000 --- a/src/ksp.jl +++ /dev/null @@ -1,73 +0,0 @@ -const CKSP = Ptr{Cvoid} - -struct PetscKSP - ptr::Ref{CKSP} - comm::MPI.Comm - - PetscKSP(comm::MPI.Comm) = new(Ref{CKSP}(), comm) -end - -# allows us to pass PetscKSP objects directly into CKSP ccall signatures -Base.cconvert(::Type{CKSP}, ksp::PetscKSP) = ksp.ptr[] - -""" - KSPCreate(comm::MPI.Comm = MPI.COMM_WORLD) - -Wrapper for `KSPCreate` -""" -function KSPCreate(comm::MPI.Comm=MPI.COMM_WORLD) - ksp = PetscKSP(comm) - error = ccall((:KSPCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}), comm, ksp.ptr) - @assert iszero(error) - return ksp -end - -""" - KSPDestroy(ksp::PetscKSP) - -Wrapper to `KSPDestroy` -""" -function KSPDestroy(ksp::PetscKSP) - error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp.ptr) - @assert iszero(error) -end - -""" - KSPSetFromOptions(ksp::PetscKSP) - -Wrapper to KSPSetFromOptions -""" -function KSPSetFromOptions(ksp::PetscKSP) - error = ccall((:KSPSetFromOptions, libpetsc), PetscErrorCode, (CKSP,), ksp) - @assert iszero(error) -end - -""" - KSPSetOperators(ksp::PetscKSP, Amat::PetscMat, Pmat::PetscMat) - -Wrapper for KSPSetOperators -""" -function KSPSetOperators(ksp::PetscKSP, Amat::PetscMat, Pmat::PetscMat) - error = ccall((:KSPSetOperators, libpetsc), PetscErrorCode, (CKSP, CMat, CMat), ksp, Amat, Pmat) - @assert iszero(error) -end - -""" - KSPSetUp(ksp::PetscKSP) - -Wrapper to KSPSetUp -""" -function KSPSetUp(ksp::PetscKSP) - error = ccall((:KSPSetUp, libpetsc), PetscErrorCode, (CKSP,), ksp) - @assert iszero(error) -end - -""" - KSPSolve(ksp::PetscKSP, b::PetscVec, x::PetscVec) - -Wrapper for KSPSolve -""" -function KSPSolve(ksp::PetscKSP, b::PetscVec, x::PetscVec) - error = ccall((:KSPSolve, libpetsc), PetscErrorCode, (CKSP, CVec, CVec), ksp, b, x) - @assert iszero(error) -end \ No newline at end of file From 4d6881786833c50d570ed86b54b73046d5bf2d01 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 14:25:23 +0200 Subject: [PATCH 08/40] convention for Vec --- src/KSP.jl | 4 +- src/Vec.jl | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vec.jl | 287 ------------------------------------------ 3 files changed, 366 insertions(+), 289 deletions(-) create mode 100644 src/Vec.jl delete mode 100644 src/vec.jl diff --git a/src/KSP.jl b/src/KSP.jl index 713483a..fe28181 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -11,12 +11,12 @@ end Base.cconvert(::Type{CKSP}, ksp::KSP) = ksp.ptr[] """ - create(::Type{KSP}, comm::MPI.Comm=MPI.COMM_WORLD) + create(::Type{KSP}, comm::MPI.Comm) Wrapper for `KSPCreate` https://petsc.org/release/docs/manualpages/KSP/KSPCreate/ """ -function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) +function create(::Type{KSP}, comm::MPI.Comm) ksp = KSP(comm) error = ccall( (:KSPCreate, libpetsc), diff --git a/src/Vec.jl b/src/Vec.jl new file mode 100644 index 0000000..10308b2 --- /dev/null +++ b/src/Vec.jl @@ -0,0 +1,364 @@ +const CVec = Ptr{Cvoid} + +struct Vec + ptr::Ref{CVec} + comm::MPI.Comm + + Vec(comm::MPI.Comm) = new(Ref{Ptr{Cvoid}}(), comm) +end + +# allows us to pass Vec objects directly into CVec ccall signatures +Base.cconvert(::Type{CVec}, vec::Vec) = vec.ptr[] + +""" + copy(x::Vec, y::Vec) + copy(x::Vec) + +Wrapper to `VecCopy` +https://petsc.org/release/docs/manualpages/Vec/VecCopy/ +""" +function copy(x::Vec, y::Vec) + error = ccall((:VecCopy, libpetsc), PetscErrorCode, (CVec, CVec), x, y) + @assert iszero(error) +end + +function copy(x::Vec) + y = duplicate(x) + copy(x, y) + return y +end + +""" + create(::Type{Vec},comm::MPI.Comm) + +Wrapper to `VecCreate` +https://petsc.org/release/docs/manualpages/Vec/VecCreate/ +""" +function create(::Type{Vec}, comm::MPI.Comm) + vec = Vec(comm) + error = ccall( + (:VecCreate, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Ptr{CVec}), + comm, + vec.ptr, + ) + @assert iszero(error) + return vec +end + +""" + duplicate(v::Vec) + +Wrapper for `VecDuplicate` +https://petsc.org/release/docs/manualpages/Vec/VecDuplicate/ +""" +function duplicate(v::Vec) + newv = Vec(v.comm) + error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), v, newv.ptr) + @assert iszero(error) + + return newv +end + +""" + setValue(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) + setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) + +Wrapper to `setValue`. Indexing starts at 0 (as in PETSc). +https://petsc.org/release/docs/manualpages/Vec/VecSetValue/ + +# Implementation + +For an unknow reason, calling PETSc.VecSetValue leads to an "undefined symbol: VecSetValue" error. +So this wrapper directly call VecSetValues (anyway, this is what is done in PETSc...) +""" +function setValue(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) + setValues(v, PetscIntOne, [row], [value], mode) +end + +function setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) + setValue(v, PetscInt(row), PetscScalar(value), mode) +end + +""" + setValues( + x::Vec, + ni::PetscInt, + ix::Vector{PetscInt}, + y::Vector{PetscScalar}, + iora::InsertMode, + ) + + setValues( + x::Vec, + I::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, + ) + setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) + +Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) +https://petsc.org/release/docs/manualpages/Vec/VecSetValues/ +""" +function setValues( + x::Vec, + ni::PetscInt, + ix::Vector{PetscInt}, + y::Vector{PetscScalar}, + iora::InsertMode, +) + error = ccall( + (:VecSetValues, libpetsc), + PetscErrorCode, + (CVec, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}, InsertMode), + x, + ni, + ix, + y, + iora, + ) + @assert iszero(error) +end + +function setValues( + x::Vec, + I::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, +) + setValues(x, PetscInt(length(I)), I, V, mode) +end + +function setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) + setValues(x, PetscInt.(I), PetscScalar.(V), mode) +end + +""" + setSizes(v::Vec, n::PetscInt, N::PetscInt) + +Wrapper to `VecSetSizes` +https://petsc.org/release/docs/manualpages/Vec/VecSetSizes/ +""" +function setSizes(v::Vec, n::PetscInt, N::PetscInt) + nr_loc = PetscInt(n) + nr_glo = PetscInt(N) + error = ccall( + (:VecSetSizes, libpetsc), + PetscErrorCode, + (CVec, PetscInt, PetscInt), + v, + nr_loc, + nr_glo, + ) + @assert iszero(error) +end + +""" + setFromOptions(vec::Vec) + +Wrapper to `VecSetFromOptions` +https://petsc.org/release/docs/manualpages/Vec/VecSetFromOptions/ +""" +function setFromOptions(vec::Vec) + error = ccall((:VecSetFromOptions, libpetsc), PetscErrorCode, (CVec,), vec) + @assert iszero(error) +end + +""" + VecSetUp(vec::Vec) + +Wrapper to `VecSetUp` +https://petsc.org/release/docs/manualpages/Vec/VecSetUp/ +""" +function VecSetUp(v::Vec) + error = ccall((:VecSetUp, libpetsc), PetscErrorCode, (CVec,), v) + @assert iszero(error) +end + +""" + getOwnershipRange(x::Vec) + +Wrapper to `VecGetOwnershipRange` +https://petsc.org/release/docs/manualpages/Vec/VecGetOwnershipRange/ + +The result `(rstart, rend)` is a Tuple indicating the rows handled by the local processor. + +# Warning + +`PETSc` indexing starts at zero (so `rstart` may be zero) and `rend-1` is the last row +handled by the local processor. +""" +function getOwnershipRange(x::Vec) + rstart = Ref{PetscInt}(0) + rend = Ref{PetscInt}(0) + + error = ccall( + (:VecGetOwnershipRange, libpetsc), + PetscErrorCode, + (CVec, Ref{PetscInt}, Ref{PetscInt}), + x, + rstart, + rend, + ) + @assert iszero(error) + + return rstart[], rend[] +end + +""" + getSize(x::Vec) + +Wrapper for `VecGetSize` +https://petsc.org/release/docs/manualpages/Vec/VecGetSize/ +""" +function getSize(x::Vec) + n = Ref{PetscInt}() + + error = ccall((:VecGetSize, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}), x, n) + @assert iszero(error) + + return n[] +end + +""" + VecGetLocalSize(vec::Vec) + +Wrapper for `VecGetLocalSize` +https://petsc.org/release/docs/manualpages/Vec/VecGetLocalSize/ +""" +function getLocalSize(x::Vec) + n = Ref{PetscInt}() + + error = ccall((:VecGetLocalSize, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}), x, n) + @assert iszero(error) + + return n[] +end + +""" + assemblyBegin(vec::Vec) + +Wrapper to `VecAssemblyBegin` +https://petsc.org/release/docs/manualpages/Vec/VecAssemblyBegin/ +""" +function assemblyBegin(vec::Vec) + error = ccall((:VecAssemblyBegin, libpetsc), PetscErrorCode, (CVec,), vec) + @assert iszero(error) +end + +""" + assemblyEnd(vec::Vec) + +Wrapper to `VecAssemblyEnd` +https://petsc.org/release/docs/manualpages/Vec/VecAssemblyEnd/ +""" +function assemblyEnd(vec::Vec) + error = ccall((:VecAssemblyEnd, libpetsc), PetscErrorCode, (CVec,), vec) + @assert iszero(error) +end + +""" + getArray(x::Vec, own::Bool = false) + +Wrapper for `VecGetArray` +https://petsc.org/release/docs/manualpages/Vec/VecGetArray/ + +# Warning + +I am not confortable at all with memory management, both on the C side and on the Julia side. Use +this at you own risk. + +According to Julia documentation, `own` optionally specifies whether Julia should take ownership +of the memory, calling free on the pointer when the array is no longer referenced." +""" +function getArray(x::Vec, own::Bool = false) + # Get array pointer + array_ref = Ref{Ptr{PetscScalar}}() + error = ccall( + (:VecGetArray, libpetsc), + PetscErrorCode, + (CVec, Ref{Ptr{PetscScalar}}), + x, + array_ref, + ) + @assert iszero(error) + + # Get array size + rstart, rend = getOwnershipRange(x) + n = rend - rstart # this is not `rend - rstart + 1` because of VecGetOwnershipRange convention + + array = unsafe_wrap(Array, array_ref[], n; own = own) + + return array, array_ref +end + +""" + VecRestoreArray(vec::Vec, array_ref) + +Wrapper for `VecRestoreArray`. `array_ref` is obtained from `VecGetArray` +https://petsc.org/release/docs/manualpages/Vec/VecRestoreArray/ +""" +function restoreArray(x::Vec, array_ref) + error = ccall( + (:VecRestoreArray, libpetsc), + PetscErrorCode, + (CVec, Ref{Ptr{PetscScalar}}), + x, + array_ref, + ) + @assert iszero(error) +end + +""" + scale(x::Vec, alpha::PetscScalar) + scale(x::Vec, alpha::Number) + +Wrapper for `VecScale` +https://petsc.org/release/docs/manualpages/Vec/VecScale/ +""" +function scale(x::Vec, alpha::PetscScalar) + error = ccall((:VecScale, libpetsc), PetscErrorCode, (CVec, PetscScalar), x, alpha) + @assert iszero(error) +end + +scale(x::Vec, alpha::Number) = scale(x, PetscScalar(alpha)) + +""" + view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) + +Wrapper to `VecView` +https://petsc.org/release/docs/manualpages/Vec/VecView/ +""" +function view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) + error = ccall((:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer) + @assert iszero(error) +end + +""" + destroy(v::Vec) + +Wrapper to `VecDestroy` +https://petsc.org/release/docs/manualpages/Vec/VecDestroy/ +""" +function destroy(v::Vec) + error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v.ptr) + @assert iszero(error) +end + +""" + setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) + +Wrapper to `VecSetLocalToGlobalMapping` +https://petsc.org/release/docs/manualpages/Vec/VecSetLocalToGlobalMapping/ +""" +function setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) + error = ccall( + (:VecSetLocalToGlobalMapping, libpetsc), + PetscErrorCode, + (CVec, CISLocalToGlobalMapping), + x, + mapping, + ) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/vec.jl b/src/vec.jl deleted file mode 100644 index c9caa3f..0000000 --- a/src/vec.jl +++ /dev/null @@ -1,287 +0,0 @@ -const CVec = Ptr{Cvoid} - -struct PetscVec - ptr::Ref{CVec} - comm::MPI.Comm - - PetscVec(comm::MPI.Comm) = new(Ref{Ptr{Cvoid}}(), comm) -end - -# allows us to pass PetscVec objects directly into CVec ccall signatures -Base.cconvert(::Type{CVec}, vec::PetscVec) = vec.ptr[] - -""" - VecCopy(x::PetscVec, y::PetscVec) - -Wrapper to `VecCopy`. - -https://petsc.org/main/docs/manualpages/Vec/VecCopy.html -""" -function VecCopy(x::PetscVec, y::PetscVec) - error = ccall((:VecCopy, libpetsc), PetscErrorCode, (CVec, CVec), x, y) - @assert iszero(error) -end - -""" - VecCopy(x::PetscVec) - -Wrapper to `VecCopy`, expect that `y` is first obtained by `VecDuplicate` -""" -function VecCopy(x::PetscVec) - y = VecDuplicate(x) - VecCopy(x,y) - return y -end - -""" - VecCreate(comm::MPI.Comm, vec::PetscVec) - -Wrapper to VecCreate -""" -function VecCreate(comm::MPI.Comm = MPI.COMM_WORLD) - vec = PetscVec(comm) - error = ccall((:VecCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CVec}), comm, vec.ptr) - @assert iszero(error) - return vec -end - -""" - VecDuplicate(vec::PetscVec) - -Wrapper for VecDuplicate, except that it returns the new vector instead of taking it as an input. - -https://petsc.org/main/docs/manualpages/Vec/VecDuplicate.html -""" -function VecDuplicate(vec::PetscVec) - x = PetscVec(vec.comm) - error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), vec, x.ptr) - @assert iszero(error) - - return x -end - -""" - VecSetValue(vec::PetscVec, i::PetscInt, v::PetscScalar, mode::InsertMode = INSERT_VALUES) - -Wrapper to `VecSetValue`. Indexing starts at 0 (as in PETSc). - -# Implementation -For an unknow reason, calling PETSc.VecSetValue leads to an "undefined symbol: VecSetValue" error. -So this wrapper directly call VecSetValues (anyway, this is what is done in PETSc...) -""" -function VecSetValue(vec::PetscVec, i::PetscInt, v::PetscScalar, mode::InsertMode = INSERT_VALUES) - VecSetValues(vec, PetscIntOne, [i], [v], mode) -end - -function VecSetValue(vec::PetscVec, i, v, mode::InsertMode = INSERT_VALUES) - VecSetValue(vec, PetscInt(i), PetscScalar(v), mode) -end - -""" - VecSetValues(vec::PetscVec, nI::PetscInt, I::Vector{PetscInt}, V::Array{PetscScalar}, mode::InsertMode = INSERT_VALUES) - -Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) -""" -function VecSetValues(vec::PetscVec, nI::PetscInt, I::Vector{PetscInt}, V::Array{PetscScalar}, mode::InsertMode = INSERT_VALUES) - error = ccall((:VecSetValues, libpetsc), PetscErrorCode, - (CVec, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}, InsertMode), - vec, nI, I, V, mode) - @assert iszero(error) -end - -function VecSetValues(vec::PetscVec, I::Vector{PetscInt}, V::Array{PetscScalar}, mode::InsertMode = INSERT_VALUES) - VecSetValues(vec, PetscInt(length(I)), I, V, mode) -end - -function VecSetValues(vec::PetscVec, I, V, mode::InsertMode = INSERT_VALUES) - VecSetValues(vec, PetscInt.(I), PetscScalar.(V), mode) -end - - -""" - VecSetSizes(vec::PetscVec, nrows_loc, nrows_glo) - -Wrapper to VecSetSizes -""" -function VecSetSizes(vec::PetscVec, nrows_loc, nrows_glo) - nr_loc = PetscInt(nrows_loc) - nr_glo = PetscInt(nrows_glo) - error = ccall((:VecSetSizes, libpetsc), - PetscErrorCode, - (CVec, PetscInt, PetscInt), - vec, nr_loc, nr_glo - ) - @assert iszero(error) -end - -""" - VecSetFromOptions(vec::PetscVec) - -Wrapper to VecSetFromOptions -""" -function VecSetFromOptions(vec::PetscVec) - error = ccall((:VecSetFromOptions, libpetsc), PetscErrorCode, (CVec,), vec) - @assert iszero(error) -end - -""" - VecSetUp(vec::PetscVec) - -Wrapper to VecSetUp -""" -function VecSetUp(vec::PetscVec) - error = ccall((:VecSetUp, libpetsc), PetscErrorCode, (CVec,), vec) - @assert iszero(error) -end - -""" - VecGetOwnershipRange(vec::PetscVec) - -Wrapper to `VecGetOwnershipRange` - -The result `(rstart, rend)` is a Tuple indicating the rows handled by the local processor. - -# Warning -`PETSc` indexing starts at zero (so `rstart` may be zero) and `rend-1` is the last row -handled by the local processor. -""" -function VecGetOwnershipRange(vec::PetscVec) - rstart = Ref{PetscInt}(0) - rend = Ref{PetscInt}(0) - - error = ccall((:VecGetOwnershipRange, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}, Ref{PetscInt}), vec, rstart, rend) - @assert iszero(error) - - return rstart[], rend[] -end - -""" - VecGetSize(vec::PetscVec) - -Wrapper for VecGetSize -""" -function VecGetSize(vec::PetscVec) - n = Ref{PetscInt}() - - error = ccall((:VecGetSize, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}), vec, n) - @assert iszero(error) - - return n[] -end - -""" - VecGetLocalSize(vec::PetscVec) - -Wrapper for VecGetLocalSize -""" -function VecGetLocalSize(vec::PetscVec) - n = Ref{PetscInt}() - - error = ccall((:VecGetLocalSize, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}), vec, n) - @assert iszero(error) - - return n[] -end - -""" - VecAssemblyBegin(vec::PetscVec) - -Wrapper to VecAssemblyBegin -""" -function VecAssemblyBegin(vec::PetscVec) - error = ccall((:VecAssemblyBegin, libpetsc), PetscErrorCode, (CVec,), vec) - @assert iszero(error) -end - -""" - VecAssemblyEnd(vec::PetscVec) - -Wrapper to VecAssemblyEnd -""" -function VecAssemblyEnd(vec::PetscVec) - error = ccall((:VecAssemblyEnd, libpetsc), PetscErrorCode, (CVec,), vec) - @assert iszero(error) -end - -""" - VecGetArray(vec::PetscVec, own = false) - -Wrapper for VecGetArray. - -# Warning -I am not confortable at all with memory management, both on the C side and on the Julia side. Use -this at you own risk. - -According to Julia documentation, `own` optionally specifies whether Julia should take ownership -of the memory, calling free on the pointer when the array is no longer referenced." - -""" -function VecGetArray(vec::PetscVec, own = false) - # Get array pointer - array_ref = Ref{Ptr{PetscScalar}}() - error = ccall((:VecGetArray, libpetsc), PetscErrorCode, (CVec, Ref{Ptr{PetscScalar}}), vec, array_ref) - @assert iszero(error) - - # Get array size - rstart, rend = VecGetOwnershipRange(vec) - n = rend - rstart # this is not `rend - rstart + 1` because of VecGetOwnershipRange convention - - array = unsafe_wrap(Array, array_ref[], n; own = own) - - return array, array_ref -end - -""" - VecRestoreArray(vec::PetscVec, array_ref) - -Wrapper for VecRestoreArray. `array_ref` is obtained from `VecGetArray` -""" -function VecRestoreArray(vec::PetscVec, array_ref) - error = ccall((:VecRestoreArray, libpetsc), PetscErrorCode, (CVec, Ref{Ptr{PetscScalar}}), vec, array_ref) - @assert iszero(error) -end - -""" - VecScale(vec::PetscVec, alpha::PetscScalar) - -Wrapper for `VecScale` - -https://petsc.org/main/docs/manualpages/Vec/VecScale.html -""" -function VecScale(vec::PetscVec, alpha::PetscScalar) - error = ccall((:VecScale, libpetsc), PetscErrorCode, (CVec, PetscScalar), vec, alpha) - @assert iszero(error) -end - -VecScale(vec::PetscVec, alpha::Number) = VecScale(vec, PetscScalar(alpha)) - -""" - VecView(vec::PetscVec, viewer::PetscViewer = PetscViewerStdWorld()) - -Wrapper to `VecView`. -""" -function VecView(vec::PetscVec, viewer::PetscViewer = PetscViewerStdWorld()) - error = ccall( (:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer); - @assert iszero(error) -end - -""" - VecDestroy(vec::PetscVec) - -Wrapper to VecDestroy -""" -function VecDestroy(vec::PetscVec) - error = ccall( (:VecDestroy, libpetsc), - PetscErrorCode, - (Ptr{CVec},), - vec.ptr) - @assert iszero(error) -end - -function VecSetLocalToGlobalMapping(vec::PetscVec, l2g::ISLocalToGlobalMapping) - error = ccall( (:VecSetLocalToGlobalMapping, libpetsc), - PetscErrorCode, - (CVec,CISLocalToGlobalMapping), - vec, l2g) - @assert iszero(error) -end \ No newline at end of file From 879068dc82603e59c8bd3a3e0e54ae5a42613094 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 14:27:53 +0200 Subject: [PATCH 09/40] convention for ISLocalToGlobalMapping --- ...al2global.jl => ISLocalToGlobalMapping.jl} | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) rename src/{local2global.jl => ISLocalToGlobalMapping.jl} (65%) diff --git a/src/local2global.jl b/src/ISLocalToGlobalMapping.jl similarity index 65% rename from src/local2global.jl rename to src/ISLocalToGlobalMapping.jl index 9849a3d..d512bc0 100644 --- a/src/local2global.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -10,8 +10,20 @@ end # allows us to pass ISLocalToGlobalMapping objects directly into CISLocalToGlobalMapping ccall signatures Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2g.ptr[] +""" + localToGlobalMappingCreate( + comm::MPI.Comm, + bs::PetscInt, + n::PetscInt, + indices::Vector{PetscInt}, + mode::PetscCopyMode, + ) -function ISLocalToGlobalMappingCreate( +Wrapper to `ISLocalToGlobalMappingCreate` +https://petsc.org/release/docs/manualpages/IS/ISLocalToGlobalMappingCreate/ +""" +function create( + ::Type{ISLocalToGlobalMapping}, comm::MPI.Comm, bs::PetscInt, n::PetscInt, @@ -41,12 +53,18 @@ function ISLocalToGlobalMappingCreate( return l2g end -function ISLocalToGlobalMappingDestroy(l2g::ISLocalToGlobalMapping) +""" + destroy(mapping::ISLocalToGlobalMapping) + +Wrapper to `ISLocalToGlobalMappingDestroy` +https://petsc.org/release/docs/manualpages/IS/ISLocalToGlobalMappingDestroy/ +""" +function destroy(mapping::ISLocalToGlobalMapping) error = ccall( (:ISLocalToGlobalMappingDestroy, libpetsc), PetscErrorCode, (Ptr{CISLocalToGlobalMapping},), - l2g.ptr, + mapping.ptr, ) @assert iszero(error) end \ No newline at end of file From 62290934f7b8a1e2b2e97a7e88924d8327d63e3f Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 14:52:07 +0200 Subject: [PATCH 10/40] convention for Mat --- src/Mat.jl | 643 ++++++++++++++++++++++++++++++++++++++++++ src/const_arch_ind.jl | 1 + src/mat.jl | 379 ------------------------- 3 files changed, 644 insertions(+), 379 deletions(-) create mode 100644 src/Mat.jl delete mode 100644 src/mat.jl diff --git a/src/Mat.jl b/src/Mat.jl new file mode 100644 index 0000000..d53d7c8 --- /dev/null +++ b/src/Mat.jl @@ -0,0 +1,643 @@ +const CMat = Ptr{Cvoid} + +""" + A Petsc matrix, actually just a pointer to the actual C matrix +""" +struct Mat + ptr::Ref{CMat} + comm::MPI.Comm + + Mat(comm::MPI.Comm) = new(Ref{CMat}(), comm) +end + + +# allows us to pass Mat objects directly into CMat ccall signatures +Base.cconvert(::Type{CMat}, mat::Mat) = mat.ptr[] + +""" + assemblyBegin(mat::Mat, type::MatAssemblyType) + +Wrapper to `MatAssemblyBegin` +https://petsc.org/release/docs/manualpages/Mat/MatAssemblyBegin/ +""" +function assemblyBegin(mat::Mat, type::MatAssemblyType) + error = ccall( + (:MatAssemblyBegin, libpetsc), + PetscErrorCode, + (CMat, MatAssemblyType), + mat, + type, + ) + @assert iszero(error) +end + +""" + assemblyEnd(mat::Mat, type::MatAssemblyType) + +Wrapper to `MatAssemblyEnd` +https://petsc.org/release/docs/manualpages/Mat/MatAssemblyEnd/ +""" +function assemblyEnd(mat::Mat, type::MatAssemblyType) + error = ccall( + (:MatAssemblyEnd, libpetsc), + PetscErrorCode, + (CMat, MatAssemblyType), + mat, + type, + ) + @assert iszero(error) +end + + +""" + compositeAddMat(mat::Mat, smat::Mat) + +Wrapper to `MatCompositeAddMat` +https://petsc.org/release/docs/manualpages/Mat/MatCompositeAddMat/ +""" +function compositeAddMat(mat::Mat, smat::Mat) + error = ccall((:MatCompositeAddMat, libpetsc), PetscErrorCode, (CMat, CMat), mat, smat) + @assert iszero(error) +end + +""" + create(::Type{Mat}, comm::MPI.Comm) + +Wrapper to `MatCreate` +https://petsc.org/release/docs/manualpages/Mat/MatCreate/ +""" +function create(::Type{Mat}, comm::MPI.Comm) + mat = Mat(comm) + error = ccall( + (:MatCreate, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Ptr{CMat}), + comm, + mat.ptr, + ) + @assert iszero(error) + return mat +end + +""" + createDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + createDense( + comm::MPI.Comm, + m::Integer = PETSC_DECIDE, + n::Integer = PETSC_DECIDE, + M::Integer = PETSC_DECIDE, + N::Integer = PETSC_DECIDE, + ) + +Wrapper to `MatCreateDense` +https://petsc.org/release/docs/manualpages/Mat/MatCreateDense/ + +Last argument `data` is not supported yet (NULL is passed). +""" +function createDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + mat = Mat(comm) + error = ccall( + (:MatCreateDense, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, Ptr{PetscScalar}, Ptr{CMat}), + comm, + m, + n, + M, + N, + C_NULL, + mat.ptr, + ) + @assert iszero(error) + return mat +end + +function createDense( + comm::MPI.Comm, + m::Integer = PETSC_DECIDE, + n::Integer = PETSC_DECIDE, + M::Integer = PETSC_DECIDE, + N::Integer = PETSC_DECIDE, +) + + return createDense(comm, PetscInt(m), PetscInt(n), PetscInt(M), PetscInt(N)) +end + +""" + createVecs(mat::Mat, vecr::PetscVec, veci::PetscVec) + createVecs(mat::Mat) + +Wrapper to `MatCreateVecs` +https://petsc.org/release/docs/manualpages/Mat/MatCreateVecs/ +""" +function createVecs(mat::Mat, right::PetscVec, left::PetscVec) + error = ccall( + (:MatCreateVecs, libpetsc), + PetscErrorCode, + (CMat, Ptr{CVec}, Ptr{CVec}), + mat, + right.ptr, + left.ptr, + ) + @assert iszero(error) +end + +function createVecs(mat::Mat) + right = PetscVec(mat.comm) + left = PetscVec(mat.comm) + createVecs(mat, right, left) + return right, left +end + +""" + destroy(A::Mat) + +Wrapper to `MatDestroy` +https://petsc.org/release/docs/manualpages/Mat/MatDestroy/ +""" +function destroy(A::Mat) + error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), A.ptr) + @assert iszero(error) +end + +""" + getLocalSize(mat::Mat) + +Wrapper to `MatGetLocalSize` +https://petsc.org/release/docs/manualpages/Mat/MatGetLocalSize/ + +Return the number of local rows and cols of the matrix (i.e on the processor). +""" +function getLocalSize(mat::Mat) + m = Ref{PetscInt}(0) + n = Ref{PetscInt}(0) + + error = ccall( + (:MatGetLocalSize, libpetsc), + PetscErrorCode, + (CMat, Ref{PetscInt}, Ref{PetscInt}), + mat, + m, + n, + ) + @assert iszero(error) + + return m[], n[] +end + +""" + getOwnershipRange(mat::Mat) + +Wrapper to `MatGetOwnershipRange` +https://petsc.org/release/docs/manualpages/Mat/MatGetOwnershipRange/ + +The result `(rstart, rend)` is a Tuple indicating the rows handled by the local processor. + +# Warning + +`PETSc` indexing starts at zero (so `rstart` may be zero) and `rend-1` is the last row +handled by the local processor. +""" +function getOwnershipRange(mat::Mat) + rstart = Ref{PetscInt}(0) + rend = Ref{PetscInt}(0) + + error = ccall( + (:MatGetOwnershipRange, libpetsc), + PetscErrorCode, + (CMat, Ref{PetscInt}, Ref{PetscInt}), + mat, + rstart, + rend, + ) + @assert iszero(error) + + return rstart[], rend[] +end + +""" + getOwnershipRangeColumn(mat::Mat) + +Wrapper to `MatGetOwnershipRangeColumn` +https://petsc.org/release/docs/manualpages/Mat/MatGetOwnershipRangeColumn/ + +The result `(cstart, cend)` is a Tuple indicating the columns handled by the local processor. + +# Warning + +`PETSc` indexing starts at zero (so `cstart` may be zero) and `cend-1` is the last column +handled by the local processor. +""" +function getOwnershipRangeColumn(mat::Mat) + cstart = Ref{PetscInt}(0) + cend = Ref{PetscInt}(0) + + error = ccall( + (:MatGetOwnershipRangeColumn, libpetsc), + PetscErrorCode, + (CMat, Ref{PetscInt}, Ref{PetscInt}), + mat, + cstart, + cend, + ) + @assert iszero(error) + + return cstart[], cend[] +end + +""" + getSize(mat::Mat) + +Wrapper to `MatGetSize` +https://petsc.org/release/docs/manualpages/Mat/MatGetSize/ + +Return the number of rows and cols of the matrix (global number). +""" +function getSize(mat::Mat) + nrows_glo = Ref{PetscInt}(0) + ncols_glo = Ref{PetscInt}(0) + + error = ccall( + (:MatGetSize, libpetsc), + PetscErrorCode, + (CMat, Ref{PetscInt}, Ref{PetscInt}), + mat, + nrows_glo, + ncols_glo, + ) + @assert iszero(error) + + return nrows_glo[], ncols_glo[] +end + +""" + getType(mat::Mat) + +Wrapper to `MatGetType` +https://petsc.org/release/docs/manualpages/Mat/MatType/ + +Return the matrix type as a string. See matrix types here: +https://petsc.org/release/docs/manualpages/Mat/MatType.html +""" +function getType(mat::Mat) + type = Ref{Cstring}() + + error = ccall((:MatGetType, libpetsc), PetscErrorCode, (CMat, Ptr{Cstring}), mat, type) + @assert iszero(error) + + return unsafe_string(type[]) +end + +""" + mult(mat::Mat, x::PetscVec, y::PetscVec) + +Wrapper to `MatMult` +https://petsc.org/release/docs/manualpages/Mat/MatMult/ + +Compute `y = Ax` +""" +function mult(mat::Mat, x::PetscVec, y::PetscVec) + error = ccall((:MatMult, libpetsc), PetscErrorCode, (CMat, CVec, CVec), mat, x, y) + @assert iszero(error) +end + +""" + multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + +Wrapper to `MatMultAdd` +https://petsc.org/release/docs/manualpages/Mat/MatMultAdd/ + +Compute `v3 = v2 + A * v1`. +""" +function multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + error = ccall( + (:MatMultAdd, libpetsc), + PetscErrorCode, + (CMat, CVec, CVec, CVec), + A, + v1, + v2, + v3, + ) + @assert iszero(error) +end + +""" + setFromOptions(mat::Mat) + +Wrapper to `MatSetFromOptions` +https://petsc.org/release/docs/manualpages/Mat/MatSetFromOptions/ +""" +function setFromOptions(mat::Mat) + error = ccall((:MatSetFromOptions, libpetsc), PetscErrorCode, (CMat,), mat) + @assert iszero(error) +end + +""" + setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + setSizes( + mat::Mat, + nrows_loc::Integer, + ncols_loc::Integer, + nrows_glo::Integer, + ncols_glo::Integer, + ) + +Wrapper to `MatSetSizes` +https://petsc.org/release/docs/manualpages/Mat/MatSetSizes/ +""" +function setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + error = ccall( + (:MatSetSizes, libpetsc), + PetscErrorCode, + (CMat, PetscInt, PetscInt, PetscInt, PetscInt), + mat, + m, + n, + M, + N, + ) + @assert iszero(error) +end + +function setSizes( + mat::Mat, + nrows_loc::Integer, + ncols_loc::Integer, + nrows_glo::Integer, + ncols_glo::Integer, +) + setSizes( + mat, + PetscInt(nrows_loc), + PetscInt(ncols_loc), + PetscInt(nrows_glo), + PetscInt(ncols_glo), + ) +end + +""" + setType(mat::Mat, type::String) + +Wrapper for `MatSetType` +https://petsc.org/release/docs/manualpages/Mat/MatSetType/ + +Values for `type` alors available here: +https://petsc.org/release/docs/manualpages/Mat/MatType.html#MatType +""" +function setType(mat::Mat, type::String) + error = ccall((:MatSetType, libpetsc), PetscErrorCode, (CMat, Cstring), mat, type) + @assert iszero(error) +end + + +""" + setUp(mat::Mat) + +Wrapper to `MatSetUp` +https://petsc.org/release/docs/manualpages/Mat/MatSetUp/ +""" +function setUp(mat::Mat) + error = ccall((:MatSetUp, libpetsc), PetscErrorCode, (CMat,), mat) + @assert iszero(error) +end + +""" + MPIAIJSetPreallocation( + B::Mat, + d_nz::PetscInt, + d_nnz::Vector{PetscInt}, + o_nz::PetscInt, + o_nnz::Vector{PetscInt}, + ) + MPIAIJSetPreallocation(mat::Mat, dnz::PetscInt, onz::PetscInt) + +Wrapper to `MatMPIAIJSetPreallocation` +https://petsc.org/release/docs/manualpages/Mat/MatMPIAIJSetPreallocation/ + +# Warning + +`dnnz` and `onnz` not tested yet. + +# Arguments + + - `dnz::PetscInt`: number of nonzeros per row in DIAGONAL portion of local submatrix (same value is used for all local rows) + - `dnnz::Vector{PetscInt}`: array containing the number of nonzeros in the various rows of the DIAGONAL portion of the local + submatrix (possibly different for each row) or NULL (PETSC_NULL_INTEGER in Fortran), if d_nz is used to specify the nonzero + structure. The size of this array is equal to the number of local rows, i.e 'm'. For matrices that will be factored, you + must leave room for (and set) the diagonal entry even if it is zero. + - `onz::PetscInt`: number of nonzeros per row in the OFF-DIAGONAL portion of local submatrix (same value is used for all local rows). + - `onnz::Vector{PetscInt}`: array containing the number of nonzeros in the various rows of the OFF-DIAGONAL portion of the local + submatrix (possibly different for each row) or NULL (PETSC_NULL_INTEGER in Fortran), if o_nz is used to specify the nonzero structure. + The size of this array is equal to the number of local rows, i.e 'm'. +""" +function MPIAIJSetPreallocation( + B::Mat, + d_nz::PetscInt, + d_nnz::Vector{PetscInt}, + o_nz::PetscInt, + o_nnz::Vector{PetscInt}, +) + error = ccall( + (:MatMPIAIJSetPreallocation, libpetsc), + PetscErrorCode, + (CMat, PetscInt, Ptr{PetscInt}, PetscInt, Ptr{PetscInt}), + B, + d_nz, + d_nnz, + o_nz, + o_nnz, + ) + @assert iszero(error) +end + +function MPIAIJSetPreallocation(mat::Mat, dnz::PetscInt, onz::PetscInt) + error = ccall( + (:MatMPIAIJSetPreallocation, libpetsc), + PetscErrorCode, + (CMat, PetscInt, Ptr{PetscInt}, PetscInt, Ptr{PetscInt}), + mat, + dnz, + C_NULL, + onz, + C_NULL, + ) + @assert iszero(error) +end + +""" + SeqAIJSetPreallocation(mat::Mat, nz::PetscInt, nnz::Vector{PetscInt}) + SeqAIJSetPreallocation(mat::Mat, nz::PetscInt) + +Wrapper to `MatSeqAIJSetPreallocation` +https://petsc.org/release/docs/manualpages/Mat/MatSeqAIJSetPreallocation/ +""" +function SeqAIJSetPreallocation(mat::Mat, nz::PetscInt, nnz::Vector{PetscInt}) + error = ccall( + (:MatSeqAIJSetPreallocation, libpetsc), + PetscErrorCode, + (CMat, PetscInt, Ptr{PetscInt}), + mat, + nz, + nnz, + ) + @assert iszero(error) +end + +function SeqAIJSetPreallocation(mat::Mat, nz::PetscInt) + error = ccall( + (:MatSeqAIJSetPreallocation, libpetsc), + PetscErrorCode, + (CMat, PetscInt, Ptr{PetscInt}), + mat, + nz, + C_NULL, + ) + @assert iszero(error) +end + +""" + setOption(mat::Mat, op::MatOption, flg::PetscBool) + +Wrapper for `MatSetOption` +https://petsc.org/release/docs/manualpages/Mat/MatSetOption/ +""" +function setOption(mat::Mat, op::MatOption, flg::PetscBool) + error = ccall( + (:MatSetOption, libpetsc), + PetscErrorCode, + (CMat, MatOption, Cuchar), + mat, + op, + flg, + ) + @assert iszero(error) +end + +setOption(mat::Mat, op::MatOption, flg::Bool) = setOption(mat, op, bool2petsc(flg)) + +# Avoid allocating an array of size 1 for each call to MatSetValue +const _ivec = zeros(PetscInt, 1) +const _jvec = zeros(PetscInt, 1) +const _vvec = zeros(PetscScalar, 1) + +""" + setValue( + m::Mat, + row::PetscInt, + col::PetscInt, + value::PetscScalar, + mode::InsertMode, + ) + setValue(m::Mat, row::Integer, col::Integer, value::Number, mode::InsertMode) + +Wrapper to `MatSetValue` +https://petsc.org/release/docs/manualpages/Mat/MatSetValue/ + +Indexing starts at 0 (as in PETSc). + +# Implementation + +For an unknow reason, calling PETSc.MatSetValue leads to an "undefined symbol: MatSetValue" error. +So this wrapper directly call MatSetValues (anyway, this is what is done in PETSc...) +""" +function setValue( + m::Mat, + row::PetscInt, + col::PetscInt, + value::PetscScalar, + mode::InsertMode, +) + # Convert to arrays + _ivec[1] = row + _jvec[1] = col + _vvec[1] = value + + setValues(m, PetscIntOne, _ivec, PetscIntOne, _jvec, _vvec, mode) + #MatSetValues(mat, PetscIntOne, [i], PetscIntOne, [j], [v], mode) +end + +function setValue(m::Mat, row::Integer, col::Integer, value::Number, mode::InsertMode) + setValue(m, PetscInt(row), PetscInt(col), PetscScalar(value), mode) +end + +""" + setValues( + mat::Mat, + m::PetscInt, + idxm::Vector{PetscInt}, + n::PetscInt, + idxn::Vector{PetscInt}, + V::Array{PetscScalar}, + addv::InsertMode, + ) + setValues( + mat::Mat, + I::Vector{PetscInt}, + J::Vector{PetscInt}, + V::Array{PetscScalar}, + mode::InsertMode, + ) + setValues(mat::Mat, I, J, V, mode::InsertMode) + +Wrapper to `MatSetValues` +https://petsc.org/release/docs/manualpages/Mat/MatSetValues/ + +Indexing starts at 0 (as in PETSc) +""" +function setValues( + mat::Mat, + m::PetscInt, + idxm::Vector{PetscInt}, + n::PetscInt, + idxn::Vector{PetscInt}, + V::Array{PetscScalar}, + addv::InsertMode, +) + error = ccall( + (:MatSetValues, libpetsc), + PetscErrorCode, + ( + CMat, + PetscInt, + Ptr{PetscInt}, + PetscInt, + Ptr{PetscInt}, + Ptr{PetscScalar}, + InsertMode, + ), + mat, + m, + idxm, + n, + idxn, + V, + addv, + ) + @assert iszero(error) +end + +function setValues( + mat::Mat, + I::Vector{PetscInt}, + J::Vector{PetscInt}, + V::Array{PetscScalar}, + mode::InsertMode, +) + setValues(mat, PetscInt(length(I)), I, PetscInt(length(J)), J, V, mode) +end + +function setValues(mat::Mat, I, J, V, mode::InsertMode) + setValues(mat, PetscInt.(I), PetscInt.(collect(J)), PetscScalar.(V), mode) +end + +""" + view(mat::Mat, viewer::PetscViewer = PetscViewerStdWorld()) + +Wrapper to `MatView` +https://petsc.org/release/docs/manualpages/Mat/MatView/ +""" +function view(mat::Mat, viewer::PetscViewer = PetscViewerStdWorld()) + error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index 1d115b5..4b8f9be 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -20,6 +20,7 @@ end @enum PetscBool PETSC_FALSE PETSC_TRUE Base.Bool(x::PetscBool) = x == PETSC_TRUE +bool2petsc(x::Bool) = x ? PETSC_TRUE : PETSC_FALSE @enum PetscCopyMode begin PETSC_COPY_VALUES diff --git a/src/mat.jl b/src/mat.jl deleted file mode 100644 index 6e3e10c..0000000 --- a/src/mat.jl +++ /dev/null @@ -1,379 +0,0 @@ -const CMat = Ptr{Cvoid} - -""" - A Petsc matrix, actually just a pointer to the actual C matrix -""" -struct PetscMat - ptr::Ref{CMat} - comm::MPI.Comm - - PetscMat(comm::MPI.Comm) = new(Ref{CMat}(), comm) -end - - -# allows us to pass PetscMat objects directly into CMat ccall signatures -Base.cconvert(::Type{CMat}, mat::PetscMat) = mat.ptr[] - -""" - Wrapper to `MatAssemblyBegin` -""" -function MatAssemblyBegin(mat::PetscMat, type::MatAssemblyType) - error = ccall((:MatAssemblyBegin, libpetsc), PetscErrorCode, (CMat, MatAssemblyType), mat, type) - @assert iszero(error) -end - -""" - Wrapper to `MatAssemblyEnd` -""" -function MatAssemblyEnd(mat::PetscMat, type::MatAssemblyType) - error = ccall((:MatAssemblyEnd, libpetsc), PetscErrorCode, (CMat, MatAssemblyType), mat, type) - @assert iszero(error) -end - - -""" - MatCompositeAddMat(mat::PetscMat, smat::PetscMat) - -Wrapper to `MatCompositeAddMat`. -""" -function MatCompositeAddMat(mat::PetscMat, smat::PetscMat) - error = ccall((:MatCompositeAddMat, libpetsc), PetscErrorCode, (CMat, CMat), mat, smat) - @assert iszero(error) -end - -""" - MatCreate(comm::MPI.Comm, mat::PetscMat) - -Wrapper to `MatCreate` -""" -function MatCreate(comm::MPI.Comm=MPI.COMM_WORLD) - mat = PetscMat(comm) - error = ccall((:MatCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CMat}), comm, mat.ptr) - @assert iszero(error) - return mat -end - -""" - MatCreateDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) - -Wrapper to `MatCreateDense`. Last argument `data` is not supported yet (NULL is passed). -""" -function MatCreateDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) - mat = PetscMat(comm) - error = ccall((:MatCreateDense, libpetsc), PetscErrorCode, - (MPI.MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, Ptr{PetscScalar}, Ptr{CMat}), - comm, m, n, M, N, C_NULL, mat.ptr) - @assert iszero(error) - return mat -end - -function MatCreateDense(comm::MPI.Comm, - m::Integer=PETSC_DECIDE, - n::Integer=PETSC_DECIDE, - M::Integer=PETSC_DECIDE, - N::Integer=PETSC_DECIDE) - - return MatCreateDense(comm, PetscInt(m), PetscInt(n), PetscInt(M), PetscInt(N)) -end - -""" - Wrapper to MatCreateVecs -""" -function MatCreateVecs(mat::PetscMat, vecr::PetscVec, veci::PetscVec) - error = ccall((:MatCreateVecs, libpetsc), PetscErrorCode, (CMat, Ptr{CVec}, Ptr{CVec}), mat, vecr.ptr, veci.ptr) - @assert iszero(error) -end - -function MatCreateVecs(mat::PetscMat) - vecr = PetscVec(mat.comm) - veci = PetscVec(mat.comm) - MatCreateVecs(mat, vecr, veci) - return vecr, veci -end - -""" - MatDestroy(mat::PetscMat) - -Wrapper to MatDestroy -""" -function MatDestroy(mat::PetscMat) - error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), mat.ptr) - @assert iszero(error) -end - -""" - MatGetLocalSize(mat::PetscMat) - -Wrapper to `MatGetLocalSize`. Return the number of local rows and cols of the matrix (i.e on the processor). -""" -function MatGetLocalSize(mat::PetscMat) - nrows_loc = Ref{PetscInt}(0) - ncols_loc = Ref{PetscInt}(0) - - error = ccall((:MatGetLocalSize, libpetsc), PetscErrorCode, (CMat, Ref{PetscInt}, Ref{PetscInt}), mat, nrows_loc, ncols_loc) - @assert iszero(error) - - return nrows_loc[], ncols_loc[] -end - -""" - MatGetOwnershipRange(mat::PetscMat) - -Wrapper to `MatGetOwnershipRange` - -The result `(rstart, rend)` is a Tuple indicating the rows handled by the local processor. - -# Warning -`PETSc` indexing starts at zero (so `rstart` may be zero) and `rend-1` is the last row -handled by the local processor. -""" -function MatGetOwnershipRange(mat::PetscMat) - rstart = Ref{PetscInt}(0) - rend = Ref{PetscInt}(0) - - error = ccall((:MatGetOwnershipRange, libpetsc), PetscErrorCode, (CMat, Ref{PetscInt}, Ref{PetscInt}), mat, rstart, rend) - @assert iszero(error) - - return rstart[], rend[] -end - -""" - MatGetOwnershipRangeColumn(mat::PetscMat) - -Wrapper to `MatGetOwnershipRangeColumn` - -The result `(cstart, cend)` is a Tuple indicating the columns handled by the local processor. - -# Warning -`PETSc` indexing starts at zero (so `cstart` may be zero) and `cend-1` is the last column -handled by the local processor. -""" -function MatGetOwnershipRangeColumn(mat::PetscMat) - cstart = Ref{PetscInt}(0) - cend = Ref{PetscInt}(0) - - error = ccall((:MatGetOwnershipRangeColumn, libpetsc), PetscErrorCode, (CMat, Ref{PetscInt}, Ref{PetscInt}), mat, cstart, cend) - @assert iszero(error) - - return cstart[], cend[] -end - -""" - MatGetSize(mat::PetscMat) - -Wrapper to `MatGetSize`. Return the number of rows and cols of the matrix (global number). -""" -function MatGetSize(mat::PetscMat) - nrows_glo = Ref{PetscInt}(0) - ncols_glo = Ref{PetscInt}(0) - - error = ccall((:MatGetSize, libpetsc), PetscErrorCode, (CMat, Ref{PetscInt}, Ref{PetscInt}), mat, nrows_glo, ncols_glo) - @assert iszero(error) - - return nrows_glo[], ncols_glo[] -end - -""" - MatGetType(mat::PetscMat) - -Wrapper to `MatGetType`. Return the matrix type as a string. See matrix types here: -https://petsc.org/release/docs/manualpages/Mat/MatType.html -""" -function MatGetType(mat::PetscMat) - type = Ref{Cstring}() - - error = ccall((:MatGetType, libpetsc), PetscErrorCode, (CMat, Ptr{Cstring}), mat, type) - @assert iszero(error) - - return unsafe_string(type[]) -end - - -""" - MatMult(mat::PetscMat, x::PetscVec, y::PetscVec) - -Wrapper to `MatMult`. Computes `y = Ax` - -https://petsc.org/main/docs/manualpages/Mat/MatMult.html -""" -function MatMult(mat::PetscMat, x::PetscVec, y::PetscVec) - error = ccall((:MatMult, libpetsc), PetscErrorCode, (CMat, CVec, CVec), mat, x, y) - @assert iszero(error) -end - -""" - MatMultAdd(A::PetscMat, v1::PetscVec, v2::PetscVec, v3::PetscVec) - -Wrapper to `MatMultAdd`. Computes `v3 = v2 + A * v1`. - -https://petsc.org/main/docs/manualpages/Mat/MatMultAdd.html -""" -function MatMultAdd(A::PetscMat, v1::PetscVec, v2::PetscVec, v3::PetscVec) - error = ccall((:MatMultAdd, libpetsc), PetscErrorCode, (CMat, CVec, CVec, CVec), A, v1, v2, v3) - @assert iszero(error) -end - -""" - MatSetFromOptions(mat::PetscMat) - -Wrapper to MatSetFromOptions -""" -function MatSetFromOptions(mat::PetscMat) - error = ccall((:MatSetFromOptions, libpetsc), PetscErrorCode, (CMat,), mat) - @assert iszero(error) -end - -""" - MatSetSizes(mat::PetscMat, nrows_loc::PetscInt, ncols_loc::PetscInt, nrows_glo::PetscInt, ncols_glo::PetscInt) - -Wrapper to MatSetSizes -""" -function MatSetSizes(mat::PetscMat, nrows_loc::PetscInt, ncols_loc::PetscInt, nrows_glo::PetscInt, ncols_glo::PetscInt) - error = ccall((:MatSetSizes, libpetsc), - PetscErrorCode, - (CMat, PetscInt, PetscInt, PetscInt, PetscInt), - mat, nrows_loc, ncols_loc, nrows_glo, ncols_glo - ) - @assert iszero(error) -end - -function MatSetSizes(mat::PetscMat, nrows_loc::Integer, ncols_loc::Integer, nrows_glo::Integer, ncols_glo::Integer) - MatSetSizes(mat, PetscInt(nrows_loc), PetscInt(ncols_loc), PetscInt(nrows_glo), PetscInt(ncols_glo)) -end - -""" - MatSetType(mat::PetscMat, type::String) - -Wrapper for `MatSetType`. Values for `type` alors available here: -https://petsc.org/release/docs/manualpages/Mat/MatType.html#MatType -""" -function MatSetType(mat::PetscMat, type::String) - error = ccall((:MatSetType, libpetsc), PetscErrorCode, (CMat, Cstring), mat, type) - @assert iszero(error) -end - - -""" - MatSetUp(mat::PetscMat) - -Wrapper to MatSetUp -""" -function MatSetUp(mat::PetscMat) - error = ccall((:MatSetUp, libpetsc), PetscErrorCode, (CMat,), mat) - @assert iszero(error) -end - -""" - MatMPIAIJSetPreallocation(mat::PetscMat, dnz::PetscInt, dnnz::Vector{PetscInt}, onz::PetscInt, onnz::Vector{PetscInt}) - -Wrapper to `MatMPIAIJSetPreallocation`. `dnnz` and `onnz` not tested yet. - -# Arguments -- `dnz::PetscInt`: number of nonzeros per row in DIAGONAL portion of local submatrix (same value is used for all local rows) -- `dnnz::Vector{PetscInt}`: array containing the number of nonzeros in the various rows of the DIAGONAL portion of the local - submatrix (possibly different for each row) or NULL (PETSC_NULL_INTEGER in Fortran), if d_nz is used to specify the nonzero - structure. The size of this array is equal to the number of local rows, i.e 'm'. For matrices that will be factored, you - must leave room for (and set) the diagonal entry even if it is zero. -- `onz::PetscInt`: number of nonzeros per row in the OFF-DIAGONAL portion of local submatrix (same value is used for all local rows). -- `onnz::Vector{PetscInt}`: array containing the number of nonzeros in the various rows of the OFF-DIAGONAL portion of the local - submatrix (possibly different for each row) or NULL (PETSC_NULL_INTEGER in Fortran), if o_nz is used to specify the nonzero structure. - The size of this array is equal to the number of local rows, i.e 'm'. -""" -function MatMPIAIJSetPreallocation(mat::PetscMat, dnz::PetscInt, dnnz::Vector{PetscInt}, onz::PetscInt, onnz::Vector{PetscInt}) - error = ccall((:MatMPIAIJSetPreallocation, libpetsc), PetscErrorCode, - (CMat, PetscInt, Ptr{PetscInt}, PetscInt, Ptr{PetscInt}), - mat, dnz, dnnz, onz, onnz) - @assert iszero(error) -end - -function MatMPIAIJSetPreallocation(mat::PetscMat, dnz::PetscInt, onz::PetscInt) - error = ccall((:MatMPIAIJSetPreallocation, libpetsc), PetscErrorCode, - (CMat, PetscInt, Ptr{PetscInt}, PetscInt, Ptr{PetscInt}), - mat, dnz, C_NULL, onz, C_NULL) - @assert iszero(error) -end - -""" - MatSeqAIJSetPreallocation(mat::PetscMat, nz::PetscInt, nnz::Vector{PetscInt}) - -Wrapper to `MatSeqAIJSetPreallocation`. -""" -function MatSeqAIJSetPreallocation(mat::PetscMat, nz::PetscInt, nnz::Vector{PetscInt}) - error = ccall((:MatSeqAIJSetPreallocation, libpetsc), PetscErrorCode, - (CMat, PetscInt, Ptr{PetscInt}), - mat, nz, nnz) - @assert iszero(error) -end - -function MatSeqAIJSetPreallocation(mat::PetscMat, nz::PetscInt) - error = ccall((:MatSeqAIJSetPreallocation, libpetsc), PetscErrorCode, - (CMat, PetscInt, Ptr{PetscInt}), - mat, nz, C_NULL) - @assert iszero(error) -end - -""" -Wrapper for `MatSetOption` -""" -function MatSetOption(mat::PetscMat, option::MatOption, value::Bool) - error = ccall((:MatSetOption, libpetsc), PetscErrorCode, (CMat, MatOption, Cuchar), mat, option, value) - @assert iszero(error) -end - -# Avoid allocating an array of size 1 for each call to MatSetValue -const _ivec = zeros(PetscInt, 1) -const _jvec = zeros(PetscInt, 1) -const _vvec = zeros(PetscScalar, 1) - -""" -MatSetValue(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode::InsertMode) - -Wrapper to `MatSetValue`. Indexing starts at 0 (as in PETSc). - -# Implementation -For an unknow reason, calling PETSc.MatSetValue leads to an "undefined symbol: MatSetValue" error. -So this wrapper directly call MatSetValues (anyway, this is what is done in PETSc...) -""" -function MatSetValue(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode::InsertMode) - # Convert to arrays - _ivec[1] = i - _jvec[1] = j - _vvec[1] = v - - MatSetValues(mat, PetscIntOne, _ivec, PetscIntOne, _jvec, _vvec, mode) - #MatSetValues(mat, PetscIntOne, [i], PetscIntOne, [j], [v], mode) -end - -function MatSetValue(mat::PetscMat, i::Integer, j::Integer, v::Number, mode::InsertMode) - MatSetValue(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) -end - -""" -MatSetValues(mat::PetscMat, nI::PetscInt, I::Vector{PetscInt}, nJ::PetscInt, J::Vector{PetscInt}, V::Array{PetscScalar}, mode::InsertMode) - -Wrapper to `MatSetValues`. Indexing starts at 0 (as in PETSc) -""" -function MatSetValues(mat::PetscMat, nI::PetscInt, I::Vector{PetscInt}, nJ::PetscInt, J::Vector{PetscInt}, V::Array{PetscScalar}, mode::InsertMode) - error = ccall((:MatSetValues, libpetsc), PetscErrorCode, - (CMat, PetscInt, Ptr{PetscInt}, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}, InsertMode), - mat, nI, I, nJ, J, V, mode) - @assert iszero(error) -end - -function MatSetValues(mat::PetscMat, I::Vector{PetscInt}, J::Vector{PetscInt}, V::Array{PetscScalar}, mode::InsertMode) - MatSetValues(mat, PetscInt(length(I)), I, PetscInt(length(J)), J, V, mode) -end - -function MatSetValues(mat::PetscMat, I, J, V, mode::InsertMode) - MatSetValues(mat, PetscInt.(I), PetscInt.(collect(J)), PetscScalar.(V), mode) -end - -""" - MatView(mat::PetscMat, viewer::PetscViewer = PetscViewerStdWorld()) - -Wrapper to `MatView` -""" -function MatView(mat::PetscMat, viewer::PetscViewer=PetscViewerStdWorld()) - error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) - @assert iszero(error) -end \ No newline at end of file From b8b0c04228367cdd1ef71d4de9c87f91bbbbefc6 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 14:59:12 +0200 Subject: [PATCH 11/40] convetion for PetscViewer --- src/PetscViewer.jl | 199 +++++++++++++++++++++++++++++++++++++++++++++ src/viewer.jl | 137 ------------------------------- 2 files changed, 199 insertions(+), 137 deletions(-) create mode 100644 src/PetscViewer.jl delete mode 100644 src/viewer.jl diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl new file mode 100644 index 0000000..da8845a --- /dev/null +++ b/src/PetscViewer.jl @@ -0,0 +1,199 @@ +const CViewer = Ptr{Cvoid} +struct PetscViewer + ptr::Ref{CViewer} + comm::MPI.Comm + + PetscViewer(comm::MPI.Comm) = new(Ref{CViewer}(), comm) +end + +# allows us to pass PetscViewer objects directly into CViewer ccall signatures +Base.cconvert(::Type{CViewer}, viewer::PetscViewer) = viewer.ptr[] + +""" + ASCIIGetStdout(comm::MPI.Comm) + +Wrapper for `PetscViewerASCIIGetStdout` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerASCIIGetStdout/ +""" +function ASCIIGetStdout(comm::MPI.Comm) + viewer = PetscViewer(comm) + error = ccall( + (:PetscViewerASCIIGetStdout, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Ptr{CViewer}), + comm, + viewer.ptr, + ) + @assert iszero(error) + return viewer +end + +const StdWorld = ASCIIGetStdout + +""" + ASCIIOpen(comm::MPI.Comm, name) + +Wrapper for `PetscViewerASCIIOpen` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerASCIIOpen/ +""" +function ASCIIOpen(comm::MPI.Comm, name::String) + viewer = PetscViewer(comm) + error = ccall( + (:PetscViewerASCIIOpen, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Cstring, Ptr{CViewer}), + comm, + name, + viewer.ptr, + ) + @assert iszero(error) + return viewer +end + +""" + create(::Type{PetscView}, comm::MPI.Comm) + +Wrapper for `PetscViewerCreate` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerCreate/ +""" +function create(::Type{PetscView}, comm::MPI.Comm) + viewer = PetscViewer(comm) + error = ccall( + (:PetscViewerCreate, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Ptr{CViewer}), + comm, + viewer.ptr, + ) + @assert iszero(error) + return viewer +end + +""" + destroy(viewer::PetscViewer) + +Wrapper for `PetscViewerDestroy` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerDestroy/ + +Warning : from what I understand, all viewers must not be destroyed explicitely using `PetscViewerDestroy`. +""" +function destroy(viewer::PetscViewer) + error = + ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer},), viewer.ptr) + @assert iszero(error) +end + +""" + popFormat(viewer::PetscViewer) + +Wrapper for `PetscViewerPopFormat` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPopFormat/ +""" +function popFormat(viewer::PetscViewer) + error = ccall((:PetscViewerPopFormat, libpetsc), PetscErrorCode, (CViewer,), viewer) + @assert iszero(error) +end + +""" + pushFormat(viewer::PetscViewer, format::PetscViewerFormat) + +Wrapper for `PetscViewerPushFormat` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPushFormat/ +""" +function pushFormat(viewer::PetscViewer, format::PetscViewerFormat) + error = ccall( + (:PetscViewerPushFormat, libpetsc), + PetscErrorCode, + (CViewer, PetscViewerFormat), + viewer, + format, + ) + @assert iszero(error) +end + +""" + fileSetMode(viewer::PetscViewer, mode::PetscFileMode) + +Wrapper for `PetscViewerFileSetMode` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerFileSetMode/ +""" +function fileSetMode(viewer::PetscViewer, mode::PetscFileMode) + error = ccall( + (:PetscViewerFileSetMode, libpetsc), + PetscErrorCode, + (CViewer, PetscFileMode), + viewer, + mode, + ) + @assert iszero(error) +end + + +""" + fileSetName(viewer::PetscViewer, name::String) + +Wrapper for `PetscViewerFileSetName` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerFileSetName/ +""" +function fileSetName(viewer::PetscViewer, name::String) + error = ccall( + (:PetscViewerFileSetName, libpetsc), + PetscErrorCode, + (CViewer, Cstring), + viewer, + name, + ) + @assert iszero(error) +end + +""" + HDF5Open(comm::MPI.Comm, name::String, type::PetscFileMode) + +Wrapper for `PetscViewerHDF5Open` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerHDF5Open/ +""" +function HDF5Open(comm::MPI.Comm, name::String, type::PetscFileMode) + viewer = PetscViewer(comm) + error = ccall( + (:PetscViewerHDF5Open, libpetsc), + PetscErrorCode, + (MPI.MPI_Comm, Cstring, PetscFileMode, Ptr{CViewer}), + comm, + name, + type, + viewer.ptr, + ) + @assert iszero(error) + return viewer +end + +""" + setType(viewer::PetscViewer, type::String) + +Wrapper for `PetscViewerSetType` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerSetType/ + +Values for `type` alors available here: +https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Viewer/PetscViewerType.html#PetscViewerType +""" +function setType(viewer::PetscViewer, type::String) + error = ccall( + (:PetscViewerSetType, libpetsc), + PetscErrorCode, + (CViewer, Cstring), + viewer, + type, + ) + @assert iszero(error) +end + +""" + view(v::PetscViewer, viewer::PetscViewer) + +Wrapper to `PetscViewerView` +""" +function view(v::PetscViewer, viewer::PetscViewer) + error = + ccall((:PetscViewerView, libpetsc), PetscErrorCode, (CViewer, CViewer), v, viewer) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/viewer.jl b/src/viewer.jl deleted file mode 100644 index 4671066..0000000 --- a/src/viewer.jl +++ /dev/null @@ -1,137 +0,0 @@ -const CViewer = Ptr{Cvoid} -struct PetscViewer - ptr::Ref{CViewer} - comm::MPI.Comm - - PetscViewer(comm::MPI.Comm) = new(Ref{CViewer}(), comm) -end - -# allows us to pass PetscViewer objects directly into CViewer ccall signatures -Base.cconvert(::Type{CViewer}, viewer::PetscViewer) = viewer.ptr[] - -""" - PetscViewerASCIIGetStdout(comm::MPI.Comm = MPI.COMM_WORLD) - -Wrapper for `PetscViewerASCIIGetStdout` -""" -function PetscViewerASCIIGetStdout(comm::MPI.Comm=MPI.COMM_WORLD) - viewer = PetscViewer(comm) - error = ccall((:PetscViewerASCIIGetStdout, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CViewer}), comm, viewer.ptr) - @assert iszero(error) - return viewer -end - -const PetscViewerStdWorld = PetscViewerASCIIGetStdout - -""" - PetscViewerASCIIOpen(comm::MPI.Comm, filename) - -Wrapper for `PetscViewerASCIIOpen` -""" -function PetscViewerASCIIOpen(comm::MPI.Comm, filename) - viewer = PetscViewer(comm) - error = ccall((:PetscViewerASCIIOpen, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Cstring, Ptr{CViewer}), comm, filename, viewer.ptr) - @assert iszero(error) - return viewer -end - -""" - PetscViewerCreate(comm::MPI.Comm = MPI.COMM_WORLD) - -Wrapper for `PetscViewerCreate` -""" -function PetscViewerCreate(comm::MPI.Comm=MPI.COMM_WORLD) - viewer = PetscViewer(comm) - error = ccall((:PetscViewerCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CViewer}), comm, viewer.ptr) - @assert iszero(error) - return viewer -end - -""" - PetscViewerDestroy(viewer::PetscViewer) - -Wrapper for `PetscViewerDestroy` - -Warning : from what I understand, all viewers must not be destroyed explicitely using `PetscViewerDestroy`. - -""" -function PetscViewerDestroy(viewer::PetscViewer) - error = ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer},), viewer.ptr) - @assert iszero(error) -end - -""" - PetscViewerPopFormat(viewer::PetscViewer) - -Wrapper for `PetscViewerPopFormat` -""" -function PetscViewerPopFormat(viewer::PetscViewer) - error = ccall((:PetscViewerPopFormat, libpetsc), PetscErrorCode, (CViewer,), viewer) - @assert iszero(error) -end - -""" - PetscViewerPushFormat(viewer::PetscViewer, format::PetscViewerFormat) - -Wrapper for `PetscViewerPushFormat` -""" -function PetscViewerPushFormat(viewer::PetscViewer, format::PetscViewerFormat) - error = ccall((:PetscViewerPushFormat, libpetsc), PetscErrorCode, (CViewer, PetscViewerFormat), viewer, format) - @assert iszero(error) -end - -""" - PetscViewerFileSetMode(viewer::PetscViewer, mode::PetscFileMode = FILE_MODE_WRITE) - -Wrapper for `PetscViewerFileSetMode` -""" -function PetscViewerFileSetMode(viewer::PetscViewer, mode::PetscFileMode=FILE_MODE_WRITE) - error = ccall((:PetscViewerFileSetMode, libpetsc), PetscErrorCode, (CViewer, PetscFileMode), viewer, mode) - @assert iszero(error) -end - - -""" - PetscViewerFileSetName(viewer::PetscViewer, filename) - -Wrapper for `PetscViewerFileSetName` -""" -function PetscViewerFileSetName(viewer::PetscViewer, filename::String) - error = ccall((:PetscViewerFileSetName, libpetsc), PetscErrorCode, (CViewer, Cstring), viewer, filename) - @assert iszero(error) -end - -""" - PetscViewerHDF5Open(comm::MPI.Comm, filename::String, type::PetscFileMode) - -Wrapper for `PetscViewerHDF5Open` -""" -function PetscViewerHDF5Open(comm::MPI.Comm, filename::String, type::PetscFileMode) - viewer = PetscViewer(comm) - error = ccall((:PetscViewerHDF5Open, libpetsc), PetscErrorCode, - (MPI.MPI_Comm, Cstring, PetscFileMode, Ptr{CViewer}), - comm, filename, type, viewer.ptr) - @assert iszero(error) - return viewer -end - -""" - PetscViewerSetType(viewer::PetscViewer, type::String) - -Wrapper for `PetscViewerSetType`. Values for `type` alors available here: -https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Viewer/PetscViewerType.html#PetscViewerType -""" -function PetscViewerSetType(viewer::PetscViewer, type::String) - error = ccall((:PetscViewerSetType, libpetsc), PetscErrorCode, (CViewer, Cstring), viewer, type) - @assert iszero(error) -end - -""" - PetscViewerView(v::PetscViewer, viewer::PetscViewer = PetscViewerStdWorld()) - -Wrapper to `PetscViewerView` -""" -function PetscViewerView(v::PetscViewer, viewer::PetscViewer=PetscViewerStdWorld()) - error = ccall((:PetscViewerView, libpetsc), PetscErrorCode, (CViewer, CViewer), v, viewer) - @assert iszero(error) -end \ No newline at end of file From 353ff360c8a2349ea3927dbed9844ffdfa272dfd Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 15:07:59 +0200 Subject: [PATCH 12/40] alphabetical order + formatter --- .JuliaFormatter.toml | 5 +- src/ISLocalToGlobalMapping.jl | 2 +- src/KSP.jl | 2 +- src/Mat.jl | 232 +++++++++++----------- src/PetscViewer.jl | 59 +++--- src/PetscWrap.jl | 2 +- src/Vec.jl | 350 +++++++++++++++++----------------- src/const_arch_dep.jl | 19 +- src/const_arch_ind.jl | 3 +- src/fancy/ksp.jl | 8 +- src/fancy/mat.jl | 106 +++++++--- src/fancy/vec.jl | 36 +++- src/fancy/viewer.jl | 10 +- src/init.jl | 29 ++- src/load.jl | 8 +- 15 files changed, 489 insertions(+), 382 deletions(-) diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml index d4be17d..d8737f8 100644 --- a/.JuliaFormatter.toml +++ b/.JuliaFormatter.toml @@ -19,4 +19,7 @@ format_docstrings = true format_markdown = true # If true, whitespace is added for binary operations in indices -whitespace_ops_in_indices = true \ No newline at end of file +whitespace_ops_in_indices = true + +# If true, superfluous newlines will be removed +remove_extra_newlines = true \ No newline at end of file diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index d512bc0..b3e30f4 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -67,4 +67,4 @@ function destroy(mapping::ISLocalToGlobalMapping) mapping.ptr, ) @assert iszero(error) -end \ No newline at end of file +end diff --git a/src/KSP.jl b/src/KSP.jl index fe28181..6c3ab27 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -89,4 +89,4 @@ https://petsc.org/release/docs/manualpages/KSP/KSPSolve/ function solve(ksp::KSP, b::PetscVec, x::PetscVec) error = ccall((:KSPSolve, libpetsc), PetscErrorCode, (CKSP, CVec, CVec), ksp, b, x) @assert iszero(error) -end \ No newline at end of file +end diff --git a/src/Mat.jl b/src/Mat.jl index d53d7c8..9ece534 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -10,7 +10,6 @@ struct Mat Mat(comm::MPI.Comm) = new(Ref{CMat}(), comm) end - # allows us to pass Mat objects directly into CMat ccall signatures Base.cconvert(::Type{CMat}, mat::Mat) = mat.ptr[] @@ -48,7 +47,6 @@ function assemblyEnd(mat::Mat, type::MatAssemblyType) @assert iszero(error) end - """ compositeAddMat(mat::Mat, smat::Mat) @@ -119,7 +117,6 @@ function createDense( M::Integer = PETSC_DECIDE, N::Integer = PETSC_DECIDE, ) - return createDense(comm, PetscInt(m), PetscInt(n), PetscInt(M), PetscInt(N)) end @@ -288,120 +285,6 @@ function getType(mat::Mat) return unsafe_string(type[]) end -""" - mult(mat::Mat, x::PetscVec, y::PetscVec) - -Wrapper to `MatMult` -https://petsc.org/release/docs/manualpages/Mat/MatMult/ - -Compute `y = Ax` -""" -function mult(mat::Mat, x::PetscVec, y::PetscVec) - error = ccall((:MatMult, libpetsc), PetscErrorCode, (CMat, CVec, CVec), mat, x, y) - @assert iszero(error) -end - -""" - multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) - -Wrapper to `MatMultAdd` -https://petsc.org/release/docs/manualpages/Mat/MatMultAdd/ - -Compute `v3 = v2 + A * v1`. -""" -function multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) - error = ccall( - (:MatMultAdd, libpetsc), - PetscErrorCode, - (CMat, CVec, CVec, CVec), - A, - v1, - v2, - v3, - ) - @assert iszero(error) -end - -""" - setFromOptions(mat::Mat) - -Wrapper to `MatSetFromOptions` -https://petsc.org/release/docs/manualpages/Mat/MatSetFromOptions/ -""" -function setFromOptions(mat::Mat) - error = ccall((:MatSetFromOptions, libpetsc), PetscErrorCode, (CMat,), mat) - @assert iszero(error) -end - -""" - setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) - setSizes( - mat::Mat, - nrows_loc::Integer, - ncols_loc::Integer, - nrows_glo::Integer, - ncols_glo::Integer, - ) - -Wrapper to `MatSetSizes` -https://petsc.org/release/docs/manualpages/Mat/MatSetSizes/ -""" -function setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) - error = ccall( - (:MatSetSizes, libpetsc), - PetscErrorCode, - (CMat, PetscInt, PetscInt, PetscInt, PetscInt), - mat, - m, - n, - M, - N, - ) - @assert iszero(error) -end - -function setSizes( - mat::Mat, - nrows_loc::Integer, - ncols_loc::Integer, - nrows_glo::Integer, - ncols_glo::Integer, -) - setSizes( - mat, - PetscInt(nrows_loc), - PetscInt(ncols_loc), - PetscInt(nrows_glo), - PetscInt(ncols_glo), - ) -end - -""" - setType(mat::Mat, type::String) - -Wrapper for `MatSetType` -https://petsc.org/release/docs/manualpages/Mat/MatSetType/ - -Values for `type` alors available here: -https://petsc.org/release/docs/manualpages/Mat/MatType.html#MatType -""" -function setType(mat::Mat, type::String) - error = ccall((:MatSetType, libpetsc), PetscErrorCode, (CMat, Cstring), mat, type) - @assert iszero(error) -end - - -""" - setUp(mat::Mat) - -Wrapper to `MatSetUp` -https://petsc.org/release/docs/manualpages/Mat/MatSetUp/ -""" -function setUp(mat::Mat) - error = ccall((:MatSetUp, libpetsc), PetscErrorCode, (CMat,), mat) - @assert iszero(error) -end - """ MPIAIJSetPreallocation( B::Mat, @@ -465,6 +348,40 @@ function MPIAIJSetPreallocation(mat::Mat, dnz::PetscInt, onz::PetscInt) @assert iszero(error) end +""" + mult(mat::Mat, x::PetscVec, y::PetscVec) + +Wrapper to `MatMult` +https://petsc.org/release/docs/manualpages/Mat/MatMult/ + +Compute `y = Ax` +""" +function mult(mat::Mat, x::PetscVec, y::PetscVec) + error = ccall((:MatMult, libpetsc), PetscErrorCode, (CMat, CVec, CVec), mat, x, y) + @assert iszero(error) +end + +""" + multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + +Wrapper to `MatMultAdd` +https://petsc.org/release/docs/manualpages/Mat/MatMultAdd/ + +Compute `v3 = v2 + A * v1`. +""" +function multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + error = ccall( + (:MatMultAdd, libpetsc), + PetscErrorCode, + (CMat, CVec, CVec, CVec), + A, + v1, + v2, + v3, + ) + @assert iszero(error) +end + """ SeqAIJSetPreallocation(mat::Mat, nz::PetscInt, nnz::Vector{PetscInt}) SeqAIJSetPreallocation(mat::Mat, nz::PetscInt) @@ -496,6 +413,17 @@ function SeqAIJSetPreallocation(mat::Mat, nz::PetscInt) @assert iszero(error) end +""" + setFromOptions(mat::Mat) + +Wrapper to `MatSetFromOptions` +https://petsc.org/release/docs/manualpages/Mat/MatSetFromOptions/ +""" +function setFromOptions(mat::Mat) + error = ccall((:MatSetFromOptions, libpetsc), PetscErrorCode, (CMat,), mat) + @assert iszero(error) +end + """ setOption(mat::Mat, op::MatOption, flg::PetscBool) @@ -516,6 +444,74 @@ end setOption(mat::Mat, op::MatOption, flg::Bool) = setOption(mat, op, bool2petsc(flg)) +""" + setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + setSizes( + mat::Mat, + nrows_loc::Integer, + ncols_loc::Integer, + nrows_glo::Integer, + ncols_glo::Integer, + ) + +Wrapper to `MatSetSizes` +https://petsc.org/release/docs/manualpages/Mat/MatSetSizes/ +""" +function setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + error = ccall( + (:MatSetSizes, libpetsc), + PetscErrorCode, + (CMat, PetscInt, PetscInt, PetscInt, PetscInt), + mat, + m, + n, + M, + N, + ) + @assert iszero(error) +end + +function setSizes( + mat::Mat, + nrows_loc::Integer, + ncols_loc::Integer, + nrows_glo::Integer, + ncols_glo::Integer, +) + setSizes( + mat, + PetscInt(nrows_loc), + PetscInt(ncols_loc), + PetscInt(nrows_glo), + PetscInt(ncols_glo), + ) +end + +""" + setType(mat::Mat, type::String) + +Wrapper for `MatSetType` +https://petsc.org/release/docs/manualpages/Mat/MatSetType/ + +Values for `type` alors available here: +https://petsc.org/release/docs/manualpages/Mat/MatType.html#MatType +""" +function setType(mat::Mat, type::String) + error = ccall((:MatSetType, libpetsc), PetscErrorCode, (CMat, Cstring), mat, type) + @assert iszero(error) +end + +""" + setUp(mat::Mat) + +Wrapper to `MatSetUp` +https://petsc.org/release/docs/manualpages/Mat/MatSetUp/ +""" +function setUp(mat::Mat) + error = ccall((:MatSetUp, libpetsc), PetscErrorCode, (CMat,), mat) + @assert iszero(error) +end + # Avoid allocating an array of size 1 for each call to MatSetValue const _ivec = zeros(PetscInt, 1) const _jvec = zeros(PetscInt, 1) @@ -640,4 +636,4 @@ https://petsc.org/release/docs/manualpages/Mat/MatView/ function view(mat::Mat, viewer::PetscViewer = PetscViewerStdWorld()) error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) @assert iszero(error) -end \ No newline at end of file +end diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index da8845a..c6d7aa3 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -83,34 +83,6 @@ function destroy(viewer::PetscViewer) @assert iszero(error) end -""" - popFormat(viewer::PetscViewer) - -Wrapper for `PetscViewerPopFormat` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPopFormat/ -""" -function popFormat(viewer::PetscViewer) - error = ccall((:PetscViewerPopFormat, libpetsc), PetscErrorCode, (CViewer,), viewer) - @assert iszero(error) -end - -""" - pushFormat(viewer::PetscViewer, format::PetscViewerFormat) - -Wrapper for `PetscViewerPushFormat` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPushFormat/ -""" -function pushFormat(viewer::PetscViewer, format::PetscViewerFormat) - error = ccall( - (:PetscViewerPushFormat, libpetsc), - PetscErrorCode, - (CViewer, PetscViewerFormat), - viewer, - format, - ) - @assert iszero(error) -end - """ fileSetMode(viewer::PetscViewer, mode::PetscFileMode) @@ -128,7 +100,6 @@ function fileSetMode(viewer::PetscViewer, mode::PetscFileMode) @assert iszero(error) end - """ fileSetName(viewer::PetscViewer, name::String) @@ -167,6 +138,34 @@ function HDF5Open(comm::MPI.Comm, name::String, type::PetscFileMode) return viewer end +""" + popFormat(viewer::PetscViewer) + +Wrapper for `PetscViewerPopFormat` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPopFormat/ +""" +function popFormat(viewer::PetscViewer) + error = ccall((:PetscViewerPopFormat, libpetsc), PetscErrorCode, (CViewer,), viewer) + @assert iszero(error) +end + +""" + pushFormat(viewer::PetscViewer, format::PetscViewerFormat) + +Wrapper for `PetscViewerPushFormat` +https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPushFormat/ +""" +function pushFormat(viewer::PetscViewer, format::PetscViewerFormat) + error = ccall( + (:PetscViewerPushFormat, libpetsc), + PetscErrorCode, + (CViewer, PetscViewerFormat), + viewer, + format, + ) + @assert iszero(error) +end + """ setType(viewer::PetscViewer, type::String) @@ -196,4 +195,4 @@ function view(v::PetscViewer, viewer::PetscViewer) error = ccall((:PetscViewerView, libpetsc), PetscErrorCode, (CViewer, CViewer), v, viewer) @assert iszero(error) -end \ No newline at end of file +end diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 4f68fe4..dccfe9d 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -125,4 +125,4 @@ export create_composite_add, create_matrix, mat2file, preallocate!, set_value!, include("fancy/ksp.jl") export create_ksp, solve, solve!, set_operators! -end \ No newline at end of file +end diff --git a/src/Vec.jl b/src/Vec.jl index 10308b2..33e676c 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -10,6 +10,28 @@ end # allows us to pass Vec objects directly into CVec ccall signatures Base.cconvert(::Type{CVec}, vec::Vec) = vec.ptr[] +""" + assemblyBegin(vec::Vec) + +Wrapper to `VecAssemblyBegin` +https://petsc.org/release/docs/manualpages/Vec/VecAssemblyBegin/ +""" +function assemblyBegin(vec::Vec) + error = ccall((:VecAssemblyBegin, libpetsc), PetscErrorCode, (CVec,), vec) + @assert iszero(error) +end + +""" + assemblyEnd(vec::Vec) + +Wrapper to `VecAssemblyEnd` +https://petsc.org/release/docs/manualpages/Vec/VecAssemblyEnd/ +""" +function assemblyEnd(vec::Vec) + error = ccall((:VecAssemblyEnd, libpetsc), PetscErrorCode, (CVec,), vec) + @assert iszero(error) +end + """ copy(x::Vec, y::Vec) copy(x::Vec) @@ -47,6 +69,17 @@ function create(::Type{Vec}, comm::MPI.Comm) return vec end +""" + destroy(v::Vec) + +Wrapper to `VecDestroy` +https://petsc.org/release/docs/manualpages/Vec/VecDestroy/ +""" +function destroy(v::Vec) + error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v.ptr) + @assert iszero(error) +end + """ duplicate(v::Vec) @@ -62,118 +95,53 @@ function duplicate(v::Vec) end """ - setValue(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) - setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) - -Wrapper to `setValue`. Indexing starts at 0 (as in PETSc). -https://petsc.org/release/docs/manualpages/Vec/VecSetValue/ - -# Implementation - -For an unknow reason, calling PETSc.VecSetValue leads to an "undefined symbol: VecSetValue" error. -So this wrapper directly call VecSetValues (anyway, this is what is done in PETSc...) -""" -function setValue(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) - setValues(v, PetscIntOne, [row], [value], mode) -end + getArray(x::Vec, own::Bool = false) -function setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) - setValue(v, PetscInt(row), PetscScalar(value), mode) -end +Wrapper for `VecGetArray` +https://petsc.org/release/docs/manualpages/Vec/VecGetArray/ -""" - setValues( - x::Vec, - ni::PetscInt, - ix::Vector{PetscInt}, - y::Vector{PetscScalar}, - iora::InsertMode, - ) +# Warning - setValues( - x::Vec, - I::Vector{PetscInt}, - V::Vector{PetscScalar}, - mode::InsertMode = INSERT_VALUES, - ) - setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) +I am not confortable at all with memory management, both on the C side and on the Julia side. Use +this at you own risk. -Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) -https://petsc.org/release/docs/manualpages/Vec/VecSetValues/ +According to Julia documentation, `own` optionally specifies whether Julia should take ownership +of the memory, calling free on the pointer when the array is no longer referenced." """ -function setValues( - x::Vec, - ni::PetscInt, - ix::Vector{PetscInt}, - y::Vector{PetscScalar}, - iora::InsertMode, -) +function getArray(x::Vec, own::Bool = false) + # Get array pointer + array_ref = Ref{Ptr{PetscScalar}}() error = ccall( - (:VecSetValues, libpetsc), + (:VecGetArray, libpetsc), PetscErrorCode, - (CVec, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}, InsertMode), + (CVec, Ref{Ptr{PetscScalar}}), x, - ni, - ix, - y, - iora, + array_ref, ) @assert iszero(error) -end - -function setValues( - x::Vec, - I::Vector{PetscInt}, - V::Vector{PetscScalar}, - mode::InsertMode = INSERT_VALUES, -) - setValues(x, PetscInt(length(I)), I, V, mode) -end -function setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) - setValues(x, PetscInt.(I), PetscScalar.(V), mode) -end + # Get array size + rstart, rend = getOwnershipRange(x) + n = rend - rstart # this is not `rend - rstart + 1` because of VecGetOwnershipRange convention -""" - setSizes(v::Vec, n::PetscInt, N::PetscInt) + array = unsafe_wrap(Array, array_ref[], n; own = own) -Wrapper to `VecSetSizes` -https://petsc.org/release/docs/manualpages/Vec/VecSetSizes/ -""" -function setSizes(v::Vec, n::PetscInt, N::PetscInt) - nr_loc = PetscInt(n) - nr_glo = PetscInt(N) - error = ccall( - (:VecSetSizes, libpetsc), - PetscErrorCode, - (CVec, PetscInt, PetscInt), - v, - nr_loc, - nr_glo, - ) - @assert iszero(error) + return array, array_ref end """ - setFromOptions(vec::Vec) - -Wrapper to `VecSetFromOptions` -https://petsc.org/release/docs/manualpages/Vec/VecSetFromOptions/ -""" -function setFromOptions(vec::Vec) - error = ccall((:VecSetFromOptions, libpetsc), PetscErrorCode, (CVec,), vec) - @assert iszero(error) -end + getLocalSize(vec::Vec) +Wrapper for `VecGetLocalSize` +https://petsc.org/release/docs/manualpages/Vec/VecGetLocalSize/ """ - VecSetUp(vec::Vec) +function getLocalSize(x::Vec) + n = Ref{PetscInt}() -Wrapper to `VecSetUp` -https://petsc.org/release/docs/manualpages/Vec/VecSetUp/ -""" -function VecSetUp(v::Vec) - error = ccall((:VecSetUp, libpetsc), PetscErrorCode, (CVec,), v) + error = ccall((:VecGetLocalSize, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}), x, n) @assert iszero(error) + + return n[] end """ @@ -222,143 +190,175 @@ function getSize(x::Vec) end """ - VecGetLocalSize(vec::Vec) + restoreArray(x::Vec, array_ref) -Wrapper for `VecGetLocalSize` -https://petsc.org/release/docs/manualpages/Vec/VecGetLocalSize/ +Wrapper for `VecRestoreArray`. `array_ref` is obtained from `VecGetArray` +https://petsc.org/release/docs/manualpages/Vec/VecRestoreArray/ """ -function getLocalSize(x::Vec) - n = Ref{PetscInt}() - - error = ccall((:VecGetLocalSize, libpetsc), PetscErrorCode, (CVec, Ref{PetscInt}), x, n) +function restoreArray(x::Vec, array_ref) + error = ccall( + (:VecRestoreArray, libpetsc), + PetscErrorCode, + (CVec, Ref{Ptr{PetscScalar}}), + x, + array_ref, + ) @assert iszero(error) - - return n[] end """ - assemblyBegin(vec::Vec) + scale(x::Vec, alpha::PetscScalar) + scale(x::Vec, alpha::Number) -Wrapper to `VecAssemblyBegin` -https://petsc.org/release/docs/manualpages/Vec/VecAssemblyBegin/ +Wrapper for `VecScale` +https://petsc.org/release/docs/manualpages/Vec/VecScale/ """ -function assemblyBegin(vec::Vec) - error = ccall((:VecAssemblyBegin, libpetsc), PetscErrorCode, (CVec,), vec) +function scale(x::Vec, alpha::PetscScalar) + error = ccall((:VecScale, libpetsc), PetscErrorCode, (CVec, PetscScalar), x, alpha) @assert iszero(error) end +scale(x::Vec, alpha::Number) = scale(x, PetscScalar(alpha)) + """ - assemblyEnd(vec::Vec) + setFromOptions(vec::Vec) -Wrapper to `VecAssemblyEnd` -https://petsc.org/release/docs/manualpages/Vec/VecAssemblyEnd/ +Wrapper to `VecSetFromOptions` +https://petsc.org/release/docs/manualpages/Vec/VecSetFromOptions/ """ -function assemblyEnd(vec::Vec) - error = ccall((:VecAssemblyEnd, libpetsc), PetscErrorCode, (CVec,), vec) +function setFromOptions(vec::Vec) + error = ccall((:VecSetFromOptions, libpetsc), PetscErrorCode, (CVec,), vec) @assert iszero(error) end """ - getArray(x::Vec, own::Bool = false) - -Wrapper for `VecGetArray` -https://petsc.org/release/docs/manualpages/Vec/VecGetArray/ - -# Warning - -I am not confortable at all with memory management, both on the C side and on the Julia side. Use -this at you own risk. + setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) -According to Julia documentation, `own` optionally specifies whether Julia should take ownership -of the memory, calling free on the pointer when the array is no longer referenced." +Wrapper to `VecSetLocalToGlobalMapping` +https://petsc.org/release/docs/manualpages/Vec/VecSetLocalToGlobalMapping/ """ -function getArray(x::Vec, own::Bool = false) - # Get array pointer - array_ref = Ref{Ptr{PetscScalar}}() +function setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) error = ccall( - (:VecGetArray, libpetsc), + (:VecSetLocalToGlobalMapping, libpetsc), PetscErrorCode, - (CVec, Ref{Ptr{PetscScalar}}), + (CVec, CISLocalToGlobalMapping), x, - array_ref, + mapping, ) @assert iszero(error) - - # Get array size - rstart, rend = getOwnershipRange(x) - n = rend - rstart # this is not `rend - rstart + 1` because of VecGetOwnershipRange convention - - array = unsafe_wrap(Array, array_ref[], n; own = own) - - return array, array_ref end """ - VecRestoreArray(vec::Vec, array_ref) + setSizes(v::Vec, n::PetscInt, N::PetscInt) -Wrapper for `VecRestoreArray`. `array_ref` is obtained from `VecGetArray` -https://petsc.org/release/docs/manualpages/Vec/VecRestoreArray/ +Wrapper to `VecSetSizes` +https://petsc.org/release/docs/manualpages/Vec/VecSetSizes/ """ -function restoreArray(x::Vec, array_ref) +function setSizes(v::Vec, n::PetscInt, N::PetscInt) + nr_loc = PetscInt(n) + nr_glo = PetscInt(N) error = ccall( - (:VecRestoreArray, libpetsc), + (:VecSetSizes, libpetsc), PetscErrorCode, - (CVec, Ref{Ptr{PetscScalar}}), - x, - array_ref, + (CVec, PetscInt, PetscInt), + v, + nr_loc, + nr_glo, ) @assert iszero(error) end """ - scale(x::Vec, alpha::PetscScalar) - scale(x::Vec, alpha::Number) + setUp(vec::Vec) -Wrapper for `VecScale` -https://petsc.org/release/docs/manualpages/Vec/VecScale/ +Wrapper to `VecSetUp` +https://petsc.org/release/docs/manualpages/Vec/VecSetUp/ """ -function scale(x::Vec, alpha::PetscScalar) - error = ccall((:VecScale, libpetsc), PetscErrorCode, (CVec, PetscScalar), x, alpha) +function setUp(v::Vec) + error = ccall((:VecSetUp, libpetsc), PetscErrorCode, (CVec,), v) @assert iszero(error) end -scale(x::Vec, alpha::Number) = scale(x, PetscScalar(alpha)) - """ - view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) + setValue(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) + setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) -Wrapper to `VecView` -https://petsc.org/release/docs/manualpages/Vec/VecView/ -""" -function view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) - error = ccall((:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer) - @assert iszero(error) -end +Wrapper to `setValue`. Indexing starts at 0 (as in PETSc). +https://petsc.org/release/docs/manualpages/Vec/VecSetValue/ -""" - destroy(v::Vec) +# Implementation -Wrapper to `VecDestroy` -https://petsc.org/release/docs/manualpages/Vec/VecDestroy/ +For an unknow reason, calling PETSc.VecSetValue leads to an "undefined symbol: VecSetValue" error. +So this wrapper directly call VecSetValues (anyway, this is what is done in PETSc...) """ -function destroy(v::Vec) - error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v.ptr) - @assert iszero(error) +function setValue(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) + setValues(v, PetscIntOne, [row], [value], mode) +end + +function setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) + setValue(v, PetscInt(row), PetscScalar(value), mode) end """ - setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) + setValues( + x::Vec, + ni::PetscInt, + ix::Vector{PetscInt}, + y::Vector{PetscScalar}, + iora::InsertMode, + ) -Wrapper to `VecSetLocalToGlobalMapping` -https://petsc.org/release/docs/manualpages/Vec/VecSetLocalToGlobalMapping/ + setValues( + x::Vec, + I::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, + ) + setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) + +Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) +https://petsc.org/release/docs/manualpages/Vec/VecSetValues/ """ -function setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) +function setValues( + x::Vec, + ni::PetscInt, + ix::Vector{PetscInt}, + y::Vector{PetscScalar}, + iora::InsertMode, +) error = ccall( - (:VecSetLocalToGlobalMapping, libpetsc), + (:VecSetValues, libpetsc), PetscErrorCode, - (CVec, CISLocalToGlobalMapping), + (CVec, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}, InsertMode), x, - mapping, + ni, + ix, + y, + iora, ) @assert iszero(error) -end \ No newline at end of file +end + +function setValues( + x::Vec, + I::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, +) + setValues(x, PetscInt(length(I)), I, V, mode) +end + +function setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) + setValues(x, PetscInt.(I), PetscScalar.(V), mode) +end + +""" + view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) + +Wrapper to `VecView` +https://petsc.org/release/docs/manualpages/Vec/VecView/ +""" +function view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) + error = ccall((:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer) + @assert iszero(error) +end diff --git a/src/const_arch_dep.jl b/src/const_arch_dep.jl index 8a89def..dd5d9e2 100644 --- a/src/const_arch_dep.jl +++ b/src/const_arch_dep.jl @@ -7,9 +7,14 @@ function DataTypeFromString(name::AbstractString) dtype_ref = Ref{PetscDataType}() found_ref = Ref{PetscBool}() - ccall((:PetscDataTypeFromString, libpetsc), PetscErrorCode, + ccall( + (:PetscDataTypeFromString, libpetsc), + PetscErrorCode, (Cstring, Ptr{PetscDataType}, Ptr{PetscBool}), - name, dtype_ref, found_ref) + name, + dtype_ref, + found_ref, + ) @assert found_ref[] == PETSC_TRUE return dtype_ref[] end @@ -19,9 +24,13 @@ end """ function PetscDataTypeGetSize(dtype::PetscDataType) datasize_ref = Ref{Csize_t}() - ccall((:PetscDataTypeGetSize, libpetsc), PetscErrorCode, + ccall( + (:PetscDataTypeGetSize, libpetsc), + PetscErrorCode, (PetscDataType, Ptr{Csize_t}), - dtype, datasize_ref) + dtype, + datasize_ref, + ) return datasize_ref[] end @@ -76,4 +85,4 @@ const PetscReal = PetscReal2Type() const PetscScalar = PetscScalar2Type() const PetscInt = PetscInt2Type() -const PetscIntOne = PetscInt(1) # Integer `1` with the type of PetscInt, usefull to go back and forth with julia/petsc indexing \ No newline at end of file +const PetscIntOne = PetscInt(1) # Integer `1` with the type of PetscInt, usefull to go back and forth with julia/petsc indexing diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index 4b8f9be..2124a56 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -17,7 +17,6 @@ macro exported_enum(name, args...) end) end - @enum PetscBool PETSC_FALSE PETSC_TRUE Base.Bool(x::PetscBool) = x == PETSC_TRUE bool2petsc(x::Bool) = x ? PETSC_TRUE : PETSC_FALSE @@ -178,4 +177,4 @@ end MATOP_SOLVE_ADD = 8 MATOP_SOLVE_TRANSPOSE = 9 MATOP_SOLVE_TRANSPOSE_ADD = 10 -end \ No newline at end of file +end diff --git a/src/fancy/ksp.jl b/src/fancy/ksp.jl index a7b3d9f..61e516c 100644 --- a/src/fancy/ksp.jl +++ b/src/fancy/ksp.jl @@ -13,8 +13,9 @@ function create_ksp(Amat::PetscMat, Pmat::PetscMat) end set_operators!(ksp::PetscKSP, Amat::PetscMat) = KSPSetOperators(ksp, Amat, Amat) -set_operators!(ksp::PetscKSP, Amat::PetscMat, Pmat::PetscMat) = KSPSetOperators(ksp, Amat, Pmat) - +function set_operators!(ksp::PetscKSP, Amat::PetscMat, Pmat::PetscMat) + KSPSetOperators(ksp, Amat, Pmat) +end solve!(ksp::PetscKSP, b::PetscVec, x::PetscVec) = KSPSolve(ksp, b, x) @@ -28,7 +29,6 @@ set_up!(ksp::PetscKSP) = KSPSetUp(ksp) set_from_options!(ksp::PetscKSP) = KSPSetFromOptions(ksp) - Base.show(::IO, ksp::PetscKSP) = KSPView(ksp) -destroy!(ksp::PetscKSP) = KSPDestroy(ksp) \ No newline at end of file +destroy!(ksp::PetscKSP) = KSPDestroy(ksp) diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 216ca5f..57c7f2b 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -2,15 +2,26 @@ `row` and `col` must be in [1,size(mat)], i.e indexing starts at 1 (Julia). # Implementation + For some unkwnown reason, calling `MatSetValue` fails. """ function Base.setindex!(mat::PetscMat, value::Number, row::Integer, col::Integer) - MatSetValues(mat, PetscInt[row-1], PetscInt[col-1], PetscScalar[value], INSERT_VALUES) + MatSetValues( + mat, + PetscInt[row - 1], + PetscInt[col - 1], + PetscScalar[value], + INSERT_VALUES, + ) end # This is stupid but I don't know how to do better yet -Base.setindex!(mat::PetscMat, values, row::Integer, cols) = MatSetValues(mat, [row - 1], collect(cols) .- 1, values, INSERT_VALUES) -Base.setindex!(mat::PetscMat, values, rows, col::Integer) = MatSetValues(mat, collect(rows) .- 1, [col - 1], values, INSERT_VALUES) +function Base.setindex!(mat::PetscMat, values, row::Integer, cols) + MatSetValues(mat, [row - 1], collect(cols) .- 1, values, INSERT_VALUES) +end +function Base.setindex!(mat::PetscMat, values, rows, col::Integer) + MatSetValues(mat, collect(rows) .- 1, [col - 1], values, INSERT_VALUES) +end Base.ndims(::Type{PetscMat}) = 2 @@ -21,7 +32,14 @@ Create a `PetscMat` matrix of global size `(nrows, ncols)`. Use `auto_setup = true` to immediatly call `set_from_options!` and `set_up!`. """ -function create_matrix(nrows, ncols, nrows_loc=PETSC_DECIDE, ncols_loc=PETSC_DECIDE; auto_setup=false, comm::MPI.Comm=MPI.COMM_WORLD) +function create_matrix( + nrows, + ncols, + nrows_loc = PETSC_DECIDE, + ncols_loc = PETSC_DECIDE; + auto_setup = false, + comm::MPI.Comm = MPI.COMM_WORLD, +) mat = MatCreate() MatSetSizes(mat::PetscMat, nrows_loc, ncols_loc, nrows, ncols) @@ -38,7 +56,7 @@ Wrapper to `MatCreateComposite` using the "alternative construction" from the PE function create_composite_add(matrices) N, M = MatGetSize(matrices[1]) n, m = MatGetLocalSize(matrices[1]) - mat = create_matrix(N, M, n, m; auto_setup=false, comm=matrices[1].comm) + mat = create_matrix(N, M, n, m; auto_setup = false, comm = matrices[1].comm) MatSetType(mat, "composite") for m in matrices MatCompositeAddMat(mat, m) @@ -47,9 +65,12 @@ function create_composite_add(matrices) return mat end - -set_global_size!(mat::PetscMat, nrows, ncols) = MatSetSizes(mat, PETSC_DECIDE, PETSC_DECIDE, nrows, ncols) -set_local_size!(mat::PetscMat, nrows, ncols) = MatSetSizes(mat, nrows, ncols, PETSC_DECIDE, PETSC_DECIDE) +function set_global_size!(mat::PetscMat, nrows, ncols) + MatSetSizes(mat, PETSC_DECIDE, PETSC_DECIDE, nrows, ncols) +end +function set_local_size!(mat::PetscMat, nrows, ncols) + MatSetSizes(mat, nrows, ncols, PETSC_DECIDE, PETSC_DECIDE) +end set_from_options!(mat::PetscMat) = MatSetFromOptions(mat) @@ -76,13 +97,13 @@ Provide a `UnitRange` from the method `get_range`. """ function get_urange(mat::PetscMat) rstart, rend = MatGetOwnershipRange(mat) - return rstart+1:rend + return (rstart + 1):rend end """ Wrapper to `MatAssemblyBegin` and `MatAssemblyEnd` successively. """ -function assemble!(mat::PetscMat, type::MatAssemblyType=MAT_FINAL_ASSEMBLY) +function assemble!(mat::PetscMat, type::MatAssemblyType = MAT_FINAL_ASSEMBLY) MatAssemblyBegin(mat, type) MatAssemblyEnd(mat, type) end @@ -93,8 +114,18 @@ end Set value of `mat` `mat[i, j] = v`. """ -set_value!(mat::PetscMat, i::PetscInt, j::PetscInt, v::PetscScalar, mode=ADD_VALUES) = MatSetValue(mat, i - 1, j - 1, v, mode) -set_value!(mat, i, j, v, mode=ADD_VALUES) = set_value!(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) +function set_value!( + mat::PetscMat, + i::PetscInt, + j::PetscInt, + v::PetscScalar, + mode = ADD_VALUES, +) + MatSetValue(mat, i - 1, j - 1, v, mode) +end +function set_value!(mat, i, j, v, mode = ADD_VALUES) + set_value!(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) +end """ set_values!(mat::PetscMat, I, J, V, mode = ADD_VALUES) @@ -102,37 +133,68 @@ set_value!(mat, i, j, v, mode=ADD_VALUES) = set_value!(mat, PetscInt(i), PetscIn Set values of `mat` in `SparseArrays` fashion : using COO format: `mat[I[k], J[k]] = V[k]`. """ -function set_values!(mat::PetscMat, I::Vector{PetscInt}, J::Vector{PetscInt}, V::Vector{PetscScalar}, mode=ADD_VALUES) +function set_values!( + mat::PetscMat, + I::Vector{PetscInt}, + J::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode = ADD_VALUES, +) for (i, j, v) in zip(I, J, V) MatSetValue(mat, i - PetscIntOne, j - PetscIntOne, v, mode) end end -set_values!(mat, I, J, V, mode=ADD_VALUES) = set_values!(mat, PetscInt.(I), PetscInt.(J), PetscScalar.(V), mode) +function set_values!(mat, I, J, V, mode = ADD_VALUES) + set_values!(mat, PetscInt.(I), PetscInt.(J), PetscScalar.(V), mode) +end # Warning : cannot use Vector{Integer} because `[1, 2] isa Vector{Integer}` is `false` -_preallocate!(mat::PetscMat, dnz::Integer, onz::Integer, ::Val{:mpiaij}) = MatMPIAIJSetPreallocation(mat, PetscInt(dnz), PetscInt(onz)) -_preallocate!(mat::PetscMat, d_nnz::Vector{I}, o_nnz::Vector{I}, ::Val{:mpiaij}) where {I} = MatMPIAIJSetPreallocation(mat, PetscInt(0), PetscInt.(d_nnz), PetscInt(0), PetscInt.(o_nnz)) -_preallocate!(mat::PetscMat, nz::Integer, ::Integer, ::Val{:seqaij}) = MatSeqAIJSetPreallocation(mat, PetscInt(nz)) -_preallocate!(mat::PetscMat, nnz::Vector{I}, ::Vector{I}, ::Val{:seqaij}) where {I} = MatSeqAIJSetPreallocation(mat, PetscInt(0), PetscInt.(nnz)) +function _preallocate!(mat::PetscMat, dnz::Integer, onz::Integer, ::Val{:mpiaij}) + MatMPIAIJSetPreallocation(mat, PetscInt(dnz), PetscInt(onz)) +end +function _preallocate!( + mat::PetscMat, + d_nnz::Vector{I}, + o_nnz::Vector{I}, + ::Val{:mpiaij}, +) where {I} + MatMPIAIJSetPreallocation( + mat, + PetscInt(0), + PetscInt.(d_nnz), + PetscInt(0), + PetscInt.(o_nnz), + ) +end +function _preallocate!(mat::PetscMat, nz::Integer, ::Integer, ::Val{:seqaij}) + MatSeqAIJSetPreallocation(mat, PetscInt(nz)) +end +function _preallocate!(mat::PetscMat, nnz::Vector{I}, ::Vector{I}, ::Val{:seqaij}) where {I} + MatSeqAIJSetPreallocation(mat, PetscInt(0), PetscInt.(nnz)) +end """ preallocate!(mat::PetscMat, dnz, onz, warn::Bool = true) Dispatch preallocation according matrix type (seq or mpiaij for instance). TODO: should use kwargs. """ -function preallocate!(mat::PetscMat, dnz, onz, warn::Bool=true) +function preallocate!(mat::PetscMat, dnz, onz, warn::Bool = true) _preallocate!(mat, dnz, onz, Val(Symbol(MatGetType(mat)))) MatSetOption(mat, MAT_NEW_NONZERO_ALLOCATION_ERR, warn) end - """ mat2file(mat::PetscMat, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") Write a PetscMat to a file. """ -function mat2file(mat::PetscMat, filename::String, format::PetscViewerFormat=PETSC_VIEWER_ASCII_CSV, type::String="ascii") +function mat2file( + mat::PetscMat, + filename::String, + format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, + type::String = "ascii", +) viewer = PetscViewer(mat.comm, filename, format, type) MatView(mat, viewer) destroy!(viewer) @@ -140,4 +202,4 @@ end Base.show(::IO, mat::PetscMat) = MatView(mat) -destroy!(mat::PetscMat) = MatDestroy(mat) \ No newline at end of file +destroy!(mat::PetscMat) = MatDestroy(mat) diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index 02ae3d6..7edeeb6 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -16,7 +16,12 @@ end Create a `PetscVec` vector of global size `(nrows)`. """ -function create_vector(nrows, nrows_loc=PETSC_DECIDE; auto_setup=false, comm::MPI.Comm=MPI.COMM_WORLD) +function create_vector( + nrows, + nrows_loc = PETSC_DECIDE; + auto_setup = false, + comm::MPI.Comm = MPI.COMM_WORLD, +) vec = VecCreate(comm) VecSetSizes(vec::PetscVec, nrows_loc, nrows) @@ -54,7 +59,7 @@ Provide a `UnitRange` from the method `get_range`. """ function get_urange(vec::PetscVec) rstart, rend = VecGetOwnershipRange(vec) - return rstart+1:rend + return (rstart + 1):rend end Base.ndims(::Type{PetscVec}) = 1 @@ -67,14 +72,17 @@ scale!(vec::PetscVec, alpha::Number) = VecScale(vec, alpha) `row` must be in [1,size(vec)], i.e indexing starts at 1 (Julia). # Implementation + For some unkwnown reason, calling `VecSetValue` fails. """ function Base.setindex!(vec::PetscVec, value::Number, row::Integer) - VecSetValues(vec, PetscInt[row.-1], PetscScalar[value], INSERT_VALUES) + VecSetValues(vec, PetscInt[row .- 1], PetscScalar[value], INSERT_VALUES) end # This is stupid but I don't know how to do better yet -Base.setindex!(vec::PetscVec, values, rows) = VecSetValues(vec, collect(rows .- 1), values, INSERT_VALUES) +function Base.setindex!(vec::PetscVec, values, rows) + VecSetValues(vec, collect(rows .- 1), values, INSERT_VALUES) +end set_from_options!(vec::PetscVec) = VecSetFromOptions(vec) @@ -83,14 +91,21 @@ set_local_size!(vec::PetscVec, nrows) = VecSetSizes(vec, nrows, PETSC_DECIDE) set_up!(vec::PetscVec) = VecSetUp(vec) -set_values!(vec::PetscVec, values) = VecSetValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) +function set_values!(vec::PetscVec, values) + VecSetValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) +end Base.show(::IO, vec::PetscVec) = VecView(vec) """ Wrapper to `VecSetValues`, using julia 1-based indexing. """ -function set_values!(vec::PetscVec, rows::Vector{PetscInt}, values::Vector{PetscScalar}, mode::InsertMode=INSERT_VALUES) +function set_values!( + vec::PetscVec, + rows::Vector{PetscInt}, + values::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, +) VecSetValues(vec, rows .- PetscIntOne, values, mode) end @@ -113,7 +128,12 @@ end Write a PetscVec to a file. """ -function vec2file(vec::PetscVec, filename::String, format::PetscViewerFormat=PETSC_VIEWER_ASCII_CSV, type::String="ascii") +function vec2file( + vec::PetscVec, + filename::String, + format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, + type::String = "ascii", +) viewer = PetscViewer(vec.comm, filename, format, type) VecView(vec, viewer) destroy!(viewer) @@ -121,4 +141,4 @@ end # Discutable choice(s) Base.length(vec::PetscVec) = VecGetLocalSize(vec) -Base.size(vec::PetscVec) = (length(vec),) \ No newline at end of file +Base.size(vec::PetscVec) = (length(vec),) diff --git a/src/fancy/viewer.jl b/src/fancy/viewer.jl index a19ba00..4c5675c 100644 --- a/src/fancy/viewer.jl +++ b/src/fancy/viewer.jl @@ -8,7 +8,13 @@ const set_type! = PetscViewerSetType Constructor for a PetscViewer intended to read/write a matrix or a vector with the supplied type and format. """ -function PetscViewer(comm::MPI.Comm, filename::String, format::PetscViewerFormat=PETSC_VIEWER_ASCII_CSV, type::String="ascii", mode::PetscFileMode=FILE_MODE_WRITE) +function PetscViewer( + comm::MPI.Comm, + filename::String, + format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, + type::String = "ascii", + mode::PetscFileMode = FILE_MODE_WRITE, +) viewer = PetscViewerCreate(comm) set_type!(viewer, type) set_mode!(viewer, FILE_MODE_WRITE) @@ -17,4 +23,4 @@ function PetscViewer(comm::MPI.Comm, filename::String, format::PetscViewerFormat return viewer end -destroy!(viewer::PetscViewer) = PetscViewerDestroy(viewer) \ No newline at end of file +destroy!(viewer::PetscViewer) = PetscViewerDestroy(viewer) diff --git a/src/init.jl b/src/init.jl index 82c8968..fb4264c 100644 --- a/src/init.jl +++ b/src/init.jl @@ -2,18 +2,20 @@ Wrapper to `PetscInitializeNoPointers`. Initialize PETCs with arguments. # Implementation + I don't know if I am supposed to use PetscInt or not... """ function PetscInitialize(args::Vector{String}, filename::String, help::String) args2 = ["julia"; args] nargs = Cint(length(args2)) - error = ccall((:PetscInitializeNoPointers, libpetsc), + error = ccall( + (:PetscInitializeNoPointers, libpetsc), PetscErrorCode, - (Cint, - Ptr{Ptr{UInt8}}, - Cstring, - Cstring), - nargs, args2, filename, help + (Cint, Ptr{Ptr{UInt8}}, Cstring, Cstring), + nargs, + args2, + filename, + help, ) @assert iszero(error) end @@ -26,7 +28,9 @@ PetscInitialize(args::Vector{String}) = PetscInitialize(args, "", "") """ Initialize PETSc with arguments concatenated in a unique string. """ -PetscInitialize(args::String) = PetscInitialize(convert(Vector{String}, split(args)), "", "") +function PetscInitialize(args::String) + PetscInitialize(convert(Vector{String}, split(args)), "", "") +end """ PetscInitialize(cmd_line_args::Bool = true) @@ -39,7 +43,7 @@ arguments for PETSc (leading to a call to `PetscInitializeNoPointers`). Otherwise, if `cmd_line_args == false`, initialize PETSc without arguments (leading to a call to `PetscInitializeNoArguments`). """ -function PetscInitialize(cmd_line_args::Bool=true) +function PetscInitialize(cmd_line_args::Bool = true) if (cmd_line_args) PetscInitialize(ARGS) else @@ -61,7 +65,12 @@ end """ function PetscInitialized() isInitialized = Ref{PetscBool}() - error = ccall((:PetscInitialized, libpetsc), PetscErrorCode, (Ref{PetscBool},), isInitialized) + error = ccall( + (:PetscInitialized, libpetsc), + PetscErrorCode, + (Ref{PetscBool},), + isInitialized, + ) @assert iszero(error) return Bool(isInitialized[]) -end \ No newline at end of file +end diff --git a/src/load.jl b/src/load.jl index bc3b861..9b45f17 100644 --- a/src/load.jl +++ b/src/load.jl @@ -27,7 +27,11 @@ function get_petsc_location() @warn "Setting fictive PETSc path because of RegistryCI or Doc deployment" PETSC_LIB = "JULIA_REGISTRYCI_AUTOMERGE" else - throw(ErrorException("PETSc shared library (libpetsc.so) not found. Please check that PETSC_DIR and PETSC_ARCH env. variables are set.")) + throw( + ErrorException( + "PETSc shared library (libpetsc.so) not found. Please check that PETSC_DIR and PETSC_ARCH env. variables are set.", + ), + ) end end @@ -37,4 +41,4 @@ end # Absolute path to libpetsc.so const libpetsc = get_petsc_location() -show_petsc_path() = return libpetsc \ No newline at end of file +show_petsc_path() = return libpetsc From f99b51bb3617460a1c2b26ea5e07c4f23c4d5a9d Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 15:11:22 +0200 Subject: [PATCH 13/40] fix exports --- src/PetscWrap.jl | 108 +++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index dccfe9d..dbc0f51 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -29,77 +29,57 @@ export PetscReal, PetscScalar, PetscInt, PetscIntOne include("init.jl") export PetscInitialize, PetscInitialized, PetscFinalize -include("viewer.jl") +include("PetscViewer.jl") export PetscViewer, CViewer, - PetscViewerASCIIOpen, - PetscViewerCreate, - PetscViewerDestroy, - PetscViewerFileSetMode, - PetscViewerFileSetName, - PetscViewerHDF5Open, - PetscViewerPopFormat, - PetscViewerPushFormat, - PetscViewerSetType, - PetscViewerStdWorld, - PetscViewerView + ASCIIOpen, + create, + destroy, + fileSetMode, + fileSetName, + HDF5Open, + popFormat, + pushFormat, + setType, + stdWorld, + view -include("local2global.jl") -export ISLocalToGlobalMappingCreate, ISLocalToGlobalMappingDestroy - -include("vec.jl") -export PetscVec, +include("ISLocalToGlobalMapping.jl") +include("Vec.jl") +export Vec, CVec, - VecAssemble, - VecAssemblyBegin, - VecAssemblyEnd, - VecCopy, - VecCreate, - VecDestroy, - VecDuplicate, - VecGetArray, - VecGetLocalSize, - VecGetOwnershipRange, - VecGetSize, - VecRestoreArray, - VecScale, - VecSetFromOptions, - VecSetSizes, - VecSetUp, - VecSetValue, - VecSetValues, - VecView + assemblyBegin, + assemblyEnd, + copy, + duplicate, + getArray, + getLocalSize, + getOwnershipRange, + getSize, + restoreArray, + scale, + setFromOptions, + setSizes, + setUp, + setValue, + setValues, + view -include("mat.jl") -export PetscMat, +include("Mat.jl") +export Mat, CMat, - MatAssemble, - MatAssemblyBegin, - MatAssemblyEnd, - MatCreate, - MatCreateComposite, - MatCreateDense, - MatCreateVecs, - MatDestroy, - MatGetLocalSize, - MatGetOwnershipRange, - MatGetOwnershipRangeColumn, - MatGetSize, - MatGetType, - MatMPIAIJSetPreallocation, - MatMult, - MatMultAdd, - MatSeqAIJSetPreallocation, - MatSetFromOptions, - MatSetSizes, - MatSetUp, - MatSetValue, - MatSetValues, - MatView + createComposite, + createDense, + createVecs, + getOwnershipRangeColumn, + getType, + MPIAIJSetPreallocation, + mult, + multAdd, + SeqAIJSetPreallocation -include("ksp.jl") -export PetscKSP, - CKSP, KSPCreate, KSPDestroy, KSPSetFromOptions, KSPSetOperators, KSPSetUp, KSPSolve +include("KSP.jl") +export KSP, CKSP, setOperators, solve # fancy include("fancy/viewer.jl") From b3286e158b79093d15a994619a028fca18627b2f Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 16:52:28 +0200 Subject: [PATCH 14/40] wip on fancy --- example/linear_system.jl | 66 +++++++++++----------- src/KSP.jl | 12 ++-- src/Mat.jl | 25 +++++---- src/PetscViewer.jl | 6 +- src/PetscWrap.jl | 1 + src/Vec.jl | 17 ++++-- src/fancy/common.jl | 3 + src/fancy/ksp.jl | 34 +++++------- src/fancy/mat.jl | 116 +++++++++++++++++---------------------- src/fancy/vec.jl | 87 ++++++++++++++--------------- src/fancy/viewer.jl | 22 +++++--- test/linear_system.jl | 69 ++++++++++++----------- test/misc.jl | 15 +++-- 13 files changed, 226 insertions(+), 247 deletions(-) create mode 100644 src/fancy/common.jl diff --git a/example/linear_system.jl b/example/linear_system.jl index 159720b..6ae178f 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -25,73 +25,73 @@ n = 11 Δx = 1.0 / (n - 1) # Create a matrix and a vector (you can specify the MPI communicator if you want) -A = MatCreate() -b = VecCreate() +A = create(Mat) +b = create(Vec) # Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should # set the number of preallocated non-zeros to increase performance. -MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) -VecSetSizes(b, PETSC_DECIDE, n) +setSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) +setSizes(b, PETSC_DECIDE, n) # We can then use command-line options to set our matrix/vectors. -MatSetFromOptions(A) -VecSetFromOptions(b) +setFromOptions(A) +setFromOptions(b) # Finish the set up -MatSetUp(A) -VecSetUp(b) +setUp(A) +setUp(b) # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. # As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor # (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout # the fancy version of this example for a more Julia-like convention. -b_start, b_end = VecGetOwnershipRange(b) +b_start, b_end = getOwnershipRange(b) # Now let's build the right hand side vector. Their are various ways to do this, this is just one. -n_loc = VecGetLocalSize(b) # Note that n_loc = b_end - b_start... -VecSetValues(b, collect(b_start:b_end-1), 2 * ones(n_loc)) +n_loc = getLocalSize(b) # Note that n_loc = b_end - b_start... +setValues(b, collect(b_start:(b_end - 1)), 2 * ones(n_loc)) # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. -A_start, A_end = MatGetOwnershipRange(A) -for i in A_start:A_end-1 - MatSetValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) +A_start, A_end = getOwnershipRange(A) +for i = A_start:(A_end - 1) + setValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # setValues(A, I, J, V, INSERT_VALUES) end # Set boundary condition (only the proc handling index `0` is acting) -(b_start == 0) && VecSetValue(b, 0, 0.0) +(b_start == 0) && setValue(b, 0, 0.0) # Assemble matrices -MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY) -VecAssemblyBegin(b) -MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY) -VecAssemblyEnd(b) +assemblyBegin(A, MAT_FINAL_ASSEMBLY) +assemblyBegin(b) +assemblyEnd(A, MAT_FINAL_ASSEMBLY) +assemblyEnd(b) # At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call -MatView(A) -VecView(b) +PetscWrap.view(A) +PetscWrap.view(b) # Set up the linear solver -ksp = KSPCreate() -KSPSetOperators(ksp, A, A) -KSPSetFromOptions(ksp) -KSPSetUp(ksp) +ksp = create(KSP) +setOperators(ksp, A, A) +setFromOptions(ksp) +setUp(ksp) # Solve the system. We first allocate the solution using the `VecDuplicate` method. -x = VecDuplicate(b) -KSPSolve(ksp, b, x) +x = duplicate(b) +solve(ksp, b, x) # Print the solution -VecView(x) +PetscWrap.view(x) # Access the solution (this part is under development), getting a Julia array; and then restore it -array, ref = VecGetArray(x) # do something with array +array, ref = getArray(x) # do something with array @show array -VecRestoreArray(x, ref) +restoreArray(x, ref) # Free memory -MatDestroy(A) -VecDestroy(b) -VecDestroy(x) +destroy(A) +destroy(b) +destroy(x) # Finalize Petsc PetscFinalize() diff --git a/src/KSP.jl b/src/KSP.jl index 6c3ab27..5a8e453 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -11,12 +11,12 @@ end Base.cconvert(::Type{CKSP}, ksp::KSP) = ksp.ptr[] """ - create(::Type{KSP}, comm::MPI.Comm) + create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) Wrapper for `KSPCreate` https://petsc.org/release/docs/manualpages/KSP/KSPCreate/ """ -function create(::Type{KSP}, comm::MPI.Comm) +function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) ksp = KSP(comm) error = ccall( (:KSPCreate, libpetsc), @@ -52,12 +52,12 @@ function setFromOptions(ksp::KSP) end """ - setOperators(ksp::KSP, Amat::PetscMat, Pmat::PetscMat) + setOperators(ksp::KSP, Amat::Mat, Pmat::Mat) Wrapper for `KSPSetOperators`` https://petsc.org/release/docs/manualpages/KSP/KSPSetOperators/ """ -function setOperators(ksp::KSP, Amat::PetscMat, Pmat::PetscMat) +function setOperators(ksp::KSP, Amat::Mat, Pmat::Mat) error = ccall( (:KSPSetOperators, libpetsc), PetscErrorCode, @@ -81,12 +81,12 @@ function setUp(ksp::KSP) end """ - solve(ksp::KSP, b::PetscVec, x::PetscVec) + solve(ksp::KSP, b::Vec, x::Vec) Wrapper for `KSPSolve` https://petsc.org/release/docs/manualpages/KSP/KSPSolve/ """ -function solve(ksp::KSP, b::PetscVec, x::PetscVec) +function solve(ksp::KSP, b::Vec, x::Vec) error = ccall((:KSPSolve, libpetsc), PetscErrorCode, (CKSP, CVec, CVec), ksp, b, x) @assert iszero(error) end diff --git a/src/Mat.jl b/src/Mat.jl index 9ece534..32fb634 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -59,12 +59,13 @@ function compositeAddMat(mat::Mat, smat::Mat) end """ - create(::Type{Mat}, comm::MPI.Comm) + create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD) + create(::Type{Mat}) Wrapper to `MatCreate` https://petsc.org/release/docs/manualpages/Mat/MatCreate/ """ -function create(::Type{Mat}, comm::MPI.Comm) +function create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD) mat = Mat(comm) error = ccall( (:MatCreate, libpetsc), @@ -121,13 +122,13 @@ function createDense( end """ - createVecs(mat::Mat, vecr::PetscVec, veci::PetscVec) + createVecs(mat::Mat, vecr::Vec, veci::Vec) createVecs(mat::Mat) Wrapper to `MatCreateVecs` https://petsc.org/release/docs/manualpages/Mat/MatCreateVecs/ """ -function createVecs(mat::Mat, right::PetscVec, left::PetscVec) +function createVecs(mat::Mat, right::Vec, left::Vec) error = ccall( (:MatCreateVecs, libpetsc), PetscErrorCode, @@ -140,8 +141,8 @@ function createVecs(mat::Mat, right::PetscVec, left::PetscVec) end function createVecs(mat::Mat) - right = PetscVec(mat.comm) - left = PetscVec(mat.comm) + right = Vec(mat.comm) + left = Vec(mat.comm) createVecs(mat, right, left) return right, left end @@ -349,27 +350,27 @@ function MPIAIJSetPreallocation(mat::Mat, dnz::PetscInt, onz::PetscInt) end """ - mult(mat::Mat, x::PetscVec, y::PetscVec) + mult(mat::Mat, x::Vec, y::Vec) Wrapper to `MatMult` https://petsc.org/release/docs/manualpages/Mat/MatMult/ Compute `y = Ax` """ -function mult(mat::Mat, x::PetscVec, y::PetscVec) +function mult(mat::Mat, x::Vec, y::Vec) error = ccall((:MatMult, libpetsc), PetscErrorCode, (CMat, CVec, CVec), mat, x, y) @assert iszero(error) end """ - multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) + multAdd(A::Mat, v1::Vec, v2::Vec, v3::Vec) Wrapper to `MatMultAdd` https://petsc.org/release/docs/manualpages/Mat/MatMultAdd/ Compute `v3 = v2 + A * v1`. """ -function multAdd(A::Mat, v1::PetscVec, v2::PetscVec, v3::PetscVec) +function multAdd(A::Mat, v1::Vec, v2::Vec, v3::Vec) error = ccall( (:MatMultAdd, libpetsc), PetscErrorCode, @@ -628,12 +629,12 @@ function setValues(mat::Mat, I, J, V, mode::InsertMode) end """ - view(mat::Mat, viewer::PetscViewer = PetscViewerStdWorld()) + view(mat::Mat, viewer::PetscViewer = StdWorld()) Wrapper to `MatView` https://petsc.org/release/docs/manualpages/Mat/MatView/ """ -function view(mat::Mat, viewer::PetscViewer = PetscViewerStdWorld()) +function view(mat::Mat, viewer::PetscViewer = StdWorld(mat.comm)) error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) @assert iszero(error) end diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index c6d7aa3..4c14236 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -15,7 +15,7 @@ Base.cconvert(::Type{CViewer}, viewer::PetscViewer) = viewer.ptr[] Wrapper for `PetscViewerASCIIGetStdout` https://petsc.org/release/docs/manualpages/Viewer/PetscViewerASCIIGetStdout/ """ -function ASCIIGetStdout(comm::MPI.Comm) +function ASCIIGetStdout(comm::MPI.Comm = MPI.COMM_WORLD) viewer = PetscViewer(comm) error = ccall( (:PetscViewerASCIIGetStdout, libpetsc), @@ -51,12 +51,12 @@ function ASCIIOpen(comm::MPI.Comm, name::String) end """ - create(::Type{PetscView}, comm::MPI.Comm) + create(::Type{PetscViewer}, comm::MPI.Comm = MPI.COMM_WORLD) Wrapper for `PetscViewerCreate` https://petsc.org/release/docs/manualpages/Viewer/PetscViewerCreate/ """ -function create(::Type{PetscView}, comm::MPI.Comm) +function create(::Type{PetscViewer}, comm::MPI.Comm = MPI.COMM_WORLD) viewer = PetscViewer(comm) error = ccall( (:PetscViewerCreate, libpetsc), diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index dbc0f51..5eae482 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -82,6 +82,7 @@ include("KSP.jl") export KSP, CKSP, setOperators, solve # fancy +include("fancy/common.jl") include("fancy/viewer.jl") export destroy!, push_format!, set_mode!, set_name!, set_type! diff --git a/src/Vec.jl b/src/Vec.jl index 33e676c..5f82de5 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -38,25 +38,27 @@ end Wrapper to `VecCopy` https://petsc.org/release/docs/manualpages/Vec/VecCopy/ + +Not really sure if I should extend Base here... """ -function copy(x::Vec, y::Vec) +function Base.copy(x::Vec, y::Vec) error = ccall((:VecCopy, libpetsc), PetscErrorCode, (CVec, CVec), x, y) @assert iszero(error) end -function copy(x::Vec) +function Base.copy(x::Vec) y = duplicate(x) copy(x, y) return y end """ - create(::Type{Vec},comm::MPI.Comm) + create(::Type{Vec},comm::MPI.Comm = MPI.COMM_WORLD) Wrapper to `VecCreate` https://petsc.org/release/docs/manualpages/Vec/VecCreate/ """ -function create(::Type{Vec}, comm::MPI.Comm) +function create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD) vec = Vec(comm) error = ccall( (:VecCreate, libpetsc), @@ -250,6 +252,7 @@ end """ setSizes(v::Vec, n::PetscInt, N::PetscInt) + setSizes(v::Vec, n::Integer, N::Integer) Wrapper to `VecSetSizes` https://petsc.org/release/docs/manualpages/Vec/VecSetSizes/ @@ -268,6 +271,8 @@ function setSizes(v::Vec, n::PetscInt, N::PetscInt) @assert iszero(error) end +setSizes(v::Vec, n::Integer, N::Integer) = setSizes(v, PetscInt(n), PetscInt(N)) + """ setUp(vec::Vec) @@ -353,12 +358,12 @@ function setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) end """ - view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) + view(vec::Vec, viewer::PetscViewer = StdWorld()) Wrapper to `VecView` https://petsc.org/release/docs/manualpages/Vec/VecView/ """ -function view(vec::Vec, viewer::PetscViewer = PetscViewerStdWorld()) +function view(vec::Vec, viewer::PetscViewer = StdWorld(vec.comm)) error = ccall((:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer) @assert iszero(error) end diff --git a/src/fancy/common.jl b/src/fancy/common.jl new file mode 100644 index 0000000..d30cdb2 --- /dev/null +++ b/src/fancy/common.jl @@ -0,0 +1,3 @@ +const destroy! = destroy +const set_from_options! = setFromOptions +const set_up! = setUp \ No newline at end of file diff --git a/src/fancy/ksp.jl b/src/fancy/ksp.jl index 61e516c..f6b2a8e 100644 --- a/src/fancy/ksp.jl +++ b/src/fancy/ksp.jl @@ -1,34 +1,26 @@ create_ksp() = KSPCreate() -function create_ksp(A::PetscMat) - ksp = KSPCreate() - KSPSetOperators(ksp, A, A) +function create_ksp(A::Mat) + ksp = create(KSP) + setOperators(ksp, A, A) return ksp end -function create_ksp(Amat::PetscMat, Pmat::PetscMat) - ksp = KSPCreate() - KSPSetOperators(ksp, Amat, Pmat) +function create_ksp(Amat::Mat, Pmat::Mat) + ksp = create(KSP) + setOperators(ksp, Amat, Pmat) return ksp end -set_operators!(ksp::PetscKSP, Amat::PetscMat) = KSPSetOperators(ksp, Amat, Amat) -function set_operators!(ksp::PetscKSP, Amat::PetscMat, Pmat::PetscMat) - KSPSetOperators(ksp, Amat, Pmat) -end +set_operators!(ksp::KSP, Amat::Mat) = setOperators(ksp, Amat, Amat) +set_operators!(ksp::KSP, Amat::Mat, Pmat::Mat) = setOperators(ksp, Amat, Pmat) -solve!(ksp::PetscKSP, b::PetscVec, x::PetscVec) = KSPSolve(ksp, b, x) +solve!(ksp::KSP, b::Vec, x::Vec) = solve(ksp, b, x) -function solve(ksp::PetscKSP, b::PetscVec) - x = VecDuplicate(b) - KSPSolve(ksp, b, x) +function solve(ksp::KSP, b::Vec) + x = duplicate(b) + solve(ksp, b, x) return x end -set_up!(ksp::PetscKSP) = KSPSetUp(ksp) - -set_from_options!(ksp::PetscKSP) = KSPSetFromOptions(ksp) - -Base.show(::IO, ksp::PetscKSP) = KSPView(ksp) - -destroy!(ksp::PetscKSP) = KSPDestroy(ksp) +Base.show(::IO, ksp::KSP) = KSPView(ksp) diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 57c7f2b..132f293 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -5,30 +5,24 @@ For some unkwnown reason, calling `MatSetValue` fails. """ -function Base.setindex!(mat::PetscMat, value::Number, row::Integer, col::Integer) - MatSetValues( - mat, - PetscInt[row - 1], - PetscInt[col - 1], - PetscScalar[value], - INSERT_VALUES, - ) +function Base.setindex!(mat::Mat, value::Number, row::Integer, col::Integer) + setValues(mat, PetscInt[row - 1], PetscInt[col - 1], PetscScalar[value], INSERT_VALUES) end # This is stupid but I don't know how to do better yet -function Base.setindex!(mat::PetscMat, values, row::Integer, cols) - MatSetValues(mat, [row - 1], collect(cols) .- 1, values, INSERT_VALUES) +function Base.setindex!(mat::Mat, values, row::Integer, cols) + setValues(mat, [row - 1], collect(cols) .- 1, values, INSERT_VALUES) end -function Base.setindex!(mat::PetscMat, values, rows, col::Integer) - MatSetValues(mat, collect(rows) .- 1, [col - 1], values, INSERT_VALUES) +function Base.setindex!(mat::Mat, values, rows, col::Integer) + setValues(mat, collect(rows) .- 1, [col - 1], values, INSERT_VALUES) end -Base.ndims(::Type{PetscMat}) = 2 +Base.ndims(::Type{Mat}) = 2 """ create_matrix(nrows, ncols, nrows_loc = PETSC_DECIDE, ncols_loc = PETSC_DECIDE; auto_setup = false) -Create a `PetscMat` matrix of global size `(nrows, ncols)`. +Create a `Mat` matrix of global size `(nrows, ncols)`. Use `auto_setup = true` to immediatly call `set_from_options!` and `set_up!`. """ @@ -40,8 +34,8 @@ function create_matrix( auto_setup = false, comm::MPI.Comm = MPI.COMM_WORLD, ) - mat = MatCreate() - MatSetSizes(mat::PetscMat, nrows_loc, ncols_loc, nrows, ncols) + mat = create(Mat) + setSizes(mat::Mat, nrows_loc, ncols_loc, nrows, ncols) if (auto_setup) set_from_options!(mat) @@ -54,30 +48,26 @@ end Wrapper to `MatCreateComposite` using the "alternative construction" from the PETSc documentation. """ function create_composite_add(matrices) - N, M = MatGetSize(matrices[1]) - n, m = MatGetLocalSize(matrices[1]) + N, M = getSize(matrices[1]) + n, m = getLocalSize(matrices[1]) mat = create_matrix(N, M, n, m; auto_setup = false, comm = matrices[1].comm) - MatSetType(mat, "composite") + setType(mat, "composite") for m in matrices - MatCompositeAddMat(mat, m) + compositeAddMat(mat, m) end assemble!(mat) return mat end -function set_global_size!(mat::PetscMat, nrows, ncols) - MatSetSizes(mat, PETSC_DECIDE, PETSC_DECIDE, nrows, ncols) +function set_global_size!(mat::Mat, nrows, ncols) + setSizes(mat, PETSC_DECIDE, PETSC_DECIDE, nrows, ncols) end -function set_local_size!(mat::PetscMat, nrows, ncols) - MatSetSizes(mat, nrows, ncols, PETSC_DECIDE, PETSC_DECIDE) +function set_local_size!(mat::Mat, nrows, ncols) + setSizes(mat, nrows, ncols, PETSC_DECIDE, PETSC_DECIDE) end -set_from_options!(mat::PetscMat) = MatSetFromOptions(mat) - -set_up!(mat::PetscMat) = MatSetUp(mat) - """ - get_range(mat::PetscMat) + get_range(mat::Mat) Wrapper to `MatGetOwnershipRange` @@ -85,63 +75,57 @@ However, the result `(rstart, rend)` is such that `mat[rstart:rend]` are the row This is different from the default `PETSc.MatGetOwnershipRange` result where the indexing starts at zero and where `rend-1` is last row handled by the local processor. """ -function get_range(mat::PetscMat) - rstart, rend = MatGetOwnershipRange(mat) +function get_range(mat::Mat) + rstart, rend = getOwnershipRange(mat) return (rstart + 1, rend) end """ - get_urange(mat::PetscMat) + get_urange(mat::Mat) Provide a `UnitRange` from the method `get_range`. """ -function get_urange(mat::PetscMat) - rstart, rend = MatGetOwnershipRange(mat) +function get_urange(mat::Mat) + rstart, rend = getOwnershipRange(mat) return (rstart + 1):rend end """ Wrapper to `MatAssemblyBegin` and `MatAssemblyEnd` successively. """ -function assemble!(mat::PetscMat, type::MatAssemblyType = MAT_FINAL_ASSEMBLY) - MatAssemblyBegin(mat, type) - MatAssemblyEnd(mat, type) +function assemble!(mat::Mat, type::MatAssemblyType = MAT_FINAL_ASSEMBLY) + assemblyBegin(mat, type) + assemblyEnd(mat, type) end """ - set_value!(mat::PetscMat, I, J, V, mode = ADD_VALUES) + set_value!(mat::Mat, I, J, V, mode = ADD_VALUES) Set value of `mat` `mat[i, j] = v`. """ -function set_value!( - mat::PetscMat, - i::PetscInt, - j::PetscInt, - v::PetscScalar, - mode = ADD_VALUES, -) - MatSetValue(mat, i - 1, j - 1, v, mode) +function set_value!(mat::Mat, i::PetscInt, j::PetscInt, v::PetscScalar, mode = ADD_VALUES) + setValue(mat, i - 1, j - 1, v, mode) end function set_value!(mat, i, j, v, mode = ADD_VALUES) set_value!(mat, PetscInt(i), PetscInt(j), PetscScalar(v), mode) end """ - set_values!(mat::PetscMat, I, J, V, mode = ADD_VALUES) + set_values!(mat::Mat, I, J, V, mode = ADD_VALUES) Set values of `mat` in `SparseArrays` fashion : using COO format: `mat[I[k], J[k]] = V[k]`. """ function set_values!( - mat::PetscMat, + mat::Mat, I::Vector{PetscInt}, J::Vector{PetscInt}, V::Vector{PetscScalar}, mode = ADD_VALUES, ) for (i, j, v) in zip(I, J, V) - MatSetValue(mat, i - PetscIntOne, j - PetscIntOne, v, mode) + setValue(mat, i - PetscIntOne, j - PetscIntOne, v, mode) end end @@ -150,16 +134,16 @@ function set_values!(mat, I, J, V, mode = ADD_VALUES) end # Warning : cannot use Vector{Integer} because `[1, 2] isa Vector{Integer}` is `false` -function _preallocate!(mat::PetscMat, dnz::Integer, onz::Integer, ::Val{:mpiaij}) - MatMPIAIJSetPreallocation(mat, PetscInt(dnz), PetscInt(onz)) +function _preallocate!(mat::Mat, dnz::Integer, onz::Integer, ::Val{:mpiaij}) + MPIAIJSetPreallocation(mat, PetscInt(dnz), PetscInt(onz)) end function _preallocate!( - mat::PetscMat, + mat::Mat, d_nnz::Vector{I}, o_nnz::Vector{I}, ::Val{:mpiaij}, ) where {I} - MatMPIAIJSetPreallocation( + MPIAIJSetPreallocation( mat, PetscInt(0), PetscInt.(d_nnz), @@ -167,39 +151,37 @@ function _preallocate!( PetscInt.(o_nnz), ) end -function _preallocate!(mat::PetscMat, nz::Integer, ::Integer, ::Val{:seqaij}) - MatSeqAIJSetPreallocation(mat, PetscInt(nz)) +function _preallocate!(mat::Mat, nz::Integer, ::Integer, ::Val{:seqaij}) + SeqAIJSetPreallocation(mat, PetscInt(nz)) end -function _preallocate!(mat::PetscMat, nnz::Vector{I}, ::Vector{I}, ::Val{:seqaij}) where {I} - MatSeqAIJSetPreallocation(mat, PetscInt(0), PetscInt.(nnz)) +function _preallocate!(mat::Mat, nnz::Vector{I}, ::Vector{I}, ::Val{:seqaij}) where {I} + SeqAIJSetPreallocation(mat, PetscInt(0), PetscInt.(nnz)) end """ - preallocate!(mat::PetscMat, dnz, onz, warn::Bool = true) + preallocate!(mat::Mat, dnz, onz, warn::Bool = true) Dispatch preallocation according matrix type (seq or mpiaij for instance). TODO: should use kwargs. """ -function preallocate!(mat::PetscMat, dnz, onz, warn::Bool = true) +function preallocate!(mat::Mat, dnz, onz, warn::Bool = true) _preallocate!(mat, dnz, onz, Val(Symbol(MatGetType(mat)))) - MatSetOption(mat, MAT_NEW_NONZERO_ALLOCATION_ERR, warn) + setOption(mat, MAT_NEW_NONZERO_ALLOCATION_ERR, warn) end """ - mat2file(mat::PetscMat, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") + mat2file(mat::Mat, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") -Write a PetscMat to a file. +Write a Mat to a file. """ function mat2file( - mat::PetscMat, + mat::Mat, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii", ) viewer = PetscViewer(mat.comm, filename, format, type) - MatView(mat, viewer) + view(mat, viewer) destroy!(viewer) end -Base.show(::IO, mat::PetscMat) = MatView(mat) - -destroy!(mat::PetscMat) = MatDestroy(mat) +Base.show(::IO, mat::Mat) = view(mat) diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index 7edeeb6..1f970ef 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -1,20 +1,20 @@ -function Base.:*(x::PetscVec, alpha::Number) +function Base.:*(x::Vec, alpha::Number) y = VecCopy(x) scale!(y, alpha) return y end -Base.:*(alpha::Number, vec::PetscVec) = vec * alpha +Base.:*(alpha::Number, vec::Vec) = vec * alpha -function assemble!(vec::PetscVec) - VecAssemblyBegin(vec) - VecAssemblyEnd(vec) +function assemble!(vec::Vec) + assemblyBegin(vec) + assemblyEnd(vec) end """ create_vector(nrows, nrows_loc = PETSC_DECIDE) -Create a `PetscVec` vector of global size `(nrows)`. +Create a `Vec` vector of global size `(nrows)`. """ function create_vector( nrows, @@ -22,8 +22,8 @@ function create_vector( auto_setup = false, comm::MPI.Comm = MPI.COMM_WORLD, ) - vec = VecCreate(comm) - VecSetSizes(vec::PetscVec, nrows_loc, nrows) + vec = create(Vec, comm) + setSizes(vec, nrows_loc, nrows) if (auto_setup) set_from_options!(vec) @@ -33,13 +33,10 @@ function create_vector( return vec end -destroy!(vec::PetscVec) = VecDestroy(vec) - -duplicate(vec::PetscVec) = VecDuplicate(vec) -duplicate(vec::PetscVec, n::Int) = ntuple(i -> VecDuplicate(vec), n) +duplicate(vec::Vec, n::Int) = ntuple(i -> duplicate(vec), n) """ - get_range(vec::PetscVec) + get_range(vec::Vec) Wrapper to `VecGetOwnershipRange` @@ -47,27 +44,27 @@ However, the result `(rstart, rend)` is such that `vec[rstart:rend]` are the row This is different from the default `PETSc.VecGetOwnershipRange` result where the indexing starts at zero and where `rend-1` is last row handled by the local processor. """ -function get_range(vec::PetscVec) - rstart, rend = VecGetOwnershipRange(vec) +function get_range(vec::Vec) + rstart, rend = getOwnershipRange(vec) return (rstart + 1, rend) end """ - get_urange(vec::PetscVec) + get_urange(vec::Vec) Provide a `UnitRange` from the method `get_range`. """ -function get_urange(vec::PetscVec) - rstart, rend = VecGetOwnershipRange(vec) +function get_urange(vec::Vec) + rstart, rend = getOwnershipRange(vec) return (rstart + 1):rend end -Base.ndims(::Type{PetscVec}) = 1 +Base.ndims(::Type{Vec}) = 1 -scale!(vec::PetscVec, alpha::Number) = VecScale(vec, alpha) +const scale! = scale """ - Base.setindex!(vec::PetscVec, value::Number, row::Integer) + Base.setindex!(vec::Vec, value::Number, row::Integer) `row` must be in [1,size(vec)], i.e indexing starts at 1 (Julia). @@ -75,70 +72,66 @@ scale!(vec::PetscVec, alpha::Number) = VecScale(vec, alpha) For some unkwnown reason, calling `VecSetValue` fails. """ -function Base.setindex!(vec::PetscVec, value::Number, row::Integer) - VecSetValues(vec, PetscInt[row .- 1], PetscScalar[value], INSERT_VALUES) +function Base.setindex!(vec::Vec, value::Number, row::Integer) + setValues(vec, PetscInt[row .- 1], PetscScalar[value], INSERT_VALUES) end # This is stupid but I don't know how to do better yet -function Base.setindex!(vec::PetscVec, values, rows) - VecSetValues(vec, collect(rows .- 1), values, INSERT_VALUES) +function Base.setindex!(vec::Vec, values, rows) + setValues(vec, collect(rows .- 1), values, INSERT_VALUES) end -set_from_options!(vec::PetscVec) = VecSetFromOptions(vec) - -set_global_size!(vec::PetscVec, nrows) = VecSetSizes(vec, PETSC_DECIDE, nrows) -set_local_size!(vec::PetscVec, nrows) = VecSetSizes(vec, nrows, PETSC_DECIDE) - -set_up!(vec::PetscVec) = VecSetUp(vec) +set_global_size!(vec::Vec, nrows) = setSizes(vec, PETSC_DECIDE, nrows) +set_local_size!(vec::Vec, nrows) = setSizes(vec, nrows, PETSC_DECIDE) -function set_values!(vec::PetscVec, values) - VecSetValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) +function set_values!(vec::Vec, values) + setValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) end -Base.show(::IO, vec::PetscVec) = VecView(vec) +Base.show(::IO, vec::Vec) = view(vec) """ Wrapper to `VecSetValues`, using julia 1-based indexing. """ function set_values!( - vec::PetscVec, + vec::Vec, rows::Vector{PetscInt}, values::Vector{PetscScalar}, mode::InsertMode = INSERT_VALUES, ) - VecSetValues(vec, rows .- PetscIntOne, values, mode) + setValues(vec, rows .- PetscIntOne, values, mode) end """ - vec2array(vec::PetscVec) + vec2array(vec::Vec) -Convert a `PetscVec` into a Julia `Array`. Allocation is involved in the process since the `PetscVec` +Convert a `Vec` into a Julia `Array`. Allocation is involved in the process since the `Vec` allocated by PETSC is copied into a freshly allocated array. If you prefer not to allocate memory, use `VectGetArray` and `VecRestoreArray` """ -function vec2array(vec::PetscVec) - arrayFromC, array_ref = VecGetArray(vec) +function vec2array(vec::Vec) + arrayFromC, array_ref = getArray(vec) array = copy(arrayFromC) - VecRestoreArray(vec, array_ref) + restoreArray(vec, array_ref) return array end """ - vec2file(vec::PetscVec, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") + vec2file(vec::Vec, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii") -Write a PetscVec to a file. +Write a Vec to a file. """ function vec2file( - vec::PetscVec, + vec::Vec, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii", ) viewer = PetscViewer(vec.comm, filename, format, type) - VecView(vec, viewer) + view(vec, viewer) destroy!(viewer) end # Discutable choice(s) -Base.length(vec::PetscVec) = VecGetLocalSize(vec) -Base.size(vec::PetscVec) = (length(vec),) +Base.length(vec::Vec) = getLocalSize(vec) +Base.size(vec::Vec) = (length(vec),) diff --git a/src/fancy/viewer.jl b/src/fancy/viewer.jl index 4c5675c..676a520 100644 --- a/src/fancy/viewer.jl +++ b/src/fancy/viewer.jl @@ -1,10 +1,16 @@ -const push_format! = PetscViewerPushFormat -const set_mode! = PetscViewerFileSetMode -const set_name! = PetscViewerFileSetName -const set_type! = PetscViewerSetType +const push_format! = pushFormat +const set_mode! = fileSetMode +const set_name! = fileSetName +const set_type! = setType """ - PetscViewer(comm::MPI.Comm, filename::String, format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, type::String = "ascii", mode::PetscFileMode = FILE_MODE_WRITE) + PetscViewer( + comm::MPI.Comm, + filename::String, + format::PetscViewerFormat = PETSC_VIEWER_ASCII_CSV, + type::String = "ascii", + mode::PetscFileMode = FILE_MODE_WRITE, + ) Constructor for a PetscViewer intended to read/write a matrix or a vector with the supplied type and format. """ @@ -15,12 +21,10 @@ function PetscViewer( type::String = "ascii", mode::PetscFileMode = FILE_MODE_WRITE, ) - viewer = PetscViewerCreate(comm) + viewer = create(PetscViewer, comm) set_type!(viewer, type) - set_mode!(viewer, FILE_MODE_WRITE) + set_mode!(viewer, mode) push_format!(viewer, format) set_name!(viewer, filename) return viewer end - -destroy!(viewer::PetscViewer) = PetscViewerDestroy(viewer) diff --git a/test/linear_system.jl b/test/linear_system.jl index 5bfb994..f4ad052 100644 --- a/test/linear_system.jl +++ b/test/linear_system.jl @@ -15,78 +15,77 @@ Δx = 1.0 / (n - 1) # Create a matrix and a vector - A = MatCreate() - b = VecCreate() + A = create(Mat) + b = create(Vec) # Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should # set the number of preallocated non-zeros to increase performance. - MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) - VecSetSizes(b, PETSC_DECIDE, n) + setSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) + setSizes(b, PETSC_DECIDE, n) # We can then use command-line options to set our matrix/vectors. - MatSetFromOptions(A) - VecSetFromOptions(b) + setFromOptions(A) + setFromOptions(b) # Finish the set up - MatSetUp(A) - VecSetUp(b) + setUp(A) + setUp(b) # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. # As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor # (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout # the fancy version of this example for a more Julia-like convention. - b_start, b_end = VecGetOwnershipRange(b) + b_start, b_end = getOwnershipRange(b) # Now let's build the right hand side vector. Their are various ways to do this, this is just one. - n_loc = VecGetLocalSize(b) # Note that n_loc = b_end - b_start... - VecSetValues(b, collect(b_start:b_end-1), 2 * ones(n_loc)) + n_loc = getLocalSize(b) # Note that n_loc = b_end - b_start... + setValues(b, collect(b_start:(b_end - 1)), 2 * ones(n_loc)) # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. - A_start, A_end = MatGetOwnershipRange(A) - for i in A_start:A_end-1 - MatSetValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) + A_start, A_end = getOwnershipRange(A) + for i = A_start:(A_end - 1) + setValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) end # Set boundary condition (only the proc handling index `0` is acting) - (b_start == 0) && VecSetValue(b, 0, 0.0) + (b_start == 0) && setValue(b, 0, 0.0) # Assemble matrices - MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY) - VecAssemblyBegin(b) - MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY) - VecAssemblyEnd(b) + assemblyBegin(A, MAT_FINAL_ASSEMBLY) + assemblyBegin(b) + assemblyEnd(A, MAT_FINAL_ASSEMBLY) + assemblyEnd(b) # At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call - MatView(A) - VecView(b) + PetscWrap.view(A) + PetscWrap.view(b) # Set up the linear solver - ksp = KSPCreate() - KSPSetOperators(ksp, A, A) - KSPSetFromOptions(ksp) - KSPSetUp(ksp) + ksp = create(KSP) + setOperators(ksp, A, A) + setFromOptions(ksp) + setUp(ksp) # Solve the system. We first allocate the solution using the `VecDuplicate` method. - x = VecDuplicate(b) - KSPSolve(ksp, b, x) + x = duplicate(b) + solve(ksp, b, x) # Print the solution - VecView(x) + PetscWrap.iew(x) # Access the solution (this part is under development), getting a Julia array; and then restore it - array, ref = VecGetArray(x) # do something with array - @test isapprox(array, range(0.0, 2.0; length=n)) - VecRestoreArray(x, ref) + array, ref = getArray(x) # do something with array + @test isapprox(array, range(0.0, 2.0; length = n)) + restoreArray(x, ref) # Free memory - MatDestroy(A) - VecDestroy(b) - VecDestroy(x) + destroy(A) + destroy(b) + destroy(x) # Finalize Petsc PetscFinalize() # Reach this point? @test true - end diff --git a/test/misc.jl b/test/misc.jl index 93a341f..ee08dcd 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1,10 +1,9 @@ @testset "composite" begin - PetscInitialize() # Create two matrices - A = create_matrix(2, 2; auto_setup=true) - B = create_matrix(2, 2; auto_setup=true) + A = create_matrix(2, 2; auto_setup = true) + B = create_matrix(2, 2; auto_setup = true) # Fill @@ -32,9 +31,9 @@ C = create_composite_add([A, B]) # Create vectors to check C (see below) - x1 = create_vector(2; auto_setup=true) - x2 = create_vector(2; auto_setup=true) - y = create_vector(2; auto_setup=true) + x1 = create_vector(2; auto_setup = true) + x2 = create_vector(2; auto_setup = true) + y = create_vector(2; auto_setup = true) x1[1] = 1.0 x1[2] = 0.0 x2[1] = 0.0 @@ -42,10 +41,10 @@ assemble!.((x1, x2, y)) # Check result by multiplying with test vectors - MatMult(C, x1, y) + mult(C, x1, y) @test vec2array(y) == [5.0, 3.0] - MatMult(C, x2, y) + mult(C, x2, y) @test vec2array(y) == [3.0, 5.0] # Free memory From 42f7ba24d0c16aa7b2ee8a1b3ee2eb598ed9d267 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 20:49:05 +0200 Subject: [PATCH 15/40] check tests --- Project.toml | 2 +- test/linear_system.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index c651b7b..bfe1864 100644 --- a/Project.toml +++ b/Project.toml @@ -9,5 +9,5 @@ MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] -MPI = "0.16, 0.17, 0.18, 0.19" +MPI = "0.16, 0.17, 0.18, 0.19, 0.20" julia = "1.5, 1.6, 1.7, 1.8" diff --git a/test/linear_system.jl b/test/linear_system.jl index f4ad052..dc6c85f 100644 --- a/test/linear_system.jl +++ b/test/linear_system.jl @@ -71,7 +71,7 @@ solve(ksp, b, x) # Print the solution - PetscWrap.iew(x) + PetscWrap.view(x) # Access the solution (this part is under development), getting a Julia array; and then restore it array, ref = getArray(x) # do something with array From d73c0fb566a8db6106cd8ba75c735b8a9273b2a6 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 20:49:51 +0200 Subject: [PATCH 16/40] update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3b46d5a..e5a893d 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ Any contribution(s) and/or remark(s) are welcome! If you need a function that is Conventions to be applied in future versions ("fancy" stuff is not concerned): -- all PETSc types should have the exact same name in Julia -- all PETSc functions should have the exact same name in julia, but without the type prefix, and with a lower case for the first letter. `VecSetValues` becomes `setValues`; -- all PETSc functions must have the same number of arguments and the same names in julia, except for out-of-place arguments. +- all PETSc types should have the exact same name in Julia; +- all PETSc functions should have the exact same name in julia, but without the type as a prefix, and with a lower case for the first letter. `VecSetValues` becomes `setValues`; +- all PETSc functions must have the same number of arguments and, if possible the same names in julia, except for out-of-place arguments. - functions arguments must all be typed. Additional functions, without type or with fewer args, can be defined if the original version is present. ## PETSc compat. From bb372a90ec02b6a8e77efa9f7bf578386102ae79 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 26 Mar 2023 21:55:41 +0200 Subject: [PATCH 17/40] wip on fancy interface --- example/linear_system_fancy.jl | 10 +++---- src/ISLocalToGlobalMapping.jl | 25 +++++++++++++++- src/Mat.jl | 26 +++++++++++++++++ src/PetscWrap.jl | 1 + src/fancy/mat.jl | 52 +++++++++++++++++++++++++--------- src/fancy/vec.jl | 48 ++++++++++++++++++------------- test/linear_system_fancy.jl | 13 ++++----- test/misc.jl | 10 +++---- 8 files changed, 134 insertions(+), 51 deletions(-) diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index 9b59048..462282b 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -25,8 +25,8 @@ n = 11 Δx = 1.0 / (n - 1) # Create a matrix of size `(n,n)` and a vector of size `(n)` -A = create_matrix(n, n) -b = create_vector(n) +A = create_matrix(; nrows_glo = n, ncols_glo = n) +b = create_vector(; nrows_glo = n) # We can then use command line options to set our matrix/vectors. set_from_options!(A) @@ -48,8 +48,8 @@ b[b_start:b_end] = 2 * ones(n_loc) # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. A_start, A_end = get_range(A) -for i in A_start:A_end - A[i, i-1:i] = [-1.0 1.0] / Δx +for i = A_start:A_end + A[i, (i - 1):i] = [-1.0 1.0] / Δx end # Set boundary condition (only the proc handling index `1` is acting) @@ -79,7 +79,7 @@ destroy!(b) destroy!(x) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: -M = create_matrix(3, 3; auto_setup=true) +M = create_matrix(; nrows_glo = 3, ncols_glo = 3, auto_setup = true) M_start, M_end = get_range(M) I = [1, 1, 1, 2, 3] J = [1, 3, 1, 3, 2] diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index b3e30f4..4bc4a2c 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -11,7 +11,7 @@ end Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2g.ptr[] """ - localToGlobalMappingCreate( + create( comm::MPI.Comm, bs::PetscInt, n::PetscInt, @@ -19,6 +19,13 @@ Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2 mode::PetscCopyMode, ) + create( + ::Type{ISLocalToGlobalMapping}, + comm::MPI.Comm, + indices::Vector{Integer}, + mode::PetscCopyMode = PETSC_COPY_VALUES, + ) + Wrapper to `ISLocalToGlobalMappingCreate` https://petsc.org/release/docs/manualpages/IS/ISLocalToGlobalMappingCreate/ """ @@ -53,6 +60,22 @@ function create( return l2g end +function create( + ::Type{ISLocalToGlobalMapping}, + comm::MPI.Comm, + indices::Vector{Integer}, + mode::PetscCopyMode = PETSC_COPY_VALUES, +) + return create( + ISLocalToGlobalMapping, + comm, + PetscIntOne, + PetscInt(length(indices)), + PetscInt.(indices), + mode, + ) +end + """ destroy(mapping::ISLocalToGlobalMapping) diff --git a/src/Mat.jl b/src/Mat.jl index 32fb634..1289c5e 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -425,6 +425,32 @@ function setFromOptions(mat::Mat) @assert iszero(error) end +""" + setLocalToGlobalMapping( + x::Mat, + rmapping::ISLocalToGlobalMapping, + cmapping::ISLocalToGlobalMapping, + ) + +Wrapper to `MatSetLocalToGlobalMapping` +https://petsc.org/release/docs/manualpages/Mat/MatSetLocalToGlobalMapping/ +""" +function setLocalToGlobalMapping( + x::Mat, + rmapping::ISLocalToGlobalMapping, + cmapping::ISLocalToGlobalMapping, +) + error = ccall( + (:MatSetLocalToGlobalMapping, libpetsc), + PetscErrorCode, + (CMat, CISLocalToGlobalMapping, CISLocalToGlobalMapping), + x, + rmapping, + cmapping, + ) + @assert iszero(error) +end + """ setOption(mat::Mat, op::MatOption, flg::PetscBool) diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 5eae482..03877b6 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -94,6 +94,7 @@ export assemble!, get_range, get_urange, set_local_size!, + set_local_to_global!, set_global_size!, set_from_options!, set_up!, diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 132f293..604faa4 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -20,22 +20,27 @@ end Base.ndims(::Type{Mat}) = 2 """ - create_matrix(nrows, ncols, nrows_loc = PETSC_DECIDE, ncols_loc = PETSC_DECIDE; auto_setup = false) - -Create a `Mat` matrix of global size `(nrows, ncols)`. + create_matrix( + comm::MPI.Comm = MPI.COMM_WORLD; + nrows_loc = PETSC_DECIDE, + ncols_loc = PETSC_DECIDE, + nrows_glo = PETSC_DECIDE, + ncols_glo = PETSC_DECIDE, + auto_setup = false, + ) Use `auto_setup = true` to immediatly call `set_from_options!` and `set_up!`. """ function create_matrix( - nrows, - ncols, + comm::MPI.Comm = MPI.COMM_WORLD; nrows_loc = PETSC_DECIDE, - ncols_loc = PETSC_DECIDE; + ncols_loc = PETSC_DECIDE, + nrows_glo = PETSC_DECIDE, + ncols_glo = PETSC_DECIDE, auto_setup = false, - comm::MPI.Comm = MPI.COMM_WORLD, ) - mat = create(Mat) - setSizes(mat::Mat, nrows_loc, ncols_loc, nrows, ncols) + mat = create(Mat, comm) + setSizes(mat, nrows_loc, ncols_loc, nrows_glo, ncols_glo) if (auto_setup) set_from_options!(mat) @@ -48,12 +53,19 @@ end Wrapper to `MatCreateComposite` using the "alternative construction" from the PETSc documentation. """ function create_composite_add(matrices) - N, M = getSize(matrices[1]) - n, m = getLocalSize(matrices[1]) - mat = create_matrix(N, M, n, m; auto_setup = false, comm = matrices[1].comm) + M, N = getSize(matrices[1]) + m, n = getLocalSize(matrices[1]) + mat = create_matrix( + matrices[1].comm; + nrows_loc = m, + ncols_loc = n, + nrows_glo = M, + nrows_glo = N, + auto_setup = false, + ) setType(mat, "composite") - for m in matrices - compositeAddMat(mat, m) + for _mat in matrices + compositeAddMat(mat, _mat) end assemble!(mat) return mat @@ -62,6 +74,18 @@ end function set_global_size!(mat::Mat, nrows, ncols) setSizes(mat, PETSC_DECIDE, PETSC_DECIDE, nrows, ncols) end + +function set_local_to_global!( + mat::Mat, + rlid2gid::Vector{Integer}, + clid2gid::Vector{Integer}, +) + rmapping = create(ISLocalToGlobalMapping, rlid2gid) + cmapping = create(ISLocalToGlobalMapping, clid2gid) + setLocalToGlobalMapping(mat, rmapping, cmapping) + destroy.(rmapping, cmapping) +end + function set_local_size!(mat::Mat, nrows, ncols) setSizes(mat, nrows, ncols, PETSC_DECIDE, PETSC_DECIDE) end diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index 1f970ef..e8aca23 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -12,20 +12,25 @@ function assemble!(vec::Vec) end """ - create_vector(nrows, nrows_loc = PETSC_DECIDE) - -Create a `Vec` vector of global size `(nrows)`. + create_vector( + comm::MPI.Comm = MPI.COMM_WORLD; + nrows_loc = PETSC_DECIDE, + nrows_glo = PETSC_DECIDE, + auto_setup = false, + ) + +Create a `Vec` vector of global size `(nrows_glo)`. """ function create_vector( - nrows, - nrows_loc = PETSC_DECIDE; + comm::MPI.Comm = MPI.COMM_WORLD; + nrows_loc = PETSC_DECIDE, + nrows_glo = PETSC_DECIDE, auto_setup = false, - comm::MPI.Comm = MPI.COMM_WORLD, ) vec = create(Vec, comm) - setSizes(vec, nrows_loc, nrows) + setSizes(vec, nrows_loc, nrows_glo) - if (auto_setup) + if auto_setup set_from_options!(vec) set_up!(vec) end @@ -82,26 +87,31 @@ function Base.setindex!(vec::Vec, values, rows) end set_global_size!(vec::Vec, nrows) = setSizes(vec, PETSC_DECIDE, nrows) -set_local_size!(vec::Vec, nrows) = setSizes(vec, nrows, PETSC_DECIDE) -function set_values!(vec::Vec, values) - setValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) +function set_local_to_global!(vec::Vec, lid2gid::Vector{Integer}) + mapping = create(ISLocalToGlobalMapping, lid2gid) + setLocalToGlobalMapping(vec, mapping) + destroy(mapping) end -Base.show(::IO, vec::Vec) = view(vec) +set_local_size!(vec::Vec, nrows) = setSizes(vec, nrows, PETSC_DECIDE) """ + set_values!(vec::Vec, rows, values, mode::InsertMode = INSERT_VALUES) + set_values!(vec::Vec, values) + Wrapper to `VecSetValues`, using julia 1-based indexing. """ -function set_values!( - vec::Vec, - rows::Vector{PetscInt}, - values::Vector{PetscScalar}, - mode::InsertMode = INSERT_VALUES, -) - setValues(vec, rows .- PetscIntOne, values, mode) +function set_values!(vec::Vec, rows, values, mode::InsertMode = INSERT_VALUES) + setValues(vec, rows .- 1, values, mode) end +function set_values!(vec::Vec, values) + setValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) +end + +Base.show(::IO, vec::Vec) = view(vec) + """ vec2array(vec::Vec) diff --git a/test/linear_system_fancy.jl b/test/linear_system_fancy.jl index 4ab7f3a..be9703b 100644 --- a/test/linear_system_fancy.jl +++ b/test/linear_system_fancy.jl @@ -12,8 +12,8 @@ Δx = 1.0 / (n - 1) # Create a matrix of size `(n,n)` and a vector of size `(n)` - A = create_matrix(n, n) - b = create_vector(n) + A = create_matrix(; nrows_glo = n, ncols_glo = n) + b = create_vector(; nrows_glo = n) # We can then use command line options to set our matrix/vectors. set_from_options!(A) @@ -35,8 +35,8 @@ # And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. A_start, A_end = get_range(A) - for i in A_start:A_end - A[i, i-1:i] = [-1.0 1.0] / Δx + for i = A_start:A_end + A[i, (i - 1):i] = [-1.0 1.0] / Δx end # Set boundary condition (only the proc handling index `1` is acting) @@ -59,7 +59,7 @@ # Convert to Julia array array = vec2array(x) - @test isapprox(array, range(0.0, 2.0; length=n)) + @test isapprox(array, range(0.0, 2.0; length = n)) # Free memory destroy!(A) @@ -67,7 +67,7 @@ destroy!(x) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: - M = create_matrix(3, 3; auto_setup=true) + M = create_matrix(; nrows_glo = 3, ncols_glo = 3, auto_setup = true) M_start, M_end = get_range(M) I = [1, 1, 1, 2, 3] J = [1, 3, 1, 3, 2] @@ -85,5 +85,4 @@ # Reach this point? @test true - end diff --git a/test/misc.jl b/test/misc.jl index ee08dcd..0f858ff 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -2,8 +2,8 @@ PetscInitialize() # Create two matrices - A = create_matrix(2, 2; auto_setup = true) - B = create_matrix(2, 2; auto_setup = true) + A = create_matrix(; nrows_glo = 2, ncols_glo = 2, auto_setup = true) + B = create_matrix(; nrows_glo = 2, ncols_glo = 2, auto_setup = true) # Fill @@ -31,9 +31,9 @@ C = create_composite_add([A, B]) # Create vectors to check C (see below) - x1 = create_vector(2; auto_setup = true) - x2 = create_vector(2; auto_setup = true) - y = create_vector(2; auto_setup = true) + x1 = create_vector(; nrows_glo = 2, auto_setup = true) + x2 = create_vector(; nrows_glo = 2, auto_setup = true) + y = create_vector(; nrows_glo = 2, auto_setup = true) x1[1] = 1.0 x1[2] = 0.0 x2[1] = 0.0 From 0d891944716fcdc54a35867a5e86bf842c4d7fb5 Mon Sep 17 00:00:00 2001 From: Maxime Bouyges Date: Mon, 27 Mar 2023 17:43:49 +0200 Subject: [PATCH 18/40] wip for HauntedArrays --- Project.toml | 1 + README.md | 151 +++++++++++++++++----------------- src/ISLocalToGlobalMapping.jl | 12 +-- src/PetscWrap.jl | 10 ++- src/Vec.jl | 132 +++++++++++++++++++++++++++++ src/fancy/ksp.jl | 13 +-- src/fancy/mat.jl | 10 ++- src/fancy/vec.jl | 42 +++++++++- test/misc.jl | 29 +++++++ test/runtests.jl | 1 + 10 files changed, 308 insertions(+), 93 deletions(-) diff --git a/Project.toml b/Project.toml index bfe1864..49fa145 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ version = "0.1.5" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/README.md b/README.md index e5a893d..db2e1dd 100644 --- a/README.md +++ b/README.md @@ -43,14 +43,13 @@ This version of PetscWrap.jl has been tested with petsc-3.13. Complex numbers ar ## How to use it -PETSc methods wrappers share the same name as their C equivalent : for instance `MatCreate` or `MatSetValue`. Furthermore, an optional "higher level" API, referred to as "fancy", is exposed : for instance `create_matrix` or `A[i,j] = v`). Note that this second way of manipulating PETSc will evolve according the package's author needs while the first one will try to follow PETSc official API. +PETSc methods wrappers share the almost same name as their C equivalent (with the type) : for instance `MatSetValues` becomes `setValues`. Furthermore, an optional "higher level" API, referred to as "fancy", is exposed : for instance `create_matrix` or `A[i,j] = v`. Note that this second way of manipulating PETSc will evolve according the package's author needs while the first one will try to follow PETSc official API. You will find examples of use by building the documentation: `julia PetscWrap.jl/docs/make.jl`. Here is one of the examples: ### A first demo - This example serves as a test since this project doesn't have a "testing" procedure yet. In this example, -the equation `u'(x) = 2` with `u(0) = 0` is solved on the domain `[0,1]` using a backward finite +the equation ``u'(x) = 2`` with ``u(0) = 0`` is solved on the domain ``[0,1]`` using a backward finite difference scheme. In this example, PETSc classic method names are used. For more fancy names, check the fancy version. @@ -62,143 +61,143 @@ To run this example, execute : `mpirun -n your_favorite_positive_integer julia e Import package -```julia +````julia using PetscWrap -``` +```` Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can also provide "command line arguments by defining them in a string, for instance `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` -```julia +````julia PetscInitialize() -``` +```` Number of mesh points and mesh step -```julia +````julia n = 11 -Δx = 1. / (n - 1) -``` +Δx = 1.0 / (n - 1) +```` -Create a matrix and a vector +Create a matrix and a vector (you can specify the MPI communicator if you want) -```julia -A = MatCreate() -b = VecCreate() -``` +````julia +A = create(Mat) +b = create(Vec) +```` Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should set the number of preallocated non-zeros to increase performance. -```julia -MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) -VecSetSizes(b, PETSC_DECIDE, n) -``` +````julia +setSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) +setSizes(b, PETSC_DECIDE, n) +```` We can then use command-line options to set our matrix/vectors. -```julia -MatSetFromOptions(A) -VecSetFromOptions(b) -``` +````julia +setFromOptions(A) +setFromOptions(b) +```` Finish the set up -```julia -MatSetUp(A) -VecSetUp(b) -``` +````julia +setUp(A) +setUp(b) +```` Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout the fancy version of this example for a more Julia-like convention. -```julia -b_start, b_end = VecGetOwnershipRange(b) -``` +````julia +b_start, b_end = getOwnershipRange(b) +```` Now let's build the right hand side vector. Their are various ways to do this, this is just one. -```julia -n_loc = VecGetLocalSize(b) # Note that n_loc = b_end - b_start... -VecSetValues(b, collect(b_start:b_end-1), 2 * ones(n_loc)) -``` +````julia +n_loc = getLocalSize(b) # Note that n_loc = b_end - b_start... +setValues(b, collect(b_start:(b_end - 1)), 2 * ones(n_loc)) +```` And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. -```julia -A_start, A_end = MatGetOwnershipRange(A) -for i in A_start:A_end-1 - MatSetValues(A, [i], [i-1, i], [-1. 1.] / Δx, INSERT_VALUES) # MatSetValues(A, I, J, V, INSERT_VALUES) +````julia +A_start, A_end = getOwnershipRange(A) +for i = A_start:(A_end - 1) + setValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # setValues(A, I, J, V, INSERT_VALUES) end -``` +```` Set boundary condition (only the proc handling index `0` is acting) -```julia -(b_start == 0) && VecSetValue(b, 0, 0.) -``` +````julia +(b_start == 0) && setValue(b, 0, 0.0) +```` Assemble matrices -```julia -MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY) -VecAssemblyBegin(b) -MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY) -VecAssemblyEnd(b) -``` +````julia +assemblyBegin(A, MAT_FINAL_ASSEMBLY) +assemblyBegin(b) +assemblyEnd(A, MAT_FINAL_ASSEMBLY) +assemblyEnd(b) +```` At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call -```julia -MatView(A) -VecView(b) -``` +````julia +PetscWrap.view(A) +PetscWrap.view(b) +```` Set up the linear solver -```julia -ksp = KSPCreate() -KSPSetOperators(ksp, A, A) -KSPSetFromOptions(ksp) -KSPSetUp(ksp) -``` +````julia +ksp = create(KSP) +setOperators(ksp, A, A) +setFromOptions(ksp) +setUp(ksp) +```` Solve the system. We first allocate the solution using the `VecDuplicate` method. -```julia -x = VecDuplicate(b) -KSPSolve(ksp, b, x) -``` +````julia +x = duplicate(b) +solve(ksp, b, x) +```` Print the solution -```julia -VecView(x) -``` +````julia +PetscWrap.view(x) +```` Access the solution (this part is under development), getting a Julia array; and then restore it -```julia -array, ref = VecGetArray(x) # do something with array +````julia +array, ref = getArray(x) # do something with array @show array -VecRestoreArray(x, ref) -``` +restoreArray(x, ref) +```` Free memory -```julia -MatDestroy(A) -VecDestroy(b) -VecDestroy(x) -``` +````julia +destroy(A) +destroy(b) +destroy(x) +```` Finalize Petsc -```julia +````julia PetscFinalize() -``` +```` \ No newline at end of file diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index 4bc4a2c..fb05e41 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -22,12 +22,14 @@ Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2 create( ::Type{ISLocalToGlobalMapping}, comm::MPI.Comm, - indices::Vector{Integer}, + indices::Vector{I}, mode::PetscCopyMode = PETSC_COPY_VALUES, - ) + ) where {I<:Integer} Wrapper to `ISLocalToGlobalMappingCreate` https://petsc.org/release/docs/manualpages/IS/ISLocalToGlobalMappingCreate/ + +0-based indexing """ function create( ::Type{ISLocalToGlobalMapping}, @@ -54,7 +56,7 @@ function create( n, indices, mode, - l2g, + l2g.ptr, ) @assert iszero(error) return l2g @@ -63,9 +65,9 @@ end function create( ::Type{ISLocalToGlobalMapping}, comm::MPI.Comm, - indices::Vector{Integer}, + indices::Vector{I}, mode::PetscCopyMode = PETSC_COPY_VALUES, -) +) where {I<:Integer} return create( ISLocalToGlobalMapping, comm, diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 03877b6..4c695c7 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -7,6 +7,7 @@ module PetscWrap using Libdl using MPI +using LinearAlgebra include("const_arch_ind.jl") export PetscErrorCode, PETSC_DECIDE @@ -56,13 +57,16 @@ export Vec, getLocalSize, getOwnershipRange, getSize, + getValues, restoreArray, scale, setFromOptions, setSizes, setUp, setValue, + setValueLocal, setValues, + setValuesLocal, view include("Mat.jl") @@ -98,11 +102,15 @@ export assemble!, set_global_size!, set_from_options!, set_up!, + set_value!, + set_value_local!, + set_values!, + set_values_local!, vec2array, vec2file include("fancy/mat.jl") -export create_composite_add, create_matrix, mat2file, preallocate!, set_value!, set_values! +export create_composite_add, create_matrix, mat2file, preallocate! include("fancy/ksp.jl") export create_ksp, solve, solve!, set_operators! diff --git a/src/Vec.jl b/src/Vec.jl index 5f82de5..a3d06d3 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -82,6 +82,14 @@ function destroy(v::Vec) @assert iszero(error) end +function LinearAlgebra.dot(x::Vec, y::Vec) + val = Ref{PetscScalar}() + error = ccall((:VecDot, libpetsc), PetscErrorCode, (CVec, CVec, Ref{PetscScalar}), x, y, val) + @assert iszero(error) + + return val[] +end + """ duplicate(v::Vec) @@ -191,6 +199,42 @@ function getSize(x::Vec) return n[] end +""" + getValues(x::Vec, ni::PetscInt, ix::Vector{PetscInt}) + getValues(x::Vec, ix::Vector{PetscInt}) + getValues(x::Vec, ix::Vector{I}) where {I<:Integer} + +Wrapper for `VecGetValues` +https://petsc.org/release/docs/manualpages/Vec/VecGetValues/ +""" +function getValues(x::Vec, ni::PetscInt, ix::Vector{PetscInt}) + y = zeros(PetscScalar, ni) + + error = ccall( + (:VecGetValues, libpetsc), + PetscErrorCode, + ( + CVec, + PetscInt, + Ptr{PetscInt}, + Ptr{PetscScalar}, + ), + x, + ni, + ix, + y, + ) + @assert iszero(error) + + return y +end + +getValues(x::Vec, ix::Vector{PetscInt}) = getValues(x, PetscInt(length(ix)), ix) + +function getValues(x::Vec, ix::Vector{I}) where {I<:Integer} + return getValues(x, PetscInt.(ix)) +end + """ restoreArray(x::Vec, array_ref) @@ -238,6 +282,8 @@ end Wrapper to `VecSetLocalToGlobalMapping` https://petsc.org/release/docs/manualpages/Vec/VecSetLocalToGlobalMapping/ + +0-based indexing """ function setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) error = ccall( @@ -357,6 +403,92 @@ function setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) setValues(x, PetscInt.(I), PetscScalar.(V), mode) end +""" + setValueLocal(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) + setValueLocal(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) + +Wrapper to `setValueLocal`. Indexing starts at 0 (as in PETSc). +https://petsc.org/release/docs/manualpages/Vec/VecSetValueLocal/ + +# Implementation + +For an unknow reason, calling PETSc.VecSetValue leads to an "undefined symbol: VecSetValue" error. +So this wrapper directly call VecSetValues (anyway, this is what is done in PETSc...) +""" +function setValueLocal(v::Vec, row::PetscInt, value::PetscScalar, mode::InsertMode) + setValuesLocal(v, PetscIntOne, [row], [value], mode) +end + +function setValueLocal(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) + setValueLocal(v, PetscInt(row), PetscScalar(value), mode) +end + +""" + setValuesLocal( + x::Vec, + ni::PetscInt, + ix::Vector{PetscInt}, + y::Vector{PetscScalar}, + iora::InsertMode, + ) + + setValuesLocal( + x::Vec, + I::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, + ) + setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) + +Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) +https://petsc.org/release/docs/manualpages/Vec/VecSetValuesLocal/ +""" +function setValuesLocal( + x::Vec, + ni::PetscInt, + ix::Vector{PetscInt}, + y::Vector{PetscScalar}, + iora::InsertMode, +) + error = ccall( + (:VecSetValuesLocal, libpetsc), + PetscErrorCode, + (CVec, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}, InsertMode), + x, + ni, + ix, + y, + iora, + ) + @assert iszero(error) +end + +function setValuesLocal( + x::Vec, + I::Vector{PetscInt}, + V::Vector{PetscScalar}, + mode::InsertMode = INSERT_VALUES, +) + setValuesLocal(x, PetscInt(length(I)), I, V, mode) +end + +function setValuesLocal(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) + setValuesLocal(x, PetscInt.(I), PetscScalar.(V), mode) +end + +function Base.sum(x::Vec) + s = Ref{PetscScalar}() + error = ccall( + (:VecSum, libpetsc), + PetscErrorCode, + (CVec, Ref{PetscScalar}), + x,s, + ) + @assert iszero(error) + + return s[] +end + """ view(vec::Vec, viewer::PetscViewer = StdWorld()) diff --git a/src/fancy/ksp.jl b/src/fancy/ksp.jl index f6b2a8e..6d4a0cd 100644 --- a/src/fancy/ksp.jl +++ b/src/fancy/ksp.jl @@ -1,14 +1,17 @@ -create_ksp() = KSPCreate() - -function create_ksp(A::Mat) +function create_ksp(A::Mat; autosetup = false) ksp = create(KSP) - setOperators(ksp, A, A) + setOperators(ksp, A, A; autosetup) return ksp end -function create_ksp(Amat::Mat, Pmat::Mat) +function create_ksp(Amat::Mat, Pmat::Mat; autosetup = false) ksp = create(KSP) setOperators(ksp, Amat, Pmat) + + if autosetup + set_from_options!(ksp) + set_up!(ksp) + end return ksp end diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 604faa4..ca99d3a 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -60,7 +60,7 @@ function create_composite_add(matrices) nrows_loc = m, ncols_loc = n, nrows_glo = M, - nrows_glo = N, + ncols_glo = N, auto_setup = false, ) setType(mat, "composite") @@ -77,9 +77,9 @@ end function set_local_to_global!( mat::Mat, - rlid2gid::Vector{Integer}, - clid2gid::Vector{Integer}, -) + rlid2gid::Vector{I}, + clid2gid::Vector{I}, +) where {I<:Integer} rmapping = create(ISLocalToGlobalMapping, rlid2gid) cmapping = create(ISLocalToGlobalMapping, clid2gid) setLocalToGlobalMapping(mat, rmapping, cmapping) @@ -127,6 +127,8 @@ end Set value of `mat` `mat[i, j] = v`. + +1-based indexing """ function set_value!(mat::Mat, i::PetscInt, j::PetscInt, v::PetscScalar, mode = ADD_VALUES) setValue(mat, i - 1, j - 1, v, mode) diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index e8aca23..169dfd9 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -88,14 +88,28 @@ end set_global_size!(vec::Vec, nrows) = setSizes(vec, PETSC_DECIDE, nrows) -function set_local_to_global!(vec::Vec, lid2gid::Vector{Integer}) - mapping = create(ISLocalToGlobalMapping, lid2gid) +""" +Wrapper to `ISSetLocalToGlobalMapping` + +1-based indexing +""" +function set_local_to_global!(vec::Vec, lid2gid::Vector{I}) where {I<:Integer} + mapping = create(ISLocalToGlobalMapping, vec.comm, lid2gid .- 1) setLocalToGlobalMapping(vec, mapping) destroy(mapping) end set_local_size!(vec::Vec, nrows) = setSizes(vec, nrows, PETSC_DECIDE) +""" + set_value!(vec::Vec, row, value, mode::InsertMode = INSERT_VALUES) + +Wrapper to `VecSetValue`, using julia 1-based indexing. +""" +function set_value!(vec::Vec, row, value, mode::InsertMode = INSERT_VALUES) + setValue(vec, row - 1, value, mode) +end + """ set_values!(vec::Vec, rows, values, mode::InsertMode = INSERT_VALUES) set_values!(vec::Vec, values) @@ -110,6 +124,30 @@ function set_values!(vec::Vec, values) setValues(vec, collect(get_urange(vec) .- 1), values, INSERT_VALUES) end +""" + set_value_local!(vec::Vec, row, value, mode::InsertMode = INSERT_VALUES) + +Wrapper to `VecSetValueLocal`, using julia 1-based indexing. +""" +function set_value_local!(vec::Vec, row, value, mode::InsertMode = INSERT_VALUES) + setValueLocal(vec, row - 1, value, mode) +end + +""" + set_values_local!(vec::Vec, rows, values, mode::InsertMode = INSERT_VALUES) + set_values_local!(vec::Vec, values) + +Wrapper to `VecSetValuesLocal`, using julia 1-based indexing. +""" +function set_values_local!(vec::Vec, rows, values, mode::InsertMode = INSERT_VALUES) + setValuesLocal(vec, rows .- 1, values, mode) +end + +function set_values_local!(vec::Vec, values) + # Since we are using the "local" numbering, we set element "1" to "nloc" + setValuesLocal(vec, collect(1:getLocalSize(vec)) .- 1, values, INSERT_VALUES) +end + Base.show(::IO, vec::Vec) = view(vec) """ diff --git a/test/misc.jl b/test/misc.jl index 0f858ff..2385d7d 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -49,5 +49,34 @@ # Free memory destroy!.((A, B, C, x1, x2, y)) + PetscFinalize() +end + +@testset "mapping" begin + + PetscInitialize() + + n = 10 + x = create_vector(; nrows_glo = n, auto_setup = true) + y = create_vector(; nrows_glo = n, auto_setup = true) + l2g = reverse(collect(1:n)) + set_local_to_global!(x, l2g) + + set_value_local!(x, 1, 1.0) + set_value!(y, 1, 33) + set_value!(y, 10, 22) + + assemble!.((x,y)) + + # @show dot(x,y) + @test dot(x,x) == 1. + @test dot(x,y) == 22. + @test sum(x) == 1. + + _x = vec2array(x) + @test _x[end] == 1. + + destroy!.((x,y)) + PetscFinalize() end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 6c897b7..8f78982 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,6 @@ using PetscWrap using Test +using LinearAlgebra # from : From 53171ade04c4f18301dad4690c92e0eeff2504ba Mon Sep 17 00:00:00 2001 From: bmxam Date: Tue, 28 Mar 2023 21:59:26 +0200 Subject: [PATCH 19/40] rename autosetup --- example/linear_system_fancy.jl | 2 +- src/fancy/mat.jl | 10 +++++----- src/fancy/vec.jl | 6 +++--- test/linear_system_fancy.jl | 2 +- test/misc.jl | 27 +++++++++++++-------------- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index 462282b..a07655f 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -79,7 +79,7 @@ destroy!(b) destroy!(x) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: -M = create_matrix(; nrows_glo = 3, ncols_glo = 3, auto_setup = true) +M = create_matrix(; nrows_glo = 3, ncols_glo = 3, autosetup = true) M_start, M_end = get_range(M) I = [1, 1, 1, 2, 3] J = [1, 3, 1, 3, 2] diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index ca99d3a..4d952e5 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -26,10 +26,10 @@ Base.ndims(::Type{Mat}) = 2 ncols_loc = PETSC_DECIDE, nrows_glo = PETSC_DECIDE, ncols_glo = PETSC_DECIDE, - auto_setup = false, + autosetup = false, ) -Use `auto_setup = true` to immediatly call `set_from_options!` and `set_up!`. +Use `autosetup = true` to immediatly call `set_from_options!` and `set_up!`. """ function create_matrix( comm::MPI.Comm = MPI.COMM_WORLD; @@ -37,12 +37,12 @@ function create_matrix( ncols_loc = PETSC_DECIDE, nrows_glo = PETSC_DECIDE, ncols_glo = PETSC_DECIDE, - auto_setup = false, + autosetup = false, ) mat = create(Mat, comm) setSizes(mat, nrows_loc, ncols_loc, nrows_glo, ncols_glo) - if (auto_setup) + if (autosetup) set_from_options!(mat) set_up!(mat) end @@ -61,7 +61,7 @@ function create_composite_add(matrices) ncols_loc = n, nrows_glo = M, ncols_glo = N, - auto_setup = false, + autosetup = false, ) setType(mat, "composite") for _mat in matrices diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index 169dfd9..a0f35a6 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -16,7 +16,7 @@ end comm::MPI.Comm = MPI.COMM_WORLD; nrows_loc = PETSC_DECIDE, nrows_glo = PETSC_DECIDE, - auto_setup = false, + autosetup = false, ) Create a `Vec` vector of global size `(nrows_glo)`. @@ -25,12 +25,12 @@ function create_vector( comm::MPI.Comm = MPI.COMM_WORLD; nrows_loc = PETSC_DECIDE, nrows_glo = PETSC_DECIDE, - auto_setup = false, + autosetup = false, ) vec = create(Vec, comm) setSizes(vec, nrows_loc, nrows_glo) - if auto_setup + if autosetup set_from_options!(vec) set_up!(vec) end diff --git a/test/linear_system_fancy.jl b/test/linear_system_fancy.jl index be9703b..1e58476 100644 --- a/test/linear_system_fancy.jl +++ b/test/linear_system_fancy.jl @@ -67,7 +67,7 @@ destroy!(x) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: - M = create_matrix(; nrows_glo = 3, ncols_glo = 3, auto_setup = true) + M = create_matrix(; nrows_glo = 3, ncols_glo = 3, autosetup = true) M_start, M_end = get_range(M) I = [1, 1, 1, 2, 3] J = [1, 3, 1, 3, 2] diff --git a/test/misc.jl b/test/misc.jl index 2385d7d..e2ea999 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -2,8 +2,8 @@ PetscInitialize() # Create two matrices - A = create_matrix(; nrows_glo = 2, ncols_glo = 2, auto_setup = true) - B = create_matrix(; nrows_glo = 2, ncols_glo = 2, auto_setup = true) + A = create_matrix(; nrows_glo = 2, ncols_glo = 2, autosetup = true) + B = create_matrix(; nrows_glo = 2, ncols_glo = 2, autosetup = true) # Fill @@ -31,9 +31,9 @@ C = create_composite_add([A, B]) # Create vectors to check C (see below) - x1 = create_vector(; nrows_glo = 2, auto_setup = true) - x2 = create_vector(; nrows_glo = 2, auto_setup = true) - y = create_vector(; nrows_glo = 2, auto_setup = true) + x1 = create_vector(; nrows_glo = 2, autosetup = true) + x2 = create_vector(; nrows_glo = 2, autosetup = true) + y = create_vector(; nrows_glo = 2, autosetup = true) x1[1] = 1.0 x1[2] = 0.0 x2[1] = 0.0 @@ -53,12 +53,11 @@ end @testset "mapping" begin - PetscInitialize() n = 10 - x = create_vector(; nrows_glo = n, auto_setup = true) - y = create_vector(; nrows_glo = n, auto_setup = true) + x = create_vector(; nrows_glo = n, autosetup = true) + y = create_vector(; nrows_glo = n, autosetup = true) l2g = reverse(collect(1:n)) set_local_to_global!(x, l2g) @@ -66,17 +65,17 @@ end set_value!(y, 1, 33) set_value!(y, 10, 22) - assemble!.((x,y)) + assemble!.((x, y)) # @show dot(x,y) - @test dot(x,x) == 1. - @test dot(x,y) == 22. - @test sum(x) == 1. + @test dot(x, x) == 1.0 + @test dot(x, y) == 22.0 + @test sum(x) == 1.0 _x = vec2array(x) - @test _x[end] == 1. + @test _x[end] == 1.0 - destroy!.((x,y)) + destroy!.((x, y)) PetscFinalize() end \ No newline at end of file From 33c75fd8cb8749315ca51ec509a4bdde43fdfd84 Mon Sep 17 00:00:00 2001 From: bmxam Date: Tue, 28 Mar 2023 22:04:56 +0200 Subject: [PATCH 20/40] fix create_ksp --- src/fancy/ksp.jl | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/fancy/ksp.jl b/src/fancy/ksp.jl index 6d4a0cd..ddb7ad3 100644 --- a/src/fancy/ksp.jl +++ b/src/fancy/ksp.jl @@ -1,10 +1,4 @@ -function create_ksp(A::Mat; autosetup = false) - ksp = create(KSP) - setOperators(ksp, A, A; autosetup) - return ksp -end - -function create_ksp(Amat::Mat, Pmat::Mat; autosetup = false) +function create_ksp(Amat::Mat, Pmat::Mat; autosetup=false) ksp = create(KSP) setOperators(ksp, Amat, Pmat) @@ -15,6 +9,8 @@ function create_ksp(Amat::Mat, Pmat::Mat; autosetup = false) return ksp end +create_ksp(A::Mat; autosetup=false) = create_ksp(A, A; autosetup) + set_operators!(ksp::KSP, Amat::Mat) = setOperators(ksp, Amat, Amat) set_operators!(ksp::KSP, Amat::Mat, Pmat::Mat) = setOperators(ksp, Amat, Pmat) From f5244a651cfb504a6647d07d1c2074cd743653fa Mon Sep 17 00:00:00 2001 From: bmxam Date: Fri, 14 Apr 2023 13:56:27 +0200 Subject: [PATCH 21/40] finalize mpi on demand --- Project.toml | 2 +- example/linear_system.jl | 2 +- example/linear_system_fancy.jl | 2 +- src/init.jl | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Project.toml b/Project.toml index 49fa145..d8a87ca 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "PetscWrap" uuid = "5be22e1c-01b5-4697-96eb-ef9ccdc854b8" authors = ["bmxam "] -version = "0.1.5" +version = "0.2.0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/example/linear_system.jl b/example/linear_system.jl index 6ae178f..0097977 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -94,6 +94,6 @@ destroy(b) destroy(x) # Finalize Petsc -PetscFinalize() +PetscFinalize(true) end #hide \ No newline at end of file diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index a07655f..2af0feb 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -93,6 +93,6 @@ destroy!(M) # at the last moment if you'd like to use `SparseArrays` or `PetscMat`. # Finalize Petsc -PetscFinalize() +PetscFinalize(true) end #hide \ No newline at end of file diff --git a/src/init.jl b/src/init.jl index fb4264c..34abe6f 100644 --- a/src/init.jl +++ b/src/init.jl @@ -55,9 +55,11 @@ end """ Wrapper to PetscFinalize """ -function PetscFinalize() +function PetscFinalize(finalizeMPI = false) error = ccall((:PetscFinalize, libpetsc), PetscErrorCode, ()) @assert iszero(error) + + finalizeMPI && MPI.Finalize() end """ From 49ef44065760ae1fc3823e59af6277892197ba9a Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 16 Apr 2023 20:27:17 +0200 Subject: [PATCH 22/40] rename view (conflict with Base) --- README.md | 87 ++++++++++++++++++++-------------------- example/linear_system.jl | 6 +-- src/Mat.jl | 4 +- src/PetscViewer.jl | 4 +- src/PetscWrap.jl | 7 ++-- src/Vec.jl | 4 +- src/fancy/mat.jl | 4 +- src/fancy/vec.jl | 4 +- test/linear_system.jl | 6 +-- 9 files changed, 64 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index db2e1dd..b82ae2f 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Any contribution(s) and/or remark(s) are welcome! If you need a function that is Conventions to be applied in future versions ("fancy" stuff is not concerned): - all PETSc types should have the exact same name in Julia; -- all PETSc functions should have the exact same name in julia, but without the type as a prefix, and with a lower case for the first letter. `VecSetValues` becomes `setValues`; +- all PETSc functions should have the exact same name in julia, but without the type as a prefix, and with a lower case for the first letter. `VecSetValues` becomes `setValues`. This rule is not applied when the name conflicts with a name from `Base` (for instance `VecView` becomes `vecView` and not `view`); - all PETSc functions must have the same number of arguments and, if possible the same names in julia, except for out-of-place arguments. - functions arguments must all be typed. Additional functions, without type or with fewer args, can be defined if the original version is present. @@ -48,8 +48,9 @@ PETSc methods wrappers share the almost same name as their C equivalent (with th You will find examples of use by building the documentation: `julia PetscWrap.jl/docs/make.jl`. Here is one of the examples: ### A first demo + This example serves as a test since this project doesn't have a "testing" procedure yet. In this example, -the equation ``u'(x) = 2`` with ``u(0) = 0`` is solved on the domain ``[0,1]`` using a backward finite +the equation `u'(x) = 2` with `u(0) = 0` is solved on the domain `[0,1]` using a backward finite difference scheme. In this example, PETSc classic method names are used. For more fancy names, check the fancy version. @@ -61,143 +62,143 @@ To run this example, execute : `mpirun -n your_favorite_positive_integer julia e Import package -````julia +```julia using PetscWrap -```` +``` Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can also provide "command line arguments by defining them in a string, for instance `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` -````julia +```julia PetscInitialize() -```` +``` Number of mesh points and mesh step -````julia +```julia n = 11 Δx = 1.0 / (n - 1) -```` +``` Create a matrix and a vector (you can specify the MPI communicator if you want) -````julia +```julia A = create(Mat) b = create(Vec) -```` +``` Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should set the number of preallocated non-zeros to increase performance. -````julia +```julia setSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) setSizes(b, PETSC_DECIDE, n) -```` +``` We can then use command-line options to set our matrix/vectors. -````julia +```julia setFromOptions(A) setFromOptions(b) -```` +``` Finish the set up -````julia +```julia setUp(A) setUp(b) -```` +``` Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout the fancy version of this example for a more Julia-like convention. -````julia +```julia b_start, b_end = getOwnershipRange(b) -```` +``` Now let's build the right hand side vector. Their are various ways to do this, this is just one. -````julia +```julia n_loc = getLocalSize(b) # Note that n_loc = b_end - b_start... setValues(b, collect(b_start:(b_end - 1)), 2 * ones(n_loc)) -```` +``` And here is the differentiation matrix. Rembember that PETSc.MatSetValues simply ignores negatives rows indices. -````julia +```julia A_start, A_end = getOwnershipRange(A) for i = A_start:(A_end - 1) setValues(A, [i], [i - 1, i], [-1.0 1.0] / Δx, INSERT_VALUES) # setValues(A, I, J, V, INSERT_VALUES) end -```` +``` Set boundary condition (only the proc handling index `0` is acting) -````julia +```julia (b_start == 0) && setValue(b, 0, 0.0) -```` +``` Assemble matrices -````julia +```julia assemblyBegin(A, MAT_FINAL_ASSEMBLY) assemblyBegin(b) assemblyEnd(A, MAT_FINAL_ASSEMBLY) assemblyEnd(b) -```` +``` At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call -````julia -PetscWrap.view(A) -PetscWrap.view(b) -```` +```julia +matView(A) +vecView(b) +``` Set up the linear solver -````julia +```julia ksp = create(KSP) setOperators(ksp, A, A) setFromOptions(ksp) setUp(ksp) -```` +``` Solve the system. We first allocate the solution using the `VecDuplicate` method. -````julia +```julia x = duplicate(b) solve(ksp, b, x) -```` +``` Print the solution -````julia -PetscWrap.view(x) -```` +```julia +vecView(x) +``` Access the solution (this part is under development), getting a Julia array; and then restore it -````julia +```julia array, ref = getArray(x) # do something with array @show array restoreArray(x, ref) -```` +``` Free memory -````julia +```julia destroy(A) destroy(b) destroy(x) -```` +``` Finalize Petsc -````julia +```julia PetscFinalize() -```` \ No newline at end of file +``` diff --git a/example/linear_system.jl b/example/linear_system.jl index 0097977..1f9eda0 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -67,8 +67,8 @@ assemblyEnd(A, MAT_FINAL_ASSEMBLY) assemblyEnd(b) # At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call -PetscWrap.view(A) -PetscWrap.view(b) +matView(A) +vecView(b) # Set up the linear solver ksp = create(KSP) @@ -81,7 +81,7 @@ x = duplicate(b) solve(ksp, b, x) # Print the solution -PetscWrap.view(x) +vecView(x) # Access the solution (this part is under development), getting a Julia array; and then restore it array, ref = getArray(x) # do something with array diff --git a/src/Mat.jl b/src/Mat.jl index 1289c5e..d94c01a 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -655,12 +655,12 @@ function setValues(mat::Mat, I, J, V, mode::InsertMode) end """ - view(mat::Mat, viewer::PetscViewer = StdWorld()) + matView(mat::Mat, viewer::PetscViewer = StdWorld()) Wrapper to `MatView` https://petsc.org/release/docs/manualpages/Mat/MatView/ """ -function view(mat::Mat, viewer::PetscViewer = StdWorld(mat.comm)) +function matView(mat::Mat, viewer::PetscViewer = StdWorld(mat.comm)) error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) @assert iszero(error) end diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index 4c14236..c75c637 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -187,11 +187,11 @@ function setType(viewer::PetscViewer, type::String) end """ - view(v::PetscViewer, viewer::PetscViewer) + viewerView(v::PetscViewer, viewer::PetscViewer) Wrapper to `PetscViewerView` """ -function view(v::PetscViewer, viewer::PetscViewer) +function viewerView(v::PetscViewer, viewer::PetscViewer) error = ccall((:PetscViewerView, libpetsc), PetscErrorCode, (CViewer, CViewer), v, viewer) @assert iszero(error) diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 4c695c7..a7fd0fe 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -43,7 +43,7 @@ export PetscViewer, pushFormat, setType, stdWorld, - view + viewerView include("ISLocalToGlobalMapping.jl") include("Vec.jl") @@ -67,7 +67,7 @@ export Vec, setValueLocal, setValues, setValuesLocal, - view + vecView include("Mat.jl") export Mat, @@ -80,7 +80,8 @@ export Mat, MPIAIJSetPreallocation, mult, multAdd, - SeqAIJSetPreallocation + SeqAIJSetPreallocation, + matView include("KSP.jl") export KSP, CKSP, setOperators, solve diff --git a/src/Vec.jl b/src/Vec.jl index a3d06d3..86741d2 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -490,12 +490,12 @@ function Base.sum(x::Vec) end """ - view(vec::Vec, viewer::PetscViewer = StdWorld()) + vecView(vec::Vec, viewer::PetscViewer = StdWorld()) Wrapper to `VecView` https://petsc.org/release/docs/manualpages/Vec/VecView/ """ -function view(vec::Vec, viewer::PetscViewer = StdWorld(vec.comm)) +function vecView(vec::Vec, viewer::PetscViewer = StdWorld(vec.comm)) error = ccall((:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer) @assert iszero(error) end diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 4d952e5..88f5a73 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -206,8 +206,8 @@ function mat2file( type::String = "ascii", ) viewer = PetscViewer(mat.comm, filename, format, type) - view(mat, viewer) + matView(mat, viewer) destroy!(viewer) end -Base.show(::IO, mat::Mat) = view(mat) +Base.show(::IO, mat::Mat) = matView(mat) diff --git a/src/fancy/vec.jl b/src/fancy/vec.jl index a0f35a6..54f2989 100644 --- a/src/fancy/vec.jl +++ b/src/fancy/vec.jl @@ -148,7 +148,7 @@ function set_values_local!(vec::Vec, values) setValuesLocal(vec, collect(1:getLocalSize(vec)) .- 1, values, INSERT_VALUES) end -Base.show(::IO, vec::Vec) = view(vec) +Base.show(::IO, vec::Vec) = vecView(vec) """ vec2array(vec::Vec) @@ -176,7 +176,7 @@ function vec2file( type::String = "ascii", ) viewer = PetscViewer(vec.comm, filename, format, type) - view(vec, viewer) + vecView(vec, viewer) destroy!(viewer) end diff --git a/test/linear_system.jl b/test/linear_system.jl index dc6c85f..f832d16 100644 --- a/test/linear_system.jl +++ b/test/linear_system.jl @@ -57,8 +57,8 @@ assemblyEnd(b) # At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call - PetscWrap.view(A) - PetscWrap.view(b) + matView(A) + vecView(b) # Set up the linear solver ksp = create(KSP) @@ -71,7 +71,7 @@ solve(ksp, b, x) # Print the solution - PetscWrap.view(x) + vecView(x) # Access the solution (this part is under development), getting a Julia array; and then restore it array, ref = getArray(x) # do something with array From f90b71a21dc22fadecb27d09258bb13ece6afd9d Mon Sep 17 00:00:00 2001 From: bmxam Date: Sun, 16 Apr 2023 20:55:02 +0200 Subject: [PATCH 23/40] fix for preallocate --- README.md | 2 +- src/Mat.jl | 2 +- src/fancy/mat.jl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b82ae2f..d0addfe 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Conventions to be applied in future versions ("fancy" stuff is not concerned): ## PETSc compat. -This version of PetscWrap.jl has been tested with petsc-3.13. Complex numbers are supported. +This version of PetscWrap.jl has been tested with petsc-3.19. Complex numbers are supported. ## How to use it diff --git a/src/Mat.jl b/src/Mat.jl index d94c01a..c518029 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -297,7 +297,7 @@ end MPIAIJSetPreallocation(mat::Mat, dnz::PetscInt, onz::PetscInt) Wrapper to `MatMPIAIJSetPreallocation` -https://petsc.org/release/docs/manualpages/Mat/MatMPIAIJSetPreallocation/ +https://petsc.org/release//manualpages/Mat/MatMPIAIJSetPreallocation/ # Warning diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index 88f5a73..ae4038a 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -190,7 +190,7 @@ end Dispatch preallocation according matrix type (seq or mpiaij for instance). TODO: should use kwargs. """ function preallocate!(mat::Mat, dnz, onz, warn::Bool = true) - _preallocate!(mat, dnz, onz, Val(Symbol(MatGetType(mat)))) + _preallocate!(mat, dnz, onz, Val(Symbol(getType(mat)))) setOption(mat, MAT_NEW_NONZERO_ALLOCATION_ERR, warn) end From 9da3433dedabfda8d49f8afa3725492b285ed4a7 Mon Sep 17 00:00:00 2001 From: bmxam Date: Mon, 17 Apr 2023 22:25:09 +0200 Subject: [PATCH 24/40] PETSC_DETERMINE --- src/const_arch_ind.jl | 1 + src/fancy/mat.jl | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index 2124a56..dbdbb0f 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -5,6 +5,7 @@ const PetscErrorCode = Cint const PETSC_DEFAULT = -2 const PETSC_DECIDE = -1 +const PETSC_DETERMINE = PETSC_DECIDE """ Macro to automatically export all items of an enum diff --git a/src/fancy/mat.jl b/src/fancy/mat.jl index ae4038a..3e2af46 100644 --- a/src/fancy/mat.jl +++ b/src/fancy/mat.jl @@ -35,8 +35,8 @@ function create_matrix( comm::MPI.Comm = MPI.COMM_WORLD; nrows_loc = PETSC_DECIDE, ncols_loc = PETSC_DECIDE, - nrows_glo = PETSC_DECIDE, - ncols_glo = PETSC_DECIDE, + nrows_glo = PETSC_DETERMINE, + ncols_glo = PETSC_DETERMINE, autosetup = false, ) mat = create(Mat, comm) From 0a38dad678490803ab5dfd568c1cd720c9c07aac Mon Sep 17 00:00:00 2001 From: bmxam Date: Tue, 18 Apr 2023 21:03:10 +0200 Subject: [PATCH 25/40] fix doc url --- src/ISLocalToGlobalMapping.jl | 4 +- src/KSP.jl | 12 +++--- src/Mat.jl | 52 ++++++++++++------------- src/PetscViewer.jl | 20 +++++----- src/Vec.jl | 71 ++++++++++++++++------------------- 5 files changed, 77 insertions(+), 82 deletions(-) diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index fb05e41..54c1d6c 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -27,7 +27,7 @@ Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2 ) where {I<:Integer} Wrapper to `ISLocalToGlobalMappingCreate` -https://petsc.org/release/docs/manualpages/IS/ISLocalToGlobalMappingCreate/ +https://petsc.org/release/manualpages/IS/ISLocalToGlobalMappingCreate/ 0-based indexing """ @@ -82,7 +82,7 @@ end destroy(mapping::ISLocalToGlobalMapping) Wrapper to `ISLocalToGlobalMappingDestroy` -https://petsc.org/release/docs/manualpages/IS/ISLocalToGlobalMappingDestroy/ +https://petsc.org/release/manualpages/IS/ISLocalToGlobalMappingDestroy/ """ function destroy(mapping::ISLocalToGlobalMapping) error = ccall( diff --git a/src/KSP.jl b/src/KSP.jl index 5a8e453..0fa2e83 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -14,7 +14,7 @@ Base.cconvert(::Type{CKSP}, ksp::KSP) = ksp.ptr[] create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) Wrapper for `KSPCreate` -https://petsc.org/release/docs/manualpages/KSP/KSPCreate/ +https://petsc.org/release/manualpages/KSP/KSPCreate/ """ function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) ksp = KSP(comm) @@ -33,7 +33,7 @@ end destroy(ksp::KSP) Wrapper to `KSPDestroy` -https://petsc.org/release/docs/manualpages/KSP/KSPDestroy/ +https://petsc.org/release/manualpages/KSP/KSPDestroy/ """ function destroy(ksp::KSP) error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp.ptr) @@ -44,7 +44,7 @@ end setFromOptions(ksp::KSP) Wrapper to `KSPSetFromOptions` -https://petsc.org/release/docs/manualpages/KSP/KSPSetFromOptions/ +https://petsc.org/release/manualpages/KSP/KSPSetFromOptions/ """ function setFromOptions(ksp::KSP) error = ccall((:KSPSetFromOptions, libpetsc), PetscErrorCode, (CKSP,), ksp) @@ -55,7 +55,7 @@ end setOperators(ksp::KSP, Amat::Mat, Pmat::Mat) Wrapper for `KSPSetOperators`` -https://petsc.org/release/docs/manualpages/KSP/KSPSetOperators/ +https://petsc.org/release/manualpages/KSP/KSPSetOperators/ """ function setOperators(ksp::KSP, Amat::Mat, Pmat::Mat) error = ccall( @@ -73,7 +73,7 @@ end KSPSetUp(ksp::KSP) Wrapper to `KSPSetUp` -https://petsc.org/release/docs/manualpages/KSP/KSPSetUp/ +https://petsc.org/release/manualpages/KSP/KSPSetUp/ """ function setUp(ksp::KSP) error = ccall((:KSPSetUp, libpetsc), PetscErrorCode, (CKSP,), ksp) @@ -84,7 +84,7 @@ end solve(ksp::KSP, b::Vec, x::Vec) Wrapper for `KSPSolve` -https://petsc.org/release/docs/manualpages/KSP/KSPSolve/ +https://petsc.org/release/manualpages/KSP/KSPSolve/ """ function solve(ksp::KSP, b::Vec, x::Vec) error = ccall((:KSPSolve, libpetsc), PetscErrorCode, (CKSP, CVec, CVec), ksp, b, x) diff --git a/src/Mat.jl b/src/Mat.jl index c518029..7e51b23 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -17,7 +17,7 @@ Base.cconvert(::Type{CMat}, mat::Mat) = mat.ptr[] assemblyBegin(mat::Mat, type::MatAssemblyType) Wrapper to `MatAssemblyBegin` -https://petsc.org/release/docs/manualpages/Mat/MatAssemblyBegin/ +https://petsc.org/release/manualpages/Mat/MatAssemblyBegin/ """ function assemblyBegin(mat::Mat, type::MatAssemblyType) error = ccall( @@ -34,7 +34,7 @@ end assemblyEnd(mat::Mat, type::MatAssemblyType) Wrapper to `MatAssemblyEnd` -https://petsc.org/release/docs/manualpages/Mat/MatAssemblyEnd/ +https://petsc.org/release/manualpages/Mat/MatAssemblyEnd/ """ function assemblyEnd(mat::Mat, type::MatAssemblyType) error = ccall( @@ -51,7 +51,7 @@ end compositeAddMat(mat::Mat, smat::Mat) Wrapper to `MatCompositeAddMat` -https://petsc.org/release/docs/manualpages/Mat/MatCompositeAddMat/ +https://petsc.org/release/manualpages/Mat/MatCompositeAddMat/ """ function compositeAddMat(mat::Mat, smat::Mat) error = ccall((:MatCompositeAddMat, libpetsc), PetscErrorCode, (CMat, CMat), mat, smat) @@ -63,7 +63,7 @@ end create(::Type{Mat}) Wrapper to `MatCreate` -https://petsc.org/release/docs/manualpages/Mat/MatCreate/ +https://petsc.org/release/manualpages/Mat/MatCreate/ """ function create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD) mat = Mat(comm) @@ -89,7 +89,7 @@ end ) Wrapper to `MatCreateDense` -https://petsc.org/release/docs/manualpages/Mat/MatCreateDense/ +https://petsc.org/release/manualpages/Mat/MatCreateDense/ Last argument `data` is not supported yet (NULL is passed). """ @@ -126,7 +126,7 @@ end createVecs(mat::Mat) Wrapper to `MatCreateVecs` -https://petsc.org/release/docs/manualpages/Mat/MatCreateVecs/ +https://petsc.org/release/manualpages/Mat/MatCreateVecs/ """ function createVecs(mat::Mat, right::Vec, left::Vec) error = ccall( @@ -151,7 +151,7 @@ end destroy(A::Mat) Wrapper to `MatDestroy` -https://petsc.org/release/docs/manualpages/Mat/MatDestroy/ +https://petsc.org/release/manualpages/Mat/MatDestroy/ """ function destroy(A::Mat) error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), A.ptr) @@ -162,7 +162,7 @@ end getLocalSize(mat::Mat) Wrapper to `MatGetLocalSize` -https://petsc.org/release/docs/manualpages/Mat/MatGetLocalSize/ +https://petsc.org/release/manualpages/Mat/MatGetLocalSize/ Return the number of local rows and cols of the matrix (i.e on the processor). """ @@ -187,7 +187,7 @@ end getOwnershipRange(mat::Mat) Wrapper to `MatGetOwnershipRange` -https://petsc.org/release/docs/manualpages/Mat/MatGetOwnershipRange/ +https://petsc.org/release/manualpages/Mat/MatGetOwnershipRange/ The result `(rstart, rend)` is a Tuple indicating the rows handled by the local processor. @@ -217,7 +217,7 @@ end getOwnershipRangeColumn(mat::Mat) Wrapper to `MatGetOwnershipRangeColumn` -https://petsc.org/release/docs/manualpages/Mat/MatGetOwnershipRangeColumn/ +https://petsc.org/release/manualpages/Mat/MatGetOwnershipRangeColumn/ The result `(cstart, cend)` is a Tuple indicating the columns handled by the local processor. @@ -247,7 +247,7 @@ end getSize(mat::Mat) Wrapper to `MatGetSize` -https://petsc.org/release/docs/manualpages/Mat/MatGetSize/ +https://petsc.org/release/manualpages/Mat/MatGetSize/ Return the number of rows and cols of the matrix (global number). """ @@ -272,10 +272,10 @@ end getType(mat::Mat) Wrapper to `MatGetType` -https://petsc.org/release/docs/manualpages/Mat/MatType/ +https://petsc.org/release/manualpages/Mat/MatType/ Return the matrix type as a string. See matrix types here: -https://petsc.org/release/docs/manualpages/Mat/MatType.html +https://petsc.org/release/manualpages/Mat/MatType.html """ function getType(mat::Mat) type = Ref{Cstring}() @@ -353,7 +353,7 @@ end mult(mat::Mat, x::Vec, y::Vec) Wrapper to `MatMult` -https://petsc.org/release/docs/manualpages/Mat/MatMult/ +https://petsc.org/release/manualpages/Mat/MatMult/ Compute `y = Ax` """ @@ -366,7 +366,7 @@ end multAdd(A::Mat, v1::Vec, v2::Vec, v3::Vec) Wrapper to `MatMultAdd` -https://petsc.org/release/docs/manualpages/Mat/MatMultAdd/ +https://petsc.org/release/manualpages/Mat/MatMultAdd/ Compute `v3 = v2 + A * v1`. """ @@ -388,7 +388,7 @@ end SeqAIJSetPreallocation(mat::Mat, nz::PetscInt) Wrapper to `MatSeqAIJSetPreallocation` -https://petsc.org/release/docs/manualpages/Mat/MatSeqAIJSetPreallocation/ +https://petsc.org/release/manualpages/Mat/MatSeqAIJSetPreallocation/ """ function SeqAIJSetPreallocation(mat::Mat, nz::PetscInt, nnz::Vector{PetscInt}) error = ccall( @@ -418,7 +418,7 @@ end setFromOptions(mat::Mat) Wrapper to `MatSetFromOptions` -https://petsc.org/release/docs/manualpages/Mat/MatSetFromOptions/ +https://petsc.org/release/manualpages/Mat/MatSetFromOptions/ """ function setFromOptions(mat::Mat) error = ccall((:MatSetFromOptions, libpetsc), PetscErrorCode, (CMat,), mat) @@ -433,7 +433,7 @@ end ) Wrapper to `MatSetLocalToGlobalMapping` -https://petsc.org/release/docs/manualpages/Mat/MatSetLocalToGlobalMapping/ +https://petsc.org/release/manualpages/Mat/MatSetLocalToGlobalMapping/ """ function setLocalToGlobalMapping( x::Mat, @@ -455,7 +455,7 @@ end setOption(mat::Mat, op::MatOption, flg::PetscBool) Wrapper for `MatSetOption` -https://petsc.org/release/docs/manualpages/Mat/MatSetOption/ +https://petsc.org/release/manualpages/Mat/MatSetOption/ """ function setOption(mat::Mat, op::MatOption, flg::PetscBool) error = ccall( @@ -482,7 +482,7 @@ setOption(mat::Mat, op::MatOption, flg::Bool) = setOption(mat, op, bool2petsc(fl ) Wrapper to `MatSetSizes` -https://petsc.org/release/docs/manualpages/Mat/MatSetSizes/ +https://petsc.org/release/manualpages/Mat/MatSetSizes/ """ function setSizes(mat::Mat, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) error = ccall( @@ -518,10 +518,10 @@ end setType(mat::Mat, type::String) Wrapper for `MatSetType` -https://petsc.org/release/docs/manualpages/Mat/MatSetType/ +https://petsc.org/release/manualpages/Mat/MatSetType/ Values for `type` alors available here: -https://petsc.org/release/docs/manualpages/Mat/MatType.html#MatType +https://petsc.org/release/manualpages/Mat/MatType.html#MatType """ function setType(mat::Mat, type::String) error = ccall((:MatSetType, libpetsc), PetscErrorCode, (CMat, Cstring), mat, type) @@ -532,7 +532,7 @@ end setUp(mat::Mat) Wrapper to `MatSetUp` -https://petsc.org/release/docs/manualpages/Mat/MatSetUp/ +https://petsc.org/release/manualpages/Mat/MatSetUp/ """ function setUp(mat::Mat) error = ccall((:MatSetUp, libpetsc), PetscErrorCode, (CMat,), mat) @@ -555,7 +555,7 @@ const _vvec = zeros(PetscScalar, 1) setValue(m::Mat, row::Integer, col::Integer, value::Number, mode::InsertMode) Wrapper to `MatSetValue` -https://petsc.org/release/docs/manualpages/Mat/MatSetValue/ +https://petsc.org/release/manualpages/Mat/MatSetValue/ Indexing starts at 0 (as in PETSc). @@ -604,7 +604,7 @@ end setValues(mat::Mat, I, J, V, mode::InsertMode) Wrapper to `MatSetValues` -https://petsc.org/release/docs/manualpages/Mat/MatSetValues/ +https://petsc.org/release/manualpages/Mat/MatSetValues/ Indexing starts at 0 (as in PETSc) """ @@ -658,7 +658,7 @@ end matView(mat::Mat, viewer::PetscViewer = StdWorld()) Wrapper to `MatView` -https://petsc.org/release/docs/manualpages/Mat/MatView/ +https://petsc.org/release/manualpages/Mat/MatView/ """ function matView(mat::Mat, viewer::PetscViewer = StdWorld(mat.comm)) error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index c75c637..430828a 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -13,7 +13,7 @@ Base.cconvert(::Type{CViewer}, viewer::PetscViewer) = viewer.ptr[] ASCIIGetStdout(comm::MPI.Comm) Wrapper for `PetscViewerASCIIGetStdout` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerASCIIGetStdout/ +https://petsc.org/release/manualpages/Viewer/PetscViewerASCIIGetStdout/ """ function ASCIIGetStdout(comm::MPI.Comm = MPI.COMM_WORLD) viewer = PetscViewer(comm) @@ -34,7 +34,7 @@ const StdWorld = ASCIIGetStdout ASCIIOpen(comm::MPI.Comm, name) Wrapper for `PetscViewerASCIIOpen` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerASCIIOpen/ +https://petsc.org/release/manualpages/Viewer/PetscViewerASCIIOpen/ """ function ASCIIOpen(comm::MPI.Comm, name::String) viewer = PetscViewer(comm) @@ -54,7 +54,7 @@ end create(::Type{PetscViewer}, comm::MPI.Comm = MPI.COMM_WORLD) Wrapper for `PetscViewerCreate` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerCreate/ +https://petsc.org/release/manualpages/Viewer/PetscViewerCreate/ """ function create(::Type{PetscViewer}, comm::MPI.Comm = MPI.COMM_WORLD) viewer = PetscViewer(comm) @@ -73,7 +73,7 @@ end destroy(viewer::PetscViewer) Wrapper for `PetscViewerDestroy` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerDestroy/ +https://petsc.org/release/manualpages/Viewer/PetscViewerDestroy/ Warning : from what I understand, all viewers must not be destroyed explicitely using `PetscViewerDestroy`. """ @@ -87,7 +87,7 @@ end fileSetMode(viewer::PetscViewer, mode::PetscFileMode) Wrapper for `PetscViewerFileSetMode` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerFileSetMode/ +https://petsc.org/release/manualpages/Viewer/PetscViewerFileSetMode/ """ function fileSetMode(viewer::PetscViewer, mode::PetscFileMode) error = ccall( @@ -104,7 +104,7 @@ end fileSetName(viewer::PetscViewer, name::String) Wrapper for `PetscViewerFileSetName` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerFileSetName/ +https://petsc.org/release/manualpages/Viewer/PetscViewerFileSetName/ """ function fileSetName(viewer::PetscViewer, name::String) error = ccall( @@ -121,7 +121,7 @@ end HDF5Open(comm::MPI.Comm, name::String, type::PetscFileMode) Wrapper for `PetscViewerHDF5Open` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerHDF5Open/ +https://petsc.org/release/manualpages/Viewer/PetscViewerHDF5Open/ """ function HDF5Open(comm::MPI.Comm, name::String, type::PetscFileMode) viewer = PetscViewer(comm) @@ -142,7 +142,7 @@ end popFormat(viewer::PetscViewer) Wrapper for `PetscViewerPopFormat` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPopFormat/ +https://petsc.org/release/manualpages/Viewer/PetscViewerPopFormat/ """ function popFormat(viewer::PetscViewer) error = ccall((:PetscViewerPopFormat, libpetsc), PetscErrorCode, (CViewer,), viewer) @@ -153,7 +153,7 @@ end pushFormat(viewer::PetscViewer, format::PetscViewerFormat) Wrapper for `PetscViewerPushFormat` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerPushFormat/ +https://petsc.org/release/manualpages/Viewer/PetscViewerPushFormat/ """ function pushFormat(viewer::PetscViewer, format::PetscViewerFormat) error = ccall( @@ -170,7 +170,7 @@ end setType(viewer::PetscViewer, type::String) Wrapper for `PetscViewerSetType` -https://petsc.org/release/docs/manualpages/Viewer/PetscViewerSetType/ +https://petsc.org/release/manualpages/Viewer/PetscViewerSetType/ Values for `type` alors available here: https://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Viewer/PetscViewerType.html#PetscViewerType diff --git a/src/Vec.jl b/src/Vec.jl index 86741d2..bf6b1cb 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -14,7 +14,7 @@ Base.cconvert(::Type{CVec}, vec::Vec) = vec.ptr[] assemblyBegin(vec::Vec) Wrapper to `VecAssemblyBegin` -https://petsc.org/release/docs/manualpages/Vec/VecAssemblyBegin/ +https://petsc.org/release/manualpages/Vec/VecAssemblyBegin/ """ function assemblyBegin(vec::Vec) error = ccall((:VecAssemblyBegin, libpetsc), PetscErrorCode, (CVec,), vec) @@ -25,7 +25,7 @@ end assemblyEnd(vec::Vec) Wrapper to `VecAssemblyEnd` -https://petsc.org/release/docs/manualpages/Vec/VecAssemblyEnd/ +https://petsc.org/release/manualpages/Vec/VecAssemblyEnd/ """ function assemblyEnd(vec::Vec) error = ccall((:VecAssemblyEnd, libpetsc), PetscErrorCode, (CVec,), vec) @@ -37,7 +37,7 @@ end copy(x::Vec) Wrapper to `VecCopy` -https://petsc.org/release/docs/manualpages/Vec/VecCopy/ +https://petsc.org/release/manualpages/Vec/VecCopy/ Not really sure if I should extend Base here... """ @@ -56,7 +56,7 @@ end create(::Type{Vec},comm::MPI.Comm = MPI.COMM_WORLD) Wrapper to `VecCreate` -https://petsc.org/release/docs/manualpages/Vec/VecCreate/ +https://petsc.org/release/manualpages/Vec/VecCreate/ """ function create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD) vec = Vec(comm) @@ -75,7 +75,7 @@ end destroy(v::Vec) Wrapper to `VecDestroy` -https://petsc.org/release/docs/manualpages/Vec/VecDestroy/ +https://petsc.org/release/manualpages/Vec/VecDestroy/ """ function destroy(v::Vec) error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v.ptr) @@ -84,7 +84,14 @@ end function LinearAlgebra.dot(x::Vec, y::Vec) val = Ref{PetscScalar}() - error = ccall((:VecDot, libpetsc), PetscErrorCode, (CVec, CVec, Ref{PetscScalar}), x, y, val) + error = ccall( + (:VecDot, libpetsc), + PetscErrorCode, + (CVec, CVec, Ref{PetscScalar}), + x, + y, + val, + ) @assert iszero(error) return val[] @@ -94,7 +101,7 @@ end duplicate(v::Vec) Wrapper for `VecDuplicate` -https://petsc.org/release/docs/manualpages/Vec/VecDuplicate/ +https://petsc.org/release/manualpages/Vec/VecDuplicate/ """ function duplicate(v::Vec) newv = Vec(v.comm) @@ -108,7 +115,7 @@ end getArray(x::Vec, own::Bool = false) Wrapper for `VecGetArray` -https://petsc.org/release/docs/manualpages/Vec/VecGetArray/ +https://petsc.org/release/manualpages/Vec/VecGetArray/ # Warning @@ -143,7 +150,7 @@ end getLocalSize(vec::Vec) Wrapper for `VecGetLocalSize` -https://petsc.org/release/docs/manualpages/Vec/VecGetLocalSize/ +https://petsc.org/release/manualpages/Vec/VecGetLocalSize/ """ function getLocalSize(x::Vec) n = Ref{PetscInt}() @@ -158,7 +165,7 @@ end getOwnershipRange(x::Vec) Wrapper to `VecGetOwnershipRange` -https://petsc.org/release/docs/manualpages/Vec/VecGetOwnershipRange/ +https://petsc.org/release/manualpages/Vec/VecGetOwnershipRange/ The result `(rstart, rend)` is a Tuple indicating the rows handled by the local processor. @@ -188,7 +195,7 @@ end getSize(x::Vec) Wrapper for `VecGetSize` -https://petsc.org/release/docs/manualpages/Vec/VecGetSize/ +https://petsc.org/release/manualpages/Vec/VecGetSize/ """ function getSize(x::Vec) n = Ref{PetscInt}() @@ -205,7 +212,7 @@ end getValues(x::Vec, ix::Vector{I}) where {I<:Integer} Wrapper for `VecGetValues` -https://petsc.org/release/docs/manualpages/Vec/VecGetValues/ +https://petsc.org/release/manualpages/Vec/VecGetValues/ """ function getValues(x::Vec, ni::PetscInt, ix::Vector{PetscInt}) y = zeros(PetscScalar, ni) @@ -213,12 +220,7 @@ function getValues(x::Vec, ni::PetscInt, ix::Vector{PetscInt}) error = ccall( (:VecGetValues, libpetsc), PetscErrorCode, - ( - CVec, - PetscInt, - Ptr{PetscInt}, - Ptr{PetscScalar}, - ), + (CVec, PetscInt, Ptr{PetscInt}, Ptr{PetscScalar}), x, ni, ix, @@ -231,15 +233,13 @@ end getValues(x::Vec, ix::Vector{PetscInt}) = getValues(x, PetscInt(length(ix)), ix) -function getValues(x::Vec, ix::Vector{I}) where {I<:Integer} - return getValues(x, PetscInt.(ix)) -end +getValues(x::Vec, ix::Vector{I}) where {I<:Integer} = getValues(x, PetscInt.(ix)) """ restoreArray(x::Vec, array_ref) Wrapper for `VecRestoreArray`. `array_ref` is obtained from `VecGetArray` -https://petsc.org/release/docs/manualpages/Vec/VecRestoreArray/ +https://petsc.org/release/manualpages/Vec/VecRestoreArray/ """ function restoreArray(x::Vec, array_ref) error = ccall( @@ -257,7 +257,7 @@ end scale(x::Vec, alpha::Number) Wrapper for `VecScale` -https://petsc.org/release/docs/manualpages/Vec/VecScale/ +https://petsc.org/release/manualpages/Vec/VecScale/ """ function scale(x::Vec, alpha::PetscScalar) error = ccall((:VecScale, libpetsc), PetscErrorCode, (CVec, PetscScalar), x, alpha) @@ -270,7 +270,7 @@ scale(x::Vec, alpha::Number) = scale(x, PetscScalar(alpha)) setFromOptions(vec::Vec) Wrapper to `VecSetFromOptions` -https://petsc.org/release/docs/manualpages/Vec/VecSetFromOptions/ +https://petsc.org/release/manualpages/Vec/VecSetFromOptions/ """ function setFromOptions(vec::Vec) error = ccall((:VecSetFromOptions, libpetsc), PetscErrorCode, (CVec,), vec) @@ -281,7 +281,7 @@ end setLocalToGlobalMapping(x::Vec, mapping::ISLocalToGlobalMapping) Wrapper to `VecSetLocalToGlobalMapping` -https://petsc.org/release/docs/manualpages/Vec/VecSetLocalToGlobalMapping/ +https://petsc.org/release/manualpages/Vec/VecSetLocalToGlobalMapping/ 0-based indexing """ @@ -301,7 +301,7 @@ end setSizes(v::Vec, n::Integer, N::Integer) Wrapper to `VecSetSizes` -https://petsc.org/release/docs/manualpages/Vec/VecSetSizes/ +https://petsc.org/release/manualpages/Vec/VecSetSizes/ """ function setSizes(v::Vec, n::PetscInt, N::PetscInt) nr_loc = PetscInt(n) @@ -323,7 +323,7 @@ setSizes(v::Vec, n::Integer, N::Integer) = setSizes(v, PetscInt(n), PetscInt(N)) setUp(vec::Vec) Wrapper to `VecSetUp` -https://petsc.org/release/docs/manualpages/Vec/VecSetUp/ +https://petsc.org/release/manualpages/Vec/VecSetUp/ """ function setUp(v::Vec) error = ccall((:VecSetUp, libpetsc), PetscErrorCode, (CVec,), v) @@ -335,7 +335,7 @@ end setValue(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) Wrapper to `setValue`. Indexing starts at 0 (as in PETSc). -https://petsc.org/release/docs/manualpages/Vec/VecSetValue/ +https://petsc.org/release/manualpages/Vec/VecSetValue/ # Implementation @@ -368,7 +368,7 @@ end setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) -https://petsc.org/release/docs/manualpages/Vec/VecSetValues/ +https://petsc.org/release/manualpages/Vec/VecSetValues/ """ function setValues( x::Vec, @@ -408,7 +408,7 @@ end setValueLocal(v::Vec, row, value, mode::InsertMode = INSERT_VALUES) Wrapper to `setValueLocal`. Indexing starts at 0 (as in PETSc). -https://petsc.org/release/docs/manualpages/Vec/VecSetValueLocal/ +https://petsc.org/release/manualpages/Vec/VecSetValueLocal/ # Implementation @@ -441,7 +441,7 @@ end setValues(x::Vec, I, V, mode::InsertMode = INSERT_VALUES) Wrapper to `VecSetValues`. Indexing starts at 0 (as in PETSc) -https://petsc.org/release/docs/manualpages/Vec/VecSetValuesLocal/ +https://petsc.org/release/manualpages/Vec/VecSetValuesLocal/ """ function setValuesLocal( x::Vec, @@ -478,12 +478,7 @@ end function Base.sum(x::Vec) s = Ref{PetscScalar}() - error = ccall( - (:VecSum, libpetsc), - PetscErrorCode, - (CVec, Ref{PetscScalar}), - x,s, - ) + error = ccall((:VecSum, libpetsc), PetscErrorCode, (CVec, Ref{PetscScalar}), x, s) @assert iszero(error) return s[] @@ -493,7 +488,7 @@ end vecView(vec::Vec, viewer::PetscViewer = StdWorld()) Wrapper to `VecView` -https://petsc.org/release/docs/manualpages/Vec/VecView/ +https://petsc.org/release/manualpages/Vec/VecView/ """ function vecView(vec::Vec, viewer::PetscViewer = StdWorld(vec.comm)) error = ccall((:VecView, libpetsc), PetscErrorCode, (CVec, CViewer), vec, viewer) From d0e982c6159587ee7be9368d733a09edb8cf2167 Mon Sep 17 00:00:00 2001 From: bmxam Date: Tue, 18 Apr 2023 21:37:42 +0200 Subject: [PATCH 26/40] add MatZeroEntries --- src/Mat.jl | 11 +++++++++++ src/PetscWrap.jl | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Mat.jl b/src/Mat.jl index 7e51b23..3be34f3 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -664,3 +664,14 @@ function matView(mat::Mat, viewer::PetscViewer = StdWorld(mat.comm)) error = ccall((:MatView, libpetsc), PetscErrorCode, (CMat, CViewer), mat, viewer) @assert iszero(error) end + +""" + zeroEntries(mat::Mat) + +Wrapper to `MatZeroEntries` +https://petsc.org/release/manualpages/Mat/MatZeroEntries/ +""" +function zeroEntries(mat::Mat) + error = ccall((:MatZeroEntries, libpetsc), PetscErrorCode, (CMat,), mat) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index a7fd0fe..3ec657e 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -81,7 +81,8 @@ export Mat, mult, multAdd, SeqAIJSetPreallocation, - matView + matView, + zeroEntries include("KSP.jl") export KSP, CKSP, setOperators, solve From 3c10f7e3a20850b7630798425de5508b42c1c0ff Mon Sep 17 00:00:00 2001 From: bmxam Date: Tue, 18 Apr 2023 21:57:48 +0200 Subject: [PATCH 27/40] wrapper for MatDuplicate --- src/Mat.jl | 21 +++++++++++++++++++++ src/PetscWrap.jl | 2 ++ src/const_arch_ind.jl | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/src/Mat.jl b/src/Mat.jl index 3be34f3..92e9cbf 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -158,6 +158,27 @@ function destroy(A::Mat) @assert iszero(error) end +""" + duplicate(mat::Mat, op::MatDuplicateOption) + +Wrapper for `MatDuplicate` +https://petsc.org/release/manualpages/Mat/MatDuplicate/ +""" +function duplicate(mat::Mat, op::MatDuplicateOption) + M = Mat(mat.comm) + error = ccall( + (:MatDuplicate, libpetsc), + PetscErrorCode, + (CMat, MatDuplicateOption, Ptr{CMat}), + mat, + op, + M.ptr, + ) + @assert iszero(error) + + return M +end + """ getLocalSize(mat::Mat) diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 3ec657e..2e37d43 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -15,6 +15,8 @@ export PetscErrorCode, PETSC_DECIDE for item in Iterators.flatten(( instances(InsertMode), instances(MatAssemblyType), + instances(MatOption), + instances(MatDuplicateOption), instances(PetscViewerFormat), instances(PetscFileMode), )) diff --git a/src/const_arch_ind.jl b/src/const_arch_ind.jl index dbdbb0f..eab3cad 100644 --- a/src/const_arch_ind.jl +++ b/src/const_arch_ind.jl @@ -117,6 +117,12 @@ end MAT_OPTION_MAX = 25 end +@enum MatDuplicateOption begin + MAT_DO_NOT_COPY_VALUES + MAT_COPY_VALUES + MAT_SHARE_NONZERO_PATTERN +end + @enum PetscViewerFormat begin PETSC_VIEWER_DEFAULT PETSC_VIEWER_ASCII_MATLAB From 0c4ebb324db8dc7dd3e50daa02d84fcb7565b2c5 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Wed, 19 Apr 2023 16:06:26 +0200 Subject: [PATCH 28/40] readme + kspdestroy in example --- Project.toml | 2 +- README.md | 2 ++ example/linear_system.jl | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d8a87ca..9ffa73c 100644 --- a/Project.toml +++ b/Project.toml @@ -10,5 +10,5 @@ MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] -MPI = "0.16, 0.17, 0.18, 0.19, 0.20" +MPI = "0.20" julia = "1.5, 1.6, 1.7, 1.8" diff --git a/README.md b/README.md index d0addfe..15d6f0a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ The main differences with the two aformentionned projects are: Note that the primary objective of this project is to enable the wrapper of the SLEPc library through the [SlepcWrap.jl](https://github.com/bmxam/SlepcWrap.jl) project. +This project is only a wrapper to PETSc functions, the purpose is not to deliver a julia `Array` (it maybe be one day the purpose of a package `PetscArrays.jl`). + ## How to install it You must have installed the PETSc library on your computer and set the two following environment variables : `PETSC_DIR` and `PETSC_ARCH`. diff --git a/example/linear_system.jl b/example/linear_system.jl index 1f9eda0..8667915 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -89,6 +89,7 @@ array, ref = getArray(x) # do something with array restoreArray(x, ref) # Free memory +destroy(ksp) destroy(A) destroy(b) destroy(x) From 11524df83263047c68555d49439cadfec31d7c13 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Wed, 19 Apr 2023 16:18:46 +0200 Subject: [PATCH 29/40] ptrs changed ok --- src/ISLocalToGlobalMapping.jl | 19 ++++++++++++------- src/KSP.jl | 21 ++++++++------------- src/Mat.jl | 29 ++++++++++++----------------- src/PetscViewer.jl | 23 ++++++++++++----------- src/Vec.jl | 23 +++++++++-------------- 5 files changed, 53 insertions(+), 62 deletions(-) diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index 54c1d6c..192c941 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -1,14 +1,19 @@ const CISLocalToGlobalMapping = Ptr{Cvoid} -struct ISLocalToGlobalMapping - ptr::Ref{CISLocalToGlobalMapping} +mutable struct ISLocalToGlobalMapping + ptr::CISLocalToGlobalMapping comm::MPI.Comm - ISLocalToGlobalMapping(comm::MPI.Comm) = new(Ref{Ptr{Cvoid}}(), comm) + ISLocalToGlobalMapping(comm::MPI.Comm) = new(CISLocalToGlobalMapping(), comm) end -# allows us to pass ISLocalToGlobalMapping objects directly into CISLocalToGlobalMapping ccall signatures -Base.cconvert(::Type{CISLocalToGlobalMapping}, l2g::ISLocalToGlobalMapping) = l2g.ptr[] +Base.unsafe_convert(::Type{CISLocalToGlobalMapping}, x::ISLocalToGlobalMapping) = x.ptr +function Base.unsafe_convert( + ::Type{Ptr{CISLocalToGlobalMapping}}, + x::ISLocalToGlobalMapping, +) + Ptr{CISLocalToGlobalMapping}(pointer_from_objref(x)) +end """ create( @@ -56,7 +61,7 @@ function create( n, indices, mode, - l2g.ptr, + l2g, ) @assert iszero(error) return l2g @@ -89,7 +94,7 @@ function destroy(mapping::ISLocalToGlobalMapping) (:ISLocalToGlobalMappingDestroy, libpetsc), PetscErrorCode, (Ptr{CISLocalToGlobalMapping},), - mapping.ptr, + mapping, ) @assert iszero(error) end diff --git a/src/KSP.jl b/src/KSP.jl index 0fa2e83..9941566 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -1,14 +1,14 @@ const CKSP = Ptr{Cvoid} -struct KSP - ptr::Ref{CKSP} +mutable struct KSP + ptr::CKSP comm::MPI.Comm - KSP(comm::MPI.Comm) = new(Ref{CKSP}(), comm) + KSP(comm::MPI.Comm) = new(CKSP(), comm) end -# allows us to pass KSP objects directly into CKSP ccall signatures -Base.cconvert(::Type{CKSP}, ksp::KSP) = ksp.ptr[] +Base.unsafe_convert(::Type{CKSP}, x::KSP) = x.ptr +Base.unsafe_convert(::Type{Ptr{CKSP}}, x::KSP) = Ptr{CKSP}(pointer_from_objref(x)) """ create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) @@ -18,13 +18,8 @@ https://petsc.org/release/manualpages/KSP/KSPCreate/ """ function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) ksp = KSP(comm) - error = ccall( - (:KSPCreate, libpetsc), - PetscErrorCode, - (MPI.MPI_Comm, Ptr{CKSP}), - comm, - ksp.ptr, - ) + error = + ccall((:KSPCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}), comm, ksp) @assert iszero(error) return ksp end @@ -36,7 +31,7 @@ Wrapper to `KSPDestroy` https://petsc.org/release/manualpages/KSP/KSPDestroy/ """ function destroy(ksp::KSP) - error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp.ptr) + error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp) @assert iszero(error) end diff --git a/src/Mat.jl b/src/Mat.jl index 92e9cbf..22fbee8 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -3,15 +3,15 @@ const CMat = Ptr{Cvoid} """ A Petsc matrix, actually just a pointer to the actual C matrix """ -struct Mat - ptr::Ref{CMat} +mutable struct Mat + ptr::CMat comm::MPI.Comm - Mat(comm::MPI.Comm) = new(Ref{CMat}(), comm) + Mat(comm::MPI.Comm) = new(CMat(), comm) end -# allows us to pass Mat objects directly into CMat ccall signatures -Base.cconvert(::Type{CMat}, mat::Mat) = mat.ptr[] +Base.unsafe_convert(::Type{CMat}, x::Mat) = x.ptr +Base.unsafe_convert(::Type{Ptr{CMat}}, x::Mat) = Ptr{CMat}(pointer_from_objref(x)) """ assemblyBegin(mat::Mat, type::MatAssemblyType) @@ -67,13 +67,8 @@ https://petsc.org/release/manualpages/Mat/MatCreate/ """ function create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD) mat = Mat(comm) - error = ccall( - (:MatCreate, libpetsc), - PetscErrorCode, - (MPI.MPI_Comm, Ptr{CMat}), - comm, - mat.ptr, - ) + error = + ccall((:MatCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CMat}), comm, mat) @assert iszero(error) return mat end @@ -105,7 +100,7 @@ function createDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::P M, N, C_NULL, - mat.ptr, + mat, ) @assert iszero(error) return mat @@ -134,8 +129,8 @@ function createVecs(mat::Mat, right::Vec, left::Vec) PetscErrorCode, (CMat, Ptr{CVec}, Ptr{CVec}), mat, - right.ptr, - left.ptr, + right, + left, ) @assert iszero(error) end @@ -154,7 +149,7 @@ Wrapper to `MatDestroy` https://petsc.org/release/manualpages/Mat/MatDestroy/ """ function destroy(A::Mat) - error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), A.ptr) + error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), A) @assert iszero(error) end @@ -172,7 +167,7 @@ function duplicate(mat::Mat, op::MatDuplicateOption) (CMat, MatDuplicateOption, Ptr{CMat}), mat, op, - M.ptr, + M, ) @assert iszero(error) diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index 430828a..529b616 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -1,13 +1,15 @@ const CViewer = Ptr{Cvoid} -struct PetscViewer - ptr::Ref{CViewer} +mutable struct PetscViewer + ptr::CViewer comm::MPI.Comm - PetscViewer(comm::MPI.Comm) = new(Ref{CViewer}(), comm) + PetscViewer(comm::MPI.Comm) = new(CViewer(), comm) end -# allows us to pass PetscViewer objects directly into CViewer ccall signatures -Base.cconvert(::Type{CViewer}, viewer::PetscViewer) = viewer.ptr[] +Base.unsafe_convert(::Type{CViewer}, x::PetscViewer) = x.ptr +function Base.unsafe_convert(::Type{Ptr{CViewer}}, x::PetscViewer) + Ptr{CViewer}(pointer_from_objref(x)) +end """ ASCIIGetStdout(comm::MPI.Comm) @@ -22,7 +24,7 @@ function ASCIIGetStdout(comm::MPI.Comm = MPI.COMM_WORLD) PetscErrorCode, (MPI.MPI_Comm, Ptr{CViewer}), comm, - viewer.ptr, + viewer, ) @assert iszero(error) return viewer @@ -44,7 +46,7 @@ function ASCIIOpen(comm::MPI.Comm, name::String) (MPI.MPI_Comm, Cstring, Ptr{CViewer}), comm, name, - viewer.ptr, + viewer, ) @assert iszero(error) return viewer @@ -63,7 +65,7 @@ function create(::Type{PetscViewer}, comm::MPI.Comm = MPI.COMM_WORLD) PetscErrorCode, (MPI.MPI_Comm, Ptr{CViewer}), comm, - viewer.ptr, + viewer, ) @assert iszero(error) return viewer @@ -78,8 +80,7 @@ https://petsc.org/release/manualpages/Viewer/PetscViewerDestroy/ Warning : from what I understand, all viewers must not be destroyed explicitely using `PetscViewerDestroy`. """ function destroy(viewer::PetscViewer) - error = - ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer},), viewer.ptr) + error = ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer},), viewer) @assert iszero(error) end @@ -132,7 +133,7 @@ function HDF5Open(comm::MPI.Comm, name::String, type::PetscFileMode) comm, name, type, - viewer.ptr, + viewer, ) @assert iszero(error) return viewer diff --git a/src/Vec.jl b/src/Vec.jl index bf6b1cb..442a5a6 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -1,14 +1,14 @@ const CVec = Ptr{Cvoid} -struct Vec - ptr::Ref{CVec} +mutable struct Vec + ptr::CVec comm::MPI.Comm - Vec(comm::MPI.Comm) = new(Ref{Ptr{Cvoid}}(), comm) + Vec(comm::MPI.Comm) = new(CVec(), comm) end -# allows us to pass Vec objects directly into CVec ccall signatures -Base.cconvert(::Type{CVec}, vec::Vec) = vec.ptr[] +Base.unsafe_convert(::Type{CVec}, x::Vec) = x.ptr +Base.unsafe_convert(::Type{Ptr{CVec}}, x::Vec) = Ptr{CVec}(pointer_from_objref(x)) """ assemblyBegin(vec::Vec) @@ -60,13 +60,8 @@ https://petsc.org/release/manualpages/Vec/VecCreate/ """ function create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD) vec = Vec(comm) - error = ccall( - (:VecCreate, libpetsc), - PetscErrorCode, - (MPI.MPI_Comm, Ptr{CVec}), - comm, - vec.ptr, - ) + error = + ccall((:VecCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CVec}), comm, vec) @assert iszero(error) return vec end @@ -78,7 +73,7 @@ Wrapper to `VecDestroy` https://petsc.org/release/manualpages/Vec/VecDestroy/ """ function destroy(v::Vec) - error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v.ptr) + error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v) @assert iszero(error) end @@ -105,7 +100,7 @@ https://petsc.org/release/manualpages/Vec/VecDuplicate/ """ function duplicate(v::Vec) newv = Vec(v.comm) - error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), v, newv.ptr) + error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), v, newv) @assert iszero(error) return newv From db995e60a87513371bef29f71a682aa0381f5298 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Wed, 19 Apr 2023 17:02:13 +0200 Subject: [PATCH 30/40] finalizer --- example/linear_system.jl | 10 +++---- src/ISLocalToGlobalMapping.jl | 17 ++++++++--- src/KSP.jl | 7 +++-- src/Mat.jl | 54 ++++++++++++++++++++++++++++------- src/PetscViewer.jl | 3 ++ src/Vec.jl | 18 ++++++++---- 6 files changed, 81 insertions(+), 28 deletions(-) diff --git a/example/linear_system.jl b/example/linear_system.jl index 8667915..8ae0e6f 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -88,13 +88,11 @@ array, ref = getArray(x) # do something with array @show array restoreArray(x, ref) -# Free memory -destroy(ksp) -destroy(A) -destroy(b) -destroy(x) +# Free memory. Note that this call is faculative since, by default, +# the julia GC will trigger a call to Petsc `destroy` to each object +destroy.((ksp, A, b, x)) -# Finalize Petsc +# Finalize Petsc (and, optionally, MPI) PetscFinalize(true) end #hide \ No newline at end of file diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index 192c941..6177f42 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -21,7 +21,8 @@ end bs::PetscInt, n::PetscInt, indices::Vector{PetscInt}, - mode::PetscCopyMode, + mode::PetscCopyMode; + add_finalizer = true, ) create( @@ -29,6 +30,8 @@ end comm::MPI.Comm, indices::Vector{I}, mode::PetscCopyMode = PETSC_COPY_VALUES, + mode::PetscCopyMode; + add_finalizer = true, ) where {I<:Integer} Wrapper to `ISLocalToGlobalMappingCreate` @@ -42,7 +45,8 @@ function create( bs::PetscInt, n::PetscInt, indices::Vector{PetscInt}, - mode::PetscCopyMode, + mode::PetscCopyMode; + add_finalizer = true, ) l2g = ISLocalToGlobalMapping(comm) error = ccall( @@ -64,6 +68,9 @@ function create( l2g, ) @assert iszero(error) + + add_finalizer && finalizer(destroy, l2g) + return l2g end @@ -71,7 +78,8 @@ function create( ::Type{ISLocalToGlobalMapping}, comm::MPI.Comm, indices::Vector{I}, - mode::PetscCopyMode = PETSC_COPY_VALUES, + mode::PetscCopyMode = PETSC_COPY_VALUES; + add_finalizer = true, ) where {I<:Integer} return create( ISLocalToGlobalMapping, @@ -79,7 +87,8 @@ function create( PetscIntOne, PetscInt(length(indices)), PetscInt.(indices), - mode, + mode; + add_finalizer, ) end diff --git a/src/KSP.jl b/src/KSP.jl index 9941566..dcdfae3 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -11,16 +11,19 @@ Base.unsafe_convert(::Type{CKSP}, x::KSP) = x.ptr Base.unsafe_convert(::Type{Ptr{CKSP}}, x::KSP) = Ptr{CKSP}(pointer_from_objref(x)) """ - create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) + create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = true) Wrapper for `KSPCreate` https://petsc.org/release/manualpages/KSP/KSPCreate/ """ -function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD) +function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = true) ksp = KSP(comm) error = ccall((:KSPCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}), comm, ksp) @assert iszero(error) + + add_finalizer && finalizer(destroy, ksp) + return ksp end diff --git a/src/Mat.jl b/src/Mat.jl index 22fbee8..edc10b0 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -59,28 +59,38 @@ function compositeAddMat(mat::Mat, smat::Mat) end """ - create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD) - create(::Type{Mat}) + create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = true) Wrapper to `MatCreate` https://petsc.org/release/manualpages/Mat/MatCreate/ """ -function create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD) +function create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = true) mat = Mat(comm) error = ccall((:MatCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CMat}), comm, mat) @assert iszero(error) + + add_finalizer && finalizer(destroy, mat) + return mat end """ - createDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) + createDense( + comm::MPI.Comm, + m::PetscInt, + n::PetscInt, + M::PetscInt, + N::PetscInt; + add_finalizer = true, + ) createDense( comm::MPI.Comm, m::Integer = PETSC_DECIDE, n::Integer = PETSC_DECIDE, M::Integer = PETSC_DECIDE, - N::Integer = PETSC_DECIDE, + N::Integer = PETSC_DECIDE; + add_finalizer = true, ) Wrapper to `MatCreateDense` @@ -88,7 +98,14 @@ https://petsc.org/release/manualpages/Mat/MatCreateDense/ Last argument `data` is not supported yet (NULL is passed). """ -function createDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::PetscInt) +function createDense( + comm::MPI.Comm, + m::PetscInt, + n::PetscInt, + M::PetscInt, + N::PetscInt; + add_finalizer = true, +) mat = Mat(comm) error = ccall( (:MatCreateDense, libpetsc), @@ -103,6 +120,9 @@ function createDense(comm::MPI.Comm, m::PetscInt, n::PetscInt, M::PetscInt, N::P mat, ) @assert iszero(error) + + add_finalizer && finalizer(destroy, mat) + return mat end @@ -111,14 +131,22 @@ function createDense( m::Integer = PETSC_DECIDE, n::Integer = PETSC_DECIDE, M::Integer = PETSC_DECIDE, - N::Integer = PETSC_DECIDE, + N::Integer = PETSC_DECIDE; + add_finalizer = true, ) - return createDense(comm, PetscInt(m), PetscInt(n), PetscInt(M), PetscInt(N)) + return createDense( + comm, + PetscInt(m), + PetscInt(n), + PetscInt(M), + PetscInt(N); + add_finalizer, + ) end """ createVecs(mat::Mat, vecr::Vec, veci::Vec) - createVecs(mat::Mat) + createVecs(mat::Mat; add_finalizer = true) Wrapper to `MatCreateVecs` https://petsc.org/release/manualpages/Mat/MatCreateVecs/ @@ -135,10 +163,16 @@ function createVecs(mat::Mat, right::Vec, left::Vec) @assert iszero(error) end -function createVecs(mat::Mat) +function createVecs(mat::Mat; add_finalizer = true) right = Vec(mat.comm) left = Vec(mat.comm) createVecs(mat, right, left) + + if add_finalizer + finalizer(destroy, right) + finalizer(destroy, left) + end + return right, left end diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index 529b616..b7dba47 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -1,3 +1,6 @@ +# DEV NOTE : using `finalizer` for PetscViewer failed because for some reason I don't understand, +# calling `PetscViewerDestroy` often fails (even outside the context of `finalizer`) + const CViewer = Ptr{Cvoid} mutable struct PetscViewer ptr::CViewer diff --git a/src/Vec.jl b/src/Vec.jl index 442a5a6..b960507 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -34,7 +34,7 @@ end """ copy(x::Vec, y::Vec) - copy(x::Vec) + copy(x::Vec; add_finalizer = true) Wrapper to `VecCopy` https://petsc.org/release/manualpages/Vec/VecCopy/ @@ -46,23 +46,27 @@ function Base.copy(x::Vec, y::Vec) @assert iszero(error) end -function Base.copy(x::Vec) +function Base.copy(x::Vec; add_finalizer = true) y = duplicate(x) copy(x, y) + add_finalizer && finalizer(destroy, y) return y end """ - create(::Type{Vec},comm::MPI.Comm = MPI.COMM_WORLD) + create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = true) Wrapper to `VecCreate` https://petsc.org/release/manualpages/Vec/VecCreate/ """ -function create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD) +function create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = true) vec = Vec(comm) error = ccall((:VecCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CVec}), comm, vec) @assert iszero(error) + + add_finalizer && finalizer(destroy, vec) + return vec end @@ -93,16 +97,18 @@ function LinearAlgebra.dot(x::Vec, y::Vec) end """ - duplicate(v::Vec) + duplicate(v::Vec; add_finalizer = true) Wrapper for `VecDuplicate` https://petsc.org/release/manualpages/Vec/VecDuplicate/ """ -function duplicate(v::Vec) +function duplicate(v::Vec; add_finalizer = true) newv = Vec(v.comm) error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), v, newv) @assert iszero(error) + add_finalizer && finalizer(destroy, newv) + return newv end From c0a9acc3fca53d57293d326ab107699c98de5575 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Wed, 19 Apr 2023 17:07:46 +0200 Subject: [PATCH 31/40] finalizer for duplicate(mat) --- src/Mat.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Mat.jl b/src/Mat.jl index edc10b0..6b37d2d 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -188,12 +188,12 @@ function destroy(A::Mat) end """ - duplicate(mat::Mat, op::MatDuplicateOption) + duplicate(mat::Mat, op::MatDuplicateOption; add_finalizer = true) Wrapper for `MatDuplicate` https://petsc.org/release/manualpages/Mat/MatDuplicate/ """ -function duplicate(mat::Mat, op::MatDuplicateOption) +function duplicate(mat::Mat, op::MatDuplicateOption; add_finalizer = true) M = Mat(mat.comm) error = ccall( (:MatDuplicate, libpetsc), @@ -205,6 +205,8 @@ function duplicate(mat::Mat, op::MatDuplicateOption) ) @assert iszero(error) + add_finalizer && finalizer(destroy, M) + return M end From a20001080f58b562370a49bea5fb08e1c5072664 Mon Sep 17 00:00:00 2001 From: bmxam Date: Wed, 19 Apr 2023 22:14:17 +0200 Subject: [PATCH 32/40] wrapper for PetscFinalized --- src/init.jl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/init.jl b/src/init.jl index 34abe6f..54a2f7d 100644 --- a/src/init.jl +++ b/src/init.jl @@ -76,3 +76,23 @@ function PetscInitialized() @assert iszero(error) return Bool(isInitialized[]) end + +""" + Wrapper to PetscFinalized + +Cmd line options: +-options_view - Calls PetscOptionsView() +-options_left - Prints unused options that remain in the database +-objects_dump [all] - Prints list of objects allocated by the user that have not been freed, the option all cause all outstanding objects to be listed +-mpidump - Calls PetscMPIDump() +-malloc_dump - Calls PetscMallocDump(), displays all memory allocated that has not been freed +-malloc_info - Prints total memory usage +-malloc_view - Prints list of all memory allocated and where +""" +function PetscFinalized() + isFinalized = Ref{PetscBool}() + error = + ccall((:PetscFinalized, libpetsc), PetscErrorCode, (Ref{PetscBool},), isFinalized) + @assert iszero(error) + return Bool(isFinalized[]) +end From 22b87f232257fa9f1f1829ac60154a25d6445b61 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Thu, 20 Apr 2023 09:21:17 +0200 Subject: [PATCH 33/40] tracking allocs --- src/ISLocalToGlobalMapping.jl | 3 +++ src/KSP.jl | 3 +++ src/Mat.jl | 6 ++++++ src/PetscWrap.jl | 3 +++ src/Vec.jl | 5 +++++ src/init.jl | 5 +++++ 6 files changed, 25 insertions(+) diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index 6177f42..06a884f 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -69,6 +69,7 @@ function create( ) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, l2g) return l2g @@ -106,4 +107,6 @@ function destroy(mapping::ISLocalToGlobalMapping) mapping, ) @assert iszero(error) + + _NREFS[] -= 1 end diff --git a/src/KSP.jl b/src/KSP.jl index dcdfae3..09806f9 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -22,6 +22,7 @@ function create(::Type{KSP}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = tr ccall((:KSPCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CKSP}), comm, ksp) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, ksp) return ksp @@ -36,6 +37,8 @@ https://petsc.org/release/manualpages/KSP/KSPDestroy/ function destroy(ksp::KSP) error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp) @assert iszero(error) + + _NREFS[] -= 1 end """ diff --git a/src/Mat.jl b/src/Mat.jl index 6b37d2d..3801dbd 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -70,6 +70,7 @@ function create(::Type{Mat}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = tr ccall((:MatCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CMat}), comm, mat) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, mat) return mat @@ -121,6 +122,7 @@ function createDense( ) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, mat) return mat @@ -168,6 +170,7 @@ function createVecs(mat::Mat; add_finalizer = true) left = Vec(mat.comm) createVecs(mat, right, left) + _NREFS[] += 2 if add_finalizer finalizer(destroy, right) finalizer(destroy, left) @@ -185,6 +188,8 @@ https://petsc.org/release/manualpages/Mat/MatDestroy/ function destroy(A::Mat) error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), A) @assert iszero(error) + + _NREFS[] -= 1 end """ @@ -205,6 +210,7 @@ function duplicate(mat::Mat, op::MatDuplicateOption; add_finalizer = true) ) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, M) return M diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 2e37d43..97459d4 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -9,6 +9,9 @@ using Libdl using MPI using LinearAlgebra +# GridapPETSc trick to track allocs/deallocs +const _NREFS = Ref(0) + include("const_arch_ind.jl") export PetscErrorCode, PETSC_DECIDE # export all items of some enums diff --git a/src/Vec.jl b/src/Vec.jl index b960507..936ab56 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -49,6 +49,7 @@ end function Base.copy(x::Vec; add_finalizer = true) y = duplicate(x) copy(x, y) + _NREFS[] += 1 add_finalizer && finalizer(destroy, y) return y end @@ -65,6 +66,7 @@ function create(::Type{Vec}, comm::MPI.Comm = MPI.COMM_WORLD; add_finalizer = tr ccall((:VecCreate, libpetsc), PetscErrorCode, (MPI.MPI_Comm, Ptr{CVec}), comm, vec) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, vec) return vec @@ -79,6 +81,8 @@ https://petsc.org/release/manualpages/Vec/VecDestroy/ function destroy(v::Vec) error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v) @assert iszero(error) + + _NREFS[] -= 1 end function LinearAlgebra.dot(x::Vec, y::Vec) @@ -107,6 +111,7 @@ function duplicate(v::Vec; add_finalizer = true) error = ccall((:VecDuplicate, libpetsc), PetscErrorCode, (CVec, Ptr{CVec}), v, newv) @assert iszero(error) + _NREFS[] += 1 add_finalizer && finalizer(destroy, newv) return newv diff --git a/src/init.jl b/src/init.jl index 54a2f7d..967bfb1 100644 --- a/src/init.jl +++ b/src/init.jl @@ -56,6 +56,11 @@ end Wrapper to PetscFinalize """ function PetscFinalize(finalizeMPI = false) + GC.gc() + if _NREFS[] != 0 + @warn "$(_NREFS[]) objects still not finalized before calling PetscWrap.Finalize()" + end + error = ccall((:PetscFinalize, libpetsc), PetscErrorCode, ()) @assert iszero(error) From b5dcb6bd59d0dd3e5a990dfa5f38ac69d4a99acf Mon Sep 17 00:00:00 2001 From: mbouyges Date: Thu, 20 Apr 2023 09:54:38 +0200 Subject: [PATCH 34/40] wrapper for PetscObjectRegisterDestroy --- src/ISLocalToGlobalMapping.jl | 2 +- src/KSP.jl | 2 +- src/Mat.jl | 2 +- src/PetscViewer.jl | 2 +- src/PetscWrap.jl | 2 ++ src/Vec.jl | 2 +- src/common.jl | 9 +++++++++ src/init.jl | 6 ++++++ 8 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/common.jl diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index 06a884f..64a3c83 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -1,6 +1,6 @@ const CISLocalToGlobalMapping = Ptr{Cvoid} -mutable struct ISLocalToGlobalMapping +mutable struct ISLocalToGlobalMapping <: AbstractPetscObject ptr::CISLocalToGlobalMapping comm::MPI.Comm diff --git a/src/KSP.jl b/src/KSP.jl index 09806f9..56cfd2a 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -1,6 +1,6 @@ const CKSP = Ptr{Cvoid} -mutable struct KSP +mutable struct KSP <: AbstractPetscObject ptr::CKSP comm::MPI.Comm diff --git a/src/Mat.jl b/src/Mat.jl index 3801dbd..f821753 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -3,7 +3,7 @@ const CMat = Ptr{Cvoid} """ A Petsc matrix, actually just a pointer to the actual C matrix """ -mutable struct Mat +mutable struct Mat <: AbstractPetscObject ptr::CMat comm::MPI.Comm diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index b7dba47..915a438 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -2,7 +2,7 @@ # calling `PetscViewerDestroy` often fails (even outside the context of `finalizer`) const CViewer = Ptr{Cvoid} -mutable struct PetscViewer +mutable struct PetscViewer <: AbstractPetscObject ptr::CViewer comm::MPI.Comm diff --git a/src/PetscWrap.jl b/src/PetscWrap.jl index 97459d4..13b017d 100644 --- a/src/PetscWrap.jl +++ b/src/PetscWrap.jl @@ -32,6 +32,8 @@ export show_petsc_path include("const_arch_dep.jl") export PetscReal, PetscScalar, PetscInt, PetscIntOne +include("common.jl") + include("init.jl") export PetscInitialize, PetscInitialized, PetscFinalize diff --git a/src/Vec.jl b/src/Vec.jl index 936ab56..6bd386b 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -1,6 +1,6 @@ const CVec = Ptr{Cvoid} -mutable struct Vec +mutable struct Vec <: AbstractPetscObject ptr::CVec comm::MPI.Comm diff --git a/src/common.jl b/src/common.jl new file mode 100644 index 0000000..f8614c1 --- /dev/null +++ b/src/common.jl @@ -0,0 +1,9 @@ +abstract type AbstractPetscObject end + +const CPetscObject = Ptr{Cvoid} + +function objectRegisterDestroy(obj::AbstractPetscObject) + error = + ccall((:PetscObjectRegisterDestroy, libpetsc), PetscErrorCode, (CPetscObject,), obj) + @assert iszero(error) +end \ No newline at end of file diff --git a/src/init.jl b/src/init.jl index 967bfb1..e6b1fcb 100644 --- a/src/init.jl +++ b/src/init.jl @@ -64,6 +64,12 @@ function PetscFinalize(finalizeMPI = false) error = ccall((:PetscFinalize, libpetsc), PetscErrorCode, ()) @assert iszero(error) + if _NREFS[] != 0 + @warn "$(_NREFS[]) objects still not finalized after calling PetscWrap.Finalize()" + end + + _NREFS[] != 0 + finalizeMPI && MPI.Finalize() end From 55a31213d92775d5507351156d76fce58c4567b0 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Thu, 20 Apr 2023 11:03:05 +0200 Subject: [PATCH 35/40] tiny improvement for comprehension --- src/Mat.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mat.jl b/src/Mat.jl index f821753..f852c82 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -170,7 +170,8 @@ function createVecs(mat::Mat; add_finalizer = true) left = Vec(mat.comm) createVecs(mat, right, left) - _NREFS[] += 2 + _NREFS[] += 1 + _NREFS[] += 1 if add_finalizer finalizer(destroy, right) finalizer(destroy, left) From 9c6750fa4f2c4e4623653cf2635a925bac0be5f5 Mon Sep 17 00:00:00 2001 From: mbouyges Date: Thu, 20 Apr 2023 11:15:54 +0200 Subject: [PATCH 36/40] using atexit --- README.md | 10 +++------- example/linear_system.jl | 2 +- example/linear_system_fancy.jl | 4 ---- src/init.jl | 27 ++++++++++++++++++++------- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 15d6f0a..e239657 100644 --- a/README.md +++ b/README.md @@ -190,16 +190,12 @@ array, ref = getArray(x) # do something with array restoreArray(x, ref) ``` -Free memory - +Free memory. Note that this call is faculative since, by default, the julia GC will trigger a call to Petsc `destroy` to each object ```julia -destroy(A) -destroy(b) -destroy(x) +destroy.((ksp, A, b, x)) ``` -Finalize Petsc - +Finalize Petsc (and, optionally, MPI): this is actually optional, it will be called automatically ```julia PetscFinalize() diff --git a/example/linear_system.jl b/example/linear_system.jl index 8ae0e6f..9ccf944 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -92,7 +92,7 @@ restoreArray(x, ref) # the julia GC will trigger a call to Petsc `destroy` to each object destroy.((ksp, A, b, x)) -# Finalize Petsc (and, optionally, MPI) +# Finalize Petsc (and, optionally, MPI): this is actually optional, it will be called automatically PetscFinalize(true) end #hide \ No newline at end of file diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index 2af0feb..b931100 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -88,11 +88,7 @@ k = findall(x -> M_start <= x <= M_end, I) # just a trick to allow this example set_values!(M, I[k], J[k], V[k], ADD_VALUES) assemble!(M) @show M -destroy!(M) # This is very convenient in sequential since you can fill the three vectors I, J, V in your code and decide only # at the last moment if you'd like to use `SparseArrays` or `PetscMat`. -# Finalize Petsc -PetscFinalize(true) - end #hide \ No newline at end of file diff --git a/src/init.jl b/src/init.jl index e6b1fcb..2581af8 100644 --- a/src/init.jl +++ b/src/init.jl @@ -5,7 +5,12 @@ I don't know if I am supposed to use PetscInt or not... """ -function PetscInitialize(args::Vector{String}, filename::String, help::String) +function PetscInitialize( + args::Vector{String}, + filename::String, + help::String; + finalize_atexit = true, +) args2 = ["julia"; args] nargs = Cint(length(args2)) error = ccall( @@ -18,22 +23,26 @@ function PetscInitialize(args::Vector{String}, filename::String, help::String) help, ) @assert iszero(error) + + finalize_atexit && atexit(PetscFinalize) end """ Initialize PETSc with arguments stored in a vector of string """ -PetscInitialize(args::Vector{String}) = PetscInitialize(args, "", "") +function PetscInitialize(args::Vector{String}; finalize_atexit = true) + PetscInitialize(args, "", ""; finalize_atexit) +end """ Initialize PETSc with arguments concatenated in a unique string. """ -function PetscInitialize(args::String) - PetscInitialize(convert(Vector{String}, split(args)), "", "") +function PetscInitialize(args::String; finalize_atexit = true) + PetscInitialize(convert(Vector{String}, split(args)), "", ""; finalize_atexit) end """ - PetscInitialize(cmd_line_args::Bool = true) + PetscInitialize(cmd_line_args::Bool = true; finalize_atexit = true) Initialize PETSc. @@ -43,12 +52,14 @@ arguments for PETSc (leading to a call to `PetscInitializeNoPointers`). Otherwise, if `cmd_line_args == false`, initialize PETSc without arguments (leading to a call to `PetscInitializeNoArguments`). """ -function PetscInitialize(cmd_line_args::Bool = true) +function PetscInitialize(cmd_line_args::Bool = true; finalize_atexit = true) if (cmd_line_args) - PetscInitialize(ARGS) + PetscInitialize(ARGS; finalize_atexit) else error = ccall((:PetscInitializeNoArguments, libpetsc), PetscErrorCode, ()) @assert iszero(error) + + finalize_atexit && atexit(PetscFinalize) end end @@ -56,6 +67,8 @@ end Wrapper to PetscFinalize """ function PetscFinalize(finalizeMPI = false) + PetscFinalized() && return + GC.gc() if _NREFS[] != 0 @warn "$(_NREFS[]) objects still not finalized before calling PetscWrap.Finalize()" From c6a08a639d08c2ef6633d82a1ff529d0cd67bd5b Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 22 Apr 2023 14:17:30 +0200 Subject: [PATCH 37/40] avoid destruction when already destroyed --- README.md | 10 +++++++--- example/linear_system.jl | 3 ++- example/linear_system_fancy.jl | 31 +++++++++++++------------------ src/ISLocalToGlobalMapping.jl | 2 ++ src/KSP.jl | 2 ++ src/Mat.jl | 4 +++- src/PetscViewer.jl | 2 ++ src/Vec.jl | 2 ++ src/common.jl | 5 ++++- src/fancy/common.jl | 6 +++--- src/fancy/ksp.jl | 4 ++-- src/init.jl | 2 +- 12 files changed, 43 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index e239657..f680a79 100644 --- a/README.md +++ b/README.md @@ -190,13 +190,17 @@ array, ref = getArray(x) # do something with array restoreArray(x, ref) ``` -Free memory. Note that this call is faculative since, by default, the julia GC will trigger a call to Petsc `destroy` to each object +Free memory. Note that this call is faculative since, by default, +the julia GC will trigger a call to Petsc `destroy` to each object + ```julia destroy.((ksp, A, b, x)) ``` -Finalize Petsc (and, optionally, MPI): this is actually optional, it will be called automatically +Finalize Petsc and MPI. If you initialized MPI yourself, this call is faculative : it will +be triggered automatically at the end of the script. + ```julia -PetscFinalize() +PetscFinalize(true) ``` diff --git a/example/linear_system.jl b/example/linear_system.jl index 9ccf944..d836fb4 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -92,7 +92,8 @@ restoreArray(x, ref) # the julia GC will trigger a call to Petsc `destroy` to each object destroy.((ksp, A, b, x)) -# Finalize Petsc (and, optionally, MPI): this is actually optional, it will be called automatically +# Finalize Petsc and MPI. If you initialized MPI yourself, this call is faculative : it will +# be triggered automatically at the end of the script. PetscFinalize(true) end #hide \ No newline at end of file diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index b931100..78ba516 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -12,8 +12,12 @@ module Example #hide # To run this example, execute : `mpirun -n your_favorite_positive_integer julia example2.jl` # Import package +using MPI using PetscWrap +# Initialize MPI +MPI.Init() + # Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can # also provide "command line arguments by defining them in a string, for instance # `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in @@ -24,17 +28,10 @@ PetscInitialize() n = 11 Δx = 1.0 / (n - 1) -# Create a matrix of size `(n,n)` and a vector of size `(n)` -A = create_matrix(; nrows_glo = n, ncols_glo = n) -b = create_vector(; nrows_glo = n) - -# We can then use command line options to set our matrix/vectors. -set_from_options!(A) -set_from_options!(b) - -# Finish the set up -set_up!(A) -set_up!(b) +# Create a matrix of size `(n,n)` and a vector of size `(n)`. The `autosetup` option +# triggers a call to `setFromOptions` and `setUp` +A = create_matrix(; nrows_glo = n, ncols_glo = n, autosetup = true) +b = create_vector(; nrows_glo = n, autosetup = true) # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. # The `rstart, rend = get_range(*)` methods differ a little bit from PETSc API since the two integers it @@ -60,9 +57,7 @@ assemble!(A) assemble!(b) # Set up the linear solver -ksp = create_ksp(A) -set_from_options!(ksp) -set_up!(ksp) +ksp = create_ksp(A; autosetup = true) # Solve the system x = solve(ksp, b) @@ -73,10 +68,8 @@ x = solve(ksp, b) # Convert `PetscVec` to Julia `Array` (and play with it!) array = vec2array(x) -# Free memory -destroy!(A) -destroy!(b) -destroy!(x) +# Free memory (optional, objects are garbage collected otherwise) +destroy!(A, b, x, ksp) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: M = create_matrix(; nrows_glo = 3, ncols_glo = 3, autosetup = true) @@ -91,4 +84,6 @@ assemble!(M) # This is very convenient in sequential since you can fill the three vectors I, J, V in your code and decide only # at the last moment if you'd like to use `SparseArrays` or `PetscMat`. +destroy!(M) + end #hide \ No newline at end of file diff --git a/src/ISLocalToGlobalMapping.jl b/src/ISLocalToGlobalMapping.jl index 64a3c83..70686fb 100644 --- a/src/ISLocalToGlobalMapping.jl +++ b/src/ISLocalToGlobalMapping.jl @@ -100,6 +100,8 @@ Wrapper to `ISLocalToGlobalMappingDestroy` https://petsc.org/release/manualpages/IS/ISLocalToGlobalMappingDestroy/ """ function destroy(mapping::ISLocalToGlobalMapping) + _is_destroyed(mapping) && return + error = ccall( (:ISLocalToGlobalMappingDestroy, libpetsc), PetscErrorCode, diff --git a/src/KSP.jl b/src/KSP.jl index 56cfd2a..7b5f29a 100644 --- a/src/KSP.jl +++ b/src/KSP.jl @@ -35,6 +35,8 @@ Wrapper to `KSPDestroy` https://petsc.org/release/manualpages/KSP/KSPDestroy/ """ function destroy(ksp::KSP) + _is_destroyed(ksp) && return + error = ccall((:KSPDestroy, libpetsc), PetscErrorCode, (Ptr{CKSP},), ksp) @assert iszero(error) diff --git a/src/Mat.jl b/src/Mat.jl index f852c82..3282172 100644 --- a/src/Mat.jl +++ b/src/Mat.jl @@ -187,6 +187,8 @@ Wrapper to `MatDestroy` https://petsc.org/release/manualpages/Mat/MatDestroy/ """ function destroy(A::Mat) + _is_destroyed(A) && return + error = ccall((:MatDestroy, libpetsc), PetscErrorCode, (Ptr{CMat},), A) @assert iszero(error) @@ -733,4 +735,4 @@ https://petsc.org/release/manualpages/Mat/MatZeroEntries/ function zeroEntries(mat::Mat) error = ccall((:MatZeroEntries, libpetsc), PetscErrorCode, (CMat,), mat) @assert iszero(error) -end \ No newline at end of file +end diff --git a/src/PetscViewer.jl b/src/PetscViewer.jl index 915a438..92dc50e 100644 --- a/src/PetscViewer.jl +++ b/src/PetscViewer.jl @@ -83,6 +83,8 @@ https://petsc.org/release/manualpages/Viewer/PetscViewerDestroy/ Warning : from what I understand, all viewers must not be destroyed explicitely using `PetscViewerDestroy`. """ function destroy(viewer::PetscViewer) + _is_destroyed(viewer) && return + error = ccall((:PetscViewerDestroy, libpetsc), PetscErrorCode, (Ptr{CViewer},), viewer) @assert iszero(error) end diff --git a/src/Vec.jl b/src/Vec.jl index 6bd386b..f3e6caf 100644 --- a/src/Vec.jl +++ b/src/Vec.jl @@ -79,6 +79,8 @@ Wrapper to `VecDestroy` https://petsc.org/release/manualpages/Vec/VecDestroy/ """ function destroy(v::Vec) + _is_destroyed(v) && return + error = ccall((:VecDestroy, libpetsc), PetscErrorCode, (Ptr{CVec},), v) @assert iszero(error) diff --git a/src/common.jl b/src/common.jl index f8614c1..92df969 100644 --- a/src/common.jl +++ b/src/common.jl @@ -1,4 +1,5 @@ abstract type AbstractPetscObject end +_get_ptr(obj::AbstractPetscObject) = obj.ptr const CPetscObject = Ptr{Cvoid} @@ -6,4 +7,6 @@ function objectRegisterDestroy(obj::AbstractPetscObject) error = ccall((:PetscObjectRegisterDestroy, libpetsc), PetscErrorCode, (CPetscObject,), obj) @assert iszero(error) -end \ No newline at end of file +end + +_is_destroyed(obj::AbstractPetscObject) = _get_ptr(obj) == C_NULL diff --git a/src/fancy/common.jl b/src/fancy/common.jl index d30cdb2..30d1d4b 100644 --- a/src/fancy/common.jl +++ b/src/fancy/common.jl @@ -1,3 +1,3 @@ -const destroy! = destroy -const set_from_options! = setFromOptions -const set_up! = setUp \ No newline at end of file +destroy!(obj::Vararg{<:AbstractPetscObject,N}) where {N} = destroy.(obj) +set_up!(obj::Vararg{<:AbstractPetscObject,N}) where {N} = setUp.(obj) +set_from_options!(obj::Vararg{<:AbstractPetscObject,N}) where {N} = setFromOptions.(obj) diff --git a/src/fancy/ksp.jl b/src/fancy/ksp.jl index ddb7ad3..0577f65 100644 --- a/src/fancy/ksp.jl +++ b/src/fancy/ksp.jl @@ -1,4 +1,4 @@ -function create_ksp(Amat::Mat, Pmat::Mat; autosetup=false) +function create_ksp(Amat::Mat, Pmat::Mat; autosetup = false) ksp = create(KSP) setOperators(ksp, Amat, Pmat) @@ -9,7 +9,7 @@ function create_ksp(Amat::Mat, Pmat::Mat; autosetup=false) return ksp end -create_ksp(A::Mat; autosetup=false) = create_ksp(A, A; autosetup) +create_ksp(A::Mat; autosetup = false) = create_ksp(A, A; autosetup) set_operators!(ksp::KSP, Amat::Mat) = setOperators(ksp, Amat, Amat) set_operators!(ksp::KSP, Amat::Mat, Pmat::Mat) = setOperators(ksp, Amat, Pmat) diff --git a/src/init.jl b/src/init.jl index 2581af8..569284c 100644 --- a/src/init.jl +++ b/src/init.jl @@ -81,7 +81,7 @@ function PetscFinalize(finalizeMPI = false) @warn "$(_NREFS[]) objects still not finalized after calling PetscWrap.Finalize()" end - _NREFS[] != 0 + _NREFS[] = 0 finalizeMPI && MPI.Finalize() end From c75865dda6d6fb9a48e33d3e5fd00a0e1302d213 Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 22 Apr 2023 20:45:33 +0200 Subject: [PATCH 38/40] fix MPI init : tests are not running anymore... --- README.md | 4 ++-- example/linear_system.jl | 6 +++--- example/linear_system_fancy.jl | 6 +----- src/init.jl | 8 +++++--- test/linear_system.jl | 23 +++++++++-------------- test/linear_system_fancy.jl | 29 ++++------------------------- test/misc.jl | 11 ++--------- test/runtests.jl | 24 ++++++++++++++++++++---- 8 files changed, 46 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index f680a79..e66e6f6 100644 --- a/README.md +++ b/README.md @@ -197,10 +197,10 @@ the julia GC will trigger a call to Petsc `destroy` to each object destroy.((ksp, A, b, x)) ``` -Finalize Petsc and MPI. If you initialized MPI yourself, this call is faculative : it will +Finalize Petsc. This call is faculative : it will be triggered automatically at the end of the script. ```julia -PetscFinalize(true) +PetscFinalize() ``` diff --git a/example/linear_system.jl b/example/linear_system.jl index d836fb4..b1f5fa6 100644 --- a/example/linear_system.jl +++ b/example/linear_system.jl @@ -92,8 +92,8 @@ restoreArray(x, ref) # the julia GC will trigger a call to Petsc `destroy` to each object destroy.((ksp, A, b, x)) -# Finalize Petsc and MPI. If you initialized MPI yourself, this call is faculative : it will +# Finalize Petsc. This call is faculative : it will # be triggered automatically at the end of the script. -PetscFinalize(true) +PetscFinalize() -end #hide \ No newline at end of file +end #hide diff --git a/example/linear_system_fancy.jl b/example/linear_system_fancy.jl index 78ba516..0fdc96b 100644 --- a/example/linear_system_fancy.jl +++ b/example/linear_system_fancy.jl @@ -12,12 +12,8 @@ module Example #hide # To run this example, execute : `mpirun -n your_favorite_positive_integer julia example2.jl` # Import package -using MPI using PetscWrap -# Initialize MPI -MPI.Init() - # Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can # also provide "command line arguments by defining them in a string, for instance # `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in @@ -86,4 +82,4 @@ assemble!(M) destroy!(M) -end #hide \ No newline at end of file +end #hide diff --git a/src/init.jl b/src/init.jl index 569284c..4595f5c 100644 --- a/src/init.jl +++ b/src/init.jl @@ -11,6 +11,8 @@ function PetscInitialize( help::String; finalize_atexit = true, ) + MPI.Initialized() || MPI.Init() + args2 = ["julia"; args] nargs = Cint(length(args2)) error = ccall( @@ -56,6 +58,8 @@ function PetscInitialize(cmd_line_args::Bool = true; finalize_atexit = true) if (cmd_line_args) PetscInitialize(ARGS; finalize_atexit) else + MPI.Initialized() || MPI.Init() + error = ccall((:PetscInitializeNoArguments, libpetsc), PetscErrorCode, ()) @assert iszero(error) @@ -66,7 +70,7 @@ end """ Wrapper to PetscFinalize """ -function PetscFinalize(finalizeMPI = false) +function PetscFinalize() PetscFinalized() && return GC.gc() @@ -82,8 +86,6 @@ function PetscFinalize(finalizeMPI = false) end _NREFS[] = 0 - - finalizeMPI && MPI.Finalize() end """ diff --git a/test/linear_system.jl b/test/linear_system.jl index f832d16..e6d64d3 100644 --- a/test/linear_system.jl +++ b/test/linear_system.jl @@ -1,23 +1,17 @@ @testset "linear system" begin - # Only on one processor... - - # Import package - using PetscWrap - - # Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can - # also provide "command line arguments by defining them in a string, for instance - # `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in - # separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` - PetscInitialize() - # Number of mesh points and mesh step n = 11 Δx = 1.0 / (n - 1) + println("before create Mat") + # Create a matrix and a vector A = create(Mat) + println("before create Vec") b = create(Vec) + println("before setSizes") + # Set the size of the different objects, leaving PETSC to decide how to distribute. Note that we should # set the number of preallocated non-zeros to increase performance. setSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n) @@ -31,6 +25,8 @@ setUp(A) setUp(b) + println("before getOwnershipRange") + # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. # As in PETSc, the `rstart, rend = *GetOwnershipRange` methods indicate the first row handled by the local processor # (starting at 0), and the last row (which is `rend-1`). This may be disturbing for non-regular PETSc users. Checkout @@ -56,6 +52,7 @@ assemblyEnd(A, MAT_FINAL_ASSEMBLY) assemblyEnd(b) + println("before matview") # At this point, you can inspect `A` or `b` using a viewer (stdout by default), simply call matView(A) vecView(b) @@ -70,6 +67,7 @@ x = duplicate(b) solve(ksp, b, x) + println("before vecview") # Print the solution vecView(x) @@ -83,9 +81,6 @@ destroy(b) destroy(x) - # Finalize Petsc - PetscFinalize() - # Reach this point? @test true end diff --git a/test/linear_system_fancy.jl b/test/linear_system_fancy.jl index 1e58476..4499917 100644 --- a/test/linear_system_fancy.jl +++ b/test/linear_system_fancy.jl @@ -1,27 +1,13 @@ @testset "linear system fancy" begin # Only on one processor... - # Initialize PETSc. Command line arguments passed to Julia are parsed by PETSc. Alternatively, you can - # also provide "command line arguments by defining them in a string, for instance - # `PetscInitialize("-ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always")` or by providing each argument in - # separate strings : `PetscInitialize(["-ksp_monitor_short", "-ksp_gmres_cgs_refinement_type", "refine_always")` - PetscInitialize() - # Number of mesh points and mesh step n = 11 Δx = 1.0 / (n - 1) # Create a matrix of size `(n,n)` and a vector of size `(n)` - A = create_matrix(; nrows_glo = n, ncols_glo = n) - b = create_vector(; nrows_glo = n) - - # We can then use command line options to set our matrix/vectors. - set_from_options!(A) - set_from_options!(b) - - # Finish the set up - set_up!(A) - set_up!(b) + A = create_matrix(; nrows_glo = n, ncols_glo = n, autosetup = true) + b = create_vector(; nrows_glo = n, autosetup = true) # Let's build the right hand side vector. We first get the range of rows of `b` handled by the local processor. # The `rstart, rend = get_range(*)` methods differ a little bit from PETSc API since the two integers it @@ -47,9 +33,7 @@ assemble!(b) # Set up the linear solver - ksp = create_ksp(A) - set_from_options!(ksp) - set_up!(ksp) + ksp = create_ksp(A; autosetup = true) # Solve the system x = solve(ksp, b) @@ -62,9 +46,7 @@ @test isapprox(array, range(0.0, 2.0; length = n)) # Free memory - destroy!(A) - destroy!(b) - destroy!(x) + destroy!(A, b, x) # Note that it's also possible to build a matrix using the COO format as in `SparseArrays`: M = create_matrix(; nrows_glo = 3, ncols_glo = 3, autosetup = true) @@ -80,9 +62,6 @@ # This is very convenient in sequential since you can fill the three vectors I, J, V in your code and decide only # at the last moment if you'd like to use `SparseArrays` or `PetscMat`. - # Finalize Petsc - PetscFinalize() - # Reach this point? @test true end diff --git a/test/misc.jl b/test/misc.jl index e2ea999..3f71bdf 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1,6 +1,4 @@ @testset "composite" begin - PetscInitialize() - # Create two matrices A = create_matrix(; nrows_glo = 2, ncols_glo = 2, autosetup = true) B = create_matrix(; nrows_glo = 2, ncols_glo = 2, autosetup = true) @@ -48,13 +46,10 @@ @test vec2array(y) == [3.0, 5.0] # Free memory - destroy!.((A, B, C, x1, x2, y)) - PetscFinalize() + destroy!(A, B, C, x1, x2, y) end @testset "mapping" begin - PetscInitialize() - n = 10 x = create_vector(; nrows_glo = n, autosetup = true) y = create_vector(; nrows_glo = n, autosetup = true) @@ -75,7 +70,5 @@ end _x = vec2array(x) @test _x[end] == 1.0 - destroy!.((x, y)) - - PetscFinalize() + destroy!(x, y) end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 8f78982..9d6c8f8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,8 +1,8 @@ using PetscWrap +using MPI using Test using LinearAlgebra - # from : # https://discourse.julialang.org/t/what-general-purpose-commands-do-you-usually-end-up-adding-to-your-projects/4889 @generated function compare_struct(x, y) @@ -13,9 +13,25 @@ using LinearAlgebra end end +""" +Custom way to "include" a file to print infos. +""" +function custom_include(path) + filename = split(path, "/")[end] + print("Running test file " * filename * "...") + include(path) + println("done.") +end + +MPI.Init() +PetscInitialize() +error("Bug : tests are not running anymore when using `test`") @testset "PetscWrap.jl" begin - include("./linear_system.jl") - include("./linear_system_fancy.jl") - include("./misc.jl") + custom_include("./linear_system.jl") + custom_include("./linear_system_fancy.jl") + custom_include("./misc.jl") end + +PetscFinalize() +MPI.Finalize() From d0aa2e08a9a7eac186a1e10b4c5e8e68ffcfa82d Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 22 Apr 2023 22:31:00 +0200 Subject: [PATCH 39/40] fake modif to trigger doc --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e66e6f6..90b0924 100644 --- a/README.md +++ b/README.md @@ -197,8 +197,7 @@ the julia GC will trigger a call to Petsc `destroy` to each object destroy.((ksp, A, b, x)) ``` -Finalize Petsc. This call is faculative : it will -be triggered automatically at the end of the script. +Finalize Petsc. This call is faculative : it will be triggered automatically at the end of the script. ```julia PetscFinalize() From b224ba70cf40577cf7504de0bd94829105f6c61c Mon Sep 17 00:00:00 2001 From: bmxam Date: Sat, 22 Apr 2023 22:36:15 +0200 Subject: [PATCH 40/40] fake commit