asyncjobs.gms : Execute asynchronously several GAMS jobs and collect the fastest

Description

This program shows how to run several GAMS jobs asynchronously.
Moreover, when a job finishes successfully, the other jobs are killed, if
they are still running. For the demonstration we retrieve model library example
DICE and run it with GUROBI using four different setting for the meta option
mipfocus.

Contributor: Toni Lastusilta, 2014

Keywords: GAMS language features


Large Model of Type : GAMS


Category : GAMS Model library


Main file : asyncjobs.gms

$title Execute asynchronously several GAMS Jobs and collect the fastest (ASYNCJOBS,SEQ=403)

$onText
This program shows how to run several GAMS jobs asynchronously.
Moreover, when a job finishes successfully, the other jobs are killed, if
they are still running. For the demonstration we retrieve model library example
DICE and run it with GUROBI using four different setting for the meta option
mipfocus.

Contributor: Toni Lastusilta, 2014

Keywords: GAMS language features
$offText

$call gamslib -q dice
$ifE errorLevel<>0 $abort 'problems retrieving dice'
$echo "abort$(xdice.modelStat <> 1 or xdice.solveStat <> 1) 'model not solved to optimality';" >> dice.gms

$echo mipFocus 0 > gurobi.opt
$echo mipFocus 1 > gurobi.op2
$echo mipFocus 2 > gurobi.op3
$echo mipFocus 3 > gurobi.op4

* Initialization
Set
   s 'scenario: option file number' / 1*4 /
   modelhdr  / system.GUSSModelAttributes /;

Singleton Set
   finished(s) 'fastest successfully finished job';

Parameter
   jh(s) 'PID number from JobHandle';

* Run several GAMS jobs asynchronously
loop(s,
   put_utility 'exec.async' / 'gams dice lo=2 mip=gurobi optcr=0 optfile=' s.tl:0 ' lf=' s.tl:0 '.log o=' s.tl:0 '.lst gdx=' s.tl:0;
   jh(s) = JobHandle;
);

* Check job status until one job is successfully finished or no job is left or some total time limit (20secs) is exceeded
option strictSingleton = 0;
finished(s) = no;

Scalar lastTimeDisplay / 0 /;

while(card(finished) = 0 and card(jh) > 0 and timeElapsed < 20,
   loop(s$jh(s),
      if(JobStatus(jh(s)) = 2,
         finished(s) = errorLevel = 0;
         jh(s) = 0;
      );
   );
   if(timeElapsed - lastTimeDisplay > 0.2$sleep(0.01),
      put_utility 'log' / 'Elasped ' timeElapsed:4:2 ' secs. Jobs running: ' card(jh):0:0;
      lastTimeDisplay = timeElapsed;
   );
);

* Kill remaining job
display 'remaining jobs to be killed', jh;
loop(s$jh(s), display$JobKill(jh(s)) 'Killing job';);

abort$(card(finished) = 0) 'No job returned successfully';
display 'winning job is', finished;

* if you want to extract some result from the winning job use the GDX file
put_utility 'gdxin' / finished.tl:0 '.gdx';
Variable objval / l 0 /;
execute_load objval = wnx;
display objval.l;