Table of Contents
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 control options) 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 (unless command line parameter forceWork is set).
- Absolute or relative path names (e.g. for put files) that do not exist or have the wrong directory separator may cause execution errors. Moreover, if the code in the work file executes a program that might not exist on another platform (e.g. gdxxrw on Linux) the GAMS execution might also result in execution errors.
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 Save 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.
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.
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:
- The number of labels and symbols must be identical.
- The size of the string pool must be identical.
- 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.