Skip to content

Commit 9585443

Browse files
committed
enable both single and double float precision
1 parent 35554d1 commit 9585443

File tree

15 files changed

+285
-915
lines changed

15 files changed

+285
-915
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[![PyPI version](https://badge.fury.io/py/simwave.svg)](https://badge.fury.io/py/simwave)
2+
13
# Simwave
24

35
`Simwave` is a Python package to simulate the propagation of the constant or variable density acoustic wave in an isotropic 2D/3D medium using the finite difference method. Finite difference kernels of aribtrary spatial order (up to 16th order) are written in C for performance and compiled at run time. These kernels are called via a user-friendly Python interface for easy integration with several scientific and engineering libraries to, for example perform full-waveform inversion.

examples/acoustic_2D.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
bounding_box=(0, 5120, 0, 5120),
1515
grid_spacing=(10, 10),
1616
velocity_model=vel,
17-
space_order=4
17+
space_order=4,
18+
dtype=np.float32
1819
)
1920

2021
# config boundary conditions

setup.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
with open("requirements.txt") as f:
55
required = f.read().splitlines()
66

7+
with open("README.md") as f:
8+
readme = f.read()
9+
710
setup(
811
name="simwave",
912
version=versioneer.get_version(),
1013
cmdclass=versioneer.get_cmdclass(),
1114
description="Finite difference 2D/3D acoustic wave propagator.",
12-
long_description="""Simwave is an hybrid Python/C tool that
13-
simulates the propagation of the acoustic wave using the
14-
finite difference method in 2D and 3D domains.""",
15+
long_description=readme,
16+
long_description_content_type="text/markdown",
1517
url='https://github.com/HPCSys-Lab/simwave',
1618
author="HPCSys-Lab",
1719
author_email="[email protected]",
Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,45 @@
33
#include <time.h>
44
#include <sys/time.h>
55

6+
// use single (float) or double precision
7+
// according to the value passed in the compilation cmd
8+
#if defined(FLOAT)
9+
typedef float f_type;
10+
#elif defined(DOUBLE)
11+
typedef double f_type;
12+
#endif
13+
614
// forward_2D_constant_density
7-
double forward(float *grid, float *vel_base, float *damp,
8-
float *wavelet, float *coeff, size_t *boundary_conditions,
9-
size_t *src_points_interval, float *src_points_values,
10-
size_t *rec_points_interval, float *rec_points_values,
11-
float *receivers, size_t num_sources, size_t num_receivers,
12-
size_t nz, size_t nx, float dz, float dx,
13-
size_t jumps, float dt,
15+
double forward(f_type *grid, f_type *velocity, f_type *damp,
16+
f_type *wavelet, f_type *coeff, size_t *boundary_conditions,
17+
size_t *src_points_interval, f_type *src_points_values,
18+
size_t *rec_points_interval, f_type *rec_points_values,
19+
f_type *receivers, size_t num_sources, size_t num_receivers,
20+
size_t nz, size_t nx, f_type dz, f_type dx,
21+
size_t saving_stride, f_type dt,
1422
size_t begin_timestep, size_t end_timestep, size_t space_order){
1523

1624
size_t stencil_radius = space_order / 2;
1725

18-
float *swap;
26+
f_type *swap;
1927
size_t current;
2028
size_t wavefield_count = 0;
2129

22-
float dzSquared = dz * dz;
23-
float dxSquared = dx * dx;
24-
float dtSquared = dt * dt;
30+
f_type dzSquared = dz * dz;
31+
f_type dxSquared = dx * dx;
32+
f_type dtSquared = dt * dt;
2533

26-
float *prev_base = malloc(nz * nx * sizeof(float));
27-
float *next_base = malloc(nz * nx * sizeof(float));
34+
f_type *prev_snapshot = malloc(nz * nx * sizeof(f_type));
35+
f_type *next_snapshot = malloc(nz * nx * sizeof(f_type));
2836

2937
// initialize aux matrix
3038
for(size_t i = 0; i < nz; i++){
3139

3240
size_t offset = i * nx;
3341

3442
for(size_t j = 0; j < nx; j++){
35-
prev_base[offset + j] = grid[offset + j];
36-
next_base[offset + j] = 0.0f;
43+
prev_snapshot[offset + j] = grid[offset + j];
44+
next_snapshot[offset + j] = 0.0;
3745
}
3846
}
3947

@@ -57,28 +65,28 @@ double forward(float *grid, float *vel_base, float *damp,
5765
current = i * nx + j;
5866

5967
// stencil code to update grid
60-
float value = 0.0;
68+
f_type value = 0.0;
6169

62-
float sum_x = coeff[0] * prev_base[current];
63-
float sum_z = coeff[0] * prev_base[current];
70+
f_type sum_x = coeff[0] * prev_snapshot[current];
71+
f_type sum_z = coeff[0] * prev_snapshot[current];
6472

6573
// radius of the stencil
6674
for(int ir = 1; ir <= stencil_radius; ir++){
6775
//neighbors in the horizontal direction
68-
sum_x += coeff[ir] * (prev_base[current + ir] + prev_base[current - ir]);
76+
sum_x += coeff[ir] * (prev_snapshot[current + ir] + prev_snapshot[current - ir]);
6977

7078
//neighbors in the vertical direction
71-
sum_z += coeff[ir] * (prev_base[current + (ir * nx)] + prev_base[current - (ir * nx)]);
79+
sum_z += coeff[ir] * (prev_snapshot[current + (ir * nx)] + prev_snapshot[current - (ir * nx)]);
7280
}
7381

7482
value += sum_x/dxSquared + sum_z/dzSquared;
7583

76-
//nominator with damp coefficient
77-
float nominator = (1.0 + damp[current] * dt);
84+
//denominator with damp coefficient
85+
f_type denominator = (1.0 + damp[current] * dt);
7886

79-
value *= (dtSquared * vel_base[current] * vel_base[current]) / nominator;
87+
value *= (dtSquared * velocity[current] * velocity[current]) / denominator;
8088

81-
next_base[current] = 2.0 / nominator * prev_base[current] - ((1.0 - damp[current] * dt) / nominator) * next_base[current] + value;
89+
next_snapshot[current] = 2.0 / denominator * prev_snapshot[current] - ((1.0 - damp[current] * dt) / denominator) * next_snapshot[current] + value;
8290
}
8391
}
8492

@@ -117,11 +125,11 @@ double forward(float *grid, float *vel_base, float *damp,
117125
// for each source point in the X axis
118126
for(size_t j = src_x_begin; j <= src_x_end; j++){
119127

120-
float kws = src_points_values[kws_index_z] * src_points_values[kws_index_x];
128+
f_type kws = src_points_values[kws_index_z] * src_points_values[kws_index_x];
121129

122130
// current source point in the grid
123131
current = i * nx + j;
124-
next_base[current] += dtSquared * vel_base[current] * vel_base[current] * kws * wavelet[n];
132+
next_snapshot[current] += dtSquared * velocity[current] * velocity[current] * kws * wavelet[n];
125133

126134
kws_index_x++;
127135
}
@@ -148,28 +156,28 @@ double forward(float *grid, float *vel_base, float *damp,
148156
// null dirichlet on the left
149157
if(x_before == 1){
150158
current = i * nx + stencil_radius;
151-
next_base[current] = 0.0;
159+
next_snapshot[current] = 0.0;
152160
}
153161

154162
// null neumann on the left
155163
if(x_before == 2){
156164
for(int ir = 1; ir <= stencil_radius; ir++){
157165
current = i * nx + stencil_radius;
158-
next_base[current - ir] = next_base[current + ir];
166+
next_snapshot[current - ir] = next_snapshot[current + ir];
159167
}
160168
}
161169

162170
// null dirichlet on the right
163171
if(x_after == 1){
164172
current = i * nx + (nx - stencil_radius - 1);
165-
next_base[current] = 0.0;
173+
next_snapshot[current] = 0.0;
166174
}
167175

168176
// null neumann on the right
169177
if(x_after == 2){
170178
for(int ir = 1; ir <= stencil_radius; ir++){
171179
current = i * nx + (nx - stencil_radius - 1);
172-
next_base[current + ir] = next_base[current - ir];
180+
next_snapshot[current + ir] = next_snapshot[current - ir];
173181
}
174182
}
175183

@@ -181,28 +189,28 @@ double forward(float *grid, float *vel_base, float *damp,
181189
// null dirichlet on the top
182190
if(z_before == 1){
183191
current = stencil_radius * nx + j;
184-
next_base[current] = 0.0;
192+
next_snapshot[current] = 0.0;
185193
}
186194

187195
// null neumann on the top
188196
if(z_before == 2){
189197
for(int ir = 1; ir <= stencil_radius; ir++){
190198
current = stencil_radius * nx + j;
191-
next_base[current - (ir * nx)] = next_base[current + (ir * nx)];
199+
next_snapshot[current - (ir * nx)] = next_snapshot[current + (ir * nx)];
192200
}
193201
}
194202

195203
// null dirichlet on the bottom
196204
if(z_after == 1){
197205
current = (nz - stencil_radius - 1) * nx + j;
198-
next_base[current] = 0.0;
206+
next_snapshot[current] = 0.0;
199207
}
200208

201209
// null neumann on the bottom
202210
if(z_after == 2){
203211
for(int ir = 1; ir <= stencil_radius; ir++){
204212
current = (nz - stencil_radius - 1) * nx + j;
205-
next_base[current + (ir * nx)] = next_base[current - (ir * nx)];
213+
next_snapshot[current + (ir * nx)] = next_snapshot[current - (ir * nx)];
206214
}
207215
}
208216

@@ -218,7 +226,7 @@ double forward(float *grid, float *vel_base, float *damp,
218226
// for each receiver
219227
for(size_t rec = 0; rec < num_receivers; rec++){
220228

221-
float sum = 0.0;
229+
f_type sum = 0.0;
222230

223231
// each receiver has 4 (z_b, z_e, x_b, x_e) point intervals
224232
size_t offset_rec = rec * 4;
@@ -245,11 +253,11 @@ double forward(float *grid, float *vel_base, float *damp,
245253
// for each receiver point in the X axis
246254
for(size_t j = rec_x_begin; j <= rec_x_end; j++){
247255

248-
float kws = rec_points_values[kws_index_z] * rec_points_values[kws_index_x];
256+
f_type kws = rec_points_values[kws_index_z] * rec_points_values[kws_index_x];
249257

250258
// current receiver point in the grid
251259
current = i * nx + j;
252-
sum += prev_base[current] * kws;
260+
sum += prev_snapshot[current] * kws;
253261

254262
kws_index_x++;
255263
}
@@ -263,21 +271,21 @@ double forward(float *grid, float *vel_base, float *damp,
263271
}
264272

265273
//swap arrays for next iteration
266-
swap = next_base;
267-
next_base = prev_base;
268-
prev_base = swap;
274+
swap = next_snapshot;
275+
next_snapshot = prev_snapshot;
276+
prev_snapshot = swap;
269277

270278
/*
271279
Section 5: save the wavefields
272280
*/
273-
if( (jumps && (n % jumps) == 0) || (n == end_timestep - 1) ){
281+
if( (saving_stride && (n % saving_stride) == 0) || (n == end_timestep - 1) ){
274282

275283
for(size_t i = 0; i < nz; i++){
276284
size_t offset_local = i * nx;
277285
size_t offset_global = (wavefield_count * nz + i) * nx;
278286

279287
for(size_t j = 0; j < nx; j++){
280-
grid[offset_global + j] = next_base[offset_local + j];
288+
grid[offset_global + j] = next_snapshot[offset_local + j];
281289
}
282290
}
283291

@@ -291,8 +299,8 @@ double forward(float *grid, float *vel_base, float *damp,
291299

292300
double exec_time = (double) (time_end.tv_sec - time_start.tv_sec) + (double) (time_end.tv_usec - time_start.tv_usec) / 1000000.0;
293301

294-
free(prev_base);
295-
free(next_base);
302+
free(prev_snapshot);
303+
free(next_snapshot);
296304

297305
return exec_time;
298306
}

0 commit comments

Comments
 (0)