pyqrack-cpu 2.5.1__tar.gz → 2.7.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.
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/Makefile +1 -1
- {pyqrack_cpu-2.5.1/pyqrack_cpu.egg-info → pyqrack_cpu-2.7.0}/PKG-INFO +1 -1
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_ace_backend.py +143 -19
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_simulator.py +18 -10
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_system/qrack_system.py +9 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0/pyqrack_cpu.egg-info}/PKG-INFO +1 -1
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/setup.py +1 -1
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/LICENSE +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/MANIFEST.in +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/README.md +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyproject.toml +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/__init__.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/neuron_activation_fn.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/pauli.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_circuit.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_near_clifford_qec_backend.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_neuron.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_neuron_torch_layer.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_stabilizer.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/qrack_system/__init__.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/quimb_circuit_type.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/stats/__init__.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/stats/load_quantized_data.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack/stats/quantize_by_range.py +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/SOURCES.txt +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/dependency_links.txt +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/not-zip-safe +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/requires.txt +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/pyqrack_cpu.egg-info/top_level.txt +0 -0
- {pyqrack_cpu-2.5.1 → pyqrack_cpu-2.7.0}/setup.cfg +0 -0
|
@@ -30,7 +30,7 @@ build-deps:
|
|
|
30
30
|
rm -rf pyqrack/qrack_system/qrack_cl_precompile
|
|
31
31
|
ifneq ($(OS),Windows_NT)
|
|
32
32
|
ifeq ($(QRACK_PRESENT),)
|
|
33
|
-
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout
|
|
33
|
+
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout f407a468fa81ccb47e1a8ace3514ec689d03de4c; cd ..
|
|
34
34
|
endif
|
|
35
35
|
mkdir -p qrack/build
|
|
36
36
|
ifeq ($(UNAME_S),Linux)
|
|
@@ -9,6 +9,7 @@ import os
|
|
|
9
9
|
import random
|
|
10
10
|
import sys
|
|
11
11
|
import time
|
|
12
|
+
from collections import deque
|
|
12
13
|
|
|
13
14
|
from .qrack_simulator import QrackSimulator
|
|
14
15
|
from .pauli import Pauli
|
|
@@ -230,6 +231,7 @@ class QrackAceBackend:
|
|
|
230
231
|
is_host_pointer=(True if os.environ.get("PYQRACK_HOST_POINTER_DEFAULT_ON") else False),
|
|
231
232
|
is_near_clifford_tableau_writer=False,
|
|
232
233
|
noise=0,
|
|
234
|
+
history_window=0,
|
|
233
235
|
to_clone=None,
|
|
234
236
|
):
|
|
235
237
|
if to_clone:
|
|
@@ -237,15 +239,19 @@ class QrackAceBackend:
|
|
|
237
239
|
long_range_columns = to_clone.long_range_columns
|
|
238
240
|
long_range_rows = to_clone.long_range_rows
|
|
239
241
|
is_transpose = to_clone.is_transpose
|
|
242
|
+
history_window = to_clone.history_window
|
|
240
243
|
if qubit_count < 0:
|
|
241
244
|
qubit_count = 0
|
|
242
245
|
if long_range_columns < 0:
|
|
243
246
|
long_range_columns = 0
|
|
247
|
+
if history_window < 0:
|
|
248
|
+
history_window = 0
|
|
244
249
|
|
|
245
250
|
self._factor_width(qubit_count, is_transpose)
|
|
246
251
|
self.long_range_columns = long_range_columns
|
|
247
252
|
self.long_range_rows = long_range_rows
|
|
248
253
|
self.is_transpose = is_transpose
|
|
254
|
+
self.history_window = history_window
|
|
249
255
|
|
|
250
256
|
fppow = 5
|
|
251
257
|
if "QRACK_FPPOW" in os.environ:
|
|
@@ -295,6 +301,22 @@ class QrackAceBackend:
|
|
|
295
301
|
|
|
296
302
|
self._qubits = []
|
|
297
303
|
self._lhv = {}
|
|
304
|
+
if self.history_window > 0:
|
|
305
|
+
if to_clone and to_clone._coupling_history is not None:
|
|
306
|
+
self._coupling_history = {
|
|
307
|
+
k: deque(v, maxlen=self.history_window)
|
|
308
|
+
for k, v in to_clone._coupling_history.items()
|
|
309
|
+
}
|
|
310
|
+
self._coupling_history_rev = dict(to_clone._coupling_history_rev)
|
|
311
|
+
self._pending_skip = {k: set(v) for k, v in to_clone._pending_skip.items()}
|
|
312
|
+
else:
|
|
313
|
+
self._coupling_history = {}
|
|
314
|
+
self._coupling_history_rev = {}
|
|
315
|
+
self._pending_skip = {}
|
|
316
|
+
else:
|
|
317
|
+
self._coupling_history = None
|
|
318
|
+
self._coupling_history_rev = None
|
|
319
|
+
self._pending_skip = None
|
|
298
320
|
sim_counts = [0] * sim_count
|
|
299
321
|
sim_id = 0
|
|
300
322
|
tot_qubits = 0
|
|
@@ -864,14 +886,17 @@ class QrackAceBackend:
|
|
|
864
886
|
hq = self._unpack(lq)
|
|
865
887
|
if len(hq) < 2:
|
|
866
888
|
b = hq[0]
|
|
889
|
+
self._invalidate_for_gate(lq)
|
|
867
890
|
self.sim[b[0]].u(b[1], th, ph, lm)
|
|
868
891
|
return
|
|
869
892
|
|
|
893
|
+
skip = self._invalidate_for_gate(lq)
|
|
870
894
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
871
895
|
|
|
872
896
|
for q in qb:
|
|
873
897
|
b = hq[q]
|
|
874
|
-
|
|
898
|
+
if (b[0], b[1]) not in skip:
|
|
899
|
+
self.sim[b[0]].u(b[1], th, ph, lm)
|
|
875
900
|
|
|
876
901
|
lhv = self._lhv.get(lq)
|
|
877
902
|
if lhv is not None:
|
|
@@ -879,18 +904,85 @@ class QrackAceBackend:
|
|
|
879
904
|
|
|
880
905
|
# Correction deferred to next 2-qubit gate (_cpauli calls _correct)
|
|
881
906
|
|
|
907
|
+
def _revert_shadow_commitment(self, lq1):
|
|
908
|
+
"""Revert shadow-committed replicas recorded under lq1. H-reverts
|
|
909
|
+
each committed shadow replica (undoing the stale Z-basis commitment),
|
|
910
|
+
stores the reverted tuples in _pending_skip[lq2] so the NEXT gate on
|
|
911
|
+
that boundary qubit skips those replicas entirely (rotating an H-reverted
|
|
912
|
+
shadow replica from the wrong starting state gives a wrong result; the
|
|
913
|
+
right behavior is to skip it and let the next coupling gate re-derive
|
|
914
|
+
from scratch), and returns the reverted set for the immediate caller to
|
|
915
|
+
skip as well (for case A, where the control's own rotation should also
|
|
916
|
+
skip its own shadow replicas that were just un-committed)."""
|
|
917
|
+
if self._coupling_history is None:
|
|
918
|
+
return set()
|
|
919
|
+
hist = self._coupling_history.pop(lq1, None)
|
|
920
|
+
if hist is None:
|
|
921
|
+
return set()
|
|
922
|
+
reverted_all = set()
|
|
923
|
+
for lq2, targets in hist:
|
|
924
|
+
reverted = set()
|
|
925
|
+
for t_sim, t_idx in targets:
|
|
926
|
+
self.sim[t_sim].h(t_idx)
|
|
927
|
+
reverted.add((t_sim, t_idx))
|
|
928
|
+
# Store as pending skip for the NEXT gate on lq2 (case B):
|
|
929
|
+
# when the boundary qubit's own gate runs, it should skip
|
|
930
|
+
# these replicas rather than applying its gate to the freshly-
|
|
931
|
+
# H-reverted, uncommitted state.
|
|
932
|
+
if reverted:
|
|
933
|
+
existing = self._pending_skip.get(lq2, set())
|
|
934
|
+
self._pending_skip[lq2] = existing | reverted
|
|
935
|
+
self._coupling_history_rev.pop(lq2, None)
|
|
936
|
+
reverted_all |= reverted
|
|
937
|
+
return reverted_all
|
|
938
|
+
|
|
939
|
+
def _invalidate_for_gate(self, lq):
|
|
940
|
+
"""Called by every single-qubit gate dispatcher. Returns the set of
|
|
941
|
+
(sim_id, idx) shadow replicas that should be SKIPPED in the calling
|
|
942
|
+
gate's own application loop.
|
|
943
|
+
- Case A: lq is the coherent-partner (lq1) in a live history entry.
|
|
944
|
+
A gate on the control side invalidates the shadow commitment: reverts
|
|
945
|
+
the shadow targets via H (returning them to uncommitted 0.5), stores
|
|
946
|
+
them in pending_skip[lq2] for the NEXT gate on the boundary qubit,
|
|
947
|
+
and returns them for the immediate caller to skip as well (since the
|
|
948
|
+
control's own replica at slot0 may also be in the reverted set).
|
|
949
|
+
- Case B: lq is the boundary recipient (lq2) of a commitment that a
|
|
950
|
+
prior case-A revert already H-reverted. Consumes the pending_skip
|
|
951
|
+
set so the boundary gate doesn't apply itself to the freshly-
|
|
952
|
+
uncommitted replicas (which would give the wrong result from the
|
|
953
|
+
wrong starting state). Case B NEVER triggers a fresh revert --
|
|
954
|
+
only case A does, because only a gate on the control side actually
|
|
955
|
+
invalidates the commitment; a gate on the boundary side just needs
|
|
956
|
+
to avoid corrupting the already-reverted starting state."""
|
|
957
|
+
if self._coupling_history is None:
|
|
958
|
+
return set()
|
|
959
|
+
skip = set()
|
|
960
|
+
# Case A: lq is the coherent control side -- fire the revert.
|
|
961
|
+
if lq in self._coupling_history:
|
|
962
|
+
skip |= self._revert_shadow_commitment(lq)
|
|
963
|
+
# Case B: lq is the boundary side -- ONLY consume pending_skip,
|
|
964
|
+
# never trigger a fresh revert (that would incorrectly revert
|
|
965
|
+
# a still-valid commitment that no control-side gate has touched).
|
|
966
|
+
pending = self._pending_skip.pop(lq, None)
|
|
967
|
+
if pending:
|
|
968
|
+
skip |= pending
|
|
969
|
+
return skip
|
|
970
|
+
|
|
882
971
|
def r(self, p, th, lq):
|
|
883
972
|
hq = self._unpack(lq)
|
|
884
973
|
if len(hq) < 2:
|
|
885
974
|
b = hq[0]
|
|
975
|
+
self._invalidate_for_gate(lq)
|
|
886
976
|
self.sim[b[0]].r(p, th, b[1])
|
|
887
977
|
return
|
|
888
978
|
|
|
889
979
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
980
|
+
skip = self._invalidate_for_gate(lq)
|
|
890
981
|
|
|
891
982
|
for q in qb:
|
|
892
983
|
b = hq[q]
|
|
893
|
-
|
|
984
|
+
if (b[0], b[1]) not in skip:
|
|
985
|
+
self.sim[b[0]].r(p, th, b[1])
|
|
894
986
|
|
|
895
987
|
lhv = self._lhv.get(lq)
|
|
896
988
|
if lhv is not None:
|
|
@@ -907,16 +999,19 @@ class QrackAceBackend:
|
|
|
907
999
|
hq = self._unpack(lq)
|
|
908
1000
|
if len(hq) < 2:
|
|
909
1001
|
b = hq[0]
|
|
1002
|
+
self._invalidate_for_gate(lq)
|
|
910
1003
|
self.sim[b[0]].h(b[1])
|
|
911
1004
|
return
|
|
912
1005
|
|
|
913
1006
|
self._correct(lq)
|
|
1007
|
+
skip = self._invalidate_for_gate(lq)
|
|
914
1008
|
|
|
915
1009
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
916
1010
|
|
|
917
1011
|
for q in qb:
|
|
918
1012
|
b = hq[q]
|
|
919
|
-
|
|
1013
|
+
if (b[0], b[1]) not in skip:
|
|
1014
|
+
self.sim[b[0]].h(b[1])
|
|
920
1015
|
|
|
921
1016
|
lhv = self._lhv.get(lq)
|
|
922
1017
|
if lhv is not None:
|
|
@@ -928,14 +1023,17 @@ class QrackAceBackend:
|
|
|
928
1023
|
hq = self._unpack(lq)
|
|
929
1024
|
if len(hq) < 2:
|
|
930
1025
|
b = hq[0]
|
|
1026
|
+
self._invalidate_for_gate(lq)
|
|
931
1027
|
self.sim[b[0]].s(b[1])
|
|
932
1028
|
return
|
|
933
1029
|
|
|
1030
|
+
skip = self._invalidate_for_gate(lq)
|
|
934
1031
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
935
1032
|
|
|
936
1033
|
for q in qb:
|
|
937
1034
|
b = hq[q]
|
|
938
|
-
|
|
1035
|
+
if (b[0], b[1]) not in skip:
|
|
1036
|
+
self.sim[b[0]].s(b[1])
|
|
939
1037
|
|
|
940
1038
|
lhv = self._lhv.get(lq)
|
|
941
1039
|
if lhv is not None:
|
|
@@ -945,14 +1043,17 @@ class QrackAceBackend:
|
|
|
945
1043
|
hq = self._unpack(lq)
|
|
946
1044
|
if len(hq) < 2:
|
|
947
1045
|
b = hq[0]
|
|
1046
|
+
self._invalidate_for_gate(lq)
|
|
948
1047
|
self.sim[b[0]].adjs(b[1])
|
|
949
1048
|
return
|
|
950
1049
|
|
|
1050
|
+
skip = self._invalidate_for_gate(lq)
|
|
951
1051
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
952
1052
|
|
|
953
1053
|
for q in qb:
|
|
954
1054
|
b = hq[q]
|
|
955
|
-
|
|
1055
|
+
if (b[0], b[1]) not in skip:
|
|
1056
|
+
self.sim[b[0]].adjs(b[1])
|
|
956
1057
|
|
|
957
1058
|
lhv = self._lhv.get(lq)
|
|
958
1059
|
if lhv is not None:
|
|
@@ -962,14 +1063,17 @@ class QrackAceBackend:
|
|
|
962
1063
|
hq = self._unpack(lq)
|
|
963
1064
|
if len(hq) < 2:
|
|
964
1065
|
b = hq[0]
|
|
1066
|
+
self._invalidate_for_gate(lq)
|
|
965
1067
|
self.sim[b[0]].x(b[1])
|
|
966
1068
|
return
|
|
967
1069
|
|
|
1070
|
+
skip = self._invalidate_for_gate(lq)
|
|
968
1071
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
969
1072
|
|
|
970
1073
|
for q in qb:
|
|
971
1074
|
b = hq[q]
|
|
972
|
-
|
|
1075
|
+
if (b[0], b[1]) not in skip:
|
|
1076
|
+
self.sim[b[0]].x(b[1])
|
|
973
1077
|
|
|
974
1078
|
lhv = self._lhv.get(lq)
|
|
975
1079
|
if lhv is not None:
|
|
@@ -979,14 +1083,17 @@ class QrackAceBackend:
|
|
|
979
1083
|
hq = self._unpack(lq)
|
|
980
1084
|
if len(hq) < 2:
|
|
981
1085
|
b = hq[0]
|
|
1086
|
+
self._invalidate_for_gate(lq)
|
|
982
1087
|
self.sim[b[0]].y(b[1])
|
|
983
1088
|
return
|
|
984
1089
|
|
|
1090
|
+
skip = self._invalidate_for_gate(lq)
|
|
985
1091
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
986
1092
|
|
|
987
1093
|
for q in qb:
|
|
988
1094
|
b = hq[q]
|
|
989
|
-
|
|
1095
|
+
if (b[0], b[1]) not in skip:
|
|
1096
|
+
self.sim[b[0]].y(b[1])
|
|
990
1097
|
|
|
991
1098
|
lhv = self._lhv.get(lq)
|
|
992
1099
|
if lhv is not None:
|
|
@@ -996,14 +1103,17 @@ class QrackAceBackend:
|
|
|
996
1103
|
hq = self._unpack(lq)
|
|
997
1104
|
if len(hq) < 2:
|
|
998
1105
|
b = hq[0]
|
|
1106
|
+
self._invalidate_for_gate(lq)
|
|
999
1107
|
self.sim[b[0]].z(b[1])
|
|
1000
1108
|
return
|
|
1001
1109
|
|
|
1110
|
+
skip = self._invalidate_for_gate(lq)
|
|
1002
1111
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
1003
1112
|
|
|
1004
1113
|
for q in qb:
|
|
1005
1114
|
b = hq[q]
|
|
1006
|
-
|
|
1115
|
+
if (b[0], b[1]) not in skip:
|
|
1116
|
+
self.sim[b[0]].z(b[1])
|
|
1007
1117
|
|
|
1008
1118
|
lhv = self._lhv.get(lq)
|
|
1009
1119
|
if lhv is not None:
|
|
@@ -1013,14 +1123,17 @@ class QrackAceBackend:
|
|
|
1013
1123
|
hq = self._unpack(lq)
|
|
1014
1124
|
if len(hq) < 2:
|
|
1015
1125
|
b = hq[0]
|
|
1126
|
+
self._invalidate_for_gate(lq)
|
|
1016
1127
|
self.sim[b[0]].t(b[1])
|
|
1017
1128
|
return
|
|
1018
1129
|
|
|
1130
|
+
skip = self._invalidate_for_gate(lq)
|
|
1019
1131
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
1020
1132
|
|
|
1021
1133
|
for q in qb:
|
|
1022
1134
|
b = hq[q]
|
|
1023
|
-
|
|
1135
|
+
if (b[0], b[1]) not in skip:
|
|
1136
|
+
self.sim[b[0]].t(b[1])
|
|
1024
1137
|
|
|
1025
1138
|
lhv = self._lhv.get(lq)
|
|
1026
1139
|
if lhv is not None:
|
|
@@ -1030,14 +1143,17 @@ class QrackAceBackend:
|
|
|
1030
1143
|
hq = self._unpack(lq)
|
|
1031
1144
|
if len(hq) < 2:
|
|
1032
1145
|
b = hq[0]
|
|
1146
|
+
self._invalidate_for_gate(lq)
|
|
1033
1147
|
self.sim[b[0]].adjt(b[1])
|
|
1034
1148
|
return
|
|
1035
1149
|
|
|
1150
|
+
skip = self._invalidate_for_gate(lq)
|
|
1036
1151
|
qb, _ = QrackAceBackend._get_qb_lhv_indices(hq)
|
|
1037
1152
|
|
|
1038
1153
|
for q in qb:
|
|
1039
1154
|
b = hq[q]
|
|
1040
|
-
|
|
1155
|
+
if (b[0], b[1]) not in skip:
|
|
1156
|
+
self.sim[b[0]].adjt(b[1])
|
|
1041
1157
|
|
|
1042
1158
|
lhv = self._lhv.get(lq)
|
|
1043
1159
|
if lhv is not None:
|
|
@@ -1081,7 +1197,8 @@ class QrackAceBackend:
|
|
|
1081
1197
|
|
|
1082
1198
|
return connected, boundary
|
|
1083
1199
|
|
|
1084
|
-
def _apply_coupling(self, pauli, anti, qb1, hq1, qb2, hq2, lq1_lr):
|
|
1200
|
+
def _apply_coupling(self, pauli, anti, qb1, hq1, qb2, hq2, lq1_lr, lq1=None, lq2=None):
|
|
1201
|
+
shadow_targets = []
|
|
1085
1202
|
for q1 in qb1:
|
|
1086
1203
|
b1 = hq1[q1]
|
|
1087
1204
|
gate_fn, shadow_fn = self._get_gate(pauli, anti, b1[0])
|
|
@@ -1091,6 +1208,20 @@ class QrackAceBackend:
|
|
|
1091
1208
|
gate_fn([b1[1]], b2[1])
|
|
1092
1209
|
elif lq1_lr or (b1[1] == b2[1]) or ((len(qb1) == 2) and (b1[1] == (b2[1] & 1))):
|
|
1093
1210
|
shadow_fn(b1, b2)
|
|
1211
|
+
shadow_targets.append(b2)
|
|
1212
|
+
|
|
1213
|
+
if (
|
|
1214
|
+
self._coupling_history is not None
|
|
1215
|
+
and lq1 is not None
|
|
1216
|
+
and lq2 is not None
|
|
1217
|
+
and shadow_targets
|
|
1218
|
+
):
|
|
1219
|
+
entry = (lq2, tuple(shadow_targets))
|
|
1220
|
+
hist = self._coupling_history.setdefault(
|
|
1221
|
+
lq1, deque(maxlen=self.history_window)
|
|
1222
|
+
)
|
|
1223
|
+
hist.append(entry)
|
|
1224
|
+
self._coupling_history_rev[lq2] = lq1
|
|
1094
1225
|
|
|
1095
1226
|
def _cpauli(self, lq1, lq2, anti, pauli):
|
|
1096
1227
|
lq1_row = lq1 // self._row_length
|
|
@@ -1110,7 +1241,7 @@ class QrackAceBackend:
|
|
|
1110
1241
|
qb2, _ = QrackAceBackend._get_qb_lhv_indices(hq2)
|
|
1111
1242
|
# Apply cross coupling on every qubit, including former-LHV boundary
|
|
1112
1243
|
# qubits, which now live as real qubits in the shared boundary sim.
|
|
1113
|
-
self._apply_coupling(pauli, anti, qb1, hq1, qb2, hq2, lq1_lr)
|
|
1244
|
+
self._apply_coupling(pauli, anti, qb1, hq1, qb2, hq2, lq1_lr, lq1, lq2)
|
|
1114
1245
|
|
|
1115
1246
|
if lq2 in self._lhv:
|
|
1116
1247
|
ctrl_prob = self.sim[hq1[0][0]].prob(hq1[0][1])
|
|
@@ -1642,10 +1773,6 @@ class QrackAceBackend:
|
|
|
1642
1773
|
return [
|
|
1643
1774
|
"id",
|
|
1644
1775
|
"u",
|
|
1645
|
-
"u1",
|
|
1646
|
-
"u2",
|
|
1647
|
-
"u3",
|
|
1648
|
-
"r",
|
|
1649
1776
|
"rx",
|
|
1650
1777
|
"ry",
|
|
1651
1778
|
"rz",
|
|
@@ -1655,9 +1782,6 @@ class QrackAceBackend:
|
|
|
1655
1782
|
"z",
|
|
1656
1783
|
"s",
|
|
1657
1784
|
"sdg",
|
|
1658
|
-
"sx",
|
|
1659
|
-
"sxdg",
|
|
1660
|
-
"p",
|
|
1661
1785
|
"t",
|
|
1662
1786
|
"tdg",
|
|
1663
1787
|
"cx",
|
|
@@ -3202,9 +3202,26 @@ class QrackSimulator:
|
|
|
3202
3202
|
Raises:
|
|
3203
3203
|
Runtimeerror: QrackSimulator raised an exception.
|
|
3204
3204
|
"""
|
|
3205
|
-
|
|
3205
|
+
Qrack.qrack_lib.Separate(self.sid, len(qs), QrackSimulator._ulonglong_byref(qs))
|
|
3206
3206
|
self._throw_if_error()
|
|
3207
3207
|
|
|
3208
|
+
def are_factorized(self, a, b):
|
|
3209
|
+
"""Check whether bits in "a" are factorized from bits in "b"
|
|
3210
|
+
|
|
3211
|
+
After flushing all buffers, check whether "a" set of qubits is factorized separate from "b" set of qubits
|
|
3212
|
+
|
|
3213
|
+
Args:
|
|
3214
|
+
a: first list of qubits
|
|
3215
|
+
b: second list of qubits
|
|
3216
|
+
|
|
3217
|
+
Raises:
|
|
3218
|
+
Runtimeerror: QrackSimulator raised an exception.
|
|
3219
|
+
"""
|
|
3220
|
+
result = Qrack.qrack_lib.AreFactorized(self.sid, len(a), QrackSimulator._ulonglong_byref(a), len(b), QrackSimulator._ulonglong_byref(b))
|
|
3221
|
+
self._throw_if_error()
|
|
3222
|
+
|
|
3223
|
+
return result
|
|
3224
|
+
|
|
3208
3225
|
def get_unitary_fidelity(self):
|
|
3209
3226
|
"""Get fidelity estimate
|
|
3210
3227
|
|
|
@@ -4499,10 +4516,6 @@ class QrackSimulator:
|
|
|
4499
4516
|
return [
|
|
4500
4517
|
"id",
|
|
4501
4518
|
"u",
|
|
4502
|
-
"u1",
|
|
4503
|
-
"u2",
|
|
4504
|
-
"u3",
|
|
4505
|
-
"r",
|
|
4506
4519
|
"rx",
|
|
4507
4520
|
"ry",
|
|
4508
4521
|
"rz",
|
|
@@ -4512,14 +4525,9 @@ class QrackSimulator:
|
|
|
4512
4525
|
"z",
|
|
4513
4526
|
"s",
|
|
4514
4527
|
"sdg",
|
|
4515
|
-
"sx",
|
|
4516
|
-
"sxdg",
|
|
4517
|
-
"p",
|
|
4518
4528
|
"t",
|
|
4519
4529
|
"tdg",
|
|
4520
4530
|
"cu",
|
|
4521
|
-
"cu1",
|
|
4522
|
-
"cu3",
|
|
4523
4531
|
"cx",
|
|
4524
4532
|
"cy",
|
|
4525
4533
|
"cz",
|
|
@@ -1204,6 +1204,15 @@ class QrackSystem:
|
|
|
1204
1204
|
POINTER(c_ulonglong),
|
|
1205
1205
|
]
|
|
1206
1206
|
|
|
1207
|
+
self.qrack_lib.AreFactorized.restype = c_bool
|
|
1208
|
+
self.qrack_lib.AreFactorized.argtypes = [
|
|
1209
|
+
c_ulonglong,
|
|
1210
|
+
c_ulonglong,
|
|
1211
|
+
POINTER(c_ulonglong),
|
|
1212
|
+
c_ulonglong,
|
|
1213
|
+
POINTER(c_ulonglong),
|
|
1214
|
+
]
|
|
1215
|
+
|
|
1207
1216
|
self.qrack_lib.GetUnitaryFidelity.restype = c_double
|
|
1208
1217
|
self.qrack_lib.GetUnitaryFidelity.argtypes = [c_ulonglong]
|
|
1209
1218
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|