Skip to content

Add new forward model configuration style #10597

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

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

Conversation

yngve-sk
Copy link
Contributor

Issue
Resolves #9615

Copy link

codspeed-hq bot commented Apr 10, 2025

CodSpeed Performance Report

Merging #10597 will not alter performance

Comparing yngve-sk:25.04.10.everest-fm-config-change (a182c95) with main (313c229)

Summary

✅ 25 untouched benchmarks

@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch 4 times, most recently from d436308 to c08e84f Compare April 14, 2025 13:21
@yngve-sk yngve-sk marked this pull request as ready for review April 15, 2025 07:08
@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch 2 times, most recently from f4edd63 to 7ccd960 Compare April 16, 2025 07:47
@yngve-sk yngve-sk closed this Apr 22, 2025
@yngve-sk yngve-sk reopened this Apr 22, 2025
@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch 10 times, most recently from 89fd199 to 2e08023 Compare April 22, 2025 11:35
@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch from 2e08023 to 3d84617 Compare April 22, 2025 11:36
@yngve-sk yngve-sk self-assigned this Apr 22, 2025
@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch from 3943605 to bfae075 Compare April 22, 2025 12:21
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.

Looking good! Some comments which might simplify it a bit

Comment on lines 254 to 266
def consolidate_forward_model_formats(
cls, values: dict[str, Any]
) -> dict[str, Any]:
def format_fm(fm: str | dict[str, Any]) -> dict[str, Any]:
if isinstance(fm, dict):
return fm

return {"job": fm, "results": None}

if "forward_model" in values:
values["forward_model"] = [format_fm(fm) for fm in values["forward_model"]]

return values
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can be done with a field validator on forward_model:

class B(BaseModel):
    a: str
    b: int

class A(BaseModel):
    a: B

    @field_validator("a", mode="before")
    @classmethod
    def transform(cls, raw: str | dict[str, int]):
        if isinstance(raw, str):
            a, b = raw.split(",")
            return {"a": a, "b": b}
        return raw

if job_name not in installed_jobs_name:
errors.append(f"unknown job {job_name}")

if len(errors) > 0: # Note: python3.11 ExceptionGroup will solve this nicely
raise ValueError(errors)
return self

def get_forward_model_steps(
self, result_type: Literal["gen_data", "summary"]
) -> list[ForwardModelStepConfigWithResults]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This will also be simplified if you add a field validator on forward_model I think

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 this and moved filtering to the 2 callsites, behavior wrt field validator remains the same though.

Comment on lines +303 to +322
@model_validator(mode="after")
def validate_at_most_one_summary_forward_model(self, _: ValidationInfo) -> Self:
if self.forward_model is None:
return self

summary_fms = [
fm
for fm in self.forward_model
if isinstance(fm, ForwardModelStepConfig)
and fm.results is not None
and fm.results.type == "summary"
]
if len(summary_fms) > 1:
raise ValueError(
f"Found ({len(summary_fms)}) "
f"forward model steps producing summary data. "
f"Only one summary-producing forward model step is supported."
)

return self
Copy link
Collaborator

Choose a reason for hiding this comment

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

Think this might be cleaner if it is located with ForwardModelStepConfig?

class ForwardModelStepConfig(BaseModelWithContextSupport):
    job: str = Field(
        description="Name of the forward model step",
    )
    results: ForwardModelStepResultsConfig | None = Field(
        default=None, description="Result file produced by the forward model"
    )
    nr_summary: ClassVar[int] = 0

    @field_validator("results")
    def check_nr_summary(self, v: Any):
        if v is not None and v.type == "summary":
            if self.nr_summary == 0:
                self.nr_summary += 1
            elif self.nr_summary > 0:
                raise ValueError("Can only have one summary result")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, I can see it would work to have a classvar to count the number of summary initializations to mimic doing a validator on the list, but not sure if it is more clean/easy to work with? Like if we directly or indirectly initialize multiple configs, the counter will keep going up, so it would have to be forced to be scoped within each EverestConfig instance.

@model_validator(mode="before")
@classmethod
def validate_no_data_file(cls, values: dict[str, Any]) -> dict[str, Any]:
if "model" in values and "data_file" in values["model"]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should probably be on ModelConfig:
´´´python
@model_validator(mode="before")
@classmethod
def deprecate_key(cls, values: Any) -> Any:
if "data_file" in values:
raise ...


though we might want cross validation between `eclbase` and `model.data_file` 🤔 

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 now that it only looks on data_file it should be moved, but I also think some cross validation makes sense, so I added that here

@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch from 38fe743 to cee48fb Compare April 23, 2025 07:10
@yngve-sk yngve-sk force-pushed the 25.04.10.everest-fm-config-change branch from cee48fb to 50275f0 Compare April 23, 2025 07:11
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.

Context validation of the simulator specific keywords
2 participants