QuLab 2.4.17__cp310-cp310-win_amd64.whl → 2.4.19__cp310-cp310-win_amd64.whl
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.
- {QuLab-2.4.17.dist-info → QuLab-2.4.19.dist-info}/METADATA +1 -1
- {QuLab-2.4.17.dist-info → QuLab-2.4.19.dist-info}/RECORD +12 -12
- qulab/executor/cli.py +8 -7
- qulab/executor/load.py +33 -8
- qulab/executor/schedule.py +13 -5
- qulab/executor/utils.py +1 -1
- qulab/fun.cp310-win_amd64.pyd +0 -0
- qulab/version.py +1 -1
- {QuLab-2.4.17.dist-info → QuLab-2.4.19.dist-info}/LICENSE +0 -0
- {QuLab-2.4.17.dist-info → QuLab-2.4.19.dist-info}/WHEEL +0 -0
- {QuLab-2.4.17.dist-info → QuLab-2.4.19.dist-info}/entry_points.txt +0 -0
- {QuLab-2.4.17.dist-info → QuLab-2.4.19.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
qulab/__init__.py,sha256=vkFybY8YSsQilYdThPRD83-btPAR41sy_WCXiM-6mME,141
|
|
2
2
|
qulab/__main__.py,sha256=g9iBs8xxX6Yik7cmgllQkpBN8C4JNoZVsEOyCCLCyFU,63
|
|
3
3
|
qulab/dicttree.py,sha256=ZoSJVWK4VMqfzj42gPb_n5RqLlM6K1Me0WmLIfLEYf8,14195
|
|
4
|
-
qulab/fun.cp310-win_amd64.pyd,sha256=
|
|
5
|
-
qulab/version.py,sha256=
|
|
4
|
+
qulab/fun.cp310-win_amd64.pyd,sha256=LGAxFzWY-IvGR2blvMvvCJRdEu7tC7Vq7PsOWJ_oQ0E,31232
|
|
5
|
+
qulab/version.py,sha256=FprAMvy2C6tN_5YBOzn2q7pwL66I-_0THetgU5i1QL0,22
|
|
6
6
|
qulab/cli/__init__.py,sha256=6xd2eYw32k1NmfAuYSu__1kaP12Oz1QVqwbkYXdWno4,588
|
|
7
7
|
qulab/cli/config.py,sha256=gvMObzaVJ-xTJ1GmhP3sATayfDasYlijX1krSGeccNY,3071
|
|
8
8
|
qulab/executor/__init__.py,sha256=LosPzOMaljSZY1thy_Fxtbrgq7uubJszMABEB7oM7tU,101
|
|
9
|
-
qulab/executor/cli.py,sha256=
|
|
10
|
-
qulab/executor/load.py,sha256=
|
|
11
|
-
qulab/executor/schedule.py,sha256=
|
|
9
|
+
qulab/executor/cli.py,sha256=owdDSaSuzTPQA5SlNCxX4nHWITU1BF0VZMj7tLqCZhM,5781
|
|
10
|
+
qulab/executor/load.py,sha256=fZNmsOGR_2s1IykVmVwziDKeWCIej-jRJAQzKJRUdaE,11990
|
|
11
|
+
qulab/executor/schedule.py,sha256=bXQzn3e3tCvAVdEBsvh5ecAThP52njyxbsrlrxC9TzA,11922
|
|
12
12
|
qulab/executor/storage.py,sha256=M66Q5_Uc5MMfc_QAuuaaexwAz7wxBPMkeleB5nRpQmI,4621
|
|
13
13
|
qulab/executor/transform.py,sha256=inaOn6eqCs22ZZ0xAQl8s8YCoEACaXSwFNNu7jqdwAk,2148
|
|
14
|
-
qulab/executor/utils.py,sha256=
|
|
14
|
+
qulab/executor/utils.py,sha256=_9EZkx2rBpsWjhDN5BZ-Lq9MboqmHcI1jtwpRyrzSTY,3101
|
|
15
15
|
qulab/monitor/__init__.py,sha256=xEVDkJF8issrsDeLqQmDsvtRmrf-UiViFcGTWuzdlFU,43
|
|
16
16
|
qulab/monitor/__main__.py,sha256=k2H1H5Zf9LLXTDLISJkbikLH-z0f1e5i5i6wXXYPOrE,105
|
|
17
17
|
qulab/monitor/config.py,sha256=y_5StMkdrbZO1ziyKBrvIkB7Jclp9RCPK1QbsOhCxnY,785
|
|
@@ -91,9 +91,9 @@ qulab/visualization/plot_seq.py,sha256=Uo1-dB1YE9IN_A9tuaOs9ZG3S5dKDQ_l98iD2Wbxp
|
|
|
91
91
|
qulab/visualization/qdat.py,sha256=HubXFu4nfcA7iUzghJGle1C86G6221hicLR0b-GqhKQ,5887
|
|
92
92
|
qulab/visualization/rot3d.py,sha256=jGHJcqj1lEWBUV-W4GUGONGacqjrYvuFoFCwPse5h1Y,757
|
|
93
93
|
qulab/visualization/widgets.py,sha256=HcYwdhDtLreJiYaZuN3LfofjJmZcLwjMfP5aasebgDo,3266
|
|
94
|
-
QuLab-2.4.
|
|
95
|
-
QuLab-2.4.
|
|
96
|
-
QuLab-2.4.
|
|
97
|
-
QuLab-2.4.
|
|
98
|
-
QuLab-2.4.
|
|
99
|
-
QuLab-2.4.
|
|
94
|
+
QuLab-2.4.19.dist-info/LICENSE,sha256=b4NRQ-GFVpJMT7RuExW3NwhfbrYsX7AcdB7Gudok-fs,1086
|
|
95
|
+
QuLab-2.4.19.dist-info/METADATA,sha256=q7WDxNcYfN0kA74z72310B_oUz32WVX1CfP6F4O6lIo,3804
|
|
96
|
+
QuLab-2.4.19.dist-info/WHEEL,sha256=rzGfZgUcGeKSgIHGYMuqg4xE4VPHxnaldXH6BG0zjVk,101
|
|
97
|
+
QuLab-2.4.19.dist-info/entry_points.txt,sha256=b0v1GXOwmxY-nCCsPN_rHZZvY9CtTbWqrGj8u1m8yHo,45
|
|
98
|
+
QuLab-2.4.19.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
|
|
99
|
+
QuLab-2.4.19.dist-info/RECORD,,
|
qulab/executor/cli.py
CHANGED
|
@@ -120,14 +120,15 @@ def get(key, api):
|
|
|
120
120
|
'-n',
|
|
121
121
|
is_flag=True,
|
|
122
122
|
help='Do not run dependents.')
|
|
123
|
+
@click.option('--update', '-u', is_flag=True)
|
|
123
124
|
@log_options
|
|
124
125
|
@command_option('run')
|
|
125
|
-
def run(workflow, code, data, api, plot, no_dependents):
|
|
126
|
+
def run(workflow, code, data, api, plot, no_dependents, update):
|
|
126
127
|
"""
|
|
127
128
|
Run a workflow.
|
|
128
129
|
"""
|
|
129
130
|
logger.info(
|
|
130
|
-
f'[CMD]: run {workflow} --code {code} --data {data} --api {api} --plot
|
|
131
|
+
f'[CMD]: run {workflow} --code {code} --data {data} --api {api}{" --plot" if plot else ""}{" --no-dependents" if no_dependents else ""}{" --update " if update else ""}'
|
|
131
132
|
)
|
|
132
133
|
if api is not None:
|
|
133
134
|
api = importlib.import_module(api)
|
|
@@ -145,15 +146,15 @@ def run(workflow, code, data, api, plot, no_dependents):
|
|
|
145
146
|
if no_dependents:
|
|
146
147
|
if hasattr(wf, 'entries'):
|
|
147
148
|
for entry in get_entries(wf, code):
|
|
148
|
-
run_workflow(entry, code, data, plot=plot)
|
|
149
|
+
run_workflow(entry, code, data, plot=plot, update=update)
|
|
149
150
|
else:
|
|
150
|
-
run_workflow(wf, code, data, plot=plot)
|
|
151
|
+
run_workflow(wf, code, data, plot=plot, update=update)
|
|
151
152
|
else:
|
|
152
153
|
if hasattr(wf, 'entries'):
|
|
153
154
|
for entry in get_entries(wf, code):
|
|
154
|
-
maintain_workflow(entry, code, data, run=True, plot=plot)
|
|
155
|
+
maintain_workflow(entry, code, data, run=True, plot=plot, update=update)
|
|
155
156
|
else:
|
|
156
|
-
maintain_workflow(wf, code, data, run=True, plot=plot)
|
|
157
|
+
maintain_workflow(wf, code, data, run=True, plot=plot, update=update)
|
|
157
158
|
|
|
158
159
|
|
|
159
160
|
@click.command()
|
|
@@ -166,7 +167,7 @@ def maintain(workflow, code, data, api, plot):
|
|
|
166
167
|
Maintain a workflow.
|
|
167
168
|
"""
|
|
168
169
|
logger.info(
|
|
169
|
-
f'[CMD]: maintain {workflow} --code {code} --data {data} --api {api} --plot
|
|
170
|
+
f'[CMD]: maintain {workflow} --code {code} --data {data} --api {api}{" --plot" if plot else ""}'
|
|
170
171
|
)
|
|
171
172
|
if api is not None:
|
|
172
173
|
api = importlib.import_module(api)
|
qulab/executor/load.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import base64
|
|
1
2
|
import hashlib
|
|
2
3
|
import inspect
|
|
4
|
+
import lzma
|
|
3
5
|
import pickle
|
|
4
6
|
import re
|
|
5
7
|
import string
|
|
8
|
+
import textwrap
|
|
6
9
|
import warnings
|
|
7
10
|
from importlib.util import module_from_spec, spec_from_file_location
|
|
8
11
|
from pathlib import Path
|
|
@@ -224,8 +227,24 @@ def load_workflow_from_file(file_name: str,
|
|
|
224
227
|
return module
|
|
225
228
|
|
|
226
229
|
|
|
230
|
+
def encode_mapping(mapping):
|
|
231
|
+
mapping_bytes = lzma.compress(pickle.dumps(mapping))
|
|
232
|
+
hash_str = hashlib.md5(mapping_bytes).hexdigest()[:8]
|
|
233
|
+
mappping_code = '\n'.join(
|
|
234
|
+
textwrap.wrap(base64.b64encode(mapping_bytes).decode(), 100))
|
|
235
|
+
return hash_str, mappping_code
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def decode_mapping(hash_str, mappping_code):
|
|
239
|
+
mapping_bytes = base64.b64decode(mappping_code.replace('\n', ''))
|
|
240
|
+
if hash_str != hashlib.md5(mapping_bytes).hexdigest()[:8]:
|
|
241
|
+
raise ValueError("Hash does not match")
|
|
242
|
+
mapping = pickle.loads(lzma.decompress(mapping_bytes))
|
|
243
|
+
return mapping
|
|
244
|
+
|
|
245
|
+
|
|
227
246
|
def load_workflow_from_template(template_path: str,
|
|
228
|
-
|
|
247
|
+
mapping: dict[str, str],
|
|
229
248
|
base_path: str | Path,
|
|
230
249
|
target_path: str | None = None,
|
|
231
250
|
package='workflows',
|
|
@@ -237,30 +256,36 @@ def load_workflow_from_template(template_path: str,
|
|
|
237
256
|
content = f.read()
|
|
238
257
|
|
|
239
258
|
mtime = max(Path(template_path).stat().st_mtime, mtime)
|
|
259
|
+
hash_str, mapping_code = encode_mapping(mapping)
|
|
240
260
|
|
|
241
261
|
def replace(text):
|
|
242
262
|
"""
|
|
243
|
-
将给定文本中的所有
|
|
263
|
+
将给定文本中的所有 VAR("var") 替换为 __VAR_{hash_str}["var"]。
|
|
244
264
|
|
|
245
265
|
Args:
|
|
246
|
-
text (str): 包含
|
|
266
|
+
text (str): 包含 VAR 调用的字符串。
|
|
247
267
|
|
|
248
268
|
Returns:
|
|
249
269
|
str: 已经替换的新字符串。
|
|
250
270
|
"""
|
|
251
|
-
pattern = re.compile(r'
|
|
252
|
-
replacement = r'
|
|
271
|
+
pattern = re.compile(r'VAR\s*\(\s*(["\'])(\w+)\1\s*\)')
|
|
272
|
+
replacement = f'__VAR_{hash_str}' + r'["\2"]'
|
|
253
273
|
new_text = re.sub(pattern, replacement, text)
|
|
254
274
|
return new_text
|
|
255
275
|
|
|
256
276
|
template = string.Template(replace(content))
|
|
257
277
|
keys = template.get_identifiers()
|
|
258
|
-
missing = set(keys) - set(
|
|
278
|
+
missing = set(keys) - set(mapping.keys())
|
|
259
279
|
if missing:
|
|
260
280
|
raise KeyError(f"{template_path}: Missing keys in mapping: {missing}")
|
|
261
|
-
content = template.substitute(
|
|
281
|
+
content = template.substitute(mapping)
|
|
262
282
|
|
|
263
|
-
|
|
283
|
+
inject_code = [
|
|
284
|
+
"from qulab.executor.load import decode_mapping",
|
|
285
|
+
f"__VAR_{hash_str} = decode_mapping(\"{hash_str}\",",
|
|
286
|
+
f"\"\"\"{mapping_code}\"\"\")"
|
|
287
|
+
]
|
|
288
|
+
content = '\n'.join(inject_code + [content])
|
|
264
289
|
if target_path is None:
|
|
265
290
|
if path.stem == 'template':
|
|
266
291
|
path = path.parent / f'tmp{hash_str}.py'
|
qulab/executor/schedule.py
CHANGED
|
@@ -236,7 +236,8 @@ def maintain(workflow: WorkflowType,
|
|
|
236
236
|
state_path: str | Path,
|
|
237
237
|
session_id: str | None = None,
|
|
238
238
|
run: bool = False,
|
|
239
|
-
plot: bool = False
|
|
239
|
+
plot: bool = False,
|
|
240
|
+
update: bool = True):
|
|
240
241
|
if session_id is None:
|
|
241
242
|
session_id = uuid.uuid4().hex
|
|
242
243
|
logger.debug(f'run "{workflow.__workflow_id__}"'
|
|
@@ -280,7 +281,8 @@ def maintain(workflow: WorkflowType,
|
|
|
280
281
|
raise CalibrationFailedError(
|
|
281
282
|
f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
|
|
282
283
|
)
|
|
283
|
-
|
|
284
|
+
if update:
|
|
285
|
+
transform.update_parameters(result)
|
|
284
286
|
return
|
|
285
287
|
|
|
286
288
|
|
|
@@ -288,13 +290,19 @@ def maintain(workflow: WorkflowType,
|
|
|
288
290
|
def run(workflow: WorkflowType,
|
|
289
291
|
code_path: str | Path,
|
|
290
292
|
state_path: str | Path,
|
|
291
|
-
plot: bool = False
|
|
293
|
+
plot: bool = False,
|
|
294
|
+
update: bool = True):
|
|
292
295
|
session_id = uuid.uuid4().hex
|
|
293
296
|
logger.debug(f'run "{workflow.__workflow_id__}" without dependences.')
|
|
294
|
-
result = calibrate(workflow,
|
|
297
|
+
result = calibrate(workflow,
|
|
298
|
+
code_path,
|
|
299
|
+
state_path,
|
|
300
|
+
plot,
|
|
301
|
+
session_id=session_id)
|
|
295
302
|
if result.bad_data or not result.in_spec:
|
|
296
303
|
raise CalibrationFailedError(
|
|
297
304
|
f'"{workflow.__workflow_id__}": All dependents passed, but calibration failed!'
|
|
298
305
|
)
|
|
299
|
-
|
|
306
|
+
if update:
|
|
307
|
+
transform.update_parameters(result)
|
|
300
308
|
return
|
qulab/executor/utils.py
CHANGED
qulab/fun.cp310-win_amd64.pyd
CHANGED
|
Binary file
|
qulab/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "2.4.
|
|
1
|
+
__version__ = "2.4.19"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|