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,93 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 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
+ ###########################################################################
17
+ # Example Spin Lock
18
+ #
19
+ # Shows how to use a spin lock to synchronize access to a shared resource.
20
+ #
21
+ ###########################################################################
22
+
23
+ import warp as wp
24
+ from warp.tests.unittest_utils import *
25
+
26
+
27
+ @wp.func
28
+ def spinlock_acquire(lock: wp.array(dtype=wp.int32)):
29
+ # Try to acquire the lock by setting it to 1 if it's 0
30
+ while wp.atomic_cas(lock, 0, 0, 1) == 1:
31
+ pass
32
+
33
+
34
+ @wp.func
35
+ def spinlock_release(lock: wp.array(dtype=wp.int32)):
36
+ # Release the lock by setting it back to 0
37
+ wp.atomic_exch(lock, 0, 0)
38
+
39
+
40
+ @wp.func
41
+ def volatile_read(ptr: wp.array(dtype=wp.int32), index: int):
42
+ value = wp.atomic_exch(ptr, index, 0)
43
+ wp.atomic_exch(ptr, index, value)
44
+ return value
45
+
46
+
47
+ @wp.kernel
48
+ def test_spinlock_counter(
49
+ counter: wp.array(dtype=wp.int32), atomic_counter: wp.array(dtype=wp.int32), lock: wp.array(dtype=wp.int32)
50
+ ):
51
+ # Try to acquire the lock
52
+ spinlock_acquire(lock)
53
+
54
+ # Critical section - increment counter
55
+ # counter[0] = counter[0] + 1 # This gives wrong results - counter should be marked as volatile
56
+
57
+ # Work around since warp arrays cannot be marked as volatile
58
+ value = volatile_read(counter, 0)
59
+ counter[0] = value + 1
60
+
61
+ # Release the lock
62
+ spinlock_release(lock)
63
+
64
+ # Increment atomic counter for comparison
65
+ wp.atomic_add(atomic_counter, 0, 1)
66
+
67
+
68
+ def test_spinlock(device):
69
+ # Create a lock array initialized to 0 (unlocked)
70
+ lock = wp.array([0], dtype=wp.int32, device=device)
71
+
72
+ # Create counter arrays initialized to 0
73
+ counter = wp.array([0], dtype=wp.int32, device=device)
74
+ atomic_counter = wp.array([0], dtype=wp.int32, device=device)
75
+
76
+ # Number of threads to test with
77
+ n = 1024
78
+
79
+ # Launch the test kernel
80
+ wp.launch(test_spinlock_counter, dim=n, inputs=[counter, atomic_counter, lock], device=device)
81
+
82
+ # Verify results
83
+ assert atomic_counter.numpy()[0] == n, f"Atomic counter should be {n}, got {atomic_counter.numpy()[0]}"
84
+ assert counter.numpy()[0] == n, f"Counter should be {n}, got {counter.numpy()[0]}"
85
+ assert lock.numpy()[0] == 0, "Lock was not properly released"
86
+
87
+ print(f"Final counter value: {counter.numpy()[0]}")
88
+ print(f"Final atomic counter value: {atomic_counter.numpy()[0]}")
89
+
90
+
91
+ if __name__ == "__main__":
92
+ wp.clear_kernel_cache()
93
+ test_spinlock(device="cuda")
@@ -0,0 +1,211 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 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
+ ###########################################################################
17
+ # Example Torch
18
+ #
19
+ # Optimizes the Rosenbrock function using the PyTorch Adam optimizer
20
+ # The Rosenbrock function is a non-convex function, and is often used
21
+ # to test optimization algorithms. The function is defined as:
22
+ # f(x, y) = (a - x)^2 + b * (y - x^2)^2
23
+ # where a = 1 and b = 100. The minimum value of the function is 0 at (1, 1).
24
+ #
25
+ # The example demonstrates how to set up a torch.autograd.Function to
26
+ # incorporate Warp kernel launches within a PyTorch graph.
27
+ ###########################################################################
28
+
29
+ import numpy as np
30
+ import torch
31
+
32
+ import warp as wp
33
+
34
+
35
+ # Define the Rosenbrock function
36
+ @wp.func
37
+ def rosenbrock(x: float, y: float):
38
+ return (1.0 - x) ** 2.0 + 100.0 * (y - x**2.0) ** 2.0
39
+
40
+
41
+ @wp.kernel
42
+ def eval_rosenbrock(xs: wp.array(dtype=wp.vec2), z: wp.array(dtype=float)):
43
+ i = wp.tid()
44
+ x = xs[i]
45
+ z[i] = rosenbrock(x[0], x[1])
46
+
47
+
48
+ class Rosenbrock(torch.autograd.Function):
49
+ @staticmethod
50
+ def forward(ctx, xy, num_particles):
51
+ ctx.xy = wp.from_torch(xy, dtype=wp.vec2, requires_grad=True)
52
+ ctx.num_particles = num_particles
53
+
54
+ # allocate output
55
+ ctx.z = wp.zeros(num_particles, requires_grad=True)
56
+
57
+ wp.launch(kernel=eval_rosenbrock, dim=ctx.num_particles, inputs=[ctx.xy], outputs=[ctx.z])
58
+
59
+ return wp.to_torch(ctx.z)
60
+
61
+ @staticmethod
62
+ def backward(ctx, adj_z):
63
+ # map incoming Torch grads to our output variables
64
+ ctx.z.grad = wp.from_torch(adj_z)
65
+
66
+ wp.launch(
67
+ kernel=eval_rosenbrock,
68
+ dim=ctx.num_particles,
69
+ inputs=[ctx.xy],
70
+ outputs=[ctx.z],
71
+ adj_inputs=[ctx.xy.grad],
72
+ adj_outputs=[ctx.z.grad],
73
+ adjoint=True,
74
+ )
75
+
76
+ # return adjoint w.r.t. inputs
77
+ return (wp.to_torch(ctx.xy.grad), None)
78
+
79
+
80
+ class Example:
81
+ def __init__(self, headless=False, train_iters=10, num_particles=1500):
82
+ self.num_particles = num_particles
83
+ self.train_iters = train_iters
84
+ self.train_iter = 0
85
+
86
+ self.learning_rate = 5e-2
87
+
88
+ self.torch_device = wp.device_to_torch(wp.get_device())
89
+
90
+ rng = np.random.default_rng(42)
91
+ self.xy = torch.tensor(
92
+ rng.normal(size=(self.num_particles, 2)), dtype=torch.float32, requires_grad=True, device=self.torch_device
93
+ )
94
+ self.xp_np = self.xy.numpy(force=True)
95
+ self.opt = torch.optim.Adam([self.xy], lr=self.learning_rate)
96
+
97
+ if headless:
98
+ self.scatter_plot = None
99
+ self.mean_marker = None
100
+ else:
101
+ self.scatter_plot = self.create_plot()
102
+
103
+ self.mean_pos = np.empty((2,))
104
+
105
+ def create_plot(self):
106
+ import matplotlib.pyplot as plt
107
+
108
+ min_x, max_x = -2.0, 2.0
109
+ min_y, max_y = -2.0, 2.0
110
+
111
+ # Create a grid of points
112
+ x = np.linspace(min_x, max_x, 100)
113
+ y = np.linspace(min_y, max_y, 100)
114
+ X, Y = np.meshgrid(x, y)
115
+ xy = np.column_stack((X.flatten(), Y.flatten()))
116
+ N = len(xy)
117
+
118
+ xy = wp.array(xy, dtype=wp.vec2)
119
+ Z = wp.empty(N, dtype=wp.float32)
120
+
121
+ wp.launch(eval_rosenbrock, dim=N, inputs=[xy], outputs=[Z])
122
+ Z = Z.numpy().reshape(X.shape)
123
+
124
+ # Plot the function as a heatmap
125
+ self.fig = plt.figure(figsize=(6, 6))
126
+ ax = plt.gca()
127
+ plt.imshow(Z, extent=[min_x, max_x, min_y, max_y], origin="lower", interpolation="bicubic", cmap="coolwarm")
128
+ plt.contour(X, Y, Z, extent=[min_x, max_x, min_y, max_y], levels=150, colors="k", alpha=0.5, linewidths=0.5)
129
+
130
+ # Plot optimum
131
+ plt.plot(1, 1, "*", color="r", markersize=10)
132
+
133
+ plt.title("Rosenbrock function")
134
+ plt.xlabel("x")
135
+ plt.ylabel("y")
136
+
137
+ (self.mean_marker,) = ax.plot([], [], "o", color="w", markersize=5)
138
+
139
+ # Create a scatter plot (initially empty)
140
+ return ax.scatter([], [], c="k", s=2)
141
+
142
+ def forward(self):
143
+ self.z = Rosenbrock.apply(self.xy, self.num_particles)
144
+
145
+ def step(self):
146
+ self.opt.zero_grad()
147
+ self.forward()
148
+ self.z.backward(torch.ones_like(self.z))
149
+
150
+ self.opt.step()
151
+
152
+ # Update the scatter plot
153
+ self.xy_np = self.xy.numpy(force=True)
154
+
155
+ # Compute mean
156
+ self.mean_pos = np.mean(self.xy_np, axis=0)
157
+ print(f"\rIter {self.train_iter:5d} particle mean: {self.mean_pos[0]:.8f}, {self.mean_pos[1]:.8f} ", end="")
158
+
159
+ self.train_iter += 1
160
+
161
+ def render(self):
162
+ if self.scatter_plot is None:
163
+ return
164
+
165
+ self.scatter_plot.set_offsets(np.c_[self.xy_np[:, 0], self.xy_np[:, 1]])
166
+ self.mean_marker.set_data([self.mean_pos[0]], [self.mean_pos[1]])
167
+
168
+ # Function to update the scatter plot
169
+ def step_and_render(self, frame):
170
+ for _ in range(self.train_iters):
171
+ self.step()
172
+
173
+ self.render()
174
+
175
+
176
+ if __name__ == "__main__":
177
+ import argparse
178
+
179
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
180
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
181
+ parser.add_argument("--num_frames", type=int, default=10000, help="Total number of frames.")
182
+ parser.add_argument("--train_iters", type=int, default=10, help="Total number of training iterations per frame.")
183
+ parser.add_argument(
184
+ "--num_particles", type=int, default=1500, help="Total number of particles to use in optimization."
185
+ )
186
+ parser.add_argument(
187
+ "--headless",
188
+ action="store_true",
189
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
190
+ )
191
+
192
+ args = parser.parse_known_args()[0]
193
+
194
+ with wp.ScopedDevice(args.device):
195
+ example = Example(headless=args.headless, train_iters=args.train_iters, num_particles=args.num_particles)
196
+
197
+ if not args.headless:
198
+ import matplotlib.pyplot as plt
199
+ from matplotlib.animation import FuncAnimation
200
+
201
+ # Create the animation
202
+ ani = FuncAnimation(
203
+ example.fig, example.step_and_render, frames=args.num_frames, interval=100, repeat=False
204
+ )
205
+
206
+ # Display the animation
207
+ plt.show()
208
+
209
+ else:
210
+ for _ in range(args.num_frames):
211
+ example.step()
@@ -0,0 +1,269 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 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
+ ###########################################################################
17
+ # Example Wave
18
+ #
19
+ # Shows how to implement a simple 2D wave-equation solver with collision
20
+ # against a moving sphere.
21
+ #
22
+ ###########################################################################
23
+
24
+ import math
25
+
26
+ import warp as wp
27
+ import warp.render
28
+
29
+
30
+ @wp.func
31
+ def sample(f: wp.array(dtype=float), x: int, y: int, width: int, height: int):
32
+ # clamp texture coords
33
+ x = wp.clamp(x, 0, width - 1)
34
+ y = wp.clamp(y, 0, height - 1)
35
+
36
+ s = f[y * width + x]
37
+ return s
38
+
39
+
40
+ @wp.func
41
+ def laplacian(f: wp.array(dtype=float), x: int, y: int, width: int, height: int):
42
+ ddx = sample(f, x + 1, y, width, height) - 2.0 * sample(f, x, y, width, height) + sample(f, x - 1, y, width, height)
43
+ ddy = sample(f, x, y + 1, width, height) - 2.0 * sample(f, x, y, width, height) + sample(f, x, y - 1, width, height)
44
+
45
+ return ddx + ddy
46
+
47
+
48
+ @wp.kernel
49
+ def wave_displace(
50
+ hcurrent: wp.array(dtype=float),
51
+ hprevious: wp.array(dtype=float),
52
+ width: int,
53
+ height: int,
54
+ center_x: float,
55
+ center_y: float,
56
+ r: float,
57
+ mag: float,
58
+ t: float,
59
+ ):
60
+ tid = wp.tid()
61
+
62
+ x = tid % width
63
+ y = tid // width
64
+
65
+ dx = float(x) - center_x
66
+ dy = float(y) - center_y
67
+
68
+ dist_sq = float(dx * dx + dy * dy)
69
+
70
+ if dist_sq < r * r:
71
+ h = mag * wp.sin(t)
72
+
73
+ hcurrent[tid] = h
74
+ hprevious[tid] = h
75
+
76
+
77
+ @wp.kernel
78
+ def wave_solve(
79
+ hprevious: wp.array(dtype=float),
80
+ hcurrent: wp.array(dtype=float),
81
+ width: int,
82
+ height: int,
83
+ inv_cell: float,
84
+ k_speed: float,
85
+ k_damp: float,
86
+ dt: float,
87
+ ):
88
+ tid = wp.tid()
89
+
90
+ x = tid % width
91
+ y = tid // width
92
+
93
+ l = laplacian(hcurrent, x, y, width, height) * inv_cell * inv_cell
94
+
95
+ # integrate
96
+ h1 = hcurrent[tid]
97
+ h0 = hprevious[tid]
98
+
99
+ h = 2.0 * h1 - h0 + dt * dt * (k_speed * l - k_damp * (h1 - h0))
100
+
101
+ # buffers get swapped each iteration
102
+ hprevious[tid] = h
103
+
104
+
105
+ # simple kernel to apply height deltas to a vertex array
106
+ @wp.kernel
107
+ def grid_update(heights: wp.array(dtype=float), vertices: wp.array(dtype=wp.vec3)):
108
+ tid = wp.tid()
109
+
110
+ h = heights[tid]
111
+ v = vertices[tid]
112
+
113
+ v_new = wp.vec3(v[0], h, v[2])
114
+
115
+ vertices[tid] = v_new
116
+
117
+
118
+ class Example:
119
+ def __init__(self, stage_path="example_wave.usd", verbose=False):
120
+ self.sim_width = 128
121
+ self.sim_height = 128
122
+
123
+ fps = 60
124
+ self.sim_substeps = 16
125
+ self.sim_dt = (1.0 / fps) / self.sim_substeps
126
+ self.sim_time = 0.0
127
+
128
+ # wave constants
129
+ self.k_speed = 1.0
130
+ self.k_damp = 0.0
131
+
132
+ # grid constants
133
+ self.grid_size = 0.1
134
+ self.grid_displace = 0.5
135
+
136
+ self.verbose = verbose
137
+
138
+ vertices = []
139
+ self.indices = []
140
+
141
+ def grid_index(x, y, stride):
142
+ return y * stride + x
143
+
144
+ for z in range(self.sim_height):
145
+ for x in range(self.sim_width):
146
+ pos = (
147
+ float(x) * self.grid_size,
148
+ 0.0,
149
+ float(z) * self.grid_size,
150
+ )
151
+
152
+ # directly modifies verts_host memory since this is a numpy alias of the same buffer
153
+ vertices.append(pos)
154
+
155
+ if x > 0 and z > 0:
156
+ self.indices.append(grid_index(x - 1, z - 1, self.sim_width))
157
+ self.indices.append(grid_index(x, z, self.sim_width))
158
+ self.indices.append(grid_index(x, z - 1, self.sim_width))
159
+
160
+ self.indices.append(grid_index(x - 1, z - 1, self.sim_width))
161
+ self.indices.append(grid_index(x - 1, z, self.sim_width))
162
+ self.indices.append(grid_index(x, z, self.sim_width))
163
+
164
+ # simulation grids
165
+ self.sim_grid0 = wp.zeros(self.sim_width * self.sim_height, dtype=float)
166
+ self.sim_grid1 = wp.zeros(self.sim_width * self.sim_height, dtype=float)
167
+ self.sim_verts = wp.array(vertices, dtype=wp.vec3)
168
+
169
+ # create surface displacement around a point
170
+ self.cx = self.sim_width / 2 + math.sin(self.sim_time) * self.sim_width / 3
171
+ self.cy = self.sim_height / 2 + math.cos(self.sim_time) * self.sim_height / 3
172
+
173
+ if stage_path:
174
+ self.renderer = wp.render.UsdRenderer(stage_path)
175
+ else:
176
+ self.renderer = None
177
+
178
+ def step(self):
179
+ with wp.ScopedTimer("step"):
180
+ for _s in range(self.sim_substeps):
181
+ # create surface displacement around a point
182
+ self.cx = self.sim_width / 2 + math.sin(self.sim_time) * self.sim_width / 3
183
+ self.cy = self.sim_height / 2 + math.cos(self.sim_time) * self.sim_height / 3
184
+
185
+ wp.launch(
186
+ kernel=wave_displace,
187
+ dim=self.sim_width * self.sim_height,
188
+ inputs=[
189
+ self.sim_grid0,
190
+ self.sim_grid1,
191
+ self.sim_width,
192
+ self.sim_height,
193
+ self.cx,
194
+ self.cy,
195
+ 10.0,
196
+ self.grid_displace,
197
+ -math.pi * 0.5,
198
+ ],
199
+ )
200
+
201
+ # integrate wave equation
202
+ wp.launch(
203
+ kernel=wave_solve,
204
+ dim=self.sim_width * self.sim_height,
205
+ inputs=[
206
+ self.sim_grid0,
207
+ self.sim_grid1,
208
+ self.sim_width,
209
+ self.sim_height,
210
+ 1.0 / self.grid_size,
211
+ self.k_speed,
212
+ self.k_damp,
213
+ self.sim_dt,
214
+ ],
215
+ )
216
+
217
+ # swap grids
218
+ (self.sim_grid0, self.sim_grid1) = (self.sim_grid1, self.sim_grid0)
219
+
220
+ self.sim_time += self.sim_dt
221
+
222
+ with wp.ScopedTimer("mesh", self.verbose):
223
+ # update grid vertices from heights
224
+ wp.launch(kernel=grid_update, dim=self.sim_width * self.sim_height, inputs=[self.sim_grid0, self.sim_verts])
225
+
226
+ def render(self):
227
+ if self.renderer is None:
228
+ return
229
+
230
+ with wp.ScopedTimer("render"):
231
+ vertices = self.sim_verts.numpy()
232
+
233
+ self.renderer.begin_frame(self.sim_time)
234
+ self.renderer.render_mesh("surface", vertices, self.indices, colors=(0.35, 0.55, 0.9))
235
+ self.renderer.render_sphere(
236
+ "sphere",
237
+ (self.cx * self.grid_size, 0.0, self.cy * self.grid_size),
238
+ (0.0, 0.0, 0.0, 1.0),
239
+ 10.0 * self.grid_size,
240
+ color=(1.0, 1.0, 1.0),
241
+ )
242
+ self.renderer.end_frame()
243
+
244
+
245
+ if __name__ == "__main__":
246
+ import argparse
247
+
248
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
249
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
250
+ parser.add_argument(
251
+ "--stage_path",
252
+ type=lambda x: None if x == "None" else str(x),
253
+ default="example_wave.usd",
254
+ help="Path to the output USD file.",
255
+ )
256
+ parser.add_argument("--num_frames", type=int, default=300, help="Total number of frames.")
257
+ parser.add_argument("--verbose", action="store_true", help="Print out additional status messages during execution.")
258
+
259
+ args = parser.parse_known_args()[0]
260
+
261
+ with wp.ScopedDevice(args.device):
262
+ example = Example(stage_path=args.stage_path, verbose=args.verbose)
263
+
264
+ for _ in range(args.num_frames):
265
+ example.step()
266
+ example.render()
267
+
268
+ if example.renderer:
269
+ example.renderer.save()
@@ -0,0 +1,118 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 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
+ ###########################################################################
17
+ # Example Work Queue
18
+ #
19
+ # Shows how to use a work queue to synchronize access to a shared resource.
20
+ #
21
+ ###########################################################################
22
+
23
+ import warp as wp
24
+ from warp.tests.unittest_utils import *
25
+
26
+
27
+ @wp.func
28
+ def volatile_read(ptr: wp.array(dtype=wp.int32), index: int):
29
+ value = wp.atomic_add(ptr, index, 0)
30
+ return value
31
+
32
+
33
+ @wp.struct
34
+ class WorkQueue:
35
+ buffer: wp.array(dtype=wp.int32)
36
+ capacity: int
37
+ head: wp.array(dtype=wp.int32)
38
+ tail: wp.array(dtype=wp.int32)
39
+
40
+
41
+ @wp.func
42
+ def enqueue(queue: WorkQueue, item: int) -> bool:
43
+ while True:
44
+ # Read current head and tail atomically
45
+ current_tail = volatile_read(queue.tail, 0)
46
+ current_head = volatile_read(queue.head, 0)
47
+
48
+ # Check if queue is full
49
+ if (current_tail - current_head) >= queue.capacity:
50
+ return False
51
+
52
+ # Try to increment tail atomically
53
+ index = current_tail % queue.capacity
54
+ if wp.atomic_cas(queue.tail, 0, current_tail, current_tail + 1) == current_tail:
55
+ queue.buffer[index] = item
56
+ return True
57
+
58
+ # Retry if another thread changed tail
59
+
60
+
61
+ @wp.func
62
+ def dequeue(queue: WorkQueue) -> tuple[bool, int]:
63
+ while True:
64
+ # Read current head and tail atomically
65
+ current_head = volatile_read(queue.head, 0)
66
+ current_tail = volatile_read(queue.tail, 0)
67
+
68
+ # Check if queue is empty
69
+ if current_head >= current_tail:
70
+ return False, 0
71
+
72
+ # Get item at current head
73
+ index = current_head % queue.capacity
74
+ item = queue.buffer[index]
75
+
76
+ # Try to increment head atomically
77
+ if wp.atomic_cas(queue.head, 0, current_head, current_head + 1) == current_head:
78
+ return True, item
79
+
80
+ # Retry if another thread changed head
81
+
82
+
83
+ @wp.kernel
84
+ def process_queue(queue: WorkQueue):
85
+ counter = int(0)
86
+ while True:
87
+ success, item = dequeue(queue)
88
+ if not success:
89
+ break
90
+ wp.printf("Processed item: %d\n", item)
91
+ if item < 1000000:
92
+ if not enqueue(queue, item + 1000000):
93
+ wp.printf("Failed to enqueue item: %d\n", item + 1000000)
94
+ counter = counter + 1
95
+
96
+
97
+ def test_work_queue(device):
98
+ # Create a work queue with capacity 1024
99
+ capacity = 8192
100
+ head = wp.array([0], dtype=wp.int32, device=device)
101
+ tail = wp.array([4096], dtype=wp.int32, device=device)
102
+ buffer = wp.array(np.arange(4096, dtype=np.int32), dtype=wp.int32, device=device)
103
+
104
+ queue = WorkQueue()
105
+ queue.capacity = capacity
106
+ queue.head = head
107
+ queue.tail = tail
108
+ queue.buffer = buffer
109
+
110
+ # Launch processing kernel
111
+ wp.launch(process_queue, dim=1024, inputs=[queue], device=device)
112
+
113
+ wp.synchronize()
114
+
115
+
116
+ if __name__ == "__main__":
117
+ wp.clear_kernel_cache()
118
+ test_work_queue(device="cuda")