warp-lang 1.0.2__py3-none-manylinux2014_aarch64.whl → 1.1.0__py3-none-manylinux2014_aarch64.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 +108 -97
- warp/__init__.pyi +1 -1
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +115 -113
- warp/build_dll.py +383 -375
- warp/builtins.py +3425 -3354
- warp/codegen.py +2878 -2792
- warp/config.py +40 -36
- warp/constants.py +45 -45
- warp/context.py +5194 -5102
- warp/dlpack.py +442 -442
- warp/examples/__init__.py +16 -16
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -110
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -92
- warp/examples/assets/nv_humanoid.xml +183 -183
- warp/examples/assets/quadruped.urdf +267 -267
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +383 -383
- warp/examples/benchmarks/benchmark_cloth.py +278 -277
- warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -88
- warp/examples/benchmarks/benchmark_cloth_jax.py +97 -100
- warp/examples/benchmarks/benchmark_cloth_numba.py +146 -142
- warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -77
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -86
- warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -112
- warp/examples/benchmarks/benchmark_cloth_warp.py +146 -146
- warp/examples/benchmarks/benchmark_launches.py +295 -295
- warp/examples/browse.py +29 -29
- warp/examples/core/example_dem.py +234 -219
- warp/examples/core/example_fluid.py +293 -267
- warp/examples/core/example_graph_capture.py +144 -126
- warp/examples/core/example_marching_cubes.py +188 -174
- warp/examples/core/example_mesh.py +174 -155
- warp/examples/core/example_mesh_intersect.py +205 -193
- warp/examples/core/example_nvdb.py +176 -170
- warp/examples/core/example_raycast.py +105 -90
- warp/examples/core/example_raymarch.py +199 -178
- warp/examples/core/example_render_opengl.py +185 -141
- warp/examples/core/example_sph.py +405 -387
- warp/examples/core/example_torch.py +222 -181
- warp/examples/core/example_wave.py +263 -248
- warp/examples/fem/bsr_utils.py +378 -380
- warp/examples/fem/example_apic_fluid.py +407 -389
- warp/examples/fem/example_convection_diffusion.py +182 -168
- warp/examples/fem/example_convection_diffusion_dg.py +219 -209
- warp/examples/fem/example_convection_diffusion_dg0.py +204 -194
- warp/examples/fem/example_deformed_geometry.py +177 -159
- warp/examples/fem/example_diffusion.py +201 -173
- warp/examples/fem/example_diffusion_3d.py +177 -152
- warp/examples/fem/example_diffusion_mgpu.py +221 -214
- warp/examples/fem/example_mixed_elasticity.py +244 -222
- warp/examples/fem/example_navier_stokes.py +259 -243
- warp/examples/fem/example_stokes.py +220 -192
- warp/examples/fem/example_stokes_transfer.py +265 -249
- warp/examples/fem/mesh_utils.py +133 -109
- warp/examples/fem/plot_utils.py +292 -287
- warp/examples/optim/example_bounce.py +260 -246
- warp/examples/optim/example_cloth_throw.py +222 -209
- warp/examples/optim/example_diffray.py +566 -536
- warp/examples/optim/example_drone.py +864 -835
- warp/examples/optim/example_inverse_kinematics.py +176 -168
- warp/examples/optim/example_inverse_kinematics_torch.py +185 -169
- warp/examples/optim/example_spring_cage.py +239 -231
- warp/examples/optim/example_trajectory.py +223 -199
- warp/examples/optim/example_walker.py +306 -293
- warp/examples/sim/example_cartpole.py +139 -129
- warp/examples/sim/example_cloth.py +196 -186
- warp/examples/sim/example_granular.py +124 -111
- warp/examples/sim/example_granular_collision_sdf.py +197 -186
- warp/examples/sim/example_jacobian_ik.py +236 -214
- warp/examples/sim/example_particle_chain.py +118 -105
- warp/examples/sim/example_quadruped.py +193 -180
- warp/examples/sim/example_rigid_chain.py +197 -187
- warp/examples/sim/example_rigid_contact.py +189 -177
- warp/examples/sim/example_rigid_force.py +127 -125
- warp/examples/sim/example_rigid_gyroscopic.py +109 -95
- warp/examples/sim/example_rigid_soft_contact.py +134 -122
- warp/examples/sim/example_soft_body.py +190 -177
- warp/fabric.py +337 -335
- warp/fem/__init__.py +60 -27
- warp/fem/cache.py +401 -388
- warp/fem/dirichlet.py +178 -179
- warp/fem/domain.py +262 -263
- warp/fem/field/__init__.py +100 -101
- warp/fem/field/field.py +148 -149
- warp/fem/field/nodal_field.py +298 -299
- warp/fem/field/restriction.py +22 -21
- warp/fem/field/test.py +180 -181
- warp/fem/field/trial.py +183 -183
- warp/fem/geometry/__init__.py +15 -19
- warp/fem/geometry/closest_point.py +69 -70
- warp/fem/geometry/deformed_geometry.py +270 -271
- warp/fem/geometry/element.py +744 -744
- warp/fem/geometry/geometry.py +184 -186
- warp/fem/geometry/grid_2d.py +380 -373
- warp/fem/geometry/grid_3d.py +441 -435
- warp/fem/geometry/hexmesh.py +953 -953
- warp/fem/geometry/partition.py +374 -376
- warp/fem/geometry/quadmesh_2d.py +532 -532
- warp/fem/geometry/tetmesh.py +840 -840
- warp/fem/geometry/trimesh_2d.py +577 -577
- warp/fem/integrate.py +1630 -1615
- warp/fem/operator.py +190 -191
- warp/fem/polynomial.py +214 -213
- warp/fem/quadrature/__init__.py +2 -2
- warp/fem/quadrature/pic_quadrature.py +243 -245
- warp/fem/quadrature/quadrature.py +295 -294
- warp/fem/space/__init__.py +294 -292
- warp/fem/space/basis_space.py +488 -489
- warp/fem/space/collocated_function_space.py +100 -105
- warp/fem/space/dof_mapper.py +236 -236
- warp/fem/space/function_space.py +148 -145
- warp/fem/space/grid_2d_function_space.py +267 -267
- warp/fem/space/grid_3d_function_space.py +305 -306
- warp/fem/space/hexmesh_function_space.py +350 -352
- warp/fem/space/partition.py +350 -350
- warp/fem/space/quadmesh_2d_function_space.py +368 -369
- warp/fem/space/restriction.py +158 -160
- warp/fem/space/shape/__init__.py +13 -15
- warp/fem/space/shape/cube_shape_function.py +738 -738
- warp/fem/space/shape/shape_function.py +102 -103
- warp/fem/space/shape/square_shape_function.py +611 -611
- warp/fem/space/shape/tet_shape_function.py +565 -567
- warp/fem/space/shape/triangle_shape_function.py +429 -429
- warp/fem/space/tetmesh_function_space.py +294 -292
- warp/fem/space/topology.py +297 -295
- warp/fem/space/trimesh_2d_function_space.py +223 -221
- warp/fem/types.py +77 -77
- warp/fem/utils.py +495 -495
- warp/jax.py +166 -141
- warp/jax_experimental.py +341 -339
- warp/native/array.h +1072 -1025
- warp/native/builtin.h +1560 -1560
- warp/native/bvh.cpp +398 -398
- warp/native/bvh.cu +525 -525
- warp/native/bvh.h +429 -429
- warp/native/clang/clang.cpp +495 -464
- warp/native/crt.cpp +31 -31
- warp/native/crt.h +334 -334
- warp/native/cuda_crt.h +1049 -1049
- warp/native/cuda_util.cpp +549 -540
- warp/native/cuda_util.h +288 -203
- warp/native/cutlass_gemm.cpp +34 -34
- warp/native/cutlass_gemm.cu +372 -372
- warp/native/error.cpp +66 -66
- warp/native/error.h +27 -27
- warp/native/fabric.h +228 -228
- warp/native/hashgrid.cpp +301 -278
- warp/native/hashgrid.cu +78 -77
- warp/native/hashgrid.h +227 -227
- warp/native/initializer_array.h +32 -32
- warp/native/intersect.h +1204 -1204
- warp/native/intersect_adj.h +365 -365
- warp/native/intersect_tri.h +322 -322
- warp/native/marching.cpp +2 -2
- warp/native/marching.cu +497 -497
- warp/native/marching.h +2 -2
- warp/native/mat.h +1498 -1498
- warp/native/matnn.h +333 -333
- warp/native/mesh.cpp +203 -203
- warp/native/mesh.cu +293 -293
- warp/native/mesh.h +1887 -1887
- warp/native/nanovdb/NanoVDB.h +4782 -4782
- warp/native/nanovdb/PNanoVDB.h +2553 -2553
- warp/native/nanovdb/PNanoVDBWrite.h +294 -294
- warp/native/noise.h +850 -850
- warp/native/quat.h +1084 -1084
- warp/native/rand.h +299 -299
- warp/native/range.h +108 -108
- warp/native/reduce.cpp +156 -156
- warp/native/reduce.cu +348 -348
- warp/native/runlength_encode.cpp +61 -61
- warp/native/runlength_encode.cu +46 -46
- warp/native/scan.cpp +30 -30
- warp/native/scan.cu +36 -36
- warp/native/scan.h +7 -7
- warp/native/solid_angle.h +442 -442
- warp/native/sort.cpp +94 -94
- warp/native/sort.cu +97 -97
- warp/native/sort.h +14 -14
- warp/native/sparse.cpp +337 -337
- warp/native/sparse.cu +544 -544
- warp/native/spatial.h +630 -630
- warp/native/svd.h +562 -562
- warp/native/temp_buffer.h +30 -30
- warp/native/vec.h +1132 -1132
- warp/native/volume.cpp +297 -297
- warp/native/volume.cu +32 -32
- warp/native/volume.h +538 -538
- warp/native/volume_builder.cu +425 -425
- warp/native/volume_builder.h +19 -19
- warp/native/warp.cpp +1057 -1052
- warp/native/warp.cu +2943 -2828
- warp/native/warp.h +313 -305
- warp/optim/__init__.py +9 -9
- warp/optim/adam.py +120 -120
- warp/optim/linear.py +1104 -939
- warp/optim/sgd.py +104 -92
- warp/render/__init__.py +10 -10
- warp/render/render_opengl.py +3217 -3204
- warp/render/render_usd.py +768 -749
- warp/render/utils.py +152 -150
- warp/sim/__init__.py +52 -59
- warp/sim/articulation.py +685 -685
- warp/sim/collide.py +1594 -1590
- warp/sim/import_mjcf.py +489 -481
- warp/sim/import_snu.py +220 -221
- warp/sim/import_urdf.py +536 -516
- warp/sim/import_usd.py +887 -881
- warp/sim/inertia.py +316 -317
- warp/sim/integrator.py +234 -233
- warp/sim/integrator_euler.py +1956 -1956
- warp/sim/integrator_featherstone.py +1910 -1991
- warp/sim/integrator_xpbd.py +3294 -3312
- warp/sim/model.py +4473 -4314
- warp/sim/particles.py +113 -112
- warp/sim/render.py +417 -403
- warp/sim/utils.py +413 -410
- warp/sparse.py +1227 -1227
- warp/stubs.py +2109 -2469
- warp/tape.py +1162 -225
- warp/tests/__init__.py +1 -1
- warp/tests/__main__.py +4 -4
- warp/tests/assets/torus.usda +105 -105
- warp/tests/aux_test_class_kernel.py +26 -26
- warp/tests/aux_test_compile_consts_dummy.py +10 -10
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -21
- warp/tests/aux_test_dependent.py +22 -22
- warp/tests/aux_test_grad_customs.py +23 -23
- warp/tests/aux_test_reference.py +11 -11
- warp/tests/aux_test_reference_reference.py +10 -10
- warp/tests/aux_test_square.py +17 -17
- warp/tests/aux_test_unresolved_func.py +14 -14
- warp/tests/aux_test_unresolved_symbol.py +14 -14
- warp/tests/disabled_kinematics.py +239 -239
- warp/tests/run_coverage_serial.py +31 -31
- warp/tests/test_adam.py +157 -157
- warp/tests/test_arithmetic.py +1124 -1124
- warp/tests/test_array.py +2417 -2326
- warp/tests/test_array_reduce.py +150 -150
- warp/tests/test_async.py +668 -656
- warp/tests/test_atomic.py +141 -141
- warp/tests/test_bool.py +204 -149
- warp/tests/test_builtins_resolution.py +1292 -1292
- warp/tests/test_bvh.py +164 -171
- warp/tests/test_closest_point_edge_edge.py +228 -228
- warp/tests/test_codegen.py +566 -553
- warp/tests/test_compile_consts.py +97 -101
- warp/tests/test_conditional.py +246 -246
- warp/tests/test_copy.py +232 -215
- warp/tests/test_ctypes.py +632 -632
- warp/tests/test_dense.py +67 -67
- warp/tests/test_devices.py +91 -98
- warp/tests/test_dlpack.py +530 -529
- warp/tests/test_examples.py +400 -378
- warp/tests/test_fabricarray.py +955 -955
- warp/tests/test_fast_math.py +62 -54
- warp/tests/test_fem.py +1277 -1278
- warp/tests/test_fp16.py +130 -130
- warp/tests/test_func.py +338 -337
- warp/tests/test_generics.py +571 -571
- warp/tests/test_grad.py +746 -640
- warp/tests/test_grad_customs.py +333 -336
- warp/tests/test_hash_grid.py +210 -164
- warp/tests/test_import.py +39 -39
- warp/tests/test_indexedarray.py +1134 -1134
- warp/tests/test_intersect.py +67 -67
- warp/tests/test_jax.py +307 -307
- warp/tests/test_large.py +167 -164
- warp/tests/test_launch.py +354 -354
- warp/tests/test_lerp.py +261 -261
- warp/tests/test_linear_solvers.py +191 -171
- warp/tests/test_lvalue.py +421 -493
- warp/tests/test_marching_cubes.py +65 -65
- warp/tests/test_mat.py +1801 -1827
- warp/tests/test_mat_lite.py +115 -115
- warp/tests/test_mat_scalar_ops.py +2907 -2889
- warp/tests/test_math.py +126 -193
- warp/tests/test_matmul.py +500 -499
- warp/tests/test_matmul_lite.py +410 -410
- warp/tests/test_mempool.py +188 -190
- warp/tests/test_mesh.py +284 -324
- warp/tests/test_mesh_query_aabb.py +228 -241
- warp/tests/test_mesh_query_point.py +692 -702
- warp/tests/test_mesh_query_ray.py +292 -303
- warp/tests/test_mlp.py +276 -276
- warp/tests/test_model.py +110 -110
- warp/tests/test_modules_lite.py +39 -39
- warp/tests/test_multigpu.py +163 -163
- warp/tests/test_noise.py +248 -248
- warp/tests/test_operators.py +250 -250
- warp/tests/test_options.py +123 -125
- warp/tests/test_peer.py +133 -137
- warp/tests/test_pinned.py +78 -78
- warp/tests/test_print.py +54 -54
- warp/tests/test_quat.py +2086 -2086
- warp/tests/test_rand.py +288 -288
- warp/tests/test_reload.py +217 -217
- warp/tests/test_rounding.py +179 -179
- warp/tests/test_runlength_encode.py +190 -190
- warp/tests/test_sim_grad.py +243 -0
- warp/tests/test_sim_kinematics.py +91 -97
- warp/tests/test_smoothstep.py +168 -168
- warp/tests/test_snippet.py +305 -266
- warp/tests/test_sparse.py +468 -460
- warp/tests/test_spatial.py +2148 -2148
- warp/tests/test_streams.py +486 -473
- warp/tests/test_struct.py +710 -675
- warp/tests/test_tape.py +173 -148
- warp/tests/test_torch.py +743 -743
- warp/tests/test_transient_module.py +87 -87
- warp/tests/test_types.py +556 -659
- warp/tests/test_utils.py +490 -499
- warp/tests/test_vec.py +1264 -1268
- warp/tests/test_vec_lite.py +73 -73
- warp/tests/test_vec_scalar_ops.py +2099 -2099
- warp/tests/test_verify_fp.py +94 -94
- warp/tests/test_volume.py +737 -736
- warp/tests/test_volume_write.py +255 -265
- warp/tests/unittest_serial.py +37 -37
- warp/tests/unittest_suites.py +363 -359
- warp/tests/unittest_utils.py +603 -578
- warp/tests/unused_test_misc.py +71 -71
- warp/tests/walkthrough_debug.py +85 -85
- warp/thirdparty/appdirs.py +598 -598
- warp/thirdparty/dlpack.py +143 -143
- warp/thirdparty/unittest_parallel.py +566 -561
- warp/torch.py +321 -295
- warp/types.py +4504 -4450
- warp/utils.py +1008 -821
- {warp_lang-1.0.2.dist-info → warp_lang-1.1.0.dist-info}/LICENSE.md +126 -126
- {warp_lang-1.0.2.dist-info → warp_lang-1.1.0.dist-info}/METADATA +338 -400
- warp_lang-1.1.0.dist-info/RECORD +352 -0
- warp/examples/assets/cube.usda +0 -42
- warp/examples/assets/sphere.usda +0 -56
- warp/examples/assets/torus.usda +0 -105
- warp_lang-1.0.2.dist-info/RECORD +0 -352
- {warp_lang-1.0.2.dist-info → warp_lang-1.1.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.0.2.dist-info → warp_lang-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,190 +1,190 @@
|
|
|
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
|
-
import unittest
|
|
9
|
-
from functools import partial
|
|
10
|
-
|
|
11
|
-
import numpy as np
|
|
12
|
-
|
|
13
|
-
import warp as wp
|
|
14
|
-
from warp.tests.unittest_utils import *
|
|
15
|
-
from warp.utils import runlength_encode
|
|
16
|
-
|
|
17
|
-
wp.init()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def test_runlength_encode_int(test, device, n):
|
|
21
|
-
rng = np.random.default_rng(123)
|
|
22
|
-
|
|
23
|
-
values_np = np.sort(rng.integers(-10, high=10, size=n, dtype=int))
|
|
24
|
-
|
|
25
|
-
unique_values_np, unique_counts_np = np.unique(values_np, return_counts=True)
|
|
26
|
-
|
|
27
|
-
values = wp.array(values_np, device=device, dtype=int)
|
|
28
|
-
|
|
29
|
-
unique_values = wp.empty_like(values)
|
|
30
|
-
unique_counts = wp.empty_like(values)
|
|
31
|
-
|
|
32
|
-
run_count = runlength_encode(values, unique_values, unique_counts)
|
|
33
|
-
|
|
34
|
-
test.assertEqual(run_count, len(unique_values_np))
|
|
35
|
-
assert_np_equal(unique_values.numpy()[:run_count], unique_values_np[:run_count])
|
|
36
|
-
assert_np_equal(unique_counts.numpy()[:run_count], unique_counts_np[:run_count])
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def test_runlength_encode_error_insufficient_storage(test, device):
|
|
40
|
-
values = wp.zeros(123, dtype=int, device=device)
|
|
41
|
-
run_values = wp.empty(1, dtype=int, device=device)
|
|
42
|
-
run_lengths = wp.empty(123, dtype=int, device=device)
|
|
43
|
-
with test.assertRaisesRegex(
|
|
44
|
-
RuntimeError,
|
|
45
|
-
r"Output array storage sizes must be at least equal to value_count$",
|
|
46
|
-
):
|
|
47
|
-
runlength_encode(values, run_values, run_lengths)
|
|
48
|
-
|
|
49
|
-
values = wp.zeros(123, dtype=int, device="cpu")
|
|
50
|
-
run_values = wp.empty(123, dtype=int, device="cpu")
|
|
51
|
-
run_lengths = wp.empty(1, dtype=int, device="cpu")
|
|
52
|
-
with test.assertRaisesRegex(
|
|
53
|
-
RuntimeError,
|
|
54
|
-
r"Output array storage sizes must be at least equal to value_count$",
|
|
55
|
-
):
|
|
56
|
-
runlength_encode(values, run_values, run_lengths)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def test_runlength_encode_error_dtypes_mismatch(test, device):
|
|
60
|
-
values = wp.zeros(123, dtype=int, device=device)
|
|
61
|
-
run_values = wp.empty(123, dtype=float, device=device)
|
|
62
|
-
run_lengths = wp.empty_like(values, device=device)
|
|
63
|
-
with test.assertRaisesRegex(
|
|
64
|
-
RuntimeError,
|
|
65
|
-
r"values and run_values data types do not match$",
|
|
66
|
-
):
|
|
67
|
-
runlength_encode(values, run_values, run_lengths)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def test_runlength_encode_error_run_length_unsupported_dtype(test, device):
|
|
71
|
-
values = wp.zeros(123, dtype=int, device=device)
|
|
72
|
-
run_values = wp.empty(123, dtype=int, device=device)
|
|
73
|
-
run_lengths = wp.empty(123, dtype=float, device=device)
|
|
74
|
-
with test.assertRaisesRegex(
|
|
75
|
-
RuntimeError,
|
|
76
|
-
r"run_lengths array must be of type int32$",
|
|
77
|
-
):
|
|
78
|
-
runlength_encode(values, run_values, run_lengths)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def test_runlength_encode_error_run_count_unsupported_dtype(test, device):
|
|
82
|
-
values = wp.zeros(123, dtype=int, device=device)
|
|
83
|
-
run_values = wp.empty_like(values, device=device)
|
|
84
|
-
run_lengths = wp.empty_like(values, device=device)
|
|
85
|
-
run_count = wp.empty(shape=(1,), dtype=float, device=device)
|
|
86
|
-
with test.assertRaisesRegex(
|
|
87
|
-
RuntimeError,
|
|
88
|
-
r"run_count array must be of type int32$",
|
|
89
|
-
):
|
|
90
|
-
runlength_encode(values, run_values, run_lengths, run_count=run_count)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def test_runlength_encode_error_unsupported_dtype(test, device):
|
|
94
|
-
values = wp.zeros(123, dtype=float, device=device)
|
|
95
|
-
run_values = wp.empty(123, dtype=float, device=device)
|
|
96
|
-
run_lengths = wp.empty(123, dtype=int, device=device)
|
|
97
|
-
with test.assertRaisesRegex(
|
|
98
|
-
RuntimeError,
|
|
99
|
-
r"Unsupported data type$",
|
|
100
|
-
):
|
|
101
|
-
runlength_encode(values, run_values, run_lengths)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
devices = get_test_devices()
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class TestRunlengthEncode(unittest.TestCase):
|
|
108
|
-
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
109
|
-
def test_runlength_encode_error_devices_mismatch(self):
|
|
110
|
-
values = wp.zeros(123, dtype=int, device="cpu")
|
|
111
|
-
run_values = wp.empty_like(values, device="cuda:0")
|
|
112
|
-
run_lengths = wp.empty_like(values, device="cuda:0")
|
|
113
|
-
with self.assertRaisesRegex(
|
|
114
|
-
RuntimeError,
|
|
115
|
-
r"Array storage devices do not match$",
|
|
116
|
-
):
|
|
117
|
-
runlength_encode(values, run_values, run_lengths)
|
|
118
|
-
|
|
119
|
-
values = wp.zeros(123, dtype=int, device="cpu")
|
|
120
|
-
run_values = wp.empty_like(values, device="cpu")
|
|
121
|
-
run_lengths = wp.empty_like(values, device="cuda:0")
|
|
122
|
-
with self.assertRaisesRegex(
|
|
123
|
-
RuntimeError,
|
|
124
|
-
r"Array storage devices do not match$",
|
|
125
|
-
):
|
|
126
|
-
runlength_encode(values, run_values, run_lengths)
|
|
127
|
-
|
|
128
|
-
values = wp.zeros(123, dtype=int, device="cpu")
|
|
129
|
-
run_values = wp.empty_like(values, device="cuda:0")
|
|
130
|
-
run_lengths = wp.empty_like(values, device="cpu")
|
|
131
|
-
with self.assertRaisesRegex(
|
|
132
|
-
RuntimeError,
|
|
133
|
-
r"Array storage devices do not match$",
|
|
134
|
-
):
|
|
135
|
-
runlength_encode(values, run_values, run_lengths)
|
|
136
|
-
|
|
137
|
-
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
138
|
-
def test_runlength_encode_error_run_count_device_mismatch(self):
|
|
139
|
-
values = wp.zeros(123, dtype=int, device="cpu")
|
|
140
|
-
run_values = wp.empty_like(values, device="cpu")
|
|
141
|
-
run_lengths = wp.empty_like(values, device="cpu")
|
|
142
|
-
run_count = wp.empty(shape=(1,), dtype=int, device="cuda:0")
|
|
143
|
-
with self.assertRaisesRegex(
|
|
144
|
-
RuntimeError,
|
|
145
|
-
r"run_count storage device does not match other arrays$",
|
|
146
|
-
):
|
|
147
|
-
runlength_encode(values, run_values, run_lengths, run_count=run_count)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
add_function_test(
|
|
151
|
-
TestRunlengthEncode, "test_runlength_encode_int", partial(test_runlength_encode_int, n=100), devices=devices
|
|
152
|
-
)
|
|
153
|
-
add_function_test(
|
|
154
|
-
TestRunlengthEncode, "test_runlength_encode_empty", partial(test_runlength_encode_int, n=0), devices=devices
|
|
155
|
-
)
|
|
156
|
-
add_function_test(
|
|
157
|
-
TestRunlengthEncode,
|
|
158
|
-
"test_runlength_encode_error_insufficient_storage",
|
|
159
|
-
test_runlength_encode_error_insufficient_storage,
|
|
160
|
-
devices=devices,
|
|
161
|
-
)
|
|
162
|
-
add_function_test(
|
|
163
|
-
TestRunlengthEncode,
|
|
164
|
-
"test_runlength_encode_error_dtypes_mismatch",
|
|
165
|
-
test_runlength_encode_error_dtypes_mismatch,
|
|
166
|
-
devices=devices,
|
|
167
|
-
)
|
|
168
|
-
add_function_test(
|
|
169
|
-
TestRunlengthEncode,
|
|
170
|
-
"test_runlength_encode_error_run_length_unsupported_dtype",
|
|
171
|
-
test_runlength_encode_error_run_length_unsupported_dtype,
|
|
172
|
-
devices=devices,
|
|
173
|
-
)
|
|
174
|
-
add_function_test(
|
|
175
|
-
TestRunlengthEncode,
|
|
176
|
-
"test_runlength_encode_error_run_count_unsupported_dtype",
|
|
177
|
-
test_runlength_encode_error_run_count_unsupported_dtype,
|
|
178
|
-
devices=devices,
|
|
179
|
-
)
|
|
180
|
-
add_function_test(
|
|
181
|
-
TestRunlengthEncode,
|
|
182
|
-
"test_runlength_encode_error_unsupported_dtype",
|
|
183
|
-
test_runlength_encode_error_unsupported_dtype,
|
|
184
|
-
devices=devices,
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if __name__ == "__main__":
|
|
189
|
-
wp.build.clear_kernel_cache()
|
|
190
|
-
unittest.main(verbosity=2)
|
|
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
|
+
import unittest
|
|
9
|
+
from functools import partial
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
import warp as wp
|
|
14
|
+
from warp.tests.unittest_utils import *
|
|
15
|
+
from warp.utils import runlength_encode
|
|
16
|
+
|
|
17
|
+
wp.init()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_runlength_encode_int(test, device, n):
|
|
21
|
+
rng = np.random.default_rng(123)
|
|
22
|
+
|
|
23
|
+
values_np = np.sort(rng.integers(-10, high=10, size=n, dtype=int))
|
|
24
|
+
|
|
25
|
+
unique_values_np, unique_counts_np = np.unique(values_np, return_counts=True)
|
|
26
|
+
|
|
27
|
+
values = wp.array(values_np, device=device, dtype=int)
|
|
28
|
+
|
|
29
|
+
unique_values = wp.empty_like(values)
|
|
30
|
+
unique_counts = wp.empty_like(values)
|
|
31
|
+
|
|
32
|
+
run_count = runlength_encode(values, unique_values, unique_counts)
|
|
33
|
+
|
|
34
|
+
test.assertEqual(run_count, len(unique_values_np))
|
|
35
|
+
assert_np_equal(unique_values.numpy()[:run_count], unique_values_np[:run_count])
|
|
36
|
+
assert_np_equal(unique_counts.numpy()[:run_count], unique_counts_np[:run_count])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_runlength_encode_error_insufficient_storage(test, device):
|
|
40
|
+
values = wp.zeros(123, dtype=int, device=device)
|
|
41
|
+
run_values = wp.empty(1, dtype=int, device=device)
|
|
42
|
+
run_lengths = wp.empty(123, dtype=int, device=device)
|
|
43
|
+
with test.assertRaisesRegex(
|
|
44
|
+
RuntimeError,
|
|
45
|
+
r"Output array storage sizes must be at least equal to value_count$",
|
|
46
|
+
):
|
|
47
|
+
runlength_encode(values, run_values, run_lengths)
|
|
48
|
+
|
|
49
|
+
values = wp.zeros(123, dtype=int, device="cpu")
|
|
50
|
+
run_values = wp.empty(123, dtype=int, device="cpu")
|
|
51
|
+
run_lengths = wp.empty(1, dtype=int, device="cpu")
|
|
52
|
+
with test.assertRaisesRegex(
|
|
53
|
+
RuntimeError,
|
|
54
|
+
r"Output array storage sizes must be at least equal to value_count$",
|
|
55
|
+
):
|
|
56
|
+
runlength_encode(values, run_values, run_lengths)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_runlength_encode_error_dtypes_mismatch(test, device):
|
|
60
|
+
values = wp.zeros(123, dtype=int, device=device)
|
|
61
|
+
run_values = wp.empty(123, dtype=float, device=device)
|
|
62
|
+
run_lengths = wp.empty_like(values, device=device)
|
|
63
|
+
with test.assertRaisesRegex(
|
|
64
|
+
RuntimeError,
|
|
65
|
+
r"values and run_values data types do not match$",
|
|
66
|
+
):
|
|
67
|
+
runlength_encode(values, run_values, run_lengths)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_runlength_encode_error_run_length_unsupported_dtype(test, device):
|
|
71
|
+
values = wp.zeros(123, dtype=int, device=device)
|
|
72
|
+
run_values = wp.empty(123, dtype=int, device=device)
|
|
73
|
+
run_lengths = wp.empty(123, dtype=float, device=device)
|
|
74
|
+
with test.assertRaisesRegex(
|
|
75
|
+
RuntimeError,
|
|
76
|
+
r"run_lengths array must be of type int32$",
|
|
77
|
+
):
|
|
78
|
+
runlength_encode(values, run_values, run_lengths)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_runlength_encode_error_run_count_unsupported_dtype(test, device):
|
|
82
|
+
values = wp.zeros(123, dtype=int, device=device)
|
|
83
|
+
run_values = wp.empty_like(values, device=device)
|
|
84
|
+
run_lengths = wp.empty_like(values, device=device)
|
|
85
|
+
run_count = wp.empty(shape=(1,), dtype=float, device=device)
|
|
86
|
+
with test.assertRaisesRegex(
|
|
87
|
+
RuntimeError,
|
|
88
|
+
r"run_count array must be of type int32$",
|
|
89
|
+
):
|
|
90
|
+
runlength_encode(values, run_values, run_lengths, run_count=run_count)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_runlength_encode_error_unsupported_dtype(test, device):
|
|
94
|
+
values = wp.zeros(123, dtype=float, device=device)
|
|
95
|
+
run_values = wp.empty(123, dtype=float, device=device)
|
|
96
|
+
run_lengths = wp.empty(123, dtype=int, device=device)
|
|
97
|
+
with test.assertRaisesRegex(
|
|
98
|
+
RuntimeError,
|
|
99
|
+
r"Unsupported data type$",
|
|
100
|
+
):
|
|
101
|
+
runlength_encode(values, run_values, run_lengths)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
devices = get_test_devices()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class TestRunlengthEncode(unittest.TestCase):
|
|
108
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
109
|
+
def test_runlength_encode_error_devices_mismatch(self):
|
|
110
|
+
values = wp.zeros(123, dtype=int, device="cpu")
|
|
111
|
+
run_values = wp.empty_like(values, device="cuda:0")
|
|
112
|
+
run_lengths = wp.empty_like(values, device="cuda:0")
|
|
113
|
+
with self.assertRaisesRegex(
|
|
114
|
+
RuntimeError,
|
|
115
|
+
r"Array storage devices do not match$",
|
|
116
|
+
):
|
|
117
|
+
runlength_encode(values, run_values, run_lengths)
|
|
118
|
+
|
|
119
|
+
values = wp.zeros(123, dtype=int, device="cpu")
|
|
120
|
+
run_values = wp.empty_like(values, device="cpu")
|
|
121
|
+
run_lengths = wp.empty_like(values, device="cuda:0")
|
|
122
|
+
with self.assertRaisesRegex(
|
|
123
|
+
RuntimeError,
|
|
124
|
+
r"Array storage devices do not match$",
|
|
125
|
+
):
|
|
126
|
+
runlength_encode(values, run_values, run_lengths)
|
|
127
|
+
|
|
128
|
+
values = wp.zeros(123, dtype=int, device="cpu")
|
|
129
|
+
run_values = wp.empty_like(values, device="cuda:0")
|
|
130
|
+
run_lengths = wp.empty_like(values, device="cpu")
|
|
131
|
+
with self.assertRaisesRegex(
|
|
132
|
+
RuntimeError,
|
|
133
|
+
r"Array storage devices do not match$",
|
|
134
|
+
):
|
|
135
|
+
runlength_encode(values, run_values, run_lengths)
|
|
136
|
+
|
|
137
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
138
|
+
def test_runlength_encode_error_run_count_device_mismatch(self):
|
|
139
|
+
values = wp.zeros(123, dtype=int, device="cpu")
|
|
140
|
+
run_values = wp.empty_like(values, device="cpu")
|
|
141
|
+
run_lengths = wp.empty_like(values, device="cpu")
|
|
142
|
+
run_count = wp.empty(shape=(1,), dtype=int, device="cuda:0")
|
|
143
|
+
with self.assertRaisesRegex(
|
|
144
|
+
RuntimeError,
|
|
145
|
+
r"run_count storage device does not match other arrays$",
|
|
146
|
+
):
|
|
147
|
+
runlength_encode(values, run_values, run_lengths, run_count=run_count)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
add_function_test(
|
|
151
|
+
TestRunlengthEncode, "test_runlength_encode_int", partial(test_runlength_encode_int, n=100), devices=devices
|
|
152
|
+
)
|
|
153
|
+
add_function_test(
|
|
154
|
+
TestRunlengthEncode, "test_runlength_encode_empty", partial(test_runlength_encode_int, n=0), devices=devices
|
|
155
|
+
)
|
|
156
|
+
add_function_test(
|
|
157
|
+
TestRunlengthEncode,
|
|
158
|
+
"test_runlength_encode_error_insufficient_storage",
|
|
159
|
+
test_runlength_encode_error_insufficient_storage,
|
|
160
|
+
devices=devices,
|
|
161
|
+
)
|
|
162
|
+
add_function_test(
|
|
163
|
+
TestRunlengthEncode,
|
|
164
|
+
"test_runlength_encode_error_dtypes_mismatch",
|
|
165
|
+
test_runlength_encode_error_dtypes_mismatch,
|
|
166
|
+
devices=devices,
|
|
167
|
+
)
|
|
168
|
+
add_function_test(
|
|
169
|
+
TestRunlengthEncode,
|
|
170
|
+
"test_runlength_encode_error_run_length_unsupported_dtype",
|
|
171
|
+
test_runlength_encode_error_run_length_unsupported_dtype,
|
|
172
|
+
devices=devices,
|
|
173
|
+
)
|
|
174
|
+
add_function_test(
|
|
175
|
+
TestRunlengthEncode,
|
|
176
|
+
"test_runlength_encode_error_run_count_unsupported_dtype",
|
|
177
|
+
test_runlength_encode_error_run_count_unsupported_dtype,
|
|
178
|
+
devices=devices,
|
|
179
|
+
)
|
|
180
|
+
add_function_test(
|
|
181
|
+
TestRunlengthEncode,
|
|
182
|
+
"test_runlength_encode_error_unsupported_dtype",
|
|
183
|
+
test_runlength_encode_error_unsupported_dtype,
|
|
184
|
+
devices=devices,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
if __name__ == "__main__":
|
|
189
|
+
wp.build.clear_kernel_cache()
|
|
190
|
+
unittest.main(verbosity=2)
|
|
@@ -0,0 +1,243 @@
|
|
|
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 unittest
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
import warp as wp
|
|
13
|
+
import warp.sim
|
|
14
|
+
from warp.tests.unittest_utils import *
|
|
15
|
+
|
|
16
|
+
wp.init()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@wp.kernel
|
|
20
|
+
def evaluate_loss(
|
|
21
|
+
joint_q: wp.array(dtype=float),
|
|
22
|
+
weighting: float,
|
|
23
|
+
target: float,
|
|
24
|
+
# output
|
|
25
|
+
loss: wp.array(dtype=float),
|
|
26
|
+
):
|
|
27
|
+
tid = wp.tid()
|
|
28
|
+
# wp.atomic_add(loss, 0, weighting * (target - joint_q[tid * 2 + 1]) ** 2.0)
|
|
29
|
+
d = wp.abs(target - joint_q[tid * 2 + 1])
|
|
30
|
+
wp.atomic_add(loss, 0, weighting * d)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@wp.kernel
|
|
34
|
+
def assign_action(action: wp.array(dtype=float), joint_act: wp.array(dtype=float)):
|
|
35
|
+
tid = wp.tid()
|
|
36
|
+
joint_act[2 * tid] = action[tid]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def gradcheck(func, inputs, device, eps=1e-1, tol=1e-2):
|
|
40
|
+
"""
|
|
41
|
+
Checks that the gradient of the Warp kernel is correct by comparing it to the
|
|
42
|
+
numerical gradient computed using finite differences.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def f(xs):
|
|
46
|
+
# call the kernel without taping for finite differences
|
|
47
|
+
wp_xs = [wp.array(xs[i], ndim=1, dtype=inputs[i].dtype, device=device) for i in range(len(inputs))]
|
|
48
|
+
output = func(*wp_xs)
|
|
49
|
+
return output.numpy()[0]
|
|
50
|
+
|
|
51
|
+
# compute numerical gradient
|
|
52
|
+
numerical_grad = []
|
|
53
|
+
np_xs = []
|
|
54
|
+
for i in range(len(inputs)):
|
|
55
|
+
np_xs.append(inputs[i].numpy().flatten().copy())
|
|
56
|
+
numerical_grad.append(np.zeros_like(np_xs[-1]))
|
|
57
|
+
inputs[i].requires_grad = True
|
|
58
|
+
|
|
59
|
+
for i in range(len(np_xs)):
|
|
60
|
+
for j in range(len(np_xs[i])):
|
|
61
|
+
np_xs[i][j] += eps
|
|
62
|
+
y1 = f(np_xs)
|
|
63
|
+
np_xs[i][j] -= 2 * eps
|
|
64
|
+
y2 = f(np_xs)
|
|
65
|
+
np_xs[i][j] += eps
|
|
66
|
+
numerical_grad[i][j] = (y1 - y2) / (2 * eps)
|
|
67
|
+
|
|
68
|
+
# compute analytical gradient
|
|
69
|
+
tape = wp.Tape()
|
|
70
|
+
with tape:
|
|
71
|
+
output = func(*inputs)
|
|
72
|
+
|
|
73
|
+
tape.backward(loss=output)
|
|
74
|
+
|
|
75
|
+
# compare gradients
|
|
76
|
+
for i in range(len(inputs)):
|
|
77
|
+
grad = tape.gradients[inputs[i]]
|
|
78
|
+
assert_np_equal(grad.numpy(), numerical_grad[i], tol=tol)
|
|
79
|
+
# ensure the signs match
|
|
80
|
+
assert np.allclose(grad.numpy() * numerical_grad[i] > 0, True)
|
|
81
|
+
|
|
82
|
+
tape.zero()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_box_pushing_on_rails(test, device, joint_type, integrator_type):
|
|
86
|
+
# Two boxes on a rail (prismatic or D6 joint), one is pushed, the other is passive.
|
|
87
|
+
# The absolute distance to a target is measured and gradients are compared for
|
|
88
|
+
# a push that is too far and too close.
|
|
89
|
+
num_envs = 2
|
|
90
|
+
num_steps = 200
|
|
91
|
+
sim_substeps = 2
|
|
92
|
+
dt = 1 / 30
|
|
93
|
+
|
|
94
|
+
target = 5.0
|
|
95
|
+
|
|
96
|
+
if integrator_type == 0:
|
|
97
|
+
contact_ke = 1e5
|
|
98
|
+
contact_kd = 1e3
|
|
99
|
+
else:
|
|
100
|
+
contact_ke = 1e5
|
|
101
|
+
contact_kd = 1e1
|
|
102
|
+
|
|
103
|
+
complete_builder = wp.sim.ModelBuilder()
|
|
104
|
+
|
|
105
|
+
complete_builder.default_shape_ke = contact_ke
|
|
106
|
+
complete_builder.default_shape_kd = contact_kd
|
|
107
|
+
|
|
108
|
+
for _ in range(num_envs):
|
|
109
|
+
builder = wp.sim.ModelBuilder()
|
|
110
|
+
|
|
111
|
+
builder.default_shape_ke = complete_builder.default_shape_ke
|
|
112
|
+
builder.default_shape_kd = complete_builder.default_shape_kd
|
|
113
|
+
|
|
114
|
+
b0 = builder.add_body(name="pusher")
|
|
115
|
+
builder.add_shape_box(b0, density=1000.0)
|
|
116
|
+
|
|
117
|
+
b1 = builder.add_body(name="passive")
|
|
118
|
+
builder.add_shape_box(b1, hx=0.4, hy=0.4, hz=0.4, density=1000.0)
|
|
119
|
+
|
|
120
|
+
if joint_type == 0:
|
|
121
|
+
builder.add_joint_prismatic(-1, b0)
|
|
122
|
+
builder.add_joint_prismatic(-1, b1)
|
|
123
|
+
else:
|
|
124
|
+
builder.add_joint_d6(-1, b0, linear_axes=[wp.sim.JointAxis((1.0, 0.0, 0.0))])
|
|
125
|
+
builder.add_joint_d6(-1, b1, linear_axes=[wp.sim.JointAxis((1.0, 0.0, 0.0))])
|
|
126
|
+
|
|
127
|
+
builder.joint_q[-2:] = [0.0, 1.0]
|
|
128
|
+
complete_builder.add_builder(builder)
|
|
129
|
+
|
|
130
|
+
assert complete_builder.body_count == 2 * num_envs
|
|
131
|
+
assert complete_builder.joint_count == 2 * num_envs
|
|
132
|
+
assert set(complete_builder.shape_collision_group) == set(range(1, num_envs + 1))
|
|
133
|
+
|
|
134
|
+
complete_builder.gravity = 0.0
|
|
135
|
+
model = complete_builder.finalize(device=device, requires_grad=True)
|
|
136
|
+
model.ground = False
|
|
137
|
+
model.joint_attach_ke = 32000.0 * 16
|
|
138
|
+
model.joint_attach_kd = 500.0 * 4
|
|
139
|
+
|
|
140
|
+
if integrator_type == 0:
|
|
141
|
+
integrator = wp.sim.FeatherstoneIntegrator(model, update_mass_matrix_every=num_steps * sim_substeps)
|
|
142
|
+
elif integrator_type == 1:
|
|
143
|
+
integrator = wp.sim.SemiImplicitIntegrator()
|
|
144
|
+
sim_substeps *= 5
|
|
145
|
+
else:
|
|
146
|
+
integrator = wp.sim.XPBDIntegrator(iterations=2, rigid_contact_relaxation=1.0)
|
|
147
|
+
|
|
148
|
+
# renderer = wp.sim.render.SimRenderer(model, "test_sim_grad.usd", scaling=1.0)
|
|
149
|
+
renderer = None
|
|
150
|
+
render_time = 0.0
|
|
151
|
+
|
|
152
|
+
def rollout(action: wp.array) -> wp.array:
|
|
153
|
+
nonlocal render_time
|
|
154
|
+
states = [model.state() for _ in range(num_steps * sim_substeps + 1)]
|
|
155
|
+
|
|
156
|
+
if not isinstance(integrator, wp.sim.FeatherstoneIntegrator):
|
|
157
|
+
# apply initial generalized coordinates
|
|
158
|
+
wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, states[0])
|
|
159
|
+
|
|
160
|
+
control_active = model.control()
|
|
161
|
+
control_nop = model.control()
|
|
162
|
+
|
|
163
|
+
wp.launch(
|
|
164
|
+
assign_action,
|
|
165
|
+
dim=num_envs,
|
|
166
|
+
inputs=[action],
|
|
167
|
+
outputs=[control_active.joint_act],
|
|
168
|
+
device=model.device,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
i = 0
|
|
172
|
+
for step in range(num_steps):
|
|
173
|
+
wp.sim.collide(model, states[i])
|
|
174
|
+
control = control_active if step < 10 else control_nop
|
|
175
|
+
if renderer:
|
|
176
|
+
renderer.begin_frame(render_time)
|
|
177
|
+
renderer.render(states[i])
|
|
178
|
+
renderer.end_frame()
|
|
179
|
+
render_time += dt
|
|
180
|
+
for _ in range(sim_substeps):
|
|
181
|
+
integrator.simulate(model, states[i], states[i + 1], dt / sim_substeps, control)
|
|
182
|
+
i += 1
|
|
183
|
+
|
|
184
|
+
if not isinstance(integrator, wp.sim.FeatherstoneIntegrator):
|
|
185
|
+
# compute generalized coordinates
|
|
186
|
+
wp.sim.eval_ik(model, states[-1], states[-1].joint_q, states[-1].joint_qd)
|
|
187
|
+
|
|
188
|
+
loss = wp.zeros(1, requires_grad=True, device=device)
|
|
189
|
+
wp.launch(
|
|
190
|
+
evaluate_loss,
|
|
191
|
+
dim=num_envs,
|
|
192
|
+
inputs=[states[-1].joint_q, 1.0, target],
|
|
193
|
+
outputs=[loss],
|
|
194
|
+
device=model.device,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if renderer:
|
|
198
|
+
renderer.save()
|
|
199
|
+
|
|
200
|
+
return loss
|
|
201
|
+
|
|
202
|
+
action_too_far = wp.array(
|
|
203
|
+
[5000.0 for _ in range(num_envs)],
|
|
204
|
+
device=device,
|
|
205
|
+
dtype=wp.float32,
|
|
206
|
+
requires_grad=True,
|
|
207
|
+
)
|
|
208
|
+
tol = 1e-2
|
|
209
|
+
if isinstance(integrator, wp.sim.XPBDIntegrator):
|
|
210
|
+
# Euler, XPBD do not yield as accurate gradients, but at least the
|
|
211
|
+
# signs should match
|
|
212
|
+
tol = 0.1
|
|
213
|
+
gradcheck(rollout, [action_too_far], device=device, eps=0.2, tol=tol)
|
|
214
|
+
|
|
215
|
+
action_too_close = wp.array(
|
|
216
|
+
[1500.0 for _ in range(num_envs)],
|
|
217
|
+
device=device,
|
|
218
|
+
dtype=wp.float32,
|
|
219
|
+
requires_grad=True,
|
|
220
|
+
)
|
|
221
|
+
gradcheck(rollout, [action_too_close], device=device, eps=0.2, tol=tol)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
devices = get_test_devices()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class TestSimGradients(unittest.TestCase):
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
for int_type, int_name in enumerate(["featherstone", "semiimplicit"]):
|
|
232
|
+
for jt_type, jt_name in enumerate(["prismatic", "d6"]):
|
|
233
|
+
test_name = f"test_box_pushing_on_rails_{int_name}_{jt_name}"
|
|
234
|
+
|
|
235
|
+
def test_fn(self, device, jt_type=jt_type, int_type=int_type):
|
|
236
|
+
return test_box_pushing_on_rails(self, device, jt_type, int_type)
|
|
237
|
+
|
|
238
|
+
add_function_test(TestSimGradients, test_name, test_fn, devices=devices)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
if __name__ == "__main__":
|
|
242
|
+
wp.build.clear_kernel_cache()
|
|
243
|
+
unittest.main(verbosity=2, failfast=True)
|