hpcflow-new2 0.2.0a149__tar.gz → 0.2.0a153__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.
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/PKG-INFO +1 -1
- hpcflow_new2-0.2.0a153/hpcflow/_version.py +1 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/app.py +35 -4
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/cli.py +32 -1
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/cli_common.py +11 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/actions.py +2 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/errors.py +4 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/task.py +8 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/utils.py +44 -16
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/workflow.py +108 -20
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/demo/cli.py +7 -0
- hpcflow_new2-0.2.0a153/hpcflow/sdk/log.py +173 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/base.py +4 -1
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/pending.py +26 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/zarr.py +3 -0
- hpcflow_new2-0.2.0a153/hpcflow/tests/data/benchmark_N_elements.yaml +6 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_utils.py +45 -1
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_workflow_template.py +9 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/pyproject.toml +2 -2
- hpcflow_new2-0.2.0a149/hpcflow/_version.py +0 -1
- hpcflow_new2-0.2.0a149/hpcflow/sdk/log.py +0 -49
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/README.md +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/__pyinstaller/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/__pyinstaller/hook-hpcflow.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/app.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/cli.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/demo_data_manifest/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/demo_data_manifest/demo_data_manifest.json +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/demo_task_1_generate_t1_infile_1.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/demo_task_1_generate_t1_infile_2.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/demo_task_1_parse_p3.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/generate_t1_file_01.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_direct_in_direct_out.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_all_iters_test.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_direct_in_direct_out_labels.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_direct_sub_param_in_direct_out.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_and_direct_in_json_out.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_in_json_and_direct_out.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_in_json_out.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_in_json_out_labels.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_in_obj.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_out_obj.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/main_script_test_json_sub_param_in_json_out_labels.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/scripts/parse_t1_file_01.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/template_components/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/template_components/command_files.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/template_components/environments.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/template_components/parameters.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/template_components/task_schemas.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/workflows/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/data/workflows/workflow_1.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/examples.ipynb +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/config/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/config/callbacks.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/config/cli.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/config/config.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/config/config_file.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/config/errors.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/command_files.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/commands.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/element.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/environment.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/json_like.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/loop.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/object_list.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/parallel.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/parameters.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/rule.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/task_schema.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/test_utils.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/validation.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/core/zarr_io.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/config_file_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/config_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/environments_spec_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/files_spec_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/parameters_spec_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/task_schema_spec_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/data/workflow_spec_schema.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/demo/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/helper/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/helper/cli.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/helper/helper.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/helper/watcher.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/json.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/store_resource.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/persistence/utils.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/runtime.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/jobscript.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/jobscript_info.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/schedulers/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/schedulers/direct.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/schedulers/sge.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/schedulers/slurm.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/schedulers/utils.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/shells/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/shells/base.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/shells/bash.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/shells/os_version.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/shells/powershell.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/submission/submission.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/sdk/typing.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/conftest.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/data/__init__.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/data/workflow_1.json +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/data/workflow_1.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/data/workflow_1_slurm.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/data/workflow_1_wsl.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/data/workflow_test_run_abort.yaml +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/schedulers/direct_linux/test_direct_linux_submission.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/schedulers/slurm/test_slurm_submission.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/scripts/test_main_scripts.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/shells/wsl/test_wsl_submission.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_action.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_action_rule.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_app.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_cli.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_command.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_config.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_config_file.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_element.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_element_iteration.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_element_set.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_input_source.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_input_value.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_json_like.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_loop.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_object_list.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_parameter.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_persistence.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_resources.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_run.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_runtime.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_schema_input.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_shell.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_slurm.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_submission.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_task.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_task_schema.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_value_sequence.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/unit/test_workflow.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/workflows/test_jobscript.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/tests/workflows/test_workflows.py +0 -0
- {hpcflow_new2-0.2.0a149 → hpcflow_new2-0.2.0a153}/hpcflow/viz_demo.ipynb +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.2.0a153"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
"""An hpcflow application."""
|
2
|
+
|
2
3
|
from __future__ import annotations
|
3
4
|
|
4
5
|
from collections import defaultdict
|
@@ -37,7 +38,7 @@ from hpcflow.sdk.core.actions import EARStatus
|
|
37
38
|
from hpcflow.sdk.core.errors import WorkflowNotFoundError
|
38
39
|
from hpcflow.sdk.core.object_list import ObjectList
|
39
40
|
from hpcflow.sdk.core.utils import (
|
40
|
-
|
41
|
+
read_YAML_str,
|
41
42
|
read_YAML_file,
|
42
43
|
read_JSON_file,
|
43
44
|
write_YAML_file,
|
@@ -46,7 +47,7 @@ from hpcflow.sdk.core.utils import (
|
|
46
47
|
from hpcflow.sdk import sdk_classes, sdk_funcs, get_SDK_logger
|
47
48
|
from hpcflow.sdk.config import Config, ConfigFile
|
48
49
|
from hpcflow.sdk.core import ALL_TEMPLATE_FORMATS
|
49
|
-
from hpcflow.sdk.log import AppLog
|
50
|
+
from hpcflow.sdk.log import AppLog, TimeIt
|
50
51
|
from hpcflow.sdk.persistence import DEFAULT_STORE_FORMAT
|
51
52
|
from hpcflow.sdk.persistence.base import TEMPLATE_COMP_TYPES
|
52
53
|
from hpcflow.sdk.runtime import RunTimeInfo
|
@@ -95,7 +96,10 @@ class Singleton(type):
|
|
95
96
|
_instances = {}
|
96
97
|
|
97
98
|
def __call__(cls, *args, **kwargs):
|
98
|
-
SDK_logger.info(
|
99
|
+
SDK_logger.info(
|
100
|
+
f"App metaclass __call__: "
|
101
|
+
f"name={kwargs['name']!r}, version={kwargs['version']!r}."
|
102
|
+
)
|
99
103
|
if cls not in cls._instances:
|
100
104
|
SDK_logger.info(f"App metaclass initialising new object {kwargs['name']!r}.")
|
101
105
|
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
@@ -255,6 +259,14 @@ class BaseApp(metaclass=Singleton):
|
|
255
259
|
def log(self) -> AppLog:
|
256
260
|
return self._log
|
257
261
|
|
262
|
+
@property
|
263
|
+
def timeit(self) -> bool:
|
264
|
+
return TimeIt.active
|
265
|
+
|
266
|
+
@timeit.setter
|
267
|
+
def timeit(self, value: bool):
|
268
|
+
TimeIt.active = bool(value)
|
269
|
+
|
258
270
|
@property
|
259
271
|
def template_components(self) -> Dict[str, ObjectList]:
|
260
272
|
if not self.is_template_components_loaded:
|
@@ -281,6 +293,7 @@ class BaseApp(metaclass=Singleton):
|
|
281
293
|
warnings.warn("Template components not loaded; loading now.")
|
282
294
|
self._load_template_components()
|
283
295
|
|
296
|
+
@TimeIt.decorator
|
284
297
|
def _load_template_components(self, *include) -> None:
|
285
298
|
"""Combine any builtin template components with user-defined template components
|
286
299
|
and initialise list objects."""
|
@@ -366,7 +379,7 @@ class BaseApp(metaclass=Singleton):
|
|
366
379
|
fh = resources.open_text(package, resource)
|
367
380
|
SDK_logger.info(f"Parsing file as YAML: {fh.name!r}")
|
368
381
|
comp_dat = fh.read()
|
369
|
-
components[comp_type] =
|
382
|
+
components[comp_type] = read_YAML_str(comp_dat)
|
370
383
|
fh.close()
|
371
384
|
|
372
385
|
return components
|
@@ -625,6 +638,7 @@ class BaseApp(metaclass=Singleton):
|
|
625
638
|
shutil.rmtree(self.user_cache_hostname_dir)
|
626
639
|
self._ensure_user_cache_hostname_dir()
|
627
640
|
|
641
|
+
@TimeIt.decorator
|
628
642
|
def _load_config(self, config_dir, config_key, **overrides) -> None:
|
629
643
|
self.logger.info("Loading configuration.")
|
630
644
|
self._ensure_user_data_dir()
|
@@ -714,6 +728,7 @@ class BaseApp(metaclass=Singleton):
|
|
714
728
|
self._config_files = {}
|
715
729
|
self._load_config(config_dir, config_key, **overrides)
|
716
730
|
|
731
|
+
@TimeIt.decorator
|
717
732
|
def _load_scripts(self):
|
718
733
|
# TODO: load custom directories / custom functions (via decorator)
|
719
734
|
|
@@ -1126,6 +1141,7 @@ class BaseApp(metaclass=Singleton):
|
|
1126
1141
|
ts_fmt: Optional[str] = None,
|
1127
1142
|
ts_name_fmt: Optional[str] = None,
|
1128
1143
|
store_kwargs: Optional[Dict] = None,
|
1144
|
+
variables: Optional[Dict[str, str]] = None,
|
1129
1145
|
) -> get_app_attribute("Workflow"):
|
1130
1146
|
"""Generate a new {app_name} workflow from a file or string containing a workflow
|
1131
1147
|
template parametrisation.
|
@@ -1160,6 +1176,8 @@ class BaseApp(metaclass=Singleton):
|
|
1160
1176
|
includes a timestamp.
|
1161
1177
|
store_kwargs
|
1162
1178
|
Keyword arguments to pass to the store's `write_empty_workflow` method.
|
1179
|
+
variables
|
1180
|
+
String variables to substitute in `template_file_or_str`.
|
1163
1181
|
"""
|
1164
1182
|
|
1165
1183
|
self.API_logger.info("make_workflow called")
|
@@ -1172,6 +1190,7 @@ class BaseApp(metaclass=Singleton):
|
|
1172
1190
|
"ts_fmt": ts_fmt,
|
1173
1191
|
"ts_name_fmt": ts_name_fmt,
|
1174
1192
|
"store_kwargs": store_kwargs,
|
1193
|
+
"variables": variables,
|
1175
1194
|
}
|
1176
1195
|
|
1177
1196
|
if not is_string:
|
@@ -1212,6 +1231,7 @@ class BaseApp(metaclass=Singleton):
|
|
1212
1231
|
ts_fmt: Optional[str] = None,
|
1213
1232
|
ts_name_fmt: Optional[str] = None,
|
1214
1233
|
store_kwargs: Optional[Dict] = None,
|
1234
|
+
variables: Optional[Dict[str, str]] = None,
|
1215
1235
|
JS_parallelism: Optional[bool] = None,
|
1216
1236
|
wait: Optional[bool] = False,
|
1217
1237
|
add_to_known: Optional[bool] = True,
|
@@ -1252,6 +1272,8 @@ class BaseApp(metaclass=Singleton):
|
|
1252
1272
|
includes a timestamp.
|
1253
1273
|
store_kwargs
|
1254
1274
|
Keyword arguments to pass to the store's `write_empty_workflow` method.
|
1275
|
+
variables
|
1276
|
+
String variables to substitute in `template_file_or_str`.
|
1255
1277
|
JS_parallelism
|
1256
1278
|
If True, allow multiple jobscripts to execute simultaneously. Raises if set to
|
1257
1279
|
True but the store type does not support the `jobscript_parallelism` feature. If
|
@@ -1282,6 +1304,7 @@ class BaseApp(metaclass=Singleton):
|
|
1282
1304
|
ts_fmt=ts_fmt,
|
1283
1305
|
ts_name_fmt=ts_name_fmt,
|
1284
1306
|
store_kwargs=store_kwargs,
|
1307
|
+
variables=variables,
|
1285
1308
|
)
|
1286
1309
|
return wk.submit(
|
1287
1310
|
JS_parallelism=JS_parallelism,
|
@@ -1302,6 +1325,7 @@ class BaseApp(metaclass=Singleton):
|
|
1302
1325
|
ts_fmt: Optional[str] = None,
|
1303
1326
|
ts_name_fmt: Optional[str] = None,
|
1304
1327
|
store_kwargs: Optional[Dict] = None,
|
1328
|
+
variables: Optional[Dict[str, str]] = None,
|
1305
1329
|
) -> get_app_attribute("Workflow"):
|
1306
1330
|
"""Generate a new {app_name} workflow from a builtin demo workflow template.
|
1307
1331
|
|
@@ -1333,6 +1357,8 @@ class BaseApp(metaclass=Singleton):
|
|
1333
1357
|
includes a timestamp.
|
1334
1358
|
store_kwargs
|
1335
1359
|
Keyword arguments to pass to the store's `write_empty_workflow` method.
|
1360
|
+
variables
|
1361
|
+
String variables to substitute in the demo workflow template file.
|
1336
1362
|
"""
|
1337
1363
|
|
1338
1364
|
self.API_logger.info("make_demo_workflow called")
|
@@ -1348,6 +1374,7 @@ class BaseApp(metaclass=Singleton):
|
|
1348
1374
|
ts_fmt=ts_fmt,
|
1349
1375
|
ts_name_fmt=ts_name_fmt,
|
1350
1376
|
store_kwargs=store_kwargs,
|
1377
|
+
variables=variables,
|
1351
1378
|
)
|
1352
1379
|
return wk
|
1353
1380
|
|
@@ -1362,6 +1389,7 @@ class BaseApp(metaclass=Singleton):
|
|
1362
1389
|
ts_fmt: Optional[str] = None,
|
1363
1390
|
ts_name_fmt: Optional[str] = None,
|
1364
1391
|
store_kwargs: Optional[Dict] = None,
|
1392
|
+
variables: Optional[Dict[str, str]] = None,
|
1365
1393
|
JS_parallelism: Optional[bool] = None,
|
1366
1394
|
wait: Optional[bool] = False,
|
1367
1395
|
add_to_known: Optional[bool] = True,
|
@@ -1399,6 +1427,8 @@ class BaseApp(metaclass=Singleton):
|
|
1399
1427
|
includes a timestamp.
|
1400
1428
|
store_kwargs
|
1401
1429
|
Keyword arguments to pass to the store's `write_empty_workflow` method.
|
1430
|
+
variables
|
1431
|
+
String variables to substitute in the demo workflow template file.
|
1402
1432
|
JS_parallelism
|
1403
1433
|
If True, allow multiple jobscripts to execute simultaneously. Raises if set to
|
1404
1434
|
True but the store type does not support the `jobscript_parallelism` feature. If
|
@@ -1428,6 +1458,7 @@ class BaseApp(metaclass=Singleton):
|
|
1428
1458
|
ts_fmt=ts_fmt,
|
1429
1459
|
ts_name_fmt=ts_name_fmt,
|
1430
1460
|
store_kwargs=store_kwargs,
|
1461
|
+
variables=variables,
|
1431
1462
|
)
|
1432
1463
|
return wk.submit(
|
1433
1464
|
JS_parallelism=JS_parallelism,
|
@@ -19,6 +19,7 @@ from hpcflow.sdk.cli_common import (
|
|
19
19
|
store_option,
|
20
20
|
ts_fmt_option,
|
21
21
|
ts_name_fmt_option,
|
22
|
+
variables_option,
|
22
23
|
js_parallelism_option,
|
23
24
|
wait_option,
|
24
25
|
add_to_known_opt,
|
@@ -31,6 +32,7 @@ from hpcflow.sdk.cli_common import (
|
|
31
32
|
unzip_log_opt,
|
32
33
|
)
|
33
34
|
from hpcflow.sdk.helper.cli import get_helper_CLI
|
35
|
+
from hpcflow.sdk.log import TimeIt
|
34
36
|
from hpcflow.sdk.submission.shells import ALL_SHELLS
|
35
37
|
|
36
38
|
string_option = click.option(
|
@@ -68,6 +70,7 @@ def _make_API_CLI(app):
|
|
68
70
|
@store_option
|
69
71
|
@ts_fmt_option
|
70
72
|
@ts_name_fmt_option
|
73
|
+
@variables_option
|
71
74
|
def make_workflow(
|
72
75
|
template_file_or_str,
|
73
76
|
string,
|
@@ -78,6 +81,7 @@ def _make_API_CLI(app):
|
|
78
81
|
store,
|
79
82
|
ts_fmt=None,
|
80
83
|
ts_name_fmt=None,
|
84
|
+
variables=None,
|
81
85
|
):
|
82
86
|
"""Generate a new {app_name} workflow.
|
83
87
|
|
@@ -95,6 +99,7 @@ def _make_API_CLI(app):
|
|
95
99
|
store=store,
|
96
100
|
ts_fmt=ts_fmt,
|
97
101
|
ts_name_fmt=ts_name_fmt,
|
102
|
+
variables=dict(variables),
|
98
103
|
)
|
99
104
|
click.echo(wk.path)
|
100
105
|
|
@@ -108,6 +113,7 @@ def _make_API_CLI(app):
|
|
108
113
|
@store_option
|
109
114
|
@ts_fmt_option
|
110
115
|
@ts_name_fmt_option
|
116
|
+
@variables_option
|
111
117
|
@js_parallelism_option
|
112
118
|
@wait_option
|
113
119
|
@add_to_known_opt
|
@@ -123,6 +129,7 @@ def _make_API_CLI(app):
|
|
123
129
|
store,
|
124
130
|
ts_fmt=None,
|
125
131
|
ts_name_fmt=None,
|
132
|
+
variables=None,
|
126
133
|
js_parallelism=None,
|
127
134
|
wait=False,
|
128
135
|
add_to_known=True,
|
@@ -146,6 +153,7 @@ def _make_API_CLI(app):
|
|
146
153
|
store=store,
|
147
154
|
ts_fmt=ts_fmt,
|
148
155
|
ts_name_fmt=ts_name_fmt,
|
156
|
+
variables=dict(variables),
|
149
157
|
JS_parallelism=js_parallelism,
|
150
158
|
wait=wait,
|
151
159
|
add_to_known=add_to_known,
|
@@ -1032,9 +1040,27 @@ def make_cli(app):
|
|
1032
1040
|
nargs=2,
|
1033
1041
|
multiple=True,
|
1034
1042
|
)
|
1043
|
+
@click.option(
|
1044
|
+
"--timeit",
|
1045
|
+
help=(
|
1046
|
+
"Time function pathways as the code executes and write out a summary at the "
|
1047
|
+
"end. Only functions decorated by `TimeIt.decorator` are included."
|
1048
|
+
),
|
1049
|
+
is_flag=True,
|
1050
|
+
)
|
1051
|
+
@click.option(
|
1052
|
+
"--timeit-file",
|
1053
|
+
help=(
|
1054
|
+
"Time function pathways as the code executes and write out a summary at the "
|
1055
|
+
"end to a text file given by this file path. Only functions decorated by "
|
1056
|
+
"`TimeIt.decorator` are included."
|
1057
|
+
),
|
1058
|
+
)
|
1035
1059
|
@click.pass_context
|
1036
|
-
def new_CLI(ctx, config_dir, config_key, with_config):
|
1060
|
+
def new_CLI(ctx, config_dir, config_key, with_config, timeit, timeit_file):
|
1037
1061
|
app.run_time_info.from_CLI = True
|
1062
|
+
TimeIt.active = timeit or timeit_file
|
1063
|
+
TimeIt.file_path = timeit_file
|
1038
1064
|
if ctx.invoked_subcommand != "manage":
|
1039
1065
|
# load the config
|
1040
1066
|
overrides = {kv[0]: kv[1] for kv in with_config}
|
@@ -1048,6 +1074,11 @@ def make_cli(app):
|
|
1048
1074
|
click.echo(f"{colored(err.__class__.__name__, 'red')}: {err}")
|
1049
1075
|
ctx.exit(1)
|
1050
1076
|
|
1077
|
+
@new_CLI.result_callback()
|
1078
|
+
def post_execution(*args, **kwargs):
|
1079
|
+
if TimeIt.active:
|
1080
|
+
TimeIt.summarise_string()
|
1081
|
+
|
1051
1082
|
@new_CLI.command()
|
1052
1083
|
@click.argument("name")
|
1053
1084
|
@click.option("--use-current-env", is_flag=True, default=False)
|
@@ -63,6 +63,17 @@ ts_name_fmt_option = click.option(
|
|
63
63
|
"includes a timestamp."
|
64
64
|
),
|
65
65
|
)
|
66
|
+
variables_option = click.option(
|
67
|
+
"-v",
|
68
|
+
"--var",
|
69
|
+
"variables",
|
70
|
+
type=(str, str),
|
71
|
+
multiple=True,
|
72
|
+
help=(
|
73
|
+
"Workflow template variable value to be substituted in to the template file or "
|
74
|
+
"string. Multiple variable values can be specified."
|
75
|
+
),
|
76
|
+
)
|
66
77
|
js_parallelism_option = click.option(
|
67
78
|
"--js-parallelism",
|
68
79
|
help=(
|
@@ -29,6 +29,7 @@ from hpcflow.sdk.core.utils import (
|
|
29
29
|
split_param_label,
|
30
30
|
swap_nested_dict_keys,
|
31
31
|
)
|
32
|
+
from hpcflow.sdk.log import TimeIt
|
32
33
|
|
33
34
|
|
34
35
|
ACTION_SCOPE_REGEX = r"(\w*)(?:\[(.*)\])?"
|
@@ -1720,6 +1721,7 @@ class Action(JSONLike):
|
|
1720
1721
|
def get_output_file_labels(self):
|
1721
1722
|
return tuple(i.label for i in self.output_files)
|
1722
1723
|
|
1724
|
+
@TimeIt.decorator
|
1723
1725
|
def generate_data_index(
|
1724
1726
|
self,
|
1725
1727
|
act_idx,
|
@@ -10,6 +10,7 @@ from valida.rules import Rule
|
|
10
10
|
|
11
11
|
from hpcflow.sdk import app
|
12
12
|
from hpcflow.sdk.core.task_schema import TaskSchema
|
13
|
+
from hpcflow.sdk.log import TimeIt
|
13
14
|
from hpcflow.sdk.submission.shells import DEFAULT_SHELL_NAMES
|
14
15
|
from .json_like import ChildObjectSpec, JSONLike
|
15
16
|
from .element import ElementGroup
|
@@ -719,6 +720,7 @@ class Task(JSONLike):
|
|
719
720
|
"""Find the nesting order for a task sequence."""
|
720
721
|
return self.nesting_order[seq.normalised_path] if len(seq.values) > 1 else -1
|
721
722
|
|
723
|
+
@TimeIt.decorator
|
722
724
|
def _prepare_persistent_outputs(self, workflow, local_element_idx_range):
|
723
725
|
# TODO: check that schema is present when adding task? (should this be here?)
|
724
726
|
|
@@ -1790,6 +1792,7 @@ class WorkflowTask:
|
|
1790
1792
|
|
1791
1793
|
return element_dat_idx
|
1792
1794
|
|
1795
|
+
@TimeIt.decorator
|
1793
1796
|
def initialise_EARs(self) -> List[int]:
|
1794
1797
|
"""Try to initialise any uninitialised EARs of this task."""
|
1795
1798
|
initialised = []
|
@@ -1815,6 +1818,7 @@ class WorkflowTask:
|
|
1815
1818
|
self.workflow.set_EARs_initialised(iter_i.id_)
|
1816
1819
|
return initialised
|
1817
1820
|
|
1821
|
+
@TimeIt.decorator
|
1818
1822
|
def _initialise_element_iter_EARs(self, element_iter: app.ElementIteration) -> None:
|
1819
1823
|
# keys are (act_idx, EAR_idx):
|
1820
1824
|
all_data_idx = {}
|
@@ -1878,6 +1882,7 @@ class WorkflowTask:
|
|
1878
1882
|
for pid, src in param_src_updates.items():
|
1879
1883
|
self.workflow._store.update_param_source(pid, src)
|
1880
1884
|
|
1885
|
+
@TimeIt.decorator
|
1881
1886
|
def _add_element_set(self, element_set):
|
1882
1887
|
"""
|
1883
1888
|
Returns
|
@@ -1982,6 +1987,7 @@ class WorkflowTask:
|
|
1982
1987
|
return_indices=return_indices,
|
1983
1988
|
)
|
1984
1989
|
|
1990
|
+
@TimeIt.decorator
|
1985
1991
|
def _add_elements(
|
1986
1992
|
self,
|
1987
1993
|
base_element=None,
|
@@ -2153,6 +2159,7 @@ class WorkflowTask:
|
|
2153
2159
|
|
2154
2160
|
return deps
|
2155
2161
|
|
2162
|
+
@TimeIt.decorator
|
2156
2163
|
def get_dependent_tasks(
|
2157
2164
|
self,
|
2158
2165
|
as_objects: bool = False,
|
@@ -2251,6 +2258,7 @@ class WorkflowTask:
|
|
2251
2258
|
|
2252
2259
|
return params
|
2253
2260
|
|
2261
|
+
@TimeIt.decorator
|
2254
2262
|
def _get_merged_parameter_data(
|
2255
2263
|
self,
|
2256
2264
|
data_index,
|
@@ -15,7 +15,7 @@ import string
|
|
15
15
|
import subprocess
|
16
16
|
from datetime import datetime, timezone
|
17
17
|
import sys
|
18
|
-
from typing import Optional, Tuple, Type, Union, List
|
18
|
+
from typing import Dict, Optional, Tuple, Type, Union, List
|
19
19
|
import fsspec
|
20
20
|
import numpy as np
|
21
21
|
|
@@ -27,7 +27,9 @@ from hpcflow.sdk.core.errors import (
|
|
27
27
|
ContainerKeyError,
|
28
28
|
FromSpecMissingObjectError,
|
29
29
|
InvalidIdentifier,
|
30
|
+
MissingVariableSubstitutionError,
|
30
31
|
)
|
32
|
+
from hpcflow.sdk.log import TimeIt
|
31
33
|
from hpcflow.sdk.typing import PathLike
|
32
34
|
|
33
35
|
|
@@ -385,19 +387,42 @@ def check_in_object_list(spec_name, spec_pos=1, obj_list_pos=2):
|
|
385
387
|
return decorator
|
386
388
|
|
387
389
|
|
388
|
-
def
|
390
|
+
def substitute_string_vars(string, variables: Dict[str, str] = None):
|
391
|
+
variables = variables or {}
|
392
|
+
|
393
|
+
def var_repl(match_obj):
|
394
|
+
var_name = match_obj.group(1)
|
395
|
+
try:
|
396
|
+
out = str(variables[var_name])
|
397
|
+
except KeyError:
|
398
|
+
raise MissingVariableSubstitutionError(
|
399
|
+
f"The variable {var_name!r} referenced in the string does not match any "
|
400
|
+
f"of the provided variables: {list(variables)!r}."
|
401
|
+
)
|
402
|
+
return out
|
403
|
+
|
404
|
+
new_str = re.sub(
|
405
|
+
pattern=r"\<\<var:(.*?)\>\>",
|
406
|
+
repl=var_repl,
|
407
|
+
string=string,
|
408
|
+
)
|
409
|
+
return new_str
|
410
|
+
|
411
|
+
|
412
|
+
@TimeIt.decorator
|
413
|
+
def read_YAML_str(yaml_str, typ="safe", variables: Dict[str, str] = None):
|
414
|
+
"""Load a YAML string."""
|
415
|
+
if variables:
|
416
|
+
yaml_str = substitute_string_vars(yaml_str, variables=variables)
|
389
417
|
yaml = YAML(typ=typ)
|
390
|
-
return yaml.load(
|
418
|
+
return yaml.load(yaml_str)
|
391
419
|
|
392
420
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
else:
|
399
|
-
loadable_yaml = Path(path)
|
400
|
-
return read_YAML(loadable_yaml, typ=typ)
|
421
|
+
@TimeIt.decorator
|
422
|
+
def read_YAML_file(path: PathLike, typ="safe", variables: Dict[str, str] = None):
|
423
|
+
with fsspec.open(path, "rt") as f:
|
424
|
+
yaml_str = f.read()
|
425
|
+
return read_YAML_str(yaml_str, typ=typ, variables=variables)
|
401
426
|
|
402
427
|
|
403
428
|
def write_YAML_file(obj, path: PathLike, typ="safe"):
|
@@ -406,13 +431,16 @@ def write_YAML_file(obj, path: PathLike, typ="safe"):
|
|
406
431
|
yaml.dump(obj, fp)
|
407
432
|
|
408
433
|
|
409
|
-
def read_JSON_string(
|
410
|
-
|
434
|
+
def read_JSON_string(json_str: str, variables: Dict[str, str] = None):
|
435
|
+
if variables:
|
436
|
+
json_str = substitute_string_vars(json_str, variables=variables)
|
437
|
+
return json.loads(json_str)
|
411
438
|
|
412
439
|
|
413
|
-
def read_JSON_file(path):
|
414
|
-
with
|
415
|
-
|
440
|
+
def read_JSON_file(path, variables: Dict[str, str] = None):
|
441
|
+
with fsspec.open(path, "rt") as f:
|
442
|
+
json_str = f.read()
|
443
|
+
return read_JSON_string(json_str, variables=variables)
|
416
444
|
|
417
445
|
|
418
446
|
def write_JSON_file(obj, path: PathLike):
|