+-------------------------------------------------------------+ ###### ###### ##### # # # # # # # # # # # ###### ###### # # # # # # # # # # # # # ##### +-------------------------------------------------------------+ 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 buffer; // data io_mode mode; // parameter mode } class RPC { void constructor (in string funcname ); void call (inout array 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 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 (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 (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