Skip to content
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

add custom easyblock for AOMP (AMD OpenMP compiler) #2435

Merged
merged 7 commits into from
Jun 8, 2021
Merged
Changes from all commits
Commits
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
132 changes: 132 additions & 0 deletions easybuild/easyblocks/a/aomp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Support for building and installing AOMP - AMD OpenMP compiler, implemented as
an EasyBlock

@author: Jorgen Nordmoen (University Center for Information Technology - UiO)
"""

from easybuild.easyblocks.generic.binary import Binary
from easybuild.framework.easyconfig import CUSTOM
from easybuild.tools.build_log import EasyBuildError, print_warning
from easybuild.tools.config import build_option
from easybuild.tools.modules import get_software_root
import os
import os.path

AOMP_ALL_COMPONENTS = ['roct', 'rocr', 'project', 'libdevice', 'openmp',
'extras', 'pgmath', 'flang', 'flang_runtime', 'comgr',
'rocminfo', 'vdi', 'hipvdi', 'ocl', 'rocdbgapi',
'rocgdb', 'roctracer', 'rocprofiler']
AOMP_DEFAULT_COMPONENTS = ['roct', 'rocr', 'project', 'libdevice', 'openmp',
'extras', 'pgmath', 'flang', 'flang_runtime',
'comgr', 'rocminfo']
AOMP_X86_COMPONENTS = ['vdi', 'hipvdi', 'ocl']
AOMP_DBG_COMPONENTS = ['rocdbgapi', 'rocgdb']
AOMP_PROF_COMPONENTS = ['roctracer', 'rocprofiler']


class EB_AOMP(Binary):
"""Support for installing AOMP"""

@staticmethod
def extra_options():
extra_vars = Binary.extra_options()
extra_vars.update({
'components': [None, "AOMP components to build. Possible components: " +
', '.join(AOMP_ALL_COMPONENTS), CUSTOM],
})
return extra_vars

def __init__(self, *args, **kwargs):
"""Initialize custom class variables for Clang."""
super(EB_AOMP, self).__init__(*args, **kwargs)
self.cfg['extract_sources'] = True
self.cfg['dontcreateinstalldir'] = True

def configure_step(self):
"""Configure AOMP build and let 'Binary' install"""
# Setup install command
self.cfg['install_cmd'] = './aomp/bin/build_aomp.sh'
# Setup 'preinstallopts'
version_major = self.version.split('.')[0]
install_options = [
'AOMP={!s}'.format(self.installdir),
'AOMP_REPOS="{!s}/aomp{!s}"'.format(self.builddir, version_major),
'AOMP_CMAKE={!s}/bin/cmake'.format(get_software_root('CMake')),
'AOMP_CHECK_GIT_BRANCH=0',
'AOMP_APPLY_ROCM_PATCHES=0',
'AOMP_STANDALONE_BUILD=1',
]
if self.cfg['parallel']:
install_options.append(
'NUM_THREADS={!s}'.format(self.cfg['parallel']))
else:
install_options.append('NUM_THREADS=1')
# Check if CUDA is loaded and alternatively build CUDA backend
if get_software_root('CUDA') or get_software_root('CUDAcore'):
cuda_root = get_software_root('CUDA') or get_software_root('CUDAcore')
install_options.append('AOMP_BUILD_CUDA=1')
install_options.append('CUDA="{!s}"'.format(cuda_root))
# list of CUDA compute capabilities to use can be specifed in two ways (where (2) overrules (1)):
# (1) in the easyconfig file, via the custom cuda_compute_capabilities;
# (2) in the EasyBuild configuration, via --cuda-compute-capabilities configuration option;
ec_cuda_cc = self.cfg['cuda_compute_capabilities']
cfg_cuda_cc = build_option('cuda_compute_capabilities')
cuda_cc = cfg_cuda_cc or ec_cuda_cc or []
if cfg_cuda_cc and ec_cuda_cc:
warning_msg = "cuda_compute_capabilities specified in easyconfig (%s) are overruled by " % ec_cuda_cc
warning_msg += "--cuda-compute-capabilities configuration option (%s)" % cfg_cuda_cc
print_warning(warning_msg)
if not cuda_cc:
raise EasyBuildError("CUDA module was loaded, "
"indicating a build with CUDA, "
"but no CUDA compute capability "
"was specified!")
# Convert '7.0' to '70' format
cuda_cc = [cc.replace('.', '') for cc in cuda_cc]
cuda_str = ",".join(cuda_cc)
install_options.append('NVPTXGPUS="{!s}"'.format(cuda_str))
else:
# Explicitly disable CUDA
install_options.append('AOMP_BUILD_CUDA=0')
# Combine install instructions above into 'preinstallopts'
self.cfg['preinstallopts'] = ' '.join(install_options)
# Setup components for install
components = self.cfg.get('components', None)
# If no components were defined we use the default
if not components:
components = AOMP_DEFAULT_COMPONENTS
# NOTE: The following has not been tested properly and is therefore
# removed
#
# Add X86 components if correct architecture
# if get_cpu_architecture() == X86_64:
# components.extend(AOMP_X86_COMPONENTS)
# Only build selected components
self.cfg['installopts'] = 'select ' + ' '.join(components)

def post_install_step(self):
super(EB_AOMP, self).post_install_step()
# The install script will create a symbolic link as the install
# directory, this creates problems for EB as it won't remove the
# symlink. To remedy this we remove the link here and rename the actual
# install directory created by the AOMP install script
if os.path.islink(self.installdir):
os.unlink(self.installdir)
else:
err_str = "Expected '{!s}' to be a symbolic link" \
" that needed to be removed, but it wasn't!"
raise EasyBuildError(err_str.format(self.installdir))
# Move the actual directory containing the install
install_name = '{!s}_{!s}'.format(os.path.basename(self.installdir),
self.version)
actual_install = os.path.join(os.path.dirname(self.installdir),
install_name)
if os.path.exists(actual_install) and os.path.isdir(actual_install):
os.rename(actual_install, self.installdir)
else:
err_str = "Tried to move '{!s}' to '{!s}', " \
" but it either doesn't exist" \
" or isn't a directory!"
raise EasyBuildError(err_str.format(actual_install,
self.installdir))