diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index caff407457..30c18aa073 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,6 @@ default: before_script: - echo 'localhost slots=8' > /etc/openmpi/openmpi-default-hostfile - apt-get install -yq intel-mkl-core-c-2020.4-304 - - ln -s /opt/intel/compilers_and_libraries_2020.4.304/linux/mkl/ /opt/intel/ build: stage: build @@ -16,16 +15,21 @@ build: image: valeevgroup/${IMAGE} variables: CXX: ${CXX} - ENABLE_MKL : "ENABLE_MKL=OFF" + TA_PYTHON : "TA_PYTHON=OFF" + BLAS : "" ENABLE_SCALAPACK : "ENABLE_SCALAPACK=OFF" script: - mkdir build - cd build + - |- + if [[ "X$BLAS" != "X" ]]; then + source /opt/intel/compilers_and_libraries_2020.4.304/linux/mkl/bin/mklvars.sh intel64 + fi - ../bin/gitlab-ci.sh .. CMAKE_BUILD_TYPE=${BUILD_TYPE} ${TA_PYTHON} - ${ENABLE_MKL} ${ENABLE_SCALAPACK} + ${BLAS} MPIEXEC_PREFLAGS="--allow-run-as-root" blacs_LIBRARIES=scalapack-openmpi scalapack_LIBRARIES=scalapack-openmpi @@ -35,7 +39,7 @@ build: - IMAGE : [ "ubuntu:20.04" ] CXX: [ g++, clang++-9 ] BUILD_TYPE : [ "Release", "Debug" ] - ENABLE_MKL : [ "ENABLE_MKL=ON", "ENABLE_MKL=OFF" ] + BLAS : [ "BLA_VENDOR=Intel10_64lp_seq", "BLA_VENDOR=Intel10_64lp", "" ] ENABLE_SCALAPACK : [ "ENABLE_SCALAPACK=ON", "ENABLE_SCALAPACK=OFF" ] - IMAGE : [ "ubuntu:18.04", "ubuntu:20.04" ] CXX: [ g++ ] diff --git a/CMakeLists.txt b/CMakeLists.txt index e22ea821df..e969c794d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,9 +105,6 @@ add_feature_info(MPI ENABLE_MPI "Message-Passing Interface supports distributed- option(ENABLE_SCALAPACK "Enable ScaLAPACK Bindings in TiledArray" OFF) add_feature_info(ScaLAPACK ENABLE_SCALAPACK "ScaLAPACK provides distributed linear algebra") -redefaultable_option(ENABLE_MKL "Enable use of MKL (info passed to MADNESS)" ON) -add_feature_info(MKL ENABLE_MKL "Intel Math Kernel Library provides linear algebra and other math functionality") - redefaultable_option(ENABLE_TBB "Enable use of TBB with MADNESS" OFF) add_feature_info(TBB ENABLE_TBB "Intel Thread-Building Blocks (TBB) supports programming shared-memory systems") @@ -293,15 +290,19 @@ include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src) add_custom_target(External-tiledarray) # required deps: +# 1. CUDA first since others may depend on it +if(ENABLE_CUDA) + include(external/cuda.cmake) +endif() include(external/madness.cmake) detect_MADNESS_configuration() include(external/eigen.cmake) -# find BTAS first, so that it finds Boost more carefully and also has a chance to memorize where it found it +# BTAS does a better job of building and checking Boost since it uses Boost::serialization +# it also memorized the location of its config for use from install tree include(FindOrFetchBTAS) -include(external/boost.cmake) -if(ENABLE_CUDA) - include(external/cuda.cmake) -endif() +# this generates blaspp_headers needed to include header files associated with the BLAS++ libraries +include(FindBLASPPHeaders) +include(FindOrFetchBoost) if(ENABLE_SCALAPACK) include(external/scalapack.cmake) endif() diff --git a/INSTALL.md b/INSTALL.md index c1d82ec046..aeac59eb62 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,6 @@ -# Synopsis +# TiledArray Installation Guide + +## Synopsis ```.cpp $ git clone https://github.com/ValeevGroup/TiledArray.git tiledarray @@ -12,7 +14,15 @@ $ cmake --build build $ cmake --build build --target install ``` -# Prerequisites +## Introduction + +There are 2 ways to build TiledArray: +- by searching for pre-compiled dependencies first; some dependencies, if they are not found, TiledArray will build from source, and +- by building all critical dependencies from source. + +Both methods are supported. However, for most users we _strongly_ recommend to build as many dependencies from source as possible. Only package maintainers have necessary expertise to properly build TiledArray from separately built components. Hence by default TiledArray will not look for precompiled versions of critical dependencies (MADNESS, BTAS, etc.). + +## Prerequisites - C++ compiler with support for the [C++17 standard](http://www.iso.org/standard/68564.html), or a more recent standard. This includes the following compilers: - [GNU C++](https://gcc.gnu.org/), version 7.0 or higher @@ -30,24 +40,28 @@ $ cmake --build build --target install - Boost.Container: header-only - Boost.Test: header-only or (optionally) as a compiled library, *only used for unit testing* - Boost.Range: header-only, *only used for unit testing* -- [BTAS](https://github.com/ValeevGroup/BTAS), tag 52cd6dba22aea0da3ccaf2e3c2ee00f821621d3f (will be downloaded automatically, if missing) -- BLAS library -- [MADNESS](https://github.com/m-a-d-n-e-s-s/madness), tag 925552feaf326cca8e83de7bd042074ad3cfd3f1 . +- [BTAS](https://github.com/ValeevGroup/BTAS), tag bd42eb3a2b84a46953edc7a8f7afbe5c98efa2c5 . If usable BTAS installation is not found, TiledArray will download and compile + BTAS from source. *This is the recommended way to compile BTAS for all users*. +- [MADNESS](https://github.com/m-a-d-n-e-s-s/madness), tag b22ee85059e6ccc9a6e803ba0550652ece8d9df1 . Only the MADworld runtime and BLAS/LAPACK C API component of MADNESS is used by TiledArray. If usable MADNESS installation is not found, TiledArray will download and compile - MADNESS. *This is the recommended way to compile MADNESS for all users*. + MADNESS from source. *This is the recommended way to compile MADNESS for all users*. A detailed list of MADNESS prerequisites can be found at [MADNESS' INSTALL file](https://github.com/m-a-d-n-e-s-s/madness/blob/master/INSTALL_CMake); it also also contains detailed MADNESS compilation instructions. - Compiling MADNESS requires the following prerequisites: +Compiling MADNESS requires the following prerequisites: - An implementation of Message Passing Interface version 2 or 3, with support for `MPI_THREAD_MULTIPLE`. - - BLAS and LAPACK libraries (only BLAS is used by TiledArray, but without LAPACK MADNESS will not compile) - (optional) - Intel Thread Building Blocks (TBB), available in a [commercial](software.intel.com/tbb‎) or + Intel Thread Building Blocks (TBB), available in a [commercial](software.intel.com/tbb) or an [open-source](https://www.threadingbuildingblocks.org/) form +Compiling BTAS requires the following prerequisites: + - [blaspp](https://bitbucket.org/icl/blaspp.git) -- C++ API for BLAS + - [lapackpp](https://bitbucket.org/icl/lapackpp.git) -- C++ API for LAPACK + - BLAS and LAPACK libraries + Optional prerequisites: - [CUDA compiler and runtime](https://developer.nvidia.com/cuda-zone) -- for execution on CUDA-enabled accelerators. CUDA 11 or later is required. Support for CUDA also requires the following additional prerequisites, both of which will be built and installed automatically if missing: - [cuTT](github.com/ValeevGroup/cutt) -- CUDA transpose library; note that our fork of the [original cuTT repo](github.com/ap-hynninen/cutt) is required to provide thread-safety (tag 0e8685bf82910bc7435835f846e88f1b39f47f09). @@ -59,13 +73,13 @@ Optional prerequisites: - Python3 interpreter -- to test (optionally-built) Python bindings - [Range-V3](https://github.com/ericniebler/range-v3.git) -- a Ranges library that served as the basis for Ranges component of C++20; only used for some unit testing of the functionality anticipated to be supported by future C++ standards. -Most of the dependencies (except for MADNESS) can be installed with a package manager, +Most of the dependencies (except for MADNESS and BTAS) can be installed with a package manager, such as Homebrew on OS X or apt-get on Debian Linux distributions; this is the preferred method. Since on some systems configuring and building MADNESS can be difficult even for experts, we recommend letting the TiledArray download and build MADNESS for you. -# Obtain TiledArray source code +## Obtain TiledArray source code Check out the source code as follows: @@ -84,25 +98,21 @@ Instructions below assume that you are located in the build directory. We will a the environment variable `TILEDARRAY_SOURCE_DIR` specifies the location of the TiledArray source tree. -# Configure TiledArray +## Configure TiledArray TiledArray is configured and built with CMake. When configuring with CMake, you specify a set of CMake variables on the command line, where each variable argument is prepended with the '-D' option. Typically, you will need to specify the install path for TiledArray, -build type, MPI Compiler wrappers, and BLAS and LAPACK libraries. - -For many platforms TiledArray provides *toolchain* files that can greatly simplify configuration; -they are located under `$TILEDARRAY_SOURCE_DIR/cmake/toolchains`. -It is strongly recommended that all users use one of the provided toolchains as is or as the -basis for a custom toolchain file. -Here's how to compile TiledArray on a macOS system: +build type, and MPI Compiler wrappers. +For basic builds you may not need to provide any arguments to CMake, however most users will want to nudge CMake towards configuring TiledArray as desired by specifying the C++ compiler to use, the MPI compiler wrapper to use, etc. The Valeev Research Group provides a number of toolchain files that can be used to specify a generic or a specific platform, e.g. to compile MPQC on MacOS use this script: ``` $ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/tiledarray \ -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_TOOLCHAIN_FILE=cmake/vg/toolchains/macos-clang-mpi-accelerate.cmake \ $TILEDARRAY_SOURCE_DIR ``` +Note that the `macos-clang-mpi-accelerate` toolchain file is part of the [the Valeev Group CMake kit](https://github.com/ValeevGroup/kit-cmake/tree/master/toolchains) which is downloaded and placed within the build tree by CMake at configure time. Following are several common examples of configuring TiledArray where instead of a toolchain file we specify CMake variables "manually" (on the command line). @@ -206,74 +216,53 @@ to use TiledArray in a distributed memory environment. Note, if you build MADNESS yourself, you must also configure MADNESS with `ENABLE_MPI=OFF` to enable this option. -## BLAS and LAPACK +## BLAS/LAPACK -TiledArray requires a serial BLAS implementation, either by linking with a +Even for basic operation TiledArray requires a serial BLAS implementation, either by linking with a serial version of the BLAS library or by setting the number of threads to one (1) with an environment variable. This is necessary because TiledArray evaluates tensor expressions in parallel by subdividing them into small tasks, each of which is assumed to be single-threaded; attempting to run a multi-threaded BLAS function inside -tasks will oversubscribe the hardware cores. - -BLAS library dependency is provided by the MADNESS library, which checks for presence -of BLAS and LAPACK (which also depends on BLAS) at the configure time. Therefore, if -MADNESS is already installed on your machine you do not need to do anything. However, -the most common scenario is where TiledArray will configure and compile -MADNESS as part of its compilation; in this case it is necessary to specify -how to find the LAPACK library to TiledArray, which will in turn pass this info -to MADNESS. This is done by setting the following -CMake variables: - -* `LAPACK_LIBRARIES` -- a string specifying LAPACK libraries and all of its dependencies (such as BLAS library, math library, etc.); this string can also include linker directory flags (`-L`) -* `LAPACK_INCLUDE_DIRS` -- (optional) a list of directories which contain BLAS/LAPACK-related header files -* `LAPACK_COMPILE_DEFINITIONS` -- (optional) a list of preprocessor definitions required for any code that uses BLAS/LAPACK-related header files -* `LAPACK_COMPILE_OPTIONS` -- (optional) a list of compiler options required for any code that uses BLAS/LAPACK-related header files -* `BLA_STATIC` -- indicates whether static or shared LAPACK and BLAS libraries will be preferred. +tasks will oversubscribe the hardware cores (this only exception to this if the MADNESS +runtime uses the same task backend as the BLAS library; this only happens if MADNESS +is configured to use Intel TBB and TBB-based Intel MKL library is used). Thus +it is user's responsibility to correctly specify the BLAS/LAPACK libraries and/or +set the environment variables (e.g. `OMP_NUM_THREADS`, `MKL_NUM_THREADS`, etc.) +to ensure single-threaded execution of BLAS/LAPACK kernels +as needed. -The last three variables are only needed if your code will use non-Fortran BLAS/LAPACK library API (such as CBLAS or LAPACKE) -and thus needs access to the header files. TiledArray only uses BLAS via the Fortran API, hence the last three -variables do not need to be specified. -Since TiledArray uses the Fortran API of BLAS, it may be necessary to -specify the Fortran integer size used by the particular BLAS library: +As of version 1.0 TiledArray also provides a direct (non-iterative) linear solvers API +implemented using LAPACK and (optionally) ScaLAPACK. Therefore LAPACK is now a mandatory +prerequisite of TiledArray -* `INTEGER4` -- Specifies the integer size (in bytes) assumed by the BLAS/LAPACK Fortran API [Default=TRUE] - TRUE = Fortran integer*4, FALSE = Fortran integer*8 +BLAS/LAPACK dependencies are provided by the BTAS library, which in turn uses BLAS++/LAPACK++ +C++ linear algebra packages to discover the BLAS and LAPACK libraries at configure time. +The most common scenario is where TiledArray will configure and compile BTAS dependency +and its BLAS++/LAPACK++ prerequisites from source (this is strongly recommended). The following +CMake variables can be used to control how BLAS/LAPACK discovery occurs: -You should use the default value unless you know it is necessary for your BLAS -implementation. - -Common optimized libraries OpenBLAS/GotoBLAS, BLIS, MKL (on Intel platforms), -Atlas, Accelerate (on OS X), ESSL (on BlueGene platforms), or ACML (on AMD -platforms). You can also use the Netlib reference implementation if nothing else -is available, but this will be very slow. - -Example flags: - -* Accelerate on OS X - - -D LAPACK_LIBRARIES="-framework Accelerate" - -* OpenBLAS with Netlib LAPACK - - -D LAPACK_LIBRARIES="-L/path/to/lapack/lib -llapack -L/path/to/openblas/lib -lopenblas -lpthread" +* `BLA_STATIC` -- indicates whether static or shared LAPACK and BLAS libraries will be preferred. +* `BLA_VENDOR` -- controls which vendor BLAS/LAPACK library will be sought + (see [CMake docs](https://cmake.org/cmake/help/latest/module/FindLAPACK.html)); + by default all possible vendor libraries will be considered. E.g., to force the use of the Accelerate + framework on MacOS use `-DBLA_VENDOR=Apple`. -* Netlib +More information can be found in the installation instructions for +[BLAS++](https://icl.bitbucket.io/blaspp/md__i_n_s_t_a_l_l.html) and +[LAPACK++](https://icl.bitbucket.io/lapackpp/md__i_n_s_t_a_l_l.html). - -D LAPACK_LIBRARIES="-L/path/to/lapack/lib -llapack -L/path/to/blas/lib -lblas" +Additional platform-specific BLAS/LAPACK notes are listed below. -* MKL on Linux +### Intel Math Kernel Library (MKL) - -D LAPACK_LIBRARIES="-L${MKLROOT}/lib/intel64 -Wl,--start-group -lmkl_intel_lp64 -lmkl_core -lmkl_sequential -Wl,--end-group -lpthread -lm” - -* MKL on OS X +Intel MKL is a freely-available collection of high-performance libraries that implements BLAS, LAPACK, and ScaLAPACK APIs. MKL is complex: it supports both serial kernels as well as parallel kernels that can take advantage of multiple cores via the use of OpenMP and Intel TBB (the [Intel OneAPI toolkit](https://software.intel.com/oneapi) provides MKL also capable of execution on some Intel GPUs and FPGAs), and the [necessary MKL link options](https://software.intel.com/sites/products/mkl/mkl_link_line_advisor.htm) will depend on the compiler, OS, and other details. - -D LAPACK_LIBRARIES="-L${MKLROOT}/lib -lmkl_intel_lp64 -lmkl_core -lmkl_sequential -lpthread -lm" +Fortunately, Intel MKL can be discovered by BLAS++/LAPACK++ automatically in most instances; if needed, specifying `BLA_VENDOR` with [appropriate argument](https://cmake.org/cmake/help/latest/module/FindBLAS.html#input-variables) can be used to force TiledArray to use MKL. Unfortunately it is not possible to specify the use of TBB-based backend for MKL without the use of a toolchain file. All MKL-enabled toolchains in [The Valeev Group CMake kit](https://github.com/ValeevGroup/kit-cmake/tree/master/toolchains) can be used to configure TiledArray to use sequential, OpenMP, or TBB backend by setting the `MKL_THREADING` CMake cache variable to `SEQ`, `OMP`, or `TBB`, respectively. The toolchains also respect the user-provided choice of `BLA_STATIC`. If multiple MKL versions are present on your system, specify the apropriate variant of the library by loading the corresponding `mklvars.sh` script to set environment variables `MKLROOT` and, if necessary, `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH`. -For additional information on linking different versions of MKL, see the MKL -Link Advisor page. +Also note that even if OpenMP or TBB backends are used, TiledArray will be default set the number of threads to be used by MKL kernels to 1, regardless of the value of environment variables `MKL_NUM_THREADS`/`OMP_NUM_THREADS`. It is possible to change the number of threads to be used programmatically in your application by calling MKL function `mkl_set_num_threads()`. - https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor +On 64-bit platforms it is possible to specify whether to use 32-bit (`LP64`, the default) or 64-bit (`ILP64`) integers in BLAS/LAPACK API. To choose the `ILP64` interface when using the VG MKL toolchains set CMake cache variable `INTEGER4` to `OFF`; the same is achieved when using the default BLAS/LAPACK detection by setting `BLA_VENDOR` to [one of the valid `Intel*64ilp*` choices](https://cmake.org/cmake/help/latest/module/FindBLAS.html#input-variables). N.B. Currently `ILP64` variant of BLACS/ScaLAPACK is not supported, due to [a pending issue](https://github.com/wavefunction91/blacspp/issues/5). ## CUDA @@ -318,7 +307,6 @@ The following CMake options may be used to modify build behavior or find MADNESS * `ENABLE_MPI` -- Enable MPI [Default=ON] * `ENABLE_SCALAPACK` -- Enable use of ScaLAPACK bindings [Default=OFF] * `ENABLE_TBB` -- Enable the use of TBB when building MADNESS [Default=ON] -* `ENABLE_MKL` -- Enable the use of MKL when building MADNESS [Default=ON] * `ENABLE_GPERFTOOLS` -- Enable the use of gperftools when building MADNESS [Default=OFF] * `ENABLE_TCMALLOC_MINIMAL` -- Enable the use of gperftool's tcmalloc_minimal library only (the rest of gperftools is skipped) when building MADNESS [Default=OFF] * `ENABLE_LIBUNWIND` -- Force the discovery of libunwind library when building MADNESS [Default=OFF] @@ -331,7 +319,6 @@ The following CMake options may be used to modify build behavior or find MADNESS The following environment variables can be used to help discovery of MADNESS dependencies: * `TBBROOT` -- the install prefix of TBB -* `MKLROOT` -- the install prefix of MKL * `GPERFTOOLS_DIR` -- the install prefix of gperftools * `LIBUNWIND_DIR` -- the install prefix of libunwind diff --git a/bin/admin/dependency-versions-update-hook.py b/bin/admin/dependency-versions-update-hook.py index 4c3751379f..99b5eceda8 100755 --- a/bin/admin/dependency-versions-update-hook.py +++ b/bin/admin/dependency-versions-update-hook.py @@ -131,10 +131,6 @@ def replace_dep_id(topsrc, file_ext, dep_name, old_id, new_id, search_prefix = ' # Boost version in INSTALL.md any_files_changed |= replace_dep_id(topsrc, 'md', 'Boost', boost_old_version, boost_new_version, 'boost.org/), version ', ' or higher') -# Boost install version in boost.cmake -any_files_changed |= replace_dep_id(topsrc, 'cmake', 'Boost', boost_old_install_version, boost_new_install_version, 'boostorg/release/', '/source/boost') -any_files_changed |= replace_dep_id(topsrc, 'cmake', 'Boost', dots_to_undescores(boost_old_install_version), dots_to_undescores(boost_new_install_version), 'source/boost_', '.tar.gz') -any_files_changed |= replace_dep_id(topsrc, 'cmake', 'Boost', boost_old_install_url_hash, boost_new_install_url_hash, 'SHA256=', '') # Eigen version in INSTALL.md any_files_changed |= replace_dep_id(topsrc, 'md', 'Eigen', eigen_old_version, eigen_new_version, 'eigen.tuxfamily.org), version ', ' or higher') diff --git a/bin/build-linux.sh b/bin/build-linux.sh index 7146fde5ff..bf5d1391b6 100755 --- a/bin/build-linux.sh +++ b/bin/build-linux.sh @@ -134,6 +134,8 @@ fi # Build all libraries, examples, and applications make -j2 all VERBOSE=1 make install +# remove install dir to avoid broken artifacts like BTAS polluting the next build via cached copy +rm -rf $INSTALL_DIR # Validate make -j1 ta_test VERBOSE=1 diff --git a/bin/build-madness-linux.sh b/bin/build-madness-linux.sh index d76ddb5e12..2c1aa45517 100755 --- a/bin/build-madness-linux.sh +++ b/bin/build-madness-linux.sh @@ -62,11 +62,11 @@ if [ "$BUILD_TYPE" = "Debug" ]; then -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ -DCMAKE_CXX_FLAGS="-ftemplate-depth=1024 -Wno-unused-command-line-argument ${EXTRACXXFLAGS}" \ + -DMADNESS_BUILD_MADWORLD_ONLY=ON \ -DENABLE_MPI=ON \ -DMPI_THREAD=multiple \ -DENABLE_TBB=OFF \ -DTBB_ROOT_DIR=/usr \ - -DENABLE_MKL=OFF \ -DFORTRAN_INTEGER_SIZE=4 \ -DENABLE_LIBXC=OFF \ -DENABLE_GPERFTOOLS=OFF \ @@ -74,7 +74,7 @@ if [ "$BUILD_TYPE" = "Debug" ]; then -DDISABLE_WORLD_GET_DEFAULT=ON # Build MADworld + LAPACK/BLAS interface - make -j2 install-madness-world install-madness-clapack install-madness-common install-madness-config VERBOSE=1 + make -j2 install-madness-world install-madness-common install-madness-config VERBOSE=1 fi fi diff --git a/cmake/modules/DetectMADNESSConfig.cmake b/cmake/modules/DetectMADNESSConfig.cmake index 76456d6e39..7930635731 100644 --- a/cmake/modules/DetectMADNESSConfig.cmake +++ b/cmake/modules/DetectMADNESSConfig.cmake @@ -23,24 +23,6 @@ macro (detect_MADNESS_configuration) CACHE STRING "Sanitized list of MADNESS include directories usable in build tree") list(APPEND CMAKE_REQUIRED_INCLUDES ${MADNESS_INTERNAL_INCLUDE_DIRS}) - if (NOT DEFINED MADNESS_HAS_MKL) - CHECK_CXX_SOURCE_COMPILES( - " - #include - #ifndef HAVE_INTEL_MKL - # error \"MADNESS does not have MKL\" - #endif - int main(int argc, char** argv) { - return 0; - } - " MADNESS_HAS_MKL) - endif() - - if (MADNESS_HAS_MKL) - unset(MADNESS_HAS_MKL) - set(MADNESS_HAS_MKL ON CACHE BOOL "MADNESS detected usable Intel MKL" FORCE) - endif() - if (NOT DEFINED MADNESS_HAS_TBB) CHECK_CXX_SOURCE_COMPILES( " @@ -59,24 +41,6 @@ macro (detect_MADNESS_configuration) set(MADNESS_HAS_TBB ON CACHE BOOL "MADNESS detected usable Intel TBB" FORCE) endif() - if (NOT DEFINED MADNESS_FORTRAN_DEFAULT_INTEGER4) - CHECK_CXX_SOURCE_COMPILES( - " - #include - #if MADNESS_FORTRAN_DEFAULT_INTEGER_SIZE != 4 - # error \"MADNESS does not assume integer*4 for Fortran BLAS/LAPACK interfaces\" - #endif - int main(int argc, char** argv) { - return 0; - } - " MADNESS_FORTRAN_DEFAULT_INTEGER4) - endif() - - if (MADNESS_FORTRAN_DEFAULT_INTEGER4) - unset(MADNESS_FORTRAN_DEFAULT_INTEGER4) - set(MADNESS_FORTRAN_DEFAULT_INTEGER4 ON CACHE BOOL "MADNESS assumes integer*4 for Fortran BLAS/LAPACK integers" FORCE) - endif() - unset(CMAKE_REQUIRED_QUIET) cmake_pop_check_state() diff --git a/cmake/modules/FindBLASPPHeaders.cmake b/cmake/modules/FindBLASPPHeaders.cmake new file mode 100644 index 0000000000..3f9c37983e --- /dev/null +++ b/cmake/modules/FindBLASPPHeaders.cmake @@ -0,0 +1,54 @@ +# +# This file is a part of TiledArray. +# Copyright (C) 2019 Virginia Tech +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Edward Valeev +# Department of Chemistry, Virginia Tech +# +# FindBLASPPHeaders.cmake +# Dec 28, 2020 +# + +# check for MKL +include( CheckFunctionExists ) +include(CMakePushCheckState) +cmake_push_check_state( RESET ) +find_package( OpenMP QUIET ) #XXX Open LAPACKPP issue for this... +set( CMAKE_REQUIRED_LIBRARIES "${blaspp_libraries}" m ) +check_function_exists( mkl_dimatcopy BLAS_IS_MKL ) +cmake_pop_check_state() + +add_library(blaspp_headers INTERFACE) + +if (BLAS_IS_MKL) + foreach(_lib ${blaspp_libraries}) + if (EXISTS ${_lib} AND _lib MATCHES libmkl_) + string(REGEX REPLACE "/lib/(|intel64/|intel64_lin/)libmkl_.*" "" _mklroot "${_lib}") + elseif (_lib MATCHES "^-L") + string(REGEX REPLACE "^-L" "" _mklroot "${_lib}") + string(REGEX REPLACE "/lib(|/intel64|/intel64_lin)(|/)" "" _mklroot "${_mklroot}") + endif() + if (_mklroot) + break() + endif(_mklroot) + endforeach() + + target_include_directories(blaspp_headers INTERFACE "${_mklroot}/include") +endif() + +install(TARGETS blaspp_headers EXPORT tiledarray COMPONENT blaspp_headers + LIBRARY DESTINATION "${TILEDARRAY_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${TILEDARRAY_INSTALL_LIBDIR}") diff --git a/cmake/modules/FindOrFetchBTAS.cmake b/cmake/modules/FindOrFetchBTAS.cmake index be876dd690..ee8d2e110a 100644 --- a/cmake/modules/FindOrFetchBTAS.cmake +++ b/cmake/modules/FindOrFetchBTAS.cmake @@ -4,15 +4,9 @@ if (TARGET BTAS::BTAS) message(STATUS "Found BTAS CONFIG at ${BTAS_CONFIG}") else (TARGET BTAS::BTAS) - set(BTAS_ENABLE_MKL ${ENABLE_MKL} CACHE BOOL "Whether BTAS should seek MKL") - if (MADNESS_FORTRAN_DEFAULT_INTEGER4) - set(mkl_pref_ilp64 OFF) - else(MADNESS_FORTRAN_DEFAULT_INTEGER4) - set(mkl_pref_ilp64 ON) - endif(MADNESS_FORTRAN_DEFAULT_INTEGER4) - set(MKL_PREFER_ILP64 ${mkl_pref_ilp64} CACHE BOOL "MKL preference: ILP64 (yes) or {LP64,LP32} (no)") - if (MADNESS_HAS_TBB) - set(MKL_THREADING "TBB" CACHE STRING "MKL flavor: SEQ, TBB or OMP (default)") + if (NOT TILEDARRAY_HAS_CUDA) + # tell BLAS++/LAPACK++ to ignore CUDA + set(use_cuda FALSE CACHE BOOL "Whether to look for CUDA-enabled libs in BLAS++/LAPACK++") endif() FetchContent_Declare( diff --git a/cmake/modules/FindOrFetchBoost.cmake b/cmake/modules/FindOrFetchBoost.cmake new file mode 100644 index 0000000000..6bb749e9f5 --- /dev/null +++ b/cmake/modules/FindOrFetchBoost.cmake @@ -0,0 +1,41 @@ +# Limit scope of the search if BOOST_ROOT or BOOST_INCLUDEDIR is provided. +if (BOOST_ROOT OR BOOST_INCLUDEDIR) + set(Boost_NO_SYSTEM_PATHS TRUE) +endif() + +# Check for Boost +# - require version 1.68 where Boost.Test preconditions work correctly (see https://svn.boost.org/trac10/ticket/12095) +find_package(Boost ${TA_TRACKED_BOOST_VERSION} QUIET CONFIG) + +if (TARGET Boost::boost) + message(STATUS "Found Boost CONFIG at ${Boost_CONFIG}") +else (TARGET Boost::boost) + include (FetchContent) + cmake_minimum_required (VERSION 3.14.0) # for FetchContent_MakeAvailable + + FetchContent_Declare( + CMAKEBOOST + GIT_REPOSITORY https://github.com/Orphis/boost-cmake + ) + FetchContent_MakeAvailable(CMAKEBOOST) + FetchContent_GetProperties(CMAKEBOOST + SOURCE_DIR CMAKEBOOST_SOURCE_DIR + BINARY_DIR CMAKEBOOST_BINARY_DIR + ) + + # current boost-cmake/master does not install boost correctly, so warn that installed TiledArray will not be usable + # boost-cmake/install_rules https://github.com/Orphis/boost-cmake/pull/45 is supposed to fix it but is inactive + message(WARNING "Building Boost from source makes TiledArray unusable from the install location! Install TA using package manager or manually and reconfigure/reinstall TiledArray to fix this") + export(EXPORT tiledarray + FILE "${PROJECT_BINARY_DIR}/boost-targets.cmake") + install(EXPORT tiledarray + FILE "boost-targets.cmake" + DESTINATION "${TILEDARRAY_INSTALL_CMAKEDIR}" + COMPONENT boost-libs) + +endif(TARGET Boost::boost) + +# postcond check +if (NOT TARGET Boost::boost) + message(FATAL_ERROR "FindOrFetchBoost could not make Boost::boost target available") +endif(NOT TARGET Boost::boost) diff --git a/examples/dgemm/ta_blas.cpp b/examples/dgemm/ta_blas.cpp index 29b82542d8..0a4feff383 100644 --- a/examples/dgemm/ta_blas.cpp +++ b/examples/dgemm/ta_blas.cpp @@ -60,7 +60,8 @@ int main(int argc, char** argv) { std::fill_n(c, matrix_size * matrix_size, 0.0); // BLAS dgemm arguments - char opa = 'n', opb = 'n'; + using namespace TiledArray::math::blas; + auto opa = Op::NoTrans, opb = Op::NoTrans; const double alpha = 1l, beta = 0l; const integer m = matrix_size, n = matrix_size, k = matrix_size; const integer lda = matrix_size, ldb = matrix_size, ldc = matrix_size; @@ -72,7 +73,7 @@ int main(int argc, char** argv) { // Note: If TiledArray has not been configured with blas, this will be an // eigen call. for (int i = 0; i < repeat; ++i) { - F77_DGEMM(&opb, &opa, &n, &m, &k, &alpha, b, &ldb, a, &lda, &beta, c, &ldc); + gemm(opa, opb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc); } // Stop clock diff --git a/examples/dgemm/ta_cc_abcd.cpp b/examples/dgemm/ta_cc_abcd.cpp index db088fb521..2d99c6c200 100644 --- a/examples/dgemm/ta_cc_abcd.cpp +++ b/examples/dgemm/ta_cc_abcd.cpp @@ -328,8 +328,8 @@ make_contract(const unsigned int result_rank, const unsigned int left_rank, const TA::Permutation& perm = TA::Permutation()) { return TA::detail::ContractReduce( - madness::cblas::NoTrans, madness::cblas::NoTrans, 1, result_rank, - left_rank, right_rank, perm); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::NoTrans, + 1, result_rank, left_rank, right_rank, perm); } template diff --git a/examples/vector_tests/vector.cpp b/examples/vector_tests/vector.cpp index aa10372819..c4fe86ec5f 100644 --- a/examples/vector_tests/vector.cpp +++ b/examples/vector_tests/vector.cpp @@ -391,7 +391,7 @@ int main(int argc, char** argv) { start = madness::wall_time(); for (std::size_t r = 0ul; r < repeat; ++r) { - TiledArray::blas::scale(n, 3.0, c); + TiledArray::math::blas::scale(n, 3.0, c); } stop = madness::wall_time(); diff --git a/external/boost.cmake b/external/boost.cmake deleted file mode 100644 index 0cf657b234..0000000000 --- a/external/boost.cmake +++ /dev/null @@ -1,82 +0,0 @@ -# -*- mode: cmake -*- - -# Limit scope of the search if BOOST_ROOT or BOOST_INCLUDEDIR is provided. -if (BOOST_ROOT OR BOOST_INCLUDEDIR) - set(Boost_NO_SYSTEM_PATHS TRUE) -endif() - -# Check for Boost -# - require version 1.68 where Boost.Test preconditions work correctly (see https://svn.boost.org/trac10/ticket/12095) -find_package(Boost ${TA_TRACKED_BOOST_VERSION}) - -if (Boost_FOUND) - - # Perform a compile check with Boost - list(APPEND CMAKE_REQUIRED_INCLUDES ${Boost_INCLUDE_DIRS}) - - CHECK_CXX_SOURCE_COMPILES( - " - #define BOOST_TEST_MAIN main_tester - #include - - BOOST_AUTO_TEST_CASE( tester ) - { - BOOST_CHECK( true ); - } - " BOOST_COMPILES) - - if (NOT BOOST_COMPILES) - message(FATAL_ERROR "Boost found at ${BOOST_ROOT}, but could not compile test program") - endif() - -elseif(TA_EXPERT) - - message("** BOOST was not explicitly set") - message(FATAL_ERROR "** Downloading and building Boost is explicitly disabled in EXPERT mode") - -else() - - include(ExternalProject) - - # Set source and build path for Boost in the TiledArray Project - set(BOOST_DOWNLOAD_DIR ${PROJECT_BINARY_DIR}/external/source) - set(BOOST_SOURCE_DIR ${PROJECT_BINARY_DIR}/external/source/boost) - set(BOOST_BUILD_DIR ${PROJECT_BINARY_DIR}/external/build/boost) - # where to get boost - set(BOOST_URL - https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz) - set(BOOST_URL_HASH SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9) - - message("** Will build Boost from ${BOOST_URL}") - - ExternalProject_Add(boost - PREFIX ${CMAKE_INSTALL_PREFIX} - STAMP_DIR ${BOOST_BUILD_DIR}/stamp - TMP_DIR ${BOOST_BUILD_DIR}/tmp - #--Download step-------------- - URL ${BOOST_URL} - URL_HASH ${BOOST_URL_HASH} - DOWNLOAD_DIR ${BOOST_DOWNLOAD_DIR} - #--Configure step------------- - SOURCE_DIR ${BOOST_SOURCE_DIR} - CONFIGURE_COMMAND "" - #--Build step----------------- - BUILD_COMMAND "" - #--Install step--------------- - INSTALL_COMMAND "" - #--Custom targets------------- - STEP_TARGETS download - ) - - add_dependencies(External-tiledarray boost) - install( - DIRECTORY ${BOOST_SOURCE_DIR} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - COMPONENT boost - ) - set(Boost_INCLUDE_DIRS ${BOOST_SOURCE_DIR}) - -endif() - -# Set the build variables -include_directories(${Boost_INCLUDE_DIRS}) diff --git a/external/eigen.cmake b/external/eigen.cmake index 49d4b91b9e..1b034177b7 100644 --- a/external/eigen.cmake +++ b/external/eigen.cmake @@ -145,17 +145,18 @@ endif() # finish configuring TiledArray_Eigen and install if (TARGET TiledArray_Eigen) - # TiledArray_Eigen uses LAPACK/MKL - target_link_libraries(TiledArray_Eigen INTERFACE ${LAPACK_LIBRARIES}) - target_include_directories(TiledArray_Eigen INTERFACE ${LAPACK_INCLUDE_DIRS}) - target_compile_definitions(TiledArray_Eigen INTERFACE ${LAPACK_COMPILE_DEFINITIONS}) - target_compile_options(TiledArray_Eigen INTERFACE ${LAPACK_COMPILE_OPTIONS}) set(TiledArray_Eigen_VERSION "${Eigen3_VERSION}" CACHE STRING "Eigen3_VERSION of the library interfaced by TiledArray_Eigen target") - # Eigen's prototypes for BLAS interface libraries do not match MADNESS cblas - if (MADNESS_HAS_MKL) - # target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_MKL EIGEN_USE_BLAS) - else(MADNESS_HAS_MKL) - # target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_BLAS) - endif(MADNESS_HAS_MKL) + # TiledArray_Eigen uses LAPACK/MKL + # N.B. used to ... seems to be disabled +# target_link_libraries(TiledArray_Eigen INTERFACE ${LAPACK_LIBRARIES}) +# target_include_directories(TiledArray_Eigen INTERFACE ${LAPACK_INCLUDE_DIRS}) +# target_compile_definitions(TiledArray_Eigen INTERFACE ${LAPACK_COMPILE_DEFINITIONS}) +# target_compile_options(TiledArray_Eigen INTERFACE ${LAPACK_COMPILE_OPTIONS}) +# # Eigen's prototypes for BLAS interface libraries do not match MADNESS cblas +# if (MADNESS_HAS_MKL) +# # target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_MKL EIGEN_USE_BLAS) +# else(MADNESS_HAS_MKL) +# # target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_BLAS) +# endif(MADNESS_HAS_MKL) install(TARGETS TiledArray_Eigen EXPORT tiledarray COMPONENT tiledarray) endif(TARGET TiledArray_Eigen) diff --git a/external/madness.cmake b/external/madness.cmake index 3975843784..730bdce125 100644 --- a/external/madness.cmake +++ b/external/madness.cmake @@ -82,22 +82,18 @@ if (MADNESS_FOUND AND NOT TILEDARRAY_DOWNLOADED_MADNESS) endif() # ensure fresh MADNESS - if (DEFINED LAPACK_INCLUDE_DIRS) # introduced in 093f60398d0b552871ca635b06d0144008c3e183 - CHECK_CXX_SOURCE_COMPILES( - " - #include - #include - int main(int argc, char** argv) { - // test 1 - madness::print_meminfo_enable(); - - // test 2 - madness::World::is_default(SafeMPI::COMM_WORLD); - - return 0; - } - " MADNESS_IS_FRESH) - endif(DEFINED LAPACK_INCLUDE_DIRS) + CHECK_CXX_SOURCE_COMPILES( + " + #include + #include + int main(int argc, char** argv) { + // test 1 + madness::print_meminfo_enable(); + // test 2 + madness::World::is_default(SafeMPI::COMM_WORLD); + return 0; + } + " MADNESS_IS_FRESH) if (NOT MADNESS_IS_FRESH) message(FATAL_ERROR "MADNESS is not fresh enough; update to ${MADNESS_OLDEST_TAG} or more recent") @@ -143,46 +139,6 @@ else() # Setup configure variables - # Set Fortran integer size - if(INTEGER4) - set(F77_INT_SIZE 4) - else(INTEGER4) - set (F77_INT_SIZE 8) - endif(INTEGER4) - - # aggregate LAPACK variables - # N.B. Even if these were given in toolchain file (recommended) this will simply duplicate their definitions - # on the command line ... this is fine (cmake is burning all around me) - set (MAD_LAPACK_OPTIONS -DENABLE_MKL=${ENABLE_MKL} -DFORTRAN_INTEGER_SIZE=${F77_INT_SIZE}) - if (DEFINED LAPACK_LIBRARIES) - set(LAPACK_LIBRARIES ${LAPACK_LIBRARIES} CACHE STRING "LAPACK libraries") - # to keep LAPACK_LIBRARIES as a list do a double-escape of the semicolon - # N.B. quotes around MAD_LAPACK_OPTIONS in MADNESS_CMAKE_ARGS - string(REPLACE ";" "\\\;" PROTECTED_LAPACK_LIBRARIES "${LAPACK_LIBRARIES}") - set(MAD_LAPACK_OPTIONS -DLAPACK_LIBRARIES=\"${PROTECTED_LAPACK_LIBRARIES}\" "${MAD_LAPACK_OPTIONS}") - endif (DEFINED LAPACK_LIBRARIES) - if (DEFINED LAPACK_INCLUDE_DIRS) - set(LAPACK_INCLUDE_DIRS ${LAPACK_INCLUDE_DIRS} CACHE STRING "LAPACK include directories") - # to keep LAPACK_INCLUDE_DIRS as a list do a double-escape of the semicolon - # N.B. quotes around MAD_LAPACK_OPTIONS in MADNESS_CMAKE_ARGS - string(REPLACE ";" "\\\;" PROTECTED_LAPACK_INCLUDE_DIRS "${LAPACK_INCLUDE_DIRS}") - set(MAD_LAPACK_OPTIONS -DLAPACK_INCLUDE_DIRS=\"${PROTECTED_LAPACK_INCLUDE_DIRS}\" "${MAD_LAPACK_OPTIONS}") - endif(DEFINED LAPACK_INCLUDE_DIRS) - if (DEFINED LAPACK_COMPILE_OPTIONS) - set(LAPACK_COMPILE_OPTIONS ${LAPACK_COMPILE_OPTIONS} CACHE STRING "LAPACK compiler options") - # to keep LAPACK_COMPILE_OPTIONS as a list do a double-escape of the semicolon - # N.B. quotes around MAD_LAPACK_OPTIONS in MADNESS_CMAKE_ARGS - string(REPLACE ";" "\\\;" PROTECTED_LAPACK_COMPILE_OPTIONS "${LAPACK_COMPILE_OPTIONS}") - set(MAD_LAPACK_OPTIONS -DLAPACK_COMPILE_OPTIONS=\"${PROTECTED_LAPACK_COMPILE_OPTIONS}\" "${MAD_LAPACK_OPTIONS}") - endif(DEFINED LAPACK_COMPILE_OPTIONS) - if (DEFINED LAPACK_COMPILE_DEFINITIONS) - set(LAPACK_COMPILE_DEFINITIONS ${LAPACK_COMPILE_DEFINITIONS} CACHE STRING "LAPACK compile definitions") - # to keep LAPACK_COMPILE_DEFINITIONS as a list do a double-escape of the semicolon - # N.B. quotes around MAD_LAPACK_OPTIONS in MADNESS_CMAKE_ARGS - string(REPLACE ";" "\\\;" PROTECTED_LAPACK_COMPILE_DEFINITIONS "${LAPACK_COMPILE_DEFINITIONS}") - set(MAD_LAPACK_OPTIONS -DLAPACK_COMPILE_DEFINITIONS=\"${PROTECTED_LAPACK_COMPILE_DEFINITIONS}\" "${MAD_LAPACK_OPTIONS}") - endif(DEFINED LAPACK_COMPILE_DEFINITIONS) - # Set error handling method (for TA_DEFAULT_ERROR values see top-level CMakeLists.txt) if(TA_DEFAULT_ERROR EQUAL 0) set(_MAD_ASSERT_TYPE disable) @@ -304,7 +260,9 @@ else() set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${MADNESS_EXTRA_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${MADNESS_EXTRA_CXX_FLAGS}") - set(MADNESS_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + set(MADNESS_CMAKE_ARGS + -DMADNESS_BUILD_MADWORLD_ONLY=ON + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DMADNESS_ASSUMES_ASLR_DISABLED=${TA_ASSUMES_ASLR_DISABLED} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} -DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE} @@ -336,11 +294,8 @@ else() -DMPI_CXX_COMPILER=${MPI_CXX_COMPILER} -DMPI_C_COMPILER=${MPI_C_COMPILER} -DMPI_CXX_SKIP_MPICXX=ON # introduced in cmake 3.10, disables search for C++ MPI-2 bindings - -DENABLE_MKL=${ENABLE_MKL} -DENABLE_TBB=${ENABLE_TBB} "-DTBB_ROOT_DIR=${TBB_ROOT_DIR}" - -DENABLE_LIBXC=FALSE - "${MAD_LAPACK_OPTIONS}" -DENABLE_GPERFTOOLS=${ENABLE_GPERFTOOLS} -DENABLE_TCMALLOC_MINIMAL=${ENABLE_TCMALLOC_MINIMAL} -DENABLE_LIBUNWIND=${ENABLE_LIBUNWIND} @@ -415,12 +370,7 @@ else() endif(BUILD_SHARED_LIBS) set(MADNESS_LIBRARIES ${MADNESS_WORLD_LIBRARY}) -# BUT it also need cblas/clapack headers ... these are not packaged into a library with a target - # these headers depend on LAPACK which is a dependency of MADlinalg, hence - # add MADlinalg's include dirs to MADNESS_INCLUDE_DIRS and MADNESS's LAPACK_LIBRARIES to MADNESS_LINKER_FLAGS (!) - list(APPEND MADNESS_LIBRARIES "${LAPACK_LIBRARIES}") - - # custom target for building MADNESS components .. only MADworld here! Headers from MADlinalg do not need compilation + # custom target for building MADNESS components .. only MADworld here! # N.B. Ninja needs spelling out the byproducts of custom targets, see https://cmake.org/cmake/help/v3.3/policy/CMP0058.html set(MADNESS_BUILD_BYPRODUCTS "${MADNESS_BINARY_DIR}/src/madness/world/lib${MADNESS_WORLD_LIBRARY}${CMAKE_STATIC_LIBRARY_SUFFIX}") message(STATUS "custom target build-madness is expected to build these byproducts: ${MADNESS_BUILD_BYPRODUCTS}") @@ -438,7 +388,7 @@ else() # Since 'install-madness' target cannot be linked to the 'install' target, # we will do it manually here. - set(INSTALL_MADNESS_SUBTARGETS install-madness-world install-madness-clapack install-madness-config install-madness-common) + set(INSTALL_MADNESS_SUBTARGETS install-madness-world install-madness-config install-madness-common) foreach(INSTALL_MADNESS_SUBTARGET IN LISTS INSTALL_MADNESS_SUBTARGETS) install(CODE "execute_process( diff --git a/external/scalapack.cmake b/external/scalapack.cmake index ee8d694b30..e7f619419a 100644 --- a/external/scalapack.cmake +++ b/external/scalapack.cmake @@ -59,29 +59,6 @@ endif() add_library( TiledArray_SCALAPACK INTERFACE ) target_link_libraries( TiledArray_SCALAPACK INTERFACE scalapackpp::scalapackpp blacspp::blacspp) -#target_compile_definitions( TiledArray_SCALAPACK INTERFACE "TA_ENABLE_SCALAPACK" ) - -#get_property( _SCALAPACK_INCLUDE_DIRS -# TARGET scalapackpp::scalapackpp -# PROPERTY INTERFACE_INCLUDE_DIRECTORIES -# ) -# -#get_property( _SCALAPACK_LIBRARIES -# TARGET scalapackpp::scalapackpp -# PROPERTY INTERFACE_LINK_LIBRARIES -# ) -# -#get_property( _SCALAPACK_COMPILE_FEATURES -# TARGET scalapackpp::scalapackpp -# PROPERTY INTERFACE_COMPILE_FEATURES -# ) -# -#set_target_properties( TiledArray_SCALAPACK PROPERTIES -# INTERFACE_INCLUDE_DIRECTORIES "${_SCALAPACK_INCLUDE_DIRS}" -# INTERFACE_LINK_LIBRARIES "${_SCALAPACK_LIBRARIES}" -# INTERFACE_COMPILE_FEATURES "${_SCALAPACK_COMPILE_FEATURES}" -# INTERFACE_COMPILE_DEFINITIONS "TA_ENABLE_SCALAPACK" -# ) install( TARGETS TiledArray_SCALAPACK EXPORT tiledarray COMPONENT tiledarray ) diff --git a/external/versions.cmake b/external/versions.cmake index 48200a1654..da41ac1fb5 100644 --- a/external/versions.cmake +++ b/external/versions.cmake @@ -17,12 +17,12 @@ set(TA_INSTALL_EIGEN_PREVIOUS_VERSION 3.3.7) set(TA_INSTALL_EIGEN_URL_HASH b9e98a200d2455f06db9c661c5610496) set(TA_INSTALL_EIGEN_PREVIOUS_URL_HASH b9e98a200d2455f06db9c661c5610496) -set(TA_TRACKED_MADNESS_TAG 925552feaf326cca8e83de7bd042074ad3cfd3f1) -set(TA_TRACKED_MADNESS_PREVIOUS_TAG 2353a30fb3257e2e7f5133975d909d8346dc7192) +set(TA_TRACKED_MADNESS_TAG b22ee85059e6ccc9a6e803ba0550652ece8d9df1) +set(TA_TRACKED_MADNESS_PREVIOUS_TAG 925552feaf326cca8e83de7bd042074ad3cfd3f1) set(TA_TRACKED_MADNESS_VERSION 0.10.1) set(TA_TRACKED_MADNESS_PREVIOUS_VERSION 0.10.1) -set(TA_TRACKED_BTAS_TAG 52cd6dba22aea0da3ccaf2e3c2ee00f821621d3f) +set(TA_TRACKED_BTAS_TAG bd42eb3a2b84a46953edc7a8f7afbe5c98efa2c5) set(TA_TRACKED_BTAS_PREVIOUS_TAG 8418021a283000ada8edd4994bd81f35652d4b49) set(TA_TRACKED_CUTT_TAG 0e8685bf82910bc7435835f846e88f1b39f47f09) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 6870f8723d..f079c1d0ab 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -56,11 +56,21 @@ enable_testing() # build step add_test(build_python "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target python-tiledarray) +# check for presence of prerequisite modules +foreach(_mod pytest numpy) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import ${_mod}" + OUTPUT_QUIET ERROR_QUIET + RESULTS_VARIABLE check_for_${_mod}) + if (check_for_${_mod}) + message(FATAL_ERROR "Python module \"${_mod}\" is not installed; install via \"${PYTHON_EXECUTABLE} -m pip install ${_mod}\" and rerun cmake") + endif(check_for_${_mod}) +endforeach(_mod) + # test step add_test( NAME test_python # need to use pytest to find tiledarray module properly - COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PROJECT_SOURCE_DIR}/test_tiledarray.py + COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PROJECT_SOURCE_DIR}/test_tiledarray.py -v WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 92ce5f841b..7d5d6a3ae0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -213,7 +213,7 @@ TiledArray/math/linalg/rank-local.cpp ) # the list of libraries on which TiledArray depends on, will be cached later -set(_TILEDARRAY_DEPENDENCIES MADworld TiledArray_Eigen BTAS::BTAS) +set(_TILEDARRAY_DEPENDENCIES MADworld TiledArray_Eigen BTAS::BTAS blaspp_headers) # TODO better ways to handle tiledarray cuda dependency if(CUDA_FOUND) @@ -255,6 +255,7 @@ add_library(tiledarray ${TILEDARRAY_SOURCE_FILES} ${TILEDARRAY_HEADER_FILES}) target_link_libraries(${targetname} PUBLIC ${TILEDARRAY_PRIVATE_LINK_LIBRARIES}) target_link_libraries(${targetname} PUBLIC MADworld) + target_link_libraries(${targetname} PUBLIC Boost::boost) if (TARGET build-madness) add_dependencies(${targetname} build-madness) @@ -275,7 +276,6 @@ add_library(tiledarray ${TILEDARRAY_SOURCE_FILES} ${TILEDARRAY_HEADER_FILES}) string(REPLACE " " ";" CMAKE_CXX_FLAG_LIST "${CMAKE_CXX_FLAGS}") target_compile_options(${targetname} PUBLIC ${CMAKE_CXX_FLAG_LIST}) target_compile_features(${targetname} PUBLIC "cxx_std_${CMAKE_CXX_STANDARD}") - target_include_directories(${targetname} PUBLIC ${Boost_INCLUDE_DIRS}) if (CUDA_FOUND) target_include_directories(${targetname} PUBLIC ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) diff --git a/src/TiledArray/config.h.in b/src/TiledArray/config.h.in index f1e8f4fdf2..f26da58c13 100644 --- a/src/TiledArray/config.h.in +++ b/src/TiledArray/config.h.in @@ -86,23 +86,8 @@ #endif // __has_include() #endif // __has_include #endif // !defined(TILEDARRAY_HAS_BTAS) - -/* if have BTAS and MADNESS detected MKL, configure BTAS+LAPACK for BTAS via #define's */ -#if defined(TILEDARRAY_HAS_BTAS) && defined(HAVE_INTEL_MKL) -// _HAS_INTEL_MKL is obsolete in BTAS 1.0.0 -#ifndef _HAS_INTEL_MKL -# define _HAS_INTEL_MKL -#endif -#ifndef BTAS_HAS_CBLAS -# define BTAS_HAS_CBLAS -#endif -// these are introduced in BTAS 1.0.0 -#ifndef BTAS_HAS_LAPACKE -# define BTAS_HAS_LAPACKE -#endif -#ifndef BTAS_HAS_INTEL_MKL -# define BTAS_HAS_INTEL_MKL -#endif +#if defined(TILEDARRAY_HAS_BTAS) && defined(BTAS_HAS_INTEL_MKL) +# define TILEDARRAY_HAS_INTEL_MKL #endif /* Add macro TILEDARRAY_FORCE_INLINE which does as the name implies. */ diff --git a/src/TiledArray/cuda/btas_cublas.h b/src/TiledArray/cuda/btas_cublas.h index 69227c8b88..ea073d0a78 100644 --- a/src/TiledArray/cuda/btas_cublas.h +++ b/src/TiledArray/cuda/btas_cublas.h @@ -24,8 +24,8 @@ #ifndef TILEDARRAY_BTAS_CUDA_CUBLAS_H__INCLUDED #define TILEDARRAY_BTAS_CUDA_CUBLAS_H__INCLUDED -#include #include +#include #ifdef TILEDARRAY_HAS_CUDA @@ -40,7 +40,8 @@ namespace TiledArray { -template +template >> btas::Tensor btas_tensor_gemm_cuda_impl( const btas::Tensor &left, const btas::Tensor &right, Scalar factor, @@ -64,14 +65,15 @@ btas::Tensor btas_tensor_gemm_cuda_impl( std::cbegin(left.range().extent()), std::cbegin(right.range().extent()))); // Compute gemm dimensions + using TiledArray::math::blas::integer; integer m = 1, n = 1, k = 1; gemm_helper.compute_matrix_sizes(m, n, k, left.range(), right.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == madness::cblas::NoTrans ? k : m); + (gemm_helper.left_op() == TiledArray::math::blas::Op::NoTrans ? k : m); const integer ldb = - (gemm_helper.right_op() == madness::cblas::NoTrans ? n : k); + (gemm_helper.right_op() == TiledArray::math::blas::Op::NoTrans ? n : k); T factor_t = T(factor); T zero(0); @@ -147,7 +149,7 @@ btas::Tensor btas_tensor_gemm_cuda_impl( TiledArray::to_execution_space( right.storage(), cuda_stream); - TiledArray::math::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, + TiledArray::math::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, factor_t, left.data(), lda, right.data(), ldb, zero, result.data(), n); } @@ -155,7 +157,7 @@ btas::Tensor btas_tensor_gemm_cuda_impl( return result; } -template +template >> void btas_tensor_gemm_cuda_impl( btas::Tensor &result, const btas::Tensor &left, @@ -212,14 +214,15 @@ void btas_tensor_gemm_cuda_impl( std::cbegin(left.range().extent()), std::cbegin(right.range().extent()))); // Compute gemm dimensions + using TiledArray::math::blas::integer; integer m, n, k; gemm_helper.compute_matrix_sizes(m, n, k, left.range(), right.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == madness::cblas::NoTrans ? k : m); + (gemm_helper.left_op() == TiledArray::math::blas::Op::NoTrans ? k : m); const integer ldb = - (gemm_helper.right_op() == madness::cblas::NoTrans ? n : k); + (gemm_helper.right_op() == TiledArray::math::blas::Op::NoTrans ? n : k); CudaSafeCall(cudaSetDevice(cudaEnv::instance()->current_cuda_device_id())); auto &cuda_stream = detail::get_stream_based_on_range(result.range()); @@ -276,7 +279,7 @@ void btas_tensor_gemm_cuda_impl( TiledArray::to_execution_space( result.storage(), cuda_stream); - TiledArray::math::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, + TiledArray::math::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, factor_t, left.data(), lda, right.data(), ldb, one, result.data(), n); } @@ -308,7 +311,8 @@ btas::Tensor btas_tensor_clone_cuda_impl( } /// result[i] = a * arg[i] -template +template >> btas::Tensor btas_tensor_scale_cuda_impl( const btas::Tensor &arg, const Scalar a) { CudaSafeCall(cudaSetDevice(cudaEnv::instance()->current_cuda_device_id())); @@ -330,7 +334,8 @@ btas::Tensor btas_tensor_scale_cuda_impl( } /// result[i] *= a -template +template >> void btas_tensor_scale_to_cuda_impl(btas::Tensor &result, const Scalar a) { CudaSafeCall(cudaSetDevice(cudaEnv::instance()->current_cuda_device_id())); @@ -345,7 +350,8 @@ void btas_tensor_scale_to_cuda_impl(btas::Tensor &result, } /// result[i] = arg1[i] - a * arg2[i] -template +template >> btas::Tensor btas_tensor_subt_cuda_impl( const btas::Tensor &arg1, const btas::Tensor &arg2, const Scalar a) { @@ -373,7 +379,7 @@ btas::Tensor btas_tensor_subt_cuda_impl( } /// result[i] -= a * arg1[i] -template +template >> void btas_tensor_subt_to_cuda_impl(btas::Tensor &result, const btas::Tensor &arg1, const Scalar a) { @@ -392,7 +398,7 @@ void btas_tensor_subt_to_cuda_impl(btas::Tensor &result, } /// result[i] = arg1[i] + a * arg2[i] -template +template >> btas::Tensor btas_tensor_add_cuda_impl( const btas::Tensor &arg1, const btas::Tensor &arg2, const Scalar a) { @@ -412,7 +418,7 @@ btas::Tensor btas_tensor_add_cuda_impl( } /// result[i] += a * arg[i] -template +template >> void btas_tensor_add_to_cuda_impl(btas::Tensor &result, const btas::Tensor &arg, const Scalar a) { @@ -480,6 +486,7 @@ btas_tensor_squared_norm_cuda_impl(const btas::Tensor &arg) { auto &cuda_stream = detail::get_stream_based_on_range(arg.range()); auto &storage = arg.storage(); + using TiledArray::math::blas::integer; integer size = storage.size(); T result = 0; if (in_memory_space(storage)) { @@ -504,6 +511,7 @@ typename btas::Tensor::value_type btas_tensor_dot_cuda_impl( auto &cuda_stream = detail::get_stream_based_on_range(arg1.range()); + using TiledArray::math::blas::integer; integer size = arg1.storage().size(); TA_ASSERT(size == arg2.storage().size()); diff --git a/src/TiledArray/cuda/btas_um_tensor.h b/src/TiledArray/cuda/btas_um_tensor.h index b20246212f..cbc40eef7c 100644 --- a/src/TiledArray/cuda/btas_um_tensor.h +++ b/src/TiledArray/cuda/btas_um_tensor.h @@ -107,7 +107,7 @@ namespace TiledArray { /// gemm /// -template +template >> btasUMTensorVarray gemm( const btasUMTensorVarray &left, const btasUMTensorVarray &right, Scalar factor, @@ -115,7 +115,7 @@ btasUMTensorVarray gemm( return btas_tensor_gemm_cuda_impl(left, right, factor, gemm_helper); } -template +template >> void gemm(btasUMTensorVarray &result, const btasUMTensorVarray &left, const btasUMTensorVarray &right, Scalar factor, @@ -204,30 +204,30 @@ btasUMTensorVarray permute(const btasUMTensorVarray &arg, synchronize_stream(&stream); - return std::move(result); + return result; } /// /// scale /// -template +template >> btasUMTensorVarray scale(const btasUMTensorVarray &arg, const Scalar factor) { detail::to_cuda(arg); return btas_tensor_scale_cuda_impl(arg, factor); } -template +template >> void scale_to(btasUMTensorVarray &arg, const Scalar factor) { detail::to_cuda(arg); btas_tensor_scale_to_cuda_impl(arg, factor); } -template +template && TiledArray::detail::is_permutation_v>> btasUMTensorVarray scale(const btasUMTensorVarray &arg, const Scalar factor, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = scale(arg, factor); // wait to finish before switch stream @@ -247,9 +247,9 @@ btasUMTensorVarray neg(const btasUMTensorVarray &arg) { return btas_tensor_scale_cuda_impl(arg, T(-1.0)); } -template +template >> btasUMTensorVarray neg(const btasUMTensorVarray &arg, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = neg(arg); // wait to finish before switch stream @@ -277,19 +277,19 @@ btasUMTensorVarray subt(const btasUMTensorVarray &arg1, return btas_tensor_subt_cuda_impl(arg1, arg2, T(1.0)); } -template +template >> btasUMTensorVarray subt(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, const Scalar factor) { auto result = subt(arg1, arg2); btas_tensor_scale_to_cuda_impl(result, factor); - return std::move(result); + return result; } -template +template >> btasUMTensorVarray subt(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = subt(arg1, arg2); // wait to finish before switch stream @@ -299,11 +299,11 @@ btasUMTensorVarray subt(const btasUMTensorVarray &arg1, return permute(result, perm); } -template +template && TiledArray::detail::is_permutation_v>> btasUMTensorVarray subt(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, const Scalar factor, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = subt(arg1, arg2, factor); // wait to finish before switch stream @@ -325,7 +325,7 @@ void subt_to(btasUMTensorVarray &result, btas_tensor_subt_to_cuda_impl(result, arg1, T(1.0)); } -template +template >> void subt_to(btasUMTensorVarray &result, const btasUMTensorVarray &arg1, const Scalar factor) { subt_to(result, arg1); @@ -344,20 +344,20 @@ btasUMTensorVarray add(const btasUMTensorVarray &arg1, return btas_tensor_add_cuda_impl(arg1, arg2, T(1.0)); } -template +template >> btasUMTensorVarray add(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, const Scalar factor) { auto result = add(arg1, arg2); btas_tensor_scale_to_cuda_impl(result, factor); - return std::move(result); + return result; } -template +template && TiledArray::detail::is_permutation_v>> btasUMTensorVarray add(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, const Scalar factor, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = add(arg1, arg2, factor); // wait to finish before switch stream @@ -367,10 +367,10 @@ btasUMTensorVarray add(const btasUMTensorVarray &arg1, return permute(result, perm); } -template +template >> btasUMTensorVarray add(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = add(arg1, arg2); // wait to finish before switch stream @@ -392,7 +392,7 @@ void add_to(btasUMTensorVarray &result, btas_tensor_add_to_cuda_impl(result, arg, T(1.0)); } -template +template >> void add_to(btasUMTensorVarray &result, const btasUMTensorVarray &arg, const Scalar factor) { add_to(result, arg); @@ -422,19 +422,19 @@ btasUMTensorVarray mult(const btasUMTensorVarray &arg1, return btas_tensor_mult_cuda_impl(arg1, arg2); } -template +template >> btasUMTensorVarray mult(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, const Scalar factor) { auto result = mult(arg1, arg2); btas_tensor_scale_to_cuda_impl(result, factor); - return std::move(result); + return result; } -template +template >> btasUMTensorVarray mult(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = mult(arg1, arg2); // wait to finish before switch stream @@ -444,11 +444,11 @@ btasUMTensorVarray mult(const btasUMTensorVarray &arg1, return permute(result, perm); } -template +template && TiledArray::detail::is_permutation_v>> btasUMTensorVarray mult(const btasUMTensorVarray &arg1, const btasUMTensorVarray &arg2, const Scalar factor, - const TiledArray::Permutation &perm) { + const Perm &perm) { auto result = mult(arg1, arg2, factor); // wait to finish before switch stream @@ -469,7 +469,7 @@ void mult_to(btasUMTensorVarray &result, btas_tensor_mult_to_cuda_impl(result, arg); } -template +template >> void mult_to(btasUMTensorVarray &result, const btasUMTensorVarray &arg, const Scalar factor) { mult_to(result, arg); @@ -641,7 +641,7 @@ um_tensor_to_ta_tensor( cudaMemcpyDefault, stream)); synchronize_stream(&stream); - return std::move(result); + return result; }; const auto convert_tile_um = [](const UMTensor &tile) { @@ -657,7 +657,7 @@ um_tensor_to_ta_tensor( std::copy_n(tile.data(), n, result.data()); - return std::move(result); + return result; }; const char *use_legacy_conversion = diff --git a/src/TiledArray/cuda/cublas.h b/src/TiledArray/cuda/cublas.h index 6b89aba889..a5d3da7afc 100644 --- a/src/TiledArray/cuda/cublas.h +++ b/src/TiledArray/cuda/cublas.h @@ -34,6 +34,8 @@ #include #include +#include + #define CublasSafeCall(err) __cublasSafeCall(err, __FILE__, __LINE__) inline void __cublasSafeCall(cublasStatus_t err, const char *file, @@ -76,17 +78,16 @@ class cuBLASHandlePool { }; // thread_local cublasHandle_t *cuBLASHandlePool::handle_; -inline cublasOperation_t to_cublas_op( - madness::cblas::CBLAS_TRANSPOSE cblas_op) { +inline cublasOperation_t to_cublas_op(math::blas::Op cblas_op) { cublasOperation_t result{}; switch (cblas_op) { - case madness::cblas::NoTrans: + case math::blas::Op::NoTrans: result = CUBLAS_OP_N; break; - case madness::cblas::Trans: + case math::blas::Op::Trans: result = CUBLAS_OP_T; break; - case madness::cblas::ConjTrans: + case math::blas::Op::ConjTrans: result = CUBLAS_OP_C; break; } diff --git a/src/TiledArray/dist_eval/binary_eval.h b/src/TiledArray/dist_eval/binary_eval.h index cefc5e529c..20e97c55b9 100644 --- a/src/TiledArray/dist_eval/binary_eval.h +++ b/src/TiledArray/dist_eval/binary_eval.h @@ -23,6 +23,8 @@ #include #include +#include + namespace TiledArray { namespace detail { @@ -126,7 +128,7 @@ class BinaryEvalImpl : public DistEvalImpl, /// \param left The left-hand tile /// \param right The right-hand tile template - std::enable_if_t::value, void> eval_tile( + std::enable_if_t, void> eval_tile( const ordinal_type i, L left, R right) { DistEvalImpl_::set_tile(i, op_(left, right)); } @@ -135,7 +137,7 @@ class BinaryEvalImpl : public DistEvalImpl, /// \param left The left-hand tile /// \param right The right-hand tile template - std::enable_if_t::value, void> eval_tile( + std::enable_if_t, void> eval_tile( const ordinal_type i, L left, R right) { // TODO avoid copy the Op object auto result_tile = diff --git a/src/TiledArray/dist_eval/contraction_eval.h b/src/TiledArray/dist_eval/contraction_eval.h index a8b44ec5ab..37e9e50516 100644 --- a/src/TiledArray/dist_eval/contraction_eval.h +++ b/src/TiledArray/dist_eval/contraction_eval.h @@ -29,6 +29,8 @@ #include #include +#include + //#define TILEDARRAY_ENABLE_SUMMA_TRACE_EVAL 1 //#define TILEDARRAY_ENABLE_SUMMA_TRACE_INITIALIZE 1 //#define TILEDARRAY_ENABLE_SUMMA_TRACE_STEP 1 @@ -477,7 +479,7 @@ class Summa static typename std::enable_if< is_lazy_tile::value #ifdef TILEDARRAY_HAS_CUDA - && !detail::is_cuda_tile::value + && !detail::is_cuda_tile_v #endif , Future>::type @@ -500,7 +502,7 @@ class Summa template static typename std::enable_if< is_lazy_tile::value && - detail::is_cuda_tile::value, + detail::is_cuda_tile_v, Future>::type get_tile(Arg& arg, const typename Arg::ordinal_type index) { auto convert_tile_fn = diff --git a/src/TiledArray/dist_eval/unary_eval.h b/src/TiledArray/dist_eval/unary_eval.h index 883c399fb7..bb565a33db 100644 --- a/src/TiledArray/dist_eval/unary_eval.h +++ b/src/TiledArray/dist_eval/unary_eval.h @@ -22,6 +22,8 @@ #include +#include + namespace TiledArray { namespace detail { @@ -113,7 +115,7 @@ class UnaryEvalImpl /// \param i The tile index /// \param tile The tile to be evaluated template - std::enable_if_t::value, void> eval_tile( + std::enable_if_t, void> eval_tile( const ordinal_type i, tile_argument_type tile) { // TODO avoid copy Op object auto result_tile = @@ -124,7 +126,7 @@ class UnaryEvalImpl /// \param i The tile index /// \param tile The tile to be evaluated template - std::enable_if_t::value, void> eval_tile( + std::enable_if_t, void> eval_tile( const ordinal_type i, tile_argument_type tile) { DistEvalImpl_::set_tile(i, op_(tile)); } diff --git a/src/TiledArray/expressions/cont_engine.h b/src/TiledArray/expressions/cont_engine.h index fedce43711..f71e44d869 100644 --- a/src/TiledArray/expressions/cont_engine.h +++ b/src/TiledArray/expressions/cont_engine.h @@ -250,14 +250,14 @@ class ContEngine : public BinaryEngine { // Initialize the tile operation in this function because it is used to // evaluate the tiled range and shape. - const blas::TransposeFlag left_op = + const math::blas::Op left_op = (left_outer_permtype_ == PermutationType::matrix_transpose - ? blas::Transpose - : blas::NoTranspose); - const blas::TransposeFlag right_op = + ? math::blas::Transpose + : math::blas::NoTranspose); + const math::blas::Op right_op = (right_outer_permtype_ == PermutationType::matrix_transpose - ? blas::Transpose - : blas::NoTranspose); + ? math::blas::Transpose + : math::blas::NoTranspose); if (outer(target_indices) != outer(indices_)) { // Initialize permuted structure @@ -397,7 +397,7 @@ class ContEngine : public BinaryEngine { /// \return The result shape shape_type make_shape() const { const TiledArray::math::GemmHelper shape_gemm_helper( - blas::NoTranspose, blas::NoTranspose, + math::blas::NoTranspose, math::blas::NoTranspose, op_.gemm_helper().result_rank(), op_.gemm_helper().left_rank(), op_.gemm_helper().right_rank()); return left_.shape().gemm(right_.shape(), factor_, shape_gemm_helper); @@ -409,7 +409,7 @@ class ContEngine : public BinaryEngine { /// \return The result shape shape_type make_shape(const Permutation& perm) const { const TiledArray::math::GemmHelper shape_gemm_helper( - blas::NoTranspose, blas::NoTranspose, + math::blas::NoTranspose, math::blas::NoTranspose, op_.gemm_helper().result_rank(), op_.gemm_helper().left_rank(), op_.gemm_helper().right_rank()); return left_.shape().gemm(right_.shape(), factor_, shape_gemm_helper, perm); diff --git a/src/TiledArray/expressions/expr.h b/src/TiledArray/expressions/expr.h index ef291392da..fbe6e314b5 100644 --- a/src/TiledArray/expressions/expr.h +++ b/src/TiledArray/expressions/expr.h @@ -43,6 +43,8 @@ #include #endif +#include + namespace TiledArray { namespace expressions { @@ -192,7 +194,7 @@ class Expr { typename std::enable_if::value && is_lazy_tile::value #ifdef TILEDARRAY_HAS_CUDA - && !::TiledArray::detail::is_cuda_tile::value + && !::TiledArray::detail::is_cuda_tile_v #endif >::type* = nullptr> void set_tile(A& array, const I& index, const Future& tile) const { @@ -215,7 +217,7 @@ class Expr { typename std::enable_if< !std::is_same::value && is_lazy_tile::value && - ::TiledArray::detail::is_cuda_tile::value>::type* = nullptr> + ::TiledArray::detail::is_cuda_tile_v>::type* = nullptr> void set_tile(A& array, const I& index, const Future& tile) const { array.set(index, madness::add_cuda_task( array.world(), @@ -252,7 +254,7 @@ class Expr { typename A, typename I, typename T, typename Op, typename std::enable_if::value #ifdef TILEDARRAY_HAS_CUDA - && !::TiledArray::detail::is_cuda_tile::value + && !::TiledArray::detail::is_cuda_tile_v #endif >::type* = nullptr> void set_tile(A& array, const I index, const Future& tile, @@ -280,7 +282,7 @@ class Expr { template ::value && - ::TiledArray::detail::is_cuda_tile::value>::type* = nullptr> + ::TiledArray::detail::is_cuda_tile_v>::type* = nullptr> void set_tile(A& array, const I index, const Future& tile, const std::shared_ptr& op) const { auto eval_tile_fn = @@ -309,7 +311,7 @@ class Expr { typename A, typename I, typename T, typename Op, typename std::enable_if::value #ifdef TILEDARRAY_HAS_CUDA - && !::TiledArray::detail::is_cuda_tile::value + && !::TiledArray::detail::is_cuda_tile_v #endif >::type* = nullptr> void set_tile(A& array, const I index, const Future& tile, @@ -337,7 +339,7 @@ class Expr { template ::value&& ::TiledArray:: - detail::is_cuda_tile::value>::type* = nullptr> + detail::is_cuda_tile_v>::type* = nullptr> void set_tile(A& array, const I index, const Future& tile, const std::shared_ptr& op) const { auto eval_tile_fn_ptr = &Expr_::template eval_tile; diff --git a/src/TiledArray/expressions/mult_engine.h b/src/TiledArray/expressions/mult_engine.h index 4db1beebb9..8d4e33de6f 100644 --- a/src/TiledArray/expressions/mult_engine.h +++ b/src/TiledArray/expressions/mult_engine.h @@ -409,6 +409,7 @@ class MultEngine : public ContEngine> { } else { // plain tensors return op_type(op_base_type()); } + abort(); // unreachable } /// Permuting tile operation factory function @@ -433,6 +434,7 @@ class MultEngine : public ContEngine> { } else { // plain tensor return op_type(op_base_type(), perm); } + abort(); // unreachable } /// Construct the distributed evaluator for this expression diff --git a/src/TiledArray/expressions/permopt.h b/src/TiledArray/expressions/permopt.h index ef5a58e17d..21d4a0ec39 100644 --- a/src/TiledArray/expressions/permopt.h +++ b/src/TiledArray/expressions/permopt.h @@ -43,12 +43,12 @@ namespace expressions { // clang-format on enum class PermutationType { identity = 1, matrix_transpose = 2, general = 3 }; -inline blas::TransposeFlag to_cblas_op(PermutationType permtype) { +inline blas::Op to_cblas_op(PermutationType permtype) { TA_ASSERT(permtype == PermutationType::matrix_transpose || permtype == PermutationType::identity); return permtype == PermutationType::matrix_transpose - ? blas::Transpose - : blas::NoTranspose; + ? math::blas::Transpose + : math::blas::NoTranspose; } /// Abstract optimizer of permutations for a binary operation diff --git a/src/TiledArray/external/btas.h b/src/TiledArray/external/btas.h index ae706a7ba5..8f1b99c9e9 100644 --- a/src/TiledArray/external/btas.h +++ b/src/TiledArray/external/btas.h @@ -44,7 +44,7 @@ namespace btas { template <> struct range_traits { - const static CBLAS_ORDER order = CblasRowMajor; + const static blas::Layout order = blas::Layout::RowMajor; using index_type = TiledArray::Range::index_type; using ordinal_type = TiledArray::Range::ordinal_type; constexpr static const bool is_general_layout = false; @@ -63,10 +63,10 @@ inline const TiledArray::Range& make_ta_range(const TiledArray::Range& range) { /// \param[in] range a btas::RangeNd object /// \throw TiledArray::Exception if \c range is non-row-major -template +template <::blas::Layout Order, typename... Args> inline TiledArray::Range make_ta_range( const btas::RangeNd& range) { - TA_ASSERT(Order == CblasRowMajor && + TA_ASSERT(Order == ::blas::Layout::RowMajor && "TiledArray::detail::make_ta_range(btas::RangeNd): " "not supported for col-major Order"); return TiledArray::Range(range.lobound(), range.upbound()); @@ -94,7 +94,7 @@ namespace btas { /// \c r1 are equal to those of \c r2. /// \param r1 The first Range to compare /// \param r2 The second Range to compare -template +template inline bool is_congruent(const btas::RangeNd& r1, const btas::RangeNd& r2) { return (r1.rank() == r2.rank()) && @@ -621,20 +621,21 @@ inline btas::Tensor gemm( std::cbegin(left.range().extent()), std::cbegin(right.range().extent()))); // Compute gemm dimensions + using integer = TiledArray::math::blas::integer; integer m = 1, n = 1, k = 1; gemm_helper.compute_matrix_sizes(m, n, k, left.range(), right.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == madness::cblas::NoTrans ? k : m); + (gemm_helper.left_op() == TiledArray::math::blas::Op::NoTrans ? k : m); const integer ldb = - (gemm_helper.right_op() == madness::cblas::NoTrans ? n : k); + (gemm_helper.right_op() == TiledArray::math::blas::Op::NoTrans ? n : k); T factor_t(factor); - TiledArray::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, - factor_t, left.data(), lda, right.data(), ldb, T(0), - result.data(), n); + TiledArray::math::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, + n, k, factor_t, left.data(), lda, right.data(), + ldb, T(0), result.data(), n); return result; } @@ -695,20 +696,21 @@ inline void gemm(btas::Tensor& result, std::cbegin(left.range().extent()), std::cbegin(right.range().extent()))); // Compute gemm dimensions + using integer = TiledArray::math::blas::integer; integer m, n, k; gemm_helper.compute_matrix_sizes(m, n, k, left.range(), right.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == madness::cblas::NoTrans ? k : m); + (gemm_helper.left_op() == TiledArray::math::blas::Op::NoTrans ? k : m); const integer ldb = - (gemm_helper.right_op() == madness::cblas::NoTrans ? n : k); + (gemm_helper.right_op() == TiledArray::math::blas::Op::NoTrans ? n : k); T factor_t(factor); - TiledArray::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, - factor_t, left.data(), lda, right.data(), ldb, T(1), - result.data(), n); + TiledArray::math::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, + n, k, factor_t, left.data(), lda, right.data(), + ldb, T(1), result.data(), n); } // sum of the hyperdiagonal elements @@ -825,10 +827,11 @@ template constexpr const bool is_btas_tensor_v = is_btas_tensor::value; /// btas::RangeNd can be col or row-major -template +template <::blas::Layout _Order, typename _Index, typename _Ordinal> struct ordinal_traits> { - static constexpr const auto type = - _Order == CblasRowMajor ? OrdinalType::RowMajor : OrdinalType::ColMajor; + static constexpr const auto type = _Order == ::blas::Layout::RowMajor + ? OrdinalType::RowMajor + : OrdinalType::ColMajor; }; } // namespace detail @@ -869,7 +872,7 @@ struct ArchiveStoreImpl> { } }; -template +template struct ArchiveLoadImpl> { static inline void load(const Archive& ar, btas::BoxOrdinal<_Order, _Index>& o) { @@ -882,7 +885,7 @@ struct ArchiveLoadImpl> { } }; -template +template struct ArchiveStoreImpl> { static inline void store(const Archive& ar, const btas::BoxOrdinal<_Order, _Index>& o) { @@ -890,7 +893,8 @@ struct ArchiveStoreImpl> { } }; -template +template struct ArchiveLoadImpl> { static inline void load(const Archive& ar, btas::RangeNd<_Order, _Index, _Ordinal>& r) { @@ -904,7 +908,8 @@ struct ArchiveLoadImpl> { } }; -template +template struct ArchiveStoreImpl> { static inline void store(const Archive& ar, const btas::RangeNd<_Order, _Index, _Ordinal>& r) { diff --git a/src/TiledArray/external/cuda.h b/src/TiledArray/external/cuda.h index cb224df1d1..bf9e3171a1 100644 --- a/src/TiledArray/external/cuda.h +++ b/src/TiledArray/external/cuda.h @@ -45,7 +45,6 @@ #include #include -#include #include #include #include diff --git a/src/TiledArray/external/madness.h b/src/TiledArray/external/madness.h index 0bd27c05f0..44db69e3bd 100644 --- a/src/TiledArray/external/madness.h +++ b/src/TiledArray/external/madness.h @@ -32,7 +32,6 @@ TILEDARRAY_PRAGMA_GCC(diagnostic push) TILEDARRAY_PRAGMA_GCC(system_header) -#include #include #include diff --git a/src/TiledArray/math/blas.h b/src/TiledArray/math/blas.h index d33fb97be8..f5b2afbd00 100644 --- a/src/TiledArray/math/blas.h +++ b/src/TiledArray/math/blas.h @@ -28,16 +28,38 @@ #include #include -#include + +#include +#include +#include +#include +#include + +#include namespace TiledArray::math::blas { -using TransposeFlag = madness::cblas::CBLAS_TRANSPOSE; -static constexpr auto NoTranspose = madness::cblas::NoTrans; -static constexpr auto Transpose = madness::cblas::Trans; -static constexpr auto ConjTranspose = madness::cblas::ConjTrans; +/// the integer type used by C++ BLAS/LAPACK interface, same as that used by +/// BLAS++/LAPACK++ +using integer = int64_t; + +using Op = ::blas::Op; +static constexpr auto NoTranspose = Op::NoTrans; +static constexpr auto Transpose = Op::Trans; +static constexpr auto ConjTranspose = Op::ConjTrans; + +/// converts Op to ints in manner useful for bit manipulations +/// NoTranspose -> 0, Transpose->1, ConjTranspose->2 +inline int64_t to_int(Op op) { + if (op == NoTranspose) + return 0; + else if (op == Transpose) + return 1; + else // op == ConjTranspose + return 2; +} -template +template using Matrix = ::Eigen::Matrix; template @@ -46,9 +68,8 @@ using Vector = ::Eigen::Matrix; // BLAS _GEMM wrapper functions template -inline void gemm(TransposeFlag op_a, - TransposeFlag op_b, const integer m, - const integer n, const integer k, const S1 alpha, const T1* a, +inline void gemm(Op op_a, Op op_b, const integer m, const integer n, + const integer k, const S1 alpha, const T1* a, const integer lda, const T2* b, const integer ldb, const S2 beta, T3* c, const integer ldc) { // Define operations @@ -70,17 +91,17 @@ inline void gemm(TransposeFlag op_a, typedef Eigen::Matrix matrixC_type; Eigen::Map> A( - a, (op_a == madness::cblas::NoTrans ? m : k), - (op_a == madness::cblas::NoTrans ? k : m), Eigen::OuterStride<>(lda)); + a, (op_a == NoTranspose ? m : k), (op_a == NoTranspose ? k : m), + Eigen::OuterStride<>(lda)); Eigen::Map> B( - b, (op_b == madness::cblas::NoTrans ? k : n), - (op_b == madness::cblas::NoTrans ? n : k), Eigen::OuterStride<>(ldb)); + b, (op_b == NoTranspose ? k : n), (op_b == NoTranspose ? n : k), + Eigen::OuterStride<>(ldb)); Eigen::Map> C( c, m, n, Eigen::OuterStride<>(ldc)); const bool beta_is_nonzero = (beta != static_cast(0)); - switch (op_a | (op_b << 2)) { + switch (to_int(op_a) | (to_int(op_b) << 2)) { case notrans_notrans: if (beta_is_nonzero) C.noalias() = alpha * A * B + beta * C; @@ -139,47 +160,40 @@ inline void gemm(TransposeFlag op_a, } } -inline void gemm(TransposeFlag op_a, - TransposeFlag op_b, const integer m, - const integer n, const integer k, const float alpha, - const float* a, const integer lda, const float* b, - const integer ldb, const float beta, float* c, - const integer ldc) { - madness::cblas::gemm(op_b, op_a, n, m, k, alpha, b, ldb, a, lda, beta, c, - ldc); +inline void gemm(Op op_a, Op op_b, const integer m, const integer n, + const integer k, const float alpha, const float* a, + const integer lda, const float* b, const integer ldb, + const float beta, float* c, const integer ldc) { + ::blas::gemm(::blas::Layout::ColMajor, op_b, op_a, n, m, k, alpha, b, ldb, a, + lda, beta, c, ldc); } -inline void gemm(TransposeFlag op_a, - TransposeFlag op_b, const integer m, - const integer n, const integer k, const double alpha, - const double* a, const integer lda, const double* b, - const integer ldb, const double beta, double* c, - const integer ldc) { - madness::cblas::gemm(op_b, op_a, n, m, k, alpha, b, ldb, a, lda, beta, c, - ldc); +inline void gemm(Op op_a, Op op_b, const integer m, const integer n, + const integer k, const double alpha, const double* a, + const integer lda, const double* b, const integer ldb, + const double beta, double* c, const integer ldc) { + ::blas::gemm(::blas::Layout::ColMajor, op_b, op_a, n, m, k, alpha, b, ldb, a, + lda, beta, c, ldc); } -inline void gemm(TransposeFlag op_a, - TransposeFlag op_b, const integer m, - const integer n, const integer k, - const std::complex alpha, const std::complex* a, - const integer lda, const std::complex* b, - const integer ldb, const std::complex beta, - std::complex* c, const integer ldc) { - madness::cblas::gemm(op_b, op_a, n, m, k, alpha, b, ldb, a, lda, beta, c, - ldc); +inline void gemm(Op op_a, Op op_b, const integer m, const integer n, + const integer k, const std::complex alpha, + const std::complex* a, const integer lda, + const std::complex* b, const integer ldb, + const std::complex beta, std::complex* c, + const integer ldc) { + ::blas::gemm(::blas::Layout::ColMajor, op_b, op_a, n, m, k, alpha, b, ldb, a, + lda, beta, c, ldc); } -inline void gemm(TransposeFlag op_a, - TransposeFlag op_b, const integer m, - const integer n, const integer k, - const std::complex alpha, +inline void gemm(Op op_a, Op op_b, const integer m, const integer n, + const integer k, const std::complex alpha, const std::complex* a, const integer lda, const std::complex* b, const integer ldb, const std::complex beta, std::complex* c, const integer ldc) { - madness::cblas::gemm(op_b, op_a, n, m, k, alpha, b, ldb, a, lda, beta, c, - ldc); + ::blas::gemm(::blas::Layout::ColMajor, op_b, op_a, n, m, k, alpha, b, ldb, a, + lda, beta, c, ldc); } // BLAS _SCAL wrapper functions @@ -191,30 +205,30 @@ inline typename std::enable_if>::type scale( } inline void scale(const integer n, const float alpha, float* x) { - madness::cblas::scal(n, alpha, x, 1); + ::blas::scal(n, alpha, x, 1); } inline void scale(const integer n, const double alpha, double* x) { - madness::cblas::scal(n, alpha, x, 1); + ::blas::scal(n, alpha, x, 1); } inline void scale(const integer n, const std::complex alpha, std::complex* x) { - madness::cblas::scal(n, alpha, x, 1); + ::blas::scal(n, alpha, x, 1); } inline void scale(const integer n, const std::complex alpha, std::complex* x) { - madness::cblas::scal(n, alpha, x, 1); + ::blas::scal(n, alpha, x, 1); } inline void scale(const integer n, const float alpha, std::complex* x) { - madness::cblas::scal(n, alpha, x, 1); + ::blas::scal(n, std::complex{alpha, 0}, x, 1); } inline void scale(const integer n, const double alpha, std::complex* x) { - madness::cblas::scal(n, alpha, x, 1); + ::blas::scal(n, std::complex{alpha, 0}, x, 1); } // BLAS _DOT wrapper functions @@ -224,31 +238,31 @@ T dot(const integer n, const T* x, const U* y) { return Vector::Map(x, n).dot(Vector::Map(y, n)); } -inline float dot(integer n, const float* x, const float* y) { - return madness::cblas::dot(n, x, 1, y, 1); +inline float dot(const integer n, const float* x, const float* y) { + return ::blas::dot(n, x, 1, y, 1); } inline double dot(integer n, const double* x, const double* y) { - return madness::cblas::dot(n, x, 1, y, 1); + return ::blas::dot(n, x, 1, y, 1); } inline std::complex dot(integer n, const std::complex* x, const std::complex* y) { - return madness::cblas::dot(n, x, 1, y, 1); + return ::blas::dot(n, x, 1, y, 1); } inline std::complex dot(integer n, const std::complex* x, const std::complex* y) { - return madness::cblas::dot(n, x, 1, y, 1); + return ::blas::dot(n, x, 1, y, 1); } // Import the madness dot functions into the TiledArray namespace -using madness::cblas::dot; +using ::blas::dot; -} // namespace TiledArray::local +} // namespace TiledArray::math::blas namespace TiledArray { - namespace blas = TiledArray::math::blas; +// namespace blas = TiledArray::math::blas; } #endif // TILEDARRAY_MATH_BLAS_H__INCLUDED diff --git a/src/TiledArray/math/gemm_helper.h b/src/TiledArray/math/gemm_helper.h index 4eb3e256f0..e3243e37c8 100644 --- a/src/TiledArray/math/gemm_helper.h +++ b/src/TiledArray/math/gemm_helper.h @@ -27,9 +27,10 @@ #define TILEDARRAY_MATH_GEMM_HELPER_H__INCLUDED #include -#include #include +#include + namespace TiledArray::math { /// Contraction to *GEMM helper @@ -38,9 +39,9 @@ namespace TiledArray::math { /// providing information on how to fuse dimensions class GemmHelper { private: - blas::TransposeFlag left_op_; + blas::Op left_op_; ///< Transpose operation that is applied to the left-hand argument - blas::TransposeFlag right_op_; + blas::Op right_op_; ///< Transpose operation that is applied to the right-hand argument unsigned int result_rank_; ///< The rank of the result tensor @@ -57,8 +58,7 @@ class GemmHelper { right_; ///< Right-hand argument range data public: - GemmHelper(const blas::TransposeFlag left_op, - const blas::TransposeFlag right_op, + GemmHelper(const blas::Op left_op, const blas::Op right_op, const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank) : left_op_(left_op), @@ -251,8 +251,9 @@ class GemmHelper { /// \param[in] left The left-hand range object /// \param[in] right The right-hand range object template - void compute_matrix_sizes(integer& m, integer& n, integer& k, - const Left& left, const Right& right) const { + void compute_matrix_sizes(blas::integer& m, blas::integer& n, + blas::integer& k, const Left& left, + const Right& right) const { // Check that the arguments are not empty and have the correct ranks TA_ASSERT(left.rank() == left_.rank); TA_ASSERT(right.rank() == right_.rank); @@ -271,8 +272,8 @@ class GemmHelper { n *= right_extent[i]; } - blas::TransposeFlag left_op() const { return left_op_; } - blas::TransposeFlag right_op() const { return right_op_; } + blas::Op left_op() const { return left_op_; } + blas::Op right_op() const { return right_op_; } }; // class GemmHelper } // namespace TiledArray::math diff --git a/src/TiledArray/math/lapack.h b/src/TiledArray/math/lapack.h index 38b2cb10d0..e841a80f85 100644 --- a/src/TiledArray/math/lapack.h +++ b/src/TiledArray/math/lapack.h @@ -3,41 +3,6 @@ #include -#if defined(BTAS_HAS_INTEL_MKL) +#include -#include -#include // lapack_int - -#elif defined(BTAS_HAS_LAPACKE) - - // see https://github.com/xianyi/OpenBLAS/issues/1992 why this is needed to prevent lapacke.h #define'ing I -# include -# ifndef lapack_complex_float -# define lapack_complex_float std::complex -# else // lapack_complex_float - static_assert(sizeof(std::complex)==sizeof(lapack_complex_float), "sizes of lapack_complex_float and std::complex do not match"); -# endif // lapack_complex_float -# ifndef lapack_complex_double -# define lapack_complex_double std::complex -# else // lapack_complex_double - static_assert(sizeof(std::complex)==sizeof(lapack_complex_double), "sizes of lapack_complex_double and std::complex do not match"); -# endif // lapack_complex_double - -#if defined(BTAS_LAPACKE_HEADER) -#include BTAS_LAPACKE_HEADER -#else -#include -#endif - -#elif defined(__APPLE__) - -#include -using lapack_int = __CLPK_integer; - -#else - -#error "Could not find Lapack/e" - -#endif - -#endif // TILEDARRAY_MATH_LAPACK_H__INCLUDED +#endif // TILEDARRAY_MATH_LAPACK_H__INCLUDED diff --git a/src/TiledArray/math/linalg/cholesky.h b/src/TiledArray/math/linalg/cholesky.h index 3678c46d80..973245cdc7 100644 --- a/src/TiledArray/math/linalg/cholesky.h +++ b/src/TiledArray/math/linalg/cholesky.h @@ -61,7 +61,7 @@ auto cholesky_solve(const Array& A, const Array& B, } template -auto cholesky_lsolve(TransposeFlag transpose, const Array& A, const Array& B, +auto cholesky_lsolve(Op transpose, const Array& A, const Array& B, TiledRange l_trange = TiledRange(), TiledRange x_trange = TiledRange()) { #if TILEDARRAY_HAS_SCALAPACK @@ -75,10 +75,10 @@ auto cholesky_lsolve(TransposeFlag transpose, const Array& A, const Array& B, } // namespace TiledArray::math::linalg namespace TiledArray { - using TiledArray::math::linalg::cholesky; - using TiledArray::math::linalg::cholesky_linv; - using TiledArray::math::linalg::cholesky_solve; - using TiledArray::math::linalg::cholesky_lsolve; -} +using TiledArray::math::linalg::cholesky; +using TiledArray::math::linalg::cholesky_linv; +using TiledArray::math::linalg::cholesky_lsolve; +using TiledArray::math::linalg::cholesky_solve; +} // namespace TiledArray #endif // TILEDARRAY_MATH_LINALG_CHOL_H__INCLUDED diff --git a/src/TiledArray/math/linalg/forward.h b/src/TiledArray/math/linalg/forward.h index 2ce19e21f6..d22df73567 100644 --- a/src/TiledArray/math/linalg/forward.h +++ b/src/TiledArray/math/linalg/forward.h @@ -28,24 +28,37 @@ #include #include +#include + namespace TiledArray::math::linalg { -enum TransposeFlag { NoTranspose, Transpose, ConjTranspose }; +using Op = ::blas::Op; +static constexpr auto NoTranspose = Op::NoTrans; +static constexpr auto Transpose = Op::Trans; +static constexpr auto ConjTranspose = Op::ConjTrans; + +/// converts Op to ints in manner useful for bit manipulations +/// NoTranspose -> 0, Transpose->1, ConjTranspose->2 +inline auto to_int(Op op) { + if (op == NoTranspose) + return 0; + else if (op == Transpose) + return 1; + else // op == ConjTranspose + return 2; +} struct SVD { - enum Vectors { - ValuesOnly, - LeftVectors, - RightVectors, - AllVectors - }; + enum Vectors { ValuesOnly, LeftVectors, RightVectors, AllVectors }; }; } // namespace TiledArray::math::linalg namespace TiledArray { - using TiledArray::math::linalg::TransposeFlag; - using TiledArray::math::linalg::SVD; -} +using TiledArray::math::linalg::ConjTranspose; +using TiledArray::math::linalg::NoTranspose; +using TiledArray::math::linalg::SVD; +using TiledArray::math::linalg::Transpose; +} // namespace TiledArray #endif // TILEDARRAY_MATH_LINALG_FORWARD_H__INCLUDED diff --git a/src/TiledArray/math/linalg/non-distributed/cholesky.h b/src/TiledArray/math/linalg/non-distributed/cholesky.h index b72a06e20e..18ddc5793b 100644 --- a/src/TiledArray/math/linalg/non-distributed/cholesky.h +++ b/src/TiledArray/math/linalg/non-distributed/cholesky.h @@ -26,9 +26,9 @@ #include -#include #include #include +#include namespace TiledArray::math::linalg::non_distributed { @@ -148,6 +148,7 @@ auto cholesky_linv(const Array& A, TiledRange l_trange = TiledRange()) { eigen_to_array(world, l_trange, L_inv_eig)); else return eigen_to_array(world, l_trange, L_eig); + abort(); // unreachable } template >> -auto cholesky_lsolve(TransposeFlag transpose, const Array& A, const Array& B, +auto cholesky_lsolve(Op transpose, const Array& A, const Array& B, TiledRange l_trange = TiledRange(), TiledRange x_trange = TiledRange()) { World& world = A.world(); @@ -195,6 +196,6 @@ auto cholesky_lsolve(TransposeFlag transpose, const Array& A, const Array& B, eigen_to_array(world, x_trange, X_eig)); } -} // namespace TiledArray::math::linalg +} // namespace TiledArray::math::linalg::non_distributed #endif // TILEDARRAY_MATH_LINALG_NON_DISTRIBUTED_CHOL_H__INCLUDED diff --git a/src/TiledArray/math/linalg/rank-local.cpp b/src/TiledArray/math/linalg/rank-local.cpp index 752f6d3929..e26ec3da59 100644 --- a/src/TiledArray/math/linalg/rank-local.cpp +++ b/src/TiledArray/math/linalg/rank-local.cpp @@ -22,16 +22,19 @@ * */ -#include +#include #include +#include -template -inline int ta_lapack_call(F f, Args ... args) { +template +inline int ta_lapack_fortran_call(F f, Args... args) { lapack_int info; - auto ptr = [](auto &&a) { + auto ptr = [](auto&& a) { using T = std::remove_reference_t; - if constexpr (std::is_pointer_v) return a; - else return &a; + if constexpr (std::is_pointer_v) + return a; + else + return &a; }; f(ptr(args)..., &info); return info; @@ -39,184 +42,167 @@ inline int ta_lapack_call(F f, Args ... args) { #define TA_LAPACK_ERROR(F) throw std::runtime_error("lapack::" #F " failed") -#define TA_LAPACK_CALL(F, ARGS...) \ - ((ta_lapack_call(F##_, ARGS) == 0) || (TA_LAPACK_ERROR(F), 0)) - -/// TA_LAPACK(fn,args) can be called only from template context, with `T` -/// defining the element type -#define TA_LAPACK(name, args...) { \ - using numeric_type = T; \ - if constexpr (std::is_same_v) \ - TA_LAPACK_CALL(d##name, args); \ - else if constexpr (std::is_same_v) \ - TA_LAPACK_CALL(s##name, args); \ - else std::abort(); \ +#define TA_LAPACK_FORTRAN_CALL(F, ARGS...) \ + ((ta_lapack_fortran_call(F, ARGS) == 0) || (TA_LAPACK_ERROR(F), 0)) + +/// \brief Invokes the Fortran LAPACK API + +/// \warning TA_LAPACK_FORTRAN(fn,args) can be called only from template +/// context, with `T` defining the element type +#define TA_LAPACK_FORTRAN(name, args...) \ + { \ + using numeric_type = T; \ + if constexpr (std::is_same_v) \ + TA_LAPACK_FORTRAN_CALL(d##name, args); \ + else if constexpr (std::is_same_v) \ + TA_LAPACK_FORTRAN_CALL(s##name, args); \ + else \ + std::abort(); \ } +/// TA_LAPACK(fn,args) invoked lapack::fn directly and checks the return value +#define TA_LAPACK(name, args...) \ + ((::lapack::name(args) == 0) || (TA_LAPACK_ERROR(name), 0)) + namespace TiledArray::math::linalg::rank_local { +using integer = math::blas::integer; + template void cholesky(Matrix& A) { - char uplo = 'L'; - lapack_int n = A.rows(); + auto uplo = lapack::Uplo::Lower; + integer n = A.rows(); auto* a = A.data(); - lapack_int lda = n; + integer lda = n; TA_LAPACK(potrf, uplo, n, a, lda); } template void cholesky_linv(Matrix& A) { - char uplo = 'L'; - char diag = 'N'; - lapack_int n = A.rows(); + auto uplo = lapack::Uplo::Lower; + auto diag = lapack::Diag::NonUnit; + integer n = A.rows(); auto* l = A.data(); - lapack_int lda = n; + integer lda = n; TA_LAPACK(trtri, uplo, diag, n, l, lda); } template void cholesky_solve(Matrix& A, Matrix& X) { - char uplo = 'L'; - lapack_int n = A.rows(); - lapack_int nrhs = X.cols(); + auto uplo = lapack::Uplo::Lower; + integer n = A.rows(); + integer nrhs = X.cols(); auto* a = A.data(); auto* b = X.data(); - lapack_int lda = n; - lapack_int ldb = n; + integer lda = n; + integer ldb = n; TA_LAPACK(posv, uplo, n, nrhs, a, lda, b, ldb); } template -void cholesky_lsolve(TransposeFlag transpose, Matrix& A, Matrix& X) { - char uplo = 'L'; - char trans = transpose == TransposeFlag::Transpose - ? 'T' - : (transpose == TransposeFlag::NoTranspose ? 'N' : 'C'); - char diag = 'N'; - lapack_int n = A.rows(); - lapack_int nrhs = X.cols(); +void cholesky_lsolve(Op transpose, Matrix& A, Matrix& X) { + auto uplo = lapack::Uplo::Lower; + auto diag = lapack::Diag::NonUnit; + integer n = A.rows(); + integer nrhs = X.cols(); auto* a = A.data(); auto* b = X.data(); - lapack_int lda = n; - lapack_int ldb = n; - TA_LAPACK(trtrs, uplo, trans, diag, n, nrhs, a, lda, b, ldb); + integer lda = n; + integer ldb = n; + TA_LAPACK(trtrs, uplo, transpose, diag, n, nrhs, a, lda, b, ldb); } template void heig(Matrix& A, std::vector& W) { - char jobz = 'V'; - char uplo = 'L'; - lapack_int n = A.rows(); + auto jobz = lapack::Job::Vec; + auto uplo = lapack::Uplo::Lower; + integer n = A.rows(); T* a = A.data(); - lapack_int lda = A.rows(); + integer lda = A.rows(); W.resize(n); T* w = W.data(); - lapack_int lwork = -1; - std::vector work(1); - TA_LAPACK(syev, jobz, uplo, n, a, lda, w, work.data(), lwork); - lwork = lapack_int(work[0]); - work.resize(lwork); - TA_LAPACK(syev, jobz, uplo, n, a, lda, w, work.data(), lwork); + TA_LAPACK(syev, jobz, uplo, n, a, lda, w); } template void heig(Matrix& A, Matrix& B, std::vector& W) { - lapack_int itype = 1; - char jobz = 'V'; - char uplo = 'L'; - lapack_int n = A.rows(); + integer itype = 1; + auto jobz = lapack::Job::Vec; + auto uplo = lapack::Uplo::Lower; + integer n = A.rows(); T* a = A.data(); - lapack_int lda = A.rows(); + integer lda = A.rows(); T* b = B.data(); - lapack_int ldb = B.rows(); + integer ldb = B.rows(); W.resize(n); T* w = W.data(); - std::vector work(1); - lapack_int lwork = -1; - TA_LAPACK(sygv, itype, jobz, uplo, n, a, lda, b, ldb, w, work.data(), lwork); - lwork = lapack_int(work[0]); - work.resize(lwork); - TA_LAPACK(sygv, itype, jobz, uplo, n, a, lda, b, ldb, w, work.data(), lwork); + TA_LAPACK(sygv, itype, jobz, uplo, n, a, lda, b, ldb, w); } template void svd(Matrix& A, std::vector& S, Matrix* U, Matrix* VT) { - lapack_int m = A.rows(); - lapack_int n = A.cols(); + integer m = A.rows(); + integer n = A.cols(); T* a = A.data(); - lapack_int lda = A.rows(); + integer lda = A.rows(); S.resize(std::min(m, n)); T* s = S.data(); - char jobu = 'N'; + auto jobu = lapack::Job::NoVec; T* u = nullptr; - lapack_int ldu = m; + integer ldu = m; if (U) { - jobu = 'A'; + jobu = lapack::Job::AllVec; U->resize(m, n); u = U->data(); ldu = U->rows(); } - char jobvt = 'N'; + auto jobvt = lapack::Job::NoVec; T* vt = nullptr; - lapack_int ldvt = n; + integer ldvt = n; if (VT) { - jobvt = 'A'; + jobvt = lapack::Job::AllVec; VT->resize(n, m); vt = VT->data(); ldvt = VT->rows(); } - std::vector work(1); - lapack_int lwork = -1; - - TA_LAPACK(gesvd, jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, - work.data(), lwork); - lwork = lapack_int(work[0]); - work.resize(lwork); - TA_LAPACK(gesvd, jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, - work.data(), lwork); - + TA_LAPACK(gesvd, jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt); } template void lu_solve(Matrix& A, Matrix& B) { - lapack_int n = A.rows(); - lapack_int nrhs = B.cols(); + integer n = A.rows(); + integer nrhs = B.cols(); T* a = A.data(); - lapack_int lda = A.rows(); + integer lda = A.rows(); T* b = B.data(); - lapack_int ldb = B.rows(); - std::vector ipiv(n); + integer ldb = B.rows(); + std::vector ipiv(n); TA_LAPACK(gesv, n, nrhs, a, lda, ipiv.data(), b, ldb); } template void lu_inv(Matrix& A) { - lapack_int n = A.rows(); + integer n = A.rows(); T* a = A.data(); - lapack_int lda = A.rows(); - std::vector ipiv(n); + integer lda = A.rows(); + std::vector ipiv(n); TA_LAPACK(getrf, n, n, a, lda, ipiv.data()); - std::vector work(1); - lapack_int lwork = -1; - TA_LAPACK(getri, n, a, lda, ipiv.data(), work.data(), lwork); - lwork = (lapack_int)work[0]; - work.resize(lwork); - TA_LAPACK(getri, n, a, lda, ipiv.data(), work.data(), lwork); + TA_LAPACK(getri, n, a, lda, ipiv.data()); } -#define TA_LAPACK_EXPLICIT(MATRIX, VECTOR) \ - template void cholesky(MATRIX&); \ - template void cholesky_linv(MATRIX&); \ - template void cholesky_solve(MATRIX&, MATRIX&); \ - template void cholesky_lsolve(TransposeFlag, MATRIX&, MATRIX&); \ - template void heig(MATRIX&, VECTOR&); \ - template void heig(MATRIX&, MATRIX&, VECTOR&); \ - template void svd(MATRIX&, VECTOR&, MATRIX*, MATRIX*); \ - template void lu_solve(MATRIX&, MATRIX&); \ +#define TA_LAPACK_EXPLICIT(MATRIX, VECTOR) \ + template void cholesky(MATRIX&); \ + template void cholesky_linv(MATRIX&); \ + template void cholesky_solve(MATRIX&, MATRIX&); \ + template void cholesky_lsolve(Op, MATRIX&, MATRIX&); \ + template void heig(MATRIX&, VECTOR&); \ + template void heig(MATRIX&, MATRIX&, VECTOR&); \ + template void svd(MATRIX&, VECTOR&, MATRIX*, MATRIX*); \ + template void lu_solve(MATRIX&, MATRIX&); \ template void lu_inv(MATRIX&); TA_LAPACK_EXPLICIT(Matrix, std::vector); diff --git a/src/TiledArray/math/linalg/rank-local.h b/src/TiledArray/math/linalg/rank-local.h index 220ad8461f..144c844e3c 100644 --- a/src/TiledArray/math/linalg/rank-local.h +++ b/src/TiledArray/math/linalg/rank-local.h @@ -3,14 +3,14 @@ #include -#include #include +#include #include namespace TiledArray::math::linalg::rank_local { -template +template using Matrix = ::Eigen::Matrix; // template @@ -26,7 +26,7 @@ template void cholesky_solve(Matrix &A, Matrix &X); template -void cholesky_lsolve(TransposeFlag transpose, Matrix &A, Matrix &X); +void cholesky_lsolve(Op transpose, Matrix &A, Matrix &X); template void heig(Matrix &A, std::vector &W); @@ -35,8 +35,7 @@ template void heig(Matrix &A, Matrix &B, std::vector &W); template -void svd(Matrix &A, std::vector &S, - Matrix *U, Matrix *VT); +void svd(Matrix &A, std::vector &S, Matrix *U, Matrix *VT); template void lu_solve(Matrix &A, Matrix &B); @@ -44,6 +43,6 @@ void lu_solve(Matrix &A, Matrix &B); template void lu_inv(Matrix &A); -} // namespace TiledArray::local +} // namespace TiledArray::math::linalg::rank_local #endif // TILEDARRAY_MATH_LINALG_RANK_LOCAL_H__INCLUDED diff --git a/src/TiledArray/math/linalg/scalapack/cholesky.h b/src/TiledArray/math/linalg/scalapack/cholesky.h index a11080f209..545015e8a9 100644 --- a/src/TiledArray/math/linalg/scalapack/cholesky.h +++ b/src/TiledArray/math/linalg/scalapack/cholesky.h @@ -28,8 +28,8 @@ #include #if TILEDARRAY_HAS_SCALAPACK -#include #include +#include #include #include @@ -110,7 +110,7 @@ auto cholesky(const Array& A, TiledRange l_trange = TiledRange(), * * @returns The inverse lower triangular Cholesky factor in TA format */ - template +template auto cholesky_linv(const Array& A, TiledRange l_trange = TiledRange(), size_t NB = default_block_size()) { using value_type = typename Array::element_type; @@ -215,7 +215,7 @@ auto cholesky_solve(const Array& A, const Array& B, } template -auto cholesky_lsolve(TransposeFlag trans, const Array& A, const Array& B, +auto cholesky_lsolve(Op trans, const Array& A, const Array& B, TiledRange l_trange = TiledRange(), TiledRange x_trange = TiledRange(), size_t NB = default_block_size()) { diff --git a/src/TiledArray/math/linalg/scalapack/util.h b/src/TiledArray/math/linalg/scalapack/util.h index ea4c76fe1e..7c9c7abd89 100644 --- a/src/TiledArray/math/linalg/scalapack/util.h +++ b/src/TiledArray/math/linalg/scalapack/util.h @@ -33,14 +33,13 @@ namespace TiledArray::math::linalg::scalapack { -inline scalapackpp::TransposeFlag to_scalapackpp_transposeflag( - TransposeFlag t) { +inline scalapackpp::TransposeFlag to_scalapackpp_transposeflag(Op t) { switch (t) { - case TransposeFlag::NoTranspose: + case Op::NoTrans: return scalapackpp::TransposeFlag::NoTranspose; - case TransposeFlag::Transpose: + case Op::Trans: return scalapackpp::TransposeFlag::Transpose; - case TransposeFlag::ConjTranspose: + case Op::ConjTrans: return scalapackpp::TransposeFlag::ConjTranspose; default: abort(); diff --git a/src/TiledArray/math/parallel_gemm.h b/src/TiledArray/math/parallel_gemm.h index fd65599356..5f3017dc44 100644 --- a/src/TiledArray/math/parallel_gemm.h +++ b/src/TiledArray/math/parallel_gemm.h @@ -129,7 +129,7 @@ class MatrixBlockTask : public tbb::task { template class GemmTask : public tbb::task { - const blas::TransposeFlag op_a_, op_b_; + const blas::Op op_a_, op_b_; const integer m_, n_, k_; const Alpha alpha_; std::shared_ptr a_; @@ -140,11 +140,10 @@ class GemmTask : public tbb::task { const integer ldc_; public: - GemmTask(blas::TransposeFlag op_a, - blas::TransposeFlag op_b, const integer m, - const integer n, const integer k, const Alpha alpha, - const std::shared_ptr& a, const std::shared_ptr& b, - const Beta beta, const std::shared_ptr& c, const integer ldc) + GemmTask(blas::Op op_a, blas::Op op_b, const integer m, const integer n, + const integer k, const Alpha alpha, const std::shared_ptr& a, + const std::shared_ptr& b, const Beta beta, + const std::shared_ptr& c, const integer ldc) : op_a_(op_a), op_b_(op_b), m_(m), diff --git a/src/TiledArray/reduce_task.h b/src/TiledArray/reduce_task.h index 716ae641e3..5b084d0bcd 100644 --- a/src/TiledArray/reduce_task.h +++ b/src/TiledArray/reduce_task.h @@ -627,7 +627,7 @@ class ReduceTask { #ifdef TILEDARRAY_HAS_CUDA template - std::enable_if_t::value, void> internal_run( + std::enable_if_t, void> internal_run( const madness::TaskThreadEnv&) { TA_ASSERT(ready_result_); @@ -640,7 +640,7 @@ class ReduceTask { } template - std::enable_if_t::value, void> + std::enable_if_t, void> #else void #endif diff --git a/src/TiledArray/sparse_shape.h b/src/TiledArray/sparse_shape.h index 172fd995f1..06f660cb0a 100644 --- a/src/TiledArray/sparse_shape.h +++ b/src/TiledArray/sparse_shape.h @@ -1464,6 +1464,7 @@ class SparseShape { const value_type threshold = threshold_; madness::AtomicInt zero_tile_count; zero_tile_count = 0; + using integer = TiledArray::math::blas::integer; integer M = 0, N = 0, K = 0; gemm_helper.compute_matrix_sizes(M, N, K, tile_norms_.range(), other.tile_norms_.range()); diff --git a/src/TiledArray/special/diagonal_array.h b/src/TiledArray/special/diagonal_array.h index 7772b3ef28..87e1c3f23f 100644 --- a/src/TiledArray/special/diagonal_array.h +++ b/src/TiledArray/special/diagonal_array.h @@ -243,6 +243,7 @@ Array diagonal_array(World &world, TiledRange const &trange, T val = 1) { detail::write_diag_tiles_to_array_val(A, val); return A; } + abort(); // unreachable } /// \brief Creates a non-constant diagonal DistArray @@ -285,6 +286,7 @@ diagonal_array(World &world, TiledRange const &trange, detail::write_diag_tiles_to_array_rng(A, diagonals_begin); return A; } + abort(); // unreachable } } // namespace TiledArray diff --git a/src/TiledArray/tensor/kernels.h b/src/TiledArray/tensor/kernels.h index bfbe25f083..7276678145 100644 --- a/src/TiledArray/tensor/kernels.h +++ b/src/TiledArray/tensor/kernels.h @@ -70,6 +70,7 @@ inline TR tensor_op(Op&& op, const T1& tensor1, const Ts&... tensors) { return TiledArray::detail::transform()(std::forward(op), tensor1, tensors...); } + abort(); // unreachable } /// Tensor permutation operations with contiguous data diff --git a/src/TiledArray/tensor/tensor.h b/src/TiledArray/tensor/tensor.h index 0e174a5fee..06b1c8cc4b 100644 --- a/src/TiledArray/tensor/tensor.h +++ b/src/TiledArray/tensor/tensor.h @@ -876,6 +876,7 @@ class Tensor { } return rv; } + abort(); // unreachable } /// Shift the lower and upper bound of this tensor @@ -983,6 +984,7 @@ class Tensor { Permute p; return p(temp, perm); } + abort(); // unreachable } /// Use a binary, element wise operation to modify this tensor @@ -1046,6 +1048,7 @@ class Tensor { Permute p; return p(temp, perm); } + abort(); // unreachable } /// Use a unary, element wise operation to modify this tensor @@ -1630,20 +1633,19 @@ class Tensor { other.range().extent_data())); // Compute gemm dimensions + using integer = TiledArray::math::blas::integer; integer m = 1, n = 1, k = 1; gemm_helper.compute_matrix_sizes(m, n, k, pimpl_->range_, other.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == blas::NoTranspose ? k : m); + (gemm_helper.left_op() == TiledArray::math::blas::NoTranspose ? k : m); const integer ldb = - (gemm_helper.right_op() == blas::NoTranspose ? n : k); + (gemm_helper.right_op() == TiledArray::math::blas::NoTranspose ? n : k); - blas::gemm( - gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, factor, - pimpl_->data_, lda, other.data(), ldb, numeric_type(0), - result.data(), n - ); + math::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, + factor, pimpl_->data_, lda, other.data(), ldb, + numeric_type(0), result.data(), n); #ifdef TA_ENABLE_TILE_OPS_LOGGING if (TiledArray::TileOpsLogger::get_instance_ptr() != nullptr && @@ -1787,14 +1789,17 @@ class Tensor { right.range().extent_data())); // Compute gemm dimensions + using integer = TiledArray::math::blas::integer; integer m, n, k; gemm_helper.compute_matrix_sizes(m, n, k, left.range(), right.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == blas::NoTranspose ? k : m); + (gemm_helper.left_op() == TiledArray::math::blas::NoTranspose ? k + : m); const integer ldb = - (gemm_helper.right_op() == blas::NoTranspose ? n : k); + (gemm_helper.right_op() == TiledArray::math::blas::NoTranspose ? n + : k); // may need to split gemm into multiply + accumulate for tracing purposes #ifdef TA_ENABLE_TILE_OPS_LOGGING @@ -1811,12 +1816,10 @@ class Tensor { std::copy(pimpl_->data_, pimpl_->data_ + tile_volume, data_copy.get()); } - non_distributed::gemm( - gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, - factor, left.data(), lda, right.data(), ldb, - twostep ? numeric_type(0) : numeric_type(1), pimpl_->data_, - n - ); + non_distributed::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, + n, k, factor, left.data(), lda, right.data(), ldb, + twostep ? numeric_type(0) : numeric_type(1), + pimpl_->data_, n); if (TiledArray::TileOpsLogger::get_instance_ptr() != nullptr && TiledArray::TileOpsLogger::get_instance().gemm) { @@ -1866,11 +1869,9 @@ class Tensor { } } #else // TA_ENABLE_TILE_OPS_LOGGING - blas::gemm( - gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, factor, - left.data(), lda, right.data(), ldb, numeric_type(1), - pimpl_->data_, n - ); + math::blas::gemm(gemm_helper.left_op(), gemm_helper.right_op(), m, n, k, + factor, left.data(), lda, right.data(), ldb, + numeric_type(1), pimpl_->data_, n); #endif // TA_ENABLE_TILE_OPS_LOGGING } @@ -1929,25 +1930,28 @@ class Tensor { } // Compute gemm dimensions + using integer = TiledArray::math::blas::integer; integer M, N, K; gemm_helper.compute_matrix_sizes(M, N, K, left.range(), right.range()); // Get the leading dimension for left and right matrices. const integer lda = - (gemm_helper.left_op() == blas::NoTranspose ? K : M); + (gemm_helper.left_op() == TiledArray::math::blas::NoTranspose ? K : M); const integer ldb = - (gemm_helper.right_op() == blas::NoTranspose ? N : K); + (gemm_helper.right_op() == TiledArray::math::blas::NoTranspose ? N : K); for (integer m = 0; m != M; ++m) { for (integer n = 0; n != N; ++n) { auto c_offset = m * N + n; for (integer k = 0; k != K; ++k) { - auto a_offset = gemm_helper.left_op() == blas::NoTranspose - ? m * lda + k - : k * lda + m; - auto b_offset = gemm_helper.right_op() == blas::NoTranspose - ? k * ldb + n - : n * ldb + k; + auto a_offset = + gemm_helper.left_op() == TiledArray::math::blas::NoTranspose + ? m * lda + k + : k * lda + m; + auto b_offset = + gemm_helper.right_op() == TiledArray::math::blas::NoTranspose + ? k * ldb + n + : n * ldb + k; elem_muladd_op(*(pimpl_->data_ + c_offset), *(left.data() + a_offset), *(right.data() + b_offset)); } diff --git a/src/TiledArray/tensor/type_traits.h b/src/TiledArray/tensor/type_traits.h index 6690eb1f61..9b39326218 100644 --- a/src/TiledArray/tensor/type_traits.h +++ b/src/TiledArray/tensor/type_traits.h @@ -26,6 +26,8 @@ #ifndef TILEDARRAY_TENSOR_TYPE_TRAITS_H__INCLUDED #define TILEDARRAY_TENSOR_TYPE_TRAITS_H__INCLUDED +#include + #include #include @@ -263,6 +265,10 @@ struct is_cuda_tile> : public is_cuda_tile {}; template struct is_cuda_tile> : public is_cuda_tile::eval_type> {}; + +template +static constexpr const auto is_cuda_tile_v = is_cuda_tile::value; + #endif template diff --git a/src/TiledArray/tile_op/contract_reduce.h b/src/TiledArray/tile_op/contract_reduce.h index ea6fa16867..48b7936d26 100644 --- a/src/TiledArray/tile_op/contract_reduce.h +++ b/src/TiledArray/tile_op/contract_reduce.h @@ -86,8 +86,7 @@ class ContractReduceBase { std::is_invocable_r_v, result_value_type&, const left_value_type&, const right_value_type&>>> - Impl(const madness::cblas::CBLAS_TRANSPOSE left_op, - const madness::cblas::CBLAS_TRANSPOSE right_op, + Impl(const math::blas::Op left_op, const math::blas::Op right_op, const scalar_type alpha, const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank, const Perm& perm = {}, ElemMultAddOp&& elem_muladd_op = {}) @@ -143,9 +142,9 @@ class ContractReduceBase { std::is_invocable_r_v, result_value_type&, const left_value_type&, const right_value_type&>>> - ContractReduceBase(const madness::cblas::CBLAS_TRANSPOSE left_op, - const madness::cblas::CBLAS_TRANSPOSE right_op, - const scalar_type alpha, const unsigned int result_rank, + ContractReduceBase(const math::blas::Op left_op, + const math::blas::Op right_op, const scalar_type alpha, + const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank, const Perm& perm = {}, ElemMultAddOp&& elem_muladd_op = {}) @@ -278,8 +277,7 @@ class ContractReduce : public ContractReduceBase { std::is_invocable_r_v, result_value_type&, const left_value_type&, const right_value_type&>>> - ContractReduce(const madness::cblas::CBLAS_TRANSPOSE left_op, - const madness::cblas::CBLAS_TRANSPOSE right_op, + ContractReduce(const math::blas::Op left_op, const math::blas::Op right_op, const scalar_type alpha, const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank, const Perm& perm = {}, ElemMultAddOp&& elem_muladd_op = {}) @@ -407,8 +405,7 @@ class ContractReduce, result_value_type&, const left_value_type&, const right_value_type&>>> - ContractReduce(const madness::cblas::CBLAS_TRANSPOSE left_op, - const madness::cblas::CBLAS_TRANSPOSE right_op, + ContractReduce(const math::blas::Op left_op, const math::blas::Op right_op, const scalar_type alpha, const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank, const Perm& perm = {}, ElemMultAddOp&& elem_muladd_op = {}) @@ -534,8 +531,7 @@ class ContractReduce, result_value_type&, const left_value_type&, const right_value_type&>>> - ContractReduce(const madness::cblas::CBLAS_TRANSPOSE left_op, - const madness::cblas::CBLAS_TRANSPOSE right_op, + ContractReduce(const math::blas::Op left_op, const math::blas::Op right_op, const scalar_type alpha, const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank, const Perm& perm = {}, ElemMultAddOp&& elem_muladd_op = {}) diff --git a/src/TiledArray/tiledarray.cpp b/src/TiledArray/tiledarray.cpp index bbb6f05533..44bcabd788 100644 --- a/src/TiledArray/tiledarray.cpp +++ b/src/TiledArray/tiledarray.cpp @@ -1,14 +1,14 @@ -#include #include +#include #ifdef TILEDARRAY_HAS_CUDA -#include #include +#include #include #endif -#ifdef HAVE_INTEL_MKL -#include +#ifdef TILEDARRAY_HAS_INTEL_MKL +#include #endif namespace TiledArray { @@ -48,15 +48,15 @@ inline bool& finalized_accessor() { static bool flag = false; return flag; } -#ifdef HAVE_INTEL_MKL +#ifdef TILEDARRAY_HAS_INTEL_MKL inline int& mklnumthreads_accessor() { static int value = -1; return value; } #endif -} // namespace detail -} +} // namespace +} // namespace TiledArray /// @return true if TiledArray (and, necessarily, MADWorld runtime) is in an /// initialized state @@ -77,11 +77,9 @@ bool TiledArray::finalized() { return finalized_accessor(); } /// @throw TiledArray::Exception if TiledArray initialized MADWorld and /// TiledArray::finalize() had been called -TiledArray::World& TiledArray::initialize( - int& argc, char**& argv, - const SafeMPI::Intracomm& comm, - bool quiet) -{ +TiledArray::World& TiledArray::initialize(int& argc, char**& argv, + const SafeMPI::Intracomm& comm, + bool quiet) { if (initialized_madworld() && finalized()) throw Exception( "TiledArray finalized MADWorld already, cannot re-initialize MADWorld " @@ -103,7 +101,7 @@ TiledArray::World& TiledArray::initialize( #ifdef TILEDARRAY_HAS_CUDA TiledArray::cuda_initialize(); #endif -#ifdef HAVE_INTEL_MKL +#ifdef TILEDARRAY_HAS_INTEL_MKL // record number of MKL threads and set to 1 mklnumthreads_accessor() = mkl_get_max_threads(); mkl_set_num_threads(1); @@ -118,7 +116,7 @@ TiledArray::World& TiledArray::initialize( /// Finalizes TiledArray (and MADWorld runtime, if it had not been initialized /// when TiledArray::initialize was called). void TiledArray::finalize() { -#ifdef HAVE_INTEL_MKL +#ifdef TILEDARRAY_HAS_INTEL_MKL // reset number of MKL threads mkl_set_num_threads(mklnumthreads_accessor()); #endif diff --git a/src/TiledArray/util/function.h b/src/TiledArray/util/function.h index f2706d8556..9acb593f68 100644 --- a/src/TiledArray/util/function.h +++ b/src/TiledArray/util/function.h @@ -27,7 +27,7 @@ class shared_function { template ())(std::declval()...))>> - auto operator()(As &&... as) const { + auto operator()(As &&...as) const { return (*f_)(std::forward(as)...); } @@ -133,6 +133,7 @@ auto make_op_shared_handle(Op &&op) { return result_t(op); else return make_shared_function(std::forward(op)); + abort(); // unreachable } } // namespace TiledArray diff --git a/src/TiledArray/util/initializer_list.h b/src/TiledArray/util/initializer_list.h index f4f9df3806..881fdb41a4 100644 --- a/src/TiledArray/util/initializer_list.h +++ b/src/TiledArray/util/initializer_list.h @@ -156,6 +156,7 @@ auto tiled_range_from_il(T&& il, U shape = {}) { return tiled_range_from_il(*first_sub_il_it, std::move(shape)); } + abort(); // unreachable } //------------------------------------------------------------------------------ @@ -270,6 +271,7 @@ auto get_elem_from_il(T idx, U&& il, std::size_t depth = 0) { return get_elem_from_il(std::forward(idx), *itr, depth + 1); } } + abort(); // unreachable } //------------------------------------------------------------------------------ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 128dfa8d97..bd9ef161db 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -139,7 +139,6 @@ target_include_directories(${executable} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_BINARY_DIR}/tests - ${Boost_INCLUDE_DIRS} ) # unit tests # 1. should disable error messages diff --git a/tests/btas.cpp b/tests/btas.cpp index adeeecc3e9..12809b5b0b 100644 --- a/tests/btas.cpp +++ b/tests/btas.cpp @@ -36,12 +36,14 @@ using namespace TiledArray; static_assert(detail::ordinal_traits>::type == OrdinalType::RowMajor, "btas::RangeNd<> is row-major"); -static_assert(detail::ordinal_traits>::type == - OrdinalType::RowMajor, - "btas::RangeNd is row-major"); -static_assert(detail::ordinal_traits>::type == - OrdinalType::ColMajor, - "btas::RangeNd is col-major"); +static_assert( + detail::ordinal_traits>::type == + OrdinalType::RowMajor, + "btas::RangeNd is row-major"); +static_assert( + detail::ordinal_traits>::type == + OrdinalType::ColMajor, + "btas::RangeNd is col-major"); static_assert(detail::ordinal_traits>::type == OrdinalType::RowMajor, "btas::Tenspr is row-major"); @@ -56,10 +58,16 @@ static_assert( "TA::Tile> is row-major"); // test traits -static_assert(TiledArray::detail::is_ta_tensor_v> == false, "btas::Tensor is not a TA::Tensor"); -static_assert(TiledArray::detail::is_ta_tensor_v> == true, "TA::Tensor is a TA::Tensor"); -static_assert(TiledArray::detail::is_btas_tensor_v> == true, "btas::Tensor is a btas::Tensor"); -static_assert(TiledArray::detail::is_btas_tensor_v> == false, "TA::Tensor is not a btas::Tensor"); +static_assert(TiledArray::detail::is_ta_tensor_v> == false, + "btas::Tensor is not a TA::Tensor"); +static_assert(TiledArray::detail::is_ta_tensor_v> == + true, + "TA::Tensor is a TA::Tensor"); +static_assert(TiledArray::detail::is_btas_tensor_v> == true, + "btas::Tensor is a btas::Tensor"); +static_assert(TiledArray::detail::is_btas_tensor_v> == + false, + "TA::Tensor is not a btas::Tensor"); // test both bare (deep-copy) BTAS tensor as well as its shallow-copy wrap in // Tile<>, using both btas::RangeNd<> and TiledArray::Range as the range type diff --git a/tests/dist_eval_contraction_eval.cpp b/tests/dist_eval_contraction_eval.cpp index 98d405d9a8..1c31328359 100644 --- a/tests/dist_eval_contraction_eval.cpp +++ b/tests/dist_eval_contraction_eval.cpp @@ -81,8 +81,9 @@ struct ContractionEvalFixture : public SparseShapeFixture { const unsigned int result_rank, const unsigned int left_rank, const unsigned int right_rank, const Permutation& perm = Permutation()) { return ContractReduce( - madness::cblas::NoTrans, madness::cblas::NoTrans, 1, result_rank, - left_rank, right_rank, perm); + TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, 1, result_rank, left_rank, + right_rank, perm); } static TiledArray::detail::UnaryWrapper > diff --git a/tests/linalg.cpp b/tests/linalg.cpp index d27ff9f554..b5c67e14fc 100644 --- a/tests/linalg.cpp +++ b/tests/linalg.cpp @@ -20,10 +20,10 @@ namespace non_dist = TA::math::linalg::non_distributed; #if TILEDARRAY_HAS_SCALAPACK namespace scalapack = TA::math::linalg::scalapack; #include "TiledArray/math/linalg/scalapack/all.h" -#define TILEDARRAY_SCALAPACK_TEST(F, E) \ - GlobalFixture::world->gop.fence(); \ +#define TILEDARRAY_SCALAPACK_TEST(F, E) \ + GlobalFixture::world->gop.fence(); \ compare("TiledArray::scalapack", non_dist::F, scalapack::F, E); \ - GlobalFixture::world->gop.fence(); \ + GlobalFixture::world->gop.fence(); \ compare("TiledArray", non_dist::F, TiledArray::F, E); #else #define TILEDARRAY_SCALAPACK_TEST(...) @@ -614,7 +614,7 @@ BOOST_AUTO_TEST_CASE(cholesky_linv_retl) { BOOST_CHECK_SMALL(norm, epsilon); - //TILEDARRAY_SCALAPACK_TEST(cholesky_linv(A), epsilon); + // TILEDARRAY_SCALAPACK_TEST(cholesky_linv(A), epsilon); GlobalFixture::world->gop.fence(); } @@ -668,13 +668,13 @@ BOOST_AUTO_TEST_CASE(cholesky_lsolve) { }); // Should produce X = L**H - auto [L, X] = non_dist::cholesky_lsolve(TA::TransposeFlag::NoTranspose, A, A); + auto [L, X] = non_dist::cholesky_lsolve(TA::NoTranspose, A, A); BOOST_CHECK(X.trange() == A.trange()); BOOST_CHECK(L.trange() == A.trange()); // first, test against NON_DIST auto [L_non_dist, X_non_dist] = - non_dist::cholesky_lsolve(TA::TransposeFlag::NoTranspose, A, A); + non_dist::cholesky_lsolve(TA::NoTranspose, A, A); decltype(L) L_error; L_error("i,j") = L("i,j") - L_non_dist("i,j"); BOOST_CHECK_SMALL(L_error("i,j").norm().get(), diff --git a/tests/math_blas.cpp b/tests/math_blas.cpp index 2b3182889f..0ae418f8ad 100644 --- a/tests/math_blas.cpp +++ b/tests/math_blas.cpp @@ -40,6 +40,7 @@ struct BlasFixture { first[i] = GlobalFixture::world->rand() % int(max); } + using integer = TiledArray::math::blas::integer; integer m, n, k; static const double tol; @@ -69,8 +70,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gemm, T, int_types) { // Test the gemm operation BOOST_REQUIRE_NO_THROW( - TiledArray::blas::gemm(madness::cblas::NoTrans, madness::cblas::NoTrans, - m, n, k, 3, a, lda, b, ldb, 0, c, ldc)); + TiledArray::math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, m, n, + k, 3, a, lda, b, ldb, 0, c, ldc)); for (integer i = 0; i < m; ++i) { for (integer j = 0; j < n; ++j) { @@ -119,8 +121,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(integral_gemm_ld, T, int_types) { // Test the gemm operation BOOST_REQUIRE_NO_THROW( - TiledArray::blas::gemm(madness::cblas::NoTrans, madness::cblas::NoTrans, - m, n, k, 3, a, lda, b, ldb, 0, c, ldc)); + TiledArray::math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, m, n, + k, 3, a, lda, b, ldb, 0, c, ldc)); for (integer i = 0; i < m; ++i) { for (integer j = 0; j < n; ++j) { @@ -168,8 +171,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(floating_point_gemm, T, floating_point_types) { // Test the gemm operation BOOST_REQUIRE_NO_THROW( - TiledArray::blas::gemm(madness::cblas::NoTrans, madness::cblas::NoTrans, - m, n, k, 3, a, lda, b, ldb, 0, c, ldc)); + TiledArray::math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, m, n, + k, 3, a, lda, b, ldb, 0, c, ldc)); for (integer i = 0; i < m; ++i) { for (integer j = 0; j < n; ++j) { // Compute the expected value @@ -216,8 +220,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(floating_point_gemm_ld, T, floating_point_types) { // Test the gemm operation BOOST_REQUIRE_NO_THROW( - TiledArray::blas::gemm(madness::cblas::NoTrans, madness::cblas::NoTrans, - m, n, k, 3, a, lda, b, ldb, 0, c, ldc)); + TiledArray::math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, m, n, + k, 3, a, lda, b, ldb, 0, c, ldc)); for (integer i = 0; i < m; ++i) { for (integer j = 0; j < n; ++j) { @@ -263,8 +268,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(complex_gemm, T, floating_point_types) { // Test the gemm operation BOOST_REQUIRE_NO_THROW( - TiledArray::blas::gemm(madness::cblas::NoTrans, madness::cblas::NoTrans, - m, n, k, 3, a, lda, b, ldb, 0, c, ldc)); + TiledArray::math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, m, n, + k, 3, a, lda, b, ldb, 0, c, ldc)); for (integer i = 0; i < m; ++i) { for (integer j = 0; j < n; ++j) { @@ -315,8 +321,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(complex_gemm_ld, T, floating_point_types) { // Test the gemm operation BOOST_REQUIRE_NO_THROW( - TiledArray::blas::gemm(madness::cblas::NoTrans, madness::cblas::NoTrans, - m, n, k, 3, a, lda, b, ldb, 0, c, ldc)); + TiledArray::math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, m, n, + k, 3, a, lda, b, ldb, 0, c, ldc)); for (integer i = 0; i < m; ++i) { for (integer j = 0; j < n; ++j) { diff --git a/tests/sparse_shape.cpp b/tests/sparse_shape.cpp index 5aa89c93d8..7be8c399e3 100644 --- a/tests/sparse_shape.cpp +++ b/tests/sparse_shape.cpp @@ -41,8 +41,8 @@ BOOST_AUTO_TEST_CASE(default_constructor) { BOOST_CHECK_NO_THROW(SparseShape x); SparseShape x, y; Permutation perm; - math::GemmHelper gemm_helper(madness::cblas::NoTrans, madness::cblas::NoTrans, - 2u, 2u, 2u); + math::GemmHelper gemm_helper(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, 2u, 2u, 2u); BOOST_CHECK(x.empty()); BOOST_CHECK(!x.is_dense()); @@ -1267,9 +1267,9 @@ BOOST_AUTO_TEST_CASE(gemm) { size_type zero_tile_count = 0ul; // Evaluate the contraction of sparse shapes - math::GemmHelper gemm_helper(madness::cblas::NoTrans, madness::cblas::NoTrans, - 2u, left.data().range().rank(), - right.data().range().rank()); + math::GemmHelper gemm_helper( + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::NoTrans, + 2u, left.data().range().rank(), right.data().range().rank()); SparseShape result; BOOST_REQUIRE_NO_THROW(result = left.gemm(right, -7.2, gemm_helper)); @@ -1326,9 +1326,9 @@ BOOST_AUTO_TEST_CASE(gemm_perm) { size_type zero_tile_count = 0ul; // Evaluate the contraction of sparse shapes - math::GemmHelper gemm_helper(madness::cblas::NoTrans, madness::cblas::NoTrans, - 2u, left.data().range().rank(), - right.data().range().rank()); + math::GemmHelper gemm_helper( + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::NoTrans, + 2u, left.data().range().rank(), right.data().range().rank()); SparseShape result; BOOST_REQUIRE_NO_THROW(result = left.gemm(right, -7.2, gemm_helper, perm)); diff --git a/tests/tensor.cpp b/tests/tensor.cpp index f8600053b5..dabdc6f934 100644 --- a/tests/tensor.cpp +++ b/tests/tensor.cpp @@ -499,6 +499,7 @@ BOOST_AUTO_TEST_CASE(binary_perm_op) { } BOOST_AUTO_TEST_CASE(gemm) { + using integer = TiledArray::math::blas::integer; TensorD x(r); rand_fill(431, x.size(), x.data()); TensorD y(r); @@ -509,9 +510,9 @@ BOOST_AUTO_TEST_CASE(gemm) { const auto ndim_free = r.rank() - ndim_contr; // this many leading modes will be free const auto alpha = 1.5; - const auto gemm_helper_nt = - math::GemmHelper(madness::cblas::NoTrans, madness::cblas::Trans, - 2 * ndim_free, x.range().rank(), y.range().rank()); + const auto gemm_helper_nt = math::GemmHelper( + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::Trans, + 2 * ndim_free, x.range().rank(), y.range().rank()); // check result-returning gemm TensorD z0; @@ -530,9 +531,10 @@ BOOST_AUTO_TEST_CASE(gemm) { { integer m = 1, n = 1, k = 1; gemm_helper_nt.compute_matrix_sizes(m, n, k, x.range(), y.range()); - madness::cblas::gemm(madness::cblas::Trans, madness::cblas::NoTrans, n, m, - k, alpha, y.data(), k, x.data(), k, 0, z0_ref.data(), - n); + math::blas::gemm(TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::Trans, + m, n, k, alpha, + x.data(), k, y.data(), k, 0, z0_ref.data(), n); } for (std::size_t i = 0ul; i < z0.size(); ++i) BOOST_CHECK_EQUAL(z0[i], z0_ref[i]); diff --git a/tests/tile_op_contract_reduce.cpp b/tests/tile_op_contract_reduce.cpp index 76d09ca6eb..5c30a5b491 100644 --- a/tests/tile_op_contract_reduce.cpp +++ b/tests/tile_op_contract_reduce.cpp @@ -81,13 +81,15 @@ BOOST_FIXTURE_TEST_SUITE(tile_op_contract_reduce_suite, ContractReduceFixture, BOOST_AUTO_TEST_CASE(constructor) { BOOST_REQUIRE_NO_THROW((ContractReduce( - madness::cblas::NoTrans, madness::cblas::NoTrans, 1, 2u, 2u, 2u))); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::NoTrans, + 1, 2u, 2u, 2u))); } BOOST_AUTO_TEST_CASE(make_result) { // Check the seed operation produces an empty tensor. ContractReduce op( - madness::cblas::NoTrans, madness::cblas::NoTrans, 1, 2u, 2u, 2u); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::NoTrans, + 1, 2u, 2u, 2u); TensorI result; BOOST_REQUIRE_NO_THROW(result = op()); BOOST_CHECK(result.empty()); @@ -96,7 +98,8 @@ BOOST_AUTO_TEST_CASE(make_result) { BOOST_AUTO_TEST_CASE(permute_empty) { // Check the seed operation produces an empty tensor. ContractReduce op( - madness::cblas::NoTrans, madness::cblas::NoTrans, 1, 2u, 2u, 2u); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::NoTrans, + 1, 2u, 2u, 2u); TensorI t, result; BOOST_REQUIRE_THROW(result = op(t), TiledArray::Exception); } @@ -133,7 +136,8 @@ BOOST_AUTO_TEST_CASE(matrix_multiply) { // Test NoTrans, NoTrans { ContractReduce op( - madness::cblas::NoTrans, madness::cblas::NoTrans, 3, 2u, 2u, 2u); + TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, 3, 2u, 2u, 2u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, left, right)); @@ -149,7 +153,8 @@ BOOST_AUTO_TEST_CASE(matrix_multiply) { // Test Trans, NoTrans { ContractReduce op( - madness::cblas::Trans, madness::cblas::NoTrans, 3, 2u, 2u, 2u); + TiledArray::math::blas::Op::Trans, TiledArray::math::blas::Op::NoTrans, + 3, 2u, 2u, 2u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, leftT, right)); @@ -171,7 +176,8 @@ BOOST_AUTO_TEST_CASE(matrix_multiply) { // Test NoTrans, Trans { ContractReduce op( - madness::cblas::NoTrans, madness::cblas::Trans, 3, 2u, 2u, 2u); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::Trans, + 3, 2u, 2u, 2u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, left, rightT)); @@ -193,7 +199,8 @@ BOOST_AUTO_TEST_CASE(matrix_multiply) { // Test Trans, Trans { ContractReduce op( - madness::cblas::Trans, madness::cblas::Trans, 3, 2u, 2u, 2u); + TiledArray::math::blas::Op::Trans, TiledArray::math::blas::Op::Trans, 3, + 2u, 2u, 2u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, leftT, rightT)); @@ -245,7 +252,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract1) { // Test NoTrans, NoTrans { ContractReduce op( - madness::cblas::NoTrans, madness::cblas::NoTrans, 3, 2u, 3u, 3u); + TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, 3, 2u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, left, right)); @@ -269,7 +277,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract1) { // Test Trans, NoTrans { ContractReduce op( - madness::cblas::Trans, madness::cblas::NoTrans, 3, 2u, 3u, 3u); + TiledArray::math::blas::Op::Trans, TiledArray::math::blas::Op::NoTrans, + 3, 2u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, leftT, right)); @@ -291,7 +300,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract1) { // Test NoTrans, Trans { ContractReduce op( - madness::cblas::NoTrans, madness::cblas::Trans, 3, 2u, 3u, 3u); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::Trans, + 3, 2u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, left, rightT)); @@ -313,7 +323,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract1) { // Test Trans, Trans { ContractReduce op( - madness::cblas::Trans, madness::cblas::Trans, 3, 2u, 3u, 3u); + TiledArray::math::blas::Op::Trans, TiledArray::math::blas::Op::Trans, 3, + 2u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, leftT, rightT)); @@ -370,7 +381,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract2) { // Test NoTrans, NoTrans { ContractReduce op( - madness::cblas::NoTrans, madness::cblas::NoTrans, 3, 4u, 3u, 3u); + TiledArray::math::blas::Op::NoTrans, + TiledArray::math::blas::Op::NoTrans, 3, 4u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, left, right)); @@ -404,7 +416,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract2) { // Test Trans, NoTrans { ContractReduce op( - madness::cblas::Trans, madness::cblas::NoTrans, 3, 4u, 3u, 3u); + TiledArray::math::blas::Op::Trans, TiledArray::math::blas::Op::NoTrans, + 3, 4u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, leftT, right)); @@ -436,7 +449,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract2) { // Test NoTrans, Trans { ContractReduce op( - madness::cblas::NoTrans, madness::cblas::Trans, 3, 4u, 3u, 3u); + TiledArray::math::blas::Op::NoTrans, TiledArray::math::blas::Op::Trans, + 3, 4u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, left, rightT)); @@ -468,7 +482,8 @@ BOOST_AUTO_TEST_CASE(tensor_contract2) { // Test Trans, Trans { ContractReduce op( - madness::cblas::Trans, madness::cblas::Trans, 3, 4u, 3u, 3u); + TiledArray::math::blas::Op::Trans, TiledArray::math::blas::Op::Trans, 3, + 4u, 3u, 3u); // Do contraction operation BOOST_REQUIRE_NO_THROW(op(result, leftT, rightT)); diff --git a/tests/tot_array_fixture.h b/tests/tot_array_fixture.h index 592d80bc7a..45a0ae0f8e 100644 --- a/tests/tot_array_fixture.h +++ b/tests/tot_array_fixture.h @@ -39,15 +39,15 @@ using namespace TiledArray; // These are all of the template parameters we are going to test over -using test_params = boost::mpl::list< - std::tuple>>, - std::tuple>>, - std::tuple>> +using test_params = + boost::mpl::list>>, + std::tuple>>, + std::tuple>> #ifdef TILEDARRAY_HAS_BTAS - , - std::tuple>>, - std::tuple>>, - std::tuple>> + , + std::tuple>>, + std::tuple>>, + std::tuple>> // ,std::tuple, Range>>, // std::tuple, Range>>, // std::tuple, Range>> @@ -55,7 +55,7 @@ using test_params = boost::mpl::list< // std::tuple, Range>>>, // std::tuple, Range>>> #endif - >; + >; // These typedefs unpack the unit test template parameter //{ @@ -275,6 +275,7 @@ struct ToTArrayFixture { lhs.world().gop.fence(); return are_same; } + abort(); // unreachable } // The world to use for the test suite madness::World& m_world; diff --git a/tests/tot_expressions.cpp b/tests/tot_expressions.cpp index 2256aaf423..1c7feb11b7 100644 --- a/tests/tot_expressions.cpp +++ b/tests/tot_expressions.cpp @@ -1,5 +1,22 @@ #include "tot_array_fixture.h" +template +std::enable_if_t, Tensor> +make_tensor(typename Tensor::range_type&& range, ElementGenerator&& op) { + Tensor result(std::move(range)); + result.generate(std::forward(op)); + return result; +} + +template +std::enable_if_t, Tensor> +make_tensor(typename Tensor::range_type&& range, ElementGenerator&& op) { + Tensor result(std::move(range)); + std::generate(result.begin(), result.end(), + std::forward(op)); + return result; +} + //------------------------------------------------------------------------------ // Permutations //------------------------------------------------------------------------------ @@ -4230,8 +4247,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(mom_outer_inner_contraction, TestParam, test_params) { using inner_type = inner_type; using element_type = typename inner_type::value_type; - // only support btas Tensors as inner tensors - if constexpr (detail::is_ta_tensor_v) return; using trange_type = TiledRange; trange_type tr{{0, 2, 3, 5, 7}, {0, 3, 5, 7, 11}}; @@ -4240,15 +4255,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(mom_outer_inner_contraction, TestParam, int x = 0; // N.B. to be able to contract for multiple outer index combinations // make all inner tensors same size - auto result = inner_type(range_type(3, 5)); - if constexpr (TiledArray::detail::is_ta_tensor_v) { - // abort(); - } else if constexpr (TiledArray::detail::is_btas_tensor_v) { - result.generate([&x]() { return x++; }); - } else { - abort(); // unknown type - } - return result; + return make_tensor(range_type(3, 5), [&x]() { return x++; }); }; static_assert(TiledArray::detail::is_tensor_of_tensor_v>, @@ -4263,8 +4270,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(mom_outer_inner_contraction, TestParam, BOOST_AUTO_TEST_CASE_TEMPLATE(mom_inner_contraction, TestParam, test_params) { using inner_type = inner_type; - // only support btas Tensors as inner tensors - if constexpr (detail::is_ta_tensor_v) return; using element_type = typename inner_type::value_type; // detail::type_printer x; // detail::type_printer y; @@ -4274,15 +4279,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(mom_inner_contraction, TestParam, test_params) { auto init_inner_tensor = [](const auto& elem_idx) { using range_type = typename inner_type::range_type; int x = 0; - auto result = inner_type(range_type(elem_idx[0] + 1, elem_idx[0] + 2)); - if constexpr (TiledArray::detail::is_ta_tensor_v) { - // abort(); - } else if constexpr (TiledArray::detail::is_btas_tensor_v) { - result.generate([&x]() { return x++; }); - } else { - abort(); // unknown type - } - return result; + return make_tensor(range_type(elem_idx[0] + 1, elem_idx[0] + 2), + [&x]() { return x++; }); }; static_assert(TiledArray::detail::is_tensor_of_tensor_v>, @@ -4298,8 +4296,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(mom_inner_contraction, TestParam, test_params) { BOOST_AUTO_TEST_CASE_TEMPLATE(mom_outer_contraction, TestParam, test_params) { using inner_type = inner_type; using element_type = typename inner_type::value_type; - // only support btas Tensors as inner tensors - if constexpr (detail::is_ta_tensor_v) return; using trange_type = TiledRange; trange_type tr{{0, 2, 3, 5, 7}, {0, 3, 5, 7, 11}}; @@ -4308,15 +4304,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(mom_outer_contraction, TestParam, test_params) { int x = 0; // N.B. to be able to contract for multiple outer index combinations // make all inner tensors same size - auto result = inner_type(range_type(3, 5)); - if constexpr (TiledArray::detail::is_ta_tensor_v) { - // abort(); - } else if constexpr (TiledArray::detail::is_btas_tensor_v) { - result.generate([&x]() { return x++; }); - } else { - abort(); // unknown type - } - return result; + return make_tensor(range_type(3, 5), [&x]() { return x++; }); }; static_assert(TiledArray::detail::is_tensor_of_tensor_v>,