Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge classical and by batch benders #738

Merged
merged 25 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
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
6 changes: 3 additions & 3 deletions src/cpp/benders/benders_by_batch/BendersByBatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ void BendersByBatch::InitializeProblems() {
MatchProblemToId();

BuildMasterProblem();
const auto &coupling_map_size = coupling_map.size();
const auto &coupling_map_size = coupling_map_.size();
std::vector<std::string> problem_names;
for (const auto &[problem_name, _] : coupling_map) {
for (const auto &[problem_name, _] : coupling_map_) {
problem_names.emplace_back(problem_name);
}
auto batch_size =
Expand All @@ -39,7 +39,7 @@ void BendersByBatch::InitializeProblems() {
Rank()) { // Assign [problemNumber % WorldSize] to processID

const auto subProblemFilePath = GetSubproblemPath(problem_name);
AddSubproblem({problem_name, coupling_map[problem_name]});
AddSubproblem({problem_name, coupling_map_[problem_name]});
AddSubproblemName(problem_name);
}
problem_count++;
Expand Down
39 changes: 9 additions & 30 deletions src/cpp/benders/benders_core/BendersBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,31 +660,21 @@ void BendersBase::set_solver_log_file(const std::filesystem::path &log_file) {
}

/*!
* \brief Build the input from the structure file
* \brief set the input
*
* Function to build the map linking each problem name to its variables and
*their id
*
* \param root : root of the structure file
*
* \param summary_name : name of the structure file
*
* \param coupling_map : empty map to increment
*
* \note The id in the coupling_map is that of the variable in the solver
*responsible for the creation of the structure file.
* \param coupling_map : CouplingMap
*/
void BendersBase::build_input_map() {
auto input = build_input(get_structure_path());
_totalNbProblems = input.size();
void BendersBase::set_input_map(const CouplingMap &coupling_map) {
coupling_map_ = coupling_map;
_totalNbProblems = coupling_map_.size();
_writer->write_nbweeks(_totalNbProblems);
_data.nsubproblem = _totalNbProblems - 1;
master_variable_map = get_master_variable_map(input);
coupling_map = GetCouplingMap(input);
master_variable_map_ = get_master_variable_map(coupling_map_);
coupling_map_.erase(get_master_name());
}

std::map<std::string, int> BendersBase::get_master_variable_map(
std::map<std::string, std::map<std::string, int>> input_map) const {
const std::map<std::string, std::map<std::string, int>> &input_map) const {
auto const it_master(input_map.find(get_master_name()));
if (it_master == input_map.end()) {
_logger->display_message(LOGLOCATION + "UNABLE TO FIND " +
Expand All @@ -694,17 +684,6 @@ std::map<std::string, int> BendersBase::get_master_variable_map(
return it_master->second;
}

CouplingMap BendersBase::GetCouplingMap(CouplingMap input) const {
CouplingMap couplingMap;
auto master_name = get_master_name();
std::copy_if(input.begin(), input.end(),
std::inserter(couplingMap, couplingMap.end()),
[master_name](const CouplingMap::value_type &kvp) {
return kvp.first != master_name;
});
return couplingMap;
}

void BendersBase::reset_master(WorkerMaster *worker_master) {
_master.reset(worker_master);
}
Expand All @@ -724,7 +703,7 @@ void BendersBase::free_subproblems() {
}
void BendersBase::MatchProblemToId() {
int count = 0;
for (const auto &problem : coupling_map) {
for (const auto &problem : coupling_map_) {
_problem_to_id[problem.first] = count;
count++;
}
Expand Down
9 changes: 4 additions & 5 deletions src/cpp/benders/benders_core/include/BendersBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ class BendersBase {
}
double execution_time() const;
virtual std::string BendersName() const = 0;
void set_input_map(const CouplingMap &coupling_map);

protected:
CurrentIterationData _data;
VariableMap master_variable_map;
CouplingMap coupling_map;
VariableMap master_variable_map_;
CouplingMap coupling_map_;

protected:
virtual void free() = 0;
Expand Down Expand Up @@ -72,7 +73,6 @@ class BendersBase {
[[nodiscard]] std::filesystem::path get_structure_path() const;
[[nodiscard]] LogData bendersDataToLogData(
const CurrentIterationData &data) const;
virtual void build_input_map();
virtual void reset_master(WorkerMaster *worker_master);
void free_master() const;
void free_subproblems();
Expand Down Expand Up @@ -152,8 +152,7 @@ class BendersBase {
void compute_cut_aggregate(const SubProblemDataMap &subproblem_data_map);
void compute_cut(const SubProblemDataMap &subproblem_data_map);
[[nodiscard]] std::map<std::string, int> get_master_variable_map(
std::map<std::string, std::map<std::string, int>> input_map) const;
[[nodiscard]] CouplingMap GetCouplingMap(CouplingMap input) const;
const std::map<std::string, std::map<std::string, int>> &input_map) const;
[[nodiscard]] virtual bool shouldParallelize() const = 0;
Output::Iteration iteration(const WorkerMasterDataPtr &masterDataPtr_l) const;
LogData FinalLogData() const;
Expand Down
7 changes: 2 additions & 5 deletions src/cpp/benders/benders_mpi/BendersMPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void BendersMpi::InitializeProblems() {
BuildMasterProblem();
int current_problem_id = 0;
// Dispatch subproblems to process
for (const auto &problem : coupling_map) {
for (const auto &problem : coupling_map_) {
// In case there are more subproblems than process
if (auto process_to_feed = current_problem_id % _world.size();
process_to_feed ==
Expand All @@ -42,7 +42,7 @@ void BendersMpi::InitializeProblems() {
}
void BendersMpi::BuildMasterProblem() {
if (_world.rank() == rank_0) {
reset_master(new WorkerMaster(master_variable_map, get_master_path(),
reset_master(new WorkerMaster(master_variable_map_, get_master_path(),
get_solver_name(), get_log_level(),
_data.nsubproblem, solver_log_manager_,
IsResumeMode(), _logger));
Expand Down Expand Up @@ -276,9 +276,6 @@ void BendersMpi::PreRunInitialization() {
}
}
void BendersMpi::launch() {
build_input_map();
_world.barrier();

InitializeProblems();
_world.barrier();

Expand Down
6 changes: 2 additions & 4 deletions src/cpp/benders/benders_sequential/BendersSequential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ BendersSequential::BendersSequential(BendersBaseOptions const &options,
void BendersSequential::InitializeProblems() {
MatchProblemToId();

reset_master(new WorkerMaster(master_variable_map, get_master_path(),
reset_master(new WorkerMaster(master_variable_map_, get_master_path(),
get_solver_name(), get_log_level(),
_data.nsubproblem, solver_log_manager_,
IsResumeMode(), _logger));
for (const auto &problem : coupling_map) {
for (const auto &problem : coupling_map_) {
const auto subProblemFilePath = GetSubproblemPath(problem.first);

AddSubproblem(problem);
Expand Down Expand Up @@ -125,8 +125,6 @@ void BendersSequential::Run() {
}

void BendersSequential::launch() {
build_input_map();

LOG(INFO) << "Building input" << std::endl;

LOG(INFO) << "Constructing workers..." << std::endl;
Expand Down
34 changes: 15 additions & 19 deletions src/cpp/benders/factories/BendersFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
#include "glog/logging.h"

int RunBenders(char** argv, const std::filesystem::path& options_file,
mpi::environment& env, mpi::communicator& world,
const BENDERSMETHOD& method) {
mpi::environment& env, mpi::communicator& world) {
// Read options, needed to have options.OUTPUTROOT
Logger logger;

Expand All @@ -35,7 +34,11 @@ int RunBenders(char** argv, const std::filesystem::path& options_file,
std::filesystem::path(options.OUTPUTROOT) / "reportbenders.txt";

Writer writer;

const auto couplig_map = build_input(benders_options.STRUCTURE_FILE);
const auto method = (options.BATCH_SIZE == 0 ||
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
options.BATCH_SIZE == couplig_map.size() - 1)
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
? BENDERSMETHOD::BENDERS
: BENDERSMETHOD::BENDERSBYBATCH;
if (world.rank() == 0) {
auto logger_factory = FileAndStdoutLoggerFactory(log_reports_name);

Expand All @@ -49,18 +52,16 @@ int RunBenders(char** argv, const std::filesystem::path& options_file,
writer = build_void_writer();
}

world.barrier();
pBendersBase benders;
if (method == BENDERSMETHOD::BENDERS) {
benders = std::make_shared<BendersMpi>(benders_options, logger, writer,
env, world);
} else if (method == BENDERSMETHOD::BENDERSBYBATCH) {
} else {
a-zakir marked this conversation as resolved.
Show resolved Hide resolved
benders = std::make_shared<BendersByBatch>(benders_options, logger,
writer, env, world);
} else {
auto err_msg = "Error only benders or benders-by-batch allowed!";
logger->display_message(err_msg);
std::exit(1);
}
benders->set_input_map(couplig_map);
std::ostringstream oss_l = start_message(options, benders->BendersName());
oss_l << std::endl;
logger->display_message(oss_l.str());
Expand Down Expand Up @@ -96,10 +97,10 @@ int RunBenders(char** argv, const std::filesystem::path& options_file,
}

BendersMainFactory::BendersMainFactory(int argc, char** argv,
const BENDERSMETHOD& method,

mpi::environment& env,
mpi::communicator& world)
: argv_(argv), method_(method), penv_(&env), pworld_(&world) {
: argv_(argv), penv_(&env), pworld_(&world) {
// First check usage (options are given)
if (world.rank() == 0) {
usage(argc);
Expand All @@ -108,19 +109,14 @@ BendersMainFactory::BendersMainFactory(int argc, char** argv,
options_file_ = std::filesystem::path(argv_[1]);
}
BendersMainFactory::BendersMainFactory(
int argc, char** argv, const BENDERSMETHOD& method,
const std::filesystem::path& options_file, mpi::environment& env,
mpi::communicator& world)
: argv_(argv),
method_(method),
options_file_(options_file),
penv_(&env),
pworld_(&world) {
int argc, char** argv, const std::filesystem::path& options_file,
mpi::environment& env, mpi::communicator& world)
: argv_(argv), options_file_(options_file), penv_(&env), pworld_(&world) {
// First check usage (options are given)
if (world.rank() == 0) {
usage(argc);
}
}
int BendersMainFactory::Run() const {
return RunBenders(argv_, options_file_, *penv_, *pworld_, method_);
return RunBenders(argv_, options_file_, *penv_, *pworld_);
}
3 changes: 0 additions & 3 deletions src/cpp/benders/factories/include/BendersFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@ enum class BENDERSMETHOD { BENDERS, BENDERSBYBATCH, MERGEMPS };
class BendersMainFactory {
private:
char** argv_;
BENDERSMETHOD method_;
std::filesystem::path options_file_;
boost::mpi::environment* penv_ = nullptr;
boost::mpi::communicator* pworld_ = nullptr;

public:
explicit BendersMainFactory(int argc, char** argv,
const BENDERSMETHOD& method,
boost::mpi::environment& env,
boost::mpi::communicator& world);
explicit BendersMainFactory(int argc, char** argv,
const BENDERSMETHOD& method,
const std::filesystem::path& options_file,
boost::mpi::environment& env,
boost::mpi::communicator& world);
Expand Down
2 changes: 0 additions & 2 deletions src/cpp/exe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,3 @@ add_subdirectory ("${CMAKE_CURRENT_SOURCE_DIR}/antares_archive_updater")

add_subdirectory ("${CMAKE_CURRENT_SOURCE_DIR}/benders")


add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/benders_by_batch")
3 changes: 1 addition & 2 deletions src/cpp/exe/benders/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
int main(int argc, char **argv) {
mpi::environment env(argc, argv);
mpi::communicator world;
auto benders_factory =
BendersMainFactory(argc, argv, BENDERSMETHOD::BENDERS, env, world);
auto benders_factory = BendersMainFactory(argc, argv, env, world);
return benders_factory.Run();
}
24 changes: 0 additions & 24 deletions src/cpp/exe/benders_by_batch/CMakeLists.txt

This file was deleted.

12 changes: 0 additions & 12 deletions src/cpp/exe/benders_by_batch/main.cpp

This file was deleted.

3 changes: 1 addition & 2 deletions src/cpp/exe/full_run/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ int main(int argc, char** argv) {
world.barrier();
int argc_ = 2;
const auto options_file = options_parser.BendersOptionsFile();
const auto benders_method = options_parser.Method();

auto benders_factory =
BendersMainFactory(argc_, argv, benders_method, options_file, env, world);
BendersMainFactory(argc_, argv, options_file, env, world);
benders_factory.Run();

if (world.rank() == 0) {
Expand Down
16 changes: 1 addition & 15 deletions src/cpp/full_run/FullRunOptionsParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
namespace po = boost::program_options;

FullRunOptionsParser::FullRunOptionsParser() : ProblemGenerationExeOptions() {
AddOptions()("method,m", po::value<std::string>(&method_str_)->required(),
"benders method")(
AddOptions()(
"benders_options,b",
po::value<std::filesystem::path>(&benders_options_file_)->required(),
"benders options file")(
Expand All @@ -15,17 +14,4 @@ FullRunOptionsParser::FullRunOptionsParser() : ProblemGenerationExeOptions() {
}
void FullRunOptionsParser::Parse(unsigned int argc, const char* const* argv) {
OptionsParser::Parse(argc, argv);
SetMethod();
}
void FullRunOptionsParser::SetMethod() {
if (method_str_ == "benders") {
method_ = BENDERSMETHOD::BENDERS;
} else if (method_str_ == "benders_by_batch") {
method_ = BENDERSMETHOD::BENDERSBYBATCH;
} else if (method_str_ == "mergeMPS") {
method_ = BENDERSMETHOD::MERGEMPS;
} else {
throw FullRunOptionsParser::FullRunOptionInvalidMethod(LOGLOCATION +
method_str_);
}
}
Loading