Skip to content

Commit

Permalink
Merge pull request #272 from jakobj/fix/fec-cache-key
Browse files Browse the repository at this point in the history
Also use all args and kwargs when computing fec cache key
  • Loading branch information
HenrikMettler committed Jan 6, 2021
2 parents adc6ac2 + b283853 commit b6d7942
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
10 changes: 6 additions & 4 deletions cgp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ def __compute_key_from_args(*args: Any, **kwargs: Any) -> str:
return hashlib.sha1(s.encode("utf-8")).hexdigest()


def __compute_key_from_evaluation(
seed: int, min_value: float, max_value: float, batch_size: int, *args: Any
def __compute_key_from_evaluation_and_args(
seed: int, min_value: float, max_value: float, batch_size: int, *args: Any, **kwargs: Any
) -> str:
"""Compute a key for the function encoded in an individual by
evaluating it's NumPy expression on random input samples and
Expand Down Expand Up @@ -96,6 +96,8 @@ def __compute_key_from_evaluation(
else:
assert False # should never be reached

s += str(args[1:]) + str(kwargs)

return hashlib.sha1(s.encode("utf-8")).hexdigest()


Expand Down Expand Up @@ -222,8 +224,8 @@ def wrapper(*args: Any, **kwargs: Any) -> Union[float, None]:

key: str
if use_fec:
key = __compute_key_from_evaluation(
fec_seed, fec_min_value, fec_max_value, fec_batch_size, *args
key = __compute_key_from_evaluation_and_args(
fec_seed, fec_min_value, fec_max_value, fec_batch_size, *args, **kwargs
)
else:
key = __compute_key_from_args(*args, **kwargs)
Expand Down
27 changes: 27 additions & 0 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,30 @@ def test_primitives_from_class_names_for_genome(genome_params):
genome_params["primitives"] = primitives

cgp.Genome(**genome_params)


def test_fec_cache_decorator_with_additional_arguments(genome_params, rng, rng_seed):
def f_target(x):
return x[0] - x[1]

@cgp.utils.disk_cache(tempfile.mkstemp()[1], use_fec=True, fec_seed=rng_seed)
def inner_objective(ind, n_samples):
np.random.seed(rng_seed)

f = ind.to_func()

loss = 0
for x in np.random.uniform(size=(n_samples, 2)):
loss += (f_target(x) - f(x)[0]) ** 2
return loss

g = cgp.Genome(**genome_params)
g.randomize(rng)
ind = cgp.IndividualSingleGenome(g)

# call with 5 and 10 samples, results should be different since
# the second call should *not* return the cached value
y0 = inner_objective(ind, 5)
y1 = inner_objective(ind, 10)

assert y0 != pytest.approx(y1)

0 comments on commit b6d7942

Please sign in to comment.