Example #1
0
void printFatalErrorHeader(FILE *fp, const char *title,
                           const char *func, const char *file, int line)
{
    // In case ProgramInfo is not initialized and there is an issue with the
    // initialization, fall back to "GROMACS".
    const char *programName = "GROMACS";
    try
    {
        programName = getProgramContext().displayName();
    }
    catch (const std::exception &)
    {
    }

    std::fprintf(fp, "\n-------------------------------------------------------\n");
    std::fprintf(fp, "Program:     %s, version %s\n", programName, gmx_version());
    if (file != nullptr)
    {
        std::fprintf(fp, "Source file: %s (line %d)\n",
                     Path::stripSourcePrefix(file), line);
    }
    if (func != nullptr)
    {
        std::fprintf(fp, "Function:    %s\n", func);
    }
    if (gmx_node_num() > 1)
    {
        std::fprintf(fp, "MPI rank:    %d (out of %d)\n", gmx_node_rank(), gmx_node_num());
    }
    std::fprintf(fp, "\n");
    std::fprintf(fp, "%s:\n", title);
}
Example #2
0
void gmx_abort(int errorno)
{
    const char *programName = "GROMACS";
    try
    {
        programName = gmx::getProgramContext().displayName();
    }
    catch (const std::exception &)
    {
    }
    const int nnodes   = gmx_node_num();
    const int noderank = gmx_node_rank();
    if (nnodes > 1)
    {
        std::fprintf(stderr, "Halting parallel program %s on rank %d out of %d\n",
                     programName, noderank, nnodes);
    }
    else
    {
        std::fprintf(stderr, "Halting program %s\n", programName);
    }

    MPI_Abort(MPI_COMM_WORLD, errorno);
    std::exit(errorno);
}
Example #3
0
void Init_Umbrella_Communicate(t_commrec *cr)
{
  int i;
  // int i_mpi;
  char fnm[256];
  FILE *fpin;

  fpin=fopen("umbrella_params","r");

  if (fpin!=NULL) {
    fprintf(stderr,"Found umbrella parameter file\n");
    // MPI_Comm_rank(MPI_COMM_WORLD,&i_mpi);
    i=fscanf(fpin,"freq_out %d",&udata.freq);
    // if (i==0 || i_mpi!=0) {
    if (i==0 || gmx_node_rank()!=0) {
      udata.freq=-1;
      udata.fp=NULL;
    } else {
      i=0;
      udata.fp=NULL;
      do {
        if (udata.fp) {
          fclose(udata.fp);
        }
        i+=1;
        sprintf(fnm,"Qumbrella.part%04d.dat",i);
      } while (udata.fp=fopen(fnm,"r"));
      fprintf(stderr,"Writing umbrella coordinates to %s\n",fnm);
      udata.fp=fopen(fnm,"w");
      if (udata.fp==NULL) {
        fprintf(stderr,"Warning, outfile %s open failed\n",fnm);
      }
    }

    udata.k_Q=0;
    udata.Q_0=0;
    udata.Q_init=0;
    udata.Q_steps=1;
    udata.cr=cr;
    i=fscanf(fpin,"%f %f %f %f",&udata.k_Q,&udata.Q_0,&udata.Q_init,&udata.Q_steps);
    if (i<4) {
      fprintf(stderr,"Warning, umbrella parameters read incorrectly\n");
    }

    fclose(fpin);
  } else {
    udata.k_Q=0;
    udata.Q_0=0;
    udata.Q_init=0;
    udata.Q_steps=1;
    udata.cr=cr;
    udata.freq=-1;
    udata.fp=NULL;
  }
}
Example #4
0
int
MdrunTestFixture::callGrompp()
{
#ifdef GMX_LIB_MPI
    // When compiled with external MPI, only call one instance of the
    // grompp function
    if (0 != gmx_node_rank())
    {
        return 0;
    }
#endif
    return callGromppOnThisRank();
}
Example #5
0
int
SimulationRunner::callGrompp()
{
    int returnValue = 0;
#if GMX_LIB_MPI
    // When compiled with external MPI, we're trying to run mdrun with
    // MPI, but we need to make sure that we only do grompp on one
    // rank
    if (0 == gmx_node_rank())
#endif
    {
        returnValue = callGromppOnThisRank();
    }
#if GMX_LIB_MPI
    // Make sure rank zero has written the .tpr file before other
    // ranks try to read it. Thread-MPI and serial do this just fine
    // on their own.
    MPI_Barrier(MPI_COMM_WORLD);
#endif
    return returnValue;
}
Example #6
0
static void quit_gmx(const char *msg)
{
  if (!fatal_errno) {
    if (log_file) 
      fprintf(log_file,"%s\n",msg);
    fprintf(stderr,"%s\n",msg);
    /* we set it to no-zero because if this function is called, something 
       has gone wrong */
    fatal_errno=255;
  }
  else {
    if (fatal_errno != -1)
      errno=fatal_errno;
    perror(msg);
  }
  
  if (gmx_parallel_env) {
    int  nnodes;
    int  noderank;
    
    nnodes   = gmx_node_num();
    noderank = gmx_node_rank();
    
    if (nnodes > 1) 
      fprintf(stderr,"Error on node %d, will try to stop all the nodes\n",
	      noderank);
    gmx_abort(noderank,nnodes,-1);
  } else {
    if (debug)
      fflush(debug);
    if (bDebug) {
      fprintf(stderr,"dump core (y/n):"); 
      fflush(stderr);
      if (toupper(getc(stdin))!='N') 
	(void) abort(); 
    }
  }

  exit(fatal_errno);
}
Example #7
0
static void quit_gmx(const char *msg)
{
  if (!fatal_errno) {
    if (log_file) 
      fprintf(log_file,"%s\n",msg);
    fprintf(stderr,"%s\n",msg);
  }
  else {
    if (fatal_errno != -1)
      errno=fatal_errno;
    perror(msg);
  }
  
  if (gmx_parallel_env) {
    int  nnodes;
    int  noderank;
    
    nnodes   = gmx_node_num();
    noderank = gmx_node_rank();
    
    if (nnodes > 1) 
      fprintf(stderr,"Error on node %d, will try to stop all the nodes\n",
	      noderank);
    gmx_abort(noderank,nnodes,-1);
  } else {
    if (debug)
      fflush(debug);
    if (bDebug) {
      fprintf(stderr,"dump core (y/n):"); 
      fflush(stderr);
      if (toupper(getc(stdin))!='N') 
	(void) abort(); 
    }
  }

  exit(-1);
}
Example #8
0
gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags,
                           int nfile, t_filenm fnm[], int npargs, t_pargs *pa,
                           int ndesc, const char **desc,
                           int nbugs, const char **bugs,
                           gmx_output_env_t **oenv)
{
    /* This array should match the order of the enum in oenv.h */
    const char *const xvg_formats[] = { "xmgrace", "xmgr", "none" };

    // Handle the flags argument, which is a bit field
    // The FF macro returns whether or not the bit is set
#define FF(arg) ((Flags & arg) == arg)

    try
    {
        double                          tbegin        = 0.0, tend = 0.0, tdelta = 0.0;
        bool                            bBeginTimeSet = false, bEndTimeSet = false, bDtSet = false;
        bool                            bView         = false;
        int                             xvgFormat     = 0;
        gmx::OptionsAdapter             adapter(*argc, argv);
        gmx::Options                    options(NULL, NULL);
        gmx::OptionsBehaviorCollection  behaviors(&options);
        gmx::FileNameOptionManager      fileOptManager;

        fileOptManager.disableInputOptionChecking(
                FF(PCA_NOT_READ_NODE) || FF(PCA_DISABLE_INPUT_FILE_CHECKING));
        options.addManager(&fileOptManager);

        if (FF(PCA_CAN_SET_DEFFNM))
        {
            fileOptManager.addDefaultFileNameOption(&options, "deffnm");
        }
        if (FF(PCA_CAN_BEGIN))
        {
            options.addOption(
                    gmx::DoubleOption("b")
                        .store(&tbegin).storeIsSet(&bBeginTimeSet).timeValue()
                        .description("First frame (%t) to read from trajectory"));
        }
        if (FF(PCA_CAN_END))
        {
            options.addOption(
                    gmx::DoubleOption("e")
                        .store(&tend).storeIsSet(&bEndTimeSet).timeValue()
                        .description("Last frame (%t) to read from trajectory"));
        }
        if (FF(PCA_CAN_DT))
        {
            options.addOption(
                    gmx::DoubleOption("dt")
                        .store(&tdelta).storeIsSet(&bDtSet).timeValue()
                        .description("Only use frame when t MOD dt = first time (%t)"));
        }
        gmx::TimeUnit  timeUnit = gmx::TimeUnit_Default;
        if (FF(PCA_TIME_UNIT))
        {
            std::shared_ptr<gmx::TimeUnitBehavior> timeUnitBehavior(
                    new gmx::TimeUnitBehavior());
            timeUnitBehavior->setTimeUnitStore(&timeUnit);
            timeUnitBehavior->setTimeUnitFromEnvironment();
            timeUnitBehavior->addTimeUnitOption(&options, "tu");
            behaviors.addBehavior(timeUnitBehavior);
        }
        if (FF(PCA_CAN_VIEW))
        {
            options.addOption(
                    gmx::BooleanOption("w").store(&bView)
                        .description("View output [REF].xvg[ref], [REF].xpm[ref], "
                                     "[REF].eps[ref] and [REF].pdb[ref] files"));
        }

        bool bXvgr = false;
        for (int i = 0; i < nfile; i++)
        {
            bXvgr = bXvgr || (fnm[i].ftp == efXVG);
        }
        xvgFormat = gmx::getDefaultXvgFormat(xvg_formats);
        if (bXvgr)
        {
            options.addOption(
                    gmx::EnumIntOption("xvg").enumValue(xvg_formats)
                        .store(&xvgFormat)
                        .description("xvg plot formatting"));
        }

        /* Now append the program specific arguments */
        for (int i = 0; i < nfile; i++)
        {
            adapter.filenmToOptions(&options, &fnm[i]);
        }
        for (int i = 0; i < npargs; i++)
        {
            adapter.pargsToOptions(&options, &pa[i]);
        }

        const gmx::CommandLineHelpContext *context =
            gmx::GlobalCommandLineHelpContext::get();
        if (context != NULL)
        {
            GMX_RELEASE_ASSERT(gmx_node_rank() == 0,
                               "Help output should be handled higher up and "
                               "only get called only on the master rank");
            gmx::CommandLineHelpWriter(options)
                .setHelpText(gmx::constArrayRefFromArray<const char *>(desc, ndesc))
                .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs))
                .writeHelp(*context);
            return FALSE;
        }

        /* Now parse all the command-line options */
        gmx::CommandLineParser(&options).skipUnknown(FF(PCA_NOEXIT_ON_ARGS))
            .parse(argc, argv);
        behaviors.optionsFinishing();
        options.finish();

        /* set program name, command line, and default values for output options */
        output_env_init(oenv, gmx::getProgramContext(),
                        (time_unit_t)(timeUnit + 1), bView,
                        (xvg_format_t)(xvgFormat + 1), 0);

        /* Extract Time info from arguments */
        if (bBeginTimeSet)
        {
            setTimeValue(TBEGIN, tbegin);
        }
        if (bEndTimeSet)
        {
            setTimeValue(TEND, tend);
        }
        if (bDtSet)
        {
            setTimeValue(TDELTA, tdelta);
        }

        adapter.copyValues(!FF(PCA_NOT_READ_NODE));

        return TRUE;
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
#undef FF
}
Example #9
0
//! \cond internal
void initTestUtils(const char *dataPath, const char *tempPath, bool usesMpi,
                   bool usesHardwareDetection, int *argc, char ***argv)
{
#if !defined NDEBUG &&                                                  \
    !((defined __clang__ || (defined(__GNUC__) && !defined(__ICC) && __GNUC__ == 7)) \
    && defined __OPTIMIZE__)
    gmx_feenableexcept();
#endif
    const CommandLineProgramContext &context = initForCommandLine(argc, argv);
    try
    {
        if (!usesMpi && gmx_node_num() > 1)
        {
            // We cannot continue, since some tests might be using
            // MPI_COMM_WORLD, which could deadlock if we would only
            // continue with the master rank here.
            if (gmx_node_rank() == 0)
            {
                fprintf(stderr, "NOTE: You are running %s on %d MPI ranks, "
                        "but it is does not contain MPI-enabled tests. "
                        "The test will now exit.\n",
                        context.programName(), gmx_node_num());
            }
            finalizeForCommandLine();
            std::exit(1);
        }
        if (usesHardwareDetection)
        {
            callAddGlobalTestEnvironment();
        }
        g_testContext = gmx::compat::make_unique<TestProgramContext>(context);
        setProgramContext(g_testContext.get());
        // Use the default finder that does not respect GMXLIB, since the tests
        // generally can only get confused by a different set of data files.
        setLibraryFileFinder(nullptr);
        ::testing::InitGoogleMock(argc, *argv);
        if (dataPath != nullptr)
        {
            TestFileManager::setInputDataDirectory(
                    Path::join(CMAKE_SOURCE_DIR, dataPath));
        }
        if (tempPath != nullptr)
        {
            TestFileManager::setGlobalOutputTempDirectory(tempPath);
        }
        bool        bHelp = false;
        std::string sourceRoot;
        Options     options;
        // TODO: A single option that accepts multiple names would be nicer.
        // Also, we recognize -help, but GTest doesn't, which leads to a bit
        // unintuitive behavior.
        options.addOption(BooleanOption("h").store(&bHelp)
                              .description("Print GROMACS-specific unit test options"));
        options.addOption(BooleanOption("help").store(&bHelp).hidden());
        options.addOption(BooleanOption("?").store(&bHelp).hidden());
        // TODO: Make this into a FileNameOption (or a DirectoryNameOption).
        options.addOption(StringOption("src-root").store(&sourceRoot)
                              .description("Override source tree location (for data files)"));
        // The potential MPI test event listener must be initialized first,
        // because it should appear in the start of the event listener list,
        // before other event listeners that may generate test failures
        // (currently, such an event listener is used by the reference data
        // framework).
        if (usesMpi)
        {
            initMPIOutput();
        }
        // TODO: Consider removing this option from test binaries that do not need it.
        initReferenceData(&options);
        initTestOptions(&options);
        try
        {
            CommandLineParser(&options).parse(argc, *argv);
            options.finish();
        }
        catch (const UserInputError &)
        {
            printHelp(options);
            throw;
        }
        if (bHelp)
        {
            printHelp(options);
        }
        if (!sourceRoot.empty())
        {
            g_testContext->overrideSourceRoot(sourceRoot);
            TestFileManager::setInputDataDirectory(
                    Path::join(sourceRoot, dataPath));
        }
    }
    catch (const std::exception &ex)
    {
        printFatalErrorMessage(stderr, ex);
        int retcode = processExceptionAtExitForCommandLine(ex);
        // TODO: It could be nice to destroy things in proper order such that
        // g_testContext would not contain hanging references at this point,
        // but in practice that should not matter.
        g_testContext.reset();
        std::exit(retcode);
    }
}
Example #10
0
int
SimulationRunner::callMdrun(const CommandLine &callerRef)
{
    /* Conforming to style guide by not passing a non-const reference
       to this function. Passing a non-const reference might make it
       easier to write code that incorrectly re-uses callerRef after
       the call to this function. */

    CommandLine caller(callerRef);
    caller.addOption("-s", tprFileName_);

    caller.addOption("-g", logFileName_);
    caller.addOption("-e", edrFileName_);
    caller.addOption("-o", fullPrecisionTrajectoryFileName_);
    caller.addOption("-x", reducedPrecisionTrajectoryFileName_);

    caller.addOption("-deffnm", fixture_->fileManager_.getTemporaryFilePath("state"));

    if (nsteps_ > -2)
    {
        caller.addOption("-nsteps", nsteps_);
    }

#if GMX_MPI
#  if GMX_GPU != GMX_GPU_NONE
#    if GMX_THREAD_MPI
    int         numGpusNeeded = g_numThreads;
#    else   /* Must be real MPI */
    int         numGpusNeeded = gmx_node_num();
#    endif
    std::string gpuIdString(numGpusNeeded, '0');
    caller.addOption("-gpu_id", gpuIdString.c_str());
#  endif
#endif

#if GMX_THREAD_MPI
    caller.addOption("-ntmpi", g_numThreads);
#endif

#if GMX_OPENMP
    caller.addOption("-ntomp", g_numOpenMPThreads);
#endif

#if GMX_GPU != GMX_GPU_NONE
    /* TODO Ideally, with real MPI, we could call
     * gmx_collect_hardware_mpi() here and find out how many nodes
     * mdrun will run on. For now, we assume that we're running on one
     * node regardless of the number of ranks, because that's true in
     * Jenkins and for most developers running the tests. */
    int numberOfNodes = 1;
#if GMX_THREAD_MPI
    /* Can't use gmx_node_num() because it is only valid after spawn of thread-MPI threads */
    int numberOfRanks = g_numThreads;
#elif GMX_LIB_MPI
    int numberOfRanks = gmx_node_num();
#else
    int numberOfRanks = 1;
#endif
    if (numberOfRanks > numberOfNodes && !gmx_multiple_gpu_per_node_supported())
    {
        if (gmx_node_rank() == 0)
        {
            fprintf(stderr, "GROMACS in this build configuration cannot run on more than one GPU per node,\n so with %d ranks and %d nodes, this test will disable GPU support", numberOfRanks, numberOfNodes);
        }
        caller.addOption("-nb", "cpu");
    }
#endif
    return gmx_mdrun(caller.argc(), caller.argv());
}
gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags,
                           int nfile, t_filenm fnm[], int npargs, t_pargs *pa,
                           int ndesc, const char **desc,
                           int nbugs, const char **bugs,
                           output_env_t *oenv)
{
    /* This array should match the order of the enum in oenv.h */
    const char *xvg_format[] = { NULL, "xmgrace", "xmgr", "none", NULL };
    /* This array should match the order of the enum in oenv.h */
    const char *time_units[] = {
        NULL, "fs", "ps", "ns", "us", "ms", "s",
        NULL
    };
    int         nicelevel = 0, debug_level = 0;
    char       *deffnm    = NULL;
    real        tbegin    = 0, tend = 0, tdelta = 0;
    gmx_bool    bView     = FALSE;

    t_pargs    *all_pa = NULL;

    t_pargs     nice_pa   = {
        "-nice", FALSE, etINT,   {&nicelevel},
        "Set the nicelevel"
    };
    t_pargs     deffnm_pa = {
        "-deffnm", FALSE, etSTR, {&deffnm},
        "Set the default filename for all file options"
    };
    t_pargs     begin_pa  = {
        "-b",    FALSE, etTIME,  {&tbegin},
        "First frame (%t) to read from trajectory"
    };
    t_pargs     end_pa    = {
        "-e",    FALSE, etTIME,  {&tend},
        "Last frame (%t) to read from trajectory"
    };
    t_pargs     dt_pa     = {
        "-dt",   FALSE, etTIME,  {&tdelta},
        "Only use frame when t MOD dt = first time (%t)"
    };
    t_pargs     view_pa   = {
        "-w",    FALSE, etBOOL,  {&bView},
        "View output [TT].xvg[tt], [TT].xpm[tt], [TT].eps[tt] and [TT].pdb[tt] files"
    };
    t_pargs     xvg_pa    = {
        "-xvg",  FALSE, etENUM,  {xvg_format},
        "xvg plot formatting"
    };
    t_pargs     time_pa   = {
        "-tu",   FALSE, etENUM,  {time_units},
        "Time unit"
    };
    /* Maximum number of extra arguments */
#define EXTRA_PA 16

    t_pargs  pca_pa[] = {
        { "-debug", FALSE, etINT, {&debug_level},
          "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
    };
#define NPCA_PA asize(pca_pa)
    gmx_bool bXvgr;
    int      i, j, k, npall, max_pa;

    // Handle the flags argument, which is a bit field
    // The FF macro returns whether or not the bit is set
#define FF(arg) ((Flags & arg) == arg)

    /* Check for double arguments */
    for (i = 1; (i < *argc); i++)
    {
        if (argv[i] && (strlen(argv[i]) > 1) && (!std::isdigit(argv[i][1])))
        {
            for (j = i+1; (j < *argc); j++)
            {
                if ( (argv[i][0] == '-') && (argv[j][0] == '-') &&
                     (strcmp(argv[i], argv[j]) == 0) )
                {
                    if (FF(PCA_NOEXIT_ON_ARGS))
                    {
                        fprintf(stderr, "Double command line argument %s\n",
                                argv[i]);
                    }
                    else
                    {
                        gmx_fatal(FARGS, "Double command line argument %s\n",
                                  argv[i]);
                    }
                }
            }
        }
    }
    debug_gmx();

    /* Check ALL the flags ... */
    max_pa = NPCA_PA + EXTRA_PA + npargs+1;
    snew(all_pa, max_pa);

    for (i = npall = 0; (i < static_cast<int>(NPCA_PA)); i++)
    {
        npall = add_parg(npall, all_pa, &(pca_pa[i]));
    }

    if (FF(PCA_BE_NICE))
    {
        nicelevel = 19;
    }
    npall = add_parg(npall, all_pa, &nice_pa);

    if (FF(PCA_CAN_SET_DEFFNM))
    {
        npall = add_parg(npall, all_pa, &deffnm_pa);
    }
    if (FF(PCA_CAN_BEGIN))
    {
        npall = add_parg(npall, all_pa, &begin_pa);
    }
    if (FF(PCA_CAN_END))
    {
        npall = add_parg(npall, all_pa, &end_pa);
    }
    if (FF(PCA_CAN_DT))
    {
        npall = add_parg(npall, all_pa, &dt_pa);
    }
    if (FF(PCA_TIME_UNIT))
    {
        npall = add_parg(npall, all_pa, &time_pa);
    }
    if (FF(PCA_CAN_VIEW))
    {
        npall = add_parg(npall, all_pa, &view_pa);
    }

    bXvgr = FALSE;
    for (i = 0; (i < nfile); i++)
    {
        bXvgr = bXvgr ||  (fnm[i].ftp == efXVG);
    }
    if (bXvgr)
    {
        npall = add_parg(npall, all_pa, &xvg_pa);
    }

    /* Now append the program specific arguments */
    for (i = 0; (i < npargs); i++)
    {
        npall = add_parg(npall, all_pa, &(pa[i]));
    }

    /* set etENUM options to default */
    for (i = 0; (i < npall); i++)
    {
        if (all_pa[i].type == etENUM)
        {
            all_pa[i].u.c[0] = all_pa[i].u.c[1];
        }
    }
    set_default_time_unit(time_units, FF(PCA_TIME_UNIT));
    set_default_xvg_format(xvg_format);

    /* Now parse all the command-line options */
    get_pargs(argc, argv, npall, all_pa);

    /* set program name, command line, and default values for output options */
    output_env_init(oenv, gmx::getProgramContext(), (time_unit_t)nenum(time_units), bView,
                    (xvg_format_t)nenum(xvg_format), 0, debug_level);

    /* Parse the file args */
    parse_file_args(argc, argv, nfile, fnm, deffnm, !FF(PCA_NOT_READ_NODE));

    /* Open the debug file */
    if (debug_level > 0)
    {
        char buf[256];

        if (gmx_mpi_initialized())
        {
            sprintf(buf, "%s%d.debug", output_env_get_short_program_name(*oenv),
                    gmx_node_rank());
        }
        else
        {
            sprintf(buf, "%s.debug", output_env_get_short_program_name(*oenv));
        }

        init_debug(debug_level, buf);
        fprintf(stderr, "Opening debug file %s (src code file %s, line %d)\n",
                buf, __FILE__, __LINE__);
    }

    /* Now copy the results back... */
    for (i = 0, k = npall-npargs; (i < npargs); i++, k++)
    {
        memcpy(&(pa[i]), &(all_pa[k]), (size_t)sizeof(pa[i]));
    }

    bool bExit = false;
    try
    {
        const gmx::CommandLineHelpContext *context =
            gmx::GlobalCommandLineHelpContext::get();
        bExit = (context != NULL);
        if (context != NULL && !(FF(PCA_QUIET)))
        {
            gmx::Options options(NULL, NULL);
            options.setDescription(gmx::constArrayRefFromArray(desc, ndesc));
            for (i = 0; i < nfile; i++)
            {
                gmx::filenmToOptions(&options, &fnm[i]);
            }
            for (i = 0; i < npall; i++)
            {
                gmx::pargsToOptions(&options, &all_pa[i]);
            }
            gmx::CommandLineHelpWriter(options)
                .setShowDescriptions(true)
                .setTimeUnitString(output_env_get_time_unit(*oenv))
                .setKnownIssues(gmx::constArrayRefFromArray(bugs, nbugs))
                .writeHelp(*context);
        }
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;

    /* Set the nice level */
#if defined(HAVE_UNISTD_H) && !defined(__MINGW32__)
#ifndef GMX_NO_NICE
    /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
    if (nicelevel != 0 && !bExit)
    {
        static gmx_bool            nice_set   = FALSE; /* only set it once */
        static tMPI_Thread_mutex_t init_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
        tMPI_Thread_mutex_lock(&init_mutex);
        if (!nice_set)
        {
            if (nice(nicelevel) == -1)
            {
                /* Do nothing, but use the return value to avoid warnings. */
            }
            nice_set = TRUE;
        }
        tMPI_Thread_mutex_unlock(&init_mutex);
    }
#endif
#endif

    /* convert time options, must be done after printing! */

    for (i = 0; i < npall; i++)
    {
        if (all_pa[i].type == etTIME && all_pa[i].bSet)
        {
            *all_pa[i].u.r *= output_env_get_time_invfactor(*oenv);
        }
    }

    /* Extract Time info from arguments */
    if (FF(PCA_CAN_BEGIN) && opt2parg_bSet("-b", npall, all_pa))
    {
        setTimeValue(TBEGIN, opt2parg_real("-b", npall, all_pa));
    }

    if (FF(PCA_CAN_END) && opt2parg_bSet("-e", npall, all_pa))
    {
        setTimeValue(TEND, opt2parg_real("-e", npall, all_pa));
    }

    if (FF(PCA_CAN_DT) && opt2parg_bSet("-dt", npall, all_pa))
    {
        setTimeValue(TDELTA, opt2parg_real("-dt", npall, all_pa));
    }

    /* clear memory */
    sfree(all_pa);

    if (!FF(PCA_NOEXIT_ON_ARGS))
    {
        if (*argc > 1)
        {
            gmx_cmd(argv[1]);
        }
    }
    return !bExit;
#undef FF
}
int CommandLineModuleManager::run(int argc, char *argv[])
{
    CommandLineModuleInterface    *module;
    const bool                     bMaster = (gmx_node_rank() == 0);
    bool                           bQuiet  = impl_->bQuiet_ || !bMaster;
    CommandLineCommonOptionsHolder optionsHolder;
    try
    {
        optionsHolder.initOptions();
        module = impl_->processCommonOptions(&optionsHolder, &argc, &argv);
    }
    catch (const std::exception &)
    {
        bQuiet |= optionsHolder.shouldBeQuiet();
        if (!bQuiet)
        {
            printBinaryInformation(stderr, impl_->programContext_,
                                   optionsHolder.binaryInfoSettings());
        }
        throw;
    }
    bQuiet |= optionsHolder.shouldBeQuiet();
    if (!bQuiet)
    {
        FILE *out = optionsHolder.startupInfoFile();
        printBinaryInformation(out, impl_->programContext_,
                               optionsHolder.binaryInfoSettings());
        fprintf(out, "\n");
    }
    if (module == NULL)
    {
        return 0;
    }

    CommandLineModuleSettings settings;
    module->init(&settings);
    optionsHolder.adjustFromSettings(settings);

    gmx_set_max_backup_count(optionsHolder.shouldBackup() ? -1 : 0);

    // Open the debug file.
    if (optionsHolder.debugLevel() > 0)
    {
        std::string filename(impl_->programContext_.programName());
        if (gmx_node_num() > 1)
        {
            filename.append(formatString("%d", gmx_node_rank()));
        }
        filename.append(".debug");

        fprintf(stderr, "Will write debug log file: %s\n", filename.c_str());
        gmx_init_debug(optionsHolder.debugLevel(), filename.c_str());
    }
    // Set the nice level unless disabled in the configuration.
    if (optionsHolder.niceLevel() != 0)
    {
        static bool bNiceSet = false; // Only set it once.
        if (!bNiceSet)
        {
            // TODO: Diagnostic if this fails and the user explicitly requested it.
            gmx_set_nice(optionsHolder.niceLevel());
            bNiceSet = true;
        }
    }
    if (optionsHolder.enableFPExceptions())
    {
        //TODO: currently it is always enabled for mdrun (verlet) and tests.
        gmx_feenableexcept();
    }

    int rc = 0;
    if (!(module == impl_->helpModule_ && !bMaster))
    {
        rc = module->run(argc, argv);
    }
    if (!bQuiet)
    {
        gmx_thanx(stderr);
    }
    return rc;
}
Example #13
0
void parse_common_args(int *argc,char *argv[],unsigned long Flags,
		       int nfile,t_filenm fnm[],int npargs,t_pargs *pa,
		       int ndesc,char **desc,int nbugs,char **bugs)
{
  static bool bHelp=FALSE,bHidden=FALSE,bQuiet=FALSE;
  static char *manstr[]      = { NULL, "no", "html", "tex", "nroff", "ascii", "completion", "py", "xml", "wiki", NULL };
  static int  nicelevel=0,mantp=0,npri=0,debug_level=0;
  static char *deffnm=NULL;
  static real tbegin=0,tend=0,tdelta=0;
       
  t_pargs *all_pa=NULL;
  
  t_pargs npri_pa   = { "-npri", FALSE, etINT,   {&npri},
		       "HIDDEN Set non blocking priority (try 128)" };
  t_pargs nice_pa   = { "-nice", FALSE, etINT,   {&nicelevel}, 
		       "Set the nicelevel" };
  t_pargs deffnm_pa = { "-deffnm", FALSE, etSTR, {&deffnm}, 
		       "Set the default filename for all file options" };
  t_pargs begin_pa  = { "-b",    FALSE, etTIME,  {&tbegin},        
		       "First frame (%t) to read from trajectory" };
  t_pargs end_pa    = { "-e",    FALSE, etTIME,  {&tend},        
		       "Last frame (%t) to read from trajectory" };
  t_pargs dt_pa     = { "-dt",   FALSE, etTIME,  {&tdelta},        
		       "Only use frame when t MOD dt = first time (%t)" };
  t_pargs view_pa   = { "-w",    FALSE, etBOOL,  {&bView},
		       "View output xvg, xpm, eps and pdb files" };
  t_pargs code_pa   = { "-xvgr", FALSE, etBOOL,  {&bXvgrCodes},
		       "Add specific codes (legends etc.) in the output xvg files for the xmgrace program" };
  t_pargs time_pa   = { "-tu",   FALSE, etENUM,  {timestr},
			"Time unit" };
  /* Maximum number of extra arguments */
#define EXTRA_PA 16

  t_pargs pca_pa[] = {
    { "-h",    FALSE, etBOOL, {&bHelp},     
      "Print help info and quit" }, 
    { "-hidden", FALSE, etBOOL, {&bHidden},
      "HIDDENPrint hidden options" },
    { "-quiet",FALSE, etBOOL, {&bQuiet},
      "HIDDENDo not print help info" },
    { "-man",  FALSE, etENUM,  {manstr},
      "HIDDENWrite manual and quit" },
    { "-debug",FALSE, etINT, {&debug_level},
      "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
  };
#define NPCA_PA asize(pca_pa)
  FILE *fp;  
  bool bPrint,bExit,bXvgr;
  int  i,j,k,npall,max_pa,cmdlength;
  char *ptr,*newdesc;
  char *envstr;

#define FF(arg) ((Flags & arg)==arg)

  cmdlength = strlen(argv[0]);
  /* Check for double arguments */
  for (i=1; (i<*argc); i++) {
    cmdlength += strlen(argv[i]);
    if (argv[i] && (strlen(argv[i]) > 1) && (!isdigit(argv[i][1]))) {
      for (j=i+1; (j<*argc); j++) {
	if ( (argv[i][0]=='-') && (argv[j][0]=='-') && 
	     (strcmp(argv[i],argv[j])==0) ) {
	  if (FF(PCA_NOEXIT_ON_ARGS))
	    fprintf(stderr,"Double command line argument %s\n",argv[i]);
	  else
	    gmx_fatal(FARGS,"Double command line argument %s\n",argv[i]);
	}
      }
    }
  }
  debug_gmx();

  /* Fill the cmdline string */
  snew(cmdline,cmdlength+*argc+1);
  for (i=0; (i<*argc); i++) {
    strcat(cmdline,argv[i]);
    strcat(cmdline," ");
  }
  
  /* Handle the flags argument, which is a bit field 
   * The FF macro returns whether or not the bit is set
   */
  bPrint        = !FF(PCA_SILENT);
  
  set_program_name(argv[0]);

  /* Check ALL the flags ... */
  max_pa = NPCA_PA + EXTRA_PA + npargs;
  snew(all_pa,max_pa);
  
  for(i=npall=0; (i<NPCA_PA); i++)
    npall = add_parg(npall,all_pa,&(pca_pa[i]));

#ifdef __sgi
  envstr = getenv("GMXNPRIALL");
  if (envstr)
    npri=atoi(envstr);
  if (FF(PCA_BE_NICE)) {
    envstr = getenv("GMXNPRI");
    if (envstr)
      npri=atoi(envstr);
  }
  npall = add_parg(npall,all_pa,&npri_pa);
#endif

  if (FF(PCA_BE_NICE)) 
    nicelevel=19;
  npall = add_parg(npall,all_pa,&nice_pa);

  if (FF(PCA_CAN_SET_DEFFNM)) 
    npall = add_parg(npall,all_pa,&deffnm_pa);   
  if (FF(PCA_CAN_BEGIN)) 
    npall = add_parg(npall,all_pa,&begin_pa);
  if (FF(PCA_CAN_END))
    npall = add_parg(npall,all_pa,&end_pa);
  if (FF(PCA_CAN_DT))
    npall = add_parg(npall,all_pa,&dt_pa);
  if (FF(PCA_TIME_UNIT)) {
    envstr = getenv("GMXTIMEUNIT");
    if ( envstr == NULL )
      envstr="ps";
    set_default_time_unit(envstr);
    npall = add_parg(npall,all_pa,&time_pa);
  } else
    set_default_time_unit("ps");
  if (FF(PCA_CAN_VIEW)) 
    npall = add_parg(npall,all_pa,&view_pa);
    
  bXvgr = FALSE;
  for(i=0; (i<nfile); i++)
    bXvgr = bXvgr ||  (fnm[i].ftp == efXVG);
  if (bXvgr)
    npall = add_parg(npall,all_pa,&code_pa);
  
  /* Now append the program specific arguments */
  for(i=0; (i<npargs); i++)
    npall = add_parg(npall,all_pa,&(pa[i]));

  /* set etENUM options to default */
  for(i=0; (i<npall); i++)
    if (all_pa[i].type==etENUM)
      all_pa[i].u.c[0]=all_pa[i].u.c[1];
  
  /* Now parse all the command-line options */
  get_pargs(argc,argv,npall,all_pa,FF(PCA_KEEP_ARGS));

  if (FF(PCA_CAN_SET_DEFFNM) && (deffnm!=NULL))
    set_default_file_name(deffnm);

  /* Parse the file args */
  parse_file_args(argc,argv,nfile,fnm,FF(PCA_KEEP_ARGS));

  /* Open the debug file */
  if (debug_level > 0) {
    char buf[256];

    if (gmx_mpi_initialized())
      sprintf(buf,"%s%d.log",ShortProgram(),gmx_node_rank());
    else
      sprintf(buf,"%s.log",ShortProgram());
      
    init_debug(debug_level,buf);
    fprintf(stderr,"Opening debug file %s (src code file %s, line %d)\n",
	    buf,__FILE__,__LINE__);
  }

  /* Now copy the results back... */
  for(i=0,k=npall-npargs; (i<npargs); i++,k++) 
    memcpy(&(pa[i]),&(all_pa[k]),(size_t)sizeof(pa[i]));
  
  for(i=0; (i<npall); i++)
    all_pa[i].desc = mk_desc(&(all_pa[i]), time_unit() );

  bExit = bHelp || (strcmp(manstr[0],"no") != 0);

#if (defined __sgi && USE_SGI_FPE)
  doexceptions();
#endif

  /* Set the nice level */
#ifdef __sgi
  if (npri != 0 && !bExit) {
    schedctl(MPTS_RTPRI,0,npri);
  }
#endif 

#ifdef HAVE_UNISTD_H

#ifndef GMX_NO_NICE
  /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
  if (nicelevel != 0 && !bExit)
    i=nice(nicelevel); /* assign ret value to avoid warnings */
#endif

#endif
  
  if (!(FF(PCA_QUIET) || bQuiet )) {
    if (bHelp)
      write_man(stderr,"help",program,ndesc,desc,nfile,fnm,npall,all_pa,
		nbugs,bugs,bHidden);
    else if (bPrint) {
      pr_fns(stderr,nfile,fnm);
      print_pargs(stderr,npall,all_pa,FALSE);
    }
  }

  if (strcmp(manstr[0],"no") != 0) {
    if(!strcmp(manstr[0],"completion")) {
      /* one file each for csh, bash and zsh if we do completions */
      fp=man_file(program,"completion-zsh");
      write_man(fp,"completion-zsh",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
      fp=man_file(program,"completion-bash");
      write_man(fp,"completion-bash",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
      fp=man_file(program,"completion-csh");
      write_man(fp,"completion-csh",program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
    } else {
      fp=man_file(program,manstr[0]);
      write_man(fp,manstr[0],program,ndesc,desc,nfile,fnm,npall,all_pa,nbugs,bugs,bHidden);
      gmx_fio_fclose(fp);
    }
  }
  
  /* convert time options, must be done after printing! */
  init_time_factor();
  for(i=0; i<npall; i++) {
    if ((all_pa[i].type == etTIME) && (*all_pa[i].u.r >= 0)) {
      *all_pa[i].u.r *= timeinvfac;
    }
  }

  /* Extract Time info from arguments */
  if (FF(PCA_CAN_BEGIN) && opt2parg_bSet("-b",npall,all_pa))
    setTimeValue(TBEGIN,opt2parg_real("-b",npall,all_pa));

  if (FF(PCA_CAN_END) && opt2parg_bSet("-e",npall,all_pa))
    setTimeValue(TEND,opt2parg_real("-e",npall,all_pa));
  
  if (FF(PCA_CAN_DT) && opt2parg_bSet("-dt",npall,all_pa))
    setTimeValue(TDELTA,opt2parg_real("-dt",npall,all_pa));
  
  /* clear memory */
  sfree(all_pa);
  
  if (!FF(PCA_NOEXIT_ON_ARGS)) {
    if (*argc > 1) {
      gmx_cmd(argv[1]);
    }
  } 
  if (bExit) {
    if (gmx_parallel_env)
      gmx_abort(gmx_node_rank(),gmx_node_num(),0);
    else
      exit(0);
  }
#undef FF
}
Example #14
0
void parse_common_args(int *argc,char *argv[],unsigned long Flags,
		       int nfile,t_filenm fnm[],int npargs,t_pargs *pa,
		       int ndesc,const char **desc,
		       int nbugs,const char **bugs,
                       output_env_t *oenv)
{
    gmx_bool bHelp=FALSE,bHidden=FALSE,bQuiet=FALSE,bVersion=FALSE;
    const char *manstr[] = { NULL, "no", "html", "tex", "nroff", "ascii", 
                            "completion", "py", "xml", "wiki", NULL };
    /* This array should match the order of the enum in oenv.h */
    const char *xvg_format[] = { NULL, "xmgrace", "xmgr", "none", NULL };
    /* This array should match the order of the enum in oenv.h */
    const char *time_units[] = { NULL, "fs", "ps", "ns", "us", "ms", "s", 
                                NULL };
    int  nicelevel=0,mantp=0,npri=0,debug_level=0,verbose_level=0;
    char *deffnm=NULL;
    real tbegin=0,tend=0,tdelta=0;
    gmx_bool bView=FALSE;
    
    t_pargs *all_pa=NULL;
    
    t_pargs npri_pa   = { "-npri", FALSE, etINT,   {&npri},
    "HIDDEN Set non blocking priority (try 128)" };
    t_pargs nice_pa   = { "-nice", FALSE, etINT,   {&nicelevel}, 
    "Set the nicelevel" };
    t_pargs deffnm_pa = { "-deffnm", FALSE, etSTR, {&deffnm}, 
    "Set the default filename for all file options" };
    t_pargs begin_pa  = { "-b",    FALSE, etTIME,  {&tbegin},        
    "First frame (%t) to read from trajectory" };
    t_pargs end_pa    = { "-e",    FALSE, etTIME,  {&tend},        
    "Last frame (%t) to read from trajectory" };
    t_pargs dt_pa     = { "-dt",   FALSE, etTIME,  {&tdelta},        
    "Only use frame when t MOD dt = first time (%t)" };
    t_pargs view_pa   = { "-w",    FALSE, etBOOL,  {&bView},
    "View output xvg, xpm, eps and pdb files" };
    t_pargs xvg_pa    = { "-xvg",  FALSE, etENUM,  {xvg_format},
    "xvg plot formatting" };
    t_pargs time_pa   = { "-tu",   FALSE, etENUM,  {time_units},
    "Time unit" };
    /* Maximum number of extra arguments */
#define EXTRA_PA 16
    
    t_pargs pca_pa[] = {
      { "-h",    FALSE, etBOOL, {&bHelp},     
	"Print help info and quit" }, 
      { "-version",  FALSE, etBOOL, {&bVersion},     
	"Print version info and quit" }, 
      { "-verb",    FALSE,  etINT, {&verbose_level},
	"HIDDENLevel of verbosity for this program" },
      { "-hidden", FALSE, etBOOL, {&bHidden},
	  "HIDDENPrint hidden options" },
      { "-quiet",FALSE, etBOOL, {&bQuiet},
        "HIDDENDo not print help info" },
      { "-man",  FALSE, etENUM,  {manstr},
        "HIDDENWrite manual and quit" },
      { "-debug",FALSE, etINT, {&debug_level},
        "HIDDENWrite file with debug information, 1: short, 2: also x and f" },
    };
#define NPCA_PA asize(pca_pa)
    FILE *fp;  
    gmx_bool bPrint,bExit,bXvgr;
    int  i,j,k,npall,max_pa,cmdlength;
    char *ptr,*newdesc;
    const char *envstr;
    
#define FF(arg) ((Flags & arg)==arg)

    snew(*oenv, 1);
    
    cmdlength = strlen(argv[0]);
    /* Check for double arguments */
    for (i=1; (i<*argc); i++) 
    {
        cmdlength += strlen(argv[i]);
        if (argv[i] && (strlen(argv[i]) > 1) && (!isdigit(argv[i][1]))) 
        {
            for (j=i+1; (j<*argc); j++) 
            {
                if ( (argv[i][0]=='-') && (argv[j][0]=='-') && 
                    (strcmp(argv[i],argv[j])==0) ) 
                {
                    if (FF(PCA_NOEXIT_ON_ARGS))
                        fprintf(stderr,"Double command line argument %s\n",
                                argv[i]);
                    else
                        gmx_fatal(FARGS,"Double command line argument %s\n",
                                  argv[i]);
                }
            }
        }
    }
    debug_gmx();
    set_program_name(argv[0]);
    set_command_line(*argc, argv);
      
    /* Handle the flags argument, which is a bit field 
     * The FF macro returns whether or not the bit is set
     */
    bPrint        = !FF(PCA_SILENT);
    
    /* Check ALL the flags ... */
    max_pa = NPCA_PA + EXTRA_PA + npargs+1;
    snew(all_pa,max_pa);
    
    for(i=npall=0; (i<NPCA_PA); i++)
        npall = add_parg(npall,all_pa,&(pca_pa[i]));
    
#ifdef __sgi
    envstr = getenv("GMXNPRIALL");
    if (envstr)
        npri=strtol(envstr,NULL,10);
    if (FF(PCA_BE_NICE)) {
        envstr = getenv("GMXNPRI");
        if (envstr)
            npri=strtol(envstr,NULL,10);
    }
    npall = add_parg(npall,all_pa,&npri_pa);
#endif
    
    if (FF(PCA_BE_NICE)) 
        nicelevel=19;
    npall = add_parg(npall,all_pa,&nice_pa);
    
    if (FF(PCA_CAN_SET_DEFFNM)) 
        npall = add_parg(npall,all_pa,&deffnm_pa);   
    if (FF(PCA_CAN_BEGIN)) 
        npall = add_parg(npall,all_pa,&begin_pa);
    if (FF(PCA_CAN_END))
        npall = add_parg(npall,all_pa,&end_pa);
    if (FF(PCA_CAN_DT))
    {
        npall = add_parg(npall,all_pa,&dt_pa);
    }
    if (FF(PCA_TIME_UNIT)) {
        npall = add_parg(npall,all_pa,&time_pa);
    } 
    if (FF(PCA_CAN_VIEW)) 
        npall = add_parg(npall,all_pa,&view_pa);
    
    bXvgr = FALSE;
    for(i=0; (i<nfile); i++)
    {
        bXvgr = bXvgr ||  (fnm[i].ftp == efXVG);
    }
    if (bXvgr)
    {
        npall = add_parg(npall,all_pa,&xvg_pa);
    }
    
    /* Now append the program specific arguments */
    for(i=0; (i<npargs); i++)
        npall = add_parg(npall,all_pa,&(pa[i]));
    
    /* set etENUM options to default */
    for(i=0; (i<npall); i++)
    {
        if (all_pa[i].type==etENUM)
        {
            all_pa[i].u.c[0]=all_pa[i].u.c[1];
        }
    }
    set_default_time_unit(time_units,FF(PCA_TIME_UNIT));
    set_default_xvg_format(xvg_format);
  
    /* Now parse all the command-line options */
    get_pargs(argc,argv,npall,all_pa,FF(PCA_KEEP_ARGS));

    /* set program name, command line, and default values for output options */
    output_env_init(*oenv, *argc, argv, (time_unit_t)nenum(time_units), bView, 
                    (xvg_format_t)nenum(xvg_format), verbose_level, debug_level);
 
    if (bVersion) {
      printf("Program: %s\n",output_env_get_program_name(*oenv));
      gmx_print_version_info(stdout);
      exit(0);
    }
    
    if (FF(PCA_CAN_SET_DEFFNM) && (deffnm!=NULL))
        set_default_file_name(deffnm);
    
    /* Parse the file args */
    parse_file_args(argc,argv,nfile,fnm,FF(PCA_KEEP_ARGS),!FF(PCA_NOT_READ_NODE));
    
    /* Open the debug file */
    if (debug_level > 0) {
        char buf[256];
        
        if (gmx_mpi_initialized())
            sprintf(buf,"%s%d.debug",output_env_get_short_program_name(*oenv),
                    gmx_node_rank());
        else
            sprintf(buf,"%s.debug",output_env_get_short_program_name(*oenv));
        
        init_debug(debug_level,buf);
        fprintf(stderr,"Opening debug file %s (src code file %s, line %d)\n",
                buf,__FILE__,__LINE__);
    }
    
    /* Now copy the results back... */
    for(i=0,k=npall-npargs; (i<npargs); i++,k++) 
        memcpy(&(pa[i]),&(all_pa[k]),(size_t)sizeof(pa[i]));


    for(i=0; (i<npall); i++)
        all_pa[i].desc = mk_desc(&(all_pa[i]), output_env_get_time_unit(*oenv));
   
    bExit = bHelp || (strcmp(manstr[0],"no") != 0);
    
#if (defined __sgi && USE_SGI_FPE)
    doexceptions();
#endif
    
    /* Set the nice level */
#ifdef __sgi
    if (npri != 0 && !bExit) {
        schedctl(MPTS_RTPRI,0,npri);
    }
#endif 
    
#ifdef HAVE_UNISTD_H
    
#ifndef GMX_NO_NICE
    /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
    if (nicelevel != 0 && !bExit)
    {
#ifdef GMX_THREADS
        static gmx_bool nice_set=FALSE; /* only set it once */
        tMPI_Thread_mutex_lock(&init_mutex);
        if (!nice_set)
        {
#endif
            i=nice(nicelevel); /* assign ret value to avoid warnings */
#ifdef GMX_THREADS
            nice_set=TRUE;
        }
        tMPI_Thread_mutex_unlock(&init_mutex);
#endif
    }
#endif
#endif
   
    /* Update oenv for parsed command line options settings. */
    (*oenv)->xvg_format = (xvg_format_t)nenum(xvg_format);
    (*oenv)->time_unit  = (time_unit_t)nenum(time_units);
    
    if (!(FF(PCA_QUIET) || bQuiet )) {
        if (bHelp)
            write_man(stderr,"help",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm,npall,all_pa, nbugs,bugs,bHidden);
        else if (bPrint) {
            pr_fns(stderr,nfile,fnm);
            print_pargs(stderr,npall,all_pa,FALSE);
        }
    }
    
    if (strcmp(manstr[0],"no") != 0) {
        if(!strcmp(manstr[0],"completion")) {
            /* one file each for csh, bash and zsh if we do completions */
            fp=man_file(*oenv,"completion-zsh");
        
            write_man(fp,"completion-zsh",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
            fp=man_file(*oenv,"completion-bash");
            write_man(fp,"completion-bash",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
            fp=man_file(*oenv,"completion-csh");
            write_man(fp,"completion-csh",output_env_get_program_name(*oenv),
                      ndesc,desc,nfile, fnm, npall,all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
        } else {
            fp=man_file(*oenv,manstr[0]);
            write_man(fp,manstr[0],output_env_get_program_name(*oenv),
                      ndesc,desc,nfile,fnm, npall, all_pa,nbugs,bugs,bHidden);
            gmx_fio_fclose(fp);
        }
    }
    
    /* convert time options, must be done after printing! */
    
    for(i=0; i<npall; i++) {
        if ((all_pa[i].type == etTIME) && (*all_pa[i].u.r >= 0)) {
            *all_pa[i].u.r *= output_env_get_time_invfactor(*oenv);
        }
    }
    
    /* Extract Time info from arguments */
    if (FF(PCA_CAN_BEGIN) && opt2parg_bSet("-b",npall,all_pa))
        setTimeValue(TBEGIN,opt2parg_real("-b",npall,all_pa));
    
    if (FF(PCA_CAN_END) && opt2parg_bSet("-e",npall,all_pa))
        setTimeValue(TEND,opt2parg_real("-e",npall,all_pa));
    
    if (FF(PCA_CAN_DT) && opt2parg_bSet("-dt",npall,all_pa))
        setTimeValue(TDELTA,opt2parg_real("-dt",npall,all_pa));
    
    /* clear memory */
    for (i = 0; i < npall; ++i)
        sfree((void *)all_pa[i].desc);
    sfree(all_pa);
    
    if (!FF(PCA_NOEXIT_ON_ARGS)) {
        if (*argc > 1) {
            gmx_cmd(argv[1]);
        }
    } 
    if (bExit) {
        if (gmx_parallel_env_initialized())
            /*gmx_abort(gmx_node_rank(),gmx_node_num(),0);*/
            gmx_finalize();
        exit(0);
    }
#undef FF
}
Example #15
0
gmx_bool parse_common_args(int *argc, char *argv[], unsigned long Flags,
                           int nfile, t_filenm fnm[], int npargs, t_pargs *pa,
                           int ndesc, const char **desc,
                           int nbugs, const char **bugs,
                           output_env_t *oenv)
{
    /* This array should match the order of the enum in oenv.h */
    const char *const xvg_formats[] = { "xmgrace", "xmgr", "none" };

    // Handle the flags argument, which is a bit field
    // The FF macro returns whether or not the bit is set
#define FF(arg) ((Flags & arg) == arg)

    try
    {
        int                        nicelevel = 0, debug_level = 0;
        double                     tbegin    = 0.0, tend = 0.0, tdelta = 0.0;
        bool                       bView     = false;
        int                        xvgFormat = 0;
        gmx::TimeUnitManager       timeUnitManager;
        gmx::OptionsAdapter        adapter(*argc, argv);
        gmx::Options               options(NULL, NULL);
        gmx::FileNameOptionManager fileOptManager;

        options.addManager(&fileOptManager);
        options.setDescription(gmx::ConstArrayRef<const char *>(desc, ndesc));
        options.addOption(
                gmx::IntegerOption("debug").store(&debug_level).hidden()
                    .description("Write file with debug information, "
                                 "1: short, 2: also x and f"));

        options.addOption(
                gmx::IntegerOption("nice").store(&nicelevel)
                    .defaultValue(FF(PCA_BE_NICE) ? 19 : 0)
                    .description("Set the nicelevel"));

        if (FF(PCA_CAN_SET_DEFFNM))
        {
            fileOptManager.addDefaultFileNameOption(&options, "deffnm");
        }
        if (FF(PCA_CAN_BEGIN))
        {
            options.addOption(
                    gmx::DoubleOption("b").store(&tbegin).timeValue()
                        .description("First frame (%t) to read from trajectory"));
        }
        if (FF(PCA_CAN_END))
        {
            options.addOption(
                    gmx::DoubleOption("e").store(&tend).timeValue()
                        .description("Last frame (%t) to read from trajectory"));
        }
        if (FF(PCA_CAN_DT))
        {
            options.addOption(
                    gmx::DoubleOption("dt").store(&tdelta).timeValue()
                        .description("Only use frame when t MOD dt = first time (%t)"));
        }
        if (FF(PCA_TIME_UNIT))
        {
            timeUnitManager.setTimeUnitFromEnvironment();
            timeUnitManager.addTimeUnitOption(&options, "tu");
        }
        if (FF(PCA_CAN_VIEW))
        {
            options.addOption(
                    gmx::BooleanOption("w").store(&bView)
                        .description("View output [TT].xvg[tt], [TT].xpm[tt], "
                                     "[TT].eps[tt] and [TT].pdb[tt] files"));
        }

        bool bXvgr = false;
        for (int i = 0; i < nfile; i++)
        {
            bXvgr = bXvgr || (fnm[i].ftp == efXVG);
        }
        xvgFormat = gmx::getDefaultXvgFormat(xvg_formats);
        if (bXvgr)
        {
            options.addOption(
                    gmx::StringOption("xvg").enumValue(xvg_formats)
                        .storeEnumIndex(&xvgFormat)
                        .description("xvg plot formatting"));
        }

        /* Now append the program specific arguments */
        for (int i = 0; i < nfile; i++)
        {
            adapter.filenmToOptions(&options, &fnm[i]);
        }
        for (int i = 0; i < npargs; i++)
        {
            adapter.pargsToOptions(&options, &pa[i]);
        }

        const gmx::CommandLineHelpContext *context =
            gmx::GlobalCommandLineHelpContext::get();
        if (context != NULL)
        {
            if (!(FF(PCA_QUIET)))
            {
                gmx::CommandLineHelpWriter(options)
                    .setShowDescriptions(true)
                    .setTimeUnitString(timeUnitManager.timeUnitAsString())
                    .setKnownIssues(gmx::ConstArrayRef<const char *>(bugs, nbugs))
                    .writeHelp(*context);
            }
            return FALSE;
        }

        /* Now parse all the command-line options */
        gmx::CommandLineParser(&options).skipUnknown(FF(PCA_NOEXIT_ON_ARGS))
            .parse(argc, argv);
        options.finish();

        /* set program name, command line, and default values for output options */
        output_env_init(oenv, gmx::getProgramContext(),
                        (time_unit_t)(timeUnitManager.timeUnit() + 1), bView,
                        (xvg_format_t)(xvgFormat + 1), 0, debug_level);

        /* Open the debug file */
        if (debug_level > 0)
        {
            char buf[256];

            if (gmx_mpi_initialized())
            {
                sprintf(buf, "%s%d.debug", output_env_get_short_program_name(*oenv),
                        gmx_node_rank());
            }
            else
            {
                sprintf(buf, "%s.debug", output_env_get_short_program_name(*oenv));
            }

            init_debug(debug_level, buf);
            fprintf(stderr, "Opening debug file %s (src code file %s, line %d)\n",
                    buf, __FILE__, __LINE__);
        }

        /* Set the nice level */
#ifdef HAVE_UNISTD_H
#ifndef GMX_NO_NICE
        /* The some system, e.g. the catamount kernel on cray xt3 do not have nice(2). */
        if (nicelevel != 0)
        {
            static gmx_bool            nice_set   = FALSE; /* only set it once */
            static tMPI_Thread_mutex_t init_mutex = TMPI_THREAD_MUTEX_INITIALIZER;
            tMPI_Thread_mutex_lock(&init_mutex);
            if (!nice_set)
            {
                if (nice(nicelevel) == -1)
                {
                    /* Do nothing, but use the return value to avoid warnings. */
                }
                nice_set = TRUE;
            }
            tMPI_Thread_mutex_unlock(&init_mutex);
        }
#endif
#endif

        timeUnitManager.scaleTimeOptions(&options);

        /* Extract Time info from arguments */
        // TODO: Use OptionInfo objects instead of string constants
        if (FF(PCA_CAN_BEGIN) && options.isSet("b"))
        {
            setTimeValue(TBEGIN, tbegin);
        }
        if (FF(PCA_CAN_END) && options.isSet("e"))
        {
            setTimeValue(TEND, tend);
        }
        if (FF(PCA_CAN_DT) && options.isSet("dt"))
        {
            setTimeValue(TDELTA, tdelta);
        }

        adapter.copyValues(!FF(PCA_NOT_READ_NODE));

        return TRUE;
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
#undef FF
}