parsl 2024.2.19__tar.gz → 2024.2.26__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 (454) hide show
  1. {parsl-2024.2.19/parsl.egg-info → parsl-2024.2.26}/PKG-INFO +2 -2
  2. {parsl-2024.2.19 → parsl-2024.2.26}/README.rst +1 -1
  3. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/errors.py +1 -4
  4. parsl-2024.2.19/parsl/configs/comet.py → parsl-2024.2.26/parsl/configs/expanse.py +5 -5
  5. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/dflow.py +12 -12
  6. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/executor.py +19 -2
  7. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/jobs/states.py +5 -5
  8. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/monitoring.py +7 -4
  9. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/multiprocessing.py +3 -4
  10. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/cobalt/cobalt.py +6 -0
  11. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/pbspro/pbspro.py +18 -4
  12. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/pbspro/template.py +2 -2
  13. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/slurm/slurm.py +17 -4
  14. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/slurm/template.py +2 -2
  15. parsl-2024.2.26/parsl/tests/test_htex/test_htex.py +109 -0
  16. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +1 -1
  17. parsl-2024.2.26/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +16 -0
  18. parsl-2024.2.26/parsl/tests/test_providers/test_pbspro_template.py +28 -0
  19. parsl-2024.2.26/parsl/tests/test_providers/test_slurm_template.py +29 -0
  20. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_radical/test_mpi_funcs.py +1 -0
  21. parsl-2024.2.26/parsl/tests/test_serialization/test_htex_code_cache.py +57 -0
  22. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/usage_tracking/usage.py +12 -9
  23. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/version.py +1 -1
  24. {parsl-2024.2.19 → parsl-2024.2.26/parsl.egg-info}/PKG-INFO +2 -2
  25. {parsl-2024.2.19 → parsl-2024.2.26}/parsl.egg-info/SOURCES.txt +5 -3
  26. parsl-2024.2.19/parsl/configs/cooley.py +0 -29
  27. parsl-2024.2.19/parsl/configs/theta.py +0 -33
  28. parsl-2024.2.19/parsl/tests/test_htex/test_htex.py +0 -46
  29. {parsl-2024.2.19 → parsl-2024.2.26}/LICENSE +0 -0
  30. {parsl-2024.2.19 → parsl-2024.2.26}/MANIFEST.in +0 -0
  31. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/__init__.py +0 -0
  32. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/addresses.py +0 -0
  33. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/app/__init__.py +0 -0
  34. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/app/app.py +0 -0
  35. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/app/bash.py +0 -0
  36. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/app/errors.py +0 -0
  37. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/app/futures.py +0 -0
  38. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/app/python.py +0 -0
  39. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/benchmark/__init__.py +0 -0
  40. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/benchmark/perf.py +0 -0
  41. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/__init__.py +0 -0
  42. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/base.py +0 -0
  43. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/local/__init__.py +0 -0
  44. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/local/local.py +0 -0
  45. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/oauth_ssh/__init__.py +0 -0
  46. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
  47. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/ssh/__init__.py +0 -0
  48. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/ssh/ssh.py +0 -0
  49. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/ssh_il/__init__.py +0 -0
  50. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/channels/ssh_il/ssh_il.py +0 -0
  51. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/concurrent/__init__.py +0 -0
  52. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/config.py +0 -0
  53. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/ASPIRE1.py +0 -0
  54. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/Azure.py +0 -0
  55. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/__init__.py +0 -0
  56. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/ad_hoc.py +0 -0
  57. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/bluewaters.py +0 -0
  58. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/bridges.py +0 -0
  59. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/cc_in2p3.py +0 -0
  60. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/ec2.py +0 -0
  61. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/frontera.py +0 -0
  62. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/htex_local.py +0 -0
  63. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/illinoiscluster.py +0 -0
  64. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/kubernetes.py +0 -0
  65. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/local_threads.py +0 -0
  66. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/midway.py +0 -0
  67. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/osg.py +0 -0
  68. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/polaris.py +0 -0
  69. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/stampede2.py +0 -0
  70. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/summit.py +0 -0
  71. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/toss3_llnl.py +0 -0
  72. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/vineex_local.py +0 -0
  73. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/configs/wqex_local.py +0 -0
  74. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/curvezmq.py +0 -0
  75. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/__init__.py +0 -0
  76. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/data_manager.py +0 -0
  77. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/file_noop.py +0 -0
  78. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/files.py +0 -0
  79. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/ftp.py +0 -0
  80. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/globus.py +0 -0
  81. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/http.py +0 -0
  82. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/rsync.py +0 -0
  83. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/data_provider/staging.py +0 -0
  84. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/__init__.py +0 -0
  85. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/errors.py +0 -0
  86. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/futures.py +0 -0
  87. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/memoization.py +0 -0
  88. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/rundirs.py +0 -0
  89. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/states.py +0 -0
  90. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/dataflow/taskrecord.py +0 -0
  91. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/errors.py +0 -0
  92. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/__init__.py +0 -0
  93. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/base.py +0 -0
  94. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/errors.py +0 -0
  95. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/flux/__init__.py +0 -0
  96. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/flux/execute_parsl_task.py +0 -0
  97. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/flux/executor.py +0 -0
  98. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/flux/flux_instance_manager.py +0 -0
  99. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/__init__.py +0 -0
  100. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/errors.py +0 -0
  101. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/interchange.py +0 -0
  102. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/manager_record.py +0 -0
  103. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  104. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  105. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  106. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/probe.py +0 -0
  107. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/process_worker_pool.py +0 -0
  108. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
  109. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/radical/__init__.py +0 -0
  110. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/radical/executor.py +0 -0
  111. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/radical/rpex_master.py +0 -0
  112. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/radical/rpex_resources.py +0 -0
  113. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/radical/rpex_worker.py +0 -0
  114. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/status_handling.py +0 -0
  115. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/__init__.py +0 -0
  116. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/errors.py +0 -0
  117. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  118. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/executor.py +0 -0
  119. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/factory.py +0 -0
  120. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/factory_config.py +0 -0
  121. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/manager.py +0 -0
  122. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/manager_config.py +0 -0
  123. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/taskvine/utils.py +0 -0
  124. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/threads.py +0 -0
  125. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/workqueue/__init__.py +0 -0
  126. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/workqueue/errors.py +0 -0
  127. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  128. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/workqueue/executor.py +0 -0
  129. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  130. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  131. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/jobs/__init__.py +0 -0
  132. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/jobs/error_handlers.py +0 -0
  133. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/jobs/errors.py +0 -0
  134. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/jobs/job_status_poller.py +0 -0
  135. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/jobs/strategy.py +0 -0
  136. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/launchers/__init__.py +0 -0
  137. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/launchers/base.py +0 -0
  138. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/launchers/errors.py +0 -0
  139. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/launchers/launchers.py +0 -0
  140. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/log_utils.py +0 -0
  141. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/__init__.py +0 -0
  142. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/db_manager.py +0 -0
  143. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/message_type.py +0 -0
  144. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/queries/__init__.py +0 -0
  145. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/queries/pandas.py +0 -0
  146. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/radios.py +0 -0
  147. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/remote.py +0 -0
  148. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/types.py +0 -0
  149. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/__init__.py +0 -0
  150. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/app.py +0 -0
  151. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/models.py +0 -0
  152. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  153. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  154. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  155. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  156. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  157. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  158. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  159. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/app.html +0 -0
  160. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/dag.html +0 -0
  161. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/error.html +0 -0
  162. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/layout.html +0 -0
  163. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  164. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/task.html +0 -0
  165. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  166. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  167. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/utils.py +0 -0
  168. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/version.py +0 -0
  169. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/monitoring/visualization/views.py +0 -0
  170. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/process_loggers.py +0 -0
  171. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/__init__.py +0 -0
  172. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/ad_hoc/__init__.py +0 -0
  173. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
  174. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/aws/__init__.py +0 -0
  175. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/aws/aws.py +0 -0
  176. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/aws/template.py +0 -0
  177. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/azure/__init__.py +0 -0
  178. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/azure/azure.py +0 -0
  179. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/azure/template.py +0 -0
  180. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/base.py +0 -0
  181. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/cluster_provider.py +0 -0
  182. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/cobalt/__init__.py +0 -0
  183. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/cobalt/template.py +0 -0
  184. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/condor/__init__.py +0 -0
  185. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/condor/condor.py +0 -0
  186. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/condor/template.py +0 -0
  187. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/errors.py +0 -0
  188. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/googlecloud/__init__.py +0 -0
  189. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/googlecloud/googlecloud.py +0 -0
  190. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/grid_engine/__init__.py +0 -0
  191. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/grid_engine/grid_engine.py +0 -0
  192. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/grid_engine/template.py +0 -0
  193. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/kubernetes/__init__.py +0 -0
  194. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/kubernetes/kube.py +0 -0
  195. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/kubernetes/template.py +0 -0
  196. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/local/__init__.py +0 -0
  197. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/local/local.py +0 -0
  198. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/lsf/__init__.py +0 -0
  199. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/lsf/lsf.py +0 -0
  200. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/lsf/template.py +0 -0
  201. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/pbspro/__init__.py +0 -0
  202. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/slurm/__init__.py +0 -0
  203. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/torque/__init__.py +0 -0
  204. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/torque/template.py +0 -0
  205. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/providers/torque/torque.py +0 -0
  206. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/py.typed +0 -0
  207. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/serialize/__init__.py +0 -0
  208. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/serialize/base.py +0 -0
  209. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/serialize/concretes.py +0 -0
  210. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/serialize/errors.py +0 -0
  211. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/serialize/facade.py +0 -0
  212. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/serialize/proxystore.py +0 -0
  213. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/__init__.py +0 -0
  214. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/callables_helper.py +0 -0
  215. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/__init__.py +0 -0
  216. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
  217. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/azure_single_node.py +0 -0
  218. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/bluewaters.py +0 -0
  219. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/bridges.py +0 -0
  220. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/cc_in2p3.py +0 -0
  221. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/comet.py +0 -0
  222. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/cooley_htex.py +0 -0
  223. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/ec2_single_node.py +0 -0
  224. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/ec2_spot.py +0 -0
  225. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/frontera.py +0 -0
  226. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
  227. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/htex_local.py +0 -0
  228. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/htex_local_alternate.py +0 -0
  229. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  230. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  231. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_adhoc.py +0 -0
  232. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_radical.py +0 -0
  233. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_radical_mpi.py +0 -0
  234. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads.py +0 -0
  235. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  236. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  237. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
  238. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  239. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  240. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_globus.py +0 -0
  241. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  242. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  243. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  244. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/midway.py +0 -0
  245. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/nscc_singapore.py +0 -0
  246. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/osg_htex.py +0 -0
  247. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/petrelkube.py +0 -0
  248. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/summit.py +0 -0
  249. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/swan_htex.py +0 -0
  250. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/taskvine_ex.py +0 -0
  251. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/theta.py +0 -0
  252. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/user_opts.py +0 -0
  253. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/configs/workqueue_ex.py +0 -0
  254. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/conftest.py +0 -0
  255. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/__init__.py +0 -0
  256. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/latency.py +0 -0
  257. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_apps/__init__.py +0 -0
  258. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/__init__.py +0 -0
  259. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_channels.py +0 -0
  260. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
  261. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
  262. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
  263. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
  264. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
  265. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
  266. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  267. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_stress/__init__.py +0 -0
  268. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  269. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  270. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/__init__.py +0 -0
  271. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/htex_local.py +0 -0
  272. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
  273. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_basic.py +0 -0
  274. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
  275. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  276. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  277. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
  278. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  279. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  280. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  281. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/__init__.py +0 -0
  282. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/htex_local.py +0 -0
  283. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/local_threads.py +0 -0
  284. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/test_scale.py +0 -0
  285. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  286. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  287. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  288. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  289. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/site_tests/__init__.py +0 -0
  290. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/site_tests/site_config_selector.py +0 -0
  291. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/site_tests/test_provider.py +0 -0
  292. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/site_tests/test_site.py +0 -0
  293. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/__init__.py +0 -0
  294. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_affinity.py +0 -0
  295. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_concurrent.py +0 -0
  296. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  297. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_ec2.py +0 -0
  298. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_launchers.py +0 -0
  299. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_local_adhoc.py +0 -0
  300. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  301. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/sites/test_worker_info.py +0 -0
  302. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_aalst_patterns.py +0 -0
  303. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/__init__.py +0 -0
  304. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  305. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_basic.py +0 -0
  306. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  307. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  308. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  309. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  310. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  311. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  312. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  313. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  314. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  315. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_callables.py +0 -0
  316. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_channels/__init__.py +0 -0
  317. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_channels/test_large_output.py +0 -0
  318. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/__init__.py +0 -0
  319. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
  320. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  321. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  322. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  323. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  324. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  325. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  326. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
  327. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_curvezmq.py +0 -0
  328. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_data/__init__.py +0 -0
  329. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_data/test_file.py +0 -0
  330. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_data/test_file_apps.py +0 -0
  331. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_data/test_file_staging.py +0 -0
  332. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_data/test_output_chain_filenames.py +0 -0
  333. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/__init__.py +0 -0
  334. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/test_from_slides.py +0 -0
  335. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/test_kwargs.py +0 -0
  336. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  337. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/test_workflow1.py +0 -0
  338. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/test_workflow2.py +0 -0
  339. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_docs/test_workflow4.py +0 -0
  340. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/__init__.py +0 -0
  341. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_fail.py +0 -0
  342. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  343. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  344. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  345. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_retries.py +0 -0
  346. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  347. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  348. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  349. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  350. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_flowcontrol/__init__.py +0 -0
  351. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_flux.py +0 -0
  352. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/__init__.py +0 -0
  353. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_basic.py +0 -0
  354. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  355. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  356. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
  357. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  358. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  359. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  360. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  361. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
  362. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/__init__.py +0 -0
  363. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/test_basic.py +0 -0
  364. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  365. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
  366. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  367. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  368. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  369. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/__init__.py +0 -0
  370. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  371. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
  372. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  373. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  374. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  375. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_providers/__init__.py +0 -0
  376. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_providers/test_local_provider.py +0 -0
  377. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  378. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  379. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/__init__.py +0 -0
  380. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  381. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_basic.py +0 -0
  382. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  383. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  384. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  385. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_fail.py +0 -0
  386. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  387. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  388. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_futures.py +0 -0
  389. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  390. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  391. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_join.py +0 -0
  392. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  393. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  394. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  395. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  396. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  397. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  398. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  399. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  400. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  401. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_overview.py +0 -0
  402. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  403. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_simple.py +0 -0
  404. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  405. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_python_apps/test_type5.py +0 -0
  406. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_radical/__init__.py +0 -0
  407. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/__init__.py +0 -0
  408. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_1480.py +0 -0
  409. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  410. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_1653.py +0 -0
  411. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_221.py +0 -0
  412. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_226.py +0 -0
  413. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_2652.py +0 -0
  414. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_69a.py +0 -0
  415. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_854.py +0 -0
  416. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  417. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_regression/test_98.py +0 -0
  418. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_scaling/__init__.py +0 -0
  419. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  420. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
  421. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  422. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_serialization/__init__.py +0 -0
  423. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  424. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_serialization/test_basic.py +0 -0
  425. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  426. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  427. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  428. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/__init__.py +0 -0
  429. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/staging_provider.py +0 -0
  430. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_1316.py +0 -0
  431. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_docs_1.py +0 -0
  432. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_docs_2.py +0 -0
  433. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  434. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  435. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  436. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  437. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_staging/test_staging_https.py +0 -0
  438. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_summary.py +0 -0
  439. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_thread_parallelism.py +0 -0
  440. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_threads/__init__.py +0 -0
  441. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_threads/test_configs.py +0 -0
  442. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  443. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_utils/__init__.py +0 -0
  444. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  445. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/tests/utils.py +0 -0
  446. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/usage_tracking/__init__.py +0 -0
  447. {parsl-2024.2.19 → parsl-2024.2.26}/parsl/utils.py +0 -0
  448. {parsl-2024.2.19 → parsl-2024.2.26}/parsl.egg-info/dependency_links.txt +0 -0
  449. {parsl-2024.2.19 → parsl-2024.2.26}/parsl.egg-info/entry_points.txt +0 -0
  450. {parsl-2024.2.19 → parsl-2024.2.26}/parsl.egg-info/requires.txt +0 -0
  451. {parsl-2024.2.19 → parsl-2024.2.26}/parsl.egg-info/top_level.txt +0 -0
  452. {parsl-2024.2.19 → parsl-2024.2.26}/requirements.txt +0 -0
  453. {parsl-2024.2.19 → parsl-2024.2.26}/setup.cfg +0 -0
  454. {parsl-2024.2.19 → parsl-2024.2.26}/setup.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.2.19
3
+ Version: 2024.2.26
4
4
  Summary: Simple data dependent workflows in Python
5
5
  Home-page: https://github.com/Parsl/parsl
6
- Download-URL: https://github.com/Parsl/parsl/archive/2024.02.19.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.02.26.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -73,7 +73,7 @@ To run the Parsl tutorial notebooks you will need to install Jupyter::
73
73
 
74
74
  Detailed information about setting up Jupyter with Python is available `here <https://jupyter.readthedocs.io/en/latest/install.html>`_
75
75
 
76
- Note: Parsl uses an opt-in model to collect anonymous usage statistics for reporting and improvement purposes. To understand what stats are collected and enable collection please refer to the `usage tracking guide <http://parsl.readthedocs.io/en/stable/userguide/usage_tracking.html>`__
76
+ Note: Parsl uses an opt-in model to collect usage statistics for reporting and improvement purposes. To understand what stats are collected and enable collection please refer to the `usage tracking guide <http://parsl.readthedocs.io/en/stable/userguide/usage_tracking.html>`__
77
77
 
78
78
  Documentation
79
79
  =============
@@ -14,11 +14,8 @@ class ChannelError(ParslError):
14
14
  self.e = e
15
15
  self.hostname = hostname
16
16
 
17
- def __repr__(self) -> str:
18
- return "Hostname:{0}, Reason:{1}".format(self.hostname, self.reason)
19
-
20
17
  def __str__(self) -> str:
21
- return self.__repr__()
18
+ return "Hostname:{0}, Reason:{1}".format(self.hostname, self.reason)
22
19
 
23
20
 
24
21
  class BadHostKeyException(ChannelError):
@@ -7,11 +7,11 @@ from parsl.executors import HighThroughputExecutor
7
7
  config = Config(
8
8
  executors=[
9
9
  HighThroughputExecutor(
10
- label='Comet_HTEX_multinode',
11
- worker_logdir_root='YOUR_LOGDIR_ON_COMET',
12
- max_workers=2,
10
+ label='Expanse_CPU_Multinode',
11
+ max_workers=32,
13
12
  provider=SlurmProvider(
14
- 'debug',
13
+ 'compute',
14
+ account='YOUR_ALLOCATION_ON_EXPANSE',
15
15
  launcher=SrunLauncher(),
16
16
  # string to prepend to #SBATCH blocks in the submit
17
17
  # script to the scheduler
@@ -19,7 +19,7 @@ config = Config(
19
19
  # Command to be run before starting a worker, such as:
20
20
  # 'module load Anaconda; source activate parsl_env'.
21
21
  worker_init='',
22
- walltime='00:10:00',
22
+ walltime='01:00:00',
23
23
  init_blocks=1,
24
24
  max_blocks=1,
25
25
  nodes_per_block=2,
@@ -113,7 +113,7 @@ class DataFlowKernel:
113
113
  if self.monitoring.logdir is None:
114
114
  self.monitoring.logdir = self.run_dir
115
115
  self.hub_address = self.monitoring.hub_address
116
- self.hub_interchange_port = self.monitoring.start(self.run_id, self.run_dir)
116
+ self.hub_interchange_port = self.monitoring.start(self.run_id, self.run_dir, self.config.run_dir)
117
117
 
118
118
  self.time_began = datetime.datetime.now()
119
119
  self.time_completed: Optional[datetime.datetime] = None
@@ -678,10 +678,10 @@ class DataFlowKernel:
678
678
  task_record : The task record
679
679
 
680
680
  Returns:
681
- Future that tracks the execution of the submitted executable
681
+ Future that tracks the execution of the submitted function
682
682
  """
683
683
  task_id = task_record['id']
684
- executable = task_record['func']
684
+ function = task_record['func']
685
685
  args = task_record['args']
686
686
  kwargs = task_record['kwargs']
687
687
 
@@ -706,17 +706,17 @@ class DataFlowKernel:
706
706
 
707
707
  if self.monitoring is not None and self.monitoring.resource_monitoring_enabled:
708
708
  wrapper_logging_level = logging.DEBUG if self.monitoring.monitoring_debug else logging.INFO
709
- (executable, args, kwargs) = self.monitoring.monitor_wrapper(executable, args, kwargs, try_id, task_id,
710
- self.monitoring.monitoring_hub_url,
711
- self.run_id,
712
- wrapper_logging_level,
713
- self.monitoring.resource_monitoring_interval,
714
- executor.radio_mode,
715
- executor.monitor_resources(),
716
- self.run_dir)
709
+ (function, args, kwargs) = self.monitoring.monitor_wrapper(function, args, kwargs, try_id, task_id,
710
+ self.monitoring.monitoring_hub_url,
711
+ self.run_id,
712
+ wrapper_logging_level,
713
+ self.monitoring.resource_monitoring_interval,
714
+ executor.radio_mode,
715
+ executor.monitor_resources(),
716
+ self.run_dir)
717
717
 
718
718
  with self.submitter_lock:
719
- exec_fu = executor.submit(executable, task_record['resource_specification'], *args, **kwargs)
719
+ exec_fu = executor.submit(function, task_record['resource_specification'], *args, **kwargs)
720
720
  self.update_task_state(task_record, States.launched)
721
721
 
722
722
  self._send_task_log_info(task_record)
@@ -6,7 +6,7 @@ import threading
6
6
  import queue
7
7
  import datetime
8
8
  import pickle
9
- from multiprocessing import Queue
9
+ from multiprocessing import Process, Queue
10
10
  from typing import Dict, Sequence
11
11
  from typing import List, Optional, Tuple, Union, Callable
12
12
  import math
@@ -290,6 +290,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
290
290
  self.hub_port = None # set to the correct hub port in dfk
291
291
  self.worker_ports = worker_ports
292
292
  self.worker_port_range = worker_port_range
293
+ self.interchange_proc: Optional[Process] = None
293
294
  self.interchange_port_range = interchange_port_range
294
295
  self.heartbeat_threshold = heartbeat_threshold
295
296
  self.heartbeat_period = heartbeat_period
@@ -766,12 +767,28 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
766
767
  )
767
768
  return job_status
768
769
 
769
- def shutdown(self):
770
+ def shutdown(self, timeout: float = 10.0):
770
771
  """Shutdown the executor, including the interchange. This does not
771
772
  shut down any workers directly - workers should be terminated by the
772
773
  scaling mechanism or by heartbeat timeout.
774
+
775
+ Parameters
776
+ ----------
777
+
778
+ timeout : float
779
+ Amount of time to wait for the Interchange process to terminate before
780
+ we forcefully kill it.
773
781
  """
782
+ if self.interchange_proc is None:
783
+ logger.info("HighThroughputExecutor has not started; skipping shutdown")
784
+ return
774
785
 
775
786
  logger.info("Attempting HighThroughputExecutor shutdown")
787
+
776
788
  self.interchange_proc.terminate()
789
+ self.interchange_proc.join(timeout=timeout)
790
+ if self.interchange_proc.is_alive():
791
+ logger.info("Unable to terminate Interchange process; sending SIGKILL")
792
+ self.interchange_proc.kill()
793
+
777
794
  logger.info("Finished HighThroughputExecutor shutdown attempt")
@@ -47,7 +47,7 @@ class JobState(IntEnum):
47
47
  """
48
48
 
49
49
  def __str__(self) -> str:
50
- return self.__class__.__name__ + "." + self.name
50
+ return f"{self.__class__.__name__}.{self.name}"
51
51
 
52
52
 
53
53
  TERMINAL_STATES = [JobState.CANCELLED, JobState.COMPLETED, JobState.FAILED,
@@ -84,16 +84,16 @@ class JobStatus:
84
84
 
85
85
  def __repr__(self) -> str:
86
86
  if self.message is not None:
87
- extra = f"state={self.state} message={self.message}".format(self.state, self.message)
87
+ extra = f"state={self.state} message={self.message}"
88
88
  else:
89
- extra = f"state={self.state}".format(self.state)
89
+ extra = f"state={self.state}"
90
90
  return f"<{type(self).__module__}.{type(self).__qualname__} object at {hex(id(self))}, {extra}>"
91
91
 
92
92
  def __str__(self) -> str:
93
93
  if self.message is not None:
94
- return "{} ({})".format(self.state, self.message)
94
+ return f"{self.state} ({self.message})"
95
95
  else:
96
- return "{}".format(self.state)
96
+ return f"{self.state}"
97
97
 
98
98
  @property
99
99
  def stdout(self) -> Optional[str]:
@@ -84,7 +84,7 @@ class MonitoringHub(RepresentationMixin):
84
84
 
85
85
  workflow_name: Optional[str] = None,
86
86
  workflow_version: Optional[str] = None,
87
- logging_endpoint: str = 'sqlite:///runinfo/monitoring.db',
87
+ logging_endpoint: Optional[str] = None,
88
88
  logdir: Optional[str] = None,
89
89
  monitoring_debug: bool = False,
90
90
  resource_monitoring_enabled: bool = True,
@@ -118,7 +118,7 @@ class MonitoringHub(RepresentationMixin):
118
118
  logging_endpoint : str
119
119
  The database connection url for monitoring to log the information.
120
120
  These URLs follow RFC-1738, and can include username, password, hostname, database name.
121
- Default: 'sqlite:///monitoring.db'
121
+ Default: sqlite, in the configured run_dir.
122
122
  logdir : str
123
123
  Parsl log directory paths. Logs and temp files go here. Default: '.'
124
124
  monitoring_debug : Bool
@@ -162,11 +162,14 @@ class MonitoringHub(RepresentationMixin):
162
162
  self.resource_monitoring_enabled = resource_monitoring_enabled
163
163
  self.resource_monitoring_interval = resource_monitoring_interval
164
164
 
165
- def start(self, run_id: str, run_dir: str) -> int:
165
+ def start(self, run_id: str, dfk_run_dir: str, config_run_dir: Union[str, os.PathLike]) -> int:
166
166
 
167
167
  if self.logdir is None:
168
168
  self.logdir = "."
169
169
 
170
+ if self.logging_endpoint is None:
171
+ self.logging_endpoint = f"sqlite:///{os.fspath(config_run_dir)}/monitoring.db"
172
+
170
173
  os.makedirs(self.logdir, exist_ok=True)
171
174
 
172
175
  # Initialize the ZMQ pipe to the Parsl Client
@@ -231,7 +234,7 @@ class MonitoringHub(RepresentationMixin):
231
234
  self.logger.info("Started the router process {} and DBM process {}".format(self.router_proc.pid, self.dbm_proc.pid))
232
235
 
233
236
  self.filesystem_proc = Process(target=filesystem_receiver,
234
- args=(self.logdir, self.resource_msgs, run_dir),
237
+ args=(self.logdir, self.resource_msgs, dfk_run_dir),
235
238
  name="Monitoring-Filesystem-Process",
236
239
  daemon=True
237
240
  )
@@ -5,17 +5,16 @@ import logging
5
5
  import multiprocessing
6
6
  import multiprocessing.queues
7
7
  import platform
8
+ from multiprocessing.context import ForkProcess as ForkProcessType
8
9
 
9
- from typing import Callable, Type
10
+ from typing import Callable
10
11
 
11
12
  logger = logging.getLogger(__name__)
12
13
 
13
14
  ForkContext = multiprocessing.get_context("fork")
14
15
  SpawnContext = multiprocessing.get_context("spawn")
15
16
 
16
- # maybe ForkProcess should be: Callable[..., Process] so as to make
17
- # it clear that it returns a Process always to the type checker?
18
- ForkProcess: Type = ForkContext.Process
17
+ ForkProcess: Callable[..., ForkProcessType] = ForkContext.Process
19
18
 
20
19
 
21
20
  class MacSafeQueue(multiprocessing.queues.Queue):
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  import os
3
3
  import time
4
+ import warnings
4
5
 
5
6
  from parsl.providers.errors import ScaleOutFailed
6
7
  from parsl.channels import LocalChannel
@@ -24,6 +25,8 @@ translate_table = {
24
25
  class CobaltProvider(ClusterProvider, RepresentationMixin):
25
26
  """ Cobalt Execution Provider
26
27
 
28
+ WARNING: CobaltProvider is deprecated and will be removed by 2024.04
29
+
27
30
  This provider uses cobalt to submit (qsub), obtain the status of (qstat), and cancel (qdel)
28
31
  jobs. Theo script to be used is created from a template file in this
29
32
  same module.
@@ -86,6 +89,9 @@ class CobaltProvider(ClusterProvider, RepresentationMixin):
86
89
  self.queue = queue
87
90
  self.scheduler_options = scheduler_options
88
91
  self.worker_init = worker_init
92
+ warnings.warn("CobaltProvider is deprecated; This will be removed after 2024-04",
93
+ DeprecationWarning,
94
+ stacklevel=2)
89
95
 
90
96
  def _status(self):
91
97
  """Returns the status list for a list of job_ids
@@ -119,13 +119,17 @@ class PBSProProvider(TorqueProvider):
119
119
 
120
120
  job_state = job.get('job_state', JobState.UNKNOWN)
121
121
  state = translate_table.get(job_state, JobState.UNKNOWN)
122
- self.resources[job_id]['status'] = JobStatus(state)
122
+ self.resources[job_id]['status'] = JobStatus(state,
123
+ stdout_path=self.resources[job_id]['job_stdout_path'],
124
+ stderr_path=self.resources[job_id]['job_stderr_path'])
123
125
  jobs_missing.remove(job_id)
124
126
 
125
127
  # squeue does not report on jobs that are not running. So we are filling in the
126
128
  # blanks for missing jobs, we might lose some information about why the jobs failed.
127
129
  for missing_job in jobs_missing:
128
- self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED)
130
+ self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED,
131
+ stdout_path=self.resources[missing_job]['job_stdout_path'],
132
+ stderr_path=self.resources[missing_job]['job_stderr_path'])
129
133
 
130
134
  def submit(self, command, tasks_per_node, job_name="parsl"):
131
135
  """Submits the command job.
@@ -149,7 +153,11 @@ class PBSProProvider(TorqueProvider):
149
153
 
150
154
  job_name = "{0}.{1}".format(job_name, time.time())
151
155
 
152
- script_path = os.path.abspath("{0}/{1}.submit".format(self.script_dir, job_name))
156
+ assert self.script_dir, "Expected script_dir to be set"
157
+ script_path = os.path.join(self.script_dir, job_name)
158
+ script_path = os.path.abspath(script_path)
159
+ job_stdout_path = script_path + ".stdout"
160
+ job_stderr_path = script_path + ".stderr"
153
161
 
154
162
  logger.debug("Requesting {} nodes_per_block, {} tasks_per_node".format(
155
163
  self.nodes_per_block, tasks_per_node)
@@ -163,6 +171,8 @@ class PBSProProvider(TorqueProvider):
163
171
  job_config["scheduler_options"] = self.scheduler_options
164
172
  job_config["worker_init"] = self.worker_init
165
173
  job_config["user_script"] = command
174
+ job_config["job_stdout_path"] = job_stdout_path
175
+ job_config["job_stderr_path"] = job_stderr_path
166
176
 
167
177
  # Add a colon to select_options if one isn't included
168
178
  if self.select_options and not self.select_options.startswith(":"):
@@ -194,7 +204,11 @@ class PBSProProvider(TorqueProvider):
194
204
  for line in stdout.split('\n'):
195
205
  if line.strip():
196
206
  job_id = line.strip()
197
- self.resources[job_id] = {'job_id': job_id, 'status': JobStatus(JobState.PENDING)}
207
+ self.resources[job_id] = {'job_id': job_id,
208
+ 'status': JobStatus(JobState.PENDING),
209
+ 'job_stdout_path': job_stdout_path,
210
+ 'job_stderr_path': job_stderr_path,
211
+ }
198
212
  else:
199
213
  message = "Command '{}' failed with return code {}".format(launch_cmd, retcode)
200
214
  if (stdout is not None) and (stderr is not None):
@@ -5,8 +5,8 @@ template_string = '''#!/bin/bash
5
5
  #PBS -m n
6
6
  #PBS -l walltime=$walltime
7
7
  #PBS -l select=${nodes_per_block}:ncpus=${ncpus}${select_options}
8
- #PBS -o ${submit_script_dir}/${jobname}.submit.stdout
9
- #PBS -e ${submit_script_dir}/${jobname}.submit.stderr
8
+ #PBS -o ${job_stdout_path}
9
+ #PBS -e ${job_stderr_path}
10
10
  ${scheduler_options}
11
11
 
12
12
  ${worker_init}
@@ -188,14 +188,18 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
188
188
  logger.warning(f"Slurm status {slurm_state} is not recognized")
189
189
  status = translate_table.get(slurm_state, JobState.UNKNOWN)
190
190
  logger.debug("Updating job {} with slurm status {} to parsl state {!s}".format(job_id, slurm_state, status))
191
- self.resources[job_id]['status'] = JobStatus(status)
191
+ self.resources[job_id]['status'] = JobStatus(status,
192
+ stdout_path=self.resources[job_id]['job_stdout_path'],
193
+ stderr_path=self.resources[job_id]['job_stderr_path'])
192
194
  jobs_missing.remove(job_id)
193
195
 
194
196
  # squeue does not report on jobs that are not running. So we are filling in the
195
197
  # blanks for missing jobs, we might lose some information about why the jobs failed.
196
198
  for missing_job in jobs_missing:
197
199
  logger.debug("Updating missing job {} to completed status".format(missing_job))
198
- self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED)
200
+ self.resources[missing_job]['status'] = JobStatus(JobState.COMPLETED,
201
+ stdout_path=self.resources[missing_job]['job_stdout_path'],
202
+ stderr_path=self.resources[missing_job]['job_stderr_path'])
199
203
 
200
204
  def submit(self, command: str, tasks_per_node: int, job_name="parsl.slurm") -> str:
201
205
  """Submit the command as a slurm job.
@@ -226,8 +230,11 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
226
230
 
227
231
  job_name = "{0}.{1}".format(job_name, time.time())
228
232
 
229
- script_path = "{0}/{1}.submit".format(self.script_dir, job_name)
233
+ assert self.script_dir, "Expected script_dir to be set"
234
+ script_path = os.path.join(self.script_dir, job_name)
230
235
  script_path = os.path.abspath(script_path)
236
+ job_stdout_path = script_path + ".stdout"
237
+ job_stderr_path = script_path + ".stderr"
231
238
 
232
239
  logger.debug("Requesting one block with {} nodes".format(self.nodes_per_block))
233
240
 
@@ -239,6 +246,8 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
239
246
  job_config["scheduler_options"] = scheduler_options
240
247
  job_config["worker_init"] = worker_init
241
248
  job_config["user_script"] = command
249
+ job_config["job_stdout_path"] = job_stdout_path
250
+ job_config["job_stderr_path"] = job_stderr_path
242
251
 
243
252
  # Wrap the command
244
253
  job_config["user_script"] = self.launcher(command,
@@ -262,7 +271,11 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
262
271
  match = re.match(self.regex_job_id, line)
263
272
  if match:
264
273
  job_id = match.group("id")
265
- self.resources[job_id] = {'job_id': job_id, 'status': JobStatus(JobState.PENDING)}
274
+ self.resources[job_id] = {'job_id': job_id,
275
+ 'status': JobStatus(JobState.PENDING),
276
+ 'job_stdout_path': job_stdout_path,
277
+ 'job_stderr_path': job_stderr_path,
278
+ }
266
279
  return job_id
267
280
  else:
268
281
  logger.error("Could not read job ID from submit command standard output.")
@@ -1,8 +1,8 @@
1
1
  template_string = '''#!/bin/bash
2
2
 
3
3
  #SBATCH --job-name=${jobname}
4
- #SBATCH --output=${submit_script_dir}/${jobname}.submit.stdout
5
- #SBATCH --error=${submit_script_dir}/${jobname}.submit.stderr
4
+ #SBATCH --output=${job_stdout_path}
5
+ #SBATCH --error=${job_stderr_path}
6
6
  #SBATCH --nodes=${nodes}
7
7
  #SBATCH --time=${walltime}
8
8
  #SBATCH --ntasks-per-node=${tasks_per_node}
@@ -0,0 +1,109 @@
1
+ import pathlib
2
+ from unittest import mock
3
+
4
+ import pytest
5
+
6
+ from parsl import curvezmq
7
+ from parsl import HighThroughputExecutor
8
+ from parsl.multiprocessing import ForkProcess
9
+
10
+ _MOCK_BASE = "parsl.executors.high_throughput.executor"
11
+
12
+
13
+ @pytest.fixture
14
+ def encrypted(request: pytest.FixtureRequest):
15
+ if hasattr(request, "param"):
16
+ return request.param
17
+ return True
18
+
19
+
20
+ @pytest.fixture
21
+ def htex(encrypted: bool):
22
+ htex = HighThroughputExecutor(encrypted=encrypted)
23
+
24
+ yield htex
25
+
26
+ htex.shutdown()
27
+
28
+
29
+ @pytest.mark.local
30
+ @pytest.mark.parametrize("encrypted", (True, False), indirect=True)
31
+ @pytest.mark.parametrize("cert_dir_provided", (True, False))
32
+ def test_htex_start_encrypted(
33
+ encrypted: bool,
34
+ cert_dir_provided: bool,
35
+ htex: HighThroughputExecutor,
36
+ tmpd_cwd: pathlib.Path,
37
+ ):
38
+ htex.run_dir = str(tmpd_cwd)
39
+ if cert_dir_provided:
40
+ provided_base_dir = tmpd_cwd / "provided"
41
+ provided_base_dir.mkdir()
42
+ cert_dir = curvezmq.create_certificates(provided_base_dir)
43
+ htex.cert_dir = cert_dir
44
+ else:
45
+ cert_dir = curvezmq.create_certificates(htex.logdir)
46
+
47
+ if not encrypted and cert_dir_provided:
48
+ with pytest.raises(AttributeError) as pyt_e:
49
+ htex.start()
50
+ assert "change cert_dir to None" in str(pyt_e.value)
51
+ return
52
+
53
+ htex.start()
54
+
55
+ assert htex.encrypted is encrypted
56
+ if encrypted:
57
+ assert htex.cert_dir == cert_dir
58
+ assert htex.outgoing_q.zmq_context.cert_dir == cert_dir
59
+ assert htex.incoming_q.zmq_context.cert_dir == cert_dir
60
+ assert htex.command_client.zmq_context.cert_dir == cert_dir
61
+ assert isinstance(htex.outgoing_q.zmq_context, curvezmq.ClientContext)
62
+ assert isinstance(htex.incoming_q.zmq_context, curvezmq.ClientContext)
63
+ assert isinstance(htex.command_client.zmq_context, curvezmq.ClientContext)
64
+ else:
65
+ assert htex.cert_dir is None
66
+ assert htex.outgoing_q.zmq_context.cert_dir is None
67
+ assert htex.incoming_q.zmq_context.cert_dir is None
68
+ assert htex.command_client.zmq_context.cert_dir is None
69
+
70
+
71
+ @pytest.mark.local
72
+ @pytest.mark.parametrize("started", (True, False))
73
+ @pytest.mark.parametrize("timeout_expires", (True, False))
74
+ @mock.patch(f"{_MOCK_BASE}.logger")
75
+ def test_htex_shutdown(
76
+ mock_logger: mock.MagicMock,
77
+ started: bool,
78
+ timeout_expires: bool,
79
+ htex: HighThroughputExecutor,
80
+ ):
81
+ mock_ix_proc = mock.Mock(spec=ForkProcess)
82
+
83
+ if started:
84
+ htex.interchange_proc = mock_ix_proc
85
+ mock_ix_proc.is_alive.return_value = True
86
+
87
+ if not timeout_expires:
88
+ # Simulate termination of the Interchange process
89
+ def kill_interchange(*args, **kwargs):
90
+ mock_ix_proc.is_alive.return_value = False
91
+
92
+ mock_ix_proc.terminate.side_effect = kill_interchange
93
+
94
+ htex.shutdown()
95
+
96
+ mock_logs = mock_logger.info.call_args_list
97
+ if started:
98
+ assert mock_ix_proc.terminate.called
99
+ assert mock_ix_proc.join.called
100
+ assert {"timeout": 10} == mock_ix_proc.join.call_args[1]
101
+ if timeout_expires:
102
+ assert "Unable to terminate Interchange" in mock_logs[1][0][0]
103
+ assert mock_ix_proc.kill.called
104
+ assert "Attempting" in mock_logs[0][0][0]
105
+ assert "Finished" in mock_logs[-1][0][0]
106
+ else:
107
+ assert not mock_ix_proc.terminate.called
108
+ assert not mock_ix_proc.join.called
109
+ assert "has not started" in mock_logs[0][0][0]
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  import os
3
- import mock
3
+ from unittest import mock
4
4
  import pytest
5
5
  import pickle
6
6
  from parsl.executors.high_throughput.mpi_resource_management import TaskScheduler, MPITaskScheduler
@@ -0,0 +1,16 @@
1
+ import warnings
2
+ import pytest
3
+ from parsl.providers import CobaltProvider
4
+
5
+
6
+ @pytest.mark.local
7
+ def test_deprecation_warning():
8
+
9
+ with warnings.catch_warnings(record=True) as w:
10
+ warnings.simplefilter("always")
11
+
12
+ CobaltProvider()
13
+
14
+ assert len(w) == 1
15
+ assert issubclass(w[-1].category, DeprecationWarning)
16
+ assert "CobaltProvider" in str(w[-1].message)
@@ -0,0 +1,28 @@
1
+ import random
2
+
3
+ from unittest import mock
4
+ import pytest
5
+
6
+ from parsl.channels import LocalChannel
7
+ from parsl.providers import PBSProProvider
8
+
9
+
10
+ @pytest.mark.local
11
+ def test_submit_script_basic(tmp_path):
12
+ """Test slurm resources table"""
13
+
14
+ provider = PBSProProvider(
15
+ queue="debug", channel=LocalChannel(script_dir=tmp_path)
16
+ )
17
+ provider.script_dir = tmp_path
18
+ job_id = str(random.randint(55000, 59000))
19
+ provider.execute_wait = mock.Mock(spec=PBSProProvider.execute_wait)
20
+ provider.execute_wait.return_value = (0, job_id, "")
21
+ result_job_id = provider.submit("test", tasks_per_node=1)
22
+ assert job_id == result_job_id
23
+ provider.execute_wait.assert_called()
24
+ assert job_id in provider.resources
25
+
26
+ job_info = provider.resources[job_id]
27
+ assert "job_stdout_path" in job_info
28
+ assert "job_stderr_path" in job_info
@@ -0,0 +1,29 @@
1
+ import logging
2
+ import random
3
+
4
+ from unittest import mock
5
+ import pytest
6
+
7
+ from parsl.channels import LocalChannel
8
+ from parsl.providers import SlurmProvider
9
+
10
+
11
+ @pytest.mark.local
12
+ def test_submit_script_basic(tmp_path):
13
+ """Test slurm resources table"""
14
+
15
+ provider = SlurmProvider(
16
+ partition="debug", channel=LocalChannel(script_dir=tmp_path)
17
+ )
18
+ provider.script_dir = tmp_path
19
+ job_id = str(random.randint(55000, 59000))
20
+ provider.execute_wait = mock.MagicMock(spec=SlurmProvider.execute_wait)
21
+ provider.execute_wait.return_value = (0, f"Submitted batch job {job_id}", "")
22
+ result_job_id = provider.submit("test", tasks_per_node=1)
23
+ assert job_id == result_job_id
24
+ provider.execute_wait.assert_called()
25
+ assert job_id in provider.resources
26
+
27
+ job_info = provider.resources[job_id]
28
+ assert "job_stdout_path" in job_info
29
+ assert "job_stderr_path" in job_info
@@ -16,6 +16,7 @@ def some_mpi_func(msg, sleep, comm=None, parsl_resource_specification={}):
16
16
  apps = []
17
17
 
18
18
 
19
+ @pytest.mark.skip("hangs in CI - waiting for resolution of issue #3029")
19
20
  @pytest.mark.local
20
21
  @pytest.mark.radical
21
22
  def test_radical_mpi(n=7):