\documentstyle[psfig]{article}

\newenvironment{rationale}{\begin{list}{}{}
\item{\em Rationale.\hspace{0.1in}}}
{{\em (End of rationale.)}
\end{list}}

\newenvironment{implementors}{\begin{list}{}{}
\item{\em Advice to implementors.\hspace{0.1in}}}
{{\em (End of advice to implementors.)}
\end{list}}

\newenvironment{arguments}{\begin{tabular}{ll}}
{\end{tabular}\vspace{0.15in}\newline}

\newenvironment{argsNoSpace}{\begin{tabular}{ll}}
{\end{tabular}}

\begin{document}

\bibliographystyle{plain}
\pagestyle{plain}

\title{\vspace{1in}{\bf mpiJava 1.2}: API Specification}

\author{Bryan Carpenter, Geoffrey Fox, \\
        Sung-Hoon Ko, Sang Lim\vspace{0.25in} \\
        \em Northeast Parallel Architectures Centre, \\
        \em Syracuse University, \\
        \em 111 College Place, \\
        \em Syracuse, New York 13244-410 \\
        \em \{dbc,gcf,shko,slim\}\@npac.syr.edu}

\date{}

\thispagestyle{empty}

\maketitle

\newpage

This document defines the API of {\em mpiJava}, a Java language
binding for MPI 1.1.
The document is not a standalone specification of the behaviour of
MPI---it is meant to be read in conjunction with the MPI standard
document \cite{MPI-1}.  Subsections are laid out in the same way
as in the standard document, to allow cross-referencing.  Where the
mpiJava binding makes no significant change to a particular section of
the standard document, we will just note here that there are no special
issues for the Java binding.  This does not mean that the corresponding
section of the standard is irrelevant to the Java binding---it may mean
it is 100\% relevant!  Where practical the API is modelled on the MPI
C++ interface defined in the MPI standard version 2.0 \cite{MPI-2}.

Changes to the mpiJava 1.1 interface:
\begin{itemize}
\item
The {\tt MPI.OBJECT} basic type has been added.
\item
The interface for {\tt MPI.Buffer\_detach} has been corrected.
\item
The API of {\tt User\_function} has been changed.
\item
Attributes cached in communicators are now assumed to have integer values.
{\tt Attr\_put} and {\tt Attr\_delete} have been removed.
\item
The interface to {\tt Cartcomm.dimsCreate} has been corrected.
\item
{\tt Errorhandler\_set}, {\tt Errorhandler\_get} have changed from
static members of {\tt MPI} to instance methods on {\tt Comm}.
\item
The method {\tt Is\_null} has been added to class {\tt Comm}.
\item
The initialization method {\tt MPI.Init} now returns the command
line arguments set by MPI.
\item
MPI exception classes are now specified to be subclasses of
{\tt MPIException} rather than {\tt IOException}.  Methods are now
declared to throw {\tt MPIExcept\-ion} (see section \ref{sec:classes}).
\end{itemize}
The current API is viewed as an interim measure.  Further significant
changes are likely to result from the efforts of the Message-passing
working group of the Java Grande Forum.

\newpage

\tableofcontents

\newpage

\section{Introduction to MPI}

Evidently, this document adds Java to the C and Fortran bindings
defined in the MPI standard.  Otherwise no special issues for the Java
binding.


\newpage

\section{MPI Terms and Conventions}

\subsection{Document Notation}

No special issues for Java binding.

\subsection{Procedure Specification}

In general we use {\em italicized} names to refer to entities in the MPI
language independent procedure definitions, and {\tt typewriter} font for
concrete Java entities.

As a rule Java argument names are the
same as the corresponding language independent names.  In instance
methods of {\tt Comm}, {\tt Status}, {\tt Request}, {\tt
Datatype}, {\tt Op} or {\tt Group} (and subclasses), the class instance
generally stands for the argument called {\em comm}, {\em status}, {\em
request}, {\em datatype}, {\em op} or {\em group}, respectively in the
language independent procedure definition.

\subsection{Semantic terms}

No special issues for Java binding.

\subsection{Data types}

Opaque objects are presented as Java objects.
This introduces the
option of simplifying the user's task in managing these objects.  MPI
destructors can be absorbed into Java object destructors, which are
called automatically by the Java garbage collector.  We adopt this
strategy as the general rule.  Explicit calls to MPI destructor functions
are typically omitted from the Java user interface (they are absorbed
into {\tt finalize} methods).  Exceptions are made for the {\tt Comm}
and {\tt Request} classes.  {\em MPI\_COMM\_\-FREE} is a collective
operation, so the user must ensure that calls are made at consistent
times by all processors involved---the call can't be left to the
vagaries of the garbage collector.  A similar case can be made for {\em
MPI\_REQUEST\_FREE}.

\subsection{Language Binding\label{binding}}

\paragraph{Naming Conventions\label{naming}}
All MPI classes belong to the package {\tt mpi}.
Conventions for capitalization, etc, in class and member names
generally follow the C++ MPI bindings.

\paragraph{Restrictions on {\em struct} derived type.}
Some options allowed for {\em derived data types} in the C and Fortran
binding are deleted in mpiJava.  The Java VM does not
incorporate a concept of a global linear address space.  Passing physical
addresses to data type definitions is not allowed.  The use of the {\em
MPI\_TYPE\_STRUCT} datatype constructor is also restricted in a way that
makes it impossible to send mixed {\em basic datatypes} in a single
message.  Since, however, the set of basic datatypes recognised by MPI
is extended to include serializable Java {\em objects}, this
should not be a serious restriction in practice.

\paragraph{Multidimensional arrays and offsets.}
The C and Fortran languages define a straightforward mapping
(or ``sequence association'') between their multidimensional
arrays and equivalent one-dimensional arrays.  So in C or Fortran a
multidimensional array passed as a message buffer argument is first
interpreted as a one-dimensional array with the same element type as
the original multidimensional array.  Offsets in the buffer (such as
offsets occuring in derived data types) are then interpretted in terms of
the effective one-dimensional array (or---equivalent up to a constant
factor---in terms of physical memory).  In Java the relationship between
multidimensional arrays and one dimensional arrays is different.
An ``$n$-dimensional array'' is equivalent to a one-dimensional array
of $(n - 1)$-dimensional arrays.  In mpiJava,
message buffers are always one-dimensional arrays.
The element type {\em may} be an object, which {\em may} have array type.
Hence multidimensional arrays can appear as message buffers, but the
interpretation is subtly different.  In distinction to the C or Fortran
case {\em offsets in multidimensional message buffers are always
interpretted as offsets in the outermost one-dimensional array}.

\paragraph{Start of message buffer.}
C and Fortran both have devices for treating a section of an array,
offset from the beginning of the array, as if it was an array in its
own right.  Java doesn't have any such mechanism.  To provide the same
flexibility, an {\tt offset} parameter is associated with any buffer
argument.  This defines the position of the first actual buffer element
in the Java array.

\paragraph{Error codes.}
Unlike the standard C and Fortran interfaces, the mpiJava interfaces to MPI
calls do not return explicit error codes.  The Java exception
mechanism will be used to report errors.
\begin{rationale}
The exception mechanism is very widely
used by Java libraries.  It is inconvenient to use up the single
return value of a Java function with an error code.  (Java doesn't allow
function arguments to be passed by reference, so returning multiple
values tends to be more clumsy than in other languages.)
\end{rationale}

\paragraph{Multiple return values.}
A few functions in the MPI interface return multiple values, even after
the error code is eliminated.  This is dealt with in mpiJava
in various ways.  Sometimes an MPI function initializes some
elements in an array and also returns a count of the number of elements
modified.  In Java we typically return an array result, omitting the
count.  The count can be obtained subsequently from the {\tt length}
member of the array.  Sometimes an MPI function initializes an object
conditionally and returns a separate flag to say if the operation
succeeded.  In Java we typically return an object reference which is
{\tt null} if the operation fails.  Occasionally extra internal state
is added to an existing MPI class to hold extra results---for example
the {\tt Status} class has extra state initialized by functions like
{\tt Waitany} to hold the {\em index} value.  Rarely none of these
methods work and we resort to defining auxilliary classes to hold
multiple results from a particular function.

\paragraph{Array count arguments.}
The mpiJava binding often omits array size arguments, because they can
be picked up within the function by reading the {\tt length} member of
the array argument.  A major exception is for message buffers, where
an explicit count is always given.
\begin{rationale}
In the mpiJava, message buffers have explicit {\tt offset} and
{\tt count} arguments whereas other kinds of array argument typically
do not.  Message buffers aside, typical array arguments to MPI
functions (eg, vectors of request structures) are small arrays.  If
subsections of these must be passed to an MPI function, the sections
can be copied to smaller arrays at little cost.  In contrast message
buffers are typically large and copying them is expensive, so it is
worthwhile to pass the extra arguments.   Also, if derived data types
are being used, the required value of the {\tt count} argument is
always different to the buffer length.
\end{rationale}

\paragraph{Concurrent access to arrays.}

In JNI-based wrapper implementations it may be
necessary to impose some non-interference rules for concurrent read
and write operations on arrays.  When an array is passed to an
MPI method such as a send or receive operation, the wrapper code will
probably extract a pointer to the contents of the array using a JNI
{\tt Get{\ldots}ArrayElements} routine.  If the garbage collector {\em does
not} support ``pinning'' (temporarily disabling run-time relocation of
data for specific arrays---see \cite{JNIBook} for more
discussion), the pointer returned by this {\tt Get} function may be to
a temporary copy of the elements.  The copy will be written back to the
true Java array when a subsequent call to {\tt
Release{\ldots}ArrayElements} is made.  If two operations involving the
same array are active concurrently, this copy-back may result in
failure to save modifications made by one or more of the concurrent
calls.

Such an implementation may have to enforce a safety rule such as:  {\em
when several MPI send or receive (etc) operations are active
concurrently, if any one of those operations writes to a particular
array, none of the other operations must read or write {\em any
portion} of that array.}

If the garbage collector supports pinning, this problem does not arise.

\subsection{Processes}

No special issues for Java binding.

\subsection{Error Handling}

As explained in section \ref{binding}, the Java methods do not return
error codes.  The Java exceptions thrown instead are defined in section
\ref{errorCodes}.

\newpage

\section{Point-to-Point Communication}

\subsection{Introduction}

In general the mpiJava binding of point-to-point communication operations
realizes the MPI functions as methods of the {\tt Comm} class.
The basic point-to-point communication operations are {\em send} and
{\em receive}.  Their use is illustrated in the example below.

\small
\begin{verbatim}
  import mpi.* ;

  class Hello {
    static public void main(String[] args) throws MPIException {
      MPI.Init(args) ;

      int myrank = MPI.COMM_WORLD.Rank() ;
      if(myrank == 0) {
        char [] message = "Hello, there".toCharArray() ;
        MPI.COMM_WORLD.Send(message, 0, message.length, MPI.CHAR, 1, 99) ;
      }
      else {
        char [] message = new char [20] ;
        MPI.COMM_WORLD.Recv(message, 0, 20, MPI.CHAR, 0, 99) ;
        System.out.println("received:" + new String(message) + ":") ;
      }

      MPI.Finalize();
    }
  }
\end{verbatim}
\normalsize

\subsection{Blocking Send and Receive operations\label{sec:blocking}}

\begin{verbatim}

void Comm.Send(Object buf, int offset, int count,
               Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag
\end{arguments}
Blocking send operation.
Java binding of the MPI operation {\em MPI\_SEND}. 
The data part of the message consists of a sequence of
{\tt count} values, each of the type indicated by {\tt datatype}.
The actual argument associated with {\tt buf} must be an
array.  The value {\tt offset} is a subscript in
this array, defining the position of the first item of the message.

The elements of {\tt buf} may have primitive type or class type.
If the elements are objects, they must be serializable objects.
If the {\tt datatype} argument represents an MPI basic type, its
value must agree with the element type of {\tt buf}:
the basic MPI datatypes supported, and their correspondence to Java types,
are as follows\vspace{0.2in} \\
\centerline{
\begin{tabular}{| l | l |} \hline
MPI datatype & Java datatype \\
\hline
MPI.BYTE     & {\tt byte} \\
MPI.CHAR     & {\tt char} \\
MPI.SHORT    & {\tt short} \\
MPI.BOOLEAN  & {\tt boolean} \\
MPI.INT      & {\tt int} \\
MPI.LONG     & {\tt long} \\
MPI.FLOAT    & {\tt float} \\
MPI.DOUBLE   & {\tt double} \\
MPI.OBJECT   & {\tt Object} \\
\hline
\end{tabular}
} \vspace{0.2in} \newline
If the {\tt datatype} argument represents an MPI derived type, its
{\em base type} must agree with the element type of {\tt buf}
(see section \ref{derived}).
\begin{rationale}
The {\tt datatype} argument is not redundant in mpiJava, because
we include support for MPI derived types.  If it was decided
to remove derived types from the API, {\tt datatype} arguments
could be removed from various functions, and Java runtime inquiries
could be used internally to extract the element type of the buffer,
or methods like {\tt Send} could be overloaded to accept
buffers with elements of the 9 basic types.  
\end{rationale}
If a data type has {\tt MPI.OBJECT} as its base type, the objects in
the buffer will be transparently serialized and unserialized inside the
communication operations.

\begin{verbatim}

Status Comm.Recv(Object buf, int offset, int count,
                 Datatype datatype, int source, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & receive buffer array \\
{\tt offset}   & initial offset in receive buffer \\
{\tt count}    & number of items in receive buffer \\
{\tt datatype} & datatype of each item in receive buffer \\
{\tt source}   & rank of source \\
{\tt tag}      & message tag \\
\\
{\em returns:} & status object
\end{arguments}
Blocking receive operation.  Java binding of the MPI operation {\em
MPI\_RECV}.  The actual argument associated with {\tt buf} must be an
array.  The value {\tt offset} is a subscript in this array, defining
the position into which the first item of the incoming message will be
copied.

The elements of {\tt buf} may have primitive type or class type.
If the {\tt datatype} argument represents an MPI basic type, its
value must agree with the element type of {\tt buf};
if {\tt datatype} represents an MPI derived type, its
{\em base type} must agree with the element type of {\tt buf}
(see section \ref{derived}).

The MPI constants {\em MPI\_ANY\_SOURCE} and {\em MPI\_ANY\_TAG} are
available as {\tt MPI.ANY\_SOURCE} and {\tt MPI.ANY\_TAG}.

The source and tag of the received message are
available in the publically accessible {\tt source} and {\tt tag} fields
of the returned object.
The following method can be used to further interrogate the return status
of a receive operation.
\begin{verbatim}

int Status.Get_count(Datatype datatype)
\end{verbatim}
\begin{arguments}
{\tt datatype} & datatype of each item in receive buffer \\
\\
{\em returns:} & number of received entries
\end{arguments}
Java binding of the MPI operation {\em MPI\_GET\_COUNT}. 

\subsection{Data type matching and data conversion}

The Java language definition places quite detailed constraints on the
representation of its primitive types---for example it requires
conformance with IEEE 754 for {\tt float} and {\tt double}.  There may
still be a requirement for representation conversion in heterogenous
systems.  For example, source and destination computers (or virtual
machines) may have different endianess.

\subsection{Communication Modes}

\begin{verbatim}

void Comm.Bsend(Object buf, int offset, int count,
                Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag
\end{arguments}
Send in buffered mode.
Java binding of the MPI operation {\em MPI\_BSEND}. 
Further comments as for {\tt send}.

\begin{verbatim}

void Comm.Ssend(Object buf, int offset, int count,
                Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag
\end{arguments}
Send in synchronous mode.
Java binding of the MPI operation {\em MPI\_SSEND}. 
Further comments as for {\tt send}.

\begin{verbatim}

void Comm.Rsend(Object buf, int offset, int count,
                Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag
\end{arguments}
Send in ready mode.
Java binding of the MPI operation {\em MPI\_RSEND}. 
Further comments as for {\tt send}.

\subsection{Semantics of point-to-point communication}

No special issues for Java binding.

\subsection{Buffer allocation and usage}

\begin{verbatim}

void MPI.Buffer_attach(byte [] buffer)
\end{verbatim}
\begin{arguments}
{\tt buffer}   & buffer array
\end{arguments}
Provides to MPI a buffer in user's memory to be used for buffering
outgoing messages.
Java binding of the MPI operation {\em MPI\_BUFFER\_ATTACH}. 

\begin{verbatim}

byte [] MPI.Buffer_detach()
\end{verbatim}
\begin{arguments}
{\em returns:} & buffer array
\end{arguments}
Detach the buffer currently associated with MPI and return it.
Java binding of the MPI operation {\em MPI\_BUFFER\_DETACH}. 
If the currently associated buffer is system-defined, returns {\tt null}.

The MPI constant {\em MPI\_BSEND\_OVERHEAD} is available as {\tt
MPI.BSEND\_\-OVERHEAD}.

\subsection{Nonblocking communication}

Nonblocking communications use methods of the {\tt Request}
class to identify communication operations and match the operation
that initiates the communication with the operation that terminates
it.

\begin{verbatim}

Request Comm.Isend(Object buf, int offset, int count,
                   Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & communication request
\end{arguments}
Start a standard mode, nonblocking send.
Java binding of the MPI operation {\em MPI\_ISEND}. 
Further comments as for {\tt send}.

\begin{verbatim}

Request Comm.Ibsend(Object buf, int offset, int count,
                    Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & communication request
\end{arguments}
Start a buffered mode, nonblocking send.
Java binding of the MPI operation {\em MPI\_IBSEND}. 
Further comments as for {\tt send}.

\begin{verbatim}

Request Comm.Issend(Object buf, int offset, int count,
                    Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & communication request
\end{arguments}
Start a synchronous mode, nonblocking send.
Java binding of the MPI operation {\em MPI\_ISSEND}. 
Further comments as for {\tt send}.

\begin{verbatim}

Request Comm.Irsend(Object buf, int offset, int count,
                    Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & communication request
\end{arguments}
Start a ready mode, nonblocking send.
Java binding of the MPI operation {\em MPI\_IRSEND}. 
Further comments as for {\tt send}.

\begin{verbatim}

Request Comm.Irecv(Object buf, int offset, int count,
                   Datatype datatype, int source, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & receive buffer array \\
{\tt offset}   & initial offset in receive buffer \\
{\tt count}    & number of items in receive buffer \\
{\tt datatype} & datatype of each item in receive buffer \\
{\tt source}   & rank of source \\
{\tt tag}      & message tag \\
\\
{\em returns:} & communication request
\end{arguments}
Start a nonblocking receive.
Java binding of the MPI operation {\em MPI\_IRECV}. 
Further comments as for {\tt recv}.

The following functions are used to complete nonblocking communication
operations (and also communications started using the persistent
communication requests---subclass {\tt Prequest}---introduced later).
We use the following terminology.  A request is ``active'' if it is
associated with an ongoing communication.  Otherwise it is inactive.
An inactive instance of the base class {\tt Request} is called a ``void
request''.  (Note, however, that an inactive instance of the {\tt Prequest}
subclass is not said to be ``void'', because it retains detailed
information about a communication pattern even when no corresponding
communication is ongoing.)
\begin{rationale}
A ``void request'' corresponds to what is called a ``null handle'' in
the C and Fortran MPI bindings.  It seems impractical to have
completion operations like {\tt wait} set request object references to
null references in the Java sense (because Java methods cannot directly
modify references passed to them as arguments).  To avoid a confusing
semantic distinction between null MPI handles and null Java references
we introduce the terminology of a ``void request object''.  If an
explicit reference to a void request is needed, one is available as
{\tt MPI.REQUEST\_NULL}.  The inquiry {\tt Request.Is\_null} can be used
to determine if a particular request is void.
\end{rationale}

\begin{verbatim}

Status Request.Wait()
\end{verbatim}
\begin{arguments}
{\em returns:} & status object
\end{arguments}
Blocks until the operation identified by
the request is complete.
Java binding of the MPI operation {\em MPI\_WAIT}. 
After the call returns, the request object becomes inactive.

\begin{verbatim}

Status Request.Test()
\end{verbatim}
\begin{arguments}
{\em returns:} & status object or null reference
\end{arguments}
Returns a status object if the operation
identified by the request is complete, or a null reference otherwise.
Java binding of the MPI operation {\em MPI\_TEST}.
After the call, if the operation is complete (ie, if the return value
of {\tt test} is non-null), the request object becomes an inactive request.

\begin{verbatim}

boolean Request.Is_null()
\end{verbatim}
\begin{arguments}
{\em returns:} & true if the request object is void, false otherwise
\end{arguments}
Note that {\tt Is\_null} is always false on instances of the
subclass {\tt Prequest}.

\begin{verbatim}

void Request.Free()
\end{verbatim}
Set the request object to be void. Java binding of the MPI operation
{\tt MPI\_REQ\-UEST\_FREE}.

\begin{verbatim}

static Status Request.Waitany(Request [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of requests \\
\\
{\em returns:}          & status object
\end{arguments}
Blocks until one of the operations associated with the active
requests in the array has completed.  Java binding of the MPI operation
{\em MPI\_WAITANY}.  The index in {\tt array\_of\_requests} for the
request that completed can be obtained from the status object from
the publically accessible {\tt Status.index} field.  The corresponding
element of {\tt array\_of\_requests} becomes inactive.

The {\tt array\_of\_requests} may contain inactive requests.  If
the list contains no active requests, the method immediately returns a
status in which the {\tt index} field is {\tt MPI.UNDEFINED}.

\begin{verbatim}

static Status Request.Testany(Request [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of requests \\
\\
{\em returns:}        & status object or null reference
\end{arguments}
Tests for completion of either one or none of the operations associated
with active requests.
Java binding of the MPI operation {\em MPI\_TESTANY}. 
If some request completed, the index in {\tt array\_of\_requests} of
that request can be obtained from the status object
through the {\tt Status.index} field.  The corresponding element
of {\tt array\_of\_requests} becomes inactive.
If no request completed, {\tt testAny} returns a null reference. 

The {\tt array\_of\_requests} may contain inactive requests.  If
the list contains no active requests, the method immediately returns a
status in which the {\tt index} field is {\tt MPI.UNDEFINED}.

\begin{verbatim}

static Status [] Request.Waitall(Request [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of requests \\
\\
{\em returns:}        & array of status objects
\end{arguments}
Blocks until all of the operations associated with the active requests
in the array have completed.  Java binding of the MPI operation {\em
MPI\_WAITALL}.  The result array will be the same size as {\tt
array\_of\_requests}.  On exit, requests become inactive.  If the {\em
input} value of {\tt array\_of\_requests} contains any inactive
requests, corresponding elements of the result array will contain null
status references.

\begin{verbatim}

static Status [] Request.Testall(Request [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of requests \\
\\
{\em returns:}        & array of status objects, or a null reference
\end{arguments}
Tests for completion of {\em all} of the operations associated
with active requests.
Java binding of the MPI operation {\em MPI\_TESTALL}. 
If all operations have completed, the exit values of the argument array
and the result array are as for {\tt Waitall}.  If any
operation has not completed, the result value is null and no
element of the argument array is modified.

\begin{verbatim}

static Status [] Request.Waitsome(Request [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of requests \\
\\
{\em returns:}        & array of status objects
\end{arguments}
Blocks until at least one of the operations associated with the active
requests in the array has completed.
Java binding of the MPI operation {\em MPI\_WAITSOME}. 
The size of the result array will be the number of operations that
completed.  The index in {\tt array\_of\_requests} for each request that
completed can be obtained from the {\tt index} field of the
returned status objects.  The corresponding elements in {\tt
array\_of\_requests} become inactive.

If {\tt array\_of\_requests} list contains no active requests, {\tt
testAll} immediately returns a null reference.

\begin{verbatim}

static Status [] Request.Testsome(Request [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of requests \\
\\
{\em returns:}        & array of status objects
\end{arguments}
Behaves like {\tt waitSome}, except that it returns immediately.
Java binding of the MPI operation {\em MPI\_TESTSOME}. 
If no operation has completed, {\tt Testsome} returns an array of length zero
and elements of {\tt array\_of\_requests} are unchanged.
Otherwise, arguments and return value are as for {\tt Waitsome}.

\subsection{Probe and Cancel}

\begin{verbatim}

Status Comm.Iprobe(int source, int tag)
\end{verbatim}
\begin{arguments}
{\tt source}   & source rank \\
{\tt tag}      & tag value \\
\\
{\em returns:} & status object or null reference
\end{arguments}
Check if there is an incoming message matching the pattern specified.
Java binding of the MPI operation {\em MPI\_IPROBE}. 
If such a message is currently available, a status object
similar to the return value of a matching {\tt Recv} operation is returned.
Otherwise a null reference is returned.

\begin{verbatim}

Status Comm.Probe(int source, int tag)
\end{verbatim}
\begin{arguments}
{\tt source}   & source rank \\
{\tt tag}      & tag value \\
\\
{\em returns:} & status object or null reference
\end{arguments}
Wait until there is an incoming message matching the pattern specified.
Java binding of the MPI operation {\em MPI\_PROBE}. 
Returns a status object
similar to the return value of a matching {\tt Recv} operation.

\begin{verbatim}

void Request.Cancel()
\end{verbatim}
Mark a pending nonblocking communication for cancellation.
Java binding of the MPI operation {\em MPI\_CANCEL}. 

\begin{verbatim}

boolean Status.Test_cancelled()
\end{verbatim}
\begin{arguments}
{\em returns:} & true if the operation was succesfully cancelled,
false otherwise
\end{arguments}
Test if communication was cancelled.
Java binding of the MPI operation {\em MPI\_\-TEST\_CANCELLED}. 

\subsection{Persistent communication requests}

\begin{verbatim}

Prequest Comm.Send_init(Object buf, int offset, int count,
                        Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & persistent communication request
\end{arguments}
Creates a persistent communication request for a standard mode send.
Java binding of the MPI operation {\em MPI\_SEND\_INIT}. 
Further comments as for {\tt Send}.

\begin{verbatim}

Prequest Comm.Bsend_init(Object buf, int offset, int count,
                         Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & persistent communication request
\end{arguments}
Creates a persistent communication request for a buffered mode send.
Java binding of the MPI operation {\em MPI\_BSEND\_INIT}. 
Further comments as for {\tt Send}.

\begin{verbatim}

Prequest Comm.Ssend_init(Object buf, int offset, int count,
                         Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & persistent communication request
\end{arguments}
Creates a persistent communication request for a synchronous mode send.
Java binding of the MPI operation {\em MPI\_SSEND\_INIT}. 
Further comments as for {\tt Send}.

\begin{verbatim}

Prequest Comm.Rsend_init(Object buf, int offset, int count,
                         Datatype datatype, int dest, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & send buffer array \\
{\tt offset}   & initial offset in send buffer \\
{\tt count}    & number of items to send \\
{\tt datatype} & datatype of each item in send buffer \\
{\tt dest}     & rank of destination \\
{\tt tag}      & message tag \\
\\
{\em returns:} & persistent communication request
\end{arguments}
Creates a persistent communication request for a ready mode send.
Java binding of the MPI operation {\em MPI\_RSEND\_INIT}. 
Further comments as for {\tt Send}.

\begin{verbatim}

Prequest Comm.Recv_init(Object buf, int offset, int count,
                        Datatype datatype, int source, int tag)
\end{verbatim}
\begin{arguments}
{\tt buf}      & receive buffer array \\
{\tt offset}   & initial offset in receive buffer \\
{\tt count}    & number of items in receive buffer \\
{\tt datatype} & datatype of each item in receive buffer \\
{\tt source}   & rank of source \\
{\tt tag}      & message tag \\
\\
{\em returns:} & persistent communication request
\end{arguments}
Creates a persistent communication request for a receive operation.
Java binding of the MPI operation {\em MPI\_RECV\_INIT}. 
Further comments as for {\tt Recv}.

\begin{verbatim}

void Prequest.Start()
\end{verbatim}
Activate a persistent communication request.
Java binding of the MPI operation {\em MPI\_START}. 
The communication is completed by using the request in
one of the operations {\tt Request.Wait}, {\tt Request.Test}, {\tt
Request.Waitany}, {\tt Request.Test\-any}, {\tt Request.Waitall}, {\tt
Request.Testall}, {\tt Request.Waitsome}, or {\tt Request.\-Testsome}.
On successful completion the request becomes inactive again.
It can be reactivated by a further call to {\tt Start}.

\begin{verbatim}

static void Prequest.Startall(Prequest [] array_of_requests)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_requests} & array of persistent communication requests \\
\end{arguments}
Activate a list of communication requests.
Java binding of the MPI operation {\em MPI\_STARTALL}. 


\subsection{Send-receive}

\begin{verbatim}

Status Comm.Sendrecv(Object sendbuf, int sendoffset,
                     int sendcount, Datatype sendtype,
                     int dest, int sendtag,
                     Object recvbuf, int recvoffset,
                     int recvcount, Datatype recvtype,
                     int source, int recvtag)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items to send \\
{\tt sendtype}   & datatype of each item in send buffer \\
{\tt dest}       & rank of destination \\
{\tt sendtag}    & send tag \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcount}  & number of items in receive buffer \\
{\tt recvtype}   & datatype of each item in receive buffer \\
{\tt source}     & rank of source \\
{\tt recvtag}    & receive tag \\
\\
{\em returns:}   & status object
\end{arguments}
Execute a blocking send and receive operation.
Java binding of the MPI operation {\em MPI\_SENDRECV}. 
Further comments as for {\tt Send} and {\tt Recv}.

\begin{verbatim}

Status Comm.Sendrecv_replace(Object buf, int offset,
                             int count, Datatype datatype,
                             int dest, int sendtag,
                             int source, int recvtag)
\end{verbatim}
\begin{arguments}
{\tt buf}        & buffer array \\
{\tt offset}     & initial offset in buffer \\
{\tt count}      & number of items to send \\
{\tt datatype}   & datatype of each item in buffer \\
{\tt dest}       & rank of destination \\
{\tt sendtag}    & send tag \\
{\tt source}     & rank of source \\
{\tt recvtag}    & receive tag \\
\\
{\em returns:}   & status object
\end{arguments}
Execute a blocking send and receive operation, receiving message
into send buffer.
Java binding of the MPI operation {\em MPI\_SENDRECV\_REPLACE}. 
Further comments as for {\tt send} and {\tt recv}.

\subsection{Null processes}

The constant {\em MPI\_PROC\_NULL} is available as {\tt MPI.PROC\_NULL}.

\subsection{Derived datatypes\label{derived}}

In C or Fortran bindings of MPI, derived datatypes have two roles.
One is to allow messages to contain mixed types (for example they
allow an integer count followed by a sequence of real numbers to be
passed in a single message).  The other is to allow noncontiguous data
to be transmitted.
In mpiJava the first role is abandoned.
Any derived type can only include elements of a single basic type.
\begin{rationale}
In the C binding of MPI, for example, the {\em MPI\_TYPE\_\-STRUCT}
constructor for derived types might be used to describe the physical
layout of a {\em struct} containing mixed types.  This will not
work in Java, because Java does not expose the low-level layout of its
objects.  In C and Fortran another use of {\em MPI\_TYPE\_\-STRUCT}
involves incorporating offsets computed as differences between absolute
addresses, so that parts of a message can come from separately declared
entities.  It might be possible to contrive something analogous in a Java
binding, somehow encoding object references instead of physical
addresses.  Such a contrivance is unlikely to be
very natural---even in C and Fortran the mechanism is not
particularly elegant.  
Meanwhile, the effect of either of these applications of
{\em MPI\_TYPE\_\-STR\-UCT} can be achieved by using {\tt MPI.OBJECT}
as the buffer type, and relying on Java object serialization.
\end{rationale}
This leaves description of noncontiguous buffers as the
essential role for derived data types in mpiJava.

Every derived data type constructable in mpiJava has
a uniquely defined {\em base type}.  This is one of the 9 basic
types enumerated in section \ref{sec:blocking}.
Derived types inherit their base types from their precursors in
a straightforward way.

In mpiJava a {\bf general datatype} is an object that
specifies two things
\begin{itemize}
\item
A base type
\item
A sequence of integer displacements
\end{itemize}
In contrast to the C and Fortran bindings the displacements are
in terms of subscripts in the buffer array argument, {\em not}
byte displacements.

The base types for the predefined MPI datatypes are 
\vspace{0.2in} \\
\centerline{
\begin{tabular}{| l | l |} \hline
MPI datatype & base type \\
\hline
MPI.BYTE     & {\tt byte} \\
MPI.CHAR     & {\tt char} \\
MPI.SHORT    & {\tt short} \\
MPI.BOOLEAN  & {\tt boolean} \\
MPI.INT      & {\tt int} \\
MPI.LONG     & {\tt long} \\
MPI.FLOAT    & {\tt float} \\
MPI.DOUBLE   & {\tt double} \\
MPI.OBJECT   & {\tt Object} \\
MPI.LB       & $\perp$  \\
MPI.UB       & $\perp$  \\
MPI.PACKED   & {\tt byte} \\
\hline
\end{tabular}
} \vspace{0.2in} \newline
The symbol $\perp$ is a special undefined value.
The displacement sequences for the predefined types (other than
{\tt MPI.LB}, {\tt MPI.UB}) consist of a single zero.

If the displacement sequence of a datatype is
\begin{displaymath}
\mbox{\em DispSeq} = \{ \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1} \}
\end{displaymath}
we define
\begin{eqnarray*}
\mbox{\em lb}(\mbox{\em DispSeq}) & = & \min_j \mbox{\em disp}_j, \\
\mbox{\em ub}(\mbox{\em DispSeq}) & = & \max_j (\mbox{\em disp}_j + 1),
                                                        \quad \mbox{and} \\
\mbox{\em extent}(\mbox{\em DispSeq}) & = &
  \mbox{\em ub}(\mbox{\em DispSeq}) - \mbox{\em lb}(\mbox{\em DispSeq})
\end{eqnarray*}
\begin{rationale}
This definition of the extent differs from the definition in the C or
Fortran.  It is in units of the buffer array index, {\em not} in units
of bytes.
\end{rationale}
As discussed at the end of this section, these definitions have to be
modified if the type construction involves {\tt MPI.LB}, {\tt MPI.UB}.

\begin{verbatim}

static Datatype Datatype.Contiguous(int count, Datatype oldtype)
\end{verbatim}
\begin{arguments}
{\tt count}      & replication count \\
{\tt oldtype}    & old datatype \\
\\
{\em returns:}   & new datatype
\end{arguments}
Construct new datatype representing replication of the old datatype into
contiguous locations.
Java binding of the MPI operation {\em MPI\_TYPE\_CONTIG\-UOUS}.
The base type of the new datatype is the same as the base type of
the old type.  Assume the displacement sequence of the old type is
\begin{displaymath}
\{ \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1} \}
\end{displaymath}
with extent {\em ex}.  Then the new datatype has a displacement sequence
with {\tt count} $\cdot$ {\tt n} entries defined by:
\begin{eqnarray*}
&\{ & \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1}, \\
&   & \mbox{\em disp}_0 + ex, \ldots, \mbox{\em disp}_{n - 1} + ex, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 + ex \cdot (\mbox{\tt count} - 1),
      \ldots, \mbox{\em disp}_{n - 1} + ex \cdot (\mbox{\tt count} - 1)
\quad \}
\end{eqnarray*}

\begin{verbatim}

static Datatype Datatype.Vector(int count,
                                int blocklength, int stride,
                                Datatype oldtype)
\end{verbatim}
\begin{arguments}
{\tt count}       & number of blocks \\
{\tt blocklength} & number of elements in each block \\
{\tt stride}      & number of elements between start of each block \\
{\tt oldtype}     & old datatype \\
\\
{\em returns:}    & new datatype
\end{arguments}
Construct new datatype representing replication of the old datatype into
locations that consist of equally spaced blocks.
Java binding of the MPI operation {\em MPI\_TYPE\_VECTOR}.
The base type of the new datatype is the same as the base type of
the old type.  Assume the displacement sequence of the old type is
\begin{displaymath}
\{ \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1} \}
\end{displaymath}
with extent {\em ex}.  Let {\tt bl} be {\tt blocklength}.
Then the new datatype has a displacement sequence
with {\tt count} $\cdot$ {\tt bl} $\cdot$ {\tt n} entries defined by:
\begin{eqnarray*}
&\{ & \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1}, \\
&   & \mbox{\em disp}_0 + \mbox{\em ex}, \ldots,
       \mbox{\em disp}_{n - 1} + \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 + \mbox{\em ex} \cdot (\mbox{\tt bl} - 1),
      \ldots, \mbox{\em disp}_{n - 1} +
          \mbox{\em ex} \cdot (\mbox{\tt bl} - 1), \\
\\
&   & \mbox{\em disp}_0 + \mbox{\em ex} \cdot \mbox{\tt stride},
      \ldots, \mbox{\em disp}_{n - 1} +
          \mbox{\em ex} \cdot \mbox{\tt stride}, \\
&   & \mbox{\em disp}_0 + \mbox{\em ex} \cdot (\mbox{\tt stride} + 1),
      \ldots,
      \mbox{\em disp}_{n - 1} + \mbox{\em ex} \cdot (\mbox{\tt stride} + 1), \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
          \mbox{\em ex} \cdot (\mbox{\tt stride} + \mbox{\tt bl} - 1),
      \ldots,
      \mbox{\em disp}_{n - 1} +
          \mbox{\em ex} \cdot (\mbox{\tt stride} + \mbox{\tt bl} - 1), \\
\\
&   & \ldots , \\
\\
&   & \mbox{\em disp}_0 +
          \mbox{\em ex} \cdot \mbox{\tt stride} \cdot (\mbox{\tt count} - 1),
      \ldots,
      \mbox{\em disp}_{n - 1} +
          \mbox{\em ex} \cdot \mbox{\tt stride} \cdot (\mbox{\tt count} - 1), \\
&   & \mbox{\em disp}_0 +
        \mbox{\em ex} \cdot (\mbox{\tt stride}
           \cdot (\mbox{\tt count} - 1) + 1),
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}_{n - 1} +
        \mbox{\em ex} \cdot (\mbox{\tt stride}
           \cdot (\mbox{\tt count} - 1) + 1), \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
        \mbox{\em ex} \cdot (\mbox{\tt stride}
           \cdot (\mbox{\tt count} - 1) + \mbox{\tt bl} - 1),
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}_{n - 1} +
        \mbox{\em ex} \cdot (\mbox{\tt stride}
           \cdot (\mbox{\tt count} - 1) + \mbox{\tt bl} - 1)
\quad \}
\end{eqnarray*}


\begin{verbatim}

static Datatype Datatype.Hvector(int count,
                                 int blocklength, int stride,
                                 Datatype oldtype)
\end{verbatim}
\begin{arguments}
{\tt count}       & number of blocks \\
{\tt blocklength} & number of elements in each block \\
{\tt stride}      & number of elements between start of each block \\
{\tt oldtype}     & old datatype \\
\\
{\em returns:}    & new datatype
\end{arguments}
Identical to {\tt Vector} except that the stride is expressed
directly in terms of the buffer index, rather than the units of the old type.
Java binding of the MPI operation {\em MPI\_TYPE\_HVECTOR}.
{\em Unlike other language bindings}, the value
of {\tt stride} is {\em not} measured in bytes.
The displacement sequence of the new type is:
\begin{eqnarray*}
&\{ & \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1}, \\
&   & \mbox{\em disp}_0 + \mbox{\em ex}, \ldots,
       \mbox{\em disp}_{n - 1} + \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 + \mbox{\em ex} \cdot (\mbox{\tt bl} - 1),
      \ldots, \mbox{\em disp}_{n - 1} +
          \mbox{\em ex} \cdot (\mbox{\tt bl} - 1), \\
\\
&   & \mbox{\em disp}_0 + \mbox{\em ex} \cdot \mbox{\tt stride},
      \ldots, \mbox{\em disp}_{n - 1} + \mbox{\tt stride}, \\
&   & \mbox{\em disp}_0 + \mbox{\tt stride} + \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} + \mbox{\tt stride} + \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
          \mbox{\tt stride} + \mbox{\em ex} \cdot (\mbox{\tt bl} - 1),
      \ldots,
      \mbox{\em disp}_{n - 1} +
          \mbox{\tt stride} + \mbox{\em ex} \cdot (\mbox{\tt bl} - 1), \\
\\
&   & \ldots , \\
\\
&   & \mbox{\em disp}_0 + \mbox{\tt stride} \cdot (\mbox{\tt count} - 1),
      \ldots,
      \mbox{\em disp}_{n - 1} +
          \mbox{\tt stride} \cdot (\mbox{\tt count} - 1), \\
&   & \mbox{\em disp}_0 +
           \mbox{\tt stride} \cdot (\mbox{\tt count} - 1) + \mbox{\em ex},
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}_{n - 1} +
        \mbox{\tt stride} \cdot (\mbox{\tt count} - 1) + \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
        \mbox{\tt stride} \cdot (\mbox{\tt count} - 1) +
           \mbox{\em ex} \cdot (\mbox{\tt bl} - 1),
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}_{n - 1} +
        \mbox{\tt stride} \cdot (\mbox{\tt count} - 1) +
           \mbox{\em ex} \cdot (\mbox{\tt bl} - 1)
\quad \}
\end{eqnarray*}

\begin{verbatim}

static Datatype Datatype.Indexed(int [] array_of_blocklengths,
                                 int [] array_of_displacements,
                                 Datatype oldtype)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_blocklengths}  & number of elements per block \\
{\tt array\_of\_displacements} & displacement of each block in units of old type \\
{\tt oldtype}     & old datatype \\
\\
{\em returns:}             & new datatype
\end{arguments}
Construct new datatype representing replication of the old type into
a sequence of blocks where each block can contain a different number
of copies and have a different displacement.
Java binding of the MPI operation {\em MPI\_TYPE\_\-INDEXED}.  The number
of blocks is taken to be size of the {\tt arrayOf\-Block\-lengths}
argument.  The second argument, {\tt array\_of\_displacements}, should
be the same size.
The base type of the new datatype is the same as the base type of
the old type.  Assume the displacement sequence of the old type is
\begin{displaymath}
\{ \mbox{\em disp}_0, \ldots, \mbox{\em disp}_{n - 1} \}
\end{displaymath}
with extent {\em ex}.  Let {\tt B} be the {\tt array\_of\_blocklengths}
argument and {\tt D} be the {\tt array\_of\_displacements} argument.
Then the new datatype has a displacement sequence with
$n \cdot \sum_{i=0}^{\mbox{\em count} - 1} \mbox{\tt B}[i]$ entries:
\begin{eqnarray*}
&\{ & \mbox{\em disp}_0 + \mbox{\tt D}[0] \cdot \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} + \mbox{\tt D}[0] \cdot \mbox{\em ex}, \\
&   & \mbox{\em disp}_0 + (\mbox{\tt D}[0] + 1) \cdot \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} + (\mbox{\tt D}[0] + 1) \cdot \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
         (\mbox{\tt D}[0] + \mbox{\tt B} [0] - 1) \cdot \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} +
         (\mbox{\tt D}[0] + \mbox{\tt B} [0] - 1) \cdot \mbox{\em ex}, \\
\\
&   & \ldots , \\
\\
&   & \mbox{\em disp}_0 + \mbox{\tt D}[\mbox{\em count} - 1]
         \cdot \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} +
         \mbox{\tt D}[\mbox{\em count} - 1] \cdot \mbox{\em ex}, \\
&   & \mbox{\em disp}_0 +
         (\mbox{\tt D}[\mbox{\em count} - 1] + 1) \cdot \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} +
         (\mbox{\tt D}[\mbox{\em count} - 1] + 1) \cdot \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
         (\mbox{\tt D}[\mbox{\em count} - 1] +
            \mbox{\tt B} [\mbox{\em count} - 1] - 1) \cdot \mbox{\em ex},
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}_{n - 1} +
         (\mbox{\tt D}[\mbox{\em count} - 1] +
            \mbox{\tt B} [\mbox{\em count} - 1] - 1) \cdot \mbox{\em ex}
\quad \}
\end{eqnarray*}
Here, {\em count} is the number of blocks.


\begin{verbatim}

static Datatype Datatype.Hindexed(int [] array_of_blocklengths,
                                  int [] array_of_displacements,
                                  Datatype oldtype)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_blocklengths}  & number of elements per block \\
{\tt array\_of\_displacements} & displacement in buffer for each block \\
{\tt oldtype}     & old datatype \\
\\
{\em returns:}             & new datatype
\end{arguments}
Identical to {\tt indexed} except that the displacements are expressed
directly in terms of the buffer index, rather than the units of the old type.
Java binding of the MPI operation {\em MPI\_TYPE\_HINDEXED}.
{\em Unlike other language bindings}, the values
in {\tt array\_of\_displacements} are {\em not} measured in bytes.
The displacement sequence of the new type is:
\begin{eqnarray*}
&\{ & \mbox{\em disp}_0 + \mbox{\tt D}[0],
      \ldots,
      \mbox{\em disp}_{n - 1} + \mbox{\tt D}[0], \\
&   & \mbox{\em disp}_0 + \mbox{\tt D}[0] + \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} + \mbox{\tt D}[0] + \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
         \mbox{\tt D}[0] + (\mbox{\tt B} [0] - 1) \cdot \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} +
         \mbox{\tt D}[0] + (\mbox{\tt B} [0] - 1) \cdot \mbox{\em ex}, \\
\\
&   & \ldots , \\
\\
&   & \mbox{\em disp}_0 + \mbox{\tt D}[\mbox{\em count} - 1],
      \ldots,
      \mbox{\em disp}_{n - 1} + \mbox{\tt D}[\mbox{\em count} - 1], \\
&   & \mbox{\em disp}_0 +
         \mbox{\tt D}[\mbox{\em count} - 1] + \mbox{\em ex},
      \ldots,
      \mbox{\em disp}_{n - 1} +
         \mbox{\tt D}[\mbox{\em count} - 1] + \mbox{\em ex}, \\
&   & \ldots , \\
&   & \mbox{\em disp}_0 +
         \mbox{\tt D}[\mbox{\em count} - 1] +
            (\mbox{\tt B} [\mbox{\em count} - 1] - 1) \cdot \mbox{\em ex},
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}_{n - 1} +
         \mbox{\tt D}[\mbox{\em count} - 1] +
            (\mbox{\tt B} [\mbox{\em count} - 1] - 1) \cdot \mbox{\em ex}
\quad \}
\end{eqnarray*}


\begin{verbatim}

static Datatype Datatype.Struct(int [] array_of_blocklengths,
                                int [] array_of_displacements,
                                Datatype [] array_of_types)
\end{verbatim}
\begin{arguments}
{\tt array\_of\_blocklengths}  & number of elements per block \\
{\tt array\_of\_displacements} & displacement in buffer for each block \\
{\tt array\_of\_types}         & type of elements in each block \\
\\
{\em returns:}             & new datatype
\end{arguments}
The most general type constructor.
Java binding of the MPI operation {\em MPI\_\-TYPE\_STRUCT}.  The number
of blocks is taken to be size of the {\tt array\_of\_\-blocklengths}
argument.  The second and third arguments, {\tt array\_of\_displace\-ments}
and {\tt array\_of\_types}, should be the same size.
{\em Unlike other language bindings}, the values
in {\tt array\_of\_\-displacements} are {\em not} measured in bytes.
All elements of {\tt array\_of\_types} with definite base types {\em must have the
{\em same} base type}: this will be the base type of new datatype.
Let {\tt T} be the {\tt array\_of\_types} argument.
Assume the displacement sequence of the old type $\mbox{\tt T}[i]$ is
\begin{displaymath}
\{ \mbox{\em disp}^i_0, \ldots, \mbox{\em disp}^i_{n_i - 1} \}
\end{displaymath}
with extent $\mbox{\em ex}_i$.  Let {\tt B} be the {\tt array\_of\_blocklengths}
argument and {\tt D} be the {\tt array\_of\_displacements} argument.
Then the new datatype has a displacement sequence with
$\sum_{i=0}^{c - 1} \mbox{\tt B}[i] \cdot n_i$ entries:
\begin{eqnarray*}
&\{ & \mbox{\em disp}^0_0 + \mbox{\tt D}[0],
      \ldots,
      \mbox{\em disp}^0_{n_0 - 1} + \mbox{\tt D}[0], \\
&   & \mbox{\em disp}^0_0 + \mbox{\tt D}[0] + \mbox{\em ex}_0,
      \ldots,
      \mbox{\em disp}^0_{n_0 - 1} + \mbox{\tt D}[0] + \mbox{\em ex}_0, \\
&   & \ldots , \\
&   & \mbox{\em disp}^0_0 +
         \mbox{\tt D}[0] + (\mbox{\tt B} [0] - 1) \cdot \mbox{\em ex}_0,
      \ldots,
      \mbox{\em disp}^0_{n_0 - 1} +
         \mbox{\tt D}[0] + (\mbox{\tt B} [0] - 1) \cdot \mbox{\em ex}_0, \\
\\
&   & \ldots , \\
\\
&   & \mbox{\em disp}^{c - 1}_0 + \mbox{\tt D}[c - 1],
      \ldots,
      \mbox{\em disp}^{c - 1}_{n_{c - 1} - 1} + \mbox{\tt D}[c - 1], \\
&   & \mbox{\em disp}^{c - 1}_0 +
         \mbox{\tt D}[c - 1] + \mbox{\em ex}_{c - 1},
      \ldots,
      \mbox{\em disp}^{c - 1}_{n_{c - 1} - 1} +
         \mbox{\tt D}[c - 1] + \mbox{\em ex}_{c - 1}, \\
&   & \ldots , \\
&   & \mbox{\em disp}^{c - 1}_0 +
         \mbox{\tt D}[c - 1] +
            (\mbox{\tt B} [c - 1] - 1) \cdot \mbox{\em ex}_{c - 1},
      \ldots, \\
&   & \quad \quad \quad \quad \quad \mbox{\em disp}^{c - 1}_{n_{c - 1} - 1} +
         \mbox{\tt D}[c - 1] +
            (\mbox{\tt B} [c - 1] - 1) \cdot \mbox{\em ex}_{c - 1}
\quad \}
\end{eqnarray*}
Here, $c$ is the number of blocks.

If any elements of {\tt array\_of\_types} are {\tt MPI.LB} or {\tt MPI.UB},
the corresponding displacements are omitted in the displacement
sequence.  These displacements only affect the computation of
{\tt Datatype.Lb}, {\tt Datatype.Ub} and {\tt Datatype.Ext\-ent},
as explained below.

\paragraph{Revised definition of general datatype.}
In the presence of {\tt MPI.LB}, {\tt MPI.UB} component types,
an mpiJava general datatype can be represented by four things:
\begin{itemize}
\item
A base type
\item
A sequence, {\em DispSeq}, of proper displacements.
\item
A set, {\em LBDisps}, of pseudo-displacements for {\tt MPI.LB} markers.
\item
A set, {\em UBDisps}, of pseudo-displacements for {\tt MPI.UB} markers.
\end{itemize}
For basic datatypes other than {\tt MPI.LB}, {\tt MPI.UB} the
displacements take the form
\begin{eqnarray*}
\mbox{\em DispSeq} & = & \{0\} \\
\mbox{\em LBDisps} & = & \emptyset \\
\mbox{\em UBDisps} & = & \emptyset
\end{eqnarray*}
For {\tt MPI.LB} they are
\begin{eqnarray*}
\mbox{\em DispSeq} & = & \emptyset \\
\mbox{\em LBDisps} & = & \{0\} \\
\mbox{\em UBDisps} & = & \emptyset
\end{eqnarray*}
For {\tt MPI.UB} they are
\begin{eqnarray*}
\mbox{\em DispSeq} & = & \emptyset \\
\mbox{\em LBDisps} & = & \emptyset \\
\mbox{\em UBDisps} & = & \{0\}
\end{eqnarray*}
The two sets of pseudo-displacements are propagated to derived types
by formulae identical to the ones given above for proper displacements.
Below we will use the definition\footnote{The notation is slightly informal.
{\em DispSeq} is really an ordered sequence rather than a set.
We occasionally use the name loosely to refer to the set of its elements.}
\begin{displaymath}
  \mbox{\em AllDisps} = \mbox{\em DispSeq} \cup
                        \mbox{\em LBDisps} \cup \mbox{\em UBDisps}
\end{displaymath}

\begin{verbatim}

int Datatype.Extent()
\end{verbatim}
\begin{arguments}
{\em returns:}             & datatype extent
\end{arguments}
Returns the extent of a datatype.
Java binding of the MPI operation {\em MPI\_\-TYPE\_\-EXTENT}.
Return value is equal to
\begin{displaymath}
  \mbox{\tt Ub()} - \mbox{\tt Lb()}
\end{displaymath}

\begin{verbatim}

int Datatype.Lb()
\end{verbatim}
\begin{arguments}
{\em returns:}             & displacement of lower bound from origin
\end{arguments}
Find the lower bound of a datatype.
Java binding of the MPI operation {\em MPI\_\-TYPE\_LB}.
If {\em LBDisps} is non-empty the return value of {\tt Lb}
is the least element of that set.  Otherwise it is the least
element of {\em AllDisps}\footnote{If {\em AllDisps} is empty (which
could happen for a derived datatype created with replication count
of zero, for instance) the results of {\tt Lb}, {\tt Ub} and thus {\tt
Extent} are undefined.}.

\begin{verbatim}

int Datatype.Ub()
\end{verbatim}
\begin{arguments}
{\em returns:}             & displacement of upper bound from origin
\end{arguments}
Find the upper bound of a datatype.
Java binding of the MPI operation {\em MPI\_\-TYPE\_UB}.
If {\em UBDisps} is non-empty the return value of {\tt Ub}
is the greatest element of that set.  Otherwise it is
\begin{displaymath}
\max_{\mbox{\scriptsize \em disp} \in \mbox{\scriptsize \em AllDisps}}
\mbox{\em disp} + 1
\end{displaymath}

\begin{verbatim}

int Datatype.Size()
\end{verbatim}
\begin{arguments}
{\em returns:}             & datatype size
\end{arguments}
Returns the total size of the type.
Java binding of the MPI operation {\em MPI\_\-TYPE\_SIZE}.
Size is defined as the total number of buffer elements incorporated by
the data type, or equivalently as the length of the displacement
sequence.  {\em Unlike other language bindings}, the size is {\em not}
measured in bytes.


\begin{verbatim}

void Datatype.Commit()
\end{verbatim}
Commit a derived datatype.
Java binding of the MPI operation {\em MPI\_TYPE\_\-COMMIT}.

\begin{verbatim}

void Datatype.finalize()
\end{verbatim}
Destructor.  Java binding of the MPI operation {\em MPI\_TYPE\_FREE}.

\begin{verbatim}

int Status.Get_elements(Datatype datatype)
\end{verbatim}
\begin{arguments}
{\tt datatype}         & datatype used by receive operation \\
\\
{\em returns:}         & number of received basic elements
\end{arguments}
Retrieve number of basic elements from status.
Java binding of the MPI operation {\em MPI\_GET\_ELEMENTS}.

\subsection{Pack and unpack}

\begin{verbatim}

int Comm.Pack(Object inbuf, int offset, int incount,
              Datatype datatype,
              byte [] outbuf, int position)
\end{verbatim}
\begin{arguments}
{\tt inbuf}    & input buffer array \\
{\tt offset}   & initial offset in input buffer \\
{\tt incount}  & number of items in input buffer \\
{\tt datatype} & datatype of each item in input buffer \\
{\tt outbuf}   & output buffer \\
{\tt position} & initial position in ouput buffer \\
\\
{\em returns:} & final position in output buffer
\end{arguments}
Packs message in send buffer {\tt inbuf} into space specified in
{\tt outbuf}.
Java binding of the MPI operation {\em MPI\_PACK}.
The return value is the output value of {\tt position}---the
inital value incremented by the number of bytes written.

\begin{verbatim}

int Comm.Unpack(byte [] inbuf, int position,
                Object outbuf, int offset, int outcount,
                Datatype datatype)
\end{verbatim}
\begin{arguments}
{\tt inbuf}    & input buffer \\
{\tt position} & initial position in input buffer \\
{\tt outbuf}   & output buffer array \\
{\tt offset}   & initial offset in output buffer \\
{\tt outcount} & number of items in output buffer \\
{\tt datatype} & datatype of each item in output buffer \\
\\
{\em returns:} & final position in input buffer
\end{arguments}
Unpacks message in receive buffer {\tt outbuf} into space specified in
{\tt inbuf}.
Java binding of the MPI operation {\em MPI\_UNPACK}.
The return value is the output value of {\em position}---the
inital value incremented by the number of bytes read.

\begin{verbatim}

int Comm.Pack_size(int incount, Datatype datatype)
\end{verbatim}
\begin{arguments}
{\tt incount}  & number of items in input buffer \\
{\tt datatype} & datatype of each item in input buffer \\
\\
{\em returns:} & upper bound on size of packed message
\end{arguments}
Returns an upper bound on the increment of {\tt position} effected
by {\tt pack}.
Java binding of the MPI operation {\em MPI\_PACK\_SIZE}.
{\em It is an error to call this function if the base type of {\tt datatype}
is {\tt MPI.OBJECT}}.

\newpage

\section{Collective Communication}

\subsection{Introduction and Overview}

In general the mpiJava bindings of collective communication operations
realize the MPI functions as members of the {\tt IntraComm} class.

\subsection{Communicator argument}

No special issues for Java binding.

\subsection{Barrier synchronization}

\begin{verbatim}

void Intracomm.Barrier()
\end{verbatim}
A call to {\tt Barrier} blocks the caller until all processes
in the group have called it.
Java binding of the MPI operation {\em MPI\_BARRIER}.

\subsection{Broadcast}

\begin{verbatim}
void Intracomm.Bcast(Object buffer, int offset, int count,
                     Datatype datatype, int root)
\end{verbatim}
\begin{arguments}
{\tt buf}      & buffer array \\
{\tt offset}   & initial offset in buffer \\
{\tt count}    & number of items in buffer \\
{\tt datatype} & datatype of each item in buffer \\
{\tt dest}     & rank of broadcast root
\end{arguments}
Broadcast a message from the process with rank {\tt root}
to all processes of the group.
Java binding of the MPI operation {\em MPI\_BCAST}.

\subsection{Gather}

\begin{verbatim}

void Intracomm.Gather(Object sendbuf, int sendoffset,
                      int sendcount, Datatype sendtype,
                      Object recvbuf, int recvoffset,
                      int recvcount, Datatype recvtype, int root)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items to send \\
{\tt sendtype}   & datatype of each item in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcount}  & number of items in receive buffer \\
{\tt recvtype}   & datatype of each item in receive buffer \\
{\tt root}       & rank of receiving process
\end{arguments}
Each process sends the contents of its send buffer to the
root process.
Java binding of the MPI operation {\em MPI\_GATHER}.

\begin{verbatim}

void Intracomm.Gatherv(Object sendbuf, int sendoffset,
                       int sendcount, Datatype sendtype,
                       Object recvbuf, int recvoffset,
                       int [] recvcounts, int [] displs,
                       Datatype recvtype, int root)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items to send \\
{\tt sendtype}   & datatype of each item in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcounts} & number of elements received from each process \\
{\tt displs}     & displacements at which to place incoming data \\
{\tt recvtype}   & datatype of each item in receive buffer \\
{\tt root}       & rank of receiving process
\end{arguments}
Extends functionality of {\tt Gather} by allowing varying
counts of data from each process.
Java binding of the MPI operation {\em MPI\_GATHERV}.
The sizes of arrays {\tt recvcounts} and {\tt displs} should be the
size of the group.  Entry $i$ of {\tt displs} specifies the
displacement relative to element {\tt recvoffset} of {\tt recvbuf}
at which to place incoming data.  Note that if {\tt recvtype} is a
derived data type, elements of {\tt displs} are in units of the derived
type extent, (unlike {\tt recvoffset}, which is a direct index into the
buffer array).

\subsection{Scatter}

\begin{verbatim}

void Intracomm.Scatter(Object sendbuf, int sendoffset,
                       int sendcount, Datatype sendtype,
                       Object recvbuf, int recvoffset,
                       int recvcount, Datatype recvtype,
                       int root)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items sent to each process \\
{\tt sendtype}   & datatype of send buffer items \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcount}  & number of items in receive buffer \\
{\tt recvtype}   & datatype of receive buffer items \\
{\tt root}       & rank of sending process
\end{arguments}
Inverse of the operation {\tt Gather}.
Java binding of the MPI operation {\em MPI\_SCAT\-TER}.

\begin{verbatim}

void Intracomm.Scatterv(Object sendbuf, int sendoffset,
                        int [] sendcounts, int [] displs,
                        Datatype sendtype,
                        Object recvbuf, int recvoffset,
                        int recvcount, Datatype recvtype,
                        int root)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcounts} & number of items sent to each process \\
{\tt displs}     & displacements from which to take outgoing data \\
{\tt sendtype}   & datatype of each item in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcount}  & number of elements in receive buffer \\
{\tt recvtype}   & datatype of receive buffer items \\
{\tt root}       & rank of sending process
\end{arguments}
Inverse of the operation {\tt Gatherv}.
Java binding of the MPI operation {\em MPI\_\-SCATTERV}.

\subsection{Gather-to-all}

\begin{verbatim}

void Intracomm.Allgather(Object sendbuf, int sendoffset,
                         int sendcount, Datatype sendtype,
                         Object recvbuf, int recvoffset,
                         int recvcount, Datatype recvtype)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items sent to each process \\
{\tt sendtype}   & datatype of send buffer items \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcount}  & number of items in receive buffer \\
{\tt recvtype}   & datatype of receive buffer items
\end{arguments}
Similar to {\tt Gather}, but all processes receive the result.
Java binding of the MPI operation {\em MPI\_ALLGATHER}.

\begin{verbatim}

void Intracomm.Allgatherv(Object sendbuf, int sendoffset,
                          int sendcount, Datatype sendtype,
                          Object recvbuf, int recvoffset,
                          int [] recvcounts, int [] displs,
                          Datatype recvtype)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items to send \\
{\tt sendtype}   & datatype of each item in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcounts} & number of elements received from each process \\
{\tt displs}     & displacements at which to place incoming data \\
{\tt recvtype}   & datatype of each item in receive buffer \\
\end{arguments}
Similar to {\tt Gatherv}, but all processes receive the result.
Java binding of the MPI operation {\em MPI\_GATHERV}.

\subsection{All-to-All Scatter/Gather}

\begin{verbatim}

void Intracomm.Alltoall(Object sendbuf, int sendoffset,
                        int sendcount, Datatype sendtype,
                        Object recvbuf, int recvoffset,
                        recvcount, Datatype recvtype)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcount}  & number of items sent to each process \\
{\tt sendtype}   & datatype of send buffer items \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcount}  & number of items received from any process \\
{\tt recvtype}   & datatype of receive buffer items
\end{arguments}
Extension of {\tt Allgather} to the case where each process sends
distinct data to each of the receivers.
Java binding of the MPI operation {\em MPI\_ALLTOALL}.

\begin{verbatim}

void Intracomm.Alltoallv(Object sendbuf, int sendoffset,
                         int [] sendcount, int [] sdispls,
                         Datatype sendtype,
                         Object recvbuf, int recvoffset,
                         int [] recvcount, int [] rdispls,
                         Datatype recvtype)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt sendcounts} & number of items sent to each process \\
{\tt sdispls}    & displacements from which to take outgoing data \\
{\tt sendtype}   & datatype of each item in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcounts} & number of elements received from each process \\
{\tt rdispls}    & displacements at which to place incoming data \\
{\tt recvtype}   & datatype of each item in receive buffer \\
\end{arguments}
Adds flexibility to {\tt Alltoall}: location of data for send is
specified by {\tt sdispls} and location to place data on receive
side is specified by {\tt rdispls}.
Java binding of the MPI operation {\em MPI\_ALLTOALLV}.

\subsection{Global Reduction Operations}

\begin{verbatim}

void Intracomm.Reduce(Object sendbuf, int sendoffset,
                      Object recvbuf, int recvoffset,
                      int count, Datatype datatype,
                      Op op, int root)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt count}      & number of items in send buffer \\
{\tt datatype}   & data type of each item in send buffer \\
{\tt op}         & reduce operation \\
{\tt dest}       & rank of root process
\end{arguments}
Combine elements in input buffer of each process using the reduce operation,
and return the combined value in the output buffer of the root process.
Java binding of the MPI operation {\em MPI\_REDUCE}.

The predefined operations are available in Java as {\tt MPI.MAX}, {\tt
MPI.MIN}, {\tt MPI.\-SUM}, {\tt MPI.PROD}, {\tt MPI.LAND}, {\tt
MPI.BAND}, {\tt MPI.LOR}, {\tt MPI.BOR}, {\tt MPI.LXOR}, {\tt
MPI.BXOR}, {\tt MPI.\-MINLOC} and {\tt MPI.MAXLOC}.

The handling of {\em MINLOC} and {\em MAXLOC} is modelled on the
Fortran binding.  The extra predefined types {\tt MPI.SHORT2}, {\tt
MPI.INT2}, {\tt MPI.LONG2}, {\tt MPI.FLOAT2}, {\tt MPI.DOUBLE2}
describe pairs of Java numeric primitive types.

\begin{verbatim}

Op.Op(User_function function, boolean commute)
\end{verbatim}
\begin{arguments}
{\tt function}   & user defined function \\
{\tt commute}    & {\tt true} if commutative, {\tt false} otherwise
\end{arguments}
Bind a user-defined global reduction operation to an {\tt Op}
object.
Java binding of the MPI operation {\em MPI\_OP\_CREATE}.
The abstract base class {\tt User\_function} is defined by
\small
\begin{verbatim}
  class User_function {
    public abstract void Call(Object invec, int inoffset,
                              Object inoutvec, int inoutoffset,
                              int count, Datatype datatype) ;
  }
\end{verbatim}
\normalsize
To define a new operation, the programmer should define a concrete
subclass of {\tt User\_function}, implementing the {\tt Call} method,
then pass an object from this class to the {\tt Op} constructor.  The
{\tt User\_function.Call} method plays exactly the same role as the
{\tt function} argument in the standard bindings of MPI.  The actual
arguments {\tt invec} and {\tt inoutvec} passed to {\tt call} will be
arrays containing {\tt count} elements of the type specified in the {\tt
datatype} argument.   Offsets in the arrays can be specified as for
message buffers.  The user-defined {\tt Call} method should combine the
arrays element by element, with results appearing in {\tt inoutvec}.

\begin{verbatim}

void Op.finalize()
\end{verbatim}
Destructor.  Java binding of the MPI operation {\em MPI\_OP\_FREE}.

\begin{verbatim}

void Intracomm.Allreduce(Object sendbuf, int sendoffset,
                         Object recvbuf, int recvoffset,
                         int count, Datatype datatype,
                         Op op)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt count}      & number of items in send buffer \\
{\tt datatype}   & data type of each item in send buffer \\
{\tt op}         & reduce operation \\
\end{arguments}
Same as {\tt Reduce} except that the result appears in receive
buffer of all processes in the group.
Java binding of the MPI operation {\em MPI\_ALLREDUCE}.

\subsection{Reduce-Scatter}

\begin{verbatim}

void Intracomm.Reduce_scatter(Object sendbuf, int sendoffset,
                              Object recvbuf, int recvoffset,
                              int [] recvcounts,
                              Datatype datatype, Op op)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt recvcounts} & numbers of result elements distributed to each process \\
{\tt datatype}   & data type of each item in send buffer \\
{\tt op}         & reduce operation \\
\end{arguments}
Combine elements in input buffer of each process using the reduce operation,
and scatter the combined values over the output buffers of the processes.
Java binding of the MPI operation {\em MPI\_REDUCE\_SCATTER}.

\subsection{Scan}

\begin{verbatim}

void Intracomm.Scan(Object sendbuf, int sendoffset,
                    Object recvbuf, int recvoffset,
                    int count, Datatype datatype,
                    Op op)
\end{verbatim}
\begin{arguments}
{\tt sendbuf}    & send buffer array \\
{\tt sendoffset} & initial offset in send buffer \\
{\tt recvbuf}    & receive buffer array \\
{\tt recvoffset} & initial offset in receive buffer \\
{\tt count}      & number of items in input buffer \\
{\tt datatype}   & data type of each item in input buffer \\
{\tt op}         & reduce operation \\
\end{arguments}
Perform a prefix reduction on data distributed across the group.
Java binding of the MPI operation {\em MPI\_SCAN}.

\subsection{Correctness}

No special issues for Java binding.

\newpage

\section{Groups, Contexts and Communicators}

\subsection{Introduction}

No special issues for Java binding.

\subsection{Basic Concepts}

The constant {\em MPI\_GROUP\_EMPTY} is available as {\tt MPI.GROUP\_EMPTY}.
The constants {\em MPI\_COMM\_WORLD}, {\em MPI\_COMM\_SELF} are available as
{\tt MPI.COMM\_\-WORLD}, {\tt MPI.COMM\_SELF}.


\subsection{Group Management}

\begin{verbatim}

int Group.Size()
\end{verbatim}
\begin{arguments}
{\em returns:} & number of processors in the group
\end{arguments}
Size of group.
Java binding of the MPI operation {\em MPI\_GROUP\_SIZE}.

\begin{verbatim}

int Group.Rank()
\end{verbatim}
\begin{arguments}
{\em returns:} & rank of the calling process in the group
\end{arguments}
Rank of this process in group.
Java binding of the MPI operation {\em MPI\_\-GROUP\_RANK}.
Result value is {\tt MPI.\-UNDEFINED} if this process is not
a member of the group.

\begin{verbatim}

static int [] Group.Translate_ranks(Group group1, int [] ranks1,
                                    Group group2)
\end{verbatim}
\begin{arguments}
{\tt group1}   & first group \\
{\tt ranks1}   & array of valid ranks in {\tt group1} \\
{\tt group2}   & second group \\
\\
{\em returns:} & array of corresponding ranks in {\tt group2}
\end{arguments}
Translate ranks within first group to ranks within second group.
Java binding of the MPI operation {\em MPI\_GROUP\_TRANSLATE\_RANKS}.
Result elements are {\tt MPI.UNDEFINED} where no correspondence exists.

\begin{verbatim}

static int Group.Compare(Group group1, Group group2)
\end{verbatim}
\begin{arguments}
{\tt group1}   & first group \\
{\tt group2}   & second group \\
\\
{\em returns:} & result
\end{arguments}
Compare two groups.
Java binding of the MPI operation {\em MPI\_GROUP\_COMP\-ARE}.
{\tt MPI.IDENT} results if the group members and group order are
exactly the same in both groups.  {\tt MPI.SIMILAR} results if
the group members are the same but the order is different.
{\tt MPI.UNEQUAL} results otherwise.

\begin{verbatim}

Group Comm.Group()
\end{verbatim}
\begin{arguments}
{\em returns:} & group corresponding to this communicator
\end{arguments}
Return group associated with a communicator.
Java binding of the MPI operation {\em MPI\_COMM\_GROUP}.

\begin{verbatim}

static Group Group.Union(Group group1, Group group2)
\end{verbatim}
\begin{arguments}
{\tt group1}   & first group \\
{\tt group2}   & second group \\
\\
{\em returns:} & union group
\end{arguments}
Set union of two groups.
Java binding of the MPI operation {\em MPI\_GROUP\_UN\-ION}.

\begin{verbatim}

static Group Group.Intersection(Group group1, Group group2)
\end{verbatim}
\begin{arguments}
{\tt group1}   & first group \\
{\tt group2}   & second group \\
\\
{\em returns:} & intersection group
\end{arguments}
Set intersection of two groups.
Java binding of the MPI operation {\em MPI\_GRO\-UP\_INTERSECTION}.

\begin{verbatim}

static Group Group.Difference(Group group1, Group group2)
\end{verbatim}
\begin{arguments}
{\tt group1}   & first group \\
{\tt group2}   & second group \\
\\
{\em returns:} & difference group
\end{arguments}
Result contains all elements of the first group that are not in the
second group.
Java binding of the MPI operation {\em MPI\_GROUP\_DIFFERENCE}.

\begin{verbatim}

Group Group.Incl(int [] ranks)
\end{verbatim}
\begin{arguments}
{\tt ranks}    & ranks from this group to appear in new group \\
\\
{\em returns:} & new group
\end{arguments}
Create a subset group including specified processes.
Java binding of the MPI operation {\em MPI\_GROUP\_INCL}.

\begin{verbatim}

Group Group.Excl(int [] ranks)
\end{verbatim}
\begin{arguments}
{\tt ranks}    & ranks from this group {\em not} to appear in new group \\
\\
{\em returns:} & new group
\end{arguments}
Create a subset group excluding specified processes.
Java binding of the MPI operation {\em MPI\_GROUP\_EXCL}.

\begin{verbatim}

Group Group.Range_incl(int [] [] ranges)
\end{verbatim}
\begin{arguments}
{\tt ranges}   & array of integer triplets \\
\\
{\em returns:} & new group
\end{arguments}
Create a subset group including processes specified
by strided intervals of ranks.
Java binding of the MPI operation {\em MPI\_GROUP\_RANGE\_INCL}.
The triplets are of the form $(\mbox{first rank}, \mbox{last rank},
\mbox{stride})$ indicating ranks in this group to be included in
the new group.  The size of the first dimension of {\tt ranges}
is the number of triplets.  The size of the second dimension is 3.

\begin{verbatim}

Group Group.Range_excl(int [] [] ranges)
\end{verbatim}
\begin{arguments}
{\tt ranges}   & array of integer triplets \\
\\
{\em returns:} & new group
\end{arguments}
Create a subset group excluding processes specified
by strided intervals of ranks.
Java binding of the MPI operation {\em MPI\_GROUP\_RANGE\_EXCL}.
Triplet array is defined as for {\tt Range\_incl}, the ranges
indicating ranks in this group to be excluded from
the new group.

\begin{verbatim}

void Group.finalize()
\end{verbatim}
Destructor.  Java binding of the MPI operation {\em MPI\_GROUP\_FREE}.

\subsection{Communicator Management}

\begin{verbatim}

int Comm.Size()
\end{verbatim}
\begin{arguments}
{\em returns:} & number of processors in the group of this communicator
\end{arguments}
Size of group of this communicator.
Java binding of the MPI operation {\em MPI\_\-COMM\_SIZE}.

\begin{verbatim}

int Comm.Rank()
\end{verbatim}
\begin{arguments}
{\em returns:} & rank of the calling process in the group of this communicator
\end{arguments}
Rank of this process in group of this communicator.
Java binding of the MPI operation {\em MPI\_COMM\_RANK}.

\begin{verbatim}

static int Comm.Compare(Comm comm1, Comm comm2)
\end{verbatim}
\begin{arguments}
{\tt comm1}   & first communicator \\
{\tt comm2}   & second communicator \\
\\
{\em returns:} & result
\end{arguments}
Compare two communicators.
Java binding of the MPI operation {\em MPI\_COMM\_\-COMPARE}.
{\tt MPI.IDENT} results if the {\tt comm1} and {\tt comm2}
are references to the same object (ie, if {\tt comm1 == comm2}).
{\tt MPI.CONGRUENT} results if
the underlying groups are identical but the communicators
differ by context.
{\tt MPI.SIMILAR} results if
the underlying groups are similar but the communicators
differ by context.
{\tt MPI.UNEQUAL} results otherwise.

\begin{verbatim}

Object Comm.clone()
\end{verbatim}
\begin{arguments}
{\em returns:} & copy of this communicator
\end{arguments}
Duplicate this communicator.
Java binding of the MPI operation {\em MPI\_COMM\_\-DUP}.
The new communicator is ``congruent'' to the old one,
but has a different context.
\begin{rationale}
The decision to use the standard Java {\tt clone} method means the
static result type must be {\tt Object}.  The dynamic type will be that
of the {\tt Comm} subclass of the parent.  MPI-defined and user-defined
subclasses of {\tt Comm} will generally override {\tt clone} to ensure
all relevant attributes are copied.
\end{rationale}

\begin{verbatim}

Intracomm Intracomm.Create(Group group)
\end{verbatim}
\begin{arguments}
{\tt group}    & group which is a subset of the group of this communicator \\
\\
{\em returns:} & new communicator
\end{arguments}
Create a new communicator.
Java binding of the MPI operation {\em MPI\_COMM\_\-CREATE}.

\begin{verbatim}

Intracomm Intracomm.Split(int color, int key)
\end{verbatim}
\begin{arguments}
{\tt color}    & control of subset assignment \\
{\tt key}      & control of rank assignment \\
\\
{\em returns:} & new communicator
\end{arguments}
Partition the group associated with this communicator and create
a new communicator within each subgroup.
Java binding of the MPI operation {\em MPI\_COMM\_\-SPLIT}.

\begin{verbatim}

void Comm.Free()
\end{verbatim}
Destroy this communicator.
Java binding of the MPI operation {\em MPI\_COMM\_\-FREE}.
\begin{rationale}
An explicitly called {\tt Free} method is required rather than an
implicitly called {\tt finalize} method, because {\em MPI\_COMM\_FREE}
is a collective operation.  We cannot assume that
the Java garbage collector will call a {\tt finalize} method
synchronously on all processors.
\end{rationale}

\begin{verbatim}

boolean Comm.Is_null()
\end{verbatim}
\begin{arguments}
{\em returns:} & true if the communicator object has been freed, false otherwise
\end{arguments}
Replaces comparision with {\tt MPI\_COMM\_NULL}.


\subsection{Motivating Examples}

No special issues for Java binding.

\subsection{Inter-Communication}

\begin{verbatim}

boolean Comm.Test_inter()
\end{verbatim}
\begin{arguments}
{\em returns:} & {\tt true} if this is an inter-communicator,
                 {\tt false} otherwise
\end{arguments}
Test if this communicator is an inter-communicator.
Java binding of the MPI operation {\em MPI\_COMM\_TEST\_INTER}.

\begin{verbatim}

int Intercomm.Remote_size()
\end{verbatim}
\begin{arguments}
{\em returns:} & number of process in remote group of this communicator
\end{arguments}
Size of remote group.
Java binding of the MPI operation {\em MPI\_COMM\_REM\-OTE\_SIZE}.

\begin{verbatim}

Group Intercomm.Remote_Group()
\end{verbatim}
\begin{arguments}
{\em returns:} & remote group of this communicator
\end{arguments}
Return the remote group.
Java binding of the MPI operation {\em MPI\_COMM\_\-REMOTE\_GROUP}.

\begin{verbatim}

Intercomm Comm.Create_intercomm(Comm local_comm, int local_leader,
                                int remote_leader, int tag)
\end{verbatim}
\begin{arguments}
{\tt local\_comm}    & local intra-communicator \\
{\tt local\_leader}  & rank of local group leader in {\tt localComm} \\
{\tt remote\_leader} & rank of remote group leader in this communictor \\
{\tt tag}          & ``safe'' tag \\
\\
{\em returns:}     & new inter-communicator
\end{arguments}
Create an inter-communicator.
Java binding of the MPI operation {\em MPI\_INTER\-COMM\_CREATE}.
\begin{rationale}
This operation is defined as a method on the ``peer communicator'',
making it analogous to a {\tt Send} or {\tt Recv} communication with the
remote group leader.
\end{rationale}

\begin{verbatim}

Intracomm Intercomm.Merge(boolean high)
\end{verbatim}
\begin{arguments}
{\tt high}     & true if the local group has higher ranks in combined group \\
\\
{\em returns:} & new intra-communicator
\end{arguments}
Create an intra-communicator from the union of the two groups in
the inter-communicator.
Java binding of the MPI operation {\em MPI\_INTERCOMM\_MER\-GE}.

\subsection{Caching}

It is assumed that to achieve the effect of caching attributes in
user-customized communicators programmers will create subclasses of
the library-defined communicator classes with suitable additional
fields.  These fields may be copied or deleted by suitably overridden
{\tt clone} and {\tt finalize} methods.

Hence the only ``caching'' operation surviving here is the binding of
{\em MPI\_\-ATTR\_GET}, which is needed to access values of attributes
predefined by the implementation.  According the standard, the key
values for such attributes include {\tt MPI.TAG\_UB}, {\tt MPI.HOST},
{\tt MPI.IO} and {\tt MPI.WTIME\_IS\_GLOBAL}.

\begin{verbatim}

int Comm.Attr_get(int keyval)
\end{verbatim}
\begin{arguments}
{\tt keyval}   & one of the key values predefined by the implementation \\
\\
{\em returns:} & attribute value
\end{arguments}
Retrieves attribute value by key.
Java binding of the MPI operation {\em MPI\_AT\-TR\_GET}.

\newpage

\section{Process Topologies}

\subsection{Introduction}

Communicators with Cartesian or graph topologies will be realized as
instances of the subclasses {\tt Cartcomm} or {\tt Graphcomm}, respectively
of {\tt Intracomm}.

\subsection{Virtual Topologies}

No special issues for Java binding.

\subsection{Embedding in MPI}

No special issues for Java binding.

\subsection{Overview of the Functions}

No special issues for Java binding.

\subsection{Topology Constructors}

\begin{verbatim}

Cartcomm Intracomm.Create_cart(int [] dims, boolean [] periods,
                               boolean reorder)
\end{verbatim}
\begin{arguments}
{\tt dims}     & the number of processes in each dimension \\
{\tt periods}  & {\tt true} if grid is periodic, {\tt false} if not,
                 in each dimension \\
{\tt reorder}  & {\tt true} if ranking may be reordered, {\tt false} if not \\
\\
{\em returns:} & new Cartesian topology communicator
\end{arguments}
Create a Cartesian topology communicator whose group is a subset
of the group of this communicator.  Java binding of the MPI operation
{\em MPI\_CART\_CREATE}.  The number of dimensions of the Cartesian
grid is taken to be the size of the {\tt dims} argument.  The array {\tt
periods} must be the same size.

\begin{verbatim}

static Cartcomm.Dims_create(int nnodes, int [] dims)
\end{verbatim}
\begin{arguments}
{\tt nnodes}   & number of nodes in a grid \\
{\tt dims}     & array specifying the number of nodes in each dimension
\end{arguments}
Select a balanced distribution of processes per coordinate direction.
Java binding of the MPI operation {\em MPI\_DIMS\_CREATE}.
Number of dimensions is the size of is {\tt dims}.  Note that
{\tt dims} is an {\em inout} parameter.

\begin{verbatim}

Graphcomm Intracomm.Create_graph(int [] index, int [] edges,
                                 boolean reorder)
\end{verbatim}
\begin{arguments}
{\tt index}    & node degrees \\
{\tt edges}    & graph edges \\
{\tt reorder}  & {\tt true} if ranking may be reordered, {\tt false} if not \\
\\
{\em returns:} & new graph topology communicator
\end{arguments}
Create a graph topology communicator whose group is a subset
of the group of this communicator.
Java binding of the MPI operation {\em MPI\_GRAPH\_CREATE}.
The number of nodes in the graph, {\em nnodes}, is taken
to be size of the {\tt index} argument.  The size of array {\tt
edges} must be $\mbox{\tt index}[\mbox{\em nnodes} - 1]$.

\begin{verbatim}

int Comm.Topo_test()
\end{verbatim}
\begin{arguments}
{\em returns:} & topology type of communicator
\end{arguments}
Returns the type of topology associated with the communicator.
Java binding of the MPI operation {\em MPI\_TOPO\_TEST}.
The return value will be one of
{\tt MPI.GRAPH}, {\tt MPI.CART} or {\tt MPI.UNDEFINED}.

\begin{verbatim}

GraphParms Graphcomm.Get()
\end{verbatim}
\begin{arguments}
{\em returns:} & object defining node degress and edges of graph
\end{arguments}
Returns graph topology information.
Java binding of the MPI operations {\em MPI\_\-GRAPHDIMS\_GET} and
{\em MPI\_GRAPH\_GET}.
The class of the returned object is
\small
\begin{verbatim}
  public class GraphParms {
    public int [] index ;
    public int [] edges ; 
  }
\end{verbatim}
\normalsize
The number of nodes and number of edges can be extracted
from the sizes of the {\tt index} and {\tt edges} arrays.

\begin{verbatim}

CartParms Cartcomm.Get()
\end{verbatim}
\begin{arguments}
{\em returns:} & object containing dimensions, periods and local coordinates
\end{arguments}
Returns Cartesian topology information.
Java binding of the MPI operations {\em MPI\_CARTDIM\_GET} and
{\em MPI\_CART\_GET}.
The class of the returned object is
\small
\begin{verbatim}
  public class CartParms {
    public int [] dims ;
    public booleans [] periods ;
    public int [] coords ; 
  }
\end{verbatim}
\normalsize
The number of dimensions can be obtained from the size of (eg)
the {\tt dims} array.
\begin{rationale}
The inquiries {\em MPI\_GRAPHDIMS\_GET}, {\em MPI\_GRAPH\_GET}, {\em
MPI\_CARTDIM\_GET}, and {\em MPI\_CART\_GET} are unusual in returning
multiple independent values from single calls.  This is a
problem in Java.  The Java binding could split these inquiries into
several independent ones, but that would complicate JNI-based wrapper
implementations.  Hence we introduced the auxilliary classes {\tt
GraphParms} and {\tt CartParms} to hold multiple results.
\end{rationale}

\begin{verbatim}

int Cartcomm.Rank(int [] coords)
\end{verbatim}
\begin{arguments}
{\tt coords}   & Cartesian coordinates of a process \\
\\
{\em returns:} & rank of the specified process
\end{arguments}
Translate logical process coordinates to process rank.
Java binding of the MPI operation {\em MPI\_CART\_RANK}.

\begin{verbatim}

int [] Cartcomm.Coords(int rank)
\end{verbatim}
\begin{arguments}
{\tt coords}   & rank of a process \\
\\
{\em returns:} & Cartesian coordinates of the specified process
\end{arguments}
Translate process rank to logical process coordinates.
Java binding of the MPI operation {\em MPI\_CART\_COORDS}.

\begin{verbatim}

int [] Graphcomm.Neighbours(int rank)
\end{verbatim}
\begin{arguments}
{\tt coords}   & rank of a process in the group of this communicator \\
\\
{\em returns:} & array of ranks of neighbouring processes to one specified
\end{arguments}
Provides adjacency information for general graph topology.
Java binding of the MPI operations {\em MPI\_GRAPH\_NEIGHBOURS\_COUNT}
and {\em MPI\_GRAPH\_\-NE\-IGHBOURS}.
The number of neighbours can be extracted from the size of the result.

\begin{verbatim}

ShiftParms Cartcomm.Shift(int direction, int disp)
\end{verbatim}
\begin{arguments}
{\tt direction} & coordinate dimension of shift \\
{\tt disp}      & displacement \\
\\
{\em returns:}  & object containing ranks of source and destination processes
\end{arguments}
Compute source and destination ranks for ``shift'' communication.
Java binding of the MPI operation {\em MPI\_CART\_SHIFT}.
The class of the returned object is
\small
\begin{verbatim}
  public class ShiftParms {
    public int rankSource ;
    public int rankDest ; 
  }
\end{verbatim}
\normalsize

\begin{verbatim}

Cartcomm Cartcomm.Sub(boolean [] remainDims)
\end{verbatim}
\begin{arguments}
{\tt remainDims} & by dimension, {\tt true} if dimension is to be kept,
                   {\tt false} otherwise \\
\\
{\em returns:}   & communicator containing subgrid including this process
\end{arguments}
Partition Cartesian communicator into subgroups of lower dimension.
Java binding of the MPI operation {\em MPI\_CART\_SUB}.

\begin{verbatim}

int Cartcomm.Map(int [] dims, boolean [] periods)
\end{verbatim}
\begin{arguments}
{\tt dims}     & the number of processes in each dimension \\
{\tt periods}  & {\tt true} if grid is periodic, {\tt false} if not, in each
                 dimension \\
\\
{\em returns:} & reordered rank of calling process
\end{arguments}
Compute an optimal placement.
Java binding of the MPI operation {\em MPI\_\-CART\_MAP}.
The number of dimensions is taken to be size of the {\tt dims} argument.

\begin{verbatim}

int Graphcomm.Map(int [] index, int [] edges)
\end{verbatim}
\begin{arguments}
{\tt index}    & node degrees \\
{\tt edges}    & graph edges \\
\\
{\em returns:} & reordered rank of calling process
\end{arguments}
Compute an optimal placement.
Java binding of the MPI operation {\em MPI\_\-GRAPH\_MAP}.
The number of nodes is taken to be size of the {\tt index} argument.

\newpage

\section{MPI Environmental Management}

\subsection{Implementation information}

The constants {\em MPI\_TAG\_UB}, {\em MPI\_HOST} and {\em MPI\_IO}
are available as
{\tt MPI.\-TAG\_UB}, {\tt MPI.HOST}, {\tt MPI.IO}.

\begin{verbatim}

static String MPI.Get_processor_name()
\end{verbatim}
\begin{arguments}
{\em returns:} & A unique specifier for the actual node.
\end{arguments}
Returns the name of the processor on which it is called.
Java binding of the MPI operation {\em MPI\_GET\_PROCESSOR\_NAME}.

\subsection{Error handling}

The constants {\em MPI\_ERRORS\_ARE\_FATAL}, {\em MPI\_ERRORS\_RETURN}
are available as
{\tt MPI.ERRORS\_ARE\_FATAL}, {\tt MPI.ERRORS\_RETURN}.

If the effective error handler is {\em MPI\_ERRORS\_RETURN}, the wrapper
codes will throw appropriate Java exceptions (see section \ref{errorCodes}).

Currently mpiJava omits an interface for creating new MPI error handlers
(the detailed interface of the handler function depends on unstandardized
features of the MPI implementation).

\begin{verbatim}

static void Comm.Errorhandler_set(Errhandler errhandler)
\end{verbatim}
\begin{arguments}
{\tt errhandler} & new MPI error handler for communicator
\end{arguments}
Associates a new error handler with communicator at the calling process.
Java binding of the MPI operation {\em MPI\_ERRORHANDLER\_SET}.

\begin{verbatim}

static Errhandler Comm.Errorhandler_get()
\end{verbatim}
\begin{arguments}
{\em returns:} & MPI error handler currently associated with communicator
\end{arguments}
Returns the error handler currently associated with the communicator.
Java binding of the MPI operation {\em MPI\_ERRORHANDLER\_GET}.


\subsection{Error codes and classes\label{errorCodes}}

The {\tt MPIException} subclasses
\begin{verbatim}
  MPIErrBuffer
  MPIErrCount
  MPIErrType
  MPIErrTag
  MPIErrComm
  MPIErrRank
  MPIErrRequest
  MPIErrRoot
  MPIErrGroup
  MPIErrOp
  MPIErrTopology
  MPIErrDims
  MPIErrArg
  MPIErrUnknown
  MPIErrTruncate
  MPIErrOther
  MPIErrIntern
\end{verbatim}
correspond to the standard MPI error classes.
{\em [Not implemented in the current release.]}

\subsection{Timers}

\begin{verbatim}

static double MPI.Wtime()
\end{verbatim}
\begin{arguments}
{\em returns:} & elapsed wallclock time in seconds since some time in the past
\end{arguments}
Returns wallclock time.
Java binding of the MPI operation {\em MPI\_WTIME}.

\begin{verbatim}

static double MPI.Wtick()
\end{verbatim}
\begin{arguments}
{\em returns:} & resolution of {\tt wtime} in seconds.
\end{arguments}
Returns resolution of timer.
Java binding of the MPI operation {\em MPI\_WTICK}.

\subsection{Startup}

\begin{verbatim}

static String [] MPI.Init(String[] argv)
\end{verbatim}
\begin{arguments}
{\tt argv} & arguments to {\tt main} method. \\
\\
{\em returns:} & command line arguments returned by MPI.
\end{arguments}
Initialize MPI.
Java binding of the MPI operation {\em MPI\_INIT}.

\begin{verbatim}

static void MPI.Finalize()
\end{verbatim}
Finalize MPI.
Java binding of the MPI operation {\em MPI\_FINALIZE}.

\begin{verbatim}

static boolean MPI.Initialized()
\end{verbatim}
\begin{arguments}
{\em returns:} & {\tt true} if {\tt init} has been called, {\tt false}
                 otherwise.
\end{arguments}
Test if MPI has been initialized.
Java binding of the MPI operation {\em MPI\_INIT\-IALIZED}.

\begin{verbatim}

void Comm.Abort(int errorcode)
\end{verbatim}
\begin{arguments}
{\tt errorcode} & error code for Unix or POSIX environments
\end{arguments}
Abort MPI.
Java binding of the MPI operation {\em MPI\_ABORT}.

\newpage

\section{Full public interface of classes\label{sec:classes}}

Section names appearing in comments refer to the preceding appendix.
Specification of the methods immediately following those comments
should be found in the referenced section.

\newpage

\subsection{\tt MPI}

\small
\begin{verbatim}
public class MPI {
  public static Intracomm COMM_WORLD;

  public static Datatype BYTE, CHAR, SHORT, BOOLEAN, INT, LONG,
                         FLOAT, DOUBLE, OBJECT, PACKED, LB, UB ;

  public static int ANY_SOURCE, ANY_TAG ;

  public static int PROC_NULL ;

  public static int BSEND_OVERHEAD ;

  public static int UNDEFINED ;

  public static Op MAX, MIN, SUM, PROD, LAND, BAND,
                   LOR, BOR, LXOR, BXOR, MINLOC, MAXLOC ;

  public static Datatype SHORT2, INT2, LONG2, FLOAT2, DOUBLE2 ;

  public static Group GROUP_EMPTY ;

  public static Comm COMM_SELF ;

  public static int IDENT, CONGRUENT, SIMILAR, UNEQUAL ;

  public static int GRAPH, CART ;

  public static ErrHandler ERRORS_ARE_FATAL, ERRORS_RETURN ;

  public static int TAG_UB, HOST, IO ;


  // Buffer allocation and usage

  public static void Buffer_attach(byte [] buffer)
                                            throws MPIException {...}

  public static byte [] Buffer_detach() throws MPIException {...}


  // Environmental Management

  public static String [] Init(String[] argv) throws MPIException {...}

  public static void Finalize() throws MPIException {...}

  public static String Get_processor_name() throws MPIException {...}

  public static double Wtime() {...}

  public static double Wtick() {...}

  public static boolean Initialized() throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\small
\begin{verbatim}
public class Errhandler {
  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Comm}

\small
\begin{verbatim}
public class Comm {

  // Communicator Management

  public int Size() throws MPIException {...}

  public int Rank() throws MPIException {...}

  public Group Group() throws MPIException {...}
                                        // (see ``Group management'')

  public static int Compare(Comm comm1, Comm comm2)
                                            throws MPIException {...}

  public Object clone() {...}

  public void Free() throws MPIException {...}

  public boolean Is_null() {...}


  // Inter-communication

  public boolean Test_inter() throws MPIException {...}

  public Intercomm Create_intercomm(Comm local_comm, int local_leader,
                                    int remote_leader, int tag)
                                             throws MPIException {...}

  // Caching

  public Object Attr_get(int keyval) throws MPIException {...}


  // Blocking Send and Receive operations

  public void Send(Object buf, int offset, int count, 
                   Datatype datatype, int dest, int tag)
                                             throws MPIException {...}

  public Status Recv(Object buf, int offset, int count, 
                     Datatype datatype, int source, int tag)
                                             throws MPIException {...}


  // Communication Modes

  public void Bsend(Object buf, int offset, int count, 
                    Datatype datatype, int dest, int tag)
                                             throws MPIException {...}

  public void Ssend(Object buf, int offset, int count, 
                    Datatype datatype, int dest, int tag) 
                                             throws MPIException {...}

  public void Rsend(Object buf, int offset, int count, 
                    Datatype datatype, int dest, int tag) 
                                             throws MPIException {...}


  // Nonblocking communication

  public Request Isend(Object buf, int offset, int count, 
                       Datatype datatype, int dest, int tag) 
                                             throws MPIException {...}

  public Request Ibsend(Object buf, int offset, int count, 
                        Datatype datatype, int dest, int tag) 
                                             throws MPIException {...}

  public Request Issend(Object buf, int offset, int count, 
                        Datatype datatype, int dest, int tag) 
                                             throws MPIException {...}

  public Request Irsend(Object buf, int offset, int count, 
                        Datatype datatype, int dest, int tag) 
                                             throws MPIException {...}

  public Request Irecv(Object buf, int offset, int count, 
                       Datatype datatype, int source, int tag) 
                                             throws MPIException {...}


  // Probe and cancel

  public Status Iprobe(int source, int tag) throws MPIException {...}

  public Status Probe(int source, int tag) throws MPIException {...}


  // Persistent communication requests

  public Prequest Send_init(Object buf, int offset, int count, 
                            Datatype datatype, int dest, int tag) 
                                            throws MPIException {...}

  public Prequest Bsend_init(Object buf, int offset, int count, 
                             Datatype datatype, int dest, int tag) 
                                            throws MPIException {...}

  public Prequest Ssend_init(Object buf, int offset, int count, 
                             Datatype datatype, int dest, int tag) 
                                            throws MPIException {...}

  public Prequest Rsend_init(Object buf, int offset, int count, 
                             Datatype datatype, int dest, int tag) 
                                            throws MPIException {...}

  public Prequest Recv_init(Object buf, int offset, int count, 
                            Datatype datatype, int source, int tag) 
                                            throws MPIException {...}


  // Send-receive

  public Status Sendrecv(Object sendbuf, int sendoffset,
                         int sendcount, Datatype sendtype,
                         int dest, int sendtag,
                         Object recvbuf, int recvoffset,
                         int recvcount, Datatype recvtype,
                         int source, int recvtag) 
                                            throws MPIException {...}

  public Status Sendrecv_replace(Object buf, int offset,
                                 int count, Datatype datatype,
                                 int dest, int sendtag,
                                 int source, int recvtag) 
                                            throws MPIException {...}

  // Pack and unpack

  public int Pack(Object inbuf, int offset, int incount, 
                  Datatype datatype,
                  byte [] outbuf, int position)
                                            throws MPIException {...}

  public int Unpack(byte [] inbuf, int position,
                    Object outbuf, int offset, int outcount, 
                    Datatype datatype) throws MPIException {...}

  public int Pack_size(int incount, Datatype datatype) 
                                            throws MPIException {...}


  // Process Topologies

  int Topo_test() throws MPIException {...}


  // Environmental Management

  public void Errorhandler_set(Errhandler errhandler)
                                            throws MPIException {...}

  public Errhandler Errorhandler_get() throws MPIException {...}

  void Abort(int errorcode) throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize


\newpage

\subsection{{\tt Intracomm} and {\tt Intercomm}}

\small
\begin{verbatim}
public class Intracomm extends Comm {

  public Object clone() { ... }

  public Intracomm Create(Group group) throws MPIException {...}

  public Intracomm Split(int colour, int key) throws MPIException {...}

  // Collective communication

  public void Barrier() throws MPIException {...}

  public void Bcast(Object buffer, int offset, int count,
                    Datatype datatype, int root)
                                            throws MPIException {...}

  public void Gather(Object sendbuf, int sendoffset,
                     int sendcount, Datatype sendtype,
                     Object recvbuf, int recvoffset,
                     int recvcount, Datatype recvtype, int root) 
                                            throws MPIException {...}

  public void Gatherv(Object sendbuf, int sendoffset,
                      int sendcount, Datatype sendtype,
                      Object recvbuf, int recvoffset,
                      int [] recvcount, int [] displs,
                      Datatype recvtype, int root) 
                                            throws MPIException {...}

  public void Scatter(Object sendbuf, int sendoffset,
                      int sendcount, Datatype sendtype,
                      Object recvbuf, int recvoffset,
                      int recvcount, Datatype recvtype, int root) 
                                            throws MPIException {...}

  public void Scatterv(Object sendbuf, int sendoffset,
                       int [] sendcount, int [] displs,
                       Datatype sendtype,
                       Object recvbuf, int recvoffset,
                       int recvcount, Datatype recvtype, int root) 
                                            throws MPIException {...}

  public void Allgather(Object sendbuf, int sendoffset,
                        int sendcount, Datatype sendtype,
                        Object recvbuf, int recvoffset,
                        int recvcount, Datatype recvtype) 
                                            throws MPIException {...}

  public void Allgatherv(Object sendbuf, int sendoffset,
                         int sendcount, Datatype sendtype,
                         Object recvbuf, int recvoffset,
                         int [] recvcounts, int [] displs,
                         Datatype recvtype) throws MPIException {...}

  public void Alltoall(Object sendbuf, int sendoffset,
                       int sendcount, Datatype sendtype,
                       Object recvbuf, int recvoffset,
                       int recvcount, Datatype recvtype) 
                                            throws MPIException {...}

  public void Alltoallv(Object sendbuf, int sendoffset,
                        int [] sendcount, int [] sdispls,
                        Datatype sendtype,
                        Object recvbuf, int recvoffset,
                        int [] recvcount, int [] rdispls,
                        Datatype recvtype) throws MPIException {...}

  public void Reduce(Object sendbuf, int sendoffset,
                     Object recvbuf, int recvoffset,
                     int count, Datatype datatype,
                     Op op, int root) throws MPIException {...}

  public void Allreduce(Object sendbuf, int sendoffset,
                        Object recvbuf, int recvoffset,
                        int count, Datatype datatype,
                        Op op) throws MPIException {...}

  public void Reduce_scatter(Object sendbuf, int sendoffset,
                             Object recvbuf, int recvoffset,
                             int [] recvcounts, Datatype datatype,
                             Op op) throws MPIException {...}

  public void Scan(Object sendbuf, int sendoffset,
                   Object recvbuf, int recvoffset,
                   int count, Datatype datatype,
                   Op op) throws MPIException {...}


  // Topology Constructors

  public Graphcomm Create_graph(int [] index, int [] edges,
                                boolean reorder) 
                                            throws MPIException {...}

  public Cartcomm Create_cart(int [] dims, boolean [] periods,
                              boolean reorder) 
                                            throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\small
\begin{verbatim}
public class Intercomm extends Comm {

  public Object clone() { ... }

  // Inter-communication

  public int Remote_size() throws MPIException {...}

  public Group Remote_group() throws MPIException {...}

  public Intracomm Merge(boolean high) throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Op}

\small
\begin{verbatim}
public class Op {
  Op(User_function function, boolean commute) throws MPIException {...}

  void finalize() throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Group}

\small
\begin{verbatim}
public class Group {

  // Group Management

  public int Size() throws MPIException {...}

  public int Rank() throws MPIException {...}

  public static int [] Translate_ranks(Group group1, int [] ranks1,
                                       Group group2)
                                            throws MPIException {...}

  public static int Compare(Group group1, Group group2)
                                            throws MPIException {...}

  public static Group Union(Group group1, Group group2)
                                            throws MPIException  {...}

  public static Group Intersection(Group group1, Group group2)
                                            throws MPIException  {...}

  public static Group Difference(Group group1, Group group2)
                                            throws MPIException  {...}

  public Group Incl(int [] ranks) throws MPIException {...}

  public Group Excl(int [] ranks) throws MPIException {...}

  public Group Range_incl(int [] [] ranges) throws MPIException {...}

  public Group Range_excl(int [] [] ranges) throws MPIException {...}

  public void finalize() throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Status}

\small
\begin{verbatim}
public class Status {

  public int source;
  public int tag;

  public int index ;

  // Blocking Send and Receive operations

  public int Get_count(Datatype datatype) throws MPIException {...}


  // Probe and Cancel

  public boolean Test_cancelled() throws MPIException {...}


  // Derived datatypes

  public int Get_elements(Datatype datatype) throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{{\tt Request} and {\tt Prequest}}

\small
\begin{verbatim}
public class Request {

  // Nonblocking communication

  public Status Wait() throws MPIException {...}

  public Status Test() throws MPIException {...}

  public void Free() throws MPIException {...}

  public boolean Is_null() {...}

  public static Status Waitany(Request [] array_of_requests) 
                                            throws MPIException {...}

  public static Status Testany(Request [] array_of_requests)
                                            throws MPIException {...}

  public static Status [] Waitall(Request [] array_of_requests)
                                            throws MPIException {...}

  public static Status [] Testall(Request [] array_of_requests)
                                            throws MPIException {...}

  public static Status [] Waitsome(Request [] array_of_requests)
                                            throws MPIException {...}

  public static Status [] Testsome(Request [] array_of_requests)
                                            throws MPIException {...}


  // Probe and cancel

  public void Cancel() throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\small
\begin{verbatim}
public class Prequest extends Request {

  // Persistent communication requests

  public void Start() throws MPIException {...}

  public static void Startall(Prequest [] array_of_requests)
                                            throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Datatype}

\small
\begin{verbatim}
public class Datatype {

  // Derived datatypes

  public static Datatype Contiguous(int count, Datatype oldtype)
                                            throws MPIException {...}

  public static Datatype Vector(int count, int blocklength, int stride,
                                Datatype oldtype)
                                            throws MPIException {...}

  public static Datatype Hvector(int count, int blocklength, int stride,
                                 Datatype oldtype)
                                            throws MPIException {...}

  public static Datatype Indexed(int [] array_of_blocklengths,
                                 int [] array_of_displacements,
                                 Datatype oldtype)
                                            throws MPIException {...}

  public static Datatype Hindexed(int [] array_of_blocklengths,
                                  int [] array_of_displacements,
                                  Datatype oldtype)
                                            throws MPIException {...}

  public static Datatype Struct(int [] array_of_blocklengths,
                                int [] array_of_displacements,
                                Datatype [] array_of_types)
                                            throws MPIException {...}

  public int Extent() throws MPIException {...}

  public int Lb() throws MPIException {...}

  public int Ub() throws MPIException {...}

  public int Size() throws MPIException {...}

  public void Commit() throws MPIException {...}

  public void finalize() throws MPIException {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{Classes for virtual topologies}

\small
\begin{verbatim}
public class Cartcomm extends Intracomm {

  public Object clone() { ... }

  // Topology Constructors

  static public Dims_create(int nnodes, int [] dims)
                                            throws MPIException {...}

  public CartParms Get() throws MPIException {...}

  public int Rank(int [] coords) throws MPIException {...}

  public int [] Coords(int rank) throws MPIException {...}

  public ShiftParms Shift(int direction, int disp) throws MPIException {...}

  public Cartcomm Sub(boolean [] remainDims) throws MPIException {...}

  public int Map(int [] dims, boolean [] periods) throws MPIException {...}
}
\end{verbatim}
\normalsize

\small
\begin{verbatim}
public class CartParms {

  // Return type for Cartcomm.get()

  public int [] dims ;
  public booleans [] periods ;
  public int [] coords ; 
}
\end{verbatim}
\normalsize

\small
\begin{verbatim}
public class ShiftParms {

  // Return type for Cartcomm.shift()

  public int rankSource ;
  public int rankDest ; 
}
\end{verbatim}
\normalsize


\small
\begin{verbatim}
public class Graphcomm extends Intracomm {

  public Object clone() { ... }

  // Topology Constructors

  public GraphParms Get() throws MPIException {...}

  public int [] Neighbours(int rank) throws MPIException {...}

  public int Map(int [] index, int [] edges) throws MPIException {...}
}
\end{verbatim}
\normalsize

\small
\begin{verbatim}
public class GraphParms {

  // Return type for Graphcomm.get()

  public int [] index ;
  public int [] edges ; 
}
\end{verbatim}
\normalsize

\newpage

\begin{flushleft}
\bibliography{mpiJava-spec}
\end{flushleft}

\end{document}


