sweep-solver 0.1.0__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 (280) hide show
  1. sweep_solver-0.1.0/LICENSE +21 -0
  2. sweep_solver-0.1.0/MANIFEST.in +5 -0
  3. sweep_solver-0.1.0/PKG-INFO +160 -0
  4. sweep_solver-0.1.0/README.md +118 -0
  5. sweep_solver-0.1.0/build_config.py +258 -0
  6. sweep_solver-0.1.0/pyproject.toml +74 -0
  7. sweep_solver-0.1.0/setup.cfg +4 -0
  8. sweep_solver-0.1.0/setup.py +15 -0
  9. sweep_solver-0.1.0/setup_cuda.py +16 -0
  10. sweep_solver-0.1.0/src/geophyai/__init__.py +4 -0
  11. sweep_solver-0.1.0/src/sweep/_C.py +35 -0
  12. sweep_solver-0.1.0/src/sweep/__init__.py +182 -0
  13. sweep_solver-0.1.0/src/sweep/_jit.py +306 -0
  14. sweep_solver-0.1.0/src/sweep/backend/__init__.py +5 -0
  15. sweep_solver-0.1.0/src/sweep/backend/jax/__init__.py +15 -0
  16. sweep_solver-0.1.0/src/sweep/backend/jax/cuda.py +17 -0
  17. sweep_solver-0.1.0/src/sweep/backend/torch/__init__.py +16 -0
  18. sweep_solver-0.1.0/src/sweep/backend/torch/binding.py +53 -0
  19. sweep_solver-0.1.0/src/sweep/backend/torch/cuda.py +17 -0
  20. sweep_solver-0.1.0/src/sweep/cli.py +165 -0
  21. sweep_solver-0.1.0/src/sweep/csrc/CMakeLists.txt +10 -0
  22. sweep_solver-0.1.0/src/sweep/csrc/bindings/bindings_utils.h +48 -0
  23. sweep_solver-0.1.0/src/sweep/csrc/bindings/module.cpp +254 -0
  24. sweep_solver-0.1.0/src/sweep/csrc/cpu/common/cpu_engine.cpp +1181 -0
  25. sweep_solver-0.1.0/src/sweep/csrc/cpu/common/cpu_engine.h +36 -0
  26. sweep_solver-0.1.0/src/sweep/csrc/cpu/cpu_binding.cpp +136 -0
  27. sweep_solver-0.1.0/src/sweep/csrc/cpu/cpu_binding.h +20 -0
  28. sweep_solver-0.1.0/src/sweep/csrc/cpu/cpu_binding_stub.cpp +54 -0
  29. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic2d/acoustic2d_cpu.cpp +1882 -0
  30. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic2d/acoustic2d_cpu.h +13 -0
  31. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic3d/acoustic3d_cpu.cpp +1645 -0
  32. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic3d/acoustic3d_cpu.h +13 -0
  33. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_lsrtm2d/acoustic_lsrtm2d_cpu.cpp +1787 -0
  34. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_lsrtm2d/acoustic_lsrtm2d_cpu.h +13 -0
  35. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_lsrtm3d/acoustic_lsrtm3d_cpu.cpp +1741 -0
  36. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_lsrtm3d/acoustic_lsrtm3d_cpu.h +13 -0
  37. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_vrz2d/acoustic_vrz2d_cpu.cpp +1549 -0
  38. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_vrz2d/acoustic_vrz2d_cpu.h +13 -0
  39. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_vrz3d/acoustic_vrz3d_cpu.cpp +1587 -0
  40. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/acoustic_vrz3d/acoustic_vrz3d_cpu.h +13 -0
  41. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das2d/das2d_cpu.cpp +752 -0
  42. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das2d/das2d_cpu.h +13 -0
  43. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das3d/das3d_cpu.cpp +938 -0
  44. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das3d/das3d_cpu.h +13 -0
  45. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das_mu2d/das_mu2d_cpu.cpp +1194 -0
  46. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das_mu2d/das_mu2d_cpu.h +13 -0
  47. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das_mu3d/das_mu3d_cpu.cpp +1364 -0
  48. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/das_mu3d/das_mu3d_cpu.h +13 -0
  49. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/elastic2d/elastic2d_cpu.cpp +826 -0
  50. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/elastic2d/elastic2d_cpu.h +13 -0
  51. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/elastic3d/elastic3d_cpu.cpp +916 -0
  52. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/elastic3d/elastic3d_cpu.h +13 -0
  53. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/elastic_tti_sg2d/elastic_tti_sg2d_cpu.cpp +1736 -0
  54. sweep_solver-0.1.0/src/sweep/csrc/cpu/equations/elastic_tti_sg2d/elastic_tti_sg2d_cpu.h +13 -0
  55. sweep_solver-0.1.0/src/sweep/csrc/cpu/operators/fd.h +268 -0
  56. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/acoustic.h +428 -0
  57. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/acoustic_vrz_fused.cuh +81 -0
  58. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundary/disk_io.cuh +349 -0
  59. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundary/kernels.cuh +193 -0
  60. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundary/runtime.cuh +1590 -0
  61. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundary/saver.cuh +1423 -0
  62. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundary/types.cuh +119 -0
  63. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundary_runtime.cuh +3 -0
  64. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundarysaver.cu +960 -0
  65. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/boundarysaver.cuh +3 -0
  66. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/checkpoint_runtime.cuh +347 -0
  67. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/common.cu +209 -0
  68. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/common.cuh +55 -0
  69. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/context.h +96 -0
  70. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/cudautils.h +147 -0
  71. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/das.h +403 -0
  72. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/das_mu.h +543 -0
  73. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/elastic.h +772 -0
  74. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/elastic_free_surface.cuh +366 -0
  75. sweep_solver-0.1.0/src/sweep/csrc/cuda/common/wavetypes.h +3 -0
  76. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic2d/acoustic2d.h +19 -0
  77. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic2d/backward.cu +1156 -0
  78. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic2d/forward.cu +217 -0
  79. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic2d/kernels.cu +170 -0
  80. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic2d/kernels.cuh +454 -0
  81. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic3d/acoustic3d.h +19 -0
  82. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic3d/backward.cu +1284 -0
  83. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic3d/forward.cu +239 -0
  84. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic3d/kernels.cu +194 -0
  85. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic3d/kernels.cuh +547 -0
  86. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm2d/acoustic_lsrtm2d.h +17 -0
  87. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm2d/backward.cu +803 -0
  88. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm2d/forward.cu +219 -0
  89. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm2d/kernels.cu +65 -0
  90. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm2d/kernels.cuh +318 -0
  91. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm3d/acoustic_lsrtm3d.h +17 -0
  92. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm3d/backward.cu +1160 -0
  93. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm3d/forward.cu +223 -0
  94. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm3d/kernels.cu +78 -0
  95. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_lsrtm3d/kernels.cuh +398 -0
  96. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz2d/acoustic_vrz2d.h +13 -0
  97. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz2d/backward.cu +648 -0
  98. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz2d/forward.cu +201 -0
  99. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz2d/kernels.cuh +1092 -0
  100. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz3d/acoustic_vrz3d.h +13 -0
  101. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz3d/backward.cu +738 -0
  102. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz3d/forward.cu +206 -0
  103. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vrz3d/kernels.cuh +1147 -0
  104. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_2d/acoustic_vti_1st_2d.h +17 -0
  105. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_2d/backward.cu +819 -0
  106. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_2d/forward.cu +353 -0
  107. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_2d/kernels.cu +4 -0
  108. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_2d/kernels.cuh +687 -0
  109. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_3d/acoustic_vti_1st_3d.h +14 -0
  110. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_3d/backward.cu +780 -0
  111. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_3d/forward.cu +365 -0
  112. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_3d/kernels.cu +5 -0
  113. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/acoustic_vti_1st_3d/kernels.cuh +777 -0
  114. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das2d/backward.cu +829 -0
  115. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das2d/das2d.h +17 -0
  116. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das2d/forward.cu +255 -0
  117. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das2d/kernels.cuh +673 -0
  118. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das3d/backward.cu +391 -0
  119. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das3d/das3d.h +17 -0
  120. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das3d/forward.cu +179 -0
  121. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das3d/kernels.cuh +639 -0
  122. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu2d/backward.cu +1068 -0
  123. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu2d/das_mu2d.h +17 -0
  124. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu2d/forward.cu +233 -0
  125. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu2d/kernels.cuh +246 -0
  126. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu3d/backward.cu +1171 -0
  127. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu3d/das_mu3d.h +17 -0
  128. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu3d/forward.cu +239 -0
  129. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/das_mu3d/kernels.cuh +283 -0
  130. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic2d/backward.cu +1485 -0
  131. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic2d/elastic2d.h +27 -0
  132. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic2d/forward.cu +392 -0
  133. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic2d/kernels.cu +0 -0
  134. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic2d/kernels.cuh +1853 -0
  135. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic3d/backward.cu +1587 -0
  136. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic3d/elastic3d.h +24 -0
  137. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic3d/forward.cu +466 -0
  138. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic3d/kernels.cuh +2658 -0
  139. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_tti_sg2d/backward.cu +784 -0
  140. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_tti_sg2d/elastic_tti_sg2d.h +15 -0
  141. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_tti_sg2d/forward.cu +246 -0
  142. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_tti_sg2d/kernels.cuh +1037 -0
  143. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_tti_sg2d/tensors.h +163 -0
  144. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_vr2d/backward.cu +883 -0
  145. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_vr2d/elastic_vr2d.h +17 -0
  146. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_vr2d/forward.cu +207 -0
  147. sweep_solver-0.1.0/src/sweep/csrc/cuda/equations/elastic_vr2d/kernels.cuh +1142 -0
  148. sweep_solver-0.1.0/src/sweep/csrc/cuda/launch/config.h +169 -0
  149. sweep_solver-0.1.0/src/sweep/csrc/cuda/operators/dim.cuh +12 -0
  150. sweep_solver-0.1.0/src/sweep/csrc/cuda/operators/gradient.cuh +345 -0
  151. sweep_solver-0.1.0/src/sweep/csrc/cuda/operators/laplace.cuh +354 -0
  152. sweep_solver-0.1.0/src/sweep/csrc/cuda/operators/staggered.cuh +540 -0
  153. sweep_solver-0.1.0/src/sweep/csrc/shared/wavetypes.h +191 -0
  154. sweep_solver-0.1.0/src/sweep/datasets/__init__.py +115 -0
  155. sweep_solver-0.1.0/src/sweep/datasets/_benchmarks.py +280 -0
  156. sweep_solver-0.1.0/src/sweep/datasets/_cache.py +94 -0
  157. sweep_solver-0.1.0/src/sweep/datasets/_formats.py +264 -0
  158. sweep_solver-0.1.0/src/sweep/datasets/cli.py +89 -0
  159. sweep_solver-0.1.0/src/sweep/datasets/marmousi.py +9178 -0
  160. sweep_solver-0.1.0/src/sweep/datasets/overthrust_2d.py +1595 -0
  161. sweep_solver-0.1.0/src/sweep/datasets/registry.py +170 -0
  162. sweep_solver-0.1.0/src/sweep/equations/__init__.py +145 -0
  163. sweep_solver-0.1.0/src/sweep/equations/_anisotropy_utils.py +89 -0
  164. sweep_solver-0.1.0/src/sweep/equations/_elastic_step_core.py +234 -0
  165. sweep_solver-0.1.0/src/sweep/equations/_free_surface.py +324 -0
  166. sweep_solver-0.1.0/src/sweep/equations/_topography.py +748 -0
  167. sweep_solver-0.1.0/src/sweep/equations/acoustic.py +175 -0
  168. sweep_solver-0.1.0/src/sweep/equations/acoustic1st.py +210 -0
  169. sweep_solver-0.1.0/src/sweep/equations/acoustic3d.py +168 -0
  170. sweep_solver-0.1.0/src/sweep/equations/acoustic_aniso.py +186 -0
  171. sweep_solver-0.1.0/src/sweep/equations/acoustic_curvilinear.py +166 -0
  172. sweep_solver-0.1.0/src/sweep/equations/acoustic_lsrtm.py +175 -0
  173. sweep_solver-0.1.0/src/sweep/equations/acoustic_lsrtm3d.py +230 -0
  174. sweep_solver-0.1.0/src/sweep/equations/acoustic_vrr.py +145 -0
  175. sweep_solver-0.1.0/src/sweep/equations/acoustic_vrz.py +365 -0
  176. sweep_solver-0.1.0/src/sweep/equations/acoustic_vti_1st.py +626 -0
  177. sweep_solver-0.1.0/src/sweep/equations/aec.py +61 -0
  178. sweep_solver-0.1.0/src/sweep/equations/aec_lsrtm.py +100 -0
  179. sweep_solver-0.1.0/src/sweep/equations/base.py +687 -0
  180. sweep_solver-0.1.0/src/sweep/equations/cuda_layout.py +42 -0
  181. sweep_solver-0.1.0/src/sweep/equations/das.py +1520 -0
  182. sweep_solver-0.1.0/src/sweep/equations/elastic.py +323 -0
  183. sweep_solver-0.1.0/src/sweep/equations/elastic3d.py +548 -0
  184. sweep_solver-0.1.0/src/sweep/equations/elasticP.py +84 -0
  185. sweep_solver-0.1.0/src/sweep/equations/elastic_apm.py +32 -0
  186. sweep_solver-0.1.0/src/sweep/equations/elastic_curvilinear.py +337 -0
  187. sweep_solver-0.1.0/src/sweep/equations/elastic_lsrtm.py +90 -0
  188. sweep_solver-0.1.0/src/sweep/equations/elastic_tti.py +489 -0
  189. sweep_solver-0.1.0/src/sweep/equations/elastic_tti_sg.py +371 -0
  190. sweep_solver-0.1.0/src/sweep/equations/elastic_vrr.py +482 -0
  191. sweep_solver-0.1.0/src/sweep/equations/elasticz.py +53 -0
  192. sweep_solver-0.1.0/src/sweep/equations/fields.py +115 -0
  193. sweep_solver-0.1.0/src/sweep/equations/pml.py +302 -0
  194. sweep_solver-0.1.0/src/sweep/equations/qP_tariq.py +128 -0
  195. sweep_solver-0.1.0/src/sweep/equations/qP_tti.py +152 -0
  196. sweep_solver-0.1.0/src/sweep/equations/qP_vti.py +129 -0
  197. sweep_solver-0.1.0/src/sweep/equations/utils.py +59 -0
  198. sweep_solver-0.1.0/src/sweep/equations/visco_acoustic.py +191 -0
  199. sweep_solver-0.1.0/src/sweep/memory/__init__.py +0 -0
  200. sweep_solver-0.1.0/src/sweep/memory/shape.py +261 -0
  201. sweep_solver-0.1.0/src/sweep/memory/torch.py +24 -0
  202. sweep_solver-0.1.0/src/sweep/operators/__init__.py +25 -0
  203. sweep_solver-0.1.0/src/sweep/operators/factory.py +47 -0
  204. sweep_solver-0.1.0/src/sweep/operators/general.py +210 -0
  205. sweep_solver-0.1.0/src/sweep/operators/jax.py +225 -0
  206. sweep_solver-0.1.0/src/sweep/operators/rsg.py +175 -0
  207. sweep_solver-0.1.0/src/sweep/operators/torch.py +200 -0
  208. sweep_solver-0.1.0/src/sweep/propagator/__init__.py +23 -0
  209. sweep_solver-0.1.0/src/sweep/propagator/_bs_dispatch.py +74 -0
  210. sweep_solver-0.1.0/src/sweep/propagator/_c.py +1850 -0
  211. sweep_solver-0.1.0/src/sweep/propagator/_c.pyi +39 -0
  212. sweep_solver-0.1.0/src/sweep/propagator/_eager_boundary_saving.py +505 -0
  213. sweep_solver-0.1.0/src/sweep/propagator/_jax_boundary_saving.py +310 -0
  214. sweep_solver-0.1.0/src/sweep/propagator/_ring_geometry.py +54 -0
  215. sweep_solver-0.1.0/src/sweep/propagator/_torch_eager.py +420 -0
  216. sweep_solver-0.1.0/src/sweep/propagator/_torch_eager_custom_grad.py +421 -0
  217. sweep_solver-0.1.0/src/sweep/propagator/base.py +1007 -0
  218. sweep_solver-0.1.0/src/sweep/propagator/jax.py +485 -0
  219. sweep_solver-0.1.0/src/sweep/propagator/jax.pyi +33 -0
  220. sweep_solver-0.1.0/src/sweep/propagator/options.py +222 -0
  221. sweep_solver-0.1.0/src/sweep/propagator/options.pyi +111 -0
  222. sweep_solver-0.1.0/src/sweep/propagator/torch.py +374 -0
  223. sweep_solver-0.1.0/src/sweep/propagator/torch.pyi +47 -0
  224. sweep_solver-0.1.0/src/sweep/receivers/__init__.py +0 -0
  225. sweep_solver-0.1.0/src/sweep/receivers/base.py +6 -0
  226. sweep_solver-0.1.0/src/sweep/receivers/jax.py +18 -0
  227. sweep_solver-0.1.0/src/sweep/receivers/torch.py +55 -0
  228. sweep_solver-0.1.0/src/sweep/scalars.py +150 -0
  229. sweep_solver-0.1.0/src/sweep/signal.py +89 -0
  230. sweep_solver-0.1.0/src/sweep/sources/__init__.py +0 -0
  231. sweep_solver-0.1.0/src/sweep/sources/base.py +24 -0
  232. sweep_solver-0.1.0/src/sweep/sources/jax.py +54 -0
  233. sweep_solver-0.1.0/src/sweep/sources/torch.py +70 -0
  234. sweep_solver-0.1.0/src/sweep/utils/__init__.py +0 -0
  235. sweep_solver-0.1.0/src/sweep/utils/curvilinear.py +235 -0
  236. sweep_solver-0.1.0/src/sweep/utils/general.py +121 -0
  237. sweep_solver-0.1.0/src/sweep/utils/jax.py +50 -0
  238. sweep_solver-0.1.0/src/sweep/utils/torch.py +41 -0
  239. sweep_solver-0.1.0/src/sweep_solver.egg-info/PKG-INFO +160 -0
  240. sweep_solver-0.1.0/src/sweep_solver.egg-info/SOURCES.txt +278 -0
  241. sweep_solver-0.1.0/src/sweep_solver.egg-info/dependency_links.txt +1 -0
  242. sweep_solver-0.1.0/src/sweep_solver.egg-info/entry_points.txt +3 -0
  243. sweep_solver-0.1.0/src/sweep_solver.egg-info/requires.txt +23 -0
  244. sweep_solver-0.1.0/src/sweep_solver.egg-info/top_level.txt +2 -0
  245. sweep_solver-0.1.0/test/test_acoustic_curvilinear.py +196 -0
  246. sweep_solver-0.1.0/test/test_acoustic_tti.py +115 -0
  247. sweep_solver-0.1.0/test/test_acoustic_vti_1st.py +1097 -0
  248. sweep_solver-0.1.0/test/test_boundary_dtype_env_leak.py +119 -0
  249. sweep_solver-0.1.0/test/test_boundary_int_idx_overflow.py +95 -0
  250. sweep_solver-0.1.0/test/test_boundary_storage_dtype_validation.py +243 -0
  251. sweep_solver-0.1.0/test/test_c_default_boundary_saving.py +108 -0
  252. sweep_solver-0.1.0/test/test_checkpoint_batch_shrink.py +106 -0
  253. sweep_solver-0.1.0/test/test_companion_aliases.py +92 -0
  254. sweep_solver-0.1.0/test/test_compiled_del_no_setattr_typeerror.py +113 -0
  255. sweep_solver-0.1.0/test/test_custom_gradient.py +95 -0
  256. sweep_solver-0.1.0/test/test_das_equations.py +577 -0
  257. sweep_solver-0.1.0/test/test_datasets_registry.py +158 -0
  258. sweep_solver-0.1.0/test/test_eager_boundary_saving.py +487 -0
  259. sweep_solver-0.1.0/test/test_elastic_apm.py +361 -0
  260. sweep_solver-0.1.0/test/test_elastic_batched_models.py +214 -0
  261. sweep_solver-0.1.0/test/test_elastic_curvilinear.py +151 -0
  262. sweep_solver-0.1.0/test/test_elastic_tti.py +171 -0
  263. sweep_solver-0.1.0/test/test_elastic_vector_reflectivity.py +433 -0
  264. sweep_solver-0.1.0/test/test_elastic_vr_cuda_parity.py +93 -0
  265. sweep_solver-0.1.0/test/test_elastic_vr_gradient_consistency.py +346 -0
  266. sweep_solver-0.1.0/test/test_equations.py +102 -0
  267. sweep_solver-0.1.0/test/test_free_surface_concat.py +94 -0
  268. sweep_solver-0.1.0/test/test_free_surface_topo.py +255 -0
  269. sweep_solver-0.1.0/test/test_installation_smoke.py +42 -0
  270. sweep_solver-0.1.0/test/test_jax_boundary_saving.py +363 -0
  271. sweep_solver-0.1.0/test/test_jax_jit_tracing.py +127 -0
  272. sweep_solver-0.1.0/test/test_multi_device_cuda_guard.py +80 -0
  273. sweep_solver-0.1.0/test/test_op.py +44 -0
  274. sweep_solver-0.1.0/test/test_source_io_contract.py +161 -0
  275. sweep_solver-0.1.0/test/test_sweep_pytorch.py +88 -0
  276. sweep_solver-0.1.0/test/test_topography_acoustic2d.py +358 -0
  277. sweep_solver-0.1.0/test/test_topography_elastic2d.py +258 -0
  278. sweep_solver-0.1.0/test/test_topography_helpers.py +189 -0
  279. sweep_solver-0.1.0/test/test_visco_acoustic.py +282 -0
  280. sweep_solver-0.1.0/test/test_visco_acoustic_jax.py +120 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to do so, subject to the
10
+ following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include LICENSE
2
+ include README.md
3
+ include build_config.py
4
+ include setup_cuda.py
5
+ recursive-include src/sweep/csrc *.cpp *.cu *.cuh *.h CMakeLists.txt
@@ -0,0 +1,160 @@
1
+ Metadata-Version: 2.1
2
+ Name: sweep-solver
3
+ Version: 0.1.0
4
+ Summary: Seismic Wave Equation Exploration Platform — equations, propagators, operators.
5
+ Author-email: Shaowen Wang <shaowen.wang@kaust.edu.sa>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/DeepWave-KAUST/sweep
8
+ Project-URL: Issues, https://github.com/DeepWave-KAUST/sweep/issues
9
+ Keywords: fwi,geophysics,seismic,wave-equation,propagator,cuda,pytorch,jax
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Physics
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: numpy>=1.20
25
+ Requires-Dist: scipy>=1.7
26
+ Requires-Dist: torch
27
+ Requires-Dist: ninja
28
+ Provides-Extra: cuda
29
+ Requires-Dist: torch; extra == "cuda"
30
+ Provides-Extra: torch
31
+ Requires-Dist: torch; extra == "torch"
32
+ Provides-Extra: jax
33
+ Requires-Dist: jax; extra == "jax"
34
+ Requires-Dist: jaxlib; extra == "jax"
35
+ Provides-Extra: all
36
+ Requires-Dist: torch; extra == "all"
37
+ Requires-Dist: jax; extra == "all"
38
+ Requires-Dist: jaxlib; extra == "all"
39
+ Provides-Extra: datasets
40
+ Requires-Dist: requests>=2.25; extra == "datasets"
41
+ Requires-Dist: tqdm>=4.60; extra == "datasets"
42
+
43
+ <p align="center">
44
+ <picture>
45
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/logo/sweep-icon-dark.svg">
46
+ <img src="docs/assets/logo/sweep-icon-light.svg" alt="SWEEP" width="180">
47
+ </picture>
48
+ </p>
49
+
50
+ <h1 align="center">SWEEP</h1>
51
+
52
+ <p align="center">
53
+ <a href="https://deepwave-kaust.github.io/sweep/"><img alt="Docs" src="https://img.shields.io/badge/docs-online-blue?logo=readthedocs&logoColor=white"></a>
54
+ <a href="https://opensource.org/licenses/MIT"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
55
+ <a href="https://pytorch.org"><img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-2.0%2B-EE4C2C?logo=pytorch&logoColor=white"></a>
56
+ </p>
57
+
58
+ <p align="center">English | <a href="README.zh-CN.md">中文</a></p>
59
+
60
+ **Seismic Wave Equation Exploration Platform** — a differentiable framework for seismic wave-equation modeling, migration, and full-waveform inversion. One API, 20+ equations (acoustic / elastic / VTI / TTI / DAS), PyTorch and JAX backends, eager and compiled CUDA paths.
61
+
62
+ 📖 **Documentation**: <https://deepwave-kaust.github.io/sweep/>
63
+
64
+ ## Install
65
+
66
+ **From PyPI** — one wheel, any PyTorch version, any Python 3:
67
+
68
+ ```bash
69
+ pip install sweepx
70
+ python -c "import sweep; sweep.precompile()" # build the CUDA backend now (one-time ~3–5 min)
71
+ ```
72
+
73
+ `sweepx` ships the C++/CUDA *sources*; the compiled backend (`impl='c'`) is compiled
74
+ against **your** torch — only for your GPU's architecture, then cached in
75
+ `~/.cache/torch_extensions`. The `precompile()` line does it up front; drop it and it
76
+ happens automatically on first use of `impl='c'`. No torch/CUDA version lock-in. Needs
77
+ a CUDA GPU + `nvcc >= 12.4` (a system install, your cluster's `module load cuda`, or
78
+ `conda install -c nvidia cuda-toolkit`); the pure-Python **eager** / **JAX** backends
79
+ work without nvcc.
80
+
81
+ **From source** (a clone):
82
+
83
+ ```bash
84
+ # pure-Python (PyTorch / JAX eager path); impl='c' JIT-compiles on first use
85
+ pip install .
86
+
87
+ # prebuild the C++/CUDA extension now — skips the first-use compile (needs nvcc)
88
+ SWEEP_BUILD_CUDA=1 pip install -v ".[cuda]" --no-build-isolation
89
+ ```
90
+
91
+ If the prebuild can't auto-detect your GPU, set `TORCH_CUDA_ARCH_LIST` (e.g. `"7.0"`
92
+ V100, `"8.0"` A100, `"8.9"` RTX 6000 Ada) before the second command.
93
+
94
+ <sub>`sweepx` is the PyPI distribution name; you `import sweep` (the `scikit-learn` → `import sklearn`
95
+ pattern, because the bare name `sweep` is taken on PyPI). `pip install sweep-solver` is equivalent.
96
+ Full install notes are in [the docs](https://deepwave-kaust.github.io/sweep/getting-started/installation/).</sub>
97
+
98
+ ## Hello SWEEP
99
+
100
+ One shot, one receiver, one `.backward()` — read off the velocity-model gradient for a single trace:
101
+
102
+ ```python
103
+ import numpy as np
104
+ import torch
105
+ from sweep.equations import Acoustic
106
+ from sweep.propagator.torch import PropTorch
107
+ from sweep.signal import ricker
108
+
109
+ shape = (96, 128)
110
+ dh, dt, nt = 10.0, 0.002, 800
111
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
112
+
113
+ vp_true = np.full(shape, 1500.0, dtype=np.float32)
114
+ vp_true[shape[0] // 2:, :] = 2500.0
115
+ vp_init = np.full(shape, 1500.0, dtype=np.float32)
116
+
117
+ solver = PropTorch(Acoustic(device=device), shape=shape, dh=dh, dt=dt,
118
+ dev=device, pml_type="cpmlr", use_ckpt=False)
119
+
120
+ t = np.arange(nt) * dt
121
+ wavelet = ricker(t - 0.14, f=10.0).astype(np.float32)
122
+ sources = np.array([[shape[1] // 4, shape[0] // 2]], dtype=np.int64)
123
+ receivers = np.array([[[3 * shape[1] // 4, shape[0] // 2]]], dtype=np.int64)
124
+
125
+ with torch.no_grad():
126
+ obs = solver(wavelet, sources, receivers, models=[torch.tensor(vp_true, device=device)])
127
+
128
+ vp_t = torch.tensor(vp_init, device=device, requires_grad=True)
129
+ pred = solver(wavelet, sources, receivers, models=[vp_t])
130
+ (0.5 * (pred - obs).pow(2).sum()).backward()
131
+
132
+ print("vp gradient shape:", tuple(vp_t.grad.shape))
133
+ ```
134
+
135
+ Swap `Acoustic` for `Elastic`, `AcousticVTI`, `ElasticTTI`, ... — the surrounding code is unchanged.
136
+
137
+ ## Notebooks & examples
138
+
139
+ - **Hello SWEEP** — forward / backward / 5-line FWI loop: [`examples/notebooks/00_hello_fwi.ipynb`](examples/notebooks/00_hello_fwi.ipynb)
140
+ - **FWI on Marmousi** (acoustic / elastic / multiscale): see [`examples/notebooks/01_*`–`03_*`](examples/notebooks/)
141
+ - **Wavefields, DAS, anisotropic, RTM**: [`examples/notebooks/04_*`–`08_*`](examples/notebooks/)
142
+ - **Production scripts** (multi-GPU, MPI shot parallelism, multi-shot batching): under [`examples/`](examples/)
143
+
144
+ ## Citing
145
+
146
+ ```bibtex
147
+ @misc{wang2026sweep,
148
+ title = {{SWEEP} ({S}eismic {W}ave {E}quation {E}xploration {P}latform):
149
+ A Unified Solver Framework for Differentiable Wave Physics},
150
+ author = {Wang, Shaowen and Alkhalifah, Tariq},
151
+ year = {2026},
152
+ eprint = {2604.14189},
153
+ archivePrefix = {arXiv},
154
+ url = {https://arxiv.org/abs/2604.14189},
155
+ }
156
+ ```
157
+
158
+ ## License
159
+
160
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,118 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/logo/sweep-icon-dark.svg">
4
+ <img src="docs/assets/logo/sweep-icon-light.svg" alt="SWEEP" width="180">
5
+ </picture>
6
+ </p>
7
+
8
+ <h1 align="center">SWEEP</h1>
9
+
10
+ <p align="center">
11
+ <a href="https://deepwave-kaust.github.io/sweep/"><img alt="Docs" src="https://img.shields.io/badge/docs-online-blue?logo=readthedocs&logoColor=white"></a>
12
+ <a href="https://opensource.org/licenses/MIT"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg"></a>
13
+ <a href="https://pytorch.org"><img alt="PyTorch" src="https://img.shields.io/badge/PyTorch-2.0%2B-EE4C2C?logo=pytorch&logoColor=white"></a>
14
+ </p>
15
+
16
+ <p align="center">English | <a href="README.zh-CN.md">中文</a></p>
17
+
18
+ **Seismic Wave Equation Exploration Platform** — a differentiable framework for seismic wave-equation modeling, migration, and full-waveform inversion. One API, 20+ equations (acoustic / elastic / VTI / TTI / DAS), PyTorch and JAX backends, eager and compiled CUDA paths.
19
+
20
+ 📖 **Documentation**: <https://deepwave-kaust.github.io/sweep/>
21
+
22
+ ## Install
23
+
24
+ **From PyPI** — one wheel, any PyTorch version, any Python 3:
25
+
26
+ ```bash
27
+ pip install sweepx
28
+ python -c "import sweep; sweep.precompile()" # build the CUDA backend now (one-time ~3–5 min)
29
+ ```
30
+
31
+ `sweepx` ships the C++/CUDA *sources*; the compiled backend (`impl='c'`) is compiled
32
+ against **your** torch — only for your GPU's architecture, then cached in
33
+ `~/.cache/torch_extensions`. The `precompile()` line does it up front; drop it and it
34
+ happens automatically on first use of `impl='c'`. No torch/CUDA version lock-in. Needs
35
+ a CUDA GPU + `nvcc >= 12.4` (a system install, your cluster's `module load cuda`, or
36
+ `conda install -c nvidia cuda-toolkit`); the pure-Python **eager** / **JAX** backends
37
+ work without nvcc.
38
+
39
+ **From source** (a clone):
40
+
41
+ ```bash
42
+ # pure-Python (PyTorch / JAX eager path); impl='c' JIT-compiles on first use
43
+ pip install .
44
+
45
+ # prebuild the C++/CUDA extension now — skips the first-use compile (needs nvcc)
46
+ SWEEP_BUILD_CUDA=1 pip install -v ".[cuda]" --no-build-isolation
47
+ ```
48
+
49
+ If the prebuild can't auto-detect your GPU, set `TORCH_CUDA_ARCH_LIST` (e.g. `"7.0"`
50
+ V100, `"8.0"` A100, `"8.9"` RTX 6000 Ada) before the second command.
51
+
52
+ <sub>`sweepx` is the PyPI distribution name; you `import sweep` (the `scikit-learn` → `import sklearn`
53
+ pattern, because the bare name `sweep` is taken on PyPI). `pip install sweep-solver` is equivalent.
54
+ Full install notes are in [the docs](https://deepwave-kaust.github.io/sweep/getting-started/installation/).</sub>
55
+
56
+ ## Hello SWEEP
57
+
58
+ One shot, one receiver, one `.backward()` — read off the velocity-model gradient for a single trace:
59
+
60
+ ```python
61
+ import numpy as np
62
+ import torch
63
+ from sweep.equations import Acoustic
64
+ from sweep.propagator.torch import PropTorch
65
+ from sweep.signal import ricker
66
+
67
+ shape = (96, 128)
68
+ dh, dt, nt = 10.0, 0.002, 800
69
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
70
+
71
+ vp_true = np.full(shape, 1500.0, dtype=np.float32)
72
+ vp_true[shape[0] // 2:, :] = 2500.0
73
+ vp_init = np.full(shape, 1500.0, dtype=np.float32)
74
+
75
+ solver = PropTorch(Acoustic(device=device), shape=shape, dh=dh, dt=dt,
76
+ dev=device, pml_type="cpmlr", use_ckpt=False)
77
+
78
+ t = np.arange(nt) * dt
79
+ wavelet = ricker(t - 0.14, f=10.0).astype(np.float32)
80
+ sources = np.array([[shape[1] // 4, shape[0] // 2]], dtype=np.int64)
81
+ receivers = np.array([[[3 * shape[1] // 4, shape[0] // 2]]], dtype=np.int64)
82
+
83
+ with torch.no_grad():
84
+ obs = solver(wavelet, sources, receivers, models=[torch.tensor(vp_true, device=device)])
85
+
86
+ vp_t = torch.tensor(vp_init, device=device, requires_grad=True)
87
+ pred = solver(wavelet, sources, receivers, models=[vp_t])
88
+ (0.5 * (pred - obs).pow(2).sum()).backward()
89
+
90
+ print("vp gradient shape:", tuple(vp_t.grad.shape))
91
+ ```
92
+
93
+ Swap `Acoustic` for `Elastic`, `AcousticVTI`, `ElasticTTI`, ... — the surrounding code is unchanged.
94
+
95
+ ## Notebooks & examples
96
+
97
+ - **Hello SWEEP** — forward / backward / 5-line FWI loop: [`examples/notebooks/00_hello_fwi.ipynb`](examples/notebooks/00_hello_fwi.ipynb)
98
+ - **FWI on Marmousi** (acoustic / elastic / multiscale): see [`examples/notebooks/01_*`–`03_*`](examples/notebooks/)
99
+ - **Wavefields, DAS, anisotropic, RTM**: [`examples/notebooks/04_*`–`08_*`](examples/notebooks/)
100
+ - **Production scripts** (multi-GPU, MPI shot parallelism, multi-shot batching): under [`examples/`](examples/)
101
+
102
+ ## Citing
103
+
104
+ ```bibtex
105
+ @misc{wang2026sweep,
106
+ title = {{SWEEP} ({S}eismic {W}ave {E}quation {E}xploration {P}latform):
107
+ A Unified Solver Framework for Differentiable Wave Physics},
108
+ author = {Wang, Shaowen and Alkhalifah, Tariq},
109
+ year = {2026},
110
+ eprint = {2604.14189},
111
+ archivePrefix = {arXiv},
112
+ url = {https://arxiv.org/abs/2604.14189},
113
+ }
114
+ ```
115
+
116
+ ## License
117
+
118
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,258 @@
1
+ import glob
2
+ import inspect
3
+ import os
4
+ import sys
5
+ from distutils import log
6
+
7
+ try:
8
+ import packaging.utils as packaging_utils
9
+ except ImportError:
10
+ packaging_utils = None
11
+
12
+ try:
13
+ import setuptools._core_metadata as setuptools_core_metadata
14
+ except ImportError:
15
+ setuptools_core_metadata = None
16
+
17
+
18
+ ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
19
+ PACKAGE_VERSION = "0.1.0"
20
+
21
+
22
+ def env_flag_enabled(name):
23
+ value = os.environ.get(name, "")
24
+ return value.strip().lower() in {"1", "true", "yes", "on"}
25
+
26
+
27
+ def openmp_flags():
28
+ if sys.platform == "win32":
29
+ return ["/openmp"]
30
+ if sys.platform == "darwin":
31
+ return []
32
+ return ["-fopenmp"]
33
+
34
+
35
+ def configure_cuda_arch_list():
36
+ """Avoid PyTorch's empty GPU-arch auto-detection on login/CPU nodes."""
37
+ if os.environ.get("TORCH_CUDA_ARCH_LIST"):
38
+ return
39
+
40
+ arch_list = os.environ.get("SWEEP_CUDA_ARCH_LIST", "7.0")
41
+ os.environ["TORCH_CUDA_ARCH_LIST"] = arch_list
42
+ log.warn(
43
+ "TORCH_CUDA_ARCH_LIST is not set; defaulting to %s. "
44
+ "Set TORCH_CUDA_ARCH_LIST or SWEEP_CUDA_ARCH_LIST to target other GPUs.",
45
+ arch_list,
46
+ )
47
+
48
+
49
+ def is_metadata_only_invocation():
50
+ metadata_commands = {"egg_info", "dist_info", "prepare_metadata_for_build_wheel"}
51
+ return any(arg in metadata_commands for arg in sys.argv[1:])
52
+
53
+
54
+ def patch_packaging_compat():
55
+ if packaging_utils is None:
56
+ return
57
+
58
+ signature = inspect.signature(packaging_utils.canonicalize_version)
59
+ if "strip_trailing_zero" in signature.parameters:
60
+ return
61
+
62
+ original = packaging_utils.canonicalize_version
63
+
64
+ def canonicalize_version_compat(version, strip_trailing_zero=True):
65
+ return original(version)
66
+
67
+ packaging_utils.canonicalize_version = canonicalize_version_compat
68
+ if setuptools_core_metadata is not None:
69
+ setuptools_core_metadata.canonicalize_version = canonicalize_version_compat
70
+
71
+
72
+ def get_sources():
73
+ """Collect C++/CUDA sources for the ``sweep._C`` extension.
74
+
75
+ Honours the ``SWEEP_SKIP_CPU`` environment variable: when set to a
76
+ truthy value (1, true, yes, on), the heavy ``cpu/equations/*`` tree
77
+ (~19k lines, often the build-time bottleneck) is *excluded* and a tiny
78
+ stub is linked in its place. The stub keeps `bindings/module.cpp`
79
+ linking and routes every call to the CUDA path; attempting to use a
80
+ CPU tensor raises a clear TORCH_CHECK message.
81
+
82
+ This is intended for users who only ever run on CUDA — typically HPC
83
+ deployments where the CPU C++ path would be dead weight.
84
+ """
85
+ cuda_sources = (
86
+ glob.glob("src/sweep/csrc/cuda/common/**/*.cu", recursive=True)
87
+ + glob.glob("src/sweep/csrc/cuda/equations/**/*.cu", recursive=True)
88
+ )
89
+ binding_sources = ["src/sweep/csrc/bindings/module.cpp"]
90
+
91
+ if env_flag_enabled("SWEEP_SKIP_CPU"):
92
+ log.warn(
93
+ "SWEEP_SKIP_CPU=1: skipping cpu/equations/* (~19k LoC); linking "
94
+ "cpu_binding_stub.cpp instead. CPU tensors will raise a clear "
95
+ "error at call time."
96
+ )
97
+ cpu_sources = ["src/sweep/csrc/cpu/cpu_binding_stub.cpp"]
98
+ else:
99
+ cpu_sources = glob.glob("src/sweep/csrc/cpu/**/*.cpp", recursive=True)
100
+ # Defensive: don't accidentally include the stub if it's globbed
101
+ cpu_sources = [
102
+ s for s in cpu_sources
103
+ if not s.endswith("cpu_binding_stub.cpp")
104
+ ]
105
+
106
+ return cpu_sources + cuda_sources + binding_sources
107
+
108
+
109
+ def _check_ninja_on_path():
110
+ """Print an actionable note if torch's ninja-binary probe will fail.
111
+
112
+ Torch's ``is_ninja_available()`` shells out to ``ninja --version`` on
113
+ PATH, NOT to the bundled Python ``ninja`` package. If the conda env is
114
+ not activated (e.g. invoking ``/path/to/envs/X/bin/python setup.py``
115
+ directly), the ninja binary at ``<env>/bin/ninja`` is invisible and
116
+ torch silently falls back to the *slow* distutils sequential build —
117
+ ~6× slower in practice. Loud-warn now, instead of having the user
118
+ discover it 20 minutes into a serial compile.
119
+ """
120
+ import shutil
121
+
122
+ if shutil.which("ninja") is not None:
123
+ return # binary on PATH — torch will use ninja, all good
124
+
125
+ # Bundled ninja package? Tell the user how to expose it.
126
+ bundled = None
127
+ try:
128
+ import ninja as _ninja_pkg
129
+ bundled = os.path.join(os.path.dirname(_ninja_pkg.__file__), "..", "..", "..", "..", "bin", "ninja")
130
+ bundled = os.path.normpath(bundled)
131
+ if not os.path.exists(bundled):
132
+ # Try the conda env layout
133
+ python_exec = sys.executable
134
+ env_bin = os.path.dirname(python_exec)
135
+ candidate = os.path.join(env_bin, "ninja")
136
+ bundled = candidate if os.path.exists(candidate) else None
137
+ except ImportError:
138
+ pass
139
+
140
+ msg = (
141
+ "ninja binary not found on PATH. Torch will fall back to the slow "
142
+ "distutils sequential build (~6× slower). "
143
+ )
144
+ if bundled and os.path.exists(bundled):
145
+ msg += (
146
+ f"A ninja binary is bundled at {bundled}; either activate your "
147
+ "conda env (`conda activate <env>`) so PATH includes it, or run "
148
+ f"PATH='{os.path.dirname(bundled)}:$PATH' python setup.py ..."
149
+ )
150
+ else:
151
+ msg += "Install ninja-build (`apt install ninja-build` or `pip install ninja`)."
152
+ log.warn(msg)
153
+ print(f"WARNING: {msg}", file=sys.stderr, flush=True)
154
+
155
+
156
+ def make_build_extension(BuildExtension):
157
+ def emit(message):
158
+ print(message, file=sys.stderr, flush=True)
159
+ log.info(message)
160
+
161
+ class SweepBuildExtension(BuildExtension):
162
+ def run(self):
163
+ self.verbose = max(getattr(self, "verbose", 1), 2)
164
+ _check_ninja_on_path()
165
+ for ext in self.extensions:
166
+ sources = list(getattr(ext, "sources", []))
167
+ emit(f"Building CUDA extension '{ext.name}' with {len(sources)} source files")
168
+ for index, source in enumerate(sources, start=1):
169
+ emit(f" [{index}/{len(sources)}] {source}")
170
+ super().run()
171
+
172
+ def build_extensions(self):
173
+ self.verbose = max(getattr(self, "verbose", 1), 2)
174
+ emit("Starting C++/CUDA compilation")
175
+ super().build_extensions()
176
+ emit("Finished C++/CUDA compilation")
177
+
178
+ return SweepBuildExtension
179
+
180
+
181
+ def build_ext_kwargs(build_cuda=None):
182
+ """Return setup() kwargs for the optional AOT C++/CUDA extension.
183
+
184
+ The default distribution is **JIT** (see ``sweep/_jit.py``): one ``py3-none``
185
+ wheel ships the C++/CUDA sources and compiles ``sweep._C`` against the user's
186
+ own torch on first use — so this returns NO ``ext_modules`` and every dep
187
+ comes from ``pyproject.toml``. The ``SWEEP_BUILD_CUDA=1`` path is kept only
188
+ for building optional pre-compiled fast-path wheels (e.g. a GitHub release),
189
+ never for the PyPI wheel.
190
+ """
191
+ if build_cuda is None:
192
+ build_cuda = env_flag_enabled("SWEEP_BUILD_CUDA")
193
+
194
+ kwargs = {
195
+ "ext_modules": [],
196
+ "cmdclass": {},
197
+ }
198
+
199
+ if not build_cuda:
200
+ return kwargs
201
+
202
+ try:
203
+ from torch.utils.cpp_extension import BuildExtension, CUDAExtension
204
+ except ImportError as exc:
205
+ if is_metadata_only_invocation():
206
+ log.warn(
207
+ "Skipping CUDA extension setup during metadata generation because PyTorch "
208
+ "is not installed in the current build environment."
209
+ )
210
+ return kwargs
211
+
212
+ raise RuntimeError(
213
+ "Building sweep with SWEEP_BUILD_CUDA=1 requires PyTorch to be installed first, "
214
+ "because the CUDA extension uses torch.utils.cpp_extension. "
215
+ "In a pure JAX environment, install without SWEEP_BUILD_CUDA or install PyTorch "
216
+ "before building the CUDA extension."
217
+ ) from exc
218
+
219
+ SweepBuildExtension = make_build_extension(BuildExtension)
220
+ omp_flags = openmp_flags()
221
+ configure_cuda_arch_list()
222
+
223
+ # Optional extra nvcc flags (e.g. -DELASTIC3D_LB_MINBLOCKS=6 to retune a
224
+ # forward launch_bounds without editing kernel source). Space-separated.
225
+ extra_nvcc = os.environ.get("SWEEP_EXTRA_NVCC", "").split()
226
+
227
+ kwargs["ext_modules"] = [
228
+ CUDAExtension(
229
+ name="sweep._C",
230
+ sources=get_sources(),
231
+ include_dirs=[
232
+ os.path.join(ROOT_DIR, "src/sweep/csrc"),
233
+ os.path.join(ROOT_DIR, "src/sweep/csrc/bindings"),
234
+ os.path.join(ROOT_DIR, "src/sweep/csrc/shared"),
235
+ os.path.join(ROOT_DIR, "src/sweep/csrc/cuda"),
236
+ os.path.join(ROOT_DIR, "src/sweep/csrc/cuda/common"),
237
+ os.path.join(ROOT_DIR, "src/sweep/csrc/cuda/equations"),
238
+ ],
239
+ extra_compile_args={
240
+ "cxx": ["-O3", "-Wno-attributes", *omp_flags],
241
+ "nvcc": [
242
+ "-O3",
243
+ "--use_fast_math",
244
+ "--threads=16",
245
+ "-Xcompiler=-Wno-deprecated-declarations",
246
+ *extra_nvcc,
247
+ ],
248
+ },
249
+ # RPATH so the shipped wheel resolves libtorch/libc10 against the
250
+ # USER's torch (auditwheel --exclude keeps those libs external).
251
+ # Belt-and-suspenders: sweep always imports torch before sweep._C.
252
+ extra_link_args=[*omp_flags, "-Wl,-rpath,$ORIGIN/../torch/lib"],
253
+ )
254
+ ]
255
+ kwargs["cmdclass"] = {
256
+ "build_ext": SweepBuildExtension.with_options(use_ninja=True)
257
+ }
258
+ return kwargs
@@ -0,0 +1,74 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sweep-solver"
7
+ version = "0.1.0"
8
+ description = "Seismic Wave Equation Exploration Platform — equations, propagators, operators."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Shaowen Wang", email = "shaowen.wang@kaust.edu.sa"},
14
+ ]
15
+ keywords = ["fwi", "geophysics", "seismic", "wave-equation", "propagator", "cuda", "pytorch", "jax"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Science/Research",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: POSIX :: Linux",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Scientific/Engineering :: Physics",
28
+ ]
29
+ # JIT distribution: one py3-none wheel ships the C++/CUDA *sources* and compiles
30
+ # sweep._C against the user's OWN torch on first use (see sweep/_jit.py), so a
31
+ # single wheel works with any torch version + any Python 3. torch is unpinned.
32
+ # The first-use compile needs nvcc from a CUDA toolkit (system / `module load
33
+ # cuda` / `conda install -c nvidia cuda-nvcc`) — the pip `nvidia-cuda-nvcc-cu12`
34
+ # wheel ships only ptxas, not the nvcc frontend, so it can't be relied on.
35
+ dependencies = [
36
+ "numpy>=1.20",
37
+ "scipy>=1.7",
38
+ "torch",
39
+ "ninja",
40
+ ]
41
+
42
+ [project.optional-dependencies]
43
+ cuda = ["torch"]
44
+ torch = ["torch"]
45
+ jax = ["jax", "jaxlib"]
46
+ all = ["torch", "jax", "jaxlib"]
47
+ # Benchmark dataset loaders (sweep.datasets). Embedded demo models need
48
+ # nothing extra; parsing is numpy-only. This extra only adds the HTTP client
49
+ # used to fetch the downloadable full-size benchmarks.
50
+ datasets = ["requests>=2.25", "tqdm>=4.60"]
51
+
52
+ [project.urls]
53
+ Homepage = "https://github.com/DeepWave-KAUST/sweep"
54
+ Issues = "https://github.com/DeepWave-KAUST/sweep/issues"
55
+
56
+ [project.scripts]
57
+ sweep = "sweep.cli:main"
58
+ sweep-datasets = "sweep.datasets.cli:main"
59
+
60
+ [tool.setuptools]
61
+ package-dir = {"" = "src"}
62
+
63
+ [tool.setuptools.packages.find]
64
+ where = ["src"]
65
+ include = ["sweep*", "geophyai*"]
66
+ exclude = ["sweep.csrc*"]
67
+
68
+ # Ship the C++/CUDA sources inside the wheel — sweep._C is JIT-compiled from them
69
+ # on first use (csrc is data, not an importable package, hence excluded above).
70
+ [tool.setuptools.package-data]
71
+ sweep = [
72
+ "csrc/**/*.cu", "csrc/**/*.cuh", "csrc/**/*.cpp",
73
+ "csrc/**/*.h", "csrc/**/*.hpp", "csrc/**/CMakeLists.txt",
74
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,15 @@
1
+ import os
2
+ import sys
3
+
4
+ from setuptools import setup
5
+
6
+ ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
7
+ if ROOT_DIR not in sys.path:
8
+ sys.path.insert(0, ROOT_DIR)
9
+
10
+ from build_config import build_ext_kwargs, patch_packaging_compat
11
+
12
+
13
+ patch_packaging_compat()
14
+
15
+ setup(**build_ext_kwargs())
@@ -0,0 +1,16 @@
1
+ import os
2
+ import sys
3
+
4
+ from setuptools import setup
5
+
6
+ ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
7
+ if ROOT_DIR not in sys.path:
8
+ sys.path.insert(0, ROOT_DIR)
9
+
10
+ from build_config import build_ext_kwargs, patch_packaging_compat
11
+
12
+
13
+ patch_packaging_compat()
14
+ os.environ["SWEEP_BUILD_CUDA"] = "1"
15
+
16
+ setup(**build_ext_kwargs(build_cuda=True))
@@ -0,0 +1,4 @@
1
+ import sys
2
+ import sweep
3
+
4
+ sys.modules['geophyai'] = sweep