ket-lang 0.9.2.dev1__tar.gz → 0.9.2.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.
Files changed (114) hide show
  1. {ket_lang-0.9.2.dev1/src/ket_lang.egg-info → ket_lang-0.9.2.dev2}/PKG-INFO +1 -1
  2. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/__init__.py +1 -1
  3. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/base.py +3 -1
  4. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/kbw.py +8 -1
  5. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/Cargo.toml +2 -1
  6. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/examples/grover.rs +2 -2
  7. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/bitwise.rs +12 -4
  8. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/c_api.rs +10 -1
  9. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/dense.rs +80 -59
  10. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/dense_gpu.rs +37 -39
  11. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/dense_v2.rs +62 -54
  12. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/lib.rs +27 -3
  13. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/sparse.rs +50 -47
  14. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2/src/ket_lang.egg-info}/PKG-INFO +1 -1
  15. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/tests/test_u3_gate.py +2 -2
  16. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/tests/test_unitaty_gate.py +2 -2
  17. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/LICENSE +0 -0
  18. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/MANIFEST.in +0 -0
  19. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/README.md +0 -0
  20. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/pyproject.toml +0 -0
  21. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/setup.cfg +0 -0
  22. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/setup.py +0 -0
  23. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/amazon.py +0 -0
  24. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/__init__.py +0 -0
  25. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libket.py +0 -0
  26. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/__init__.py +0 -0
  27. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/.git +0 -0
  28. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/.gitignore +0 -0
  29. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/.gitlab-ci.yml +0 -0
  30. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/.pre-commit-config.yaml +0 -0
  31. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/CHANGELOG.md +0 -0
  32. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/LICENSE +0 -0
  33. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/LICENSES/Apache-2.0.txt +0 -0
  34. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/README.md +0 -0
  35. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/REUSE.toml +0 -0
  36. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/build.rs +0 -0
  37. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/examples/grover_gpu.rs +0 -0
  38. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/convert.rs +0 -0
  39. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/error.rs +0 -0
  40. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/kbw/src/quantum_execution.rs +0 -0
  41. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/.git +0 -0
  42. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/.gitignore +0 -0
  43. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/.gitlab-ci.yml +0 -0
  44. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/.pre-commit-config.yaml +0 -0
  45. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/CHANGELOG.md +0 -0
  46. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/Cargo.toml +0 -0
  47. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/LICENSE +0 -0
  48. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/LICENSES/Apache-2.0.txt +0 -0
  49. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/README.md +0 -0
  50. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/REUSE.toml +0 -0
  51. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/build.rs +0 -0
  52. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/examples/grover.rs +0 -0
  53. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/examples/qft.rs +0 -0
  54. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/c_api/error.rs +0 -0
  55. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/c_api/execution.rs +0 -0
  56. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/c_api/mod.rs +0 -0
  57. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/c_api/objects.rs +0 -0
  58. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/c_api/process.rs +0 -0
  59. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/circuit.rs +0 -0
  60. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/mod.rs +0 -0
  61. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/network.rs +0 -0
  62. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/su2.rs +0 -0
  63. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/u2.rs +0 -0
  64. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/util.rs +0 -0
  65. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/x/c2to4x.rs +0 -0
  66. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/x/mod.rs +0 -0
  67. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/x/single_aux.rs +0 -0
  68. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/decompose/x/v_chain.rs +0 -0
  69. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/error.rs +0 -0
  70. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/ex_arch.rs +0 -0
  71. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/execution.rs +0 -0
  72. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/graph.rs +0 -0
  73. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/ir/gate.rs +0 -0
  74. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/ir/hamiltonian.rs +0 -0
  75. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/ir/instructions.rs +0 -0
  76. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/ir/mod.rs +0 -0
  77. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/ir/qubit.rs +0 -0
  78. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/lib.rs +0 -0
  79. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/mapping/allocation.rs +0 -0
  80. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/mapping/graph.rs +0 -0
  81. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/mapping/map.rs +0 -0
  82. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/mapping/mcpe.rs +0 -0
  83. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/mapping/mod.rs +0 -0
  84. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/prelude.rs +0 -0
  85. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/process/aux.rs +0 -0
  86. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/process/ctrl.rs +0 -0
  87. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/process/execution.rs +0 -0
  88. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/process/measure.rs +0 -0
  89. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/process/mod.rs +0 -0
  90. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/process/util.rs +0 -0
  91. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/libs/libket/src/util.rs +0 -0
  92. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/clib/wrapper.py +0 -0
  93. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/expv.py +0 -0
  94. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/gates.py +0 -0
  95. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/ibm.py +0 -0
  96. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/npsim.py +0 -0
  97. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/operations.py +0 -0
  98. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/quantumstate.py +0 -0
  99. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/quforge.py +0 -0
  100. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/qulib/__init__.py +0 -0
  101. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/qulib/gates.py +0 -0
  102. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/qulib/ham.py +0 -0
  103. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/qulib/math.py +0 -0
  104. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/qulib/oracle.py +0 -0
  105. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/qulib/prepare.py +0 -0
  106. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket/remote.py +0 -0
  107. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket_lang.egg-info/SOURCES.txt +0 -0
  108. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket_lang.egg-info/dependency_links.txt +0 -0
  109. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket_lang.egg-info/not-zip-safe +0 -0
  110. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket_lang.egg-info/requires.txt +0 -0
  111. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/src/ket_lang.egg-info/top_level.txt +0 -0
  112. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/tests/test_decompose.py +0 -0
  113. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/tests/test_grover.py +0 -0
  114. {ket_lang-0.9.2.dev1 → ket_lang-0.9.2.dev2}/tests/test_phase_estimation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ket-lang
3
- Version: 0.9.2.dev1
3
+ Version: 0.9.2.dev2
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
@@ -91,7 +91,7 @@ from .quantumstate import *
91
91
  from .quantumstate import __all__ as all_state
92
92
  from . import qulib
93
93
 
94
- __version__ = "0.9.2dev1"
94
+ __version__ = "0.9.2dev2"
95
95
 
96
96
  __all__ = all_base + all_func + all_gate + all_expv + all_state + ["qulib"]
97
97
 
@@ -127,7 +127,9 @@ class Process(LibketProcess):
127
127
  self,
128
128
  execution_target: BatchExecution | LiveExecution | None = None,
129
129
  num_qubits: Optional[int] = None,
130
- simulator: Optional[Literal["sparse", "dense", "dense v2", "dense gpu"]] = None,
130
+ simulator: Optional[
131
+ Literal["sparse", "dense", "dense v2", "dense gpu", "dense cuda"]
132
+ ] = None,
131
133
  execution: Optional[Literal["live", "batch"]] = None,
132
134
  gradient: bool = False,
133
135
  **kwargs,
@@ -60,6 +60,7 @@ _SIMULATOR = {
60
60
  "sparse": 1,
61
61
  "dense v2": 2,
62
62
  "dense gpu": 3,
63
+ "dense cuda": 4,
63
64
  }
64
65
 
65
66
 
@@ -69,7 +70,13 @@ _CLASSICAL_SHADOWS = {"bias": (1, 1, 1), "samples": 1_000, "shots": 2048}
69
70
  def get_simulator( # pylint: disable=too-many-arguments,too-many-positional-arguments
70
71
  num_qubits: int,
71
72
  execution: Literal["live", "batch"] = "live",
72
- simulator: Literal["sparse", "dense", "dense v2", "dense gpu"] = "sparse",
73
+ simulator: Literal[
74
+ "sparse",
75
+ "dense",
76
+ "dense v2",
77
+ "dense gpu",
78
+ "dense cuda",
79
+ ] = "sparse",
73
80
  coupling_graph: list[tuple[int, int]] | None = None,
74
81
  gradient: bool = False,
75
82
  classical_shadows=None,
@@ -32,8 +32,9 @@ build-info = { version = "0.0.42", default-features = false, features = [] }
32
32
  serde = { version = "1.0.228", features = ["derive"] }
33
33
  serde_json = "1.0.145"
34
34
  indexmap = "2.12.1"
35
+ num-traits = "0.2"
35
36
 
36
- cubecl = { version = "0.8.1", features = ["wgpu"] }
37
+ cubecl = { version = "0.8.1", features = ["wgpu", "cuda"] }
37
38
 
38
39
  [build-dependencies]
39
40
  build-info-build = "0.0.42"
@@ -4,12 +4,12 @@
4
4
 
5
5
  use std::f64::consts::{FRAC_PI_2, FRAC_PI_4};
6
6
 
7
- use kbw::DenseSimulator;
7
+ use kbw::DenseV2Simulator;
8
8
  use ket::prelude::*;
9
9
 
10
10
  fn main() -> Result<(), KetError> {
11
11
  let size = 12;
12
- let (target, execution) = DenseSimulator::configuration(size, false, None, None, None, false);
12
+ let (target, execution) = DenseV2Simulator::configuration(size, false, None, None, None, false);
13
13
 
14
14
  let mut process = Process::new(target, execution);
15
15
 
@@ -3,8 +3,20 @@
3
3
  //
4
4
  // SPDX-License-Identifier: Apache-2.0
5
5
 
6
+ use std::ops::{BitOrAssign, Shl};
7
+
6
8
  use num::Integer;
7
9
 
10
+ pub(crate) fn get_ctrl_mask<T: Integer + BitOrAssign + Shl<usize, Output = T>>(
11
+ control: &[usize],
12
+ ) -> T {
13
+ let mut control_mask = T::zero();
14
+ for c in control {
15
+ control_mask |= T::one() << *c;
16
+ }
17
+ control_mask
18
+ }
19
+
8
20
  pub(crate) fn bit_flip(state: usize, index: usize) -> usize {
9
21
  state ^ (1 << index)
10
22
  }
@@ -24,10 +36,6 @@ pub(crate) fn is_one_at_vec(state: &[u64], target: usize) -> bool {
24
36
  state[outer_index] & (1 << inner_index) != 0
25
37
  }
26
38
 
27
- pub(crate) fn ctrl_check(state: usize, control: &[usize]) -> bool {
28
- control.iter().all(|control| is_one_at(state, *control))
29
- }
30
-
31
39
  pub(crate) fn ctrl_check_vec(state: &[u64], control: &[usize]) -> bool {
32
40
  control.iter().all(|control| is_one_at_vec(state, *control))
33
41
  }
@@ -4,7 +4,8 @@
4
4
  // SPDX-License-Identifier: Apache-2.0
5
5
 
6
6
  use crate::{
7
- error::KBWError, DenseGPUSimulator, DenseSimulator, DenseV2Simulator, SparseSimulator,
7
+ error::KBWError, DenseCUDASimulator, DenseGPUSimulator, DenseSimulator, DenseV2Simulator,
8
+ SparseSimulator,
8
9
  };
9
10
  use env_logger::Builder;
10
11
  use ket::prelude::ExecutionTarget;
@@ -129,6 +130,14 @@ pub unsafe extern "C" fn kbw_make_configuration(
129
130
  classical_shadows,
130
131
  gradient,
131
132
  ),
133
+ 4 => DenseCUDASimulator::configuration(
134
+ num_qubits,
135
+ use_live,
136
+ coupling_graph,
137
+ sample_base,
138
+ classical_shadows,
139
+ gradient,
140
+ ),
132
141
  _ => return KBWError::InvalidSimulator.error_code(),
133
142
  }));
134
143
 
@@ -3,30 +3,30 @@
3
3
  //
4
4
  // SPDX-License-Identifier: Apache-2.0
5
5
 
6
- use crate::bitwise::*;
7
6
  use crate::error::{KBWError, Result};
8
7
  use crate::quantum_execution::{ExecutionFeatures, QuantumExecution};
8
+ use crate::{bitwise::*, FloatOps};
9
9
  use itertools::Itertools;
10
10
  use ket::execution::*;
11
11
  use ket::process::DumpData;
12
12
  use log::error;
13
- use num::{complex::Complex64, Zero};
13
+ use num::complex::Complex;
14
+ use num::{One, Zero};
14
15
  use rand::distr::weighted::WeightedIndex;
15
16
  use rand::prelude::*;
16
17
  use rayon::prelude::*;
17
18
  use serde::{Deserialize, Serialize};
18
- use std::f64::consts::FRAC_1_SQRT_2;
19
19
 
20
20
  #[derive(Serialize, Deserialize)]
21
- pub struct Dense {
22
- state_0: Vec<Complex64>,
23
- state_1: Vec<Complex64>,
21
+ pub struct Dense<F: FloatOps> {
22
+ state_0: Vec<Complex<F>>,
23
+ state_1: Vec<Complex<F>>,
24
24
  state: bool,
25
25
  num_states: usize,
26
26
  }
27
27
 
28
- impl Dense {
29
- fn get_states(&mut self) -> (&mut [Complex64], &mut [Complex64]) {
28
+ impl<F: FloatOps> Dense<F> {
29
+ fn get_states(&mut self) -> (&mut [Complex<F>], &mut [Complex<F>]) {
30
30
  self.state = !self.state;
31
31
  if self.state {
32
32
  (&mut self.state_1, &mut self.state_0)
@@ -35,7 +35,7 @@ impl Dense {
35
35
  }
36
36
  }
37
37
 
38
- fn get_current_state(&self) -> &[Complex64] {
38
+ fn get_current_state(&self) -> &[Complex<F>] {
39
39
  if self.state {
40
40
  &self.state_0
41
41
  } else {
@@ -44,7 +44,7 @@ impl Dense {
44
44
  }
45
45
  }
46
46
 
47
- impl QuantumExecution for Dense {
47
+ impl<F: FloatOps> QuantumExecution for Dense<F> {
48
48
  fn new(num_qubits: usize) -> Result<Self> {
49
49
  if num_qubits > 32 {
50
50
  error!("dense implementation supports up to 32 qubits");
@@ -54,10 +54,10 @@ impl QuantumExecution for Dense {
54
54
  let num_states = 1 << num_qubits;
55
55
  let mut state_0 = Vec::new();
56
56
  let mut state_1 = Vec::new();
57
- state_0.resize(num_states, Complex64::zero());
58
- state_1.resize(num_states, Complex64::zero());
57
+ state_0.resize(num_states, Complex::<F>::zero());
58
+ state_1.resize(num_states, Complex::<F>::zero());
59
59
 
60
- state_0[0] = Complex64::new(1.0, 0.0);
60
+ state_0[0] = Complex::<F>::one();
61
61
 
62
62
  Ok(Dense {
63
63
  state: true,
@@ -70,11 +70,13 @@ impl QuantumExecution for Dense {
70
70
  fn pauli_x(&mut self, target: usize, control: &[usize]) {
71
71
  let (current_state, next_state) = self.get_states();
72
72
 
73
+ let ctrl_mask: usize = get_ctrl_mask(control);
74
+
73
75
  next_state
74
76
  .par_iter_mut()
75
77
  .enumerate()
76
78
  .for_each(|(state, amp)| {
77
- *amp = current_state[if ctrl_check(state, control) {
79
+ *amp = current_state[if (state & ctrl_mask) == ctrl_mask {
78
80
  bit_flip(state, target)
79
81
  } else {
80
82
  state
@@ -85,16 +87,18 @@ impl QuantumExecution for Dense {
85
87
  fn pauli_y(&mut self, target: usize, control: &[usize]) {
86
88
  let (current_state, next_state) = self.get_states();
87
89
 
90
+ let ctrl_mask: usize = get_ctrl_mask(control);
91
+
88
92
  next_state
89
93
  .par_iter_mut()
90
94
  .enumerate()
91
95
  .for_each(|(state, amp)| {
92
- if ctrl_check(state, control) {
96
+ if (state & ctrl_mask) == ctrl_mask {
93
97
  *amp = current_state[bit_flip(state, target)]
94
98
  * if is_one_at(state, target) {
95
- Complex64::i()
99
+ Complex::<F>::i()
96
100
  } else {
97
- -Complex64::i()
101
+ -Complex::<F>::i()
98
102
  };
99
103
  } else {
100
104
  *amp = current_state[state];
@@ -105,11 +109,13 @@ impl QuantumExecution for Dense {
105
109
  fn pauli_z(&mut self, target: usize, control: &[usize]) {
106
110
  let (current_state, next_state) = self.get_states();
107
111
 
112
+ let ctrl_mask: usize = get_ctrl_mask(control);
113
+
108
114
  next_state
109
115
  .par_iter_mut()
110
116
  .enumerate()
111
117
  .for_each(|(state, amp)| {
112
- if ctrl_check(state, control) && is_one_at(state, target) {
118
+ if (state & ctrl_mask) == ctrl_mask && is_one_at(state, target) {
113
119
  *amp = -current_state[state];
114
120
  } else {
115
121
  *amp = current_state[state];
@@ -120,14 +126,16 @@ impl QuantumExecution for Dense {
120
126
  fn hadamard(&mut self, target: usize, control: &[usize]) {
121
127
  let (current_state, next_state) = self.get_states();
122
128
 
129
+ let ctrl_mask: usize = get_ctrl_mask(control);
130
+
123
131
  next_state
124
132
  .par_iter_mut()
125
133
  .enumerate()
126
134
  .for_each(|(state, amp)| {
127
- if ctrl_check(state, control) {
128
- *amp = current_state[bit_flip(state, target)] * FRAC_1_SQRT_2;
135
+ if (state & ctrl_mask) == ctrl_mask {
136
+ *amp = current_state[bit_flip(state, target)] * F::FRAC_1_SQRT_2();
129
137
  } else {
130
- *amp = Complex64::zero();
138
+ *amp = Complex::<F>::zero();
131
139
  }
132
140
  });
133
141
 
@@ -135,11 +143,11 @@ impl QuantumExecution for Dense {
135
143
  .par_iter_mut()
136
144
  .enumerate()
137
145
  .for_each(|(state, amp)| {
138
- if ctrl_check(state, control) {
146
+ if (state & ctrl_mask) == ctrl_mask {
139
147
  *amp *= if is_one_at(state, target) {
140
- -FRAC_1_SQRT_2
148
+ -F::FRAC_1_SQRT_2()
141
149
  } else {
142
- FRAC_1_SQRT_2
150
+ F::FRAC_1_SQRT_2()
143
151
  };
144
152
  }
145
153
  });
@@ -155,13 +163,15 @@ impl QuantumExecution for Dense {
155
163
  fn phase(&mut self, lambda: f64, target: usize, control: &[usize]) {
156
164
  let (current_state, next_state) = self.get_states();
157
165
 
158
- let phase = Complex64::exp(lambda * Complex64::i());
166
+ let phase = Complex::<F>::exp(Complex::<F>::i() * F::from(lambda).unwrap());
167
+
168
+ let ctrl_mask: usize = get_ctrl_mask(control);
159
169
 
160
170
  next_state
161
171
  .par_iter_mut()
162
172
  .enumerate()
163
173
  .for_each(|(state, amp)| {
164
- if ctrl_check(state, control) && is_one_at(state, target) {
174
+ if (state & ctrl_mask) == ctrl_mask && is_one_at(state, target) {
165
175
  *amp = current_state[state] * phase;
166
176
  } else {
167
177
  *amp = current_state[state];
@@ -172,17 +182,19 @@ impl QuantumExecution for Dense {
172
182
  fn rx(&mut self, theta: f64, target: usize, control: &[usize]) {
173
183
  let (current_state, next_state) = self.get_states();
174
184
 
175
- let cons_theta_2 = Complex64::from(f64::cos(theta / 2.0));
176
- let sin_theta_2 = -Complex64::i() * f64::sin(theta / 2.0);
185
+ let cons_theta_2 = Complex::<F>::from(F::cos(F::from(theta / 2.0).unwrap()));
186
+ let sin_theta_2 = -Complex::<F>::i() * F::sin(F::from(theta / 2.0).unwrap());
187
+
188
+ let ctrl_mask: usize = get_ctrl_mask(control);
177
189
 
178
190
  next_state
179
191
  .par_iter_mut()
180
192
  .enumerate()
181
193
  .for_each(|(state, amp)| {
182
- if ctrl_check(state, control) {
194
+ if (state & ctrl_mask) == ctrl_mask {
183
195
  *amp = current_state[bit_flip(state, target)] * sin_theta_2;
184
196
  } else {
185
- *amp = Complex64::zero();
197
+ *amp = Complex::<F>::zero();
186
198
  }
187
199
  });
188
200
 
@@ -190,7 +202,7 @@ impl QuantumExecution for Dense {
190
202
  .par_iter_mut()
191
203
  .enumerate()
192
204
  .for_each(|(state, amp)| {
193
- if ctrl_check(state, control) {
205
+ if (state & ctrl_mask) == ctrl_mask {
194
206
  *amp *= cons_theta_2;
195
207
  }
196
208
  });
@@ -206,15 +218,17 @@ impl QuantumExecution for Dense {
206
218
  fn ry(&mut self, theta: f64, target: usize, control: &[usize]) {
207
219
  let (current_state, next_state) = self.get_states();
208
220
 
209
- let cons_theta_2 = Complex64::from(f64::cos(theta / 2.0));
210
- let p_sin_theta_2 = Complex64::from(f64::sin(theta / 2.0));
221
+ let cons_theta_2 = Complex::<F>::from(F::cos(F::from(theta / 2.0).unwrap()));
222
+ let p_sin_theta_2 = Complex::<F>::from(F::sin(F::from(theta / 2.0).unwrap()));
211
223
  let m_sin_theta_2 = -p_sin_theta_2;
212
224
 
225
+ let ctrl_mask: usize = get_ctrl_mask(control);
226
+
213
227
  next_state
214
228
  .par_iter_mut()
215
229
  .enumerate()
216
230
  .for_each(|(state, amp)| {
217
- if ctrl_check(state, control) {
231
+ if (state & ctrl_mask) == ctrl_mask {
218
232
  *amp = current_state[bit_flip(state, target)]
219
233
  * if is_one_at(state, target) {
220
234
  p_sin_theta_2
@@ -222,7 +236,7 @@ impl QuantumExecution for Dense {
222
236
  m_sin_theta_2
223
237
  };
224
238
  } else {
225
- *amp = Complex64::zero();
239
+ *amp = Complex::<F>::zero();
226
240
  }
227
241
  });
228
242
 
@@ -230,7 +244,7 @@ impl QuantumExecution for Dense {
230
244
  .par_iter_mut()
231
245
  .enumerate()
232
246
  .for_each(|(state, amp)| {
233
- if ctrl_check(state, control) {
247
+ if (state & ctrl_mask) == ctrl_mask {
234
248
  *amp *= cons_theta_2;
235
249
  }
236
250
  });
@@ -246,14 +260,16 @@ impl QuantumExecution for Dense {
246
260
  fn rz(&mut self, theta: f64, target: usize, control: &[usize]) {
247
261
  let (current_state, next_state) = self.get_states();
248
262
 
249
- let phase_0 = Complex64::exp(-theta / 2.0 * Complex64::i());
250
- let phase_1 = Complex64::exp(theta / 2.0 * Complex64::i());
263
+ let phase_0 = Complex::<F>::exp(Complex::<F>::i() * F::from(-theta / 2.0).unwrap());
264
+ let phase_1 = Complex::<F>::exp(Complex::<F>::i() * F::from(theta / 2.0).unwrap());
265
+
266
+ let ctrl_mask: usize = get_ctrl_mask(control);
251
267
 
252
268
  next_state
253
269
  .par_iter_mut()
254
270
  .enumerate()
255
271
  .for_each(|(state, amp)| {
256
- if ctrl_check(state, control) {
272
+ if (state & ctrl_mask) == ctrl_mask {
257
273
  *amp = current_state[state]
258
274
  * if is_one_at(state, target) {
259
275
  phase_1
@@ -269,26 +285,29 @@ impl QuantumExecution for Dense {
269
285
  fn measure<R: Rng>(&mut self, target: usize, rng: &mut R) -> bool {
270
286
  let (current_state, next_state) = self.get_states();
271
287
 
272
- let p1: f64 = current_state
288
+ let p1: F = current_state
273
289
  .par_iter()
274
290
  .enumerate()
275
291
  .map(|(state, amp)| {
276
292
  if is_one_at(state, target) {
277
293
  amp.norm().powi(2)
278
294
  } else {
279
- 0.0
295
+ F::zero()
280
296
  }
281
297
  })
282
298
  .sum();
283
299
 
284
- let p0 = match 1.0 - p1 {
285
- p0 if p0 >= 0.0 => p0,
286
- _ => 0.0,
300
+ let p0 = match F::one() - p1 {
301
+ p0 if p0 >= F::zero() => p0,
302
+ _ => F::zero(),
287
303
  };
288
304
 
289
- let result = WeightedIndex::new([p0, p1]).unwrap().sample(rng) == 1;
305
+ let result = WeightedIndex::new([p0.to_f64().unwrap(), p1.to_f64().unwrap()])
306
+ .unwrap()
307
+ .sample(rng)
308
+ == 1;
290
309
 
291
- let p = 1.0 / f64::sqrt(if result { p1 } else { p0 });
310
+ let p = F::one() / F::sqrt(if result { p1 } else { p0 });
292
311
 
293
312
  next_state
294
313
  .par_iter_mut()
@@ -297,7 +316,7 @@ impl QuantumExecution for Dense {
297
316
  *amp = if is_one_at(state, target) == result {
298
317
  current_state[state] * p
299
318
  } else {
300
- Complex64::zero()
319
+ Complex::<F>::zero()
301
320
  };
302
321
  });
303
322
 
@@ -306,10 +325,10 @@ impl QuantumExecution for Dense {
306
325
 
307
326
  fn dump(&mut self, qubits: &[usize]) -> DumpData {
308
327
  let state = self.get_current_state();
309
- let (basis_states, amplitudes_real, amplitudes_imag): (Vec<_>, Vec<_>, Vec<_>) = state
328
+ let (basis_states, amplitudes_real, amplitudes_imag): (Vec<_>, Vec<f64>, Vec<f64>) = state
310
329
  .iter()
311
330
  .enumerate()
312
- .filter(|(_state, amp)| amp.norm() > 1e-15)
331
+ .filter(|(_state, amp)| amp.norm() > F::from(1e-15).unwrap())
313
332
  .map(|(state, amp)| {
314
333
  let state = qubits
315
334
  .iter()
@@ -319,7 +338,11 @@ impl QuantumExecution for Dense {
319
338
  .reduce(|a, b| a | b)
320
339
  .unwrap_or(0);
321
340
 
322
- (Vec::from([state as u64]), amp.re, amp.im)
341
+ (
342
+ Vec::from([state as u64]),
343
+ amp.re.to_f64().unwrap(),
344
+ amp.im.to_f64().unwrap(),
345
+ )
323
346
  })
324
347
  .multiunzip();
325
348
 
@@ -333,24 +356,22 @@ impl QuantumExecution for Dense {
333
356
  fn clear(&mut self) {
334
357
  self.state_0.clear();
335
358
  self.state_1.clear();
336
- self.state_0.resize(self.num_states, Complex64::zero());
337
- self.state_1.resize(self.num_states, Complex64::zero());
338
- self.state_0[0] = Complex64::new(1.0, 0.0);
359
+ self.state_0.resize(self.num_states, Complex::<F>::zero());
360
+ self.state_1.resize(self.num_states, Complex::<F>::zero());
361
+ self.state_0[0] = Complex::<F>::one();
339
362
  self.state = true;
340
363
  }
341
364
 
342
365
  fn save(&self) -> Vec<u8> {
343
- serde_json::to_vec(&self).unwrap()
366
+ unimplemented!()
344
367
  }
345
368
 
346
- fn load(&mut self, data: &[u8]) {
347
- if let Ok(simulator) = serde_json::from_slice::<Self>(data) {
348
- *self = simulator;
349
- }
369
+ fn load(&mut self, _data: &[u8]) {
370
+ unimplemented!()
350
371
  }
351
372
  }
352
373
 
353
- impl ExecutionFeatures for Dense {
374
+ impl<F: FloatOps> ExecutionFeatures for Dense<F> {
354
375
  fn feature_measure() -> Capability {
355
376
  Capability::Advanced
356
377
  }