cuquantum-python-jax 0.0.2__tar.gz → 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {cuquantum_python_jax-0.0.2/cuquantum_python_jax.egg-info → cuquantum_python_jax-0.0.3}/PKG-INFO +14 -35
  2. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/README.md +10 -31
  3. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/__init__.py +7 -0
  4. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/operator_action.py +13 -9
  5. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/pysrc/operator_action.py +3 -3
  6. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/pysrc/operators.py +57 -34
  7. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3/cuquantum_python_jax.egg-info}/PKG-INFO +14 -35
  8. cuquantum_python_jax-0.0.3/cuquantum_python_jax.egg-info/requires.txt +3 -0
  9. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/setup.py +67 -19
  10. cuquantum_python_jax-0.0.2/cuquantum_python_jax.egg-info/requires.txt +0 -3
  11. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/LICENSE +0 -0
  12. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/MANIFEST.in +0 -0
  13. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/cppsrc/CMakeLists.txt +0 -0
  14. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/cppsrc/cudensitymat_jax.cpp +0 -0
  15. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/cppsrc/cudensitymat_jax.h +0 -0
  16. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/cppsrc/pybind.cpp +0 -0
  17. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/cppsrc/utils.h +0 -0
  18. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/pysrc/__init__.py +0 -0
  19. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/pysrc/base.py +0 -0
  20. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum/densitymat/jax/pysrc/context.py +0 -0
  21. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum_python_jax.egg-info/SOURCES.txt +0 -0
  22. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum_python_jax.egg-info/dependency_links.txt +0 -0
  23. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum_python_jax.egg-info/not-zip-safe +0 -0
  24. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/cuquantum_python_jax.egg-info/top_level.txt +0 -0
  25. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/pyproject.toml +0 -0
  26. {cuquantum_python_jax-0.0.2 → cuquantum_python_jax-0.0.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuquantum-python-jax
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: NVIDIA cuQuantum Python JAX
5
5
  Home-page: https://developer.nvidia.com/cuquantum-sdk
6
6
  Author: NVIDIA Corporation
@@ -16,13 +16,13 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Classifier: Programming Language :: Python :: Implementation :: CPython
18
18
  Classifier: Environment :: GPU :: NVIDIA CUDA
19
- Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
19
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 13
20
20
  Requires-Python: >=3.11.0
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
- Requires-Dist: cuquantum-python-cu12~=25.09
24
- Requires-Dist: jax[cuda12-local]<0.7,>=0.5
25
23
  Requires-Dist: pybind11
24
+ Requires-Dist: cuquantum-python-cu13~=25.11
25
+ Requires-Dist: jax[cuda13-local]<0.9,>=0.8
26
26
  Dynamic: author
27
27
  Dynamic: author-email
28
28
  Dynamic: classifier
@@ -49,18 +49,18 @@ Please visit the [NVIDIA cuQuantum Python documentation](https://docs.nvidia.com
49
49
 
50
50
  The install-time dependencies of the cuQuantum Python package include:
51
51
 
52
- * cuquantum-python-cu12~=25.09
53
- * setuptools>=77.0.3
54
- * jax[cuda12]>=0.5,<0.7 or jax[cuda12-local]>=0.5,<0.7
52
+ * cuquantum-python-cu12~=25.11 for CUDA 12 or cuquantum-python-cu13~=25.11 for CUDA 13
53
+ * jax[cuda12-local]>=0.5,<0.7 for CUDA 12 or jax[cuda13-local]>=0.8,<0.9 for CUDA 13
55
54
  * pybind11
55
+ * setuptools>=77.0.3
56
56
 
57
- Note: cuQuantum Python JAX is only supported with CUDA 12.
57
+ Note: cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13.
58
58
 
59
- #### Installation using `jax[cuda12-local]`
59
+ #### Installation using `jax[cudaXX-local]`
60
60
 
61
- `cuquantum-python-jax` depends explicitly on `jax[cuda12-local]`. `pip install cuquantum-python-jax` will install `jax[cuda12-local]`.
61
+ `cuquantum-python-jax` depends explicitly on `jax[cudaXX-local]`. `pip install cuquantum-python-jax` will install `jax[cudaXX-local]`.
62
62
 
63
- Using `jax[cuda12-local]` assumes the user provides both cuDNN and the CUDA Toolkit. cuDNN is not a part of the CUDA Toolkit and requires an additional installation. The user must also specify `LD_LIBRARY_PATH`, including the library folders containing `libcudnn.so` and `libcupti.so`.
63
+ Using `jax[cudaXX-local]` assumes the user provides both cuDNN and the CUDA Toolkit. cuDNN is not a part of the CUDA Toolkit and requires an additional installation. The user must also specify `LD_LIBRARY_PATH`, including the library folders containing `libcudnn.so` and `libcupti.so`.
64
64
 
65
65
  `libcupti.so` is provided by the CUDA Toolkit. If the CUDA Toolkit is installed under `/usr/local/cuda`, `libcupti.so` is located under `/usr/local/cuda/extras/CUPTI/lib64` and `LD_LIBRARY_PATH` should contain this path.
66
66
 
@@ -83,32 +83,11 @@ or
83
83
 
84
84
  ```
85
85
  pip install cuquantum-python-cu12[jax]
86
+ pip install cuquantum-python-cu13[jax]
86
87
  ```
87
88
 
88
89
  Note: if cuDNN and cuPTI are installed with `pip`, the user does not need to specify library folders in `LD_LIBRARY_PATH`.
89
90
 
90
- #### Installation using `jax[cuda12]`
91
-
92
- Alternatively, the user may
93
-
94
- ```
95
- pip install jax[cuda12] # install cuPTI and cuDNN together with CUDA-enabled JAX
96
- ```
97
-
98
- and either
99
-
100
- ```
101
- pip install cuquantum-python-jax
102
- ```
103
-
104
- or
105
-
106
- ```
107
- pip install cuquantum-python-cu12[jax]
108
- ```
109
-
110
- Warning: if the user has an installation of CUDA outside of `pip`, this may create conflicts and undefined behavior.
111
-
112
91
  #### Installing from source
113
92
 
114
93
  To install cuQuantum Python JAX from source, first compile cuQuantum Python from source using the [instructions on GitHub](https://github.com/NVIDIA/cuQuantum/blob/main/python/README.md). Once complete, navigate to `python/extensions`, then:
@@ -127,8 +106,8 @@ Where `CUDENSITYMAT_ROOT` is the path to the libraries parent directory. For exa
127
106
  Runtime dependencies of the cuQuantum Python package include:
128
107
 
129
108
  * An NVIDIA GPU with compute capability 7.5+
130
- * cuquantum-python-cu12~=25.09
131
- * jax[cuda12]>=0.5,<0.7 or jax[cuda12-local]>=0.5,<0.7
109
+ * cuquantum-python-cu12~=25.11 for CUDA 12 or cuquantum-python-cu13~=25.11 for CUDA 13
110
+ * jax[cuda12-local]>=0.5,<0.7 for CUDA 12 or jax[cuda13-local]>=0.8<0.9 for CUDA 13
132
111
  * pybind11
133
112
 
134
113
  ## Developer Notes
@@ -12,18 +12,18 @@ Please visit the [NVIDIA cuQuantum Python documentation](https://docs.nvidia.com
12
12
 
13
13
  The install-time dependencies of the cuQuantum Python package include:
14
14
 
15
- * cuquantum-python-cu12~=25.09
16
- * setuptools>=77.0.3
17
- * jax[cuda12]>=0.5,<0.7 or jax[cuda12-local]>=0.5,<0.7
15
+ * cuquantum-python-cu12~=25.11 for CUDA 12 or cuquantum-python-cu13~=25.11 for CUDA 13
16
+ * jax[cuda12-local]>=0.5,<0.7 for CUDA 12 or jax[cuda13-local]>=0.8,<0.9 for CUDA 13
18
17
  * pybind11
18
+ * setuptools>=77.0.3
19
19
 
20
- Note: cuQuantum Python JAX is only supported with CUDA 12.
20
+ Note: cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13.
21
21
 
22
- #### Installation using `jax[cuda12-local]`
22
+ #### Installation using `jax[cudaXX-local]`
23
23
 
24
- `cuquantum-python-jax` depends explicitly on `jax[cuda12-local]`. `pip install cuquantum-python-jax` will install `jax[cuda12-local]`.
24
+ `cuquantum-python-jax` depends explicitly on `jax[cudaXX-local]`. `pip install cuquantum-python-jax` will install `jax[cudaXX-local]`.
25
25
 
26
- Using `jax[cuda12-local]` assumes the user provides both cuDNN and the CUDA Toolkit. cuDNN is not a part of the CUDA Toolkit and requires an additional installation. The user must also specify `LD_LIBRARY_PATH`, including the library folders containing `libcudnn.so` and `libcupti.so`.
26
+ Using `jax[cudaXX-local]` assumes the user provides both cuDNN and the CUDA Toolkit. cuDNN is not a part of the CUDA Toolkit and requires an additional installation. The user must also specify `LD_LIBRARY_PATH`, including the library folders containing `libcudnn.so` and `libcupti.so`.
27
27
 
28
28
  `libcupti.so` is provided by the CUDA Toolkit. If the CUDA Toolkit is installed under `/usr/local/cuda`, `libcupti.so` is located under `/usr/local/cuda/extras/CUPTI/lib64` and `LD_LIBRARY_PATH` should contain this path.
29
29
 
@@ -46,32 +46,11 @@ or
46
46
 
47
47
  ```
48
48
  pip install cuquantum-python-cu12[jax]
49
+ pip install cuquantum-python-cu13[jax]
49
50
  ```
50
51
 
51
52
  Note: if cuDNN and cuPTI are installed with `pip`, the user does not need to specify library folders in `LD_LIBRARY_PATH`.
52
53
 
53
- #### Installation using `jax[cuda12]`
54
-
55
- Alternatively, the user may
56
-
57
- ```
58
- pip install jax[cuda12] # install cuPTI and cuDNN together with CUDA-enabled JAX
59
- ```
60
-
61
- and either
62
-
63
- ```
64
- pip install cuquantum-python-jax
65
- ```
66
-
67
- or
68
-
69
- ```
70
- pip install cuquantum-python-cu12[jax]
71
- ```
72
-
73
- Warning: if the user has an installation of CUDA outside of `pip`, this may create conflicts and undefined behavior.
74
-
75
54
  #### Installing from source
76
55
 
77
56
  To install cuQuantum Python JAX from source, first compile cuQuantum Python from source using the [instructions on GitHub](https://github.com/NVIDIA/cuQuantum/blob/main/python/README.md). Once complete, navigate to `python/extensions`, then:
@@ -90,8 +69,8 @@ Where `CUDENSITYMAT_ROOT` is the path to the libraries parent directory. For exa
90
69
  Runtime dependencies of the cuQuantum Python package include:
91
70
 
92
71
  * An NVIDIA GPU with compute capability 7.5+
93
- * cuquantum-python-cu12~=25.09
94
- * jax[cuda12]>=0.5,<0.7 or jax[cuda12-local]>=0.5,<0.7
72
+ * cuquantum-python-cu12~=25.11 for CUDA 12 or cuquantum-python-cu13~=25.11 for CUDA 13
73
+ * jax[cuda12-local]>=0.5,<0.7 for CUDA 12 or jax[cuda13-local]>=0.8<0.9 for CUDA 13
95
74
  * pybind11
96
75
 
97
76
  ## Developer Notes
@@ -2,6 +2,13 @@
2
2
  #
3
3
  # SPDX-License-Identifier: BSD-3-Clause
4
4
 
5
+ import warnings
6
+
7
+ import jax
8
+
9
+ if not jax.config.jax_enable_x64:
10
+ raise RuntimeError(f"jax_enable_x64 must be set to True to use cuQuantum Python JAX")
11
+
5
12
  from .operator_action import operator_action
6
13
  from .pysrc.operators import (
7
14
  ElementaryOperator,
@@ -19,9 +19,6 @@ from .pysrc.operator_action import (
19
19
  OperatorActionBackwardDiffPrimitive
20
20
  )
21
21
 
22
- # params are required to be float64 when passed to the cuDensityMat library.
23
- jax.config.update("jax_enable_x64", True)
24
-
25
22
  logger = logging.getLogger("cudensitymat-jax.operator_action")
26
23
 
27
24
 
@@ -62,7 +59,9 @@ def operator_action(op: Operator,
62
59
 
63
60
  # Process input arguments.
64
61
  if isinstance(state_in_bufs, jax.Array):
65
- state_in_bufs = [state_in_bufs]
62
+ state_in_bufs = (state_in_bufs,)
63
+ else:
64
+ state_in_bufs = tuple(state_in_bufs)
66
65
 
67
66
  # Check all states are of the same shape.
68
67
  state_in_shape = state_in_bufs[0].shape
@@ -71,9 +70,9 @@ def operator_action(op: Operator,
71
70
  raise ValueError("All input state buffers must have the same shape.")
72
71
 
73
72
  # Determine the state purity.
74
- if state_in_shape == op.dims:
73
+ if state_in_shape == op.dims: # state vector
75
74
  purity = cudm.StatePurity.PURE
76
- elif state_in_shape == (*op.dims, *op.dims):
75
+ elif state_in_shape == (*op.dims, *op.dims): # density matrix
77
76
  purity = cudm.StatePurity.MIXED
78
77
  else:
79
78
  raise ValueError("The dimensions of the input state do not match the dimensions of the operator.")
@@ -108,7 +107,7 @@ def operator_action(op: Operator,
108
107
  @jax.custom_vjp
109
108
  def _operator_action(op: Operator,
110
109
  t: float,
111
- state_in_bufs: Sequence[jax.Array],
110
+ state_in_bufs: Tuple[jax.Array, ...],
112
111
  params: jax.Array
113
112
  ) -> List[jax.Array]:
114
113
  """
@@ -121,7 +120,7 @@ def _operator_action(op: Operator,
121
120
 
122
121
  def _operator_action_fwd(op: Operator,
123
122
  t: float,
124
- state_in_bufs: Sequence[jax.Array],
123
+ state_in_bufs: Tuple[jax.Array, ...],
125
124
  params: jax.Array
126
125
  ) -> Tuple[List[jax.Array], tuple]:
127
126
  """
@@ -135,6 +134,9 @@ def _operator_action_fwd(op: Operator,
135
134
  def _operator_action_bwd(res: tuple, state_out_adj_bufs: jax.Array | Sequence[jax.Array]) -> tuple:
136
135
  """
137
136
  Backward rule for operator_action.
137
+
138
+ Args:
139
+ state_out_adj_bufs: Data buffers of the output state adjoint.
138
140
  """
139
141
  logger.info(f"Calling _operator_action_bwd")
140
142
 
@@ -147,7 +149,9 @@ def _operator_action_bwd(res: tuple, state_out_adj_bufs: jax.Array | Sequence[ja
147
149
 
148
150
  # Process input argument.
149
151
  if isinstance(state_out_adj_bufs, jax.Array):
150
- state_out_adj_bufs = [state_out_adj_bufs]
152
+ state_out_adj_bufs = (state_out_adj_bufs,)
153
+ else:
154
+ state_out_adj_bufs = tuple(state_out_adj_bufs)
151
155
 
152
156
  if len(state_in_bufs) != len(state_out_adj_bufs):
153
157
  raise ValueError("state_in_bufs and state_out_adj_bufs must have the same number of components.")
@@ -154,7 +154,7 @@ register_primitive(OperatorActionPrimitive)
154
154
 
155
155
  def operator_action_prim(op: Operator,
156
156
  t: float,
157
- state_in_bufs: Sequence[jax.Array],
157
+ state_in_bufs: Tuple[jax.Array, ...],
158
158
  params: jax.Array
159
159
  ) -> List[jax.Array]:
160
160
  """
@@ -308,8 +308,8 @@ register_primitive(OperatorActionBackwardDiffPrimitive)
308
308
 
309
309
  def operator_action_backward_diff_prim(op: Operator,
310
310
  t: float,
311
- state_in_bufs: Sequence[jax.Array],
312
- state_out_adj_bufs: Sequence[jax.Array],
311
+ state_in_bufs: Tuple[jax.Array, ...],
312
+ state_out_adj_bufs: Tuple[jax.Array, ...],
313
313
  params: jax.Array
314
314
  ) -> Tuple[jax.Array, ...]:
315
315
  """
@@ -254,7 +254,7 @@ class OperatorTerm:
254
254
  self.modes: List[Tuple[int, ...]] = []
255
255
  self.conjs: List[Tuple[bool, ...]] = []
256
256
  self.duals: List[Tuple[bool, ...]] = []
257
- self.coeffs: List[float] = []
257
+ self.coeffs: List[float | complex] = []
258
258
  self.coeff_callbacks: List[cudm.WrappedScalarCallback | None] = []
259
259
  self.coeff_grad_callbacks: List[cudm.WrappedScalarGradientCallback | None] = []
260
260
 
@@ -346,7 +346,7 @@ class OperatorTerm:
346
346
  modes: Sequence[int] | None = None,
347
347
  conjs: Sequence[bool] | None = None,
348
348
  duals: Sequence[bool] | None = None,
349
- coeff: float = 1.0,
349
+ coeff: float | complex = 1.0,
350
350
  coeff_callback: cudm.WrappedScalarCallback | None = None,
351
351
  coeff_grad_callback: cudm.WrappedScalarGradientCallback | None = None
352
352
  ) -> None:
@@ -356,6 +356,7 @@ class OperatorTerm:
356
356
  Args:
357
357
  op_prod: Product of elementary or matrix operators to be appended.
358
358
  modes: Modes acted on by the operator product.
359
+ conjs: Conjugations in the operator product. Only applies to MatrixOperators.
359
360
  duals: Dualities of the operator product.
360
361
  coeff: Coefficient of the operator product.
361
362
  coeff_callback: Forward callback for the coeffient.
@@ -365,54 +366,76 @@ class OperatorTerm:
365
366
  self._check_dtype(op_prod)
366
367
  self._check_and_append_op_prod_type(op_prod)
367
368
 
368
- # TODO: Check that modes have to be in dims.
369
-
369
+ # Check consistency and append modes, conjs and duals.
370
370
  if self._op_prod_types[-1] is ElementaryOperator:
371
- # Check consistency of modes.
371
+ # Modes have to specified for elementary operators.
372
372
  if modes is None:
373
373
  raise ValueError("Modes acted on must be specified for elementary operators.")
374
-
375
- # FIXME: Check dims of each elementary operator
376
- if len(modes) != len(op_prod):
377
- pass
378
- # raise ValueError(f"Number of modes acted on {len(modes)} does not match number of operator products {len(op_prod)}.")
379
-
374
+
375
+ # Check all modes are in Hilbert space.
376
+ if not set(modes) <= set(range(len(self.dims))):
377
+ raise ValueError("Modes acted on must be in the Hilbert space, i.e. between 0 and len(self.dims) - 1")
378
+
379
+ # Check length of modes acted on are the same as combined number of modes in the operator product.
380
+ if len(modes) != sum([elem_op.num_modes for elem_op in op_prod]):
381
+ raise ValueError(f"Number of modes acted on {len(modes)} does not match combined number of modes in the operator product.")
382
+
383
+ # Check mode extents of each elementary operator match corresponding qubit dimensions.
384
+ modes_index = 0
385
+ for elem_op in op_prod:
386
+ if elem_op.mode_extents != tuple(
387
+ [self.dims[modes[i]] for i in range(modes_index, modes_index + elem_op.num_modes)]
388
+ ):
389
+ raise ValueError("Mode extents of each elementary operator must match corresponding qubit dimensions.")
390
+ modes_index += elem_op.num_modes
391
+
380
392
  # Check that matrix conjugations cannot be specified for elementary operators.
381
393
  if conjs is not None:
382
394
  raise ValueError("Matrix conjugations cannot be specified for elementary operators.")
383
395
 
396
+ # Check that number of duals matches number of modes.
397
+ if duals is None:
398
+ duals = (False,) * len(modes)
399
+ else:
400
+ if len(duals) != len(modes):
401
+ raise ValueError("Number of duals must match number of modes acted on for elementary operator product.")
402
+
403
+ # For elementary operator product, we only need modes and duals.
404
+ self.modes.append(tuple(modes))
405
+ self.conjs.append(()) # empty tuple is appended here to preserve length
406
+ self.duals.append(tuple(duals))
407
+
384
408
  else: # matrix operator product
409
+ # Check that mode extents match Hilbert space dimensions.
410
+ for matrix_op in op_prod:
411
+ if matrix_op.mode_extents != self.dims:
412
+ raise ValueError("Mode extents must match Hilbert space dimensions for matrix operators.")
413
+
414
+ # Check that modes acted on cannot be specified for matrix operators.
415
+ if modes is not None:
416
+ raise ValueError("Modes acted on cannot be specified for matrix operators.")
417
+
385
418
  # Check consistency of conjs.
386
419
  if conjs is None:
387
420
  conjs = (False,) * len(op_prod)
388
421
  else:
389
- # FIXME: Check dims of each elementary operator
390
422
  if len(conjs) != len(op_prod):
391
- pass
392
- # raise ValueError("Number of matrix conjugations must match number of operator products.")
423
+ raise ValueError("Number of matrix conjugations must match number of operator products.")
393
424
 
394
- # Check that modes acted on cannot be specified for matrix operators.
395
- if modes is not None:
396
- raise ValueError("Modes acted on cannot be specified for matrix operators.")
425
+ # Check that number of duals matches number of matrix operators.
426
+ if duals is None:
427
+ duals = (False,) * len(op_prod)
428
+ else:
429
+ if len(duals) != len(op_prod):
430
+ raise ValueError("Number of duals must match number of matrix operators.")
397
431
 
398
- if duals is None:
399
- duals = (False,) * len(op_prod)
400
- else:
401
- # FIXME: Check dims of each elementary operator
402
- if len(duals) != len(op_prod):
403
- pass
404
- # raise ValueError("Number of duals must match number of operator products.")
432
+ # For matrix operator product, we only need conjs and duals.
433
+ self.modes.append(tuple(range(len(self.dims)))) # used in reference implementation during testing
434
+ self.conjs.append(tuple(conjs))
435
+ self.duals.append(tuple(duals))
405
436
 
406
437
  # Populate instance attributes.
407
438
  self.op_prods.append(tuple(op_prod))
408
- if modes is not None:
409
- self.modes.append(tuple(modes))
410
- else:
411
- # Append modes here for testing purposes.
412
- self.modes.append(tuple(range(len(self.dims))))
413
- if conjs is not None:
414
- self.conjs.append(tuple(conjs))
415
- self.duals.append(tuple(duals))
416
439
  self.coeffs.append(coeff)
417
440
  self.coeff_callbacks.append(coeff_callback)
418
441
  self.coeff_grad_callbacks.append(coeff_grad_callback)
@@ -498,7 +521,7 @@ class Operator:
498
521
 
499
522
  self.op_terms: List[OperatorTerm] = []
500
523
  self.duals: List[bool] = []
501
- self.coeffs: List[float] = []
524
+ self.coeffs: List[float | complex] = []
502
525
  self.coeff_callbacks: List[cudm.WrappedScalarCallback | None] = []
503
526
  self.coeff_grad_callbacks: List[cudm.WrappedScalarGradientCallback | None] = []
504
527
 
@@ -564,7 +587,7 @@ class Operator:
564
587
  op_term: OperatorTerm,
565
588
  *,
566
589
  dual: bool = False,
567
- coeff: float = 1.0,
590
+ coeff: float | complex = 1.0,
568
591
  coeff_callback: cudm.WrappedScalarCallback | None = None,
569
592
  coeff_grad_callback: cudm.WrappedScalarGradientCallback | None = None
570
593
  ) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cuquantum-python-jax
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: NVIDIA cuQuantum Python JAX
5
5
  Home-page: https://developer.nvidia.com/cuquantum-sdk
6
6
  Author: NVIDIA Corporation
@@ -16,13 +16,13 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Classifier: Programming Language :: Python :: Implementation :: CPython
18
18
  Classifier: Environment :: GPU :: NVIDIA CUDA
19
- Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
19
+ Classifier: Environment :: GPU :: NVIDIA CUDA :: 13
20
20
  Requires-Python: >=3.11.0
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
- Requires-Dist: cuquantum-python-cu12~=25.09
24
- Requires-Dist: jax[cuda12-local]<0.7,>=0.5
25
23
  Requires-Dist: pybind11
24
+ Requires-Dist: cuquantum-python-cu13~=25.11
25
+ Requires-Dist: jax[cuda13-local]<0.9,>=0.8
26
26
  Dynamic: author
27
27
  Dynamic: author-email
28
28
  Dynamic: classifier
@@ -49,18 +49,18 @@ Please visit the [NVIDIA cuQuantum Python documentation](https://docs.nvidia.com
49
49
 
50
50
  The install-time dependencies of the cuQuantum Python package include:
51
51
 
52
- * cuquantum-python-cu12~=25.09
53
- * setuptools>=77.0.3
54
- * jax[cuda12]>=0.5,<0.7 or jax[cuda12-local]>=0.5,<0.7
52
+ * cuquantum-python-cu12~=25.11 for CUDA 12 or cuquantum-python-cu13~=25.11 for CUDA 13
53
+ * jax[cuda12-local]>=0.5,<0.7 for CUDA 12 or jax[cuda13-local]>=0.8,<0.9 for CUDA 13
55
54
  * pybind11
55
+ * setuptools>=77.0.3
56
56
 
57
- Note: cuQuantum Python JAX is only supported with CUDA 12.
57
+ Note: cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13.
58
58
 
59
- #### Installation using `jax[cuda12-local]`
59
+ #### Installation using `jax[cudaXX-local]`
60
60
 
61
- `cuquantum-python-jax` depends explicitly on `jax[cuda12-local]`. `pip install cuquantum-python-jax` will install `jax[cuda12-local]`.
61
+ `cuquantum-python-jax` depends explicitly on `jax[cudaXX-local]`. `pip install cuquantum-python-jax` will install `jax[cudaXX-local]`.
62
62
 
63
- Using `jax[cuda12-local]` assumes the user provides both cuDNN and the CUDA Toolkit. cuDNN is not a part of the CUDA Toolkit and requires an additional installation. The user must also specify `LD_LIBRARY_PATH`, including the library folders containing `libcudnn.so` and `libcupti.so`.
63
+ Using `jax[cudaXX-local]` assumes the user provides both cuDNN and the CUDA Toolkit. cuDNN is not a part of the CUDA Toolkit and requires an additional installation. The user must also specify `LD_LIBRARY_PATH`, including the library folders containing `libcudnn.so` and `libcupti.so`.
64
64
 
65
65
  `libcupti.so` is provided by the CUDA Toolkit. If the CUDA Toolkit is installed under `/usr/local/cuda`, `libcupti.so` is located under `/usr/local/cuda/extras/CUPTI/lib64` and `LD_LIBRARY_PATH` should contain this path.
66
66
 
@@ -83,32 +83,11 @@ or
83
83
 
84
84
  ```
85
85
  pip install cuquantum-python-cu12[jax]
86
+ pip install cuquantum-python-cu13[jax]
86
87
  ```
87
88
 
88
89
  Note: if cuDNN and cuPTI are installed with `pip`, the user does not need to specify library folders in `LD_LIBRARY_PATH`.
89
90
 
90
- #### Installation using `jax[cuda12]`
91
-
92
- Alternatively, the user may
93
-
94
- ```
95
- pip install jax[cuda12] # install cuPTI and cuDNN together with CUDA-enabled JAX
96
- ```
97
-
98
- and either
99
-
100
- ```
101
- pip install cuquantum-python-jax
102
- ```
103
-
104
- or
105
-
106
- ```
107
- pip install cuquantum-python-cu12[jax]
108
- ```
109
-
110
- Warning: if the user has an installation of CUDA outside of `pip`, this may create conflicts and undefined behavior.
111
-
112
91
  #### Installing from source
113
92
 
114
93
  To install cuQuantum Python JAX from source, first compile cuQuantum Python from source using the [instructions on GitHub](https://github.com/NVIDIA/cuQuantum/blob/main/python/README.md). Once complete, navigate to `python/extensions`, then:
@@ -127,8 +106,8 @@ Where `CUDENSITYMAT_ROOT` is the path to the libraries parent directory. For exa
127
106
  Runtime dependencies of the cuQuantum Python package include:
128
107
 
129
108
  * An NVIDIA GPU with compute capability 7.5+
130
- * cuquantum-python-cu12~=25.09
131
- * jax[cuda12]>=0.5,<0.7 or jax[cuda12-local]>=0.5,<0.7
109
+ * cuquantum-python-cu12~=25.11 for CUDA 12 or cuquantum-python-cu13~=25.11 for CUDA 13
110
+ * jax[cuda12-local]>=0.5,<0.7 for CUDA 12 or jax[cuda13-local]>=0.8<0.9 for CUDA 13
132
111
  * pybind11
133
112
 
134
113
  ## Developer Notes
@@ -0,0 +1,3 @@
1
+ pybind11
2
+ cuquantum-python-cu13~=25.11
3
+ jax[cuda13-local]<0.9,>=0.8
@@ -7,6 +7,8 @@
7
7
  # versioning scheme.
8
8
 
9
9
  import os
10
+ import re
11
+ import sys
10
12
  import shutil
11
13
  import pathlib
12
14
  import subprocess
@@ -16,6 +18,45 @@ from setuptools.command.build_ext import build_ext
16
18
  from setuptools.command.bdist_wheel import bdist_wheel
17
19
 
18
20
 
21
+ try:
22
+ cuda_path = os.environ['CUDA_PATH']
23
+ except KeyError as e:
24
+ raise RuntimeError('CUDA is not found, please set $CUDA_PATH') from e
25
+
26
+
27
+ def check_cuda_version():
28
+ try:
29
+ # We cannot do a dlopen and call cudaRuntimeGetVersion, because it
30
+ # requires GPUs. We also do not want to rely on the compiler utility
31
+ # provided in distutils (deprecated) or setuptools, as this is a very
32
+ # simple string parsing task.
33
+ # TODO: switch to cudaRuntimeGetVersion once it's fixed (nvbugs 3624208)
34
+ cuda_h = os.path.join(cuda_path, 'include', 'cuda.h')
35
+ with open(cuda_h, 'r') as f:
36
+ cuda_h = f.read()
37
+ m = re.search('#define CUDA_VERSION ([0-9]*)', cuda_h)
38
+ if m:
39
+ ver = int(m.group(1))
40
+ else:
41
+ raise RuntimeError("cannot parse CUDA_VERSION")
42
+ except:
43
+ raise
44
+ else:
45
+ # 12020 -> "12.2"
46
+ return str(ver // 1000) + '.' + str((ver % 100) // 10)
47
+
48
+
49
+ # We support CUDA 12/13 starting 25.09
50
+ cuda_ver = check_cuda_version()
51
+
52
+ if '12.0' <= cuda_ver < '13.0':
53
+ cuda_major_ver = '12'
54
+ elif '13.0' <= cuda_ver < '14.0':
55
+ cuda_major_ver = '13'
56
+ else:
57
+ raise RuntimeError(f"Unsupported CUDA version: {cuda_ver}")
58
+
59
+
19
60
  class CMakeExtension(Extension):
20
61
  def __init__(self, name: str, source_dir: str = ""):
21
62
  super().__init__(name, sources=[])
@@ -75,7 +116,30 @@ description = "NVIDIA cuQuantum Python JAX"
75
116
  with open(os.path.join(os.path.dirname(__file__), "README.md"), encoding="utf-8") as f:
76
117
  long_description = f.read()
77
118
 
78
- __version__ = "0.0.2"
119
+ __version__ = "0.0.3"
120
+
121
+ classifiers=[
122
+ "Development Status :: 5 - Production/Stable",
123
+ "Operating System :: POSIX :: Linux",
124
+ "Topic :: Education",
125
+ "Topic :: Scientific/Engineering",
126
+ "Programming Language :: Python :: 3 :: Only",
127
+ "Programming Language :: Python :: 3.11",
128
+ "Programming Language :: Python :: 3.12",
129
+ "Programming Language :: Python :: 3.13",
130
+ "Programming Language :: Python :: Implementation :: CPython",
131
+ "Environment :: GPU :: NVIDIA CUDA"
132
+ ]
133
+
134
+ install_requires = ['pybind11']
135
+ if cuda_major_ver == '12':
136
+ classifiers.append("Environment :: GPU :: NVIDIA CUDA :: 12")
137
+ install_requires.append("cuquantum-python-cu12~=25.11")
138
+ install_requires.append("jax[cuda12-local]>=0.5,<0.7")
139
+ else:
140
+ classifiers.append("Environment :: GPU :: NVIDIA CUDA :: 13")
141
+ install_requires.append("cuquantum-python-cu13~=25.11")
142
+ install_requires.append("jax[cuda13-local]>=0.8,<0.9")
79
143
 
80
144
  setup(
81
145
  name="cuquantum-python-jax",
@@ -84,29 +148,13 @@ setup(
84
148
  author="NVIDIA Corporation",
85
149
  author_email="cuquantum-python@nvidia.com",
86
150
  python_requires=">=3.11.0",
87
- install_requires=[
88
- "cuquantum-python-cu12~=25.09",
89
- "jax[cuda12-local]>=0.5,<0.7",
90
- "pybind11"
91
- ],
151
+ install_requires=install_requires,
92
152
  license="BSD-3-Clause",
93
153
  license_files = ('LICENSE',),
94
154
  description=description,
95
155
  long_description=long_description,
96
156
  long_description_content_type="text/markdown",
97
- classifiers=[
98
- "Development Status :: 5 - Production/Stable",
99
- "Operating System :: POSIX :: Linux",
100
- "Topic :: Education",
101
- "Topic :: Scientific/Engineering",
102
- "Programming Language :: Python :: 3 :: Only",
103
- "Programming Language :: Python :: 3.11",
104
- "Programming Language :: Python :: 3.12",
105
- "Programming Language :: Python :: 3.13",
106
- "Programming Language :: Python :: Implementation :: CPython",
107
- "Environment :: GPU :: NVIDIA CUDA",
108
- "Environment :: GPU :: NVIDIA CUDA :: 12",
109
- ],
157
+ classifiers=classifiers,
110
158
  ext_modules=[
111
159
  CMakeExtension("cppsrc", source_dir="cuquantum/densitymat/jax/cppsrc"),
112
160
  ],
@@ -1,3 +0,0 @@
1
- cuquantum-python-cu12~=25.09
2
- jax[cuda12-local]<0.7,>=0.5
3
- pybind11