interrupt.gms : Check Ctrl-C/Interrupt handling of Embedded Code, MIP solver, and GAMS

Description

This test checks that embedded code, the MIP solver, and GAMS itself (during execution) can be
interrupted. The test can be run interactively requiring the user to hit 25 times Ctrl-C or in
a batch mode, where some embedded Python issues these 25 interrupt signals

Contributor: Michael Bussieck, March 2023


Small Model of Type : GAMS


Category : GAMS Test library


Main file : interrupt.gms

$title 'Check Ctrl-C/Interrupt handling of Embedded Code, MIP solver, and GAMS' (INTERRUPT,SEQ=937)

$onText
This test checks that embedded code, the MIP solver, and GAMS itself (during execution) can be
interrupted. The test can be run interactively requiring the user to hit 25 times Ctrl-C or in
a batch mode, where some embedded Python issues these 25 interrupt signals

Contributor: Michael Bussieck, March 2023
$offText


$onEchoV > stopme.gms
$onEmbeddedCode Connect:
- PythonCode:
   code: |
     x = 0
     for i in range(1000):
      for j in range(1000):
       for k in range(1000):
        for l in range(1000):
         x = x + 1
$offEmbeddedCode
$clearErrors
$onEmbeddedCode Python:
x = 0
for i in range(1000):
 for j in range(1000):
  for k in range(1000):
   for l in range(1000):
    x = x + 1
$offEmbeddedCode
$clearErrors
$onEmbeddedCode GAMS:
set i / 1*1000 /; alias (i,j,k,l);
scalar x /0/;
loop((i,j,k,l), x = x+1);
$offEmbeddedCode
$clearErrors

embeddedCode Connect:
- PythonCode:
   code: |
     x = 0
     for i in range(1000):
      for j in range(1000):
       for k in range(1000):
        for l in range(1000):
         x = x + 1
endEmbeddedCode
execError = 0;
embeddedCode Python:
x = 0
for i in range(1000):
 for j in range(1000):
  for k in range(1000):
   for l in range(1000):
    x = x + 1
pauseEmbeddedCode
execError = 0;
continueEmbeddedCode:
x = 0
for i in range(1000):
 for j in range(1000):
  for k in range(1000):
   for l in range(1000):
    x = x + 1
endEmbeddedCode
execError = 0;
embeddedCode GAMS:
set i / 1*1000 /; alias (i,j,k,l);
scalar x /0/;
loop((i,j,k,l), x = x+1);
endEmbeddedCode
execError = 0;

* MIPLIB pk1 problem with last five binaries relaxed (to fit the demo limit and make test faster)

Variables  x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19
          ,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31,x32,b33,b34,b35,b36
          ,b37,b38,b39,b40,b41,b42,b43,b44,b45,b46,b47,b48,b49,b50,b51,b52,b53
          ,b54,b55,b56,b57,b58,b59,b60,b61,b62,b63,b64,b65,b66,b67,b68,b69,b70
          ,b71,b72,b73,b74,b75,b76,b77,b78,b79,b80,b81,b82,b83,b84,b85,b86,b87;

Positive Variables  x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17
          ,x18,x19,x20,x21,x22,x23,x24,x25,x26,x27,x28,x29,x30,x31,x32;

Binary Variables  b33,b34,b35,b36,b37,b38,b39,b40,b41,b42,b43,b44,b45,b46,b47
          ,b48,b49,b50,b51,b52,b53,b54,b55,b56,b57,b58,b59,b60,b61,b62,b63,b64
          ,b65,b66,b67,b68,b69,b70,b71,b72,b73,b74,b75,b76,b77,b78,b79,b80,b81
          ,b82,b83,b84,b85,b86,b87;

Equations  e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19
          ,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31,e32,e33,e34,e35,e36
          ,e37,e38,e39,e40,e41,e42,e43,e44,e45,e46;


e1..    x1 - x2 =E= 0;
e2..    x2 - x3 =G= 0;
e3..    x2 - x4 =G= 0;
e4..    x2 - x5 =G= 0;
e5..    x2 - x6 =G= 0;
e6..    x2 - x7 =G= 0;
e7..    x2 - x8 =G= 0;
e8..    x2 - x9 =G= 0;
e9..    x2 - x10 =G= 0;
e10..    x2 - x11 =G= 0;
e11..    x2 - x12 =G= 0;
e12..    x2 - x13 =G= 0;
e13..    x2 - x14 =G= 0;
e14..    x2 - x15 =G= 0;
e15..    x2 - x16 =G= 0;
e16..    x2 - x17 =G= 0;
e17..    x2 - x18 =G= 0;
e18..    x2 - x19 =G= 0;
e19..    x2 - x20 =G= 0;
e20..    x2 - x21 =G= 0;
e21..    x2 - x22 =G= 0;
e22..    x2 - x23 =G= 0;
e23..    x2 - x24 =G= 0;
e24..    x2 - x25 =G= 0;
e25..    x2 - x26 =G= 0;
e26..    x2 - x27 =G= 0;
e27..    x2 - x28 =G= 0;
e28..    x2 - x29 =G= 0;
e29..    x2 - x30 =G= 0;
e30..    x2 - x31 =G= 0;
e31..    x2 - x32 =G= 0;

e32..    x3 - x4 + 14*b33 + 36*b34 + 11*b35 + 27*b36 + 49*b37 + 26*b38 + 37*b39
       + 45*b40 + 21*b41 + 6*b42 + 48*b43 + 38*b44 + 37*b45 + 10*b46 + 16*b47
       + 35*b48 + 17*b49 + 7*b50 + 46*b51 + 26*b52 + 8*b53 + 40*b54 + 19*b55
       + 33*b56 + 5*b57 + 42*b58 + 22*b59 + 14*b60 + 51*b61 + 49*b62 + 7*b63
       + 10*b64 + 30*b65 + 14*b66 + 32*b67 + 24*b68 + 36*b69 + 14*b70 + 13*b71
       + 52*b72 + 16*b73 + 5*b74 + 35*b75 + 48*b76 + 11*b77 + 47*b78 + 27*b79
       + 24*b80 + 49*b81 + 17*b82 + 46*b83 + 53*b84 + 53*b85 + 10*b86 + 30*b87
       =E= 731;

e33..    x5 - x6 + 53*b33 + 48*b34 + 48*b35 + 12*b36 + 43*b37 + 42*b38 + 14*b39
       + 48*b40 + 16*b41 + 23*b42 + 25*b43 + 36*b44 + 54*b45 + 34*b46 + 45*b47
       + 51*b48 + 45*b49 + 46*b50 + 30*b51 + 38*b52 + 52*b53 + 21*b54 + 9*b55
       + 21*b56 + 15*b57 + 22*b58 + 12*b59 + 12*b60 + 19*b61 + 17*b62 + 38*b63
       + 17*b64 + 9*b65 + 30*b66 + 24*b67 + 48*b68 + 16*b69 + 34*b70 + 41*b71
       + 28*b72 + 52*b73 + 10*b74 + 8*b75 + 51*b76 + 40*b77 + 48*b78 + 46*b79
       + 30*b80 + 38*b81 + 21*b82 + 12*b83 + 35*b84 + 38*b85 + 17*b86 + 52*b87
       =E= 731;

e34..    x7 - x8 + 48*b33 + 34*b34 + 8*b35 + 5*b36 + 49*b37 + 21*b38 + 38*b39
       + 11*b40 + 26*b41 + 12*b42 + 30*b43 + 18*b44 + 23*b45 + 8*b46 + 55*b47
       + 46*b48 + 5*b49 + 10*b50 + 50*b51 + 52*b52 + 45*b53 + 42*b54 + 43*b55
       + 19*b56 + 25*b57 + 8*b58 + 27*b59 + 5*b60 + 41*b61 + 39*b62 + 52*b63
       + 33*b64 + 17*b65 + 5*b66 + 34*b67 + 11*b68 + 21*b69 + 16*b70 + 17*b71
       + 42*b72 + 23*b73 + 43*b74 + 5*b75 + 42*b76 + 47*b77 + 55*b78 + 32*b79
       + 47*b80 + 9*b81 + 26*b82 + 43*b83 + 50*b84 + 13*b85 + 30*b86 + 14*b87
       =E= 731;

e35..    x9 - x10 + 33*b33 + 34*b34 + 36*b35 + 34*b36 + 19*b37 + 19*b38
       + 30*b39 + 48*b40 + 32*b41 + 30*b42 + 26*b43 + 39*b44 + 47*b45 + 37*b46
       + 52*b47 + 33*b48 + 5*b49 + 39*b50 + 34*b51 + 42*b52 + 30*b53 + 33*b54
       + 19*b55 + 21*b56 + 38*b57 + 40*b58 + 9*b59 + 33*b60 + 48*b61 + 35*b62
       + 42*b63 + 26*b64 + 13*b65 + 23*b66 + 55*b67 + 27*b68 + 37*b69 + 30*b70
       + 20*b71 + 14*b72 + 5*b73 + 42*b74 + 49*b75 + 47*b76 + 24*b77 + 45*b78
       + 25*b79 + 24*b80 + 28*b81 + 54*b82 + 11*b83 + 53*b84 + 32*b85 + 25*b86
       + 19*b87 =E= 731;

e36..    x11 - x12 + 15*b33 + 9*b34 + 24*b35 + 43*b36 + 53*b37 + 54*b38
       + 29*b39 + 24*b40 + 11*b41 + 47*b42 + 24*b43 + 34*b44 + 29*b45 + 49*b46
       + 50*b47 + 39*b48 + 50*b49 + 36*b50 + 32*b51 + 42*b52 + 55*b53 + 21*b54
       + 11*b55 + 24*b56 + 45*b57 + 10*b58 + 30*b59 + 42*b60 + 38*b61 + 51*b62
       + 6*b63 + 48*b64 + 5*b65 + 25*b66 + 36*b67 + 53*b68 + 24*b69 + 10*b70
       + 22*b71 + 31*b72 + 53*b73 + 41*b74 + 10*b75 + 26*b76 + 35*b77 + 55*b78
       + 10*b79 + 29*b80 + 36*b81 + 37*b82 + 15*b83 + 36*b84 + 54*b85 + 22*b86
       + 55*b87 =E= 731;

e37..    x13 - x14 + 43*b33 + 28*b34 + 30*b35 + 30*b36 + 10*b37 + 26*b38
       + 32*b39 + 54*b40 + 26*b41 + 52*b42 + 34*b43 + 24*b44 + 21*b45 + 39*b46
       + 41*b47 + 47*b48 + 36*b49 + 27*b50 + 52*b51 + 7*b52 + 6*b53 + 52*b54
       + 13*b55 + 30*b56 + 32*b57 + 46*b58 + 41*b59 + 12*b60 + 44*b61 + 7*b62
       + 12*b63 + 32*b64 + 30*b65 + 38*b66 + 6*b67 + 36*b68 + 8*b69 + 34*b70
       + 34*b71 + 30*b72 + 31*b73 + 13*b74 + 49*b75 + 47*b76 + 48*b77 + 35*b78
       + 39*b79 + 29*b80 + 6*b81 + 35*b82 + 32*b83 + 7*b84 + 32*b85 + 40*b86
       + 33*b87 =E= 731;

e38..    x15 - x16 + 8*b33 + 30*b34 + 18*b35 + 16*b36 + 18*b37 + 21*b38
       + 24*b39 + 46*b40 + 47*b41 + 6*b42 + 48*b43 + 27*b44 + 10*b45 + 26*b46
       + 6*b47 + 36*b48 + 52*b49 + 14*b50 + 29*b51 + 43*b52 + 7*b53 + 8*b54
       + 26*b55 + 31*b56 + 10*b57 + 6*b58 + 7*b59 + 12*b60 + 33*b61 + 42*b62
       + 41*b63 + 37*b64 + 17*b65 + 55*b66 + 48*b67 + 31*b68 + 20*b69 + 17*b70
       + 21*b71 + 11*b72 + 19*b73 + 13*b74 + 34*b75 + 24*b76 + 35*b77 + 35*b78
       + 55*b79 + 31*b80 + 44*b81 + 29*b82 + 19*b83 + 46*b84 + 33*b85 + 41*b86
       + 22*b87 =E= 731;

e39..    x17 - x18 + 38*b33 + 42*b34 + 24*b35 + 46*b36 + 20*b37 + 11*b38
       + 32*b39 + 52*b40 + 24*b41 + 31*b42 + 45*b43 + 50*b44 + 47*b45 + 6*b46
       + 15*b47 + 53*b48 + 20*b49 + 24*b50 + 31*b51 + 40*b52 + 54*b53 + 10*b54
       + 40*b55 + 30*b56 + 50*b57 + 14*b58 + 44*b59 + 41*b60 + 42*b61 + 29*b62
       + 8*b63 + 24*b64 + 16*b65 + 27*b66 + 15*b67 + 31*b68 + 34*b69 + 42*b70
       + 28*b71 + 53*b72 + 17*b73 + 18*b74 + 48*b75 + 8*b76 + 19*b77 + 7*b78
       + 6*b79 + 35*b80 + 27*b81 + 33*b82 + 20*b83 + 25*b84 + 39*b85 + 55*b86
       + 51*b87 =E= 731;

e40..    x19 - x20 + 34*b33 + 13*b34 + 39*b35 + 19*b36 + 51*b37 + 13*b38
       + 22*b39 + 20*b40 + 24*b41 + 45*b42 + 30*b43 + 51*b44 + 24*b45 + 17*b46
       + 23*b47 + 22*b48 + 29*b49 + 36*b50 + 14*b51 + 33*b52 + 51*b53 + 17*b54
       + 35*b55 + 31*b56 + 39*b57 + 12*b58 + 47*b59 + 9*b60 + 46*b61 + 46*b62
       + 55*b63 + 25*b64 + 55*b65 + 38*b66 + 39*b67 + 51*b68 + 46*b69 + 6*b70
       + 15*b71 + 15*b72 + 47*b73 + 40*b74 + 10*b75 + 15*b76 + 52*b77 + 29*b78
       + 32*b79 + 26*b80 + 10*b81 + 42*b82 + 55*b83 + 6*b84 + 54*b85 + 34*b86
       + 32*b87 =E= 731;

e41..    x21 - x22 + 37*b33 + 42*b34 + 23*b35 + 41*b36 + 33*b37 + 14*b38
       + 40*b39 + 53*b40 + 14*b41 + 23*b42 + 37*b43 + 9*b44 + 14*b45 + 38*b46
       + 19*b47 + 24*b48 + 29*b49 + 55*b50 + 29*b51 + 40*b52 + 52*b53 + 54*b54
       + 16*b55 + 23*b56 + 8*b57 + 53*b58 + 23*b59 + 9*b60 + 52*b61 + 52*b62
       + 37*b63 + 33*b64 + 39*b65 + 55*b66 + 18*b67 + 17*b68 + 14*b69 + 54*b70
       + 14*b71 + 24*b72 + 21*b73 + 46*b74 + 28*b75 + 30*b76 + 29*b77 + 43*b78
       + 50*b79 + 53*b80 + 43*b81 + 24*b82 + 38*b83 + 39*b84 + 22*b85 + 49*b86
       + 7*b87 =E= 731;

e42..    x23 - x24 + 25*b33 + 47*b34 + 25*b35 + 29*b36 + 44*b37 + 22*b38
       + 10*b39 + 21*b40 + 5*b41 + 10*b42 + 35*b43 + 17*b44 + 20*b45 + 33*b46
       + 27*b47 + 39*b48 + 50*b49 + 17*b50 + 11*b51 + 25*b52 + 42*b53 + 50*b54
       + 19*b55 + 40*b56 + 37*b57 + 38*b58 + 22*b59 + 20*b60 + 5*b61 + 16*b62
       + 22*b63 + 25*b64 + 8*b65 + 43*b66 + 50*b67 + 47*b68 + 9*b69 + 5*b70
       + 12*b71 + 10*b72 + 10*b73 + 42*b74 + 22*b75 + 25*b76 + 20*b77 + 45*b78
       + 9*b79 + 15*b80 + 7*b81 + 15*b82 + 35*b83 + 44*b84 + 9*b85 + 50*b86
       + 28*b87 =E= 731;

e43..    x25 - x26 + 42*b33 + 33*b34 + 45*b35 + 6*b36 + 33*b37 + 6*b38 + 24*b39
       + 54*b40 + 9*b41 + 12*b42 + 48*b43 + 51*b44 + 16*b45 + 48*b46 + 8*b47
       + 21*b48 + 54*b49 + 46*b50 + 39*b51 + 23*b52 + 11*b53 + 28*b54 + 27*b55
       + 21*b56 + 30*b57 + 38*b58 + 52*b59 + 18*b60 + 43*b61 + 46*b62 + 42*b63
       + 29*b64 + 23*b65 + 32*b66 + 31*b67 + 52*b68 + 33*b69 + 51*b70 + 50*b71
       + 38*b72 + 7*b73 + 42*b74 + 34*b75 + 18*b76 + 35*b77 + 37*b78 + 35*b79
       + 33*b80 + 28*b81 + 18*b82 + 52*b83 + 34*b84 + 42*b85 + 24*b86 + 51*b87
       =E= 731;

e44..    x27 - x28 + 16*b33 + 6*b34 + 47*b35 + 30*b36 + 45*b37 + 37*b38
       + 16*b39 + 19*b40 + 5*b41 + 44*b42 + 45*b43 + 53*b44 + 22*b45 + 40*b46
       + 47*b47 + 55*b48 + 43*b49 + 34*b50 + 33*b51 + 6*b52 + 13*b53 + 15*b54
       + 36*b55 + 41*b56 + 39*b57 + 50*b58 + 38*b59 + 18*b60 + 36*b61 + 6*b62
       + 13*b63 + 47*b64 + 8*b65 + 5*b66 + 22*b67 + 48*b68 + 37*b69 + 34*b70
       + 11*b71 + 38*b72 + 22*b73 + 52*b74 + 35*b75 + 39*b76 + 37*b77 + 27*b78
       + 38*b79 + 24*b80 + 5*b81 + 16*b82 + 25*b83 + 14*b84 + 27*b85 + 6*b86
       + 51*b87 =E= 731;

e45..    x29 - x30 + 10*b33 + 51*b34 + 33*b35 + 23*b36 + 31*b37 + 34*b38
       + 32*b39 + 23*b40 + 38*b41 + 32*b42 + 40*b43 + 30*b44 + 14*b45 + 19*b46
       + 37*b47 + 48*b48 + 36*b49 + 33*b50 + 27*b51 + 20*b52 + 14*b53 + 50*b54
       + 54*b55 + 34*b56 + 50*b57 + 14*b58 + 54*b59 + 9*b60 + 37*b61 + 55*b62
       + 55*b63 + 42*b64 + 51*b65 + 32*b66 + 10*b67 + 26*b68 + 11*b69 + 38*b70
       + 45*b71 + 44*b72 + 14*b73 + 30*b74 + 19*b75 + 24*b76 + 44*b77 + 52*b78
       + 16*b79 + 24*b80 + 29*b81 + 39*b82 + 39*b83 + 39*b84 + 33*b85 + 37*b86
       + 17*b87 =E= 731;

e46..    x31 - x32 + 28*b33 + 47*b34 + 16*b35 + 32*b36 + 28*b37 + 16*b38
       + 32*b39 + 15*b40 + 11*b41 + 8*b42 + 21*b43 + 33*b44 + 15*b45 + 54*b46
       + 22*b47 + 55*b48 + 13*b49 + 47*b50 + 19*b51 + 33*b52 + 35*b53 + 15*b54
       + 44*b55 + 55*b56 + 39*b57 + 28*b58 + 39*b59 + 23*b60 + 6*b61 + 20*b62
       + 36*b63 + 29*b64 + 12*b65 + 48*b66 + 6*b67 + 35*b68 + 8*b69 + 33*b70
       + 46*b71 + 15*b72 + 37*b73 + 11*b74 + 44*b75 + 48*b76 + 9*b77 + 11*b78
       + 47*b79 + 18*b80 + 54*b81 + 10*b82 + 46*b83 + 34*b84 + 20*b85 + 35*b86
       + 33*b87 =E= 731;

Model m / all /;

m.limrow=0; m.limcol=0;

Solve m using MIP minimizing x1;

embeddedCode Connect:
- PythonCode:
   code: |
     x = 0
     for i in range(1000):
      for j in range(1000):
       for k in range(1000):
        for l in range(1000):
         x = x + 1
endEmbeddedCode
execError = 0;
embeddedCode Python:
x = 0
for i in range(1000):
 for j in range(1000):
  for k in range(1000):
   for l in range(1000):
    x = x + 1
pauseEmbeddedCode
execError = 0;
continueEmbeddedCode:
x = 0
for i in range(1000):
 for j in range(1000):
  for k in range(1000):
   for l in range(1000):
    x = x + 1
endEmbeddedCode
execError = 0;
embeddedCode GAMS:
set i / 1*1000 /; alias (i,j,k,l);
scalar x /0/;
loop((i,j,k,l), x = x+1);
endEmbeddedCode
execError = 0;
$if set SKIPEXECERROR $exit
set i / 1*1000 /; alias (i,j,k,l);
scalar x /0/;
loop((i,j,k,l), x = x+1);
$offEcho

$ifThen set interactive
* This requires to hit interrupt or Ctrl-C 25 times
$  call.checkErrorLevel gams stopme lo=%gams.lo% --SKIPEXECERROR=1
$  call gams stopme lo=%gams.lo%
$  if not errorLevel 1 $abort expect error from previous run
$else
$onEmbeddedCode Python:
import sys
import threading
  
def interrupt_gams(job,num,secs):
    import time
    time.sleep(2)
    for i in range(num):
        time.sleep(secs)
        job.interrupt()

gams.wsWorkingDir = '.' 
job = gams.ws.add_job_from_file("stopme.gms")
  
# start thread asynchronously that interrupts the GamsJob after 1 seconds
threading.Thread(target=interrupt_gams, args=(job,12,1)).start()

# start GamsJob
opt = gams.ws.add_options()
opt.defines["SKIPEXECERROR"] = "1"
job.run(opt,output=sys.stdout)

# start thread asynchronously that interrupts the GamsJob after 1 seconds
threading.Thread(target=interrupt_gams, args=(job,13,1)).start()
try:
   job.run(output=sys.stdout)
except Exception as e:
   assert type(e)==GamsExceptionExecution
   assert e.get_rc()==3
$offEmbeddedCode
$endIf