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.
- docs/conf.py +17 -5
- examples/env/env_ant.py +1 -1
- examples/env/env_cartpole.py +1 -1
- examples/env/env_humanoid.py +1 -1
- examples/env/env_usd.py +4 -1
- examples/env/environment.py +8 -9
- examples/example_dem.py +34 -33
- examples/example_diffray.py +364 -337
- examples/example_fluid.py +32 -23
- examples/example_jacobian_ik.py +97 -93
- examples/example_marching_cubes.py +6 -16
- examples/example_mesh.py +6 -16
- examples/example_mesh_intersect.py +16 -14
- examples/example_nvdb.py +14 -16
- examples/example_raycast.py +14 -13
- examples/example_raymarch.py +16 -23
- examples/example_render_opengl.py +19 -10
- examples/example_sim_cartpole.py +82 -78
- examples/example_sim_cloth.py +45 -48
- examples/example_sim_fk_grad.py +51 -44
- examples/example_sim_fk_grad_torch.py +47 -40
- examples/example_sim_grad_bounce.py +108 -133
- examples/example_sim_grad_cloth.py +99 -113
- examples/example_sim_granular.py +5 -6
- examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
- examples/example_sim_neo_hookean.py +51 -55
- examples/example_sim_particle_chain.py +4 -4
- examples/example_sim_quadruped.py +126 -81
- examples/example_sim_rigid_chain.py +54 -61
- examples/example_sim_rigid_contact.py +66 -70
- examples/example_sim_rigid_fem.py +3 -3
- examples/example_sim_rigid_force.py +1 -1
- examples/example_sim_rigid_gyroscopic.py +3 -4
- examples/example_sim_rigid_kinematics.py +28 -39
- examples/example_sim_trajopt.py +112 -110
- examples/example_sph.py +9 -8
- examples/example_wave.py +7 -7
- examples/fem/bsr_utils.py +30 -17
- examples/fem/example_apic_fluid.py +85 -69
- examples/fem/example_convection_diffusion.py +97 -93
- examples/fem/example_convection_diffusion_dg.py +142 -149
- examples/fem/example_convection_diffusion_dg0.py +141 -136
- examples/fem/example_deformed_geometry.py +146 -0
- examples/fem/example_diffusion.py +115 -84
- examples/fem/example_diffusion_3d.py +116 -86
- examples/fem/example_diffusion_mgpu.py +102 -79
- examples/fem/example_mixed_elasticity.py +139 -100
- examples/fem/example_navier_stokes.py +175 -162
- examples/fem/example_stokes.py +143 -111
- examples/fem/example_stokes_transfer.py +186 -157
- examples/fem/mesh_utils.py +59 -97
- examples/fem/plot_utils.py +138 -17
- tools/ci/publishing/build_nodes_info.py +54 -0
- warp/__init__.py +4 -3
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +5 -3
- warp/build_dll.py +29 -9
- warp/builtins.py +836 -492
- warp/codegen.py +864 -553
- warp/config.py +3 -1
- warp/context.py +389 -172
- warp/fem/__init__.py +24 -6
- warp/fem/cache.py +318 -25
- warp/fem/dirichlet.py +7 -3
- warp/fem/domain.py +14 -0
- warp/fem/field/__init__.py +30 -38
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +244 -138
- warp/fem/field/restriction.py +8 -6
- warp/fem/field/test.py +127 -59
- warp/fem/field/trial.py +117 -60
- warp/fem/geometry/__init__.py +5 -1
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +24 -1
- warp/fem/geometry/geometry.py +86 -14
- warp/fem/geometry/grid_2d.py +112 -54
- warp/fem/geometry/grid_3d.py +134 -65
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +85 -33
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +451 -115
- warp/fem/geometry/trimesh_2d.py +197 -92
- warp/fem/integrate.py +534 -268
- warp/fem/operator.py +58 -31
- warp/fem/polynomial.py +11 -0
- warp/fem/quadrature/__init__.py +1 -1
- warp/fem/quadrature/pic_quadrature.py +150 -58
- warp/fem/quadrature/quadrature.py +209 -57
- warp/fem/space/__init__.py +230 -53
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +49 -2
- warp/fem/space/function_space.py +90 -39
- warp/fem/space/grid_2d_function_space.py +149 -496
- warp/fem/space/grid_3d_function_space.py +173 -538
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +129 -76
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +46 -34
- warp/fem/space/shape/__init__.py +15 -0
- warp/fem/space/shape/cube_shape_function.py +738 -0
- warp/fem/space/shape/shape_function.py +103 -0
- warp/fem/space/shape/square_shape_function.py +611 -0
- warp/fem/space/shape/tet_shape_function.py +567 -0
- warp/fem/space/shape/triangle_shape_function.py +429 -0
- warp/fem/space/tetmesh_function_space.py +132 -1039
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +104 -742
- warp/fem/types.py +13 -11
- warp/fem/utils.py +335 -60
- warp/native/array.h +120 -34
- warp/native/builtin.h +101 -72
- warp/native/bvh.cpp +73 -325
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +22 -40
- warp/native/clang/clang.cpp +1 -0
- warp/native/crt.h +2 -0
- warp/native/cuda_util.cpp +8 -3
- warp/native/cuda_util.h +1 -0
- warp/native/exports.h +1522 -1243
- warp/native/intersect.h +19 -4
- warp/native/intersect_adj.h +8 -8
- warp/native/mat.h +76 -17
- warp/native/mesh.cpp +33 -108
- warp/native/mesh.cu +114 -18
- warp/native/mesh.h +395 -40
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +44 -34
- warp/native/reduce.cpp +1 -1
- warp/native/sparse.cpp +4 -4
- warp/native/sparse.cu +163 -155
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +18 -14
- warp/native/vec.h +103 -21
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +28 -3
- warp/native/warp.h +4 -3
- warp/render/render_opengl.py +261 -109
- warp/sim/__init__.py +1 -2
- warp/sim/articulation.py +385 -185
- warp/sim/import_mjcf.py +59 -48
- warp/sim/import_urdf.py +15 -15
- warp/sim/import_usd.py +174 -102
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_xpbd.py +4 -3
- warp/sim/model.py +330 -250
- warp/sim/render.py +1 -1
- warp/sparse.py +625 -152
- warp/stubs.py +341 -309
- warp/tape.py +9 -6
- warp/tests/__main__.py +3 -6
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/disabled_kinematics.py +239 -0
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +103 -106
- warp/tests/test_arithmetic.py +94 -74
- warp/tests/test_array.py +82 -101
- warp/tests/test_array_reduce.py +57 -23
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +22 -12
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +18 -18
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +165 -134
- warp/tests/test_compile_consts.py +28 -20
- warp/tests/test_conditional.py +108 -24
- warp/tests/test_copy.py +10 -12
- warp/tests/test_ctypes.py +112 -88
- warp/tests/test_dense.py +21 -14
- warp/tests/test_devices.py +98 -0
- warp/tests/test_dlpack.py +75 -75
- warp/tests/test_examples.py +237 -0
- warp/tests/test_fabricarray.py +22 -24
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1034 -124
- warp/tests/test_fp16.py +23 -16
- warp/tests/test_func.py +187 -86
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +123 -181
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +35 -34
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +24 -25
- warp/tests/test_intersect.py +18 -9
- warp/tests/test_large.py +141 -0
- warp/tests/test_launch.py +14 -41
- warp/tests/test_lerp.py +64 -65
- warp/tests/test_lvalue.py +493 -0
- warp/tests/test_marching_cubes.py +12 -13
- warp/tests/test_mat.py +517 -2898
- warp/tests/test_mat_lite.py +115 -0
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +103 -9
- warp/tests/test_matmul.py +304 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +60 -22
- warp/tests/test_mesh_query_aabb.py +21 -25
- warp/tests/test_mesh_query_point.py +111 -22
- warp/tests/test_mesh_query_ray.py +12 -24
- warp/tests/test_mlp.py +30 -22
- warp/tests/test_model.py +92 -89
- warp/tests/test_modules_lite.py +39 -0
- warp/tests/test_multigpu.py +88 -114
- warp/tests/test_noise.py +12 -11
- warp/tests/test_operators.py +16 -20
- warp/tests/test_options.py +11 -11
- warp/tests/test_pinned.py +17 -18
- warp/tests/test_print.py +32 -11
- warp/tests/test_quat.py +275 -129
- warp/tests/test_rand.py +18 -16
- warp/tests/test_reload.py +38 -34
- warp/tests/test_rounding.py +50 -43
- warp/tests/test_runlength_encode.py +168 -20
- warp/tests/test_smoothstep.py +9 -11
- warp/tests/test_snippet.py +143 -0
- warp/tests/test_sparse.py +261 -63
- warp/tests/test_spatial.py +276 -243
- warp/tests/test_streams.py +110 -85
- warp/tests/test_struct.py +268 -63
- warp/tests/test_tape.py +39 -21
- warp/tests/test_torch.py +90 -86
- warp/tests/test_transient_module.py +10 -12
- warp/tests/test_types.py +363 -0
- warp/tests/test_utils.py +451 -0
- warp/tests/test_vec.py +354 -2050
- warp/tests/test_vec_lite.py +73 -0
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +418 -376
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +291 -0
- warp/tests/unittest_utils.py +342 -0
- warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +589 -0
- warp/types.py +622 -211
- warp/utils.py +54 -393
- warp_lang-1.0.0b6.dist-info/METADATA +238 -0
- warp_lang-1.0.0b6.dist-info/RECORD +409 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
- examples/example_cache_management.py +0 -40
- examples/example_multigpu.py +0 -54
- examples/example_struct.py +0 -65
- examples/fem/example_stokes_transfer_3d.py +0 -210
- warp/fem/field/discrete_field.py +0 -80
- warp/fem/space/nodal_function_space.py +0 -233
- warp/tests/test_all.py +0 -223
- warp/tests/test_array_scan.py +0 -60
- warp/tests/test_base.py +0 -208
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- warp_lang-1.0.0b2.dist-info/METADATA +0 -26
- warp_lang-1.0.0b2.dist-info/RECORD +0 -378
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
examples/fem/mesh_utils.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
+
|
examples/fem/plot_utils.py
CHANGED
|
@@ -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.
|
|
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, "
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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,
|
|
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(
|
|
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}-
|
|
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}-
|
|
379
|
+
os.remove(f"{dll_path}-aarch64")
|
|
362
380
|
|
|
363
381
|
else:
|
|
364
|
-
build_dll_for_arch(
|
|
382
|
+
build_dll_for_arch(
|
|
383
|
+
dll_path, cpp_paths, cu_path, libs, mode, machine_architecture(), verify_fp, fast_math, quick
|
|
384
|
+
)
|