warp-lang 1.7.0__py3-none-manylinux_2_34_aarch64.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 (429) hide show
  1. warp/__init__.py +139 -0
  2. warp/__init__.pyi +1 -0
  3. warp/autograd.py +1142 -0
  4. warp/bin/warp-clang.so +0 -0
  5. warp/bin/warp.so +0 -0
  6. warp/build.py +557 -0
  7. warp/build_dll.py +405 -0
  8. warp/builtins.py +6855 -0
  9. warp/codegen.py +3969 -0
  10. warp/config.py +158 -0
  11. warp/constants.py +57 -0
  12. warp/context.py +6812 -0
  13. warp/dlpack.py +462 -0
  14. warp/examples/__init__.py +24 -0
  15. warp/examples/assets/bear.usd +0 -0
  16. warp/examples/assets/bunny.usd +0 -0
  17. warp/examples/assets/cartpole.urdf +110 -0
  18. warp/examples/assets/crazyflie.usd +0 -0
  19. warp/examples/assets/cube.usd +0 -0
  20. warp/examples/assets/nonuniform.usd +0 -0
  21. warp/examples/assets/nv_ant.xml +92 -0
  22. warp/examples/assets/nv_humanoid.xml +183 -0
  23. warp/examples/assets/nvidia_logo.png +0 -0
  24. warp/examples/assets/pixel.jpg +0 -0
  25. warp/examples/assets/quadruped.urdf +268 -0
  26. warp/examples/assets/rocks.nvdb +0 -0
  27. warp/examples/assets/rocks.usd +0 -0
  28. warp/examples/assets/sphere.usd +0 -0
  29. warp/examples/assets/square_cloth.usd +0 -0
  30. warp/examples/benchmarks/benchmark_api.py +389 -0
  31. warp/examples/benchmarks/benchmark_cloth.py +296 -0
  32. warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
  33. warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
  34. warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
  35. warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
  36. warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
  37. warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
  38. warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
  39. warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
  40. warp/examples/benchmarks/benchmark_gemm.py +164 -0
  41. warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
  42. warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
  43. warp/examples/benchmarks/benchmark_launches.py +301 -0
  44. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  45. warp/examples/browse.py +37 -0
  46. warp/examples/core/example_cupy.py +86 -0
  47. warp/examples/core/example_dem.py +241 -0
  48. warp/examples/core/example_fluid.py +299 -0
  49. warp/examples/core/example_graph_capture.py +150 -0
  50. warp/examples/core/example_marching_cubes.py +194 -0
  51. warp/examples/core/example_mesh.py +180 -0
  52. warp/examples/core/example_mesh_intersect.py +211 -0
  53. warp/examples/core/example_nvdb.py +182 -0
  54. warp/examples/core/example_raycast.py +111 -0
  55. warp/examples/core/example_raymarch.py +205 -0
  56. warp/examples/core/example_render_opengl.py +193 -0
  57. warp/examples/core/example_sample_mesh.py +300 -0
  58. warp/examples/core/example_sph.py +411 -0
  59. warp/examples/core/example_torch.py +211 -0
  60. warp/examples/core/example_wave.py +269 -0
  61. warp/examples/fem/example_adaptive_grid.py +286 -0
  62. warp/examples/fem/example_apic_fluid.py +423 -0
  63. warp/examples/fem/example_burgers.py +261 -0
  64. warp/examples/fem/example_convection_diffusion.py +178 -0
  65. warp/examples/fem/example_convection_diffusion_dg.py +204 -0
  66. warp/examples/fem/example_deformed_geometry.py +172 -0
  67. warp/examples/fem/example_diffusion.py +196 -0
  68. warp/examples/fem/example_diffusion_3d.py +225 -0
  69. warp/examples/fem/example_diffusion_mgpu.py +220 -0
  70. warp/examples/fem/example_distortion_energy.py +228 -0
  71. warp/examples/fem/example_magnetostatics.py +240 -0
  72. warp/examples/fem/example_mixed_elasticity.py +291 -0
  73. warp/examples/fem/example_navier_stokes.py +261 -0
  74. warp/examples/fem/example_nonconforming_contact.py +298 -0
  75. warp/examples/fem/example_stokes.py +213 -0
  76. warp/examples/fem/example_stokes_transfer.py +262 -0
  77. warp/examples/fem/example_streamlines.py +352 -0
  78. warp/examples/fem/utils.py +1000 -0
  79. warp/examples/interop/example_jax_callable.py +116 -0
  80. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  81. warp/examples/interop/example_jax_kernel.py +205 -0
  82. warp/examples/optim/example_bounce.py +266 -0
  83. warp/examples/optim/example_cloth_throw.py +228 -0
  84. warp/examples/optim/example_diffray.py +561 -0
  85. warp/examples/optim/example_drone.py +870 -0
  86. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  87. warp/examples/optim/example_inverse_kinematics.py +182 -0
  88. warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
  89. warp/examples/optim/example_softbody_properties.py +400 -0
  90. warp/examples/optim/example_spring_cage.py +245 -0
  91. warp/examples/optim/example_trajectory.py +227 -0
  92. warp/examples/sim/example_cartpole.py +143 -0
  93. warp/examples/sim/example_cloth.py +225 -0
  94. warp/examples/sim/example_cloth_self_contact.py +322 -0
  95. warp/examples/sim/example_granular.py +130 -0
  96. warp/examples/sim/example_granular_collision_sdf.py +202 -0
  97. warp/examples/sim/example_jacobian_ik.py +244 -0
  98. warp/examples/sim/example_particle_chain.py +124 -0
  99. warp/examples/sim/example_quadruped.py +203 -0
  100. warp/examples/sim/example_rigid_chain.py +203 -0
  101. warp/examples/sim/example_rigid_contact.py +195 -0
  102. warp/examples/sim/example_rigid_force.py +133 -0
  103. warp/examples/sim/example_rigid_gyroscopic.py +115 -0
  104. warp/examples/sim/example_rigid_soft_contact.py +140 -0
  105. warp/examples/sim/example_soft_body.py +196 -0
  106. warp/examples/tile/example_tile_cholesky.py +87 -0
  107. warp/examples/tile/example_tile_convolution.py +66 -0
  108. warp/examples/tile/example_tile_fft.py +55 -0
  109. warp/examples/tile/example_tile_filtering.py +113 -0
  110. warp/examples/tile/example_tile_matmul.py +85 -0
  111. warp/examples/tile/example_tile_mlp.py +383 -0
  112. warp/examples/tile/example_tile_nbody.py +199 -0
  113. warp/examples/tile/example_tile_walker.py +327 -0
  114. warp/fabric.py +355 -0
  115. warp/fem/__init__.py +106 -0
  116. warp/fem/adaptivity.py +508 -0
  117. warp/fem/cache.py +572 -0
  118. warp/fem/dirichlet.py +202 -0
  119. warp/fem/domain.py +411 -0
  120. warp/fem/field/__init__.py +125 -0
  121. warp/fem/field/field.py +619 -0
  122. warp/fem/field/nodal_field.py +326 -0
  123. warp/fem/field/restriction.py +37 -0
  124. warp/fem/field/virtual.py +848 -0
  125. warp/fem/geometry/__init__.py +32 -0
  126. warp/fem/geometry/adaptive_nanogrid.py +857 -0
  127. warp/fem/geometry/closest_point.py +84 -0
  128. warp/fem/geometry/deformed_geometry.py +221 -0
  129. warp/fem/geometry/element.py +776 -0
  130. warp/fem/geometry/geometry.py +362 -0
  131. warp/fem/geometry/grid_2d.py +392 -0
  132. warp/fem/geometry/grid_3d.py +452 -0
  133. warp/fem/geometry/hexmesh.py +911 -0
  134. warp/fem/geometry/nanogrid.py +571 -0
  135. warp/fem/geometry/partition.py +389 -0
  136. warp/fem/geometry/quadmesh.py +663 -0
  137. warp/fem/geometry/tetmesh.py +855 -0
  138. warp/fem/geometry/trimesh.py +806 -0
  139. warp/fem/integrate.py +2335 -0
  140. warp/fem/linalg.py +419 -0
  141. warp/fem/operator.py +293 -0
  142. warp/fem/polynomial.py +229 -0
  143. warp/fem/quadrature/__init__.py +17 -0
  144. warp/fem/quadrature/pic_quadrature.py +299 -0
  145. warp/fem/quadrature/quadrature.py +591 -0
  146. warp/fem/space/__init__.py +228 -0
  147. warp/fem/space/basis_function_space.py +468 -0
  148. warp/fem/space/basis_space.py +667 -0
  149. warp/fem/space/dof_mapper.py +251 -0
  150. warp/fem/space/function_space.py +309 -0
  151. warp/fem/space/grid_2d_function_space.py +177 -0
  152. warp/fem/space/grid_3d_function_space.py +227 -0
  153. warp/fem/space/hexmesh_function_space.py +257 -0
  154. warp/fem/space/nanogrid_function_space.py +201 -0
  155. warp/fem/space/partition.py +367 -0
  156. warp/fem/space/quadmesh_function_space.py +223 -0
  157. warp/fem/space/restriction.py +179 -0
  158. warp/fem/space/shape/__init__.py +143 -0
  159. warp/fem/space/shape/cube_shape_function.py +1105 -0
  160. warp/fem/space/shape/shape_function.py +133 -0
  161. warp/fem/space/shape/square_shape_function.py +926 -0
  162. warp/fem/space/shape/tet_shape_function.py +834 -0
  163. warp/fem/space/shape/triangle_shape_function.py +672 -0
  164. warp/fem/space/tetmesh_function_space.py +271 -0
  165. warp/fem/space/topology.py +424 -0
  166. warp/fem/space/trimesh_function_space.py +194 -0
  167. warp/fem/types.py +99 -0
  168. warp/fem/utils.py +420 -0
  169. warp/jax.py +187 -0
  170. warp/jax_experimental/__init__.py +16 -0
  171. warp/jax_experimental/custom_call.py +351 -0
  172. warp/jax_experimental/ffi.py +698 -0
  173. warp/jax_experimental/xla_ffi.py +602 -0
  174. warp/math.py +244 -0
  175. warp/native/array.h +1145 -0
  176. warp/native/builtin.h +1800 -0
  177. warp/native/bvh.cpp +492 -0
  178. warp/native/bvh.cu +791 -0
  179. warp/native/bvh.h +554 -0
  180. warp/native/clang/clang.cpp +536 -0
  181. warp/native/coloring.cpp +613 -0
  182. warp/native/crt.cpp +51 -0
  183. warp/native/crt.h +362 -0
  184. warp/native/cuda_crt.h +1058 -0
  185. warp/native/cuda_util.cpp +646 -0
  186. warp/native/cuda_util.h +307 -0
  187. warp/native/error.cpp +77 -0
  188. warp/native/error.h +36 -0
  189. warp/native/exports.h +1878 -0
  190. warp/native/fabric.h +245 -0
  191. warp/native/hashgrid.cpp +311 -0
  192. warp/native/hashgrid.cu +87 -0
  193. warp/native/hashgrid.h +240 -0
  194. warp/native/initializer_array.h +41 -0
  195. warp/native/intersect.h +1230 -0
  196. warp/native/intersect_adj.h +375 -0
  197. warp/native/intersect_tri.h +339 -0
  198. warp/native/marching.cpp +19 -0
  199. warp/native/marching.cu +514 -0
  200. warp/native/marching.h +19 -0
  201. warp/native/mat.h +2220 -0
  202. warp/native/mathdx.cpp +87 -0
  203. warp/native/matnn.h +343 -0
  204. warp/native/mesh.cpp +266 -0
  205. warp/native/mesh.cu +404 -0
  206. warp/native/mesh.h +1980 -0
  207. warp/native/nanovdb/GridHandle.h +366 -0
  208. warp/native/nanovdb/HostBuffer.h +590 -0
  209. warp/native/nanovdb/NanoVDB.h +6624 -0
  210. warp/native/nanovdb/PNanoVDB.h +3390 -0
  211. warp/native/noise.h +859 -0
  212. warp/native/quat.h +1371 -0
  213. warp/native/rand.h +342 -0
  214. warp/native/range.h +139 -0
  215. warp/native/reduce.cpp +174 -0
  216. warp/native/reduce.cu +364 -0
  217. warp/native/runlength_encode.cpp +79 -0
  218. warp/native/runlength_encode.cu +61 -0
  219. warp/native/scan.cpp +47 -0
  220. warp/native/scan.cu +53 -0
  221. warp/native/scan.h +23 -0
  222. warp/native/solid_angle.h +466 -0
  223. warp/native/sort.cpp +251 -0
  224. warp/native/sort.cu +277 -0
  225. warp/native/sort.h +33 -0
  226. warp/native/sparse.cpp +378 -0
  227. warp/native/sparse.cu +524 -0
  228. warp/native/spatial.h +657 -0
  229. warp/native/svd.h +702 -0
  230. warp/native/temp_buffer.h +46 -0
  231. warp/native/tile.h +2584 -0
  232. warp/native/tile_reduce.h +264 -0
  233. warp/native/vec.h +1426 -0
  234. warp/native/volume.cpp +501 -0
  235. warp/native/volume.cu +67 -0
  236. warp/native/volume.h +969 -0
  237. warp/native/volume_builder.cu +477 -0
  238. warp/native/volume_builder.h +52 -0
  239. warp/native/volume_impl.h +70 -0
  240. warp/native/warp.cpp +1082 -0
  241. warp/native/warp.cu +3636 -0
  242. warp/native/warp.h +381 -0
  243. warp/optim/__init__.py +17 -0
  244. warp/optim/adam.py +163 -0
  245. warp/optim/linear.py +1137 -0
  246. warp/optim/sgd.py +112 -0
  247. warp/paddle.py +407 -0
  248. warp/render/__init__.py +18 -0
  249. warp/render/render_opengl.py +3518 -0
  250. warp/render/render_usd.py +784 -0
  251. warp/render/utils.py +160 -0
  252. warp/sim/__init__.py +65 -0
  253. warp/sim/articulation.py +793 -0
  254. warp/sim/collide.py +2395 -0
  255. warp/sim/graph_coloring.py +300 -0
  256. warp/sim/import_mjcf.py +790 -0
  257. warp/sim/import_snu.py +227 -0
  258. warp/sim/import_urdf.py +579 -0
  259. warp/sim/import_usd.py +894 -0
  260. warp/sim/inertia.py +324 -0
  261. warp/sim/integrator.py +242 -0
  262. warp/sim/integrator_euler.py +1997 -0
  263. warp/sim/integrator_featherstone.py +2101 -0
  264. warp/sim/integrator_vbd.py +2048 -0
  265. warp/sim/integrator_xpbd.py +3292 -0
  266. warp/sim/model.py +4791 -0
  267. warp/sim/particles.py +121 -0
  268. warp/sim/render.py +427 -0
  269. warp/sim/utils.py +428 -0
  270. warp/sparse.py +2057 -0
  271. warp/stubs.py +3333 -0
  272. warp/tape.py +1203 -0
  273. warp/tests/__init__.py +1 -0
  274. warp/tests/__main__.py +4 -0
  275. warp/tests/assets/curlnoise_golden.npy +0 -0
  276. warp/tests/assets/mlp_golden.npy +0 -0
  277. warp/tests/assets/pixel.npy +0 -0
  278. warp/tests/assets/pnoise_golden.npy +0 -0
  279. warp/tests/assets/spiky.usd +0 -0
  280. warp/tests/assets/test_grid.nvdb +0 -0
  281. warp/tests/assets/test_index_grid.nvdb +0 -0
  282. warp/tests/assets/test_int32_grid.nvdb +0 -0
  283. warp/tests/assets/test_vec_grid.nvdb +0 -0
  284. warp/tests/assets/torus.nvdb +0 -0
  285. warp/tests/assets/torus.usda +105 -0
  286. warp/tests/aux_test_class_kernel.py +34 -0
  287. warp/tests/aux_test_compile_consts_dummy.py +18 -0
  288. warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
  289. warp/tests/aux_test_dependent.py +29 -0
  290. warp/tests/aux_test_grad_customs.py +29 -0
  291. warp/tests/aux_test_instancing_gc.py +26 -0
  292. warp/tests/aux_test_module_unload.py +23 -0
  293. warp/tests/aux_test_name_clash1.py +40 -0
  294. warp/tests/aux_test_name_clash2.py +40 -0
  295. warp/tests/aux_test_reference.py +9 -0
  296. warp/tests/aux_test_reference_reference.py +8 -0
  297. warp/tests/aux_test_square.py +16 -0
  298. warp/tests/aux_test_unresolved_func.py +22 -0
  299. warp/tests/aux_test_unresolved_symbol.py +22 -0
  300. warp/tests/cuda/__init__.py +0 -0
  301. warp/tests/cuda/test_async.py +676 -0
  302. warp/tests/cuda/test_ipc.py +124 -0
  303. warp/tests/cuda/test_mempool.py +233 -0
  304. warp/tests/cuda/test_multigpu.py +169 -0
  305. warp/tests/cuda/test_peer.py +139 -0
  306. warp/tests/cuda/test_pinned.py +84 -0
  307. warp/tests/cuda/test_streams.py +634 -0
  308. warp/tests/geometry/__init__.py +0 -0
  309. warp/tests/geometry/test_bvh.py +200 -0
  310. warp/tests/geometry/test_hash_grid.py +221 -0
  311. warp/tests/geometry/test_marching_cubes.py +74 -0
  312. warp/tests/geometry/test_mesh.py +316 -0
  313. warp/tests/geometry/test_mesh_query_aabb.py +399 -0
  314. warp/tests/geometry/test_mesh_query_point.py +932 -0
  315. warp/tests/geometry/test_mesh_query_ray.py +311 -0
  316. warp/tests/geometry/test_volume.py +1103 -0
  317. warp/tests/geometry/test_volume_write.py +346 -0
  318. warp/tests/interop/__init__.py +0 -0
  319. warp/tests/interop/test_dlpack.py +729 -0
  320. warp/tests/interop/test_jax.py +371 -0
  321. warp/tests/interop/test_paddle.py +800 -0
  322. warp/tests/interop/test_torch.py +1001 -0
  323. warp/tests/run_coverage_serial.py +39 -0
  324. warp/tests/sim/__init__.py +0 -0
  325. warp/tests/sim/disabled_kinematics.py +244 -0
  326. warp/tests/sim/flaky_test_sim_grad.py +290 -0
  327. warp/tests/sim/test_collision.py +604 -0
  328. warp/tests/sim/test_coloring.py +258 -0
  329. warp/tests/sim/test_model.py +224 -0
  330. warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
  331. warp/tests/sim/test_sim_kinematics.py +98 -0
  332. warp/tests/sim/test_vbd.py +597 -0
  333. warp/tests/test_adam.py +163 -0
  334. warp/tests/test_arithmetic.py +1096 -0
  335. warp/tests/test_array.py +2972 -0
  336. warp/tests/test_array_reduce.py +156 -0
  337. warp/tests/test_assert.py +250 -0
  338. warp/tests/test_atomic.py +153 -0
  339. warp/tests/test_bool.py +220 -0
  340. warp/tests/test_builtins_resolution.py +1298 -0
  341. warp/tests/test_closest_point_edge_edge.py +327 -0
  342. warp/tests/test_codegen.py +810 -0
  343. warp/tests/test_codegen_instancing.py +1495 -0
  344. warp/tests/test_compile_consts.py +215 -0
  345. warp/tests/test_conditional.py +252 -0
  346. warp/tests/test_context.py +42 -0
  347. warp/tests/test_copy.py +238 -0
  348. warp/tests/test_ctypes.py +638 -0
  349. warp/tests/test_dense.py +73 -0
  350. warp/tests/test_devices.py +97 -0
  351. warp/tests/test_examples.py +482 -0
  352. warp/tests/test_fabricarray.py +996 -0
  353. warp/tests/test_fast_math.py +74 -0
  354. warp/tests/test_fem.py +2003 -0
  355. warp/tests/test_fp16.py +136 -0
  356. warp/tests/test_func.py +454 -0
  357. warp/tests/test_future_annotations.py +98 -0
  358. warp/tests/test_generics.py +656 -0
  359. warp/tests/test_grad.py +893 -0
  360. warp/tests/test_grad_customs.py +339 -0
  361. warp/tests/test_grad_debug.py +341 -0
  362. warp/tests/test_implicit_init.py +411 -0
  363. warp/tests/test_import.py +45 -0
  364. warp/tests/test_indexedarray.py +1140 -0
  365. warp/tests/test_intersect.py +73 -0
  366. warp/tests/test_iter.py +76 -0
  367. warp/tests/test_large.py +177 -0
  368. warp/tests/test_launch.py +411 -0
  369. warp/tests/test_lerp.py +151 -0
  370. warp/tests/test_linear_solvers.py +193 -0
  371. warp/tests/test_lvalue.py +427 -0
  372. warp/tests/test_mat.py +2089 -0
  373. warp/tests/test_mat_lite.py +122 -0
  374. warp/tests/test_mat_scalar_ops.py +2913 -0
  375. warp/tests/test_math.py +178 -0
  376. warp/tests/test_mlp.py +282 -0
  377. warp/tests/test_module_hashing.py +258 -0
  378. warp/tests/test_modules_lite.py +44 -0
  379. warp/tests/test_noise.py +252 -0
  380. warp/tests/test_operators.py +299 -0
  381. warp/tests/test_options.py +129 -0
  382. warp/tests/test_overwrite.py +551 -0
  383. warp/tests/test_print.py +339 -0
  384. warp/tests/test_quat.py +2315 -0
  385. warp/tests/test_rand.py +339 -0
  386. warp/tests/test_reload.py +302 -0
  387. warp/tests/test_rounding.py +185 -0
  388. warp/tests/test_runlength_encode.py +196 -0
  389. warp/tests/test_scalar_ops.py +105 -0
  390. warp/tests/test_smoothstep.py +108 -0
  391. warp/tests/test_snippet.py +318 -0
  392. warp/tests/test_sparse.py +582 -0
  393. warp/tests/test_spatial.py +2229 -0
  394. warp/tests/test_special_values.py +361 -0
  395. warp/tests/test_static.py +592 -0
  396. warp/tests/test_struct.py +734 -0
  397. warp/tests/test_tape.py +204 -0
  398. warp/tests/test_transient_module.py +93 -0
  399. warp/tests/test_triangle_closest_point.py +145 -0
  400. warp/tests/test_types.py +562 -0
  401. warp/tests/test_utils.py +588 -0
  402. warp/tests/test_vec.py +1487 -0
  403. warp/tests/test_vec_lite.py +80 -0
  404. warp/tests/test_vec_scalar_ops.py +2327 -0
  405. warp/tests/test_verify_fp.py +100 -0
  406. warp/tests/tile/__init__.py +0 -0
  407. warp/tests/tile/test_tile.py +780 -0
  408. warp/tests/tile/test_tile_load.py +407 -0
  409. warp/tests/tile/test_tile_mathdx.py +208 -0
  410. warp/tests/tile/test_tile_mlp.py +402 -0
  411. warp/tests/tile/test_tile_reduce.py +447 -0
  412. warp/tests/tile/test_tile_shared_memory.py +247 -0
  413. warp/tests/tile/test_tile_view.py +173 -0
  414. warp/tests/unittest_serial.py +47 -0
  415. warp/tests/unittest_suites.py +427 -0
  416. warp/tests/unittest_utils.py +468 -0
  417. warp/tests/walkthrough_debug.py +93 -0
  418. warp/thirdparty/__init__.py +0 -0
  419. warp/thirdparty/appdirs.py +598 -0
  420. warp/thirdparty/dlpack.py +145 -0
  421. warp/thirdparty/unittest_parallel.py +570 -0
  422. warp/torch.py +391 -0
  423. warp/types.py +5230 -0
  424. warp/utils.py +1137 -0
  425. warp_lang-1.7.0.dist-info/METADATA +516 -0
  426. warp_lang-1.7.0.dist-info/RECORD +429 -0
  427. warp_lang-1.7.0.dist-info/WHEEL +5 -0
  428. warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
  429. warp_lang-1.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,996 @@
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 math
17
+ import unittest
18
+ from typing import Any
19
+
20
+ import numpy as np
21
+
22
+ import warp as wp
23
+ from warp.tests.unittest_utils import *
24
+
25
+ # types to test fabric arrays
26
+ _fabric_types = [
27
+ *wp.types.scalar_types,
28
+ *[wp.types.vector(2, T) for T in wp.types.scalar_types],
29
+ *[wp.types.vector(3, T) for T in wp.types.scalar_types],
30
+ *[wp.types.vector(4, T) for T in wp.types.scalar_types],
31
+ *[wp.types.matrix((2, 2), T) for T in wp.types.scalar_types],
32
+ *[wp.types.matrix((3, 3), T) for T in wp.types.scalar_types],
33
+ *[wp.types.matrix((4, 4), T) for T in wp.types.scalar_types],
34
+ *[wp.types.quaternion(T) for T in wp.types.float_types],
35
+ ]
36
+
37
+
38
+ def _warp_type_to_fabric(dtype, is_array=False):
39
+ scalar_map = {
40
+ wp.bool: "b",
41
+ wp.int8: "i1",
42
+ wp.int16: "i2",
43
+ wp.int32: "i4",
44
+ wp.int64: "i8",
45
+ wp.uint8: "u1",
46
+ wp.uint16: "u2",
47
+ wp.uint32: "u4",
48
+ wp.uint64: "u8",
49
+ wp.float16: "f2",
50
+ wp.float32: "f4",
51
+ wp.float64: "f8",
52
+ }
53
+
54
+ if hasattr(dtype, "_wp_scalar_type_"):
55
+ type_str = scalar_map[dtype._wp_scalar_type_]
56
+ if len(dtype._shape_) == 1:
57
+ role = "vector"
58
+ else:
59
+ role = "matrix"
60
+ else:
61
+ type_str = scalar_map[dtype]
62
+ role = ""
63
+
64
+ if is_array:
65
+ array_depth = 1
66
+ else:
67
+ array_depth = 0
68
+
69
+ return (True, type_str, dtype._length_, array_depth, role)
70
+
71
+
72
+ # returns a fabric array interface constructed from a regular array
73
+ def _create_fabric_array_interface(data: wp.array, attrib: str, bucket_sizes: list = None, copy=False):
74
+ assert isinstance(data, wp.array)
75
+ assert data.ndim == 1
76
+
77
+ assert isinstance(attrib, str)
78
+
79
+ if copy:
80
+ data = wp.clone(data)
81
+
82
+ if bucket_sizes is not None:
83
+ assert hasattr(bucket_sizes, "__len__")
84
+
85
+ # verify total size
86
+ total_size = 0
87
+ for bucket_size in bucket_sizes:
88
+ total_size += bucket_size
89
+
90
+ if total_size != data.size:
91
+ raise RuntimeError("Bucket sizes don't add up to the size of data array")
92
+
93
+ elif data.size > 0:
94
+ rng = np.random.default_rng(123)
95
+
96
+ # generate random bucket sizes
97
+ bucket_min = 1
98
+ bucket_max = math.ceil(0.5 * data.size)
99
+ total_size = data.size
100
+ size_remaining = total_size
101
+
102
+ bucket_sizes = []
103
+ while size_remaining >= bucket_max:
104
+ bucket_size = rng.integers(bucket_min, high=bucket_max, dtype=int)
105
+ bucket_sizes.append(bucket_size)
106
+ size_remaining -= bucket_size
107
+
108
+ if size_remaining > 0:
109
+ bucket_sizes.append(size_remaining)
110
+
111
+ else:
112
+ # empty data array
113
+ bucket_sizes = []
114
+
115
+ dtype_size = wp.types.type_size_in_bytes(data.dtype)
116
+ p = int(data.ptr) if data.ptr else 0
117
+ pointers = []
118
+ counts = []
119
+ for bucket_size in bucket_sizes:
120
+ pointers.append(p)
121
+ counts.append(bucket_size)
122
+ p += bucket_size * dtype_size
123
+
124
+ attrib_info = {}
125
+
126
+ attrib_info["type"] = _warp_type_to_fabric(data.dtype)
127
+ attrib_info["access"] = 2 # ReadWrite
128
+ attrib_info["pointers"] = pointers
129
+ attrib_info["counts"] = counts
130
+
131
+ iface = {}
132
+ iface["version"] = 1
133
+ iface["device"] = str(data.device)
134
+ iface["attribs"] = {attrib: attrib_info}
135
+ iface["_ref"] = data # backref to keep the array alive
136
+
137
+ return iface
138
+
139
+
140
+ # returns a fabric array array interface constructed from a list of regular arrays
141
+ def _create_fabric_array_array_interface(data: list, attrib: str, bucket_sizes: list = None):
142
+ # data should be a list of arrays
143
+ assert isinstance(data, list)
144
+
145
+ num_arrays = len(data)
146
+ assert num_arrays > 0
147
+
148
+ device = data[0].device
149
+ dtype = data[0].dtype
150
+
151
+ assert isinstance(attrib, str)
152
+
153
+ if bucket_sizes is not None:
154
+ assert hasattr(bucket_sizes, "__len__")
155
+
156
+ # verify total size
157
+ total_size = 0
158
+ for bucket_size in bucket_sizes:
159
+ total_size += bucket_size
160
+
161
+ if total_size != num_arrays:
162
+ raise RuntimeError("Bucket sizes don't add up to the number of given arrays")
163
+
164
+ else:
165
+ rng = np.random.default_rng(123)
166
+
167
+ # generate random bucket sizes
168
+ bucket_min = 1
169
+ bucket_max = math.ceil(0.5 * num_arrays)
170
+ total_size = num_arrays
171
+ size_remaining = total_size
172
+
173
+ bucket_sizes = []
174
+ while size_remaining >= bucket_max:
175
+ bucket_size = rng.integers(bucket_min, high=bucket_max, dtype=int)
176
+ bucket_sizes.append(bucket_size)
177
+ size_remaining -= bucket_size
178
+
179
+ if size_remaining > 0:
180
+ bucket_sizes.append(size_remaining)
181
+
182
+ # initialize array of pointers to arrays and their lengths
183
+ _array_pointers = []
184
+ _array_lengths = []
185
+ for i in range(num_arrays):
186
+ _array_pointers.append(data[i].ptr)
187
+ _array_lengths.append(data[i].size)
188
+
189
+ array_pointers = wp.array(_array_pointers, dtype=wp.uint64, device=device)
190
+ pointer_size = wp.types.type_size_in_bytes(array_pointers.dtype)
191
+
192
+ lengths = wp.array(_array_lengths, dtype=wp.uint64, device=device)
193
+ length_size = wp.types.type_size_in_bytes(lengths.dtype)
194
+
195
+ p_pointers = int(array_pointers.ptr)
196
+ p_lengths = int(lengths.ptr)
197
+ pointers = []
198
+ counts = []
199
+ array_lengths = []
200
+ for bucket_size in bucket_sizes:
201
+ pointers.append(p_pointers)
202
+ counts.append(bucket_size)
203
+ array_lengths.append(p_lengths)
204
+ p_pointers += bucket_size * pointer_size
205
+ p_lengths += bucket_size * length_size
206
+
207
+ attrib_info = {}
208
+
209
+ attrib_info["type"] = _warp_type_to_fabric(dtype, is_array=True)
210
+ attrib_info["access"] = 2 # ReadWrite
211
+ attrib_info["pointers"] = pointers
212
+ attrib_info["counts"] = counts
213
+ attrib_info["array_lengths"] = array_lengths
214
+
215
+ iface = {}
216
+ iface["version"] = 1
217
+ iface["device"] = str(device)
218
+ iface["attribs"] = {attrib: attrib_info}
219
+ iface["_ref"] = data # backref to keep the data arrays alive
220
+ iface["_ref_pointers"] = array_pointers # backref to keep the array pointers alive
221
+ iface["_ref_lengths"] = lengths # backref to keep the lengths array alive
222
+
223
+ return iface
224
+
225
+
226
+ @wp.kernel
227
+ def fa_kernel(a: wp.fabricarray(dtype=float), expected: wp.array(dtype=float)):
228
+ i = wp.tid()
229
+
230
+ wp.expect_eq(a[i], expected[i])
231
+
232
+ a[i] = 2.0 * a[i]
233
+
234
+ wp.atomic_add(a, i, 1.0)
235
+
236
+ wp.expect_eq(a[i], 2.0 * expected[i] + 1.0)
237
+
238
+
239
+ @wp.kernel
240
+ def fa_kernel_indexed(a: wp.indexedfabricarray(dtype=float), expected: wp.indexedarray(dtype=float)):
241
+ i = wp.tid()
242
+
243
+ wp.expect_eq(a[i], expected[i])
244
+
245
+ a[i] = 2.0 * a[i]
246
+
247
+ wp.atomic_add(a, i, 1.0)
248
+
249
+ wp.expect_eq(a[i], 2.0 * expected[i] + 1.0)
250
+
251
+
252
+ def test_fabricarray_kernel(test, device):
253
+ data = wp.array(data=np.arange(100, dtype=np.float32), device=device)
254
+ iface = _create_fabric_array_interface(data, "foo", copy=True)
255
+ fa = wp.fabricarray(data=iface, attrib="foo")
256
+
257
+ test.assertEqual(fa.dtype, data.dtype)
258
+ test.assertEqual(fa.ndim, 1)
259
+ test.assertEqual(fa.shape, data.shape)
260
+ test.assertEqual(fa.size, data.size)
261
+
262
+ wp.launch(fa_kernel, dim=fa.size, inputs=[fa, data], device=device)
263
+
264
+ # reset data
265
+ wp.copy(fa, data)
266
+
267
+ # test indexed
268
+ indices = wp.array(data=np.arange(1, data.size, 2, dtype=np.int32), device=device)
269
+ ifa = fa[indices]
270
+ idata = data[indices]
271
+
272
+ test.assertEqual(ifa.dtype, idata.dtype)
273
+ test.assertEqual(ifa.ndim, 1)
274
+ test.assertEqual(ifa.shape, idata.shape)
275
+ test.assertEqual(ifa.size, idata.size)
276
+
277
+ wp.launch(fa_kernel_indexed, dim=ifa.size, inputs=[ifa, idata], device=device)
278
+
279
+ wp.synchronize_device(device)
280
+
281
+
282
+ @wp.kernel
283
+ def fa_generic_dtype_kernel(a: wp.fabricarray(dtype=Any), b: wp.fabricarray(dtype=Any)):
284
+ i = wp.tid()
285
+ b[i] = a[i] + a[i]
286
+
287
+
288
+ @wp.kernel
289
+ def fa_generic_dtype_kernel_indexed(a: wp.indexedfabricarray(dtype=Any), b: wp.indexedfabricarray(dtype=Any)):
290
+ i = wp.tid()
291
+ b[i] = a[i] + a[i]
292
+
293
+
294
+ def test_fabricarray_generic_dtype(test, device):
295
+ for T in _fabric_types:
296
+ if hasattr(T, "_wp_scalar_type_"):
297
+ nptype = wp.types.warp_type_to_np_dtype[T._wp_scalar_type_]
298
+ else:
299
+ nptype = wp.types.warp_type_to_np_dtype[T]
300
+
301
+ data = wp.array(data=np.arange(10, dtype=nptype), device=device)
302
+ data_iface = _create_fabric_array_interface(data, "foo", copy=True)
303
+ fa = wp.fabricarray(data=data_iface, attrib="foo")
304
+
305
+ result = wp.zeros_like(data)
306
+ result_iface = _create_fabric_array_interface(result, "foo", copy=True)
307
+ fb = wp.fabricarray(data=result_iface, attrib="foo")
308
+
309
+ test.assertEqual(fa.dtype, fb.dtype)
310
+ test.assertEqual(fa.ndim, fb.ndim)
311
+ test.assertEqual(fa.shape, fb.shape)
312
+ test.assertEqual(fa.size, fb.size)
313
+
314
+ wp.launch(fa_generic_dtype_kernel, dim=fa.size, inputs=[fa, fb], device=device)
315
+
316
+ assert_np_equal(fb.numpy(), 2 * fa.numpy())
317
+
318
+ # reset data
319
+ wp.copy(fa, data)
320
+ wp.copy(fb, result)
321
+
322
+ # test indexed
323
+ indices = wp.array(data=np.arange(1, data.size, 2, dtype=np.int32), device=device)
324
+ ifa = fa[indices]
325
+ ifb = fb[indices]
326
+
327
+ test.assertEqual(ifa.dtype, ifb.dtype)
328
+ test.assertEqual(ifa.ndim, ifb.ndim)
329
+ test.assertEqual(ifa.shape, ifb.shape)
330
+ test.assertEqual(ifa.size, ifb.size)
331
+
332
+ wp.launch(fa_generic_dtype_kernel_indexed, dim=ifa.size, inputs=[ifa, ifb], device=device)
333
+
334
+ assert_np_equal(ifb.numpy(), 2 * ifa.numpy())
335
+
336
+
337
+ @wp.kernel
338
+ def fa_generic_array_kernel(a: Any, b: Any):
339
+ i = wp.tid()
340
+ b[i] = a[i] + a[i]
341
+
342
+
343
+ def test_fabricarray_generic_array(test, device):
344
+ for T in _fabric_types:
345
+ if hasattr(T, "_wp_scalar_type_"):
346
+ nptype = wp.types.warp_type_to_np_dtype[T._wp_scalar_type_]
347
+ else:
348
+ nptype = wp.types.warp_type_to_np_dtype[T]
349
+
350
+ data = wp.array(data=np.arange(100, dtype=nptype), device=device)
351
+ data_iface = _create_fabric_array_interface(data, "foo", copy=True)
352
+ fa = wp.fabricarray(data=data_iface, attrib="foo")
353
+
354
+ result = wp.zeros_like(data)
355
+ result_iface = _create_fabric_array_interface(result, "foo", copy=True)
356
+ fb = wp.fabricarray(data=result_iface, attrib="foo")
357
+
358
+ test.assertEqual(fa.dtype, fb.dtype)
359
+ test.assertEqual(fa.ndim, fb.ndim)
360
+ test.assertEqual(fa.shape, fb.shape)
361
+ test.assertEqual(fa.size, fb.size)
362
+
363
+ wp.launch(fa_generic_array_kernel, dim=fa.size, inputs=[fa, fb], device=device)
364
+
365
+ assert_np_equal(fb.numpy(), 2 * fa.numpy())
366
+
367
+ # reset data
368
+ wp.copy(fa, data)
369
+ wp.copy(fb, result)
370
+
371
+ # test indexed
372
+ indices = wp.array(data=np.arange(1, data.size, 2, dtype=np.int32), device=device)
373
+ ifa = fa[indices]
374
+ ifb = fb[indices]
375
+
376
+ test.assertEqual(ifa.dtype, ifb.dtype)
377
+ test.assertEqual(ifa.ndim, ifb.ndim)
378
+ test.assertEqual(ifa.shape, ifb.shape)
379
+ test.assertEqual(ifa.size, ifb.size)
380
+
381
+ wp.launch(fa_generic_array_kernel, dim=ifa.size, inputs=[ifa, ifb], device=device)
382
+
383
+ assert_np_equal(ifb.numpy(), 2 * ifa.numpy())
384
+
385
+
386
+ def test_fabricarray_empty(test, device):
387
+ # Test whether common operations work with empty (zero-sized) indexed arrays
388
+ # without throwing exceptions.
389
+
390
+ def test_empty_ops(nrows, ncols, wptype, nptype):
391
+ # scalar, vector, or matrix
392
+ if ncols > 0:
393
+ if nrows > 0:
394
+ wptype = wp.types.matrix((nrows, ncols), wptype)
395
+ else:
396
+ wptype = wp.types.vector(ncols, wptype)
397
+ dtype_shape = wptype._shape_
398
+ else:
399
+ dtype_shape = ()
400
+
401
+ fill_value = wptype(42)
402
+
403
+ # create an empty data array
404
+ data = wp.empty(0, dtype=wptype, device=device)
405
+ iface = _create_fabric_array_interface(data, "foo", copy=True)
406
+ fa = wp.fabricarray(data=iface, attrib="foo")
407
+
408
+ test.assertEqual(fa.size, 0)
409
+ test.assertEqual(fa.shape, (0,))
410
+
411
+ # all of these methods should succeed with zero-sized arrays
412
+ fa.zero_()
413
+ fa.fill_(fill_value)
414
+ fb = fa.contiguous()
415
+
416
+ fb = wp.empty_like(fa)
417
+ fb = wp.zeros_like(fa)
418
+ fb = wp.full_like(fa, fill_value)
419
+ fb = wp.clone(fa)
420
+
421
+ wp.copy(fa, fb)
422
+ fa.assign(fb)
423
+
424
+ na = fa.numpy()
425
+ test.assertEqual(na.size, 0)
426
+ test.assertEqual(na.shape, (0, *dtype_shape))
427
+ test.assertEqual(na.dtype, nptype)
428
+
429
+ test.assertEqual(fa.list(), [])
430
+
431
+ # test indexed
432
+
433
+ # create a zero-sized array of indices
434
+ indices = wp.empty(0, dtype=int, device=device)
435
+
436
+ ifa = fa[indices]
437
+
438
+ test.assertEqual(ifa.size, 0)
439
+ test.assertEqual(ifa.shape, (0,))
440
+
441
+ # all of these methods should succeed with zero-sized arrays
442
+ ifa.zero_()
443
+ ifa.fill_(fill_value)
444
+ ifb = ifa.contiguous()
445
+
446
+ ifb = wp.empty_like(ifa)
447
+ ifb = wp.zeros_like(ifa)
448
+ ifb = wp.full_like(ifa, fill_value)
449
+ ifb = wp.clone(ifa)
450
+
451
+ wp.copy(ifa, ifb)
452
+ ifa.assign(ifb)
453
+
454
+ na = ifa.numpy()
455
+ test.assertEqual(na.size, 0)
456
+ test.assertEqual(na.shape, (0, *dtype_shape))
457
+ test.assertEqual(na.dtype, nptype)
458
+
459
+ test.assertEqual(ifa.list(), [])
460
+
461
+ # test with scalars, vectors, and matrices
462
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
463
+ # scalars
464
+ test_empty_ops(0, 0, wptype, nptype)
465
+
466
+ for ncols in [2, 3, 4, 5]:
467
+ # vectors
468
+ test_empty_ops(0, ncols, wptype, nptype)
469
+ # square matrices (the Fabric interface only supports square matrices right now)
470
+ test_empty_ops(ncols, ncols, wptype, nptype)
471
+
472
+
473
+ def test_fabricarray_fill_scalar(test, device):
474
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
475
+ # create a data array
476
+ data = wp.zeros(100, dtype=wptype, device=device)
477
+ iface = _create_fabric_array_interface(data, "foo", copy=True)
478
+ fa = wp.fabricarray(data=iface, attrib="foo")
479
+
480
+ assert_np_equal(fa.numpy(), np.zeros(fa.shape, dtype=nptype))
481
+
482
+ # fill with int value
483
+ fill_value = 42
484
+ fa.fill_(fill_value)
485
+ assert_np_equal(fa.numpy(), np.full(fa.shape, fill_value, dtype=nptype))
486
+
487
+ fa.zero_()
488
+ assert_np_equal(fa.numpy(), np.zeros(fa.shape, dtype=nptype))
489
+
490
+ if wptype in wp.types.float_types:
491
+ # fill with float value
492
+ fill_value = 13.37
493
+ fa.fill_(fill_value)
494
+ assert_np_equal(fa.numpy(), np.full(fa.shape, fill_value, dtype=nptype))
495
+
496
+ # fill with Warp scalar value
497
+ fill_value = wptype(17)
498
+ fa.fill_(fill_value)
499
+ assert_np_equal(fa.numpy(), np.full(fa.shape, fill_value.value, dtype=nptype))
500
+
501
+ # reset data
502
+ wp.copy(fa, data)
503
+
504
+ # test indexed
505
+ indices1 = wp.array(data=np.arange(1, data.size, 2, dtype=np.int32), device=device)
506
+ ifa = fa[indices1]
507
+
508
+ # ensure that the other indices remain unchanged
509
+ indices2 = wp.array(data=np.arange(0, data.size, 2, dtype=np.int32), device=device)
510
+ ifb = fa[indices2]
511
+
512
+ assert_np_equal(ifa.numpy(), np.zeros(ifa.shape, dtype=nptype))
513
+ assert_np_equal(ifb.numpy(), np.zeros(ifb.shape, dtype=nptype))
514
+
515
+ # fill with int value
516
+ fill_value = 42
517
+ ifa.fill_(fill_value)
518
+ assert_np_equal(ifa.numpy(), np.full(ifa.shape, fill_value, dtype=nptype))
519
+ assert_np_equal(ifb.numpy(), np.zeros(ifb.shape, dtype=nptype))
520
+
521
+ ifa.zero_()
522
+ assert_np_equal(ifa.numpy(), np.zeros(ifa.shape, dtype=nptype))
523
+ assert_np_equal(ifb.numpy(), np.zeros(ifb.shape, dtype=nptype))
524
+
525
+ if wptype in wp.types.float_types:
526
+ # fill with float value
527
+ fill_value = 13.37
528
+ ifa.fill_(fill_value)
529
+ assert_np_equal(ifa.numpy(), np.full(ifa.shape, fill_value, dtype=nptype))
530
+ assert_np_equal(ifb.numpy(), np.zeros(ifb.shape, dtype=nptype))
531
+
532
+ # fill with Warp scalar value
533
+ fill_value = wptype(17)
534
+ ifa.fill_(fill_value)
535
+ assert_np_equal(ifa.numpy(), np.full(ifa.shape, fill_value.value, dtype=nptype))
536
+ assert_np_equal(ifb.numpy(), np.zeros(ifb.shape, dtype=nptype))
537
+
538
+
539
+ def test_fabricarray_fill_vector(test, device):
540
+ # test filling a vector array with scalar or vector values (vec_type, list, or numpy array)
541
+
542
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
543
+ # vector types
544
+ vector_types = [
545
+ wp.types.vector(2, wptype),
546
+ wp.types.vector(3, wptype),
547
+ wp.types.vector(4, wptype),
548
+ wp.types.vector(5, wptype),
549
+ ]
550
+
551
+ for vec_type in vector_types:
552
+ vec_len = vec_type._length_
553
+
554
+ data = wp.zeros(100, dtype=vec_type, device=device)
555
+ iface = _create_fabric_array_interface(data, "foo", copy=True)
556
+ fa = wp.fabricarray(data=iface, attrib="foo")
557
+
558
+ assert_np_equal(fa.numpy(), np.zeros((*fa.shape, vec_len), dtype=nptype))
559
+
560
+ # fill with int scalar
561
+ fill_value = 42
562
+ fa.fill_(fill_value)
563
+ assert_np_equal(fa.numpy(), np.full((*fa.shape, vec_len), fill_value, dtype=nptype))
564
+
565
+ # test zeroing
566
+ fa.zero_()
567
+ assert_np_equal(fa.numpy(), np.zeros((*fa.shape, vec_len), dtype=nptype))
568
+
569
+ # vector values can be passed as a list, numpy array, or Warp vector instance
570
+ fill_list = [17, 42, 99, 101, 127][:vec_len]
571
+ fill_arr = np.array(fill_list, dtype=nptype)
572
+ fill_vec = vec_type(fill_list)
573
+
574
+ expected = np.tile(fill_arr, fa.size).reshape((*fa.shape, vec_len))
575
+
576
+ # fill with list of vector length
577
+ fa.fill_(fill_list)
578
+ assert_np_equal(fa.numpy(), expected)
579
+
580
+ # clear
581
+ fa.zero_()
582
+
583
+ # fill with numpy array of vector length
584
+ fa.fill_(fill_arr)
585
+ assert_np_equal(fa.numpy(), expected)
586
+
587
+ # clear
588
+ fa.zero_()
589
+
590
+ # fill with vec instance
591
+ fa.fill_(fill_vec)
592
+ assert_np_equal(fa.numpy(), expected)
593
+
594
+ if wptype in wp.types.float_types:
595
+ # fill with float scalar
596
+ fill_value = 13.37
597
+ fa.fill_(fill_value)
598
+ assert_np_equal(fa.numpy(), np.full((*fa.shape, vec_len), fill_value, dtype=nptype))
599
+
600
+ # fill with float list of vector length
601
+ fill_list = [-2.5, -1.25, 1.25, 2.5, 5.0][:vec_len]
602
+
603
+ fa.fill_(fill_list)
604
+
605
+ expected = np.tile(np.array(fill_list, dtype=nptype), fa.size).reshape((*fa.shape, vec_len))
606
+
607
+ assert_np_equal(fa.numpy(), expected)
608
+
609
+ # reset data
610
+ wp.copy(fa, data)
611
+
612
+ # test indexed
613
+ indices1 = wp.array(data=np.arange(1, data.size, 2, dtype=np.int32), device=device)
614
+ ifa = fa[indices1]
615
+
616
+ # ensure that the other indices remain unchanged
617
+ indices2 = wp.array(data=np.arange(0, data.size, 2, dtype=np.int32), device=device)
618
+ ifb = fa[indices2]
619
+
620
+ assert_np_equal(ifa.numpy(), np.zeros((*ifa.shape, vec_len), dtype=nptype))
621
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
622
+
623
+ # fill with int scalar
624
+ fill_value = 42
625
+ ifa.fill_(fill_value)
626
+ assert_np_equal(ifa.numpy(), np.full((*ifa.shape, vec_len), fill_value, dtype=nptype))
627
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
628
+
629
+ # test zeroing
630
+ ifa.zero_()
631
+ assert_np_equal(ifa.numpy(), np.zeros((*ifa.shape, vec_len), dtype=nptype))
632
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
633
+
634
+ # vector values can be passed as a list, numpy array, or Warp vector instance
635
+ fill_list = [17, 42, 99, 101, 127][:vec_len]
636
+ fill_arr = np.array(fill_list, dtype=nptype)
637
+ fill_vec = vec_type(fill_list)
638
+
639
+ expected = np.tile(fill_arr, ifa.size).reshape((*ifa.shape, vec_len))
640
+
641
+ # fill with list of vector length
642
+ ifa.fill_(fill_list)
643
+ assert_np_equal(ifa.numpy(), expected)
644
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
645
+
646
+ # clear
647
+ ifa.zero_()
648
+
649
+ # fill with numpy array of vector length
650
+ ifa.fill_(fill_arr)
651
+ assert_np_equal(ifa.numpy(), expected)
652
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
653
+
654
+ # clear
655
+ ifa.zero_()
656
+
657
+ # fill with vec instance
658
+ ifa.fill_(fill_vec)
659
+ assert_np_equal(ifa.numpy(), expected)
660
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
661
+
662
+ if wptype in wp.types.float_types:
663
+ # fill with float scalar
664
+ fill_value = 13.37
665
+ ifa.fill_(fill_value)
666
+ assert_np_equal(ifa.numpy(), np.full((*ifa.shape, vec_len), fill_value, dtype=nptype))
667
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
668
+
669
+ # fill with float list of vector length
670
+ fill_list = [-2.5, -1.25, 1.25, 2.5, 5.0][:vec_len]
671
+
672
+ ifa.fill_(fill_list)
673
+
674
+ expected = np.tile(np.array(fill_list, dtype=nptype), ifa.size).reshape((*ifa.shape, vec_len))
675
+
676
+ assert_np_equal(ifa.numpy(), expected)
677
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, vec_len), dtype=nptype))
678
+
679
+
680
+ def test_fabricarray_fill_matrix(test, device):
681
+ # test filling a matrix array with scalar or matrix values (mat_type, nested list, or 2d numpy array)
682
+
683
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
684
+ # matrix types
685
+ matrix_types = [
686
+ # square matrices only
687
+ wp.types.matrix((2, 2), wptype),
688
+ wp.types.matrix((3, 3), wptype),
689
+ wp.types.matrix((4, 4), wptype),
690
+ wp.types.matrix((5, 5), wptype),
691
+ ]
692
+
693
+ for mat_type in matrix_types:
694
+ mat_len = mat_type._length_
695
+ mat_shape = mat_type._shape_
696
+
697
+ data = wp.zeros(100, dtype=mat_type, device=device)
698
+ iface = _create_fabric_array_interface(data, "foo", copy=True)
699
+ fa = wp.fabricarray(data=iface, attrib="foo")
700
+
701
+ assert_np_equal(fa.numpy(), np.zeros((*fa.shape, *mat_shape), dtype=nptype))
702
+
703
+ # fill with scalar
704
+ fill_value = 42
705
+ fa.fill_(fill_value)
706
+ assert_np_equal(fa.numpy(), np.full((*fa.shape, *mat_shape), fill_value, dtype=nptype))
707
+
708
+ # test zeroing
709
+ fa.zero_()
710
+ assert_np_equal(fa.numpy(), np.zeros((*fa.shape, *mat_shape), dtype=nptype))
711
+
712
+ # matrix values can be passed as a 1d numpy array, 2d numpy array, flat list, nested list, or Warp matrix instance
713
+ if wptype != wp.bool:
714
+ fill_arr1 = np.arange(mat_len, dtype=nptype)
715
+ else:
716
+ fill_arr1 = np.ones(mat_len, dtype=nptype)
717
+
718
+ fill_arr2 = fill_arr1.reshape(mat_shape)
719
+ fill_list1 = list(fill_arr1)
720
+ fill_list2 = [list(row) for row in fill_arr2]
721
+ fill_mat = mat_type(fill_arr1)
722
+
723
+ expected = np.tile(fill_arr1, fa.size).reshape((*fa.shape, *mat_shape))
724
+
725
+ # fill with 1d numpy array
726
+ fa.fill_(fill_arr1)
727
+ assert_np_equal(fa.numpy(), expected)
728
+
729
+ # clear
730
+ fa.zero_()
731
+
732
+ # fill with 2d numpy array
733
+ fa.fill_(fill_arr2)
734
+ assert_np_equal(fa.numpy(), expected)
735
+
736
+ # clear
737
+ fa.zero_()
738
+
739
+ # fill with flat list
740
+ fa.fill_(fill_list1)
741
+ assert_np_equal(fa.numpy(), expected)
742
+
743
+ # clear
744
+ fa.zero_()
745
+
746
+ # fill with nested list
747
+ fa.fill_(fill_list2)
748
+ assert_np_equal(fa.numpy(), expected)
749
+
750
+ # clear
751
+ fa.zero_()
752
+
753
+ # fill with mat instance
754
+ fa.fill_(fill_mat)
755
+ assert_np_equal(fa.numpy(), expected)
756
+
757
+ # reset data
758
+ wp.copy(fa, data)
759
+
760
+ # test indexed
761
+ indices1 = wp.array(data=np.arange(1, data.size, 2, dtype=np.int32), device=device)
762
+ ifa = fa[indices1]
763
+
764
+ # ensure that the other indices remain unchanged
765
+ indices2 = wp.array(data=np.arange(0, data.size, 2, dtype=np.int32), device=device)
766
+ ifb = fa[indices2]
767
+
768
+ assert_np_equal(ifa.numpy(), np.zeros((*ifa.shape, *mat_shape), dtype=nptype))
769
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
770
+
771
+ # fill with scalar
772
+ fill_value = 42
773
+ ifa.fill_(fill_value)
774
+ assert_np_equal(ifa.numpy(), np.full((*ifa.shape, *mat_shape), fill_value, dtype=nptype))
775
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
776
+
777
+ # test zeroing
778
+ ifa.zero_()
779
+ assert_np_equal(ifa.numpy(), np.zeros((*ifa.shape, *mat_shape), dtype=nptype))
780
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
781
+
782
+ # matrix values can be passed as a 1d numpy array, 2d numpy array, flat list, nested list, or Warp matrix instance
783
+ if wptype != wp.bool:
784
+ fill_arr1 = np.arange(mat_len, dtype=nptype)
785
+ else:
786
+ fill_arr1 = np.ones(mat_len, dtype=nptype)
787
+ fill_arr2 = fill_arr1.reshape(mat_shape)
788
+ fill_list1 = list(fill_arr1)
789
+ fill_list2 = [list(row) for row in fill_arr2]
790
+ fill_mat = mat_type(fill_arr1)
791
+
792
+ expected = np.tile(fill_arr1, ifa.size).reshape((*ifa.shape, *mat_shape))
793
+
794
+ # fill with 1d numpy array
795
+ ifa.fill_(fill_arr1)
796
+ assert_np_equal(ifa.numpy(), expected)
797
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
798
+
799
+ # clear
800
+ ifa.zero_()
801
+
802
+ # fill with 2d numpy array
803
+ ifa.fill_(fill_arr2)
804
+ assert_np_equal(ifa.numpy(), expected)
805
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
806
+
807
+ # clear
808
+ ifa.zero_()
809
+
810
+ # fill with flat list
811
+ ifa.fill_(fill_list1)
812
+ assert_np_equal(ifa.numpy(), expected)
813
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
814
+
815
+ # clear
816
+ ifa.zero_()
817
+
818
+ # fill with nested list
819
+ ifa.fill_(fill_list2)
820
+ assert_np_equal(ifa.numpy(), expected)
821
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
822
+
823
+ # clear
824
+ ifa.zero_()
825
+
826
+ # fill with mat instance
827
+ ifa.fill_(fill_mat)
828
+ assert_np_equal(ifa.numpy(), expected)
829
+ assert_np_equal(ifb.numpy(), np.zeros((*ifb.shape, *mat_shape), dtype=nptype))
830
+
831
+
832
+ @wp.kernel
833
+ def fa_kernel_indexing_types(
834
+ a: wp.fabricarray(dtype=wp.int32),
835
+ ):
836
+ x = a[wp.uint8(0)]
837
+ y = a[wp.int16(1)]
838
+ z = a[wp.uint32(2)]
839
+ w = a[wp.int64(3)]
840
+
841
+ a[wp.uint8(0)] = 123
842
+ a[wp.int16(1)] = 123
843
+ a[wp.uint32(2)] = 123
844
+ a[wp.int64(3)] = 123
845
+
846
+ wp.atomic_add(a, wp.uint8(0), 123)
847
+ wp.atomic_sub(a, wp.int16(1), 123)
848
+ # wp.atomic_min(a, wp.uint32(2), 123)
849
+ # wp.atomic_max(a, wp.int64(3), 123)
850
+
851
+
852
+ def test_fabricarray_indexing_types(test, device):
853
+ data = wp.zeros(shape=(4,), dtype=wp.int32, device=device)
854
+ iface = _create_fabric_array_interface(data, "foo", copy=True)
855
+ fa = wp.fabricarray(data=iface, attrib="foo")
856
+ wp.launch(
857
+ kernel=fa_kernel_indexing_types,
858
+ dim=1,
859
+ inputs=(fa,),
860
+ device=device,
861
+ )
862
+
863
+
864
+ @wp.kernel
865
+ def fa_generic_sums_kernel(a: wp.fabricarrayarray(dtype=Any), sums: wp.array(dtype=Any)):
866
+ i = wp.tid()
867
+
868
+ # get sub-array using wp::view()
869
+ row = a[i]
870
+
871
+ # get sub-array length
872
+ count = row.shape[0]
873
+
874
+ # compute sub-array sum
875
+ for j in range(count):
876
+ sums[i] = sums[i] + row[j]
877
+
878
+
879
+ @wp.kernel
880
+ def fa_generic_sums_kernel_indexed(a: wp.indexedfabricarrayarray(dtype=Any), sums: wp.array(dtype=Any)):
881
+ i = wp.tid()
882
+
883
+ # get sub-array using wp::view()
884
+ row = a[i]
885
+
886
+ # get sub-array length
887
+ count = row.shape[0]
888
+
889
+ # compute sub-array sum
890
+ for j in range(count):
891
+ sums[i] = sums[i] + row[j]
892
+
893
+
894
+ def test_fabricarrayarray(test, device):
895
+ for T in _fabric_types:
896
+ if hasattr(T, "_wp_scalar_type_"):
897
+ nptype = wp.types.warp_type_to_np_dtype[T._wp_scalar_type_]
898
+ else:
899
+ nptype = wp.types.warp_type_to_np_dtype[T]
900
+
901
+ n = 100
902
+
903
+ min_length = 1
904
+ max_length = 10
905
+ arrays = []
906
+ expected_sums = []
907
+ expected_sums_indexed = []
908
+
909
+ # generate data arrays
910
+ length = min_length
911
+ for i in range(n):
912
+ if length > max_length:
913
+ length = min_length
914
+
915
+ na = np.arange(1, length + 1, dtype=nptype)
916
+
917
+ arrays.append(wp.array(data=na, device=device))
918
+ expected_sums.append(na.sum())
919
+
920
+ # every second index
921
+ if i % 2 == 0:
922
+ expected_sums_indexed.append(na.sum())
923
+
924
+ length += 1
925
+
926
+ data_iface = _create_fabric_array_array_interface(arrays, "foo")
927
+ fa = wp.fabricarrayarray(data=data_iface, attrib="foo")
928
+
929
+ sums = wp.zeros_like(fa)
930
+
931
+ test.assertEqual(fa.dtype, sums.dtype)
932
+ test.assertEqual(fa.ndim, 2)
933
+ test.assertEqual(sums.ndim, 1)
934
+ test.assertEqual(fa.shape, sums.shape)
935
+ test.assertEqual(fa.size, sums.size)
936
+
937
+ wp.launch(fa_generic_sums_kernel, dim=fa.size, inputs=[fa, sums], device=device)
938
+
939
+ assert_np_equal(sums.numpy(), np.array(expected_sums, dtype=nptype))
940
+
941
+ # test indexed
942
+ indices = wp.array(data=np.arange(0, n, 2, dtype=np.int32), device=device)
943
+ ifa = fa[indices]
944
+
945
+ sums = wp.zeros_like(ifa)
946
+
947
+ test.assertEqual(ifa.dtype, sums.dtype)
948
+ test.assertEqual(ifa.ndim, 2)
949
+ test.assertEqual(sums.ndim, 1)
950
+ test.assertEqual(ifa.shape, sums.shape)
951
+ test.assertEqual(ifa.size, sums.size)
952
+
953
+ wp.launch(fa_generic_sums_kernel_indexed, dim=ifa.size, inputs=[ifa, sums], device=device)
954
+
955
+ assert_np_equal(sums.numpy(), np.array(expected_sums_indexed, dtype=nptype))
956
+
957
+
958
+ # explicit kernel overloads
959
+ for T in _fabric_types:
960
+ wp.overload(fa_generic_dtype_kernel, [wp.fabricarray(dtype=T), wp.fabricarray(dtype=T)])
961
+ wp.overload(fa_generic_dtype_kernel_indexed, [wp.indexedfabricarray(dtype=T), wp.indexedfabricarray(dtype=T)])
962
+
963
+ wp.overload(fa_generic_array_kernel, [wp.fabricarray(dtype=T), wp.fabricarray(dtype=T)])
964
+ wp.overload(fa_generic_array_kernel, [wp.indexedfabricarray(dtype=T), wp.indexedfabricarray(dtype=T)])
965
+
966
+ wp.overload(fa_generic_sums_kernel, [wp.fabricarrayarray(dtype=T), wp.array(dtype=T)])
967
+ wp.overload(fa_generic_sums_kernel_indexed, [wp.indexedfabricarrayarray(dtype=T), wp.array(dtype=T)])
968
+
969
+
970
+ devices = get_test_devices()
971
+
972
+
973
+ class TestFabricArray(unittest.TestCase):
974
+ def test_fabricarray_new_del(self):
975
+ # test the scenario in which a fabricarray is created but not initialized before gc
976
+ instance = wp.fabricarray.__new__(wp.fabricarray)
977
+ instance.__del__()
978
+
979
+
980
+ # fabric arrays
981
+ add_function_test(TestFabricArray, "test_fabricarray_kernel", test_fabricarray_kernel, devices=devices)
982
+ add_function_test(TestFabricArray, "test_fabricarray_empty", test_fabricarray_empty, devices=devices)
983
+ add_function_test(TestFabricArray, "test_fabricarray_generic_dtype", test_fabricarray_generic_dtype, devices=devices)
984
+ add_function_test(TestFabricArray, "test_fabricarray_generic_array", test_fabricarray_generic_array, devices=devices)
985
+ add_function_test(TestFabricArray, "test_fabricarray_fill_scalar", test_fabricarray_fill_scalar, devices=devices)
986
+ add_function_test(TestFabricArray, "test_fabricarray_fill_vector", test_fabricarray_fill_vector, devices=devices)
987
+ add_function_test(TestFabricArray, "test_fabricarray_fill_matrix", test_fabricarray_fill_matrix, devices=devices)
988
+ add_function_test(TestFabricArray, "test_fabricarray_indexing_types", test_fabricarray_indexing_types, devices=devices)
989
+
990
+ # fabric arrays of arrays
991
+ add_function_test(TestFabricArray, "test_fabricarrayarray", test_fabricarrayarray, devices=devices)
992
+
993
+
994
+ if __name__ == "__main__":
995
+ wp.clear_kernel_cache()
996
+ unittest.main(verbosity=2)