Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions cpp/src/mip_heuristics/diversity/diversity_manager.cu
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,16 @@ diversity_manager_t<i_t, f_t>::diversity_manager_t(mip_solver_context_t<i_t, f_t
context.problem_ptr->handle_ptr),
sub_mip_recombiner(
context, population, context.problem_ptr->n_variables, context.problem_ptr->handle_ptr),
rng(cuopt::seed_generator::get_seed()),
rng(mip_derive_seed(context.base_seed, mip_rng_component_id_t::diversity_manager, 0)),
stats(context.stats),
mab_recombiner(0, cuopt::seed_generator::get_seed(), recombiner_alpha, "recombiner"),
mab_ls(mab_ls_config_t<i_t, f_t>::n_of_arms, cuopt::seed_generator::get_seed(), ls_alpha, "ls"),
mab_recombiner(0,
mip_derive_seed(context.base_seed, mip_rng_component_id_t::diversity_manager, 1),
Comment thread
nguidotti marked this conversation as resolved.
Outdated
recombiner_alpha,
"recombiner"),
mab_ls(mab_ls_config_t<i_t, f_t>::n_of_arms,
mip_derive_seed(context.base_seed, mip_rng_component_id_t::diversity_manager, 2),
ls_alpha,
"ls"),
ls_hash_map(*context.problem_ptr)
{
int max_config = -1;
Expand Down Expand Up @@ -439,7 +445,7 @@ template <typename i_t, typename f_t>
void diversity_manager_t<i_t, f_t>::run_fj_alone(solution_t<i_t, f_t>& solution)
{
CUOPT_LOG_INFO("Running FJ alone!");
solution.round_nearest();
solution.round_nearest(static_cast<int64_t>(rng()));
Comment thread
nguidotti marked this conversation as resolved.
Outdated
ls.fj.settings.mode = fj_mode_t::EXIT_NON_IMPROVING;
ls.fj.settings.n_of_minimums_for_exit = 20000 * 1000;
ls.fj.settings.update_weights = true;
Expand Down Expand Up @@ -693,7 +699,7 @@ solution_t<i_t, f_t> diversity_manager_t<i_t, f_t>::run_solver()
if (ls.lp_optimal_exists) {
solution_t<i_t, f_t> lp_rounded_sol(*problem_ptr);
lp_rounded_sol.copy_new_assignment(lp_optimal_solution);
lp_rounded_sol.round_nearest();
lp_rounded_sol.round_nearest(static_cast<int64_t>(rng()));
Comment thread
nguidotti marked this conversation as resolved.
Outdated
lp_rounded_sol.compute_feasibility();
population.add_solution(std::move(lp_rounded_sol));
ls.start_cpufj_lptopt_scratch_threads(population);
Expand Down
3 changes: 1 addition & 2 deletions cpp/src/mip_heuristics/diversity/population.cu
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <mip_heuristics/utils.cuh>
#include <pdlp/utils.cuh>
#include <utilities/copy_helpers.hpp>
#include <utilities/seed_generator.cuh>

#include <mutex>

Expand Down Expand Up @@ -42,7 +41,7 @@ population_t<i_t, f_t>::population_t(std::string const& name_,
max_solutions(max_solutions_),
infeasibility_importance(infeasibility_weight_),
weights(0, context.problem_ptr->handle_ptr),
rng(cuopt::seed_generator::get_seed()),
rng(mip_derive_seed(context.base_seed, mip_rng_component_id_t::population)),
early_exit_primal_generation(false),
population_hash_map(*problem_ptr),
timer(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

#include <thrust/pair.h>
#include <mip_heuristics/local_search/rounding/constraint_prop.cuh>
#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/relaxed_lp/relaxed_lp.cuh>
#include <mip_heuristics/solution/solution.cuh>
#include <utilities/seed_generator.cuh>
#include <utilities/pcgenerator.hpp>

namespace cuopt::mathematical_optimization::mip {

Expand All @@ -24,9 +25,9 @@ class bound_prop_recombiner_t : public recombiner_t<i_t, f_t> {
i_t n_vars,
constraint_prop_t<i_t, f_t>& constraint_prop_,
const raft::handle_t* handle_ptr)
: recombiner_t<i_t, f_t>(context, n_vars, handle_ptr),
: recombiner_t<i_t, f_t>(
context, n_vars, handle_ptr, mip_rng_component_id_t::recombiner_bound_prop),
constraint_prop(constraint_prop_),
rng(cuopt::seed_generator::get_seed()),
vars_to_fix(n_vars, handle_ptr->get_stream())
{
}
Expand Down Expand Up @@ -65,7 +66,7 @@ class bound_prop_recombiner_t : public recombiner_t<i_t, f_t> {
offspring_view,
int_tol,
probing_values = probing_values.data(),
seed = cuopt::seed_generator::get_seed()] __device__(i_t idx) {
seed = this->rng.next_i64()] __device__(i_t idx) {
f_t guiding_val = guiding_view.assignment[idx];
f_t other_val = other_view.assignment[idx];
cuopt_assert(guiding_view.problem.check_variable_within_bounds(idx, guiding_val), "");
Expand Down Expand Up @@ -151,7 +152,7 @@ class bound_prop_recombiner_t : public recombiner_t<i_t, f_t> {
if (n_different_vars > (i_t)bp_recombiner_config_t::max_n_of_vars_from_other) {
fixed_from_guiding = n_vars_from_other - bp_recombiner_config_t::max_n_of_vars_from_other;
n_vars_from_other = bp_recombiner_config_t::max_n_of_vars_from_other;
thrust::default_random_engine g{(unsigned int)cuopt::seed_generator::get_seed()};
thrust::default_random_engine g{(unsigned int)this->rng.next_i64()};
thrust::shuffle(a.handle_ptr->get_thrust_policy(),
this->remaining_indices.data(),
this->remaining_indices.data() + n_different_vars,
Expand Down Expand Up @@ -245,7 +246,6 @@ class bound_prop_recombiner_t : public recombiner_t<i_t, f_t> {

rmm::device_uvector<i_t> vars_to_fix;
constraint_prop_t<i_t, f_t>& constraint_prop;
thrust::default_random_engine rng;
};

} // namespace cuopt::mathematical_optimization::mip
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

#include <mip_heuristics/local_search/feasibility_pump/feasibility_pump.cuh>
#include <mip_heuristics/local_search/rounding/constraint_prop.cuh>
#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/relaxed_lp/relaxed_lp.cuh>
#include <mip_heuristics/solution/solution.cuh>
#include <utilities/seed_generator.cuh>

#include <thrust/partition.h>

Expand All @@ -29,7 +29,7 @@ class fp_recombiner_t : public recombiner_t<i_t, f_t> {
line_segment_search_t<i_t, f_t>& line_segment_search,
rmm::device_uvector<f_t>& lp_optimal_solution,
const raft::handle_t* handle_ptr)
: recombiner_t<i_t, f_t>(context, n_vars, handle_ptr),
: recombiner_t<i_t, f_t>(context, n_vars, handle_ptr, mip_rng_component_id_t::recombiner_fp),
vars_to_fix(n_vars, handle_ptr->get_stream()),
fp(context, fj, constraint_prop, line_segment_search, lp_optimal_solution)
{
Expand All @@ -53,7 +53,7 @@ class fp_recombiner_t : public recombiner_t<i_t, f_t> {
i_t n_vars_from_other = n_different_vars;
if (n_vars_from_other > (i_t)fp_recombiner_config_t::max_n_of_vars_from_other) {
n_vars_from_other = fp_recombiner_config_t::max_n_of_vars_from_other;
thrust::default_random_engine g{(unsigned int)cuopt::seed_generator::get_seed()};
thrust::default_random_engine g{(unsigned int)this->rng.next_i64()};
thrust::shuffle(a.handle_ptr->get_thrust_policy(),
this->remaining_indices.data(),
this->remaining_indices.data() + n_different_vars,
Expand Down Expand Up @@ -114,7 +114,7 @@ class fp_recombiner_t : public recombiner_t<i_t, f_t> {
}
// unfix the assignment on given result no matter if it is feasible
offspring.unfix_variables(fixed_assignment, variable_map);
if (!run_fp) { offspring.round_nearest(); }
if (!run_fp) { offspring.round_nearest(this->rng.next_i64()); }
cuopt_assert(offspring.test_number_all_integer(), "All must be integers after offspring");
offspring.compute_feasibility();
bool same_as_parents = this->check_if_offspring_is_same_as_parents(offspring, a, b);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
#include "recombiner.cuh"

#include <mip_heuristics/local_search/line_segment_search/line_segment_search.cuh>
#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/relaxed_lp/relaxed_lp.cuh>
#include <mip_heuristics/solution/solution.cuh>
#include <utilities/seed_generator.cuh>

namespace cuopt::mathematical_optimization::mip {

Expand All @@ -23,7 +23,9 @@ class line_segment_recombiner_t : public recombiner_t<i_t, f_t> {
i_t n_vars,
line_segment_search_t<i_t, f_t>& line_segment_search_,
const raft::handle_t* handle_ptr)
: recombiner_t<i_t, f_t>(context, n_vars, handle_ptr), line_segment_search(line_segment_search_)
: recombiner_t<i_t, f_t>(
context, n_vars, handle_ptr, mip_rng_component_id_t::recombiner_line_segment),
line_segment_search(line_segment_search_)
{
}

Expand All @@ -40,7 +42,7 @@ class line_segment_recombiner_t : public recombiner_t<i_t, f_t> {
i_t n_vars_from_other = remaining_variables;
if (n_vars_from_other > (i_t)ls_recombiner_config_t::max_n_of_vars_from_other) {
n_vars_from_other = ls_recombiner_config_t::max_n_of_vars_from_other;
thrust::default_random_engine g{(unsigned int)cuopt::seed_generator::get_seed()};
thrust::default_random_engine g{(unsigned int)this->rng.next_i64()};
Comment thread
nguidotti marked this conversation as resolved.
Outdated
thrust::shuffle(guiding_solution.handle_ptr->get_thrust_policy(),
this->remaining_indices.data(),
this->remaining_indices.data() + remaining_variables,
Expand Down
12 changes: 9 additions & 3 deletions cpp/src/mip_heuristics/diversity/recombiners/recombiner.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
#include "recombiner_configs.hpp"
#include "recombiner_stats.hpp"

#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/solution/solution.cuh>
#include <mip_heuristics/solver.cuh>
#include <mip_heuristics/utils.cuh>
#include <utilities/copy_helpers.hpp>
#include <utilities/device_utils.cuh>
#include <utilities/seed_generator.cuh>
#include <utilities/pcgenerator.hpp>

#include <thrust/random.h>
#include <thrust/set_operations.h>
Expand Down Expand Up @@ -65,8 +66,12 @@ class recombiner_t {
public:
recombiner_t(mip_solver_context_t<i_t, f_t>& context_,
i_t n_integer_vars,
const raft::handle_t* handle_ptr)
const raft::handle_t* handle_ptr,
mip_rng_component_id_t component_id)
: context(context_),
rng(static_cast<uint64_t>(context.base_seed) + cuopt::pcgenerator_t::default_seed +
Comment thread
nguidotti marked this conversation as resolved.
Outdated
static_cast<uint64_t>(component_id),
cuopt::pcgenerator_t::default_stream ^ static_cast<uint64_t>(component_id)),
remaining_indices(n_integer_vars, handle_ptr->get_stream()),
n_remaining(handle_ptr->get_stream())
{
Expand Down Expand Up @@ -119,7 +124,7 @@ class recombiner_t {
objective_indices.size());
if (objective_indices.size() > 0 &&
objective_indices_in_subproblem.size() < 0.4 * remaining_variables) {
std::default_random_engine rng_host(cuopt::seed_generator::get_seed());
std::default_random_engine rng_host(rng.next_i64());
std::vector<i_t> objective_indices_not_in_subproblem;
std::set_difference(objective_indices.begin(),
objective_indices.end(),
Expand Down Expand Up @@ -219,6 +224,7 @@ class recombiner_t {
}

mip_solver_context_t<i_t, f_t>& context;
cuopt::pcgenerator_t rng;
rmm::device_uvector<i_t> remaining_indices;
rmm::device_scalar<i_t> n_remaining;
static std::vector<recombiner_enum_t> enabled_recombiners;
Expand Down
7 changes: 4 additions & 3 deletions cpp/src/mip_heuristics/diversity/recombiners/sub_mip.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class sub_mip_recombiner_t : public recombiner_t<i_t, f_t> {
population_t<i_t, f_t>& population,
i_t n_vars,
const raft::handle_t* handle_ptr)
: recombiner_t<i_t, f_t>(context, n_vars, handle_ptr),
: recombiner_t<i_t, f_t>(
context, n_vars, handle_ptr, mip_rng_component_id_t::recombiner_sub_mip),
vars_to_fix(n_vars, handle_ptr->get_stream()),
context(context),
population(population)
Expand Down Expand Up @@ -57,7 +58,7 @@ class sub_mip_recombiner_t : public recombiner_t<i_t, f_t> {
i_t n_vars_from_other = n_different_vars;
if (n_vars_from_other > (i_t)sub_mip_recombiner_config_t::max_n_of_vars_from_other) {
n_vars_from_other = sub_mip_recombiner_config_t::max_n_of_vars_from_other;
thrust::default_random_engine g{(unsigned int)cuopt::seed_generator::get_seed()};
thrust::default_random_engine g{(unsigned int)this->rng.next_i64()};
Comment thread
nguidotti marked this conversation as resolved.
Outdated
thrust::shuffle(a.handle_ptr->get_thrust_policy(),
this->remaining_indices.data(),
this->remaining_indices.data() + n_different_vars,
Expand Down Expand Up @@ -156,7 +157,7 @@ class sub_mip_recombiner_t : public recombiner_t<i_t, f_t> {
offspring
.clamp_within_bounds(); // Scaling might bring some very slight variable bound violations
} else {
offspring.round_nearest();
offspring.round_nearest(this->rng.next_i64());
}
cuopt_func_call(offspring.test_variable_bounds());
cuopt_assert(offspring.test_number_all_integer(), "All must be integers after offspring");
Expand Down
9 changes: 6 additions & 3 deletions cpp/src/mip_heuristics/feasibility_jump/early_cpufj.cu
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ template <typename i_t, typename f_t>
early_cpufj_t<i_t, f_t>::early_cpufj_t(
const optimization_problem_t<i_t, f_t>& op_problem,
const typename mip_solver_settings_t<i_t, f_t>::tolerances_t& tolerances,
early_incumbent_callback_t<f_t> incumbent_callback)
early_incumbent_callback_t<f_t> incumbent_callback,
int64_t seed)
: early_heuristic_t<i_t, f_t, early_cpufj_t<i_t, f_t>>(
op_problem, tolerances, std::move(incumbent_callback))
op_problem, tolerances, std::move(incumbent_callback)),
seed_(seed)
{
}

Expand All @@ -36,7 +38,8 @@ void early_cpufj_t<i_t, f_t>::start()
this->preemption_flag_.store(false);
this->start_time_ = std::chrono::steady_clock::now();

fj_cpu_ = init_fj_cpu_standalone(*this->problem_ptr_, *this->solution_ptr_, preemption_flag_);
fj_cpu_ =
init_fj_cpu_standalone(*this->problem_ptr_, *this->solution_ptr_, preemption_flag_, seed_);

fj_cpu_->log_prefix = "[Early CPUFJ] ";

Expand Down
6 changes: 5 additions & 1 deletion cpp/src/mip_heuristics/feasibility_jump/early_cpufj.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class early_cpufj_t : public early_heuristic_t<i_t, f_t, early_cpufj_t<i_t, f_t>
public:
early_cpufj_t(const optimization_problem_t<i_t, f_t>& op_problem,
const typename mip_solver_settings_t<i_t, f_t>::tolerances_t& tolerances,
early_incumbent_callback_t<f_t> incumbent_callback);
early_incumbent_callback_t<f_t> incumbent_callback,
int64_t seed);

~early_cpufj_t();

Expand All @@ -32,6 +33,9 @@ class early_cpufj_t : public early_heuristic_t<i_t, f_t, early_cpufj_t<i_t, f_t>
private:
std::unique_ptr<fj_cpu_climber_t<i_t, f_t>> fj_cpu_;
std::atomic<bool> preemption_flag_{false};
// Explicit seed for this climber's FJ RNG, resolved once from the solve's base seed (see
// mip_solver_context_t::base_seed) since this heuristic runs before that context exists.
int64_t seed_;
};

} // namespace cuopt::mathematical_optimization::mip
3 changes: 2 additions & 1 deletion cpp/src/mip_heuristics/feasibility_jump/early_gpufj.cu
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void early_gpufj_t<i_t, f_t>::start()
fj_settings.update_weights = true;
fj_settings.feasibility_run = false;

fj_ptr_ = std::make_unique<fj_t<i_t, f_t>>(*context_ptr_, fj_settings);
fj_ptr_ = std::make_unique<fj_t<i_t, f_t>>(
*context_ptr_, fj_settings, mip_rng_component_id_t::early_gpufj);

fj_ptr_->improvement_callback = [this](f_t user_obj, const std::vector<f_t>& h_assignment) {
f_t solver_obj = this->problem_ptr_->get_solver_obj_from_user_obj(user_obj);
Expand Down
16 changes: 10 additions & 6 deletions cpp/src/mip_heuristics/feasibility_jump/feasibility_jump.cu
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/utils.cuh>
#include <utilities/device_scalar_init.hpp>
#include <utilities/seed_generator.cuh>
#include <utilities/timer.hpp>

#include <raft/linalg/eltwise.cuh>
Expand Down Expand Up @@ -43,8 +42,13 @@ static constexpr int iterations_per_graph = 50;
#endif

template <typename i_t, typename f_t>
fj_t<i_t, f_t>::fj_t(mip_solver_context_t<i_t, f_t>& context_, fj_settings_t in_settings)
fj_t<i_t, f_t>::fj_t(mip_solver_context_t<i_t, f_t>& context_,
fj_settings_t in_settings,
mip_rng_component_id_t seed_component_id)
: context(context_),
rng(static_cast<uint64_t>(context.base_seed) + cuopt::pcgenerator_t::default_seed +
static_cast<uint64_t>(seed_component_id),
cuopt::pcgenerator_t::default_stream ^ static_cast<uint64_t>(seed_component_id)),
pb_ptr(context.problem_ptr),
handle_ptr(const_cast<raft::handle_t*>(pb_ptr->handle_ptr)),
settings(in_settings),
Expand Down Expand Up @@ -135,12 +139,12 @@ void fj_t<i_t, f_t>::reset_weights(const rmm::cuda_stream_view& climber_stream,
template <typename i_t, typename f_t>
void fj_t<i_t, f_t>::randomize_weights(const raft::handle_t* handle_ptr)
{
std::mt19937 rng(cuopt::seed_generator::get_seed());
std::mt19937 host_rng(rng.next_i64());
constexpr f_t min_weight = 10.;
constexpr f_t max_weight = 30.;
// generate a range of weights between 10. and 30.
auto h_cstr_vec =
get_random_uniform_vector<i_t, f_t>(cstr_weights.size(), rng, min_weight, max_weight);
get_random_uniform_vector<i_t, f_t>(cstr_weights.size(), host_rng, min_weight, max_weight);
f_t h_max_weight = *std::max_element(h_cstr_vec.begin(), h_cstr_vec.end());
max_cstr_weight.set_value_async(h_max_weight, handle_ptr->get_stream());
raft::copy(cstr_weights.data(), h_cstr_vec.data(), h_cstr_vec.size(), handle_ptr->get_stream());
Expand Down Expand Up @@ -672,7 +676,7 @@ void fj_t<i_t, f_t>::run_step_device(const rmm::cuda_stream_view& climber_stream

auto& data = *climbers[climber_idx];
auto v = data.view();
settings.seed = cuopt::seed_generator::get_seed();
settings.seed = rng.next_i64();
// ensure an updated copy of the settings is used device-side
raft::copy(v.settings, &settings, 1, climber_stream);

Expand Down Expand Up @@ -1128,7 +1132,7 @@ i_t fj_t<i_t, f_t>::solve(solution_t<i_t, f_t>& solution)

// if time limit exceeded: round all remaining fractionals if any by nearest rounding.
if (climbers[0]->fractional_variables.set_size.value(handle_ptr->get_stream()) > 0) {
solution.round_nearest();
solution.round_nearest(rng.next_i64());
}
}

Expand Down
10 changes: 9 additions & 1 deletion cpp/src/mip_heuristics/feasibility_jump/feasibility_jump.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <cuopt/mathematical_optimization/mip/solver_settings.hpp>
#include <mip_heuristics/diversity/weights.cuh>
#include <mip_heuristics/logger.cuh>
#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/problem/problem.cuh>
#include <mip_heuristics/solution/solution.cuh>
#include <mip_heuristics/solver.cuh>
Expand All @@ -20,6 +21,7 @@
#include <utilities/device_scalar_init.hpp>
#include <utilities/event_handler.cuh>
#include <utilities/manual_cuda_graph.cuh>
#include <utilities/pcgenerator.hpp>

#include <functional>

Expand Down Expand Up @@ -213,7 +215,9 @@ class fj_t {
using move_score_info_t = fj_move_score_info_base_t<f_t>;
using move_candidate_t = fj_move_candidate_t<f_t>;

fj_t(mip_solver_context_t<i_t, f_t>& context, fj_settings_t settings = fj_settings_t{});
fj_t(mip_solver_context_t<i_t, f_t>& context,
fj_settings_t settings = fj_settings_t{},
mip_rng_component_id_t seed_component_id = mip_rng_component_id_t::local_search_cpu_fj);
~fj_t();
void reset_cuda_graph();
i_t solve(solution_t<i_t, f_t>& solution);
Expand Down Expand Up @@ -250,6 +254,10 @@ class fj_t {

public:
mip_solver_context_t<i_t, f_t>& context;
// Persistent RNG seeded once from context.base_seed and this instance's fixed component id,
// used for every seed this fj_t (and the CPU climbers it creates) needs. Never a runtime
// thread id -- see mip_rng_component_id_t.
cuopt::pcgenerator_t rng;
problem_t<i_t, f_t>* pb_ptr;
raft::handle_t* handle_ptr;

Expand Down
Loading
Loading