SST/macro
Basic MPI Program

Basic MPI Program

Let us go back to the simple send/recv skeleton and actually look at the code.

#include <stdlib.h>
#include <stdio.h>
#include <sstmac/sstmpi.h>
#include <sstmac/util.h>
int user_skeleton_main(int argc, char **argv)
{
int message_size = 128;
int me, nproc;
int tag = 0;
int dst = 1;
int src = 0;
MPI_Status stat;
MPI_Init(&argc,&argv);
MPI_Comm world = MPI_COMM_WORLD;
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nproc);

The starting point is creating a main routine for the application, which should be named user_skeleton_main. When SST/macro launches, it will invoke this routine and pass in any command line arguments specified via the launch_app1_argv parameter. Upon entering the main routine, the code is now indistinguishable from regular MPI C code. In the parameter file to be used with the simulation, you must set

1 launch_app1 = user_mpiapp_c

or, if compiling as C++

1 launch_app1 = user_mpiapp_cxx

At the very top of the file, the SST/macro header files must be included. This header provides the MPI API and configures MPI function calls to link to SST/macro instead of the real MPI library. In most cases, only sstmpi.h will be needed, but util.h contains utility functions that may be useful. If trying to maintain code as "single-source'' compilable without modification for both SST/macro and actual MPI, we recommend creating a parallel.h.

#ifdef SSTMACRO
#include <sstmac/sstmpi.h>
#include <sstmac/util.h>
#define USER_MAIN user_skeleton_main
#else
#include <mpi.h>
#define USER_MAIN main
#endif

This creates a central point for swapping back and forth. The beginning of the file would then become

#include <stdlib.h>
#include <stdio.h>
#include <parallel.h>
int USER_MAIN(int argc, char **argv)
{

The end of the file is again just regular MPI C code:

if (nproc != 2) {
fprintf(stderr, "sendrecv only runs with two processors\n");
abort();
}
if (me == 0) {
MPI_Send(NULL, message_size, MPI_INT, dst, tag, world);
printf("rank %i sending a message\n", me);
}
else {
MPI_Recv(NULL, message_size, MPI_INT, src, tag, world, &stat);
printf("rank %i receiving a message\n", me);
}
MPI_Finalize();
return 0;
}

Here the code just checks the MPI rank and sends (rank 0) or receives (rank 1) a message.