warp-lang 1.0.0b5__py3-none-manylinux2014_x86_64.whl → 1.0.0b6__py3-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docs/conf.py +3 -4
- examples/env/env_ant.py +1 -1
- examples/env/env_cartpole.py +1 -1
- examples/env/env_humanoid.py +1 -1
- examples/example_dem.py +28 -26
- examples/example_diffray.py +37 -30
- examples/example_fluid.py +7 -3
- examples/example_jacobian_ik.py +1 -1
- examples/example_mesh_intersect.py +10 -7
- examples/example_nvdb.py +3 -3
- examples/example_render_opengl.py +19 -10
- examples/example_sim_cartpole.py +9 -5
- examples/example_sim_cloth.py +29 -25
- examples/example_sim_fk_grad.py +2 -2
- examples/example_sim_fk_grad_torch.py +3 -3
- examples/example_sim_grad_bounce.py +11 -8
- examples/example_sim_grad_cloth.py +12 -9
- examples/example_sim_granular.py +2 -2
- examples/example_sim_granular_collision_sdf.py +13 -13
- examples/example_sim_neo_hookean.py +3 -3
- examples/example_sim_particle_chain.py +2 -2
- examples/example_sim_quadruped.py +8 -5
- examples/example_sim_rigid_chain.py +8 -5
- examples/example_sim_rigid_contact.py +13 -10
- examples/example_sim_rigid_fem.py +2 -2
- examples/example_sim_rigid_gyroscopic.py +2 -2
- examples/example_sim_rigid_kinematics.py +1 -1
- examples/example_sim_trajopt.py +3 -2
- examples/fem/example_apic_fluid.py +5 -7
- examples/fem/example_diffusion_mgpu.py +18 -16
- warp/__init__.py +3 -2
- warp/bin/warp.so +0 -0
- warp/build_dll.py +29 -9
- warp/builtins.py +206 -7
- warp/codegen.py +58 -38
- warp/config.py +3 -1
- warp/context.py +234 -128
- warp/fem/__init__.py +2 -2
- warp/fem/cache.py +2 -1
- warp/fem/field/nodal_field.py +18 -17
- warp/fem/geometry/hexmesh.py +11 -6
- warp/fem/geometry/quadmesh_2d.py +16 -12
- warp/fem/geometry/tetmesh.py +19 -8
- warp/fem/geometry/trimesh_2d.py +18 -7
- warp/fem/integrate.py +341 -196
- warp/fem/quadrature/__init__.py +1 -1
- warp/fem/quadrature/pic_quadrature.py +138 -53
- warp/fem/quadrature/quadrature.py +81 -9
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/basis_space.py +169 -51
- warp/fem/space/grid_2d_function_space.py +2 -2
- warp/fem/space/grid_3d_function_space.py +2 -2
- warp/fem/space/hexmesh_function_space.py +2 -2
- warp/fem/space/partition.py +9 -6
- warp/fem/space/quadmesh_2d_function_space.py +2 -2
- warp/fem/space/shape/cube_shape_function.py +27 -15
- warp/fem/space/shape/square_shape_function.py +29 -18
- warp/fem/space/tetmesh_function_space.py +2 -2
- warp/fem/space/topology.py +10 -0
- warp/fem/space/trimesh_2d_function_space.py +2 -2
- warp/fem/utils.py +10 -5
- warp/native/array.h +49 -8
- warp/native/builtin.h +31 -14
- warp/native/cuda_util.cpp +8 -3
- warp/native/cuda_util.h +1 -0
- warp/native/exports.h +1177 -1108
- warp/native/intersect.h +4 -4
- warp/native/intersect_adj.h +8 -8
- warp/native/mat.h +65 -6
- warp/native/mesh.h +126 -5
- warp/native/quat.h +28 -4
- warp/native/vec.h +76 -14
- warp/native/warp.cu +1 -6
- warp/render/render_opengl.py +261 -109
- warp/sim/import_mjcf.py +13 -7
- warp/sim/import_urdf.py +14 -14
- warp/sim/inertia.py +17 -18
- warp/sim/model.py +67 -67
- warp/sim/render.py +1 -1
- warp/sparse.py +6 -6
- warp/stubs.py +19 -81
- warp/tape.py +1 -1
- warp/tests/__main__.py +3 -6
- 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/{test_kinematics.py → disabled_kinematics.py} +10 -12
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +102 -106
- warp/tests/test_arithmetic.py +39 -40
- warp/tests/test_array.py +46 -48
- warp/tests/test_array_reduce.py +25 -19
- warp/tests/test_atomic.py +62 -26
- warp/tests/test_bool.py +16 -11
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +9 -12
- warp/tests/test_closest_point_edge_edge.py +53 -57
- warp/tests/test_codegen.py +164 -134
- warp/tests/test_compile_consts.py +13 -19
- warp/tests/test_conditional.py +30 -32
- warp/tests/test_copy.py +9 -12
- warp/tests/test_ctypes.py +90 -98
- warp/tests/test_dense.py +20 -14
- warp/tests/test_devices.py +34 -35
- warp/tests/test_dlpack.py +74 -75
- warp/tests/test_examples.py +215 -97
- warp/tests/test_fabricarray.py +15 -21
- warp/tests/test_fast_math.py +14 -11
- warp/tests/test_fem.py +280 -97
- warp/tests/test_fp16.py +19 -15
- warp/tests/test_func.py +177 -194
- warp/tests/test_generics.py +71 -77
- warp/tests/test_grad.py +83 -32
- warp/tests/test_grad_customs.py +7 -9
- warp/tests/test_hash_grid.py +6 -10
- warp/tests/test_import.py +9 -23
- warp/tests/test_indexedarray.py +19 -21
- warp/tests/test_intersect.py +15 -9
- warp/tests/test_large.py +17 -19
- warp/tests/test_launch.py +14 -17
- warp/tests/test_lerp.py +63 -63
- warp/tests/test_lvalue.py +84 -35
- warp/tests/test_marching_cubes.py +9 -13
- warp/tests/test_mat.py +388 -3004
- warp/tests/test_mat_lite.py +9 -12
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +10 -11
- warp/tests/test_matmul.py +104 -100
- warp/tests/test_matmul_lite.py +72 -98
- warp/tests/test_mesh.py +35 -32
- warp/tests/test_mesh_query_aabb.py +18 -25
- warp/tests/test_mesh_query_point.py +39 -23
- warp/tests/test_mesh_query_ray.py +9 -21
- warp/tests/test_mlp.py +8 -9
- warp/tests/test_model.py +89 -93
- warp/tests/test_modules_lite.py +15 -25
- warp/tests/test_multigpu.py +87 -114
- warp/tests/test_noise.py +10 -12
- warp/tests/test_operators.py +14 -21
- warp/tests/test_options.py +10 -11
- warp/tests/test_pinned.py +16 -18
- warp/tests/test_print.py +16 -20
- warp/tests/test_quat.py +121 -88
- warp/tests/test_rand.py +12 -13
- warp/tests/test_reload.py +27 -32
- warp/tests/test_rounding.py +7 -10
- warp/tests/test_runlength_encode.py +105 -106
- warp/tests/test_smoothstep.py +8 -9
- warp/tests/test_snippet.py +13 -22
- warp/tests/test_sparse.py +30 -29
- warp/tests/test_spatial.py +179 -174
- warp/tests/test_streams.py +100 -107
- warp/tests/test_struct.py +98 -67
- warp/tests/test_tape.py +11 -17
- warp/tests/test_torch.py +89 -86
- warp/tests/test_transient_module.py +9 -12
- warp/tests/test_types.py +328 -50
- warp/tests/test_utils.py +217 -218
- warp/tests/test_vec.py +133 -2133
- warp/tests/test_vec_lite.py +8 -11
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +391 -382
- warp/tests/test_volume_write.py +122 -135
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +291 -0
- warp/tests/{test_base.py → unittest_utils.py} +138 -25
- warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
- warp/tests/{test_debug.py → walkthough_debug.py} +2 -15
- warp/thirdparty/unittest_parallel.py +257 -54
- warp/types.py +119 -98
- warp/utils.py +14 -0
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/METADATA +2 -1
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/RECORD +182 -178
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
- warp/tests/test_all.py +0 -239
- warp/tests/test_conditional_unequal_types_kernels.py +0 -14
- warp/tests/test_coverage.py +0 -38
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- /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.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
warp/tests/test_utils.py
CHANGED
|
@@ -6,36 +6,15 @@
|
|
|
6
6
|
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
7
|
|
|
8
8
|
import contextlib
|
|
9
|
-
import io
|
|
10
9
|
import inspect
|
|
10
|
+
import io
|
|
11
11
|
import unittest
|
|
12
12
|
|
|
13
|
-
from warp.tests.
|
|
14
|
-
|
|
13
|
+
from warp.tests.unittest_utils import *
|
|
15
14
|
|
|
16
15
|
wp.init()
|
|
17
16
|
|
|
18
17
|
|
|
19
|
-
def test_warn(test, device):
|
|
20
|
-
with contextlib.redirect_stdout(io.StringIO()) as f:
|
|
21
|
-
frame_info = inspect.getframeinfo(inspect.currentframe())
|
|
22
|
-
wp.utils.warn("hello, world!")
|
|
23
|
-
|
|
24
|
-
expected = '{}:{}: UserWarning: hello, world!\n wp.utils.warn("hello, world!")\n'.format(
|
|
25
|
-
frame_info.filename,
|
|
26
|
-
frame_info.lineno + 1,
|
|
27
|
-
)
|
|
28
|
-
test.assertEqual(f.getvalue(), expected)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def test_transform_expand(test, device):
|
|
32
|
-
t = (1.0, 2.0, 3.0, 4.0, 3.0, 2.0, 1.0)
|
|
33
|
-
test.assertEqual(
|
|
34
|
-
wp.utils.transform_expand(t),
|
|
35
|
-
wp.transformf(p=(1.0, 2.0, 3.0), q=(4.0, 3.0, 2.0, 1.0)),
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
|
|
39
18
|
def test_array_scan(test, device):
|
|
40
19
|
rng = np.random.default_rng(123)
|
|
41
20
|
|
|
@@ -71,19 +50,9 @@ def test_array_scan_empty(test, device):
|
|
|
71
50
|
wp.utils.array_scan(values, result)
|
|
72
51
|
|
|
73
52
|
|
|
74
|
-
def test_array_scan_error_devices_mismatch(test, device):
|
|
75
|
-
values = wp.zeros(123, dtype=int, device="cpu")
|
|
76
|
-
result = wp.zeros_like(values, device="cuda:0")
|
|
77
|
-
with test.assertRaisesRegex(
|
|
78
|
-
RuntimeError,
|
|
79
|
-
r"Array storage devices do not match$",
|
|
80
|
-
):
|
|
81
|
-
wp.utils.array_scan(values, result, True)
|
|
82
|
-
|
|
83
|
-
|
|
84
53
|
def test_array_scan_error_sizes_mismatch(test, device):
|
|
85
|
-
values = wp.zeros(123, dtype=int, device=
|
|
86
|
-
result = wp.zeros(234, dtype=int, device=
|
|
54
|
+
values = wp.zeros(123, dtype=int, device=device)
|
|
55
|
+
result = wp.zeros(234, dtype=int, device=device)
|
|
87
56
|
with test.assertRaisesRegex(
|
|
88
57
|
RuntimeError,
|
|
89
58
|
r"Array storage sizes do not match$",
|
|
@@ -92,8 +61,8 @@ def test_array_scan_error_sizes_mismatch(test, device):
|
|
|
92
61
|
|
|
93
62
|
|
|
94
63
|
def test_array_scan_error_dtypes_mismatch(test, device):
|
|
95
|
-
values = wp.zeros(123, dtype=int, device=
|
|
96
|
-
result = wp.zeros(123, dtype=float, device=
|
|
64
|
+
values = wp.zeros(123, dtype=int, device=device)
|
|
65
|
+
result = wp.zeros(123, dtype=float, device=device)
|
|
97
66
|
with test.assertRaisesRegex(
|
|
98
67
|
RuntimeError,
|
|
99
68
|
r"Array data types do not match$",
|
|
@@ -125,19 +94,9 @@ def test_radix_sort_pairs_empty(test, device):
|
|
|
125
94
|
wp.utils.radix_sort_pairs(keys, values, 0)
|
|
126
95
|
|
|
127
96
|
|
|
128
|
-
def test_radix_sort_pairs_error_devices_mismatch(test, device):
|
|
129
|
-
keys = wp.array((1, 2, 3), dtype=int, device="cpu")
|
|
130
|
-
values = wp.array((1, 2, 3), dtype=int, device="cuda:0")
|
|
131
|
-
with test.assertRaisesRegex(
|
|
132
|
-
RuntimeError,
|
|
133
|
-
r"Array storage devices do not match$",
|
|
134
|
-
):
|
|
135
|
-
wp.utils.radix_sort_pairs(keys, values, 1)
|
|
136
|
-
|
|
137
|
-
|
|
138
97
|
def test_radix_sort_pairs_error_insufficient_storage(test, device):
|
|
139
|
-
keys = wp.array((1, 2, 3), dtype=int, device=
|
|
140
|
-
values = wp.array((1, 2, 3), dtype=int, device=
|
|
98
|
+
keys = wp.array((1, 2, 3), dtype=int, device=device)
|
|
99
|
+
values = wp.array((1, 2, 3), dtype=int, device=device)
|
|
141
100
|
with test.assertRaisesRegex(
|
|
142
101
|
RuntimeError,
|
|
143
102
|
r"Array storage must be large enough to contain 2\*count elements$",
|
|
@@ -157,28 +116,19 @@ def test_radix_sort_pairs_error_unsupported_dtype(test, device):
|
|
|
157
116
|
|
|
158
117
|
def test_array_sum(test, device):
|
|
159
118
|
for dtype in (wp.float32, wp.float64):
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
values = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
|
|
164
|
-
result = wp.empty(shape=(1,), dtype=dtype, device=device)
|
|
165
|
-
wp.utils.array_sum(values, out=result)
|
|
166
|
-
test.assertEqual(result.numpy()[0], 6.0)
|
|
167
|
-
|
|
119
|
+
with test.subTest(dtype=dtype):
|
|
120
|
+
values = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
|
|
121
|
+
test.assertEqual(wp.utils.array_sum(values), 6.0)
|
|
168
122
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
RuntimeError,
|
|
174
|
-
r"out storage device should match values array$",
|
|
175
|
-
):
|
|
176
|
-
wp.utils.array_sum(values, out=result)
|
|
123
|
+
values = wp.array((1.0, 2.0, 3.0), dtype=dtype, device=device)
|
|
124
|
+
result = wp.empty(shape=(1,), dtype=dtype, device=device)
|
|
125
|
+
wp.utils.array_sum(values, out=result)
|
|
126
|
+
test.assertEqual(result.numpy()[0], 6.0)
|
|
177
127
|
|
|
178
128
|
|
|
179
129
|
def test_array_sum_error_out_dtype_mismatch(test, device):
|
|
180
|
-
values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
181
|
-
result = wp.empty(shape=(1,), dtype=wp.float64, device=
|
|
130
|
+
values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
131
|
+
result = wp.empty(shape=(1,), dtype=wp.float64, device=device)
|
|
182
132
|
with test.assertRaisesRegex(
|
|
183
133
|
RuntimeError,
|
|
184
134
|
r"out array should have type float32$",
|
|
@@ -187,8 +137,8 @@ def test_array_sum_error_out_dtype_mismatch(test, device):
|
|
|
187
137
|
|
|
188
138
|
|
|
189
139
|
def test_array_sum_error_out_shape_mismatch(test, device):
|
|
190
|
-
values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
191
|
-
result = wp.empty(shape=(2,), dtype=wp.float32, device=
|
|
140
|
+
values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
141
|
+
result = wp.empty(shape=(2,), dtype=wp.float32, device=device)
|
|
192
142
|
with test.assertRaisesRegex(
|
|
193
143
|
RuntimeError,
|
|
194
144
|
r"out array should have shape \(1,\)$",
|
|
@@ -219,8 +169,8 @@ def test_array_inner(test, device):
|
|
|
219
169
|
|
|
220
170
|
|
|
221
171
|
def test_array_inner_error_sizes_mismatch(test, device):
|
|
222
|
-
a = wp.array((1.0, 2.0), dtype=wp.float32, device=
|
|
223
|
-
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
172
|
+
a = wp.array((1.0, 2.0), dtype=wp.float32, device=device)
|
|
173
|
+
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
224
174
|
with test.assertRaisesRegex(
|
|
225
175
|
RuntimeError,
|
|
226
176
|
r"Array storage sizes do not match$",
|
|
@@ -228,19 +178,9 @@ def test_array_inner_error_sizes_mismatch(test, device):
|
|
|
228
178
|
wp.utils.array_inner(a, b)
|
|
229
179
|
|
|
230
180
|
|
|
231
|
-
def test_array_inner_error_devices_mismatch(test, device):
|
|
232
|
-
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
233
|
-
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cuda:0")
|
|
234
|
-
with test.assertRaisesRegex(
|
|
235
|
-
RuntimeError,
|
|
236
|
-
r"Array storage devices do not match$",
|
|
237
|
-
):
|
|
238
|
-
wp.utils.array_inner(a, b)
|
|
239
|
-
|
|
240
|
-
|
|
241
181
|
def test_array_inner_error_dtypes_mismatch(test, device):
|
|
242
|
-
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
243
|
-
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float64, device=
|
|
182
|
+
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
183
|
+
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float64, device=device)
|
|
244
184
|
with test.assertRaisesRegex(
|
|
245
185
|
RuntimeError,
|
|
246
186
|
r"Array data types do not match$",
|
|
@@ -248,21 +188,10 @@ def test_array_inner_error_dtypes_mismatch(test, device):
|
|
|
248
188
|
wp.utils.array_inner(a, b)
|
|
249
189
|
|
|
250
190
|
|
|
251
|
-
def test_array_inner_error_out_device_mismatch(test, device):
|
|
252
|
-
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
253
|
-
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
254
|
-
result = wp.empty(shape=(1,), dtype=wp.float32, device="cuda:0")
|
|
255
|
-
with test.assertRaisesRegex(
|
|
256
|
-
RuntimeError,
|
|
257
|
-
r"out storage device should match values array$",
|
|
258
|
-
):
|
|
259
|
-
wp.utils.array_inner(a, b, result)
|
|
260
|
-
|
|
261
|
-
|
|
262
191
|
def test_array_inner_error_out_dtype_mismatch(test, device):
|
|
263
|
-
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
264
|
-
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
265
|
-
result = wp.empty(shape=(1,), dtype=wp.float64, device=
|
|
192
|
+
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
193
|
+
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
194
|
+
result = wp.empty(shape=(1,), dtype=wp.float64, device=device)
|
|
266
195
|
with test.assertRaisesRegex(
|
|
267
196
|
RuntimeError,
|
|
268
197
|
r"out array should have type float32$",
|
|
@@ -271,9 +200,9 @@ def test_array_inner_error_out_dtype_mismatch(test, device):
|
|
|
271
200
|
|
|
272
201
|
|
|
273
202
|
def test_array_inner_error_out_shape_mismatch(test, device):
|
|
274
|
-
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
275
|
-
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=
|
|
276
|
-
result = wp.empty(shape=(2,), dtype=wp.float32, device=
|
|
203
|
+
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
204
|
+
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device=device)
|
|
205
|
+
result = wp.empty(shape=(2,), dtype=wp.float32, device=device)
|
|
277
206
|
with test.assertRaisesRegex(
|
|
278
207
|
RuntimeError,
|
|
279
208
|
r"out array should have shape \(1,\)$",
|
|
@@ -313,27 +242,17 @@ def test_array_cast(test, device):
|
|
|
313
242
|
test.assertEqual(result.shape, (2,))
|
|
314
243
|
assert_np_equal(result.numpy(), np.array((1.0, 2.0), dtype=float))
|
|
315
244
|
|
|
316
|
-
values = wp.array(((1, 2), (3, 4)), dtype=int, device=
|
|
317
|
-
result = wp.zeros((2, 2), dtype=int, device=
|
|
245
|
+
values = wp.array(((1, 2), (3, 4)), dtype=int, device=device)
|
|
246
|
+
result = wp.zeros((2, 2), dtype=int, device=device)
|
|
318
247
|
wp.utils.array_cast(values, result)
|
|
319
248
|
test.assertEqual(result.dtype, wp.int32)
|
|
320
249
|
test.assertEqual(result.shape, (2, 2))
|
|
321
250
|
assert_np_equal(result.numpy(), np.array(((1, 2), (3, 4)), dtype=int))
|
|
322
251
|
|
|
323
252
|
|
|
324
|
-
def test_array_cast_error_devices_mismatch(test, device):
|
|
325
|
-
values = wp.array((1, 2, 3), dtype=int, device="cpu")
|
|
326
|
-
result = wp.empty(3, dtype=float, device="cuda:0")
|
|
327
|
-
with test.assertRaisesRegex(
|
|
328
|
-
RuntimeError,
|
|
329
|
-
r"Array storage devices do not match$",
|
|
330
|
-
):
|
|
331
|
-
wp.utils.array_cast(values, result)
|
|
332
|
-
|
|
333
|
-
|
|
334
253
|
def test_array_cast_error_unsupported_partial_cast(test, device):
|
|
335
|
-
values = wp.array(((1, 2), (3, 4)), dtype=int, device=
|
|
336
|
-
result = wp.zeros((2, 2), dtype=float, device=
|
|
254
|
+
values = wp.array(((1, 2), (3, 4)), dtype=int, device=device)
|
|
255
|
+
result = wp.zeros((2, 2), dtype=float, device=device)
|
|
337
256
|
with test.assertRaisesRegex(
|
|
338
257
|
RuntimeError,
|
|
339
258
|
r"Partial cast is not supported for arrays with more than one dimension$",
|
|
@@ -341,112 +260,192 @@ def test_array_cast_error_unsupported_partial_cast(test, device):
|
|
|
341
260
|
wp.utils.array_cast(values, result, count=1)
|
|
342
261
|
|
|
343
262
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
wp.
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
)
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
263
|
+
devices = get_test_devices()
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class TestUtils(unittest.TestCase):
|
|
267
|
+
def test_warn(self):
|
|
268
|
+
with contextlib.redirect_stdout(io.StringIO()) as f:
|
|
269
|
+
frame_info = inspect.getframeinfo(inspect.currentframe())
|
|
270
|
+
wp.utils.warn("hello, world!")
|
|
271
|
+
|
|
272
|
+
expected = '{}:{}: UserWarning: hello, world!\n wp.utils.warn("hello, world!")\n'.format(
|
|
273
|
+
frame_info.filename,
|
|
274
|
+
frame_info.lineno + 1,
|
|
275
|
+
)
|
|
276
|
+
self.assertEqual(f.getvalue(), expected)
|
|
277
|
+
|
|
278
|
+
def test_transform_expand(self):
|
|
279
|
+
t = (1.0, 2.0, 3.0, 4.0, 3.0, 2.0, 1.0)
|
|
280
|
+
self.assertEqual(
|
|
281
|
+
wp.utils.transform_expand(t),
|
|
282
|
+
wp.transformf(p=(1.0, 2.0, 3.0), q=(4.0, 3.0, 2.0, 1.0)),
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
286
|
+
def test_array_scan_error_devices_mismatch(self):
|
|
287
|
+
values = wp.zeros(123, dtype=int, device="cpu")
|
|
288
|
+
result = wp.zeros_like(values, device="cuda:0")
|
|
289
|
+
with self.assertRaisesRegex(
|
|
290
|
+
RuntimeError,
|
|
291
|
+
r"Array storage devices do not match$",
|
|
292
|
+
):
|
|
293
|
+
wp.utils.array_scan(values, result, True)
|
|
294
|
+
|
|
295
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
296
|
+
def test_radix_sort_pairs_error_devices_mismatch(self):
|
|
297
|
+
keys = wp.array((1, 2, 3), dtype=int, device="cpu")
|
|
298
|
+
values = wp.array((1, 2, 3), dtype=int, device="cuda:0")
|
|
299
|
+
with self.assertRaisesRegex(
|
|
300
|
+
RuntimeError,
|
|
301
|
+
r"Array storage devices do not match$",
|
|
302
|
+
):
|
|
303
|
+
wp.utils.radix_sort_pairs(keys, values, 1)
|
|
304
|
+
|
|
305
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
306
|
+
def test_array_inner_error_out_device_mismatch(self):
|
|
307
|
+
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
308
|
+
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
309
|
+
result = wp.empty(shape=(1,), dtype=wp.float32, device="cuda:0")
|
|
310
|
+
with self.assertRaisesRegex(
|
|
311
|
+
RuntimeError,
|
|
312
|
+
r"out storage device should match values array$",
|
|
313
|
+
):
|
|
314
|
+
wp.utils.array_inner(a, b, result)
|
|
315
|
+
|
|
316
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
317
|
+
def test_array_sum_error_out_device_mismatch(self):
|
|
318
|
+
values = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
319
|
+
result = wp.empty(shape=(1,), dtype=wp.float32, device="cuda:0")
|
|
320
|
+
with self.assertRaisesRegex(
|
|
321
|
+
RuntimeError,
|
|
322
|
+
r"out storage device should match values array$",
|
|
323
|
+
):
|
|
324
|
+
wp.utils.array_sum(values, out=result)
|
|
325
|
+
|
|
326
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
327
|
+
def test_array_inner_error_devices_mismatch(self):
|
|
328
|
+
a = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cpu")
|
|
329
|
+
b = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, device="cuda:0")
|
|
330
|
+
with self.assertRaisesRegex(
|
|
331
|
+
RuntimeError,
|
|
332
|
+
r"Array storage devices do not match$",
|
|
333
|
+
):
|
|
334
|
+
wp.utils.array_inner(a, b)
|
|
335
|
+
|
|
336
|
+
@unittest.skipUnless(wp.is_cuda_available(), "Requires CUDA")
|
|
337
|
+
def test_array_cast_error_devices_mismatch(self):
|
|
338
|
+
values = wp.array((1, 2, 3), dtype=int, device="cpu")
|
|
339
|
+
result = wp.empty(3, dtype=float, device="cuda:0")
|
|
340
|
+
with self.assertRaisesRegex(
|
|
341
|
+
RuntimeError,
|
|
342
|
+
r"Array storage devices do not match$",
|
|
343
|
+
):
|
|
344
|
+
wp.utils.array_cast(values, result)
|
|
345
|
+
|
|
346
|
+
def test_mesh_adjacency(self):
|
|
347
|
+
triangles = (
|
|
348
|
+
(0, 3, 1),
|
|
349
|
+
(0, 2, 3),
|
|
350
|
+
)
|
|
351
|
+
adj = wp.utils.MeshAdjacency(triangles, len(triangles))
|
|
352
|
+
expected_edges = {
|
|
353
|
+
(0, 3): (0, 3, 1, 2, 0, 1),
|
|
354
|
+
(1, 3): (3, 1, 0, -1, 0, -1),
|
|
355
|
+
(0, 1): (1, 0, 3, -1, 0, -1),
|
|
356
|
+
(0, 2): (0, 2, 3, -1, 1, -1),
|
|
357
|
+
(2, 3): (2, 3, 0, -1, 1, -1),
|
|
358
|
+
}
|
|
359
|
+
edges = {k: (e.v0, e.v1, e.o0, e.o1, e.f0, e.f1) for k, e in adj.edges.items()}
|
|
360
|
+
self.assertDictEqual(edges, expected_edges)
|
|
361
|
+
|
|
362
|
+
def test_mesh_adjacency_error_manifold(self):
|
|
363
|
+
triangles = (
|
|
364
|
+
(0, 3, 1),
|
|
365
|
+
(0, 2, 3),
|
|
366
|
+
(3, 0, 1),
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
with contextlib.redirect_stdout(io.StringIO()) as f:
|
|
370
|
+
wp.utils.MeshAdjacency(triangles, len(triangles))
|
|
371
|
+
|
|
372
|
+
self.assertEqual(f.getvalue(), "Detected non-manifold edge\n")
|
|
373
|
+
|
|
374
|
+
def test_scoped_timer(self):
|
|
375
|
+
with contextlib.redirect_stdout(io.StringIO()) as f:
|
|
376
|
+
with wp.ScopedTimer("hello"):
|
|
377
|
+
pass
|
|
378
|
+
|
|
379
|
+
self.assertRegex(f.getvalue(), r"^hello took \d+\.\d+ ms$")
|
|
380
|
+
|
|
381
|
+
with contextlib.redirect_stdout(io.StringIO()) as f:
|
|
382
|
+
with wp.ScopedTimer("hello", detailed=True):
|
|
383
|
+
pass
|
|
384
|
+
|
|
385
|
+
self.assertRegex(f.getvalue(), r"^ 2 function calls in \d+\.\d+ seconds")
|
|
386
|
+
self.assertRegex(f.getvalue(), r"hello took \d+\.\d+ ms$")
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
add_function_test(TestUtils, "test_array_scan", test_array_scan, devices=devices)
|
|
390
|
+
add_function_test(TestUtils, "test_array_scan_empty", test_array_scan_empty, devices=devices)
|
|
391
|
+
add_function_test(
|
|
392
|
+
TestUtils, "test_array_scan_error_sizes_mismatch", test_array_scan_error_sizes_mismatch, devices=devices
|
|
393
|
+
)
|
|
394
|
+
add_function_test(
|
|
395
|
+
TestUtils, "test_array_scan_error_dtypes_mismatch", test_array_scan_error_dtypes_mismatch, devices=devices
|
|
396
|
+
)
|
|
397
|
+
add_function_test(
|
|
398
|
+
TestUtils, "test_array_scan_error_unsupported_dtype", test_array_scan_error_unsupported_dtype, devices=devices
|
|
399
|
+
)
|
|
400
|
+
add_function_test(TestUtils, "test_radix_sort_pairs", test_radix_sort_pairs, devices=devices)
|
|
401
|
+
add_function_test(TestUtils, "test_radix_sort_pairs_empty", test_radix_sort_pairs, devices=devices)
|
|
402
|
+
add_function_test(
|
|
403
|
+
TestUtils,
|
|
404
|
+
"test_radix_sort_pairs_error_insufficient_storage",
|
|
405
|
+
test_radix_sort_pairs_error_insufficient_storage,
|
|
406
|
+
devices=devices,
|
|
407
|
+
)
|
|
408
|
+
add_function_test(
|
|
409
|
+
TestUtils,
|
|
410
|
+
"test_radix_sort_pairs_error_unsupported_dtype",
|
|
411
|
+
test_radix_sort_pairs_error_unsupported_dtype,
|
|
412
|
+
devices=devices,
|
|
413
|
+
)
|
|
414
|
+
add_function_test(TestUtils, "test_array_sum", test_array_sum, devices=devices)
|
|
415
|
+
add_function_test(
|
|
416
|
+
TestUtils, "test_array_sum_error_out_dtype_mismatch", test_array_sum_error_out_dtype_mismatch, devices=devices
|
|
417
|
+
)
|
|
418
|
+
add_function_test(
|
|
419
|
+
TestUtils, "test_array_sum_error_out_shape_mismatch", test_array_sum_error_out_shape_mismatch, devices=devices
|
|
420
|
+
)
|
|
421
|
+
add_function_test(
|
|
422
|
+
TestUtils, "test_array_sum_error_unsupported_dtype", test_array_sum_error_unsupported_dtype, devices=devices
|
|
423
|
+
)
|
|
424
|
+
add_function_test(TestUtils, "test_array_inner", test_array_inner, devices=devices)
|
|
425
|
+
add_function_test(
|
|
426
|
+
TestUtils, "test_array_inner_error_sizes_mismatch", test_array_inner_error_sizes_mismatch, devices=devices
|
|
427
|
+
)
|
|
428
|
+
add_function_test(
|
|
429
|
+
TestUtils, "test_array_inner_error_dtypes_mismatch", test_array_inner_error_dtypes_mismatch, devices=devices
|
|
430
|
+
)
|
|
431
|
+
add_function_test(
|
|
432
|
+
TestUtils, "test_array_inner_error_out_dtype_mismatch", test_array_inner_error_out_dtype_mismatch, devices=devices
|
|
433
|
+
)
|
|
434
|
+
add_function_test(
|
|
435
|
+
TestUtils, "test_array_inner_error_out_shape_mismatch", test_array_inner_error_out_shape_mismatch, devices=devices
|
|
436
|
+
)
|
|
437
|
+
add_function_test(
|
|
438
|
+
TestUtils, "test_array_inner_error_unsupported_dtype", test_array_inner_error_unsupported_dtype, devices=devices
|
|
439
|
+
)
|
|
440
|
+
add_function_test(TestUtils, "test_array_cast", test_array_cast, devices=devices)
|
|
441
|
+
add_function_test(
|
|
442
|
+
TestUtils,
|
|
443
|
+
"test_array_cast_error_unsupported_partial_cast",
|
|
444
|
+
test_array_cast_error_unsupported_partial_cast,
|
|
445
|
+
devices=devices,
|
|
446
|
+
)
|
|
447
447
|
|
|
448
448
|
|
|
449
449
|
if __name__ == "__main__":
|
|
450
450
|
wp.build.clear_kernel_cache()
|
|
451
|
-
_ = register(unittest.TestCase)
|
|
452
451
|
unittest.main(verbosity=2)
|