Skip to content

Commit 606e174

Browse files
Merge pull request #67 from GeorgeJuniorGG/master
add miniwave module
2 parents c8e62be + decd4c6 commit 606e174

File tree

16 files changed

+1310
-0
lines changed

16 files changed

+1310
-0
lines changed

miniwave/.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
plots/*
2+
R-miniwave*
3+
run.sh
4+
*.nvvp
5+
__pycache__
6+
tmp/
7+
*.sif
8+
data/
9+
build/

miniwave/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Miniwave - Minimum Simwave
2+
3+
Python wrapper for forward wave propagation.
4+
5+
# Dependencies
6+
7+
`pip install numpy matplotlib findiff h5py`
8+
9+
```
10+
mkdir /hdf5 && \
11+
cd /hdf5 && \
12+
wget https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.14/hdf5-1.14.3/src/CMake-hdf5-1.14.3.tar.gz && \
13+
tar xf CMake-hdf5-1.14.3.tar.gz && \
14+
cd CMake-hdf5-1.14.3 && \
15+
./build-unix.sh && \
16+
yes | ./HDF5-1.14.3-Linux.sh && \
17+
cp -r HDF5-1.14.3-Linux/HDF_Group/HDF5/1.14.3/ ../build
18+
```
19+
20+
# How to use
21+
22+
`python3 miniwave.py --help`
23+
24+
`python3 miniwave.py --file FILE --grid_size GRID_SIZE --num_timesteps NUM_TIMESTEPS --language {c,openmp,openacc,cuda,python} --space_order SPACE_ORDER`
25+

miniwave/c-frontend/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
3+
project(miniwave)
4+
5+
# Set the kernel source file and header
6+
configure_file(${CMAKE_SOURCE_DIR}/selected_kernel.h.in
7+
${CMAKE_BINARY_DIR}/selected_kernel.h)
8+
include_directories(${CMAKE_BINARY_DIR})
9+
10+
add_executable(miniwave ../${KERNEL_SOURCE} miniwave.c)
11+
12+
# Include miniwave header files (sequential.h)
13+
target_include_directories(miniwave PUBLIC ${CMAKE_SOURCE_DIR}/../kernels)
14+
15+
# HDF5 commands
16+
set(HDF5DIR "$ENV{HOME}/hdf5/build")
17+
target_include_directories(miniwave PRIVATE ${HDF5DIR}/include)
18+
target_link_directories(miniwave PRIVATE ${HDF5DIR}/lib)
19+
target_link_libraries(miniwave PRIVATE libhdf5.so libhdf5_cpp.so)

miniwave/c-frontend/miniwave.c

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
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+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef SELECTED_KERNEL_H
2+
#define SELECTED_KERNEL_H
3+
4+
#include "../@KERNEL_HEADER@"
5+
6+
#endif // SELECTED_KERNEL_H

miniwave/kernels/sequential.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
#include "sequential.h"
5+
6+
int forward(f_type *prev_u, f_type *next_u, f_type *vel_model, f_type *coefficient,
7+
f_type d1, f_type d2, f_type d3, f_type dt, int n1, int n2, int n3,
8+
int iterations, int stencil_radius,
9+
int block_size_1, int block_size_2, int block_size_3
10+
){
11+
12+
f_type d1Squared = d1 * d1;
13+
f_type d2Squared = d2 * d2;
14+
f_type d3Squared = d3 * d3;
15+
f_type dtSquared = dt * dt;
16+
17+
for(int t = 0; t < iterations; t++) {
18+
19+
for(int i = stencil_radius; i < n1 - stencil_radius; i++){
20+
for(int j = stencil_radius; j < n2 - stencil_radius; j++){
21+
for(int k = stencil_radius; k < n3 - stencil_radius; k++){
22+
// index of the current point in the grid
23+
int current = (i * n2 + j) * n3 + k;
24+
25+
// stencil code to update grid
26+
f_type value = coefficient[0] * (prev_u[current]/d1Squared + prev_u[current]/d2Squared + prev_u[current]/d3Squared);
27+
28+
// radius of the stencil
29+
for(int ir = 1; ir <= stencil_radius; ir++){
30+
value += coefficient[ir] * (
31+
( (prev_u[current + ir] + prev_u[current - ir]) / d3Squared ) + //neighbors in the third axis
32+
( (prev_u[current + (ir * n3)] + prev_u[current - (ir * n3)]) / d2Squared ) + //neighbors in the second axis
33+
( (prev_u[current + (ir * n2 * n3)] + prev_u[current - (ir * n2 * n3)]) / d1Squared )); //neighbors in the first axis
34+
}
35+
36+
value *= dtSquared * vel_model[current] * vel_model[current];
37+
next_u[current] = 2.0 * prev_u[current] - next_u[current] + value;
38+
}
39+
}
40+
}
41+
42+
// swap arrays for next iteration
43+
f_type *swap = next_u;
44+
next_u = prev_u;
45+
prev_u = swap;
46+
}
47+
48+
return 0;
49+
}

miniwave/kernels/sequential.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
// use single (float) or double precision
3+
// according to the value passed in the compilation cmd
4+
#if defined(FLOAT)
5+
typedef float f_type;
6+
#elif defined(DOUBLE)
7+
typedef double f_type;
8+
#else
9+
typedef float f_type;
10+
#endif
11+
12+
int forward(f_type *prev_u, f_type *next_u, f_type *vel_model, f_type *coefficient,
13+
f_type d1, f_type d2, f_type d3, f_type dt, int n1, int n2, int n3,
14+
int iterations, int stencil_radius,
15+
int block_size_1, int block_size_2, int block_size_3
16+
);

0 commit comments

Comments
 (0)