diff --git a/changelog/fragments/991.fixed.rst b/changelog/fragments/991.fixed.rst new file mode 100644 index 0000000000000000000000000000000000000000..0a6550ffe51c1d6d5592b88875d458784069f6d0 --- /dev/null +++ b/changelog/fragments/991.fixed.rst @@ -0,0 +1,2 @@ +An ``MDODiscipline`` now checks the validity of the input data against the grammar before trying to retrieve them +from the cache. diff --git a/src/gemseo/utils/comparisons.py b/src/gemseo/utils/comparisons.py index 432fe63319e70384bda0c59b963aae65da3deb3b..a0e2e7bddd1c827a66b38e21f040b94ea4deca85 100644 --- a/src/gemseo/utils/comparisons.py +++ b/src/gemseo/utils/comparisons.py @@ -23,7 +23,9 @@ from collections.abc import Mapping from typing import Union from numpy import asarray +from numpy import ndarray from numpy.linalg import norm +from scipy.sparse import spmatrix from scipy.sparse.linalg import norm as spnorm from gemseo.utils.compatibility.scipy import ArrayType @@ -66,6 +68,9 @@ def compare_dict_of_arrays( # Check the values if tolerance: for key, value in dict_of_arrays.items(): + if not isinstance(value, (ndarray, spmatrix)): + return False + difference = other_dict_of_arrays[key] - value if isinstance(difference, sparse_classes): @@ -81,6 +86,8 @@ def compare_dict_of_arrays( return False else: for key, value in dict_of_arrays.items(): + if not isinstance(value, (ndarray, spmatrix)): + return False is_different = other_dict_of_arrays[key] != value if isinstance(is_different, sparse_classes): diff --git a/tests/core/test_discipline.py b/tests/core/test_discipline.py index eb775de5d45594e77f66dae6c29ed1d228aa1a2b..ea2dbd1834b52407a38ee6b90b94547d871697e2 100644 --- a/tests/core/test_discipline.py +++ b/tests/core/test_discipline.py @@ -1320,3 +1320,27 @@ def test_set_cache_policy_to_none(): assert isinstance(discipline.cache, SimpleCache) discipline.set_cache_policy(discipline.CacheType.NONE) assert discipline.cache is None + + +class SimpleDiscipline(MDODiscipline): + def __init__(self): + super().__init__(grammar_type="JSONGrammar") + self.input_grammar.update_from_names(["x"]) + self.output_grammar.update_from_names(["y"]) + + def _run(self): + (x,) = self.get_inputs_by_name(["x"]) + self.local_data["y"] = array([2.0 * x[0]]) + + +def test_grammar_same_input_different_types(): + """Test that a discipline does not return a cached result for invalid data. + + The hash of cached 1d array entry is the same as the hash of the same data as a + float, here we test that even if an entry already exists for a numpy array, the + cache will not return the cached result if the types are different. + """ + discipline = SimpleDiscipline() + discipline.execute({"x": array([1.0])}) + with pytest.raises(InvalidDataError): + discipline.execute({"x": 1.0})