void init_multisystem(t_commrec *cr, int nsim, char **multidirs,
                      int nfile, const t_filenm fnm[], gmx_bool bParFn)
{
    gmx_multisim_t *ms;
    int             nnodes, nnodpersim, sim, i, ftp;
    char            buf[256];
#ifdef GMX_MPI
    MPI_Group       mpi_group_world;
    int            *rank;
#endif

#ifndef GMX_MPI
    if (nsim > 1)
    {
        gmx_fatal(FARGS, "This binary is compiled without MPI support, can not do multiple simulations.");
    }
#endif

    nnodes  = cr->nnodes;
    if (nnodes % nsim != 0)
    {
        gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%d)", nnodes, nsim);
    }

    nnodpersim = nnodes/nsim;
    sim        = cr->nodeid/nnodpersim;

    if (debug)
    {
        fprintf(debug, "We have %d simulations, %d ranks per simulation, local simulation is %d\n", nsim, nnodpersim, sim);
    }

    snew(ms, 1);
    cr->ms   = ms;
    ms->nsim = nsim;
    ms->sim  = sim;
#ifdef GMX_MPI
    /* Create a communicator for the master nodes */
    snew(rank, ms->nsim);
    for (i = 0; i < ms->nsim; i++)
    {
        rank[i] = i*nnodpersim;
    }
    MPI_Comm_group(MPI_COMM_WORLD, &mpi_group_world);
    MPI_Group_incl(mpi_group_world, nsim, rank, &ms->mpi_group_masters);
    sfree(rank);
    MPI_Comm_create(MPI_COMM_WORLD, ms->mpi_group_masters,
                    &ms->mpi_comm_masters);

#if !defined(MPI_IN_PLACE_EXISTS)
    /* initialize the MPI_IN_PLACE replacement buffers */
    snew(ms->mpb, 1);
    ms->mpb->ibuf        = NULL;
    ms->mpb->libuf       = NULL;
    ms->mpb->fbuf        = NULL;
    ms->mpb->dbuf        = NULL;
    ms->mpb->ibuf_alloc  = 0;
    ms->mpb->libuf_alloc = 0;
    ms->mpb->fbuf_alloc  = 0;
    ms->mpb->dbuf_alloc  = 0;
#endif

#endif

    /* Reduce the intra-simulation communication */
    cr->sim_nodeid = cr->nodeid % nnodpersim;
    cr->nnodes     = nnodpersim;
#ifdef GMX_MPI
    MPI_Comm_split(MPI_COMM_WORLD, sim, cr->sim_nodeid, &cr->mpi_comm_mysim);
    cr->mpi_comm_mygroup = cr->mpi_comm_mysim;
    cr->nodeid           = cr->sim_nodeid;
#endif

    if (debug)
    {
        fprintf(debug, "This is simulation %d", cr->ms->sim);
        if (PAR(cr))
        {
            fprintf(debug, ", local number of ranks %d, local rank ID %d",
                    cr->nnodes, cr->sim_nodeid);
        }
        fprintf(debug, "\n\n");
    }

    if (multidirs)
    {
        if (debug)
        {
            fprintf(debug, "Changing to directory %s\n", multidirs[cr->ms->sim]);
        }
        gmx_chdir(multidirs[cr->ms->sim]);
    }
    else if (bParFn)
    {
        /* Patch output and tpx, cpt and rerun input file names */
        for (i = 0; (i < nfile); i++)
        {
            /* Because of possible multiple extensions per type we must look
             * at the actual file name
             */
            if (is_output(&fnm[i]) ||
                fnm[i].ftp == efTPX || fnm[i].ftp == efCPT ||
                strcmp(fnm[i].opt, "-rerun") == 0)
            {
                ftp = fn2ftp(fnm[i].fns[0]);
                par_fn(fnm[i].fns[0], ftp, cr, TRUE, FALSE, buf, 255);
                sfree(fnm[i].fns[0]);
                fnm[i].fns[0] = gmx_strdup(buf);
            }
        }
    }
}
Example #2
0
void init_multisystem(t_commrec *cr,int nsim,
		      int nfile,t_filenm fnm[],bool bParFn)
{
  gmx_multisim_t *ms;
  int  nnodes,nnodpersim,sim,i,ftp;
  char buf[256];
#ifdef GMX_MPI
  MPI_Group mpi_group_world;
#endif  
  int *rank;

  nnodes  = cr->nnodes;
  if (nnodes % nsim != 0)
    gmx_fatal(FARGS,"The number of nodes (%d) is not a multiple of the number of simulations (%d)",nnodes,nsim);

  nnodpersim = nnodes/nsim;
  sim = cr->nodeid/nnodpersim;

  if (debug)
    fprintf(debug,"We have %d simulations, %d nodes per simulation, local simulation is %d\n",nsim,nnodpersim,sim);

  snew(ms,1);
  cr->ms = ms;
  ms->nsim = nsim;
  ms->sim  = sim;
#ifdef GMX_MPI
  /* Create a communicator for the master nodes */
  snew(rank,ms->nsim);
  for(i=0; i<ms->nsim; i++)
    rank[i] = i*nnodpersim;
  MPI_Comm_group(MPI_COMM_WORLD,&mpi_group_world);
  MPI_Group_incl(mpi_group_world,nsim,rank,&ms->mpi_group_masters);
  sfree(rank);
  MPI_Comm_create(MPI_COMM_WORLD,ms->mpi_group_masters,
		  &ms->mpi_comm_masters);
#endif

  /* Reduce the intra-simulation communication */
  cr->sim_nodeid = cr->nodeid % nnodpersim;
  cr->nnodes = nnodpersim;
#ifdef GMX_MPI
  MPI_Comm_split(MPI_COMM_WORLD,sim,cr->sim_nodeid,&cr->mpi_comm_mysim);
  cr->mpi_comm_mygroup = cr->mpi_comm_mysim;
  cr->nodeid = cr->sim_nodeid;
#endif

  if (debug) {
    fprintf(debug,"This is simulation %d",cr->ms->sim);
    if (PAR(cr))
      fprintf(debug,", local number of nodes %d, local nodeid %d",
	      cr->nnodes,cr->sim_nodeid);
    fprintf(debug,"\n\n");
  }

  if (bParFn) {
    /* Patch output and tpx file names (except log which has been done already)
     */
    for(i=0; (i<nfile); i++) {
      /* Because of possible multiple extensions per type we must look 
       * at the actual file name 
       */
      if (is_output(&fnm[i]) ||
	  fnm[i].ftp == efTPX || fnm[i].ftp == efCPT ||
	  strcmp(fnm[i].opt,"-rerun") == 0) {
	ftp = fn2ftp(fnm[i].fns[0]);
	par_fn(fnm[i].fns[0],ftp,cr,FALSE,buf,255);
	sfree(fnm[i].fns[0]);
	fnm[i].fns[0] = strdup(buf);
      }
    }
  }
}
void gmx_log_open(const char *lognm, const t_commrec *cr, gmx_bool bMasterOnly,
                  gmx_bool bAppendFiles, FILE** fplog)
{
    int    len, pid;
    char   buf[256], host[256];
    time_t t;
    char   timebuf[STRLEN];
    FILE  *fp = *fplog;
    char  *tmpnm;

    debug_gmx();

    /* Communicate the filename for logfile */
    if (cr->nnodes > 1 && !bMasterOnly
#ifdef GMX_THREAD_MPI
        /* With thread MPI the non-master log files are opened later
         * when the files names are already known on all nodes.
         */
        && FALSE
#endif
        )
    {
        if (MASTER(cr))
        {
            len = strlen(lognm) + 1;
        }
        gmx_bcast(sizeof(len), &len, cr);
        if (!MASTER(cr))
        {
            snew(tmpnm, len+8);
        }
        else
        {
            tmpnm = gmx_strdup(lognm);
        }
        gmx_bcast(len*sizeof(*tmpnm), tmpnm, cr);
    }
    else
    {
        tmpnm = gmx_strdup(lognm);
    }

    debug_gmx();

    if (!bMasterOnly && !MASTER(cr))
    {
        /* Since log always ends with '.log' let's use this info */
        par_fn(tmpnm, efLOG, cr, FALSE, !bMasterOnly, buf, 255);
        fp = gmx_fio_fopen(buf, bAppendFiles ? "a+" : "w+" );
    }
    else if (!bAppendFiles)
    {
        fp = gmx_fio_fopen(tmpnm, bAppendFiles ? "a+" : "w+" );
    }

    sfree(tmpnm);

    gmx_fatal_set_log_file(fp);

    /* Get some machine parameters */
    gmx_gethostname(host, 256);

    time(&t);

#ifndef NO_GETPID
#   ifdef GMX_NATIVE_WINDOWS
    pid = _getpid();
#   else
    pid = getpid();
#   endif
#else
    pid = 0;
#endif

    if (bAppendFiles)
    {
        fprintf(fp,
                "\n"
                "\n"
                "-----------------------------------------------------------\n"
                "Restarting from checkpoint, appending to previous log file.\n"
                "\n"
                );
    }

    gmx_ctime_r(&t, timebuf, STRLEN);

    fprintf(fp,
            "Log file opened on %s"
            "Host: %s  pid: %d  rank ID: %d  number of ranks:  %d\n",
            timebuf, host, pid, cr->nodeid, cr->nnodes);
    try
    {
        gmx::BinaryInformationSettings settings;
        settings.extendedInfo(true);
        settings.copyright(!bAppendFiles);
        gmx::printBinaryInformation(fp, gmx::getProgramContext(), settings);
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
    fprintf(fp, "\n\n");

    fflush(fp);
    debug_gmx();

    *fplog = fp;
}
Example #4
0
FILE *gmx_log_open(char *lognm,const t_commrec *cr,bool bMasterOnly, unsigned long Flags)
{
  int  len,testlen,pid;
  char buf[256],host[256];
  time_t t;
  FILE *fp;

  bool bAppend = Flags & MD_APPENDFILES;	
  
  debug_gmx();
  
  /* Communicate the filename for logfile */
  if (cr->nnodes > 1 && !bMasterOnly) {
    if (MASTER(cr))
      len = strlen(lognm)+1;
    gmx_bcast(sizeof(len),&len,cr);
    if (!MASTER(cr))
      snew(lognm,len+8);
    gmx_bcast(len*sizeof(*lognm),lognm,cr);
  }
  
  debug_gmx();

  if (PAR(cr) && !bMasterOnly) {
    /* Since log always ends with '.log' let's use this info */
    par_fn(lognm,efLOG,cr,cr->ms!=NULL,buf,255);
	  fp = gmx_fio_fopen(buf, bAppend ? "a" : "w" );
  } else {
	  fp = gmx_fio_fopen(lognm, bAppend ? "a" : "w" );
  }

  gmx_fatal_set_log_file(fp);
  
  /* Get some machine parameters */
#ifdef HAVE_UNISTD_H
  if( gethostname(host,255) != 0)
    sprintf(host,"unknown");
#else
  sprintf(host,"unknown");
#endif  

  time(&t);

#ifndef NO_GETPID
#   if ((defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64) && !defined __CYGWIN__ && !defined __CYGWIN32__)
	  pid = _getpid();
#   else
	  pid = getpid();
#   endif
#else
	pid = 0;
#endif

  if(bAppend)
  {
	  fprintf(fp,
			  "\n\n"
			  "-----------------------------------------------------------\n"
			  "Restarting from checkpoint, appending to previous log file.\n\n"
			  );
  }
	
  fprintf(fp,
	  "Log file opened on %s"
	  "Host: %s  pid: %d  nodeid: %d  nnodes:  %d\n",
	  ctime(&t),host,pid,cr->nodeid,cr->nnodes);

#if (defined BUILD_MACHINE && defined BUILD_TIME && defined BUILD_USER) 
  fprintf(fp,
	  "The Gromacs distribution was built %s by\n"
	  "%s (%s)\n\n\n",BUILD_TIME,BUILD_USER,BUILD_MACHINE);
#endif

  fflush(fp);
  debug_gmx();

  return fp;
}