Ultra 0.9.4
Loading...
Searching...
No Matches
evaluator_proxy.tcc
Go to the documentation of this file.
1
12
13#if !defined(ULTRA_EVALUATOR_PROXY_H)
14# error "Don't include this file directly, include the specific .h instead"
15#endif
16
17#if !defined(ULTRA_EVALUATOR_PROXY_TCC)
18#define ULTRA_EVALUATOR_PROXY_TCC
19
27template<Evaluator E>
28evaluator_proxy<E>::evaluator_proxy(E eva, bitwidth ts) : eva_(std::move(eva)),
29 cache_(ts)
30{
31 static_assert(!std::derived_from<E, evaluator_proxy>);
32
33 if (!ts)
34 ultraWARNING("Evaluator proxy cache is disabled");
35}
36
47template<Evaluator E>
48evaluator_fitness_t<E> evaluator_proxy<E>::operator()(
49 const evaluator_individual_t<E> &prg) const
50{
51 if (!cache_.bits())
52 return eva_(prg);
53
54 if (const auto cached_fit(cache_.find(prg.signature())); cached_fit)
55 {
56 // Hash collision checking code can severely slow down the program.
57#if !defined(NDEBUG)
58 const auto effective_fit(eva_(prg));
59
60 if (!almost_equal(*cached_fit, effective_fit)) [[unlikely]]
61 {
62 ultraERROR("COLLISION [{} != {}]",
63 internal::streamed(*cached_fit),
64 internal::streamed(effective_fit));
65 return effective_fit;
66 }
67
68 // The above comparison may produce false positives.
69 // E.g. it fails if a component of the fitness is function of the program's
70 // length.
71 // For example if the fitness is a 2D vector (where the first component
72 // is the "score" on the training set and the second one is the effective
73 // length of the program), then the following two programs:
74 //
75 // PROGRAM A PROGRAM B
76 // ------------------ ------------------
77 // [000] FADD 3 3 [000] FADD 3 3
78 // [001] FADD 3 3 [001] FADD [000] [000]
79 // [002] FADD [000] [001]
80 //
81 // have the same signature, the same stored "score" but distinct
82 // effective size and so distinct fitnesses.
83#endif
84
85 return *cached_fit;
86 }
87
88 // Not found in cache.
89 const auto effective_fit(eva_(prg));
90 cache_.insert(prg.signature(), effective_fit);
91
92 return effective_fit;
93}
94
104template<Evaluator E>
105evaluator_fitness_t<E> evaluator_proxy<E>::fast(
106 const evaluator_individual_t<E> &prg) const
107{
108 if constexpr (requires { eva_.fast(prg); })
109 return eva_.fast(prg);
110
111 return operator()(prg);
112}
113
124template<Evaluator E>
125bool evaluator_proxy<E>::load_cache(std::istream &in) const
126{
127 return cache_.load(in);
128}
129
142template<Evaluator E>
143bool evaluator_proxy<E>::load(std::istream &in)
144{
145 return load_eva(in, &eva_) && load_cache(in);
146}
147
151// \param[out] out output stream
154template<Evaluator E>
155bool evaluator_proxy<E>::save_cache(std::ostream &out) const
156{
157 return cache_.save(out);
158}
159
170template<Evaluator E>
171bool evaluator_proxy<E>::save(std::ostream &out) const
172{
173 return save_eva(out, eva_) && save_cache(out);
174}
175
182template<Evaluator E>
183void evaluator_proxy<E>::clear() const noexcept
184{
185 cache_.clear();
186}
187
194template<Evaluator E>
195void evaluator_proxy<E>::clear(const hash_t &h) const
196{
197 cache_.clear(h);
198}
199
212template<Evaluator E>
213bool evaluator_proxy<E>::set_parallel_evaluation(unsigned helpers,
214 std::size_t min_samples)
215{
216 if constexpr (requires {eva_.set_parallel_evaluation(helpers, min_samples);})
217 return eva_.set_parallel_evaluation(helpers, min_samples);
218
219 return false;
220}
221
227template<Evaluator E>
228const E &evaluator_proxy<E>::core() const noexcept
229{
230 return eva_;
231}
232
233#endif // include guard
bool save_eva(std::ostream &out, const E &e)
Definition evaluator.tcc:121
bool load_eva(std::istream &in, E *e)
Definition evaluator.tcc:93
STL namespace.