\documentstyle[psfig]{article}

\begin{document}

\sloppy

\pagestyle{plain}

\title{\vspace{2in}A Draft Java Binding for MPI}

\author{Bryan Carpenter, Geoffrey Fox, \\
        Sung-Hoon Ko, Xinying Li, Guansong Zhang\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,xli,zgs\}\@npac.syr.edu}


\maketitle

\newpage

\tableofcontents

\newpage

\section{Introduction}

This document proposes a Java language binding for MPI,
version 1.1.  The document is meant to be read in conjunction with the
that standard, and its principal sections are laid out in the same way as
the standard to allow cross-referencing.  The appendices collect
together complete Java class interfaces.
Where practical the current proposals follow the MPI C++ interface
defined in the MPI standard version 2.0.

The current document should be seen as a specification for software under
development at NPAC.  The interface described makes no claim as a
general standard for Java MPI binding, and it has not been endorsed by
the MPI forum.

A protoype Java MPI wrapper has been available from NPAC for some
time\footnote{\tt http://www.npac.syr.edu/users/yjchang/javaMPI/}.
We aim to make an initial implementation of the full interface
described here available by the end of December, 1997.

\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.

Unless otherwise stated, Java argument names are identical to the
corresponding language independent names.  Unless otherwise stated, in
non-static member functions of {\tt Comm}, {\tt Status}, {\tt Request},
{\tt Datatype}, {\tt Op} or {\tt Group} (and subclasses), the class
instance stands for the {\em comm}, {\em status}, {\em request}, {\em
datatype}, {\em op} or {\em group} argument, respectively in the
corresponding the language independent procedure definition.

\subsection{Semantic terms}

No special issues for Java binding.

\subsection{Data types}

Opaque objects will be presented as Java objects.
This introduces the
option of simplifying the user's task in managing these objects.  MPI
destructors can be called by the Java object destructors, which are
called automatically by the Java garbage collector.

In contrast to the MPI C++ binding, we adopt this strategy as the general
rule.  Explicit calls to MPI destructor functions are typically
omitted from the Java user interface.  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 consistently across processors.  Similarly
{\em MPI\_REQUEST\_FREE} has a specific semantic effect which is better
left under user control.


\subsection{Language Binding\label{binding}}

Special issues for Java binding:
\begin{itemize}
\item
Some options allowed for derived data types in the C and Fortran
binding are deleted in the Java binding.  The Java VM does not provide
any concept of a global linear address space.  Passing physical
addresses to data type definitions is not allowed, and use of
the {\em MPI\_TYPE\_STRUCT} datatype constructor is restricted in a way that
makes it impossible to send mixed primitive types in a single
message.
In an initial implementation it will
not be possible to directly send a general Java object in
a message.
We assume that Java programmers who want to achieve
this goal will explicitly serialize their objects before transmitting
them.  Later we hope to treat {\tt MPI.JAVA\_OBJECT} as a new MPI
{\em primitive type}, with serialization handled automatically in the wrapper
code.
\item
Message buffers in C or Fortran can be multidimensional
arrays, so it may seem natural to allow Java message buffers to be
multidimensional arrays.  But a Java multi-dimensional array does not
necessarily map to a contiguous chunk of memory (it is implemented as a
vector of separately allocated arrays), so there is no obvious way to
support this facility in a ``wrapper'' interface.
Hence Java message buffers are always one dimensional arrays with primitive
element type.  To allow a little extra 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.
\item
Unlike the C and Fortran interfaces, the Java interfaces to MPI
calls will not return explicit error codes.  The Java exception
mechanism will be used to report errors.  This 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 awkward than in normal languages).
A few functions in the MPI interface return multiple values, even after
the error code is eliminated.  In these cases the Java binding returns
a single object of some artificial class introduced to support the
function concerned.
\item
To permit a straightforward wrapper implementation it seems to be
necessary to impose some non-interference rules for concurrent read
and write operations on arrays.  When an array is passed to an
MPI member such as a send or receive operation, the wrapper code will
extract a pointer to the contents of the array using a JNI
{\tt Get<PrimitiveType>ArrayElements} routine.  If the garbage collector
does not support ``pinning'' (temporarily disabling run-time relocation of data
for specific arrays), 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<PrimitiveType>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.

For safety, the rule suggested is that 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.

Operations may occur concurrently through explicit use of threads, {\em
or through use of non-blocking communication operations}.  So far as
use of non-blocking communication operations is concerned, the
restriction could be relaxed at the price of having the wrapper always
explicitly copy buffers using {\em MPI\_PACK} and {\em MPI\_UNPACK}.  Of course
this is an undesirable overhead.  A final decision on whether
this overhead is acceptable will be defered until the implementation
is more complete.

\end{itemize}

\subsection{Processes}

No special issues for Java binding.

\subsection{Error Handling}

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

\section{Point-to-Point Communication}

\subsection{Introduction}

In general the Java binding of point-to-point communication operations will
realize the MPI functions as members of the {\tt Comm} class.

\subsection{Blocking Send and Receive operations}

\begin{verbatim}

void Comm.Send(Object buf, int offset, int count,
               Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SEND}. 
The actual argument associated with {\tt buf} must be a one-dimensional
array.  The array elements must have primitive type, and that type must
agree with {\tt datatype}, or be the {\em base type} of {\tt datatype} (see
section \ref{derived}).  The value {\tt offset} is a subscript in
the array, defining the position of the first item of the message.

The basic datatypes for Java will be\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.PACKED   &  \\
\hline
\end{tabular}
} \vspace{0.2in} \newline
Later we intend to add a new ``primitive'' type {\tt MPI.JAVA\_OBJECT}.
If a buffer has ``Java object'' is its base type, it
will be serialized inside the wrapper code.

\begin{verbatim}

Status Comm.Recv(Object buf, int offset, int count,
                 Datatype datatype, int source, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_RECV}. 
The actual argument associated with {\tt buf} must be a one-dimensional
array.  The array elements must have primitive type, and that type must
agree with {\tt datatype}, or be the {\em base type} of {\tt datatype} (see
section \ref{derived}).  The value {\tt offset} is a subscript in
the array, defining the position into which the first item of the incoming
message will be copied.  The return value is {\em status}.

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

\begin{verbatim}

int Status.Get_count(Datatype datatype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GET\_COUNT}. 
The return value is {\em count}.

\subsection{Data type matching and data conversion}

We have no requirement for representation conversion, because
all Java implementations are supposed to use the same representation, and
the MPI standard does not mandate support for inter-language communication.

\subsection{Communication Modes}

\begin{verbatim}

void Comm.Bsend(Object buf, int offset, int count,
                Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_BSEND}. 
Arguments as for {\tt send}.

\begin{verbatim}

void Comm.Ssend(Object buf, int offset, int count,
                Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SSEND}. 
Arguments as for {\tt send}.

\begin{verbatim}

void Comm.Rsend(Object buf, int offset, int count,
                Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_RSEND}. 
Arguments 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}
Java binding of the MPI operation {\em MPI\_BUFFER\_ATTACH}. 
The value of {\em size} is taken to be size of the {\tt buffer} argument.

\begin{verbatim}

byte [] MPI.Buffer_detach()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_BUFFER\_DETACH}. 
The return value is {\em buffer}.
The size of the returned arrray is {\em size}.

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

\subsection{Nonblocking communication}

\begin{verbatim}

Request Comm.Isend(Object buf, int offset, int count,
                   Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ISEND}. 
Arguments as for {\tt send}.  The result value is {\em request}.

\begin{verbatim}

Request Comm.Ibsend(Object buf, int offset, int count,
                    Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_IBSEND}. 
Arguments as for {\tt send}.  The result value is {\em request}.

\begin{verbatim}

Request Comm.Issend(Object buf, int offset, int count,
                    Datatype datatype, int dest, int tag)
\end{verbatim}

Java binding of the MPI operation {\em MPI\_ISSEND}. 
Arguments as for {\tt send}.  The result value is {\em request}.

\begin{verbatim}

Request Comm.Irsend(Object buf, int offset, int count,
                    Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_IRSEND}. 
Arguments as for {\tt send}.  The result value is {\em request}.

\begin{verbatim}

Request Comm.Irecv(Object buf, int offset, int count,
                   Datatype datatype, int source, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_IRECV}. 
Arguments as for {\tt Recv}.  The result value is {\em request}.

\begin{verbatim}

Status Request.Wait()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WAIT}. 
Return value is {\em status}.

\begin{verbatim}

Status Request.Test()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TEST}.
Return value is {\em status}, or {\tt null} if {\em flag} was
false.

\begin{verbatim}

void Request.Free()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_REQUEST\_FREE}.
(Note: a {\em Free} method is required rather than a {\em finalize}
method, because {\em MPI\_REQUEST\_FREE} has a specific effect
on communications, and we cannot assume that the Java garbage
collector would call a {\em finalize} at an appropriate time.)

\begin{verbatim}

boolean Request.Is_null()
\end{verbatim}
Returns true if the underlying MPI Request object is equal to {\em
MPI\_REQUEST\_NULL}, false otherwise.

\begin{verbatim}

static Status Request.Waitany(Request [] array_of_requests)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WAITANY}. 
The value of {\em count} is taken to be size of the {\tt
array\_of\_requests} argument.
Return value is {\em status}.  It contains {\em index} in its
{\tt index} field.


\begin{verbatim}

static Status Request.Testany(Request [] array_of_requests)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TESTANY}. 
The value of {\em count} is taken to be size of the {\tt array\_of\_requests}
argument.
Return value is {\em status}, containing {\em index} in its {\tt index}
field, or {\tt null} if {\em flag} was false.

\begin{verbatim}

static void Request.Waitall(Request [] array_of_requests,
                            Status [] array_of_statuses)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WAITALL}. 
The value of {\em count} is taken to be size of the {\tt array\_of\_requests}
argument.
The second argument, {\tt array\_of\_statuses}, should be the same
size.

\begin{verbatim}

static boolean Request.Testall(Request [] array_of_requests,
                               Status [] array_of_statuses)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WAITALL}. 
Arguments as for {\tt Waitall}.  The return value is {\em flag}.

\begin{verbatim}

static Status [] Request.Waitsome(Request [] array_of_requests)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WAITALL}. 
The value of {\em incount} is taken to be size of {\tt
array\_of\_requests} argument.
The return value is an array of size {\em outcount} containing the
statuses and indices from {\em array\_of\_statuses} and {\em
array\_of\_indices}.

\begin{verbatim}

static Status [] Request.Testsome(Request [] array_of_requests)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TESTALL}. 
Arguments and return value as for {\tt Waitsome}.


\subsection{Probe and Cancel}

\begin{verbatim}

Status Comm.Iprobe(int source, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_IPROBE}. 
Return value is {\em status}, or {\tt null} if {\em flag} was false.

\begin{verbatim}

Status Comm.Probe(int source, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_PROBE}. 
Return value is {\em status}.

\begin{verbatim}

void Request.Cancel()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_CANCEL}. 

\begin{verbatim}

boolean Status.Test_cancelled()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TEST\_CANCELLED}. 
The return value is {\em flag}.

\subsection{Persistent communication requests}

\begin{verbatim}

Prequest Comm.Send_init(Object buf, int offset, int count,
                        Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SEND\_INIT}. 
Return value is {\em request}.

\begin{verbatim}

Prequest Comm.Bsend_init(Object buf, int offset, int count,
                         Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_BSEND\_INIT}. 
Return value is {\em request}.

\begin{verbatim}

Prequest Comm.Ssend_init(Object buf, int offset, int count,
                         Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SSEND\_INIT}. 
Return value is {\em request}.

\begin{verbatim}

Prequest Comm.Rsend_init(Object buf, int offset, int count,
                         Datatype datatype, int dest, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_RSEND\_INIT}. 
Return value is {\em request}.

\begin{verbatim}

Prequest Comm.Recv_init(Object buf, int offset, int count,
                        Datatype datatype, int source, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_RECV\_INIT}. 
Return value is {\em request}.

\begin{verbatim}

void Prequest.Start()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_START}. 

\begin{verbatim}

static void Prequest.Startall(Prequest [] array_of_requests)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_STARTALL}. 
The value of {\em count} is taken to be size of {\tt array\_of\_requests}
argument.


\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}
Java binding of the MPI operation {\em MPI\_SENDRECV}. 
The value {\tt sendoffset} is a subscript in
{\tt sendbuf}, defining the position of the first item of the message
to be sent.
The value {\tt recvoffset} is a subscript in {\tt recvbuf},
defining the position into which the first item of the incoming
message will be copied.

The return value is {\em status}.

\begin{verbatim}

Status Comm.Sendrecv_replace(Object buf, int offset,
                     int count, Datatype datatype,
                     int dest, int sendtag,
                     int source, int recvtag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SENDRECV\_REPLACE}. 
The value {\tt offset} is a subscript in
{\tt buf}, defining the position of the first item of the message
to be sent,
and the position into which the first item of the incoming
message will be copied.

The return value is {\em status}.

\subsection{Null processes}

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

\subsection{Derived datatypes\label{derived}}

Every derived data type constructable in the Java binding has
a uniquely defined {\em base type}.  This is a Java primitive
type.  For the system-defined {\tt Datatype} values, the base type
is (naturally) the Java primitive type for which the value stands.
Derived types inherit their base types from their precursors in
a straightforward way.

\begin{verbatim}

static Datatype Datatype.Contiguous(int count, Datatype oldtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_CONTIGUOUS}.
The return value is {\em newtype}.
The base type of {\em newtype} is the same as the base type of
{\em oldtype}.

\begin{verbatim}

static Datatype Datatype.Vector(int count, int blocklength,
                                int stride, Datatype oldtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_VECTOR}.
The return value is {\em newtype}.
The base type of {\em newtype} is the same as the base type of
{\em oldtype}.

\begin{verbatim}

static Datatype Datatype.Hvector(int count, int blocklength,
                                 int stride, Datatype oldtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_HVECTOR}.  Arguments
as for {\tt Vector}.  {\em Unlike other language bindings}, the value
of {\tt stride} is given in units of the base type, {\em not} bytes.

\begin{verbatim}

static Datatype Datatype.Indexed(int [] array_of_blocklengths,
                                 int [] array_of_displacements,
                                 Datatype oldtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_INDEXED}.  The value
of {\em count} is taken to be size of the {\tt array\_of\_blocklengths}
argument.  The second argument, {\tt array\_of\_displacements}, should
be the same size.  The return
value is {\em newtype}.  The base type of {\em newtype} is the same as
the base type of {\em oldtype}.

\begin{verbatim}

static Datatype Datatype.Hindexed(int [] array_of_blocklengths,
                                  int [] array_of_displacements,
                                  Datatype oldtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_HINDEXED}.  Arguments
as for {\tt Indexed}.  {\em Unlike other language bindings}, the values
in {\tt array\_of\_displacements} are given in units of the base type,
{\em not} bytes.


\begin{verbatim}

static Datatype Datatype.Struct(int [] array_of_blocklengths,
                                int [] array_of_displacements,
                                Datatype [] array_of_types)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_STRUCT}.  The value
of {\em count} is taken to be size of the {\tt array\_of\_blocklengths}
argument.  The second and third arguments, {\tt array\_of\_displacements}
and {\tt array\_of\_types}, should be the same size.  The return value is
{\em newtype}.  All elements of {\tt array\_of\_types} should have the
same base type; this will also be the base type of {\em newtype}.
{\em Unlike other language bindings}, the values in {\tt
array\_of\_displacements} are given in units of the base type, {\em not}
bytes.

\begin{verbatim}

int Datatype.Extent()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_EXTENT}.
The return value is {\em extent}.

\begin{verbatim}

int Datatype.Size()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_SIZE}.
The return value is {\em size}.

\begin{verbatim}

int Datatype.Lb()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_LB}.
The return value is {\em displacement}.

\begin{verbatim}

int Datatype.Ub()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_UB}.
The return value is {\em displacement}.

\begin{verbatim}

void Datatype.Commit()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_TYPE\_COMMIT}.

\begin{verbatim}

void Datatype.finalize()
\end{verbatim}
The {\tt Datatype} destructor will invoke the MPI operation {\em
MPI\_TYPE\_FREE}.

\begin{verbatim}

int Status.Get_elements(Datatype datatype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GET\_ELEMENTS}.
The return value is {\em count}.

\subsection{Pack and unpack}

\begin{verbatim}

int Comm.Pack(Object inbuf, int offset, int incount,
              Datatype datatype,
              byte [] outbuf, int position)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_PACK}.
The value of {\em outcount} is taken to be size of the {\tt outbuf}
argument.
The return value is the output value of {\em position}.

\begin{verbatim}

int Comm.Unpack(byte [] inbuf, int position,
                Object outbuf, int offset, int outcount,
                Datatype datatype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_UNPACK}.
The value of {\em insize} is taken to be size of the {\tt inbuf}
argument.
The return value is the output value of {\em position}.

\begin{verbatim}

int Comm.Pack_size(int incount, Datatype datatype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_PACK\_SIZE}.
The return value is {\em size}.

\section{Collective Communication}

\subsection{Introduction and Overview}

In general the Java binding of collective communication operations will
realize the MPI functions as members of the {\tt Comm} class.

\subsection{Communicator argument}

No special issues for Java binding.

\subsection{Barrier synchronization}

\begin{verbatim}

void Intracomm.Barrier()
\end{verbatim}
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}
Java binding of the MPI operation {\em MPI\_BCAST}.
The value {\tt offset} is a subscript in {\tt buffer},
defining the position of the first item to be broadcast or
received.

\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}
Java binding of the MPI operation {\em MPI\_GATHER}.
The value {\tt sendoffset} is a subscript in
{\tt sendbuf}, defining the position of the first item of the message
to be sent.
The value {\tt recvoffset} is a subscript in {\tt recvbuf},
defining the position into which the first item of the 
gathered data will be copied.

\begin{verbatim}

void Intracomm.Gatherv(Object sendbuf, int sendoffset,
                       int sendcount, Datatype sendtype,
                       Object recvbuf, int recvoffset,
                       int [] recvcount, int [] displs,
                       Datatype recvtype, int root)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GATHERV}.
Arguments other than {\tt displs} as for {\tt Gather}.
(Note that if {\tt recvtype} is a derived data type,
{\tt displs} is in units of the derived data type,
unlike {\tt recvoffset}, which is in units of the base
type.)

\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}
Java binding of the MPI operation {\em MPI\_SCATTER}.
The value {\tt sendoffset} is a subscript in
{\tt sendbuf}, defining the position of the first item of the
data to be scattered.
The value {\tt recvoffset} is a subscript in {\tt recvbuf},
defining the position into which the first item of the incoming
message will be copied.

\begin{verbatim}

void Intracomm.Scatterv(Object sendbuf, int sendoffset,
                        int [] sendcount, int [] displs,
                        Datatype sendtype,
                        Object recvbuf, int recvoffset,
                        int recvcount, Datatype recvtype, int root)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SCATTERV}.
Arguments other than {\tt displs} as for {\tt Scatter}.

\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}
Java binding of the MPI operation {\em MPI\_ALLGATHER}.
Arguments as for {\tt Gather}, except for the omission of {\tt root}.

\begin{verbatim}

void Intracomm.Allgatherv(Object sendbuf, int sendoffset,
                          int sendcount, Datatype sendtype,
                          Object recvbuf, int recvoffset,
                          int recvcount, int [] displs,
                          Datatype recvtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GATHERV}.
Arguments other than {\tt displs} as for {\tt Gather},
except for the omission of {\tt root}.

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

\begin{verbatim}

void Intracomm.Alltoall(Object sendbuf, int sendoffset,
                        int sendcount, Datatype sendtype,
                        Object recvbuf, int recvoffset,
                        int [] recvcount, Datatype recvtype)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ALLTOALL}.
The value {\tt sendoffset} is a subscript in
{\tt sendbuf}, defining the position of the first item of the
data to be scattered.
The value {\tt recvoffset} is a subscript in {\tt recvbuf},
defining the position into which the first item of the 
gathered data will be copied.

\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}
Java binding of the MPI operation {\em MPI\_ALLTOALLV}.
Arguments other than {\tt sdispls}, {\tt rdispls} as for {\tt Alltoall}.

\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}
Java binding of the MPI operation {\em MPI\_REDUCE}.
The value {\tt sendoffset} is a subscript in
{\tt sendbuf}, defining the position of the first item input data.
The value {\tt recvoffset} is a subscript in {\tt recvbuf},
defining the position into which the first item of result data
be copied.

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}
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, Object outvec,
                              Datatype datatype) ;
  }
\end{verbatim}
\normalsize
There is an implementation problem here: how does the C code inside the
wrapper persuade the MPI reduction operation to invoke the Java
method, {\tt call}?  Some C {\tt MPI\_User\_function} must dispatch
the {\tt call} method of a Java object of type {\tt
User\_function}.  The difficulty is creating a C function at runtime
that will do this.  A generic C function can reference a Java
object through a handle held in some static variable.  But if more
than one user defined operation is needed, how does a particular
invocation find the proper Java function object?  One possibility is to
assume a fixed bound, $N$, on the number of allowed user-defined
operations, and define $N$ different {\tt MPI\_User\_function}
functions, invoking {\tt call} methods through $N$ different static
variables.  These {\tt MPI\_User\_function}/static-variable pairs are
managed as a pool.  Calling the {\tt Op} constructor involves copying a
handle to its {\tt function} object argument into one of the static
variables in the pool and passing the corresponding {\tt
MPI\_User\_function} to {\em MPI\_OP\_CREATE}.

\begin{verbatim}

void Op.finalize()
\end{verbatim}
The {\tt Op} destructor will invoke 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}
Java binding of the MPI operation {\em MPI\_ALLREDUCE}.
Arguments as for {\tt Reduce}, except for the omission of {\tt root}.

\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}
Java binding of the MPI operation {\em MPI\_REDUCE\_SCATTER}.
Arguments as for {\tt Reduce}, except for the omission of {\tt root}
and replacement of {\tt count} with {\tt recvcounts}.

\subsection{Scan}

\begin{verbatim}

void Intracomm.Scan(Object sendbuf, int sendoffset,
                    Object recvbuf, int recvoffset,
                    int count, Datatype datatype,
                    Op op)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_SCAN}.
Arguments as for {\tt Reduce}, except for the omission of {\tt root}.

\subsection{Correctness}

No special issues for Java binding.

\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}
Java binding of the MPI operation {\em MPI\_GROUP\_SIZE}.
The return value is {\em size}.

\begin{verbatim}

int Group.Rank()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_RANK}.
The return value is {\em Rank}.

\begin{verbatim}

static int [] Group.Translate_ranks(Group group1, int [] ranks1,
                                    Group group2)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_TRANSLATE\_RANKS}.
The value of {\em n} is taken to be size of the {\tt ranks1} argument.
The return value is {\em ranks2}.

\begin{verbatim}

static int Group.Compare(Group group1, Group group2)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_COMPARE}.
The return value is {\em result}.

\begin{verbatim}

Group Comm.Group()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_GROUP}.
The return value is {\em group}.

\begin{verbatim}

static Group Group.Union(Group group1, Group group2)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_UNION}.
The return value is {\em newgroup}.

\begin{verbatim}

static Group Group.Intersection(Group group1, Group group2)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_INTERSECTION}.
The return value is {\em newgroup}.

\begin{verbatim}

static Group Group.Difference(Group group1, Group group2)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_DIFFERENCE}.
The return value is {\em newgroup}.

\begin{verbatim}

Group Group.Incl(int [] ranks)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_INCL}.
The value of {\em n} is taken to be size of the {\tt ranks} argument.
The return value is {\em newgroup}.

\begin{verbatim}

Group Group.Excl(int [] ranks)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_EXCL}.
The value of {\em n} is taken to be size of the {\tt ranks} argument.
The return value is {\em newgroup}.

\begin{verbatim}

Group Group.Range_incl(int [] [] ranges)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_RANGE\_INCL}.
The value of {\em n} is taken to be size of the {\tt ranges} argument.
The return value is {\em newgroup}.

\begin{verbatim}

Group Group.Range_excl(int [] [] ranges)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GROUP\_RANGE\_EXCL}.
The value of {\em n} is taken to be size of the {\tt ranges} argument.
The return value is {\em newgroup}.

\begin{verbatim}

void Group.finalize()
\end{verbatim}
The {\tt Group} destructor will invoke the MPI operation {\em
MPI\_GROUP\_FREE}.

\subsection{Communicator Management}

\begin{verbatim}

int Comm.Size()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_SIZE}.
The return value is {\em size}.

\begin{verbatim}

int Comm.Rank()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_RANK}.
The return value is {\em rank}.

\begin{verbatim}

static int Compare(Comm comm1, Comm comm2)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_COMPARE}.
The return value is {\em result}.

The constants {\em MPI\_IDENT}, {\em MPI\_CONGRUENT}, {\em MPI\_SIMILAR},
{\em MPI\_UNEQUAL} are available as
{\tt MPI.IDENT}, {\tt MPI.CONGRUENT}, {\tt MPI.SIMILAR},
{\tt MPI.UNEQUAL}.

\begin{verbatim}

Object Comm.clone()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_DUP}.
The return value is {\em newcomm}.

\begin{verbatim}

Intracomm Intracomm.Create(Group group)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_CREATE}.
{The return value is {\em newcomm}.

\begin{verbatim}

Intracomm Intracomm.Split(int colour, int key)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_SPLIT}.
The return value is {\em newcomm}.

\begin{verbatim}

void Comm.Free()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_FREE}.
(Note: a {\em Free} method is required rather than a {\em finalize}
method, because {\em MPI\_COMM\_FREE} is, strictly-speaking, a
collective operations, and we cannot assume that the Java garbage
collector would call a {\em finalize} method synchronously on all
processors.)

\subsection{Motivating Examples}

No special issues for Java binding.

\subsection{Inter-Communication}

\begin{verbatim}

boolean Comm.Test_inter()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_TEST\_INTER}.
The return value is {\em flag}.

\begin{verbatim}

int Intercomm.Remote_size()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_REMOTE\_SIZE}.
The return value is {\em size}.

\begin{verbatim}

Group Intercomm.Remote_group()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_COMM\_REMOTE\_GROUP}.
The return value is {\em group}.

\begin{verbatim}

Intercomm Comm.Create_intercomm(Comm local_comm, int local_leader,
                                int remote_leader, int tag)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_INTERCOMM\_CREATE}.
The class instance is {\em peer\_comm}.
The return value is {\em newintercomm}.

\begin{verbatim}

Intracomm Intercomm.merge(boolean high)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_INTERCOMM\_MERGE}.
The class instance is {\em intercomm}.
The return value is {\em newintracomm}.

\subsection{Caching}

It is assumed that, to achieve the effect of caching attributes in
user-customized communicator, programmers will create subclasses of the
library-defined communicator classes.

%\begin{verbatim}
%
%static int MPI.Keyval_create(Call_back call_back)
%\end{verbatim}
%Java binding of the MPI operation {\em MPI\_KEYVAL\_CREATE}.
%The return value is {\em keyval}.
%
%The abstract base class, {\tt Call\_back}, is
%\small
%\begin{verbatim}
%  class Call_back {
%    public abstract Object copy(Comm oldcomm, int keyval,
%                                Object attribute_val_in) ;
%
%    public abstract void delete(Comm comm, int keyval,
%                                Object attribute_val) ;
%  }
%\end{verbatim}
%\normalsize
%
%We sketch a possible implementation of this binding.
%
%The Java function {\tt Keyval\_create} calls {\em MPI\_KEYVAL\_CREATE}
%setting {\em copy\_fn}, {\em delete\_fn} to generic Java values
%{\tt Java\_copy\_fn}, {\tt Java\_delete\_fn}, and setting
%{\em extra\_state} to be a handle to the {\tt call\_back} object.
%In a mixed-language pseudocode, the schematic implementation
%of the generic Java call back functions is
%\small
%\begin{verbatim}
%  Java_copy_fn(oldcomm, keyval, extra_state, attribute_val_in,
%               attribute_val_out, flag) {
%
%    attribute_val_out = extra_state.copy(oldcomm, keyval,
%                                         attribute_val_in)) ;
%    if(attribute_val_out)
%      flag = true ;
%    else
%      flag = false ;
%  }
%
%
%  int Java_delete_fn(comm, keyval, attribute_val, extra_state) {
%
%    extra_state.delete(comm, keyval, attribute_val) ;
%  }
%\end{verbatim}
%\normalsize
%(remember that {\tt extra\_state} is a handle to {\tt call\_back}).
%The actual implementation of these functions will be in C with JNI calls, and
%it may be necessary to cache the JNI environment pointer along with
%{\tt call\_back} in the MPI {\em extra\_state}.  In any case, any
%``extra state'' the Java programmer really needs sits naturally in the
%{\tt call\_back} object defined by that programmer.
%
%\begin{verbatim}
%
%static void MPI.Keyval_free(int keyval)
%\end{verbatim}
%Java binding of the MPI operation {\em MPI\_KEYVAL\_FREE}.

\begin{verbatim}

void Comm.Attr_put(int keyval, Object attribute_val)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ATTR\_PUT}.

\begin{verbatim}

Object Comm.Attr_get(int keyval)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ATTR\_GET}.
If {\em flag} is false, return value is {\tt null}.  Otherwise
return value is {\em attribute\_val}

\begin{verbatim}

void Comm.Attr_delete(int keyval)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ATTR\_DELETE}.

\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}
Java binding of the MPI operation {\em MPI\_CART\_CREATE}.
The class instance is {\em comm\_old}.
The value of {\em ndims} is taken to be size of the {\tt dims} argument.
The constructed object is {\em comm\_cart}.

\begin{verbatim}

static int [] Cartcomm.Dims_create(int nnodes, int ndims)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_DIMS\_CREATE}.
The return value is {\em dims}.

\begin{verbatim}

Graphcomm Intracomm.Create_graph(int [] index, int [] edges,
                                 boolean reorder)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GRAPH\_CREATE}.
The class instance is {\em comm\_old}.
The value of {\em nnodes} is taken to be size of the {\tt index} argument.
The constructed object is {\em comm\_graph}.

\begin{verbatim}

int Comm.Topo_test()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_Topo\_TEST}.
The return value is {\em status}.  It will be one of
{\tt MPI.GRAPH}, {\tt MPI.CART} or {\tt MPI.UNDEFINED}.

\begin{verbatim}

GraphParms Graphcomm.Get()
\end{verbatim}
Java binding of the MPI operations {\em MPI\_GRAPHDIMS\_GET} and
{\em MPI\_GRAPH\_GET}.
The return value contains {\em index} and {\em edges}.
The values of {\em nnodes} and {\em nedges} can be extracted
from the sizes of these arrays.

\begin{verbatim}

CartParms Cartcomm.Get()
\end{verbatim}
Java binding of the MPI operations {\em MPI\_CARTDIM\_GET} and
{\em MPI\_CART\_GET}.
The return value contains {\em dims} and {\em periods} and {\em coords}.
The value of {\em ndims} can be extracted from the size of {\em dims}.

\begin{verbatim}

int Cartcomm.Rank(int [] coords)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_CART\_RANK}.
The return value is {\em rank}.

\begin{verbatim}

int [] Cartcomm.Coords(int rank)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_CART\_COORDS} and  
{\em MPI\_CARTDIM\_GET} .
The return value is {\em coords}.

\begin{verbatim}

int [] Graphcomm.Neighbours(int rank)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GRAPH\_NEIGHBOURS\_COUNT}
and {\em MPI\_GRAPH\_NEIGHBOURS}.
The return value is {\em neighbours}.
The value of {\em nneighbours} can be extracted from the size {\em neighbours}.

\begin{verbatim}

ShiftParms Cartcomm.Shift(int direction, int disp)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_CART\_SHIFT}.
The return value contains {\em rank\_source} and {\em rank\_dest}.


\begin{verbatim}

Cartcomm Cartcomm.Sub(boolean [] remain_dims)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_CART\_SUB}.
The return value is {\em newcomm}.

\begin{verbatim}

int Cartcomm.Map(int [] dims, boolean [] periods)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_CART\_MAP}.
The value of {\em ndims} is taken to be size of the {\tt dims} argument.
The return value is {\em newrank}.

\begin{verbatim}

int Graphcomm.Map(int [] index, int [] edges)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_GRAPH\_MAP}.
The value of {\em nnodes} is taken to be size of the {\tt index} argument.
The return value is {\em newrank}.

\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}
Java binding of the MPI operation {\em MPI\_GET\_PROCESSOR\_NAME}.
The return value is {\em 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}).

For now, we omit a specification of Java interface for creating new MPI error
handlers, because the detailed interface of the handler function
depends on unstandardized features of the MPI implementation.

\begin{verbatim}

static void MPI.Errorhandler_set(Errhandler errhandler)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ERRORHANDLER\_SET}.

\begin{verbatim}

static Errhandler MPI.Errorhandler_get()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ERRORHANDLER\_GET}.
The return value is {\em errhandler}.


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

The {\tt IOException} 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.

\subsection{Timers}

\begin{verbatim}

static double MPI.Wtime()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WTIME}.

\begin{verbatim}

static double MPI.Wtick()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_WTICK}.

\subsection{Startup}

\begin{verbatim}

static void MPI.Init(String[] argv)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_INIT}.
The value of {\em argc} is taken to be size of the {\tt argv} argument.

\begin{verbatim}

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

\begin{verbatim}

static boolean MPI.Initialized()
\end{verbatim}
Java binding of the MPI operation {\em MPI\_INITIALIZED}.
The return value is {\em flag}.

\begin{verbatim}

void Comm.Abort(int errorcode)
\end{verbatim}
Java binding of the MPI operation {\em MPI\_ABORT}.

\newpage

\appendix

\section{Full public interface of classes}

Comments included in the class definitions are generally
cross-references to names of sections in the main document, where
members following the comment are defined.

\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, 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 ;

  public static Request REQUEST_NULL;

  // Buffer allocation and usage

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

  public static void Buffer_detach(byte [] buffer) {...}


  // Environmental Management

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

  public static void Finalize() {...}

  public static String Get_processor_name() {...}

  public static void Errorhandler_set(Errhandler errhandler) {...}

  public static Errhandler Errorhandler_get() {...}

  public static double Wtime() {...}

  public static double Wtick() {...}

  public static boolean Initialized() {...}

  ...
}
\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() {...}

  public int Rank() {...}

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

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

  public Object clone() {...}

  public void Free() {...}


  // Inter-communication

  public boolean Test_inter() {...}

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


  // Caching

  public void Attr_put(int keyval, Object attribute_val) {...}

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

  public void Attr_delete(int keyval) {...}


  // Blocking Send and Receive operations

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

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


  // Communication Modes

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

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

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


  // Nonblocking communication

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

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

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

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

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


  // Probe and cancel

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

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


  // Persistent communication requests

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

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

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

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

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


  // 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) {...}

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

  // Pack and unpack

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

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

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


  // Process Topologies

  int Topo_test()


  // Environmental Management

  void Abort(int errorcode) {...}

  ...
}
\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) {...}

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

  // Collective communication

  public void Barrier() {...}

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

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

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

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

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

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

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

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

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

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

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

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

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


  // Topology Constructors

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

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

  ...
}
\end{verbatim}
\normalsize

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

  public Object clone() { ... }

  // Inter-communication

  public int Remote_size() {...}

  public Group Remote_group() {...}

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

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Op}

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

  void finalize() {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Group}

\small
\begin{verbatim}
public class Group {

  // Group Management

  public int Size() {...}

  public int Rank() {...}

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

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

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

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

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

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

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

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

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

  public void finalize() {...}

  ...
}
\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) {...}


  // Probe and Cancel

  public boolean Test_cancelled() {...}


  // Derived datatypes

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

  ...
}
\end{verbatim}
\normalsize

\newpage

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

\small
\begin{verbatim}
public class Request {

  // Nonblocking communication

  public Status Wait() {...}

  public Status Test() {...}

  public void finalize() {...}

  public boolean Is_null() {...}

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

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

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

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

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

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


  // Probe and cancel

  public void Cancel() {...}

  ...
}
\end{verbatim}
\normalsize

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

  // Persistent communication requests

  public void Start() {...}

  public static void Startall(Request [] array_of_requests) {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{\tt Datatype}

\small
\begin{verbatim}
public class Datatype {

  // Derived datatypes

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

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

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

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

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

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

  public int Extent() {...}

  public int Size() {...}

  public int Lb() {...}

  public int Ub() {...}

  public void Commit() {...}

  public void finalize() {...}

  ...
}
\end{verbatim}
\normalsize

\newpage

\subsection{Classes for virtual topologies}

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

  public Object clone() { ... }

  // Topology Constructors

  static public int [] Dims_create(int nnodes, int ndims) {...}

  public CartParms Get() {...}

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

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

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

  public Cartcomm Sub(boolean [] remain_dims) {...}

  public int Map(int [] dims, boolean [] periods) {...}
}
\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 rank_source ;
  public int rank_dest ; 
}
\end{verbatim}
\normalsize


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

  public Object clone() { ... }

  // Topology Constructors

  public GraphParms Get() {...}

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

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

\small
\begin{verbatim}
public class GraphParms {

  // Return type for Graphcomm.Get()

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


\end{document}

