gsolver.gms : Compare the actual system with the original solver database

Description

This model compares the solvers and their capabilities on the
actual system with the original solver capability database.
It then runs all combinations with solvers known to the global database
and checks if the return code of a GAMS run is 0.

All exceptions are captured in a compare report. If the report is not empty,
the model will terminate with an execution error.

Keywords: GAMS language features


Small Model of Type : GAMS


Category : GAMS Model library


Main file : gsolver.gms

$title Compare the actual System with the original Solver Database (GSOLVER,SEQ=311)

$onText
This model compares the solvers and their capabilities on the
actual system with the original solver capability database.
It then runs all combinations with solvers known to the global database
and checks if the return code of a GAMS run is 0.

All exceptions are captured in a compare report. If the report is not empty,
the model will terminate with an execution error.

Keywords: GAMS language features
$offText

Set
   ModelTypes  / system.ModelTypes   /
   SolverNames / system.SolverNames  /
   Platforms   / system.Platforms    /
   BuildCode   /'%system.buildcode%' /
   glbSolverDB(SolverNames,ModelTypes,Platforms) / system.SolverTypePlatformMap /;

Set
   s(SolverNames)                                'solvers available for this platform'
   glbSolverCapabilities(SolverNames,ModelTypes) 'original solver model type map';

Parameter comprep 'compare report';

s(SolverNames) = sum(glbSolverDB(SolverNames,ModelTypes,'%system.platform%'), yes);
glbSolverCapabilities(s,ModelTypes) = sum(glbSolverDB(s,ModelTypes,'%system.platform%'), yes);

* Solver/Capability pairs missing in the actual system
comprep(s,ModelTypes,'missing')    = glbSolverCapabilities(s,ModelTypes) and
                                     not SolverCapabilities(s,ModelTypes);
* Additional Solver/Capability pairs in the actual system
comprep(s,ModelTypes,'additional') = not glbSolverCapabilities(s,ModelTypes) and
                                     SolverCapabilities(s,ModelTypes);

$onEmpty
Set
   skiplist 'list of solvers to skip'
            / de
              decisc
              decism
              kestrel
$if %system.buildcode% == DEG shot 'CPLEX output to stdout cannot be redirected'
            /
   skipm       'list of skipped modeltypes' / emp /
   skipsm(*,*) 'list of skipped solver/modeltype combinations' /
      (gurobi,osigurobi,mosek,osimosek,osixpress).(nlp,rminlp,dnlp,minlp)   'cannot solve the kind of ((r)mi/d)nlp that is used in this test'
    /;
$offEmpty

* Produce a GAMS program that will execute and configure the test
* models (shown at the end). For each solver model type combination
* we will execute a program like:
*
* $call =gams <scratch dir>m.%gams.scrext% lo=0 --mtype=rmip --solver=conopt
* $ifE errorLevel<>0 $abort "Solver conopt expected to solve rmip";
*
* and record exceptions in the 'fail' column of the report set tuple comprep.

$set mname '"%gams.scrdir%m.%gams.scrext%"'
File fx   / rungslv.gms /; fx.lcase = 1;
File flog / '' /;          flog.ps  = 1;
$set singlerun
$set lo lo=0
$if set solver    $set lo lo=3
$if set solver    $set singlerun and sameas('%solver%',s)
$if set modeltype $set singlerun %singlerun% and sameas('%modeltype%',Modeltypes)

loop(SolverCapabilities(s,ModelTypes)$([not skipsm(s,ModelTypes)] and [sum{skiplist(s),1}=0] and [sum(skipm(ModelTypes),1)=0] %singlerun%),
   putClose fx '$call =gams %mname% %lo% --mtype=' ModelTypes.tl:0 ' --solver=' s.tl:0
             / '$ifE errorLevel<>0 $abort "Solver ' s.tl:0 ' expected to solve ' ModelTypes.tl:0;
   put flog '--- Running Solver ' s.tl:0 ' on Model Type ' ModelTypes.tl:0 /;
   execute '=gams rungslv.gms %lo%';
   comprep(s,ModelTypes,'fail')$errorLevel = yes;
);
$if set solver $goto modeldump

File ff / gslvfail.gms /;
loop((s,ModelTypes)$comprep(s,ModelTypes,'fail'),
   put ff '$call gams gsolver --Solver ' s.tl:0 ' --ModelType ' ModelTypes.tl:0 /;
);

* Trigger an execution error if the comprep report has entries
abort$card(comprep) comprep;

$label modeldump
* Below is the test program to be executed. Note that we
* copy the model into the scratch directory with the name extension
* .%gams.scrext%. This file will then be removed automatically when gams
* terminates.

$onEchoV > %mname%
* A tiny test model for all different model types
* The $setddlist (Double Dash List) defines all
* 'legal' --names.

$if not set mtype  $error --mtype=xxxx missing
$if not set solver $error --solver=xxxx missing
$setDDList mtype solver

Variable z;
Positive Variable w, x, y;
x.up = 200;
x.l = 1; y.l = 1; z.l = 1;
Integer Variable xi, yi;
xi.up = 100; xi.l = 1;
yi.up = 100; yi.l = 1;

Equation lpe1, nlpe1, dnlpe1, mipe1, minlpe1, lpo, qcpo, nlpo, mipo, miqcpo, minlpo
         cnse1, cnse2, mcpe1, mpeco, dece1, deco;

* LP QCP NLP MIP MIQCP MINLP
lpe1..    x + y      =l= 2.2;
nlpe1..   exp(x+y)   =l= 4.1;
dnlpe1..  abs(x*y)   =l= 4.1;
mipe1..   xi + yi    =l= 3.5;
minlpe1.. exp(xi*yi) =l= 4.6;

lpo..     z =e= -3*x - 4*y;
qcpo..    z =e= 2*sqr(x - 3.4) + 3*sqr(y - 2.9);
nlpo..    z =e= exp(3*x + 2*y);
mipo..    z =e= -3*xi - 4*yi;
miqcpo..  z =e= 2*sqr(xi - 3.4) + 3*sqr(yi - 2.9);
minlpo..  z =e= exp(3*xi + 2*yi);

* CNS
cnse1..   sqr(x-3) + sqrt(y+4) =e= 3.7;
cnse2..   x + 3.1*y            =e= 3.5;

* MPEC and MCP
mcpe1..   0.5*x + 2*y =g= 100;
mpeco..   z =e= 0.5*sqr(x) + 0.5*x*y - 95*x;

* DECIS
dece1..   x =e= y + w;
deco..    z =e= 24*y -2.49*x - 4*w;

Model
   m_lp     / lpe1,    lpo    /
   m_qcp    / lpe1,    qcpo   /
   m_nlp    / nlpe1,   nlpo   /
   m_dnlp   / dnlpe1,  nlpo   /
   m_rmip   / mipe1,   mipo   /
   m_mip    / mipe1,   mipo   /
   m_rmiqcp / mipe1,   miqcpo /
   m_miqcp  / mipe1,   miqcpo /
   m_rminlp / minlpe1, minlpo /
   m_minlp  / minlpe1, minlpo /
   m_cns    / cnse1,   cnse2  /
   m_mpec   / mcpe1.y, mpeco  /
   m_rmpec  / mcpe1.y, mpeco  /
   m_mcp    / mcpe1.y         /
   m_decis  / dece1,   deco   /;

option %mtype% = %solver%, optCr = 0;

* Special handling of solvers with special requirements
$ifI %solver% == decisc     $goto DECIS
$ifI %solver% == decism     $goto DECIS
$ifI %solver% == guss       $goto GUSS

* Special handling for model types that do not have an objective
$ifI %mtype%  == cns $goto CNS
$ifI %mtype%  == mcp $goto MCP

solve m_%mtype% using %mtype% min z;
abort$(m_%mtype%.solveStat <> %solveStat.normalCompletion%) 'solver return not normal';
$exit

$label CNS
solve m_cns using cns;
abort$(m_cns.solveStat <> %solveStat.normalCompletion%) 'solver return not normal';
$exit

$label MCP
x.fx = 200;
solve m_mcp using mcp;
abort$(m_mcp.solveStat <> %solveStat.normalCompletion%) 'solver return not normal';
$exit

$label DECIS
y.up        = 160;
x.stage     =   1;
dece1.stage =   2;
y.stage     =   2;

File fx / MODEL.STG /
     fy / MINOS.SPC /;
putClose fx 'BLOCKS DISCRETE'
          / 'BL BLOCK1 PERIOD2 0.25'
          / 'UP BND y  150'
          / 'BL BLOCK1 PERIOD2 0.75'
          / 'UP BND y  160';
putClose fy 'begin'
          / 'rows 250'
          / 'columns 250'
          / 'elements 10000'
          / 'end';

solve m_decis using %mtype% max z;
abort$(m_decis.solveStat <> %solveStat.normalCompletion%) 'solver return not normal';
$exit

$label GUSS
Set i / d1*d2 /, j / i1, o1 /, ji(j) / i1 /, jo(j) / o1 /;
Parameter ds(i,j) / d1.i1 3, d1.o1 5, d2.i1 2.5, d2.o1 4.5 /;
Parameter d(j);

Variable z;
Positive Variable v(ji), u(jo);

Equation deao, deae1, deae2;

deao..  z =e= sum(jo, u(jo)*d(jo));
deae1.. sum(ji, v(ji)*d(ji)) =e= 1;
deae2.. sum(jo, u(jo)*d(jo)) =l= sum(ji, v(ji)*d(ji));

Model m_scen / deao, deae1, deae2 /;

Set dict(*,*,*) / i.scenario.'' 1, d.param.ds    2 /;

d(j) = ds('d1',j);
option lp = soplex;
solve m_scen using lp minimizing z scenario dict;
abort$(m_scen.solveStat <> %solveStat.normalCompletion%) 'solver return not normal';
$exit

$offEcho