1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <time.h>
4+
5+ #include "hdf5.h"
6+ #ifdef CONTAINS_MPI
7+ #include "mpi.h"
8+ #endif
9+ #include "selected_kernel.h"
10+
11+ hid_t open_hdf5_file (char * file ) {
12+ return H5Fopen (file , H5F_ACC_RDONLY , H5P_DEFAULT );
13+ }
14+ hid_t open_hdf5_dataset (hid_t file_id , char * dataset ) {
15+ return H5Dopen2 (file_id , dataset , H5P_DEFAULT );
16+ }
17+ float * read_float_dataset (hid_t dataset_id ) {
18+ hid_t dataspace ;
19+ hsize_t dims_out [10 ];
20+ int rank , total_size ;
21+
22+ dataspace = H5Dget_space (dataset_id ); /* dataspace handle */
23+ rank = H5Sget_simple_extent_ndims (dataspace );
24+ H5Sget_simple_extent_dims (dataspace , dims_out , NULL );
25+
26+ total_size = 1 ;
27+ for (size_t i = 0 ; i < rank ; i ++ ) {
28+ total_size *= dims_out [i ];
29+ }
30+
31+ float * dset_data = malloc (sizeof (float ) * total_size );
32+ H5Dread (dataset_id , H5T_NATIVE_FLOAT , H5S_ALL , H5S_ALL , H5P_DEFAULT ,
33+ dset_data );
34+ return dset_data ;
35+ }
36+ float read_float_attribute (hid_t dataset_id , char * attribute_name ) {
37+ // Gets attribute value from a dataset in a file
38+ // Ex: file example_data.h5 has a dataset named scalar_data
39+ // which has an attribute named 'attribute_X'. To get
40+ // the value of this attribute:
41+ //
42+ // float attribute_X =
43+ // read_float_attribute(scalar_data_dataset_id, "attribute_X");
44+
45+
46+ const char * attribute_value ;
47+ // Get attribute value as string
48+ hid_t attribute_id = H5Aopen (dataset_id , attribute_name , H5P_DEFAULT );
49+ hid_t attribute_type = H5Aget_type (attribute_id );
50+ H5Aread (attribute_id , attribute_type , & attribute_value );
51+ // Convert attribute value to float
52+ return atof (attribute_value );
53+ }
54+ void close_hdf5_dataset (hid_t dataset_id ) { H5Dclose (dataset_id ); }
55+ void close_hdf5_file (hid_t file_id ) { H5Fclose (file_id ); }
56+
57+ int write_hdf5_result (int n1 , int n2 , int n3 , double execution_time , f_type * next_u ) {
58+ hid_t h5t_type = H5T_NATIVE_FLOAT ;
59+ #if defined(DOUBLE )
60+ h5t_type = H5T_NATIVE_DOUBLE ;
61+ #endif
62+
63+ // Create a new HDF5 file using the default properties
64+ hid_t file_id = H5Fcreate ("c-frontend/data/results.h5" , H5F_ACC_TRUNC , H5P_DEFAULT , H5P_DEFAULT );
65+ if (file_id < 0 ) {
66+ printf ("Error creating file.\n" );
67+ return 1 ;
68+ }
69+
70+ // Define the dataspace for the vector dataset
71+ hsize_t vector_dims [3 ] = {n1 ,n2 ,n3 }; // 3D vector
72+ hid_t vector_dataspace_id = H5Screate_simple (3 , vector_dims , NULL );
73+ if (vector_dataspace_id < 0 ) {
74+ printf ("Error creating vector dataspace.\n" );
75+ H5Fclose (file_id );
76+ return 1 ;
77+ }
78+
79+ // Create the vector dataset with default properties
80+ hid_t vector_dataset_id = H5Dcreate (file_id , "vector" , h5t_type , vector_dataspace_id ,
81+ H5P_DEFAULT , H5P_DEFAULT , H5P_DEFAULT );
82+ if (vector_dataset_id < 0 ) {
83+ printf ("Error creating vector dataset.\n" );
84+ H5Sclose (vector_dataspace_id );
85+ H5Fclose (file_id );
86+ return 1 ;
87+ }
88+
89+ // Write the vector data to the dataset
90+ if (H5Dwrite (vector_dataset_id , h5t_type , H5S_ALL , H5S_ALL , H5P_DEFAULT , next_u ) < 0 ) {
91+ printf ("Error writing vector data.\n" );
92+ H5Dclose (vector_dataset_id );
93+ H5Sclose (vector_dataspace_id );
94+ H5Fclose (file_id );
95+ return 1 ;
96+ }
97+
98+ // Define the dataspace for the execution time dataset
99+ hsize_t time_dims [1 ] = {1 }; // Scalar
100+ hid_t time_dataspace_id = H5Screate_simple (1 , time_dims , NULL );
101+ if (time_dataspace_id < 0 ) {
102+ printf ("Error creating time dataspace.\n" );
103+ H5Dclose (vector_dataset_id );
104+ H5Sclose (vector_dataspace_id );
105+ H5Fclose (file_id );
106+ return 1 ;
107+ }
108+
109+ // Create the execution time dataset with default properties
110+ hid_t time_dataset_id = H5Dcreate (file_id , "execution_time" , H5T_NATIVE_DOUBLE , time_dataspace_id ,
111+ H5P_DEFAULT , H5P_DEFAULT , H5P_DEFAULT );
112+ if (time_dataset_id < 0 ) {
113+ printf ("Error creating time dataset.\n" );
114+ H5Dclose (vector_dataset_id );
115+ H5Sclose (vector_dataspace_id );
116+ H5Sclose (time_dataspace_id );
117+ H5Fclose (file_id );
118+ return 1 ;
119+ }
120+
121+ // Write the execution time to the dataset
122+ if (H5Dwrite (time_dataset_id , H5T_NATIVE_DOUBLE , H5S_ALL , H5S_ALL , H5P_DEFAULT , & execution_time ) < 0 ) {
123+ printf ("Error writing time data.\n" );
124+ H5Dclose (vector_dataset_id );
125+ H5Sclose (vector_dataspace_id );
126+ H5Dclose (time_dataset_id );
127+ H5Sclose (time_dataspace_id );
128+ H5Fclose (file_id );
129+ return 1 ;
130+ }
131+
132+ // Close the datasets, dataspaces, and file
133+ H5Dclose (vector_dataset_id );
134+ H5Sclose (vector_dataspace_id );
135+ H5Dclose (time_dataset_id );
136+ H5Sclose (time_dataspace_id );
137+ H5Fclose (file_id );
138+ return 0 ;
139+ }
140+
141+ int main () {
142+ #ifdef CONTAINS_MPI
143+ MPI_Init (NULL , NULL );
144+ #endif
145+
146+ int rank = 0 ;
147+
148+ #ifdef CONTAINS_MPI
149+ MPI_Comm_rank (MPI_COMM_WORLD , & rank );
150+ #endif
151+
152+ // Get the file id
153+ hid_t file_id = open_hdf5_file ("c-frontend/data/miniwave_data.h5" );
154+ // Read arguments
155+ hid_t vel_model_id = open_hdf5_dataset (file_id , "vel_model" );
156+ hid_t next_u_id = open_hdf5_dataset (file_id , "next_u" );
157+ hid_t prev_u_id = open_hdf5_dataset (file_id , "prev_u" );
158+ hid_t coefficient_id = open_hdf5_dataset (file_id , "coefficient" );
159+ hid_t scalar_data_id = open_hdf5_dataset (file_id , "scalar_data" );
160+ float * vel_model = read_float_dataset (vel_model_id );
161+ float * next_u = read_float_dataset (next_u_id );
162+ float * prev_u = read_float_dataset (prev_u_id );
163+ float * coefficient = read_float_dataset (coefficient_id );
164+ float block_size_1 = read_float_attribute (scalar_data_id , "block_size_1" );
165+ float block_size_2 = read_float_attribute (scalar_data_id , "block_size_2" );
166+ float block_size_3 = read_float_attribute (scalar_data_id , "block_size_3" );
167+ float d1 = read_float_attribute (scalar_data_id , "d1" );
168+ float d2 = read_float_attribute (scalar_data_id , "d2" );
169+ float d3 = read_float_attribute (scalar_data_id , "d3" );
170+ float dt = read_float_attribute (scalar_data_id , "dt" );
171+ float iterations = read_float_attribute (scalar_data_id , "iterations" );
172+ float n1 = read_float_attribute (scalar_data_id , "n1" );
173+ float n2 = read_float_attribute (scalar_data_id , "n2" );
174+ float n3 = read_float_attribute (scalar_data_id , "n3" );
175+ float stencil_radius = read_float_attribute (scalar_data_id , "stencil_radius" );
176+
177+ if (rank == 0 ) {
178+ printf ("vel_model[0:50]:\n" );
179+ for (size_t i = 0 ; i < 50 ; i ++ ) {
180+ printf ("%f " , vel_model [i ]);
181+ }
182+ printf ("\n" );
183+ printf ("next_u[0:50]:\n" );
184+ for (size_t i = 0 ; i < 50 ; i ++ ) {
185+ printf ("%lf " , next_u [i ]);
186+ }
187+ printf ("\n" );
188+ printf ("prev_u[0:50]:\n" );
189+ for (size_t i = 0 ; i < 50 ; i ++ ) {
190+ printf ("%lf " , prev_u [i ]);
191+ }
192+ printf ("\n" );
193+ printf ("coefficient:\n" );
194+ for (size_t i = 0 ; i < 2 ; i ++ ) {
195+ printf ("%lf " , coefficient [i ]);
196+ }
197+ printf ("\n" );
198+ printf ("block_size_1: %f\n" ,block_size_1 );
199+ printf ("block_size_2: %f\n" ,block_size_2 );
200+ printf ("block_size_3: %f\n" ,block_size_3 );
201+ printf ("d1: %f\n" ,d1 );
202+ printf ("d2: %f\n" ,d2 );
203+ printf ("d3: %f\n" ,d3 );
204+ printf ("dt: %f\n" ,dt );
205+ printf ("iterations: %f\n" ,iterations );
206+ printf ("n1: %f\n" ,n1 );
207+ printf ("n2: %f\n" ,n2 );
208+ printf ("n3: %f\n" ,n3 );
209+ printf ("stencil_radius: %f\n" ,stencil_radius );
210+ }
211+
212+ clock_t start_time = clock ();
213+
214+ forward (prev_u , next_u , vel_model , coefficient , d1 , d2 , d3 , dt , n1 , n2 , n3 , iterations , stencil_radius , block_size_1 , block_size_2 , block_size_3 );
215+
216+ clock_t end_time = clock ();
217+ double execution_time = ((double )(end_time - start_time )) / CLOCKS_PER_SEC ;
218+
219+ if (rank == 0 ) {
220+ printf ("\nprev_u[0:50]" );
221+ for (size_t i = 0 ; i < 50 ; i ++ ) {
222+ printf ("%lf " , prev_u [i ]);
223+ }
224+ printf ("\n" );
225+
226+ write_hdf5_result (n1 , n2 , n3 , execution_time , next_u );
227+ }
228+
229+ close_hdf5_dataset (vel_model_id );
230+ close_hdf5_dataset (next_u_id );
231+ close_hdf5_dataset (prev_u_id );
232+ close_hdf5_dataset (coefficient_id );
233+ close_hdf5_file (file_id );
234+
235+ #ifdef CONTAINS_MPI
236+ MPI_Finalize ();
237+ #endif
238+ }
0 commit comments