root/orte/test/mpi/xlib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. notification_fn
  2. model_callback
  3. model_registration_callback
  4. main

   1 #include <stdlib.h>
   2 #include <stdio.h>
   3 #include <mpi.h>
   4 #include <pmix.h>
   5 
   6 #define SIZE 20
   7 #define POS 10
   8 #define INITIAL_VALUE 10
   9 
  10 static pmix_proc_t myproc;
  11 
  12 /* this is the event notification function we pass down below
  13  * when registering for general events - i.e.,, the default
  14  * handler. We don't technically need to register one, but it
  15  * is usually good practice to catch any events that occur */
  16 static void notification_fn(size_t evhdlr_registration_id,
  17                             pmix_status_t status,
  18                             const pmix_proc_t *source,
  19                             pmix_info_t info[], size_t ninfo,
  20                             pmix_info_t results[], size_t nresults,
  21                             pmix_event_notification_cbfunc_fn_t cbfunc,
  22                             void *cbdata)
  23 {
  24     /* this example doesn't do anything with default events */
  25     fprintf(stderr, "Default event handler called with status %s\n", PMIx_Error_string(status));
  26 
  27     if (NULL != cbfunc) {
  28         cbfunc(PMIX_EVENT_ACTION_COMPLETE, NULL, 0, NULL, NULL, cbdata);
  29     }
  30 }
  31 
  32 /* this is an event notification function that we explicitly request
  33  * be called when the PMIX_MODEL_DECLARED notification is issued.
  34  * We could catch it in the general event notification function and test
  35  * the status to see if the status matched, but it often is simpler
  36  * to declare a use-specific notification callback point. In this case,
  37  * we are asking to know whenever a programming model library is
  38  * instantiated */
  39 static void model_callback(size_t evhdlr_registration_id,
  40                            pmix_status_t status,
  41                            const pmix_proc_t *source,
  42                            pmix_info_t info[], size_t ninfo,
  43                            pmix_info_t results[], size_t nresults,
  44                            pmix_event_notification_cbfunc_fn_t cbfunc,
  45                            void *cbdata)
  46 {
  47     size_t n;
  48 
  49     fprintf(stderr, "Model event handler called with status %d(%s)\n", status, PMIx_Error_string(status));
  50 
  51     /* check to see what model declared itself */
  52     for (n=0; n < ninfo; n++) {
  53         if (PMIX_STRING == info[n].value.type) {
  54             fprintf(stderr, "\t%s:\t%s\n", info[n].key, info[n].value.data.string);
  55         }
  56     }
  57 
  58     /* we must NOT tell the event handler state machine that we
  59      * are the last step as that will prevent it from notifying
  60      * anyone else that might be listening for declarations */
  61     if (NULL != cbfunc) {
  62         cbfunc(PMIX_SUCCESS, NULL, 0, NULL, NULL, cbdata);
  63     }
  64 }
  65 
  66 /* event handler registration is done asynchronously because it
  67  * may involve the PMIx server registering with the host RM for
  68  * external events. So we provide a callback function that returns
  69  * the status of the request (success or an error), plus a numerical index
  70  * to the registered event. The index is used later on to deregister
  71  * an event handler - if we don't explicitly deregister it, then the
  72  * PMIx server will do so when it see us exit */
  73 static void model_registration_callback(pmix_status_t status,
  74                                         size_t evhandler_ref,
  75                                         void *cbdata)
  76 {
  77     volatile int *active = (volatile int*)cbdata;
  78 
  79     if (PMIX_SUCCESS != status) {
  80         fprintf(stderr, "Client %s:%d EVENT HANDLER REGISTRATION FAILED WITH STATUS %d, ref=%lu\n",
  81                    myproc.nspace, myproc.rank, status, (unsigned long)evhandler_ref);
  82     }
  83     *active = status;
  84 }
  85 
  86 int main(int argc, char *argv[])
  87 {
  88     int i, rank, size, next, prev, tag = 201;
  89     int array_size = SIZE;
  90     int pos = POS;
  91     int *send_array;
  92     int *recv_array;
  93     pmix_info_t *info;
  94     size_t ninfo;
  95     pmix_status_t code = PMIX_MODEL_DECLARED;
  96     pmix_status_t rc;
  97     volatile int active;
  98 
  99 
 100     if (1 < argc) {
 101         fprintf(stderr, "Declaring ourselves\n");
 102         /* declare ourselves as a non-MPI library prior to MPI_Init */
 103         ninfo = 4;
 104         PMIX_INFO_CREATE(info, ninfo);
 105         PMIX_INFO_LOAD(&info[0], PMIX_PROGRAMMING_MODEL, "EXAMPLE", PMIX_STRING);
 106         PMIX_INFO_LOAD(&info[1], PMIX_MODEL_LIBRARY_NAME, "FOOL", PMIX_STRING);
 107         PMIX_INFO_LOAD(&info[2], PMIX_MODEL_LIBRARY_VERSION, "1.2.3", PMIX_STRING);
 108         PMIX_INFO_LOAD(&info[3], PMIX_THREADING_MODEL, "NONE", PMIX_STRING);
 109         if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, info, ninfo))) {
 110             fprintf(stderr, "PMIx Init failed: %s\n", PMIx_Error_string(rc));
 111             exit(1);
 112         }
 113         PMIX_INFO_FREE(info, ninfo);
 114 
 115         /* register a handler specifically for when models declare */
 116         active = -1;
 117         ninfo = 1;
 118         PMIX_INFO_CREATE(info, ninfo);
 119         PMIX_INFO_LOAD(&info[0], PMIX_EVENT_HDLR_NAME, "APP-MODEL", PMIX_STRING);
 120         PMIx_Register_event_handler(&code, 1, info, ninfo,
 121                                     model_callback, model_registration_callback, (void*)&active);
 122         while (-1 == active) {
 123             usleep(10);
 124         }
 125         PMIX_INFO_FREE(info, ninfo);
 126         if (0 != active) {
 127             exit(active);
 128         }
 129     }
 130 
 131     /* initialize the MPI library - it will declare itself */
 132     MPI_Init(&argc, &argv);
 133     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 134     MPI_Comm_size(MPI_COMM_WORLD, &size);
 135     if (argc <= 1) {
 136         fprintf(stderr, "Registering handler\n");
 137         /* register a handler specifically for when models declare */
 138         active = -1;
 139         ninfo = 1;
 140         PMIX_INFO_CREATE(info, ninfo);
 141         PMIX_INFO_LOAD(&info[0], PMIX_EVENT_HDLR_NAME, "APP-MODEL", PMIX_STRING);
 142 
 143         PMIx_Register_event_handler(&code, 1, info, ninfo,
 144                                     model_callback, model_registration_callback, (void*)&active);
 145         while (-1 == active) {
 146             usleep(10);
 147         }
 148         PMIX_INFO_FREE(info, ninfo);
 149         if (0 != active) {
 150             exit(active);
 151         }
 152     }
 153 
 154     fprintf(stderr, "Rank %d has cleared MPI_Init\n", rank);
 155 
 156     next = (rank + 1) % size;
 157     prev = (rank + size - 1) % size;
 158     send_array = malloc(sizeof(int) * SIZE);
 159     recv_array = malloc(sizeof(int) * SIZE);
 160 
 161     for (i = 0; i < array_size; ++i) {
 162         send_array[i] = 17;
 163         recv_array[i] = -1;
 164     }
 165 
 166     if (0 == rank) {
 167         send_array[pos] = INITIAL_VALUE;
 168         MPI_Send(send_array, array_size, MPI_INT, next, tag,
 169                  MPI_COMM_WORLD);
 170     }
 171 
 172     /* if we didn't already do it, declare another model now */
 173     if (argc <= 1) {
 174         fprintf(stderr, "Declaring ourselves\n");
 175         /* declare ourselves as a non-MPI library after MPI_Init */
 176         ninfo = 4;
 177         PMIX_INFO_CREATE(info, ninfo);
 178         PMIX_INFO_LOAD(&info[0], PMIX_PROGRAMMING_MODEL, "EXAMPLE", PMIX_STRING);
 179         PMIX_INFO_LOAD(&info[1], PMIX_MODEL_LIBRARY_NAME, "FOOL", PMIX_STRING);
 180         PMIX_INFO_LOAD(&info[2], PMIX_MODEL_LIBRARY_VERSION, "1.2.3", PMIX_STRING);
 181         PMIX_INFO_LOAD(&info[3], PMIX_THREADING_MODEL, "NONE", PMIX_STRING);
 182 
 183         if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, info, ninfo))) {
 184             fprintf(stderr, "PMIx Init failed: %s\n", PMIx_Error_string(rc));
 185             exit(1);
 186         }
 187         PMIX_INFO_FREE(info, ninfo);
 188     }
 189 
 190     while (1) {
 191         recv_array[pos] = -1;
 192         MPI_Recv(recv_array, array_size, MPI_INT, prev, tag,
 193                  MPI_COMM_WORLD, MPI_STATUS_IGNORE);
 194         send_array[pos] = recv_array[pos];
 195         if (rank == 0) {
 196             --send_array[pos];
 197         }
 198         MPI_Send(send_array, array_size, MPI_INT, next, tag, MPI_COMM_WORLD);
 199         if (0 == send_array[pos]) {
 200             break;
 201         }
 202     }
 203 
 204     if (rank == 0) {
 205         MPI_Recv(recv_array, array_size, MPI_INT, prev, tag,
 206                  MPI_COMM_WORLD, MPI_STATUS_IGNORE);
 207     }
 208 
 209     fprintf(stderr, "Rank %d has completed ring\n", rank);
 210     MPI_Barrier(MPI_COMM_WORLD);
 211     fprintf(stderr, "Rank %d has completed MPI_Barrier\n", rank);
 212 
 213     /* decrement the PMIx refcount */
 214     PMIx_Finalize(NULL, 0);
 215     MPI_Finalize();
 216     return 0;
 217 }

/* [<][>][^][v][top][bottom][index][help] */