Some General Comments

Nowadays the objected-oriented APIs are the most efficient and elegant way to interact with the GAMS system. They allow the effective communication of data, and do parameterized runs of GAMS. This whole chapter describes a much more basic interaction of GAMS through calling the GAMS executable from different environments. This still can be useful, e.g. if no object-oriented API is available for the particular target language (e.g. VBA).

While the principle of calling the GAMS executable holds for all operating systems, this chapter often focuses on the Windows platform.

One of the interesting problems one faces when spawning GAMS.EXE in a Windows environment is multi-threading. If one does not take precautions, a call to Shell (VB function) or CreateProcess (Win32 API function) causes GAMS to run asynchronously: the function will return while GAMS is still running. In order to read the results one would need to wait until the GAMS job has finished. The machinery for this requires some Windows trickery, and for Visual Basic version 6 and Delphi version 4 we have implemented some small examples that illustrate how this can be done.

Another issue that needs to be addressed is that GAMS needs a place to put its scratch files. By default this is the current directory, a concept that is not always clear in a windowing environment. A good way of dealing with his is to set both the current drive and the current directory before running the GAMS job. It should be noted that GAMS needs write permission there. In the examples we use the Windows TEMP directory for this, but in a real application you may want to use a designated directory. The Windows TEMP directory is found by calling the API function GetTempPath.

The GAMS architecture

GAMS itself is a 32 bit console mode application. In fact it is not a single program, but a driver program (GAMS.EXE) that executes in turn the GAMS language compiler (GAMSCMEX.EXE) or one of the solvers. For a model with a single solve statement, GAMS.EXE will first call GAMSCMEX to compile the GAMS model. Then GAMSCMEX will start executing the internal code that was generated by the compiler. As soon as it hits the instructions belonging to a SOLVE statement it will generate model instance, and GAMSCMEX will exit. Then GAMS.EXE will spawn a solver capable of solving the model. As soon as the solver is finished, GAMS.EXE will execute GAMSCMEX again so it can read the solution and can continue with executing instructions.

Spawning GAMS from VBA

Visual Basic for Applications (VBA) is a programming language that is built into most Microsoft Office applications, e.g. Excel and Access. A VBA program may include modules, which can be imported from files, i.e. in the VBA editor you can choose menu “File”→“Import File”. The GAMS distribution includes some VBA modules, which can be found from:

For further details, please inspecte the VBA part of the examples below.

A Simple Example

This very simple example shows how GAMS can be invoked from an Excel spreadsheet. The "example spreadsheet"has a button, which will cause GAMS to run the trnsport.gms model stored in c:/tmp. There is no data exchange.

A more complete application will write an include file for a GAMS model, and will import a comma delimited file with results when the run is finished. An example of such a complete application is described in http://www.gams.com/mccarl/excelgams.pdf.

Sudoku Example

This "spreadsheet"is a complete example that uses GDX files to exchange information solves a 25x25 Sudoku problem using CPLEX. You will need a GAMS/CPLEX license to be able to run the spreadsheet. The MIP model solves very easily: the solution is found in the presolve phase.

Note: This spreadsheet requires distribution 22.6 or younger to work properly. If you are using an older distribution, please download "this one".

Problem

Solution

Efficient frontier example

This "example"(screen shot below) solves a series of NLPs to create an efficient frontier of a portfolio optimization problem.

Note: This spreadsheet requires distribution 22.6 or younger to work properly. If you are using an older distribution, please download "this one".

Spawning GAMS from C

The example below shows an absolute minimal version of calling GAMS from a C program:

#include <stdio.h>

int main(int argc, char** argv)

{

system("gams trnsport lo=2");

return 0;

}

As can be seen the GAMS executable gams.exe is called via a simple invocation of system(). The extra command line parameter lo=2 indicates that the log file is not written to the screen (this is the default) but to a file model.log.

If we want to generate some data from the application program (e.g. parameter DEMAND), we can use an include file which is written by the application. Of the way back results can be read from a PUT file. The GAMS file can now look like:

Spawning GAMS from Visual Basic

When executed a simple window appears where a GAMS model can be specified and possible other command line options. The [GAMS] button will execute the model.

When the Normal display is used, a console window will be opened. This console window will be closed automatically at the end of the run if the Close process window on completion check box is checked. Minimized does not show a window, but in the taskbar an icon will appear. If the job takes a long time, the user can click on this icon to make the console window visible. The Hidden option prevents any GAMS associated window or icon to appear.

Note: it is required for this program to work, that the GAMS system directory is in the path. If this is not the case, an error code of -1 is returned.

The main program is attached below, the full source for this example is "available for download".

Spawning GAMS from Delphi

This is a Delphi 4 application that has similar features as the Visual Basic application described in the previous paragraph.

Note: it is required for this program to work, that the GAMS system directory is in the path. If this is not the case, an error code of -1 is returned. The main code is attached below, the full source and the executable for this example are "available for download".

The command line formed here is gams modelname LO=0 –runid=xxx. The option LO (logoption) will disable writing a log, and the option –runid passes a parameter to the GAMS model (inside the model you can access this through runid%).

Spawning GAMS from Java

Java has a class Runtime that implements spawning of processes using the Exec() method. This is quite trivial to use in applications, but in applets the default security settings don't allow this operation (in general). The problem can be solved by loading the applet from a local drive or by using a signed applet. Similarly if the Java classes are loaded from inside a database, this operation may require additional privileges. For an example see the previous section, where GAMS is called from Oracle using a Java Stored Procedure. The relevant code may look like:

Below another example, which avoids problems, if the model has a long screen log (the buffer gets filled and locks the execution), which could happen if GAMS does not write the log to the file like above. This example is based on suggestion made by Edson Valle.

Spawning GAMS from a Web Server

Running GAMS remotely using a Web based thin-client architecture requires that GAMS is executed directly or indirectly from the Web server or HTTP server. A simple way of doing this is via a CGI process. Common Gateway Interface (CGI) programs can be written in many languages such as C, Perl or Delphi. CGI is relatively slow, as for each interaction, even the most simple one, a process needs to be started. Alternatives exist in the form of CGI extensions such as FastCGI or using DLLs or shared libraries. A basic algorithm for a CGI script could be:

Create a unique directory, and CD to that directory.

Get information from user forms and save it as GAMS readable files.

Run GAMS making sure it does not write the log to the screen (i.e. use the option LO=2 (log to a file) or LO=3 (log to stdout)).

Let the model write solution info to text files using the PUT statement.

Read solution, and create formatted HTML to send back to the user.

Remove temp files and directory.

Complications arise when there is a need to show graphics (files need to be stored somewhere and discarded after a while), when jobs take a long time to finish (you will need to add a facility where the user can pick up results at a later moment) or when the server resources can be exhausted (e.g. because of a large number of simultaneous users or because of large models).

An important complicating issue in the above list are jobs that take more time to finish: web servers like to respond to the user within a short time, and time out errors will occur if a job takes a long time. The solution is to use a queue based approach. An actual implementation available is the NEOS Server - there is also a GAMS interface to NEOS: KESTREL - Remote Solver Execution on NEOS Servers.