pyGSTi 0.9.12.1__cp39-cp39-win32.whl → 0.9.13__cp39-cp39-win32.whl
Sign up to get free protection for your applications and to get access to all the features.
- pyGSTi-0.9.13.dist-info/METADATA +197 -0
- {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/RECORD +207 -217
- {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/WHEEL +1 -1
- pygsti/_version.py +2 -2
- pygsti/algorithms/contract.py +1 -1
- pygsti/algorithms/core.py +42 -28
- pygsti/algorithms/fiducialselection.py +17 -8
- pygsti/algorithms/gaugeopt.py +2 -2
- pygsti/algorithms/germselection.py +87 -77
- pygsti/algorithms/mirroring.py +0 -388
- pygsti/algorithms/randomcircuit.py +165 -1333
- pygsti/algorithms/rbfit.py +0 -234
- pygsti/baseobjs/basis.py +94 -396
- pygsti/baseobjs/errorgenbasis.py +0 -132
- pygsti/baseobjs/errorgenspace.py +0 -10
- pygsti/baseobjs/label.py +52 -168
- pygsti/baseobjs/opcalc/fastopcalc.cp39-win32.pyd +0 -0
- pygsti/baseobjs/opcalc/fastopcalc.pyx +2 -2
- pygsti/baseobjs/polynomial.py +13 -595
- pygsti/baseobjs/statespace.py +1 -0
- pygsti/circuits/__init__.py +1 -1
- pygsti/circuits/circuit.py +682 -505
- pygsti/circuits/circuitconstruction.py +0 -4
- pygsti/circuits/circuitlist.py +47 -5
- pygsti/circuits/circuitparser/__init__.py +8 -8
- pygsti/circuits/circuitparser/fastcircuitparser.cp39-win32.pyd +0 -0
- pygsti/circuits/circuitstructure.py +3 -3
- pygsti/circuits/cloudcircuitconstruction.py +1 -1
- pygsti/data/datacomparator.py +2 -7
- pygsti/data/dataset.py +46 -44
- pygsti/data/hypothesistest.py +0 -7
- pygsti/drivers/bootstrap.py +0 -49
- pygsti/drivers/longsequence.py +2 -1
- pygsti/evotypes/basereps_cython.cp39-win32.pyd +0 -0
- pygsti/evotypes/chp/opreps.py +0 -61
- pygsti/evotypes/chp/statereps.py +0 -32
- pygsti/evotypes/densitymx/effectcreps.cpp +9 -10
- pygsti/evotypes/densitymx/effectreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/densitymx/effectreps.pyx +1 -1
- pygsti/evotypes/densitymx/opreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/densitymx/opreps.pyx +2 -2
- pygsti/evotypes/densitymx/statereps.cp39-win32.pyd +0 -0
- pygsti/evotypes/densitymx/statereps.pyx +1 -1
- pygsti/evotypes/densitymx_slow/effectreps.py +7 -23
- pygsti/evotypes/densitymx_slow/opreps.py +16 -23
- pygsti/evotypes/densitymx_slow/statereps.py +10 -3
- pygsti/evotypes/evotype.py +39 -2
- pygsti/evotypes/stabilizer/effectreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/effectreps.pyx +0 -4
- pygsti/evotypes/stabilizer/opreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/opreps.pyx +0 -4
- pygsti/evotypes/stabilizer/statereps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/statereps.pyx +1 -5
- pygsti/evotypes/stabilizer/termreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/stabilizer/termreps.pyx +0 -7
- pygsti/evotypes/stabilizer_slow/effectreps.py +0 -22
- pygsti/evotypes/stabilizer_slow/opreps.py +0 -4
- pygsti/evotypes/stabilizer_slow/statereps.py +0 -4
- pygsti/evotypes/statevec/effectreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/effectreps.pyx +1 -1
- pygsti/evotypes/statevec/opreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/opreps.pyx +2 -2
- pygsti/evotypes/statevec/statereps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/statereps.pyx +1 -1
- pygsti/evotypes/statevec/termreps.cp39-win32.pyd +0 -0
- pygsti/evotypes/statevec/termreps.pyx +0 -7
- pygsti/evotypes/statevec_slow/effectreps.py +0 -3
- pygsti/evotypes/statevec_slow/opreps.py +0 -5
- pygsti/extras/__init__.py +0 -1
- pygsti/extras/drift/stabilityanalyzer.py +3 -1
- pygsti/extras/interpygate/__init__.py +12 -0
- pygsti/extras/interpygate/core.py +0 -36
- pygsti/extras/interpygate/process_tomography.py +44 -10
- pygsti/extras/rpe/rpeconstruction.py +0 -2
- pygsti/forwardsims/__init__.py +1 -0
- pygsti/forwardsims/forwardsim.py +14 -55
- pygsti/forwardsims/mapforwardsim.py +69 -18
- pygsti/forwardsims/mapforwardsim_calc_densitymx.cp39-win32.pyd +0 -0
- pygsti/forwardsims/mapforwardsim_calc_densitymx.pyx +65 -66
- pygsti/forwardsims/mapforwardsim_calc_generic.py +91 -13
- pygsti/forwardsims/matrixforwardsim.py +63 -15
- pygsti/forwardsims/termforwardsim.py +8 -110
- pygsti/forwardsims/termforwardsim_calc_stabilizer.cp39-win32.pyd +0 -0
- pygsti/forwardsims/termforwardsim_calc_statevec.cp39-win32.pyd +0 -0
- pygsti/forwardsims/termforwardsim_calc_statevec.pyx +0 -651
- pygsti/forwardsims/torchfwdsim.py +265 -0
- pygsti/forwardsims/weakforwardsim.py +2 -2
- pygsti/io/__init__.py +1 -2
- pygsti/io/mongodb.py +0 -2
- pygsti/io/stdinput.py +6 -22
- pygsti/layouts/copalayout.py +10 -12
- pygsti/layouts/distlayout.py +0 -40
- pygsti/layouts/maplayout.py +103 -25
- pygsti/layouts/matrixlayout.py +99 -60
- pygsti/layouts/prefixtable.py +1534 -52
- pygsti/layouts/termlayout.py +1 -1
- pygsti/modelmembers/instruments/instrument.py +3 -3
- pygsti/modelmembers/instruments/tpinstrument.py +2 -2
- pygsti/modelmembers/modelmember.py +0 -17
- pygsti/modelmembers/operations/__init__.py +2 -4
- pygsti/modelmembers/operations/affineshiftop.py +1 -0
- pygsti/modelmembers/operations/composederrorgen.py +1 -1
- pygsti/modelmembers/operations/composedop.py +1 -24
- pygsti/modelmembers/operations/denseop.py +5 -5
- pygsti/modelmembers/operations/eigpdenseop.py +2 -2
- pygsti/modelmembers/operations/embeddederrorgen.py +1 -1
- pygsti/modelmembers/operations/embeddedop.py +0 -1
- pygsti/modelmembers/operations/experrorgenop.py +2 -2
- pygsti/modelmembers/operations/fullarbitraryop.py +1 -0
- pygsti/modelmembers/operations/fullcptpop.py +2 -2
- pygsti/modelmembers/operations/fulltpop.py +28 -6
- pygsti/modelmembers/operations/fullunitaryop.py +5 -4
- pygsti/modelmembers/operations/lindbladcoefficients.py +93 -78
- pygsti/modelmembers/operations/lindbladerrorgen.py +268 -441
- pygsti/modelmembers/operations/linearop.py +7 -27
- pygsti/modelmembers/operations/opfactory.py +1 -1
- pygsti/modelmembers/operations/repeatedop.py +1 -24
- pygsti/modelmembers/operations/staticstdop.py +1 -1
- pygsti/modelmembers/povms/__init__.py +3 -3
- pygsti/modelmembers/povms/basepovm.py +7 -36
- pygsti/modelmembers/povms/complementeffect.py +4 -9
- pygsti/modelmembers/povms/composedeffect.py +0 -320
- pygsti/modelmembers/povms/computationaleffect.py +1 -1
- pygsti/modelmembers/povms/computationalpovm.py +3 -1
- pygsti/modelmembers/povms/effect.py +3 -5
- pygsti/modelmembers/povms/marginalizedpovm.py +0 -79
- pygsti/modelmembers/povms/tppovm.py +74 -2
- pygsti/modelmembers/states/__init__.py +2 -5
- pygsti/modelmembers/states/composedstate.py +0 -317
- pygsti/modelmembers/states/computationalstate.py +3 -3
- pygsti/modelmembers/states/cptpstate.py +4 -4
- pygsti/modelmembers/states/densestate.py +6 -4
- pygsti/modelmembers/states/fullpurestate.py +0 -24
- pygsti/modelmembers/states/purestate.py +1 -1
- pygsti/modelmembers/states/state.py +5 -6
- pygsti/modelmembers/states/tpstate.py +28 -10
- pygsti/modelmembers/term.py +3 -6
- pygsti/modelmembers/torchable.py +50 -0
- pygsti/modelpacks/_modelpack.py +1 -1
- pygsti/modelpacks/smq1Q_ZN.py +3 -1
- pygsti/modelpacks/smq2Q_XXYYII.py +2 -1
- pygsti/modelpacks/smq2Q_XY.py +3 -3
- pygsti/modelpacks/smq2Q_XYI.py +2 -2
- pygsti/modelpacks/smq2Q_XYICNOT.py +3 -3
- pygsti/modelpacks/smq2Q_XYICPHASE.py +3 -3
- pygsti/modelpacks/smq2Q_XYXX.py +1 -1
- pygsti/modelpacks/smq2Q_XYZICNOT.py +3 -3
- pygsti/modelpacks/smq2Q_XYZZ.py +1 -1
- pygsti/modelpacks/stdtarget.py +0 -121
- pygsti/models/cloudnoisemodel.py +1 -2
- pygsti/models/explicitcalc.py +3 -3
- pygsti/models/explicitmodel.py +3 -13
- pygsti/models/fogistore.py +5 -3
- pygsti/models/localnoisemodel.py +1 -2
- pygsti/models/memberdict.py +0 -12
- pygsti/models/model.py +800 -65
- pygsti/models/modelconstruction.py +4 -4
- pygsti/models/modelnoise.py +2 -2
- pygsti/models/modelparaminterposer.py +1 -1
- pygsti/models/oplessmodel.py +1 -1
- pygsti/models/qutrit.py +15 -14
- pygsti/objectivefns/objectivefns.py +73 -138
- pygsti/objectivefns/wildcardbudget.py +2 -7
- pygsti/optimize/__init__.py +1 -0
- pygsti/optimize/arraysinterface.py +28 -0
- pygsti/optimize/customcg.py +0 -12
- pygsti/optimize/customlm.py +129 -323
- pygsti/optimize/customsolve.py +2 -2
- pygsti/optimize/optimize.py +0 -84
- pygsti/optimize/simplerlm.py +841 -0
- pygsti/optimize/wildcardopt.py +19 -598
- pygsti/protocols/confidenceregionfactory.py +28 -14
- pygsti/protocols/estimate.py +31 -14
- pygsti/protocols/gst.py +142 -68
- pygsti/protocols/modeltest.py +6 -10
- pygsti/protocols/protocol.py +9 -37
- pygsti/protocols/rb.py +450 -79
- pygsti/protocols/treenode.py +8 -2
- pygsti/protocols/vb.py +108 -206
- pygsti/protocols/vbdataframe.py +1 -1
- pygsti/report/factory.py +0 -15
- pygsti/report/fogidiagram.py +1 -17
- pygsti/report/modelfunction.py +12 -3
- pygsti/report/mpl_colormaps.py +1 -1
- pygsti/report/plothelpers.py +8 -2
- pygsti/report/reportables.py +41 -37
- pygsti/report/templates/offline/pygsti_dashboard.css +6 -0
- pygsti/report/templates/offline/pygsti_dashboard.js +12 -0
- pygsti/report/workspace.py +2 -14
- pygsti/report/workspaceplots.py +326 -504
- pygsti/tools/basistools.py +9 -36
- pygsti/tools/edesigntools.py +124 -96
- pygsti/tools/fastcalc.cp39-win32.pyd +0 -0
- pygsti/tools/fastcalc.pyx +35 -81
- pygsti/tools/internalgates.py +151 -15
- pygsti/tools/jamiolkowski.py +5 -5
- pygsti/tools/lindbladtools.py +19 -11
- pygsti/tools/listtools.py +0 -114
- pygsti/tools/matrixmod2.py +1 -1
- pygsti/tools/matrixtools.py +173 -339
- pygsti/tools/nameddict.py +1 -1
- pygsti/tools/optools.py +154 -88
- pygsti/tools/pdftools.py +0 -25
- pygsti/tools/rbtheory.py +3 -320
- pygsti/tools/slicetools.py +64 -12
- pyGSTi-0.9.12.1.dist-info/METADATA +0 -155
- pygsti/algorithms/directx.py +0 -711
- pygsti/evotypes/qibo/__init__.py +0 -33
- pygsti/evotypes/qibo/effectreps.py +0 -78
- pygsti/evotypes/qibo/opreps.py +0 -376
- pygsti/evotypes/qibo/povmreps.py +0 -98
- pygsti/evotypes/qibo/statereps.py +0 -174
- pygsti/extras/rb/__init__.py +0 -13
- pygsti/extras/rb/benchmarker.py +0 -957
- pygsti/extras/rb/dataset.py +0 -378
- pygsti/extras/rb/io.py +0 -814
- pygsti/extras/rb/simulate.py +0 -1020
- pygsti/io/legacyio.py +0 -385
- pygsti/modelmembers/povms/denseeffect.py +0 -142
- {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/LICENSE +0 -0
- {pyGSTi-0.9.12.1.dist-info → pyGSTi-0.9.13.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ import numpy as _np
|
|
7
7
|
import numpy.linalg as _lin
|
8
8
|
|
9
9
|
from pygsti.tools.basistools import change_basis
|
10
|
+
from pygsti.tools.legacytools import deprecate
|
10
11
|
|
11
12
|
|
12
13
|
#Helper functions
|
@@ -15,8 +16,11 @@ def multi_kron(*a):
|
|
15
16
|
return reduce(_np.kron, a)
|
16
17
|
|
17
18
|
|
19
|
+
@deprecate("Calls to this function should be replaced with in-lined code: matrix.reshape((matrix.size, 1), 'F')")
|
18
20
|
def vec(matrix):
|
19
|
-
"""
|
21
|
+
"""
|
22
|
+
Returns an explicit column-vector representation of a square matrix, obtained by reading
|
23
|
+
from the square matrix in column-major order.
|
20
24
|
|
21
25
|
Args:
|
22
26
|
matrix (list,numpy.ndarray): NxN matrix
|
@@ -30,11 +34,12 @@ def vec(matrix):
|
|
30
34
|
"""
|
31
35
|
matrix = _np.array(matrix)
|
32
36
|
if matrix.shape == (len(matrix), len(matrix)):
|
33
|
-
return
|
37
|
+
return matrix.reshape(shape=(matrix.size, 1), order='F')
|
34
38
|
else:
|
35
39
|
raise ValueError('The input matrix must be square.')
|
36
40
|
|
37
41
|
|
42
|
+
@deprecate("Calls to this function should be replaced by unvec_square(vectorized, 'F')")
|
38
43
|
def unvec(vectorized):
|
39
44
|
"""A function that vectorizes a process in the basis of matrix units, sorted first
|
40
45
|
by column, then row.
|
@@ -49,13 +54,42 @@ def unvec(vectorized):
|
|
49
54
|
ValueError: If the length of the input is not a perfect square
|
50
55
|
|
51
56
|
"""
|
52
|
-
vectorized =
|
53
|
-
|
54
|
-
|
55
|
-
|
57
|
+
return unvec_square(vectorized, order='F')
|
58
|
+
|
59
|
+
|
60
|
+
def unvec_square(vectorized, order):
|
61
|
+
"""
|
62
|
+
Takes a vector whose length is a perfect square, and returns a square matrix
|
63
|
+
representation by reading from the vectors entries to define the matrix in
|
64
|
+
column-major order (order='F') or row-major order (order='C').
|
65
|
+
|
66
|
+
Args:
|
67
|
+
vectorized: array-like, where np.array(vectorized).size is a perfect square.
|
68
|
+
order: 'F' or 'C'
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
numpy.ndarray: NxN dimensional array
|
72
|
+
|
73
|
+
Raises:
|
74
|
+
ValueError: If the length of the input is not a perfect square.
|
75
|
+
|
76
|
+
"""
|
77
|
+
assert order == 'F' or order == 'C'
|
78
|
+
if not isinstance(vectorized, _np.ndarray):
|
79
|
+
vectorized = _np.array(vectorized)
|
80
|
+
|
81
|
+
if vectorized.ndim == 2:
|
82
|
+
assert min(vectorized.shape) == 1
|
83
|
+
vectorized = vectorized.ravel()
|
84
|
+
elif vectorized.ndim > 2:
|
85
|
+
raise ValueError('vectorized.ndim must be <= 2.')
|
86
|
+
|
87
|
+
n = int(_np.sqrt(max(vectorized.shape)))
|
88
|
+
if len(vectorized) == n ** 2:
|
89
|
+
return vectorized.reshape((n, n), order=order)
|
56
90
|
else:
|
57
|
-
|
58
|
-
|
91
|
+
msg = 'The input vector length must be a perfect square, but this input has length %d.' % len(vectorized)
|
92
|
+
raise ValueError(msg)
|
59
93
|
|
60
94
|
|
61
95
|
def split(n, a):
|
@@ -129,7 +163,7 @@ def run_process_tomography(state_to_density_matrix_fn, n_qubits=1, comm=None,
|
|
129
163
|
states = _itertools.product(one_qubit_states, repeat=n_qubits)
|
130
164
|
states = [multi_kron(*state) for state in states]
|
131
165
|
in_density_matrices = [_np.outer(state, state.conj()) for state in states]
|
132
|
-
in_states = _np.column_stack(list([
|
166
|
+
in_states = _np.column_stack(list([rho.ravel(order='F') for rho in in_density_matrices]))
|
133
167
|
my_states = split(size, states)[rank]
|
134
168
|
if verbose:
|
135
169
|
print("Process %d of %d evaluating %d input states." % (rank, size, len(my_states)))
|
@@ -150,7 +184,7 @@ def run_process_tomography(state_to_density_matrix_fn, n_qubits=1, comm=None,
|
|
150
184
|
out_density_matrices = _np.array([y for x in gathered_out_density_matrices for y in x])
|
151
185
|
# Sort the list by time
|
152
186
|
out_density_matrices = _np.transpose(out_density_matrices, [1, 0, 2, 3])
|
153
|
-
out_states = [_np.column_stack(list([
|
187
|
+
out_states = [_np.column_stack(list([rho.ravel(order='F') for rho in density_matrices_at_time]))
|
154
188
|
for density_matrices_at_time in out_density_matrices]
|
155
189
|
process_matrices = [_np.dot(out_states_at_time, _lin.inv(in_states)) for out_states_at_time in out_states]
|
156
190
|
process_matrices = [change_basis(process_matrix_at_time, 'col', basis)
|
@@ -113,8 +113,6 @@ def create_parameterized_rpe_model(alpha_true, epsilon_true, aux_rot, spam_depol
|
|
113
113
|
|
114
114
|
return outputModel
|
115
115
|
|
116
|
-
#def make_rpe_alpha_str_lists(k_list,angleStr,rpeconfig_inst):
|
117
|
-
|
118
116
|
|
119
117
|
def create_rpe_angle_circuit_lists(k_list, angle_name, rpeconfig_inst):
|
120
118
|
"""
|
pygsti/forwardsims/__init__.py
CHANGED
@@ -12,6 +12,7 @@ pyGSTi Forward Simulators Python Package
|
|
12
12
|
|
13
13
|
from .forwardsim import ForwardSimulator
|
14
14
|
from .mapforwardsim import SimpleMapForwardSimulator, MapForwardSimulator
|
15
|
+
from .torchfwdsim import TorchForwardSimulator
|
15
16
|
from .matrixforwardsim import SimpleMatrixForwardSimulator, MatrixForwardSimulator
|
16
17
|
from .termforwardsim import TermForwardSimulator
|
17
18
|
from .weakforwardsim import WeakForwardSimulator
|
pygsti/forwardsims/forwardsim.py
CHANGED
@@ -63,9 +63,7 @@ class ForwardSimulator(_NicelySerializable):
|
|
63
63
|
if isinstance(obj, ForwardSimulator):
|
64
64
|
return obj
|
65
65
|
elif isinstance(obj, str):
|
66
|
-
if obj == "auto":
|
67
|
-
return _MapFSim() if (num_qubits is None or num_qubits > 2) else _MatrixFSim()
|
68
|
-
elif obj == "map":
|
66
|
+
if obj == "auto" or obj == "map":
|
69
67
|
return _MapFSim()
|
70
68
|
elif obj == "matrix":
|
71
69
|
return _MatrixFSim()
|
@@ -147,57 +145,6 @@ class ForwardSimulator(_NicelySerializable):
|
|
147
145
|
`evotype` will be `None` when the current model is None"""
|
148
146
|
pass
|
149
147
|
|
150
|
-
#def to_vector(self):
|
151
|
-
# """
|
152
|
-
# Returns the parameter vector of the associated Model.
|
153
|
-
#
|
154
|
-
# Returns
|
155
|
-
# -------
|
156
|
-
# numpy array
|
157
|
-
# The vectorized model parameters.
|
158
|
-
# """
|
159
|
-
# return self.paramvec
|
160
|
-
#
|
161
|
-
#def from_vector(self, v, close=False, nodirty=False):
|
162
|
-
# """
|
163
|
-
# The inverse of to_vector.
|
164
|
-
#
|
165
|
-
# Initializes the Model-like members of this
|
166
|
-
# calculator based on `v`. Used for computing finite-difference derivatives.
|
167
|
-
#
|
168
|
-
# Parameters
|
169
|
-
# ----------
|
170
|
-
# v : numpy.ndarray
|
171
|
-
# The parameter vector.
|
172
|
-
#
|
173
|
-
# close : bool, optional
|
174
|
-
# Set to `True` if `v` is close to the current parameter vector.
|
175
|
-
# This can make some operations more efficient.
|
176
|
-
#
|
177
|
-
# nodirty : bool, optional
|
178
|
-
# If True, the framework for marking and detecting when operations
|
179
|
-
# have changed and a Model's parameter-vector needs to be updated
|
180
|
-
# is disabled. Disabling this will increases the speed of the call.
|
181
|
-
#
|
182
|
-
# Returns
|
183
|
-
# -------
|
184
|
-
# None
|
185
|
-
# """
|
186
|
-
# #Note: this *will* initialize the parent Model's objects too,
|
187
|
-
# # since only references to preps, effects, and gates are held
|
188
|
-
# # by the calculator class. ORDER is important, as elements of
|
189
|
-
# # POVMs and Instruments rely on a fixed from_vector ordering
|
190
|
-
# # of their simplified effects/gates.
|
191
|
-
# self.paramvec = v.copy() # now self.paramvec is *not* the same as the Model's paramvec
|
192
|
-
# self.sos.from_vector(v, close, nodirty) # so don't always want ", nodirty=True)" - we
|
193
|
-
# # need to set dirty flags so *parent* will re-init it's paramvec...
|
194
|
-
#
|
195
|
-
# #Re-init reps for computation
|
196
|
-
# #self.operationreps = { i:self.operations[lbl].torep() for lbl,i in self.operation_lookup.items() }
|
197
|
-
# #self.operationreps = { lbl:g.torep() for lbl,g in gates.items() }
|
198
|
-
# #self.prepreps = { lbl:p.torep('prep') for lbl,p in preps.items() }
|
199
|
-
# #self.effectreps = { lbl:e.torep('effect') for lbl,e in effects.items() }
|
200
|
-
|
201
148
|
def _compute_circuit_outcome_probabilities(self, array_to_fill, circuit, outcomes, resource_alloc, time=None):
|
202
149
|
raise NotImplementedError("Derived classes should implement this!")
|
203
150
|
|
@@ -323,7 +270,8 @@ class ForwardSimulator(_NicelySerializable):
|
|
323
270
|
# ---------------------------------------------------------------------------
|
324
271
|
|
325
272
|
def create_layout(self, circuits, dataset=None, resource_alloc=None,
|
326
|
-
array_types=(), derivative_dimensions=None, verbosity=0
|
273
|
+
array_types=(), derivative_dimensions=None, verbosity=0,
|
274
|
+
layout_creation_circuit_cache = None):
|
327
275
|
"""
|
328
276
|
Constructs an circuit-outcome-probability-array (COPA) layout for `circuits` and `dataset`.
|
329
277
|
|
@@ -364,6 +312,8 @@ class ForwardSimulator(_NicelySerializable):
|
|
364
312
|
verbosity : int or VerbosityPrinter
|
365
313
|
Determines how much output to send to stdout. 0 means no output, higher
|
366
314
|
integers mean more output.
|
315
|
+
|
316
|
+
|
367
317
|
|
368
318
|
Returns
|
369
319
|
-------
|
@@ -378,6 +328,15 @@ class ForwardSimulator(_NicelySerializable):
|
|
378
328
|
derivative_dimensions = tuple()
|
379
329
|
return _CircuitOutcomeProbabilityArrayLayout.create_from(circuits, self.model, dataset, derivative_dimensions,
|
380
330
|
resource_alloc=resource_alloc)
|
331
|
+
|
332
|
+
@staticmethod
|
333
|
+
def create_copa_layout_circuit_cache(circuits, model, dataset=None):
|
334
|
+
"""
|
335
|
+
Helper function for pre-computing/pre-processing circuits structures
|
336
|
+
used in matrix layout creation.
|
337
|
+
"""
|
338
|
+
msg = "Not currently implemented for this forward simulator class."
|
339
|
+
raise NotImplementedError(msg)
|
381
340
|
|
382
341
|
def bulk_probs(self, circuits, clip_to=None, resource_alloc=None, smartc=None):
|
383
342
|
"""
|
@@ -26,6 +26,8 @@ from pygsti.baseobjs.verbosityprinter import VerbosityPrinter as _VerbosityPrint
|
|
26
26
|
from pygsti.tools import sharedmemtools as _smt
|
27
27
|
from pygsti.tools import slicetools as _slct
|
28
28
|
from pygsti.tools.matrixtools import _fas
|
29
|
+
from pygsti.tools import listtools as _lt
|
30
|
+
from pygsti.circuits import CircuitList as _CircuitList
|
29
31
|
|
30
32
|
_dummy_profiler = _DummyProfiler()
|
31
33
|
|
@@ -49,7 +51,7 @@ class SimpleMapForwardSimulator(_ForwardSimulator):
|
|
49
51
|
# If this is done, then MapForwardSimulator wouldn't need to separately subclass DistributableForwardSimulator
|
50
52
|
|
51
53
|
def _compute_circuit_outcome_probabilities(self, array_to_fill, circuit, outcomes, resource_alloc, time=None):
|
52
|
-
expanded_circuit_outcomes =
|
54
|
+
expanded_circuit_outcomes = self.model.expand_instruments_and_separate_povm(circuit, outcomes)
|
53
55
|
outcome_to_index = {outc: i for i, outc in enumerate(outcomes)}
|
54
56
|
for spc, spc_outcomes in expanded_circuit_outcomes.items(): # spc is a SeparatePOVMCircuit
|
55
57
|
# Note: `spc.circuit_without_povm` *always* begins with a prep label.
|
@@ -157,7 +159,7 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
157
159
|
if method_name == 'bulk_fill_timedep_dchi2': return ('p',) # just an additional parameter vector
|
158
160
|
return super()._array_types_for_method(method_name)
|
159
161
|
|
160
|
-
def __init__(self, model=None, max_cache_size=
|
162
|
+
def __init__(self, model=None, max_cache_size=None, num_atoms=None, processor_grid=None, param_blk_sizes=None,
|
161
163
|
derivative_eps=1e-7, hessian_eps=1e-5):
|
162
164
|
#super().__init__(model, num_atoms, processor_grid, param_blk_sizes)
|
163
165
|
_DistributableForwardSimulator.__init__(self, model, num_atoms, processor_grid, param_blk_sizes)
|
@@ -193,7 +195,9 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
193
195
|
self._processor_grid, self._pblk_sizes)
|
194
196
|
|
195
197
|
def create_layout(self, circuits, dataset=None, resource_alloc=None, array_types=('E',),
|
196
|
-
derivative_dimensions=None, verbosity=0
|
198
|
+
derivative_dimensions=None, verbosity=0, layout_creation_circuit_cache=None,
|
199
|
+
circuit_partition_cost_functions=('size', 'propagations'),
|
200
|
+
load_balancing_parameters=(1.15,.1)):
|
197
201
|
"""
|
198
202
|
Constructs an circuit-outcome-probability-array (COPA) layout for a list of circuits.
|
199
203
|
|
@@ -223,6 +227,23 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
223
227
|
verbosity : int or VerbosityPrinter
|
224
228
|
Determines how much output to send to stdout. 0 means no output, higher
|
225
229
|
integers mean more output.
|
230
|
+
|
231
|
+
layout_creation_circuit_cache : dict, optional (default None)
|
232
|
+
A precomputed dictionary serving as a cache for completed circuits. I.e. circuits
|
233
|
+
with prep labels and POVM labels appended. Along with other useful pre-computed
|
234
|
+
circuit structures used in layout creation.
|
235
|
+
|
236
|
+
circuit_partition_cost_functions : tuple of str, optional (default ('size', 'propagations'))
|
237
|
+
A tuple of strings denoting cost function to use in each of the two stages of the algorithm
|
238
|
+
for determining the partitions of the complete circuit set amongst atoms.
|
239
|
+
Allowed options are 'size', which corresponds to balancing the number of circuits,
|
240
|
+
and 'propagations', which corresponds to balancing the number of state propagations.
|
241
|
+
|
242
|
+
load_balancing_parameters : tuple of floats, optional (default (1.15, .1))
|
243
|
+
A tuple of floats used as load balancing parameters when splitting a layout across atoms,
|
244
|
+
as in the multi-processor setting when using MPI. These parameters correspond to the `imbalance_threshold`
|
245
|
+
and `minimum_improvement_threshold` parameters described in the method `find_splitting_new`
|
246
|
+
of the `PrefixTable` class.
|
226
247
|
|
227
248
|
Returns
|
228
249
|
-------
|
@@ -248,15 +269,15 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
248
269
|
raise MemoryError("Attempted layout creation w/memory limit = %g <= 0!" % mem_limit)
|
249
270
|
printer.log("Layout creation w/mem limit = %.2fGB" % (mem_limit * C))
|
250
271
|
|
251
|
-
#Start with how we'd like to split processors up (without regard to memory limit):
|
252
|
-
|
253
|
-
#
|
254
|
-
|
255
|
-
#
|
256
|
-
#work_per_proc = self.model.dim**2
|
272
|
+
#Start with how we'd like to split processors up (without regard to memory limit):
|
273
|
+
#The current implementation of map (should) benefit more from having a matching between the number of atoms
|
274
|
+
#and the number of processors, at least for up to around two-qubits.
|
275
|
+
default_natoms = nprocs # heuristic
|
276
|
+
#TODO: factor in the mem_limit value to more intelligently set the default number of atoms.
|
257
277
|
|
258
278
|
natoms, na, npp, param_dimensions, param_blk_sizes = self._compute_processor_distribution(
|
259
|
-
array_types, nprocs, num_params, len(circuits), default_natoms=
|
279
|
+
array_types, nprocs, num_params, len(circuits), default_natoms=default_natoms)
|
280
|
+
|
260
281
|
printer.log(f'Num Param Processors {npp}')
|
261
282
|
|
262
283
|
printer.log("MapLayout: %d processors divided into %s (= %d) grid along circuit and parameter directions." %
|
@@ -265,7 +286,9 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
265
286
|
assert(_np.prod((na,) + npp) <= nprocs), "Processor grid size exceeds available processors!"
|
266
287
|
|
267
288
|
layout = _MapCOPALayout(circuits, self.model, dataset, self._max_cache_size, natoms, na, npp,
|
268
|
-
param_dimensions, param_blk_sizes, resource_alloc,
|
289
|
+
param_dimensions, param_blk_sizes, resource_alloc,circuit_partition_cost_functions,
|
290
|
+
verbosity, layout_creation_circuit_cache= layout_creation_circuit_cache,
|
291
|
+
load_balancing_parameters=load_balancing_parameters)
|
269
292
|
|
270
293
|
if mem_limit is not None:
|
271
294
|
loc_nparams1 = num_params / npp[0] if len(npp) > 0 else 0
|
@@ -291,13 +314,6 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
291
314
|
layout._param_dimensions, (loc_nparams1, loc_nparams2),
|
292
315
|
(blk1, blk2), max_atom_cachesize, self.model.dim)
|
293
316
|
|
294
|
-
#def approx_mem_estimate(nc, np1, np2):
|
295
|
-
# approx_cachesize = (num_circuits / nc) * 1.3 # inflate expected # of circuits per atom => cache_size
|
296
|
-
# return _bytes_for_array_types(array_types, num_elements, num_elements / nc,
|
297
|
-
# num_circuits, num_circuits / nc,
|
298
|
-
# (num_params, num_params), (num_params / np1, num_params / np2),
|
299
|
-
# approx_cachesize, self.model.dim)
|
300
|
-
|
301
317
|
GB = 1.0 / 1024.0**3
|
302
318
|
if mem_estimate > mem_limit:
|
303
319
|
raise MemoryError("Not enough memory for desired layout! (limit=%.1fGB, required=%.1fGB)" % (
|
@@ -306,6 +322,41 @@ class MapForwardSimulator(_DistributableForwardSimulator, SimpleMapForwardSimula
|
|
306
322
|
printer.log(" Esimated memory required = %.1fGB" % (mem_estimate * GB))
|
307
323
|
|
308
324
|
return layout
|
325
|
+
|
326
|
+
@staticmethod
|
327
|
+
def create_copa_layout_circuit_cache(circuits, model, dataset=None):
|
328
|
+
"""
|
329
|
+
Helper function for pre-computing/pre-processing circuits structures
|
330
|
+
used in matrix layout creation.
|
331
|
+
"""
|
332
|
+
cache = dict()
|
333
|
+
completed_circuits = model.complete_circuits(circuits)
|
334
|
+
|
335
|
+
cache['completed_circuits'] = {ckt: comp_ckt for ckt, comp_ckt in zip(circuits, completed_circuits)}
|
336
|
+
|
337
|
+
split_circuits = model.split_circuits(completed_circuits, split_prep=False)
|
338
|
+
cache['split_circuits'] = {ckt: split_ckt for ckt, split_ckt in zip(circuits, split_circuits)}
|
339
|
+
|
340
|
+
|
341
|
+
if dataset is not None:
|
342
|
+
aliases = circuits.op_label_aliases if isinstance(circuits, _CircuitList) else None
|
343
|
+
ds_circuits = _lt.apply_aliases_to_circuits(circuits, aliases)
|
344
|
+
unique_outcomes_list = []
|
345
|
+
for ckt in ds_circuits:
|
346
|
+
ds_row = dataset[ckt]
|
347
|
+
unique_outcomes_list.append(ds_row.unique_outcomes if ds_row is not None else None)
|
348
|
+
else:
|
349
|
+
unique_outcomes_list = [None]*len(circuits)
|
350
|
+
|
351
|
+
expanded_circuit_outcome_list = model.bulk_expand_instruments_and_separate_povm(circuits,
|
352
|
+
observed_outcomes_list = unique_outcomes_list,
|
353
|
+
completed_circuits= completed_circuits)
|
354
|
+
|
355
|
+
expanded_circuit_cache = {ckt: expanded_ckt for ckt,expanded_ckt in zip(completed_circuits, expanded_circuit_outcome_list)}
|
356
|
+
cache['expanded_and_separated_circuits'] = expanded_circuit_cache
|
357
|
+
|
358
|
+
return cache
|
359
|
+
|
309
360
|
|
310
361
|
def _bulk_fill_probs_atom(self, array_to_fill, layout_atom, resource_alloc):
|
311
362
|
# Note: *don't* set dest_indices arg = layout.element_slice, as this is already done by caller
|
Binary file
|
@@ -1,6 +1,4 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# cython: profile=False
|
3
|
-
# cython: linetrace=False
|
4
2
|
|
5
3
|
#***************************************************************************************************
|
6
4
|
# Copyright 2015, 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
@@ -28,12 +26,6 @@ from ..tools import slicetools as _slct
|
|
28
26
|
#from ..tools import optools as _ot
|
29
27
|
from ..tools.matrixtools import _fas
|
30
28
|
|
31
|
-
#DEBUG REMOVE MEMORY PROFILING
|
32
|
-
#import os, psutil
|
33
|
-
#process = psutil.Process(os.getpid())
|
34
|
-
#def print_mem_usage(prefix):
|
35
|
-
# print("%s: mem usage = %.3f GB" % (prefix, process.memory_info().rss / (1024.0**3)))
|
36
|
-
|
37
29
|
#Use 64-bit integers
|
38
30
|
ctypedef long long INT
|
39
31
|
ctypedef unsigned long long UINT
|
@@ -59,15 +51,16 @@ def propagate_staterep(staterep, operationreps):
|
|
59
51
|
# Python -> C Conversion functions
|
60
52
|
# -----------------------------------------
|
61
53
|
|
62
|
-
|
54
|
+
@cython.wraparound(False)
|
55
|
+
cdef vector[vector[INT]] convert_maplayout(prefix_table_contents, operation_lookup, rho_lookup):
|
63
56
|
# c_layout :
|
64
57
|
# an array of INT-arrays; each INT-array is [iDest,iStart,iCache,<remainder gate indices>]
|
65
58
|
cdef vector[INT] intarray
|
66
|
-
cdef vector[vector[INT]] c_layout_atom = vector[vector[INT]](len(
|
67
|
-
for kk, (iDest, iStart, remainder, iCache) in enumerate(
|
59
|
+
cdef vector[vector[INT]] c_layout_atom = vector[vector[INT]](len(prefix_table_contents))
|
60
|
+
for kk, (iDest, iStart, remainder, iCache) in enumerate(prefix_table_contents):
|
68
61
|
if iStart is None: iStart = -1 # so always an int
|
69
62
|
if iCache is None: iCache = -1 # so always an int
|
70
|
-
remainder = remainder
|
63
|
+
remainder = remainder
|
71
64
|
intarray = vector[INT](3 + len(remainder))
|
72
65
|
intarray[0] = iDest
|
73
66
|
intarray[1] = iStart
|
@@ -107,6 +100,8 @@ cdef vector[vector[INT]] convert_and_wrap_dict_of_intlists(d, wrapper):
|
|
107
100
|
ret[i][j] = wrapper[intlist[j]]
|
108
101
|
return ret
|
109
102
|
|
103
|
+
@cython.boundscheck(False)
|
104
|
+
@cython.wraparound(False)
|
110
105
|
cdef vector[StateCRep*] create_rhocache(INT cacheSize, INT state_dim):
|
111
106
|
cdef INT i
|
112
107
|
cdef vector[StateCRep*] rho_cache = vector[StateCRep_ptr](cacheSize)
|
@@ -114,11 +109,14 @@ cdef vector[StateCRep*] create_rhocache(INT cacheSize, INT state_dim):
|
|
114
109
|
rho_cache[i] = new StateCRep(state_dim)
|
115
110
|
return rho_cache
|
116
111
|
|
112
|
+
@cython.boundscheck(False)
|
113
|
+
@cython.wraparound(False)
|
117
114
|
cdef void free_rhocache(vector[StateCRep*] rho_cache):
|
118
115
|
cdef UINT i
|
119
116
|
for i in range(rho_cache.size()): # fill cache with empty but alloc'd states
|
120
117
|
del rho_cache[i]
|
121
118
|
|
119
|
+
@cython.wraparound(False)
|
122
120
|
cdef vector[OpCRep*] convert_opreps(operationreps):
|
123
121
|
# c_opreps : an array of OpCReps
|
124
122
|
cdef vector[OpCRep*] c_opreps = vector[OpCRep_ptr](len(operationreps))
|
@@ -130,19 +128,20 @@ cdef StateCRep* convert_rhorep(rhorep):
|
|
130
128
|
# extract c-reps from rhorep and ereps => c_rho and c_ereps
|
131
129
|
return (<StateRep?>rhorep).c_state
|
132
130
|
|
131
|
+
@cython.wraparound(False)
|
133
132
|
cdef vector[StateCRep*] convert_rhoreps(rhoreps):
|
134
133
|
cdef vector[StateCRep*] c_rhoreps = vector[StateCRep_ptr](len(rhoreps))
|
135
134
|
for ii,rrep in rhoreps.items(): # (ii = python variable)
|
136
135
|
c_rhoreps[ii] = (<StateRep?>rrep).c_state
|
137
136
|
return c_rhoreps
|
138
137
|
|
138
|
+
@cython.wraparound(False)
|
139
139
|
cdef vector[EffectCRep*] convert_ereps(ereps):
|
140
140
|
cdef vector[EffectCRep*] c_ereps = vector[EffectCRep_ptr](len(ereps))
|
141
141
|
for i in range(len(ereps)):
|
142
142
|
c_ereps[i] = (<EffectRep>ereps[i]).c_effect
|
143
143
|
return c_ereps
|
144
144
|
|
145
|
-
|
146
145
|
# -----------------------------------------
|
147
146
|
# Mapfill functions
|
148
147
|
# -----------------------------------------
|
@@ -159,7 +158,6 @@ def mapfill_probs_atom(fwdsim, np.ndarray[double, mode="c", ndim=1] array_to_fil
|
|
159
158
|
shared_mem_leader = resource_alloc.is_host_leader if (resource_alloc is not None) else True
|
160
159
|
|
161
160
|
dest_indices = _slct.to_array(dest_indices) # make sure this is an array and not a slice
|
162
|
-
#dest_indices = np.ascontiguousarray(dest_indices) #unneeded
|
163
161
|
|
164
162
|
#Get (extension-type) representation objects
|
165
163
|
rho_lookup = { lbl:i for i,lbl in enumerate(layout_atom.rho_labels) } # rho labels -> ints for faster lookup
|
@@ -169,7 +167,7 @@ def mapfill_probs_atom(fwdsim, np.ndarray[double, mode="c", ndim=1] array_to_fil
|
|
169
167
|
ereps = [fwdsim.model._circuit_layer_operator(elbl, 'povm')._rep for elbl in layout_atom.full_effect_labels] # cache these in future
|
170
168
|
|
171
169
|
# convert to C-mode: evaltree, operation_lookup, operationreps
|
172
|
-
cdef vector[vector[INT]] c_layout_atom = convert_maplayout(layout_atom, operation_lookup, rho_lookup)
|
170
|
+
cdef vector[vector[INT]] c_layout_atom = convert_maplayout(layout_atom.table.contents, operation_lookup, rho_lookup)
|
173
171
|
cdef vector[StateCRep*] c_rhos = convert_rhoreps(rhoreps)
|
174
172
|
cdef vector[EffectCRep*] c_ereps = convert_ereps(ereps)
|
175
173
|
cdef vector[OpCRep*] c_opreps = convert_opreps(operationreps)
|
@@ -182,17 +180,6 @@ def mapfill_probs_atom(fwdsim, np.ndarray[double, mode="c", ndim=1] array_to_fil
|
|
182
180
|
cdef vector[vector[INT]] final_indices_per_circuit = convert_and_wrap_dict_of_intlists(
|
183
181
|
layout_atom.elindices_by_expcircuit, dest_indices)
|
184
182
|
|
185
|
-
#DEBUG REMOVE
|
186
|
-
#print_mem_usage("MAPFILL PROBS begin")
|
187
|
-
#for i in [1808, 419509, 691738, 497424]:
|
188
|
-
# from ..evotypes.densitymx.opreps import OpRepComposed
|
189
|
-
# op = operationreps[i]
|
190
|
-
# if isinstance(op.embedded_rep, OpRepComposed):
|
191
|
-
# extra = " factors = " + ', '.join([str(type(opp)) for opp in op.embedded_rep.factor_reps])
|
192
|
-
# else:
|
193
|
-
# extra = ""
|
194
|
-
# print("ID ",i,str(type(op)),str(type(op.embedded_rep)), extra)
|
195
|
-
|
196
183
|
if shared_mem_leader:
|
197
184
|
#Note: dm_mapfill_probs could have taken a resource_alloc to employ multiple cpus to do computation.
|
198
185
|
# Since array_fo_fill is assumed to be shared mem it would need to only update `array_to_fill` *if*
|
@@ -203,6 +190,7 @@ def mapfill_probs_atom(fwdsim, np.ndarray[double, mode="c", ndim=1] array_to_fil
|
|
203
190
|
free_rhocache(rho_cache) #delete cache entries
|
204
191
|
|
205
192
|
|
193
|
+
@cython.wraparound(False)
|
206
194
|
cdef dm_mapfill_probs(double[:] array_to_fill,
|
207
195
|
vector[vector[INT]] c_layout_atom,
|
208
196
|
vector[OpCRep*] c_opreps,
|
@@ -234,7 +222,7 @@ cdef dm_mapfill_probs(double[:] array_to_fill,
|
|
234
222
|
# - all rho_cache entries have been allocated via "new"
|
235
223
|
#REMOVE print("MAPFILL PROBS begin cfn")
|
236
224
|
for k in range(<INT>c_layout_atom.size()):
|
237
|
-
t0 = pytime.time() # DEBUG
|
225
|
+
#t0 = pytime.time() # DEBUG
|
238
226
|
intarray = c_layout_atom[k]
|
239
227
|
i = intarray[0]
|
240
228
|
istart = intarray[1]
|
@@ -298,22 +286,27 @@ cdef dm_mapfill_probs(double[:] array_to_fill,
|
|
298
286
|
del prop2
|
299
287
|
del shelved
|
300
288
|
|
301
|
-
|
289
|
+
@cython.wraparound(False)
|
302
290
|
def mapfill_dprobs_atom(fwdsim,
|
303
291
|
np.ndarray[double, ndim=2] array_to_fill,
|
304
292
|
dest_indices,
|
305
293
|
dest_param_indices,
|
306
294
|
layout_atom, param_indices, resource_alloc, double eps):
|
307
295
|
|
308
|
-
|
296
|
+
cdef int num_params = fwdsim.model.num_params
|
297
|
+
cdef int model_dim = fwdsim.model.dim
|
309
298
|
|
310
299
|
if param_indices is None:
|
311
|
-
param_indices = list(range(
|
300
|
+
param_indices = list(range(num_params))
|
312
301
|
if dest_param_indices is None:
|
313
302
|
dest_param_indices = list(range(_slct.length(param_indices)))
|
314
303
|
|
315
|
-
|
316
|
-
|
304
|
+
cdef np.ndarray[np.int64_t, ndim=1, mode='c'] param_indices_array = _slct.to_array(param_indices)
|
305
|
+
cdef np.ndarray[np.int64_t, ndim=1, mode='c'] dest_param_indices_array = _slct.to_array(dest_param_indices)
|
306
|
+
|
307
|
+
cdef np.int64_t[::1] param_indices_view = param_indices_array
|
308
|
+
cdef np.int64_t[::1] dest_param_indices_view = dest_param_indices_array
|
309
|
+
|
317
310
|
|
318
311
|
#Get (extension-type) representation objects
|
319
312
|
# NOTE: the circuit_layer_operator(lbl) functions cache the returned operation
|
@@ -327,7 +320,7 @@ def mapfill_dprobs_atom(fwdsim,
|
|
327
320
|
ereps = [fwdsim.model._circuit_layer_operator(elbl, 'povm')._rep for elbl in layout_atom.full_effect_labels] # cache these in future
|
328
321
|
|
329
322
|
# convert to C-mode: evaltree, operation_lookup, operationreps
|
330
|
-
cdef vector[vector[INT]] c_layout_atom = convert_maplayout(layout_atom, operation_lookup, rho_lookup)
|
323
|
+
cdef vector[vector[INT]] c_layout_atom = convert_maplayout(layout_atom.table.contents, operation_lookup, rho_lookup)
|
331
324
|
cdef vector[StateCRep*] c_rhos = convert_rhoreps(rhoreps)
|
332
325
|
cdef vector[EffectCRep*] c_ereps = convert_ereps(ereps)
|
333
326
|
cdef vector[OpCRep*] c_opreps = convert_opreps(operationreps)
|
@@ -335,53 +328,60 @@ def mapfill_dprobs_atom(fwdsim,
|
|
335
328
|
# create rho_cache = vector of StateCReps
|
336
329
|
#print "DB: creating rho_cache of size %d * %g GB => %g GB" % \
|
337
330
|
# (layout_atom.cache_size, 8.0 * fwdsim.model.dim / 1024.0**3, layout_atom.cache_size * 8.0 * fwdsim.model.dim / 1024.0**3)
|
338
|
-
cdef vector[StateCRep*] rho_cache = create_rhocache(layout_atom.cache_size,
|
331
|
+
cdef vector[StateCRep*] rho_cache = create_rhocache(layout_atom.cache_size, model_dim)
|
339
332
|
|
340
333
|
cdef vector[vector[INT]] elabel_indices_per_circuit = convert_dict_of_intlists(layout_atom.elbl_indices_by_expcircuit)
|
341
334
|
cdef vector[vector[INT]] final_indices_per_circuit = convert_dict_of_intlists(layout_atom.elindices_by_expcircuit)
|
342
335
|
|
343
|
-
orig_vec = fwdsim.model.to_vector().copy()
|
336
|
+
cdef np.ndarray[np.float64_t, ndim=1, mode='c'] orig_vec = fwdsim.model.to_vector().copy()
|
337
|
+
cdef double[::1] orig_vec_view = orig_vec
|
344
338
|
fwdsim.model.from_vector(orig_vec, close=False) # ensure we call with close=False first
|
345
339
|
|
346
340
|
nEls = layout_atom.num_elements
|
347
|
-
probs = np.empty(nEls,
|
348
|
-
probs2 = np.empty(nEls,
|
341
|
+
cdef np.ndarray[np.float64_t, ndim=1, mode='c'] probs = np.empty(nEls, dtype=np.float64) #must be contiguous!
|
342
|
+
cdef np.ndarray[np.float64_t, ndim=1, mode='c'] probs2 = np.empty(nEls, dtype=np.float64) #must be contiguous!
|
343
|
+
|
344
|
+
cdef double[::1] probs_view = probs
|
345
|
+
cdef double[::1] probs2_view = probs2
|
349
346
|
|
350
347
|
#if resource_alloc.comm_rank == 0:
|
351
348
|
# print("MAPFILL DPROBS ATOM 1"); t=pytime.time(); t0=pytime.time()
|
352
|
-
dm_mapfill_probs(
|
353
|
-
elabel_indices_per_circuit, final_indices_per_circuit, fwdsim.model.dim)
|
349
|
+
dm_mapfill_probs(probs_view, c_layout_atom, c_opreps, c_rhos, c_ereps, &rho_cache, elabel_indices_per_circuit, final_indices_per_circuit, model_dim)
|
354
350
|
#if resource_alloc.comm_rank == 0:
|
355
351
|
# print("MAPFILL DPROBS ATOM 2 %.3fs" % (pytime.time() - t)); t=pytime.time()
|
356
352
|
|
357
|
-
shared_mem_leader = resource_alloc.is_host_leader
|
358
|
-
|
359
|
-
#
|
360
|
-
|
361
|
-
|
353
|
+
cdef bint shared_mem_leader = resource_alloc.is_host_leader
|
354
|
+
|
355
|
+
#add typing to indices we'll be using below:
|
356
|
+
cdef int i
|
357
|
+
cdef int first_param_idx
|
358
|
+
cdef int iFinal
|
359
|
+
|
360
|
+
#Split off the first finite difference step, as the pattern I want in the loop with each step
|
361
|
+
#is to simultaneously undo the previous update and apply the new one.
|
362
|
+
if len(param_indices_view)>0:
|
363
|
+
#probs2_view[:] = probs_view[:]
|
364
|
+
first_param_idx = param_indices_view[0]
|
365
|
+
iFinal = dest_param_indices_view[0]
|
366
|
+
fwdsim.model.set_parameter_value(first_param_idx, orig_vec_view[first_param_idx]+eps)
|
367
|
+
if shared_mem_leader: # don't fill assumed-shared array-to_fill on non-mem-leaders
|
368
|
+
dm_mapfill_probs(probs2_view, c_layout_atom, c_opreps, c_rhos, c_ereps, &rho_cache, elabel_indices_per_circuit, final_indices_per_circuit, model_dim)
|
369
|
+
array_to_fill[dest_indices, iFinal] = (probs2 - probs) / eps
|
370
|
+
|
371
|
+
for i in range(1, len(param_indices_view)):
|
372
|
+
#probs2_view[:] = probs_view[:]
|
373
|
+
iFinal = dest_param_indices_view[i]
|
374
|
+
fwdsim.model.set_parameter_values([param_indices_view[i-1], param_indices_view[i]], [orig_vec_view[param_indices_view[i-1]], orig_vec_view[param_indices_view[i]]+eps])
|
375
|
+
|
376
|
+
if shared_mem_leader: # don't fill assumed-shared array-to_fill on non-mem-leaders
|
377
|
+
dm_mapfill_probs(probs2_view, c_layout_atom, c_opreps, c_rhos, c_ereps, &rho_cache, elabel_indices_per_circuit, final_indices_per_circuit, model_dim)
|
378
|
+
array_to_fill[dest_indices, iFinal] = (probs2 - probs) / eps
|
379
|
+
|
380
|
+
#reset the final model parameter we changed to it's original value.
|
381
|
+
fwdsim.model.set_parameter_value(param_indices_view[len(param_indices_view)-1], orig_vec_view[param_indices_view[len(param_indices_view)-1]])
|
362
382
|
|
363
|
-
for i in range(fwdsim.model.num_params):
|
364
|
-
#print("dprobs cache %d of %d" % (i,self.Np))
|
365
|
-
if i in iParamToFinal:
|
366
|
-
#if resource_alloc.comm_rank == 0:
|
367
|
-
# print("MAPFILL DPROBS ATOM 3 (i=%d) %.3fs elapssed=%.1fs" % (i, pytime.time() - t, pytime.time() - t0)); t=pytime.time()
|
368
|
-
iFinal = iParamToFinal[i]
|
369
|
-
vec = orig_vec.copy(); vec[i] += eps
|
370
|
-
fwdsim.model.from_vector(vec, close=True)
|
371
|
-
#Note: dm_mapfill_probs could have taken a resource_alloc to employ multiple cpus to do computation.
|
372
|
-
# If probs2 were shared mem (seems not benefit to this?) it would need to only update `probs2` *if*
|
373
|
-
# it were the host leader.
|
374
|
-
if shared_mem_leader: # don't fill assumed-shared array-to_fill on non-mem-leaders
|
375
|
-
dm_mapfill_probs(probs2, c_layout_atom, c_opreps, c_rhos, c_ereps, &rho_cache,
|
376
|
-
elabel_indices_per_circuit, final_indices_per_circuit, fwdsim.model.dim)
|
377
|
-
#_fas(array_to_fill, [dest_indices, iFinal], (probs2 - probs) / eps) # I don't think this is needed
|
378
|
-
array_to_fill[dest_indices, iFinal] = (probs2 - probs) / eps
|
379
|
-
|
380
|
-
#if resource_alloc.comm_rank == 0:
|
381
|
-
# print("MAPFILL DPROBS ATOM 4 elapsed=%.1fs" % (pytime.time() - t0))
|
382
|
-
fwdsim.model.from_vector(orig_vec, close=True)
|
383
383
|
free_rhocache(rho_cache) #delete cache entries
|
384
|
-
|
384
|
+
|
385
385
|
|
386
386
|
cdef double TDchi2_obj_fn(double p, double f, double n_i, double n, double omitted_p, double min_prob_clip_for_weighting, double extra):
|
387
387
|
cdef double cp, v, omitted_cp
|
@@ -475,7 +475,6 @@ def mapfill_TDterms(fwdsim, objective, array_to_fill, dest_indices, num_outcomes
|
|
475
475
|
#comm is currently ignored
|
476
476
|
#TODO: if layout_atom is split, distribute among processors
|
477
477
|
for iDest, iStart, remainder, iCache in layout_atom.table.contents:
|
478
|
-
remainder = remainder.circuit_without_povm.layertup
|
479
478
|
rholabel = remainder[0]; remainder = remainder[1:]
|
480
479
|
rhoVec = fwdsim.model._circuit_layer_operator(rholabel, 'prep')
|
481
480
|
|