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