X-Git-Url: http://git.treefish.org/~alex/phys/latlib.git/blobdiff_plain/7ba7584af501689c899b1b311286140d88e23b25..594f56b186b5d2f5e25293d6952c9325576aa080:/o815/o815.cpp?ds=inline diff --git a/o815/o815.cpp b/o815/o815.cpp index 9b0fff8..17581ec 100644 --- a/o815/o815.cpp +++ b/o815/o815.cpp @@ -1,14 +1,20 @@ #include "o815.h" #include +#include +#include + +#ifndef MPI_DISABLED +#include +#endif #include "latlib/progress.h" -extern int opterr; +using namespace std; -o815::o815(int argc, char **argv, const string& _programid) { - long timestamp; +extern int opterr; +o815::o815(int argc, char **argv, const string& _programid, comoption specOps[], void (*helpHeader)()) { programid = _programid; comargs.nmeas = 100; @@ -22,31 +28,93 @@ o815::o815(int argc, char **argv, const string& _programid) { comargs.idonly = false; comargs.showjobnum = false; +#ifndef MPI_DISABLED MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); +#else + numprocs = 1; + rank = 0; +#endif + + addComOption("lsize", required_argument, NULL, 'L', "define lattice size", "xsize:tsize"); + addComOption("nmeas", required_argument, NULL, 'N', "set number of measurements", "nmeas"); + addComOption("skip", required_argument, NULL, 'S', "set number of skips between configs", "nskip"); + addComOption("nequi", required_argument, NULL, 'E', "set number of equilibrations", "nequi"); + addComOption("ocache", required_argument, NULL, 'O', "set observable cache (mode=oo|ro|wo|rw)", "dir:mode"); + addComOption("ccache", required_argument, NULL, 'C', "set config cache (mode=oo|ro|wo|rw)", "dir:mode"); + addComOption("write", required_argument, NULL, 'W', "data writeout directory", "dir"); + addComOption("idonly", no_argument, &comargs.idonly, 'I', "show output-id only", ""); + addComOption("jobnum", no_argument, &comargs.showjobnum, 'J', "show jobnumber only", ""); + + vector::iterator lastO815Opt = comOptions.end()-1; + + if (specOps != NULL) + for (int ispecop = 0; specOps[ispecop].name != ""; ispecop++) + comOptions.push_back(specOps[ispecop]); + + if (argc > 1) + parseArgs(argc, argv, specOps); + else { + int longestCombinedLong=0; + + if (helpHeader != NULL) + helpHeader(); + + cout << "General options:" << endl; + + for (vector::iterator opit = comOptions.begin(); opit != comOptions.end(); ++opit) { + stringstream combinedLong; + + combinedLong << opit->name; + if (opit->has_arg == required_argument) + combinedLong << "=" << opit->argdesc; + else if (opit->has_arg == optional_argument) + combinedLong << "[=" << opit->argdesc << "]"; + + if (longestCombinedLong < combinedLong.str().size()) + longestCombinedLong = combinedLong.str().size(); + } + + for (vector::iterator opit = comOptions.begin(); opit != comOptions.end(); ++opit) { + stringstream combinedLong; + + cout << " -" << char(opit->val) << ", --"; + + combinedLong << opit->name; + if (opit->has_arg == required_argument) + combinedLong << "=" << opit->argdesc; + else if (opit->has_arg == optional_argument) + combinedLong << "[=" << opit->argdesc << "]"; + + cout << setw(longestCombinedLong) << setiosflags(ios::left) << combinedLong.str(); + + cout << "\t" << opit->optdesc; + + cout << endl; + + if ( opit == lastO815Opt && (opit+1) != comOptions.end() ) { + cout << endl; + cout << "Simulation specific options:" << endl; + } + } + exit(0); + } paraQ = new paraq(numprocs, rank); - parseArgs(argc, argv); + hypercache::addPara("lx", comargs.lsize[0]); + hypercache::addPara("lt", comargs.lsize[1]); +} + +void o815::postParaInit() { + long timestamp; if(comargs.idonly) { cout << programid << headMaster() << endl << flush; exit(0); } - if(rank==0) { - timestamp = time(NULL); - for(int idest=1; idest0) - MPI_Recv(×tamp, 1, MPI_LONG, 0, 123, MPI_COMM_WORLD, &mpiStatus); - - out = new writeout(comargs.outdir, programid+headMaster(), rank, numprocs, timestamp); -} - -void o815::mainLoop() { if( comargs.showjobnum ) { for( int i=1; i<=paraQ->getTotalJobs(); i++ ) { if( paraQ->getTotalJobs()%i == 0 ) cout << paraQ->getTotalJobs()/i << "@" << i << " "; @@ -54,7 +122,11 @@ void o815::mainLoop() { cout << endl; exit(0); } + + out = new writeout(comargs.outdir, programid+headMaster(), rank, numprocs); +} +void o815::mainLoop() { *out->log << "OBS: Starting main loop." << endl; for (vector::iterator obsit = observables.begin(); obsit != observables.end(); ++obsit) @@ -65,6 +137,8 @@ void o815::mainLoop() { for (vector::iterator parait = paraQ->allParaIds.begin(); parait != paraQ->allParaIds.end(); ++parait) *out->log << *parait << "=" << (*paraQ)[*parait] << " "; *out->log << ">" << endl << flush; + + Sim->_newParas(); progress measProg(comargs.nmeas); @@ -73,21 +147,26 @@ void o815::mainLoop() { *out->log << " " << (*obsit)->obsid; *out->log << endl << flush; - Sim->toEquilibrate = true; - for( int imeas=0; imeas::iterator obsit = observables.begin(); obsit != observables.end(); ++obsit) { - if( hypercache::readO( (*obsit)->ocid ) != -1 ) { + bool readnewObs; + int nequileftNewObs; + + hypercache::readO( (*obsit)->ocid, &readnewObs, &nequileftNewObs ); + + if ( readnewObs && nequileftNewObs < 0 ) { + (*obsit)->meas(true, imeas); + } + else { if (!nextAlready) { Sim->nextConfig(); nextAlready = true; } - (*obsit)->meas(false); + (*obsit)->meas(false, imeas); hypercache::writeO( (*obsit)->ocid ); } - else - (*obsit)->meas(true); + } while( measProg.madeStep(imeas) ) *out->log << "O815: " << measProg.done()*100 << "% of measurements done." << endl << flush; @@ -97,12 +176,37 @@ void o815::mainLoop() { } } -void o815::parseArgs(int argc, char **argv) { - int opt = 0; - - opterr = 0; +void o815::addComOption(const char* name, int has_arg, int *flag, int val, const char* optdesc, const char* argdesc) { + comoption newop = { name, has_arg, flag, val, optdesc, argdesc }; + comOptions.push_back(newop); +} + +void o815::parseArgs(int argc, char **argv, comoption specOps[]) { + int opt; + int indexptr=0; + stringstream optargstr; + option allOptions[comOptions.size()+1]; + + for (int iop=0; iop < comOptions.size(); iop++) { + allOptions[iop].name = comOptions[iop].name.c_str(); + allOptions[iop].has_arg = comOptions[iop].has_arg; + //allOptions[iop].flag = NULL; + allOptions[iop].flag = comOptions[iop].flag; + allOptions[iop].val = comOptions[iop].val; + + optargstr << char(allOptions[iop].val); + if (allOptions[iop].has_arg == required_argument) + optargstr << ":"; + else if (allOptions[iop].has_arg == optional_argument) + optargstr << "::"; + } + + allOptions[comOptions.size()].name = 0; + allOptions[comOptions.size()].has_arg = 0; + allOptions[comOptions.size()].flag = 0; + allOptions[comOptions.size()].val = 0; - while( (opt = getopt(argc, argv, "L:N:S:E:o:O:c:C:w:i:j:")) != -1 ) + while((opt = getopt_long( argc, argv, optargstr.str().c_str(), allOptions, &indexptr )) != -1) switch(opt) { case 'L': listArg(comargs.lsize, 2, optarg); @@ -116,32 +220,35 @@ void o815::parseArgs(int argc, char **argv) { case 'E': comargs.nequi = atoi(optarg); break; - case 'o': - comargs.obscache.first = optarg; - comargs.obscache.second = 1; - break; case 'O': - comargs.obscache.first = optarg; - comargs.obscache.second = 2; - break; - case 'c': - comargs.confcache.first = optarg; - comargs.confcache.second = 1; + readCacheArgs(optarg, comargs.obscache.first, comargs.obscache.second); break; case 'C': - comargs.confcache.first = optarg; - comargs.confcache.second = 2; + readCacheArgs(optarg, comargs.confcache.first, comargs.confcache.second); break; case 'w': comargs.outdir = optarg; break; - case 'i': - comargs.idonly = atoi(optarg); - break; - case 'j': - comargs.showjobnum = atoi(optarg); + default: + if ( opt != 0) { + comoption* thisop = getOptionByVal(opt); + if (thisop->flag != 0) + *thisop->flag = thisop->val; + else + parsedSpecOps.push_back( pair(thisop->val, optarg) ); + } break; } + + for (int ilon=0; optind+ilon < argc; ilon++) + lonelyArgs.push_back(argv[optind+ilon]); +} + +o815::comoption* o815::getOptionByVal(int val) { + for (vector::iterator opit = comOptions.begin(); opit != comOptions.end(); ++opit) + if ( opit->val == val ) + return &(*opit); + exit(1); } void o815::listArg(int *target, int tlen, char *listarg) { @@ -172,13 +279,17 @@ string o815::headMaster() o815::~o815() { if(comargs.outdir=="") { +#ifndef MPI_DISABLED MPI_Barrier(MPI_COMM_WORLD); +#endif if(rank==0) cout << "#end" << endl << flush; } hypercache::finalize(); delete out; +#ifndef MPI_DISABLED MPI_Finalize(); +#endif } int o815::nextParas() @@ -196,3 +307,27 @@ void o815::addPara(const string& paraid, const double& paraDefault) { hypercache::addPara(paraid); paraQ->setDefault(paraid, paraDefault); } + +void o815::readCacheArgs(const string& arg, string& cachedir, int& cachemode) +{ + if ( arg.rfind(":") == string::npos ) { + cerr << "O815: Invalid cache argument!" << endl; + exit(1); + } + + string arg_mode = arg.substr( arg.rfind(":")+1 ); + if ( arg_mode == "oo" ) + cachemode = CACHE_MODE_OO; + else if ( arg_mode == "ro" ) + cachemode = CACHE_MODE_RO; + else if ( arg_mode == "wo" ) + cachemode = CACHE_MODE_WO; + else if ( arg_mode == "rw" ) + cachemode = CACHE_MODE_RW; + else { + cerr << "O815: Unknown cache mode " << arg_mode << "!" << endl; + exit(1); + } + + cachedir = arg.substr( 0, arg.rfind(":") ); +}