📄 cmnargs.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2003 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. *//* OWNER=gropp *//* Allow fprintf in informational routines *//* style: allow:fprintf:8 sig:0 */#include "pmutilconf.h"#include <stdio.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#include <ctype.h>#include "pmutil.h"#include "process.h"#include "labelout.h"#include "env.h"#include "pmiserv.h"#include "cmnargs.h"/* Use the memory defintions from mpich2/src/include */#include "mpimem.h"/* ----------------------------------------------------------------------- *//* Process options *//* The process options steps loads up the processTable with entries, *//* including the hostname, for each process. If no host is specified, *//* one will be provided in a subsequent step *//* ----------------------------------------------------------------------- *//*-n num - number of processes-host hostname-arch architecture name-wdir working directory (cd to this one BEFORE running executable?)-path pathlist - use this to find the executable-soft comma separated triplets (ignore for now)-file name - implementation-defined specification file-configfile name - file containing specifications of host/program, one per line, with # as a comment indicator, e.g., the usual mpiexec input, but with ":" replaced with a newline. That is, the configfile contains lines with -soft, -n etc. In addition, to enable singleton init, mpiexec should allow -pmi_args port interface-name key pid mpiexec starts, then connects to the interface-name:port for PMI communication*//* Internal routines */static int getInt( int, int, char *[] );static int GetIntValue( const char [], int );static int ReadConfigFile( const char *, ProcessUniverse * );/*@ MPIE_Args - Process the arguments for mpiexec. Input Parameters:+ argc,argv - Argument count and vector. ProcessArg - Routine that is called with any unrecognized argument. Returns 0 if the argument is successfully handled, non-zero otherwise. - extraData - Pointer passed to 'ProcessArg' routine Output Parameter:. pUniv - The elements of the 'ProcessUniverse' structure are filled in. Notes: This routine may be called to parse the arguments for an implementation of 'mpiexec'. The 'ProcessUniverse' structure is filled in with information about each process. 'MPIE_Args' processes the arguments for 'mpiexec'. For any argument that is not recognized, it calls the 'ProcessArg' routine, which returns the number of arguments that should be skipped. The 'void * pointer' in the call to 'ProcessArg' is filled with the 'extraData' pointer. If 'ProcessArg' is null, then any unrecognized argument causes mpiexec to print a help message and exit. In most cases, this will invoke the 'MPIE_ArgsCheckForEnv' routine which will check for control of the environment variables to be provided to the created processes. In some cases, In addition the the arguments specified by the MPI standard, -np is accepted as a synonym for -n and -hostfile is allowed to specify the available hosts. The implementation understands the ':' notation to separate out different executables. Since no ordering of these arguments is implied, other than that the executable comes last, we store the values until we see an executable. The routine 'mpiexec_usage' may be called to provide usage information if this routine detects an erroneous argument specification. @*/int MPIE_Args( int argc, char *argv[], ProcessUniverse *pUniv, int (*ProcessArg)( int, char *[], void *), void *extraData ){ int i; int appnum=0; int np=-1; /* These 6 values are set by command line options */ const char *host=0; /* These are the defaults. When a program name */ const char *arch=0; /* is seen, the values in these variables are */ const char *wdir=0; /* used to initialize the ProcessState entries */ const char *path=0; /* we use np == -1 to detect both -n and -soft */ const char *soft=0; const char *exename=0; int indexOfFirstArg=-1; int curplist = 0; /* Index of current ProcessList element */ int optionArgs = 0; /* Keep track of where we got the options */ int optionCmdline = 0; ProcessApp *pApp = 0, **nextAppPtr; EnvInfo *appEnv = 0; /* FIXME: Get values from the environment first. Command line options override the environment */ /* Allocate the members of the ProcessUniverse structure */ pUniv->worlds = (ProcessWorld*) MPIU_Malloc( sizeof(ProcessWorld) ); pUniv->worlds->nApps = 0; pUniv->worlds->nProcess = 0; pUniv->worlds->nextWorld = 0; pUniv->worlds->worldNum = 0; pUniv->worlds->genv = 0; pUniv->nWorlds = 1; pUniv->giveExitInfo = 0; nextAppPtr = &(pUniv->worlds->apps); /* Pointer to set with the next app */ for (i=1; i<argc; i++) { if ( strncmp( argv[i], "-n", strlen( argv[i] ) ) == 0 || strncmp( argv[i], "-np", strlen( argv[i] ) ) == 0 ) { np = getInt( i+1, argc, argv ); optionArgs = 1; i++; } else if ( strncmp( argv[i], "-soft", 6 ) == 0 ) { if ( i+1 < argc ) soft = argv[++i]; else { mpiexec_usage( "Missing argument to -soft" ); } optionArgs = 1; } else if ( strncmp( argv[i], "-host", 6 ) == 0 ) { if ( i+1 < argc ) host = argv[++i]; else mpiexec_usage( "Missing argument to -host" ); optionArgs = 1; } else if ( strncmp( argv[i], "-arch", 6 ) == 0 ) { if ( i+1 < argc ) arch = argv[++i]; else mpiexec_usage( "Missing argument to -arch" ); optionArgs = 1; } else if ( strncmp( argv[i], "-wdir", 6 ) == 0 ) { if ( i+1 < argc ) wdir = argv[++i]; else mpiexec_usage( "Missing argument to -wdir" ); optionArgs = 1; } else if ( strncmp( argv[i], "-path", 6 ) == 0 ) { if ( i+1 < argc ) path = argv[++i]; else mpiexec_usage( "Missing argument to -path" ); optionArgs = 1; } else if ( strncmp( argv[i], "-configfile", 12 ) == 0) { if ( i+1 < argc ) { /* Ignore the other command line arguments */ ReadConfigFile( argv[++i], pUniv ); } else mpiexec_usage( "Missing argument to -configfile" ); optionCmdline = 1; } /* Here begins the MPICH2 mpiexec extension for singleton init */ else if ( strncmp( argv[i], "-pmi_args", 8 ) == 0) { if (i+4 < argc ) { pUniv->fromSingleton = 1; pUniv->portKey = MPIU_Strdup( argv[i+3] ); pUniv->singletonIfname = MPIU_Strdup( argv[i+2] ); pUniv->singletonPID = atoi(argv[i+4] ); pUniv->singletonPort = atoi(argv[i+1] ); i += 4; } else mpiexec_usage( "Missing argument to -pmi_args" ); optionArgs = 1; }/* Here begin the MPICH2 mpiexec common extensions for -usize n - Universe size -l - label stdout/err -maxtime n - set a timelimit of n seconds -exitinfo - Provide exit code and signal info if there is an abnormal exit (either non-zero, a process died on a signal, or pmi was initialized but not finalized) -stdoutbuf=type -stderrbuf=type - Control the buffering on stdout and stderr. By default, uses the default Unix choice. Does *not* control the application; the application may also need to control buffering. -channel=name - Pass a name in the environment variable MPICH_CH3CHANNEL to all processes. This is a special feature that supports the ch3 channel. In the future, we'll allow implementations of the ADI to provide some hooks for their specific mpiexec. */ else if (strcmp( argv[i], "-usize" ) == 0) { pUniv->size = getInt( i+1, argc, argv ); optionArgs = 1; i++; } else if (strcmp( argv[i], "-l" ) == 0) { IOLabelSetDefault( 1 ); optionArgs = 1; } else if (strcmp( argv[i], "-maxtime" ) == 0) { pUniv->timeout = getInt( i+1, argc, argv ); optionArgs = 1; i++; } else if (strcmp( argv[i], "-exitinfo" ) == 0) { pUniv->giveExitInfo = 1; optionArgs = 1; } else if ( strncmp( argv[i], "-stdoutbuf=", 11) == 0) { const char *cmd = argv[i] + 11; MPIE_StdioSetMode( stdout, cmd ); } else if (strncmp( argv[i], "-stderrbuf=", 11 ) == 0) { const char *cmd = argv[i] + 11; MPIE_StdioSetMode( stderr, cmd ); } else if (strncmp( argv[i], "-channel=", 9 ) == 0) { const char *channame = argv[i] + 9; char envstring[256]; MPIU_Snprintf( envstring, sizeof(envstring), "MPICH_CH3CHANNEL=%s", channame ); MPIE_Putenv( pUniv->worlds, envstring ); }/* End of the MPICH2 mpiexec common extentions */ else if (argv[i][0] != '-') { exename = argv[i]; /* if the executable name is relative to the current directory, convert it to an absolute name. FIXME: Make this optional (MPIEXEC_EXEPATH_ABSOLUTE?) */ /* We may not want to do this, if the idea is that that executable should be found in the PATH at the destionation */ /* wd = getwd( curdir ) */ /* Skip arguments until we hit either the end of the args or a : */ i++; indexOfFirstArg = i; while (i < argc && argv[i][0] != ':') i++; if (i == indexOfFirstArg) { /* There really wasn't an argument */ indexOfFirstArg = -1; } /* Create a new app and add to the app list*/ pApp = (ProcessApp*) MPIU_Malloc( sizeof(ProcessApp) ); *nextAppPtr = pApp; nextAppPtr = &(pApp->nextApp); pApp->nextApp = 0; pUniv->worlds[0].nApps++; pApp->pWorld = &pUniv->worlds[0]; if (appEnv) { /* Initialize the env items */ MPIE_EnvInitData( appEnv->envPairs, 0 ); MPIE_EnvInitData( appEnv->envNames, 1 ); } pApp->env = appEnv; appEnv = 0; pApp->pState = 0; /* Save the properties of this app */ pApp->exename = exename; pApp->arch = arch; pApp->path = path; pApp->wdir = wdir; pApp->hostname = host; if (indexOfFirstArg > 0) { pApp->args = (const char **)(argv + indexOfFirstArg); pApp->nArgs = i - indexOfFirstArg; } else { pApp->args = 0; pApp->nArgs = 0; } if (soft) { /* Set the np to 0 to indicate valid softspec */ pApp->nProcess = 0; if (np > 0) { mpiexec_usage( "-n and -soft may not be used together" ); } MPIE_ParseSoftspec( soft, &pApp->soft ); } else { if (np == -1) np = 1; pApp->nProcess = np; pApp->soft.nelm = 0; pApp->soft.tuples = 0; pUniv->worlds[0].nProcess += np; } pApp->myAppNum = appnum++; /* Now, clear all of the values for the next set */ host = arch = wdir = path = soft = exename = 0; indexOfFirstArg = -1; np = -1; } else { int incr = 0; /* Unrecognized argument. First check for environment variable controls */ incr = MPIE_ArgsCheckForEnv( argc-i, &argv[i], &pUniv->worlds[0], &appEnv ); if (incr == 0) { /* Use the callback routine to handle any unknown arguments before the program name */ if (ProcessArg) { incr = ProcessArg( argc, argv, extraData ); } } if (incr) { /* increment by one less because the for loop will also increment i */ i += (incr-1); } else { MPIU_Error_printf( "invalid mpiexec argument %s\n", argv[i] ); mpiexec_usage( NULL ); return -1; } } } /* Initialize the genv items */ if (pUniv->worlds->genv) { MPIE_EnvInitData( pUniv->worlds->genv->envPairs, 0 ); MPIE_EnvInitData( pUniv->worlds->genv->envNames, 1 ); } if (optionArgs && optionCmdline) { MPIU_Error_printf( "-configfile may not be used with other options\n" ); return -1; } return curplist;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -