warp-lang 1.5.1__py3-none-macosx_10_13_universal2.whl → 1.6.1__py3-none-macosx_10_13_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +5 -0
- warp/autograd.py +414 -191
- warp/bin/libwarp-clang.dylib +0 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +40 -12
- warp/build_dll.py +13 -6
- warp/builtins.py +1077 -481
- warp/codegen.py +250 -122
- warp/config.py +65 -21
- warp/context.py +500 -149
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_gemm.py +27 -18
- warp/examples/benchmarks/benchmark_interop_paddle.py +3 -3
- warp/examples/benchmarks/benchmark_interop_torch.py +3 -3
- warp/examples/core/example_marching_cubes.py +1 -1
- warp/examples/core/example_mesh.py +1 -1
- warp/examples/core/example_torch.py +18 -34
- warp/examples/core/example_wave.py +1 -1
- warp/examples/fem/example_apic_fluid.py +1 -0
- warp/examples/fem/example_mixed_elasticity.py +1 -1
- warp/examples/optim/example_bounce.py +1 -1
- warp/examples/optim/example_cloth_throw.py +1 -1
- warp/examples/optim/example_diffray.py +4 -15
- warp/examples/optim/example_drone.py +1 -1
- warp/examples/optim/example_softbody_properties.py +392 -0
- warp/examples/optim/example_trajectory.py +1 -3
- warp/examples/optim/example_walker.py +5 -0
- warp/examples/sim/example_cartpole.py +0 -2
- warp/examples/sim/example_cloth_self_contact.py +314 -0
- warp/examples/sim/example_granular_collision_sdf.py +4 -5
- warp/examples/sim/example_jacobian_ik.py +0 -2
- warp/examples/sim/example_quadruped.py +5 -2
- warp/examples/tile/example_tile_cholesky.py +79 -0
- warp/examples/tile/example_tile_convolution.py +2 -2
- warp/examples/tile/example_tile_fft.py +2 -2
- warp/examples/tile/example_tile_filtering.py +3 -3
- warp/examples/tile/example_tile_matmul.py +4 -4
- warp/examples/tile/example_tile_mlp.py +12 -12
- warp/examples/tile/example_tile_nbody.py +191 -0
- warp/examples/tile/example_tile_walker.py +319 -0
- warp/math.py +147 -0
- warp/native/array.h +12 -0
- warp/native/builtin.h +0 -1
- warp/native/bvh.cpp +149 -70
- warp/native/bvh.cu +287 -68
- warp/native/bvh.h +195 -85
- warp/native/clang/clang.cpp +6 -2
- warp/native/crt.h +1 -0
- warp/native/cuda_util.cpp +35 -0
- warp/native/cuda_util.h +5 -0
- warp/native/exports.h +40 -40
- warp/native/intersect.h +17 -0
- warp/native/mat.h +57 -3
- warp/native/mathdx.cpp +19 -0
- warp/native/mesh.cpp +25 -8
- warp/native/mesh.cu +153 -101
- warp/native/mesh.h +482 -403
- warp/native/quat.h +40 -0
- warp/native/solid_angle.h +7 -0
- warp/native/sort.cpp +85 -0
- warp/native/sort.cu +34 -0
- warp/native/sort.h +3 -1
- warp/native/spatial.h +11 -0
- warp/native/tile.h +1189 -664
- warp/native/tile_reduce.h +8 -6
- warp/native/vec.h +41 -0
- warp/native/warp.cpp +8 -1
- warp/native/warp.cu +263 -40
- warp/native/warp.h +19 -5
- warp/optim/linear.py +22 -4
- warp/render/render_opengl.py +132 -59
- warp/render/render_usd.py +10 -2
- warp/sim/__init__.py +6 -1
- warp/sim/collide.py +289 -32
- warp/sim/import_urdf.py +20 -5
- warp/sim/integrator_euler.py +25 -7
- warp/sim/integrator_featherstone.py +147 -35
- warp/sim/integrator_vbd.py +842 -40
- warp/sim/model.py +173 -112
- warp/sim/render.py +2 -2
- warp/stubs.py +249 -116
- warp/tape.py +28 -30
- warp/tests/aux_test_module_unload.py +15 -0
- warp/tests/{test_sim_grad.py → flaky_test_sim_grad.py} +104 -63
- warp/tests/test_array.py +100 -0
- warp/tests/test_assert.py +242 -0
- warp/tests/test_codegen.py +14 -61
- warp/tests/test_collision.py +8 -8
- warp/tests/test_examples.py +16 -1
- warp/tests/test_grad_debug.py +87 -2
- warp/tests/test_hash_grid.py +1 -1
- warp/tests/test_ipc.py +116 -0
- warp/tests/test_launch.py +77 -26
- warp/tests/test_mat.py +213 -168
- warp/tests/test_math.py +47 -1
- warp/tests/test_matmul.py +11 -7
- warp/tests/test_matmul_lite.py +4 -4
- warp/tests/test_mesh.py +84 -60
- warp/tests/test_mesh_query_aabb.py +165 -0
- warp/tests/test_mesh_query_point.py +328 -286
- warp/tests/test_mesh_query_ray.py +134 -121
- warp/tests/test_mlp.py +2 -2
- warp/tests/test_operators.py +43 -0
- warp/tests/test_overwrite.py +6 -5
- warp/tests/test_quat.py +77 -0
- warp/tests/test_reload.py +29 -0
- warp/tests/test_sim_grad_bounce_linear.py +204 -0
- warp/tests/test_static.py +16 -0
- warp/tests/test_tape.py +25 -0
- warp/tests/test_tile.py +134 -191
- warp/tests/test_tile_load.py +399 -0
- warp/tests/test_tile_mathdx.py +61 -8
- warp/tests/test_tile_mlp.py +17 -17
- warp/tests/test_tile_reduce.py +24 -18
- warp/tests/test_tile_shared_memory.py +66 -17
- warp/tests/test_tile_view.py +165 -0
- warp/tests/test_torch.py +35 -0
- warp/tests/test_utils.py +36 -24
- warp/tests/test_vec.py +110 -0
- warp/tests/unittest_suites.py +29 -4
- warp/tests/unittest_utils.py +30 -11
- warp/thirdparty/unittest_parallel.py +5 -2
- warp/types.py +419 -111
- warp/utils.py +9 -5
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/METADATA +86 -45
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/RECORD +129 -118
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/WHEEL +1 -1
- warp/examples/benchmarks/benchmark_tile.py +0 -179
- warp/native/tile_gemm.h +0 -341
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.1.dist-info}/top_level.txt +0 -0
warp/tape.py
CHANGED
|
@@ -43,7 +43,6 @@ class Tape:
|
|
|
43
43
|
|
|
44
44
|
def __init__(self):
|
|
45
45
|
self.gradients = {}
|
|
46
|
-
self.const_gradients = set()
|
|
47
46
|
self.launches = []
|
|
48
47
|
self.scopes = []
|
|
49
48
|
|
|
@@ -106,7 +105,6 @@ class Tape:
|
|
|
106
105
|
else:
|
|
107
106
|
# ensure we can capture this backward pass in a CUDA graph
|
|
108
107
|
a.grad.assign(g)
|
|
109
|
-
self.const_gradients.add(a)
|
|
110
108
|
|
|
111
109
|
# run launches backwards
|
|
112
110
|
for launch in reversed(self.launches):
|
|
@@ -115,13 +113,13 @@ class Tape:
|
|
|
115
113
|
|
|
116
114
|
else:
|
|
117
115
|
# kernel option takes precedence over module option
|
|
118
|
-
|
|
119
|
-
if
|
|
116
|
+
enable_backward = launch[0].options.get("enable_backward")
|
|
117
|
+
if enable_backward is False:
|
|
120
118
|
msg = f"Running the tape backwards may produce incorrect gradients because recorded kernel {launch[0].key} is configured with the option 'enable_backward=False'."
|
|
121
119
|
wp.utils.warn(msg)
|
|
122
|
-
elif
|
|
123
|
-
|
|
124
|
-
if
|
|
120
|
+
elif enable_backward is None:
|
|
121
|
+
enable_backward = launch[0].module.options.get("enable_backward")
|
|
122
|
+
if enable_backward is False:
|
|
125
123
|
msg = f"Running the tape backwards may produce incorrect gradients because recorded kernel {launch[0].key} is defined in a module with the option 'enable_backward=False' set."
|
|
126
124
|
wp.utils.warn(msg)
|
|
127
125
|
|
|
@@ -144,18 +142,19 @@ class Tape:
|
|
|
144
142
|
for a in outputs:
|
|
145
143
|
adj_outputs.append(self.get_adjoint(a))
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
if enable_backward:
|
|
146
|
+
wp.launch(
|
|
147
|
+
kernel=kernel,
|
|
148
|
+
dim=dim,
|
|
149
|
+
inputs=inputs,
|
|
150
|
+
outputs=outputs,
|
|
151
|
+
adj_inputs=adj_inputs,
|
|
152
|
+
adj_outputs=adj_outputs,
|
|
153
|
+
device=device,
|
|
154
|
+
adjoint=True,
|
|
155
|
+
max_blocks=max_blocks,
|
|
156
|
+
block_dim=block_dim,
|
|
157
|
+
)
|
|
159
158
|
|
|
160
159
|
# record a kernel launch on the tape
|
|
161
160
|
def record_launch(self, kernel, dim, max_blocks, inputs, outputs, device, block_dim=0, metadata=None):
|
|
@@ -222,9 +221,9 @@ class Tape:
|
|
|
222
221
|
# returns the adjoint of a kernel parameter
|
|
223
222
|
def get_adjoint(self, a):
|
|
224
223
|
if not wp.types.is_array(a) and not isinstance(a, wp.codegen.StructInstance):
|
|
225
|
-
# if input is a simple type (e.g.: float, vec3, etc)
|
|
226
|
-
# no gradient needed (we only return gradients through arrays and structs)
|
|
227
|
-
return
|
|
224
|
+
# if input is a simple type (e.g.: float, vec3, etc) or a non-Warp array,
|
|
225
|
+
# then no gradient needed (we only return gradients through Warp arrays and structs)
|
|
226
|
+
return None
|
|
228
227
|
|
|
229
228
|
elif wp.types.is_array(a) and a.grad:
|
|
230
229
|
# keep track of all gradients used by the tape (for zeroing)
|
|
@@ -267,13 +266,12 @@ class Tape:
|
|
|
267
266
|
Zero out all gradients recorded on the tape.
|
|
268
267
|
"""
|
|
269
268
|
for a, g in self.gradients.items():
|
|
270
|
-
if a
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
g.zero_()
|
|
269
|
+
if isinstance(a, wp.codegen.StructInstance):
|
|
270
|
+
for name in g._cls.vars:
|
|
271
|
+
if isinstance(g._cls.vars[name].type, wp.array) and g._cls.vars[name].requires_grad:
|
|
272
|
+
getattr(g, name).zero_()
|
|
273
|
+
else:
|
|
274
|
+
g.zero_()
|
|
277
275
|
|
|
278
276
|
def _reset_array_read_flags(self):
|
|
279
277
|
"""
|
|
@@ -517,7 +515,7 @@ class GraphvizTapeVisitor(TapeVisitor):
|
|
|
517
515
|
node_attrs = f"label=<{label}>"
|
|
518
516
|
if "caller" in launch_data:
|
|
519
517
|
caller = launch_data["caller"]
|
|
520
|
-
node_attrs += f
|
|
518
|
+
node_attrs += f',tooltip="{self.sanitize(caller["file"])}:{caller["lineno"]} ({caller["func"]})"'
|
|
521
519
|
|
|
522
520
|
self.graphviz_lines.append(f"{chart_indent}{kernel_launch_id} [{node_attrs}];")
|
|
523
521
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright (c) 2024 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
|
+
"""Dummy module used in test_reload.py"""
|
|
9
|
+
|
|
10
|
+
import warp as wp
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@wp.kernel
|
|
14
|
+
def k():
|
|
15
|
+
pass
|
|
@@ -11,6 +11,7 @@ import numpy as np
|
|
|
11
11
|
|
|
12
12
|
import warp as wp
|
|
13
13
|
import warp.sim
|
|
14
|
+
import warp.sim.render
|
|
14
15
|
from warp.tests.unittest_utils import *
|
|
15
16
|
|
|
16
17
|
|
|
@@ -23,8 +24,7 @@ def evaluate_loss(
|
|
|
23
24
|
loss: wp.array(dtype=float),
|
|
24
25
|
):
|
|
25
26
|
tid = wp.tid()
|
|
26
|
-
|
|
27
|
-
d = wp.abs(target - joint_q[tid * 2 + 1])
|
|
27
|
+
d = (target - joint_q[tid * 2 + 1]) ** 2.0
|
|
28
28
|
wp.atomic_add(loss, 0, weighting * d)
|
|
29
29
|
|
|
30
30
|
|
|
@@ -34,7 +34,13 @@ def assign_action(action: wp.array(dtype=float), joint_act: wp.array(dtype=float
|
|
|
34
34
|
joint_act[2 * tid] = action[tid]
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
@wp.kernel
|
|
38
|
+
def assign_force(action: wp.array(dtype=float), body_f: wp.array(dtype=wp.spatial_vector)):
|
|
39
|
+
tid = wp.tid()
|
|
40
|
+
body_f[2 * tid] = wp.spatial_vector(0.0, 0.0, 0.0, action[tid], 0.0, 0.0)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def gradcheck(func, inputs, device, eps=1e-1, tol=1e-2, print_grad=False):
|
|
38
44
|
"""
|
|
39
45
|
Checks that the gradient of the Warp kernel is correct by comparing it to the
|
|
40
46
|
numerical gradient computed using finite differences.
|
|
@@ -46,56 +52,64 @@ def gradcheck(func, inputs, device, eps=1e-1, tol=1e-2):
|
|
|
46
52
|
output = func(*wp_xs)
|
|
47
53
|
return output.numpy()[0]
|
|
48
54
|
|
|
55
|
+
# compute analytical gradient
|
|
56
|
+
tape = wp.Tape()
|
|
57
|
+
with tape:
|
|
58
|
+
output = func(*inputs)
|
|
59
|
+
|
|
60
|
+
tape.backward(loss=output)
|
|
61
|
+
|
|
49
62
|
# compute numerical gradient
|
|
50
|
-
numerical_grad = []
|
|
51
63
|
np_xs = []
|
|
52
64
|
for i in range(len(inputs)):
|
|
53
65
|
np_xs.append(inputs[i].numpy().flatten().copy())
|
|
54
|
-
numerical_grad.append(np.zeros_like(np_xs[-1]))
|
|
55
|
-
inputs[i].requires_grad = True
|
|
56
66
|
|
|
57
|
-
for i in range(len(
|
|
67
|
+
for i in range(len(inputs)):
|
|
68
|
+
fd_grad = np.zeros_like(np_xs[i])
|
|
58
69
|
for j in range(len(np_xs[i])):
|
|
59
70
|
np_xs[i][j] += eps
|
|
60
71
|
y1 = f(np_xs)
|
|
61
72
|
np_xs[i][j] -= 2 * eps
|
|
62
73
|
y2 = f(np_xs)
|
|
63
74
|
np_xs[i][j] += eps
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
# compare gradients
|
|
74
|
-
for i in range(len(inputs)):
|
|
75
|
-
grad = tape.gradients[inputs[i]]
|
|
76
|
-
assert_np_equal(grad.numpy(), numerical_grad[i], tol=tol)
|
|
75
|
+
fd_grad[j] = (y1 - y2) / (2 * eps)
|
|
76
|
+
|
|
77
|
+
# compare gradients
|
|
78
|
+
ad_grad = tape.gradients[inputs[i]].numpy()
|
|
79
|
+
if print_grad:
|
|
80
|
+
print("grad ad:", ad_grad)
|
|
81
|
+
print("grad fd:", fd_grad)
|
|
82
|
+
assert_np_equal(ad_grad, fd_grad, tol=tol)
|
|
77
83
|
# ensure the signs match
|
|
78
|
-
assert np.allclose(
|
|
84
|
+
assert np.allclose(ad_grad * fd_grad > 0, True)
|
|
79
85
|
|
|
80
86
|
tape.zero()
|
|
81
87
|
|
|
82
88
|
|
|
83
|
-
def
|
|
84
|
-
|
|
89
|
+
def test_sphere_pushing_on_rails(
|
|
90
|
+
test,
|
|
91
|
+
device,
|
|
92
|
+
joint_type,
|
|
93
|
+
integrator_type,
|
|
94
|
+
apply_force=False,
|
|
95
|
+
static_contacts=True,
|
|
96
|
+
print_grad=False,
|
|
97
|
+
):
|
|
98
|
+
# Two spheres on a rail (prismatic or D6 joint), one is pushed, the other is passive.
|
|
85
99
|
# The absolute distance to a target is measured and gradients are compared for
|
|
86
100
|
# a push that is too far and too close.
|
|
87
101
|
num_envs = 2
|
|
88
|
-
num_steps =
|
|
89
|
-
sim_substeps =
|
|
102
|
+
num_steps = 150
|
|
103
|
+
sim_substeps = 10
|
|
90
104
|
dt = 1 / 30
|
|
91
105
|
|
|
92
|
-
target =
|
|
106
|
+
target = 3.0
|
|
93
107
|
|
|
94
108
|
if integrator_type == 0:
|
|
95
|
-
contact_ke =
|
|
96
|
-
contact_kd =
|
|
109
|
+
contact_ke = 1e3
|
|
110
|
+
contact_kd = 1e1
|
|
97
111
|
else:
|
|
98
|
-
contact_ke =
|
|
112
|
+
contact_ke = 1e3
|
|
99
113
|
contact_kd = 1e1
|
|
100
114
|
|
|
101
115
|
complete_builder = wp.sim.ModelBuilder()
|
|
@@ -104,16 +118,16 @@ def test_box_pushing_on_rails(test, device, joint_type, integrator_type):
|
|
|
104
118
|
complete_builder.default_shape_kd = contact_kd
|
|
105
119
|
|
|
106
120
|
for _ in range(num_envs):
|
|
107
|
-
builder = wp.sim.ModelBuilder()
|
|
121
|
+
builder = wp.sim.ModelBuilder(gravity=0.0)
|
|
108
122
|
|
|
109
123
|
builder.default_shape_ke = complete_builder.default_shape_ke
|
|
110
124
|
builder.default_shape_kd = complete_builder.default_shape_kd
|
|
111
125
|
|
|
112
126
|
b0 = builder.add_body(name="pusher")
|
|
113
|
-
builder.
|
|
127
|
+
builder.add_shape_sphere(b0, radius=0.4, density=100.0)
|
|
114
128
|
|
|
115
129
|
b1 = builder.add_body(name="passive")
|
|
116
|
-
builder.
|
|
130
|
+
builder.add_shape_sphere(b1, radius=0.47, density=100.0)
|
|
117
131
|
|
|
118
132
|
if joint_type == 0:
|
|
119
133
|
builder.add_joint_prismatic(-1, b0)
|
|
@@ -122,7 +136,7 @@ def test_box_pushing_on_rails(test, device, joint_type, integrator_type):
|
|
|
122
136
|
builder.add_joint_d6(-1, b0, linear_axes=[wp.sim.JointAxis((1.0, 0.0, 0.0))])
|
|
123
137
|
builder.add_joint_d6(-1, b1, linear_axes=[wp.sim.JointAxis((1.0, 0.0, 0.0))])
|
|
124
138
|
|
|
125
|
-
builder.joint_q[-2:] = [0.0,
|
|
139
|
+
builder.joint_q[-2:] = [0.0, 2.0]
|
|
126
140
|
complete_builder.add_builder(builder)
|
|
127
141
|
|
|
128
142
|
assert complete_builder.body_count == 2 * num_envs
|
|
@@ -135,6 +149,15 @@ def test_box_pushing_on_rails(test, device, joint_type, integrator_type):
|
|
|
135
149
|
model.joint_attach_ke = 32000.0 * 16
|
|
136
150
|
model.joint_attach_kd = 500.0 * 4
|
|
137
151
|
|
|
152
|
+
model.shape_geo.scale.requires_grad = False
|
|
153
|
+
model.shape_geo.thickness.requires_grad = False
|
|
154
|
+
|
|
155
|
+
if static_contacts:
|
|
156
|
+
wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, model)
|
|
157
|
+
model.rigid_contact_margin = 10.0
|
|
158
|
+
state = model.state()
|
|
159
|
+
wp.sim.collide(model, state)
|
|
160
|
+
|
|
138
161
|
if integrator_type == 0:
|
|
139
162
|
integrator = wp.sim.FeatherstoneIntegrator(model, update_mass_matrix_every=num_steps * sim_substeps)
|
|
140
163
|
elif integrator_type == 1:
|
|
@@ -143,40 +166,57 @@ def test_box_pushing_on_rails(test, device, joint_type, integrator_type):
|
|
|
143
166
|
else:
|
|
144
167
|
integrator = wp.sim.XPBDIntegrator(iterations=2, rigid_contact_relaxation=1.0)
|
|
145
168
|
|
|
146
|
-
# renderer = wp.sim.render.
|
|
169
|
+
# renderer = wp.sim.render.SimRendererOpenGL(model, "test_sim_grad.usd", scaling=1.0)
|
|
147
170
|
renderer = None
|
|
148
171
|
render_time = 0.0
|
|
149
172
|
|
|
173
|
+
if renderer:
|
|
174
|
+
renderer.render_sphere("target", pos=wp.vec3(target, 0, 0), rot=wp.quat_identity(), radius=0.1, color=(1, 0, 0))
|
|
175
|
+
|
|
150
176
|
def rollout(action: wp.array) -> wp.array:
|
|
151
177
|
nonlocal render_time
|
|
152
178
|
states = [model.state() for _ in range(num_steps * sim_substeps + 1)]
|
|
153
179
|
|
|
154
|
-
|
|
155
|
-
# apply initial generalized coordinates
|
|
156
|
-
wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, states[0])
|
|
180
|
+
wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, states[0])
|
|
157
181
|
|
|
158
182
|
control_active = model.control()
|
|
159
183
|
control_nop = model.control()
|
|
160
184
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
185
|
+
if not apply_force:
|
|
186
|
+
wp.launch(
|
|
187
|
+
assign_action,
|
|
188
|
+
dim=num_envs,
|
|
189
|
+
inputs=[action],
|
|
190
|
+
outputs=[control_active.joint_act],
|
|
191
|
+
device=model.device,
|
|
192
|
+
)
|
|
168
193
|
|
|
169
194
|
i = 0
|
|
170
195
|
for step in range(num_steps):
|
|
171
|
-
|
|
172
|
-
|
|
196
|
+
state = states[i]
|
|
197
|
+
if not static_contacts:
|
|
198
|
+
wp.sim.collide(model, state)
|
|
199
|
+
if apply_force:
|
|
200
|
+
control = control_nop
|
|
201
|
+
else:
|
|
202
|
+
control = control_active if step < 10 else control_nop
|
|
173
203
|
if renderer:
|
|
174
204
|
renderer.begin_frame(render_time)
|
|
175
|
-
renderer.render(
|
|
205
|
+
renderer.render(state)
|
|
176
206
|
renderer.end_frame()
|
|
177
207
|
render_time += dt
|
|
178
208
|
for _ in range(sim_substeps):
|
|
179
|
-
|
|
209
|
+
state = states[i]
|
|
210
|
+
next_state = states[i + 1]
|
|
211
|
+
if apply_force and step < 10:
|
|
212
|
+
wp.launch(
|
|
213
|
+
assign_force,
|
|
214
|
+
dim=num_envs,
|
|
215
|
+
inputs=[action],
|
|
216
|
+
outputs=[state.body_f],
|
|
217
|
+
device=model.device,
|
|
218
|
+
)
|
|
219
|
+
integrator.simulate(model, state, next_state, dt / sim_substeps, control)
|
|
180
220
|
i += 1
|
|
181
221
|
|
|
182
222
|
if not isinstance(integrator, wp.sim.FeatherstoneIntegrator):
|
|
@@ -184,39 +224,40 @@ def test_box_pushing_on_rails(test, device, joint_type, integrator_type):
|
|
|
184
224
|
wp.sim.eval_ik(model, states[-1], states[-1].joint_q, states[-1].joint_qd)
|
|
185
225
|
|
|
186
226
|
loss = wp.zeros(1, requires_grad=True, device=device)
|
|
227
|
+
weighting = 1.0
|
|
187
228
|
wp.launch(
|
|
188
229
|
evaluate_loss,
|
|
189
230
|
dim=num_envs,
|
|
190
|
-
inputs=[states[-1].joint_q,
|
|
231
|
+
inputs=[states[-1].joint_q, weighting, target],
|
|
191
232
|
outputs=[loss],
|
|
192
233
|
device=model.device,
|
|
193
234
|
)
|
|
194
235
|
|
|
195
|
-
if renderer:
|
|
196
|
-
|
|
236
|
+
# if renderer:
|
|
237
|
+
# renderer.save()
|
|
197
238
|
|
|
198
239
|
return loss
|
|
199
240
|
|
|
200
241
|
action_too_far = wp.array(
|
|
201
|
-
[
|
|
242
|
+
[80.0 for _ in range(num_envs)],
|
|
202
243
|
device=device,
|
|
203
244
|
dtype=wp.float32,
|
|
204
245
|
requires_grad=True,
|
|
205
246
|
)
|
|
206
|
-
tol =
|
|
247
|
+
tol = 2e-1
|
|
207
248
|
if isinstance(integrator, wp.sim.XPBDIntegrator):
|
|
208
249
|
# Euler, XPBD do not yield as accurate gradients, but at least the
|
|
209
250
|
# signs should match
|
|
210
251
|
tol = 0.1
|
|
211
|
-
gradcheck(rollout, [action_too_far], device=device, eps=0.2, tol=tol)
|
|
252
|
+
gradcheck(rollout, [action_too_far], device=device, eps=0.2, tol=tol, print_grad=print_grad)
|
|
212
253
|
|
|
213
254
|
action_too_close = wp.array(
|
|
214
|
-
[
|
|
255
|
+
[40.0 for _ in range(num_envs)],
|
|
215
256
|
device=device,
|
|
216
257
|
dtype=wp.float32,
|
|
217
258
|
requires_grad=True,
|
|
218
259
|
)
|
|
219
|
-
gradcheck(rollout, [action_too_close], device=device, eps=0.2, tol=tol)
|
|
260
|
+
gradcheck(rollout, [action_too_close], device=device, eps=0.2, tol=tol, print_grad=print_grad)
|
|
220
261
|
|
|
221
262
|
|
|
222
263
|
devices = get_test_devices()
|
|
@@ -226,15 +267,15 @@ class TestSimGradients(unittest.TestCase):
|
|
|
226
267
|
pass
|
|
227
268
|
|
|
228
269
|
|
|
229
|
-
for
|
|
230
|
-
|
|
231
|
-
test_name = f"test_box_pushing_on_rails_{int_name}_{jt_name}"
|
|
270
|
+
for jt_type, jt_name in enumerate(["prismatic", "d6"]):
|
|
271
|
+
test_name = f"test_sphere_pushing_on_rails_{jt_name}"
|
|
232
272
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
273
|
+
def test_fn(self, device, jt_type=jt_type, int_type=1):
|
|
274
|
+
return test_sphere_pushing_on_rails(
|
|
275
|
+
self, device, jt_type, int_type, apply_force=True, static_contacts=True, print_grad=False
|
|
276
|
+
)
|
|
237
277
|
|
|
278
|
+
add_function_test(TestSimGradients, test_name, test_fn, devices=devices)
|
|
238
279
|
|
|
239
280
|
if __name__ == "__main__":
|
|
240
281
|
wp.clear_kernel_cache()
|
warp/tests/test_array.py
CHANGED
|
@@ -2766,6 +2766,101 @@ def test_indexing_types(test, device):
|
|
|
2766
2766
|
)
|
|
2767
2767
|
|
|
2768
2768
|
|
|
2769
|
+
def test_alloc_strides(test, device):
|
|
2770
|
+
def test_transposed(shape, dtype):
|
|
2771
|
+
# allocate without specifying strides
|
|
2772
|
+
a1 = wp.zeros(shape, dtype=dtype)
|
|
2773
|
+
|
|
2774
|
+
# allocate with contiguous strides
|
|
2775
|
+
strides = wp.types.strides_from_shape(shape, dtype)
|
|
2776
|
+
a2 = wp.zeros(shape, dtype=dtype, strides=strides)
|
|
2777
|
+
|
|
2778
|
+
# allocate with transposed (reversed) shape/strides
|
|
2779
|
+
rshape = shape[::-1]
|
|
2780
|
+
rstrides = strides[::-1]
|
|
2781
|
+
a3 = wp.zeros(rshape, dtype=dtype, strides=rstrides)
|
|
2782
|
+
|
|
2783
|
+
# ensure that correct capacity was allocated
|
|
2784
|
+
assert a2.capacity == a1.capacity
|
|
2785
|
+
assert a3.capacity == a1.capacity
|
|
2786
|
+
|
|
2787
|
+
with wp.ScopedDevice(device):
|
|
2788
|
+
shapes = [(5, 5), (5, 3), (3, 5), (2, 3, 4), (4, 2, 3), (3, 2, 4)]
|
|
2789
|
+
for shape in shapes:
|
|
2790
|
+
with test.subTest(msg=f"shape={shape}"):
|
|
2791
|
+
test_transposed(shape, wp.int8)
|
|
2792
|
+
test_transposed(shape, wp.float32)
|
|
2793
|
+
test_transposed(shape, wp.vec3)
|
|
2794
|
+
|
|
2795
|
+
|
|
2796
|
+
def test_casting(test, device):
|
|
2797
|
+
idxs = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
|
|
2798
|
+
idxs = wp.array(idxs, device=device).reshape((-1, 3))
|
|
2799
|
+
idxs = wp.array(idxs, shape=idxs.shape[0], dtype=wp.vec3i, device=device)
|
|
2800
|
+
assert idxs.dtype is wp.vec3i
|
|
2801
|
+
assert idxs.shape == (4,)
|
|
2802
|
+
assert idxs.strides == (12,)
|
|
2803
|
+
|
|
2804
|
+
|
|
2805
|
+
@wp.kernel
|
|
2806
|
+
def array_len_kernel(
|
|
2807
|
+
a1: wp.array(dtype=int),
|
|
2808
|
+
a2: wp.array(dtype=float, ndim=3),
|
|
2809
|
+
out: wp.array(dtype=int),
|
|
2810
|
+
):
|
|
2811
|
+
length = len(a1)
|
|
2812
|
+
wp.expect_eq(len(a1), 123)
|
|
2813
|
+
out[0] = len(a1)
|
|
2814
|
+
|
|
2815
|
+
length = len(a2)
|
|
2816
|
+
wp.expect_eq(len(a2), 2)
|
|
2817
|
+
out[1] = len(a2)
|
|
2818
|
+
|
|
2819
|
+
|
|
2820
|
+
def test_array_len(test, device):
|
|
2821
|
+
a1 = wp.zeros(123, dtype=int, device=device)
|
|
2822
|
+
a2 = wp.zeros((2, 3, 4), dtype=float, device=device)
|
|
2823
|
+
out = wp.empty(2, dtype=int, device=device)
|
|
2824
|
+
wp.launch(
|
|
2825
|
+
array_len_kernel,
|
|
2826
|
+
dim=(1,),
|
|
2827
|
+
inputs=(
|
|
2828
|
+
a1,
|
|
2829
|
+
a2,
|
|
2830
|
+
),
|
|
2831
|
+
outputs=(out,),
|
|
2832
|
+
device=device,
|
|
2833
|
+
)
|
|
2834
|
+
|
|
2835
|
+
test.assertEqual(out.numpy()[0], 123)
|
|
2836
|
+
test.assertEqual(out.numpy()[1], 2)
|
|
2837
|
+
|
|
2838
|
+
|
|
2839
|
+
def test_cuda_interface_conversion(test, device):
|
|
2840
|
+
class MyArrayInterface:
|
|
2841
|
+
def __init__(self, data):
|
|
2842
|
+
self.data = np.array(data)
|
|
2843
|
+
self.__array_interface__ = self.data.__array_interface__
|
|
2844
|
+
self.__cuda_array_interface__ = self.data.__array_interface__
|
|
2845
|
+
self.__len__ = self.data.__len__
|
|
2846
|
+
|
|
2847
|
+
array = MyArrayInterface((1, 2, 3))
|
|
2848
|
+
wp_array = wp.array(array, dtype=wp.int8, device=device)
|
|
2849
|
+
assert wp_array.ptr != 0
|
|
2850
|
+
|
|
2851
|
+
array = MyArrayInterface((1, 2, 3))
|
|
2852
|
+
wp_array = wp.array(array, dtype=wp.float32, device=device)
|
|
2853
|
+
assert wp_array.ptr != 0
|
|
2854
|
+
|
|
2855
|
+
array = MyArrayInterface((1, 2, 3))
|
|
2856
|
+
wp_array = wp.array(array, dtype=wp.vec3, device=device)
|
|
2857
|
+
assert wp_array.ptr != 0
|
|
2858
|
+
|
|
2859
|
+
array = MyArrayInterface((1, 2, 3, 4))
|
|
2860
|
+
wp_array = wp.array(array, dtype=wp.mat22, device=device)
|
|
2861
|
+
assert wp_array.ptr != 0
|
|
2862
|
+
|
|
2863
|
+
|
|
2769
2864
|
devices = get_test_devices()
|
|
2770
2865
|
|
|
2771
2866
|
|
|
@@ -2835,6 +2930,11 @@ add_function_test(TestArray, "test_array_from_int32_domain", test_array_from_int
|
|
|
2835
2930
|
add_function_test(TestArray, "test_array_from_int64_domain", test_array_from_int64_domain, devices=devices)
|
|
2836
2931
|
add_function_test(TestArray, "test_indexing_types", test_indexing_types, devices=devices)
|
|
2837
2932
|
|
|
2933
|
+
add_function_test(TestArray, "test_alloc_strides", test_alloc_strides, devices=devices)
|
|
2934
|
+
add_function_test(TestArray, "test_casting", test_casting, devices=devices)
|
|
2935
|
+
add_function_test(TestArray, "test_array_len", test_array_len, devices=devices)
|
|
2936
|
+
add_function_test(TestArray, "test_cuda_interface_conversion", test_cuda_interface_conversion, devices=devices)
|
|
2937
|
+
|
|
2838
2938
|
try:
|
|
2839
2939
|
import torch
|
|
2840
2940
|
|