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 = 1073741824;
32 cgsize_t NodePerElem = 6;
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 cgsize_t 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   /* use queued IO */
167   if(cgp_queue_set(queue) != CG_OK) {
168     printf("*FAILED* cgp_queue_set \n");
169     cgp_error_exit();
170   }
171 
172   /* ====================================== */
173   /* == (A) WRITE THE NODAL COORDINATES  == */
174   /* ====================================== */
175 
176   count = nijk[0]/comm_size;
177 
178   if( !(Coor_x = (double*) malloc(count*sizeof(double))) ) {
179     printf("*FAILED* allocation of Coor_x \n");
180     cgp_error_exit();
181   }
182 
183   min = count*comm_rank+1;
184   max = count*(comm_rank+1);
185 
186   for (k=0; k < count; k++) {
187     Coor_x[k] = comm_rank*count + k + 1.1;
188   }
189 
190   if(cgp_coord_write(fn,B,Z,CGNS_ENUMV(RealDouble),"CoordinateX",&Cx) != CG_OK) {
191     printf("*FAILED* cgp_coord_write (Coor_x) \n");
192     cgp_error_exit();
193   }
194 
195   t1 = MPI_Wtime();
196   if((cgp_coord_write_data(fn,B,Z,Cx,&min,&max,Coor_x)) != CG_OK) {
197     printf("*FAILED* cgp_coord_write_data (Coor_x) \n");
198     cgp_error_exit();
199   }
200   t2 = MPI_Wtime();
201   xtiming[1] = t2-t1;
202 
203   if(!queue) {
204     free(Coor_x);
205   }
206 
207   if(cgp_close(fn) != CG_OK) {
208     printf("*FAILED* cgp_close \n");
209     cgp_error_exit();
210   };
211 
212   xtiming[0] = t2-t0;
213 
214   MPI_Reduce(&xtiming, &timing, 15, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
215   MPI_Reduce(&xtiming, &timingMin, 15, MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD);
216   MPI_Reduce(&xtiming, &timingMax, 15, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
217 
218   if(comm_rank==0) {
219     sprintf(fname, "timing_%06d_%d.dat", comm_size, piomode_i+1);
220     FILE *fid = fopen(fname, "w");
221     if (fid == NULL) {
222       printf("Error opening timing file!\n");
223     } else {
224       fprintf(fid,"#nprocs, wcoord, welem, wfield, warray, rcoord, relem, rfield, rarray \n%d", comm_size);
225 
226       for ( k = 0; k < 15; k++) {
227 	fprintf(fid," %20f %20f %20f ",timing[k]/((double) comm_size), timingMin[k], timingMax[k]);
228       }
229       fprintf(fid,"\n");
230     }
231   }
232 
233   MPI_Finalize();
234 
235   return 0;
236 }
237 
238 
239