Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some adaptations to workflows #9994

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

yngve-sk
Copy link
Contributor

@yngve-sk yngve-sk commented Feb 6, 2025

Issue
Resolves equinor/semeio#685

Add support for defaulted kwargs from workflows

@yngve-sk yngve-sk force-pushed the 25.02.05.internal-workflows-pass-some-stuff branch 2 times, most recently from e38fc26 to 16d8860 Compare February 6, 2025 11:11
Copy link

codspeed-hq bot commented Feb 6, 2025

CodSpeed Performance Report

Merging #9994 will improve performances by 13.37%

Comparing yngve-sk:25.02.05.internal-workflows-pass-some-stuff (9d1a66e) with main (3f4a93e)

Summary

⚡ 1 improvements
✅ 24 untouched benchmarks

Benchmarks breakdown

Benchmark BASE HEAD Change
test_direct_dark_performance_with_storage[gen_x: 20, sum_x: 20 reals: 10-gen_data_with_obs-get_record_observations] 2.5 ms 2.2 ms +13.37%

@yngve-sk yngve-sk force-pushed the 25.02.05.internal-workflows-pass-some-stuff branch 3 times, most recently from a1fc9a1 to ab916da Compare February 6, 2025 13:40
Copy link
Collaborator

@oyvindeide oyvindeide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, I have some minor questions.

runner = WorkflowRunner(
workflow=workflow,
storage=storage,
ert_config=ert_config,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we should remove this as it is not available in run models, where most of these are run from?

if is_using_wf_args_fixture
else [*workflow_args, *fixture_args]
)
if not positional_args and not use_kwargs:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This we could keep this as it used to be? I dont think kwargs were really supported before, they just ended up being workflow_args in a list?

@@ -107,14 +107,16 @@ class WorkflowRunner:
def __init__(
self,
workflow: Workflow,
config_file: str | None = None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also commented in semeio, could potentially give reports dir, we do something similar for the update report, that has a folder it writes to.

storage: Storage | None = None,
ensemble: Ensemble | None = None,
ert_config: ErtConfig | None = None,
) -> None:
self.__workflow = workflow
self.storage = storage
self.ensemble = ensemble
self.ert_config = ert_config
self.ert_config = ert_config # Should eventually be removed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove now?

@yngve-sk yngve-sk force-pushed the 25.02.05.internal-workflows-pass-some-stuff branch 8 times, most recently from a60c42c to 6e47da3 Compare February 11, 2025 08:55
@jonathan-eq jonathan-eq self-requested a review February 11, 2025 09:13
func_args: MappingProxyType[str, inspect.Parameter],
fixtures: dict[str, Fixtures],
func_args: dict[str, inspect.Parameter],
fixtures: dict[WorkflowFixtures, Any],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not entirely getting this. If fixtures is a dict, where the keys can only be any of the WorkflowFixtures enum values; shouldnt WorkflowFixtures be a dataclass and we would use fixtures: WorkflowFixtures instead of fixtures: dict[WorkflowFixtures, Any]?
Why is the fixture value Any?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm it could be set as a dataclass I think, but eventually the fixtures are passed in as arguments, and we also give them in a very "partial" way. We can do this in dataclasses by omitting stuff etc etc, but there we would have lots of default'ed None values. In some cases we want an error if a workflow requests an argument that is not a fixture, nor a provided kwarg. If we had a dataclass, we would have to know whether the None in the fixture means an explicit None from outside, or a truly "missing" argument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we have it as a TypedDict and mark the types with NotRequired?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is probably better, testing...

fixtures: dict[str, Fixtures],
func_args: dict[str, inspect.Parameter],
fixtures: dict[WorkflowFixtures, Any],
kwargs: dict[str, Any],
) -> list[Any]:
arguments = []
errors = []
for val in func_args:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is val here? Is it the required argument?

Copy link
Contributor Author

@yngve-sk yngve-sk Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep it is required, and we mark it as an error if val is not in the fixtures, or explicit kwargs the run fn is invoked with. So func_args here is the arguments of the run function of the workflow, and here we are creating the arguments to call the run function with, by inserting the values for corresponding fixtures. So the whole purpose of the fixtures is to substitute here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh, okay! That makes sense! Very good 👍

Comment on lines 750 to 757
self.run_workflows(
HookRuntime.POST_SIMULATION,
fixtures={
WorkflowFixtures.storage: self._storage,
WorkflowFixtures.ensemble: ensemble,
WorkflowFixtures.reports_dir: self.reports_dir(
ensemble_name=ensemble.name
),
WorkflowFixtures.random_seed: self.random_seed,
WorkflowFixtures.run_paths: self.run_paths,
},
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this and the the self.run_workflows above it the same, except for the ensemble maybe changing? Maybe we can move most of it into the run_workflows method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes most sense to keep the fixtures as an arg to run_workflows, since it is invoked from other places than BaseRunModel at different points/hooks in the ERT execution, and it makes it clear at the callsites which fixtures are given to the workflows.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, good!

@yngve-sk yngve-sk force-pushed the 25.02.05.internal-workflows-pass-some-stuff branch 3 times, most recently from 87c7ada to 0aeee68 Compare February 11, 2025 13:11
Copy link
Contributor

@jonathan-eq jonathan-eq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good :) See some minor questions 🔍

from ert.storage import Ensemble, Storage


class WorkflowFixtures(TypedDict):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can omit marking all keys with NotRequired if you change class WorkflowFixtures(TypedDict) to class WorkflowFixtures(TypedDict, total=False) https://peps.python.org/pep-0589/#totality

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

func_args = inspect.signature(script.getArguments).parameters
arguments = script.insert_fixtures(func_args, fixtures)
arguments = script.insert_fixtures(dict(func_args), fixtures, {})

# Part of deprecation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover comment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^the part of deprecation line

Comment on lines 11 to 12
if TYPE_CHECKING:
from ert.storage import Ensemble, Storage
pass
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets remove this type_checking :)

["1", "2", "3"],
fixture_mock,
)


def test_plugin_with_default_arguments(capsys):
def test_plugin_with_fixtures_and_enough_arguments_positional():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think test_plugin_with_fixtures_and_enough_positional_arguments would read a tad better

)


def test_plugin_with_default_arguments(capsys):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test using capsys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed it in separate commit

@yngve-sk yngve-sk force-pushed the 25.02.05.internal-workflows-pass-some-stuff branch from 0aeee68 to 9d1a66e Compare February 11, 2025 14:20
@jonathan-eq
Copy link
Contributor

There seems to be a GUI test hanging now 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

AHMAnalysis not working after ErtConfig change
3 participants