1 /*
2 ! @file benchmark_hdf5.F90
3 ! @author M. Scot Breitenfeld <brtnfld@hdfgroup.org>
4 ! @version 0.1
5 !
6 ! @section LICENSE
7 ! BSD style license
8 !
9 ! @section DESCRIPTION
10 ! Benchmarking program for pcgns library
11 !
12 ! TO COMPILE: h5pcc -O2 benchmark_hdf5.c -I.. -L../lib -lcgns
13 !
14 */
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <math.h>
19 
20 #include "pcgnslib.h"
21 #include "mpi.h"
22 
23 #define false 0
24 #define true 1
25 
26 int comm_size;
27 int comm_rank;
28 MPI_Info info;
29 
30 /* cgsize_t Nelem = 33554432; */
31 cgsize_t Nelem = 262144;
32 cgsize_t NodePerElem = 512;
33 
34 cgsize_t Nnodes;
35 int mpi_err;
36 int err;
37 int comm_size;
38 int comm_rank;
39 int fn;
40 int B;
41 int Z;
42 int S;
43 int Cx,Cy,Cz, Fx, Fy, Fz, Ar, Ai;
44 int cell_dim = 3;
45 int phys_dim = 3;
46 int r_cell_dim = 0;
47 int r_phys_dim = 0;
48 cgsize_t nijk[3], sizes[3];
49 cgsize_t size_1D[1];
50 cgsize_t min, max;
51 int k, count;
52 /* For writing and reading data*/
53 double* Coor_x;
54 double* Coor_y;
55 double* Coor_z;
56 double* Data_Fx;
57 double* Data_Fy;
58 double* Data_Fz;
59 double* Array_r;
60 cgsize_t* Array_i;
61 cgsize_t start, end, emin, emax;
62 cgsize_t* elements;
63 char name[33];
64 int queue, debug;
65 double t0, t1, t2;
66 
67 /*
68  * Timing storage convention:
69  * timing(0) = Total program time
70  * timing(1) = Time to write nodal coordinates
71  * timing(2) = Time to write connectivity table
72  * timing(3) = Time to write solution data (field data)
73  * timing(4) = Time to write array data
74  * timing(5) = Time to read nodal coordinates
75  * timing(6) = Time to read connectivity table
76  * timing(7) = Time to read solution data (field data)
77  * timing(8) = Time to read array data
78  * timing(9) = Time for cgp_open, CG_MODE_WRITE
79  * timing(10) = Time for cg_base_write
80  * timing(11) = Time for cg_zone_write
81  * timing(12) = Time for cgp_open, CG_MODE_READ
82  * timing(13) = Time for cg_read_write
83  * timing(14) = Time for cg_read_write
84  */
85 double xtiming[15], timing[15], timingMin[15], timingMax[15];
86 
87 int piomode[2] = {0, 1};
88 int piomode_i;
89 
initialize(int * argc,char ** argv[])90 int initialize(int* argc, char** argv[]) {
91 	MPI_Init(argc,argv);
92 	MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
93 	MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
94 	MPI_Info_create(&info);
95 	MPI_Info_set(info, "striping_unit", "8388608");
96 	/* or whatever your GPFS block size actually is*/
97 	return 0;
98 }
99 
c_double_eq(double a,double b)100 int c_double_eq(double a, double b) {
101 
102   double eps = 1.e-8;
103 
104   if(fabs(a-b) < eps) {
105     return true;
106   }
107   return false;
108 }
109 
main(int argc,char * argv[])110 int main(int argc, char* argv[]) {
111   /* Initialize variables */
112   initialize(&argc,&argv);
113 
114   char fname[32];
115   char name[32];
116   int Cvec[3];
117   int Fvec[3];
118   int Avec[2];
119 
120   /* parameters */
121   piomode_i = 1;
122   queue = false;
123   debug = false;
124 
125   t0 = MPI_Wtime(); /* Timer */
126 
127   err = (int)cgp_mpi_info(info)
128   err = (int)cgp_pio_mode((CGNS_ENUMT(PIOmode_t))piomode_i);
129 
130   Nnodes = Nelem*NodePerElem;
131 
132   nijk[0] = Nnodes; /* Number of vertices */
133   nijk[1] = Nelem; /* Number of cells */
134   nijk[2] = 0; /* Number of boundary vertices */
135 
136   /* ====================================== */
137   /* ==    **WRITE THE CGNS FILE **      == */
138   /* ====================================== */
139 
140   sprintf(fname, "benchmark_%06d.cgns", comm_size);
141 
142   t1 = MPI_Wtime();
143   if(cgp_open(fname, CG_MODE_WRITE, &fn) != CG_OK) {
144     printf("*FAILED* cgp_open \n");
145     cgp_error_exit();
146   }
147   t2 = MPI_Wtime();
148   xtiming[9] = t2-t1;
149 
150   t1 = MPI_Wtime();
151   if(cg_base_write(fn, "Base 1", cell_dim, phys_dim, &B) != CG_OK) {
152     printf("*FAILED* cg_base_write \n");
153     cgp_error_exit();
154   }
155   t2 = MPI_Wtime();
156   xtiming[10] = t2-t1;
157 
158   t1 = MPI_Wtime();
159   if(cg_zone_write(fn, B, "Zone 1", nijk, Unstructured, &Z) != CG_OK) {
160     printf("*FAILED* cg_zone_write \n");
161     cgp_error_exit();
162   t2 = MPI_Wtime();
163   xtiming[11] = t2-t1;
164 
165   }
166 
167   /* ====================================== */
168   /* == (C) WRITE THE FIELD DATA         == */
169   /* ====================================== */
170 
171   count = nijk[0]/comm_size;
172 
173   min = count*comm_rank+1;
174   max = count*(comm_rank+1);
175 
176   if( !(Data_Fx = (double*) malloc(count*sizeof(double))) ) {
177     printf("*FAILED* allocation of Data_Fx \n");
178     cgp_error_exit();
179   }
180 
181   if( !(Data_Fy= (double*) malloc(count*sizeof(double))) ) {
182     printf("*FAILED* allocation of Data_Fy \n");
183     cgp_error_exit();
184   }
185 
186   if( !(Data_Fz= (double*) malloc(count*sizeof(double))) ) {
187     printf("*FAILED* allocation of Data_Fz \n");
188     cgp_error_exit();
189   }
190 
191   for ( k = 0; k < count; k++) {
192      Data_Fx[k] = comm_rank*count+k + 1.01;
193      Data_Fy[k] = comm_rank*count+k + 1.02;
194      Data_Fz[k] = comm_rank*count+k + 1.03;
195   }
196 
197   if(cg_sol_write(fn, B, Z, "Solution", Vertex, &S) != CG_OK) {
198     printf("*FAILED* cg_sol_write \n");
199     cgp_error_exit();
200   }
201 
202   if(cgp_field_write(fn,B,Z,S,CGNS_ENUMV(RealDouble),"MomentumX",&Fx) != CG_OK) {
203     printf("*FAILED* cgp_field_write (MomentumX) \n");
204     cgp_error_exit();
205   }
206   if(cgp_field_write(fn,B,Z,S,CGNS_ENUMV(RealDouble),"MomentumY",&Fy) != CG_OK) {
207     printf("*FAILED* cgp_field_write (MomentumY) \n");
208     cgp_error_exit();
209   }
210   if(cgp_field_write(fn,B,Z,S,CGNS_ENUMV(RealDouble),"MomentumZ",&Fz) != CG_OK) {
211     printf("*FAILED* cgp_field_write (MomentumZ) \n");
212     cgp_error_exit();
213   }
214 
215   t1 = MPI_Wtime();
216 
217 
218 #if HDF5_HAVE_MULTI_DATASETS
219 
220   Fvec[0] = Fx;
221   Fvec[1] = Fy;
222   Fvec[2] = Fz;
223 
224   if(cgp_field_multi_write_data(fn,B,Z,S,Fvec,&min,&max,3,Data_Fx,Data_Fy,Data_Fz) != CG_OK) {
225     printf("*FAILED* cgp_field_multi_write_data \n");
226     cgp_error_exit();
227   }
228 #else
229   if(cgp_field_write_data(fn,B,Z,S,Fx,&min,&max,Data_Fx) != CG_OK) {
230     printf("*FAILED* cgp_field_write_data (Data_Fx) \n");
231     cgp_error_exit();
232   }
233   if(cgp_field_write_data(fn,B,Z,S,Fy,&min,&max,Data_Fy) != CG_OK) {
234     printf("*FAILED* cgp_field_write_data (Data_Fy)\n");
235     cgp_error_exit();
236   }
237   if(cgp_field_write_data(fn,B,Z,S,Fz,&min,&max,Data_Fz) != CG_OK) {
238     printf("*FAILED* cgp_field_write_data (Data_Fz)\n");
239     cgp_error_exit();
240   }
241 #endif
242   t2 = MPI_Wtime();
243   xtiming[3] = t2-t1;
244 
245   if(!queue) {
246     free(Data_Fx);
247     free(Data_Fy);
248     free(Data_Fz);
249   }
250 
251   if(cgp_close(fn) !=CG_OK) {
252      printf("*FAILED* cgp_close\n");
253      cgp_error_exit();
254   }
255 
256   xtiming[0] = t2-t0;
257 
258   MPI_Reduce(&xtiming, &timing, 15, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
259   MPI_Reduce(&xtiming, &timingMin, 15, MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD);
260   MPI_Reduce(&xtiming, &timingMax, 15, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
261 
262   if(comm_rank==0) {
263     sprintf(fname, "timing_%06d_%d.dat", comm_size, piomode_i+1);
264     FILE *fid = fopen(fname, "w");
265     if (fid == NULL) {
266       printf("Error opening timing file!\n");
267     } else {
268       fprintf(fid,"#nprocs, wcoord, welem, wfield, warray, rcoord, relem, rfield, rarray \n%d", comm_size);
269 
270       for ( k = 0; k < 15; k++) {
271 	fprintf(fid," %20f %20f %20f ",timing[k]/((double) comm_size), timingMin[k], timingMax[k]);
272       }
273       fprintf(fid,"\n");
274     }
275   }
276 
277   MPI_Finalize();
278 
279   return 0;
280 }
281 
282 
283