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