Skip to content

Commit

Permalink
Merge branch 'release-v24.03' into 'main'
Browse files Browse the repository at this point in the history
Release v24.03

See merge request cuda-hpc-libraries/cuquantum-sdk/cuquantum-public!26
  • Loading branch information
mtjrider committed Mar 26, 2024
2 parents 2ac5645 + eacdc0e commit 788c048
Show file tree
Hide file tree
Showing 104 changed files with 14,133 additions and 8,537 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

BSD-3-Clause

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES.
Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES.

BSD-3-Clause

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/cuquantum_benchmarks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
#
# SPDX-License-Identifier: BSD-3-Clause

__version__ = '0.3.1'
__version__ = '0.3.2'
13 changes: 10 additions & 3 deletions benchmarks/cuquantum_benchmarks/backends/backend_qiskit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

Expand Down Expand Up @@ -43,7 +43,11 @@ def __init__(self, ngpus, ncpu_threads, precision, *args, identifier=None, **kwa
def find_version(self, identifier):
if identifier == 'cusvaer':
return version('cusvaer')
return qiskit.__qiskit_version__['qiskit-aer']

if hasattr(qiskit_aer, "__version__"):
return qiskit_aer.__version__
else:
return qiskit.__qiskit_version__['qiskit-aer']

def preprocess_circuit(self, circuit, *args, **kwargs):
if _internal_utils is not None:
Expand Down Expand Up @@ -77,7 +81,10 @@ def create_aer_backend(self, identifier, ngpus, ncpu_threads, *args, **kwargs):
try:
# we defer importing Aer as late as possible, due to a bug it has that
# could init all GPUs prematurely
from qiskit.providers.aer import AerSimulator
if hasattr(qiskit, "__version__") and qiskit.__version__ >= "1.0.0":
from qiskit_aer import AerSimulator
else:
from qiskit.providers.aer import AerSimulator
except ImportError as e:
raise RuntimeError("qiskit-aer (or qiskit-aer-gpu) is not installed") from e

Expand Down
9 changes: 6 additions & 3 deletions benchmarks/cuquantum_benchmarks/frontends/frontend_qiskit.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

from math import pi

try:
import qiskit
from qiskit.extensions import UnitaryGate
if hasattr(qiskit, "__version__") and qiskit.__version__ >= "1.0.0":
from qiskit.circuit.library import UnitaryGate
else:
from qiskit.extensions import UnitaryGate
except ImportError:
qiskit = UnitaryGate = None

Expand Down Expand Up @@ -35,7 +38,7 @@ def generateCircuit(self, gateSeq):
circuit.x(g.targets)

elif g.id == 'cnot':
circuit.cnot(g.controls, g.targets)
circuit.cx(g.controls, g.targets)

elif g.id == 'cz':
circuit.cz(g.controls, g.targets)
Expand Down
7 changes: 5 additions & 2 deletions benchmarks/cuquantum_benchmarks/run_interface.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

Expand Down Expand Up @@ -206,7 +206,10 @@ def _fix_filename_for_cutn(self, circuit_filename, nqubits):
def extract_frontend_version(self):
if self.frontend == 'qiskit':
import qiskit
version = qiskit.__qiskit_version__['qiskit-terra']
if hasattr(qiskit, "__version__") and qiskit.__version__ >= "1.0.0":
version = qiskit.__version__
else:
version = qiskit.__qiskit_version__['qiskit-terra']
elif self.frontend == 'cirq':
import cirq
version = cirq.__version__
Expand Down
2 changes: 1 addition & 1 deletion python/LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

BSD-3-Clause

Expand Down
44 changes: 7 additions & 37 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,18 @@

Please visit the [NVIDIA cuQuantum Python documentation](https://docs.nvidia.com/cuda/cuquantum/latest/python).

For instructions on installing *cuQuantum Python*, refer to our
[getting started section](../getting_started/getting_started.rst)

## Installation
## Building and installing cuQuantum Python from source

### Install cuQuantum Python from conda-forge

If you already have a Conda environment set up, it is the easiest to install cuQuantum Python from the conda-forge channel:
```
conda install -c conda-forge cuquantum-python
```
The Conda solver will install all required dependencies for you. If you need to select a particular CUDA version, say CUDA 12.0, please issue the following command:
```
conda install -c conda-forge cuquantum-python cuda-version=12.0
```

### Install cuQuantum Python from PyPI

Alternatively, assuming you already have a Python environment set up (it doesn't matter if it's a Conda env or not),
you can also install cuQuantum Python this way:

```
pip install cuquantum-python-cuXX
```
with `XX` being `11` (for CUDA 11) or `12` (for CUDA 12).
The `pip` solver will also install all required dependencies for you (including both cuTENSOR and cuQuantum wheels).

Notes:

- Users can install cuQuantum Python using `pip install --no-cache-dir cuquantum-python`, which will attempt to detect the current CUDA environment and choose the appropriate wheel to install. In the event of detection failure, CUDA 11 is assumed. This is subject to change in the future. Installing wheels with the `-cuXX` suffix is encouraged. `--no-cache-dir` is required when using `pip` 23.1+.
- CuPy also uses a similar auto-detection mechanism to determine the correct wheel to install. If in doubt, or if installing `cuquantum-python-cu11`, please follow [CuPy's installation guide](https://docs.cupy.dev/en/stable/install.html) and install it manually.
- To manually manage all Python dependencies, append `--no-deps` to `pip install` to bypass the `pip` solver, see below.

### Building and installing cuQuantum Python from source

#### Requirements
### Requirements

The build-time dependencies of the cuQuantum Python package include:

* CUDA Toolkit 11.x or 12.x
* cuStateVec 1.4.0+
* cuTensorNet 2.2.0+
* cuTENSOR 1.6.1+
* cuTensorNet 2.4.0+
* Python 3.9+
* Cython >=0.29.22,<3
* pip 21.3.1+
Expand Down Expand Up @@ -86,11 +57,10 @@ Runtime dependencies of the cuQuantum Python package include:
* Driver: Linux (450.80.02+ for CUDA 11, 525.60.13+ for CUDA 12)
* CUDA Toolkit 11.x or 12.x
* cuStateVec 1.4.0+
* cuTensorNet 2.2.0+
* cuTENSOR 1.6.1+
* cuTensorNet 2.4.0+
* Python 3.9+
* NumPy v1.21+
* CuPy v10.0.0+ (see [installation guide](https://docs.cupy.dev/en/stable/install.html))
* CuPy v13.0.0+ (see [installation guide](https://docs.cupy.dev/en/stable/install.html))
* PyTorch v1.10+ (optional, see [installation guide](https://pytorch.org/get-started/locally/))
* Qiskit v0.24.0+ (optional, see [installation guide](https://qiskit.org/documentation/getting_started.html))
* Cirq v0.6.0+ (optional, see [installation guide](https://quantumai.google/cirq/install))
Expand Down
6 changes: 3 additions & 3 deletions python/builder/pep517.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

Expand Down Expand Up @@ -30,8 +30,8 @@ def get_requires_for_build_wheel(config_settings=None):
# set up version constraints: note that CalVer like 22.03 is normalized to
# 22.3 by setuptools, so we must follow the same practice in the constraints;
# also, we don't need the patch number here
cuqnt_require = [f'custatevec-cu{utils.cuda_major_ver}~=1.5', # ">=1.5.0,<2"
f'cutensornet-cu{utils.cuda_major_ver}~=2.3', # ">=2.3.0,<3"
cuqnt_require = [f'custatevec-cu{utils.cuda_major_ver}~=1.6', # ">=1.6.0,<2"
f'cutensornet-cu{utils.cuda_major_ver}~=2.4', # ">=2.4.0,<3"
]

return _build_meta.get_requires_for_build_wheel(config_settings) + cuqnt_require
Expand Down
72 changes: 30 additions & 42 deletions python/builder/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

Expand Down Expand Up @@ -79,7 +79,7 @@ def run(self):
class build_ext(_build_ext):

def _set_library_roots(self):
custatevec_root = cutensornet_root = cutensor_root = None
custatevec_root = cutensornet_root = cuquantum_root = None
# Note that we need sys.path because of build isolation (since PEP 517)
py_paths = sys.path + [site.getusersitepackages()] + site.getsitepackages()

Expand All @@ -102,83 +102,71 @@ def _set_library_roots(self):
if cuquantum_root is None:
raise RuntimeError('cuStateVec is not found, please set $CUQUANTUM_ROOT '
'or $CUSTATEVEC_ROOT') from e
else:
custatevec_root = cuquantum_root
try:
cutensornet_root = os.environ['CUTENSORNET_ROOT']
except KeyError as e:
if cuquantum_root is None:
raise RuntimeError('cuTensorNet is not found, please set $CUQUANTUM_ROOT '
'or $CUTENSORNET_ROOT') from e
else:
cutensornet_root = cuquantum_root

return custatevec_root, cutensornet_root
return custatevec_root, cutensornet_root, cuquantum_root

def _prep_includes_libs_rpaths(self):
"""
Set global vars cusv_incl_dir, cutn_incl_dir, cusv_lib_dir, cutn_lib_dir,
cusv_lib, cutn_lib, and extra_linker_flags.
Set global vars cusv_incl_dir, cutn_incl_dir, and extra_linker_flags.
With the new bindings, we no longer need to link to cuQuantum DSOs.
"""
custatevec_root, cutensornet_root = self._set_library_roots()

global cusv_incl_dir, cutn_incl_dir
cusv_incl_dir = [os.path.join(cuda_path, 'include'),
os.path.join(custatevec_root, 'include')]
cutn_incl_dir = [os.path.join(cuda_path, 'include'),
os.path.join(cutensornet_root, 'include')]

global cusv_lib_dir, cutn_lib_dir
# we include both lib64 and lib to accommodate all possible sources
cusv_lib_dir = [os.path.join(custatevec_root, 'lib'),
os.path.join(custatevec_root, 'lib64')]
cutn_lib_dir = [os.path.join(cutensornet_root, 'lib'),
os.path.join(cutensornet_root, 'lib64')]

global cusv_lib, cutn_lib, extra_linker_flags
custatevec_root, cutensornet_root, cuquantum_root = self._set_library_roots()

global cusv_incl_dir, cutn_incl_dir, cuqnt_incl_dir
cusv_incl_dir = cutn_incl_dir = cuqnt_incl_dir = None
base_incl_dir = (os.path.join(cuda_path, 'include'),)
if cuquantum_root is not None:
cuqnt_incl_dir = base_incl_dir + (os.path.join(cuquantum_root, 'include'),)
if custatevec_root is not None:
cusv_incl_dir = base_incl_dir + (os.path.join(custatevec_root, 'include'),)
if cutensornet_root is not None:
cutn_incl_dir = base_incl_dir + (os.path.join(cutensornet_root, 'include'),)

global extra_linker_flags
if not building_wheel:
# Note: with PEP-517 the editable mode would not build a wheel for installation
# (and we purposely do not support PEP-660).
cusv_lib = ['custatevec']
cutn_lib = ['cutensornet']
extra_linker_flags = []
else:
# Note: soname = library major version
# We don't need to link to cuBLAS/cuSOLVER/cuTensor at build time
cusv_lib = [':libcustatevec.so.1']
cutn_lib = [':libcutensornet.so.2']
# The rpaths must be adjusted given the following full-wheel installation:
# - cuquantum-python: site-packages/cuquantum/{custatevec, cutensornet}/ [=$ORIGIN]
# - cuquantum-python: site-packages/cuquantum/{custatevec, cutensornet}/_internal/ [=$ORIGIN]
# - cusv & cutn: site-packages/cuquantum/lib/
# - cutensor: site-packages/cutensor/lib/
# - cublas: site-packages/nvidia/cublas/lib/
# - cusolver: site-packages/nvidia/cusolver/lib/
# (Note that starting v22.11 we use the new wheel format, so all lib wheels have suffix -cuXX,
# and cuBLAS/cuSOLVER additionally have prefix nvidia-.)
ldflag = "-Wl,--disable-new-dtags,"
ldflag += "-rpath,$ORIGIN/../lib,"
ldflag += "-rpath,$ORIGIN/../../cutensor/lib,"
ldflag += "-rpath,$ORIGIN/../../nvidia/cublas/lib,"
ldflag += "-rpath,$ORIGIN/../../nvidia/cusolver/lib"
ldflag += "-rpath,$ORIGIN/../../lib,"
ldflag += "-rpath,$ORIGIN/../../../cutensor/lib,"
ldflag += "-rpath,$ORIGIN/../../../nvidia/cublas/lib,"
ldflag += "-rpath,$ORIGIN/../../../nvidia/cusolver/lib"
extra_linker_flags = [ldflag]

print("\n"+"*"*80)
print("CUDA version:", cuda_ver)
print("CUDA path:", cuda_path)
print("cuStateVec path:", custatevec_root)
print("cuTensorNet path:", cutensornet_root)
print("cuStateVec path:", custatevec_root if custatevec_root else cuquantum_root)
print("cuTensorNet path:", cutensornet_root if cutensornet_root else cuquantum_root)
print("*"*80+"\n")

def build_extension(self, ext):
ext.include_dirs = ()
for include_dir in (cusv_incl_dir, cutn_incl_dir, cuqnt_incl_dir):
if include_dir is not None:
ext.include_dirs += include_dir
if ext.name.endswith("custatevec"):
ext.include_dirs = cusv_incl_dir
ext.library_dirs = cusv_lib_dir
ext.libraries = cusv_lib
ext.extra_link_args = extra_linker_flags
elif ext.name.endswith("cutensornet"):
ext.include_dirs = cutn_incl_dir
ext.library_dirs = cutn_lib_dir
ext.libraries = cutn_lib
ext.extra_link_args = extra_linker_flags

super().build_extension(ext)
Expand Down
6 changes: 3 additions & 3 deletions python/cuquantum/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

Expand All @@ -7,7 +7,7 @@
from cuquantum.cutensornet import (
contract, contract_path, einsum, einsum_path, tensor, tensor_qualifiers_dtype, Network, BaseCUDAMemoryManager, MemoryPointer,
NetworkOptions, OptimizerInfo, OptimizerOptions, PathFinderOptions, ReconfigOptions, SlicerOptions, CircuitToEinsum)
from cuquantum.utils import ComputeType, cudaDataType, libraryPropertyType
from cuquantum._utils import ComputeType, cudaDataType, libraryPropertyType
from cuquantum._version import __version__


Expand Down Expand Up @@ -43,4 +43,4 @@
):
cutensornet._internal.enum_utils.add_enum_class_doc(enum, chomp="_ATTRIBUTE|_PREFERENCE_ATTRIBUTE")

del enum, utils
del enum
13 changes: 10 additions & 3 deletions python/cuquantum/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2021-2023, NVIDIA CORPORATION & AFFILIATES
# Copyright (c) 2021-2024, NVIDIA CORPORATION & AFFILIATES
#
# SPDX-License-Identifier: BSD-3-Clause

Expand All @@ -7,14 +7,21 @@
import site
import sys

import cuquantum # get the shared libraries loaded


def get_lib_path(name):
"""Get the loaded shared library path."""
# Ideally we should call dl_iterate_phdr or dladdr to do the job, but this
# is simpler and not bad; the former two are not strictly portable anyway
# (not part of POSIX). Obviously this only works on Linux!

# We have switched to use dlopen, force library loading via internal API
if "custatevec" in name:
from cuquantum import custatevec as cusv
cusv._internal.custatevec._inspect_function_pointers()
elif "cutensor" in name: # cutensor or cutensornet
from cuquantum import cutensornet as cutn
cutn._internal.cutensornet._inspect_function_pointers()

try:
with open('/proc/self/maps') as f:
lib_map = f.read()
Expand Down
Loading

0 comments on commit 788c048

Please sign in to comment.