1 /*----------------------------------------------------------------------
2   exx_file_eri.c
3 
4   Coded by M. Toyoda, 25/NOV/2009
5 ----------------------------------------------------------------------*/
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <assert.h>
10 #include "exx.h"
11 #include "exx_log.h"
12 #include "exx_file_eri.h"
13 #include <mpi.h>
14 
cachefile_path(char * path,size_t len,const char * cachedir)15 static void cachefile_path(char *path, size_t len, const char *cachedir)
16 {
17   int rank;
18 
19 #ifdef EXX_USE_MPI
20   MPI_Comm_rank(g_exx_mpicomm, &rank);
21 #else
22   rank = EXX_ROOT_RANK;
23 #endif
24 
25   snprintf(path, len, "%s/eri%03d.dat", cachedir, rank);
26 }
27 
28 
29 
EXX_File_ERI_Create(const EXX_t * exx)30 void EXX_File_ERI_Create(const EXX_t *exx)
31 {
32   int n;
33   FILE *fp;
34   char path[EXX_PATHLEN];
35   size_t sz;
36 
37   cachefile_path(path, EXX_PATHLEN, EXX_CacheDir(exx));
38 
39   fp = fopen(path, "wb");
40 
41   /* write record number which is zero at this stage */
42   n = 0;
43   sz = fwrite(&n, sizeof(int), 1, fp);
44 
45   fclose(fp);
46 }
47 
48 
EXX_File_ERI_Write(const EXX_t * exx,const double * eri,int iop1,int iop2,int nb1,int nb2,int nb3,int nb4,int nrn,const int * iRd)49 void EXX_File_ERI_Write(
50   const EXX_t  *exx,
51   const double *eri, /* [nb1*nb2*nb3*nb4*nrn] */
52   int           iop1,
53   int           iop2,
54   int           nb1,
55   int           nb2,
56   int           nb3,
57   int           nb4,
58   int           nrn,
59   const int    *iRd  /* [nrn] */
60 )
61 {
62   int neri, nr, stat;
63   FILE *fp;
64   char path[EXX_PATHLEN];
65   size_t sz;
66 
67   cachefile_path(path, EXX_PATHLEN, EXX_CacheDir(exx));
68 
69   /* open file in 'append' mode */
70   fp = fopen(path, "ab");
71 
72   /* write header information */
73   sz = fwrite(&iop1, sizeof(int), 1, fp);
74   sz = fwrite(&iop2, sizeof(int), 1, fp);
75   sz = fwrite(&nb1,  sizeof(int), 1, fp);
76   sz = fwrite(&nb2,  sizeof(int), 1, fp);
77   sz = fwrite(&nb3,  sizeof(int), 1, fp);
78   sz = fwrite(&nb4,  sizeof(int), 1, fp);
79   sz = fwrite(&nrn,  sizeof(int), 1, fp);
80   sz = fwrite(iRd,   sizeof(int), nrn, fp);
81 
82   /* write ERIs */
83   neri = nb1*nb2*nb3*nb4*nrn;
84   sz = fwrite(eri, sizeof(double), neri, fp);
85 
86   /* close file */
87   fclose(fp);
88 
89   /* open file again in 'write-read' mode */
90   fp = fopen(path, "r+b");
91 
92   /* increment record number */
93   fseek(fp, 0, SEEK_SET);
94   sz = fread(&nr, sizeof(int), 1, fp);
95   nr++;
96   fseek(fp, 0, SEEK_SET);
97   sz = fwrite(&nr, sizeof(int), 1, fp);
98 
99   /* close file */
100   fclose(fp);
101 }
102 
103 
104 
105 
EXX_File_ERI_Read_NRecord(const EXX_t * exx)106 int EXX_File_ERI_Read_NRecord(const EXX_t *exx)
107 {
108   int n;
109   FILE *fp;
110   char path[EXX_PATHLEN];
111   size_t sz;
112 
113   cachefile_path(path, EXX_PATHLEN, EXX_CacheDir(exx));
114 
115   fp = fopen(path, "rb");
116   sz = fread(&n, sizeof(int), 1, fp);
117   fclose(fp);
118 
119   return n;
120 }
121 
122 
123 
EXX_File_ERI_Read_Data_Head(const EXX_t * exx,int record,int * out_iop1,int * out_iop2,int * out_nb1,int * out_nb2,int * out_nb3,int * out_nb4,int * out_nrn)124 void EXX_File_ERI_Read_Data_Head(
125   const EXX_t *exx,
126   int         record,
127   int        *out_iop1,
128   int        *out_iop2,
129   int        *out_nb1,
130   int        *out_nb2,
131   int        *out_nb3,
132   int        *out_nb4,
133   int        *out_nrn
134 )
135 {
136   int i, nr, iop1, iop2, nb1, nb2, nb3, nb4, nrn;
137   FILE *fp;
138   char path[EXX_PATHLEN];
139   size_t cb, sz;
140 
141   cachefile_path(path, EXX_PATHLEN, EXX_CacheDir(exx));
142 
143   /* open file */
144   fp = fopen(path, "rb");
145 
146   /* boundary check */
147   sz = fread(&nr, sizeof(int), 1, fp);
148   if (nr<record) {
149     fprintf(stderr, "  record= %d nr= %d\n", record, nr);
150     EXX_ERROR("record number is too large");
151   }
152 
153   /* seeking */
154   for (i=0; i<record; i++) {
155     /* read header information */
156     sz = fread(&iop1, sizeof(int), 1, fp);
157     sz = fread(&iop2, sizeof(int), 1, fp);
158     sz = fread(&nb1,  sizeof(int), 1, fp);
159     sz = fread(&nb2,  sizeof(int), 1, fp);
160     sz = fread(&nb3,  sizeof(int), 1, fp);
161     sz = fread(&nb4,  sizeof(int), 1, fp);
162     sz = fread(&nrn,  sizeof(int), 1, fp);
163 
164     /* skip iRd data */
165     cb = sizeof(int)*nrn;
166     fseek(fp, (long)cb, SEEK_CUR);
167 
168     /* skip ERIs */
169     cb = sizeof(double)*nb1*nb2*nb3*nb4*nrn;
170     fseek(fp, (long)cb, SEEK_CUR);
171   }
172 
173   /* read requested header data */
174   sz = fread(out_iop1, sizeof(int), 1, fp);
175   sz = fread(out_iop2, sizeof(int), 1, fp);
176   sz = fread(out_nb1,  sizeof(int), 1, fp);
177   sz = fread(out_nb2,  sizeof(int), 1, fp);
178   sz = fread(out_nb3,  sizeof(int), 1, fp);
179   sz = fread(out_nb4,  sizeof(int), 1, fp);
180   sz = fread(out_nrn,  sizeof(int), 1, fp);
181 
182   fclose(fp);
183 }
184 
185 
EXX_File_ERI_Read(const EXX_t * exx,int record,double * out_eri,int * out_iRd,int in_iop1,int in_iop2,int in_nrn,int in_neri)186 void EXX_File_ERI_Read(
187   const EXX_t *exx,
188   int         record,
189   double     *out_eri, /* [in_n] */
190   int        *out_iRd, /* [in_n] */
191   int         in_iop1,
192   int         in_iop2,
193   int         in_nrn,
194   int         in_neri
195 )
196 {
197   int i, neri, nr, iop1, iop2, nb1, nb2, nb3, nb4, nrn;
198   FILE *fp;
199   char path[EXX_PATHLEN];
200   size_t sz, cb;
201 
202   cachefile_path(path, EXX_PATHLEN, EXX_CacheDir(exx));
203 
204   /* open file */
205   fp = fopen(path, "rb");
206 
207   /* boundary check */
208   sz = fread(&nr, sizeof(int), 1, fp);
209   if (nr<record) {
210     fprintf(stderr, "  record= %d nr= %d\n", record, nr);
211     EXX_ERROR("record number is too large");
212   }
213 
214   /* seeking */
215   for (i=0; i<record; i++) {
216     sz = fread(&iop1, sizeof(int), 1, fp);
217     sz = fread(&iop2, sizeof(int), 1, fp);
218     sz = fread(&nb1,  sizeof(int), 1, fp);
219     sz = fread(&nb2,  sizeof(int), 1, fp);
220     sz = fread(&nb3,  sizeof(int), 1, fp);
221     sz = fread(&nb4,  sizeof(int), 1, fp);
222     sz = fread(&nrn,  sizeof(int), 1, fp);
223 
224     /* skip R data */
225     cb = sizeof(int)*nrn;
226     fseek(fp, (long)cb, SEEK_CUR);
227 
228     /* skip ERI */
229     cb = sizeof(double)*nb1*nb2*nb3*nb4*nrn;
230     fseek(fp, (long)cb, SEEK_CUR);
231   }
232 
233   /* read header information */
234   sz = fread(&iop1, sizeof(int), 1, fp);
235   sz = fread(&iop2, sizeof(int), 1, fp);
236   sz = fread(&nb1,  sizeof(int), 1, fp);
237   sz = fread(&nb2,  sizeof(int), 1, fp);
238   sz = fread(&nb3,  sizeof(int), 1, fp);
239   sz = fread(&nb4,  sizeof(int), 1, fp);
240   sz = fread(&nrn,  sizeof(int), 1, fp);
241 
242   /* buffer length */
243   neri = nb1*nb2*nb3*nb4*nrn;
244 
245   /* check consistency */
246   if (neri != in_neri || nrn != in_nrn) { EXX_ERROR("file is broken"); }
247 
248   /* read R data */
249   if (out_iRd) {
250     sz = fread(out_iRd, sizeof(int), nrn, fp);
251   } else {
252     fseek(fp, sizeof(int)*nrn, SEEK_CUR);
253   }
254 
255   /* read ERI data */
256   if (out_eri) { sz = fread(out_eri, sizeof(double), neri, fp); }
257 
258   /* close file */
259   fclose(fp);
260 }
261 
262 
263 
264 
265