warp-lang 1.10.0__py3-none-macosx_11_0_arm64.whl

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.

Potentially problematic release.


This version of warp-lang might be problematic. Click here for more details.

Files changed (468) hide show
  1. warp/__init__.py +334 -0
  2. warp/__init__.pyi +5856 -0
  3. warp/_src/__init__.py +14 -0
  4. warp/_src/autograd.py +1077 -0
  5. warp/_src/build.py +620 -0
  6. warp/_src/build_dll.py +642 -0
  7. warp/_src/builtins.py +10555 -0
  8. warp/_src/codegen.py +4361 -0
  9. warp/_src/config.py +178 -0
  10. warp/_src/constants.py +59 -0
  11. warp/_src/context.py +8352 -0
  12. warp/_src/dlpack.py +464 -0
  13. warp/_src/fabric.py +362 -0
  14. warp/_src/fem/__init__.py +14 -0
  15. warp/_src/fem/adaptivity.py +510 -0
  16. warp/_src/fem/cache.py +689 -0
  17. warp/_src/fem/dirichlet.py +190 -0
  18. warp/_src/fem/domain.py +553 -0
  19. warp/_src/fem/field/__init__.py +131 -0
  20. warp/_src/fem/field/field.py +703 -0
  21. warp/_src/fem/field/nodal_field.py +403 -0
  22. warp/_src/fem/field/restriction.py +39 -0
  23. warp/_src/fem/field/virtual.py +1021 -0
  24. warp/_src/fem/geometry/__init__.py +32 -0
  25. warp/_src/fem/geometry/adaptive_nanogrid.py +782 -0
  26. warp/_src/fem/geometry/closest_point.py +99 -0
  27. warp/_src/fem/geometry/deformed_geometry.py +277 -0
  28. warp/_src/fem/geometry/element.py +854 -0
  29. warp/_src/fem/geometry/geometry.py +693 -0
  30. warp/_src/fem/geometry/grid_2d.py +478 -0
  31. warp/_src/fem/geometry/grid_3d.py +539 -0
  32. warp/_src/fem/geometry/hexmesh.py +956 -0
  33. warp/_src/fem/geometry/nanogrid.py +660 -0
  34. warp/_src/fem/geometry/partition.py +483 -0
  35. warp/_src/fem/geometry/quadmesh.py +597 -0
  36. warp/_src/fem/geometry/tetmesh.py +762 -0
  37. warp/_src/fem/geometry/trimesh.py +588 -0
  38. warp/_src/fem/integrate.py +2507 -0
  39. warp/_src/fem/linalg.py +385 -0
  40. warp/_src/fem/operator.py +398 -0
  41. warp/_src/fem/polynomial.py +231 -0
  42. warp/_src/fem/quadrature/__init__.py +17 -0
  43. warp/_src/fem/quadrature/pic_quadrature.py +318 -0
  44. warp/_src/fem/quadrature/quadrature.py +665 -0
  45. warp/_src/fem/space/__init__.py +248 -0
  46. warp/_src/fem/space/basis_function_space.py +499 -0
  47. warp/_src/fem/space/basis_space.py +681 -0
  48. warp/_src/fem/space/dof_mapper.py +253 -0
  49. warp/_src/fem/space/function_space.py +312 -0
  50. warp/_src/fem/space/grid_2d_function_space.py +179 -0
  51. warp/_src/fem/space/grid_3d_function_space.py +229 -0
  52. warp/_src/fem/space/hexmesh_function_space.py +255 -0
  53. warp/_src/fem/space/nanogrid_function_space.py +199 -0
  54. warp/_src/fem/space/partition.py +435 -0
  55. warp/_src/fem/space/quadmesh_function_space.py +222 -0
  56. warp/_src/fem/space/restriction.py +221 -0
  57. warp/_src/fem/space/shape/__init__.py +152 -0
  58. warp/_src/fem/space/shape/cube_shape_function.py +1107 -0
  59. warp/_src/fem/space/shape/shape_function.py +134 -0
  60. warp/_src/fem/space/shape/square_shape_function.py +928 -0
  61. warp/_src/fem/space/shape/tet_shape_function.py +829 -0
  62. warp/_src/fem/space/shape/triangle_shape_function.py +674 -0
  63. warp/_src/fem/space/tetmesh_function_space.py +270 -0
  64. warp/_src/fem/space/topology.py +461 -0
  65. warp/_src/fem/space/trimesh_function_space.py +193 -0
  66. warp/_src/fem/types.py +114 -0
  67. warp/_src/fem/utils.py +488 -0
  68. warp/_src/jax.py +188 -0
  69. warp/_src/jax_experimental/__init__.py +14 -0
  70. warp/_src/jax_experimental/custom_call.py +389 -0
  71. warp/_src/jax_experimental/ffi.py +1286 -0
  72. warp/_src/jax_experimental/xla_ffi.py +658 -0
  73. warp/_src/marching_cubes.py +710 -0
  74. warp/_src/math.py +416 -0
  75. warp/_src/optim/__init__.py +14 -0
  76. warp/_src/optim/adam.py +165 -0
  77. warp/_src/optim/linear.py +1608 -0
  78. warp/_src/optim/sgd.py +114 -0
  79. warp/_src/paddle.py +408 -0
  80. warp/_src/render/__init__.py +14 -0
  81. warp/_src/render/imgui_manager.py +291 -0
  82. warp/_src/render/render_opengl.py +3638 -0
  83. warp/_src/render/render_usd.py +939 -0
  84. warp/_src/render/utils.py +162 -0
  85. warp/_src/sparse.py +2718 -0
  86. warp/_src/tape.py +1208 -0
  87. warp/_src/thirdparty/__init__.py +0 -0
  88. warp/_src/thirdparty/appdirs.py +598 -0
  89. warp/_src/thirdparty/dlpack.py +145 -0
  90. warp/_src/thirdparty/unittest_parallel.py +676 -0
  91. warp/_src/torch.py +393 -0
  92. warp/_src/types.py +5888 -0
  93. warp/_src/utils.py +1695 -0
  94. warp/autograd.py +33 -0
  95. warp/bin/libwarp-clang.dylib +0 -0
  96. warp/bin/libwarp.dylib +0 -0
  97. warp/build.py +29 -0
  98. warp/build_dll.py +24 -0
  99. warp/codegen.py +24 -0
  100. warp/constants.py +24 -0
  101. warp/context.py +33 -0
  102. warp/dlpack.py +24 -0
  103. warp/examples/__init__.py +24 -0
  104. warp/examples/assets/bear.usd +0 -0
  105. warp/examples/assets/bunny.usd +0 -0
  106. warp/examples/assets/cube.usd +0 -0
  107. warp/examples/assets/nonuniform.usd +0 -0
  108. warp/examples/assets/nvidia_logo.png +0 -0
  109. warp/examples/assets/pixel.jpg +0 -0
  110. warp/examples/assets/rocks.nvdb +0 -0
  111. warp/examples/assets/rocks.usd +0 -0
  112. warp/examples/assets/sphere.usd +0 -0
  113. warp/examples/assets/square_cloth.usd +0 -0
  114. warp/examples/benchmarks/benchmark_api.py +389 -0
  115. warp/examples/benchmarks/benchmark_cloth.py +296 -0
  116. warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
  117. warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
  118. warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
  119. warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
  120. warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
  121. warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
  122. warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
  123. warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
  124. warp/examples/benchmarks/benchmark_gemm.py +164 -0
  125. warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
  126. warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
  127. warp/examples/benchmarks/benchmark_launches.py +301 -0
  128. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  129. warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
  130. warp/examples/browse.py +37 -0
  131. warp/examples/core/example_cupy.py +86 -0
  132. warp/examples/core/example_dem.py +241 -0
  133. warp/examples/core/example_fluid.py +299 -0
  134. warp/examples/core/example_graph_capture.py +150 -0
  135. warp/examples/core/example_marching_cubes.py +195 -0
  136. warp/examples/core/example_mesh.py +180 -0
  137. warp/examples/core/example_mesh_intersect.py +211 -0
  138. warp/examples/core/example_nvdb.py +182 -0
  139. warp/examples/core/example_raycast.py +111 -0
  140. warp/examples/core/example_raymarch.py +205 -0
  141. warp/examples/core/example_render_opengl.py +290 -0
  142. warp/examples/core/example_sample_mesh.py +300 -0
  143. warp/examples/core/example_sph.py +411 -0
  144. warp/examples/core/example_spin_lock.py +93 -0
  145. warp/examples/core/example_torch.py +211 -0
  146. warp/examples/core/example_wave.py +269 -0
  147. warp/examples/core/example_work_queue.py +118 -0
  148. warp/examples/distributed/example_jacobi_mpi.py +506 -0
  149. warp/examples/fem/example_adaptive_grid.py +286 -0
  150. warp/examples/fem/example_apic_fluid.py +469 -0
  151. warp/examples/fem/example_burgers.py +261 -0
  152. warp/examples/fem/example_convection_diffusion.py +181 -0
  153. warp/examples/fem/example_convection_diffusion_dg.py +225 -0
  154. warp/examples/fem/example_darcy_ls_optimization.py +489 -0
  155. warp/examples/fem/example_deformed_geometry.py +172 -0
  156. warp/examples/fem/example_diffusion.py +196 -0
  157. warp/examples/fem/example_diffusion_3d.py +225 -0
  158. warp/examples/fem/example_diffusion_mgpu.py +225 -0
  159. warp/examples/fem/example_distortion_energy.py +228 -0
  160. warp/examples/fem/example_elastic_shape_optimization.py +387 -0
  161. warp/examples/fem/example_magnetostatics.py +242 -0
  162. warp/examples/fem/example_mixed_elasticity.py +293 -0
  163. warp/examples/fem/example_navier_stokes.py +263 -0
  164. warp/examples/fem/example_nonconforming_contact.py +300 -0
  165. warp/examples/fem/example_stokes.py +213 -0
  166. warp/examples/fem/example_stokes_transfer.py +262 -0
  167. warp/examples/fem/example_streamlines.py +357 -0
  168. warp/examples/fem/utils.py +1047 -0
  169. warp/examples/interop/example_jax_callable.py +146 -0
  170. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  171. warp/examples/interop/example_jax_kernel.py +232 -0
  172. warp/examples/optim/example_diffray.py +561 -0
  173. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  174. warp/examples/tile/example_tile_block_cholesky.py +502 -0
  175. warp/examples/tile/example_tile_cholesky.py +88 -0
  176. warp/examples/tile/example_tile_convolution.py +66 -0
  177. warp/examples/tile/example_tile_fft.py +55 -0
  178. warp/examples/tile/example_tile_filtering.py +113 -0
  179. warp/examples/tile/example_tile_matmul.py +85 -0
  180. warp/examples/tile/example_tile_mcgp.py +191 -0
  181. warp/examples/tile/example_tile_mlp.py +385 -0
  182. warp/examples/tile/example_tile_nbody.py +199 -0
  183. warp/fabric.py +24 -0
  184. warp/fem/__init__.py +173 -0
  185. warp/fem/adaptivity.py +26 -0
  186. warp/fem/cache.py +30 -0
  187. warp/fem/dirichlet.py +24 -0
  188. warp/fem/field/__init__.py +24 -0
  189. warp/fem/field/field.py +26 -0
  190. warp/fem/geometry/__init__.py +21 -0
  191. warp/fem/geometry/closest_point.py +31 -0
  192. warp/fem/linalg.py +38 -0
  193. warp/fem/operator.py +32 -0
  194. warp/fem/polynomial.py +29 -0
  195. warp/fem/space/__init__.py +22 -0
  196. warp/fem/space/basis_space.py +24 -0
  197. warp/fem/space/shape/__init__.py +68 -0
  198. warp/fem/space/topology.py +24 -0
  199. warp/fem/types.py +24 -0
  200. warp/fem/utils.py +32 -0
  201. warp/jax.py +29 -0
  202. warp/jax_experimental/__init__.py +29 -0
  203. warp/jax_experimental/custom_call.py +29 -0
  204. warp/jax_experimental/ffi.py +39 -0
  205. warp/jax_experimental/xla_ffi.py +24 -0
  206. warp/marching_cubes.py +24 -0
  207. warp/math.py +37 -0
  208. warp/native/array.h +1687 -0
  209. warp/native/builtin.h +2327 -0
  210. warp/native/bvh.cpp +562 -0
  211. warp/native/bvh.cu +826 -0
  212. warp/native/bvh.h +555 -0
  213. warp/native/clang/clang.cpp +541 -0
  214. warp/native/coloring.cpp +622 -0
  215. warp/native/crt.cpp +51 -0
  216. warp/native/crt.h +568 -0
  217. warp/native/cuda_crt.h +1058 -0
  218. warp/native/cuda_util.cpp +677 -0
  219. warp/native/cuda_util.h +313 -0
  220. warp/native/error.cpp +77 -0
  221. warp/native/error.h +36 -0
  222. warp/native/exports.h +2023 -0
  223. warp/native/fabric.h +246 -0
  224. warp/native/hashgrid.cpp +311 -0
  225. warp/native/hashgrid.cu +89 -0
  226. warp/native/hashgrid.h +240 -0
  227. warp/native/initializer_array.h +41 -0
  228. warp/native/intersect.h +1253 -0
  229. warp/native/intersect_adj.h +375 -0
  230. warp/native/intersect_tri.h +348 -0
  231. warp/native/mat.h +5189 -0
  232. warp/native/mathdx.cpp +93 -0
  233. warp/native/matnn.h +221 -0
  234. warp/native/mesh.cpp +266 -0
  235. warp/native/mesh.cu +406 -0
  236. warp/native/mesh.h +2097 -0
  237. warp/native/nanovdb/GridHandle.h +533 -0
  238. warp/native/nanovdb/HostBuffer.h +591 -0
  239. warp/native/nanovdb/NanoVDB.h +6246 -0
  240. warp/native/nanovdb/NodeManager.h +323 -0
  241. warp/native/nanovdb/PNanoVDB.h +3390 -0
  242. warp/native/noise.h +859 -0
  243. warp/native/quat.h +1664 -0
  244. warp/native/rand.h +342 -0
  245. warp/native/range.h +145 -0
  246. warp/native/reduce.cpp +174 -0
  247. warp/native/reduce.cu +363 -0
  248. warp/native/runlength_encode.cpp +79 -0
  249. warp/native/runlength_encode.cu +61 -0
  250. warp/native/scan.cpp +47 -0
  251. warp/native/scan.cu +55 -0
  252. warp/native/scan.h +23 -0
  253. warp/native/solid_angle.h +466 -0
  254. warp/native/sort.cpp +251 -0
  255. warp/native/sort.cu +286 -0
  256. warp/native/sort.h +35 -0
  257. warp/native/sparse.cpp +241 -0
  258. warp/native/sparse.cu +435 -0
  259. warp/native/spatial.h +1306 -0
  260. warp/native/svd.h +727 -0
  261. warp/native/temp_buffer.h +46 -0
  262. warp/native/tile.h +4124 -0
  263. warp/native/tile_radix_sort.h +1112 -0
  264. warp/native/tile_reduce.h +838 -0
  265. warp/native/tile_scan.h +240 -0
  266. warp/native/tuple.h +189 -0
  267. warp/native/vec.h +2199 -0
  268. warp/native/version.h +23 -0
  269. warp/native/volume.cpp +501 -0
  270. warp/native/volume.cu +68 -0
  271. warp/native/volume.h +970 -0
  272. warp/native/volume_builder.cu +483 -0
  273. warp/native/volume_builder.h +52 -0
  274. warp/native/volume_impl.h +70 -0
  275. warp/native/warp.cpp +1143 -0
  276. warp/native/warp.cu +4604 -0
  277. warp/native/warp.h +358 -0
  278. warp/optim/__init__.py +20 -0
  279. warp/optim/adam.py +24 -0
  280. warp/optim/linear.py +35 -0
  281. warp/optim/sgd.py +24 -0
  282. warp/paddle.py +24 -0
  283. warp/py.typed +0 -0
  284. warp/render/__init__.py +22 -0
  285. warp/render/imgui_manager.py +29 -0
  286. warp/render/render_opengl.py +24 -0
  287. warp/render/render_usd.py +24 -0
  288. warp/render/utils.py +24 -0
  289. warp/sparse.py +51 -0
  290. warp/tape.py +24 -0
  291. warp/tests/__init__.py +1 -0
  292. warp/tests/__main__.py +4 -0
  293. warp/tests/assets/curlnoise_golden.npy +0 -0
  294. warp/tests/assets/mlp_golden.npy +0 -0
  295. warp/tests/assets/pixel.npy +0 -0
  296. warp/tests/assets/pnoise_golden.npy +0 -0
  297. warp/tests/assets/spiky.usd +0 -0
  298. warp/tests/assets/test_grid.nvdb +0 -0
  299. warp/tests/assets/test_index_grid.nvdb +0 -0
  300. warp/tests/assets/test_int32_grid.nvdb +0 -0
  301. warp/tests/assets/test_vec_grid.nvdb +0 -0
  302. warp/tests/assets/torus.nvdb +0 -0
  303. warp/tests/assets/torus.usda +105 -0
  304. warp/tests/aux_test_class_kernel.py +34 -0
  305. warp/tests/aux_test_compile_consts_dummy.py +18 -0
  306. warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
  307. warp/tests/aux_test_dependent.py +29 -0
  308. warp/tests/aux_test_grad_customs.py +29 -0
  309. warp/tests/aux_test_instancing_gc.py +26 -0
  310. warp/tests/aux_test_module_aot.py +7 -0
  311. warp/tests/aux_test_module_unload.py +23 -0
  312. warp/tests/aux_test_name_clash1.py +40 -0
  313. warp/tests/aux_test_name_clash2.py +40 -0
  314. warp/tests/aux_test_reference.py +9 -0
  315. warp/tests/aux_test_reference_reference.py +8 -0
  316. warp/tests/aux_test_square.py +16 -0
  317. warp/tests/aux_test_unresolved_func.py +22 -0
  318. warp/tests/aux_test_unresolved_symbol.py +22 -0
  319. warp/tests/cuda/__init__.py +0 -0
  320. warp/tests/cuda/test_async.py +676 -0
  321. warp/tests/cuda/test_conditional_captures.py +1147 -0
  322. warp/tests/cuda/test_ipc.py +124 -0
  323. warp/tests/cuda/test_mempool.py +233 -0
  324. warp/tests/cuda/test_multigpu.py +169 -0
  325. warp/tests/cuda/test_peer.py +139 -0
  326. warp/tests/cuda/test_pinned.py +84 -0
  327. warp/tests/cuda/test_streams.py +691 -0
  328. warp/tests/geometry/__init__.py +0 -0
  329. warp/tests/geometry/test_bvh.py +335 -0
  330. warp/tests/geometry/test_hash_grid.py +259 -0
  331. warp/tests/geometry/test_marching_cubes.py +294 -0
  332. warp/tests/geometry/test_mesh.py +318 -0
  333. warp/tests/geometry/test_mesh_query_aabb.py +392 -0
  334. warp/tests/geometry/test_mesh_query_point.py +935 -0
  335. warp/tests/geometry/test_mesh_query_ray.py +323 -0
  336. warp/tests/geometry/test_volume.py +1103 -0
  337. warp/tests/geometry/test_volume_write.py +346 -0
  338. warp/tests/interop/__init__.py +0 -0
  339. warp/tests/interop/test_dlpack.py +730 -0
  340. warp/tests/interop/test_jax.py +1673 -0
  341. warp/tests/interop/test_paddle.py +800 -0
  342. warp/tests/interop/test_torch.py +1001 -0
  343. warp/tests/run_coverage_serial.py +39 -0
  344. warp/tests/test_adam.py +162 -0
  345. warp/tests/test_arithmetic.py +1096 -0
  346. warp/tests/test_array.py +3756 -0
  347. warp/tests/test_array_reduce.py +156 -0
  348. warp/tests/test_assert.py +303 -0
  349. warp/tests/test_atomic.py +336 -0
  350. warp/tests/test_atomic_bitwise.py +209 -0
  351. warp/tests/test_atomic_cas.py +312 -0
  352. warp/tests/test_bool.py +220 -0
  353. warp/tests/test_builtins_resolution.py +732 -0
  354. warp/tests/test_closest_point_edge_edge.py +327 -0
  355. warp/tests/test_codegen.py +974 -0
  356. warp/tests/test_codegen_instancing.py +1495 -0
  357. warp/tests/test_compile_consts.py +215 -0
  358. warp/tests/test_conditional.py +298 -0
  359. warp/tests/test_context.py +35 -0
  360. warp/tests/test_copy.py +319 -0
  361. warp/tests/test_ctypes.py +618 -0
  362. warp/tests/test_dense.py +73 -0
  363. warp/tests/test_devices.py +127 -0
  364. warp/tests/test_enum.py +136 -0
  365. warp/tests/test_examples.py +424 -0
  366. warp/tests/test_fabricarray.py +998 -0
  367. warp/tests/test_fast_math.py +72 -0
  368. warp/tests/test_fem.py +2204 -0
  369. warp/tests/test_fixedarray.py +229 -0
  370. warp/tests/test_fp16.py +136 -0
  371. warp/tests/test_func.py +501 -0
  372. warp/tests/test_future_annotations.py +100 -0
  373. warp/tests/test_generics.py +656 -0
  374. warp/tests/test_grad.py +893 -0
  375. warp/tests/test_grad_customs.py +339 -0
  376. warp/tests/test_grad_debug.py +341 -0
  377. warp/tests/test_implicit_init.py +411 -0
  378. warp/tests/test_import.py +45 -0
  379. warp/tests/test_indexedarray.py +1140 -0
  380. warp/tests/test_intersect.py +103 -0
  381. warp/tests/test_iter.py +76 -0
  382. warp/tests/test_large.py +177 -0
  383. warp/tests/test_launch.py +411 -0
  384. warp/tests/test_lerp.py +151 -0
  385. warp/tests/test_linear_solvers.py +223 -0
  386. warp/tests/test_lvalue.py +427 -0
  387. warp/tests/test_map.py +526 -0
  388. warp/tests/test_mat.py +3515 -0
  389. warp/tests/test_mat_assign_copy.py +178 -0
  390. warp/tests/test_mat_constructors.py +573 -0
  391. warp/tests/test_mat_lite.py +122 -0
  392. warp/tests/test_mat_scalar_ops.py +2913 -0
  393. warp/tests/test_math.py +212 -0
  394. warp/tests/test_module_aot.py +287 -0
  395. warp/tests/test_module_hashing.py +258 -0
  396. warp/tests/test_modules_lite.py +70 -0
  397. warp/tests/test_noise.py +252 -0
  398. warp/tests/test_operators.py +299 -0
  399. warp/tests/test_options.py +129 -0
  400. warp/tests/test_overwrite.py +551 -0
  401. warp/tests/test_print.py +408 -0
  402. warp/tests/test_quat.py +2653 -0
  403. warp/tests/test_quat_assign_copy.py +145 -0
  404. warp/tests/test_rand.py +339 -0
  405. warp/tests/test_reload.py +303 -0
  406. warp/tests/test_rounding.py +157 -0
  407. warp/tests/test_runlength_encode.py +196 -0
  408. warp/tests/test_scalar_ops.py +133 -0
  409. warp/tests/test_smoothstep.py +108 -0
  410. warp/tests/test_snippet.py +318 -0
  411. warp/tests/test_sparse.py +845 -0
  412. warp/tests/test_spatial.py +2859 -0
  413. warp/tests/test_spatial_assign_copy.py +160 -0
  414. warp/tests/test_special_values.py +361 -0
  415. warp/tests/test_static.py +640 -0
  416. warp/tests/test_struct.py +901 -0
  417. warp/tests/test_tape.py +242 -0
  418. warp/tests/test_transient_module.py +93 -0
  419. warp/tests/test_triangle_closest_point.py +192 -0
  420. warp/tests/test_tuple.py +361 -0
  421. warp/tests/test_types.py +615 -0
  422. warp/tests/test_utils.py +594 -0
  423. warp/tests/test_vec.py +1408 -0
  424. warp/tests/test_vec_assign_copy.py +143 -0
  425. warp/tests/test_vec_constructors.py +325 -0
  426. warp/tests/test_vec_lite.py +80 -0
  427. warp/tests/test_vec_scalar_ops.py +2327 -0
  428. warp/tests/test_verify_fp.py +100 -0
  429. warp/tests/test_version.py +75 -0
  430. warp/tests/tile/__init__.py +0 -0
  431. warp/tests/tile/test_tile.py +1519 -0
  432. warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
  433. warp/tests/tile/test_tile_cholesky.py +608 -0
  434. warp/tests/tile/test_tile_load.py +724 -0
  435. warp/tests/tile/test_tile_mathdx.py +156 -0
  436. warp/tests/tile/test_tile_matmul.py +179 -0
  437. warp/tests/tile/test_tile_mlp.py +400 -0
  438. warp/tests/tile/test_tile_reduce.py +950 -0
  439. warp/tests/tile/test_tile_shared_memory.py +376 -0
  440. warp/tests/tile/test_tile_sort.py +121 -0
  441. warp/tests/tile/test_tile_view.py +173 -0
  442. warp/tests/unittest_serial.py +47 -0
  443. warp/tests/unittest_suites.py +430 -0
  444. warp/tests/unittest_utils.py +469 -0
  445. warp/tests/walkthrough_debug.py +95 -0
  446. warp/torch.py +24 -0
  447. warp/types.py +51 -0
  448. warp/utils.py +31 -0
  449. warp_lang-1.10.0.dist-info/METADATA +459 -0
  450. warp_lang-1.10.0.dist-info/RECORD +468 -0
  451. warp_lang-1.10.0.dist-info/WHEEL +5 -0
  452. warp_lang-1.10.0.dist-info/licenses/LICENSE.md +176 -0
  453. warp_lang-1.10.0.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  454. warp_lang-1.10.0.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  455. warp_lang-1.10.0.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  456. warp_lang-1.10.0.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  457. warp_lang-1.10.0.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  458. warp_lang-1.10.0.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  459. warp_lang-1.10.0.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  460. warp_lang-1.10.0.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  461. warp_lang-1.10.0.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  462. warp_lang-1.10.0.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  463. warp_lang-1.10.0.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  464. warp_lang-1.10.0.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  465. warp_lang-1.10.0.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  466. warp_lang-1.10.0.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  467. warp_lang-1.10.0.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
  468. warp_lang-1.10.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,782 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from typing import Optional
17
+
18
+ import warp as wp
19
+ from warp._src.fem import cache, utils
20
+ from warp._src.fem.types import OUTSIDE, Coords, ElementIndex, Sample, make_free_sample
21
+
22
+ from .nanogrid import NanogridBase
23
+
24
+ _wp_module_name_ = "warp.fem.geometry.adaptive_nanogrid"
25
+
26
+ _FACE_LEVEL_BIT = wp.constant(wp.uint8(4)) # follows nanogrid.FACE_OUTER_OFFSET_BIT
27
+ _GRID_LEVEL_BIT = wp.constant(wp.int32(19)) # follows nanogrid.GRID_AXIS_FLAG
28
+
29
+
30
+ @wp.struct
31
+ class AdaptiveNanogridCellArg:
32
+ # Utility device functions
33
+ cell_grid: wp.uint64
34
+ cell_ijk: wp.array(dtype=wp.vec3i)
35
+ cell_level: wp.array(dtype=wp.uint8)
36
+ inverse_transform: wp.mat33
37
+ cell_volume: float
38
+ level_count: int
39
+
40
+
41
+ @wp.struct
42
+ class AdaptiveNanogridSideArg:
43
+ # Utility device functions
44
+ cell_arg: AdaptiveNanogridCellArg
45
+ face_ijk: wp.array(dtype=wp.vec3i)
46
+ face_cell_indices: wp.array(dtype=wp.vec2i)
47
+ face_flags: wp.array(dtype=wp.uint8)
48
+ face_areas: wp.vec3
49
+
50
+
51
+ class AdaptiveNanogrid(NanogridBase):
52
+ """Adaptive sparse grid"""
53
+
54
+ dimension = 3
55
+
56
+ def __init__(
57
+ self,
58
+ cell_grid: wp.Volume,
59
+ cell_level: wp.array,
60
+ level_count: int,
61
+ temporary_store: cache.TemporaryStore,
62
+ ):
63
+ """
64
+ Constructs an adaptive sparse grid geometry from an in-memory NanoVDB volume and a list of levels.
65
+
66
+ It is not recommended to use this constructor directly; see the helper functions :func:`warp.fem.adaptive_nanogrid_from_field` and :func:`warp.fem.adaptive_nanogrid_from_hierarchy`
67
+
68
+ Args:
69
+ cell_grid: A warp volume (ideally backed by an index grid) whose voxels coordinates correspond to the lowest fine-resolution voxel of each cell.
70
+ The cell's extent is then given by the `cell_level` array. For instance, a voxel at coordinates ``ijk`` and level ``0`` corresponds to a fine cell at the same coordinates,
71
+ a voxel at coordinates ``2*ijk`` and level ``1`` corresponds to a cell spanning ``2^3`` voxels from ``2*ijk`` to ``2*ijk + (1,1,1)``, etc.
72
+ cell_level: Refinement level for each voxel of the volume. Level 0 is the finest, level ``level_count-1`` is the coarsest.
73
+ level_count: Number of levels in the grid
74
+ """
75
+
76
+ if level_count > 8:
77
+ raise ValueError("Too many refinement levels, max 8 supported")
78
+
79
+ self.level_count = level_count
80
+ self._cell_level = cell_level
81
+
82
+ device = cell_grid.device
83
+ cell_ijk = wp.array(dtype=wp.vec3i, shape=(cell_grid.get_voxel_count(),), device=device)
84
+ cell_grid.get_voxels(out=cell_ijk)
85
+
86
+ node_grid = _build_node_grid(cell_ijk, cell_level, cell_grid, temporary_store)
87
+ node_count = node_grid.get_voxel_count()
88
+ node_ijk = wp.array(shape=(node_count,), dtype=wp.vec3i, device=device)
89
+ node_grid.get_voxels(out=node_ijk)
90
+
91
+ super().__init__(cell_grid, cell_ijk, node_grid, node_ijk)
92
+
93
+ self._stacked_edge_grid = None
94
+ self._stacked_edge_count = 0
95
+ self._stacked_face_grid = None
96
+ self._stacked_face_count = 0
97
+
98
+ @property
99
+ def stacked_face_grid(self) -> wp.Volume:
100
+ self._ensure_stacked_face_grid()
101
+ return self._stacked_face_grid
102
+
103
+ def stacked_face_count(self):
104
+ self._ensure_stacked_face_grid()
105
+ return self._stacked_face_count
106
+
107
+ @property
108
+ def stacked_edge_grid(self) -> wp.Volume:
109
+ self._ensure_stacked_edge_grid()
110
+ return self._stacked_edge_grid
111
+
112
+ def stacked_edge_count(self):
113
+ self._ensure_stacked_edge_grid()
114
+ return self._stacked_edge_count
115
+
116
+ CellArg = AdaptiveNanogridCellArg
117
+
118
+ def fill_cell_arg(self, arg: CellArg, device):
119
+ arg.cell_grid = self._cell_grid.id
120
+ arg.cell_ijk = self._cell_ijk
121
+ arg.cell_level = self._cell_level
122
+ arg.inverse_transform = self._inverse_transform
123
+ arg.cell_volume = self._cell_volume
124
+ arg.level_count = self.level_count
125
+
126
+ @wp.func
127
+ def _cell_scale(args: CellArg, cell_index: int):
128
+ return float(1 << int(args.cell_level[cell_index]))
129
+
130
+ @wp.func
131
+ def cell_position(args: CellArg, s: Sample):
132
+ cell_idx = s.element_index
133
+ scale = AdaptiveNanogrid._cell_scale(args, cell_idx)
134
+ cell_coords = s.element_coords
135
+ cell_ijk = args.cell_ijk[cell_idx]
136
+ uvw = wp.vec3(cell_ijk) + cell_coords * scale
137
+ grid_id = args.cell_grid
138
+ return wp.volume_index_to_world(grid_id, uvw - wp.vec3(0.5))
139
+
140
+ @wp.func
141
+ def cell_deformation_gradient(args: CellArg, s: Sample):
142
+ scale = AdaptiveNanogrid._cell_scale(args, s.element_index)
143
+ return wp.inverse(args.inverse_transform) * scale
144
+
145
+ @wp.func
146
+ def cell_inverse_deformation_gradient(args: CellArg, s: Sample):
147
+ scale = AdaptiveNanogrid._cell_scale(args, s.element_index)
148
+ return args.inverse_transform / scale
149
+
150
+ def supports_cell_lookup(self, device):
151
+ return True
152
+
153
+ @wp.func
154
+ def _lookup_cell_index(args: AdaptiveNanogridCellArg, i: int, j: int, k: int):
155
+ return AdaptiveNanogrid.find_cell(args.cell_grid, wp.vec3i(i, j, k), args.level_count, args.cell_level)
156
+
157
+ @wp.func
158
+ def _cell_coordinates_local(args: AdaptiveNanogridCellArg, cell_index: int, uvw: wp.vec3):
159
+ ijk = wp.vec3(args.cell_ijk[cell_index])
160
+ rel_pos = uvw - ijk
161
+ scale = AdaptiveNanogrid._cell_scale(args, cell_index)
162
+ return rel_pos / scale
163
+
164
+ @wp.func
165
+ def _cell_closest_point_local(args: AdaptiveNanogridCellArg, cell_index: int, uvw: wp.vec3):
166
+ ijk = wp.vec3(args.cell_ijk[cell_index])
167
+ rel_pos = uvw - ijk
168
+ scale = AdaptiveNanogrid._cell_scale(args, cell_index)
169
+ coords = wp.min(wp.max(rel_pos / scale, wp.vec3(0.0)), wp.vec3(1.0))
170
+ return wp.length_sq(wp.volume_index_to_world_dir(args.cell_grid, coords * scale - rel_pos)), coords
171
+
172
+ @wp.func
173
+ def cell_coordinates(args: AdaptiveNanogridCellArg, cell_index: int, pos: wp.vec3):
174
+ uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
175
+ return AdaptiveNanogrid._cell_coordinates_local(args, cell_index, uvw)
176
+
177
+ @wp.func
178
+ def cell_closest_point(args: AdaptiveNanogridCellArg, cell_index: int, pos: wp.vec3):
179
+ uvw = wp.volume_world_to_index(args.cell_grid, pos) + wp.vec3(0.5)
180
+ dist, coords = AdaptiveNanogrid._cell_closest_point_local(args, cell_index, uvw)
181
+ return coords, dist
182
+
183
+ @wp.func
184
+ def cell_measure(args: CellArg, s: Sample):
185
+ scale = AdaptiveNanogrid._cell_scale(args, s.element_index)
186
+ return args.cell_volume * scale * scale * scale
187
+
188
+ @wp.func
189
+ def cell_normal(args: CellArg, s: Sample):
190
+ return wp.vec3(0.0)
191
+
192
+ SideArg = AdaptiveNanogridSideArg
193
+
194
+ @wp.func
195
+ def side_to_cell_arg(side_arg: SideArg):
196
+ return side_arg.cell_arg
197
+
198
+ def fill_side_arg(self, arg: SideArg, device):
199
+ self._ensure_face_grid()
200
+
201
+ self.fill_cell_arg(arg.cell_arg, device)
202
+ arg.face_ijk = self._face_ijk.to(device)
203
+ arg.face_flags = self._face_flags.to(device)
204
+ arg.face_cell_indices = self._face_cell_indices.to(device)
205
+ arg.face_areas = self._face_areas
206
+
207
+ @wp.func
208
+ def _get_face_level(flags: wp.uint8):
209
+ return wp.int32(flags >> _FACE_LEVEL_BIT)
210
+
211
+ @wp.func
212
+ def _get_face_scale(flags: wp.uint8):
213
+ return float(1 << AdaptiveNanogrid._get_face_level(flags))
214
+
215
+ @wp.func
216
+ def side_position(args: SideArg, s: Sample):
217
+ ijk = args.face_ijk[s.element_index]
218
+ flags = args.face_flags[s.element_index]
219
+ axis = NanogridBase._get_face_axis(flags)
220
+ flip = NanogridBase._get_face_inner_offset(flags)
221
+ scale = AdaptiveNanogrid._get_face_scale(flags)
222
+
223
+ uvw = wp.vec3(ijk) + scale * NanogridBase._side_to_cell_coords(axis, flip, 0.0, s.element_coords)
224
+
225
+ cell_grid = args.cell_arg.cell_grid
226
+ return wp.volume_index_to_world(cell_grid, uvw - wp.vec3(0.5))
227
+
228
+ @wp.func
229
+ def side_deformation_gradient(args: SideArg, s: Sample):
230
+ flags = args.face_flags[s.element_index]
231
+ axis = NanogridBase._get_face_axis(flags)
232
+ flip = NanogridBase._get_face_inner_offset(flags)
233
+ scale = AdaptiveNanogrid._get_face_scale(flags)
234
+ v1, v2 = NanogridBase._face_tangent_vecs(args.cell_arg.cell_grid, axis, flip)
235
+ return wp.matrix_from_cols(v1, v2) * scale
236
+
237
+ @wp.func
238
+ def side_inner_inverse_deformation_gradient(args: SideArg, s: Sample):
239
+ s_cell = make_free_sample(AdaptiveNanogrid.side_inner_cell_index(args, s.element_index), Coords())
240
+ return AdaptiveNanogrid.cell_inverse_deformation_gradient(args.cell_arg, s_cell)
241
+
242
+ @wp.func
243
+ def side_outer_inverse_deformation_gradient(args: SideArg, s: Sample):
244
+ s_cell = make_free_sample(AdaptiveNanogrid.side_outer_cell_index(args, s.element_index), Coords())
245
+ return AdaptiveNanogrid.cell_inverse_deformation_gradient(args.cell_arg, s_cell)
246
+
247
+ @wp.func
248
+ def side_measure(args: SideArg, s: Sample):
249
+ flags = args.face_flags[s.element_index]
250
+ axis = NanogridBase._get_face_axis(flags)
251
+ scale = AdaptiveNanogrid._get_face_scale(flags)
252
+ return args.face_areas[axis] * scale * scale
253
+
254
+ @wp.func
255
+ def side_measure_ratio(args: SideArg, s: Sample):
256
+ flags = args.face_flags[s.element_index]
257
+ axis = NanogridBase._get_face_axis(flags)
258
+ scale = AdaptiveNanogrid._get_face_scale(flags)
259
+ return args.face_areas[axis] / (args.cell_arg.cell_volume * scale)
260
+
261
+ @wp.func
262
+ def side_normal(args: SideArg, s: Sample):
263
+ flags = args.face_flags[s.element_index]
264
+ axis = NanogridBase._get_face_axis(flags)
265
+ flip = NanogridBase._get_face_inner_offset(flags)
266
+
267
+ v1, v2 = NanogridBase._face_tangent_vecs(args.cell_arg.cell_grid, axis, flip)
268
+ return wp.cross(v1, v2) / args.face_areas[axis]
269
+
270
+ @wp.func
271
+ def side_inner_cell_index(args: SideArg, side_index: ElementIndex):
272
+ return args.face_cell_indices[side_index][0]
273
+
274
+ @wp.func
275
+ def side_outer_cell_index(args: SideArg, side_index: ElementIndex):
276
+ return args.face_cell_indices[side_index][1]
277
+
278
+ @wp.func
279
+ def _coarse_cell_coords(
280
+ fine_ijk: wp.vec3i,
281
+ fine_level: int,
282
+ fine_coords: Coords,
283
+ coarse_ijk: wp.vec3i,
284
+ coarse_level: int,
285
+ ):
286
+ return (wp.vec3f(fine_ijk - coarse_ijk) + fine_coords * float(1 << fine_level)) / float(1 << coarse_level)
287
+
288
+ @wp.func
289
+ def side_inner_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
290
+ flags = args.face_flags[side_index]
291
+ axis = NanogridBase._get_face_axis(flags)
292
+ flip = NanogridBase._get_face_inner_offset(flags)
293
+ offset = NanogridBase._get_face_inner_offset(flags)
294
+
295
+ same_level_cell_coords = NanogridBase._side_to_cell_coords(axis, flip, 1.0 - float(offset), side_coords)
296
+ same_level_cell_ijk = args.face_ijk[side_index]
297
+ side_level = AdaptiveNanogrid._get_face_level(flags)
298
+ same_level_cell_ijk[axis] += (offset - 1) << side_level
299
+
300
+ cell_index = AdaptiveNanogrid.side_inner_cell_index(args, side_index)
301
+ cell_level = int(args.cell_arg.cell_level[cell_index])
302
+ cell_ijk = args.cell_arg.cell_ijk[cell_index]
303
+
304
+ return AdaptiveNanogrid._coarse_cell_coords(
305
+ same_level_cell_ijk, side_level, same_level_cell_coords, cell_ijk, cell_level
306
+ )
307
+
308
+ @wp.func
309
+ def side_outer_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
310
+ flags = args.face_flags[side_index]
311
+ axis = NanogridBase._get_face_axis(flags)
312
+ flip = NanogridBase._get_face_inner_offset(flags)
313
+ offset = NanogridBase._get_face_outer_offset(flags)
314
+
315
+ same_level_cell_coords = NanogridBase._side_to_cell_coords(axis, flip, float(offset), side_coords)
316
+ same_level_cell_ijk = args.face_ijk[side_index]
317
+ side_level = AdaptiveNanogrid._get_face_level(flags)
318
+ same_level_cell_ijk[axis] -= offset << side_level
319
+
320
+ cell_index = AdaptiveNanogrid.side_outer_cell_index(args, side_index)
321
+ cell_level = int(args.cell_arg.cell_level[cell_index])
322
+ cell_ijk = args.cell_arg.cell_ijk[cell_index]
323
+
324
+ return AdaptiveNanogrid._coarse_cell_coords(
325
+ same_level_cell_ijk, side_level, same_level_cell_coords, cell_ijk, cell_level
326
+ )
327
+
328
+ @wp.func
329
+ def side_from_cell_coords(
330
+ args: SideArg,
331
+ side_index: ElementIndex,
332
+ element_index: ElementIndex,
333
+ element_coords: Coords,
334
+ ):
335
+ flags = args.face_flags[side_index]
336
+ axis = NanogridBase._get_face_axis(flags)
337
+ flip = NanogridBase._get_face_inner_offset(flags)
338
+ side_level = AdaptiveNanogrid._get_face_level(flags)
339
+ cell_level = int(args.cell_arg.cell_level[element_index])
340
+
341
+ cell_ijk = args.cell_arg.cell_ijk[element_index]
342
+ side_ijk = args.face_ijk[side_index]
343
+
344
+ same_level_cell_coords = AdaptiveNanogrid._coarse_cell_coords(
345
+ cell_ijk, cell_level, element_coords, side_ijk, side_level
346
+ )
347
+
348
+ on_side = (
349
+ same_level_cell_coords[axis] == 0.0
350
+ and wp.min(same_level_cell_coords) >= 0.0
351
+ and wp.max(same_level_cell_coords) <= 1.0
352
+ )
353
+
354
+ return wp.where(on_side, NanogridBase._cell_to_side_coords(axis, flip, same_level_cell_coords), Coords(OUTSIDE))
355
+
356
+ @wp.func
357
+ def side_coordinates(args: SideArg, side_index: int, pos: wp.vec3):
358
+ cell_arg = args.cell_arg
359
+
360
+ ijk = args.face_ijk[side_index]
361
+ fine_cell_coords = wp.volume_world_to_index(cell_arg.cell_grid, pos) + wp.vec3(0.5) - wp.vec3(ijk)
362
+
363
+ flags = args.face_flags[side_index]
364
+ side_level = AdaptiveNanogrid._get_face_level(flags)
365
+ axis = NanogridBase._get_face_axis(flags)
366
+ flip = NanogridBase._get_face_inner_offset(flags)
367
+
368
+ return NanogridBase._cell_to_side_coords(axis, flip, fine_cell_coords / float(1 << side_level))
369
+
370
+ @wp.func
371
+ def side_closest_point(args: SideArg, side_index: int, pos: wp.vec3):
372
+ coords = AdaptiveNanogrid.side_coordinates(args, side_index, pos)
373
+
374
+ proj_coords = Coords(wp.clamp(coords[0], 0.0, 1.0), wp.clamp(coords[1], 0.0, 1.0), 0.0)
375
+
376
+ flags = args.face_flags[side_index]
377
+ axis = NanogridBase._get_face_axis(flags)
378
+ flip = NanogridBase._get_face_inner_offset(flags)
379
+ side_level = AdaptiveNanogrid._get_face_level(flags)
380
+ cell_coord_offset = NanogridBase._side_to_cell_coords(axis, flip, 0, coords - proj_coords) * float(
381
+ 1 << side_level
382
+ )
383
+
384
+ return proj_coords, wp.length_sq(wp.volume_index_to_world_dir(args.cell_grid, cell_coord_offset))
385
+
386
+ def _build_face_grid(self, temporary_store: Optional[cache.TemporaryStore] = None):
387
+ device = self._cell_grid.device
388
+
389
+ # Create a first grid with faces from cells
390
+ cell_face_grid = _build_cell_face_grid(self._cell_ijk, self._cell_level, self._cell_grid, temporary_store)
391
+
392
+ # Complete faces at resolution boundaries
393
+ self._face_grid = _build_completed_face_grid(
394
+ cell_face_grid, self._cell_grid, self.level_count, self._cell_level, temporary_store
395
+ )
396
+
397
+ face_count = self._face_grid.get_voxel_count()
398
+ self._face_ijk = wp.array(shape=(face_count,), dtype=wp.vec3i, device=device)
399
+ self._face_grid.get_voxels(out=self._face_ijk)
400
+
401
+ # Finalize our faces, cache flags and neighbour indices
402
+ self._face_cell_indices = wp.array(shape=(face_count,), dtype=wp.vec2i, device=device)
403
+ self._face_flags = wp.array(shape=(face_count,), dtype=wp.uint8, device=device)
404
+ boundary_face_mask = cache.borrow_temporary(temporary_store, shape=(face_count,), dtype=wp.int32, device=device)
405
+
406
+ wp.launch(
407
+ _build_face_indices_and_flags,
408
+ dim=face_count,
409
+ device=device,
410
+ inputs=[
411
+ self._cell_grid.id,
412
+ self.level_count,
413
+ self._cell_level,
414
+ self._face_ijk,
415
+ self._face_cell_indices,
416
+ self._face_flags,
417
+ boundary_face_mask,
418
+ ],
419
+ )
420
+ boundary_face_indices, _ = utils.masked_indices(boundary_face_mask)
421
+ self._boundary_face_indices = boundary_face_indices.detach()
422
+
423
+ def _ensure_stacked_edge_grid(self):
424
+ if self._stacked_edge_grid is None:
425
+ self._stacked_edge_grid = _build_stacked_edge_grid(
426
+ self._cell_ijk, self._cell_level, self._cell_grid, temporary_store=None
427
+ )
428
+ self._stacked_edge_count = self._stacked_edge_grid.get_voxel_count()
429
+
430
+ def _ensure_stacked_face_grid(self):
431
+ if self._stacked_face_grid is None:
432
+ self._stacked_face_grid = _build_stacked_face_grid(
433
+ self._cell_ijk, self._cell_level, self._cell_grid, temporary_store=None
434
+ )
435
+ self._stacked_face_count = self._stacked_face_grid.get_voxel_count()
436
+
437
+ @wp.func
438
+ def coarse_ijk(ijk: wp.vec3i, level: int):
439
+ # technically implementation-defined, but
440
+ # right-shifting negative numbers 1-fills on all our platforms
441
+ return wp.vec3i(ijk[0] >> level, ijk[1] >> level, ijk[2] >> level)
442
+
443
+ @wp.func
444
+ def fine_ijk(ijk: wp.vec3i, level: int):
445
+ # Our coords cannot exceed 1<<21,so no worries about overwriting the sign bit
446
+ return wp.vec3i(ijk[0] << level, ijk[1] << level, ijk[2] << level)
447
+
448
+ @wp.func
449
+ def encode_axis_and_level(ijk: wp.vec3i, axis: int, level: int):
450
+ # Embed a 3-bit level in the voxel coordinates
451
+ # by switching the _GRID_LEVEL_BIT for each axis
452
+
453
+ for ax in range(3):
454
+ coord = ijk[ax]
455
+ level_flag = ((level >> ax) & 1) << _GRID_LEVEL_BIT
456
+ ijk[ax] = wp.where(coord < 0, coord & ~level_flag, coord | level_flag)
457
+
458
+ return NanogridBase._add_axis_flag(ijk, axis)
459
+
460
+ @wp.func
461
+ def find_cell(
462
+ cell_grid: wp.uint64,
463
+ ijk: wp.vec3i,
464
+ level_count: int,
465
+ cell_level: wp.array(dtype=wp.uint8),
466
+ ):
467
+ for l in range(level_count):
468
+ mask = ~((1 << l) - 1)
469
+ cell_index = wp.volume_lookup_index(cell_grid, ijk[0] & mask, ijk[1] & mask, ijk[2] & mask)
470
+ if cell_index != -1:
471
+ if int(cell_level[cell_index]) >= l:
472
+ return cell_index
473
+
474
+ return -1
475
+
476
+
477
+ @wp.kernel
478
+ def _cell_node_indices(
479
+ cell_ijk: wp.array(dtype=wp.vec3i),
480
+ cell_level: wp.array(dtype=wp.uint8),
481
+ node_ijk: wp.array2d(dtype=wp.vec3i),
482
+ ):
483
+ cell, n = wp.tid()
484
+ level = int(cell_level[cell])
485
+ offset = AdaptiveNanogrid.fine_ijk(wp.vec3i((n & 4) >> 2, (n & 2) >> 1, n & 1), level)
486
+ node_ijk[cell, n] = cell_ijk[cell] + offset
487
+
488
+
489
+ @wp.kernel
490
+ def _cell_face_indices(
491
+ cell_ijk: wp.array(dtype=wp.vec3i),
492
+ cell_level: wp.array(dtype=wp.uint8),
493
+ node_ijk: wp.array2d(dtype=wp.vec3i),
494
+ ):
495
+ cell = wp.tid()
496
+ ijk = cell_ijk[cell]
497
+ node_ijk[cell, 0] = NanogridBase._add_axis_flag(ijk, 0)
498
+ node_ijk[cell, 1] = NanogridBase._add_axis_flag(ijk, 1)
499
+ node_ijk[cell, 2] = NanogridBase._add_axis_flag(ijk, 2)
500
+
501
+ offset = 1 << int(cell_level[cell])
502
+
503
+ node_ijk[cell, 3] = NanogridBase._add_axis_flag(ijk + wp.vec3i(offset, 0, 0), 0)
504
+ node_ijk[cell, 4] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, offset, 0), 1)
505
+ node_ijk[cell, 5] = NanogridBase._add_axis_flag(ijk + wp.vec3i(0, 0, offset), 2)
506
+
507
+
508
+ @wp.kernel
509
+ def _cell_stacked_face_indices(
510
+ cell_ijk: wp.array(dtype=wp.vec3i),
511
+ cell_level: wp.array(dtype=wp.uint8),
512
+ node_ijk: wp.array2d(dtype=wp.vec3i),
513
+ ):
514
+ cell = wp.tid()
515
+
516
+ level = int(cell_level[cell])
517
+ ijk = AdaptiveNanogrid.coarse_ijk(cell_ijk[cell], level)
518
+
519
+ node_ijk[cell, 0] = AdaptiveNanogrid.encode_axis_and_level(ijk, 0, level)
520
+ node_ijk[cell, 1] = AdaptiveNanogrid.encode_axis_and_level(ijk, 1, level)
521
+ node_ijk[cell, 2] = AdaptiveNanogrid.encode_axis_and_level(ijk, 2, level)
522
+
523
+ node_ijk[cell, 3] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(1, 0, 0), 0, level)
524
+ node_ijk[cell, 4] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 1, 0), 1, level)
525
+ node_ijk[cell, 5] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 0, 1), 2, level)
526
+
527
+
528
+ @wp.kernel
529
+ def _cell_stacked_edge_indices(
530
+ cell_ijk: wp.array(dtype=wp.vec3i),
531
+ cell_level: wp.array(dtype=wp.uint8),
532
+ edge_ijk: wp.array2d(dtype=wp.vec3i),
533
+ ):
534
+ cell = wp.tid()
535
+ level = int(cell_level[cell])
536
+ ijk = AdaptiveNanogrid.coarse_ijk(cell_ijk[cell], level)
537
+
538
+ edge_ijk[cell, 0] = AdaptiveNanogrid.encode_axis_and_level(ijk, 0, level)
539
+ edge_ijk[cell, 1] = AdaptiveNanogrid.encode_axis_and_level(ijk, 1, level)
540
+ edge_ijk[cell, 2] = AdaptiveNanogrid.encode_axis_and_level(ijk, 2, level)
541
+
542
+ edge_ijk[cell, 3] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 1, 0), 0, level)
543
+ edge_ijk[cell, 4] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 0, 1), 1, level)
544
+ edge_ijk[cell, 5] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(1, 0, 0), 2, level)
545
+
546
+ edge_ijk[cell, 6] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 1, 1), 0, level)
547
+ edge_ijk[cell, 7] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(1, 0, 1), 1, level)
548
+ edge_ijk[cell, 8] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(1, 1, 0), 2, level)
549
+
550
+ edge_ijk[cell, 9] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 0, 1), 0, level)
551
+ edge_ijk[cell, 10] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(1, 0, 0), 1, level)
552
+ edge_ijk[cell, 11] = AdaptiveNanogrid.encode_axis_and_level(ijk + wp.vec3i(0, 1, 0), 2, level)
553
+
554
+
555
+ def _build_node_grid(cell_ijk, cell_level, cell_grid: wp.Volume, temporary_store: cache.TemporaryStore):
556
+ cell_count = cell_ijk.shape[0]
557
+
558
+ cell_nodes = cache.borrow_temporary(temporary_store, shape=(cell_count, 8), dtype=wp.vec3i, device=cell_ijk.device)
559
+ wp.launch(
560
+ _cell_node_indices,
561
+ dim=cell_nodes.shape,
562
+ inputs=[cell_ijk, cell_level, cell_nodes],
563
+ device=cell_ijk.device,
564
+ )
565
+ node_grid = wp.Volume.allocate_by_voxels(
566
+ cell_nodes.flatten(), voxel_size=cell_grid.get_voxel_size()[0], device=cell_ijk.device
567
+ )
568
+
569
+ return node_grid
570
+
571
+
572
+ def _build_cell_face_grid(cell_ijk, cell_level, grid: wp.Volume, temporary_store: cache.TemporaryStore):
573
+ cell_count = cell_ijk.shape[0]
574
+
575
+ cell_faces = cache.borrow_temporary(temporary_store, shape=(cell_count, 6), dtype=wp.vec3i, device=cell_ijk.device)
576
+ wp.launch(_cell_face_indices, dim=cell_count, inputs=[cell_ijk, cell_level, cell_faces], device=cell_ijk.device)
577
+ face_grid = wp.Volume.allocate_by_voxels(
578
+ cell_faces.flatten(), voxel_size=grid.get_voxel_size()[0], device=cell_ijk.device
579
+ )
580
+
581
+ return face_grid
582
+
583
+
584
+ def _build_completed_face_grid(
585
+ cell_face_grid: wp.Volume,
586
+ cell_grid: wp.Volume,
587
+ level_count: int,
588
+ cell_level: wp.array,
589
+ temporary_store: cache.TemporaryStore,
590
+ ):
591
+ device = cell_grid.device
592
+
593
+ cell_face_count = cell_face_grid.get_voxel_count()
594
+ cell_face_ijk = cache.borrow_temporary(temporary_store, shape=(cell_face_count,), dtype=wp.vec3i, device=device)
595
+
596
+ additional_face_count = cache.borrow_temporary(temporary_store, shape=1, dtype=int, device=device)
597
+
598
+ # Count the number of supplemental faces we need to add at resolution boundaries
599
+ cell_face_grid.get_voxels(out=cell_face_ijk)
600
+ additional_face_count.zero_()
601
+ wp.launch(
602
+ _count_multires_faces,
603
+ dim=cell_face_count,
604
+ device=device,
605
+ inputs=[
606
+ cell_grid.id,
607
+ level_count,
608
+ cell_level,
609
+ cell_face_ijk,
610
+ additional_face_count,
611
+ ],
612
+ )
613
+
614
+ # Cat these new faces with the original ones
615
+ cat_face_count = cell_face_count + int(additional_face_count.numpy()[0])
616
+ cat_face_ijk = cache.borrow_temporary(temporary_store, shape=(cat_face_count,), dtype=wp.vec3i, device=device)
617
+ wp.copy(src=cell_face_ijk, dest=cat_face_ijk, dest_offset=cat_face_count - cell_face_count)
618
+
619
+ wp.launch(
620
+ _fill_multires_faces,
621
+ dim=cell_face_count,
622
+ device=device,
623
+ inputs=[
624
+ cell_grid.id,
625
+ level_count,
626
+ cell_level,
627
+ cell_face_ijk,
628
+ additional_face_count,
629
+ cat_face_ijk,
630
+ ],
631
+ )
632
+
633
+ # Now recreate a new grid with all those faces
634
+ face_grid = wp.Volume.allocate_by_voxels(
635
+ cat_face_ijk.flatten(), voxel_size=cell_face_grid.get_voxel_size(), device=device
636
+ )
637
+
638
+ return face_grid
639
+
640
+
641
+ def _build_stacked_face_grid(cell_ijk, cell_level, grid: wp.Volume, temporary_store: cache.TemporaryStore):
642
+ cell_count = cell_ijk.shape[0]
643
+
644
+ cell_faces = cache.borrow_temporary(temporary_store, shape=(cell_count, 6), dtype=wp.vec3i, device=cell_ijk.device)
645
+ wp.launch(
646
+ _cell_stacked_face_indices,
647
+ dim=cell_count,
648
+ inputs=[cell_ijk, cell_level, cell_faces],
649
+ device=cell_ijk.device,
650
+ )
651
+ face_grid = wp.Volume.allocate_by_voxels(
652
+ cell_faces.flatten(), voxel_size=grid.get_voxel_size()[0], device=cell_ijk.device
653
+ )
654
+
655
+ return face_grid
656
+
657
+
658
+ def _build_stacked_edge_grid(cell_ijk, cell_level, grid: wp.Volume, temporary_store: cache.TemporaryStore):
659
+ cell_count = cell_ijk.shape[0]
660
+
661
+ cell_edges = cache.borrow_temporary(temporary_store, shape=(cell_count, 12), dtype=wp.vec3i, device=cell_ijk.device)
662
+ wp.launch(
663
+ _cell_stacked_edge_indices,
664
+ dim=cell_count,
665
+ inputs=[cell_ijk, cell_level, cell_edges],
666
+ device=cell_ijk.device,
667
+ )
668
+ edge_grid = wp.Volume.allocate_by_voxels(
669
+ cell_edges.flatten(), voxel_size=grid.get_voxel_size()[0], device=cell_ijk.device
670
+ )
671
+
672
+ return edge_grid
673
+
674
+
675
+ @wp.func
676
+ def _find_face_neighbours(
677
+ cell_grid: wp.uint64,
678
+ ijk: wp.vec3i,
679
+ axis: int,
680
+ level_count: int,
681
+ cell_level: wp.array(dtype=wp.uint8),
682
+ ):
683
+ ijk_minus = ijk
684
+ ijk_minus[axis] -= 1
685
+
686
+ plus_cell_index = AdaptiveNanogrid.find_cell(cell_grid, ijk, level_count, cell_level)
687
+ minus_cell_index = AdaptiveNanogrid.find_cell(cell_grid, ijk_minus, level_count, cell_level)
688
+ return plus_cell_index, minus_cell_index
689
+
690
+
691
+ @wp.kernel
692
+ def _count_multires_faces(
693
+ cell_grid: wp.uint64,
694
+ level_count: int,
695
+ cell_level: wp.array(dtype=wp.uint8),
696
+ face_ijk: wp.array(dtype=wp.vec3i),
697
+ count: wp.array(dtype=int),
698
+ ):
699
+ face = wp.tid()
700
+
701
+ axis, ijk = NanogridBase._extract_axis_flag(face_ijk[face])
702
+
703
+ plus_cell_index, minus_cell_index = _find_face_neighbours(cell_grid, ijk, axis, level_count, cell_level)
704
+
705
+ if plus_cell_index == -1 or minus_cell_index == -1:
706
+ return
707
+
708
+ plus_level = int(cell_level[plus_cell_index])
709
+ minus_level = int(cell_level[minus_cell_index])
710
+ level_diff = wp.abs(plus_level - minus_level)
711
+
712
+ if level_diff != 0:
713
+ fine_face_count = 1 << (2 * level_diff)
714
+ wp.atomic_add(count, 0, fine_face_count)
715
+
716
+
717
+ @wp.kernel
718
+ def _fill_multires_faces(
719
+ cell_grid: wp.uint64,
720
+ level_count: int,
721
+ cell_level: wp.array(dtype=wp.uint8),
722
+ face_ijk: wp.array(dtype=wp.vec3i),
723
+ count: wp.array(dtype=int),
724
+ added_ijk: wp.array(dtype=wp.vec3i),
725
+ ):
726
+ face = wp.tid()
727
+
728
+ axis, ijk = NanogridBase._extract_axis_flag(face_ijk[face])
729
+ plus_cell_index, minus_cell_index = _find_face_neighbours(cell_grid, ijk, axis, level_count, cell_level)
730
+
731
+ if plus_cell_index == -1 or minus_cell_index == -1:
732
+ return
733
+
734
+ plus_level = int(cell_level[plus_cell_index])
735
+ minus_level = int(cell_level[minus_cell_index])
736
+ level_diff = wp.abs(plus_level - minus_level)
737
+
738
+ if level_diff != 0:
739
+ fine_face_count = 1 << (2 * level_diff)
740
+ side_mask = (1 << level_diff) - 1
741
+
742
+ fine_level = min(plus_level, minus_level)
743
+ base_level = max(plus_level, minus_level)
744
+
745
+ base_mask = ~((1 << base_level) - 1)
746
+ base_ijk = wp.vec3i(ijk[0] & base_mask, ijk[1] & base_mask, ijk[2] & base_mask)
747
+
748
+ offset = wp.atomic_sub(count, 0, fine_face_count) - fine_face_count
749
+ for f in range(fine_face_count):
750
+ f_ijk = base_ijk
751
+ f_ijk[(axis + 1) % 3] |= (f & side_mask) << fine_level
752
+ f_ijk[(axis + 2) % 3] |= (f >> level_diff) << fine_level
753
+ added_ijk[offset + f] = NanogridBase._add_axis_flag(f_ijk, axis)
754
+
755
+
756
+ @wp.kernel
757
+ def _build_face_indices_and_flags(
758
+ cell_grid: wp.uint64,
759
+ level_count: int,
760
+ cell_level: wp.array(dtype=wp.uint8),
761
+ face_ijk: wp.array(dtype=wp.vec3i),
762
+ face_cell_indices: wp.array(dtype=wp.vec2i),
763
+ face_flags: wp.array(dtype=wp.uint8),
764
+ boundary_face_mask: wp.array(dtype=int),
765
+ ):
766
+ face = wp.tid()
767
+
768
+ axis, ijk = NanogridBase._extract_axis_flag(face_ijk[face])
769
+
770
+ plus_cell_index, minus_cell_index = _find_face_neighbours(cell_grid, ijk, axis, level_count, cell_level)
771
+
772
+ inner_cell = wp.where(minus_cell_index == -1, plus_cell_index, minus_cell_index)
773
+ outer_cell = wp.where(plus_cell_index == -1, minus_cell_index, plus_cell_index)
774
+
775
+ face_level = wp.min(cell_level[inner_cell], cell_level[outer_cell])
776
+
777
+ face_ijk[face] = ijk
778
+ flags = NanogridBase._make_face_flags(axis, plus_cell_index, minus_cell_index) | (face_level << _FACE_LEVEL_BIT)
779
+ face_flags[face] = flags
780
+ boundary_face_mask[face] = NanogridBase._get_boundary_mask(flags)
781
+
782
+ face_cell_indices[face] = wp.vec2i(inner_cell, outer_cell)