Beispiel #1
0
    def prepare_step(self, *args, **kwargs):
        """Do compiler appropriate prepare step, determine system compiler version and prefix."""
        if self.cfg['generate_standalone_module']:
            if self.cfg['name'] in ['GCC', 'GCCcore']:
                EB_GCC.prepare_step(self, *args, **kwargs)
            elif self.cfg['name'] in ['icc']:
                EB_icc.prepare_step(self, *args, **kwargs)
            elif self.cfg['name'] in ['ifort']:
                EB_ifort.prepare_step(self, *args, **kwargs)
            else:
                raise EasyBuildError(
                    "I don't know how to do the prepare_step for %s",
                    self.cfg['name'])
        else:
            Bundle.prepare_step(self, *args, **kwargs)

        # Determine compiler path (real path, with resolved symlinks)
        compiler_name = self.cfg['name'].lower()
        if compiler_name == 'gcccore':
            compiler_name = 'gcc'
        path_to_compiler = which(compiler_name)
        if path_to_compiler:
            path_to_compiler = resolve_path(path_to_compiler)
            self.log.info(
                "Found path to compiler '%s' (with symlinks resolved): %s",
                compiler_name, path_to_compiler)
        else:
            raise EasyBuildError("%s not found in $PATH", compiler_name)

        # Determine compiler version
        self.compiler_version = extract_compiler_version(compiler_name)

        # Determine installation prefix
        if compiler_name == 'gcc':
            # strip off 'bin/gcc'
            self.compiler_prefix = os.path.dirname(
                os.path.dirname(path_to_compiler))

        elif compiler_name in ['icc', 'ifort']:
            intelvars_fn = path_to_compiler + 'vars.sh'
            if os.path.isfile(intelvars_fn):
                self.log.debug(
                    "Trying to determine compiler install prefix from %s",
                    intelvars_fn)
                intelvars_txt = read_file(intelvars_fn)
                prod_dir_regex = re.compile(r'^PROD_DIR=(.*)$', re.M)
                res = prod_dir_regex.search(intelvars_txt)
                if res:
                    self.compiler_prefix = res.group(1)
                else:
                    raise EasyBuildError(
                        "Failed to determine %s installation prefix from %s",
                        compiler_name, intelvars_fn)
            else:
                # strip off 'bin/intel*/icc'
                self.compiler_prefix = os.path.dirname(
                    os.path.dirname(os.path.dirname(path_to_compiler)))

            # For versions 2016+ of Intel compilers they changed the installation path so must shave off 2 more
            # directories from result of the above
            if LooseVersion(self.compiler_version) >= LooseVersion('2016'):
                self.compiler_prefix = os.path.dirname(
                    os.path.dirname(self.compiler_prefix))

        else:
            raise EasyBuildError("Unknown system compiler %s" %
                                 self.cfg['name'])

        if not os.path.exists(self.compiler_prefix):
            raise EasyBuildError(
                "Path derived for system compiler (%s) does not exist: %s!",
                compiler_name, self.compiler_prefix)
        self.log.debug(
            "Derived version/install prefix for system compiler %s: %s, %s",
            compiler_name, self.compiler_version, self.compiler_prefix)

        # If EasyConfig specified "real" version (not 'system' which means 'derive automatically'), check it
        if self.cfg['version'] == 'system':
            self.log.info(
                "Found specified version '%s', going with derived compiler version '%s'",
                self.cfg['version'], self.compiler_version)
        elif self.cfg['version'] != self.compiler_version:
            raise EasyBuildError(
                "Specified version (%s) does not match version reported by compiler (%s)"
                % (self.cfg['version'], self.compiler_version))
Beispiel #2
0
class EB_DOLFIN(CMakePythonPackage):
    """Support for building and installing DOLFIN."""
    def __init__(self, *args, **kwargs):
        """Initialize class variables."""
        super(EB_DOLFIN, self).__init__(*args, **kwargs)

        self.boost_dir = None
        self.saved_configopts = None

    def configure_step(self):
        """Set DOLFIN-specific configure options and configure with CMake."""

        # compilers
        self.cfg.update('configopts',
                        "-DCMAKE_C_COMPILER='%s' " % os.getenv('CC'))
        self.cfg.update('configopts',
                        "-DCMAKE_CXX_COMPILER='%s' " % os.getenv('CXX'))
        self.cfg.update('configopts',
                        "-DCMAKE_Fortran_COMPILER='%s' " % os.getenv('F90'))

        # compiler flags
        cflags = os.getenv('CFLAGS')
        cxxflags = os.getenv('CXXFLAGS')
        fflags = os.getenv('FFLAGS')

        # fix for "SEEK_SET is #defined but must not be for the C++ binding of MPI. Include mpi.h before stdio.h"
        if self.toolchain.mpi_family() in [
                toolchain.INTELMPI, toolchain.MPICH, toolchain.MPICH2,
                toolchain.MVAPICH2
        ]:
            cflags += " -DMPICH_IGNORE_CXX_SEEK"
            cxxflags += " -DMPICH_IGNORE_CXX_SEEK"
            fflags += " -DMPICH_IGNORE_CXX_SEEK"

        self.cfg.update('configopts', '-DCMAKE_C_FLAGS="%s"' % cflags)
        self.cfg.update('configopts', '-DCMAKE_CXX_FLAGS="%s"' % cxxflags)
        self.cfg.update('configopts', '-DCMAKE_Fortran_FLAGS="%s"' % fflags)

        # run cmake in debug mode
        self.cfg.update('configopts', ' -DCMAKE_BUILD_TYPE=Debug')

        # set correct compilers to be used at runtime
        self.cfg.update('configopts', ' -DMPI_C_COMPILER="$MPICC"')
        self.cfg.update('configopts', ' -DMPI_CXX_COMPILER="$MPICXX"')

        # specify MPI library
        self.cfg.update('configopts',
                        ' -DMPI_COMPILER="%s"' % os.getenv('MPICC'))

        if os.getenv('MPI_LIB_SHARED') and os.getenv('MPI_INC_DIR'):
            self.cfg.update(
                'configopts',
                ' -DMPI_LIBRARY="%s"' % os.getenv('MPI_LIB_SHARED'))
            self.cfg.update(
                'configopts',
                ' -DMPI_INCLUDE_PATH="%s"' % os.getenv('MPI_INC_DIR'))
        else:
            raise EasyBuildError(
                "MPI_LIB_SHARED or MPI_INC_DIR not set, could not determine MPI-related paths."
            )

        # save config options to reuse them later (e.g. for sanity check commands)
        self.saved_configopts = self.cfg['configopts']

        # make sure that required dependencies are loaded
        deps = [
            'Armadillo', 'Boost', 'CGAL', 'MTL4', 'ParMETIS', 'PETSc',
            'Python', 'SCOTCH', 'Sphinx', 'SLEPc', 'SuiteSparse', 'Trilinos',
            'UFC', 'zlib'
        ]
        depsdict = {}
        for dep in deps:
            deproot = get_software_root(dep)
            if not deproot:
                raise EasyBuildError("Dependency %s not available.", dep)
            else:
                depsdict.update({dep: deproot})

        # zlib
        self.cfg.update(
            'configopts', '-DZLIB_INCLUDE_DIR=%s' %
            os.path.join(depsdict['zlib'], "include"))
        self.cfg.update(
            'configopts', '-DZLIB_LIBRARY=%s' %
            os.path.join(depsdict['zlib'], "lib", "libz.a"))

        # set correct openmp options
        openmp = self.toolchain.get_flag('openmp')
        self.cfg.update('configopts', ' -DOpenMP_CXX_FLAGS="%s"' % openmp)
        self.cfg.update('configopts', ' -DOpenMP_C_FLAGS="%s"' % openmp)

        # Boost config parameters
        self.cfg.update('configopts',
                        " -DBOOST_INCLUDEDIR=%s/include" % depsdict['Boost'])
        self.cfg.update(
            'configopts',
            " -DBoost_DEBUG=ON -DBOOST_ROOT=%s" % depsdict['Boost'])
        self.boost_dir = depsdict['Boost']

        # UFC and Armadillo config params
        self.cfg.update('configopts', " -DUFC_DIR=%s" % depsdict['UFC'])
        self.cfg.update('configopts',
                        "-DARMADILLO_DIR:PATH=%s " % depsdict['Armadillo'])

        # specify Python paths
        python_short_ver = ".".join(
            get_software_version('Python').split(".")[0:2])
        self.cfg.update(
            'configopts', " -DPYTHON_INCLUDE_PATH=%s/include/python%s" %
            (depsdict['Python'], python_short_ver))
        self.cfg.update(
            'configopts', " -DPYTHON_LIBRARY=%s/lib/libpython%s.so" %
            (depsdict['Python'], python_short_ver))

        # SuiteSparse config params
        suitesparse = depsdict['SuiteSparse']
        umfpack_params = [
            ' -DUMFPACK_DIR="%(sp)s/UMFPACK"',
            '-DUMFPACK_INCLUDE_DIRS="%(sp)s/UMFPACK/include;%(sp)s/UFconfig"',
            '-DAMD_DIR="%(sp)s/UMFPACK"', '-DCHOLMOD_DIR="%(sp)s/CHOLMOD"',
            '-DCHOLMOD_INCLUDE_DIRS="%(sp)s/CHOLMOD/include;%(sp)s/UFconfig"',
            '-DUFCONFIG_DIR="%(sp)s/UFconfig"',
            '-DCAMD_LIBRARY:PATH="%(sp)s/CAMD/lib/libcamd.a"',
            '-DCCOLAMD_LIBRARY:PATH="%(sp)s/CCOLAMD/lib/libccolamd.a"',
            '-DCOLAMD_LIBRARY:PATH="%(sp)s/COLAMD/lib/libcolamd.a"'
        ]

        self.cfg.update('configopts',
                        ' '.join(umfpack_params) % {'sp': suitesparse})

        # ParMETIS and SCOTCH
        self.cfg.update('configopts',
                        '-DPARMETIS_DIR="%s"' % depsdict['ParMETIS'])
        self.cfg.update(
            'configopts',
            '-DSCOTCH_DIR="%s" -DSCOTCH_DEBUG:BOOL=ON' % depsdict['SCOTCH'])

        # BLACS and LAPACK
        self.cfg.update('configopts',
                        '-DBLAS_LIBRARIES:PATH="%s"' % os.getenv('LIBBLAS'))
        self.cfg.update(
            'configopts',
            '-DLAPACK_LIBRARIES:PATH="%s"' % os.getenv('LIBLAPACK'))

        # CGAL
        self.cfg.update('configopts',
                        '-DCGAL_DIR:PATH="%s"' % depsdict['CGAL'])

        # PETSc
        # need to specify PETSC_ARCH explicitely (env var alone is not sufficient)
        for env_var in ["PETSC_DIR", "PETSC_ARCH"]:
            val = os.getenv(env_var)
            if val:
                self.cfg.update('configopts', '-D%s=%s' % (env_var, val))

        # MTL4
        self.cfg.update('configopts',
                        '-DMTL4_DIR:PATH="%s"' % depsdict['MTL4'])

        # configure
        out = super(EB_DOLFIN, self).configure_step()

        # make sure that all optional packages are found
        not_found_re = re.compile(
            "The following optional packages could not be found")
        if not_found_re.search(out):
            raise EasyBuildError(
                "Optional packages could not be found, this should not happen..."
            )

        # enable verbose build, so we have enough information if something goes wrong
        self.cfg.update('buildopts', "VERBOSE=1")

    def make_module_extra(self):
        """Set extra environment variables for DOLFIN."""

        txt = super(EB_DOLFIN, self).make_module_extra()

        # Dolfin needs to find Boost
        txt += self.module_generator.set_environment('BOOST_DIR',
                                                     self.boost_dir)

        envvars = ['I_MPI_CXX', 'I_MPI_CC']
        for envvar in envvars:
            envar_val = os.getenv(envvar)
            # if environment variable is set, also set it in module
            if envar_val:
                txt += self.module_generator.set_environment(envvar, envar_val)

        return txt

    def sanity_check_step(self):
        """Custom sanity check for DOLFIN."""

        # custom sanity check paths
        custom_paths = {
            'files': [
                'bin/dolfin-%s' % x
                for x in ['version', 'convert', 'order', 'plot']
            ] + ['include/dolfin.h'],
            'dirs': ['%s/dolfin' % self.pylibdir]
        }

        # custom sanity check commands

        # set cache/error dirs for Instant
        tmpdir = tempfile.mkdtemp()
        instant_cache_dir = os.path.join(tmpdir, '.instant', 'cache')
        instant_error_dir = os.path.join(tmpdir, '.instant', 'error')
        try:
            os.makedirs(instant_cache_dir)
            os.makedirs(instant_error_dir)
        except OSError, err:
            raise EasyBuildError(
                "Failed to create Instant cache/error dirs: %s", err)

        # keep track of $LDFLAGS, so we can restore them for the sanity check commands
        # this is required to make sure that linking of libraries (OpenBLAS, etc.) works as expected
        ldflags = os.getenv('LDFLAGS')

        # we need to explicitely set the following environment variables as a part of the sanity check command,
        # because the environment is reset and only the environment variables set by the DOLFIN module are there
        env_vars = [
            ('LDFLAGS', ldflags),
            ('INSTANT_CACHE_DIR', instant_cache_dir),
            ('INSTANT_ERROR_DIR', instant_error_dir),
        ]
        env_var_cmds = ' && '.join(
            ['export %s="%s"' % (var, val) for (var, val) in env_vars])

        pref = os.path.join('share', 'dolfin', 'demo')

        # test command templates
        cmd_template_python = " && ".join([
            env_var_cmds,
            "cd %(dir)s",
            "python demo_%(name)s.py",
            "cd -",
        ])

        cmd_template_cpp = " && ".join([
            env_var_cmds,
            "cd %(dir)s",
            "cmake . %s" % self.saved_configopts,
            "make VERBOSE=1",
            "./demo_%(name)s",
            "cd -",
        ])

        # list based on demos available for DOLFIN v1.0.0
        pde_demos = [
            'biharmonic', 'cahn-hilliard', 'hyperelasticity', 'mixed-poisson',
            'navier-stokes', 'poisson', 'stokes-iterative'
        ]

        demos = [os.path.join('la', 'eigenvalue')
                 ] + [os.path.join('pde', x) for x in pde_demos]

        # construct commands
        cmds = [
            tmpl % {
                'dir': os.path.join(pref, d, subdir),
                'name': os.path.basename(d),
            } for d in demos for (tmpl, subdir) in [(cmd_template_cpp, 'cpp')]
        ]
        # exclude Python tests for now, because they 'hang' sometimes (unclear why)
        # they can be reinstated once run_cmd (or its equivalent) has support for timeouts
        # see https://github.com/hpcugent/easybuild-framework/issues/581
        #for (tmpl, subdir) in [(cmd_template_python, 'python'), (cmd_template_cpp, 'cpp')]]

        # subdomains-poisson has no C++ get_version, only Python
        # Python tests excluded, see above
        #name = 'subdomains-poisson'
        #path = os.path.join(pref, 'pde', name, 'python')
        #cmds += [cmd_template_python % {'dir': path, 'name': name}]

        # supply empty argument to each command
        custom_commands = [(cmd, "") for cmd in cmds]

        super(EB_DOLFIN,
              self).sanity_check_step(custom_paths=custom_paths,
                                      custom_commands=custom_commands)

        # clean up temporary dir
        try:
            rmtree2(tmpdir)
        except OSError, err:
            raise EasyBuildError(
                "Failed to remove Instant cache/error dirs: %s", err)
Beispiel #3
0
class EB_imkl(IntelBase):
    """
    Class that can be used to install mkl
    - tested with 10.2.1.017
    -- will fail for all older versions (due to newer silent installer)
    """
    @staticmethod
    def extra_options():
        """Add easyconfig parameters custom to imkl (e.g. interfaces)."""
        extra_vars = {
            'interfaces':
            [True, "Indicates whether interfaces should be built", CUSTOM],
        }
        return IntelBase.extra_options(extra_vars)

    def __init__(self, *args, **kwargs):
        super(EB_imkl, self).__init__(*args, **kwargs)
        # make sure $MKLROOT isn't set, it's known to cause problems with the installation
        self.cfg.update('unwanted_env_vars', ['MKLROOT'])
        self.cdftlibs = []
        self.mpi_spec = None

    def prepare_step(self, *args, **kwargs):
        if LooseVersion(self.version) >= LooseVersion('2017.2.174'):
            kwargs['requires_runtime_license'] = False
            super(EB_imkl, self).prepare_step(*args, **kwargs)
        else:
            super(EB_imkl, self).prepare_step(*args, **kwargs)

        # build the mkl interfaces, if desired
        if self.cfg['interfaces']:
            self.cdftlibs = ['fftw2x_cdft']
            if LooseVersion(self.version) >= LooseVersion('10.3'):
                self.cdftlibs.append('fftw3x_cdft')
            # check whether MPI_FAMILY constant is defined, so mpi_family() can be used
            if hasattr(self.toolchain,
                       'MPI_FAMILY') and self.toolchain.MPI_FAMILY is not None:
                mpi_spec_by_fam = {
                    toolchain.MPICH:
                    'mpich2',  # MPICH is MPICH v3.x, which is MPICH2 compatible
                    toolchain.MPICH2: 'mpich2',
                    toolchain.MVAPICH2: 'mpich2',
                    toolchain.OPENMPI: 'openmpi',
                }
                mpi_fam = self.toolchain.mpi_family()
                self.mpi_spec = mpi_spec_by_fam.get(mpi_fam)
                debugstr = "MPI toolchain component"
            else:
                # can't use toolchain.mpi_family, because of dummy toolchain
                if get_software_root('MPICH2') or get_software_root(
                        'MVAPICH2'):
                    self.mpi_spec = 'mpich2'
                elif get_software_root('OpenMPI'):
                    self.mpi_spec = 'openmpi'
                elif not get_software_root('impi'):
                    # no compatible MPI found: do not build cdft
                    self.cdftlibs = []
                debugstr = "loaded MPI module"
            if self.mpi_spec:
                self.log.debug("Determined MPI specification based on %s: %s",
                               debugstr, self.mpi_spec)
            else:
                self.log.debug(
                    "No MPI or no compatible MPI found: do not build CDFT")

    def install_step(self):
        """
        Actual installation
        - create silent cfg file
        - execute command
        """
        silent_cfg_names_map = None
        silent_cfg_extras = None

        if LooseVersion(self.version) < LooseVersion('11.1'):
            # since imkl v11.1, silent.cfg has been slightly changed to be 'more standard'

            silent_cfg_names_map = {
                'activation_name': ACTIVATION_NAME_2012,
                'license_file_name': LICENSE_FILE_NAME_2012,
            }

        if LooseVersion(self.version) >= LooseVersion(
                '11.1') and self.install_components is None:
            silent_cfg_extras = {
                'COMPONENTS': 'ALL',
            }

        super(EB_imkl,
              self).install_step(silent_cfg_names_map=silent_cfg_names_map,
                                 silent_cfg_extras=silent_cfg_extras)

    def make_module_req_guess(self):
        """
        A dictionary of possible directories to look for
        """
        if LooseVersion(self.version) >= LooseVersion('10.3'):
            if self.cfg['m32']:
                raise EasyBuildError(
                    "32-bit not supported yet for IMKL v%s (>= 10.3)",
                    self.version)
            else:
                retdict = {
                    'PATH': [
                        'bin', 'mkl/bin', 'mkl/bin/intel64',
                        'composerxe-2011/bin'
                    ],
                    'LD_LIBRARY_PATH': ['lib/intel64', 'mkl/lib/intel64'],
                    'LIBRARY_PATH': ['lib/intel64', 'mkl/lib/intel64'],
                    'MANPATH': ['man', 'man/en_US'],
                    'CPATH': ['mkl/include', 'mkl/include/fftw'],
                }
                if LooseVersion(self.version) >= LooseVersion('11.0'):
                    if LooseVersion(self.version) >= LooseVersion('11.3'):
                        retdict['MIC_LD_LIBRARY_PATH'] = [
                            'lib/intel64_lin_mic', 'mkl/lib/mic'
                        ]
                    elif LooseVersion(self.version) >= LooseVersion('11.1'):
                        retdict['MIC_LD_LIBRARY_PATH'] = [
                            'lib/mic', 'mkl/lib/mic'
                        ]
                    else:
                        retdict['MIC_LD_LIBRARY_PATH'] = [
                            'compiler/lib/mic', 'mkl/lib/mic'
                        ]
                return retdict
        else:
            if self.cfg['m32']:
                return {
                    'PATH': ['bin', 'bin/ia32', 'tbb/bin/ia32'],
                    'LD_LIBRARY_PATH': ['lib', 'lib/32'],
                    'LIBRARY_PATH': ['lib', 'lib/32'],
                    'MANPATH': ['man', 'share/man', 'man/en_US'],
                    'CPATH': ['include'],
                }

            else:
                return {
                    'PATH': ['bin', 'bin/intel64', 'tbb/bin/em64t'],
                    'LD_LIBRARY_PATH': ['lib', 'lib/em64t'],
                    'LIBRARY_PATH': ['lib', 'lib/em64t'],
                    'MANPATH': ['man', 'share/man', 'man/en_US'],
                    'CPATH': ['include'],
                }

    def make_module_extra(self):
        """Overwritten from Application to add extra txt"""
        txt = super(EB_imkl, self).make_module_extra()
        txt += self.module_generator.set_environment(
            'MKLROOT', os.path.join(self.installdir, 'mkl'))
        return txt

    def post_install_step(self):
        """
        Install group libraries and interfaces (if desired).
        """
        super(EB_imkl, self).post_install_step()

        shlib_ext = get_shared_lib_ext()

        # reload the dependencies
        self.load_dependency_modules()

        if self.cfg['m32']:
            extra = {
                'libmkl.%s' % shlib_ext:
                'GROUP (-lmkl_intel -lmkl_intel_thread -lmkl_core)',
                'libmkl_em64t.a':
                'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)',
                'libmkl_solver.a': 'GROUP (libmkl_solver.a)',
                'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_core.a)',
                'libmkl_lapack.a':
                'GROUP (libmkl_intel.a libmkl_intel_thread.a libmkl_core.a)',
                'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)'
            }
        else:
            extra = {
                'libmkl.%s' % shlib_ext:
                'GROUP (-lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core)',
                'libmkl_em64t.a':
                'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)',
                'libmkl_solver.a': 'GROUP (libmkl_solver_lp64.a)',
                'libmkl_scalapack.a': 'GROUP (libmkl_scalapack_lp64.a)',
                'libmkl_lapack.a':
                'GROUP (libmkl_intel_lp64.a libmkl_intel_thread.a libmkl_core.a)',
                'libmkl_cdft.a': 'GROUP (libmkl_cdft_core.a)'
            }

        if LooseVersion(self.version) >= LooseVersion('10.3'):
            libsubdir = os.path.join('mkl', 'lib', 'intel64')
        else:
            if self.cfg['m32']:
                libsubdir = os.path.join('lib', '32')
            else:
                libsubdir = os.path.join('lib', 'em64t')

        for fil, txt in extra.items():
            dest = os.path.join(self.installdir, libsubdir, fil)
            if not os.path.exists(dest):
                try:
                    f = open(dest, 'w')
                    f.write(txt)
                    f.close()
                    self.log.info("File %s written" % dest)
                except IOError, err:
                    raise EasyBuildError("Can't write file %s: %s", dest, err)

        # build the mkl interfaces, if desired
        if self.cfg['interfaces']:

            if LooseVersion(self.version) >= LooseVersion('10.3'):
                intsubdir = os.path.join('mkl', 'interfaces')
                inttarget = 'libintel64'
            else:
                intsubdir = 'interfaces'
                if self.cfg['m32']:
                    inttarget = 'lib32'
                else:
                    inttarget = 'libem64t'

            cmd = "make -f makefile %s" % inttarget

            # blas95 and lapack95 need more work, ignore for now
            # blas95 and lapack also need include/.mod to be processed
            fftw2libs = ['fftw2xc', 'fftw2xf']
            fftw3libs = ['fftw3xc', 'fftw3xf']

            interfacedir = os.path.join(self.installdir, intsubdir)
            try:
                os.chdir(interfacedir)
                self.log.info("Changed to interfaces directory %s" %
                              interfacedir)
            except OSError, err:
                raise EasyBuildError("Can't change to interfaces directory %s",
                                     interfacedir)

            compopt = None
            # determine whether we're using a non-Intel GCC-based or PGI-based toolchain
            # can't use toolchain.comp_family, because of dummy toolchain used when installing imkl
            if get_software_root('icc') is None:
                # check for PGI first, since there's a GCC underneath PGI too...
                if get_software_root('PGI'):
                    compopt = 'compiler=pgi'
                elif get_software_root('GCC'):
                    compopt = 'compiler=gnu'
                else:
                    raise EasyBuildError(
                        "Not using Intel/GCC/PGI compilers, don't know how to build wrapper libs"
                    )
            else:
                compopt = 'compiler=intel'

            # patch makefiles for cdft wrappers when PGI is used as compiler
            if get_software_root('PGI'):
                regex_subs = [
                    # pgi should be considered as a valid compiler
                    ("intel gnu", "intel gnu pgi"),
                    # transform 'gnu' case to 'pgi' case
                    (r"ifeq \(\$\(compiler\),gnu\)", "ifeq ($(compiler),pgi)"),
                    ('=gcc', '=pgcc'),
                    # correct flag to use C99 standard
                    ('-std=c99', '-c99'),
                    # -Wall and -Werror are not valid options for pgcc, no close equivalent
                    ('-Wall', ''),
                    ('-Werror', ''),
                ]
                for lib in self.cdftlibs:
                    apply_regex_substitutions(
                        os.path.join(interfacedir, lib, 'makefile'),
                        regex_subs)

            for lib in fftw2libs + fftw3libs + self.cdftlibs:
                buildopts = [compopt]
                if lib in fftw3libs:
                    buildopts.append('install_to=$INSTALL_DIR')
                elif lib in self.cdftlibs:
                    if self.mpi_spec is not None:
                        buildopts.append('mpi=%s' % self.mpi_spec)

                precflags = ['']
                if lib.startswith('fftw2x') and not self.cfg['m32']:
                    # build both single and double precision variants
                    precflags = [
                        'PRECISION=MKL_DOUBLE', 'PRECISION=MKL_SINGLE'
                    ]

                intflags = ['']
                if lib in self.cdftlibs and not self.cfg['m32']:
                    # build both 32-bit and 64-bit interfaces
                    intflags = ['interface=lp64', 'interface=ilp64']

                allopts = [
                    list(opts)
                    for opts in itertools.product(intflags, precflags)
                ]

                for flags, extraopts in itertools.product(['', '-fPIC'],
                                                          allopts):
                    tup = (lib, flags, buildopts, extraopts)
                    self.log.debug(
                        "Building lib %s with: flags %s, buildopts %s, extraopts %s"
                        % tup)

                    tmpbuild = tempfile.mkdtemp(dir=self.builddir)
                    self.log.debug("Created temporary directory %s" % tmpbuild)

                    # always set INSTALL_DIR, SPEC_OPT, COPTS and CFLAGS
                    # fftw2x(c|f): use $INSTALL_DIR, $CFLAGS and $COPTS
                    # fftw3x(c|f): use $CFLAGS
                    # fftw*cdft: use $INSTALL_DIR and $SPEC_OPT
                    env.setvar('INSTALL_DIR', tmpbuild)
                    env.setvar('SPEC_OPT', flags)
                    env.setvar('COPTS', flags)
                    env.setvar('CFLAGS', flags)

                    try:
                        intdir = os.path.join(interfacedir, lib)
                        os.chdir(intdir)
                        self.log.info("Changed to interface %s directory %s" %
                                      (lib, intdir))
                    except OSError, err:
                        raise EasyBuildError(
                            "Can't change to interface %s directory %s: %s",
                            lib, intdir, err)

                    fullcmd = "%s %s" % (cmd, ' '.join(buildopts + extraopts))
                    res = run_cmd(fullcmd, log_all=True, simple=True)
                    if not res:
                        raise EasyBuildError(
                            "Building %s (flags: %s, fullcmd: %s) failed", lib,
                            flags, fullcmd)

                    for fn in os.listdir(tmpbuild):
                        src = os.path.join(tmpbuild, fn)
                        if flags == '-fPIC':
                            # add _pic to filename
                            ff = fn.split('.')
                            fn = '.'.join(ff[:-1]) + '_pic.' + ff[-1]
                        dest = os.path.join(self.installdir, libsubdir, fn)
                        try:
                            if os.path.isfile(src):
                                shutil.move(src, dest)
                                self.log.info("Moved %s to %s" % (src, dest))
                        except OSError, err:
                            raise EasyBuildError("Failed to move %s to %s: %s",
                                                 src, dest, err)

                    rmtree2(tmpbuild)
Beispiel #4
0
class EB_SciPy_minus_Stack(EB_Python):
    """Support for building/installing SciPy-Stack"""
    def install_step(self):
        """Extend make install to make sure that the 'python' command is present."""
        super(EB_Python, self).install_step()

        python_binary_path = os.path.join(self.installdir, 'bin', 'python')
        if not os.path.isfile(python_binary_path):
            if os.path.isfile(python_binary_path + '2'):
                pyver = '2'
            elif os.path.isfile(python_binary_path + '3'):
                pyver = '3'
            else:
                raise EasyBuildError("Can't find a python binary in %s",
                                     os.path.join(self.installdir, 'bin'))
            symlink(python_binary_path + pyver, python_binary_path)

    def sanity_check_step(self):
        """Custom sanity check for SciPy-Stack."""

        pyver = 'python' + '.'.join(self.version.split('.')[:2])
        shlib_ext = get_shared_lib_ext()

        try:
            fake_mod_data = self.load_fake_module()
        except EasyBuildError, err:
            raise EasyBuildError("Loading fake module failed: %s", err)

        abiflags = ''
        if LooseVersion(self.version) >= LooseVersion("3"):
            run_cmd("which python", log_all=True, simple=False)
            cmd = 'python -c "import sysconfig; print(sysconfig.get_config_var(\'abiflags\'));"'
            (abiflags, _) = run_cmd(cmd, log_all=True, simple=False)
            if not abiflags:
                raise EasyBuildError("Failed to determine abiflags: %s",
                                     abiflags)
            else:
                abiflags = abiflags.strip()

        custom_paths = {
            'files': [
                os.path.join('bin', pyver),
                os.path.join('lib', 'lib' + pyver + abiflags + '.' + shlib_ext)
            ],
            'dirs': [
                os.path.join('include', pyver + abiflags),
                os.path.join('lib', pyver)
            ],
        }

        # cleanup
        self.clean_up_fake_module(fake_mod_data)

        custom_commands = [
            "python --version",
            "python -c 'import _ctypes'",  # make sure that foreign function interface (libffi) works
            "python -c 'import _ssl'",  # make sure SSL support is enabled one way or another
            "python -c 'import readline'",  # make sure readline support was built correctly
        ]

        super(EB_Python,
              self).sanity_check_step(custom_paths=custom_paths,
                                      custom_commands=custom_commands)
    def configure_step(self):
        """Set some extra environment variables before configuring."""

        # enable verbose output if desired
        if self.cfg['verbose']:
            for x in ["CONFIGURE", "MAKEFILE"]:
                self.cfg.update('configopts', "-DTrilinos_VERBOSE_%s:BOOL=ON" % x)

        # compiler flags
        cflags = [os.getenv('CFLAGS')]
        cxxflags = [os.getenv('CXXFLAGS')]
        fflags = [os.getenv('FFLAGS')]

        ignore_cxx_seek_mpis = [toolchain.INTELMPI, toolchain.MPICH,
                                toolchain.MPICH2, toolchain.MVAPICH2]  # @UndefinedVariable
        ignore_cxx_seek_flag = "-DMPICH_IGNORE_CXX_SEEK"
        if self.toolchain.mpi_family() in ignore_cxx_seek_mpis:
            cflags.append(ignore_cxx_seek_flag)
            cxxflags.append(ignore_cxx_seek_flag)
            fflags.append(ignore_cxx_seek_flag)

        self.cfg.update('configopts', '-DCMAKE_C_FLAGS="%s"' % ' '.join(cflags))
        self.cfg.update('configopts', '-DCMAKE_CXX_FLAGS="%s"' % ' '.join(cxxflags))
        self.cfg.update('configopts', '-DCMAKE_Fortran_FLAGS="%s"' % ' '.join(fflags))

        # Make sure Tpetra/Kokkos Serial mode is enabled regardless of OpenMP
        self.cfg.update('configopts', "-DKokkos_ENABLE_Serial:BOOL=ON")
        self.cfg.update('configopts', "-DTpetra_INST_SERIAL:BOOL=ON")

        # OpenMP
        if self.cfg['openmp']:
            self.cfg.update('configopts', "-DTrilinos_ENABLE_OpenMP:BOOL=ON")
            self.cfg.update('configopts', "-DKokkos_ENABLE_OpenMP:BOOL=ON")

        # MPI
        if self.toolchain.options.get('usempi', None):
            self.cfg.update('configopts', "-DTPL_ENABLE_MPI:BOOL=ON")

        # enable full testing
        self.cfg.update('configopts', "-DTrilinos_ENABLE_TESTS:BOOL=ON")
        self.cfg.update('configopts', "-DTrilinos_ENABLE_ALL_FORWARD_DEP_PACKAGES:BOOL=ON")

        lib_re = re.compile("^lib(.*).a$")

        # BLAS, LAPACK
        for dep in ["BLAS", "LAPACK"]:
            self.cfg.update('configopts', '-DTPL_ENABLE_%s:BOOL=ON' % dep)
            libdirs = os.getenv('%s_LIB_DIR' % dep)
            if self.toolchain.comp_family() == toolchain.GCC:  # @UndefinedVariable
                libdirs += ";%s/lib64" % get_software_root('GCC')
            self.cfg.update('configopts', '-D%s_LIBRARY_DIRS="%s"' % (dep, libdirs))
            if self.cfg['openmp']:
                libs = os.getenv('%s_MT_STATIC_LIBS' % dep).split(',')
            else:
                libs = os.getenv('%s_STATIC_LIBS' % dep).split(',')
            lib_names = ';'.join([lib_re.search(x).group(1) for x in libs])
            if self.toolchain.comp_family() == toolchain.GCC:  # @UndefinedVariable
                # explicitely specify static lib!
                lib_names += ";libgfortran.a"
            self.cfg.update('configopts', '-D%s_LIBRARY_NAMES="%s"' % (dep, lib_names))

        # MKL
        if get_software_root('imkl') and LooseVersion(self.version) >= LooseVersion('12.12'):
            self.cfg.update('configopts', "-DTPL_ENABLE_MKL:BOOL=ON")
            self.cfg.update('configopts', '-DMKL_LIBRARY_DIRS:PATH="%s/lib/intel64"' % os.getenv('MKLROOT'))
            self.cfg.update('configopts', '-DMKL_INCLUDE_DIRS:PATH="%s/include"' % os.getenv('MKLROOT'))

        # UMFPACK is part of SuiteSparse
        suitesparse = get_software_root('SuiteSparse')
        if suitesparse:
            self.cfg.update('configopts', "-DTPL_ENABLE_UMFPACK:BOOL=ON")
            self.cfg.update('configopts', "-DTPL_ENABLE_Cholmod:BOOL=ON")
            incdirs, libdirs, libnames = [], [], []
            for lib in ["UMFPACK", "CHOLMOD", "COLAMD", "AMD", "CCOLAMD", "CAMD"]:
                incdirs.append(os.path.join(suitesparse, lib, "Include"))
                libdirs.append(os.path.join(suitesparse, lib, "Lib"))
                libnames.append(lib.lower())

            # add SuiteSparse config lib, it is in recent versions of suitesparse
            libdirs.append(os.path.join(suitesparse, 'SuiteSparse_config'))
            libnames.append('suitesparseconfig')
            # because of "SuiteSparse_config.c:function SuiteSparse_tic: error: undefined reference to 'clock_gettime'"
            libnames.append('rt')

            # required to resolve METIS symbols in SuiteSparse's libcholmod.a
            # doesn't need to be full location, probably because it can be found via $LIBRARY_PATH
            # not easy to know whether it should come from METIS or ParMETIS...
            # see https://answers.launchpad.net/dorsal/+question/223167
            libnames.append('libmetis.a')

            self.cfg.update('configopts', '-DUMFPACK_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
            self.cfg.update('configopts', '-DUMFPACK_LIBRARY_DIRS:PATH="%s"' % ';'.join(libdirs))
            self.cfg.update('configopts', '-DUMFPACK_LIBRARY_NAMES:STRING="%s"' % ';'.join(libnames))
            self.cfg.update('configopts', '-DCholmod_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
            self.cfg.update('configopts', '-DCholmod_LIBRARY_DIRS:PATH="%s"' % ';'.join(libdirs))
            self.cfg.update('configopts', '-DCholmod_LIBRARY_NAMES:STRING="%s"' % ';'.join(libnames))

        # BLACS
        if get_software_root('BLACS'):
            self.cfg.update('configopts', "-DTPL_ENABLE_BLACS:BOOL=ON")
            self.cfg.update('configopts', '-DBLACS_INCLUDE_DIRS:PATH="%s"' % os.getenv('BLACS_INC_DIR'))
            self.cfg.update('configopts', '-DBLACS_LIBRARY_DIRS:PATH="%s"' % os.getenv('BLACS_LIB_DIR'))
            blacs_lib_names = os.getenv('BLACS_STATIC_LIBS').split(',')
            blacs_lib_names = [lib_re.search(x).group(1) for x in blacs_lib_names]
            self.cfg.update('configopts', '-DBLACS_LIBRARY_NAMES:STRING="%s"' % (';'.join(blacs_lib_names)))

        # ScaLAPACK
        if get_software_root('ScaLAPACK'):
            self.cfg.update('configopts', "-DTPL_ENABLE_SCALAPACK:BOOL=ON")
            self.cfg.update('configopts', '-DSCALAPACK_INCLUDE_DIRS:PATH="%s"' % os.getenv('SCALAPACK_INC_DIR'))
            self.cfg.update('configopts', '-DSCALAPACK_LIBRARY_DIRS:PATH="%s;%s"' % (os.getenv('SCALAPACK_LIB_DIR'),
                                                                                     os.getenv('BLACS_LIB_DIR')))
        # PETSc
        petsc = get_software_root('PETSc')
        if petsc:
            self.cfg.update('configopts', "-DTPL_ENABLE_PETSC:BOOL=ON")
            incdirs = [os.path.join(petsc, "include")]
            self.cfg.update('configopts', '-DPETSC_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
            petsc_libdirs = [
                os.path.join(petsc, "lib"),
                os.path.join(suitesparse, "UMFPACK", "Lib"),
                os.path.join(suitesparse, "CHOLMOD", "Lib"),
                os.path.join(suitesparse, "COLAMD", "Lib"),
                os.path.join(suitesparse, "AMD", "Lib"),
                os.getenv('FFTW_LIB_DIR'),
                os.path.join(get_software_root('ParMETIS'), "Lib")
            ]
            self.cfg.update('configopts', '-DPETSC_LIBRARY_DIRS:PATH="%s"' % ';'.join(petsc_libdirs))
            petsc_libnames = ["petsc", "umfpack", "cholmod", "colamd", "amd", "parmetis", "metis"]
            petsc_libnames += [lib_re.search(x).group(1) for x in os.getenv('FFTW_STATIC_LIBS').split(',')]
            self.cfg.update('configopts', '-DPETSC_LIBRARY_NAMES:STRING="%s"' % ';'.join(petsc_libnames))

        # other Third-Party Libraries (TPLs)
        deps = self.cfg.dependencies()
        builddeps = [d['name'] for d in self.cfg.builddependencies()] + ["SuiteSparse"]
        deps = [dep['name'] for dep in deps if not dep['name'] in builddeps]
        for dep in deps:
            deproot = get_software_root(dep)
            if deproot:
                depmap = {
                    'SCOTCH': 'Scotch',
                }
                dep = depmap.get(dep, dep)
                self.cfg.update('configopts', "-DTPL_ENABLE_%s:BOOL=ON" % dep)
                incdir = os.path.join(deproot, "include")
                self.cfg.update('configopts', '-D%s_INCLUDE_DIRS:PATH="%s"' % (dep, incdir))
                libdir = os.path.join(deproot, "lib")
                self.cfg.update('configopts', '-D%s_LIBRARY_DIRS:PATH="%s"' % (dep, libdir))

        # extensions_step
        if self.cfg['all_exts']:
            self.cfg.update('configopts', "-DTrilinos_ENABLE_ALL_PACKAGES:BOOL=ON")

        else:
            for ext in self.cfg['exts_list']:
                self.cfg.update('configopts', "-DTrilinos_ENABLE_%s=ON" % ext)

        # packages to skip
        skip_exts = self.cfg['skip_exts']
        if skip_exts:
            for ext in skip_exts:
                self.cfg.update('configopts', "-DTrilinos_ENABLE_%s:BOOL=OFF" % ext)

        # building in source dir not supported
        # + if the build directory is a long path, problems like "Argument list too long" may occur
        # cfr. https://github.com/trilinos/Trilinos/issues/2434
        # so, try to create build directory with shorter path length to build in
        salt = ''.join(random.choice(ascii_letters) for _ in range(5))
        self.short_start_dir = os.path.join(build_path(), self.name + '-' + salt)
        if os.path.exists(self.short_start_dir):
            raise EasyBuildError("Short start directory %s for Trilinos already exists?!", self.short_start_dir)

        self.log.info("Length of path to original start directory: %s", len(self.start_dir))
        self.log.info("Short start directory: %s (length: %d)", self.short_start_dir, len(self.short_start_dir))

        mkdir(self.short_start_dir)
        short_src_dir = os.path.join(self.short_start_dir, 'src')
        symlink(self.start_dir, short_src_dir)
        short_build_dir = os.path.join(self.short_start_dir, 'obj')
        obj_dir = os.path.join(self.builddir, 'obj')
        mkdir(obj_dir)
        symlink(obj_dir, short_build_dir)

        # configure using cmake
        super(EB_Trilinos, self).configure_step(srcdir=short_src_dir, builddir=short_build_dir)
Beispiel #6
0
    def sanity_check_step(self):
        """Custom sanity check paths for Intel MKL."""
        shlib_ext = get_shared_lib_ext()

        mklfiles = None
        mkldirs = None
        ver = LooseVersion(self.version)
        libs = [
            'libmkl_core.%s' % shlib_ext,
            'libmkl_gnu_thread.%s' % shlib_ext,
            'libmkl_intel_thread.%s' % shlib_ext,
            'libmkl_sequential.%s' % shlib_ext
        ]
        extralibs = [
            'libmkl_blacs_intelmpi_%(suff)s.' + shlib_ext,
            'libmkl_scalapack_%(suff)s.' + shlib_ext
        ]

        if self.cfg['interfaces']:
            compsuff = '_intel'
            if get_software_root('icc') is None:
                # check for PGI first, since there's a GCC underneath PGI too...
                if get_software_root('PGI'):
                    compsuff = '_pgi'
                elif get_software_root('GCC'):
                    compsuff = '_gnu'
                else:
                    raise EasyBuildError(
                        "Not using Intel/GCC/PGI, don't know compiler suffix for FFTW libraries."
                    )

            precs = ['_double', '_single']
            if ver < LooseVersion('11'):
                # no precision suffix in libfftw2 libs before imkl v11
                precs = ['']
            fftw_vers = [
                '2x%s%s' % (x, prec) for x in ['c', 'f'] for prec in precs
            ] + ['3xc', '3xf']
            pics = ['', '_pic']
            libs += [
                'libfftw%s%s%s.a' % (fftwver, compsuff, pic)
                for fftwver in fftw_vers for pic in pics
            ]

            if self.cdftlibs:
                fftw_cdft_vers = ['2x_cdft_DOUBLE']
                if not self.cfg['m32']:
                    fftw_cdft_vers.append('2x_cdft_SINGLE')
                if ver >= LooseVersion('10.3'):
                    fftw_cdft_vers.append('3x_cdft')
                if ver >= LooseVersion('11.0.2'):
                    bits = ['_lp64']
                    if not self.cfg['m32']:
                        bits.append('_ilp64')
                else:
                    # no bits suffix in cdft libs before imkl v11.0.2
                    bits = ['']
                libs += [
                    'libfftw%s%s%s.a' % x
                    for x in itertools.product(fftw_cdft_vers, bits, pics)
                ]

        if ver >= LooseVersion('10.3'):
            if self.cfg['m32']:
                raise EasyBuildError(
                    "Sanity check for 32-bit not implemented yet for IMKL v%s (>= 10.3)",
                    self.version)
            else:
                mkldirs = ['bin', 'mkl/bin', 'mkl/lib/intel64', 'mkl/include']
                if ver < LooseVersion('11.3'):
                    mkldirs.append('mkl/bin/intel64')
                libs += [
                    lib % {
                        'suff': suff
                    } for lib in extralibs for suff in ['lp64', 'ilp64']
                ]
                mklfiles = ['mkl/lib/intel64/libmkl.%s' % shlib_ext, 'mkl/include/mkl.h'] + \
                           ['mkl/lib/intel64/%s' % lib for lib in libs]
                if ver >= LooseVersion('10.3.4') and ver < LooseVersion(
                        '11.1'):
                    mkldirs += ['compiler/lib/intel64']
                else:
                    if ver >= LooseVersion('2017.0.0'):
                        mkldirs += ['lib/intel64_lin']
                    else:
                        mkldirs += ['lib/intel64']

        else:
            if self.cfg['m32']:
                mklfiles = ['lib/32/libmkl.%s' % shlib_ext, 'include/mkl.h'] + \
                           ['lib/32/%s' % lib for lib in libs]
                mkldirs = ['lib/32', 'include/32', 'interfaces']
            else:
                libs += [
                    lib % {
                        'suff': suff
                    } for lib in extralibs for suff in ['lp64', 'ilp64']
                ]
                mklfiles = ['lib/em64t/libmkl.%s' % shlib_ext, 'include/mkl.h'] + \
                           ['lib/em64t/%s' % lib for lib in libs]
                mkldirs = ['lib/em64t', 'include/em64t', 'interfaces']

        custom_paths = {
            'files': mklfiles,
            'dirs': mkldirs,
        }

        super(EB_imkl, self).sanity_check_step(custom_paths=custom_paths)
Beispiel #7
0
    def fixup_hardcoded_paths(self):
        """Patch out hard coded paths to compiler and binutils tools"""
        binutils_root = get_software_root('binutils')
        gcc_root = get_software_root('GCCcore') or get_software_root('GCC')
        gcc_ver = get_software_version('GCCcore') or get_software_version(
            'GCC')

        # only patch Bazel scripts if binutils & GCC installation prefix could be determined
        if not binutils_root or not gcc_root:
            self.log.info(
                "Not patching Bazel build scripts, installation prefix for binutils/GCC not found"
            )
            return

        # replace hardcoded paths in (unix_)cc_configure.bzl
        # hard-coded paths in (unix_)cc_configure.bzl were removed in 0.19.0
        if LooseVersion(self.version) < LooseVersion('0.19.0'):
            regex_subs = [
                (r'-B/usr/bin', '-B%s' % os.path.join(binutils_root, 'bin')),
                (r'"/usr/bin', '"' + os.path.join(binutils_root, 'bin')),
            ]
            for conf_bzl in ['cc_configure.bzl', 'unix_cc_configure.bzl']:
                filepath = os.path.join('tools', 'cpp', conf_bzl)
                if os.path.exists(filepath):
                    apply_regex_substitutions(filepath, regex_subs)

        # replace hardcoded paths in CROSSTOOL
        # CROSSTOOL script is no longer there in Bazel 0.24.0
        if LooseVersion(self.version) < LooseVersion('0.24.0'):
            res = glob.glob(
                os.path.join(gcc_root, 'lib', 'gcc', '*', gcc_ver, 'include'))
            if res and len(res) == 1:
                gcc_lib_inc = res[0]
            else:
                raise EasyBuildError(
                    "Failed to pinpoint location of GCC include files: %s",
                    res)

            gcc_lib_inc_bis = os.path.join(os.path.dirname(gcc_lib_inc),
                                           'include-fixed')
            if not os.path.exists(gcc_lib_inc_bis):
                self.log.info(
                    "Derived directory %s does not exist, falling back to %s",
                    gcc_lib_inc_bis, gcc_lib_inc)
                gcc_lib_inc_bis = gcc_lib_inc

            gcc_cplusplus_inc = os.path.join(gcc_root, 'include', 'c++',
                                             gcc_ver)
            if not os.path.exists(gcc_cplusplus_inc):
                raise EasyBuildError("Derived directory %s does not exist",
                                     gcc_cplusplus_inc)

            regex_subs = [
                (r'-B/usr/bin', '-B%s' % os.path.join(binutils_root, 'bin')),
                (r'(cxx_builtin_include_directory:.*)/usr/lib/gcc',
                 r'\1%s' % gcc_lib_inc),
                (r'(cxx_builtin_include_directory:.*)/usr/local/include',
                 r'\1%s' % gcc_lib_inc_bis),
                (r'(cxx_builtin_include_directory:.*)/usr/include',
                 r'\1%s' % gcc_cplusplus_inc),
            ]
            for tool in ['ar', 'cpp', 'dwp', 'gcc', 'ld']:
                path = which(tool)
                if path:
                    regex_subs.append((os.path.join('/usr', 'bin',
                                                    tool), path))
                else:
                    raise EasyBuildError("Failed to determine path to '%s'",
                                         tool)

            apply_regex_substitutions(
                os.path.join('tools', 'cpp', 'CROSSTOOL'), regex_subs)
Beispiel #8
0
    def configure_intel_based(self):
        """Configure for Intel based toolchains"""

        # based on guidelines available at
        # http://software.intel.com/en-us/articles/build-cp2k-using-intel-fortran-compiler-professional-edition/
        intelurl = ''.join(["http://software.intel.com/en-us/articles/",
                            "build-cp2k-using-intel-fortran-compiler-professional-edition/"])

        options = self.configure_common()

        extrainc = ''
        if self.modincpath:
            extrainc = '-I%s' % self.modincpath

        options.update({
            # -Vaxlib : older options
            'FREE': '-fpp -free',

            # SAFE = -assume protect_parens -fp-model precise -ftz  # causes problems, so don't use this
            'SAFE': '-assume protect_parens -no-unroll-aggressive',

            'INCFLAGS': '$(DFLAGS) -I$(INTEL_INC) -I$(INTEL_INCF) %s' % extrainc,

            'LDFLAGS': '$(INCFLAGS) -i-static',
            'OBJECTS_ARCHITECTURE': 'machine_intel.o',
        })

        options['DFLAGS'] += ' -D__INTEL'

        optarch = ''
        if self.toolchain.options['optarch']:
            optarch = '-xHOST'

        options['FCFLAGSOPT'] += ' $(INCFLAGS) %s -heap-arrays 64' % optarch
        options['FCFLAGSOPT2'] += ' $(INCFLAGS) %s -heap-arrays 64' % optarch

        ifortver = LooseVersion(get_software_version('ifort'))
        failmsg = "CP2K won't build correctly with the Intel %%s compilers prior to %%s, see %s" % intelurl

        if ifortver >= LooseVersion("2011") and ifortver < LooseVersion("2012"):

            # don't allow using Intel compiler 2011 prior to release 8, because of known issue (see Intel URL)
            if ifortver >= LooseVersion("2011.8"):
                # add additional make instructions to Makefile
                self.make_instructions += "et_coupling.o: et_coupling.F\n\t$(FC) -c $(FCFLAGS2) $<\n"
                self.make_instructions += "qs_vxc_atom.o: qs_vxc_atom.F\n\t$(FC) -c $(FCFLAGS2) $<\n"

            else:
                raise EasyBuildError(failmsg, "v12", "v2011.8")

        elif ifortver >= LooseVersion("11"):
            if LooseVersion(get_software_version('ifort')) >= LooseVersion("11.1.072"):
                self.make_instructions += "qs_vxc_atom.o: qs_vxc_atom.F\n\t$(FC) -c $(FCFLAGS2) $<\n"

            else:
                raise EasyBuildError(failmsg, "v11", "v11.1.072")

        else:
            raise EasyBuildError("Intel compilers version %s not supported yet.", ifortver)

        return options
Beispiel #9
0
    def configure_common(self):
        """Common configuration for all toolchains"""

        # openmp introduces 2 major differences
        # -automatic is default: -noautomatic -auto-scalar
        # some mem-bandwidth optimisation
        if self.cfg['type'] == 'psmp':
            self.openmp = self.toolchain.get_flag('openmp')

        # determine which opt flags to use
        if self.cfg['typeopt']:
            optflags = 'OPT'
            regflags = 'OPT2'
        else:
            optflags = 'NOOPT'
            regflags = 'NOOPT'

        # make sure a MPI-2 able MPI lib is used
        mpi2 = False
        if hasattr(self.toolchain, 'MPI_FAMILY') and self.toolchain.MPI_FAMILY is not None:
            known_mpi2_fams = [toolchain.MPICH, toolchain.MPICH2, toolchain.MVAPICH2, toolchain.OPENMPI,
                               toolchain.INTELMPI]
            mpi_fam = self.toolchain.mpi_family()
            if mpi_fam in known_mpi2_fams:
                mpi2 = True
                self.log.debug("Determined MPI2 compatibility based on MPI toolchain component: %s" % mpi_fam)
            else:
                self.log.debug("Cannot determine MPI2 compatibility based on MPI toolchain component: %s" % mpi_fam)
        else:
            # can't use toolchain.mpi_family, because of dummy toolchain
            mpi2libs = ['impi', 'MVAPICH2', 'OpenMPI', 'MPICH2', 'MPICH']
            for mpi2lib in mpi2libs:
                if get_software_root(mpi2lib):
                    mpi2 = True
                    self.log.debug("Determined MPI2 compatibility based on loaded MPI module: %s")
                else:
                    self.log.debug("MPI-2 supporting MPI library %s not loaded.")

        if not mpi2:
            raise EasyBuildError("CP2K needs MPI-2, no known MPI-2 supporting library loaded?")

        options = {
            'CC': os.getenv('MPICC'),
            'CPP': '',
            'FC': '%s %s' % (os.getenv('MPIF90'), self.openmp),
            'LD': '%s %s' % (os.getenv('MPIF90'), self.openmp),
            'AR': 'ar -r',
            'CPPFLAGS': '',

            'FPIC': self.fpic,
            'DEBUG': self.debug,

            'FCFLAGS': '$(FCFLAGS%s)' % optflags,
            'FCFLAGS2': '$(FCFLAGS%s)' % regflags,

            'CFLAGS': ' %s %s $(FPIC) $(DEBUG) %s ' % (os.getenv('CPPFLAGS'), os.getenv('LDFLAGS'),
                                                       self.cfg['extracflags']),
            'DFLAGS': ' -D__parallel -D__BLACS -D__SCALAPACK -D__FFTSG %s' % self.cfg['extradflags'],

            'LIBS': os.getenv('LIBS', ''),

            'FCFLAGSNOOPT': '$(DFLAGS) $(CFLAGS) -O0  $(FREE) $(FPIC) $(DEBUG)',
            'FCFLAGSOPT': '-O2 $(FREE) $(SAFE) $(FPIC) $(DEBUG)',
            'FCFLAGSOPT2': '-O1 $(FREE) $(SAFE) $(FPIC) $(DEBUG)'
        }

        libint = get_software_root('LibInt')
        if libint:
            options['DFLAGS'] += ' -D__LIBINT'

            libintcompiler = "%s %s" % (os.getenv('CC'), os.getenv('CFLAGS'))

            # Build libint-wrapper, if required
            libint_wrapper = ''

            # required for old versions of GCC
            if not self.compilerISO_C_BINDING:
                options['DFLAGS'] += ' -D__HAS_NO_ISO_C_BINDING'

                # determine path for libint_tools dir
                libinttools_paths = ['libint_tools', 'tools/hfx_tools/libint_tools']
                libinttools_path = None
                for path in libinttools_paths:
                    path = os.path.join(self.cfg['start_dir'], path)
                    if os.path.isdir(path):
                        libinttools_path = path
                        os.chdir(libinttools_path)
                if not libinttools_path:
                    raise EasyBuildError("No libinttools dir found")

                # build libint wrapper
                cmd = "%s -c libint_cpp_wrapper.cpp -I%s/include" % (libintcompiler, libint)
                if not run_cmd(cmd, log_all=True, simple=True):
                    raise EasyBuildError("Building the libint wrapper failed")
                libint_wrapper = '%s/libint_cpp_wrapper.o' % libinttools_path

            # determine LibInt libraries based on major version number
            libint_maj_ver = get_software_version('LibInt').split('.')[0]
            if libint_maj_ver == '1':
                libint_libs = "$(LIBINTLIB)/libderiv.a $(LIBINTLIB)/libint.a $(LIBINTLIB)/libr12.a"
            elif libint_maj_ver == '2':
                libint_libs = "$(LIBINTLIB)/libint2.a"
            else:
                raise EasyBuildError("Don't know how to handle libint version %s", libint_maj_ver)
            self.log.info("Using LibInt version %s" % (libint_maj_ver))

            options['LIBINTLIB'] = '%s/lib' % libint
            options['LIBS'] += ' %s -lstdc++ %s' % (libint_libs, libint_wrapper)

        else:
            # throw a warning, since CP2K without LibInt doesn't make much sense
            self.log.warning("LibInt module not loaded, so building without LibInt support")


        libxc = get_software_root('libxc')
        if libxc:
            cur_libxc_version = get_software_version('libxc')
            if LooseVersion(cur_libxc_version) < LooseVersion(LIBXC_MIN_VERSION):
                raise EasyBuildError("CP2K only works with libxc v%s (or later)", LIBXC_MIN_VERSION)

            options['DFLAGS'] += ' -D__LIBXC2'
            if LooseVersion(cur_libxc_version) >= LooseVersion('2.2'):
                options['LIBS'] += ' -L%s/lib -lxcf90 -lxc' % libxc
            else:
                options['LIBS'] += ' -L%s/lib -lxc' % libxc
            self.log.info("Using Libxc-%s" % cur_libxc_version)
        else:
            self.log.info("libxc module not loaded, so building without libxc support")

        return options
Beispiel #10
0
    def configure_step(self):
        """Configure build
        - build Libint wrapper
        - generate Makefile
        """

        known_types = ['popt', 'psmp']
        if self.cfg['type'] not in known_types:
            raise EasyBuildError("Unknown build type specified: '%s', known types are %s",
                                 self.cfg['type'], known_types)

        # correct start dir, if needed
        # recent CP2K versions have a 'cp2k' dir in the unpacked 'cp2k' dir
        cp2k_path = os.path.join(self.cfg['start_dir'], 'cp2k')
        if os.path.exists(cp2k_path):
            self.cfg['start_dir'] = cp2k_path
            self.log.info("Corrected start_dir to %s" % self.cfg['start_dir'])

        # set compilers options according to toolchain config
        # full debug: -g -traceback -check all -fp-stack-check
        # -g links to mpi debug libs
        if self.toolchain.options['debug']:
            self.debug = '-g'
            self.log.info("Debug build")
        if self.toolchain.options['pic']:
            self.fpic = "-fPIC"
            self.log.info("Using fPIC")

        # report on extra flags being used
        if self.cfg['extracflags']:
            self.log.info("Using extra CFLAGS: %s" % self.cfg['extracflags'])
        if self.cfg['extradflags']:
            self.log.info("Using extra CFLAGS: %s" % self.cfg['extradflags'])

        # lib(x)smm support
        libsmm = get_software_root('libsmm')
        libxsmm = get_software_root('libxsmm')
        if libxsmm:
            self.cfg.update('extradflags', '-D__LIBXSMM')
            self.libsmm = '-lxsmm'
            self.log.debug('Using libxsmm %s' % libxsmm)
        elif libsmm:
            libsmms = glob.glob(os.path.join(libsmm, 'lib', 'libsmm_*nn.a'))
            dfs = [os.path.basename(os.path.splitext(x)[0]).replace('lib', '-D__HAS_') for x in libsmms]
            moredflags = ' ' + ' '.join(dfs)
            self.cfg.update('extradflags', moredflags)
            self.libsmm = ' '.join(libsmms)
            self.log.debug('Using libsmm %s (extradflags %s)' % (self.libsmm, moredflags))

        # obtain list of modinc's to use
        if self.cfg["modinc"]:
            self.modincpath = self.prepmodinc()

        # set typearch
        self.typearch = "Linux-x86-64-%s" % self.toolchain.name

        # extra make instructions
        self.make_instructions = ''  # "graphcon.o: graphcon.F\n\t$(FC) -c $(FCFLAGS2) $<\n"

        # compiler toolchain specific configuration
        comp_fam = self.toolchain.comp_family()
        if comp_fam == toolchain.INTELCOMP:
            options = self.configure_intel_based()
        elif comp_fam == toolchain.GCC:
            options = self.configure_GCC_based()
        else:
            raise EasyBuildError("Don't know how to tweak configuration for compiler family %s" % comp_fam)

        # BLAS/FFTW
        if get_software_root('IMKL'):
            options = self.configure_MKL(options)
        else:
            # BLAS
            if get_software_root('ACML'):
                options = self.configure_ACML(options)
            else:
                options = self.configure_BLAS_lib(options)

            # FFTW (no MKL involved)
            if 'fftw3' in os.getenv('LIBFFT', ''):
                options = self.configure_FFTW3(options)

        # LAPACK
        if os.getenv('LIBLAPACK_MT', None) is not None:
            options = self.configure_LAPACK(options)

        if os.getenv('LIBSCALAPACK', None) is not None:
            options = self.configure_ScaLAPACK(options)

        # PLUMED
        if self.cfg["plumed"]:
            if not get_software_root('PLUMED'):
                raise EasyBuildError("The PLUMED module needs to be loaded to build CP2K with PLUMED support")
            options['LIBS'] += ' -lplumed'
            options['DFLAGS'] += ' -D__PLUMED2'

        # CUDA
        cuda = get_software_root('CUDA')
        if cuda:
            options['DFLAGS'] += ' -D__ACC -D__DBCSR_ACC'
            options['LIBS'] += ' -lcudart -lcublas -lcufft -lrt'
            options['NVCC'] = ' nvcc'

        # avoid group nesting
        options['LIBS'] = options['LIBS'].replace('-Wl,--start-group', '').replace('-Wl,--end-group', '')

        options['LIBS'] = "-Wl,--start-group %s -Wl,--end-group" % options['LIBS']

        # create arch file using options set
        archfile = os.path.join(self.cfg['start_dir'], 'arch',
                                '%s.%s' % (self.typearch, self.cfg['type']))
        try:
            txt = self._generate_makefile(options)
            f = open(archfile, 'w')
            f.write(txt)
            f.close()
            self.log.info("Content of makefile (%s):\n%s" % (archfile, txt))
        except IOError, err:
            raise EasyBuildError("Writing makefile %s failed: %s", archfile, err)
Beispiel #11
0
                raise EasyBuildError("F77 environment variable not set, can't continue.")

            # create modinc files
            for f in modfiles:
                if f77.endswith('ifort'):
                    cmd = "%s -module %s -c %s" % (f77, modincpath, f)
                elif f77 in ['gfortran', 'mpif77']:
                    cmd = "%s -J%s -c %s" % (f77, modincpath, f)
                else:
                    raise EasyBuildError("prepmodinc: Unknown value specified for F77 (%s)", f77)

                run_cmd(cmd, log_all=True, simple=True)

            return modincpath
        else:
            raise EasyBuildError("Don't know how to prepare modinc, IMKL not found")

    def configure_common(self):
        """Common configuration for all toolchains"""

        # openmp introduces 2 major differences
        # -automatic is default: -noautomatic -auto-scalar
        # some mem-bandwidth optimisation
        if self.cfg['type'] == 'psmp':
            self.openmp = self.toolchain.get_flag('openmp')

        # determine which opt flags to use
        if self.cfg['typeopt']:
            optflags = 'OPT'
            regflags = 'OPT2'
        else: