diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0a41e8d727..301d66da36 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.7' + python-version: '3.8' - name: Install cibuildwheel run: | python -m pip install cibuildwheel==2.11.2 @@ -45,7 +45,7 @@ jobs: - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.7' + python-version: '3.8' - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -119,28 +119,35 @@ jobs: TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} TWINE_USERNAME: qiskit run: twine upload dist/qiskit* - gpu-build: - name: Build qiskit-aer-gpu wheels + gpu-build-cuda11: + name: Build qiskit-aer-gpu-cu11 wheels runs-on: ubuntu-latest steps: + - name: Maximize build space + uses: easimon/maximize-build-space@master + with: + root-reserve-mb: 40000 + swap-size-mb: 1024 + remove-dotnet: 'true' + remove-android: 'true' + remove-haskell: 'true' + remove-codeql: 'true' + remove-docker-images: 'true' - uses: actions/checkout@v2 - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.7' - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 - if: runner.os == 'Windows' + python-version: '3.8' - name: Install cibuildwheel run: | python -m pip install cibuildwheel==2.11.2 - name: Build wheels env: - CIBW_BEFORE_ALL: "yum install -y yum-utils wget && wget -q https://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel6-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm && rpm -i cuda-repo-rhel6-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm && yum clean all && yum -y install cuda-10-1 openblas-devel" - CIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux2010_x86_64:latest - CIBW_SKIP: "*-manylinux_i686 cp310* pp* cp36* *musllinux*" - CIBW_TEST_SKIP: "cp*" - CIBW_ENVIRONMENT: QISKIT_AER_PACKAGE_NAME=qiskit-aer-gpu AER_THRUST_BACKEND=CUDA CUDACXX=/usr/local/cuda/bin/nvcc + CIBW_BEFORE_ALL: "yum install -y yum-utils wget && wget -q https://developer.download.nvidia.com/compute/cuda/11.8.0/local_installers/cuda-repo-rhel7-11-8-local-11.8.0_520.61.05-1.x86_64.rpm && rpm -i cuda-repo-rhel7-11-8-local-11.8.0_520.61.05-1.x86_64.rpm && yum clean all && yum -y install cuda && yum -y install openblas-devel && yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo && yum clean all" + CIBW_BEFORE_BUILD : "pip install --user nvidia-cuda-runtime-cu11 nvidia-cublas-cu11 nvidia-cusolver-cu11 nvidia-cusparse-cu11 cuquantum-cu11 && pip show nvidia-cuda-runtime-cu11 nvidia-cublas-cu11 nvidia-cusolver-cu11 nvidia-cusparse-cu11 cuquantum-cu11" + CIBW_SKIP: "*-manylinux_i686 pp* cp36* *musllinux*" + CIBW_ENVIRONMENT: QISKIT_AER_PACKAGE_NAME=qiskit-aer-gpu-cu11 QISKIT_AER_CUDA_MAJOR=11 CMAKE_VERBOSE_MAKEFILE=true AER_THRUST_BACKEND=CUDA CUDACXX=/usr/local/cuda/bin/nvcc AER_CUDA_ARCH="7.0 7.2 7.5 8.0 8.6 8.7" AER_PYTHON_CUDA_ROOT=/root/.local LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/.local/lib/python3.7/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.7/site-packages/cuquantum/lib:/root/.local/lib/python3.8/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.8/site-packages/cuquantum/lib:/root/.local/lib/python3.9/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.9/site-packages/cuquantum/lib:/root/.local/lib/python3.10/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.10/site-packages/cuquantum/lib:/root/.local/lib/python3.11/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.11/site-packages/cuquantum/lib + CIBW_REPAIR_WHEEL_COMMAND: 'auditwheel repair --exclude libcudart.so.11.0 --exclude libcustatevec.so.1 --exclude libcutensornet.so.2 --exclude libcutensor.so.1 --exclude libcutensorMg.so.1 --exclude libcusolver.so.11 --exclude libcusolverMg.so.11 --exclude libcusparse.so.11 --exclude libcublas.so.11 --exclude libcublasLt.so.11 -w {dest_dir} {wheel}' run: | python -m cibuildwheel --output-dir wheelhouse - uses: actions/upload-artifact@v2 @@ -153,26 +160,35 @@ jobs: run : | pip install -U twine twine upload wheelhouse/* - gpu-build-310: - name: Build qiskit-aer-gpu wheels + gpu-build-cuda12: + name: Build qiskit-aer-gpu-cu12 wheels runs-on: ubuntu-latest steps: + - name: Maximize build space + uses: easimon/maximize-build-space@master + with: + root-reserve-mb: 40000 + swap-size-mb: 1024 + remove-dotnet: 'true' + remove-android: 'true' + remove-haskell: 'true' + remove-codeql: 'true' + remove-docker-images: 'true' - uses: actions/checkout@v2 - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.7' - - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 - if: runner.os == 'Windows' + python-version: '3.8' - name: Install cibuildwheel run: | python -m pip install cibuildwheel==2.11.2 - name: Build wheels env: - CIBW_BEFORE_ALL: "yum install -y yum-utils wget && wget -q https://developer.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel7-10-1-local-10.1.105-418.39-1.0-1.x86_64.rpm && rpm -i cuda-repo-rhel7-10-1-local-10.1.105-418.39-1.0-1.x86_64.rpm && yum clean all && yum -y install cuda-10-1 openblas-devel" - CIBW_BUILD: "cp310-manylinux_x86_64" - CIBW_ENVIRONMENT: QISKIT_AER_PACKAGE_NAME=qiskit-aer-gpu AER_THRUST_BACKEND=CUDA CUDACXX=/usr/local/cuda/bin/nvcc + CIBW_BEFORE_ALL: "yum install -y yum-utils wget && wget -q https://developer.download.nvidia.com/compute/cuda/12.1.1/local_installers/cuda-repo-rhel7-12-1-local-12.1.1_530.30.02-1.x86_64.rpm && rpm -i cuda-repo-rhel7-12-1-local-12.1.1_530.30.02-1.x86_64.rpm && yum clean all && yum -y install cuda && yum -y install openblas-devel && yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo && yum clean all" + CIBW_BEFORE_BUILD : "pip install --user nvidia-cuda-runtime-cu12 nvidia-cublas-cu12 nvidia-cusolver-cu12 nvidia-cusparse-cu12 cuquantum-cu12" + CIBW_SKIP: "*-manylinux_i686 pp* cp36* *musllinux*" + CIBW_ENVIRONMENT: QISKIT_AER_PACKAGE_NAME=qiskit-aer-gpu QISKIT_AER_CUDA_MAJOR=12 CMAKE_VERBOSE_MAKEFILE=true AER_THRUST_BACKEND=CUDA CUDACXX=/usr/local/cuda/bin/nvcc AER_CUDA_ARCH="7.0 7.2 7.5 8.0 8.6 8.7 9.0" AER_PYTHON_CUDA_ROOT=/root/.local LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/.local/lib/python3.7/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.7/site-packages/cuquantum/lib:/root/.local/lib/python3.8/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.8/site-packages/cuquantum/lib:/root/.local/lib/python3.9/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.9/site-packages/cuquantum/lib:/root/.local/lib/python3.10/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.10/site-packages/cuquantum/lib:/root/.local/lib/python3.11/site-packages/nvidia/cuda_runtime/lib:/root/.local/lib/python3.11/site-packages/cuquantum/lib + CIBW_REPAIR_WHEEL_COMMAND: 'auditwheel repair --exclude libcudart.so.12 --exclude libcustatevec.so.1 --exclude libcutensornet.so.2 --exclude libcutensor.so.1 --exclude libcutensorMg.so.1 --exclude libcusolver.so.11 --exclude libcusolverMg.so.11 --exclude libcusolver.so.12 --exclude libcusolverMg.so.12 --exclude libcusparse.so.12 --exclude libcublas.so.12 --exclude libcublasLt.so.12 --exclude libnvJitLink.so.12 -w {dest_dir} {wheel}' run: | python -m cibuildwheel --output-dir wheelhouse - uses: actions/upload-artifact@v2 @@ -197,7 +213,7 @@ jobs: - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.7' + python-version: '3.8' - uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -233,7 +249,7 @@ jobs: - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.7' + python-version: '3.8' - uses: actions-rs/toolchain@v1 with: toolchain: stable diff --git a/CMakeLists.txt b/CMakeLists.txt index 1db8b19893..5a3bc55c2a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,49 +259,80 @@ if(AER_THRUST_SUPPORTED) set(CMAKE_CUDA_ARCHITECTURES "${AER_CUDA_ARCHITECTURES}") message(STATUS "CMAKE_CUDA_ARCHITECTURES = ${CMAKE_CUDA_ARCHITECTURES}") - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} ${AER_CUDA_ARCH_FLAGS_EXPAND} -DAER_THRUST_CUDA -I${AER_SIMULATOR_CPP_SRC_DIR} -isystem ${AER_SIMULATOR_CPP_SRC_DIR}/third-party/headers -use_fast_math --expt-extended-lambda") - - set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA) - set(THRUST_DEPENDANT_LIBS "-L${CUDA_TOOLKIT_ROOT_DIR}/lib64") - if(NOT DEFINED CUQUANTUM_ROOT) - if(DEFINED ENV{CUQUANTUM_ROOT}) - set(CUQUANTUM_ROOT $ENV{CUQUANTUM_ROOT}) - endif() - endif() - if(NOT DEFINED CUTENSOR_ROOT) - if(DEFINED ENV{CUTENSOR_ROOT}) - set(CUTENSOR_ROOT $ENV{CUTENSOR_ROOT}) - endif() - endif() - if(NOT DEFINED AER_ENABLE_CUQUANTUM) - if(DEFINED ENV{AER_ENABLE_CUQUANTUM}) - set(AER_ENABLE_CUQUANTUM $ENV{AER_ENABLE_CUQUANTUM}) - endif() + if(NOT DEFINED AER_PYTHON_CUDA_ROOT AND DEFINED ENV{AER_PYTHON_CUDA_ROOT}) + set(AER_PYTHON_CUDA_ROOT $ENV{AER_PYTHON_CUDA_ROOT}) endif() + if(AER_PYTHON_CUDA_ROOT) + find_package(Python) + set(PYTHON_SITE_PATH ${AER_PYTHON_CUDA_ROOT}/lib/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages) +# execute_process(COMMAND "${Python_EXECUTABLE}" -c "from distutils.sysconfig import get_python_lib; print (get_python_lib())" OUTPUT_VARIABLE PYTHON_SITE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "PYTHON_SITE_PATH = ${PYTHON_SITE_PATH}") - if(AER_ENABLE_CUQUANTUM) + set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA) set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_CUSTATEVEC AER_CUTENSORNET) - if(DEFINED CUQUANTUM_ROOT) - set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} -I${CUQUANTUM_ROOT}/include") - set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUQUANTUM_ROOT}/lib/${CUDA_VERSION_MAJOR}") + + set(CUDA_NVCC_FLAGS "${AER_CUDA_ARCH_FLAGS_EXPAND} -DAER_THRUST_CUDA -I${AER_SIMULATOR_CPP_SRC_DIR} -isystem ${AER_SIMULATOR_CPP_SRC_DIR}/third-party/headers -use_fast_math --expt-extended-lambda") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -I${PYTHON_SITE_PATH}/cuquantum/include") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -I${PYTHON_SITE_PATH}/cutensor/include") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Xlinker \"--disable-new-dtags\" ") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Xlinker \"--rpath=${PYTHON_SITE_PATH}/nvidia/cusolver/lib\" ") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Xlinker \"--rpath=${PYTHON_SITE_PATH}/nvidia/cusparse/lib\" ") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Xlinker \"--rpath=${PYTHON_SITE_PATH}/cutensor/lib\" ") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Xlinker \"--rpath=${PYTHON_SITE_PATH}/nvidia/cuda_runtime/lib\" ") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -Xlinker \"--no-as-needed,-l:libcusolver.so.${CUDA_VERSION_MAJOR},-l:libcusparse.so.${CUDA_VERSION_MAJOR},--as-needed\" ") + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${PYTHON_SITE_PATH}/cuquantum/lib -l:libcustatevec.so.1 -l:libcutensornet.so.2") + if(CUDA_VERSION_MAJOR STREQUAL "11") + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${PYTHON_SITE_PATH}/nvidia/cuda_runtime/lib -l:libcudart.so.${CUDA_VERSION_MAJOR}.0") + else() + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${PYTHON_SITE_PATH}/nvidia/cuda_runtime/lib -l:libcudart.so.${CUDA_VERSION_MAJOR}") endif() - if(DEFINED CUTENSOR_ROOT) - set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} -I${CUTENSOR_ROOT}/include") - set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUTENSOR_ROOT}/lib/${CUDA_VERSION_MAJOR}") + string(STRIP ${CUDA_NVCC_FLAGS} CUDA_NVCC_FLAGS) + string(STRIP ${THRUST_DEPENDANT_LIBS} THRUST_DEPENDANT_LIBS) + else() + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} ${AER_CUDA_ARCH_FLAGS_EXPAND} -DAER_THRUST_CUDA -I${AER_SIMULATOR_CPP_SRC_DIR} -isystem ${AER_SIMULATOR_CPP_SRC_DIR}/third-party/headers -use_fast_math --expt-extended-lambda") + + set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} THRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA) + set(THRUST_DEPENDANT_LIBS "-L${CUDA_TOOLKIT_ROOT_DIR}/lib64") + if(NOT DEFINED CUQUANTUM_ROOT) + if(DEFINED ENV{CUQUANTUM_ROOT}) + set(CUQUANTUM_ROOT $ENV{CUQUANTUM_ROOT}) + endif() endif() - if(CUQUANTUM_STATIC) - set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -lcustatevec_static -lcutensornet_static -lcutensor_static -lmetis_static -lcusolver_static -lcusparse_static -lcusolver_lapack_static -lcublas_static -lcublasLt_static -lculibos") - else() - set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -lcustatevec -lcutensornet -lcutensor") + if(NOT DEFINED CUTENSOR_ROOT) + if(DEFINED ENV{CUTENSOR_ROOT}) + set(CUTENSOR_ROOT $ENV{CUTENSOR_ROOT}) + endif() endif() - elseif(CUSTATEVEC_ROOT) - #TODO this is remained for backward compatibility, use CUQUANTUM_ROOT instead - set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_CUSTATEVEC) - set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} -I${CUSTATEVEC_ROOT}/include") - if(CUSTATEVEC_STATIC) - set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUSTATEVEC_ROOT}/lib -L${CUSTATEVEC_ROOT}/lib/${CUDA_VERSION_MAJOR} -lcustatevec_static -lcusolver_static -lcusparse_static -lcusolver_lapack_static -lcublas_static -lcublasLt_static -lculibos") - else() - set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUSTATEVEC_ROOT}/lib -L${CUSTATEVEC_ROOT}/lib/${CUDA_VERSION_MAJOR} -lcustatevec") + if(NOT DEFINED AER_ENABLE_CUQUANTUM) + if(DEFINED ENV{AER_ENABLE_CUQUANTUM}) + set(AER_ENABLE_CUQUANTUM $ENV{AER_ENABLE_CUQUANTUM}) + endif() + endif() + + if(AER_ENABLE_CUQUANTUM) + set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_CUSTATEVEC AER_CUTENSORNET) + if(DEFINED CUQUANTUM_ROOT) + set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} -I${CUQUANTUM_ROOT}/include") + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUQUANTUM_ROOT}/lib/${CUDA_VERSION_MAJOR}") + endif() + if(DEFINED CUTENSOR_ROOT) + set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} -I${CUTENSOR_ROOT}/include") + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUTENSOR_ROOT}/lib/${CUDA_VERSION_MAJOR}") + endif() + if(CUQUANTUM_STATIC) + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -lcustatevec_static -lcutensornet_static -lcutensor_static -lmetis_static -lcusolver_static -lcusparse_static -lcusolver_lapack_static -lcublas_static -lcublasLt_static -lculibos") + else() + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -lcustatevec -lcutensornet -lcutensor") + endif() + elseif(CUSTATEVEC_ROOT) + #TODO this is remained for backward compatibility, use CUQUANTUM_ROOT instead + set(AER_COMPILER_DEFINITIONS ${AER_COMPILER_DEFINITIONS} AER_CUSTATEVEC) + set(AER_COMPILER_FLAGS "${AER_COMPILER_FLAGS} -I${CUSTATEVEC_ROOT}/include") + if(CUSTATEVEC_STATIC) + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUSTATEVEC_ROOT}/lib -L${CUSTATEVEC_ROOT}/lib/${CUDA_VERSION_MAJOR} -lcustatevec_static -lcusolver_static -lcusparse_static -lcusolver_lapack_static -lcublas_static -lcublasLt_static -lculibos") + else() + set(THRUST_DEPENDANT_LIBS "${THRUST_DEPENDANT_LIBS} -L${CUSTATEVEC_ROOT}/lib -L${CUSTATEVEC_ROOT}/lib/${CUDA_VERSION_MAJOR} -lcustatevec") + endif() endif() endif() elseif(AER_THRUST_BACKEND STREQUAL "TBB") diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 59d1bdb829..5e11aa1bc1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -637,7 +637,7 @@ options we have on `Aer` to CMake, we use its native mechanism: 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® >= 10.1 preinstalled. See install instructions [here](https://developer.nvidia.com/cuda-toolkit-archive) +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. Once CUDA® is properly installed, you only need to set a flag so the build system knows what to do: @@ -648,43 +648,51 @@ AER_THRUST_BACKEND=CUDA For example, - qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA + qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -- If you want to specify the CUDA® architecture instead of letting the build system auto detect it, you can use the AER_CUDA_ARCH flag (can also be set as an ENV variable with the same name, although the flag takes precedence). For example: - qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -DAER_CUDA_ARCH="5.2" + qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -DAER_CUDA_ARCH="7.0" -- or - qiskit-aer$ export AER_CUDA_ARCH="5.2" - qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA + qiskit-aer$ export AER_CUDA_ARCH="7.0" + qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -- 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: 1. Building takes considerable more time than non-GPU build, so be patient :) -2. CUDA® >= 10.1 imposes the restriction of building with g++ version not newer than 8 +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 4. Only Linux platforms are supported Qiskit Aer now supports cuQuantum optimized Quantum computing APIs from NVIDIA®. cuStateVec APIs can be exploited to accelerate statevector, density_matrix and unitary methods. cuTensorNet APIs can be exploited to tensor_network merthod. -This implementation requires CUDA toolkit version 11.2 or higher and Volta or Ampare architecture GPUs. +This implementation requires CUDA® toolkit version 11.2 or higher and Volta or Ampare architecture GPUs. -To build Qiskit Aer with cuQuantum support, please set the path to cuQuantum root directory to CUQUANTUM_ROOT -and directory to cuTensor to CUTENSOR_ROOT then set AER_ENABLE_CUQUANTUM=true. -as following. +Before building Qiskit Aer with cuQuantum support, install required components via pip install as following. + + qiskit-aer$ pip install nvidia-cuda-runtime-cu11 nvidia-cublas-cu11 nvidia-cusolver-cu11 nvidia-cusparse-cu11 cuquantum-cu11 + +This example is for CUDA 11. Please replace cu11 to cu12 if your system has CUDA 12. + +Then to build with cuQuantum support, set the value `AER_PYTHON_CUDA_ROOT=` as following example. + + qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -DAER_PYTHON_CUDA_ROOT=qiskit-aer-venv -- + + +If you want to link cuQuantum library statically, cuQuantum SDK and cuTENSOR should be installed in your system from NVIDIA®. +Then set `CUQUANTUM_ROOT` `CUTENSOR_ROOT` and `CUQUANTUM_STATIC` to setup.py. For example, - qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -DCUQUANTUM_ROOT=path_to_cuQuantum -DCUTENSOR_ROOT=path_to_cuTENSOR -DAER_ENABLE_CUQUANTUM=true -- + qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_THRUST_BACKEND=CUDA -DCUQUANTUM_ROOT=path_to_cuQuantum -DCUTENSOR_ROOT=path_to_cuTENSOR -DAER_ENABLE_CUQUANTUM=true -DCUQUANTUM_STATIC=true -- -if you want to link cuQuantum library statically, set `CUQUANTUM_STATIC` to setup.py. -Otherwise you also have to set environmental variable LD_LIBRARY_PATH to indicate path to the cuQuantum libraries. To run with cuStateVec, set `device='GPU'` to AerSimulator option and set `cuStateVec_enable=True` to option in execute method. @@ -731,7 +739,7 @@ AER_DISABLE_GDR=True For example, - qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_MPI=True -DAER_DISABLE_GDR=True + qiskit-aer$ python ./setup.py bdist_wheel -- -DAER_MPI=True -DAER_DISABLE_GDR=True -- ### Running with multiple-GPUs and/or multiple nodes diff --git a/README.md b/README.md index d261484abc..a6f673317a 100755 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ To install from source, follow the instructions in the [contribution guidelines] ## Installing GPU support -In order to install and run the GPU supported simulators on Linux, you need CUDA® 10.1 or newer previously installed. +In order to install and run the GPU supported simulators on Linux, you need CUDA® 11.2 or newer previously installed. CUDA® itself would require a set of specific GPU drivers. Please follow CUDA® installation procedure in the NVIDIA® [web](https://www.nvidia.com/drivers). If you want to install our GPU supported simulators, you have to install this other package: @@ -29,6 +29,11 @@ If you want to install our GPU supported simulators, you have to install this ot pip install qiskit-aer-gpu ``` +The package above is for CUDA® 12, so if your system has CUDA® 11 installed, install separate package: +```bash +pip install qiskit-aer-gpu-cu11 +``` + This will overwrite your current `qiskit-aer` package installation giving you the same functionality found in the canonical `qiskit-aer` package, plus the ability to run the GPU supported simulators: statevector, density matrix, and unitary. diff --git a/constraints.txt b/constraints.txt index a0a43723c5..1f3bd7a329 100644 --- a/constraints.txt +++ b/constraints.txt @@ -1,7 +1,7 @@ pylint==2.4.4 astroid==2.3.3 six>1.10,<=1.14 -numpy>=1.16.3 +numpy>=1.16.3,<1.25 scipy>=1.0 # stevedore, used by Terra currently (as of 3.4.0) issues deprecation warnings # with modern importlib-metadata (4.8.1). importlib-metadata is only needed on diff --git a/docs/conf.py b/docs/conf.py index c82f7439e8..9982b6e135 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -45,9 +45,9 @@ author = 'Qiskit Development Team' # The short X.Y version -version = '0.12.1' +version = '0.12.2' # The full version, including alpha/beta/rc tags -release = '0.12.1' +release = '0.12.2' templates_path = ['_templates'] diff --git a/qiskit_aer/VERSION.txt b/qiskit_aer/VERSION.txt index 34a83616bb..26acbf080b 100644 --- a/qiskit_aer/VERSION.txt +++ b/qiskit_aer/VERSION.txt @@ -1 +1 @@ -0.12.1 +0.12.2 diff --git a/qiskit_aer/backends/aer_compiler.py b/qiskit_aer/backends/aer_compiler.py index eafd0e7a1c..307902e9cb 100644 --- a/qiskit_aer/backends/aer_compiler.py +++ b/qiskit_aer/backends/aer_compiler.py @@ -503,6 +503,8 @@ def assemble_circuit(circuit: QuantumCircuit): aer_circ.num_memory = num_memory aer_circ.global_phase_angle = global_phase + num_of_aer_ops = 0 + index_map = [] for inst in circuit.data: # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition @@ -522,11 +524,15 @@ def assemble_circuit(circuit: QuantumCircuit): val |= ((ctrl_val >> list(ctrl_reg).index(clbit)) & 1) << idx conditional_reg = num_memory + max_conditional_idx aer_circ.bfunc(f"0x{mask:X}", f"0x{val:X}", "==", conditional_reg) + num_of_aer_ops += 1 max_conditional_idx += 1 - _assemble_op(aer_circ, inst, qubit_indices, clbit_indices, is_conditional, conditional_reg) + num_of_aer_ops += _assemble_op( + aer_circ, inst, qubit_indices, clbit_indices, is_conditional, conditional_reg + ) + index_map.append(num_of_aer_ops - 1) - return aer_circ + return aer_circ, index_map def _assemble_op(aer_circ, inst, qubit_indices, clbit_indices, is_conditional, conditional_reg): @@ -545,6 +551,7 @@ def _assemble_op(aer_circ, inst, qubit_indices, clbit_indices, is_conditional, c copied = True params[i] = 0.0 + num_of_aer_ops = 1 # fmt: off if name in { "ccx", "ccz", "cp", "cswap", "csx", "cx", "cy", "cz", "delay", "ecr", "h", @@ -623,7 +630,7 @@ def _assemble_op(aer_circ, inst, qubit_indices, clbit_indices, is_conditional, c elif name == "superop": aer_circ.superop(qubits, params[0], conditional_reg) elif name == "barrier": - aer_circ.barrier(qubits) + num_of_aer_ops = 0 elif name == "jump": aer_circ.jump(qubits, params, conditional_reg) elif name == "mark": @@ -638,6 +645,8 @@ def _assemble_op(aer_circ, inst, qubit_indices, clbit_indices, is_conditional, c else: raise AerError(f"unknown instruction: {name}") + return num_of_aer_ops + def assemble_circuits(circuits: List[QuantumCircuit]) -> List[AerCircuit]: """converts a list of Qiskit circuits into circuits mapped AER::Circuit @@ -646,7 +655,8 @@ def assemble_circuits(circuits: List[QuantumCircuit]) -> List[AerCircuit]: circuits: circuit(s) to be converted Returns: - circuits to be run on the Aer backends + a list of circuits to be run on the Aer backends and + a list of index mapping from Qiskit instructions to Aer operations of the circuits Examples: @@ -660,6 +670,7 @@ def assemble_circuits(circuits: List[QuantumCircuit]) -> List[AerCircuit]: qc.cx(0, 1) qc.measure_all() # Generate AerCircuit from the input circuit - aer_qc_list = assemble_circuits(circuits=[qc]) + aer_qc_list, idx_maps = assemble_circuits(circuits=[qc]) """ - return [assemble_circuit(circuit) for circuit in circuits] + aer_circuits, idx_maps = zip(*[assemble_circuit(circuit) for circuit in circuits]) + return list(aer_circuits), list(idx_maps) diff --git a/qiskit_aer/backends/aerbackend.py b/qiskit_aer/backends/aerbackend.py index 859cb986da..7266572ae9 100644 --- a/qiskit_aer/backends/aerbackend.py +++ b/qiskit_aer/backends/aerbackend.py @@ -82,7 +82,7 @@ def __init__( if backend_options is not None: self.set_options(**backend_options) - def _convert_circuit_binds(self, circuit, binds): + def _convert_circuit_binds(self, circuit, binds, idx_map): parameterizations = [] def append_param_values(index, bind_pos, param): @@ -111,22 +111,22 @@ def append_param_values(index, bind_pos, param): for index, instruction in enumerate(circuit.data): if instruction.operation.is_parameterized(): for bind_pos, param in enumerate(instruction.operation.params): - append_param_values(index, bind_pos, param) + append_param_values(idx_map[index] if idx_map else index, bind_pos, param) return parameterizations - def _convert_binds(self, circuits, parameter_binds): + def _convert_binds(self, circuits, parameter_binds, idx_maps=None): if isinstance(circuits, QuantumCircuit): if len(parameter_binds) > 1: raise AerError("More than 1 parameter table provided for a single circuit") - return [self._convert_circuit_binds(circuits, parameter_binds[0])] + return [self._convert_circuit_binds(circuits, parameter_binds[0], None)] elif len(parameter_binds) != len(circuits): raise AerError( "Number of input circuits does not match number of input " "parameter bind dictionaries" ) parameterizations = [ - self._convert_circuit_binds(circuit, parameter_binds[idx]) + self._convert_circuit_binds(circuit, parameter_binds[idx], idx_maps[idx]) for idx, circuit in enumerate(circuits) ] return parameterizations @@ -236,22 +236,15 @@ def run(self, circuits, validate=False, parameter_binds=None, **run_options): def _run_circuits(self, circuits, parameter_binds, **run_options): """Run circuits by generating native circuits.""" - circuits, noise_model = self._compile(circuits, **run_options) - if parameter_binds: - run_options["parameterizations"] = self._convert_binds(circuits, parameter_binds) - elif not all([len(circuit.parameters) == 0 for circuit in circuits]): - raise AerError("circuits have parameters but parameter_binds is not specified.") - config = generate_aer_config(circuits, self.options, **run_options) - # Submit job job_id = str(uuid.uuid4()) aer_job = AerJob( self, job_id, self._execute_circuits_job, + parameter_binds=parameter_binds, circuits=circuits, - noise_model=noise_model, - config=config, + run_options=run_options, ) aer_job.submit() @@ -429,15 +422,33 @@ def _execute_qobj_job(self, qobj, job_id="", format_result=True): return self._format_results(output) return output - def _execute_circuits_job(self, circuits, noise_model, config, job_id="", format_result=True): + def _execute_circuits_job( + self, circuits, parameter_binds, run_options, job_id="", format_result=True + ): """Run a job""" # Start timer start = time.time() + # Compile circuits + circuits, noise_model = self._compile(circuits, **run_options) + + aer_circuits, idx_maps = assemble_circuits(circuits) + if parameter_binds: + run_options["parameterizations"] = self._convert_binds( + circuits, parameter_binds, idx_maps + ) + elif not all([len(circuit.parameters) == 0 for circuit in circuits]): + raise AerError("circuits have parameters but parameter_binds is not specified.") + + for circ_id, aer_circuit in enumerate(aer_circuits): + aer_circuit.circ_id = circ_id + + config = generate_aer_config(circuits, self.options, **run_options) + # Run simulation - aer_circuits = assemble_circuits(circuits) metadata_map = { - aer_circuit: circuit.metadata for aer_circuit, circuit in zip(aer_circuits, circuits) + aer_circuit.circ_id: circuit.metadata + for aer_circuit, circuit in zip(aer_circuits, circuits) } output = self._execute_circuits(aer_circuits, noise_model, config) @@ -458,7 +469,7 @@ def _execute_circuits_job(self, circuits, noise_model, config, job_id="", format for result in output["results"]: if "header" not in result: continue - result["header"]["metadata"] = metadata_map[result["circuit"]] + result["header"]["metadata"] = metadata_map[result.pop("circ_id")] # Add execution time output["time_taken"] = time.time() - start diff --git a/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp b/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp index dbfd7a8ce4..12f3eeba5a 100644 --- a/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp +++ b/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp @@ -62,6 +62,7 @@ void bind_aer_circuit(MODULE m) { return ss.str(); }); + aer_circuit.def_readwrite("circ_id", &Circuit::circ_id); aer_circuit.def_readwrite("shots", &Circuit::shots); aer_circuit.def_readwrite("num_qubits", &Circuit::num_qubits); aer_circuit.def_readwrite("num_memory", &Circuit::num_memory); diff --git a/qiskit_aer/jobs/aerjob.py b/qiskit_aer/jobs/aerjob.py index 545fbe773e..7f309a51a5 100644 --- a/qiskit_aer/jobs/aerjob.py +++ b/qiskit_aer/jobs/aerjob.py @@ -34,8 +34,8 @@ def __init__( fn, qobj=None, circuits=None, - noise_model=None, - config=None, + parameter_binds=None, + run_options=None, executor=None, ): """Initializes the asynchronous job. @@ -49,9 +49,9 @@ def __init__( qobj(QasmQobj): qobj to execute circuits(list of QuantumCircuit): circuits to execute. If `qobj` is set, this argument is ignored. - noise_model(NoiseModel): noise_model to execute. + parameter_binds(list): parameters for circuits. If `qobj` is set, this argument is ignored. - config(dict): configuration to execute. + run_options(dict): run_options to execute. If `qobj` is set, this argument is ignored. executor(ThreadPoolExecutor or dask.distributed.client): The executor to be used to submit the job. @@ -64,13 +64,13 @@ def __init__( if qobj: self._qobj = qobj self._circuits = None - self._noise_model = None - self._config = None + self._parameter_binds = None + self._run_options = None elif circuits: self._qobj = None self._circuits = circuits - self._noise_model = noise_model - self._config = config + self._parameter_binds = parameter_binds + self._run_options = run_options else: raise JobError("AerJob needs a qobj or circuits") self._executor = executor or DEFAULT_EXECUTOR @@ -90,7 +90,7 @@ def submit(self): self._future = self._executor.submit(self._fn, self._qobj, self._job_id) else: self._future = self._executor.submit( - self._fn, self._circuits, self._noise_model, self._config, self._job_id + self._fn, self._circuits, self._parameter_binds, self._run_options, self._job_id ) @requires_submit diff --git a/qiskit_aer/library/default_qubits.py b/qiskit_aer/library/default_qubits.py index df251d158d..bc446e73f9 100644 --- a/qiskit_aer/library/default_qubits.py +++ b/qiskit_aer/library/default_qubits.py @@ -13,7 +13,7 @@ Helper function """ -from qiskit.circuit import QuantumCircuit, QuantumRegister +from qiskit.circuit import QuantumRegister from qiskit.extensions.exceptions import ExtensionError @@ -38,18 +38,8 @@ def default_qubits(circuit, qubits=None): if isinstance(qubits, QuantumRegister): qubits = qubits[:] if not qubits: - tuples = [] - if isinstance(circuit, QuantumCircuit): - for register in circuit.qregs: - tuples.append(register) - if not tuples: + qubits = list(circuit.qubits) + if len(qubits) == 0: raise ExtensionError("no qubits for snapshot") - qubits = [] - for tuple_element in tuples: - if isinstance(tuple_element, QuantumRegister): - for j in range(tuple_element.size): - qubits.append(tuple_element[j]) - else: - qubits.append(tuple_element) return qubits diff --git a/releasenotes/notes/avoid_copy_of_config-7f7891864c1a1bd0.yaml b/releasenotes/notes/0.12/avoid_copy_of_config-7f7891864c1a1bd0.yaml similarity index 100% rename from releasenotes/notes/avoid_copy_of_config-7f7891864c1a1bd0.yaml rename to releasenotes/notes/0.12/avoid_copy_of_config-7f7891864c1a1bd0.yaml diff --git a/releasenotes/notes/avoid_kernel_crash_in_mac_from_blas_error-bd5b836a23f2e3ee.yaml b/releasenotes/notes/0.12/avoid_kernel_crash_in_mac_from_blas_error-bd5b836a23f2e3ee.yaml similarity index 100% rename from releasenotes/notes/avoid_kernel_crash_in_mac_from_blas_error-bd5b836a23f2e3ee.yaml rename to releasenotes/notes/0.12/avoid_kernel_crash_in_mac_from_blas_error-bd5b836a23f2e3ee.yaml diff --git a/releasenotes/notes/check_param_length-eb69cd92825bbca4.yaml b/releasenotes/notes/0.12/check_param_length-eb69cd92825bbca4.yaml similarity index 100% rename from releasenotes/notes/check_param_length-eb69cd92825bbca4.yaml rename to releasenotes/notes/0.12/check_param_length-eb69cd92825bbca4.yaml diff --git a/releasenotes/notes/check_parameter_binds_exist-9d52c665d5f94dde.yaml b/releasenotes/notes/0.12/check_parameter_binds_exist-9d52c665d5f94dde.yaml similarity index 100% rename from releasenotes/notes/check_parameter_binds_exist-9d52c665d5f94dde.yaml rename to releasenotes/notes/0.12/check_parameter_binds_exist-9d52c665d5f94dde.yaml diff --git a/releasenotes/notes/defer-backend-gathering-773d0ed8092c24d9.yaml b/releasenotes/notes/0.12/defer-backend-gathering-773d0ed8092c24d9.yaml similarity index 100% rename from releasenotes/notes/defer-backend-gathering-773d0ed8092c24d9.yaml rename to releasenotes/notes/0.12/defer-backend-gathering-773d0ed8092c24d9.yaml diff --git a/releasenotes/notes/do_not_modify_metadata-60bb4b88707bd021.yaml b/releasenotes/notes/0.12/do_not_modify_metadata-60bb4b88707bd021.yaml similarity index 100% rename from releasenotes/notes/do_not_modify_metadata-60bb4b88707bd021.yaml rename to releasenotes/notes/0.12/do_not_modify_metadata-60bb4b88707bd021.yaml diff --git a/releasenotes/notes/estimator-performance-da83a59b9fd69086.yaml b/releasenotes/notes/0.12/estimator-performance-da83a59b9fd69086.yaml similarity index 100% rename from releasenotes/notes/estimator-performance-da83a59b9fd69086.yaml rename to releasenotes/notes/0.12/estimator-performance-da83a59b9fd69086.yaml diff --git a/releasenotes/notes/estimator-variance-type-2b04ff7bcd305920.yaml b/releasenotes/notes/0.12/estimator-variance-type-2b04ff7bcd305920.yaml similarity index 100% rename from releasenotes/notes/estimator-variance-type-2b04ff7bcd305920.yaml rename to releasenotes/notes/0.12/estimator-variance-type-2b04ff7bcd305920.yaml diff --git a/releasenotes/notes/fix-cuStateVec_enable-0936f2269466e3be.yaml b/releasenotes/notes/0.12/fix-cuStateVec_enable-0936f2269466e3be.yaml similarity index 100% rename from releasenotes/notes/fix-cuStateVec_enable-0936f2269466e3be.yaml rename to releasenotes/notes/0.12/fix-cuStateVec_enable-0936f2269466e3be.yaml diff --git a/releasenotes/notes/fix-none-handling-in-noise-model-34fcc9a3e3cbdf6f.yaml b/releasenotes/notes/0.12/fix-none-handling-in-noise-model-34fcc9a3e3cbdf6f.yaml similarity index 100% rename from releasenotes/notes/fix-none-handling-in-noise-model-34fcc9a3e3cbdf6f.yaml rename to releasenotes/notes/0.12/fix-none-handling-in-noise-model-34fcc9a3e3cbdf6f.yaml diff --git a/releasenotes/notes/fix-number-qubits-a417ca6afa64264f.yaml b/releasenotes/notes/0.12/fix-number-qubits-a417ca6afa64264f.yaml similarity index 100% rename from releasenotes/notes/fix-number-qubits-a417ca6afa64264f.yaml rename to releasenotes/notes/0.12/fix-number-qubits-a417ca6afa64264f.yaml diff --git a/releasenotes/notes/fix_cuQuantum_libpath-90d24880cd9a9ea8.yaml b/releasenotes/notes/0.12/fix_cuQuantum_libpath-90d24880cd9a9ea8.yaml similarity index 100% rename from releasenotes/notes/fix_cuQuantum_libpath-90d24880cd9a9ea8.yaml rename to releasenotes/notes/0.12/fix_cuQuantum_libpath-90d24880cd9a9ea8.yaml diff --git a/releasenotes/notes/fix_cuQuantum_static-ad132d742a64a3d5.yaml b/releasenotes/notes/0.12/fix_cuQuantum_static-ad132d742a64a3d5.yaml similarity index 100% rename from releasenotes/notes/fix_cuQuantum_static-ad132d742a64a3d5.yaml rename to releasenotes/notes/0.12/fix_cuQuantum_static-ad132d742a64a3d5.yaml diff --git a/releasenotes/notes/fix_mpi_procs-68b76c11fe7a6b8e.yaml b/releasenotes/notes/0.12/fix_mpi_procs-68b76c11fe7a6b8e.yaml similarity index 100% rename from releasenotes/notes/fix_mpi_procs-68b76c11fe7a6b8e.yaml rename to releasenotes/notes/0.12/fix_mpi_procs-68b76c11fe7a6b8e.yaml diff --git a/releasenotes/notes/fix_param_binding_for_pram_circuit-50e64efbedaec8fd.yaml b/releasenotes/notes/0.12/fix_param_binding_for_pram_circuit-50e64efbedaec8fd.yaml similarity index 100% rename from releasenotes/notes/fix_param_binding_for_pram_circuit-50e64efbedaec8fd.yaml rename to releasenotes/notes/0.12/fix_param_binding_for_pram_circuit-50e64efbedaec8fd.yaml diff --git a/releasenotes/notes/fix_qobj_run-8ea657a93ce9acd2.yaml b/releasenotes/notes/0.12/fix_qobj_run-8ea657a93ce9acd2.yaml similarity index 100% rename from releasenotes/notes/fix_qobj_run-8ea657a93ce9acd2.yaml rename to releasenotes/notes/0.12/fix_qobj_run-8ea657a93ce9acd2.yaml diff --git a/releasenotes/notes/implicit_cast_for_arguments-a3c671db2fff6f17.yaml b/releasenotes/notes/0.12/implicit_cast_for_arguments-a3c671db2fff6f17.yaml similarity index 100% rename from releasenotes/notes/implicit_cast_for_arguments-a3c671db2fff6f17.yaml rename to releasenotes/notes/0.12/implicit_cast_for_arguments-a3c671db2fff6f17.yaml diff --git a/releasenotes/notes/primitives-grouping-index-bug-56f69afbdc3e86a0.yaml b/releasenotes/notes/0.12/primitives-grouping-index-bug-56f69afbdc3e86a0.yaml similarity index 100% rename from releasenotes/notes/primitives-grouping-index-bug-56f69afbdc3e86a0.yaml rename to releasenotes/notes/0.12/primitives-grouping-index-bug-56f69afbdc3e86a0.yaml diff --git a/releasenotes/notes/release_0121-eeda752822eb0ad3.yaml b/releasenotes/notes/0.12/release_0121-eeda752822eb0ad3.yaml similarity index 100% rename from releasenotes/notes/release_0121-eeda752822eb0ad3.yaml rename to releasenotes/notes/0.12/release_0121-eeda752822eb0ad3.yaml diff --git a/releasenotes/notes/support_int_initialize-8491979c4a003908.yaml b/releasenotes/notes/0.12/support_int_initialize-8491979c4a003908.yaml similarity index 100% rename from releasenotes/notes/support_int_initialize-8491979c4a003908.yaml rename to releasenotes/notes/0.12/support_int_initialize-8491979c4a003908.yaml diff --git a/releasenotes/notes/support_param_for_global_phase-704a97129e7bdbaa.yaml b/releasenotes/notes/0.12/support_param_for_global_phase-704a97129e7bdbaa.yaml similarity index 100% rename from releasenotes/notes/support_param_for_global_phase-704a97129e7bdbaa.yaml rename to releasenotes/notes/0.12/support_param_for_global_phase-704a97129e7bdbaa.yaml diff --git a/releasenotes/notes/use_omp_set_max_active_levels-7e6c1d301c4434a6.yaml b/releasenotes/notes/0.12/use_omp_set_max_active_levels-7e6c1d301c4434a6.yaml similarity index 100% rename from releasenotes/notes/use_omp_set_max_active_levels-7e6c1d301c4434a6.yaml rename to releasenotes/notes/0.12/use_omp_set_max_active_levels-7e6c1d301c4434a6.yaml diff --git a/releasenotes/notes/fix_parameter_indexing-f29f19568270d002.yaml b/releasenotes/notes/fix_parameter_indexing-f29f19568270d002.yaml new file mode 100644 index 0000000000..d09bb7500a --- /dev/null +++ b/releasenotes/notes/fix_parameter_indexing-f29f19568270d002.yaml @@ -0,0 +1,14 @@ +--- +fixes: + - | + If a circuit has conditional and parameters, the circuit was not be + correctly simulated because parameter bindings of Aer used wrong positions + to apply parameters. This is from a lack of consideration of bfunc operations + injected by conditional. With this commit, parameters are set to correct + positions with consideration of injected bfun operations. + - | + Parameters for global phases were not correctly set in #1814. + https://github.com/Qiskit/qiskit-aer/pull/1814 + Parameter values for global phases were copied to a template circuit and not to + actual circuits to be simulated. This commit correctly copies parameter values + to circuits to be simulated. diff --git a/releasenotes/notes/release_0122-3a30897b3ac2df2b.yaml b/releasenotes/notes/release_0122-3a30897b3ac2df2b.yaml new file mode 100644 index 0000000000..55e933ab74 --- /dev/null +++ b/releasenotes/notes/release_0122-3a30897b3ac2df2b.yaml @@ -0,0 +1,4 @@ +--- +prelude: > + Qiskit Aer 0.12.2 is the second patch release to 0.12.0. + This fixes some bugs that have been discovered since the release of 0.12.1. diff --git a/releasenotes/notes/remove_aer_circuit_from_metadata-e4fe09029c1a3a3c.yaml b/releasenotes/notes/remove_aer_circuit_from_metadata-e4fe09029c1a3a3c.yaml new file mode 100644 index 0000000000..9d5a5bb0ee --- /dev/null +++ b/releasenotes/notes/remove_aer_circuit_from_metadata-e4fe09029c1a3a3c.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Results of ``backend.run()`` were not serializable because they include :class:`.AerCircuit`\ s. + This commit makes the results serializable by removing :class:`.AerCircuit`\ s from metadata. diff --git a/releasenotes/notes/renew_gpu_binaries-2cf3eba0853b8407.yaml b/releasenotes/notes/renew_gpu_binaries-2cf3eba0853b8407.yaml new file mode 100644 index 0000000000..0f7ea2e44d --- /dev/null +++ b/releasenotes/notes/renew_gpu_binaries-2cf3eba0853b8407.yaml @@ -0,0 +1,19 @@ +--- +upgrade: + - | + Qiskit Aer now requires CUDA version for GPU simulator to 11.2 or + higher. Previously, CUDA 10.1 was the minimum supported version. + This change was necessary because of changes in the upstream CUDA + ecosystem, including cuQuantum support. To support users running + with different versions of CUDA there is now a separate package available + for running with CUDA 11: ``qiskit-aer-gpu-cu11`` and using the + ``qiskit-aer-gpu`` package now requires CUDA 12. If you're an existing + user of the ``qiskit-aer-gpu`` package and want to use CUDA 11 + you will need to run:: + + pip uninstall qiskit-aer-gpu && pip install -U qiskit-aer-gpu-cu11 + + to go from the previously CUDA 10.x compatible ``qiskit-aer-gpu`` + package's releases to upgrade to the new CUDA 11 compatible + package. If you're running CUDA 12 locally already you can upgrade + the ``qiskit-aer-gpu`` package as normal. diff --git a/releasenotes/notes/save_statevector_for_qasm3_circ-642ade99af3ff0d2.yaml b/releasenotes/notes/save_statevector_for_qasm3_circ-642ade99af3ff0d2.yaml new file mode 100644 index 0000000000..2db81d60ff --- /dev/null +++ b/releasenotes/notes/save_statevector_for_qasm3_circ-642ade99af3ff0d2.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + :meth:``QuantumCircuit.save_statevector()`` does not work if the circuit + is generated from OpenQASM3 text because its quantum registers have duplicated + qubit instances. With this commit, :meth:``QuantumCircuit.save_statevector()`` + uses :data:``QuantumCircuit.qubits`` to get qubits to be saved. diff --git a/requirements-dev.txt b/requirements-dev.txt index 7e21763be6..d1a45eda8b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -16,3 +16,4 @@ seaborn>=0.9.0 qiskit_sphinx_theme~=1.12.0 sphinx-design>=0.2.0 nbsphinx +qiskit_qasm3_import diff --git a/setup.py b/setup.py index d35d076c23..5e9285c208 100644 --- a/setup.py +++ b/setup.py @@ -9,8 +9,8 @@ import setuptools from skbuild import setup - PACKAGE_NAME = os.getenv("QISKIT_AER_PACKAGE_NAME", "qiskit-aer") +CUDA_MAJOR = os.getenv("QISKIT_AER_CUDA_MAJOR", "12") extras_requirements = {"dask": ["dask", "distributed"]} @@ -20,6 +20,50 @@ "scipy>=1.0", ] +classifiers = [ + "Environment :: Console", + "License :: OSI Approved :: Apache Software License", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Operating System :: Microsoft :: Windows", + "Operating System :: MacOS", + "Operating System :: POSIX :: Linux", + "Programming Language :: C++", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", +] + +if "gpu" in PACKAGE_NAME: + if "11" in CUDA_MAJOR: + requirements_cuda = [ + "nvidia-cuda-runtime-cu11>=11.8.89", + "nvidia-cublas-cu11>=11.11.3.6", + "nvidia-cusolver-cu11>=11.4.1.48", + "nvidia-cusparse-cu11>=11.7.5.86", + "cuquantum-cu11>=23.3.0", + ] + classifiers_cuda = [ + "Environment :: GPU :: NVIDIA CUDA :: 11", + ] + else: + requirements_cuda = [ + "nvidia-cuda-runtime-cu12>=12.1.105", + "nvidia-cublas-cu12>=12.1.3.1", + "nvidia-cusolver-cu12>=11.4.5.107", + "nvidia-cusparse-cu12>=12.1.0.106", + "cuquantum-cu12>=23.3.0", + ] + classifiers_cuda = [ + "Environment :: GPU :: NVIDIA CUDA :: 12", + ] + requirements.extend(requirements_cuda) + classifiers.extend(classifiers_cuda) + VERSION_PATH = os.path.join(os.path.dirname(__file__), "qiskit_aer", "VERSION.txt") with open(VERSION_PATH, "r") as version_file: VERSION = version_file.read().strip() @@ -46,23 +90,7 @@ author="AER Development Team", author_email="hello@qiskit.org", license="Apache 2.0", - classifiers=[ - "Environment :: Console", - "License :: OSI Approved :: Apache Software License", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "Operating System :: Microsoft :: Windows", - "Operating System :: MacOS", - "Operating System :: POSIX :: Linux", - "Programming Language :: C++", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Topic :: Scientific/Engineering", - ], + classifiers=classifiers, python_requires=">=3.7", install_requires=requirements, include_package_data=False, diff --git a/src/controllers/controller_execute.hpp b/src/controllers/controller_execute.hpp index 72ff1d9e17..4c2015461f 100644 --- a/src/controllers/controller_execute.hpp +++ b/src/controllers/controller_execute.hpp @@ -105,7 +105,7 @@ Result controller_execute(std::vector> &input_circs, // Validation if (instr_pos == AER::Config::GLOBAL_PHASE_POS) { // negative position is for global phase - circ->global_phase_angle = params.second[j]; + param_circ->global_phase_angle = params.second[j]; } else { if (instr_pos >= num_instr) { std::cout << "Invalid parameterization: instruction position " @@ -169,7 +169,7 @@ Result controller_execute(std::vector> &input_circs, auto ret = controller.execute(circs, noise_model, config); for (size_t i = 0; i < ret.results.size(); ++i) - ret.results[i].circuit = template_circs[i]; + ret.results[i].circ_id = template_circs[i]->circ_id; return ret; } diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index 50045996db..bc7645d694 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -36,6 +36,9 @@ class Circuit { using Op = Operations::Op; using OpType = Operations::OpType; + // circuit id + int circ_id = 0; + // Circuit operations std::vector ops; diff --git a/src/framework/qobj.hpp b/src/framework/qobj.hpp index d6cf1e32da..01084fd20e 100644 --- a/src/framework/qobj.hpp +++ b/src/framework/qobj.hpp @@ -153,7 +153,7 @@ Qobj::Qobj(const inputdata_t &input) { // Validation if (instr_pos == AER::Config::GLOBAL_PHASE_POS) { // negative position is for global phase - circuit->global_phase_angle = params.second[j]; + param_circuit->global_phase_angle = params.second[j]; } else { if (instr_pos >= num_instr) { throw std::invalid_argument( diff --git a/src/framework/results/experiment_result.hpp b/src/framework/results/experiment_result.hpp index e69a0af264..b956e5f06b 100644 --- a/src/framework/results/experiment_result.hpp +++ b/src/framework/results/experiment_result.hpp @@ -41,7 +41,7 @@ struct ExperimentResult { uint_t shots; uint_t seed; double time_taken; - std::shared_ptr circuit; + int circ_id; // Success and status Status status = Status::empty; diff --git a/src/framework/results/pybind_result.hpp b/src/framework/results/pybind_result.hpp index b9cd5fddbe..fbfcc24155 100644 --- a/src/framework/results/pybind_result.hpp +++ b/src/framework/results/pybind_result.hpp @@ -44,7 +44,7 @@ py::object AerToPy::to_python(AER::ExperimentResult &&result) { py::dict pyexperiment; pyexperiment["shots"] = result.shots; - pyexperiment["circuit"] = result.circuit; + pyexperiment["circ_id"] = result.circ_id; pyexperiment["seed_simulator"] = result.seed; pyexperiment["data"] = AerToPy::to_python(std::move(result.data)); diff --git a/test/terra/backends/aer_simulator/test_circuit.py b/test/terra/backends/aer_simulator/test_circuit.py index e5d22c16c0..cd4c0f7806 100644 --- a/test/terra/backends/aer_simulator/test_circuit.py +++ b/test/terra/backends/aer_simulator/test_circuit.py @@ -13,6 +13,7 @@ AerSimulator Integration Tests """ from math import sqrt +from copy import deepcopy from ddt import ddt import numpy as np from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister, assemble @@ -190,7 +191,7 @@ def test_metadata_protected(self): self.assertEqual(circuit.metadata["foo"], "bar") self.assertEqual(circuit.metadata["object"], object) - job.result() + deepcopy(job.result()) def test_run_qobj(self): """Test qobj run""" diff --git a/test/terra/backends/aer_simulator/test_save_statevector.py b/test/terra/backends/aer_simulator/test_save_statevector.py index c8f374a54d..d5353dc49c 100644 --- a/test/terra/backends/aer_simulator/test_save_statevector.py +++ b/test/terra/backends/aer_simulator/test_save_statevector.py @@ -13,10 +13,12 @@ Integration Tests for SaveStatevector instruction """ +import sys from ddt import ddt import qiskit.quantum_info as qi from qiskit import QuantumCircuit, transpile from test.terra.backends.simulator_test_case import SimulatorTestCase, supported_methods +from qiskit.qasm3 import dumps, loads @ddt @@ -201,3 +203,44 @@ def test_save_statevector_cache_blocking(self, method, device): self.assertIn(label, simdata) value = simdata[label] self.assertEqual(value, target) + + @supported_methods( + [ + "automatic", + "statevector", + "matrix_product_state", + "extended_stabilizer", + "tensor_network", + ] + ) + def test_save_statevector_for_qasm3_circuit(self, method, device): + """Test save statevector instruction""" + # qiskit_qasm3_import, which is used in qiskit.qasm3 does not support 3.7 + if sys.version_info < (3, 8): + return + + backend = self.backend(method=method, device=device) + + # Stabilizer test circuit + circ = QuantumCircuit(3) + circ.h(0) + circ.sdg(0) + circ.cx(0, 1) + circ.cx(0, 2) + + # Target statevector + target = qi.Statevector(circ) + + circ = loads(dumps(circ)) + + # Add save to circuit + label = "state" + circ.save_statevector(label=label) + + # Run + result = backend.run(transpile(circ, backend, optimization_level=0), shots=1).result() + self.assertTrue(result.success) + simdata = result.data(0) + self.assertIn(label, simdata) + value = simdata[label] + self.assertEqual(value, target) diff --git a/test/terra/backends/test_parameterized_qobj.py b/test/terra/backends/test_parameterized_qobj.py index f5b26bfc22..4ca2c809ca 100644 --- a/test/terra/backends/test_parameterized_qobj.py +++ b/test/terra/backends/test_parameterized_qobj.py @@ -426,6 +426,26 @@ def test_parameters_with_barrier(self): self.assertSuccess(res) self.assertEqual(res.get_counts(), {"111": 1024}) + def test_parameters_with_conditional(self): + """Test parameterized circuit path with conditional""" + backend = AerSimulator() + circuit = QuantumCircuit(3, 3) + theta = Parameter("theta") + phi = Parameter("phi") + circuit.rx(theta, 0).c_if(1, False) + circuit.rx(theta, 1).c_if(2, False) + circuit.rx(theta, 2).c_if(0, False) + circuit.rx(phi, 0) + circuit.rx(phi, 1) + circuit.rx(phi, 2) + circuit.measure_all() + + parameter_binds = [{theta: [pi / 2], phi: [pi / 2]}] + res = backend.run([circuit], shots=1024, parameter_binds=parameter_binds).result() + + self.assertSuccess(res) + self.assertEqual(res.get_counts(), {"111 000": 1024}) + def test_check_parameter_binds_exist(self): """Test parameter_binds exists to simulate parameterized circuits""" @@ -441,22 +461,28 @@ def test_check_parameter_binds_exist(self): def test_global_phase_parameters(self): """Test parameterized global phase""" - backend = AerSimulator() + backend = AerSimulator(method="extended_stabilizer") - x = Parameter("x") - circuit = QuantumCircuit(1) - circuit.u(x, x, x, [0]) - circuit.measure_all() + theta = Parameter("theta") + circ = QuantumCircuit(2) + circ.ry(theta, 0) + circ.ry(theta, 1) + circ.measure_all() - parameter_binds = [{x: [1, 2, 3]}] + circ = transpile(circ, backend) + + parameter_binds = [{theta: [1, 2, 3]}] res = backend.run( - [circuit], shots=1024, parameter_binds=parameter_binds, seed_simulator=100 + [circ], shots=10, parameter_binds=parameter_binds, seed_simulator=100 ).result() self.assertSuccess(res) - circuits = [circuit.bind_parameters({x: v}) for v in [1, 2, 3]] - expected = backend.run(circuits, shots=1024, seed_simulator=100).result() + circs = [] + for v in [1, 2, 3]: + circs.append(circ.bind_parameters({theta: v})) + + expected = backend.run(circs, shots=10, seed_simulator=100).result() self.assertEqual(res.get_counts(), expected.get_counts())