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