parsl 2024.7.1__tar.gz → 2024.7.15__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.7.1/parsl.egg-info → parsl-2024.7.15}/PKG-INFO +2 -2
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/app/app.py +4 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/ssh/ssh.py +12 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/dflow.py +17 -0
- parsl-2024.7.15/parsl/executors/flux/flux_instance_manager.py +56 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/executor.py +49 -21
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/mpi_executor.py +2 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/process_worker_pool.py +20 -1
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/radical/executor.py +105 -65
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/radical/rpex_resources.py +14 -7
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/kubernetes/kube.py +2 -3
- parsl-2024.7.15/parsl/tests/test_bash_apps/test_inputs_default.py +25 -0
- parsl-2024.7.15/parsl/tests/test_channels/test_dfk_close.py +26 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_htex.py +13 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/test_local_provider.py +12 -7
- parsl-2024.7.15/parsl/tests/test_python_apps/test_inputs_default.py +22 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/version.py +1 -1
- {parsl-2024.7.1 → parsl-2024.7.15/parsl.egg-info}/PKG-INFO +2 -2
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl.egg-info/SOURCES.txt +3 -1
- parsl-2024.7.1/parsl/executors/flux/flux_instance_manager.py +0 -57
- parsl-2024.7.1/parsl/executors/radical/rpex_master.py +0 -41
- {parsl-2024.7.1 → parsl-2024.7.15}/LICENSE +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/MANIFEST.in +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/README.rst +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/addresses.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/app/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/app/bash.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/app/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/app/futures.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/app/python.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/benchmark/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/benchmark/perf.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/base.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/local/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/local/local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/oauth_ssh/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/ssh/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/ssh_il/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/channels/ssh_il/ssh_il.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/concurrent/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/config.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/ASPIRE1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/Azure.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/ad_hoc.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/bridges.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/cc_in2p3.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/ec2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/expanse.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/frontera.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/htex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/illinoiscluster.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/kubernetes.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/local_threads.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/midway.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/osg.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/polaris.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/stampede2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/summit.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/toss3_llnl.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/vineex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/configs/wqex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/curvezmq.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/data_manager.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/file_noop.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/files.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/ftp.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/globus.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/http.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/rsync.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/staging.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/data_provider/zip.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/dependency_resolvers.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/futures.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/memoization.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/rundirs.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/states.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/dataflow/taskrecord.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/base.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/flux/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/flux/execute_parsl_task.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/flux/executor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/interchange.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/manager_record.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/monitoring_info.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/probe.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/radical/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/radical/rpex_worker.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/status_handling.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/executor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/factory.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/factory_config.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/manager.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/manager_config.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/taskvine/utils.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/threads.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/workqueue/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/workqueue/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/workqueue/executor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/jobs/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/jobs/error_handlers.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/jobs/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/jobs/job_status_poller.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/jobs/states.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/jobs/strategy.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/launchers/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/launchers/base.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/launchers/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/launchers/launchers.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/log_utils.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/db_manager.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/message_type.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/monitoring.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/queries/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/queries/pandas.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/radios.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/remote.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/router.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/types.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/app.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/models.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/plots/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/app.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/dag.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/error.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/layout.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/task.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/workflow.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/utils.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/version.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/monitoring/visualization/views.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/multiprocessing.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/process_loggers.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/ad_hoc/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/aws/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/aws/aws.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/aws/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/azure/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/azure/azure.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/azure/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/base.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/cluster_provider.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/cobalt/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/cobalt/cobalt.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/cobalt/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/condor/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/condor/condor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/condor/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/googlecloud/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/googlecloud/googlecloud.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/grid_engine/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/grid_engine/grid_engine.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/grid_engine/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/kubernetes/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/kubernetes/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/local/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/local/local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/lsf/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/lsf/lsf.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/lsf/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/pbspro/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/pbspro/pbspro.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/pbspro/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/slurm/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/slurm/slurm.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/slurm/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/torque/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/torque/template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/providers/torque/torque.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/py.typed +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/serialize/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/serialize/base.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/serialize/concretes.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/serialize/errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/serialize/facade.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/serialize/proxystore.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/callables_helper.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/azure_single_node.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/bluewaters.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/bridges.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/cc_in2p3.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/comet.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/cooley_htex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/ec2_single_node.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/ec2_spot.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/flux_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/frontera.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/htex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/htex_local_alternate.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_adhoc.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_radical.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_radical_mpi.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_globus.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_monitoring.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/local_threads_no_cache.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/midway.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/nscc_singapore.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/osg_htex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/petrelkube.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/summit.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/swan_htex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/taskvine_ex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/theta.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/user_opts.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/configs/workqueue_ex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/conftest.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/latency.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_apps/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_channels.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_stress/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/htex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_basic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_log_filter.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_regression_220.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/manual_tests/test_worker_count.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/htex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/local_threads.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/test_scale.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/vineex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/scaling_tests/wqex_local.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/site_tests/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/site_tests/site_config_selector.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/site_tests/test_provider.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/site_tests/test_site.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_affinity.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_concurrent.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_dynamic_executor.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_ec2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_launchers.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_local_adhoc.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_mpi/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/sites/test_worker_info.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_aalst_patterns.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_basic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_std_uri.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_callables.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_channels/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_channels/test_large_output.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_curvezmq.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/test_from_slides.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/test_kwargs.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/test_workflow1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/test_workflow2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_docs/test_workflow4.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_fail.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_retries.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_flowcontrol/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_flux.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_basic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_command_client_timeout.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_drain.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_manager_failure.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_managers_command.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_missing_worker.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_worker_failure.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_app_names.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_basic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_stdouterr.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_mpiex.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/test_slurm_template.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_basic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_context_manager.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_dependencies_deep.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_fail.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_futures.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_join.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_lifted.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_mapred.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_outputs.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_overview.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_pluggable_future_resolution.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_simple.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_timeout.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_python_apps/test_type5.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_radical/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_1480.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_1653.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_221.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_226.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_2652.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_69a.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_854.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_regression/test_98.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/test_scale_down.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_basic.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_shutdown/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/staging_provider.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_1316.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_docs_1.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_docs_2.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_file.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_file_apps.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_file_staging.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_staging_globus.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_staging_https.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_staging_stdout.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_zip_in.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_zip_out.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_staging/test_zip_to_zip.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_summary.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_thread_parallelism.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_threads/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_threads/test_configs.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_utils/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/unit/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/unit/test_file.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/unit/test_usage_tracking.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/tests/utils.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/usage_tracking/__init__.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/usage_tracking/api.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/usage_tracking/levels.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/usage_tracking/usage.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl/utils.py +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl.egg-info/dependency_links.txt +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl.egg-info/entry_points.txt +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl.egg-info/requires.txt +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/parsl.egg-info/top_level.txt +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/requirements.txt +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/setup.cfg +0 -0
- {parsl-2024.7.1 → parsl-2024.7.15}/setup.py +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2024.7.
|
3
|
+
Version: 2024.7.15
|
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.07.
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2024.07.15.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|
@@ -66,6 +66,10 @@ class AppBase(metaclass=ABCMeta):
|
|
66
66
|
self.kwargs['walltime'] = params['walltime'].default
|
67
67
|
if 'parsl_resource_specification' in params:
|
68
68
|
self.kwargs['parsl_resource_specification'] = params['parsl_resource_specification'].default
|
69
|
+
if 'outputs' in params:
|
70
|
+
self.kwargs['outputs'] = params['outputs'].default
|
71
|
+
if 'inputs' in params:
|
72
|
+
self.kwargs['inputs'] = params['inputs'].default
|
69
73
|
|
70
74
|
@abstractmethod
|
71
75
|
def __call__(self, *args: Any, **kwargs: Any) -> AppFuture:
|
@@ -227,8 +227,20 @@ class SSHChannel(Channel, RepresentationMixin):
|
|
227
227
|
|
228
228
|
def close(self) -> None:
|
229
229
|
if self._is_connected():
|
230
|
+
transport = self.ssh_client.get_transport()
|
230
231
|
self.ssh_client.close()
|
231
232
|
|
233
|
+
# ssh_client.close calls transport.close, but transport.close does
|
234
|
+
# not always wait for the transport thread to be stopped. See impl
|
235
|
+
# of Transport.close in paramiko and issue
|
236
|
+
# https://github.com/paramiko/paramiko/issues/520
|
237
|
+
logger.debug("Waiting for transport thread to stop")
|
238
|
+
transport.join(30)
|
239
|
+
if transport.is_alive():
|
240
|
+
logger.warning("SSH transport thread did not shut down")
|
241
|
+
else:
|
242
|
+
logger.debug("SSH transport thread stopped")
|
243
|
+
|
232
244
|
def isdir(self, path):
|
233
245
|
"""Return true if the path refers to an existing directory.
|
234
246
|
|
@@ -1277,6 +1277,23 @@ class DataFlowKernel:
|
|
1277
1277
|
executor.shutdown()
|
1278
1278
|
logger.info(f"Shut down executor {executor.label}")
|
1279
1279
|
|
1280
|
+
if hasattr(executor, 'provider'):
|
1281
|
+
if hasattr(executor.provider, 'script_dir'):
|
1282
|
+
logger.info(f"Closing channel(s) for {executor.label}")
|
1283
|
+
|
1284
|
+
if hasattr(executor.provider, 'channels'):
|
1285
|
+
for channel in executor.provider.channels:
|
1286
|
+
logger.info(f"Closing channel {channel}")
|
1287
|
+
channel.close()
|
1288
|
+
logger.info(f"Closed channel {channel}")
|
1289
|
+
else:
|
1290
|
+
assert hasattr(executor.provider, 'channel'), "If provider has no .channels, it must have .channel"
|
1291
|
+
logger.info(f"Closing channel {executor.provider.channel}")
|
1292
|
+
executor.provider.channel.close()
|
1293
|
+
logger.info(f"Closed channel {executor.provider.channel}")
|
1294
|
+
|
1295
|
+
logger.info(f"Closed executor channel(s) for {executor.label}")
|
1296
|
+
|
1280
1297
|
logger.info("Terminated executors")
|
1281
1298
|
self.time_completed = datetime.datetime.now()
|
1282
1299
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"""Script meant to be the initial program of a Flux instance."""
|
2
|
+
|
3
|
+
import argparse
|
4
|
+
import logging
|
5
|
+
import os
|
6
|
+
from os.path import dirname
|
7
|
+
from socket import gethostbyname, gethostname
|
8
|
+
|
9
|
+
import zmq
|
10
|
+
|
11
|
+
|
12
|
+
def main():
|
13
|
+
"""Run a Flux instance to completion.
|
14
|
+
|
15
|
+
Send the path to the Flux Python package and the URI of the
|
16
|
+
encapsulating Flux instance.
|
17
|
+
"""
|
18
|
+
# flux imports only available when launched under Flux instance
|
19
|
+
import flux
|
20
|
+
import flux.job
|
21
|
+
|
22
|
+
logging.basicConfig(
|
23
|
+
level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s"
|
24
|
+
)
|
25
|
+
parser = argparse.ArgumentParser()
|
26
|
+
parser.add_argument("protocol", help="Protocol of the parent executor's socket")
|
27
|
+
parser.add_argument("hostname", help="hostname of the parent executor's socket")
|
28
|
+
parser.add_argument("port", help="Port of the parent executor's socket")
|
29
|
+
args = parser.parse_args()
|
30
|
+
with zmq.Context() as context, context.socket(zmq.REQ) as socket:
|
31
|
+
socket.connect(
|
32
|
+
args.protocol + "://" + gethostbyname(args.hostname) + ":" + args.port
|
33
|
+
)
|
34
|
+
# send the path to the ``flux.job`` package
|
35
|
+
socket.send(dirname(dirname(os.path.realpath(flux.__file__))).encode())
|
36
|
+
logging.debug("Flux package path sent.")
|
37
|
+
# collect the encapsulating Flux instance's URI
|
38
|
+
local_uri = flux.Flux().attr_get("local-uri")
|
39
|
+
hostname = gethostname()
|
40
|
+
if args.hostname == hostname:
|
41
|
+
flux_uri = local_uri
|
42
|
+
else:
|
43
|
+
flux_uri = "ssh://" + gethostname() + local_uri.replace("local://", "")
|
44
|
+
logging.debug("Flux URI is %s", flux_uri)
|
45
|
+
response = socket.recv() # get acknowledgment
|
46
|
+
logging.debug("Received acknowledgment %s", response)
|
47
|
+
socket.send(flux_uri.encode()) # send URI
|
48
|
+
logging.debug("URI sent. Blocking for response...")
|
49
|
+
response = socket.recv() # wait for shutdown message
|
50
|
+
logging.debug("Response %s received, draining flux jobs...", response)
|
51
|
+
flux.Flux().rpc("job-manager.drain").get()
|
52
|
+
logging.debug("Flux jobs drained, exiting.")
|
53
|
+
|
54
|
+
|
55
|
+
if __name__ == "__main__":
|
56
|
+
main()
|
@@ -56,6 +56,8 @@ DEFAULT_LAUNCH_CMD = ("process_worker_pool.py {debug} {max_workers_per_node} "
|
|
56
56
|
"--mpi-launcher={mpi_launcher} "
|
57
57
|
"--available-accelerators {accelerators}")
|
58
58
|
|
59
|
+
DEFAULT_INTERCHANGE_LAUNCH_CMD = "interchange.py"
|
60
|
+
|
59
61
|
GENERAL_HTEX_PARAM_DOCS = """provider : :class:`~parsl.providers.base.ExecutionProvider`
|
60
62
|
Provider to access computation resources. Can be one of :class:`~parsl.providers.aws.aws.EC2Provider`,
|
61
63
|
:class:`~parsl.providers.cobalt.cobalt.Cobalt`,
|
@@ -76,6 +78,10 @@ GENERAL_HTEX_PARAM_DOCS = """provider : :class:`~parsl.providers.base.ExecutionP
|
|
76
78
|
cores_per_worker, nodes_per_block, heartbeat_period ,heartbeat_threshold, logdir). For example:
|
77
79
|
launch_cmd="process_worker_pool.py {debug} -c {cores_per_worker} --task_url={task_url} --result_url={result_url}"
|
78
80
|
|
81
|
+
interchange_launch_cmd : str
|
82
|
+
Custom command line string to launch the interchange process from the executor. If undefined,
|
83
|
+
the executor will use the default "interchange.py" command.
|
84
|
+
|
79
85
|
address : string
|
80
86
|
An address to connect to the main Parsl process which is reachable from the network in which
|
81
87
|
workers will be running. This field expects an IPv4 address (xxx.xxx.xxx.xxx).
|
@@ -162,7 +168,8 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
162
168
|
| | | | batching | | |
|
163
169
|
Parsl<---Fut-| | | load-balancing| result exception
|
164
170
|
^ | | | watchdogs | | |
|
165
|
-
| | |
|
171
|
+
| | | Result | | | |
|
172
|
+
| | | Queue | | V V
|
166
173
|
| | | Thread<--|-incoming_q<---|--- +---------+
|
167
174
|
| | | | | |
|
168
175
|
| | | | | |
|
@@ -231,6 +238,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
231
238
|
label: str = 'HighThroughputExecutor',
|
232
239
|
provider: ExecutionProvider = LocalProvider(),
|
233
240
|
launch_cmd: Optional[str] = None,
|
241
|
+
interchange_launch_cmd: Optional[str] = None,
|
234
242
|
address: Optional[str] = None,
|
235
243
|
worker_ports: Optional[Tuple[int, int]] = None,
|
236
244
|
worker_port_range: Optional[Tuple[int, int]] = (54000, 55000),
|
@@ -329,6 +337,10 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
329
337
|
launch_cmd = DEFAULT_LAUNCH_CMD
|
330
338
|
self.launch_cmd = launch_cmd
|
331
339
|
|
340
|
+
if not interchange_launch_cmd:
|
341
|
+
interchange_launch_cmd = DEFAULT_INTERCHANGE_LAUNCH_CMD
|
342
|
+
self.interchange_launch_cmd = interchange_launch_cmd
|
343
|
+
|
332
344
|
radio_mode = "htex"
|
333
345
|
|
334
346
|
def _warn_deprecated(self, old: str, new: str):
|
@@ -418,20 +430,19 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
418
430
|
"127.0.0.1", self.interchange_port_range, self.cert_dir
|
419
431
|
)
|
420
432
|
|
421
|
-
self.
|
422
|
-
self.
|
433
|
+
self._result_queue_thread = None
|
434
|
+
self._start_result_queue_thread()
|
423
435
|
self._start_local_interchange_process()
|
424
436
|
|
425
|
-
logger.debug("Created
|
437
|
+
logger.debug("Created result queue thread: %s", self._result_queue_thread)
|
426
438
|
|
427
439
|
self.initialize_scaling()
|
428
440
|
|
429
441
|
@wrap_with_logs
|
430
|
-
def
|
431
|
-
"""Listen to the queue for task
|
442
|
+
def _result_queue_worker(self):
|
443
|
+
"""Listen to the queue for task result messages and handle them.
|
432
444
|
|
433
|
-
Depending on the message, tasks will be updated with results
|
434
|
-
or updates. It expects the following messages:
|
445
|
+
Depending on the message, tasks will be updated with results or exceptions.
|
435
446
|
|
436
447
|
.. code:: python
|
437
448
|
|
@@ -448,7 +459,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
448
459
|
|
449
460
|
The `None` message is a die request.
|
450
461
|
"""
|
451
|
-
logger.debug("
|
462
|
+
logger.debug("Result queue worker starting")
|
452
463
|
|
453
464
|
while not self.bad_state_is_set:
|
454
465
|
try:
|
@@ -517,7 +528,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
517
528
|
else:
|
518
529
|
raise BadMessage("Message received with unknown type {}".format(msg['type']))
|
519
530
|
|
520
|
-
logger.info("
|
531
|
+
logger.info("Result queue worker finished")
|
521
532
|
|
522
533
|
def _start_local_interchange_process(self) -> None:
|
523
534
|
""" Starts the interchange process locally
|
@@ -544,7 +555,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
544
555
|
|
545
556
|
config_pickle = pickle.dumps(interchange_config)
|
546
557
|
|
547
|
-
self.interchange_proc = subprocess.Popen(
|
558
|
+
self.interchange_proc = subprocess.Popen(self.interchange_launch_cmd.encode("utf-8"), stdin=subprocess.PIPE)
|
548
559
|
stdin = self.interchange_proc.stdin
|
549
560
|
assert stdin is not None, "Popen should have created an IO object (vs default None) because of PIPE mode"
|
550
561
|
|
@@ -560,21 +571,21 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
560
571
|
raise Exception("Interchange failed to start")
|
561
572
|
logger.debug("Got worker ports")
|
562
573
|
|
563
|
-
def
|
564
|
-
"""Method to start the
|
574
|
+
def _start_result_queue_thread(self):
|
575
|
+
"""Method to start the result queue thread as a daemon.
|
565
576
|
|
566
577
|
Checks if a thread already exists, then starts it.
|
567
|
-
Could be used later as a restart if the
|
578
|
+
Could be used later as a restart if the result queue thread dies.
|
568
579
|
"""
|
569
|
-
if self.
|
570
|
-
logger.debug("Starting queue
|
571
|
-
self.
|
572
|
-
self.
|
573
|
-
self.
|
574
|
-
logger.debug("Started queue
|
580
|
+
if self._result_queue_thread is None:
|
581
|
+
logger.debug("Starting result queue thread")
|
582
|
+
self._result_queue_thread = threading.Thread(target=self._result_queue_worker, name="HTEX-Result-Queue-Thread")
|
583
|
+
self._result_queue_thread.daemon = True
|
584
|
+
self._result_queue_thread.start()
|
585
|
+
logger.debug("Started result queue thread")
|
575
586
|
|
576
587
|
else:
|
577
|
-
logger.error("
|
588
|
+
logger.error("Result queue thread already exists, returning")
|
578
589
|
|
579
590
|
def hold_worker(self, worker_id: str) -> None:
|
580
591
|
"""Puts a worker on hold, preventing scheduling of additional tasks to it.
|
@@ -823,6 +834,23 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
823
834
|
logger.info("Unable to terminate Interchange process; sending SIGKILL")
|
824
835
|
self.interchange_proc.kill()
|
825
836
|
|
837
|
+
logger.info("Closing ZMQ pipes")
|
838
|
+
|
839
|
+
# These pipes are used in a thread unsafe manner. If you have traced a
|
840
|
+
# problem to this block of code, you might consider what is happening
|
841
|
+
# with other threads that access these.
|
842
|
+
|
843
|
+
# incoming_q is not closed here because it is used by the results queue
|
844
|
+
# worker which is not shut down at this point.
|
845
|
+
|
846
|
+
if hasattr(self, 'outgoing_q'):
|
847
|
+
logger.info("Closing outgoing_q")
|
848
|
+
self.outgoing_q.close()
|
849
|
+
|
850
|
+
if hasattr(self, 'command_client'):
|
851
|
+
logger.info("Closing command client")
|
852
|
+
self.command_client.close()
|
853
|
+
|
826
854
|
logger.info("Finished HighThroughputExecutor shutdown attempt")
|
827
855
|
|
828
856
|
def get_usage_information(self):
|
@@ -38,6 +38,7 @@ class MPIExecutor(HighThroughputExecutor):
|
|
38
38
|
label: str = 'MPIExecutor',
|
39
39
|
provider: ExecutionProvider = LocalProvider(),
|
40
40
|
launch_cmd: Optional[str] = None,
|
41
|
+
interchange_launch_cmd: Optional[str] = None,
|
41
42
|
address: Optional[str] = None,
|
42
43
|
worker_ports: Optional[Tuple[int, int]] = None,
|
43
44
|
worker_port_range: Optional[Tuple[int, int]] = (54000, 55000),
|
@@ -66,6 +67,7 @@ class MPIExecutor(HighThroughputExecutor):
|
|
66
67
|
label=label,
|
67
68
|
provider=provider,
|
68
69
|
launch_cmd=launch_cmd,
|
70
|
+
interchange_launch_cmd=interchange_launch_cmd,
|
69
71
|
address=address,
|
70
72
|
worker_ports=worker_ports,
|
71
73
|
worker_port_range=worker_port_range,
|
@@ -9,6 +9,7 @@ import os
|
|
9
9
|
import pickle
|
10
10
|
import platform
|
11
11
|
import queue
|
12
|
+
import subprocess
|
12
13
|
import sys
|
13
14
|
import threading
|
14
15
|
import time
|
@@ -731,9 +732,27 @@ def worker(
|
|
731
732
|
os.sched_setaffinity(0, my_cores) # type: ignore[attr-defined, unused-ignore]
|
732
733
|
logger.info("Set worker CPU affinity to {}".format(my_cores))
|
733
734
|
|
735
|
+
# If CUDA devices, find total number of devices to allow for MPS
|
736
|
+
# See: https://developer.nvidia.com/system-management-interface
|
737
|
+
nvidia_smi_cmd = "nvidia-smi -L > /dev/null && nvidia-smi -L | wc -l"
|
738
|
+
nvidia_smi_ret = subprocess.run(nvidia_smi_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
739
|
+
if nvidia_smi_ret.returncode == 0:
|
740
|
+
num_cuda_devices = int(nvidia_smi_ret.stdout.split()[0])
|
741
|
+
else:
|
742
|
+
num_cuda_devices = None
|
743
|
+
|
734
744
|
# If desired, pin to accelerator
|
735
745
|
if accelerator is not None:
|
736
|
-
|
746
|
+
try:
|
747
|
+
if num_cuda_devices is not None:
|
748
|
+
procs_per_cuda_device = pool_size // num_cuda_devices
|
749
|
+
partitioned_accelerator = str(int(accelerator) // procs_per_cuda_device) # multiple workers will share a GPU
|
750
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = partitioned_accelerator
|
751
|
+
logger.info(f'Pinned worker to partitioned cuda device: {partitioned_accelerator}')
|
752
|
+
else:
|
753
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = accelerator
|
754
|
+
except (TypeError, ValueError, ZeroDivisionError):
|
755
|
+
os.environ["CUDA_VISIBLE_DEVICES"] = accelerator
|
737
756
|
os.environ["ROCR_VISIBLE_DEVICES"] = accelerator
|
738
757
|
os.environ["ZE_AFFINITY_MASK"] = accelerator
|
739
758
|
os.environ["ZE_ENABLE_PCI_ID_DEVICE_ORDER"] = '1'
|
@@ -9,7 +9,7 @@ import threading as mt
|
|
9
9
|
import time
|
10
10
|
from concurrent.futures import Future
|
11
11
|
from functools import partial
|
12
|
-
from pathlib import
|
12
|
+
from pathlib import PosixPath
|
13
13
|
from typing import Dict, Optional
|
14
14
|
|
15
15
|
import requests
|
@@ -24,7 +24,7 @@ from parsl.serialize import deserialize, pack_res_spec_apply_message
|
|
24
24
|
from parsl.serialize.errors import DeserializationError, SerializationError
|
25
25
|
from parsl.utils import RepresentationMixin
|
26
26
|
|
27
|
-
from .rpex_resources import ResourceConfig
|
27
|
+
from .rpex_resources import CLIENT, MPI, ResourceConfig
|
28
28
|
|
29
29
|
try:
|
30
30
|
import radical.pilot as rp
|
@@ -59,7 +59,7 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
59
59
|
``rp.PilotManager`` and ``rp.TaskManager``.
|
60
60
|
2. "translate": Unwrap, identify, and parse Parsl ``apps`` into ``rp.TaskDescription``.
|
61
61
|
3. "submit": Submit Parsl apps to ``rp.TaskManager``.
|
62
|
-
4. "
|
62
|
+
4. "shutdown": Shut down the RADICAL-Pilot runtime and all associated components.
|
63
63
|
|
64
64
|
Here is a diagram
|
65
65
|
|
@@ -138,19 +138,26 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
138
138
|
self.future_tasks: Dict[str, Future] = {}
|
139
139
|
|
140
140
|
if rpex_cfg:
|
141
|
-
self.rpex_cfg = rpex_cfg
|
141
|
+
self.rpex_cfg = rpex_cfg.get_config()
|
142
142
|
elif not rpex_cfg and 'local' in resource:
|
143
|
-
self.rpex_cfg = ResourceConfig()
|
143
|
+
self.rpex_cfg = ResourceConfig().get_config()
|
144
144
|
else:
|
145
|
-
raise ValueError('Resource config
|
146
|
-
'specified for a non-local
|
145
|
+
raise ValueError('Resource config must be '
|
146
|
+
'specified for a non-local resources')
|
147
147
|
|
148
148
|
def task_state_cb(self, task, state):
|
149
149
|
"""
|
150
150
|
Update the state of Parsl Future apps
|
151
151
|
Based on RP task state callbacks.
|
152
152
|
"""
|
153
|
-
|
153
|
+
# check the Master/Worker state
|
154
|
+
if task.mode in [rp.RAPTOR_MASTER, rp.RAPTOR_WORKER]:
|
155
|
+
if state == rp.FAILED:
|
156
|
+
exception = RuntimeError(f'{task.uid} failed with internal error: {task.stderr}')
|
157
|
+
self._fail_all_tasks(exception)
|
158
|
+
|
159
|
+
# check all other tasks state
|
160
|
+
else:
|
154
161
|
parsl_task = self.future_tasks[task.uid]
|
155
162
|
|
156
163
|
if state == rp.DONE:
|
@@ -186,6 +193,23 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
186
193
|
else:
|
187
194
|
parsl_task.set_exception('Task failed for an unknown reason')
|
188
195
|
|
196
|
+
def _fail_all_tasks(self, exception):
|
197
|
+
"""
|
198
|
+
Fail all outstanding tasks with the given exception.
|
199
|
+
|
200
|
+
This method iterates through all outstanding tasks in the
|
201
|
+
`_future_tasks` dictionary, which have not yet completed,
|
202
|
+
and sets the provided exception as their result, indicating
|
203
|
+
a failure.
|
204
|
+
|
205
|
+
Parameters:
|
206
|
+
- exception: The exception to be set as the result for all
|
207
|
+
outstanding tasks.
|
208
|
+
"""
|
209
|
+
for fut_task in self.future_tasks.values():
|
210
|
+
if not fut_task.done():
|
211
|
+
fut_task.set_exception(exception)
|
212
|
+
|
189
213
|
def start(self):
|
190
214
|
"""Create the Pilot component and pass it.
|
191
215
|
"""
|
@@ -202,63 +226,62 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
202
226
|
'resource': self.resource}
|
203
227
|
|
204
228
|
if not self.resource or 'local' in self.resource:
|
205
|
-
|
206
|
-
|
207
|
-
# to include the agent sandbox with the ci artifacts.
|
208
|
-
if os.environ.get("LOCAL_SANDBOX"):
|
209
|
-
pd_init['sandbox'] = self.run_dir
|
210
|
-
os.environ["RADICAL_LOG_LVL"] = "DEBUG"
|
211
|
-
|
212
|
-
logger.info("RPEX will be running in the local mode")
|
229
|
+
os.environ["RADICAL_LOG_LVL"] = "DEBUG"
|
230
|
+
logger.info("RPEX will be running in local mode")
|
213
231
|
|
214
232
|
pd = rp.PilotDescription(pd_init)
|
215
233
|
pd.verify()
|
216
234
|
|
217
|
-
|
218
|
-
|
235
|
+
# start RP's main components TMGR, PMGR and Pilot
|
236
|
+
self.tmgr = rp.TaskManager(session=self.session)
|
237
|
+
self.pmgr = rp.PilotManager(session=self.session)
|
238
|
+
self.pilot = self.pmgr.submit_pilots(pd)
|
219
239
|
|
220
|
-
self.
|
221
|
-
|
240
|
+
if not self.pilot.description.get('cores') or not self.pilot.description.get('nodes'):
|
241
|
+
logger.warning('no "cores/nodes" per pilot were set, using default resources')
|
242
|
+
|
243
|
+
self.tmgr.add_pilots(self.pilot)
|
244
|
+
self.tmgr.register_callback(self.task_state_cb)
|
222
245
|
|
223
|
-
tds = list()
|
224
|
-
master_path = '{0}/rpex_master.py'.format(PWD)
|
225
246
|
worker_path = '{0}/rpex_worker.py'.format(PWD)
|
226
247
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
248
|
+
self.masters = []
|
249
|
+
|
250
|
+
logger.info(f'Starting {self.rpex_cfg.n_masters} masters and {self.rpex_cfg.n_workers} workers for each master')
|
251
|
+
|
252
|
+
# create N masters
|
253
|
+
for _ in range(self.rpex_cfg.n_masters):
|
254
|
+
md = rp.TaskDescription(self.rpex_cfg.master_descr)
|
255
|
+
md.uid = ru.generate_id('rpex.master.%(item_counter)06d', ru.ID_CUSTOM,
|
231
256
|
ns=self.session.uid)
|
232
|
-
td.ranks = 1
|
233
|
-
td.cores_per_rank = 1
|
234
|
-
td.arguments = [self.rpex_cfg, i]
|
235
|
-
td.input_staging = self._stage_files([File(master_path),
|
236
|
-
File(worker_path),
|
237
|
-
File(self.rpex_cfg)], mode='in')
|
238
|
-
tds.append(td)
|
239
257
|
|
240
|
-
|
241
|
-
|
258
|
+
# submit the master to the TMGR
|
259
|
+
master = self.tmgr.submit_raptors(md)[0]
|
260
|
+
self.masters.append(master)
|
242
261
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
262
|
+
workers = []
|
263
|
+
# create N workers for each master and submit them to the TMGR
|
264
|
+
for _ in range(self.rpex_cfg.n_workers):
|
265
|
+
wd = rp.TaskDescription(self.rpex_cfg.worker_descr)
|
266
|
+
wd.uid = ru.generate_id('rpex.worker.%(item_counter)06d', ru.ID_CUSTOM,
|
267
|
+
ns=self.session.uid)
|
268
|
+
wd.raptor_id = master.uid
|
269
|
+
wd.input_staging = self._stage_files([File(worker_path)], mode='in')
|
270
|
+
workers.append(wd)
|
247
271
|
|
248
|
-
|
272
|
+
self.tmgr.submit_workers(workers)
|
273
|
+
|
274
|
+
self.select_master = self._cyclic_master_selector()
|
249
275
|
|
250
276
|
# prepare or use the current env for the agent/pilot side environment
|
251
|
-
if
|
252
|
-
logger.info("creating {0} environment for the executor".format(
|
253
|
-
pilot.prepare_env(env_name=
|
254
|
-
|
277
|
+
if self.rpex_cfg.pilot_env_mode != CLIENT:
|
278
|
+
logger.info("creating {0} environment for the executor".format(self.rpex_cfg.pilot_env.name))
|
279
|
+
self.pilot.prepare_env(env_name=self.rpex_cfg.pilot_env.name,
|
280
|
+
env_spec=self.rpex_cfg.pilot_env.as_dict())
|
255
281
|
else:
|
256
282
|
client_env = sys.prefix
|
257
283
|
logger.info("reusing ({0}) environment for the executor".format(client_env))
|
258
284
|
|
259
|
-
self.tmgr.add_pilots(pilot)
|
260
|
-
self.tmgr.register_callback(self.task_state_cb)
|
261
|
-
|
262
285
|
# create a bulking thread to run the actual task submission
|
263
286
|
# to RP in bulks
|
264
287
|
if self.bulk_mode:
|
@@ -272,8 +295,21 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
272
295
|
self._bulk_thread.daemon = True
|
273
296
|
self._bulk_thread.start()
|
274
297
|
|
298
|
+
logger.info('bulk mode is on, submitting tasks in bulks')
|
299
|
+
|
275
300
|
return True
|
276
301
|
|
302
|
+
def _cyclic_master_selector(self):
|
303
|
+
"""
|
304
|
+
Balance tasks submission across N masters and N workers
|
305
|
+
"""
|
306
|
+
current_master = 0
|
307
|
+
masters_uids = [m.uid for m in self.masters]
|
308
|
+
|
309
|
+
while True:
|
310
|
+
yield masters_uids[current_master]
|
311
|
+
current_master = (current_master + 1) % len(self.masters)
|
312
|
+
|
277
313
|
def unwrap(self, func, args):
|
278
314
|
"""
|
279
315
|
Unwrap a Parsl app and its args for further processing.
|
@@ -364,22 +400,25 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
364
400
|
|
365
401
|
# This is the default mode where the bash_app will be executed as
|
366
402
|
# as a single core process by RP. For cores > 1 the user must use
|
367
|
-
# above or use MPI functions if their
|
403
|
+
# task.mode=rp.TASK_EXECUTABLE (above) or use MPI functions if their
|
404
|
+
# code is Python.
|
368
405
|
else:
|
369
406
|
task.mode = rp.TASK_PROC
|
370
|
-
task.raptor_id =
|
407
|
+
task.raptor_id = next(self.select_master)
|
371
408
|
task.executable = self._pack_and_apply_message(func, args, kwargs)
|
372
409
|
|
373
410
|
elif PYTHON in task_type or not task_type:
|
374
411
|
task.mode = rp.TASK_FUNCTION
|
375
|
-
task.raptor_id =
|
412
|
+
task.raptor_id = next(self.select_master)
|
376
413
|
if kwargs.get('walltime'):
|
377
414
|
func = timeout(func, kwargs['walltime'])
|
378
415
|
|
379
|
-
#
|
380
|
-
if
|
416
|
+
# Check how to serialize the function object
|
417
|
+
if MPI in self.rpex_cfg.worker_type.lower():
|
418
|
+
task.use_mpi = True
|
381
419
|
task.function = rp.PythonTask(func, *args, **kwargs)
|
382
420
|
else:
|
421
|
+
task.use_mpi = False
|
383
422
|
task.function = self._pack_and_apply_message(func, args, kwargs)
|
384
423
|
|
385
424
|
task.input_staging = self._stage_files(kwargs.get("inputs", []),
|
@@ -394,7 +433,7 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
394
433
|
try:
|
395
434
|
task.verify()
|
396
435
|
except ru.typeddict.TDKeyError as e:
|
397
|
-
raise Exception(f'{e}. Please check
|
436
|
+
raise Exception(f'{e}. Please check: https://radicalpilot.readthedocs.io/en/stable/ documentation')
|
398
437
|
|
399
438
|
return task
|
400
439
|
|
@@ -413,7 +452,11 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
413
452
|
|
414
453
|
def _unpack_and_set_parsl_exception(self, parsl_task, exception):
|
415
454
|
try:
|
416
|
-
|
455
|
+
try:
|
456
|
+
s = rp.utils.deserialize_bson(exception)
|
457
|
+
except Exception:
|
458
|
+
s = exception
|
459
|
+
|
417
460
|
if isinstance(s, RemoteExceptionWrapper):
|
418
461
|
try:
|
419
462
|
s.reraise()
|
@@ -421,6 +464,8 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
421
464
|
parsl_task.set_exception(e)
|
422
465
|
elif isinstance(s, Exception):
|
423
466
|
parsl_task.set_exception(s)
|
467
|
+
elif isinstance(s, str):
|
468
|
+
parsl_task.set_exception(eval(s))
|
424
469
|
else:
|
425
470
|
raise ValueError("Unknown exception-like type received: {}".format(type(s)))
|
426
471
|
except Exception as e:
|
@@ -440,16 +485,10 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
440
485
|
elif isinstance(k_val, PosixPath):
|
441
486
|
k_val = k_val.__str__()
|
442
487
|
|
443
|
-
#
|
444
|
-
#
|
445
|
-
# we just set the path to the cwd
|
446
|
-
if '/' not in k_val:
|
447
|
-
k_val = CWD + '/' + k_val
|
448
|
-
|
449
|
-
# finally set the stderr/out to
|
450
|
-
# the desired name by the user
|
488
|
+
# set the stderr/out to the desired
|
489
|
+
# name by the user
|
451
490
|
setattr(task, k, k_val)
|
452
|
-
task.sandbox =
|
491
|
+
task.sandbox = CWD
|
453
492
|
|
454
493
|
def _stage_files(self, files, mode):
|
455
494
|
"""
|
@@ -477,7 +516,7 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
477
516
|
# this indicates that the user
|
478
517
|
# did not provided a specific
|
479
518
|
# output file and RP will stage out
|
480
|
-
# the task.
|
519
|
+
# the task.stdout from pilot://task_folder
|
481
520
|
# to the CWD or file.url
|
482
521
|
if '/' not in file.url:
|
483
522
|
f = {'source': file.filename,
|
@@ -548,7 +587,8 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
548
587
|
|
549
588
|
def shutdown(self, hub=True, targets='all', block=False):
|
550
589
|
"""Shutdown the executor, including all RADICAL-Pilot components."""
|
551
|
-
logger.info("RadicalPilotExecutor
|
590
|
+
logger.info("RadicalPilotExecutor is terminating...")
|
552
591
|
self.session.close(download=True)
|
592
|
+
logger.info("RadicalPilotExecutor is terminated.")
|
553
593
|
|
554
594
|
return True
|