warp-lang 1.0.0b2__py3-none-manylinux2014_x86_64.whl → 1.0.0b6__py3-none-manylinux2014_x86_64.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.
Files changed (269) hide show
  1. docs/conf.py +17 -5
  2. examples/env/env_ant.py +1 -1
  3. examples/env/env_cartpole.py +1 -1
  4. examples/env/env_humanoid.py +1 -1
  5. examples/env/env_usd.py +4 -1
  6. examples/env/environment.py +8 -9
  7. examples/example_dem.py +34 -33
  8. examples/example_diffray.py +364 -337
  9. examples/example_fluid.py +32 -23
  10. examples/example_jacobian_ik.py +97 -93
  11. examples/example_marching_cubes.py +6 -16
  12. examples/example_mesh.py +6 -16
  13. examples/example_mesh_intersect.py +16 -14
  14. examples/example_nvdb.py +14 -16
  15. examples/example_raycast.py +14 -13
  16. examples/example_raymarch.py +16 -23
  17. examples/example_render_opengl.py +19 -10
  18. examples/example_sim_cartpole.py +82 -78
  19. examples/example_sim_cloth.py +45 -48
  20. examples/example_sim_fk_grad.py +51 -44
  21. examples/example_sim_fk_grad_torch.py +47 -40
  22. examples/example_sim_grad_bounce.py +108 -133
  23. examples/example_sim_grad_cloth.py +99 -113
  24. examples/example_sim_granular.py +5 -6
  25. examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
  26. examples/example_sim_neo_hookean.py +51 -55
  27. examples/example_sim_particle_chain.py +4 -4
  28. examples/example_sim_quadruped.py +126 -81
  29. examples/example_sim_rigid_chain.py +54 -61
  30. examples/example_sim_rigid_contact.py +66 -70
  31. examples/example_sim_rigid_fem.py +3 -3
  32. examples/example_sim_rigid_force.py +1 -1
  33. examples/example_sim_rigid_gyroscopic.py +3 -4
  34. examples/example_sim_rigid_kinematics.py +28 -39
  35. examples/example_sim_trajopt.py +112 -110
  36. examples/example_sph.py +9 -8
  37. examples/example_wave.py +7 -7
  38. examples/fem/bsr_utils.py +30 -17
  39. examples/fem/example_apic_fluid.py +85 -69
  40. examples/fem/example_convection_diffusion.py +97 -93
  41. examples/fem/example_convection_diffusion_dg.py +142 -149
  42. examples/fem/example_convection_diffusion_dg0.py +141 -136
  43. examples/fem/example_deformed_geometry.py +146 -0
  44. examples/fem/example_diffusion.py +115 -84
  45. examples/fem/example_diffusion_3d.py +116 -86
  46. examples/fem/example_diffusion_mgpu.py +102 -79
  47. examples/fem/example_mixed_elasticity.py +139 -100
  48. examples/fem/example_navier_stokes.py +175 -162
  49. examples/fem/example_stokes.py +143 -111
  50. examples/fem/example_stokes_transfer.py +186 -157
  51. examples/fem/mesh_utils.py +59 -97
  52. examples/fem/plot_utils.py +138 -17
  53. tools/ci/publishing/build_nodes_info.py +54 -0
  54. warp/__init__.py +4 -3
  55. warp/__init__.pyi +1 -0
  56. warp/bin/warp-clang.so +0 -0
  57. warp/bin/warp.so +0 -0
  58. warp/build.py +5 -3
  59. warp/build_dll.py +29 -9
  60. warp/builtins.py +836 -492
  61. warp/codegen.py +864 -553
  62. warp/config.py +3 -1
  63. warp/context.py +389 -172
  64. warp/fem/__init__.py +24 -6
  65. warp/fem/cache.py +318 -25
  66. warp/fem/dirichlet.py +7 -3
  67. warp/fem/domain.py +14 -0
  68. warp/fem/field/__init__.py +30 -38
  69. warp/fem/field/field.py +149 -0
  70. warp/fem/field/nodal_field.py +244 -138
  71. warp/fem/field/restriction.py +8 -6
  72. warp/fem/field/test.py +127 -59
  73. warp/fem/field/trial.py +117 -60
  74. warp/fem/geometry/__init__.py +5 -1
  75. warp/fem/geometry/deformed_geometry.py +271 -0
  76. warp/fem/geometry/element.py +24 -1
  77. warp/fem/geometry/geometry.py +86 -14
  78. warp/fem/geometry/grid_2d.py +112 -54
  79. warp/fem/geometry/grid_3d.py +134 -65
  80. warp/fem/geometry/hexmesh.py +953 -0
  81. warp/fem/geometry/partition.py +85 -33
  82. warp/fem/geometry/quadmesh_2d.py +532 -0
  83. warp/fem/geometry/tetmesh.py +451 -115
  84. warp/fem/geometry/trimesh_2d.py +197 -92
  85. warp/fem/integrate.py +534 -268
  86. warp/fem/operator.py +58 -31
  87. warp/fem/polynomial.py +11 -0
  88. warp/fem/quadrature/__init__.py +1 -1
  89. warp/fem/quadrature/pic_quadrature.py +150 -58
  90. warp/fem/quadrature/quadrature.py +209 -57
  91. warp/fem/space/__init__.py +230 -53
  92. warp/fem/space/basis_space.py +489 -0
  93. warp/fem/space/collocated_function_space.py +105 -0
  94. warp/fem/space/dof_mapper.py +49 -2
  95. warp/fem/space/function_space.py +90 -39
  96. warp/fem/space/grid_2d_function_space.py +149 -496
  97. warp/fem/space/grid_3d_function_space.py +173 -538
  98. warp/fem/space/hexmesh_function_space.py +352 -0
  99. warp/fem/space/partition.py +129 -76
  100. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  101. warp/fem/space/restriction.py +46 -34
  102. warp/fem/space/shape/__init__.py +15 -0
  103. warp/fem/space/shape/cube_shape_function.py +738 -0
  104. warp/fem/space/shape/shape_function.py +103 -0
  105. warp/fem/space/shape/square_shape_function.py +611 -0
  106. warp/fem/space/shape/tet_shape_function.py +567 -0
  107. warp/fem/space/shape/triangle_shape_function.py +429 -0
  108. warp/fem/space/tetmesh_function_space.py +132 -1039
  109. warp/fem/space/topology.py +295 -0
  110. warp/fem/space/trimesh_2d_function_space.py +104 -742
  111. warp/fem/types.py +13 -11
  112. warp/fem/utils.py +335 -60
  113. warp/native/array.h +120 -34
  114. warp/native/builtin.h +101 -72
  115. warp/native/bvh.cpp +73 -325
  116. warp/native/bvh.cu +406 -23
  117. warp/native/bvh.h +22 -40
  118. warp/native/clang/clang.cpp +1 -0
  119. warp/native/crt.h +2 -0
  120. warp/native/cuda_util.cpp +8 -3
  121. warp/native/cuda_util.h +1 -0
  122. warp/native/exports.h +1522 -1243
  123. warp/native/intersect.h +19 -4
  124. warp/native/intersect_adj.h +8 -8
  125. warp/native/mat.h +76 -17
  126. warp/native/mesh.cpp +33 -108
  127. warp/native/mesh.cu +114 -18
  128. warp/native/mesh.h +395 -40
  129. warp/native/noise.h +272 -329
  130. warp/native/quat.h +51 -8
  131. warp/native/rand.h +44 -34
  132. warp/native/reduce.cpp +1 -1
  133. warp/native/sparse.cpp +4 -4
  134. warp/native/sparse.cu +163 -155
  135. warp/native/spatial.h +2 -2
  136. warp/native/temp_buffer.h +18 -14
  137. warp/native/vec.h +103 -21
  138. warp/native/warp.cpp +2 -1
  139. warp/native/warp.cu +28 -3
  140. warp/native/warp.h +4 -3
  141. warp/render/render_opengl.py +261 -109
  142. warp/sim/__init__.py +1 -2
  143. warp/sim/articulation.py +385 -185
  144. warp/sim/import_mjcf.py +59 -48
  145. warp/sim/import_urdf.py +15 -15
  146. warp/sim/import_usd.py +174 -102
  147. warp/sim/inertia.py +17 -18
  148. warp/sim/integrator_xpbd.py +4 -3
  149. warp/sim/model.py +330 -250
  150. warp/sim/render.py +1 -1
  151. warp/sparse.py +625 -152
  152. warp/stubs.py +341 -309
  153. warp/tape.py +9 -6
  154. warp/tests/__main__.py +3 -6
  155. warp/tests/assets/curlnoise_golden.npy +0 -0
  156. warp/tests/assets/pnoise_golden.npy +0 -0
  157. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  158. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  159. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  160. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  161. warp/tests/aux_test_unresolved_func.py +14 -0
  162. warp/tests/aux_test_unresolved_symbol.py +14 -0
  163. warp/tests/disabled_kinematics.py +239 -0
  164. warp/tests/run_coverage_serial.py +31 -0
  165. warp/tests/test_adam.py +103 -106
  166. warp/tests/test_arithmetic.py +94 -74
  167. warp/tests/test_array.py +82 -101
  168. warp/tests/test_array_reduce.py +57 -23
  169. warp/tests/test_atomic.py +64 -28
  170. warp/tests/test_bool.py +22 -12
  171. warp/tests/test_builtins_resolution.py +1292 -0
  172. warp/tests/test_bvh.py +18 -18
  173. warp/tests/test_closest_point_edge_edge.py +54 -57
  174. warp/tests/test_codegen.py +165 -134
  175. warp/tests/test_compile_consts.py +28 -20
  176. warp/tests/test_conditional.py +108 -24
  177. warp/tests/test_copy.py +10 -12
  178. warp/tests/test_ctypes.py +112 -88
  179. warp/tests/test_dense.py +21 -14
  180. warp/tests/test_devices.py +98 -0
  181. warp/tests/test_dlpack.py +75 -75
  182. warp/tests/test_examples.py +237 -0
  183. warp/tests/test_fabricarray.py +22 -24
  184. warp/tests/test_fast_math.py +15 -11
  185. warp/tests/test_fem.py +1034 -124
  186. warp/tests/test_fp16.py +23 -16
  187. warp/tests/test_func.py +187 -86
  188. warp/tests/test_generics.py +194 -49
  189. warp/tests/test_grad.py +123 -181
  190. warp/tests/test_grad_customs.py +176 -0
  191. warp/tests/test_hash_grid.py +35 -34
  192. warp/tests/test_import.py +10 -23
  193. warp/tests/test_indexedarray.py +24 -25
  194. warp/tests/test_intersect.py +18 -9
  195. warp/tests/test_large.py +141 -0
  196. warp/tests/test_launch.py +14 -41
  197. warp/tests/test_lerp.py +64 -65
  198. warp/tests/test_lvalue.py +493 -0
  199. warp/tests/test_marching_cubes.py +12 -13
  200. warp/tests/test_mat.py +517 -2898
  201. warp/tests/test_mat_lite.py +115 -0
  202. warp/tests/test_mat_scalar_ops.py +2889 -0
  203. warp/tests/test_math.py +103 -9
  204. warp/tests/test_matmul.py +304 -69
  205. warp/tests/test_matmul_lite.py +410 -0
  206. warp/tests/test_mesh.py +60 -22
  207. warp/tests/test_mesh_query_aabb.py +21 -25
  208. warp/tests/test_mesh_query_point.py +111 -22
  209. warp/tests/test_mesh_query_ray.py +12 -24
  210. warp/tests/test_mlp.py +30 -22
  211. warp/tests/test_model.py +92 -89
  212. warp/tests/test_modules_lite.py +39 -0
  213. warp/tests/test_multigpu.py +88 -114
  214. warp/tests/test_noise.py +12 -11
  215. warp/tests/test_operators.py +16 -20
  216. warp/tests/test_options.py +11 -11
  217. warp/tests/test_pinned.py +17 -18
  218. warp/tests/test_print.py +32 -11
  219. warp/tests/test_quat.py +275 -129
  220. warp/tests/test_rand.py +18 -16
  221. warp/tests/test_reload.py +38 -34
  222. warp/tests/test_rounding.py +50 -43
  223. warp/tests/test_runlength_encode.py +168 -20
  224. warp/tests/test_smoothstep.py +9 -11
  225. warp/tests/test_snippet.py +143 -0
  226. warp/tests/test_sparse.py +261 -63
  227. warp/tests/test_spatial.py +276 -243
  228. warp/tests/test_streams.py +110 -85
  229. warp/tests/test_struct.py +268 -63
  230. warp/tests/test_tape.py +39 -21
  231. warp/tests/test_torch.py +90 -86
  232. warp/tests/test_transient_module.py +10 -12
  233. warp/tests/test_types.py +363 -0
  234. warp/tests/test_utils.py +451 -0
  235. warp/tests/test_vec.py +354 -2050
  236. warp/tests/test_vec_lite.py +73 -0
  237. warp/tests/test_vec_scalar_ops.py +2099 -0
  238. warp/tests/test_volume.py +418 -376
  239. warp/tests/test_volume_write.py +124 -134
  240. warp/tests/unittest_serial.py +35 -0
  241. warp/tests/unittest_suites.py +291 -0
  242. warp/tests/unittest_utils.py +342 -0
  243. warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
  244. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  245. warp/thirdparty/appdirs.py +36 -45
  246. warp/thirdparty/unittest_parallel.py +589 -0
  247. warp/types.py +622 -211
  248. warp/utils.py +54 -393
  249. warp_lang-1.0.0b6.dist-info/METADATA +238 -0
  250. warp_lang-1.0.0b6.dist-info/RECORD +409 -0
  251. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
  252. examples/example_cache_management.py +0 -40
  253. examples/example_multigpu.py +0 -54
  254. examples/example_struct.py +0 -65
  255. examples/fem/example_stokes_transfer_3d.py +0 -210
  256. warp/fem/field/discrete_field.py +0 -80
  257. warp/fem/space/nodal_function_space.py +0 -233
  258. warp/tests/test_all.py +0 -223
  259. warp/tests/test_array_scan.py +0 -60
  260. warp/tests/test_base.py +0 -208
  261. warp/tests/test_unresolved_func.py +0 -7
  262. warp/tests/test_unresolved_symbol.py +0 -7
  263. warp_lang-1.0.0b2.dist-info/METADATA +0 -26
  264. warp_lang-1.0.0b2.dist-info/RECORD +0 -378
  265. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  266. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  267. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  268. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
  269. {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,8 @@
1
1
  import numpy as np
2
2
  import warp as wp
3
3
 
4
+ from warp.fem.utils import grid_to_tets, grid_to_tris, grid_to_quads, grid_to_hexes
5
+
4
6
 
5
7
  def gen_trimesh(res, bounds_lo: wp.vec2 = wp.vec2(0.0), bounds_hi: wp.vec2 = wp.vec2(1.0)):
6
8
  """Constructs a triangular mesh by diving each cell of a dense 2D grid into two triangles
@@ -14,7 +16,6 @@ def gen_trimesh(res, bounds_lo: wp.vec2 = wp.vec2(0.0), bounds_hi: wp.vec2 = wp.
14
16
  Tuple of ndarrays: (Vertex positions, Triangle vertex indices)
15
17
  """
16
18
 
17
-
18
19
  Nx = res[0]
19
20
  Ny = res[1]
20
21
 
@@ -23,20 +24,7 @@ def gen_trimesh(res, bounds_lo: wp.vec2 = wp.vec2(0.0), bounds_hi: wp.vec2 = wp.
23
24
 
24
25
  positions = np.transpose(np.meshgrid(x, y, indexing="ij"), axes=(1, 2, 0)).reshape(-1, 2)
25
26
 
26
- cx, cy = np.meshgrid(np.arange(Nx, dtype=int), np.arange(Ny, dtype=int), indexing="ij")
27
-
28
- vidx = np.transpose(
29
- np.array(
30
- [
31
- (Ny + 1) * cx + cy,
32
- (Ny + 1) * (cx + 1) + cy,
33
- (Ny + 1) * (cx + 1) + (cy + 1),
34
- (Ny + 1) * cx + cy,
35
- (Ny + 1) * (cx + 1) + (cy + 1),
36
- (Ny + 1) * (cx) + (cy + 1),
37
- ]
38
- )
39
- ).reshape((-1, 3))
27
+ vidx = grid_to_tris(Nx, Ny)
40
28
 
41
29
  return wp.array(positions, dtype=wp.vec2), wp.array(vidx, dtype=int)
42
30
 
@@ -63,85 +51,59 @@ def gen_tetmesh(res, bounds_lo: wp.vec3 = wp.vec3(0.0), bounds_hi: wp.vec3 = wp.
63
51
 
64
52
  positions = np.transpose(np.meshgrid(x, y, z, indexing="ij"), axes=(1, 2, 3, 0)).reshape(-1, 3)
65
53
 
66
- # Global node indices for each cell
67
- cx, cy, cz = np.meshgrid(
68
- np.arange(Nx, dtype=int), np.arange(Ny, dtype=int), np.arange(Nz, dtype=int), indexing="ij"
69
- )
70
-
71
- grid_vidx = np.array(
72
- [
73
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * cy + cz,
74
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * cy + cz + 1,
75
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * (cy + 1) + cz,
76
- (Ny + 1) * (Nz + 1) * cx + (Nz + 1) * (cy + 1) + cz + 1,
77
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * cy + cz,
78
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * cy + cz + 1,
79
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * (cy + 1) + cz,
80
- (Ny + 1) * (Nz + 1) * (cx + 1) + (Nz + 1) * (cy + 1) + cz + 1,
81
- ]
82
- )
83
-
84
- # decompose grid cells into 5 tets
85
- tet_vidx = np.array(
86
- [
87
- [0, 1, 2, 4],
88
- [3, 2, 1, 7],
89
- [5, 1, 7, 4],
90
- [6, 7, 4, 2],
91
- [4, 1, 2, 7],
92
- ]
93
- )
94
-
95
- # Convert to 3d index coordinates
96
- vidx_coords = np.array(
97
- [
98
- [0, 0, 0],
99
- [0, 0, 1],
100
- [0, 1, 0],
101
- [0, 1, 1],
102
- [1, 0, 0],
103
- [1, 0, 1],
104
- [1, 1, 0],
105
- [1, 1, 1],
106
- ]
107
- )
108
- tet_coords = vidx_coords[tet_vidx]
109
-
110
- # Symmetry bits for each cell
111
- ox, oy, oz = np.meshgrid(
112
- np.arange(Nx, dtype=int) % 2, np.arange(Ny, dtype=int) % 2, np.arange(Nz, dtype=int) % 2, indexing="ij"
113
- )
114
- tet_coords = np.broadcast_to(tet_coords, shape=(*ox.shape, *tet_coords.shape))
115
-
116
- # Flip coordinates according to symmetry
117
- ox_bk = np.broadcast_to(ox.reshape(*ox.shape, 1, 1), tet_coords.shape[:-1])
118
- oy_bk = np.broadcast_to(oy.reshape(*oy.shape, 1, 1), tet_coords.shape[:-1])
119
- oz_bk = np.broadcast_to(oz.reshape(*oz.shape, 1, 1), tet_coords.shape[:-1])
120
-
121
- tet_coords_x = tet_coords[..., 0] ^ ox_bk
122
- tet_coords_y = tet_coords[..., 1] ^ oy_bk
123
- tet_coords_z = tet_coords[..., 2] ^ oz_bk
124
-
125
- # Back to local vertex indices
126
- corner_indices = 4 * tet_coords_x + 2 * tet_coords_y + tet_coords_z
127
-
128
- # Now go from cell-local to global node indices
129
- # There must be a nicer way than this, but for example purposes this works
130
-
131
- corner_indices = corner_indices.reshape(-1, 4)
132
-
133
- grid_vidx = grid_vidx.reshape((8, -1, 1))
134
- grid_vidx = np.broadcast_to(grid_vidx, shape=(8, grid_vidx.shape[1], 5))
135
- grid_vidx = grid_vidx.reshape((8, -1))
136
-
137
- node_indices = np.arange(corner_indices.shape[0])
138
- tet_grid_vidx = np.transpose(
139
- [
140
- grid_vidx[corner_indices[:, 0], node_indices],
141
- grid_vidx[corner_indices[:, 1], node_indices],
142
- grid_vidx[corner_indices[:, 2], node_indices],
143
- grid_vidx[corner_indices[:, 3], node_indices],
144
- ]
145
- )
146
-
147
- return wp.array(positions, dtype=wp.vec3), wp.array(tet_grid_vidx, dtype=int)
54
+ vidx = grid_to_tets(Nx, Ny, Nz)
55
+
56
+ return wp.array(positions, dtype=wp.vec3), wp.array(vidx, dtype=int)
57
+
58
+
59
+ def gen_quadmesh(res, bounds_lo: wp.vec2 = wp.vec2(0.0), bounds_hi: wp.vec2 = wp.vec2(1.0)):
60
+ """Constructs a quadrilateral mesh from a dense 2D grid
61
+
62
+ Args:
63
+ res: Resolution of the grid along each dimension
64
+ bounds_lo: Position of the lower bound of the axis-aligned grid
65
+ bounds_up: Position of the upper bound of the axis-aligned grid
66
+
67
+ Returns:
68
+ Tuple of ndarrays: (Vertex positions, Triangle vertex indices)
69
+ """
70
+
71
+ Nx = res[0]
72
+ Ny = res[1]
73
+
74
+ x = np.linspace(bounds_lo[0], bounds_hi[0], Nx + 1)
75
+ y = np.linspace(bounds_lo[1], bounds_hi[1], Ny + 1)
76
+
77
+ positions = np.transpose(np.meshgrid(x, y, indexing="ij"), axes=(1, 2, 0)).reshape(-1, 2)
78
+
79
+ vidx = grid_to_quads(Nx, Ny)
80
+
81
+ return wp.array(positions, dtype=wp.vec2), wp.array(vidx, dtype=int)
82
+
83
+
84
+ def gen_hexmesh(res, bounds_lo: wp.vec3 = wp.vec3(0.0), bounds_hi: wp.vec3 = wp.vec3(1.0)):
85
+ """Constructs a quadrilateral mesh from a dense 2D grid
86
+
87
+ Args:
88
+ res: Resolution of the grid along each dimension
89
+ bounds_lo: Position of the lower bound of the axis-aligned grid
90
+ bounds_up: Position of the upper bound of the axis-aligned grid
91
+
92
+ Returns:
93
+ Tuple of ndarrays: (Vertex positions, Triangle vertex indices)
94
+ """
95
+
96
+ Nx = res[0]
97
+ Ny = res[1]
98
+ Nz = res[2]
99
+
100
+ x = np.linspace(bounds_lo[0], bounds_hi[0], Nx + 1)
101
+ y = np.linspace(bounds_lo[1], bounds_hi[1], Ny + 1)
102
+ z = np.linspace(bounds_lo[1], bounds_hi[1], Nz + 1)
103
+
104
+ positions = np.transpose(np.meshgrid(x, y, z, indexing="ij"), axes=(1, 2, 3, 0)).reshape(-1, 3)
105
+
106
+ vidx = grid_to_hexes(Nx, Ny, Nz)
107
+
108
+ return wp.array(positions, dtype=wp.vec3), wp.array(vidx, dtype=int)
109
+
@@ -1,5 +1,9 @@
1
+ from typing import Set
2
+
1
3
  import numpy as np
2
4
 
5
+ from warp.fem import DiscreteField
6
+
3
7
 
4
8
  def plot_grid_surface(field, axes=None):
5
9
  import matplotlib.pyplot as plt
@@ -8,7 +12,7 @@ def plot_grid_surface(field, axes=None):
8
12
  if axes is None:
9
13
  fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
10
14
 
11
- node_positions = field.space.node_positions()
15
+ node_positions = field.space.node_grid()
12
16
 
13
17
  # Make data.
14
18
  X = node_positions[0]
@@ -27,10 +31,10 @@ def plot_tri_surface(field, axes=None):
27
31
  if axes is None:
28
32
  fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
29
33
 
30
- node_positions = field.space.node_positions()
31
-
34
+ node_positions = field.space.node_positions().numpy()
35
+
32
36
  triangulation = Triangulation(
33
- x=node_positions[0], y=node_positions[1], triangles=field.space.node_triangulation()
37
+ x=node_positions[:, 0], y=node_positions[:, 1], triangles=field.space.node_triangulation()
34
38
  )
35
39
 
36
40
  Z = field.dof_values.numpy()
@@ -46,7 +50,7 @@ def plot_scatter_surface(field, axes=None):
46
50
  if axes is None:
47
51
  fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
48
52
 
49
- X, Y = field.space.node_positions()
53
+ X, Y = field.space.node_positions().numpy().T
50
54
 
51
55
  # Make data.
52
56
  Z = field.dof_values.numpy().reshape(X.shape)
@@ -56,13 +60,12 @@ def plot_scatter_surface(field, axes=None):
56
60
 
57
61
 
58
62
  def plot_surface(field, axes=None):
59
- if hasattr(field.space, "node_triangulation"):
63
+ if hasattr(field.space, "node_grid"):
64
+ return plot_grid_surface(field, axes)
65
+ elif hasattr(field.space, "node_triangulation"):
60
66
  return plot_tri_surface(field, axes)
61
67
  else:
62
- try:
63
- return plot_grid_surface(field, axes)
64
- except:
65
- return plot_scatter_surface(field, axes)
68
+ return plot_scatter_surface(field, axes)
66
69
 
67
70
 
68
71
  def plot_grid_color(field, axes=None):
@@ -72,7 +75,7 @@ def plot_grid_color(field, axes=None):
72
75
  if axes is None:
73
76
  fig, axes = plt.subplots()
74
77
 
75
- node_positions = field.space.node_positions()
78
+ node_positions = field.space.node_grid()
76
79
 
77
80
  # Make data.
78
81
  X = node_positions[0]
@@ -89,11 +92,11 @@ def plot_velocities(field, axes=None):
89
92
  if axes is None:
90
93
  fig, axes = plt.subplots()
91
94
 
92
- node_positions = field.space.node_positions()
95
+ node_positions = field.space.node_positions().numpy()
93
96
 
94
97
  # Make data.
95
- X = node_positions[0]
96
- Y = node_positions[1]
98
+ X = node_positions[:, 0]
99
+ Y = node_positions[:, 1]
97
100
 
98
101
  vel = field.dof_values.numpy()
99
102
  u = np.ascontiguousarray(vel[:, 0])
@@ -111,7 +114,7 @@ def plot_grid_streamlines(field, axes=None):
111
114
  if axes is None:
112
115
  fig, axes = plt.subplots()
113
116
 
114
- node_positions = field.space.node_positions()
117
+ node_positions = field.space.node_grid()
115
118
 
116
119
  # Make data.
117
120
  X = node_positions[0][:, 0]
@@ -136,7 +139,7 @@ def plot_3d_scatter(field, axes=None):
136
139
  if axes is None:
137
140
  fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
138
141
 
139
- X, Y, Z = field.space.node_positions()
142
+ X, Y, Z = field.space.node_positions().numpy().T
140
143
 
141
144
  # Make data.
142
145
  f = field.dof_values.numpy().reshape(X.shape)
@@ -151,7 +154,7 @@ def plot_3d_velocities(field, axes=None):
151
154
  if axes is None:
152
155
  fig, axes = plt.subplots(subplot_kw={"projection": "3d"})
153
156
 
154
- X, Y, Z = field.space.node_positions()
157
+ X, Y, Z = field.space.node_positions().numpy().T
155
158
 
156
159
  vel = field.dof_values.numpy()
157
160
  u = np.ascontiguousarray(vel[:, 0])
@@ -163,3 +166,121 @@ def plot_3d_velocities(field, axes=None):
163
166
  w = w.reshape(X.shape)
164
167
 
165
168
  return axes.quiver(X, Y, Z, u, v, w, length=1.0 / X.shape[0], normalize=False)
169
+
170
+
171
+ class Plot:
172
+ def __init__(self, stage=None, default_point_radius=0.01):
173
+ self.default_point_radius = default_point_radius
174
+
175
+ self._surfaces = {}
176
+ self._surface_vectors = {}
177
+ self._volumes = {}
178
+
179
+ if stage is not None:
180
+ from warp.render import UsdRenderer
181
+
182
+ self._usd_renderer = UsdRenderer(stage)
183
+ self._plt = None
184
+ else:
185
+ self._usd_renderer = None
186
+
187
+ def begin_frame(self, time):
188
+ if self._usd_renderer is not None:
189
+ self._usd_renderer.begin_frame(time=time)
190
+
191
+ def end_frame(self):
192
+ if self._usd_renderer is not None:
193
+ self._usd_renderer.end_frame()
194
+
195
+ def add_surface(self, name: str, field: DiscreteField):
196
+ if self._usd_renderer is not None:
197
+ points_2d = field.space.node_positions().numpy()
198
+ values = field.dof_values.numpy()
199
+ points_3d = np.hstack((points_2d, values.reshape(-1, 1)))
200
+
201
+ if hasattr(field.space, "node_triangulation"):
202
+ indices = field.space.node_triangulation()
203
+ self._usd_renderer.render_mesh(name, points=points_3d, indices=indices)
204
+ else:
205
+ self._usd_renderer.render_points(name, points=points_3d, radius=self.default_point_radius)
206
+
207
+ if name not in self._surfaces:
208
+ field_clone = field.space.make_field(space_partition=field.space_partition)
209
+ self._surfaces[name] = (field_clone, [])
210
+
211
+ self._surfaces[name][1].append(field.dof_values.numpy())
212
+
213
+ def add_surface_vector(self, name: str, field: DiscreteField):
214
+ if self._usd_renderer is not None:
215
+ points_2d = field.space.node_positions().numpy()
216
+ values = field.dof_values.numpy()
217
+ points_3d = np.hstack((points_2d + values, np.zeros_like(points_2d[:, 0]).reshape(-1, 1)))
218
+
219
+ if hasattr(field.space, "node_triangulation"):
220
+ indices = field.space.node_triangulation()
221
+ self._usd_renderer.render_mesh(name, points=points_3d, indices=indices)
222
+ else:
223
+ self._usd_renderer.render_points(name, points=points_3d, radius=self.default_point_radius)
224
+
225
+ if name not in self._surface_vectors:
226
+ field_clone = field.space.make_field(space_partition=field.space_partition)
227
+ self._surface_vectors[name] = (field_clone, [])
228
+
229
+ self._surface_vectors[name][1].append(field.dof_values.numpy())
230
+
231
+ def add_volume(self, name: str, field: DiscreteField):
232
+ if self._usd_renderer is not None:
233
+ points_3d = field.space.node_positions().numpy()
234
+ values = field.dof_values.numpy()
235
+
236
+ self._usd_renderer.render_points(name, points_3d, radius=values)
237
+
238
+ if name not in self._volumes:
239
+ field_clone = field.space.make_field(space_partition=field.space_partition)
240
+ self._volumes[name] = (field_clone, [])
241
+
242
+ self._volumes[name][1].append(field.dof_values.numpy())
243
+
244
+ def plot(self, streamlines: Set[str] = []):
245
+ return self._plot_matplotlib(streamlines)
246
+
247
+ def _plot_matplotlib(self, streamlines: Set[str] = []):
248
+ import matplotlib.pyplot as plt
249
+ import matplotlib.animation as animation
250
+
251
+ def make_animation(ax, field, values, plot_func, num_frames: int):
252
+ def animate(i):
253
+ ax.clear()
254
+ field.dof_values = values[i]
255
+ return plot_func(field, axes=ax)
256
+
257
+ return animation.FuncAnimation(
258
+ ax.figure,
259
+ animate,
260
+ interval=30,
261
+ blit=False,
262
+ frames=len(values),
263
+ )
264
+
265
+ for name, (field, values) in self._surfaces.items():
266
+ field.dof_values = values[0]
267
+ ax = plot_surface(field).axes
268
+
269
+ if len(values) > 1:
270
+ anim = make_animation(ax, field, values, plot_func=plot_surface, num_frames=len(values))
271
+
272
+ for name, (field, values) in self._surface_vectors.items():
273
+ field.dof_values = values[0]
274
+ if name in streamlines and hasattr(field.space, "node_grid"):
275
+ ax = plot_grid_streamlines(field).axes
276
+ else:
277
+ ax = plot_velocities(field).axes
278
+
279
+ if len(values) > 1:
280
+ anim = make_animation(ax, field, values, plot_func=plot_velocities, num_frames=len(values))
281
+
282
+ for name, (field, values) in self._volumes.items():
283
+ field.dof_values = values[0]
284
+ ax = plot_3d_scatter(field).axes
285
+
286
+ plt.show()
@@ -0,0 +1,54 @@
1
+ # Copyright (c) 2023 NVIDIA CORPORATION. All rights reserved.
2
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
3
+ # and proprietary rights in and to this software, related documentation
4
+ # and any modifications thereto. Any use, reproduction, disclosure or
5
+ # distribution of this software and related documentation without an express
6
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
+
8
+ """Script to build the node.json OGN file that lists the extension's nodes."""
9
+
10
+ import json
11
+ import os
12
+
13
+
14
+ def gather_nodes_info(
15
+ ext_path: str,
16
+ ext_name: str,
17
+ ) -> None:
18
+ # fmt: off
19
+ ogn_file_paths = tuple(
20
+ os.path.join(dir_path, file_name)
21
+ for (dir_path, _, file_names) in os.walk(ext_path)
22
+ for file_name in file_names if file_name.endswith(".ogn")
23
+ )
24
+ # fmt: on
25
+
26
+ nodes_info = {}
27
+ for file_path in ogn_file_paths:
28
+ with open(file_path) as file:
29
+ data = json.load(file)
30
+ node_key = next(iter(data.keys()))
31
+ node_data = data[node_key]
32
+ nodes_info[node_key] = {
33
+ "description": node_data.get("description", ""),
34
+ "version": node_data.get("version", 1),
35
+ "uiName": node_data.get("uiName", ""),
36
+ "extension": ext_name,
37
+ "language": node_data.get("language", ""),
38
+ }
39
+
40
+ return {"nodes": nodes_info}
41
+
42
+
43
+ if __name__ == "__main__":
44
+ here = os.path.dirname(__file__)
45
+ root_path = os.path.abspath(os.path.join(here, "..", "..", ".."))
46
+ ext_path = os.path.join(root_path, "exts", "omni.warp")
47
+ ogn_path = os.path.join(ext_path, "ogn")
48
+ nodes_info_path = os.path.join(ogn_path, "nodes.json")
49
+
50
+ nodes_info = gather_nodes_info(ext_path, "omni.warp")
51
+
52
+ os.makedirs(ogn_path, exist_ok=True)
53
+ with open(nodes_info_path, "w") as file:
54
+ json.dump(nodes_info, file, indent=4)
warp/__init__.py CHANGED
@@ -26,7 +26,9 @@ from warp.types import spatial_matrix, spatial_matrixh, spatial_matrixf, spatial
26
26
 
27
27
  # geometry types
28
28
  from warp.types import Bvh, Mesh, HashGrid, Volume, MarchingCubes
29
- from warp.types import bvh_query_t, mesh_query_aabb_t, hash_grid_query_t
29
+ from warp.types import bvh_query_t, hash_grid_query_t, mesh_query_aabb_t, mesh_query_point_t, mesh_query_ray_t
30
+
31
+
30
32
 
31
33
  # device-wide gemms
32
34
  from warp.types import matmul, adj_matmul, batched_matmul, adj_batched_matmul, from_ptr
@@ -35,7 +37,7 @@ from warp.types import matmul, adj_matmul, batched_matmul, adj_batched_matmul, f
35
37
  from warp.types import vector as vec
36
38
  from warp.types import matrix as mat
37
39
 
38
- from warp.context import init, func, func_grad, func_replay, kernel, struct, overload
40
+ from warp.context import init, func, func_grad, func_replay, func_native, kernel, struct, overload
39
41
  from warp.context import is_cpu_available, is_cuda_available, is_device_available
40
42
  from warp.context import get_devices, get_preferred_device
41
43
  from warp.context import get_cuda_devices, get_cuda_device_count, get_cuda_device, map_cuda_device, unmap_cuda_device
@@ -57,7 +59,6 @@ from warp.context import (
57
59
  )
58
60
  from warp.context import set_module_options, get_module_options, get_module
59
61
  from warp.context import capture_begin, capture_end, capture_launch
60
- from warp.context import print_builtins, export_builtins, export_stubs
61
62
  from warp.context import Kernel, Function, Launch
62
63
  from warp.context import Stream, get_stream, set_stream, synchronize_stream
63
64
  from warp.context import Event, record_event, wait_event, wait_stream
warp/__init__.pyi ADDED
@@ -0,0 +1 @@
1
+ from .stubs import *
warp/bin/warp-clang.so CHANGED
Binary file
warp/bin/warp.so CHANGED
Binary file
warp/build.py CHANGED
@@ -26,8 +26,8 @@ def build_cuda(cu_path, arch, output_path, config="release", verify_fp=False, fa
26
26
  err = warp.context.runtime.core.cuda_compile_program(
27
27
  src, arch, inc_path, config == "debug", warp.config.verbose, verify_fp, fast_math, output_path
28
28
  )
29
- if err:
30
- raise Exception("CUDA build failed")
29
+ if err != 0:
30
+ raise Exception(f"CUDA kernel build failed with error code {err}")
31
31
 
32
32
 
33
33
  # load PTX or CUBIN as a CUDA runtime module (input type determined by input_path extension)
@@ -45,7 +45,9 @@ def build_cpu(obj_path, cpp_path, mode="release", verify_fp=False, fast_math=Fal
45
45
  inc_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "native").encode("utf-8")
46
46
  obj_path = obj_path.encode("utf-8")
47
47
 
48
- warp.context.runtime.llvm.compile_cpp(src, cpp_path, inc_path, obj_path, mode == "debug")
48
+ err = warp.context.runtime.llvm.compile_cpp(src, cpp_path, inc_path, obj_path, mode == "debug")
49
+ if err != 0:
50
+ raise Exception(f"CPU kernel build failed with error code {err}")
49
51
 
50
52
 
51
53
  kernel_bin_dir = None
warp/build_dll.py CHANGED
@@ -8,11 +8,24 @@
8
8
  import sys
9
9
  import os
10
10
  import subprocess
11
+ import platform
11
12
 
12
13
  import warp.config
13
14
  from warp.utils import ScopedTimer
14
15
 
15
16
 
17
+ # return a canonical machine architecture string
18
+ # - "x86_64" for x86-64, aka. AMD64, aka. x64
19
+ # - "aarch64" for AArch64, aka. ARM64
20
+ def machine_architecture() -> str:
21
+ machine = platform.machine()
22
+ if machine == "x86_64" or machine == "AMD64":
23
+ return "x86_64"
24
+ if machine == "aarch64" or machine == "arm64":
25
+ return "aarch64"
26
+ raise RuntimeError(f"Unrecognized machine architecture {machine}")
27
+
28
+
16
29
  def run_cmd(cmd, capture=False):
17
30
  if warp.config.verbose:
18
31
  print(cmd)
@@ -182,12 +195,15 @@ def build_dll_for_arch(dll_path, cpp_paths, cu_path, libs, mode, arch, verify_fp
182
195
  "-gencode=arch=compute_75,code=sm_75", # Turing
183
196
  "-gencode=arch=compute_80,code=sm_80", # Ampere
184
197
  "-gencode=arch=compute_86,code=sm_86",
185
- # SASS for supported mobile architectures (e.g. Tegra/Jetson)
186
- # "-gencode=arch=compute_53,code=sm_53",
187
- # "-gencode=arch=compute_62,code=sm_62",
188
- # "-gencode=arch=compute_72,code=sm_72",
189
- # "-gencode=arch=compute_87,code=sm_87",
190
198
  ]
199
+ if arch == "aarch64" and sys.platform == "linux":
200
+ gencode_opts += [
201
+ # SASS for supported mobile architectures (e.g. Tegra/Jetson)
202
+ "-gencode=arch=compute_53,code=sm_53", # X1
203
+ "-gencode=arch=compute_62,code=sm_62", # X2
204
+ "-gencode=arch=compute_72,code=sm_72", # Xavier
205
+ "-gencode=arch=compute_87,code=sm_87", # Orin
206
+ ]
191
207
 
192
208
  # support for Ada and Hopper is available with CUDA Toolkit 11.8+
193
209
  if ctk_version >= (11, 8):
@@ -354,11 +370,15 @@ def build_dll(dll_path, cpp_paths, cu_path, libs=[], mode="release", verify_fp=F
354
370
  if sys.platform == "darwin":
355
371
  # create a universal binary by combining x86-64 and AArch64 builds
356
372
  build_dll_for_arch(dll_path + "-x86_64", cpp_paths, cu_path, libs, mode, "x86_64", verify_fp, fast_math, quick)
357
- build_dll_for_arch(dll_path + "-arm64", cpp_paths, cu_path, libs, mode, "arm64", verify_fp, fast_math, quick)
373
+ build_dll_for_arch(
374
+ dll_path + "-aarch64", cpp_paths, cu_path, libs, mode, "aarch64", verify_fp, fast_math, quick
375
+ )
358
376
 
359
- run_cmd(f"lipo -create -output {dll_path} {dll_path}-x86_64 {dll_path}-arm64")
377
+ run_cmd(f"lipo -create -output {dll_path} {dll_path}-x86_64 {dll_path}-aarch64")
360
378
  os.remove(f"{dll_path}-x86_64")
361
- os.remove(f"{dll_path}-arm64")
379
+ os.remove(f"{dll_path}-aarch64")
362
380
 
363
381
  else:
364
- build_dll_for_arch(dll_path, cpp_paths, cu_path, libs, mode, "x86_64", verify_fp, fast_math, quick)
382
+ build_dll_for_arch(
383
+ dll_path, cpp_paths, cu_path, libs, mode, machine_architecture(), verify_fp, fast_math, quick
384
+ )