Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into support-expr
Browse files Browse the repository at this point in the history
  • Loading branch information
hhorii committed Sep 11, 2023
2 parents 3dff8b5 + 5e77fc8 commit 1aa991c
Show file tree
Hide file tree
Showing 29 changed files with 631 additions and 98 deletions.
151 changes: 151 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,34 @@
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
file(STRINGS "qiskit_aer/VERSION.txt" VERSION_NUM)

# For ROCm builds we need to make sure the CXX and HIP compilers match and are clang.
# We should do this before the project() call to make sure the compiler options are
# properly assessed.
if(AER_THRUST_BACKEND STREQUAL "ROCM")

if(DEFINED ENV{ROCM_PATH})
set(ROCM_PATH "$ENV{ROCM_PATH}")
else()
set(ROCM_PATH "/opt/rocm")
endif()

if(NOT DEFINED CMAKE_HIP_COMPILER)
if(DEFINED ENV{CMAKE_HIP_COMPILER})
set(CMAKE_HIP_COMPILER "$ENV{CMAKE_HIP_COMPILER}")
else()
set(CMAKE_HIP_COMPILER "${ROCM_PATH}/llvm/bin/clang++")
endif()
endif()

if(NOT DEFINED CMAKE_CXX_COMPILER)
if(DEFINED ENV{CMAKE_CXX_COMPILER})
set(CMAKE_CXX_COMPILER "$ENV{CMAKE_CXX_COMPILER}")
else()
set(CMAKE_CXX_COMPILER "${CMAKE_HIP_COMPILER}")
endif()
endif()
endif()

# Add CUDA to the project if needed.
set(EXTRA_LANGUAGES "")
if(AER_THRUST_BACKEND STREQUAL "CUDA")
Expand Down Expand Up @@ -376,6 +404,96 @@ if(AER_THRUST_SUPPORTED)
set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_THRUST_CPU=TRUE)
# We don't need to add OMP because it's already an AER dependency
set(THRUST_DEPENDENT_LIBS "")
elseif(AER_THRUST_BACKEND STREQUAL "ROCM")
#
# Build with GPU support with ROCm
#

# Assert that the C++ and compilers are Clang to enable ROCm builds.
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR
"The compiler for ROCm builds must be Clang. Set CMAKE_CXX_COMPILER to <ROCm path>/llvm/bin/clang++")
endif()

# GDB debug information is what is needed for runs enabled with ROCm.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ggdb")

# Leverage AER_ROCM_ARCH to specify the relevant targets and send the ROCm default ones to
# the background by marking them as advanced. We need to set the architectures in advance
# of attemting to find HIP to leverage the package machinery.

string(REPLACE " " ";" AER_ROCM_ARCH_LIST ${AER_ROCM_ARCH})
set(GPU_TARGETS ${AER_ROCM_ARCH_LIST} CACHE INTERNAL "GPU targets to compile for")
set(AMDGPU_TARGETS ${AER_ROCM_ARCH_LIST} CACHE INTERNAL "AMD GPU targets to compile for")
set(CMAKE_HIP_ARCHITECTURES ${AER_ROCM_ARCH_LIST})

mark_as_advanced(GPU_TARGETS)
mark_as_advanced(AMDGPU_TARGETS)
mark_as_advanced(CMAKE_HIP_ARCHITECTURES)
message(STATUS "ROCm build targeting GPU Architectures: ${GPU_TARGETS}")

message(STATUS "ROCm assumed path: ${ROCM_PATH}")
list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH})
list(APPEND CMAKE_MODULE_PATH ${ROCM_PATH}/hip/cmake ${ROCM_PATH})

include(CheckLanguage)
check_language(HIP)

# Find HIP in config mode as the module mode may not provide the hip:: targets. We can use module mode
# if we had hip libraries as they invoke the config package.
find_package(HIP CONFIG)
if(HIP_FOUND)
message(STATUS "Found HIP: " ${HIP_VERSION})
else()
message(FATAL_ERROR "Could not find HIP.")
endif()

list(APPEND AER_LIBRARIES hip::device)

# Add definitions so that dependencies are properly determined.
# TODO: investigate the need for THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA
list(APPEND ROCM_EXTRA_DEFS AER_THRUST_GPU AER_THRUST_ROCM THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_HIP)

# Add -D prefix to all defs as that is what ROCM_EXTRA_* expect to be set to.
list(TRANSFORM ROCM_EXTRA_DEFS PREPEND -D)
add_definitions(${ROCM_EXTRA_DEFS})
list(APPEND ROCM_EXTRA_FLAGS ${ROCM_EXTRA_DEFS})
list(APPEND ROCM_EXTRA_FLAGS -isystem${ROCM_PATH}/include; -I${AER_SIMULATOR_CPP_SRC_DIR} ; -isystem${AER_SIMULATOR_CPP_SRC_DIR}/third-party/headers; -ffast-math; -fPIC)

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND ROCM_EXTRA_FLAGS -O0)
else()
list(APPEND ROCM_EXTRA_FLAGS -O3)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
list(APPEND ROCM_EXTRA_FLAGS -g; -ggdb)
endif()

# Add some warning flags to allow existing code to go through with clang.
list(APPEND ROCM_EXTRA_FLAGS -ferror-limit=3
-Wno-unused-lambda-capture
-Wno-bitwise-instead-of-logical
-Wno-inconsistent-missing-override
-Wno-cast-align
-Wno-float-equal
-Wno-unused-variable
-Wno-unused-but-set-variable
-Wno-switch
-Wno-writable-strings
-Wno-shadow
-Wno-delete-non-abstract-non-virtual-dtor
-Wno-pessimizing-move
-Wno-return-type-c-linkage
-Wno-overloaded-virtual
-Wno-braced-scalar-init)


if(AER_ENABLE_CUQUANTUM)
message(WARNING "Implementation of cuQuantum is not available for ROCm builds.")
endif()

else()
message(STATUS "No Thrust supported backend")
set(AER_THRUST_SUPPORTED FALSE)
Expand Down Expand Up @@ -463,6 +581,35 @@ else() # Standalone build
RUNTIME_OUTPUT_DIRECTORY_DEBUG Debug
RUNTIME_OUTPUT_DIRECTORY_RELEASE Release)
endfunction()

function(build_rocm target src_file is_exec)
# ROCm is only supported in x86_64 devices so it should be safe to leverage AVX2.
set(SIMD_SOURCE_FILE "${PROJECT_SOURCE_DIR}/src/simulators/statevector/qv_avx2.cpp")

set_source_files_properties(
${SIMD_SOURCE_FILE}
${src_file}
PROPERTIES LANGUAGE CXX)

if(${is_exec})
add_executable(${target} ${src_file} ${SIMD_SOURCE_FILE})
else()
add_library(${target} ${src_file} ${SIMD_SOURCE_FILE})
endif()

target_compile_options(${target} PRIVATE ${ROCM_EXTRA_FLAGS} ${SIMD_FLAGS_LIST})
target_compile_definitions(${target} PRIVATE ${ROCM_EXTRA_DEFS} ${AER_COMPILER_DEFINITIONS})

target_link_libraries(${target} PRIVATE ${AER_LIBRARIES})

set_target_properties(${target} PROPERTIES
LINKER_LANGUAGE CXX
CXX_STANDARD 14
COMPILE_FLAGS ${AER_COMPILER_FLAGS}
LINK_FLAGS ${AER_LINKER_FLAGS}
RUNTIME_OUTPUT_DIRECTORY_DEBUG Debug
RUNTIME_OUTPUT_DIRECTORY_RELEASE Release)
endfunction()

function(build_cpu target src_file is_exec)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "amd64")
Expand Down Expand Up @@ -506,6 +653,8 @@ else() # Standalone build
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
if(CUDA_FOUND AND AER_THRUST_BACKEND STREQUAL "CUDA")
build_cuda(qasm_simulator ${AER_SIMULATOR_SOURCE} TRUE)
elseif(HIP_FOUND AND AER_THRUST_BACKEND STREQUAL "ROCM")
build_rocm(qasm_simulator ${AER_SIMULATOR_SOURCE} TRUE)
else()
build_cpu(qasm_simulator ${AER_SIMULATOR_SOURCE} TRUE)
endif()
Expand All @@ -516,6 +665,8 @@ else() # Standalone build
set(AER_RUNTIME_SOURCE "${PROJECT_SOURCE_DIR}/contrib/runtime/aer_runtime.cpp")
if(CUDA_FOUND AND AER_THRUST_BACKEND STREQUAL "CUDA")
build_cuda(aer ${AER_RUNTIME_SOURCE} FALSE)
elseif(HIP_FOUND AND AER_THRUST_BACKEND STREQUAL "ROCM")
build_rocm(aer ${AER_RUNTIME_SOURCE} FALSE)
else()
build_cpu(aer ${AER_RUNTIME_SOURCE} FALSE)
endif()
Expand Down
60 changes: 56 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,9 +636,11 @@ options we have on `Aer` to CMake, we use its native mechanism:
### Building with GPU support

Qiskit Aer can exploit GPU's horsepower to accelerate some simulations, specially the larger ones.
GPU access is supported via CUDA® (NVIDIA® chipset), so to build with GPU support, you need
to have CUDA® >= 11.2 preinstalled. See install instructions [here](https://developer.nvidia.com/cuda-toolkit-archive)
Please note that we only support GPU acceleration on Linux platforms at the moment.
GPU access is supported either via CUDA® (NVIDIA® chipset) or ROCm® (AMD® GPUs).

#### Building with CUDA® support
To build with CUDA® support, you need to have CUDA® >= 11.2 preinstalled. See install instructions [here](https://developer.nvidia.com/cuda-toolkit-archive).
Please note that we only support CUDA® GPU acceleration on Linux platforms at the moment.

Once CUDA® is properly installed, you only need to set a flag so the build system knows what to do:

Expand All @@ -664,7 +666,7 @@ or
This will reduce the amount of compilation time when, for example, the architecture auto detection
fails and the build system compiles all common architectures.

Few notes on GPU builds:
Few notes on CUDA® GPU builds:
1. Building takes considerable more time than non-GPU build, so be patient :)
2. CUDA® >= 11.2 imposes the restriction of building with g++ version not newer than 8
3. We don't need NVIDIA® drivers for building, but we need them for running simulations
Expand Down Expand Up @@ -706,8 +708,58 @@ Also you can accelrate density matrix and unitary matrix simulations as well.
sim = AerSimulator(method='density_matrix', device='GPU')
results = execute(circuit,sim,cuStateVec_enable=True).result()
```
#### Building with ROCm® support
ROCm® support has been added matching the CUDA® implementation based
on the `thrust` library. This enables Qiskit-Aer to run on AMD® GPUs,
including the AMD® Instinct GPU line based on the CDNA architecture.
ROCm® only support linux platforms.

To build the standalone version, the following should be sufficient:

```
cmake <Qiskit-Aer source folder> -G Ninja \
-DCMAKE_INSTALL_PREFIX=<Qiskit-Aer target instalation folder> \
-DSKBUILD=FALSE \
-DAER_THRUST_BACKEND=ROCM \
-DAER_MPI=<set to ON or OFF depending on whether to activate MPI support> \
-DAER_ROCM_ARCH=<target AMD GPU list, white-space separated, e.g. 'gfx90a gfx908'> \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTS=True
ninja install
```
Alternatively, and possibly preferred for most use cases, you can create a Python
wheel file that you can install as part of your Python environemnt:
```
cd <Qiskit-Aer source folder>
QISKIT_AER_PACKAGE_NAME='qiskit-aer-gpu-rocm' \
python3 setup.py bdist_wheel -- \
-DAER_THRUST_BACKEND=ROCM \
-DAER_MPI=<set to ON or OFF depending on whether to activate MPI support> \
-DAER_ROCM_ARCH=<target AMD GPU list, white-space separated, e.g. 'gfx90a gfx908'>
pip install --force-reinstall dist/qiskit_aer_gpu_rocm-*.whl
```

In both cases, the host system needs to have a functional ROCm® instalation and
the environment variable `ROCM_PATH` set pointing to the ROCm® instalation folder if
that is not the default `/opt/rocm`.
Depending on how your Python environment is set, you might need to install
Qiskit-Aer's required development modules:
```
cd <Qiskit-Aer source folder>
pip install -r requirements-dev.txt
```

To leverage the ROCm® implementations no code changes are needed on top of one
already does for CUDA®. Running with cuStateVec, for instance, requires set
`device='GPU'` to AerSimulator option and set `cuStateVec_enable=True` option,
similarly to what is done for CUDA®:

```
sim = AerSimulator(method='statevector', device='GPU')
results = execute(circuit,sim,cuStateVec_enable=True).result()
```

### Building with MPI support

Expand Down
2 changes: 2 additions & 0 deletions cmake/conan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ function(_get_msvc_ide_version result)
set(${result} 15 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
set(${result} 16 PARENT_SCOPE)
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940)
set(${result} 17 PARENT_SCOPE)
else()
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
endif()
Expand Down
4 changes: 2 additions & 2 deletions cmake/conan_utils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ macro(setup_conan)
endif()
endif()

if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA")
if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA" AND NOT AER_THRUST_BACKEND STREQUAL "ROCM")
set(REQUIREMENTS ${REQUIREMENTS} thrust/1.9.5)
list(APPEND AER_CONAN_LIBS thrust)
string(TOLOWER ${AER_THRUST_BACKEND} THRUST_BACKEND)
Expand Down Expand Up @@ -78,7 +78,7 @@ macro(setup_conan)
endif()

# Headers includes
if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA")
if(AER_THRUST_BACKEND AND NOT AER_THRUST_BACKEND STREQUAL "CUDA" AND NOT AER_THRUST_BACKEND STREQUAL "ROCM")
set(AER_SIMULATOR_CPP_EXTERNAL_LIBS ${AER_SIMULATOR_CPP_EXTERNAL_LIBS} ${CONAN_INCLUDE_DIRS_THRUST})
endif()

Expand Down
2 changes: 1 addition & 1 deletion contrib/runtime/aer_runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ void aer_apply_tdg(void *handler, uint_t qubit) {
// sqrt(NOT) gate
void aer_apply_sx(void *handler, uint_t qubit) {
AER::AerState *state = reinterpret_cast<AER::AerState *>(handler);
state->apply_mcrx({qubit}, -M_PI / 4.0);
state->apply_mcsx({qubit});
};

// Rotation around X-axis
Expand Down
14 changes: 14 additions & 0 deletions qiskit_aer/backends/wrappers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ if(AER_THRUST_BACKEND STREQUAL "CUDA")
nvcc_add_compiler_options(${AER_COMPILER_FLAGS_STRIPPED} AER_COMPILER_FLAGS_OUT)
set_target_properties(controller_wrappers PROPERTIES COMPILE_FLAGS "${AER_COMPILER_FLAGS_OUT}")
enable_language(CUDA)
elseif(AER_THRUST_BACKEND STREQUAL "ROCM")

if(NOT DEFINED SIMD_SOURCE_FILE)
message(FATAL_ERROR "ROCm supported target machines are expected to be SIMD-enabled.")
endif()

set_source_files_properties(
bindings.cc
${SIMD_SOURCE_FILE}
PROPERTIES LANGUAGE CXX)

target_compile_options(controller_wrappers PRIVATE ${ROCM_EXTRA_FLAGS} ${SIMD_FLAGS_LIST})
target_compile_definitions(controller_wrappers PRIVATE ${ROCM_EXTRA_DEFS} ${AER_COMPILER_DEFINITIONS})
set_target_properties(controller_wrappers PROPERTIES COMPILE_FLAGS "${AER_COMPILER_FLAGS}")
else()
if(DEFINED SIMD_SOURCE_FILE)
string(REPLACE ";" " " SIMD_FLAGS "${SIMD_FLAGS_LIST}")
Expand Down
40 changes: 40 additions & 0 deletions releasenotes/notes/add-rocm-support-db991e3c2f2ca455.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
features:
- |
ROCm support has been added matching the existing CUDA implementation based
on the ``thrust`` library. This enables Qiskit-Aer to run on AMD GPUs,
including the AMD Instinct GPU line based on the CDNA architecture. To build
the standalone version, the following should be sufficient::
cmake <Qiskit-Aer source folder> -G Ninja \
-DCMAKE_INSTALL_PREFIX=<Qiskit-Aer target instalation folder> \
-DSKBUILD=FALSE \
-DAER_THRUST_BACKEND=ROCM \
-DAER_MPI=<set to ON or OFF depending on whether to activate MPI support> \
-DAER_ROCM_ARCH=<target AMD GPU list, white-space separated, e.g. 'gfx90a gfx908'> \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTS=True
ninja install
Alternatively, and possibly preferred for most use cases, you can create a Python
wheel file that you can install as part of your Python environemnt::
cd <Qiskit-Aer source folder>
QISKIT_AER_PACKAGE_NAME='qiskit-aer-gpu-rocm' \
python3 setup.py bdist_wheel -- \
-DAER_THRUST_BACKEND=ROCM \
-DAER_MPI=<set to ON or OFF depending on whether to activate MPI support> \
-DAER_ROCM_ARCH=<target AMD GPU list, white-space separated, e.g. 'gfx90a gfx908'>
pip install --force-reinstall dist/qiskit_aer_gpu_rocm-*.whl
In both cases, the host system needs to have a functional ROCm instalation and
the environment variable ``ROCM_PATH`` set pointing to the ROCm instalation folder if
that is not the default ``/opt/rocm``.
Depending on how your Python environment is set, you might need to install
Qiskit-Aer's required development modules::
cd <Qiskit-Aer source folder>
pip install -r requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Aer runtime api (from contrib) exposed the wrong sx operation,
implemented with a rx. The implementation is changed now by
adding AerState::apply_mcsx and calling it from aer_apply_sx.
This way the api has the same behavior as the documentation
states and also how the sx gate behaves in python.
Fix for: https://github.com/Qiskit/qiskit-aer/issues/1925
10 changes: 10 additions & 0 deletions releasenotes/notes/fix-aer-vector-alignment-aace6e14342c002e.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
fixes:
- |
Change ``AER::Vector`` object alignement to 64-byte. In some cases, it is used to
initialize ``AER:QV::QubitVector`` objects by moving storage ownership to these
objects. As the code assumes that ``AER:QV::QubitVector`` storage is at least
32-byte aligned for AVX2 load instructions, this change enforces the same alignement
requirements for both ``AER::Vector`` and ``AER:QV::QubitVector`` objects so that
one doesn't get into segmentation faults.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
fixes:
- |
Fixes an issue when compiling a release version on windows with vc++,
also unrolls a for, avoiding an unnecessary switch inside it.
The fix is for https://github.com/Qiskit/qiskit-aer/issues/1918
Loading

0 comments on commit 1aa991c

Please sign in to comment.