diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 0000000..108f8b6 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,240 @@ +name: CMake + +on: [pull_request] + + +jobs: + linux-check-all-libs: + runs-on: ubuntu-18.04 + strategy: + matrix: + linalg_lib: [blis,openblas,netlib,intel-mkl] + mpi_dist: [mpich,openmpi] + int_interface: [lp64,ilp64] + thread: [sequential,openmp,pthreads,tbb] + exclude: + - linalg_lib: netlib + int_interface: ilp64 + - linalg_lib: netlib + thread: pthreads + - linalg_lib: netlib + thread: openmp + - linalg_lib: intel-mkl + thread: pthreads + - linalg_lib: netlib + mpi_dist: openmpi + - linalg_lib: blis + mpi_dist: openmpi + - linalg_lib: openblas + mpi_dist: openmpi + - linalg_lib: blis + thread: tbb + - linalg_lib: openblas + thread: tbb + - linalg_lib: netlib + thread: tbb + env: + MKLROOT: /opt/intel/mkl + CMAKE_PREFIX_PATH: '/home/software/install/${{matrix.linalg_lib}}-${{matrix.int_interface}}-${{matrix.thread}};/home/software/install/netlib-lp64-sequential' + + steps: + - uses: actions/checkout@v2 + + - name: Ubuntu Setup + run: | + sudo apt-get -yq update && sudo apt-get install make wget curl libomp5 + sudo make -C .github/workflows/linalg install/main + sudo make -C .github/workflows/linalg install/cmake + sudo apt-get clean + sudo make -C .github/workflows/linalg apt-add-repository/intel-mkl + + - name: Setup MPI + run: | + sudo make -C .github/workflows/linalg install/${{matrix.mpi_dist}} + which mpicc + + - name: Setup TBB + if: ${{matrix.thread == 'tbb'}} + run: | + sudo apt-get install libtbb-dev + + + - name: Build Linalg + env: + BUILD_TARGET: ${{matrix.linalg_lib}}/${{matrix.int_interface}}-${{matrix.thread}} + run: | + sudo make -C .github/workflows/linalg download/${{matrix.linalg_lib}} + sudo make -C .github/workflows/linalg install/${BUILD_TARGET} + + - name: Add-On NETLIB + # Disable for + # - MKL b/c MKL already has a LAPACK/ScaLAPACK linker + # - NETLIB b/c the NETLIB is already the used linear algebra lib (no need to add on) + # - ILP64 b/c NETLIB isn't reliable for ILP64 yet + if: ${{ matrix.linalg_lib != 'intel-mkl' && matrix.linalg_lib != 'netlib' && matrix.int_interface == 'lp64' }} + run: | + sudo make -C .github/workflows/linalg download/netlib + sudo make -C .github/workflows/linalg install/netlib/lp64-sequential + + + + - name: FindBLAS Default + # Disable for MKL-ILP64 b/c the default is LP64 unless otherwise specified + if: ${{ matrix.linalg_lib != 'intel-mkl' || matrix.int_interface != 'ilp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/blas/default \ + -B${{runner.workspace}}/build-findblas-default \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_blas_cmake_cache.sh \ + ${{runner.workspace}}/build-findblas-default \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + - name: FindBLAS Integer Specific + run: | + cmake -H${GITHUB_WORKSPACE}/examples/blas/${{matrix.int_interface}} \ + -B${{runner.workspace}}/build-findblas-${{matrix.int_interface}} \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_blas_cmake_cache.sh \ + ${{runner.workspace}}/build-findblas-${{matrix.int_interface}} \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + - name: FindBLAS Static Linkage + run: | + cmake -H${GITHUB_WORKSPACE}/examples/blas/${{matrix.int_interface}} \ + -B${{runner.workspace}}/build-findblas-static \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=${{matrix.thread}} \ + -DBLAS_PREFERS_STATIC=ON + .github/workflows/scripts/check_blas_cmake_cache.sh \ + ${{runner.workspace}}/build-findblas-static \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + - name: FindBLAS Static Linkage (Error Output) + if: ${{ failure() }} + run: | + echo "CMAKE OUTPUT" && cat ${{runner.workspace}}/build-findblas-static/CMakeFiles/CMakeOutput.log + echo "CMAKE ERROR" && cat ${{runner.workspace}}/build-findblas-static/CMakeFiles/CMakeError.log + + + - name: FindLAPACK Default + # Disable for + # - BLIS-ILP64 b/c BLIS doesn't have a LAPACK linker and NETLIB is not tested for ILP64 + # - MKL-ILP64 b/c the default is LP64 unless otherwise specified + if: ${{ (matrix.linalg_lib != 'blis' && matrix.linalg_lib != 'intel-mkl') || matrix.int_interface != 'ilp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/lapack/default \ + -B${{runner.workspace}}/build-findlapack-default \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DLAPACK_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_lapack_cmake_cache.sh \ + ${{runner.workspace}}/build-findlapack-default \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + - name: FindLAPACK Integer Specific + # Disable for BLIS-ILP64 b/c BLIS doesn't have a LAPACK linker and NETLIB is not tested for ILP64 + if: ${{ matrix.linalg_lib != 'blis' || matrix.int_interface != 'ilp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/lapack/${{matrix.int_interface}} \ + -B${{runner.workspace}}/build-findlapack-${{matrix.int_interface}} \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DLAPACK_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_lapack_cmake_cache.sh \ + ${{runner.workspace}}/build-findlapack-${{matrix.int_interface}} \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + - name: FindLAPACK Static Linkage + if: ${{ matrix.linalg_lib != 'blis' || matrix.int_interface != 'ilp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/lapack/${{matrix.int_interface}} \ + -B${{runner.workspace}}/build-findlapack-static \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DLAPACK_THREAD_LAYER=${{matrix.thread}} \ + -DLAPACK_PREFERS_STATIC=ON + .github/workflows/scripts/check_lapack_cmake_cache.sh \ + ${{runner.workspace}}/build-findlapack-static \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} + + + - name: FindScaLAPACK Default + # Disable for + # - Non-MKL-ILP64 b/c NETLIB can't handle ILP64 consist + # - MKL-ILP64 b/c the default is LP64 unless otherwise specified + if: ${{ (matrix.linalg_lib == 'intel-mkl' && matrix.int_interface == 'lp64') || matrix.int_interface == 'lp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/scalapack/default \ + -B${{runner.workspace}}/build-findscalapack-default \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_scalapack_cmake_cache.sh \ + ${{runner.workspace}}/build-findscalapack-default \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} ${{matrix.mpi_dist}} + + - name: FindScaLAPACK Integer Specific + # Disable for + # - Non-MKL-ILP64 b/c NETLIB can't handle ILP64 consist + if: ${{ matrix.linalg_lib == 'intel-mkl' || matrix.int_interface == 'lp64' }} + run: | + cmake -H${GITHUB_WORKSPACE}/examples/scalapack/${{matrix.int_interface}} \ + -B${{runner.workspace}}/build-findscalapack-${{matrix.int_interface}} \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=${{matrix.thread}} + .github/workflows/scripts/check_scalapack_cmake_cache.sh \ + ${{runner.workspace}}/build-findscalapack-${{matrix.int_interface}} \ + ${{matrix.linalg_lib}} ${{matrix.thread}} ${{matrix.int_interface}} ${{matrix.mpi_dist}} + + check-kitware-compatability: + runs-on: ubuntu-18.04 + env: + MKLROOT: /opt/intel/mkl + CMAKE_PREFIX_PATH: '/home/software/install/blis-lp64-sequential;/home/software/install/netlib-lp64-sequential' + steps: + - uses: actions/checkout@v2 + + - name: Ubuntu Setup + run: | + sudo apt-get -yq update && sudo apt-get install make wget curl libomp5 + sudo make -C .github/workflows/linalg install/main + sudo make -C .github/workflows/linalg install/cmake + sudo apt-get clean + sudo make -C .github/workflows/linalg apt-add-repository/intel-mkl + + - name: Build Linalg + run: | + sudo make -C .github/workflows/linalg download/intel-mkl + sudo make -C .github/workflows/linalg install/intel-mkl + sudo make -C .github/workflows/linalg download/blis + sudo make -C .github/workflows/linalg install/blis/lp64-sequential + + - name: Check BLA_STATIC + run: | + cmake -H${GITHUB_WORKSPACE}/examples/blas/lp64 \ + -B${{runner.workspace}}/check-bla-static \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=sequential \ + -DBLA_STATIC=ON + .github/workflows/scripts/check_blas_cmake_cache.sh \ + ${{runner.workspace}}/check-bla-static \ + intel-mkl sequential lp64 + + - name: Check BLA_VENDOR + run: | + cmake -H${GITHUB_WORKSPACE}/examples/blas/lp64 \ + -B${{runner.workspace}}/check-bla-vendor \ + -DCMAKE_MODULE_PATH=${GITHUB_WORKSPACE} \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBLAS_THREAD_LAYER=sequential \ + -DBLA_VENDOR="BLIS" + .github/workflows/scripts/check_blas_cmake_cache.sh \ + ${{runner.workspace}}/check-bla-vendor \ + blis sequential lp64 diff --git a/.github/workflows/linalg/Makefile b/.github/workflows/linalg/Makefile new file mode 100644 index 0000000..4836b3d --- /dev/null +++ b/.github/workflows/linalg/Makefile @@ -0,0 +1,179 @@ +ubuntu_codename ?= $(shell lsb_release -sc) +clang_version ?= 9 +mpich_version ?= 3.3 +openmpi_version ?= 4.1.0 +software_prefix := /home/software + +export DEBIAN_FRONTEND=noninteractive + +ubuntu_release = $(shell lsb_release -sr) + + +intel_mkl_version ?= 2020.4-304 +intel_mkl := intel-mkl-\*-${intel_mkl_version} + +install/main: + apt-get update + apt-get -yq install \ + lsb-release coreutils sudo bash-completion \ + apt-transport-https software-properties-common ca-certificates gnupg \ + build-essential wget curl \ + git make ninja-build \ + gcc g++ gfortran gdb valgrind \ + libunwind-dev libomp-dev \ + vim + +install/g++-%: + apt-get -yq install gcc-$* g++-$* gfortran-$* + +# CMake +install/cmake: + wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc | apt-key add - + apt-add-repository "deb https://apt.kitware.com/ubuntu/ ${ubuntu_codename} main" + apt-get -yq update + apt-get -yq install cmake + + +# LLVM +install/clang-%: + wget https://apt.llvm.org/llvm-snapshot.gpg.key -O - | apt-key add - + add-apt-repository "deb http://apt.llvm.org/${ubuntu_codename}/ llvm-toolchain-${ubuntu_codename}-$* main" + apt-get -yq update + apt-get -yq install clang-$* + +install/clang: install/clang-${clang_version} + + +# MPICH +#download/mpich: +# mkdir -p ${software_prefix}/src/mpich +# cd ${software_prefix}/src/mpich && wget --no-check-certificate -q http://www.mpich.org/static/downloads/${mpich_version}/mpich-${mpich_version}.tar.gz +# cd ${software_prefix}/src/mpich && tar xzf mpich-${mpich_version}.tar.gz +# +#install/mpich: +# cd ${software_prefix}/src/mpich/mpich-${mpich_version} && CC=gcc CXX=g++ FC=gfortran ./configure --prefix=${software_prefix}/install/mpich +# make -C ${software_prefix}/src/mpich/mpich-${mpich_version} install +install/mpich: + apt-get install -yq libmpich-dev + +# OpenMPI +#download/openmpi: +# mkdir -p ${software_prefix}/src/openmpi +# cd ${software_prefix}/src/openmpi && wget --no-check-certificate -qi https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.0.tar.gz +# cd ${software_prefix}/src/openmpi && tar xzf openmpi-${openmpi_version}.tar.gz +# +#install/openmpi: +# cd ${software_prefix}/src/openmpi/openmpi-${openmpi_version} && CC=gcc CXX=g++ FC=gfortran ./configure --prefix=${software_prefix}/install/openmpi +# make -C ${software_prefix}/src/openmpi/openmpi-${openmpi_version} install +install/openmpi: + apt-get install -yq libopenmpi-dev openmpi-bin + + + +# Intel +apt-add-repository/intel-mkl: + wget -O - https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB | apt-key add - + apt-add-repository "deb https://apt.repos.intel.com/mkl all main" + apt-get -yq update + +download/intel-mkl: + apt-get install -yq --download-only ${intel_mkl} + +install/intel-mkl: + apt-get -yq install ${intel_mkl} + rm -rf /opt/intel/mkl + ln -s /opt/intel/compilers_and_libraries_$(subst -,.,${intel_mkl_version})/linux/mkl /opt/intel/mkl + test -x /opt/intel/mkl/bin/mklvars.sh + +install/intel-mkl/lp64-sequential: install/intel-mkl +install/intel-mkl/lp64-openmp: install/intel-mkl +install/intel-mkl/lp64-tbb: install/intel-mkl +install/intel-mkl/ilp64-sequential: install/intel-mkl +install/intel-mkl/ilp64-openmp: install/intel-mkl +install/intel-mkl/ilp64-tbb: install/intel-mkl + + +# BLIS +download/blis: + mkdir -p ${software_prefix}/src/blis + cd ${software_prefix}/src/blis && wget --no-verbose https://github.com/flame/blis/archive/0.8.0.tar.gz + cd ${software_prefix}/src/blis && tar xzf 0.8.0.tar.gz + +install/blis/lp64-pthreads: + cd ${software_prefix}/src/blis/blis-0.8.0 && CC=gcc ./configure -p ${software_prefix}/install/blis-lp64-pthreads -t pthreads -i 32 -b 32 --enable-blas auto + make -C ${software_prefix}/src/blis/blis-0.8.0 install +install/blis/lp64-openmp: + cd ${software_prefix}/src/blis/blis-0.8.0 && CC=gcc ./configure -p ${software_prefix}/install/blis-lp64-openmp -t openmp -i 32 -b 32 --enable-blas auto + make -C ${software_prefix}/src/blis/blis-0.8.0 install +install/blis/lp64-sequential: + cd ${software_prefix}/src/blis/blis-0.8.0 && CC=gcc ./configure -p ${software_prefix}/install/blis-lp64-sequential -t no -i 32 -b 32 --enable-blas auto + make -C ${software_prefix}/src/blis/blis-0.8.0 install + +install/blis/ilp64-pthreads: + cd ${software_prefix}/src/blis/blis-0.8.0 && CC=gcc ./configure -p ${software_prefix}/install/blis-ilp64-pthreads -t pthreads -i 64 -b 64 --enable-blas auto + make -C ${software_prefix}/src/blis/blis-0.8.0 install +install/blis/ilp64-openmp: + cd ${software_prefix}/src/blis/blis-0.8.0 && CC=gcc ./configure -p ${software_prefix}/install/blis-ilp64-openmp -t openmp -i 64 -b 64 --enable-blas auto + make -C ${software_prefix}/src/blis/blis-0.8.0 install +install/blis/ilp64-sequential: + cd ${software_prefix}/src/blis/blis-0.8.0 && CC=gcc ./configure -p ${software_prefix}/install/blis-ilp64-sequential -t no -i 64 -b 64 --enable-blas auto + make -C ${software_prefix}/src/blis/blis-0.8.0 install + +# OpenBLAS +download/openblas: + mkdir -p ${software_prefix}/src/openblas + cd ${software_prefix}/src/openblas && wget https://github.com/xianyi/OpenBLAS/releases/download/v0.3.13/OpenBLAS-0.3.13.tar.gz + cd ${software_prefix}/src/openblas && tar xzf OpenBLAS-0.3.13.tar.gz + +install/openblas/lp64-sequential: + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 clean + BINARY64=1 USE_THREAD=0 CC=gcc FC=gfortran NO_CBLAS=1 NO_LAPACKE=1 TARGET=GENERIC make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 PREFIX=${software_prefix}/install/openblas-lp64-sequential install +install/openblas/lp64-pthreads: + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 clean + BINARY64=1 USE_THREAD=1 CC=gcc FC=gfortran NO_CBLAS=1 NO_LAPACKE=1 TARGET=GENERIC make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 PREFIX=${software_prefix}/install/openblas-lp64-pthreads install +install/openblas/lp64-openmp: + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 clean + BINARY64=1 USE_OPENMP=1 CC=gcc FC=gfortran NO_CBLAS=1 NO_LAPACKE=1 TARGET=GENERIC make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 PREFIX=${software_prefix}/install/openblas-lp64-openmp install + +install/openblas/ilp64-sequential: + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 clean + BINARY64=1 INTERFACE64=1 USE_THREAD=0 CC=gcc FC=gfortran NO_CBLAS=1 NO_LAPACKE=1 TARGET=GENERIC make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 PREFIX=${software_prefix}/install/openblas-ilp64-sequential install +install/openblas/ilp64-pthreads: + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 clean + BINARY64=1 INTERFACE64=1 USE_THREAD=1 CC=gcc FC=gfortran NO_CBLAS=1 NO_LAPACKE=1 TARGET=GENERIC make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 PREFIX=${software_prefix}/install/openblas-ilp64-pthreads install +install/openblas/ilp64-openmp: + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 clean + BINARY64=1 INTERFACE64=1 USE_OPENMP=1 CC=gcc FC=gfortran NO_CBLAS=1 NO_LAPACKE=1 TARGET=GENERIC make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 + make -C ${software_prefix}/src/openblas/OpenBLAS-0.3.13 PREFIX=${software_prefix}/install/openblas-ilp64-openmp install + +# NETLIB == NETLIB-ScaLAPACK b/c it includes NETLIB-BLAS/LAPACK +download/netlib: + mkdir -p ${software_prefix}/src/netlib + cd ${software_prefix}/src/netlib && wget https://github.com/Reference-ScaLAPACK/scalapack/archive/v2.1.0.tar.gz + cd ${software_prefix}/src/netlib && tar xzf v2.1.0.tar.gz + +install/netlib/lp64-sequential-static: + rm -fr ${software_prefix}/build/netlib-lp64-sequential + cmake -H${software_prefix}/src/netlib/scalapack-2.1.0 \ + -B${software_prefix}/build/netlib-lp64-sequential \ + -DSCALAPACK_BUILD_TESTS=OFF \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DCMAKE_INSTALL_PREFIX=${software_prefix}/install/netlib-lp64-sequential + cmake --build ${software_prefix}/build/netlib-lp64-sequential --target install + +install/netlib/lp64-sequential-shared: + rm -fr ${software_prefix}/build/netlib-lp64-sequential + cmake -H${software_prefix}/src/netlib/scalapack-2.1.0 \ + -B${software_prefix}/build/netlib-lp64-sequential \ + -DSCALAPACK_BUILD_TESTS=OFF \ + -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} \ + -DBUILD_SHARED_LIBS=ON \ + -DCMAKE_INSTALL_PREFIX=${software_prefix}/install/netlib-lp64-sequential + cmake --build ${software_prefix}/build/netlib-lp64-sequential --target install + +install/netlib/lp64-sequential: install/netlib/lp64-sequential-static install/netlib/lp64-sequential-shared diff --git a/.github/workflows/scripts/blas_libname.sh b/.github/workflows/scripts/blas_libname.sh new file mode 100755 index 0000000..7dc82c3 --- /dev/null +++ b/.github/workflows/scripts/blas_libname.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +export dist_name=$1 +export thread_name=$2 +export int_type=$3 + +if [ "$dist_name" == "intel-mkl" ] +then + export mkl_base_name="mkl_intel_$3" + if [ "$thread_name" == "sequential" ] + then + export mkl_thread_name="mkl_sequential" + elif [ "$thread_name" == "openmp" ] + then + export mkl_thread_name="mkl_(gnu|intel|pgi)_thread" + elif [ "$thread_name" == "tbb" ] + then + export mkl_thread_name="mkl_tbb_thread" + fi + echo "$mkl_base_name.*$mkl_thread_name" +elif [ "$dist_name" == "netlib" ] +then + echo "blas" +else + echo "$dist_name" +fi + diff --git a/.github/workflows/scripts/check_blas_cmake_cache.sh b/.github/workflows/scripts/check_blas_cmake_cache.sh new file mode 100755 index 0000000..a6ebf93 --- /dev/null +++ b/.github/workflows/scripts/check_blas_cmake_cache.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +export cmake_dir=$1 +export linalg_dist=$2 +export linalg_thread=$3 +export linalg_int=$4 + + +my_realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +export local_path=$(my_realpath $0) +export script_dir=$(dirname $local_path) + + +echo "CHECKING BLAS_LIBRARIES=`cmake -N -LA $cmake_dir | grep BLAS_LIBRARIES`" +echo "REFERENCE REGEX=`$script_dir/blas_libname.sh $linalg_dist $linalg_thread $linalg_int`" + +cmake -N -LA $cmake_dir | \ + grep "BLAS_LIBRARIES" | \ + grep -q -E `$script_dir/blas_libname.sh $linalg_dist $linalg_thread $linalg_int` diff --git a/.github/workflows/scripts/check_lapack_cmake_cache.sh b/.github/workflows/scripts/check_lapack_cmake_cache.sh new file mode 100755 index 0000000..da45532 --- /dev/null +++ b/.github/workflows/scripts/check_lapack_cmake_cache.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +export cmake_dir=$1 +export linalg_dist=$2 +export linalg_thread=$3 +export linalg_int=$4 + + +my_realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +export local_path=$(my_realpath $0) +export script_dir=$(dirname $local_path) + + +echo "CHECKING LAPACK_LIBRARIES=`cmake -N -LA $cmake_dir | grep LAPACK_LIBRARIES`" +echo "REFERENCE REGEX=`$script_dir/lapack_libname.sh $linalg_dist $linalg_thread $linalg_int`" + +cmake -N -LA $cmake_dir | \ + grep "LAPACK_LIBRARIES" | \ + grep -q -E `$script_dir/lapack_libname.sh $linalg_dist $linalg_thread $linalg_int` diff --git a/.github/workflows/scripts/check_scalapack_cmake_cache.sh b/.github/workflows/scripts/check_scalapack_cmake_cache.sh new file mode 100755 index 0000000..66a129b --- /dev/null +++ b/.github/workflows/scripts/check_scalapack_cmake_cache.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +export cmake_dir=$1 +export linalg_dist=$2 +export linalg_thread=$3 +export linalg_int=$4 +export mpi_dist=$5 + + +my_realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +export local_path=$(my_realpath $0) +export script_dir=$(dirname $local_path) + + +echo "CHECKING ScaLAPACK_LIBRARIES=`cmake -N -LA $cmake_dir | grep ScaLAPACK_LIBRARIES`" +echo "REFERENCE REGEX=`$script_dir/scalapack_libname.sh $linalg_dist $linalg_thread $linalg_int $mpi_dist`" + +cmake -N -LA $cmake_dir | \ + grep "ScaLAPACK_LIBRARIES" | \ + grep -q -E `$script_dir/scalapack_libname.sh $linalg_dist $linalg_thread $linalg_int $mpi_dist` diff --git a/.github/workflows/scripts/lapack_libname.sh b/.github/workflows/scripts/lapack_libname.sh new file mode 100755 index 0000000..9088b96 --- /dev/null +++ b/.github/workflows/scripts/lapack_libname.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +export dist_name=$1 +export thread_name=$2 +export int_type=$3 + +my_realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + +export local_path=$(my_realpath $0) +export script_dir=$(dirname $local_path) +export blas_name=`$script_dir/blas_libname.sh "$dist_name" "$thread_name" "$int_type"` + +if [ "$dist_name" == "netlib" ] +then + echo "lapack" +elif [ "$dist_name" == "blis" ] +then + echo "lapack.*$blas_name" +else + echo "$blas_name" +fi + diff --git a/.github/workflows/scripts/scalapack_libname.sh b/.github/workflows/scripts/scalapack_libname.sh new file mode 100755 index 0000000..3ebe419 --- /dev/null +++ b/.github/workflows/scripts/scalapack_libname.sh @@ -0,0 +1,36 @@ + +#!/bin/bash + +export dist_name=$1 +export thread_name=$2 +export int_type=$3 +export mpi_type=$4 + +my_realpath() { + [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}" +} + + +export local_path=$(my_realpath $0) +export script_dir=$(dirname $local_path) +export lapack_name=`$script_dir/lapack_libname.sh "$dist_name" "$thread_name" "$int_type"` + +if [ "$dist_name" == "intel-mkl" ] +then + export mkl_scalapack_name="mkl_scalapack_$3" + + if [ "$mpi_type" == "mpich" ] || [ "$mpi_type" == "intelmpi" ] + then + export mkl_blacs_name="mkl_blacs_intelmpi_$3" + elif [ "$mpi_type" == "openmpi" ] + then + export mkl_blacs_name="mkl_blacs_openmpi_$3" + else + export mkl_blacs_name="mkl_blacs_sgimpt_$3" + fi + + echo "$mkl_scalapack_name.*$lapack_name.*$mkl_blacs_name" +else + echo "scalapack" +fi + diff --git a/FindAccelerate.cmake b/FindAccelerate.cmake new file mode 100644 index 0000000..945e2f3 --- /dev/null +++ b/FindAccelerate.cmake @@ -0,0 +1,13 @@ +include( CheckCCompilerFlag ) +check_c_compiler_flag( "-framework Accelerate" COMPILER_RECOGNIZES_ACCELERATE ) +if( COMPILER_RECOGNIZES_ACCELERATE ) + set( Accelerate_LIBRARIES "-framework Accelerate" CACHE STRING "Accelerate Libraries" FORCE) + set( Accelerate_lp64_FOUND TRUE ) + set( Accelerate_ilp64_FOUND FALSE ) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( Accelerate + REQUIRED_VARS Accelerate_LIBRARIES + HANDLE_COMPONENTS +) diff --git a/FindBLAS.cmake b/FindBLAS.cmake index a2ff8a0..10379b7 100644 --- a/FindBLAS.cmake +++ b/FindBLAS.cmake @@ -1,17 +1,19 @@ -cmake_minimum_required( VERSION 3.11 ) # Require CMake 3.11+ +cmake_minimum_required( VERSION 3.17 ) # Require CMake 3.17+ include( CMakePushCheckState ) include( CheckLibraryExists ) include( CheckSymbolExists ) include( FindPackageHandleStandardArgs ) +include( CMakeFindDependencyMacro ) include( ${CMAKE_CURRENT_LIST_DIR}/util/CommonFunctions.cmake ) include( ${CMAKE_CURRENT_LIST_DIR}/util/BLASUtilities.cmake ) +include( ${CMAKE_CURRENT_LIST_DIR}/LinAlgModulesMacros.cmake ) # SANITY CHECK: Make sure only one integer interface is requested if( "ilp64" IN_LIST BLAS_FIND_COMPONENTS AND "lp64" IN_LIST BLAS_FIND_COMPONENTS ) - message( FATAL_ERROR "BLAS cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "BLAS cannot link to both ILP64 and LP64 interfaces" ) endif() @@ -24,10 +26,14 @@ foreach( _comp ${BLAS_FIND_COMPONENTS} ) endif() endforeach() +emulate_kitware_linalg_modules( BLAS ) fill_out_prefix( BLAS ) if( NOT BLAS_PREFERENCE_LIST ) set( BLAS_PREFERENCE_LIST "IntelMKL" "IBMESSL" "BLIS" "OpenBLAS" "ReferenceBLAS" ) + if( CMAKE_SYSTEM_NAME MATCHES "Darwin" ) + list( PREPEND BLAS_PREFERENCE_LIST "Accelerate" ) + endif() endif() if( NOT BLAS_LIBRARIES ) @@ -49,11 +55,12 @@ if( NOT BLAS_LIBRARIES ) set( BLAS_VENDOR "${blas_type}" ) set( BLAS_LIBRARIES "${${blas_type}_LIBRARIES}" ) set( BLAS_COMPILE_DEFINITIONS "${${blas_type}_COMPILE_DEFINITIONS}" ) - set( BLAS_INCLUDE_DIR "${${blas_type}_INCLUDE_DIR}" ) - + set( BLAS_INCLUDE_DIRS "${${blas_type}_INCLUDE_DIR}" ) + set( BLAS_COMPILE_OPTIONS "${${blas_type}_COMPILE_OPTIONS}" ) # Generic Components #set( BLAS_headers_FOUND ${${blas_type}_headers_FOUND} ) + set( BLAS_sycl_FOUND ${${blas_type}_sycl_FOUND} ) set( BLAS_blacs_FOUND ${${blas_type}_blacs_FOUND} ) set( BLAS_scalapack_FOUND ${${blas_type}_scalapack_FOUND} ) @@ -63,6 +70,8 @@ if( NOT BLAS_LIBRARIES ) endforeach() +else() + find_linalg_dependencies( BLAS_LIBRARIES ) endif() @@ -73,18 +82,18 @@ endif() # Check if DGEMM exists in proposed BLAS_LIBRARIES -check_dgemm_exists( BLAS_LIBRARIES - BLAS_LINK_OK BLAS_FORTRAN_LOWER BLAS_FORTRAN_UNDERSCORE ) +check_fortran_functions_exist( dgemm BLAS BLAS_LIBRARIES + BLAS_LINK_OK BLAS_Fortran_LOWER BLAS_Fortran_UNDERSCORE ) -# If BLAS linkage sucessful, check if it is ILP64/LP64 +# If BLAS linkage successful, check if it is ILP64/LP64 if( BLAS_LINK_OK ) set( _dgemm_name "dgemm" ) - if( NOT BLAS_FORTRAN_LOWER ) + if( NOT BLAS_Fortran_LOWER ) string( TOUPPER "${_dgemm_name}" _dgemm_name ) endif() - if( BLAS_FORTRAN_UNDERSCORE ) + if( BLAS_Fortran_UNDERSCORE ) set( _dgemm_name "${_dgemm_name}_" ) endif() @@ -95,6 +104,13 @@ if( BLAS_LINK_OK ) else() set( BLAS_lp64_FOUND FALSE ) set( BLAS_ilp64_FOUND TRUE ) + find_dependency( ILP64 ) + list( APPEND BLAS_COMPILE_OPTIONS "${ILP64_COMPILE_OPTIONS}" ) + foreach ( lang C CXX Fortran ) + if ( DEFINED ILP64_${lang}_COMPILE_OPTIONS ) + list( APPEND BLAS_${lang}_COMPILE_OPTIONS "${ILP64_${lang}_COMPILE_OPTIONS}" ) + endif() + endforeach() endif() endif() @@ -105,11 +121,27 @@ find_package_handle_standard_args( BLAS HANDLE_COMPONENTS ) +# Cache variables +if( BLAS_FOUND ) + set( BLAS_VENDOR "${BLAS_VENDOR}" CACHE STRING "BLAS Vendor" FORCE ) + set( BLAS_IS_LP64 "${BLAS_IS_LP64}" CACHE STRING "BLAS LP64 Flag" FORCE ) + set( BLAS_LIBRARIES "${BLAS_LIBRARIES}" CACHE STRING "BLAS Libraries" FORCE ) + set( BLAS_COMPILE_DEFINITIONS "${BLAS_COMPILE_DEFINITIONS}" CACHE STRING "BLAS Compile Definitions" FORCE ) + set( BLAS_INCLUDE_DIRS "${BLAS_INCLUDE_DIRS}" CACHE STRING "BLAS Include Directories" FORCE ) + set( BLAS_COMPILE_OPTIONS "${BLAS_COMPILE_OPTIONS}" CACHE STRING "BLAS Compile Options" FORCE ) + foreach ( lang C CXX Fortran ) + if ( DEFINED BLAS_${lang}_COMPILE_OPTIONS ) + set( BLAS_${lang}_COMPILE_OPTIONS "${BLAS_${lang}_COMPILE_OPTIONS}" CACHE STRING "BLAS Compile Options for Language ${lang}" FORCE ) + endif() + endforeach() +endif() if( BLAS_FOUND AND NOT TARGET BLAS::BLAS ) add_library( BLAS::BLAS INTERFACE IMPORTED ) set_target_properties( BLAS::BLAS PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${BLAS_INCLUDE_DIRS}" + INTERFACE_COMPILE_OPTIONS "${BLAS_COMPILE_OPTIONS}" INTERFACE_COMPILE_DEFINITIONS "${BLAS_COMPILE_DEFINITIONS}" INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}" ) diff --git a/FindBLIS.cmake b/FindBLIS.cmake index d7f5a65..1ee6e5e 100644 --- a/FindBLIS.cmake +++ b/FindBLIS.cmake @@ -1,12 +1,12 @@ # SANITY CHECK if( "ilp64" IN_LIST BLIS_FIND_COMPONENTS AND "lp64" IN_LIST BLIS_FIND_COMPONENTS ) - message( FATAL_ERROR "BLIS cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "BLIS cannot link to both ILP64 and LP64 interfaces" ) endif() if( BLIS_PREFERS_STATIC ) - set( BLIS_LIBRARY_NAME "libblis.a" ) + set( BLIS_LIBRARY_NAME "libblis.a" "libblis-mt.a" ) else() - set( BLIS_LIBRARY_NAME "blis" ) + set( BLIS_LIBRARY_NAME "blis" "blis-mt") endif() find_library( BLIS_LIBRARIES @@ -25,24 +25,52 @@ find_path( BLIS_INCLUDE_DIR DOC "BLIS header" ) -#if( BLIS_LIBRARY AND BLIS_PREFERS_STATIC ) -# include( CMakeFindDependency ) -# find_package( Threads QUIET ) -# set( BLIS_LIBRARIES ${BLIS_LIBRARY} Threads::Threads "m") -#endif() +if( BLIS_LIBRARIES ) + if( NOT "m" IN_LIST BLIS_LIBRARIES ) + list( APPEND BLIS_LIBRARIES "m") + endif() +endif() # check ILP64 if( BLIS_INCLUDE_DIR ) try_run( BLIS_USES_LP64 - _blis_idx_test_compile_result + BLIS_TEST_COMPILES + ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${CMAKE_CURRENT_LIST_DIR}/util/blis_int_size.c + CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${BLIS_INCLUDE_DIR} + LINK_LIBRARIES ${BLIS_LIBRARIES} + COMPILE_OUTPUT_VARIABLE _blis_idx_compile_output + RUN_OUTPUT_VARIABLE _blis_idx_run_output + ) + + if( NOT BLIS_TEST_COMPILES ) + if( ${_blis_idx_compile_output} MATCHES "pthread_" ) + if (NOT TARGET Threads::Threads) + find_dependency(Threads) + # Threads::Threads by default is not GLOBAL, so to allow users of LINALG_LIBRARIES to safely use it we need to make it global + # more discussion here: https://gitlab.kitware.com/cmake/cmake/-/issues/17256 + set_target_properties(Threads::Threads PROPERTIES IMPORTED_GLOBAL TRUE) + endif(NOT TARGET Threads::Threads) + list( APPEND BLIS_LIBRARIES Threads::Threads ) + endif() + if( ${_blis_idx_compile_output} MATCHES "omp_" ) + find_dependency( OpenMP ) + list( APPEND BLIS_LIBRARIES OpenMP::OpenMP_C ) + endif() + endif() + + try_run( BLIS_USES_LP64 + BLIS_TEST_COMPILES ${CMAKE_CURRENT_BINARY_DIR} SOURCES ${CMAKE_CURRENT_LIST_DIR}/util/blis_int_size.c CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${BLIS_INCLUDE_DIR} + LINK_LIBRARIES ${BLIS_LIBRARIES} COMPILE_OUTPUT_VARIABLE _blis_idx_compile_output RUN_OUTPUT_VARIABLE _blis_idx_run_output ) + if( ${BLIS_USES_LP64} EQUAL 0 ) set( BLIS_USES_LP64 TRUE ) else() diff --git a/FindFLAME.cmake b/FindFLAME.cmake new file mode 100644 index 0000000..d8cf9c0 --- /dev/null +++ b/FindFLAME.cmake @@ -0,0 +1,47 @@ +# SANITY CHECK +if( "ilp64" IN_LIST FLAME_FIND_COMPONENTS AND "lp64" IN_LIST FLAME_FIND_COMPONENTS ) + message( FATAL_ERROR "FLAME cannot link to both ILP64 and LP64 interfaces" ) +endif() + +if( FLAME_PREFERS_STATIC ) + set( FLAME_LIBRARY_NAME "libflame.a" ) +else() + set( FLAME_LIBRARY_NAME "flame" ) +endif() + +find_library( FLAME_LIBRARIES + NAMES ${FLAME_LIBRARY_NAME} + HINTS ${FLAME_PREFIX} + PATHS ${FLAME_LIBRARY_DIR} ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES} + PATH_SUFFIXES lib lib64 lib32 + DOC "FLAME Library" +) + +find_path( FLAME_INCLUDE_DIR + NAMES FLAME.h + HINTS ${FLAME_PREFIX} + PATHS ${FLAME_INCLUDE_DIR} + PATH_SUFFIXES include + DOC "FLAME header" +) + +#XXX Seems that FLAME is only LP64 +set( FLAME_lp64_FOUND TRUE ) +set( FLAME_ilp64_FOUND FALSE ) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( FLAME + REQUIRED_VARS FLAME_LIBRARIES FLAME_INCLUDE_DIR + HANDLE_COMPONENTS +) + +#if( FLAME_FOUND AND NOT TARGET FLAME::FLAME ) +# +# add_library( FLAME::FLAME INTERFACE IMPORTED ) +# set_target_properties( FLAME::FLAME PROPERTIES +# INTERFACE_INCLUDE_DIRECTORIES "${FLAME_INCLUDE_DIR}" +# INTERFACE_LINK_LIBRARIES "${FLAME_LIBRARIES}" +# ) +# +#endif() diff --git a/FindIBMESSL.cmake b/FindIBMESSL.cmake index bcd003a..38f4e2a 100644 --- a/FindIBMESSL.cmake +++ b/FindIBMESSL.cmake @@ -1,5 +1,5 @@ if( "ilp64" IN_LIST IBMESSL_FIND_COMPONENTS AND "lp64" IN_LIST IBMESSL_FIND_COMPONENTS ) - message( FATAL_ERROR "IBMESSL cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "IBMESSL cannot link to both ILP64 and LP64 interfaces" ) endif() set( IBMESSL_LP64_SERIAL_LIBRARY_NAME "essl" ) @@ -8,11 +8,11 @@ set( IBMESSL_ILP64_SERIAL_LIBRARY_NAME "essl6464" ) set( IBMESSL_ILP64_SMP_LIBRARY_NAME "esslsmp6464" ) -if( NOT IBMESSL_PREFERED_THREAD_LEVEL ) - set( IBMESSL_PREFERED_THREAD_LEVEL "smp" ) +if( NOT IBMESSL_THREAD_LAYER ) + set( IBMESSL_THREAD_LAYER "smp" ) endif() -if( IBMESSL_PREFERED_THREAD_LEVEL MATCHES "smp" ) +if( IBMESSL_THREAD_LAYER MATCHES "smp" ) set( IBMESSL_LP64_LIBRARY_NAME ${IBMESSL_LP64_SMP_LIBRARY_NAME} ) set( IBMESSL_ILP64_LIBRARY_NAME ${IBMESSL_ILP64_SMP_LIBRARY_NAME} ) else() @@ -20,7 +20,6 @@ else() set( IBMESSL_ILP64_LIBRARY_NAME ${IBMESSL_ILP64_SERIAL_LIBRARY_NAME} ) endif() - find_path( IBMESSL_INCLUDE_DIR NAMES essl.h HINTS ${IBMESSL_PREFIX} @@ -71,12 +70,10 @@ endif() # LP64 Default if( "ilp64" IN_LIST IBMESSL_FIND_COMPONENTS ) set( IBMESSL_LIBRARIES "${IBMESSL_ILP64_LIBRARIES}" ) - else() set( IBMESSL_LIBRARIES "${IBMESSL_LP64_LIBRARIES}" ) endif() - include(FindPackageHandleStandardArgs) find_package_handle_standard_args( IBMESSL REQUIRED_VARS IBMESSL_LIBRARIES IBMESSL_INCLUDE_DIR diff --git a/FindILP64.cmake b/FindILP64.cmake new file mode 100644 index 0000000..38231ea --- /dev/null +++ b/FindILP64.cmake @@ -0,0 +1,27 @@ +set( ILP64_FOUND TRUE CACHE BOOL "ILP64 Flags Found" FORCE ) +set( ILP64_COMPILE_OPTIONS + # Ensure 64-bit executables for GNU C,CXX,Fortran + $<$,$>:-m64> + # Make default integers 64-bit for Fortran + $<$,$>:-i8> + $<$,$>:-fdefault-integer-8> + ) +set( ILP64_COMPILE_OPTIONS "${ILP64_COMPILE_OPTIONS}" CACHE STRING "ILP64 compile options" FORCE ) + +foreach (lang C CXX Fortran) + if ( NOT DEFINED CMAKE_${lang}_COMPILER_ID ) + continue() + endif() + if ( CMAKE_${lang}_COMPILER_ID STREQUAL GNU ) + list( APPEND ILP64_${lang}_COMPILE_OPTIONS -m64 ) + endif() + if ( lang STREQUAL Fortran ) + if ( CMAKE_Fortran_COMPILER_ID STREQUAL Intel OR CMAKE_Fortran_COMPILER_ID STREQUAL PGI ) + list( APPEND ILP64_${lang}_COMPILE_OPTIONS -i8 ) + endif() + if ( CMAKE_Fortran_COMPILER_ID STREQUAL GNU OR CMAKE_Fortran_COMPILER_ID STREQUAL Flang ) + list( APPEND ILP64_${lang}_COMPILE_OPTIONS -fdefault-integer-8 ) + endif() + endif() + set( ILP64_${lang}_COMPILE_OPTIONS "${ILP64_${lang}_COMPILE_OPTIONS}" CACHE STRING "ILP64 compile options for language ${lang}" FORCE ) +endforeach() diff --git a/FindIntelMKL.cmake b/FindIntelMKL.cmake index 721d379..1eb00d8 100644 --- a/FindIntelMKL.cmake +++ b/FindIntelMKL.cmake @@ -19,7 +19,7 @@ include( CMakeFindDependencyMacro ) # SANITY CHECK if( "ilp64" IN_LIST IntelMKL_FIND_COMPONENTS AND "lp64" IN_LIST IntelMKL_FIND_COMPONENTS ) - message( FATAL_ERROR "IntelMKL cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "IntelMKL cannot link to both ILP64 and LP64 interfaces" ) endif() if( "scalapack" IN_LIST IntelMKL_FIND_COMPONENTS AND NOT ("blacs" IN_LIST IntelMKL_FIND_COMPONENTS) ) @@ -36,6 +36,7 @@ if( IntelMKL_PREFERS_STATIC ) set( IntelMKL_OMP_PGI_LIBRARY_NAME "libmkl_pgi_thread.a" ) set( IntelMKL_TBB_LIBRARY_NAME "libmkl_tbb_thread.a" ) set( IntelMKL_CORE_LIBRARY_NAME "libmkl_core.a" ) + set( IntelMKL_SYCL_LIBRARY_NAME "libmkl_sycl.a" ) set( IntelMKL_LP64_ScaLAPACK_LIBRARY_NAME "libmkl_scalapack_lp64.a" ) set( IntelMKL_ILP64_ScaLAPACK_LIBRARY_NAME "libmkl_scalapack_ilp64.a" ) @@ -55,6 +56,7 @@ else() set( IntelMKL_OMP_PGI_LIBRARY_NAME "mkl_pgi_thread" ) set( IntelMKL_TBB_LIBRARY_NAME "mkl_tbb_thread" ) set( IntelMKL_CORE_LIBRARY_NAME "mkl_core" ) + set( IntelMKL_SYCL_LIBRARY_NAME "mkl_sycl" ) set( IntelMKL_LP64_ScaLAPACK_LIBRARY_NAME "mkl_scalapack_lp64" ) set( IntelMKL_ILP64_ScaLAPACK_LIBRARY_NAME "mkl_scalapack_ilp64" ) @@ -193,8 +195,6 @@ find_library( IntelMKL_CORE_LIBRARY DOC "Intel(R) MKL CORE Library" ) - - # Check version if( EXISTS ${IntelMKL_INCLUDE_DIR}/mkl_version.h ) set( version_pattern @@ -253,6 +253,16 @@ else() set( IntelMKL_lp64_FOUND FALSE ) endif() +# SYCL +if( "sycl" IN_LIST IntelMKL_FIND_COMPONENTS ) + find_library( IntelMKL_SYCL_LIBRARY + NAMES ${IntelMKL_SYCL_LIBRARY_NAME} + HINTS ${IntelMKL_PREFIX} + PATHS ${IntelMKL_LIBRARY_DIR} ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES} + PATH_SUFFIXES lib/intel64 lib/ia32 + DOC "Intel(R) MKL SYCL Library" + ) +endif() # BLACS / ScaLAPACK @@ -293,13 +303,8 @@ find_library( IntelMKL_LP64_ScaLAPACK_LIBRARY # Default to LP64 if( "ilp64" IN_LIST IntelMKL_FIND_COMPONENTS ) + set( IntelMKL_COMPILE_DEFINITIONS "MKL_ILP64" ) - if( CMAKE_C_COMPILER_ID MATCHES "GNU" ) - set( IntelMKL_C_COMPILE_FLAGS "-m64" ) - set( IntelMKL_Fortran_COMPILE_FLAGS "-m64" "-fdefault-integer-8" ) - elseif( CMAKE_C_COMPILER_ID MATCHES "PGI" ) - set( IntelMKL_Fortran_COMPILE_FLAGS "-i8" ) - endif() set( IntelMKL_LIBRARY ${IntelMKL_ILP64_LIBRARY} ) if( IntelMKL_ILP64_BLACS_LIBRARY ) @@ -326,7 +331,9 @@ else() endif() endif() - +if( IntelMKL_SYCL_LIBRARY ) + set( IntelMKL_sycl_FOUND TRUE ) +endif() @@ -345,6 +352,10 @@ if( IntelMKL_LIBRARY AND IntelMKL_THREAD_LIBRARY AND IntelMKL_CORE_LIBRARY ) ${IntelMKL_THREAD_LIBRARY} ${IntelMKL_CORE_LIBRARY} ) + if( "sycl" IN_LIST IntelMKL_FIND_COMPONENTS ) + list( APPEND IntelMKL_BLAS_LAPACK_LIBRARIES ${IntelMKL_SYCL_LIBRARY} ) + endif() + if( "blacs" IN_LIST IntelMKL_FIND_COMPONENTS ) set( IntelMKL_BLACS_LIBRARIES ${IntelMKL_BLAS_LAPACK_LIBRARIES} @@ -402,19 +413,19 @@ if( IntelMKL_LIBRARY AND IntelMKL_THREAD_LIBRARY AND IntelMKL_CORE_LIBRARY ) elseif( IntelMKL_THREAD_LAYER MATCHES "tbb" ) - if( NOT TARGET tbb ) - message( FATAL_ERROR "TBB Bindings Not Currently Accessible Through FindIntelMKL" ) - find_dependency( TBB ) + if( NOT TARGET TBB::tbb ) + find_dependency( TBB REQUIRED ) + # TBB::tbb by default is not GLOBAL, so to allow users of LINALG_LIBRARIES to safely use it we need to make it global + # more discussion here: https://gitlab.kitware.com/cmake/cmake/-/issues/17256 + set_target_properties(TBB::tbb PROPERTIES IMPORTED_GLOBAL TRUE) endif() - list( APPEND IntelMKL_BLAS_LAPACK_LIBRARIES tbb ) - + list( APPEND IntelMKL_BLAS_LAPACK_LIBRARIES TBB::tbb ) if( IntelMKL_BLACS_LIBRARIES ) - list( APPEND IntelMKL_BLACS_LIBRARIES tbb ) + list( APPEND IntelMKL_BLACS_LIBRARIES TBB::tbb ) endif() - if( IntelMKL_ScaLAPACK_LIBRARIES ) - list( APPEND IntelMKL_ScaLAPACK_LIBRARIES tbb ) + list( APPEND IntelMKL_ScaLAPACK_LIBRARIES TBB::tbb ) endif() endif() @@ -422,6 +433,9 @@ if( IntelMKL_LIBRARY AND IntelMKL_THREAD_LIBRARY AND IntelMKL_CORE_LIBRARY ) if( NOT TARGET Threads::Threads ) find_dependency( Threads ) + # Threads::Threads by default is not GLOBAL, so to allow users of LINALG_LIBRARIES to safely use it we need to make it global + # more discussion here: https://gitlab.kitware.com/cmake/cmake/-/issues/17256 + set_target_properties(Threads::Threads PROPERTIES IMPORTED_GLOBAL TRUE) endif() list( APPEND IntelMKL_BLAS_LAPACK_LIBRARIES "m" "dl" Threads::Threads ) @@ -454,22 +468,30 @@ find_package_handle_standard_args( IntelMKL HANDLE_COMPONENTS ) -#if( IntelMKL_FOUND AND NOT TARGET IntelMKL::mkl ) -# -# add_library( IntelMKL::mkl INTERFACE IMPORTED ) -# set_target_properties( IntelMKL::mkl PROPERTIES -# INTERFACE_INCLUDE_DIRECTORIES "${IntelMKL_INCLUDE_DIR}" -# INTERFACE_LINK_LIBRARIES "${IntelMKL_LIBRARIES}" -# INTERFACE_COMPILE_OPTIONS "${IntelMKL_C_COMPILE_FLAGS}" -# INTERFACE_COMPILE_DEFINITIONS "${IntelMKL_COMPILE_DEFINITIONS}" -# ) -# -# if( "scalapack" IN_LIST IntelMKL_FIND_COMPONENTS AND NOT scalapack_LIBRARIES ) -# set( scalapack_LIBRARIES IntelMKL::mkl ) -# endif() -# -# if( "blacs" IN_LIST IntelMKL_FIND_COMPONENTS AND NOT blacs_LIBRARIES ) -# set( blacs_LIBRARIES IntelMKL::mkl ) -# endif() -# -#endif() +if( IntelMKL_FOUND ) + + if( IntelMKL_BLAS_LAPACK_LIBRARIES AND NOT TARGET IntelMKL::IntelMKL ) + add_library( IntelMKL::IntelMKL INTERFACE IMPORTED ) + set_target_properties( IntelMKL::IntelMKL PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${IntelMKL_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${IntelMKL_BLAS_LAPACK_LIBRARIES}" + ) + endif() + + if( IntelMKL_BLACS_LIBRARIES AND NOT TARGET IntelMKL::BLACS ) + add_library( IntelMKL::BLACS INTERFACE IMPORTED ) + set_target_properties( IntelMKL::BLACS PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${IntelMKL_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${IntelMKL_BLACS_LIBRARIES}" + ) + endif() + + if( IntelMKL_ScaLAPACK_LIBRARIES AND NOT TARGET IntelMKL::ScaLAPACK ) + add_library( IntelMKL::ScaLAPACK INTERFACE IMPORTED ) + set_target_properties( IntelMKL::ScaLAPACK PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${IntelMKL_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${IntelMKL_ScaLAPACK_LIBRARIES}" + ) + endif() + +endif() diff --git a/FindLAPACK.cmake b/FindLAPACK.cmake index dbcfab2..3fe8a0a 100644 --- a/FindLAPACK.cmake +++ b/FindLAPACK.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 3.11 ) # Require CMake 3.11+ +cmake_minimum_required( VERSION 3.17 ) # Require CMake 3.17+ include( CMakePushCheckState ) include( CheckLibraryExists ) @@ -8,11 +8,12 @@ include( FindPackageHandleStandardArgs ) include( ${CMAKE_CURRENT_LIST_DIR}/util/CommonFunctions.cmake ) -include( ${CMAKE_CURRENT_LIST_DIR}/util/LAPACKUtilities.cmake ) +include( ${CMAKE_CURRENT_LIST_DIR}/util/LAPACKUtilities.cmake ) +include( ${CMAKE_CURRENT_LIST_DIR}/LinAlgModulesMacros.cmake ) # SANITY CHECK if( "ilp64" IN_LIST LAPACK_FIND_COMPONENTS AND "lp64" IN_LIST LAPACK_FIND_COMPONENTS ) - message( FATAL_ERROR "LAPACK cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "LAPACK cannot link to both ILP64 and LP64 interfaces" ) endif() @@ -25,40 +26,46 @@ foreach( _comp ${LAPACK_FIND_COMPONENTS} ) endif() endforeach() +emulate_kitware_linalg_modules( LAPACK ) fill_out_prefix( LAPACK ) if( NOT LAPACK_PREFERENCE_LIST ) - set( LAPACK_PREFERENCE_LIST "ReferenceLAPACK" ) + set( LAPACK_PREFERENCE_LIST "ReferenceLAPACK" "FLAME" ) endif() if( NOT LAPACK_LIBRARIES ) # Find BLAS if( NOT TARGET BLAS::BLAS ) - find_dependency( BLAS - COMPONENTS ${LAPACK_REQUIRED_COMPONENTS} - OPTIONAL_COMPONENTS ${LAPACK_OPTIONAL_COMPONENTS} + copy_meta_data( LAPACK BLAS ) + find_dependency( BLAS + COMPONENTS ${LAPACK_REQUIRED_COMPONENTS} + OPTIONAL_COMPONENTS ${LAPACK_OPTIONAL_COMPONENTS} ) endif() - + # Check if BLAS contains a LAPACK linker message( STATUS "LAPACK_LIBRARIES Not Given: Checking for LAPACK in BLAS" ) set( LAPACK_LIBRARIES ${BLAS_LIBRARIES} ) - set( LAPACK_INCLUDE_DIR ${BLAS_INCLUDE_DIR} ) + set( LAPACK_INCLUDE_DIRS ${BLAS_INCLUDE_DIRS} ) set( LAPACK_COMPILE_DEFINITIONS ${BLAS_COMPILE_DEFINITIONS} ) - check_dpstrf_exists( LAPACK_LIBRARIES - BLAS_HAS_LAPACK LAPACK_FORTRAN_LOWER LAPACK_FORTRAN_UNDERSCORE - ) - - + + # use dpstrf to check for full LAPACK API ... some implementations are incomplete (e.g. older OpenBLAS) + # also need to handle several corner cases: + # - OpenBLAS needs libgfortran only for some functions, dpstrf is not one of them, so check for dgesvd + check_fortran_functions_exist( "dpstrf;dgesvd" LAPACK LAPACK_LIBRARIES + BLAS_HAS_LAPACK LAPACK_Fortran_LOWER LAPACK_Fortran_UNDERSCORE + ) + # If BLAS has a full LAPACK Linker, propagate vars if( BLAS_HAS_LAPACK ) message( STATUS "BLAS Has A Full LAPACK Linker" ) - set( LAPACK_VENDOR ${BLAS_VENDOR} ) - set( LAPACK_IS_LP64 ${BLAS_IS_LP64} ) - set( LAPACK_blacs_FOUND ${BLAS_blacs_FOUND} ) + set( LAPACK_VENDOR ${BLAS_VENDOR} ) + set( LAPACK_IS_LP64 ${BLAS_IS_LP64} ) + set( LAPACK_blacs_FOUND ${BLAS_blacs_FOUND} ) set( LAPACK_scalapack_FOUND ${BLAS_scalapack_FOUND} ) + set( LAPACK_sycl_FOUND ${BLAS_sycl_FOUND} ) # Else find LAPACK installation consistent with BLAS else( BLAS_HAS_LAPACK ) @@ -75,9 +82,9 @@ if( NOT LAPACK_LIBRARIES ) copy_meta_data( LAPACK ${lapack_type} ) - find_package( ${lapack_type} - COMPONENTS ${LAPACK_REQUIRED_COMPONENTS} - OPTIONAL_COMPONENTS ${LAPACK_OPTIONAL_COMPONENTS} + find_package( ${lapack_type} + COMPONENTS ${LAPACK_REQUIRED_COMPONENTS} + OPTIONAL_COMPONENTS ${LAPACK_OPTIONAL_COMPONENTS} ) if( ${lapack_type}_FOUND ) @@ -93,6 +100,7 @@ if( NOT LAPACK_LIBRARIES ) #set( LAPACK_headers_FOUND ${${lapack_type}_headers_FOUND} ) set( LAPACK_blacs_FOUND ${${lapack_type}_blacs_FOUND} ) set( LAPACK_scalapack_FOUND ${${lapack_type}_scalapack_FOUND} ) + set( LAPACK_sycl_FOUND ${${lapack_type}_sycl_FOUND} ) break() # Break from search loop @@ -101,7 +109,8 @@ if( NOT LAPACK_LIBRARIES ) endforeach() endif( BLAS_HAS_LAPACK ) - +else() + find_linalg_dependencies( LAPACK_LIBRARIES ) endif() # Handle implicit LAPACK linkage @@ -114,19 +123,20 @@ endif() if( BLAS_HAS_LAPACK ) set( LAPACK_LINK_OK TRUE ) else() - check_dpstrf_exists( LAPACK_LIBRARIES - LAPACK_LINK_OK LAPACK_FORTRAN_LOWER LAPACK_FORTRAN_UNDERSCORE - ) + # see notes above the first invocation of check_fortran_functions_exist + check_fortran_functions_exist( "dpstrf;dgesvd" LAPACK LAPACK_LIBRARIES + LAPACK_LINK_OK LAPACK_Fortran_LOWER LAPACK_Fortran_UNDERSCORE + ) endif() -# If LAPACK linkage sucessful, check if it is ILP64/LP64 +# If LAPACK linkage successful, check if it is ILP64/LP64 if( LAPACK_LINK_OK ) set( _dsyev_name "dsyev" ) - if( NOT LAPACK_FORTRAN_LOWER ) + if( NOT LAPACK_Fortran_LOWER ) string( TOUPPER "${_dsyev_name}" _dsyev_name ) endif() - if( LAPACK_FORTRAN_UNDERSCORE ) + if( LAPACK_Fortran_UNDERSCORE ) set( _dsyev_name "${_dsyev_name}_" ) endif() @@ -137,6 +147,13 @@ if( LAPACK_LINK_OK ) else() set( LAPACK_lp64_FOUND FALSE ) set( LAPACK_ilp64_FOUND TRUE ) + find_dependency( ILP64 ) + list( APPEND LAPACK_COMPILE_OPTIONS "${ILP64_COMPILE_OPTIONS}" ) + foreach ( lang C CXX Fortran ) + if ( DEFINED ILP64_${lang}_COMPILE_OPTIONS ) + list( APPEND LAPACK_${lang}_COMPILE_OPTIONS "${ILP64_${lang}_COMPILE_OPTIONS}" ) + endif() + endforeach() endif() else() @@ -155,10 +172,27 @@ find_package_handle_standard_args( LAPACK HANDLE_COMPONENTS ) +# Cache variables +if( LAPACK_FOUND ) + set( LAPACK_VENDOR "${LAPACK_VENDOR}" CACHE STRING "LAPACK Vendor" FORCE ) + set( LAPACK_IS_LP64 "${LAPACK_IS_LP64}" CACHE STRING "LAPACK LP64 Flag" FORCE ) + set( LAPACK_LIBRARIES "${LAPACK_LIBRARIES}" CACHE STRING "LAPACK Libraries" FORCE ) + set( LAPACK_COMPILE_DEFINITIONS "${LAPACK_COMPILE_DEFINITIONS}" CACHE STRING "LAPACK Compile Definitions" FORCE ) + set( LAPACK_INCLUDE_DIRS "${LAPACK_INCLUDE_DIRS}" CACHE STRING "LAPACK Include Directories" FORCE ) + set( LAPACK_COMPILE_OPTIONS "${LAPACK_COMPILE_OPTIONS}" CACHE STRING "LAPACK Compile Options" FORCE ) + foreach ( lang C CXX Fortran ) + if ( DEFINED LAPACK_${lang}_COMPILE_OPTIONS ) + set( LAPACK_${lang}_COMPILE_OPTIONS "${LAPACK_${lang}_COMPILE_OPTIONS}" CACHE STRING "LAPACK Compile Options for Language ${lang}" FORCE ) + endif() + endforeach() +endif() + if( LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK ) - + add_library( LAPACK::LAPACK INTERFACE IMPORTED ) set_target_properties( LAPACK::LAPACK PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LAPACK_INCLUDE_DIRS}" + INTERFACE_COMPILE_OPTIONS "${LAPACK_COMPILE_OPTIONS}" INTERFACE_COMPILE_DEFINITIONS "${LAPACK_COMPILE_DEFINITIONS}" INTERFACE_LINK_LIBRARIES "${LAPACK_LIBRARIES}" ) diff --git a/FindOpenBLAS.cmake b/FindOpenBLAS.cmake index 93f5e9c..c4e3c4b 100644 --- a/FindOpenBLAS.cmake +++ b/FindOpenBLAS.cmake @@ -1,6 +1,6 @@ # SANITY CHECK if( "ilp64" IN_LIST OpenBLAS_FIND_COMPONENTS AND "lp64" IN_LIST OpenBLAS_FIND_COMPONENTS ) - message( FATAL_ERROR "OpenBLAS cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "OpenBLAS cannot link to both ILP64 and LP64 interfaces" ) endif() if( OpenBLAS_PREFERS_STATIC ) diff --git a/FindReferenceBLAS.cmake b/FindReferenceBLAS.cmake index 8a9904b..d6caf54 100644 --- a/FindReferenceBLAS.cmake +++ b/FindReferenceBLAS.cmake @@ -1,6 +1,6 @@ # SANITY CHECK if( "ilp64" IN_LIST ReferenceBLAS_FIND_COMPONENTS AND "lp64" IN_LIST ReferenceBLAS_FIND_COMPONENTS ) - message( FATAL_ERROR "ReferenceBLAS cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "ReferenceBLAS cannot link to both ILP64 and LP64 interfaces" ) endif() if( ReferenceBLAS_PREFERS_STATIC ) diff --git a/FindReferenceLAPACK.cmake b/FindReferenceLAPACK.cmake index 238cf55..14b5095 100644 --- a/FindReferenceLAPACK.cmake +++ b/FindReferenceLAPACK.cmake @@ -1,6 +1,6 @@ # SANITY CHECK if( "ilp64" IN_LIST ReferenceLAPACK_FIND_COMPONENTS AND "lp64" IN_LIST ReferenceLAPACK_FIND_COMPONENTS ) - message( FATAL_ERROR "ReferenceLAPACK cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "ReferenceLAPACK cannot link to both ILP64 and LP64 interfaces" ) endif() if( ReferenceLAPACK_PREFERS_STATIC ) @@ -46,7 +46,6 @@ else() set( ReferenceLAPACK_LIBRARIES ${ReferenceLAPACK_LP64_LIBRARIES} ) endif() - include(FindPackageHandleStandardArgs) find_package_handle_standard_args( ReferenceLAPACK REQUIRED_VARS ReferenceLAPACK_LIBRARIES diff --git a/FindReferenceScaLAPACK.cmake b/FindReferenceScaLAPACK.cmake index 2de366c..b09c63a 100644 --- a/FindReferenceScaLAPACK.cmake +++ b/FindReferenceScaLAPACK.cmake @@ -1,6 +1,10 @@ # SANITY CHECK if( "ilp64" IN_LIST ReferenceScaLAPACK_FIND_COMPONENTS AND "lp64" IN_LIST ReferenceScaLAPACK_FIND_COMPONENTS ) - message( FATAL_ERROR "ReferenceScaLAPACK cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "ReferenceScaLAPACK cannot link to both ILP64 and LP64 interfaces" ) +endif() + +if( "ilp64" IN_LIST ReferenceScaLAPACK_FIND_COMPONENTS ) + message( FATAL_ERROR "ReferenceScaLAPACK ILP64 interface discovery is currently not supported" ) endif() if( NOT TARGET MPI::MPI_C ) diff --git a/FindScaLAPACK.cmake b/FindScaLAPACK.cmake index 79697cc..11b1375 100644 --- a/FindScaLAPACK.cmake +++ b/FindScaLAPACK.cmake @@ -9,10 +9,7 @@ # # This module will export the following targets if SCALAPACK_FOUND # -# ScaLAPACK::scalapack -# -# -# +# ScaLAPACK::ScaLAPACK # # Proper usage: # @@ -21,73 +18,33 @@ # # if( ScaLAPACK_FOUND ) # add_executable( test test.cxx ) -# target_link_libraries( test ScaLAPACK::scalapack ) +# target_link_libraries( test ScaLAPACK::ScaLAPACK ) # endif() # # -# -# # This module will use the following variables to change # default behaviour if set # -# scalapack_PREFIX -# scalapack_LIBRARY_DIR -# scalapack_LIBRARIES -# -#================================================================== -# Copyright (c) 2018 The Regents of the University of California, -# through Lawrence Berkeley National Laboratory. -# -# Author: David Williams-Young -# -# This file is part of cmake-modules. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# (1) Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# (2) Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# (3) Neither the name of the University of California, Lawrence Berkeley -# National Laboratory, U.S. Dept. of Energy nor the names of its contributors may -# be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# You are under no obligation whatsoever to provide any bug fixes, patches, or -# upgrades to the features, functionality or performance of the source code -# ("Enhancements") to anyone; however, if you choose to make your Enhancements -# available either publicly, or directly to Lawrence Berkeley National -# Laboratory, without imposing a separate written license agreement for such -# Enhancements, then you hereby grant the following license: a non-exclusive, -# royalty-free perpetual license to install, use, modify, prepare derivative -# works, incorporate into other computer software, distribute, and sublicense -# such enhancements or derivative works thereof, in binary and source code form. -# -#================================================================== +# ScaLAPACK_PREFIX +# ScaLAPACK_LIBRARY_DIR +# ScaLAPACK_LIBRARIES -cmake_minimum_required( VERSION 3.11 ) # Require CMake 3.11+ +cmake_minimum_required( VERSION 3.17 ) # Require CMake 3.17+ +include( CMakePushCheckState ) +include( CheckLibraryExists ) +include( CheckSymbolExists ) +include( FindPackageHandleStandardArgs ) include( CMakeFindDependencyMacro ) -include( ${CMAKE_CURRENT_LIST_DIR}/util/CommonFunctions.cmake ) +include( ${CMAKE_CURRENT_LIST_DIR}/util/CommonFunctions.cmake ) include( ${CMAKE_CURRENT_LIST_DIR}/util/ScaLAPACKUtilities.cmake ) +include( ${CMAKE_CURRENT_LIST_DIR}/LinAlgModulesMacros.cmake ) + # SANITY CHECK if( "ilp64" IN_LIST ScaLAPACK_FIND_COMPONENTS AND "lp64" IN_LIST ScaLAPACK_FIND_COMPONENTS ) - message( FATAL_ERROR "ScaLAPACK cannot link to both ILP64 and LP64 iterfaces" ) + message( FATAL_ERROR "ScaLAPACK cannot link to both ILP64 and LP64 interfaces" ) endif() @@ -100,6 +57,7 @@ foreach( _comp ${ScaLAPACK_FIND_COMPONENTS} ) endif() endforeach() +emulate_kitware_linalg_modules( ScaLAPACK ) fill_out_prefix( ScaLAPACK ) if( NOT ScaLAPACK_PREFERENCE_LIST ) @@ -111,6 +69,7 @@ if( NOT ScaLAPACK_LIBRARIES ) # Find LAPACK if( NOT TARGET LAPACK::LAPACK ) + copy_meta_data( ScaLAPACK LAPACK ) find_dependency( LAPACK COMPONENTS ${ScaLAPACK_REQUIRED_COMPONENTS} OPTIONAL_COMPONENTS ${ScaLAPACK_OPTIONAL_COMPONENTS} scalapack blacs @@ -123,7 +82,7 @@ if( NOT ScaLAPACK_LIBRARIES ) set( ScaLAPACK_INCLUDE_DIR ${LAPACK_INCLUDE_DIR} ) set( ScaLAPACK_COMPILE_DEFINITIONS ${LAPACK_COMPILE_DEFINITIONS} ) check_pdpotrf_exists( ScaLAPACK_LIBRARIES - LAPACK_HAS_ScaLAPACK ScaLAPACK_FORTRAN_LOWER ScaLAPACK_FORTRAN_UNDERSCORE + LAPACK_HAS_ScaLAPACK ScaLAPACK_Fortran_LOWER ScaLAPACK_Fortran_UNDERSCORE ) # If LAPACK has a full ScaLAPACK Linker, propagate vars @@ -168,6 +127,9 @@ if( NOT ScaLAPACK_LIBRARIES ) endforeach() endif( LAPACK_HAS_ScaLAPACK ) + + else() + find_linalg_dependencies( ScaLAPACK_LIBRARIES ) endif() # Handle implicit LAPACK linkage @@ -181,7 +143,7 @@ if( LAPACK_HAS_ScaLAPACK ) set( ScaLAPACK_LINK_OK TRUE ) else() check_pdpotrf_exists( ScaLAPACK_LIBRARIES - ScaLAPACK_LINK_OK ScaLAPACK_FORTRAN_LOWER ScaLAPACK_FORTRAN_UNDERSCORE + ScaLAPACK_LINK_OK ScaLAPACK_Fortran_LOWER ScaLAPACK_Fortran_UNDERSCORE ) endif() @@ -190,10 +152,10 @@ if( ScaLAPACK_LINK_OK ) # TODO: This requires running an MPI program, pretty dangerous #set( _pdpotrf_name "pdpotrf" ) - #if( NOT ScaLAPACK_FORTRAN_LOWER ) + #if( NOT ScaLAPACK_Fortran_LOWER ) # string( TOUPPER "${_pdpotrf_name}" _pdpotrf_name ) #endif() - #if( ScaLAPACK_FORTRAN_UNDERSCORE ) + #if( ScaLAPACK_Fortran_UNDERSCORE ) # set( _pdpotrf_name "${_pdpotrf_name}_" ) #endif() @@ -210,6 +172,13 @@ if( ScaLAPACK_LINK_OK ) else() set( ScaLAPACK_lp64_FOUND FALSE ) set( ScaLAPACK_ilp64_FOUND TRUE ) + find_dependency( ILP64 ) + list( APPEND ScaLAPACK_COMPILE_OPTIONS "${ILP64_COMPILE_OPTIONS}" ) + foreach ( lang C CXX Fortran ) + if ( DEFINED ILP64_${lang}_COMPILE_OPTIONS ) + list( APPEND ScaLAPACK_${lang}_COMPILE_OPTIONS "${ILP64_${lang}_COMPILE_OPTIONS}" ) + endif() + endforeach() endif() else() @@ -220,14 +189,15 @@ else() endif() - - - find_package_handle_standard_args( ScaLAPACK REQUIRED_VARS ScaLAPACK_LINK_OK HANDLE_COMPONENTS ) +# Cache variables +set( ScaLAPACK_IS_LP64 "${ScaLAPACK_IS_LP64}" CACHE STRING "ScaLAPACK LP64 Flag" FORCE ) +set( ScaLAPACK_LIBRARIES "${ScaLAPACK_LIBRARIES}" CACHE STRING "ScaLAPACK Libraries" FORCE ) + if( ScaLAPACK_FOUND AND NOT TARGET ScaLAPACK::ScaLAPACK ) add_library( ScaLAPACK::ScaLAPACK INTERFACE IMPORTED ) diff --git a/FindStandardFortran.cmake b/FindStandardFortran.cmake new file mode 100644 index 0000000..c58db6a --- /dev/null +++ b/FindStandardFortran.cmake @@ -0,0 +1,45 @@ +# +# This module will locate the Fortran standard libraries so that a Fortran +# object or library can be linked against using a C/C++ compiler. +# +# After calling this module the following will be set: +# STANDARDFORTRAN_LIBRARIES : A list of libraries to link against +# StandardFortran_FOUND : True if we found the standard Fortran libraries +# +# Implemenation note. CMake provides a variable +# CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES which is a list of all libraries a +# compiler implicitly links against. Unfortunately, at least for GNU, this +# list includes a lot of extra libraries that we don't necessarily want to +# link against (including both static and shared versions of libgcc). This is +# why we've hardcoded the list per compiler. +# +enable_language(Fortran) +include(FindPackageHandleStandardArgs) + +if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU") + set(STANDARDFORTRAN_LIBS gfortran) +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Intel") + set(STANDARDFORTRAN_LIBS ifcore) +elseif(CMAKE_Fortran_COMPILER_ID MATCHES "Flang") + set(STANDARDFORTRAN_LIBS flang flangrti pgmath) + #CMAKE_Fortran_COMPILER_ID does not give "ArmFlang" + if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") + set(STANDARDFORTRAN_LIBS armflang amath_a64fx) + endif() +else() + message(FATAL_ERROR "${CMAKE_Fortran_COMPILER_ID} is not yet supported by this module.") +endif() + +foreach(STANDARDFORTRAN_LIB ${STANDARDFORTRAN_LIBS}) + set(STANDARDFORTRAN_LIB_NAME + lib${STANDARDFORTRAN_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(${STANDARDFORTRAN_LIB}_LIBRARY + ${STANDARDFORTRAN_LIB_NAME} + HINTS ${CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES} + ) + list(APPEND STANDARDFORTRAN_LIBRARIES ${${STANDARDFORTRAN_LIB}_LIBRARY}) +endforeach() + +find_package_handle_standard_args(StandardFortran DEFAULT_MSG + STANDARDFORTRAN_LIBRARIES) +set(STANDARDFORTRAN_FOUND ${StandardFortran_FOUND}) diff --git a/FindTBB.cmake b/FindTBB.cmake new file mode 100644 index 0000000..f9ea7ab --- /dev/null +++ b/FindTBB.cmake @@ -0,0 +1,474 @@ +# based https://github.com/Kitware/VTK/blob/master/CMake/FindTBB.cmake +# +# CHANGES: +# - TBB_ROOT -> TBBROOT (tbb shell scripts set envvar TBBROOT) + +# - Find ThreadingBuildingBlocks include dirs and libraries +# Use this module by invoking find_package with the form: +# find_package(TBB +# [REQUIRED] # Fail with error if TBB is not found +# ) # +# Once done, this will define +# +# TBB_FOUND - system has TBB +# TBB_INCLUDE_DIRS - the TBB include directories +# TBB_LIBRARIES - TBB libraries to be linked, doesn't include malloc or +# malloc proxy +# TBB::tbb - imported target for the TBB library +# +# TBB_VERSION_MAJOR - Major Product Version Number +# TBB_VERSION_MINOR - Minor Product Version Number +# TBB_INTERFACE_VERSION - Engineering Focused Version Number +# TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major interface version +# still supported. This uses the engineering +# focused interface version numbers. +# +# TBB_MALLOC_FOUND - system has TBB malloc library +# TBB_MALLOC_INCLUDE_DIRS - the TBB malloc include directories +# TBB_MALLOC_LIBRARIES - The TBB malloc libraries to be lined +# TBB::malloc - imported target for the TBB malloc library +# +# TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library +# TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories +# TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined +# TBB::malloc_proxy - imported target for the TBB malloc proxy library +# +# +# This module reads hints about search locations from variables: +# ENV TBB_ARCH_PLATFORM - for eg. set it to "mic" for Xeon Phi builds +# ENV TBBROOT or just TBBROOT - root directory of tbb installation +# ENV TBB_BUILD_PREFIX - specifies the build prefix for user built tbb +# libraries. Should be specified with ENV TBBROOT +# and optionally... +# ENV TBB_BUILD_DIR - if build directory is different than ${TBBROOT}/build +# +# +# Modified by Robert Maynard from the original OGRE source +# +#------------------------------------------------------------------- +# This file is part of the CMake build system for OGRE +# (Object-oriented Graphics Rendering Engine) +# For the latest info, see http://www.ogre3d.org/ +# +# The contents of this file are placed in the public domain. Feel +# free to make use of it in any way you like. +#------------------------------------------------------------------- +# +#============================================================================= +# Copyright 2010-2012 Kitware, Inc. +# Copyright 2012 Rolf Eike Beer +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +#============================================================================= +# FindTBB helper functions and macros +# + +# Use TBBConfig.cmake if possible. + +set(_tbb_find_quiet) +if (TBB_FIND_QUIETLY) + set(_tbb_find_quiet QUIET) +endif () +set(_tbb_find_components) +set(_tbb_find_optional_components) +foreach (_tbb_find_component IN LISTS TBB_FIND_COMPONENTS) + if (TBB_FIND_REQUIRED_${_tbb_find_component}) + list(APPEND _tbb_find_components "${_tbb_find_component}") + else () + list(APPEND _tbb_find_optional_components "${_tbb_find_component}") + endif () +endforeach () +unset(_tbb_find_component) +find_package(TBB CONFIG ${_tbb_find_quiet} + COMPONENTS ${_tbb_find_components} + OPTIONAL_COMPONENTS ${_tbb_find_optional_components}) +unset(_tbb_find_quiet) +unset(_tbb_find_components) +unset(_tbb_find_optional_components) +if (TBB_FOUND) + return () +endif () + +#==================================================== +# Fix the library path in case it is a linker script +#==================================================== +function(tbb_extract_real_library library real_library) + if(NOT UNIX OR NOT EXISTS ${library}) + set(${real_library} "${library}" PARENT_SCOPE) + return() + endif() + + #Read in the first 4 bytes and see if they are the ELF magic number + set(_elf_magic "7f454c46") + file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX) + if(_hex_data STREQUAL _elf_magic) + #we have opened a elf binary so this is what + #we should link to + set(${real_library} "${library}" PARENT_SCOPE) + return() + endif() + + file(READ ${library} _data OFFSET 0 LIMIT 1024) + if("${_data}" MATCHES "INPUT \\(([^(]+)\\)") + #extract out the .so name from REGEX MATCH command + set(_proper_so_name "${CMAKE_MATCH_1}") + + #construct path to the real .so which is presumed to be in the same directory + #as the input file + get_filename_component(_so_dir "${library}" DIRECTORY) + set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE) + else() + #unable to determine what this library is so just hope everything works + #and pass it unmodified. + set(${real_library} "${library}" PARENT_SCOPE) + endif() +endfunction() + +#=============================================== +# Do the final processing for the package find. +#=============================================== +macro(findpkg_finish PREFIX TARGET_NAME) + if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) + set(${PREFIX}_FOUND TRUE) + set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) + set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) + else () + if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY) + message(FATAL_ERROR "Required library ${PREFIX} not found.") + endif () + endif () + + if (NOT TARGET "TBB::${TARGET_NAME}") + if (${PREFIX}_LIBRARY_RELEASE) + tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release) + endif () + if (${PREFIX}_LIBRARY_DEBUG) + tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug) + endif () + add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}") + if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_release}" + IMPORTED_LOCATION_DEBUG "${real_debug}" + IMPORTED_LOCATION_RELEASE "${real_release}") + elseif (${PREFIX}_LIBRARY_RELEASE) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_release}") + elseif (${PREFIX}_LIBRARY_DEBUG) + set_target_properties(TBB::${TARGET_NAME} PROPERTIES + IMPORTED_LOCATION "${real_debug}") + endif () + # on non-Windows platforms need C++ library + # tried IMPORTED_LINK_DEPENDENT_LIBRARIES + # and IMPORTED_LINK_INTERFACE_LANGUAGES (and changing UNKNOWN -> SHARED/STATIC in add_library) + # to pass this info, to no avail + if (NOT (WIN32 AND MSVC)) + if (USE_LIBCXX) + set(std_cxx_lib_name c++) + else (USE_LIBCXX) + set(std_cxx_lib_name stdc++) + endif (USE_LIBCXX) + target_link_libraries(TBB::${TARGET_NAME} INTERFACE ${std_cxx_lib_name}) + unset(std_cxx_lib_name) + endif () + endif () + + #mark the following variables as internal variables + mark_as_advanced(${PREFIX}_INCLUDE_DIR + ${PREFIX}_LIBRARY + ${PREFIX}_LIBRARY_DEBUG + ${PREFIX}_LIBRARY_RELEASE) +endmacro() + +#=============================================== +# Generate debug names from given release names +#=============================================== +macro(get_debug_names PREFIX) + foreach(i ${${PREFIX}}) + set(${PREFIX}_DEBUG ${${PREFIX}_DEBUG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i}) + endforeach() +endmacro() + +#=============================================== +# See if we have env vars to help us find tbb +#=============================================== +macro(getenv_path VAR) + set(ENV_${VAR} $ENV{${VAR}}) + # replace won't work if var is blank + if (ENV_${VAR}) + string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} ) + endif () +endmacro() + +#=============================================== +# Couple a set of release AND debug libraries +#=============================================== +macro(make_library_set PREFIX) + if (${PREFIX}_RELEASE AND ${PREFIX}_DEBUG) + set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG}) + elseif (${PREFIX}_RELEASE) + set(${PREFIX} ${${PREFIX}_RELEASE}) + elseif (${PREFIX}_DEBUG) + set(${PREFIX} ${${PREFIX}_DEBUG}) + endif () +endmacro() + + +#============================================================================= +# Now to actually find TBB +# + +# Get path, convert backslashes as ${ENV_${var}} +getenv_path(TBBROOT) + +# initialize search paths +set(TBB_PREFIX_PATH ${TBBROOT} ${ENV_TBBROOT}) +set(TBB_INC_SEARCH_PATH "") +set(TBB_LIB_SEARCH_PATH "") + + +# If user built from sources +set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX}) +if (TBB_BUILD_PREFIX AND ENV_TBBROOT) + getenv_path(TBB_BUILD_DIR) + if (NOT ENV_TBB_BUILD_DIR) + set(ENV_TBB_BUILD_DIR ${ENV_TBBROOT}/build) + endif () + + # include directory under ${ENV_TBBROOT}/include + list(APPEND TBB_LIB_SEARCH_PATH + ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release + ${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug) +endif () + + +# For Windows, let's assume that the user might be using the precompiled +# TBB packages from the main website. These use a rather awkward directory +# structure (at least for automatically finding the right files) depending +# on platform and compiler, but we'll do our best to accommodate it. +# Not adding the same effort for the precompiled linux builds, though. Those +# have different versions for CC compiler versions and linux kernels which +# will never adequately match the user's setup, so there is no feasible way +# to detect the "best" version to use. The user will have to manually +# select the right files. (Chances are the distributions are shipping their +# custom version of tbb, anyway, so the problem is probably nonexistent.) +if (WIN32 AND MSVC) + set(COMPILER_PREFIX "vc7.1") + if (MSVC_VERSION EQUAL 1400) + set(COMPILER_PREFIX "vc8") + elseif(MSVC_VERSION EQUAL 1500) + set(COMPILER_PREFIX "vc9") + elseif(MSVC_VERSION EQUAL 1600) + set(COMPILER_PREFIX "vc10") + elseif(MSVC_VERSION EQUAL 1700) + set(COMPILER_PREFIX "vc11") + elseif(MSVC_VERSION EQUAL 1800) + set(COMPILER_PREFIX "vc12") + elseif(MSVC_VERSION GREATER_EQUAL 1900) + set(COMPILER_PREFIX "vc14") + endif () + + # for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search path + foreach (dir IN LISTS TBB_PREFIX_PATH) + if (CMAKE_CL_64) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX}) + else () + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX}) + endif () + endforeach () +endif () + +# For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9) +# and above and AppleClang +if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND + NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0) + set (USE_LIBCXX OFF) + cmake_policy(GET CMP0025 POLICY_VAR) + + if (POLICY_VAR STREQUAL "NEW") + if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set (USE_LIBCXX ON) + endif () + else () + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set (USE_LIBCXX ON) + endif () + endif () + + if (USE_LIBCXX) + foreach (dir IN LISTS TBB_PREFIX_PATH) + list (APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib) + endforeach () + endif () +endif () + +# check compiler ABI +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(COMPILER_PREFIX) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + list(APPEND COMPILER_PREFIX "gcc4.8") + endif() + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + list(APPEND COMPILER_PREFIX "gcc4.7") + endif() + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) + list(APPEND COMPILER_PREFIX "gcc4.4") + endif() + list(APPEND COMPILER_PREFIX "gcc4.1") +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(COMPILER_PREFIX) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) # Complete guess + list(APPEND COMPILER_PREFIX "gcc4.8") + endif() + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6) + list(APPEND COMPILER_PREFIX "gcc4.7") + endif() + list(APPEND COMPILER_PREFIX "gcc4.4") +else() # Assume compatibility with 4.4 for other compilers + list(APPEND COMPILER_PREFIX "gcc4.4") +endif () + +# if platform architecture is explicitly specified +set(TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM}) +if (TBB_ARCH_PLATFORM) + foreach (dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM}) + endforeach () +endif () + +foreach (dir IN LISTS TBB_PREFIX_PATH) + foreach (prefix IN LISTS COMPILER_PREFIX) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib) + else () + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix}) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib) + endif () + endforeach() +endforeach () + +# add general search paths +foreach (dir IN LISTS TBB_PREFIX_PATH) + list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb + ${dir}/Libs) + list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include + ${dir}/include/tbb) +endforeach () + +set(TBB_LIBRARY_NAMES tbb) +get_debug_names(TBB_LIBRARY_NAMES) + + +find_path(TBB_INCLUDE_DIR + NAMES tbb/tbb.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library(TBB_LIBRARY_RELEASE + NAMES ${TBB_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library(TBB_LIBRARY_DEBUG + NAMES ${TBB_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) +make_library_set(TBB_LIBRARY) + +findpkg_finish(TBB tbb) + +#if we haven't found TBB no point on going any further +if (NOT TBB_FOUND) + return() +endif () + +#============================================================================= +# Look for TBB's malloc package +set(TBB_MALLOC_LIBRARY_NAMES tbbmalloc) +get_debug_names(TBB_MALLOC_LIBRARY_NAMES) + +find_path(TBB_MALLOC_INCLUDE_DIR + NAMES tbb/tbb.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library(TBB_MALLOC_LIBRARY_RELEASE + NAMES ${TBB_MALLOC_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library(TBB_MALLOC_LIBRARY_DEBUG + NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) +make_library_set(TBB_MALLOC_LIBRARY) + +findpkg_finish(TBB_MALLOC tbbmalloc) + +#============================================================================= +# Look for TBB's malloc proxy package +set(TBB_MALLOC_PROXY_LIBRARY_NAMES tbbmalloc_proxy) +get_debug_names(TBB_MALLOC_PROXY_LIBRARY_NAMES) + +find_path(TBB_MALLOC_PROXY_INCLUDE_DIR + NAMES tbb/tbbmalloc_proxy.h + PATHS ${TBB_INC_SEARCH_PATH}) + +find_library(TBB_MALLOC_PROXY_LIBRARY_RELEASE + NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES} + PATHS ${TBB_LIB_SEARCH_PATH}) +find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG + NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG} + PATHS ${TBB_LIB_SEARCH_PATH}) +make_library_set(TBB_MALLOC_PROXY_LIBRARY) + +findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy) + + +#============================================================================= +#parse all the version numbers from tbb +if(NOT TBB_VERSION) + if (EXISTS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h") + file(STRINGS + "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h" + TBB_VERSION_CONTENTS + REGEX "VERSION") + else() + #only read the start of the file + file(STRINGS + "${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h" + TBB_VERSION_CONTENTS + REGEX "VERSION") + endif() + + string(REGEX REPLACE + ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1" + TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE + ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1" + TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE + ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") + + string(REGEX REPLACE + ".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1" + TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}") + +endif() \ No newline at end of file diff --git a/LinAlgModulesMacros.cmake b/LinAlgModulesMacros.cmake index 5c42131..6e064f9 100644 --- a/LinAlgModulesMacros.cmake +++ b/LinAlgModulesMacros.cmake @@ -1,14 +1,71 @@ set( LINALG_MACROS_DIR ${CMAKE_CURRENT_LIST_DIR} ) +macro( find_linalg_dependencies _libs ) + include( CMakeFindDependencyMacro ) + foreach( _lib ${${_libs}} ) + if (${_lib} MATCHES "OpenMP") + find_dependency(OpenMP) + elseif (${_lib} MATCHES "Threads") + if (NOT TARGET Threads::Threads) + find_dependency(Threads) + # Threads::Threads by default is not GLOBAL, so to allow users of LINALG_LIBRARIES to safely use it we need to make it global + # more discussion here: https://gitlab.kitware.com/cmake/cmake/-/issues/17256 + set_target_properties(Threads::Threads PROPERTIES IMPORTED_GLOBAL TRUE) + endif(NOT TARGET Threads::Threads) + elseif (${_lib} MATCHES "tbb") + find_dependency(TBB) + elseif (${_lib} MATCHES "MPI") + find_dependency(MPI) + endif() + endforeach() +endmacro() + function( install_linalg_modules _dest_dir ) -install( DIRECTORY ${LINALG_MACROS_DIR} - DESTINATION ${${_dest_dir}} - FILES_MATCHING - REGEX "Find.*cmake" - REGEX "util/.*" - REGEX ".*git.*" EXCLUDE - REGEX ".*examples.*" EXCLUDE +set( LINALG_FIND_MODULES + FindBLAS.cmake + FindBLIS.cmake + FindIBMESSL.cmake + FindIntelMKL.cmake + FindLAPACK.cmake + FindOpenBLAS.cmake + FindReferenceBLAS.cmake + FindReferenceLAPACK.cmake + FindReferenceScaLAPACK.cmake + FindScaLAPACK.cmake + FindILP64.cmake + FindTBB.cmake + FindStandardFortran.cmake + LinAlgModulesMacros.cmake +) + +set( LINALG_UTIL_FILES + util/BLASUtilities.cmake + util/blis_int_size.c + util/func_check.c + util/get_mpi_vendor.c + util/ilp64_checker.c + util/lapack_ilp64_checker.c + util/openblas_int_size.c + util/CommonFunctions.cmake + util/IntrospectMPI.cmake + util/IntrospectOpenMP.cmake + util/LAPACKUtilities.cmake + util/ScaLAPACKUtilities.cmake ) + +list( TRANSFORM LINALG_FIND_MODULES + PREPEND ${LINALG_MACROS_DIR}/ ) +list( TRANSFORM LINALG_UTIL_FILES + PREPEND ${LINALG_MACROS_DIR}/ ) + +install( + FILES ${LINALG_FIND_MODULES} ${LINALG_MACROS_DIR}/LICENSE.txt + DESTINATION ${${_dest_dir}}/linalg-cmake-modules +) + +install( + FILES ${LINALG_UTIL_FILES} + DESTINATION ${${_dest_dir}}/linalg-cmake-modules/util ) endfunction() diff --git a/examples/blas/common.cmake b/examples/blas/common.cmake new file mode 100644 index 0000000..f134490 --- /dev/null +++ b/examples/blas/common.cmake @@ -0,0 +1,12 @@ +message( STATUS "BLAS_VENDOR = ${BLAS_VENDOR}" ) +message( STATUS "BLAS_LIBRARIES = ${BLAS_LIBRARIES}" ) +message( STATUS "BLAS_COMPILE_DEFINITIONS = ${BLAS_COMPILE_DEFINITIONS}" ) +message( STATUS "BLAS_COMPILE_OPTIONS = ${BLAS_COMPILE_OPTIONS}" ) +foreach (lang C CXX Fortran) + if (DEFINED BLAS_${lang}_COMPILE_OPTIONS) + message( STATUS "BLAS_${lang}_COMPILE_OPTIONS = ${BLAS_${lang}_COMPILE_OPTIONS}" ) + endif() +endforeach() +message( STATUS "BLAS_Fortran_LOWER = ${BLAS_Fortran_LOWER}" ) +message( STATUS "BLAS_Fortran_UNDERSCORE = ${BLAS_Fortran_UNDERSCORE}" ) +message( STATUS "BLAS_IS_LP64 = ${BLAS_IS_LP64}" ) diff --git a/examples/blas/default/CMakeLists.txt b/examples/blas/default/CMakeLists.txt index 4dc547c..5b1457a 100644 --- a/examples/blas/default/CMakeLists.txt +++ b/examples/blas/default/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(blas_test LANGUAGES C) -find_package( BLAS COMPONENTS ) -message( STATUS "BLAS_VENDOR = ${BLAS_VENDOR}" ) -message( STATUS "BLAS_LIBRARIES = ${BLAS_LIBRARIES}" ) -message( STATUS "BLAS_COMPILE_DEFINITIONS = ${BLAS_COMPILE_DEFINITIONS}" ) -message( STATUS "BLAS_FORTRAN_LOWER = ${BLAS_FORTRAN_LOWER}" ) -message( STATUS "BLAS_FORTRAN_UNDERSCORE = ${BLAS_FORTRAN_UNDERSCORE}" ) -message( STATUS "BLAS_IS_LP64 = ${BLAS_IS_LP64}" ) +find_package( BLAS REQUIRED ) +include( ../../blas/common.cmake ) diff --git a/examples/blas/ilp64/CMakeLists.txt b/examples/blas/ilp64/CMakeLists.txt index 26b18e8..c22a120 100644 --- a/examples/blas/ilp64/CMakeLists.txt +++ b/examples/blas/ilp64/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(blas_test LANGUAGES C) -find_package( BLAS COMPONENTS ilp64 ) -message( STATUS "BLAS_VENDOR = ${BLAS_VENDOR}" ) -message( STATUS "BLAS_LIBRARIES = ${BLAS_LIBRARIES}" ) -message( STATUS "BLAS_COMPILE_DEFINITIONS = ${BLAS_COMPILE_DEFINITIONS}" ) -message( STATUS "BLAS_FORTRAN_LOWER = ${BLAS_FORTRAN_LOWER}" ) -message( STATUS "BLAS_FORTRAN_UNDERSCORE = ${BLAS_FORTRAN_UNDERSCORE}" ) -message( STATUS "BLAS_IS_LP64 = ${BLAS_IS_LP64}" ) +find_package( BLAS REQUIRED COMPONENTS ilp64 ) +include( ../../blas/common.cmake ) diff --git a/examples/blas/lp64/CMakeLists.txt b/examples/blas/lp64/CMakeLists.txt index 77ea85b..866700c 100644 --- a/examples/blas/lp64/CMakeLists.txt +++ b/examples/blas/lp64/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(blas_test LANGUAGES C) -find_package( BLAS COMPONENTS lp64 ) -message( STATUS "BLAS_VENDOR = ${BLAS_VENDOR}" ) -message( STATUS "BLAS_LIBRARIES = ${BLAS_LIBRARIES}" ) -message( STATUS "BLAS_COMPILE_DEFINITIONS = ${BLAS_COMPILE_DEFINITIONS}" ) -message( STATUS "BLAS_FORTRAN_LOWER = ${BLAS_FORTRAN_LOWER}" ) -message( STATUS "BLAS_FORTRAN_UNDERSCORE = ${BLAS_FORTRAN_UNDERSCORE}" ) -message( STATUS "BLAS_IS_LP64 = ${BLAS_IS_LP64}" ) +find_package( BLAS REQUIRED COMPONENTS lp64 ) +include( ../../blas/common.cmake ) diff --git a/examples/ilp64/CMakeLists.txt b/examples/ilp64/CMakeLists.txt new file mode 100644 index 0000000..1dd62a7 --- /dev/null +++ b/examples/ilp64/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required( VERSION 3.17 FATAL_ERROR ) +project( check_ilp64 LANGUAGES C CXX Fortran ) + +find_package( ILP64 REQUIRED ) +add_executable( my_test_c test.c ) +add_executable( my_test_cxx test.cxx ) +add_executable( my_test_fortran test.f90 ) + +target_compile_options( my_test_c PUBLIC ${ILP64_COMPILE_OPTIONS} ) +target_compile_options( my_test_cxx PUBLIC ${ILP64_COMPILE_OPTIONS} ) +target_compile_options( my_test_fortran PUBLIC ${ILP64_COMPILE_OPTIONS} ) + +add_executable( my_test_c_2 test.c ) +add_executable( my_test_cxx_2 test.cxx ) +add_executable( my_test_fortran_2 test.f90 ) +target_compile_options( my_test_c PUBLIC ${ILP64_C_COMPILE_OPTIONS} ) +target_compile_options( my_test_cxx PUBLIC ${ILP64_CXX_COMPILE_OPTIONS} ) +target_compile_options( my_test_fortran PUBLIC ${ILP64_Fortran_COMPILE_OPTIONS} ) diff --git a/examples/ilp64/test.c b/examples/ilp64/test.c new file mode 100644 index 0000000..cd357bf --- /dev/null +++ b/examples/ilp64/test.c @@ -0,0 +1,3 @@ +int main(int argc, char** argv) { + return 0; +} diff --git a/examples/ilp64/test.cxx b/examples/ilp64/test.cxx new file mode 100644 index 0000000..cd357bf --- /dev/null +++ b/examples/ilp64/test.cxx @@ -0,0 +1,3 @@ +int main(int argc, char** argv) { + return 0; +} diff --git a/examples/ilp64/test.f90 b/examples/ilp64/test.f90 new file mode 100644 index 0000000..fb16805 --- /dev/null +++ b/examples/ilp64/test.f90 @@ -0,0 +1,3 @@ + program my_program + implicit none + end program my_program diff --git a/examples/lapack/common.cmake b/examples/lapack/common.cmake new file mode 100644 index 0000000..ee208a9 --- /dev/null +++ b/examples/lapack/common.cmake @@ -0,0 +1,12 @@ +message( STATUS "LAPACK_VENDOR = ${LAPACK_VENDOR}" ) +message( STATUS "LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}" ) +message( STATUS "LAPACK_COMPILE_DEFINITIONS = ${LAPACK_COMPILE_DEFINITIONS}" ) +message( STATUS "LAPACK_COMPILE_OPTIONS = ${LAPACK_COMPILE_OPTIONS}" ) +foreach (lang C CXX Fortran) + if (DEFINED LAPACK_${lang}_COMPILE_OPTIONS) + message( STATUS "LAPACK_${lang}_COMPILE_OPTIONS = ${LAPACK_${lang}_COMPILE_OPTIONS}" ) + endif() +endforeach() +message( STATUS "LAPACK_Fortran_LOWER = ${LAPACK_Fortran_LOWER}" ) +message( STATUS "LAPACK_Fortran_UNDERSCORE = ${LAPACK_Fortran_UNDERSCORE}" ) +message( STATUS "LAPACK_IS_LP64 = ${LAPACK_IS_LP64}" ) diff --git a/examples/lapack/default/CMakeLists.txt b/examples/lapack/default/CMakeLists.txt index 0c5df41..4cb5798 100644 --- a/examples/lapack/default/CMakeLists.txt +++ b/examples/lapack/default/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(lapack_test LANGUAGES C) -find_package( LAPACK COMPONENTS ) -message( STATUS "LAPACK_VENDOR = ${LAPACK_VENDOR}" ) -message( STATUS "LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}" ) -message( STATUS "LAPACK_COMPILE_DEFINITIONS = ${LAPACK_COMPILE_DEFINITIONS}" ) -message( STATUS "LAPACK_FORTRAN_LOWER = ${LAPACK_FORTRAN_LOWER}" ) -message( STATUS "LAPACK_FORTRAN_UNDERSCORE = ${LAPACK_FORTRAN_UNDERSCORE}" ) -message( STATUS "LAPACK_IS_LP64 = ${LAPACK_IS_LP64}" ) +find_package( LAPACK REQUIRED ) +include( ../../lapack/common.cmake ) \ No newline at end of file diff --git a/examples/lapack/ilp64/CMakeLists.txt b/examples/lapack/ilp64/CMakeLists.txt index 262636e..84be218 100644 --- a/examples/lapack/ilp64/CMakeLists.txt +++ b/examples/lapack/ilp64/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(lapack_test LANGUAGES C) -find_package( LAPACK COMPONENTS ilp64 ) -message( STATUS "LAPACK_VENDOR = ${LAPACK_VENDOR}" ) -message( STATUS "LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}" ) -message( STATUS "LAPACK_COMPILE_DEFINITIONS = ${LAPACK_COMPILE_DEFINITIONS}" ) -message( STATUS "LAPACK_FORTRAN_LOWER = ${LAPACK_FORTRAN_LOWER}" ) -message( STATUS "LAPACK_FORTRAN_UNDERSCORE = ${LAPACK_FORTRAN_UNDERSCORE}" ) -message( STATUS "LAPACK_IS_LP64 = ${LAPACK_IS_LP64}" ) +find_package( LAPACK REQUIRED COMPONENTS ilp64 ) +include( ../../lapack/common.cmake ) \ No newline at end of file diff --git a/examples/lapack/lp64/CMakeLists.txt b/examples/lapack/lp64/CMakeLists.txt index 40c8bb5..3efe500 100644 --- a/examples/lapack/lp64/CMakeLists.txt +++ b/examples/lapack/lp64/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(lapack_test LANGUAGES C) -find_package( LAPACK COMPONENTS lp64 ) -message( STATUS "LAPACK_VENDOR = ${LAPACK_VENDOR}" ) -message( STATUS "LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}" ) -message( STATUS "LAPACK_COMPILE_DEFINITIONS = ${LAPACK_COMPILE_DEFINITIONS}" ) -message( STATUS "LAPACK_FORTRAN_LOWER = ${LAPACK_FORTRAN_LOWER}" ) -message( STATUS "LAPACK_FORTRAN_UNDERSCORE = ${LAPACK_FORTRAN_UNDERSCORE}" ) -message( STATUS "LAPACK_IS_LP64 = ${LAPACK_IS_LP64}" ) +find_package( LAPACK REQUIRED COMPONENTS lp64 ) +include( ../../lapack/common.cmake ) \ No newline at end of file diff --git a/examples/scalapack/common.cmake b/examples/scalapack/common.cmake new file mode 100644 index 0000000..7ea9cf0 --- /dev/null +++ b/examples/scalapack/common.cmake @@ -0,0 +1,12 @@ +message( STATUS "ScaLAPACK_VENDOR = ${ScaLAPACK_VENDOR}" ) +message( STATUS "ScaLAPACK_LIBRARIES = ${ScaLAPACK_LIBRARIES}" ) +message( STATUS "ScaLAPACK_COMPILE_DEFINITIONS = ${ScaLAPACK_COMPILE_DEFINITIONS}" ) +message( STATUS "ScaLAPACK_COMPILE_OPTIONS = ${ScaLAPACK_COMPILE_OPTIONS}" ) +foreach (lang C CXX Fortran) + if (DEFINED ScaLAPACK_${lang}_COMPILE_OPTIONS) + message( STATUS "ScaLAPACK_${lang}_COMPILE_OPTIONS = ${ScaLAPACK_${lang}_COMPILE_OPTIONS}" ) + endif() +endforeach() +message( STATUS "ScaLAPACK_Fortran_LOWER = ${ScaLAPACK_Fortran_LOWER}" ) +message( STATUS "ScaLAPACK_Fortran_UNDERSCORE = ${ScaLAPACK_Fortran_UNDERSCORE}" ) +message( STATUS "ScaLAPACK_IS_LP64 = ${ScaLAPACK_IS_LP64}" ) diff --git a/examples/scalapack/default/CMakeLists.txt b/examples/scalapack/default/CMakeLists.txt index aa0743f..17c7710 100644 --- a/examples/scalapack/default/CMakeLists.txt +++ b/examples/scalapack/default/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(scalapack_test LANGUAGES C) -find_package( ScaLAPACK COMPONENTS ) -message( STATUS "ScaLAPACK_VENDOR = ${ScaLAPACK_VENDOR}" ) -message( STATUS "ScaLAPACK_LIBRARIES = ${ScaLAPACK_LIBRARIES}" ) -message( STATUS "ScaLAPACK_COMPILE_DEFINITIONS = ${ScaLAPACK_COMPILE_DEFINITIONS}" ) -message( STATUS "ScaLAPACK_FORTRAN_LOWER = ${ScaLAPACK_FORTRAN_LOWER}" ) -message( STATUS "ScaLAPACK_FORTRAN_UNDERSCORE = ${ScaLAPACK_FORTRAN_UNDERSCORE}" ) -message( STATUS "ScaLAPACK_IS_LP64 = ${ScaLAPACK_IS_LP64}" ) +find_package( ScaLAPACK REQUIRED ) +include( ../../scalapack/common.cmake ) \ No newline at end of file diff --git a/examples/scalapack/ilp64/CMakeLists.txt b/examples/scalapack/ilp64/CMakeLists.txt index 0dd9bed..b291fb6 100644 --- a/examples/scalapack/ilp64/CMakeLists.txt +++ b/examples/scalapack/ilp64/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(scalapack_test LANGUAGES C) -find_package( ScaLAPACK COMPONENTS ilp64 ) -message( STATUS "ScaLAPACK_VENDOR = ${ScaLAPACK_VENDOR}" ) -message( STATUS "ScaLAPACK_LIBRARIES = ${ScaLAPACK_LIBRARIES}" ) -message( STATUS "ScaLAPACK_COMPILE_DEFINITIONS = ${ScaLAPACK_COMPILE_DEFINITIONS}" ) -message( STATUS "ScaLAPACK_FORTRAN_LOWER = ${ScaLAPACK_FORTRAN_LOWER}" ) -message( STATUS "ScaLAPACK_FORTRAN_UNDERSCORE = ${ScaLAPACK_FORTRAN_UNDERSCORE}" ) -message( STATUS "ScaLAPACK_IS_LP64 = ${ScaLAPACK_IS_LP64}" ) +find_package( ScaLAPACK REQUIRED COMPONENTS ilp64 ) +include( ../../scalapack/common.cmake ) \ No newline at end of file diff --git a/examples/scalapack/lp64/CMakeLists.txt b/examples/scalapack/lp64/CMakeLists.txt index 323024f..bed3ae4 100644 --- a/examples/scalapack/lp64/CMakeLists.txt +++ b/examples/scalapack/lp64/CMakeLists.txt @@ -1,10 +1,5 @@ cmake_minimum_required( VERSION 3.10 ) project(scalapack_test LANGUAGES C) -find_package( ScaLAPACK COMPONENTS lp64 ) -message( STATUS "ScaLAPACK_VENDOR = ${ScaLAPACK_VENDOR}" ) -message( STATUS "ScaLAPACK_LIBRARIES = ${ScaLAPACK_LIBRARIES}" ) -message( STATUS "ScaLAPACK_COMPILE_DEFINITIONS = ${ScaLAPACK_COMPILE_DEFINITIONS}" ) -message( STATUS "ScaLAPACK_FORTRAN_LOWER = ${ScaLAPACK_FORTRAN_LOWER}" ) -message( STATUS "ScaLAPACK_FORTRAN_UNDERSCORE = ${ScaLAPACK_FORTRAN_UNDERSCORE}" ) -message( STATUS "ScaLAPACK_IS_LP64 = ${ScaLAPACK_IS_LP64}" ) +find_package( ScaLAPACK REQUIRED COMPONENTS lp64 ) +include( ../../scalapack/common.cmake ) \ No newline at end of file diff --git a/util/BLASUtilities.cmake b/util/BLASUtilities.cmake index 0bbf527..1d782f3 100644 --- a/util/BLASUtilities.cmake +++ b/util/BLASUtilities.cmake @@ -1,95 +1,5 @@ set( BLAS_UTILITY_CMAKE_FILE_DIR ${CMAKE_CURRENT_LIST_DIR} ) - -function( check_dgemm_exists _libs _link_ok _uses_lower _uses_underscore ) - -include( ${BLAS_UTILITY_CMAKE_FILE_DIR}/CommonFunctions.cmake ) - -set( ${_link_ok} FALSE ) -set( ${_uses_lower} ) -set( ${_uses_underscore} ) - - -foreach( _uplo LOWER UPPER ) - - set( _dgemm_name_template "dgemm" ) - string( TO${_uplo} ${_dgemm_name_template} _dgemm_name_uplo ) - - foreach( _under UNDERSCORE NO_UNDERSCORE ) - - set( _item BLAS_${_uplo}_${_under} ) - if( _under EQUAL "UNDERSCORE" ) - set( _dgemm_name "${_dgemm_name_uplo}_" ) - else() - set( _dgemm_name "${_dgemm_name_uplo}_" ) - endif() - - check_function_exists_w_results( - "${${_libs}}" ${_dgemm_name} _compile_output _compile_result - ) - - message( STATUS "Performing Test ${_item}" ) - if( _compile_result ) - - message( STATUS "Performing Test ${_item} -- found" ) - set( ${_link_ok} TRUE ) - string( COMPARE EQUAL "${_uplo}" "LOWER" ${_uses_lower} ) - string( COMPARE EQUAL "${_under}" "UNDERSCORE" ${_uses_underscore} ) - break() - - else() - - # Check for GFORTRAN - if( _compile_output MATCHES "gfortran" ) - - message( STATUS " * Mising GFORTRAN - Adding TO BLAS LINKER" ) - - list( APPEND ${_libs} "gfortran" ) - set( ${_libs} ${${_libs}} PARENT_SCOPE ) - - endif() - - # Recheck Compiliation - check_function_exists_w_results( - "${${_libs}}" ${_dgemm_name} _compile_output _compile_result - ) - - if( _compile_result ) - message( STATUS "Performing Test ${_item} -- found" ) - set( ${_link_ok} TRUE ) - string( COMPARE EQUAL "${_uplo}" "LOWER" ${_uses_lower} ) - string( COMPARE EQUAL "${_under}" "UNDERSCORE" ${_uses_underscore} ) - break() - else() - message( STATUS "Performing Test ${_item} -- not found" ) - endif() - - endif() - - endforeach() - - if( ${${_link_ok}} ) - break() - endif() - - unset( _dgemm_name_template ) - unset( _dgemm_name_uplo ) -endforeach() - -#cmake_pop_check_state() - - -set( ${_link_ok} ${${_link_ok}} PARENT_SCOPE ) -set( ${_uses_lower} ${${_uses_lower}} PARENT_SCOPE ) -set( ${_uses_underscore} ${${_uses_underscore}} PARENT_SCOPE ) - -endfunction() - - - - - - function( check_blas_int _libs _dgemm_name _libs_are_lp64 ) try_run( _run_result _compile_result ${CMAKE_CURRENT_BINARY_DIR} @@ -100,8 +10,11 @@ try_run( _run_result _compile_result ${CMAKE_CURRENT_BINARY_DIR} RUN_OUTPUT_VARIABLE _run_output ) +if (NOT _compile_result) + message(FATAL_ERROR "check_blas_int: try_run failed: _compile_output=${_compile_output}") +endif() -if( ${_run_result} EQUAL 0 ) +if( _run_output MATCHES "BLAS IS LP64" ) set( ${_libs_are_lp64} TRUE PARENT_SCOPE ) else() set( ${_libs_are_lp64} FALSE PARENT_SCOPE ) diff --git a/util/CommonFunctions.cmake b/util/CommonFunctions.cmake index 75065b5..26d66cc 100644 --- a/util/CommonFunctions.cmake +++ b/util/CommonFunctions.cmake @@ -44,6 +44,28 @@ set( COMMON_UTILITY_CMAKE_FILE_DIR ${CMAKE_CURRENT_LIST_DIR} ) +function( emulate_kitware_linalg_modules name ) + + if( DEFINED BLA_STATIC AND NOT DEFINED ${name}_PREFERS_STATIC ) + if( DEFINED CACHE{BLA_STATIC} ) + set( ${name}_PREFERS_STATIC ${BLA_STATIC} CACHE BOOL + "Use Static ${name} LIBRARIES" ) + else() + set( ${name}_PREFERS_STATIC ${BLA_STATIC} PARENT_SCOPE ) + endif() + endif() + + if( DEFINED BLA_VENDOR AND NOT DEFINED ${name}_PREFERENCE_LIST ) + if( DEFINED CACHE{BLA_VENDOR} ) + set( ${name}_PREFERENCE_LIST ${BLA_VENDOR} CACHE BOOL + "Use Static ${name} LIBRARIES" ) + else() + set( ${name}_PREFERENCE_LIST ${BLA_VENDOR} PARENT_SCOPE ) + endif() + endif() + +endfunction() + function( fill_out_prefix name ) #if( ${name}_PREFIX AND NOT ${name}_INCLUDE_DIR ) @@ -61,9 +83,9 @@ endfunction() function( copy_meta_data _src _dest ) - if( ${_src}_LIBRARIES AND NOT ${_dest}_LIBRARIES ) - set( ${_dest}_LIBRARIES ${${_src}_LIBRARIES} PARENT_SCOPE ) - endif() + #if( ${_src}_LIBRARIES AND NOT ${_dest}_LIBRARIES ) + # set( ${_dest}_LIBRARIES ${${_src}_LIBRARIES} PARENT_SCOPE ) + #endif() if( ${_src}_PREFIX AND NOT ${_dest}_PREFIX ) set( ${_dest}_PREFIX ${${_src}_PREFIX} PARENT_SCOPE ) @@ -77,6 +99,14 @@ function( copy_meta_data _src _dest ) set( ${_dest}_LIBRARY_DIR ${${_src}_LIBRARY_DIR} PARENT_SCOPE ) endif() + if( ${_src}_PREFERS_STATIC AND NOT ${_dest}_PREFERS_STATIC ) + set( ${_dest}_PREFERS_STATIC ${${_src}_PREFERS_STATIC} PARENT_SCOPE ) + endif() + + if( ${_src}_THREAD_LAYER AND NOT ${_dest}_THREAD_LAYER ) + set( ${_dest}_THREAD_LAYER ${${_src}_THREAD_LAYER} PARENT_SCOPE ) + endif() + endfunction() @@ -133,3 +163,129 @@ function( check_function_exists_w_results _libs _func _output _result ) set( ${_result} "${${_result}}" PARENT_SCOPE ) endfunction() + +function( append_possibly_missing_libs _linker_test __compile_output _orig_libs __new_libs ) + + + set( _tmp_libs ) + # Check for missing Fortran symbols + if( ${__compile_output} MATCHES "fortran" OR ${__compile_output} MATCHES "f90_" ) + message( STATUS + " * Missing Standard Fortran Libs - Adding to ${_linker_test} linker" ) + # Check for Standard Fortran Libraries + if(NOT STANDARDFORTRAN_LIBRARIES) + include(CMakeFindDependencyMacro) + find_dependency( StandardFortran ) + endif() + list( APPEND _tmp_libs "${STANDARDFORTRAN_LIBRARIES}" ) + endif() + + + if( ${__compile_output} MATCHES "omp_" ) + message( STATUS + " * Missing OpenMP - Adding to ${_linker_test} linker" ) + if( NOT TARGET OpenMP::OpenMP_C ) + find_dependency( OpenMP ) + endif() + list( APPEND _tmp_libs OpenMP::OpenMP_C ) + endif() + + if( ${__compile_output} MATCHES "pthread_" ) + message( STATUS + " * Missing PThreads - Adding to ${_linker_test} linker" ) + if( NOT TARGET Threads::Threads ) + find_dependency( Threads ) + # Threads::Threads by default is not GLOBAL, so to allow users of LINALG_LIBRARIES to safely use it we need to make it global + # more discussion here: https://gitlab.kitware.com/cmake/cmake/-/issues/17256 + set_target_properties(Threads::Threads PROPERTIES IMPORTED_GLOBAL TRUE) + endif() + list( APPEND _tmp_libs Threads::Threads ) + endif() + + if( ${__compile_output} MATCHES "logf" OR ${__compile_output} MATCHES "sqrt" ) + message( STATUS + " * Missing LIBM - Adding to ${_linker_test} linker" ) + list( APPEND _tmp_libs "m" ) + endif() + + set( ${__new_libs} "${_tmp_libs}" PARENT_SCOPE ) + +endfunction() + +# _funcs = LIST of lowercase symbol name +# _namespace = namespace (BLAS, LAPACK, etc.) +function( check_fortran_functions_exist _funcs _namespace _libs _link_ok _uses_lower _uses_underscore ) + + set( ${_link_ok} FALSE ) + set( ${_uses_lower} ) + set( ${_uses_underscore} ) + + foreach( _uplo LOWER UPPER ) + + foreach( _under UNDERSCORE NO_UNDERSCORE ) + + set( _item ${_namespace}_${_uplo}_${_under} ) + message( STATUS "Performing Test ${_item}" ) + + # ask linker for each symbol in _funcs, exit early if any fail + foreach( _func IN LISTS _funcs) + + set( _${_func}_name_template "${_func}" ) + string( TO${_uplo} ${_${_func}_name_template} _${_func}_name_uplo ) + if( _under EQUAL "UNDERSCORE" ) + set( _${_func}_name "${_${_func}_name_uplo}_" ) + else() + set( _${_func}_name "${_${_func}_name_uplo}_" ) + endif() + + check_function_exists_w_results( + "${${_libs}}" ${_${_func}_name} _compile_output _compile_result + ) + + if( NOT _compile_result ) + + append_possibly_missing_libs( ${_namespace} _compile_output ${_libs} _new_libs ) + list( APPEND ${_libs} ${_new_libs} ) + set( ${_libs} ${${_libs}} PARENT_SCOPE ) + + # try linking again + check_function_exists_w_results( + "${${_libs}}" ${_${_func}_name} _compile_output _compile_result + ) + + endif() + + unset( _${_func}_name_template ) + unset( _${_func}_name_uplo ) + + if( _compile_result ) + set( ${_link_ok} TRUE ) + string( COMPARE EQUAL "${_uplo}" "LOWER" ${_uses_lower} ) + string( COMPARE EQUAL "${_under}" "UNDERSCORE" ${_uses_underscore} ) + else() + break() # early exit foreach if linking failed for any symbol even with extra libs + endif() + + endforeach() # _funcs + + if( ${${_link_ok}} ) + message( STATUS "Performing Test ${_item} -- found" ) + break() + else () + message( STATUS "Performing Test ${_item} -- not found" ) + endif() + + endforeach() # underscore + + if( ${${_link_ok}} ) + break() + endif() + + endforeach() # lowerupper + + + set( ${_link_ok} ${${_link_ok}} PARENT_SCOPE ) + set( ${_uses_lower} ${${_uses_lower}} PARENT_SCOPE ) + set( ${_uses_underscore} ${${_uses_underscore}} PARENT_SCOPE ) + +endfunction() diff --git a/util/LAPACKUtilities.cmake b/util/LAPACKUtilities.cmake index 2a7162d..ed78c03 100644 --- a/util/LAPACKUtilities.cmake +++ b/util/LAPACKUtilities.cmake @@ -1,118 +1,23 @@ set( LAPACK_UTILITY_CMAKE_FILE_DIR ${CMAKE_CURRENT_LIST_DIR} ) -function( check_dpstrf_exists _libs _link_ok _uses_lower _uses_underscore ) - -include( ${LAPACK_UTILITY_CMAKE_FILE_DIR}/CommonFunctions.cmake ) - -set( ${_link_ok} FALSE ) -set( ${_uses_lower} ) -set( ${_uses_underscore} ) - -foreach( _uplo LOWER UPPER ) +function( check_lapack_int _libs _dsyev_name _libs_are_lp64 ) - set( _dpstrf_name_template "dpstrf" ) - string( TO${_uplo} ${_dpstrf_name_template} _dpstrf_name_uplo ) - - foreach( _under UNDERSCORE NO_UNDERSCORE ) + try_run( _run_result _compile_result ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${LAPACK_UTILITY_CMAKE_FILE_DIR}/lapack_ilp64_checker.c + LINK_LIBRARIES ${${_libs}} + COMPILE_DEFINITIONS "-DDSYEV_NAME=${_dsyev_name}" + COMPILE_OUTPUT_VARIABLE _compile_output + RUN_OUTPUT_VARIABLE _run_output + ) - set( _item LAPACK_${_uplo}_${_under} ) - if( _under EQUAL "UNDERSCORE" ) - set( _dpstrf_name "${_dpstrf_name_uplo}_" ) - else() - set( _dpstrf_name "${_dpstrf_name_uplo}_" ) + if (NOT _compile_result) + message(FATAL_ERROR "check_lapack_int: try_run failed: _compile_output=${_compile_output}") endif() - check_function_exists_w_results( - "${${_libs}}" ${_dpstrf_name} _compile_output _compile_result - ) - - message( STATUS "Performing Test ${_item}" ) - if( _compile_result ) - - message( STATUS "Performing Test ${_item} -- found" ) - set( ${_link_ok} TRUE ) - string( COMPARE EQUAL "${_uplo}" "LOWER" ${_uses_lower} ) - string( COMPARE EQUAL "${_under}" "UNDERSCORE" ${_uses_underscore} ) - break() - + if( _run_output MATCHES "LAPACK IS LP64" ) + set( ${_libs_are_lp64} TRUE PARENT_SCOPE ) else() - - #message( STATUS ${_compile_output} ) - - # Check for GFORTRAN - if( _compile_output MATCHES "_gfortran" ) - - message( STATUS " * Mising GFORTRAN - Adding TO LAPACK LINKER" ) - - list( APPEND ${_libs} "gfortran" ) - set( ${_libs} ${${_libs}} PARENT_SCOPE ) - - endif() - - if( _compile_output MATCHES "logf" ) - - message( STATUS " * Mising LIBM - Adding TO LAPACK LINKER" ) - - list( APPEND ${_libs} "m" ) - set( ${_libs} ${${_libs}} PARENT_SCOPE ) - - endif() - - # Recheck Compiliation - check_function_exists_w_results( - "${${_libs}}" ${_dpstrf_name} _compile_output _compile_result - ) - - if( _compile_result ) - message( STATUS "Performing Test ${_item} -- found" ) - set( ${_link_ok} TRUE ) - string( COMPARE EQUAL "${_uplo}" "LOWER" ${_uses_lower} ) - string( COMPARE EQUAL "${_under}" "UNDERSCORE" ${_uses_underscore} ) - break() - else() - message( STATUS "Performing Test ${_item} -- not found" ) - endif() - + set( ${_libs_are_lp64} FALSE PARENT_SCOPE ) endif() - endforeach() - - if( ${${_link_ok}} ) - break() - endif() - - unset( _dpstrf_name_template ) - unset( _dpstrf_name_uplo ) -endforeach() - -#cmake_pop_check_state() - - -set( ${_link_ok} ${${_link_ok}} PARENT_SCOPE ) -set( ${_uses_lower} ${${_uses_lower}} PARENT_SCOPE ) -set( ${_uses_underscore} ${${_uses_underscore}} PARENT_SCOPE ) - endfunction() - - - - -function( check_lapack_int _libs _dsyev_name _libs_are_lp64 ) - -try_run( _run_result _compile_result ${CMAKE_CURRENT_BINARY_DIR} - SOURCES ${LAPACK_UTILITY_CMAKE_FILE_DIR}/lapack_ilp64_checker.c - LINK_LIBRARIES ${${_libs}} - COMPILE_DEFINITIONS "-DDSYEV_NAME=${_dsyev_name}" - COMPILE_OUTPUT_VARIABLE _compile_output - RUN_OUTPUT_VARIABLE _run_output -) - -#message( STATUS ${_run_result} ) - -if( ${_run_result} EQUAL 0 ) - set( ${_libs_are_lp64} TRUE PARENT_SCOPE ) -else() - set( ${_libs_are_lp64} FALSE PARENT_SCOPE ) -endif() - -endfunction() diff --git a/util/ScaLAPACKUtilities.cmake b/util/ScaLAPACKUtilities.cmake index 12b2c7d..a77190e 100644 --- a/util/ScaLAPACKUtilities.cmake +++ b/util/ScaLAPACKUtilities.cmake @@ -37,28 +37,11 @@ foreach( _uplo LOWER UPPER ) else() - #message( STATUS ${_compile_output} ) + append_possibly_missing_libs( ScaLAPACK _compile_output ${_libs} _new_libs ) + list( APPEND ${_libs} ${_new_libs} ) + set( ${_libs} ${${_libs}} PARENT_SCOPE ) - # Check for GFORTRAN - if( _compile_output MATCHES "_gfortran" ) - - message( STATUS " * Mising GFORTRAN - Adding TO ScaLAPACK LINKER" ) - - list( APPEND ${_libs} "gfortran" ) - set( ${_libs} ${${_libs}} PARENT_SCOPE ) - - endif() - - if( _compile_output MATCHES "logf" ) - - message( STATUS " * Mising LIBM - Adding TO ScaLAPACK LINKER" ) - - list( APPEND ${_libs} "m" ) - set( ${_libs} ${${_libs}} PARENT_SCOPE ) - - endif() - - # Recheck Compiliation + # Recheck Compilation check_function_exists_w_results( "${${_libs}}" ${_pdpotrf_name} _compile_output _compile_result ) diff --git a/util/blis_int_size.c b/util/blis_int_size.c index 9b1a368..96d5733 100644 --- a/util/blis_int_size.c +++ b/util/blis_int_size.c @@ -1,3 +1,4 @@ +#if 0 //#define BLIS_PARAM_MACRO_DEFS_H //#define BLIS_OBJ_MACRO_DEFS_H //#define BLIS_MISC_MACRO_DEFS_H @@ -30,7 +31,7 @@ void bli_thread_range_sub thrinfo_t* thread, dim_t n, dim_t bf, - bool handle_edge_low, + bool_t handle_edge_low, dim_t* start, dim_t* end ){ } @@ -67,7 +68,7 @@ void bli_obj_scalar_detach obj_t* a, obj_t* alpha ){ } -bool bli_obj_imag_is_zero( obj_t* a ){ } +bool_t bli_obj_imag_is_zero( obj_t* a ){ } double round( double x) {} int main() { @@ -75,3 +76,11 @@ int main() { if( blis_int_size == 32 ) return 0; else return 1; } +#else +#include +int main() { + int blis_int_size = BLIS_BLAS_INT_TYPE_SIZE; + if( blis_int_size == 32 ) return 0; + else return 1; +} +#endif diff --git a/util/ilp64_checker.c b/util/ilp64_checker.c index 253deb4..58c5925 100644 --- a/util/ilp64_checker.c +++ b/util/ilp64_checker.c @@ -35,10 +35,15 @@ int main() { double sum = 0.; int i; for( i = 0; i < 4; ++i ) sum += C[i]; - //printf("BLAS LP64 CHECK = %.1f\n", sum); + +#if 0 if( ((int)sum) == 8 ) return 0; else return 1; +#else + if( ((int)sum) == 8 ) printf("XXXX BLAS IS LP64 XXXX\n" ); + else printf("XXXX BLAS IS ILP64 XXXX\n"); +#endif return 0; }; diff --git a/util/lapack_ilp64_checker.c b/util/lapack_ilp64_checker.c index 2ea9187..7593bee 100644 --- a/util/lapack_ilp64_checker.c +++ b/util/lapack_ilp64_checker.c @@ -29,7 +29,12 @@ int main() { // Valid for MKL, OpenBLAS, NETLIB (Reference) LAPACK, and ESSL DSYEV_NAME( "N","L", fake_two_ptr, A, true_two_ptr, W, &WORK, LWORK, INFO ); +#if 0 if( INFO[0] == 0 ) return 0; else return -1; +#else + if( INFO[0] == 0 ) printf("XXXX LAPACK IS LP64 XXXX\n" ); + else printf("XXXX LAPACK IS ILP64 XXXX\n"); +#endif };