[gridrpc-wg] Final call: GridRPC API for inclusion in SAGA 1.0

Thilo Kielmann kielmann at cs.vu.nl
Wed Aug 9 12:00:49 CDT 2006


Dear all,

Hidemoto Nakada, Yusuke Tanimura, and myself have met and we have 
re-worked the pending proposal for a GridRPC module for inclusion in
the upcoming SAGA spec. The only thing we have changed is the way in which
parameters to an RPC invocation are passed. Now, it is an array of parameters,
where a paramter is a struct, consisting of buffer, size, and, IN/OUT/INOUT
mode. We have also modelled examples from the Ninf-G web page with this API.
We think that this now has a "look and feel" of GridRPC.

Attached please find the proposed text with API and examples. If this (or
something similar) can be agreed upon quickly, then the GridRPC module can
be included in the SAGA 1.0 spec. We see this API not as a competitor to the
GridRPC API, as published in GFD-R.52. It is rather an alternative, embedded
in the SAGA framework, to access existing GridRPC implementations, thus
extending their user base.

We are now doing the final call for comments for the two groups involved.
If you have comments or questions, please post them TO BOTH MAILING LISTS.

This final call is open until FRIDAY, AUGUST 18th.
Comments and objections made by then will happily be included in the
proposal. By this deadline, we will add this text (with all modifications
we got) into the SAGA API document.


Thanks to you all for your contributions.


Thilo Kielmann
-- 
Thilo Kielmann                                 http://www.cs.vu.nl/~kielmann/
-------------- next part --------------
+-------------------------------------------------------------+

                  ######  ######   #####
                  #     # #     # #     #
                  #     # #     # #
                  ######  ######  #
                  #   #   #       #
                  #    #  #       #     #
                  #     # #        #####
    
+-------------------------------------------------------------+
     
     
Summary:
========
     
     GridRPC is one of the few high level APIs defined by the
     GGF.  Including it into the SAGA API benefits both:  SAGA
     gets more complete, and provides a better coverage of its
     use cases with a single look and feel; and GridRPC gets
     embedded into a set of other tools of similar scope, which
     opens it to a potentially wider user community, and ensures
     its further development.

     The RPC package of the SAGA API described here is a one 
     to one mapping from the GridRPC standard, equipped with the
     SAGA look and feel, error conventions, task model etc.

+-------------------------------------------------------------+


Specification:
==============

  package SAGA version 0.1 {
  
    package RPC {
   
      enum io_mode{
        IN    = 1,  // input parameter
        OUT   = 2,  // output parameter
        INOUT = 3   // both input and output parameter
      }

      struct parameter{
        long size;            // number of bytes in buffer
        array<byte,1> buffer; // data
        io_mode mode;         // parameter mode
      }

      class RPC {
      
        void constructor (in    string            funcname   );
        void call        (inout array<parameter>  parameters );
      };
    }
  }

+-------------------------------------------------------------+

#ifndef SHORT

Details:
========

    class RPC

      This class represents a remote function handle, which 
      can be called (repeatedly), and returns the result of 
      the respective remote procedure invocation.  
      
      The class offers one non trivial constructor, which
      initialises the remote function handle (see [1] for
      details).  That process may involve connection setup,
      service discovery etc.  The class further offers one 
      method 'call', which invokes the remote procedure, and
      returns the respective return data and values.  The
      asynchroneous versions described in [1] are realised by 
      the SAGA task model, and are not represented as separate
      calls here.

      In the constructor, the remote procedure to be invoked is
      specified by a URL, whith the syntax:

        gridrpc://server.net:1234/my_function

      with the elements responding to:

        gridrpc     - scheme - identifying a grid rpc operation
        server.net  - server - server host serving the rpc call
        1234        - port   - contact point for the server
        my_function - name of the remote method to invoke

      All elements but the scheme can be empty, which allows the
      implementation to fall back to some default remote method
      to invoke (minimal URL: gridrpc:///).

      The argument and return value handling is currently very
      basic, and reflects the traditional scheme for remote
      procedure calls: an array of parameters, for each of which
      the buffer, its size, and the input/output mode is described.
      On invocation of the 'call' method, for each parameter the
      'mode' value has to be initialized, for parameters with mode
      IN or INOUT, also 'size' and 'buffer' must be initialized.
      For parameters with mode OUT, 'size' might also have the value 0
      in which case the 'buffer' is considered to be void, and has to be
      created (e.g., allocated) by the SAGA system upon arrival of the
      result data.

      This argument handling scheme allows efficient (copy-free)
      passing of parameters. For OUT parameters with a size value of 0,
      the implementation is required to allocate the data structure and to
      overwrite the size and buffer fields for the parameter.

      - constructor
        Purpose: inits a remote function handle
        Format:  void constructor   (in  string      funcname)
        Inputs:  funcname:           name remote method to
                                     initialize
        Outputs: none
        Throws:  NoSuccess:          server could not be
                                     contacted, or method is 
                                     unknown
        Notes:   - see [1] for details
                 - if funcname is NULL, a default handle is 
                   created

      - call
        Purpose: call the remote procedure
        Format:  void call         (inout array<parameter> parameters);
        In/Out:  parameters:        argument/result values for call
        Throws:  NoSuccess:         remote operation failed
        Notes:   - see [1] for details
                 - by passing an array of variable size, different numbers
                   of parameters can be handled. No special variable argument
                   list handling is required.

+-------------------------------------------------------------+


Examples:
=========

  // call a remote matrix multiplication A = A * B
  try {
    rpc rpc ("gridrpc://fs0.das2.cs.vu.nl/matmul1");

    saga::rpc::parameter[2] params;
    params[0].buffer = // ptr to matrix A
    params[0].size   = sizeof(buffer);
    params[0].mode = saga::rpc::IO_MODE::INOUT;
    params[1].buffer = // ptr to matrix B
    params[1].size   = sizeof(buffer);
    params[1].mode = saga::rpc::IO_MODE::IN;

    rpc.call (params);

    // A now contains the result
  }
  catch ( const saga::NoSuccess & e)
  {
    std::err << "SAGA error: " << e.what() << std::endl;
  }



  // call a remote matrix multiplication C = A * B
  try {
    rpc rpc ("gridrpc://fs0.das2.cs.vu.nl/matmul2");

    saga::rpc::parameter[3] params;
    params[0].size   = 0; // buffer will be created
    params[0].mode = saga::rpc::IO_MODE::OUT;
    params[1].buffer = // ptr to matrix A
    params[1].size   = sizeof(buffer);
    params[1].mode = saga::rpc::IO_MODE::INOUT;
    params[2].buffer = // ptr to matrix B
    params[2].size   = sizeof(buffer);
    params[2].mode = saga::rpc::IO_MODE::IN;

    rpc.call (params);

    // params[0].buffer now contains the result
  }
  catch ( const saga::NoSuccess & e)
  {
    std::err << "SAGA error: " << e.what() << std::endl;
  }



  // asynchronous version of A = A * B
  try {
    rpc rpc ("gridrpc://fs0.das2.cs.vu.nl/matmul1");

    saga::rpc::parameter[2] params;
    params[0].buffer = // ptr to matrix A
    params[0].size   = sizeof(buffer);
    params[0].mode = saga::rpc::IO_MODE::INOUT;
    params[1].buffer = // ptr to matrix B
    params[1].size   = sizeof(buffer);
    params[1].mode = saga::rpc::IO_MODE::IN;

    saga::task t1 = rpc.call <saga::sync> (params);

    t1.wait();
    // A now contains the result
  }
  catch ( const saga::NoSuccess & e)
  {
    std::err << "SAGA error: " << e.what() << std::endl;
  }



  // parameter sweep example from
  // http://ninf.apgrid.org/documents/ng4-manual/examples.html
  //
  // Monte Carlo computation of PI
  //
  try {
    string uri[NUM_HOSTS]; // initialize...
    double pi;
    long times, count[NUM_HOSTS], sum;

    saga::rpc::rpc *servers[NUM_HOSTS];
    for (int i = 0; i < NUM_HOSTS; i++)
      servers[i] = new saga::rpc::rpc(uri[i]);

    saga:rpc::parameter params[NUM_HOSTS][3];
    saga::task t[NUM_HOSTS];
    saga::task_container tc;

    for (int i = 0; i < NUM_HOSTS; i++){

      params[i][0]->buffer = i; // use as random seed
      params[i][0]->size   = sizeof(buffer);
      params[i][0]->mode = saga::rpc::IO_MODE::IN;
      params[i][1]->buffer = times;
      params[i][1]->size   = sizeof(buffer);
      params[i][1]->mode = saga::rpc::IO_MODE::IN;
      params[i][2]->buffer = count[i];
      params[i][2]->size   = sizeof(buffer);
      params[i][2]->mode = saga::rpc::IO_MODE::OUT;

      t[i] = servers[i]->call <saga::async> (params[i]);
      tc.add(t[i]);
    }

    tc.wait(-1,ALL);

    // compute and print pi
    for (int i = 0; i < NUM_HOSTS; i++){
      sum += count[i];
    }
    pi = 4.0 * ( sum / ((double) times * NUM_HOSTS));
    std::out << "PI = " << pi << std::endl;

    for (int i=0; i < NUM_HOSTS; i++)
      delete servers[i];

  }
  catch ( const saga::NoSuccess & e)
  {
    std::err << "SAGA error: " << e.what() << std::endl;
  }

+-------------------------------------------------------------+


Notes:
======

  References:
  -----------

    [1] H. Nakada, S. Matsuoka, K. Seymour, J.Dongarra, 
        C. Lee, H.  Casanova: "A GridRPC Model and API for End-User
        Applications", Global Grid Forum Document GFD-R.52.

  Comparision to the original GridRPC calls:
  ------------------------------------------

    initialization:
    ---------------

    - grpc_initialize 
      
      GridRPC: reads the configuration file and initializes the
               required modules.
      SAGA:    not needed, implicit
     
     
    - grpc_finalize 

      GridRPC: releases any resources being used
      SAGA:    not needed, implicit
      
     
    handle management:
    ------------------
     
    - grpc_function_handle_default 
    
      GridRPC: creates a new function handle using the default
               server.  This could be a pre-determined server 
               name or it could be a server that is dynamically 
               chosen by the resource discovery mechanisms of 
               the underlying GridRPC implementation, such as 
               the NetSolve agent.
      SAGA:    default constructor

     
    - grpc_function_handle_init 
      
      GridRPC: creates a new function handle with a server
               explicitly specified by the user.
      SAGA:    explicit constructor
      
    
    - grpc_function_handle_destruct 
      
      GridRPC: releases the memory associated with the
               specified function handle.
      SAGA:    destructor
    
    
    - grpc_get_handle

      GridRPC: returns the handle corresponding to the given
               session ID (that is, corresponding to that 
               particular non-blocking request).
      SAGA:    not possible right now.
               However, status of asynchronous operations can be checked
               via the corresponding task objects.


    call functions:
    ---------------

    - grpc_call 
    
      GridRPC: makes a blocking remote procedure call with a variable
               number of arguments.
      SAGA:    has no variable number of aguments, this case is covered
               via the SAGA version of grpc_call_argstack.


    - grpc_call_async 
    
      GridRPC: makes a non-blocking remote procedure call with a
               variable number of arguments.
      SAGA:    done via task model and equivalent to grpc_call_argstack.


    - grpc_call_argstack 
    
      GridRPC: makes a blocking call using the argument stack
      SAGA:    call provides a parameter array of variable size

      
    - grpc_call_argstack_async 
    
      GridRPC: makes a non-blocking call using the argument stack.
      SAGA:    done via the task model and call


    asynchronous control functions:
    -------------------------------

    - grpc_probe 
    
      GridRPC: checks whether the asynchronous GridRPC call has
               completed.
      SAGA:    done via the task model


    - grpc_cancel 
    
      GridRPC: cancels the specified asynchronous GridRPC call.
      SAGA:    done via the task model
       

    asynchronous wait functions:
    ----------------------------

    - grpc_wait 
    
      GridRPC: blocks until the specified non-blocking requests to
               complete.
      SAGA:    done via the task model
       
    
    - grpc_wait_and 
    
      GridRPC: blocks until all of the specified non- blocking requests
               in a given set have completed.
      SAGA:    done via the task container

    
    - grpc_wait_or 
    
      GridRPC: blocks until any of the specified non- blocking requests
               in a given set has completed.
      SAGA:    done via the task container
           
    
    - grpc_wait_all 
    
      GridRPC: blocks until all previously issued non-blocking requests
               have completed.
      SAGA:    done via the task container
             
    
    - grpc_wait_any 
    
      GridRPC: blocks until any previously issued non-blocking request
               has completed.
      SAGA:    done via the task container
      

    error reporting functions:
    --------------------------

    - grpc_perror 
    
      GridRPC: prints the error string associated with the last GridRPC
               call.
      SAGA:    exceptions
     
     
    - grpc_error_string 
    
      GridRPC: returns the error description string, given a numeric
               error code.
      SAGA:    exceptions
     
     
    - grpc_get_error 
    
      GridRPC: returns the error code associated with a given
               non-blocking request.
      SAGA:    exceptions
    
     
    - grpc_get_last_error 
    
      GridRPC: returns the error code for the last invoked GridRPC call.
      SAGA:    exceptions

  
+-------------------------------------------------------------+

#endif // SHORT


More information about the gridrpc-wg mailing list