experimaestro 1.7.0rc0__tar.gz → 1.7.0rc2__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.

Potentially problematic release.


This version of experimaestro might be problematic. Click here for more details.

Files changed (158) hide show
  1. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/PKG-INFO +2 -1
  2. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/pyproject.toml +6 -2
  3. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/experiments/cli.py +7 -3
  4. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launcherfinder/registry.py +12 -1
  5. experimaestro-1.7.0rc2/src/experimaestro/notifications.proto +17 -0
  6. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/notifications.py +3 -1
  7. experimaestro-1.7.0rc2/src/experimaestro/notifications_pb2.py +39 -0
  8. experimaestro-1.7.0rc2/src/experimaestro/streaming_state.py +124 -0
  9. experimaestro-1.7.0rc2/src/experimaestro/tests/state_streamer.proto +9 -0
  10. experimaestro-1.7.0rc2/src/experimaestro/tests/state_streamer_pb2.py +38 -0
  11. experimaestro-1.7.0rc2/src/experimaestro/tests/test_state_streamer.py +18 -0
  12. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/LICENSE +0 -0
  13. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/README.md +0 -0
  14. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/__init__.py +0 -0
  15. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/__main__.py +0 -0
  16. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/annotations.py +0 -0
  17. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/checkers.py +0 -0
  18. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/cli/__init__.py +0 -0
  19. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/cli/filter.py +0 -0
  20. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/cli/jobs.py +0 -0
  21. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/click.py +0 -0
  22. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/commandline.py +0 -0
  23. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/compat.py +0 -0
  24. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/connectors/__init__.py +0 -0
  25. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/connectors/local.py +0 -0
  26. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/connectors/ssh.py +0 -0
  27. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/__init__.py +0 -0
  28. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/arguments.py +0 -0
  29. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/context.py +0 -0
  30. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/objects.py +0 -0
  31. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/objects.pyi +0 -0
  32. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/serialization.py +0 -0
  33. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/serializers.py +0 -0
  34. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/types.py +0 -0
  35. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/core/utils.py +0 -0
  36. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/exceptions.py +0 -0
  37. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/experiments/__init__.py +0 -0
  38. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/experiments/configuration.py +0 -0
  39. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/generators.py +0 -0
  40. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/huggingface.py +0 -0
  41. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/ipc.py +0 -0
  42. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launcherfinder/__init__.py +0 -0
  43. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launcherfinder/base.py +0 -0
  44. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launcherfinder/parser.py +0 -0
  45. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launcherfinder/specs.py +0 -0
  46. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launchers/__init__.py +0 -0
  47. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launchers/direct.py +0 -0
  48. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launchers/oar.py +0 -0
  49. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launchers/slurm/__init__.py +0 -0
  50. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/launchers/slurm/base.py +0 -0
  51. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/locking.py +0 -0
  52. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/mkdocs/__init__.py +0 -0
  53. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/mkdocs/annotations.py +0 -0
  54. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/mkdocs/base.py +0 -0
  55. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/mkdocs/metaloader.py +0 -0
  56. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/mkdocs/style.css +0 -0
  57. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/mypy.py +0 -0
  58. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/py.typed +0 -0
  59. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/rpyc.py +0 -0
  60. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/run.py +0 -0
  61. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scheduler/__init__.py +0 -0
  62. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scheduler/base.py +0 -0
  63. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scheduler/dependencies.py +0 -0
  64. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scheduler/dynamic_outputs.py +0 -0
  65. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scheduler/services.py +0 -0
  66. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scheduler/workspace.py +0 -0
  67. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/scriptbuilder.py +0 -0
  68. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/__init__.py +0 -0
  69. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/016b4a6cdced82ab3aa1.ttf +0 -0
  70. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
  71. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/1815e00441357e01619e.ttf +0 -0
  72. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
  73. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/2463b90d9a316e4e5294.woff2 +0 -0
  74. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/2582b0e4bcf85eceead0.ttf +0 -0
  75. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
  76. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
  77. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
  78. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
  79. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/50701fbb8177c2dde530.ttf +0 -0
  80. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
  81. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
  82. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/878f31251d960bd6266f.woff2 +0 -0
  83. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/89999bdf5d835c012025.woff2 +0 -0
  84. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/914997e1bdfc990d0897.ttf +0 -0
  85. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/b041b1fa4fe241b23445.woff2 +0 -0
  86. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/b6879d41b0852f01ed5b.woff2 +0 -0
  87. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/c210719e60948b211a12.woff2 +0 -0
  88. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
  89. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/d75e3fd1eb12e9bd6655.ttf +0 -0
  90. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
  91. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/favicon.ico +0 -0
  92. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/index.css +0 -0
  93. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/index.css.map +0 -0
  94. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/index.html +0 -0
  95. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/index.js +0 -0
  96. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/index.js.map +0 -0
  97. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/login.html +0 -0
  98. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/server/data/manifest.json +0 -0
  99. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/settings.py +0 -0
  100. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/sphinx/__init__.py +0 -0
  101. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/sphinx/static/experimaestro.css +0 -0
  102. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/taskglobals.py +0 -0
  103. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/__init__.py +0 -0
  104. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/conftest.py +0 -0
  105. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/connectors/bin/executable.py +0 -0
  106. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/connectors/test_local.py +0 -0
  107. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/connectors/utils.py +0 -0
  108. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/definitions_types.py +0 -0
  109. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/__init__.py +0 -0
  110. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/bin/sacct +0 -0
  111. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/bin/sbatch +0 -0
  112. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/bin/test.py +0 -0
  113. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/common.py +0 -0
  114. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/config_slurm/__init__.py +0 -0
  115. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/config_slurm/launchers.py +0 -0
  116. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/test_local.py +0 -0
  117. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/launchers/test_slurm.py +0 -0
  118. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/restart.py +0 -0
  119. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/restart_main.py +0 -0
  120. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/scripts/notifyandwait.py +0 -0
  121. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/scripts/waitforfile.py +0 -0
  122. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/task_tokens.py +0 -0
  123. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/tasks/__init__.py +0 -0
  124. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/tasks/all.py +0 -0
  125. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/tasks/foreign.py +0 -0
  126. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_checkers.py +0 -0
  127. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_dependencies.py +0 -0
  128. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_findlauncher.py +0 -0
  129. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_forward.py +0 -0
  130. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_identifier.py +0 -0
  131. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_instance.py +0 -0
  132. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_objects.py +0 -0
  133. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_outputs.py +0 -0
  134. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_param.py +0 -0
  135. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_progress.py +0 -0
  136. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_serializers.py +0 -0
  137. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_snippets.py +0 -0
  138. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_ssh.py +0 -0
  139. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_tags.py +0 -0
  140. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_tasks.py +0 -0
  141. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_tokens.py +0 -0
  142. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_types.py +0 -0
  143. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/test_validation.py +0 -0
  144. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/token_reschedule.py +0 -0
  145. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tests/utils.py +0 -0
  146. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tokens.py +0 -0
  147. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tools/__init__.py +0 -0
  148. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tools/diff.py +0 -0
  149. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tools/documentation.py +0 -0
  150. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/tools/jobs.py +0 -0
  151. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/typingutils.py +0 -0
  152. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/utils/__init__.py +0 -0
  153. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/utils/asyncio.py +0 -0
  154. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/utils/jobs.py +0 -0
  155. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/utils/jupyter.py +0 -0
  156. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/utils/resources.py +0 -0
  157. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/utils/settings.py +0 -0
  158. {experimaestro-1.7.0rc0 → experimaestro-1.7.0rc2}/src/experimaestro/xpmutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: experimaestro
3
- Version: 1.7.0rc0
3
+ Version: 1.7.0rc2
4
4
  Summary: "Experimaestro is a computer science experiment manager"
5
5
  License: GPL-3
6
6
  Keywords: experiment manager
@@ -34,6 +34,7 @@ Requires-Dist: huggingface-hub (>0.17)
34
34
  Requires-Dist: humanfriendly (>=10,<11)
35
35
  Requires-Dist: marshmallow (>=3.20,<4.0)
36
36
  Requires-Dist: omegaconf (>=2.3,<3.0)
37
+ Requires-Dist: protobuf (>5)
37
38
  Requires-Dist: psutil (>=7)
38
39
  Requires-Dist: pyparsing (>=3.1,<4.0)
39
40
  Requires-Dist: pytools (>=2023.1.1,<2024.0.0)
@@ -20,7 +20,7 @@ include = [
20
20
  "src/experimaestro/mkdocs/style.css",
21
21
  { path="src/experimaestro/server/data/*", format=['sdist', 'wheel']}
22
22
  ]
23
- version = "1.7.0-rc0"
23
+ version = "1.7.0-rc2"
24
24
  repository = "https://github.com/experimaestro/experimaestro-python"
25
25
  documentation = "https://experimaestro-python.readthedocs.io/"
26
26
 
@@ -29,7 +29,10 @@ enable = false
29
29
  vcs = "git"
30
30
  style = "semver"
31
31
  dirty = true
32
- format-jinja = """{{ serialize_semver(base, ["rc" + revision|string]) }}"""
32
+ format-jinja = """{%- set pre = [] -%}{%- set metadata = [] -%}
33
+ {%- if revision is not none -%}{{ pre.append("rc" + revision|string) or "" }}{%- endif -%}
34
+ {%- if distance > 0 -%}{{ metadata.append(distance|string) or "" }}{%- endif -%}
35
+ {{ serialize_semver(base, pre, metadata)}}"""
33
36
  [build-system]
34
37
  requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.0.0,<2.0.0"]
35
38
  build-backend = "poetry_dynamic_versioning.backend"
@@ -61,6 +64,7 @@ watchdog = "^2"
61
64
  marshmallow = "^3.20"
62
65
  decorator = "^5"
63
66
  rpyc = ">=5,<7"
67
+ protobuf = ">5"
64
68
 
65
69
  [tool.poetry.group.ssh]
66
70
  optional = true
@@ -194,7 +194,11 @@ def experiments_cli( # noqa: C901
194
194
  xp_file = Path(xp_file)
195
195
  if not python_path:
196
196
  python_path.append(xp_file.parent)
197
- logging.info("Using python path: %s", ", ".join(str(s) for s in python_path))
197
+ logging.info(
198
+ "Using python path: %s", ", ".join(str(s) for s in python_path)
199
+ )
200
+ else:
201
+ xp_file = Path(xp_file)
198
202
 
199
203
  assert (
200
204
  module_name or xp_file
@@ -269,11 +273,11 @@ def experiments_cli( # noqa: C901
269
273
 
270
274
  # Define the workspace
271
275
  ws_env = find_workspace(workdir=workdir, workspace=workspace)
272
-
276
+
273
277
  workdir = ws_env.path
274
278
 
275
279
  logging.info("Using working directory %s", str(workdir.resolve()))
276
-
280
+
277
281
  # --- Runs the experiment
278
282
  with experiment(
279
283
  ws_env, configuration.id, host=host, port=port, run_mode=run_mode
@@ -1,5 +1,6 @@
1
1
  # Configuration registers
2
2
 
3
+ from contextlib import contextmanager
3
4
  from typing import ClassVar, Dict, Optional, Set, Type, Union
4
5
 
5
6
  from pathlib import Path
@@ -36,6 +37,16 @@ def load_yaml(schema, path: Path):
36
37
  )
37
38
 
38
39
 
40
+ @contextmanager
41
+ def ensure_enter(fp):
42
+ """Behaves as a resource, whether it is one or not"""
43
+ if hasattr(fp, "__enter__"):
44
+ with fp as _fp:
45
+ yield _fp
46
+ else:
47
+ yield fp
48
+
49
+
39
50
  class LauncherRegistry:
40
51
  INSTANCES: ClassVar[Dict[Path, "LauncherRegistry"]] = {}
41
52
  CURRENT_CONFIG_DIR: ClassVar[Optional[Path]] = None
@@ -78,7 +89,7 @@ class LauncherRegistry:
78
89
 
79
90
  from importlib import util
80
91
 
81
- with launchers_py.__fspath__() as fp:
92
+ with ensure_enter(launchers_py.__fspath__()) as fp:
82
93
  spec = util.spec_from_file_location("xpm_launchers_conf", fp)
83
94
  module = util.module_from_spec(spec)
84
95
  spec.loader.exec_module(module)
@@ -0,0 +1,17 @@
1
+ syntax = "proto3";
2
+ import "google/protobuf/any.proto";
3
+
4
+
5
+ message Envelope {
6
+ google.protobuf.Any payload = 1;
7
+ }
8
+
9
+ message LevelInformation {
10
+ int32 level = 1;
11
+
12
+ optional string desc = 2; // Optional in proto3 is handled by default unless you want to use 'optional'
13
+ float progress = 3;
14
+
15
+ float previous_progress = 4;
16
+ string previous_desc = 5;
17
+ }
@@ -12,15 +12,16 @@ from tqdm.auto import tqdm as std_tqdm
12
12
 
13
13
  from .utils import logger
14
14
  from experimaestro.taskglobals import Env as TaskEnv
15
+ from experimaestro.notifications_pb2 import LevelInformation
15
16
 
16
17
  # --- Progress and other notifications
17
18
 
18
19
  T = TypeVar("T")
19
20
 
20
-
21
21
  @dataclass
22
22
  class LevelInformation:
23
23
  level: int
24
+
24
25
  desc: Optional[str]
25
26
  progress: float
26
27
 
@@ -213,6 +214,7 @@ class Reporter(threading.Thread):
213
214
 
214
215
  self.cv.notify_all()
215
216
 
217
+ #: The reporter instance
216
218
  INSTANCE: ClassVar[Optional["Reporter"]] = None
217
219
 
218
220
  @staticmethod
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: src/experimaestro/notifications.proto
5
+ # Protobuf Python Version: 5.29.3
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 5,
15
+ 29,
16
+ 3,
17
+ '',
18
+ 'src/experimaestro/notifications.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%src/experimaestro/notifications.proto\x1a\x19google/protobuf/any.proto\"1\n\x08\x45nvelope\x12%\n\x07payload\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\"\x81\x01\n\x10LevelInformation\x12\r\n\x05level\x18\x01 \x01(\x05\x12\x11\n\x04\x64\x65sc\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x10\n\x08progress\x18\x03 \x01(\x02\x12\x19\n\x11previous_progress\x18\x04 \x01(\x02\x12\x15\n\rprevious_desc\x18\x05 \x01(\tB\x07\n\x05_descb\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'src.experimaestro.notifications_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ DESCRIPTOR._loaded_options = None
35
+ _globals['_ENVELOPE']._serialized_start=68
36
+ _globals['_ENVELOPE']._serialized_end=117
37
+ _globals['_LEVELINFORMATION']._serialized_start=120
38
+ _globals['_LEVELINFORMATION']._serialized_end=249
39
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,124 @@
1
+ """Handles streaming states
2
+
3
+ Allows to track a global state via a file
4
+
5
+ - partial states can be output
6
+ - every K bytes, a global state is output
7
+
8
+ The reader can then recover quickly by seeking the last global state output.
9
+
10
+ """
11
+
12
+ import struct
13
+ from io import BufferedWriter, BufferedReader, SEEK_END
14
+ from typing import Type, Generator, Union
15
+
16
+ from google.protobuf.message import Message
17
+
18
+ # Constants
19
+ PARTIAL_UPDATE = 1
20
+ GLOBAL_STATE = 2
21
+ HEADER_FORMAT = ">BI" # 1-byte type tag, 4-byte message size
22
+ HEADER_SIZE = struct.calcsize(HEADER_FORMAT)
23
+ MAGIC_NUMBER = b"\xab\xcd\xef\x00"
24
+ MAGIC_SIZE = len(MAGIC_NUMBER)
25
+
26
+
27
+ class StreamingStateWriter:
28
+ def __init__(
29
+ self,
30
+ file: BufferedWriter,
31
+ partial_cls: Type[Message],
32
+ snapshot_cls: Type[Message],
33
+ chunk_size: int = 8192,
34
+ ):
35
+ self.file = file
36
+ self.partial_cls = partial_cls
37
+ self.snapshot_cls = snapshot_cls
38
+ self.chunk_size = chunk_size
39
+ self.bytes_since_last_snapshot = 0
40
+
41
+ def write_partial(self, message: Message):
42
+ assert isinstance(message, self.partial_cls)
43
+ self._write_message(PARTIAL_UPDATE, message)
44
+
45
+ def write_snapshot_if_needed(self, message: Message):
46
+ assert isinstance(message, self.snapshot_cls)
47
+ if self.bytes_since_last_snapshot >= self.chunk_size:
48
+ self._write_message(GLOBAL_STATE, message, with_magic=True)
49
+ self.bytes_since_last_snapshot = 0
50
+
51
+ def _write_message(self, type_tag: int, message: Message, with_magic: bool = False):
52
+ data = message.SerializeToString()
53
+ header = struct.pack(HEADER_FORMAT, type_tag, len(data))
54
+ if with_magic:
55
+ self.file.write(MAGIC_NUMBER)
56
+ self.bytes_since_last_snapshot += MAGIC_SIZE
57
+ self.file.write(header + data)
58
+ self.file.flush()
59
+ self.bytes_since_last_snapshot += HEADER_SIZE + len(data)
60
+
61
+
62
+ class StreamingStateReader:
63
+ def __init__(
64
+ self,
65
+ file: BufferedReader,
66
+ partial_cls: Type[Message],
67
+ snapshot_cls: Type[Message],
68
+ ):
69
+ self.file = file
70
+ self.partial_cls = partial_cls
71
+ self.snapshot_cls = snapshot_cls
72
+
73
+ def __iter__(self) -> Generator[Union[Message, Message], None, None]:
74
+ while True:
75
+ peek = self.file.peek(MAGIC_SIZE)[:MAGIC_SIZE]
76
+ if peek == MAGIC_NUMBER:
77
+ self.file.read(MAGIC_SIZE)
78
+
79
+ header = self.file.read(HEADER_SIZE)
80
+ if len(header) < HEADER_SIZE:
81
+ break
82
+
83
+ type_tag, length = struct.unpack(HEADER_FORMAT, header)
84
+ payload = self.file.read(length)
85
+
86
+ if type_tag == PARTIAL_UPDATE:
87
+ msg = self.partial_cls()
88
+ elif type_tag == GLOBAL_STATE:
89
+ msg = self.snapshot_cls()
90
+ else:
91
+ raise ValueError(f"Unknown type tag: {type_tag}")
92
+
93
+ msg.ParseFromString(payload)
94
+ yield msg
95
+
96
+ def seek_last_snapshot(self) -> Union[Message, None]:
97
+ self.file.seek(0, SEEK_END)
98
+ file_size = self.file.tell()
99
+
100
+ window = 4096
101
+ pos = file_size
102
+
103
+ while pos > 0:
104
+ read_size = min(window, pos)
105
+ pos -= read_size
106
+ self.file.seek(pos)
107
+ data = self.file.read(read_size)
108
+
109
+ idx = data.rfind(MAGIC_NUMBER)
110
+ if idx != -1:
111
+ snapshot_pos = pos + idx + MAGIC_SIZE
112
+ self.file.seek(snapshot_pos)
113
+ header = self.file.read(HEADER_SIZE)
114
+ if len(header) < HEADER_SIZE:
115
+ break
116
+ type_tag, length = struct.unpack(HEADER_FORMAT, header)
117
+ if type_tag != GLOBAL_STATE:
118
+ continue
119
+ payload = self.file.read(length)
120
+ msg = self.snapshot_cls()
121
+ msg.ParseFromString(payload)
122
+ return msg
123
+
124
+ return None
@@ -0,0 +1,9 @@
1
+ syntax = "proto3";
2
+
3
+ message PartialUpdate {
4
+ int32 updated_field = 1;
5
+ }
6
+
7
+ message GlobalState {
8
+ int32 field = 1;
9
+ }
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: src/experimaestro/tests/state_streamer.proto
5
+ # Protobuf Python Version: 5.29.3
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 5,
15
+ 29,
16
+ 3,
17
+ '',
18
+ 'src/experimaestro/tests/state_streamer.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,src/experimaestro/tests/state_streamer.proto\"&\n\rPartialUpdate\x12\x15\n\rupdated_field\x18\x01 \x01(\x05\"\x1c\n\x0bGlobalState\x12\r\n\x05\x66ield\x18\x01 \x01(\x05\x62\x06proto3')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'src.experimaestro.tests.state_streamer_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_PARTIALUPDATE']._serialized_start=48
35
+ _globals['_PARTIALUPDATE']._serialized_end=86
36
+ _globals['_GLOBALSTATE']._serialized_start=88
37
+ _globals['_GLOBALSTATE']._serialized_end=116
38
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,18 @@
1
+ from .state_streamer_pb2 import PartialUpdate, GlobalState
2
+
3
+ # Writing
4
+ with open("log.bin", "wb") as f:
5
+ writer = StreamingStateWriter(f, PartialUpdate, GlobalState)
6
+ for i in range(1000):
7
+ writer.write_partial(PartialUpdate(updated_field=i))
8
+ if i % 100 == 0:
9
+ writer.write_snapshot_if_needed(GlobalState(field=i))
10
+
11
+ # Reading
12
+ with open("log.bin", "rb") as f:
13
+ reader = StreamingStateReader(f, PartialUpdate, GlobalState)
14
+ last_snapshot = reader.seek_last_snapshot()
15
+ print("Last Snapshot:", last_snapshot)
16
+
17
+ for msg in reader:
18
+ print(type(msg).__name__, msg)