warp-lang 1.8.0__py3-none-manylinux_2_34_aarch64.whl → 1.8.1__py3-none-manylinux_2_34_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of warp-lang might be problematic. Click here for more details.

Files changed (59) hide show
  1. warp/bin/warp-clang.so +0 -0
  2. warp/bin/warp.so +0 -0
  3. warp/build_dll.py +5 -0
  4. warp/codegen.py +15 -3
  5. warp/config.py +1 -1
  6. warp/context.py +122 -24
  7. warp/examples/interop/example_jax_callable.py +34 -4
  8. warp/examples/interop/example_jax_kernel.py +27 -1
  9. warp/fem/field/virtual.py +2 -0
  10. warp/fem/integrate.py +78 -47
  11. warp/jax_experimental/ffi.py +201 -53
  12. warp/native/array.h +4 -4
  13. warp/native/builtin.h +8 -4
  14. warp/native/coloring.cpp +5 -1
  15. warp/native/cuda_util.cpp +1 -1
  16. warp/native/intersect.h +2 -2
  17. warp/native/mat.h +3 -3
  18. warp/native/mesh.h +1 -1
  19. warp/native/quat.h +6 -2
  20. warp/native/rand.h +7 -7
  21. warp/native/sparse.cu +1 -1
  22. warp/native/svd.h +23 -8
  23. warp/native/tile.h +20 -1
  24. warp/native/tile_radix_sort.h +5 -1
  25. warp/native/tile_reduce.h +16 -25
  26. warp/native/tuple.h +2 -2
  27. warp/native/vec.h +4 -4
  28. warp/native/warp.cpp +1 -1
  29. warp/native/warp.cu +15 -2
  30. warp/native/warp.h +1 -1
  31. warp/render/render_opengl.py +52 -51
  32. warp/render/render_usd.py +0 -1
  33. warp/sim/collide.py +1 -2
  34. warp/sim/integrator_vbd.py +10 -2
  35. warp/sparse.py +1 -1
  36. warp/tape.py +2 -0
  37. warp/tests/sim/test_cloth.py +89 -6
  38. warp/tests/sim/test_coloring.py +76 -1
  39. warp/tests/test_assert.py +53 -0
  40. warp/tests/test_atomic_cas.py +127 -114
  41. warp/tests/test_mat.py +22 -0
  42. warp/tests/test_quat.py +22 -0
  43. warp/tests/test_sparse.py +32 -0
  44. warp/tests/test_static.py +48 -0
  45. warp/tests/test_tape.py +38 -0
  46. warp/tests/test_vec.py +38 -408
  47. warp/tests/test_vec_constructors.py +325 -0
  48. warp/tests/tile/test_tile.py +31 -143
  49. warp/tests/tile/test_tile_mathdx.py +2 -2
  50. warp/tests/tile/test_tile_matmul.py +179 -0
  51. warp/tests/tile/test_tile_reduce.py +100 -11
  52. warp/tests/tile/test_tile_shared_memory.py +12 -12
  53. warp/tests/tile/test_tile_sort.py +59 -55
  54. warp/tests/unittest_suites.py +10 -0
  55. {warp_lang-1.8.0.dist-info → warp_lang-1.8.1.dist-info}/METADATA +4 -4
  56. {warp_lang-1.8.0.dist-info → warp_lang-1.8.1.dist-info}/RECORD +59 -57
  57. {warp_lang-1.8.0.dist-info → warp_lang-1.8.1.dist-info}/WHEEL +0 -0
  58. {warp_lang-1.8.0.dist-info → warp_lang-1.8.1.dist-info}/licenses/LICENSE.md +0 -0
  59. {warp_lang-1.8.0.dist-info → warp_lang-1.8.1.dist-info}/top_level.txt +0 -0
warp/sparse.py CHANGED
@@ -483,7 +483,7 @@ def bsr_set_from_triplets(
483
483
 
484
484
  device = dest.values.device
485
485
  scalar_type = dest.scalar_type
486
- zero_value_mask = _zero_value_masks.get(scalar_type, 0)
486
+ zero_value_mask = _zero_value_masks.get(scalar_type, 0) if prune_numerical_zeros else 0
487
487
 
488
488
  # compute the BSR topology
489
489
 
warp/tape.py CHANGED
@@ -251,6 +251,8 @@ class Tape:
251
251
  else:
252
252
  grad = None
253
253
  setattr(adj, name, grad)
254
+ elif isinstance(a._cls.vars[name].type, wp.codegen.Struct):
255
+ setattr(adj, name, self.get_adjoint(getattr(a, name)))
254
256
  else:
255
257
  setattr(adj, name, getattr(a, name))
256
258
 
@@ -25,6 +25,7 @@ import warp.sim.integrator_euler
25
25
  import warp.sim.integrator_vbd
26
26
  import warp.sim.integrator_xpbd
27
27
  import warp.sim.particles
28
+ import warp.sim.render
28
29
  from warp.sim.model import PARTICLE_FLAG_ACTIVE
29
30
  from warp.tests.unittest_utils import *
30
31
 
@@ -299,14 +300,16 @@ CLOTH_FACES = [
299
300
 
300
301
  # fmt: on
301
302
  class ClothSim:
302
- def __init__(self, device, solver, use_cuda_graph=False):
303
+ def __init__(self, device, solver, use_cuda_graph=False, do_rendering=False):
303
304
  self.frame_dt = 1 / 60
304
305
  self.num_test_frames = 50
305
306
  self.iterations = 5
307
+ self.do_rendering = do_rendering
306
308
  self.device = device
307
309
  self.use_cuda_graph = self.device.is_cuda and use_cuda_graph
308
310
  self.builder = wp.sim.ModelBuilder()
309
311
  self.solver = solver
312
+ self.renderer_scale_factor = 1.0
310
313
 
311
314
  if solver != "semi_implicit":
312
315
  self.num_substeps = 10
@@ -434,7 +437,7 @@ class ClothSim:
434
437
 
435
438
  self.finalize()
436
439
 
437
- def set_collision_experiment(self):
440
+ def set_self_collision_experiment(self):
438
441
  elasticity_ke = 1e4
439
442
  elasticity_kd = 1e-6
440
443
 
@@ -487,6 +490,44 @@ class ClothSim:
487
490
  self.model.gravity = wp.vec3(0.0, -1000.0, 0)
488
491
  self.num_test_frames = 30
489
492
 
493
+ def set_body_collision_experiment(self, handle_self_contact=False):
494
+ self.renderer_scale_factor = 1.0
495
+ elasticity_ke = 1e4
496
+ elasticity_kd = 1e-6
497
+
498
+ vs1 = [wp.vec3(v) for v in [[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]]]
499
+ fs1 = [0, 1, 2, 0, 2, 3]
500
+
501
+ self.builder.add_cloth_mesh(
502
+ pos=wp.vec3(0.0, 0.0, 0.0),
503
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
504
+ scale=1.0,
505
+ vertices=vs1,
506
+ indices=fs1,
507
+ vel=wp.vec3(0.0, 0.0, 0.0),
508
+ density=0.02,
509
+ tri_ke=elasticity_ke,
510
+ tri_ka=elasticity_ke,
511
+ tri_kd=elasticity_kd,
512
+ add_springs=self.solver == "xpbd",
513
+ spring_ke=1.0e3,
514
+ spring_kd=0.0,
515
+ particle_radius=0.1,
516
+ )
517
+
518
+ self.builder.add_shape_box(-1, pos=wp.vec3(0, -3.3, 0), hx=3, hy=3, hz=3)
519
+
520
+ self.fixed_particles = []
521
+
522
+ self.finalize(handle_self_contact=handle_self_contact, ground=False)
523
+ self.model.soft_contact_radius = 0.1
524
+ self.model.soft_contact_margin = 0.1
525
+ self.model.soft_contact_ke = 1e4
526
+ self.model.soft_contact_kd = 1e-3
527
+ self.model.soft_contact_mu = 0.2
528
+ self.model.gravity = wp.vec3(0.0, -1000.0, 0)
529
+ self.num_test_frames = 30
530
+
490
531
  def set_up_non_zero_rest_angle_bending_experiment(self):
491
532
  # fmt: off
492
533
  vs =[
@@ -629,6 +670,9 @@ class ClothSim:
629
670
  wp.load_module(warp.sim.integrator_euler, device=self.device)
630
671
  wp.load_module(warp.sim.particles, device=self.device)
631
672
  wp.load_module(warp.sim.integrator, device=self.device)
673
+ collide_module = importlib.import_module("warp.sim.collide")
674
+ wp.set_module_options({"block_dim": 256}, collide_module)
675
+ wp.load_module(collide_module, device=self.device)
632
676
  wp.load_module(device=self.device)
633
677
  with wp.ScopedCapture(device=self.device, force_module_load=False) as capture:
634
678
  self.simulate()
@@ -637,17 +681,30 @@ class ClothSim:
637
681
  def simulate(self):
638
682
  for _step in range(self.num_substeps):
639
683
  self.state0.clear_forces()
684
+ wp.sim.collide(self.model, self.state0)
640
685
 
641
686
  self.integrator.simulate(self.model, self.state0, self.state1, self.dt, None)
642
687
  (self.state0, self.state1) = (self.state1, self.state0)
643
688
 
644
689
  def run(self):
645
690
  self.sim_time = 0.0
691
+
692
+ if self.do_rendering:
693
+ self.renderer = wp.sim.render.SimRendererOpenGL(self.model, "cloth_sim", scaling=self.renderer_scale_factor)
694
+ else:
695
+ self.renderer = None
696
+
646
697
  for _frame in range(self.num_test_frames):
647
698
  if self.graph:
648
699
  wp.capture_launch(self.graph)
649
700
  else:
650
701
  self.simulate()
702
+
703
+ if self.renderer is not None:
704
+ self.renderer.begin_frame()
705
+ self.renderer.render(self.state0)
706
+ self.renderer.end_frame()
707
+
651
708
  self.sim_time = self.sim_time + self.frame_dt
652
709
 
653
710
  def set_points_fixed(self, model, fixed_particles):
@@ -702,16 +759,41 @@ def test_cloth_bending_non_zero_rest_angle_bending(test, device, solver):
702
759
  test.assertTrue((example.init_pos != final_pos).any())
703
760
 
704
761
 
705
- def test_cloth_collision(test, device, solver):
762
+ def test_cloth_body_collision(test, device, solver):
763
+ example = ClothSim(device, solver, use_cuda_graph=True)
764
+ example.set_body_collision_experiment(handle_self_contact=False)
765
+
766
+ example.run()
767
+
768
+ # examine that the velocity has died out
769
+ final_vel = example.state0.particle_qd.numpy()
770
+ final_pos = example.state0.particle_q.numpy()
771
+ test.assertTrue((np.linalg.norm(final_vel, axis=1) < 1.0).all())
772
+ # examine that the simulation has moved
773
+ test.assertTrue((example.init_pos[:, 1] != final_pos[:, 1]).any())
774
+
775
+ # run again with handle_self_contact=True
776
+ example = ClothSim(device, solver, use_cuda_graph=True)
777
+ example.set_body_collision_experiment(handle_self_contact=True)
778
+ example.run()
779
+ # examine that the velocity has died out
780
+ final_vel = example.state0.particle_qd.numpy()
781
+ final_pos = example.state0.particle_q.numpy()
782
+ test.assertTrue((np.linalg.norm(final_vel, axis=1) < 1.0).all())
783
+ # examine that the simulation has moved
784
+ test.assertTrue((example.init_pos[:, 1] != final_pos[:, 1]).any())
785
+
786
+
787
+ def test_cloth_self_collision(test, device, solver):
706
788
  example = ClothSim(device, solver, use_cuda_graph=True)
707
- example.set_collision_experiment()
789
+ example.set_self_collision_experiment()
708
790
 
709
791
  example.run()
710
792
 
711
793
  # examine that the velocity has died out
712
794
  final_vel = example.state0.particle_qd.numpy()
713
795
  final_pos = example.state0.particle_q.numpy()
714
- test.assertTrue((np.linalg.norm(final_vel, axis=0) < 1.0).all())
796
+ test.assertTrue((np.linalg.norm(final_vel, axis=1) < 1.0).all())
715
797
  # examine that the simulation has moved
716
798
  test.assertTrue((example.init_pos != final_pos).any())
717
799
 
@@ -763,7 +845,8 @@ tests_to_run = {
763
845
  test_cloth_free_fall,
764
846
  test_cloth_sagging,
765
847
  test_cloth_bending,
766
- test_cloth_collision,
848
+ test_cloth_self_collision,
849
+ test_cloth_body_collision,
767
850
  test_cloth_bending_non_zero_rest_angle_bending,
768
851
  ],
769
852
  }
@@ -13,6 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import itertools
17
+
16
18
  import numpy as np
17
19
 
18
20
  import warp as wp
@@ -48,6 +50,63 @@ def color_lattice_grid(num_x, num_y):
48
50
  return color_groups
49
51
 
50
52
 
53
+ def create_lattice_grid(N):
54
+ size = 10
55
+ position = (0, 0)
56
+
57
+ X = np.linspace(-0.5 * size + position[0], 0.5 * size + position[0], N)
58
+ Y = np.linspace(-0.5 * size + position[1], 0.5 * size + position[1], N)
59
+
60
+ X, Y = np.meshgrid(X, Y)
61
+
62
+ Z = []
63
+ for _i in range(N):
64
+ Z.append(np.linspace(0, size, N))
65
+
66
+ Z = np.array(Z)
67
+
68
+ vs = []
69
+ for i, j in itertools.product(range(N), range(N)):
70
+ vs.append(wp.vec3((X[i, j], Y[i, j], Z[i, j])))
71
+
72
+ fs = []
73
+ for i, j in itertools.product(range(0, N - 1), range(0, N - 1)):
74
+ vId = j + i * N
75
+
76
+ if (j + i) % 2:
77
+ fs.extend(
78
+ [
79
+ vId,
80
+ vId + N + 1,
81
+ vId + 1,
82
+ ]
83
+ )
84
+ fs.extend(
85
+ [
86
+ vId,
87
+ vId + N,
88
+ vId + N + 1,
89
+ ]
90
+ )
91
+ else:
92
+ fs.extend(
93
+ [
94
+ vId,
95
+ vId + N,
96
+ vId + 1,
97
+ ]
98
+ )
99
+ fs.extend(
100
+ [
101
+ vId + N,
102
+ vId + N + 1,
103
+ vId + 1,
104
+ ]
105
+ )
106
+
107
+ return vs, fs
108
+
109
+
51
110
  def test_coloring_corner_case(test, device):
52
111
  builder_1 = wp.sim.ModelBuilder()
53
112
  builder_1.color()
@@ -164,6 +223,22 @@ def test_coloring_trimesh(test, device):
164
223
  color_sizes = np.array([c.shape[0] for c in color_categories_balanced], dtype=np.float32)
165
224
  test.assertTrue(np.max(color_sizes) / np.min(color_sizes) <= max_min_ratio)
166
225
 
226
+ # test if the color balance can quit from equilibrium
227
+ builder = wp.sim.ModelBuilder()
228
+
229
+ vs, fs = create_lattice_grid(100)
230
+ builder.add_cloth_mesh(
231
+ pos=wp.vec3(0.0, 0.0, 0.0),
232
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
233
+ scale=1.0,
234
+ vertices=vs,
235
+ indices=fs,
236
+ vel=wp.vec3(0.0, 0.0, 0.0),
237
+ density=0.02,
238
+ )
239
+
240
+ builder.color(include_bending=True)
241
+
167
242
 
168
243
  @unittest.skipUnless(USD_AVAILABLE, "Requires usd-core")
169
244
  def test_combine_coloring(test, device):
@@ -263,7 +338,7 @@ class TestColoring(unittest.TestCase):
263
338
  pass
264
339
 
265
340
 
266
- add_function_test(TestColoring, "test_coloring_trimesh", test_coloring_trimesh, devices=devices)
341
+ add_function_test(TestColoring, "test_coloring_trimesh", test_coloring_trimesh, devices=devices, check_output=False)
267
342
  add_function_test(TestColoring, "test_combine_coloring", test_combine_coloring, devices=devices)
268
343
  add_function_test(TestColoring, "test_coloring_corner_case", test_coloring_corner_case, devices=devices)
269
344
 
warp/tests/test_assert.py CHANGED
@@ -245,6 +245,59 @@ class TestAssertDebug(unittest.TestCase):
245
245
  self.assertRegex(output, r"Assertion failed: .*assert value == 1.*Array element must be 1")
246
246
 
247
247
 
248
+ class TestAssertModeSwitch(unittest.TestCase):
249
+ """Test that switching from release mode to debug mode rebuilds the module with assertions enabled."""
250
+
251
+ @classmethod
252
+ def setUpClass(cls):
253
+ cls._saved_mode = wp.config.mode
254
+ cls._saved_mode_module = wp.get_module_options()["mode"]
255
+ cls._saved_cache_kernels = wp.config.cache_kernels
256
+
257
+ # Don't set any mode initially - use whatever the default is
258
+ wp.config.cache_kernels = False
259
+
260
+ @classmethod
261
+ def tearDownClass(cls):
262
+ wp.config.mode = cls._saved_mode
263
+ wp.set_module_options({"mode": cls._saved_mode_module})
264
+ wp.config.cache_kernels = cls._saved_cache_kernels
265
+
266
+ def test_switch_to_debug_mode(self):
267
+ """Test that switching from release mode to debug mode rebuilds the module with assertions enabled."""
268
+ with wp.ScopedDevice("cpu"):
269
+ # Create an array that will trigger an assertion
270
+ input_array = wp.zeros(1, dtype=int)
271
+
272
+ # In default mode, this should not assert
273
+ capture = StdErrCapture()
274
+ capture.begin()
275
+ wp.launch(expect_ones, input_array.shape, inputs=[input_array])
276
+ output = capture.end()
277
+
278
+ # Should not have any assertion output in release mode
279
+ self.assertEqual(output, "", f"Kernel should not print anything to stderr in release mode, got {output}")
280
+
281
+ # Now switch to debug mode and have it compile a new kernel
282
+ wp.config.mode = "debug"
283
+
284
+ @wp.kernel
285
+ def expect_ones_debug(a: wp.array(dtype=int)):
286
+ i = wp.tid()
287
+ assert a[i] == 1
288
+
289
+ # In debug mode, this should assert
290
+ capture = StdErrCapture()
291
+ capture.begin()
292
+ wp.launch(expect_ones_debug, input_array.shape, inputs=[input_array])
293
+ output = capture.end()
294
+
295
+ # Should have assertion output in debug mode
296
+ # Older Windows C runtimes have a bug where stdout sometimes does not get properly flushed.
297
+ if output != "" or sys.platform != "win32":
298
+ self.assertRegex(output, r"Assertion failed: .*assert a\[i\] == 1")
299
+
300
+
248
301
  if __name__ == "__main__":
249
302
  wp.clear_kernel_cache()
250
303
  unittest.main(verbosity=2)