parsl 2024.5.27__py3-none-any.whl → 2024.6.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. parsl/__init__.py +9 -10
  2. parsl/addresses.py +6 -4
  3. parsl/app/app.py +3 -6
  4. parsl/app/bash.py +4 -4
  5. parsl/app/errors.py +5 -3
  6. parsl/app/futures.py +3 -3
  7. parsl/app/python.py +2 -1
  8. parsl/benchmark/perf.py +2 -1
  9. parsl/channels/__init__.py +2 -2
  10. parsl/channels/base.py +0 -1
  11. parsl/channels/errors.py +2 -1
  12. parsl/channels/oauth_ssh/oauth_ssh.py +4 -3
  13. parsl/channels/ssh/ssh.py +9 -1
  14. parsl/channels/ssh_il/ssh_il.py +1 -0
  15. parsl/concurrent/__init__.py +2 -2
  16. parsl/config.py +32 -9
  17. parsl/configs/ASPIRE1.py +3 -3
  18. parsl/configs/Azure.py +6 -7
  19. parsl/configs/ad_hoc.py +4 -3
  20. parsl/configs/bridges.py +3 -3
  21. parsl/configs/cc_in2p3.py +2 -2
  22. parsl/configs/ec2.py +1 -1
  23. parsl/configs/expanse.py +1 -2
  24. parsl/configs/frontera.py +2 -3
  25. parsl/configs/htex_local.py +1 -2
  26. parsl/configs/illinoiscluster.py +1 -1
  27. parsl/configs/kubernetes.py +1 -2
  28. parsl/configs/midway.py +3 -3
  29. parsl/configs/osg.py +1 -1
  30. parsl/configs/polaris.py +1 -1
  31. parsl/configs/stampede2.py +4 -5
  32. parsl/configs/summit.py +1 -3
  33. parsl/configs/toss3_llnl.py +1 -2
  34. parsl/configs/vineex_local.py +3 -3
  35. parsl/configs/wqex_local.py +2 -2
  36. parsl/data_provider/data_manager.py +3 -3
  37. parsl/data_provider/file_noop.py +1 -2
  38. parsl/data_provider/files.py +3 -3
  39. parsl/data_provider/ftp.py +1 -3
  40. parsl/data_provider/globus.py +7 -6
  41. parsl/data_provider/http.py +2 -2
  42. parsl/data_provider/rsync.py +1 -1
  43. parsl/data_provider/staging.py +2 -2
  44. parsl/data_provider/zip.py +4 -5
  45. parsl/dataflow/dflow.py +57 -26
  46. parsl/dataflow/errors.py +2 -1
  47. parsl/dataflow/futures.py +1 -2
  48. parsl/dataflow/memoization.py +5 -5
  49. parsl/dataflow/rundirs.py +1 -1
  50. parsl/dataflow/taskrecord.py +4 -5
  51. parsl/executors/__init__.py +3 -3
  52. parsl/executors/base.py +1 -0
  53. parsl/executors/flux/execute_parsl_task.py +2 -2
  54. parsl/executors/flux/executor.py +11 -12
  55. parsl/executors/flux/flux_instance_manager.py +3 -3
  56. parsl/executors/high_throughput/executor.py +31 -36
  57. parsl/executors/high_throughput/interchange.py +37 -38
  58. parsl/executors/high_throughput/manager_record.py +1 -0
  59. parsl/executors/high_throughput/monitoring_info.py +2 -1
  60. parsl/executors/high_throughput/mpi_executor.py +5 -2
  61. parsl/executors/high_throughput/mpi_prefix_composer.py +1 -1
  62. parsl/executors/high_throughput/mpi_resource_management.py +1 -2
  63. parsl/executors/high_throughput/probe.py +6 -4
  64. parsl/executors/high_throughput/process_worker_pool.py +31 -20
  65. parsl/executors/high_throughput/zmq_pipes.py +28 -14
  66. parsl/executors/radical/executor.py +15 -15
  67. parsl/executors/radical/rpex_master.py +1 -2
  68. parsl/executors/radical/rpex_resources.py +1 -2
  69. parsl/executors/radical/rpex_worker.py +2 -1
  70. parsl/executors/status_handling.py +5 -4
  71. parsl/executors/taskvine/__init__.py +1 -1
  72. parsl/executors/taskvine/errors.py +1 -1
  73. parsl/executors/taskvine/exec_parsl_function.py +2 -2
  74. parsl/executors/taskvine/executor.py +23 -24
  75. parsl/executors/taskvine/factory.py +1 -1
  76. parsl/executors/taskvine/manager.py +11 -13
  77. parsl/executors/threads.py +4 -5
  78. parsl/executors/workqueue/errors.py +1 -1
  79. parsl/executors/workqueue/exec_parsl_function.py +5 -4
  80. parsl/executors/workqueue/executor.py +26 -27
  81. parsl/executors/workqueue/parsl_coprocess.py +1 -1
  82. parsl/jobs/error_handlers.py +1 -1
  83. parsl/jobs/job_status_poller.py +2 -5
  84. parsl/jobs/states.py +1 -1
  85. parsl/jobs/strategy.py +2 -2
  86. parsl/launchers/__init__.py +12 -3
  87. parsl/launchers/errors.py +1 -1
  88. parsl/log_utils.py +1 -2
  89. parsl/monitoring/db_manager.py +16 -10
  90. parsl/monitoring/monitoring.py +11 -15
  91. parsl/monitoring/queries/pandas.py +1 -2
  92. parsl/monitoring/radios.py +2 -4
  93. parsl/monitoring/remote.py +13 -8
  94. parsl/monitoring/router.py +8 -11
  95. parsl/monitoring/types.py +2 -0
  96. parsl/monitoring/visualization/app.py +4 -2
  97. parsl/monitoring/visualization/models.py +0 -1
  98. parsl/monitoring/visualization/plots/default/workflow_plots.py +8 -4
  99. parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
  100. parsl/monitoring/visualization/utils.py +0 -1
  101. parsl/monitoring/visualization/views.py +16 -9
  102. parsl/multiprocessing.py +0 -1
  103. parsl/process_loggers.py +1 -2
  104. parsl/providers/__init__.py +9 -12
  105. parsl/providers/ad_hoc/ad_hoc.py +1 -1
  106. parsl/providers/aws/aws.py +2 -3
  107. parsl/providers/azure/azure.py +4 -5
  108. parsl/providers/base.py +1 -1
  109. parsl/providers/cluster_provider.py +1 -1
  110. parsl/providers/cobalt/cobalt.py +3 -3
  111. parsl/providers/condor/condor.py +4 -2
  112. parsl/providers/errors.py +2 -2
  113. parsl/providers/googlecloud/googlecloud.py +2 -1
  114. parsl/providers/grid_engine/grid_engine.py +2 -2
  115. parsl/providers/kubernetes/kube.py +24 -9
  116. parsl/providers/local/local.py +5 -1
  117. parsl/providers/lsf/lsf.py +2 -2
  118. parsl/providers/pbspro/pbspro.py +1 -1
  119. parsl/providers/slurm/slurm.py +36 -27
  120. parsl/providers/torque/torque.py +1 -1
  121. parsl/serialize/__init__.py +8 -3
  122. parsl/serialize/base.py +1 -2
  123. parsl/serialize/concretes.py +5 -4
  124. parsl/serialize/proxystore.py +3 -2
  125. parsl/tests/__init__.py +1 -1
  126. parsl/tests/configs/ad_hoc_cluster_htex.py +4 -4
  127. parsl/tests/configs/azure_single_node.py +4 -5
  128. parsl/tests/configs/bridges.py +3 -2
  129. parsl/tests/configs/cc_in2p3.py +2 -2
  130. parsl/tests/configs/comet.py +2 -1
  131. parsl/tests/configs/ec2_single_node.py +1 -2
  132. parsl/tests/configs/ec2_spot.py +1 -2
  133. parsl/tests/configs/flux_local.py +11 -0
  134. parsl/tests/configs/frontera.py +3 -2
  135. parsl/tests/configs/htex_ad_hoc_cluster.py +2 -4
  136. parsl/tests/configs/htex_local.py +2 -3
  137. parsl/tests/configs/htex_local_alternate.py +8 -11
  138. parsl/tests/configs/htex_local_intask_staging.py +5 -7
  139. parsl/tests/configs/htex_local_rsync_staging.py +4 -6
  140. parsl/tests/configs/local_adhoc.py +1 -1
  141. parsl/tests/configs/local_radical.py +1 -3
  142. parsl/tests/configs/local_radical_mpi.py +2 -2
  143. parsl/tests/configs/midway.py +2 -2
  144. parsl/tests/configs/nscc_singapore.py +3 -3
  145. parsl/tests/configs/osg_htex.py +1 -1
  146. parsl/tests/configs/petrelkube.py +3 -2
  147. parsl/tests/configs/summit.py +1 -0
  148. parsl/tests/configs/swan_htex.py +2 -2
  149. parsl/tests/configs/taskvine_ex.py +3 -5
  150. parsl/tests/configs/theta.py +2 -2
  151. parsl/tests/configs/workqueue_ex.py +3 -4
  152. parsl/tests/conftest.py +8 -4
  153. parsl/tests/integration/test_channels/test_ssh_errors.py +1 -1
  154. parsl/tests/integration/test_stress/test_python_simple.py +3 -4
  155. parsl/tests/integration/test_stress/test_python_threads.py +3 -5
  156. parsl/tests/manual_tests/htex_local.py +4 -4
  157. parsl/tests/manual_tests/test_ad_hoc_htex.py +2 -1
  158. parsl/tests/manual_tests/test_basic.py +1 -0
  159. parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +4 -4
  160. parsl/tests/manual_tests/test_log_filter.py +3 -1
  161. parsl/tests/manual_tests/test_memory_limits.py +6 -6
  162. parsl/tests/manual_tests/test_regression_220.py +2 -1
  163. parsl/tests/manual_tests/test_udp_simple.py +4 -3
  164. parsl/tests/manual_tests/test_worker_count.py +3 -2
  165. parsl/tests/scaling_tests/htex_local.py +2 -2
  166. parsl/tests/scaling_tests/test_scale.py +0 -9
  167. parsl/tests/scaling_tests/vineex_condor.py +1 -2
  168. parsl/tests/scaling_tests/vineex_local.py +1 -2
  169. parsl/tests/site_tests/test_provider.py +3 -1
  170. parsl/tests/site_tests/test_site.py +2 -0
  171. parsl/tests/sites/test_affinity.py +7 -5
  172. parsl/tests/sites/test_dynamic_executor.py +3 -3
  173. parsl/tests/sites/test_ec2.py +3 -2
  174. parsl/tests/sites/test_local_adhoc.py +2 -1
  175. parsl/tests/sites/test_worker_info.py +4 -3
  176. parsl/tests/test_aalst_patterns.py +0 -1
  177. parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
  178. parsl/tests/test_bash_apps/test_error_codes.py +1 -4
  179. parsl/tests/test_bash_apps/test_memoize_ignore_args.py +1 -0
  180. parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +2 -2
  181. parsl/tests/test_bash_apps/test_pipeline.py +1 -1
  182. parsl/tests/test_bash_apps/test_std_uri.py +4 -3
  183. parsl/tests/test_bash_apps/test_stdout.py +20 -2
  184. parsl/tests/test_callables.py +2 -2
  185. parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
  186. parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -1
  187. parsl/tests/test_checkpointing/test_regression_239.py +1 -1
  188. parsl/tests/test_checkpointing/test_task_exit.py +1 -1
  189. parsl/tests/test_docs/test_from_slides.py +2 -2
  190. parsl/tests/test_docs/test_kwargs.py +1 -1
  191. parsl/tests/test_docs/test_tutorial_1.py +1 -2
  192. parsl/tests/test_docs/test_workflow1.py +2 -2
  193. parsl/tests/test_docs/test_workflow2.py +0 -1
  194. parsl/tests/test_error_handling/test_rand_fail.py +2 -2
  195. parsl/tests/test_error_handling/test_resource_spec.py +4 -2
  196. parsl/tests/test_error_handling/test_retries.py +2 -1
  197. parsl/tests/test_error_handling/test_retry_handler.py +1 -0
  198. parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
  199. parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
  200. parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
  201. parsl/tests/test_flux.py +1 -1
  202. parsl/tests/test_htex/test_command_client_timeout.py +9 -12
  203. parsl/tests/test_htex/test_connected_blocks.py +3 -2
  204. parsl/tests/test_htex/test_cpu_affinity_explicit.py +5 -2
  205. parsl/tests/test_htex/test_disconnected_blocks.py +6 -4
  206. parsl/tests/test_htex/test_drain.py +5 -5
  207. parsl/tests/test_htex/test_htex.py +1 -2
  208. parsl/tests/test_htex/test_managers_command.py +3 -2
  209. parsl/tests/test_htex/test_multiple_disconnected_blocks.py +6 -4
  210. parsl/tests/test_htex/test_zmq_binding.py +22 -6
  211. parsl/tests/test_monitoring/test_app_names.py +3 -2
  212. parsl/tests/test_monitoring/test_basic.py +4 -4
  213. parsl/tests/test_monitoring/test_db_locks.py +6 -3
  214. parsl/tests/test_monitoring/test_fuzz_zmq.py +6 -3
  215. parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +5 -5
  216. parsl/tests/test_monitoring/test_incomplete_futures.py +5 -3
  217. parsl/tests/test_monitoring/test_memoization_representation.py +4 -1
  218. parsl/tests/test_monitoring/test_stdouterr.py +4 -4
  219. parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
  220. parsl/tests/test_mpi_apps/test_bad_mpi_config.py +1 -1
  221. parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +2 -0
  222. parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +7 -5
  223. parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
  224. parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
  225. parsl/tests/test_mpi_apps/test_mpiex.py +4 -3
  226. parsl/tests/test_mpi_apps/test_resource_spec.py +9 -10
  227. parsl/tests/test_providers/test_cobalt_deprecation_warning.py +2 -0
  228. parsl/tests/test_providers/test_local_provider.py +2 -1
  229. parsl/tests/test_providers/test_pbspro_template.py +1 -1
  230. parsl/tests/test_providers/test_slurm_template.py +1 -1
  231. parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
  232. parsl/tests/test_python_apps/test_context_manager.py +99 -3
  233. parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
  234. parsl/tests/test_python_apps/test_dependencies_deep.py +59 -0
  235. parsl/tests/test_python_apps/test_futures.py +2 -1
  236. parsl/tests/test_python_apps/test_join.py +0 -1
  237. parsl/tests/test_python_apps/test_lifted.py +3 -3
  238. parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
  239. parsl/tests/test_python_apps/test_pluggable_future_resolution.py +1 -1
  240. parsl/tests/test_radical/test_mpi_funcs.py +1 -2
  241. parsl/tests/test_regression/test_1480.py +2 -1
  242. parsl/tests/test_regression/test_1653.py +2 -1
  243. parsl/tests/test_regression/test_2652.py +1 -0
  244. parsl/tests/test_regression/test_69a.py +0 -1
  245. parsl/tests/test_regression/test_854.py +4 -2
  246. parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
  247. parsl/tests/test_regression/test_98.py +0 -1
  248. parsl/tests/test_scaling/test_block_error_handler.py +9 -4
  249. parsl/tests/test_scaling/test_scale_down.py +2 -3
  250. parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +4 -5
  251. parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +3 -4
  252. parsl/tests/test_scaling/test_shutdown_scalein.py +1 -2
  253. parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
  254. parsl/tests/test_serialization/test_basic.py +2 -1
  255. parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
  256. parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
  257. parsl/tests/test_serialization/test_proxystore_configured.py +10 -5
  258. parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
  259. parsl/tests/test_shutdown/test_kill_monitoring.py +3 -2
  260. parsl/tests/test_staging/staging_provider.py +2 -2
  261. parsl/tests/test_staging/test_1316.py +3 -2
  262. parsl/tests/test_staging/test_docs_1.py +1 -1
  263. parsl/tests/test_staging/test_docs_2.py +2 -1
  264. parsl/tests/test_staging/test_elaborate_noop_file.py +2 -2
  265. parsl/tests/test_staging/test_staging_https.py +2 -2
  266. parsl/tests/test_staging/test_staging_stdout.py +4 -3
  267. parsl/tests/test_staging/test_zip_in.py +6 -8
  268. parsl/tests/test_staging/test_zip_out.py +7 -9
  269. parsl/tests/test_staging/test_zip_to_zip.py +6 -8
  270. parsl/tests/test_summary.py +2 -1
  271. parsl/tests/test_thread_parallelism.py +0 -1
  272. parsl/tests/test_threads/test_configs.py +1 -1
  273. parsl/tests/test_threads/test_lazy_errors.py +2 -1
  274. parsl/tests/unit/test_usage_tracking.py +45 -0
  275. parsl/usage_tracking/api.py +2 -3
  276. parsl/usage_tracking/levels.py +6 -0
  277. parsl/usage_tracking/usage.py +60 -39
  278. parsl/utils.py +13 -2
  279. parsl/version.py +1 -1
  280. {parsl-2024.5.27.data → parsl-2024.6.10.data}/scripts/exec_parsl_function.py +5 -4
  281. {parsl-2024.5.27.data → parsl-2024.6.10.data}/scripts/process_worker_pool.py +31 -20
  282. {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/METADATA +2 -2
  283. parsl-2024.6.10.dist-info/RECORD +475 -0
  284. parsl-2024.5.27.dist-info/RECORD +0 -471
  285. {parsl-2024.5.27.data → parsl-2024.6.10.data}/scripts/parsl_coprocess.py +1 -1
  286. {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/LICENSE +0 -0
  287. {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/WHEEL +0 -0
  288. {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/entry_points.txt +0 -0
  289. {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/top_level.txt +0 -0
@@ -2,20 +2,22 @@ import logging
2
2
  import os
3
3
  import re
4
4
  import time
5
+
5
6
  import typeguard
6
7
 
7
8
  from parsl.channels import LocalChannel
8
9
  from parsl.jobs.states import JobState, JobStatus
9
- from parsl.utils import RepresentationMixin
10
10
  from parsl.launchers import SingleNodeLauncher
11
11
  from parsl.launchers.base import Launcher
12
- from parsl.providers.condor.template import template_string
13
12
  from parsl.providers.cluster_provider import ClusterProvider
13
+ from parsl.providers.condor.template import template_string
14
14
  from parsl.providers.errors import ScaleOutFailed
15
+ from parsl.utils import RepresentationMixin
15
16
 
16
17
  logger = logging.getLogger(__name__)
17
18
 
18
19
  from typing import Dict, List, Optional
20
+
19
21
  from parsl.channels.base import Channel
20
22
 
21
23
  # See http://pages.cs.wisc.edu/~adesmet/status.html
parsl/providers/errors.py CHANGED
@@ -1,7 +1,7 @@
1
- from parsl.errors import ParslError
2
-
3
1
  import warnings
4
2
 
3
+ from parsl.errors import ParslError
4
+
5
5
 
6
6
  class ExecutionProviderException(ParslError):
7
7
  """ Base class for all exceptions
@@ -1,8 +1,9 @@
1
1
  import atexit
2
2
  import logging
3
3
  import os
4
- from parsl.launchers import SingleNodeLauncher
4
+
5
5
  from parsl.jobs.states import JobState, JobStatus
6
+ from parsl.launchers import SingleNodeLauncher
6
7
 
7
8
  logger = logging.getLogger(__name__)
8
9
 
@@ -3,10 +3,10 @@ import os
3
3
  import time
4
4
 
5
5
  from parsl.channels import LocalChannel
6
+ from parsl.jobs.states import JobState, JobStatus
7
+ from parsl.launchers import SingleNodeLauncher
6
8
  from parsl.providers.cluster_provider import ClusterProvider
7
9
  from parsl.providers.grid_engine.template import template_string
8
- from parsl.launchers import SingleNodeLauncher
9
- from parsl.jobs.states import JobState, JobStatus
10
10
  from parsl.utils import RepresentationMixin
11
11
 
12
12
  logger = logging.getLogger(__name__)
@@ -1,17 +1,19 @@
1
1
  import logging
2
2
  import time
3
+
3
4
  from parsl.providers.kubernetes.template import template_string
4
5
 
5
6
  logger = logging.getLogger(__name__)
6
7
 
8
+ from typing import Any, Dict, List, Optional, Tuple
9
+
10
+ import typeguard
11
+
7
12
  from parsl.errors import OptionalModuleMissing
8
13
  from parsl.jobs.states import JobState, JobStatus
9
14
  from parsl.providers.base import ExecutionProvider
10
15
  from parsl.utils import RepresentationMixin
11
16
 
12
- import typeguard
13
- from typing import Any, Dict, List, Optional, Tuple
14
-
15
17
  try:
16
18
  from kubernetes import client, config
17
19
  _kubernetes_enabled = True
@@ -81,6 +83,10 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
81
83
  persistent_volumes: list[(str, str)]
82
84
  List of tuples describing persistent volumes to be mounted in the pod.
83
85
  The tuples consist of (PVC Name, Mount Directory).
86
+ service_account_name: str
87
+ Name of the service account to run the pod as.
88
+ annotations: Dict[str, str]
89
+ Annotations to set on the pod.
84
90
  """
85
91
  @typeguard.typechecked
86
92
  def __init__(self,
@@ -101,7 +107,9 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
101
107
  group_id: Optional[str] = None,
102
108
  run_as_non_root: bool = False,
103
109
  secret: Optional[str] = None,
104
- persistent_volumes: List[Tuple[str, str]] = []) -> None:
110
+ persistent_volumes: List[Tuple[str, str]] = [],
111
+ service_account_name: Optional[str] = None,
112
+ annotations: Optional[Dict[str, str]] = None) -> None:
105
113
  if not _kubernetes_enabled:
106
114
  raise OptionalModuleMissing(['kubernetes'],
107
115
  "Kubernetes provider requires kubernetes module and config.")
@@ -144,6 +152,8 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
144
152
  self.group_id = group_id
145
153
  self.run_as_non_root = run_as_non_root
146
154
  self.persistent_volumes = persistent_volumes
155
+ self.service_account_name = service_account_name
156
+ self.annotations = annotations
147
157
 
148
158
  self.kube_client = client.CoreV1Api()
149
159
 
@@ -182,7 +192,9 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
182
192
  pod_name=pod_name,
183
193
  job_name=job_name,
184
194
  cmd_string=formatted_cmd,
185
- volumes=self.persistent_volumes)
195
+ volumes=self.persistent_volumes,
196
+ service_account_name=self.service_account_name,
197
+ annotations=self.annotations)
186
198
  self.resources[pod_name] = {'status': JobStatus(JobState.RUNNING)}
187
199
 
188
200
  return pod_name
@@ -251,7 +263,9 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
251
263
  job_name,
252
264
  port=80,
253
265
  cmd_string=None,
254
- volumes=[]):
266
+ volumes=[],
267
+ service_account_name=None,
268
+ annotations=None):
255
269
  """ Create a kubernetes pod for the job.
256
270
  Args:
257
271
  - image (string) : Docker image to launch
@@ -309,11 +323,12 @@ class KubernetesProvider(ExecutionProvider, RepresentationMixin):
309
323
  claim_name=volume[0])))
310
324
 
311
325
  metadata = client.V1ObjectMeta(name=pod_name,
312
- labels={"app": job_name})
326
+ labels={"app": job_name},
327
+ annotations=annotations)
313
328
  spec = client.V1PodSpec(containers=[container],
314
329
  image_pull_secrets=[secret],
315
- volumes=volume_defs
316
- )
330
+ volumes=volume_defs,
331
+ service_account_name=service_account_name)
317
332
 
318
333
  pod = client.V1Pod(spec=spec, metadata=metadata)
319
334
  api_response = self.kube_client.create_namespaced_pod(namespace=self.namespace,
@@ -6,7 +6,11 @@ from parsl.channels import LocalChannel
6
6
  from parsl.jobs.states import JobState, JobStatus
7
7
  from parsl.launchers import SingleNodeLauncher
8
8
  from parsl.providers.base import ExecutionProvider
9
- from parsl.providers.errors import SchedulerMissingArgs, ScriptPathError, SubmitException
9
+ from parsl.providers.errors import (
10
+ SchedulerMissingArgs,
11
+ ScriptPathError,
12
+ SubmitException,
13
+ )
10
14
  from parsl.utils import RepresentationMixin
11
15
 
12
16
  logger = logging.getLogger(__name__)
@@ -1,7 +1,7 @@
1
- import os
2
- import time
3
1
  import logging
4
2
  import math
3
+ import os
4
+ import time
5
5
 
6
6
  from parsl.channels import LocalChannel
7
7
  from parsl.jobs.states import JobState, JobStatus
@@ -1,7 +1,7 @@
1
+ import json
1
2
  import logging
2
3
  import os
3
4
  import time
4
- import json
5
5
 
6
6
  from parsl.channels import LocalChannel
7
7
  from parsl.jobs.states import JobState, JobStatus
@@ -1,12 +1,12 @@
1
- import os
2
- import math
3
- import time
4
1
  import logging
2
+ import math
3
+ import os
5
4
  import re
6
- import typeguard
7
-
5
+ import time
8
6
  from typing import Optional
9
7
 
8
+ import typeguard
9
+
10
10
  from parsl.channels import LocalChannel
11
11
  from parsl.channels.base import Channel
12
12
  from parsl.jobs.states import JobState, JobStatus
@@ -19,25 +19,29 @@ from parsl.utils import RepresentationMixin, wtime_to_minutes
19
19
 
20
20
  logger = logging.getLogger(__name__)
21
21
 
22
+ # From https://slurm.schedmd.com/sacct.html#SECTION_JOB-STATE-CODES
22
23
  translate_table = {
23
- 'PD': JobState.PENDING,
24
- 'R': JobState.RUNNING,
25
- 'CA': JobState.CANCELLED,
26
- 'CF': JobState.PENDING, # (configuring),
27
- 'CG': JobState.RUNNING, # (completing),
28
- 'CD': JobState.COMPLETED,
29
- 'F': JobState.FAILED, # (failed),
30
- 'TO': JobState.TIMEOUT, # (timeout),
31
- 'NF': JobState.FAILED, # (node failure),
32
- 'RV': JobState.FAILED, # (revoked) and
33
- 'SE': JobState.FAILED # (special exit state)
24
+ 'PENDING': JobState.PENDING,
25
+ 'RUNNING': JobState.RUNNING,
26
+ 'CANCELLED': JobState.CANCELLED,
27
+ 'COMPLETED': JobState.COMPLETED,
28
+ 'FAILED': JobState.FAILED,
29
+ 'NODE_FAIL': JobState.FAILED,
30
+ 'BOOT_FAIL': JobState.FAILED,
31
+ 'DEADLINE': JobState.TIMEOUT,
32
+ 'TIMEOUT': JobState.TIMEOUT,
33
+ 'REVOKED': JobState.FAILED,
34
+ 'OUT_OF_MEMORY': JobState.FAILED,
35
+ 'SUSPENDED': JobState.HELD,
36
+ 'PREEMPTED': JobState.TIMEOUT,
37
+ 'REQUEUED': JobState.PENDING
34
38
  }
35
39
 
36
40
 
37
41
  class SlurmProvider(ClusterProvider, RepresentationMixin):
38
42
  """Slurm Execution Provider
39
43
 
40
- This provider uses sbatch to submit, squeue for status and scancel to cancel
44
+ This provider uses sbatch to submit, sacct for status and scancel to cancel
41
45
  jobs. The sbatch script to be used is created from a template file in this
42
46
  same module.
43
47
 
@@ -168,14 +172,16 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
168
172
  logger.debug('No active jobs, skipping status update')
169
173
  return
170
174
 
171
- cmd = "squeue --noheader --format='%i %t' --job '{0}'".format(job_id_list)
175
+ # Using state%20 to get enough characters to not truncate output
176
+ # of the state. Without output can look like "<job_id> CANCELLED+"
177
+ cmd = "sacct -X --noheader --format=jobid,state%20 --job '{0}'".format(job_id_list)
172
178
  logger.debug("Executing %s", cmd)
173
179
  retcode, stdout, stderr = self.execute_wait(cmd)
174
- logger.debug("squeue returned %s %s", stdout, stderr)
180
+ logger.debug("sacct returned %s %s", stdout, stderr)
175
181
 
176
182
  # Execute_wait failed. Do no update
177
183
  if retcode != 0:
178
- logger.warning("squeue failed with non-zero exit code {}".format(retcode))
184
+ logger.warning("sacct failed with non-zero exit code {}".format(retcode))
179
185
  return
180
186
 
181
187
  jobs_missing = set(self.resources.keys())
@@ -183,7 +189,10 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
183
189
  if not line:
184
190
  # Blank line
185
191
  continue
186
- job_id, slurm_state = line.split()
192
+ # Sacct includes extra information in some outputs
193
+ # For example "<job_id> CANCELLED by <user_id>"
194
+ # This splits and ignores anything past the first two unpacked values
195
+ job_id, slurm_state, *ignore = line.split()
187
196
  if slurm_state not in translate_table:
188
197
  logger.warning(f"Slurm status {slurm_state} is not recognized")
189
198
  status = translate_table.get(slurm_state, JobState.UNKNOWN)
@@ -193,13 +202,13 @@ class SlurmProvider(ClusterProvider, RepresentationMixin):
193
202
  stderr_path=self.resources[job_id]['job_stderr_path'])
194
203
  jobs_missing.remove(job_id)
195
204
 
196
- # squeue does not report on jobs that are not running. So we are filling in the
197
- # blanks for missing jobs, we might lose some information about why the jobs failed.
205
+ # sacct can get job info after jobs have completed so this path shouldn't be hit
206
+ # log a warning if there are missing jobs for some reason
198
207
  for missing_job in jobs_missing:
199
- logger.debug("Updating missing job {} to completed status".format(missing_job))
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'])
208
+ logger.warning("Updating missing job {} to completed status".format(missing_job))
209
+ self.resources[missing_job]['status'] = JobStatus(
210
+ JobState.COMPLETED, stdout_path=self.resources[missing_job]['job_stdout_path'],
211
+ stderr_path=self.resources[missing_job]['job_stderr_path'])
203
212
 
204
213
  def submit(self, command: str, tasks_per_node: int, job_name="parsl.slurm") -> str:
205
214
  """Submit the command as a slurm job.
@@ -5,8 +5,8 @@ import time
5
5
  from parsl.channels import LocalChannel
6
6
  from parsl.jobs.states import JobState, JobStatus
7
7
  from parsl.launchers import AprunLauncher
8
- from parsl.providers.torque.template import template_string
9
8
  from parsl.providers.cluster_provider import ClusterProvider
9
+ from parsl.providers.torque.template import template_string
10
10
  from parsl.utils import RepresentationMixin
11
11
 
12
12
  logger = logging.getLogger(__name__)
@@ -1,6 +1,11 @@
1
- from parsl.serialize.facade import (serialize, deserialize, pack_apply_message,
2
- unpack_apply_message, unpack_res_spec_apply_message,
3
- pack_res_spec_apply_message)
1
+ from parsl.serialize.facade import (
2
+ deserialize,
3
+ pack_apply_message,
4
+ pack_res_spec_apply_message,
5
+ serialize,
6
+ unpack_apply_message,
7
+ unpack_res_spec_apply_message,
8
+ )
4
9
 
5
10
  __all__ = ['serialize',
6
11
  'deserialize',
parsl/serialize/base.py CHANGED
@@ -1,7 +1,6 @@
1
+ import logging
1
2
  from abc import abstractmethod
2
3
  from functools import cached_property
3
- import logging
4
-
5
4
  from typing import Any
6
5
 
7
6
  logger = logging.getLogger(__name__)
@@ -1,13 +1,14 @@
1
- import dill
2
1
  import functools
3
- import pickle
4
2
  import logging
3
+ import pickle
5
4
 
6
- logger = logging.getLogger(__name__)
7
- from parsl.serialize.base import SerializerBase
5
+ import dill
8
6
 
7
+ logger = logging.getLogger(__name__)
9
8
  from typing import Any
10
9
 
10
+ from parsl.serialize.base import SerializerBase
11
+
11
12
 
12
13
  class PickleSerializer(SerializerBase):
13
14
  """ Pickle serialization covers most python objects, with some notable exceptions:
@@ -1,10 +1,11 @@
1
- import dill
2
1
  import io
3
2
  import typing as t
4
3
 
5
- from parsl.serialize.base import SerializerBase
4
+ import dill
6
5
  from proxystore.store import Store
7
6
 
7
+ from parsl.serialize.base import SerializerBase
8
+
8
9
 
9
10
  class ProxyStoreDeepPickler(dill.Pickler):
10
11
  """This class extends dill so that certain objects will be stored into
parsl/tests/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
- from parsl.dataflow.memoization import id_for_memo
2
1
  from parsl.data_provider.files import File
2
+ from parsl.dataflow.memoization import id_for_memo
3
3
 
4
4
 
5
5
  @id_for_memo.register(File)
@@ -1,9 +1,9 @@
1
- from parsl.providers import AdHocProvider
1
+ from typing import Any, Dict
2
+
2
3
  from parsl.channels import SSHChannel
3
- from parsl.executors import HighThroughputExecutor
4
4
  from parsl.config import Config
5
-
6
- from typing import Any, Dict
5
+ from parsl.executors import HighThroughputExecutor
6
+ from parsl.providers import AdHocProvider
7
7
 
8
8
  user_opts = {'adhoc':
9
9
  {'username': 'YOUR_USERNAME',
@@ -1,13 +1,12 @@
1
1
  """Config for Azure"""
2
- from parsl.providers import AzureProvider
2
+ import getpass
3
3
 
4
4
  from parsl.config import Config
5
- from parsl.executors import HighThroughputExecutor
6
- from parsl.data_provider.http import HTTPInTaskStaging
7
5
  from parsl.data_provider.ftp import FTPInTaskStaging
6
+ from parsl.data_provider.http import HTTPInTaskStaging
8
7
  from parsl.data_provider.rsync import RSyncStaging
9
-
10
- import getpass
8
+ from parsl.executors import HighThroughputExecutor
9
+ from parsl.providers import AzureProvider
11
10
 
12
11
  # If you are a developer running tests, make sure to update parsl/tests/configs/user_opts.py
13
12
  # If you are a user copying-and-pasting this as an example, make sure to either
@@ -1,7 +1,8 @@
1
1
  from parsl.config import Config
2
- from parsl.providers import SlurmProvider
3
- from parsl.launchers import SrunLauncher
4
2
  from parsl.executors import HighThroughputExecutor
3
+ from parsl.launchers import SrunLauncher
4
+ from parsl.providers import SlurmProvider
5
+
5
6
  from .user_opts import user_opts
6
7
 
7
8
 
@@ -1,7 +1,7 @@
1
- from parsl.config import Config
2
1
  from parsl.channels import LocalChannel
3
- from parsl.providers import GridEngineProvider
2
+ from parsl.config import Config
4
3
  from parsl.executors import HighThroughputExecutor
4
+ from parsl.providers import GridEngineProvider
5
5
 
6
6
  from .user_opts import user_opts
7
7
 
@@ -1,7 +1,8 @@
1
1
  from parsl.config import Config
2
+ from parsl.executors import HighThroughputExecutor
2
3
  from parsl.launchers import SrunLauncher
3
4
  from parsl.providers import SlurmProvider
4
- from parsl.executors import HighThroughputExecutor
5
+
5
6
  from .user_opts import user_opts
6
7
 
7
8
 
@@ -11,10 +11,9 @@ Block {Min:0, init:1, Max:1}
11
11
  ==================
12
12
 
13
13
  """
14
- from parsl.providers import AWSProvider
15
-
16
14
  from parsl.config import Config
17
15
  from parsl.executors import HighThroughputExecutor
16
+ from parsl.providers import AWSProvider
18
17
 
19
18
  # If you are a developer running tests, make sure to update parsl/tests/configs/user_opts.py
20
19
  # If you are a user copying-and-pasting this as an example, make sure to either
@@ -1,7 +1,6 @@
1
- from parsl.providers import AWSProvider
2
-
3
1
  from parsl.config import Config
4
2
  from parsl.executors import HighThroughputExecutor
3
+ from parsl.providers import AWSProvider
5
4
 
6
5
  # If you are a developer running tests, make sure to update parsl/tests/configs/user_opts.py
7
6
  # If you are a user copying-and-pasting this as an example, make sure to either
@@ -0,0 +1,11 @@
1
+ from parsl.config import Config
2
+ from parsl.executors import FluxExecutor
3
+
4
+
5
+ def fresh_config():
6
+ return Config(
7
+ executors=[FluxExecutor()],
8
+ )
9
+
10
+
11
+ config = fresh_config()
@@ -1,10 +1,11 @@
1
- from parsl.config import Config
2
1
  from parsl.channels import LocalChannel
3
- from parsl.providers import SlurmProvider
2
+ from parsl.config import Config
4
3
  from parsl.executors import HighThroughputExecutor
5
4
  from parsl.launchers import SrunLauncher
5
+ from parsl.providers import SlurmProvider
6
6
 
7
7
  from .user_opts import user_opts
8
+
8
9
  """ This config assumes that it is used to launch parsl tasks from the login nodes
9
10
  of Frontera at TACC. Each job submitted to the scheduler will request 2 nodes for 10 minutes.
10
11
  """
@@ -1,9 +1,7 @@
1
- from parsl.providers import AdHocProvider
2
1
  from parsl.channels import SSHChannel
3
- from parsl.executors import HighThroughputExecutor
4
-
5
2
  from parsl.config import Config
6
-
3
+ from parsl.executors import HighThroughputExecutor
4
+ from parsl.providers import AdHocProvider
7
5
  from parsl.tests.configs.user_opts import user_opts
8
6
 
9
7
  config = Config(
@@ -1,9 +1,8 @@
1
- from parsl.providers import LocalProvider
2
1
  from parsl.channels import LocalChannel
3
- from parsl.launchers import SimpleLauncher
4
-
5
2
  from parsl.config import Config
6
3
  from parsl.executors import HighThroughputExecutor
4
+ from parsl.launchers import SimpleLauncher
5
+ from parsl.providers import LocalProvider
7
6
 
8
7
 
9
8
  def fresh_config():
@@ -15,23 +15,20 @@ will cause substantially different behaviour on whatever
15
15
  those timing parameters control.
16
16
  """
17
17
 
18
- # imports for monitoring:
19
- from parsl.monitoring import MonitoringHub
20
-
21
18
  import os
22
19
 
23
- from parsl.providers import LocalProvider
24
20
  from parsl.channels import LocalChannel
25
- from parsl.launchers import SingleNodeLauncher
26
-
27
21
  from parsl.config import Config
28
- from parsl.executors import HighThroughputExecutor
29
-
30
-
31
- from parsl.data_provider.http import HTTPInTaskStaging
32
- from parsl.data_provider.ftp import FTPInTaskStaging
33
22
  from parsl.data_provider.file_noop import NoOpFileStaging
23
+ from parsl.data_provider.ftp import FTPInTaskStaging
24
+ from parsl.data_provider.http import HTTPInTaskStaging
34
25
  from parsl.data_provider.zip import ZipFileStaging
26
+ from parsl.executors import HighThroughputExecutor
27
+ from parsl.launchers import SingleNodeLauncher
28
+
29
+ # imports for monitoring:
30
+ from parsl.monitoring import MonitoringHub
31
+ from parsl.providers import LocalProvider
35
32
 
36
33
  working_dir = os.getcwd() + "/" + "test_htex_alternate"
37
34
 
@@ -1,13 +1,11 @@
1
- from parsl.providers import LocalProvider
2
1
  from parsl.channels import LocalChannel
3
- from parsl.launchers import SimpleLauncher
4
-
5
- from parsl.data_provider.http import HTTPInTaskStaging
6
- from parsl.data_provider.ftp import FTPInTaskStaging
7
- from parsl.data_provider.file_noop import NoOpFileStaging
8
-
9
2
  from parsl.config import Config
3
+ from parsl.data_provider.file_noop import NoOpFileStaging
4
+ from parsl.data_provider.ftp import FTPInTaskStaging
5
+ from parsl.data_provider.http import HTTPInTaskStaging
10
6
  from parsl.executors import HighThroughputExecutor
7
+ from parsl.launchers import SimpleLauncher
8
+ from parsl.providers import LocalProvider
11
9
 
12
10
  config = Config(
13
11
  executors=[
@@ -1,13 +1,11 @@
1
- from parsl.providers import LocalProvider
2
1
  from parsl.channels import LocalChannel
3
- from parsl.launchers import SimpleLauncher
4
-
5
- from parsl.data_provider.http import HTTPInTaskStaging
2
+ from parsl.config import Config
6
3
  from parsl.data_provider.ftp import FTPInTaskStaging
4
+ from parsl.data_provider.http import HTTPInTaskStaging
7
5
  from parsl.data_provider.rsync import RSyncStaging
8
-
9
- from parsl.config import Config
10
6
  from parsl.executors import HighThroughputExecutor
7
+ from parsl.launchers import SimpleLauncher
8
+ from parsl.providers import LocalProvider
11
9
 
12
10
  config = Config(
13
11
  executors=[
@@ -1,5 +1,5 @@
1
- from parsl.config import Config
2
1
  from parsl.channels import LocalChannel
2
+ from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.providers import AdHocProvider
5
5
 
@@ -1,9 +1,7 @@
1
1
  import os
2
2
 
3
3
  from parsl.config import Config
4
- from parsl.executors.radical import RadicalPilotExecutor
5
- from parsl.executors.radical import ResourceConfig
6
-
4
+ from parsl.executors.radical import RadicalPilotExecutor, ResourceConfig
7
5
 
8
6
  rpex_cfg = ResourceConfig()
9
7
 
@@ -1,10 +1,10 @@
1
1
  import os
2
+
2
3
  from parsl.config import Config
3
4
 
4
5
 
5
6
  def fresh_config():
6
- from parsl.executors.radical import ResourceConfig
7
- from parsl.executors.radical import RadicalPilotExecutor
7
+ from parsl.executors.radical import RadicalPilotExecutor, ResourceConfig
8
8
 
9
9
  rpex_cfg = ResourceConfig()
10
10
  rpex_cfg.worker_type = "MPI"
@@ -1,7 +1,7 @@
1
1
  from parsl.config import Config
2
- from parsl.providers import SlurmProvider
3
- from parsl.launchers import SrunLauncher
4
2
  from parsl.executors import HighThroughputExecutor
3
+ from parsl.launchers import SrunLauncher
4
+ from parsl.providers import SlurmProvider
5
5
 
6
6
  from .user_opts import user_opts
7
7
 
@@ -1,8 +1,8 @@
1
- from parsl.providers import PBSProProvider
2
- from parsl.executors import HighThroughputExecutor
3
- from parsl.launchers import MpiRunLauncher
4
1
  from parsl.addresses import address_by_interface
5
2
  from parsl.config import Config
3
+ from parsl.executors import HighThroughputExecutor
4
+ from parsl.launchers import MpiRunLauncher
5
+ from parsl.providers import PBSProProvider
6
6
 
7
7
  from .user_opts import user_opts
8
8