parsl 2024.5.20__py3-none-any.whl → 2024.6.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- parsl/__init__.py +9 -10
- parsl/addresses.py +6 -4
- parsl/app/app.py +3 -6
- parsl/app/bash.py +4 -4
- parsl/app/errors.py +5 -3
- parsl/app/futures.py +3 -3
- parsl/app/python.py +2 -1
- parsl/benchmark/perf.py +2 -1
- parsl/channels/__init__.py +2 -2
- parsl/channels/base.py +0 -1
- parsl/channels/errors.py +2 -1
- parsl/channels/oauth_ssh/oauth_ssh.py +4 -3
- parsl/channels/ssh/ssh.py +9 -1
- parsl/channels/ssh_il/ssh_il.py +1 -0
- parsl/concurrent/__init__.py +2 -2
- parsl/config.py +12 -6
- parsl/configs/ASPIRE1.py +3 -3
- parsl/configs/Azure.py +6 -7
- parsl/configs/ad_hoc.py +4 -3
- parsl/configs/bridges.py +3 -3
- parsl/configs/cc_in2p3.py +2 -2
- parsl/configs/ec2.py +1 -1
- parsl/configs/expanse.py +1 -2
- parsl/configs/frontera.py +2 -3
- parsl/configs/htex_local.py +1 -2
- parsl/configs/illinoiscluster.py +1 -1
- parsl/configs/kubernetes.py +1 -2
- parsl/configs/midway.py +3 -3
- parsl/configs/osg.py +1 -1
- parsl/configs/polaris.py +1 -1
- parsl/configs/stampede2.py +4 -5
- parsl/configs/summit.py +1 -3
- parsl/configs/toss3_llnl.py +1 -2
- parsl/configs/vineex_local.py +3 -3
- parsl/configs/wqex_local.py +2 -2
- parsl/data_provider/data_manager.py +3 -3
- parsl/data_provider/file_noop.py +1 -2
- parsl/data_provider/files.py +3 -3
- parsl/data_provider/ftp.py +1 -3
- parsl/data_provider/globus.py +7 -6
- parsl/data_provider/http.py +2 -2
- parsl/data_provider/rsync.py +1 -1
- parsl/data_provider/staging.py +2 -2
- parsl/data_provider/zip.py +4 -5
- parsl/dataflow/dependency_resolvers.py +115 -0
- parsl/dataflow/dflow.py +65 -54
- parsl/dataflow/errors.py +2 -1
- parsl/dataflow/futures.py +1 -2
- parsl/dataflow/memoization.py +5 -5
- parsl/dataflow/rundirs.py +1 -1
- parsl/dataflow/taskrecord.py +4 -5
- parsl/executors/__init__.py +3 -3
- parsl/executors/base.py +1 -0
- parsl/executors/flux/execute_parsl_task.py +2 -2
- parsl/executors/flux/executor.py +11 -12
- parsl/executors/flux/flux_instance_manager.py +3 -3
- parsl/executors/high_throughput/errors.py +10 -0
- parsl/executors/high_throughput/executor.py +31 -36
- parsl/executors/high_throughput/interchange.py +16 -18
- parsl/executors/high_throughput/manager_record.py +1 -0
- parsl/executors/high_throughput/monitoring_info.py +2 -1
- parsl/executors/high_throughput/mpi_executor.py +6 -3
- parsl/executors/high_throughput/mpi_prefix_composer.py +19 -3
- parsl/executors/high_throughput/mpi_resource_management.py +1 -2
- parsl/executors/high_throughput/probe.py +6 -4
- parsl/executors/high_throughput/process_worker_pool.py +31 -20
- parsl/executors/high_throughput/zmq_pipes.py +63 -15
- parsl/executors/radical/executor.py +15 -15
- parsl/executors/radical/rpex_master.py +1 -2
- parsl/executors/radical/rpex_resources.py +4 -9
- parsl/executors/radical/rpex_worker.py +2 -1
- parsl/executors/status_handling.py +5 -4
- parsl/executors/taskvine/__init__.py +1 -1
- parsl/executors/taskvine/errors.py +1 -1
- parsl/executors/taskvine/exec_parsl_function.py +2 -2
- parsl/executors/taskvine/executor.py +23 -24
- parsl/executors/taskvine/factory.py +1 -1
- parsl/executors/taskvine/manager.py +11 -13
- parsl/executors/threads.py +4 -5
- parsl/executors/workqueue/errors.py +1 -1
- parsl/executors/workqueue/exec_parsl_function.py +5 -4
- parsl/executors/workqueue/executor.py +26 -27
- parsl/executors/workqueue/parsl_coprocess.py +1 -1
- parsl/jobs/error_handlers.py +1 -1
- parsl/jobs/job_status_poller.py +2 -5
- parsl/jobs/states.py +1 -1
- parsl/jobs/strategy.py +2 -2
- parsl/launchers/__init__.py +12 -3
- parsl/launchers/errors.py +1 -1
- parsl/log_utils.py +1 -2
- parsl/monitoring/db_manager.py +16 -10
- parsl/monitoring/monitoring.py +11 -15
- parsl/monitoring/queries/pandas.py +1 -2
- parsl/monitoring/radios.py +2 -4
- parsl/monitoring/remote.py +13 -8
- parsl/monitoring/router.py +8 -11
- parsl/monitoring/types.py +2 -0
- parsl/monitoring/visualization/app.py +4 -2
- parsl/monitoring/visualization/models.py +0 -1
- parsl/monitoring/visualization/plots/default/workflow_plots.py +8 -4
- parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
- parsl/monitoring/visualization/utils.py +0 -1
- parsl/monitoring/visualization/views.py +16 -9
- parsl/multiprocessing.py +0 -1
- parsl/process_loggers.py +1 -2
- parsl/providers/__init__.py +9 -12
- parsl/providers/ad_hoc/ad_hoc.py +1 -1
- parsl/providers/aws/aws.py +2 -3
- parsl/providers/azure/azure.py +4 -5
- parsl/providers/base.py +1 -1
- parsl/providers/cluster_provider.py +1 -1
- parsl/providers/cobalt/cobalt.py +3 -3
- parsl/providers/condor/condor.py +4 -2
- parsl/providers/errors.py +2 -2
- parsl/providers/googlecloud/googlecloud.py +2 -1
- parsl/providers/grid_engine/grid_engine.py +2 -2
- parsl/providers/kubernetes/kube.py +5 -3
- parsl/providers/local/local.py +5 -1
- parsl/providers/lsf/lsf.py +2 -2
- parsl/providers/pbspro/pbspro.py +1 -1
- parsl/providers/slurm/slurm.py +5 -5
- parsl/providers/torque/torque.py +1 -1
- parsl/serialize/__init__.py +8 -3
- parsl/serialize/base.py +1 -2
- parsl/serialize/concretes.py +5 -4
- parsl/serialize/proxystore.py +3 -2
- parsl/tests/__init__.py +1 -1
- parsl/tests/configs/ad_hoc_cluster_htex.py +4 -4
- parsl/tests/configs/azure_single_node.py +4 -5
- parsl/tests/configs/bridges.py +3 -2
- parsl/tests/configs/cc_in2p3.py +2 -2
- parsl/tests/configs/comet.py +2 -1
- parsl/tests/configs/ec2_single_node.py +1 -2
- parsl/tests/configs/ec2_spot.py +1 -2
- parsl/tests/configs/frontera.py +3 -2
- parsl/tests/configs/htex_ad_hoc_cluster.py +2 -4
- parsl/tests/configs/htex_local.py +2 -3
- parsl/tests/configs/htex_local_alternate.py +8 -11
- parsl/tests/configs/htex_local_intask_staging.py +5 -7
- parsl/tests/configs/htex_local_rsync_staging.py +4 -6
- parsl/tests/configs/local_adhoc.py +1 -1
- parsl/tests/configs/local_radical.py +1 -3
- parsl/tests/configs/local_radical_mpi.py +2 -2
- parsl/tests/configs/midway.py +2 -2
- parsl/tests/configs/nscc_singapore.py +3 -3
- parsl/tests/configs/osg_htex.py +1 -1
- parsl/tests/configs/petrelkube.py +3 -2
- parsl/tests/configs/summit.py +1 -0
- parsl/tests/configs/swan_htex.py +2 -2
- parsl/tests/configs/taskvine_ex.py +3 -5
- parsl/tests/configs/theta.py +2 -2
- parsl/tests/configs/workqueue_ex.py +3 -4
- parsl/tests/conftest.py +6 -6
- parsl/tests/integration/test_channels/test_ssh_errors.py +1 -1
- parsl/tests/integration/test_stress/test_python_simple.py +3 -4
- parsl/tests/integration/test_stress/test_python_threads.py +3 -5
- parsl/tests/manual_tests/htex_local.py +4 -4
- parsl/tests/manual_tests/test_ad_hoc_htex.py +2 -1
- parsl/tests/manual_tests/test_basic.py +1 -0
- parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +4 -4
- parsl/tests/manual_tests/test_log_filter.py +3 -1
- parsl/tests/manual_tests/test_memory_limits.py +6 -6
- parsl/tests/manual_tests/test_regression_220.py +2 -1
- parsl/tests/manual_tests/test_udp_simple.py +4 -3
- parsl/tests/manual_tests/test_worker_count.py +3 -2
- parsl/tests/scaling_tests/htex_local.py +2 -2
- parsl/tests/scaling_tests/test_scale.py +0 -9
- parsl/tests/scaling_tests/vineex_condor.py +1 -2
- parsl/tests/scaling_tests/vineex_local.py +1 -2
- parsl/tests/site_tests/test_provider.py +3 -1
- parsl/tests/site_tests/test_site.py +2 -0
- parsl/tests/sites/test_affinity.py +7 -5
- parsl/tests/sites/test_dynamic_executor.py +3 -4
- parsl/tests/sites/test_ec2.py +3 -2
- parsl/tests/sites/test_local_adhoc.py +2 -1
- parsl/tests/sites/test_worker_info.py +4 -3
- parsl/tests/test_aalst_patterns.py +0 -1
- parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
- parsl/tests/test_bash_apps/test_error_codes.py +1 -4
- parsl/tests/test_bash_apps/test_memoize_ignore_args.py +1 -0
- parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +2 -2
- parsl/tests/test_bash_apps/test_pipeline.py +1 -1
- parsl/tests/test_bash_apps/test_std_uri.py +4 -9
- parsl/tests/test_callables.py +2 -2
- parsl/tests/test_checkpointing/test_periodic.py +2 -7
- parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
- parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
- parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
- parsl/tests/test_checkpointing/test_regression_239.py +1 -1
- parsl/tests/test_checkpointing/test_task_exit.py +1 -2
- parsl/tests/test_docs/test_from_slides.py +2 -2
- parsl/tests/test_docs/test_kwargs.py +1 -1
- parsl/tests/test_docs/test_tutorial_1.py +1 -2
- parsl/tests/test_docs/test_workflow1.py +2 -2
- parsl/tests/test_docs/test_workflow2.py +0 -1
- parsl/tests/test_error_handling/test_rand_fail.py +2 -2
- parsl/tests/test_error_handling/test_resource_spec.py +4 -2
- parsl/tests/test_error_handling/test_retries.py +2 -1
- parsl/tests/test_error_handling/test_retry_handler.py +1 -0
- parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
- parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
- parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
- parsl/tests/test_flux.py +1 -1
- parsl/tests/test_htex/test_basic.py +0 -1
- parsl/tests/test_htex/test_command_client_timeout.py +66 -0
- parsl/tests/test_htex/test_connected_blocks.py +3 -2
- parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
- parsl/tests/test_htex/test_disconnected_blocks.py +6 -4
- parsl/tests/test_htex/test_drain.py +5 -5
- parsl/tests/test_htex/test_htex.py +1 -2
- parsl/tests/test_htex/test_manager_failure.py +0 -1
- parsl/tests/test_htex/test_managers_command.py +5 -9
- parsl/tests/test_htex/test_missing_worker.py +2 -8
- parsl/tests/test_htex/test_multiple_disconnected_blocks.py +6 -4
- parsl/tests/test_monitoring/test_app_names.py +3 -3
- parsl/tests/test_monitoring/test_basic.py +4 -6
- parsl/tests/test_monitoring/test_db_locks.py +6 -4
- parsl/tests/test_monitoring/test_fuzz_zmq.py +6 -4
- parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +5 -7
- parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
- parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
- parsl/tests/test_monitoring/test_stdouterr.py +4 -6
- parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
- parsl/tests/test_mpi_apps/test_bad_mpi_config.py +1 -1
- parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +4 -7
- parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +15 -4
- parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
- parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
- parsl/tests/test_mpi_apps/test_mpiex.py +4 -3
- parsl/tests/test_mpi_apps/test_resource_spec.py +21 -17
- parsl/tests/test_providers/test_cobalt_deprecation_warning.py +2 -0
- parsl/tests/test_providers/test_local_provider.py +2 -1
- parsl/tests/test_providers/test_pbspro_template.py +1 -1
- parsl/tests/test_providers/test_slurm_template.py +1 -1
- parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
- parsl/tests/test_python_apps/test_context_manager.py +5 -12
- parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
- parsl/tests/test_python_apps/test_futures.py +2 -1
- parsl/tests/test_python_apps/test_join.py +0 -1
- parsl/tests/test_python_apps/test_lifted.py +11 -7
- parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
- parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
- parsl/tests/test_radical/test_mpi_funcs.py +1 -1
- parsl/tests/test_regression/test_1480.py +2 -1
- parsl/tests/test_regression/test_1653.py +2 -1
- parsl/tests/test_regression/test_2652.py +1 -0
- parsl/tests/test_regression/test_69a.py +0 -1
- parsl/tests/test_regression/test_854.py +4 -2
- parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
- parsl/tests/test_regression/test_98.py +0 -1
- parsl/tests/test_scaling/test_block_error_handler.py +9 -4
- parsl/tests/test_scaling/test_regression_1621.py +0 -2
- parsl/tests/test_scaling/test_scale_down.py +2 -3
- parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +4 -5
- parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +3 -4
- parsl/tests/test_scaling/test_shutdown_scalein.py +1 -4
- parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
- parsl/tests/test_serialization/test_basic.py +2 -1
- parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
- parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
- parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
- parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
- parsl/tests/test_shutdown/test_kill_monitoring.py +3 -4
- parsl/tests/test_staging/staging_provider.py +2 -2
- parsl/tests/test_staging/test_1316.py +3 -4
- parsl/tests/test_staging/test_docs_1.py +1 -1
- parsl/tests/test_staging/test_docs_2.py +2 -1
- parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
- parsl/tests/test_staging/test_staging_https.py +2 -2
- parsl/tests/test_staging/test_staging_stdout.py +4 -3
- parsl/tests/test_staging/test_zip_in.py +6 -8
- parsl/tests/test_staging/test_zip_out.py +7 -9
- parsl/tests/test_staging/test_zip_to_zip.py +6 -8
- parsl/tests/test_summary.py +2 -2
- parsl/tests/test_thread_parallelism.py +0 -1
- parsl/tests/test_threads/test_configs.py +1 -2
- parsl/tests/test_threads/test_lazy_errors.py +2 -2
- parsl/usage_tracking/api.py +2 -3
- parsl/usage_tracking/usage.py +8 -18
- parsl/utils.py +13 -2
- parsl/version.py +1 -1
- {parsl-2024.5.20.data → parsl-2024.6.3.data}/scripts/exec_parsl_function.py +5 -4
- {parsl-2024.5.20.data → parsl-2024.6.3.data}/scripts/process_worker_pool.py +31 -20
- {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/METADATA +6 -6
- parsl-2024.6.3.dist-info/RECORD +471 -0
- parsl-2024.5.20.dist-info/RECORD +0 -468
- {parsl-2024.5.20.data → parsl-2024.6.3.data}/scripts/parsl_coprocess.py +1 -1
- {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/LICENSE +0 -0
- {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/WHEEL +0 -0
- {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/entry_points.txt +0 -0
- {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@ import pytest
|
|
2
2
|
|
3
3
|
from parsl import Config
|
4
4
|
from parsl.executors import HighThroughputExecutor
|
5
|
-
from parsl.launchers import
|
5
|
+
from parsl.launchers import AprunLauncher, SimpleLauncher, SrunLauncher
|
6
6
|
from parsl.providers import SlurmProvider
|
7
7
|
|
8
8
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from typing import Dict
|
2
|
+
|
2
3
|
import pytest
|
4
|
+
|
3
5
|
import parsl
|
4
6
|
from parsl import python_app
|
5
7
|
from parsl.tests.configs.htex_local import fresh_config
|
@@ -7,17 +9,12 @@ from parsl.tests.configs.htex_local import fresh_config
|
|
7
9
|
EXECUTOR_LABEL = "MPI_TEST"
|
8
10
|
|
9
11
|
|
10
|
-
def
|
12
|
+
def local_config():
|
11
13
|
config = fresh_config()
|
12
14
|
config.executors[0].label = EXECUTOR_LABEL
|
13
15
|
config.executors[0].max_workers_per_node = 1
|
14
16
|
config.executors[0].enable_mpi_mode = False
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def local_teardown():
|
19
|
-
parsl.dfk().cleanup()
|
20
|
-
parsl.clear()
|
17
|
+
return config
|
21
18
|
|
22
19
|
|
23
20
|
@python_app
|
@@ -1,13 +1,17 @@
|
|
1
1
|
import logging
|
2
|
+
import os
|
2
3
|
import random
|
3
4
|
from typing import Dict
|
5
|
+
|
4
6
|
import pytest
|
7
|
+
|
5
8
|
import parsl
|
6
|
-
from parsl import
|
9
|
+
from parsl import bash_app, python_app
|
10
|
+
from parsl.executors.high_throughput.mpi_prefix_composer import (
|
11
|
+
MissingResourceSpecification,
|
12
|
+
)
|
7
13
|
from parsl.tests.configs.htex_local import fresh_config
|
8
14
|
|
9
|
-
import os
|
10
|
-
|
11
15
|
EXECUTOR_LABEL = "MPI_TEST"
|
12
16
|
|
13
17
|
|
@@ -28,7 +32,6 @@ def local_setup():
|
|
28
32
|
|
29
33
|
def local_teardown():
|
30
34
|
parsl.dfk().cleanup()
|
31
|
-
parsl.clear()
|
32
35
|
|
33
36
|
|
34
37
|
@python_app
|
@@ -169,3 +172,11 @@ def test_simulated_load(rounds: int = 100):
|
|
169
172
|
total_ranks, nodes = future.result(timeout=10)
|
170
173
|
assert len(nodes) == futures[future]["num_nodes"]
|
171
174
|
assert total_ranks == futures[future]["num_nodes"] * futures[future]["ranks_per_node"]
|
175
|
+
|
176
|
+
|
177
|
+
@pytest.mark.local
|
178
|
+
def test_missing_resource_spec():
|
179
|
+
|
180
|
+
with pytest.raises(MissingResourceSpecification):
|
181
|
+
future = mock_app(sleep_dur=0.4)
|
182
|
+
future.result(timeout=10)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
import logging
|
2
|
+
|
2
3
|
import pytest
|
3
4
|
|
4
|
-
from parsl.executors.high_throughput.mpi_resource_management import Scheduler
|
5
5
|
from parsl.executors.high_throughput.mpi_prefix_composer import (
|
6
|
-
|
6
|
+
compose_all,
|
7
7
|
compose_aprun_launch_cmd,
|
8
8
|
compose_mpiexec_launch_cmd,
|
9
|
-
|
9
|
+
compose_srun_launch_cmd,
|
10
10
|
)
|
11
|
-
|
11
|
+
from parsl.executors.high_throughput.mpi_resource_management import Scheduler
|
12
12
|
|
13
13
|
resource_spec = {"num_nodes": 2,
|
14
14
|
"num_ranks": 8,
|
@@ -1,9 +1,14 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
+
import pickle
|
3
4
|
from unittest import mock
|
5
|
+
|
4
6
|
import pytest
|
5
|
-
|
6
|
-
from parsl.executors.high_throughput.mpi_resource_management import
|
7
|
+
|
8
|
+
from parsl.executors.high_throughput.mpi_resource_management import (
|
9
|
+
MPITaskScheduler,
|
10
|
+
TaskScheduler,
|
11
|
+
)
|
7
12
|
from parsl.multiprocessing import SpawnContext
|
8
13
|
from parsl.serialize import pack_res_spec_apply_message, unpack_res_spec_apply_message
|
9
14
|
|
@@ -5,11 +5,12 @@ from pathlib import Path
|
|
5
5
|
import pytest
|
6
6
|
|
7
7
|
import parsl
|
8
|
-
from
|
9
|
-
from parsl import
|
8
|
+
from parsl import Config, HighThroughputExecutor
|
9
|
+
from parsl.executors.high_throughput.mpi_executor import MPIExecutor
|
10
10
|
from parsl.launchers import SimpleLauncher
|
11
11
|
from parsl.providers import LocalProvider
|
12
|
-
|
12
|
+
|
13
|
+
from .test_mpi_mode_enabled import get_env_vars
|
13
14
|
|
14
15
|
cwd = Path(__file__).parent.absolute()
|
15
16
|
pbs_nodefile = cwd.joinpath("mocks", "pbs_nodefile")
|
@@ -2,25 +2,25 @@ import contextlib
|
|
2
2
|
import logging
|
3
3
|
import os
|
4
4
|
import typing
|
5
|
-
|
5
|
+
import unittest
|
6
|
+
from typing import Dict
|
6
7
|
|
7
8
|
import pytest
|
8
|
-
import unittest
|
9
9
|
|
10
10
|
import parsl
|
11
11
|
from parsl.app.app import python_app
|
12
|
-
from parsl.
|
13
|
-
|
12
|
+
from parsl.executors.high_throughput.mpi_prefix_composer import (
|
13
|
+
InvalidResourceSpecification,
|
14
|
+
MissingResourceSpecification,
|
15
|
+
validate_resource_spec,
|
16
|
+
)
|
14
17
|
from parsl.executors.high_throughput.mpi_resource_management import (
|
18
|
+
get_nodes_in_batchjob,
|
15
19
|
get_pbs_hosts_list,
|
16
20
|
get_slurm_hosts_list,
|
17
|
-
get_nodes_in_batchjob,
|
18
21
|
identify_scheduler,
|
19
22
|
)
|
20
|
-
from parsl.
|
21
|
-
validate_resource_spec,
|
22
|
-
InvalidResourceSpecification
|
23
|
-
)
|
23
|
+
from parsl.tests.configs.htex_local import fresh_config
|
24
24
|
|
25
25
|
EXECUTOR_LABEL = "MPI_TEST"
|
26
26
|
|
@@ -122,18 +122,22 @@ def test_top_level():
|
|
122
122
|
|
123
123
|
@pytest.mark.local
|
124
124
|
@pytest.mark.parametrize(
|
125
|
-
"resource_spec, exception",
|
125
|
+
"resource_spec, is_mpi_enabled, exception",
|
126
126
|
(
|
127
|
-
({"num_nodes": 2, "ranks_per_node": 1}, None),
|
128
|
-
({"launcher_options": "--debug_foo"}, None),
|
129
|
-
({"num_nodes": 2, "BAD_OPT": 1}, InvalidResourceSpecification),
|
130
|
-
({}, None),
|
127
|
+
({"num_nodes": 2, "ranks_per_node": 1}, False, None),
|
128
|
+
({"launcher_options": "--debug_foo"}, False, None),
|
129
|
+
({"num_nodes": 2, "BAD_OPT": 1}, False, InvalidResourceSpecification),
|
130
|
+
({}, False, None),
|
131
|
+
({"num_nodes": 2, "ranks_per_node": 1}, True, None),
|
132
|
+
({"launcher_options": "--debug_foo"}, True, None),
|
133
|
+
({"num_nodes": 2, "BAD_OPT": 1}, True, InvalidResourceSpecification),
|
134
|
+
({}, True, MissingResourceSpecification),
|
131
135
|
)
|
132
136
|
)
|
133
|
-
def test_resource_spec(resource_spec: Dict, exception):
|
137
|
+
def test_resource_spec(resource_spec: Dict, is_mpi_enabled: bool, exception):
|
134
138
|
if exception:
|
135
139
|
with pytest.raises(exception):
|
136
|
-
validate_resource_spec(resource_spec)
|
140
|
+
validate_resource_spec(resource_spec, is_mpi_enabled)
|
137
141
|
else:
|
138
|
-
result = validate_resource_spec(resource_spec)
|
142
|
+
result = validate_resource_spec(resource_spec, is_mpi_enabled)
|
139
143
|
assert result is None
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
3
|
import pathlib
|
4
|
-
import pytest
|
5
4
|
import random
|
6
5
|
import shutil
|
7
6
|
import socket
|
@@ -10,6 +9,8 @@ import tempfile
|
|
10
9
|
import threading
|
11
10
|
import time
|
12
11
|
|
12
|
+
import pytest
|
13
|
+
|
13
14
|
from parsl.channels import LocalChannel, SSHChannel
|
14
15
|
from parsl.jobs.states import JobState
|
15
16
|
from parsl.launchers import SingleNodeLauncher
|
@@ -1,8 +1,9 @@
|
|
1
|
-
import parsl
|
2
|
-
from parsl.tests.configs.local_threads import fresh_config
|
3
1
|
import pytest
|
4
|
-
|
2
|
+
|
3
|
+
import parsl
|
5
4
|
from parsl.dataflow.dflow import DataFlowKernel
|
5
|
+
from parsl.errors import NoDataFlowKernelError
|
6
|
+
from parsl.tests.configs.local_threads import fresh_config
|
6
7
|
|
7
8
|
|
8
9
|
@parsl.python_app
|
@@ -15,14 +16,6 @@ def foo(x, stdout='foo.stdout'):
|
|
15
16
|
return f"echo {x + 1}"
|
16
17
|
|
17
18
|
|
18
|
-
def local_setup():
|
19
|
-
pass
|
20
|
-
|
21
|
-
|
22
|
-
def local_teardown():
|
23
|
-
parsl.clear()
|
24
|
-
|
25
|
-
|
26
19
|
@pytest.mark.local
|
27
20
|
def test_within_context_manger(tmpd_cwd):
|
28
21
|
config = fresh_config()
|
@@ -37,4 +30,4 @@ def test_within_context_manger(tmpd_cwd):
|
|
37
30
|
|
38
31
|
with pytest.raises(NoDataFlowKernelError) as excinfo:
|
39
32
|
square(2).result()
|
40
|
-
assert str(excinfo.value) == "
|
33
|
+
assert str(excinfo.value) == "Must first load config"
|
@@ -11,9 +11,10 @@ Same applies to datafutures, and we need to know the behavior wrt.
|
|
11
11
|
2. done() called on 1, vs 2
|
12
12
|
|
13
13
|
"""
|
14
|
-
import pytest
|
15
14
|
from os.path import basename
|
16
15
|
|
16
|
+
import pytest
|
17
|
+
|
17
18
|
from parsl.app.app import python_app
|
18
19
|
from parsl.data_provider.files import File
|
19
20
|
|
@@ -1,26 +1,30 @@
|
|
1
|
+
from concurrent.futures import Future
|
2
|
+
from typing import TypeVar
|
3
|
+
|
1
4
|
import pytest
|
2
5
|
|
3
|
-
from concurrent.futures import Future
|
4
6
|
from parsl import python_app
|
5
7
|
|
8
|
+
T = TypeVar('T')
|
9
|
+
|
6
10
|
|
7
11
|
@python_app
|
8
|
-
def returns_a_dict():
|
12
|
+
def returns_a_dict() -> dict:
|
9
13
|
return {"a": "X", "b": "Y"}
|
10
14
|
|
11
15
|
|
12
16
|
@python_app
|
13
|
-
def returns_a_list():
|
17
|
+
def returns_a_list() -> list:
|
14
18
|
return ["X", "Y"]
|
15
19
|
|
16
20
|
|
17
21
|
@python_app
|
18
|
-
def returns_a_tuple():
|
22
|
+
def returns_a_tuple() -> tuple:
|
19
23
|
return ("X", "Y")
|
20
24
|
|
21
25
|
|
22
26
|
@python_app
|
23
|
-
def returns_a_class():
|
27
|
+
def returns_a_class() -> type:
|
24
28
|
from dataclasses import dataclass
|
25
29
|
|
26
30
|
@dataclass
|
@@ -38,7 +42,7 @@ class MyOuterClass():
|
|
38
42
|
|
39
43
|
|
40
44
|
@python_app
|
41
|
-
def returns_a_class_instance():
|
45
|
+
def returns_a_class_instance() -> object:
|
42
46
|
return MyOuterClass()
|
43
47
|
|
44
48
|
|
@@ -110,7 +114,7 @@ def test_returns_a_class():
|
|
110
114
|
|
111
115
|
|
112
116
|
@python_app
|
113
|
-
def passthrough(v):
|
117
|
+
def passthrough(v: T) -> T:
|
114
118
|
return v
|
115
119
|
|
116
120
|
|
@@ -0,0 +1,161 @@
|
|
1
|
+
from concurrent.futures import Future
|
2
|
+
from pathlib import Path
|
3
|
+
from threading import Event
|
4
|
+
from typing import Sequence
|
5
|
+
|
6
|
+
import pytest
|
7
|
+
|
8
|
+
import parsl
|
9
|
+
from parsl.config import Config
|
10
|
+
from parsl.dataflow.dependency_resolvers import DEEP_DEPENDENCY_RESOLVER
|
11
|
+
from parsl.dataflow.errors import DependencyError
|
12
|
+
|
13
|
+
|
14
|
+
def local_config():
|
15
|
+
return Config(dependency_resolver=DEEP_DEPENDENCY_RESOLVER)
|
16
|
+
|
17
|
+
|
18
|
+
@parsl.python_app
|
19
|
+
def a(event):
|
20
|
+
event.wait()
|
21
|
+
return 7
|
22
|
+
|
23
|
+
|
24
|
+
@parsl.python_app
|
25
|
+
def b(x: int):
|
26
|
+
return x + 1
|
27
|
+
|
28
|
+
|
29
|
+
@pytest.mark.local
|
30
|
+
def test_simple_pos_arg():
|
31
|
+
e = Event()
|
32
|
+
s = a(e)
|
33
|
+
f_b = b(s)
|
34
|
+
e.set()
|
35
|
+
|
36
|
+
assert f_b.result() == 8
|
37
|
+
|
38
|
+
|
39
|
+
@parsl.python_app
|
40
|
+
def b_first(x: Sequence[int]):
|
41
|
+
return x[0] + 1
|
42
|
+
|
43
|
+
|
44
|
+
@pytest.mark.local
|
45
|
+
def test_tuple_pos_arg():
|
46
|
+
e = Event()
|
47
|
+
s = (a(e),)
|
48
|
+
f_b = b_first(s)
|
49
|
+
e.set()
|
50
|
+
assert f_b.result() == 8
|
51
|
+
|
52
|
+
|
53
|
+
@pytest.mark.local
|
54
|
+
def test_list_exception():
|
55
|
+
a = Future()
|
56
|
+
a.set_exception(RuntimeError("artificial error"))
|
57
|
+
f_b = b([a])
|
58
|
+
assert isinstance(f_b.exception(), DependencyError)
|
59
|
+
|
60
|
+
|
61
|
+
@parsl.python_app
|
62
|
+
def make_path(s: str):
|
63
|
+
return Path(s)
|
64
|
+
|
65
|
+
|
66
|
+
@parsl.python_app
|
67
|
+
def append_paths(iterable, end_str: str = "end"):
|
68
|
+
type_ = type(iterable)
|
69
|
+
return type_([Path(s, end_str) for s in iterable])
|
70
|
+
|
71
|
+
|
72
|
+
@pytest.mark.local
|
73
|
+
@pytest.mark.parametrize(
|
74
|
+
"type_",
|
75
|
+
[
|
76
|
+
tuple,
|
77
|
+
list,
|
78
|
+
set,
|
79
|
+
],
|
80
|
+
)
|
81
|
+
def test_resolving_iterables(type_):
|
82
|
+
output1 = make_path("test1")
|
83
|
+
output2 = make_path("test2")
|
84
|
+
output3 = append_paths(type_([output1, output2]), end_str="end")
|
85
|
+
assert output3.result() == type_([Path("test1", "end"), Path("test2", "end")])
|
86
|
+
|
87
|
+
|
88
|
+
@parsl.python_app
|
89
|
+
def append_paths_dict(iterable: dict, end_str: str = "end"):
|
90
|
+
return {Path(k, end_str): Path(v, end_str) for k, v in iterable.items()}
|
91
|
+
|
92
|
+
|
93
|
+
@pytest.mark.local
|
94
|
+
def test_resolving_dict():
|
95
|
+
output1 = make_path("test1")
|
96
|
+
output2 = make_path("test2")
|
97
|
+
output3 = append_paths_dict({output1: output2}, end_str="end")
|
98
|
+
assert output3.result() == {Path("test1", "end"): Path("test2", "end")}
|
99
|
+
|
100
|
+
|
101
|
+
@parsl.python_app
|
102
|
+
def extract_deep(struct: list):
|
103
|
+
return struct[0][0][0][0][0]
|
104
|
+
|
105
|
+
|
106
|
+
@pytest.mark.local
|
107
|
+
def test_deeper_list():
|
108
|
+
f = Future()
|
109
|
+
f.set_result(7)
|
110
|
+
f_b = extract_deep([[[[[f]]]]])
|
111
|
+
|
112
|
+
assert f_b.result() == 7
|
113
|
+
|
114
|
+
|
115
|
+
@pytest.mark.local
|
116
|
+
def test_deeper_list_and_tuple():
|
117
|
+
f = Future()
|
118
|
+
f.set_result(7)
|
119
|
+
f_b = extract_deep([([([f],)],)])
|
120
|
+
|
121
|
+
assert f_b.result() == 7
|
122
|
+
|
123
|
+
|
124
|
+
@parsl.python_app
|
125
|
+
def dictionary_checker(d):
|
126
|
+
assert d["a"] == [30, 10]
|
127
|
+
assert d["b"] == 20
|
128
|
+
|
129
|
+
|
130
|
+
@pytest.mark.local
|
131
|
+
def test_dictionary():
|
132
|
+
k1 = Future()
|
133
|
+
k1.set_result("a")
|
134
|
+
k2 = Future()
|
135
|
+
k2.set_result("b")
|
136
|
+
v1 = Future()
|
137
|
+
v1.set_result(10)
|
138
|
+
|
139
|
+
# this .result() will fail if the asserts fail
|
140
|
+
dictionary_checker({k1: [30, v1], k2: 20}).result()
|
141
|
+
|
142
|
+
|
143
|
+
@pytest.mark.local
|
144
|
+
def test_dictionary_later():
|
145
|
+
k1 = Future()
|
146
|
+
k2 = Future()
|
147
|
+
v1 = Future()
|
148
|
+
|
149
|
+
f1 = dictionary_checker({k1: [30, v1], k2: 20})
|
150
|
+
|
151
|
+
assert not f1.done()
|
152
|
+
k1.set_result("a")
|
153
|
+
k2.set_result("b")
|
154
|
+
v1.set_result(10)
|
155
|
+
|
156
|
+
# having set the results, f1 should fairly rapidly complete (but not
|
157
|
+
# instantly) so we can't assert on done() here... but we can
|
158
|
+
# check that f1 does "eventually" complete... meaning that
|
159
|
+
# none of the assertions inside test_dictionary have failed
|
160
|
+
|
161
|
+
assert f1.result() is None
|
@@ -1,11 +1,10 @@
|
|
1
1
|
import pytest
|
2
2
|
|
3
3
|
import parsl
|
4
|
-
|
5
4
|
from parsl.config import Config
|
6
5
|
from parsl.executors import HighThroughputExecutor
|
7
|
-
from parsl.providers import LocalProvider
|
8
6
|
from parsl.launchers import SimpleLauncher
|
7
|
+
from parsl.providers import LocalProvider
|
9
8
|
|
10
9
|
|
11
10
|
def local_config() -> Config:
|
@@ -1,11 +1,16 @@
|
|
1
|
+
from functools import partial
|
2
|
+
from unittest.mock import Mock
|
3
|
+
|
1
4
|
import pytest
|
2
5
|
|
3
6
|
from parsl.executors import HighThroughputExecutor
|
7
|
+
from parsl.jobs.error_handlers import (
|
8
|
+
noop_error_handler,
|
9
|
+
simple_error_handler,
|
10
|
+
windowed_error_handler,
|
11
|
+
)
|
12
|
+
from parsl.jobs.states import JobState, JobStatus
|
4
13
|
from parsl.providers import LocalProvider
|
5
|
-
from unittest.mock import Mock
|
6
|
-
from parsl.jobs.states import JobStatus, JobState
|
7
|
-
from parsl.jobs.error_handlers import simple_error_handler, windowed_error_handler, noop_error_handler
|
8
|
-
from functools import partial
|
9
14
|
|
10
15
|
|
11
16
|
@pytest.mark.local
|
@@ -4,13 +4,12 @@ import time
|
|
4
4
|
import pytest
|
5
5
|
|
6
6
|
import parsl
|
7
|
-
|
8
7
|
from parsl import File, python_app
|
9
|
-
from parsl.providers import LocalProvider
|
10
8
|
from parsl.channels import LocalChannel
|
11
|
-
from parsl.launchers import SingleNodeLauncher
|
12
9
|
from parsl.config import Config
|
13
10
|
from parsl.executors import HighThroughputExecutor
|
11
|
+
from parsl.launchers import SingleNodeLauncher
|
12
|
+
from parsl.providers import LocalProvider
|
14
13
|
|
15
14
|
logger = logging.getLogger(__name__)
|
16
15
|
|