QuLab 2.2.7__cp312-cp312-macosx_10_9_universal2.whl → 2.3.0__cp312-cp312-macosx_10_9_universal2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: QuLab
3
- Version: 2.2.7
3
+ Version: 2.3.0
4
4
  Summary: contral instruments and manage data
5
5
  Author-email: feihoo87 <feihoo87@gmail.com>
6
6
  Maintainer-email: feihoo87 <feihoo87@gmail.com>
@@ -1,7 +1,7 @@
1
1
  qulab/__init__.py,sha256=P-Mx2p4TVmL91SoxoeXcj8Qm0x4xUf5Q_FLk0Yc_gIQ,138
2
2
  qulab/__main__.py,sha256=ZC1NKaoxKyy60DaCfB8vYnB1z3RXQ2j8E1sRZ4A8sXE,428
3
- qulab/fun.cpython-312-darwin.so,sha256=bK6YBpg8BHy3YmH1ak7NVoXnaF1HMAXTsvevATS9aHQ,159632
4
- qulab/version.py,sha256=I501tBgxLlOMpveUyk065aIcjgpxqCi7zjY3gqoar7c,21
3
+ qulab/fun.cpython-312-darwin.so,sha256=JVHBI8lJzKnWDQrrte1tgnQMgtZJCl-CHbDnN1qad6s,159632
4
+ qulab/version.py,sha256=GxSenfTTbLiVCmY5yEHjwuV-eKudBrOQ2NqIY4Qj64g,21
5
5
  qulab/monitor/__init__.py,sha256=nTHelnDpxRS_fl_B38TsN0njgq8eVTEz9IAnN3NbDlM,42
6
6
  qulab/monitor/__main__.py,sha256=w3yUcqq195LzSnXTkQcuC1RSFRhy4oQ_PEBmucXguME,97
7
7
  qulab/monitor/config.py,sha256=fQ5JcsMApKc1UwANEnIvbDQZl8uYW0tle92SaYtX9lI,744
@@ -14,14 +14,14 @@ qulab/monitor/qt_compat.py,sha256=OK71_JSO_iyXjRIKHANmaK4Lx4bILUzmXI-mwKg3QeI,78
14
14
  qulab/monitor/toolbar.py,sha256=WEag6cxAtEsOLL14XvM7pSE56EA3MO188_JuprNjdBs,7948
15
15
  qulab/scan/__init__.py,sha256=ZX4WsvqYxvJeHLgGSrtJoAnVU94gxY7EHKMxYooMERg,130
16
16
  qulab/scan/curd.py,sha256=thq_qfi3qng3Zx-1uhNG64IQhGCuum_LR4MOKnS8cDI,6896
17
- qulab/scan/expression.py,sha256=-aTYbjFQNI1mwOcoSBztqhKfGJpu_n4a1QnWro_xnTU,15694
17
+ qulab/scan/expression.py,sha256=JsJ00qK05QVDAgz-husRuov7hKg8nW75rsTwLG8RH7Q,15843
18
18
  qulab/scan/models.py,sha256=5Jpo25WGMWs0GtLzYLsWO61G3-FFYx5BHhBr2b6rOTE,17681
19
- qulab/scan/optimize.py,sha256=vErjRTCtn2MwMF5Xyhs1P4gHF2IFHv_EqxsUvH_4y7k,2287
19
+ qulab/scan/optimize.py,sha256=jYceGazEabuwYqmZE8P6Nnq_KsLyUP0p-p88VbbJLhM,2559
20
20
  qulab/scan/query.py,sha256=-5uHMhXSyGovK1oy_uUbGVEbRFzaMBkP78ZMNfI3jD0,11809
21
21
  qulab/scan/record.py,sha256=-FL9JMgfhvkT0q7dhJJXbjXOrOkTIk2J9oPmxP6psuA,21070
22
- qulab/scan/scan.py,sha256=KRCoq0ezqwIQlOifUAk9hUR-G-ryywUwEwP__rLMdPo,36499
23
- qulab/scan/server.py,sha256=6sWOx6xScz0CDMEexk9KYJ5nugneL9F45yeYQNIT7qM,14184
24
- qulab/scan/space.py,sha256=jDmFY2FcYe-Qcp16YBhAEdTKibOAsHQUnpDrpcPhvzg,5279
22
+ qulab/scan/scan.py,sha256=GXjx5gDT2L7S2H_opdFl9fEEJNsHi2RlwJpcbAY4aKg,37837
23
+ qulab/scan/server.py,sha256=ZT-J447xuLSpmbTNm5dNIz8_CXKOow66_bjkFNGh_vI,14274
24
+ qulab/scan/space.py,sha256=tmTMrLzUwm-NiXDQyJsr--D6Gj8GbF9XQx--o1QpQzE,6092
25
25
  qulab/scan/utils.py,sha256=Pg_tCf3SUKTiPSBqb6Enkgx4bAyQJAkDGe9uYys1xVU,3613
26
26
  qulab/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  qulab/storage/__main__.py,sha256=3emxxRry8BB0m8hUZvJ_oBqkPy7ksV7flHB_KEDXZuI,1692
@@ -78,9 +78,9 @@ qulab/visualization/plot_layout.py,sha256=clNw9QjE_kVNpIIx2Ob4YhAz2fucPGMuzkoIrO
78
78
  qulab/visualization/plot_seq.py,sha256=lphYF4VhkEdc_wWr1kFBwrx2yujkyFPFaJ3pjr61awI,2693
79
79
  qulab/visualization/qdat.py,sha256=ZeevBYWkzbww4xZnsjHhw7wRorJCBzbG0iEu-XQB4EA,5735
80
80
  qulab/visualization/widgets.py,sha256=6KkiTyQ8J-ei70LbPQZAK35wjktY47w2IveOa682ftA,3180
81
- QuLab-2.2.7.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
82
- QuLab-2.2.7.dist-info/METADATA,sha256=aP8Msk6d2Qyve2m5nVGNn8N3CniIqSdeqTbKS-8PqIo,3510
83
- QuLab-2.2.7.dist-info/WHEEL,sha256=aK27B_a3TQKBFhN_ATCfuFR4pBRqHlzwr7HpZ6iA79M,115
84
- QuLab-2.2.7.dist-info/entry_points.txt,sha256=ohBzutEnQimP_BZWiuXdSliu4QAYSHHcN0PZD8c7ZCY,46
85
- QuLab-2.2.7.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
86
- QuLab-2.2.7.dist-info/RECORD,,
81
+ QuLab-2.3.0.dist-info/LICENSE,sha256=PRzIKxZtpQcH7whTG6Egvzl1A0BvnSf30tmR2X2KrpA,1065
82
+ QuLab-2.3.0.dist-info/METADATA,sha256=FB6pFPfzfkG_vsOZXBQhdl-lGrsSGXsAPAjOiaT6YfI,3510
83
+ QuLab-2.3.0.dist-info/WHEEL,sha256=aK27B_a3TQKBFhN_ATCfuFR4pBRqHlzwr7HpZ6iA79M,115
84
+ QuLab-2.3.0.dist-info/entry_points.txt,sha256=ohBzutEnQimP_BZWiuXdSliu4QAYSHHcN0PZD8c7ZCY,46
85
+ QuLab-2.3.0.dist-info/top_level.txt,sha256=3T886LbAsbvjonu_TDdmgxKYUn939BVTRPxPl9r4cEg,6
86
+ QuLab-2.3.0.dist-info/RECORD,,
Binary file
qulab/scan/expression.py CHANGED
@@ -284,6 +284,9 @@ class Expression():
284
284
  return ObjectMethod(self, '__getitem__', other)
285
285
 
286
286
  def __getattr__(self, other):
287
+ if isinstance(other, str):
288
+ if other.startswith('_') or other in self.__dict__:
289
+ return super().__getattr__(other)
287
290
  if isinstance(other, Expression):
288
291
  other = other.eval(_default_env)
289
292
  return ObjectMethod(self, '__getattr__', other)
qulab/scan/optimize.py CHANGED
@@ -37,6 +37,12 @@ class NgOptimizer():
37
37
  self.config['method'])(self.instrum,
38
38
  budget=self.config['budget'])
39
39
 
40
+ def suggest(self, *suggested):
41
+ suggested = [
42
+ space.transform(x) for x, space in zip(suggested, self.dimensions)
43
+ ]
44
+ self.opt.suggest(*suggested)
45
+
40
46
  def ask(self):
41
47
  tmp = self.opt.ask()
42
48
  return [
@@ -47,15 +53,16 @@ class NgOptimizer():
47
53
  def tell(self, suggested: Sequence, value: Any):
48
54
  self._all_x.append(suggested)
49
55
  self._all_y.append(value)
50
- suggested = [
56
+ suggested = tuple([
51
57
  space.transform(x) for x, space in zip(suggested, self.dimensions)
52
- ]
53
- self.opt.suggest(*suggested)
54
- x = self.opt.ask()
58
+ ])
59
+ # self.opt.suggest(*suggested)
60
+ # x = self.opt.ask()
61
+ x = self.instrum.spawn_child(new_value=(suggested, {}))
55
62
  self.opt.tell(x, value)
56
63
 
57
64
  def get_result(self, history: bool = False) -> OptimizeResult:
58
- recommendation = self.opt.recommend()
65
+ recommendation = self.opt.provide_recommendation()
59
66
  ret = OptimizeResult({
60
67
  'x': [
61
68
  space.inverse_transform(x)
qulab/scan/scan.py CHANGED
@@ -226,10 +226,11 @@ class Scan():
226
226
  max_workers: int = 4,
227
227
  max_promise: int = 100,
228
228
  max_message: int = 1000,
229
+ config: dict | None = None,
229
230
  mixin=None):
230
231
  self.id = task_uuid()
231
232
  self.record = None
232
- self.config = None
233
+ self.config = {} if config is None else copy.deepcopy(config)
233
234
  self.description = {
234
235
  'app': app,
235
236
  'tags': tags,
@@ -250,7 +251,7 @@ class Scan():
250
251
  'filters': {},
251
252
  'total': {},
252
253
  'database': database,
253
- 'hiden': ['self', r'^__.*', r'.*__$'],
254
+ 'hiden': ['self', 'config', r'^__.*', r'.*__$'],
254
255
  'entry': {
255
256
  'system': get_system_info(),
256
257
  'env': {},
@@ -392,7 +393,10 @@ class Scan():
392
393
  if name in self.description['consts']:
393
394
  return self.description['consts'][name]
394
395
  else:
395
- return Symbol(name)
396
+ try:
397
+ return self._query_config(name)
398
+ except:
399
+ return Symbol(name)
396
400
 
397
401
  def _add_search_space(self, name: str, level: int, space):
398
402
  if level not in self.description['loops']:
@@ -402,6 +406,8 @@ class Scan():
402
406
  def add_depends(self, name: str, depends: list[str]):
403
407
  if isinstance(depends, str):
404
408
  depends = [depends]
409
+ if 'self' in depends:
410
+ depends.append('config')
405
411
  if name not in self.description['dependents']:
406
412
  self.description['dependents'][name] = set()
407
413
  self.description['dependents'][name].update(depends)
@@ -448,6 +454,9 @@ class Scan():
448
454
  pass
449
455
  self.description['consts'][name] = value
450
456
 
457
+ if '.' in name:
458
+ self.add_depends('config', [name])
459
+
451
460
  if ',' in name:
452
461
  for key in name.split(','):
453
462
  if not key.startswith('*'):
@@ -472,6 +481,8 @@ class Scan():
472
481
  elif isinstance(space, OptimizeSpace):
473
482
  space.name = name
474
483
  space.optimizer.dimensions[name] = space.space
484
+ if space.suggestions:
485
+ space.optimizer.suggestions[name] = space.suggestions
475
486
  self._add_search_space(name, space.optimizer.level, space)
476
487
  self.add_depends(space.optimizer.name, [name])
477
488
  else:
@@ -486,6 +497,8 @@ class Scan():
486
497
  self.add_depends(name, space.symbols())
487
498
  if setter:
488
499
  self.description['setters'][name] = setter
500
+ if '.' in name:
501
+ self.add_depends('config', [name])
489
502
 
490
503
  def trace(self,
491
504
  name: str,
@@ -535,6 +548,28 @@ class Scan():
535
548
  self.description['getters'][name] = getter
536
549
  return opt
537
550
 
551
+ def _synchronize_config(self):
552
+ for key, value in self.variables.items():
553
+ if '.' in key:
554
+ d = self.config
555
+ ks = key.split('.')
556
+ if not ks:
557
+ continue
558
+ for k in ks[:-1]:
559
+ if k in d:
560
+ d = d[k]
561
+ else:
562
+ d[k] = {}
563
+ d = d[k]
564
+ d[ks[-1]] = value
565
+ return self.config
566
+
567
+ def _query_config(self, key):
568
+ d = self.config
569
+ for k in key.split('.'):
570
+ d = d[k]
571
+ return d
572
+
538
573
  async def _update_progress(self):
539
574
  while True:
540
575
  task = await self._prm_queue.get()
@@ -549,17 +584,6 @@ class Scan():
549
584
 
550
585
  async def run(self):
551
586
  assymbly(self.description)
552
- if self.config:
553
- self.description['config'] = await create_config(
554
- self.config, self.description['database'], self._sock)
555
- if current_notebook() is None:
556
- await create_notebook('untitle', self.description['database'],
557
- self._sock)
558
- cell_id = await save_input_cells(current_notebook(),
559
- self.description['entry']['scripts'],
560
- self.description['database'],
561
- self._sock)
562
- self.description['entry']['scripts'] = cell_id
563
587
  if isinstance(
564
588
  self.description['database'],
565
589
  str) and self.description['database'].startswith("tcp://"):
@@ -567,15 +591,28 @@ class Scan():
567
591
  connect=self.description['database'],
568
592
  socket=self._sock) as socket:
569
593
  self._sock = socket
594
+ if self.config:
595
+ self.description['config'] = await create_config(
596
+ self.config, self.description['database'], self._sock)
597
+ if current_notebook() is None:
598
+ await create_notebook('untitle',
599
+ self.description['database'],
600
+ self._sock)
601
+ cell_id = await save_input_cells(
602
+ current_notebook(), self.description['entry']['scripts'],
603
+ self.description['database'], self._sock)
604
+ self.description['entry']['scripts'] = cell_id
570
605
  await self._run()
571
606
  else:
607
+ if self.config:
608
+ self.description['config'] = copy.deepcopy(self.config)
572
609
  await self._run()
573
610
 
574
611
  async def _run(self):
575
612
  send_msg_task = asyncio.create_task(self._send_msg())
576
613
  update_progress_task = asyncio.create_task(self._update_progress())
577
614
 
578
- self._variables = {'self': self}
615
+ self._variables = {'self': self, 'config': self.config}
579
616
 
580
617
  consts = {}
581
618
  for k, v in self.description['consts'].items():
@@ -671,8 +708,10 @@ class Scan():
671
708
  self.variables,
672
709
  self.description['loops'].get(self.current_level, []),
673
710
  self.description['order'].get(self.current_level, []),
674
- self.description['functions'], self.description['optimizers'],
675
- self.description['setters'], self.description['getters']):
711
+ self.description['functions']
712
+ | {'config': self._synchronize_config},
713
+ self.description['optimizers'], self.description['setters'],
714
+ self.description['getters']):
676
715
  self._current_level += 1
677
716
  if await self._filter(variables, self.current_level - 1):
678
717
  yield variables
qulab/scan/server.py CHANGED
@@ -160,8 +160,7 @@ async def handle(session: Session, request: Request, datapath: Path):
160
160
  else:
161
161
  iter_id = uuid.uuid3(namespace, str(time.time_ns())).bytes
162
162
  record = get_record(session, msg['record_id'], datapath)
163
- bufferlist = record.get(msg['key'],
164
- buffer_to_array=False)
163
+ bufferlist = record.get(msg['key'], buffer_to_array=False)
165
164
  if msg['slice']:
166
165
  bufferlist._slice = msg['slice']
167
166
  it = bufferlist.iter()
@@ -329,7 +328,11 @@ async def serv(port,
329
328
  while True:
330
329
  identity, msg = await sock.recv_multipart()
331
330
  received += len(msg)
332
- req = Request(sock, identity, msg)
331
+ try:
332
+ req = Request(sock, identity, msg)
333
+ except:
334
+ logger.exception('bad request')
335
+ continue
333
336
  asyncio.create_task(
334
337
  handle_with_timeout(session, req, datapath, timeout=60.0))
335
338
  if received > buffer_size or time.time(
qulab/scan/space.py CHANGED
@@ -1,3 +1,4 @@
1
+ import itertools
1
2
  from typing import Type
2
3
 
3
4
  import numpy as np
@@ -103,10 +104,14 @@ def geomspace(start, stop, num=50, endpoint=True):
103
104
 
104
105
  class OptimizeSpace():
105
106
 
106
- def __init__(self, optimizer: 'Optimizer', space):
107
+ def __init__(self, optimizer: 'Optimizer', space, suggestions=None):
107
108
  self.optimizer = optimizer
108
109
  self.space = space
109
110
  self.name = None
111
+ if suggestions is not None and not isinstance(
112
+ suggestions, (list, tuple, np.ndarray)):
113
+ suggestions = [suggestions]
114
+ self.suggestions = suggestions
110
115
 
111
116
  def __len__(self):
112
117
  return self.optimizer.maxiter
@@ -130,39 +135,58 @@ class Optimizer():
130
135
  self.level = level
131
136
  self.kwds = kwds
132
137
  self.minimize = minimize
138
+ self.suggestions = {}
133
139
 
134
140
  def create(self):
135
- return self.method(list(self.dimensions.values()), **self.kwds)
141
+ opt = self.method(list(self.dimensions.values()), **self.kwds)
142
+
143
+ def rvs(space):
144
+ while True:
145
+ yield space.rvs()[0]
146
+
147
+ if self.suggestions:
148
+ for suggestion in zip(*[
149
+ self.suggestions.get(key, rvs(space))
150
+ for key, space in self.dimensions.items()
151
+ ]):
152
+ opt.suggest(*suggestion)
153
+ return opt
136
154
 
137
155
  def Categorical(self,
138
156
  categories,
139
157
  prior=None,
140
158
  transform=None,
141
- name=None) -> OptimizeSpace:
159
+ name=None,
160
+ suggestions=None) -> OptimizeSpace:
142
161
  return OptimizeSpace(self,
143
- Categorical(categories, prior, transform, name))
162
+ Categorical(categories, prior, transform, name),
163
+ suggestions)
144
164
 
145
165
  def Integer(self,
146
166
  low,
147
167
  high,
148
168
  prior="uniform",
149
169
  base=10,
150
- transform=None,
170
+ transform="normalize",
151
171
  name=None,
152
- dtype=np.int64) -> OptimizeSpace:
172
+ dtype=np.int64,
173
+ suggestions=None) -> OptimizeSpace:
153
174
  return OptimizeSpace(
154
- self, Integer(low, high, prior, base, transform, name, dtype))
175
+ self, Integer(low, high, prior, base, transform, name, dtype),
176
+ suggestions)
155
177
 
156
178
  def Real(self,
157
179
  low,
158
180
  high,
159
181
  prior="uniform",
160
182
  base=10,
161
- transform=None,
183
+ transform="normalize",
162
184
  name=None,
163
- dtype=float) -> OptimizeSpace:
185
+ dtype=float,
186
+ suggestions=None) -> OptimizeSpace:
164
187
  return OptimizeSpace(
165
- self, Real(low, high, prior, base, transform, name, dtype))
188
+ self, Real(low, high, prior, base, transform, name, dtype),
189
+ suggestions)
166
190
 
167
191
  def __getstate__(self) -> dict:
168
192
  state = self.__dict__.copy()
qulab/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "2.2.7"
1
+ __version__ = "2.3.0"
File without changes
File without changes