1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
#include <stdio.h>
#include <stdarg.h>
#include <pmix.h>
static void hide_unused_params(int x, ...)
{
va_list ap;
va_start(ap, x);
va_end(ap);
}
//<EG BEGIN ID="declare_model_cb">
static void model_declared_cb(size_t evhdlr_registration_id, pmix_status_t status,
const pmix_proc_t *source, pmix_info_t info[], size_t ninfo,
pmix_info_t results[], size_t nresults,
pmix_event_notification_cbfunc_fn_t cbfunc, void *cbdata)
{
printf("Entered %s\n", __func__);
size_t n;
hide_unused_params(evhdlr_registration_id, status, source, results, nresults);
for (n = 0; n < ninfo; n++) {
if (PMIX_CHECK_KEY(&info[n], PMIX_PROGRAMMING_MODEL)
&& strcmp(info[n].value.data.string, "MPI") == 0) {
/* ignore our own declaration */
break;
} else {
/* actions to perform when another model registers */
}
}
if (NULL != cbfunc) {
/* tell the event handler that we are only a partial step */
cbfunc(PMIX_EVENT_PARTIAL_ACTION_TAKEN, NULL, 0, NULL, NULL, cbdata);
}
}
//<EG END ID="declare_model_cb">
//<EG BEGIN ID="omp_thread">
static void parallel_region_OMP_cb(size_t evhdlr_registration_id, pmix_status_t status,
const pmix_proc_t *source, pmix_info_t info[], size_t ninfo,
pmix_info_t results[], size_t nresults,
pmix_event_notification_cbfunc_fn_t cbfunc, void *cbdata)
{
hide_unused_params(evhdlr_registration_id, status, source, info, ninfo,
results, nresults);
printf("Entered %s\n", __func__);
/* do what we need OpenMP to do on entering a parallel region */
if (NULL != cbfunc) {
/* tell the event handler that we are only a partial step */
cbfunc(PMIX_EVENT_PARTIAL_ACTION_TAKEN, NULL, 0, NULL, NULL, cbdata);
}
}
//<EG END ID="omp_thread">
//<EG BEGIN ID="mpi_thread">
static void parallel_region_MPI_cb(size_t evhdlr_registration_id, pmix_status_t status,
const pmix_proc_t *source, pmix_info_t info[], size_t ninfo,
pmix_info_t results[], size_t nresults,
pmix_event_notification_cbfunc_fn_t cbfunc, void *cbdata)
{
hide_unused_params(evhdlr_registration_id, status, source, info, ninfo,
results, nresults);
printf("Entered %s\n", __func__);
/* do what we need MPI to do on entering a parallel region */
if (NULL != cbfunc) {
/* do what we need MPI to do on entering a parallel region */
cbfunc(PMIX_EVENT_ACTION_COMPLETE, NULL, 0, NULL, NULL, cbdata);
}
}
//<EG END ID="mpi_thread">
static int openmp_handler(void)
{
pmix_info_t *info;
int rc;
printf("Entered %s\n", __func__);
//<EG BEGIN ID="omp_thread">
bool is_true = true;
pmix_status_t code = PMIX_OPENMP_PARALLEL_ENTERED;
PMIX_INFO_CREATE(info, 2);
PMIX_INFO_LOAD(&info[0], PMIX_EVENT_HDLR_NAME, "OpenMP-Master", PMIX_STRING);
PMIX_INFO_LOAD(&info[1], PMIX_EVENT_HDLR_FIRST, &is_true, PMIX_BOOL);
rc = PMIx_Register_event_handler(&code, 1, info, 2, parallel_region_OMP_cb, NULL, NULL);
if (rc < 0)
fprintf(stderr, "%s: Failed to register event handler for OpenMP region entrance\n",
__func__);
PMIX_INFO_FREE(info, 2);
//<EG END ID="omp_thread">
printf("Registered OpenMP event handler for OpenMP parallel region entered\n");
return rc;
}
static int mpi_handler(void)
{
pmix_info_t *info;
int rc;
printf("Entered %s\n", __func__);
//<EG BEGIN ID="mpi_thread">
pmix_status_t code = PMIX_OPENMP_PARALLEL_ENTERED;
PMIX_INFO_CREATE(info, 2);
PMIX_INFO_LOAD(&info[0], PMIX_EVENT_HDLR_NAME, "MPI-Thread", PMIX_STRING);
PMIX_INFO_LOAD(&info[1], PMIX_EVENT_HDLR_AFTER, "OpenMP-Master", PMIX_STRING);
rc = PMIx_Register_event_handler(&code, 1, info, 2, parallel_region_MPI_cb, NULL, NULL);
if (rc < 0)
fprintf(stderr, "%s: Failed to register event handler for OpenMP region entrance\n",
__func__);
PMIX_INFO_FREE(info, 2);
//<EG END ID="mpi_thread">
printf("Registered MPI event handler for OpenMP parallel region entered\n");
return rc;
}
static void notify_complete(pmix_status_t status, void *cbdata)
{
volatile bool *flag = (volatile bool *) cbdata;
hide_unused_params(status);
*flag = true;
}
int main(int argc, char **argv)
{
//<EG BEGIN ID="declare_model">
pmix_proc_t myproc;
pmix_info_t *info;
volatile bool wearedone = false;
hide_unused_params(argc, argv);
PMIX_INFO_CREATE(info, 4);
PMIX_INFO_LOAD(&info[0], PMIX_PROGRAMMING_MODEL, "MPI", PMIX_STRING);
PMIX_INFO_LOAD(&info[1], PMIX_MODEL_LIBRARY_NAME, "FooMPI", PMIX_STRING);
PMIX_INFO_LOAD(&info[2], PMIX_MODEL_LIBRARY_VERSION, "1.0.0", PMIX_STRING);
PMIX_INFO_LOAD(&info[3], PMIX_THREADING_MODEL, "pthread", PMIX_STRING);
pmix_status_t rc = PMIx_Init(&myproc, info, 4);
PMIX_INFO_FREE(info, 4);
//<EG END ID="declare_model">
printf("Registered MPI programming model\n");
printf("Registering event handler for model declaration\n");
//<EG BEGIN ID="declare_model_cb">
pmix_status_t code = PMIX_MODEL_DECLARED;
rc = PMIx_Register_event_handler(&code, 1, NULL, 0, model_declared_cb, NULL, NULL);
//<EG END ID="declare_model_cb">
if (rc < 0) {
fprintf(stderr, "Failed to register event handler for model declaration\n");
goto fin;
}
printf("Registered event handler for model declaration\n");
openmp_handler();
mpi_handler();
printf("Notifying OpenMP parallel region about to be entered\n");
//<EG BEGIN ID="notify_event">
PMIX_INFO_CREATE(info, 1);
PMIX_INFO_LOAD(&info[0], PMIX_EVENT_NON_DEFAULT, NULL, PMIX_BOOL);
rc = PMIx_Notify_event(PMIX_OPENMP_PARALLEL_ENTERED, &myproc, PMIX_RANGE_PROC_LOCAL, info, 1,
notify_complete, (void *) &wearedone);
if (rc < 0) {
fprintf(stderr, "Failed to notify OpenMP region entered\n");
goto fin;
}
while (!wearedone) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 100000;
nanosleep(&ts, NULL);
}
fprintf(stderr, "Test completed\n");
fin:
PMIx_Finalize(NULL, 0);
//<EG END ID="notify_event">
}
|