build(meson): updated build system. Note that this build system should be able to bring in MFEM and all needed deps automatically (tested on ubuntu, fedora, and macos)

This commit is contained in:
2026-11-09 13:50:06 -05:00
parent 811bbd9694
commit 829e53d56e
6 changed files with 3155 additions and 182 deletions

164
justfile
View File

@@ -1,14 +1,11 @@
set shell := ["bash", "-euo", "pipefail", "-c"]
meson_bin := env_var_or_default("MESON_BIN", "meson")
python_bin := env_var_or_default("PYTHON", "python3")
jobs := env_var_or_default("MFEM_JOBS", "4")
allow_preinstalled := env_var_or_default("MFEM_ALLOW_PREINSTALLED", "false")
dependency_prefix := env_var_or_default("MFEM_DEPENDENCY_PREFIX", "")
cuda_home := env_var_or_default("CUDA_HOME", "")
cuda_arch := env_var_or_default("MFEM_CUDA_ARCH", "native")
web_port := env_var_or_default("MFEM_WEB_PORT", "8000")
macos_target := env_var_or_default("MACOSX_DEPLOYMENT_TARGET", "11.0")
project_root := justfile_directory()
build_root := project_root + "/" + env_var_or_default("MFEM_BUILD_ROOT", "build")
@@ -19,22 +16,12 @@ parallel_dir := build_root + "/parallel"
debug_dir := build_root + "/debug"
cuda_dir := build_root + "/cuda"
hip_dir := build_root + "/hip"
wasm_dir := build_root + "/emscripten"
wasm_cache := build_root + "/emscripten-cache"
basic_install := install_root + "/basic"
serial_install := install_root + "/serial"
parallel_install := install_root + "/parallel"
debug_install := install_root + "/debug"
cuda_install := install_root + "/cuda"
hip_install := install_root + "/hip"
benchmark_trials := env_var_or_default("MFEM_BENCH_TRIALS", "5")
benchmark_mesh_n := env_var_or_default("MFEM_BENCH_MESH_N", "48")
benchmark_order := env_var_or_default("MFEM_BENCH_ORDER", "3")
benchmark_applications := env_var_or_default("MFEM_BENCH_APPLICATIONS", "50")
benchmark_minimum_apply_seconds := env_var_or_default("MFEM_BENCH_MIN_SECONDS", "1.0")
benchmark_max_applications := env_var_or_default("MFEM_BENCH_MAX_APPLICATIONS", "1000000")
benchmark_omp_threads := env_var_or_default("MFEM_BENCH_OMP_THREADS", "8")
benchmark_mpi_ranks := env_var_or_default("MFEM_BENCH_MPI_RANKS", "4")
cuda_cc := env_var_or_default("MFEM_CUDA_CC", env_var_or_default("CC", "cc"))
cuda_cxx := env_var_or_default("MFEM_CUDA_CXX", env_var_or_default("CXX", "c++"))
@@ -54,7 +41,6 @@ configure dir install_dir buildtype profile allow *extra:
"-Dallow_preinstalled={{ allow }}"
"-Ddependency_prefix={{ dependency_prefix }}"
"-Djobs={{ jobs }}"
"-Dbuild_examples=true"
"-Dbuild_tests=true"
)
if [[ -f "{{ dir }}/meson-private/coredata.dat" ]]; then
@@ -71,7 +57,7 @@ basic: (configure basic_dir basic_install "release" "minimal" allow_preinstalled
serial: (configure serial_dir serial_install "release" "portable" allow_preinstalled "-Dmfem_mpi=disabled" "-Dmfem_metis=disabled" "-Dmfem_cuda=disabled" "-Dmfem_hip=disabled") (build-and-test serial_dir)
parallel: (configure parallel_dir parallel_install "release" "portable" allow_preinstalled "-Dmfem_mpi=enabled" "-Dmfem_sundials=enabled" "-Dmfem_cuda=disabled" "-Dmfem_hip=disabled" "-Dbuild_benchmarks=true") (build-and-test parallel_dir)
parallel: (configure parallel_dir parallel_install "release" "portable" allow_preinstalled "-Dmfem_mpi=enabled" "-Dmfem_sundials=enabled" "-Dmfem_cuda=disabled" "-Dmfem_hip=disabled") (build-and-test parallel_dir)
debug: (configure debug_dir debug_install "debug" "portable" allow_preinstalled) (build-and-test debug_dir)
@@ -117,8 +103,6 @@ cuda:
"-Dallow_preinstalled={{ allow_preinstalled }}"
"-Ddependency_prefix={{ dependency_prefix }}"
"-Djobs={{ jobs }}"
"-Dbuild_examples=true"
"-Dbuild_benchmarks=true"
"-Dbuild_tests=true"
"-Dmfem_cuda=enabled"
"-Dmfem_hip=disabled"
@@ -133,152 +117,6 @@ cuda:
hip: (configure hip_dir hip_install "release" "portable" allow_preinstalled "-Dmfem_hip=enabled" "-Dmfem_cuda=disabled") (build-and-test hip_dir)
emscripten:
#!/usr/bin/env bash
set -euo pipefail
mkdir -p "{{ wasm_cache }}"
setup_args=(
"{{ wasm_dir }}"
"--cross-file={{ project_root }}/cross/wasm32.ini"
"--prefix={{ install_root }}/emscripten"
"--buildtype=release"
"-Dfeature_profile=portable"
"-Dallow_preinstalled=false"
"-Djobs={{ jobs }}"
"-Dbuild_python=false"
"-Dbuild_examples=true"
"-Dbuild_tests=true"
)
if [[ -f "{{ wasm_dir }}/meson-private/coredata.dat" ]]; then
setup_args=(--reconfigure "${setup_args[@]}")
fi
EM_CACHE="{{ wasm_cache }}" "{{ meson_bin }}" setup "${setup_args[@]}"
EM_CACHE="{{ wasm_cache }}" "{{ meson_bin }}" compile -C "{{ wasm_dir }}"
EM_CACHE="{{ wasm_cache }}" "{{ meson_bin }}" test -C "{{ wasm_dir }}" --print-errorlogs
serve-emscripten port=web_port: emscripten
@echo "MFEM browser demo: http://0.0.0.0:{{ port }}"
"{{ python_bin }}" -m http.server "{{ port }}" --bind 0.0.0.0 --directory "{{ wasm_dir }}/web"
python:
mkdir -p "{{ project_root }}/dist"
MACOSX_DEPLOYMENT_TARGET="{{ macos_target }}" "{{ python_bin }}" -m build --wheel --no-isolation --outdir "{{ project_root }}/dist"
run-serial: serial
"{{ serial_dir }}/examples/mfem-serial-poisson"
run-parallel ranks="4": parallel
"{{ python_bin }}" "{{ project_root }}/tools/run_mpi_test.py" --launcher "{{ parallel_dir }}/build-config/mfem/mfem-prefix/bin/mpiexec" --processes "{{ ranks }}" "{{ parallel_dir }}/examples/mfem-parallel-hypre"
run-cuda ranks="2": cuda
"{{ python_bin }}" "{{ project_root }}/tools/run_mpi_test.py" --launcher "{{ cuda_dir }}/build-config/mfem/mfem-prefix/bin/mpiexec" --processes "{{ ranks }}" "{{ cuda_dir }}/examples/mfem-parallel-hypre" cuda
benchmark: benchmark-cpu
benchmark-cpu: parallel
#!/usr/bin/env bash
set -euo pipefail
launcher="{{ parallel_dir }}/build-config/mfem/mfem-prefix/bin/mpiexec"
dep_prefix="{{ dependency_prefix }}"
if [[ ! -x "$launcher" && -n "$dep_prefix" ]]; then
for candidate in "$dep_prefix/bin/mpiexec" "$dep_prefix/bin/mpirun"; do
[[ -x "$candidate" ]] && launcher="$candidate" && break
done
fi
if [[ ! -x "$launcher" ]]; then
launcher="$(command -v mpiexec || command -v mpirun || true)"
fi
[[ -n "$launcher" ]] || { echo "No MPI launcher was found." >&2; exit 2; }
if [[ -n "$dep_prefix" ]]; then
export PATH="$dep_prefix/bin:$PATH"
if [[ "$(uname -s)" == Darwin ]]; then
export DYLD_LIBRARY_PATH="$dep_prefix/lib:$dep_prefix/lib64:${DYLD_LIBRARY_PATH:-}"
else
export LD_LIBRARY_PATH="$dep_prefix/lib:$dep_prefix/lib64:${LD_LIBRARY_PATH:-}"
fi
fi
"{{ python_bin }}" "{{ project_root }}/tools/run_backend_benchmarks.py" \
--executable "{{ parallel_dir }}/benchmarks/mfem-backend-benchmark" \
--launcher "$launcher" \
--cases cpu,ceed-cpu,omp,mpi \
--omp-threads "{{ benchmark_omp_threads }}" \
--mpi-ranks "{{ benchmark_mpi_ranks }}" \
--trials "{{ benchmark_trials }}" \
--mesh-n "{{ benchmark_mesh_n }}" \
--order "{{ benchmark_order }}" \
--applications "{{ benchmark_applications }}" \
--minimum-apply-seconds "{{ benchmark_minimum_apply_seconds }}" \
--max-applications "{{ benchmark_max_applications }}" \
--output-dir "{{ parallel_dir }}/benchmarks/results"
benchmark-cuda: cuda
#!/usr/bin/env bash
set -euo pipefail
launcher="{{ cuda_dir }}/build-config/mfem/mfem-prefix/bin/mpiexec"
dep_prefix="{{ dependency_prefix }}"
if [[ ! -x "$launcher" && -n "$dep_prefix" ]]; then
for candidate in "$dep_prefix/bin/mpiexec" "$dep_prefix/bin/mpirun"; do
[[ -x "$candidate" ]] && launcher="$candidate" && break
done
fi
if [[ ! -x "$launcher" ]]; then
launcher="$(command -v mpiexec || command -v mpirun || true)"
fi
[[ -n "$launcher" ]] || { echo "No MPI launcher was found." >&2; exit 2; }
if [[ -n "$dep_prefix" ]]; then
export PATH="$dep_prefix/bin:$PATH"
if [[ "$(uname -s)" == Darwin ]]; then
export DYLD_LIBRARY_PATH="$dep_prefix/lib:$dep_prefix/lib64:${DYLD_LIBRARY_PATH:-}"
else
export LD_LIBRARY_PATH="$dep_prefix/lib:$dep_prefix/lib64:${LD_LIBRARY_PATH:-}"
fi
fi
"{{ python_bin }}" "{{ project_root }}/tools/run_backend_benchmarks.py" \
--executable "{{ cuda_dir }}/benchmarks/mfem-backend-benchmark" \
--launcher "$launcher" \
--cases cpu,ceed-cpu,omp,mpi,cuda,ceed-cuda \
--omp-threads "{{ benchmark_omp_threads }}" \
--mpi-ranks "{{ benchmark_mpi_ranks }}" \
--trials "{{ benchmark_trials }}" \
--mesh-n "{{ benchmark_mesh_n }}" \
--order "{{ benchmark_order }}" \
--applications "{{ benchmark_applications }}" \
--minimum-apply-seconds "{{ benchmark_minimum_apply_seconds }}" \
--max-applications "{{ benchmark_max_applications }}" \
--output-dir "{{ cuda_dir }}/benchmarks/results"
benchmark-quick: parallel
#!/usr/bin/env bash
set -euo pipefail
launcher="{{ parallel_dir }}/build-config/mfem/mfem-prefix/bin/mpiexec"
dep_prefix="{{ dependency_prefix }}"
if [[ ! -x "$launcher" && -n "$dep_prefix" ]]; then
for candidate in "$dep_prefix/bin/mpiexec" "$dep_prefix/bin/mpirun"; do
[[ -x "$candidate" ]] && launcher="$candidate" && break
done
fi
if [[ ! -x "$launcher" ]]; then
launcher="$(command -v mpiexec || command -v mpirun || true)"
fi
[[ -n "$launcher" ]] || { echo "No MPI launcher was found." >&2; exit 2; }
if [[ -n "$dep_prefix" ]]; then
export PATH="$dep_prefix/bin:$PATH"
if [[ "$(uname -s)" == Darwin ]]; then
export DYLD_LIBRARY_PATH="$dep_prefix/lib:$dep_prefix/lib64:${DYLD_LIBRARY_PATH:-}"
else
export LD_LIBRARY_PATH="$dep_prefix/lib:$dep_prefix/lib64:${LD_LIBRARY_PATH:-}"
fi
fi
"{{ python_bin }}" "{{ project_root }}/tools/run_backend_benchmarks.py" \
--executable "{{ parallel_dir }}/benchmarks/mfem-backend-benchmark" \
--launcher "$launcher" \
--cases cpu,ceed-cpu,omp,mpi \
--omp-threads "{{ benchmark_omp_threads }}" \
--mpi-ranks "{{ benchmark_mpi_ranks }}" \
--trials 1 --mesh-n 16 --order 2 --applications 5 \
--minimum-apply-seconds 0 \
--output-dir "{{ parallel_dir }}/benchmarks/quick-results"
install-basic: basic
"{{ meson_bin }}" install -C "{{ basic_dir }}"