From 30aba611005b3fc4767c3deb82dfbdbbe74c45d4 Mon Sep 17 00:00:00 2001 From: Jeremy Rapin Date: Wed, 10 Feb 2021 20:08:16 +0100 Subject: [PATCH 1/5] copy --- nevergrad/common/decorators.py | 4 +-- nevergrad/parametrization/choice.py | 15 ---------- nevergrad/parametrization/core.py | 42 +++++++++++++++++++--------- nevergrad/parametrization/data.py | 16 ++++------- nevergrad/parametrization/helpers.py | 1 + nevergrad/parametrization/utils.py | 3 ++ 6 files changed, 41 insertions(+), 40 deletions(-) diff --git a/nevergrad/common/decorators.py b/nevergrad/common/decorators.py index d102e2f36..05f657663 100644 --- a/nevergrad/common/decorators.py +++ b/nevergrad/common/decorators.py @@ -33,8 +33,8 @@ def register_name( self, name: str, obj: X, info: tp.Optional[tp.Dict[tp.Hashable, tp.Any]] = None ) -> None: """Register an object with a provided name""" - if name in self: - raise RuntimeError(f'Encountered a name collision "{name}"') + # if name in self: + # raise RuntimeError(f'Encountered a name collision "{name}"') self[name] = obj if info is not None: assert isinstance(info, dict) diff --git a/nevergrad/parametrization/choice.py b/nevergrad/parametrization/choice.py index 3009f0dd5..f37cd736c 100644 --- a/nevergrad/parametrization/choice.py +++ b/nevergrad/parametrization/choice.py @@ -228,15 +228,6 @@ def mutate(self) -> None: for ind in indices: self.choices[ind].mutate() - def _internal_spawn_child(self: C) -> C: - child = self.__class__( - choices=self.choices.spawn_child(), - deterministic=self._deterministic, - repetitions=self._repetitions, - ) - child._content["weights"] = self.weights.spawn_child() - return child - class TransitionChoice(BaseChoice): """Ordered categorical parameter, choosing one of the provided choice options as a value, with continuous transitions. @@ -325,9 +316,3 @@ def mutate(self) -> None: indices = set(self.indices) for ind in indices: self.choices[ind].mutate() - - def _internal_spawn_child(self: T) -> T: - child = self.__class__(choices=self.choices.spawn_child(), repetitions=self._repetitions) - child._content["positions"] = self.positions.spawn_child() - child._content["transitions"] = self.transitions.spawn_child() - return child diff --git a/nevergrad/parametrization/core.py b/nevergrad/parametrization/core.py index edeeac2c5..e9e6184fa 100644 --- a/nevergrad/parametrization/core.py +++ b/nevergrad/parametrization/core.py @@ -4,6 +4,7 @@ # LICENSE file in the root directory of this source tree. import uuid +import copy import warnings import operator import functools @@ -358,14 +359,35 @@ def spawn_child(self: P, new_value: tp.Optional[tp.Any] = None) -> P: Optionally, a new value will be set after creation """ rng = self.random_state # make sure to create one before spawning - child = self._internal_spawn_child() - child._set_random_state(rng) - child._constraint_checkers = list(self._constraint_checkers) - child._generation = self.generation + 1 - child._descriptors = self._descriptors - child._name = self._name - child.parents_uids.append(self.uid) + child = copy.copy(self) + child.uid = uuid.uuid4().hex + child._frozen = False + child._generation += 1 + child.parents_uids = [self.uid] child.heritage = dict(self.heritage) + child._treecall = self._treecall.new(child) + child._meta = {} + child.loss = None + child._losses = None + attribute = self._treecall.attribute + container = getattr(child, self._treecall.attribute) + if attribute != "__dict__": # make a copy of the container if different from __dict__ + container = dict(container) if isinstance(container, dict) else list(container) + setattr(child, attribute, container) + for key, val in self._treecall._subitems(): + container[key] = val.spawn_child() + child._set_random_state(rng) + # print("after", container) + + # rng = self.random_state # make sure to create one before spawning + # child = self._internal_spawn_child() + # child._set_random_state(rng) + # child._constraint_checkers = list(self._constraint_checkers) + # child._generation = self.generation + 1 + # child._descriptors = self._descriptors + # child._name = self._name + # child.heritage = dict(self.heritage) + # child.parents_uids.append(self.uid) if new_value is not None: child.value = new_value return child @@ -397,7 +419,6 @@ def copy(self: P) -> P: # TODO test (see former instrumentation_copy test) This is used to run multiple experiments """ child = self.spawn_child() - child._name = self._name child.random_state = None return child @@ -581,11 +602,6 @@ def sample(self: D) -> D: child.heritage["lineage"] = child.uid return child - def _internal_spawn_child(self: D) -> D: - child = self.__class__() - child._content = {k: v.spawn_child() for k, v in self._content.items()} - return child - class Dict(Container): """Dictionary-valued parameter. This Parameter can contain other Parameters, diff --git a/nevergrad/parametrization/data.py b/nevergrad/parametrization/data.py index 296990b6a..8028ec37c 100644 --- a/nevergrad/parametrization/data.py +++ b/nevergrad/parametrization/data.py @@ -341,16 +341,6 @@ def _internal_set_standardized_data( if reference.bound_transform is not None: self._value = reference.bound_transform.forward(self._value) - def _internal_spawn_child(self: D) -> D: - child = self.__class__(init=self.value) - child.parameters._content = { - k: v.spawn_child() if isinstance(v, core.Parameter) else v - for k, v in self.parameters._content.items() - } - for name in ["integer", "exponent", "bounds", "bound_transform", "full_range_sampling"]: - setattr(child, name, getattr(self, name)) - return child - def _internal_get_standardized_data(self: D, reference: D) -> np.ndarray: return reference._to_reduced_space(self._value) - reference._get_ref_data() # type: ignore @@ -388,6 +378,12 @@ def recombine(self: D, *others: D) -> None: else: raise ValueError(f'Unknown recombination "{recomb}"') + def spawn_child(self: D, new_value: tp.Optional[tp.Any] = None) -> D: + child = super().spawn_child() + if new_value is None: + child._value = np.array(self._value, copy=True) + return child + class Array(Data): diff --git a/nevergrad/parametrization/helpers.py b/nevergrad/parametrization/helpers.py index 16df4680d..a65205b08 100644 --- a/nevergrad/parametrization/helpers.py +++ b/nevergrad/parametrization/helpers.py @@ -111,6 +111,7 @@ def split_as_data_parameters( # analyze results data = copied.get_standardized_data(reference=ref) order: tp.List[int] = [] + print(data) for val, _ in itertools.groupby(data): num = int(np.round(val)) if num in order: diff --git a/nevergrad/parametrization/utils.py b/nevergrad/parametrization/utils.py index eb32dc3e7..56b1bb4ba 100644 --- a/nevergrad/parametrization/utils.py +++ b/nevergrad/parametrization/utils.py @@ -232,6 +232,9 @@ def __init__(self, obj: tp.Any, cls: tp.Type[tp.Any], attribute: str = "__dict__ self.cls = cls self.attribute = attribute + def new(self, obj: tp.Any) -> "Treecall": + return Treecall(obj, cls=self.cls, attribute=self.attribute) + def _subitems(self) -> tp.Iterator[tp.Tuple[tp.Any, tp.Any]]: container = getattr(self.obj, self.attribute) if not isinstance(container, (list, dict)): From 53854218dbd12282db98c9189e0dc4a24cb4625b Mon Sep 17 00:00:00 2001 From: Jeremy Rapin Date: Wed, 10 Feb 2021 20:14:32 +0100 Subject: [PATCH 2/5] better --- nevergrad/parametrization/core.py | 1 + nevergrad/parametrization/data.py | 9 +++++---- nevergrad/parametrization/test_parameters_legacy.py | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nevergrad/parametrization/core.py b/nevergrad/parametrization/core.py index e9e6184fa..c96872e4a 100644 --- a/nevergrad/parametrization/core.py +++ b/nevergrad/parametrization/core.py @@ -389,6 +389,7 @@ def spawn_child(self: P, new_value: tp.Optional[tp.Any] = None) -> P: # child.heritage = dict(self.heritage) # child.parents_uids.append(self.uid) if new_value is not None: + print("Updating") child.value = new_value return child diff --git a/nevergrad/parametrization/data.py b/nevergrad/parametrization/data.py index 8028ec37c..e27eb490c 100644 --- a/nevergrad/parametrization/data.py +++ b/nevergrad/parametrization/data.py @@ -379,9 +379,10 @@ def recombine(self: D, *others: D) -> None: raise ValueError(f'Unknown recombination "{recomb}"') def spawn_child(self: D, new_value: tp.Optional[tp.Any] = None) -> D: - child = super().spawn_child() - if new_value is None: - child._value = np.array(self._value, copy=True) + child = super().spawn_child() # dont forward the value + child._value = np.array(self._value, copy=True) + if new_value is not None: + child.value = new_value return child @@ -424,7 +425,7 @@ class Scalar(Data): upper: optional float maximum value if any mutable_sigma: bool - whether the mutation standard deviation must mutate as well (for mutation based algorithms) + wheter the mutation standard deviation must mutate as well (for mutation based algorithms) Notes ----- diff --git a/nevergrad/parametrization/test_parameters_legacy.py b/nevergrad/parametrization/test_parameters_legacy.py index 64103ab87..6c42fd6ed 100644 --- a/nevergrad/parametrization/test_parameters_legacy.py +++ b/nevergrad/parametrization/test_parameters_legacy.py @@ -124,6 +124,7 @@ def test_scalar() -> None: token = p.Scalar().set_integer_casting() assert token.spawn_child().set_standardized_data([0.7]).value == 1 new_token = token.spawn_child(new_value=1) + print(new_token) assert new_token.get_standardized_data(reference=token).tolist() == [1.0] From 8d973f35914ef60dd7d6419317e20e3c3f230610 Mon Sep 17 00:00:00 2001 From: Jeremy Rapin Date: Wed, 10 Feb 2021 20:18:02 +0100 Subject: [PATCH 3/5] working --- nevergrad/parametrization/core.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/nevergrad/parametrization/core.py b/nevergrad/parametrization/core.py index c96872e4a..623ae93c8 100644 --- a/nevergrad/parametrization/core.py +++ b/nevergrad/parametrization/core.py @@ -369,6 +369,7 @@ def spawn_child(self: P, new_value: tp.Optional[tp.Any] = None) -> P: child._meta = {} child.loss = None child._losses = None + child._constraint_checkers = list(self._constraint_checkers) attribute = self._treecall.attribute container = getattr(child, self._treecall.attribute) if attribute != "__dict__": # make a copy of the container if different from __dict__ @@ -377,19 +378,7 @@ def spawn_child(self: P, new_value: tp.Optional[tp.Any] = None) -> P: for key, val in self._treecall._subitems(): container[key] = val.spawn_child() child._set_random_state(rng) - # print("after", container) - - # rng = self.random_state # make sure to create one before spawning - # child = self._internal_spawn_child() - # child._set_random_state(rng) - # child._constraint_checkers = list(self._constraint_checkers) - # child._generation = self.generation + 1 - # child._descriptors = self._descriptors - # child._name = self._name - # child.heritage = dict(self.heritage) - # child.parents_uids.append(self.uid) if new_value is not None: - print("Updating") child.value = new_value return child From 0685afebc3eb54f1e1dd33dd810a9ae772daf585 Mon Sep 17 00:00:00 2001 From: Jeremy Rapin Date: Wed, 10 Feb 2021 21:33:24 +0100 Subject: [PATCH 4/5] fix --- nevergrad/common/decorators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nevergrad/common/decorators.py b/nevergrad/common/decorators.py index 05f657663..d102e2f36 100644 --- a/nevergrad/common/decorators.py +++ b/nevergrad/common/decorators.py @@ -33,8 +33,8 @@ def register_name( self, name: str, obj: X, info: tp.Optional[tp.Dict[tp.Hashable, tp.Any]] = None ) -> None: """Register an object with a provided name""" - # if name in self: - # raise RuntimeError(f'Encountered a name collision "{name}"') + if name in self: + raise RuntimeError(f'Encountered a name collision "{name}"') self[name] = obj if info is not None: assert isinstance(info, dict) From 253f030b877bd0cd0e142749d9b0c6d46db3ee73 Mon Sep 17 00:00:00 2001 From: Jeremy Rapin Date: Wed, 10 Feb 2021 21:33:43 +0100 Subject: [PATCH 5/5] remove --- nevergrad/parametrization/test_parameters_legacy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nevergrad/parametrization/test_parameters_legacy.py b/nevergrad/parametrization/test_parameters_legacy.py index 6c42fd6ed..64103ab87 100644 --- a/nevergrad/parametrization/test_parameters_legacy.py +++ b/nevergrad/parametrization/test_parameters_legacy.py @@ -124,7 +124,6 @@ def test_scalar() -> None: token = p.Scalar().set_integer_casting() assert token.spawn_child().set_standardized_data([0.7]).value == 1 new_token = token.spawn_child(new_value=1) - print(new_token) assert new_token.get_standardized_data(reference=token).tolist() == [1.0]