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); } } } }
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; }
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; }