diff --git a/src/constants.cpp b/src/constants.cpp index 53ec017..21620c9 100644 --- a/src/constants.cpp +++ b/src/constants.cpp @@ -18,6 +18,7 @@ limitations under the License. #define COMMAND_UK 1 #define COMMAND_ENSTROPHY 2 #define COMMAND_QUIET 3 +#define COMMAND_RESUME 4 #define DRIVING_ZERO 1 #define DRIVING_TEST 2 diff --git a/src/main.c b/src/main.c index eedc1e5..a72278e 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,7 @@ limitations under the License. #include #include #include +#include #include "constants.cpp" #include "driving.h" @@ -61,9 +62,12 @@ int print_usage(); int print_params(nstrophy_parameters parameters, char* initfile_str, char* drivingfile_str, FILE* file); // read command line arguments -int read_args(int argc, const char* argv[], char** params, unsigned int* command, unsigned int* nthreads, char** savefile_str, char** utfile_str); +int read_args(int argc, const char* argv[], char** params, unsigned int* command, unsigned int* nthreads, char** savefile_str, char** utfile_str, char** resumefile_str); +int set_default_params(nstrophy_parameters* parameters); int read_params(char* param_str, nstrophy_parameters* parameters, char** initfile_str, char** drivingfile_str); int set_parameter(char* lhs, char* rhs, nstrophy_parameters* parameters, bool* setN1, bool* setN2, char** initfile_str, char** drivingfile_str); +// read args from file +int args_from_file(char** params, unsigned int* command, unsigned int* nthreads, char** savefile_str, char** utfile_str, char* file_str); // set driving force _Complex double* set_driving(nstrophy_parameters parameters); @@ -77,9 +81,17 @@ void sig_handler (int signo); volatile bool g_abort = false; // signal handler void sig_handler (int signo){ - if (signo == SIGINT || signo == SIGTERM){ + if (signo == SIGINT){ + fprintf(stderr,"received signal SIGINT, interrupting computation\n"); g_abort = true; } + else if (signo == SIGTERM){ + fprintf(stderr,"received signal SIGTERM, interrupting computation\n"); + g_abort = true; + } + else{ + fprintf(stderr,"received signal %d\n",signo); + } } @@ -98,23 +110,50 @@ int main ( char* utfile_str=NULL; char* initfile_str=NULL; char* drivingfile_str=NULL; + char* resumefile_str=NULL; FILE* savefile=NULL; FILE* utfile=NULL; command=0; // read command line arguments - ret=read_args(argc, argv, ¶m_str, &command, &nthreads, &savefile_str, &utfile_str); + ret=read_args(argc, argv, ¶m_str, &command, &nthreads, &savefile_str, &utfile_str, &resumefile_str); if(ret<0){ return(-1); } + // set default params + set_default_params(¶meters); // read params ret=read_params(param_str, ¶meters, &initfile_str, &drivingfile_str); if(ret<0){ return(-1); } + // if command is 'resume', then read args from file + if(command==COMMAND_RESUME){ + ret=args_from_file(¶m_str, &command, &nthreads, &savefile_str, &utfile_str, resumefile_str); + if(ret<0){ + return(-1); + } + // read params + ret=read_params(param_str, ¶meters, &initfile_str, &drivingfile_str); + if(ret<0){ + return(-1); + } + + // reread arguments (to allow overrides from the command line) + ret=read_args(argc, argv, ¶m_str, &command, &nthreads, &savefile_str, &utfile_str, &resumefile_str); + if(ret<0){ + return(-1); + } + // reread params + ret=read_params(param_str, ¶meters, &initfile_str, &drivingfile_str); + if(ret<0){ + return(-1); + } + } + // open initfile if(initfile_str!=NULL){ parameters.initfile=fopen(initfile_str,"r"); @@ -213,7 +252,7 @@ int main ( // usage message int print_usage(){ - fprintf(stderr, "usage:\n nstrophy [-t nthreads] [-p parameters] [-s savefile] [-u u_outfile] \n\n"); + fprintf(stderr, "usage:\n nstrophy [-t nthreads] [-p parameters] [-s savefile] [-u u_outfile] \n where is one of\n enstrophy\n uk\n quiet\n resume \n\n"); return(0); } @@ -319,6 +358,7 @@ int print_params( #define CP_FLAG_NTHREADS 2 #define CP_FLAG_SAVEFILE 3 #define CP_FLAG_UTFILE 4 +#define CP_FLAG_RESUME 5 int read_args( int argc, const char* argv[], @@ -326,7 +366,8 @@ int read_args( unsigned int* command, unsigned int* nthreads, char** savefile_str, - char** utfile_str + char** utfile_str, + char** resumefile_str ){ int i; int ret; @@ -385,6 +426,11 @@ int read_args( *utfile_str=(char*)argv[i]; flag=0; } + // resume file + else if(flag==CP_FLAG_RESUME){ + *resumefile_str=(char*)argv[i]; + flag=0; + } // computation to run else{ if(strcmp(argv[i], "uk")==0){ @@ -396,37 +442,31 @@ int read_args( else if(strcmp(argv[i], "quiet")==0){ *command=COMMAND_QUIET; } + else if(strcmp(argv[i], "resume")==0){ + *command=COMMAND_RESUME; + flag=CP_FLAG_RESUME; + } else{ fprintf(stderr, "error: unrecognized command: '%s'\n",argv[i]); return(-1); } - flag=0; } } + // check that if the command is 'resume', then resumefile has been set + if(*command==COMMAND_RESUME && *resumefile_str==NULL){ + fprintf(stderr, "error: 'resume' command used, but no resume file\n"); + print_usage(); + return(-1); + } + return(0); } -// read parameters string -int read_params( - char* param_str, - nstrophy_parameters* parameters, - char** initfile_str, - char** drivingfile_str +// set default parameters +int set_default_params( + nstrophy_parameters* parameters ){ - int ret; - // pointer in params - char* ptr; - // buffer and associated pointer - char *buffer_lhs, *lhs_ptr; - char *buffer_rhs, *rhs_ptr; - // whether N was set explicitly - bool setN1=false; - bool setN2=false; - // whether lhs (false is rhs) - bool lhs=true; - - // defaults parameters->init_en=1.54511597324389e+02; parameters->irreversible=true; parameters->K1=16; @@ -450,6 +490,28 @@ int read_params( parameters->initfile=NULL; parameters->algorithm=ALGORITHM_RK4; parameters->keep_en_cst=false; + + return(0); +} + +// read parameters string +int read_params( + char* param_str, + nstrophy_parameters* parameters, + char** initfile_str, + char** drivingfile_str +){ + int ret; + // pointer in params + char* ptr; + // buffer and associated pointer + char *buffer_lhs, *lhs_ptr; + char *buffer_rhs, *rhs_ptr; + // whether N was set explicitly + bool setN1=false; + bool setN2=false; + // whether lhs (false is rhs) + bool lhs=true; if (param_str!=NULL){ // init @@ -775,6 +837,87 @@ int set_parameter( return(0); } +// read args from file +int args_from_file( + char** params, + unsigned int* command, + unsigned int* nthreads, + char** savefile_str, + char** utfile_str, + char* file_str +){ + char* line; + unsigned int len=256; + unsigned int pos=0; + char* line_realloc; + char c; + + // open file + FILE* file=fopen(file_str,"r"); + if(file==NULL){ + fprintf(stderr,"Error opening file '%s' for reading: %s\n", file_str, strerror(errno)); + return(-1); + } + + // allocate line buffer + line=calloc(sizeof(char), len); + + while(1){ + c=fgetc(file); + + // end of file + if (feof(file)){ + break; + } + + // newline: read line and reset buffer + if(c=='\n' || c=='\r'){ + // read entry + // ignore lines with fewer than three characters + if(pos>=3){ + // find line starting with "#!" + if(line[0]=='#' && line[1]=='!'){ + wordexp_t pwordexp; + wordexp(line+2,&pwordexp,0); + // read arguments + read_args(pwordexp.we_wordc, (const char **)pwordexp.we_wordv, params, command, nthreads, savefile_str, utfile_str, NULL); + wordfree(&pwordexp); + // exit + break; + } + } + + // reset buffer + pos=0; + line[pos]='\0'; + } + // add to buffer + else { + // check that there is room in buffer + if(pos==len){ + // too short: reallocate + line_realloc=calloc(sizeof(char), 2*len); + for(pos=0;pos