diff options
author | Michael Hirsch, Ph.D <scivision@users.noreply.github.com> | 2019-11-30 22:16:40 -0500 |
---|---|---|
committer | Michael Hirsch, Ph.D <scivision@users.noreply.github.com> | 2019-11-30 22:16:40 -0500 |
commit | e209dd2607c775cf8705c3b6ef70389c85a782e3 (patch) | |
tree | 962ecb1ce6d7c7a4f26ebf1957969a8572f6bbf5 | |
parent | 3120481d7757760ab3f8d81c5848f55e95603182 (diff) | |
download | meson-e209dd2607c775cf8705c3b6ef70389c85a782e3.zip meson-e209dd2607c775cf8705c3b6ef70389c85a782e3.tar.gz meson-e209dd2607c775cf8705c3b6ef70389c85a782e3.tar.bz2 |
scalapack: allow specifying find method
-rw-r--r-- | mesonbuild/dependencies/scalapack.py | 173 | ||||
-rw-r--r-- | test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake | 223 | ||||
-rw-r--r-- | test cases/frameworks/30 scalapack/meson.build | 2 |
3 files changed, 311 insertions, 87 deletions
diff --git a/mesonbuild/dependencies/scalapack.py b/mesonbuild/dependencies/scalapack.py index 4057091..36bfd66 100644 --- a/mesonbuild/dependencies/scalapack.py +++ b/mesonbuild/dependencies/scalapack.py @@ -16,106 +16,105 @@ from pathlib import Path import os from .. import mesonlib -from .base import (CMakeDependency, ExternalDependency, PkgConfigDependency) +from .base import CMakeDependency, DependencyMethods, ExternalDependency, PkgConfigDependency class ScalapackDependency(ExternalDependency): def __init__(self, environment, kwargs: dict): - language = kwargs.get('language') - super().__init__('scalapack', environment, language, kwargs) + methods = mesonlib.listify(kwargs.get('method', 'auto')) + super().__init__('scalapack', environment, None, kwargs) kwargs['required'] = False kwargs['silent'] = True self.is_found = False self.static = kwargs.get('static', False) - # 1. try pkg-config - pkgconfig_files = [] - mklroot = None - is_gcc = None - if language == 'fortran': - is_gcc = environment.detect_fortran_compiler(self.for_machine).get_id() == 'gcc' - elif language == 'c': - is_gcc = environment.detect_c_compiler(self.for_machine).get_id() == 'gcc' - elif language == 'cpp': - is_gcc = environment.detect_cpp_compiler(self.for_machine).get_id() == 'gcc' - # Intel MKL works with non-Intel compilers too -- but not gcc on windows - if 'MKLROOT' in os.environ and not (mesonlib.is_windows() and is_gcc): - try: - mklroot = Path(os.environ['MKLROOT']).resolve() - except Exception: - pass - if mklroot is not None: - # MKL pkg-config is a start, but you have to add / change stuff - # https://software.intel.com/en-us/articles/intel-math-kernel-library-intel-mkl-and-pkg-config-tool - pkgconfig_files = ( - ['mkl-static-lp64-iomp'] if self.static else ['mkl-dynamic-lp64-iomp'] - ) - if mesonlib.is_windows(): - suffix = '.lib' - elif self.static: - suffix = '.a' - else: - suffix = '' - libdir = mklroot / 'lib/intel64' - # Intel compiler might not have Parallel Suite - pkgconfig_files += ['scalapack-openmpi', 'scalapack'] + if set(methods).intersection(['auto', 'pkg-config']): + pkgconfig_files = [] + mklroot = None + is_gcc = self.clib_compiler.get_id() == 'gcc' + # Intel MKL works with non-Intel compilers too -- but not gcc on windows + if 'MKLROOT' in os.environ and not (mesonlib.is_windows() and is_gcc): + try: + mklroot = Path(os.environ['MKLROOT']).resolve() + except Exception: + pass + if mklroot is not None: + # MKL pkg-config is a start, but you have to add / change stuff + # https://software.intel.com/en-us/articles/intel-math-kernel-library-intel-mkl-and-pkg-config-tool + pkgconfig_files = ( + ['mkl-static-lp64-iomp'] if self.static else ['mkl-dynamic-lp64-iomp'] + ) + if mesonlib.is_windows(): + suffix = '.lib' + elif self.static: + suffix = '.a' + else: + suffix = '' + libdir = mklroot / 'lib/intel64' + # Intel compiler might not have Parallel Suite + pkgconfig_files += ['scalapack-openmpi', 'scalapack'] - for pkg in pkgconfig_files: - pkgdep = PkgConfigDependency( - pkg, environment, kwargs, language=self.language - ) - if pkgdep.found(): - self.compile_args = pkgdep.get_compile_args() - if mklroot: - link_args = pkgdep.get_link_args() - if is_gcc: - for i, a in enumerate(link_args): - if 'mkl_intel_lp64' in a: - link_args[i] = a.replace('intel', 'gf') + for pkg in pkgconfig_files: + pkgdep = PkgConfigDependency( + pkg, environment, kwargs, language=self.language + ) + if pkgdep.found(): + self.compile_args = pkgdep.get_compile_args() + if mklroot: + link_args = pkgdep.get_link_args() + if is_gcc: + for i, a in enumerate(link_args): + if 'mkl_intel_lp64' in a: + link_args[i] = a.replace('intel', 'gf') + break + # MKL pkg-config omits scalapack + # be sure "-L" and "-Wl" are first if present + i = 0 + for j, a in enumerate(link_args): + if a.startswith(('-L', '-Wl')): + i = j + 1 + elif j > 3: break - # MKL pkg-config omits scalapack - # be sure "-L" and "-Wl" are first if present - i = 0 - for j, a in enumerate(link_args): - if a.startswith(('-L', '-Wl')): - i = j + 1 - elif j > 3: - break - if mesonlib.is_windows() or self.static: - link_args.insert( - i, str(libdir / ('mkl_scalapack_lp64' + suffix)) - ) - link_args.insert( - i + 1, str(libdir / ('mkl_blacs_intelmpi_lp64' + suffix)) - ) + if mesonlib.is_windows() or self.static: + link_args.insert( + i, str(libdir / ('mkl_scalapack_lp64' + suffix)) + ) + link_args.insert( + i + 1, str(libdir / ('mkl_blacs_intelmpi_lp64' + suffix)) + ) + else: + link_args.insert(i, '-lmkl_scalapack_lp64') + link_args.insert(i + 1, '-lmkl_blacs_intelmpi_lp64') else: - link_args.insert(i, '-lmkl_scalapack_lp64') - link_args.insert(i + 1, '-lmkl_blacs_intelmpi_lp64') - else: - link_args = pkgdep.get_link_args() - self.link_args = link_args + link_args = pkgdep.get_link_args() + self.link_args = link_args - self.version = pkgdep.get_version() - if self.version == 'unknown' and mklroot: - try: - v = ( - mklroot.as_posix() - .split('compilers_and_libraries_')[1] - .split('/', 1)[0] - ) - if v: - self.version = v - except IndexError: - pass + self.version = pkgdep.get_version() + if self.version == 'unknown' and mklroot: + try: + v = ( + mklroot.as_posix() + .split('compilers_and_libraries_')[1] + .split('/', 1)[0] + ) + if v: + self.version = v + except IndexError: + pass + self.is_found = True + self.pcdep = pkgdep + return + + if set(methods).intersection(['auto', 'cmake']): + cmakedep = CMakeDependency('Scalapack', environment, kwargs) + if cmakedep.found(): + self.compile_args = cmakedep.get_compile_args() + self.link_args = cmakedep.get_link_args() + self.version = cmakedep.get_version() self.is_found = True - self.pcdep = pkgdep return - # 2. try CMake - cmakedep = CMakeDependency('Scalapack', environment, kwargs) - if cmakedep.found(): - self.compile_args = cmakedep.get_compile_args() - self.link_args = cmakedep.get_link_args() - self.version = cmakedep.get_version() - self.is_found = True - return + + @staticmethod + def get_methods(): + return [DependencyMethods.AUTO, DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE] diff --git a/test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake b/test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake new file mode 100644 index 0000000..d67ff7a --- /dev/null +++ b/test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake @@ -0,0 +1,223 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: + +FindSCALAPACK +------------- + +* Michael Hirsch, Ph.D. www.scivision.dev + +Let Michael know if there are more MKL / Lapack / compiler combination you want. +Refer to https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor + +Finds SCALAPACK libraries for MKL, OpenMPI and MPICH. +Intel MKL relies on having environment variable MKLROOT set, typically by sourcing +mklvars.sh beforehand. + +This also uses our FindLAPACK.cmake to deduplicate code. + + +Parameters +^^^^^^^^^^ + +``MKL`` + Intel MKL for MSVC, ICL, ICC, GCC and PGCC. Working with IntelMPI (default Window, Linux), MPICH (default Mac) or OpenMPI (Linux only). + +``IntelMPI`` + MKL BLACS IntelMPI + +``MKL64`` + MKL only: 64-bit integers (default is 32-bit integers) + +``OpenMPI`` + SCALAPACK + OpenMPI + +``MPICH`` + SCALAPACK + MPICH + + +Result Variables +^^^^^^^^^^^^^^^^ + +``SCALAPACK_FOUND`` + SCALapack libraries were found +``SCALAPACK_<component>_FOUND`` + SCALAPACK <component> specified was found +``SCALAPACK_LIBRARIES`` + SCALapack library files +``SCALAPACK_INCLUDE_DIRS`` + SCALapack include directories + + +References +^^^^^^^^^^ + +* Pkg-Config and MKL: https://software.intel.com/en-us/articles/intel-math-kernel-library-intel-mkl-and-pkg-config-tool +* MKL for Windows: https://software.intel.com/en-us/mkl-windows-developer-guide-static-libraries-in-the-lib-intel64-win-directory +* MKL Windows directories: https://software.intel.com/en-us/mkl-windows-developer-guide-high-level-directory-structure +#]=======================================================================] + +#===== functions +function(mkl_scala) + +set(_mkl_libs ${ARGV}) + +foreach(s ${_mkl_libs}) + find_library(SCALAPACK_${s}_LIBRARY + NAMES ${s} + PATHS ENV MKLROOT ENV I_MPI_ROOT ENV TBBROOT + PATH_SUFFIXES + lib/intel64 lib/intel64_win + intel64/lib/release + lib/intel64/gcc4.7 ../tbb/lib/intel64/gcc4.7 + lib/intel64/vc_mt ../tbb/lib/intel64/vc_mt + ../compiler/lib/intel64 + HINTS ${MKL_LIBRARY_DIRS} ${MKL_LIBDIR} + NO_DEFAULT_PATH) + if(NOT SCALAPACK_${s}_LIBRARY) + message(WARNING "MKL component not found: " ${s}) + return() + endif() + + list(APPEND SCALAPACK_LIB ${SCALAPACK_${s}_LIBRARY}) +endforeach() + + +find_path(SCALAPACK_INCLUDE_DIR + NAMES mkl_scalapack.h + PATHS ENV MKLROOT ENV I_MPI_ROOT ENV TBBROOT + PATH_SUFFIXES + include + include/intel64/${_mkl_bitflag}lp64 + HINTS ${MKL_INCLUDE_DIRS}) + +if(NOT SCALAPACK_INCLUDE_DIR) + message(WARNING "MKL Include Dir not found") + return() +endif() + +list(APPEND SCALAPACK_INCLUDE_DIR + ${MKL_INCLUDE_DIRS}) + +set(SCALAPACK_LIBRARY ${SCALAPACK_LIB} PARENT_SCOPE) +set(SCALAPACK_INCLUDE_DIR ${SCALAPACK_INCLUDE_DIR} PARENT_SCOPE) + +endfunction(mkl_scala) + +#==== main program + +cmake_policy(VERSION 3.11) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12) + cmake_policy(SET CMP0074 NEW) + cmake_policy(SET CMP0075 NEW) +endif() + +if(NOT (OpenMPI IN_LIST SCALAPACK_FIND_COMPONENTS + OR MPICH IN_LIST SCALAPACK_FIND_COMPONENTS + OR MKL IN_LIST SCALAPACK_FIND_COMPONENTS)) + if(DEFINED ENV{MKLROOT}) + if(APPLE) + list(APPEND SCALAPACK_FIND_COMPONENTS MKL MPICH) + else() + list(APPEND SCALAPACK_FIND_COMPONENTS MKL IntelMPI) + endif() + else() + list(APPEND SCALAPACK_FIND_COMPONENTS OpenMPI) + endif() +endif() + +find_package(PkgConfig) + +if(NOT WIN32) + find_package(Threads) # not required--for example Flang +endif() + +if(MKL IN_LIST SCALAPACK_FIND_COMPONENTS) + + if(BUILD_SHARED_LIBS) + set(_mkltype dynamic) + else() + set(_mkltype static) + endif() + + if(MKL64 IN_LIST SCALAPACK_FIND_COMPONENTS) + set(_mkl_bitflag i) + else() + set(_mkl_bitflag) + endif() + + + if(WIN32) + set(_impi impi) + else() + unset(_impi) + endif() + + + pkg_check_modules(MKL mkl-${_mkltype}-${_mkl_bitflag}lp64-iomp) + + if(OpenMPI IN_LIST SCALAPACK_FIND_COMPONENTS) + mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_openmpi_${_mkl_bitflag}lp64) + if(SCALAPACK_LIBRARY) + set(SCALAPACK_OpenMPI_FOUND true) + endif() + elseif(MPICH IN_LIST SCALAPACK_FIND_COMPONENTS) + if(APPLE) + mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_mpich_${_mkl_bitflag}lp64) + elseif(WIN32) + mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_mpich2_${_mkl_bitflag}lp64.lib mpi.lib fmpich2.lib) + else() # linux, yes it's just like IntelMPI + mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_intelmpi_${_mkl_bitflag}lp64) + endif() + if(SCALAPACK_LIBRARY) + set(SCALAPACK_MPICH_FOUND true) + endif() + else() # IntelMPI + mkl_scala(mkl_scalapack_${_mkl_bitflag}lp64 mkl_blacs_intelmpi_${_mkl_bitflag}lp64 ${_impi}) + if(SCALAPACK_LIBRARY) + set(SCALAPACK_IntelMPI_FOUND true) + endif() + endif() + + if(SCALAPACK_LIBRARY) + set(SCALAPACK_MKL_FOUND true) + endif() + +elseif(OpenMPI IN_LIST SCALAPACK_FIND_COMPONENTS) + + pkg_check_modules(SCALAPACK scalapack-openmpi) + + find_library(SCALAPACK_LIBRARY + NAMES scalapack scalapack-openmpi + HINTS ${SCALAPACK_LIBRARY_DIRS} ${SCALAPACK_LIBDIR}) + + if(SCALAPACK_LIBRARY) + set(SCALAPACK_OpenMPI_FOUND true) + endif() + +elseif(MPICH IN_LIST SCALAPACK_FIND_COMPONENTS) + find_library(SCALAPACK_LIBRARY + NAMES scalapack-mpich scalapack-mpich2) + + if(SCALAPACK_LIBRARY) + set(SCALAPACK_MPICH_FOUND true) + endif() + +endif() + +# Finalize + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + SCALAPACK + REQUIRED_VARS SCALAPACK_LIBRARY + HANDLE_COMPONENTS) + +if(SCALAPACK_FOUND) + set(SCALAPACK_LIBRARIES ${SCALAPACK_LIBRARY}) + set(SCALAPACK_INCLUDE_DIRS ${SCALAPACK_INCLUDE_DIR}) +endif() + +mark_as_advanced(SCALAPACK_LIBRARY SCALAPACK_INCLUDE_DIR) diff --git a/test cases/frameworks/30 scalapack/meson.build b/test cases/frameworks/30 scalapack/meson.build index 430f54f..afef674 100644 --- a/test cases/frameworks/30 scalapack/meson.build +++ b/test cases/frameworks/30 scalapack/meson.build @@ -25,3 +25,5 @@ if add_languages('fortran') dependencies: [scalapack, mpi_f]) test('scalapack_fortran', f_exe, timeout: 30) endif + +scalapack_cmake = dependency('scalapack', method: 'cmake', cmake_module_path: 'cmake', required: false) |