Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions docs/src/man/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ Since there are usually only a limited number of new or updated functions betwee

Make sure that the tests work!

#### Running the tests
The tests live in `test/`, one folder per group: `core` (initialization, handles, lifetimes, the API register), `vecmat`, `solvers`, `dm`, `lowlevel` (the generated `LibPETSc` wrappers), `regression`, `examples` (the scripts in `examples/` and the manual's examples) and `mpi` (files run on 4 ranks). A new test file goes in its group's folder and is listed in that group's block in `test/runtests.jl`.

The whole suite takes about 15 minutes. To run only some groups:

```julia
using Pkg
Pkg.test("PETSc"; test_args = ["dm", "mpi"])
```

#### Adding new functionality
Please open a pull request to add any of the above contributions.

Expand Down
6 changes: 3 additions & 3 deletions docs/src/man/naming.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ The names stay short, and the package pays for it with a convention rather than

```julia
d = dm(ksp) # not dm = dm(ksp)
s = snes(ts) # as test/ts.jl already writes it
s = snes(ts) # as test/solvers/ts.jl already writes it
k = ksp(ts)
```

Expand Down Expand Up @@ -649,7 +649,7 @@ Argument problems raise standard Julia exceptions. `@assert` is reserved for inv
| Library not initialized | `PetscNotInitialized` |
| Error returned by PETSc itself | `PetscError` (existing) |

Every high-level constructor that creates a PETSc object (`PetscVec`, `PetscMat`, `PetscOptions`, `KSP`, `SNES`, `TS` and the DM types) checks that its library is initialized before calling PETSc, so a missing `initialize` is reported as `PetscNotInitialized` and not as the `PetscError` PETSc would raise. `test/test_errors.jl` checks each of them. `PetscOptions` is included although PETSc's `PetscOptionsCreate` works before `PetscInitialize`: the object records the library's current `age`, `initialize` advances it, so an options database created first would already be stale and `destroy!` would skip it.
Every high-level constructor that creates a PETSc object (`PetscVec`, `PetscMat`, `PetscOptions`, `KSP`, `SNES`, `TS` and the DM types) checks that its library is initialized before calling PETSc, so a missing `initialize` is reported as `PetscNotInitialized` and not as the `PetscError` PETSc would raise. `test/core/errors.jl` checks each of them. `PetscOptions` is included although PETSc's `PetscOptionsCreate` works before `PetscInitialize`: the object records the library's current `age`, `initialize` advances it, so an options database created first would already be stale and `destroy!` would skip it.

```julia
length(A) == prod(sz) ||
Expand Down Expand Up @@ -765,7 +765,7 @@ The last row is policy with no instances, and that is the point of writing it do
### 17.3 Test coverage

The main test suite is converted to the new names, so CI exercises the API that ships.
`test/test_deprecations.jl` calls every shim and asserts the warning is emitted, and asserts a throw for any entry marked as an erroring stub. It is generated from `scripts/renames.jl` too, so a rename cannot land without its shim being covered.
`test/core/deprecations.jl` calls every shim and asserts the warning is emitted, and asserts a throw for any entry marked as an erroring stub. It is generated from `scripts/renames.jl` too, so a rename cannot land without its shim being covered.

### Rename table

Expand Down
2 changes: 2 additions & 0 deletions docs/src/man/tao_lowlevel.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Available through `TaoSetType`:
- `TAOBNTL`: Bound-constrained Newton trust-region
- `TAOTRON`: Trust-region Newton method

The types built on an LMVM matrix (`lmvm`, `blmvm`, `bncg`, `bqnls`, `bqnkls`, `bntl` and `bntr`) fail after a `PETSc.finalize`/`PETSc.initialize` cycle in which a `KSP` was created: PETSc 3.25 forgets the LMVM matrix types at `PetscFinalize` and has no public way to register them again, so `TaoSetType` throws with "Unknown Mat type given: lmvmbfgs". Initialize once per Julia session, or restart Julia. `cg`, `nm`, `nls`, `ntr`, `ntl` and `tron` are not affected.

- **Constrained**:
- `TAOALMM`: Augmented Lagrangian multiplier method
- `TAOIPM`: Interior point method
Expand Down
4 changes: 2 additions & 2 deletions examples/ex12_mpi_test.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# MPI subprocess tests for examples/ex12.jl.
# Picked up by test/examples.jl (plain Julia); each test internally spawns mpiexec.
# Picked up by test/examples/examples.jl (plain Julia); each test internally spawns mpiexec.
# Each test launches ex12.jl as an MPI subprocess and checks L² error.
#
# Run via:
# julia --project examples/ex12_mpi_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test
using MPI
Expand Down
2 changes: 1 addition & 1 deletion examples/ex12_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# Run via:
# julia --project examples/ex12_test.jl
# or through the project test suite (picked up automatically by test/examples.jl).
# or through the project test suite (picked up automatically by test/examples/examples.jl).

using Test

Expand Down
4 changes: 2 additions & 2 deletions examples/ex17_mpi_test.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# MPI subprocess tests for examples/ex17.jl.
# Picked up by test/examples.jl (plain Julia); each test internally spawns mpiexec.
# Picked up by test/examples/examples.jl (plain Julia); each test internally spawns mpiexec.
#
# Run via:
# julia --project examples/ex17_mpi_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test
using MPI
Expand Down
2 changes: 1 addition & 1 deletion examples/ex17_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# Run via:
# julia --project examples/ex17_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test

Expand Down
2 changes: 1 addition & 1 deletion examples/ex62_mpi_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#
# Run via:
# julia --project examples/ex62_mpi_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test
using MPI
Expand Down
2 changes: 1 addition & 1 deletion examples/ex62_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# Run via:
# julia --project examples/ex62_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test

Expand Down
2 changes: 1 addition & 1 deletion examples/ex69_mpi_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
# Run via:
# julia --project examples/ex69_mpi_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test
using MPI
Expand Down
2 changes: 1 addition & 1 deletion examples/ex69_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# Run via:
# julia --project examples/ex69_test.jl
# or through the project test suite (picked up by test/examples.jl).
# or through the project test suite (picked up by test/examples/examples.jl).

using Test

Expand Down
8 changes: 4 additions & 4 deletions scripts/generate_renames.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# src/deprecations.jl forwarding shims (§17)
# src/public_names.jl the `public` declaration (§13.1)
# src/audit_names.jl the name sets src/audit.jl matches against
# test/test_deprecations.jl one test per shim (§17.3)
# test/core/deprecations.jl one test per shim (§17.3)
#
# None of those four files is edited by hand.

Expand Down Expand Up @@ -263,7 +263,7 @@ the garbage collector rather than performing it, but the object is accounted for
end

# ---------------------------------------------------------------------------
# test/test_deprecations.jl
# test/core/deprecations.jl
# ---------------------------------------------------------------------------

function write_tests(path)
Expand Down Expand Up @@ -403,5 +403,5 @@ check_register()
write_deprecations(joinpath(ROOT, "src", "deprecations.jl"))
write_public(joinpath(ROOT, "src", "public_names.jl"))
write_audit_names(joinpath(ROOT, "src", "audit_names.jl"))
write_tests(joinpath(ROOT, "test", "test_deprecations.jl"))
println("wrote src/deprecations.jl, src/public_names.jl, src/audit_names.jl, test/test_deprecations.jl")
write_tests(joinpath(ROOT, "test", "core", "deprecations.jl"))
println("wrote src/deprecations.jl, src/public_names.jl, src/audit_names.jl, test/core/deprecations.jl")
4 changes: 2 additions & 2 deletions scripts/renames.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# src/deprecations.jl the forwarding shims (§17)
# src/public_names.jl the `public` declaration (§13.1)
# src/audit_names.jl the creator/destroyer name sets used by src/audit.jl
# test/test_deprecations.jl one test per shim (§17.3)
# test/core/deprecations.jl one test per shim (§17.3)
# (the rename table at the end of docs/src/man/naming.md)
#
# Run `julia --project=. scripts/generate_renames.jl` after editing.
Expand Down Expand Up @@ -273,7 +273,7 @@ const CUSTOM_SHIMS = Dict{Symbol, String}(
# These keep an argument the v0.5 signature no longer takes and warn when it is
# passed, so they cannot be expressed as `old => new`. They are emitted verbatim
# into src/deprecations.jl and removed with it in v0.6. `test` is a test body
# appended to test/test_deprecations.jl.
# appended to test/core/deprecations.jl.
# ---------------------------------------------------------------------------

const EXTRA_SHIMS = NamedTuple{(:name, :code, :test), Tuple{String, String, String}}[
Expand Down
7 changes: 0 additions & 7 deletions test/01-hello.jl

This file was deleted.

2 changes: 1 addition & 1 deletion test/test_api_surface.jl → test/core/api_surface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using Test
using PETSc

include(joinpath(@__DIR__, "..", "scripts", "api_surface.jl"))
include(joinpath(pkgdir(PETSc), "scripts", "api_surface.jl"))

@testset "api_surface --check" begin
absent = APISurface.unregistered()
Expand Down
4 changes: 2 additions & 2 deletions test/test_audit.jl → test/core/audit.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Test
using PETSc

const LEAKY = joinpath(@__DIR__, "fixtures", "leaky.jl")
const CONSTRUCTS = joinpath(@__DIR__, "fixtures", "constructs.jl")
const LEAKY = joinpath(dirname(@__DIR__), "fixtures", "leaky.jl")
const CONSTRUCTS = joinpath(dirname(@__DIR__), "fixtures", "constructs.jl")

@testset "audit_file" begin
report = PETSc.audit_file(LEAKY; verbose = false)
Expand Down
2 changes: 1 addition & 1 deletion test/bang_returns.jl → test/core/bang_returns.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/bang_returns.jl
# test/core/bang_returns.jl
# A `!` function returns the object it mutates (docs/src/man/naming.md §7), with
# the exceptions §7 lists: releases and package-state setters return `nothing`,
# and a do-block function returns the block's result.
Expand Down
2 changes: 1 addition & 1 deletion test/blas_threads.jl → test/core/blas_threads.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/blas_threads.jl
# test/core/blas_threads.jl
# PETSc's BLAS runs in Julia's OpenBLAS pool, so `-blas_num_threads` has to size
# that pool: PETSc's own setter cannot reach it.

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion test/test_destroy.jl → test/core/destroy.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/test_destroy.jl
# test/core/destroy.jl
# Destroying PETSc objects must stay safe in the awkward cases: a second
# explicit destroy!, and an object left over from an earlier
# initialize/finalize cycle.
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion test/handle_arrays.jl → test/core/handle_arrays.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/handle_arrays.jl
# test/core/handle_arrays.jl
# C arrays of handles: the vector a wrapper returns goes back to the matching
# release function, and a vector built in Julia is refused.

Expand Down
2 changes: 1 addition & 1 deletion test/handles.jl → test/core/handles.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/handles.jl
# test/core/handles.jl
# destroy! on the handles with no high-level layer (IS, AO, PF, Tao), and the
# ownership of the index sets ISColoringGetIS hands out.

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion test/lifetimes.jl → test/core/lifetimes.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/lifetimes.jl
# test/core/lifetimes.jl
# A Vec or Mat built on Julia arrays uses their memory without copying it, so the
# arrays must live as long as the PETSc object. Each test drops every Julia
# reference to the arrays, forces a collection and reuses the memory, then reads
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions test/petscbool.jl → test/core/petscbool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ MPI.Initialized() || MPI.Init()
@test Bool(LibPETSc.PETSC_FALSE) === false && Bool(LibPETSc.PETSC_TRUE) === true
@test LibPETSc.PetscBool(false) == LibPETSc.PETSC_FALSE

petsclib = PETSc.getlib()
petsclib = PETSc.petsclibs[1]
PETSc.initialize(petsclib)
# false answers must read as false, many times over (fresh Refs each call)
opts = LibPETSc.PetscOptions{typeof(petsclib)}()
Expand All @@ -36,7 +36,7 @@ end
# A sentinel goes into the byte after each flag, and is restored afterwards.
# The flags are not exported on Windows, so there is nothing to check there.
@testset "RegisterAllCalled reset writes one byte" begin
petsclib = PETSc.getlib()
petsclib = PETSc.petsclibs[1]
PETSc.initialize(petsclib)
handle, _ = PETSc.ensure_library_handle(petsclib)
lib = PETSc.library_ptr(handle)
Expand Down
43 changes: 43 additions & 0 deletions test/core/smoke.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# test/core/smoke.jl
# Vec, Mat, KSP and MatShell end to end on small problems, against Julia's own
# linear algebra: the quickest check that the library works at all.

using Test
using PETSc, MPI, LinearAlgebra, SparseArrays

MPI.Initialized() || MPI.Init()

@testset "Vec, Mat and KSP end to end" begin
petsclib = PETSc.petsclibs[1]
PETSc.initialize(petsclib)
PetscInt = petsclib.PetscInt
comm = MPI.COMM_SELF

n = 20
x = randn(n)
V = LibPETSc.VecCreateSeqWithArray(petsclib, comm, PetscInt(1), PetscInt(n), x)
@test norm(x) ≈ norm(V) rtol = 10eps()

S = sprand(n, n, 0.1) + I
M = PETSc.PetscMat(petsclib, comm, S)
@test norm(S) ≈ norm(M) rtol = 10eps()

vec_x = LibPETSc.VecCreateSeqWithArray(petsclib, comm, PetscInt(1), PetscInt(n), copy(x))
w = M * vec_x
@test w[:] ≈ S * x

ksp = PETSc.KSP(M; ksp_rtol = 1e-8, pc_type = "jacobi", ksp_monitor = false)
@test PETSc.type_name(ksp) === :gmres # the default
y = ksp \ w
@test S * y[:] ≈ w[:] rtol = 1e-6

# a matrix-free operator
f!(y, x) = y .= 2 .* x
shell = PETSc.MatShell(petsclib, f!, comm, 10, 10)
z = rand(10)
@test shell * z ≈ 2z
@test PETSc.KSP(shell) \ z ≈ z / 2

foreach(PETSc.destroy!, (ksp, shell, M, vec_x, V))
PETSc.finalize(petsclib)
end
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion test/dmnetwork.jl → test/dm/dmnetwork.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if !MPI.Initialized()
mpi_started = true
end
try
local petsclib = PETSc.getlib()
local petsclib = PETSc.petsclibs[1]
petsc_started = false
if !PETSc.isinitialized(petsclib)
PETSc.initialize(petsclib)
Expand Down
4 changes: 2 additions & 2 deletions test/dmplex.jl → test/dm/dmplex.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/dmplex.jl
# test/dm/dmplex.jl
# Tests for DMPlex (unstructured mesh) functionality.
# Covers both high-level PETSc.* wrappers and low-level LibPETSc.* calls.
# Runs across all available petsclibs (different PetscScalar/PetscInt combos).
Expand All @@ -16,7 +16,7 @@ MPI.Initialized() || MPI.Init()
# time, so they MUST be module-level names before the macros are invoked.
# We define them once for the Float64/Int64 lib that owns the FEM callbacks.

const _dmplex_petsclib = PETSc.getlib(PetscScalar = Float64)
const _dmplex_petsclib = PETSc.petsclibs[1]
PETSc.initialize(_dmplex_petsclib)

const PetscInt = _dmplex_petsclib.PetscInt
Expand Down
2 changes: 1 addition & 1 deletion test/dmproduct.jl → test/dm/dmproduct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if !MPI.Initialized()
mpi_started = true
end
try
local petsclib = PETSc.getlib()
local petsclib = PETSc.petsclibs[1]
petsc_started = false
if !PETSc.isinitialized(petsclib)
PETSc.initialize(petsclib)
Expand Down
2 changes: 1 addition & 1 deletion test/dmshell.jl → test/dm/dmshell.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using PETSc, MPI
mpi_started = true
end
try
local petsclib = PETSc.getlib()
local petsclib = PETSc.petsclibs[1]
petsc_started = false
if !PETSc.isinitialized(petsclib)
PETSc.initialize(petsclib)
Expand Down
5 changes: 5 additions & 0 deletions test/dmstag.jl → test/dm/dmstag.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# test/dm/dmstag.jl
# Creating 1D, 2D and 3D DMStags for every boundary combination, with the checks
# that hold on any number of ranks: runs serially and on 4 ranks. The exact values
# a single rank sees are in dmstag_serial.jl.

using Test
using PETSc, MPI
MPI.Initialized() || MPI.Init()
Expand Down
2 changes: 1 addition & 1 deletion test/dmstag_halos.jl → test/dm/dmstag_halos.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# test/dmstag_halos.jl
# test/dm/dmstag_halos.jl
# local_to_local! (in place and into another vector), the product coordinate
# do-block, and matrices preallocated without their nonzero pattern.

Expand Down
12 changes: 8 additions & 4 deletions test/test_dmstag.jl → test/dm/dmstag_serial.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# test/dm/dmstag_serial.jl
# DMStag on one rank, where sizes, entries, slots and vector positions have exact
# values: the LibPETSc getters, stencil get/set, array checkout, coordinates and
# matrices. Serial only; the checks that hold on any number of ranks are in dmstag.jl.

using Test
using PETSc, MPI, OffsetArrays
#using SparseArrays
MPI.Initialized() || MPI.Init()


@testset "DMStag All" begin
@testset "DMStag getters on one rank" begin

comm = MPI.COMM_WORLD
mpirank = MPI.Comm_rank(comm)
Expand Down Expand Up @@ -316,7 +320,7 @@ MPI.Initialized() || MPI.Init()
end
end

@testset "DMStagCreate1d" begin
@testset "DMStag 1D: boundary types, keywords, local indices" begin

comm = MPI.COMM_WORLD
mpirank = MPI.Comm_rank(comm)
Expand Down Expand Up @@ -435,7 +439,7 @@ end
end
end

@testset "DMStagCreate2d" begin
@testset "DMStag 2D: corners on one rank" begin

comm = MPI.COMM_WORLD
mpirank = MPI.Comm_rank(comm)
Expand Down
Loading
Loading