Skip to content

Commit

Permalink
Delay computation in default executor (facebookresearch#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrapin authored Feb 20, 2019
1 parent 221ef94 commit 0c4469a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
12 changes: 6 additions & 6 deletions nevergrad/optimization/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ def tell(self, x: ArrayLike, value: float) -> None:
value: float
value of the function
"""
# call callbacks for logging etc...
for callback in self._callbacks.get("tell", []):
callback(self, x, value)
if not isinstance(value, Real):
raise TypeError(f'"tell" method only supports float values but the passed value was: {value} (type: {type(value)}.')
if np.isnan(value) or value == np.inf:
Expand All @@ -155,20 +158,17 @@ def tell(self, x: ArrayLike, value: float) -> None:
assert self.current_bests[name].x in self.archive, "Best value should exist in the archive"
self._internal_tell(x, value)
self._num_tell += 1
# call callbacks for logging etc...
for callback in self._callbacks.get("tell", []):
callback(self, x, value)

def ask(self) -> Tuple[float, ...]:
"""Provides a point to explore.
This function can be called multiple times to explore several points in parallel
"""
suggestion = self._internal_ask()
assert suggestion is not None, f"{self.__class__.__name__}._internal_ask method returned None instead of a point."
self._num_ask += 1
# call callbacks for logging etc...
for callback in self._callbacks.get("ask", []):
callback(self)
suggestion = self._internal_ask()
assert suggestion is not None, f"{self.__class__.__name__}._internal_ask method returned None instead of a point."
self._num_ask += 1
return suggestion

def provide_recommendation(self) -> Tuple[float, ...]:
Expand Down
5 changes: 4 additions & 1 deletion nevergrad/optimization/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ def test_sequential_executor() -> None:
np.testing.assert_equal(job1.done(), True)
np.testing.assert_equal(job1.result(), 4)
np.testing.assert_equal(func.count, 1)
executor.submit(func, [3])
job2 = executor.submit(func, [3])
np.testing.assert_equal(job2.done(), True)
np.testing.assert_equal(func.count, 1) # not computed just yet
job2.result()
np.testing.assert_equal(func.count, 2)


Expand Down
21 changes: 14 additions & 7 deletions nevergrad/optimization/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# LICENSE file in the root directory of this source tree.

import operator
from typing import Tuple, Any, Callable, List
from typing import Tuple, Any, Callable, List, Optional
import numpy as np


Expand Down Expand Up @@ -123,17 +123,24 @@ def sample_nash(optimizer: Any) -> Tuple[float, ...]: # Somehow like fictitiou
return nash[index][0]


class FinishedJob:
"""Future-like object with a pre-computed value
class DelayedJob:
"""Future-like object which delays computation
"""

def __init__(self, result: Any) -> None:
self._result = result
def __init__(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
self.func = func
self.args = args
self.kwargs = kwargs
self._result: Optional[Any] = None
self._computed = False

def done(self) -> bool:
return True

def result(self) -> Any:
if not self._computed:
self._result = self.func(*self.args, **self.kwargs)
self._computed = True
return self._result


Expand All @@ -142,5 +149,5 @@ class SequentialExecutor:
(just calls the function and returns a FinishedJob)
"""

def submit(self, function: Callable[..., Any], *args: Any, **kwargs: Any) -> FinishedJob:
return FinishedJob(function(*args, **kwargs))
def submit(self, function: Callable[..., Any], *args: Any, **kwargs: Any) -> DelayedJob:
return DelayedJob(function, *args, **kwargs)

0 comments on commit 0c4469a

Please sign in to comment.