Hi Ben,
On 15/10/14 03:17, Ben Roberts wrote:
Hi list,
I’m trying to install Amber 12 with Easybuild. My current version of the
framework is the latest checkout of the “develop” branch from git: commit
3c4976c5f0ea5dad572f6ed3c014380b299e2d7a.
I’m having trouble because the Amber installation process, being inherently
non-standard, is interacting strangely with the Easybuild process.
An overview of the Amber build process is as follows:
1. Download and extract the Amber tarball (extracts to “amber12”)
2. Download and extract the AmberTools tarball (also extracts into “amber12”)
3. Change into the “amber12” directory
4. Set the AMBERHOME environment variable to the amber12 directory
5. Run “configure” with options for a serial build
6. Run “make install” — note that this combines the functionality of “make” and
“make install” into a single step, and builds AmberTools and Amber in situ
7. Run “make test”
8. Run “make clean” to delete serial-specific object files, etc.
9. Run “configure” again with options for a parallel build
10. Run “make install”
11. Run “make test.parallel”
12. Run “make clean”
13. Run “configure” again with options for a CUDA build
14. Run “make install”
15. Run “make test.cuda”
16. Optionally, run “make clean”
I’ve attached my easyconfig and easyblock for your information.
The particular issue I’m having is the interplay of three features of this
build. One is that the build and install directories are the same, so that I’ve
used the “buildininstalldir” option in my easyconfig. The other is that it’s
necessary to keep at least some parts of the serial installation around for
parallel and CUDA builds, so that deleting the install directory between builds
is not an option. The third is the use of multiple configure calls, to reflect
the staged nature of the build.
You can probably already see where I’m going with this, which is the method
“make_builddir” in easybuild-framework/easybuild/framework/easyblock.py. This
method, if “buildininstalldir” is set, will force a “cleanupoldbuild” and veto
a “keeppreviousinstall” (line 641ff.), regardless of any options to the
contrary that I set in the easyconfig.
How can I get around this? Is there an option that can be implemented to deal
with staged builds of this sort, the prospect of overloading the make_builddir
method in my easyblock, or some other solution that I haven’t floated yet?
Since you already have a dedicated easyblock for Amber, you should push
as much as possible in there, and keep Amber easyconfigs absolutely minimal.
That is: move defining the configure options and test targets in the
easyblock, set self.build_in_installdir = True in the easyblock (see the
WRF easyblock for example), move the custom sanity check to the
easyblock, etc.
Combining a custom easyblock together with the support for using a list
of strings for configopts/buildopts/installopts (rather a single string)
is indeed tricky, and the build_in_installdir requirements isn't exactly
helping either.
Basically, it boils down to the observation that Amber doesn't fit the
step-wise approach for configure/build/install that EasyBuild uses...
Here's what I would do: leave both the configure_step and install_step
empty in the easyblock for Amber, and run the whole procedure in the
build_step (or, alternatively, in the install_step, and leave the
build_step empty). Since only the configure options and the test command
are different, you can probably implement this as a simple for-loop.
For example (totally untested, but it should give you an idea):
### START of untested build_step implementation for Amber
# define $AMBERHOME and move to right subdirectory for build
amber_dir = os.path.join(self.installdir, 'amber%s' % self.version)
env.setvar('AMBERHOME', amber_dir)
try:
os.chdir(amber_dir)
except OSError, err:
self.log.error("Failed to change to %s: %s" % (amber_dir, err))
# make sure $LIBS is unset, since it may break the build
if 'LIBS' in os.environ:
del os.environ['LIBS']
# set required environment variables
# note: what if another BLAS/LAPACK lib is used?
imkl_root = get_software_root('imkl')
if imkl_root:
env.setvar('MKL_HOME', imkl_root)
# note: not sure if this would also work with MPI libs other than impi?
for mpilib in ['impi', 'OpenMPI', 'MVAPICH2', 'MPICH2']:
mpi_root = get_software_root(mpilib)
if mpi_root:
env.setvar('MPI_HOME', mpi_root)
# list of common configure options, including dependency-specific options
common_configopts = ["--no-updates"]
netcdf_root = get_software_root('netCDF')
if netcdf_root:
common_configopts.append("--with-netcdf %s" % netcdf_root)
python_root = get_software_root('Python')
if python_root:
common_configopts.append("--with-python %s" %
os.path.join(python_root, 'bin', 'python'))
# hardcoded for Intel compilers, what if another compiler is used?
# use self.toolchain.comp_family(), compare with toolchain.INTELCOMP,
toolchain.GCC, etc?
config_target = "intel"
# list of make targets + corresponding test target
targets = [('', 'test')]
if self.toolchain.options.get('usempi', None):
targets.append(('-mpi', 'test.parallel'))
cuda_root = get_software_root('CUDA')
if cuda_root:
env.setvar('CUDA_HOME', cuda_root)
targets.append(('-cuda', 'test.cuda'))
# configure/build/test/clean for each target
for target_configopt, target_test in targets:
# configure
self.cfg['configopts'] = ' '.join(common_configopts +
[target_configopt, config_target])
super(EB_Amber, self).configure_step()
# build (in-situ) using 'make install'
super(EB_Amber, self).install_step()
# make test
self.cfg['runtest'] = target_test
super(EB_Amber, self).test_step()
# make clean
self.cfg['buildopts'] = 'clean'
super(EB_Amber, self).build_step()
### END of untested build_step implementation for Amber
Other remarks:
* Name the easyblock class 'EB_Amber' rather than 'Amber', that way EB
will auto-determine it should use that based on the software name.
* I'm not sure what you're trying to achieve with the
self.already_extracted check in extract_step? This seemsto mean the 2nd
source file will not be unpacked, is that what you're aiming for?
* The patchlevels should be part of the versionsuffix somehow, to
distinguish between Amber builds with different patch levels?
* What's the problem with the currently commented out code in
make_module_extra?
Don't hesitate to ask further questions. Maybe it's worthwhile to set up
a conf call to discuss this further at some point (if the time of the
day is decent on both ends ;-)), let me know.
regards,
Kenneth