qmlkit 0.1.0__tar.gz → 0.3.0__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.
- {qmlkit-0.1.0 → qmlkit-0.3.0}/.github/workflows/ci.yml +8 -6
- {qmlkit-0.1.0 → qmlkit-0.3.0}/.github/workflows/docs.yml +6 -1
- qmlkit-0.3.0/AGENTS.md +144 -0
- qmlkit-0.3.0/CHANGELOG.md +2287 -0
- qmlkit-0.3.0/HANDOFF.md +711 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/PKG-INFO +222 -325
- qmlkit-0.3.0/README.md +581 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/RELEASING.md +27 -31
- qmlkit-0.3.0/docs/about/index.md +17 -0
- qmlkit-0.3.0/docs/about/validation.md +230 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/guides/agents.md +1 -1
- qmlkit-0.3.0/docs/guides/backends.md +317 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/guides/choosing-a-gradient.md +64 -2
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/guides/evaluation.md +2 -0
- qmlkit-0.3.0/docs/guides/extending.md +498 -0
- qmlkit-0.3.0/docs/guides/from-pennylane.md +190 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/guides/index.md +3 -0
- qmlkit-0.3.0/docs/guides/openqarp.md +296 -0
- qmlkit-0.3.0/docs/guides/watching-a-run.md +130 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/index.md +42 -35
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/install.md +14 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/llms-full.txt +2221 -173
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/llms.txt +21 -9
- qmlkit-0.3.0/docs/reference/algorithms.md +130 -0
- qmlkit-0.3.0/docs/reference/analysis.md +108 -0
- qmlkit-0.3.0/docs/reference/backends.md +110 -0
- qmlkit-0.3.0/docs/reference/core.md +31 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/reference/encoding.md +6 -0
- qmlkit-0.3.0/docs/reference/evaluation.md +68 -0
- qmlkit-0.3.0/docs/reference/kernels.md +41 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/02-quantum-kernels.md +10 -6
- qmlkit-0.3.0/docs/studies/08-selective-classification.md +134 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/index.md +3 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/02-encoding-data.md +62 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/03-gradients.md +1 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/06-quantum-kernels.md +131 -4
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/08-trainability.md +54 -7
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/accelerate_pennylane.py +32 -11
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/benchmark_pennylane.py +46 -20
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/credit_risk.py +21 -11
- qmlkit-0.3.0/examples/landscape_walkthrough.py +130 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/mkdocs.yml +8 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/pyproject.toml +9 -1
- qmlkit-0.3.0/scripts/check_doc_numbers.py +131 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/scripts/generate_llms_txt.py +11 -5
- qmlkit-0.3.0/scripts/probe_dispatch.py +79 -0
- qmlkit-0.3.0/scripts/probe_fusion.py +77 -0
- qmlkit-0.3.0/scripts/probe_openqarp.py +184 -0
- qmlkit-0.3.0/scripts/probe_qrack.py +84 -0
- qmlkit-0.3.0/scripts/probe_threads.py +88 -0
- qmlkit-0.3.0/scripts/proto_fusion.py +123 -0
- qmlkit-0.3.0/scripts/proto_fusion2.py +109 -0
- qmlkit-0.3.0/scripts/proto_fusion3.py +119 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/scripts/verify_install.py +15 -2
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/__init__.py +48 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/_aliases.py +11 -2
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/adapt.py +42 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/autoencoder.py +32 -10
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/clustering.py +21 -5
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/qaoa.py +31 -3
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/rl.py +27 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/vqe.py +21 -2
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/ansatz/blocks.py +92 -8
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/ansatz/library.py +87 -5
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/ansatz/reupload.py +32 -23
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/baselines.py +10 -3
- qmlkit-0.3.0/src/qmlkit/core/backends/aer_backend.py +151 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/base.py +44 -3
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/cirq_backend.py +20 -7
- qmlkit-0.3.0/src/qmlkit/core/backends/mps_backend.py +186 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/numpy_backend.py +123 -35
- qmlkit-0.3.0/src/qmlkit/core/backends/openqarp_backend.py +320 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/qiskit_backend.py +33 -7
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/registry.py +13 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/spinqit_backend.py +5 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/torch_backend.py +16 -3
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/execute.py +15 -2
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/observables.py +80 -6
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/diagnostics.py +234 -16
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/encoding/__init__.py +17 -0
- qmlkit-0.3.0/src/qmlkit/encoding/amplitude.py +411 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/encoding/feature_maps.py +266 -3
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/encoding/hamiltonian.py +11 -3
- qmlkit-0.3.0/src/qmlkit/encoding/loading.py +256 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/evaluate.py +198 -8
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/dispatch.py +20 -7
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/hadamard.py +6 -2
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/info.py +33 -5
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/kernels/matrix.py +242 -20
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/kernels/models.py +27 -13
- qmlkit-0.3.0/src/qmlkit/landscape.py +1051 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/metrics.py +36 -9
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/nn/layer.py +28 -5
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/nn/models.py +91 -29
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/optim.py +105 -2
- qmlkit-0.3.0/src/qmlkit/parallel.py +94 -0
- qmlkit-0.3.0/src/qmlkit/progress.py +375 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/provenance.py +6 -1
- qmlkit-0.3.0/src/qmlkit/recommend.py +332 -0
- qmlkit-0.3.0/src/qmlkit/report.py +248 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/search.py +16 -5
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/utils/shots.py +15 -3
- qmlkit-0.3.0/tests/densesim.py +206 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_advanced.py +129 -4
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_agent_api.py +8 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_algorithms.py +17 -4
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_analysis.py +431 -0
- qmlkit-0.3.0/tests/test_audit_regressions.py +314 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_batch.py +70 -7
- qmlkit-0.3.0/tests/test_contribution.py +105 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_core.py +4 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_cross_backend.py +86 -6
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_docs.py +35 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_encoding.py +131 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_evaluate.py +122 -0
- qmlkit-0.3.0/tests/test_fusion.py +248 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_kernels.py +172 -2
- qmlkit-0.3.0/tests/test_landscape.py +459 -0
- qmlkit-0.3.0/tests/test_loading_cost.py +109 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_nn.py +25 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_noisy_backends.py +1 -1
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_observables.py +76 -0
- qmlkit-0.3.0/tests/test_openqarp_backend.py +221 -0
- qmlkit-0.3.0/tests/test_optimizer_wiring.py +77 -0
- qmlkit-0.3.0/tests/test_parallel.py +111 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_pennylane_parity.py +3 -1
- qmlkit-0.3.0/tests/test_progress.py +238 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_provenance.py +1 -1
- qmlkit-0.3.0/tests/test_report.py +188 -0
- qmlkit-0.3.0/tests/test_torture.py +388 -0
- qmlkit-0.1.0/AGENTS.md +0 -81
- qmlkit-0.1.0/CHANGELOG.md +0 -959
- qmlkit-0.1.0/HANDOFF.md +0 -228
- qmlkit-0.1.0/README.md +0 -686
- qmlkit-0.1.0/docs/about/validation.md +0 -141
- qmlkit-0.1.0/docs/guides/backends.md +0 -182
- qmlkit-0.1.0/docs/guides/extending.md +0 -248
- qmlkit-0.1.0/docs/reference/algorithms.md +0 -78
- qmlkit-0.1.0/docs/reference/analysis.md +0 -45
- qmlkit-0.1.0/docs/reference/core.md +0 -40
- qmlkit-0.1.0/docs/reference/evaluation.md +0 -34
- qmlkit-0.1.0/docs/reference/kernels.md +0 -15
- qmlkit-0.1.0/src/qmlkit/encoding/amplitude.py +0 -178
- {qmlkit-0.1.0 → qmlkit-0.3.0}/.gitattributes +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/.github/workflows/release.yml +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/.gitignore +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/LICENSE +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/NOTICE +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/about/changelog.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/about/releasing.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/about/stability.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/guides/noise.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/guides/parameter-shift.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/javascripts/mathjax.js +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/reference/ansatz.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/reference/gradients.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/reference/index.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/reference/nn.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/01-imbalanced-classification.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/03-regression.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/04-chemistry.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/05-beyond-classification.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/06-clinical.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/studies/07-images-and-structure.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/01-first-circuit.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/04-ansatz-design.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/05-training-torch.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/07-reuploading.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/docs/tutorials/index.md +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/compare_pennylane.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/credit_data.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/experiments.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/head_to_head.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/quickstart.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/examples/toward_hardware.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/chemistry.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/hamiltonians.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/algorithms/molecule.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/ansatz/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/budget.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/_sampling.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/cirq_density_backend.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/noisy.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/backends/qiskit_aer_backend.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/builder.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/gates.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/core/ir.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/datasets.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/draw.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/encoding/angle.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/encoding/pipeline.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/encoding/scaling.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/fourier.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/generative.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/adjoint.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/batch.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/parameter_shift.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/rules.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/gradients/spsa.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/imbalance.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/interop.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/kernels/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/kernels/estimators.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/nn/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/nn/advanced.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/nn/losses.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/py.typed +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/shadows.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/utils/__init__.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/src/qmlkit/utils/errors.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_ansatz.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_baseline.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_budget.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_builder.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_grad_batch.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_gradient_methods.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_gradients.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_imbalance.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_import.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_injection.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_interop.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_search.py +0 -0
- {qmlkit-0.1.0 → qmlkit-0.3.0}/tests/test_spinqit_backend.py +0 -0
|
@@ -98,13 +98,15 @@ jobs:
|
|
|
98
98
|
with:
|
|
99
99
|
python-version: "3.12"
|
|
100
100
|
cache: pip
|
|
101
|
-
- run: pip install -e ".[dev,torch,qiskit,cirq,aer,sklearn,pennylane,viz]"
|
|
102
|
-
# aer
|
|
103
|
-
#
|
|
104
|
-
#
|
|
105
|
-
#
|
|
101
|
+
- run: pip install -e ".[dev,torch,qiskit,cirq,aer,openqarp,sklearn,pennylane,viz]"
|
|
102
|
+
# aer and openqarp are here and not in the matrix above because that job
|
|
103
|
+
# installs `[<sdk>]` and then imports `<sdk>`, and for these two the
|
|
104
|
+
# distribution and the module are different words (qiskit-aer/qiskit_aer,
|
|
105
|
+
# openqarp/qarp). aer is also the only way the qiskit-aer noisy backend gets
|
|
106
|
+
# exercised at all: without it every test in tests/test_noisy_backends.py
|
|
107
|
+
# skips itself and the job still goes green.
|
|
106
108
|
- name: Confirm every extra actually imported
|
|
107
|
-
run: python -c "import torch, qiskit, qiskit_aer, cirq, sklearn, pennylane, matplotlib"
|
|
109
|
+
run: python -c "import torch, qiskit, qiskit_aer, cirq, qarp, sklearn, pennylane, matplotlib"
|
|
108
110
|
- name: Whole suite, no marker filter
|
|
109
111
|
run: coverage run --parallel-mode --source=qmlkit -m pytest -q
|
|
110
112
|
- uses: actions/upload-artifact@v4
|
|
@@ -46,7 +46,12 @@ jobs:
|
|
|
46
46
|
|
|
47
47
|
deploy:
|
|
48
48
|
name: Publish to GitHub Pages
|
|
49
|
-
|
|
49
|
+
# A manual run has to be able to publish, or `workflow_dispatch` is a build
|
|
50
|
+
# button with no effect - which is exactly when it is reached for, because the
|
|
51
|
+
# push trigger did not fire.
|
|
52
|
+
if: >-
|
|
53
|
+
github.ref == 'refs/heads/main'
|
|
54
|
+
&& (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
|
|
50
55
|
needs: build
|
|
51
56
|
runs-on: ubuntu-latest
|
|
52
57
|
permissions:
|
qmlkit-0.3.0/AGENTS.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Instructions for a coding agent working **on** qmlkit. To *use* the library, read
|
|
4
|
+
[`docs/llms.txt`](docs/llms.txt) instead — it is the same information written for
|
|
5
|
+
the caller rather than the contributor.
|
|
6
|
+
|
|
7
|
+
[`HANDOFF.md`](HANDOFF.md) is the long version of this file: current status, why
|
|
8
|
+
each convention exists, and what to do next. Read it before anything non-trivial.
|
|
9
|
+
This page is the short list of things that will break the build if you get them
|
|
10
|
+
wrong.
|
|
11
|
+
|
|
12
|
+
## The map
|
|
13
|
+
|
|
14
|
+
21,000 lines over 86 modules, 217 names in the top-level `__all__`. Two halves:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
src/qmlkit/
|
|
18
|
+
core/ the IR, and only the IR: ir · builder · gates · observables · execute
|
|
19
|
+
core/backends/ ten of them. base.py supplies the semantics; a backend supplies
|
|
20
|
+
statevector() and inherits sampling, grouping, expectation, batching
|
|
21
|
+
ansatz/ encoding/ gradients/ kernels/ nn/ the ML layer
|
|
22
|
+
algorithms/ VQE · ADAPT · QAOA · chemistry · autoencoder · clustering · rl
|
|
23
|
+
*.py the honesty layer — diagnostics · landscape · baselines · budget ·
|
|
24
|
+
evaluate · imbalance · provenance · search · progress · report · metrics
|
|
25
|
+
utils/errors.py how every "unknown X" error in the library is built
|
|
26
|
+
_aliases.py PennyLane and Qiskit names, answered with the qmlkit one
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The top-level modules are the point of the project. `core/` is machinery in service
|
|
30
|
+
of them.
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install -e ".[dev,torch,qiskit,cirq,sklearn,pennylane]"
|
|
36
|
+
pytest -q # the whole suite
|
|
37
|
+
pytest -q -m "not pennylane" # faster, skips the parity cases
|
|
38
|
+
ruff check src tests && ruff format --check src tests && mypy
|
|
39
|
+
python scripts/generate_llms_txt.py # after any docs or public-API change
|
|
40
|
+
python -m mkdocs build --strict # after any docs change; CI runs it
|
|
41
|
+
python scripts/verify_install.py # the core really does import with only NumPy
|
|
42
|
+
QMLKIT_TORTURE_EXAMPLES=1500 pytest tests/test_torture.py # ~10 min, before a release
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
SpinQit needs its own interpreter — it ships wheels for Python 3.8–3.10 only and
|
|
46
|
+
pins `numpy<2`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
C:/Users/pc/miniconda3/envs/spinq_env/python.exe -m pytest -m spinqit
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Rules the tests enforce
|
|
53
|
+
|
|
54
|
+
1. **An algorithm owns its loop, not its circuit.** Every model takes `ansatz=` /
|
|
55
|
+
`feature_map=` / `filter=` and must actually use it. `tests/test_injection.py`
|
|
56
|
+
injects two different sizes and asserts the parameter count follows.
|
|
57
|
+
2. **Estimators must be scikit-learn clonable.** Constructor arguments stored under
|
|
58
|
+
their own names, plus `SklearnCompatible`. This keeps scikit-learn optional while
|
|
59
|
+
letting QSVC/QSVR run inside `Pipeline` and `GridSearchCV`.
|
|
60
|
+
3. **The core depends on NumPy and nothing else.** Not SciPy — use `math.erf` and the
|
|
61
|
+
stdlib. CI installs nothing else in the `core` jobs, and this has been broken once.
|
|
62
|
+
4. **Documentation is executable.** `tests/test_docs.py` runs every Python block on
|
|
63
|
+
every page, so an API change and its docs go in the same commit.
|
|
64
|
+
5. **Names have to stay findable.** `qmlkit/_aliases.py` maps what PennyLane and
|
|
65
|
+
Qiskit call each thing; `tests/test_agent_api.py` asserts every target still
|
|
66
|
+
exists. Rename a public name and you update that table in the same commit.
|
|
67
|
+
6. **`docs/llms.txt` is generated and committed.** Change the docs or the public API
|
|
68
|
+
and regenerate it, or CI fails on the stale copy.
|
|
69
|
+
|
|
70
|
+
## Traps that have already cost time
|
|
71
|
+
|
|
72
|
+
- **Never use a NumPy-2-only API** (`np.trapezoid`, `np.in1d`, …) in `src/` or
|
|
73
|
+
`tests/`. SpinQit pins `numpy<2` and the suite must pass in both environments.
|
|
74
|
+
- **Always write `npt.NDArray[Any]`, never bare `np.ndarray`.** Type-parameter
|
|
75
|
+
defaults only arrived in NumPy 2.3, so 3.10 CI fails with 60 `type-arg` errors.
|
|
76
|
+
- **Never set `python_version` in `[tool.mypy]`.** It makes mypy parse dependency
|
|
77
|
+
stubs at that version too, and NumPy's stubs use PEP 695 `type` statements, which
|
|
78
|
+
are a syntax error before 3.12. Cross-version signal comes from CI running mypy
|
|
79
|
+
on 3.10.
|
|
80
|
+
- **The PennyLane parity fuzzer draws gate names from a snapshot taken at import**,
|
|
81
|
+
not from the live registry — other test modules register throwaway gates at run
|
|
82
|
+
time, which made it pass alone and fail in a full run.
|
|
83
|
+
- **Extend `tests/test_pennylane_parity.py` when adding a gate.** A test there
|
|
84
|
+
asserts the mapping covers every built-in gate, so a new one cannot escape
|
|
85
|
+
cross-validation. Every bug found in this project has been the
|
|
86
|
+
plausible-wrong-number kind that only a second implementation catches.
|
|
87
|
+
|
|
88
|
+
## Where a change has to land
|
|
89
|
+
|
|
90
|
+
The library is built on registries, so adding something is usually one call — and
|
|
91
|
+
then three or four places that will not fail loudly if you forget them.
|
|
92
|
+
|
|
93
|
+
| Adding | Also touch |
|
|
94
|
+
|---|---|
|
|
95
|
+
| **A gate** | `frequencies` on the `GateDef` or differentiation is refused; `dmatrix` or adjoint is refused; the PennyLane mapping in `tests/test_pennylane_parity.py`, which asserts it covers every built-in gate |
|
|
96
|
+
| **An ansatz or conv filter** | `register_*`, and check it is not inert — an all-`rz` filter does nothing at all from `|0…0⟩`, which is why `test_no_shipped_filter_is_inert` exists |
|
|
97
|
+
| **A backend** | `supports_exact` and `supports_statevector` are a contract, not metadata. Then **sweep the public API against it**: adding the noisy backends broke `diagnose`, `expressibility`, `entangling_capability`, `fidelity_samples`, `metric_tensor` and `qng_step`, and the suite did not notice |
|
|
98
|
+
| **A diagnostic finding** | Write the test so it asserts the finding is **true**, not that it fired. The old tests asserted firing, which is how three wrong findings survived. A false positive here is worse than a false negative: it teaches people to ignore the tool |
|
|
99
|
+
| **Anything public** | `docs/llms.txt` regenerated, a reference page entry, and a CHANGELOG entry |
|
|
100
|
+
| **A version bump** | `pyproject.toml` **and** `src/qmlkit/__init__.py`. A third hardcoded copy in `scripts/verify_install.py` once failed the release gate |
|
|
101
|
+
|
|
102
|
+
**Releasing is a tag on this repository**, which `release.yml` turns into a TestPyPI
|
|
103
|
+
then PyPI publish over Trusted Publishing - no token is handled anywhere. It asserts
|
|
104
|
+
the tag matches `pyproject.toml` before it builds. A PyPI version number can never be
|
|
105
|
+
reused, so tags stay unpushed until the release is actually wanted, and a release that
|
|
106
|
+
half-completes burns the number. `RELEASING.md` has the procedure.
|
|
107
|
+
|
|
108
|
+
Until 2026-09-13 this repo was a `git subtree split` of a subdirectory in the lecture
|
|
109
|
+
repository. If you find a document that still says so, it is stale - fix it.
|
|
110
|
+
|
|
111
|
+
## Writing
|
|
112
|
+
|
|
113
|
+
The prose is a deliberate artefact. Match it rather than inventing a second voice.
|
|
114
|
+
|
|
115
|
+
- **Claims enter through the failure they prevent**, never through the feature name.
|
|
116
|
+
The order is: here is a way to be wrong, here is why it does not raise, here is the
|
|
117
|
+
call. Almost nothing opens with "qmlkit provides".
|
|
118
|
+
- **Every number carries its provenance.** "Measured on a 5-qubit hardware-efficient
|
|
119
|
+
ansatz"; "measured: five frequencies". A bare number reads as an unsupported claim.
|
|
120
|
+
- **Caveats get their own sentence, in the same voice as the claims**, usually last and
|
|
121
|
+
usually against the author's interest — "JAX is not installed on the benchmark
|
|
122
|
+
machine, so jit-compiled PennyLane is untested and unclaimed."
|
|
123
|
+
- **Headings are assertions, not labels**: "Data re-uploading is a pattern, not a
|
|
124
|
+
structure"; "Noise, when you ask for it by name". Label headings mark reference
|
|
125
|
+
sections, and the contrast is the point.
|
|
126
|
+
- A long sentence that does the analysis, then a short one that lands it. British
|
|
127
|
+
spelling. Second person about the reader's actions, never their level.
|
|
128
|
+
|
|
129
|
+
## Design commitments
|
|
130
|
+
|
|
131
|
+
- **Simulator-only for the whole 0.x line.** This is a constraint that propagates,
|
|
132
|
+
not a scope trim: it makes `adjoint` the correct default gradient, makes shot
|
|
133
|
+
noise opt-in, and demotes anything whose value is cutting *measurement* cost.
|
|
134
|
+
Parameter-shift stays the teaching subject and the reference that validates
|
|
135
|
+
adjoint — never the performance default.
|
|
136
|
+
- **Simple on top, open underneath.** Three layers, and nothing at a higher one
|
|
137
|
+
hides a lower one. Every extension point is a registry.
|
|
138
|
+
- **When something is named after a pattern rather than a structure, make it a
|
|
139
|
+
composition, not a class.** Data re-uploading is `EncodingLayer` in the block
|
|
140
|
+
vocabulary, with `reupload()` as a convenience over it.
|
|
141
|
+
- **The error message is the documentation.** Most callers are models that will not
|
|
142
|
+
read the docs site; they read the traceback. An error about a name says what was
|
|
143
|
+
wrong, what was probably meant, and what is allowed — build it with
|
|
144
|
+
`qmlkit.utils.errors.unknown`.
|