cuquantum-python-jax-cu13 0.0.6__tar.gz → 0.0.7__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.
- {cuquantum_python_jax_cu13-0.0.6/cuquantum_python_jax_cu13.egg-info → cuquantum_python_jax_cu13-0.0.7}/PKG-INFO +11 -8
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/README.md +9 -6
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/__init__.py +2 -9
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/cppsrc/cudensitymat.h +166 -26
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/operator_action.py +61 -30
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/pysrc/__init__.py +1 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/pysrc/base.py +0 -8
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/pysrc/context.py +17 -2
- cuquantum_python_jax_cu13-0.0.7/cuquantum/densitymat/jax/pysrc/elementary_operator.py +474 -0
- cuquantum_python_jax_cu13-0.0.7/cuquantum/densitymat/jax/pysrc/matrix_operator.py +387 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/pysrc/operator.py +156 -66
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/pysrc/operator_action_prim.py +134 -46
- cuquantum_python_jax_cu13-0.0.7/cuquantum/densitymat/jax/pysrc/operator_term.py +1138 -0
- cuquantum_python_jax_cu13-0.0.7/cuquantum/densitymat/jax/pysrc/simplifier_config.py +112 -0
- cuquantum_python_jax_cu13-0.0.7/cuquantum/densitymat/jax/utils.py +858 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/__init__.py +0 -10
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/cppsrc/CMakeLists.txt +0 -1
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/cppsrc/custabilizer.h +229 -8
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/pysrc/_ffi.py +30 -4
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7/cuquantum_python_jax_cu13.egg-info}/PKG-INFO +11 -8
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum_python_jax_cu13.egg-info/SOURCES.txt +1 -0
- cuquantum_python_jax_cu13-0.0.7/cuquantum_python_jax_cu13.egg-info/requires.txt +2 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/pyproject.toml +2 -2
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/pyproject.toml.template +2 -2
- cuquantum_python_jax_cu13-0.0.6/cuquantum/densitymat/jax/pysrc/elementary_operator.py +0 -259
- cuquantum_python_jax_cu13-0.0.6/cuquantum/densitymat/jax/pysrc/matrix_operator.py +0 -200
- cuquantum_python_jax_cu13-0.0.6/cuquantum/densitymat/jax/pysrc/operator_term.py +0 -487
- cuquantum_python_jax_cu13-0.0.6/cuquantum/densitymat/jax/utils.py +0 -399
- cuquantum_python_jax_cu13-0.0.6/cuquantum_python_jax_cu13.egg-info/requires.txt +0 -2
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/LICENSE +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/MANIFEST.in +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/NV.LICENSE +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/configure.sh +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/_build_info.py +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/cppsrc/CMakeLists.txt +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/cppsrc/cudensitymat_jax.cpp +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/cppsrc/cudensitymat_jax.h +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/cppsrc/pybind.cpp +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/densitymat/jax/cppsrc/utils.h +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/_build_info.py +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/cppsrc/custabilizer_jax.cpp +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/cppsrc/custabilizer_jax.h +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/cppsrc/pybind.cpp +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/pysrc/__init__.py +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum/stabilizer/jax/pysrc/_backend.py +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum_python_jax_cu13.egg-info/dependency_links.txt +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum_python_jax_cu13.egg-info/not-zip-safe +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/cuquantum_python_jax_cu13.egg-info/top_level.txt +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/setup.cfg +0 -0
- {cuquantum_python_jax_cu13-0.0.6 → cuquantum_python_jax_cu13-0.0.7}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cuquantum-python-jax-cu13
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
4
4
|
Summary: NVIDIA cuQuantum Python JAX
|
|
5
5
|
Author-email: NVIDIA Corporation <cuquantum-python@nvidia.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -21,13 +21,13 @@ Requires-Python: >=3.11.0
|
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
23
|
License-File: NV.LICENSE
|
|
24
|
-
Requires-Dist: cuquantum-python-cu13~=26.
|
|
24
|
+
Requires-Dist: cuquantum-python-cu13~=26.9.0
|
|
25
25
|
Requires-Dist: jax[cuda13-local]>=0.8
|
|
26
26
|
Dynamic: license-file
|
|
27
27
|
|
|
28
28
|
# cuQuantum Python JAX
|
|
29
29
|
|
|
30
|
-
cuQuantum Python JAX provides a JAX extension for cuQuantum Python. It exposes selected
|
|
30
|
+
cuQuantum Python JAX provides a JAX extension for cuQuantum Python. It exposes selected functionalities of cuQuantum SDK in a JAX-compatible way that enables JAX frameworks to directly interface with the exposed cuQuantum API. In the current release, cuQuantum JAX exposes JAX interfaces to the Operator Action API from the cuDensityMat library and the GF(2) sparse-dense matrix multiplication from the cuStabilizer library.
|
|
31
31
|
|
|
32
32
|
## Documentation
|
|
33
33
|
|
|
@@ -39,15 +39,17 @@ Please visit the [NVIDIA cuQuantum Python documentation](https://docs.nvidia.com
|
|
|
39
39
|
|
|
40
40
|
The build-time dependencies of the cuQuantum Python JAX package include:
|
|
41
41
|
|
|
42
|
+
* Python 3.11+
|
|
42
43
|
* CUDA Toolkit 12.x or 13.x
|
|
43
|
-
*
|
|
44
|
+
* cmake>=3.22
|
|
45
|
+
* jax[cuda12-local]>=0.8 for CUDA 12 or jax[cuda13-local]>=0.8 for CUDA 13
|
|
44
46
|
* pybind11
|
|
45
47
|
* wheel
|
|
46
48
|
* setuptools>=77.0.3
|
|
47
49
|
|
|
48
50
|
Note:
|
|
49
|
-
- cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13.
|
|
50
|
-
-
|
|
51
|
+
- cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13 and the distributions are CUDA-versioned: `cuquantum-python-jax-cu12` for CUDA 12 and `cuquantum-python-jax-cu13` for CUDA 13.
|
|
52
|
+
- **Build isolation note:** When installing with build isolation (`pip`'s default mode), the JAX version used at build time is determined by the build dependency specification in `pyproject.toml` and may differ from the JAX version pre-installed in the environment. Mismatched build-time and runtime JAX versions can lead to errors when importing cuQuantum's JAX extension. We recommend passing `--no-build-isolation` to `pip install` and pre-installing all build dependencies manually.
|
|
51
53
|
|
|
52
54
|
#### Installation using `jax[cudaXX-local]`
|
|
53
55
|
|
|
@@ -101,10 +103,11 @@ The CUDA version is detected automatically from `$CUDA_PATH` and the wheel will
|
|
|
101
103
|
|
|
102
104
|
Runtime dependencies of the cuQuantum Python JAX package include:
|
|
103
105
|
|
|
106
|
+
* Python 3.11+
|
|
104
107
|
* An NVIDIA GPU with compute capability 7.5+
|
|
105
108
|
* CUDA Toolkit 12.x or 13.x
|
|
106
|
-
* cuquantum-python-cu12~=26.
|
|
107
|
-
* jax[cuda12-local]>=0.
|
|
109
|
+
* cuquantum-python-cu12~=26.9.0 for CUDA 12 or cuquantum-python-cu13~=26.9.0 for CUDA 13
|
|
110
|
+
* jax[cuda12-local]>=0.8 for CUDA 12 or jax[cuda13-local]>=0.8 for CUDA 13
|
|
108
111
|
|
|
109
112
|
## Developer Notes
|
|
110
113
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# cuQuantum Python JAX
|
|
2
2
|
|
|
3
|
-
cuQuantum Python JAX provides a JAX extension for cuQuantum Python. It exposes selected
|
|
3
|
+
cuQuantum Python JAX provides a JAX extension for cuQuantum Python. It exposes selected functionalities of cuQuantum SDK in a JAX-compatible way that enables JAX frameworks to directly interface with the exposed cuQuantum API. In the current release, cuQuantum JAX exposes JAX interfaces to the Operator Action API from the cuDensityMat library and the GF(2) sparse-dense matrix multiplication from the cuStabilizer library.
|
|
4
4
|
|
|
5
5
|
## Documentation
|
|
6
6
|
|
|
@@ -12,15 +12,17 @@ Please visit the [NVIDIA cuQuantum Python documentation](https://docs.nvidia.com
|
|
|
12
12
|
|
|
13
13
|
The build-time dependencies of the cuQuantum Python JAX package include:
|
|
14
14
|
|
|
15
|
+
* Python 3.11+
|
|
15
16
|
* CUDA Toolkit 12.x or 13.x
|
|
16
|
-
*
|
|
17
|
+
* cmake>=3.22
|
|
18
|
+
* jax[cuda12-local]>=0.8 for CUDA 12 or jax[cuda13-local]>=0.8 for CUDA 13
|
|
17
19
|
* pybind11
|
|
18
20
|
* wheel
|
|
19
21
|
* setuptools>=77.0.3
|
|
20
22
|
|
|
21
23
|
Note:
|
|
22
|
-
- cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13.
|
|
23
|
-
-
|
|
24
|
+
- cuQuantum Python JAX is only supported with CUDA 12 and CUDA 13 and the distributions are CUDA-versioned: `cuquantum-python-jax-cu12` for CUDA 12 and `cuquantum-python-jax-cu13` for CUDA 13.
|
|
25
|
+
- **Build isolation note:** When installing with build isolation (`pip`'s default mode), the JAX version used at build time is determined by the build dependency specification in `pyproject.toml` and may differ from the JAX version pre-installed in the environment. Mismatched build-time and runtime JAX versions can lead to errors when importing cuQuantum's JAX extension. We recommend passing `--no-build-isolation` to `pip install` and pre-installing all build dependencies manually.
|
|
24
26
|
|
|
25
27
|
#### Installation using `jax[cudaXX-local]`
|
|
26
28
|
|
|
@@ -74,10 +76,11 @@ The CUDA version is detected automatically from `$CUDA_PATH` and the wheel will
|
|
|
74
76
|
|
|
75
77
|
Runtime dependencies of the cuQuantum Python JAX package include:
|
|
76
78
|
|
|
79
|
+
* Python 3.11+
|
|
77
80
|
* An NVIDIA GPU with compute capability 7.5+
|
|
78
81
|
* CUDA Toolkit 12.x or 13.x
|
|
79
|
-
* cuquantum-python-cu12~=26.
|
|
80
|
-
* jax[cuda12-local]>=0.
|
|
82
|
+
* cuquantum-python-cu12~=26.9.0 for CUDA 12 or cuquantum-python-cu13~=26.9.0 for CUDA 13
|
|
83
|
+
* jax[cuda12-local]>=0.8 for CUDA 12 or jax[cuda13-local]>=0.8 for CUDA 13
|
|
81
84
|
|
|
82
85
|
## Developer Notes
|
|
83
86
|
|
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
4
4
|
|
|
5
|
-
from cuquantum.bindings._internal import cudensitymat as _cudm
|
|
6
|
-
_cudm._inspect_function_pointers() # for loading libcudensitymat.so
|
|
7
|
-
|
|
8
|
-
import jax
|
|
9
|
-
|
|
10
5
|
try:
|
|
11
6
|
from ._build_info import check_jax_abi as _check_jax_abi
|
|
12
7
|
except ImportError:
|
|
@@ -15,13 +10,11 @@ else:
|
|
|
15
10
|
_check_jax_abi()
|
|
16
11
|
del _check_jax_abi
|
|
17
12
|
|
|
18
|
-
if not jax.config.jax_enable_x64:
|
|
19
|
-
raise RuntimeError("jax_enable_x64 must be set to True to use cuQuantum Python JAX")
|
|
20
|
-
|
|
21
13
|
from .operator_action import operator_action
|
|
22
14
|
from .pysrc import (
|
|
23
15
|
ElementaryOperator,
|
|
24
16
|
MatrixOperator,
|
|
25
17
|
OperatorTerm,
|
|
26
|
-
Operator
|
|
18
|
+
Operator,
|
|
19
|
+
SimplifierConfig
|
|
27
20
|
)
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
// LIBRARY VERSION
|
|
64
64
|
|
|
65
65
|
#define CUDENSITYMAT_MAJOR 0 //!< cuDensityMat major version.
|
|
66
|
-
#define CUDENSITYMAT_MINOR
|
|
66
|
+
#define CUDENSITYMAT_MINOR 7 //!< cuDensityMat minor version.
|
|
67
67
|
#define CUDENSITYMAT_PATCH 0 //!< cuDensityMat patch version.
|
|
68
68
|
#define CUDENSITYMAT_VERSION (CUDENSITYMAT_MAJOR * 10000 + CUDENSITYMAT_MINOR * 100 + CUDENSITYMAT_PATCH)
|
|
69
69
|
|
|
@@ -282,7 +282,8 @@ typedef enum
|
|
|
282
282
|
*/
|
|
283
283
|
typedef enum
|
|
284
284
|
{
|
|
285
|
-
CUDENSITYMAT_EIGEN_SCOPE_SPLIT_DMRG = 0,
|
|
285
|
+
CUDENSITYMAT_EIGEN_SCOPE_SPLIT_DMRG = 0, ///< DMRG-based split decomposition (default)
|
|
286
|
+
CUDENSITYMAT_EIGEN_SCOPE_SPLIT_SHIFT_INVERT_DMRG = 1, ///< Shift-invert DMRG split decomposition (eigenpair nearest a target energy)
|
|
286
287
|
} cudensitymatEigenDecompositionScopeSplitKind_t;
|
|
287
288
|
|
|
288
289
|
/**
|
|
@@ -298,8 +299,9 @@ typedef enum
|
|
|
298
299
|
*/
|
|
299
300
|
typedef enum
|
|
300
301
|
{
|
|
301
|
-
CUDENSITYMAT_EIGEN_APPROACH_KRYLOV = 0, ///< Krylov subspace
|
|
302
|
-
|
|
302
|
+
CUDENSITYMAT_EIGEN_APPROACH_KRYLOV = 0, ///< Krylov subspace (block-Lanczos) eigensolver
|
|
303
|
+
CUDENSITYMAT_EIGEN_APPROACH_LINEAR = 1, ///< Iterative linear solver (currently MINRES)
|
|
304
|
+
//CUDENSITYMAT_EIGEN_APPROACH_DAVIDSON = 2, ///< Davidson method
|
|
303
305
|
} cudensitymatEigenDecompositionApproachKind_t;
|
|
304
306
|
|
|
305
307
|
/**
|
|
@@ -322,8 +324,9 @@ typedef enum
|
|
|
322
324
|
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_KIND = 0, ///< int32_t (cudensitymatEigenDecompositionScopeSplitKind_t): Split kind
|
|
323
325
|
//CUDENSITYMAT_EIGEN_FULL_SCOPE_KIND = 1, ///< int32_t (cudensitymatEigenDecompositionScopeFullKind_t): Full-scope kind
|
|
324
326
|
//CUDENSITYMAT_EIGEN_FULL_SCOPE_EXACT_CONFIG = 2, ///< cudensitymatEigenDecompositionScopeFullExactConfig_t: Full exact-scope configuration
|
|
325
|
-
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_CONFIG = 3, ///< cudensitymatEigenDecompositionScopeSplitDMRGConfig_t: DMRG split configuration
|
|
327
|
+
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_CONFIG = 3, ///< cudensitymatEigenDecompositionScopeSplitDMRGConfig_t: DMRG split configuration (shared by the DMRG and shift-invert DMRG split kinds)
|
|
326
328
|
CUDENSITYMAT_EIGEN_APPROACH_KRYLOV_CONFIG = 10, ///< cudensitymatEigenDecompositionApproachKrylovConfig_t: Krylov approach configuration
|
|
329
|
+
CUDENSITYMAT_EIGEN_APPROACH_LINEAR_CONFIG = 11, ///< cudensitymatEigenDecompositionApproachLinearConfig_t: Linear-solver approach configuration
|
|
327
330
|
} cudensitymatEigenDecompositionAttribute_t;
|
|
328
331
|
|
|
329
332
|
// /**
|
|
@@ -378,12 +381,21 @@ typedef enum
|
|
|
378
381
|
*/
|
|
379
382
|
typedef enum
|
|
380
383
|
{
|
|
381
|
-
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_NUM_SITES = 0, ///< int32_t: Number of sites in
|
|
382
|
-
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_SVD_CONFIG = 1, ///< cudensitymatSVDConfig_t: SVD truncation configuration
|
|
383
|
-
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_MAX_SWEEPS = 2, ///< int32_t: Maximum number of full L-R-L sweeps (default: 20)
|
|
384
|
-
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_ENERGY_TOLERANCE = 3, ///< double: Convergence threshold on the change in
|
|
384
|
+
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_NUM_SITES = 0, ///< int32_t: Number of neighboring MPS sites updated in each local solve (1 or 2; default: 1). SetAttribute returns CUDENSITYMAT_STATUS_INVALID_VALUE for values <= 0 and CUDENSITYMAT_STATUS_NOT_SUPPORTED for values > 2.
|
|
385
|
+
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_SVD_CONFIG = 1, ///< cudensitymatSVDConfig_t: SVD truncation configuration for 2-site updates
|
|
386
|
+
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_MAX_SWEEPS = 2, ///< int32_t: Maximum number of full L-R-L sweeps (default: 20); for shift-invert, the fitting-sweep cap for each inverse application
|
|
387
|
+
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_ENERGY_TOLERANCE = 3, ///< double: Convergence threshold on the change in energy between consecutive sweeps for ground-state DMRG or outer power iterations for shift-invert DMRG (default: 1e-10)
|
|
388
|
+
CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_MAX_POWER_ITERATIONS = 4, ///< int32_t: Maximum number of outer power iterations on (H - sigma)^{-1} for the shift-invert DMRG split kind; ignored by the ground-state DMRG split kind (default: 10)
|
|
385
389
|
} cudensitymatEigenDecompositionScopeSplitDMRGConfigAttribute_t;
|
|
386
390
|
|
|
391
|
+
/**
|
|
392
|
+
* \brief Configuration attributes for the iterative linear solver (currently MINRES).
|
|
393
|
+
*/
|
|
394
|
+
typedef enum
|
|
395
|
+
{
|
|
396
|
+
CUDENSITYMAT_EIGEN_APPROACH_LINEAR_MAX_ITERATIONS = 0, ///< int32_t: Maximum number of iterations for the local linear solve (default: 200). The per-site solve convergence tolerance is supplied at Compute time via the in/out tolerances[] argument, not as a config attribute.
|
|
397
|
+
} cudensitymatEigenDecompositionApproachLinearConfigAttribute_t;
|
|
398
|
+
|
|
387
399
|
/**
|
|
388
400
|
* \brief State-fitting scope (full vs split fitting).
|
|
389
401
|
*/
|
|
@@ -500,7 +512,7 @@ typedef enum
|
|
|
500
512
|
typedef enum
|
|
501
513
|
{
|
|
502
514
|
CUDENSITYMAT_EIGEN_SPECTRUM_LARGEST = 0, ///< Compute the largest by magnitude eigen-values of the operator
|
|
503
|
-
CUDENSITYMAT_EIGEN_SPECTRUM_SMALLEST = 1, ///< Compute the smallest by magnitude
|
|
515
|
+
CUDENSITYMAT_EIGEN_SPECTRUM_SMALLEST = 1, ///< Compute the smallest by magnitude eigenvalues; for shift-invert DMRG, select the smallest |E - sigma| using the Compute target
|
|
504
516
|
CUDENSITYMAT_EIGEN_SPECTRUM_LARGEST_REAL = 2, ///< Compute the largest by the real part eigen-values of the operator
|
|
505
517
|
CUDENSITYMAT_EIGEN_SPECTRUM_SMALLEST_REAL = 3, ///< Compute the smallest by the real part eigen-values of the operator
|
|
506
518
|
} cudensitymatEigenDecompositionSpectrumKind_t;
|
|
@@ -685,6 +697,14 @@ typedef void * cudensitymatTimePropagationScopeSplitTDVPConfig_t;
|
|
|
685
697
|
*/
|
|
686
698
|
typedef void * cudensitymatEigenDecompositionScopeSplitDMRGConfig_t;
|
|
687
699
|
|
|
700
|
+
/**
|
|
701
|
+
* \brief Opaque data structure holding the iterative linear-solver configuration.
|
|
702
|
+
*
|
|
703
|
+
* \details This configuration object stores the iteration cap for the iterative
|
|
704
|
+
* linear solver; the solve tolerance is supplied to Compute.
|
|
705
|
+
*/
|
|
706
|
+
typedef void * cudensitymatEigenDecompositionApproachLinearConfig_t;
|
|
707
|
+
|
|
688
708
|
/**
|
|
689
709
|
* \brief Opaque data structure holding variational ALS configuration
|
|
690
710
|
* for split-scope state fitting on a factorized (e.g., MPS) quantum state.
|
|
@@ -1631,7 +1651,8 @@ cudensitymatStatus_t cudensitymatStateComputeInnerProduct(
|
|
|
1631
1651
|
* The full non-zero diagonals are stored in a concatenated form,
|
|
1632
1652
|
* following the order how they appear in the `diagonalOffsets` argument.
|
|
1633
1653
|
* The length of each stored diagonal is equal to the full matrix dimension,
|
|
1634
|
-
* padded with trailing zeros for non-main diagonals.
|
|
1654
|
+
* padded with trailing zeros for non-main diagonals. Each non-zero diagonal
|
|
1655
|
+
* is stored exactly once, hence all diagonal offsets must be unique.
|
|
1635
1656
|
*
|
|
1636
1657
|
* \note Currently the multi-diagonal storage format is only supported
|
|
1637
1658
|
* by 1-body elementary tensor operators (restriction subject to lifting in future).
|
|
@@ -1648,7 +1669,9 @@ cudensitymatStatus_t cudensitymatStateComputeInnerProduct(
|
|
|
1648
1669
|
* \param[in] diagonalOffsets For multi-diagonal tensor operator matrices, these are
|
|
1649
1670
|
* the offsets of the non-zero diagonals (for example, the main diagonal has offset 0,
|
|
1650
1671
|
* the diagonal right above the main diagonal has offset +1, the diagonal right below
|
|
1651
|
-
* the main diagonal has offset -1, and so on).
|
|
1672
|
+
* the main diagonal has offset -1, and so on). The diagonal offsets must be unique
|
|
1673
|
+
* (each non-zero diagonal is specified and stored exactly once); repeated offsets
|
|
1674
|
+
* are rejected.
|
|
1652
1675
|
* \param[in] dataType Tensor operator data type.
|
|
1653
1676
|
* \param[in] tensorData GPU-accessible pointer to the tensor operator elements storage.
|
|
1654
1677
|
* \param[in] tensorCallback Optional user-defined tensor callback function
|
|
@@ -1703,7 +1726,8 @@ cudensitymatStatus_t cudensitymatCreateElementaryOperator(
|
|
|
1703
1726
|
* The full non-zero diagonals are stored in a concatenated form,
|
|
1704
1727
|
* following the order how they appear in the `diagonalOffsets` argument.
|
|
1705
1728
|
* The length of each stored diagonal is equal to the full matrix dimension,
|
|
1706
|
-
* padded with trailing zeros for non-main diagonals.
|
|
1729
|
+
* padded with trailing zeros for non-main diagonals. Each non-zero diagonal
|
|
1730
|
+
* is stored exactly once, hence all diagonal offsets must be unique.
|
|
1707
1731
|
*
|
|
1708
1732
|
* \note Currently the multi-diagonal storage format is only supported
|
|
1709
1733
|
* by 1-body elementary tensor operators (restriction subject to lifting in future).
|
|
@@ -1724,6 +1748,8 @@ cudensitymatStatus_t cudensitymatCreateElementaryOperator(
|
|
|
1724
1748
|
* \param[in] diagonalOffsets Offsets of the non-zero diagonals (for example,
|
|
1725
1749
|
* the main diagonal has offset 0, the diagonal right above the main diagonal
|
|
1726
1750
|
* has offset +1, the diagonal right below the main diagonal has offset -1, and so on).
|
|
1751
|
+
* The diagonal offsets must be unique (each non-zero diagonal is specified and
|
|
1752
|
+
* stored exactly once); repeated offsets are rejected.
|
|
1727
1753
|
* \param[in] dataType Tensor operator data type.
|
|
1728
1754
|
* \param[in] tensorData GPU-accessible pointer to the tensor operator elements storage,
|
|
1729
1755
|
* where all elementary tensor operators within the batch are stored contiguously in memory.
|
|
@@ -3011,9 +3037,13 @@ cudensitymatStatus_t cudensitymatOperatorSpectrumPrepare(
|
|
|
3011
3037
|
* of shape [numEigenStates, batchSize]) in GPU-accessible RAM (same data type
|
|
3012
3038
|
* as used by the quantum state and operator).
|
|
3013
3039
|
* \param[inout] tolerances Pointer to an F-order array of shape [numEigenStates, batchSize]
|
|
3014
|
-
* in CPU-accessible RAM.
|
|
3015
|
-
*
|
|
3016
|
-
*
|
|
3040
|
+
* in CPU-accessible RAM. On input, the desired solver convergence tolerances for all
|
|
3041
|
+
* eigen-states; on output, the actually achieved solver convergence residual norms (which
|
|
3042
|
+
* may differ from the requested values in either direction). These characterize solver
|
|
3043
|
+
* convergence, not the representation error of the returned state. For the full-state solver
|
|
3044
|
+
* they coincide with the eigenpair residual ||H x - E x||; for split (DMRG / shift-invert)
|
|
3045
|
+
* solvers the returned value is the local per-site solver residual, NOT the global
|
|
3046
|
+
* ||H|psi> - E|psi>||. The representation error is a separate quantity (dedicated query, when available).
|
|
3017
3047
|
* \param[in] workspace Allocated workspace descriptor.
|
|
3018
3048
|
* \param[in] stream CUDA stream.
|
|
3019
3049
|
* \return cudensitymatStatus_t
|
|
@@ -3572,6 +3602,71 @@ cudensitymatStatus_t cudensitymatEigenDecompositionApproachKrylovConfigGetAttrib
|
|
|
3572
3602
|
void * attributeValue,
|
|
3573
3603
|
size_t attributeSize);
|
|
3574
3604
|
|
|
3605
|
+
// ============================================================================
|
|
3606
|
+
// Linear-Solver Configuration API (eigensolver)
|
|
3607
|
+
// ============================================================================
|
|
3608
|
+
|
|
3609
|
+
/**
|
|
3610
|
+
* \brief Creates an eigen-decomposition iterative linear-solver approach
|
|
3611
|
+
* configuration object with default settings.
|
|
3612
|
+
*
|
|
3613
|
+
* \param[in] handle Library handle.
|
|
3614
|
+
* \param[out] config Linear-solver configuration object.
|
|
3615
|
+
* \return cudensitymatStatus_t
|
|
3616
|
+
*/
|
|
3617
|
+
cudensitymatStatus_t cudensitymatCreateEigenDecompositionApproachLinearConfig(
|
|
3618
|
+
const cudensitymatHandle_t handle,
|
|
3619
|
+
cudensitymatEigenDecompositionApproachLinearConfig_t * config);
|
|
3620
|
+
|
|
3621
|
+
/**
|
|
3622
|
+
* \brief Destroys an eigen-decomposition iterative linear-solver approach
|
|
3623
|
+
* configuration object.
|
|
3624
|
+
*
|
|
3625
|
+
* \param[in] config Linear-solver configuration object.
|
|
3626
|
+
* \return cudensitymatStatus_t
|
|
3627
|
+
*/
|
|
3628
|
+
cudensitymatStatus_t cudensitymatDestroyEigenDecompositionApproachLinearConfig(cudensitymatEigenDecompositionApproachLinearConfig_t config);
|
|
3629
|
+
|
|
3630
|
+
/**
|
|
3631
|
+
* \brief Sets an attribute of the eigen-decomposition iterative linear-solver
|
|
3632
|
+
* approach configuration.
|
|
3633
|
+
*
|
|
3634
|
+
* \param[in] handle Library handle.
|
|
3635
|
+
* \param[in] config Linear-solver configuration object.
|
|
3636
|
+
* \param[in] attribute Attribute to set.
|
|
3637
|
+
* \param[in] attributeValue Pointer to the attribute value.
|
|
3638
|
+
* \param[in] attributeSize Size of the attribute value in bytes.
|
|
3639
|
+
* \return cudensitymatStatus_t
|
|
3640
|
+
*
|
|
3641
|
+
* \note The library captures the attribute by value at this call; the caller
|
|
3642
|
+
* retains ownership of `attributeValue` and may destroy the source as soon as
|
|
3643
|
+
* the call returns.
|
|
3644
|
+
*/
|
|
3645
|
+
cudensitymatStatus_t cudensitymatEigenDecompositionApproachLinearConfigSetAttribute(
|
|
3646
|
+
const cudensitymatHandle_t handle,
|
|
3647
|
+
cudensitymatEigenDecompositionApproachLinearConfig_t config,
|
|
3648
|
+
cudensitymatEigenDecompositionApproachLinearConfigAttribute_t attribute,
|
|
3649
|
+
const void * attributeValue,
|
|
3650
|
+
size_t attributeSize);
|
|
3651
|
+
|
|
3652
|
+
/**
|
|
3653
|
+
* \brief Gets an attribute of the eigen-decomposition iterative linear-solver
|
|
3654
|
+
* approach configuration.
|
|
3655
|
+
*
|
|
3656
|
+
* \param[in] handle Library handle.
|
|
3657
|
+
* \param[in] config Linear-solver configuration object.
|
|
3658
|
+
* \param[in] attribute Attribute to get.
|
|
3659
|
+
* \param[out] attributeValue Pointer to store the attribute value.
|
|
3660
|
+
* \param[in] attributeSize Size of the buffer in bytes.
|
|
3661
|
+
* \return cudensitymatStatus_t
|
|
3662
|
+
*/
|
|
3663
|
+
cudensitymatStatus_t cudensitymatEigenDecompositionApproachLinearConfigGetAttribute(
|
|
3664
|
+
const cudensitymatHandle_t handle,
|
|
3665
|
+
const cudensitymatEigenDecompositionApproachLinearConfig_t config,
|
|
3666
|
+
cudensitymatEigenDecompositionApproachLinearConfigAttribute_t attribute,
|
|
3667
|
+
void * attributeValue,
|
|
3668
|
+
size_t attributeSize);
|
|
3669
|
+
|
|
3575
3670
|
// ============================================================================
|
|
3576
3671
|
// Eigen Decomposition API
|
|
3577
3672
|
// ============================================================================
|
|
@@ -3584,7 +3679,8 @@ cudensitymatStatus_t cudensitymatEigenDecompositionApproachKrylovConfigGetAttrib
|
|
|
3584
3679
|
* \param[in] isHermitian Specifies whether the operator is Hermitian (!=0) or not (0).
|
|
3585
3680
|
* \param[in] spectrumKind Requested kind of the eigen-spectrum computation.
|
|
3586
3681
|
* \param[in] scopeKind Requested decomposition scope (full vs split).
|
|
3587
|
-
* \param[in] approachKind Requested decomposition approach (e.g., Krylov
|
|
3682
|
+
* \param[in] approachKind Requested decomposition approach (e.g., Krylov or
|
|
3683
|
+
* iterative linear solve).
|
|
3588
3684
|
* \param[out] eigenDecomposition Eigen-decomposition computation object.
|
|
3589
3685
|
* \return cudensitymatStatus_t
|
|
3590
3686
|
*
|
|
@@ -3595,6 +3691,10 @@ cudensitymatStatus_t cudensitymatEigenDecompositionApproachKrylovConfigGetAttrib
|
|
|
3595
3691
|
* `CUDENSITYMAT_STATUS_NOT_SUPPORTED`; only Hermitian operators are
|
|
3596
3692
|
* supported in this release. The library trusts the caller's flag and does
|
|
3597
3693
|
* not verify Hermiticity of the operator.
|
|
3694
|
+
*
|
|
3695
|
+
* \note In this release, an operator containing more than one MPO product,
|
|
3696
|
+
* or an MPO product containing more than one MPO, is rejected at Create with
|
|
3697
|
+
* `CUDENSITYMAT_STATUS_NOT_SUPPORTED`.
|
|
3598
3698
|
*/
|
|
3599
3699
|
cudensitymatStatus_t cudensitymatCreateEigenDecomposition(
|
|
3600
3700
|
const cudensitymatHandle_t handle,
|
|
@@ -3655,17 +3755,30 @@ cudensitymatStatus_t cudensitymatEigenDecompositionConfigure(
|
|
|
3655
3755
|
* \param[in] stream CUDA stream.
|
|
3656
3756
|
* \return cudensitymatStatus_t
|
|
3657
3757
|
*
|
|
3758
|
+
* \note Prepare is transactional with respect to the cached eigen plan and
|
|
3759
|
+
* workspace requirements. If Prepare fails without an intervening successful
|
|
3760
|
+
* Configure, the last successfully prepared plan and workspace requirements
|
|
3761
|
+
* remain valid provided the generator, state geometry, and Context distribution
|
|
3762
|
+
* are unchanged. A successful Configure invalidates the prepared lifecycle, so
|
|
3763
|
+
* a subsequent failed Prepare leaves the object unprepared.
|
|
3764
|
+
*
|
|
3658
3765
|
* \note In this release, Prepare returns `CUDENSITYMAT_STATUS_NOT_SUPPORTED`
|
|
3659
3766
|
* when any of the following conditions is met:
|
|
3660
3767
|
* (a) the `scopeKind` provided at Create is `CUDENSITYMAT_EIGEN_SCOPE_FULL`;
|
|
3661
3768
|
* (b) the bound DMRG configuration has `CUDENSITYMAT_EIGEN_SPLIT_SCOPE_DMRG_NUM_SITES`
|
|
3662
3769
|
* not in `{1, 2}` (only 1-site and 2-site DMRG are supported in this release);
|
|
3663
3770
|
* (c) `maxEigenStates != 1` (only a single eigen-pair is supported in this release);
|
|
3664
|
-
* (d) the
|
|
3665
|
-
* `
|
|
3666
|
-
*
|
|
3771
|
+
* (d) the selected split/approach/spectrum combination is neither
|
|
3772
|
+
* `SPLIT_DMRG + KRYLOV + SMALLEST_REAL` nor
|
|
3773
|
+
* `SPLIT_SHIFT_INVERT_DMRG + LINEAR + SMALLEST`;
|
|
3667
3774
|
* (e) the representative `state` is a single-site (1-mode) MPS (an MPS
|
|
3668
|
-
* with at least two sites is required by the DMRG engine)
|
|
3775
|
+
* with at least two sites is required by the DMRG engine);
|
|
3776
|
+
* (f) the state data type is not `CUDA_R_64F` or `CUDA_C_64F`, or
|
|
3777
|
+
* `computeType` is not `CUDENSITYMAT_COMPUTE_64F`; or
|
|
3778
|
+
* (g) shift-invert DMRG is configured with `NUM_SITES == 2` for an MPS
|
|
3779
|
+
* containing exactly two tensors. This last restriction is a two-site
|
|
3780
|
+
* ProjectionMPS dependency limitation: `NUM_SITES == 1` remains supported
|
|
3781
|
+
* for a two-tensor MPS.
|
|
3669
3782
|
*/
|
|
3670
3783
|
cudensitymatStatus_t cudensitymatEigenDecompositionPrepare(
|
|
3671
3784
|
const cudensitymatHandle_t handle,
|
|
@@ -3697,13 +3810,25 @@ cudensitymatStatus_t cudensitymatEigenDecompositionPrepare(
|
|
|
3697
3810
|
* \param[inout] eigenstates Quantum eigenstates.
|
|
3698
3811
|
* The initial values of the provided quantum states will be used as the
|
|
3699
3812
|
* initial guesses for the iterative solver.
|
|
3700
|
-
* \param[
|
|
3813
|
+
* \param[inout] eigenvalues Pointer to the eigenvalues storage (F-order array
|
|
3701
3814
|
* of shape [numEigenStates, batchSize]) in GPU-accessible RAM (same data type
|
|
3702
|
-
* as used by the quantum state and operator).
|
|
3815
|
+
* as used by the quantum state and operator). For the shift-invert DMRG split kind,
|
|
3816
|
+
* the input value is the target energy sigma (the returned eigenpair is the one whose
|
|
3817
|
+
* eigenvalue is nearest sigma); it is ignored on input by other split kinds/approaches.
|
|
3818
|
+
* On output, holds the computed eigenvalue(s).
|
|
3703
3819
|
* \param[inout] tolerances Pointer to an F-order array of shape [numEigenStates, batchSize]
|
|
3704
|
-
* in CPU-accessible RAM.
|
|
3705
|
-
*
|
|
3706
|
-
*
|
|
3820
|
+
* in CPU-accessible RAM. On input, the desired solver convergence tolerances for all
|
|
3821
|
+
* eigen-states; on output, the actually achieved solver convergence residual norms (which
|
|
3822
|
+
* may differ from the requested values in either direction). These characterize solver
|
|
3823
|
+
* convergence, not the representation error of the returned state. For the full-state solver
|
|
3824
|
+
* they coincide with the eigenpair residual ||H x - E x||; for split (DMRG / shift-invert)
|
|
3825
|
+
* solvers the returned value is the local per-site solver residual, NOT the global
|
|
3826
|
+
* ||H|psi> - E|psi>||. The representation error is a separate quantity (dedicated query, when available).
|
|
3827
|
+
* For shift-invert DMRG specifically, the input value is the requested per-site
|
|
3828
|
+
* relative normal-equation tolerance. On output it is the maximum achieved absolute
|
|
3829
|
+
* post-insertion (and, for 2-site updates, post-truncation) local normal-equation
|
|
3830
|
+
* residual over every region in the final complete fitting sweep of the final outer
|
|
3831
|
+
* iteration. It is not the achieved outer energy-difference metric.
|
|
3707
3832
|
* \param[in] workspace Allocated workspace descriptor.
|
|
3708
3833
|
* \param[in] stream CUDA stream.
|
|
3709
3834
|
* \return cudensitymatStatus_t
|
|
@@ -3714,10 +3839,25 @@ cudensitymatStatus_t cudensitymatEigenDecompositionPrepare(
|
|
|
3714
3839
|
* \note `numEigenStates != 1` returns `CUDENSITYMAT_STATUS_NOT_SUPPORTED`
|
|
3715
3840
|
* in this release; only a single eigen-pair is supported.
|
|
3716
3841
|
*
|
|
3842
|
+
* \note `batchSize < 1` returns `CUDENSITYMAT_STATUS_INVALID_VALUE`;
|
|
3843
|
+
* `batchSize > 1` returns `CUDENSITYMAT_STATUS_NOT_SUPPORTED`.
|
|
3844
|
+
*
|
|
3845
|
+
* \note `handle` and its distributed configuration must match the last
|
|
3846
|
+
* successful Prepare. After changing either, call Prepare again before Compute.
|
|
3847
|
+
*
|
|
3717
3848
|
* \note The eigenvalue data type matches the state's data type (i.e., the
|
|
3718
3849
|
* complex type used for the input `eigenstates`). For Hermitian operators
|
|
3719
3850
|
* the real eigenvalue is written into the complex slot with `imag = 0`.
|
|
3720
3851
|
*
|
|
3852
|
+
* \note Shift-invert convergence requires finite real sigma, d1 > 0, and
|
|
3853
|
+
* d1 < d2, where d1 and d2 are the nearest distinct-eigenvalue distances.
|
|
3854
|
+
* A degenerate nearest eigenspace is allowed; exact and equidistant targets
|
|
3855
|
+
* are not detected or detuned.
|
|
3856
|
+
*
|
|
3857
|
+
* \note Cap exhaustion returns `CUDENSITYMAT_STATUS_SUCCESS` with the final
|
|
3858
|
+
* normalized approximation, Rayleigh quotient, and final-sweep local residual;
|
|
3859
|
+
* these outputs do not certify outer or global convergence.
|
|
3860
|
+
*
|
|
3721
3861
|
* \note The input `eigenstates` are used as initial guesses for the iterative
|
|
3722
3862
|
* solver. The library does not canonicalize them; the caller is responsible
|
|
3723
3863
|
* for providing a linearly-independent (and ideally well-conditioned) set.
|
|
@@ -8,8 +8,6 @@ from collections.abc import Sequence
|
|
|
8
8
|
|
|
9
9
|
import jax
|
|
10
10
|
|
|
11
|
-
from cuquantum.lib.cudensitymat_jax import InputType
|
|
12
|
-
|
|
13
11
|
from .pysrc.context import CudensitymatContext
|
|
14
12
|
from .pysrc.operator import Operator
|
|
15
13
|
from .pysrc.operator_action_prim import (
|
|
@@ -24,14 +22,33 @@ from .utils import (
|
|
|
24
22
|
check_and_return_final_batch_size,
|
|
25
23
|
check_and_return_device,
|
|
26
24
|
get_original_shape,
|
|
27
|
-
|
|
28
|
-
is_grad_inside_vmap,
|
|
25
|
+
is_vmap_traced,
|
|
29
26
|
)
|
|
30
27
|
|
|
31
28
|
|
|
32
29
|
logger = logging.getLogger("cudensitymat-jax.operator_action")
|
|
33
30
|
|
|
34
31
|
|
|
32
|
+
_ffi_registered = False
|
|
33
|
+
_InputType = None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _register_ffi_targets():
|
|
37
|
+
global _ffi_registered, _InputType
|
|
38
|
+
if _ffi_registered:
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
from cuquantum.bindings._internal import cudensitymat as _cudm
|
|
42
|
+
_cudm._inspect_function_pointers() # for loading libcudensitymat.so
|
|
43
|
+
|
|
44
|
+
from cuquantum.lib import cudensitymat_jax
|
|
45
|
+
_InputType = cudensitymat_jax.InputType
|
|
46
|
+
|
|
47
|
+
for _name, _value in cudensitymat_jax.registrations().items():
|
|
48
|
+
jax.ffi.register_ffi_target(_name, _value, platform="CUDA")
|
|
49
|
+
_ffi_registered = True
|
|
50
|
+
|
|
51
|
+
|
|
35
52
|
def operator_action(op: Operator,
|
|
36
53
|
state_in_bufs: jax.Array | Sequence[jax.Array],
|
|
37
54
|
device: jax.Device | None = None,
|
|
@@ -49,20 +66,17 @@ def operator_action(op: Operator,
|
|
|
49
66
|
"""
|
|
50
67
|
logger.info("Calling operator_action")
|
|
51
68
|
|
|
69
|
+
_register_ffi_targets()
|
|
70
|
+
|
|
71
|
+
if not jax.config.jax_enable_x64:
|
|
72
|
+
raise RuntimeError("jax_enable_x64 must be set to True to use cuQuantum Python JAX")
|
|
73
|
+
|
|
52
74
|
# Process input arguments.
|
|
53
75
|
if isinstance(state_in_bufs, jax.Array):
|
|
54
76
|
state_in_bufs = (state_in_bufs,)
|
|
55
77
|
else:
|
|
56
78
|
state_in_bufs = tuple(state_in_bufs)
|
|
57
79
|
|
|
58
|
-
# Guard against nested vmap transformations, which are not supported.
|
|
59
|
-
if get_vmap_depth(state_in_bufs[0]) > 1:
|
|
60
|
-
raise NotImplementedError("operator_action does not support nested vmap transformations.")
|
|
61
|
-
|
|
62
|
-
# Guard against grad applied inside vmap, which is not supported.
|
|
63
|
-
if is_grad_inside_vmap(state_in_bufs[0]):
|
|
64
|
-
raise NotImplementedError("operator_action does not support grad transformations inside vmap.")
|
|
65
|
-
|
|
66
80
|
# Check and set device from op and state.
|
|
67
81
|
device = check_and_return_device(op, state_in_bufs)
|
|
68
82
|
|
|
@@ -74,12 +88,23 @@ def operator_action(op: Operator,
|
|
|
74
88
|
device = devices[0]
|
|
75
89
|
logger.info("No device specified, using the first GPU device.")
|
|
76
90
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
91
|
+
if op._ptr is None:
|
|
92
|
+
op._simplify()
|
|
93
|
+
op._update_metadata() # update batch sizes
|
|
80
94
|
|
|
81
|
-
|
|
82
|
-
|
|
95
|
+
# Check state shape and maybe expand to a leading batch dimension.
|
|
96
|
+
state_batch_size, purity, has_explicit_batch = get_state_batch_size_and_purity(
|
|
97
|
+
state_in_bufs, op.dims)
|
|
98
|
+
batch_size = check_and_return_final_batch_size(state_batch_size, op._batch_size)
|
|
99
|
+
|
|
100
|
+
state_in_bufs, did_expand = maybe_expand_dim(state_in_bufs, has_explicit_batch)
|
|
101
|
+
# For nested vmap, get_original_shape would return a multi-dim batch prefix
|
|
102
|
+
# (outer_B, inner_B, *physical), which breaks maybe_create_state_context's
|
|
103
|
+
# single-leading-batch assumption. Fuse all batch levels into one leading dim.
|
|
104
|
+
if is_vmap_traced(state_in_bufs[0]):
|
|
105
|
+
state_shape = (batch_size, *state_in_bufs[0].shape)
|
|
106
|
+
else:
|
|
107
|
+
state_shape = tuple(state_in_bufs[0].shape) # already has batch from maybe_expand_dim
|
|
83
108
|
|
|
84
109
|
# Prepare library context for forward operator action.
|
|
85
110
|
# NOTE: Assuming a single state component.
|
|
@@ -117,19 +142,19 @@ def operator_action(op: Operator,
|
|
|
117
142
|
is_op_term_coeff_batched = op._op_term_batch_sizes[i] != 1
|
|
118
143
|
if is_op_term_coeff_batched:
|
|
119
144
|
dynamic_ptr = op_term_total_coeffs_ptr
|
|
120
|
-
dynamic_type =
|
|
145
|
+
dynamic_type = _InputType.OPERATOR_TERM_BATCHED_COEFFS.value
|
|
121
146
|
if dynamic_ptr == 0:
|
|
122
147
|
raise RuntimeError("Missing total coefficient pointer for batched operator term coefficient.")
|
|
123
148
|
else:
|
|
124
149
|
dynamic_ptr = op_term_coeff_ptr
|
|
125
|
-
dynamic_type =
|
|
150
|
+
dynamic_type = _InputType.NON_BATCHED_COEFFS.value
|
|
126
151
|
|
|
127
152
|
if dynamic_ptr not in op_term_coeff_metadata.ptrs:
|
|
128
153
|
op_term_coeff_metadata.indices.append(i)
|
|
129
154
|
op_term_coeff_metadata.types.append(dynamic_type)
|
|
130
155
|
op_term_coeff_metadata.ptrs.append(dynamic_ptr)
|
|
131
156
|
|
|
132
|
-
if op_term_coeff_grad_ptr != 0:
|
|
157
|
+
if op_term_coeff_grad_ptr != 0 and op_term_coeff_grad_ptr not in op_term_coeff_grad_metadata.ptrs:
|
|
133
158
|
op_term_coeff_grad_metadata.indices.append(i)
|
|
134
159
|
op_term_coeff_grad_metadata.ptrs.append(op_term_coeff_grad_ptr)
|
|
135
160
|
# The gradient buffer is always sized (batch_size,) regardless of whether the
|
|
@@ -155,19 +180,19 @@ def operator_action(op: Operator,
|
|
|
155
180
|
is_op_prod_coeff_batched = op_term._op_prod_batch_sizes[j] != 1
|
|
156
181
|
if is_op_prod_coeff_batched:
|
|
157
182
|
dynamic_ptr = op_prod_total_coeffs_ptr
|
|
158
|
-
dynamic_type =
|
|
183
|
+
dynamic_type = _InputType.OPERATOR_PRODUCT_BATCHED_COEFFS.value
|
|
159
184
|
if dynamic_ptr == 0:
|
|
160
185
|
raise RuntimeError("Missing total coefficient pointer for batched operator product coefficient.")
|
|
161
186
|
else:
|
|
162
187
|
dynamic_ptr = op_prod_coeff_ptr
|
|
163
|
-
dynamic_type =
|
|
188
|
+
dynamic_type = _InputType.NON_BATCHED_COEFFS.value
|
|
164
189
|
|
|
165
190
|
if dynamic_ptr not in op_prod_coeff_metadata.ptrs:
|
|
166
191
|
op_prod_coeff_metadata.indices.append((i, j))
|
|
167
192
|
op_prod_coeff_metadata.types.append(dynamic_type)
|
|
168
193
|
op_prod_coeff_metadata.ptrs.append(dynamic_ptr)
|
|
169
194
|
|
|
170
|
-
if op_prod_coeff_grad_ptr != 0:
|
|
195
|
+
if op_prod_coeff_grad_ptr != 0 and op_prod_coeff_grad_ptr not in op_prod_coeff_grad_metadata.ptrs:
|
|
171
196
|
op_prod_coeff_grad_metadata.indices.append((i, j))
|
|
172
197
|
op_prod_coeff_grad_metadata.ptrs.append(op_prod_coeff_grad_ptr)
|
|
173
198
|
# The gradient buffer is always sized (batch_size,) regardless of whether the
|
|
@@ -182,8 +207,8 @@ def operator_action(op: Operator,
|
|
|
182
207
|
if base_op._ptr is not None and base_op._ptr not in base_op_metadata.ptrs:
|
|
183
208
|
base_op_metadata.indices.append((i, j, k))
|
|
184
209
|
base_op_metadata.types.append(
|
|
185
|
-
|
|
186
|
-
else
|
|
210
|
+
_InputType.ELEMENTARY_OPERATOR.value if base_op._is_elementary
|
|
211
|
+
else _InputType.MATRIX_OPERATOR.value
|
|
187
212
|
)
|
|
188
213
|
base_op_metadata.ptrs.append(base_op._ptr)
|
|
189
214
|
|
|
@@ -191,12 +216,18 @@ def operator_action(op: Operator,
|
|
|
191
216
|
base_op_grad_metadata.indices.append((i, j, k))
|
|
192
217
|
base_op_grad_metadata.ptrs.append(base_op._grad_ptr)
|
|
193
218
|
data_shape = get_original_shape(base_op.data)
|
|
194
|
-
if base_op.
|
|
195
|
-
#
|
|
219
|
+
if is_vmap_traced(base_op.data) or base_op._batch_size > 1:
|
|
220
|
+
# data_shape already includes the batch dim: either fused in by
|
|
221
|
+
# get_original_shape for a vmap trace (at any extent, including a
|
|
222
|
+
# size-1 vmap axis), or baked into the concrete array's own shape
|
|
223
|
+
# for materialized (non-vmap) batching, where _batch_size > 1 is a
|
|
224
|
+
# rank-verified presence signal (elementary_operator.py's
|
|
225
|
+
# `ndim % 2 == 1` check), not an extent guess.
|
|
226
|
+
grad_shape = data_shape
|
|
227
|
+
else:
|
|
228
|
+
# Genuinely unbatched: cudensitymat writes batch_size gradient tensors
|
|
196
229
|
# with batch as the last dimension, so buffer has (batch_size, *data_shape).
|
|
197
230
|
grad_shape = (batch_size, *data_shape)
|
|
198
|
-
else:
|
|
199
|
-
grad_shape = data_shape # already includes batch dim
|
|
200
231
|
shape_dtype = jax.ShapeDtypeStruct(grad_shape, base_op.data.dtype)
|
|
201
232
|
base_op_grad_metadata.shape_dtypes.append(shape_dtype)
|
|
202
233
|
|
|
@@ -228,7 +259,7 @@ def operator_action(op: Operator,
|
|
|
228
259
|
)
|
|
229
260
|
|
|
230
261
|
# Undo the leading batch dim when it was added by maybe_expand_dim (single-state, non-vmap).
|
|
231
|
-
state_out_bufs = maybe_squeeze_dim(state_out_bufs,
|
|
262
|
+
state_out_bufs = maybe_squeeze_dim(state_out_bufs, did_expand)
|
|
232
263
|
|
|
233
264
|
# Process output argument.
|
|
234
265
|
if len(state_out_bufs) == 1:
|