warp-lang 1.7.2rc1__py3-none-macosx_10_13_universal2.whl → 1.8.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 (192) hide show
  1. warp/__init__.py +3 -1
  2. warp/__init__.pyi +3489 -1
  3. warp/autograd.py +45 -122
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +241 -252
  6. warp/build_dll.py +130 -26
  7. warp/builtins.py +1907 -384
  8. warp/codegen.py +272 -104
  9. warp/config.py +12 -1
  10. warp/constants.py +1 -1
  11. warp/context.py +770 -238
  12. warp/dlpack.py +1 -1
  13. warp/examples/benchmarks/benchmark_cloth.py +2 -2
  14. warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
  15. warp/examples/core/example_sample_mesh.py +1 -1
  16. warp/examples/core/example_spin_lock.py +93 -0
  17. warp/examples/core/example_work_queue.py +118 -0
  18. warp/examples/fem/example_adaptive_grid.py +5 -5
  19. warp/examples/fem/example_apic_fluid.py +1 -1
  20. warp/examples/fem/example_burgers.py +1 -1
  21. warp/examples/fem/example_convection_diffusion.py +9 -6
  22. warp/examples/fem/example_darcy_ls_optimization.py +489 -0
  23. warp/examples/fem/example_deformed_geometry.py +1 -1
  24. warp/examples/fem/example_diffusion.py +2 -2
  25. warp/examples/fem/example_diffusion_3d.py +1 -1
  26. warp/examples/fem/example_distortion_energy.py +1 -1
  27. warp/examples/fem/example_elastic_shape_optimization.py +387 -0
  28. warp/examples/fem/example_magnetostatics.py +5 -3
  29. warp/examples/fem/example_mixed_elasticity.py +5 -3
  30. warp/examples/fem/example_navier_stokes.py +11 -9
  31. warp/examples/fem/example_nonconforming_contact.py +5 -3
  32. warp/examples/fem/example_streamlines.py +8 -3
  33. warp/examples/fem/utils.py +9 -8
  34. warp/examples/interop/example_jax_callable.py +34 -4
  35. warp/examples/interop/example_jax_ffi_callback.py +2 -2
  36. warp/examples/interop/example_jax_kernel.py +27 -1
  37. warp/examples/optim/example_drone.py +1 -1
  38. warp/examples/sim/example_cloth.py +1 -1
  39. warp/examples/sim/example_cloth_self_contact.py +48 -54
  40. warp/examples/tile/example_tile_block_cholesky.py +502 -0
  41. warp/examples/tile/example_tile_cholesky.py +2 -1
  42. warp/examples/tile/example_tile_convolution.py +1 -1
  43. warp/examples/tile/example_tile_filtering.py +1 -1
  44. warp/examples/tile/example_tile_matmul.py +1 -1
  45. warp/examples/tile/example_tile_mlp.py +2 -0
  46. warp/fabric.py +7 -7
  47. warp/fem/__init__.py +5 -0
  48. warp/fem/adaptivity.py +1 -1
  49. warp/fem/cache.py +152 -63
  50. warp/fem/dirichlet.py +2 -2
  51. warp/fem/domain.py +136 -6
  52. warp/fem/field/field.py +141 -99
  53. warp/fem/field/nodal_field.py +85 -39
  54. warp/fem/field/virtual.py +99 -52
  55. warp/fem/geometry/adaptive_nanogrid.py +91 -86
  56. warp/fem/geometry/closest_point.py +13 -0
  57. warp/fem/geometry/deformed_geometry.py +102 -40
  58. warp/fem/geometry/element.py +56 -2
  59. warp/fem/geometry/geometry.py +323 -22
  60. warp/fem/geometry/grid_2d.py +157 -62
  61. warp/fem/geometry/grid_3d.py +116 -20
  62. warp/fem/geometry/hexmesh.py +86 -20
  63. warp/fem/geometry/nanogrid.py +166 -86
  64. warp/fem/geometry/partition.py +59 -25
  65. warp/fem/geometry/quadmesh.py +86 -135
  66. warp/fem/geometry/tetmesh.py +47 -119
  67. warp/fem/geometry/trimesh.py +77 -270
  68. warp/fem/integrate.py +181 -95
  69. warp/fem/linalg.py +25 -58
  70. warp/fem/operator.py +124 -27
  71. warp/fem/quadrature/pic_quadrature.py +36 -14
  72. warp/fem/quadrature/quadrature.py +40 -16
  73. warp/fem/space/__init__.py +1 -1
  74. warp/fem/space/basis_function_space.py +66 -46
  75. warp/fem/space/basis_space.py +17 -4
  76. warp/fem/space/dof_mapper.py +1 -1
  77. warp/fem/space/function_space.py +2 -2
  78. warp/fem/space/grid_2d_function_space.py +4 -1
  79. warp/fem/space/hexmesh_function_space.py +4 -2
  80. warp/fem/space/nanogrid_function_space.py +3 -1
  81. warp/fem/space/partition.py +11 -2
  82. warp/fem/space/quadmesh_function_space.py +4 -1
  83. warp/fem/space/restriction.py +5 -2
  84. warp/fem/space/shape/__init__.py +10 -8
  85. warp/fem/space/tetmesh_function_space.py +4 -1
  86. warp/fem/space/topology.py +52 -21
  87. warp/fem/space/trimesh_function_space.py +4 -1
  88. warp/fem/utils.py +53 -8
  89. warp/jax.py +1 -2
  90. warp/jax_experimental/ffi.py +210 -67
  91. warp/jax_experimental/xla_ffi.py +37 -24
  92. warp/math.py +171 -1
  93. warp/native/array.h +103 -4
  94. warp/native/builtin.h +182 -35
  95. warp/native/coloring.cpp +6 -2
  96. warp/native/cuda_util.cpp +1 -1
  97. warp/native/exports.h +118 -63
  98. warp/native/intersect.h +5 -5
  99. warp/native/mat.h +8 -13
  100. warp/native/mathdx.cpp +11 -5
  101. warp/native/matnn.h +1 -123
  102. warp/native/mesh.h +1 -1
  103. warp/native/quat.h +34 -6
  104. warp/native/rand.h +7 -7
  105. warp/native/sparse.cpp +121 -258
  106. warp/native/sparse.cu +181 -274
  107. warp/native/spatial.h +305 -17
  108. warp/native/svd.h +23 -8
  109. warp/native/tile.h +603 -73
  110. warp/native/tile_radix_sort.h +1112 -0
  111. warp/native/tile_reduce.h +239 -13
  112. warp/native/tile_scan.h +240 -0
  113. warp/native/tuple.h +189 -0
  114. warp/native/vec.h +10 -20
  115. warp/native/warp.cpp +36 -4
  116. warp/native/warp.cu +588 -52
  117. warp/native/warp.h +47 -74
  118. warp/optim/linear.py +5 -1
  119. warp/paddle.py +7 -8
  120. warp/py.typed +0 -0
  121. warp/render/render_opengl.py +110 -80
  122. warp/render/render_usd.py +124 -62
  123. warp/sim/__init__.py +9 -0
  124. warp/sim/collide.py +253 -80
  125. warp/sim/graph_coloring.py +8 -1
  126. warp/sim/import_mjcf.py +4 -3
  127. warp/sim/import_usd.py +11 -7
  128. warp/sim/integrator.py +5 -2
  129. warp/sim/integrator_euler.py +1 -1
  130. warp/sim/integrator_featherstone.py +1 -1
  131. warp/sim/integrator_vbd.py +761 -322
  132. warp/sim/integrator_xpbd.py +1 -1
  133. warp/sim/model.py +265 -260
  134. warp/sim/utils.py +10 -7
  135. warp/sparse.py +303 -166
  136. warp/tape.py +54 -51
  137. warp/tests/cuda/test_conditional_captures.py +1046 -0
  138. warp/tests/cuda/test_streams.py +1 -1
  139. warp/tests/geometry/test_volume.py +2 -2
  140. warp/tests/interop/test_dlpack.py +9 -9
  141. warp/tests/interop/test_jax.py +0 -1
  142. warp/tests/run_coverage_serial.py +1 -1
  143. warp/tests/sim/disabled_kinematics.py +2 -2
  144. warp/tests/sim/{test_vbd.py → test_cloth.py} +378 -112
  145. warp/tests/sim/test_collision.py +159 -51
  146. warp/tests/sim/test_coloring.py +91 -2
  147. warp/tests/test_array.py +254 -2
  148. warp/tests/test_array_reduce.py +2 -2
  149. warp/tests/test_assert.py +53 -0
  150. warp/tests/test_atomic_cas.py +312 -0
  151. warp/tests/test_codegen.py +142 -19
  152. warp/tests/test_conditional.py +47 -1
  153. warp/tests/test_ctypes.py +0 -20
  154. warp/tests/test_devices.py +8 -0
  155. warp/tests/test_fabricarray.py +4 -2
  156. warp/tests/test_fem.py +58 -25
  157. warp/tests/test_func.py +42 -1
  158. warp/tests/test_grad.py +1 -1
  159. warp/tests/test_lerp.py +1 -3
  160. warp/tests/test_map.py +481 -0
  161. warp/tests/test_mat.py +23 -24
  162. warp/tests/test_quat.py +28 -15
  163. warp/tests/test_rounding.py +10 -38
  164. warp/tests/test_runlength_encode.py +7 -7
  165. warp/tests/test_smoothstep.py +1 -1
  166. warp/tests/test_sparse.py +83 -2
  167. warp/tests/test_spatial.py +507 -1
  168. warp/tests/test_static.py +48 -0
  169. warp/tests/test_struct.py +2 -2
  170. warp/tests/test_tape.py +38 -0
  171. warp/tests/test_tuple.py +265 -0
  172. warp/tests/test_types.py +2 -2
  173. warp/tests/test_utils.py +24 -18
  174. warp/tests/test_vec.py +38 -408
  175. warp/tests/test_vec_constructors.py +325 -0
  176. warp/tests/tile/test_tile.py +438 -131
  177. warp/tests/tile/test_tile_mathdx.py +518 -14
  178. warp/tests/tile/test_tile_matmul.py +179 -0
  179. warp/tests/tile/test_tile_reduce.py +307 -5
  180. warp/tests/tile/test_tile_shared_memory.py +136 -7
  181. warp/tests/tile/test_tile_sort.py +121 -0
  182. warp/tests/unittest_suites.py +14 -6
  183. warp/types.py +462 -308
  184. warp/utils.py +647 -86
  185. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/METADATA +20 -6
  186. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/RECORD +189 -175
  187. warp/stubs.py +0 -3381
  188. warp/tests/sim/test_xpbd.py +0 -399
  189. warp/tests/test_mlp.py +0 -282
  190. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/WHEEL +0 -0
  191. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/licenses/LICENSE.md +0 -0
  192. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/top_level.txt +0 -0
warp/tape.py CHANGED
@@ -13,8 +13,9 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ from __future__ import annotations
17
+
16
18
  from collections import defaultdict, namedtuple
17
- from typing import Dict, List
18
19
 
19
20
  import warp as wp
20
21
 
@@ -77,22 +78,21 @@ class Tape:
77
78
  #
78
79
  # adj_tensor = tape.gradients[tensor]
79
80
  #
80
- def backward(self, loss: wp.array = None, grads: dict = None):
81
- """
82
- Evaluate the backward pass of the recorded operations on the tape.
81
+ def backward(self, loss: wp.array | None = None, grads: dict[wp.array, wp.array] | None = None):
82
+ """Evaluate the backward pass of the recorded operations on the tape.
83
+
83
84
  A single-element array ``loss`` or a dictionary of arrays ``grads``
84
85
  can be provided to assign the incoming gradients for the reverse-mode
85
86
  automatic differentiation pass.
86
87
 
87
88
  Args:
88
- loss (wp.array): A single-element array that holds the loss function value whose gradient is to be computed
89
- grads (dict): A dictionary of arrays that map from Warp arrays to their incoming gradients
90
-
89
+ loss: A single-element array that holds the loss function value whose gradient is to be computed
90
+ grads: A dictionary of arrays that map from Warp arrays to their incoming gradients
91
91
  """
92
92
  # if scalar loss is specified then initialize
93
93
  # a 'seed' array for it, with gradient of one
94
94
  if loss:
95
- if loss.size > 1 or wp.types.type_length(loss.dtype) > 1:
95
+ if loss.size > 1 or wp.types.type_size(loss.dtype) > 1:
96
96
  raise RuntimeError("Can only return gradients for scalar loss functions.")
97
97
 
98
98
  if not loss.requires_grad:
@@ -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
 
@@ -291,20 +293,19 @@ class Tape:
291
293
 
292
294
  def visualize(
293
295
  self,
294
- filename: str = None,
295
- simplify_graph=True,
296
- hide_readonly_arrays=False,
297
- array_labels: Dict[wp.array, str] = None,
296
+ filename: str | None = None,
297
+ simplify_graph: bool = True,
298
+ hide_readonly_arrays: bool = False,
299
+ array_labels: dict[wp.array, str] | None = None,
298
300
  choose_longest_node_name: bool = True,
299
301
  ignore_graph_scopes: bool = False,
300
- track_inputs: List[wp.array] = None,
301
- track_outputs: List[wp.array] = None,
302
- track_input_names: List[str] = None,
303
- track_output_names: List[str] = None,
302
+ track_inputs: list[wp.array] | None = None,
303
+ track_outputs: list[wp.array] | None = None,
304
+ track_input_names: list[str] | None = None,
305
+ track_output_names: list[str] | None = None,
304
306
  graph_direction: str = "LR",
305
307
  ) -> str:
306
- """
307
- Visualize the recorded operations on the tape as a `GraphViz diagram <https://graphviz.org/>`_.
308
+ """Visualize the recorded operations on the tape as a `GraphViz diagram <https://graphviz.org/>`_.
308
309
 
309
310
  Example
310
311
  -------
@@ -327,22 +328,22 @@ class Tape:
327
328
  dot -Tpng tape.dot -o tape.png
328
329
 
329
330
  Args:
330
- filename (str): The filename to save the visualization to (optional).
331
- simplify_graph (bool): If True, simplify the graph by detecting repeated kernel launch sequences and summarizing them in subgraphs.
332
- hide_readonly_arrays (bool): If True, hide arrays that are not modified by any kernel launch.
333
- array_labels (Dict[wp.array, str]): A dictionary mapping arrays to custom labels.
334
- choose_longest_node_name (bool): If True, the automatic name resolution will aim to find the longest name for each array in the computation graph.
335
- ignore_graph_scopes (bool): If True, ignore the scopes recorded on the tape when visualizing the graph.
336
- track_inputs (List[wp.array]): A list of arrays to track as inputs in the graph to ensure they are shown regardless of the `hide_readonly_arrays` setting.
337
- track_outputs (List[wp.array]): A list of arrays to track as outputs in the graph so that they remain visible.
338
- track_input_names (List[str]): A list of custom names for the input arrays to track in the graph (used in conjunction with `track_inputs`).
339
- track_output_names (List[str]): A list of custom names for the output arrays to track in the graph (used in conjunction with `track_outputs`).
340
- graph_direction (str): The direction of the graph layout (default: "LR").
331
+ filename: The filename to save the visualization to (optional).
332
+ simplify_graph: If True, simplify the graph by detecting repeated kernel launch sequences and summarizing them in subgraphs.
333
+ hide_readonly_arrays: If True, hide arrays that are not modified by any kernel launch.
334
+ array_labels: A dictionary mapping arrays to custom labels.
335
+ choose_longest_node_name: If True, the automatic name resolution will aim to find the longest name for each array in the computation graph.
336
+ ignore_graph_scopes: If True, ignore the scopes recorded on the tape when visualizing the graph.
337
+ track_inputs: A list of arrays to track as inputs in the graph to ensure they are shown regardless of the `hide_readonly_arrays` setting.
338
+ track_outputs: A list of arrays to track as outputs in the graph so that they remain visible.
339
+ track_input_names: A list of custom names for the input arrays to track in the graph (used in conjunction with `track_inputs`).
340
+ track_output_names: A list of custom names for the output arrays to track in the graph (used in conjunction with `track_outputs`).
341
+ graph_direction: The direction of the graph layout (default: "LR").
341
342
 
342
343
  Returns:
343
344
  str: The dot code representing the graph.
344
-
345
345
  """
346
+
346
347
  if track_output_names is None:
347
348
  track_output_names = []
348
349
  if track_input_names is None:
@@ -370,7 +371,7 @@ class Tape:
370
371
 
371
372
 
372
373
  class TapeVisitor:
373
- def emit_array_node(self, arr: wp.array, label: str, active_scope_stack: List[str], indent_level: int):
374
+ def emit_array_node(self, arr: wp.array, label: str, active_scope_stack: list[str], indent_level: int):
374
375
  pass
375
376
 
376
377
  def emit_kernel_launch_node(
@@ -441,7 +442,7 @@ class GraphvizTapeVisitor(TapeVisitor):
441
442
  type_str = type_str.split("'")[1]
442
443
  return type_str
443
444
 
444
- def emit_array_node(self, arr: wp.array, label: str, active_scope_stack: List[str], indent_level: int):
445
+ def emit_array_node(self, arr: wp.array, label: str, active_scope_stack: list[str], indent_level: int):
445
446
  if arr.ptr in self.array_nodes:
446
447
  return
447
448
  if arr.ptr in self.pointer_to_port:
@@ -462,7 +463,9 @@ class GraphvizTapeVisitor(TapeVisitor):
462
463
  # type_str = self.sanitize(type_str)
463
464
  # class_name = "array" if not arr.requires_grad else "array_grad"
464
465
  # self.graphviz_lines.append(chart_indent + f'{arr_id}(["`{label}`"]):::{class_name}')
465
- tooltip = f"Array {label} / ptr={arr.ptr}, shape={str(arr.shape)}, dtype={type_str}, requires_grad={arr.requires_grad}"
466
+ tooltip = (
467
+ f"Array {label} / ptr={arr.ptr}, shape={arr.shape}, dtype={type_str}, requires_grad={arr.requires_grad}"
468
+ )
466
469
  options.append(f'tooltip="{tooltip}"')
467
470
  # self.graphviz_lines.append(chart_indent + f'click {arr_id} callback "{tooltip}"')
468
471
  # self.max_indent = max(self.max_indent, indent_level)
@@ -594,7 +597,7 @@ class ArrayStatsVisitor(TapeVisitor):
594
597
  self.array_value_stats = []
595
598
  self.array_grad_stats = []
596
599
 
597
- def emit_array_node(self, arr: wp.array, label: str, active_scope_stack: List[str], indent_level: int):
600
+ def emit_array_node(self, arr: wp.array, label: str, active_scope_stack: list[str], indent_level: int):
598
601
  if arr.device.is_capturing:
599
602
  raise RuntimeError("Cannot record arrays while graph capturing is active.")
600
603
  self.array_names[arr.ptr] = label
@@ -631,15 +634,15 @@ RepeatedSequence = namedtuple("RepeatedSequence", ["start", "end", "repetitions"
631
634
  def visit_tape(
632
635
  tape: Tape,
633
636
  visitor: TapeVisitor,
634
- simplify_graph=True,
635
- hide_readonly_arrays=False,
636
- array_labels: Dict[wp.array, str] = None,
637
+ simplify_graph: bool = True,
638
+ hide_readonly_arrays: bool = False,
639
+ array_labels: dict[wp.array, str] | None = None,
637
640
  choose_longest_node_name: bool = True,
638
641
  ignore_graph_scopes: bool = False,
639
- track_inputs: List[wp.array] = None,
640
- track_outputs: List[wp.array] = None,
641
- track_input_names: List[str] = None,
642
- track_output_names: List[str] = None,
642
+ track_inputs: list[wp.array] | None = None,
643
+ track_outputs: list[wp.array] | None = None,
644
+ track_input_names: list[str] | None = None,
645
+ track_output_names: list[str] | None = None,
643
646
  ):
644
647
  if track_output_names is None:
645
648
  track_output_names = []
@@ -697,7 +700,7 @@ def visit_tape(
697
700
  ]
698
701
  launch_ids = [get_launch_id(launch) for launch in kernel_launches]
699
702
 
700
- def get_repeating_sequences(sequence: List[str]):
703
+ def get_repeating_sequences(sequence: list[str]):
701
704
  # yield all consecutively repeating subsequences in descending order of length
702
705
  for length in range(len(sequence) // 2 + 1, 0, -1):
703
706
  for start in range(len(sequence) - length):
@@ -725,7 +728,7 @@ def visit_tape(
725
728
  yield candidate
726
729
  break
727
730
 
728
- def process_sequence(sequence: List[str]) -> RepeatedSequence:
731
+ def process_sequence(sequence: list[str]) -> RepeatedSequence | None:
729
732
  # find the longest contiguous repetition in the sequence
730
733
  if len(sequence) < 2:
731
734
  return None
@@ -1149,17 +1152,17 @@ def visit_tape(
1149
1152
  def visualize_tape_graphviz(
1150
1153
  tape: Tape,
1151
1154
  filename: str,
1152
- simplify_graph=True,
1153
- hide_readonly_arrays=False,
1154
- array_labels: Dict[wp.array, str] = None,
1155
+ simplify_graph: bool = True,
1156
+ hide_readonly_arrays: bool = False,
1157
+ array_labels: dict[wp.array, str] | None = None,
1155
1158
  choose_longest_node_name: bool = True,
1156
1159
  ignore_graph_scopes: bool = False,
1157
- track_inputs: List[wp.array] = None,
1158
- track_outputs: List[wp.array] = None,
1159
- track_input_names: List[str] = None,
1160
- track_output_names: List[str] = None,
1160
+ track_inputs: list[wp.array] | None = None,
1161
+ track_outputs: list[wp.array] | None = None,
1162
+ track_input_names: list[str] | None = None,
1163
+ track_output_names: list[str] | None = None,
1161
1164
  graph_direction: str = "LR",
1162
- ):
1165
+ ) -> str:
1163
1166
  if track_output_names is None:
1164
1167
  track_output_names = []
1165
1168
  if track_input_names is None: