q8s 0.8.0__tar.gz → 0.8.0.dev2__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.
Files changed (41) hide show
  1. {q8s-0.8.0 → q8s-0.8.0.dev2}/PKG-INFO +1 -1
  2. {q8s-0.8.0 → q8s-0.8.0.dev2}/pyproject.toml +1 -1
  3. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/cli.py +0 -16
  4. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/plugins/cpu_job.py +2 -3
  5. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/plugins/cuda_job.py +2 -3
  6. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/project.py +6 -46
  7. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/workload.py +15 -15
  8. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s.egg-info/PKG-INFO +1 -1
  9. {q8s-0.8.0 → q8s-0.8.0.dev2}/LICENSE +0 -0
  10. {q8s-0.8.0 → q8s-0.8.0.dev2}/README.md +0 -0
  11. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/__init__.py +0 -0
  12. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/__main__.py +0 -0
  13. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/constants.py +0 -0
  14. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/deps/__init__.py +0 -0
  15. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/deps/code_analyzer.py +0 -0
  16. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/deps/parser.py +0 -0
  17. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/enums.py +0 -0
  18. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/execution.py +0 -0
  19. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/install.py +0 -0
  20. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/kernel.py +0 -0
  21. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/matplotlib/backend.py +0 -0
  22. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/multifiles.py +0 -0
  23. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/plugins/__init__.py +0 -0
  24. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/plugins/job_template_spec.py +0 -0
  25. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s/utils.py +0 -0
  26. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s.egg-info/SOURCES.txt +0 -0
  27. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s.egg-info/dependency_links.txt +0 -0
  28. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s.egg-info/entry_points.txt +0 -0
  29. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s.egg-info/requires.txt +0 -0
  30. {q8s-0.8.0 → q8s-0.8.0.dev2}/q8s.egg-info/top_level.txt +0 -0
  31. {q8s-0.8.0 → q8s-0.8.0.dev2}/setup.cfg +0 -0
  32. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/__init__.py +0 -0
  33. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/fixtures/cache/app.py +0 -0
  34. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/fixtures/simple/qiskit.py +0 -0
  35. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_backend.py +0 -0
  36. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_deps.py +0 -0
  37. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_job_template_spec.py +0 -0
  38. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_kernel.py +0 -0
  39. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_multifiles.py +0 -0
  40. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_project.py +0 -0
  41. {q8s-0.8.0 → q8s-0.8.0.dev2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: q8s
3
- Version: 0.8.0
3
+ Version: 0.8.0.dev2
4
4
  Summary: Kernel extension for executing quantum programs in simulators on q8s clusters
5
5
  Author-email: Vlad Stirbu <vstirbu@gmail.com>
6
6
  License: Apache License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "q8s"
3
- version = "0.8.0"
3
+ version = "0.8.0.dev2"
4
4
  description = "Kernel extension for executing quantum programs in simulators on q8s clusters"
5
5
  authors = [{ name = "Vlad Stirbu", email = "vstirbu@gmail.com" }]
6
6
  readme = "README.md"
@@ -16,22 +16,6 @@ from q8s.workload import Workload
16
16
  app = typer.Typer()
17
17
 
18
18
 
19
- @app.command()
20
- def init(
21
- images: Annotated[
22
- bool, typer.Option(help="Initialize images cache if build in a CI pipeline")
23
- ] = False,
24
- ):
25
- project = Project()
26
- project.init_cache()
27
-
28
- if images:
29
- project.images_from_ci()
30
- project.update_images_cache()
31
-
32
- print(f"Project {project.name} initialized")
33
-
34
-
35
19
  @app.command()
36
20
  def build(
37
21
  init: Annotated[bool, typer.Option(help="Initialize project")] = False,
@@ -25,14 +25,13 @@ class CPUJobTemplatePlugin:
25
25
 
26
26
  volume_name = f"app-volume-{name}"
27
27
 
28
- env_var = list(env)
29
28
  if workload.is_src_project:
30
- env_var.append(client.V1EnvVar(name="PYTHONPATH", value=f"{WORKSPACE}/src"))
29
+ env.append(client.V1EnvVar(name="PYTHONPATH", value=f"{WORKSPACE}/src"))
31
30
 
32
31
  container = client.V1Container(
33
32
  name="quantum-routine",
34
33
  image=container_image,
35
- env=env_var,
34
+ env=env,
36
35
  command=["python"],
37
36
  args=(
38
37
  ["-m", workload.entry_module] + workload.args
@@ -31,14 +31,13 @@ class CUDAJobTemplatePlugin:
31
31
 
32
32
  volume_name = f"app-volume-{name}"
33
33
 
34
- env_var = list(env)
35
34
  if workload.is_src_project:
36
- env_var.append(client.V1EnvVar(name="PYTHONPATH", value=f"{WORKSPACE}/src"))
35
+ env.append(client.V1EnvVar(name="PYTHONPATH", value=f"{WORKSPACE}/src"))
37
36
 
38
37
  container = client.V1Container(
39
38
  name="quantum-routine",
40
39
  image=container_image,
41
- env=env_var,
40
+ env=env,
42
41
  command=["python"],
43
42
  args=(
44
43
  ["-m", workload.entry_module] + workload.args
@@ -1,4 +1,3 @@
1
- import configparser
2
1
  from dataclasses import dataclass
3
2
  from datetime import datetime
4
3
  from pathlib import Path
@@ -44,7 +43,7 @@ def _read_stream_lines(stream, progress, silent, is_error: bool = False):
44
43
  """
45
44
  while True:
46
45
  line = stream.readline()
47
- if line == "":
46
+ if line == '':
48
47
  break
49
48
  if not silent:
50
49
  if is_error:
@@ -97,7 +96,6 @@ class Q8SDocker:
97
96
  username: str
98
97
  registry: Optional[str]
99
98
 
100
-
101
99
  @dataclass
102
100
  class Q8SProject:
103
101
  name: str
@@ -114,11 +112,9 @@ class CacheNotBuiltException(Exception):
114
112
  class ProjectNotFoundException(Exception):
115
113
  pass
116
114
 
117
-
118
115
  class ProjectInvalidConfigurationException(Exception):
119
116
  pass
120
117
 
121
-
122
118
  class Project:
123
119
  name: str
124
120
  __path: str
@@ -219,15 +215,14 @@ class Project:
219
215
  stderr=STDOUT,
220
216
  bufsize=1,
221
217
  universal_newlines=True,
222
- encoding="utf-8", # force UTF-8 decoding
223
- errors="replace", # avoid crashing on bad bytes
218
+ encoding="utf-8", # force UTF-8 decoding
219
+ errors="replace", # avoid crashing on bad bytes
224
220
  )
225
221
 
226
222
  if sys.platform == "win32":
227
223
  # Windows-safe: read line by line instead of using selectors
228
224
  _handle_subprocess_output(build_process, progress, silent)
229
225
  else:
230
-
231
226
  def handle_output(stream, mask):
232
227
  # Because the process' output is line buffered, there's only ever one
233
228
  # line to read when this function is called
@@ -275,8 +270,8 @@ class Project:
275
270
  stderr=STDOUT,
276
271
  bufsize=1,
277
272
  universal_newlines=True,
278
- encoding="utf-8", # force UTF-8 decoding
279
- errors="replace", # avoid crashing on bad bytes
273
+ encoding="utf-8", # force UTF-8 decoding
274
+ errors="replace", # avoid crashing on bad bytes
280
275
  )
281
276
 
282
277
  if sys.platform == "win32":
@@ -284,7 +279,6 @@ class Project:
284
279
  _handle_subprocess_output(push_process, progress, silent)
285
280
 
286
281
  else:
287
-
288
282
  def handle_output(stream, mask):
289
283
  # Because the process' output is line buffered, there's only ever one
290
284
  # line to read when this function is called
@@ -312,19 +306,11 @@ class Project:
312
306
  else:
313
307
  progress.advance(task)
314
308
 
315
- def images_from_ci(self):
316
- """
317
- Images are build in a CI pipeline.
318
- """
319
- for target in self.configuration.targets.keys():
320
- self.__images[target] = self.__image_name(target)
321
-
322
309
  def update_images_cache(self):
323
310
  """
324
311
  Update the images cache
325
312
  """
326
313
  with open(join(self.__path, ".q8s_cache", "images"), "w") as f:
327
- print(f"# This file is autogenerated by q8sctl\n", file=f)
328
314
  yaml.dump(self.__images, f)
329
315
 
330
316
  def clear_cache(self):
@@ -339,7 +325,7 @@ class Project:
339
325
 
340
326
  def __image_name(self, target: str):
341
327
  registry = self.configuration.docker.registry
342
- username = self.__docker_login().lower()
328
+ username = self.__docker_login()
343
329
 
344
330
  # Build image name based on available information
345
331
  if registry and username:
@@ -402,15 +388,6 @@ class Project:
402
388
  file=f,
403
389
  )
404
390
  print(f"LABEL org.opencontainers.image.title={self.name}", file=f)
405
-
406
- url = self.__get_project_url()
407
-
408
- if url is not None:
409
- print(
410
- f"LABEL org.opencontainers.image.source={url.strip()}",
411
- file=f,
412
- )
413
-
414
391
  print("", file=f)
415
392
 
416
393
  print(f"WORKDIR {WORKSPACE}", file=f)
@@ -422,20 +399,3 @@ class Project:
422
399
  raise Exception(f"Target {target} not found")
423
400
 
424
401
  return getattr(self.configuration.targets, target)
425
-
426
- def __get_project_url(self) -> Optional[str]:
427
- """
428
- Get the project URL from setup.cfg if available
429
- """
430
- cfg_path = Path(self.__path) / "setup.cfg"
431
- if not cfg_path.exists():
432
- return None
433
-
434
- config = configparser.ConfigParser()
435
- config.read(cfg_path)
436
-
437
- url = config.get("metadata", "url", fallback=None)
438
- if url is not None:
439
- return url.strip()
440
-
441
- return None
@@ -7,34 +7,34 @@ from .multifiles import collect_imported_files
7
7
 
8
8
  class Workload:
9
9
  """
10
- Represents a multifile workload consisting of an entry script and its imported files
10
+ Represents a mutifile workload consisting of an entry script and its imported files
11
11
  """
12
12
 
13
- def __init__(self, entry_script: Path | str = None, code: str = None):
14
- self.__pyproject_root: Path | None = None
15
- self.__args: list[str] = []
13
+ __pyproject_root: Path | None = None
14
+ __args: list[str] = []
16
15
 
16
+ def __init__(self, entry_script: Path | str = None, code: str = None):
17
17
  if entry_script is not None:
18
18
 
19
- self.__entry_script = Path(os.path.abspath(entry_script))
20
-
21
- if self.__detect_and_set_src_layout():
19
+ if self.__is_src_layout():
20
+ self.__entry_script = Path(os.path.abspath(entry_script))
22
21
  self.__base_path = self.__pyproject_root
23
22
 
24
23
  self.__files = collect_imported_files(
25
24
  self.__entry_script, is_project=True
26
25
  )
26
+
27
27
  else:
28
+ self.__entry_script = Path(os.path.abspath(entry_script))
28
29
  self.__base_path = self.__entry_script.parent
29
30
 
30
31
  self.__files = collect_imported_files(
31
32
  self.__entry_script, is_project=False
32
33
  )
33
34
 
34
- self.__data = {}
35
- for f in self.__files:
36
- with open(f, "r", encoding="utf-8") as file:
37
- self.__data[self.__path_mapping(f)] = file.read()
35
+ self.__data = {
36
+ self.__path_mapping(f): open(f, "r").read() for f in self.__files
37
+ }
38
38
 
39
39
  elif code is not None:
40
40
  self.__entry_script = Path(os.path.abspath("main.py"))
@@ -86,7 +86,7 @@ class Workload:
86
86
  """
87
87
  Entry script module name
88
88
  """
89
- return self.entry_script.replace(os.path.sep, ".")[:-3] # strip .py
89
+ return self.entry_script.replace("/", ".")[:-3] # strip .py
90
90
 
91
91
  @property
92
92
  def data(self) -> dict[str, str]:
@@ -127,7 +127,7 @@ class Workload:
127
127
  """
128
128
  return self.__relative_path(file).replace("/", "__")
129
129
 
130
- def __find_pyproject_root(self) -> Path | None:
130
+ def __pyproject_root(self, start: Path | None = None) -> Path | None:
131
131
  """
132
132
  Find the project root by looking for setup.cfg or pyproject.toml
133
133
  """
@@ -140,11 +140,11 @@ class Workload:
140
140
 
141
141
  return None
142
142
 
143
- def __detect_and_set_src_layout(self) -> bool:
143
+ def __is_src_layout(self) -> bool:
144
144
  """
145
145
  Determine if the project uses a src/ layout
146
146
  """
147
- root = self.__find_pyproject_root()
147
+ root = self.__pyproject_root()
148
148
 
149
149
  if root is None:
150
150
  return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: q8s
3
- Version: 0.8.0
3
+ Version: 0.8.0.dev2
4
4
  Summary: Kernel extension for executing quantum programs in simulators on q8s clusters
5
5
  Author-email: Vlad Stirbu <vstirbu@gmail.com>
6
6
  License: Apache License
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
File without changes
File without changes
File without changes
File without changes