ket-lang 0.10.4.2.dev1__tar.gz → 0.10.4.3.dev2__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.
- {ket_lang-0.10.4.2.dev1/src/ket_lang.egg-info → ket_lang-0.10.4.3.dev2}/PKG-INFO +26 -30
- ket_lang-0.10.4.3.dev2/pyproject.toml +76 -0
- ket_lang-0.10.4.3.dev2/pyproject.toml.orig +59 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/__init__.py +6 -1
- ket_lang-0.10.4.3.dev2/src/ket/_shared_control.py +109 -0
- ket_lang-0.10.4.3.dev2/src/ket/_verification.py +146 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/base/__init__.py +48 -17
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/kbw.py +43 -1
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libket/__init__.py +80 -1
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/block.rs +90 -19
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/c_api.rs +39 -5
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/dense_gpu/kernel.rs +42 -10
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/dense_gpu/mod.rs +184 -69
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/kbw/src/dense_gpu/tuning.rs +476 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/dense_v2.rs +55 -2
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/kbw/src/equivalence_tests.rs +204 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/lib.rs +23 -1
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/kbw/src/pauli.rs +214 -0
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/kbw/src/sampling.rs +201 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/sparse.rs +61 -2
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/examples/grover.rs +2 -2
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/libket.h +152 -0
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/libket/src/annealing.rs +911 -0
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/libket/src/c_api/annealing.rs +172 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/c_api/block.rs +84 -4
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/c_api/mod.rs +1 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/c_api/process.rs +33 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/u2.rs +2 -2
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/util.rs +16 -7
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/error.rs +14 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/ir/block.rs +392 -46
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/ir/gate.rs +552 -151
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/lib.rs +1 -0
- ket_lang-0.10.4.3.dev2/src/ket/clib/libs/libket/src/process/known_zero.rs +75 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/process/mod.rs +83 -6
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/tests.rs +672 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/expv.py +320 -42
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/gates.py +44 -4
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/operations.py +56 -52
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/qulib/__init__.py +319 -155
- ket_lang-0.10.4.3.dev2/src/ket/qulib/qubo.py +1003 -0
- ket_lang-0.10.4.2.dev1/MANIFEST.in +0 -7
- ket_lang-0.10.4.2.dev1/PKG-INFO +0 -232
- ket_lang-0.10.4.2.dev1/pyproject.toml +0 -14
- ket_lang-0.10.4.2.dev1/setup.cfg +0 -65
- ket_lang-0.10.4.2.dev1/setup.py +0 -8
- ket_lang-0.10.4.2.dev1/src/ket_lang.egg-info/SOURCES.txt +0 -118
- ket_lang-0.10.4.2.dev1/src/ket_lang.egg-info/dependency_links.txt +0 -1
- ket_lang-0.10.4.2.dev1/src/ket_lang.egg-info/not-zip-safe +0 -1
- ket_lang-0.10.4.2.dev1/src/ket_lang.egg-info/requires.txt +0 -27
- ket_lang-0.10.4.2.dev1/src/ket_lang.egg-info/top_level.txt +0 -1
- ket_lang-0.10.4.2.dev1/tests/test_fermion.py +0 -535
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/LICENSE +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/README.md +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/amazon.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/base/qasm.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/base/quant.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/__init__.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libket/execution.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/__init__.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/.git +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/.gitignore +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/.gitlab-ci.yml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/.pre-commit-config.yaml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/CHANGELOG.md +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/Cargo.toml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/LICENSE +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/LICENSES/Apache-2.0.txt +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/README.md +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/REUSE.toml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/build.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/cbindgen.toml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/examples/grover_batch.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/examples/grover_live.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/examples/grover_live_dv2.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/kbw.h +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/bitwise.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/convert.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/dense.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/quantum_execution.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/kbw/src/sparse_v2.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/.git +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/.gitignore +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/.gitlab-ci.yml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/.pre-commit-config.yaml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/CHANGELOG.md +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/Cargo.toml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/LICENSE +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/LICENSES/Apache-2.0.txt +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/README.md +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/REUSE.toml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/build.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/cbindgen.toml +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/examples/qft.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/c_api/execute.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/mod.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/network.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/su2.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/x/c2to4x.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/x/mod.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/x/single_aux.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/decompose/x/v_chain.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/execution.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/ir/hamiltonian.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/ir/macros.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/ir/mod.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/mapping/allocation.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/mapping/dynamic_look_ahead.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/mapping/graph.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/mapping/mod.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/matrix.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/process/classical_shadow.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/process/qwc.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/qasm/ast.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/qasm/executor.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/qasm/gates.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/qasm/mod.rs +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/libs/libket/src/qasm/openqasm.lalrpop +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/clib/wrapper.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/fermion.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/gateset.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/ibm.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/measurement.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/mps.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/npsim.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/qint.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/quantumstate.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/qulib/gates.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/qulib/ham.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/qulib/oracle.py +0 -0
- {ket_lang-0.10.4.2.dev1 → ket_lang-0.10.4.3.dev2}/src/ket/qulib/prepare.py +0 -0
|
@@ -1,48 +1,44 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ket-lang
|
|
3
|
-
Version: 0.10.4.
|
|
3
|
+
Version: 0.10.4.3.dev2
|
|
4
4
|
Summary: Ket quantum programming language interpreter and library
|
|
5
|
-
Home-page: https://quantumket.org
|
|
6
|
-
Author: Evandro Chagas Ribeiro da Rosa
|
|
7
|
-
Author-email: evandro@quantuloop.com
|
|
8
|
-
License: Apache-2.0
|
|
9
|
-
Project-URL: Source, https://gitlab.com/quantum-ket/ket
|
|
10
5
|
Keywords: quantum computer,quantum programming,quantum simulator
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
Author: Evandro Chagas Ribeiro da Rosa
|
|
7
|
+
Author-email: Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
License-File: LICENSE
|
|
14
10
|
Classifier: Topic :: Scientific/Engineering :: Quantum Computing
|
|
15
11
|
Classifier: Operating System :: POSIX :: Linux
|
|
16
12
|
Classifier: Operating System :: Microsoft :: Windows
|
|
17
13
|
Classifier: Operating System :: MacOS
|
|
18
14
|
Classifier: Programming Language :: Python :: 3
|
|
19
15
|
Classifier: Programming Language :: Rust
|
|
16
|
+
Requires-Dist: amazon-braket-sdk ; extra == 'amazon'
|
|
17
|
+
Requires-Dist: qiskit>=2.0.0,<3.0 ; extra == 'ibm'
|
|
18
|
+
Requires-Dist: qiskit-aer ; extra == 'ibm'
|
|
19
|
+
Requires-Dist: qiskit-ibm-runtime ; extra == 'ibm'
|
|
20
|
+
Requires-Dist: quimb ; extra == 'mps'
|
|
21
|
+
Requires-Dist: jax ; extra == 'mps'
|
|
22
|
+
Requires-Dist: jaxlib ; extra == 'mps'
|
|
23
|
+
Requires-Dist: cotengra ; extra == 'mps'
|
|
24
|
+
Requires-Dist: numpy ; extra == 'plot'
|
|
25
|
+
Requires-Dist: plotly ; extra == 'plot'
|
|
26
|
+
Requires-Dist: pandas ; extra == 'plot'
|
|
27
|
+
Requires-Dist: nbformat ; extra == 'plot'
|
|
28
|
+
Requires-Dist: kaleido ; extra == 'plot'
|
|
29
|
+
Requires-Dist: qiskit[visualization]>=2.0.0,<3.0 ; extra == 'plot'
|
|
30
|
+
Requires-Dist: requests ; extra == 'remote'
|
|
31
|
+
Requires-Dist: pyjwt[crypto] ; extra == 'remote'
|
|
32
|
+
Requires-Dist: bcrypt ; extra == 'remote'
|
|
20
33
|
Requires-Python: >=3.10
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
Project-URL: Homepage, https://quantumket.org
|
|
35
|
+
Project-URL: Source, https://gitlab.com/quantum-ket/ket
|
|
23
36
|
Provides-Extra: amazon
|
|
24
|
-
Requires-Dist: amazon-braket-sdk; extra == "amazon"
|
|
25
37
|
Provides-Extra: ibm
|
|
26
|
-
|
|
27
|
-
Requires-Dist: qiskit-aer; extra == "ibm"
|
|
28
|
-
Requires-Dist: qiskit-ibm-runtime; extra == "ibm"
|
|
38
|
+
Provides-Extra: mps
|
|
29
39
|
Provides-Extra: plot
|
|
30
|
-
Requires-Dist: numpy; extra == "plot"
|
|
31
|
-
Requires-Dist: plotly; extra == "plot"
|
|
32
|
-
Requires-Dist: pandas; extra == "plot"
|
|
33
|
-
Requires-Dist: nbformat; extra == "plot"
|
|
34
|
-
Requires-Dist: kaleido; extra == "plot"
|
|
35
|
-
Requires-Dist: qiskit[visualization]<3.0,>=2.0.0; extra == "plot"
|
|
36
40
|
Provides-Extra: remote
|
|
37
|
-
|
|
38
|
-
Requires-Dist: PyJWT[crypto]; extra == "remote"
|
|
39
|
-
Requires-Dist: bcrypt; extra == "remote"
|
|
40
|
-
Provides-Extra: mps
|
|
41
|
-
Requires-Dist: quimb; extra == "mps"
|
|
42
|
-
Requires-Dist: jax; extra == "mps"
|
|
43
|
-
Requires-Dist: jaxlib; extra == "mps"
|
|
44
|
-
Requires-Dist: cotengra; extra == "mps"
|
|
45
|
-
Dynamic: license-file
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
46
42
|
|
|
47
43
|
<!--
|
|
48
44
|
SPDX-FileCopyrightText: 2020 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.13.5,<0.14"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ket-lang"
|
|
7
|
+
version = "0.10.4.3.dev2"
|
|
8
|
+
description = "Ket quantum programming language interpreter and library"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
keywords = [
|
|
14
|
+
"quantum computer",
|
|
15
|
+
"quantum programming",
|
|
16
|
+
"quantum simulator",
|
|
17
|
+
]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Topic :: Scientific/Engineering :: Quantum Computing",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Operating System :: Microsoft :: Windows",
|
|
22
|
+
"Operating System :: MacOS",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Rust",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[[project.authors]]
|
|
28
|
+
name = "Evandro Chagas Ribeiro da Rosa"
|
|
29
|
+
email = "evandro@quantuloop.com"
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://quantumket.org"
|
|
33
|
+
Source = "https://gitlab.com/quantum-ket/ket"
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
amazon = ["amazon-braket-sdk"]
|
|
37
|
+
ibm = [
|
|
38
|
+
"qiskit>=2.0.0,<3.0",
|
|
39
|
+
"qiskit-aer",
|
|
40
|
+
"qiskit-ibm-runtime",
|
|
41
|
+
]
|
|
42
|
+
plot = [
|
|
43
|
+
"numpy",
|
|
44
|
+
"plotly",
|
|
45
|
+
"pandas",
|
|
46
|
+
"nbformat",
|
|
47
|
+
"kaleido",
|
|
48
|
+
"qiskit[visualization]>=2.0.0,<3.0",
|
|
49
|
+
]
|
|
50
|
+
remote = [
|
|
51
|
+
"requests",
|
|
52
|
+
"PyJWT[crypto]",
|
|
53
|
+
"bcrypt",
|
|
54
|
+
]
|
|
55
|
+
mps = [
|
|
56
|
+
"quimb",
|
|
57
|
+
"jax",
|
|
58
|
+
"jaxlib",
|
|
59
|
+
"cotengra",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[tool.uv.build-backend]
|
|
63
|
+
module-name = "ket"
|
|
64
|
+
module-root = "src"
|
|
65
|
+
wheel-exclude = [
|
|
66
|
+
"ket/clib/libs/kbw",
|
|
67
|
+
"ket/clib/libs/libket",
|
|
68
|
+
]
|
|
69
|
+
source-exclude = ["target"]
|
|
70
|
+
|
|
71
|
+
[tool.pytest.ini_options]
|
|
72
|
+
addopts = [
|
|
73
|
+
"--cov=ket",
|
|
74
|
+
"--cov-report=html",
|
|
75
|
+
]
|
|
76
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2020 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
|
|
2
|
+
# SPDX-FileCopyrightText: 2020 Rafael de Santiago <r.santiago@ufsc.br>
|
|
3
|
+
#
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
[build-system]
|
|
7
|
+
requires = ["uv_build>=0.13.5,<0.14"]
|
|
8
|
+
build-backend = "uv_build"
|
|
9
|
+
|
|
10
|
+
[project]
|
|
11
|
+
name = "ket-lang"
|
|
12
|
+
version = "0.10.4.3.dev2"
|
|
13
|
+
description = "Ket quantum programming language interpreter and library"
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
requires-python = ">=3.10"
|
|
16
|
+
license = "Apache-2.0"
|
|
17
|
+
license-files = ["LICENSE"]
|
|
18
|
+
keywords = ["quantum computer", "quantum programming", "quantum simulator"]
|
|
19
|
+
authors = [
|
|
20
|
+
{ name = "Evandro Chagas Ribeiro da Rosa", email = "evandro@quantuloop.com" },
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Topic :: Scientific/Engineering :: Quantum Computing",
|
|
24
|
+
"Operating System :: POSIX :: Linux",
|
|
25
|
+
"Operating System :: Microsoft :: Windows",
|
|
26
|
+
"Operating System :: MacOS",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Rust",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://quantumket.org"
|
|
33
|
+
Source = "https://gitlab.com/quantum-ket/ket"
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
amazon = ["amazon-braket-sdk"]
|
|
37
|
+
ibm = ["qiskit>=2.0.0,<3.0", "qiskit-aer", "qiskit-ibm-runtime"]
|
|
38
|
+
plot = [
|
|
39
|
+
"numpy",
|
|
40
|
+
"plotly",
|
|
41
|
+
"pandas",
|
|
42
|
+
"nbformat",
|
|
43
|
+
"kaleido",
|
|
44
|
+
"qiskit[visualization]>=2.0.0,<3.0",
|
|
45
|
+
]
|
|
46
|
+
remote = ["requests", "PyJWT[crypto]", "bcrypt"]
|
|
47
|
+
mps = ["quimb", "jax", "jaxlib", "cotengra"]
|
|
48
|
+
|
|
49
|
+
[tool.uv.build-backend]
|
|
50
|
+
module-name = "ket"
|
|
51
|
+
module-root = "src"
|
|
52
|
+
# The libkbw/libket binaries in src/ket/clib/libs are shipped; the Rust
|
|
53
|
+
# submodules next to them are build inputs only.
|
|
54
|
+
wheel-exclude = ["ket/clib/libs/kbw", "ket/clib/libs/libket"]
|
|
55
|
+
source-exclude = ["target"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
addopts = ["--cov=ket", "--cov-report=html"]
|
|
59
|
+
testpaths = ["tests"]
|
|
@@ -63,6 +63,8 @@ Examples:
|
|
|
63
63
|
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
|
+
from importlib import metadata as _metadata
|
|
67
|
+
|
|
66
68
|
from .clib import libs
|
|
67
69
|
from .base import *
|
|
68
70
|
from .base import __all__ as all_base
|
|
@@ -83,7 +85,10 @@ from .fermion import *
|
|
|
83
85
|
from .fermion import __all__ as all_fermion
|
|
84
86
|
from . import qulib
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
try:
|
|
89
|
+
__version__ = _metadata.version("ket-lang")
|
|
90
|
+
except _metadata.PackageNotFoundError: # running from a source checkout
|
|
91
|
+
__version__ = "unknown"
|
|
87
92
|
|
|
88
93
|
__all__ = (
|
|
89
94
|
all_base
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Shared multi-qubit controls through a clean auxiliary qubit.
|
|
2
|
+
|
|
3
|
+
Used by :func:`~ket.operations.control` when a block is controlled by two or
|
|
4
|
+
more qubits.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
# SPDX-FileCopyrightText: 2026 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
|
|
10
|
+
#
|
|
11
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
12
|
+
|
|
13
|
+
# pylint: disable=protected-access
|
|
14
|
+
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
|
+
|
|
17
|
+
from .clib.libket import Block
|
|
18
|
+
from .clib.wrapper import LibketError
|
|
19
|
+
from ._verification import _block_proprieties, _touched_qubits
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from .base import Process, Quant
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _mark(process: Process, block: Block):
|
|
26
|
+
"""Apply the diagonal/permutation annotation of the enclosing builders."""
|
|
27
|
+
if process._is_diagonal > 0:
|
|
28
|
+
block.set_as_diagonal()
|
|
29
|
+
elif process._is_permutation > 0:
|
|
30
|
+
block.set_as_permutation()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def append_controlled(process: Process, body: Block, control_qubits: Quant):
|
|
34
|
+
r"""Append ``body`` controlled by two or more ``control_qubits``.
|
|
35
|
+
|
|
36
|
+
If sharing reduces the CNOT count (estimated by Libket, see below), the
|
|
37
|
+
controls are shared through a clean auxiliary qubit:
|
|
38
|
+
|
|
39
|
+
.. code-block:: text
|
|
40
|
+
|
|
41
|
+
compute: aux ^= AND(control_qubits) (relative-phase decomposition allowed)
|
|
42
|
+
action: body controlled by aux
|
|
43
|
+
uncompute: adjoint of compute
|
|
44
|
+
|
|
45
|
+
The action only reads ``aux`` (as a control) and does not touch the control
|
|
46
|
+
qubits, so ``aux`` returns to |0> and the approximated decomposition of the
|
|
47
|
+
compute step is exact. Each gate of the body then needs a single control
|
|
48
|
+
instead of the whole control set. Otherwise (no CNOT saved,
|
|
49
|
+
no decomposition of the gates, a body that acts on a control qubit, or no
|
|
50
|
+
qubit left for the auxiliary), the controls are added to every gate of
|
|
51
|
+
``body``.
|
|
52
|
+
|
|
53
|
+
The estimate is computed by ``Process::shared_control_gain`` in Libket.
|
|
54
|
+
Sharing costs the compute and the uncompute of the approximated AND of the
|
|
55
|
+
controls. It saves, for each gate of the body,
|
|
56
|
+
the difference between its cost with all the controls and with one, and a
|
|
57
|
+
non-zero global phase saves its correction, a :math:`C^{n-1}P` gate on the
|
|
58
|
+
controls, which becomes a :math:`P` gate on ``aux``. Libket obtains each
|
|
59
|
+
cost from the decomposition it would select with the qubits free now, so
|
|
60
|
+
the decision takes into account the auxiliary qubits available to the
|
|
61
|
+
decompositions, including the one that the shared control takes. The
|
|
62
|
+
controls are never shared when the process does not decompose the gates,
|
|
63
|
+
since the shared form would only add a qubit and gates to the circuit.
|
|
64
|
+
|
|
65
|
+
The auxiliary qubit comes from a pool reserved for shared controls (see
|
|
66
|
+
:meth:`~ket.base.Process._alloc_control_aux`), which the verification of
|
|
67
|
+
:func:`~ket.operations.around` ignores: it is |0> outside the three steps
|
|
68
|
+
above, which are always appended together.
|
|
69
|
+
"""
|
|
70
|
+
aux = None
|
|
71
|
+
num_controls = len(control_qubits)
|
|
72
|
+
touches_controls = bool(
|
|
73
|
+
_touched_qubits(_block_proprieties(body)) & set(control_qubits.qubits)
|
|
74
|
+
)
|
|
75
|
+
if (
|
|
76
|
+
not touches_controls
|
|
77
|
+
and process.shared_control_gain(
|
|
78
|
+
body, num_controls, not process._control_aux_free
|
|
79
|
+
).value
|
|
80
|
+
> 0
|
|
81
|
+
):
|
|
82
|
+
try:
|
|
83
|
+
aux = process._alloc_control_aux()
|
|
84
|
+
except LibketError:
|
|
85
|
+
aux = None
|
|
86
|
+
|
|
87
|
+
if aux is None:
|
|
88
|
+
controlled = body.control(control_qubits.qubits)
|
|
89
|
+
_mark(process, controlled)
|
|
90
|
+
process.append_block(controlled)
|
|
91
|
+
return
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
target = Block(process)
|
|
95
|
+
target.append_gate("PauliX", aux.qubits[0])
|
|
96
|
+
compute = target.control(control_qubits.qubits)
|
|
97
|
+
_mark(process, compute)
|
|
98
|
+
compute.lock_control()
|
|
99
|
+
compute.enable_approximated_decomposition()
|
|
100
|
+
uncompute = compute.inverse()
|
|
101
|
+
|
|
102
|
+
action = body.control(aux.qubits)
|
|
103
|
+
_mark(process, action)
|
|
104
|
+
|
|
105
|
+
process.append_block(compute, check_qubits=False)
|
|
106
|
+
process.append_block(action)
|
|
107
|
+
process.append_block(uncompute, check_qubits=False)
|
|
108
|
+
finally:
|
|
109
|
+
process._free_control_aux(aux)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Verification helpers for the compute-action-uncompute pattern.
|
|
2
|
+
|
|
3
|
+
Used by :func:`~ket.operations.around` and :func:`~ket.operations.undo` to
|
|
4
|
+
check the safe use of auxiliary qubits (clean auxiliary qubit pattern) and to
|
|
5
|
+
decide when the approximated decomposition can be enabled. They query the
|
|
6
|
+
per-qubit properties (gate classification and read qubits) that Libket
|
|
7
|
+
records for each block.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
# SPDX-FileCopyrightText: 2026 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
|
|
13
|
+
#
|
|
14
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
15
|
+
|
|
16
|
+
# pylint: disable=protected-access
|
|
17
|
+
|
|
18
|
+
from ctypes import c_size_t
|
|
19
|
+
import json
|
|
20
|
+
from typing import TYPE_CHECKING
|
|
21
|
+
|
|
22
|
+
from ket.clib.libket import API as libket
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from .base import Process
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _block_proprieties(block) -> dict[int, dict]:
|
|
29
|
+
"""Return the per-qubit properties of a block, keyed by qubit index."""
|
|
30
|
+
proprieties_ptr = block.proprieties_json()
|
|
31
|
+
proprieties = json.loads(proprieties_ptr.value)
|
|
32
|
+
libket["ket_string_delete"](proprieties_ptr)
|
|
33
|
+
return {int(target): op for target, op in proprieties.items()}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _block_proprieties_subset(block, qubits) -> dict[int, dict]:
|
|
37
|
+
"""Return the per-qubit properties of a block for the given qubits only.
|
|
38
|
+
|
|
39
|
+
Equivalent to ``{q: p for q, p in _block_proprieties(block).items() if q in qubits}``,
|
|
40
|
+
but Libket only serializes the requested qubits (using its cached records),
|
|
41
|
+
so the cost does not grow with the size of the block.
|
|
42
|
+
"""
|
|
43
|
+
qubits = list(qubits)
|
|
44
|
+
array = (c_size_t * len(qubits))(*qubits)
|
|
45
|
+
proprieties_ptr = block.proprieties_subset_json(array, len(qubits))
|
|
46
|
+
proprieties = json.loads(proprieties_ptr.value)
|
|
47
|
+
libket["ket_string_delete"](proprieties_ptr)
|
|
48
|
+
return {int(target): op for target, op in proprieties.items()}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _without_control_aux(
|
|
52
|
+
proprieties: dict[int, dict], control_aux: set[int]
|
|
53
|
+
) -> dict[int, dict]:
|
|
54
|
+
"""Remove the shared-control auxiliary qubits from block properties.
|
|
55
|
+
|
|
56
|
+
A shared-control auxiliary qubit (see ``ket.operations.control``) holds the
|
|
57
|
+
AND of a set of control qubits only between its compute and uncompute
|
|
58
|
+
steps, which are always appended together, so it is |0> outside them. It
|
|
59
|
+
is removed from the properties, and a qubit that reads it reads, instead,
|
|
60
|
+
the qubits it was computed from (transitively).
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def sources(qubit, seen):
|
|
64
|
+
result = set()
|
|
65
|
+
for read in proprieties.get(qubit, {}).get("read_qubits", ()):
|
|
66
|
+
if read in control_aux:
|
|
67
|
+
if read not in seen:
|
|
68
|
+
seen.add(read)
|
|
69
|
+
result |= sources(read, seen)
|
|
70
|
+
else:
|
|
71
|
+
result.add(read)
|
|
72
|
+
return result
|
|
73
|
+
|
|
74
|
+
filtered = {}
|
|
75
|
+
for target, op in proprieties.items():
|
|
76
|
+
if target in control_aux:
|
|
77
|
+
continue
|
|
78
|
+
read_qubits = set(op["read_qubits"])
|
|
79
|
+
if read_qubits & control_aux:
|
|
80
|
+
read_qubits = (read_qubits - control_aux) | sources(target, set())
|
|
81
|
+
op = {**op, "read_qubits": sorted(read_qubits)}
|
|
82
|
+
filtered[target] = op
|
|
83
|
+
return filtered
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _analyze_compute(proprieties: dict[int, dict], ket_process: Process):
|
|
87
|
+
"""Check the compute block of a compute-action-uncompute pattern.
|
|
88
|
+
|
|
89
|
+
Returns the set of qubits that must remain unchanged (except for diagonal
|
|
90
|
+
operations) until the uncomputation, and whether every qubit modified by
|
|
91
|
+
the compute block is classified as identity, diagonal, or permutation.
|
|
92
|
+
|
|
93
|
+
The returned blocked set is the transitive closure of the qubits read by
|
|
94
|
+
the auxiliary qubits: if an auxiliary qubit reads ``q`` and ``q`` reads
|
|
95
|
+
``r`` in the compute block, both ``q`` and ``r`` are blocked.
|
|
96
|
+
|
|
97
|
+
Raises:
|
|
98
|
+
RuntimeError: If an auxiliary qubit is subject to a non-permutation
|
|
99
|
+
operation, or if a qubit read (directly or transitively) by an
|
|
100
|
+
auxiliary qubit is subject to a non-permutation operation in the
|
|
101
|
+
compute block.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
if ket_process._control_aux:
|
|
105
|
+
proprieties = _without_control_aux(proprieties, ket_process._control_aux)
|
|
106
|
+
|
|
107
|
+
blocked_qubits = set()
|
|
108
|
+
for target, op in proprieties.items():
|
|
109
|
+
if not ket_process._is_aux(target):
|
|
110
|
+
continue
|
|
111
|
+
match op["propriety"]:
|
|
112
|
+
case "Permutation":
|
|
113
|
+
blocked_qubits.update(op["read_qubits"])
|
|
114
|
+
case "Unitary":
|
|
115
|
+
raise RuntimeError("Operation not allowed on axillary qubit.")
|
|
116
|
+
|
|
117
|
+
pending = list(blocked_qubits)
|
|
118
|
+
while pending:
|
|
119
|
+
qubit = pending.pop()
|
|
120
|
+
op = proprieties.get(qubit)
|
|
121
|
+
if op is None:
|
|
122
|
+
continue
|
|
123
|
+
if op["propriety"] == "Unitary":
|
|
124
|
+
raise RuntimeError(
|
|
125
|
+
"Operation violates uncomputation: a qubit read by an auxiliary "
|
|
126
|
+
"qubit is subject to a non-permutation operation in the compute block."
|
|
127
|
+
)
|
|
128
|
+
for read_qubit in op["read_qubits"]:
|
|
129
|
+
if read_qubit not in blocked_qubits:
|
|
130
|
+
blocked_qubits.add(read_qubit)
|
|
131
|
+
pending.append(read_qubit)
|
|
132
|
+
|
|
133
|
+
is_permutation = all(
|
|
134
|
+
op["propriety"] in ("Identity", "Diagonal", "Permutation")
|
|
135
|
+
for op in proprieties.values()
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return blocked_qubits, is_permutation
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _touched_qubits(proprieties: dict[int, dict]) -> set[int]:
|
|
142
|
+
"""Return the qubits a block acts on, either as target or as control."""
|
|
143
|
+
touched = set(proprieties)
|
|
144
|
+
for op in proprieties.values():
|
|
145
|
+
touched.update(op["read_qubits"])
|
|
146
|
+
return touched
|
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
from collections import defaultdict
|
|
20
20
|
from contextlib import contextmanager
|
|
21
|
-
from ctypes import c_void_p
|
|
21
|
+
from ctypes import c_size_t, c_void_p
|
|
22
22
|
import json
|
|
23
23
|
from typing import Literal, Optional
|
|
24
24
|
|
|
@@ -169,6 +169,12 @@ class Process(LibketProcess): # pylint: disable=too-many-instance-attributes
|
|
|
169
169
|
|
|
170
170
|
self._qubit_pool = []
|
|
171
171
|
self._aux = set()
|
|
172
|
+
# Auxiliary qubits used to share multi-qubit controls (see
|
|
173
|
+
# ``ket.operations.control``). They are never returned to
|
|
174
|
+
# ``_qubit_pool``: they are only used by the compute, action, and
|
|
175
|
+
# uncompute steps of a shared control, which are appended together.
|
|
176
|
+
self._control_aux = set()
|
|
177
|
+
self._control_aux_free = []
|
|
172
178
|
self._blocked_qubits = defaultdict(int)
|
|
173
179
|
|
|
174
180
|
self._blocks = []
|
|
@@ -222,6 +228,30 @@ class Process(LibketProcess): # pylint: disable=too-many-instance-attributes
|
|
|
222
228
|
return self._qubit_pool.pop(0)
|
|
223
229
|
return super().__getattr__("alloc")().value
|
|
224
230
|
|
|
231
|
+
def _alloc_control_aux(self) -> Quant:
|
|
232
|
+
"""Allocate an auxiliary qubit to share a multi-qubit control."""
|
|
233
|
+
if self._control_aux_free:
|
|
234
|
+
index = self._control_aux_free.pop()
|
|
235
|
+
else:
|
|
236
|
+
index = self._alloc()
|
|
237
|
+
self._control_aux.add(index)
|
|
238
|
+
return Quant(qubits=[index], process=self)
|
|
239
|
+
|
|
240
|
+
def _free_control_aux(self, aux: Quant):
|
|
241
|
+
self._control_aux_free.extend(aux.qubits)
|
|
242
|
+
|
|
243
|
+
def _set_unknown_state(self, qubits: Quant):
|
|
244
|
+
"""Declare that the initial state of ``qubits`` is unknown.
|
|
245
|
+
|
|
246
|
+
Libket skips controlled gates that act as the identity on qubits known
|
|
247
|
+
to be in |0> (every qubit starts in |0>). Functions that analyze a gate
|
|
248
|
+
for arbitrary inputs, such as :func:`~ket.qulib.gate_count`, declare
|
|
249
|
+
the input qubits as unknown. Must be called before any gate is applied
|
|
250
|
+
to ``qubits``.
|
|
251
|
+
"""
|
|
252
|
+
array = (c_size_t * len(qubits.qubits))(*qubits.qubits)
|
|
253
|
+
super().__getattr__("set_unknown_state")(array, len(qubits.qubits))
|
|
254
|
+
|
|
225
255
|
def _is_aux(self, index):
|
|
226
256
|
return index in self._aux
|
|
227
257
|
|
|
@@ -493,22 +523,23 @@ class Process(LibketProcess): # pylint: disable=too-many-instance-attributes
|
|
|
493
523
|
try:
|
|
494
524
|
yield block
|
|
495
525
|
finally:
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
526
|
+
try:
|
|
527
|
+
if inverse:
|
|
528
|
+
block.set(block.inverse())
|
|
529
|
+
if control is not None:
|
|
530
|
+
block.set(block.control(control))
|
|
531
|
+
|
|
532
|
+
if self._is_diagonal > 0:
|
|
533
|
+
block.set_as_diagonal()
|
|
534
|
+
elif self._is_permutation > 0:
|
|
535
|
+
block.set_as_permutation()
|
|
536
|
+
finally:
|
|
537
|
+
if diagonal:
|
|
538
|
+
self._is_diagonal -= 1
|
|
539
|
+
elif permutation:
|
|
540
|
+
self._is_permutation -= 1
|
|
541
|
+
|
|
542
|
+
self._blocks.pop()
|
|
512
543
|
if append:
|
|
513
544
|
self.append_block(block)
|
|
514
545
|
|
|
@@ -28,8 +28,15 @@ api_argtypes = {
|
|
|
28
28
|
],
|
|
29
29
|
[c_void_p], # qpu_config
|
|
30
30
|
),
|
|
31
|
+
"kbw_gpu_tune": (
|
|
32
|
+
[c_bool], # force
|
|
33
|
+
[c_size_t, c_bool], # block_size, cached
|
|
34
|
+
),
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
NO_BLOCKING = 64
|
|
38
|
+
"""Block size meaning that the ``"dense gpu"`` simulator never splits the state."""
|
|
39
|
+
|
|
33
40
|
|
|
34
41
|
def kbw_path():
|
|
35
42
|
"""Get KBW path"""
|
|
@@ -76,7 +83,10 @@ def get_simulator( # pylint: disable=too-many-arguments,too-many-positional-arg
|
|
|
76
83
|
- ``"dense v1"``: Previous dense simulator variant.
|
|
77
84
|
- ``"dense v2"``: Dense simulator with a smaller memory footprint.
|
|
78
85
|
- ``"dense gpu"``: Dense simulator targeting most GPUs (Intel, AMD,
|
|
79
|
-
Apple, and NVIDIA). Recommended for large qubit counts.
|
|
86
|
+
Apple, and NVIDIA). Recommended for large qubit counts. Large
|
|
87
|
+
states are split into blocks to keep gates inside the GPU
|
|
88
|
+
caches; the block size is tuned for the device on first use
|
|
89
|
+
(about two seconds) and stored, see :func:`tune_gpu_block_size`.
|
|
80
90
|
|
|
81
91
|
coupling_graph: Optional list of ``(control, target)`` qubit pairs
|
|
82
92
|
describing the hardware connectivity. When provided, the compiler
|
|
@@ -103,3 +113,35 @@ def get_simulator( # pylint: disable=too-many-arguments,too-many-positional-arg
|
|
|
103
113
|
gradient, # gradient
|
|
104
114
|
coupling_graph_json, # coupling_graph
|
|
105
115
|
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def tune_gpu_block_size(force: bool = False) -> int:
|
|
119
|
+
"""Tune the block size of the ``"dense gpu"`` simulator for this device.
|
|
120
|
+
|
|
121
|
+
The ``"dense gpu"`` simulator splits states with many qubits into blocks
|
|
122
|
+
of ``2**block_size`` amplitudes so that gates stay inside the GPU caches.
|
|
123
|
+
The best size depends on the GPU, so it is measured with a short benchmark
|
|
124
|
+
(about one to two seconds) the first time the simulator is used, then
|
|
125
|
+
stored in ``gpu_tuning.json`` in the user cache directory, per device and
|
|
126
|
+
KBW version. Call this function to run the tuning ahead of time, or with
|
|
127
|
+
``force=True`` to measure again (for example, after a driver update).
|
|
128
|
+
|
|
129
|
+
Environment variables:
|
|
130
|
+
|
|
131
|
+
- ``KBW_BLOCK_SIZE``: use this block size and skip tuning.
|
|
132
|
+
- ``KBW_GPU_TUNE=0``: skip tuning and use the default block size, 20.
|
|
133
|
+
- ``KBW_GPU_RETUNE=1``: measure again on first use.
|
|
134
|
+
- ``KBW_CACHE_DIR``: directory of ``gpu_tuning.json``.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
force: Measure even if a stored result exists.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
The chosen block size. :data:`NO_BLOCKING` (64) means that the state is
|
|
141
|
+
never split.
|
|
142
|
+
|
|
143
|
+
Raises:
|
|
144
|
+
LibketError: If no GPU is available or KBW was built without GPU support.
|
|
145
|
+
"""
|
|
146
|
+
block_size, _cached = API["kbw_gpu_tune"](force)
|
|
147
|
+
return block_size.value
|