The User's Manual

Build Ninf-G remote libraries

The Ninf-G remote libraries are implemented as executable programs which contain network stub routine as its main routine, and spawned off by the Gram component on the Ninf-G system. We call such executable programs Ninf-G executable associated with its name, and executes the found executable, sets up an appropriate communication with the client. The stub routine handles the communication to the Ninf-G system and its client, including argument marshalling. The underlying executable can be written in any existing scientific languages such as Fortran, C, etc, as long as it can be executed in the host.
To register and publish your numerical libraries and computational resource, you first should provide interface information about those numerical libraries and prepares the Ninf-G executable by performing the following task.

Programming Interface

Before starting, be sure that the environment variables GLOBUS_LOCATION (for GT2) or GLOBUS_INSTALL_PATH (for Globus Ver.1), and NS_DIR are defined appropriately. Since the original Ninf client programming interface was designed to be as language independent as possible, we have developed a variety of programming interfaces such as C, Fortran, Java, and Lisp. The concept of the Ninf-G system is the same. Currently the Ninf-G system supports the C interface, and we are in the process of building the Java interface and other language bindings. Ninf-G provides both Grid RPC native API (GRPC API) and Ninf compatible API (Ninf API). Ninf API is a full-compatible API with Ninf version 1 which provides simple and easy programming interface to programmers. GRPC API provides lower level and flexible programming interface to programmers. According to the requirements, application programmers can build Grid-enabled applications using either GRPC API or Ninf API. In this section, we introduce you several representative functions using C interface for both GRPC API and Ninf API. The complete API reference is described in the Appendix.



This function read configuration file for your client program and set system parameters for Ninf-G.
main (int argc, char **argv) {
   char *conf_file = argv[1];


Synchronous Call

The synchronous call to Ninf-G from C is the easiest to implement, just call the function, grpc_call() . This function returns an error code. It takes as arguments the name of a problem and the list of input data and output data. These inputs are listed according to the calling sequence defined in the corresponding Ninf IDL. The more detailed information on the Ninf-G IDL are described in the section called Ninf-G IDL The C prototype of the function is
grpc_call(grpc_function_handle_t *handle, <argument list>)
where *handle is a pointer to the handle to the numerical library on the Ninf-G system. Let us resume our example of the call to a simple matrix multiplication. In C, the local function to this caliculation looks like
 mmul(double *A, double *B, double *C), 
Meanwhile, the equivalent synchronous call to Ninf-G in C is
grpc_function_handle_t *handle;
grpc_function_handle_init(&handle, "", 
                          3030, "lib/mmul");
status = grpc_call(&handle, A, B, C);
As such, you should initialize a function handle to the Ninf-G remote library using grpc_function_handle_init which takes as arguments a server name, port number, and a module name of the library.

Asynchronous Call

The standard grpc_call() RPC is synchronous in that the client waits until the completion of the computation on the server side. For task-parallel execution, Ninf-G facilitates several asynchronous call APIs. For example, the most basic asynchronous call
int grpc_async_call(grpc_function_handle_t *handle, 
                    <argument list>)
It is almost identical to grpc_call except that it returns immediately after all the arguments have been sent. The return value is the session ID of the asynchronous call; the ID is used for various synchronizations such as waiting for the return value of the call.
There are several calls for synchronization. The most basic is the
grpc_wait(int sessionID); 
, grpc_wait() is the function with which we wait for the result of the asynchronous call with the supplied session ID. grpc_wait_all() waits for all preceding asynchronous invocations made.

Running the Ninf-G Client

After developing the Ninf Client Application by the use of the programming interface, what you need to do for running the application are listed here.

Managing Jobs

Since the Ninf-G system is built on top of the Globus, you can directly take advantage of the Globus commands for managing the submitted jobs such as checking, killing, and cleaning. We give you very quick overview of the Globus commands, and more detailed explanation can be seen in the Globus manual.

Checking my job

% globus-job-run <hostname> /bin/ps -u <username>
When you submit a job to the batch scheduler, enter globus-job-status followed by the job contact string URL.
% globus-job-submit $lt;hostname$gt; $lt;command$gt;
% globus-job-status
The different status are PENDING(waiting in the queue), ACTIVE(running), SUSPENDED, DONE, and FAILED.

Canceling/Cleaning a Job

If you interrupt the globusrun or globus-job-run process(by entering CTRL-C or sending it a SIGINT), your jobs should automatically be canceld.

Ninf API


This function parse argument list for your client program and retrieve arguments for Ninf-G system. This function returns new argc value. Here is an example showing typical usage.
main (int argc, char ** argv){
	argc = Ninf_parse_arg(argc, argv);

Synchronous call

This function calls Ninf function on a remote server. The first argument specifies server and function. Here is an example that calls "mmul" function.
     Ninf_call("mmul", n, A, B, C);
You can omit the server name and port. In such case, a default server will be used. Default server can be specified by environment variable "NINF_SERVER" and "NINF_SERVER_PORT", or Ninf_parse_arg. This function returns 0 if succeed, returns -1 if failed.

Asynchronous Call

This function is almost same as Ninf_call, but it returns immediately. Using this function, you can invoke several sessions simultaneously. It returns non-negative ID if succeed, returns -1 if failed.
     id = Ninf_call_async("mmul", n, A, B, C);
There are several calls for synchronization. The most basic is the
Ninf_wait(int sessionID); 
, Ninf_wait() is the function with which we wait for the result of the asynchronous call with the supplied session ID. grpc_wait_all() waits for all preceding asynchronous invocations made.

As mentioned above, Ninf_call() is the client interface to the Ninf compute and database servers. In order to illustrate the programming interface with an example, let us consider a simple matrix multiply routine in C programs with the following interface:

double A[N][N],B[N][N],C[N][N];   /* declaration */
dmmul(N,A,B,C);	                  /* calls matrix multiply, C = A * B */
When the dmmul routine is available on a Ninf server, the client program can call the remote library using Ninf_call , in the following manner:
Ninf_call("dmmul",N,A,B,C); /* call remote Ninf library on server */
Here, dmmul is the name of library registered as a Ninf executable on a server, and N,A,B,C are the same arguments. As we see here, the client user only needs to specify the name of the function as if he were making a local function call; Ninf_call() automatically determines the function arity and the type of each argument, appropriately marshals the arguments, makes the remote call to the server, obtains the results, places the results in the appropriate argument, and returns to the client. In this way, the Ninf RPC is designed to give the users an illusion that arguments are shared between the client and the server.

The reader may also notice that the physical location of the Ninf server is not specified in the example. Ninf provides a variety of ways for the client to specify the server and its registered library:

To realize such simplicity in the client programming interface, we designed Ninf RPC so that client function call obtains all the interface information regarding the called library function at runtime from the server. Although this will cost an extra network round trip time, we judged that typical scientific applications are both compute and data intensive such that the overhead should be small enough. The interface information includes:

The client function call requests the interface information of the calling function to the Ninf server, which in turn returns the registered Ninf executable interface information to the client. The client library then interprets and marshals the arguments on the stack according to the supplied information. For variable-sized array arguments, the IDL must specify an expression that includes the input scalar arguments whereby the size of the arrays can be computed. This design is in contrast to traditional RPCs, where stub generation is done on the client side at compile time. As a result of dynamic interface acquisition, Ninf RPC does not require such compile-time activities at all, relieving the users from any code maintenance. [2] describes the structure of the interface information and the protocol in detail.

In the above example, the client function call sends the input arrays, A and B, whose size is computed by the parameter N . The Ninf server invokes the Ninf executable of dmmul library, and forwards the input data to it. When the computation is done, the result is sent back to the client through the server. The client function call stores the returned data at the location pointed by the argument, C.

The Ninf RPC may also be invoked asynchronously to exploit network-wide parallelism. It is possible to issue the request to a Ninf server, continue with the other computation, and poll for the request later. Multiple RPC requests to different servers are also possible. For this reason, the asynchronous Ninf PRC is an important feature for parallel programming.