static bool test2(void)
{
int i, j;
char **argv = NULL;
int argc;
char *a[] = { "aaa", "bbb", "ccc", NULL };
char *b[4];
/* Similar test to above, but ensure that opal_argv_add is actually
*copying* the string by value, not by reference. So copy the a
array into b, and then opal_argv_add() from b. After that,
scribble in the first character of the b[] string that we just
added, and compare all entries in a to argv -- they should be
identical (even though b is now corrupted). */
for (i = 0; a[i] != NULL; ++i) {
b[i] = strdup(a[i]);
}
b[i] = NULL;
for (i = 0; b[i] != NULL; ++i) {
if (opal_argv_append(&argc, &argv, b[i]) != OPAL_SUCCESS) {
return false;
}
++b[i][0];
for (j = 0; j <= i; ++j) {
if (strcmp(argv[j], a[j]) != 0) {
return false;
}
}
if (NULL != argv[i + 1]) {
return false;
}
if (argc != i + 1) {
return false;
}
}
opal_argv_free(argv);
for (i = 0; b[i] != NULL; ++i) {
free(b[i]);
}
return true;
}
static bool test6(void)
{
char *a = "the quick brown fox jumped over the lazy dog a_really_long_argument_to_force_a_long_copy_zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
char **b;
char *c;
/* split the string above and then join it -- the joined version
should be just like the original */
b = opal_argv_split(a, ' ');
c = opal_argv_join(b, ' ');
if (strcmp(a, c) != 0) {
return false;
}
/* All done */
free(c);
opal_argv_free(b);
return true;
}
开发者ID:00datman,项目名称:ompi,代码行数:22,代码来源:opal_argv.c
示例6: test1
static bool test1(void)
{
char *a[] = { "argv1", "argv2", "argv3", NULL };
char **argv = NULL;
int i, j, argc = 28;
/* Test basic functionality. Start with a NULL argv and add the
contents of the a array.
Set argc to be an initiall bogus number -- opal_argv_add() should
reset it back to zero after the first iteration.
After adding the a[i], ensure that argv[0 - (i-1)] are the same
as a[0 - (i-1)].
Also ensure that a[i + 1] == NULL and that argc is the proper
value. */
for (i = 0; a[i] != NULL; ++i) {
if (opal_argv_append(&argc, &argv, a[i]) != OPAL_SUCCESS) {
return false;
}
for (j = 0; j <= i; ++j) {
if (strcmp(argv[j], a[j]) != 0) {
return false;
}
}
if (NULL != argv[i + 1]) {
return false;
}
if (argc != i + 1) {
return false;
}
}
opal_argv_free(argv);
return true;
}
static void
options_data_expand(const char *value)
{
/* make space for the new set of args */
parse_options_idx++;
options_data = (struct options_data_t *) realloc(options_data, sizeof(struct options_data_t) * (parse_options_idx + 1));
options_data_init(&(options_data[parse_options_idx]));
/* if there are values, this is not the default case.
Otherwise, it's the default case... */
if (NULL != value && 0 != strcmp(value, "")) {
char **values = opal_argv_split(value, ';');
opal_argv_insert(&(options_data[parse_options_idx].compiler_args),
opal_argv_count(options_data[parse_options_idx].compiler_args),
values);
opal_argv_free(values);
} else {
free(options_data[parse_options_idx].compiler_args);
options_data[parse_options_idx].compiler_args = NULL;
/* this is a default */
default_data_idx = parse_options_idx;
}
}
static int allocate(opal_list_t *nodes)
{
char **nodelist;
orte_node_t *node;
int i, num_nodes;
/* get the list of allocated nodes */
if ((num_nodes = lsb_getalloc(&nodelist)) < 0) {
orte_show_help("help-ras-lsf.txt", "nodelist-failed", true);
return ORTE_ERR_NOT_AVAILABLE;
}
node = NULL;
/* step through the list */
for (i = 0; i < num_nodes; i++) {
/* is this a repeat of the current node? */
if (NULL != node && 0 == strcmp(nodelist[i], node->name)) {
/* it is a repeat - just bump the slot count */
++node->slots;
continue;
}
/* not a repeat - create a node entry for it */
node = OBJ_NEW(orte_node_t);
node->name = strdup(nodelist[i]);
node->slots_inuse = 0;
node->slots_max = 0;
node->slots = 1;
opal_list_append(nodes, &node->super);
}
/* release the nodelist from lsf */
opal_argv_free(nodelist);
return ORTE_SUCCESS;
}
int opal_os_dirpath_create(const char *path, const mode_t mode)
{
struct stat buf;
char **parts, *tmp;
int i, len;
int ret;
if (NULL == path) { /* protect ourselves from errors */
return(OPAL_ERROR);
}
if (0 == (ret = stat(path, &buf))) { /* already exists */
if (mode == (mode & buf.st_mode)) { /* has correct mode */
return(OPAL_SUCCESS);
}
if (0 == (ret = chmod(path, (buf.st_mode | mode)))) { /* successfully change mode */
return(OPAL_SUCCESS);
}
opal_output(0,
"opal_os_dirpath_create: "
"Error: Unable to create directory (%s), unable to set the correct mode [%d]\n",
path, ret);
return(OPAL_ERROR); /* can't set correct mode */
}
/* quick -- try to make directory */
if (0 == mkdir(path, mode)) {
return(OPAL_SUCCESS);
}
/* didnt work, so now have to build our way down the tree */
/* Split the requested path up into its individual parts */
parts = opal_argv_split(path, path_sep[0]);
/* Ensure to allocate enough space for tmp: the strlen of the
incoming path + 1 (for \0) */
tmp = (char*)malloc(strlen(path) + 1);
tmp[0] = '\0';
/* Iterate through all the subdirectory names in the path,
building up a directory name. Check to see if that dirname
exists. If it doesn't, create it. */
len = opal_argv_count(parts);
for (i = 0; i < len; ++i) {
if (i == 0) {
/* If in POSIX-land, ensure that we never end a directory
name with path_sep */
if ('/' == path[0]) {
strcat(tmp, path_sep);
}
strcat(tmp, parts[i]);
}
/* If it's not the first part, ensure that there's a
preceeding path_sep and then append this part */
else {
if (path_sep[0] != tmp[strlen(tmp) - 1]) {
strcat(tmp, path_sep);
}
strcat(tmp, parts[i]);
}
/* Now that we finally have the name to check, check it.
Create it if it doesn't exist. */
ret = mkdir(tmp, mode);
if ((0 > ret && EEXIST != errno) || 0 != stat(tmp, &buf)) {
opal_output(0,
"opal_os_dirpath_create: "
"Error: Unable to create the sub-directory (%s) of (%s), mkdir failed [%d]\n",
tmp, path, ret);
opal_argv_free(parts);
free(tmp);
return OPAL_ERROR;
}
}
/* All done */
opal_argv_free(parts);
free(tmp);
return OPAL_SUCCESS;
}
static int rte_init(void)
{
int ret;
char *error = NULL;
char **hosts = NULL;
/* run the prolog */
if (ORTE_SUCCESS != (ret = orte_ess_base_std_prolog())) {
error = "orte_ess_base_std_prolog";
goto error;
}
/* Start by getting a unique name */
tm_set_name();
/* if I am a daemon, complete my setup using the
* default procedure
*/
if (ORTE_PROC_IS_DAEMON) {
if (NULL != orte_node_regex) {
/* extract the nodes */
if (ORTE_SUCCESS != (ret =
orte_regex_extract_node_names(orte_node_regex, &hosts)) ||
NULL == hosts) {
error = "orte_regex_extract_node_names";
goto error;
}
}
if (ORTE_SUCCESS != (ret = orte_ess_base_orted_setup(hosts))) {
ORTE_ERROR_LOG(ret);
error = "orte_ess_base_orted_setup";
goto error;
}
opal_argv_free(hosts);
return ORTE_SUCCESS;
}
if (ORTE_PROC_IS_TOOL) {
/* otherwise, if I am a tool proc, use that procedure */
if (ORTE_SUCCESS != (ret = orte_ess_base_tool_setup())) {
ORTE_ERROR_LOG(ret);
error = "orte_ess_base_tool_setup";
goto error;
}
return ORTE_SUCCESS;
}
/* no other options are supported! */
error = "ess_error";
ret = ORTE_ERROR;
error:
if (ORTE_ERR_SILENT != ret && !orte_report_silent_errors) {
orte_show_help("help-orte-runtime.txt",
"orte_init:startup:internal-failure",
true, error, ORTE_ERROR_NAME(ret), ret);
}
return ret;
}
/* we can only enter this routine if no other allocation
* was found, so we only need to know that finding any
* relative node syntax should generate an immediate error
*/
int orte_util_add_dash_host_nodes(opal_list_t *nodes,
bool *override_oversubscribed,
char ** host_argv)
{
opal_list_item_t* item;
orte_std_cntr_t i, j, k;
int rc;
char **mapped_nodes = NULL, **mini_map;
orte_node_t *node;
/* Accumulate all of the host name mappings */
for (j = 0; j < opal_argv_count(host_argv); ++j) {
mini_map = opal_argv_split(host_argv[j], ',');
if (mapped_nodes == NULL) {
mapped_nodes = mini_map;
} else {
for (k = 0; NULL != mini_map[k]; ++k) {
rc = opal_argv_append_nosize(&mapped_nodes,
mini_map[k]);
if (OPAL_SUCCESS != rc) {
goto cleanup;
}
}
opal_argv_free(mini_map);
}
}
/* Did we find anything? If not, then do nothing */
if (NULL == mapped_nodes) {
return ORTE_SUCCESS;
}
/* go through the names found and
add them to the host list. If they're not unique, then
bump the slots count for each duplicate */
for (i = 0; NULL != mapped_nodes[i]; ++i) {
/* if the specified node contains a relative node syntax,
* this is an error
*/
if ('+' == mapped_nodes[i][0]) {
orte_show_help("help-dash-host.txt", "dash-host:relative-syntax",
true, mapped_nodes[i]);
rc = ORTE_ERR_SILENT;
goto cleanup;
}
/* see if the node is already on the list */
for (item = opal_list_get_first(nodes);
item != opal_list_get_end(nodes);
item = opal_list_get_next(item)) {
node = (orte_node_t*) item;
if (0 == strcmp(node->name, mapped_nodes[i]) ||
(0 == strcmp(node->name, orte_process_info.nodename) &&
(0 == strcmp(mapped_nodes[i], "localhost") || opal_ifislocal(mapped_nodes[i])))) {
++node->slots;
break;
}
}
/* If we didn't find it, add it to the list */
if (item == opal_list_get_end(nodes)) {
node = OBJ_NEW(orte_node_t);
if (NULL == node) {
return ORTE_ERR_OUT_OF_RESOURCE;
}
/* check to see if this is a local name */
if (0 == strcmp(mapped_nodes[i], "localhost") ||
opal_ifislocal(mapped_nodes[i])) {
/* it is local, so use the local nodename to avoid
* later confusion
*/
if (orte_show_resolved_nodenames &&
0 != strcmp(mapped_nodes[i], orte_process_info.nodename)) {
/* add to list of aliases for this node - only add if unique */
opal_argv_append_unique_nosize(&node->alias, mapped_nodes[i]);
}
node->name = strdup(orte_process_info.nodename);
} else {
/* not local - use the given name */
node->name = strdup(mapped_nodes[i]);
}
node->state = ORTE_NODE_STATE_UP;
node->slots_inuse = 0;
node->slots_max = 0;
node->slots = 1;
/* indicate that ORTE should override any oversubscribed conditions
* based on local hardware limits since the user (a) might not have
* provided us any info on the #slots for a node, and (b) the user
* might have been wrong! If we don't check the number of local physical
* processors, then we could be too aggressive on our sched_yield setting
* and cause performance problems.
*/
*override_oversubscribed = true;
//.........这里部分代码省略.........
static int mca_btl_tcp_component_register(void)
{
char* message;
/* register TCP component parameters */
mca_btl_tcp_param_register_uint("links", NULL, 1, OPAL_INFO_LVL_4, &mca_btl_tcp_component.tcp_num_links);
mca_btl_tcp_param_register_string("if_include", "Comma-delimited list of devices and/or CIDR notation of networks to use for MPI communication (e.g., \"eth0,192.168.0.0/16\"). Mutually exclusive with btl_tcp_if_exclude.", "", OPAL_INFO_LVL_1, &mca_btl_tcp_component.tcp_if_include);
mca_btl_tcp_param_register_string("if_exclude", "Comma-delimited list of devices and/or CIDR notation of networks to NOT use for MPI communication -- all devices not matching these specifications will be used (e.g., \"eth0,192.168.0.0/16\"). If set to a non-default value, it is mutually exclusive with btl_tcp_if_include.",
"127.0.0.1/8,sppp",
OPAL_INFO_LVL_1, &mca_btl_tcp_component.tcp_if_exclude);
mca_btl_tcp_param_register_int ("free_list_num", NULL, 8, OPAL_INFO_LVL_5, &mca_btl_tcp_component.tcp_free_list_num);
mca_btl_tcp_param_register_int ("free_list_max", NULL, -1, OPAL_INFO_LVL_5, &mca_btl_tcp_component.tcp_free_list_max);
mca_btl_tcp_param_register_int ("free_list_inc", NULL, 32, OPAL_INFO_LVL_5, &mca_btl_tcp_component.tcp_free_list_inc);
mca_btl_tcp_param_register_int ("sndbuf", NULL, 128*1024, OPAL_INFO_LVL_4, &mca_btl_tcp_component.tcp_sndbuf);
mca_btl_tcp_param_register_int ("rcvbuf", NULL, 128*1024, OPAL_INFO_LVL_4, &mca_btl_tcp_component.tcp_rcvbuf);
mca_btl_tcp_param_register_int ("endpoint_cache",
"The size of the internal cache for each TCP connection. This cache is"
" used to reduce the number of syscalls, by replacing them with memcpy."
" Every read will read the expected data plus the amount of the"
" endpoint_cache", 30*1024, OPAL_INFO_LVL_4, &mca_btl_tcp_component.tcp_endpoint_cache);
mca_btl_tcp_param_register_int ("use_nagle", "Whether to use Nagle's algorithm or not (using Nagle's algorithm may increase short message latency)", 0, OPAL_INFO_LVL_4, &mca_btl_tcp_component.tcp_not_use_nodelay);
mca_btl_tcp_param_register_int( "port_min_v4",
"The minimum port where the TCP BTL will try to bind (default 1024)",
1024, OPAL_INFO_LVL_2, &mca_btl_tcp_component.tcp_port_min);
asprintf( &message,
"The number of ports where the TCP BTL will try to bind (default %d)."
" This parameter together with the port min, define a range of ports"
" where Open MPI will open sockets.",
(0x1 << 16) - mca_btl_tcp_component.tcp_port_min - 1 );
mca_btl_tcp_param_register_int( "port_range_v4", message,
(0x1 << 16) - mca_btl_tcp_component.tcp_port_min - 1,
OPAL_INFO_LVL_2, &mca_btl_tcp_component.tcp_port_range);
free(message);
#if OPAL_WANT_IPV6
mca_btl_tcp_param_register_int( "port_min_v6",
"The minimum port where the TCP BTL will try to bind (default 1024)", 1024,
OPAL_INFO_LVL_2, & mca_btl_tcp_component.tcp6_port_min );
asprintf( &message,
"The number of ports where the TCP BTL will try to bind (default %d)."
" This parameter together with the port min, define a range of ports"
" where Open MPI will open sockets.",
(0x1 << 16) - mca_btl_tcp_component.tcp6_port_min - 1 );
mca_btl_tcp_param_register_int( "port_range_v6", message,
(0x1 << 16) - mca_btl_tcp_component.tcp6_port_min - 1,
OPAL_INFO_LVL_2, &mca_btl_tcp_component.tcp6_port_range );
free(message);
#endif
mca_btl_tcp_module.super.btl_exclusivity = MCA_BTL_EXCLUSIVITY_LOW + 100;
mca_btl_tcp_module.super.btl_eager_limit = 64*1024;
mca_btl_tcp_module.super.btl_rndv_eager_limit = 64*1024;
mca_btl_tcp_module.super.btl_max_send_size = 128*1024;
mca_btl_tcp_module.super.btl_rdma_pipeline_send_length = 128*1024;
mca_btl_tcp_module.super.btl_rdma_pipeline_frag_size = INT_MAX;
mca_btl_tcp_module.super.btl_min_rdma_pipeline_size = 0;
mca_btl_tcp_module.super.btl_flags = MCA_BTL_FLAGS_PUT |
MCA_BTL_FLAGS_SEND_INPLACE |
MCA_BTL_FLAGS_NEED_CSUM |
MCA_BTL_FLAGS_NEED_ACK |
MCA_BTL_FLAGS_HETEROGENEOUS_RDMA;
mca_btl_tcp_module.super.btl_seg_size = sizeof (mca_btl_base_segment_t);
mca_btl_tcp_module.super.btl_bandwidth = 100;
mca_btl_tcp_module.super.btl_latency = 100;
mca_btl_base_param_register(&mca_btl_tcp_component.super.btl_version,
&mca_btl_tcp_module.super);
mca_btl_tcp_param_register_int ("disable_family", NULL, 0, OPAL_INFO_LVL_2, &mca_btl_tcp_component.tcp_disable_family);
/* Register a list of interfaces to use in sequence */
mca_btl_tcp_param_register_string("if_seq",
"If specified, a comma-delimited list of TCP interfaces. Interfaces will be assigned, one to each MPI process, in a round-robin fashion on each server. For example, if the list is \"eth0,eth1\" and four MPI processes are run on a single server, then local ranks 0 and 2 will use eth0 and local ranks 1 and 3 will use eth1.", NULL, OPAL_INFO_LVL_9, &mca_btl_tcp_if_seq_string);
mca_btl_tcp_component.tcp_if_seq = NULL;
if (NULL != mca_btl_tcp_if_seq_string && '\0' != *mca_btl_tcp_if_seq_string) {
char **argv = opal_argv_split(mca_btl_tcp_if_seq_string, ',');
if (NULL != argv && '\0' != *(argv[0])) {
int if_index, rc, count;
ompi_node_rank_t node_rank;
char name[256];
node_rank = ompi_process_info.my_node_rank;
/* Now that we've got that local rank, take the
corresponding entry from the tcp_if_seq list (wrapping
if necessary) */
count = opal_argv_count(argv);
mca_btl_tcp_component.tcp_if_seq =
strdup(argv[node_rank % count]);
opal_argv_free(argv);
/* Double check that the selected interface actually exists */
for (if_index = opal_ifbegin(); if_index >= 0;
if_index = opal_ifnext(if_index)){
if (OPAL_SUCCESS !=
(rc = opal_ifindextoname(if_index, name, sizeof(name)))) {
return rc;
//.........这里部分代码省略.........
/*
* Register MCA parameters
*/
int ompi_btl_openib_connect_base_register(void)
{
int i, j, save;
char **temp = NULL, *string = NULL, *all_cpc_names = NULL;
char *cpc_include = NULL, *cpc_exclude = NULL;
/* Make an MCA parameter to select which connect module to use */
for (i = 0; NULL != all[i]; ++i) {
/* The CPC name "empty" is reserved for "fake" CPC modules */
if (0 != strcmp(all[i]->cbc_name, "empty")) {
opal_argv_append_nosize(&temp, all[i]->cbc_name);
}
}
all_cpc_names = opal_argv_join(temp, ',');
opal_argv_free(temp);
asprintf(&string,
"Method used to select OpenFabrics connections (valid values: %s)",
all_cpc_names);
mca_base_param_reg_string(&mca_btl_openib_component.super.btl_version,
"cpc_include", string, false, false,
NULL, &cpc_include);
free(string);
asprintf(&string,
"Method used to exclude OpenFabrics connections (valid values: %s)",
all_cpc_names);
mca_base_param_reg_string(&mca_btl_openib_component.super.btl_version,
"cpc_exclude", string, false, false,
NULL, &cpc_exclude);
free(string);
/* Parse the if_[in|ex]clude paramters to come up with a list of
CPCs that are available */
available = calloc(1, sizeof(all));
/* If we have an "include" list, then find all those CPCs and put
them in available[] */
if (NULL != cpc_include) {
mca_btl_openib_component.cpc_explicitly_defined = true;
temp = opal_argv_split(cpc_include, ',');
for (save = j = 0; NULL != temp[j]; ++j) {
for (i = 0; NULL != all[i]; ++i) {
if (0 == strcmp(temp[j], all[i]->cbc_name)) {
opal_output(-1, "include: saving %s", all[i]->cbc_name);
available[save++] = all[i];
++num_available;
break;
}
}
if (NULL == all[i]) {
orte_show_help("help-mpi-btl-openib-cpc-base.txt",
"cpc name not found", true,
"include", orte_process_info.nodename,
"include", cpc_include, temp[j],
all_cpc_names);
opal_argv_free(temp);
free(all_cpc_names);
return OMPI_ERR_NOT_FOUND;
}
}
opal_argv_free(temp);
}
/* Otherwise, if we have an "exclude" list, take all the CPCs that
are not in that list and put them in available[] */
else if (NULL != cpc_exclude) {
mca_btl_openib_component.cpc_explicitly_defined = true;
temp = opal_argv_split(cpc_exclude, ',');
/* First: error check -- ensure that all the names are valid */
for (j = 0; NULL != temp[j]; ++j) {
for (i = 0; NULL != all[i]; ++i) {
if (0 == strcmp(temp[j], all[i]->cbc_name)) {
break;
}
}
if (NULL == all[i]) {
orte_show_help("help-mpi-btl-openib-cpc-base.txt",
"cpc name not found", true,
"exclude", orte_process_info.nodename,
"exclude", cpc_exclude, temp[j],
all_cpc_names);
opal_argv_free(temp);
free(all_cpc_names);
return OMPI_ERR_NOT_FOUND;
}
}
/* Now do the exclude */
for (save = i = 0; NULL != all[i]; ++i) {
for (j = 0; NULL != temp[j]; ++j) {
if (0 == strcmp(temp[j], all[i]->cbc_name)) {
break;
}
}
if (NULL == temp[j]) {
//.........这里部分代码省略.........
/*
* Scan all the files in a directory (or path) and invoke a callback
* on each one.
*/
static int dlopen_foreachfile(const char *search_path,
int (*func)(const char *filename, void *data),
void *data)
{
int ret;
DIR *dp = NULL;
char **dirs = NULL;
char **good_files = NULL;
dirs = opal_argv_split(search_path, OPAL_ENV_SEP);
for (int i = 0; NULL != dirs && NULL != dirs[i]; ++i) {
dp = opendir(dirs[i]);
if (NULL == dp) {
ret = OPAL_ERR_IN_ERRNO;
goto error;
}
struct dirent *de;
while (NULL != (de = readdir(dp))) {
/* Make the absolute path name */
char *abs_name = NULL;
asprintf(&abs_name, "%s/%s", dirs[i], de->d_name);
if (NULL == abs_name) {
ret = OPAL_ERR_IN_ERRNO;
goto error;
}
/* Stat the file */
struct stat buf;
if (stat(abs_name, &buf) < 0) {
free(abs_name);
ret = OPAL_ERR_IN_ERRNO;
goto error;
}
/* Skip if not a file */
if (!S_ISREG(buf.st_mode)) {
free(abs_name);
continue;
}
/* Find the suffix */
char *ptr = strrchr(abs_name, '.');
if (NULL != ptr) {
/* Skip libtool files */
if (strcmp(ptr, ".la") == 0 ||
strcmp(ptr, ".lo") == 0) {
continue;
}
*ptr = '\0';
}
/* Have we already found this file? Or already found a
file with the same basename (but different suffix)? */
bool found = false;
for (int j = 0; NULL != good_files &&
NULL != good_files[j]; ++j) {
if (strcmp(good_files[j], abs_name) == 0) {
found = true;
break;
}
}
if (!found) {
opal_argv_append_nosize(&good_files, abs_name);
}
free(abs_name);
}
closedir(dp);
}
dp = NULL;
/* Invoke the callback on all the found files */
if (NULL != good_files) {
for (int i = 0; NULL != good_files[i]; ++i) {
ret = func(good_files[i], data);
if (OPAL_SUCCESS != ret) {
goto error;
}
}
}
ret = OPAL_SUCCESS;
error:
if (NULL != dp) {
closedir(dp);
}
if (NULL != dirs) {
opal_argv_free(dirs);
}
if (NULL != good_files) {
//.........这里部分代码省略.........
请发表评论