Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically wrapping with Clang.jl #149

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
e7a2b61
Format doc string function
Aug 4, 2021
2336629
Start to rework using Clang.jl generated wrappers
Jul 19, 2021
c85e8e8
Add back in options
Jul 19, 2021
8c17b12
Add back in vec.jl
Jul 19, 2021
32c044e
Add back in mat.jl
Jul 19, 2021
b25f87c
Add back matshell
Jul 19, 2021
90086fe
Remove some `getlibs`s and VecSeq->VecSeqWithArray
Jul 20, 2021
e5b9751
Add VecMPI
Jul 20, 2021
f814d21
Add VecGhost
Jul 20, 2021
105fb57
Add getpetsctype for vectors
Jul 20, 2021
922d74f
Update matshell and with_localarray name
Jul 21, 2021
a14f9e8
Clean up some function comments and names
Jul 21, 2021
a0013a4
Add a parallel matrix type and test
Jul 21, 2021
21d9e05
Update generator for KSP
Aug 3, 2021
6e7b0b7
Update options
Aug 4, 2021
c8b91b4
Add (basic) ksp functionality
Aug 4, 2021
208bd91
Update generator for DM
Aug 4, 2021
bb45f97
Fix generator for MatStencil
Aug 5, 2021
2924799
Add in basic dm and dmda functionality
Aug 5, 2021
2e708a9
Move old examples to "stale" folder
Aug 6, 2021
a605eb3
Move unused tests to "stale" folder
Aug 6, 2021
31c2286
Enable examples and mpi_examples testing
Aug 6, 2021
05da75f
Update MPI test output
Aug 6, 2021
2fb5c5d
Add a Julia sparse matrix to PETSc MatSeqAIJ
Aug 6, 2021
df23af1
Add function to get library with types
Aug 6, 2021
d59de98
Allow KSP with Julia vectors and SparseMatrixCSC
Aug 6, 2021
f6cb8d4
Add Laplacian example
Aug 6, 2021
94689e0
Add a petsc world age
Aug 7, 2021
9bf780e
Register finalizers based on MPI.Comm_size
Aug 7, 2021
5bc18bb
Update .gitignore
Aug 7, 2021
67e9d41
Update Project.toml
Aug 7, 2021
59c1f33
Disable dmda test with MPI and Windows
Aug 7, 2021
1edae83
Disable examples/laplacian.jl on windows
Aug 7, 2021
d0e01e8
Move to test/Project.toml
Aug 9, 2021
ad4e9aa
Allow for a Project.toml in examples
Aug 9, 2021
ef22f8c
Rework KSP a bit to simplify cases
Aug 9, 2021
0adc67c
Add KSP / DMDA interaction routines
Aug 10, 2021
c7e6d67
Update options parsing
Aug 10, 2021
b623b2f
Remove MPI.Init from precompile
Aug 11, 2021
2abbd8d
Add dmda_laplacian example
Aug 10, 2021
d3efdde
Remove some old dmda code
Aug 12, 2021
1e59f7c
All read/write tuples for withlocalarray!
Aug 12, 2021
19d9bb0
Add local and global vectors to DM
Aug 18, 2021
d6597fa
Partially add DM coord
Aug 18, 2021
caf1f70
Add view for DM
Aug 19, 2021
2675fd6
Fix up generator for SNES
Aug 12, 2021
ae24f14
Add back SNES functionality
Aug 20, 2021
7fdff85
Add better options parsing
Aug 31, 2021
208178c
Add coord and reshape utils to dmda
boriskaus Aug 31, 2021
2c7ff3d
Add SNES example (Liouville-Bratu-Gelfand equation)
Aug 20, 2021
fb8f5d4
Add copyto! between Julia and PETSc sparse matrix
boriskaus Aug 31, 2021
16d3fbf
Add porosity waves example
boriskaus Aug 31, 2021
581f379
Fix viewer for long output on stdout
Sep 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
deps/ComplexDouble/
deps/RealDouble/
deps/RealSingle/
deps/deps.jl
deps/petsc-*.tar.gz
*.jl.cov
*.jl.mem
*.swp
*.DS_Store
*~
docs/build/
docs/site/
Manifest.toml
Manifest.toml
12 changes: 1 addition & 11 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,11 @@ version = "0.1.3"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PETSc_jll = "8fa3689e-f0b9-5420-9873-adf6ccf46f2d"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[compat]
MPI = "0.15, 0.16, 0.17, 0.18, 0.19"
PETSc_jll = "3.15.2"
julia = "1.3"

[extras]
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
SparseDiffTools = "47a9eef4-7e08-11e9-0b38-333d64bd3804"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"

[targets]
test = ["ForwardDiff", "UnicodePlots", "Test", "Plots", "SparseDiffTools", "Printf"]
276 changes: 276 additions & 0 deletions examples/Liouville_Bratu_Gelfand.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
# INCLUDE IN MPI TEST
#=
In this example we solve the [Liouville–Bratu–Gelfand
equation](https://en.wikipedia.org/wiki/Liouville%E2%80%93Bratu%E2%80%93Gelfand_equation):
```math
∇² ψ + λ exp(ψ)
```
with zero Dirichlet boundary conditions.

To solve the problem we use the standard central, finite difference
approximation of the Laplacian in `d`-dimensions

This example is motivated by the following PETSc examples:
- [`snes/ex5`](https://petsc.org/release/src/snes/tutorials/ex5.c.html)
- [`snes/ex14`](https://petsc.org/release/src/snes/tutorials/ex14.c.html)
=#

using MPI
using PETSc
using OffsetArrays: OffsetArray
using LinearAlgebra: norm

opts = if !isinteractive()
PETSc.parse_options(ARGS)
else
(ksp_monitor = true, ksp_view = true)
end

# Set our MPI communicator
comm = MPI.COMM_WORLD

# Set our PETSc Scalar Type
PetscScalar = Float64

# get the PETSc lib with our chosen `PetscScalar` type
petsclib = PETSc.getlib(; PetscScalar = PetscScalar)

# Initialize PETSc
PETSc.initialize(petsclib)

# dimensionality of the problem
dim = haskey(opts, :dim) ? opts.dim : 3

# Set the total number of grid points in each direction
Nq = ntuple(_ -> 10, dim)

# Set the boundary conditions on each side
bcs = ntuple(_ -> PETSc.DM_BOUNDARY_NONE, dim)

# Set parameter
λ = PetscScalar(6)

# Create the PETSC dmda object
da = PETSc.DMDA(
petsclib,
comm,
bcs, # boundary conditions
Nq, # Global grid size
1, # Number of DOF per node
1, # Stencil width
PETSc.DMDA_STENCIL_STAR; # Stencil type
opts...,
)

# Create the PETSC snes object
snes = PETSc.SNES(petsclib, comm; opts...)

# add the da to the snes
PETSc.setDM!(snes, da)

# Set up the initial guess
x = PETSc.DMGlobalVec(da)
xl = PETSc.DMLocalVec(da)
PETSc.withlocalarray!(xl; read = false) do l_x
corners = PETSc.getcorners(da)

# Get the global grid dimensions
Nq = PETSc.getinfo(da).global_size

# Figure out the interior points
int_min = min(CartesianIndex(corners.size), CartesianIndex(2, 2, 2))
int_max = max(CartesianIndex(corners.size .- 1), CartesianIndex(1, 1, 1))
interior = (int_min):(int_max)

# Allows us to adress the local array with global indexing
ox = @view PETSc.reshapelocalarray(l_x, da)[1, :, :, :]

# Set up the global coordinates in each direction
# -1 to 1 when Nq > 1 and 0 otherwise
coords = map(
Nq ->
Nq == 1 ? range(PetscScalar(0), stop = 0, length = Nq) :
range(-PetscScalar(1), stop = 1, length = Nq),
Nq,
)

scaling = λ / (λ + 1)

# Loop over all the points on the processor and set the initial condition to
# be a hat function
for i in ((corners.lower):(corners.upper))
ox[i] =
scaling * sqrt(
min(
(1 - abs(coords[1][i[1]])),
(1 - abs(coords[2][i[2]])),
(1 - abs(coords[3][i[3]])),
),
)
end
end
PETSc.update!(x, xl, PETSc.INSERT_VALUES) # update local -> global

# Set up the nonlinear function
r = similar(x)
PETSc.setfunction!(snes, r) do g_fx, snes, g_x
# Get the DMDA associated with the snes
da = PETSc.getDMDA(snes)

# Get a local vector and transfer the data from the global vector into it
l_x = PETSc.DMLocalVec(da)
PETSc.update!(l_x, g_x, PETSc.INSERT_VALUES)

ghostcorners = PETSc.getghostcorners(da)
corners = PETSc.getcorners(da)

# Global grid size
Nq = PETSc.getinfo(da).global_size

# grid spacing in each dimension
Δx, Δy, Δz = PetscScalar(1) ./ Nq

# Get local arrays
PETSc.withlocalarray!(
(g_fx, l_x);
read = (false, true),
write = (true, false),
) do fx, x

# reshape the array and allow for global indexing
x = @view PETSc.reshapelocalarray(x, da)[1, :, :, :]
fx = @view PETSc.reshapelocalarray(fx, da)[1, :, :, :]

# Store a tuple of stencils in each direction
stencils = (
(
CartesianIndex(-1, 0, 0),
CartesianIndex(0, 0, 0),
CartesianIndex(1, 0, 0),
),
(
CartesianIndex(0, -1, 0),
CartesianIndex(0, 0, 0),
CartesianIndex(0, 1, 0),
),
(
CartesianIndex(0, 0, -1),
CartesianIndex(0, 0, 0),
CartesianIndex(0, 0, 1),
),
)
# Weights for each direction
weights = (Δy * Δz / Δx, Δx * Δz / Δy, Δx * Δy / Δz)

# loop over indices and set the function value
for ind in ((corners.lower):(corners.upper))
# If on the boundary just set equal to the incoming data
# otherwise apply the finite difference operator
if any(ntuple(j -> ind[j] == 1 || ind[j] == Nq[j], dim))
fx[ind] = x[ind]
else
# Apply the source
u = -Δx * Δy * Δz * λ * exp(x[ind])

# Apply the finite diffference stencil
for (s, w) in zip(stencils[1:dim], weights[1:dim])
u +=
w * (-x[ind + s[1]] + 2 * x[ind + s[2]] - x[ind + s[3]])
end
fx[ind] = u
end
end
end

# Clean up the local vector
PETSc.destroy(l_x)
return 0
end

J = PETSc.MatAIJ(da)
PETSc.setjacobian!(snes, J) do J, snes, g_x
# Get the DMDA associated with the snes
da = PETSc.getDMDA(snes)

# Get the corners of the points we own
corners = PETSc.getcorners(da)

# Global grid size
Nq = PETSc.getinfo(da).global_size

# grid spacing in each dimension
Δx, Δy, Δz = PetscScalar(1) ./ Nq

# Store a tuple of stencils in each direction
stencils = (
(
CartesianIndex(-1, 0, 0),
CartesianIndex(0, 0, 0),
CartesianIndex(1, 0, 0),
),
(
CartesianIndex(0, -1, 0),
CartesianIndex(0, 0, 0),
CartesianIndex(0, 1, 0),
),
(
CartesianIndex(0, 0, -1),
CartesianIndex(0, 0, 0),
CartesianIndex(0, 0, 1),
),
)
# Weights for each direction
weights = (Δy * Δz / Δx, Δx * Δz / Δy, Δx * Δy / Δz)

# Get a local array of the solution vector
PETSc.withlocalarray!(g_x; write = false) do l_x
# reshape so we can use multi-D indexing
x = @view PETSc.reshapelocalarray(l_x, da)[1, :, :, :]

# loop over indices and set the function value
for ind in ((corners.lower):(corners.upper))
# If on the boundary just set equal to the incoming data
# otherwise apply the finite difference operator
if any(ntuple(j -> ind[j] == 1 || ind[j] == Nq[j], dim))
J[ind, ind] = 1
else
# We accumulate the diagonal and add it at the end
Jii = -Δx * Δy * Δz * λ * exp(x[ind]) # Apply the source

# Apply the finite diffference stencil
for (s, w) in zip(stencils[1:dim], weights[1:dim])
Jii += w * 2
J[ind, ind + s[1]] = -w
J[ind, ind + s[3]] = -w
end
J[ind, ind] = Jii
end
end
end

# Assemble the Jacobian matrix
PETSc.assemble!(J)
return 0
end

if MPI.Comm_rank(comm) == 0
println(@elapsed(PETSc.solve!(x, snes)))
else
PETSc.solve!(x, snes)
end
g = similar(x)
snes.f!(g, snes, x)
nm = norm(g)
if MPI.Comm_rank(comm) == 0
@show nm
end

# Do some clean up
PETSc.destroy(J)
PETSc.destroy(x)
PETSc.destroy(g)
PETSc.destroy(r)
PETSc.destroy(da)
PETSc.destroy(snes)

PETSc.finalize(petsclib)
8 changes: 8 additions & 0 deletions examples/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[deps]
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
PETSc = "ace2c81b-2b5f-4b1e-a30d-d662738edfe0"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
SparseDiffTools = "47a9eef4-7e08-11e9-0b38-333d64bd3804"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
16 changes: 16 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# `PETSc.jl` Examples

The examples directory includes a `Project.toml` file. Since there is no
`Manifest.toml` when instantiated, this will use the latest released version of
`PETSc.jl`.

To use a specific branch, for example `main`, you should run
```sh
julia --project=examples -e "import Pkg; Pkg.add(name=\"PETSc\", rev=\"main\");"
```

If you are developing the repository you should run
```sh
julia --project=examples -e "import Pkg; Pkg.develop(path=@__DIR__);"
```
in order for your current developments to be used.
Loading