Automatic code generation

From the interface definition some code is automatically generated by gsstubgen, a tool provided with the GRID superscalar distribution. This automatically generated code is mainly two files: the function stubs and the skeleton for the code that will be run on the servers.

Figure 1 shows a part of the stubs file that will be generated for the idl file when the C/C++ interface is used. Similar stub files would be generated for other languages.
 

#include
. . .
int gs_result;

void Filter(file referenceCFG, double latency, double bandwidth, file newCFG)
{
    char buff_latency[GS_GENLENGTH];
    char buff_bandwidth[GS_GENLENGTH];
    /* Parameter marshalling */

    sprintf(buff_latency, "%.20g", latency);
    sprintf(buff_bandwidth, "%.20g", bandwidth);
    Execute(FilterOp, 1, 2, 1, 0, referenceCFG, buff_latency, buff_bandwidth, newCFG);
}
. . .

 

Figure 1: Example of stubs generated for the user functions



For each function in the idl file, a wrapper function is defined. In the wrapper function, the parameters of the function are encoded using base64 format. Then, the Execute function is called. The Execute function is the main primitive of the GRID superscalar interface.

The other file automatically generated by gsstubgen is shown in figure 2. This is the main program of the code executed in the servers. This code will be called from GRID superscalar by means of the middleware.
 

#include
. . .
int main(int argc, char **argv)
{
    enum operationCode opCod = (enum operationCode)atoi(argv[2]);

    IniWorker(argc, argv);
    switch(opCod)
    {
        case FilterOp:
        {
            double latency;
            double bandwidth;

            latency = strtod(argv[4], NULL);
            bandwidth = strtod(argv[5], NULL);
            Filter(argv[3], latency, bandwidth, argv[6]);
        }
        break;
        . . .
    }
    EndWorker(gs_result, argc, argv);
    return 0;
}

 

Figure 2: Example of skeleton generated for the server code


Inside this program, calls to the original user functions are performed. Before calling the user functions, the parameters are decoded.

Figure 3 shows how files are linked to obtain the final application binaries. One executable will exist in the client host and one in each server host. In the client, the original main program (app.c) is linked with the generated stubs (app-stubs.c). In the servers, the skeleton (app-worker.c) and the file with the code of the original user functions (app-functions.c) are linked to obtain each server’s binary. Currently, the deployment process can be performed by hand or with the help of the deployment center.
   

Files_generated

Figure 3: GRID superscalar application files organization



The process is slightly different when we use a programming language different from C/C++. gsstubgen is also used to generate the required files that enables the execution of the application in a computational GRID. Some of these files are similar to the files generated for the C/C++ case. But other extra files can be generated in order to allow the translation from idl to the interference syntax required by the programming language.