/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2017 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2008-2012 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved. * Copyright (c) 2015 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2015-2017 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "ompi_config.h" #include #include "opal/mca/pmix/pmix.h" #include "ompi/mca/rte/rte.h" #include "ompi/interlib/interlib.h" typedef struct { int status; volatile bool active; } myreg_t; /* * errhandler id */ static size_t interlibhandler_id = SIZE_MAX; static void model_registration_callback(int status, size_t errhandler_ref, void *cbdata) { myreg_t *trk = (myreg_t*)cbdata; trk->status = status; interlibhandler_id = errhandler_ref; trk->active = false; } static void model_callback(int status, const opal_process_name_t *source, opal_list_t *info, opal_list_t *results, opal_pmix_notification_complete_fn_t cbfunc, void *cbdata) { opal_value_t *val; /* we can ignore our own callback as we obviously * know that we are MPI */ if (NULL != info) { OPAL_LIST_FOREACH(val, info, opal_value_t) { if (OPAL_STRING == val->type) { #if 0 opal_output(0, "OMPI Model Callback Key: %s Val %s", val->key, val->data.string); #else if (0 == strcmp(val->key, OPAL_PMIX_MODEL_LIBRARY_NAME) && 0 == strcmp(val->data.string, "OpenMPI")) { goto cback; } #endif } } } /* otherwise, do something clever here */ cback: /* we must NOT tell the event handler state machine that we * are the last step as that will prevent it from notifying * anyone else that might be listening for declarations */ if (NULL != cbfunc) { cbfunc(OMPI_SUCCESS, NULL, NULL, NULL, cbdata); } } int ompi_interlib_declare(int threadlevel, char *version) { opal_list_t info, directives; opal_value_t *kv; myreg_t trk; int ret; /* Register an event handler for library model declarations */ trk.status = OPAL_ERROR; trk.active = true; /* give it a name so we can distinguish it */ OBJ_CONSTRUCT(&directives, opal_list_t); kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_EVENT_HDLR_NAME); kv->type = OPAL_STRING; kv->data.string = strdup("MPI-Model-Declarations"); opal_list_append(&directives, &kv->super); /* specify the event code */ OBJ_CONSTRUCT(&info, opal_list_t); kv = OBJ_NEW(opal_value_t); kv->key = strdup("status"); // the key here is irrelevant kv->type = OPAL_INT; kv->data.integer = OPAL_ERR_MODEL_DECLARED; opal_list_append(&info, &kv->super); /* we could constrain the range to proc_local - technically, this * isn't required so long as the code that generates * the event stipulates its range as proc_local. We rely * on that here */ opal_pmix.register_evhandler(&info, &directives, model_callback, model_registration_callback, (void*)&trk); OMPI_LAZY_WAIT_FOR_COMPLETION(trk.active); OPAL_LIST_DESTRUCT(&directives); OPAL_LIST_DESTRUCT(&info); if (OPAL_SUCCESS != trk.status) { return trk.status; } /* declare that we are present and active */ OBJ_CONSTRUCT(&info, opal_list_t); kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_PROGRAMMING_MODEL); kv->type = OPAL_STRING; kv->data.string = strdup("MPI"); opal_list_append(&info, &kv->super); kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_MODEL_LIBRARY_NAME); kv->type = OPAL_STRING; kv->data.string = strdup("OpenMPI"); opal_list_append(&info, &kv->super); kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_MODEL_LIBRARY_VERSION); kv->type = OPAL_STRING; kv->data.string = strdup(version); opal_list_append(&info, &kv->super); kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_THREADING_MODEL); kv->type = OPAL_STRING; if (MPI_THREAD_SINGLE == threadlevel) { kv->data.string = strdup("NONE"); } else { kv->data.string = strdup("PTHREAD"); } opal_list_append(&info, &kv->super); /* call pmix to initialize these values */ if (OPAL_SUCCESS != (ret = opal_pmix.init(&info))) { OPAL_LIST_DESTRUCT(&info); return ret; } OPAL_LIST_DESTRUCT(&info); return OMPI_SUCCESS; }