warp-lang 1.8.1__py3-none-macosx_10_13_universal2.whl → 1.9.1__py3-none-macosx_10_13_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +282 -103
- warp/__init__.pyi +1904 -114
- warp/bin/libwarp-clang.dylib +0 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +93 -30
- warp/build_dll.py +331 -101
- warp/builtins.py +1244 -160
- warp/codegen.py +317 -206
- warp/config.py +1 -1
- warp/context.py +1465 -789
- warp/examples/core/example_marching_cubes.py +1 -0
- warp/examples/core/example_render_opengl.py +100 -3
- warp/examples/fem/example_apic_fluid.py +98 -52
- warp/examples/fem/example_convection_diffusion_dg.py +25 -4
- warp/examples/fem/example_diffusion_mgpu.py +8 -3
- warp/examples/fem/utils.py +68 -22
- warp/examples/interop/example_jax_kernel.py +2 -1
- warp/fabric.py +1 -1
- warp/fem/cache.py +27 -19
- warp/fem/domain.py +2 -2
- warp/fem/field/nodal_field.py +2 -2
- warp/fem/field/virtual.py +264 -166
- warp/fem/geometry/geometry.py +5 -5
- warp/fem/integrate.py +129 -51
- warp/fem/space/restriction.py +4 -0
- warp/fem/space/shape/tet_shape_function.py +3 -10
- warp/jax_experimental/custom_call.py +25 -2
- warp/jax_experimental/ffi.py +22 -1
- warp/jax_experimental/xla_ffi.py +16 -7
- warp/marching_cubes.py +708 -0
- warp/native/array.h +99 -4
- warp/native/builtin.h +86 -9
- warp/native/bvh.cpp +64 -28
- warp/native/bvh.cu +58 -58
- warp/native/bvh.h +2 -2
- warp/native/clang/clang.cpp +7 -7
- warp/native/coloring.cpp +8 -2
- warp/native/crt.cpp +2 -2
- warp/native/crt.h +3 -5
- warp/native/cuda_util.cpp +41 -10
- warp/native/cuda_util.h +10 -4
- warp/native/exports.h +1842 -1908
- warp/native/fabric.h +2 -1
- warp/native/hashgrid.cpp +37 -37
- warp/native/hashgrid.cu +2 -2
- warp/native/initializer_array.h +1 -1
- warp/native/intersect.h +2 -2
- warp/native/mat.h +1910 -116
- warp/native/mathdx.cpp +43 -43
- warp/native/mesh.cpp +24 -24
- warp/native/mesh.cu +26 -26
- warp/native/mesh.h +4 -2
- warp/native/nanovdb/GridHandle.h +179 -12
- warp/native/nanovdb/HostBuffer.h +8 -7
- warp/native/nanovdb/NanoVDB.h +517 -895
- warp/native/nanovdb/NodeManager.h +323 -0
- warp/native/nanovdb/PNanoVDB.h +2 -2
- warp/native/quat.h +331 -14
- warp/native/range.h +7 -1
- warp/native/reduce.cpp +10 -10
- warp/native/reduce.cu +13 -14
- warp/native/runlength_encode.cpp +2 -2
- warp/native/runlength_encode.cu +5 -5
- warp/native/scan.cpp +3 -3
- warp/native/scan.cu +4 -4
- warp/native/sort.cpp +10 -10
- warp/native/sort.cu +40 -31
- warp/native/sort.h +2 -0
- warp/native/sparse.cpp +8 -8
- warp/native/sparse.cu +13 -13
- warp/native/spatial.h +366 -17
- warp/native/temp_buffer.h +2 -2
- warp/native/tile.h +471 -82
- warp/native/vec.h +328 -14
- warp/native/volume.cpp +54 -54
- warp/native/volume.cu +1 -1
- warp/native/volume.h +2 -1
- warp/native/volume_builder.cu +30 -37
- warp/native/warp.cpp +150 -149
- warp/native/warp.cu +377 -216
- warp/native/warp.h +227 -226
- warp/optim/linear.py +736 -271
- warp/render/imgui_manager.py +289 -0
- warp/render/render_opengl.py +99 -18
- warp/render/render_usd.py +1 -0
- warp/sim/graph_coloring.py +2 -2
- warp/sparse.py +558 -175
- warp/tests/aux_test_module_aot.py +7 -0
- warp/tests/cuda/test_async.py +3 -3
- warp/tests/cuda/test_conditional_captures.py +101 -0
- warp/tests/geometry/test_hash_grid.py +38 -0
- warp/tests/geometry/test_marching_cubes.py +233 -12
- warp/tests/interop/test_jax.py +608 -28
- warp/tests/sim/test_coloring.py +6 -6
- warp/tests/test_array.py +58 -5
- warp/tests/test_codegen.py +4 -3
- warp/tests/test_context.py +8 -15
- warp/tests/test_enum.py +136 -0
- warp/tests/test_examples.py +2 -2
- warp/tests/test_fem.py +49 -6
- warp/tests/test_fixedarray.py +229 -0
- warp/tests/test_func.py +18 -15
- warp/tests/test_future_annotations.py +7 -5
- warp/tests/test_linear_solvers.py +30 -0
- warp/tests/test_map.py +15 -1
- warp/tests/test_mat.py +1518 -378
- warp/tests/test_mat_assign_copy.py +178 -0
- warp/tests/test_mat_constructors.py +574 -0
- warp/tests/test_module_aot.py +287 -0
- warp/tests/test_print.py +69 -0
- warp/tests/test_quat.py +140 -34
- warp/tests/test_quat_assign_copy.py +145 -0
- warp/tests/test_reload.py +2 -1
- warp/tests/test_sparse.py +71 -0
- warp/tests/test_spatial.py +140 -34
- warp/tests/test_spatial_assign_copy.py +160 -0
- warp/tests/test_struct.py +43 -3
- warp/tests/test_tuple.py +96 -0
- warp/tests/test_types.py +61 -20
- warp/tests/test_vec.py +179 -34
- warp/tests/test_vec_assign_copy.py +143 -0
- warp/tests/tile/test_tile.py +245 -18
- warp/tests/tile/test_tile_cholesky.py +605 -0
- warp/tests/tile/test_tile_load.py +169 -0
- warp/tests/tile/test_tile_mathdx.py +2 -558
- warp/tests/tile/test_tile_matmul.py +1 -1
- warp/tests/tile/test_tile_mlp.py +1 -1
- warp/tests/tile/test_tile_shared_memory.py +5 -5
- warp/tests/unittest_suites.py +6 -0
- warp/tests/walkthrough_debug.py +1 -1
- warp/thirdparty/unittest_parallel.py +108 -9
- warp/types.py +571 -267
- warp/utils.py +68 -86
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/METADATA +29 -69
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/RECORD +138 -128
- warp/native/marching.cpp +0 -19
- warp/native/marching.cu +0 -514
- warp/native/marching.h +0 -19
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/top_level.txt +0 -0
warp/tests/test_tuple.py
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import sys
|
|
16
17
|
import unittest
|
|
17
18
|
from typing import Any, Tuple
|
|
18
19
|
|
|
@@ -208,6 +209,92 @@ def test_loop_variadic_ellipsis():
|
|
|
208
209
|
wp.expect_eq(res, 22)
|
|
209
210
|
|
|
210
211
|
|
|
212
|
+
# Test for Python 3.10 tuple type compatibility issue
|
|
213
|
+
# Only define these functions on Python 3.9+ where lowercase tuple is supported
|
|
214
|
+
if sys.version_info >= (3, 9):
|
|
215
|
+
|
|
216
|
+
@wp.func
|
|
217
|
+
def complex_tuple_function(scale: float, offset: wp.vec3) -> tuple[float, wp.vec3f, wp.vec3f]:
|
|
218
|
+
"""
|
|
219
|
+
Function that returns a complex tuple with mixed types.
|
|
220
|
+
This specifically tests the tuple[float, wp.vec3f, wp.vec3f] case
|
|
221
|
+
that was problematic on Python 3.10.
|
|
222
|
+
"""
|
|
223
|
+
# Create some computed values
|
|
224
|
+
scaled_value = scale * 2.5
|
|
225
|
+
position = wp.vec3f(offset.x + 1.0, offset.y + 2.0, offset.z + 3.0)
|
|
226
|
+
velocity = wp.vec3f(scale * 0.1, scale * 0.2, scale * 0.3)
|
|
227
|
+
|
|
228
|
+
return (scaled_value, position, velocity)
|
|
229
|
+
|
|
230
|
+
@wp.func
|
|
231
|
+
def mixed_types_tuple_function() -> tuple[wp.vec3f, wp.vec3f, float, wp.mat33f]:
|
|
232
|
+
"""
|
|
233
|
+
Function returning mixed types in a tuple.
|
|
234
|
+
Tests tuple[vec3f, vec3f, float, mat33f] type annotation.
|
|
235
|
+
"""
|
|
236
|
+
return (
|
|
237
|
+
wp.vec3f(1.0, 2.0, 3.0),
|
|
238
|
+
wp.vec3f(4.0, 5.0, 6.0),
|
|
239
|
+
42.0,
|
|
240
|
+
wp.mat33f(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0),
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
@wp.func
|
|
244
|
+
def homogeneous_tuple_function() -> tuple[wp.vec3f, wp.vec3f, wp.vec3f]:
|
|
245
|
+
"""
|
|
246
|
+
Function returning fixed-size homogeneous tuple.
|
|
247
|
+
Tests tuple[wp.vec3f, wp.vec3f, wp.vec3f] type annotation.
|
|
248
|
+
"""
|
|
249
|
+
return (wp.vec3f(1.0, 2.0, 3.0), wp.vec3f(4.0, 5.0, 6.0), wp.vec3f(7.0, 8.0, 9.0))
|
|
250
|
+
|
|
251
|
+
@wp.kernel
|
|
252
|
+
def test_complex_tuple_functions():
|
|
253
|
+
"""
|
|
254
|
+
Kernel that tests complex tuple return types that were problematic on Python 3.10.
|
|
255
|
+
"""
|
|
256
|
+
# Test the main problematic case: tuple[float, wp.vec3f, wp.vec3f]
|
|
257
|
+
result1 = complex_tuple_function(4.0, wp.vec3(10.0, 20.0, 30.0))
|
|
258
|
+
|
|
259
|
+
# Unpack and verify
|
|
260
|
+
scale_result, pos_result, vel_result = result1
|
|
261
|
+
wp.expect_near(scale_result, 10.0) # 4.0 * 2.5
|
|
262
|
+
wp.expect_eq(pos_result, wp.vec3f(11.0, 22.0, 33.0))
|
|
263
|
+
wp.expect_eq(vel_result, wp.vec3f(0.4, 0.8, 1.2))
|
|
264
|
+
|
|
265
|
+
# Test access by index
|
|
266
|
+
wp.expect_near(result1[0], 10.0)
|
|
267
|
+
wp.expect_eq(result1[1], wp.vec3f(11.0, 22.0, 33.0))
|
|
268
|
+
wp.expect_eq(result1[2], wp.vec3f(0.4, 0.8, 1.2))
|
|
269
|
+
|
|
270
|
+
# Test more complex tuple: tuple[vec3f, vec3f, float, mat33f]
|
|
271
|
+
mixed_result = mixed_types_tuple_function()
|
|
272
|
+
result_pos, result_vel, result_energy, result_transform = mixed_result
|
|
273
|
+
|
|
274
|
+
# Verify known values
|
|
275
|
+
wp.expect_eq(result_pos, wp.vec3f(1.0, 2.0, 3.0))
|
|
276
|
+
wp.expect_eq(result_vel, wp.vec3f(4.0, 5.0, 6.0))
|
|
277
|
+
wp.expect_eq(result_energy, 42.0)
|
|
278
|
+
|
|
279
|
+
# Verify transform matrix is identity
|
|
280
|
+
wp.expect_eq(result_transform[0, 0], 1.0)
|
|
281
|
+
wp.expect_eq(result_transform[1, 1], 1.0)
|
|
282
|
+
wp.expect_eq(result_transform[2, 2], 1.0)
|
|
283
|
+
|
|
284
|
+
# Test fixed-size homogeneous tuple: tuple[wp.vec3f, wp.vec3f, wp.vec3f]
|
|
285
|
+
homo_result = homogeneous_tuple_function()
|
|
286
|
+
wp.expect_eq(len(homo_result), 3)
|
|
287
|
+
wp.expect_eq(homo_result[0], wp.vec3f(1.0, 2.0, 3.0))
|
|
288
|
+
wp.expect_eq(homo_result[1], wp.vec3f(4.0, 5.0, 6.0))
|
|
289
|
+
wp.expect_eq(homo_result[2], wp.vec3f(7.0, 8.0, 9.0))
|
|
290
|
+
|
|
291
|
+
# Test unpacking
|
|
292
|
+
vec1, vec2, vec3 = homo_result
|
|
293
|
+
wp.expect_eq(vec1, wp.vec3f(1.0, 2.0, 3.0))
|
|
294
|
+
wp.expect_eq(vec2, wp.vec3f(4.0, 5.0, 6.0))
|
|
295
|
+
wp.expect_eq(vec3, wp.vec3f(7.0, 8.0, 9.0))
|
|
296
|
+
|
|
297
|
+
|
|
211
298
|
devices = get_test_devices()
|
|
212
299
|
|
|
213
300
|
|
|
@@ -258,6 +345,15 @@ add_kernel_test(
|
|
|
258
345
|
dim=1,
|
|
259
346
|
devices=devices,
|
|
260
347
|
)
|
|
348
|
+
# Only register the test for lowercase tuple syntax on Python 3.9+
|
|
349
|
+
if sys.version_info >= (3, 9):
|
|
350
|
+
add_kernel_test(
|
|
351
|
+
TestTuple,
|
|
352
|
+
name="test_complex_tuple_functions",
|
|
353
|
+
kernel=test_complex_tuple_functions,
|
|
354
|
+
dim=1,
|
|
355
|
+
devices=devices,
|
|
356
|
+
)
|
|
261
357
|
|
|
262
358
|
|
|
263
359
|
if __name__ == "__main__":
|
warp/tests/test_types.py
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
+
import sys
|
|
16
17
|
import unittest
|
|
17
18
|
|
|
18
19
|
from warp.tests.unittest_utils import *
|
|
@@ -267,11 +268,6 @@ class TestTypes(unittest.TestCase):
|
|
|
267
268
|
with self.assertRaisesRegex(TypeError, r"Expected to assign a `int32` value but got `str` instead"):
|
|
268
269
|
v1[0] = "123.0"
|
|
269
270
|
|
|
270
|
-
with self.assertRaisesRegex(
|
|
271
|
-
TypeError, r"Expected to assign a slice from a sequence of values but got `int` instead"
|
|
272
|
-
):
|
|
273
|
-
v1[:] = 123
|
|
274
|
-
|
|
275
271
|
with self.assertRaisesRegex(
|
|
276
272
|
TypeError, r"Expected to assign a slice from a sequence of `int32` values but got `vec3i` instead"
|
|
277
273
|
):
|
|
@@ -483,26 +479,11 @@ class TestTypes(unittest.TestCase):
|
|
|
483
479
|
with self.assertRaisesRegex(TypeError, r"Expected to assign a `float16` value but got `str` instead"):
|
|
484
480
|
m[0][0] = "123.0"
|
|
485
481
|
|
|
486
|
-
with self.assertRaisesRegex(
|
|
487
|
-
TypeError, r"Expected to assign a slice from a sequence of values but got `int` instead"
|
|
488
|
-
):
|
|
489
|
-
m[0] = 123
|
|
490
|
-
|
|
491
482
|
with self.assertRaisesRegex(
|
|
492
483
|
TypeError, r"Expected to assign a slice from a sequence of `float16` values but got `mat22h` instead"
|
|
493
484
|
):
|
|
494
485
|
m[0] = (m,)
|
|
495
486
|
|
|
496
|
-
with self.assertRaisesRegex(
|
|
497
|
-
KeyError, r"Slices are not supported when indexing matrices using the `m\[start:end\]` notation"
|
|
498
|
-
):
|
|
499
|
-
m[:] = 123
|
|
500
|
-
|
|
501
|
-
with self.assertRaisesRegex(
|
|
502
|
-
KeyError, r"Slices are not supported when indexing matrices using the `m\[i, j\]` notation"
|
|
503
|
-
):
|
|
504
|
-
m[0, :1] = (123,)
|
|
505
|
-
|
|
506
487
|
with self.assertRaisesRegex(ValueError, r"Can only assign sequence of same size"):
|
|
507
488
|
m[0][:1] = (1, 2)
|
|
508
489
|
|
|
@@ -547,6 +528,66 @@ class TestTypes(unittest.TestCase):
|
|
|
547
528
|
test_conversions(wp.uint64, np.uint64)
|
|
548
529
|
test_conversions(wp.bool, np.bool_)
|
|
549
530
|
|
|
531
|
+
# Only define this test method on Python 3.9+ where lowercase tuple is supported
|
|
532
|
+
if sys.version_info >= (3, 9):
|
|
533
|
+
|
|
534
|
+
def test_tuple_type_code_generation(self):
|
|
535
|
+
"""Test that tuple type annotations generate correct type codes, especially on Python 3.10."""
|
|
536
|
+
import sys
|
|
537
|
+
import types
|
|
538
|
+
from typing import get_origin
|
|
539
|
+
|
|
540
|
+
# Test basic tuple types
|
|
541
|
+
tuple_float_float = tuple[float, float]
|
|
542
|
+
result = wp.types.get_type_code(tuple_float_float)
|
|
543
|
+
self.assertEqual(result, "tpl2f4f4", "tuple[float, float] should generate 'tpl2f4f4'")
|
|
544
|
+
|
|
545
|
+
# Test tuple with Warp vector types - the problematic case from Python 3.10
|
|
546
|
+
tuple_mixed = tuple[float, wp.vec3f, wp.vec3f]
|
|
547
|
+
result = wp.types.get_type_code(tuple_mixed)
|
|
548
|
+
self.assertEqual(result, "tpl3f4v3f4v3f4", "tuple[float, vec3f, vec3f] should generate 'tpl3f4v3f4v3f4'")
|
|
549
|
+
|
|
550
|
+
# Test homogeneous tuple with ellipsis
|
|
551
|
+
tuple_homogeneous = tuple[wp.vec3f, ...]
|
|
552
|
+
result = wp.types.get_type_code(tuple_homogeneous)
|
|
553
|
+
self.assertEqual(result, "tpl2v3f4?", "tuple[vec3f, ...] should generate 'tpl2v3f4?'")
|
|
554
|
+
|
|
555
|
+
# Test single element tuple
|
|
556
|
+
tuple_single = tuple[wp.int32]
|
|
557
|
+
result = wp.types.get_type_code(tuple_single)
|
|
558
|
+
self.assertEqual(result, "tpl1i4", "tuple[int32] should generate 'tpl1i4'")
|
|
559
|
+
|
|
560
|
+
# Test tuple with multiple Warp types
|
|
561
|
+
tuple_multi_warp = tuple[wp.vec3f, wp.mat33f, wp.quatf]
|
|
562
|
+
result = wp.types.get_type_code(tuple_multi_warp)
|
|
563
|
+
self.assertEqual(
|
|
564
|
+
result, "tpl3v3f4m33f4qf4", "tuple[vec3f, mat33f, quatf] should generate 'tpl3v3f4m33f4qf4'"
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
# Verify the fix works on Python 3.9-3.10 specifically
|
|
568
|
+
if sys.version_info < (3, 11) and hasattr(types, "GenericAlias"):
|
|
569
|
+
# On Python 3.9-3.10, tuple[...] creates types.GenericAlias
|
|
570
|
+
self.assertIsInstance(
|
|
571
|
+
tuple_mixed, types.GenericAlias, "On Python 3.9-3.10, tuple[...] should create types.GenericAlias"
|
|
572
|
+
)
|
|
573
|
+
self.assertIs(tuple_mixed.__origin__, tuple, "GenericAlias origin should be tuple")
|
|
574
|
+
|
|
575
|
+
# Verify our fix catches this case
|
|
576
|
+
self.assertEqual(get_origin(tuple_mixed), tuple, "get_origin should return tuple")
|
|
577
|
+
elif sys.version_info >= (3, 11):
|
|
578
|
+
# On Python 3.11+, the existing code path should handle it
|
|
579
|
+
self.assertEqual(get_origin(tuple_mixed), tuple, "get_origin should return tuple on Python 3.11+")
|
|
580
|
+
|
|
581
|
+
# Test that the fix doesn't break existing functionality
|
|
582
|
+
# Test with built-in Python types
|
|
583
|
+
tuple_builtin = tuple[int, str, bool]
|
|
584
|
+
try:
|
|
585
|
+
# This might fail because str and bool aren't Warp types, but it shouldn't crash
|
|
586
|
+
wp.types.get_type_code(tuple_builtin)
|
|
587
|
+
except TypeError as e:
|
|
588
|
+
# Expected to fail for non-Warp types, but should be a clean TypeError
|
|
589
|
+
self.assertIn("Unrecognized type", str(e))
|
|
590
|
+
|
|
550
591
|
|
|
551
592
|
for dtype in wp.types.int_types:
|
|
552
593
|
add_function_test(TestTypes, f"test_integers_{dtype.__name__}", test_integers, devices=devices, dtype=dtype)
|
warp/tests/test_vec.py
CHANGED
|
@@ -922,39 +922,6 @@ def test_vec_assign(test, device):
|
|
|
922
922
|
run(vec_assign_attribute)
|
|
923
923
|
|
|
924
924
|
|
|
925
|
-
def test_vec_assign_copy(test, device):
|
|
926
|
-
saved_enable_vector_component_overwrites_setting = wp.config.enable_vector_component_overwrites
|
|
927
|
-
try:
|
|
928
|
-
wp.config.enable_vector_component_overwrites = True
|
|
929
|
-
|
|
930
|
-
@wp.kernel(module="unique")
|
|
931
|
-
def vec_assign_overwrite(x: wp.array(dtype=wp.vec3), y: wp.array(dtype=wp.vec3)):
|
|
932
|
-
tid = wp.tid()
|
|
933
|
-
|
|
934
|
-
a = wp.vec3()
|
|
935
|
-
b = x[tid]
|
|
936
|
-
a = b
|
|
937
|
-
a[1] = 3.0
|
|
938
|
-
|
|
939
|
-
y[tid] = a
|
|
940
|
-
|
|
941
|
-
x = wp.ones(1, dtype=wp.vec3, device=device, requires_grad=True)
|
|
942
|
-
y = wp.zeros(1, dtype=wp.vec3, device=device, requires_grad=True)
|
|
943
|
-
|
|
944
|
-
tape = wp.Tape()
|
|
945
|
-
with tape:
|
|
946
|
-
wp.launch(vec_assign_overwrite, dim=1, inputs=[x, y], device=device)
|
|
947
|
-
|
|
948
|
-
y.grad = wp.ones_like(y, requires_grad=False)
|
|
949
|
-
tape.backward()
|
|
950
|
-
|
|
951
|
-
assert_np_equal(y.numpy(), np.array([[1.0, 3.0, 1.0]], dtype=float))
|
|
952
|
-
assert_np_equal(x.grad.numpy(), np.array([[1.0, 0.0, 1.0]], dtype=float))
|
|
953
|
-
|
|
954
|
-
finally:
|
|
955
|
-
wp.config.enable_vector_component_overwrites = saved_enable_vector_component_overwrites_setting
|
|
956
|
-
|
|
957
|
-
|
|
958
925
|
@wp.kernel
|
|
959
926
|
def vec_array_extract_subscript(x: wp.array2d(dtype=wp.vec3), y: wp.array2d(dtype=float)):
|
|
960
927
|
i, j = wp.tid()
|
|
@@ -1189,6 +1156,181 @@ def test_scalar_vec_div(test, device):
|
|
|
1189
1156
|
assert_np_equal(x.grad.numpy(), np.array(((-1.0, -0.25, -0.0625),), dtype=float))
|
|
1190
1157
|
|
|
1191
1158
|
|
|
1159
|
+
def test_vec_indexing_assign(test, device):
|
|
1160
|
+
@wp.func
|
|
1161
|
+
def fn():
|
|
1162
|
+
v = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1163
|
+
|
|
1164
|
+
v[0] = 123.0
|
|
1165
|
+
v[1] *= 2.0
|
|
1166
|
+
|
|
1167
|
+
wp.expect_eq(v[0], 123.0)
|
|
1168
|
+
wp.expect_eq(v[1], 4.0)
|
|
1169
|
+
wp.expect_eq(v[2], 3.0)
|
|
1170
|
+
wp.expect_eq(v[3], 4.0)
|
|
1171
|
+
|
|
1172
|
+
v[-1] = 123.0
|
|
1173
|
+
v[-2] *= 2.0
|
|
1174
|
+
|
|
1175
|
+
wp.expect_eq(v[-1], 123.0)
|
|
1176
|
+
wp.expect_eq(v[-2], 6.0)
|
|
1177
|
+
wp.expect_eq(v[-3], 4.0)
|
|
1178
|
+
wp.expect_eq(v[-4], 123.0)
|
|
1179
|
+
|
|
1180
|
+
@wp.kernel(module="unique")
|
|
1181
|
+
def kernel():
|
|
1182
|
+
fn()
|
|
1183
|
+
|
|
1184
|
+
wp.launch(kernel, 1, device=device)
|
|
1185
|
+
wp.synchronize()
|
|
1186
|
+
fn()
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
def test_vec_slicing_assign(test, device):
|
|
1190
|
+
vec0 = wp.vec(0, float)
|
|
1191
|
+
vec1 = wp.vec(1, float)
|
|
1192
|
+
vec2 = wp.vec(2, float)
|
|
1193
|
+
vec3 = wp.vec(3, float)
|
|
1194
|
+
vec4 = wp.vec(4, float)
|
|
1195
|
+
|
|
1196
|
+
@wp.func
|
|
1197
|
+
def fn():
|
|
1198
|
+
v = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1199
|
+
|
|
1200
|
+
wp.expect_eq(v[:] == vec4(1.0, 2.0, 3.0, 4.0), True)
|
|
1201
|
+
wp.expect_eq(v[-123:123] == vec4(1.0, 2.0, 3.0, 4.0), True)
|
|
1202
|
+
wp.expect_eq(v[123:] == vec0(), True)
|
|
1203
|
+
wp.expect_eq(v[:-123] == vec0(), True)
|
|
1204
|
+
wp.expect_eq(v[::123] == vec1(1.0), True)
|
|
1205
|
+
|
|
1206
|
+
wp.expect_eq(v[1:] == vec3(2.0, 3.0, 4.0), True)
|
|
1207
|
+
wp.expect_eq(v[-2:] == vec2(3.0, 4.0), True)
|
|
1208
|
+
wp.expect_eq(v[:2] == vec2(1.0, 2.0), True)
|
|
1209
|
+
wp.expect_eq(v[:-1] == vec3(1.0, 2.0, 3.0), True)
|
|
1210
|
+
wp.expect_eq(v[::2] == vec2(1.0, 3.0), True)
|
|
1211
|
+
wp.expect_eq(v[1::2] == vec2(2.0, 4.0), True)
|
|
1212
|
+
wp.expect_eq(v[::-1] == vec4(4.0, 3.0, 2.0, 1.0), True)
|
|
1213
|
+
wp.expect_eq(v[::-2] == vec2(4.0, 2.0), True)
|
|
1214
|
+
wp.expect_eq(v[1::-2] == vec1(2.0), True)
|
|
1215
|
+
|
|
1216
|
+
v[1:] = vec3(5.0, 6.0, 7.0)
|
|
1217
|
+
wp.expect_eq(v == wp.vec4(1.0, 5.0, 6.0, 7.0), True)
|
|
1218
|
+
|
|
1219
|
+
v[-2:] = vec2(8.0, 9.0)
|
|
1220
|
+
wp.expect_eq(v == wp.vec4(1.0, 5.0, 8.0, 9.0), True)
|
|
1221
|
+
|
|
1222
|
+
v[:2] = vec2(10.0, 11.0)
|
|
1223
|
+
wp.expect_eq(v == wp.vec4(10.0, 11.0, 8.0, 9.0), True)
|
|
1224
|
+
|
|
1225
|
+
v[:-1] = vec3(12.0, 13.0, 14.0)
|
|
1226
|
+
wp.expect_eq(v == wp.vec4(12.0, 13.0, 14.0, 9.0), True)
|
|
1227
|
+
|
|
1228
|
+
v[::2] = vec2(15.0, 16.0)
|
|
1229
|
+
wp.expect_eq(v == wp.vec4(15.0, 13.0, 16.0, 9.0), True)
|
|
1230
|
+
|
|
1231
|
+
v[1::2] = vec2(17.0, 18.0)
|
|
1232
|
+
wp.expect_eq(v == wp.vec4(15.0, 17.0, 16.0, 18.0), True)
|
|
1233
|
+
|
|
1234
|
+
v[::-1] = vec4(19.0, 20.0, 21.0, 22.0)
|
|
1235
|
+
wp.expect_eq(v == wp.vec4(22.0, 21.0, 20.0, 19.0), True)
|
|
1236
|
+
|
|
1237
|
+
v[::-2] = vec2(23.0, 24.0)
|
|
1238
|
+
wp.expect_eq(v == wp.vec4(22.0, 24.0, 20.0, 23.0), True)
|
|
1239
|
+
|
|
1240
|
+
v[1::-2] = vec1(25.0)
|
|
1241
|
+
wp.expect_eq(v == wp.vec4(22.0, 25.0, 20.0, 23.0), True)
|
|
1242
|
+
|
|
1243
|
+
v[1:] += vec3(26.0, 27.0, 28.0)
|
|
1244
|
+
wp.expect_eq(v == wp.vec4(22.0, 51.0, 47.0, 51.0), True)
|
|
1245
|
+
|
|
1246
|
+
v[:-1] -= vec3(29.0, 30.0, 31.0)
|
|
1247
|
+
wp.expect_eq(v == wp.vec4(-7.0, 21.0, 16.0, 51.0), True)
|
|
1248
|
+
|
|
1249
|
+
v[:] %= vec4(32.0, 33.0, 34.0, 35.0)
|
|
1250
|
+
wp.expect_eq(v == wp.vec4(-7.0, 21.0, 16.0, 16.0), True)
|
|
1251
|
+
|
|
1252
|
+
@wp.kernel(module="unique")
|
|
1253
|
+
def kernel():
|
|
1254
|
+
fn()
|
|
1255
|
+
|
|
1256
|
+
wp.launch(kernel, 1, device=device)
|
|
1257
|
+
wp.synchronize()
|
|
1258
|
+
fn()
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
def test_vec_assign_inplace_errors(test, device):
|
|
1262
|
+
@wp.kernel
|
|
1263
|
+
def kernel_1():
|
|
1264
|
+
v = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1265
|
+
v[1:] = wp.vec3d(wp.float64(5.0), wp.float64(6.0), wp.float64(7.0))
|
|
1266
|
+
|
|
1267
|
+
with test.assertRaisesRegex(
|
|
1268
|
+
ValueError,
|
|
1269
|
+
r"The provided vector is expected to be of length 3 with dtype float32.$",
|
|
1270
|
+
):
|
|
1271
|
+
wp.launch(kernel_1, dim=1, device=device)
|
|
1272
|
+
|
|
1273
|
+
@wp.kernel
|
|
1274
|
+
def kernel_2():
|
|
1275
|
+
v = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1276
|
+
v[1:] = wp.float64(5.0)
|
|
1277
|
+
|
|
1278
|
+
with test.assertRaisesRegex(
|
|
1279
|
+
ValueError,
|
|
1280
|
+
r"The provided value is expected to be a vector of length 3, with dtype float32.$",
|
|
1281
|
+
):
|
|
1282
|
+
wp.launch(kernel_2, dim=1, device=device)
|
|
1283
|
+
|
|
1284
|
+
@wp.kernel
|
|
1285
|
+
def kernel_3():
|
|
1286
|
+
v = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1287
|
+
v[1:] = wp.mat22(5.0, 6.0, 7.0, 8.0)
|
|
1288
|
+
|
|
1289
|
+
with test.assertRaisesRegex(
|
|
1290
|
+
ValueError,
|
|
1291
|
+
r"The provided value is expected to be a vector of length 3, with dtype float32.$",
|
|
1292
|
+
):
|
|
1293
|
+
wp.launch(kernel_3, dim=1, device=device)
|
|
1294
|
+
|
|
1295
|
+
@wp.kernel
|
|
1296
|
+
def kernel_4():
|
|
1297
|
+
v = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1298
|
+
v[1:] = wp.vec2(5.0, 6.0)
|
|
1299
|
+
|
|
1300
|
+
with test.assertRaisesRegex(
|
|
1301
|
+
ValueError,
|
|
1302
|
+
r"The length of the provided vector \(2\) isn't compatible with the given slice \(expected 3\).$",
|
|
1303
|
+
):
|
|
1304
|
+
wp.launch(kernel_4, dim=1, device=device)
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
def test_vec_slicing_assign_backward(test, device):
|
|
1308
|
+
@wp.kernel(module="unique")
|
|
1309
|
+
def kernel(arr_x: wp.array(dtype=wp.vec2), arr_y: wp.array(dtype=wp.vec4)):
|
|
1310
|
+
i = wp.tid()
|
|
1311
|
+
|
|
1312
|
+
y = arr_y[i]
|
|
1313
|
+
|
|
1314
|
+
y[:2] = arr_x[i]
|
|
1315
|
+
y[1:-1] += arr_x[i][:2]
|
|
1316
|
+
y[3:1:-1] -= arr_x[i][0:]
|
|
1317
|
+
|
|
1318
|
+
arr_y[i] = y
|
|
1319
|
+
|
|
1320
|
+
x = wp.ones(1, dtype=wp.vec2, requires_grad=True, device=device)
|
|
1321
|
+
y = wp.zeros(1, dtype=wp.vec4, requires_grad=True, device=device)
|
|
1322
|
+
|
|
1323
|
+
tape = wp.Tape()
|
|
1324
|
+
with tape:
|
|
1325
|
+
wp.launch(kernel, 1, inputs=(x,), outputs=(y,), device=device)
|
|
1326
|
+
|
|
1327
|
+
y.grad = wp.ones_like(y)
|
|
1328
|
+
tape.backward()
|
|
1329
|
+
|
|
1330
|
+
assert_np_equal(y.numpy(), np.array(((1.0, 2.0, 0.0, -1.0),), dtype=float))
|
|
1331
|
+
assert_np_equal(x.grad.numpy(), np.array(((1.0, 1.0),), dtype=float))
|
|
1332
|
+
|
|
1333
|
+
|
|
1192
1334
|
devices = get_test_devices()
|
|
1193
1335
|
|
|
1194
1336
|
|
|
@@ -1248,7 +1390,6 @@ add_function_test(TestVec, "test_length_mismatch", test_length_mismatch, devices
|
|
|
1248
1390
|
add_function_test(TestVec, "test_vector_len", test_vector_len, devices=devices)
|
|
1249
1391
|
add_function_test(TestVec, "test_vec_extract", test_vec_extract, devices=devices)
|
|
1250
1392
|
add_function_test(TestVec, "test_vec_assign", test_vec_assign, devices=devices)
|
|
1251
|
-
add_function_test(TestVec, "test_vec_assign_copy", test_vec_assign_copy, devices=devices)
|
|
1252
1393
|
add_function_test(TestVec, "test_vec_array_extract", test_vec_array_extract, devices=devices)
|
|
1253
1394
|
add_function_test(TestVec, "test_vec_array_assign", test_vec_array_assign, devices=devices)
|
|
1254
1395
|
add_function_test(TestVec, "test_vec_add_inplace", test_vec_add_inplace, devices=devices)
|
|
@@ -1256,6 +1397,10 @@ add_function_test(TestVec, "test_vec_sub_inplace", test_vec_sub_inplace, devices
|
|
|
1256
1397
|
add_function_test(TestVec, "test_vec_array_add_inplace", test_vec_array_add_inplace, devices=devices)
|
|
1257
1398
|
add_function_test(TestVec, "test_vec_array_sub_inplace", test_vec_array_sub_inplace, devices=devices)
|
|
1258
1399
|
add_function_test(TestVec, "test_scalar_vec_div", test_scalar_vec_div, devices=devices)
|
|
1400
|
+
add_function_test(TestVec, "test_vec_indexing_assign", test_vec_indexing_assign, devices=devices)
|
|
1401
|
+
add_function_test(TestVec, "test_vec_slicing_assign", test_vec_slicing_assign, devices=devices)
|
|
1402
|
+
add_function_test(TestVec, "test_vec_assign_inplace_errors", test_vec_assign_inplace_errors, devices=devices)
|
|
1403
|
+
add_function_test(TestVec, "test_vec_slicing_assign_backward", test_vec_slicing_assign_backward, devices=devices)
|
|
1259
1404
|
|
|
1260
1405
|
|
|
1261
1406
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
import unittest
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
import warp as wp
|
|
21
|
+
from warp.tests.unittest_utils import *
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def setUpModule():
|
|
25
|
+
wp.config.enable_vector_component_overwrites = True
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def tearDownModule():
|
|
29
|
+
wp.config.enable_vector_component_overwrites = False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@wp.kernel
|
|
33
|
+
def vec_assign_subscript(x: wp.array(dtype=float), y: wp.array(dtype=wp.vec3)):
|
|
34
|
+
i = wp.tid()
|
|
35
|
+
|
|
36
|
+
a = wp.vec3()
|
|
37
|
+
a[0] = 1.0 * x[i]
|
|
38
|
+
a[1] = 2.0 * x[i]
|
|
39
|
+
a[2] = 3.0 * x[i]
|
|
40
|
+
y[i] = a
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@wp.kernel
|
|
44
|
+
def vec_assign_attribute(x: wp.array(dtype=float), y: wp.array(dtype=wp.vec3)):
|
|
45
|
+
i = wp.tid()
|
|
46
|
+
|
|
47
|
+
a = wp.vec3()
|
|
48
|
+
a.x = 1.0 * x[i]
|
|
49
|
+
a.y = 2.0 * x[i]
|
|
50
|
+
a.z = 3.0 * x[i]
|
|
51
|
+
y[i] = a
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_vec_assign(test, device):
|
|
55
|
+
def run(kernel):
|
|
56
|
+
x = wp.ones(1, dtype=float, requires_grad=True, device=device)
|
|
57
|
+
y = wp.zeros(1, dtype=wp.vec3, requires_grad=True, device=device)
|
|
58
|
+
|
|
59
|
+
tape = wp.Tape()
|
|
60
|
+
with tape:
|
|
61
|
+
wp.launch(kernel, 1, inputs=[x], outputs=[y], device=device)
|
|
62
|
+
|
|
63
|
+
y.grad = wp.ones_like(y)
|
|
64
|
+
tape.backward()
|
|
65
|
+
|
|
66
|
+
assert_np_equal(y.numpy(), np.array([[1.0, 2.0, 3.0]], dtype=float))
|
|
67
|
+
assert_np_equal(x.grad.numpy(), np.array([6.0], dtype=float))
|
|
68
|
+
|
|
69
|
+
run(vec_assign_subscript)
|
|
70
|
+
run(vec_assign_attribute)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_vec_assign_copy(test, device):
|
|
74
|
+
@wp.kernel(module="unique")
|
|
75
|
+
def vec_assign_overwrite(x: wp.array(dtype=wp.vec3), y: wp.array(dtype=wp.vec3)):
|
|
76
|
+
tid = wp.tid()
|
|
77
|
+
|
|
78
|
+
a = wp.vec3()
|
|
79
|
+
b = x[tid]
|
|
80
|
+
a = b
|
|
81
|
+
a[1] = 3.0
|
|
82
|
+
|
|
83
|
+
y[tid] = a
|
|
84
|
+
|
|
85
|
+
x = wp.ones(1, dtype=wp.vec3, device=device, requires_grad=True)
|
|
86
|
+
y = wp.zeros(1, dtype=wp.vec3, device=device, requires_grad=True)
|
|
87
|
+
|
|
88
|
+
tape = wp.Tape()
|
|
89
|
+
with tape:
|
|
90
|
+
wp.launch(vec_assign_overwrite, dim=1, inputs=[x, y], device=device)
|
|
91
|
+
|
|
92
|
+
y.grad = wp.ones_like(y, requires_grad=False)
|
|
93
|
+
tape.backward()
|
|
94
|
+
|
|
95
|
+
assert_np_equal(y.numpy(), np.array([[1.0, 3.0, 1.0]], dtype=float))
|
|
96
|
+
assert_np_equal(x.grad.numpy(), np.array([[1.0, 0.0, 1.0]], dtype=float))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_vec_slicing_assign_backward(test, device):
|
|
100
|
+
@wp.kernel(module="unique")
|
|
101
|
+
def kernel(arr_x: wp.array(dtype=wp.vec2), arr_y: wp.array(dtype=wp.vec4)):
|
|
102
|
+
i = wp.tid()
|
|
103
|
+
|
|
104
|
+
x = arr_x[i]
|
|
105
|
+
y = arr_y[i]
|
|
106
|
+
|
|
107
|
+
y[:2] = x
|
|
108
|
+
y[1:-1] += x[:2]
|
|
109
|
+
y[3:1:-1] -= x[0:]
|
|
110
|
+
|
|
111
|
+
arr_y[i] = y
|
|
112
|
+
|
|
113
|
+
x = wp.ones(1, dtype=wp.vec2, requires_grad=True, device=device)
|
|
114
|
+
y = wp.zeros(1, dtype=wp.vec4, requires_grad=True, device=device)
|
|
115
|
+
|
|
116
|
+
tape = wp.Tape()
|
|
117
|
+
with tape:
|
|
118
|
+
wp.launch(kernel, 1, inputs=(x,), outputs=(y,), device=device)
|
|
119
|
+
|
|
120
|
+
y.grad = wp.ones_like(y)
|
|
121
|
+
tape.backward()
|
|
122
|
+
|
|
123
|
+
assert_np_equal(y.numpy(), np.array(((1.0, 2.0, 0.0, -1.0),), dtype=float))
|
|
124
|
+
assert_np_equal(x.grad.numpy(), np.array(((1.0, 1.0),), dtype=float))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
devices = get_test_devices()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class TestVecAssignCopy(unittest.TestCase):
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
add_function_test(TestVecAssignCopy, "test_vec_assign", test_vec_assign, devices=devices)
|
|
135
|
+
add_function_test(TestVecAssignCopy, "test_vec_assign_copy", test_vec_assign_copy, devices=devices)
|
|
136
|
+
add_function_test(
|
|
137
|
+
TestVecAssignCopy, "test_vec_slicing_assign_backward", test_vec_slicing_assign_backward, devices=devices
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
wp.clear_kernel_cache()
|
|
143
|
+
unittest.main(verbosity=2, failfast=True)
|