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