1
1
openmpi/oshmem/mca/memheap/base/memheap_base_select.c

252 строки
8.7 KiB
C

/*
* Copyright (c) 2013 Mellanox Technologies, Inc.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "oshmem_config.h"
#include "opal/util/argv.h"
#include "opal/util/output.h"
#include "orte/util/show_help.h"
#include "opal/mca/mca.h"
#include "opal/mca/base/base.h"
#include "opal/mca/base/mca_base_component_repository.h"
#include "oshmem/mca/memheap/memheap.h"
#include "oshmem/mca/memheap/base/base.h"
#include "orte/mca/errmgr/errmgr.h"
#include "opal/runtime/opal.h"
mca_memheap_base_module_t mca_memheap;
/**
* Function for weeding out memheap components that shouldn't be executed.
* Implementation inspired by btl/base.
*
* Call the init function on all available components to find out if
* they want to run. Select all components that don't fail. Failing
* components will be closed and unloaded. The selected modules will
* be pointed to by mca_memheap_base_module_t.
*/
static memheap_context_t* __memheap_create(void);
/**
* Choose to init one component with the highest priority.
* If the include list if it is not empty choose a component that appear in the list.
* O/W choose the highest priority component not in the exclude list.
* Include and exclude lists may be given in the shmem launcher command line.
*/
int mca_memheap_base_select()
{
int priority = 0;
int max_priority = 0;
mca_base_component_list_item_t *cli, *next;
mca_memheap_base_component_t *component = NULL;
mca_memheap_base_component_t *max_priority_component = NULL;
mca_memheap_base_module_t *module = NULL;
memheap_context_t *context = NULL;
char** include = opal_argv_split(mca_memheap_base_include, ',');
char** exclude = opal_argv_split(mca_memheap_base_exclude, ',');
context = __memheap_create();
if (!context) {
return OSHMEM_ERROR;
}
OPAL_LIST_FOREACH_SAFE(cli, next, &oshmem_memheap_base_framework.framework_components, mca_base_component_list_item_t) {
component = (mca_memheap_base_component_t *) cli->cli_component;
/* Verify if the component is in the include or the exclude list. */
/* If there is an include list - item must be in the list to be included */
if (NULL != include) {
char** argv = include;
bool found = false;
while (argv && *argv) {
if (strcmp(component->memheap_version.mca_component_name, *argv)
== 0) {
found = true;
break;
}
argv++;
}
/* If not in the list do not choose this component */
if (found == false) {
continue;
}
/* Otherwise - check the exclude list to see if this item has been specifically excluded */
} else if (NULL != exclude) {
char** argv = exclude;
bool found = false;
while (argv && *argv) {
if (strcmp(component->memheap_version.mca_component_name, *argv)
== 0) {
found = true;
break;
}
argv++;
}
if (found == true) {
continue;
}
}
/* Verify that the component has an init function */
if (NULL == component->memheap_init) {
MEMHEAP_VERBOSE(10,
"select: no init function; for component %s. No component selected",
component->memheap_version.mca_component_name);
} else {
MEMHEAP_VERBOSE(5,
"select: component %s size : user %d private: %d",
component->memheap_version.mca_component_name, (int)context->user_size, (int)context->private_size);
/* Init the component in order to get its priority */
module = component->memheap_init(context, &priority);
/* If the component didn't initialize, remove it from the opened list, remove it from the component repository and return an error */
if (NULL == module) {
MEMHEAP_VERBOSE(10,
"select: init of component %s returned failure",
component->memheap_version.mca_component_name);
opal_list_remove_item(&oshmem_memheap_base_framework.framework_components, &cli->super);
mca_base_component_close((mca_base_component_t *) component,
oshmem_memheap_base_framework.framework_output);
}
/* Calculate memheap size in case it was not set during component initialization */
module->memheap_size = context->user_size;
}
/* Init max priority component */
if (NULL == max_priority_component) {
max_priority_component = component;
mca_memheap_base_module_initialized = module;
max_priority = priority;
}
/* Update max priority component if current component has greater priority */
if (priority > max_priority) {
max_priority = priority;
max_priority_component = component;
mca_memheap_base_module_initialized = module;
}
}
opal_argv_free(include);
opal_argv_free(exclude);
/* Verify that a component was selected */
if (NULL == max_priority_component) {
MEMHEAP_VERBOSE(10, "select: no component selected");
return OSHMEM_ERROR;
}
/* Verify that some module was initialized */
if (NULL == mca_memheap_base_module_initialized) {
orte_show_help("help-shmem-mca.txt",
"find-available:none-found",
true,
"memheap");
orte_errmgr.abort(1, NULL );
}
MEMHEAP_VERBOSE(10,
"SELECTED %s component %s",
max_priority_component->memheap_version.mca_type_name, max_priority_component->memheap_version.mca_component_name);
setenv(SHMEM_HEAP_TYPE,
max_priority_component->memheap_version.mca_component_name,
1);
mca_memheap = *mca_memheap_base_module_initialized;
return OSHMEM_SUCCESS;
}
static size_t memheap_size(void)
{
char *p;
unsigned long long factor;
int idx;
unsigned long long size;
p = getenv(SHMEM_HEAP_SIZE);
if (!p)
return SIZE_IN_MEGA_BYTES(DEFAULT_SYMMETRIC_HEAP_SIZE);
idx = strlen(p) - 1;
if (p[idx] == 'k' || p[idx] == 'K') {
factor = 1024;
} else if (p[idx] == 'm' || p[idx] == 'M') {
factor = 1024 * 1024;
} else if (p[idx] == 'g' || p[idx] == 'G') {
factor = 1024 * 1024 * 1024;
} else if (p[idx] == 't' || p[idx] == 'T') {
factor = 1024UL * 1024UL * 1024UL * 1024UL;
} else
factor = 1;
size = atoll(p);
if (size == 0) {
MEMHEAP_ERROR("Incorrect symmetric heap size %s. Using default heap size %d M\n",
p, DEFAULT_SYMMETRIC_HEAP_SIZE);
return SIZE_IN_MEGA_BYTES(DEFAULT_SYMMETRIC_HEAP_SIZE);
}
return (size_t) memheap_align(size * factor);
}
static memheap_context_t* __memheap_create(void)
{
int rc = OSHMEM_SUCCESS;
static memheap_context_t context;
size_t user_size;
user_size = memheap_size();
if (user_size < MEMHEAP_BASE_MIN_SIZE) {
MEMHEAP_ERROR("Requested memheap size is less than minimal meamheap size (%llu < %llu)",
(unsigned long long)user_size, MEMHEAP_BASE_MIN_SIZE);
return NULL ;
}
/* Inititialize symmetric area */
if (OSHMEM_SUCCESS == rc) {
rc = mca_memheap_base_alloc_init(&mca_memheap_base_map,
user_size + MEMHEAP_BASE_PRIVATE_SIZE);
}
/* Inititialize static/global variables area */
if (OSHMEM_SUCCESS == rc) {
rc = mca_memheap_base_static_init(&mca_memheap_base_map);
}
/* Memory Registration */
if (OSHMEM_SUCCESS == rc) {
rc = mca_memheap_base_reg(&mca_memheap_base_map);
}
/* Init OOB channel */
if (OSHMEM_SUCCESS == rc) {
rc = memheap_oob_init(&mca_memheap_base_map);
}
if (OSHMEM_SUCCESS == rc) {
context.user_size = user_size;
context.private_size = MEMHEAP_BASE_PRIVATE_SIZE;
context.user_base_addr =
(void*) ((unsigned char*) mca_memheap_base_map.mem_segs[HEAP_SEG_INDEX].start
+ 0);
context.private_base_addr =
(void*) ((unsigned char*) mca_memheap_base_map.mem_segs[HEAP_SEG_INDEX].start
+ context.user_size);
}
return ((OSHMEM_SUCCESS == rc) ? &context : NULL );
}