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,594 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023 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
+ import contextlib
17
+ import inspect
18
+ import io
19
+ import unittest
20
+
21
+ from warp._src.types import type_scalar_type
22
+ from warp.tests.unittest_utils import *
23
+
24
+
25
+ def test_array_scan(test, device):
26
+ rng = np.random.default_rng(123)
27
+
28
+ for dtype in (int, float):
29
+ if dtype == int:
30
+ values = rng.integers(-1e6, high=1e6, size=100000, dtype=dtype)
31
+ else:
32
+ values = rng.uniform(low=-1e6, high=1e6, size=100000)
33
+
34
+ expected = np.cumsum(values)
35
+
36
+ values = wp.array(values, dtype=dtype, device=device)
37
+ result_inc = wp.zeros_like(values)
38
+ result_exc = wp.zeros_like(values)
39
+
40
+ wp._src.utils.array_scan(values, result_inc, True)
41
+ wp._src.utils.array_scan(values, result_exc, False)
42
+
43
+ tolerance = 0 if dtype == int else 1e-3
44
+
45
+ result_inc = result_inc.numpy().squeeze()
46
+ result_exc = result_exc.numpy().squeeze()
47
+ error_inc = np.max(np.abs(result_inc - expected)) / abs(expected[-1])
48
+ error_exc = max(np.max(np.abs(result_exc[1:] - expected[:-1])), abs(result_exc[0])) / abs(expected[-2])
49
+
50
+ test.assertTrue(error_inc <= tolerance)
51
+ test.assertTrue(error_exc <= tolerance)
52
+
53
+
54
+ def test_array_scan_empty(test, device):
55
+ values = wp.array((), dtype=int, device=device)
56
+ result = wp.array((), dtype=int, device=device)
57
+ wp._src.utils.array_scan(values, result)
58
+
59
+
60
+ def test_array_scan_error_sizes_mismatch(test, device):
61
+ values = wp.zeros(123, dtype=int, device=device)
62
+ result = wp.zeros(234, dtype=int, device=device)
63
+ with test.assertRaisesRegex(
64
+ RuntimeError,
65
+ r"In and out array storage sizes do not match \(123 vs 234\)$",
66
+ ):
67
+ wp._src.utils.array_scan(values, result, True)
68
+
69
+
70
+ def test_array_scan_error_dtypes_mismatch(test, device):
71
+ values = wp.zeros(123, dtype=int, device=device)
72
+ result = wp.zeros(123, dtype=float, device=device)
73
+ with test.assertRaisesRegex(
74
+ RuntimeError,
75
+ r"In and out array data types do not match \(int32 vs float32\)$",
76
+ ):
77
+ wp._src.utils.array_scan(values, result, True)
78
+
79
+
80
+ def test_array_scan_error_unsupported_dtype(test, device):
81
+ values = wp.zeros(123, dtype=wp.vec3, device=device)
82
+ result = wp.zeros(123, dtype=wp.vec3, device=device)
83
+ with test.assertRaisesRegex(
84
+ RuntimeError,
85
+ r"Unsupported data type: vec3f$",
86
+ ):
87
+ wp._src.utils.array_scan(values, result, True)
88
+
89
+
90
+ def test_radix_sort_pairs(test, device):
91
+ keyTypes = [int, wp.float32, wp.int64]
92
+
93
+ for keyType in keyTypes:
94
+ keys = wp.array((7, 2, 8, 4, 1, 6, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0), dtype=keyType, device=device)
95
+ values = wp.array((1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0), dtype=int, device=device)
96
+ wp._src.utils.radix_sort_pairs(keys, values, 8)
97
+ assert_np_equal(keys.numpy()[:8], np.array((1, 2, 3, 4, 5, 6, 7, 8)))
98
+ assert_np_equal(values.numpy()[:8], np.array((5, 2, 8, 4, 7, 6, 1, 3)))
99
+
100
+
101
+ def test_segmented_sort_pairs(test, device):
102
+ keyTypes = [int, wp.float32]
103
+
104
+ for keyType in keyTypes:
105
+ keys = wp.array((7, 2, 8, 4, 1, 6, 5, 3, 0, 0, 0, 0, 0, 0, 0, 0), dtype=keyType, device=device)
106
+ values = wp.array((1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0), dtype=int, device=device)
107
+ wp._src.utils.segmented_sort_pairs(
108
+ keys,
109
+ values,
110
+ 8,
111
+ wp.array((0, 4), dtype=int, device=device),
112
+ wp.array((4, 8), dtype=int, device=device),
113
+ )
114
+ assert_np_equal(keys.numpy()[:8], np.array((2, 4, 7, 8, 1, 3, 5, 6)))
115
+ assert_np_equal(values.numpy()[:8], np.array((2, 4, 1, 3, 5, 8, 7, 6)))
116
+
117
+
118
+ def test_radix_sort_pairs_empty(test, device):
119
+ keyTypes = [int, wp.float32, wp.int64]
120
+
121
+ for keyType in keyTypes:
122
+ keys = wp.array((), dtype=keyType, device=device)
123
+ values = wp.array((), dtype=int, device=device)
124
+ wp._src.utils.radix_sort_pairs(keys, values, 0)
125
+
126
+
127
+ def test_segmented_sort_pairs_empty(test, device):
128
+ keyTypes = [int, wp.float32]
129
+
130
+ for keyType in keyTypes:
131
+ keys = wp.array((), dtype=keyType, device=device)
132
+ values = wp.array((), dtype=int, device=device)
133
+ wp._src.utils.segmented_sort_pairs(
134
+ keys, values, 0, wp.array((), dtype=int, device=device), wp.array((), dtype=int, device=device)
135
+ )
136
+
137
+
138
+ def test_radix_sort_pairs_error_insufficient_storage(test, device):
139
+ keyTypes = [int, wp.float32, wp.int64]
140
+
141
+ for keyType in keyTypes:
142
+ keys = wp.array((1, 2, 3), dtype=keyType, device=device)
143
+ values = wp.array((1, 2, 3), dtype=int, device=device)
144
+ with test.assertRaisesRegex(
145
+ RuntimeError,
146
+ r"Keys and values array storage must be large enough to contain 2\*count elements$",
147
+ ):
148
+ wp._src.utils.radix_sort_pairs(keys, values, 3)
149
+
150
+
151
+ def test_segmented_sort_pairs_error_insufficient_storage(test, device):
152
+ keyTypes = [int, wp.float32]
153
+
154
+ for keyType in keyTypes:
155
+ keys = wp.array((1, 2, 3), dtype=keyType, device=device)
156
+ values = wp.array((1, 2, 3), dtype=int, device=device)
157
+ with test.assertRaisesRegex(
158
+ RuntimeError,
159
+ r"Array storage must be large enough to contain 2\*count elements$",
160
+ ):
161
+ wp._src.utils.segmented_sort_pairs(
162
+ keys,
163
+ values,
164
+ 3,
165
+ wp.array((0,), dtype=int, device=device),
166
+ wp.array((3,), dtype=int, device=device),
167
+ )
168
+
169
+
170
+ def test_radix_sort_pairs_error_unsupported_dtype(test, device):
171
+ keyTypes = [wp.int32, wp.float32, wp.int64]
172
+
173
+ for keyType in keyTypes:
174
+ keys = wp.array((1.0, 2.0, 3.0), dtype=keyType, device=device)
175
+ values = wp.array((1.0, 2.0, 3.0), dtype=float, device=device)
176
+ with test.assertRaisesRegex(
177
+ RuntimeError,
178
+ rf"Unsupported keys and values data types: {keyType.__name__}, float32$",
179
+ ):
180
+ wp._src.utils.radix_sort_pairs(keys, values, 1)
181
+
182
+
183
+ def test_segmented_sort_pairs_error_unsupported_dtype(test, device):
184
+ keyTypes = [wp.int32, wp.float32]
185
+
186
+ for keyType in keyTypes:
187
+ keys = wp.array((1.0, 2.0, 3.0), dtype=keyType, device=device)
188
+ values = wp.array((1.0, 2.0, 3.0), dtype=float, device=device)
189
+ with test.assertRaisesRegex(
190
+ RuntimeError,
191
+ rf"Unsupported data type: {keyType.__name__}$",
192
+ ):
193
+ wp._src.utils.segmented_sort_pairs(
194
+ keys,
195
+ values,
196
+ 1,
197
+ wp.array((0,), dtype=int, device=device),
198
+ wp.array((3,), dtype=int, device=device),
199
+ )
200
+
201
+
202
+ def test_array_sum(test, device):
203
+ for dtype in (wp.float32, wp.float64):
204
+ with test.subTest(dtype=dtype):
205
+ values = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
206
+ test.assertEqual(wp._src.utils.array_sum(values), 6.0)
207
+
208
+ values = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
209
+ result = wp.empty(shape=(1,), dtype=dtype, device=device)
210
+ wp._src.utils.array_sum(values, out=result)
211
+ test.assertEqual(result.numpy()[0], 6.0)
212
+
213
+
214
+ def test_array_sum_error_out_dtype_mismatch(test, device):
215
+ values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
216
+ result = wp.empty(shape=(1,), dtype=wp.float64, device=device)
217
+ with test.assertRaisesRegex(
218
+ RuntimeError,
219
+ r"out array should have type float32$",
220
+ ):
221
+ wp._src.utils.array_sum(values, out=result)
222
+
223
+
224
+ def test_array_sum_error_out_shape_mismatch(test, device):
225
+ values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
226
+ result = wp.empty(shape=(2,), dtype=wp.float32, device=device)
227
+ with test.assertRaisesRegex(
228
+ RuntimeError,
229
+ r"out array should have shape \(1,\)$",
230
+ ):
231
+ wp._src.utils.array_sum(values, out=result)
232
+
233
+
234
+ def test_array_sum_error_unsupported_dtype(test, device):
235
+ values = wp.array((1, 2, 3), dtype=int, device=device)
236
+ with test.assertRaisesRegex(
237
+ RuntimeError,
238
+ r"Unsupported data type: int32$",
239
+ ):
240
+ wp._src.utils.array_sum(values)
241
+
242
+
243
+ def test_array_inner(test, device):
244
+ for dtype in (wp.float32, wp.float64, wp.vec3):
245
+ a = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
246
+ b = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
247
+ test.assertEqual(wp._src.utils.array_inner(a, b), 14.0)
248
+
249
+ a = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
250
+ b = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
251
+ result = wp.empty(shape=(1,), dtype=type_scalar_type(dtype), device=device)
252
+ wp._src.utils.array_inner(a, b, out=result)
253
+ test.assertEqual(result.numpy()[0], 14.0)
254
+
255
+ # test with different instances of same type
256
+ a = wp.array((1.0, 2.0, 3.0), dtype=wp.vec3, device=device)
257
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.vec(3, float), device=device)
258
+ test.assertEqual(wp._src.utils.array_inner(a, b), 14.0)
259
+
260
+
261
+ def test_array_inner_error_sizes_mismatch(test, device):
262
+ a = wp.array((1.0, 2.0), dtype=wp.float32, device=device)
263
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
264
+ with test.assertRaisesRegex(
265
+ RuntimeError,
266
+ r"A and b array storage sizes do not match \(2 vs 3\)$",
267
+ ):
268
+ wp._src.utils.array_inner(a, b)
269
+
270
+
271
+ def test_array_inner_error_dtypes_mismatch(test, device):
272
+ a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
273
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.float64, device=device)
274
+ with test.assertRaisesRegex(
275
+ RuntimeError,
276
+ r"A and b array data types do not match \(float32 vs float64\)$",
277
+ ):
278
+ wp._src.utils.array_inner(a, b)
279
+
280
+
281
+ def test_array_inner_error_out_dtype_mismatch(test, device):
282
+ a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
283
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
284
+ result = wp.empty(shape=(1,), dtype=wp.float64, device=device)
285
+ with test.assertRaisesRegex(
286
+ RuntimeError,
287
+ r"out array should have type float32$",
288
+ ):
289
+ wp._src.utils.array_inner(a, b, result)
290
+
291
+
292
+ def test_array_inner_error_out_shape_mismatch(test, device):
293
+ a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
294
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
295
+ result = wp.empty(shape=(2,), dtype=wp.float32, device=device)
296
+ with test.assertRaisesRegex(
297
+ RuntimeError,
298
+ r"out array should have shape \(1,\)$",
299
+ ):
300
+ wp._src.utils.array_inner(a, b, result)
301
+
302
+
303
+ def test_array_inner_error_unsupported_dtype(test, device):
304
+ a = wp.array((1, 2, 3), dtype=int, device=device)
305
+ b = wp.array((1, 2, 3), dtype=int, device=device)
306
+ with test.assertRaisesRegex(
307
+ RuntimeError,
308
+ r"Unsupported data type: int32$",
309
+ ):
310
+ wp._src.utils.array_inner(a, b)
311
+
312
+
313
+ def test_array_cast(test, device):
314
+ values = wp.array((1, 2, 3), dtype=int, device=device)
315
+ result = wp.empty(3, dtype=float, device=device)
316
+ wp._src.utils.array_cast(values, result)
317
+ test.assertEqual(result.dtype, wp.float32)
318
+ test.assertEqual(result.shape, (3,))
319
+ assert_np_equal(result.numpy(), np.array((1.0, 2.0, 3.0), dtype=float))
320
+
321
+ values = wp.array((1, 2, 3, 4), dtype=int, device=device)
322
+ result = wp.empty((2, 2), dtype=float, device=device)
323
+ wp._src.utils.array_cast(values, result)
324
+ test.assertEqual(result.dtype, wp.float32)
325
+ test.assertEqual(result.shape, (2, 2))
326
+ assert_np_equal(result.numpy(), np.array(((1.0, 2.0), (3.0, 4.0)), dtype=float))
327
+
328
+ values = wp.array(((1, 2), (3, 4)), dtype=wp.vec2, device=device)
329
+ result = wp.zeros(2, dtype=float, device=device)
330
+ wp._src.utils.array_cast(values, result, count=1)
331
+ test.assertEqual(result.dtype, wp.float32)
332
+ test.assertEqual(result.shape, (2,))
333
+ assert_np_equal(result.numpy(), np.array((1.0, 2.0), dtype=float))
334
+
335
+ values = wp.array(((1, 2), (3, 4)), dtype=int, device=device)
336
+ result = wp.zeros((2, 2), dtype=int, device=device)
337
+ wp._src.utils.array_cast(values, result)
338
+ test.assertEqual(result.dtype, wp.int32)
339
+ test.assertEqual(result.shape, (2, 2))
340
+ assert_np_equal(result.numpy(), np.array(((1, 2), (3, 4)), dtype=int))
341
+
342
+
343
+ def test_array_cast_error_unsupported_partial_cast(test, device):
344
+ values = wp.array(((1, 2), (3, 4)), dtype=int, device=device)
345
+ result = wp.zeros((2, 2), dtype=float, device=device)
346
+ with test.assertRaisesRegex(
347
+ RuntimeError,
348
+ r"Partial cast is not supported for arrays with more than one dimension$",
349
+ ):
350
+ wp._src.utils.array_cast(values, result, count=1)
351
+
352
+
353
+ devices = get_test_devices()
354
+
355
+
356
+ class TestUtils(unittest.TestCase):
357
+ def test_warn(self):
358
+ # Multiple warnings get printed out each time.
359
+ with contextlib.redirect_stdout(io.StringIO()) as f:
360
+ wp._src.utils.warn("hello, world!")
361
+ wp._src.utils.warn("hello, world!")
362
+
363
+ expected = "Warp UserWarning: hello, world!\nWarp UserWarning: hello, world!\n"
364
+
365
+ self.assertEqual(f.getvalue(), expected)
366
+
367
+ # Test verbose warnings
368
+ saved_verbosity = wp.config.verbose_warnings
369
+ try:
370
+ wp.config.verbose_warnings = True
371
+ with contextlib.redirect_stdout(io.StringIO()) as f:
372
+ frame_info = inspect.getframeinfo(inspect.currentframe())
373
+ wp._src.utils.warn("hello, world!")
374
+ wp._src.utils.warn("hello, world!")
375
+
376
+ expected = (
377
+ f"Warp UserWarning: hello, world! ({frame_info.filename}:{frame_info.lineno + 1})\n"
378
+ ' wp._src.utils.warn("hello, world!")\n'
379
+ f"Warp UserWarning: hello, world! ({frame_info.filename}:{frame_info.lineno + 2})\n"
380
+ ' wp._src.utils.warn("hello, world!")\n'
381
+ )
382
+
383
+ self.assertEqual(f.getvalue(), expected)
384
+
385
+ finally:
386
+ # make sure to restore warning verbosity
387
+ wp.config.verbose_warnings = saved_verbosity
388
+
389
+ # Multiple similar deprecation warnings get printed out only once.
390
+ with contextlib.redirect_stdout(io.StringIO()) as f:
391
+ wp._src.utils.warn("hello, world!", category=DeprecationWarning)
392
+ wp._src.utils.warn("hello, world!", category=DeprecationWarning)
393
+
394
+ expected = "Warp DeprecationWarning: hello, world!\n"
395
+
396
+ self.assertEqual(f.getvalue(), expected)
397
+
398
+ # Multiple different deprecation warnings get printed out each time.
399
+ with contextlib.redirect_stdout(io.StringIO()) as f:
400
+ wp._src.utils.warn("foo", category=DeprecationWarning)
401
+ wp._src.utils.warn("bar", category=DeprecationWarning)
402
+
403
+ expected = "Warp DeprecationWarning: foo\nWarp DeprecationWarning: bar\n"
404
+
405
+ self.assertEqual(f.getvalue(), expected)
406
+
407
+ def test_transform_expand(self):
408
+ t = (1.0, 2.0, 3.0, 4.0, 3.0, 2.0, 1.0)
409
+ self.assertEqual(
410
+ wp._src.utils.transform_expand(t),
411
+ wp.transformf(p=(1.0, 2.0, 3.0), q=(4.0, 3.0, 2.0, 1.0)),
412
+ )
413
+
414
+ @unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
415
+ def test_array_scan_error_devices_mismatch(self):
416
+ values = wp.zeros(123, dtype=int, device="cpu")
417
+ result = wp.zeros_like(values, device="cuda:0")
418
+ with self.assertRaisesRegex(
419
+ RuntimeError,
420
+ r"In and out array storage devices do not match \(cpu vs cuda:0\)$",
421
+ ):
422
+ wp._src.utils.array_scan(values, result, True)
423
+
424
+ @unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
425
+ def test_radix_sort_pairs_error_devices_mismatch(self):
426
+ keys = wp.array((1, 2, 3), dtype=int, device="cpu")
427
+ values = wp.array((1, 2, 3), dtype=int, device="cuda:0")
428
+ with self.assertRaisesRegex(
429
+ RuntimeError,
430
+ r"Keys and values array storage devices do not match \(cpu vs cuda:0\)$",
431
+ ):
432
+ wp._src.utils.radix_sort_pairs(keys, values, 1)
433
+
434
+ @unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
435
+ def test_array_inner_error_out_device_mismatch(self):
436
+ a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
437
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
438
+ result = wp.empty(shape=(1,), dtype=wp.float32, device="cuda:0")
439
+ with self.assertRaisesRegex(
440
+ RuntimeError,
441
+ r"out storage device should match values array$",
442
+ ):
443
+ wp._src.utils.array_inner(a, b, result)
444
+
445
+ @unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
446
+ def test_array_sum_error_out_device_mismatch(self):
447
+ values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
448
+ result = wp.empty(shape=(1,), dtype=wp.float32, device="cuda:0")
449
+ with self.assertRaisesRegex(
450
+ RuntimeError,
451
+ r"out storage device should match values array$",
452
+ ):
453
+ wp._src.utils.array_sum(values, out=result)
454
+
455
+ @unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
456
+ def test_array_inner_error_devices_mismatch(self):
457
+ a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
458
+ b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cuda:0")
459
+ with self.assertRaisesRegex(
460
+ RuntimeError,
461
+ r"A and b array storage devices do not match \(cpu vs cuda:0\)$",
462
+ ):
463
+ wp._src.utils.array_inner(a, b)
464
+
465
+ @unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
466
+ def test_array_cast_error_devices_mismatch(self):
467
+ values = wp.array((1, 2, 3), dtype=int, device="cpu")
468
+ result = wp.empty(3, dtype=float, device="cuda:0")
469
+ with self.assertRaisesRegex(
470
+ RuntimeError,
471
+ r"Array storage devices do not match \(cpu vs cuda:0\)$",
472
+ ):
473
+ wp._src.utils.array_cast(values, result)
474
+
475
+ def test_mesh_adjacency(self):
476
+ triangles = (
477
+ (0, 3, 1),
478
+ (0, 2, 3),
479
+ )
480
+ adj = wp._src.utils.MeshAdjacency(triangles, len(triangles))
481
+ expected_edges = {
482
+ (0, 3): (0, 3, 1, 2, 0, 1),
483
+ (1, 3): (3, 1, 0, -1, 0, -1),
484
+ (0, 1): (1, 0, 3, -1, 0, -1),
485
+ (0, 2): (0, 2, 3, -1, 1, -1),
486
+ (2, 3): (2, 3, 0, -1, 1, -1),
487
+ }
488
+ edges = {k: (e.v0, e.v1, e.o0, e.o1, e.f0, e.f1) for k, e in adj.edges.items()}
489
+ self.assertDictEqual(edges, expected_edges)
490
+
491
+ def test_mesh_adjacency_error_manifold(self):
492
+ triangles = (
493
+ (0, 3, 1),
494
+ (0, 2, 3),
495
+ (3, 0, 1),
496
+ )
497
+
498
+ with contextlib.redirect_stdout(io.StringIO()) as f:
499
+ wp._src.utils.MeshAdjacency(triangles, len(triangles))
500
+
501
+ self.assertEqual(f.getvalue(), "Detected non-manifold edge\n")
502
+
503
+ def test_scoped_timer(self):
504
+ with contextlib.redirect_stdout(io.StringIO()) as f:
505
+ with wp.ScopedTimer("hello"):
506
+ pass
507
+
508
+ self.assertRegex(f.getvalue(), r"^hello took \d+\.\d+ ms$")
509
+
510
+ with contextlib.redirect_stdout(io.StringIO()) as f:
511
+ with wp.ScopedTimer("hello", detailed=True):
512
+ pass
513
+
514
+ self.assertRegex(f.getvalue(), r"^ 4 function calls in \d+\.\d+ seconds")
515
+ self.assertRegex(f.getvalue(), r"hello took \d+\.\d+ ms$")
516
+
517
+
518
+ add_function_test(TestUtils, "test_array_scan", test_array_scan, devices=devices)
519
+ add_function_test(TestUtils, "test_array_scan_empty", test_array_scan_empty, devices=devices)
520
+ add_function_test(
521
+ TestUtils, "test_array_scan_error_sizes_mismatch", test_array_scan_error_sizes_mismatch, devices=devices
522
+ )
523
+ add_function_test(
524
+ TestUtils, "test_array_scan_error_dtypes_mismatch", test_array_scan_error_dtypes_mismatch, devices=devices
525
+ )
526
+ add_function_test(
527
+ TestUtils, "test_array_scan_error_unsupported_dtype", test_array_scan_error_unsupported_dtype, devices=devices
528
+ )
529
+ add_function_test(TestUtils, "test_radix_sort_pairs", test_radix_sort_pairs, devices=devices)
530
+ add_function_test(TestUtils, "test_radix_sort_pairs_empty", test_radix_sort_pairs, devices=devices)
531
+ add_function_test(
532
+ TestUtils,
533
+ "test_radix_sort_pairs_error_insufficient_storage",
534
+ test_radix_sort_pairs_error_insufficient_storage,
535
+ devices=devices,
536
+ )
537
+ add_function_test(
538
+ TestUtils,
539
+ "test_radix_sort_pairs_error_unsupported_dtype",
540
+ test_radix_sort_pairs_error_unsupported_dtype,
541
+ devices=devices,
542
+ )
543
+ add_function_test(TestUtils, "test_segmented_sort_pairs", test_segmented_sort_pairs, devices=devices)
544
+ add_function_test(TestUtils, "test_segmented_sort_pairs_empty", test_segmented_sort_pairs, devices=devices)
545
+ add_function_test(
546
+ TestUtils,
547
+ "test_segmented_sort_pairs_error_insufficient_storage",
548
+ test_segmented_sort_pairs_error_insufficient_storage,
549
+ devices=devices,
550
+ )
551
+ add_function_test(
552
+ TestUtils,
553
+ "test_segmented_sort_pairs_error_unsupported_dtype",
554
+ test_segmented_sort_pairs_error_unsupported_dtype,
555
+ devices=devices,
556
+ )
557
+ add_function_test(TestUtils, "test_array_sum", test_array_sum, devices=devices)
558
+ add_function_test(
559
+ TestUtils, "test_array_sum_error_out_dtype_mismatch", test_array_sum_error_out_dtype_mismatch, devices=devices
560
+ )
561
+ add_function_test(
562
+ TestUtils, "test_array_sum_error_out_shape_mismatch", test_array_sum_error_out_shape_mismatch, devices=devices
563
+ )
564
+ add_function_test(
565
+ TestUtils, "test_array_sum_error_unsupported_dtype", test_array_sum_error_unsupported_dtype, devices=devices
566
+ )
567
+ add_function_test(TestUtils, "test_array_inner", test_array_inner, devices=devices)
568
+ add_function_test(
569
+ TestUtils, "test_array_inner_error_sizes_mismatch", test_array_inner_error_sizes_mismatch, devices=devices
570
+ )
571
+ add_function_test(
572
+ TestUtils, "test_array_inner_error_dtypes_mismatch", test_array_inner_error_dtypes_mismatch, devices=devices
573
+ )
574
+ add_function_test(
575
+ TestUtils, "test_array_inner_error_out_dtype_mismatch", test_array_inner_error_out_dtype_mismatch, devices=devices
576
+ )
577
+ add_function_test(
578
+ TestUtils, "test_array_inner_error_out_shape_mismatch", test_array_inner_error_out_shape_mismatch, devices=devices
579
+ )
580
+ add_function_test(
581
+ TestUtils, "test_array_inner_error_unsupported_dtype", test_array_inner_error_unsupported_dtype, devices=devices
582
+ )
583
+ add_function_test(TestUtils, "test_array_cast", test_array_cast, devices=devices)
584
+ add_function_test(
585
+ TestUtils,
586
+ "test_array_cast_error_unsupported_partial_cast",
587
+ test_array_cast_error_unsupported_partial_cast,
588
+ devices=devices,
589
+ )
590
+
591
+
592
+ if __name__ == "__main__":
593
+ wp.clear_kernel_cache()
594
+ unittest.main(verbosity=2)