simstack 2.0.1__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.
- simstack/__init__.py +0 -0
- simstack/_version.py +24 -0
- simstack/core/__init__.py +0 -0
- simstack/core/artifacts.py +406 -0
- simstack/core/asnyc_helper.py +14 -0
- simstack/core/config_file.py +60 -0
- simstack/core/context.py +283 -0
- simstack/core/definitions.py +22 -0
- simstack/core/engine.py +115 -0
- simstack/core/find_simstack_modules.py +41 -0
- simstack/core/hash.py +179 -0
- simstack/core/node.py +1137 -0
- simstack/core/node_claim.py +31 -0
- simstack/core/node_runner.py +362 -0
- simstack/core/process_results.py +102 -0
- simstack/core/recompute_artifacts.py +117 -0
- simstack/core/reset_db.py +12 -0
- simstack/core/resource_assignment.py +222 -0
- simstack/core/resources.py +90 -0
- simstack/core/route_table.py +24 -0
- simstack/core/run_docker.py +109 -0
- simstack/core/run_node.py +71 -0
- simstack/core/runner.py +169 -0
- simstack/core/services/__init__.py +11 -0
- simstack/core/services/base_service.py +191 -0
- simstack/core/services/file_transfer_service.py +117 -0
- simstack/core/services/git_restart_service.py +12 -0
- simstack/core/services/git_uv_update_service.py +105 -0
- simstack/core/services/node_execution_service.py +182 -0
- simstack/core/services/resource_branch_monitor_service.py +71 -0
- simstack/core/services/runner_cleanup_service.py +149 -0
- simstack/core/services/runner_manager.py +163 -0
- simstack/core/services/runner_status_service.py +10 -0
- simstack/core/services/slurm_status_service.py +67 -0
- simstack/core/services/stop_check_service.py +27 -0
- simstack/core/services/timeout_restart_service.py +26 -0
- simstack/core/simstack_result.py +39 -0
- simstack/core/submit_node.py +217 -0
- simstack/core/task_id.py +22 -0
- simstack/methods/__init__.py +0 -0
- simstack/methods/archive_files.py +292 -0
- simstack/methods/fire_and_forget_runner.py +113 -0
- simstack/methods/generate_test.py +125 -0
- simstack/methods/get_file.py +26 -0
- simstack/methods/mass_runner.py +154 -0
- simstack/methods/multiple_executor.py +307 -0
- simstack/methods/switch_git.py +16 -0
- simstack/methods/upload_helpers.py +81 -0
- simstack/models/__init__.py +74 -0
- simstack/models/array_list.py +21 -0
- simstack/models/array_storage.py +83 -0
- simstack/models/artifact_models.py +127 -0
- simstack/models/base_lists.py +51 -0
- simstack/models/base_types.py +209 -0
- simstack/models/charts_artifact.py +690 -0
- simstack/models/dataset.py +451 -0
- simstack/models/dataset_metadata.py +390 -0
- simstack/models/datasettuple.py +587 -0
- simstack/models/file_instance.py +150 -0
- simstack/models/file_list.py +45 -0
- simstack/models/files.py +424 -0
- simstack/models/fire_and_forget_result.py +19 -0
- simstack/models/images2d.py +113 -0
- simstack/models/log_entry_model.py +37 -0
- simstack/models/models.py +52 -0
- simstack/models/named_data_reference.py +36 -0
- simstack/models/node_registry.py +96 -0
- simstack/models/pandas_model.py +239 -0
- simstack/models/parameters.py +402 -0
- simstack/models/pickle_models.py +300 -0
- simstack/models/project.py +13 -0
- simstack/models/resource_assignment.py +170 -0
- simstack/models/resource_definition.py +125 -0
- simstack/models/runner_model.py +39 -0
- simstack/models/simple_table.py +79 -0
- simstack/models/simstack_model.py +97 -0
- simstack/models/slurm_info.py +17 -0
- simstack/models/table_artifact.py +87 -0
- simstack/models/tag.py +12 -0
- simstack/models/unused_test_file.py +5 -0
- simstack/simstack_marker.com +1 -0
- simstack/static/docs/.buildinfo +4 -0
- simstack/static/docs/_images/GUI Concept.webp +0 -0
- simstack/static/docs/_modules/index.html +434 -0
- simstack/static/docs/_modules/simstack/core/artifacts.html +743 -0
- simstack/static/docs/_modules/simstack/core/asnyc_helper.html +330 -0
- simstack/static/docs/_modules/simstack/core/config_file.html +379 -0
- simstack/static/docs/_modules/simstack/core/definitions.html +341 -0
- simstack/static/docs/_modules/simstack/core/engine.html +437 -0
- simstack/static/docs/_modules/simstack/core/find_simstack_modules.html +360 -0
- simstack/static/docs/_modules/simstack/core/hash.html +528 -0
- simstack/static/docs/_modules/simstack/core/node.html +1392 -0
- simstack/static/docs/_modules/simstack/core/node_claim.html +347 -0
- simstack/static/docs/_modules/simstack/core/node_runner.html +711 -0
- simstack/static/docs/_modules/simstack/core/process_results.html +418 -0
- simstack/static/docs/_modules/simstack/core/recompute_artifacts.html +433 -0
- simstack/static/docs/_modules/simstack/core/reset_db.html +328 -0
- simstack/static/docs/_modules/simstack/core/resource_assignment.html +553 -0
- simstack/static/docs/_modules/simstack/core/resources.html +424 -0
- simstack/static/docs/_modules/simstack/core/route_table.html +349 -0
- simstack/static/docs/_modules/simstack/core/run_docker.html +425 -0
- simstack/static/docs/_modules/simstack/core/run_node.html +390 -0
- simstack/static/docs/_modules/simstack/core/runner.html +491 -0
- simstack/static/docs/_modules/simstack/core/services/base_service.html +522 -0
- simstack/static/docs/_modules/simstack/core/services/file_transfer_service.html +436 -0
- simstack/static/docs/_modules/simstack/core/services/git_restart_service.html +331 -0
- simstack/static/docs/_modules/simstack/core/services/git_uv_update_service.html +427 -0
- simstack/static/docs/_modules/simstack/core/services/node_execution_service.html +507 -0
- simstack/static/docs/_modules/simstack/core/services/resource_branch_monitor_service.html +390 -0
- simstack/static/docs/_modules/simstack/core/services/runner_cleanup_service.html +468 -0
- simstack/static/docs/_modules/simstack/core/services/runner_manager.html +485 -0
- simstack/static/docs/_modules/simstack/core/services/runner_status_service.html +329 -0
- simstack/static/docs/_modules/simstack/core/services/slurm_status_service.html +386 -0
- simstack/static/docs/_modules/simstack/core/services/stop_check_service.html +346 -0
- simstack/static/docs/_modules/simstack/core/services/timeout_restart_service.html +345 -0
- simstack/static/docs/_modules/simstack/core/simstack_result.html +355 -0
- simstack/static/docs/_modules/simstack/core/submit_node.html +536 -0
- simstack/static/docs/_modules/simstack/core/task_id.html +344 -0
- simstack/static/docs/_modules/simstack/methods/archive_files.html +598 -0
- simstack/static/docs/_modules/simstack/methods/fire_and_forget_runner.html +432 -0
- simstack/static/docs/_modules/simstack/methods/generate_test.html +443 -0
- simstack/static/docs/_modules/simstack/methods/get_file.html +342 -0
- simstack/static/docs/_modules/simstack/methods/mass_runner.html +476 -0
- simstack/static/docs/_modules/simstack/methods/multiple_executor.html +674 -0
- simstack/static/docs/_modules/simstack/methods/switch_git.html +332 -0
- simstack/static/docs/_modules/simstack/methods/upload_helpers.html +403 -0
- simstack/static/docs/_modules/simstack/models/array_list.html +337 -0
- simstack/static/docs/_modules/simstack/models/array_storage.html +417 -0
- simstack/static/docs/_modules/simstack/models/base_lists.html +374 -0
- simstack/static/docs/_modules/simstack/models/base_types.html +588 -0
- simstack/static/docs/_modules/simstack/models/charts_artifact.html +1035 -0
- simstack/static/docs/_modules/simstack/models/dataset.html +866 -0
- simstack/static/docs/_modules/simstack/models/dataset_metadata.html +711 -0
- simstack/static/docs/_modules/simstack/models/datasettuple.html +1005 -0
- simstack/static/docs/_modules/simstack/models/file_instance.html +472 -0
- simstack/static/docs/_modules/simstack/models/file_list.html +367 -0
- simstack/static/docs/_modules/simstack/models/files.html +773 -0
- simstack/static/docs/_modules/simstack/models/fire_and_forget_result.html +335 -0
- simstack/static/docs/_modules/simstack/models/images2d.html +447 -0
- simstack/static/docs/_modules/simstack/models/log_entry_model.html +356 -0
- simstack/static/docs/_modules/simstack/models/models.html +374 -0
- simstack/static/docs/_modules/simstack/models/named_data_reference.html +355 -0
- simstack/static/docs/_modules/simstack/models/node_registry.html +415 -0
- simstack/static/docs/_modules/simstack/models/pandas_model.html +570 -0
- simstack/static/docs/_modules/simstack/models/parameters.html +739 -0
- simstack/static/docs/_modules/simstack/models/pickle_models.html +631 -0
- simstack/static/docs/_modules/simstack/models/project.html +329 -0
- simstack/static/docs/_modules/simstack/models/resource_assignment.html +501 -0
- simstack/static/docs/_modules/simstack/models/resource_definition.html +477 -0
- simstack/static/docs/_modules/simstack/models/runner_model.html +361 -0
- simstack/static/docs/_modules/simstack/models/simple_table.html +413 -0
- simstack/static/docs/_modules/simstack/models/simstack_model.html +416 -0
- simstack/static/docs/_modules/simstack/models/slurm_info.html +333 -0
- simstack/static/docs/_modules/simstack/models/table_artifact.html +406 -0
- simstack/static/docs/_modules/simstack/models/tag.html +328 -0
- simstack/static/docs/_modules/simstack/tables/model_table.html +519 -0
- simstack/static/docs/_modules/simstack/tables/node_children.html +538 -0
- simstack/static/docs/_modules/simstack/tables/node_table.html +854 -0
- simstack/static/docs/_modules/simstack/tables/table_builder.html +642 -0
- simstack/static/docs/_modules/simstack/util/async_zip_utils.html +337 -0
- simstack/static/docs/_modules/simstack/util/b64mixin.html +339 -0
- simstack/static/docs/_modules/simstack/util/cleaned_json_schema.html +336 -0
- simstack/static/docs/_modules/simstack/util/config_reader.html +498 -0
- simstack/static/docs/_modules/simstack/util/custom_model_dump.html +391 -0
- simstack/static/docs/_modules/simstack/util/database_information.html +488 -0
- simstack/static/docs/_modules/simstack/util/db.html +1392 -0
- simstack/static/docs/_modules/simstack/util/db_logger.html +448 -0
- simstack/static/docs/_modules/simstack/util/default_from_dict.html +376 -0
- simstack/static/docs/_modules/simstack/util/directory_iterator.html +553 -0
- simstack/static/docs/_modules/simstack/util/docstring_parser.html +526 -0
- simstack/static/docs/_modules/simstack/util/file_hashing.html +394 -0
- simstack/static/docs/_modules/simstack/util/file_transfer_client.html +791 -0
- simstack/static/docs/_modules/simstack/util/files.html +733 -0
- simstack/static/docs/_modules/simstack/util/find_python_files.html +349 -0
- simstack/static/docs/_modules/simstack/util/generate_ui_schema.html +396 -0
- simstack/static/docs/_modules/simstack/util/generic_list_mixin.html +487 -0
- simstack/static/docs/_modules/simstack/util/get_module_path.html +336 -0
- simstack/static/docs/_modules/simstack/util/git_pull.html +381 -0
- simstack/static/docs/_modules/simstack/util/git_repository_status.html +411 -0
- simstack/static/docs/_modules/simstack/util/import_module.html +377 -0
- simstack/static/docs/_modules/simstack/util/importer.html +637 -0
- simstack/static/docs/_modules/simstack/util/init_data_source.html +357 -0
- simstack/static/docs/_modules/simstack/util/make_graph.html +423 -0
- simstack/static/docs/_modules/simstack/util/make_table.html +1171 -0
- simstack/static/docs/_modules/simstack/util/mappings.html +378 -0
- simstack/static/docs/_modules/simstack/util/minimal_route_finder.html +388 -0
- simstack/static/docs/_modules/simstack/util/mock_db.html +472 -0
- simstack/static/docs/_modules/simstack/util/module_path_checker.html +354 -0
- simstack/static/docs/_modules/simstack/util/object_list_mixin.html +649 -0
- simstack/static/docs/_modules/simstack/util/path_manager.html +566 -0
- simstack/static/docs/_modules/simstack/util/project_root_finder.html +357 -0
- simstack/static/docs/_modules/simstack/util/queue_watcher.html +593 -0
- simstack/static/docs/_modules/simstack/util/resource_config.html +532 -0
- simstack/static/docs/_modules/simstack/util/route_finder.html +390 -0
- simstack/static/docs/_modules/simstack/util/runner_util.html +487 -0
- simstack/static/docs/_modules/simstack/util/runner_utils.html +468 -0
- simstack/static/docs/_modules/simstack/util/safe_code_executor.html +510 -0
- simstack/static/docs/_modules/simstack/util/sample_config.html +414 -0
- simstack/static/docs/_modules/simstack/util/sensitive_content_filter.html +364 -0
- simstack/static/docs/_modules/simstack/util/setup_logging.html +365 -0
- simstack/static/docs/_modules/simstack/util/submit_to_watchdog.html +425 -0
- simstack/static/docs/_modules/simstack/util/toml_reader.html +482 -0
- simstack/static/docs/_modules/simstack/util/transform_file_name.html +357 -0
- simstack/static/docs/_modules/simstack/util/ui_tools.html +541 -0
- simstack/static/docs/_sources/architecture.rst.txt +25 -0
- simstack/static/docs/_sources/array_lists.rst.txt +60 -0
- simstack/static/docs/_sources/ci_pipeline.rst.txt +34 -0
- simstack/static/docs/_sources/data.rst.txt +175 -0
- simstack/static/docs/_sources/database_migrations.rst.txt +310 -0
- simstack/static/docs/_sources/datasets.rst.txt +93 -0
- simstack/static/docs/_sources/developer_guide.rst.txt +25 -0
- simstack/static/docs/_sources/docker_nodes.rst.txt +149 -0
- simstack/static/docs/_sources/files.rst.txt +159 -0
- simstack/static/docs/_sources/fire_and_forget_runner.rst.txt +67 -0
- simstack/static/docs/_sources/index.rst.txt +25 -0
- simstack/static/docs/_sources/installation.rst.txt +213 -0
- simstack/static/docs/_sources/lists.rst.txt +111 -0
- simstack/static/docs/_sources/mass_runner.rst.txt +91 -0
- simstack/static/docs/_sources/misc.rst.txt +106 -0
- simstack/static/docs/_sources/overview.rst.txt +91 -0
- simstack/static/docs/_sources/recovery.rst.txt +38 -0
- simstack/static/docs/_sources/resource_config.rst.txt +141 -0
- simstack/static/docs/_sources/simstack/modules/modules.rst.txt +7 -0
- simstack/static/docs/_sources/simstack/modules/simstack.core.rst.txt +205 -0
- simstack/static/docs/_sources/simstack/modules/simstack.core.services.rst.txt +109 -0
- simstack/static/docs/_sources/simstack/modules/simstack.methods.rst.txt +77 -0
- simstack/static/docs/_sources/simstack/modules/simstack.models.rst.txt +261 -0
- simstack/static/docs/_sources/simstack/modules/simstack.rst.txt +22 -0
- simstack/static/docs/_sources/simstack/modules/simstack.tables.rst.txt +45 -0
- simstack/static/docs/_sources/simstack/modules/simstack.util.rst.txt +381 -0
- simstack/static/docs/_sources/submit.rst.txt +141 -0
- simstack/static/docs/_sources/tables.rst.txt +50 -0
- simstack/static/docs/_sources/testing_complex_nodes.rst.txt +92 -0
- simstack/static/docs/_sources/ui_documentation.rst.txt +272 -0
- simstack/static/docs/_sources/workflows.rst.txt +446 -0
- simstack/static/docs/_static/base-stemmer.js +476 -0
- simstack/static/docs/_static/basic.css +906 -0
- simstack/static/docs/_static/cobalt2-theme.css +1 -0
- simstack/static/docs/_static/debug.css +69 -0
- simstack/static/docs/_static/docs-build-badge.css +51 -0
- simstack/static/docs/_static/docs-build-badge.js +51 -0
- simstack/static/docs/_static/doctools.js +150 -0
- simstack/static/docs/_static/documentation_options.js +13 -0
- simstack/static/docs/_static/english-stemmer.js +1066 -0
- simstack/static/docs/_static/file.png +0 -0
- simstack/static/docs/_static/language_data.js +13 -0
- simstack/static/docs/_static/minus.png +0 -0
- simstack/static/docs/_static/plus.png +0 -0
- simstack/static/docs/_static/pygments.css +250 -0
- simstack/static/docs/_static/scripts/furo-extensions.js +0 -0
- simstack/static/docs/_static/scripts/furo.js +3 -0
- simstack/static/docs/_static/scripts/furo.js.LICENSE.txt +7 -0
- simstack/static/docs/_static/scripts/furo.js.map +1 -0
- simstack/static/docs/_static/searchtools.js +693 -0
- simstack/static/docs/_static/skeleton.css +296 -0
- simstack/static/docs/_static/sphinx_highlight.js +159 -0
- simstack/static/docs/_static/styles/furo-extensions.css +2 -0
- simstack/static/docs/_static/styles/furo-extensions.css.map +1 -0
- simstack/static/docs/_static/styles/furo.css +2 -0
- simstack/static/docs/_static/styles/furo.css.map +1 -0
- simstack/static/docs/architecture.html +340 -0
- simstack/static/docs/array_lists.html +678 -0
- simstack/static/docs/ci_pipeline.html +385 -0
- simstack/static/docs/data.html +545 -0
- simstack/static/docs/database_migrations.html +652 -0
- simstack/static/docs/datasets.html +1268 -0
- simstack/static/docs/developer_guide.html +359 -0
- simstack/static/docs/docker_nodes.html +503 -0
- simstack/static/docs/files.html +718 -0
- simstack/static/docs/fire_and_forget_runner.html +641 -0
- simstack/static/docs/genindex.html +6390 -0
- simstack/static/docs/index.html +516 -0
- simstack/static/docs/installation.html +553 -0
- simstack/static/docs/lists.html +478 -0
- simstack/static/docs/mass_runner.html +481 -0
- simstack/static/docs/misc.html +454 -0
- simstack/static/docs/objects.inv +0 -0
- simstack/static/docs/overview.html +469 -0
- simstack/static/docs/py-modindex.html +1111 -0
- simstack/static/docs/recovery.html +371 -0
- simstack/static/docs/resource_config.html +590 -0
- simstack/static/docs/search.html +327 -0
- simstack/static/docs/searchindex.js +1 -0
- simstack/static/docs/simstack/modules/modules.html +489 -0
- simstack/static/docs/simstack/modules/simstack.core.html +1883 -0
- simstack/static/docs/simstack/modules/simstack.core.services.html +698 -0
- simstack/static/docs/simstack/modules/simstack.html +3060 -0
- simstack/static/docs/simstack/modules/simstack.methods.html +1150 -0
- simstack/static/docs/simstack/modules/simstack.models.html +13113 -0
- simstack/static/docs/simstack/modules/simstack.tables.html +635 -0
- simstack/static/docs/simstack/modules/simstack.util.html +3320 -0
- simstack/static/docs/submit.html +487 -0
- simstack/static/docs/tables.html +539 -0
- simstack/static/docs/testing_complex_nodes.html +458 -0
- simstack/static/docs/ui_documentation.html +788 -0
- simstack/static/docs/workflows.html +766 -0
- simstack/tables/__init__.py +0 -0
- simstack/tables/model_table.py +191 -0
- simstack/tables/node_children.py +219 -0
- simstack/tables/node_table.py +517 -0
- simstack/tables/table_builder.py +314 -0
- simstack/util/__init__.py +0 -0
- simstack/util/async_zip_utils.py +18 -0
- simstack/util/b64mixin.py +23 -0
- simstack/util/cleaned_json_schema.py +20 -0
- simstack/util/config_reader.py +179 -0
- simstack/util/custom_model_dump.py +75 -0
- simstack/util/database_information.py +160 -0
- simstack/util/db.py +1013 -0
- simstack/util/db_logger.py +117 -0
- simstack/util/default_from_dict.py +57 -0
- simstack/util/directory_iterator.py +216 -0
- simstack/util/docstring_parser.py +186 -0
- simstack/util/file_hashing.py +72 -0
- simstack/util/file_transfer_client.py +427 -0
- simstack/util/files.py +396 -0
- simstack/util/find_python_files.py +33 -0
- simstack/util/generate_ui_schema.py +80 -0
- simstack/util/generic_list_mixin.py +120 -0
- simstack/util/geometry_utils.py +118 -0
- simstack/util/get_module_path.py +20 -0
- simstack/util/git_pull.py +65 -0
- simstack/util/git_repository_status.py +95 -0
- simstack/util/import_module.py +63 -0
- simstack/util/importer.py +312 -0
- simstack/util/init_data_source.py +41 -0
- simstack/util/make_graph.py +107 -0
- simstack/util/make_table.py +837 -0
- simstack/util/mappings.py +41 -0
- simstack/util/minimal_route_finder.py +72 -0
- simstack/util/mock_db.py +144 -0
- simstack/util/module_path_checker.py +38 -0
- simstack/util/object_list_mixin.py +282 -0
- simstack/util/path_manager.py +223 -0
- simstack/util/project_root_finder.py +41 -0
- simstack/util/queue_watcher.py +262 -0
- simstack/util/resource_config.py +198 -0
- simstack/util/route_finder.py +74 -0
- simstack/util/runner_util.py +166 -0
- simstack/util/runner_utils.py +143 -0
- simstack/util/safe_code_executor.py +194 -0
- simstack/util/sample_config.py +98 -0
- simstack/util/sensitive_content_filter.py +48 -0
- simstack/util/setup_logging.py +49 -0
- simstack/util/submit_to_watchdog.py +106 -0
- simstack/util/toml_reader.py +142 -0
- simstack/util/transform_file_name.py +41 -0
- simstack/util/ui_tools.py +213 -0
- simstack-2.0.1.dist-info/METADATA +454 -0
- simstack-2.0.1.dist-info/RECORD +354 -0
- simstack-2.0.1.dist-info/WHEEL +5 -0
- simstack-2.0.1.dist-info/entry_points.txt +12 -0
- simstack-2.0.1.dist-info/licenses/LICENSE +21 -0
- simstack-2.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
.. _workflows:
|
|
2
|
+
|
|
3
|
+
Workflows
|
|
4
|
+
=========
|
|
5
|
+
|
|
6
|
+
.. note::
|
|
7
|
+
|
|
8
|
+
This section is intended for workflow developers but also helpful to users. A more detailed how-to for nodes is given in :ref:`developer-guide`
|
|
9
|
+
|
|
10
|
+
From Python to Workflows
|
|
11
|
+
------------------------
|
|
12
|
+
|
|
13
|
+
The following section is intended to guide developers who are familiar with python to transform their code
|
|
14
|
+
into Simstack II. We will introduce the concepts step by step, starting with a simple python "workflow".
|
|
15
|
+
Workflows are comprised of nodes, which are implemented as python functions.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
.. code-block:: python
|
|
19
|
+
|
|
20
|
+
def adder(arg1: float, arg2: float) -> float:
|
|
21
|
+
return arg1 + arg2
|
|
22
|
+
|
|
23
|
+
def multiplier(arg1: float, arg2: float) -> float:
|
|
24
|
+
return arg1 * arg2
|
|
25
|
+
|
|
26
|
+
def add_multiply_python(arg1: float, arg2: float, arg3: float) -> float:
|
|
27
|
+
add_result = adder(arg1, arg2)
|
|
28
|
+
multiply_result = multiplier(add_result, arg3)
|
|
29
|
+
return multiply_result
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
In this code we have three nodes, `adder`, `multiplier`, and `add_multiply_python`. The first two nodes are simple
|
|
33
|
+
functions, the last function nests the 2 simple functions, making this function a template for a workflow.
|
|
34
|
+
|
|
35
|
+
To transform this code into a Simstack II workflow, we want to introduce minimal changes to the code above to accomplish
|
|
36
|
+
the following:
|
|
37
|
+
|
|
38
|
+
* One or more of the functions should be visible and startable in the GUI
|
|
39
|
+
* The results of the nodes should be persisted in the database and visible in the GUI
|
|
40
|
+
* The nodes should be executable on remote resources
|
|
41
|
+
|
|
42
|
+
To achievieve this, we need to make the following changes in the code:
|
|
43
|
+
|
|
44
|
+
* decorate the functions that should be visible in the GUI with the `@node` decorator
|
|
45
|
+
* ensure that all input and output types of the nodes are registered odmantic Models
|
|
46
|
+
* specifiy where the nodes should be executed
|
|
47
|
+
|
|
48
|
+
For the specific example above the code looks as follows:
|
|
49
|
+
|
|
50
|
+
.. code-block:: python
|
|
51
|
+
|
|
52
|
+
@node(parameters=Parameters(resource="my-remote-host", queue="slurm-queue"))
|
|
53
|
+
def adder(arg1: FloatData, arg2: FloatData, **kwargs) -> FloatData:
|
|
54
|
+
return FloatData(field_name="adder_result", value=arg1.value + arg2.value)
|
|
55
|
+
|
|
56
|
+
@node(parameters=Parameters(resource="my-remote-host", queue="default"))
|
|
57
|
+
def multiplier(arg1: FloatData, arg2: FloatData, **kwargs) -> FloatData:
|
|
58
|
+
return FloatData(field_name="multiplier_result", value=arg1.value * arg2.value)
|
|
59
|
+
|
|
60
|
+
@node
|
|
61
|
+
def add_multiply_python(arg1: FloatData, arg2: FloatData, arg3: FloatData, **kwargs) -> FloatData:
|
|
62
|
+
add_result = adder(arg1, arg2, **kwargs) # note passing the kwargs!!!!
|
|
63
|
+
multiply_result = multiplier(add_result, arg3, **kwargs)
|
|
64
|
+
return multiply_result
|
|
65
|
+
|
|
66
|
+
The first thing you notice is that the datatypes have changed. Since int, floats etc appear a lot, Simstack provides
|
|
67
|
+
models for these types (see: :mod:`simstack.models.base_types`).
|
|
68
|
+
|
|
69
|
+
The @node decorator embeds the simple python functions into a complex workflow class
|
|
70
|
+
(see: :func:`simstack.core.node.node` in module: :mod:`simstack.core.node`).
|
|
71
|
+
|
|
72
|
+
To allow Simstack II with new data models you need to register them once, see :ref:`persisting_models`.
|
|
73
|
+
In order execute nodes via the UI you need to register the nodes. This would result in a workflow where all nodes are
|
|
74
|
+
visible in the GUI (:ref:`submitting-workflows`).
|
|
75
|
+
The nodes `adder` and `multiplier` would be executed on a runner running on "my-remote-host".
|
|
76
|
+
The adder would be submitted to the "slurm-queue" and the multiplier would be executed immediately in the foreground.
|
|
77
|
+
add_multiply_python would be executed on the default resource by a runner called `local`. You can change these defaults in the UI.
|
|
78
|
+
The relationship between the classes in the code, the tables in the database
|
|
79
|
+
and the representation of this data in the GUI, these models are discussed in :ref:`persisting-results-section`.
|
|
80
|
+
|
|
81
|
+
Here are some ground rules to write workflows in Simstack II:
|
|
82
|
+
|
|
83
|
+
.. important::
|
|
84
|
+
- Node functions must have a **unique name** (across the whole installation).
|
|
85
|
+
- Node functions must have the **\*\*kwargs argument**
|
|
86
|
+
- Node functions must **pass** the \*\*kwargs argument to nodes they call
|
|
87
|
+
- Node functions must be **registered in the node_model table** of the database
|
|
88
|
+
by running make_node_table (:ref:`registering`)
|
|
89
|
+
- All positional arguments of node functions must be **registered Models** in the model_table of the database
|
|
90
|
+
by running make_model_table (:ref:`registering`). Presently kwargs for models are not supported.
|
|
91
|
+
|
|
92
|
+
Beyond that nodes functions are normal python functions which can use the full flexibility of python.
|
|
93
|
+
The can call other functions or other nodes, but should **avoid "closures"**, such as global variables.
|
|
94
|
+
For this reason, node function should **not be class members** unless they are class members of an odmantic model.
|
|
95
|
+
|
|
96
|
+
You can consult the documentation of this class to understand how this works but this is not required to write
|
|
97
|
+
workflows.
|
|
98
|
+
|
|
99
|
+
The choice, whether a function is a "normal" function or a node is influenced
|
|
100
|
+
by the following considerations:
|
|
101
|
+
|
|
102
|
+
- Only nodes are visible in the GUI
|
|
103
|
+
- only nodes can be executed automatically on remote resources
|
|
104
|
+
- in principle nodes can call normal functions which can call nodes, as long as the \*\*kwargs
|
|
105
|
+
are passed correctly
|
|
106
|
+
|
|
107
|
+
Return Types
|
|
108
|
+
~~~~~~~~~~~~
|
|
109
|
+
|
|
110
|
+
In workflows, the results of node functions must be visible in the databse and may be
|
|
111
|
+
processed by other nodes. This means that **results** of the nodes must by odmantic models which
|
|
112
|
+
can be visualized in the GUI and passed to other nodes which may execute on different resources.
|
|
113
|
+
|
|
114
|
+
In order to encapsulate data processing, this essentially **precludes the use
|
|
115
|
+
of files as relevant results**. Many terminal nodes will call external
|
|
116
|
+
programs that return their output in file format. In Simstack, all human
|
|
117
|
+
readable content of these files should be **parsed into Simstack Model types**
|
|
118
|
+
that can be stored in the database. In many cases the output files of
|
|
119
|
+
terminal nodes will nevertheless be required input by other terminal nodes. In
|
|
120
|
+
order to facilitate processing, references to these files should be stored in
|
|
121
|
+
the output to avoid error-prone parsing and recreation.
|
|
122
|
+
|
|
123
|
+
THe following return types od node_functions are supported:
|
|
124
|
+
|
|
125
|
+
- any **registered** Model (:ref:`registering`),
|
|
126
|
+
- True or False, the indicating success or failure,
|
|
127
|
+
- a class derived from SimstackResult, in particular NodeRunner,
|
|
128
|
+
- None will result in failure
|
|
129
|
+
|
|
130
|
+
:class:`simstack.core.simstack_result.SimstackResult` provides a framework to
|
|
131
|
+
return more than one result, including files and info_files to the calling
|
|
132
|
+
function. The class NodeRunner is a child class of SimstackResult and
|
|
133
|
+
provides useful helper functions to manage results, files and logging
|
|
134
|
+
(see below).
|
|
135
|
+
|
|
136
|
+
The Noderunner Helper Class
|
|
137
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
138
|
+
|
|
139
|
+
:class:`simstack.core.node_runner.NodeRunner` instances provide
|
|
140
|
+
useful quality-of-life features from logging to
|
|
141
|
+
the management of results. In realistic applications, nodes generate a lot of
|
|
142
|
+
auxiliary data, such as log-files of external programs, that are not results,
|
|
143
|
+
but useful to keep track of the data-flow. To facilitate oversight over
|
|
144
|
+
nodes that are executed remotely, it is useful to capture the available
|
|
145
|
+
output of nodes, even when they fail. The NodeRunner
|
|
146
|
+
class offers some quality-of-life features for this. Each node is passed an
|
|
147
|
+
instance of NodeRunner in the \*\*kwargs.
|
|
148
|
+
|
|
149
|
+
You can add output by:
|
|
150
|
+
|
|
151
|
+
- adding any **registered** Models to the node_runner as attributes
|
|
152
|
+
- appending FileStack instances to node_runner.files
|
|
153
|
+
- appending FileStack instances to node_runner.info_files
|
|
154
|
+
|
|
155
|
+
**Node Example with NodeRunner**
|
|
156
|
+
|
|
157
|
+
.. code-block:: python
|
|
158
|
+
|
|
159
|
+
@node
|
|
160
|
+
def my_node(*args,**kwargs) -> SimstackResult
|
|
161
|
+
# get the supplied node_runner first
|
|
162
|
+
node_runner = kwargs.get('node_runner',None)
|
|
163
|
+
if node_runner is None:
|
|
164
|
+
raise ValueError('no node_runner')
|
|
165
|
+
# your code here ....
|
|
166
|
+
|
|
167
|
+
file_with_data = FileStack.from_local_file("my_important_file.dat")
|
|
168
|
+
node_runner.files.append(file_with_data) # file_with_data will be added
|
|
169
|
+
# automatically to the result
|
|
170
|
+
# table of the NodeRegistry
|
|
171
|
+
# entry
|
|
172
|
+
|
|
173
|
+
some_file_with_log_output = FileStack.from_local_file("my_log.txt")
|
|
174
|
+
# will not be added to the result tables but to the info_files tab or the node and
|
|
175
|
+
# can be inspected in the gui for potential problems or output
|
|
176
|
+
# that has not been parsed.
|
|
177
|
+
node_runner.make_info_files(some_file_with_log_output)
|
|
178
|
+
|
|
179
|
+
if some_error:
|
|
180
|
+
# this error will be caught in the calling function
|
|
181
|
+
# which will post-process the results above this line
|
|
182
|
+
# but set the task_status to TaskStatus.FAILED
|
|
183
|
+
raise RuntimeError("Something went wrong")
|
|
184
|
+
|
|
185
|
+
my_data = ArrayStorage(name="my cool numpy result")
|
|
186
|
+
my_data.set_array(numpy_array)
|
|
187
|
+
node_runner.my_data = my_data # will also be added to the result table
|
|
188
|
+
|
|
189
|
+
return node_runner.succeed("happy ending") # node_runner is a child
|
|
190
|
+
# class of SimstackResult
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
.. note::
|
|
194
|
+
NodeRunner.make_info_files(file1,file2,pattern1,pattern2) is a more clever way to append many files to the info_files list.
|
|
195
|
+
NodeRunner.info_file_patterns defines a standard set of endings to include automatically
|
|
196
|
+
|
|
197
|
+
.. note::
|
|
198
|
+
The instance of NodeRunner passed from the calling function, will be
|
|
199
|
+
post-processed by the calling function even when the node fails. This allows
|
|
200
|
+
capturing of partial output, in particular the info_files.
|
|
201
|
+
|
|
202
|
+
.. note::
|
|
203
|
+
The call to your actual function is always wrapped in a try-except-block.
|
|
204
|
+
In most scenarios you do not need your own try-except-finally blocks in the
|
|
205
|
+
node
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
**Data Provided by \*\*kwargs**
|
|
210
|
+
|
|
211
|
+
.. code-block:: python
|
|
212
|
+
|
|
213
|
+
node_runner = NodeRunner(self._func.__name__, None, task_id=self.id)
|
|
214
|
+
node_kwargs = {
|
|
215
|
+
'node_runner': node_runner,
|
|
216
|
+
'parent_id': self.id, # DO NOT CHANGE & pass to children
|
|
217
|
+
|
|
218
|
+
'task_id': self.id, # DO NOT CHANGE & pass
|
|
219
|
+
'call_path': self.call_path, # DO NOT CHANGE &
|
|
220
|
+
'parent_parameters': self.parameters, # this must have a name different from parameters, because
|
|
221
|
+
# otherwise this setting will override all the parameters of
|
|
222
|
+
# the child nodes
|
|
223
|
+
'recompute_artifacts': self.recompute_artifacts,
|
|
224
|
+
'custom_name' : self.custom_name
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if self.parameters.force_rerun:
|
|
228
|
+
node_kwargs['force_rerun'] = True
|
|
229
|
+
|
|
230
|
+
**Logging**
|
|
231
|
+
|
|
232
|
+
In order to keep track of the node execution, the Simstack core modules and
|
|
233
|
+
user written nodes should write logs. Simstack will initialize a custom
|
|
234
|
+
database logger which will be added to the logging system. In your node you
|
|
235
|
+
can therefore just instantiate and use a logger
|
|
236
|
+
|
|
237
|
+
.. code-block:: python
|
|
238
|
+
|
|
239
|
+
import logging
|
|
240
|
+
logger = logging.getLogger("name")
|
|
241
|
+
|
|
242
|
+
@node
|
|
243
|
+
def my_node(*args,**kwargs) -> SimstackResult
|
|
244
|
+
|
|
245
|
+
node_runner = kwargs['node_runner'] # should never fail
|
|
246
|
+
|
|
247
|
+
# this will log to the database and be visible in the general logs
|
|
248
|
+
logger.info("Some message I will never find")
|
|
249
|
+
|
|
250
|
+
# this will be shown in a special tab called task-logs which collects
|
|
251
|
+
# only messages for this node
|
|
252
|
+
logger.info(f"task_id: {node_runner.task_id} informative message")
|
|
253
|
+
|
|
254
|
+
# node_runner will add the task_id info
|
|
255
|
+
node_runner.info("another informative message")
|
|
256
|
+
|
|
257
|
+
The node_runner helper functions are provided for all log-levels.
|
|
258
|
+
|
|
259
|
+
.. note::
|
|
260
|
+
Simstack generates a lot of log messages. Use the task_id mechanism as
|
|
261
|
+
much as possible to provide useful info
|
|
262
|
+
|
|
263
|
+
**Executing external programs**
|
|
264
|
+
|
|
265
|
+
The NodeRunner class provides :func:`simstack.core.NodeRunner.subprocess` to
|
|
266
|
+
facilitate execution of external programs. This helper function will execute
|
|
267
|
+
a command in the current shell and automatically add standard output and
|
|
268
|
+
error to the info_files of the node. The function returns True/False upon
|
|
269
|
+
success and failure. Stdout and sterr of the last command are also stored in
|
|
270
|
+
attributes so that they can be parsed by the node.
|
|
271
|
+
|
|
272
|
+
Node Decorator Arguments
|
|
273
|
+
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
274
|
+
The node decorator may have arguments.
|
|
275
|
+
|
|
276
|
+
- Parameters: :class:`simstack.models.Parameters` where and how shall the node
|
|
277
|
+
be executed
|
|
278
|
+
- force_rerun: force execution of the node, but not the children
|
|
279
|
+
- recompute artifacts: without executing the node or its children recompute
|
|
280
|
+
all artifacts.
|
|
281
|
+
|
|
282
|
+
The :class:`simstack.models.parameters.Parameters` can specify
|
|
283
|
+
|
|
284
|
+
* a resource :class:`simstack.models.parameters.Resource` which must be one
|
|
285
|
+
of the resource names listed in the configuration file(:ref:`configuration-file`).
|
|
286
|
+
Specifying the resource ``self`` (the default) means that the node will be
|
|
287
|
+
executed on the same resource as the calling node.
|
|
288
|
+
* a queue (makes sense only for remote resources), with values ``default`` for
|
|
289
|
+
immediate execution, ``slurm_queue`` for submission to the batch system by
|
|
290
|
+
slurm
|
|
291
|
+
|
|
292
|
+
.. note:
|
|
293
|
+
|
|
294
|
+
The parameters are passed to the node as ``parent_parameters`` in the
|
|
295
|
+
\*\*kwargs because terminal nodes may need the memory settings etc for
|
|
296
|
+
mpi or other values
|
|
297
|
+
|
|
298
|
+
The slurm parameters are specified in Parameters has an attribute
|
|
299
|
+
``slurm_parameters`` of type: :class:`simstack.models.parameters.SlurmParameters`.
|
|
300
|
+
|
|
301
|
+
When specifying parameters in the @node decoration, the developer should
|
|
302
|
+
specify sensible default parameters for node execution. These can be overwritten
|
|
303
|
+
on-the-fly when calling the node:
|
|
304
|
+
|
|
305
|
+
.. code-block:: python
|
|
306
|
+
|
|
307
|
+
@node(parameters=Parameters(resource="standard-resource",
|
|
308
|
+
queue="slurm-queue"))
|
|
309
|
+
def some_node(*args,**kwargs):
|
|
310
|
+
.....
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def calling_function():
|
|
314
|
+
# we are already in a slurm job, we dont want to start another
|
|
315
|
+
# this node will run on the same resource
|
|
316
|
+
some_node(*args,parameters=Parameters(resource="self"))
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
Node Execution
|
|
320
|
+
--------------
|
|
321
|
+
|
|
322
|
+
The node decorator wraps the actual execution of the function into a series
|
|
323
|
+
of operations controlled by the class Node.
|
|
324
|
+
|
|
325
|
+
- before execution all arguments and the function body are hashed using
|
|
326
|
+
:func:`simstack.core.hash.complex_hash_function`, which will infer how to
|
|
327
|
+
deal with nested objects, such as list, dicts, classes, etc.
|
|
328
|
+
For odmantic models which have a ``complex_hash_function`` this function will
|
|
329
|
+
override the default behavior. Odmantic ObjectId are not hashed.
|
|
330
|
+
- if a NodeRegistry :class:`simstack.models.node_registry.NodeRegistry` entry
|
|
331
|
+
matching the name of the function, the hash of the
|
|
332
|
+
arguments and the hash of the function is found, this registry entry is
|
|
333
|
+
returned, even if the node has failed unless force_rerun is True.
|
|
334
|
+
- if no such NodeRegistry entry exists a new one is created with TaskStatus.SUBMITTED
|
|
335
|
+
- the node class then calls the function :func:`simstack.core.node.Node.run_somewhere`
|
|
336
|
+
which executes the node locally using
|
|
337
|
+
:func:`simstack.core.node.Node.execute_node_locally` or waits until
|
|
338
|
+
the task status is changed in the database by a runner. This function will
|
|
339
|
+
set the ``status`` field in the ``node_registry`` entry depending on the
|
|
340
|
+
outcome of the node execution an process the data in ``node_runner``
|
|
341
|
+
- after node execution the results from remote nodes are loaded from the
|
|
342
|
+
database.
|
|
343
|
+
|
|
344
|
+
.. note::
|
|
345
|
+
Timeouts for remote execution are not yet implemented.
|
|
346
|
+
|
|
347
|
+
Remote Execution
|
|
348
|
+
~~~~~~~~~~~~~~~~
|
|
349
|
+
|
|
350
|
+
Nodes scheduled to run on a remote execution require a runner
|
|
351
|
+
(:func:`simstack.core.runner.runner`) to be running on that resource with the
|
|
352
|
+
--resource flag set to the name of that node. The user or the administrator
|
|
353
|
+
has to install Simstack and the relevant user repositories on the remote
|
|
354
|
+
server and specify the information relevant to the remote node in the
|
|
355
|
+
``simstack.toml`` configuration file (see: :ref:`configuration-file`). This
|
|
356
|
+
needs to be done only once.
|
|
357
|
+
|
|
358
|
+
When someone is actively developing new nodes or other code to be run on the
|
|
359
|
+
remote node, it is important to keep the code on the remote server up-to-date.
|
|
360
|
+
The preferred way is to periodically check for a git-update or other server
|
|
361
|
+
crashes and restart the server if such events are detected.
|
|
362
|
+
The file :file:`simstack.scripts.check_runner.sh` provides a template that
|
|
363
|
+
must be adapted to the configuration of the remote node. This needs to be
|
|
364
|
+
done only once.
|
|
365
|
+
|
|
366
|
+
.. _registering:
|
|
367
|
+
|
|
368
|
+
Registering Models and Nodes
|
|
369
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
370
|
+
|
|
371
|
+
Database access to the mongodb database in Simstack II is facilitated by a
|
|
372
|
+
using the odmantic package, which provides asynchronous object oriented access
|
|
373
|
+
to the database (see :ref:`persisting_data`). This means that data in the
|
|
374
|
+
generic code-base of Simstack is loaded/stored by storing class instances.
|
|
375
|
+
|
|
376
|
+
These classes cannot be imported via the standard ``import`` statements,
|
|
377
|
+
because they are unknown to the SimStack core modules. To overcome this
|
|
378
|
+
problem a dynamic import system has been implemented, where the module paths
|
|
379
|
+
of Simstack Models and Nodes are stored in database tables (``node_model``
|
|
380
|
+
and ``model_table``, respectively).
|
|
381
|
+
|
|
382
|
+
The functions :func:`simstack.core.model_table.make_model_table` and
|
|
383
|
+
:func:`simstack.core.node_table.make_node_table` scan the directories
|
|
384
|
+
provided in the path section of the configuration file
|
|
385
|
+
(:ref:`configuration_file`)
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
.. code-block:: python
|
|
389
|
+
|
|
390
|
+
[paths]
|
|
391
|
+
# Path configuration for the PathManager.
|
|
392
|
+
# Each path entry should have a path and an optional drops value.
|
|
393
|
+
# The path is the directory to search for Python files
|
|
394
|
+
# The "drops" value is a prefix to drop from module names (for import paths)
|
|
395
|
+
models = { path = "src\\simstack\\models", drops = "src" }
|
|
396
|
+
methods = { path = "src\\simstack\\methods", drops = "src" }
|
|
397
|
+
ui_testing = { path = "src\\simstack\\ui_testing", drops = "src" }
|
|
398
|
+
applications = { path = "applications", drops = "", use_pickle = false }
|
|
399
|
+
tests = { path = "tests", drops = "", use_pickle = false }
|
|
400
|
+
projects = { path = "projects", drops = "",
|
|
401
|
+
use_pickle = false }
|
|
402
|
+
|
|
403
|
+
The first 4 entries are standard paths. The first three (models, methods,
|
|
404
|
+
ui_testing) belong to the Simstack core. ``applications`` is the standard
|
|
405
|
+
directory where you should install community application packages for
|
|
406
|
+
specific application domains.
|
|
407
|
+
|
|
408
|
+
The nodes and application programs written by you should go under
|
|
409
|
+
``projects``.
|
|
410
|
+
|
|
411
|
+
Most Common Errors & Problems
|
|
412
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
413
|
+
|
|
414
|
+
* remote runners are not on the same branch or not up-to-date (see Health
|
|
415
|
+
Check in the GUI)
|
|
416
|
+
* you can set the branch of the runners in the GUI (in profile). Unless in ver special
|
|
417
|
+
circumstances all runners should be on the same branch.
|
|
418
|
+
* all runners will periodically update from git. when the branch has changed the **default runner** will
|
|
419
|
+
recreate models and nodes. the runners will update --locked, i.e. they need an up-to-date uv.lock
|
|
420
|
+
* model and node creation is incremental. when you move things around the exisiting bindings will be
|
|
421
|
+
overridden, but if you delete models and nodes the database will not know this (which is intended because
|
|
422
|
+
data may still exist in the db)
|
|
423
|
+
* when you not only develop your own package but also the simstack core (you should not), it makes
|
|
424
|
+
sense to clone simstack as a subrepo into you main repo. You then must run ``uv lock --upgrade-package simstack``
|
|
425
|
+
after commits of simstack to keep your pyproject.toml up to date. after that you must run `` uv sync --locked`` and commit again
|
|
426
|
+
your main repo so that the runners can update simstack.
|
|
427
|
+
* node or model not registered in the database (see :ref:`registering`)
|
|
428
|
+
* node or model not imported correctly (see below)
|
|
429
|
+
* forgetting \*\*kwargs in the node function definition. Nodes will crash.
|
|
430
|
+
* relative imports suggested by IDE:
|
|
431
|
+
|
|
432
|
+
.. code-block:: python
|
|
433
|
+
|
|
434
|
+
from models import Model
|
|
435
|
+
from core.nodes import node
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
make sure all imports are relative to simstack. For example:
|
|
439
|
+
|
|
440
|
+
.. code-block:: python
|
|
441
|
+
|
|
442
|
+
from simstack.core.parameters import Parameters
|
|
443
|
+
from simstack.core.workflow import Workflow
|
|
444
|
+
from simstack.core.runner import Runner
|
|
445
|
+
|
|
446
|
+
or relative the other top-level modules. e.g. applications
|