Skip to content
Draft
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
87 changes: 87 additions & 0 deletions easybuild/easyconfigs/o/OpenFOAM/OpenFOAM-v2506-foss-2025a-SP.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name = 'OpenFOAM'
version = 'v2506'
versionsuffix = '-SP'

homepage = 'https://www.openfoam.com/'
description = """OpenFOAM is a free, open source CFD software package.
OpenFOAM has an extensive range of features to solve anything from complex fluid flows
involving chemical reactions, turbulence and heat transfer,
to solid dynamics and electromagnetics.
This is a single-precision (WM_PRECISION_OPTION=SP) build, required by the fp32
petsc4Foam adapter (PetscScalar == Foam::solveScalar == float)."""

toolchain = {'name': 'foss', 'version': '2025a'}
# Users have found that vectorizion caused OpenFOAM to produce some very incorrect results.
# Disabling vectorize was confirmed to fix the the known issues.
# With no test suite, sticking to known working toolchain options until proven otherwise.
toolchainopts = {'cstd': 'c++17', 'vectorize': False}

# Single-precision build. Handled by the OpenFOAM easyblock 'precision' parameter (patched
# in this repo's easyblocks/openfoam.py, deployed via --include-easyblocks). etc/bashrc sets
# WM_PRECISION_OPTION=DP unconditionally, so the easyblock writes etc/prefs.sh (the sanctioned
# override, sourced after the DP default and before WM_OPTIONS is computed) => linux64GccSPInt32Opt.
precision = 'SP'

source_urls = ['https://sourceforge.net/projects/openfoam/files/%(version)s/']
sources = [
SOURCE_TGZ,
{
'filename': '%(name)s-plugins-%(version)s.tgz',
'extract_cmd': 'tar --strip-components=1 -C %(installdir)s/%(name)s-%(version)s/ -xzf %s'
}
]
patches = [
('OpenFOAM-v2406-cleanup.patch', 1),
('OpenFOAM-v2212-wmake-OpenMPI.patch', 1),
]
checksums = [
{'OpenFOAM-v2506.tgz': '63d26f48ae7ee9a7806a0ceb339ef8a0ba485a4714d54fbfb31e78e1a4849965'},
{'OpenFOAM-plugins-v2506.tgz': '79309a0e2e798bd533dc60384542fdfd916b3f5c131600c5a7696b51d4120845'},
{'OpenFOAM-v2406-cleanup.patch': '3abff48a517fb63719ad57fa32af746bc379a1e80c72d3e5852aa17cd13cf03e'},
{'OpenFOAM-v2212-wmake-OpenMPI.patch': '241dc4898c22aab0cbd10c1ea931a07a786508ee03462d45dbc1c202fee3ebe8'},
]

builddependencies = [
('Bison', '3.8.2'),
('CMake', '3.31.3'),
('flex', '2.6.4'),
]

dependencies = [
('libreadline', '8.2'),
('ncurses', '6.5'),
# OpenFOAM requires 64 bit METIS using 32 bit indexes (array indexes)
('METIS', '5.1.0'),
('SCOTCH', '7.0.8'),
('KaHIP', '3.19'),
('CGAL', '6.0.1'),
('GMP', '6.3.0'),
('MPFR', '4.2.2'),
('ParaView', '6.0.1'),
('gnuplot', '6.0.3'),
]

# --- EESSI-local fix: disable OpenFOAM readline auto-detection ---
# On EESSI, OpenFOAM's wmake have_readline script defaulted READLINE_ARCH_PATH to /usr,
# injecting `-DHAVE_LIBREADLINE -I/usr/include` into the setSet.C compile. On this system
# /usr/include resolves to the EESSI compat layer
# (/cvmfs/software.eessi.io/.../compat/linux/x86_64/usr/include/stdlib.h), whose __COLD
# attribute breaks the GCCcore-14.2.0 libstdc++ <cstdlib> (error: expected initializer
# before '__COLD'; 'abort' has not been declared). That aborts the mesh utilities build
# (make Error 2), leaving 10 solvers unbuilt and failing the EasyBuild sanity check.
# readline only provides interactive line-editing in setSet, which is irrelevant to the
# solvers and to petsc4Foam. Disable it cleanly: overwrite the config.sh/readline snippet
# with READLINE_ARCH_PATH=none (have_readline treats 'none' as "not found", so it emits no
# -DHAVE_LIBREADLINE / -I/usr/include at all) and belt-and-suspenders export it in the env.
# NOTE: prebuildopts must contain NO '%' characters. The OpenFOAM easyblock inlines
# prebuildopts into the build command and then runs `cmd_tmpl % cmd` (a second %-format
# pass), so a literal %s here raises "not enough arguments for format string". Use echo,
# not printf, to write the config snippet.
prebuildopts = (
'mkdir -p "$WM_PROJECT_DIR/etc/easybuild/config.sh" && '
'echo "export READLINE_ARCH_PATH=none" > "$WM_PROJECT_DIR/etc/easybuild/config.sh/readline" && '
'export FOAM_CONFIG_ETC=etc/easybuild && '
'export READLINE_ARCH_PATH=none && '
)

moduleclass = 'cae'
125 changes: 125 additions & 0 deletions easybuild/easyconfigs/p/PETSc/PETSc-3.23.5-foss-2025a-HIP-fp32.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# EasyBuild easyconfig: PETSc with AMD-GPU (HIP) backend — SINGLE PRECISION (fp32)
#
# =========================================================================
# fp32 VARIANT of PETSc-3.23.5-foss-2025a-HIP.eb.
# IDENTICAL to the (default, double-precision / fp64) HIP easyconfig in
# every respect EXCEPT:
# * versionsuffix '-HIP' -> '-HIP-fp32'
# * configopts adds --with-precision=single
# See PETSc-3.23.5-foss-2025a-HIP.eb for the full rationale on the GPU-arch
# parameterisation and the ROCm dependency reconciliation — all of that is
# unchanged here. Only the scalar precision differs.
#
# WHY A SEPARATE MODULE:
# PETSc's scalar precision (double vs single) is fixed at configure time and
# baked into libpetsc + the installed headers. fp32 and fp64 cannot coexist
# in one install, so the fp32 build gets its own module
# (PETSc/3.23.5-foss-2025a-HIP-fp32) and its own petsc4Foam adapter linked
# against it (petsc4Foam/v2506-foss-2025a-HIP-fp32).
# =========================================================================

easyblock = 'EB_PETSc'

name = 'PETSc'
version = '3.23.5'
# fp32 single-precision HIP variant. Arch (gfxNNN) still lives in the EESSI accel
# path, not the suffix; the suffix marks (HIP backend + single precision).
versionsuffix = '-HIP-fp32'

homepage = 'https://www.mcs.anl.gov/petsc'
description = """PETSc, pronounced PET-see (the S is silent), is a suite of data structures and routines for the
scalable (parallel) solution of scientific applications modeled by partial differential equations.

This variant enables the AMD-GPU (HIP) backend with hipBLAS and hipSPARSE, built in SINGLE precision
(--with-precision=single, fp32), so GPU-accelerated Krylov solvers/preconditioners run in 32-bit
floating point (e.g. for the petsc4Foam / OpenFOAM external-solver adapter). The target GPU
architecture is taken from the amdgcn_capabilities parameter (default gfx1101, AMD Radeon Pro V710),
overridable via --amdgcn-capabilities."""

toolchain = {'name': 'foss', 'version': '2025a'}
toolchainopts = {'openmp': True, 'usempi': True, 'pic': True}

source_urls = [
'https://web.cels.anl.gov/projects/petsc/download/release-snapshots',
]
sources = [SOURCELOWER_TAR_GZ]
checksums = ['b0bb614dfbf36c286c8cad30912fe77359dccbf6b65a5edd1dde82af293f21fc']

builddependencies = [('CMake', '3.31.3')]

# --- GPU architecture (first-class framework param; NOT hardcoded) -------------
# Default target is gfx1101 (V710). EESSI overrides per accel path via
# --amdgcn-capabilities (EASYBUILD_AMDGCN_CAPABILITIES); the value flows into
# configopts through the %(amdgcn_cc_space_sep)s template below.
amdgcn_capabilities = ['gfx1101']

dependencies = [
('Python', '3.13.1'),
('SciPy-bundle', '2025.06'),
('Boost', '1.88.0'),
('METIS', '5.1.0'),
('SCOTCH', '7.0.8'),
('MUMPS', '5.8.1', '-metis'),
# NOTE (fp32-only delta): SuiteSparse (7.10.3) and Hypre (2.33.0) are DROPPED
# from the single-precision build because both are double-precision-only:
# * SuiteSparse ships no single-precision UMFPACK/CHOLMOD/etc. PETSc aborts
# configure with "Cannot use SuiteSparse with single, it is not available
# in this precision".
# * Hypre's HYPRE_config.h has HYPRE_SINGLE #undef (built for HYPRE_Real=double),
# so PETSc single cannot link it.
# The EB_PETSc easyblock auto-injects each listed dependency via get_software_root()
# (--with-<dep>=1 --with-<dep>-dir=<root>), so the only clean, reviewable way to keep
# them out of an fp32 configure is to not list them here. MUMPS (libsmumps) and
# SuperLU_DIST (psgssvx symbols present) DO provide single precision, so they stay.
('ParMETIS', '4.0.3'),
('SuperLU_DIST', '9.1.0'),
('mpi4py', '4.1.0'),
# --- AMD-GPU (HIP) stack, as shipped by EESSI 2025.06 ---
# These are built with the rocm-compilers/19.0.0 toolchain (NOT foss), so the
# dep toolchain MUST be given explicitly (4-element form), otherwise EasyBuild
# applies PETSc's foss-2025a toolchain and looks for a non-existent module.
# Resulting module names: HIP/6.4.1-rocm-compilers-19.0.0-ROCm-6.4.1, etc.
('HIP', '6.4.1', '-ROCm-6.4.1', ('rocm-compilers', '19.0.0')),
('hipBLAS', '2.4.0', '-ROCm-6.4.1', ('rocm-compilers', '19.0.0')),
('hipSPARSE', '3.2.0', '-ROCm-6.4.1', ('rocm-compilers', '19.0.0')),
# PETSc's hip.py liblist requires libhipsolver (grouped with rocrand) whenever
# the HIP backend is on; without it configure fails at 'ld: cannot find -lhipsolver'.
('hipSOLVER', '2.4.0', '-ROCm-6.4.1', ('rocm-compilers', '19.0.0')),
# rocRAND is grouped WITH hipsolver in PETSc's liblist; it must be a direct dep so
# its lib dir is on LIBRARY_PATH, else configure fails at 'ld: cannot find -lrocrand'.
('rocRAND', '3.3.0', '-ROCm-6.4.1', ('rocm-compilers', '19.0.0')),
# rocm-core provides <rocm-core/rocm_version.h>, which PETSc's hip.py version
# conftest #includes to emit PETSC_PKG_HIP_VERSION_* macros. Without it on CPATH,
# version detection silently fails and petscdevice_hip.h errors on an undefined
# PETSC_PKG_HIP_VERSION_GE, falling through to a non-existent bare <hipblas.h>.
# NOTE: built with the GCCcore-14.2.0 subtoolchain (NOT rocm-compilers), so the
# 3-element form resolves rocm-core/6.4.1-GCCcore-14.2.0-ROCm-6.4.1.
('rocm-core', '6.4.1', '-ROCm-6.4.1'),
# rocThrust provides <thrust/complex.h>, hard-required by petscsystypes.h when the
# HIP device backend is on (compiling src/sys/memory/hip/mhiphost for gfx1101).
# EESSI 2025.06 ships no rocThrust module, so we build it (header-only, deps rocPRIM).
('rocThrust', '3.3.0', '-ROCm-6.4.1', ('rocm-compilers', '19.0.0')),
]

# Base (CPU) configure knobs from upstream PETSc-3.23.5-foss-2025a.eb ...
configopts = '--LIBS="$LIBS -lrt" --with-mpi4py=0 '
# ... single precision (fp32): scalars are 32-bit. This is the ONLY functional
# delta from the default (fp64) HIP easyconfig.
configopts += '--with-precision=single '
# PETSc/foss auto-enables FFTW from the toolchain (foss bundles FFTW), but PETSc
# refuses to use FFTW in single precision ("Cannot use fftw with single, it is not
# available in this precision"), which aborts configure. FFTW is not needed by the
# petsc4Foam linear-solver path, so disable it for the fp32 build.
configopts += '--with-fftw=0 '
# ... plus the AMD-GPU (HIP) delta. --with-hip-arch is fed the framework template
# so the EESSI/CLI amdgcn override propagates (expands to "gfx1101" here). PETSc
# locates hipcc/ROCm from the loaded HIP module (ROCM_PATH/PATH), not /opt/rocm.
configopts += '--with-hip=1 --with-hip-arch=%(amdgcn_cc_space_sep)s '
configopts += '--with-hipblas=1 --with-hipsparse=1 '

# Match the proven -O3, no-debugging production settings from the manual build.
buildopts = 'COPTFLAGS="-O3" CXXOPTFLAGS="-O3" HIPOPTFLAGS="-O3"'

shared_libs = 1

moduleclass = 'numlib'
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# EasyBuild easyconfig: petsc4Foam — OpenFOAM external-solver (PETSc) adapter, HIP, fp32
#
# =========================================================================
# fp32 VARIANT of petsc4Foam-v2506-foss-2025a-HIP.eb.
# IDENTICAL to the (double-precision / fp64) HIP adapter easyconfig EXCEPT:
# * versionsuffix '-HIP' -> '-HIP-fp32'
# * PETSc dependency '-HIP' -> '-HIP-fp32'
# The adapter compiles no GPU code itself — it only links -lpetsc — so the
# precision is inherited entirely from the PETSc it links against. Linking the
# fp32 PETSc (built --with-precision=single) yields a single-precision adapter.
# See petsc4Foam-v2506-foss-2025a-HIP.eb for the full rationale (unchanged).
# =========================================================================

easyblock = 'Bundle'

name = 'petsc4Foam'
version = 'v2506'
# fp32 single-precision variant. Arch (gfxNNN) still lives in the accel path + the
# PETSc-HIP-fp32 dep; the suffix marks (HIP backend + single precision).
versionsuffix = '-HIP-fp32'

homepage = 'https://develop.openfoam.com/modules/external-solver'
description = """petsc4Foam is the OpenFOAM 'external-solver' module (ESI), providing a
PETSc linear-solver adapter (libpetscFoam) that lets OpenFOAM offload its linear systems
to PETSc — here to a PETSc built with the AMD-GPU HIP backend (hipBLAS/hipSPARSE) in SINGLE
precision (fp32), by default for AMD Radeon Pro V710 (gfx1101). Built via OpenFOAM's wmake
against OpenFOAM-v2506 and a GPU-enabled, single-precision PETSc 3.23.5. Grounded in a working
manual build verified on host ROCm 6.3.1."""

toolchain = {'name': 'foss', 'version': '2025a'}

dependencies = [
('OpenFOAM', 'v2506', '-SP'), # single-precision OpenFOAM (fp32 adapter requires solveScalar==float)
('PETSc', '3.23.5', '-HIP-fp32'), # this repo's single-precision PETSc-HIP easyconfig
]

# The adapter ships inside the ESI external-solver module, versioned to the OpenFOAM
# release. Pin the real snapshot + checksum before contributing.
#
# --- Build: OpenFOAM wmake (mirrors ~/external-solver-esi/Allwmake) -------------
# We drive the build as a Bundle with a single component using the external-solver
# source. Because OpenFOAM builds via wmake (not configure/make/cmake), the actual
# compile is the Allwmake script, which honours FOAM_MODULE_LIBBIN.
#
# Required environment at build time (set by the OpenFOAM + PETSc-HIP modules,
# asserted here for clarity):
# - OpenFOAM bashrc sourced (WM_PROJECT_DIR, wmake on PATH, WM_MPLIB=SYSTEMOPENMPI)
# - PETSC_ARCH_PATH -> the PETSc-HIP-fp32 install (EBROOTPETSC). Make/options reads
# PETSC_INC_DIR / PETSC_LIB_DIR from it and links -lpetsc.
# - FOAM_MODULE_LIBBIN -> point at %(installdir)s/lib so libpetscFoam.so lands
# in the module (default falls back to FOAM_USER_LIBBIN).

# Upstream external-solver has NO 'v2506' tag (latest real tag is v2412; default
# branch 'main' is byte-for-byte identical to v2412 in content). The adapter is
# OpenFOAM-version-agnostic (compiles against loaded OpenFOAM $LIB_SRC, links
# -lpetsc), so v2412 sources build correctly against the OpenFOAM/v2506 dep. Keep
# the module identity at v2506 but source the real, checksummed v2412 snapshot.
local_es_source_ver = 'v2412'

components = [
(name, version, {
'easyblock': 'MakeCp',
'source_urls': ['https://develop.openfoam.com/modules/external-solver/-/archive/%s/' % local_es_source_ver],
'sources': ['external-solver-%s.tar.gz' % local_es_source_ver],
'checksums': ['db6a161c68a2a0d3095c67bc82a9f3c84bd55dd72dcd2c57f6b847098b880ff6'],
'start_dir': 'external-solver-%s' % local_es_source_ver,
# Export PETSC_ARCH_PATH (ASSUMPTION 2) and target the module libdir,
# then run the upstream Allwmake. wmake libso produces libpetscFoam.so.
'prebuildopts': (
# Allwmake requires the full OpenFOAM shell environment (WM_PROJECT_DIR,
# wmake, $LIB_SRC, ...). The OpenFOAM module exports $FOAM_BASH (path to
# OpenFOAM/etc/bashrc); source it to populate that environment.
'source $FOAM_BASH && '
'export PETSC_ARCH_PATH=$EBROOTPETSC && '
'export FOAM_MODULE_LIBBIN=%(installdir)s/lib && '
'mkdir -p %(installdir)s/lib && '
),
'build_cmd': './Allwmake',
'buildopts': '-j %(parallel)s',
# Allwmake already installs into FOAM_MODULE_LIBBIN; nothing extra to copy.
'files_to_copy': [],
}),
]

sanity_check_paths = {
'files': ['lib/libpetscFoam.so'],
'dirs': [],
}

# petsc4Foam is loaded by OpenFOAM at runtime via libs ("libpetscFoam.so"); make
# the module's lib dir discoverable.
modextrapaths = {
'LD_LIBRARY_PATH': ['lib'],
'FOAM_MODULE_LIBBIN': ['lib'],
}

moduleclass = 'cae'
Loading