warp-lang 1.0.0b2__py3-none-win_amd64.whl → 1.0.0b6__py3-none-win_amd64.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 (271) hide show
  1. docs/conf.py +17 -5
  2. examples/env/env_ant.py +1 -1
  3. examples/env/env_cartpole.py +1 -1
  4. examples/env/env_humanoid.py +1 -1
  5. examples/env/env_usd.py +4 -1
  6. examples/env/environment.py +8 -9
  7. examples/example_dem.py +34 -33
  8. examples/example_diffray.py +364 -337
  9. examples/example_fluid.py +32 -23
  10. examples/example_jacobian_ik.py +97 -93
  11. examples/example_marching_cubes.py +6 -16
  12. examples/example_mesh.py +6 -16
  13. examples/example_mesh_intersect.py +16 -14
  14. examples/example_nvdb.py +14 -16
  15. examples/example_raycast.py +14 -13
  16. examples/example_raymarch.py +16 -23
  17. examples/example_render_opengl.py +19 -10
  18. examples/example_sim_cartpole.py +82 -78
  19. examples/example_sim_cloth.py +45 -48
  20. examples/example_sim_fk_grad.py +51 -44
  21. examples/example_sim_fk_grad_torch.py +47 -40
  22. examples/example_sim_grad_bounce.py +108 -133
  23. examples/example_sim_grad_cloth.py +99 -113
  24. examples/example_sim_granular.py +5 -6
  25. examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
  26. examples/example_sim_neo_hookean.py +51 -55
  27. examples/example_sim_particle_chain.py +4 -4
  28. examples/example_sim_quadruped.py +126 -81
  29. examples/example_sim_rigid_chain.py +54 -61
  30. examples/example_sim_rigid_contact.py +66 -70
  31. examples/example_sim_rigid_fem.py +3 -3
  32. examples/example_sim_rigid_force.py +1 -1
  33. examples/example_sim_rigid_gyroscopic.py +3 -4
  34. examples/example_sim_rigid_kinematics.py +28 -39
  35. examples/example_sim_trajopt.py +112 -110
  36. examples/example_sph.py +9 -8
  37. examples/example_wave.py +7 -7
  38. examples/fem/bsr_utils.py +30 -17
  39. examples/fem/example_apic_fluid.py +85 -69
  40. examples/fem/example_convection_diffusion.py +97 -93
  41. examples/fem/example_convection_diffusion_dg.py +142 -149
  42. examples/fem/example_convection_diffusion_dg0.py +141 -136
  43. examples/fem/example_deformed_geometry.py +146 -0
  44. examples/fem/example_diffusion.py +115 -84
  45. examples/fem/example_diffusion_3d.py +116 -86
  46. examples/fem/example_diffusion_mgpu.py +102 -79
  47. examples/fem/example_mixed_elasticity.py +139 -100
  48. examples/fem/example_navier_stokes.py +175 -162
  49. examples/fem/example_stokes.py +143 -111
  50. examples/fem/example_stokes_transfer.py +186 -157
  51. examples/fem/mesh_utils.py +59 -97
  52. examples/fem/plot_utils.py +138 -17
  53. tools/ci/publishing/build_nodes_info.py +54 -0
  54. warp/__init__.py +4 -3
  55. warp/__init__.pyi +1 -0
  56. warp/bin/warp-clang.dll +0 -0
  57. warp/bin/warp.dll +0 -0
  58. warp/build.py +5 -3
  59. warp/build_dll.py +29 -9
  60. warp/builtins.py +836 -492
  61. warp/codegen.py +864 -553
  62. warp/config.py +3 -1
  63. warp/context.py +389 -172
  64. warp/fem/__init__.py +24 -6
  65. warp/fem/cache.py +318 -25
  66. warp/fem/dirichlet.py +7 -3
  67. warp/fem/domain.py +14 -0
  68. warp/fem/field/__init__.py +30 -38
  69. warp/fem/field/field.py +149 -0
  70. warp/fem/field/nodal_field.py +244 -138
  71. warp/fem/field/restriction.py +8 -6
  72. warp/fem/field/test.py +127 -59
  73. warp/fem/field/trial.py +117 -60
  74. warp/fem/geometry/__init__.py +5 -1
  75. warp/fem/geometry/deformed_geometry.py +271 -0
  76. warp/fem/geometry/element.py +24 -1
  77. warp/fem/geometry/geometry.py +86 -14
  78. warp/fem/geometry/grid_2d.py +112 -54
  79. warp/fem/geometry/grid_3d.py +134 -65
  80. warp/fem/geometry/hexmesh.py +953 -0
  81. warp/fem/geometry/partition.py +85 -33
  82. warp/fem/geometry/quadmesh_2d.py +532 -0
  83. warp/fem/geometry/tetmesh.py +451 -115
  84. warp/fem/geometry/trimesh_2d.py +197 -92
  85. warp/fem/integrate.py +534 -268
  86. warp/fem/operator.py +58 -31
  87. warp/fem/polynomial.py +11 -0
  88. warp/fem/quadrature/__init__.py +1 -1
  89. warp/fem/quadrature/pic_quadrature.py +150 -58
  90. warp/fem/quadrature/quadrature.py +209 -57
  91. warp/fem/space/__init__.py +230 -53
  92. warp/fem/space/basis_space.py +489 -0
  93. warp/fem/space/collocated_function_space.py +105 -0
  94. warp/fem/space/dof_mapper.py +49 -2
  95. warp/fem/space/function_space.py +90 -39
  96. warp/fem/space/grid_2d_function_space.py +149 -496
  97. warp/fem/space/grid_3d_function_space.py +173 -538
  98. warp/fem/space/hexmesh_function_space.py +352 -0
  99. warp/fem/space/partition.py +129 -76
  100. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  101. warp/fem/space/restriction.py +46 -34
  102. warp/fem/space/shape/__init__.py +15 -0
  103. warp/fem/space/shape/cube_shape_function.py +738 -0
  104. warp/fem/space/shape/shape_function.py +103 -0
  105. warp/fem/space/shape/square_shape_function.py +611 -0
  106. warp/fem/space/shape/tet_shape_function.py +567 -0
  107. warp/fem/space/shape/triangle_shape_function.py +429 -0
  108. warp/fem/space/tetmesh_function_space.py +132 -1039
  109. warp/fem/space/topology.py +295 -0
  110. warp/fem/space/trimesh_2d_function_space.py +104 -742
  111. warp/fem/types.py +13 -11
  112. warp/fem/utils.py +335 -60
  113. warp/native/array.h +120 -34
  114. warp/native/builtin.h +101 -72
  115. warp/native/bvh.cpp +73 -325
  116. warp/native/bvh.cu +406 -23
  117. warp/native/bvh.h +22 -40
  118. warp/native/clang/clang.cpp +1 -0
  119. warp/native/crt.h +2 -0
  120. warp/native/cuda_util.cpp +8 -3
  121. warp/native/cuda_util.h +1 -0
  122. warp/native/exports.h +1522 -1243
  123. warp/native/intersect.h +19 -4
  124. warp/native/intersect_adj.h +8 -8
  125. warp/native/mat.h +76 -17
  126. warp/native/mesh.cpp +33 -108
  127. warp/native/mesh.cu +114 -18
  128. warp/native/mesh.h +395 -40
  129. warp/native/noise.h +272 -329
  130. warp/native/quat.h +51 -8
  131. warp/native/rand.h +44 -34
  132. warp/native/reduce.cpp +1 -1
  133. warp/native/sparse.cpp +4 -4
  134. warp/native/sparse.cu +163 -155
  135. warp/native/spatial.h +2 -2
  136. warp/native/temp_buffer.h +18 -14
  137. warp/native/vec.h +103 -21
  138. warp/native/warp.cpp +2 -1
  139. warp/native/warp.cu +28 -3
  140. warp/native/warp.h +4 -3
  141. warp/render/render_opengl.py +261 -109
  142. warp/sim/__init__.py +1 -2
  143. warp/sim/articulation.py +385 -185
  144. warp/sim/import_mjcf.py +59 -48
  145. warp/sim/import_urdf.py +15 -15
  146. warp/sim/import_usd.py +174 -102
  147. warp/sim/inertia.py +17 -18
  148. warp/sim/integrator_xpbd.py +4 -3
  149. warp/sim/model.py +330 -250
  150. warp/sim/render.py +1 -1
  151. warp/sparse.py +625 -152
  152. warp/stubs.py +341 -309
  153. warp/tape.py +9 -6
  154. warp/tests/__main__.py +3 -6
  155. warp/tests/assets/curlnoise_golden.npy +0 -0
  156. warp/tests/assets/pnoise_golden.npy +0 -0
  157. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  158. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  159. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  160. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  161. warp/tests/aux_test_unresolved_func.py +14 -0
  162. warp/tests/aux_test_unresolved_symbol.py +14 -0
  163. warp/tests/disabled_kinematics.py +239 -0
  164. warp/tests/run_coverage_serial.py +31 -0
  165. warp/tests/test_adam.py +103 -106
  166. warp/tests/test_arithmetic.py +94 -74
  167. warp/tests/test_array.py +82 -101
  168. warp/tests/test_array_reduce.py +57 -23
  169. warp/tests/test_atomic.py +64 -28
  170. warp/tests/test_bool.py +22 -12
  171. warp/tests/test_builtins_resolution.py +1292 -0
  172. warp/tests/test_bvh.py +18 -18
  173. warp/tests/test_closest_point_edge_edge.py +54 -57
  174. warp/tests/test_codegen.py +165 -134
  175. warp/tests/test_compile_consts.py +28 -20
  176. warp/tests/test_conditional.py +108 -24
  177. warp/tests/test_copy.py +10 -12
  178. warp/tests/test_ctypes.py +112 -88
  179. warp/tests/test_dense.py +21 -14
  180. warp/tests/test_devices.py +98 -0
  181. warp/tests/test_dlpack.py +75 -75
  182. warp/tests/test_examples.py +237 -0
  183. warp/tests/test_fabricarray.py +22 -24
  184. warp/tests/test_fast_math.py +15 -11
  185. warp/tests/test_fem.py +1034 -124
  186. warp/tests/test_fp16.py +23 -16
  187. warp/tests/test_func.py +187 -86
  188. warp/tests/test_generics.py +194 -49
  189. warp/tests/test_grad.py +123 -181
  190. warp/tests/test_grad_customs.py +176 -0
  191. warp/tests/test_hash_grid.py +35 -34
  192. warp/tests/test_import.py +10 -23
  193. warp/tests/test_indexedarray.py +24 -25
  194. warp/tests/test_intersect.py +18 -9
  195. warp/tests/test_large.py +141 -0
  196. warp/tests/test_launch.py +14 -41
  197. warp/tests/test_lerp.py +64 -65
  198. warp/tests/test_lvalue.py +493 -0
  199. warp/tests/test_marching_cubes.py +12 -13
  200. warp/tests/test_mat.py +517 -2898
  201. warp/tests/test_mat_lite.py +115 -0
  202. warp/tests/test_mat_scalar_ops.py +2889 -0
  203. warp/tests/test_math.py +103 -9
  204. warp/tests/test_matmul.py +304 -69
  205. warp/tests/test_matmul_lite.py +410 -0
  206. warp/tests/test_mesh.py +60 -22
  207. warp/tests/test_mesh_query_aabb.py +21 -25
  208. warp/tests/test_mesh_query_point.py +111 -22
  209. warp/tests/test_mesh_query_ray.py +12 -24
  210. warp/tests/test_mlp.py +30 -22
  211. warp/tests/test_model.py +92 -89
  212. warp/tests/test_modules_lite.py +39 -0
  213. warp/tests/test_multigpu.py +88 -114
  214. warp/tests/test_noise.py +12 -11
  215. warp/tests/test_operators.py +16 -20
  216. warp/tests/test_options.py +11 -11
  217. warp/tests/test_pinned.py +17 -18
  218. warp/tests/test_print.py +32 -11
  219. warp/tests/test_quat.py +275 -129
  220. warp/tests/test_rand.py +18 -16
  221. warp/tests/test_reload.py +38 -34
  222. warp/tests/test_rounding.py +50 -43
  223. warp/tests/test_runlength_encode.py +168 -20
  224. warp/tests/test_smoothstep.py +9 -11
  225. warp/tests/test_snippet.py +143 -0
  226. warp/tests/test_sparse.py +261 -63
  227. warp/tests/test_spatial.py +276 -243
  228. warp/tests/test_streams.py +110 -85
  229. warp/tests/test_struct.py +268 -63
  230. warp/tests/test_tape.py +39 -21
  231. warp/tests/test_torch.py +90 -86
  232. warp/tests/test_transient_module.py +10 -12
  233. warp/tests/test_types.py +363 -0
  234. warp/tests/test_utils.py +451 -0
  235. warp/tests/test_vec.py +354 -2050
  236. warp/tests/test_vec_lite.py +73 -0
  237. warp/tests/test_vec_scalar_ops.py +2099 -0
  238. warp/tests/test_volume.py +418 -376
  239. warp/tests/test_volume_write.py +124 -134
  240. warp/tests/unittest_serial.py +35 -0
  241. warp/tests/unittest_suites.py +291 -0
  242. warp/tests/unittest_utils.py +342 -0
  243. warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
  244. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  245. warp/thirdparty/appdirs.py +36 -45
  246. warp/thirdparty/unittest_parallel.py +589 -0
  247. warp/types.py +622 -211
  248. warp/utils.py +54 -393
  249. warp_lang-1.0.0b6.dist-info/METADATA +238 -0
  250. warp_lang-1.0.0b6.dist-info/RECORD +409 -0
  251. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
  252. examples/example_cache_management.py +0 -40
  253. examples/example_multigpu.py +0 -54
  254. examples/example_struct.py +0 -65
  255. examples/fem/example_stokes_transfer_3d.py +0 -210
  256. warp/bin/warp-clang.so +0 -0
  257. warp/bin/warp.so +0 -0
  258. warp/fem/field/discrete_field.py +0 -80
  259. warp/fem/space/nodal_function_space.py +0 -233
  260. warp/tests/test_all.py +0 -223
  261. warp/tests/test_array_scan.py +0 -60
  262. warp/tests/test_base.py +0 -208
  263. warp/tests/test_unresolved_func.py +0 -7
  264. warp/tests/test_unresolved_symbol.py +0 -7
  265. warp_lang-1.0.0b2.dist-info/METADATA +0 -26
  266. warp_lang-1.0.0b2.dist-info/RECORD +0 -380
  267. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  268. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  269. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  270. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
  271. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
examples/example_fluid.py CHANGED
@@ -18,10 +18,6 @@ import math
18
18
  import warp as wp
19
19
  import warp.render
20
20
 
21
- import matplotlib
22
- import matplotlib.pyplot as plt
23
- import matplotlib.animation as anim
24
-
25
21
  wp.init()
26
22
 
27
23
  grid_width = wp.constant(256)
@@ -168,7 +164,9 @@ def init(rho: wp.array2d(dtype=float), u: wp.array2d(dtype=wp.vec2), radius: int
168
164
 
169
165
 
170
166
  class Example:
171
- def __init__(self):
167
+ def __init__(self, **kwargs):
168
+ self.device = wp.get_device()
169
+
172
170
  self.sim_fps = 60.0
173
171
  self.sim_substeps = 2
174
172
  self.iterations = 100
@@ -191,23 +189,15 @@ class Example:
191
189
 
192
190
  # capture pressure solve as a CUDA graph
193
191
  if self.device.is_cuda:
194
- wp.capture_begin()
195
- self.solve()
196
- self.graph = wp.capture_end()
192
+ wp.capture_begin(self.device)
193
+ try:
194
+ self.pressure_iterations()
195
+ finally:
196
+ self.graph = wp.capture_end(self.device)
197
197
 
198
198
  def update(self):
199
- pass
200
-
201
- def solve(self):
202
- for i in range(self.iterations):
203
- wp.launch(pressure_solve, dim=self.p0.shape, inputs=[self.p0, self.p1, self.div])
204
-
205
- # swap pressure fields
206
- (self.p0, self.p1) = (self.p1, self.p0)
207
-
208
- def render(self, img, i):
209
199
  with wp.ScopedTimer("update"):
210
- for i in range(self.sim_substeps):
200
+ for _ in range(self.sim_substeps):
211
201
  shape = (grid_width, grid_height)
212
202
  dt = self.sim_dt
213
203
 
@@ -230,7 +220,7 @@ class Example:
230
220
  wp.capture_launch(self.graph)
231
221
 
232
222
  else:
233
- self.solve()
223
+ self.pressure_iterations()
234
224
 
235
225
  # velocity update
236
226
  wp.launch(pressure_apply, dim=shape, inputs=[self.p0, self.u0])
@@ -244,20 +234,39 @@ class Example:
244
234
 
245
235
  self.sim_time += dt
246
236
 
247
- # plot
237
+ def render(self):
238
+ pass
239
+
240
+ def pressure_iterations(self):
241
+ for _ in range(self.iterations):
242
+ wp.launch(pressure_solve, dim=self.p0.shape, inputs=[self.p0, self.p1, self.div])
243
+
244
+ # swap pressure fields
245
+ (self.p0, self.p1) = (self.p1, self.p0)
246
+
247
+ def update_and_render_frame(self, frame_num=None, img=None):
248
+ self.update()
249
+
248
250
  with wp.ScopedTimer("render"):
249
- img.set_array(self.rho0.numpy())
251
+ if img:
252
+ img.set_array(self.rho0.numpy())
250
253
 
251
254
  return (img,)
252
255
 
253
256
 
254
257
  if __name__ == "__main__":
258
+ import matplotlib
259
+ import matplotlib.animation as anim
260
+ import matplotlib.pyplot as plt
261
+
255
262
  example = Example()
256
263
 
257
264
  fig = plt.figure()
258
265
 
259
266
  img = plt.imshow(example.rho0.numpy(), origin="lower", animated=True, interpolation="antialiased")
260
267
  img.set_norm(matplotlib.colors.Normalize(0.0, 1.0))
261
- seq = anim.FuncAnimation(fig, lambda i: example.render(img, i), frames=100000, blit=True, interval=8, repeat=False)
268
+ seq = anim.FuncAnimation(
269
+ fig, example.update_and_render_frame, fargs=(img,), frames=100000, blit=True, interval=8, repeat=False
270
+ )
262
271
 
263
272
  plt.show()
@@ -16,8 +16,8 @@
16
16
  #
17
17
  ###########################################################################
18
18
 
19
- import os
20
19
  import math
20
+ import os
21
21
 
22
22
  import numpy as np
23
23
 
@@ -28,22 +28,32 @@ import warp.sim.render
28
28
  wp.init()
29
29
 
30
30
 
31
- class Robot:
32
- frame_dt = 1.0 / 60.0
33
-
34
- render_time = 0.0
31
+ @wp.kernel
32
+ def compute_endeffector_position(
33
+ body_q: wp.array(dtype=wp.transform),
34
+ num_links: int,
35
+ ee_link_index: int,
36
+ ee_link_offset: wp.vec3,
37
+ ee_pos: wp.array(dtype=wp.vec3),
38
+ ):
39
+ tid = wp.tid()
40
+ ee_pos[tid] = wp.transform_point(body_q[tid * num_links + ee_link_index], ee_link_offset)
35
41
 
36
- # step size to use for the IK updates
37
- step_size = 0.1
38
42
 
39
- def __init__(self, render=True, num_envs=1, device=None):
43
+ class Example:
44
+ def __init__(self, stage=None, enable_rendering=True, num_envs=1, device=None):
40
45
  builder = wp.sim.ModelBuilder()
41
46
 
42
- self.render = render
43
-
44
47
  self.num_envs = num_envs
45
48
  self.device = device
46
49
 
50
+ self.frame_dt = 1.0 / 60.0
51
+
52
+ self.render_time = 0.0
53
+
54
+ # step size to use for the IK updates
55
+ self.step_size = 0.1
56
+
47
57
  articulation_builder = wp.sim.ModelBuilder()
48
58
 
49
59
  wp.sim.parse_urdf(
@@ -77,7 +87,7 @@ class Robot:
77
87
  builder.add_builder(
78
88
  articulation_builder,
79
89
  xform=wp.transform(
80
- np.array((i * 2.0, 4.0, 0.0)), wp.quat_from_axis_angle((1.0, 0.0, 0.0), -math.pi * 0.5)
90
+ wp.vec3(i * 2.0, 4.0, 0.0), wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), -math.pi * 0.5)
81
91
  ),
82
92
  )
83
93
  self.target_origin.append((i * 2.0, 4.0, 0.0))
@@ -97,31 +107,24 @@ class Robot:
97
107
 
98
108
  self.integrator = wp.sim.SemiImplicitIntegrator()
99
109
 
100
- # -----------------------
101
- # set up Usd renderer
102
- if self.render:
103
- self.renderer = wp.sim.render.SimRenderer(
104
- self.model, os.path.join(os.path.dirname(__file__), "outputs/example_jacobian_ik.usd")
105
- )
110
+ self.enable_rendering = enable_rendering
111
+ self.renderer = None
112
+ if enable_rendering:
113
+ self.renderer = wp.sim.render.SimRenderer(self.model, stage)
106
114
 
107
115
  self.ee_pos = wp.zeros(self.num_envs, dtype=wp.vec3, device=device, requires_grad=True)
108
116
 
109
- @wp.kernel
110
- def compute_endeffector_position(
111
- body_q: wp.array(dtype=wp.transform),
112
- num_links: int,
113
- ee_link_index: int,
114
- ee_link_offset: wp.vec3,
115
- ee_pos: wp.array(dtype=wp.vec3),
116
- ):
117
- tid = wp.tid()
118
- ee_pos[tid] = wp.transform_point(body_q[tid * num_links + ee_link_index], ee_link_offset)
117
+ self.state = self.model.state(requires_grad=True)
118
+
119
+ self.targets = self.target_origin.copy()
120
+
121
+ self.profiler = {}
119
122
 
120
123
  def compute_ee_position(self):
121
124
  # computes the end-effector position from the current joint angles
122
125
  wp.sim.eval_fk(self.model, self.model.joint_q, self.model.joint_qd, None, self.state)
123
126
  wp.launch(
124
- self.compute_endeffector_position,
127
+ compute_endeffector_position,
125
128
  dim=self.num_envs,
126
129
  inputs=[self.state.body_q, self.num_links, self.ee_link_index, self.ee_link_offset],
127
130
  outputs=[self.ee_pos],
@@ -163,12 +166,38 @@ class Robot:
163
166
  jacobians[e, :, i] = (f_plus - f_minus) / (2 * eps)
164
167
  return jacobians
165
168
 
166
- def run(self, render=True):
167
- profiler = {}
169
+ def update(self):
170
+ with wp.ScopedTimer("jacobian", print=False, active=True, dict=self.profiler):
171
+ # compute jacobian
172
+ jacobians = self.compute_jacobian()
173
+ # jacobians = self.compute_fd_jacobian()
168
174
 
169
- self.state = self.model.state(requires_grad=True)
175
+ # compute error
176
+ self.ee_pos_np = self.compute_ee_position().numpy()
177
+ error = self.targets - self.ee_pos_np
178
+ self.error = error.reshape(self.num_envs, 3, 1)
179
+
180
+ # compute Jacobian transpose update
181
+ delta_q = np.matmul(jacobians.transpose(0, 2, 1), self.error)
182
+
183
+ self.model.joint_q = wp.array(
184
+ self.model.joint_q.numpy() + self.step_size * delta_q.flatten(),
185
+ dtype=wp.float32,
186
+ device=self.device,
187
+ requires_grad=True,
188
+ )
170
189
 
171
- if render:
190
+ def render(self):
191
+ if self.enable_rendering:
192
+ self.renderer.begin_frame(self.render_time)
193
+ self.renderer.render(self.state)
194
+ self.renderer.render_points("targets", self.targets, radius=0.05)
195
+ self.renderer.render_points("ee_pos", self.ee_pos_np, radius=0.05)
196
+ self.renderer.end_frame()
197
+ self.render_time += self.frame_dt
198
+
199
+ def run(self):
200
+ if self.enable_rendering:
172
201
  print("autodiff:")
173
202
  print(self.compute_jacobian())
174
203
  print("finite diff:")
@@ -176,45 +205,18 @@ class Robot:
176
205
 
177
206
  for _ in range(5):
178
207
  # select new random target points
179
- targets = self.target_origin.copy()
180
- targets[:, 1:] += np.random.uniform(-0.5, 0.5, size=(self.num_envs, 2))
208
+ self.targets = self.target_origin.copy()
209
+ self.targets[:, 1:] += np.random.uniform(-0.5, 0.5, size=(self.num_envs, 2))
181
210
 
182
211
  for iter in range(50):
183
- with wp.ScopedTimer("jacobian", print=False, active=True, dict=profiler):
184
- # compute jacobian
185
- jacobians = self.compute_jacobian()
186
- # jacobians = self.compute_fd_jacobian()
187
-
188
- # compute error
189
- ee_pos = self.compute_ee_position().numpy()
190
- error = targets - ee_pos
191
- error = error.reshape(self.num_envs, 3, 1)
192
-
193
- # compute Jacobian transpose update
194
- delta_q = np.matmul(jacobians.transpose(0, 2, 1), error)
195
-
196
- self.model.joint_q = wp.array(
197
- self.model.joint_q.numpy() + self.step_size * delta_q.flatten(),
198
- dtype=wp.float32,
199
- device=self.device,
200
- requires_grad=True,
201
- )
202
-
203
- # render
204
- if render:
205
- self.render_time += self.frame_dt
206
-
207
- self.renderer.begin_frame(self.render_time)
208
- self.renderer.render(self.state)
209
- self.renderer.render_points("targets", targets, radius=0.05)
210
- self.renderer.render_points("ee_pos", ee_pos, radius=0.05)
211
- self.renderer.end_frame()
212
-
213
- self.renderer.save()
212
+ self.update()
213
+ self.render()
214
+ print("iter:", iter, "error:", self.error.mean())
214
215
 
215
- print("iter:", iter, "error:", error.mean())
216
+ if self.enable_rendering:
217
+ self.renderer.save()
216
218
 
217
- avg_time = np.array(profiler["jacobian"]).mean()
219
+ avg_time = np.array(self.profiler["jacobian"]).mean()
218
220
  avg_steps_second = 1000.0 * float(self.num_envs) / avg_time
219
221
 
220
222
  print(f"envs: {self.num_envs} steps/second {avg_steps_second} avg_time {avg_time}")
@@ -222,37 +224,39 @@ class Robot:
222
224
  return 1000.0 * float(self.num_envs) / avg_time
223
225
 
224
226
 
225
- profile = False
227
+ if __name__ == "__main__":
228
+ profile = False
226
229
 
227
- if profile:
228
- env_count = 2
229
- env_times = []
230
- env_size = []
230
+ if profile:
231
+ env_count = 2
232
+ env_times = []
233
+ env_size = []
231
234
 
232
- for i in range(12):
233
- robot = Robot(render=False, num_envs=env_count)
234
- steps_per_second = robot.run(render=False)
235
+ for i in range(12):
236
+ example = Example(enable_rendering=False, num_envs=env_count)
237
+ steps_per_second = example.run()
235
238
 
236
- env_size.append(env_count)
237
- env_times.append(steps_per_second)
239
+ env_size.append(env_count)
240
+ env_times.append(steps_per_second)
238
241
 
239
- env_count *= 2
242
+ env_count *= 2
240
243
 
241
- # dump times
242
- for i in range(len(env_times)):
243
- print(f"envs: {env_size[i]} steps/second: {env_times[i]}")
244
+ # dump times
245
+ for i in range(len(env_times)):
246
+ print(f"envs: {env_size[i]} steps/second: {env_times[i]}")
244
247
 
245
- # plot
246
- import matplotlib.pyplot as plt
248
+ # plot
249
+ import matplotlib.pyplot as plt
247
250
 
248
- plt.figure(1)
249
- plt.plot(env_size, env_times)
250
- plt.xscale("log")
251
- plt.xlabel("Number of Envs")
252
- plt.yscale("log")
253
- plt.ylabel("Steps/Second")
254
- plt.show()
251
+ plt.figure(1)
252
+ plt.plot(env_size, env_times)
253
+ plt.xscale("log")
254
+ plt.xlabel("Number of Envs")
255
+ plt.yscale("log")
256
+ plt.ylabel("Steps/Second")
257
+ plt.show()
255
258
 
256
- else:
257
- robot = Robot(render=True, num_envs=10)
258
- robot.run()
259
+ else:
260
+ stage_path = os.path.join(os.path.dirname(__file__), "outputs/example_jacobian_ik.usd")
261
+ example = Example(stage_path, enable_rendering=True, num_envs=10)
262
+ example.run()
@@ -14,12 +14,12 @@
14
14
  ###########################################################################
15
15
 
16
16
 
17
+ import math
18
+ import os
19
+
17
20
  import warp as wp
18
21
  import warp.render
19
22
 
20
- import os
21
- import math
22
-
23
23
  wp.init()
24
24
 
25
25
 
@@ -41,7 +41,6 @@ def sdf_box(upper: wp.vec3, p: wp.vec3):
41
41
  return wp.length(e) + wp.min(wp.max(qx, wp.max(qy, qz)), 0.0)
42
42
 
43
43
 
44
- # union
45
44
  @wp.func
46
45
  def op_union(d1: float, d2: float):
47
46
  return wp.min(d1, d2)
@@ -49,11 +48,6 @@ def op_union(d1: float, d2: float):
49
48
 
50
49
  @wp.func
51
50
  def op_smooth_union(d1: float, d2: float, k: float):
52
- # a = wp.pow(d1, k)
53
- # b = wp.pow(d2, k)
54
-
55
- # return wp.pow((a*b)/(a+b), 1.0/k)
56
-
57
51
  a = d1
58
52
  b = d2
59
53
 
@@ -61,13 +55,11 @@ def op_smooth_union(d1: float, d2: float, k: float):
61
55
  return wp.lerp(b, a, h) - k * h * (1.0 - h)
62
56
 
63
57
 
64
- # subtraction
65
58
  @wp.func
66
59
  def op_subtract(d1: float, d2: float):
67
60
  return wp.max(-d1, d2)
68
61
 
69
62
 
70
- # intersection
71
63
  @wp.func
72
64
  def op_intersect(d1: float, d2: float):
73
65
  return wp.max(d1, d2)
@@ -97,6 +89,7 @@ class Example:
97
89
  self.max_tris = 10**6
98
90
 
99
91
  self.time = 0.0
92
+ self.frame_dt = 1.0 / 60.0
100
93
 
101
94
  self.field = wp.zeros(shape=(self.dim, self.dim, self.dim), dtype=float)
102
95
 
@@ -107,26 +100,23 @@ class Example:
107
100
  self.renderer = wp.render.UsdRenderer(stage)
108
101
 
109
102
  def update(self):
110
- pass
111
-
112
- def render(self, is_live=False):
113
103
  with wp.ScopedTimer("Update Field"):
114
104
  wp.launch(
115
105
  make_field,
116
106
  dim=self.field.shape,
117
107
  inputs=[self.field, wp.vec3(self.dim / 2, self.dim / 2, self.dim / 2), self.dim / 4, self.time],
118
108
  )
109
+ self.time += self.frame_dt
119
110
 
120
111
  with wp.ScopedTimer("Surface Extraction"):
121
112
  self.iso.surface(field=self.field, threshold=math.sin(self.time) * self.dim / 8)
122
113
 
114
+ def render(self, is_live=False):
123
115
  with wp.ScopedTimer("Render"):
124
116
  self.renderer.begin_frame(self.time)
125
117
  self.renderer.render_mesh("surface", self.iso.verts.numpy(), self.iso.indices.numpy(), update_topology=True)
126
118
  self.renderer.end_frame()
127
119
 
128
- self.time += 1.0 / 60.0
129
-
130
120
 
131
121
  if __name__ == "__main__":
132
122
  stage_path = os.path.join(os.path.dirname(__file__), "outputs/example_marching_cubes.usd")
examples/example_mesh.py CHANGED
@@ -15,15 +15,14 @@
15
15
  #
16
16
  ###########################################################################
17
17
 
18
+ import os
19
+
18
20
  import numpy as np
21
+ from pxr import Usd, UsdGeom
19
22
 
20
23
  import warp as wp
21
24
  import warp.render
22
25
 
23
- from pxr import Usd, UsdGeom
24
-
25
- import os
26
-
27
26
  wp.init()
28
27
 
29
28
 
@@ -46,7 +45,6 @@ def simulate(
46
45
  positions: wp.array(dtype=wp.vec3),
47
46
  velocities: wp.array(dtype=wp.vec3),
48
47
  mesh: wp.uint64,
49
- restitution: float,
50
48
  margin: float,
51
49
  dt: float,
52
50
  ):
@@ -96,7 +94,6 @@ class Example:
96
94
  self.sim_time = 0.0
97
95
  self.sim_timers = {}
98
96
 
99
- self.sim_restitution = 0.0
100
97
  self.sim_margin = 0.1
101
98
 
102
99
  self.renderer = wp.render.UsdRenderer(stage)
@@ -128,16 +125,11 @@ class Example:
128
125
  wp.launch(
129
126
  kernel=simulate,
130
127
  dim=self.num_particles,
131
- inputs=[
132
- self.positions,
133
- self.velocities,
134
- self.mesh.id,
135
- self.sim_restitution,
136
- self.sim_margin,
137
- self.sim_dt,
138
- ],
128
+ inputs=[self.positions, self.velocities, self.mesh.id, self.sim_margin, self.sim_dt],
139
129
  )
140
130
 
131
+ self.sim_time += self.sim_dt
132
+
141
133
  def render(self, is_live=False):
142
134
  with wp.ScopedTimer("render", detailed=False):
143
135
  time = 0.0 if is_live else self.sim_time
@@ -147,8 +139,6 @@ class Example:
147
139
  self.renderer.render_points(name="points", points=self.positions.numpy(), radius=self.sim_margin)
148
140
  self.renderer.end_frame()
149
141
 
150
- self.sim_time += self.sim_dt
151
-
152
142
 
153
143
  if __name__ == "__main__":
154
144
  stage_path = os.path.join(os.path.dirname(__file__), "outputs/example_mesh.usd")
@@ -12,15 +12,16 @@
12
12
  #
13
13
  ##############################################################################
14
14
 
15
- import warp as wp
16
- import warp.render
15
+ import os
17
16
 
18
17
  import numpy as np
18
+ from pxr import Usd, UsdGeom
19
+
20
+ import warp as wp
21
+ import warp.render
19
22
 
20
23
  np.random.seed(42)
21
24
 
22
- from pxr import Usd, UsdGeom
23
- import os
24
25
 
25
26
  wp.init()
26
27
 
@@ -82,6 +83,9 @@ def intersect(
82
83
 
83
84
  class Example:
84
85
  def __init__(self, stage):
86
+ rng = np.random.default_rng()
87
+
88
+ self.device = wp.get_device()
85
89
  self.query_count = 1024
86
90
  self.has_queried = False
87
91
 
@@ -101,10 +105,10 @@ class Example:
101
105
 
102
106
  for i in range(self.query_count):
103
107
  # random offset
104
- p = (np.random.rand(3) * 0.5 - 0.5) * 5.0
108
+ p = wp.vec3(rng.random(3) * 0.5 - 0.5) * 5.0
105
109
 
106
110
  # random orientation
107
- axis = wp.normalize(np.random.rand(3) * 0.5 - 0.5)
111
+ axis = wp.normalize(wp.vec3(rng.random(3) * 0.5 - 0.5))
108
112
  angle = float(np.random.rand(1)[0])
109
113
 
110
114
  q = wp.quat_from_axis_angle(wp.normalize(axis), angle)
@@ -114,8 +118,8 @@ class Example:
114
118
  self.array_result = wp.zeros(self.query_count, dtype=int)
115
119
  self.array_xforms = wp.array(self.xforms, dtype=wp.transform)
116
120
 
117
- # force module load (for accurate profiling)
118
- wp.force_load()
121
+ # compile and load the module up front (for accurate profiling)
122
+ wp.load_module(device=self.device)
119
123
 
120
124
  def update(self):
121
125
  with wp.ScopedTimer("intersect", active=True):
@@ -124,12 +128,10 @@ class Example:
124
128
  dim=self.query_num_faces * self.query_count,
125
129
  inputs=[self.mesh_0.id, self.mesh_1.id, self.query_num_faces, self.array_xforms, self.array_result],
126
130
  )
127
- wp.synchronize()
128
131
 
129
- def render(self, is_live=False):
132
+ def render(self):
130
133
  # bring results back to host
131
134
  result = self.array_result.numpy()
132
- print(result)
133
135
 
134
136
  with wp.ScopedTimer("render", active=True):
135
137
  self.renderer.begin_frame(0.0)
@@ -144,14 +146,14 @@ class Example:
144
146
  os.path.join(os.path.dirname(__file__), self.path_0),
145
147
  pos=wp.vec3(xform.p[0] + offset, xform.p[1], xform.p[2]),
146
148
  rot=xform.q,
147
- scale=(1.0, 1.0, 1.0),
149
+ scale=wp.vec3(1.0, 1.0, 1.0),
148
150
  )
149
151
  self.renderer.render_ref(
150
152
  f"mesh_{i}_1",
151
153
  os.path.join(os.path.dirname(__file__), self.path_1),
152
- pos=(offset, 0.0, 0.0),
154
+ pos=wp.vec3(offset, 0.0, 0.0),
153
155
  rot=wp.quat_identity(),
154
- scale=(1.0, 1.0, 1.0),
156
+ scale=wp.vec3(1.0, 1.0, 1.0),
155
157
  )
156
158
 
157
159
  # if pair intersects then draw a small box above the pair