aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hirsch, Ph.D <scivision@users.noreply.github.com>2019-11-30 22:16:40 -0500
committerMichael Hirsch, Ph.D <scivision@users.noreply.github.com>2019-11-30 22:16:40 -0500
commite209dd2607c775cf8705c3b6ef70389c85a782e3 (patch)
tree962ecb1ce6d7c7a4f26ebf1957969a8572f6bbf5
parent3120481d7757760ab3f8d81c5848f55e95603182 (diff)
downloadmeson-e209dd2607c775cf8705c3b6ef70389c85a782e3.zip
meson-e209dd2607c775cf8705c3b6ef70389c85a782e3.tar.gz
meson-e209dd2607c775cf8705c3b6ef70389c85a782e3.tar.bz2
scalapack: allow specifying find method
-rw-r--r--mesonbuild/dependencies/scalapack.py173
-rw-r--r--test cases/frameworks/30 scalapack/cmake/FindSCALAPACK.cmake223
-rw-r--r--test cases/frameworks/30 scalapack/meson.build2
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)