GaussJacobiQuad supports Coarray Fortran (CAF) for multi-image runs.
-fcoarray=single (CAF paths still run; one image
owns every index)libcaf_mpi + MPICH (not OpenMPI
with gfortran ≥14)| Method string | Meaning | Multi-image work |
|---|---|---|
auto (omit) |
select_method_auto |
Picks *_caf when num_images()>1 |
rec |
Serial recurrence Newton roots | — |
rec_caf |
Same math | Root indices partitioned |
gw / gw_caf |
Golub–Welsch + dsteqr |
One rule is serial (use batch) |
algo665 / algo665_caf |
GW + imtqlx |
One rule is serial (use batch) |
algo665_dc |
Cuppen D&C + imtqlx leaves |
serial D&C |
algo665_dc_caf |
D&C with CAF hooks | leaf / merge structure |
sturm / sturm_caf |
Sturm bisection + inv. iter. | Eigenvalue index partitioned |
glr |
Prüfer phase-by-π chain + Newton | sequential (true GLR) |
glr_caf |
Independent k-th starters + Newton | Root indices partitioned |
bogaert |
Legendre asymptotics | serial |
bogaert_caf |
Same math | Half-node indices partitioned |
glr keeps the sequential Prüfer march.
glr_caf is the parallel path (asymptotic
starter per index + Newton); it is not a split of the phase chain.
Aliases gw_caf / algo665_caf accept multi-image launch but do
not split a single eigensolve. Use the batch
API for multi-image speedup on those methods.
use GaussJacobiQuad, only: gauss_jacobi_rule, select_method_auto
! omit / "auto": select_method_auto (CAF names if multi-image)
call gauss_jacobi_rule(npts, alpha, beta, x, wts)
call gauss_jacobi_rule(npts, alpha, beta, x, wts, "glr_caf")
call gauss_jacobi_rule(npts, 0.0_dp, 0.0_dp, x, wts, "bogaert_caf")use GaussJacobiQuad, only: gauss_jacobi_batch_caf
! alphas(nbatch), betas(nbatch), xs(npts,nbatch), wts(npts,nbatch)
call gauss_jacobi_batch_caf(npts, nbatch, alphas, betas, xs, wts, "gw")
call gauss_jacobi_batch_caf(npts, nbatch, alphas, betas, xs, wts, "sturm")
call gauss_jacobi_batch_caf(npts, nbatch, alphas, betas, xs, wts, "glr")
call gauss_jacobi_batch_caf(npts, nbatch, alphas, betas, xs, wts, "bogaert")Batch kernels (serial math per owned rule): rec, gw, algo665, algo665_dc, sturm,
glr, bogaert
(and *_caf aliases map to the serial
kernel inside a batch).
Ownership: round-robin batch index i on
image mod(i-1, num_images())+1.
# 1-image
fpm build --flag "-fcoarray=single"
fpm test --flag "-fcoarray=single"
# multi-image (OpenCoarrays + MPICH)
fpm build --flag "-fcoarray=lib" \
--link-flag "-L$OC/lib -lcaf_mpi -L$MPICH/lib -lmpifort -lmpi"
cafrun -n 4 ./build/*/app/gjp_quad -- 64 0.5 0.5 rec_caf
cafrun -n 4 ./build/*/app/gjp_quad -- 64 0.0 0.0 bogaert_cafReproducible toolchain: docker/caf.
# single-rule node partition (rec)
cafrun -n 4 ./build/*/app/gjp_bench_caf single rec_caf 6144 0.5 0.5 5 2
# multi-rule batch (rec|gw|algo665|…)
cafrun -n 4 ./build/*/app/gjp_bench_caf batch gw 192 48 0.5 0.0 5 2*_caf single-rule paths match serial
within tight tolerances under -fcoarray=single. See test/test_auto_glr_bogaert.f90 (bogaert_caf, glr_caf), test/test_caf_rec.f90, test/test_caf_batch.f90.
| Module | Role |
|---|---|
GaussJacobiQuad |
gauss_jacobi_rule / gauss_jacobi; re-exports batch |
gjp_auto |
select_method_auto (CAF-aware) |
gjp_rec |
rec / rec_caf, ownership helpers |
gjp_glr |
glr (phase march) / glr_caf (index partition) |
gjp_bogaert |
bogaert / bogaert_caf |
gjp_sturm |
sturm / sturm_caf |
gjp_caf |
gauss_jacobi_batch_caf |
gjp_gw |
Golub–Welsch |
gjp_algo665 |
Algorithm 655 + imtqlx / D&C |