gs_call.cpp

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*    gs_call.cpp                                                             */
00004 /*    source file that implements blocking                                    */
00005 /*    call to GridSolve system from Octave                                    */
00006 /*                                                                            */
00007 /*    Copyright (C)                                                           */
00008 /*    Innovative Computing Laboratory (ICL)                                   */
00009 /*    Univesity of Tennessee, Knoxville                                       */
00010 /*                                                                            */
00011 /*    Feburary 22, 2007                                                       */
00012 /******************************************************************************/
00013 
00014 
00015 #include <oct.h>
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include "grpc.h"
00019 #include "gs_oct.h"
00020 
00021 
00022 DEFUN_DLD (gs_call, args, nargout, "Octave client for GridSolve") {
00023     octave_value_list retvals;      //return value
00024     octave_value_list bad_retval;   //bad return value
00025     gs_problem_t* pd;               //GridSolve problem description
00026     grpc_arg_stack* argstack;       //GridRPC argument stack
00027     gs_argument_t* argp;            //GridRPC argument pointer
00028     grpc_function_handle_t *handle; //GridRPC function handle
00029     grpc_error_t status;            //GridRPC status/error code
00030     char *info[1];
00031 
00032 
00033     //meaningless return value for error condition
00034     //or those calls that do not make grpc function call
00035     for (int i = 0; i < nargout; i++) {
00036         bad_retval(i) = Matrix(0, 0);
00037     }
00038 
00039     //initialize the GridSolve environment
00040     status = grpc_initialize(NULL);
00041     if (status != GRPC_NO_ERROR && status != GRPC_ALREADY_INITIALIZED) {
00042         fprintf(stderr, "%s\n", grpc_error_string(status));
00043         return bad_retval;
00044     }
00045 
00046     //number of input arguments
00047     int nargin = args.length();
00048 
00049     //invalid first argument
00050     if (nargin >= 1 && !args(0).is_string()) {
00051         fprintf(stderr, "Invalid first parameter: should be a string. Aborted.\n");
00052         grpc_finalize();
00053         return bad_retval;
00054     }
00055 
00056     //do a grpc call to a remote service
00057     if (nargin >= 1) {
00058         int strlen = args(0).string_value().length();
00059 
00060         //get the problem name
00061         char *pname = new char[strlen + 1];
00062         for (int i = 0; i < strlen; i++)
00063             pname[i] = (args(0).string_value())[i];
00064         pname[strlen] = '\0';
00065 
00066         //initialize the GridRPC function handle
00067         handle = (grpc_function_handle_t *) malloc(sizeof(grpc_function_handle_t));
00068         if (handle == NULL) {
00069             perror("malloc");
00070             delete pname;
00071             grpc_finalize();
00072             return bad_retval;
00073         }
00074 
00075         status = grpc_function_handle_default(handle, pname);
00076         if (status != GRPC_NO_ERROR) {
00077             fprintf(stderr, "%s\n", grpc_error_string(status));
00078             delete pname;
00079             grpc_function_handle_destruct(handle);
00080             if (handle != NULL) free(handle);
00081             grpc_finalize();
00082             return bad_retval;
00083         }
00084 
00085         //get the GridSolve problem description
00086         pd = handle->problem_desc;
00087 
00088         if (pd == NULL) {
00089             fprintf(stderr, "Empty GridSolve problem description. Aborted.\n");
00090             delete pname;
00091             grpc_function_handle_destruct(handle);
00092             if (handle != NULL) free(handle);
00093             grpc_finalize();
00094             return bad_retval;
00095         }
00096 
00097         //convert object types before make the call
00098         if (convert_octave_arguments(pd, args) < 0) {
00099             fprintf(stderr, "Failure to convert input arguments. Aborted.\n");
00100             delete pname;
00101             grpc_function_handle_destruct(handle);
00102             if (handle != NULL) free(handle);
00103             grpc_finalize();
00104             return bad_retval;
00105         }
00106 
00107         int arg_stack_size = 0;
00108         //compute the argument stack size
00109         for (argp = pd->arglist; argp != NULL; argp = argp->next) {
00110             if (argp->inout != GS_WORKSPACE) arg_stack_size++;
00111         }
00112 
00113         //create a new argument stack for the grpc call
00114         if ((argstack = grpc_arg_stack_new(arg_stack_size)) == NULL) {
00115             fprintf(stderr, "Failed to create argument stack. Aborted.\n");
00116             delete pname;
00117             grpc_function_handle_destruct(handle);
00118             if (handle != NULL) free(handle);
00119             grpc_arg_stack_destruct(argstack);
00120             if (argstack != NULL) free(argstack);
00121             grpc_finalize();
00122             return bad_retval;
00123         }
00124 
00125         //push the converted arguments onto the stack
00126         for (argp = pd->arglist; argp != NULL; argp = argp->next) {
00127             if (argp->inout != GS_WORKSPACE) {
00128                 if (grpc_arg_stack_push_arg(argstack, argp->data) < 0) {
00129                     fprintf(stderr, "Error in pushing argument stack. Aborted.\n");
00130                     delete pname;
00131                     grpc_function_handle_destruct(handle);
00132                     if (handle != NULL) free(handle);
00133                     grpc_arg_stack_destruct(argstack);
00134                     if (argstack != NULL) free(argstack);
00135                     grpc_finalize();
00136                     return bad_retval;
00137                 }
00138             }
00139         }
00140 
00141         grpc_set_default_major("C");
00142         grpc_set_client_major("C");
00143 
00144         //calling the remote service
00145         status = grpc_call_arg_stack(handle, argstack);
00146         if (status == GRPC_NO_ERROR) {
00147             //printf("Blocking GridRPC call succeeded.\n");
00148         } else {
00149             fprintf(stderr, "%s\n", grpc_error_string(status));
00150             delete pname;
00151             grpc_function_handle_destruct(handle);
00152             if (handle != NULL) free(handle);
00153             grpc_arg_stack_destruct(argstack);
00154             if (argstack != NULL) free(argstack);
00155             grpc_finalize();
00156             return bad_retval;
00157         }
00158 
00159         //printf("Blocking GridRPC call finishes...\n");
00160 
00161         //create the return value object
00162         retvals = octave_value_list();
00163 
00164         //convert object back
00165         if (convert_output_objects(pd, retvals) < 0) {
00166             fprintf(stderr, "Failed to convert output arguments. Aborted.\n");
00167             delete pname;
00168             grpc_function_handle_destruct(handle);
00169             if (handle != NULL) free(handle);
00170             grpc_arg_stack_destruct(argstack);
00171             if (argstack != NULL) free(argstack);
00172             grpc_finalize();
00173             return bad_retval;
00174         }
00175 
00176         //finalize and clean up
00177         grpc_function_handle_destruct(handle);
00178         if (handle != NULL) free(handle);
00179         delete pname;
00180         grpc_arg_stack_destruct(argstack);
00181         grpc_finalize();
00182 
00183         return retvals;
00184     }
00185 }
00186 
00187