Source code for gemseo.problems.scalable.data_driven.study.result

# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
# Contributors:
#    INITIAL AUTHORS - initial API and implementation and/or initial
#         documentation
#        :author:  Matthias De Lozzo
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""Scalability study - Result."""

from __future__ import annotations

import pickle
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any

if TYPE_CHECKING:
    from collections.abc import Iterable
    from collections.abc import Mapping
    from collections.abc import Sequence

RESULTS_DIRECTORY = Path("results")


[docs] class ScalabilityResult: """Scalability Result.""" def __init__(self, name: str, id_scaling: int, id_sample: int) -> None: """ Args: name: The name of the scalability result. id_scaling: The scaling identifier. id_sample: The sample identifier. """ # noqa: D205, D212, D415 self.name = name self.id_scaling = id_scaling self.id_sample = id_sample self.algo = None self.algo_options = None self.formulation_options = None self.formulation = None self.scaling = None self.n_calls = None self.n_calls_linearize = None self.n_calls_top_level = None self.n_calls_linearize_top_level = None self.exec_time = None self.original_exec_time = None self.status = None self.is_feasible = None self.disc_names = None self.old_varsizes = None self.new_varsizes = None self.output_names = None
[docs] def get( self, algo: str, algo_options: Mapping[str, Any], formulation: str, formulation_options: Mapping[str, Any], scaling: Mapping[str, Any], n_calls: Iterable[int], n_calls_linearize: Iterable[int], n_calls_top_level: Iterable[int], n_calls_linearize_top_level: Iterable[int], exec_time: float, status: int, is_feasible: bool, disc_names: Sequence[str], output_names: Sequence[str], old_varsizes: Mapping[str, int], new_varsizes: Mapping[str, int], ) -> None: """Get a scalability result for a given optimization strategy and a given scaling strategy. Args: algo: The name of the optimization algorithm. algo_options: The options of the optimization algorithm. formulation: The name of the MDO formulation. formulation_options: The options of the MDO formulation. scaling: The scaling strategy. n_calls: The number of calls per discipline. n_calls_linearize: The number of linearization per discipline n_calls_top_level: The number of calls per discipline n_calls_linearize_top_level: The number of linearizations per discipline. exec_time: The execution time. status: The status of the optimization scenario. is_feasible: Whether the solution is feasible. disc_names: The names of the disciplines. output_names: The names of the outputs. old_varsizes: The sizes of the original variables. new_varsizes: The sizes of the new variables. """ self.algo = algo self.algo_options = algo_options self.formulation = formulation self.formulation_options = formulation_options self.scaling = scaling self.n_calls = n_calls self.n_calls_linearize = n_calls_linearize self.n_calls_top_level = n_calls_top_level self.n_calls_linearize_top_level = n_calls_linearize_top_level self.exec_time = exec_time self.status = status self.is_feasible = is_feasible self.disc_names = disc_names self.output_names = output_names self.old_varsizes = old_varsizes self.new_varsizes = new_varsizes
[docs] def get_file_path(self, study_directory: str) -> Path: """Return file path. Args: study_directory: The study directory name. """ return ( Path(study_directory) / RESULTS_DIRECTORY / Path(self.name).with_suffix(".pkl") )
[docs] def to_pickle(self, study_directory: str) -> Path: """Save a scalability result into a pickle file whose name is the name of the ScalabilityResult instance. Args: study_directory: The study directory name. Returns: The path to the result. """ fpath = self.get_file_path(study_directory) result = { "algo": self.algo, "algo_options": self.algo_options, "formulation": self.formulation, "formulation_options": self.formulation_options, "scaling": self.scaling, "n_calls": self.n_calls, "n_calls_linearize": self.n_calls_linearize, "n_calls_top_level": self.n_calls_top_level, "n_calls_linearize_top_level": self.n_calls_linearize_top_level, "exec_time": self.exec_time, "status": self.status, "is_feasible": self.is_feasible, "disc_names": self.disc_names, "output_names": self.output_names, "old_varsizes": self.old_varsizes, "new_varsizes": self.new_varsizes, } with fpath.open("wb") as fout: pickle.dump(result, fout) return fpath
[docs] def load(self, study_directory) -> None: """Load a scalability result from a pickle file whose name is the name of the ScalabilityResult instance.""" fname = self.name + ".pkl" fpath = Path(study_directory) / RESULTS_DIRECTORY / fname with fpath.open("rb") as fin: result = pickle.load(fin) self.algo = result["algo"] self.formulation = result["formulation"] self.scaling = result["scaling"] self.n_calls = result["n_calls"] self.n_calls_linearize = result["n_calls_linearize"] self.n_calls_top_level = result["n_calls_top_level"] self.n_calls_linearize_top_level = result["n_calls_linearize_top_level"] self.exec_time = result["exec_time"] self.status = result["status"] self.is_feasible = result["is_feasible"] self.disc_names = result["disc_names"] self.output_names = result["output_names"] self.old_varsizes = result["old_varsizes"] self.new_varsizes = result["new_varsizes"]