sl601.gms : Check correct behavior when using solveLink=6

Description

With GAMS 24.6 a new variant for the SolveLink option and model attribute has
been added. If SolveLink is set to %solveLink.Async Threads%, GAMS does not wait
for the solver to return and does not collect the result when a solve statement
is executed. Instead, the model is generated and then passed to the solver in a
separate thread while GAMS continues the execution. This way, multiple models
can be solved in parallel and the results can be collected later.

This is similar to the Grid Facility (SolveLink = %solveLink.Async Grid%) with
the difference, that the solver does not operate in its own process space but in
a separate thread, which allows efficient in-memory communication between GAMS
and the solver (like it is done with SolveLink = %solveLink.Load Library%).
After the solve statement, one can store a handle of the model instance (using
the model attribute mymodel.handle) and use the same functions that are used for
the Grid Facility to collect the solution and deal with the model instance:
HandleCollect(handle), HandleStatus(handle), and HandleDelete(handle).

The new function ReadyCollect(handleParameter [, maxWait]) can be used to wait
until a model is ready to be collected. It can be used for both SolveLink =
%solveLink.Async Threads% and SolveLink = %solveLink.Async Grid%.

In this model the basic functionality is tested.

Keyword: solveLink=%solvelink.Async Threads%

Contributor: Lutz Westermann, January 2016


Small Model of Type : GAMS


Category : GAMS Test library


Main file : sl601.gms

$title 'Check correct behavior when using solveLink=%solvelink.Async Threads%' (SL601,SEQ=691)

$ontext
With GAMS 24.6 a new variant for the SolveLink option and model attribute has
been added. If SolveLink is set to %solveLink.Async Threads%, GAMS does not wait
for the solver to return and does not collect the result when a solve statement
is executed. Instead, the model is generated and then passed to the solver in a
separate thread while GAMS continues the execution. This way, multiple models
can be solved in parallel and the results can be collected later.

This is similar to the Grid Facility (SolveLink = %solveLink.Async Grid%) with
the difference, that the solver does not operate in its own process space but in
a separate thread, which allows efficient in-memory communication between GAMS
and the solver (like it is done with SolveLink = %solveLink.Load Library%).
After the solve statement, one can store a handle of the model instance (using
the model attribute mymodel.handle) and use the same functions that are used for
the Grid Facility to collect the solution and deal with the model instance:
HandleCollect(handle), HandleStatus(handle), and HandleDelete(handle).

The new function ReadyCollect(handleParameter [, maxWait]) can be used to wait
until a model is ready to be collected. It can be used for both SolveLink =
%solveLink.Async Threads% and SolveLink = %solveLink.Async Grid%.

In this model the basic functionality is tested.

Keyword: solveLink=%solvelink.Async Threads%

Contributor: Lutz Westermann, January 2016
$offtext


Sets
     i   canning plants   / seattle, san-diego /
     j   markets          / new-york, chicago, topeka / ;

Parameters
     a(i)  capacity of plant i in cases
       /    seattle     350
            san-diego   600  /
     b(j)  demand at market j in cases
       /    new-york    325
            chicago     300
            topeka      275  / ;

Table d(i,j)  distance in thousands of miles
                  new-york       chicago      topeka
    seattle          2.5           1.7          1.8
    san-diego        2.5           1.8          1.4  ;

Scalar f  freight in dollars per case per thousand miles  /90/ ;

Parameter c(i,j)  transport cost in thousands of dollars per case ;
          c(i,j) = f * d(i,j) / 1000 ;

Variables
     x(i,j)  shipment quantities in cases
     z       total transportation costs in thousands of dollars ;

Positive Variable x ;

Equations
     cost        define objective function
     supply(i)   observe supply limit at plant i
     demand(j)   satisfy demand at market j ;

cost ..        z  =e=  sum((i,j), c(i,j)*x(i,j)) ;
supply(i) ..   sum(j, x(i,j))  =l=  a(i) ;
demand(j) ..   sum(i, x(i,j))  =g=  b(j) ;

Model transport /all/ ;

*Solve model, wait for results, collect result, delete handle and do some checks
$onEcho > SolveWaitCollectDelete.inc
Solve transport using lp minimizing z ;
abort$(ReadyCollect (transport.handle)<>0) 'Problem waiting for model',  transport.handle;
abort$(HandleCollect(transport.handle)<>1) 'Problem collecting results', transport.handle;
abort$(HandleDelete (transport.handle)<>0) 'Problem deleteing result',   transport.handle;

abort$(transport.objVal<>153.675) 'wrong objective value';
abort$(z.l<>153.675)              'wrong value for z';
$offEcho

* Set solvelink
option solvelink = %solvelink.Async Threads%;

* Not every solver works with sl=6, test that the resetting to 3 works if 6 cannot be used
* Select a solver that supports %solvelink.Async Threads%
option lp=cplexd;
$include SolveWaitCollectDelete.inc
abort$(transport.LinkUsed<>%solvelink.Async Threads%) 'sl was reset unexpectedly'

* Select a solver that does not support %solvelink.Async Threads%
option lp=cplex;
$include SolveWaitCollectDelete.inc
abort$(transport.LinkUsed<>%solvelink.Async Grid%) 'sl should be reset to %solvelink.Async Grid%'

* Check return codes of functions
Scalar wrongHandle /111/;
abort$(ReadyCollect(wrongHandle)<>1)  'Expected ReadyCollect to signal that there is no job to wait for';
abort$(HandleStatus(wrongHandle)<>0)  'Expected error return from HandleStatus';
abort$(HandleCollect(wrongHandle)<>0) 'Expected error return from HandleCollect';
abort$(HandleDelete(wrongHandle)<>1)  'Expected error return from HandleDelete';

set       s /s1*s3/;
parameter handles(s);
handles(s)=no;
abort$(ReadyCollect(handles)<>2)  'Expected ReadyCollect to signal that the provided symbol is empty';