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

  No Gurobi on Solaris

Reference

  • GAMS Development Corporation, Formulation and Language Example.

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
$offtext

* No Gurobi on Solaris
$ifi %system.platform% == sox $exit
$ifi %system.platform% == sis $exit

$call gamslib -q dice
$if errorlevel 1 $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
File  fx; put fx;
Sets  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 fx 'gdxin' / finished.tl:0 '.gdx';
variable objval /L 0/;
execute_load objval=wnx; display objval.l;