Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integrated a new cuQuantum and Thrust GPU backend #386

Merged
merged 15 commits into from
Sep 20, 2023
Merged
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
Loading