warp-lang 1.0.0b2__py3-none-win_amd64.whl → 1.0.0b6__py3-none-win_amd64.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.
- docs/conf.py +17 -5
- examples/env/env_ant.py +1 -1
- examples/env/env_cartpole.py +1 -1
- examples/env/env_humanoid.py +1 -1
- examples/env/env_usd.py +4 -1
- examples/env/environment.py +8 -9
- examples/example_dem.py +34 -33
- examples/example_diffray.py +364 -337
- examples/example_fluid.py +32 -23
- examples/example_jacobian_ik.py +97 -93
- examples/example_marching_cubes.py +6 -16
- examples/example_mesh.py +6 -16
- examples/example_mesh_intersect.py +16 -14
- examples/example_nvdb.py +14 -16
- examples/example_raycast.py +14 -13
- examples/example_raymarch.py +16 -23
- examples/example_render_opengl.py +19 -10
- examples/example_sim_cartpole.py +82 -78
- examples/example_sim_cloth.py +45 -48
- examples/example_sim_fk_grad.py +51 -44
- examples/example_sim_fk_grad_torch.py +47 -40
- examples/example_sim_grad_bounce.py +108 -133
- examples/example_sim_grad_cloth.py +99 -113
- examples/example_sim_granular.py +5 -6
- examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
- examples/example_sim_neo_hookean.py +51 -55
- examples/example_sim_particle_chain.py +4 -4
- examples/example_sim_quadruped.py +126 -81
- examples/example_sim_rigid_chain.py +54 -61
- examples/example_sim_rigid_contact.py +66 -70
- examples/example_sim_rigid_fem.py +3 -3
- examples/example_sim_rigid_force.py +1 -1
- examples/example_sim_rigid_gyroscopic.py +3 -4
- examples/example_sim_rigid_kinematics.py +28 -39
- examples/example_sim_trajopt.py +112 -110
- examples/example_sph.py +9 -8
- examples/example_wave.py +7 -7
- examples/fem/bsr_utils.py +30 -17
- examples/fem/example_apic_fluid.py +85 -69
- examples/fem/example_convection_diffusion.py +97 -93
- examples/fem/example_convection_diffusion_dg.py +142 -149
- examples/fem/example_convection_diffusion_dg0.py +141 -136
- examples/fem/example_deformed_geometry.py +146 -0
- examples/fem/example_diffusion.py +115 -84
- examples/fem/example_diffusion_3d.py +116 -86
- examples/fem/example_diffusion_mgpu.py +102 -79
- examples/fem/example_mixed_elasticity.py +139 -100
- examples/fem/example_navier_stokes.py +175 -162
- examples/fem/example_stokes.py +143 -111
- examples/fem/example_stokes_transfer.py +186 -157
- examples/fem/mesh_utils.py +59 -97
- examples/fem/plot_utils.py +138 -17
- tools/ci/publishing/build_nodes_info.py +54 -0
- warp/__init__.py +4 -3
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +5 -3
- warp/build_dll.py +29 -9
- warp/builtins.py +836 -492
- warp/codegen.py +864 -553
- warp/config.py +3 -1
- warp/context.py +389 -172
- warp/fem/__init__.py +24 -6
- warp/fem/cache.py +318 -25
- warp/fem/dirichlet.py +7 -3
- warp/fem/domain.py +14 -0
- warp/fem/field/__init__.py +30 -38
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +244 -138
- warp/fem/field/restriction.py +8 -6
- warp/fem/field/test.py +127 -59
- warp/fem/field/trial.py +117 -60
- warp/fem/geometry/__init__.py +5 -1
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +24 -1
- warp/fem/geometry/geometry.py +86 -14
- warp/fem/geometry/grid_2d.py +112 -54
- warp/fem/geometry/grid_3d.py +134 -65
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +85 -33
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +451 -115
- warp/fem/geometry/trimesh_2d.py +197 -92
- warp/fem/integrate.py +534 -268
- warp/fem/operator.py +58 -31
- warp/fem/polynomial.py +11 -0
- warp/fem/quadrature/__init__.py +1 -1
- warp/fem/quadrature/pic_quadrature.py +150 -58
- warp/fem/quadrature/quadrature.py +209 -57
- warp/fem/space/__init__.py +230 -53
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +49 -2
- warp/fem/space/function_space.py +90 -39
- warp/fem/space/grid_2d_function_space.py +149 -496
- warp/fem/space/grid_3d_function_space.py +173 -538
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +129 -76
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +46 -34
- warp/fem/space/shape/__init__.py +15 -0
- warp/fem/space/shape/cube_shape_function.py +738 -0
- warp/fem/space/shape/shape_function.py +103 -0
- warp/fem/space/shape/square_shape_function.py +611 -0
- warp/fem/space/shape/tet_shape_function.py +567 -0
- warp/fem/space/shape/triangle_shape_function.py +429 -0
- warp/fem/space/tetmesh_function_space.py +132 -1039
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +104 -742
- warp/fem/types.py +13 -11
- warp/fem/utils.py +335 -60
- warp/native/array.h +120 -34
- warp/native/builtin.h +101 -72
- warp/native/bvh.cpp +73 -325
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +22 -40
- warp/native/clang/clang.cpp +1 -0
- warp/native/crt.h +2 -0
- warp/native/cuda_util.cpp +8 -3
- warp/native/cuda_util.h +1 -0
- warp/native/exports.h +1522 -1243
- warp/native/intersect.h +19 -4
- warp/native/intersect_adj.h +8 -8
- warp/native/mat.h +76 -17
- warp/native/mesh.cpp +33 -108
- warp/native/mesh.cu +114 -18
- warp/native/mesh.h +395 -40
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +44 -34
- warp/native/reduce.cpp +1 -1
- warp/native/sparse.cpp +4 -4
- warp/native/sparse.cu +163 -155
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +18 -14
- warp/native/vec.h +103 -21
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +28 -3
- warp/native/warp.h +4 -3
- warp/render/render_opengl.py +261 -109
- warp/sim/__init__.py +1 -2
- warp/sim/articulation.py +385 -185
- warp/sim/import_mjcf.py +59 -48
- warp/sim/import_urdf.py +15 -15
- warp/sim/import_usd.py +174 -102
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_xpbd.py +4 -3
- warp/sim/model.py +330 -250
- warp/sim/render.py +1 -1
- warp/sparse.py +625 -152
- warp/stubs.py +341 -309
- warp/tape.py +9 -6
- warp/tests/__main__.py +3 -6
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/disabled_kinematics.py +239 -0
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +103 -106
- warp/tests/test_arithmetic.py +94 -74
- warp/tests/test_array.py +82 -101
- warp/tests/test_array_reduce.py +57 -23
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +22 -12
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +18 -18
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +165 -134
- warp/tests/test_compile_consts.py +28 -20
- warp/tests/test_conditional.py +108 -24
- warp/tests/test_copy.py +10 -12
- warp/tests/test_ctypes.py +112 -88
- warp/tests/test_dense.py +21 -14
- warp/tests/test_devices.py +98 -0
- warp/tests/test_dlpack.py +75 -75
- warp/tests/test_examples.py +237 -0
- warp/tests/test_fabricarray.py +22 -24
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1034 -124
- warp/tests/test_fp16.py +23 -16
- warp/tests/test_func.py +187 -86
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +123 -181
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +35 -34
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +24 -25
- warp/tests/test_intersect.py +18 -9
- warp/tests/test_large.py +141 -0
- warp/tests/test_launch.py +14 -41
- warp/tests/test_lerp.py +64 -65
- warp/tests/test_lvalue.py +493 -0
- warp/tests/test_marching_cubes.py +12 -13
- warp/tests/test_mat.py +517 -2898
- warp/tests/test_mat_lite.py +115 -0
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +103 -9
- warp/tests/test_matmul.py +304 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +60 -22
- warp/tests/test_mesh_query_aabb.py +21 -25
- warp/tests/test_mesh_query_point.py +111 -22
- warp/tests/test_mesh_query_ray.py +12 -24
- warp/tests/test_mlp.py +30 -22
- warp/tests/test_model.py +92 -89
- warp/tests/test_modules_lite.py +39 -0
- warp/tests/test_multigpu.py +88 -114
- warp/tests/test_noise.py +12 -11
- warp/tests/test_operators.py +16 -20
- warp/tests/test_options.py +11 -11
- warp/tests/test_pinned.py +17 -18
- warp/tests/test_print.py +32 -11
- warp/tests/test_quat.py +275 -129
- warp/tests/test_rand.py +18 -16
- warp/tests/test_reload.py +38 -34
- warp/tests/test_rounding.py +50 -43
- warp/tests/test_runlength_encode.py +168 -20
- warp/tests/test_smoothstep.py +9 -11
- warp/tests/test_snippet.py +143 -0
- warp/tests/test_sparse.py +261 -63
- warp/tests/test_spatial.py +276 -243
- warp/tests/test_streams.py +110 -85
- warp/tests/test_struct.py +268 -63
- warp/tests/test_tape.py +39 -21
- warp/tests/test_torch.py +90 -86
- warp/tests/test_transient_module.py +10 -12
- warp/tests/test_types.py +363 -0
- warp/tests/test_utils.py +451 -0
- warp/tests/test_vec.py +354 -2050
- warp/tests/test_vec_lite.py +73 -0
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +418 -376
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +291 -0
- warp/tests/unittest_utils.py +342 -0
- warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +589 -0
- warp/types.py +622 -211
- warp/utils.py +54 -393
- warp_lang-1.0.0b6.dist-info/METADATA +238 -0
- warp_lang-1.0.0b6.dist-info/RECORD +409 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
- examples/example_cache_management.py +0 -40
- examples/example_multigpu.py +0 -54
- examples/example_struct.py +0 -65
- examples/fem/example_stokes_transfer_3d.py +0 -210
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/fem/field/discrete_field.py +0 -80
- warp/fem/space/nodal_function_space.py +0 -233
- warp/tests/test_all.py +0 -223
- warp/tests/test_array_scan.py +0 -60
- warp/tests/test_base.py +0 -208
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- warp_lang-1.0.0b2.dist-info/METADATA +0 -26
- warp_lang-1.0.0b2.dist-info/RECORD +0 -380
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
warp/tape.py
CHANGED
|
@@ -37,6 +37,7 @@ class Tape:
|
|
|
37
37
|
print(tape.gradients[a])
|
|
38
38
|
|
|
39
39
|
"""
|
|
40
|
+
|
|
40
41
|
def __init__(self):
|
|
41
42
|
self.gradients = {}
|
|
42
43
|
self.const_gradients = set()
|
|
@@ -81,7 +82,7 @@ class Tape:
|
|
|
81
82
|
if loss.size > 1 or wp.types.type_length(loss.dtype) > 1:
|
|
82
83
|
raise RuntimeError("Can only return gradients for scalar loss functions.")
|
|
83
84
|
|
|
84
|
-
if loss.requires_grad
|
|
85
|
+
if not loss.requires_grad:
|
|
85
86
|
raise RuntimeError(
|
|
86
87
|
"Scalar loss arrays should have requires_grad=True set before calling Tape.backward()"
|
|
87
88
|
)
|
|
@@ -105,9 +106,10 @@ class Tape:
|
|
|
105
106
|
else:
|
|
106
107
|
kernel = launch[0]
|
|
107
108
|
dim = launch[1]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
max_blocks = launch[2]
|
|
110
|
+
inputs = launch[3]
|
|
111
|
+
outputs = launch[4]
|
|
112
|
+
device = launch[5]
|
|
111
113
|
|
|
112
114
|
adj_inputs = []
|
|
113
115
|
adj_outputs = []
|
|
@@ -129,11 +131,12 @@ class Tape:
|
|
|
129
131
|
adj_outputs=adj_outputs,
|
|
130
132
|
device=device,
|
|
131
133
|
adjoint=True,
|
|
134
|
+
max_blocks=max_blocks,
|
|
132
135
|
)
|
|
133
136
|
|
|
134
137
|
# record a kernel launch on the tape
|
|
135
|
-
def record_launch(self, kernel, dim, inputs, outputs, device):
|
|
136
|
-
self.launches.append([kernel, dim, inputs, outputs, device])
|
|
138
|
+
def record_launch(self, kernel, dim, max_blocks, inputs, outputs, device):
|
|
139
|
+
self.launches.append([kernel, dim, max_blocks, inputs, outputs, device])
|
|
137
140
|
|
|
138
141
|
def record_func(self, backward, arrays):
|
|
139
142
|
"""
|
warp/tests/__main__.py
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,15 @@
|
|
|
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
|
+
"""Dummy class used in test_reload.py"""
|
|
9
|
+
|
|
1
10
|
import warp as wp
|
|
2
11
|
|
|
3
12
|
|
|
4
|
-
# dummy class used in test_reload.py
|
|
5
13
|
class ClassKernelTest:
|
|
6
14
|
def __init__(self, device):
|
|
7
15
|
# 3x3 frames in the rest pose:
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
"""This file defines a kernel that fails on codegen.py"""
|
|
9
|
+
|
|
10
|
+
import warp as wp
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@wp.kernel
|
|
14
|
+
def unequal_types_kernel():
|
|
15
|
+
x = wp.int32(10)
|
|
16
|
+
y = 10
|
|
17
|
+
z = True
|
|
18
|
+
|
|
19
|
+
# Throws a TypeError
|
|
20
|
+
if x == y == z:
|
|
21
|
+
pass
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
# distribution of this software and related documentation without an express
|
|
6
6
|
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
"""This file is used to test reloading module references."""
|
|
9
9
|
|
|
10
10
|
import warp as wp
|
|
11
|
-
import warp.tests.
|
|
11
|
+
import warp.tests.aux_test_reference as ref
|
|
12
12
|
|
|
13
13
|
wp.init()
|
|
14
14
|
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
|
|
11
|
+
@wp.kernel
|
|
12
|
+
def unresolved_func_kernel():
|
|
13
|
+
# this should trigger an exception due to unresolved function
|
|
14
|
+
x = wp.missing_func(42)
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
|
|
11
|
+
@wp.kernel
|
|
12
|
+
def unresolved_symbol_kernel():
|
|
13
|
+
# this should trigger an exception due to unresolved symbol
|
|
14
|
+
x = missing_symbol
|
|
@@ -0,0 +1,239 @@
|
|
|
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 math
|
|
9
|
+
import unittest
|
|
10
|
+
|
|
11
|
+
import warp as wp
|
|
12
|
+
import warp.sim
|
|
13
|
+
from warp.tests.unittest_utils import *
|
|
14
|
+
|
|
15
|
+
wp.init()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def build_ant(num_envs):
|
|
19
|
+
builder = wp.sim.ModelBuilder()
|
|
20
|
+
for i in range(num_envs):
|
|
21
|
+
wp.sim.parse_mjcf(
|
|
22
|
+
os.path.join(os.path.dirname(__file__), "../../examples/assets/nv_ant.xml"),
|
|
23
|
+
builder,
|
|
24
|
+
up_axis="y",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
coord_count = 15
|
|
28
|
+
dof_count = 14
|
|
29
|
+
|
|
30
|
+
coord_start = i * coord_count
|
|
31
|
+
dof_start = i * dof_count
|
|
32
|
+
|
|
33
|
+
# base
|
|
34
|
+
builder.joint_q[coord_start : coord_start + 3] = [i * 2.0, 0.70, 0.0]
|
|
35
|
+
builder.joint_q[coord_start + 3 : coord_start + 7] = wp.quat_from_axis_angle((1.0, 0.0, 0.0), -math.pi * 0.5)
|
|
36
|
+
|
|
37
|
+
# joints
|
|
38
|
+
builder.joint_q[coord_start + 7 : coord_start + coord_count] = [0.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0]
|
|
39
|
+
builder.joint_qd[dof_start + 6 : dof_start + dof_count] = [1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0]
|
|
40
|
+
|
|
41
|
+
return builder
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def build_complex_joint_mechanism(chain_length):
|
|
45
|
+
builder = wp.sim.ModelBuilder()
|
|
46
|
+
com0 = wp.vec3(1.0, 2.0, 3.0)
|
|
47
|
+
com1 = wp.vec3(4.0, 5.0, 6.0)
|
|
48
|
+
com2 = wp.vec3(7.0, 8.0, 9.0)
|
|
49
|
+
ax0 = wp.normalize(wp.vec3(-1.0, 2.0, 3.0))
|
|
50
|
+
ax1 = wp.normalize(wp.vec3(4.0, -1.0, 2.0))
|
|
51
|
+
ax2 = wp.normalize(wp.vec3(-3.0, 4.0, -1.0))
|
|
52
|
+
# declare some transforms with nonzero translation and orientation
|
|
53
|
+
tf0 = wp.transform(wp.vec3(1.0, 2.0, 3.0), wp.quat_from_axis_angle((1.0, 0.0, 0.0), math.pi * 0.25))
|
|
54
|
+
tf1 = wp.transform(wp.vec3(4.0, 5.0, 6.0), wp.quat_from_axis_angle((0.0, 1.0, 0.0), math.pi * 0.5))
|
|
55
|
+
tf2 = wp.transform(wp.vec3(7.0, 8.0, 9.0), wp.quat_from_axis_angle((0.0, 0.0, 1.0), math.pi * 0.75))
|
|
56
|
+
|
|
57
|
+
parent = -1
|
|
58
|
+
for i in range(chain_length):
|
|
59
|
+
b0 = builder.add_body(com=com0)
|
|
60
|
+
builder.add_joint_fixed(parent=parent, child=b0, parent_xform=tf1, child_xform=tf0)
|
|
61
|
+
assert builder.articulation_count == 1
|
|
62
|
+
|
|
63
|
+
b1 = builder.add_body(com=com1)
|
|
64
|
+
builder.add_joint_revolute(parent=b0, child=b1, parent_xform=tf1, child_xform=tf2, axis=ax1)
|
|
65
|
+
builder.joint_q[-1] = 0.3
|
|
66
|
+
builder.joint_qd[-1] = 1.0
|
|
67
|
+
|
|
68
|
+
b2 = builder.add_body(com=com2)
|
|
69
|
+
builder.add_joint_universal(parent=b1, child=b2, parent_xform=tf2, child_xform=tf0, axis_0=ax0, axis_1=ax1)
|
|
70
|
+
builder.joint_q[-2:] = [0.3, 0.5]
|
|
71
|
+
builder.joint_qd[-2:] = [1.0, -1.0]
|
|
72
|
+
|
|
73
|
+
b3 = builder.add_body(com=com0)
|
|
74
|
+
builder.add_joint_ball(parent=b2, child=b3, parent_xform=tf0, child_xform=tf1)
|
|
75
|
+
builder.joint_q[-4:] = list(wp.quat_from_axis_angle(ax0, 0.7))
|
|
76
|
+
builder.joint_qd[-3:] = [1.0, -0.6, 1.5]
|
|
77
|
+
|
|
78
|
+
b4 = builder.add_body(com=com1)
|
|
79
|
+
builder.add_joint_compound(
|
|
80
|
+
parent=b3,
|
|
81
|
+
child=b4,
|
|
82
|
+
parent_xform=tf2,
|
|
83
|
+
child_xform=tf1,
|
|
84
|
+
axis_0=(0, 0, 1),
|
|
85
|
+
axis_1=(1, 0, 0),
|
|
86
|
+
axis_2=(0, 1, 0),
|
|
87
|
+
)
|
|
88
|
+
builder.joint_q[-3:] = [0.3, 0.5, 0.27]
|
|
89
|
+
builder.joint_qd[-3:] = [1.23, -1.0, 0.5]
|
|
90
|
+
|
|
91
|
+
b5 = builder.add_body(com=com2)
|
|
92
|
+
builder.add_joint_prismatic(
|
|
93
|
+
parent=b4,
|
|
94
|
+
child=b5,
|
|
95
|
+
parent_xform=tf2,
|
|
96
|
+
child_xform=tf0,
|
|
97
|
+
axis=ax0,
|
|
98
|
+
)
|
|
99
|
+
builder.joint_q[-1] = 0.92
|
|
100
|
+
builder.joint_qd[-1] = -0.63
|
|
101
|
+
|
|
102
|
+
b6 = builder.add_body(com=com0)
|
|
103
|
+
builder.add_joint_d6(
|
|
104
|
+
parent=b5,
|
|
105
|
+
child=b6,
|
|
106
|
+
parent_xform=tf0,
|
|
107
|
+
child_xform=tf2,
|
|
108
|
+
linear_axes=[ax0, ax1, wp.cross(ax0, ax1)],
|
|
109
|
+
angular_axes=[ax1, ax2, wp.cross(ax1, ax2)],
|
|
110
|
+
)
|
|
111
|
+
builder.joint_q[-6:] = [0.3, 0.5, 0.7, 0.9, 1.1, 1.3]
|
|
112
|
+
builder.joint_qd[-6:] = [1.0, -1.0, 0.5, 0.8, -0.3, 0.1]
|
|
113
|
+
|
|
114
|
+
b7 = builder.add_body(com=com1)
|
|
115
|
+
builder.add_joint_free(
|
|
116
|
+
parent=b6,
|
|
117
|
+
child=b7,
|
|
118
|
+
parent_xform=tf1,
|
|
119
|
+
child_xform=tf2,
|
|
120
|
+
)
|
|
121
|
+
builder.joint_q[-7:] = [0.5, -0.9, 1.4] + list(wp.quat_rpy(0.3, -0.5, 0.7))
|
|
122
|
+
builder.joint_qd[-6:] = [1.0, -1.0, 0.5, 0.8, -0.3, 0.1]
|
|
123
|
+
|
|
124
|
+
b8 = builder.add_body(com=com2)
|
|
125
|
+
builder.add_joint_distance(
|
|
126
|
+
parent=b7,
|
|
127
|
+
child=b8,
|
|
128
|
+
parent_xform=tf1,
|
|
129
|
+
child_xform=tf2,
|
|
130
|
+
)
|
|
131
|
+
builder.joint_q[-7:] = [-0.3, -0.7, 0.2] + list(wp.quat_rpy(0.1, 0.1, 0.4))
|
|
132
|
+
builder.joint_qd[-6:] = [-0.34, 0.5, -0.6, -0.4, 0.2, 0.1]
|
|
133
|
+
|
|
134
|
+
# D6 joint that behaves like a fixed joint
|
|
135
|
+
b9 = builder.add_body(com=com0)
|
|
136
|
+
builder.add_joint_d6(
|
|
137
|
+
parent=b8,
|
|
138
|
+
child=b9,
|
|
139
|
+
parent_xform=tf0,
|
|
140
|
+
child_xform=tf2,
|
|
141
|
+
linear_axes=[],
|
|
142
|
+
angular_axes=[],
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
b10 = builder.add_body(com=com0)
|
|
146
|
+
builder.add_joint_d6(
|
|
147
|
+
parent=b9,
|
|
148
|
+
child=b10,
|
|
149
|
+
parent_xform=tf1,
|
|
150
|
+
child_xform=tf2,
|
|
151
|
+
linear_axes=[ax1],
|
|
152
|
+
angular_axes=[ax2, ax0],
|
|
153
|
+
)
|
|
154
|
+
builder.joint_q[-3:] = [0.3, 0.5, 0.7]
|
|
155
|
+
builder.joint_qd[-3:] = [1.0, -1.0, 0.5]
|
|
156
|
+
|
|
157
|
+
b11 = builder.add_body(com=com1)
|
|
158
|
+
builder.add_joint_d6(
|
|
159
|
+
parent=b10,
|
|
160
|
+
child=b11,
|
|
161
|
+
parent_xform=tf1,
|
|
162
|
+
child_xform=tf2,
|
|
163
|
+
linear_axes=[ax1, ax0, wp.cross(ax1, ax0)],
|
|
164
|
+
angular_axes=[],
|
|
165
|
+
)
|
|
166
|
+
builder.joint_q[-3:] = [0.3, 0.5, 0.7]
|
|
167
|
+
builder.joint_qd[-3:] = [1.0, -1.0, 0.5]
|
|
168
|
+
|
|
169
|
+
b12 = builder.add_body(com=com2)
|
|
170
|
+
builder.add_joint_d6(
|
|
171
|
+
parent=b11,
|
|
172
|
+
child=b12,
|
|
173
|
+
parent_xform=tf1,
|
|
174
|
+
child_xform=tf2,
|
|
175
|
+
linear_axes=[],
|
|
176
|
+
angular_axes=[ax1, ax2, wp.cross(ax1, ax2)],
|
|
177
|
+
)
|
|
178
|
+
builder.joint_q[-3:] = [0.3, 0.5, 0.7]
|
|
179
|
+
builder.joint_qd[-3:] = [1.0, -1.0, 0.5]
|
|
180
|
+
|
|
181
|
+
parent = b12
|
|
182
|
+
|
|
183
|
+
return builder
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def check_fk_ik(builder, device):
|
|
187
|
+
model = builder.finalize(device)
|
|
188
|
+
state = model.state()
|
|
189
|
+
|
|
190
|
+
q_fk = model.joint_q.numpy()
|
|
191
|
+
qd_fk = model.joint_qd.numpy()
|
|
192
|
+
|
|
193
|
+
wp.sim.eval_fk(model, model.joint_q, model.joint_qd, None, state)
|
|
194
|
+
|
|
195
|
+
q_ik = wp.zeros_like(model.joint_q)
|
|
196
|
+
qd_ik = wp.zeros_like(model.joint_qd)
|
|
197
|
+
|
|
198
|
+
wp.sim.eval_ik(model, state, q_ik, qd_ik)
|
|
199
|
+
|
|
200
|
+
# adjust numpy print settings
|
|
201
|
+
# np.set_printoptions(precision=4, floatmode="fixed", suppress=True)
|
|
202
|
+
# print("q:")
|
|
203
|
+
# print(np.array(q_fk))
|
|
204
|
+
# print(q_ik.numpy())
|
|
205
|
+
|
|
206
|
+
# print("qd:")
|
|
207
|
+
# print(np.array(qd_fk))
|
|
208
|
+
# print(qd_ik.numpy())
|
|
209
|
+
|
|
210
|
+
assert_np_equal(q_ik.numpy(), q_fk, tol=1e-4)
|
|
211
|
+
assert_np_equal(qd_ik.numpy(), qd_fk, tol=1e-4)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def test_fk_ik_ant(test, device):
|
|
215
|
+
builder = build_ant(3)
|
|
216
|
+
check_fk_ik(builder, device)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def test_fk_ik_complex_joint_mechanism(test, device):
|
|
220
|
+
builder = build_complex_joint_mechanism(2)
|
|
221
|
+
check_fk_ik(builder, device)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
devices = get_test_devices()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class TestKinematics(unittest.TestCase):
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
add_function_test(TestKinematics, "test_fk_ik_ant", test_fk_ik_ant, devices=devices)
|
|
232
|
+
add_function_test(
|
|
233
|
+
TestKinematics, "test_fk_ik_complex_joint_mechanism", test_fk_ik_complex_joint_mechanism, devices=devices
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
if __name__ == "__main__":
|
|
238
|
+
wp.build.clear_kernel_cache()
|
|
239
|
+
unittest.main(verbosity=2, failfast=False)
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
"""Serial code-coverage runner
|
|
9
|
+
|
|
10
|
+
This script is used to generate code-coverage reports by running Warp tests.
|
|
11
|
+
It runs in serial so can take over an hour to finish. To generate a coverage
|
|
12
|
+
report in parallel, use the warp/thirdparty./unittest_parallel.py script
|
|
13
|
+
instead with the --coverage option, e.g. python -m warp.tests --coverage
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import coverage
|
|
17
|
+
|
|
18
|
+
cover = coverage.Coverage(config_file=True, messages=True)
|
|
19
|
+
|
|
20
|
+
cover.start()
|
|
21
|
+
|
|
22
|
+
with cover.collect():
|
|
23
|
+
import unittest_serial # noqa: E402
|
|
24
|
+
|
|
25
|
+
unittest_serial.run_specified()
|
|
26
|
+
|
|
27
|
+
cover.save()
|
|
28
|
+
|
|
29
|
+
cover.report()
|
|
30
|
+
|
|
31
|
+
cover.html_report(title="Warp Testing Code Coverage Report")
|
warp/tests/test_adam.py
CHANGED
|
@@ -5,16 +5,14 @@
|
|
|
5
5
|
# distribution of this software and related documentation without an express
|
|
6
6
|
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
import unittest
|
|
9
|
+
|
|
9
10
|
import numpy as np
|
|
10
|
-
import math
|
|
11
11
|
|
|
12
12
|
import warp as wp
|
|
13
|
-
from warp.tests.test_base import *
|
|
14
|
-
import unittest
|
|
15
|
-
|
|
16
13
|
import warp.optim
|
|
17
14
|
import warp.sim
|
|
15
|
+
from warp.tests.unittest_utils import *
|
|
18
16
|
|
|
19
17
|
wp.init()
|
|
20
18
|
|
|
@@ -28,32 +26,32 @@ def objective(params: wp.array(dtype=float), score: wp.array(dtype=float)):
|
|
|
28
26
|
|
|
29
27
|
# This test inspired by https://machinelearningmastery.com/adam-optimization-from-scratch/
|
|
30
28
|
def test_adam_solve_float(test, device):
|
|
31
|
-
wp.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
29
|
+
with wp.ScopedDevice(device):
|
|
30
|
+
params_start = np.array([0.1, 0.2], dtype=float)
|
|
31
|
+
score = wp.zeros(1, dtype=float, requires_grad=True)
|
|
32
|
+
params = wp.array(params_start, dtype=float, requires_grad=True)
|
|
33
|
+
tape = wp.Tape()
|
|
34
|
+
opt = warp.optim.Adam([params], lr=0.02, betas=(0.8, 0.999))
|
|
35
|
+
|
|
36
|
+
def gradient_func():
|
|
37
|
+
tape.reset()
|
|
38
|
+
score.zero_()
|
|
39
|
+
with tape:
|
|
40
|
+
wp.launch(kernel=objective, dim=len(params), inputs=[params, score])
|
|
41
|
+
tape.backward(score)
|
|
42
|
+
return [tape.gradients[params]]
|
|
43
|
+
|
|
44
|
+
niters = 100
|
|
45
|
+
|
|
46
|
+
opt.reset_internal_state()
|
|
47
|
+
for _ in range(niters):
|
|
48
|
+
opt.step(gradient_func())
|
|
49
|
+
|
|
50
|
+
result = params.numpy()
|
|
51
|
+
# optimum is at the origin, so the result should be close to it in all N dimensions.
|
|
52
|
+
tol = 1e-5
|
|
53
|
+
for r in result:
|
|
54
|
+
test.assertLessEqual(r, tol)
|
|
57
55
|
|
|
58
56
|
|
|
59
57
|
@wp.kernel
|
|
@@ -65,32 +63,32 @@ def objective_vec3(params: wp.array(dtype=wp.vec3), score: wp.array(dtype=float)
|
|
|
65
63
|
|
|
66
64
|
# This test inspired by https://machinelearningmastery.com/adam-optimization-from-scratch/
|
|
67
65
|
def test_adam_solve_vec3(test, device):
|
|
68
|
-
wp.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
66
|
+
with wp.ScopedDevice(device):
|
|
67
|
+
params_start = np.array([[0.1, 0.2, -0.1]], dtype=float)
|
|
68
|
+
score = wp.zeros(1, dtype=float, requires_grad=True)
|
|
69
|
+
params = wp.array(params_start, dtype=wp.vec3, requires_grad=True)
|
|
70
|
+
tape = wp.Tape()
|
|
71
|
+
opt = warp.optim.Adam([params], lr=0.02, betas=(0.8, 0.999))
|
|
72
|
+
|
|
73
|
+
def gradient_func():
|
|
74
|
+
tape.reset()
|
|
75
|
+
score.zero_()
|
|
76
|
+
with tape:
|
|
77
|
+
wp.launch(kernel=objective_vec3, dim=len(params), inputs=[params, score])
|
|
78
|
+
tape.backward(score)
|
|
79
|
+
return [tape.gradients[params]]
|
|
80
|
+
|
|
81
|
+
niters = 100
|
|
82
|
+
opt.reset_internal_state()
|
|
83
|
+
for _ in range(niters):
|
|
84
|
+
opt.step(gradient_func())
|
|
85
|
+
|
|
86
|
+
result = params.numpy()
|
|
87
|
+
tol = 1e-5
|
|
88
|
+
# optimum is at the origin, so the result should be close to it in all N dimensions.
|
|
89
|
+
for r in result:
|
|
90
|
+
for v in r:
|
|
91
|
+
test.assertLessEqual(v, tol)
|
|
94
92
|
|
|
95
93
|
|
|
96
94
|
@wp.kernel
|
|
@@ -105,56 +103,55 @@ def objective_two_inputs_vec3(
|
|
|
105
103
|
|
|
106
104
|
# This test inspired by https://machinelearningmastery.com/adam-optimization-from-scratch/
|
|
107
105
|
def test_adam_solve_two_inputs(test, device):
|
|
108
|
-
wp.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return TestArray
|
|
106
|
+
with wp.ScopedDevice(device):
|
|
107
|
+
params_start1 = np.array([[0.1, 0.2, -0.1]], dtype=float)
|
|
108
|
+
params_start2 = np.array([[0.2, 0.1, 0.1]], dtype=float)
|
|
109
|
+
score = wp.zeros(1, dtype=float, requires_grad=True)
|
|
110
|
+
params1 = wp.array(params_start1, dtype=wp.vec3, requires_grad=True)
|
|
111
|
+
params2 = wp.array(params_start2, dtype=wp.vec3, requires_grad=True)
|
|
112
|
+
tape = wp.Tape()
|
|
113
|
+
opt = warp.optim.Adam([params1, params2], lr=0.02, betas=(0.8, 0.999))
|
|
114
|
+
|
|
115
|
+
def gradient_func():
|
|
116
|
+
tape.reset()
|
|
117
|
+
score.zero_()
|
|
118
|
+
with tape:
|
|
119
|
+
wp.launch(kernel=objective_two_inputs_vec3, dim=len(params1), inputs=[params1, params2, score])
|
|
120
|
+
tape.backward(score)
|
|
121
|
+
return [tape.gradients[params1], tape.gradients[params2]]
|
|
122
|
+
|
|
123
|
+
niters = 100
|
|
124
|
+
opt.reset_internal_state()
|
|
125
|
+
for _ in range(niters):
|
|
126
|
+
opt.step(gradient_func())
|
|
127
|
+
|
|
128
|
+
result = params1.numpy()
|
|
129
|
+
tol = 1e-5
|
|
130
|
+
# optimum is at the origin, so the result should be close to it in all N dimensions.
|
|
131
|
+
for r in result:
|
|
132
|
+
for v in r:
|
|
133
|
+
test.assertLessEqual(v, tol)
|
|
134
|
+
|
|
135
|
+
result = params2.numpy()
|
|
136
|
+
tol = 1e-5
|
|
137
|
+
# optimum is at the origin, so the result should be close to it in all N dimensions.
|
|
138
|
+
for r in result:
|
|
139
|
+
for v in r:
|
|
140
|
+
test.assertLessEqual(v, tol)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
devices = get_test_devices()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class TestAdam(unittest.TestCase):
|
|
147
|
+
pass
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
add_function_test(TestAdam, "test_adam_solve_float", test_adam_solve_float, devices=devices)
|
|
151
|
+
add_function_test(TestAdam, "test_adam_solve_vec3", test_adam_solve_vec3, devices=devices)
|
|
152
|
+
add_function_test(TestAdam, "test_adam_solve_two_inputs", test_adam_solve_two_inputs, devices=devices)
|
|
156
153
|
|
|
157
154
|
|
|
158
155
|
if __name__ == "__main__":
|
|
159
|
-
|
|
156
|
+
wp.build.clear_kernel_cache()
|
|
160
157
|
unittest.main(verbosity=2)
|