Skip to content

Commit 4d490fc

Browse files
committed
Merge branch '5.0.x' into parallel_prop
2 parents 4adc5b3 + 4edfdbe commit 4d490fc

File tree

20 files changed

+551
-676
lines changed

20 files changed

+551
-676
lines changed

easybuild/easyblocks/g/gromacs.py

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,27 @@
3232
@author: Guilherme Peretti-Pezzi (CSCS)
3333
@author: Oliver Stueker (Compute Canada/ACENET)
3434
@author: Davide Vanzo (Vanderbilt University)
35+
@author: Alex Domingo (Vrije Universiteit Brussel)
3536
"""
3637
import glob
3738
import os
3839
import re
3940
import shutil
40-
from easybuild.tools import LooseVersion
4141

4242
import easybuild.tools.environment as env
4343
import easybuild.tools.toolchain as toolchain
44-
from easybuild.easyblocks.generic.configuremake import ConfigureMake
4544
from easybuild.easyblocks.generic.cmakemake import CMakeMake
45+
from easybuild.easyblocks.generic.configuremake import ConfigureMake
4646
from easybuild.framework.easyconfig import CUSTOM
47+
from easybuild.tools import LooseVersion
4748
from easybuild.tools.build_log import EasyBuildError, print_warning
4849
from easybuild.tools.config import build_option
4950
from easybuild.tools.filetools import copy_dir, find_backup_name_candidate, remove_dir, which
5051
from easybuild.tools.modules import get_software_libdir, get_software_root, get_software_version
5152
from easybuild.tools.run import run_shell_cmd
53+
from easybuild.tools.systemtools import X86_64, get_cpu_architecture, get_cpu_features, get_shared_lib_ext
5254
from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC
53-
from easybuild.tools.systemtools import X86_64, get_cpu_architecture, get_shared_lib_ext, get_cpu_features
55+
from easybuild.tools.utilities import nub
5456
from easybuild.tools.version import VERBOSE_VERSION as EASYBUILD_VERSION
5557

5658

@@ -79,12 +81,15 @@ def extra_options():
7981
def __init__(self, *args, **kwargs):
8082
"""Initialize GROMACS-specific variables."""
8183
super(EB_GROMACS, self).__init__(*args, **kwargs)
82-
self.lib_subdir = ''
84+
85+
self.lib_subdirs = ''
8386
self.pre_env = ''
8487
self.cfg['build_shared_libs'] = self.cfg.get('build_shared_libs', False)
88+
8589
if LooseVersion(self.version) >= LooseVersion('2019'):
8690
# Building the gmxapi interface requires shared libraries
8791
self.cfg['build_shared_libs'] = True
92+
8893
if self.cfg['build_shared_libs']:
8994
self.libext = get_shared_lib_ext()
9095
else:
@@ -142,6 +147,7 @@ def get_gromacs_arch(self):
142147

143148
return res
144149

150+
@property
145151
def is_double_precision_cuda_build(self):
146152
"""Check if the current build step involves double precision and CUDA"""
147153
cuda = get_software_root('CUDA')
@@ -461,15 +467,15 @@ def build_step(self):
461467
iteration is for double precision
462468
"""
463469

464-
if self.is_double_precision_cuda_build():
470+
if self.is_double_precision_cuda_build:
465471
self.log.info("skipping build step")
466472
else:
467473
super(EB_GROMACS, self).build_step()
468474

469475
def test_step(self):
470476
"""Run the basic tests (but not necessarily the full regression tests) using make check"""
471477

472-
if self.is_double_precision_cuda_build():
478+
if self.is_double_precision_cuda_build:
473479
self.log.info("skipping test step")
474480
else:
475481
# allow to escape testing by setting runtest to False
@@ -525,7 +531,7 @@ def install_step(self):
525531
Custom install step for GROMACS; figure out where libraries were installed to.
526532
"""
527533
# Skipping if CUDA is enabled and the current iteration is double precision
528-
if self.is_double_precision_cuda_build():
534+
if self.is_double_precision_cuda_build:
529535
self.log.info("skipping install step")
530536
else:
531537
# run 'make install' in parallel since it involves more compilation
@@ -548,48 +554,55 @@ def extensions_step(self, fetch=False):
548554
super(EB_GROMACS, self).extensions_step(fetch)
549555
self.cfg['runtest'] = orig_runtest
550556

551-
def get_lib_subdir(self):
552-
# the GROMACS libraries get installed in different locations (deeper subdirectory),
553-
# depending on the platform;
554-
# this is determined by the GNUInstallDirs CMake module;
555-
# rather than trying to replicate the logic, we just figure out where the library was placed
557+
def get_lib_subdirs(self):
558+
"""
559+
Return list of relative paths to sub-directories that contain GROMACS libraries
560+
561+
The GROMACS libraries get installed in different locations (deeper subdirectory),
562+
depending on the platform;
563+
this is determined by the GNUInstallDirs CMake module;
564+
rather than trying to replicate the logic, we just figure out where the library was placed
565+
"""
556566

557567
if LooseVersion(self.version) < LooseVersion('5.0'):
558-
libname = 'libgmx*.%s' % self.libext
568+
libname = f'libgmx*.{self.libext}'
559569
else:
560-
libname = 'libgromacs*.%s' % self.libext
561-
lib_subdir = None
562-
for libdir in ['lib', 'lib64']:
563-
if os.path.exists(os.path.join(self.installdir, libdir)):
564-
for subdir in [libdir, os.path.join(libdir, '*')]:
565-
libpaths = glob.glob(os.path.join(self.installdir, subdir, libname))
566-
if libpaths:
567-
lib_subdir = os.path.dirname(libpaths[0])[len(self.installdir) + 1:]
568-
self.log.info("Found lib subdirectory that contains %s: %s", libname, lib_subdir)
569-
break
570-
if not lib_subdir:
571-
raise EasyBuildError("Failed to determine lib subdirectory in %s", self.installdir)
572-
573-
return lib_subdir
574-
575-
def make_module_req_guess(self):
570+
libname = f'libgromacs*.{self.libext}'
571+
572+
lib_subdirs = []
573+
real_installdir = os.path.realpath(self.installdir)
574+
for lib_path in glob.glob(os.path.join(real_installdir, '**', libname)):
575+
lib_relpath = os.path.realpath(lib_path) # avoid symlinks
576+
lib_relpath = lib_relpath[len(real_installdir) + 1:] # relative path from installdir
577+
subdir = lib_relpath.split(os.sep)[0:-1]
578+
lib_subdirs.append(os.path.join(*subdir))
579+
580+
if len(lib_subdirs) == 0:
581+
raise EasyBuildError(f"Failed to determine sub-directory with {libname} in {self.installdir}")
582+
583+
# remove duplicates, 'libname' pattern can match symlinks to actual library file
584+
lib_subdirs = nub(lib_subdirs)
585+
self.log.info(f"Found sub-directories that contain {libname}: {', '.join(lib_subdirs)}")
586+
587+
return lib_subdirs
588+
589+
def make_module_step(self, *args, **kwargs):
576590
"""Custom library subdirectories for GROMACS."""
577-
guesses = super(EB_GROMACS, self).make_module_req_guess()
578-
if not self.lib_subdir:
591+
if not self.lib_subdirs:
579592
try:
580-
self.lib_subdir = self.get_lib_subdir()
593+
self.lib_subdirs = self.get_lib_subdirs()
581594
except EasyBuildError as error:
582595
if build_option('force') and build_option('module_only'):
583-
self.log.info("No lib subdirectory directory found in installation: %s", error)
596+
self.log.info(f"No sub-directory with GROMACS libraries found in installation: {error}")
584597
self.log.info("You are forcing module creation for a non-existent installation!")
585598
else:
586599
raise error
587-
guesses.update({
588-
'LD_LIBRARY_PATH': [self.lib_subdir],
589-
'LIBRARY_PATH': [self.lib_subdir],
590-
'PKG_CONFIG_PATH': [os.path.join(self.lib_subdir, 'pkgconfig')],
591-
})
592-
return guesses
600+
601+
self.module_load_environment.LD_LIBRARY_PATH = self.lib_subdirs
602+
self.module_load_environment.LIBRARY_PATH = self.lib_subdirs
603+
self.module_load_environment.PKG_CONFIG_PATH = [os.path.join(ld, 'pkgconfig') for ld in self.lib_subdirs]
604+
605+
return super().make_module_step(*args, **kwargs)
593606

594607
def sanity_check_step(self):
595608
"""Custom sanity check for GROMACS."""
@@ -660,21 +673,19 @@ def sanity_check_step(self):
660673
if dsuff:
661674
suffixes.extend([dsuff])
662675

663-
lib_files.extend([
664-
'lib%s%s.%s' % (x, suff, self.libext) for x in libnames + mpi_libnames for suff in suffixes
665-
])
676+
lib_files.extend([f'lib{x}{suff}.{self.libext}' for x in libnames + mpi_libnames for suff in suffixes])
666677
bin_files.extend([b + suff for b in bins + mpi_bins for suff in suffixes])
667678

668-
if not self.lib_subdir:
669-
self.lib_subdir = self.get_lib_subdir()
679+
if not self.lib_subdirs:
680+
self.lib_subdirs = self.get_lib_subdirs()
670681

671682
# pkgconfig dir not available for earlier versions, exact version to use here is unclear
672683
if LooseVersion(self.version) >= LooseVersion('4.6'):
673-
dirs.append(os.path.join(self.lib_subdir, 'pkgconfig'))
684+
dirs.extend([os.path.join(ld, 'pkgconfig') for ld in self.lib_subdirs])
674685

675686
custom_paths = {
676687
'files': [os.path.join('bin', b) for b in bin_files] +
677-
[os.path.join(self.lib_subdir, lib) for lib in lib_files],
688+
[os.path.join(libdir, lib) for libdir in self.lib_subdirs for lib in lib_files],
678689
'dirs': dirs,
679690
}
680691
super(EB_GROMACS, self).sanity_check_step(custom_paths=custom_paths)

easybuild/easyblocks/generic/pythonpackage.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,6 @@ def __init__(self, *args, **kwargs):
474474
self.pylibdir = UNKNOWN
475475
self.all_pylibdirs = [UNKNOWN]
476476

477-
self.py_installopts = []
478477
self.install_cmd_output = ''
479478

480479
# make sure there's no site.cfg in $HOME, because setup.py will find it and use it
@@ -499,8 +498,6 @@ def __init__(self, *args, **kwargs):
499498
# figure out whether this Python package is being installed for multiple Python versions
500499
self.multi_python = 'Python' in self.cfg['multi_deps']
501500

502-
# determine install command
503-
self.use_setup_py = False
504501
self.determine_install_command()
505502

506503
# avoid that pip (ab)uses $HOME/.cache/pip
@@ -522,7 +519,9 @@ def determine_install_command(self):
522519
"""
523520
Determine install command to use.
524521
"""
522+
self.py_installopts = []
525523
if self.cfg.get('use_pip', True) or self.cfg.get('use_pip_editable', False):
524+
self.use_setup_py = False
526525
self.install_cmd = PIP_INSTALL_CMD
527526

528527
pip_verbose = self.cfg.get('pip_verbose', None)
@@ -551,8 +550,8 @@ def determine_install_command(self):
551550
else:
552551
self.use_setup_py = True
553552
self.install_cmd = SETUP_PY_INSTALL_CMD
554-
install_target = self.cfg.get_ref('install_target')
555553

554+
install_target = self.cfg.get_ref('install_target')
556555
if install_target == EASY_INSTALL_TARGET:
557556
self.install_cmd += " %(loc)s"
558557
self.py_installopts.append('--no-deps')

easybuild/easyblocks/i/icc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def sanity_check_step(self):
177177
}
178178

179179
# make very sure that expected 'compilers_and_libraries_<VERSION>/linux' subdir is there for recent versions,
180-
# since we rely on it being there in make_module_req_guess
180+
# since we rely on it being there in module_load_environment
181181
if self.comp_libs_subdir:
182182
custom_paths['dirs'].append(self.comp_libs_subdir)
183183

easybuild/easyblocks/i/ifort.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def sanity_check_step(self):
8282
}
8383

8484
# make very sure that expected 'compilers_and_libraries_<VERSION>/linux' subdir is there for recent versions,
85-
# since we rely on it being there in make_module_req_guess
85+
# since we rely on it being there in module_load_environment
8686
if self.comp_libs_subdir:
8787
custom_paths['dirs'].append(self.comp_libs_subdir)
8888

easybuild/easyblocks/n/neuron.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
2828
@author: Kenneth Hoste (Ghent University)
2929
@author: Maxime Boissonneault (Universite Laval, Compute Canada)
30+
@author: Alex Domingo (Vrije Universiteit Brussel)
3031
"""
3132
import os
3233
import re

0 commit comments

Comments
 (0)