Skip to content

ESPResSo 5.0-dev #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f631ac5
ESPResSo 5.0-dev
jngrad Jun 5, 2025
11693f8
Use full commit SHA and update source download file name
Neves-P Jun 12, 2025
de7e829
Add missing
Neves-P Jun 12, 2025
a6cc000
Adjust URLs
jngrad Jun 12, 2025
58f024b
Add download_filename fields
Neves-P Jun 12, 2025
79a7629
Add missing comma
Neves-P Jun 12, 2025
f0f6488
Correct ESPReSso"s GitHub repo URL
Neves-P Jun 12, 2025
d50b220
Fix espresso tarball name
Neves-P Jun 12, 2025
820c07c
Fix source tarball names and checksums
Neves-P Jun 12, 2025
7bbf4c6
Consistent tarball namesb between steps
Neves-P Jun 13, 2025
4357188
Explicitly include this repo's easyblock
Neves-P Jun 13, 2025
497d642
Proper path to easyblock
Neves-P Jun 13, 2025
8aa2e96
Add EESSI version subdir in easystacks/ to account for EESSI/software…
Neves-P Jun 13, 2025
4b689c9
Try pathname with wildcards
Neves-P Jun 13, 2025
c2a2927
Remove failing git commands
jngrad Jun 13, 2025
c530ef6
Use EasyBuild 5.1.0
Neves-P Jun 13, 2025
a7e1733
\Merge branch 'easyblock' of https://github.com/jngrad/dev.eessi.io-e…
Neves-P Jun 13, 2025
49d9c34
Try with
Neves-P Jun 13, 2025
8f3cdf7
move 2023.06 subdir to new dev.eessi.io subdir. Comply with EESSI/sof…
Neves-P Jun 13, 2025
fd78a65
Rename easystacks subdir (temporarily, to confirm effect of change)
Neves-P Jun 13, 2025
d6bf902
Fix silly typo...
Neves-P Jun 13, 2025
6870310
Add HeFFTe-2.4.1-foss-2023b.eb
Neves-P Jun 23, 2025
986485a
Use EESSI heFFTe
jngrad Jun 23, 2025
69a4b59
Temporarily revert heFFTe changes
jngrad Jun 23, 2025
b78aaca
Bump ESPResSo version
jngrad Jun 23, 2025
4704e9a
Fix linker errors
jngrad Jun 23, 2025
d55b86f
Remove auxiliary files
jngrad Jun 23, 2025
83d1872
Cleanup espresso.py
jngrad Jun 24, 2025
6d90140
Bump ESPResSo version
jngrad Jun 24, 2025
2626b89
More tweaks
jngrad Jun 24, 2025
f010aee
Use lib64
jngrad Jun 24, 2025
4773c27
Revert "Use lib64"
jngrad Jun 24, 2025
49f1079
Factor in oversubscription
jngrad Jun 24, 2025
d879c93
Disable parallel scheduling of tests
jngrad Jun 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# dev.eessi.io-espresso
# dev.eessi.io-espresso

Repository for pre-release builds of [ESPResSo](https://github.com/espressomd/espresso).
Builds are deployed to the [`dev.eessi.io`](https://www.eessi.io/docs/repositories/dev.eessi.io/) repository.
142 changes: 142 additions & 0 deletions easyconfigs/ESPResSo-foss-2023b-software-commit.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
easyblock = 'EB_ESPResSo'

name = 'ESPResSo'
version = '%(software_commit)s'

homepage = 'https://espressomd.org/wordpress'
description = """A software package for Molecular Dynamics and Monte Carlo
simulations of bead-spring models, with electrostatics, magnetostatics,
hydrodynamics and reaction-diffusion-advection solvers."""

sources = [
{
'source_urls': ['https://github.com/espressomd/espresso/archive/'],
'filename': 'espresso-%(software_commit)s.tar.gz',
'download_filename': '%(software_commit)s.tar.gz',
},
{
'source_urls': ['https://i10git.cs.fau.de/api/v4/projects/walberla%2Fwalberla/repository/archive?sha=59c9b8b1#'],
'filename': 'walberla-59c9b8b1.tar.gz',
},
{
'source_urls': ['https://github.com/icl-utk-edu/heffte/archive/'],
'filename': 'heffte-2.4.1.tar.gz',
'download_filename': 'v2.4.1.tar.gz',
},
{
'source_urls': ['https://github.com/kokkos/kokkos/archive/'],
'filename': 'kokkos-18b830e3360dff9f44a9a9c729ca9e74c037e354.tar.gz',
'download_filename': '18b830e3360dff9f44a9a9c729ca9e74c037e354.tar.gz',
},
{
'source_urls': ['https://github.com/ECP-copa/Cabana/archive/'],
'filename': 'Cabana-ebfaa51.tar.gz',
'download_filename': 'ebfaa51.tar.gz',
},
{
'source_urls': ['https://github.com/highfive-devs/highfive/archive/'],
'filename': 'highfive-0103467c3b609628fe3b892c6a85915610f2f3d2.tar.gz',
'download_filename': '0103467.tar.gz',
},
]
checksums = [{
'espresso-%(software_commit)s.tar.gz': '73d71511eca932adcff4f33ac778c77279e97cec91ea1ac53987ba488fc1288d',
'walberla-59c9b8b1.tar.gz': 'a709d7299f2c06143946d9bb8033d4ddbb0cf8b9142e4bbaa15fecc78463038f',
'heffte-2.4.1.tar.gz': 'de2cf26df5d61baac7841525db3f393cb007f79612ac7534fd4757f154ba3e6c',
'kokkos-18b830e.tar.gz': 'dc0127134f47752f61e74c77237bd9ec560535c4283fef8c9643f947b3733063',
'Cabana-ebfaa51.tar.gz': 'fe5b1b1d419662b29a80cbd6703994b28c942ccbee3b201eca87e48a13836350',
'highfive-0103467.tar.gz': 'd0ce87abd07cdd676c6d6069d3b05f869138d115d8e22b935c9bd43c872c1f3d',
}]
patches = [
'espresso.patch',
]

toolchain = {'name': 'foss', 'version': '2023b'}
toolchainopts = {'usempi': True, 'pic': True}

builddependencies = [
('CMake', '3.27.6'),
('Ninja', '1.11.1'),
]

dependencies = [
('Python', '3.11.5'),
('SciPy-bundle', '2023.11'),
('Boost.MPI', '1.83.0'),
('Mesa', '23.1.9'),
('GSL', '2.7'),
('IPython', '8.17.2'),
('Pint', '0.24'),
('HDF5', '1.14.3'),
#('VTK', '9.3.0'), # error: libpython3.10.so.1.0: file not found
#('PFFT', '20181230'), # not available in this toolchain
#('CUDA', '12.1.1', '', SYSTEM), # deferred for now
]

# default CUDA compute capabilities to use (override via --cuda-compute-capabilities)
if any(x[0] == 'CUDA' for x in dependencies):
cuda_compute_capabilities = ['5.2', '6.0', '7.0', '7.5', '8.0', '8.6', '9.0']

configopts = f' -DESPRESSO_BUILD_TESTS=ON '
# make sure the right Python is used (note: -DPython3_EXECUTABLE or -DPython_EXECUTABLE does not work!)
configopts += ' -D PYTHON_EXECUTABLE=$EBROOTPYTHON/bin/python '
configopts += ' -DCMAKE_INSTALL_LIBDIR:PATH=lib '
# workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/22678
# (this only affects testsuite executable files in the build folder)
_exe_linker_flags = ':'.join(f'%(builddir)s/easybuild_obj/_deps/{path}'
for path in ['kokkos-build/containers/src',
'kokkos-build/core/src',
'kokkos-build/simd/src',
'heffte-build'])
configopts += f' -DCMAKE_EXE_LINKER_FLAGS="-Wl,-rpath-link,{_exe_linker_flags}" '

test_cmd = 'ninja'
runtest = f'check_unit_tests && {test_cmd} check_python'

modextrapaths = {'PYTHONPATH': ['lib/python%(pyshortver)s/site-packages']}

_binaries = ['ipypresso', 'pypresso']
_libs = [
# ESPResSo
'espresso_core', 'espresso_shapes', 'espresso_walberla',
'espresso_script_interface', 'script_interface', 'utils', '_init',
# waLBerla
'libwalberla_core', 'libwalberla_executiontree', 'libwalberla_timeloop',
'libwalberla_field', 'libwalberla_blockforest', 'libwalberla_geometry',
'libwalberla_lbm', 'libwalberla_vtk', 'libwalberla_domain_decomposition',
'libwalberla_boundary', 'liblodepng',
# Kokkos
'libkokkoscontainers', 'libkokkoscore', 'libkokkossimd',
# heFFte
'libheffte',
]
_python_modules = [
'__init__.py', 'system.py', 'version.py', 'collision_detection.py', 'lb.py',
'accumulators.py', 'constraints.py', 'observables.py', 'particle_data.py',
]
if any(x[0] == 'PFFT' for x in dependencies):
_libs.append('libwalberla_fft')
if any(x[0] == 'HDF5' for x in dependencies):
_libs.append('espresso_hdf5')
_python_modules.append('io/writer/h5md.py')
if any(x[0] == 'CUDA' for x in dependencies):
_libs += [
'espresso_cuda', 'espresso_walberla_cuda', 'libwalberla_gpu',
]
_python_modules.append('cuda_init.py')

_lib_path = 'lib/python%(pyshortver)s/site-packages/espressomd'
sanity_check_paths = {
'files': [f'bin/{x}' for x in _binaries] +
[f'{_lib_path}/{x}.{SHLIB_EXT}' for x in _libs] +
[f'{_lib_path}/{x}' for x in _python_modules],
'dirs': ['bin', 'lib']
}

sanity_check_commands = [
'pypresso -h', 'ipypresso -h',
'pypresso -c "import espressomd.version;print(espressomd.version.friendly())"',
'python3 -c "import espressomd.version;print(espressomd.version.friendly())"',
]

moduleclass = 'chem'
15 changes: 15 additions & 0 deletions easyconfigs/e/ESPResSo/espresso.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Cython 3.0.4 is supported, although it generates many warnings
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -245,3 +245,3 @@
find_package(Python 3.11 REQUIRED COMPONENTS Interpreter Development NumPy)
- find_package(Cython 3.0.8...<3.1.0 REQUIRED)
+ find_package(Cython 3.0.4...<3.1.0 REQUIRED)
find_program(IPYTHON_EXECUTABLE NAMES jupyter ipython3 ipython)
# skip fragile test which may crash hdf5 depending on how it was built
--- testsuite/python/CMakeLists.txt
+++ testsuite/python/CMakeLists.txt
@@ -386,3 +386,2 @@
python_test(FILE h5md.py MAX_NUM_PROC 2)
-python_test(FILE h5md.py MAX_NUM_PROC 1 SUFFIX 1_core)
python_test(FILE p3m_fft.py MAX_NUM_PROC 6)
154 changes: 154 additions & 0 deletions easyconfigs/e/ESPResSo/espresso.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#
# Copyright 2025 Jean-Noël Grad
#
# This code is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This code is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

"""
EasyBuild support for ESPResSo, implemented as an easyblock.

@author: Jean-Noël Grad (University of Stuttgart)
"""

import os
import re
import shutil
from easybuild.easyblocks.generic.cmakeninja import CMakeNinja
from easybuild.tools.systemtools import get_cpu_architecture, get_cpu_features
from easybuild.tools.systemtools import X86_64
from easybuild.tools.utilities import trace_msg
from easybuild.tools.build_log import print_error


class EB_ESPResSo(CMakeNinja):
"""Support for building and installing ESPResSo."""

def _get_extracted_tarball_paths(self):
"""
Locate the source code of all dependencies.
"""
extracted_paths = {}
for src in self.src:
name = src['name'].split('-', 1)[0]
# process main software
if name == 'espresso':
extracted_paths['espresso'] = src['finalpath']
continue
# process dependencies
tarball = src['name']
if not tarball.endswith('.tar.gz'):
raise ValueError(tarball + ' is not a tar.gz file')
prefix = tarball.rsplit('.', 2)[0]
matches = [x for x in os.listdir(src['finalpath']) if x.startswith(prefix)]
if len(matches) == 0:
raise RuntimeError(tarball + ' was not extracted')
if len(matches) > 1:
raise RuntimeError(tarball + ' matches multiple folders: ' + str(matches))
extracted_paths[name] = os.path.join(src['finalpath'], matches[0])
return extracted_paths

def _patch_fetchcontent(self):
"""
Modify CMake ``FetchContent_Declare`` blocks to point to the folders
containing the already-downloaded dependencies rather than to URLs.
This avoids a download step during configuration.
"""
extracted_paths = self._get_extracted_tarball_paths()
cmakelists_path = os.path.join(extracted_paths['espresso'], 'CMakeLists.txt')
with open(cmakelists_path, 'r') as f:
content = f.read()
for name, local_uri in extracted_paths.items():
if name == 'espresso':
continue
pattern = fr'FetchContent_Declare\(\s*{name}\s+GIT_REPOSITORY\s+\S+\s+GIT_TAG\s+\S+(?=\s|\))'
m = re.search(pattern, content, flags=re.IGNORECASE)
if m is None:
raise RuntimeError(f'{name} is not part of the ESPResSo FetchContent workflow')
content = re.sub(pattern, f'FetchContent_Declare({name} URL {local_uri}', content, flags=re.IGNORECASE)
with open(cmakelists_path, 'w') as f:
f.write(content)

def configure_step(self):
# patch FetchContent to avoid re-downloading dependencies
self._patch_fetchcontent()

configopts = self.cfg.get('configopts', '')
dependencies = self.cfg.get('dependencies', [])

cpu_features = get_cpu_features()
with_cuda = any(x.get('name', '') == 'CUDA' for x in dependencies)
with_pfft = any(x.get('name', '') == 'PFFT' for x in dependencies)
with_hdf5 = any(x.get('name', '') == 'HDF5' for x in dependencies)
with_gsl = any(x.get('name', '') == 'GSL' for x in dependencies)

if with_cuda:
configopts += ' -DESPRESSO_BUILD_WITH_CUDA=ON'
else:
configopts += ' -DESPRESSO_BUILD_WITH_CUDA=OFF'
if with_hdf5:
configopts += ' -DESPRESSO_BUILD_WITH_HDF5=ON'
else:
configopts += ' -DESPRESSO_BUILD_WITH_HDF5=OFF'
if with_gsl:
configopts += ' -DESPRESSO_BUILD_WITH_GSL=ON'
else:
configopts += ' -DESPRESSO_BUILD_WITH_GSL=OFF'

configopts += ' -DESPRESSO_BUILD_WITH_WALBERLA=ON'
if with_pfft:
configopts += ' -DESPRESSO_BUILD_WITH_WALBERLA_FFT=ON'
else:
configopts += ' -DESPRESSO_BUILD_WITH_WALBERLA_FFT=OFF'
if get_cpu_architecture() == X86_64 and 'avx2' in cpu_features:
configopts += ' -DESPRESSO_BUILD_WITH_WALBERLA_AVX=ON'

configopts += ' -DESPRESSO_BUILD_WITH_SHARED_MEMORY_PARALLELISM=ON'
configopts += ' -DESPRESSO_BUILD_WITH_FFTW=ON'

self.cfg['configopts'] = configopts

return super(EB_ESPResSo, self).configure_step()

def _cleanup_aux_files(self):
"""
Remove files automatically installed by CMake outside the ESPResSo
main directory: header files, config files, duplicated shared objects.
"""
def delete_dir(path):
if os.path.isdir(path):
trace_msg(f'removing directory \'%s\'' % path.replace(f'{self.installdir}/', ''))
shutil.rmtree(path)

def delete_file(path):
if os.path.isfile(path) or os.path.islink(path):
trace_msg(f'removing file \'%s\'' % path.replace(f'{self.installdir}/', ''))
os.remove(path)

lib_dir = f'{self.installdir}/lib'
if os.path.isdir(f'{self.installdir}/lib64'):
lib_dir = f'{self.installdir}/lib64'
delete_dir(f'{self.installdir}/include')
delete_dir(f'{self.installdir}/share')
delete_dir(f'{self.installdir}/walberla')
delete_dir(f'{lib_dir}/cmake')
for path in os.listdir(lib_dir):
if '.so' in path:
delete_file(f'{lib_dir}/{path}')

def post_processing_step(self):
try:
self._cleanup_aux_files()
except Exception as err:
print_error("Failed to remove some auxiliary files (easyblock: %s): %s" % (self.__class__.__name__, str(err)))
return super(EB_ESPResSo, self).post_processing_step()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
easyconfigs:
- ESPResSo-foss-2023b-software-commit.eb:
options:
software-commit: 8aa60cecd56cdd10ab62042c567552f347374f36 # waLBerla coupling and OpenMP support
include-easyblocks: easyconfigs/*/*/*.py