1
1
openmpi/opal/mca/db/base/db_base_fns.c
Ralph Castain d565a76814 Do some cleanup of the way we handle modex data. Identify data that needs to be shared with peers in my job vs data that needs to be shared with non-peers - no point in sharing extra data. When we share data with some process(es) from another job, we cannot know in advance what info they have or lack, so we have to share everything just in case. This limits the optimization we can do for things like comm_spawn.
Create a new required key in the OMPI layer for retrieving a "node id" from the database. ALL RTE'S MUST DEFINE THIS KEY. This allows us to compute locality in the MPI layer, which is necessary when we do things like intercomm_create.

cmr:v1.7.4:reviewer=rhc:subject=Cleanup handling of modex data

This commit was SVN r29274.
2013-09-27 00:37:49 +00:00

316 строки
9.1 KiB
C

/*
* Copyright (c) 2012-2013 Los Alamos National Security, Inc. All rights reserved.
* Copyright (c) 2013 Intel Inc. All rights reserved
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "opal_config.h"
#include "opal/constants.h"
#include "opal_stdint.h"
#include "opal/mca/mca.h"
#include "opal/util/error.h"
#include "opal/util/output.h"
#include "opal/mca/base/base.h"
#include "opal/dss/dss_types.h"
#include "opal/mca/db/base/base.h"
void opal_db_base_set_id(const opal_identifier_t *proc)
{
/* to protect alignment, copy the data across */
memcpy(&opal_db_base.my_id, proc, sizeof(opal_identifier_t));
opal_db_base.id_set = true;
}
int opal_db_base_store(const opal_identifier_t *proc,
opal_scope_t scope,
const char *key, const void *object,
opal_data_type_t type)
{
bool did_op;
opal_db_active_module_t *mod;
int rc;
if (!opal_db_base.id_set) {
return OPAL_ERR_FATAL;
}
/* cycle thru the active modules until one agrees to perform the op */
did_op = false;
OPAL_LIST_FOREACH(mod, &opal_db_base.store_order, opal_db_active_module_t) {
if (NULL == mod->module->store) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->store(proc, scope, key, object, type))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
OPAL_ERROR_LOG(rc);
return rc;
}
}
/* if we get here without performing the operation, that's an error */
if (!did_op) {
OPAL_ERROR_LOG(OPAL_ERROR);
return OPAL_ERROR;
}
return OPAL_SUCCESS;
}
int opal_db_base_store_pointer(const opal_identifier_t *proc,
opal_value_t *kv)
{
bool did_op;
opal_db_active_module_t *mod;
int rc;
if (!opal_db_base.id_set) {
return OPAL_ERR_FATAL;
}
/* cycle thru the active modules until one agrees to perform the op */
did_op = false;
OPAL_LIST_FOREACH(mod, &opal_db_base.store_order, opal_db_active_module_t) {
if (NULL == mod->module->store_pointer) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->store_pointer(proc, kv))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
OPAL_ERROR_LOG(rc);
return rc;
}
}
/* if we get here without performing the operation, that's an error */
if (!did_op) {
OPAL_ERROR_LOG(OPAL_ERROR);
return OPAL_ERROR;
}
return OPAL_SUCCESS;
}
void opal_db_base_commit(const opal_identifier_t *proc)
{
opal_db_active_module_t *mod;
/* cycle thru the active modules giving each a chance to perform the op */
OPAL_LIST_FOREACH(mod, &opal_db_base.store_order, opal_db_active_module_t) {
if (NULL == mod->module->commit) {
continue;
}
mod->module->commit(proc);
}
}
int opal_db_base_fetch(const opal_identifier_t *proc,
const char *key, void **data,
opal_data_type_t type)
{
bool did_op;
opal_db_active_module_t *mod;
int rc, i;
if (!opal_db_base.id_set) {
return OPAL_ERR_FATAL;
}
/* cycle thru the active modules until one agrees to perform the op */
did_op = false;
/* we cycle thru the list of modules twice - this allows us to check
* a local store first, then attempt to obtain the data from an
* external store that puts it in the local store
*/
for(i=0; i < 2 && !did_op; i++) {
OPAL_LIST_FOREACH(mod, &opal_db_base.fetch_order, opal_db_active_module_t) {
if (NULL == mod->module->fetch) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->fetch(proc, key, data, type))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
/* if we get here without performing the operation, that's an error */
if (!did_op) {
return OPAL_ERR_DATA_VALUE_NOT_FOUND;
}
return OPAL_SUCCESS;
}
int opal_db_base_fetch_pointer(const opal_identifier_t *proc,
const char *key,
void **data, opal_data_type_t type)
{
bool did_op;
opal_db_active_module_t *mod;
int rc, i;
if (!opal_db_base.id_set) {
return OPAL_ERR_FATAL;
}
/* cycle thru the active modules until one agrees to perform the op */
did_op = false;
/* we cycle thru the list of modules twice - this allows us to check
* a local store first, then attempt to obtain the data from an
* external store that puts it in the local store
*/
for(i=0; i < 2 && !did_op; i++) {
OPAL_LIST_FOREACH(mod, &opal_db_base.fetch_order, opal_db_active_module_t) {
if (NULL == mod->module->fetch_pointer) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->fetch_pointer(proc, key, data, type))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
/* if we get here without performing the operation, that's an error */
if (!did_op) {
return OPAL_ERR_DATA_VALUE_NOT_FOUND;
}
return OPAL_SUCCESS;
}
int opal_db_base_fetch_multiple(const opal_identifier_t *proc,
opal_scope_t scope,
const char *key,
opal_list_t *kvs)
{
bool did_op;
opal_db_active_module_t *mod;
int rc;
if (!opal_db_base.id_set) {
return OPAL_ERR_FATAL;
}
/* cycle thru the active modules until one agrees to perform the op */
did_op = false;
OPAL_LIST_FOREACH(mod, &opal_db_base.fetch_order, opal_db_active_module_t) {
if (NULL == mod->module->fetch_multiple) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->fetch_multiple(proc, scope, key, kvs))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
/* if we get here without performing the operation, that's an error */
if (!did_op) {
return OPAL_ERR_DATA_VALUE_NOT_FOUND;
}
return OPAL_SUCCESS;
}
int opal_db_base_remove_data(const opal_identifier_t *proc,
const char *key)
{
bool did_op;
opal_db_active_module_t *mod;
int rc;
/* cycle thru the actiove modules until one agrees to perform the op */
did_op = false;
OPAL_LIST_FOREACH(mod, &opal_db_base.store_order, opal_db_active_module_t) {
if (NULL == mod->module->remove) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->remove(proc, key))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
OPAL_ERROR_LOG(rc);
return rc;
}
}
/* if we get here without performing the operation, that's an error */
if (!did_op) {
OPAL_ERROR_LOG(OPAL_ERROR);
return OPAL_ERROR;
}
return OPAL_SUCCESS;
}
int opal_db_base_add_log(const char *table,
const opal_value_t *kvs, int nkvs)
{
bool did_op;
opal_db_active_module_t *mod;
int rc;
/* cycle thru the active modules until one agrees to perform the op */
did_op = false;
OPAL_LIST_FOREACH(mod, &opal_db_base.store_order, opal_db_active_module_t) {
if (NULL == mod->module->add_log) {
continue;
}
if (OPAL_SUCCESS == (rc = mod->module->add_log(table, kvs, nkvs))) {
did_op = true;
break;
}
/* modules return "next option" if they didn't perform
* the operation - anything else is a true error.
*/
if (OPAL_ERR_TAKE_NEXT_OPTION != rc) {
/* don't error log it here */
return rc;
}
}
/* if we get here without performing the operation, let the caller know */
if (!did_op) {
/* don't error log it here */
return OPAL_ERROR;
}
return OPAL_SUCCESS;
}