The mpjdev API is much simpler. It only includes point-to-point communications. Currently the only messaging modes for mpjdev are standard blocking mode (like MPI_SEND, MPI_RECV) and standard non-blocking mode (like MPI_ISEND, MPI_IRECV), together with a couple of ``wait'' primitives.
The communicator class, Comm, is very similar to the one in MPI but it has a reduced number of functionalities. It has communication methods like send(), recv(), isend(), and irecv(), and defines constants ANY_SOURCE, and ANY_TAG as static variables.
Figure 5.7 shows the public interface of Comm class.
We can get the number of processes that are spanned by this communicator by calling size() (similar to MPI_COMM_SIZE). Current id of process relative to this communicator is returned by id() (similar to MPI_COMM_RANK).
The two methods send() and recv() are blocking communication modes. These two methods block until the communication finishes. The method send() sends a message containing the contents of buf to the destination described by dest and message tag value tag.
The method recv() receives a message from matching source described by src with matching tag value tag and copies contents of message to the receive buffer, buf. The receiver may use wildcard value ANY_SOURCE for src and ANY_TAG for tag instead specifying src and tag values. These indicate that a receiver accepts any source and/or tag of send. The Comm class also has the initial communicator, WORLD, like MPI_COMM_WORLD in MPI and other utility methods. The capacity of receive buffer must be large enough to accept these contents. Initializes the source and tag fields of the returned Status class which describes a completed communication.
The functionalities of send() and recv() methods are same as standard mode point-to-point communication of MPI (MPI_SEND and MPI_RECV). A recv() will be blocked until the send if posted. A send() will be blocked until the message have been safely stored away. Internal buffering is not guaranteed in send(), and the message may be copied directly into the matching receive buffer. If no recv() is posted, send() is allowed to block indefinitely, depending on the availability of internal buffering in the implementation. The programmer must allow for this--this is a low-level API for experts.
The other two communication methods isend() and irecv() are non-blocking versions of send() and recv. These are equivalent to MPI_ISEND and MPI_IRECV in MPI. Unlike blocking send, a non-blocking send returns immediately after its call and does not wait for completion. To complete the communication a separate send complete call (like iwait() and iwaitany() methods in the Request class) is needed. A non-blocking receive also work similarly. The wait() operations block exactly as for the blocking versions of send() and recv() (e.g. the wait() operation for an isend() is allowed to block indefinitely if no matching receive is posted).
The method dup() creates a new communicator the spanning the same set of processes, but with a distinct communication context. We can also create a new communicator spanning a selected set of processes selected using the create() method. The ids of array ids contains a list of ids relative to this communicator. Processes that are outside of the group will get a null result. The new communicator has a distinct communication context.
By calling the free() method, we can destroy this communicator (like MPI_COMM_FREE in MPI). This method is called usually when this communicator is no longer in use. It frees any resources that used by this communicator.
We should call static init() method once before calling any other methods in communicator. This static method initializes mpjdev and makes it ready to use. The static method finish() (which is equivalent of MPI_FINALIZE) is the last method should be called in mpjdev.