warp-lang 1.6.2__py3-none-macosx_10_13_universal2.whl → 1.7.1__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 (191) hide show
  1. warp/__init__.py +7 -1
  2. warp/autograd.py +12 -2
  3. warp/bin/libwarp-clang.dylib +0 -0
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +410 -0
  6. warp/build_dll.py +6 -14
  7. warp/builtins.py +463 -372
  8. warp/codegen.py +196 -124
  9. warp/config.py +42 -6
  10. warp/context.py +496 -271
  11. warp/dlpack.py +8 -6
  12. warp/examples/assets/nonuniform.usd +0 -0
  13. warp/examples/assets/nvidia_logo.png +0 -0
  14. warp/examples/benchmarks/benchmark_cloth.py +1 -1
  15. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  16. warp/examples/core/example_sample_mesh.py +300 -0
  17. warp/examples/distributed/example_jacobi_mpi.py +507 -0
  18. warp/examples/fem/example_apic_fluid.py +1 -1
  19. warp/examples/fem/example_burgers.py +2 -2
  20. warp/examples/fem/example_deformed_geometry.py +1 -1
  21. warp/examples/fem/example_distortion_energy.py +1 -1
  22. warp/examples/fem/example_magnetostatics.py +6 -6
  23. warp/examples/fem/utils.py +9 -3
  24. warp/examples/interop/example_jax_callable.py +116 -0
  25. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  26. warp/examples/interop/example_jax_kernel.py +205 -0
  27. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  28. warp/examples/tile/example_tile_matmul.py +2 -4
  29. warp/fem/__init__.py +11 -1
  30. warp/fem/adaptivity.py +4 -4
  31. warp/fem/field/field.py +11 -1
  32. warp/fem/field/nodal_field.py +56 -88
  33. warp/fem/field/virtual.py +62 -23
  34. warp/fem/geometry/adaptive_nanogrid.py +16 -13
  35. warp/fem/geometry/closest_point.py +1 -1
  36. warp/fem/geometry/deformed_geometry.py +5 -2
  37. warp/fem/geometry/geometry.py +5 -0
  38. warp/fem/geometry/grid_2d.py +12 -12
  39. warp/fem/geometry/grid_3d.py +12 -15
  40. warp/fem/geometry/hexmesh.py +5 -7
  41. warp/fem/geometry/nanogrid.py +9 -11
  42. warp/fem/geometry/quadmesh.py +13 -13
  43. warp/fem/geometry/tetmesh.py +3 -4
  44. warp/fem/geometry/trimesh.py +7 -20
  45. warp/fem/integrate.py +262 -93
  46. warp/fem/linalg.py +5 -5
  47. warp/fem/quadrature/pic_quadrature.py +37 -22
  48. warp/fem/quadrature/quadrature.py +194 -25
  49. warp/fem/space/__init__.py +1 -1
  50. warp/fem/space/basis_function_space.py +4 -2
  51. warp/fem/space/basis_space.py +25 -18
  52. warp/fem/space/hexmesh_function_space.py +2 -2
  53. warp/fem/space/partition.py +6 -2
  54. warp/fem/space/quadmesh_function_space.py +8 -8
  55. warp/fem/space/shape/cube_shape_function.py +23 -23
  56. warp/fem/space/shape/square_shape_function.py +12 -12
  57. warp/fem/space/shape/triangle_shape_function.py +1 -1
  58. warp/fem/space/tetmesh_function_space.py +3 -3
  59. warp/fem/space/trimesh_function_space.py +2 -2
  60. warp/fem/utils.py +12 -6
  61. warp/jax.py +14 -1
  62. warp/jax_experimental/__init__.py +16 -0
  63. warp/{jax_experimental.py → jax_experimental/custom_call.py} +28 -29
  64. warp/jax_experimental/ffi.py +702 -0
  65. warp/jax_experimental/xla_ffi.py +602 -0
  66. warp/math.py +89 -0
  67. warp/native/array.h +13 -0
  68. warp/native/builtin.h +29 -3
  69. warp/native/bvh.cpp +3 -1
  70. warp/native/bvh.cu +42 -14
  71. warp/native/bvh.h +2 -1
  72. warp/native/clang/clang.cpp +30 -3
  73. warp/native/cuda_util.cpp +14 -0
  74. warp/native/cuda_util.h +2 -0
  75. warp/native/exports.h +68 -63
  76. warp/native/intersect.h +26 -26
  77. warp/native/intersect_adj.h +33 -33
  78. warp/native/marching.cu +1 -1
  79. warp/native/mat.h +513 -9
  80. warp/native/mesh.h +10 -10
  81. warp/native/quat.h +99 -11
  82. warp/native/rand.h +6 -0
  83. warp/native/sort.cpp +122 -59
  84. warp/native/sort.cu +152 -15
  85. warp/native/sort.h +8 -1
  86. warp/native/sparse.cpp +43 -22
  87. warp/native/sparse.cu +52 -17
  88. warp/native/svd.h +116 -0
  89. warp/native/tile.h +312 -116
  90. warp/native/tile_reduce.h +46 -3
  91. warp/native/vec.h +68 -7
  92. warp/native/volume.cpp +85 -113
  93. warp/native/volume_builder.cu +25 -10
  94. warp/native/volume_builder.h +6 -0
  95. warp/native/warp.cpp +5 -6
  96. warp/native/warp.cu +100 -11
  97. warp/native/warp.h +19 -10
  98. warp/optim/linear.py +10 -10
  99. warp/render/render_opengl.py +19 -17
  100. warp/render/render_usd.py +93 -3
  101. warp/sim/articulation.py +4 -4
  102. warp/sim/collide.py +32 -19
  103. warp/sim/import_mjcf.py +449 -155
  104. warp/sim/import_urdf.py +32 -12
  105. warp/sim/inertia.py +189 -156
  106. warp/sim/integrator_euler.py +8 -5
  107. warp/sim/integrator_featherstone.py +3 -10
  108. warp/sim/integrator_vbd.py +207 -2
  109. warp/sim/integrator_xpbd.py +8 -5
  110. warp/sim/model.py +71 -25
  111. warp/sim/render.py +4 -0
  112. warp/sim/utils.py +2 -2
  113. warp/sparse.py +642 -555
  114. warp/stubs.py +217 -20
  115. warp/tests/__main__.py +0 -15
  116. warp/tests/assets/torus.usda +1 -1
  117. warp/tests/cuda/__init__.py +0 -0
  118. warp/tests/{test_mempool.py → cuda/test_mempool.py} +39 -0
  119. warp/tests/{test_streams.py → cuda/test_streams.py} +71 -0
  120. warp/tests/geometry/__init__.py +0 -0
  121. warp/tests/{test_mesh_query_point.py → geometry/test_mesh_query_point.py} +66 -63
  122. warp/tests/{test_mesh_query_ray.py → geometry/test_mesh_query_ray.py} +1 -1
  123. warp/tests/{test_volume.py → geometry/test_volume.py} +41 -6
  124. warp/tests/interop/__init__.py +0 -0
  125. warp/tests/{test_dlpack.py → interop/test_dlpack.py} +28 -5
  126. warp/tests/sim/__init__.py +0 -0
  127. warp/tests/{disabled_kinematics.py → sim/disabled_kinematics.py} +9 -10
  128. warp/tests/{test_collision.py → sim/test_collision.py} +236 -205
  129. warp/tests/sim/test_inertia.py +161 -0
  130. warp/tests/{test_model.py → sim/test_model.py} +40 -0
  131. warp/tests/{flaky_test_sim_grad.py → sim/test_sim_grad.py} +4 -0
  132. warp/tests/{test_sim_kinematics.py → sim/test_sim_kinematics.py} +2 -1
  133. warp/tests/sim/test_vbd.py +597 -0
  134. warp/tests/sim/test_xpbd.py +399 -0
  135. warp/tests/test_bool.py +1 -1
  136. warp/tests/test_codegen.py +24 -3
  137. warp/tests/test_examples.py +40 -38
  138. warp/tests/test_fem.py +98 -14
  139. warp/tests/test_linear_solvers.py +0 -11
  140. warp/tests/test_mat.py +577 -156
  141. warp/tests/test_mat_scalar_ops.py +4 -4
  142. warp/tests/test_overwrite.py +0 -60
  143. warp/tests/test_quat.py +356 -151
  144. warp/tests/test_rand.py +44 -37
  145. warp/tests/test_sparse.py +47 -6
  146. warp/tests/test_spatial.py +75 -0
  147. warp/tests/test_static.py +1 -1
  148. warp/tests/test_utils.py +84 -4
  149. warp/tests/test_vec.py +336 -178
  150. warp/tests/tile/__init__.py +0 -0
  151. warp/tests/{test_tile.py → tile/test_tile.py} +136 -51
  152. warp/tests/{test_tile_load.py → tile/test_tile_load.py} +98 -1
  153. warp/tests/{test_tile_mathdx.py → tile/test_tile_mathdx.py} +9 -6
  154. warp/tests/{test_tile_mlp.py → tile/test_tile_mlp.py} +25 -14
  155. warp/tests/{test_tile_reduce.py → tile/test_tile_reduce.py} +60 -1
  156. warp/tests/{test_tile_view.py → tile/test_tile_view.py} +1 -1
  157. warp/tests/unittest_serial.py +1 -0
  158. warp/tests/unittest_suites.py +45 -62
  159. warp/tests/unittest_utils.py +2 -1
  160. warp/thirdparty/unittest_parallel.py +3 -1
  161. warp/types.py +175 -666
  162. warp/utils.py +137 -72
  163. {warp_lang-1.6.2.dist-info → warp_lang-1.7.1.dist-info}/METADATA +46 -12
  164. {warp_lang-1.6.2.dist-info → warp_lang-1.7.1.dist-info}/RECORD +184 -171
  165. {warp_lang-1.6.2.dist-info → warp_lang-1.7.1.dist-info}/WHEEL +1 -1
  166. {warp_lang-1.6.2.dist-info → warp_lang-1.7.1.dist-info/licenses}/LICENSE.md +0 -26
  167. warp/examples/optim/example_walker.py +0 -317
  168. warp/native/cutlass_gemm.cpp +0 -43
  169. warp/native/cutlass_gemm.cu +0 -382
  170. warp/tests/test_matmul.py +0 -511
  171. warp/tests/test_matmul_lite.py +0 -411
  172. warp/tests/test_vbd.py +0 -386
  173. warp/tests/unused_test_misc.py +0 -77
  174. /warp/tests/{test_async.py → cuda/test_async.py} +0 -0
  175. /warp/tests/{test_ipc.py → cuda/test_ipc.py} +0 -0
  176. /warp/tests/{test_multigpu.py → cuda/test_multigpu.py} +0 -0
  177. /warp/tests/{test_peer.py → cuda/test_peer.py} +0 -0
  178. /warp/tests/{test_pinned.py → cuda/test_pinned.py} +0 -0
  179. /warp/tests/{test_bvh.py → geometry/test_bvh.py} +0 -0
  180. /warp/tests/{test_hash_grid.py → geometry/test_hash_grid.py} +0 -0
  181. /warp/tests/{test_marching_cubes.py → geometry/test_marching_cubes.py} +0 -0
  182. /warp/tests/{test_mesh.py → geometry/test_mesh.py} +0 -0
  183. /warp/tests/{test_mesh_query_aabb.py → geometry/test_mesh_query_aabb.py} +0 -0
  184. /warp/tests/{test_volume_write.py → geometry/test_volume_write.py} +0 -0
  185. /warp/tests/{test_jax.py → interop/test_jax.py} +0 -0
  186. /warp/tests/{test_paddle.py → interop/test_paddle.py} +0 -0
  187. /warp/tests/{test_torch.py → interop/test_torch.py} +0 -0
  188. /warp/tests/{test_coloring.py → sim/test_coloring.py} +0 -0
  189. /warp/tests/{test_sim_grad_bounce_linear.py → sim/test_sim_grad_bounce_linear.py} +0 -0
  190. /warp/tests/{test_tile_shared_memory.py → tile/test_tile_shared_memory.py} +0 -0
  191. {warp_lang-1.6.2.dist-info → warp_lang-1.7.1.dist-info}/top_level.txt +0 -0
@@ -13,6 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import math
16
17
  import unittest
17
18
 
18
19
  import numpy as np
@@ -178,6 +179,45 @@ class TestModel(unittest.TestCase):
178
179
  assert builder2.articulation_count == 2 * builder.articulation_count
179
180
  assert builder2.articulation_start == [0, 1, 2, 3]
180
181
 
182
+ def test_add_builder_with_open_edges(self):
183
+ builder = wp.sim.ModelBuilder()
184
+
185
+ dim_x = 16
186
+ dim_y = 16
187
+
188
+ env_builder = wp.sim.ModelBuilder()
189
+ env_builder.add_cloth_grid(
190
+ pos=wp.vec3(0.0, 0.0, 0.0),
191
+ vel=wp.vec3(0.1, 0.1, 0.0),
192
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), -math.pi * 0.25),
193
+ dim_x=dim_x,
194
+ dim_y=dim_y,
195
+ cell_x=1.0 / dim_x,
196
+ cell_y=1.0 / dim_y,
197
+ mass=1.0,
198
+ )
199
+
200
+ num_envs = 2
201
+ env_offsets = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])
202
+
203
+ builder_open_edge_count = np.sum(np.array(builder.edge_indices) == -1)
204
+ env_builder_open_edge_count = np.sum(np.array(env_builder.edge_indices) == -1)
205
+
206
+ for i in range(num_envs):
207
+ xform = wp.transform(env_offsets[i], wp.quat_identity())
208
+ builder.add_builder(
209
+ env_builder,
210
+ xform,
211
+ update_num_env_count=True,
212
+ separate_collision_group=True,
213
+ )
214
+
215
+ self.assertEqual(
216
+ np.sum(np.array(builder.edge_indices) == -1),
217
+ builder_open_edge_count + num_envs * env_builder_open_edge_count,
218
+ "builder does not have the expected number of open edges",
219
+ )
220
+
181
221
 
182
222
  if __name__ == "__main__":
183
223
  wp.clear_kernel_cache()
@@ -13,6 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ import platform
16
17
  import unittest
17
18
 
18
19
  import numpy as np
@@ -103,6 +104,9 @@ def test_sphere_pushing_on_rails(
103
104
  static_contacts=True,
104
105
  print_grad=False,
105
106
  ):
107
+ if platform.system() == "Darwin":
108
+ test.skipTest("Crashes on Mac runners")
109
+
106
110
  # Two spheres on a rail (prismatic or D6 joint), one is pushed, the other is passive.
107
111
  # The absolute distance to a target is measured and gradients are compared for
108
112
  # a push that is too far and too close.
@@ -18,6 +18,7 @@ import os
18
18
  import unittest
19
19
 
20
20
  import warp as wp
21
+ import warp.examples
21
22
  import warp.sim
22
23
  from warp.tests.unittest_utils import *
23
24
 
@@ -29,7 +30,7 @@ def test_fk_ik(test, device):
29
30
 
30
31
  for i in range(num_envs):
31
32
  wp.sim.parse_mjcf(
32
- os.path.join(os.path.dirname(__file__), "../examples/assets/nv_ant.xml"),
33
+ os.path.join(warp.examples.get_asset_directory(), "nv_ant.xml"),
33
34
  builder,
34
35
  stiffness=0.0,
35
36
  damping=1.0,
@@ -0,0 +1,597 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import contextlib
17
+ import io
18
+ import unittest
19
+
20
+ import warp as wp
21
+ import warp.optim
22
+ import warp.sim
23
+ import warp.sim.graph_coloring
24
+ import warp.sim.integrator_vbd
25
+ from warp.sim.model import PARTICLE_FLAG_ACTIVE
26
+ from warp.tests.unittest_utils import *
27
+
28
+ # fmt: off
29
+ CLOTH_POINTS = [
30
+ (-50.0000000, 0.0000000, -50.0000000),
31
+ (-38.8888893, 11.1111107, -50.0000000),
32
+ (-27.7777786, 22.2222214, -50.0000000),
33
+ (-16.6666679, 33.3333321, -50.0000000),
34
+ (-5.5555558, 44.4444427, -50.0000000),
35
+ (5.5555558, 55.5555573, -50.0000000),
36
+ (16.6666679, 66.6666641, -50.0000000),
37
+ (27.7777786, 77.7777786, -50.0000000),
38
+ (38.8888893, 88.8888855, -50.0000000),
39
+ (50.0000000, 100.0000000, -50.0000000),
40
+ (-50.0000000, 0.0000000, -38.8888893),
41
+ (-38.8888893, 11.1111107, -38.8888893),
42
+ (-27.7777786, 22.2222214, -38.8888893),
43
+ (-16.6666679, 33.3333321, -38.8888893),
44
+ (-5.5555558, 44.4444427, -38.8888893),
45
+ (5.5555558, 55.5555573, -38.8888893),
46
+ (16.6666679, 66.6666641, -38.8888893),
47
+ (27.7777786, 77.7777786, -38.8888893),
48
+ (38.8888893, 88.8888855, -38.8888893),
49
+ (50.0000000, 100.0000000, -38.8888893),
50
+ (-50.0000000, 0.0000000, -27.7777786),
51
+ (-38.8888893, 11.1111107, -27.7777786),
52
+ (-27.7777786, 22.2222214, -27.7777786),
53
+ (-16.6666679, 33.3333321, -27.7777786),
54
+ (-5.5555558, 44.4444427, -27.7777786),
55
+ (5.5555558, 55.5555573, -27.7777786),
56
+ (16.6666679, 66.6666641, -27.7777786),
57
+ (27.7777786, 77.7777786, -27.7777786),
58
+ (38.8888893, 88.8888855, -27.7777786),
59
+ (50.0000000, 100.0000000, -27.7777786),
60
+ (-50.0000000, 0.0000000, -16.6666679),
61
+ (-38.8888893, 11.1111107, -16.6666679),
62
+ (-27.7777786, 22.2222214, -16.6666679),
63
+ (-16.6666679, 33.3333321, -16.6666679),
64
+ (-5.5555558, 44.4444427, -16.6666679),
65
+ (5.5555558, 55.5555573, -16.6666679),
66
+ (16.6666679, 66.6666641, -16.6666679),
67
+ (27.7777786, 77.7777786, -16.6666679),
68
+ (38.8888893, 88.8888855, -16.6666679),
69
+ (50.0000000, 100.0000000, -16.6666679),
70
+ (-50.0000000, 0.0000000, -5.5555558),
71
+ (-38.8888893, 11.1111107, -5.5555558),
72
+ (-27.7777786, 22.2222214, -5.5555558),
73
+ (-16.6666679, 33.3333321, -5.5555558),
74
+ (-5.5555558, 44.4444427, -5.5555558),
75
+ (5.5555558, 55.5555573, -5.5555558),
76
+ (16.6666679, 66.6666641, -5.5555558),
77
+ (27.7777786, 77.7777786, -5.5555558),
78
+ (38.8888893, 88.8888855, -5.5555558),
79
+ (50.0000000, 100.0000000, -5.5555558),
80
+ (-50.0000000, 0.0000000, 5.5555558),
81
+ (-38.8888893, 11.1111107, 5.5555558),
82
+ (-27.7777786, 22.2222214, 5.5555558),
83
+ (-16.6666679, 33.3333321, 5.5555558),
84
+ (-5.5555558, 44.4444427, 5.5555558),
85
+ (5.5555558, 55.5555573, 5.5555558),
86
+ (16.6666679, 66.6666641, 5.5555558),
87
+ (27.7777786, 77.7777786, 5.5555558),
88
+ (38.8888893, 88.8888855, 5.5555558),
89
+ (50.0000000, 100.0000000, 5.5555558),
90
+ (-50.0000000, 0.0000000, 16.6666679),
91
+ (-38.8888893, 11.1111107, 16.6666679),
92
+ (-27.7777786, 22.2222214, 16.6666679),
93
+ (-16.6666679, 33.3333321, 16.6666679),
94
+ (-5.5555558, 44.4444427, 16.6666679),
95
+ (5.5555558, 55.5555573, 16.6666679),
96
+ (16.6666679, 66.6666641, 16.6666679),
97
+ (27.7777786, 77.7777786, 16.6666679),
98
+ (38.8888893, 88.8888855, 16.6666679),
99
+ (50.0000000, 100.0000000, 16.6666679),
100
+ (-50.0000000, 0.0000000, 27.7777786),
101
+ (-38.8888893, 11.1111107, 27.7777786),
102
+ (-27.7777786, 22.2222214, 27.7777786),
103
+ (-16.6666679, 33.3333321, 27.7777786),
104
+ (-5.5555558, 44.4444427, 27.7777786),
105
+ (5.5555558, 55.5555573, 27.7777786),
106
+ (16.6666679, 66.6666641, 27.7777786),
107
+ (27.7777786, 77.7777786, 27.7777786),
108
+ (38.8888893, 88.8888855, 27.7777786),
109
+ (50.0000000, 100.0000000, 27.7777786),
110
+ (-50.0000000, 0.0000000, 38.8888893),
111
+ (-38.8888893, 11.1111107, 38.8888893),
112
+ (-27.7777786, 22.2222214, 38.8888893),
113
+ (-16.6666679, 33.3333321, 38.8888893),
114
+ (-5.5555558, 44.4444427, 38.8888893),
115
+ (5.5555558, 55.5555573, 38.8888893),
116
+ (16.6666679, 66.6666641, 38.8888893),
117
+ (27.7777786, 77.7777786, 38.8888893),
118
+ (38.8888893, 88.8888855, 38.8888893),
119
+ (50.0000000, 100.0000000, 38.8888893),
120
+ (-50.0000000, 0.0000000, 50.0000000),
121
+ (-38.8888893, 11.1111107, 50.0000000),
122
+ (-27.7777786, 22.2222214, 50.0000000),
123
+ (-16.6666679, 33.3333321, 50.0000000),
124
+ (-5.5555558, 44.4444427, 50.0000000),
125
+ (5.5555558, 55.5555573, 50.0000000),
126
+ (16.6666679, 66.6666641, 50.0000000),
127
+ (27.7777786, 77.7777786, 50.0000000),
128
+ (38.8888893, 88.8888855, 50.0000000),
129
+ (50.0000000, 100.0000000, 50.0000000),
130
+ ]
131
+
132
+ CLOTH_FACES = [
133
+ 1, 12, 2,
134
+ 1, 11, 12,
135
+ 2, 12, 3,
136
+ 12, 13, 3,
137
+ 3, 14, 4,
138
+ 3, 13, 14,
139
+ 4, 14, 5,
140
+ 14, 15, 5,
141
+ 5, 16, 6,
142
+ 5, 15, 16,
143
+ 6, 16, 7,
144
+ 16, 17, 7,
145
+ 7, 18, 8,
146
+ 7, 17, 18,
147
+ 8, 18, 9,
148
+ 18, 19, 9,
149
+ 9, 20, 10,
150
+ 9, 19, 20,
151
+ 11, 21, 12,
152
+ 21, 22, 12,
153
+ 12, 23, 13,
154
+ 12, 22, 23,
155
+ 13, 23, 14,
156
+ 23, 24, 14,
157
+ 14, 25, 15,
158
+ 14, 24, 25,
159
+ 15, 25, 16,
160
+ 25, 26, 16,
161
+ 16, 27, 17,
162
+ 16, 26, 27,
163
+ 17, 27, 18,
164
+ 27, 28, 18,
165
+ 18, 29, 19,
166
+ 18, 28, 29,
167
+ 19, 29, 20,
168
+ 29, 30, 20,
169
+ 21, 32, 22,
170
+ 21, 31, 32,
171
+ 22, 32, 23,
172
+ 32, 33, 23,
173
+ 23, 34, 24,
174
+ 23, 33, 34,
175
+ 24, 34, 25,
176
+ 34, 35, 25,
177
+ 25, 36, 26,
178
+ 25, 35, 36,
179
+ 26, 36, 27,
180
+ 36, 37, 27,
181
+ 27, 38, 28,
182
+ 27, 37, 38,
183
+ 28, 38, 29,
184
+ 38, 39, 29,
185
+ 29, 40, 30,
186
+ 29, 39, 40,
187
+ 31, 41, 32,
188
+ 41, 42, 32,
189
+ 32, 43, 33,
190
+ 32, 42, 43,
191
+ 33, 43, 34,
192
+ 43, 44, 34,
193
+ 34, 45, 35,
194
+ 34, 44, 45,
195
+ 35, 45, 36,
196
+ 45, 46, 36,
197
+ 36, 47, 37,
198
+ 36, 46, 47,
199
+ 37, 47, 38,
200
+ 47, 48, 38,
201
+ 38, 49, 39,
202
+ 38, 48, 49,
203
+ 39, 49, 40,
204
+ 49, 50, 40,
205
+ 41, 52, 42,
206
+ 41, 51, 52,
207
+ 42, 52, 43,
208
+ 52, 53, 43,
209
+ 43, 54, 44,
210
+ 43, 53, 54,
211
+ 44, 54, 45,
212
+ 54, 55, 45,
213
+ 45, 56, 46,
214
+ 45, 55, 56,
215
+ 46, 56, 47,
216
+ 56, 57, 47,
217
+ 47, 58, 48,
218
+ 47, 57, 58,
219
+ 48, 58, 49,
220
+ 58, 59, 49,
221
+ 49, 60, 50,
222
+ 49, 59, 60,
223
+ 51, 61, 52,
224
+ 61, 62, 52,
225
+ 52, 63, 53,
226
+ 52, 62, 63,
227
+ 53, 63, 54,
228
+ 63, 64, 54,
229
+ 54, 65, 55,
230
+ 54, 64, 65,
231
+ 55, 65, 56,
232
+ 65, 66, 56,
233
+ 56, 67, 57,
234
+ 56, 66, 67,
235
+ 57, 67, 58,
236
+ 67, 68, 58,
237
+ 58, 69, 59,
238
+ 58, 68, 69,
239
+ 59, 69, 60,
240
+ 69, 70, 60,
241
+ 61, 72, 62,
242
+ 61, 71, 72,
243
+ 62, 72, 63,
244
+ 72, 73, 63,
245
+ 63, 74, 64,
246
+ 63, 73, 74,
247
+ 64, 74, 65,
248
+ 74, 75, 65,
249
+ 65, 76, 66,
250
+ 65, 75, 76,
251
+ 66, 76, 67,
252
+ 76, 77, 67,
253
+ 67, 78, 68,
254
+ 67, 77, 78,
255
+ 68, 78, 69,
256
+ 78, 79, 69,
257
+ 69, 80, 70,
258
+ 69, 79, 80,
259
+ 71, 81, 72,
260
+ 81, 82, 72,
261
+ 72, 83, 73,
262
+ 72, 82, 83,
263
+ 73, 83, 74,
264
+ 83, 84, 74,
265
+ 74, 85, 75,
266
+ 74, 84, 85,
267
+ 75, 85, 76,
268
+ 85, 86, 76,
269
+ 76, 87, 77,
270
+ 76, 86, 87,
271
+ 77, 87, 78,
272
+ 87, 88, 78,
273
+ 78, 89, 79,
274
+ 78, 88, 89,
275
+ 79, 89, 80,
276
+ 89, 90, 80,
277
+ 81, 92, 82,
278
+ 81, 91, 92,
279
+ 82, 92, 83,
280
+ 92, 93, 83,
281
+ 83, 94, 84,
282
+ 83, 93, 94,
283
+ 84, 94, 85,
284
+ 94, 95, 85,
285
+ 85, 96, 86,
286
+ 85, 95, 96,
287
+ 86, 96, 87,
288
+ 96, 97, 87,
289
+ 87, 98, 88,
290
+ 87, 97, 98,
291
+ 88, 98, 89,
292
+ 98, 99, 89,
293
+ 89, 100, 90,
294
+ 89, 99, 100
295
+ ]
296
+
297
+ # fmt: on
298
+ class VBDClothSim:
299
+ def __init__(self, device, use_cuda_graph=False):
300
+ self.frame_dt = 1 / 60
301
+ self.num_test_frames = 100
302
+ self.num_substeps = 10
303
+ self.iterations = 10
304
+ self.dt = self.frame_dt / self.num_substeps
305
+ self.device = device
306
+ self.use_cuda_graph = self.device.is_cuda and use_cuda_graph
307
+ self.builder = wp.sim.ModelBuilder()
308
+
309
+ def set_up_sagging_experiment(self):
310
+ stiffness = 1e5
311
+ kd = 1.0e-7
312
+
313
+ self.input_scale_factor = 1.0
314
+ self.renderer_scale_factor = 0.01
315
+ vertices = [wp.vec3(v) * self.input_scale_factor for v in CLOTH_POINTS]
316
+ faces_flatten = [fv - 1 for fv in CLOTH_FACES]
317
+
318
+ self.builder.add_cloth_mesh(
319
+ pos=wp.vec3(0.0, 200.0, 0.0),
320
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
321
+ scale=1.0,
322
+ vertices=vertices,
323
+ indices=faces_flatten,
324
+ vel=wp.vec3(0.0, 0.0, 0.0),
325
+ density=0.02,
326
+ tri_ke=stiffness,
327
+ tri_ka=stiffness,
328
+ tri_kd=kd,
329
+ )
330
+ self.fixed_particles = [0, 9]
331
+
332
+ def set_up_bending_experiment(self):
333
+ stretching_stiffness = 1e4
334
+ stretching_damping = 1e-6
335
+ bending_damping = 1e-3
336
+ # fmt: off
337
+ vs = [[-6.0, 0.0, -6.0], [-3.6, 0.0, -6.0], [-1.2, 0.0, -6.0], [1.2, 0.0, -6.0], [3.6, 0.0, -6.0], [6.0, 0.0, -6.0],
338
+ [-6.0, 0.0, -3.6], [-3.6, 0.0, -3.6], [-1.2, 0.0, -3.6], [1.2, 0.0, -3.6], [3.6, 0.0, -3.6], [6.0, 0.0, -3.6],
339
+ [-6.0, 0.0, -1.2], [-3.6, 0.0, -1.2], [-1.2, 0.0, -1.2], [1.2, 0.0, -1.2], [3.6, 0.0, -1.2], [6.0, 0.0, -1.2],
340
+ [-6.0, 0.0, 1.2], [-3.6, 0.0, 1.2], [-1.2, 0.0, 1.2], [1.2, 0.0, 1.2], [3.6, 0.0, 1.2], [6.0, 0.0, 1.2],
341
+ [-6.0, 0.0, 3.6], [-3.6, 0.0, 3.6], [-1.2, 0.0, 3.6], [1.2, 0.0, 3.6], [3.6, 0.0, 3.6], [6.0, 0.0, 3.6],
342
+ [-6.0, 0.0, 6.0], [-3.6, 0.0, 6.0], [-1.2, 0.0, 6.0], [1.2, 0.0, 6.0], [3.6, 0.0, 6.0], [6.0, 0.0, 6.0]]
343
+
344
+ fs = [0, 7, 1, 0, 6, 7, 1, 7, 2, 7, 8, 2, 2, 9, 3, 2, 8, 9, 3, 9, 4, 9, 10, 4, 4, 11, 5, 4, 10, 11, 6, 12, 7, 12, 13,
345
+ 7, 7, 14, 8, 7, 13, 14, 8, 14, 9, 14, 15, 9, 9, 16, 10, 9, 15, 16, 10, 16, 11, 16, 17, 11, 12, 19, 13, 12, 18,
346
+ 19, 13, 19, 14, 19, 20, 14, 14, 21, 15, 14, 20, 21, 15, 21, 16, 21, 22, 16, 16, 23, 17, 16, 22, 23, 18, 24, 19,
347
+ 24, 25, 19, 19, 26, 20, 19, 25, 26, 20, 26, 21, 26, 27, 21, 21, 28, 22, 21, 27, 28, 22, 28, 23, 28, 29, 23, 24,
348
+ 31, 25, 24, 30, 31, 25, 31, 26, 31, 32, 26, 26, 33, 27, 26, 32, 33, 27, 33, 28, 33, 34, 28, 28, 35, 29, 28, 34,
349
+ 35]
350
+ # fmt: on
351
+
352
+ vs = [wp.vec3(v) for v in vs]
353
+
354
+ self.builder.add_cloth_mesh(
355
+ pos=wp.vec3(0.0, 10.0, 0.0),
356
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
357
+ scale=1.0,
358
+ vertices=vs,
359
+ indices=fs,
360
+ vel=wp.vec3(0.0, 0.0, 0.0),
361
+ density=0.02,
362
+ tri_ke=stretching_stiffness,
363
+ tri_ka=stretching_stiffness,
364
+ tri_kd=stretching_damping,
365
+ edge_ke=10,
366
+ edge_kd=bending_damping,
367
+ )
368
+
369
+ self.builder.add_cloth_mesh(
370
+ pos=wp.vec3(15.0, 10.0, 0.0),
371
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
372
+ scale=1.0,
373
+ vertices=vs,
374
+ indices=fs,
375
+ vel=wp.vec3(0.0, 0.0, 0.0),
376
+ density=0.02,
377
+ tri_ke=stretching_stiffness,
378
+ tri_ka=stretching_stiffness,
379
+ tri_kd=stretching_damping,
380
+ edge_ke=100,
381
+ edge_kd=bending_damping,
382
+ )
383
+
384
+ self.builder.add_cloth_mesh(
385
+ pos=wp.vec3(30.0, 10.0, 0.0),
386
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
387
+ scale=1.0,
388
+ vertices=vs,
389
+ indices=fs,
390
+ vel=wp.vec3(0.0, 0.0, 0.0),
391
+ density=0.02,
392
+ tri_ke=stretching_stiffness,
393
+ tri_ka=stretching_stiffness,
394
+ tri_kd=stretching_damping,
395
+ edge_ke=1000,
396
+ edge_kd=bending_damping,
397
+ )
398
+
399
+ self.fixed_particles = [0, 29, 36, 65, 72, 101]
400
+
401
+ def set_up_non_zero_rest_angle_bending_experiment(self):
402
+ # fmt: off
403
+ vs = [
404
+ [ 0. , 10. , -10. ],
405
+ [ 0. , 10. , 10. ],
406
+ [ 7.07107, 7.07107, -10. ],
407
+ [ 7.07107, 7.07107, 10. ],
408
+ [ 10. , 0. , -10. ],
409
+ [ 10. , -0. , 10. ],
410
+ [ 7.07107, -7.07107, -10. ],
411
+ [ 7.07107, -7.07107, 10. ],
412
+ [ 0. , -10. , -10. ],
413
+ [ 0. , -10. , 10. ],
414
+ [ -7.07107, -7.07107, -10. ],
415
+ [ -7.07107, -7.07107, 10. ],
416
+ [-10. , 0. , -10. ],
417
+ [-10. , -0. , 10. ],
418
+ [ -7.07107, 7.07107, -10. ],
419
+ [ -7.07107, 7.07107, 10. ],
420
+ ]
421
+ fs = [
422
+ 1, 2, 0,
423
+ 3, 4, 2,
424
+ 5, 6, 4,
425
+ 7, 8, 6,
426
+ 9, 10, 8,
427
+ 11, 12, 10,
428
+ 3, 5, 4,
429
+ 13, 14, 12,
430
+ 15, 0, 14,
431
+ 1, 3, 2,
432
+ 5, 7, 6,
433
+ 7, 9, 8,
434
+ 9, 11, 10,
435
+ 11, 13, 12,
436
+ ]
437
+ # fmt: on
438
+
439
+ stretching_stiffness = 1e4
440
+ stretching_damping = 1e-6
441
+ edge_ke = 1000
442
+ bending_damping = 1e-2
443
+ vs = [wp.vec3(v) for v in vs]
444
+
445
+ self.builder.add_cloth_mesh(
446
+ pos=wp.vec3(0.0, 10.0, 0.0),
447
+ rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), np.pi / 2),
448
+ scale=1.0,
449
+ vertices=vs,
450
+ indices=fs,
451
+ vel=wp.vec3(0.0, 0.0, 0.0),
452
+ density=0.02,
453
+ tri_ke=stretching_stiffness,
454
+ tri_ka=stretching_stiffness,
455
+ tri_kd=stretching_damping,
456
+ edge_ke=edge_ke,
457
+ edge_kd=bending_damping,
458
+ )
459
+ self.fixed_particles = [0, 1]
460
+
461
+ def finalize(self):
462
+ self.builder.color()
463
+
464
+ self.model = self.builder.finalize(device=self.device)
465
+ self.model.ground = True
466
+ self.model.gravity = wp.vec3(0, -1000.0, 0)
467
+ self.model.soft_contact_ke = 1.0e4
468
+ self.model.soft_contact_kd = 1.0e2
469
+
470
+ self.set_points_fixed(self.model, self.fixed_particles)
471
+
472
+ self.integrator = wp.sim.VBDIntegrator(self.model, self.iterations)
473
+ self.state0 = self.model.state()
474
+ self.state1 = self.model.state()
475
+
476
+ self.init_pos = np.array(self.state0.particle_q.numpy(), copy=True)
477
+
478
+ self.graph = None
479
+ if self.use_cuda_graph:
480
+ wp.load_module(device=self.device)
481
+ wp.set_module_options({"block_dim": 256}, warp.sim.integrator_vbd)
482
+ wp.load_module(warp.sim.integrator_vbd, device=self.device)
483
+ with wp.ScopedCapture(device=self.device, force_module_load=False) as capture:
484
+ self.simulate()
485
+ self.graph = capture.graph
486
+
487
+ def simulate(self):
488
+ for _step in range(self.num_substeps * self.num_test_frames):
489
+ self.integrator.simulate(self.model, self.state0, self.state1, self.dt, None)
490
+ (self.state0, self.state1) = (self.state1, self.state0)
491
+
492
+ def run(self):
493
+ if self.graph:
494
+ wp.capture_launch(self.graph)
495
+ else:
496
+ self.simulate()
497
+
498
+ def set_points_fixed(self, model, fixed_particles):
499
+ if len(fixed_particles):
500
+ flags = model.particle_flags.numpy()
501
+ for fixed_v_id in fixed_particles:
502
+ flags[fixed_v_id] = wp.uint32(int(flags[fixed_v_id]) & ~int(PARTICLE_FLAG_ACTIVE))
503
+
504
+ model.particle_flags = wp.array(flags, device=model.device)
505
+
506
+
507
+ def test_vbd_cloth(test, device):
508
+ with contextlib.redirect_stdout(io.StringIO()) as f:
509
+ example = VBDClothSim(device)
510
+ example.set_up_bending_experiment()
511
+ example.finalize()
512
+ example.model.ground = False
513
+
514
+ test.assertRegex(
515
+ f.getvalue(),
516
+ r"Warp UserWarning: The graph is not optimizable anymore, terminated with a max/min ratio: 2.0 without reaching the target ratio: 1.1",
517
+ )
518
+
519
+ example.run()
520
+
521
+ # examine that the simulation does not explode
522
+ final_pos = example.state0.particle_q.numpy()
523
+ test.assertTrue((final_pos < 1e5).all())
524
+ # examine that the simulation have moved
525
+ test.assertTrue((example.init_pos != final_pos).any())
526
+
527
+
528
+ def test_vbd_cloth_cuda_graph(test, device):
529
+ with contextlib.redirect_stdout(io.StringIO()) as f:
530
+ example = VBDClothSim(device, use_cuda_graph=True)
531
+ example.set_up_sagging_experiment()
532
+ example.finalize()
533
+
534
+ test.assertRegex(
535
+ f.getvalue(),
536
+ r"Warp UserWarning: The graph is not optimizable anymore, terminated with a max/min ratio: 2.0 without reaching the target ratio: 1.1",
537
+ )
538
+
539
+ example.run()
540
+
541
+ # examine that the simulation does not explode
542
+ final_pos = example.state0.particle_q.numpy()
543
+ test.assertTrue((final_pos < 1e5).all())
544
+ # examine that the simulation have moved
545
+ test.assertTrue((example.init_pos != final_pos).any())
546
+
547
+
548
+ def test_vbd_bending(test, device):
549
+ example = VBDClothSim(device, use_cuda_graph=True)
550
+ example.set_up_bending_experiment()
551
+ example.finalize()
552
+
553
+ example.run()
554
+
555
+ # examine that the simulation does not explode
556
+ final_pos = example.state0.particle_q.numpy()
557
+ test.assertTrue((final_pos < 1e5).all())
558
+ # examine that the simulation have moved
559
+ test.assertTrue((example.init_pos != final_pos).any())
560
+
561
+
562
+ def test_vbd_bending_non_zero_rest_angle_bending(test, device):
563
+ example = VBDClothSim(device, use_cuda_graph=True)
564
+ example.set_up_non_zero_rest_angle_bending_experiment()
565
+ example.finalize()
566
+ example.run()
567
+
568
+ # examine that the simulation does not explode
569
+ final_pos = example.state0.particle_q.numpy()
570
+ test.assertTrue((final_pos < 1e5).all())
571
+ # examine that the simulation have moved
572
+ test.assertTrue((example.init_pos != final_pos).any())
573
+
574
+
575
+ devices = get_test_devices()
576
+ cuda_devices = get_selected_cuda_test_devices()
577
+
578
+
579
+ class TestVbd(unittest.TestCase):
580
+ pass
581
+
582
+
583
+ add_function_test(TestVbd, "test_vbd_cloth", test_vbd_cloth, devices=devices)
584
+ add_function_test(TestVbd, "test_vbd_cloth_cuda_graph", test_vbd_cloth_cuda_graph, devices=cuda_devices)
585
+ add_function_test(TestVbd, "test_vbd_bending", test_vbd_bending, devices=devices, check_output=False)
586
+ add_function_test(
587
+ TestVbd,
588
+ "test_vbd_bending_non_zero_rest_angle_bending",
589
+ test_vbd_bending_non_zero_rest_angle_bending,
590
+ devices=devices,
591
+ check_output=False,
592
+ )
593
+
594
+
595
+ if __name__ == "__main__":
596
+ wp.clear_kernel_cache()
597
+ unittest.main(verbosity=2)