MP_Lite: Using standard MPI syntax

MP_Lite provides MPI wrappers that allow you to use standard MPI syntax to run on top of the MP_Lite library. However, only a subset of the core functions are supported. This is referred to as 'MPI_Lite' mode, since it is essentially a lightweight implementation of the core set of MPI functions that most users will need. MPI_Lite provides the same high level of performance you would get using the MP_Lite syntax directly. It is, in my opinion, not as convenient, but many codes are already programmed in MPI, and it is 'the standard', so most users will go this route.

To use MP_Lite with an MPI code, simply compile the MP_Lite library for the system desired (make tcp, shmem, scalar, etc.). Be sure not to use 'make mpi' to compile the library, as this would have your MPI code running on top of MP_Lite that was compiled to run on top of MPI. You also need to be careful to use the mpi.h and mpif.h files included in the MP_Lite package. This should just be a matter of setting the -I include path properly in your compile lines.

Use the mprun or mpirun scripts described previously to run your MPI code.

Below is a complete listing of the MPI functions supported for C and Fortran. All the basic stuff that most people need is supported. All MPI data types are supported. For global functions, only the sum, max, and min functions are currently supported, though it would be easy to add more in the mpcore.c file.

What is missing are most of the more advanced features like support for communicators, derived data types, etc. If you think there is something 'basic' that is missing, send me email, but I won't make any guarantees. MP_Lite will never grow into a full implementation.

Definitions for variables below

ierror = the return error value for all Fortran MPI functions
In C, the error code is the return value of the function

nprocs = the number of processes in the run
myproc = my relative process number (rank) from 0 .. nprocs-1

buf, sbuf, dbuf, array, result = the buffer addresses for sends/recvs
count, scount, dcount = the number of elements to send/recv
datatype, stype, dtype = the type of element (MPI_INT, MPI_DOUBLE, etc)
operator = MPI_Op type (MPI_MAX, MPI_MIN, MPI_SUM)
tag, stag, dtag = the message tag, which can be used for sorting
comm = the communicator, which is MPI_COMM_WORLD for MP_Lite
request = the message id for asynchronous communications
status = the status structure for asynchronous communications

base = the pointer to the base of a window for 1-sided communications
local_buf, remote_buf = the buffer addresses for puts/gets
nbytes = the size in bytes
window = the window for a 1-sided communication
disp, local_disp, remote_disp = displacement from the window base

root = the rank of the root process
MPI Fortran functions supported
INCLUDE "mpif.h"

CALL MPI_Init(ierror)
CALL MPI_Comm_size(comm, nprocs, ierror)
CALL MPI_Comm_rank(comm, myproc, ierror)
CALL MPI_Finalize(ierror)

CALL MPI_Send(buf, count, stype, dest, stag, comm, ierror)
CALL MPI_Isend(buf, count, stype, dest, stag, comm, request, ierror)
CALL MPI_Ssend(buf, count, stype, dest, stag, comm, ierror)
CALL MPI_Recv(buf, count, dtype, source, dtag, comm, ierror)
CALL MPI_Irecv(buf, count, dtype, source, dtag, comm, request, ierror)
CALL MPI_Wait( request, status, ierror)
CALL MPI_Waitall( count, array_of_requests, array_of_statuses, ierror)

CALL MPI_Buffer_attach( buffer, buffer_size + MPI_BSEND_OVERHEAD, ierror )
CALL MPI_Bsend(buf, count, stype, dest, stag, comm, ierror)
CALL MPI_Ibsend(buf, count, stype, dest, stag, comm, request, ierror)
CALL MPI_Buffer_detach( buffer, buffer_size, ierror )

CALL MPI_Put( local_buf, scount, stype, dest, remote_disp, dcount, dtype, window, ierror)
CALL MPI_Get( remote_buf, scount, stype, source, local_disp, dcount, dtype, window, ierror)
CALL MPI_Accumulate( sbuf, scount, stype, dest, remote_disp, dcount, dtype, operator, window, ierror)
CALL MPI_Win_create( base, nbytes, disp_unit, info, comm, window)
CALL MPI_Win_free( base, ierror )

CALL MPI_Bcast(array, count, datatype, root, comm, ierror)
CALL MPI_Reduce( array, result, count, datatype, operator, root, comm, ierror)
CALL MPI_Allreduce( array, result, count, datatype, operator, comm, ierror)
CALL MPI_Gather( sbuf, scount, stype, dbuf, dcount, dtype, root, comm, ierror)
CALL MPI_Allgather( sbuf, scount, stype, dbuf, dcount, dtype, comm, ierror)
CALL MPI_Sendrecv( sbuf, scount, stype, dest, stag, dbuf, dcount, dtype, source, dtag, comm, status, ierror)
CALL MPI_Sendrecv_replace( buf, count, datatype, dest, stag, source, dtag, comm, status, ierror)

CALL MPI_Abort( comm, ierror)
CALL MPI_Test( request, rtn_flag, status, ierror)
CALL MPI_Testall( count, array_of_request, rtn_flag, array_of_statuses, ierror)
CALL MPI_Get_count( status, datatype, count, ierror)

CALL MPI_Barrier(comm, ierror)

DOUBLE PRECISION time_x
time_x = MPI_Wtime()

MPI_Cart_create, MPI_Cart_coords, MPI_Cart_get, MPI_Cart_shift, MPI_Cart_rank
MPI_Comm_free, MPI_Comm_group, MPI_Group_incl
MPI C functions supported
#include "mpi.h"

MPI_Init(&argc, &argv);
MPI_Comm_size(comm, &nprocs);
MPI_Comm_rank(comm, &myproc);
MPI_Finalize();

MPI_Send(&buf, count, stype, dest, stag, comm);
MPI_Isend(&buf, count, stype, dest, stag, comm, &request);
MPI_Ssend(&buf, count, stype, dest, stag, comm);
MPI_Recv(&buf, count, dtype, source, dtag, comm);
MPI_Irecv(&buf, count, dtype, source, dtag, comm, &request);
MPI_Wait( &request, &status);
MPI_Waitall( count, &array_of_requests, &array_of_statuses);

MPI_Buffer_attach( &buffer, buffer_size + MPI_BSEND_OVERHEAD);
MPI_Bsend(&buf, count, stype, dest, stag, comm);
MPI_Ibsend(&buf, count, stype, dest, stag, comm, &request);
MPI_Buffer_detach( &(&buffer), &buffer_size);

MPI_Put( &local_buf, scount, stype, dest, remote_disp, dcount, dtype, window);
MPI_Get( &remote_buf, scount, stype, source, local_disp, dcount, dtype, window);
MPI_Accumulate( &sbuf, scount, stype, dest, remote_disp, dcount, dtype, operator, window);
MPI_Win_create( &base, nbytes, disp_unit, info, comm, &window);
MPI_Win_free( &base);

MPI_Bcast(&array, count, datatype, root, comm);
MPI_Reduce( &array, result, count, datatype, operator, root, comm);
MPI_Allreduce( &array, result, count, datatype, operator, comm);
MPI_Gather( &sbuf, scount, stype, &dbuf, dcount, dtype, root, comm);
MPI_Allgather( &sbuf, scount, stype, &dbuf, dcount, dtype, comm);
MPI_Sendrecv( &sbuf, scount, stype, dest, stag, &dbuf, dcount, dtype, source, dtag, comm, &status);
MPI_Sendrecv_replace( &buf, count, datatype, dest, stag, source, dtag, comm, &status);

MPI_Abort( comm);
MPI_Test( request, &rtn_flag, &status);
MPI_Testall( count, &array_of_request, &rtn_flag, &array_of_statuses);
MPI_Get_count( &status, datatype, &count);

MPI_Barrier(comm);

double time_x, MPI_Wtime();
time_x = MPI_Wtime();

MPI_Cart_create, MPI_Cart_coords, MPI_Cart_get, MPI_Cart_shift, MPI_Cart_rank
MPI_Comm_free, MPI_Comm_group, MPI_Group_incl

One-sided communications
The one-sided communications are currently only supported in the TCP module. They will soon be added to the SMP module.

Buffered sends

MP_Lite automatically handles the buffering in the basic send operation, so it is not necessary to do it manually. The MPI_Bsend() and MPI_Ibsend() are therefore mapped directly into the basic MP_Send() and MP_ASend() functions and the MPI_Buffer_attach() and MPI_Buffer_detach() functions do nothing.

Cartesian coordinate functions

MPI has several functions to assist in mapping the nodes to a cartesian coordinate system. These are useful, and easy to implement, so I support them in MPI_Lite. For further documentation, look at the function descriptions in the mpcore.c file.