Skip to content

Commit

Permalink
tech:optionnative[read/write]: Gurobi, Mosek #231
Browse files Browse the repository at this point in the history
These were renamed from tech:param[:read/:write]

Doc: AMPL vs native solver options
  • Loading branch information
glebbelov committed Jan 18, 2024
1 parent 2f78ac9 commit a1cb209
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 64 deletions.
68 changes: 45 additions & 23 deletions doc/source/features-guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,57 @@ Solver options
=================

Solver options are key-value pairs controlling a solver's behavior.
Many of them are standardized across AMPL solvers
(for solver's native options see :ref:`further <native-options>`.)
We distinguish between :ref:`ampl-solver-options` and :ref:`native-options`.


.. _ampl-solver-options:

AMPL solver options
-----------------------------

AMPL solver options provide a unified interface to the underlying solver's
configuration:

.. code-block:: ampl
ampl: option solver gurobi;
ampl: option gurobi_options 'outlev=1'; ## verbose output
ampl: solve;
Many of them are standardized across AMPL solvers.


List all available options
----------------------------------
'''''''''''''''''''''''''''''''''''''''''''''

Run the AMPL solver executable with ``-=`` to list all options,
or with ``-=prefix`` to list all options starting with ``prefix``:
or with ``-=key`` to list all options containing ``key``:

.. code-block:: bash
$ highs -=acc
$ highs -=acc:
.....
acc Options:
acc: Options:
acc:linrange (acc:linrng)
Solver acceptance level for 'LinConRange', default 2
Option file
'''''''''''''''''''''''''''''''''''

It is possible to input a file with predefined AMPL solver options,
using ``tech:optionfile``:

.. code-block:: ampl
ampl: option cbc_options 'optionfile="options_experiment1.txt"';
For the underlying solver's native options see :ref:`native-options`.


Solver-specific vs common MP options
-------------------------------------------
''''''''''''''''''''''''''''''''''''''''''''''''

From AMPL, options can be passed to an MP solver in two ways.
Solver-specific options are passed
Expand Down Expand Up @@ -72,7 +101,7 @@ with the possibility to override some of them for a specific solver.


Set options from command line
--------------------------------------
'''''''''''''''''''''''''''''''''''''''''''''''

When running from command line, there are two ways to pass options:
via the environment variable, or via arguments:
Expand All @@ -83,19 +112,8 @@ via the environment variable, or via arguments:
gurobi.exe model.nl outlev=1 tech:writesol=model.sol ## Method 2
Set options from file
--------------------------

It is possible to input a file with predefined solver options,
using ``tech:optionfile``:

.. code-block:: ampl
ampl: option cbc_options 'optionfile="options_experiment1.txt"';
Query option values
--------------------------
''''''''''''''''''''''''''''''''''''''

To query the value of an option (default, or set via other methods),
use '?' as argument:
Expand All @@ -119,11 +137,15 @@ For example, to control Gurobi ``NumericFocus`` setting, there are two ways:

.. code-block:: ampl
ampl: option gurobi_options 'alg:numericfocus 3'; ## standard way
ampl: option gurobi_options 'tech:param "NumericFocus 3"'; ## native
ampl: option gurobi_options 'alg:numericfocus 3'; ## standard way
ampl: option gurobi_options 'tech:optionnative "NumericFocus 3"'; ## native
gurobi.exe model.nl optnative="numericfocus 2" optnative="Seed 500" # cmdline
Additionally, for some solvers, native options can be read / written
from / to files using ``tech:param:read`` and ``tech:param:write``.
from / to files using ``tech:optionnativeread`` and ``tech:optionnativewrite``.




General features
================
Expand Down
8 changes: 7 additions & 1 deletion include/mp/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,12 @@ enum Status {

/** Limit.
* Feasible solution, stopped by a limit, e.g., on iterations or Ctrl-C.
* Codes 400-449. */
* Codes 400-449.
* For new custom codes, use LIMIT_FEAS_CUSTOM, LIMIT_NO_FEAS_CUSTOM.
*/
LIMIT_FEAS = 400,
/** Start of custom LIMIT_FEAS codes. */
LIMIT_FEAS_NEW = LIMIT_FEAS + 20,
/** End of the 'limit_feas' range. */
LIMIT_FEAS_LAST = 449,
/** Deprecated. */
Expand Down Expand Up @@ -251,6 +255,8 @@ enum Status {
No feasible solution returned.
Codes 470-499. */
LIMIT_NO_FEAS = LIMIT_FEAS + 70,
/** Start of custom LIMIT_FEAS codes. */
LIMIT_NO_FEAS_NEW = LIMIT_NO_FEAS + 20,
/** End of the 'limit-no-feas' range. */
LIMIT_NO_FEAS_LAST = LIMIT_FEAS + 99,
/** User interrupt, no feasible solution. */
Expand Down
2 changes: 1 addition & 1 deletion solvers/gcgmp/gcgmpbackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ void GcgBackend::InitCustomOptions() {
"Log file name.",
storedOptions_.logFile_);

AddStoredOption("tech:param:read param:read paramfile",
AddStoredOption("tech:optionnativeread optionnativeread tech:param:read param:read",
"Filename of GCG parameter file (as path)."
"The suffix on a parameter file should be .set.\n",
storedOptions_.paramRead_);
Expand Down
28 changes: 16 additions & 12 deletions solvers/gurobi/gurobibackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,22 @@ void GurobiBackend::FinishOptionParsing() {
}
}
OpenGurobiModel();
// Tell the base class our verbosity
set_verbose_mode(GrbGetIntParam(GRB_INT_PAR_LOGTOCONSOLE));

// Nartive params
if (paramfile_read().size())
GRB_CALL(
GRBreadparams(GRBgetenv(model()),
paramfile_read().c_str() ));
/// Set advanced parameters
for (const auto& prm: storedOptions_.inlineParams_)
this->SetSolverOption("Dummy", prm);
// Write native params
if (paramfile_write().size())
GRB_CALL(
GRBwriteparams(GRBgetenv(model()),
paramfile_write().c_str() ));
/// Tell the base class our verbosity
set_verbose_mode(GrbGetIntParam(GRB_INT_PAR_LOGTOCONSOLE));
/// Set advanced parameters
if (storedOptions_.advancedParams_.size() > 0)
this->SetSolverOption("Dummy", storedOptions_.advancedParams_);
GRBwriteparams(GRBgetenv(model()),
paramfile_write().c_str()));
}

void GurobiBackend::OpenGurobiComputeServer() {
Expand Down Expand Up @@ -2394,16 +2397,16 @@ void GurobiBackend::InitCustomOptions() {
"0*/1: Whether to write gurobi log lines (chatter) to stdout.",
GRB_INT_PAR_LOGTOCONSOLE, 0, 1);

AddStoredOption("tech:param param",
AddListOption("tech:optionnative optionnative optnative tech:param",
"General way to specify values of both documented and "
"undocumented Gurobi parameters; value should be a quoted "
"string (delimited by ' or \") containing a parameter name, a "
"space, and the value to be assigned to the parameter. Can "
"appear more than once. Cannot be used to query current "
"parameter values.",
storedOptions_.advancedParams_);
storedOptions_.inlineParams_);

AddStoredOption("tech:param:read param:read paramfile",
AddStoredOption("tech:optionnativeread optionnativeread tech:param:read param:read",
"Name of Gurobi parameter file (surrounded by 'single' or "
"\"double\" quotes if the name contains blanks). "
"The suffix on a parameter file should be .prm, optionally followed "
Expand All @@ -2412,7 +2415,7 @@ void GurobiBackend::InitCustomOptions() {
"Lines that start with # are ignored. Otherwise, each nonempty "
"line should contain a name and a value, separated by a space.",
storedOptions_.paramRead_);
AddStoredOption("tech:param:write param:write",
AddStoredOption("tech:optionnativewrite optionnativewrite tech:param:write param:write",
"Name of Gurobi parameter file (surrounded by 'single' or \"double\" quotes if the "
"name contains blanks) to be written.",
storedOptions_.paramWrite_);
Expand All @@ -2429,7 +2432,8 @@ void GurobiBackend::InitCustomOptions() {
"| .mps, .rew, .lp, or .rlp - To capture the original model.\n"
"\n"
"The file suffix may optionally be followed by .gz, .bz2, or .7z, "
"which produces a compressed result.",
"which produces a compressed result. Use tech:writesolution "
"to write several files.",
GRB_STR_PAR_RESULTFILE);


Expand Down
4 changes: 3 additions & 1 deletion solvers/gurobi/gurobibackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MP_GUROBI_BACKEND_H_

#include <string>
#include <list>

#include "gurobicommon.h"
#include "mp/backend-mip.h"
Expand Down Expand Up @@ -279,7 +280,8 @@ class GurobiBackend :
/// These options are stored in the class as variables
/// for direct access
struct Options {
std::string paramRead_, paramWrite_, advancedParams_, exportPresolvedFile_, logFile_;
std::string paramRead_, paramWrite_, exportPresolvedFile_, logFile_;
std::list<std::string> inlineParams_;

int nMIPStart_=1;
int nPoolMode_=2;
Expand Down
40 changes: 40 additions & 0 deletions solvers/mosek/mosekbackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,28 @@ void MosekBackend::FinishOptionParsing() {
int v=-1;
GetSolverOption(MSK_IPAR_LOG, v);
set_verbose_mode(v>0);

// Nartive params
if (paramfile_read().size())
MOSEK_CCALL(
MSK_readparamfile(lp(), paramfile_read().c_str()));
/// Set advanced parameters
for (const auto& prm : storedOptions_.inlineParams_) {
auto sp1 = prm.find_first_of(' ');
auto sp2 = prm.find_last_of(' ');
if (sp1 != sp2 || std::string::npos == sp1
|| 0==sp1 || prm.back()==' ')
MP_RAISE(
fmt::format("Bad native option assignment:\n"
" '{}',\n"
" need 'name value'", prm));
MOSEK_CCALL( MSK_putparam(lp(),
prm.substr(0, sp1).c_str(), prm.substr(sp1+1, prm.size()-sp1-1).c_str()));
}
// Write native params
if (paramfile_write().size())
MOSEK_CCALL(
MSK_writeparamfile(lp(), paramfile_write().c_str()));
}


Expand Down Expand Up @@ -431,6 +453,24 @@ void MosekBackend::InitCustomOptions() {
"Default = OFF",
storedOptions_.MIPConstructSol_);

AddListOption("tech:optionnative optionnative optnative tech:param",
"General way to specify values of both documented and "
"undocumented Mosek parameters; value should be a quoted "
"string (delimited by ' or \") containing a parameter name, a "
"space, and the value to be assigned to the parameter. Can "
"appear more than once. Cannot be used to query current "
"parameter values.",
storedOptions_.inlineParams_);

AddStoredOption("tech:optionnativeread optionnativeread tech:param:read param:read",
"Name of Mosek parameter file (surrounded by 'single' or "
"\"double\" quotes if the name contains blanks) to be read.",
storedOptions_.paramRead_);
AddStoredOption("tech:optionnativewrite optionnativewrite tech:param:write param:write",
"Name of Mosek parameter file (surrounded by 'single' or \"double\" quotes if the "
"name contains blanks) to be written.",
storedOptions_.paramWrite_);

AddSolverOption("mip:presolve presolve",
"MIP presolve:\n"
"\n.. value-table::\n",
Expand Down
8 changes: 8 additions & 0 deletions solvers/mosek/mosekbackend.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef MP_MOSEK_BACKEND_H_
#define MP_MOSEK_BACKEND_H_

#include <list>
#include <string>

#include "mp/backend-mip.h"
Expand Down Expand Up @@ -173,13 +174,20 @@ class MosekBackend :
struct Options {
// Whether to set MSK_IPAR_MIO_CONSTRUCT_SOL
int MIPConstructSol_=0;

std::string paramRead_, paramWrite_;
std::list<std::string> inlineParams_;
};
Options storedOptions_;

protected:
/**** Option accessors ****/
int Mosek_mip_construct_sol() const { return storedOptions_.MIPConstructSol_; }

const std::list<std::string>& params_inline() const
{ return storedOptions_.inlineParams_; }
const std::string& paramfile_read() const { return storedOptions_.paramRead_; }
const std::string& paramfile_write() const { return storedOptions_.paramWrite_; }
};

} // namespace mp
Expand Down
2 changes: 1 addition & 1 deletion solvers/scipmp/scipmpbackend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ void ScipBackend::InitCustomOptions() {
"Log file name.",
storedOptions_.logFile_);

AddStoredOption("tech:param:read param:read paramfile",
AddStoredOption("tech:optionnativeread optionnativeread tech:param:read param:read",
"Filename of SCIP parameter file (as path)."
"The suffix on a parameter file should be .set.\n",
storedOptions_.paramRead_);
Expand Down
Loading

0 comments on commit a1cb209

Please sign in to comment.