The Save and Restart Feature

GAMS saves the information provided in input files in intermediate - mostly binary - files, called work files or scratch files. Some of these files are used to exchange information between GAMS and the solvers. They are usually deleted just before a GAMS run is complete. However, these intermediate files may be used to process an input file, save the result and later reload this file and continue with processing another input file. Thus, input files may be processed sequentially through the use of the intermediate files. This is a useful feature that can help to reduce the required time when, e.g., several runs of similar models are being made, all of them sharing an equal large initialization part.

The same process may be described in a different way. Assume a large GAMS program is run and an output file is generated, as usual. Suppose the large program is split in two parts. The first part is run and the resulting work file is saved along with the resulting listing file. Then the second part is run after reading in the data from the work file saved previously and a new listing file is generated for the second part. The content of the two listing files will be the same as the content of the output from the very first run when the large program was processed without interruption. Only the arrangement of the content will slightly differ. Splitting the files makes it possible to interrupt a GAMS task and restart it later without loss of information. Furthermore, changes could be made or errors corrected in the later parts.

Note
The work file preserves all information (including declarations, values, option settings and dollar command line parameters) known to GAMS at the end of the run.
The work file is not machine specific and thus is portable between platforms. However, a work file that has been generated with one version of GAMS cannot be used for a restart with an older GAMS version.

This chapter illustrates the basics of the save and restart feature in Section Basic Usage and presents some use cases in Section Use Cases. Preventing unauthorized access to and obfuscating the content of work files is discussed in Sections Secure Work Files and Obfuscated Work Files, respectively. An overview of all command line parameters for saving and restarting in GAMS is given in Section Solve and Restart Options (chapter The GAMS Call and Command Line Parameters).

Basic Usage

The mechanism to break up the compilation of a large input file into many components and stages is provided by the command line parameters save and restart.

The following demonstrates saves and restarts with the well known transportation model [TRNSPORT]. First, the code is split into three parts, resulting in the files tranmodel.gms, transolve.gms, and tranreport.gms. The file tranmodel.gms contains the first part of the model up to and including the model statement:

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 1000 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/case per 1000 miles" /90/ ;

Parameter c(i,j)  "transport cost in $1000/case" ;
c(i,j) = f * d(i,j) / 1000 ;

Variables
    x(i,j)  "shipment quantities in cases"
    z       "total transportation costs in 1000$" ;
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/ ;

The file transolve.gms contains the solve statement:

solve transport using lp minimizing z;

And the third file, tranreport.gms, contains the display statement:

display x.l, x.m ;

Observe that concatenating the three files (in the right order) results in the original model [TRNSPORT].

Saving The Work File

The information in tranmodel.gms may be stored by using the following call to GAMS:

> gams tranmodel save=s1

This command line statement creates the output file tranmodel.lst and the work file s1.g00 in the current working directory. Observe that actually eight save files are created by GAMS. For information on the names of these save files, see the detailed description of the command line parameter save.

Note that the command line parameter s is a synonym to save.

Restarting from the Work File

Consider the following call:

> gams transolve restart=s1

GAMS reads the work file named s1.g00 and regenerates the information stored in tranmodel.gms. Then transolve.gms is run and the result is as if the a concatenation of tranmodel.gms and transolve.gms had been executed. Note, that the output file tranmodel.lst will contain the echo print of the model and transolve.lst will contain the echo print of the solve statement and all the output generated by the solve.

Note that the command line parameter r is a synonym of restart.

Observe that a restarted run always requires a GAMS input file to continue with. The restart does not alter work files. They may be used repeatedly to continue a particular run many times, possibly with many different continuation input files.

A Sequence of Saves and Restarts

In case there are more than two files that should be run sequentially, the second and any other non-final run will have to generate input files for a following restart. Therefore, their workfiles need to be saved.

Following the splitup of model [TRNSPORT] into the three files tranmodel.gms, transolve.gms, and tranreport.gms, a sequence of GAMS calls that would run the whole trnsport model could be as follows:

> gams tranmodel       s=s1
> gams transolve  r=s1 s=s2
> gams tranreport r=s2

The listing file of tranreport.gms will contain the compilation output with the echo print of the display statement, the final execution summary with the output generated from the display statement and the file summary. The listing files of all three input files together will have the same content as trnsport.lst (generated by a run of trnsport.gms).

Observe that the three files could also have been processed with a sequence of $include file statements. The advantages of using the save and restart feature instead are given in section Use Cases below.

Avoiding Common Mistakes

A common mistake that occurs when using the save and restart feature is running GAMS on the same file twice, e.g.,

> gams trnsport s=trans
> gams trnsport r=trans

In this case all the data and equation definitions are repeated, which will cause compilation errors for the second run as in GAMS each data item may be defined only once.

Further, it is the responsibility of the modeler to ensure that the contents of the input file matches that of the work file, although the compiler will issue errors if it detects any inconsistencies, such as references to symbols not previously declared.

Prefixing Symbols in the Work File

Assume writing some reporting code that works off a restart file and new symbol names that have not been used in the previous program are required. GAMS offers a convenient and systematic way to achieve this by prefixing all symbols in the work file with a specified string. Consider the following example, again using the transportation model [TRNSPORT]:

> gams trnsport s=prefixed symPrefix=aa_

This solves the model and saves the work file prefixed.g00. The command line parameter symPrefix has the effect that all symbols in the work file are prefixed with aa_. For the next step, consider the following simple reporting code, saved in a file called report.gms:

Scalar i / 0 /;
loop(aa_i, i = i+1);
display 'number of canning plants', i;

Note that this code will be run with a restart from the work file prefixed.g00. Therefore, the looping set aa_i is identical to the set i in the model [TRANSPORT]. Since all symbols from the original model have been prefixed, convenient symbol names can be used for reporting purposes. The run of report.gms is achieved by the following call:

> gams report r=prefixed

The resulting listing file contains the following output:

----     76 number of canning plants
            PARAMETER i                    =        2.000

Use Cases

The basic function of a work file is to preserve information that has been expensive to produce. The following discusses several use cases for work files.

Separation of Model and Data

The separation of model and data is one of the core principles of the GAMS modeling paradigm. Using the save and restart feature helps to exploit this separation.

Separation of model and data will be illustrated on the transportation model [TRNSPORT]. First, consider a GAMS file transportmodel.gms which contains only the algebraic representation of the transportation problem, obtained by removing all data and execution statements from [TRNSPORT]:

Sets i   canning plants
     j   markets

Parameters  a(i)    "capacity of plant i in cases"
            b(j)    "demand at market j in cases"
            c(i,j)  "transport cost in 1000$/case"
            d(i,j)  "distance in 1000 miles"  ;

Scalar f  "freight in $/case per 1000 miles"

Variables   x(i,j)  "shipment quantities in cases"
            z       "total transportation costs in 1000$"  ;
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/ ;

Second, consider a GAMS file transportdata.gms that contains the data of the model as well as the solve and display statements:

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

Parameters  a(i)  / seattle     350
                    san-diego   600  /
            b(j)  / new-york    325
                    chicago     300
                    topeka      275  /

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

Scalar f / 90 / ;

c(i,j) = f * d(i,j) / 1000 ;

Solve transport using lp minimizing z ;
Display x.l, x.m ;

The second file (transportdata.gms) cannot be run alone as the definition of model transport is missing. However, one may first run the first file (transportmodel.gms) and save its work file. Then one can restart from this work file to run the second file:

> gams transportmodel.gms s=transmod
> gams transportdata.gms  r=transmod

Advanced Separation of Model and Data

In the previous example some execution time statements namely the assignment of c, the solve, and the display where performed in the data file. If the model execution logic is more complex we do not want to add this to the data file. Hence we create in this example a restart file from this first file but will only compile, but not execute (see difference between compile and execute phases in section GAMS Compile Time and Execution Time Phase):

$onEmpty
Sets i(*)   canning plants / /
     j(*)   markets        / /

Parameters  a(i)    "capacity of plant i in cases" / /
            b(j)    "demand at market j in cases"  / /
            c(i,j)  "transport cost in 1000$/case"
            d(i,j)  "distance in 1000 miles"       / /;

Scalar f  "freight in $/case per 1000 miles" / 0 /;

c(i,j) = f * d(i,j) / 1000 ;

Variables   x(i,j)  "shipment quantities in cases"
            z       "total transportation costs in 1000$"  ;
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 transport using lp minimizing z ;
Display x.l, x.m ;

Second, we consider a file that contains the data of the model but no other execution time statements. Because we already have empty data statements (/ /) for the data items in the first file, we need to instruct the compiler to allow a second data statement with the real data using $onMulti:

$onMulti
Sets   i   / seattle, san-diego /
       j   / new-york, chicago, topeka / ;

Parameters  a(i)  / seattle     350
                    san-diego   600  /
            b(j)  / new-york    325
                    chicago     300
                    topeka      275  /

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

Scalar f / 90 / ;
$offMulti

In order to run the model we first compile, but not execute the first model (see command line parameter action=c) and create a save file. Next, we run the second model. This does a continued compilation, it compiles the data statements from the second files and then executes the execution time statements from the first (c(i,j)=..., solve ..., and display ...) and second (here there are none).

> gams transportmodel.gms action=c s=transmod
> gams transportdata.gms  r=transmod

Generating Concise Listing Files

By default a GAMS listing file has many components, see chapter GAMS Output for details. In case a more concise listing file is needed, the save and restart feature may be used to generate such a file.

Recall the reorganization of the transportation model [TRNSPORT] into a model file trnsportmodel.gms and a data-and-solve file trnsportdata.gms from the previous section. Now consider the addition of two further files. The first one, called trnsportreport.gms, contains post-solution computations for reporting:

Parameter m(*,*) 'movement of commodities in cases';
m(i,j)             = x.l(i,j);
m('total',j)       = sum(i, x.l(i,j));
m(i,'total')       = sum(j, x.l(i,j));
m('total','total') = sum(j, m('total',j));

The second one, called trnsportdisplay.gms, contains only a display statement:

Option decimals = 0;
Display m;

Using these four files, the following save and restart sequence can be called:

> gams trnsportmodel            s=trans1
> gams trnsportdata    r=trans1 s=trans2
> gams trnsportreport  r=trans2 s=trans3
> gams trnsportdisplay r=trans3

The output file trnsportdisplay.lst is brief. Apart from the echo print, the execution time and the file summary, it contains only the output generated by the display statement:

----     52 PARAMETER m  movement of commodities in cases

             new-york     chicago      topeka       total

seattle            50         300                     350
san-diego         275                     275         550
total             325         300         275         900

In this way it is possible to create output files that are concise and contain only the information needed, while at the same time the more detailed output is stored in other listing files and may be inspected if needed.

Incremental Program Development

GAMS programs are often developed in stages. A typical approach is to start with set statements, tables and data manipulations, then equations are declared and defined, followed by model and solve statements and finally assignments for generating reports. As each piece of the model is built, it should be run and checked for errors by inserting diagnostic display and abort statements. As confidence grows that the parts of the model are correct, it is useful to save the completed parts in a work file. Subsequently, it is possible to work only on the piece under active development by restarting from the saved work file and thus reducing running time and the amount of output produced in each of the development runs.

This approach is especially useful when working on the results report part, since the setup and solution of a model instance is typically dominating the computing time, while the report part has to be run often to get all details of setting up content and layout into a satisfying form. Thus, the model may be generated and solved and the result saved in a work file. One may then restart from the work file while developing the report.

Tracking a Sequence of Difficult Solve Statements

In many cases where solves are known to be difficult and expensive, it may be too risky to let GAMS process a job containing many solve statements. The risk is that if one solve does not proceed to normal completion, then the following solve will not be possible or will start from a bad initial point and much time and effort will be wasted.

An alternative is to request one solve at a time and save the work file. By doing so, the output of each solve can be carefully inspected before proceeding. If everything is as expected, the job can be restarted and the next solve be executed. If an error has occurred, the previous solve may be repeated, maybe with a different initial point or modified working limits such as iteration or time limits.

What-If Analysis

Many modeling exercises involve a 'what if ' analysis, in which a base case is defined and the point of the study is to see how the system changes when circumstances change, either naturally or by design. Often, the effect of many different changes to the base case are considered separately.

The save and restart feature facilitates such analyses. The base case may be saved using a work file and then all desired scenarios may be run separately by restarting from the same work file. Each scenario probably involves only doing some changes to the data (e.g., coefficients in equations or variable bounds), solving the changed model (the solution of the base case will then automatically be used as a starting point), and reporting.

The GAMS Runtime License

A GAMS runtime license can be used to restrict users to run an existing model with their own data without the possibility to modify the model itself.

For example, recall the separation of model [TRNSPORT] from Section Separation of Model and Data above into a model file trnsportmodel.gms and a data and solve file trnsportdata.gms. The developer of the model may run trnsportmodel.gms with the command

> gams trnsportmodel s=trans

to generate a work file trans.g00. She then distributes this work file and the data and solve file trnsportdata.gms to endusers. If the endusers have a run-time license for GAMS, they are not able to see the model or change it by adding any new variables or equations, but they can run the model by the command

> gams trnsportdata r=trans

Observe that the endusers have full control of the data, e.g., are able to manipulate the elements of sets or the values of the various parameters.

Secure Work Files

When models are distributed to users other than the original developers or embedded in applications to be deployed by other developers, issues of privacy, security, data integrity and ownership arise. One may have to hide, protect or purge some parts of the model before it can be released. The information to be protected can be of numeric or symbolic nature. Examples include the following:

Privacy

A Social Accounting Matrix supplied by a statistical office is required in a general equilibrium model to be used by the Ministry of Finance. The data from the statistical office needs to be protected for obvious privacy reasons and the model experiments are used to evaluate policy options that are highly confidential. Most of the model structure is public, most of the data however is private and model results need to be transformed in such a way as to prohibit the discovery of the original data.

Security

Components of a model contain proprietary information that describes mathematically a chemical reaction. The associated algebra and some of the data are considered of strategic importance and need to be hidden completely. However, the final model will be used at different locations around the world.

Integrity

Data integrity safeguards are needed to assure the proper functioning of a model. Certain data and symbolic information need to be protected from accidental changes that would compromise the operation of the model.

To address these issues, so called secure work files have been introduced to GAMS. Such a work file behaves like any other work file but it is locked to a specific user's license file. The content of a secure work file protected against unauthorized access via the GAMS license mechanism.

Attention
A special GAMS license is required to create secure work file, see also Usage.
The security features of secure work files are not extended to the solver level. As a consequence, full information about a model instance can be extracted on the GAMS solver level by a user that is authorized to solve the model. See Limitations for more information.

An Introductory Example

The well-known transportation model [TRNSPORT] will be used again to illustrate the creation and deployment of a secure work file. Assume one wants to distribute this model but there are concerns about proprietary formulations and data. In addition, one would like to prevent that the user does unintentional modifications to the model. It is assumed that the objective function and the supply constraints are to be hidden from other users and only the demand figures should be allowed to be changed. Data that is not needed any more will be purged as well.

First, a copy of the model from the model library is created, the model is run and a normal work file t1 is created:

> gamslib trnsport
> gams trnsport s=t1

Next, a file t2.gms with access control commands is created,

 $eolcom //
 $protect all             // make all symbols read only
 $purge   d f             // remove items d and f
 $hide    cost supply a   // make objective invisible
 $expose  transport b     // allow changes to b

and a secure work file t2.g00 is created by executing t2.gms with a restart from t1.g00:

> gams t2 r=t1 s=t2 plicense=target

The newly created work file is secure since the access control commands were activated with the privacy GAMS license option PLicense. This command line parameter specifies the name of the target user's license file. The effect is that the work file t2.g00 can now only be read with the target license file.

The log output will contain the following lines:

GAMS Rev 124  Copyright (C) 1987-2001 GAMS Development...
Licensee: Source User Name
          Source Company Name
*** Creating a Secure Restart File for:
***       Target User Name
***       Target Company Name
--- Starting continued compilation
--- T2.GMS(6) 1 Mb
--- Starting execution
*** Status: Normal completion

The three lines starting with *** are a recap of the content of the target license file. From now on, the source and the target licenses are 'burned into' this file and all its descendants. One can now send the restart file to the target user or system.

The target user may run the model with new data, add new GAMS statements and create new work files. However, there are two restrictions: some of the symbols are hidden and this model can only be executed using the target license file.

For example, the target user may want to half the demand and compare the original solution with the new one. The following file, called t3.gms, will accomplish this:

Parameter rep   'summary report';
rep(i,j,'base') = x.l(i,j);
b(j) = b(j)*0.5;

solve transport minimizing z using lp;

rep(i,j,'half') = x.l(i,j);
display rep;

This new file may be executed on the target system, restarting from the work file t2.g00:

> gams t3 r=t2

The resulting log file will contain the following lines:

GAMS Rev 124 Copyright (C) 1987-2001 GAMS Development...
Licensee: Target User Name
                Target User Company
*** Restarting from a Secure Restart File created by:
***       Source User Name
***       Source Company Name
--- Starting continued compilation
--- T3.GMS(5) 1 Mb
...

Note that the originator/owner of the secure work file is mentioned by name. A similar message will be contained in the listing file:

...
EXECUTION TIME    =    0.000 SECONDS   1.1 Mb   WIN201-124

**** Secure Save/Restart File Source:
        Source User Name
        Source Company Name
**** Secure Save/Restart File Target:
        Target User Name
        Target User Company
...

A more detailed inspection of the listing file shows that the hidden variables and equations do not appear in the usual equation and variable listings and the solution print. The hidden items can only be accessed via a public (exposed) model and a solve statement. However, note that the full model instance may still be accessed by the target user, see Limitations.

In the following, secure work files and the access control commands are described in more detail.

Usage

Secure work files control access to symbolic and numeric information and can only be read by a specific GAMS user. The initial creation or additions to access control requires a special GAMS license. Saving secure work files without new access controls does not require a special GAMS license. The creation or addition of access control is signaled by the use of the GAMS command line parameter PLicense, which gives the name of a privacy license file. The shortcut PLICENSE=LICENSE sets the privacy license to the current license file. This is convenient when experimenting with access controls.

When a secure work file is written for the first time, the first and second lines of the current license file and the privacy license file are inserted into the work file. This information cannot be changed any more and the original source and the intended target users are locked into the work file.

A secure work file may be used just like any other work file and new work files may be derived from secure files. However, their use is restricted to the target user specified with the command line parameter PLicense. The target user can, if licensed, add access controls to an existing secure file by using the parameter PLICENSE=LICENSE but cannot change the original information about source and target users.

There are four access control commands (ACCs) that are processed during the compilation phase. These commands can be inserted anywhere in the program. They are processed in chronological order and have the following syntax:

$acc ident1 ident2 ...
$acc all

Here ident1 and ident2 are GAMS identifiers previously defined in the program and acc denotes one of the four access control commands:

Dollar Control Option Description
purge Removes the objects and all data associated.
hide Hides the objects but allows them to be used in model calculations.
protect The objects cannot be modified but they may be used in model calculations.
expose Removes all privacy restrictions, the symbols will be reverted to their original state.

The keyword all applies the ACCs to all identifiers defined up to this point in the GAMS source code. Note that ACCs may be changed and redefined within the same GAMS program. However, identifiers inherited from a restart file cannot be changed.

A Practical Example

This section uses the transportation model [TRNSPORT] to show how to hide input data and results from the target user. The target user will be allowed to view percentage changes from an unknown base case only. In addition to the original model, a data initialization and a report model will be introduced.

First, a method to calculate input data is defined. As the GAMS language does not offer the definition of methods (or functions), here a model is used to define algebraically the desired correspondence between the input and output of the method we wish to emulate. Execution of the method will then correspond to solving the model. The model is the following:

$include trnsport.gms

Variable newc(i,j)    'new tansport data';
Equation defnewc(i,j) 'definition of new transport data';
defnewc(i,j).. newc(i,j) =e= f*d(i,j)/1000;

Model getc            'compute new transport data' / defnewc /;
Solve getc using cns;

By solving model getc (see Constrained Nonlinear System (CNS) for details on problem type CNS), the variable newc(i,j) will obtain the value of f*d(i,j)/1000 in the variable level attributes. Thus, newc.l corresponds to parameter c in the original model.

Next, the objective function of the original model is changed to reflect

economies of scale. Furthermore, a base case value basex is computed for later use in the reporting model:

Scalar   beta        'scaling exponent' / 1.1 /;
Equation newcost     'economies of scale objective function';
newcost.. z =e= sum((i,j), newc.l(i,j) * x(i,j)**beta);

Model estrans / newcost, supply, demand /;
solve estrans using nlp minimizing z;

Parameter basex(i,j)  'base values of x';
basex(i,j) = x.l(i,j);

Finally, a method to transform the results of model estrans to the relative change with respect to the base case is defined. As for the computation of the input data (newc), a model is used to emulate this method:

Variable delta(i,j)      'percentage change from base values';
Equation defdelta(i,j)   'definition of delta';
defdelta(i,j)$basex(i,j).. delta(i,j) =e= 100*(x.l(i,j)-basex(i,j))/basex(i,j);

Model rep / defdelta /;
solve rep using cns;

Assume the GAMS code above has been saved in a file p1.gms. Running GAMS on this file,

> gams p1 s=p1

creates a work file with the name p1.g00.

In the following, some test runs similar to those that are expected to be defined by the target user are made. Three scenarios to be solved in a loop are defined in file u1.gms:

Set       s        / one, two, three /;
Parameter sbeta(s) / one 1.25, two 1.5, three 2.0 /
          sf(s)    / one 85,   two 75,  three 50 /;
Parameter report   'summary report';

loop(s,
   beta = sbeta(s);
   f    = sf(s);
   solve getc using cns;
   solve estrans using nlp minmizing z;
   solve rep using cns;
   report(i,j,s) = delta.l(i,j);
   report('','beta',s) = beta;
   report('','f',s)    = f;
   report('obj','z',s) = z.l
);

display report;

File u1.gms can be executed with a restart from the work file p1.g00:

> gams u1 r=p1

The display statement generates the following output:

----    109 PARAMETER report summary report

                           one         two       three

seattle  .new-york      -4.050      -6.967      -8.083
seattle  .chicago      -18.797     -27.202     -31.550
seattle  .topeka       233.958     348.468     404.187
san-diego.new-york       3.605       6.201       7.194
san-diego.chicago       28.138      40.719      47.228
san-diego.topeka       -15.512     -23.104     -26.799
         .beta           1.250       1.500       2.000
         .f             85.000      75.000      50.000
obj      .z            526.912    1652.963   13988.774

Note that all symbols are still completely exposed. Access controls need to be added to the model p1.gms before it can be made available to the target client. The information to be protected is the original distance matrix and derived information. A recommended procedure is to first hide everything and then enable access to only selected parts of the model. The access control information is collected in the file s1.gms:

$hide all
$expose getc estrans rep
$expose i j z delta
$expose f beta a b

Using the initial workfile p1, a secure work file s1.g00 is created by executing

> gams s1 r=p1 s=s1 plicense=license

To test the system from the target users point of view, the license of the current GAMS system is used also for the target user.

To test the secure work file, problem u1.gms is run again, restarting from the work file s1:

> gams u1 r=s1

Inspecting the resulting listing file, one observes that equation, variable and solution listings related to the hidden variables are not shown anymore. Any attempt to reference a hidden variable will cause a compilation error.

Limitations

One of the design goals for secure work files has been to minimize the impact on other components of the GAMS system. Solvers used within a secure environment should work as if called within a normal environment. This implies that certain information about a model can easily be recovered by using solvers like CONVERT or solver options like writelp for CPLEX, writemps for CBC, or gams/interactive for SCIP.

For example, consider the secure work file t2.g00 from Section An Introductory Example. The target user could now reproduce the complete model instance, including the hidden equation supply or the objective function cost by running the following GAMS code, restarting from t2.g00:

option mip = scip;
transport.optfile = 1;
$echo gams/interactive = "display prob quit" > scip.opt
solve transport min z using mip;

This produces the log output:

...
original problem has 6 variables (0 bin, 0 int, 6 cont) and 5 constraints

STATISTICS
  Problem name     : r
  Variables        : 6 (0 binary, 0 integer, 0 implicit integer, 6 continuous)
  Constraints      : 0 initial, 5 maximal
OBJECTIVE
  Sense            : minimize
VARIABLES
  [continuous] <x(seattle,new-york)>: obj=0.225, original bounds=[0,+inf]
  [continuous] <x(seattle,chicago)>: obj=0.153, original bounds=[0,+inf]
  [continuous] <x(seattle,topeka)>: obj=0.162, original bounds=[0,+inf]
  [continuous] <x(san-diego,new-york)>: obj=0.225, original bounds=[0,+inf]
  [continuous] <x(san-diego,chicago)>: obj=0.162, original bounds=[0,+inf]
  [continuous] <x(san-diego,topeka)>: obj=0.126, original bounds=[0,+inf]
CONSTRAINTS
  [linear] <supply(seattle)>: <x(seattle,new-york)>[C] +<x(seattle,chicago)>[C] +<x(seattle,topeka)>[C] <= 350;
  [linear] <supply(san-diego)>: <x(san-diego,new-york)>[C] +<x(san-diego,chicago)>[C] +<x(san-diego,topeka)>[C] <= 600;
  [linear] <demand(new-york)>: <x(seattle,new-york)>[C] +<x(san-diego,new-york)>[C] >= 325;
  [linear] <demand(chicago)>: <x(seattle,chicago)>[C] +<x(san-diego,chicago)>[C] >= 300;
  [linear] <demand(topeka)>: <x(seattle,topeka)>[C] +<x(san-diego,topeka)>[C] >= 275;
END
...

Note, that this approach is only possible for the target user, since its license is required to unlock the work file. Further, the original algebra of the model is still protected by GAMS, only the generated model instance (with original variable and equation names) and variable and equation symbols can be made available this way.

A further limitation of secure work files is that the source and target license files are locked to the secure work file and cannot be changed. If the target user receives a new license file (due to a system upgrade, for example), the secure work file cannot be read any more by the target user and must be recreated.

Obfuscated Work Files

GAMS offers a limited set of facilities to change all the names and other documentation related to a specific model run in a work file. This can be useful if the model has to be solved in an untrusted computing environment, e.g., a public cloud facility. When the results are back in the secure environment, the changed names can be transformed back to their original.

A work file that has all strings for symbols, set elements and explanatory text replaced with obfuscated names is called an obfuscated work file. GAMS obfuscates by keeping the original length of the symbol name or label name, but replaces them by a sequence of strings. For example, for symbols of length 3 it creates A00, A01, A02, ..., Z__. The method used for explanatory text is similar, but here GAMS always uses the single quote character and thus may create many weird looking labels. In addition to item names, labels and explanatory text, titles and subtitles in the listing file are obfuscated. Observe that other strings that have some meaning in the execution of GAMS, e.g., file names, cannot be changed. Despite of the changes in the string pool, a obfuscated work file has all the capabilities of a normal work file.

Recall from Section Saving The Work File that work files are created with the command line parameter save. Obfuscated work files are created with the variant saveobfuscate. The creation of an obfuscated work file is often combined with the creation of a regular work file, as the latter will be necessary to translate information from an obfuscated work file back to the name space of the original model.

In the following, the intended use of obfuscated work files is illustrated. First, a GAMS model (here [TRNSPORT]) is compiled into a regular and an obfuscated work file:

> gamslib trnsport
> gams trnsport action=compile s=0named so=0obfuscated

Note, that the command line parameter action=compile is used to only compile, but not execute, the model. Observe that the name of the regular work file is 0named.g00 and the name of obfuscated work file is 0obfuscated.g00.

In the next step, the obfuscated work file is moved to a non-secure machine and GAMS is restarted from this work file on an empty GAMS model file. This executes the original model (here trnsport), but with all names obfuscated. The outcome of this execution is saved in another, still obfuscated, work file 1obfuscated.g00.

> echo *Empty > empty.gms
> gams empty r=0obfuscated s=1obfuscated

The work file 1obfuscated.g00 is now brought back to a trusted machine. To obtain the results, say the marginal values of the supply equation, in a non-obfuscated form, GAMS is executed again on a model that writes out values of supply.m to a GDX file supply.gdx. This model is restarted from the obfuscated work file 1obfuscated.g00, but additionally the originally created non-obfuscated work file 0named.g00 is passed in via the command line parameter RestartNamed (short: rn):

> echo "execute_unload 'supply', supply.m;" > unload.gms
> gams unload r=1obfuscated rn=0named

Recall, that the work file 0named.g00 resulted from the initial compilation and contains the names from the original namespace. It never left the trusted environment. The effect of combining options r and rn is that all content from the obfuscated work file is taken, except for the names of symbols and labels, the explanatory texts, and the listing file titles and subtitles, which are read from the work file specified via rn.

GAMS automatically performs the following three checks to ensure that the named and obfuscated work files are consistent:

  1. The number of labels and symbols must be identical.
  2. The size of the string pool must be identical.
  3. The first 10 labels point to the same addresses in the string pool.

The first two checks imply that the execution in the obfuscated name space cannot introduce new symbols or labels or even new strings (e.g., from display 'this is a new string'). Therefore, the empty GAMS program that was used to execute from the obfuscated work file above can hardly be replaced by any useful code since the obfuscated symbols and labels are not known.