diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e822d1..b3428ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,68 @@ if (CUDAQX_INCLUDE_TESTS) endif() endif() +# Hooks setup. If the repo contains a custom pre-push hook, attempt to install +# it. If the user has a different one installed, then warn them but do not fail +# configuration. +# ============================================================================== + +# Define the directory where your hooks are stored +set(SRC_HOOK_PRE_PUSH "${CMAKE_SOURCE_DIR}/.githooks/pre-push") + +if(EXISTS "${SRC_HOOK_PRE_PUSH}") + # Get the Git hooks directory from the Git configuration + execute_process( + COMMAND git config --get core.hooksPath + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE GIT_HOOKS_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Determine the target hooks directory + if(GIT_HOOKS_DIR) + set(TARGET_HOOKS_DIR "${GIT_HOOKS_DIR}") + else() + set(TARGET_HOOKS_DIR "${CMAKE_SOURCE_DIR}/.git/hooks") + endif() + set(DST_HOOK_PRE_PUSH "${TARGET_HOOKS_DIR}/pre-push") + + if(EXISTS "${DST_HOOK_PRE_PUSH}") + # Compare the contents of the src and dst hook. + execute_process( + COMMAND git hash-object "${DST_HOOK_PRE_PUSH}" + OUTPUT_VARIABLE SHA_DST + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + execute_process( + COMMAND git hash-object "${SRC_HOOK_PRE_PUSH}" + OUTPUT_VARIABLE SHA_SRC + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT SHA_SRC STREQUAL SHA_DST) + message(WARNING + "You already have a ${DST_HOOK_PRE_PUSH} script installed. " + "This configuration script will not overwrite it despite the fact that " + "it is strongly recommended to use ${SRC_HOOK_PRE_PUSH} in your environment." + "\nProceed with caution!") + endif() + else() + if(EXISTS "${TARGET_HOOKS_DIR}") + file(COPY "${SRC_HOOK_PRE_PUSH}" + DESTINATION "${TARGET_HOOKS_DIR}" + FILE_PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) + message(STATUS "Git pre-push hook installed to ${TARGET_HOOKS_DIR}") + else() + message(WARNING + "The Git hooks directory does not exist: ${TARGET_HOOKS_DIR}\n" + "Are you sure this is a Git repository? Hook cannot be installed." + ) + endif() + endif() +endif() + # Directory setup # ============================================================================== diff --git a/docs/sphinx/quickstart/installation.rst b/docs/sphinx/quickstart/installation.rst index 75cc26b..9f2f32c 100644 --- a/docs/sphinx/quickstart/installation.rst +++ b/docs/sphinx/quickstart/installation.rst @@ -22,6 +22,14 @@ The simplest way to install CUDA-QX is via pip. You can install individual compo # Install both libraries pip install cudaq-qec cudaq-solvers +.. note:: + + CUDA-Q Solvers will require the presence of :code:`libgfortran`, which is + not distributed with the Python wheel, for provided classical optimizers. If + :code:`libgfortran` is not installed, you will need to install it via your + distribution's package manager. On Debian based systems, you can install + this with :code:`apt-get install gfortran`. + Docker Container ^^^^^^^^^^^^^^^^ diff --git a/libs/qec/CMakeLists.txt b/libs/qec/CMakeLists.txt index 68b3ad7..4b5969a 100644 --- a/libs/qec/CMakeLists.txt +++ b/libs/qec/CMakeLists.txt @@ -6,7 +6,7 @@ # the terms of the Apache License 2.0 which accompanies this distribution. # # ============================================================================ # -# Requering the same version as the others. +# Requiring the same version as the others. cmake_minimum_required(VERSION 3.28 FATAL_ERROR) # Project setup @@ -52,6 +52,44 @@ option(CUDAQX_QEC_INSTALL_PYTHON "Install python files alongside the library." ${CUDAQX_INSTALL_PYTHON}) +# Check for CUDA Support (ref: cuda-quantum/CMakeLists.txt) +# ============================================================================== +include(CheckLanguage) +check_language(CUDA) +set(CUDA_FOUND FALSE) +# Generate -gencode arch=compute_XX,code=sm_XX for list of supported +# arch values. +# List should be sorted in increasing order. +function(CUDA_get_gencode_args out_args_string arch_values) + # allow the user to pass the list like a normal variable + set(arch_list ${arch_values} ${ARGN}) + set(out "") + foreach(arch IN LISTS arch_list) + set(out "${out} -gencode arch=compute_${arch},code=sm_${arch}") + endforeach(arch) + + # Repeat the last one as to ensure the generation of PTX for most + # recent virtual architecture for forward compatibility + list(GET arch_list -1 last_arch) + set(out "${out} -gencode arch=compute_${last_arch},code=compute_${last_arch}") + set(${out_args_string} ${out} PARENT_SCOPE) +endfunction() + +if(CMAKE_CUDA_COMPILER) + if (NOT CUDA_TARGET_ARCHS) + # Volta, Ampere, Hopper + set(CUDA_TARGET_ARCHS "70;80;90") + endif() + CUDA_get_gencode_args(CUDA_gencode_flags ${CUDA_TARGET_ARCHS}) + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -shared -std=c++17 ${CUDA_gencode_flags} --compiler-options -fPIC") + + enable_language(CUDA) + set(CUDA_FOUND TRUE) + set(CMAKE_CUDA_STANDARD 17) + set(CMAKE_CUDA_STANDARD_REQUIRED TRUE) + message(STATUS "Cuda language found.") +endif() + # External Dependencies # ============================================================================== diff --git a/libs/solvers/CMakeLists.txt b/libs/solvers/CMakeLists.txt index 4d265bc..d001fd1 100644 --- a/libs/solvers/CMakeLists.txt +++ b/libs/solvers/CMakeLists.txt @@ -63,6 +63,44 @@ option(CUDAQX_SOLVERS_INSTALL_PYTHON "Install python files alongside the library." ${CUDAQX_INSTALL_PYTHON}) +# Check for CUDA Support (ref: cuda-quantum/CMakeLists.txt) +# ============================================================================== +include(CheckLanguage) +check_language(CUDA) +set(CUDA_FOUND FALSE) +# Generate -gencode arch=compute_XX,code=sm_XX for list of supported +# arch values. +# List should be sorted in increasing order. +function(CUDA_get_gencode_args out_args_string arch_values) + # allow the user to pass the list like a normal variable + set(arch_list ${arch_values} ${ARGN}) + set(out "") + foreach(arch IN LISTS arch_list) + set(out "${out} -gencode arch=compute_${arch},code=sm_${arch}") + endforeach(arch) + + # Repeat the last one as to ensure the generation of PTX for most + # recent virtual architecture for forward compatibility + list(GET arch_list -1 last_arch) + set(out "${out} -gencode arch=compute_${last_arch},code=compute_${last_arch}") + set(${out_args_string} ${out} PARENT_SCOPE) +endfunction() + +if(CMAKE_CUDA_COMPILER) + if (NOT CUDA_TARGET_ARCHS) + # Volta, Ampere, Hopper + set(CUDA_TARGET_ARCHS "70;80;90") + endif() + CUDA_get_gencode_args(CUDA_gencode_flags ${CUDA_TARGET_ARCHS}) + set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -shared -std=c++17 ${CUDA_gencode_flags} --compiler-options -fPIC") + + enable_language(CUDA) + set(CUDA_FOUND TRUE) + set(CMAKE_CUDA_STANDARD 17) + set(CMAKE_CUDA_STANDARD_REQUIRED TRUE) + message(STATUS "Cuda language found.") +endif() + # External Dependencies # ==============================================================================