warp-lang 1.4.2__py3-none-macosx_10_13_universal2.whl → 1.5.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 (158) hide show
  1. warp/__init__.py +4 -0
  2. warp/autograd.py +43 -8
  3. warp/bin/libwarp-clang.dylib +0 -0
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +21 -2
  6. warp/build_dll.py +23 -6
  7. warp/builtins.py +1783 -2
  8. warp/codegen.py +177 -45
  9. warp/config.py +2 -2
  10. warp/context.py +321 -73
  11. warp/examples/assets/pixel.jpg +0 -0
  12. warp/examples/benchmarks/benchmark_cloth_paddle.py +86 -0
  13. warp/examples/benchmarks/benchmark_gemm.py +121 -0
  14. warp/examples/benchmarks/benchmark_interop_paddle.py +158 -0
  15. warp/examples/benchmarks/benchmark_tile.py +179 -0
  16. warp/examples/fem/example_adaptive_grid.py +37 -10
  17. warp/examples/fem/example_apic_fluid.py +3 -2
  18. warp/examples/fem/example_convection_diffusion_dg.py +4 -5
  19. warp/examples/fem/example_deformed_geometry.py +1 -1
  20. warp/examples/fem/example_diffusion_3d.py +47 -4
  21. warp/examples/fem/example_distortion_energy.py +220 -0
  22. warp/examples/fem/example_magnetostatics.py +127 -85
  23. warp/examples/fem/example_nonconforming_contact.py +5 -5
  24. warp/examples/fem/example_stokes.py +3 -1
  25. warp/examples/fem/example_streamlines.py +12 -19
  26. warp/examples/fem/utils.py +38 -15
  27. warp/examples/sim/example_cloth.py +2 -25
  28. warp/examples/sim/example_quadruped.py +2 -1
  29. warp/examples/tile/example_tile_convolution.py +58 -0
  30. warp/examples/tile/example_tile_fft.py +47 -0
  31. warp/examples/tile/example_tile_filtering.py +105 -0
  32. warp/examples/tile/example_tile_matmul.py +79 -0
  33. warp/examples/tile/example_tile_mlp.py +375 -0
  34. warp/fem/__init__.py +8 -0
  35. warp/fem/cache.py +16 -12
  36. warp/fem/dirichlet.py +1 -1
  37. warp/fem/domain.py +44 -1
  38. warp/fem/field/__init__.py +1 -2
  39. warp/fem/field/field.py +31 -19
  40. warp/fem/field/nodal_field.py +101 -49
  41. warp/fem/field/virtual.py +794 -0
  42. warp/fem/geometry/__init__.py +2 -2
  43. warp/fem/geometry/deformed_geometry.py +3 -105
  44. warp/fem/geometry/element.py +13 -0
  45. warp/fem/geometry/geometry.py +165 -5
  46. warp/fem/geometry/grid_2d.py +3 -6
  47. warp/fem/geometry/grid_3d.py +31 -28
  48. warp/fem/geometry/hexmesh.py +3 -46
  49. warp/fem/geometry/nanogrid.py +3 -2
  50. warp/fem/geometry/{quadmesh_2d.py → quadmesh.py} +280 -159
  51. warp/fem/geometry/tetmesh.py +2 -43
  52. warp/fem/geometry/{trimesh_2d.py → trimesh.py} +354 -186
  53. warp/fem/integrate.py +683 -261
  54. warp/fem/linalg.py +404 -0
  55. warp/fem/operator.py +101 -18
  56. warp/fem/polynomial.py +5 -5
  57. warp/fem/quadrature/quadrature.py +45 -21
  58. warp/fem/space/__init__.py +45 -11
  59. warp/fem/space/basis_function_space.py +451 -0
  60. warp/fem/space/basis_space.py +58 -11
  61. warp/fem/space/function_space.py +146 -5
  62. warp/fem/space/grid_2d_function_space.py +80 -66
  63. warp/fem/space/grid_3d_function_space.py +113 -68
  64. warp/fem/space/hexmesh_function_space.py +96 -108
  65. warp/fem/space/nanogrid_function_space.py +62 -110
  66. warp/fem/space/quadmesh_function_space.py +208 -0
  67. warp/fem/space/shape/__init__.py +45 -7
  68. warp/fem/space/shape/cube_shape_function.py +328 -54
  69. warp/fem/space/shape/shape_function.py +10 -1
  70. warp/fem/space/shape/square_shape_function.py +328 -60
  71. warp/fem/space/shape/tet_shape_function.py +269 -19
  72. warp/fem/space/shape/triangle_shape_function.py +238 -19
  73. warp/fem/space/tetmesh_function_space.py +69 -37
  74. warp/fem/space/topology.py +38 -0
  75. warp/fem/space/trimesh_function_space.py +179 -0
  76. warp/fem/utils.py +6 -331
  77. warp/jax_experimental.py +3 -1
  78. warp/native/array.h +15 -0
  79. warp/native/builtin.h +66 -26
  80. warp/native/bvh.h +4 -0
  81. warp/native/coloring.cpp +600 -0
  82. warp/native/cuda_util.cpp +14 -0
  83. warp/native/cuda_util.h +2 -1
  84. warp/native/fabric.h +8 -0
  85. warp/native/hashgrid.h +4 -0
  86. warp/native/marching.cu +8 -0
  87. warp/native/mat.h +14 -3
  88. warp/native/mathdx.cpp +59 -0
  89. warp/native/mesh.h +4 -0
  90. warp/native/range.h +13 -1
  91. warp/native/reduce.cpp +9 -1
  92. warp/native/reduce.cu +7 -0
  93. warp/native/runlength_encode.cpp +9 -1
  94. warp/native/runlength_encode.cu +7 -1
  95. warp/native/scan.cpp +8 -0
  96. warp/native/scan.cu +8 -0
  97. warp/native/scan.h +8 -1
  98. warp/native/sparse.cpp +8 -0
  99. warp/native/sparse.cu +8 -0
  100. warp/native/temp_buffer.h +7 -0
  101. warp/native/tile.h +1857 -0
  102. warp/native/tile_gemm.h +341 -0
  103. warp/native/tile_reduce.h +210 -0
  104. warp/native/volume_builder.cu +8 -0
  105. warp/native/volume_builder.h +8 -0
  106. warp/native/warp.cpp +10 -2
  107. warp/native/warp.cu +369 -15
  108. warp/native/warp.h +12 -2
  109. warp/optim/adam.py +39 -4
  110. warp/paddle.py +29 -12
  111. warp/render/render_opengl.py +137 -65
  112. warp/sim/graph_coloring.py +292 -0
  113. warp/sim/integrator_euler.py +4 -2
  114. warp/sim/integrator_featherstone.py +115 -44
  115. warp/sim/integrator_vbd.py +6 -0
  116. warp/sim/model.py +88 -15
  117. warp/stubs.py +569 -4
  118. warp/tape.py +12 -7
  119. warp/tests/assets/pixel.npy +0 -0
  120. warp/tests/aux_test_instancing_gc.py +18 -0
  121. warp/tests/test_array.py +39 -0
  122. warp/tests/test_codegen.py +81 -1
  123. warp/tests/test_codegen_instancing.py +30 -0
  124. warp/tests/test_collision.py +110 -0
  125. warp/tests/test_coloring.py +241 -0
  126. warp/tests/test_context.py +34 -0
  127. warp/tests/test_examples.py +18 -4
  128. warp/tests/test_fem.py +453 -113
  129. warp/tests/test_func.py +13 -0
  130. warp/tests/test_generics.py +52 -0
  131. warp/tests/test_iter.py +68 -0
  132. warp/tests/test_mat_scalar_ops.py +1 -1
  133. warp/tests/test_mesh_query_point.py +1 -1
  134. warp/tests/test_module_hashing.py +23 -0
  135. warp/tests/test_paddle.py +27 -87
  136. warp/tests/test_print.py +56 -1
  137. warp/tests/test_spatial.py +1 -1
  138. warp/tests/test_tile.py +700 -0
  139. warp/tests/test_tile_mathdx.py +144 -0
  140. warp/tests/test_tile_mlp.py +383 -0
  141. warp/tests/test_tile_reduce.py +374 -0
  142. warp/tests/test_tile_shared_memory.py +190 -0
  143. warp/tests/test_vbd.py +12 -20
  144. warp/tests/test_volume.py +43 -0
  145. warp/tests/unittest_suites.py +19 -2
  146. warp/tests/unittest_utils.py +4 -0
  147. warp/types.py +338 -72
  148. warp/utils.py +22 -1
  149. {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/METADATA +33 -7
  150. {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/RECORD +153 -126
  151. {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/WHEEL +1 -1
  152. warp/fem/field/test.py +0 -180
  153. warp/fem/field/trial.py +0 -183
  154. warp/fem/space/collocated_function_space.py +0 -102
  155. warp/fem/space/quadmesh_2d_function_space.py +0 -261
  156. warp/fem/space/trimesh_2d_function_space.py +0 -153
  157. {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/LICENSE.md +0 -0
  158. {warp_lang-1.4.2.dist-info → warp_lang-1.5.0.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,8 @@ import warp as wp
4
4
  from warp.fem import cache
5
5
  from warp.fem.types import Coords
6
6
 
7
+ from .shape_function import ShapeFunction
8
+
7
9
 
8
10
  def _tet_node_index(tx: int, ty: int, tz: int, degree: int):
9
11
  from .triangle_shape_function import _triangle_node_index
@@ -91,18 +93,79 @@ def _tet_node_index(tx: int, ty: int, tz: int, degree: int):
91
93
  return VERTEX_EDGE_FACE_NODE_COUNT + _tet_node_index(tx - 1, ty - 1, tz - 1, degree - 4)
92
94
 
93
95
 
94
- class TetrahedronPolynomialShapeFunctions:
96
+ class TetrahedronShapeFunction(ShapeFunction):
95
97
  VERTEX = wp.constant(0)
96
98
  EDGE = wp.constant(1)
97
99
  FACE = wp.constant(2)
98
100
  INTERIOR = wp.constant(3)
99
101
 
102
+ VERTEX_NODE_COUNT: int
103
+ """Number of shape function nodes per vertex"""
104
+
105
+ EDGE_NODE_COUNT: int
106
+ """Number of shape function nodes per tet edge (excluding vertex nodes)"""
107
+
108
+ FACE_NODE_COUNT: int
109
+ """Number of shape function nodes per tet face (excluding edge and vertex nodes)"""
110
+
111
+ INTERIOR_NODE_COUNT: int
112
+ """Number of shape function nodes per tet (excluding face, edge and vertex nodes)"""
113
+
114
+ @staticmethod
115
+ def node_type_and_index(node_index_in_elt: int):
116
+ pass
117
+
118
+ @wp.func
119
+ def edge_vidx(edge: int):
120
+ if edge < 3:
121
+ c1 = edge
122
+ c2 = (edge + 1) % 3
123
+ else:
124
+ c1 = edge - 3
125
+ c2 = 3
126
+ return c1, c2
127
+
128
+ @wp.func
129
+ def opposite_edge_vidx(edge: int):
130
+ if edge < 3:
131
+ e1 = (edge + 2) % 3
132
+ e2 = 3
133
+ else:
134
+ e1 = (edge - 2) % 3
135
+ e2 = (edge - 1) % 3
136
+ return e1, e2
137
+
138
+ @wp.func
139
+ def _vertex_coords(vidx: int):
140
+ return wp.vec3(
141
+ float(vidx == 1),
142
+ float(vidx == 2),
143
+ float(vidx == 3),
144
+ )
145
+
146
+
147
+ class TetrahedronPolynomialShapeFunctions(TetrahedronShapeFunction):
100
148
  def __init__(self, degree: int):
101
149
  self.ORDER = wp.constant(degree)
102
150
 
103
151
  self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) * (degree + 3) // 6)
104
152
  self.NODES_PER_SIDE = wp.constant((degree + 1) * (degree + 2) // 2)
105
153
 
154
+ self.VERTEX_NODE_COUNT = wp.constant(1)
155
+ self.EDGE_NODE_COUNT = wp.constant(degree - 1)
156
+ self.NODES_PER_ELEMENT = wp.constant((degree + 1) * (degree + 2) * (degree + 3) // 6)
157
+ self.NODES_PER_SIDE = wp.constant((degree + 1) * (degree + 2) // 2)
158
+
159
+ self.SIDE_NODE_COUNT = wp.constant(self.NODES_PER_ELEMENT - 3 * (self.VERTEX_NODE_COUNT + self.EDGE_NODE_COUNT))
160
+ self.INTERIOR_NODE_COUNT = wp.constant(
161
+ self.NODES_PER_ELEMENT - 3 * (self.VERTEX_NODE_COUNT + self.EDGE_NODE_COUNT)
162
+ )
163
+
164
+ self.VERTEX_NODE_COUNT = wp.constant(1)
165
+ self.EDGE_NODE_COUNT = wp.constant(degree - 1)
166
+ self.FACE_NODE_COUNT = wp.constant(max(0, degree - 2) * max(0, degree - 1) // 2)
167
+ self.INERIOR_NODE_COUNT = wp.constant(max(0, degree - 1) * max(0, degree - 2) * max(0, degree - 3) // 6)
168
+
106
169
  tet_coords = np.empty((self.NODES_PER_ELEMENT, 3), dtype=int)
107
170
 
108
171
  for tx in range(degree + 1):
@@ -127,11 +190,7 @@ class TetrahedronPolynomialShapeFunctions:
127
190
  def node_tet_coordinates(
128
191
  node_index_in_elt: int,
129
192
  ):
130
- return wp.vec3i(
131
- NODE_TET_COORDS[node_index_in_elt, 0],
132
- NODE_TET_COORDS[node_index_in_elt, 1],
133
- NODE_TET_COORDS[node_index_in_elt, 2],
134
- )
193
+ return NODE_TET_COORDS[node_index_in_elt]
135
194
 
136
195
  return cache.get_func(node_tet_coordinates, self.name)
137
196
 
@@ -261,12 +320,7 @@ class TetrahedronPolynomialShapeFunctions:
261
320
 
262
321
  elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
263
322
  # Edge
264
- if type_index < 3:
265
- c1 = type_index
266
- c2 = (type_index + 1) % 3
267
- else:
268
- c1 = type_index - 3
269
- c2 = 3
323
+ c1, c2 = TetrahedronShapeFunction.edge_vidx(type_index)
270
324
  return 4.0 * tet_coords[c1] * tet_coords[c2]
271
325
 
272
326
  return 0.0
@@ -355,12 +409,7 @@ class TetrahedronPolynomialShapeFunctions:
355
409
 
356
410
  elif node_type == TetrahedronPolynomialShapeFunctions.EDGE:
357
411
  # Edge
358
- if type_index < 3:
359
- c1 = type_index
360
- c2 = (type_index + 1) % 3
361
- else:
362
- c1 = type_index - 3
363
- c2 = 3
412
+ c1, c2 = TetrahedronShapeFunction.edge_vidx(type_index)
364
413
  dw_dc[c1] = 4.0 * tet_coords[c2]
365
414
  dw_dc[c2] = 4.0 * tet_coords[c1]
366
415
 
@@ -451,7 +500,7 @@ class TetrahedronPolynomialShapeFunctions:
451
500
  return cells[np.newaxis, :], np.array([cell_type], dtype=np.int8)
452
501
 
453
502
 
454
- class TetrahedronNonConformingPolynomialShapeFunctions:
503
+ class TetrahedronNonConformingPolynomialShapeFunctions(ShapeFunction):
455
504
  def __init__(self, degree: int):
456
505
  self._tet_shape = TetrahedronPolynomialShapeFunctions(degree=degree)
457
506
  self.ORDER = self._tet_shape.ORDER
@@ -567,3 +616,204 @@ class TetrahedronNonConformingPolynomialShapeFunctions:
567
616
  return grad / TET_SCALE
568
617
 
569
618
  return element_inner_weight_gradient
619
+
620
+
621
+ class TetrahedronNedelecFirstKindShapeFunctions(TetrahedronShapeFunction):
622
+ value = ShapeFunction.Value.CovariantVector
623
+
624
+ def __init__(self, degree: int):
625
+ if degree != 1:
626
+ raise NotImplementedError("Only linear Nédélec implemented right now")
627
+
628
+ self.ORDER = wp.constant(degree)
629
+
630
+ self.NODES_PER_ELEMENT = wp.constant(6)
631
+ self.NODES_PER_SIDE = wp.constant(3)
632
+
633
+ self.VERTEX_NODE_COUNT = wp.constant(0)
634
+ self.EDGE_NODE_COUNT = wp.constant(1)
635
+ self.FACE_NODE_COUNT = wp.constant(0)
636
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
637
+
638
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
639
+
640
+ @property
641
+ def name(self) -> str:
642
+ return f"TetN1_{self.ORDER}"
643
+
644
+ def _get_node_type_and_type_index(self):
645
+ @cache.dynamic_func(suffix=self.name)
646
+ def node_type_and_index(
647
+ node_index_in_elt: int,
648
+ ):
649
+ return TetrahedronShapeFunction.EDGE, node_index_in_elt
650
+
651
+ return node_type_and_index
652
+
653
+ def make_node_coords_in_element(self):
654
+ @cache.dynamic_func(suffix=self.name)
655
+ def node_coords_in_element(
656
+ node_index_in_elt: int,
657
+ ):
658
+ c1, c2 = TetrahedronShapeFunction.edge_vidx(node_index_in_elt)
659
+
660
+ coords = wp.vec4(0.0)
661
+ coords[c1] = 0.5
662
+ coords[c2] = 0.5
663
+
664
+ return Coords(coords[1], coords[2], coords[3])
665
+
666
+ return node_coords_in_element
667
+
668
+ def make_node_quadrature_weight(self):
669
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
670
+
671
+ @cache.dynamic_func(suffix=self.name)
672
+ def node_quadrature_weight(node_index_in_element: int):
673
+ return 1.0 / float(NODES_PER_ELEMENT)
674
+
675
+ return node_quadrature_weight
676
+
677
+ def make_trace_node_quadrature_weight(self):
678
+ NODES_PER_SIDE = self.NODES_PER_SIDE
679
+
680
+ @cache.dynamic_func(suffix=self.name)
681
+ def trace_node_quadrature_weight(node_index_in_element: int):
682
+ return 1.0 / float(NODES_PER_SIDE)
683
+
684
+ return trace_node_quadrature_weight
685
+
686
+ def make_element_inner_weight(self):
687
+ ORDER = self.ORDER
688
+
689
+ def element_inner_weight_linear(
690
+ coords: Coords,
691
+ node_index_in_elt: int,
692
+ ):
693
+ e1, e2 = TetrahedronShapeFunction.opposite_edge_vidx(node_index_in_elt)
694
+
695
+ v1 = self._vertex_coords(e1)
696
+ v2 = self._vertex_coords(e2)
697
+
698
+ nor = v2 - v1
699
+ return wp.cross(nor, coords - v1)
700
+
701
+ if ORDER == 1:
702
+ return cache.get_func(element_inner_weight_linear, self.name)
703
+
704
+ return None
705
+
706
+ def make_element_inner_weight_gradient(self):
707
+ ORDER = self.ORDER
708
+
709
+ def element_inner_weight_gradient_linear(
710
+ coords: Coords,
711
+ node_index_in_elt: int,
712
+ ):
713
+ e1, e2 = TetrahedronShapeFunction.opposite_edge_vidx(node_index_in_elt)
714
+
715
+ v1 = self._vertex_coords(e1)
716
+ v2 = self._vertex_coords(e2)
717
+
718
+ nor = v2 - v1
719
+ return wp.skew(nor)
720
+
721
+ if ORDER == 1:
722
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
723
+
724
+ return None
725
+
726
+
727
+ class TetrahedronRaviartThomasShapeFunctions(TetrahedronShapeFunction):
728
+ value = ShapeFunction.Value.ContravariantVector
729
+
730
+ def __init__(self, degree: int):
731
+ if degree != 1:
732
+ raise NotImplementedError("Only linear Raviart-Thomas implemented right now")
733
+
734
+ self.ORDER = wp.constant(degree)
735
+
736
+ self.NODES_PER_ELEMENT = wp.constant(4)
737
+ self.NODES_PER_SIDE = wp.constant(1)
738
+
739
+ self.VERTEX_NODE_COUNT = wp.constant(0)
740
+ self.EDGE_NODE_COUNT = wp.constant(0)
741
+ self.FACE_NODE_COUNT = wp.constant(1)
742
+ self.INTERIOR_NODE_COUNT = wp.constant(0)
743
+
744
+ self.node_type_and_type_index = self._get_node_type_and_type_index()
745
+
746
+ @property
747
+ def name(self) -> str:
748
+ return f"TetRT_{self.ORDER}"
749
+
750
+ def _get_node_type_and_type_index(self):
751
+ @cache.dynamic_func(suffix=self.name)
752
+ def node_type_and_index(
753
+ node_index_in_elt: int,
754
+ ):
755
+ return TetrahedronShapeFunction.FACE, node_index_in_elt
756
+
757
+ return node_type_and_index
758
+
759
+ def make_node_coords_in_element(self):
760
+ @cache.dynamic_func(suffix=self.name)
761
+ def node_coords_in_element(
762
+ node_index_in_elt: int,
763
+ ):
764
+ v = (node_index_in_elt + 3) % 4
765
+
766
+ coords = wp.vec4(1.0 / 3.0)
767
+ coords[v] = 0.0
768
+
769
+ return Coords(coords[1], coords[2], coords[3])
770
+
771
+ return node_coords_in_element
772
+
773
+ def make_node_quadrature_weight(self):
774
+ NODES_PER_ELEMENT = self.NODES_PER_ELEMENT
775
+
776
+ @cache.dynamic_func(suffix=self.name)
777
+ def node_quadrature_weight(node_index_in_element: int):
778
+ return 1.0 / float(NODES_PER_ELEMENT)
779
+
780
+ return node_quadrature_weight
781
+
782
+ def make_trace_node_quadrature_weight(self):
783
+ NODES_PER_SIDE = self.NODES_PER_SIDE
784
+
785
+ @cache.dynamic_func(suffix=self.name)
786
+ def trace_node_quadrature_weight(node_index_in_element: int):
787
+ return 1.0 / float(NODES_PER_SIDE)
788
+
789
+ return trace_node_quadrature_weight
790
+
791
+ def make_element_inner_weight(self):
792
+ ORDER = self.ORDER
793
+
794
+ def element_inner_weight_linear(
795
+ coords: Coords,
796
+ node_index_in_elt: int,
797
+ ):
798
+ v = (node_index_in_elt + 3) % 4
799
+
800
+ return 2.0 * (coords - self._vertex_coords(v))
801
+
802
+ if ORDER == 1:
803
+ return cache.get_func(element_inner_weight_linear, self.name)
804
+
805
+ return None
806
+
807
+ def make_element_inner_weight_gradient(self):
808
+ ORDER = self.ORDER
809
+
810
+ def element_inner_weight_gradient_linear(
811
+ coords: Coords,
812
+ node_index_in_elt: int,
813
+ ):
814
+ return 2.0 * wp.identity(n=3, dtype=float)
815
+
816
+ if ORDER == 1:
817
+ return cache.get_func(element_inner_weight_gradient_linear, self.name)
818
+
819
+ return None