Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5255a26
fix python package install logic
mitchdz Nov 3, 2025
1ede876
* Using unified package for `nvidia-curand`
khalatepradnya Nov 4, 2025
8bebd34
Add CUDA 13 .so files to the version check (#3569)
1tnguyen Nov 4, 2025
a09b122
Use python packages throughout (#3571)
1tnguyen Nov 4, 2025
db285ea
* Refactor the logic to find CUDA libraries - use `try...catch` for e…
khalatepradnya Nov 4, 2025
130ba15
Merge branch 'main' into test-publishing
khalatepradnya Nov 4, 2025
f1fd04b
Attempt to fix metapackage_validation_conda: be explicit about conda …
1tnguyen Nov 5, 2025
8d533ca
[CI] Run Jupyter notebooks in their own virtual environment (#3577)
khalatepradnya Nov 5, 2025
7d629b5
Swap order: cublas depends on cublaslt, e.g. cublasLtGetEnvironmentMode
1tnguyen Nov 5, 2025
c2e1cbd
Merge branch 'main' into test-publishing
khalatepradnya Nov 5, 2025
ba55e63
Merge branch 'main' into test-publishing
khalatepradnya Nov 5, 2025
c79b5fd
Update publishing.yml
khalatepradnya Nov 5, 2025
a7a677b
* Also preinstall pip
khalatepradnya Nov 5, 2025
49861b6
* Remove verbose warnings
khalatepradnya Nov 5, 2025
4e057fc
installing nvidia runtime
sacpis Nov 5, 2025
7cfd28f
fixing the label for sigma
sacpis Nov 5, 2025
9c63038
* Addtional packages installed in docker image
khalatepradnya Nov 5, 2025
9079523
remove unused torch package
sacpis Nov 5, 2025
37cb34f
remove import torch
sacpis Nov 5, 2025
2e90157
Merge branch 'test-publishing' of https://github.com/NVIDIA/cuda-quan…
sacpis Nov 5, 2025
05a01ca
* Restore docs page
khalatepradnya Nov 6, 2025
2412062
removing the warning and torch geometric import
sacpis Nov 6, 2025
07c8b8d
Update the auto-generated README file to write 13.0.2 instead of 13.0.0
1tnguyen Nov 6, 2025
95135d4
Merge branch 'main' into test-publishing
khalatepradnya Nov 6, 2025
045481e
Merge branch 'main' into test-publishing
khalatepradnya Nov 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions .github/workflows/publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ jobs:
# Seems like we will need to install build-essential for resolving nbconvert issue `RuntimeError: Unsupported compiler -- at least C++11 support is needed!`"
# Given here: https://github.com/NVIDIA/cuda-quantum/blob/main/docs/sphinx/applications/python/qchem/cppe_lib.py#L18
# and https://github.com/jupyter/nbconvert/issues/1742
sudo apt-get update && sudo apt-get install build-essential python3-dev -y
sudo apt-get update && sudo apt-get install -y build-essential python3-dev python3-venv python3-pip

backends_to_test=`\
for file in $(ls $CUDA_QUANTUM_PATH/targets/*.yml); \
Expand Down Expand Up @@ -1136,7 +1136,10 @@ jobs:

strategy:
matrix:
cuda_version: ['12.4', '13.0']
# Note: this is the version of the conda 'nvidia/label/cuda' channel.
# Specifically, 'nvidia/label/cuda-13.0.0' does not contain proper CUDA 13 packages,
# hence we need to use later channels.
cuda_version_conda: ['12.4.0', '13.0.2']
fail-fast: false

# Must have environment to access environment secreats
Expand Down Expand Up @@ -1196,10 +1199,10 @@ jobs:
source validate_pycudaq.sh \
-v ${{ needs.assets.outputs.cudaq_version }} \
-i /tmp/packages -f /tmp \
-c ${{ matrix.cuda_version }} -p 3.12
-c ${{ matrix.cuda_version_conda }} -p 3.12
set -e # Re-enable exit code error checking

expected_dependency=cuda-quantum-cu$(echo ${{ matrix.cuda_version }} | cut -d . -f1)
expected_dependency=cuda-quantum-cu$(echo ${{ matrix.cuda_version_conda }} | cut -d . -f1)
if [ -z "$(python3 -m pip list | grep ${expected_dependency})" ]; then
echo "::error::Missing installation of ${expected_dependency} package."
exit 1
Expand Down
17 changes: 15 additions & 2 deletions docker/release/cudaq.ext.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,21 @@ RUN if [ -x "$(command -v pip)" ]; then \
pip install --no-cache-dir mpi4py~=3.1; \
fi; \
fi
RUN cuda_version_suffix=$(echo ${CUDA_VERSION} | tr . -) && \
pip install nvidia-curand-cu${cuda_version_suffix}
# Install CUDA Python packages based on CUDA version
RUN cuda_major_version=$(echo ${CUDA_VERSION} | cut -d . -f1) && \
if [ "$cuda_major_version" = "12" ]; then \
pip install --no-cache-dir \
nvidia-cuda-runtime-cu12 \
nvidia-cuda-nvrtc-cu12 \
nvidia-curand-cu12; \
elif [ "$cuda_major_version" = "13" ]; then \
pip install --no-cache-dir \
nvidia-cuda-runtime \
nvidia-cuda-nvrtc \
nvidia-curand; \
else \
echo "Unsupported CUDA major version: ${cuda_major_version}" && exit 1; \
fi

# Make sure that apt-get remains updated at the end!;
# If we don't do that, then apt-get will get confused when some CUDA
Expand Down
2 changes: 2 additions & 0 deletions docker/release/cudaq.wheel.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ RUN cd /cuda-quantum && \
esac

# Create the README
# Note: conda channel 13.0.0 does not contain CUDA 13 (still 12.x), so we map to 13.0.2
RUN cd cuda-quantum && cat python/README.md.in > python/README.md && \
package_name=cuda-quantum-cu$(echo ${CUDA_VERSION} | cut -d . -f1) && \
cuda_version_requirement="\>= ${CUDA_VERSION}" && \
cuda_version_conda=${CUDA_VERSION}.0 && \
cuda_version_conda=${cuda_version_conda/13.0.0/13.0.2} && \
for variable in package_name cuda_version_requirement cuda_version_conda deprecation_notice; do \
sed -i "s/.{{[ ]*$variable[ ]*}}/${!variable}/g" python/README.md; \
done && \
Expand Down
33 changes: 23 additions & 10 deletions docs/notebook_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

import time
import os
import re
import subprocess
import sys
import time
from pathlib import Path
import subprocess
from shutil import which

if which('jupyter') is None:
Expand Down Expand Up @@ -39,16 +39,19 @@ def validate(notebook_filename, available_backends):
return True


def execute(notebook_filename):
def execute(notebook_filename, jupyter_kernel=None):
notebook_filename_out = notebook_filename.replace('.ipynb',
'.nbconvert.ipynb')
try:
start_time = time.perf_counter()
subprocess.run([
cmd = [
"jupyter", "nbconvert", "--to", "notebook", "--execute",
notebook_filename
],
check=True)
]
if jupyter_kernel:
cmd.extend(["--ExecutePreprocessor.kernel_name", jupyter_kernel])

subprocess.run(cmd, check=True)
elapsed = time.perf_counter() - start_time
print(
f"Time taken for nbconvert : {elapsed:.2f} seconds for '{notebook_filename}'"
Expand Down Expand Up @@ -83,11 +86,21 @@ def print_results(success, failed, skipped=[]):


if __name__ == "__main__":
if len(sys.argv) > 1:
notebook_filenames = sys.argv[1:]
# Check for optional Jupyter kernel argument
jupyter_kernel = None
args_to_process = sys.argv[1:]

# Check if first argument is a kernel name (not a `.ipynb` file)
if args_to_process and not args_to_process[0].endswith('.ipynb'):
jupyter_kernel = args_to_process[0]
args_to_process = args_to_process[1:]

if args_to_process:
# Direct notebook file execution mode
notebook_filenames = args_to_process
notebooks_success, notebooks_failed = ([] for i in range(2))
for notebook_filename in notebook_filenames:
if (execute(notebook_filename)):
if (execute(notebook_filename, jupyter_kernel=jupyter_kernel)):
notebooks_success.append(notebook_filename)
else:
notebooks_failed.append(notebook_filename)
Expand Down Expand Up @@ -118,7 +131,7 @@ def print_results(success, failed, skipped=[]):
if not validate(notebook_filename, available_backends):
notebooks_skipped.append(base_name)
continue
if execute(notebook_filename):
if execute(notebook_filename, jupyter_kernel=jupyter_kernel):
notebooks_success.append(notebook_filename)
else:
notebooks_failed.append(notebook_filename)
Expand Down
41 changes: 15 additions & 26 deletions docs/sphinx/applications/python/quantum_pagerank.ipynb

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions docs/sphinx/examples/python/dynamics/dynamics_intro_2.ipynb

Large diffs are not rendered by default.

209 changes: 124 additions & 85 deletions python/cudaq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,97 +6,130 @@
# the terms of the Apache License 2.0 which accompanies this distribution. #
# ============================================================================ #

import sys, os, numpy, platform, multiprocessing
from ._packages import get_library_path
import multiprocessing
import os
import sys
import warnings
from pathlib import Path
from typing import Dict, List, Tuple

import numpy

from ._metadata import cuda_major
from ._packages import get_library_path

# Set the multiprocessing start method to 'spawn' if not already set
# Set the multiprocessing start method to `forkserver` if not already set
if multiprocessing.get_start_method(allow_none=True) is None:
multiprocessing.set_start_method('forkserver')


# ============================================================================ #
# CUDA Library Path Configuration
# ============================================================================ #
def _configure_cuda_library_paths() -> None:
"""
Sets the `CUDAQ_DYNLIBS` environment variable with paths to required
CUDA libraries based on the detected CUDA version.
"""
# Skip if already configured or CUDA not detected
if "CUDAQ_DYNLIBS" in os.environ or cuda_major is None:
return

# Library configuration: (package_name_template, library_filename_template)
# Common libraries
common_libs: Dict[str, Tuple[str, str]] = {
'cutensor': ('cutensor-cu{cuda_major}', 'libcutensor.so.2'),
'custatevec': ('custatevec-cu{cuda_major}', 'libcustatevec.so.1'),
'cutensornet': ('cutensornet-cu{cuda_major}', 'libcutensornet.so.2'),
'cudensitymat': ('cudensitymat-cu{cuda_major}', 'libcudensitymat.so.0'),
}

# CUDA 12 specific libraries
cuda_12_specific: Dict[str, Tuple[str, str]] = {
'curand': ('nvidia-curand-cu{cuda_major}', 'libcurand.so.10'),
'cudart':
('nvidia-cuda_runtime-cu{cuda_major}', 'libcudart.so.{cuda_major}'),
'nvrtc':
('nvidia-cuda_nvrtc-cu{cuda_major}', 'libnvrtc.so.{cuda_major}'),
'cublas': ('nvidia-cublas-cu{cuda_major}', 'libcublas.so.{cuda_major}'),
'cublaslt':
('nvidia-cublas-cu{cuda_major}', 'libcublasLt.so.{cuda_major}'),
'cusolver': ('nvidia-cusolver-cu{cuda_major}', 'libcusolver.so.11'),
'cusolvermg': ('nvidia-cusolver-cu{cuda_major}', 'libcusolverMg.so.11'),
}

# CUDA 13 specific libraries
cuda_13_specific: Dict[str, Tuple[str, str]] = {
'curand': ('nvidia-curand', 'libcurand.so.10'),
'cudart': ('nvidia-cuda_runtime', 'libcudart.so.{cuda_major}'),
'nvrtc': ('nvidia-cuda_nvrtc', 'libnvrtc.so.{cuda_major}'),
'nvrtc_builtins':
('nvidia-cuda_nvrtc', 'libnvrtc-builtins.so.{cuda_major}.0'),
'cublas': ('nvidia-cublas', 'libcublas.so.{cuda_major}'),
'cublaslt': ('nvidia-cublas', 'libcublasLt.so.{cuda_major}'),
'cusolver': ('nvidia-cusolver', 'libcusolver.so.12'),
'cusolvermg': ('nvidia-cusolver', 'libcusolverMg.so.12'),
}

# Load dependencies first
load_order: List[str] = [
'cudart', 'curand', 'nvrtc', 'nvrtc_builtins', 'cublaslt', 'cublas',
'cusolver', 'cusolvermg', 'cutensor', 'custatevec', 'cutensornet',
'cudensitymat'
]

# Select library configuration based on CUDA version
if cuda_major == 12:
lib_config = {**common_libs, **cuda_12_specific}
elif cuda_major == 13:
lib_config = {**common_libs, **cuda_13_specific}
else:
warnings.warn(f"Unsupported CUDA version {cuda_major}.", RuntimeWarning)
return

# Colon-separated list of library paths for `LinkedLibraryHolder` to load
library_paths: List[str] = []

# Attempt to load each library
for lib_name in load_order:
if lib_name not in lib_config:
continue

package_template, lib_filename_template = lib_config[lib_name]

try:
# Resolve package and library names
package_name = package_template.format(cuda_major=cuda_major)
lib_filename = lib_filename_template.format(cuda_major=cuda_major)
# Get library directory and construct full path
lib_dir = get_library_path(package_name)
lib_path = os.path.join(lib_dir, lib_filename)
# Verify the library file exists
if not os.path.isfile(lib_path):
raise FileNotFoundError(f"Library file not found: {lib_path}")

library_paths.append(lib_path)

except Exception:
continue

os.environ["CUDAQ_DYNLIBS"] = ":".join(library_paths)


# CUDAQ_DYNLIBS must be set before any other imports that would initialize
# LinkedLibraryHolder.
if not "CUDAQ_DYNLIBS" in os.environ and not cuda_major is None:
try:
if cuda_major == 12:
custatevec_libs = get_library_path(f"custatevec-cu{cuda_major}")
custatevec_path = os.path.join(custatevec_libs,
"libcustatevec.so.1")

cutensornet_libs = get_library_path(f"cutensornet-cu{cuda_major}")
cutensornet_path = os.path.join(cutensornet_libs,
"libcutensornet.so.2")

cudensitymat_libs = get_library_path(f"cudensitymat-cu{cuda_major}")
cudensitymat_path = os.path.join(cudensitymat_libs,
"libcudensitymat.so.0")

cutensor_libs = get_library_path(f"cutensor-cu{cuda_major}")
cutensor_path = os.path.join(cutensor_libs, "libcutensor.so.2")

curand_libs = get_library_path(f"nvidia-curand-cu{cuda_major}")
curand_path = os.path.join(curand_libs, "libcurand.so.10")

cudart_libs = get_library_path(
f"nvidia-cuda_runtime-cu{cuda_major}")
cudart_path = os.path.join(cudart_libs,
f"libcudart.so.{cuda_major}")

cuda_nvrtc_libs = get_library_path(
f"nvidia-cuda_nvrtc-cu{cuda_major}")
cuda_nvrtc_path = os.path.join(cuda_nvrtc_libs,
f"libnvrtc.so.{cuda_major}")

os.environ[
"CUDAQ_DYNLIBS"] = f"{custatevec_path}:{cutensornet_path}:{cudensitymat_path}:{cutensor_path}:{cudart_path}:{curand_path}:{cuda_nvrtc_path}"
else: # CUDA 13
custatevec_libs = get_library_path(f"custatevec-cu{cuda_major}")
custatevec_path = os.path.join(custatevec_libs,
"libcustatevec.so.1")

cutensornet_libs = get_library_path(f"cutensornet-cu{cuda_major}")
cutensornet_path = os.path.join(cutensornet_libs,
"libcutensornet.so.2")

cudensitymat_libs = get_library_path(f"cudensitymat-cu{cuda_major}")
cudensitymat_path = os.path.join(cudensitymat_libs,
"libcudensitymat.so.0")

cutensor_libs = get_library_path(f"cutensor-cu{cuda_major}")
cutensor_path = os.path.join(cutensor_libs, "libcutensor.so.2")

curand_libs = get_library_path(f"nvidia-curand")
curand_path = os.path.join(curand_libs, "libcurand.so.10")

cudart_libs = get_library_path(f"nvidia-cuda_runtime")
cudart_path = os.path.join(cudart_libs,
f"libcudart.so.{cuda_major}")

cuda_nvrtc_libs = get_library_path(f"nvidia-cuda_nvrtc")
cuda_nvrtc_path = os.path.join(cuda_nvrtc_libs,
f"libnvrtc.so.{cuda_major}")
cuda_nvrtc_builtin_path = os.path.join(
cuda_nvrtc_libs, f"libnvrtc-builtins.so.{cuda_major}.0")

cublas_libs = get_library_path(f"nvidia-cublas")
cublas_path = os.path.join(cublas_libs,
f"libcublas.so.{cuda_major}")
cublaslt_path = os.path.join(cublas_libs,
f"libcublasLt.so.{cuda_major}")

cusolver_libs = get_library_path(f"nvidia-cusolver")
cusolver_path = os.path.join(cusolver_libs, f"libcusolver.so.12")
cusolvermg_path = os.path.join(cusolver_libs,
f"libcusolverMg.so.12")

os.environ[
"CUDAQ_DYNLIBS"] = f"{cudart_path}:{curand_path}:{cuda_nvrtc_path}:{cuda_nvrtc_builtin_path}:{cublas_path}:{cublaslt_path}:{cusolver_path}:{cusolvermg_path}:{cutensor_path}:{custatevec_path}:{cutensornet_path}:{cudensitymat_path}"
except:
import importlib.util
package_spec = importlib.util.find_spec(f"cuda-quantum-cu{cuda_major}")
if not package_spec is None and not package_spec.loader is None:
print("Could not find a suitable cuQuantum Python package.")
pass
# `LinkedLibraryHolder`.
try:
_configure_cuda_library_paths()
except Exception:
import importlib.util
package_spec = importlib.util.find_spec(f"cuda-quantum-cu{cuda_major}")
if not package_spec is None and not package_spec.loader is None:
print("Could not find a suitable cuQuantum Python package.")
pass

# ============================================================================ #
# Module Imports
# ============================================================================ #

from .display import display_trace
from .kernel.kernel_decorator import kernel, PyKernelDecorator
Expand Down Expand Up @@ -227,6 +260,9 @@
orca = cudaq_runtime.orca


# ============================================================================ #
# Utility Functions
# ============================================================================ #
def synthesize(kernel, *args):
# Compile if necessary, no-op if already compiled
kernel.compile()
Expand Down Expand Up @@ -272,6 +308,9 @@ def __clearKernelRegistries():
from .kernels import uccsd
from .dbg import ast

# ============================================================================ #
# Command Line Argument Parsing
# ============================================================================ #
initKwargs = {}

# Look for --target=<target> options
Expand Down
2 changes: 2 additions & 0 deletions python/metapackages/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def _get_cuda_version() -> Optional[int]:

# Try to detect version from NVRTC
libnames = [
'libnvrtc.so.13',
'libnvrtc.so.12',
'libnvrtc.so.11.2',
'libnvrtc.so.11.1',
Expand All @@ -87,6 +88,7 @@ def _get_cuda_version() -> Optional[int]:

# Try to detect version from CUDART (a CUDA context will be initialized)
libnames = [
'libcudart.so.13',
'libcudart.so.12',
'libcudart.so.11.0',
]
Expand Down
Loading
Loading