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,39 @@
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
+ """Serial code-coverage runner
17
+
18
+ This script is used to generate code-coverage reports by running Warp tests.
19
+ It runs in serial so can take over an hour to finish. To generate a coverage
20
+ report in parallel, use the warp/thirdparty./unittest_parallel.py script
21
+ instead with the --coverage option, e.g. python -m warp.tests --coverage
22
+ """
23
+
24
+ import coverage
25
+
26
+ cover = coverage.Coverage(config_file=True, messages=True)
27
+
28
+ cover.start()
29
+
30
+ with cover.collect():
31
+ import unittest_serial # noqa: E402
32
+
33
+ unittest_serial.run_specified()
34
+
35
+ cover.save()
36
+
37
+ cover.report()
38
+
39
+ cover.html_report(title="Warp Testing Code Coverage Report")
File without changes
@@ -0,0 +1,244 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import math
17
+ import unittest
18
+
19
+ import warp as wp
20
+ import warp.examples
21
+ import warp.sim
22
+ from warp.tests.unittest_utils import *
23
+
24
+
25
+ def build_ant(num_envs):
26
+ builder = wp.sim.ModelBuilder()
27
+ for i in range(num_envs):
28
+ wp.sim.parse_mjcf(os.path.join(warp.examples.get_asset_directory(), "nv_ant.xml"), builder, up_axis="y")
29
+
30
+ coord_count = 15
31
+ dof_count = 14
32
+
33
+ coord_start = i * coord_count
34
+ dof_start = i * dof_count
35
+
36
+ # base
37
+ p = [i * 2.0, 0.70, 0.0]
38
+ q = wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), -math.pi * 0.5)
39
+ builder.joint_q[coord_start : coord_start + 3] = p
40
+ builder.joint_q[coord_start + 3 : coord_start + 7] = q
41
+
42
+ # joints
43
+ builder.joint_q[coord_start + 7 : coord_start + coord_count] = [0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0]
44
+ builder.joint_qd[dof_start + 6 : dof_start + dof_count] = [1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0]
45
+
46
+ return builder
47
+
48
+
49
+ def build_complex_joint_mechanism(chain_length):
50
+ builder = wp.sim.ModelBuilder()
51
+ com0 = wp.vec3(1.0, 2.0, 3.0)
52
+ com1 = wp.vec3(4.0, 5.0, 6.0)
53
+ com2 = wp.vec3(7.0, 8.0, 9.0)
54
+ ax0 = wp.normalize(wp.vec3(-1.0, 2.0, 3.0))
55
+ ax1 = wp.normalize(wp.vec3(4.0, -1.0, 2.0))
56
+ ax2 = wp.normalize(wp.vec3(-3.0, 4.0, -1.0))
57
+ # declare some transforms with nonzero translation and orientation
58
+ tf0 = wp.transform(wp.vec3(1.0, 2.0, 3.0), wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), math.pi * 0.25))
59
+ tf1 = wp.transform(wp.vec3(4.0, 5.0, 6.0), wp.quat_from_axis_angle(wp.vec3(0.0, 1.0, 0.0), math.pi * 0.5))
60
+ tf2 = wp.transform(wp.vec3(7.0, 8.0, 9.0), wp.quat_from_axis_angle(wp.vec3(0.0, 0.0, 1.0), math.pi * 0.75))
61
+
62
+ parent = -1
63
+ for _i in range(chain_length):
64
+ b0 = builder.add_body(com=com0)
65
+ builder.add_joint_fixed(parent=parent, child=b0, parent_xform=tf1, child_xform=tf0)
66
+ assert builder.articulation_count == 1
67
+
68
+ b1 = builder.add_body(com=com1)
69
+ builder.add_joint_revolute(parent=b0, child=b1, parent_xform=tf1, child_xform=tf2, axis=ax1)
70
+ builder.joint_q[-1] = 0.3
71
+ builder.joint_qd[-1] = 1.0
72
+
73
+ b2 = builder.add_body(com=com2)
74
+ builder.add_joint_universal(parent=b1, child=b2, parent_xform=tf2, child_xform=tf0, axis_0=ax0, axis_1=ax1)
75
+ builder.joint_q[-2:] = [0.3, 0.5]
76
+ builder.joint_qd[-2:] = [1.0, -1.0]
77
+
78
+ b3 = builder.add_body(com=com0)
79
+ builder.add_joint_ball(parent=b2, child=b3, parent_xform=tf0, child_xform=tf1)
80
+ builder.joint_q[-4:] = list(wp.quat_from_axis_angle(ax0, 0.7))
81
+ builder.joint_qd[-3:] = [1.0, -0.6, 1.5]
82
+
83
+ b4 = builder.add_body(com=com1)
84
+ builder.add_joint_compound(
85
+ parent=b3,
86
+ child=b4,
87
+ parent_xform=tf2,
88
+ child_xform=tf1,
89
+ axis_0=(0, 0, 1),
90
+ axis_1=(1, 0, 0),
91
+ axis_2=(0, 1, 0),
92
+ )
93
+ builder.joint_q[-3:] = [0.3, 0.5, 0.27]
94
+ builder.joint_qd[-3:] = [1.23, -1.0, 0.5]
95
+
96
+ b5 = builder.add_body(com=com2)
97
+ builder.add_joint_prismatic(
98
+ parent=b4,
99
+ child=b5,
100
+ parent_xform=tf2,
101
+ child_xform=tf0,
102
+ axis=ax0,
103
+ )
104
+ builder.joint_q[-1] = 0.92
105
+ builder.joint_qd[-1] = -0.63
106
+
107
+ b6 = builder.add_body(com=com0)
108
+ builder.add_joint_d6(
109
+ parent=b5,
110
+ child=b6,
111
+ parent_xform=tf0,
112
+ child_xform=tf2,
113
+ linear_axes=[ax0, ax1, wp.cross(ax0, ax1)],
114
+ angular_axes=[ax1, ax2, wp.cross(ax1, ax2)],
115
+ )
116
+ builder.joint_q[-6:] = [0.3, 0.5, 0.7, 0.9, 1.1, 1.3]
117
+ builder.joint_qd[-6:] = [1.0, -1.0, 0.5, 0.8, -0.3, 0.1]
118
+
119
+ b7 = builder.add_body(com=com1)
120
+ builder.add_joint_free(
121
+ parent=b6,
122
+ child=b7,
123
+ parent_xform=tf1,
124
+ child_xform=tf2,
125
+ )
126
+ builder.joint_q[-7:] = [0.5, -0.9, 1.4] + list(wp.quat_rpy(0.3, -0.5, 0.7))
127
+ builder.joint_qd[-6:] = [1.0, -1.0, 0.5, 0.8, -0.3, 0.1]
128
+
129
+ b8 = builder.add_body(com=com2)
130
+ builder.add_joint_distance(
131
+ parent=b7,
132
+ child=b8,
133
+ parent_xform=tf1,
134
+ child_xform=tf2,
135
+ )
136
+ builder.joint_q[-7:] = [-0.3, -0.7, 0.2] + list(wp.quat_rpy(0.1, 0.1, 0.4))
137
+ builder.joint_qd[-6:] = [-0.34, 0.5, -0.6, -0.4, 0.2, 0.1]
138
+
139
+ # D6 joint that behaves like a fixed joint
140
+ b9 = builder.add_body(com=com0)
141
+ builder.add_joint_d6(
142
+ parent=b8,
143
+ child=b9,
144
+ parent_xform=tf0,
145
+ child_xform=tf2,
146
+ linear_axes=[],
147
+ angular_axes=[],
148
+ )
149
+
150
+ b10 = builder.add_body(com=com0)
151
+ builder.add_joint_d6(
152
+ parent=b9,
153
+ child=b10,
154
+ parent_xform=tf1,
155
+ child_xform=tf2,
156
+ linear_axes=[ax1],
157
+ angular_axes=[ax2, ax0],
158
+ )
159
+ builder.joint_q[-3:] = [0.3, 0.5, 0.7]
160
+ builder.joint_qd[-3:] = [1.0, -1.0, 0.5]
161
+
162
+ b11 = builder.add_body(com=com1)
163
+ builder.add_joint_d6(
164
+ parent=b10,
165
+ child=b11,
166
+ parent_xform=tf1,
167
+ child_xform=tf2,
168
+ linear_axes=[ax1, ax0, wp.cross(ax1, ax0)],
169
+ angular_axes=[],
170
+ )
171
+ builder.joint_q[-3:] = [0.3, 0.5, 0.7]
172
+ builder.joint_qd[-3:] = [1.0, -1.0, 0.5]
173
+
174
+ b12 = builder.add_body(com=com2)
175
+ builder.add_joint_d6(
176
+ parent=b11,
177
+ child=b12,
178
+ parent_xform=tf1,
179
+ child_xform=tf2,
180
+ linear_axes=[],
181
+ angular_axes=[ax1, ax2, wp.cross(ax1, ax2)],
182
+ )
183
+ builder.joint_q[-3:] = [0.3, 0.5, 0.7]
184
+ builder.joint_qd[-3:] = [1.0, -1.0, 0.5]
185
+
186
+ parent = b12
187
+
188
+ return builder
189
+
190
+
191
+ def check_fk_ik(builder, device):
192
+ model = builder.finalize(device)
193
+ state = model.state()
194
+
195
+ q_fk = model.joint_q.numpy()
196
+ qd_fk = model.joint_qd.numpy()
197
+
198
+ wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, state)
199
+
200
+ q_ik = wp.zeros_like(model.joint_q)
201
+ qd_ik = wp.zeros_like(model.joint_qd)
202
+
203
+ wp.sim.eval_ik(model, state, q_ik, qd_ik)
204
+
205
+ # adjust numpy print settings
206
+ # np.set_printoptions(precision=4, floatmode="fixed", suppress=True)
207
+ # print("q:")
208
+ # print(np.array(q_fk))
209
+ # print(q_ik.numpy())
210
+
211
+ # print("qd:")
212
+ # print(np.array(qd_fk))
213
+ # print(qd_ik.numpy())
214
+
215
+ assert_np_equal(q_ik.numpy(), q_fk, tol=1e-4)
216
+ assert_np_equal(qd_ik.numpy(), qd_fk, tol=1e-4)
217
+
218
+
219
+ def test_fk_ik_ant(test, device):
220
+ builder = build_ant(3)
221
+ check_fk_ik(builder, device)
222
+
223
+
224
+ def test_fk_ik_complex_joint_mechanism(test, device):
225
+ builder = build_complex_joint_mechanism(2)
226
+ check_fk_ik(builder, device)
227
+
228
+
229
+ devices = get_test_devices()
230
+
231
+
232
+ class TestKinematics(unittest.TestCase):
233
+ pass
234
+
235
+
236
+ add_function_test(TestKinematics, "test_fk_ik_ant", test_fk_ik_ant, devices=devices)
237
+ add_function_test(
238
+ TestKinematics, "test_fk_ik_complex_joint_mechanism", test_fk_ik_complex_joint_mechanism, devices=devices
239
+ )
240
+
241
+
242
+ if __name__ == "__main__":
243
+ wp.clear_kernel_cache()
244
+ unittest.main(verbosity=2, failfast=False)
@@ -0,0 +1,290 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import unittest
17
+
18
+ import numpy as np
19
+
20
+ import warp as wp
21
+ import warp.sim
22
+ import warp.sim.render
23
+ from warp.tests.unittest_utils import *
24
+
25
+
26
+ @wp.kernel
27
+ def evaluate_loss(
28
+ joint_q: wp.array(dtype=float),
29
+ weighting: float,
30
+ target: float,
31
+ # output
32
+ loss: wp.array(dtype=float),
33
+ ):
34
+ tid = wp.tid()
35
+ d = (target - joint_q[tid * 2 + 1]) ** 2.0
36
+ wp.atomic_add(loss, 0, weighting * d)
37
+
38
+
39
+ @wp.kernel
40
+ def assign_action(action: wp.array(dtype=float), joint_act: wp.array(dtype=float)):
41
+ tid = wp.tid()
42
+ joint_act[2 * tid] = action[tid]
43
+
44
+
45
+ @wp.kernel
46
+ def assign_force(action: wp.array(dtype=float), body_f: wp.array(dtype=wp.spatial_vector)):
47
+ tid = wp.tid()
48
+ body_f[2 * tid] = wp.spatial_vector(0.0, 0.0, 0.0, action[tid], 0.0, 0.0)
49
+
50
+
51
+ def gradcheck(func, inputs, device, eps=1e-1, tol=1e-2, print_grad=False):
52
+ """
53
+ Checks that the gradient of the Warp kernel is correct by comparing it to the
54
+ numerical gradient computed using finite differences.
55
+ """
56
+
57
+ def f(xs):
58
+ # call the kernel without taping for finite differences
59
+ wp_xs = [wp.array(xs[i], ndim=1, dtype=inputs[i].dtype, device=device) for i in range(len(inputs))]
60
+ output = func(*wp_xs)
61
+ return output.numpy()[0]
62
+
63
+ # compute analytical gradient
64
+ tape = wp.Tape()
65
+ with tape:
66
+ output = func(*inputs)
67
+
68
+ tape.backward(loss=output)
69
+
70
+ # compute numerical gradient
71
+ np_xs = []
72
+ for i in range(len(inputs)):
73
+ np_xs.append(inputs[i].numpy().flatten().copy())
74
+
75
+ for i in range(len(inputs)):
76
+ fd_grad = np.zeros_like(np_xs[i])
77
+ for j in range(len(np_xs[i])):
78
+ np_xs[i][j] += eps
79
+ y1 = f(np_xs)
80
+ np_xs[i][j] -= 2 * eps
81
+ y2 = f(np_xs)
82
+ np_xs[i][j] += eps
83
+ fd_grad[j] = (y1 - y2) / (2 * eps)
84
+
85
+ # compare gradients
86
+ ad_grad = tape.gradients[inputs[i]].numpy()
87
+ if print_grad:
88
+ print("grad ad:", ad_grad)
89
+ print("grad fd:", fd_grad)
90
+ assert_np_equal(ad_grad, fd_grad, tol=tol)
91
+ # ensure the signs match
92
+ assert np.allclose(ad_grad * fd_grad > 0, True)
93
+
94
+ tape.zero()
95
+
96
+
97
+ def test_sphere_pushing_on_rails(
98
+ test,
99
+ device,
100
+ joint_type,
101
+ integrator_type,
102
+ apply_force=False,
103
+ static_contacts=True,
104
+ print_grad=False,
105
+ ):
106
+ # Two spheres on a rail (prismatic or D6 joint), one is pushed, the other is passive.
107
+ # The absolute distance to a target is measured and gradients are compared for
108
+ # a push that is too far and too close.
109
+ num_envs = 2
110
+ num_steps = 150
111
+ sim_substeps = 10
112
+ dt = 1 / 30
113
+
114
+ target = 3.0
115
+
116
+ if integrator_type == 0:
117
+ contact_ke = 1e3
118
+ contact_kd = 1e1
119
+ else:
120
+ contact_ke = 1e3
121
+ contact_kd = 1e1
122
+
123
+ complete_builder = wp.sim.ModelBuilder()
124
+
125
+ complete_builder.default_shape_ke = contact_ke
126
+ complete_builder.default_shape_kd = contact_kd
127
+
128
+ for _ in range(num_envs):
129
+ builder = wp.sim.ModelBuilder(gravity=0.0)
130
+
131
+ builder.default_shape_ke = complete_builder.default_shape_ke
132
+ builder.default_shape_kd = complete_builder.default_shape_kd
133
+
134
+ b0 = builder.add_body(name="pusher")
135
+ builder.add_shape_sphere(b0, radius=0.4, density=100.0)
136
+
137
+ b1 = builder.add_body(name="passive")
138
+ builder.add_shape_sphere(b1, radius=0.47, density=100.0)
139
+
140
+ if joint_type == 0:
141
+ builder.add_joint_prismatic(-1, b0)
142
+ builder.add_joint_prismatic(-1, b1)
143
+ else:
144
+ builder.add_joint_d6(-1, b0, linear_axes=[wp.sim.JointAxis((1.0, 0.0, 0.0))])
145
+ builder.add_joint_d6(-1, b1, linear_axes=[wp.sim.JointAxis((1.0, 0.0, 0.0))])
146
+
147
+ builder.joint_q[-2:] = [0.0, 2.0]
148
+ complete_builder.add_builder(builder)
149
+
150
+ assert complete_builder.body_count == 2 * num_envs
151
+ assert complete_builder.joint_count == 2 * num_envs
152
+ assert set(complete_builder.shape_collision_group) == set(range(1, num_envs + 1))
153
+
154
+ complete_builder.gravity = 0.0
155
+ model = complete_builder.finalize(device=device, requires_grad=True)
156
+ model.ground = False
157
+ model.joint_attach_ke = 32000.0 * 16
158
+ model.joint_attach_kd = 500.0 * 4
159
+
160
+ model.shape_geo.scale.requires_grad = False
161
+ model.shape_geo.thickness.requires_grad = False
162
+
163
+ if static_contacts:
164
+ wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, model)
165
+ model.rigid_contact_margin = 10.0
166
+ state = model.state()
167
+ wp.sim.collide(model, state)
168
+
169
+ if integrator_type == 0:
170
+ integrator = wp.sim.FeatherstoneIntegrator(model, update_mass_matrix_every=num_steps * sim_substeps)
171
+ elif integrator_type == 1:
172
+ integrator = wp.sim.SemiImplicitIntegrator()
173
+ sim_substeps *= 5
174
+ else:
175
+ integrator = wp.sim.XPBDIntegrator(iterations=2, rigid_contact_relaxation=1.0)
176
+
177
+ # renderer = wp.sim.render.SimRendererOpenGL(model, "test_sim_grad.usd", scaling=1.0)
178
+ renderer = None
179
+ render_time = 0.0
180
+
181
+ if renderer:
182
+ renderer.render_sphere("target", pos=wp.vec3(target, 0, 0), rot=wp.quat_identity(), radius=0.1, color=(1, 0, 0))
183
+
184
+ def rollout(action: wp.array) -> wp.array:
185
+ nonlocal render_time
186
+ states = [model.state() for _ in range(num_steps * sim_substeps + 1)]
187
+
188
+ wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, states[0])
189
+
190
+ control_active = model.control()
191
+ control_nop = model.control()
192
+
193
+ if not apply_force:
194
+ wp.launch(
195
+ assign_action,
196
+ dim=num_envs,
197
+ inputs=[action],
198
+ outputs=[control_active.joint_act],
199
+ device=model.device,
200
+ )
201
+
202
+ i = 0
203
+ for step in range(num_steps):
204
+ state = states[i]
205
+ if not static_contacts:
206
+ wp.sim.collide(model, state)
207
+ if apply_force:
208
+ control = control_nop
209
+ else:
210
+ control = control_active if step < 10 else control_nop
211
+ if renderer:
212
+ renderer.begin_frame(render_time)
213
+ renderer.render(state)
214
+ renderer.end_frame()
215
+ render_time += dt
216
+ for _ in range(sim_substeps):
217
+ state = states[i]
218
+ next_state = states[i + 1]
219
+ if apply_force and step < 10:
220
+ wp.launch(
221
+ assign_force,
222
+ dim=num_envs,
223
+ inputs=[action],
224
+ outputs=[state.body_f],
225
+ device=model.device,
226
+ )
227
+ integrator.simulate(model, state, next_state, dt / sim_substeps, control)
228
+ i += 1
229
+
230
+ if not isinstance(integrator, wp.sim.FeatherstoneIntegrator):
231
+ # compute generalized coordinates
232
+ wp.sim.eval_ik(model, states[-1], states[-1].joint_q, states[-1].joint_qd)
233
+
234
+ loss = wp.zeros(1, requires_grad=True, device=device)
235
+ weighting = 1.0
236
+ wp.launch(
237
+ evaluate_loss,
238
+ dim=num_envs,
239
+ inputs=[states[-1].joint_q, weighting, target],
240
+ outputs=[loss],
241
+ device=model.device,
242
+ )
243
+
244
+ # if renderer:
245
+ # renderer.save()
246
+
247
+ return loss
248
+
249
+ action_too_far = wp.array(
250
+ [80.0 for _ in range(num_envs)],
251
+ device=device,
252
+ dtype=wp.float32,
253
+ requires_grad=True,
254
+ )
255
+ tol = 2e-1
256
+ if isinstance(integrator, wp.sim.XPBDIntegrator):
257
+ # Euler, XPBD do not yield as accurate gradients, but at least the
258
+ # signs should match
259
+ tol = 0.1
260
+ gradcheck(rollout, [action_too_far], device=device, eps=0.2, tol=tol, print_grad=print_grad)
261
+
262
+ action_too_close = wp.array(
263
+ [40.0 for _ in range(num_envs)],
264
+ device=device,
265
+ dtype=wp.float32,
266
+ requires_grad=True,
267
+ )
268
+ gradcheck(rollout, [action_too_close], device=device, eps=0.2, tol=tol, print_grad=print_grad)
269
+
270
+
271
+ devices = get_test_devices()
272
+
273
+
274
+ class TestSimGradients(unittest.TestCase):
275
+ pass
276
+
277
+
278
+ for jt_type, jt_name in enumerate(["prismatic", "d6"]):
279
+ test_name = f"test_sphere_pushing_on_rails_{jt_name}"
280
+
281
+ def test_fn(self, device, jt_type=jt_type, int_type=1):
282
+ return test_sphere_pushing_on_rails(
283
+ self, device, jt_type, int_type, apply_force=True, static_contacts=True, print_grad=False
284
+ )
285
+
286
+ add_function_test(TestSimGradients, test_name, test_fn, devices=devices)
287
+
288
+ if __name__ == "__main__":
289
+ wp.clear_kernel_cache()
290
+ unittest.main(verbosity=2, failfast=True)