parsl 2024.4.15__tar.gz → 2024.4.29__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 (471) hide show
  1. {parsl-2024.4.15/parsl.egg-info → parsl-2024.4.29}/PKG-INFO +2 -2
  2. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/addresses.py +2 -2
  3. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/app/bash.py +10 -2
  4. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/app/errors.py +3 -5
  5. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/config.py +10 -1
  6. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/zip.py +32 -0
  7. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/dflow.py +102 -62
  8. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/futures.py +26 -5
  9. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/base.py +16 -0
  10. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/executor.py +7 -1
  11. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/executor.py +6 -0
  12. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/workqueue/executor.py +6 -0
  13. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/monitoring.py +15 -0
  14. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/kubernetes/kube.py +20 -1
  15. parsl-2024.4.29/parsl/tests/configs/local_threads_checkpoint_periodic.py +11 -0
  16. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/conftest.py +12 -1
  17. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_basic.py +2 -0
  18. parsl-2024.4.29/parsl/tests/test_bash_apps/test_std_uri.py +128 -0
  19. parsl-2024.4.29/parsl/tests/test_checkpointing/test_periodic.py +53 -0
  20. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_task_exit.py +1 -1
  21. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_basic.py +2 -2
  22. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_missing_worker.py +0 -4
  23. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_zmq_binding.py +1 -0
  24. parsl-2024.4.29/parsl/tests/test_monitoring/test_stdouterr.py +137 -0
  25. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/test_resource_spec.py +2 -8
  26. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_context_manager.py +3 -3
  27. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/test_regression_1621.py +11 -11
  28. parsl-2024.4.29/parsl/tests/test_staging/test_staging_stdout.py +61 -0
  29. parsl-2024.4.29/parsl/tests/test_staging/test_zip_in.py +42 -0
  30. parsl-2024.4.29/parsl/tests/test_staging/test_zip_to_zip.py +44 -0
  31. parsl-2024.4.29/parsl/tests/unit/test_file.py +99 -0
  32. parsl-2024.4.29/parsl/usage_tracking/__init__.py +0 -0
  33. parsl-2024.4.29/parsl/usage_tracking/api.py +66 -0
  34. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/usage_tracking/usage.py +39 -26
  35. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/utils.py +11 -2
  36. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/version.py +1 -1
  37. {parsl-2024.4.15 → parsl-2024.4.29/parsl.egg-info}/PKG-INFO +2 -2
  38. {parsl-2024.4.15 → parsl-2024.4.29}/parsl.egg-info/SOURCES.txt +8 -0
  39. {parsl-2024.4.15 → parsl-2024.4.29}/parsl.egg-info/requires.txt +2 -2
  40. {parsl-2024.4.15 → parsl-2024.4.29}/setup.py +1 -1
  41. parsl-2024.4.15/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -13
  42. parsl-2024.4.15/parsl/tests/test_checkpointing/test_periodic.py +0 -66
  43. {parsl-2024.4.15 → parsl-2024.4.29}/LICENSE +0 -0
  44. {parsl-2024.4.15 → parsl-2024.4.29}/MANIFEST.in +0 -0
  45. {parsl-2024.4.15 → parsl-2024.4.29}/README.rst +0 -0
  46. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/__init__.py +0 -0
  47. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/app/__init__.py +0 -0
  48. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/app/app.py +0 -0
  49. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/app/futures.py +0 -0
  50. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/app/python.py +0 -0
  51. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/benchmark/__init__.py +0 -0
  52. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/benchmark/perf.py +0 -0
  53. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/__init__.py +0 -0
  54. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/base.py +0 -0
  55. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/errors.py +0 -0
  56. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/local/__init__.py +0 -0
  57. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/local/local.py +0 -0
  58. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/oauth_ssh/__init__.py +0 -0
  59. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
  60. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/ssh/__init__.py +0 -0
  61. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/ssh/ssh.py +0 -0
  62. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/ssh_il/__init__.py +0 -0
  63. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/channels/ssh_il/ssh_il.py +0 -0
  64. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/concurrent/__init__.py +0 -0
  65. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/ASPIRE1.py +0 -0
  66. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/Azure.py +0 -0
  67. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/__init__.py +0 -0
  68. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/ad_hoc.py +0 -0
  69. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/bridges.py +0 -0
  70. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/cc_in2p3.py +0 -0
  71. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/ec2.py +0 -0
  72. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/expanse.py +0 -0
  73. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/frontera.py +0 -0
  74. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/htex_local.py +0 -0
  75. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/illinoiscluster.py +0 -0
  76. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/kubernetes.py +0 -0
  77. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/local_threads.py +0 -0
  78. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/midway.py +0 -0
  79. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/osg.py +0 -0
  80. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/polaris.py +0 -0
  81. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/stampede2.py +0 -0
  82. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/summit.py +0 -0
  83. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/toss3_llnl.py +0 -0
  84. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/vineex_local.py +0 -0
  85. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/configs/wqex_local.py +0 -0
  86. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/curvezmq.py +0 -0
  87. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/__init__.py +0 -0
  88. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/data_manager.py +0 -0
  89. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/file_noop.py +0 -0
  90. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/files.py +0 -0
  91. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/ftp.py +0 -0
  92. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/globus.py +0 -0
  93. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/http.py +0 -0
  94. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/rsync.py +0 -0
  95. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/data_provider/staging.py +0 -0
  96. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/__init__.py +0 -0
  97. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/errors.py +0 -0
  98. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/memoization.py +0 -0
  99. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/rundirs.py +0 -0
  100. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/states.py +0 -0
  101. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/dataflow/taskrecord.py +0 -0
  102. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/errors.py +0 -0
  103. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/__init__.py +0 -0
  104. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/errors.py +0 -0
  105. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/flux/__init__.py +0 -0
  106. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/flux/execute_parsl_task.py +0 -0
  107. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/flux/executor.py +0 -0
  108. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/flux/flux_instance_manager.py +0 -0
  109. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/__init__.py +0 -0
  110. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/errors.py +0 -0
  111. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/interchange.py +0 -0
  112. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/manager_record.py +0 -0
  113. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  114. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  115. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  116. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/probe.py +0 -0
  117. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/process_worker_pool.py +0 -0
  118. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
  119. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/radical/__init__.py +0 -0
  120. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/radical/executor.py +0 -0
  121. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/radical/rpex_master.py +0 -0
  122. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/radical/rpex_resources.py +0 -0
  123. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/radical/rpex_worker.py +0 -0
  124. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/status_handling.py +0 -0
  125. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/__init__.py +0 -0
  126. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/errors.py +0 -0
  127. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  128. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/factory.py +0 -0
  129. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/factory_config.py +0 -0
  130. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/manager.py +0 -0
  131. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/manager_config.py +0 -0
  132. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/taskvine/utils.py +0 -0
  133. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/threads.py +0 -0
  134. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/workqueue/__init__.py +0 -0
  135. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/workqueue/errors.py +0 -0
  136. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  137. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  138. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  139. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/jobs/__init__.py +0 -0
  140. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/jobs/error_handlers.py +0 -0
  141. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/jobs/errors.py +0 -0
  142. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/jobs/job_status_poller.py +0 -0
  143. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/jobs/states.py +0 -0
  144. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/jobs/strategy.py +0 -0
  145. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/launchers/__init__.py +0 -0
  146. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/launchers/base.py +0 -0
  147. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/launchers/errors.py +0 -0
  148. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/launchers/launchers.py +0 -0
  149. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/log_utils.py +0 -0
  150. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/__init__.py +0 -0
  151. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/db_manager.py +0 -0
  152. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/message_type.py +0 -0
  153. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/queries/__init__.py +0 -0
  154. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/queries/pandas.py +0 -0
  155. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/radios.py +0 -0
  156. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/remote.py +0 -0
  157. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/router.py +0 -0
  158. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/types.py +0 -0
  159. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/__init__.py +0 -0
  160. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/app.py +0 -0
  161. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/models.py +0 -0
  162. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  163. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  164. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  165. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  166. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  167. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  168. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  169. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/app.html +0 -0
  170. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/dag.html +0 -0
  171. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/error.html +0 -0
  172. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/layout.html +0 -0
  173. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  174. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/task.html +0 -0
  175. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  176. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  177. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/utils.py +0 -0
  178. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/version.py +0 -0
  179. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/monitoring/visualization/views.py +0 -0
  180. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/multiprocessing.py +0 -0
  181. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/process_loggers.py +0 -0
  182. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/__init__.py +0 -0
  183. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/ad_hoc/__init__.py +0 -0
  184. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
  185. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/aws/__init__.py +0 -0
  186. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/aws/aws.py +0 -0
  187. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/aws/template.py +0 -0
  188. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/azure/__init__.py +0 -0
  189. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/azure/azure.py +0 -0
  190. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/azure/template.py +0 -0
  191. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/base.py +0 -0
  192. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/cluster_provider.py +0 -0
  193. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/cobalt/__init__.py +0 -0
  194. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/cobalt/cobalt.py +0 -0
  195. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/cobalt/template.py +0 -0
  196. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/condor/__init__.py +0 -0
  197. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/condor/condor.py +0 -0
  198. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/condor/template.py +0 -0
  199. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/errors.py +0 -0
  200. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/googlecloud/__init__.py +0 -0
  201. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/googlecloud/googlecloud.py +0 -0
  202. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/grid_engine/__init__.py +0 -0
  203. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/grid_engine/grid_engine.py +0 -0
  204. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/grid_engine/template.py +0 -0
  205. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/kubernetes/__init__.py +0 -0
  206. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/kubernetes/template.py +0 -0
  207. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/local/__init__.py +0 -0
  208. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/local/local.py +0 -0
  209. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/lsf/__init__.py +0 -0
  210. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/lsf/lsf.py +0 -0
  211. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/lsf/template.py +0 -0
  212. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/pbspro/__init__.py +0 -0
  213. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/pbspro/pbspro.py +0 -0
  214. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/pbspro/template.py +0 -0
  215. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/slurm/__init__.py +0 -0
  216. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/slurm/slurm.py +0 -0
  217. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/slurm/template.py +0 -0
  218. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/torque/__init__.py +0 -0
  219. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/torque/template.py +0 -0
  220. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/providers/torque/torque.py +0 -0
  221. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/py.typed +0 -0
  222. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/serialize/__init__.py +0 -0
  223. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/serialize/base.py +0 -0
  224. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/serialize/concretes.py +0 -0
  225. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/serialize/errors.py +0 -0
  226. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/serialize/facade.py +0 -0
  227. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/serialize/proxystore.py +0 -0
  228. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/__init__.py +0 -0
  229. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/callables_helper.py +0 -0
  230. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/__init__.py +0 -0
  231. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
  232. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/azure_single_node.py +0 -0
  233. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/bluewaters.py +0 -0
  234. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/bridges.py +0 -0
  235. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/cc_in2p3.py +0 -0
  236. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/comet.py +0 -0
  237. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/cooley_htex.py +0 -0
  238. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/ec2_single_node.py +0 -0
  239. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/ec2_spot.py +0 -0
  240. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/frontera.py +0 -0
  241. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
  242. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/htex_local.py +0 -0
  243. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/htex_local_alternate.py +0 -0
  244. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  245. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  246. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_adhoc.py +0 -0
  247. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_radical.py +0 -0
  248. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_radical_mpi.py +0 -0
  249. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads.py +0 -0
  250. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  251. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  252. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  253. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  254. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_globus.py +0 -0
  255. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  256. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  257. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  258. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/midway.py +0 -0
  259. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/nscc_singapore.py +0 -0
  260. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/osg_htex.py +0 -0
  261. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/petrelkube.py +0 -0
  262. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/summit.py +0 -0
  263. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/swan_htex.py +0 -0
  264. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/taskvine_ex.py +0 -0
  265. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/theta.py +0 -0
  266. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/user_opts.py +0 -0
  267. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/configs/workqueue_ex.py +0 -0
  268. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/__init__.py +0 -0
  269. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/latency.py +0 -0
  270. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_apps/__init__.py +0 -0
  271. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/__init__.py +0 -0
  272. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_channels.py +0 -0
  273. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
  274. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
  275. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
  276. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
  277. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
  278. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
  279. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  280. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_stress/__init__.py +0 -0
  281. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  282. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  283. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/__init__.py +0 -0
  284. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/htex_local.py +0 -0
  285. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
  286. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_basic.py +0 -0
  287. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
  288. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  289. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  290. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
  291. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  292. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  293. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  294. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/__init__.py +0 -0
  295. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/htex_local.py +0 -0
  296. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/local_threads.py +0 -0
  297. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/test_scale.py +0 -0
  298. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  299. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  300. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  301. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  302. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/site_tests/__init__.py +0 -0
  303. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/site_tests/site_config_selector.py +0 -0
  304. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/site_tests/test_provider.py +0 -0
  305. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/site_tests/test_site.py +0 -0
  306. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/__init__.py +0 -0
  307. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_affinity.py +0 -0
  308. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_concurrent.py +0 -0
  309. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  310. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_ec2.py +0 -0
  311. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_launchers.py +0 -0
  312. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_local_adhoc.py +0 -0
  313. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  314. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/sites/test_worker_info.py +0 -0
  315. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_aalst_patterns.py +0 -0
  316. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/__init__.py +0 -0
  317. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  318. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  319. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  320. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  321. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  322. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  323. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  324. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  325. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  326. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  327. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_callables.py +0 -0
  328. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_channels/__init__.py +0 -0
  329. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_channels/test_large_output.py +0 -0
  330. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/__init__.py +0 -0
  331. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  332. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  333. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  334. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  335. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  336. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  337. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_curvezmq.py +0 -0
  338. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/__init__.py +0 -0
  339. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/test_from_slides.py +0 -0
  340. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/test_kwargs.py +0 -0
  341. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  342. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/test_workflow1.py +0 -0
  343. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/test_workflow2.py +0 -0
  344. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_docs/test_workflow4.py +0 -0
  345. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/__init__.py +0 -0
  346. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_fail.py +0 -0
  347. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  348. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  349. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  350. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_retries.py +0 -0
  351. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  352. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  353. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  354. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  355. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_flowcontrol/__init__.py +0 -0
  356. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_flux.py +0 -0
  357. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/__init__.py +0 -0
  358. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  359. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  360. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
  361. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_drain.py +0 -0
  362. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_htex.py +0 -0
  363. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  364. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  365. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  366. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/__init__.py +0 -0
  367. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_app_names.py +0 -0
  368. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_basic.py +0 -0
  369. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  370. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
  371. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
  372. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  373. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  374. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  375. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/__init__.py +0 -0
  376. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  377. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
  378. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  379. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  380. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
  381. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/__init__.py +0 -0
  382. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
  383. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/test_local_provider.py +0 -0
  384. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  385. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  386. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  387. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  388. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/__init__.py +0 -0
  389. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  390. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_basic.py +0 -0
  391. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  392. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  393. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  394. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_fail.py +0 -0
  395. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  396. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  397. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_futures.py +0 -0
  398. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  399. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  400. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_join.py +0 -0
  401. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  402. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  403. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  404. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  405. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  406. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  407. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  408. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  409. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  410. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_overview.py +0 -0
  411. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  412. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_simple.py +0 -0
  413. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  414. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_python_apps/test_type5.py +0 -0
  415. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_radical/__init__.py +0 -0
  416. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  417. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/__init__.py +0 -0
  418. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_1480.py +0 -0
  419. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  420. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_1653.py +0 -0
  421. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_221.py +0 -0
  422. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_226.py +0 -0
  423. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_2652.py +0 -0
  424. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_69a.py +0 -0
  425. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_854.py +0 -0
  426. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  427. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_regression/test_98.py +0 -0
  428. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/__init__.py +0 -0
  429. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  430. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  431. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
  432. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +0 -0
  433. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
  434. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/__init__.py +0 -0
  435. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  436. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/test_basic.py +0 -0
  437. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  438. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  439. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  440. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  441. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_shutdown/__init__.py +0 -0
  442. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
  443. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/__init__.py +0 -0
  444. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/staging_provider.py +0 -0
  445. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_1316.py +0 -0
  446. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_docs_1.py +0 -0
  447. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_docs_2.py +0 -0
  448. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  449. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_file.py +0 -0
  450. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_file_apps.py +0 -0
  451. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_file_staging.py +0 -0
  452. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
  453. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  454. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  455. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  456. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_staging_https.py +0 -0
  457. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_staging/test_zip_out.py +0 -0
  458. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_summary.py +0 -0
  459. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_thread_parallelism.py +0 -0
  460. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_threads/__init__.py +0 -0
  461. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_threads/test_configs.py +0 -0
  462. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  463. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_utils/__init__.py +0 -0
  464. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  465. {parsl-2024.4.15/parsl/usage_tracking → parsl-2024.4.29/parsl/tests/unit}/__init__.py +0 -0
  466. {parsl-2024.4.15 → parsl-2024.4.29}/parsl/tests/utils.py +0 -0
  467. {parsl-2024.4.15 → parsl-2024.4.29}/parsl.egg-info/dependency_links.txt +0 -0
  468. {parsl-2024.4.15 → parsl-2024.4.29}/parsl.egg-info/entry_points.txt +0 -0
  469. {parsl-2024.4.15 → parsl-2024.4.29}/parsl.egg-info/top_level.txt +0 -0
  470. {parsl-2024.4.15 → parsl-2024.4.29}/requirements.txt +0 -0
  471. {parsl-2024.4.15 → parsl-2024.4.29}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.4.15
3
+ Version: 2024.4.29
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.04.15.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.04.29.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -113,7 +113,7 @@ def get_all_addresses() -> Set[str]:
113
113
  try:
114
114
  s_addresses.add(address_by_interface(interface))
115
115
  except Exception:
116
- logger.info("Ignoring failure to fetch address from interface {}".format(interface))
116
+ logger.debug("Ignoring failure to fetch address from interface {}".format(interface))
117
117
 
118
118
  resolution_functions: List[Callable[[], str]]
119
119
  resolution_functions = [address_by_hostname, address_by_route, address_by_query]
@@ -121,7 +121,7 @@ def get_all_addresses() -> Set[str]:
121
121
  try:
122
122
  s_addresses.add(f())
123
123
  except Exception:
124
- logger.info("Ignoring an address finder exception")
124
+ logger.debug("Ignoring an address finder exception")
125
125
 
126
126
  return s_addresses
127
127
 
@@ -5,6 +5,7 @@ import logging
5
5
 
6
6
  from parsl.app.errors import wrap_error
7
7
  from parsl.app.app import AppBase
8
+ from parsl.data_provider.files import File
8
9
  from parsl.dataflow.dflow import DataFlowKernelLoader
9
10
 
10
11
  logger = logging.getLogger(__name__)
@@ -54,13 +55,20 @@ def remote_side_bash_executor(func, *args, **kwargs):
54
55
  if stdfspec is None:
55
56
  return None
56
57
 
57
- fname, mode = get_std_fname_mode(fdname, stdfspec)
58
+ if isinstance(stdfspec, File):
59
+ # a File is an os.PathLike and so we can use it directly for
60
+ # the subsequent file operations
61
+ fname = stdfspec
62
+ mode = "w"
63
+ else:
64
+ fname, mode = get_std_fname_mode(fdname, stdfspec)
65
+
58
66
  try:
59
67
  if os.path.dirname(fname):
60
68
  os.makedirs(os.path.dirname(fname), exist_ok=True)
61
69
  fd = open(fname, mode)
62
70
  except Exception as e:
63
- raise pe.BadStdStreamFile(fname, e)
71
+ raise pe.BadStdStreamFile(str(fname)) from e
64
72
  return fd
65
73
 
66
74
  std_out = open_std_fd('stdout')
@@ -78,16 +78,14 @@ class BadStdStreamFile(ParslError):
78
78
 
79
79
  Contains:
80
80
  reason(string)
81
- exception object
82
81
  """
83
82
 
84
- def __init__(self, reason: str, exception: Exception) -> None:
85
- super().__init__(reason, exception)
83
+ def __init__(self, reason: str) -> None:
84
+ super().__init__(reason)
86
85
  self._reason = reason
87
- self._exception = exception
88
86
 
89
87
  def __repr__(self) -> str:
90
- return "Bad Stream File: {} Exception: {}".format(self._reason, self._exception)
88
+ return "Bad Stream File: {}".format(self._reason)
91
89
 
92
90
  def __str__(self) -> str:
93
91
  return self.__repr__()
@@ -10,11 +10,12 @@ from parsl.executors.threads import ThreadPoolExecutor
10
10
  from parsl.errors import ConfigurationError
11
11
  from parsl.dataflow.taskrecord import TaskRecord
12
12
  from parsl.monitoring import MonitoringHub
13
+ from parsl.usage_tracking.api import UsageInformation
13
14
 
14
15
  logger = logging.getLogger(__name__)
15
16
 
16
17
 
17
- class Config(RepresentationMixin):
18
+ class Config(RepresentationMixin, UsageInformation):
18
19
  """
19
20
  Specification of Parsl configuration options.
20
21
 
@@ -50,6 +51,9 @@ class Config(RepresentationMixin):
50
51
  of 1.
51
52
  run_dir : str, optional
52
53
  Path to run directory. Default is 'runinfo'.
54
+ std_autopath : function, optional
55
+ Sets the function used to generate stdout/stderr specifications when parsl.AUTO_LOGPATH is used. If no function
56
+ is specified, generates paths that look like: ``rundir/NNN/task_logs/X/task_{id}_{name}{label}.{out/err}``
53
57
  strategy : str, optional
54
58
  Strategy to use for scaling blocks according to workflow needs. Can be 'simple', 'htex_auto_scale', 'none'
55
59
  or `None`.
@@ -89,6 +93,7 @@ class Config(RepresentationMixin):
89
93
  retries: int = 0,
90
94
  retry_handler: Optional[Callable[[Exception, TaskRecord], float]] = None,
91
95
  run_dir: str = 'runinfo',
96
+ std_autopath: Optional[Callable] = None,
92
97
  strategy: Optional[str] = 'simple',
93
98
  strategy_period: Union[float, int] = 5,
94
99
  max_idletime: float = 120.0,
@@ -129,6 +134,7 @@ class Config(RepresentationMixin):
129
134
  self.usage_tracking = usage_tracking
130
135
  self.initialize_logging = initialize_logging
131
136
  self.monitoring = monitoring
137
+ self.std_autopath: Optional[Callable] = std_autopath
132
138
 
133
139
  @property
134
140
  def executors(self) -> Sequence[ParslExecutor]:
@@ -144,3 +150,6 @@ class Config(RepresentationMixin):
144
150
  if len(duplicates) > 0:
145
151
  raise ConfigurationError('Executors must have unique labels ({})'.format(
146
152
  ', '.join(['label={}'.format(repr(d)) for d in duplicates])))
153
+
154
+ def get_usage_information(self):
155
+ return {"executors_len": len(self.executors)}
@@ -42,6 +42,12 @@ class ZipFileStaging(Staging):
42
42
  """
43
43
 
44
44
  def can_stage_out(self, file: File) -> bool:
45
+ return self.is_zip_url(file)
46
+
47
+ def can_stage_in(self, file: File) -> bool:
48
+ return self.is_zip_url(file)
49
+
50
+ def is_zip_url(self, file: File) -> bool:
45
51
  logger.debug("archive provider checking File {}".format(repr(file)))
46
52
 
47
53
  # First check if this is the scheme we care about
@@ -76,6 +82,20 @@ class ZipFileStaging(Staging):
76
82
  app_fut = stage_out_app(zip_path, inside_path, working_dir, inputs=[file], _parsl_staging_inhibit=True, parent_fut=parent_fut)
77
83
  return app_fut
78
84
 
85
+ def stage_in(self, dm, executor, file, parent_fut):
86
+ assert file.scheme == 'zip'
87
+
88
+ zip_path, inside_path = zip_path_split(file.path)
89
+
90
+ working_dir = dm.dfk.executors[executor].working_dir
91
+
92
+ if working_dir:
93
+ file.local_path = os.path.join(working_dir, inside_path)
94
+
95
+ stage_in_app = _zip_stage_in_app(dm)
96
+ app_fut = stage_in_app(zip_path, inside_path, working_dir, outputs=[file], _parsl_staging_inhibit=True, parent_fut=parent_fut)
97
+ return app_fut._outputs[0]
98
+
79
99
 
80
100
  def _zip_stage_out(zip_file, inside_path, working_dir, parent_fut=None, inputs=[], _parsl_staging_inhibit=True):
81
101
  file = inputs[0]
@@ -93,6 +113,18 @@ def _zip_stage_out_app(dm):
93
113
  return parsl.python_app(executors=['_parsl_internal'], data_flow_kernel=dm.dfk)(_zip_stage_out)
94
114
 
95
115
 
116
+ def _zip_stage_in(zip_file, inside_path, working_dir, *, parent_fut, outputs, _parsl_staging_inhibit=True):
117
+ with filelock.FileLock(zip_file + ".lock"):
118
+ with zipfile.ZipFile(zip_file, mode='r') as z:
119
+ content = z.read(inside_path)
120
+ with open(outputs[0], "wb") as of:
121
+ of.write(content)
122
+
123
+
124
+ def _zip_stage_in_app(dm):
125
+ return parsl.python_app(executors=['_parsl_internal'], data_flow_kernel=dm.dfk)(_zip_stage_in)
126
+
127
+
96
128
  def zip_path_split(path: str) -> Tuple[str, str]:
97
129
  """Split zip: path into a zipfile name and a contained-file name.
98
130
  """
@@ -219,14 +219,18 @@ class DataFlowKernel:
219
219
  task_log_info = self._create_task_log_info(task_record)
220
220
  self.monitoring.send(MessageType.TASK_INFO, task_log_info)
221
221
 
222
- def _create_task_log_info(self, task_record):
222
+ def _create_task_log_info(self, task_record: TaskRecord) -> Dict[str, Any]:
223
223
  """
224
224
  Create the dictionary that will be included in the log.
225
225
  """
226
226
  info_to_monitor = ['func_name', 'memoize', 'hashsum', 'fail_count', 'fail_cost', 'status',
227
227
  'id', 'time_invoked', 'try_time_launched', 'time_returned', 'try_time_returned', 'executor']
228
228
 
229
- task_log_info = {"task_" + k: task_record[k] for k in info_to_monitor}
229
+ # mypy cannot verify that these task_record[k] references are valid:
230
+ # They are valid if all entries in info_to_monitor are declared in the definition of TaskRecord
231
+ # This type: ignore[literal-required] asserts that fact.
232
+ task_log_info = {"task_" + k: task_record[k] for k in info_to_monitor} # type: ignore[literal-required]
233
+
230
234
  task_log_info['run_id'] = self.run_id
231
235
  task_log_info['try_id'] = task_record['try_id']
232
236
  task_log_info['timestamp'] = datetime.datetime.now()
@@ -238,33 +242,28 @@ class DataFlowKernel:
238
242
  task_log_info['task_inputs'] = str(task_record['kwargs'].get('inputs', None))
239
243
  task_log_info['task_outputs'] = str(task_record['kwargs'].get('outputs', None))
240
244
  task_log_info['task_stdin'] = task_record['kwargs'].get('stdin', None)
241
- stdout_spec = task_record['kwargs'].get('stdout', None)
242
- stderr_spec = task_record['kwargs'].get('stderr', None)
243
245
 
244
- # stdout and stderr strings are set to the filename if we can
245
- # interpret the specification; otherwise, set to the empty string
246
- # (on exception, or when not specified)
246
+ def std_spec_to_name(name, spec):
247
+ if spec is None:
248
+ name = ""
249
+ elif isinstance(spec, File):
250
+ name = spec.url
251
+ else:
252
+ # fallthrough case is various str, os.PathLike, tuple modes that
253
+ # can be interpreted by get_std_fname_mode.
254
+ try:
255
+ name, _ = get_std_fname_mode(name, spec)
256
+ except Exception:
257
+ logger.exception(f"Could not parse {name} specification {spec} for task {task_record['id']}")
258
+ name = ""
259
+ return name
247
260
 
248
- if stdout_spec is not None:
249
- try:
250
- stdout_name, _ = get_std_fname_mode('stdout', stdout_spec)
251
- except Exception:
252
- logger.exception("Could not parse stdout specification {} for task {}".format(stdout_spec, task_record['id']))
253
- stdout_name = ""
254
- else:
255
- stdout_name = ""
261
+ stdout_spec = task_record['kwargs'].get('stdout')
262
+ task_log_info['task_stdout'] = std_spec_to_name('stdout', stdout_spec)
256
263
 
257
- if stderr_spec is not None:
258
- try:
259
- stderr_name, _ = get_std_fname_mode('stderr', stderr_spec)
260
- except Exception:
261
- logger.exception("Could not parse stderr specification {} for task {}".format(stderr_spec, task_record['id']))
262
- stderr_name = ""
263
- else:
264
- stderr_name = ""
264
+ stderr_spec = task_record['kwargs'].get('stderr')
265
+ task_log_info['task_stderr'] = std_spec_to_name('stderr', stderr_spec)
265
266
 
266
- task_log_info['task_stdout'] = stdout_name
267
- task_log_info['task_stderr'] = stderr_name
268
267
  task_log_info['task_fail_history'] = ",".join(task_record['fail_history'])
269
268
  task_log_info['task_depends'] = None
270
269
  if task_record['depends'] is not None:
@@ -774,6 +773,10 @@ class DataFlowKernel:
774
773
  (inputs[idx], func) = self.data_manager.optionally_stage_in(f, func, executor)
775
774
 
776
775
  for kwarg, f in kwargs.items():
776
+ # stdout and stderr files should not be staging in (they will be staged *out*
777
+ # in _add_output_deps)
778
+ if kwarg in ['stdout', 'stderr']:
779
+ continue
777
780
  (kwargs[kwarg], func) = self.data_manager.optionally_stage_in(f, func, executor)
778
781
 
779
782
  newargs = list(args)
@@ -786,33 +789,55 @@ class DataFlowKernel:
786
789
  logger.debug("Adding output dependencies")
787
790
  outputs = kwargs.get('outputs', [])
788
791
  app_fut._outputs = []
789
- for idx, f in enumerate(outputs):
790
- if isinstance(f, File) and not self.check_staging_inhibited(kwargs):
792
+
793
+ # Pass over all possible outputs: the outputs kwarg, stdout and stderr
794
+ # and for each of those, perform possible stage-out. This can result in:
795
+ # a DataFuture to be exposed in app_fut to represent the completion of
796
+ # that stageout (sometimes backed by a new sub-workflow for separate-task
797
+ # stageout), a replacement for the function to be executed (intended to
798
+ # be the original function wrapped with an in-task stageout wrapper), a
799
+ # rewritten File object to be passed to task to be executed
800
+
801
+ def stageout_one_file(file: File, rewritable_func: Callable):
802
+ if not self.check_staging_inhibited(kwargs):
791
803
  # replace a File with a DataFuture - either completing when the stageout
792
804
  # future completes, or if no stage out future is returned, then when the
793
805
  # app itself completes.
794
806
 
795
807
  # The staging code will get a clean copy which it is allowed to mutate,
796
808
  # while the DataFuture-contained original will not be modified by any staging.
797
- f_copy = f.cleancopy()
798
- outputs[idx] = f_copy
809
+ f_copy = file.cleancopy()
799
810
 
800
- logger.debug("Submitting stage out for output file {}".format(repr(f)))
811
+ logger.debug("Submitting stage out for output file {}".format(repr(file)))
801
812
  stageout_fut = self.data_manager.stage_out(f_copy, executor, app_fut)
802
813
  if stageout_fut:
803
- logger.debug("Adding a dependency on stageout future for {}".format(repr(f)))
804
- app_fut._outputs.append(DataFuture(stageout_fut, f, tid=app_fut.tid))
814
+ logger.debug("Adding a dependency on stageout future for {}".format(repr(file)))
815
+ df = DataFuture(stageout_fut, file, tid=app_fut.tid)
805
816
  else:
806
- logger.debug("No stageout dependency for {}".format(repr(f)))
807
- app_fut._outputs.append(DataFuture(app_fut, f, tid=app_fut.tid))
817
+ logger.debug("No stageout dependency for {}".format(repr(file)))
818
+ df = DataFuture(app_fut, file, tid=app_fut.tid)
808
819
 
809
820
  # this is a hook for post-task stageout
810
821
  # note that nothing depends on the output - which is maybe a bug
811
822
  # in the not-very-tested stageout system?
812
- func = self.data_manager.replace_task_stage_out(f_copy, func, executor)
823
+ rewritable_func = self.data_manager.replace_task_stage_out(f_copy, rewritable_func, executor)
824
+ return rewritable_func, f_copy, df
813
825
  else:
814
- logger.debug("Not performing output staging for: {}".format(repr(f)))
815
- app_fut._outputs.append(DataFuture(app_fut, f, tid=app_fut.tid))
826
+ logger.debug("Not performing output staging for: {}".format(repr(file)))
827
+ return rewritable_func, file, DataFuture(app_fut, file, tid=app_fut.tid)
828
+
829
+ for idx, file in enumerate(outputs):
830
+ func, outputs[idx], o = stageout_one_file(file, func)
831
+ app_fut._outputs.append(o)
832
+
833
+ file = kwargs.get('stdout')
834
+ if isinstance(file, File):
835
+ func, kwargs['stdout'], app_fut._stdout_future = stageout_one_file(file, func)
836
+
837
+ file = kwargs.get('stderr')
838
+ if isinstance(file, File):
839
+ func, kwargs['stderr'], app_fut._stderr_future = stageout_one_file(file, func)
840
+
816
841
  return func
817
842
 
818
843
  def _gather_all_deps(self, args: Sequence[Any], kwargs: Dict[str, Any]) -> List[Future]:
@@ -970,32 +995,16 @@ class DataFlowKernel:
970
995
  executor = random.choice(choices)
971
996
  logger.debug("Task {} will be sent to executor {}".format(task_id, executor))
972
997
 
973
- # The below uses func.__name__ before it has been wrapped by any staging code.
974
-
975
- label = app_kwargs.get('label')
976
- for kw in ['stdout', 'stderr']:
977
- if kw in app_kwargs:
978
- if app_kwargs[kw] == parsl.AUTO_LOGNAME:
979
- if kw not in ignore_for_cache:
980
- ignore_for_cache += [kw]
981
- app_kwargs[kw] = os.path.join(
982
- self.run_dir,
983
- 'task_logs',
984
- str(int(task_id / 10000)).zfill(4), # limit logs to 10k entries per directory
985
- 'task_{}_{}{}.{}'.format(
986
- str(task_id).zfill(4),
987
- func.__name__,
988
- '' if label is None else '_{}'.format(label),
989
- kw)
990
- )
991
-
992
998
  resource_specification = app_kwargs.get('parsl_resource_specification', {})
993
999
 
994
1000
  task_record: TaskRecord
995
- task_record = {'depends': [],
1001
+ task_record = {'args': app_args,
1002
+ 'depends': [],
996
1003
  'dfk': self,
997
1004
  'executor': executor,
1005
+ 'func': func,
998
1006
  'func_name': func.__name__,
1007
+ 'kwargs': app_kwargs,
999
1008
  'memoize': cache,
1000
1009
  'hashsum': None,
1001
1010
  'exec_fu': None,
@@ -1017,18 +1026,30 @@ class DataFlowKernel:
1017
1026
 
1018
1027
  self.update_task_state(task_record, States.unsched)
1019
1028
 
1029
+ for kw in ['stdout', 'stderr']:
1030
+ if kw in app_kwargs:
1031
+ if app_kwargs[kw] == parsl.AUTO_LOGNAME:
1032
+ if kw not in ignore_for_cache:
1033
+ ignore_for_cache += [kw]
1034
+ if self.config.std_autopath is None:
1035
+ app_kwargs[kw] = self.default_std_autopath(task_record, kw)
1036
+ else:
1037
+ app_kwargs[kw] = self.config.std_autopath(task_record, kw)
1038
+
1020
1039
  app_fu = AppFuture(task_record)
1040
+ task_record['app_fu'] = app_fu
1021
1041
 
1022
1042
  # Transform remote input files to data futures
1023
1043
  app_args, app_kwargs, func = self._add_input_deps(executor, app_args, app_kwargs, func)
1024
1044
 
1025
1045
  func = self._add_output_deps(executor, app_args, app_kwargs, app_fu, func)
1026
1046
 
1047
+ # Replace the function invocation in the TaskRecord with whatever file-staging
1048
+ # substitutions have been made.
1027
1049
  task_record.update({
1028
1050
  'args': app_args,
1029
1051
  'func': func,
1030
- 'kwargs': app_kwargs,
1031
- 'app_fu': app_fu})
1052
+ 'kwargs': app_kwargs})
1032
1053
 
1033
1054
  assert task_id not in self.tasks
1034
1055
 
@@ -1140,8 +1161,6 @@ class DataFlowKernel:
1140
1161
  executor.hub_port = self.hub_zmq_port
1141
1162
  if self.monitoring:
1142
1163
  executor.monitoring_radio = self.monitoring.radio
1143
- else:
1144
- executor.monitoring_radio = None
1145
1164
  if hasattr(executor, 'provider'):
1146
1165
  if hasattr(executor.provider, 'script_dir'):
1147
1166
  executor.provider.script_dir = os.path.join(self.run_dir, 'submit_scripts')
@@ -1221,8 +1240,10 @@ class DataFlowKernel:
1221
1240
  self._checkpoint_timer.close()
1222
1241
 
1223
1242
  # Send final stats
1243
+ logger.info("Sending end message for usage tracking")
1224
1244
  self.usage_tracker.send_end_message()
1225
1245
  self.usage_tracker.close()
1246
+ logger.info("Closed usage tracking")
1226
1247
 
1227
1248
  logger.info("Closing job status poller")
1228
1249
  self.job_status_poller.close()
@@ -1402,14 +1423,33 @@ class DataFlowKernel:
1402
1423
  logger.info(f"{name} for task {tid} will not be redirected.")
1403
1424
  elif isinstance(target, str):
1404
1425
  logger.info(f"{name} for task {tid} will be redirected to {target}")
1405
- elif isinstance(target, tuple) and len(target) == 2:
1426
+ elif isinstance(target, os.PathLike):
1427
+ logger.info(f"{name} for task {tid} will be redirected to {os.fspath(target)}")
1428
+ elif isinstance(target, tuple) and len(target) == 2 and isinstance(target[0], str):
1406
1429
  logger.info(f"{name} for task {tid} will be redirected to {target[0]} with mode {target[1]}")
1430
+ elif isinstance(target, tuple) and len(target) == 2 and isinstance(target[0], os.PathLike):
1431
+ logger.info(f"{name} for task {tid} will be redirected to {os.fspath(target[0])} with mode {target[1]}")
1432
+ elif isinstance(target, DataFuture):
1433
+ logger.info(f"{name} for task {tid} will staged to {target.file_obj.url}")
1407
1434
  else:
1408
1435
  logger.error(f"{name} for task {tid} has unknown specification: {target!r}")
1409
1436
 
1410
1437
  log_std_stream("Standard out", task_record['app_fu'].stdout)
1411
1438
  log_std_stream("Standard error", task_record['app_fu'].stderr)
1412
1439
 
1440
+ def default_std_autopath(self, taskrecord, kw):
1441
+ label = taskrecord['kwargs'].get('label')
1442
+ task_id = taskrecord['id']
1443
+ return os.path.join(
1444
+ self.run_dir,
1445
+ 'task_logs',
1446
+ str(int(task_id / 10000)).zfill(4), # limit logs to 10k entries per directory
1447
+ 'task_{}_{}{}.{}'.format(
1448
+ str(task_id).zfill(4),
1449
+ taskrecord['func_name'],
1450
+ '' if label is None else '_{}'.format(label),
1451
+ kw))
1452
+
1413
1453
 
1414
1454
  class DataFlowKernelLoader:
1415
1455
  """Manage which DataFlowKernel is active.
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from concurrent.futures import Future
4
4
  import logging
5
5
  import threading
6
- from typing import Any, Optional, Sequence
6
+ from typing import Any, Optional, Sequence, Union
7
7
 
8
8
  import parsl.app.app as app
9
9
 
@@ -70,13 +70,34 @@ class AppFuture(Future):
70
70
  self._outputs = []
71
71
  self.task_record = task_record
72
72
 
73
+ self._stdout_future: Optional[DataFuture] = None
74
+ self._stderr_future: Optional[DataFuture] = None
75
+
73
76
  @property
74
- def stdout(self) -> Optional[str]:
75
- return self.task_record['kwargs'].get('stdout')
77
+ def stdout(self) -> Union[None, str, DataFuture]:
78
+ """Return app stdout. If stdout was specified as a string, then this
79
+ property will return that string. If stdout was specified as a File,
80
+ then this property will return a DataFuture representing that file
81
+ stageout.
82
+ TODO: this can be a tuple too I think?"""
83
+ if self._stdout_future:
84
+ return self._stdout_future
85
+ else:
86
+ # this covers the str and None cases
87
+ return self.task_record['kwargs'].get('stdout')
76
88
 
77
89
  @property
78
- def stderr(self) -> Optional[str]:
79
- return self.task_record['kwargs'].get('stderr')
90
+ def stderr(self) -> Union[None, str, DataFuture]:
91
+ """Return app stderr. If stdout was specified as a string, then this
92
+ property will return that string. If stdout was specified as a File,
93
+ then this property will return a DataFuture representing that file
94
+ stageout.
95
+ TODO: this can be a tuple too I think?"""
96
+ if self._stderr_future:
97
+ return self._stderr_future
98
+ else:
99
+ # this covers the str and None cases
100
+ return self.task_record['kwargs'].get('stderr')
80
101
 
81
102
  @property
82
103
  def tid(self) -> int:
@@ -1,3 +1,4 @@
1
+ import os
1
2
  from abc import ABCMeta, abstractmethod
2
3
  from concurrent.futures import Future
3
4
  from typing import Any, Callable, Dict, Optional
@@ -45,6 +46,21 @@ class ParslExecutor(metaclass=ABCMeta):
45
46
  label: str = "undefined"
46
47
  radio_mode: str = "udp"
47
48
 
49
+ def __init__(
50
+ self,
51
+ *,
52
+ hub_address: Optional[str] = None,
53
+ hub_port: Optional[int] = None,
54
+ monitoring_radio: Optional[MonitoringRadio] = None,
55
+ run_dir: str = ".",
56
+ run_id: Optional[str] = None,
57
+ ):
58
+ self.hub_address = hub_address
59
+ self.hub_port = hub_port
60
+ self.monitoring_radio = monitoring_radio
61
+ self.run_dir = os.path.abspath(run_dir)
62
+ self.run_id = run_id
63
+
48
64
  def __enter__(self) -> Self:
49
65
  return self
50
66
 
@@ -14,6 +14,7 @@ import math
14
14
  import warnings
15
15
 
16
16
  import parsl.launchers
17
+ from parsl.usage_tracking.api import UsageInformation
17
18
  from parsl.serialize import pack_res_spec_apply_message, deserialize
18
19
  from parsl.serialize.errors import SerializationError, DeserializationError
19
20
  from parsl.app.errors import RemoteExceptionWrapper
@@ -62,7 +63,7 @@ DEFAULT_LAUNCH_CMD = ("process_worker_pool.py {debug} {max_workers_per_node} "
62
63
  "--available-accelerators {accelerators}")
63
64
 
64
65
 
65
- class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
66
+ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageInformation):
66
67
  """Executor designed for cluster-scale
67
68
 
68
69
  The HighThroughputExecutor system has the following components:
@@ -818,4 +819,9 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
818
819
  logger.info("Unable to terminate Interchange process; sending SIGKILL")
819
820
  self.interchange_proc.kill()
820
821
 
822
+ self.interchange_proc.close()
823
+
821
824
  logger.info("Finished HighThroughputExecutor shutdown attempt")
825
+
826
+ def get_usage_information(self):
827
+ return {"mpi": self.enable_mpi_mode}
@@ -644,6 +644,12 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
644
644
  logger.debug("Joining on factory process")
645
645
  self._factory_process.join()
646
646
 
647
+ # Shutdown multiprocessing queues
648
+ self._ready_task_queue.close()
649
+ self._ready_task_queue.join_thread()
650
+ self._finished_task_queue.close()
651
+ self._finished_task_queue.join_thread()
652
+
647
653
  self._is_shutdown = True
648
654
  logger.debug("TaskVine shutdown completed")
649
655
 
@@ -735,6 +735,12 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
735
735
  logger.debug("Joining on collector thread")
736
736
  self.collector_thread.join()
737
737
 
738
+ logger.debug("Closing multiprocessing queues")
739
+ self.task_queue.close()
740
+ self.task_queue.join_thread()
741
+ self.collector_queue.close()
742
+ self.collector_queue.join_thread()
743
+
738
744
  self.is_shutdown = True
739
745
  logger.debug("Work Queue shutdown completed")
740
746
 
@@ -195,6 +195,8 @@ class MonitoringHub(RepresentationMixin):
195
195
 
196
196
  try:
197
197
  comm_q_result = comm_q.get(block=True, timeout=120)
198
+ comm_q.close()
199
+ comm_q.join_thread()
198
200
  except queue.Empty:
199
201
  logger.error("Hub has not completed initialization in 120s. Aborting")
200
202
  raise Exception("Hub failed to start")
@@ -258,6 +260,19 @@ class MonitoringHub(RepresentationMixin):
258
260
  self.filesystem_proc.terminate()
259
261
  self.filesystem_proc.join()
260
262
 
263
+ logger.info("Closing monitoring multiprocessing queues")
264
+ self.exception_q.close()
265
+ self.exception_q.join_thread()
266
+ self.priority_msgs.close()
267
+ self.priority_msgs.join_thread()
268
+ self.resource_msgs.close()
269
+ self.resource_msgs.join_thread()
270
+ self.node_msgs.close()
271
+ self.node_msgs.join_thread()
272
+ self.block_msgs.close()
273
+ self.block_msgs.join_thread()
274
+ logger.info("Closed monitoring multiprocessing queues")
275
+
261
276
 
262
277
  @wrap_with_logs
263
278
  def filesystem_receiver(logdir: str, q: "queue.Queue[AddressedMonitoringMessage]", run_dir: str) -> None:
@@ -105,7 +105,26 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
105
105
  if not _kubernetes_enabled:
106
106
  raise OptionalModuleMissing(['kubernetes'],
107
107
  "Kubernetes provider requires kubernetes module and config.")
108
- config.load_kube_config()
108
+ try:
109
+ config.load_kube_config()
110
+ except config.config_exception.ConfigException:
111
+ # `load_kube_config` assumes a local kube-config file, and fails if not
112
+ # present, raising:
113
+ #
114
+ # kubernetes.config.config_exception.ConfigException: Invalid
115
+ # kube-config file. No configuration found.
116
+ #
117
+ # Since running a parsl driver script on a kubernetes cluster is a common
118
+ # pattern to enable worker-interchange communication, this enables an
119
+ # in-cluster config to be loaded if a kube-config file isn't found.
120
+ #
121
+ # Based on: https://github.com/kubernetes-client/python/issues/1005
122
+ try:
123
+ config.load_incluster_config()
124
+ except config.config_exception.ConfigException:
125
+ raise config.config_exception.ConfigException(
126
+ "Failed to load both kube-config file and in-cluster configuration."
127
+ )
109
128
 
110
129
  self.namespace = namespace
111
130
  self.image = image
@@ -0,0 +1,11 @@
1
+ from parsl.config import Config
2
+ from parsl.executors.threads import ThreadPoolExecutor
3
+
4
+
5
+ def fresh_config():
6
+ tpe = ThreadPoolExecutor(label='local_threads_checkpoint_periodic', max_threads=1)
7
+ return Config(
8
+ executors=[tpe],
9
+ checkpoint_mode='periodic',
10
+ checkpoint_period='00:00:02'
11
+ )