1
1
openmpi/opal/mca/base/mca_base_cmd_line.c
Jeff Squyres 32e71e5c6c Fix a problem where orterun itself would not receive MCA parameters
that were set on the command line.  This was techinically exactly the
way the code was designed, but it certainly violated the Law of Least
Astonishment (even to its designer ;-) ).  So now if you execute
something like this:

   mpirun -mca pls_rsh_debug 1 -np 4 hello

You'll see debugging output from the rsh pls component, as you would
expect (this was not previously the case -- the MCA pls_rsh_debug
parame would be set to 1 in the 4 spawned hello processes, but *not*
in the orterun process).

More specifically, MCA parameters will be set in the orterun process
in the following cases:

- The new command line switch "--gmca" (or "-gmca") is used,
  indicating that the MCA parameter is "global".  --gmca also means
  that that MCA parameter will be applied to all context app's.  For
  example:

      mpirun -gmca foo bar -np 1 hello : -np 2 goodbye

  The foo MCA param will be set in both the hello and goodbye
  processes.

- If there is only one context app.  For example:

      mpirun -mca pls_rsh_debug 1 -np 4 hello

  will set pls_rsh_debug to 1 in both the orterun process and the 4
  spawned hello processes.

Also added a few more comments inside orterun to document a somewhat
confusing use of a state variable in a recursive case.

This commit was SVN r6764.
2005-08-08 16:42:28 +00:00

159 строки
4.3 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* 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$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include <stdio.h>
#include <string.h>
#include "include/constants.h"
#include "opal/util/cmd_line.h"
#include "opal/util/argv.h"
#include "opal/util/opal_environ.h"
#include "mca/base/base.h"
/*
* Private variables
*/
/*
* Private functions
*/
static int process_arg(const char *param, const char *value,
char ***params, char ***values);
static void add_to_env(char **params, char **values, char ***env);
/*
* Add -mca to the possible command line options list
*/
int mca_base_cmd_line_setup(opal_cmd_line_t *cmd)
{
int ret;
ret = opal_cmd_line_make_opt3(cmd, '\0', "mca", "mca", 2,
"Pass context-specific MCA parameters; they are considered global if --gmca is not used and only one context is specified (arg0 is the parameter name; arg1 is the parameter value)");
if (OMPI_SUCCESS != ret) {
return ret;
}
ret = opal_cmd_line_make_opt3(cmd, '\0', "gmca", "gmca", 2,
"Pass global MCA parameters that are applicable to all contexts (arg0 is the parameter name; arg1 is the parameter value)");
return ret;
}
/*
* Look for and handle any -mca options on the command line
*/
int mca_base_cmd_line_process_args(opal_cmd_line_t *cmd,
char ***context_env, char ***global_env)
{
int i, num_insts;
char **params;
char **values;
/* If no relevant parameters were given, just return */
if (!opal_cmd_line_is_taken(cmd, "mca") &&
!opal_cmd_line_is_taken(cmd, "gmca")) {
return OMPI_SUCCESS;
}
/* Handle app context-specific parameters */
num_insts = opal_cmd_line_get_ninsts(cmd, "mca");
params = values = NULL;
for (i = 0; i < num_insts; ++i) {
process_arg(opal_cmd_line_get_param(cmd, "mca", i, 0),
opal_cmd_line_get_param(cmd, "mca", i, 1),
&params, &values);
}
if (NULL != params) {
add_to_env(params, values, context_env);
opal_argv_free(params);
opal_argv_free(values);
}
/* Handle global parameters */
num_insts = opal_cmd_line_get_ninsts(cmd, "gmca");
params = values = NULL;
for (i = 0; i < num_insts; ++i) {
process_arg(opal_cmd_line_get_param(cmd, "gmca", i, 0),
opal_cmd_line_get_param(cmd, "gmca", i, 1),
&params, &values);
}
if (NULL != params) {
add_to_env(params, values, global_env);
opal_argv_free(params);
opal_argv_free(values);
}
/* All done */
return OMPI_SUCCESS;
}
/*
* Process a single MCA argument.
*/
int static process_arg(const char *param, const char *value,
char ***params, char ***values)
{
int i;
char *new_str;
/* Look to see if we've already got an -mca argument for the same
param. Check against the list of MCA param's that we've
already saved arguments for. */
for (i = 0; NULL != *params && NULL != (*params)[i]; ++i) {
if (0 == strcmp(param, (*params)[i])) {
asprintf(&new_str, "%s,%s", (*values)[i], value);
free((*values)[i]);
(*values)[i] = new_str;
return OMPI_SUCCESS;
}
}
/* If we didn't already have an value for the same param, save
this one away */
opal_argv_append_nosize(params, param);
opal_argv_append_nosize(values, value);
return OMPI_SUCCESS;
}
static void add_to_env(char **params, char **values, char ***env)
{
int i;
char *name;
/* Loop through all the args that we've gotten and make env
vars of the form OMPI_MCA_*=value. */
for (i = 0; NULL != params && NULL != params[i]; ++i) {
name = mca_base_param_environ_variable(params[i], NULL, NULL);
opal_setenv(name, values[i], true, env);
free(name);
}
}