From 24cdb462231e9571b9a227a903978d65ae43ff5a Mon Sep 17 00:00:00 2001 From: Boris Kaus Date: Tue, 21 Apr 2026 22:11:03 +0200 Subject: [PATCH 1/7] add page for HPC (not finished) --- docs/make.jl | 1 + docs/src/man/hpc.md | 150 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 docs/src/man/hpc.md diff --git a/docs/make.jl b/docs/make.jl index ce7588be..e22029fb 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -47,6 +47,7 @@ makedocs(; "AO (Application Ordering)" => "man/ao_lowlevel.md", ], "Utilities" => "man/utilities.md", + "Running on HPC Systems" => "man/hpc.md", "FAQ" => "man/FAQ.md", "Contributing" => "man/contributing.md", "Funding" => "man/funding.md", diff --git a/docs/src/man/hpc.md b/docs/src/man/hpc.md new file mode 100644 index 00000000..36c92208 --- /dev/null +++ b/docs/src/man/hpc.md @@ -0,0 +1,150 @@ +# Running on HPC Systems + +PETSc.jl can be used on HPC clusters in two main configurations: using precompiled binaries via MPITrampoline, or by pointing to a locally installed PETSc build. + +## 1. Use precompiled binaries via MPITrampoline + +[MPITrampoline](https://github.com/eschnett/MPITrampoline) is an MPI wrapper layer that lets MPI-linked binaries be redirected to any system MPI at runtime. The `PETSc_jll` binaries distributed with PETSc.jl are built against MPITrampoline, which means they can be used on clusters by simply configuring `MPI.jl` to use the system MPI. + +#### Install MPITrampoline + +**Steps:** +1. Configure `MPI.jl` to use the system MPI (do this once per cluster): +```julia +using MPI +MPI.install_mpiexecjl() # optional: installs mpiexecjl wrapper +``` +Or set the environment variable before starting Julia: +```bash +export JULIA_MPI_BINARY=system +export JULIA_MPI_PATH=/path/to/system/mpi # e.g. /usr/lib/openmpi +``` + +2. Use PETSc.jl as normal — no changes to your script needed: +```julia +using PETSc, MPI +petsclib = PETSc.getlib(; PetscScalar = Float64, PetscInt = Int64) +PETSc.initialize(petsclib) +# ... +``` + +3. Launch via the cluster's MPI: +```bash +mpiexec -n 128 julia --project myScript.jl +``` +This is the easiest path for most clusters and requires no custom PETSc compilation. + +## Option 2: Locally installed PETSc build + +If you need a PETSc build with specific options (external packages, GPU support, custom BLAS, etc.), you can point PETSc.jl directly to your local installation. +The local PETSc must be compiled as a **shared library** (`--with-shared-libraries=1`) and linked against the **same MPI** that `MPI.jl` is configured to use. + +### Via environment variables (recommended for batch scripts) + +Set these before starting Julia: + +```bash +export JULIA_PETSC_LIBRARY=/path/to/petsc/install/lib/libpetsc.so +export JULIA_PETSC_SCALAR=Float64 # Float32 | ComplexFloat64 | ComplexFloat32 +export JULIA_PETSC_INT=Int64 # Int32 +``` + +With `JULIA_PETSC_LIBRARY` set, `PETSc_jll` is **not** loaded or precompiled, which +avoids MPI incompatibility issues common on HPC clusters. + +### Via `set_petsclib` (recommended for scripts) + +```julia +using PETSc, MPI + +petsclib = PETSc.set_petsclib( + "/path/to/petsc/install/lib/libpetsc.so"; + PetscScalar = Float64, + PetscInt = Int64 +) +PETSc.initialize(petsclib) +# ... your code ... +PETSc.finalize(petsclib) +``` + +To prevent `PETSc_jll` from being precompiled at all (which can fail on clusters +with incompatible MPI), set: +```bash +export JULIA_PETSC_SKIP_JLL=1 +``` + +### Typical HPC job script + +```bash +#!/bin/bash +#SBATCH --nodes=8 +#SBATCH --ntasks-per-node=128 + +module load PETSc/3.22.0-foss-2023b + +export JULIA_PETSC_SKIP_JLL=1 + +srun julia --project ex45.jl \ + -N 257 \ + -ksp_type cg \ + -pc_type mg \ + -pc_mg_levels 5 \ + -mg_levels_ksp_type chebyshev \ + -mg_levels_pc_type sor \ + -ksp_rtol 1e-8 \ + -ksp_view \ + -pc_mg_log \ + -log_view +``` + +--- + +## Performance and Weak Scalability + +This section summarises weak scalability results for the 3D Laplacian benchmark ([`ex45.jl`](https://github.com/JuliaParallel/PETSc.jl/blob/main/examples/ex45.jl)) using a CG solver with geometric multigrid preconditioning (`-pc_type mg`). The problem size is scaled proportionally with the number of MPI ranks so that the work per rank stays constant. + +### Setup + +- Problem: 3D Poisson equation on a uniform grid, solved with CG + geometric MG +- Grid size per rank: ~65³ degrees of freedom +- Solver: `-ksp_type cg -pc_type mg -pc_mg_levels 4 -ksp_rtol 1e-8` +- Machine: *[HPC system name, node type, interconnect]* + +### a) PETSc.jl with precompiled `PETSc_jll` binaries + +*Results to be added.* + +| Ranks | Grid size | Solve time (s) | KSP iterations | +|------:|----------:|---------------:|---------------:| +| 1 | 65³ | — | — | +| 8 | 130³ | — | — | +| 64 | 260³ | — | — | +| 512 | 520³ | — | — | + +### b) PETSc.jl linked against a local PETSc build (system MPI) + +*Results to be added.* + +| Ranks | Grid size | Solve time (s) | KSP iterations | +|------:|----------:|---------------:|---------------:| +| 1 | 65³ | — | — | +| 8 | 130³ | — | — | +| 64 | 260³ | — | — | +| 512 | 520³ | — | — | + +### c) Native C build (`ex45.c`) + +The equivalent PETSc C example compiled natively, serving as the baseline. + +*Results to be added.* + +| Ranks | Grid size | Solve time (s) | KSP iterations | +|------:|----------:|---------------:|---------------:| +| 1 | 65³ | — | — | +| 8 | 130³ | — | — | +| 64 | 260³ | — | — | +| 512 | 520³ | — | — | + +### Observations + +*To be filled in once results are available.* From 6e9573b54370d8898fa315caabd9acc06dcc525b Mon Sep 17 00:00:00 2001 From: Boris Kaus Date: Tue, 21 Apr 2026 22:11:35 +0200 Subject: [PATCH 2/7] update ex45 --- examples/ex45.jl | 200 ++++++++++++++++++++++------------------------- 1 file changed, 95 insertions(+), 105 deletions(-) diff --git a/examples/ex45.jl b/examples/ex45.jl index 7d29ac57..295b3ffa 100644 --- a/examples/ex45.jl +++ b/examples/ex45.jl @@ -7,21 +7,18 @@ exact(x, y, z) = sin(2π * x) * sin(2π * y) * sin(2π * z) # The discrete operator is -∇², so forcing = -∇²(exact) # For exact(x,y,z) = sin(2πx)sin(2πy)sin(2πz), we have ∇²u = -3(2π)²sin(2πx)sin(2πy)sin(2πz) # So forcing = -∇²u = 12π²sin(2πx)sin(2πy)sin(2πz) -forcing(x, y, z) = 12 * π^2 * sin(2π * x) * sin(2π * y) * sin(2π * z) +forcing(x, y, z) = 12 * π^2 * sin(2π * x) * sin(2π * y) * sin(2π * z) # Get the PETSc lib with our chosen `PetscScalar` type petsclib = PETSc.getlib(; PetscScalar = Float64) # Initialize PETSc -PETSc.initialize(petsclib) +PETSc.initialize(petsclib, log_view=true) function solve_ex45(N=7; da_grid_x=7, da_grid_y=7, da_grid_z=7, kwargs...) comm = MPI.COMM_WORLD - # Parse command-line options and merge with keyword arguments passed - # programmatically. Keyword args take precedence over CLI. - cli_opts = PETSc.parse_options(ARGS) # NamedTuple - # Build a flexible Dict{Symbol,Any} to allow merging CLI and kwargs + cli_opts = PETSc.parse_options(ARGS) cli = Dict{Symbol,Any}() for (k, v) in pairs(cli_opts) cli[k] = v @@ -30,11 +27,6 @@ function solve_ex45(N=7; da_grid_x=7, da_grid_y=7, da_grid_z=7, kwargs...) cli[k] = v end - # Default RHS: continuous analytic forcing (scaled by cell volume) - # We keep CLI/kwargs simple — any specific forcing-mode option was - # removed: continuous mode is now the only behavior. - - # Determine N (keyword/arg default overridden by CLI/kwargs) function _as_int(x, default) if x === nothing return default @@ -45,76 +37,81 @@ function solve_ex45(N=7; da_grid_x=7, da_grid_y=7, da_grid_z=7, kwargs...) end end - N = _as_int(get(cli, :N, N), N) - dim = _as_int(get(cli, :dim, 3), 3) + N = _as_int(get(cli, :N, N), N) + dim = _as_int(get(cli, :dim, 3), 3) + Nx = _as_int(get(cli, :Nx, N), N) + Ny = _as_int(get(cli, :Ny, N), N) + Nz = _as_int(get(cli, :Nz, N), N) - # Re-pack merged options into a NamedTuple for keyword splatting opts = (; [(k => cli[k]) for k in keys(cli)]...) - # Create a 3D DMDA (defaults 7x7x7 like the C example) - boundary = Tuple(fill(PETSc.DM_BOUNDARY_NONE,dim)) - stencil = PETSc.DMDA_STENCIL_STAR - global_size = Tuple(fill(N,dim)) - # Pass parsed opts into DMDA so other DM options are applied + boundary = Tuple(fill(PETSc.DM_BOUNDARY_NONE, dim)) + stencil = PETSc.DMDA_STENCIL_STAR + global_size = dim == 3 ? (Nx, Ny, Nz) : (Nx, Ny, 1) da = PETSc.DMDA(petsclib, comm, boundary, global_size, 1, 1, stencil; opts...) - # Print fine grid resolution at start (only on rank 0) final_grid = PETSc.getinfo(da).global_size if MPI.Comm_rank(comm) == 0 @printf("Solving on %d × %d × %d grid\n", final_grid[1], final_grid[2], final_grid[3]) end - # Create KSP tied to DM and pass parsed PETSc options so - # command-line flags (e.g. -ksp_monitor) are applied like in `ex50.jl` ksp = PETSc.KSP(da; opts...) - # Set compute operators (matrix assembly) and RHS PETSc.setcomputeoperators!(ksp) do J, jac, ksp - dm = PETSc.getDM(ksp) + dm = PETSc.getDM(ksp) corners = PETSc.getcorners(dm) - info = PETSc.getinfo(dm) - N = info.global_size - - Hx,Hy,Hz = 1.0 ./ (N .- 1) - HxHydHz = Hx * Hy / Hz - HxHzdHy = Hx * Hz / Hy - HyHzdHx = Hy * Hz / Hx + info = PETSc.getinfo(dm) + N = info.global_size + + # Grid spacings (uniform) + Hx, Hy, Hz = 1.0 ./ (N .- 1) + + # Scale entire system by Hx*Hy*Hz (= h³ for uniform grid) so that + # matrix entries are O(h) ~ O(1/N) rather than O(1/h²) ~ O(N²). + # This keeps MG smoothers well-conditioned regardless of resolution. + # + # Scaled operator: (Hx*Hy*Hz) * (-∇²_h) + # For uniform h: scaled diagonal = 6h³/h² = 6h + # scaled off-diag = -h³/h² = -h + # All entries O(h) → matrix is well-scaled for MG. + scale = Hx * Hy * Hz + + # Scaled coefficients + cx = scale / (Hx * Hx) # = Hy*Hz/Hx + cy = scale / (Hy * Hy) # = Hx*Hz/Hy + cz = scale / (Hz * Hz) # = Hx*Hy/Hz + diag3d = 2.0 * (cx + cy + cz) + diag2d = 2.0 * (cx + cy) - HxdHy = Hx / Hy - HydHx = Hy / Hx for k in corners.lower[3]:corners.upper[3] for j in corners.lower[2]:corners.upper[2] for i in corners.lower[1]:corners.upper[1] idx = CartesianIndex(i, j, k) - # boundary check (global indices start at 1 here) - is_boundary = (i == 1 || j == 1 || k == 1 || i == N[1] || j == N[2] || k == N[3]) - if dim==3 + is_boundary = (i == 1 || j == 1 || k == 1 || + i == N[1] || j == N[2] || k == N[3]) + if dim == 3 if is_boundary - # Dirichlet BC: set row to identity jac[idx, idx] = 1.0 else - jac[idx, idx + CartesianIndex(0,-1,0)] = -HxHzdHy - jac[idx, idx + CartesianIndex(-1,0,0)] = -HyHzdHx - jac[idx, idx] = 2.0 * (HxHydHz + HxHzdHy + HyHzdHx) - jac[idx, idx + CartesianIndex(1,0,0)] = -HyHzdHx - jac[idx, idx + CartesianIndex(0,1,0)] = -HxHzdHy - jac[idx, idx + CartesianIndex(0,0,-1)] = -HxHydHz - jac[idx, idx + CartesianIndex(0,0,1)] = -HxHydHz + jac[idx, idx + CartesianIndex(-1, 0, 0)] = -cx + jac[idx, idx + CartesianIndex( 1, 0, 0)] = -cx + jac[idx, idx + CartesianIndex( 0, -1, 0)] = -cy + jac[idx, idx + CartesianIndex( 0, 1, 0)] = -cy + jac[idx, idx + CartesianIndex( 0, 0, -1)] = -cz + jac[idx, idx + CartesianIndex( 0, 0, 1)] = -cz + jac[idx, idx] = diag3d end - elseif dim==2 + elseif dim == 2 if is_boundary - # Dirichlet BC: set row to identity jac[idx, idx] = 1.0 else - # Interior point - full 5-point stencil - jac[idx, idx + CartesianIndex(0, -1, 0)] = -HxdHy - jac[idx, idx + CartesianIndex(-1, 0, 0)] = -HydHx - jac[idx, idx] = 2.0 * (HxdHy + HydHx) - jac[idx, idx + CartesianIndex(1, 0, 0)] = -HydHx - jac[idx, idx + CartesianIndex(0, 1, 0)] = -HxdHy + jac[idx, idx + CartesianIndex(-1, 0, 0)] = -cx + jac[idx, idx + CartesianIndex( 1, 0, 0)] = -cx + jac[idx, idx + CartesianIndex( 0,-1, 0)] = -cy + jac[idx, idx + CartesianIndex( 0, 1, 0)] = -cy + jac[idx, idx] = diag2d end end - end end end @@ -123,84 +120,78 @@ function solve_ex45(N=7; da_grid_x=7, da_grid_y=7, da_grid_z=7, kwargs...) end PETSc.setcomputerhs!(ksp) do b_vec, ksp - dm = PETSc.getDM(ksp) + dm = PETSc.getDM(ksp) corners = PETSc.getcorners(dm) - info = PETSc.getinfo(dm) - N = info.global_size + info = PETSc.getinfo(dm) + N = info.global_size - Hx,Hy,Hz = 1.0 ./ (N .- 1) - HxHydHz = Hx * Hy / Hz - HxHzdHy = Hx * Hz / Hy - HyHzdHx = Hy * Hz / Hx + Hx, Hy, Hz = 1.0 ./ (N .- 1) + scale = Hx * Hy * Hz # same scaling as matrix g_x = range(0, length = N[1], stop = 1) g_y = range(0, length = N[2], stop = 1) g_z = range(0, length = N[3], stop = 1) - + l_x = g_x[(corners.lower[1]):(corners.upper[1])] l_y = g_y[(corners.lower[2]):(corners.upper[2])] l_z = g_z[(corners.lower[3]):(corners.upper[3])] - - PETSc.withlocalarray!(b_vec; read=false) do b - # reshape into local block (xm, ym, zm) - N = corners.size; - #nx = Int(corners.size[1]); ny = Int(corners.size[2]); nz = Int(corners.size[3]) - if dim==3 - #is_boundary = (x == 1 || y == 1 || x == global_size[1] || y == global_size[2]) - b3 = reshape(b, N...) - for kk = 1:N[3], jj = 1:N[2], ii = 1:N[1] - # global indices - x,y,z = l_x[ii], l_y[jj], l_z[kk] + PETSc.withlocalarray!(b_vec; read=false) do b + sz = corners.size + if dim == 3 + b3 = reshape(b, sz...) + for kk = 1:sz[3], jj = 1:sz[2], ii = 1:sz[1] + x, y, z = l_x[ii], l_y[jj], l_z[kk] gi = corners.lower[1] + (ii - 1) gj = corners.lower[2] + (jj - 1) gk = corners.lower[3] + (kk - 1) - if gi == 1 || gj == 1 || gk == 1 || gi == N[1] || gj == N[2] || gk == N[3] - # Dirichlet BC: RHS is analytic boundary value + if gi == 1 || gj == 1 || gk == 1 || + gi == N[1] || gj == N[2] || gk == N[3] + # Dirichlet BC: identity row in matrix → RHS = exact value b3[ii, jj, kk] = exact(x, y, z) else - # Continuous forcing (default): analytic -∇² evaluated - # at the point and scaled by the cell volume so the - # RHS uses the same quadrature scaling as the matrix. - vol_cell = Hx * Hy * Hz - b3[ii, jj, kk] = forcing(x, y, z) * vol_cell + # Scale forcing by same factor as matrix + b3[ii, jj, kk] = forcing(x, y, z) * scale + end + end + elseif dim == 2 + b2 = reshape(b, sz...) + for jj = 1:sz[2], ii = 1:sz[1] + x, y = l_x[ii], l_y[jj] + gi = corners.lower[1] + (ii - 1) + gj = corners.lower[2] + (jj - 1) + if gi == 1 || gj == 1 || gi == N[1] || gj == N[2] + b2[ii, jj, 1] = exact(x, y, 0.0) + else + b2[ii, jj, 1] = forcing(x, y, 0.0) * scale end end - else - end - end PETSc.assemble!(b_vec) return 0 end - # Time the solve so callers can inspect runtime solve_time = @elapsed PETSc.solve!(ksp) - - # Number of outer KSP iterations - niter = LibPETSc.KSPGetIterationNumber(petsclib, ksp) - - # Final (fine) grid resolution + niter = LibPETSc.KSPGetIterationNumber(petsclib, ksp) final_grid = PETSc.getinfo(da).global_size - # Get the residual norm - x = LibPETSc.KSPGetSolution(petsclib, ksp) + x = LibPETSc.KSPGetSolution(petsclib, ksp) norm = LibPETSc.KSPGetResidualNorm(petsclib, ksp) - # Compute L2 and max error against analytic solution `exact(x,y,z)` - info = PETSc.getinfo(da) + # Compute L2 and max error against analytic solution + info = PETSc.getinfo(da) Nglob = info.global_size - Hx,Hy,Hz = 1.0 ./ (Nglob .- 1) + Hx, Hy, Hz = 1.0 ./ (Nglob .- 1) vol = Hx * Hy * Hz local_err2 = 0.0 - local_max = 0.0 + local_max = 0.0 PETSc.withlocalarray!(x; read=true) do xu corners = PETSc.getcorners(da) - dims = corners.size - uas = reshape(xu, dims...) + dims = corners.size + uas = reshape(xu, dims...) for kk = 1:dims[3], jj = 1:dims[2], ii = 1:dims[1] gi = corners.lower[1] + (ii - 1) gj = corners.lower[2] + (jj - 1) @@ -209,15 +200,15 @@ function solve_ex45(N=7; da_grid_x=7, da_grid_y=7, da_grid_z=7, kwargs...) yc = (gj - 1) * Hy zc = (gk - 1) * Hz u_num = uas[ii, jj, kk] - u_ex = exact(xc, yc, zc) - err = u_num - u_ex + u_ex = exact(xc, yc, zc) + err = u_num - u_ex local_err2 += err^2 * vol - local_max = max(local_max, abs(err)) + local_max = max(local_max, abs(err)) end end global_err2 = MPI.Allreduce(local_err2, MPI.SUM, comm) - global_max = MPI.Allreduce(local_max, MPI.MAX, comm) + global_max = MPI.Allreduce(local_max, MPI.MAX, comm) L2 = sqrt(global_err2) if MPI.Comm_rank(MPI.COMM_WORLD) == 0 @@ -227,21 +218,20 @@ function solve_ex45(N=7; da_grid_x=7, da_grid_y=7, da_grid_z=7, kwargs...) @printf("Solve time: %.6f seconds\n", solve_time) end - # Clean up PETSc.destroy(ksp) - return (;norm,final_grid,niter,solve_time,L2,global_max) + return (; norm, final_grid, niter, solve_time, L2, global_max) end if !isinteractive() && abspath(PROGRAM_FILE) == @__FILE__ res = solve_ex45() - # res is a NamedTuple: (norm, final_grid, niter, solve_time, L2, max) if MPI.Comm_rank(MPI.COMM_WORLD) == 0 @printf("Final residual norm %g\n", res.norm) - @printf("Fine grid resolution: %d × %d × %d\n", res.final_grid[1], res.final_grid[2], res.final_grid[3]) + @printf("Fine grid resolution: %d × %d × %d\n", + res.final_grid[1], res.final_grid[2], res.final_grid[3]) @printf("Outer KSP iterations: %d\n", res.niter) @printf("Solve time: %.6f seconds\n", res.solve_time) @printf("L2 error: %.6e\n", res.L2) @printf("Max error: %.6e\n", res.global_max) end PETSc.finalize(petsclib) -end +end \ No newline at end of file From 9dae2c057829c024cd518f06b0fd34f14d5dc5bc Mon Sep 17 00:00:00 2001 From: Boris Kaus Date: Wed, 22 Apr 2026 09:22:24 +0200 Subject: [PATCH 3/7] split getting started into installation and getting started --- docs/make.jl | 1 + docs/src/man/getting_started.md | 61 +++++---------------------------- docs/src/man/installation.md | 49 ++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 53 deletions(-) create mode 100644 docs/src/man/installation.md diff --git a/docs/make.jl b/docs/make.jl index e22029fb..17f7c94f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,6 +12,7 @@ makedocs(; ), pages=[ "Home" => "index.md", + "Installation" => "man/installation.md", "Getting Started" => "man/getting_started.md", "High-level interface" => Any[ "Vec" => "man/vec.md", diff --git a/docs/src/man/getting_started.md b/docs/src/man/getting_started.md index bb0c799a..6e42a01e 100644 --- a/docs/src/man/getting_started.md +++ b/docs/src/man/getting_started.md @@ -1,55 +1,10 @@ # Getting started +- [1. Solving a linear system of equations](#1-solving-a-linear-system-of-equations) +- [2. Nonlinear example](#2-nonlinear-example) +- [3. Next steps](#3-next-steps) -- [Getting started](#getting-started) - - [1a. Installation using pre-built libraries](#1a-installation-using-pre-built-libraries) - - [1b. Installation using a custom PETSc build](#1b-installation-using-a-custom-petsc-build) - - [2. Solving a linear system of equations](#2-solving-a-linear-system-of-equations) - - [3. Nonlinear example](#3-nonlinear-example) - - [4. Next steps](#4-next-steps) - -### 1a. Installation using pre-built libraries -The easiest way to install the package is: -```julia -julia> ] -(@v1.12) pkg> add PETSc -``` -which will install a pre-built PETSc library (`PETSc_jll`) as well as `MPI.jl` on your system. This will work both in serial and in parallel on your machine. - -!!! warning "Windows Users" - The prebuild binaries currently do not work on Windows as we had to build `PETSc_jll` without MPI due to compatibility issues with `MicrosoftMPI_jll`. - - **Windows users are therefore advised to install the [Windows Subsystem for Linux](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux) (WSL) and run PETSc.jl from within WSL.** This will provide full functionality with both serial and parallel (MPI) support. - -### 1b. Installation using a custom PETSc build -Sometimes, you may be interested in a PETSc installation that comes with additional external packages, or that you compiled yourself. Ensure the library is compiled as a **dynamic** (not static) library. - -Use `set_library!` to configure the path once — it is stored in `LocalPreferences.toml` and no environment variables are needed afterwards: - -```julia -using PETSc -PETSc.set_library!( - "/path/to/custom/libpetsc.so"; - PetscScalar = Float64, - PetscInt = Int64, -) -# Restart Julia — PETSc_jll is not loaded and your library is used automatically. -``` - -To revert to the bundled binaries: `PETSc.unset_library!()`. - -For a one-off session without changing persistent settings, use `set_petsclib` directly: - -```julia -petsclib = PETSc.set_petsclib("/path/to/custom/libpetsc.so"; - PetscScalar=Float64, PetscInt=Int64) -PETSc.initialize(petsclib, log_view=true) -# ... your code ... -PETSc.finalize(petsclib) -``` - - -### 2. Solving a linear system of equations +### 1. Solving a linear system of equations Lets consider the following elliptic equation: ```math @@ -202,7 +157,7 @@ This is important information that helps PETSc to distribute the problem over se PETSc uses the `DM` infrastructure for such cases. `DMDA` is for (collocated) finite differences, `DMStag` for staggered finite differences, `DMPlex` for finite element/finite volume discretisations and `DMForest` for adaptive mesh refinement problems. If possible, use this infrastructure as it simplifies your life. Have a look at the [examples](https://github.com/JuliaParallel/PETSc.jl/tree/main/examples) or [tests](https://github.com/JuliaParallel/PETSc.jl/tree/main/test) of `PETSc.jl`. -### 3. Nonlinear example +### 2. Nonlinear example Let's solve the coupled system of nonlinear equations: ```math \begin{aligned} @@ -285,8 +240,8 @@ julia> PETSc.finalize(petsclib) ``` -### 4. Next steps -Now that you have the basics, ypu can start playing with some more complete examples. +### 3. Next steps +Now that you have the basics, you can start playing with some more complete examples. Here some suggestions: 1. [laplacian.jl](https://github.com/JuliaParallel/PETSc.jl/blob/main/examples/laplacian.jl) - simple (non-parallel) laplacian example using Julia sparse matrixes 2. [dmda_laplacian.jl](https://github.com/JuliaParallel/PETSc.jl/blob/main/examples/dmda_laplacian.jl) - 2D laplacian example with Dirichlet boundary conditions using the `DMDA` framework. Examples are given on how to run it with various (multigrid) solvers. @@ -300,4 +255,4 @@ Working through those examples should give you a fair idea of how to use PETSc. If you have further questions, please have a look at the [test](https://github.com/JuliaParallel/PETSc.jl/tree/main/test) directory; this is run automatically every time we make a new commit, and we do our best to keep it working. -Furthermore, the left menu gives additional instructions on how to use the low-level interface. \ No newline at end of file +Furthermore, the left menu gives additional instructions on how to use the low-level interface. diff --git a/docs/src/man/installation.md b/docs/src/man/installation.md new file mode 100644 index 00000000..e12d659b --- /dev/null +++ b/docs/src/man/installation.md @@ -0,0 +1,49 @@ +# Installation + +## Using pre-built libraries + +The easiest way to install the package is: +```julia +julia> ] +(@v1.12) pkg> add PETSc +``` +which will install a pre-built PETSc library (`PETSc_jll`) as well as `MPI.jl` on your system. This will work both in serial and in parallel on your machine. + +!!! warning "Windows Users" + The prebuild binaries currently do not work on Windows as we had to build `PETSc_jll` without MPI due to compatibility issues with `MicrosoftMPI_jll`. + + **Windows users are therefore advised to install the [Windows Subsystem for Linux](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux) (WSL) and run PETSc.jl from within WSL.** This will provide full functionality with both serial and parallel (MPI) support. + +## Using a custom PETSc build + +Sometimes, you may be interested in a PETSc installation that comes with additional external packages, or that you compiled yourself. Ensure the library is compiled as a **dynamic** (not static) library. + +Use `set_library!` to configure the path once — it is stored in `LocalPreferences.toml` and no environment variables are needed afterwards: + +```julia +using PETSc +PETSc.set_library!( + "/path/to/custom/libpetsc.so"; + PetscScalar = Float64, + PetscInt = Int64, +) +# Restart Julia — PETSc_jll is not loaded and your library is used automatically. +``` + +To revert to the bundled binaries: `PETSc.unset_library!()`. + +To check what is currently configured: `PETSc.library_info()`. + +For a one-off session without changing persistent settings, use `set_petsclib` directly: + +```julia +petsclib = PETSc.set_petsclib("/path/to/custom/libpetsc.so"; + PetscScalar=Float64, PetscInt=Int64) +PETSc.initialize(petsclib, log_view=true) +# ... your code ... +PETSc.finalize(petsclib) +``` + +## HPC systems + +On many high-performance clusters, you will need to use the cluster's MPI installation. There are a number of options to do so - see the [Running on HPC Systems](hpc.md) page for details. From c5cbbf2077abcab51da5ffdc9f762923027f1aa7 Mon Sep 17 00:00:00 2001 From: Boris Kaus Date: Wed, 22 Apr 2026 21:51:52 +0200 Subject: [PATCH 4/7] docs on how to run on HPC --- .../src/assets/img/weak_scaling_ex45_LUMI.png | Bin 0 -> 137567 bytes docs/src/man/hpc.md | 303 +++++++++++++----- examples/ex45.jl | 14 + examples/scalability_tests/ex45_julia.c | 264 +++++++++++++++ examples/scalability_tests/job.sh | 77 +++++ examples/scalability_tests/makefile | 24 ++ examples/scalability_tests/parse_scaling.jl | 246 ++++++++++++++ examples/scalability_tests/submit_scaling.sh | 49 +++ 8 files changed, 900 insertions(+), 77 deletions(-) create mode 100644 docs/src/assets/img/weak_scaling_ex45_LUMI.png create mode 100644 examples/scalability_tests/ex45_julia.c create mode 100644 examples/scalability_tests/job.sh create mode 100644 examples/scalability_tests/makefile create mode 100644 examples/scalability_tests/parse_scaling.jl create mode 100644 examples/scalability_tests/submit_scaling.sh diff --git a/docs/src/assets/img/weak_scaling_ex45_LUMI.png b/docs/src/assets/img/weak_scaling_ex45_LUMI.png new file mode 100644 index 0000000000000000000000000000000000000000..4a737f2dffdb963edf767e9ff2e0f9154d2f7762 GIT binary patch literal 137567 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℘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

  • eXpXii0Rj#$SVjD{&p(ab3T~ffCLy5d9K- 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 literal 0 HcmV?d00001 diff --git a/docs/src/man/hpc.md b/docs/src/man/hpc.md index 36c92208..a10b5b9b 100644 --- a/docs/src/man/hpc.md +++ b/docs/src/man/hpc.md @@ -4,23 +4,82 @@ PETSc.jl can be used on HPC clusters in two main configurations: using precompil ## 1. Use precompiled binaries via MPITrampoline -[MPITrampoline](https://github.com/eschnett/MPITrampoline) is an MPI wrapper layer that lets MPI-linked binaries be redirected to any system MPI at runtime. The `PETSc_jll` binaries distributed with PETSc.jl are built against MPITrampoline, which means they can be used on clusters by simply configuring `MPI.jl` to use the system MPI. +The main reason that it is challenging to run applications on HPC systems is that MPI is implemented in a different way by different vendors. This will change in the future as there is now the MPI ABI (application Binary Interface) and our precompiled PETSc binaries are already compatible with that. -#### Install MPITrampoline +Yet, until all MPI implementations fully support this, we recommend using [MPITrampoline](https://github.com/eschnett/MPITrampoline) instead, which is a MPI wrapper layer that lets MPI-linked binaries be redirected to any system MPI at runtime. The `PETSc_jll` binaries distributed with PETSc.jl are built against MPITrampoline, which means they can be used on clusters by simply configuring `MPI.jl` to use the system MPI. +Doing this requires you to compile a small code on the HPC system that is linked versus the local MPI implementation. -**Steps:** -1. Configure `MPI.jl` to use the system MPI (do this once per cluster): -```julia -using MPI -MPI.install_mpiexecjl() # optional: installs mpiexecjl wrapper +Here step-by-step instructions (for Linux, as that is what essentially all HPC systems use): + +#### 1.1 Install MPIwrapper + +* Download [MPIwrapper](https://github.com/eschnett/MPIwrapper): +```bash +git clone https://github.com/eschnett/MPIwrapper.git +cd MPIwrapper ``` -Or set the environment variable before starting Julia: + +* Install it after making sure that `mpiexec` points to the one you want (you may have to load some modules, depending on your system): ```bash -export JULIA_MPI_BINARY=system -export JULIA_MPI_PATH=/path/to/system/mpi # e.g. /usr/lib/openmpi +cmake -S . -B build -DMPIEXEC_EXECUTABLE=/full/path/to/mpiexec -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=$HOME/mpiwrapper +cmake --build build +cmake --install build +``` +> [!IMPORTANT] +> You need to specify the full path to `mpiexec` (or equivalent, such as `srun` or `mpirun`, depending oin your system) and not just the name. If you don't know that, you can determine this with +> `which mpiexec` + +At this stage, `MPIwrapper` is installed in `$HOME/mpiwrapper` + +#### 1.2 Set the correct wrappers +Next, you need to specify these environmental variables: +``` +export MPITRAMPOLINE_LIB=$HOME/mpiwrapper/lib64/libmpiwrapper.so +export MPITRAMPOLINE_MPIEXEC=$HOME/MPIwrapper/mpiwrapper/bin/mpiwrapperexec +``` +Depending on the system it may be called `lib` instead of `lib64` (check!). + + +#### 1.3 Install the `MPI` and `MPIPreferences` packages: +Install packages the usual way: +```julia +julia +julia> ] +pkg>add MPI, MPIPreferences +``` + +Set the preference to use `MPItrampoline`: +```julia +julia> using MPIPreferences; MPIPreferences.use_jll_binary("MPItrampoline_jll") +┌ Info: MPIPreferences unchanged +└ binary = "MPItrampoline_jll" +``` + +Load `MPI` and verify it is the correct one: +```julia +julia> using MPI +julia> MPI.Get_library_version() +"MPIwrapper 2.10.3, using MPIABI 2.9.0, wrapping:\nOpen MPI v4.1.4, package: Open MPI boris@Pluton Distribution, ident: 4.1.4, repo rev: v4.1.4, May 26, 2022" +``` +After this, restart julia (this only needs to be done once, next time all is fine). + +#### 1.4 Test `MPI`: + +If you want you can run a test case with: +```julia +julia> using MPI +julia> mpiexec(cmd -> run(`$cmd -n 3 echo hello world`)); +hello world +hello world +hello world ``` -2. Use PETSc.jl as normal — no changes to your script needed: +#### 1.5 Install and use `PETSc.jl`: +Now install `PETSc.jl`: +```julia +julia> using MPI,PETSc +``` +At this stage you can use PETSc.jl as normal — no changes to your script needed: ```julia using PETSc, MPI petsclib = PETSc.getlib(; PetscScalar = Float64, PetscInt = Int64) @@ -28,61 +87,55 @@ PETSc.initialize(petsclib) # ... ``` -3. Launch via the cluster's MPI: +1. Launch via the cluster's MPI: ```bash mpiexec -n 128 julia --project myScript.jl ``` This is the easiest path for most clusters and requires no custom PETSc compilation. -## Option 2: Locally installed PETSc build +## 2. Use a locally installed PETSc build -If you need a PETSc build with specific options (external packages, GPU support, custom BLAS, etc.), you can point PETSc.jl directly to your local installation. -The local PETSc must be compiled as a **shared library** (`--with-shared-libraries=1`) and linked against the **same MPI** that `MPI.jl` is configured to use. +If you need a PETSc build with specific options (external packages, GPU support, custom BLAS, etc.), you can point `PETSc.jl` directly to your local installation. +The local PETSc must be compiled as a **shared library** (`--with-shared-libraries=1`) and linked against the **same MPI** that `MPI.jl` is configured to use (i.e. the one that you should use on your HPC machine). -### Via environment variables (recommended for batch scripts) +#### 2.1 Link `PETSc` to the local library -Set these before starting Julia: +Use `set_library!` to configure the path once — it is stored in `LocalPreferences.toml` and no environment variables are needed afterwards: -```bash -export JULIA_PETSC_LIBRARY=/path/to/petsc/install/lib/libpetsc.so -export JULIA_PETSC_SCALAR=Float64 # Float32 | ComplexFloat64 | ComplexFloat32 -export JULIA_PETSC_INT=Int64 # Int32 +```julia +using PETSc +PETSc.set_library!( + "/path/to/custom/libpetsc.so"; + PetscScalar = Float64, + PetscInt = Int64, +) +# Restart Julia — PETSc_jll is not loaded and your library is used automatically. ``` -With `JULIA_PETSC_LIBRARY` set, `PETSc_jll` is **not** loaded or precompiled, which -avoids MPI incompatibility issues common on HPC clusters. - -### Via `set_petsclib` (recommended for scripts) +#### 2.2 Link `MPI.jl` to the local mpi +You *must* use the same MPI implementation as the one versus which you compiled PETSc (otherwise you'll get heaps of problems). +Check with: ```julia -using PETSc, MPI +julia> using MPI -petsclib = PETSc.set_petsclib( - "/path/to/petsc/install/lib/libpetsc.so"; - PetscScalar = Float64, - PetscInt = Int64 -) -PETSc.initialize(petsclib) -# ... your code ... -PETSc.finalize(petsclib) +julia> MPI.Get_library_version() ``` -To prevent `PETSc_jll` from being precompiled at all (which can fail on clusters -with incompatible MPI), set: -```bash -export JULIA_PETSC_SKIP_JLL=1 -``` -### Typical HPC job script + +### 3. Typical HPC job script + +A typical slurm submissions script to run PETSc code using `MPITrampoline` binaries can look like: ```bash #!/bin/bash #SBATCH --nodes=8 #SBATCH --ntasks-per-node=128 -module load PETSc/3.22.0-foss-2023b -export JULIA_PETSC_SKIP_JLL=1 +export MPITRAMPOLINE_LIB=/users/kausbori/mpiwrapper/lib64/libmpiwrapper.so +export JULIA_CPU_TARGET="generic" srun julia --project ex45.jl \ -N 257 \ @@ -97,54 +150,150 @@ srun julia --project ex45.jl \ -log_view ``` ---- +#### Precompile code on compute nodes +On some machines, it can be useful to precompile `PETSc.jl` on a single core rather than having many processors trying to do the same thing simultaneously. -## Performance and Weak Scalability +This is an example on how this can be done by getting access on an interactive node using slurm. Note that julia was installed in the home directory using `juliaup`. +```bash +salloc --nodes=1 --ntasks=1 --time=00:30:00 \ + --partition=standard --account=your_project_number + +# Once on the compute node: +module --force purge +module load CrayEnv +module load craype +module load gcc-native/13.2 +module load cray-mpich/8.1.32 + +export HOME=/users/kausbori +export JULIA_DEPOT_PATH=/users/kausbori/.julia +export MPITRAMPOLINE_LIB=/users/kausbori/mpiwrapper/lib64/libmpiwrapper.so +export JULIA_CPU_TARGET="generic" + +JULIA=/users/kausbori/.julia/juliaup/julia-1.12.6+0.x64.linux.gnu/bin/julia + +# Clear stale cache +rm -rf /users/kausbori/.julia/compiled/v1.12/PETSc/ +rm -rf /users/kausbori/.julia/compiled/v1.12/PETSc_jll/ +rm -rf /users/kausbori/.julia/compiled/v1.12/MPI/ + +# Precompile +$JULIA --project=/users/kausbori/PETSc_jl_scalability \ + -e 'using PETSc; println("OK")' +``` -This section summarises weak scalability results for the 3D Laplacian benchmark ([`ex45.jl`](https://github.com/JuliaParallel/PETSc.jl/blob/main/examples/ex45.jl)) using a CG solver with geometric multigrid preconditioning (`-pc_type mg`). The problem size is scaled proportionally with the number of MPI ranks so that the work per rank stays constant. +--- -### Setup +## Performance and Weak Scalability -- Problem: 3D Poisson equation on a uniform grid, solved with CG + geometric MG -- Grid size per rank: ~65³ degrees of freedom -- Solver: `-ksp_type cg -pc_type mg -pc_mg_levels 4 -ksp_rtol 1e-8` -- Machine: *[HPC system name, node type, interconnect]* +This section summarises weak scalability results for a 3D Laplacian benchmark ([`ex45.jl`](https://github.com/JuliaParallel/PETSc.jl/blob/main/examples/ex45.jl)) using a CG solver with geometric multigrid preconditioning (`-pc_type mg`). The problem size is scaled proportionally with the number of MPI ranks so that the work per rank stays constant. -### a) PETSc.jl with precompiled `PETSc_jll` binaries +We have performed these simulations on LUMI-C (Finnland) and provide job submission scripts (`submit_scaling.sh`, `job.sh`), along with a parsing file that collects and summarizes the results (`parse_scaling.jl`). +All files are uploaded under [PETSc.jl/examples/scalability_tests](PETSc.jl/examples/scalability_tests), and can be started with +```bash +$ ./submit_scaling.sh 512 1025 1025 1025 6 16 +``` +which will start a $1025 \times 1025 \times 1015$ simulation on 512 cores, with 6 multigrid levels and the coarse grid solver being solved on 16 cores. + +We consider 3 cases: +- Using `PETSc.jl` with MPITrampoline linked to the local MPI ("PETSc.jl"). This is generally the easiest setup +- Using `PETSc.jl` linked to our locally build PETSc version ("local lib") +- Using a C-compiled version of `ex45_julia.c` ("native") + +#### Results +Here the collected results: + +| JobID | Cores | MG levels | NC | Grid | Backend | SolveTime (s) | KSPSolve (s) | TotGFlops | GFlops/s | KSP | L2 error | Max error | Residual | Converged | +|-------|--------|----|----|------|---------|--------------|-------------|-----------|----------|-----|----------|-----------|----------|-----------| +| 17655324 | 64 | 5 | 16 | 513³ | PETSc.jl | 55.843 | 27.916 | 335.60 | 5.13 | 9 | 4.4372e-06 | 1.2557e-05 | 3.5610e-05 | ✅ | +| 17684772 | 64 | 5 | 16 | 513³ | PETSc.jl | 50.800 | 27.108 | 335.60 | 6.00 | 9 | 4.4372e-06 | 1.2557e-05 | 3.5610e-05 | ✅ | +| 17724069 | 64 | 5 | 16 | 513³ | PETSc.jl | 56.352 | 28.121 | 335.60 | 4.99 | 9 | 4.4372e-06 | 1.2557e-05 | 3.5610e-05 | ✅ | +| 17701600 | 64 | 5 | 16 | 513³ | local lib | 69.544 | 37.073 | 335.60 | 4.08 | 9 | 4.4372e-06 | 1.2557e-05 | 3.5610e-05 | ✅ | +| 17705963 | 64 | 5 | 16 | 513³ | local lib | 70.112 | 32.767 | 335.60 | 4.07 | 9 | 4.4372e-06 | 1.2557e-05 | 3.5610e-05 | ✅ | +| 17678227 | 64 | 5 | 16 | 513³ | native | 42.550 | 27.434 | 337.90 | 7.40 | 9 | 4.4372e-06 | 1.2557e-05 | 3.5610e-05 | ✅ | +| 17657242 | 512 | 6 | 16 | 1025³ | PETSc.jl | 66.789 | 33.670 | 2878.00 | 34.89 | 10 | 1.1093e-06 | 3.1236e-06 | 9.6257e-05 | ✅ | +| 17724458 | 512 | 6 | 16 | 1025³ | PETSc.jl | 61.715 | 32.482 | 2878.00 | 37.52 | 10 | 1.1093e-06 | 3.1236e-06 | 9.6257e-05 | ✅ | +| 17725367 | 512 | 6 | 16 | 1025³ | PETSc.jl | 65.473 | 34.236 | 2878.00 | 35.53 | 10 | 1.1093e-06 | 3.1236e-06 | 9.6257e-05 | ✅ | +| 17701691 | 512 | 6 | 16 | 1025³ | local lib | 70.233 | 34.772 | 2878.00 | 34.21 | 10 | 1.1093e-06 | 3.1236e-06 | 9.6257e-05 | ✅ | +| 17678240 | 512 | 6 | 16 | 1025³ | native | 47.616 | 31.498 | 2896.00 | 57.49 | 10 | 1.1093e-06 | 3.1236e-06 | 9.6257e-05 | ✅ | +| 17658195 | 4096 | 7 | 16 | 2049³ | PETSc.jl | 72.949 | 34.332 | 21390.00 | 258.00 | 9 | 2.7738e-07 | 7.8741e-07 | 1.9254e-04 | ✅ | +| 17701696 | 4096 | 7 | 16 | 2049³ | local lib | 94.214 | 50.987 | 21390.00 | 203.10 | 9 | 2.7738e-07 | 7.8741e-07 | 1.9254e-04 | ✅ | +| 17678253 | 4096 | 7 | 16 | 2049³ | native | 60.047 | 33.801 | 21540.00 | 310.20 | 9 | 2.7738e-07 | 7.8741e-07 | 1.9254e-04 | ✅ | +| 17703689 | 32768 | 8 | 16 | 4097³ | PETSc.jl | — | — | — | — | — | — | — | — | ❌ FAILED | +--- +In this table `KSPSolve` indicates the time spend in the solver (taken from the log) and `SolveTime` the time for the full solution. -*Results to be added.* +Below, we break this for each of the cases: -| Ranks | Grid size | Solve time (s) | KSP iterations | -|------:|----------:|---------------:|---------------:| -| 1 | 65³ | — | — | -| 8 | 130³ | — | — | -| 64 | 260³ | — | — | -| 512 | 520³ | — | — | +#### a) PETSc.jl with precompiled `PETSc_jll` binaries -### b) PETSc.jl linked against a local PETSc build (system MPI) +the results of using PETSc.jl with precompiled `jll` libraries are: -*Results to be added.* +| Cores | Grid | DOFs/core | KSPSolve (s) | SolveTime (s) | Efficiency | Converged | +|--------|------|-----------|-------------|--------------|------------|-----------| +| 64 | 513³ | 2,109,464 | 27.916 | 55.843 | 100.0% | ✅ | +| 64 | 513³ | 2,109,464 | 27.108 | 50.800 | 103.0% | ✅ | +| 64 | 513³ | 2,109,464 | 28.121 | 56.352 | 99.3% | ✅ | +| 512 | 1025³ | 2,103,302 | 33.670 | 66.789 | 82.9% | ✅ | +| 512 | 1025³ | 2,103,302 | 32.482 | 61.715 | 85.9% | ✅ | +| 512 | 1025³ | 2,103,302 | 34.236 | 65.473 | 81.5% | ✅ | +| 4096 | 2049³ | 2,100,226 | 34.332 | 72.949 | 81.3% | ✅ | -| Ranks | Grid size | Solve time (s) | KSP iterations | -|------:|----------:|---------------:|---------------:| -| 1 | 65³ | — | — | -| 8 | 130³ | — | — | -| 64 | 260³ | — | — | -| 512 | 520³ | — | — | +Please note that in the way we run this on LUMI-C, the 64 core case is on a single node and does not have inter-node communication. Despite this, weak scalability is pretty good (one could also argue to use the 512 core case as reference as this includes communication, in which case it would even be better). +There is some variability in the timing when repeating the same run (a few %). -### c) Native C build (`ex45.c`) +#### b) PETSc.jl linked against a local PETSc build (system MPI) -The equivalent PETSc C example compiled natively, serving as the baseline. +| Ntasks | Grid | DOFs/core | KSPSolve (s) | SolveTime (s) | Efficiency | Converged | +|--------|------|-----------|-------------|--------------|------------|-----------| +| 64 | 513³ | 2,109,464 | 37.073 | 69.544 | 100.0% | ✅ | +| 64 | 513³ | 2,109,464 | 32.767 | 70.112 | 113.1% | ✅ | +| 512 | 1025³ | 2,103,302 | 34.772 | 70.233 | 106.6% | ✅ | +| 4096 | 2049³ | 2,100,226 | 50.987 | 94.214 | 72.7% | ✅ | -*Results to be added.* -| Ranks | Grid size | Solve time (s) | KSP iterations | -|------:|----------:|---------------:|---------------:| -| 1 | 65³ | — | — | -| 8 | 130³ | — | — | -| 64 | 260³ | — | — | -| 512 | 520³ | — | — | +#### c) Native C build (`ex45_julia.c`) -### Observations +The equivalent PETSc C example compiled natively, serving as the baseline. -*To be filled in once results are available.* +| Ntasks | Grid | DOFs/core | KSPSolve (s) | SolveTime (s) | Efficiency | Converged | +|--------|------|-----------|-------------|--------------|------------|-----------| +| 64 | 513³ | 2,109,464 | 27.434 | 42.550 | 100.0% | ✅ | +| 512 | 1025³ | 2,103,302 | 31.498 | 47.616 | 87.1% | ✅ | +| 4096 | 2049³ | 2,100,226 | 33.801 | 60.047 | 81.2% | ✅ | + +#### d) Backend Comparison + +If we compare the case on 4096 cores with a 2049³ grid, for 3D Poisson, 64 nodes × 64 tasks/node, MG levels = 7, coarse ranks = 16 we get: + +| Metric | native C | PETSc.jl (`_jll`) | PETSc.jl (`_jll`) | local lib | +|--------|----------|-------------------|-------------------|-----------| +| **JobID** | 17678253 | 17658195 | 17724464 | 17701696 | +| **SolveTime (s)** | 60.047 | 72.949 | 79.557 | 94.214 | +| **KSPSolve (s)** | 33.801 | 34.332 | 44.244 | 50.987 | +| **KSP iterations** | 9 | 9 | 9 | 9 | +| **Total GFlops** | 21,540 | 21,390 | 21,390 | 21,390 | +| **GFlops/s** | 310.2 | 258.0 | 208.5 | 203.1 | +| **L2 error** | 2.7738e-07 | 2.7738e-07 | 2.7738e-07 | 2.7738e-07 | +| **Max error** | 7.8741e-07 | 7.8741e-07 | 7.8741e-07 | 7.8741e-07 | +| **Converged** | ✅ | ✅ | ✅ | ✅ | + +The relative performance is thus: + +| Backend | SolveTime overhead | KSPSolve overhead | +|---------|--------------------|-------------------| +| native C | — (reference) | — (reference) | +| PETSc.jl (best run) | +21.5% | +1.6% | +| PETSc.jl (worst run) | +32.5% | +30.9% | +| local lib | +56.9% | +50.8% | + +From this we can conclude: +- **Numerical results are identical** across all backends — same iterations, same L2/Max error. +- **KSPSolve time** (pure solver kernel) is nearly identical between native and `PETSc.jl` best run (+1.6%), suggesting the Julia wrapper overhead is minimal in the solver itself. +- **SolveTime overhead** for `PETSc.jl` vs native (+21–33%) comes mostly from setup (mesh construction, matrix assembly, MG hierarchy setup) rather than the solve. +- **local lib** is slower than `_jll` despite using the same PETSc version. The likely cause for this is a different SuperLU_dist build, different BLAS (system libsci vs OpenBLAS in `_jll`), and going through GNU Cray MPI instead of MPItrampoline. +- The variability between the two `PETSc.jl` runs (34s vs 44s KSPSolve) suggests some node-to-node performance variability on LUMI-C + +#### Weak scalability plot +Results can be summarized in the plot below: +![weak_scalability_LUMI](../assets/img/weak_scaling_ex45_LUMI.png) \ No newline at end of file diff --git a/examples/ex45.jl b/examples/ex45.jl index 295b3ffa..503f7006 100644 --- a/examples/ex45.jl +++ b/examples/ex45.jl @@ -12,6 +12,20 @@ forcing(x, y, z) = 12 * π^2 * sin(2π * x) * sin(2π * y) * sin(2π * z) # Get the PETSc lib with our chosen `PetscScalar` type petsclib = PETSc.getlib(; PetscScalar = Float64) +# If we want to use a custom PETSc library, we can set it with `PETSc.set_library!` before calling `PETSc.getlib`. For example: +#= +using PETSc +PETSc.set_library!( + "/path/to/custom/libpetsc.so"; + PetscScalar = Float64, + PetscInt = Int64, +) +# Restart Julia — PETSc_jll is not loaded and your library is used automatically. +=# +# This creates a LocalPreferences.toml file. +#petsclib = PETSc.getlib(; PetscScalar = Float64, PetscInt = Int64) + + # Initialize PETSc PETSc.initialize(petsclib, log_view=true) diff --git a/examples/scalability_tests/ex45_julia.c b/examples/scalability_tests/ex45_julia.c new file mode 100644 index 00000000..1fc15215 --- /dev/null +++ b/examples/scalability_tests/ex45_julia.c @@ -0,0 +1,264 @@ +/* + Laplacian in 3D with manufactured solution. + + PDE: -Laplacian u = 12*pi^2 * sin(2*pi*x) * sin(2*pi*y) * sin(2*pi*z) + on (0,1)^3 with Dirichlet BCs: + u = sin(2*pi*x) * sin(2*pi*y) * sin(2*pi*z) on all boundaries + + Exact solution: u = sin(2*pi*x) * sin(2*pi*y) * sin(2*pi*z) + + Matrix is scaled by h^3 (= Hx*Hy*Hz) so entries are O(h) rather than O(1/h^2), + matching the scaling used in ex45.jl. + + Grid size is controlled by -Nx, -Ny, -Nz (matching ex45.jl convention). + + Output is formatted to match ex45.jl so that parse_scaling.jl works unchanged. +*/ + +static char help[] = "Solves 3D Laplacian (manufactured solution) using multigrid.\n\n"; + +#include +#include +#include +#include + +/* Context passed to callbacks */ +typedef struct { + PetscInt Nx, Ny, Nz; +} AppCtx; + +extern PetscErrorCode ComputeMatrix(KSP, Mat, Mat, void *); +extern PetscErrorCode ComputeRHS(KSP, Vec, void *); +extern PetscErrorCode ComputeInitialGuess(KSP, Vec, void *); + +static inline PetscReal exact_sol(PetscReal x, PetscReal y, PetscReal z) +{ + return sin(2.0 * PETSC_PI * x) * sin(2.0 * PETSC_PI * y) * sin(2.0 * PETSC_PI * z); +} + +static inline PetscReal forcing(PetscReal x, PetscReal y, PetscReal z) +{ + return 12.0 * PETSC_PI * PETSC_PI * + sin(2.0 * PETSC_PI * x) * sin(2.0 * PETSC_PI * y) * sin(2.0 * PETSC_PI * z); +} + +int main(int argc, char **argv) +{ + KSP ksp; + DM da; + Vec x, b, r; + Mat A; + AppCtx ctx; + PetscReal norm, solve_time, L2, maxerr; + PetscInt niter; + PetscLogDouble t0, t1; + + PetscFunctionBeginUser; + PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); + + /* Default grid size matches ex45.jl default */ + ctx.Nx = 7; ctx.Ny = 7; ctx.Nz = 7; + PetscCall(PetscOptionsGetInt(NULL, NULL, "-Nx", &ctx.Nx, NULL)); + PetscCall(PetscOptionsGetInt(NULL, NULL, "-Ny", &ctx.Ny, NULL)); + PetscCall(PetscOptionsGetInt(NULL, NULL, "-Nz", &ctx.Nz, NULL)); + + /* Print grid info matching ex45.jl output */ + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Solving on %d × %d × %d grid\n", + (int)ctx.Nx, (int)ctx.Ny, (int)ctx.Nz)); + + PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp)); + PetscCall(DMDACreate3d(PETSC_COMM_WORLD, + DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, + DMDA_STENCIL_STAR, + ctx.Nx, ctx.Ny, ctx.Nz, + PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, + 1, 1, NULL, NULL, NULL, &da)); + PetscCall(DMSetFromOptions(da)); + PetscCall(DMSetUp(da)); + PetscCall(KSPSetDM(ksp, da)); + PetscCall(KSPSetComputeInitialGuess(ksp, ComputeInitialGuess, &ctx)); + PetscCall(KSPSetComputeRHS(ksp, ComputeRHS, &ctx)); + PetscCall(KSPSetComputeOperators(ksp, ComputeMatrix, &ctx)); + PetscCall(DMDestroy(&da)); + PetscCall(KSPSetFromOptions(ksp)); + + /* Time the solve */ + PetscCall(PetscTime(&t0)); + PetscCall(KSPSolve(ksp, NULL, NULL)); + PetscCall(PetscTime(&t1)); + solve_time = (PetscReal)(t1 - t0); + + PetscCall(KSPGetSolution(ksp, &x)); + PetscCall(KSPGetRhs(ksp, &b)); + PetscCall(KSPGetIterationNumber(ksp, &niter)); + PetscCall(KSPGetResidualNorm(ksp, &norm)); + + /* Compute explicit residual norm */ + PetscCall(VecDuplicate(b, &r)); + PetscCall(KSPGetOperators(ksp, &A, NULL)); + PetscCall(MatMult(A, x, r)); + PetscCall(VecAXPY(r, -1.0, b)); + PetscReal resnorm; + PetscCall(VecNorm(r, NORM_2, &resnorm)); + + /* Compute L2 and max error against exact solution */ + { + DM dm; + DMDALocalInfo info; + Vec x_local; + PetscScalar ***xu; + PetscReal local_err2 = 0.0, local_max = 0.0; + PetscReal Hx, Hy, Hz, vol; + PetscInt i, j, k; + + PetscCall(KSPGetDM(ksp, &dm)); + PetscCall(DMDAGetLocalInfo(dm, &info)); + Hx = 1.0 / (PetscReal)(info.mx - 1); + Hy = 1.0 / (PetscReal)(info.my - 1); + Hz = 1.0 / (PetscReal)(info.mz - 1); + vol = Hx * Hy * Hz; + + PetscCall(DMGetLocalVector(dm, &x_local)); + PetscCall(DMGlobalToLocalBegin(dm, x, INSERT_VALUES, x_local)); + PetscCall(DMGlobalToLocalEnd(dm, x, INSERT_VALUES, x_local)); + PetscCall(DMDAVecGetArrayRead(dm, x_local, &xu)); + + for (k = info.zs; k < info.zs + info.zm; k++) { + for (j = info.ys; j < info.ys + info.ym; j++) { + for (i = info.xs; i < info.xs + info.xm; i++) { + PetscReal xc = i * Hx; + PetscReal yc = j * Hy; + PetscReal zc = k * Hz; + PetscReal u_ex = exact_sol(xc, yc, zc); + PetscReal err = (PetscReal)xu[k][j][i] - u_ex; + local_err2 += err * err * vol; + if (PetscAbsReal(err) > local_max) local_max = PetscAbsReal(err); + } + } + } + + PetscCall(DMDAVecRestoreArrayRead(dm, x_local, &xu)); + PetscCall(DMRestoreLocalVector(dm, &x_local)); + + PetscCall(MPI_Allreduce(&local_err2, &L2, 1, MPIU_REAL, MPIU_SUM, PETSC_COMM_WORLD)); + PetscCall(MPI_Allreduce(&local_max, &maxerr, 1, MPIU_REAL, MPIU_MAX, PETSC_COMM_WORLD)); + L2 = PetscSqrtReal(L2); + } + + /* Output exactly matching ex45.jl format for parse_scaling.jl */ + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "L2 error: %e\n", (double)L2)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Max error: %e\n", (double)maxerr)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Residual norm %g\n", (double)resnorm)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Solve time: %f seconds\n", (double)solve_time)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Final residual norm %g\n", (double)norm)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Fine grid resolution: %d × %d × %d\n", + (int)ctx.Nx, (int)ctx.Ny, (int)ctx.Nz)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Outer KSP iterations: %d\n", (int)niter)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Solve time: %f seconds\n", (double)solve_time)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "L2 error: %e\n", (double)L2)); + PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Max error: %e\n", (double)maxerr)); + + PetscCall(VecDestroy(&r)); + PetscCall(KSPDestroy(&ksp)); + PetscCall(PetscFinalize()); + return 0; +} + +PetscErrorCode ComputeInitialGuess(KSP ksp, Vec b, void *ctx) +{ + PetscFunctionBeginUser; + PetscCall(VecSet(b, 0)); + PetscFunctionReturn(PETSC_SUCCESS); +} + +PetscErrorCode ComputeRHS(KSP ksp, Vec b, void *ctx) +{ + AppCtx *user = (AppCtx *)ctx; + DM dm; + DMDALocalInfo info; + PetscScalar ***barray; + PetscInt i, j, k; + PetscReal Hx, Hy, Hz, scale; + + PetscFunctionBeginUser; + PetscCall(KSPGetDM(ksp, &dm)); + PetscCall(DMDAGetLocalInfo(dm, &info)); + + Hx = 1.0 / (PetscReal)(info.mx - 1); + Hy = 1.0 / (PetscReal)(info.my - 1); + Hz = 1.0 / (PetscReal)(info.mz - 1); + scale = Hx * Hy * Hz; /* same h^3 scaling as ex45.jl */ + + PetscCall(DMDAVecGetArray(dm, b, &barray)); + for (k = info.zs; k < info.zs + info.zm; k++) { + for (j = info.ys; j < info.ys + info.ym; j++) { + for (i = info.xs; i < info.xs + info.xm; i++) { + PetscReal x = i * Hx; + PetscReal y = j * Hy; + PetscReal z = k * Hz; + if (i == 0 || j == 0 || k == 0 || + i == info.mx - 1 || j == info.my - 1 || k == info.mz - 1) { + /* Dirichlet BC: identity row -> RHS = exact value */ + barray[k][j][i] = exact_sol(x, y, z); + } else { + /* Interior: scale forcing by h^3 */ + barray[k][j][i] = forcing(x, y, z) * scale; + } + } + } + } + PetscCall(DMDAVecRestoreArray(dm, b, &barray)); + PetscFunctionReturn(PETSC_SUCCESS); +} + +PetscErrorCode ComputeMatrix(KSP ksp, Mat jac, Mat B, void *ctx) +{ + DM da; + DMDALocalInfo info; + PetscInt i, j, k; + PetscReal Hx, Hy, Hz, scale; + PetscReal cx, cy, cz, diag; + PetscScalar v[7]; + MatStencil row, col[7]; + + PetscFunctionBeginUser; + PetscCall(KSPGetDM(ksp, &da)); + PetscCall(DMDAGetLocalInfo(da, &info)); + + Hx = 1.0 / (PetscReal)(info.mx - 1); + Hy = 1.0 / (PetscReal)(info.my - 1); + Hz = 1.0 / (PetscReal)(info.mz - 1); + scale = Hx * Hy * Hz; /* h^3 scaling matching ex45.jl */ + + /* Scaled FD coefficients: scale * (1/h^2) = h^3/h^2 = h */ + cx = scale / (Hx * Hx); /* = Hy*Hz/Hx */ + cy = scale / (Hy * Hy); /* = Hx*Hz/Hy */ + cz = scale / (Hz * Hz); /* = Hx*Hy/Hz */ + diag = 2.0 * (cx + cy + cz); + + for (k = info.zs; k < info.zs + info.zm; k++) { + for (j = info.ys; j < info.ys + info.ym; j++) { + for (i = info.xs; i < info.xs + info.xm; i++) { + row.i = i; row.j = j; row.k = k; + if (i == 0 || j == 0 || k == 0 || + i == info.mx - 1 || j == info.my - 1 || k == info.mz - 1) { + /* Identity row for Dirichlet BC */ + v[0] = 1.0; + PetscCall(MatSetValuesStencil(B, 1, &row, 1, &row, v, INSERT_VALUES)); + } else { + v[0] = -cz; col[0].i = i; col[0].j = j; col[0].k = k-1; + v[1] = -cy; col[1].i = i; col[1].j = j-1; col[1].k = k; + v[2] = -cx; col[2].i = i-1; col[2].j = j; col[2].k = k; + v[3] = diag; col[3].i = i; col[3].j = j; col[3].k = k; + v[4] = -cx; col[4].i = i+1; col[4].j = j; col[4].k = k; + v[5] = -cy; col[5].i = i; col[5].j = j+1; col[5].k = k; + v[6] = -cz; col[6].i = i; col[6].j = j; col[6].k = k+1; + PetscCall(MatSetValuesStencil(B, 1, &row, 7, col, v, INSERT_VALUES)); + } + } + } + } + PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); + PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); + PetscFunctionReturn(PETSC_SUCCESS); +} \ No newline at end of file diff --git a/examples/scalability_tests/job.sh b/examples/scalability_tests/job.sh new file mode 100644 index 00000000..5591b73d --- /dev/null +++ b/examples/scalability_tests/job.sh @@ -0,0 +1,77 @@ +#!/bin/bash -l +#SBATCH --job-name=scaling +#SBATCH --partition=standard +#SBATCH --cpus-per-task=1 +#SBATCH --exclusive +#SBATCH --mem=200000M +#SBATCH --time=0-00:10:00 +#SBATCH --account=??? # add your account here +# --ntasks, --nodes, --ntasks-per-node, --output passed by submit_scaling.sh + +module --force purge +module load CrayEnv +module load craype +module load gcc-native/13.2 +module load cray-mpich/8.1.32 + +export HOME=/users/kausbori +export JULIA_DEPOT_PATH=/users/kausbori/.julia +export MPITRAMPOLINE_LIB=/users/kausbori/mpiwrapper/lib64/libmpiwrapper.so +export JULIA_PKG_PRECOMPILE_AUTO=0 +export JULIA_NUM_THREADS=1 +export JULIA_CPU_TARGET="generic" + +export MPICH_OFI_STARTUP_CONNECT=1 +export MPICH_OFI_NIC_POLICY=NUMA +export FI_CXI_DEFAULT_CQ_SIZE=131072 +export MPICH_OFI_STARTUP_CONNECT=0 +export FI_CXI_DISABLE_CQ_HUGETLB=1 +export MPICH_MAX_THREAD_SAFETY=single +export LD_LIBRARY_PATH=/opt/cray/pe/mpich/8.1.32/ofi/cray/17.0/lib:$LD_LIBRARY_PATH + +JULIA=/users/kausbori/.julia/juliaup/julia-1.12.6+0.x64.linux.gnu/bin/julia + +echo "=== Scaling run: ntasks=${NTASKS}, Nx=${NX}, Ny=${NY}, Nz=${NZ}, mg_levels=${NMGLEVELS}, ncoarse=${NCOARSE}, reduction_factor=${REDUCTION_FACTOR} ===" +echo "=== Running on ${SLURM_NNODES} nodes, ${SLURM_NTASKS} tasks, $(( SLURM_NTASKS / SLURM_NNODES )) tasks/node ===" + +echo "=== MPI diagnostic ===" +srun -n 1 $JULIA --project=/users/kausbori/PETSc_jl_scalability -e ' +using MPI +MPI.Init() +println("MPI library: ", MPI.libmpi) +println("MPI version: ", MPI.MPI_LIBRARY_VERSION_STRING) +println("hostname: ", gethostname()) +' +echo "=== End MPI diagnostic ===" + +echo "MPI run started at $(date)" +srun -n ${NTASKS} $JULIA --heap-size-hint=1G \ + --project=/users/kausbori/PETSc_jl_scalability ex45.jl \ + -Nx ${NX} \ + -Ny ${NY} \ + -Nz ${NZ} \ + -pc_mg_levels ${NMGLEVELS} \ + -ksp_type cg \ + -pc_type mg \ + -mg_levels_ksp_type chebyshev \ + -mg_levels_pc_type sor \ + -ksp_rtol 1e-8 \ + -mg_coarse_ksp_type preonly \ + -mg_coarse_pc_type telescope \ + -mg_coarse_telescope_reduction_factor ${REDUCTION_FACTOR} \ + -mg_coarse_telescope_pc_type lu \ + -mg_coarse_telescope_pc_factor_mat_solver_type superlu_dist \ + -pc_mg_log \ + -malloc_view \ + -memory_view \ + -ksp_converged_reason \ + -ksp_monitor_true_residual \ + -log_view \ + 2>&1 +echo "MPI run finished at $(date)" + +echo "=== Memory usage ===" +sacct -j ${SLURM_JOB_ID} --format=JobID,MaxRSS,AveRSS,NNodes,NCPUs --units=G + +echo "exit: $?" +echo "Job finished at $(date)" \ No newline at end of file diff --git a/examples/scalability_tests/makefile b/examples/scalability_tests/makefile new file mode 100644 index 00000000..7677bfde --- /dev/null +++ b/examples/scalability_tests/makefile @@ -0,0 +1,24 @@ +-include ../../../../petscdir.mk + +LOCDIR = src/ksp/ksp/tutorials/ +MANSEC = KSP +CLEANFILES = rhs.vtk solution.vtk bench_pcsetup +NP = 1 +DIRS = network amrex + +include ${PETSC_DIR}/lib/petsc/conf/variables +include ${PETSC_DIR}/lib/petsc/conf/rules + +testex100: ex100.PETSc + -@OMPI_MCA_mpi_warn_on_fork=0 ${MPIEXEC} -n 1 ./ex100 -test > ex100_1.tmp 2>&1; \ + if (${DIFF} output/ex100_1.testout ex100_1.tmp > /dev/null 2>&1) then \ + echo "C/C++ Python example src/ksp/ksp/tutorials/ex100 run successfully with 1 MPI process"; \ + else \ + echo "Possible error running C/C++ Python src/ksp/ksp/tutorials/ex100 with 1 MPI process"; \ + echo "See https://petsc.org/release/faq/";\ + cat ex100_1.tmp;\ + touch ${PETSC_DIR}/check_error;\ + fi; \ + ${RM} -f ex100_1.tmp + +include ${PETSC_DIR}/lib/petsc/conf/test diff --git a/examples/scalability_tests/parse_scaling.jl b/examples/scalability_tests/parse_scaling.jl new file mode 100644 index 00000000..2c24718c --- /dev/null +++ b/examples/scalability_tests/parse_scaling.jl @@ -0,0 +1,246 @@ +#!/usr/bin/env julia +# parse_scaling.jl +# Usage: julia parse_scaling.jl scaling_*.out + +using Printf + +struct ScalingResult + jobid :: String + ntasks :: Int + nx :: Int + ny :: Int + nz :: Int + mg_levels :: Int + ncoarse :: Int + solve_time :: Float64 # application "Solve time:" field + ksp_solve_time :: Float64 # PETSc KSPSolve event time (for weak scaling) + ksp_iter :: Int + l2_error :: Float64 + max_error :: Float64 + residual :: Float64 + total_gflops :: Float64 + gflops_s :: Float64 + converged_reason :: String + backend :: String # "native" or "PETSc.jl" +end + +function parse_file(filename::String) + m = match(r"scaling([a-zA-Z]*)_(\d+)_n(\d+)_nx(\d+)_ny(\d+)_nz(\d+)_mg(\d+)_nc(\d+)\.out", basename(filename)) + if isnothing(m) + @warn "Filename $filename does not match expected pattern, skipping" + return nothing + end + variant = m[1] # e.g. "", "Galerkin", "NATIVE" + jobid = m[2] + ntasks = parse(Int, m[3]) + nx = parse(Int, m[4]) + ny = parse(Int, m[5]) + nz = parse(Int, m[6]) + mg_levels = parse(Int, m[7]) + ncoarse = parse(Int, m[8]) + backend = if uppercase(variant) == "NATIVE" + "native" + elseif uppercase(variant) == "LOCALLIB" + "local lib" + else + "PETSc.jl" + end + + solve_time = NaN + ksp_solve_time = NaN + ksp_iter = -1 + l2_error = NaN + max_error = NaN + residual = NaN + total_gflops = NaN + gflops_s = NaN + converged_reason = "UNKNOWN" + + in_petsc_summary = false + in_ksp_monitor = false + + for line in eachline(filename) + + # Detect PETSc performance summary block + if occursin("PETSc Performance Summary", line) + in_petsc_summary = true + end + + # Detect KSP monitor lines (leading spaces + digit + " KSP") + if match(r"^\s+\d+ KSP", line) !== nothing + in_ksp_monitor = true + end + + # KSP monitor block ends at the "Linear solve" line + if occursin("Linear solve", line) && occursin("due to", line) + in_ksp_monitor = false + m2 = match(r"Linear solve (\w+) due to (\S+)", line) + isnothing(m2) || (converged_reason = string(m2[1] == "converged" ? "OK " : "FAIL ") * m2[2]) + continue + end + + # Skip KSP monitor lines entirely + in_ksp_monitor && continue + + # ---- application output (before PETSc summary) ---- + if !in_petsc_summary + + if occursin("Outer KSP iterations:", line) + m2 = match(r"Outer KSP iterations:\s+(\d+)", line) + isnothing(m2) || (ksp_iter = parse(Int, m2[1])) + + elseif occursin("Final residual norm", line) + m2 = match(r"Final residual norm\s+([\d.e+\-]+)", line) + isnothing(m2) || (residual = parse(Float64, m2[1])) + + elseif occursin("Solve time:", line) + m2 = match(r"Solve time:\s+([\d.e+\-]+)", line) + isnothing(m2) || isnan(solve_time) && (solve_time = parse(Float64, m2[1])) + + elseif occursin("L2 error:", line) + m2 = match(r"L2 error:\s+([\d.e+\-]+)", line) + isnothing(m2) || isnan(l2_error) && (l2_error = parse(Float64, m2[1])) + + elseif occursin("Max error:", line) + m2 = match(r"Max error:\s+([\d.e+\-]+)", line) + isnothing(m2) || isnan(max_error) && (max_error = parse(Float64, m2[1])) + end + + # ---- PETSc performance summary block ---- + else + # KSPSolve event line: extract the Max time (column 3 after the counts) + # Format: "KSPSolve count ratio maxtime ratio ..." + if match(r"^\s*KSPSolve\s", line) !== nothing && isnan(ksp_solve_time) + # fields: Name Count Ratio MaxTime Ratio ... + vals = split(strip(line)) + # vals[1]=KSPSolve, vals[2]=count, vals[3]=ratio, vals[4]=maxtime + if length(vals) >= 4 + t = tryparse(Float64, vals[4]) + isnothing(t) || (ksp_solve_time = t) + end + end + + if match(r"^\s*Flops:\s", line) !== nothing + vals = split(strip(replace(line, r"^\s*Flops:\s*" => ""))) + length(vals) >= 4 && (total_gflops = parse(Float64, vals[4]) / 1e9) + + elseif match(r"^\s*Flops/sec:\s", line) !== nothing + vals = split(strip(replace(line, r"^\s*Flops/sec:\s*" => ""))) + length(vals) >= 4 && (gflops_s = parse(Float64, vals[4]) / 1e9) + end + end + end + + return ScalingResult(jobid, ntasks, nx, ny, nz, mg_levels, ncoarse, + solve_time, ksp_solve_time, ksp_iter, + l2_error, max_error, residual, + total_gflops, gflops_s, + converged_reason, backend) +end + +function ndofs(r::ScalingResult) + return r.nx * r.ny * r.nz +end + +function print_table(results::Vector{ScalingResult}) + sort!(results, by = r -> (r.ntasks, r.backend)) + + println() + @printf("%-12s %6s %4s %4s %15s %9s %10s %11s %10s %10s %4s %12s %12s %12s %s\n", + "JobID", "Ntasks", "MG", "NC", "Grid", "Backend", + "SolveTime", "KSPSolveTime", "TotGFlops", + "GFlops/s", "KSP", "L2_error", "Max_error", "Residual", "Converged") + println(repeat("-", 190)) + + for r in results + grid = @sprintf("%dx%dx%d", r.nx, r.ny, r.nz) + ksp_t = isnan(r.ksp_solve_time) ? " N/A" : @sprintf("%11.3f", r.ksp_solve_time) + @printf("%-12s %6d %4d %4d %15s %9s %10.3f %s %10.2f %10.2f %4d %12.4e %12.4e %12.4e %s\n", + r.jobid, r.ntasks, r.mg_levels, r.ncoarse, grid, r.backend, + r.solve_time, ksp_t, r.total_gflops, r.gflops_s, + r.ksp_iter, r.l2_error, r.max_error, r.residual, + r.converged_reason) + end + println() +end + +function print_convergence(results::Vector{ScalingResult}) + iso = filter(r -> r.nx == r.ny == r.nz, results) + sort!(iso, by = r -> r.nx) + + if length(iso) >= 2 + println("Spatial convergence rate - isotropic runs (should be ~2.0 for second-order FD):") + println(repeat("-", 65)) + for i in 2:length(iso) + r_fine = iso[i] + r_coarse = iso[i-1] + h_fine = 1.0 / (r_fine.nx - 1) + h_coarse = 1.0 / (r_coarse.nx - 1) + if !isnan(r_fine.l2_error) && !isnan(r_coarse.l2_error) + rate = log(r_coarse.l2_error / r_fine.l2_error) / log(h_coarse / h_fine) + @printf(" %dx%dx%d -> %dx%dx%d L2: %.4e->%.4e rate= %.2f [%s]\n", + r_coarse.nx, r_coarse.ny, r_coarse.nz, + r_fine.nx, r_fine.ny, r_fine.nz, + r_coarse.l2_error, r_fine.l2_error, rate, r_fine.backend) + end + end + println() + end +end + +function print_scaling(results::Vector{ScalingResult}) + # Print separate weak scaling tables per backend + backends = unique(r.backend for r in results) + for backend in sort(backends) + subset = filter(r -> r.backend == backend, results) + sorted = sort(subset, by = r -> r.ntasks) + isempty(sorted) && continue + + ref = sorted[1] + t0_ksp = ref.ksp_solve_time + t0_solve = ref.solve_time + use_ksp = !isnan(t0_ksp) + t0 = use_ksp ? t0_ksp : t0_solve + + label = use_ksp ? "KSPSolve time" : "Solve time (fallback)" + println("Weak scaling efficiency [$backend] based on $label (relative to smallest ntasks):") + println(repeat("-", 85)) + @printf(" %-6s %-15s %8s %11s %10s %10s %s\n", + "Ntasks", "Grid", "DOFs/core", "KSPSolve(s)", "SolveTime", "Efficiency", "Converged") + println(repeat("-", 85)) + for r in sorted + t_ksp = isnan(r.ksp_solve_time) ? NaN : r.ksp_solve_time + t_use = use_ksp ? t_ksp : r.solve_time + eff = isnan(t_use) ? NaN : t0 / t_use * 100 + dpc = ndofs(r) / r.ntasks + grid_str = @sprintf("%dx%dx%d", r.nx, r.ny, r.nz) + ksp_str = isnan(t_ksp) ? " N/A" : @sprintf("%11.3f", t_ksp) + eff_str = isnan(eff) ? " N/A" : @sprintf("%9.1f%%", eff) + @printf(" %-6d %-15s %8.0f %s %10.3f %s %s\n", + r.ntasks, grid_str, dpc, ksp_str, r.solve_time, eff_str, r.converged_reason) + end + println() + end +end + +function main() + if isempty(ARGS) + println("Usage: julia parse_scaling.jl scaling_*.out") + exit(1) + end + + results = ScalingResult[] + for f in ARGS + isfile(f) || (@warn "File not found: $f, skipping"; continue) + r = parse_file(f) + isnothing(r) || push!(results, r) + end + + isempty(results) && (println("No valid files found."); exit(1)) + + print_table(results) + print_convergence(results) + print_scaling(results) +end + +main() \ No newline at end of file diff --git a/examples/scalability_tests/submit_scaling.sh b/examples/scalability_tests/submit_scaling.sh new file mode 100644 index 00000000..403d5c4d --- /dev/null +++ b/examples/scalability_tests/submit_scaling.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# submit_scaling.sh +# Usage: ./submit_scaling.sh [ncoarse] +# +# Arguments: +# ntasks - total MPI tasks (default: 8) +# Nx/Ny/Nz - global grid size in each dimension (default: 129) +# mg_levels - number of multigrid levels (default: 4) +# ncoarse - number of ranks for coarse solve (default: 16) +# +# Coarse grid size guidance: +# mg_levels=4, fine=129^3 -> coarse ~16^3 (~4096 DOF) +# mg_levels=5, fine=257^3 -> coarse ~17^3 (~4913 DOF) +# +# Examples: +# ./submit_scaling.sh 64 257 257 257 5 16 +# ./submit_scaling.sh 512 1025 1025 1025 6 16 +# ./submit_scaling.sh 4096 2049 2049 2049 7 16 + +NTASKS=${1:-8} +NX=${2:-129} +NY=${3:-129} +NZ=${4:-129} +NMGLEVELS=${5:-4} +NCOARSE=${6:-16} + +if [ ${NCOARSE} -gt ${NTASKS} ]; then + ec + ho "ERROR: NCOARSE=${NCOARSE} > NTASKS=${NTASKS}" + exit 1 +fi + +REDUCTION_FACTOR=$((NTASKS / NCOARSE)) + +NTASKS_PER_NODE=64 +NNODES=$(( (NTASKS + NTASKS_PER_NODE - 1) / NTASKS_PER_NODE )) +ACTUAL_NTASKS_PER_NODE=$(( NTASKS < NTASKS_PER_NODE ? NTASKS : NTASKS_PER_NODE )) + +echo "Submitting: ntasks=${NTASKS}, nodes=${NNODES}, ntasks-per-node=${ACTUAL_NTASKS_PER_NODE}" +echo " Nx=${NX}, Ny=${NY}, Nz=${NZ}, mg_levels=${NMGLEVELS}" +echo " ncoarse=${NCOARSE}, reduction_factor=${REDUCTION_FACTOR}" + +sbatch \ + --ntasks=${NTASKS} \ + --nodes=${NNODES} \ + --ntasks-per-node=${ACTUAL_NTASKS_PER_NODE} \ + --output="scaling_%j_n${NTASKS}_nx${NX}_ny${NY}_nz${NZ}_mg${NMGLEVELS}_nc${NCOARSE}.out" \ + --export=ALL,NTASKS=${NTASKS},NX=${NX},NY=${NY},NZ=${NZ},NMGLEVELS=${NMGLEVELS},NCOARSE=${NCOARSE},REDUCTION_FACTOR=${REDUCTION_FACTOR} \ + job.sh \ No newline at end of file From 9c959a88d08433a2d186306506c0789e7d59daee Mon Sep 17 00:00:00 2001 From: Boris Kaus Date: Thu, 23 Apr 2026 09:55:50 +0200 Subject: [PATCH 5/7] update scaling results --- .../src/assets/img/weak_scaling_ex45_LUMI.png | Bin 137567 -> 175886 bytes docs/src/man/hpc.md | 94 ++++++++++------- .../scalability_tests/weak_scaling_plot.jl | 98 ++++++++++++++++++ 3 files changed, 154 insertions(+), 38 deletions(-) create mode 100644 examples/scalability_tests/weak_scaling_plot.jl diff --git a/docs/src/assets/img/weak_scaling_ex45_LUMI.png b/docs/src/assets/img/weak_scaling_ex45_LUMI.png index 4a737f2dffdb963edf767e9ff2e0f9154d2f7762..b8ebeecca41628283f09461cc457e3e92ea78dab 100644 GIT binary patch literal 175886 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຿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