Commit db8190ff authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

internal: move random distribution into local thread structure

parent 6ff07821
......@@ -215,6 +215,9 @@ solver_finished_cb(const baryonyx::result& r)
r.remaining_constraints,
r.duration);
break;
case baryonyx::result_status::empty_context:
fmt::print("Context uninitialized\n");
break;
}
}
......@@ -1108,6 +1111,9 @@ resume(const baryonyx::result& result, std::ostream& os) noexcept
"\\ remaining constraints.: {}\n",
result.remaining_constraints);
break;
case baryonyx::result_status::empty_context:
fmt::print(os, "context uninitialized\n");
break;
}
}
......
......@@ -162,7 +162,8 @@ enum class file_format_error_tag
bad_constraint,
too_many_variables,
too_many_constraints,
bad_name // Mainly use when read result file and report unknown variable.
bad_name, // Mainly use when read result file and report unknown variable.
empty_context
};
struct file_format_error
......@@ -691,7 +692,8 @@ enum class result_status
uninitialized,
time_limit_reached,
kappa_max_reached,
limit_reached
limit_reached,
empty_context
};
struct solution
......@@ -745,9 +747,11 @@ struct result
using solver_started_cb = std::function<void(const solver_parameters& params)>;
/// Function called for each solution improvement.
using solver_updated_cb = std::function<
void(int remaining_constraints, double value, long int loop, double duration,
long int reinit_number)>;
using solver_updated_cb = std::function<void(int remaining_constraints,
double value,
long int loop,
double duration,
long int reinit_number)>;
/// finish Function called at the end of the computation.
using solver_finished_cb = std::function<void(const result& r)>;
......
......@@ -79,6 +79,9 @@ struct fmt::formatter<baryonyx::file_format_error_tag>
case baryonyx::file_format_error_tag::bad_name:
name = "bad_name";
break;
case baryonyx::file_format_error_tag::empty_context:
name = "empty_context";
break;
}
return formatter<string_view>::format(name, ctx);
......@@ -143,6 +146,9 @@ struct fmt::formatter<baryonyx::result_status> : fmt::formatter<string_view>
case baryonyx::result_status::limit_reached:
name = "limit_reached";
break;
case baryonyx::result_status::empty_context:
name = "empty_context";
break;
}
return formatter<string_view>::format(name, ctx);
......
......@@ -59,7 +59,7 @@ is_best(const baryonyx::result& lhs,
}
static bool
is_best(const baryonyx::context_ptr& ctx,
is_best(const baryonyx::context& ctx,
const baryonyx::result& current,
const baryonyx::result& best,
baryonyx::objective_function_type type)
......@@ -136,19 +136,15 @@ struct node_result_compare
using problem_set = std::multiset<node, node_result_compare>;
static baryonyx::result
optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
optimize(const baryonyx::context& ctx, const baryonyx::problem& pb)
{
// NOTE 1 - add a solver parameter to limit the size of the list.
baryonyx::context internal_ctx(ctx);
internal_ctx.log_priority = baryonyx::context::message_type::warning;
auto old_log_priority = ctx->log_priority;
#ifndef BARYONYX_ENABLE_DEBUG
ctx->log_priority = baryonyx::context::message_type::notice;
#endif
auto best = baryonyx::itm::optimize(ctx, pb);
auto best = baryonyx::itm::optimize(internal_ctx, pb);
if (best)
baryonyx::notice(ctx,
baryonyx::notice(internal_ctx,
" - branch optimization found solution {:f}\n",
best.solutions.front().value);
......@@ -163,15 +159,16 @@ optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
do {
auto it = jobs.begin();
baryonyx::notice(ctx,
baryonyx::notice(internal_ctx,
" - branch-optimization splits on {} (id: {})\n",
it->problem.vars.names[it->annoying_variable],
it->annoying_variable);
auto sp = baryonyx::split(ctx, it->problem, annoying_variable);
auto sp =
baryonyx::split(internal_ctx, it->problem, annoying_variable);
auto ret0 = baryonyx::itm::optimize(ctx, std::get<0>(sp));
if (is_best(ctx, ret0, best, it->problem.type))
auto ret0 = baryonyx::itm::optimize(internal_ctx, std::get<0>(sp));
if (is_best(internal_ctx, ret0, best, it->problem.type))
best = ret0;
jobs.emplace(std::get<0>(sp),
......@@ -179,8 +176,8 @@ optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
ret0.remaining_constraints,
ret0.annoying_variable);
auto ret1 = baryonyx::itm::optimize(ctx, std::get<1>(sp));
if (is_best(ctx, ret1, best, it->problem.type))
auto ret1 = baryonyx::itm::optimize(internal_ctx, std::get<1>(sp));
if (is_best(internal_ctx, ret1, best, it->problem.type))
best = ret1;
jobs.emplace(std::get<1>(sp),
......@@ -190,11 +187,11 @@ optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
jobs.erase(it);
baryonyx::notice(ctx, " Jobs lists:\n");
baryonyx::notice(internal_ctx, " Jobs lists:\n");
for (const auto& elem : jobs) {
if (elem.remaining_constraints == 0)
baryonyx::notice(
ctx,
internal_ctx,
" * solution: {} annoying: {} vars: {}/{}\n",
elem.solution,
elem.annoying_variable,
......@@ -203,7 +200,7 @@ optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
elem.problem.vars.values.size());
else
baryonyx::notice(
ctx,
internal_ctx,
" * remaining: {} annoying: {} vars: {}/{}\n",
elem.remaining_constraints,
elem.annoying_variable,
......@@ -214,8 +211,6 @@ optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
} while (!jobs.empty());
ctx->log_priority = old_log_priority;
return best;
}
......@@ -223,10 +218,9 @@ namespace baryonyx {
namespace itm {
result
branch_optimize(const baryonyx::context_ptr& ctx, const baryonyx::problem& pb)
branch_optimize(const baryonyx::context& ctx, const baryonyx::problem& pb)
{
baryonyx::notice(ctx, "- branch-optimization starts\n");
return ::optimize(ctx, pb);
}
......
......@@ -45,10 +45,12 @@
#include <fmt/ostream.h>
namespace baryonyx {
namespace itm {
// We statically define this PRNG for all subsystems in Baryonyx.
using random_engine = std::default_random_engine;
namespace itm {
struct maximize_tag
{};
......@@ -74,7 +76,7 @@ struct merged_constraint
};
std::vector<merged_constraint>
make_merged_constraints(const context_ptr& ctx, const problem& pb);
make_merged_constraints(const context& ctx, const problem& pb);
template<typename Solver, typename Xtype>
bool
......@@ -549,7 +551,7 @@ struct bounds_printer
return { 0 };
}
void print_bound(const context_ptr& ctx,
void print_bound(const context& ctx,
floatingpointT lower_bound,
floatingpointT upper_bound,
minimize_tag)
......@@ -574,7 +576,7 @@ struct bounds_printer
}
}
void print_bound(const context_ptr& ctx,
void print_bound(const context& ctx,
floatingpointT lower_bound,
floatingpointT upper_bound,
maximize_tag)
......@@ -610,9 +612,7 @@ struct bounds_printer
}
template<typename SolverT>
void operator()(const SolverT& slv,
const context_ptr& ctx,
const result& best)
void operator()(const SolverT& slv, const context& ctx, const result& best)
{
floatingpointT lb = init_bound(slv);
floatingpointT ub = init_ub(modeT());
......@@ -921,7 +921,7 @@ struct compute_order
template<typename Float, typename Cost>
inline Float
compute_delta(const context_ptr& ctx, const Cost& c, Float theta, int n)
compute_delta(const context& ctx, const Cost& c, Float theta, int n)
{
info(ctx, " - delta not defined, compute it:\n");
......@@ -971,14 +971,11 @@ random_epsilon_unique(iteratorT begin,
*/
template<typename floatingpointT, typename Cost>
inline Cost
normalize_costs(const context_ptr& ctx,
const Cost& c,
random_engine& rng,
int n)
normalize_costs(const context& ctx, const Cost& c, random_engine& rng, int n)
{
Cost ret(c, n);
switch (ctx->parameters.cost_norm) {
switch (ctx.parameters.cost_norm) {
case solver_parameters::cost_norm_type::none:
info(ctx, " - No norm");
return ret;
......@@ -1448,10 +1445,10 @@ struct quadratic_cost_type
};
inline random_engine::result_type
init_random_generator_seed(const context_ptr& ctx) noexcept
init_random_generator_seed(const context& ctx) noexcept
{
auto epoch = std::chrono::system_clock::now().time_since_epoch().count();
auto param = ctx->parameters.seed;
auto param = ctx.parameters.seed;
if (param <= 0)
return static_cast<random_engine::result_type>(epoch);
......
This diff is collapsed.
......@@ -50,12 +50,12 @@ struct solver_functor
std::chrono::time_point<std::chrono::steady_clock> m_begin;
std::chrono::time_point<std::chrono::steady_clock> m_end;
const context_ptr& m_ctx;
const context& m_ctx;
random_engine& m_rng;
raw_result<Mode> m_best;
solver_functor(const context_ptr& ctx, random_engine& rng)
solver_functor(const context& ctx, random_engine& rng)
: m_ctx(ctx)
, m_rng(rng)
{}
......@@ -71,7 +71,7 @@ struct solver_functor
int best_remaining = INT_MAX;
auto& p = m_ctx->parameters;
auto& p = m_ctx.parameters;
auto norm_costs = normalize_costs<Float, Cost>(
m_ctx, original_costs, m_rng, variables);
......@@ -91,18 +91,6 @@ struct solver_functor
const long int w_limit = static_cast<long int>(p.w);
if (p.limit <= 0)
p.limit = std::numeric_limits<long int>::max();
if (p.time_limit <= 0)
p.time_limit = std::numeric_limits<double>::infinity();
if (p.pushes_limit <= 0)
p.pushes_limit = 0;
if (p.pushing_iteration_limit <= 0)
p.pushes_limit = 0;
Solver slv(
m_rng, length(constraints), variables, norm_costs, constraints);
......@@ -110,7 +98,7 @@ struct solver_functor
{
std::bernoulli_distribution choose_mutation(
m_ctx->parameters.init_policy_random);
m_ctx.parameters.init_policy_random);
bit_array empty_x;
switch (p.init_policy) {
......@@ -241,7 +229,7 @@ private:
{
m_end = std::chrono::steady_clock::now();
return is_time_limit(m_ctx->parameters.time_limit, m_begin, m_end);
return is_time_limit(m_ctx.parameters.time_limit, m_begin, m_end);
}
double duration()
......@@ -275,10 +263,10 @@ private:
template<typename Solver, typename Float, typename Mode, typename Cost>
inline result
solve_problem(const context_ptr& ctx, const problem& pb)
solve_problem(const context& ctx, const problem& pb)
{
if (ctx->start)
ctx->start(ctx->parameters);
if (ctx.start)
ctx.start(ctx.parameters);
result ret;
......@@ -291,7 +279,7 @@ solve_problem(const context_ptr& ctx, const problem& pb)
auto cost = Cost(pb.objective, variables);
auto cost_constant = pb.objective.value;
switch (ctx->parameters.observer) {
switch (ctx.parameters.observer) {
case solver_parameters::observer_type::pnm: {
using obs = pnm_observer;
......@@ -322,8 +310,8 @@ solve_problem(const context_ptr& ctx, const problem& pb)
ret.variables = variables;
ret.constraints = length(constraints);
if (ctx->finish)
ctx->finish(ret);
if (ctx.finish)
ctx.finish(ret);
return ret;
}
......
......@@ -272,11 +272,9 @@ struct solver_equalities_01coeff : debug_logger<debug>
template<typename Float, typename Mode, typename Cost>
static result
solve_or_optimize(const context_ptr& ctx,
const problem& pb,
bool is_optimization)
solve_or_optimize(const context& ctx, const problem& pb, bool is_optimization)
{
if (ctx->parameters.debug) {
if (ctx.parameters.debug) {
using Solver = solver_equalities_01coeff<Float, Mode, Cost, true>;
return is_optimization
......@@ -293,7 +291,7 @@ solve_or_optimize(const context_ptr& ctx,
template<typename Float, typename Mode>
static result
select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_cost(const context& ctx, const problem& pb, bool is_optimization)
{
return pb.objective.qelements.empty()
? solve_or_optimize<Float,
......@@ -308,7 +306,7 @@ select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
template<typename Float>
static result
select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_mode(const context& ctx, const problem& pb, bool is_optimization)
{
const auto m = static_cast<int>(pb.type);
......@@ -317,9 +315,9 @@ select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
static result
select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_float(const context& ctx, const problem& pb, bool is_optimization)
{
const auto f = static_cast<int>(ctx->parameters.float_type);
const auto f = static_cast<int>(ctx.parameters.float_type);
if (f == 0)
return select_mode<float_sel<0>>(ctx, pb, is_optimization);
......@@ -330,14 +328,14 @@ select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
result
solve_equalities_01(const context_ptr& ctx, const problem& pb)
solve_equalities_01(const context& ctx, const problem& pb)
{
info(ctx, " - solve_equalities_01\n");
return select_float(ctx, pb, false);
}
result
optimize_equalities_01(const context_ptr& ctx, const problem& pb)
optimize_equalities_01(const context& ctx, const problem& pb)
{
info(ctx, " - optimize_equalities_01\n");
return select_float(ctx, pb, true);
......
......@@ -309,11 +309,9 @@ struct solver_equalities_101coeff : debug_logger<debug>
template<typename Float, typename Mode, typename Cost>
static result
solve_or_optimize(const context_ptr& ctx,
const problem& pb,
bool is_optimization)
solve_or_optimize(const context& ctx, const problem& pb, bool is_optimization)
{
if (ctx->parameters.debug) {
if (ctx.parameters.debug) {
using Solver = solver_equalities_101coeff<Float, Mode, Cost, true>;
return is_optimization
......@@ -330,7 +328,7 @@ solve_or_optimize(const context_ptr& ctx,
template<typename Float, typename Mode>
static result
select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_cost(const context& ctx, const problem& pb, bool is_optimization)
{
return pb.objective.qelements.empty()
? solve_or_optimize<Float,
......@@ -345,7 +343,7 @@ select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
template<typename Float>
static result
select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_mode(const context& ctx, const problem& pb, bool is_optimization)
{
const auto m = static_cast<int>(pb.type);
......@@ -354,9 +352,9 @@ select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
static result
select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_float(const context& ctx, const problem& pb, bool is_optimization)
{
const auto f = static_cast<int>(ctx->parameters.float_type);
const auto f = static_cast<int>(ctx.parameters.float_type);
if (f == 0)
return select_mode<float_sel<0>>(ctx, pb, is_optimization);
......@@ -367,14 +365,14 @@ select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
result
solve_equalities_101(const context_ptr& ctx, const problem& pb)
solve_equalities_101(const context& ctx, const problem& pb)
{
info(ctx, " - solve_equalities_101\n");
return select_float(ctx, pb, false);
}
result
optimize_equalities_101(const context_ptr& ctx, const problem& pb)
optimize_equalities_101(const context& ctx, const problem& pb)
{
info(ctx, " - solve_equalities_101\n");
return select_float(ctx, pb, true);
......
......@@ -298,11 +298,9 @@ struct solver_inequalities_01coeff : debug_logger<debug>
template<typename Float, typename Mode, typename Cost>
static result
solve_or_optimize(const context_ptr& ctx,
const problem& pb,
bool is_optimization)
solve_or_optimize(const context& ctx, const problem& pb, bool is_optimization)
{
if (ctx->parameters.debug) {
if (ctx.parameters.debug) {
using Solver = solver_inequalities_01coeff<Float, Mode, Cost, true>;
return is_optimization
......@@ -319,7 +317,7 @@ solve_or_optimize(const context_ptr& ctx,
template<typename Float, typename Mode>
static result
select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_cost(const context& ctx, const problem& pb, bool is_optimization)
{
return pb.objective.qelements.empty()
? solve_or_optimize<Float,
......@@ -334,7 +332,7 @@ select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
template<typename Float>
static result
select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_mode(const context& ctx, const problem& pb, bool is_optimization)
{
const auto m = static_cast<int>(pb.type);
......@@ -343,9 +341,9 @@ select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
static result
select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_float(const context& ctx, const problem& pb, bool is_optimization)
{
const auto f = static_cast<int>(ctx->parameters.float_type);
const auto f = static_cast<int>(ctx.parameters.float_type);
if (f == 0)
return select_mode<float_sel<0>>(ctx, pb, is_optimization);
......@@ -356,14 +354,14 @@ select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
result
solve_inequalities_01(const context_ptr& ctx, const problem& pb)
solve_inequalities_01(const context& ctx, const problem& pb)
{
info(ctx, " - solve_inequalities_01\n");
return select_float(ctx, pb, false);
}
result
optimize_inequalities_01(const context_ptr& ctx, const problem& pb)
optimize_inequalities_01(const context& ctx, const problem& pb)
{
info(ctx, " - optimize_inequalities_01\n");
return select_float(ctx, pb, true);
......
......@@ -378,11 +378,9 @@ struct solver_inequalities_101coeff_buffered : debug_logger<debug>
template<typename Float, typename Mode, typename Cost>
static result
solve_or_optimize(const context_ptr& ctx,
const problem& pb,
bool is_optimization)
solve_or_optimize(const context& ctx, const problem& pb, bool is_optimization)
{
if (ctx->parameters.debug) {
if (ctx.parameters.debug) {
using Solver =
solver_inequalities_101coeff_buffered<Float, Mode, Cost, true>;
......@@ -401,7 +399,7 @@ solve_or_optimize(const context_ptr& ctx,
template<typename Float, typename Mode>
static result
select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_cost(const context& ctx, const problem& pb, bool is_optimization)
{
return pb.objective.qelements.empty()
? solve_or_optimize<Float,
......@@ -416,7 +414,7 @@ select_cost(const context_ptr& ctx, const problem& pb, bool is_optimization)
template<typename Float>
static result
select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_mode(const context& ctx, const problem& pb, bool is_optimization)
{
const auto m = static_cast<int>(pb.type);
......@@ -425,9 +423,9 @@ select_mode(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
static result
select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
select_float(const context& ctx, const problem& pb, bool is_optimization)
{
const auto f = static_cast<int>(ctx->parameters.float_type);
const auto f = static_cast<int>(ctx.parameters.float_type);
if (f == 0)
return select_mode<float_sel<0>>(ctx, pb, is_optimization);
......@@ -438,14 +436,14 @@ select_float(const context_ptr& ctx, const problem& pb, bool is_optimization)
}
result
solve_inequalities_101_buffered(const context_ptr& ctx, const problem& pb)
solve_inequalities_101_buffered(const context& ctx, const problem& pb)
{
info(ctx, " - solve_inequalities_101_buffered\n");
return select_float(ctx, pb, false);
}
result
optimize_inequalities_101_buffered(const context_ptr& ctx, const problem& pb)
optimize_inequalities_101_buffered(const context& ctx, const problem& pb)
{
info(ctx, " - optimize_inequalities_101_buffered\n");
return select_float(ctx, pb, true);
......
......@@ -349,11 +349,9 @@ struct solver_inequalities_101coeff : debug_logger<debug>
template<typename Float, typename Mode, typename Cost>
static result
solve_or_optimize(const context_ptr& ctx,
const problem& pb,