Skip to content

Commit

Permalink
ASL-style: repeated 'writeprob' and 'writesol' #128
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed Jul 28, 2023
1 parent 1605d9b commit deac242
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 68 deletions.
106 changes: 55 additions & 51 deletions include/mp/backend-std.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ class StdBackend :

SetupTimerAndInterrupter();
if (exportFileMode() > 0)
ExportModel(export_file_name());
ExportModel(export_file_names());

// exportFileMode == 2 -> do not solve, just export
if (exportFileMode() != 2)
Expand Down Expand Up @@ -702,13 +702,14 @@ class StdBackend :
int round_=0;
double round_reptol_=1e-9;

// For write prob
std::string export_file_;
std::string just_export_file_;
// For write sol
std::string export_sol_;
/// For write prob
std::vector<std::string> export_files_;
std::vector<std::string> just_export_files_;
/// For write sol
std::vector<std::string> export_sol_files_;
} storedOptions_;


/// Once Impl allows FEASRELAX,
/// it should check this via feasrelax()
class FeasrelaxIO {
Expand Down Expand Up @@ -758,23 +759,18 @@ class StdBackend :
int exportFileMode() const
{
if (IMPL_HAS_STD_FEATURE(WRITE_PROBLEM)) {
if (!storedOptions_.export_file_.empty())
if (!storedOptions_.export_files_.empty())
return 1;
if (!storedOptions_.just_export_file_.empty())
if (!storedOptions_.just_export_files_.empty())
return 2;
}
return 0;
}
std::string export_file_name() const {
std::string name
= storedOptions_.export_file_.empty()
? storedOptions_.just_export_file_
: storedOptions_.export_file_;
if (((name.front() == '"') && (name.back() == '"')) ||
((name.front() == '\'') && (name.back() == '\'')))
return name.substr(1, name.length() - 2);
else
return name;
const std::vector<std::string>& export_file_names() const {
return
storedOptions_.export_files_.empty()
? storedOptions_.just_export_files_
: storedOptions_.export_files_;
}


Expand Down Expand Up @@ -836,26 +832,27 @@ class StdBackend :
}

if (IMPL_HAS_STD_FEATURE(WRITE_PROBLEM)) {
AddStoredOption("tech:writemodel writeprob writemodel",
"Specifies the name of a file where to export the model before "
"solving it. This file name can have extension ``.lp[.7zip]``, ``.mps``, etc. "
"Default = \"\" (don't export the model).",
storedOptions_.export_file_);

AddStoredOption("tech:writemodelonly justwriteprob justwritemodel",
"Specifies the name of a file where to export the model, do not solve it. "
"This file name can have extension ``.dlp``, ``.mps``, etc. "
"Default = \"\" (don't export the model).",
storedOptions_.just_export_file_);
AddListOption("tech:writemodel writeprob writemodel tech:exportfile",
"Specifies files where to export the model before "
"solving (repeat the option for several files.) "
"File name extensions can be ``.lp[.7z]``, ``.mps``, etc.",
storedOptions_.export_files_);

AddListOption("tech:writemodelonly justwriteprob justwritemodel",
"Specifies files where to export the model, no solving "
"(option can be repeated.) "
"File extensions can be ``.dlp``, ``.mps``, etc.",
storedOptions_.just_export_files_);
}

if (IMPL_HAS_STD_FEATURE(WRITE_SOLUTION))
AddStoredOption("tech:writesolution writesol writesolution",
"Specifies the name of a file where to export the solution "
"or other result file. This file name can have extension "
"``.sol[.tar.gz]``, ``.json``, ``.bas``, ``.ilp``, etc. "
"Default = \"\" (don't export results).",
storedOptions_.export_sol_);
AddListOption("tech:writesolution writesol writesolution",
"Specifies the names of files where to export the solution "
"and/or other result files in solver's native formats. "
"Option can be repeated. "
"File name extensions can be "
"``.sol[.tar.gz]``, ``.json``, ``.bas``, ``.ilp``, etc.",
storedOptions_.export_sol_files_);
}

virtual void InitCustomOptions() { }
Expand Down Expand Up @@ -940,27 +937,34 @@ class StdBackend :


public:
/// Via solver's output
/// Write solution result in solver native format
/// via solver's output.
virtual void ReportSolutionViaSolver() {
if (IMPL_HAS_STD_FEATURE(WRITE_SOLUTION))
if (!storedOptions_.export_sol_.empty())
DoWriteSolution(storedOptions_.export_sol_);
if (!storedOptions_.export_sol_files_.empty())
for (const auto& fln: storedOptions_.export_sol_files_)
DoWriteSolution(fln);
}

/// Write model
virtual void ExportModel(const std::string& filename) {
try {
DoWriteProblem(filename);
} catch (const std::exception& exc) {
auto msg
= std::string("Model export failed:\n")
+ exc.what();
if (IMPL_HAS_STD_FEATURE(WRITE_SOLUTION))
msg +=
"\n Note: to export solutions and results\n"
" in the solver's native formats,\n"
" use option 'tech:writesolution'";
MP_RAISE(msg);
virtual void ExportModel(
const std::vector<std::string>& filenames) {
for (const auto& fln: filenames) {
try {
DoWriteProblem(fln);
} catch (const std::exception& exc) {
auto msg
= std::string("Model export to file '")
+ fln
+ "' failed:\n"
+ exc.what();
if (IMPL_HAS_STD_FEATURE(WRITE_SOLUTION))
msg +=
"\n Note: to export solutions and results\n"
" in the solver's native formats,\n"
" use option 'tech:writesolution'";
MP_RAISE(msg);
}
}
}

Expand Down
53 changes: 52 additions & 1 deletion include/mp/solver-opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ class SolverOptionManager {


public:
/// Stored option: references a variable
template <class Value>
class StoredOption : public mp::TypedSolverOption<Value> {
Value& value_;
Expand All @@ -495,7 +496,9 @@ class SolverOptionManager {
}

/// Simple stored option referencing a variable; min, max values
/// (currently unused)
/// (they are unused but to deduce type;
/// we aree too lazy to maintain correct min/max
/// between solver versions.)
template <class Value>
void AddStoredOption(const char *name, const char *description,
Value& value, Value , Value ) {
Expand All @@ -511,12 +514,60 @@ class SolverOptionManager {
AddStoredOption(name, description, value, lb, ub);
}


/// List option: references a container of values.
/// Any container with value_type, back() and push_back().
template <class Container>
class ListOption
: public mp::TypedSolverOption
<typename Container::value_type> {
Container& value_;
public:
using value_type = typename Container::value_type;
ListOption(const char *name_list, const char *description,
Container& v, ValueArrayRef values = ValueArrayRef())
: mp::TypedSolverOption<value_type>(
name_list, description, values), value_(v) {}

void GetValue(value_type &v) const override
{ assert(value_.size()); v = value_.back(); }
void SetValue(
typename internal::OptionHelper<value_type>::Arg v) override
{ value_.push_back(v); }
};

/// Add list option referencing a container
template <class Value>
void AddListOption(const char *name, const char *description,
Value& value, ValueArrayRef values = ValueArrayRef()) {
AddOption(OptionPtr(
new ListOption<Value>(
name, description, value, values)));
}

/// Add list option referencing a container; min, max values
/// (they are unused but to deduce type;
/// we aree too lazy to maintain correct min/max
/// between solver versions.)
template <class Value>
void AddListOption(const char *name, const char *description,
Value& value,
typename Value::value_type ,
typename Value::value_type ) {
AddOption(OptionPtr(
new ListOption<Value>(
name, description, value, ValueArrayRef())));
}


/// Replace option descr
void ReplaceOptionDescription(const char* name, const char* desc) {
auto pOption = FindOption(name);
assert(pOption);
pOption->set_description(desc);
}

/// Add to option descr
void AddToOptionDescription(const char* name, const char* desc_add) {
auto pOption = FindOption(name);
assert(pOption);
Expand Down
22 changes: 9 additions & 13 deletions solvers/visitor/visitorbackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,6 @@ int VisitorBackend::BarrierIterations() const {
// return getIntAttr(VISITOR_INTATTR_BARRIERITER);
}

void VisitorBackend::ExportModel(const std::string &file) {
// TODO export proper by file extension
//VISITOR_CCALL(VISITOR_WriteLp(lp(), file.data()));
}


void VisitorBackend::SetInterrupter(mp::Interrupter *inter) {
inter->SetHandler(InterruptVisitor, lp());
Expand All @@ -194,9 +189,6 @@ void VisitorBackend::SetInterrupter(mp::Interrupter *inter) {
}

void VisitorBackend::Solve() {
if (!storedOptions_.exportFile_.empty()) {
ExportModel(storedOptions_.exportFile_);
}
//VISITOR_CCALL(VISITOR_Solve(lp()));
WindupVISITORSolve();
}
Expand Down Expand Up @@ -345,12 +337,16 @@ void VisitorBackend::InitCustomOptions() {
"\n"
" ampl: option visitor_options 'mipgap=1e-6';\n");

AddStoredOption("tech:exportfile writeprob writemodel",
"Specifies the name of a file where to export the model before "
"solving it. This file name can have extension ``.lp()``, ``.mps``, etc. "
"Default = \"\" (don't export the model).",
storedOptions_.exportFile_);
AddStoredOption("tech:option_example opt_example example_opt",
"Example option. "
"Default = \"\" (don't work too hard).",
storedOptions_.option_example_);

AddListOption("tech:list_option opt_list multi_valued_option",
"Multi-valued option when repeated.",
storedOptions_.list_option_);

// Use AddSolverOption() for solver parameters
}


Expand Down
11 changes: 8 additions & 3 deletions solvers/visitor/visitorbackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ class VisitorBackend :
void OpenSolver();
void CloseSolver();

void ExportModel(const std::string& file);

double ObjectiveValue() const;

/// Solution values. The vectors are emptied if not available
Expand Down Expand Up @@ -180,11 +178,18 @@ class VisitorBackend :
private:
/// These options are stored in the class
struct Options {
std::string exportFile_;
std::string option_example_;
std::vector<double> list_option_;
};
Options storedOptions_;


protected:
const std::string& get_example_option() const
{ return storedOptions_.option_example_; }
const std::vector<double>& get_list_option() const
{ return storedOptions_.list_option_; }

};

} // namespace mp
Expand Down

1 comment on commit deac242

@glebbelov
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct: #218

Please sign in to comment.