warp-lang 1.7.0__py3-none-manylinux_2_28_x86_64.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,245 @@
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
+ ###########################################################################
17
+ # Example Diff Sim Spring Cage
18
+ #
19
+ # A single particle is attached with springs to each point of a cage.
20
+ # The objective is to optimize the rest length of the springs in order
21
+ # for the particle to be pulled towards a target position.
22
+ #
23
+ ###########################################################################
24
+
25
+ import numpy as np
26
+
27
+ import warp as wp
28
+ import warp.sim
29
+ import warp.sim.render
30
+
31
+
32
+ @wp.kernel
33
+ def compute_loss_kernel(
34
+ pos: wp.array(dtype=wp.vec3),
35
+ target_pos: wp.vec3,
36
+ loss: wp.array(dtype=float),
37
+ ):
38
+ loss[0] = wp.length_sq(pos[0] - target_pos)
39
+
40
+
41
+ @wp.kernel(enable_backward=False)
42
+ def apply_gradient_kernel(
43
+ spring_rest_lengths_grad: wp.array(dtype=float),
44
+ train_rate: float,
45
+ spring_rest_lengths: wp.array(dtype=float),
46
+ ):
47
+ tid = wp.tid()
48
+
49
+ spring_rest_lengths[tid] -= spring_rest_lengths_grad[tid] * train_rate
50
+
51
+
52
+ class Example:
53
+ def __init__(self, stage_path="example_spring_cage.usd", num_frames=30, train_iters=25):
54
+ # Number of frames per second.
55
+ self.fps = 30
56
+
57
+ # Duration of a single simulation iteration in number of frames.
58
+ self.num_frames = num_frames
59
+
60
+ # Number of simulation steps to take per frame.
61
+ self.sim_substep_count = 1
62
+
63
+ # Delta time between each simulation substep.
64
+ self.sim_dt = 1.0 / (self.fps * self.sim_substep_count)
65
+
66
+ # Target position that we want the main particle to reach by optimising
67
+ # the rest lengths of the springs.
68
+ self.target_pos = (0.125, 0.25, 0.375)
69
+
70
+ # Number of training iterations.
71
+ self.train_iters = train_iters
72
+
73
+ # Factor by which the rest lengths of the springs are adjusted after each
74
+ # iteration, relatively to the corresponding gradients. Lower values
75
+ # converge more slowly but have less chances to miss the local minimum.
76
+ self.train_rate = 0.5
77
+
78
+ # Initialize the helper to build a physics scene.
79
+ builder = wp.sim.ModelBuilder()
80
+
81
+ # Define the main particle at the origin.
82
+ particle_mass = 1.0
83
+ builder.add_particle((0.0, 0.0, 0.0), (0.0, 0.0, 0.0), particle_mass)
84
+
85
+ # Define the cage made of points that will be pulling our main particle
86
+ # using springs.
87
+ # fmt: off
88
+ builder.add_particle((-0.7, 0.8, 0.2), (0.0, 0.0, 0.0), 0.0)
89
+ builder.add_particle(( 0.0, 0.2, 1.1), (0.0, 0.0, 0.0), 0.0)
90
+ builder.add_particle(( 0.1, 0.1, -1.2), (0.0, 0.0, 0.0), 0.0)
91
+ builder.add_particle(( 0.6, 0.4, 0.4), (0.0, 0.0, 0.0), 0.0)
92
+ builder.add_particle(( 0.7, -0.9, -0.2), (0.0, 0.0, 0.0), 0.0)
93
+ builder.add_particle((-0.8, -0.8, 0.1), (0.0, 0.0, 0.0), 0.0)
94
+ builder.add_particle((-0.9, 0.2, -0.8), (0.0, 0.0, 0.0), 0.0)
95
+ builder.add_particle(( 1.0, 0.4, -0.1), (0.0, 0.0, 0.0), 0.0)
96
+ # fmt: on
97
+
98
+ # Define the spring constraints between the main particle and the cage points.
99
+ spring_elastic_stiffness = 100.0
100
+ spring_elastic_damping = 10.0
101
+ for i in range(1, builder.particle_count):
102
+ builder.add_spring(0, i, spring_elastic_stiffness, spring_elastic_damping, 0)
103
+
104
+ # Build the model and set-up its properties.
105
+ self.model = builder.finalize(requires_grad=True)
106
+ self.model.gravity = np.array((0.0, 0.0, 0.0))
107
+ self.model.ground = False
108
+
109
+ # Use the Euler integrator for stepping through the simulation.
110
+ self.integrator = wp.sim.SemiImplicitIntegrator()
111
+
112
+ # Initialize a state for each simulation step.
113
+ self.states = tuple(self.model.state() for _ in range(self.num_frames * self.sim_substep_count + 1))
114
+
115
+ # Initialize a loss value that will represent the distance of the main
116
+ # particle to the target position. It needs to be defined as an array
117
+ # so that it can be written out by a kernel.
118
+ self.loss = wp.zeros(1, dtype=float, requires_grad=True)
119
+
120
+ if stage_path:
121
+ # Helper to render the physics scene as a USD file.
122
+ self.renderer = warp.sim.render.SimRenderer(self.model, stage_path, fps=self.fps, scaling=10.0)
123
+
124
+ # Allows rendering one simulation to USD every N training iterations.
125
+ self.render_iteration_steps = 2
126
+
127
+ # Frame number used to render the simulation iterations onto the USD file.
128
+ self.render_frame = 0
129
+ else:
130
+ self.renderer = None
131
+
132
+ self.use_cuda_graph = wp.get_device().is_cuda
133
+ if self.use_cuda_graph:
134
+ # Capture all the kernel launches into a CUDA graph so that they can
135
+ # all be run in a single graph launch, which helps with performance.
136
+ with wp.ScopedCapture() as capture:
137
+ self.tape = wp.Tape()
138
+ with self.tape:
139
+ self.forward()
140
+ self.tape.backward(loss=self.loss)
141
+ self.graph = capture.graph
142
+
143
+ def forward(self):
144
+ for i in range(1, len(self.states)):
145
+ prev = self.states[i - 1]
146
+ curr = self.states[i]
147
+ prev.clear_forces()
148
+ self.integrator.simulate(
149
+ self.model,
150
+ prev,
151
+ curr,
152
+ self.sim_dt,
153
+ )
154
+
155
+ last_state = self.states[-1]
156
+ wp.launch(
157
+ compute_loss_kernel,
158
+ dim=1,
159
+ inputs=(
160
+ last_state.particle_q,
161
+ self.target_pos,
162
+ ),
163
+ outputs=(self.loss,),
164
+ )
165
+
166
+ def step(self):
167
+ with wp.ScopedTimer("step"):
168
+ if self.use_cuda_graph:
169
+ wp.capture_launch(self.graph)
170
+ else:
171
+ self.tape = wp.Tape()
172
+ with self.tape:
173
+ self.forward()
174
+ self.tape.backward(loss=self.loss)
175
+
176
+ wp.launch(
177
+ apply_gradient_kernel,
178
+ dim=self.model.spring_count,
179
+ inputs=(
180
+ self.model.spring_rest_length.grad,
181
+ self.train_rate,
182
+ ),
183
+ outputs=(self.model.spring_rest_length,),
184
+ )
185
+
186
+ self.tape.zero()
187
+
188
+ def render(self):
189
+ if self.renderer is None:
190
+ return
191
+
192
+ with wp.ScopedTimer("render"):
193
+ self.renderer.begin_frame(0.0)
194
+ self.renderer.render_box(
195
+ name="target",
196
+ pos=self.target_pos,
197
+ rot=wp.quat_identity(),
198
+ extents=(0.1, 0.1, 0.1),
199
+ color=(1.0, 0.0, 0.0),
200
+ )
201
+ self.renderer.end_frame()
202
+
203
+ for frame in range(self.num_frames):
204
+ self.renderer.begin_frame(self.render_frame / self.fps)
205
+ self.renderer.render(self.states[frame * self.sim_substep_count])
206
+ self.renderer.end_frame()
207
+
208
+ self.render_frame += 1
209
+
210
+
211
+ if __name__ == "__main__":
212
+ import argparse
213
+
214
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
215
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
216
+ parser.add_argument(
217
+ "--stage_path",
218
+ type=lambda x: None if x == "None" else str(x),
219
+ default="example_spring_cage.usd",
220
+ help="Path to the output USD file.",
221
+ )
222
+ parser.add_argument("--num_frames", type=int, default=30, help="Total number of frames per training iteration.")
223
+ parser.add_argument("--train_iters", type=int, default=25, help="Total number of training iterations.")
224
+ parser.add_argument("--verbose", action="store_true", help="Print out additional status messages during execution.")
225
+
226
+ args = parser.parse_known_args()[0]
227
+
228
+ with wp.ScopedDevice(args.device):
229
+ example = Example(stage_path=args.stage_path, num_frames=args.num_frames, train_iters=args.train_iters)
230
+
231
+ for iteration in range(args.train_iters):
232
+ example.step()
233
+
234
+ loss = example.loss.numpy()[0]
235
+
236
+ if args.verbose:
237
+ print(f"[{iteration:3d}] loss={loss:.8f}")
238
+
239
+ if example.renderer and (
240
+ iteration == example.train_iters - 1 or iteration % example.render_iteration_steps == 0
241
+ ):
242
+ example.render()
243
+
244
+ if example.renderer:
245
+ example.renderer.save()
@@ -0,0 +1,227 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ ###########################################################################
17
+ # Example Trajectory Optimization
18
+ #
19
+ # Shows how to optimize torque trajectories for a simple planar environment
20
+ # using Warp's provided Adam optimizer.
21
+ #
22
+ ###########################################################################
23
+
24
+ import numpy as np
25
+
26
+ import warp as wp
27
+ import warp.sim
28
+ import warp.sim.render
29
+ from warp.optim import Adam
30
+
31
+
32
+ @wp.kernel
33
+ def loss_l2(
34
+ states: wp.array2d(dtype=wp.float32), targets: wp.array2d(dtype=wp.float32), loss: wp.array(dtype=wp.float32)
35
+ ):
36
+ i, j = wp.tid()
37
+ diff = states[i, j] - targets[i, j]
38
+ l = diff * diff
39
+ wp.atomic_add(loss, 0, l)
40
+
41
+
42
+ @wp.kernel
43
+ def apply_torque(torques: wp.array(dtype=wp.float32), start_index: int, body_f: wp.array(dtype=wp.spatial_vector)):
44
+ fx = torques[start_index + 0]
45
+ fz = torques[start_index + 1]
46
+ body_f[0] = wp.spatial_vector(0.0, 0.0, 0.0, fx, 0.0, fz)
47
+
48
+
49
+ @wp.kernel
50
+ def save_state(body_q: wp.array(dtype=wp.transform), write_index: int, states: wp.array2d(dtype=wp.float32)):
51
+ pos = wp.transform_get_translation(body_q[0])
52
+ states[write_index, 0] = pos[0]
53
+ states[write_index, 1] = pos[2]
54
+
55
+
56
+ class Example:
57
+ def __init__(self, stage_path="example_trajectory.usd", verbose=False, num_frames=100):
58
+ self.verbose = verbose
59
+
60
+ fps = 60
61
+ self.frame_dt = 1.0 / fps
62
+ self.num_frames = num_frames
63
+
64
+ self.sim_substeps = 1
65
+ self.sim_dt = self.frame_dt / self.sim_substeps
66
+
67
+ self.render_time = 0.0
68
+
69
+ self.iter = 0
70
+
71
+ # add planar joints
72
+ builder = wp.sim.ModelBuilder(gravity=0.0)
73
+ builder.add_articulation()
74
+ b = builder.add_body(origin=wp.transform())
75
+ builder.add_shape_sphere(pos=wp.vec3(0.0, 0.0, 0.0), radius=0.1, density=100.0, body=b)
76
+
77
+ # compute reference trajectory
78
+ rad = np.linspace(0.0, np.pi * 2, self.num_frames)
79
+ self.ref_traj = np.stack([np.cos(rad), np.sin(rad)], axis=1)
80
+
81
+ # set initial joint configuration to first reference state
82
+ builder.body_q[0] = wp.transform(p=[self.ref_traj[0][0], 0.0, self.ref_traj[0][1]])
83
+
84
+ self.ref_traj = wp.array(self.ref_traj, dtype=wp.float32, requires_grad=True)
85
+ self.last_traj = wp.empty_like(self.ref_traj)
86
+
87
+ # finalize model
88
+ self.model = builder.finalize(requires_grad=True)
89
+
90
+ self.builder = builder
91
+ self.model.ground = False
92
+
93
+ self.dof_q = self.model.joint_coord_count
94
+ self.dof_qd = self.model.joint_dof_count
95
+ self.num_bodies = self.model.body_count
96
+
97
+ self.action_dim = 2
98
+ self.state_dim = 2
99
+
100
+ assert self.ref_traj.shape == (self.num_frames, self.state_dim)
101
+
102
+ self.integrator = wp.sim.SemiImplicitIntegrator()
103
+
104
+ # initial guess
105
+ self.actions = wp.array(
106
+ np.zeros(self.num_frames * self.action_dim) * 100.0, dtype=wp.float32, requires_grad=True
107
+ )
108
+
109
+ self.optimizer = Adam([self.actions], lr=1e2)
110
+ self.loss = wp.zeros(1, dtype=wp.float32, requires_grad=True)
111
+
112
+ if stage_path:
113
+ self.renderer = wp.sim.render.SimRenderer(self.model, stage_path, scaling=100.0)
114
+ else:
115
+ self.renderer = None
116
+
117
+ # allocate sim states for trajectory
118
+ self.states = []
119
+ for _ in range(self.num_frames + 1):
120
+ self.states.append(self.model.state())
121
+
122
+ def forward(self):
123
+ """
124
+ Advances the system dynamics given the rigid-body state in maximal coordinates and generalized joint torques
125
+ [body_q, body_qd, tau].
126
+ """
127
+
128
+ self.last_traj.zero_()
129
+
130
+ for i in range(self.num_frames):
131
+ state = self.states[i]
132
+
133
+ for _ in range(self.sim_substeps):
134
+ next_state = self.model.state(requires_grad=True)
135
+
136
+ wp.sim.collide(self.model, state)
137
+
138
+ # apply generalized torques to rigid body here, instead of planar joints
139
+ wp.launch(apply_torque, 1, inputs=[self.actions, i * self.action_dim], outputs=[state.body_f])
140
+
141
+ state = self.integrator.simulate(self.model, state, next_state, self.sim_dt)
142
+
143
+ self.states[i + 1] = state
144
+
145
+ # save state
146
+ wp.launch(save_state, dim=1, inputs=[self.states[i + 1].body_q, i], outputs=[self.last_traj])
147
+
148
+ # compute loss
149
+ wp.launch(loss_l2, dim=self.last_traj.shape, inputs=[self.last_traj, self.ref_traj], outputs=[self.loss])
150
+
151
+ def step(self):
152
+ """Runs a single optimizer iteration"""
153
+
154
+ with wp.ScopedTimer("step"):
155
+ self.loss.zero_()
156
+ tape = wp.Tape()
157
+ with tape:
158
+ self.forward()
159
+ tape.backward(loss=self.loss)
160
+
161
+ if self.verbose and (self.iter + 1) % 10 == 0:
162
+ print(f"Iter {self.iter + 1} Loss: {self.loss.numpy()[0]:.3f}")
163
+
164
+ assert not np.isnan(self.actions.grad.numpy()).any(), "NaN in gradient"
165
+
166
+ self.optimizer.step([self.actions.grad])
167
+ tape.zero()
168
+ self.iter = self.iter + 1
169
+
170
+ def render(self):
171
+ if self.renderer is None:
172
+ return
173
+
174
+ with wp.ScopedTimer("render"):
175
+ for i in range(self.num_frames):
176
+ self.renderer.begin_frame(self.render_time)
177
+ self.renderer.render(self.states[i + 1])
178
+ self.renderer.end_frame()
179
+ self.render_time += self.frame_dt
180
+
181
+
182
+ if __name__ == "__main__":
183
+ import argparse
184
+
185
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
186
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
187
+ parser.add_argument(
188
+ "--stage_path",
189
+ type=lambda x: None if x == "None" else str(x),
190
+ default="example_trajectory.usd",
191
+ help="Path to the output USD file.",
192
+ )
193
+ parser.add_argument("--num_frames", type=int, default=100, help="Total number of frames per training iteration.")
194
+ parser.add_argument("--train_iters", type=int, default=250, help="Total number of training iterations.")
195
+ parser.add_argument("--verbose", action="store_true", help="Print out additional status messages during execution.")
196
+ parser.add_argument(
197
+ "--headless",
198
+ action="store_true",
199
+ help="Run in headless mode, suppressing the opening of any graphical windows.",
200
+ )
201
+
202
+ args = parser.parse_known_args()[0]
203
+
204
+ with wp.ScopedDevice(args.device):
205
+ example = Example(stage_path=args.stage_path, verbose=args.verbose, num_frames=args.num_frames)
206
+
207
+ for i in range(args.train_iters):
208
+ example.step()
209
+
210
+ if i % 25 == 0:
211
+ example.render()
212
+
213
+ if example.renderer:
214
+ example.renderer.save()
215
+
216
+ np_states = example.last_traj.numpy()
217
+ np_ref = example.ref_traj.numpy()
218
+
219
+ if not args.headless:
220
+ import matplotlib.pyplot as plt
221
+
222
+ plt.plot(np_ref[:, 0], np_ref[:, 1], label="Reference Trajectory")
223
+ plt.plot(np_states[:, 0], np_states[:, 1], label="Optimized Trajectory")
224
+ plt.grid()
225
+ plt.legend()
226
+ plt.axis("equal")
227
+ plt.show()
@@ -0,0 +1,143 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ ###########################################################################
17
+ # Example Sim Cartpole
18
+ #
19
+ # Shows how to set up a simulation of a rigid-body cartpole articulation
20
+ # from a URDF using the wp.sim.ModelBuilder().
21
+ # Note this example does not include a trained policy.
22
+ #
23
+ ###########################################################################
24
+
25
+ import math
26
+ import os
27
+
28
+ import numpy as np
29
+
30
+ import warp as wp
31
+ import warp.examples
32
+ import warp.sim
33
+ import warp.sim.render
34
+
35
+
36
+ class Example:
37
+ def __init__(self, stage_path="example_cartpole.usd", num_envs=8):
38
+ self.num_envs = num_envs
39
+
40
+ articulation_builder = wp.sim.ModelBuilder()
41
+
42
+ wp.sim.parse_urdf(
43
+ os.path.join(warp.examples.get_asset_directory(), "cartpole.urdf"),
44
+ articulation_builder,
45
+ xform=wp.transform(wp.vec3(), wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), -math.pi * 0.5)),
46
+ floating=False,
47
+ density=100,
48
+ armature=0.1,
49
+ stiffness=0.0,
50
+ damping=0.0,
51
+ limit_ke=1.0e4,
52
+ limit_kd=1.0e1,
53
+ enable_self_collisions=False,
54
+ )
55
+
56
+ builder = wp.sim.ModelBuilder()
57
+
58
+ self.sim_time = 0.0
59
+ fps = 60
60
+ self.frame_dt = 1.0 / fps
61
+
62
+ self.sim_substeps = 10
63
+ self.sim_dt = self.frame_dt / self.sim_substeps
64
+
65
+ for i in range(self.num_envs):
66
+ builder.add_builder(
67
+ articulation_builder, xform=wp.transform(np.array((i * 2.0, 4.0, 0.0)), wp.quat_identity())
68
+ )
69
+
70
+ # joint initial positions
71
+ builder.joint_q[-3:] = [0.0, 0.3, 0.0]
72
+
73
+ # finalize model
74
+ self.model = builder.finalize()
75
+ self.model.ground = False
76
+
77
+ self.model.joint_attach_ke = 1600.0
78
+ self.model.joint_attach_kd = 20.0
79
+
80
+ self.integrator = wp.sim.SemiImplicitIntegrator()
81
+
82
+ self.renderer = None
83
+ if stage_path:
84
+ self.renderer = wp.sim.render.SimRenderer(path=stage_path, model=self.model, scaling=15.0)
85
+
86
+ self.state = self.model.state()
87
+
88
+ wp.sim.eval_fk(self.model, self.model.joint_q, self.model.joint_qd, None, self.state)
89
+
90
+ self.use_cuda_graph = wp.get_device().is_cuda
91
+ if self.use_cuda_graph:
92
+ with wp.ScopedCapture() as capture:
93
+ self.simulate()
94
+ self.graph = capture.graph
95
+
96
+ def simulate(self):
97
+ for _ in range(self.sim_substeps):
98
+ self.state.clear_forces()
99
+ self.state = self.integrator.simulate(self.model, self.state, self.state, self.sim_dt)
100
+
101
+ def step(self):
102
+ with wp.ScopedTimer("step"):
103
+ if self.use_cuda_graph:
104
+ wp.capture_launch(self.graph)
105
+ else:
106
+ self.simulate()
107
+ self.sim_time += self.frame_dt
108
+
109
+ def render(self):
110
+ if self.renderer is None:
111
+ return
112
+
113
+ with wp.ScopedTimer("render"):
114
+ self.renderer.begin_frame(self.sim_time)
115
+ self.renderer.render(self.state)
116
+ self.renderer.end_frame()
117
+
118
+
119
+ if __name__ == "__main__":
120
+ import argparse
121
+
122
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
123
+ parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
124
+ parser.add_argument(
125
+ "--stage_path",
126
+ type=lambda x: None if x == "None" else str(x),
127
+ default="example_cartpole.usd",
128
+ help="Path to the output USD file.",
129
+ )
130
+ parser.add_argument("--num_frames", type=int, default=1200, help="Total number of frames.")
131
+ parser.add_argument("--num_envs", type=int, default=8, help="Total number of simulated environments.")
132
+
133
+ args = parser.parse_known_args()[0]
134
+
135
+ with wp.ScopedDevice(args.device):
136
+ example = Example(stage_path=args.stage_path, num_envs=args.num_envs)
137
+
138
+ for _ in range(args.num_frames):
139
+ example.step()
140
+ example.render()
141
+
142
+ if example.renderer:
143
+ example.renderer.save()