warp-lang 1.5.0__py3-none-macosx_10_13_universal2.whl → 1.6.0__py3-none-macosx_10_13_universal2.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 (132) hide show
  1. warp/__init__.py +5 -0
  2. warp/autograd.py +414 -191
  3. warp/bin/libwarp-clang.dylib +0 -0
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +40 -12
  6. warp/build_dll.py +13 -6
  7. warp/builtins.py +1124 -497
  8. warp/codegen.py +261 -136
  9. warp/config.py +1 -1
  10. warp/context.py +357 -119
  11. warp/examples/assets/square_cloth.usd +0 -0
  12. warp/examples/benchmarks/benchmark_gemm.py +27 -18
  13. warp/examples/benchmarks/benchmark_interop_paddle.py +3 -3
  14. warp/examples/benchmarks/benchmark_interop_torch.py +3 -3
  15. warp/examples/core/example_torch.py +18 -34
  16. warp/examples/fem/example_apic_fluid.py +1 -0
  17. warp/examples/fem/example_mixed_elasticity.py +1 -1
  18. warp/examples/optim/example_bounce.py +1 -1
  19. warp/examples/optim/example_cloth_throw.py +1 -1
  20. warp/examples/optim/example_diffray.py +4 -15
  21. warp/examples/optim/example_drone.py +1 -1
  22. warp/examples/optim/example_softbody_properties.py +392 -0
  23. warp/examples/optim/example_trajectory.py +1 -3
  24. warp/examples/optim/example_walker.py +5 -0
  25. warp/examples/sim/example_cartpole.py +0 -2
  26. warp/examples/sim/example_cloth.py +3 -1
  27. warp/examples/sim/example_cloth_self_contact.py +260 -0
  28. warp/examples/sim/example_granular_collision_sdf.py +4 -5
  29. warp/examples/sim/example_jacobian_ik.py +0 -2
  30. warp/examples/sim/example_quadruped.py +5 -2
  31. warp/examples/tile/example_tile_cholesky.py +79 -0
  32. warp/examples/tile/example_tile_convolution.py +2 -2
  33. warp/examples/tile/example_tile_fft.py +2 -2
  34. warp/examples/tile/example_tile_filtering.py +3 -3
  35. warp/examples/tile/example_tile_matmul.py +4 -4
  36. warp/examples/tile/example_tile_mlp.py +12 -12
  37. warp/examples/tile/example_tile_nbody.py +180 -0
  38. warp/examples/tile/example_tile_walker.py +319 -0
  39. warp/fem/geometry/geometry.py +0 -2
  40. warp/math.py +147 -0
  41. warp/native/array.h +12 -0
  42. warp/native/builtin.h +0 -1
  43. warp/native/bvh.cpp +149 -70
  44. warp/native/bvh.cu +287 -68
  45. warp/native/bvh.h +195 -85
  46. warp/native/clang/clang.cpp +5 -1
  47. warp/native/coloring.cpp +5 -1
  48. warp/native/cuda_util.cpp +91 -53
  49. warp/native/cuda_util.h +5 -0
  50. warp/native/exports.h +40 -40
  51. warp/native/intersect.h +17 -0
  52. warp/native/mat.h +41 -0
  53. warp/native/mathdx.cpp +19 -0
  54. warp/native/mesh.cpp +25 -8
  55. warp/native/mesh.cu +153 -101
  56. warp/native/mesh.h +482 -403
  57. warp/native/quat.h +40 -0
  58. warp/native/solid_angle.h +7 -0
  59. warp/native/sort.cpp +85 -0
  60. warp/native/sort.cu +34 -0
  61. warp/native/sort.h +3 -1
  62. warp/native/spatial.h +11 -0
  63. warp/native/tile.h +1187 -669
  64. warp/native/tile_reduce.h +8 -6
  65. warp/native/vec.h +41 -0
  66. warp/native/warp.cpp +8 -1
  67. warp/native/warp.cu +263 -40
  68. warp/native/warp.h +19 -5
  69. warp/optim/linear.py +22 -4
  70. warp/render/render_opengl.py +130 -64
  71. warp/sim/__init__.py +6 -1
  72. warp/sim/collide.py +270 -26
  73. warp/sim/import_urdf.py +8 -8
  74. warp/sim/integrator_euler.py +25 -7
  75. warp/sim/integrator_featherstone.py +154 -35
  76. warp/sim/integrator_vbd.py +842 -40
  77. warp/sim/model.py +134 -72
  78. warp/sparse.py +1 -1
  79. warp/stubs.py +265 -132
  80. warp/tape.py +28 -30
  81. warp/tests/aux_test_module_unload.py +15 -0
  82. warp/tests/{test_sim_grad.py → flaky_test_sim_grad.py} +104 -63
  83. warp/tests/test_array.py +74 -0
  84. warp/tests/test_assert.py +242 -0
  85. warp/tests/test_codegen.py +14 -61
  86. warp/tests/test_collision.py +2 -2
  87. warp/tests/test_coloring.py +12 -2
  88. warp/tests/test_examples.py +12 -1
  89. warp/tests/test_func.py +21 -4
  90. warp/tests/test_grad_debug.py +87 -2
  91. warp/tests/test_hash_grid.py +1 -1
  92. warp/tests/test_ipc.py +116 -0
  93. warp/tests/test_lerp.py +13 -87
  94. warp/tests/test_mat.py +138 -167
  95. warp/tests/test_math.py +47 -1
  96. warp/tests/test_matmul.py +17 -16
  97. warp/tests/test_matmul_lite.py +10 -15
  98. warp/tests/test_mesh.py +84 -60
  99. warp/tests/test_mesh_query_aabb.py +165 -0
  100. warp/tests/test_mesh_query_point.py +328 -286
  101. warp/tests/test_mesh_query_ray.py +134 -121
  102. warp/tests/test_mlp.py +2 -2
  103. warp/tests/test_operators.py +43 -0
  104. warp/tests/test_overwrite.py +47 -2
  105. warp/tests/test_quat.py +77 -0
  106. warp/tests/test_reload.py +29 -0
  107. warp/tests/test_sim_grad_bounce_linear.py +204 -0
  108. warp/tests/test_smoothstep.py +17 -83
  109. warp/tests/test_static.py +19 -3
  110. warp/tests/test_tape.py +25 -0
  111. warp/tests/test_tile.py +178 -191
  112. warp/tests/test_tile_load.py +356 -0
  113. warp/tests/test_tile_mathdx.py +61 -8
  114. warp/tests/test_tile_mlp.py +17 -17
  115. warp/tests/test_tile_reduce.py +24 -18
  116. warp/tests/test_tile_shared_memory.py +66 -17
  117. warp/tests/test_tile_view.py +165 -0
  118. warp/tests/test_torch.py +35 -0
  119. warp/tests/test_utils.py +36 -24
  120. warp/tests/test_vec.py +110 -0
  121. warp/tests/unittest_suites.py +29 -4
  122. warp/tests/unittest_utils.py +30 -13
  123. warp/thirdparty/unittest_parallel.py +2 -2
  124. warp/types.py +411 -101
  125. warp/utils.py +10 -7
  126. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/METADATA +92 -69
  127. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/RECORD +130 -119
  128. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/WHEEL +1 -1
  129. warp/examples/benchmarks/benchmark_tile.py +0 -179
  130. warp/native/tile_gemm.h +0 -341
  131. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/LICENSE.md +0 -0
  132. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/top_level.txt +0 -0
Binary file
@@ -13,23 +13,28 @@ wp.clear_kernel_cache()
13
13
  wp.set_module_options({"fast_math": True, "enable_backward": False})
14
14
 
15
15
 
16
- def create_mlp_kernel(m, n, k):
16
+ # returns a kernel to compute a GEMM given m,n,k tile sizes
17
+ def create_gemm_kernel(m, n, k):
17
18
  TILE_M = m
18
19
  TILE_N = n
19
20
  TILE_K = k
20
21
 
21
22
  @wp.kernel
22
- def mlp(x: wp.array2d(dtype=float), weights_wp: wp.array2d(dtype=float), n_k: int, output: wp.array2d(dtype=float)):
23
- i_m, i_n = wp.tid()
24
- sum = wp.tile_zeros(m=TILE_M, n=TILE_N, dtype=wp.float32)
25
- for count in range(n_k):
26
- feat = wp.tile_load(x, i_m, count, TILE_M, TILE_K)
27
- weight = wp.tile_load(weights_wp, count, i_n, TILE_K, TILE_N)
28
- wp.tile_matmul(feat, weight, sum)
23
+ def gemm(A: wp.array2d(dtype=float), B: wp.array2d(dtype=float), output: wp.array2d(dtype=float)):
24
+ i, j = wp.tid()
25
+ sum = wp.tile_zeros(shape=(TILE_M, TILE_N), dtype=wp.float32)
29
26
 
30
- wp.tile_store(output, i_m, i_n, sum)
27
+ count = A.shape[1] // TILE_K
31
28
 
32
- return mlp
29
+ for k in range(count):
30
+ a = wp.tile_load(A, shape=(TILE_M, TILE_K), offset=(i * TILE_M, k * TILE_K))
31
+ b = wp.tile_load(B, shape=(TILE_K, TILE_N), offset=(k * TILE_K, j * TILE_N))
32
+
33
+ wp.tile_matmul(a, b, sum)
34
+
35
+ wp.tile_store(output, sum, offset=(i * TILE_M, j * TILE_N))
36
+
37
+ return gemm
33
38
 
34
39
 
35
40
  def benchmark_torch(A, B, warm_up, iterations):
@@ -55,19 +60,25 @@ def benchmark_warp(A, B, config, warm_up, iterations):
55
60
  TILE_K = config[2]
56
61
  BLOCK_DIM = config[3]
57
62
 
58
- mlp = create_mlp_kernel(TILE_M, TILE_N, TILE_K)
63
+ mlp = create_gemm_kernel(TILE_M, TILE_N, TILE_K)
59
64
 
60
65
  M = A.shape[0]
61
66
  N = B.shape[1]
62
- K = A.shape[1]
63
67
 
64
68
  output = wp.zeros((M, N), dtype=float)
65
69
 
70
+ # create launch command
71
+ cmd = wp.launch_tiled(
72
+ kernel=mlp,
73
+ dim=[M // TILE_M, N // TILE_N],
74
+ inputs=[A, B, output],
75
+ block_dim=BLOCK_DIM,
76
+ record_cmd=True,
77
+ )
78
+
66
79
  # warm-up
67
80
  for _ in range(warm_up):
68
- wp.launch_tiled(
69
- kernel=mlp, dim=[M // TILE_M, N // TILE_N], inputs=[A, B, K // TILE_K, output], block_dim=BLOCK_DIM
70
- )
81
+ cmd.launch()
71
82
 
72
83
  # check output
73
84
  if warm_up > 0:
@@ -77,9 +88,7 @@ def benchmark_warp(A, B, config, warm_up, iterations):
77
88
  timers = {}
78
89
  with wp.ScopedTimer("warp", print=False, dict=timers, synchronize=True):
79
90
  for _ in range(iterations):
80
- wp.launch_tiled(
81
- kernel=mlp, dim=[M // TILE_M, N // TILE_N], inputs=[A, B, K // TILE_K, output], block_dim=BLOCK_DIM
82
- )
91
+ cmd.launch()
83
92
 
84
93
  return timers["warp"][0]
85
94
 
@@ -58,7 +58,7 @@ def test_from_paddle(kernel, num_iters, array_size, device, warp_dtype=None):
58
58
  wp.launch(kernel, dim=array_size, inputs=[a, b, c, d, e])
59
59
 
60
60
  t2 = time.time_ns()
61
- print(f"{(t2 - t1) / 1_000_000 :8.0f} ms from_paddle(...)")
61
+ print(f"{(t2 - t1) / 1_000_000:8.0f} ms from_paddle(...)")
62
62
 
63
63
  # profiler.stop()
64
64
  # profiler.print()
@@ -97,7 +97,7 @@ def test_array_ctype_from_paddle(kernel, num_iters, array_size, device, warp_dty
97
97
  wp.launch(kernel, dim=array_size, inputs=[a, b, c, d, e])
98
98
 
99
99
  t2 = time.time_ns()
100
- print(f"{(t2 - t1) / 1_000_000 :8.0f} ms from_paddle(..., return_ctype=True)")
100
+ print(f"{(t2 - t1) / 1_000_000:8.0f} ms from_paddle(..., return_ctype=True)")
101
101
 
102
102
  # profiler.stop()
103
103
  # profiler.print()
@@ -131,7 +131,7 @@ def test_direct_from_paddle(kernel, num_iters, array_size, device, warp_dtype=No
131
131
  wp.launch(kernel, dim=array_size, inputs=[_a, _b, _c, _d, _e])
132
132
 
133
133
  t2 = time.time_ns()
134
- print(f"{(t2 - t1) / 1_000_000 :8.0f} ms direct from paddle")
134
+ print(f"{(t2 - t1) / 1_000_000:8.0f} ms direct from paddle")
135
135
 
136
136
  # profiler.stop()
137
137
  # profiler.print()
@@ -58,7 +58,7 @@ def test_from_torch(kernel, num_iters, array_size, device, warp_dtype=None):
58
58
  wp.launch(kernel, dim=array_size, inputs=[a, b, c, d, e])
59
59
 
60
60
  t2 = time.time_ns()
61
- print(f"{(t2 - t1) / 1_000_000 :8.0f} ms from_torch(...)")
61
+ print(f"{(t2 - t1) / 1_000_000:8.0f} ms from_torch(...)")
62
62
 
63
63
  # profiler.stop()
64
64
  # profiler.print()
@@ -97,7 +97,7 @@ def test_array_ctype_from_torch(kernel, num_iters, array_size, device, warp_dtyp
97
97
  wp.launch(kernel, dim=array_size, inputs=[a, b, c, d, e])
98
98
 
99
99
  t2 = time.time_ns()
100
- print(f"{(t2 - t1) / 1_000_000 :8.0f} ms from_torch(..., return_ctype=True)")
100
+ print(f"{(t2 - t1) / 1_000_000:8.0f} ms from_torch(..., return_ctype=True)")
101
101
 
102
102
  # profiler.stop()
103
103
  # profiler.print()
@@ -131,7 +131,7 @@ def test_direct_from_torch(kernel, num_iters, array_size, device, warp_dtype=Non
131
131
  wp.launch(kernel, dim=array_size, inputs=[_a, _b, _c, _d, _e])
132
132
 
133
133
  t2 = time.time_ns()
134
- print(f"{(t2 - t1) / 1_000_000 :8.0f} ms direct from torch")
134
+ print(f"{(t2 - t1) / 1_000_000:8.0f} ms direct from torch")
135
135
 
136
136
  # profiler.stop()
137
137
  # profiler.print()
@@ -23,8 +23,6 @@ import torch
23
23
 
24
24
  import warp as wp
25
25
 
26
- pvec2 = wp.types.vector(length=2, dtype=wp.float32)
27
-
28
26
 
29
27
  # Define the Rosenbrock function
30
28
  @wp.func
@@ -33,11 +31,7 @@ def rosenbrock(x: float, y: float):
33
31
 
34
32
 
35
33
  @wp.kernel
36
- def eval_rosenbrock(
37
- xs: wp.array(dtype=pvec2),
38
- # outputs
39
- z: wp.array(dtype=float),
40
- ):
34
+ def eval_rosenbrock(xs: wp.array(dtype=wp.vec2), z: wp.array(dtype=float)):
41
35
  i = wp.tid()
42
36
  x = xs[i]
43
37
  z[i] = rosenbrock(x[0], x[1])
@@ -46,7 +40,7 @@ def eval_rosenbrock(
46
40
  class Rosenbrock(torch.autograd.Function):
47
41
  @staticmethod
48
42
  def forward(ctx, xy, num_particles):
49
- ctx.xy = wp.from_torch(xy, dtype=pvec2, requires_grad=True)
43
+ ctx.xy = wp.from_torch(xy, dtype=wp.vec2, requires_grad=True)
50
44
  ctx.num_particles = num_particles
51
45
 
52
46
  # allocate output
@@ -76,10 +70,10 @@ class Rosenbrock(torch.autograd.Function):
76
70
 
77
71
 
78
72
  class Example:
79
- def __init__(self, headless=False, train_iters=10):
80
- self.num_particles = 1500
73
+ def __init__(self, headless=False, train_iters=10, num_particles=1500):
74
+ self.num_particles = num_particles
81
75
  self.train_iters = train_iters
82
- self.frame = 0
76
+ self.train_iter = 0
83
77
 
84
78
  self.learning_rate = 5e-2
85
79
 
@@ -113,7 +107,7 @@ class Example:
113
107
  xy = np.column_stack((X.flatten(), Y.flatten()))
114
108
  N = len(xy)
115
109
 
116
- xy = wp.array(xy, dtype=pvec2)
110
+ xy = wp.array(xy, dtype=wp.vec2)
117
111
  Z = wp.empty(N, dtype=wp.float32)
118
112
 
119
113
  wp.launch(eval_rosenbrock, dim=N, inputs=[xy], outputs=[Z])
@@ -122,23 +116,8 @@ class Example:
122
116
  # Plot the function as a heatmap
123
117
  self.fig = plt.figure(figsize=(6, 6))
124
118
  ax = plt.gca()
125
- plt.imshow(
126
- Z,
127
- extent=[min_x, max_x, min_y, max_y],
128
- origin="lower",
129
- interpolation="bicubic",
130
- cmap="coolwarm",
131
- )
132
- plt.contour(
133
- X,
134
- Y,
135
- Z,
136
- extent=[min_x, max_x, min_y, max_y],
137
- levels=150,
138
- colors="k",
139
- alpha=0.5,
140
- linewidths=0.5,
141
- )
119
+ plt.imshow(Z, extent=[min_x, max_x, min_y, max_y], origin="lower", interpolation="bicubic", cmap="coolwarm")
120
+ plt.contour(X, Y, Z, extent=[min_x, max_x, min_y, max_y], levels=150, colors="k", alpha=0.5, linewidths=0.5)
142
121
 
143
122
  # Plot optimum
144
123
  plt.plot(1, 1, "*", color="r", markersize=10)
@@ -167,16 +146,16 @@ class Example:
167
146
 
168
147
  # Compute mean
169
148
  self.mean_pos = np.mean(self.xy_np, axis=0)
170
- print(f"\rFrame {self.frame:5d} particle mean: {self.mean_pos[0]:.8f}, {self.mean_pos[1]:.8f} ", end="")
149
+ print(f"\rIter {self.train_iter:5d} particle mean: {self.mean_pos[0]:.8f}, {self.mean_pos[1]:.8f} ", end="")
171
150
 
172
- self.frame += 1
151
+ self.train_iter += 1
173
152
 
174
153
  def render(self):
175
154
  if self.scatter_plot is None:
176
155
  return
177
156
 
178
157
  self.scatter_plot.set_offsets(np.c_[self.xy_np[:, 0], self.xy_np[:, 1]])
179
- self.mean_marker.set_data(self.mean_pos[0], self.mean_pos[1])
158
+ self.mean_marker.set_data([self.mean_pos[0]], [self.mean_pos[1]])
180
159
 
181
160
  # Function to update the scatter plot
182
161
  def step_and_render(self, frame):
@@ -193,6 +172,9 @@ if __name__ == "__main__":
193
172
  parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
194
173
  parser.add_argument("--num_frames", type=int, default=10000, help="Total number of frames.")
195
174
  parser.add_argument("--train_iters", type=int, default=10, help="Total number of training iterations per frame.")
175
+ parser.add_argument(
176
+ "--num_particles", type=int, default=1500, help="Total number of particles to use in optimization."
177
+ )
196
178
  parser.add_argument(
197
179
  "--headless",
198
180
  action="store_true",
@@ -202,14 +184,16 @@ if __name__ == "__main__":
202
184
  args = parser.parse_known_args()[0]
203
185
 
204
186
  with wp.ScopedDevice(args.device):
205
- example = Example(headless=args.headless, train_iters=args.train_iters)
187
+ example = Example(headless=args.headless, train_iters=args.train_iters, num_particles=args.num_particles)
206
188
 
207
189
  if not args.headless:
208
190
  import matplotlib.pyplot as plt
209
191
  from matplotlib.animation import FuncAnimation
210
192
 
211
193
  # Create the animation
212
- ani = FuncAnimation(example.fig, example.step_and_render, frames=args.num_frames, interval=100)
194
+ ani = FuncAnimation(
195
+ example.fig, example.step_and_render, frames=args.num_frames, interval=100, repeat=False
196
+ )
213
197
 
214
198
  # Display the animation
215
199
  plt.show()
@@ -220,6 +220,7 @@ class Example:
220
220
  jitter=self.radius * 1.0,
221
221
  )
222
222
  self.model: Model = builder.finalize()
223
+ self.model.ground = False
223
224
 
224
225
  # Storage for temporary variables
225
226
  self.temporary_store = fem.TemporaryStore()
@@ -236,7 +236,7 @@ class Example:
236
236
  final_area = fem.integrate(
237
237
  area_form, quadrature=fem.RegularQuadrature(domain, order=4), fields={"u_cur": self._u_field}
238
238
  )
239
- print(f"Area gain: {final_area} (using Poisson ratio={self._lame[0] / (self._lame[0] + 2.0*self._lame[1])})")
239
+ print(f"Area gain: {final_area} (using Poisson ratio={self._lame[0] / (self._lame[0] + 2.0 * self._lame[1])})")
240
240
 
241
241
  def render(self):
242
242
  self.renderer.add_field("solution", self._u_field)
@@ -169,7 +169,7 @@ class Example:
169
169
  vertices=traj_verts,
170
170
  color=wp.render.bourke_color_map(0.0, 7.0, self.loss.numpy()[0]),
171
171
  radius=0.02,
172
- name=f"traj_{self.iter-1}",
172
+ name=f"traj_{self.iter - 1}",
173
173
  )
174
174
  self.renderer.end_frame()
175
175
 
@@ -184,7 +184,7 @@ class Example:
184
184
  vertices=traj_verts,
185
185
  color=wp.render.bourke_color_map(0.0, 269.0, self.loss.numpy()[0]),
186
186
  radius=0.02,
187
- name=f"traj_{self.iter-1}",
187
+ name=f"traj_{self.iter - 1}",
188
188
  )
189
189
  self.renderer.end_frame()
190
190
 
@@ -166,24 +166,12 @@ def draw_kernel(
166
166
  j = mesh.indices[query.face * 3 + 1]
167
167
  k = mesh.indices[query.face * 3 + 2]
168
168
 
169
- a = mesh.vertices[i]
170
- b = mesh.vertices[j]
171
- c = mesh.vertices[k]
172
-
173
- p = wp.mesh_eval_position(mesh.id, query.face, query.u, query.v)
174
-
175
- # barycentric coordinates
176
- tri_area = wp.length(wp.cross(b - a, c - a))
177
- w = wp.length(wp.cross(b - a, p - a)) / tri_area
178
- v = wp.length(wp.cross(p - a, c - a)) / tri_area
179
- u = 1.0 - w - v
180
-
181
169
  a_n = mesh.vertex_normals[i]
182
170
  b_n = mesh.vertex_normals[j]
183
171
  c_n = mesh.vertex_normals[k]
184
172
 
185
173
  # vertex normal interpolation
186
- normal = u * a_n + v * b_n + w * c_n
174
+ normal = query.u * a_n + query.v * b_n + (1.0 - query.u - query.v) * c_n
187
175
 
188
176
  if mode == 0 or mode == 1:
189
177
  if mode == 0: # grayscale
@@ -194,7 +182,7 @@ def draw_kernel(
194
182
  tex_b = mesh.tex_coords[mesh.tex_indices[query.face * 3 + 1]]
195
183
  tex_c = mesh.tex_coords[mesh.tex_indices[query.face * 3 + 2]]
196
184
 
197
- tex = u * tex_a + v * tex_b + w * tex_c
185
+ tex = query.u * tex_a + query.v * tex_b + (1.0 - query.u - query.v) * tex_c
198
186
 
199
187
  color = texture_interpolation(tex, texture)
200
188
 
@@ -352,7 +340,8 @@ class Example:
352
340
  # construct RenderMesh
353
341
  self.render_mesh = RenderMesh()
354
342
  self.mesh = wp.Mesh(
355
- points=wp.array(points, dtype=wp.vec3, requires_grad=True), indices=wp.array(indices, dtype=int)
343
+ points=wp.array(points, dtype=wp.vec3, requires_grad=True),
344
+ indices=wp.array(indices, dtype=int),
356
345
  )
357
346
  self.render_mesh.id = self.mesh.id
358
347
  self.render_mesh.vertices = self.mesh.points
@@ -702,7 +702,7 @@ class Example:
702
702
  def step(self):
703
703
  if self.frame % int((self.num_frames / len(self.targets))) == 0:
704
704
  if self.verbose:
705
- print(f"Choosing new flight target: {self.target_idx+1}")
705
+ print(f"Choosing new flight target: {self.target_idx + 1}")
706
706
 
707
707
  self.target_idx += 1
708
708
  self.target_idx %= len(self.targets)