warp-lang 0.11.0__py3-none-manylinux2014_x86_64.whl → 1.0.0__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.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +8 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +7 -6
- warp/build_dll.py +70 -79
- warp/builtins.py +10 -6
- warp/codegen.py +51 -19
- warp/config.py +7 -8
- warp/constants.py +3 -0
- warp/context.py +948 -245
- warp/dlpack.py +198 -113
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -0
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usda +42 -0
- warp/examples/assets/nv_ant.xml +92 -0
- warp/examples/assets/nv_humanoid.xml +183 -0
- warp/examples/assets/quadruped.urdf +268 -0
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usda +56 -0
- warp/examples/assets/torus.usda +105 -0
- warp/examples/benchmarks/benchmark_api.py +383 -0
- warp/examples/benchmarks/benchmark_cloth.py +279 -0
- warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -0
- warp/examples/benchmarks/benchmark_cloth_jax.py +100 -0
- warp/examples/benchmarks/benchmark_cloth_numba.py +142 -0
- warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -0
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -0
- warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +146 -0
- warp/examples/benchmarks/benchmark_launches.py +295 -0
- warp/examples/core/example_dem.py +221 -0
- warp/examples/core/example_fluid.py +267 -0
- warp/examples/core/example_graph_capture.py +129 -0
- warp/examples/core/example_marching_cubes.py +177 -0
- warp/examples/core/example_mesh.py +154 -0
- warp/examples/core/example_mesh_intersect.py +193 -0
- warp/examples/core/example_nvdb.py +169 -0
- warp/examples/core/example_raycast.py +89 -0
- warp/examples/core/example_raymarch.py +178 -0
- warp/examples/core/example_render_opengl.py +141 -0
- warp/examples/core/example_sph.py +389 -0
- warp/examples/core/example_torch.py +181 -0
- warp/examples/core/example_wave.py +249 -0
- warp/examples/fem/bsr_utils.py +380 -0
- warp/examples/fem/example_apic_fluid.py +391 -0
- warp/examples/fem/example_convection_diffusion.py +168 -0
- warp/examples/fem/example_convection_diffusion_dg.py +209 -0
- warp/examples/fem/example_convection_diffusion_dg0.py +194 -0
- warp/examples/fem/example_deformed_geometry.py +159 -0
- warp/examples/fem/example_diffusion.py +173 -0
- warp/examples/fem/example_diffusion_3d.py +152 -0
- warp/examples/fem/example_diffusion_mgpu.py +214 -0
- warp/examples/fem/example_mixed_elasticity.py +222 -0
- warp/examples/fem/example_navier_stokes.py +243 -0
- warp/examples/fem/example_stokes.py +192 -0
- warp/examples/fem/example_stokes_transfer.py +249 -0
- warp/examples/fem/mesh_utils.py +109 -0
- warp/examples/fem/plot_utils.py +287 -0
- warp/examples/optim/example_bounce.py +248 -0
- warp/examples/optim/example_cloth_throw.py +210 -0
- warp/examples/optim/example_diffray.py +535 -0
- warp/examples/optim/example_drone.py +850 -0
- warp/examples/optim/example_inverse_kinematics.py +169 -0
- warp/examples/optim/example_inverse_kinematics_torch.py +170 -0
- warp/examples/optim/example_spring_cage.py +234 -0
- warp/examples/optim/example_trajectory.py +201 -0
- warp/examples/sim/example_cartpole.py +128 -0
- warp/examples/sim/example_cloth.py +184 -0
- warp/examples/sim/example_granular.py +113 -0
- warp/examples/sim/example_granular_collision_sdf.py +185 -0
- warp/examples/sim/example_jacobian_ik.py +213 -0
- warp/examples/sim/example_particle_chain.py +106 -0
- warp/examples/sim/example_quadruped.py +179 -0
- warp/examples/sim/example_rigid_chain.py +191 -0
- warp/examples/sim/example_rigid_contact.py +176 -0
- warp/examples/sim/example_rigid_force.py +126 -0
- warp/examples/sim/example_rigid_gyroscopic.py +97 -0
- warp/examples/sim/example_rigid_soft_contact.py +124 -0
- warp/examples/sim/example_soft_body.py +178 -0
- warp/fabric.py +29 -20
- warp/fem/cache.py +0 -1
- warp/fem/dirichlet.py +0 -2
- warp/fem/integrate.py +0 -1
- warp/jax.py +45 -0
- warp/jax_experimental.py +339 -0
- warp/native/builtin.h +12 -0
- warp/native/bvh.cu +18 -18
- warp/native/clang/clang.cpp +8 -3
- warp/native/cuda_util.cpp +94 -5
- warp/native/cuda_util.h +35 -6
- warp/native/cutlass_gemm.cpp +1 -1
- warp/native/cutlass_gemm.cu +4 -1
- warp/native/error.cpp +66 -0
- warp/native/error.h +27 -0
- warp/native/mesh.cu +2 -2
- warp/native/reduce.cu +4 -4
- warp/native/runlength_encode.cu +2 -2
- warp/native/scan.cu +2 -2
- warp/native/sparse.cu +0 -1
- warp/native/temp_buffer.h +2 -2
- warp/native/warp.cpp +95 -60
- warp/native/warp.cu +1053 -218
- warp/native/warp.h +49 -32
- warp/optim/linear.py +33 -16
- warp/render/render_opengl.py +202 -101
- warp/render/render_usd.py +82 -40
- warp/sim/__init__.py +13 -4
- warp/sim/articulation.py +4 -5
- warp/sim/collide.py +320 -175
- warp/sim/import_mjcf.py +25 -30
- warp/sim/import_urdf.py +94 -63
- warp/sim/import_usd.py +51 -36
- warp/sim/inertia.py +3 -2
- warp/sim/integrator.py +233 -0
- warp/sim/integrator_euler.py +447 -469
- warp/sim/integrator_featherstone.py +1991 -0
- warp/sim/integrator_xpbd.py +1420 -640
- warp/sim/model.py +765 -487
- warp/sim/particles.py +2 -1
- warp/sim/render.py +35 -13
- warp/sim/utils.py +222 -11
- warp/stubs.py +8 -0
- warp/tape.py +16 -1
- warp/tests/aux_test_grad_customs.py +23 -0
- warp/tests/test_array.py +190 -1
- warp/tests/test_async.py +656 -0
- warp/tests/test_bool.py +50 -0
- warp/tests/test_dlpack.py +164 -11
- warp/tests/test_examples.py +166 -74
- warp/tests/test_fem.py +8 -1
- warp/tests/test_generics.py +15 -5
- warp/tests/test_grad.py +1 -1
- warp/tests/test_grad_customs.py +172 -12
- warp/tests/test_jax.py +254 -0
- warp/tests/test_large.py +29 -6
- warp/tests/test_launch.py +25 -0
- warp/tests/test_linear_solvers.py +20 -3
- warp/tests/test_matmul.py +61 -16
- warp/tests/test_matmul_lite.py +13 -13
- warp/tests/test_mempool.py +186 -0
- warp/tests/test_multigpu.py +3 -0
- warp/tests/test_options.py +16 -2
- warp/tests/test_peer.py +137 -0
- warp/tests/test_print.py +3 -1
- warp/tests/test_quat.py +23 -0
- warp/tests/test_sim_kinematics.py +97 -0
- warp/tests/test_snippet.py +126 -3
- warp/tests/test_streams.py +108 -79
- warp/tests/test_torch.py +16 -8
- warp/tests/test_utils.py +32 -27
- warp/tests/test_verify_fp.py +65 -0
- warp/tests/test_volume.py +1 -1
- warp/tests/unittest_serial.py +2 -0
- warp/tests/unittest_suites.py +12 -0
- warp/tests/unittest_utils.py +14 -7
- warp/thirdparty/unittest_parallel.py +15 -3
- warp/torch.py +10 -8
- warp/types.py +363 -246
- warp/utils.py +143 -19
- warp_lang-1.0.0.dist-info/LICENSE.md +126 -0
- warp_lang-1.0.0.dist-info/METADATA +394 -0
- {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/RECORD +167 -86
- warp/sim/optimizer.py +0 -138
- warp_lang-0.11.0.dist-info/LICENSE.md +0 -36
- warp_lang-0.11.0.dist-info/METADATA +0 -238
- /warp/tests/{walkthough_debug.py → walkthrough_debug.py} +0 -0
- {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/WHEEL +0 -0
- {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Copyright (c) 2022 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
|
+
import warp as wp
|
|
9
|
+
|
|
10
|
+
wp.init()
|
|
11
|
+
wp.build.clear_kernel_cache()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@wp.kernel
|
|
15
|
+
def eval_springs(
|
|
16
|
+
x: wp.array(dtype=wp.vec3),
|
|
17
|
+
v: wp.array(dtype=wp.vec3),
|
|
18
|
+
spring_indices: wp.array(dtype=int),
|
|
19
|
+
spring_rest_lengths: wp.array(dtype=float),
|
|
20
|
+
spring_stiffness: wp.array(dtype=float),
|
|
21
|
+
spring_damping: wp.array(dtype=float),
|
|
22
|
+
f: wp.array(dtype=wp.vec3),
|
|
23
|
+
):
|
|
24
|
+
tid = wp.tid()
|
|
25
|
+
|
|
26
|
+
i = spring_indices[tid * 2 + 0]
|
|
27
|
+
j = spring_indices[tid * 2 + 1]
|
|
28
|
+
|
|
29
|
+
ke = spring_stiffness[tid]
|
|
30
|
+
kd = spring_damping[tid]
|
|
31
|
+
rest = spring_rest_lengths[tid]
|
|
32
|
+
|
|
33
|
+
xi = x[i]
|
|
34
|
+
xj = x[j]
|
|
35
|
+
|
|
36
|
+
vi = v[i]
|
|
37
|
+
vj = v[j]
|
|
38
|
+
|
|
39
|
+
xij = xi - xj
|
|
40
|
+
vij = vi - vj
|
|
41
|
+
|
|
42
|
+
l = wp.length(xij)
|
|
43
|
+
l_inv = 1.0 / l
|
|
44
|
+
|
|
45
|
+
# normalized spring direction
|
|
46
|
+
dir = xij * l_inv
|
|
47
|
+
|
|
48
|
+
c = l - rest
|
|
49
|
+
dcdt = wp.dot(dir, vij)
|
|
50
|
+
|
|
51
|
+
# damping based on relative velocity.
|
|
52
|
+
fs = dir * (ke * c + kd * dcdt)
|
|
53
|
+
|
|
54
|
+
wp.atomic_sub(f, i, fs)
|
|
55
|
+
wp.atomic_add(f, j, fs)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@wp.kernel
|
|
59
|
+
def integrate_particles(
|
|
60
|
+
x: wp.array(dtype=wp.vec3),
|
|
61
|
+
v: wp.array(dtype=wp.vec3),
|
|
62
|
+
f: wp.array(dtype=wp.vec3),
|
|
63
|
+
w: wp.array(dtype=float),
|
|
64
|
+
dt: float,
|
|
65
|
+
):
|
|
66
|
+
tid = wp.tid()
|
|
67
|
+
|
|
68
|
+
x0 = x[tid]
|
|
69
|
+
v0 = v[tid]
|
|
70
|
+
f0 = f[tid]
|
|
71
|
+
inv_mass = w[tid]
|
|
72
|
+
|
|
73
|
+
g = wp.vec3()
|
|
74
|
+
|
|
75
|
+
# treat particles with inv_mass == 0 as kinematic
|
|
76
|
+
if inv_mass > 0.0:
|
|
77
|
+
g = wp.vec3(0.0, 0.0 - 9.81, 0.0)
|
|
78
|
+
|
|
79
|
+
# simple semi-implicit Euler. v1 = v0 + a dt, x1 = x0 + v1 dt
|
|
80
|
+
v1 = v0 + (f0 * inv_mass + g) * dt
|
|
81
|
+
x1 = x0 + v1 * dt
|
|
82
|
+
|
|
83
|
+
x[tid] = x1
|
|
84
|
+
v[tid] = v1
|
|
85
|
+
|
|
86
|
+
# clear forces
|
|
87
|
+
f[tid] = wp.vec3()
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class WpIntegrator:
|
|
91
|
+
def __init__(self, cloth, device):
|
|
92
|
+
self.device = wp.get_device(device)
|
|
93
|
+
|
|
94
|
+
with wp.ScopedDevice(self.device):
|
|
95
|
+
self.positions = wp.from_numpy(cloth.positions, dtype=wp.vec3)
|
|
96
|
+
self.positions_host = wp.from_numpy(cloth.positions, dtype=wp.vec3, device="cpu")
|
|
97
|
+
self.invmass = wp.from_numpy(cloth.inv_masses, dtype=float)
|
|
98
|
+
|
|
99
|
+
self.velocities = wp.zeros(cloth.num_particles, dtype=wp.vec3)
|
|
100
|
+
self.forces = wp.zeros(cloth.num_particles, dtype=wp.vec3)
|
|
101
|
+
|
|
102
|
+
self.spring_indices = wp.from_numpy(cloth.spring_indices, dtype=int)
|
|
103
|
+
self.spring_lengths = wp.from_numpy(cloth.spring_lengths, dtype=float)
|
|
104
|
+
self.spring_stiffness = wp.from_numpy(cloth.spring_stiffness, dtype=float)
|
|
105
|
+
self.spring_damping = wp.from_numpy(cloth.spring_damping, dtype=float)
|
|
106
|
+
|
|
107
|
+
self.cloth = cloth
|
|
108
|
+
|
|
109
|
+
def simulate(self, dt, substeps):
|
|
110
|
+
sim_dt = dt / substeps
|
|
111
|
+
|
|
112
|
+
for s in range(substeps):
|
|
113
|
+
wp.launch(
|
|
114
|
+
kernel=eval_springs,
|
|
115
|
+
dim=self.cloth.num_springs,
|
|
116
|
+
inputs=[
|
|
117
|
+
self.positions,
|
|
118
|
+
self.velocities,
|
|
119
|
+
self.spring_indices,
|
|
120
|
+
self.spring_lengths,
|
|
121
|
+
self.spring_stiffness,
|
|
122
|
+
self.spring_damping,
|
|
123
|
+
self.forces,
|
|
124
|
+
],
|
|
125
|
+
outputs=[],
|
|
126
|
+
device=self.device,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# integrate
|
|
130
|
+
wp.launch(
|
|
131
|
+
kernel=integrate_particles,
|
|
132
|
+
dim=self.cloth.num_particles,
|
|
133
|
+
inputs=[self.positions, self.velocities, self.forces, self.invmass, sim_dt],
|
|
134
|
+
outputs=[],
|
|
135
|
+
device=self.device,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# copy data back to host
|
|
139
|
+
if self.device.is_cuda:
|
|
140
|
+
wp.copy(self.positions_host, self.positions)
|
|
141
|
+
wp.synchronize()
|
|
142
|
+
|
|
143
|
+
return self.positions_host.numpy()
|
|
144
|
+
|
|
145
|
+
else:
|
|
146
|
+
return self.positions.numpy()
|
|
@@ -0,0 +1,295 @@
|
|
|
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
|
+
###########################################################################
|
|
9
|
+
# Benchmarks for kernel launches with different types of args
|
|
10
|
+
###########################################################################
|
|
11
|
+
|
|
12
|
+
import warp as wp
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@wp.struct
|
|
16
|
+
class S0:
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@wp.struct
|
|
21
|
+
class Sf:
|
|
22
|
+
x: float
|
|
23
|
+
y: float
|
|
24
|
+
z: float
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@wp.struct
|
|
28
|
+
class Sv:
|
|
29
|
+
u: wp.vec3
|
|
30
|
+
v: wp.vec3
|
|
31
|
+
w: wp.vec3
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@wp.struct
|
|
35
|
+
class Sm:
|
|
36
|
+
M: wp.mat33
|
|
37
|
+
N: wp.mat33
|
|
38
|
+
O: wp.mat33
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@wp.struct
|
|
42
|
+
class Sa:
|
|
43
|
+
a: wp.array(dtype=float)
|
|
44
|
+
b: wp.array(dtype=float)
|
|
45
|
+
c: wp.array(dtype=float)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@wp.struct
|
|
49
|
+
class Sz:
|
|
50
|
+
a: wp.array(dtype=float)
|
|
51
|
+
b: wp.array(dtype=float)
|
|
52
|
+
c: wp.array(dtype=float)
|
|
53
|
+
x: float
|
|
54
|
+
y: float
|
|
55
|
+
z: float
|
|
56
|
+
u: wp.vec3
|
|
57
|
+
v: wp.vec3
|
|
58
|
+
w: wp.vec3
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@wp.kernel
|
|
62
|
+
def k0():
|
|
63
|
+
tid = wp.tid()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@wp.kernel
|
|
67
|
+
def kf(x: float, y: float, z: float):
|
|
68
|
+
tid = wp.tid()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@wp.kernel
|
|
72
|
+
def kv(u: wp.vec3, v: wp.vec3, w: wp.vec3):
|
|
73
|
+
tid = wp.tid()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@wp.kernel
|
|
77
|
+
def km(M: wp.mat33, N: wp.mat33, O: wp.mat33):
|
|
78
|
+
tid = wp.tid()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@wp.kernel
|
|
82
|
+
def ka(a: wp.array(dtype=float), b: wp.array(dtype=float), c: wp.array(dtype=float)):
|
|
83
|
+
tid = wp.tid()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@wp.kernel
|
|
87
|
+
def kz(
|
|
88
|
+
a: wp.array(dtype=float),
|
|
89
|
+
b: wp.array(dtype=float),
|
|
90
|
+
c: wp.array(dtype=float),
|
|
91
|
+
x: float,
|
|
92
|
+
y: float,
|
|
93
|
+
z: float,
|
|
94
|
+
u: wp.vec3,
|
|
95
|
+
v: wp.vec3,
|
|
96
|
+
w: wp.vec3,
|
|
97
|
+
):
|
|
98
|
+
tid = wp.tid()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@wp.kernel
|
|
102
|
+
def ks0(s: S0):
|
|
103
|
+
tid = wp.tid()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@wp.kernel
|
|
107
|
+
def ksf(s: Sf):
|
|
108
|
+
tid = wp.tid()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@wp.kernel
|
|
112
|
+
def ksv(s: Sv):
|
|
113
|
+
tid = wp.tid()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@wp.kernel
|
|
117
|
+
def ksm(s: Sm):
|
|
118
|
+
tid = wp.tid()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@wp.kernel
|
|
122
|
+
def ksa(s: Sa):
|
|
123
|
+
tid = wp.tid()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@wp.kernel
|
|
127
|
+
def ksz(s: Sz):
|
|
128
|
+
tid = wp.tid()
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
wp.init()
|
|
132
|
+
|
|
133
|
+
wp.build.clear_kernel_cache()
|
|
134
|
+
|
|
135
|
+
devices = wp.get_devices()
|
|
136
|
+
num_launches = 100000
|
|
137
|
+
|
|
138
|
+
for device in devices:
|
|
139
|
+
with wp.ScopedDevice(device):
|
|
140
|
+
print(f"\n=================== Device '{device}' ===================")
|
|
141
|
+
|
|
142
|
+
wp.force_load(device)
|
|
143
|
+
|
|
144
|
+
n = 1
|
|
145
|
+
a = wp.zeros(n, dtype=float)
|
|
146
|
+
b = wp.zeros(n, dtype=float)
|
|
147
|
+
c = wp.zeros(n, dtype=float)
|
|
148
|
+
x = 17.0
|
|
149
|
+
y = 42.0
|
|
150
|
+
z = 99.0
|
|
151
|
+
u = wp.vec3(1, 2, 3)
|
|
152
|
+
v = wp.vec3(10, 20, 30)
|
|
153
|
+
w = wp.vec3(100, 200, 300)
|
|
154
|
+
M = wp.mat33()
|
|
155
|
+
N = wp.mat33()
|
|
156
|
+
O = wp.mat33()
|
|
157
|
+
|
|
158
|
+
s0 = S0()
|
|
159
|
+
|
|
160
|
+
sf = Sf()
|
|
161
|
+
sf.x = x
|
|
162
|
+
sf.y = y
|
|
163
|
+
sf.z = z
|
|
164
|
+
|
|
165
|
+
sv = Sv()
|
|
166
|
+
sv.u = u
|
|
167
|
+
sv.v = v
|
|
168
|
+
sv.w = w
|
|
169
|
+
|
|
170
|
+
sm = Sm()
|
|
171
|
+
sm.M = M
|
|
172
|
+
sm.N = N
|
|
173
|
+
sm.O = O
|
|
174
|
+
|
|
175
|
+
sa = Sa()
|
|
176
|
+
sa.a = a
|
|
177
|
+
sa.b = b
|
|
178
|
+
sa.c = c
|
|
179
|
+
|
|
180
|
+
sz = Sz()
|
|
181
|
+
sz.a = a
|
|
182
|
+
sz.b = b
|
|
183
|
+
sz.c = c
|
|
184
|
+
sz.x = x
|
|
185
|
+
sz.y = y
|
|
186
|
+
sz.z = z
|
|
187
|
+
sz.u = u
|
|
188
|
+
sz.v = v
|
|
189
|
+
sz.w = w
|
|
190
|
+
|
|
191
|
+
tk0 = wp.ScopedTimer("k0")
|
|
192
|
+
tkf = wp.ScopedTimer("kf")
|
|
193
|
+
tkv = wp.ScopedTimer("kv")
|
|
194
|
+
tkm = wp.ScopedTimer("km")
|
|
195
|
+
tka = wp.ScopedTimer("ka")
|
|
196
|
+
tkz = wp.ScopedTimer("kz")
|
|
197
|
+
|
|
198
|
+
ts0 = wp.ScopedTimer("s0")
|
|
199
|
+
tsf = wp.ScopedTimer("sf")
|
|
200
|
+
tsv = wp.ScopedTimer("sv")
|
|
201
|
+
tsm = wp.ScopedTimer("sm")
|
|
202
|
+
tsa = wp.ScopedTimer("sa")
|
|
203
|
+
tsz = wp.ScopedTimer("sz")
|
|
204
|
+
|
|
205
|
+
wp.synchronize_device()
|
|
206
|
+
|
|
207
|
+
with tk0:
|
|
208
|
+
for _ in range(num_launches):
|
|
209
|
+
wp.launch(k0, dim=1, inputs=[])
|
|
210
|
+
|
|
211
|
+
wp.synchronize_device()
|
|
212
|
+
|
|
213
|
+
with tkf:
|
|
214
|
+
for _ in range(num_launches):
|
|
215
|
+
wp.launch(kf, dim=1, inputs=[x, y, z])
|
|
216
|
+
|
|
217
|
+
wp.synchronize_device()
|
|
218
|
+
|
|
219
|
+
with tkv:
|
|
220
|
+
for _ in range(num_launches):
|
|
221
|
+
wp.launch(kv, dim=1, inputs=[u, v, w])
|
|
222
|
+
|
|
223
|
+
wp.synchronize_device()
|
|
224
|
+
|
|
225
|
+
with tkm:
|
|
226
|
+
for _ in range(num_launches):
|
|
227
|
+
wp.launch(km, dim=1, inputs=[M, N, O])
|
|
228
|
+
|
|
229
|
+
wp.synchronize_device()
|
|
230
|
+
|
|
231
|
+
with tka:
|
|
232
|
+
for _ in range(num_launches):
|
|
233
|
+
wp.launch(ka, dim=1, inputs=[a, b, c])
|
|
234
|
+
|
|
235
|
+
wp.synchronize_device()
|
|
236
|
+
|
|
237
|
+
with tkz:
|
|
238
|
+
for _ in range(num_launches):
|
|
239
|
+
wp.launch(kz, dim=1, inputs=[a, b, c, x, y, z, u, v, w])
|
|
240
|
+
|
|
241
|
+
# structs
|
|
242
|
+
|
|
243
|
+
wp.synchronize_device()
|
|
244
|
+
|
|
245
|
+
with ts0:
|
|
246
|
+
for _ in range(num_launches):
|
|
247
|
+
wp.launch(ks0, dim=1, inputs=[s0])
|
|
248
|
+
|
|
249
|
+
wp.synchronize_device()
|
|
250
|
+
|
|
251
|
+
with tsf:
|
|
252
|
+
for _ in range(num_launches):
|
|
253
|
+
wp.launch(ksf, dim=1, inputs=[sf])
|
|
254
|
+
|
|
255
|
+
wp.synchronize_device()
|
|
256
|
+
|
|
257
|
+
with tsv:
|
|
258
|
+
for _ in range(num_launches):
|
|
259
|
+
wp.launch(ksv, dim=1, inputs=[sv])
|
|
260
|
+
|
|
261
|
+
wp.synchronize_device()
|
|
262
|
+
|
|
263
|
+
with tsm:
|
|
264
|
+
for _ in range(num_launches):
|
|
265
|
+
wp.launch(ksm, dim=1, inputs=[sm])
|
|
266
|
+
|
|
267
|
+
wp.synchronize_device()
|
|
268
|
+
|
|
269
|
+
with tsa:
|
|
270
|
+
for _ in range(num_launches):
|
|
271
|
+
wp.launch(ksa, dim=1, inputs=[sa])
|
|
272
|
+
|
|
273
|
+
wp.synchronize_device()
|
|
274
|
+
|
|
275
|
+
with tsz:
|
|
276
|
+
for _ in range(num_launches):
|
|
277
|
+
wp.launch(ksz, dim=1, inputs=[sz])
|
|
278
|
+
|
|
279
|
+
wp.synchronize_device()
|
|
280
|
+
|
|
281
|
+
timers = [
|
|
282
|
+
[tk0, ts0],
|
|
283
|
+
[tkf, tsf],
|
|
284
|
+
[tkv, tsv],
|
|
285
|
+
[tkm, tsm],
|
|
286
|
+
[tka, tsa],
|
|
287
|
+
[tkz, tsz],
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
print("--------------------------------")
|
|
291
|
+
print("| args | direct | struct |")
|
|
292
|
+
print("--------------------------------")
|
|
293
|
+
for tk, ts in timers:
|
|
294
|
+
print(f"| {tk.name} |{tk.elapsed:10.0f} |{ts.elapsed:10.0f} |")
|
|
295
|
+
print("--------------------------------")
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Copyright (c) 2022 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
|
+
###########################################################################
|
|
9
|
+
# Example DEM
|
|
10
|
+
#
|
|
11
|
+
# Shows how to implement a DEM particle simulation with cohesion between
|
|
12
|
+
# particles. Neighbors are found using the wp.HashGrid class, and
|
|
13
|
+
# wp.hash_grid_query(), wp.hash_grid_query_next() kernel methods.
|
|
14
|
+
#
|
|
15
|
+
###########################################################################
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
import warp as wp
|
|
22
|
+
import warp.render
|
|
23
|
+
|
|
24
|
+
wp.init()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@wp.func
|
|
28
|
+
def contact_force(n: wp.vec3, v: wp.vec3, c: float, k_n: float, k_d: float, k_f: float, k_mu: float):
|
|
29
|
+
vn = wp.dot(n, v)
|
|
30
|
+
jn = c * k_n
|
|
31
|
+
jd = min(vn, 0.0) * k_d
|
|
32
|
+
|
|
33
|
+
# contact force
|
|
34
|
+
fn = jn + jd
|
|
35
|
+
|
|
36
|
+
# friction force
|
|
37
|
+
vt = v - n * vn
|
|
38
|
+
vs = wp.length(vt)
|
|
39
|
+
|
|
40
|
+
if vs > 0.0:
|
|
41
|
+
vt = vt / vs
|
|
42
|
+
|
|
43
|
+
# Coulomb condition
|
|
44
|
+
ft = wp.min(vs * k_f, k_mu * wp.abs(fn))
|
|
45
|
+
|
|
46
|
+
# total force
|
|
47
|
+
return -n * fn - vt * ft
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@wp.kernel
|
|
51
|
+
def apply_forces(
|
|
52
|
+
grid: wp.uint64,
|
|
53
|
+
particle_x: wp.array(dtype=wp.vec3),
|
|
54
|
+
particle_v: wp.array(dtype=wp.vec3),
|
|
55
|
+
particle_f: wp.array(dtype=wp.vec3),
|
|
56
|
+
radius: float,
|
|
57
|
+
k_contact: float,
|
|
58
|
+
k_damp: float,
|
|
59
|
+
k_friction: float,
|
|
60
|
+
k_mu: float,
|
|
61
|
+
):
|
|
62
|
+
tid = wp.tid()
|
|
63
|
+
|
|
64
|
+
# order threads by cell
|
|
65
|
+
i = wp.hash_grid_point_id(grid, tid)
|
|
66
|
+
|
|
67
|
+
x = particle_x[i]
|
|
68
|
+
v = particle_v[i]
|
|
69
|
+
|
|
70
|
+
f = wp.vec3()
|
|
71
|
+
|
|
72
|
+
# ground contact
|
|
73
|
+
n = wp.vec3(0.0, 1.0, 0.0)
|
|
74
|
+
c = wp.dot(n, x)
|
|
75
|
+
|
|
76
|
+
cohesion_ground = 0.02
|
|
77
|
+
cohesion_particle = 0.0075
|
|
78
|
+
|
|
79
|
+
if c < cohesion_ground:
|
|
80
|
+
f = f + contact_force(n, v, c, k_contact, k_damp, 100.0, 0.5)
|
|
81
|
+
|
|
82
|
+
# particle contact
|
|
83
|
+
neighbors = wp.hash_grid_query(grid, x, radius * 5.0)
|
|
84
|
+
|
|
85
|
+
for index in neighbors:
|
|
86
|
+
if index != i:
|
|
87
|
+
# compute distance to point
|
|
88
|
+
n = x - particle_x[index]
|
|
89
|
+
d = wp.length(n)
|
|
90
|
+
err = d - radius * 2.0
|
|
91
|
+
|
|
92
|
+
if err <= cohesion_particle:
|
|
93
|
+
n = n / d
|
|
94
|
+
vrel = v - particle_v[index]
|
|
95
|
+
|
|
96
|
+
f = f + contact_force(n, vrel, err, k_contact, k_damp, k_friction, k_mu)
|
|
97
|
+
|
|
98
|
+
particle_f[i] = f
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@wp.kernel
|
|
102
|
+
def integrate(
|
|
103
|
+
x: wp.array(dtype=wp.vec3),
|
|
104
|
+
v: wp.array(dtype=wp.vec3),
|
|
105
|
+
f: wp.array(dtype=wp.vec3),
|
|
106
|
+
gravity: wp.vec3,
|
|
107
|
+
dt: float,
|
|
108
|
+
inv_mass: float,
|
|
109
|
+
):
|
|
110
|
+
tid = wp.tid()
|
|
111
|
+
|
|
112
|
+
v_new = v[tid] + f[tid] * inv_mass * dt + gravity * dt
|
|
113
|
+
x_new = x[tid] + v_new * dt
|
|
114
|
+
|
|
115
|
+
v[tid] = v_new
|
|
116
|
+
x[tid] = x_new
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class Example:
|
|
120
|
+
def __init__(self, stage):
|
|
121
|
+
self.frame_dt = 1.0 / 60
|
|
122
|
+
self.frame_count = 400
|
|
123
|
+
|
|
124
|
+
self.sim_substeps = 64
|
|
125
|
+
self.sim_dt = self.frame_dt / self.sim_substeps
|
|
126
|
+
self.sim_steps = self.frame_count * self.sim_substeps
|
|
127
|
+
self.sim_time = 0.0
|
|
128
|
+
|
|
129
|
+
self.point_radius = 0.1
|
|
130
|
+
|
|
131
|
+
self.k_contact = 8000.0
|
|
132
|
+
self.k_damp = 2.0
|
|
133
|
+
self.k_friction = 1.0
|
|
134
|
+
self.k_mu = 100000.0 # for cohesive materials
|
|
135
|
+
|
|
136
|
+
self.inv_mass = 64.0
|
|
137
|
+
|
|
138
|
+
self.grid = wp.HashGrid(128, 128, 128)
|
|
139
|
+
self.grid_cell_size = self.point_radius * 5.0
|
|
140
|
+
|
|
141
|
+
self.points = self.particle_grid(32, 128, 32, (0.0, 0.3, 0.0), self.point_radius, 0.1)
|
|
142
|
+
|
|
143
|
+
self.x = wp.array(self.points, dtype=wp.vec3)
|
|
144
|
+
self.v = wp.array(np.ones([len(self.x), 3]) * np.array([0.0, 0.0, 10.0]), dtype=wp.vec3)
|
|
145
|
+
self.f = wp.zeros_like(self.v)
|
|
146
|
+
|
|
147
|
+
self.renderer = None
|
|
148
|
+
if stage is not None:
|
|
149
|
+
self.renderer = wp.render.UsdRenderer(stage)
|
|
150
|
+
self.renderer.render_ground()
|
|
151
|
+
|
|
152
|
+
self.use_graph = wp.get_device().is_cuda
|
|
153
|
+
if self.use_graph:
|
|
154
|
+
with wp.ScopedCapture() as capture:
|
|
155
|
+
self.simulate()
|
|
156
|
+
self.graph = capture.graph
|
|
157
|
+
|
|
158
|
+
def simulate(self):
|
|
159
|
+
for _ in range(self.sim_substeps):
|
|
160
|
+
wp.launch(
|
|
161
|
+
kernel=apply_forces,
|
|
162
|
+
dim=len(self.x),
|
|
163
|
+
inputs=[
|
|
164
|
+
self.grid.id,
|
|
165
|
+
self.x,
|
|
166
|
+
self.v,
|
|
167
|
+
self.f,
|
|
168
|
+
self.point_radius,
|
|
169
|
+
self.k_contact,
|
|
170
|
+
self.k_damp,
|
|
171
|
+
self.k_friction,
|
|
172
|
+
self.k_mu,
|
|
173
|
+
],
|
|
174
|
+
)
|
|
175
|
+
wp.launch(
|
|
176
|
+
kernel=integrate,
|
|
177
|
+
dim=len(self.x),
|
|
178
|
+
inputs=[self.x, self.v, self.f, (0.0, -9.8, 0.0), self.sim_dt, self.inv_mass],
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def step(self):
|
|
182
|
+
with wp.ScopedTimer("step", active=True):
|
|
183
|
+
with wp.ScopedTimer("grid build", active=False):
|
|
184
|
+
self.grid.build(self.x, self.grid_cell_size)
|
|
185
|
+
|
|
186
|
+
if self.use_graph:
|
|
187
|
+
wp.capture_launch(self.graph)
|
|
188
|
+
else:
|
|
189
|
+
self.simulate()
|
|
190
|
+
|
|
191
|
+
self.sim_time += self.frame_dt
|
|
192
|
+
|
|
193
|
+
def render(self):
|
|
194
|
+
if self.renderer is None:
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
with wp.ScopedTimer("render", active=True):
|
|
198
|
+
self.renderer.begin_frame(self.sim_time)
|
|
199
|
+
self.renderer.render_points(points=self.x.numpy(), radius=self.point_radius, name="points", colors=((0.8, 0.3, 0.2),) * len(self.x))
|
|
200
|
+
self.renderer.end_frame()
|
|
201
|
+
|
|
202
|
+
# creates a grid of particles
|
|
203
|
+
def particle_grid(self, dim_x, dim_y, dim_z, lower, radius, jitter):
|
|
204
|
+
points = np.meshgrid(np.linspace(0, dim_x, dim_x), np.linspace(0, dim_y, dim_y), np.linspace(0, dim_z, dim_z))
|
|
205
|
+
points_t = np.array((points[0], points[1], points[2])).T * radius * 2.0 + np.array(lower)
|
|
206
|
+
points_t = points_t + np.random.rand(*points_t.shape) * radius * jitter
|
|
207
|
+
|
|
208
|
+
return points_t.reshape((-1, 3))
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
if __name__ == "__main__":
|
|
212
|
+
stage_path = os.path.join(os.path.dirname(__file__), "example_dem.usd")
|
|
213
|
+
|
|
214
|
+
example = Example(stage_path)
|
|
215
|
+
|
|
216
|
+
for i in range(example.frame_count):
|
|
217
|
+
example.step()
|
|
218
|
+
example.render()
|
|
219
|
+
|
|
220
|
+
if example.renderer:
|
|
221
|
+
example.renderer.save()
|