Skip to content

Commit

Permalink
Remove old SimulatorCache
Browse files Browse the repository at this point in the history
  • Loading branch information
yngve-sk committed Jan 27, 2025
1 parent 4c972df commit 4e70ffd
Showing 1 changed file with 8 additions and 123 deletions.
131 changes: 8 additions & 123 deletions src/ert/run_models/everest_run_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import os
import queue
import shutil
from collections import defaultdict
from collections.abc import Callable
from dataclasses import dataclass
from enum import IntEnum
Expand Down Expand Up @@ -125,14 +124,6 @@ def __init__(
self._fm_errors: dict[int, dict[str, Any]] = {}
self._result: OptimalResult | None = None
self._exit_code: EverestExitCode | None = None
self._simulator_cache = (
SimulatorCache()
if (
everest_config.simulator is not None
and everest_config.simulator.enable_cache
)
else None
)
self._experiment: EverestExperiment | None = None
self._eval_server_cfg: EvaluatorServerConfig | None = None
self._batch_id: int = 0
Expand Down Expand Up @@ -387,7 +378,6 @@ def _forward_model_evaluator(

realizations = self._everest_config.model.realizations
num_perturbations = self._everest_config.optimization.perturbation_num

Check failure on line 380 in src/ert/run_models/everest_run_model.py

View workflow job for this annotation

GitHub Actions / type-checking (3.12)

Item "None" of "OptimizationConfig | None" has no attribute "perturbation_num"
realization_mapping: dict[int, EverestRealizationInfo] = {}

realization_mapping: dict[int, EverestRealizationInfo] = {}
if len(evaluator_context.realizations) == len(realizations):
Expand Down Expand Up @@ -444,15 +434,6 @@ def _forward_model_evaluator(
control_values, batch_data, results, cached_results
)

# Add the results from the evaluations to the cache:
self._add_results_to_cache(
control_values,
evaluator_context,
batch_data,
evaluator_result.objectives,
evaluator_result.constraints,
)

# Increase the batch ID for the next evaluation:
self._batch_id += 1

Expand All @@ -477,16 +458,6 @@ def controls_1d_to_dict(values_: list[float]):
)
}

cached_results: dict[int, Any] = {}
if self._simulator_cache is not None:
for control_idx, real_idx in enumerate(evaluator_context.realizations):
cached_data = self._simulator_cache.get(
self._everest_config.model.realizations[real_idx],
control_values[control_idx, :],
)
if cached_data is not None:
cached_results[control_idx] = cached_data

cached_results2: dict[int, Any] = {}
for control_values_ in control_values.tolist():
parameter_group_values = controls_1d_to_dict(control_values_)
Expand Down Expand Up @@ -522,20 +493,6 @@ def controls_1d_to_dict(values_: list[float]):
)
cached_results2[ert_realization] = cached_data

# Redundant double-checking for sanity, to be removed
# +--------------------------------------------------------+
for k, expected in cached_results.items():
actual_objs, actual_constrs = cached_results2[k]
exp_objs, exp_constrs = expected
if not np.allclose(actual_objs, exp_objs, atol=1e-6):
print("Something wrong with caching!")

if actual_constrs != exp_constrs and not np.allclose(
actual_constrs, exp_constrs, atol=1e-6
):
print("Something wrong with caching!")
# +--------------------------------------------------------+

return cached_results2

def _init_batch_data(
Expand Down Expand Up @@ -720,15 +677,14 @@ def _make_evaluator_result(
batch_data,
)

if self._simulator_cache is not None:
for control_idx, (
cached_objectives,
cached_constraints,
) in cached_results.items():
objectives[control_idx, ...] = cached_objectives
if constraints is not None:
assert cached_constraints is not None
constraints[control_idx, ...] = cached_constraints
for control_idx, (
cached_objectives,
cached_constraints,
) in cached_results.items():
objectives[control_idx, ...] = cached_objectives
if constraints is not None:
assert cached_constraints is not None
constraints[control_idx, ...] = cached_constraints

sim_ids = np.full(control_values.shape[0], -1, dtype=np.intc)
sim_ids[list(batch_data.keys())] = np.arange(len(batch_data), dtype=np.intc)
Expand All @@ -755,25 +711,6 @@ def _get_simulation_results(
)
return values

def _add_results_to_cache(
self,
control_values: NDArray[np.float64],
evaluator_context: EvaluatorContext,
batch_data: dict[int, Any],
objectives: NDArray[np.float64],
constraints: NDArray[np.float64] | None,
) -> None:
if self._simulator_cache is not None:
for control_idx in batch_data:
self._simulator_cache.add(
self._everest_config.model.realizations[
evaluator_context.realizations[control_idx]
],
control_values[control_idx, ...],
objectives[control_idx, ...],
None if constraints is None else constraints[control_idx, ...],
)

def check_if_runpath_exists(self) -> bool:
return (
self._everest_config.simulation_dir is not None
Expand Down Expand Up @@ -855,55 +792,3 @@ def _handle_errors(
elif fm_id not in self._fm_errors[error_hash]["ids"]:
self._fm_errors[error_hash]["ids"].append(fm_id)
error_id = self._fm_errors[error_hash]["error_id"]
fm_logger.error(err_msg.format("Already reported as", error_id))


class SimulatorCache:
EPS = float(np.finfo(np.float32).eps)

def __init__(self) -> None:
self._data: defaultdict[
int,
list[
tuple[
NDArray[np.float64], NDArray[np.float64], NDArray[np.float64] | None
]
],
] = defaultdict(list)

def add(
self,
realization: int,
control_values: NDArray[np.float64],
objectives: NDArray[np.float64],
constraints: NDArray[np.float64] | None,
) -> None:
"""Add objective and constraints for a given realization and control values.
The realization is the index of the realization in the ensemble, as specified
in by the realizations entry in the everest model configuration. Both the control
values and the realization are used as keys to retrieve the objectives and
constraints later.
"""
self._data[realization].append(
(
control_values.copy(),
objectives.copy(),
None if constraints is None else constraints.copy(),
),
)

def get(
self, realization: int, controls: NDArray[np.float64]
) -> tuple[NDArray[np.float64], NDArray[np.float64] | None] | None:
"""Get objective and constraints for a given realization and control values.
The realization is the index of the realization in the ensemble, as specified
in by the realizations entry in the everest model configuration. Both the control
values and the realization are used as keys to retrieve the objectives and
constraints from the cached values.
"""
for control_values, objectives, constraints in self._data.get(realization, []):
if np.allclose(controls, control_values, rtol=0.0, atol=self.EPS):
return objectives, constraints
return None

0 comments on commit 4e70ffd

Please sign in to comment.