diff --git a/.gitignore b/.gitignore index 30fbd8f48..01095f2cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,22 @@ -*.e -*.o -*.so +# Python __pycache__ .python-version -/build* -.cache/ + +# CMake +CMakeUserPresets.json + +# Visual Studio Code .vscode/ + +# this project +build/ Testing/ + +# need to be cleaned up +.cache/ *.swp *.swo dev_test +*.e +*.o +*.so diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e2111576..d99fc2fc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,20 +72,106 @@ FILE(APPEND "${CMAKE_BINARY_DIR}/vinfo.tmp" "${CYTNX_VARIANT_INFO}" "") # ##################################################################### # ## COMMAND LINE OPTIONS # ##################################################################### -option(BACKEND_TORCH "Build Cytnx with pytorch backend (requires pytorch)" OFF) -# # the following are only referenced when BACKEND_TORCH=OFF -option(USE_CUDA "Build using Nvidia CUDA for GPU library" OFF) -option(BUILD_PYTHON "Build Python wrapper" ON) -option(USE_MKL "Build using MKL" ON) -option(BUILD_DOC "Build API docuemntation" OFF) -option(USE_HPTT "Build Cytnx with HPTT" OFF) +# ----------------------------------------------------------------------------- +# :Function: require_dependent_variable +# +# :Description: +# Conditionally creates or validates a cache variable based on a set of +# dependency conditions. +# +# The dependency conditions are provided in the *depends* parameter as a +# semicolon-separated list. The cache variable is required only when all +# these conditions evaluate to true. +# +# :Parameters: +# - **variable**: The name of the variable to set. +# - **default**: The default value for the variable. +# - **type**: The cache type (e.g., STRING, PATH) for the variable. +# - **help**: A descriptive help message for the variable. +# - **depends**: A semicolon-separated list of dependency conditions. +# The variable is required only if all conditions are met. +# +# :Behavior: +# - Evaluates each dependency condition; if any condition evaluates to false, +# will not update the variable. +# - If all conditions are met and the variable is not already defined, the +# variable is set to the provided default value in the cache using the +# specified type and help message. +# - If the variable’s value is empty, a fatal error is raised. +# +# :Examples: +# +# .. code-block:: cmake +# +# require_dependent_variable( +# PACKAGE_INCLUDE_DIRS +# "$ENV{PACKAGE_INCLUDE_DIRS}" +# PATH +# "Path to the include directory of the package." +# "USE_A AND (USE_B OR USE_C);USE_D" +# ) +# +# In this example, if "USE_A AND (USE_B OR USE_C);USE_D" is true, then +# PACKAGE_INCLUDE_DIRS must be defined and non-empty. Otherwise, a fatal error +# is raised. +# ----------------------------------------------------------------------------- +function(require_dependent_variable variable default type help depends) + # Evaluate each dependency condition; if any condition is false, exit early. + # This is copied from the source code of `cmake_dependent_option` function. + set(IS_NOT_AVAILABLE 0) + foreach(d ${depends}) + cmake_language(EVAL CODE " + if (${d}) + else() + set(IS_NOT_AVAILABLE 1) + endif()" + ) + endforeach() + if(IS_NOT_AVAILABLE) + return() + endif() + + if(NOT DEFINED ${variable}) + set(${variable} "${default}" CACHE ${type} "${help}") + endif() + + if("${${variable}}" STREQUAL "") + message(FATAL_ERROR "\ +Error: Cache variable '${variable}' is required under dependency conditions \ +(${depends}) but its value is empty. +${help} +") + endif() +endfunction() + +include(CMakeDependentOption) + +set(CMAKE_INSTALL_PREFIX "/usr/local/cytnx" CACHE PATH "the destination path for installation") +option(BUILD_PYTHON "Build Python API. Require Python and pybind11 installed." ON) +option(BACKEND_TORCH "Use PyTorch as a backend container for tensors." OFF) +cmake_dependent_option(USE_MKL "Use MKL as a BLAS provider otherwise use OpenBLAS." OFF "NOT BACKEND_TORCH" OFF) +cmake_dependent_option(USE_HPTT "Use HPTT library to accelrate tensor transpose." OFF "NOT BACKEND_TORCH" OFF) +cmake_dependent_option(HPTT_ENABLE_FINE_TUNE "Enable fine tune HPTT for the native hardware." OFF "USE_HPTT" OFF) +# TODO: use variable instead of option to handle HPTT variant. +cmake_dependent_option(HPTT_ENABLE_ARM "HPTT variant" OFF "USE_HPTT;NOT HPTT_ENABLE_AVX; NOT HPTT_ENABLE_IBM" OFF) +cmake_dependent_option(HPTT_ENABLE_AVX "HPTT variant" OFF "USE_HPTT;NOT HPTT_ENABLE_ARM; NOT HPTT_ENABLE_IBM" OFF) +cmake_dependent_option(HPTT_ENABLE_IBM "HPTT variant" OFF "USE_HPTT;NOT HPTT_ENABLE_ARM; NOT HPTT_ENABLE_AVX" OFF) +cmake_dependent_option(USE_CUDA "Enable CUDA support." OFF "NOT BACKEND_TORCH" OFF) +cmake_dependent_option(USE_CUTT "Use CUTT library to accelrate tensor transpose." OFF "USE_CUDA" OFF) +cmake_dependent_option(CUTT_ENABLE_FINE_TUNE "Enable CUTT fine tune for the native hardware." OFF "USE_CUTT" OFF) +cmake_dependent_option(USE_CUTENSOR "Enable cuTENSOR." OFF "USE_CUDA" OFF) +require_dependent_variable(CUTENSOR_ROOT "$ENV{CUTENSOR_ROOT}" PATH +"Please provide CUTENSOR_ROOT in the environment variables. +CUTENSOR_ROOT is the path to the folder of cuTENSOR." "USE_CUTENSOR") +cmake_dependent_option(USE_CUQUANTUM "Enable cuQuantum." OFF "USE_CUDA" OFF) +require_dependent_variable(CUQUANTUM_ROOT "$ENV{CUQUANTUM_ROOT}" PATH +"Please provide CUQUANTUM_ROOT in the environment variables. +CUQUANTUM_ROOT is the path to the folder of cuQuantum." "USE_CUQUANTUM") option(RUN_TESTS "Run Cytnx tests" OFF) option(RUN_BENCHMARKS "Run Cytnx benchmarks" OFF) -option(USE_CUTT "Build Cytnx with CUTT" OFF) -option(USE_CUTENSOR "Build Cytnx with CuTensor (requires CUDA)" ON) -option(USE_CUQUANTUM "Build Cytnx with CUQuantum (requires CUDA)" ON) - +option(USE_DEBUG "Build in debug more and enable address sanitizer" OFF) +option(BUILD_DOC "Build API docuemntation" OFF) option(DEV_MODE "Build testing dev_test.cpp with cytnx" OFF) # ##################################################################### diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..a1934a102 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,170 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "configurePresets": [ + { + "name": "default", + "displayName": "openblas-cpu", + "description": "OpenBLAS as the BLAS vendor with CPU-only support.", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/${presetName}/libcytnx", + "CMAKE_EXPORT_COMPILE_COMMANDS": "OFF", + "USE_MKL": "OFF", + "BUILD_PYTHON": "ON", + "BACKEND_TORCH": "OFF", + "USE_HPTT": "ON", + "HPTT_ENABLE_FINE_TUNE": "ON", + "USE_CUDA": "OFF", + "RUN_TESTS": "OFF", + "RUN_BENCHMARKS": "OFF", + "USE_DEBUG": "OFF", + "BUILD_DOC": "OFF", + "DEV_MODE": "OFF" + } + }, + { + "name": "mkl", + "hidden": true, + "description": "A base preset overriding OpenBLAS variables with MKL variables.", + "cacheVariables": { + "USE_MKL": "ON" + } + }, + { + "name": "mkl-cpu", + "displayName": "mkl-cpu", + "description": "Intel MKL as the BLAS vendor with CPU-only support.", + "inherits": ["mkl", "default"] + }, + { + "name": "openblas-cuda", + "displayName": "openblas-cuda", + "description": "OpenBLAS as the BLAS vendor with CUDA support.", + "inherits": "default", + "cacheVariables": { + "USE_CUDA": "ON", + "USE_CUTT": "ON", + "CUTT_ENABLE_FINE_TUNE": "ON", + "USE_CUTENSOR": "ON", + "USE_CUQUANTUM": "ON" + } + }, + { + "name": "mkl-cuda", + "displayName": "mkl-cuda", + "description": "Intel MKL as the BLAS vendor with CUDA support.", + "inherits": ["mkl", "openblas-cuda"] + }, + { + "name": "debug", + "hidden": true, + "description": "A base preset overriding release variables with debug variables.", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "USE_DEBUG": "ON", + "RUN_TESTS": "ON", + "RUN_BENCHMARKS": "OFF", + "BUILD_DOC": "OFF", + "DEV_MODE": "OFF" + } + }, + { + "name": "debug-openblas-cpu", + "displayName": "debug-openblas-cpu", + "description": "Debug build: OpenBLAS as the BLAS vendor with CPU-only support.", + "inherits": ["debug", "default"] + }, + { + "name": "debug-mkl-cpu", + "displayName": "debug-mkl-cpu", + "description": "Debug build: Intel MKL as the BLAS vendor with CPU-only support.", + "inherits": ["debug", "mkl-cpu"] + }, + { + "name": "debug-openblas-cuda", + "displayName": "debug-openblas-cuda", + "description": "Debug build: OpenBLAS as the BLAS vendor with CUDA support.", + "inherits": ["debug", "openblas-cuda"] + }, + { + "name": "debug-mkl-cuda", + "displayName": "debug-mkl-cuda", + "description": "Debug build: Intel MKL as the BLAS vendor with CUDA support.", + "inherits": ["debug", "mkl-cuda"] + } + ], + "buildPresets": [ + { + "name": "default", + "displayName": "openblas-cpu", + "description": "Build using OpenBLAS with CPU-only support.", + "configurePreset": "default", + "targets": ["all", "install"], + "jobs": 8 + }, + { + "name": "openblas-cuda", + "description": "Build using OpenBLAS with CUDA support.", + "configurePreset": "openblas-cuda", + "inherits": "default" + }, + { + "name": "mkl-cuda", + "description": "Build using Intel MKL with CUDA support.", + "configurePreset": "mkl-cuda", + "inherits": "default" + }, + { + "name": "debug-openblas-cpu", + "description": "Debug build using OpenBLAS with CPU-only support.", + "configurePreset": "debug", + "inherits": "default" + }, + { + "name": "debug-mkl-cpu", + "description": "Debug build using Intel MKL with CPU-only support.", + "configurePreset": "debug-mkl-cpu", + "inherits": "default" + }, + { + "name": "debug-openblas-cuda", + "description": "Debug build using OpenBLAS with CUDA support.", + "configurePreset": "debug-openblas-cuda", + "inherits": "default" + }, + { + "name": "debug-mkl-cuda", + "description": "Debug build using Intel MKL with CUDA support.", + "configurePreset": "debug-mkl-cuda", + "inherits": "default" + } + ], + "testPresets": [ + { + "name": "default", + "displayName": "cpu-only", + "description": "Run tests for CPU-only builds.", + "configurePreset": "debug", + "output": { + "outputOnFailure": true, + "verbosity": "verbose" + }, + "execution": { + "jobs": 8 + } + }, + { + "name": "cpu-and-cuda", + "description": "Run tests for builds with CUDA support.", + "configurePreset": "debug-openblas-cuda", + "inherits": "default" + } + ] +} diff --git a/Install.sh b/Install.sh deleted file mode 100755 index fc9b13440..000000000 --- a/Install.sh +++ /dev/null @@ -1,196 +0,0 @@ -#========================================================= -## 1) Custom install destination (DEFAULT /usr/local/cytnx) -#========================================================= -# [Note] Set the destination path for installation in Ins_dest -#---------------------------------------------- -Ins_dest="/usr/local/cytnx" -FLAG="${FLAG} -DCMAKE_INSTALL_PREFIX=${Ins_dest}" -#----------------------------------------------- - -#================================================================= -# 2) linalg libs: -#================================================================= -# [Note] we have two choice: OpenBLAS or MKL (choose either one!) -# uncomments either a) or b) for the one you wish to use. -#--------------------------- -# 2-a) use MKL (DEFAULT = OFF): -# [Note] if using mkl, uncomments the following line and -# Please follow the guide from official mkl/oneMKL "post-installation" part -# to source the proper setvars.sh and/or vars.sh -#--------------------------- -FLAG="${FLAG} -DUSE_MKL=OFF" -#--------------------------- -# 2-b) use OpenBLAS (DEFAULT = on (by settung DUSE_MKL=OFF above)) -# [Note] By default it will automatically find openblas installed -# In case of cmake cannot find the BLAS, uncomments the following lines -# and set the BLAS_ROOT: -#--------------------------- -#BLASROOT=/deps/OpenBLAS -#export C_INCLUDE_PATH=${BLASROOT}/include -#export CPLUS_INCLUDE_PATH=${BLASROOT}/include -#export LD_LIBRARY_PATH=${BLASROOT}/lib -#--------------------------- - - -#============================================================================ -# 3) use python (DEFAULT = ON) -#============================================================================ -# set to "=on" for building python API, required python and pybind11 installed. -#-------------------------------- -FLAG="${FLAG} -DBUILD_PYTHON=ON" -#-------------------------------- - - -#================================================================= -# 4) torch backend (DEFAULT = OFF): -#================================================================= -# [Note] if set to ON, torch will be used as a backend container -# for tensors. This allows to use automatic differentiatio -#-------------------------------- -FLAG="${FLAG} -DBACKEND_TORCH=OFF" -#-------------------------------- - - -#========================================================= -# 5) Boost: -#========================================================= -# [Note] by default, it will automatically find system installed boost. -# In case boost cannot be found automatically, uncomment the following line, -# and set the boost path manually. -#----------------------------------- -#BOOST_ROOT=/deps/BOOST -#FLAG="${FLAG} -DBOOSTROOT=${BOOST_ROOT}" -#----------------------------------- - - -#========================================================= -# 6) HPTT (DEFAULT = OFF): -#========================================================= -# [Note] set to "=on" for using hptt library to accelrate tensor transpose. -# for "=off" case one can skip 5-a) and 5-b) -#----------------------------------- -FLAG="${FLAG} -DUSE_HPTT=OFF" -#----------------------------------- -# 6-a) HPTT fine tune (DEFAULT = OFF) -# [Note] set to "=on" to enable fine tune for the native hardware. -#----------------------------------- -FLAG="${FLAG} -DHPTT_ENABLE_FINE_TUNE=OFF" -#----------------------------------- -# 6-b) HPTT variant options (DEFAULT = no option) -# [Note] uncomment one of the desired options below 1: AVX 2: IBM 3: ARM. -#----------------------------------- -#FLAG="${FLAG} -DHPTT_ENABLE_ARM=ON" -#FLAG="${FLAG} -DHPTT_ENABLE_AVX=ON" -#FLAG="${FLAG} -DHPTT_ENABLE_IBM=ON" -#----------------------------------- - - -#========================================================= -# 7) CUDA (DEFAULT = OFF): -#========================================================= -# [Note] set to "=on" to build with with GPU (CUDA) support. -# for "=off" case one can skip 6-a) and 6-b) -#----------------------------------- -FLAG="${FLAG} -DUSE_CUDA=OFF" -#----------------------------------- -# 7-a) CUTT (DEFAULT = OFF) -# [Note] set to "=on" for using CUTT library to accelrate tensor transpose. -# for "=off" case one can skip 6-b) -#----------------------------------- -FLAG="${FLAG} -DUSE_CUTT=OFF" -#----------------------------------- -# 7-b) CUTT fine tune (DEFAULT = OFF) -# [Note] set to "=on" to enable fine tune for the native hardware. -#----------------------------------- -FLAG="${FLAG} -DCUTT_ENABLE_FINE_TUNE=OFF" -#----------------------------------- -# 7-c) CuTensor (DEFAULT = OFF) -# [Note] set to "=off" will make permutation on GPU into using cutt library. -# [Note] CUTENSOR_ROOT is required to given, either from enviroment variable in bashrc -# or given in the following line using -DCUTENSOR_ROOT -FLAG="${FLAG} -DUSE_CUTENSOR=OFF" -#CUTENSOR_ROOT=/usr/local/libcutensor-... -#FLAG="${FLAG} -DCUTENSOR_ROOT=${CUTENSOR_ROOT}" -#----------------------------------- -# 7-d) CuQuantum (DEFAULT = OFF) -# [Note] CUQUANTUM_ROOT is required to given, either from enviroment variable in bashrc -# or given in the following line using -DCUTENSOR_ROOT -FLAG="${FLAG} -DUSE_CUQUANTUM=OFF" -# CUQUANTUM_ROOT=/usr/local/cuqunatum-...... -#FLAG="${FLAG} -DCUQUANTUM_ROOT=${CUQUANTUM_ROOT}" -#----------------------------------- - - -#========================================================= -# 8) Generate compile_commands.json -#========================================================= -# [Note] Wheather to generate compile_commands.json for IDE support (DEFAULT = 1) -#----------------------------------- -FLAG="${FLAG} -DCMAKE_EXPORT_COMPILE_COMMANDS=1" -#----------------------------------- - - -#========================================================= -# 9) Use openmp to accelerate -#========================================================= -# [Note] This will run the threaded code in cytnx lib while it will not disable muiltithreading in mkl. (DEFAULT = OFF) -#----------------------------------- -FLAG="${FLAG} -DUSE_OMP=OFF" -#----------------------------------- - - -#========================================================= -# 10) Run tests and benchmarks -#========================================================= -# [Note] Wheather to run cytnx tests (DEFAULT = OFF) and benchmarks (DEFAULT = OFF) -#----------------------------------- -DRUN_TESTS=OFF -FLAG="${FLAG} -DRUN_TESTS=${DRUN_TESTS}" -FLAG="${FLAG} -DRUN_BENCHMARKS=OFF " -#----------------------------------- - - -#========================================================= -# 11) Use icpc -#========================================================= -# [Note] Build using intel icpc compiler, uncomment to enable (DEFAULT = OFF (commented out)) -#----------------------------------- -#FLAG="${FLAG} -DUSE_ICPC=ON " # You should set this to ON if you want to use icpc -# This option is needed if you want to use icpc, to set the compiler -# Although icc&icpc is deprecated, but since icx&icpx has poor support for conda environment, we still use icpc -#FLAG="${FLAG} -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc" -# This option is to use the intel compiler's ar and linker, which is optional -#FLAG = "${FLAG} -DCMAKE_AR=xiar -DCMAKE_LINKER=xild" -#----------------------------------- - - -#========================================================= -# 12) Use Debug -#========================================================= -# [Note] Build using debug mode (DEFAULT = OFF) -#----------------------------------- -FLAG="${FLAG} -DUSE_DEBUG=OFF" -# This is for compile with -fsanitize=address and cuda, -# if you use the DEBUG flag above, you need to export ASAN_OPTIONS=protect_shadow_gap=0 -# export ASAN_OPTIONS=protect_shadow_gap=0 -# Just a note: export ASAN_OPTIONS=protect_shadow_gap=0:replace_intrin=0:detect_leaks=0 -#----------------------------------- - - -#========================================================= -# Build commands -#========================================================= -echo ${FLAG} -rm -rf build -mkdir build -cd build -cmake ../ ${FLAG} #-DDEV_MODE=on -make -j`nproc` -make install -# if DRUN_TESTS=ON, run tests -# ctest -# shopt -s nocasematch -# case "${DRUN_TESTS}" in -# "ON" ) ctest; gcovr -r ../ . --html-details cov.html;; -# *) echo "Tests are skipped";; -# esac