feat(initial): added portable mfem build system
This commit is contained in:
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/dist/
|
||||||
|
/.mesonpy-*/
|
||||||
|
/.pytest_cache/
|
||||||
|
/.venv/
|
||||||
|
__pycache__/
|
||||||
|
*.egg-info/
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
subprojects/packagecache/
|
||||||
|
subprojects/*/
|
||||||
|
!subprojects/packagefiles/
|
||||||
|
|
||||||
18
build-check/meson.build
Normal file
18
build-check/meson.build
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
message('C compiler: ' + cc.get_id())
|
||||||
|
message('C++ compiler: ' + cpp.get_id())
|
||||||
|
|
||||||
|
if not cpp.has_header('memory') or not cpp.compiles('''
|
||||||
|
#include <type_traits>
|
||||||
|
int main() { static_assert(__cplusplus >= 201703L); return 0; }
|
||||||
|
''', name: 'C++17 language support')
|
||||||
|
error('MFEM 4.10 requires a C++17-or-newer compiler.')
|
||||||
|
endif
|
||||||
|
|
||||||
|
cmake_program = find_program('cmake', required: true)
|
||||||
|
# With meson-python, the generated native file pins this to the interpreter
|
||||||
|
# building the wheel. For command-line builds, PATH controls the selection.
|
||||||
|
python_build = python_mod.find_installation(required: true, pure: false)
|
||||||
|
|
||||||
|
if meson.is_cross_build()
|
||||||
|
message('Cross build: ' + build_machine.system() + ' -> ' + host_machine.system())
|
||||||
|
endif
|
||||||
2
build-config/meson.build
Normal file
2
build-config/meson.build
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
subdir('mfem')
|
||||||
|
|
||||||
651
build-config/mfem/meson.build
Normal file
651
build-config/mfem/meson.build
Normal file
@@ -0,0 +1,651 @@
|
|||||||
|
profile = get_option('feature_profile')
|
||||||
|
allow_preinstalled = get_option('allow_preinstalled')
|
||||||
|
dependency_prefix = get_option('dependency_prefix')
|
||||||
|
wheel_carries_native_bundle = get_option('build_python') and get_option('python_install_native')
|
||||||
|
|
||||||
|
|
||||||
|
effective_allow_preinstalled = allow_preinstalled and not wheel_carries_native_bundle
|
||||||
|
is_wasm = host_machine.system() == 'emscripten'
|
||||||
|
is_windows = host_machine.system() == 'windows'
|
||||||
|
can_build_posix_mpi = not meson.is_cross_build() and not is_windows and not is_wasm
|
||||||
|
|
||||||
|
nvcc_program = find_program('nvcc', required: false)
|
||||||
|
hipcc_program = find_program('hipcc', required: false)
|
||||||
|
dependency_has_nvcc = dependency_prefix != '' and fs.exists(dependency_prefix / 'bin' / 'nvcc')
|
||||||
|
dependency_has_hipcc = dependency_prefix != '' and fs.exists(dependency_prefix / 'bin' / 'hipcc')
|
||||||
|
cuda_toolkit_available = nvcc_program.found() or dependency_has_nvcc
|
||||||
|
hip_toolkit_available = hipcc_program.found() or dependency_has_hipcc
|
||||||
|
openmp_dep = dependency('openmp', required: false)
|
||||||
|
|
||||||
|
bundled_compiler_openmp = cpp.get_id() == 'gcc' and openmp_dep.found()
|
||||||
|
usable_openmp = openmp_dep.found() and (
|
||||||
|
effective_allow_preinstalled or dependency_prefix != '' or bundled_compiler_openmp
|
||||||
|
)
|
||||||
|
simd_arch_supported = host_machine.cpu_family() in ['x86', 'x86_64']
|
||||||
|
if host_machine.cpu_family() in ['aarch64', 'arm']
|
||||||
|
simd_arch_supported = cpp.compiles('''
|
||||||
|
#ifndef __ARM_FEATURE_SVE
|
||||||
|
#error SVE is required by MFEM's ARM SIMD specialization
|
||||||
|
#endif
|
||||||
|
int main() { return 0; }
|
||||||
|
''', name: 'MFEM ARM SVE SIMD support')
|
||||||
|
elif host_machine.cpu_family() in ['ppc', 'ppc64']
|
||||||
|
simd_arch_supported = cpp.compiles('''
|
||||||
|
#ifndef __VSX__
|
||||||
|
#error VSX is required by MFEM's Power SIMD specialization
|
||||||
|
#endif
|
||||||
|
int main() { return 0; }
|
||||||
|
''', name: 'MFEM Power VSX SIMD support')
|
||||||
|
endif
|
||||||
|
|
||||||
|
mfem_feature_names = [
|
||||||
|
'mpi', 'metis', 'exceptions', 'zlib', 'libunwind', 'lapack',
|
||||||
|
'thread_safe', 'openmp', 'legacy_openmp', 'memalloc', 'sundials',
|
||||||
|
'suitesparse', 'superlu', 'superlu5', 'mumps', 'strumpack', 'cudss',
|
||||||
|
'ginkgo', 'amgx', 'magma', 'gnutls', 'gslib', 'hdf5', 'netcdf',
|
||||||
|
'petsc', 'slepc', 'mpfr', 'sidre', 'fms', 'conduit', 'pumi', 'hiop',
|
||||||
|
'cuda', 'hip', 'occa', 'raja', 'ceed', 'umpire', 'simd', 'adios2',
|
||||||
|
'caliper', 'algoim', 'mkl_cpardiso', 'mkl_pardiso', 'adforward',
|
||||||
|
'codipack', 'benchmark', 'parelag', 'tribol', 'enzyme', 'moonolith',
|
||||||
|
'simmetrix',
|
||||||
|
]
|
||||||
|
|
||||||
|
mfem_cmake_names = [
|
||||||
|
'MFEM_USE_MPI', 'MFEM_USE_METIS', 'MFEM_USE_EXCEPTIONS', 'MFEM_USE_ZLIB',
|
||||||
|
'MFEM_USE_LIBUNWIND', 'MFEM_USE_LAPACK', 'MFEM_THREAD_SAFE',
|
||||||
|
'MFEM_USE_OPENMP', 'MFEM_USE_LEGACY_OPENMP', 'MFEM_USE_MEMALLOC',
|
||||||
|
'MFEM_USE_SUNDIALS', 'MFEM_USE_SUITESPARSE', 'MFEM_USE_SUPERLU',
|
||||||
|
'MFEM_USE_SUPERLU5', 'MFEM_USE_MUMPS', 'MFEM_USE_STRUMPACK',
|
||||||
|
'MFEM_USE_CUDSS', 'MFEM_USE_GINKGO', 'MFEM_USE_AMGX', 'MFEM_USE_MAGMA',
|
||||||
|
'MFEM_USE_GNUTLS', 'MFEM_USE_GSLIB', 'MFEM_USE_HDF5', 'MFEM_USE_NETCDF',
|
||||||
|
'MFEM_USE_PETSC', 'MFEM_USE_SLEPC', 'MFEM_USE_MPFR', 'MFEM_USE_SIDRE',
|
||||||
|
'MFEM_USE_FMS', 'MFEM_USE_CONDUIT', 'MFEM_USE_PUMI', 'MFEM_USE_HIOP',
|
||||||
|
'MFEM_USE_CUDA', 'MFEM_USE_HIP', 'MFEM_USE_OCCA', 'MFEM_USE_RAJA',
|
||||||
|
'MFEM_USE_CEED', 'MFEM_USE_UMPIRE', 'MFEM_USE_SIMD', 'MFEM_USE_ADIOS2',
|
||||||
|
'MFEM_USE_CALIPER', 'MFEM_USE_ALGOIM', 'MFEM_USE_MKL_CPARDISO',
|
||||||
|
'MFEM_USE_MKL_PARDISO', 'MFEM_USE_ADFORWARD', 'MFEM_USE_CODIPACK',
|
||||||
|
'MFEM_USE_BENCHMARK', 'MFEM_USE_PARELAG', 'MFEM_USE_TRIBOL',
|
||||||
|
'MFEM_USE_ENZYME', 'MFEM_USE_MOONOLITH', 'MFEM_USE_SIMMETRIX',
|
||||||
|
]
|
||||||
|
|
||||||
|
source_capable = {
|
||||||
|
'mpi': can_build_posix_mpi,
|
||||||
|
'metis': not is_windows and not is_wasm,
|
||||||
|
'exceptions': true,
|
||||||
|
'zlib': true,
|
||||||
|
'thread_safe': true,
|
||||||
|
'openmp': bundled_compiler_openmp,
|
||||||
|
'legacy_openmp': bundled_compiler_openmp,
|
||||||
|
'memalloc': true,
|
||||||
|
'sundials': not is_windows and not is_wasm,
|
||||||
|
'gslib': not is_windows and not is_wasm,
|
||||||
|
'fms': not is_windows,
|
||||||
|
'ceed': not is_windows,
|
||||||
|
'algoim': not meson.is_cross_build() and not is_windows and not is_wasm,
|
||||||
|
'cuda': cuda_toolkit_available and not is_wasm and not host_machine.system() == 'darwin',
|
||||||
|
'hip': hip_toolkit_available and not is_wasm and not host_machine.system() == 'darwin',
|
||||||
|
'simd': simd_arch_supported and not is_wasm,
|
||||||
|
}
|
||||||
|
|
||||||
|
single_precision_conflicts = [
|
||||||
|
'sundials', 'suitesparse', 'superlu', 'strumpack', 'ginkgo', 'amgx',
|
||||||
|
'slepc', 'pumi', 'simmetrix', 'gslib', 'algoim', 'ceed', 'tribol', 'moonolith',
|
||||||
|
]
|
||||||
|
|
||||||
|
cuda_option = get_option('mfem_cuda')
|
||||||
|
hip_option = get_option('mfem_hip')
|
||||||
|
profile_cuda = false
|
||||||
|
profile_hip = false
|
||||||
|
if cuda_option.enabled() and hip_option.enabled()
|
||||||
|
profile_cuda = true
|
||||||
|
profile_hip = true
|
||||||
|
elif cuda_option.enabled()
|
||||||
|
profile_cuda = true
|
||||||
|
elif hip_option.enabled()
|
||||||
|
profile_hip = true
|
||||||
|
else
|
||||||
|
profile_cuda = cuda_option.auto() and source_capable.get('cuda')
|
||||||
|
profile_hip = hip_option.auto() and not profile_cuda and source_capable.get('hip')
|
||||||
|
endif
|
||||||
|
|
||||||
|
portable_defaults = {
|
||||||
|
'mpi': can_build_posix_mpi,
|
||||||
|
'metis': can_build_posix_mpi,
|
||||||
|
'exceptions': true,
|
||||||
|
'zlib': true,
|
||||||
|
'thread_safe': true,
|
||||||
|
'openmp': usable_openmp,
|
||||||
|
'memalloc': true,
|
||||||
|
'sundials': not is_windows and not is_wasm,
|
||||||
|
'gslib': not is_windows and not is_wasm,
|
||||||
|
'fms': not is_windows,
|
||||||
|
'ceed': not is_windows,
|
||||||
|
'algoim': source_capable.get('algoim'),
|
||||||
|
'cuda': profile_cuda,
|
||||||
|
'hip': profile_hip,
|
||||||
|
'simd': simd_arch_supported and not is_wasm,
|
||||||
|
}
|
||||||
|
|
||||||
|
full_cuda = false
|
||||||
|
full_hip = false
|
||||||
|
if profile == 'full'
|
||||||
|
full_cuda = profile_cuda
|
||||||
|
full_hip = profile_hip
|
||||||
|
endif
|
||||||
|
|
||||||
|
mfem_features = {}
|
||||||
|
mfem_feature_states = []
|
||||||
|
foreach feature_name : mfem_feature_names
|
||||||
|
feature_opt = get_option('mfem_' + feature_name)
|
||||||
|
feature_on = feature_opt.enabled()
|
||||||
|
if feature_opt.auto()
|
||||||
|
if profile == 'portable'
|
||||||
|
feature_on = portable_defaults.get(feature_name, false)
|
||||||
|
elif profile == 'full'
|
||||||
|
feature_on = true
|
||||||
|
if feature_name == 'legacy_openmp' or feature_name == 'superlu5'
|
||||||
|
feature_on = false
|
||||||
|
elif feature_name == 'openmp'
|
||||||
|
feature_on = usable_openmp
|
||||||
|
elif feature_name == 'cuda'
|
||||||
|
feature_on = full_cuda
|
||||||
|
elif feature_name == 'hip'
|
||||||
|
feature_on = full_hip
|
||||||
|
elif feature_name == 'cudss' or feature_name == 'amgx'
|
||||||
|
feature_on = full_cuda
|
||||||
|
elif feature_name == 'magma'
|
||||||
|
feature_on = full_cuda or full_hip
|
||||||
|
elif feature_name == 'simd'
|
||||||
|
feature_on = simd_arch_supported and not is_wasm
|
||||||
|
elif feature_name == 'enzyme'
|
||||||
|
feature_on = cpp.get_id() == 'clang' and not full_cuda
|
||||||
|
elif feature_name in ['benchmark', 'parelag', 'tribol']
|
||||||
|
feature_on = false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if (
|
||||||
|
feature_opt.auto() and get_option('mfem_precision') == 'single' and
|
||||||
|
feature_name in single_precision_conflicts
|
||||||
|
)
|
||||||
|
feature_on = false
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (
|
||||||
|
feature_on and
|
||||||
|
feature_name not in ['cuda', 'hip', 'openmp', 'simd'] and
|
||||||
|
not effective_allow_preinstalled and dependency_prefix == '' and
|
||||||
|
not source_capable.get(feature_name, false)
|
||||||
|
)
|
||||||
|
error(
|
||||||
|
'Selected feature mfem_' + feature_name + ' has no bundled source provider. ' +
|
||||||
|
'Supply -Ddependency_prefix=/path/to/a/hermetic/prefix or enable preinstalled dependencies.'
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
mfem_features += {feature_name: feature_on}
|
||||||
|
mfem_feature_states += [feature_on]
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
foreach build_only_feature : ['benchmark', 'parelag', 'tribol']
|
||||||
|
if get_option('mfem_' + build_only_feature).enabled()
|
||||||
|
error(
|
||||||
|
'mfem_' + build_only_feature + ' is an upstream non-installed ' +
|
||||||
|
'benchmark/miniapp build switch, not an MFEM library capability. ' +
|
||||||
|
'Build that program in a separate consumer project against this SDK.'
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
mfem_has_mpi = mfem_features.get('mpi')
|
||||||
|
mfem_has_metis = mfem_features.get('metis')
|
||||||
|
mfem_has_cuda = mfem_features.get('cuda')
|
||||||
|
mfem_has_hip = mfem_features.get('hip')
|
||||||
|
mfem_has_openmp = mfem_features.get('openmp')
|
||||||
|
mfem_has_gslib = mfem_features.get('gslib')
|
||||||
|
mfem_has_zlib = mfem_features.get('zlib')
|
||||||
|
mfem_has_sundials = mfem_features.get('sundials')
|
||||||
|
|
||||||
|
if get_option('mfem_mpi').enabled() and not can_build_posix_mpi and not allow_preinstalled and dependency_prefix == ''
|
||||||
|
error('The bundled MPI provider needs a native POSIX build. For cross/Windows builds, provide an MPI prefix or use -Dmfem_mpi=disabled.')
|
||||||
|
endif
|
||||||
|
if get_option('mfem_cuda').enabled() and not source_capable.get('cuda')
|
||||||
|
error('CUDA was forced on, but nvcc and a supported non-macOS CUDA host were not found.')
|
||||||
|
endif
|
||||||
|
if get_option('mfem_hip').enabled() and not source_capable.get('hip')
|
||||||
|
error('HIP was forced on, but hipcc was not found.')
|
||||||
|
endif
|
||||||
|
if get_option('mfem_openmp').enabled() and not usable_openmp
|
||||||
|
error('OpenMP was forced on, but no permitted OpenMP runtime was found for the selected compiler.')
|
||||||
|
endif
|
||||||
|
if get_option('mfem_simd').enabled() and not simd_arch_supported
|
||||||
|
error('SIMD was forced on, but MFEM has no intrinsic specialization for this target/compiler.')
|
||||||
|
endif
|
||||||
|
if get_option('mfem_enzyme').enabled() and cpp.get_id() != 'clang'
|
||||||
|
error('Enzyme was forced on, but Enzyme requires a matching Clang/LLVM compiler toolchain.')
|
||||||
|
endif
|
||||||
|
if mfem_has_cuda and mfem_has_hip
|
||||||
|
error('MFEM CUDA and HIP backends are mutually exclusive.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('enzyme') and mfem_has_cuda
|
||||||
|
error('The bundled CUDA route uses nvcc and cannot be combined with Enzyme; use a dedicated clang-CUDA toolchain or disable one feature.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('cudss') and not mfem_has_cuda
|
||||||
|
error('cuDSS requires -Dmfem_cuda=enabled (or an auto-detected CUDA toolkit).')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('amgx') and not mfem_has_cuda
|
||||||
|
error('AmgX requires the CUDA backend.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('magma') and not (mfem_has_cuda or mfem_has_hip)
|
||||||
|
error('MAGMA requires either the CUDA or HIP backend.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('slepc') and not mfem_features.get('petsc')
|
||||||
|
error('SLEPc requires PETSc.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('adforward') and not mfem_features.get('codipack')
|
||||||
|
error('Forward-mode automatic differentiation requires CoDiPack.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('superlu5') and not mfem_features.get('superlu')
|
||||||
|
error('The SuperLU 5 compatibility option requires SuperLU_DIST.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('simmetrix') and not mfem_features.get('pumi')
|
||||||
|
error('Simmetrix integration requires PUMI.')
|
||||||
|
endif
|
||||||
|
foreach mpi_feature : ['superlu', 'mumps', 'strumpack', 'petsc', 'slepc', 'pumi', 'mkl_cpardiso', 'tribol']
|
||||||
|
if mfem_features.get(mpi_feature) and not mfem_has_mpi
|
||||||
|
error('MFEM feature ' + mpi_feature + ' requires MPI/Hypre.')
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
if mfem_features.get('legacy_openmp') and (
|
||||||
|
mfem_has_openmp or mfem_has_cuda or mfem_features.get('raja') or mfem_features.get('occa'))
|
||||||
|
error('Legacy OpenMP cannot be combined with OpenMP, CUDA, RAJA, or OCCA.')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('legacy_openmp') and not mfem_features.get('thread_safe')
|
||||||
|
error('Legacy OpenMP requires MFEM thread-safe mode.')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if get_option('mfem_precision') == 'single'
|
||||||
|
foreach single_conflict : single_precision_conflicts
|
||||||
|
if mfem_features.get(single_conflict)
|
||||||
|
error('Single precision is incompatible with MFEM feature ' + single_conflict + '.')
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
endif
|
||||||
|
mfem_consumer_cpp_std = (
|
||||||
|
mfem_features.get('raja') or mfem_features.get('umpire')
|
||||||
|
) ? 'c++20' : 'c++17'
|
||||||
|
system_mfem = disabler()
|
||||||
|
mfem_provider = 'source bundle'
|
||||||
|
if effective_allow_preinstalled
|
||||||
|
system_candidate = dependency('mfem', version: '>=4.10', required: false, allow_fallback: false)
|
||||||
|
if system_candidate.found()
|
||||||
|
system_compatible = true
|
||||||
|
foreach i : range(mfem_feature_names.length())
|
||||||
|
if mfem_feature_states[i]
|
||||||
|
feature_macro = mfem_cmake_names[i]
|
||||||
|
macro_ok = cpp.compiles(
|
||||||
|
'#include <mfem/config/config.hpp>\n#ifndef ' + feature_macro + '\n#error missing\n#endif\nint main(){return 0;}',
|
||||||
|
dependencies: system_candidate,
|
||||||
|
name: 'system MFEM provides ' + feature_macro,
|
||||||
|
)
|
||||||
|
system_compatible = system_compatible and macro_ok
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
precision_macro = get_option('mfem_precision') == 'single' ? 'MFEM_USE_SINGLE' : 'MFEM_USE_DOUBLE'
|
||||||
|
system_compatible = system_compatible and cpp.compiles(
|
||||||
|
'#include <mfem/config/config.hpp>\n#ifndef ' + precision_macro + '\n#error precision mismatch\n#endif\nint main(){return 0;}',
|
||||||
|
dependencies: system_candidate,
|
||||||
|
name: 'system MFEM uses requested precision',
|
||||||
|
)
|
||||||
|
foreach i : range(mfem_feature_names.length())
|
||||||
|
feature_opt = get_option('mfem_' + mfem_feature_names[i])
|
||||||
|
feature_macro = mfem_cmake_names[i]
|
||||||
|
if feature_opt.disabled()
|
||||||
|
macro_absent = cpp.compiles(
|
||||||
|
'#include <mfem/config/config.hpp>\n#ifdef ' + feature_macro + '\n#error explicitly disabled\n#endif\nint main(){return 0;}',
|
||||||
|
dependencies: system_candidate,
|
||||||
|
name: 'system MFEM omits disabled ' + feature_macro,
|
||||||
|
)
|
||||||
|
system_compatible = system_compatible and macro_absent
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
if system_compatible
|
||||||
|
system_mfem = system_candidate
|
||||||
|
mfem_provider = 'system'
|
||||||
|
else
|
||||||
|
message('The system MFEM does not satisfy the selected feature set; using the pinned source bundle.')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
uses_unmodelled_system_tpl = false
|
||||||
|
foreach feature_name : mfem_feature_names
|
||||||
|
if (
|
||||||
|
mfem_features.get(feature_name) and feature_name != 'openmp' and
|
||||||
|
not source_capable.get(feature_name, false)
|
||||||
|
)
|
||||||
|
uses_unmodelled_system_tpl = true
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
if (
|
||||||
|
not system_mfem.found() and effective_allow_preinstalled and
|
||||||
|
dependency_prefix == '' and uses_unmodelled_system_tpl
|
||||||
|
)
|
||||||
|
error(
|
||||||
|
'The selected features need external TPLs, but no complete compatible system MFEM was found. ' +
|
||||||
|
'Provide one coherent -Ddependency_prefix=/path/to/tpls so the source MFEM usage interface remains reproducible.'
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if not system_mfem.found() and is_windows
|
||||||
|
error(
|
||||||
|
'The source fallback currently targets POSIX and Emscripten toolchains. ' +
|
||||||
|
'On Windows, provide a complete compatible MFEM installation and use -Dallow_preinstalled=true.'
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
|
mfem_runtime_prefix = ''
|
||||||
|
mfem_build_target = []
|
||||||
|
mpi_launcher_from_dependency = false
|
||||||
|
|
||||||
|
if system_mfem.found()
|
||||||
|
mfem_dep = system_mfem
|
||||||
|
else
|
||||||
|
mfem_source = subproject('mfem').get_variable('mfem_source_dir')
|
||||||
|
|
||||||
|
mpich_source = ''
|
||||||
|
hypre_source = ''
|
||||||
|
metis_source = ''
|
||||||
|
gslib_source = ''
|
||||||
|
zlib_source = ''
|
||||||
|
sundials_source = ''
|
||||||
|
libceed_source = ''
|
||||||
|
fms_source = ''
|
||||||
|
algoim_source = ''
|
||||||
|
blitz_source = ''
|
||||||
|
|
||||||
|
dependency_has_mpi = dependency_prefix != '' and (
|
||||||
|
fs.exists(dependency_prefix / 'bin' / 'mpicc') and
|
||||||
|
fs.exists(dependency_prefix / 'bin' / 'mpicxx')
|
||||||
|
)
|
||||||
|
dependency_has_hypre = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'HYPRE_config.h'
|
||||||
|
)
|
||||||
|
dependency_has_metis = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'metis.h'
|
||||||
|
)
|
||||||
|
dependency_has_gslib = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'gslib' / 'gslib.h'
|
||||||
|
)
|
||||||
|
dependency_has_zlib = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'zlib.h'
|
||||||
|
)
|
||||||
|
dependency_has_sundials = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'sundials' / 'sundials_config.h'
|
||||||
|
)
|
||||||
|
dependency_has_ceed = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'ceed.h'
|
||||||
|
)
|
||||||
|
dependency_has_fms = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'fms.h'
|
||||||
|
)
|
||||||
|
dependency_has_algoim = dependency_prefix != '' and fs.exists(
|
||||||
|
dependency_prefix / 'include' / 'algoim_quad.hpp'
|
||||||
|
) and fs.exists(dependency_prefix / 'include' / 'blitz' / 'array.h')
|
||||||
|
|
||||||
|
build_mpi_from_source = mfem_has_mpi and can_build_posix_mpi and not dependency_has_mpi
|
||||||
|
mpi_launcher_from_dependency = mfem_has_mpi and dependency_has_mpi
|
||||||
|
if build_mpi_from_source
|
||||||
|
mpich_source = subproject('mpich').get_variable('mpich_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_has_mpi and (build_mpi_from_source or not dependency_has_hypre)
|
||||||
|
hypre_source = subproject('hypre').get_variable('hypre_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_has_metis and not dependency_has_metis
|
||||||
|
metis_source = subproject('metis').get_variable('metis_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_has_gslib and (build_mpi_from_source or not dependency_has_gslib)
|
||||||
|
gslib_source = subproject('gslib').get_variable('gslib_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_has_zlib and not dependency_has_zlib
|
||||||
|
zlib_source = subproject('zlib').get_variable('zlib_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_has_sundials and (build_mpi_from_source or not dependency_has_sundials)
|
||||||
|
sundials_source = subproject('sundials').get_variable('sundials_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('ceed') and not dependency_has_ceed
|
||||||
|
libceed_source = subproject('libceed').get_variable('libceed_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('fms') and not dependency_has_fms
|
||||||
|
fms_source = subproject('fms').get_variable('fms_source_dir')
|
||||||
|
endif
|
||||||
|
if mfem_features.get('algoim') and not dependency_has_algoim
|
||||||
|
algoim_source = subproject('algoim').get_variable('algoim_source_dir')
|
||||||
|
blitz_source = subproject('blitz').get_variable('blitz_source_dir')
|
||||||
|
endif
|
||||||
|
|
||||||
|
bundle_is_python_package = get_option('build_python') and get_option('python_install_native')
|
||||||
|
bundle_output_name = bundle_is_python_package ? 'meson_mfem_template' : 'mfem-prefix'
|
||||||
|
mfem_runtime_prefix = meson.current_build_dir() / bundle_output_name
|
||||||
|
bundle_work_dir = meson.current_build_dir() / '_bundle' / 'work'
|
||||||
|
bundle_builder = files('../../tools/build_mfem_bundle.py')
|
||||||
|
bundle_auxiliary_files = files('../../tools/ceed_jit_source_root_relocatable.c')
|
||||||
|
cc_command = cc.cmd_array()
|
||||||
|
cxx_command = cpp.cmd_array()
|
||||||
|
known_compiler_launchers = ['ccache', 'sccache', 'distcc']
|
||||||
|
cc_executable = ''
|
||||||
|
cc_launchers = []
|
||||||
|
cc_fixed_args = []
|
||||||
|
foreach command_part : cc_command
|
||||||
|
if cc_executable == '' and fs.name(command_part) in known_compiler_launchers
|
||||||
|
cc_launchers += [command_part]
|
||||||
|
elif cc_executable == ''
|
||||||
|
cc_executable = command_part
|
||||||
|
else
|
||||||
|
cc_fixed_args += [command_part]
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
cxx_executable = ''
|
||||||
|
cxx_launchers = []
|
||||||
|
cxx_fixed_args = []
|
||||||
|
foreach command_part : cxx_command
|
||||||
|
if cxx_executable == '' and fs.name(command_part) in known_compiler_launchers
|
||||||
|
cxx_launchers += [command_part]
|
||||||
|
elif cxx_executable == ''
|
||||||
|
cxx_executable = command_part
|
||||||
|
else
|
||||||
|
cxx_fixed_args += [command_part]
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
if cc_executable == '' or cxx_executable == ''
|
||||||
|
error('Could not identify the C/C++ compiler executables in Meson compiler commands.')
|
||||||
|
endif
|
||||||
|
bundle_command = [
|
||||||
|
python_build,
|
||||||
|
bundle_builder,
|
||||||
|
'--source', mfem_source,
|
||||||
|
'--work-dir', bundle_work_dir,
|
||||||
|
'--prefix', '@OUTPUT@',
|
||||||
|
'--cmake', cmake_program,
|
||||||
|
'--cc', cc_executable,
|
||||||
|
'--cxx', cxx_executable,
|
||||||
|
'--buildtype', get_option('buildtype'),
|
||||||
|
'--jobs', get_option('jobs').to_string(),
|
||||||
|
'--host-system', host_machine.system(),
|
||||||
|
'--cross-build', meson.is_cross_build() ? 'true' : 'false',
|
||||||
|
'--library-kind', is_wasm ? 'static' : 'shared',
|
||||||
|
'--cuda-arch', get_option('mfem_cuda_arch'),
|
||||||
|
'--hip-arch', get_option('mfem_hip_arch'),
|
||||||
|
'--precision', get_option('mfem_precision'),
|
||||||
|
'--dependency-prefix', dependency_prefix,
|
||||||
|
'--allow-system', effective_allow_preinstalled ? 'true' : 'false',
|
||||||
|
'--vendor-dependency-prefix', wheel_carries_native_bundle ? 'true' : 'false',
|
||||||
|
]
|
||||||
|
foreach compiler_launcher : cc_launchers
|
||||||
|
bundle_command += ['--cc-launcher=' + compiler_launcher]
|
||||||
|
endforeach
|
||||||
|
foreach compiler_launcher : cxx_launchers
|
||||||
|
bundle_command += ['--cxx-launcher=' + compiler_launcher]
|
||||||
|
endforeach
|
||||||
|
foreach c_arg : cc_fixed_args
|
||||||
|
bundle_command += ['--c-arg=' + c_arg]
|
||||||
|
endforeach
|
||||||
|
foreach c_arg : get_option('c_args')
|
||||||
|
bundle_command += ['--c-arg=' + c_arg]
|
||||||
|
endforeach
|
||||||
|
foreach c_arg : platform_c_args
|
||||||
|
bundle_command += ['--c-arg=' + c_arg]
|
||||||
|
endforeach
|
||||||
|
foreach cpp_arg : get_option('cpp_args')
|
||||||
|
bundle_command += ['--cxx-arg=' + cpp_arg]
|
||||||
|
endforeach
|
||||||
|
foreach cpp_arg : cxx_fixed_args
|
||||||
|
bundle_command += ['--cxx-arg=' + cpp_arg]
|
||||||
|
endforeach
|
||||||
|
foreach cpp_arg : platform_cpp_args
|
||||||
|
bundle_command += ['--cxx-arg=' + cpp_arg]
|
||||||
|
endforeach
|
||||||
|
foreach c_link_arg : get_option('c_link_args')
|
||||||
|
bundle_command += ['--c-link-arg=' + c_link_arg]
|
||||||
|
endforeach
|
||||||
|
foreach cpp_link_arg : get_option('cpp_link_args')
|
||||||
|
bundle_command += ['--cxx-link-arg=' + cpp_link_arg]
|
||||||
|
endforeach
|
||||||
|
foreach platform_link_arg : platform_link_args
|
||||||
|
bundle_command += ['--c-link-arg=' + platform_link_arg]
|
||||||
|
bundle_command += ['--cxx-link-arg=' + platform_link_arg]
|
||||||
|
endforeach
|
||||||
|
foreach i : range(mfem_feature_names.length())
|
||||||
|
bundle_command += [
|
||||||
|
'--feature',
|
||||||
|
mfem_feature_names[i] + '=' + (mfem_feature_states[i] ? 'ON' : 'OFF'),
|
||||||
|
]
|
||||||
|
endforeach
|
||||||
|
foreach source_pair : [
|
||||||
|
['mpich', mpich_source],
|
||||||
|
['hypre', hypre_source],
|
||||||
|
['metis', metis_source],
|
||||||
|
['gslib', gslib_source],
|
||||||
|
['zlib', zlib_source],
|
||||||
|
['sundials', sundials_source],
|
||||||
|
['libceed', libceed_source],
|
||||||
|
['fms', fms_source],
|
||||||
|
['algoim', algoim_source],
|
||||||
|
['blitz', blitz_source],
|
||||||
|
]
|
||||||
|
if source_pair[1] != ''
|
||||||
|
bundle_command += ['--' + source_pair[0] + '-source', source_pair[1]]
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
if bundle_is_python_package and get_option('install_mfem')
|
||||||
|
mfem_build_target = custom_target(
|
||||||
|
'mfem-source-bundle',
|
||||||
|
output: bundle_output_name,
|
||||||
|
command: bundle_command,
|
||||||
|
depend_files: bundle_auxiliary_files,
|
||||||
|
build_by_default: true,
|
||||||
|
build_always_stale: dependency_prefix != '',
|
||||||
|
console: true,
|
||||||
|
install: true,
|
||||||
|
install_dir: python_build.get_install_dir(),
|
||||||
|
install_tag: 'python-native',
|
||||||
|
)
|
||||||
|
else
|
||||||
|
mfem_build_target = custom_target(
|
||||||
|
'mfem-source-bundle',
|
||||||
|
output: bundle_output_name,
|
||||||
|
command: bundle_command,
|
||||||
|
depend_files: bundle_auxiliary_files,
|
||||||
|
build_by_default: true,
|
||||||
|
build_always_stale: dependency_prefix != '',
|
||||||
|
console: true,
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
|
bundle_compile_args = ['-I' + mfem_runtime_prefix / 'include']
|
||||||
|
bundle_link_args = [
|
||||||
|
'-L' + mfem_runtime_prefix / 'lib',
|
||||||
|
'-L' + mfem_runtime_prefix / 'lib64',
|
||||||
|
]
|
||||||
|
if dependency_prefix != '' and not wheel_carries_native_bundle
|
||||||
|
bundle_compile_args += ['-I' + dependency_prefix / 'include']
|
||||||
|
bundle_link_args += [
|
||||||
|
'-L' + dependency_prefix / 'lib',
|
||||||
|
'-L' + dependency_prefix / 'lib64',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
bundle_link_args += ['-lmfem']
|
||||||
|
if mfem_has_mpi
|
||||||
|
bundle_link_args += ['-lHYPRE', '-lmpi']
|
||||||
|
endif
|
||||||
|
if mfem_has_metis
|
||||||
|
bundle_link_args += ['-lmetis']
|
||||||
|
endif
|
||||||
|
if mfem_has_gslib
|
||||||
|
bundle_link_args += ['-lgs']
|
||||||
|
endif
|
||||||
|
if mfem_has_zlib
|
||||||
|
bundle_link_args += ['-lz']
|
||||||
|
endif
|
||||||
|
if mfem_has_sundials
|
||||||
|
bundle_link_args += [
|
||||||
|
'-lsundials_nvecserial',
|
||||||
|
'-lsundials_cvodes',
|
||||||
|
'-lsundials_arkode',
|
||||||
|
'-lsundials_kinsol',
|
||||||
|
'-lsundials_core',
|
||||||
|
]
|
||||||
|
if mfem_has_mpi
|
||||||
|
bundle_link_args += [
|
||||||
|
'-lsundials_nvecparallel',
|
||||||
|
'-lsundials_nvecmpiplusx',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if mfem_features.get('ceed')
|
||||||
|
bundle_link_args += ['-lceed']
|
||||||
|
endif
|
||||||
|
if mfem_features.get('fms')
|
||||||
|
bundle_link_args += ['-lfms']
|
||||||
|
endif
|
||||||
|
if mfem_features.get('algoim')
|
||||||
|
bundle_link_args += ['-lblitz']
|
||||||
|
endif
|
||||||
|
|
||||||
|
mfem_dep_parts = []
|
||||||
|
if mfem_has_openmp or mfem_features.get('legacy_openmp')
|
||||||
|
mfem_dep_parts += [openmp_dep]
|
||||||
|
endif
|
||||||
|
mfem_dep = declare_dependency(
|
||||||
|
compile_args: bundle_compile_args,
|
||||||
|
link_args: bundle_link_args,
|
||||||
|
dependencies: mfem_dep_parts,
|
||||||
|
sources: mfem_build_target,
|
||||||
|
version: '4.10',
|
||||||
|
variables: {
|
||||||
|
'prefix': mfem_runtime_prefix,
|
||||||
|
'includedir': mfem_runtime_prefix / 'include',
|
||||||
|
'libdir': mfem_runtime_prefix / 'lib',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if get_option('install_mfem') and not bundle_is_python_package
|
||||||
|
install_bundle = files('../../tools/install_bundle.py')
|
||||||
|
meson.add_install_script(
|
||||||
|
python_build,
|
||||||
|
install_bundle,
|
||||||
|
'--source', mfem_runtime_prefix,
|
||||||
|
'--destination', get_option('prefix'),
|
||||||
|
install_tag: 'runtime',
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if get_option('build_python') and not get_option('python_install_native') and not system_mfem.found()
|
||||||
|
error('A source-built Python extension requires -Dpython_install_native=true so its runtime libraries are included in the wheel.')
|
||||||
|
endif
|
||||||
|
if get_option('build_python') and get_option('python_install_native') and not get_option('install_mfem')
|
||||||
|
error('A self-contained Python wheel requires -Dinstall_mfem=true so the native bundle is installed.')
|
||||||
|
endif
|
||||||
|
|
||||||
|
meson.override_dependency('mfem', mfem_dep)
|
||||||
41
build-python/meson.build
Normal file
41
build-python/meson.build
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
python_extension = []
|
||||||
|
python_extension_dir = ''
|
||||||
|
|
||||||
|
if get_option('build_python')
|
||||||
|
if is_wasm
|
||||||
|
error('The native CPython extension cannot be built for Emscripten. Disable build_python for the WASM profile.')
|
||||||
|
endif
|
||||||
|
nanobind_dep = dependency('nanobind', version: '>=2.15.0', fallback: 'nanobind')
|
||||||
|
extension_rpath_args = []
|
||||||
|
if host_machine.system() == 'darwin'
|
||||||
|
extension_rpath_args = [
|
||||||
|
'-Wl,-rpath,@loader_path/lib',
|
||||||
|
'-Wl,-rpath,@loader_path/lib64',
|
||||||
|
]
|
||||||
|
elif not is_windows
|
||||||
|
extension_rpath_args = [
|
||||||
|
'-Wl,-rpath,$ORIGIN/lib',
|
||||||
|
'-Wl,-rpath,$ORIGIN/lib64',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
python_extension = python_build.extension_module(
|
||||||
|
'_core',
|
||||||
|
'../src/python/bindings.cpp',
|
||||||
|
dependencies: [nanobind_dep, mfem_dep, template_include_dep],
|
||||||
|
override_options: ['cpp_std=' + mfem_consumer_cpp_std],
|
||||||
|
link_args: extension_rpath_args,
|
||||||
|
build_rpath: '',
|
||||||
|
install_rpath: '',
|
||||||
|
install: true,
|
||||||
|
install_tag: 'python-runtime',
|
||||||
|
subdir: 'meson_mfem_template',
|
||||||
|
)
|
||||||
|
python_extension_dir = meson.current_build_dir()
|
||||||
|
python_build.install_sources(
|
||||||
|
'../python/meson_mfem_template/__init__.py',
|
||||||
|
'../python/meson_mfem_template/_core.pyi',
|
||||||
|
'../python/meson_mfem_template/py.typed',
|
||||||
|
subdir: 'meson_mfem_template',
|
||||||
|
install_tag: 'python-runtime',
|
||||||
|
)
|
||||||
|
endif
|
||||||
21
cross/wasm32.ini
Normal file
21
cross/wasm32.ini
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
[binaries]
|
||||||
|
c = 'emcc'
|
||||||
|
cpp = 'em++'
|
||||||
|
ar = 'emar'
|
||||||
|
strip = 'emstrip'
|
||||||
|
exe_wrapper = 'node'
|
||||||
|
|
||||||
|
[built-in options]
|
||||||
|
c_args = ['-O1']
|
||||||
|
cpp_args = ['-O1', '-fwasm-exceptions']
|
||||||
|
c_link_args = ['-O1', '-sALLOW_MEMORY_GROWTH=1']
|
||||||
|
cpp_link_args = ['-O1', '-fwasm-exceptions', '-sALLOW_MEMORY_GROWTH=1']
|
||||||
|
|
||||||
|
[host_machine]
|
||||||
|
system = 'emscripten'
|
||||||
|
cpu_family = 'wasm32'
|
||||||
|
cpu = 'wasm32'
|
||||||
|
endian = 'little'
|
||||||
|
|
||||||
|
[properties]
|
||||||
|
needs_exe_wrapper = true
|
||||||
35
examples/meson.build
Normal file
35
examples/meson.build
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
example_deps = [mfem_dep, template_include_dep]
|
||||||
|
example_build_rpath = mfem_runtime_prefix == '' ? '' : mfem_runtime_prefix / 'lib'
|
||||||
|
example_install_rpath = ''
|
||||||
|
if mfem_runtime_prefix != '' and not is_windows and not is_wasm
|
||||||
|
example_install_rpath = host_machine.system() == 'darwin' ? '@loader_path/../lib' : '$ORIGIN/../lib'
|
||||||
|
endif
|
||||||
|
|
||||||
|
serial_example = []
|
||||||
|
parallel_example = []
|
||||||
|
|
||||||
|
if get_option('build_examples')
|
||||||
|
serial_example = executable(
|
||||||
|
'mfem-serial-poisson',
|
||||||
|
'serial_poisson.cpp',
|
||||||
|
dependencies: example_deps,
|
||||||
|
override_options: ['cpp_std=' + mfem_consumer_cpp_std],
|
||||||
|
build_rpath: example_build_rpath,
|
||||||
|
install_rpath: example_install_rpath,
|
||||||
|
install: true,
|
||||||
|
install_tag: 'examples',
|
||||||
|
)
|
||||||
|
|
||||||
|
if mfem_has_mpi
|
||||||
|
parallel_example = executable(
|
||||||
|
'mfem-parallel-hypre',
|
||||||
|
'parallel_hypre.cpp',
|
||||||
|
dependencies: example_deps,
|
||||||
|
override_options: ['cpp_std=' + mfem_consumer_cpp_std],
|
||||||
|
build_rpath: example_build_rpath,
|
||||||
|
install_rpath: example_install_rpath,
|
||||||
|
install: true,
|
||||||
|
install_tag: 'examples',
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
80
examples/parallel_hypre.cpp
Normal file
80
examples/parallel_hypre.cpp
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#include <meson_mfem_template/config.hpp>
|
||||||
|
#include <mfem.hpp>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#if !MESON_MFEM_HAS_MPI || !MESON_MFEM_HAS_HYPRE
|
||||||
|
#error "This example requires the MPI/Hypre capability"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
mfem::Mpi::Init(argc, argv);
|
||||||
|
mfem::Hypre::Init();
|
||||||
|
const int rank = mfem::Mpi::WorldRank();
|
||||||
|
const char *device_name = argc > 1 ? argv[1] : "cpu";
|
||||||
|
mfem::Device device(device_name);
|
||||||
|
|
||||||
|
mfem::Mesh serial_mesh = mfem::Mesh::MakeCartesian2D(
|
||||||
|
8, 8, mfem::Element::QUADRILATERAL, true, 1.0, 1.0);
|
||||||
|
mfem::ParMesh mesh(MPI_COMM_WORLD, serial_mesh);
|
||||||
|
serial_mesh.Clear();
|
||||||
|
|
||||||
|
mfem::H1_FECollection elements(2, mesh.Dimension());
|
||||||
|
mfem::ParFiniteElementSpace space(&mesh, &elements);
|
||||||
|
mfem::Array<int> essential_boundary(mesh.bdr_attributes.Max());
|
||||||
|
essential_boundary = 1;
|
||||||
|
mfem::Array<int> essential_dofs;
|
||||||
|
space.GetEssentialTrueDofs(essential_boundary, essential_dofs);
|
||||||
|
|
||||||
|
mfem::ConstantCoefficient one(1.0);
|
||||||
|
mfem::ParLinearForm rhs(&space);
|
||||||
|
rhs.AddDomainIntegrator(new mfem::DomainLFIntegrator(one));
|
||||||
|
rhs.Assemble();
|
||||||
|
|
||||||
|
mfem::ParGridFunction solution(&space);
|
||||||
|
solution = 0.0;
|
||||||
|
mfem::ParBilinearForm diffusion(&space);
|
||||||
|
diffusion.AddDomainIntegrator(new mfem::DiffusionIntegrator(one));
|
||||||
|
diffusion.Assemble();
|
||||||
|
|
||||||
|
mfem::OperatorPtr matrix;
|
||||||
|
mfem::Vector linear_rhs;
|
||||||
|
mfem::Vector linear_solution;
|
||||||
|
diffusion.FormLinearSystem(
|
||||||
|
essential_dofs, solution, rhs, matrix, linear_solution, linear_rhs);
|
||||||
|
|
||||||
|
mfem::HypreBoomerAMG boomer_amg;
|
||||||
|
boomer_amg.SetPrintLevel(0);
|
||||||
|
mfem::CGSolver solver(MPI_COMM_WORLD);
|
||||||
|
solver.SetPreconditioner(boomer_amg);
|
||||||
|
solver.SetOperator(*matrix);
|
||||||
|
solver.SetRelTol(1e-10);
|
||||||
|
solver.SetAbsTol(0.0);
|
||||||
|
solver.SetMaxIter(300);
|
||||||
|
solver.SetPrintLevel(0);
|
||||||
|
solver.Mult(linear_rhs, linear_solution);
|
||||||
|
diffusion.RecoverFEMSolution(linear_solution, rhs, solution);
|
||||||
|
|
||||||
|
#if MESON_MFEM_HAS_GSLIB
|
||||||
|
mfem::FindPointsGSLIB find_points(MPI_COMM_WORLD);
|
||||||
|
#endif
|
||||||
|
#if MESON_MFEM_HAS_SUNDIALS
|
||||||
|
mfem::CVODESolver cvode(MPI_COMM_WORLD, CV_BDF);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const double local_norm = solution.Norml2();
|
||||||
|
double global_norm = 0.0;
|
||||||
|
MPI_Allreduce(&local_norm, &global_norm, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
|
||||||
|
if (rank == 0)
|
||||||
|
{
|
||||||
|
std::cout << "MFEM parallel Poisson: ranks=" << mfem::Mpi::WorldSize()
|
||||||
|
<< " global_dofs=" << space.GlobalTrueVSize()
|
||||||
|
<< " norm_sum=" << global_norm
|
||||||
|
<< " device=" << device_name << '\n';
|
||||||
|
}
|
||||||
|
return solver.GetConverged() && std::isfinite(global_norm) && global_norm > 0.0
|
||||||
|
? 0
|
||||||
|
: 2;
|
||||||
|
}
|
||||||
81
examples/serial_poisson.cpp
Normal file
81
examples/serial_poisson.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include <meson_mfem_template/config.hpp>
|
||||||
|
#include <mfem.hpp>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *device_name = argc > 1 ? argv[1] :
|
||||||
|
#if MESON_MFEM_HAS_CEED && !defined(__EMSCRIPTEN__)
|
||||||
|
"ceed-cpu";
|
||||||
|
#else
|
||||||
|
"cpu";
|
||||||
|
#endif
|
||||||
|
mfem::Device device(device_name);
|
||||||
|
|
||||||
|
mfem::Mesh mesh = mfem::Mesh::MakeCartesian2D(
|
||||||
|
6, 6, mfem::Element::QUADRILATERAL, true, 1.0, 1.0);
|
||||||
|
const int dimension = mesh.Dimension();
|
||||||
|
mfem::H1_FECollection elements(2, dimension);
|
||||||
|
mfem::FiniteElementSpace space(&mesh, &elements);
|
||||||
|
|
||||||
|
mfem::Array<int> essential_boundary(mesh.bdr_attributes.Max());
|
||||||
|
essential_boundary = 1;
|
||||||
|
mfem::Array<int> essential_dofs;
|
||||||
|
space.GetEssentialTrueDofs(essential_boundary, essential_dofs);
|
||||||
|
|
||||||
|
mfem::ConstantCoefficient one(1.0);
|
||||||
|
mfem::LinearForm rhs(&space);
|
||||||
|
rhs.AddDomainIntegrator(new mfem::DomainLFIntegrator(one));
|
||||||
|
rhs.Assemble();
|
||||||
|
|
||||||
|
mfem::GridFunction solution(&space);
|
||||||
|
solution = 0.0;
|
||||||
|
|
||||||
|
mfem::BilinearForm diffusion(&space);
|
||||||
|
diffusion.AddDomainIntegrator(new mfem::DiffusionIntegrator(one));
|
||||||
|
if (mfem::Device::Allows(mfem::Backend::CEED_MASK))
|
||||||
|
{
|
||||||
|
diffusion.SetAssemblyLevel(mfem::AssemblyLevel::PARTIAL);
|
||||||
|
}
|
||||||
|
diffusion.Assemble();
|
||||||
|
|
||||||
|
mfem::OperatorPtr matrix;
|
||||||
|
mfem::Vector linear_rhs;
|
||||||
|
mfem::Vector linear_solution;
|
||||||
|
diffusion.FormLinearSystem(
|
||||||
|
essential_dofs, solution, rhs, matrix, linear_solution, linear_rhs);
|
||||||
|
|
||||||
|
mfem::CGSolver solver;
|
||||||
|
solver.SetOperator(*matrix);
|
||||||
|
solver.SetRelTol(1e-12);
|
||||||
|
solver.SetAbsTol(0.0);
|
||||||
|
solver.SetMaxIter(200);
|
||||||
|
solver.SetPrintLevel(0);
|
||||||
|
solver.Mult(linear_rhs, linear_solution);
|
||||||
|
diffusion.RecoverFEMSolution(linear_solution, rhs, solution);
|
||||||
|
|
||||||
|
#if MESON_MFEM_HAS_FMS
|
||||||
|
mfem::FMSDataCollection fms_collection("meson-mfem-smoke", &mesh);
|
||||||
|
fms_collection.SetProtocol("ascii");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MESON_MFEM_HAS_ALGOIM
|
||||||
|
mfem::FunctionCoefficient level_set(
|
||||||
|
[](const mfem::Vector &point) { return point[0] + point[1] - 0.2; });
|
||||||
|
mfem::AlgoimIntegrationRules algoim_rules(2, level_set, 2);
|
||||||
|
mfem::IntegrationRule cut_rule;
|
||||||
|
algoim_rules.GetVolumeIntegrationRule(
|
||||||
|
*mesh.GetElementTransformation(0), cut_rule);
|
||||||
|
if (cut_rule.GetNPoints() == 0)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const double norm = solution.Norml2();
|
||||||
|
std::cout << "MFEM serial Poisson: dofs=" << space.GetTrueVSize()
|
||||||
|
<< " l2=" << norm << " device=" << device_name << '\n';
|
||||||
|
return solver.GetConverged() && std::isfinite(norm) && norm > 0.0 ? 0 : 2;
|
||||||
|
}
|
||||||
261
include/meson_mfem_template/config.hpp.in
Normal file
261
include/meson_mfem_template/config.hpp.in
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MESON_MFEM_TEMPLATE_VERSION @MESON_MFEM_TEMPLATE_VERSION@
|
||||||
|
#mesondefine01 MESON_MFEM_USING_BUNDLED_MFEM
|
||||||
|
|
||||||
|
#include <mfem/config/config.hpp>
|
||||||
|
|
||||||
|
#ifdef MFEM_USE_MPI
|
||||||
|
#define MESON_MFEM_HAS_MPI 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MPI 0
|
||||||
|
#endif
|
||||||
|
#define MESON_MFEM_HAS_HYPRE MESON_MFEM_HAS_MPI
|
||||||
|
|
||||||
|
#ifdef MFEM_USE_METIS
|
||||||
|
#define MESON_MFEM_HAS_METIS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_METIS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_EXCEPTIONS
|
||||||
|
#define MESON_MFEM_HAS_EXCEPTIONS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_EXCEPTIONS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_ZLIB
|
||||||
|
#define MESON_MFEM_HAS_ZLIB 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_ZLIB 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_LIBUNWIND
|
||||||
|
#define MESON_MFEM_HAS_LIBUNWIND 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_LIBUNWIND 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_LAPACK
|
||||||
|
#define MESON_MFEM_HAS_LAPACK 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_LAPACK 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_THREAD_SAFE
|
||||||
|
#define MESON_MFEM_HAS_THREAD_SAFE 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_THREAD_SAFE 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_OPENMP
|
||||||
|
#define MESON_MFEM_HAS_OPENMP 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_OPENMP 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_LEGACY_OPENMP
|
||||||
|
#define MESON_MFEM_HAS_LEGACY_OPENMP 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_LEGACY_OPENMP 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MEMALLOC
|
||||||
|
#define MESON_MFEM_HAS_MEMALLOC 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MEMALLOC 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SUNDIALS
|
||||||
|
#define MESON_MFEM_HAS_SUNDIALS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SUNDIALS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SUITESPARSE
|
||||||
|
#define MESON_MFEM_HAS_SUITESPARSE 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SUITESPARSE 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SUPERLU
|
||||||
|
#define MESON_MFEM_HAS_SUPERLU 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SUPERLU 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SUPERLU5
|
||||||
|
#define MESON_MFEM_HAS_SUPERLU5 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SUPERLU5 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MUMPS
|
||||||
|
#define MESON_MFEM_HAS_MUMPS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MUMPS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_STRUMPACK
|
||||||
|
#define MESON_MFEM_HAS_STRUMPACK 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_STRUMPACK 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_CUDSS
|
||||||
|
#define MESON_MFEM_HAS_CUDSS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_CUDSS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_GINKGO
|
||||||
|
#define MESON_MFEM_HAS_GINKGO 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_GINKGO 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_AMGX
|
||||||
|
#define MESON_MFEM_HAS_AMGX 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_AMGX 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MAGMA
|
||||||
|
#define MESON_MFEM_HAS_MAGMA 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MAGMA 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_GNUTLS
|
||||||
|
#define MESON_MFEM_HAS_GNUTLS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_GNUTLS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_GSLIB
|
||||||
|
#define MESON_MFEM_HAS_GSLIB 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_GSLIB 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_HDF5
|
||||||
|
#define MESON_MFEM_HAS_HDF5 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_HDF5 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_NETCDF
|
||||||
|
#define MESON_MFEM_HAS_NETCDF 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_NETCDF 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_PETSC
|
||||||
|
#define MESON_MFEM_HAS_PETSC 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_PETSC 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SLEPC
|
||||||
|
#define MESON_MFEM_HAS_SLEPC 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SLEPC 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MPFR
|
||||||
|
#define MESON_MFEM_HAS_MPFR 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MPFR 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SIDRE
|
||||||
|
#define MESON_MFEM_HAS_SIDRE 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SIDRE 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_FMS
|
||||||
|
#define MESON_MFEM_HAS_FMS 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_FMS 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_CONDUIT
|
||||||
|
#define MESON_MFEM_HAS_CONDUIT 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_CONDUIT 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_PUMI
|
||||||
|
#define MESON_MFEM_HAS_PUMI 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_PUMI 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_HIOP
|
||||||
|
#define MESON_MFEM_HAS_HIOP 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_HIOP 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_CUDA
|
||||||
|
#define MESON_MFEM_HAS_CUDA 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_CUDA 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_HIP
|
||||||
|
#define MESON_MFEM_HAS_HIP 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_HIP 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_OCCA
|
||||||
|
#define MESON_MFEM_HAS_OCCA 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_OCCA 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_RAJA
|
||||||
|
#define MESON_MFEM_HAS_RAJA 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_RAJA 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_CEED
|
||||||
|
#define MESON_MFEM_HAS_CEED 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_CEED 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_UMPIRE
|
||||||
|
#define MESON_MFEM_HAS_UMPIRE 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_UMPIRE 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SIMD
|
||||||
|
#define MESON_MFEM_HAS_SIMD 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SIMD 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_ADIOS2
|
||||||
|
#define MESON_MFEM_HAS_ADIOS2 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_ADIOS2 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_CALIPER
|
||||||
|
#define MESON_MFEM_HAS_CALIPER 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_CALIPER 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_ALGOIM
|
||||||
|
#define MESON_MFEM_HAS_ALGOIM 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_ALGOIM 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MKL_CPARDISO
|
||||||
|
#define MESON_MFEM_HAS_MKL_CPARDISO 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MKL_CPARDISO 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MKL_PARDISO
|
||||||
|
#define MESON_MFEM_HAS_MKL_PARDISO 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MKL_PARDISO 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_ADFORWARD
|
||||||
|
#define MESON_MFEM_HAS_ADFORWARD 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_ADFORWARD 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_CODIPACK
|
||||||
|
#define MESON_MFEM_HAS_CODIPACK 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_CODIPACK 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_BENCHMARK
|
||||||
|
#define MESON_MFEM_HAS_BENCHMARK 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_BENCHMARK 0
|
||||||
|
#endif
|
||||||
|
#define MESON_MFEM_HAS_PARELAG 0
|
||||||
|
#define MESON_MFEM_HAS_TRIBOL 0
|
||||||
|
#ifdef MFEM_USE_ENZYME
|
||||||
|
#define MESON_MFEM_HAS_ENZYME 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_ENZYME 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_MOONOLITH
|
||||||
|
#define MESON_MFEM_HAS_MOONOLITH 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_MOONOLITH 0
|
||||||
|
#endif
|
||||||
|
#ifdef MFEM_USE_SIMMETRIX
|
||||||
|
#define MESON_MFEM_HAS_SIMMETRIX 1
|
||||||
|
#else
|
||||||
|
#define MESON_MFEM_HAS_SIMMETRIX 0
|
||||||
|
#endif
|
||||||
19
include/meson_mfem_template/meson.build
Normal file
19
include/meson_mfem_template/meson.build
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
mfem_config = configuration_data()
|
||||||
|
mfem_config.set_quoted('MESON_MFEM_TEMPLATE_VERSION', meson.project_version())
|
||||||
|
mfem_config.set10('MESON_MFEM_USING_BUNDLED_MFEM', mfem_provider != 'system')
|
||||||
|
|
||||||
|
mfem_config_header = configure_file(
|
||||||
|
input: 'config.hpp.in',
|
||||||
|
output: 'config.hpp',
|
||||||
|
configuration: mfem_config,
|
||||||
|
install: true,
|
||||||
|
install_tag: get_option('build_python') ? 'python-runtime' : 'devel',
|
||||||
|
install_dir: get_option('build_python')
|
||||||
|
? python_build.get_install_dir() / 'meson_mfem_template' / 'include' / 'meson_mfem_template'
|
||||||
|
: get_option('includedir') / 'meson_mfem_template',
|
||||||
|
)
|
||||||
|
|
||||||
|
template_include_dep = declare_dependency(
|
||||||
|
include_directories: include_directories('..'),
|
||||||
|
sources: mfem_config_header,
|
||||||
|
)
|
||||||
58
meson.build
Normal file
58
meson.build
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
project(
|
||||||
|
'meson-mfem-template',
|
||||||
|
['c', 'cpp'],
|
||||||
|
version: '0.1.0',
|
||||||
|
meson_version: '>=1.9.1',
|
||||||
|
default_options: [
|
||||||
|
'c_std=c11',
|
||||||
|
'cpp_std=c++23',
|
||||||
|
'warning_level=2',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
python_mod = import('python')
|
||||||
|
fs = import('fs')
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
cpp = meson.get_compiler('cpp')
|
||||||
|
platform_c_args = []
|
||||||
|
platform_cpp_args = []
|
||||||
|
platform_link_args = []
|
||||||
|
if host_machine.system() == 'darwin' and get_option('macos_deployment_target') != ''
|
||||||
|
macos_minimum_flag = '-mmacosx-version-min=' + get_option('macos_deployment_target')
|
||||||
|
platform_c_args += [macos_minimum_flag]
|
||||||
|
platform_cpp_args += [macos_minimum_flag]
|
||||||
|
platform_link_args += [macos_minimum_flag]
|
||||||
|
add_project_arguments(macos_minimum_flag, language: ['c', 'cpp'])
|
||||||
|
add_project_link_arguments(macos_minimum_flag, language: ['c', 'cpp'])
|
||||||
|
endif
|
||||||
|
|
||||||
|
subdir('build-check')
|
||||||
|
subdir('build-config')
|
||||||
|
subdir('include/meson_mfem_template')
|
||||||
|
subdir('examples')
|
||||||
|
subdir('build-python')
|
||||||
|
subdir('tests')
|
||||||
|
|
||||||
|
summary(
|
||||||
|
{
|
||||||
|
'MFEM provider': mfem_provider,
|
||||||
|
'dependency profile': get_option('feature_profile'),
|
||||||
|
'allow preinstalled': get_option('allow_preinstalled'),
|
||||||
|
'parallel MPI/Hypre': mfem_has_mpi,
|
||||||
|
'METIS': mfem_has_metis,
|
||||||
|
'CUDA': mfem_has_cuda,
|
||||||
|
'HIP': mfem_has_hip,
|
||||||
|
'OpenMP': mfem_has_openmp,
|
||||||
|
'GSLIB': mfem_has_gslib,
|
||||||
|
'zlib': mfem_has_zlib,
|
||||||
|
'SUNDIALS': mfem_has_sundials,
|
||||||
|
'libCEED': mfem_features.get('ceed'),
|
||||||
|
'FMS': mfem_features.get('fms'),
|
||||||
|
'Algoim': mfem_features.get('algoim'),
|
||||||
|
'Python bindings': get_option('build_python'),
|
||||||
|
'examples': get_option('build_examples'),
|
||||||
|
'tests': get_option('build_tests'),
|
||||||
|
},
|
||||||
|
section: 'meson-mfem-template ' + meson.project_version(),
|
||||||
|
bool_yn: true,
|
||||||
|
)
|
||||||
66
meson_options.txt
Normal file
66
meson_options.txt
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
option('allow_preinstalled', type: 'boolean', value: true, description: 'Allow one complete, feature-compatible system MFEM. Set false for the dependency-hermetic source fallback.')
|
||||||
|
option('feature_profile', type: 'combo', choices: ['minimal', 'portable', 'full'], value: 'portable', description: 'Defaults for auto features. full is strict and requires all selected non-bundled TPLs in dependency_prefix.')
|
||||||
|
option('build_python', type: 'boolean', value: false, description: 'Build the nanobind Python extension and install native assets inside the Python package.')
|
||||||
|
option('build_examples', type: 'boolean', value: true, description: 'Build MFEM capability examples.')
|
||||||
|
option('build_tests', type: 'boolean', value: true, description: 'Register serial, parallel, and Python smoke tests when applicable.')
|
||||||
|
option('install_mfem', type: 'boolean', value: true, description: 'Install the source-built MFEM bundle and its runtime dependencies.')
|
||||||
|
option('dependency_prefix', type: 'string', value: '', description: 'Explicit prefix containing optional TPLs. Used even when allow_preinstalled=false.')
|
||||||
|
option('jobs', type: 'integer', min: 1, max: 1024, value: 4, description: 'Parallel jobs for the CMake/Make source bundle.')
|
||||||
|
option('mfem_cuda_arch', type: 'string', value: 'native', description: 'CUDA architectures understood by CMake, for example 80;86. native requires a recent CMake/toolkit.')
|
||||||
|
option('mfem_hip_arch', type: 'string', value: '', description: 'HIP GPU target, for example gfx90a. Empty lets the toolchain choose.')
|
||||||
|
option('mfem_precision', type: 'combo', choices: ['double', 'single'], value: 'double', description: 'Floating-point precision used consistently by MFEM and Hypre.')
|
||||||
|
option('python_install_native', type: 'boolean', value: true, description: 'Install MFEM headers, CMake/pkg-config data, and runtime libraries under the Python package.')
|
||||||
|
option('macos_deployment_target', type: 'string', value: '11.0', description: 'Minimum macOS version for native artifacts; ignored on other systems. Empty uses the toolchain default.')
|
||||||
|
|
||||||
|
option('mfem_mpi', type: 'feature', value: 'auto', description: 'MPI parallel MFEM; implies Hypre.')
|
||||||
|
option('mfem_metis', type: 'feature', value: 'auto', description: 'METIS graph partitioning.')
|
||||||
|
option('mfem_exceptions', type: 'feature', value: 'auto', description: 'MFEM C++ exceptions.')
|
||||||
|
option('mfem_zlib', type: 'feature', value: 'auto', description: 'zlib compressed streams.')
|
||||||
|
option('mfem_libunwind', type: 'feature', value: 'auto', description: 'libunwind backtraces.')
|
||||||
|
option('mfem_lapack', type: 'feature', value: 'auto', description: 'BLAS/LAPACK solvers.')
|
||||||
|
option('mfem_thread_safe', type: 'feature', value: 'auto', description: 'MFEM thread-safe mode.')
|
||||||
|
option('mfem_openmp', type: 'feature', value: 'auto', description: 'OpenMP backend.')
|
||||||
|
option('mfem_legacy_openmp', type: 'feature', value: 'disabled', description: 'Legacy OpenMP backend (mutually exclusive with modern device backends).')
|
||||||
|
option('mfem_memalloc', type: 'feature', value: 'enabled', description: 'MFEM internal memory allocator.')
|
||||||
|
option('mfem_sundials', type: 'feature', value: 'auto', description: 'SUNDIALS ODE/nonlinear solvers.')
|
||||||
|
option('mfem_suitesparse', type: 'feature', value: 'auto', description: 'SuiteSparse direct solvers.')
|
||||||
|
option('mfem_superlu', type: 'feature', value: 'auto', description: 'SuperLU_DIST.')
|
||||||
|
option('mfem_superlu5', type: 'feature', value: 'disabled', description: 'Compatibility with old SuperLU_DIST 5.1.')
|
||||||
|
option('mfem_mumps', type: 'feature', value: 'auto', description: 'MUMPS parallel direct solver.')
|
||||||
|
option('mfem_strumpack', type: 'feature', value: 'auto', description: 'STRUMPACK parallel solver.')
|
||||||
|
option('mfem_cudss', type: 'feature', value: 'auto', description: 'NVIDIA cuDSS (CUDA only, vendor binary dependency).')
|
||||||
|
option('mfem_ginkgo', type: 'feature', value: 'auto', description: 'Ginkgo solvers.')
|
||||||
|
option('mfem_amgx', type: 'feature', value: 'auto', description: 'NVIDIA AmgX.')
|
||||||
|
option('mfem_magma', type: 'feature', value: 'auto', description: 'MAGMA dense linear algebra.')
|
||||||
|
option('mfem_gnutls', type: 'feature', value: 'auto', description: 'GnuTLS socket security.')
|
||||||
|
option('mfem_gslib', type: 'feature', value: 'auto', description: 'GSLIB FindPoints support.')
|
||||||
|
option('mfem_hdf5', type: 'feature', value: 'auto', description: 'HDF5 data support.')
|
||||||
|
option('mfem_netcdf', type: 'feature', value: 'auto', description: 'NetCDF data support.')
|
||||||
|
option('mfem_petsc', type: 'feature', value: 'auto', description: 'PETSc solvers.')
|
||||||
|
option('mfem_slepc', type: 'feature', value: 'auto', description: 'SLEPc eigensolvers; implies PETSc.')
|
||||||
|
option('mfem_mpfr', type: 'feature', value: 'auto', description: 'MPFR arbitrary precision support.')
|
||||||
|
option('mfem_sidre', type: 'feature', value: 'auto', description: 'Axom/Sidre support.')
|
||||||
|
option('mfem_fms', type: 'feature', value: 'auto', description: 'FMS data model.')
|
||||||
|
option('mfem_conduit', type: 'feature', value: 'auto', description: 'Conduit data support.')
|
||||||
|
option('mfem_pumi', type: 'feature', value: 'auto', description: 'PUMI meshes.')
|
||||||
|
option('mfem_hiop', type: 'feature', value: 'auto', description: 'HiOp optimization.')
|
||||||
|
option('mfem_cuda', type: 'feature', value: 'auto', description: 'NVIDIA CUDA backend; requires a host CUDA toolkit.')
|
||||||
|
option('mfem_hip', type: 'feature', value: 'auto', description: 'AMD HIP backend; requires a host ROCm toolkit.')
|
||||||
|
option('mfem_occa', type: 'feature', value: 'auto', description: 'OCCA device backend.')
|
||||||
|
option('mfem_raja', type: 'feature', value: 'auto', description: 'RAJA device backend; raises MFEM to C++20.')
|
||||||
|
option('mfem_ceed', type: 'feature', value: 'auto', description: 'libCEED operator backend.')
|
||||||
|
option('mfem_umpire', type: 'feature', value: 'auto', description: 'Umpire memory manager; raises MFEM to C++20.')
|
||||||
|
option('mfem_simd', type: 'feature', value: 'auto', description: 'SIMD intrinsics.')
|
||||||
|
option('mfem_adios2', type: 'feature', value: 'auto', description: 'ADIOS2 I/O.')
|
||||||
|
option('mfem_caliper', type: 'feature', value: 'auto', description: 'Caliper profiling.')
|
||||||
|
option('mfem_algoim', type: 'feature', value: 'auto', description: 'Algoim implicit geometry support.')
|
||||||
|
option('mfem_mkl_cpardiso', type: 'feature', value: 'auto', description: 'Intel MKL Cluster PARDISO.')
|
||||||
|
option('mfem_mkl_pardiso', type: 'feature', value: 'auto', description: 'Intel MKL PARDISO.')
|
||||||
|
option('mfem_adforward', type: 'feature', value: 'auto', description: 'Forward mode for supported automatic differentiation packages.')
|
||||||
|
option('mfem_codipack', type: 'feature', value: 'auto', description: 'CoDiPack automatic differentiation.')
|
||||||
|
option('mfem_benchmark', type: 'feature', value: 'disabled', description: 'Upstream benchmark-program build switch; enabling is rejected because it is not an installed MFEM library capability.')
|
||||||
|
option('mfem_parelag', type: 'feature', value: 'disabled', description: 'Upstream ParELAG miniapp-only switch; enabling is rejected because it is not an installed MFEM library capability.')
|
||||||
|
option('mfem_tribol', type: 'feature', value: 'disabled', description: 'Upstream Tribol miniapp-only switch; enabling is rejected because it is not an installed MFEM library capability.')
|
||||||
|
option('mfem_enzyme', type: 'feature', value: 'auto', description: 'Enzyme AD plugin; requires matching Clang/LLVM.')
|
||||||
|
option('mfem_moonolith', type: 'feature', value: 'auto', description: 'Moonolith transfer miniapp integration.')
|
||||||
|
option('mfem_simmetrix', type: 'feature', value: 'auto', description: 'Simmetrix commercial mesh integration.')
|
||||||
41
pyproject.toml
Normal file
41
pyproject.toml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
[build-system]
|
||||||
|
build-backend = "mesonpy"
|
||||||
|
requires = [
|
||||||
|
"meson-python>=0.20",
|
||||||
|
"meson>=1.9.1",
|
||||||
|
"ninja>=1.11",
|
||||||
|
"cmake>=3.24",
|
||||||
|
"patchelf>=0.17; sys_platform == 'linux'",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "meson-mfem-template"
|
||||||
|
dynamic = ["version"]
|
||||||
|
description = "Portable Meson source bundle and nanobind validation module for MFEM"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
license = "MIT"
|
||||||
|
license-files = ["LICENSE"]
|
||||||
|
|
||||||
|
[tool.meson-python]
|
||||||
|
allow-windows-internal-shared-libs = true
|
||||||
|
|
||||||
|
[tool.meson-python.args]
|
||||||
|
setup = [
|
||||||
|
"-Dbuildtype=release",
|
||||||
|
"-Dallow_preinstalled=false",
|
||||||
|
"-Dfeature_profile=portable",
|
||||||
|
"-Dbuild_python=true",
|
||||||
|
"-Dbuild_examples=false",
|
||||||
|
"-Dbuild_tests=false",
|
||||||
|
"-Dinstall_mfem=true",
|
||||||
|
"-Dpython_install_native=true",
|
||||||
|
"-Dmfem_openmp=disabled",
|
||||||
|
"-Dmfem_cuda=disabled",
|
||||||
|
"-Dmfem_hip=disabled",
|
||||||
|
"--force-fallback-for=nanobind,robin-map",
|
||||||
|
]
|
||||||
|
install = [
|
||||||
|
"--tags=python-runtime,python-native",
|
||||||
|
"--skip-subprojects",
|
||||||
|
]
|
||||||
46
python/meson_mfem_template/__init__.py
Normal file
46
python/meson_mfem_template/__init__.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def _native_search_paths() -> list[Path]:
|
||||||
|
package = Path(__file__).resolve().parent
|
||||||
|
return [package / "lib", package / "lib64", package / "bin"]
|
||||||
|
|
||||||
|
|
||||||
|
_dll_directory_handles = []
|
||||||
|
if os.name == "nt" and hasattr(os, "add_dll_directory"):
|
||||||
|
for _directory in _native_search_paths():
|
||||||
|
if _directory.is_dir():
|
||||||
|
_dll_directory_handles.append(os.add_dll_directory(str(_directory)))
|
||||||
|
|
||||||
|
from ._core import capabilities, mfem_version, serial_poisson_dofs
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"capabilities",
|
||||||
|
"get_cmake_prefix",
|
||||||
|
"get_include",
|
||||||
|
"get_lib",
|
||||||
|
"mfem_version",
|
||||||
|
"serial_poisson_dofs",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _package_dir() -> Path:
|
||||||
|
return Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
|
||||||
|
def get_include() -> str:
|
||||||
|
"""Return the wheel-local include directory containing MFEM headers."""
|
||||||
|
return str(_package_dir() / "include")
|
||||||
|
|
||||||
|
|
||||||
|
def get_lib() -> str:
|
||||||
|
"""Return the wheel-local directory containing MFEM runtime libraries."""
|
||||||
|
return str(_package_dir() / "lib")
|
||||||
|
|
||||||
|
|
||||||
|
def get_cmake_prefix() -> str:
|
||||||
|
"""Return the prefix that can be appended to CMAKE_PREFIX_PATH."""
|
||||||
|
return str(_package_dir())
|
||||||
4
python/meson_mfem_template/_core.pyi
Normal file
4
python/meson_mfem_template/_core.pyi
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
def mfem_version() -> str: ...
|
||||||
|
def capabilities() -> dict[str, bool]: ...
|
||||||
|
def serial_poisson_dofs(cells: int = 4, order: int = 2) -> int: ...
|
||||||
|
|
||||||
1
python/meson_mfem_template/py.typed
Normal file
1
python/meson_mfem_template/py.typed
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
91
src/python/bindings.cpp
Normal file
91
src/python/bindings.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include <meson_mfem_template/config.hpp>
|
||||||
|
#include <mfem.hpp>
|
||||||
|
#include <nanobind/nanobind.h>
|
||||||
|
#include <nanobind/stl/string.h>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace nb = nanobind;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
int serial_poisson_dofs(int cells, int order)
|
||||||
|
{
|
||||||
|
if (cells < 2 || order < 1)
|
||||||
|
{
|
||||||
|
throw nb::value_error("cells must be >= 2 and order must be >= 1");
|
||||||
|
}
|
||||||
|
mfem::Mesh mesh = mfem::Mesh::MakeCartesian2D(
|
||||||
|
cells, cells, mfem::Element::QUADRILATERAL, true, 1.0, 1.0);
|
||||||
|
mfem::H1_FECollection elements(order, mesh.Dimension());
|
||||||
|
mfem::FiniteElementSpace space(&mesh, &elements);
|
||||||
|
mfem::Array<int> essential_boundary(mesh.bdr_attributes.Max());
|
||||||
|
essential_boundary = 1;
|
||||||
|
mfem::Array<int> essential_dofs;
|
||||||
|
space.GetEssentialTrueDofs(essential_boundary, essential_dofs);
|
||||||
|
|
||||||
|
mfem::ConstantCoefficient one(1.0);
|
||||||
|
mfem::LinearForm rhs(&space);
|
||||||
|
rhs.AddDomainIntegrator(new mfem::DomainLFIntegrator(one));
|
||||||
|
rhs.Assemble();
|
||||||
|
mfem::GridFunction solution(&space);
|
||||||
|
solution = 0.0;
|
||||||
|
mfem::BilinearForm diffusion(&space);
|
||||||
|
diffusion.AddDomainIntegrator(new mfem::DiffusionIntegrator(one));
|
||||||
|
diffusion.Assemble();
|
||||||
|
|
||||||
|
mfem::OperatorPtr matrix;
|
||||||
|
mfem::Vector linear_rhs;
|
||||||
|
mfem::Vector linear_solution;
|
||||||
|
diffusion.FormLinearSystem(
|
||||||
|
essential_dofs, solution, rhs, matrix, linear_solution, linear_rhs);
|
||||||
|
mfem::GSSmoother smoother(static_cast<mfem::SparseMatrix &>(*matrix));
|
||||||
|
mfem::CGSolver solver;
|
||||||
|
solver.SetOperator(*matrix);
|
||||||
|
solver.SetPreconditioner(smoother);
|
||||||
|
solver.SetRelTol(1e-10);
|
||||||
|
solver.SetMaxIter(200);
|
||||||
|
solver.SetPrintLevel(0);
|
||||||
|
solver.Mult(linear_rhs, linear_solution);
|
||||||
|
if (!solver.GetConverged())
|
||||||
|
{
|
||||||
|
throw std::runtime_error("MFEM CG solve did not converge");
|
||||||
|
}
|
||||||
|
return space.GetTrueVSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
nb::dict capabilities()
|
||||||
|
{
|
||||||
|
nb::dict result;
|
||||||
|
result["mpi"] = MESON_MFEM_HAS_MPI != 0;
|
||||||
|
result["hypre"] = MESON_MFEM_HAS_HYPRE != 0;
|
||||||
|
result["metis"] = MESON_MFEM_HAS_METIS != 0;
|
||||||
|
result["cuda"] = MESON_MFEM_HAS_CUDA != 0;
|
||||||
|
result["hip"] = MESON_MFEM_HAS_HIP != 0;
|
||||||
|
result["openmp"] = MESON_MFEM_HAS_OPENMP != 0;
|
||||||
|
result["gslib"] = MESON_MFEM_HAS_GSLIB != 0;
|
||||||
|
result["zlib"] = MESON_MFEM_HAS_ZLIB != 0;
|
||||||
|
result["sundials"] = MESON_MFEM_HAS_SUNDIALS != 0;
|
||||||
|
result["ceed"] = MESON_MFEM_HAS_CEED != 0;
|
||||||
|
result["fms"] = MESON_MFEM_HAS_FMS != 0;
|
||||||
|
result["algoim"] = MESON_MFEM_HAS_ALGOIM != 0;
|
||||||
|
result["simd"] = MESON_MFEM_HAS_SIMD != 0;
|
||||||
|
result["bundled_mfem"] = MESON_MFEM_USING_BUNDLED_MFEM != 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
NB_MODULE(_core, module)
|
||||||
|
{
|
||||||
|
module.doc() = "Small nanobind validation module for the Meson MFEM bundle";
|
||||||
|
module.def("mfem_version", []() { return std::string(MFEM_VERSION_STRING); });
|
||||||
|
module.def("capabilities", &capabilities);
|
||||||
|
module.def(
|
||||||
|
"serial_poisson_dofs",
|
||||||
|
&serial_poisson_dofs,
|
||||||
|
nb::arg("cells") = 4,
|
||||||
|
nb::arg("order") = 2,
|
||||||
|
"Assemble and solve a small MFEM Poisson problem; return true DOFs.");
|
||||||
|
}
|
||||||
0
subprojects/.wraplock
Normal file
0
subprojects/.wraplock
Normal file
10
subprojects/algoim.wrap
Normal file
10
subprojects/algoim.wrap
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = algoim-9c9ca0ef094d8ab0390ed36367a1151b459bbe0a
|
||||||
|
source_url = https://github.com/algoim/algoim/archive/9c9ca0ef094d8ab0390ed36367a1151b459bbe0a.tar.gz
|
||||||
|
source_filename = algoim-9c9ca0ef094d8ab0390ed36367a1151b459bbe0a.tar.gz
|
||||||
|
source_hash = 8b0cbeb3821665c57bbd88426cee7ffca21c95cb2e37edf2f670139b1e50c2cf
|
||||||
|
patch_directory = algoim
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
algoim = algoim_dep
|
||||||
|
|
||||||
10
subprojects/blitz.wrap
Normal file
10
subprojects/blitz.wrap
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = blitz-1.0.2
|
||||||
|
source_url = https://github.com/blitzpp/blitz/archive/refs/tags/1.0.2.tar.gz
|
||||||
|
source_filename = blitz-1.0.2.tar.gz
|
||||||
|
source_hash = 500db9c3b2617e1f03d0e548977aec10d36811ba1c43bb5ef250c0e3853ae1c2
|
||||||
|
patch_directory = blitz
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
blitz = blitz_dep
|
||||||
|
|
||||||
10
subprojects/fms.wrap
Normal file
10
subprojects/fms.wrap
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = FMS-0.2
|
||||||
|
source_url = https://github.com/CEED/FMS/archive/refs/tags/v0.2.tar.gz
|
||||||
|
source_filename = fms-0.2.tar.gz
|
||||||
|
source_hash = 872489a1325b247968dbb7265b8736660af94121a86c93f7938441ce7478183e
|
||||||
|
patch_directory = fms
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
fms = fms_dep
|
||||||
|
|
||||||
7
subprojects/gslib.wrap
Normal file
7
subprojects/gslib.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = gslib-1.0.9
|
||||||
|
source_url = https://github.com/Nek5000/gslib/archive/refs/tags/v1.0.9.tar.gz
|
||||||
|
source_filename = gslib-1.0.9.tar.gz
|
||||||
|
source_hash = 572c78b1ca4ddda75ec85c6299ee0597459f4dbf5170b9faa6de4c435dcdc80b
|
||||||
|
patch_directory = gslib
|
||||||
|
|
||||||
7
subprojects/hypre.wrap
Normal file
7
subprojects/hypre.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = hypre-2.33.0
|
||||||
|
source_url = https://github.com/hypre-space/hypre/archive/refs/tags/v2.33.0.tar.gz
|
||||||
|
source_filename = hypre-2.33.0.tar.gz
|
||||||
|
source_hash = 0f9103c34bce7a5dcbdb79a502720fc8aab4db9fd0146e0791cde7ec878f27da
|
||||||
|
patch_directory = hypre
|
||||||
|
|
||||||
10
subprojects/libceed.wrap
Normal file
10
subprojects/libceed.wrap
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = libCEED-0.12.0
|
||||||
|
source_url = https://github.com/CEED/libCEED/archive/refs/tags/v0.12.0.tar.gz
|
||||||
|
source_filename = libceed-0.12.0.tar.gz
|
||||||
|
source_hash = 2d94c218f6ab1bed072d11b70b0a0e70a5720fdf3d61db924e89909424a2f93e
|
||||||
|
patch_directory = libceed
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
libceed = libceed_dep
|
||||||
|
|
||||||
7
subprojects/metis.wrap
Normal file
7
subprojects/metis.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = tpls-b60352fbe9675d374b00828055e55be4584c7995
|
||||||
|
source_url = https://github.com/mfem/tpls/archive/b60352fbe9675d374b00828055e55be4584c7995.tar.gz
|
||||||
|
source_filename = mfem-tpls-b60352f.tar.gz
|
||||||
|
source_hash = 026192230134b8e8028ef4969553f180c7f64fca8a156993d2db38868536f71f
|
||||||
|
patch_directory = metis
|
||||||
|
|
||||||
7
subprojects/mfem.wrap
Normal file
7
subprojects/mfem.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = mfem-4.10
|
||||||
|
source_url = https://github.com/mfem/mfem/archive/refs/tags/v4.10.tar.gz
|
||||||
|
source_filename = mfem-4.10.tar.gz
|
||||||
|
source_hash = d5aabe991b8b5569aa26e2b5d4b59ac617ee10ebac3d45fd6ff9c74b2c1a47dd
|
||||||
|
patch_directory = mfem
|
||||||
|
|
||||||
7
subprojects/mpich.wrap
Normal file
7
subprojects/mpich.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = mpich-4.3.2
|
||||||
|
source_url = https://www.mpich.org/static/downloads/4.3.2/mpich-4.3.2.tar.gz
|
||||||
|
source_filename = mpich-4.3.2.tar.gz
|
||||||
|
source_hash = 47d774587a7156a53752218c811c852e70ac44db9c502dc3f399b4cb817e3818
|
||||||
|
patch_directory = mpich
|
||||||
|
|
||||||
15
subprojects/nanobind.wrap
Normal file
15
subprojects/nanobind.wrap
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = nanobind-2.15.0
|
||||||
|
source_url = https://github.com/wjakob/nanobind/archive/refs/tags/v2.15.0.tar.gz
|
||||||
|
source_filename = nanobind-2.15.0.tar.gz
|
||||||
|
source_hash = 36c8760b3acb25643cd89d549782d8c67bd82ce54c6238608787c22a34fd490f
|
||||||
|
source_fallback_url = https://wrapdb.mesonbuild.com/v2/nanobind_2.15.0-1/get_source/nanobind-2.15.0.tar.gz
|
||||||
|
patch_filename = nanobind_2.15.0-1_patch.zip
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/nanobind_2.15.0-1/get_patch
|
||||||
|
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/nanobind_2.15.0-1/nanobind_2.15.0-1_patch.zip
|
||||||
|
patch_hash = 4a3956c67792830e0c85dff3cf88b30a5547bd087c33842fa5f1596ca86ccabf
|
||||||
|
wrapdb_version = 2.15.0-1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
dependency_names = nanobind
|
||||||
|
|
||||||
4
subprojects/packagefiles/algoim/meson.build
Normal file
4
subprojects/packagefiles/algoim/meson.build
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
project('algoim-source')
|
||||||
|
algoim_source_dir = meson.current_source_dir()
|
||||||
|
algoim_dep = declare_dependency(variables: {'source_dir': algoim_source_dir})
|
||||||
|
|
||||||
3
subprojects/packagefiles/blitz/meson.build
Normal file
3
subprojects/packagefiles/blitz/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('blitz-source', version: '1.0.2')
|
||||||
|
blitz_source_dir = meson.current_source_dir()
|
||||||
|
blitz_dep = declare_dependency(variables: {'source_dir': blitz_source_dir})
|
||||||
3
subprojects/packagefiles/fms/meson.build
Normal file
3
subprojects/packagefiles/fms/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('fms-source', version: '0.2')
|
||||||
|
fms_source_dir = meson.current_source_dir()
|
||||||
|
fms_dep = declare_dependency(variables: {'source_dir': fms_source_dir})
|
||||||
3
subprojects/packagefiles/gslib/meson.build
Normal file
3
subprojects/packagefiles/gslib/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('gslib-source', 'c', version: '1.0.9', meson_version: '>=1.5.0')
|
||||||
|
gslib_source_dir = meson.current_source_dir()
|
||||||
|
|
||||||
3
subprojects/packagefiles/hypre/meson.build
Normal file
3
subprojects/packagefiles/hypre/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('hypre-source', 'c', version: '2.33.0', meson_version: '>=1.5.0')
|
||||||
|
hypre_source_dir = meson.current_source_dir()
|
||||||
|
|
||||||
4
subprojects/packagefiles/libceed/meson.build
Normal file
4
subprojects/packagefiles/libceed/meson.build
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
project('libceed-source', version: '0.12.0')
|
||||||
|
libceed_source_dir = meson.current_source_dir()
|
||||||
|
libceed_dep = declare_dependency(variables: {'source_dir': libceed_source_dir})
|
||||||
|
|
||||||
2
subprojects/packagefiles/metis/meson.build
Normal file
2
subprojects/packagefiles/metis/meson.build
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
project('metis-source', 'c', version: '5.1.0', meson_version: '>=1.5.0')
|
||||||
|
metis_source_dir = meson.current_source_dir()
|
||||||
3
subprojects/packagefiles/mfem/meson.build
Normal file
3
subprojects/packagefiles/mfem/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('mfem-source', 'cpp', version: '4.10', meson_version: '>=1.5.0')
|
||||||
|
mfem_source_dir = meson.current_source_dir()
|
||||||
|
|
||||||
3
subprojects/packagefiles/mpich/meson.build
Normal file
3
subprojects/packagefiles/mpich/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('mpich-source', 'c', version: '4.3.2', meson_version: '>=1.5.0')
|
||||||
|
mpich_source_dir = meson.current_source_dir()
|
||||||
|
|
||||||
3
subprojects/packagefiles/sundials/meson.build
Normal file
3
subprojects/packagefiles/sundials/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('sundials-source', ['c', 'cpp'], version: '7.8.0', meson_version: '>=1.5.0')
|
||||||
|
sundials_source_dir = meson.current_source_dir()
|
||||||
|
|
||||||
3
subprojects/packagefiles/zlib/meson.build
Normal file
3
subprojects/packagefiles/zlib/meson.build
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
project('zlib-source', 'c', version: '1.3.1', meson_version: '>=1.5.0')
|
||||||
|
zlib_source_dir = meson.current_source_dir()
|
||||||
|
|
||||||
15
subprojects/robin-map.wrap
Normal file
15
subprojects/robin-map.wrap
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = robin-map-1.4.1
|
||||||
|
source_url = https://github.com/Tessil/robin-map/archive/refs/tags/v1.4.1.tar.gz
|
||||||
|
source_filename = robin-map-1.4.1.tar.gz
|
||||||
|
source_hash = 0e3f53a377fdcdc5f9fed7a4c0d4f99e82bbb64175233bd13427fef9a771f4a1
|
||||||
|
source_fallback_url = https://wrapdb.mesonbuild.com/v2/robin-map_1.4.1-1/get_source/robin-map-1.4.1.tar.gz
|
||||||
|
patch_filename = robin-map_1.4.1-1_patch.zip
|
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/robin-map_1.4.1-1/get_patch
|
||||||
|
patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/robin-map_1.4.1-1/robin-map_1.4.1-1_patch.zip
|
||||||
|
patch_hash = 8137d5283004db445d744d603e600119047fed865cbd740f8fec4421dc1a45b6
|
||||||
|
wrapdb_version = 1.4.1-1
|
||||||
|
|
||||||
|
[provide]
|
||||||
|
dependency_names = tsl-robin-map
|
||||||
|
|
||||||
7
subprojects/sundials.wrap
Normal file
7
subprojects/sundials.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = sundials-7.8.0
|
||||||
|
source_url = https://github.com/LLNL/sundials/archive/refs/tags/v7.8.0.tar.gz
|
||||||
|
source_filename = sundials-7.8.0.tar.gz
|
||||||
|
source_hash = c2ca15a16d7ae0d79cf1c2c288335f16b0f1c2c6d349db20aff2ce3fd1296d5a
|
||||||
|
patch_directory = sundials
|
||||||
|
|
||||||
7
subprojects/zlib.wrap
Normal file
7
subprojects/zlib.wrap
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[wrap-file]
|
||||||
|
directory = zlib-1.3.1
|
||||||
|
source_url = https://github.com/madler/zlib/archive/refs/tags/v1.3.1.tar.gz
|
||||||
|
source_filename = zlib-1.3.1.tar.gz
|
||||||
|
source_hash = 17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c
|
||||||
|
patch_directory = zlib
|
||||||
|
|
||||||
86
tests/meson.build
Normal file
86
tests/meson.build
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
if get_option('build_tests') and get_option('build_examples')
|
||||||
|
runtime_environment = environment()
|
||||||
|
if (
|
||||||
|
mfem_runtime_prefix != '' and dependency_prefix != '' and
|
||||||
|
not wheel_carries_native_bundle
|
||||||
|
)
|
||||||
|
runtime_environment.prepend('PATH', dependency_prefix / 'bin')
|
||||||
|
if host_machine.system() == 'darwin'
|
||||||
|
runtime_environment.prepend('DYLD_LIBRARY_PATH', dependency_prefix / 'lib64')
|
||||||
|
runtime_environment.prepend('DYLD_LIBRARY_PATH', dependency_prefix / 'lib')
|
||||||
|
elif host_machine.system() != 'windows' and not is_wasm
|
||||||
|
runtime_environment.prepend('LD_LIBRARY_PATH', dependency_prefix / 'lib64')
|
||||||
|
runtime_environment.prepend('LD_LIBRARY_PATH', dependency_prefix / 'lib')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if mfem_runtime_prefix != ''
|
||||||
|
runtime_environment.prepend('PATH', mfem_runtime_prefix / 'bin')
|
||||||
|
if host_machine.system() == 'darwin'
|
||||||
|
runtime_environment.prepend('DYLD_LIBRARY_PATH', mfem_runtime_prefix / 'lib64')
|
||||||
|
runtime_environment.prepend('DYLD_LIBRARY_PATH', mfem_runtime_prefix / 'lib')
|
||||||
|
elif host_machine.system() != 'windows' and not is_wasm
|
||||||
|
runtime_environment.prepend('LD_LIBRARY_PATH', mfem_runtime_prefix / 'lib64')
|
||||||
|
runtime_environment.prepend('LD_LIBRARY_PATH', mfem_runtime_prefix / 'lib')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
test(
|
||||||
|
'serial-poisson',
|
||||||
|
serial_example,
|
||||||
|
env: runtime_environment,
|
||||||
|
timeout: 120,
|
||||||
|
)
|
||||||
|
|
||||||
|
if mfem_has_mpi
|
||||||
|
if mpi_launcher_from_dependency and not wheel_carries_native_bundle
|
||||||
|
mpi_launcher_program = find_program(
|
||||||
|
dependency_prefix / 'bin' / 'mpiexec',
|
||||||
|
dependency_prefix / 'bin' / 'mpirun',
|
||||||
|
required: true,
|
||||||
|
)
|
||||||
|
mpi_launcher = mpi_launcher_program.full_path()
|
||||||
|
elif mfem_runtime_prefix != ''
|
||||||
|
mpi_launcher = mfem_runtime_prefix / 'bin' / 'mpiexec'
|
||||||
|
else
|
||||||
|
mpi_launcher_program = find_program('mpiexec', 'mpirun', required: true)
|
||||||
|
mpi_launcher = mpi_launcher_program.full_path()
|
||||||
|
endif
|
||||||
|
test(
|
||||||
|
'parallel-hypre-boomeramg',
|
||||||
|
python_build,
|
||||||
|
args: [
|
||||||
|
files('../tools/run_mpi_test.py'),
|
||||||
|
'--launcher', mpi_launcher,
|
||||||
|
'--processes', '2',
|
||||||
|
parallel_example,
|
||||||
|
],
|
||||||
|
env: runtime_environment,
|
||||||
|
timeout: 180,
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if get_option('build_tests') and get_option('build_python')
|
||||||
|
python_test_environment = environment()
|
||||||
|
python_test_environment.prepend('PYTHONPATH', python_extension_dir)
|
||||||
|
if mfem_runtime_prefix != ''
|
||||||
|
if host_machine.system() == 'darwin'
|
||||||
|
python_test_environment.prepend('DYLD_LIBRARY_PATH', mfem_runtime_prefix / 'lib64')
|
||||||
|
python_test_environment.prepend('DYLD_LIBRARY_PATH', mfem_runtime_prefix / 'lib')
|
||||||
|
elif host_machine.system() != 'windows'
|
||||||
|
python_test_environment.prepend('LD_LIBRARY_PATH', mfem_runtime_prefix / 'lib64')
|
||||||
|
python_test_environment.prepend('LD_LIBRARY_PATH', mfem_runtime_prefix / 'lib')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
test(
|
||||||
|
'python-nanobind',
|
||||||
|
python_build,
|
||||||
|
args: [
|
||||||
|
'-c',
|
||||||
|
'import _core; assert _core.serial_poisson_dofs(3, 1) > 0; assert _core.capabilities()["hypre"] == _core.capabilities()["mpi"]',
|
||||||
|
],
|
||||||
|
depends: python_extension,
|
||||||
|
env: python_test_environment,
|
||||||
|
timeout: 120,
|
||||||
|
)
|
||||||
|
endif
|
||||||
2387
tools/build_mfem_bundle.py
Normal file
2387
tools/build_mfem_bundle.py
Normal file
File diff suppressed because it is too large
Load Diff
51
tools/ceed_jit_source_root_relocatable.c
Normal file
51
tools/ceed_jit_source_root_relocatable.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and
|
||||||
|
// other CEED contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// Relocatable replacement for libCEED's installed JIT source-root object.
|
||||||
|
// Upstream normally compiles the installation prefix into libceed. Native
|
||||||
|
// source bundles here are shared libraries, so derive ../include from the
|
||||||
|
// loaded library instead. Emscripten has no runtime compiler/JIT filesystem.
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
|
||||||
|
const char *CeedJitSourceRootDefault = "";
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char ceed_jit_source_root[PATH_MAX];
|
||||||
|
const char *CeedJitSourceRootDefault = ceed_jit_source_root;
|
||||||
|
|
||||||
|
__attribute__((constructor)) static void CeedSetRelocatableJitSourceRoot(void) {
|
||||||
|
Dl_info info;
|
||||||
|
char library_path[PATH_MAX];
|
||||||
|
|
||||||
|
if (!dladdr((void *)&CeedJitSourceRootDefault, &info) || !info.dli_fname) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (snprintf(library_path, sizeof library_path, "%s", info.dli_fname) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char *separator = strrchr(library_path, '/');
|
||||||
|
if (!separator) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*separator = '\0';
|
||||||
|
(void)snprintf(ceed_jit_source_root, sizeof ceed_jit_source_root,
|
||||||
|
"%s/../include/", library_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
39
tools/install_bundle.py
Normal file
39
tools/install_bundle.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Copy a build-tree MFEM prefix into a Meson/meson-python destination."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
|
def staged_destination(destination: Path) -> Path:
|
||||||
|
destdir = os.environ.get("DESTDIR", "")
|
||||||
|
if not destdir or not destination.is_absolute():
|
||||||
|
return destination
|
||||||
|
destination_text = os.fspath(destination)
|
||||||
|
relative = destination_text[len(destination.anchor) :].lstrip("/\\")
|
||||||
|
return Path(destdir) / relative
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--source", type=Path, required=True)
|
||||||
|
parser.add_argument("--destination", type=Path, required=True)
|
||||||
|
args = parser.parse_args()
|
||||||
|
destination = staged_destination(args.destination)
|
||||||
|
destination.mkdir(parents=True, exist_ok=True)
|
||||||
|
for child in args.source.iterdir():
|
||||||
|
target = destination / child.name
|
||||||
|
if child.is_dir():
|
||||||
|
shutil.copytree(child, target, dirs_exist_ok=True, symlinks=True)
|
||||||
|
else:
|
||||||
|
shutil.copy2(child, target, follow_symlinks=False)
|
||||||
|
print(f"Installed MFEM native bundle to {destination}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
33
tools/run_mpi_test.py
Normal file
33
tools/run_mpi_test.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run one MPI test without baking a particular MPI launcher into the meson build tree."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--launcher", required=True)
|
||||||
|
parser.add_argument("--processes", type=int, default=2)
|
||||||
|
parser.add_argument("executable")
|
||||||
|
parser.add_argument("arguments", nargs="*")
|
||||||
|
args = parser.parse_args()
|
||||||
|
command = [args.launcher, "-n", str(args.processes), args.executable, *args.arguments]
|
||||||
|
environment = dict(os.environ)
|
||||||
|
environment.setdefault("OMPI_ALLOW_RUN_AS_ROOT", "1")
|
||||||
|
environment.setdefault("OMPI_ALLOW_RUN_AS_ROOT_CONFIRM", "1")
|
||||||
|
loopback = "lo0" if sys.platform == "darwin" else "lo"
|
||||||
|
environment.setdefault("FI_PROVIDER", "sockets")
|
||||||
|
environment.setdefault("FI_SOCKETS_IFACE", loopback)
|
||||||
|
environment.setdefault("HYDRA_IFACE", loopback)
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
environment.setdefault("MPICH_INTERFACE_HOSTNAME", "127.0.0.1")
|
||||||
|
return subprocess.run(command, env=environment, check=False).returncode
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
66
tools/validate_matrix.sh
Executable file
66
tools/validate_matrix.sh
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
project_root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||||
|
meson_bin=${MESON_BIN:-meson}
|
||||||
|
meson_dir=$(CDPATH= cd -- "$(dirname -- "$meson_bin")" && pwd)
|
||||||
|
profile=${MFEM_MATRIX_PROFILE:-portable}
|
||||||
|
jobs=${MFEM_JOBS:-4}
|
||||||
|
|
||||||
|
compiler_family() {
|
||||||
|
"$1" --version 2>&1 | sed -n '1p'
|
||||||
|
}
|
||||||
|
|
||||||
|
require_clang() {
|
||||||
|
version=$(compiler_family "$1")
|
||||||
|
case "$version" in
|
||||||
|
*clang*|*Clang*) ;;
|
||||||
|
*) echo "error: $1 is not a Clang compiler: $version" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
require_gnu() {
|
||||||
|
version=$(compiler_family "$1")
|
||||||
|
case "$version" in
|
||||||
|
*gcc*|*GCC*|*"Free Software Foundation"*) ;;
|
||||||
|
*) echo "error: $1 is not a GNU compiler: $version" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
run_configuration() {
|
||||||
|
name=$1
|
||||||
|
c_compiler=$2
|
||||||
|
cxx_compiler=$3
|
||||||
|
mode=$4
|
||||||
|
build_dir="$project_root/build-$name"
|
||||||
|
|
||||||
|
if test -f "$build_dir/meson-private/coredata.dat"; then
|
||||||
|
wipe_flag=--wipe
|
||||||
|
else
|
||||||
|
wipe_flag=
|
||||||
|
fi
|
||||||
|
env PATH="$meson_dir:$PATH" CC="$c_compiler" CXX="$cxx_compiler" \
|
||||||
|
"$meson_bin" setup $wipe_flag "$build_dir" "$project_root" \
|
||||||
|
--buildtype="$mode" \
|
||||||
|
-Dallow_preinstalled=false \
|
||||||
|
-Dfeature_profile="$profile" \
|
||||||
|
-Dbuild_examples=true \
|
||||||
|
-Dbuild_tests=true \
|
||||||
|
-Dbuild_python=false \
|
||||||
|
-Djobs="$jobs"
|
||||||
|
env PATH="$meson_dir:$PATH" "$meson_bin" compile -C "$build_dir"
|
||||||
|
env PATH="$meson_dir:$PATH" "$meson_bin" test -C "$build_dir" --print-errorlogs
|
||||||
|
}
|
||||||
|
|
||||||
|
clang_cc=${CLANG_CC:-clang}
|
||||||
|
clang_cxx=${CLANG_CXX:-clang++}
|
||||||
|
gcc_cc=${GNU_CC:-gcc}
|
||||||
|
gcc_cxx=${GNU_CXX:-g++}
|
||||||
|
|
||||||
|
require_clang "$clang_cxx"
|
||||||
|
require_gnu "$gcc_cxx"
|
||||||
|
|
||||||
|
run_configuration clang-debug "$clang_cc" "$clang_cxx" debug
|
||||||
|
run_configuration clang-release "$clang_cc" "$clang_cxx" release
|
||||||
|
run_configuration gcc-debug "$gcc_cc" "$gcc_cxx" debug
|
||||||
|
run_configuration gcc-release "$gcc_cc" "$gcc_cxx" release
|
||||||
Reference in New Issue
Block a user