-
Notifications
You must be signed in to change notification settings - Fork 56
/
legacyio.py
327 lines (267 loc) · 15.7 KB
/
legacyio.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
""" Functions for allowing old-vesion objects to unpickle load."""
#***************************************************************************************************
# Copyright 2015, 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
# Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government retains certain rights
# in this software.
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0 or in the LICENSE file in the root pyGSTi directory.
#***************************************************************************************************
import sys as _sys
import numpy as _np
import numbers as _numbers
from types import ModuleType as _ModuleType
from contextlib import contextmanager as _contextmanager
from .. import objects as _objs
from ..objects import circuit as _circuit
@_contextmanager
def enable_old_object_unpickling(old_version="0.9.6"):
"""
Returns a context manager which enables the unpickling of old-version (0.9.6
and sometimes prior) objects.
"""
def totup(v): return tuple(map(int, v.split('.')))
old_version = totup(old_version)
if old_version < totup("0.9.6"):
raise ValueError(("Cannot unpickle files from version < 0.9.6 with this version."
" Revert back to 0.9.6 and update to 0.9.6 first."))
if old_version == totup("0.9.6"):
class dummy_GateString(object):
def __new__(cls):
replacement_obj = _circuit.Circuit.__new__(_circuit.Circuit)
return replacement_obj
def GateString_setstate(self, state):
s = state['_str'] if '_str' in state else state['str']
c = _objs.Circuit(state['_tup'], stringrep=s)
#OLD: self.__dict__.update(c.__dict__)
return c.__dict__ # now just return updated Circuit state
class dummy_CompressedGateString(object):
def __new__(cls):
replacement_obj = _circuit.CompressedCircuit.__new__(_circuit.CompressedCircuit)
return replacement_obj
class dummy_GateSet(object):
def __new__(cls):
replacement_obj = _objs.ExplicitOpModel.__new__(_objs.ExplicitOpModel)
return replacement_obj
class dummy_GateMatrixCalc(object):
def __new__(cls):
replacement_obj = _objs.MatrixForwardSimulator.__new__(_objs.MatrixForwardSimulator)
return replacement_obj
class dummy_AutoGator(object): pass
class dummy_SimpleCompositionAutoGator(object): pass
class dummy_LindbladParameterizedGate(object):
def __new__(cls):
replacement_obj = _objs.LindbladDenseOp.__new__(_objs.LindbladDenseOp)
return replacement_obj
def Lind_setstate(self, state):
assert(not state['sparse']), "Can only unpickle old *dense* LindbladParameterizedGate objects"
g = _objs.LindbladDenseOp.from_operation_matrix(state['base'], state['unitary_postfactor'],
ham_basis=state['ham_basis'],
nonham_basis=state['other_basis'],
param_mode=state['param_mode'],
nonham_mode=state['nonham_mode'], truncate=True,
mxBasis=state['matrix_basis'], evotype=state['_evotype'])
self.__dict__.update(g.__dict__)
def ModelMember_setstate(self, state):
if "dirty" in state: # .dirty was replaced with ._dirty
state['_dirty'] = state['dirty']
del state['dirty']
self.__dict__.update(state)
#Modules
gatestring = _ModuleType("gatestring")
gatestring.GateString = dummy_GateString
gatestring.CompressedGateString = dummy_CompressedGateString
_sys.modules['pygsti.objects.gatestring'] = gatestring
#_objs.circuit.Circuit.__setstate__ = GateString_setstate Never needed now
gateset = _ModuleType("gateset")
gateset.GateSet = dummy_GateSet
_sys.modules['pygsti.objects.gateset'] = gateset
gate = _ModuleType("gate")
gate.EigenvalueParameterizedGate = _objs.EigenvalueParamDenseOp
gate.LinearlyParameterizedGate = _objs.LinearlyParamDenseOp
#gate.LindbladParameterizedGateMap = _objs.LindbladOp # no upgrade code for this yet
gate.LindbladParameterizedGate = dummy_LindbladParameterizedGate
_objs.LindbladDenseOp.__setstate__ = Lind_setstate # dummy_LindbladParameterizedGate.__setstate__
gate.FullyParameterizedGate = _objs.FullDenseOp
gate.TPParameterizedGate = _objs.TPDenseOp
gate.GateMatrix = _objs.DenseOperator
gate.ComposedGateMap = _objs.ComposedOp
gate.EmbeddedGateMap = _objs.EmbeddedOp
gate.ComposedGate = _objs.ComposedDenseOp
gate.EmbeddedGate = _objs.EmbeddedDenseOp
gate.StaticGate = _objs.StaticDenseOp
gate.LinearlyParameterizedElementTerm = _objs.operation.LinearlyParameterizedElementTerm
#MapOp = _objs.MapOperator
_sys.modules['pygsti.objects.gate'] = gate
# spamvec = _ModuleType("spamvec") #already exists - just add to it
spamvec = _sys.modules['pygsti.objects.spamvec']
spamvec.LindbladParameterizedSPAMVec = _objs.LindbladSPAMVec
spamvec.FullyParameterizedSPAMVec = _objs.FullSPAMVec
spamvec.CPTPParameterizedSPAMVec = _objs.CPTPSPAMVec
spamvec.TPParameterizedSPAMVec = _objs.TPSPAMVec
povm = _sys.modules['pygsti.objects.povm']
povm.LindbladParameterizedPOVM = _objs.LindbladPOVM
#Don't need class logic here b/c we just store the class itself in a model object:
gatematrixcalc = _ModuleType("gatematrixcalc")
gatematrixcalc.GateMatrixCalc = _objs.matrixforwardsim.MatrixForwardSimulator # dummy_GateMatrixCalc
_sys.modules['pygsti.objects.gatematrixcalc'] = gatematrixcalc
autogator = _ModuleType("autogator")
autogator.AutoGator = dummy_AutoGator
autogator.SimpleCompositionAutoGator = dummy_SimpleCompositionAutoGator
_sys.modules['pygsti.objects.autogator'] = autogator
gatestringstructure = _ModuleType("gatestringstructure")
gatestringstructure.GatestringPlaquette = _objs.circuitstructure.CircuitPlaquette
gatestringstructure.GateStringStructure = _objs.CircuitStructure
gatestringstructure.LsGermsStructure = _objs.LsGermsStructure
_sys.modules['pygsti.objects.gatestringstructure'] = gatestringstructure
_objs.modelmember.ModelMember.__setstate__ = ModelMember_setstate
if old_version <= totup("0.9.7.1"):
class dummy_Basis(object):
def __new__(cls):
replacement_obj = _objs.basis.BuiltinBasis.__new__(_objs.basis.BuiltinBasis)
return replacement_obj
def __setstate__(self, state):
return Basis_setstate(self, state)
def Basis_setstate(self, state):
if "labels" in state: # .label was replaced with ._label
state['_labels'] = state['labels']
del state['labels']
if "name" in state and state['name'] in ('pp', 'std', 'gm', 'qt', 'unknown') and 'dim' in state:
dim = state['dim'].opDim if hasattr(state['dim'], 'opDim') else state['dim']
assert(isinstance(dim, _numbers.Integral))
sparse = state['sparse'] if ('sparse' in state) else False
newBasis = _objs.BuiltinBasis(state['name'], int(dim), sparse)
self.__class__ = _objs.basis.BuiltinBasis
self.__dict__.update(newBasis.__dict__)
else:
raise ValueError("Can only load old *builtin* basis objects!")
class dummy_Dim(object):
def __setstate__(self, state): # was Dim_setstate
if "gateDim" in state: # .label was replaced with ._label
state['opDim'] = state['gateDim']
del state['gateDim']
self.__dict__.update(state)
def StateSpaceLabels_setstate(self, state):
squared_labeldims = {k: int(d**2) for k, d in state['labeldims'].items()}
squared_dims = [tuple((squared_labeldims[lbl] for lbl in tpbLbls))
for tpbLbls in state['labels']]
sslbls = _objs.StateSpaceLabels(state['labels'], squared_dims)
self.__dict__.update(sslbls.__dict__)
#DEBUG!!!
#print("!!setstate:")
#print(state)
#assert(False),"STOP"
def Circuit_setstate(self, state):
if old_version == totup("0.9.6"): # b/c this clobbers older-version upgrade
state = GateString_setstate(self, state)
if 'line_labels' in state: line_labels = state['line_labels']
elif '_line_labels' in state: line_labels = state['_line_labels']
else: raise ValueError("Cannot determing line labels from old Circuit state: %s" % str(state.keys()))
if state['_str']: # then rely on string rep to init new circuit
c = _objs.Circuit(None, line_labels, editable=not state['_static'], stringrep=state['_str'])
else:
if 'labels' in state: labels = state['labels']
elif '_labels' in state: labels = state['_labels']
else: raise ValueError("Cannot determing labels from old Circuit state: %s" % str(state.keys()))
c = _objs.Circuit(labels, line_labels, editable=not state['_static'])
self.__dict__.update(c.__dict__)
def Hack_CompressedCircuit_expand(self):
""" Hacked version to rely on string rep & re-parse if it's there """
return _objs.Circuit(None, self._line_labels, editable=False, stringrep=self._str)
def SPAMVec_setstate(self, state):
if "dirty" in state: # backward compat: .dirty was replaced with ._dirty in ModelMember
state['_dirty'] = state['dirty']; del state['dirty']
self.__dict__.update(state)
dim = _ModuleType("dim")
dim.Dim = dummy_Dim
_sys.modules['pygsti.baseobjs.dim'] = dim
#_objs.basis.saved_Basis = _objs.basis.Basis
#_objs.basis.Basis = dummy_Basis
_objs.basis.Basis.__setstate__ = Basis_setstate
_objs.circuit.Circuit.__setstate__ = Circuit_setstate
_objs.labeldicts.StateSpaceLabels.__setstate__ = StateSpaceLabels_setstate
_objs.circuit.CompressedCircuit.saved_expand = _objs.circuit.CompressedCircuit.expand
_objs.circuit.CompressedCircuit.expand = Hack_CompressedCircuit_expand
_objs.spamvec.SPAMVec.__setstate__ = SPAMVec_setstate
if old_version < totup("0.9.9"):
def SPAMVec_setstate(self, state):
#Note: include "dirty"
if old_version <= totup("0.9.7.1"): # b/c this clobbers older-version upgrade
if "dirty" in state: # backward compat: .dirty was replaced with ._dirty in ModelMember
state['_dirty'] = state['dirty']; del state['dirty']
if "_prep_or_effect" not in state:
state['_prep_or_effect'] = "unknown"
if "base1D" not in state and 'base' in state:
state['base1D'] = state['base'].flatten()
del state['base']
self.__dict__.update(state)
#HERE TODO: need to remake/add ._reps to all spam & operation objects
_objs.spamvec.SPAMVec.__setstate__ = SPAMVec_setstate
# Compatibility with refactored `baseobjs` API
_sys.modules['pygsti.baseobjs.smartcache'] = _objs.smartcache
_sys.modules['pygsti.baseobjs.verbosityprinter'] = _objs.verbosityprinter
_sys.modules['pygsti.baseobjs.profiler'] = _objs.profiler
_sys.modules['pygsti.baseobjs.protectedarray'] = _objs.protectedarray
_sys.modules['pygsti.baseobjs.objectivefns'] = _objs.objectivefns
_sys.modules['pygsti.baseobjs.basis'] = _objs.basis
_sys.modules['pygsti.baseobjs.label'] = _objs.label
if old_version < totup("0.9.9.1"):
def DenseOperator_setstate(self, state):
if "base" in state:
del state['base']
self.__dict__.update(state)
def DenseSPAMVec_setstate(self, state):
if old_version <= totup("0.9.9"): # b/c this clobbers (or shadows) older-version upgrade
if old_version <= totup("0.9.7.1"): # b/c this clobbers older-version upgrade
if "dirty" in state: # backward compat: .dirty was replaced with ._dirty in ModelMember
state['_dirty'] = state['dirty']; del state['dirty']
if "_prep_or_effect" not in state:
state['_prep_or_effect'] = "unknown"
if "base1D" not in state and 'base' in state:
state['base1D'] = state['base'].flatten()
del state['base']
if "base" in state:
del state['base']
if "base1D" in state:
del state['base1D']
self.__dict__.update(state)
_objs.spamvec.DenseSPAMVec.__setstate__ = DenseSPAMVec_setstate
_objs.operation.DenseOperator.__setstate__ = DenseOperator_setstate
yield # body of context-manager block
if old_version <= totup("0.9.6"):
del _sys.modules['pygsti.objects.gatestring']
del _sys.modules['pygsti.objects.gateset']
del _sys.modules['pygsti.objects.gate']
del _sys.modules['pygsti.objects.gatematrixcalc']
del _sys.modules['pygsti.objects.autogator']
del _sys.modules['pygsti.objects.gatestringstructure']
del _sys.modules['pygsti.objects.spamvec'].LindbladParameterizedSPAMVec
del _sys.modules['pygsti.objects.spamvec'].FullyParameterizedSPAMVec
del _sys.modules['pygsti.objects.spamvec'].CPTPParameterizedSPAMVec
del _sys.modules['pygsti.objects.spamvec'].TPParameterizedSPAMVec
del _sys.modules['pygsti.objects.povm'].LindbladParameterizedPOVM
delattr(_objs.Circuit, '__setstate__')
delattr(_objs.LindbladDenseOp, '__setstate__')
delattr(_objs.modelmember.ModelMember, '__setstate__')
if old_version <= totup("0.9.7.1"):
del _sys.modules['pygsti.baseobjs.dim']
delattr(_objs.Basis, '__setstate__')
delattr(_objs.labeldicts.StateSpaceLabels, '__setstate__')
if hasattr(_objs.Circuit, '__setstate__'): # b/c above block may have already deleted this
delattr(_objs.Circuit, '__setstate__')
_objs.circuit.CompressedCircuit.expand = _objs.circuit.CompressedCircuit.saved_expand
delattr(_objs.circuit.CompressedCircuit, 'saved_expand')
delattr(_objs.spamvec.SPAMVec, '__setstate__')
if old_version < totup("0.9.9"):
if hasattr(_objs.spamvec.SPAMVec, '__setstate__'): # b/c above block may have already deleted this
delattr(_objs.spamvec.SPAMVec, '__setstate__')
del _sys.modules['pygsti.baseobjs.smartcache']
del _sys.modules['pygsti.baseobjs.verbosityprinter']
del _sys.modules['pygsti.baseobjs.profiler']
del _sys.modules['pygsti.baseobjs.protectedarray']
del _sys.modules['pygsti.baseobjs.objectivefns']
del _sys.modules['pygsti.baseobjs.basis']
del _sys.modules['pygsti.baseobjs.label']
if old_version < totup("0.9.9.1"):
delattr(_objs.spamvec.DenseSPAMVec, '__setstate__')
delattr(_objs.operation.DenseOperator, '__setstate__')