root/ompi/interlib/interlib.c

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

DEFINITIONS

This source file includes following definitions.
  1. model_registration_callback
  2. model_callback
  3. ompi_interlib_declare

   1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
   2 /*
   3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2017 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2008-2012 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2009      Sun Microsystems, Inc.  All rights reserved.
  15  * Copyright (c) 2015      Research Organization for Information Science
  16  *                         and Technology (RIST). All rights reserved.
  17  * Copyright (c) 2015-2017 Intel, Inc. All rights reserved.
  18  * Copyright (c) 2017      IBM Corporation. All rights reserved.
  19  * $COPYRIGHT$
  20  *
  21  * Additional copyrights may follow
  22  *
  23  * $HEADER$
  24  */
  25 
  26 #include "ompi_config.h"
  27 
  28 #include <string.h>
  29 
  30 #include "opal/mca/pmix/pmix.h"
  31 #include "ompi/mca/rte/rte.h"
  32 #include "ompi/interlib/interlib.h"
  33 
  34 #include "mpi.h"
  35 
  36 typedef struct {
  37     int status;
  38     volatile bool active;
  39 } myreg_t;
  40 
  41 /*
  42  * errhandler id
  43  */
  44 static size_t interlibhandler_id = SIZE_MAX;
  45 
  46 
  47 static void model_registration_callback(int status,
  48                                         size_t errhandler_ref,
  49                                         void *cbdata)
  50 {
  51     myreg_t *trk = (myreg_t*)cbdata;
  52 
  53     trk->status = status;
  54     interlibhandler_id = errhandler_ref;
  55     trk->active = false;
  56 }
  57 static void model_callback(int status,
  58                            const opal_process_name_t *source,
  59                            opal_list_t *info, opal_list_t *results,
  60                            opal_pmix_notification_complete_fn_t cbfunc,
  61                            void *cbdata)
  62 {
  63     opal_value_t *val;
  64 
  65     if (NULL != getenv("OMPI_SHOW_MODEL_CALLBACK")) {
  66         /* we can ignore our own callback as we obviously
  67          * know that we are MPI */
  68         if (NULL != info) {
  69             OPAL_LIST_FOREACH(val, info, opal_value_t) {
  70                 if (0 == strcmp(val->key, OPAL_PMIX_PROGRAMMING_MODEL) &&
  71                     0 == strcmp(val->data.string, "MPI")) {
  72                     goto cback;
  73                 }
  74                 if (OPAL_STRING == val->type) {
  75                         opal_output(0, "OMPI Model Callback Key: %s Val %s", val->key, val->data.string);
  76                 }
  77             }
  78         }
  79     }
  80     /* otherwise, do something clever here */
  81 
  82   cback:
  83     /* we must NOT tell the event handler state machine that we
  84      * are the last step as that will prevent it from notifying
  85      * anyone else that might be listening for declarations */
  86     if (NULL != cbfunc) {
  87         cbfunc(OMPI_SUCCESS, NULL, NULL, NULL, cbdata);
  88     }
  89 }
  90 
  91 int ompi_interlib_declare(int threadlevel, char *version)
  92 {
  93     opal_list_t info, directives;
  94     opal_value_t *kv;
  95     myreg_t trk;
  96     int ret;
  97 
  98     /* Register an event handler for library model declarations  */
  99     trk.status = OPAL_ERROR;
 100     trk.active = true;
 101     /* give it a name so we can distinguish it */
 102     OBJ_CONSTRUCT(&directives, opal_list_t);
 103     kv = OBJ_NEW(opal_value_t);
 104     kv->key = strdup(OPAL_PMIX_EVENT_HDLR_NAME);
 105     kv->type = OPAL_STRING;
 106     kv->data.string = strdup("MPI-Model-Declarations");
 107     opal_list_append(&directives, &kv->super);
 108     /* specify the event code */
 109     OBJ_CONSTRUCT(&info, opal_list_t);
 110     kv = OBJ_NEW(opal_value_t);
 111     kv->key = strdup("status");   // the key here is irrelevant
 112     kv->type = OPAL_INT;
 113     kv->data.integer = OPAL_ERR_MODEL_DECLARED;
 114     opal_list_append(&info, &kv->super);
 115     /* we could constrain the range to proc_local - technically, this
 116      * isn't required so long as the code that generates
 117      * the event stipulates its range as proc_local. We rely
 118      * on that here */
 119     opal_pmix.register_evhandler(&info, &directives, model_callback,
 120                                  model_registration_callback,
 121                                  (void*)&trk);
 122     OMPI_LAZY_WAIT_FOR_COMPLETION(trk.active);
 123 
 124     OPAL_LIST_DESTRUCT(&directives);
 125     OPAL_LIST_DESTRUCT(&info);
 126     if (OPAL_SUCCESS != trk.status) {
 127         return trk.status;
 128     }
 129 
 130     /* declare that we are present and active */
 131     OBJ_CONSTRUCT(&info, opal_list_t);
 132     kv = OBJ_NEW(opal_value_t);
 133     kv->key = strdup(OPAL_PMIX_PROGRAMMING_MODEL);
 134     kv->type = OPAL_STRING;
 135     kv->data.string = strdup("MPI");
 136     opal_list_append(&info, &kv->super);
 137     kv = OBJ_NEW(opal_value_t);
 138     kv->key = strdup(OPAL_PMIX_MODEL_LIBRARY_NAME);
 139     kv->type = OPAL_STRING;
 140     kv->data.string = strdup("OpenMPI");
 141     opal_list_append(&info, &kv->super);
 142     kv = OBJ_NEW(opal_value_t);
 143     kv->key = strdup(OPAL_PMIX_MODEL_LIBRARY_VERSION);
 144     kv->type = OPAL_STRING;
 145     kv->data.string = strdup(version);
 146     opal_list_append(&info, &kv->super);
 147     kv = OBJ_NEW(opal_value_t);
 148     kv->key = strdup(OPAL_PMIX_THREADING_MODEL);
 149     kv->type = OPAL_STRING;
 150     if (MPI_THREAD_SINGLE == threadlevel) {
 151         kv->data.string = strdup("NONE");
 152     } else {
 153         kv->data.string = strdup("PTHREAD");
 154     }
 155     opal_list_append(&info, &kv->super);
 156     /* call pmix to initialize these values */
 157     ret = opal_pmix.init(&info);
 158     OPAL_LIST_DESTRUCT(&info);
 159     /* account for our refcount on pmix_init */
 160     opal_pmix.finalize();
 161     return ret;
 162 }

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