-
Notifications
You must be signed in to change notification settings - Fork 0
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
cleanup in Mesa easyblock + add custom sanity check step #17
Changes from all commits
54826ec
99d9f80
1904d14
bc18448
3986f0f
61f5389
4255b23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,17 +26,46 @@ | |
EasyBuild support for installing Mesa, implemented as an easyblock | ||
|
||
@author: Andrew Edmondson (University of Birmingham) | ||
@author: Kenneth Hoste (HPC-UGent) | ||
""" | ||
import os | ||
from distutils.version import LooseVersion | ||
|
||
from easybuild.easyblocks.generic.mesonninja import MesonNinja | ||
from easybuild.tools.systemtools import POWER, X86_64, get_cpu_architecture, get_cpu_features | ||
from easybuild.tools.filetools import copy_dir | ||
from easybuild.tools.systemtools import POWER, X86_64, get_cpu_architecture, get_cpu_features, get_shared_lib_ext | ||
|
||
|
||
class EB_Mesa(MesonNinja): | ||
def configure_step(self, cmd_prefix=''): | ||
"""Custom easyblock for building and installing Mesa.""" | ||
|
||
def __init__(self, *args, **kwargs): | ||
"""Constructor for custom Mesa easyblock: figure out which vales to pass to swr-arches configuration option.""" | ||
|
||
super(EB_Mesa, self).__init__(*args, **kwargs) | ||
|
||
self.swr_arches = [] | ||
|
||
if 'swr-arches' not in self.cfg['configopts']: | ||
# set cpu features of SWR for current architecture (only on x86_64) | ||
if get_cpu_architecture() == X86_64: | ||
feat_to_swrarch = { | ||
'avx': 'avx', | ||
'avx1.0': 'avx', # on macOS, AVX is indicated with 'avx1.0' rather than 'avx' | ||
'avx2': 'avx2', | ||
'avx512f': 'skx', # AVX-512 Foundation - introduced in Skylake | ||
'avx512er': 'knl', # AVX-512 Exponential and Reciprocal Instructions implemented in Knights Landing | ||
} | ||
# determine list of values to pass to swr-arches configuration option | ||
cpu_features = get_cpu_features() | ||
self.swr_arches = sorted([swrarch for feat, swrarch in feat_to_swrarch.items() if feat in cpu_features]) | ||
|
||
def configure_step(self): | ||
""" | ||
Customise the configopts based on the platform | ||
Customise the configure options based on the processor architecture of the host | ||
(x86_64 or not, CPU features, ...) | ||
""" | ||
|
||
arch = get_cpu_architecture() | ||
if 'gallium-drivers' not in self.cfg['configopts']: | ||
# Install appropriate Gallium drivers for current architecture | ||
|
@@ -45,16 +74,49 @@ def configure_step(self, cmd_prefix=''): | |
elif arch == POWER: | ||
self.cfg.update('configopts', "-Dgallium-drivers='swrast'") | ||
|
||
if 'swr-arches' not in self.cfg['configopts']: | ||
# Set cpu features of SWR for current architecture | ||
cpu_features = set(get_cpu_features()) | ||
swr_arches = [] | ||
if arch == X86_64: | ||
# avx512f: AVX-512 Foundation - introduced in Skylake | ||
# avx512er: AVX-512 Exponential and Reciprocal Instructions implemented in Knights Landing | ||
x86_features = {'avx': 'avx', 'avx1.0': 'avx', 'avx2': 'avx2', 'avx512f': 'skx', 'avx512er': 'knl'} | ||
swr_arches = [farch for fname, farch in x86_features.items() if fname in cpu_features] | ||
if swr_arches: | ||
self.cfg.update('configopts', "-Dswr-arches=%s" % ','.join(swr_arches)) | ||
|
||
return super(EB_Mesa, self).configure_step(cmd_prefix=cmd_prefix) | ||
if self.swr_arches: | ||
self.cfg.update('configopts', '-Dswr-arches=' + ','.join(self.swr_arches)) | ||
|
||
return super(EB_Mesa, self).configure_step() | ||
|
||
def install_step(self): | ||
"""Also copy additional header files after installing Mesa.""" | ||
|
||
super(EB_Mesa, self).install_step() | ||
|
||
# also install header files located in include/GL/internal, unless they're available already; | ||
# we can't enable both DRI and Gallium drivers, | ||
# but we can provide the DRI header file (GL/internal/dri_interface.h) | ||
target_inc_GL_internal = os.path.join(self.installdir, 'include', 'GL', 'internal') | ||
if not os.path.exists(target_inc_GL_internal): | ||
src_inc_GL_internal = os.path.join(self.start_dir, 'include', 'GL', 'internal') | ||
copy_dir(src_inc_GL_internal, target_inc_GL_internal) | ||
self.log.info("Copied %s to %s" % (src_inc_GL_internal, target_inc_GL_internal)) | ||
|
||
def sanity_check_step(self): | ||
"""Custom sanity check for Mesa.""" | ||
|
||
shlib_ext = get_shared_lib_ext() | ||
|
||
if LooseVersion(self.version) >= LooseVersion('20.0'): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just thinking: If this changes so considerably between versions, wouldn't this be better done in the EC? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Time will tell. Going forward we can always easily overrule the easyblock by including There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah they take precedence. Didn't know that, than 👍 |
||
header_files = [os.path.join('include', 'EGL', x) for x in ['eglmesaext.h', 'eglextchromium.h']] | ||
header_files.extend([ | ||
os.path.join('include', 'GL', 'osmesa.h'), | ||
os.path.join('include', 'GL', 'internal', 'dri_interface.h'), | ||
]) | ||
else: | ||
gl_inc_files = ['glext.h', 'gl_mangle.h', 'glx.h', 'osmesa.h', 'gl.h', 'glxext.h', 'glx_mangle.h'] | ||
gles_inc_files = [('GLES', 'gl.h'), ('GLES2', 'gl2.h'), ('GLES3', 'gl3.h')] | ||
header_files = [os.path.join('include', 'GL', x) for x in gl_inc_files] | ||
header_files.extend([os.path.join('include', x, y) for (x, y) in gles_inc_files]) | ||
|
||
custom_paths = { | ||
'files': [os.path.join('lib', 'libOSMesa.%s' % shlib_ext)] + header_files, | ||
'dirs': [os.path.join('include', 'GL', 'internal')], | ||
} | ||
|
||
if self.swr_arches: | ||
swr_arch_libs = [os.path.join('lib', 'libswr%s.%s' % (a.upper(), shlib_ext)) for a in self.swr_arches] | ||
custom_paths['files'].extend(swr_arch_libs) | ||
|
||
super(EB_Mesa, self).sanity_check_step(custom_paths=custom_paths) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this coming from? internal header doesn't sound like something a user would need. Also why is it not installed if it is meant to?
The description sounds like it belongs to a library not installed. Wouldn't that be bad if the header exist but the library does not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see easybuilders/easybuild-easyconfigs#9129
It seems like this is no longer needed for the most recent
Mesa
versions (hence theos.path.exists
check)