modernize and simplify code to find best matching restart file

This commit is contained in:
Axel Kohlmeyer 2021-07-29 11:50:11 -04:00
parent c49a533ad9
commit 4710b7bc9e
No known key found for this signature in database
GPG Key ID: D9B44E93BF0C375A
2 changed files with 37 additions and 75 deletions

View File

@ -71,16 +71,18 @@ void ReadRestart::command(int narg, char **arg)
// if filename contains "*", search dir for latest restart file
char *file = new char[strlen(arg[0]) + 16];
char *file;
if (strchr(arg[0],'*')) {
int n;
int n=0;
if (me == 0) {
file_search(arg[0],file);
n = strlen(file) + 1;
auto fn = file_search(arg[0]);
n = fn.size()+1;
file = utils::strdup(fn);
}
MPI_Bcast(&n,1,MPI_INT,0,world);
if (me != 0) file = new char[n];
MPI_Bcast(file,n,MPI_CHAR,0,world);
} else strcpy(file,arg[0]);
} else file = utils::strdup(arg[0]);
// check for multiproc files and an MPI-IO filename
@ -90,14 +92,12 @@ void ReadRestart::command(int narg, char **arg)
else mpiioflag = 0;
if (multiproc && mpiioflag)
error->all(FLERR,
"Read restart MPI-IO input not allowed with % in filename");
error->all(FLERR,"Read restart MPI-IO input not allowed with % in filename");
if (mpiioflag) {
mpiio = new RestartMPIIO(lmp);
if (!mpiio->mpiio_exists)
error->all(FLERR,"Reading from MPI-IO filename when "
"MPIIO package is not installed");
error->all(FLERR,"Reading from MPI-IO filename when MPIIO package is not installed");
}
// open single restart file or base file for multiproc case
@ -538,83 +538,45 @@ void ReadRestart::command(int narg, char **arg)
only called by proc 0
------------------------------------------------------------------------- */
void ReadRestart::file_search(char *inpfile, char *outfile)
std::string ReadRestart::file_search(const std::string &inpfile)
{
char *ptr;
// separate inpfile into dir + filename
char *dirname = new char[strlen(inpfile) + 1];
char *filename = new char[strlen(inpfile) + 1];
if (strchr(inpfile,'/')) {
ptr = strrchr(inpfile,'/');
*ptr = '\0';
strcpy(dirname,inpfile);
strcpy(filename,ptr+1);
*ptr = '/';
} else {
strcpy(dirname,"./");
strcpy(filename,inpfile);
}
auto dirname = utils::path_dirname(inpfile);
auto filename = utils::path_basename(inpfile);
// if filename contains "%" replace "%" with "base"
char *pattern = new char[strlen(filename) + 16];
auto pattern = filename;
auto loc = pattern.find('%');
if (loc != std::string::npos) pattern.replace(loc,1,"base");
if ((ptr = strchr(filename,'%'))) {
*ptr = '\0';
sprintf(pattern,"%s%s%s",filename,"base",ptr+1);
*ptr = '%';
} else strcpy(pattern,filename);
// scan all files in directory, searching for files that match regexp pattern
// maxnum = largest integer that matches "*"
// scan all files in directory, searching for files that match pattern
// maxnum = largest int that matches "*"
int n = strlen(pattern) + 16;
char *begin = new char[n];
char *middle = new char[n];
char *end = new char[n];
ptr = strchr(pattern,'*');
*ptr = '\0';
strcpy(begin,pattern);
strcpy(end,ptr+1);
int nbegin = strlen(begin);
bigint maxnum = -1;
loc = pattern.find('*');
if (loc != std::string::npos) {
// convert pattern to equivalent regexp
pattern.replace(loc,1,"\\d+");
struct dirent *ep;
DIR *dp = opendir(dirname.c_str());
if (dp == nullptr)
error->one(FLERR,"Cannot open directory {} to search for restart file: {}",
dirname, utils::getsyserror());
struct dirent *ep;
DIR *dp = opendir(dirname);
if (dp == nullptr)
error->one(FLERR,"Cannot open dir to search for restart file");
while ((ep = readdir(dp))) {
if (strstr(ep->d_name,begin) != ep->d_name) continue;
if ((ptr = strstr(&ep->d_name[nbegin],end)) == nullptr) continue;
if (strlen(end) == 0) ptr = ep->d_name + strlen(ep->d_name);
*ptr = '\0';
if ((int)strlen(&ep->d_name[nbegin]) < n) {
strcpy(middle,&ep->d_name[nbegin]);
if (ATOBIGINT(middle) > maxnum) maxnum = ATOBIGINT(middle);
while ((ep = readdir(dp))) {
std::string candidate(ep->d_name);
if (utils::strmatch(candidate,pattern)) {
bigint num = ATOBIGINT(utils::strfind(candidate.substr(loc),"\\d+").c_str());
if (num > maxnum) maxnum = num;
}
}
closedir(dp);
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
filename.replace(filename.find('*'),1,std::to_string(maxnum));
}
closedir(dp);
if (maxnum < 0) error->one(FLERR,"Found no restart file matching pattern");
// create outfile with maxint substituted for "*"
// use original inpfile, not pattern, since need to retain "%" in filename
std::string newoutfile = inpfile;
newoutfile.replace(newoutfile.find("*"),1,fmt::format("{}",maxnum));
strcpy(outfile,newoutfile.c_str());
// clean up
delete [] dirname;
delete [] filename;
delete [] pattern;
delete [] begin;
delete [] middle;
delete [] end;
return utils::path_join(dirname,filename);
}
/* ----------------------------------------------------------------------

View File

@ -46,7 +46,7 @@ class ReadRestart : public Command {
bigint assignedChunkSize;
MPI_Offset assignedChunkOffset, headerOffset;
void file_search(char *, char *);
std::string file_search(const std::string &);
void header();
void type_arrays();
void force_fields();