DeepGPR 0.0.16__tar.gz → 0.0.17__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {deepgpr-0.0.16 → deepgpr-0.0.17}/PKG-INFO +1 -1
  2. {deepgpr-0.0.16 → deepgpr-0.0.17}/pyproject.toml +1 -1
  3. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr.cu +223 -64
  4. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr.dll +0 -0
  5. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr.so +0 -0
  6. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr_cpu.dll +0 -0
  7. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR.egg-info/PKG-INFO +1 -1
  8. {deepgpr-0.0.16 → deepgpr-0.0.17}/tests/test_discrete_adjoint.py +18 -8
  9. {deepgpr-0.0.16 → deepgpr-0.0.17}/README.md +0 -0
  10. {deepgpr-0.0.16 → deepgpr-0.0.17}/license +0 -0
  11. {deepgpr-0.0.16 → deepgpr-0.0.17}/setup.cfg +0 -0
  12. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/__init__.py +0 -0
  13. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/common.py +0 -0
  14. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/compute2.py +0 -0
  15. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr.h +0 -0
  16. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr_cpu.c +0 -0
  17. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr_cpu.dylib +0 -0
  18. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/deepgpr_cpu.so +0 -0
  19. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/lib/libomp.dylib +0 -0
  20. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/multiscale.py +0 -0
  21. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR/wavelet.py +0 -0
  22. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR.egg-info/SOURCES.txt +0 -0
  23. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR.egg-info/dependency_links.txt +0 -0
  24. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR.egg-info/requires.txt +0 -0
  25. {deepgpr-0.0.16 → deepgpr-0.0.17}/src/DeepGPR.egg-info/top_level.txt +0 -0
  26. {deepgpr-0.0.16 → deepgpr-0.0.17}/tests/test_numerics.py +0 -0
  27. {deepgpr-0.0.16 → deepgpr-0.0.17}/tests/test_wavelet.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DeepGPR
3
- Version: 0.0.16
3
+ Version: 0.0.17
4
4
  Summary: PyTorch and CUDA for GPR FWI
5
5
  Author-email: Lei Liu <liulei990222@gmail.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "DeepGPR"
7
- version = "0.0.16"
7
+ version = "0.0.17"
8
8
  authors = [
9
9
  { name = "Lei Liu", email = "liulei990222@gmail.com" }
10
10
  ]
@@ -175,6 +175,139 @@ __device__ __forceinline__ float load_wavefield_value_device(
175
175
  } \
176
176
  } while (0)
177
177
 
178
+ static int clamp_cpml_index(int value, int extent)
179
+ {
180
+ if (value < 0) return 0;
181
+ if (value > extent) return extent;
182
+ return value;
183
+ }
184
+
185
+ /*
186
+ * Partition the CPML shell into six disjoint boxes. The x boxes own edges and
187
+ * corners, the y boxes exclude the x boxes, and the z boxes exclude both.
188
+ * Return the number of compact boundary cells without passing a large layout
189
+ * object to CUDA kernels, which is unreliable with CUDA 11.8's old frontend.
190
+ */
191
+ static long long cpml_cells_per_shot(
192
+ int NX, int NY, int NZ,
193
+ int pml0, int pml1, int pml2, int pml3, int pml4, int pml5,
194
+ int electric)
195
+ {
196
+ int x_low_end = pml0 > 0
197
+ ? clamp_cpml_index(pml0 + (electric ? 1 : 0), NX) : 0;
198
+ int y_low_end = pml2 > 0
199
+ ? clamp_cpml_index(pml2 + (electric ? 1 : 0), NY) : 0;
200
+ int z_low_end = pml4 > 0
201
+ ? clamp_cpml_index(pml4 + (electric ? 1 : 0), NZ) : 0;
202
+ int x_high_begin = pml1 > 0
203
+ ? clamp_cpml_index(NX - 1 - pml1, NX) : NX;
204
+ int y_high_begin = pml3 > 0
205
+ ? clamp_cpml_index(NY - 1 - pml3, NY) : NY;
206
+ int z_high_begin = pml5 > 0
207
+ ? clamp_cpml_index(NZ - 1 - pml5, NZ) : NZ;
208
+
209
+ int x_mid_end = x_high_begin > x_low_end ? x_high_begin : x_low_end;
210
+ int y_mid_end = y_high_begin > y_low_end ? y_high_begin : y_low_end;
211
+ int z_mid_end = z_high_begin > z_low_end ? z_high_begin : z_low_end;
212
+ long long x_mid = x_mid_end - x_low_end;
213
+ long long y_mid = y_mid_end - y_low_end;
214
+
215
+ long long cells = (long long)x_low_end * NY * NZ;
216
+ if (pml1 > 0) cells += (long long)(NX - x_mid_end) * NY * NZ;
217
+ cells += x_mid * y_low_end * NZ;
218
+ if (pml3 > 0) cells += x_mid * (NY - y_mid_end) * NZ;
219
+ cells += x_mid * y_mid * z_low_end;
220
+ if (pml5 > 0) cells += x_mid * y_mid * (NZ - z_mid_end);
221
+ return cells;
222
+ }
223
+
224
+ template<int ELECTRIC>
225
+ __device__ inline bool map_cpml_work(
226
+ long long compact_work, int step, long long cells_per_shot,
227
+ int NX, int NY, int NZ,
228
+ int pml0, int pml1, int pml2, int pml3, int pml4, int pml5,
229
+ int* shot, long long* i, long long* j, long long* k)
230
+ {
231
+ if (cells_per_shot == 0 ||
232
+ compact_work >= (long long)step * cells_per_shot) {
233
+ return false;
234
+ }
235
+
236
+ int x_low_end = pml0 > 0 ? pml0 + ELECTRIC : 0;
237
+ int y_low_end = pml2 > 0 ? pml2 + ELECTRIC : 0;
238
+ int z_low_end = pml4 > 0 ? pml4 + ELECTRIC : 0;
239
+ if (x_low_end > NX) x_low_end = NX;
240
+ if (y_low_end > NY) y_low_end = NY;
241
+ if (z_low_end > NZ) z_low_end = NZ;
242
+
243
+ int x_high_begin = pml1 > 0 ? NX - 1 - pml1 : NX;
244
+ int y_high_begin = pml3 > 0 ? NY - 1 - pml3 : NY;
245
+ int z_high_begin = pml5 > 0 ? NZ - 1 - pml5 : NZ;
246
+ if (x_high_begin < 0) x_high_begin = 0;
247
+ if (y_high_begin < 0) y_high_begin = 0;
248
+ if (z_high_begin < 0) z_high_begin = 0;
249
+
250
+ int x_mid_end = x_high_begin > x_low_end ? x_high_begin : x_low_end;
251
+ int y_mid_end = y_high_begin > y_low_end ? y_high_begin : y_low_end;
252
+ int z_mid_end = z_high_begin > z_low_end ? z_high_begin : z_low_end;
253
+ int x_mid = x_mid_end - x_low_end;
254
+ int y_mid = y_mid_end - y_low_end;
255
+
256
+ long long local = compact_work % cells_per_shot;
257
+ long long region_size = (long long)x_low_end * NY * NZ;
258
+ int i0, j0, nj, k0, nk;
259
+ if (local < region_size) {
260
+ i0 = 0;
261
+ j0 = 0; nj = NY;
262
+ k0 = 0; nk = NZ;
263
+ } else {
264
+ local -= region_size;
265
+ region_size = pml1 > 0 ? (long long)(NX - x_mid_end) * NY * NZ : 0;
266
+ if (local < region_size) {
267
+ i0 = x_mid_end;
268
+ j0 = 0; nj = NY;
269
+ k0 = 0; nk = NZ;
270
+ } else {
271
+ local -= region_size;
272
+ region_size = (long long)x_mid * y_low_end * NZ;
273
+ if (local < region_size) {
274
+ i0 = x_low_end;
275
+ j0 = 0; nj = y_low_end;
276
+ k0 = 0; nk = NZ;
277
+ } else {
278
+ local -= region_size;
279
+ region_size = pml3 > 0 ? (long long)x_mid * (NY - y_mid_end) * NZ : 0;
280
+ if (local < region_size) {
281
+ i0 = x_low_end;
282
+ j0 = y_mid_end; nj = NY - y_mid_end;
283
+ k0 = 0; nk = NZ;
284
+ } else {
285
+ local -= region_size;
286
+ region_size = (long long)x_mid * y_mid * z_low_end;
287
+ if (local < region_size) {
288
+ i0 = x_low_end;
289
+ j0 = y_low_end; nj = y_mid;
290
+ k0 = 0; nk = z_low_end;
291
+ } else {
292
+ local -= region_size;
293
+ i0 = x_low_end;
294
+ j0 = y_low_end; nj = y_mid;
295
+ k0 = z_mid_end; nk = NZ - z_mid_end;
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+
302
+ *shot = (int)(compact_work / cells_per_shot);
303
+ long long jk = (long long)nj * nk;
304
+ *i = i0 + local / jk;
305
+ long long remainder = local % jk;
306
+ *j = j0 + remainder / nk;
307
+ *k = k0 + remainder % nk;
308
+ return true;
309
+ }
310
+
178
311
  static int g_fdtd_order = 2;
179
312
 
180
313
  DEEPGPR_API int deepgpr_abi_version(void)
@@ -663,20 +796,19 @@ __global__ void cpml_e_gpu(
663
796
  float* __restrict__ y0EPhi1, float* __restrict__ y0EPhi2,
664
797
  float* __restrict__ ymEPhi1, float* __restrict__ ymEPhi2,
665
798
  float* __restrict__ z0EPhi1, float* __restrict__ z0EPhi2,
666
- float* __restrict__ zmEPhi1, float* __restrict__ zmEPhi2)
799
+ float* __restrict__ zmEPhi1, float* __restrict__ zmEPhi2,
800
+ long long compact_cells_per_shot)
667
801
  {
668
802
  long long ny_nz = (long long)NY_FIELDS * NZ_FIELDS;
669
803
  long long field_stride = (long long)NX_FIELDS * ny_nz;
670
- long long work = blockIdx.x * blockDim.x + threadIdx.x;
671
- if (work >= (long long)step * field_stride) return;
672
-
673
- int s = (int)(work / field_stride);
674
- long long idx = work % field_stride;
675
-
676
- long long i = idx / ny_nz;
677
- long long rem = idx % ny_nz;
678
- long long j = rem / NZ_FIELDS;
679
- long long k = rem % NZ_FIELDS;
804
+ long long compact_work = blockIdx.x * blockDim.x + threadIdx.x;
805
+ int s;
806
+ long long i, j, k;
807
+ if (!map_cpml_work<1>(compact_work, step, compact_cells_per_shot,
808
+ NX_FIELDS, NY_FIELDS, NZ_FIELDS,
809
+ pml0, pml1, pml2, pml3, pml4, pml5, &s, &i, &j, &k)) return;
810
+ long long idx = i * ny_nz + j * NZ_FIELDS + k;
811
+ long long work = (long long)s * field_stride + idx;
680
812
 
681
813
  bool in_x0 = (pml0 > 0 && i > 0 && i <= pml0 && j < NY_FIELDS && k < NZ_FIELDS);
682
814
  bool in_xm = (pml1 > 0 && i >= NX_FIELDS - 1 - pml1 && i < NX_FIELDS - 1 && j < NY_FIELDS && k < NZ_FIELDS);
@@ -957,20 +1089,19 @@ __global__ void cpml_h_gpu(
957
1089
  float* __restrict__ y0HPhi1, float* __restrict__ y0HPhi2,
958
1090
  float* __restrict__ ymHPhi1, float* __restrict__ ymHPhi2,
959
1091
  float* __restrict__ z0HPhi1, float* __restrict__ z0HPhi2,
960
- float* __restrict__ zmHPhi1, float* __restrict__ zmHPhi2)
1092
+ float* __restrict__ zmHPhi1, float* __restrict__ zmHPhi2,
1093
+ long long compact_cells_per_shot)
961
1094
  {
962
1095
  long long ny_nz = (long long)NY_FIELDS * NZ_FIELDS;
963
1096
  long long field_stride = (long long)NX_FIELDS * ny_nz;
964
- long long work = blockIdx.x * blockDim.x + threadIdx.x;
965
- if (work >= (long long)step * field_stride) return;
966
-
967
- int s = (int)(work / field_stride);
968
- long long idx = work % field_stride;
969
-
970
- long long i = idx / ny_nz;
971
- long long rem = idx % ny_nz;
972
- long long j = rem / NZ_FIELDS;
973
- long long k = rem % NZ_FIELDS;
1097
+ long long compact_work = blockIdx.x * blockDim.x + threadIdx.x;
1098
+ int s;
1099
+ long long i, j, k;
1100
+ if (!map_cpml_work<0>(compact_work, step, compact_cells_per_shot,
1101
+ NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1102
+ pml0, pml1, pml2, pml3, pml4, pml5, &s, &i, &j, &k)) return;
1103
+ long long idx = i * ny_nz + j * NZ_FIELDS + k;
1104
+ long long work = (long long)s * field_stride + idx;
974
1105
 
975
1106
  bool in_x0 = (pml0 > 0 && i < pml0 && j < NY_FIELDS && k < NZ_FIELDS);
976
1107
  bool in_xm = (pml1 > 0 && i >= NX_FIELDS - 1 - pml1 && i < NX_FIELDS - 1 && j < NY_FIELDS && k < NZ_FIELDS);
@@ -1111,18 +1242,19 @@ __global__ void adjoint_cpml_e_gpu(
1111
1242
  const float* z0R, const float* zmR, const float* update,
1112
1243
  float* x0P1, float* x0P2, float* xmP1, float* xmP2,
1113
1244
  float* y0P1, float* y0P2, float* ymP1, float* ymP2,
1114
- float* z0P1, float* z0P2, float* zmP1, float* zmP2)
1245
+ float* z0P1, float* z0P2, float* zmP1, float* zmP2,
1246
+ long long compact_cells_per_shot)
1115
1247
  {
1116
1248
  long long ny_nz = (long long)NY * NZ;
1117
1249
  long long field_stride = (long long)NX * ny_nz;
1118
- long long work = blockIdx.x * blockDim.x + threadIdx.x;
1119
- if (work >= (long long)step * field_stride) return;
1120
- int s = (int)(work / field_stride);
1121
- long long idx = work % field_stride;
1122
- long long i = idx / ny_nz;
1123
- long long rem = idx % ny_nz;
1124
- long long j = rem / NZ;
1125
- long long k = rem % NZ;
1250
+ long long compact_work = blockIdx.x * blockDim.x + threadIdx.x;
1251
+ int s;
1252
+ long long i, j, k;
1253
+ if (!map_cpml_work<1>(compact_work, step, compact_cells_per_shot,
1254
+ NX, NY, NZ, pml0, pml1, pml2, pml3, pml4, pml5,
1255
+ &s, &i, &j, &k)) return;
1256
+ long long idx = i * ny_nz + j * NZ + k;
1257
+ long long work = (long long)s * field_stride + idx;
1126
1258
  float upd = update[idx];
1127
1259
 
1128
1260
  #define APPLY_E_PML_GPU(R, P, p, q, stride, coord, n, spacing, field, source, sign) \
@@ -1211,18 +1343,19 @@ __global__ void adjoint_cpml_h_gpu(
1211
1343
  const float* z0R, const float* zmR, const float* update,
1212
1344
  float* x0P1, float* x0P2, float* xmP1, float* xmP2,
1213
1345
  float* y0P1, float* y0P2, float* ymP1, float* ymP2,
1214
- float* z0P1, float* z0P2, float* zmP1, float* zmP2)
1346
+ float* z0P1, float* z0P2, float* zmP1, float* zmP2,
1347
+ long long compact_cells_per_shot)
1215
1348
  {
1216
1349
  long long ny_nz = (long long)NY * NZ;
1217
1350
  long long field_stride = (long long)NX * ny_nz;
1218
- long long work = blockIdx.x * blockDim.x + threadIdx.x;
1219
- if (work >= (long long)step * field_stride) return;
1220
- int s = (int)(work / field_stride);
1221
- long long idx = work % field_stride;
1222
- long long i = idx / ny_nz;
1223
- long long rem = idx % ny_nz;
1224
- long long j = rem / NZ;
1225
- long long k = rem % NZ;
1351
+ long long compact_work = blockIdx.x * blockDim.x + threadIdx.x;
1352
+ int s;
1353
+ long long i, j, k;
1354
+ if (!map_cpml_work<0>(compact_work, step, compact_cells_per_shot,
1355
+ NX, NY, NZ, pml0, pml1, pml2, pml3, pml4, pml5,
1356
+ &s, &i, &j, &k)) return;
1357
+ long long idx = i * ny_nz + j * NZ + k;
1358
+ long long work = (long long)s * field_stride + idx;
1226
1359
  float upd = update[idx];
1227
1360
 
1228
1361
  #define APPLY_H_PML_GPU(R, P, p, q, stride, coord, n, spacing, field, source, sign) \
@@ -1666,6 +1799,16 @@ DEEPGPR_API void forward(const float* __restrict__ eps_r_pad, const float* __res
1666
1799
  long long total_fields = (long long)NX_FIELDS * NY_FIELDS * NZ_FIELDS;
1667
1800
  dim3 grid_material(CEIL_DIV(total_fields, blockSize));
1668
1801
  dim3 grid_fields(CEIL_DIV((long long)step * total_fields, blockSize));
1802
+ long long cpml_e_cells = cpml_cells_per_shot(
1803
+ NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1804
+ pml0, pml1, pml2, pml3, pml4, pml5, 1);
1805
+ long long cpml_h_cells = cpml_cells_per_shot(
1806
+ NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1807
+ pml0, pml1, pml2, pml3, pml4, pml5, 0);
1808
+ int has_cpml_e = has_cpml && cpml_e_cells > 0;
1809
+ int has_cpml_h = has_cpml && cpml_h_cells > 0;
1810
+ dim3 grid_cpml_e(CEIL_DIV((long long)step * cpml_e_cells, blockSize));
1811
+ dim3 grid_cpml_h(CEIL_DIV((long long)step * cpml_h_cells, blockSize));
1669
1812
 
1670
1813
  build_update_coeffs_gpu<<<grid_material, blockSize, 0, stream_comp>>>(eps_r_pad, sigma_pad, mu_r_pad, ce_hist, ce_curl, ce_rhs, ch_hist, ch_curl, ch_rhs, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dt, dx);
1671
1814
  CUDA_CHECK_LAST();
@@ -1717,58 +1860,64 @@ DEEPGPR_API void forward(const float* __restrict__ eps_r_pad, const float* __res
1717
1860
  if (fdtd_order == 8) {
1718
1861
  update_h_gpu<8><<<grid_fields, blockSize, 0, stream_comp>>>(ch_hist, ch_curl, Ex, Ey, Ez, Hx, Hy, Hz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
1719
1862
  CUDA_CHECK_LAST();
1720
- if (has_cpml) {
1721
- cpml_h_gpu<8><<<grid_fields, blockSize, 0, stream_comp>>>(
1863
+ if (has_cpml_h) {
1864
+ cpml_h_gpu<8><<<grid_cpml_h, blockSize, 0, stream_comp>>>(
1722
1865
  Ex, Ey, Ez, Hx, Hy, Hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1723
1866
  pml0, pml1, pml2, pml3, pml4, pml5, x0HR, xmHR, y0HR, ymHR, z0HR, zmHR, ch_rhs,
1724
- x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2, z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2);
1867
+ x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2, z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2,
1868
+ cpml_h_cells);
1725
1869
  CUDA_CHECK_LAST();
1726
1870
  }
1727
1871
  update_e_gpu<8><<<grid_fields, blockSize, 0, stream_comp>>>(ce_hist, ce_curl, Ex, Ey, Ez, Hx, Hy, Hz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
1728
1872
  CUDA_CHECK_LAST();
1729
- if (has_cpml) {
1730
- cpml_e_gpu<8><<<grid_fields, blockSize, 0, stream_comp>>>(
1873
+ if (has_cpml_e) {
1874
+ cpml_e_gpu<8><<<grid_cpml_e, blockSize, 0, stream_comp>>>(
1731
1875
  Ex, Ey, Ez, Hx, Hy, Hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1732
1876
  pml0, pml1, pml2, pml3, pml4, pml5, x0ER, xmER, y0ER, ymER, z0ER, zmER, ce_rhs,
1733
- x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2, z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2);
1877
+ x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2, z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2,
1878
+ cpml_e_cells);
1734
1879
  CUDA_CHECK_LAST();
1735
1880
  }
1736
1881
  } else if (fdtd_order == 4) {
1737
1882
  update_h_gpu<4><<<grid_fields, blockSize, 0, stream_comp>>>(ch_hist, ch_curl, Ex, Ey, Ez, Hx, Hy, Hz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
1738
1883
  CUDA_CHECK_LAST();
1739
- if (has_cpml) {
1740
- cpml_h_gpu<4><<<grid_fields, blockSize, 0, stream_comp>>>(
1884
+ if (has_cpml_h) {
1885
+ cpml_h_gpu<4><<<grid_cpml_h, blockSize, 0, stream_comp>>>(
1741
1886
  Ex, Ey, Ez, Hx, Hy, Hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1742
1887
  pml0, pml1, pml2, pml3, pml4, pml5, x0HR, xmHR, y0HR, ymHR, z0HR, zmHR, ch_rhs,
1743
- x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2, z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2);
1888
+ x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2, z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2,
1889
+ cpml_h_cells);
1744
1890
  CUDA_CHECK_LAST();
1745
1891
  }
1746
1892
  update_e_gpu<4><<<grid_fields, blockSize, 0, stream_comp>>>(ce_hist, ce_curl, Ex, Ey, Ez, Hx, Hy, Hz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
1747
1893
  CUDA_CHECK_LAST();
1748
- if (has_cpml) {
1749
- cpml_e_gpu<4><<<grid_fields, blockSize, 0, stream_comp>>>(
1894
+ if (has_cpml_e) {
1895
+ cpml_e_gpu<4><<<grid_cpml_e, blockSize, 0, stream_comp>>>(
1750
1896
  Ex, Ey, Ez, Hx, Hy, Hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1751
1897
  pml0, pml1, pml2, pml3, pml4, pml5, x0ER, xmER, y0ER, ymER, z0ER, zmER, ce_rhs,
1752
- x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2, z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2);
1898
+ x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2, z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2,
1899
+ cpml_e_cells);
1753
1900
  CUDA_CHECK_LAST();
1754
1901
  }
1755
1902
  } else {
1756
1903
  update_h_gpu<2><<<grid_fields, blockSize, 0, stream_comp>>>(ch_hist, ch_curl, Ex, Ey, Ez, Hx, Hy, Hz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
1757
1904
  CUDA_CHECK_LAST();
1758
- if (has_cpml) {
1759
- cpml_h_gpu<2><<<grid_fields, blockSize, 0, stream_comp>>>(
1905
+ if (has_cpml_h) {
1906
+ cpml_h_gpu<2><<<grid_cpml_h, blockSize, 0, stream_comp>>>(
1760
1907
  Ex, Ey, Ez, Hx, Hy, Hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1761
1908
  pml0, pml1, pml2, pml3, pml4, pml5, x0HR, xmHR, y0HR, ymHR, z0HR, zmHR, ch_rhs,
1762
- x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2, z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2);
1909
+ x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2, z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2,
1910
+ cpml_h_cells);
1763
1911
  CUDA_CHECK_LAST();
1764
1912
  }
1765
1913
  update_e_gpu<2><<<grid_fields, blockSize, 0, stream_comp>>>(ce_hist, ce_curl, Ex, Ey, Ez, Hx, Hy, Hz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
1766
1914
  CUDA_CHECK_LAST();
1767
- if (has_cpml) {
1768
- cpml_e_gpu<2><<<grid_fields, blockSize, 0, stream_comp>>>(
1915
+ if (has_cpml_e) {
1916
+ cpml_e_gpu<2><<<grid_cpml_e, blockSize, 0, stream_comp>>>(
1769
1917
  Ex, Ey, Ez, Hx, Hy, Hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
1770
1918
  pml0, pml1, pml2, pml3, pml4, pml5, x0ER, xmER, y0ER, ymER, z0ER, zmER, ce_rhs,
1771
- x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2, z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2);
1919
+ x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2, z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2,
1920
+ cpml_e_cells);
1772
1921
  CUDA_CHECK_LAST();
1773
1922
  }
1774
1923
  }
@@ -1964,6 +2113,16 @@ DEEPGPR_API void backward(const float* __restrict__ eps_r_pad, const float* __re
1964
2113
  long long total_fields = (long long)NX_FIELDS * NY_FIELDS * NZ_FIELDS;
1965
2114
  dim3 grid_material(CEIL_DIV(total_fields, blockSize));
1966
2115
  dim3 grid_fields(CEIL_DIV((long long)step * total_fields, blockSize));
2116
+ long long cpml_e_cells = cpml_cells_per_shot(
2117
+ NX_FIELDS, NY_FIELDS, NZ_FIELDS,
2118
+ pml0, pml1, pml2, pml3, pml4, pml5, 1);
2119
+ long long cpml_h_cells = cpml_cells_per_shot(
2120
+ NX_FIELDS, NY_FIELDS, NZ_FIELDS,
2121
+ pml0, pml1, pml2, pml3, pml4, pml5, 0);
2122
+ int has_cpml_e = has_cpml && cpml_e_cells > 0;
2123
+ int has_cpml_h = has_cpml && cpml_h_cells > 0;
2124
+ dim3 grid_cpml_e(CEIL_DIV((long long)step * cpml_e_cells, blockSize));
2125
+ dim3 grid_cpml_h(CEIL_DIV((long long)step * cpml_h_cells, blockSize));
1967
2126
 
1968
2127
  build_update_coeffs_gpu<<<grid_material, blockSize, 0, stream_comp>>>(eps_r_pad, sigma_pad, mu_r_pad, ce_hist, ce_curl, ce_rhs, ch_hist, ch_curl, ch_rhs, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dt, dx);
1969
2128
  CUDA_CHECK_LAST();
@@ -2032,24 +2191,24 @@ DEEPGPR_API void backward(const float* __restrict__ eps_r_pad, const float* __re
2032
2191
  }
2033
2192
 
2034
2193
  /* E CPML^T -> E update^T -> H CPML^T -> H update^T. */
2035
- if (has_cpml) {
2036
- LAUNCH_ORDER_KERNEL(adjoint_cpml_e_gpu, grid_fields, blockSize, stream_comp, fdtd_order,
2194
+ if (has_cpml_e) {
2195
+ LAUNCH_ORDER_KERNEL(adjoint_cpml_e_gpu, grid_cpml_e, blockSize, stream_comp, fdtd_order,
2037
2196
  lambda_ex, lambda_ey, lambda_ez, lambda_hx, lambda_hy, lambda_hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
2038
2197
  pml0, pml1, pml2, pml3, pml4, pml5, x0ER, xmER, y0ER, ymER, z0ER, zmER, ce_rhs,
2039
2198
  x0EPhi1, x0EPhi2, xmEPhi1, xmEPhi2, y0EPhi1, y0EPhi2, ymEPhi1, ymEPhi2,
2040
- z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2);
2199
+ z0EPhi1, z0EPhi2, zmEPhi1, zmEPhi2, cpml_e_cells);
2041
2200
  CUDA_CHECK_LAST();
2042
2201
  }
2043
2202
  LAUNCH_ORDER_KERNEL(adjoint_e_gpu, grid_fields, blockSize, stream_comp, fdtd_order,
2044
2203
  ce_hist, ce_curl, lambda_ex, lambda_ey, lambda_ez, lambda_hx, lambda_hy, lambda_hz,
2045
2204
  step, NX_FIELDS, NY_FIELDS, NZ_FIELDS, dx, dy, dz);
2046
2205
  CUDA_CHECK_LAST();
2047
- if (has_cpml) {
2048
- LAUNCH_ORDER_KERNEL(adjoint_cpml_h_gpu, grid_fields, blockSize, stream_comp, fdtd_order,
2206
+ if (has_cpml_h) {
2207
+ LAUNCH_ORDER_KERNEL(adjoint_cpml_h_gpu, grid_cpml_h, blockSize, stream_comp, fdtd_order,
2049
2208
  lambda_ex, lambda_ey, lambda_ez, lambda_hx, lambda_hy, lambda_hz, dx, dy, dz, step, NX_FIELDS, NY_FIELDS, NZ_FIELDS,
2050
2209
  pml0, pml1, pml2, pml3, pml4, pml5, x0HR, xmHR, y0HR, ymHR, z0HR, zmHR, ch_rhs,
2051
2210
  x0HPhi1, x0HPhi2, xmHPhi1, xmHPhi2, y0HPhi1, y0HPhi2, ymHPhi1, ymHPhi2,
2052
- z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2);
2211
+ z0HPhi1, z0HPhi2, zmHPhi1, zmHPhi2, cpml_h_cells);
2053
2212
  CUDA_CHECK_LAST();
2054
2213
  }
2055
2214
  LAUNCH_ORDER_KERNEL(adjoint_h_gpu, grid_fields, blockSize, stream_comp, fdtd_order,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DeepGPR
3
- Version: 0.0.16
3
+ Version: 0.0.17
4
4
  Summary: PyTorch and CUDA for GPR FWI
5
5
  Author-email: Lei Liu <liulei990222@gmail.com>
6
6
  License-Expression: MIT
@@ -67,23 +67,24 @@ def _locations(shape):
67
67
  return torch.tensor([[center]], dtype=torch.int32)
68
68
 
69
69
 
70
- def _state_problem(order, pml):
70
+ def _state_problem(order, pml, device="cpu"):
71
71
  torch.manual_seed(1100 + order + pml)
72
+ device = torch.device(device)
72
73
  shape = (9, 10, 8)
73
74
  nx, ny, nz = shape
74
- x = torch.linspace(0.0, 1.0, nx)[:, None, None]
75
- y = torch.linspace(0.0, 1.0, ny)[None, :, None]
76
- z = torch.linspace(0.0, 1.0, nz)[None, None, :]
75
+ x = torch.linspace(0.0, 1.0, nx, device=device)[:, None, None]
76
+ y = torch.linspace(0.0, 1.0, ny, device=device)[None, :, None]
77
+ z = torch.linspace(0.0, 1.0, nz, device=device)[None, None, :]
77
78
  eps_r = 3.5 + 0.7 * x + 0.2 * y + 0.1 * z
78
79
  sigma = 1.0e-4 + 1.0e-4 * (x + y + z) / 3.0
79
80
  mu_r = 1.0 + 0.15 * x + 0.0 * y + 0.05 * z
80
- location = _locations(shape)
81
- source = torch.zeros((1, 1, 1), dtype=torch.float32)
81
+ location = _locations(shape).to(device)
82
+ source = torch.zeros((1, 1, 1), dtype=torch.float32, device=device)
82
83
  spacing = (0.020, 0.017, 0.013)
83
84
  dt = 1.0e-11
84
85
 
85
86
  initial_e, initial_h, initial_cpml = DeepGPR.checkpoint_initial_field(
86
- device="cpu",
87
+ device=device,
87
88
  dx=spacing,
88
89
  dt=dt,
89
90
  source_amplitudes=source,
@@ -102,7 +103,7 @@ def _state_problem(order, pml):
102
103
  ]
103
104
  state = [tensor.clone().requires_grad_(True) for tensor in base_state]
104
105
  result = DeepGPR.compute(
105
- device="cpu",
106
+ device=device,
106
107
  dx=spacing,
107
108
  dt=dt,
108
109
  source_amplitudes=source,
@@ -269,6 +270,15 @@ class DiscreteAdjointTests(unittest.TestCase):
269
270
  def test_native_cpml_single_step_dot_product_all_faces(self):
270
271
  self.assertLess(_state_problem(order=4, pml=2), 3.0e-5)
271
272
 
273
+ @unittest.skipUnless(torch.cuda.is_available(), "CUDA is not available")
274
+ def test_cuda_cpml_single_step_dot_products_orders_2_4_8(self):
275
+ for order in (2, 4, 8):
276
+ with self.subTest(order=order):
277
+ self.assertLess(
278
+ _state_problem(order=order, pml=2, device="cuda"),
279
+ 2.0e-4,
280
+ )
281
+
272
282
  def test_source_waveform_gradient_matches_finite_difference(self):
273
283
  nx, ny, nt = 12, 14, 60
274
284
  eps_r = torch.full((nx, ny), 4.0)
File without changes
File without changes
File without changes
File without changes
File without changes