Skip to content

Commit

Permalink
Merge pull request #386 from QuEST-Kit/cuquantum
Browse files Browse the repository at this point in the history
integrated a new cuQuantum and Thrust GPU backend
  • Loading branch information
TysonRayJones authored Sep 20, 2023
2 parents 2c465c2 + f7515b0 commit c63a0f8
Show file tree
Hide file tree
Showing 12 changed files with 2,615 additions and 1,031 deletions.
53 changes: 36 additions & 17 deletions QuEST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ option(USE_HIP "Whether to use HIP for GPU code compilation for AMD GPUs. Set to

set(GPU_ARCH gfx90 CACHE STRING "GPU hardware dependent, used for AMD GPUs when USE_HIP=1. Lookup at https://llvm.org/docs/AMDGPUUsage.html#amdgpu-processor-table. Write without fullstop")

option(USE_CUQUANTUM "Whether to use NVIDIA's cuQuantum library (requires prior installation) in lieu of QuEST's bespoke GPU kernel. Set to 1 to enable." 0)


# *****************************************************************************
# ***** NO CHANGES SHOULD BE REQUIRED FROM THE USER BEYOND THIS POINT *********
Expand All @@ -49,6 +51,7 @@ message(STATUS "OMP acceleration is ${MULTITHREADED}")
message(STATUS "MPI distribution is ${DISTRIBUTED}")
if (${GPUACCELERATED})
message(STATUS "HIP compilation is ${USE_HIP}")
message(STATUS "cuQuantum compilation is ${USE_CUQUANTUM}")
endif()


Expand Down Expand Up @@ -119,25 +122,28 @@ endif()
if (GPUACCELERATED)
if (USE_HIP)

if(NOT DEFINED HIP_PATH)
if(NOT DEFINED ENV{HIP_PATH})
message(WARNING "WARNING: HIP_PATH is not defiend. Using default HIP_PATH=/opt/rocm/hip " ${HIP_VERSION})
set(HIP_PATH "/opt/rocm/hip" CACHE PATH "Path to which HIP has been installed")
else()
set(HIP_PATH $ENV{HIP_PATH} CACHE PATH "Path to which HIP has been installed")
if(NOT DEFINED HIP_PATH)
if(NOT DEFINED ENV{HIP_PATH})
message(WARNING "WARNING: HIP_PATH is not defiend. Using default HIP_PATH=/opt/rocm/hip " ${HIP_VERSION})
set(HIP_PATH "/opt/rocm/hip" CACHE PATH "Path to which HIP has been installed")
else()
set(HIP_PATH $ENV{HIP_PATH} CACHE PATH "Path to which HIP has been installed")
endif()
endif()
endif()

if(EXISTS "${HIP_PATH}")
set(CMAKE_MODULE_PATH "${HIP_PATH}/cmake" ${CMAKE_MODULE_PATH})
find_package(HIP REQUIRED)
message(STATUS "Found HIP: " ${HIP_VERSION})
message(STATUS "HIP PATH: " ${HIP_PATH})
endif()

ADD_DEFINITIONS( -DUSE_HIP )
ADD_DEFINITIONS( -D__HIP_PLATFORM_AMD__ )
if(EXISTS "${HIP_PATH}")
set(CMAKE_MODULE_PATH "${HIP_PATH}/cmake" ${CMAKE_MODULE_PATH})
find_package(HIP REQUIRED)
message(STATUS "Found HIP: " ${HIP_VERSION})
message(STATUS "HIP PATH: " ${HIP_PATH})
endif()
ADD_DEFINITIONS( -DUSE_HIP )
ADD_DEFINITIONS( -D__HIP_PLATFORM_AMD__ )

elseif (USE_CUQUANTUM)
find_package(CUDA REQUIRED)
ADD_DEFINITIONS( -DUSE_CUQUANTUM )
else()
find_package(CUDA REQUIRED)
endif()
Expand Down Expand Up @@ -280,7 +286,12 @@ endif()
# ----- C++ COMPILER FLAGS --------------------------------------------------

# set C++ flags that are common between compilers and build types
set (CMAKE_CXX_STANDARD 98)
if (USE_CUQUANTUM)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
else ()
set (CMAKE_CXX_STANDARD 98)
endif ()

# Use -O2 for all but debug mode by default
if (NOT("${CMAKE_BUILD_TYPE}" STREQUAL "Debug"))
Expand Down Expand Up @@ -412,6 +423,14 @@ target_link_libraries(QuEST PUBLIC ${MPI_C_LIBRARIES})
# ----- GPU -------------------------------------------------------------------
if (USE_HIP)
target_link_libraries(QuEST PUBLIC ${HIP_PATH}/lib/libamdhip64.so )
elseif (USE_CUQUANTUM)
find_library(CUQUANTUM_LIBRARIES custatevec)
if (NOT CUQUANTUM_LIBRARIES)
message(FATAL_ERROR "cuQuantum library (specifically custatevec) not found")
endif ()

target_link_libraries(QuEST ${CUDA_LIBRARIES} ${CUQUANTUM_LIBRARIES})
target_include_directories(QuEST PUBLIC "/usr/local/cuda/include")
else()
target_link_libraries(QuEST ${CUDA_LIBRARIES})
endif()
Expand Down
30 changes: 30 additions & 0 deletions QuEST/include/QuEST.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@

# include "QuEST_precision.h"



// ensure custatevecHandle_t is defined, even if no GPU
# ifdef USE_CUQUANTUM
# include <custatevec.h>
typedef struct CuQuantumConfig {
cudaMemPool_t cuMemPool;
cudaStream_t cuStream;
custatevecHandle_t cuQuantumHandle;
custatevecDeviceMemHandler_t cuMemHandler;
} CuQuantumConfig;
# else
# define CuQuantumConfig void*
# endif



// prevent C++ name mangling
#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -368,6 +385,11 @@ typedef struct Qureg
//! Storage for reduction of probabilities on GPU
qreal *firstLevelReduction, *secondLevelReduction;

//! Storage for wavefunction amplitues and config (copy of QuESTEnv's handle) in cuQuantum deployment
cuAmp* cuStateVec;
cuAmp* deviceCuStateVec;
CuQuantumConfig* cuConfig;

//! Storage for generated QASM output
QASMLogger* qasmLog;

Expand All @@ -386,6 +408,10 @@ typedef struct QuESTEnv
int numRanks;
unsigned long int* seeds;
int numSeeds;

// a copy of the QuESTEnv's config, used only in cuQuantum deployment
CuQuantumConfig* cuConfig;

} QuESTEnv;


Expand Down Expand Up @@ -4236,6 +4262,10 @@ qreal calcPurity(Qureg qureg);
* linear algebra calculation.
*
* The number of qubits represented in \p qureg and \p pureState must match.
*
* > In the GPU-accelerated cuQuantum backend, this function further assumes that
* > the density matrix \p qureg is correctly normalised, and otherwise returns the
* > fidelity of the conjugate-transpose of \p qureg.
*
* @see
* - calcHilbertSchmidtDistance()
Expand Down
23 changes: 19 additions & 4 deletions QuEST/include/QuEST_precision.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,27 @@
* @author Tyson Jones (doc)
*/

# include <math.h>

# ifndef QUEST_PRECISION_H
# define QUEST_PRECISION_H

# include <math.h>


// define CUDA complex types as void if not using cuQuantum.
// note we used cuComplex.h for complex numbers, in lieu of
// Thrust's complex<qreal>, so that the QuEST.h header can
// always be compiled with C99, rather than C++14.
# ifdef USE_CUQUANTUM
# include <cuComplex.h>
# else
# define cuFloatComplex void
# define cuDoubleComplex void
# endif


// set default double precision if not set during compilation
# ifndef QuEST_PREC
# define QuEST_PREC 2
# define QuEST_PREC 2
# endif


Expand All @@ -28,6 +40,7 @@
# if QuEST_PREC==1
# define qreal float
// \cond HIDDEN_SYMBOLS
# define cuAmp cuFloatComplex
# define MPI_QuEST_REAL MPI_FLOAT
# define MPI_MAX_AMPS_IN_MSG (1LL<<29) // must be 2^int
# define REAL_STRING_FORMAT "%.8f"
Expand All @@ -41,7 +54,8 @@
*/
# elif QuEST_PREC==2
# define qreal double
// \cond HIDDEN_SYMBOLS
// \cond HIDDEN_SYMBOLS
# define cuAmp cuDoubleComplex
# define MPI_QuEST_REAL MPI_DOUBLE
# define MPI_MAX_AMPS_IN_MSG (1LL<<28) // must be 2^int
# define REAL_STRING_FORMAT "%.14f"
Expand All @@ -57,6 +71,7 @@
# elif QuEST_PREC==4
# define qreal long double
// \cond HIDDEN_SYMBOLS
# define cuAmp void // invalid
# define MPI_QuEST_REAL MPI_LONG_DOUBLE
# define MPI_MAX_AMPS_IN_MSG (1LL<<27) // must be 2^int
# define REAL_STRING_FORMAT "%.17Lf"
Expand Down
11 changes: 8 additions & 3 deletions QuEST/src/GPU/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
if (USE_CUQUANTUM)
set(GPU_CORE QuEST_cuQuantum.cu)
else ()
set(GPU_CORE QuEST_gpu.cu)
endif()

set(QuEST_SRC_ARCHITECTURE_DEPENDENT
${CMAKE_CURRENT_SOURCE_DIR}/QuEST_gpu.cu
${CMAKE_CURRENT_SOURCE_DIR}/${GPU_CORE}
${CMAKE_CURRENT_SOURCE_DIR}/QuEST_gpu_common.cu
PARENT_SCOPE
)


Loading

0 comments on commit c63a0f8

Please sign in to comment.