ket-lang 0.10.3.dev1__tar.gz → 0.10.4.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. {ket_lang-0.10.3.dev1/src/ket_lang.egg-info → ket_lang-0.10.4.dev1}/PKG-INFO +1 -1
  2. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/__init__.py +1 -1
  3. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/amazon.py +15 -5
  4. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libket/__init__.py +1 -0
  5. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/.gitlab-ci.yml +2 -2
  6. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/Cargo.toml +3 -2
  7. ket_lang-0.10.4.dev1/src/ket/clib/libs/libket/examples/grover.rs +73 -0
  8. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/examples/qft.rs +1 -1
  9. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/libket.h +20 -0
  10. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/c_api/block.rs +16 -19
  11. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/c_api/process.rs +38 -9
  12. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/error.rs +7 -0
  13. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/ir/block.rs +301 -8
  14. ket_lang-0.10.4.dev1/src/ket/clib/libs/libket/src/ir/macros.rs +77 -0
  15. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/ir/mod.rs +1 -0
  16. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/lib.rs +77 -0
  17. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/process/mod.rs +22 -15
  18. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/tests.rs +73 -2
  19. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/gates.py +15 -21
  20. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/mps.py +162 -35
  21. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1/src/ket_lang.egg-info}/PKG-INFO +1 -1
  22. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket_lang.egg-info/SOURCES.txt +1 -0
  23. ket_lang-0.10.3.dev1/src/ket/clib/libs/libket/examples/grover.rs +0 -67
  24. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/LICENSE +0 -0
  25. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/MANIFEST.in +0 -0
  26. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/README.md +0 -0
  27. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/pyproject.toml +0 -0
  28. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/setup.cfg +0 -0
  29. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/setup.py +0 -0
  30. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/base/__init__.py +0 -0
  31. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/base/qasm.py +0 -0
  32. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/base/quant.py +0 -0
  33. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/__init__.py +0 -0
  34. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/kbw.py +0 -0
  35. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libket/execution.py +0 -0
  36. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/__init__.py +0 -0
  37. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/.git +0 -0
  38. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/.gitignore +0 -0
  39. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/.gitlab-ci.yml +0 -0
  40. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/.pre-commit-config.yaml +0 -0
  41. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/CHANGELOG.md +0 -0
  42. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/Cargo.toml +0 -0
  43. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/LICENSE +0 -0
  44. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/LICENSES/Apache-2.0.txt +0 -0
  45. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/README.md +0 -0
  46. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/REUSE.toml +0 -0
  47. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/build.rs +0 -0
  48. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/cbindgen.toml +0 -0
  49. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/examples/grover_batch.rs +0 -0
  50. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/examples/grover_live.rs +0 -0
  51. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/examples/grover_live_dv2.rs +0 -0
  52. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/kbw.h +0 -0
  53. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/bitwise.rs +0 -0
  54. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/block.rs +0 -0
  55. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/c_api.rs +0 -0
  56. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/convert.rs +0 -0
  57. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/dense.rs +0 -0
  58. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/dense_gpu/kernel.rs +0 -0
  59. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/dense_gpu/mod.rs +0 -0
  60. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/dense_v2.rs +0 -0
  61. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/lib.rs +0 -0
  62. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/quantum_execution.rs +0 -0
  63. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/sparse.rs +0 -0
  64. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/kbw/src/sparse_v2.rs +0 -0
  65. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/.git +0 -0
  66. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/.gitignore +0 -0
  67. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/.pre-commit-config.yaml +0 -0
  68. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/CHANGELOG.md +0 -0
  69. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/LICENSE +0 -0
  70. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/LICENSES/Apache-2.0.txt +0 -0
  71. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/README.md +0 -0
  72. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/REUSE.toml +0 -0
  73. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/build.rs +0 -0
  74. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/cbindgen.toml +0 -0
  75. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/c_api/execute.rs +0 -0
  76. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/c_api/mod.rs +0 -0
  77. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/mod.rs +0 -0
  78. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/network.rs +0 -0
  79. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/su2.rs +0 -0
  80. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/u2.rs +0 -0
  81. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/util.rs +0 -0
  82. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/x/c2to4x.rs +0 -0
  83. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/x/mod.rs +0 -0
  84. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/x/single_aux.rs +0 -0
  85. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/decompose/x/v_chain.rs +0 -0
  86. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/execution.rs +0 -0
  87. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/ir/gate.rs +0 -0
  88. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/ir/hamiltonian.rs +0 -0
  89. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/mapping/allocation.rs +0 -0
  90. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/mapping/dynamic_look_ahead.rs +0 -0
  91. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/mapping/graph.rs +0 -0
  92. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/mapping/mod.rs +0 -0
  93. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/matrix.rs +0 -0
  94. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/process/classical_shadow.rs +0 -0
  95. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/process/qwc.rs +0 -0
  96. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/qasm/ast.rs +0 -0
  97. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/qasm/executor.rs +0 -0
  98. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/qasm/gates.rs +0 -0
  99. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/qasm/mod.rs +0 -0
  100. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/libs/libket/src/qasm/openqasm.lalrpop +0 -0
  101. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/clib/wrapper.py +0 -0
  102. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/expv.py +0 -0
  103. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/fermion.py +0 -0
  104. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/ibm.py +0 -0
  105. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/measurement.py +0 -0
  106. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/npsim.py +0 -0
  107. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/operations.py +0 -0
  108. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/qint.py +0 -0
  109. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/quantumstate.py +0 -0
  110. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/qulib/__init__.py +0 -0
  111. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/qulib/gates.py +0 -0
  112. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/qulib/ham.py +0 -0
  113. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/qulib/oracle.py +0 -0
  114. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket/qulib/prepare.py +0 -0
  115. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket_lang.egg-info/dependency_links.txt +0 -0
  116. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket_lang.egg-info/not-zip-safe +0 -0
  117. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket_lang.egg-info/requires.txt +0 -0
  118. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/src/ket_lang.egg-info/top_level.txt +0 -0
  119. {ket_lang-0.10.3.dev1 → ket_lang-0.10.4.dev1}/tests/test_fermion.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ket-lang
3
- Version: 0.10.3.dev1
3
+ Version: 0.10.4.dev1
4
4
  Summary: Ket quantum programming language interpreter and library
5
5
  Home-page: https://quantumket.org
6
6
  Author: Evandro Chagas Ribeiro da Rosa
@@ -83,7 +83,7 @@ from .fermion import *
83
83
  from .fermion import __all__ as all_fermion
84
84
  from . import qulib
85
85
 
86
- __version__ = "0.10.3.dev1"
86
+ __version__ = "0.10.4.dev1"
87
87
 
88
88
  __all__ = (
89
89
  all_base
@@ -204,15 +204,25 @@ class AmazonBraket(BatchExecution): # pylint: disable=too-many-instance-attribu
204
204
  for gate_inst in gates:
205
205
  gate = gate_inst["gate"]
206
206
  target = gate_inst["target"]
207
- decomposed = gate_inst["decomposed"]
207
+ controls = gate_inst.get("control", [])
208
+ decomposed = gate_inst.get("decomposed")
209
+
210
+ if len(controls) == 1:
211
+ control = controls[0]
212
+ if gate == "PauliX":
213
+ circuit.cnot(control, target)
214
+ continue
215
+ if isinstance(gate, dict) and "Phase" in gate:
216
+ circuit.cphaseshift(control, target, gate["Phase"]["Value"])
217
+ continue
208
218
 
209
219
  if decomposed is not None:
210
- for gate in decomposed:
211
- match gate:
220
+ for dec_gate in decomposed:
221
+ match dec_gate:
212
222
  case {"CNOT": (control, target)}:
213
223
  circuit.cnot(control, target)
214
- case {"U": (gate, target)}:
215
- self._call_gate(circuit, gate, target)
224
+ case {"U": (u_gate, target)}:
225
+ self._call_gate(circuit, u_gate, target)
216
226
  else:
217
227
  self._call_gate(circuit, gate, target)
218
228
 
@@ -311,6 +311,7 @@ api_argtypes = {
311
311
  "ket_block_set_as_permutation": ([c_void_p], []),
312
312
  "ket_process_set_parameter": ([c_void_p, c_double], [c_size_t]),
313
313
  "ket_parse_openqasm": ([POINTER(c_size_t), c_size_t, c_char_p], [c_void_p]),
314
+ "ket_qft": ([POINTER(c_size_t), c_size_t, c_bool], [c_void_p]),
314
315
  }
315
316
 
316
317
 
@@ -83,7 +83,7 @@ linux-build:
83
83
  - target/CACHEDIR.TAG
84
84
  policy: pull-push
85
85
  script:
86
- - cargo build -F c_api --release
86
+ - cargo build --release
87
87
  artifacts:
88
88
  paths:
89
89
  - target/release/libket.so
@@ -107,7 +107,7 @@ windows-build:
107
107
  - target/CACHEDIR.TAG
108
108
  policy: pull-push
109
109
  script:
110
- - cargo build -F c_api --release --target x86_64-pc-windows-gnu
110
+ - cargo build --release --target x86_64-pc-windows-gnu
111
111
  artifacts:
112
112
  paths:
113
113
  - target/x86_64-pc-windows-gnu/release/ket.dll
@@ -25,7 +25,8 @@ thiserror = "2.0.19"
25
25
  itertools = "0.15.0"
26
26
  rand = "0.10.2"
27
27
  rayon = "1.5.3"
28
- build-info = { version = "0.0.45", default-features = false, features = [], optional = true }
28
+ build-info = { version = "0.0.45", default-features = false, features = [
29
+ ], optional = true }
29
30
 
30
31
  [build-dependencies]
31
32
  lalrpop = { version = "0.23.1", optional = true }
@@ -39,6 +40,6 @@ crate-type = ["cdylib", "rlib"]
39
40
  strip = true
40
41
 
41
42
  [features]
42
- default = ["qasm"]
43
+ default = ["qasm", "c_api"]
43
44
  c_api = ["build-info"]
44
45
  qasm = ["dep:lalrpop-util", "dep:lalrpop"]
@@ -0,0 +1,73 @@
1
+ // SPDX-FileCopyrightText: 2024 Evandro Chagas Ribeiro da Rosa <evandro@quantuloop.com>
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ use std::f64::consts::FRAC_PI_4;
6
+
7
+ use ket::{
8
+ compute_action_uncompute_gate,
9
+ error::KetError,
10
+ ir::{block::BasicBlock, gate::QuantumGate},
11
+ process::{Process, QPUConfig},
12
+ };
13
+
14
+ fn main() -> Result<(), KetError> {
15
+ let num_qubits = 3;
16
+
17
+ let mut process = Process::new(QPUConfig {
18
+ num_qubits,
19
+ quantum_execution: None,
20
+ });
21
+
22
+ let qubits: Result<Vec<_>, _> = (0..num_qubits).map(|_| process.alloc()).collect();
23
+ let qubits = qubits?;
24
+
25
+ let mut quantum_code = BasicBlock::new();
26
+
27
+ for target in &qubits {
28
+ quantum_code.append_gate(QuantumGate::Hadamard, *target);
29
+ }
30
+
31
+ process.append_block(quantum_code.into())?;
32
+
33
+ let steps = ((FRAC_PI_4) * f64::sqrt((1 << num_qubits) as f64)) as i64;
34
+
35
+ for _ in 0..steps {
36
+ process.append_block(
37
+ compute_action_uncompute_gate(
38
+ |mut compute| {
39
+ for target in &qubits {
40
+ compute.append_gate(QuantumGate::PauliX, *target);
41
+ }
42
+ Ok(compute)
43
+ },
44
+ |mut action| {
45
+ action.append_gate(QuantumGate::PauliZ, qubits[0]);
46
+ Ok(action.control(&qubits[1..])?)
47
+ },
48
+ )?
49
+ .into(),
50
+ )?;
51
+
52
+ process.append_block(
53
+ compute_action_uncompute_gate(
54
+ |mut compute| {
55
+ for target in &qubits {
56
+ compute.append_gate(QuantumGate::Hadamard, *target);
57
+ compute.append_gate(QuantumGate::PauliX, *target);
58
+ }
59
+ Ok(compute)
60
+ },
61
+ |mut action| {
62
+ action.append_gate(QuantumGate::PauliZ, qubits[0]);
63
+ Ok(action.control(&qubits[1..])?)
64
+ },
65
+ )?
66
+ .into(),
67
+ )?;
68
+ }
69
+
70
+ println!("{:#?}", process);
71
+
72
+ Ok(())
73
+ }
@@ -54,7 +54,7 @@ fn main() -> Result<(), KetError> {
54
54
  let qubits: Result<Vec<_>, _> = (0..num_qubits).map(|_| process.alloc()).collect();
55
55
  let qubits = qubits?;
56
56
 
57
- process.append_block(qft(&qubits, true)?)?;
57
+ process.append_block(qft(&qubits, true)?.into())?;
58
58
 
59
59
  println!("{:#?}", process);
60
60
 
@@ -711,6 +711,26 @@ int32_t ket_parse_openqasm(const uintptr_t *qubits,
711
711
  struct BasicBlock **block_out);
712
712
  #endif
713
713
 
714
+ /**
715
+ * Creates a BasicBlock that implements the Quantum Fourier Transform (QFT) on the given qubits.
716
+ *
717
+ * On success, a newly heap-allocated `BasicBlock` is written to `*block_out`.
718
+ * The caller takes ownership and must eventually free it with [`ket_block_delete`].
719
+ *
720
+ * # Parameters
721
+ * - `qubits` : Pointer to an array of `size_t` physical qubit indices. The MSQ should be at index 0.
722
+ * - `qubits_len` : Number of entries in `qubits`.
723
+ * - `do_swap` : Boolean flag indicating whether to add SWAP gates at the end of the circuit to reverse the qubit order.
724
+ * - `block_out` : Output: on success, set to a pointer to the new `BasicBlock`.
725
+ *
726
+ * # Returns
727
+ * `0` on success, non-zero error code on failure.
728
+ */
729
+ int32_t ket_qft(const uintptr_t *qubits,
730
+ uintptr_t qubits_len,
731
+ bool do_swap,
732
+ struct BasicBlock **block_out);
733
+
714
734
  #ifdef __cplusplus
715
735
  } // extern "C"
716
736
  #endif // __cplusplus
@@ -11,19 +11,19 @@ use std::ffi::{c_char, CString};
11
11
  use crate::{
12
12
  c_api::c_ok,
13
13
  error::KetError,
14
- ir::{block::BasicBlock, gate::QuantumGate},
14
+ ir::{block::Block, gate::QuantumGate},
15
15
  };
16
16
 
17
17
  /// Allocates a new, empty [`BasicBlock`] and writes its pointer to `block`.
18
18
  #[no_mangle]
19
- pub extern "C" fn ket_block_new(block: &mut *mut BasicBlock) -> i32 {
20
- *block = Box::into_raw(Box::new(BasicBlock::new()));
19
+ pub extern "C" fn ket_block_new(block: &mut *mut Block) -> i32 {
20
+ *block = Box::into_raw(Box::new(Block::new()));
21
21
  c_ok()
22
22
  }
23
23
 
24
24
  /// Deallocates the memory associated with a [`BasicBlock`].
25
25
  #[no_mangle]
26
- pub extern "C" fn ket_block_delete(block: *mut BasicBlock) -> i32 {
26
+ pub extern "C" fn ket_block_delete(block: *mut Block) -> i32 {
27
27
  let _ = unsafe { *Box::from_raw(block) };
28
28
  c_ok()
29
29
  }
@@ -31,7 +31,7 @@ pub extern "C" fn ket_block_delete(block: *mut BasicBlock) -> i32 {
31
31
  /// Appends a new quantum gate (provided as a JSON payload) to a [`BasicBlock`].
32
32
  #[no_mangle]
33
33
  pub extern "C" fn ket_block_append_gate(
34
- block: &mut BasicBlock,
34
+ block: &mut Block,
35
35
  gate_json: *const c_char,
36
36
  target: usize,
37
37
  ) -> i32 {
@@ -42,10 +42,7 @@ pub extern "C" fn ket_block_append_gate(
42
42
 
43
43
  /// Creates a new [`BasicBlock`] that is the adjoint (inverse) of the provided block.
44
44
  #[no_mangle]
45
- pub extern "C" fn ket_block_inverse(
46
- block: &BasicBlock,
47
- inverted_block: &mut *mut BasicBlock,
48
- ) -> i32 {
45
+ pub extern "C" fn ket_block_inverse(block: &Block, inverted_block: &mut *mut Block) -> i32 {
49
46
  *inverted_block = Box::into_raw(Box::new(block.inverse()));
50
47
  c_ok()
51
48
  }
@@ -53,10 +50,10 @@ pub extern "C" fn ket_block_inverse(
53
50
  /// Creates a new [`BasicBlock`] resulting from adding control qubits to all gates in the block.
54
51
  #[no_mangle]
55
52
  pub extern "C" fn ket_block_control(
56
- block: &BasicBlock,
53
+ block: &Block,
57
54
  control_qubits: *const usize,
58
55
  control_qubits_len: usize,
59
- controlled_block: &mut *mut BasicBlock,
56
+ controlled_block: &mut *mut Block,
60
57
  ) -> i32 {
61
58
  let qubits = unsafe { std::slice::from_raw_parts(control_qubits, control_qubits_len) };
62
59
  match block.control(qubits) {
@@ -70,21 +67,21 @@ pub extern "C" fn ket_block_control(
70
67
 
71
68
  /// Enables approximate decomposition strategies for all gates in the given [`BasicBlock`].
72
69
  #[no_mangle]
73
- pub extern "C" fn ket_block_enable_approximated_decomposition(block: &mut BasicBlock) -> i32 {
70
+ pub extern "C" fn ket_block_enable_approximated_decomposition(block: &mut Block) -> i32 {
74
71
  block.enable_approximated_decomposition();
75
72
  c_ok()
76
73
  }
77
74
 
78
75
  /// Locks the control qubits of all gates in the given [`BasicBlock`], preventing further additions.
79
76
  #[no_mangle]
80
- pub extern "C" fn ket_block_lock_control(block: &mut BasicBlock) -> i32 {
77
+ pub extern "C" fn ket_block_lock_control(block: &mut Block) -> i32 {
81
78
  block.lock_control();
82
79
  c_ok()
83
80
  }
84
81
 
85
82
  /// Appends the contents of `other` block to `block` and consumes `other`.
86
83
  #[no_mangle]
87
- pub extern "C" fn ket_block_append_block(block: &mut BasicBlock, other: *mut BasicBlock) -> i32 {
84
+ pub extern "C" fn ket_block_append_block(block: &mut Block, other: *mut Block) -> i32 {
88
85
  let other = unsafe { Box::from_raw(other) };
89
86
  block.append_block(*other);
90
87
  c_ok()
@@ -92,7 +89,7 @@ pub extern "C" fn ket_block_append_block(block: &mut BasicBlock, other: *mut Bas
92
89
 
93
90
  /// Adds a global phase to the [`BasicBlock`].
94
91
  #[no_mangle]
95
- pub extern "C" fn ket_block_add_global_phase(block: &mut BasicBlock, phase: f64) -> i32 {
92
+ pub extern "C" fn ket_block_add_global_phase(block: &mut Block, phase: f64) -> i32 {
96
93
  block.add_global_phase(phase);
97
94
  c_ok()
98
95
  }
@@ -100,17 +97,17 @@ pub extern "C" fn ket_block_add_global_phase(block: &mut BasicBlock, phase: f64)
100
97
  /// Serializes the properties of the [`BasicBlock`] into a JSON payload and writes it to the buffer.
101
98
  #[no_mangle]
102
99
  pub extern "C" fn ket_block_proprieties_json(
103
- block: &BasicBlock,
100
+ block: &Block,
104
101
  proprieties: &mut *const c_char,
105
102
  ) -> i32 {
106
- *proprieties = to_json!(&block.qubits_op).into_raw();
103
+ *proprieties = to_json!(&block.flatten().unwrap().qubits_op).into_raw();
107
104
 
108
105
  c_ok()
109
106
  }
110
107
 
111
108
  /// Marks the [`BasicBlock`] as implementing a diagonal gate.
112
109
  #[no_mangle]
113
- pub extern "C" fn ket_block_set_as_diagonal(block: &mut BasicBlock) -> i32 {
110
+ pub extern "C" fn ket_block_set_as_diagonal(block: &mut Block) -> i32 {
114
111
  block.set_as_diagonal();
115
112
 
116
113
  c_ok()
@@ -118,7 +115,7 @@ pub extern "C" fn ket_block_set_as_diagonal(block: &mut BasicBlock) -> i32 {
118
115
 
119
116
  /// Marks the [`BasicBlock`] as implementing a permutation gate.
120
117
  #[no_mangle]
121
- pub extern "C" fn ket_block_set_as_permutation(block: &mut BasicBlock) -> i32 {
118
+ pub extern "C" fn ket_block_set_as_permutation(block: &mut Block) -> i32 {
122
119
  block.set_as_permutation();
123
120
 
124
121
  c_ok()
@@ -11,7 +11,7 @@ use std::ffi::{c_char, CStr, CString};
11
11
  use crate::{
12
12
  c_api::{c_error, c_ok},
13
13
  error::KetError,
14
- ir::{block::BasicBlock, gate::Param, hamiltonian::Hamiltonian},
14
+ ir::{block::Block, gate::Param, hamiltonian::Hamiltonian},
15
15
  process::{Process, ProcessState, QPUConfig},
16
16
  };
17
17
 
@@ -92,7 +92,7 @@ pub extern "C" fn ket_process_alloc(process: &mut Process, qubit: &mut usize) ->
92
92
  c_ok()
93
93
  }
94
94
 
95
- /// Appends a [`BasicBlock`] of gates to the process.
95
+ /// Appends a [`Block`] of gates to the process.
96
96
  ///
97
97
  /// The `block` is **consumed** by this call and must not be used afterwards.
98
98
  /// Returns an error if the process state does not allow gate appending
@@ -107,7 +107,7 @@ pub extern "C" fn ket_process_alloc(process: &mut Process, qubit: &mut usize) ->
107
107
  /// `0` on success, non-zero error code on failure (including
108
108
  /// `GateAppendForbidden` and `QubitIndexOutOfRange`).
109
109
  #[no_mangle]
110
- pub extern "C" fn ket_process_append_block(process: &mut Process, block: *mut BasicBlock) -> i32 {
110
+ pub extern "C" fn ket_process_append_block(process: &mut Process, block: *mut Block) -> i32 {
111
111
  let block = unsafe { *Box::from_raw(block) };
112
112
  c_error(process.append_block(block))
113
113
  }
@@ -127,7 +127,7 @@ pub extern "C" fn ket_process_append_block(process: &mut Process, block: *mut Ba
127
127
  /// `0` on success, non-zero error code on failure.
128
128
  #[no_mangle]
129
129
  pub extern "C" fn ket_process_gates_json(process: &Process, block: &mut *mut c_char) -> i32 {
130
- *block = to_json!(&process.main_block().gates).into_raw();
130
+ *block = to_json!(&process.main_block().flatten().unwrap().gates).into_raw();
131
131
  c_ok()
132
132
  }
133
133
 
@@ -449,7 +449,7 @@ pub extern "C" fn ket_process_set_parameter(
449
449
  }
450
450
 
451
451
  /// Parses an `OpenQASM` 2.0 source string and returns a heap-allocated
452
- /// [`BasicBlock`] containing the resulting gate sequence.
452
+ /// [`Block`] containing the resulting gate sequence.
453
453
  ///
454
454
  /// Physical qubit indices are mapped to the `qreg` declarations in the source
455
455
  /// in order. The total number of entries in `qubits` must be ≥ the sum of all
@@ -459,7 +459,7 @@ pub extern "C" fn ket_process_set_parameter(
459
459
  /// recorded so that subsequent `if` statements are converted to controlled
460
460
  /// quantum gates instead of classical branches.
461
461
  ///
462
- /// On success, a newly heap-allocated `BasicBlock` is written to `*block_out`.
462
+ /// On success, a newly heap-allocated `Block` is written to `*block_out`.
463
463
  /// The caller takes ownership and must eventually free it with
464
464
  /// [`ket_block_delete`].
465
465
  ///
@@ -467,7 +467,7 @@ pub extern "C" fn ket_process_set_parameter(
467
467
  /// - `qubits` : Pointer to an array of `size_t` physical qubit indices.
468
468
  /// - `qubits_len` : Number of entries in `qubits`.
469
469
  /// - `qasm` : Null-terminated C string with the `OpenQASM` 2.0 source.
470
- /// - `block_out` : Output: on success, set to a pointer to the new `BasicBlock`.
470
+ /// - `block_out` : Output: on success, set to a pointer to the new `Block`.
471
471
  ///
472
472
  /// # Returns
473
473
  /// `0` on success, non-zero error code on failure.
@@ -477,7 +477,7 @@ pub unsafe extern "C" fn ket_parse_openqasm(
477
477
  qubits: *const usize,
478
478
  qubits_len: usize,
479
479
  qasm: *const c_char,
480
- block_out: &mut *mut crate::ir::block::BasicBlock,
480
+ block_out: &mut *mut Block,
481
481
  ) -> i32 {
482
482
  if qasm.is_null() || (qubits_len > 0 && qubits.is_null()) {
483
483
  return KetError::OpenQasmParseError.error_code();
@@ -495,10 +495,39 @@ pub unsafe extern "C" fn ket_parse_openqasm(
495
495
  };
496
496
 
497
497
  match crate::qasm::parse_openqasm(qubit_slice, qasm_str) {
498
- Ok(block) => {
498
+ Ok(bb) => {
499
+ let mut block = Block::new();
500
+ block.append_basic_block(bb);
499
501
  *block_out = Box::into_raw(Box::new(block));
500
502
  c_ok()
501
503
  }
502
504
  Err(e) => e.error_code(),
503
505
  }
504
506
  }
507
+
508
+ /// Creates a BasicBlock that implements the Quantum Fourier Transform (QFT) on the given qubits.
509
+ ///
510
+ /// On success, a newly heap-allocated `Block` is written to `*block_out`.
511
+ /// The caller takes ownership and must eventually free it with [`ket_block_delete`].
512
+ ///
513
+ /// # Parameters
514
+ /// - `qubits` : Pointer to an array of `size_t` physical qubit indices. The MSQ should be at index 0.
515
+ /// - `qubits_len` : Number of entries in `qubits`.
516
+ /// - `do_swap` : Boolean flag indicating whether to add SWAP gates at the end of the circuit to reverse the qubit order.
517
+ /// - `block_out` : Output: on success, set to a pointer to the new `Block`.
518
+ ///
519
+ /// # Returns
520
+ /// `0` on success, non-zero error code on failure.
521
+ #[no_mangle]
522
+ pub unsafe extern "C" fn ket_qft(
523
+ qubits: *const usize,
524
+ qubits_len: usize,
525
+ do_swap: bool,
526
+ block_out: &mut *mut Block,
527
+ ) -> i32 {
528
+ let qubits = unsafe { std::slice::from_raw_parts(qubits, qubits_len) };
529
+
530
+ *block_out = Box::into_raw(Box::new(c_error!(crate::qft(qubits, do_swap))));
531
+
532
+ c_ok()
533
+ }
@@ -179,6 +179,9 @@ pub enum KetError {
179
179
  )]
180
180
  DumpUnavailableInBatch,
181
181
 
182
+ #[error("unknown macro")]
183
+ UnknownMacro,
184
+
182
185
  /// `execute` was called on a process that has no pending measurement or
183
186
  /// expectation-value request.
184
187
  ///
@@ -355,6 +358,7 @@ impl KetError {
355
358
  Self::SamplingUnavailable => 8,
356
359
  Self::ExpectationValueUnavailable => 9,
357
360
  Self::DumpUnavailableInBatch => 10,
361
+ Self::UnknownMacro => 24,
358
362
  Self::NoPendingMeasurement => 11,
359
363
  Self::ExplicitExecuteInLiveMode => 12,
360
364
  Self::ExecutionFailed => 13,
@@ -397,6 +401,7 @@ impl KetError {
397
401
  8 => Self::SamplingUnavailable,
398
402
  9 => Self::ExpectationValueUnavailable,
399
403
  10 => Self::DumpUnavailableInBatch,
404
+ 24 => Self::UnknownMacro,
400
405
  11 => Self::NoPendingMeasurement,
401
406
  12 => Self::ExplicitExecuteInLiveMode,
402
407
  13 => Self::ExecutionFailed,
@@ -438,6 +443,7 @@ mod tests {
438
443
  KetError::SamplingUnavailable,
439
444
  KetError::ExpectationValueUnavailable,
440
445
  KetError::DumpUnavailableInBatch,
446
+ KetError::UnknownMacro,
441
447
  KetError::NoPendingMeasurement,
442
448
  KetError::ExplicitExecuteInLiveMode,
443
449
  KetError::ExecutionFailed,
@@ -474,6 +480,7 @@ mod tests {
474
480
  KetError::SamplingUnavailable,
475
481
  KetError::ExpectationValueUnavailable,
476
482
  KetError::DumpUnavailableInBatch,
483
+ KetError::UnknownMacro,
477
484
  KetError::NoPendingMeasurement,
478
485
  KetError::ExplicitExecuteInLiveMode,
479
486
  KetError::ExpValueNotSupported,