caf

Coarray Fortran API (library)

Scope

GaussJacobiQuad supports Coarray Fortran (CAF) for multi-image runs.

Methods

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.

Single-rule API

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")

Multi-rule batch API

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.

Build

# 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_caf

Reproducible toolchain: docker/caf.

Timed driver

# 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

Correctness

*_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.

Modules

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