Beispiel #1
0
    def sanity_check_step(self):
        """Custom sanity check for Boost."""
        shlib_ext = get_shared_lib_ext()

        custom_paths = {'files': [], 'dirs': ['include/boost']}
        if self.cfg['tagged_layout']:
            lib_mt_suffix = '-mt'
            # Architecture tags introduced in 1.69.0
            if LooseVersion(self.version) >= LooseVersion("1.69.0"):
                if get_cpu_architecture() == AARCH64:
                    lib_mt_suffix += '-a64'
                elif get_cpu_architecture() == POWER:
                    lib_mt_suffix += '-p64'
                else:
                    lib_mt_suffix += '-x64'

        if self.cfg['only_python_bindings']:
            for pyver in self.pyvers:
                pymajorver, pyminorver = pyver.split('.')[:2]
                if LooseVersion(self.version) >= LooseVersion("1.67.0"):
                    suffix = '%s%s' % (pymajorver, pyminorver)
                elif int(pymajorver) >= 3:
                    suffix = pymajorver
                else:
                    suffix = ''
                custom_paths['files'].append(
                    os.path.join('lib',
                                 'libboost_python%s.%s' % (suffix, shlib_ext)))
                if self.cfg['tagged_layout']:
                    custom_paths['files'].append(
                        os.path.join(
                            'lib', 'libboost_python%s%s.%s' %
                            (suffix, lib_mt_suffix, shlib_ext)))

        else:
            custom_paths['files'].append(
                os.path.join('lib', 'libboost_system.%s' % shlib_ext))

            if self.cfg['tagged_layout']:
                custom_paths['files'].append(
                    os.path.join(
                        'lib',
                        'libboost_system%s.%s' % (lib_mt_suffix, shlib_ext)))
                custom_paths['files'].append(
                    os.path.join(
                        'lib',
                        'libboost_thread%s.%s' % (lib_mt_suffix, shlib_ext)))

            if self.cfg['boost_mpi']:
                custom_paths['files'].append(
                    os.path.join('lib', 'libboost_mpi.%s' % shlib_ext))
                if self.cfg['tagged_layout']:
                    custom_paths['files'].append(
                        os.path.join(
                            'lib',
                            'libboost_mpi%s.%s' % (lib_mt_suffix, shlib_ext)))

        super(EB_Boost, self).sanity_check_step(custom_paths=custom_paths)
Beispiel #2
0
    def __init__(self, *args, **kwargs):
        """Constructor for custom Mesa easyblock: figure out which values to pass to swr-arches configuration option."""

        super(EB_Mesa, self).__init__(*args, **kwargs)

        self.gallium_configopts = []

        # Mesa fails to build with libunwind on aarch64
        # See https://github.com/easybuilders/easybuild-easyblocks/issues/2150
        if get_cpu_architecture() == AARCH64:
            given_config_opts = self.cfg.get('configopts')
            if "-Dlibunwind=true" in given_config_opts:
                self.log.warning('libunwind not supported on aarch64, stripping from configopts!')
                configopts_libunwind_stripped = given_config_opts.replace('-Dlibunwind=true', '-Dlibunwind=false')
                self.cfg.set_keys({'configopts': configopts_libunwind_stripped})
                self.log.warning('New configopts after stripping: ' + self.cfg.get('configopts'))

        # Check user-defined Gallium drivers
        gallium_drivers = self.get_configopt_value('gallium-drivers')

        if not gallium_drivers:
            # Add appropriate Gallium drivers for current architecture
            arch = get_cpu_architecture()
            arch_gallium_drivers = {
                X86_64: ['swrast', 'swr'],
                POWER: ['swrast'],
                AARCH64: ['swrast'],
            }
            if arch in arch_gallium_drivers:
                gallium_drivers = arch_gallium_drivers[arch]
                # Add configopt for additional Gallium drivers
                self.gallium_configopts.append('-Dgallium-drivers=' + ','.join(gallium_drivers))

        self.log.debug('Gallium driver(s) included in the installation: %s' % ', '.join(gallium_drivers))

        self.swr_arches = []

        if 'swr' in gallium_drivers:
            # Check user-defined SWR arches
            self.swr_arches = self.get_configopt_value('swr-arches')

            if not self.swr_arches:
                # Set cpu features of SWR for current micro-architecture
                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])
                # Add configopt for additional SWR arches
                self.gallium_configopts.append('-Dswr-arches=' + ','.join(self.swr_arches))

            self.log.debug('SWR Gallium driver will support: %s' % ', '.join(self.swr_arches))
Beispiel #3
0
    def sanity_check_step(self):
        """Custom sanity check for Boost."""
        shlib_ext = get_shared_lib_ext()

        custom_paths = {'files': [], 'dirs': ['include/boost']}
        if not self.cfg['only_python_bindings']:
            custom_paths['files'].append(
                os.path.join('lib', 'libboost_system.%s' % shlib_ext))

        if self.cfg['boost_mpi']:
            custom_paths['files'].append(
                os.path.join('lib', 'libboost_mpi.%s' % shlib_ext))

        for pyver in self.pyvers:
            pymajorver = pyver.split('.')[0]
            pyminorver = pyver.split('.')[1]
            if LooseVersion(self.version) >= LooseVersion("1.67.0"):
                suffix = '%s%s' % (pymajorver, pyminorver)
            elif int(pymajorver) >= 3:
                suffix = pymajorver
            else:
                suffix = ''
            custom_paths['files'].append(
                os.path.join('lib',
                             'libboost_python%s.%s' % (suffix, shlib_ext)))

        lib_mt_suffix = '-mt'
        # MT libraries gained an extra suffix from v1.69.0 onwards
        if LooseVersion(self.version) >= LooseVersion("1.69.0"):
            if get_cpu_architecture() == AARCH64:
                lib_mt_suffix += '-a64'
            elif get_cpu_architecture() == POWER:
                lib_mt_suffix += '-p64'
            else:
                lib_mt_suffix += '-x64'

        if self.cfg['boost_multi_thread']:
            custom_paths['files'].append(
                os.path.join(
                    'lib',
                    'libboost_thread%s.%s' % (lib_mt_suffix, shlib_ext)))

        if self.cfg['boost_mpi'] and self.cfg['boost_multi_thread']:
            custom_paths['files'].append(
                os.path.join('lib',
                             'libboost_mpi%s.%s' % (lib_mt_suffix, shlib_ext)))

        super(EB_Boost, self).sanity_check_step(custom_paths=custom_paths)
Beispiel #4
0
    def prepare_step(self, *args, **kwargs):
        """Prepare environment for installing OpenCV."""
        super(EB_OpenCV, self).prepare_step(*args, **kwargs)

        self.pylibdir = det_pylibdir()

        if get_cpu_architecture() == X86_64:
            # IPP are Intel's Integrated Performance Primitives - so only make sense on X86_64
            ippicv_tgz = glob.glob(os.path.join(self.builddir, 'ippicv*.tgz'))
            if ippicv_tgz:
                if len(ippicv_tgz) == 1:
                    # copy ippicv tarball in the right place
                    # expected location is 3rdparty/ippicv/downloads/linux-<md5sum>/
                    ippicv_tgz = ippicv_tgz[0]
                    ippicv_tgz_md5 = compute_checksum(ippicv_tgz,
                                                      checksum_type='md5')
                    target_subdir = os.path.join('3rdparty', 'ippicv',
                                                 'downloads',
                                                 'linux-%s' % ippicv_tgz_md5)
                    copy([ippicv_tgz],
                         os.path.join(self.cfg['start_dir'], target_subdir))

                    self.cfg.update('configopts', '-DWITH_IPP=ON')

                    # for recent OpenCV 3.x versions (and newer), we must also specify the download location
                    # to prevent that the ippicv tarball is re-downloaded
                    if LooseVersion(self.version) >= LooseVersion('3.4.4'):
                        self.cfg.update(
                            'configopts',
                            '-DOPENCV_DOWNLOAD_PATH=%s' % self.builddir)
                else:
                    raise EasyBuildError(
                        "Found multiple ippicv*.tgz source tarballs in %s: %s",
                        self.builddir, ippicv_tgz)
    def __init__(self, *args, **kwargs):
        """Initialisation of custom class variables for tbb"""
        super(EB_tbb, self).__init__(*args, **kwargs)

        platform_name = get_platform_name()
        myarch = get_cpu_architecture()
        if platform_name.startswith('x86_64'):
            self.arch = "intel64"
        elif platform_name.startswith('i386') or platform_name.startswith(
                'i686'):
            self.arch = 'ia32'
        elif myarch == POWER:
            self.arch = 'ppc64'
        else:
            raise EasyBuildError(
                "Failed to determine system architecture based on %s",
                platform_name)

        if not self.toolchain.is_system_toolchain():
            # open-source TBB version
            self.build_in_installdir = True
            self.cfg['requires_runtime_license'] = False

        if self.toolchain.is_system_toolchain():
            self.tbb_subdir = 'tbb'
        else:
            self.tbb_subdir = ''
    def __init__(self, *args, **kwargs):
        """ Init the cuDNN easyblock adding a new cudnnarch template var """

        # Need to call super's init first, so we can use self.version
        super(EB_cuDNN, self).__init__(*args, **kwargs)

        # Generate cudnnarch template value for this system
        cudnnarch = False
        myarch = get_cpu_architecture()

        if LooseVersion(self.version) < LooseVersion('8.3.3'):
            if myarch == AARCH64:
                cudnnarch = 'aarch64sbsa'
            elif myarch == POWER:
                cudnnarch = 'ppc64le'
            elif myarch == X86_64:
                cudnnarch = 'x64'
        else:
            if myarch == AARCH64:
                cudnnarch = 'sbsa'
            elif myarch == POWER:
                cudnnarch = 'ppc64le'
            elif myarch == X86_64:
                cudnnarch = 'x86_64'

        if not cudnnarch:
            raise EasyBuildError("The cuDNN easyblock does not currently support architecture %s", myarch)
        self.cfg['keepsymlinks'] = True
        self.cfg.template_values['cudnnarch'] = cudnnarch
        self.cfg.generate_template_values()
Beispiel #7
0
    def extra_options():
        # We only want to install mkl-dnn by default on x86_64 systems
        with_mkl_dnn_default = get_cpu_architecture() == X86_64
        extra_vars = {
            # see https://developer.nvidia.com/cuda-gpus
            'cuda_compute_capabilities':
            [[], "List of CUDA compute capabilities to build with", CUSTOM],
            'path_filter':
            [[],
             "List of patterns to be filtered out in paths in $CPATH and $LIBRARY_PATH",
             CUSTOM],
            'with_jemalloc': [
                None,
                "Make TensorFlow use jemalloc (usually enabled by default)",
                CUSTOM
            ],
            'with_mkl_dnn': [
                with_mkl_dnn_default, "Make TensorFlow use Intel MKL-DNN",
                CUSTOM
            ],
            'test_script':
            [None, "Script to test TensorFlow installation with", CUSTOM],
        }

        return PythonPackage.extra_options(extra_vars)
    def det_psubdir(self):
        """Determine the platform-specific installation directory for OpenFOAM."""
        # OpenFOAM >= 3.0.0 can use 64 bit integers
        # same goes for OpenFOAM-Extend >= 4.1
        if 'extend' in self.name.lower():
            set_int_size = self.looseversion >= LooseVersion('4.1')
        else:
            set_int_size = self.looseversion >= LooseVersion('3.0')

        if set_int_size:
            if self.toolchain.options['i8']:
                int_size = 'Int64'
            else:
                int_size = 'Int32'
        else:
            int_size = ''

        archpart = '64'
        arch = get_cpu_architecture()
        if arch == AARCH64:
            # Variants have different abbreviations for ARM64...
            if self.looseversion < LooseVersion("100"):
                archpart = 'Arm64'
            else:
                archpart = 'ARM64'
        elif arch == POWER:
            archpart = 'PPC64le'

        psubdir = "linux%s%sDP%s%s" % (archpart, self.wm_compiler, int_size, self.build_type)
        return psubdir
    def __init__(self, *args, **kwargs):
        """Initialize custom class variables for Clang."""

        super(EB_Clang, self).__init__(*args, **kwargs)
        self.llvm_src_dir = None
        self.llvm_obj_dir_stage1 = None
        self.llvm_obj_dir_stage2 = None
        self.llvm_obj_dir_stage3 = None
        self.make_parallel_opts = ""

        build_targets = self.cfg['build_targets']
        if build_targets is None:
            arch = get_cpu_architecture()
            default_targets = DEFAULT_TARGETS_MAP.get(arch, None)
            if default_targets:
                self.cfg['build_targets'] = build_targets = default_targets
                self.log.debug("Using %s as default build targets for CPU architecture %s.", default_targets, arch)
            else:
                raise EasyBuildError("No default build targets defined for CPU architecture %s.", arch)

        unknown_targets = [target for target in build_targets if target not in CLANG_TARGETS]

        if unknown_targets:
            raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.",
                                 ', '.join(unknown_targets), ', '.join(CLANG_TARGETS))

        if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in build_targets:
            raise EasyBuildError("Build target R600 not supported in < Clang-3.4")

        if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in build_targets:
            raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3")
Beispiel #10
0
    def configure_step(self):
        """ set up some options - but no configure command to run"""

        default_opts = {
            'BINARY': '64',
            'CC': os.getenv('CC'),
            'FC': os.getenv('FC'),
            'USE_OPENMP': '1',
            'USE_THREAD': '1',
        }

        if '%s=' % TARGET in self.cfg['buildopts']:
            # Add any TARGET in buildopts to default_opts, so it is passed to testopts and installopts
            for buildopt in self.cfg['buildopts'].split():
                optpair = buildopt.split('=')
                if optpair[0] == TARGET:
                    default_opts[optpair[0]] = optpair[1]
        elif LooseVersion(self.version) < LooseVersion(
                '0.3.6') and get_cpu_architecture() == POWER:
            # There doesn't seem to be a POWER9 option yet, but POWER8 should work.
            print_warning(
                "OpenBLAS 0.3.5 and lower have known issues on POWER systems")
            default_opts[TARGET] = 'POWER8'

        for key in sorted(default_opts.keys()):
            for opts_key in ['buildopts', 'testopts', 'installopts']:
                if '%s=' % key not in self.cfg[opts_key]:
                    self.cfg.update(opts_key,
                                    "%s='%s'" % (key, default_opts[key]))

        self.cfg.update('installopts', 'PREFIX=%s' % self.installdir)
Beispiel #11
0
    def prepare_step(self, *args, **kwargs):
        """Prepare build environment."""
        super(EB_Clang, self).prepare_step(*args, **kwargs)

        build_targets = self.cfg['build_targets']
        if build_targets is None:
            arch = get_cpu_architecture()
            try:
                default_targets = DEFAULT_TARGETS_MAP[arch][:]
                # If CUDA is included as a dep, add NVPTX as a target (could also support AMDGPU if we knew how)
                if get_software_root("CUDA"):
                    default_targets += ["NVPTX"]
                self.cfg['build_targets'] = build_targets = default_targets
                self.log.debug("Using %s as default build targets for CPU/GPU architecture %s.", default_targets, arch)
            except KeyError:
                raise EasyBuildError("No default build targets defined for CPU architecture %s.", arch)

        # carry on with empty list from this point forward if no build targets are specified
        if build_targets is None:
            self.cfg['build_targets'] = build_targets = []

        unknown_targets = [target for target in build_targets if target not in CLANG_TARGETS]

        if unknown_targets:
            raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.",
                                 ', '.join(unknown_targets), ', '.join(CLANG_TARGETS))

        if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in build_targets:
            raise EasyBuildError("Build target R600 not supported in < Clang-3.4")

        if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in build_targets:
            raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3")
Beispiel #12
0
    def sanity_check_step(self):
        """Custom sanity check for Qt."""

        shlib_ext = get_shared_lib_ext()

        if LooseVersion(self.version) >= LooseVersion('4'):
            libversion = ''
            if LooseVersion(self.version) >= LooseVersion('5'):
                libversion = self.version.split('.')[0]

            libfile = os.path.join('lib', 'libQt%sCore.%s' % (libversion, shlib_ext))

        else:
            libfile = os.path.join('lib', 'libqt.%s' % shlib_ext)

        custom_paths = {
            'files': ['bin/moc', 'bin/qmake', libfile],
            'dirs': ['include', 'plugins'],
        }

        if self.cfg['check_qtwebengine']:
            glibc_version = get_glibc_version()
            myarch = get_cpu_architecture()
            if LooseVersion(glibc_version) <= LooseVersion("2.16"):
                self.log.debug("Skipping check for qtwebengine, since it requires a more recent glibc.")
            elif myarch == POWER:
                self.log.debug("Skipping check for qtwebengine, since it is not supported on POWER.")
            else:
                qtwebengine_libs = ['libQt%s%s.%s' % (libversion, x, shlib_ext) for x in ['WebEngine', 'WebEngineCore']]
                custom_paths['files'].extend([os.path.join('lib', lib) for lib in qtwebengine_libs])

        if LooseVersion(self.version) >= LooseVersion('4'):
            custom_paths['files'].append('bin/xmlpatterns')

        super(EB_Qt, self).sanity_check_step(custom_paths=custom_paths)
Beispiel #13
0
 def __init__(self, *args, **kwargs):
     """Compiler constructor."""
     Toolchain.base_init(self)
     self.arch = systemtools.get_cpu_architecture()
     self.cpu_family = systemtools.get_cpu_family()
     # list of compiler prefixes
     self.prefixes = []
     super(Compiler, self).__init__(*args, **kwargs)
Beispiel #14
0
    def get_gromacs_arch(self):
        """Determine value of GMX_SIMD CMake flag based on optarch string.

        Refs:
        [0] http://manual.gromacs.org/documentation/2016.3/install-guide/index.html#typical-installation
        [1] http://manual.gromacs.org/documentation/2016.3/install-guide/index.html#simd-support
        [2] http://www.gromacs.org/Documentation/Acceleration_and_parallelization
        """
        # default: fall back on autodetection
        res = None

        optarch = build_option('optarch') or ''
        # take into account that optarch value is a dictionary if it is specified by compiler family
        if isinstance(optarch, dict):
            comp_fam = self.toolchain.comp_family()
            optarch = optarch.get(comp_fam, '')
        optarch = optarch.upper()

        # The list of GMX_SIMD options can be found
        # http://manual.gromacs.org/documentation/2018/install-guide/index.html#simd-support
        if 'MIC-AVX512' in optarch and LooseVersion(
                self.version) >= LooseVersion('2016'):
            res = 'AVX_512_KNL'
        elif 'AVX512' in optarch and LooseVersion(
                self.version) >= LooseVersion('2016'):
            res = 'AVX_512'
        elif 'AVX2' in optarch and LooseVersion(
                self.version) >= LooseVersion('5.0'):
            res = 'AVX2_256'
        elif 'AVX' in optarch:
            res = 'AVX_256'
        elif 'SSE3' in optarch or 'SSE2' in optarch or 'MARCH=NOCONA' in optarch:
            # Gromacs doesn't have any GMX_SIMD=SSE3 but only SSE2 and SSE4.1 [1].
            # According to [2] the performance difference between SSE2 and SSE4.1 is minor on x86
            # and SSE4.1 is not supported by AMD Magny-Cours[1].
            res = 'SSE2'
        elif optarch == OPTARCH_GENERIC:
            cpu_arch = get_cpu_architecture()
            if cpu_arch == X86_64:
                res = 'SSE2'
            else:
                res = 'None'
        elif optarch:
            warn_msg = "--optarch configuration setting set to %s but not taken into account; " % optarch
            warn_msg += "compiling GROMACS for the current host architecture (i.e. the default behavior)"
            self.log.warning(warn_msg)
            print_warning(warn_msg)

        if res:
            self.log.info(
                "Target architecture based on optarch configuration option ('%s'): %s",
                optarch, res)
        else:
            self.log.info(
                "No target architecture specified based on optarch configuration option ('%s')",
                optarch)

        return res
Beispiel #15
0
    def __init__(self, *args, **kwargs):
        """Initialisation of custom class variables for FFTW."""
        super(EB_FFTW, self).__init__(*args, **kwargs)

        # do not enable MPI if the toolchain does not support it
        if not self.toolchain.mpi_family():
            self.log.info("Disabling MPI support because the toolchain used does not support it.")
            self.cfg['with_mpi'] = False

        for flag in FFTW_CPU_FEATURE_FLAGS:
            # fail-safe: make sure we're not overwriting an existing attribute (could lead to weird bugs if we do)
            if hasattr(self, flag):
                raise EasyBuildError("EasyBlock attribute '%s' already exists")
            setattr(self, flag, self.cfg['use_%s' % flag])

            # backwards compatibility: use use_fma setting if use_fma4 is not set
            if flag == 'fma4' and self.cfg['use_fma4'] is None and self.cfg['use_fma'] is not None:
                self.log.deprecated("Use 'use_fma4' instead of 'use_fma' easyconfig parameter", '4.0')
                self.fma4 = self.cfg['use_fma']

        # auto-detect CPU features that can be used and are not enabled/disabled explicitly,
        # but only if --optarch=GENERIC is not being used
        cpu_arch = get_cpu_architecture()
        if self.cfg['auto_detect_cpu_features']:

            # if --optarch=GENERIC is used, limit which CPU features we consider for auto-detection
            if build_option('optarch') == OPTARCH_GENERIC:
                if cpu_arch == X86_64:
                    # SSE(2) is supported on all x86_64 architectures
                    cpu_features = ['sse', 'sse2']
                elif cpu_arch == AARCH64:
                    # NEON is supported on all AARCH64 architectures (indicated with 'asimd')
                    cpu_features = ['asimd']
                else:
                    cpu_features = []
            else:
                cpu_features = FFTW_CPU_FEATURE_FLAGS
            self.log.info("CPU features considered for auto-detection: %s", cpu_features)

            # get list of available CPU features, so we can check which ones to retain
            avail_cpu_features = get_cpu_features()

            # on macOS, AVX is indicated with 'avx1.0' rather than 'avx'
            if 'avx1.0' in avail_cpu_features:
                avail_cpu_features.append('avx')

            self.log.info("List of available CPU features: %s", avail_cpu_features)

            for flag in cpu_features:
                # only enable use of a particular CPU feature if it's still undecided (i.e. None)
                if getattr(self, flag) is None and flag in avail_cpu_features:
                    self.log.info("Enabling use of %s (should be supported based on CPU features)", flag.upper())
                    setattr(self, flag, True)

        # Auto-disable quad-precision on ARM and POWER, as it is unsupported
        if self.cfg['with_quad_prec'] and cpu_arch in [AARCH32, AARCH64, POWER]:
            self.cfg['with_quad_prec'] = False
            self.log.debug("Quad-precision automatically disabled; not supported on %s.", cpu_arch)
    def sanity_check_step(self):
        """Custom sanity check for AOMP"""
        shlib_ext = get_shared_lib_ext()
        arch = get_cpu_architecture()
        # Check architecture explicitly since Clang uses potentially
        # different names
        arch_map = {
            X86_64: 'x86_64',
            POWER: 'ppc64',
            AARCH64: 'aarch64',
        }

        if arch in arch_map:
            arch = arch_map[arch]
        else:
            print_warning(
                "Unknown CPU architecture (%s) for OpenMP offloading!" % arch)
        custom_paths = {
            'files': [
                "amdgcn/bitcode/hip.bc",
                "amdgcn/bitcode/opencl.bc",
                "bin/aompcc",
                "bin/aompversion",
                "bin/clang",
                "bin/flang",
                "bin/ld.lld",
                "bin/llvm-config",
                "bin/mygpu",
                "bin/opt",
                "bin/rocminfo",
                "include/amd_comgr.h",
                "include/hsa/amd_hsa_common.h",
                "include/hsa/hsa.h",
                "include/omp.h",
                "include/omp_lib.h",
                "lib/libclang.%s" % shlib_ext,
                "lib/libflang.%s" % shlib_ext,
                "lib/libomp.%s" % shlib_ext,
                "lib/libomptarget.rtl.amdgpu.%s" % shlib_ext,
                "lib/libomptarget.rtl.%s.%s" % (arch, shlib_ext),
                "lib/libomptarget.%s" % shlib_ext,
            ],
            'dirs': ["amdgcn", "include/clang", "include/hsa", "include/llvm"],
        }
        # If we are building with CUDA support we need to check if it was built properly
        if get_software_root('CUDA') or get_software_root('CUDAcore'):
            custom_paths['files'].append("lib/libomptarget.rtl.cuda.%s" %
                                         shlib_ext)
        custom_commands = [
            'aompcc --help',
            'clang --help',
            'clang++ --help',
            'flang --help',
            'llvm-config --cxxflags',
        ]
        super(EB_AOMP, self).sanity_check_step(custom_paths=custom_paths,
                                               custom_commands=custom_commands)
    def test_step(self):
        """Run unit tests"""
        # Make PyTorch tests not use the user home
        env.setvar('XDG_CACHE_HOME', os.path.join(self.tmpdir, '.cache'))
        # Pretend to be on FB CI which disables some tests, especially those which download stuff
        env.setvar('SANDCASTLE', '1')
        # Skip this test(s) which is very flaky
        env.setvar('SKIP_TEST_BOTTLENECK', '1')
        # Parse excluded_tests and flatten into space separated string
        excluded_tests = []
        for arch, tests in self.cfg['excluded_tests'].items():
            if not arch or arch == get_cpu_architecture():
                excluded_tests.extend(tests)
        # -x should not be used if there are no excluded tests
        if excluded_tests:
            excluded_tests = ['-x'] + excluded_tests
        self.cfg.template_values.update({
            'python': self.python_cmd,
            'excluded_tests': ' '.join(excluded_tests)
        })

        (tests_out, tests_ec) = super(EB_PyTorch, self).test_step(return_output_ec=True)

        ran_tests_hits = re.findall(r"^Ran (?P<test_cnt>[0-9]+) tests in", tests_out, re.M)
        test_cnt = 0
        for hit in ran_tests_hits:
            test_cnt += int(hit)

        failed_tests = nub(re.findall(r"^(?P<failed_test_name>.*) failed!\s*$", tests_out, re.M))
        failed_test_cnt = len(failed_tests)

        if failed_test_cnt:
            max_failed_tests = self.cfg['max_failed_tests']

            test_or_tests = 'tests' if failed_test_cnt > 1 else 'test'
            msg = "%d %s (out of %d) failed:\n" % (failed_test_cnt, test_or_tests, test_cnt)
            msg += '\n'.join('* %s' % t for t in sorted(failed_tests))

            if max_failed_tests == 0:
                raise EasyBuildError(msg)
            else:
                msg += '\n\n' + ' '.join([
                    "The PyTorch test suite is known to include some flaky tests,",
                    "which may fail depending on the specifics of the system or the context in which they are run.",
                    "For this PyTorch installation, EasyBuild allows up to %d tests to fail." % max_failed_tests,
                    "We recommend to double check that the failing tests listed above ",
                    "are known to be flaky, or do not affect your intended usage of PyTorch.",
                    "In case of doubt, reach out to the EasyBuild community (via GitHub, Slack, or mailing list).",
                ])
                print_warning(msg)

                if failed_test_cnt > max_failed_tests:
                    raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d",
                                         failed_test_cnt, max_failed_tests)
        elif tests_ec:
            raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec)
Beispiel #18
0
    def __init__(self, *args, **kwargs):
        """Constructor for custom Mesa easyblock: figure out which values to pass to swr-arches configuration option."""

        super(EB_Mesa, self).__init__(*args, **kwargs)

        self.gallium_configopts = []

        # Check user-defined Gallium drivers
        gallium_drivers = self.get_configopt_value('gallium-drivers')

        if not gallium_drivers:
            # Add appropriate Gallium drivers for current architecture
            arch = get_cpu_architecture()
            arch_gallium_drivers = {
                'x86_64': ['swrast', 'swr'],
                'POWER': ['swrast'],
            }
            if arch in arch_gallium_drivers:
                gallium_drivers = arch_gallium_drivers[arch]
                # Add configopt for additional Gallium drivers
                self.gallium_configopts.append('-Dgallium-drivers=' +
                                               ','.join(gallium_drivers))

        self.log.debug('Gallium driver(s) included in the installation: %s' %
                       ', '.join(gallium_drivers))

        self.swr_arches = []

        if 'swr' in gallium_drivers:
            # Check user-defined SWR arches
            self.swr_arches = self.get_configopt_value('swr-arches')

            if not self.swr_arches:
                # Set cpu features of SWR for current micro-architecture
                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
                ])
                # Add configopt for additional SWR arches
                self.gallium_configopts.append('-Dswr-arches=' +
                                               ','.join(self.swr_arches))

            self.log.debug('SWR Gallium driver will support: %s' %
                           ', '.join(self.swr_arches))
    def get_gromacs_arch(self):
        """Determine value of GMX_SIMD CMake flag based on optarch string.

        Refs:
        [0] http://manual.gromacs.org/documentation/2016.3/install-guide/index.html#typical-installation
        [1] http://manual.gromacs.org/documentation/2016.3/install-guide/index.html#simd-support
        [2] http://www.gromacs.org/Documentation/Acceleration_and_parallelization
        """
        # default: fall back on autodetection
        res = None

        optarch = build_option('optarch') or ''
        # take into account that optarch value is a dictionary if it is specified by compiler family
        if isinstance(optarch, dict):
            comp_fam = self.toolchain.comp_family()
            optarch = optarch.get(comp_fam, '')
        optarch = optarch.upper()

        # The list of GMX_SIMD options can be found
        # http://manual.gromacs.org/documentation/2018/install-guide/index.html#simd-support
        if 'MIC-AVX512' in optarch and LooseVersion(self.version) >= LooseVersion('2016'):
            res = 'AVX_512_KNL'
        elif 'AVX512' in optarch and LooseVersion(self.version) >= LooseVersion('2016'):
            res = 'AVX_512'
        elif 'AVX2' in optarch and LooseVersion(self.version) >= LooseVersion('5.0'):
            res = 'AVX2_256'
        elif 'AVX' in optarch:
            res = 'AVX_256'
        elif 'SSE3' in optarch or 'SSE2' in optarch or 'MARCH=NOCONA' in optarch:
            # Gromacs doesn't have any GMX_SIMD=SSE3 but only SSE2 and SSE4.1 [1].
            # According to [2] the performance difference between SSE2 and SSE4.1 is minor on x86
            # and SSE4.1 is not supported by AMD Magny-Cours[1].
            res = 'SSE2'
        elif optarch == OPTARCH_GENERIC:
            cpu_arch = get_cpu_architecture()
            if cpu_arch == X86_64:
                res = 'SSE2'
            else:
                res = 'None'
        elif optarch:
            warn_msg = "--optarch configuration setting set to %s but not taken into account; " % optarch
            warn_msg += "compiling GROMACS for the current host architecture (i.e. the default behavior)"
            self.log.warning(warn_msg)
            print_warning(warn_msg)

        if res:
            self.log.info("Target architecture based on optarch configuration option ('%s'): %s", optarch, res)
        else:
            self.log.info("No target architecture specified based on optarch configuration option ('%s')", optarch)

        return res
Beispiel #20
0
    def sanity_check_step(self):
        """Custom sanity check for libdrm"""
        shlib_ext = get_shared_lib_ext()
        custom_paths = {
            'files': ['include/xf86drm.h', 'include/xf86drmMode.h',
                      'lib/libdrm_radeon.%s' % shlib_ext, 'lib/libdrm.%s' % shlib_ext, 'lib/libkms.%s' % shlib_ext],
            'dirs': ['include/libdrm', 'include/libkms', 'lib/pkgconfig'],
        }

        arch = get_cpu_architecture()
        if arch == X86_64:
            custom_paths['files'].append('lib/libdrm_intel.%s' % shlib_ext)

        super(EB_libdrm, self).sanity_check_step(custom_paths=custom_paths)
Beispiel #21
0
    def sanity_check_step(self):
        """Custom sanity check for Clang."""
        shlib_ext = get_shared_lib_ext()
        custom_paths = {
            'files': [
                "bin/clang", "bin/clang++", "bin/llvm-ar", "bin/llvm-nm", "bin/llvm-as", "bin/opt", "bin/llvm-link",
                "bin/llvm-config", "bin/llvm-symbolizer", "include/llvm-c/Core.h", "include/clang-c/Index.h",
                "lib/libclang.%s" % shlib_ext, "lib/clang/%s/include/stddef.h" % self.version,
            ],
            'dirs': ["include/clang", "include/llvm", "lib/clang/%s/lib" % self.version],
        }
        if self.cfg['static_analyzer']:
            custom_paths['files'].extend(["bin/scan-build", "bin/scan-view"])

        if self.cfg['build_extra_clang_tools'] and LooseVersion(self.version) >= LooseVersion('3.4'):
            custom_paths['files'].extend(["bin/clang-tidy"])

        if self.cfg["usepolly"]:
            custom_paths['files'].extend(["lib/LLVMPolly.%s" % shlib_ext])
            custom_paths['dirs'].extend(["include/polly"])

        if self.cfg["build_lld"]:
            custom_paths['files'].extend(["bin/lld"])

        if self.cfg["libcxx"]:
            custom_paths['files'].extend(["lib/libc++.%s" % shlib_ext])
            custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext])

        if LooseVersion(self.version) >= LooseVersion('3.8'):
            custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version])

        if 'NVPTX' in self.cfg['build_targets']:
            arch = get_cpu_architecture()
            # Check architecture explicitly since Clang uses potentially
            # different names
            if arch == X86_64:
                arch = 'x86_64'
            elif arch == POWER:
                arch = 'ppc64'
            elif arch == AARCH64:
                arch = 'aarch64'
            else:
                print_warning("Unknown CPU architecture (%s) for OpenMP offloading!" % arch)
            custom_paths['files'].extend(["lib/libomptarget.%s" % shlib_ext,
                                          "lib/libomptarget-nvptx.a",
                                          "lib/libomptarget.rtl.cuda.%s" % shlib_ext,
                                          "lib/libomptarget.rtl.%s.%s" % (arch, shlib_ext)])

        custom_commands = ['clang --help', 'clang++ --help', 'llvm-config --cxxflags']
        super(EB_Clang, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)
Beispiel #22
0
    def get_user_depot_path(self):
        user_depot_path = ''

        hostname = socket.gethostname()
        hostname_short = ''.join(c for c in hostname if not c.isdigit())

        optarch = build_option('optarch') or None
        if optarch:
            user_depot_path = os.path.join('~', '.julia', self.version, self.get_environment_folder())
        else:
            arch = systemtools.get_cpu_architecture()
            cpu_family = systemtools.get_cpu_family()
            user_depot_path = os.path.join('~', '.julia', self.version, self.get_environment_folder())
        return user_depot_path
    def __init__(self, *args, **kwargs):
        """ Init the easyblock adding a new mapped_arch template var """
        myarch = get_cpu_architecture()
        if myarch == X86_64:
            self.mapped_arch = 'amd64'
        elif myarch == AARCH64:
            self.mapped_arch = 'arm64'
        else:
            raise EasyBuildError("Architecture %s is not supported for code-server on EasyBuild", myarch)

        super(EB_code_minus_server, self).__init__(*args, **kwargs)

        self.cfg.template_values['mapped_arch'] = self.mapped_arch
        self.cfg.generate_template_values()
    def __init__(self, *args, **kwargs):
        """ Init the Java easyblock adding a new jdkarch template var """
        myarch = get_cpu_architecture()
        if myarch == AARCH64:
            jdkarch = 'aarch64'
        elif myarch == POWER:
            jdkarch = 'ppc64le'
        elif myarch == X86_64:
            jdkarch = 'x64'
        else:
            raise EasyBuildError("Architecture %s is not supported for Java on EasyBuild", myarch)

        super(EB_Java, self).__init__(*args, **kwargs)

        self.cfg.template_values['jdkarch'] = jdkarch
        self.cfg.generate_template_values()
Beispiel #25
0
    def __init__(self, *args, **kwargs):
        """ Init the cuda easyblock adding a new cudaarch template var """
        myarch = get_cpu_architecture()
        if myarch == X86_64:
            cudaarch = ''
        elif myarch == POWER:
            cudaarch = '_ppc64le'
        else:
            raise EasyBuildError(
                "Architecture %s is not supported for CUDA on EasyBuild",
                myarch)

        super(EB_CUDA, self).__init__(*args, **kwargs)

        self.cfg.template_values['cudaarch'] = cudaarch
        self.cfg.generate_template_values()
Beispiel #26
0
    def prepare_step(self, *args, **kwargs):
        """Prepare build environment."""
        super(EB_NAMD, self).prepare_step(*args, **kwargs)

        if self.cfg['namd_basearch'] is None:

            self.log.info("namd_basearch not specified, so determining it based a CPU arch...")

            arch = get_cpu_architecture()
            if arch == X86_64:
                basearch = 'Linux-x86_64'
            elif arch == POWER:
                basearch = 'Linux-POWER'

            self.cfg['namd_basearch'] = basearch
            self.log.info("Derived value for 'namd_basearch': %s", self.cfg['namd_basearch'])
Beispiel #27
0
    def __init__(self, *args, **kwargs):
        """Initialisation of custom class variables for FFTW."""
        super(EB_FFTW, self).__init__(*args, **kwargs)

        for flag in FFTW_CPU_FEATURE_FLAGS:
            # fail-safe: make sure we're not overwriting an existing attribute (could lead to weird bugs if we do)
            if hasattr(self, flag):
                raise EasyBuildError("EasyBlock attribute '%s' already exists")
            setattr(self, flag, self.cfg['use_%s' % flag])

        # auto-detect CPU features that can be used and are not enabled/disabled explicitly,
        # but only if --optarch=GENERIC is not being used
        if self.cfg['auto_detect_cpu_features']:

            # if --optarch=GENERIC is used, limit which CPU features we consider for auto-detection
            if build_option('optarch') == OPTARCH_GENERIC:
                cpu_arch = get_cpu_architecture()
                if cpu_arch == X86_64:
                    # SSE(2) is supported on all x86_64 architectures
                    cpu_features = ['sse', 'sse2']
                elif cpu_arch == AARCH64:
                    # NEON is supported on all AARCH64 architectures (indicated with 'asimd')
                    cpu_features = ['asimd']
                else:
                    cpu_features = []
            else:
                cpu_features = FFTW_CPU_FEATURE_FLAGS
            self.log.info("CPU features considered for auto-detection: %s",
                          cpu_features)

            # get list of available CPU features, so we can check which ones to retain
            avail_cpu_features = get_cpu_features()

            # on macOS, AVX is indicated with 'avx1.0' rather than 'avx'
            if 'avx1.0' in avail_cpu_features:
                avail_cpu_features.append('avx')

            self.log.info("List of available CPU features: %s",
                          avail_cpu_features)

            for flag in cpu_features:
                # only enable use of a particular CPU feature if it's still undecided (i.e. None)
                if getattr(self, flag) is None and flag in avail_cpu_features:
                    self.log.info(
                        "Enabling use of %s (should be supported based on CPU features)",
                        flag.upper())
                    setattr(self, flag, True)
Beispiel #28
0
    def configure_step(self):
        """
        Install extra tools in bin/; enable zlib if it is a dep; optionally enable rtti; and set the build target
        """
        if LooseVersion(self.version) >= LooseVersion('14'):
            self.cfg.update('configopts', '-DLLVM_INCLUDE_BENCHMARKS=OFF')
            if self.build_shared:
                self.cfg.update(
                    'configopts',
                    '-DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON')

        self.cfg.update('configopts', '-DLLVM_INSTALL_UTILS=ON')

        if get_software_root('zlib'):
            self.cfg.update('configopts', '-DLLVM_ENABLE_ZLIB=ON')

        if self.cfg["enable_rtti"]:
            self.cfg.update('configopts', '-DLLVM_ENABLE_RTTI=ON')

        build_targets = self.cfg['build_targets']
        if build_targets is None:
            arch = get_cpu_architecture()
            try:
                default_targets = DEFAULT_TARGETS_MAP[arch][:]
                self.cfg['build_targets'] = build_targets = default_targets
                self.log.debug(
                    "Using %s as default build targets for CPU architecture %s.",
                    default_targets, arch)
            except KeyError:
                raise EasyBuildError(
                    "No default build targets defined for CPU architecture %s.",
                    arch)

        unknown_targets = [
            target for target in build_targets if target not in CLANG_TARGETS
        ]

        if unknown_targets:
            raise EasyBuildError(
                "Some of the chosen build targets (%s) are not in %s.",
                ', '.join(unknown_targets), ', '.join(CLANG_TARGETS))

        self.cfg.update(
            'configopts',
            '-DLLVM_TARGETS_TO_BUILD="%s"' % ';'.join(build_targets))

        super(EB_LLVM, self).configure_step()
Beispiel #29
0
    def test_cpu_architecture(self):
        """Test getting the CPU architecture (mocked)."""
        st.platform.uname = mocked_uname
        global MACHINE_NAME

        machine_names = {
            'aarch64': AARCH64,
            'aarch64_be': AARCH64,
            'armv7l': AARCH32,
            'ppc64': POWER,
            'ppc64le': POWER,
            'x86_64': X86_64,
            'some_fancy_arch': UNKNOWN,
        }
        for name in machine_names:
            MACHINE_NAME = name
            self.assertEqual(get_cpu_architecture(), machine_names[name])
Beispiel #30
0
    def __init__(self, *args, **kwargs):
        """Init and validate easyconfig parameters and system architecture"""
        super(EB_ORCA, self).__init__(*args, **kwargs)

        # If user overwrites 'files_to_copy', custom 'sanity_check_paths' must be present
        if self.cfg['files_to_copy'] and not self.cfg['sanity_check_paths']:
            raise EasyBuildError("Found 'files_to_copy' option in easyconfig without 'sanity_check_paths'")

        # Add orcaarch template for supported architectures
        myarch = get_cpu_architecture()
        if myarch == X86_64:
            orcaarch = 'x86-64'
        else:
            raise EasyBuildError("Architecture %s is not supported by ORCA on EasyBuild", myarch)

        self.cfg.template_values['orcaarch'] = orcaarch
        self.cfg.generate_template_values()
    def test_cpu_architecture(self):
        """Test getting the CPU architecture (mocked)."""
        st.platform.uname = mocked_uname
        global MACHINE_NAME

        machine_names = {
            'aarch64': AARCH64,
            'aarch64_be': AARCH64,
            'armv7l': AARCH32,
            'ppc64': POWER,
            'ppc64le': POWER,
            'x86_64': X86_64,
            'some_fancy_arch': UNKNOWN,
        }
        for name in machine_names:
            MACHINE_NAME = name
            self.assertEqual(get_cpu_architecture(), machine_names[name])
Beispiel #32
0
 def test_step(self):
     """Run unit tests"""
     # Make PyTorch tests not use the user home
     env.setvar('XDG_CACHE_HOME', os.path.join(self.tmpdir, '.cache'))
     # Parse excluded_tests and flatten into space separated string
     excluded_tests = []
     for arch, tests in self.cfg['excluded_tests'].items():
         if not arch or arch == get_cpu_architecture():
             excluded_tests.extend(tests)
     # -x should not be used if there are no excluded tests
     if excluded_tests:
         excluded_tests = ['-x'] + excluded_tests
     self.cfg.template_values.update({
         'python': self.python_cmd,
         'excluded_tests': ' '.join(excluded_tests)
     })
     super(EB_PyTorch, self).test_step()
    def run_all_steps(self, *args, **kwargs):
        """
        Put configure options in place for different precisions (single, double, long double, quad).
        """
        # keep track of configopts specified in easyconfig file, so we can include them in each iteration later
        common_config_opts = self.cfg['configopts']

        self.cfg['configopts'] = []

        for prec in FFTW_PRECISION_FLAGS:
            if self.cfg[EB_FFTW._prec_param(prec)]:

                prec_configopts = []

                # double precison is the default, no configure flag needed (there is no '--enable-double')
                if prec != 'double':
                    prec_configopts.append('--enable-%s' % prec)

                # MPI is not supported for quad precision
                if prec != 'quad-precision' and self.cfg['with_mpi']:
                    prec_configopts.append('--enable-mpi')

                if self.toolchain.options['pic']:
                    prec_configopts.append('--with-pic')

                for libtype in ['openmp', 'shared', 'threads']:
                    if self.cfg['with_%s' % libtype]:
                        prec_configopts.append('--enable-%s' % libtype)

                # SSE2, AVX* only supported for single/double precision
                if prec in ['single', 'double']:
                    for flag in FFTW_CPU_FEATURE_FLAGS_SINGLE_DOUBLE:
                        if getattr(self, flag):
                            if flag == 'fma4':
                                prec_configopts.append('--enable-avx-128-fma')
                            else:
                                prec_configopts.append('--enable-%s' % flag)

                # Altivec (POWER) and SSE only for single precision
                for flag in ['altivec', 'sse']:
                    if prec == 'single' and getattr(self, flag):
                        prec_configopts.append('--enable-%s' % flag)

                # NEON (ARM) only for single precision and double precision (on AARCH64)
                if (prec == 'single' and (self.asimd or self.neon)) or (prec == 'double' and self.asimd):
                    prec_configopts.append('--enable-neon')

                # For POWER with GCC 5/6/7 and FFTW/3.3.6 we need to disable some settings for tests to pass
                # (we do it last so as not to affect previous logic)
                cpu_arch = get_cpu_architecture()
                comp_fam = self.toolchain.comp_family()
                fftw_ver = LooseVersion(self.version)
                if cpu_arch == POWER and comp_fam == TC_CONSTANT_GCC and fftw_ver <= LooseVersion('3.3.8'):
                    # See https://github.com/FFTW/fftw3/issues/59 which applies to GCC 5/6/7
                    if prec == 'single':
                        self.log.info("Disabling altivec for single precision on POWER with GCC for FFTW/%s"
                                      % self.version)
                        prec_configopts.append('--disable-altivec')
                    if prec == 'double':
                        self.log.info("Disabling vsx for double precision on POWER with GCC for FFTW/%s" % self.version)
                        prec_configopts.append('--disable-vsx')

                # append additional configure options (may be empty string, but that's OK)
                self.cfg.update('configopts', [' '.join(prec_configopts) + ' ' + common_config_opts])

        self.log.debug("List of configure options to iterate over: %s", self.cfg['configopts'])

        return super(EB_FFTW, self).run_all_steps(*args, **kwargs)
 def test_cpu_architecture_native(self):
     """Test getting the CPU architecture."""
     arch = get_cpu_architecture()
     self.assertTrue(arch in CPU_ARCHITECTURES)