We define a remote executable module in the IDL file. The stub generation program (omrpc-gen) from the IDL file description creates a remote executable program which communications with the remote executable module. A command (omrpc-cc) is a driver that generates the remote executable program and , also serves as link to library.
We show an example as follows.
Module mat_mult; Define dmmul(mode_in int n, mode_in double A[n][n], mode_in double B[n][n], mode_out double C[n][n]) { double t; int i,j,k; for (i=0;i<n;i++){ for (j=0;j<n;j++){ t = 0; for (k=0;k<n;k++){ t += A[i*n + k] * B[k*n+j]; /* inner product */ } C[i*n+j] = t; } } }
The module statement defines the module name. The functions inside this module are described by the "Define" statement The definitions of the arguments are similar to those in C language, but some differences exist, as follows.
After the Define statement, you can describe any program in C language inside of brace ({...}). Argument names can be used as the arguments in C language without modification.
You can call a library function, like the example, below.
Define dmmul(mode_in int n, mode_in double A[n][n], mode_in double B[n][n], mode_out double C[n][n]) Calls "C" mmul(n,A,B,C);
This above example calls "mmul" function, which writes in C language.
And, you can define multiple functions inside the module's definition file. These descriptions should be in the remote executable program.
At the time of this writing, fundamental data types and their arrays are supported. We are going to support structure data types in a future release.
A description of IDL includes some elements.
We define the module's name.
Module module_name;
module_name is the identifier of the module. You should define the module name first in IDL file.
We define an interface of a function which called from the remote program.
Define function_name (parameter1,parameter2,...) "...description..." interface_body
Function name is "function_name." We describe this parameter as follows.
mode type_specifier parameter_name
Mode specifies whether an argument is input or output. If the argument is input, you write "mode_in" or "IN." If the argument is output, you should write "mode_out" or "OUT." And, if you want to allocate temporary data, you can specify "work." the "type_specifier" supports the names of the fundamental data type in C language and "string," which stands for string.
You can specify arguments of an array in C language.
mode type_specifier parameter_name[size]...
Arguments of a multi-dimensional array are enclosed in brackets ([...]) for each dimension, as in C language.
You can describe the upper limit, bottom limit and stride of a transferred array area.
mode type_specifier parameter_name[size:low,high,stride]...
Between the body information about the function is described in a string.
In the body, you need to conform to C language.
Define function_name (...) { in manner of C language }
In the description of a function of C , arguments are accessed as a parameter variable.
And, if you call a function which is linked, you write the function call after the Call directive.
Define function_name (...) Calls foo(...);
You can describe in programs written in C language the functions and data which are to be used in an entire module. For example, you can describe a necessary function definition when you define the definition of the function in C language. And, you can describe variables which are shared in functions and multiple functions.
Globals { ... any programs }
This specifies the rule of function mangling when function link to FORTRAN program.
OmniRPC's IDL description is based on Ninf's IDL. However, there are some differences.
We show the informal definitions of IDL grammar as follows.
program := {declaration}* declaration:= 'Module' IDENTIFIER ';' | 'Define' interface_definition OPT_STRING interface_body | 'Globals' '{' C_PROGRAM '}' | 'Fortranformat' STRING ';' ; interface_definition:= IDENTIFIER '(' parameter {',' parameter}* ')' ; parameter:= decl_specifier declarator ; decl_specifier: type_specifier | MODE | MODE type_specifier | type_specifier MODE | type_specifier MODE type_specifier ; MODE := 'mode_in' | 'IN' | 'mode_out' | 'OUT'; declarator=: IDENTIFIER | '(' declarator ')' | declarator '['expr_or_null ']' | declarator '['expr_or_null ':' range_spec ']' | '*' declarator ; range_spec=: expr | expr ',' expr | expr ',' expr ',' expr ; interface_body: '{' C_PROGRAM '}' | CALLS OPT_STRING IDENTIFIER '(' IDENTIFIER {',' IDEFINTIER}* ')' ';' ; expr_or_null:= expr | /* null */; expr:= primary_expr | '*' expr /* pointer reference */ | '-' expr /* unary minus */ | expr '/' expr | expr '%' expr | expr '+' expr | expr '-' expr | expr '*' expr | expr '^' expr | expr RELOP expr | expr '?' expr ':' expr ; primary_expr:= primary_expr '[' expr ']' | IDENTIFIER | CONSTANT | '(' expr ')' ;