Skip to content

AnalyticDiscipline is not serializable

A Scenario cannot be serialized if it contains an AnalyticDiscipline as the latter is not serializable:

from gemseo.algos.design_space import DesignSpace
from gemseo.core.doe_scenario import DOEScenario
from gemseo.disciplines.analytic import AnalyticDiscipline

file_path = "scenario.h5"

design_space = DesignSpace()
design_space.add_variable("x", l_b=0.0, u_b=1.0, value=0.5)
discipline = AnalyticDiscipline({"y1": "x+y1", "y2": "x+2*y1", "f": "y1+y2+x"})
scenario = DOEScenario([discipline], "DisciplinaryOpt", "f", design_space)
scenario.serialize(file_path)

input_data = {"algo": "fullfact", "n_samples": 2}
scenario.execute(input_data)

saved_scenario = DOEScenario.deserialize(file_path)
saved_scenario.execute(input_data)
print(scenario.formulation.opt_problem.database)
print(saved_scenario.formulation.opt_problem.database)

Furthermore, sympy objects seems to be unserializable as after enrichment of AnalyticDiscipline._ATTR_TO_SERIALIZE with the appropriate, we have a new error:

    def serialize(
        self,
        file_path: str | Path,
    ) -> None:
        """Serialize the discipline and store it in a file.

        Args:
            file_path: The path to the file to store the discipline.
        """
        with Path(file_path).open("wb") as outfobj:
            pickler = pickle.Pickler(outfobj, protocol=2)
>           pickler.dump(self)
E           _pickle.PicklingError: Can't pickle <function _lambdifygenerated at 0x0000015DDB147A60>: attribute lookup _lambdifygenerated on __main__ fai
led

Thus, I propose to override serialize, deserialize, __getstate__ and __setstate__ in AnalyticDiscipline.

Traceback

Traceback (most recent call last):
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\sandbox\as_dict.py", line 17, in <module>
    saved_scenario.execute(input_data)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\discipline.py", line 918, in execute
    self._run()
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\scenario.py", line 459, in _run
    self._run_algorithm()
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\doe_scenario.py", line 131, in _run_algorithm
    self.optimization_result = lib.execute(self.formulation.opt_problem, **options)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\algos\driver_lib.py", line 466, in execute
    result = self._run(**options)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\algos\doe\doe_lib.py", line 182, in _run
    self.evaluate_samples(eval_jac, n_processes, wait_time_between_samples)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\algos\doe\doe_lib.py", line 363, in evaluate_samples
    self.problem.evaluate_functions(
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\algos\opt_problem.py", line 991, in evaluate_functions
    outputs[func.name] = func.evaluate(func_inputs)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 445, in evaluate
    val = self.__counted_f(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 325, in __counted_f
    self.last_eval = self._func(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\norm_db_function.py", line 130, in _func
    value = self.__evaluate_orig_func(xu_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 445, in evaluate
    val = self.__counted_f(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 325, in __counted_f
    self.last_eval = self._func(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\norm_function.py", line 98, in _func
    return self.__evaluate_orig_func(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 445, in evaluate
    val = self.__counted_f(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 325, in __counted_f
    self.last_eval = self._func(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\function_from_discipline.py", line 124, in _func
    return self.__out_x_func(x_vect[self.__x_mask])
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 430, in __call__
    return self.evaluate(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 445, in evaluate
    val = self.__counted_f(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\mdo_function.py", line 325, in __counted_f
    self.last_eval = self._func(x_vect)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\mdofunctions\make_function.py", line 142, in _func
    output_data = self.__discipline.execute(input_data)
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\core\discipline.py", line 918, in execute
    self._run()
  File "C:\Users\matthias.delozzo\workspace\GEMSEO\gemseo\src\gemseo\disciplines\analytic.py", line 184, in _run
    if self._fast_evaluation:
AttributeError: 'AnalyticDiscipline' object has no attribute '_fast_evaluation'
Edited by Matthias De Lozzo