Ubuntu 14.04 LTS Japanese Remix
on VMWare Fusion v8.5.2 (4635224)
on OS X El Captian v10.11.4
GNU bash, version 4.3.11(1)-release
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
(also for g++)
ADDA v.1.3b6
This article is related to ADDA (light scattering simulator based on the discrete dipole approximation).
Related: http://qiita.com/7of9/items/9537252c79f5318d8f55
Related: http://qiita.com/7of9/items/4966f131d405cd89ee07
Related: http://qiita.com/7of9/items/0d477f8f84445ce35c3d
In order to read Chpoint file, we need auxiliary information shown below:
- params[ind_m].sc_N
- scalars[i].size
- params[ind_m].vec_N
- vectors[i].size
There may be two ways to store these values:
- Modify the Chpoint file format
- Disadvantage: reading part of the Chpoint file also need to be modified
- Disadvantage: causes conflict to the update of the ADDA
- Output as separate file
- Advantage: can be removed easily
- Advantage: can follow the update of ADDA
I chose the second.
modification of the code
I modify the iterative.c
- Added
#define OUTPUT_AUX_FILE
and related - Added
if (output_auxfile) {
and related
This way, we can disable the output feature just by comment out #define OUTPUT_AUX_FILE
. I decided to follow the way using const bool output_auxfile = true;
as suggested by @nonbiri15.
In Japanese.
#define OUTPUT_AUX_FILE // to output auxiliary values
#ifdef OUTPUT_AUX_FILE
const bool output_auxfile = true;
#else
const bool output_auxfile = false;
#endif
static void SaveIterChpoint(void)
/* save a binary checkpoint; only limitedly foolproof - user should take care to load checkpoints on the same machine
* (number of processors) and with the same command line.
*/
{
int i;
char fname[MAX_FNAME];
FILE * restrict chp_file;
TIME_TYPE tstart;
// to store auxiliary values required to read Chpoint file by tools
FILE * restrict aux_file;
char fauxName[MAX_FNAME];
tstart=GET_TIME();
if (IFROOT) {
// create directory "chp_dir" if needed and open info file
SnprintfErr(ONE_POS,fname,MAX_FNAME,"%s/"F_CHP_LOG,chp_dir);
if ((chp_file=fopen(fname,"w"))==NULL) {
MkDirErr(chp_dir,ONE_POS);
chp_file=FOpenErr(fname,"w",ONE_POS);
}
// write info and close file
fprintf(chp_file,"Info about the run, which produced the checkpoint, can be found in ../%s",directory);
FCloseErr(chp_file,fname,ONE_POS);
}
// wait to ensure that directory exists
Synchronize();
// open output file; writing errors are checked only for vectors
SnprintfErr(ALL_POS,fname,MAX_FNAME,"%s/"F_CHP,chp_dir,ringid);
chp_file=FOpenErr(fname,"wb",ALL_POS);
if (output_auxfile) {
SnprintfErr(ALL_POS,fauxName,MAX_FNAME,"%s/aux.0",chp_dir);
fprintf(stdout, "\r\n[DEBUG] Line220>SaveIterChpoint: %s\r\n", fauxName);
aux_file=FOpenErr(fauxName,"wb",ALL_POS);
}
// write common scalars
fwrite(&ind_m,sizeof(int),1,chp_file);
fwrite(&local_nRows,sizeof(size_t),1,chp_file);
fwrite(&niter,sizeof(int),1,chp_file);
fwrite(&counter,sizeof(int),1,chp_file);
fwrite(&inprodR,sizeof(double),1,chp_file);
fwrite(&prev_err,sizeof(double),1,chp_file); // written on ALL processors but used only on root
fwrite(&resid_scale,sizeof(double),1,chp_file);
// write specific scalars
for (i=0;i<params[ind_m].sc_N;i++) fwrite(scalars[i].ptr,scalars[i].size,1,chp_file);
// write common vectors
if (fwrite(xvec,sizeof(doublecomplex),local_nRows,chp_file)!=local_nRows)
LogError(ALL_POS,"Failed writing to file '%s'",fname);
if (fwrite(rvec,sizeof(doublecomplex),local_nRows,chp_file)!=local_nRows)
LogError(ALL_POS,"Failed writing to file '%s'",fname);
if (fwrite(pvec,sizeof(doublecomplex),local_nRows,chp_file)!=local_nRows)
LogError(ALL_POS,"Failed writing to file '%s'",fname);
// write specific vectors
for (i=0;i<params[ind_m].vec_N;i++) if (fwrite(vectors[i].ptr,vectors[i].size,local_nRows,chp_file)!=local_nRows)
LogError(ALL_POS,"Failed writing to file '%s'",fname);
if (output_auxfile) {
fwrite(&(params[ind_m].sc_N), sizeof(int), 1, aux_file);
for (i=0;i<params[ind_m].sc_N;i++) {
fwrite(&(scalars[i].size), sizeof(int), 1, aux_file);
}
fwrite(&(params[ind_m].vec_N), sizeof(int), 1, aux_file);
for (i=0;i<params[ind_m].vec_N;i++) {
fwrite(&(vectors[i].size), sizeof(int), 1, aux_file);
}
fprintf(stdout, "[DEBUG] Line254>SaveIterChpoint: sc_N=%d\r\n", params[ind_m].sc_N);
for (i=0;i<params[ind_m].sc_N;i++) {
fprintf(stdout, "[DEBUG] Line256>SaveIterChpoint: scalars.size=%d\r\n", scalars[i].size);
}
fprintf(stdout, "[DEBUG] Line258>SaveIterChpoint: vec_N=%d\r\n", params[ind_m].vec_N);
for (i=0;i<params[ind_m].vec_N;i++) {
fprintf(stdout, "[DEBUG] Line260>SaveIterChpoint: vectors.size=%d\r\n", vectors[i].size);
}
}
// close file
FCloseErr(chp_file,fname,ALL_POS);
if (output_auxfile) {
FCloseErr(aux_file,fauxName,ALL_POS);
}
// write info to logfile after everyone is finished
Synchronize();
if (IFROOT) PrintBoth(logfile,"Checkpoint (iteration) saved\n");
Timing_FileIO+=GET_TIME()-tstart;
Synchronize(); // this is to ensure that message above appears if and only if OK
}
test run (#define OUTPUT_AUX_FILE
enabled)
$ ./adda -grid 25 -chp_type normal -chpoint 1s > log
$ tail -n 20 log
RE_052 = 3.3098144752E-01 +
RE_053 = 3.2839613884E-01 +
RE_054 = 3.2540677697E-01 +
RE_055 = 3.2272283461E-01 +
[DEBUG] Line220>SaveIterChpoint: chpoint/aux.0
[DEBUG] Line254>SaveIterChpoint: sc_N=8
[DEBUG] Line256>SaveIterChpoint: scalars.size=8
[DEBUG] Line256>SaveIterChpoint: scalars.size=8
[DEBUG] Line256>SaveIterChpoint: scalars.size=8
[DEBUG] Line256>SaveIterChpoint: scalars.size=8
[DEBUG] Line256>SaveIterChpoint: scalars.size=16
[DEBUG] Line256>SaveIterChpoint: scalars.size=16
[DEBUG] Line256>SaveIterChpoint: scalars.size=16
[DEBUG] Line256>SaveIterChpoint: scalars.size=16
[DEBUG] Line258>SaveIterChpoint: vec_N=3
[DEBUG] Line260>SaveIterChpoint: vectors.size=16
[DEBUG] Line260>SaveIterChpoint: vectors.size=16
[DEBUG] Line260>SaveIterChpoint: vectors.size=16
Checkpoint (iteration) saved
$ ls chpoint/
aux.0 chp.0 chp.log
By reading aux.0 and chp.0, we can fully recover the values output to chp.0 from tools.