warp-lang 1.3.2__py3-none-manylinux2014_aarch64.whl → 1.4.0__py3-none-manylinux2014_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +6 -0
- warp/autograd.py +59 -6
- warp/bin/warp.so +0 -0
- warp/build_dll.py +8 -10
- warp/builtins.py +126 -4
- warp/codegen.py +435 -53
- warp/config.py +1 -1
- warp/context.py +678 -403
- warp/dlpack.py +2 -0
- warp/examples/benchmarks/benchmark_cloth.py +10 -0
- warp/examples/core/example_render_opengl.py +12 -10
- warp/examples/fem/example_adaptive_grid.py +251 -0
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_diffusion_3d.py +2 -2
- warp/examples/fem/example_magnetostatics.py +1 -1
- warp/examples/fem/example_streamlines.py +1 -0
- warp/examples/fem/utils.py +23 -4
- warp/examples/sim/example_cloth.py +50 -6
- warp/fem/__init__.py +2 -0
- warp/fem/adaptivity.py +493 -0
- warp/fem/field/field.py +2 -1
- warp/fem/field/nodal_field.py +18 -26
- warp/fem/field/test.py +4 -4
- warp/fem/field/trial.py +4 -4
- warp/fem/geometry/__init__.py +1 -0
- warp/fem/geometry/adaptive_nanogrid.py +843 -0
- warp/fem/geometry/nanogrid.py +55 -28
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/nanogrid_function_space.py +69 -35
- warp/fem/utils.py +113 -107
- warp/jax_experimental.py +28 -15
- warp/native/array.h +0 -1
- warp/native/builtin.h +103 -6
- warp/native/bvh.cu +2 -0
- warp/native/cuda_util.cpp +14 -0
- warp/native/cuda_util.h +2 -0
- warp/native/error.cpp +4 -2
- warp/native/exports.h +99 -17
- warp/native/mat.h +97 -0
- warp/native/mesh.cpp +36 -0
- warp/native/mesh.cu +51 -0
- warp/native/mesh.h +1 -0
- warp/native/quat.h +43 -0
- warp/native/spatial.h +6 -0
- warp/native/vec.h +74 -0
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +10 -3
- warp/native/warp.h +8 -1
- warp/paddle.py +382 -0
- warp/sim/__init__.py +1 -0
- warp/sim/collide.py +519 -0
- warp/sim/integrator_euler.py +18 -5
- warp/sim/integrator_featherstone.py +5 -5
- warp/sim/integrator_vbd.py +1026 -0
- warp/sim/model.py +49 -23
- warp/stubs.py +459 -0
- warp/tape.py +2 -0
- warp/tests/aux_test_dependent.py +1 -0
- warp/tests/aux_test_name_clash1.py +32 -0
- warp/tests/aux_test_name_clash2.py +32 -0
- warp/tests/aux_test_square.py +1 -0
- warp/tests/test_array.py +222 -0
- warp/tests/test_async.py +3 -3
- warp/tests/test_atomic.py +6 -0
- warp/tests/test_closest_point_edge_edge.py +93 -1
- warp/tests/test_codegen.py +62 -15
- warp/tests/test_codegen_instancing.py +1457 -0
- warp/tests/test_collision.py +486 -0
- warp/tests/test_compile_consts.py +3 -28
- warp/tests/test_dlpack.py +170 -0
- warp/tests/test_examples.py +22 -8
- warp/tests/test_fast_math.py +10 -4
- warp/tests/test_fem.py +64 -0
- warp/tests/test_func.py +46 -0
- warp/tests/test_implicit_init.py +49 -0
- warp/tests/test_jax.py +58 -0
- warp/tests/test_mat.py +84 -0
- warp/tests/test_mesh_query_point.py +188 -0
- warp/tests/test_module_hashing.py +40 -0
- warp/tests/test_multigpu.py +3 -3
- warp/tests/test_overwrite.py +8 -0
- warp/tests/test_paddle.py +852 -0
- warp/tests/test_print.py +89 -0
- warp/tests/test_quat.py +111 -0
- warp/tests/test_reload.py +31 -1
- warp/tests/test_scalar_ops.py +2 -0
- warp/tests/test_static.py +412 -0
- warp/tests/test_streams.py +64 -3
- warp/tests/test_struct.py +4 -4
- warp/tests/test_torch.py +24 -0
- warp/tests/test_triangle_closest_point.py +137 -0
- warp/tests/test_types.py +1 -1
- warp/tests/test_vbd.py +386 -0
- warp/tests/test_vec.py +143 -0
- warp/tests/test_vec_scalar_ops.py +139 -0
- warp/tests/test_volume.py +30 -0
- warp/tests/unittest_suites.py +12 -0
- warp/tests/unittest_utils.py +9 -5
- warp/thirdparty/dlpack.py +3 -1
- warp/types.py +157 -34
- warp/utils.py +37 -14
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/METADATA +10 -8
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/RECORD +106 -94
- warp/tests/test_point_triangle_closest_point.py +0 -143
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/top_level.txt +0 -0
|
@@ -192,12 +192,14 @@ def test_py_arithmetic_ops(test, device, dtype):
|
|
|
192
192
|
test.assertSequenceEqual(-v, make_vec(-1, 2, -3))
|
|
193
193
|
test.assertSequenceEqual(v + vec_cls(5, 5, 5), make_vec(6, 3, 8))
|
|
194
194
|
test.assertSequenceEqual(v - vec_cls(5, 5, 5), make_vec(-4, -7, -2))
|
|
195
|
+
test.assertSequenceEqual(v % vec_cls(2, 2, 2), make_vec(1, 0, 1))
|
|
195
196
|
|
|
196
197
|
v = vec_cls(2, 4, 6)
|
|
197
198
|
test.assertSequenceEqual(v * wptype(2), make_vec(4, 8, 12))
|
|
198
199
|
test.assertSequenceEqual(wptype(2) * v, make_vec(4, 8, 12))
|
|
199
200
|
test.assertSequenceEqual(v / wptype(2), make_vec(1, 2, 3))
|
|
200
201
|
test.assertSequenceEqual(wptype(24) / v, make_vec(12, 6, 4))
|
|
202
|
+
test.assertSequenceEqual(v % vec_cls(3, 3, 3), make_vec(2, 1, 0))
|
|
201
203
|
|
|
202
204
|
|
|
203
205
|
def test_constructors(test, device, dtype, register_kernels=False):
|
|
@@ -1797,6 +1799,140 @@ def test_dotproduct(test, device, dtype, register_kernels=False):
|
|
|
1797
1799
|
tape.zero()
|
|
1798
1800
|
|
|
1799
1801
|
|
|
1802
|
+
def test_modulo(test, device, dtype, register_kernels=False):
|
|
1803
|
+
rng = np.random.default_rng(123)
|
|
1804
|
+
|
|
1805
|
+
tol = {
|
|
1806
|
+
np.float16: 1.0e-2,
|
|
1807
|
+
np.float32: 1.0e-6,
|
|
1808
|
+
np.float64: 1.0e-8,
|
|
1809
|
+
}.get(dtype, 0)
|
|
1810
|
+
|
|
1811
|
+
wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)]
|
|
1812
|
+
vec2 = wp.types.vector(length=2, dtype=wptype)
|
|
1813
|
+
vec3 = wp.types.vector(length=3, dtype=wptype)
|
|
1814
|
+
vec4 = wp.types.vector(length=4, dtype=wptype)
|
|
1815
|
+
vec5 = wp.types.vector(length=5, dtype=wptype)
|
|
1816
|
+
|
|
1817
|
+
def check_mod(
|
|
1818
|
+
s2: wp.array(dtype=vec2),
|
|
1819
|
+
s3: wp.array(dtype=vec3),
|
|
1820
|
+
s4: wp.array(dtype=vec4),
|
|
1821
|
+
s5: wp.array(dtype=vec5),
|
|
1822
|
+
v2: wp.array(dtype=vec2),
|
|
1823
|
+
v3: wp.array(dtype=vec3),
|
|
1824
|
+
v4: wp.array(dtype=vec4),
|
|
1825
|
+
v5: wp.array(dtype=vec5),
|
|
1826
|
+
v20: wp.array(dtype=wptype),
|
|
1827
|
+
v21: wp.array(dtype=wptype),
|
|
1828
|
+
v30: wp.array(dtype=wptype),
|
|
1829
|
+
v31: wp.array(dtype=wptype),
|
|
1830
|
+
v32: wp.array(dtype=wptype),
|
|
1831
|
+
v40: wp.array(dtype=wptype),
|
|
1832
|
+
v41: wp.array(dtype=wptype),
|
|
1833
|
+
v42: wp.array(dtype=wptype),
|
|
1834
|
+
v43: wp.array(dtype=wptype),
|
|
1835
|
+
v50: wp.array(dtype=wptype),
|
|
1836
|
+
v51: wp.array(dtype=wptype),
|
|
1837
|
+
v52: wp.array(dtype=wptype),
|
|
1838
|
+
v53: wp.array(dtype=wptype),
|
|
1839
|
+
v54: wp.array(dtype=wptype),
|
|
1840
|
+
):
|
|
1841
|
+
v20[0] = (wptype(2) * wp.mod(v2[0], s2[0]))[0]
|
|
1842
|
+
v21[0] = (wptype(2) * wp.mod(v2[0], s2[0]))[1]
|
|
1843
|
+
|
|
1844
|
+
v30[0] = (wptype(2) * wp.mod(v3[0], s3[0]))[0]
|
|
1845
|
+
v31[0] = (wptype(2) * wp.mod(v3[0], s3[0]))[1]
|
|
1846
|
+
v32[0] = (wptype(2) * wp.mod(v3[0], s3[0]))[2]
|
|
1847
|
+
|
|
1848
|
+
v40[0] = (wptype(2) * wp.mod(v4[0], s4[0]))[0]
|
|
1849
|
+
v41[0] = (wptype(2) * wp.mod(v4[0], s4[0]))[1]
|
|
1850
|
+
v42[0] = (wptype(2) * wp.mod(v4[0], s4[0]))[2]
|
|
1851
|
+
v43[0] = (wptype(2) * wp.mod(v4[0], s4[0]))[3]
|
|
1852
|
+
|
|
1853
|
+
v50[0] = (wptype(2) * wp.mod(v5[0], s5[0]))[0]
|
|
1854
|
+
v51[0] = (wptype(2) * wp.mod(v5[0], s5[0]))[1]
|
|
1855
|
+
v52[0] = (wptype(2) * wp.mod(v5[0], s5[0]))[2]
|
|
1856
|
+
v53[0] = (wptype(2) * wp.mod(v5[0], s5[0]))[3]
|
|
1857
|
+
v54[0] = (wptype(2) * wp.mod(v5[0], s5[0]))[4]
|
|
1858
|
+
|
|
1859
|
+
kernel = getkernel(check_mod, suffix=dtype.__name__)
|
|
1860
|
+
|
|
1861
|
+
if register_kernels:
|
|
1862
|
+
return
|
|
1863
|
+
|
|
1864
|
+
s2 = wp.array(randvals(rng, (1, 2), dtype), dtype=vec2, requires_grad=True, device=device)
|
|
1865
|
+
s3 = wp.array(randvals(rng, (1, 3), dtype), dtype=vec3, requires_grad=True, device=device)
|
|
1866
|
+
s4 = wp.array(randvals(rng, (1, 4), dtype), dtype=vec4, requires_grad=True, device=device)
|
|
1867
|
+
s5 = wp.array(randvals(rng, (1, 5), dtype), dtype=vec5, requires_grad=True, device=device)
|
|
1868
|
+
v2 = wp.array(randvals(rng, (1, 2), dtype), dtype=vec2, requires_grad=True, device=device)
|
|
1869
|
+
v3 = wp.array(randvals(rng, (1, 3), dtype), dtype=vec3, requires_grad=True, device=device)
|
|
1870
|
+
v4 = wp.array(randvals(rng, (1, 4), dtype), dtype=vec4, requires_grad=True, device=device)
|
|
1871
|
+
v5 = wp.array(randvals(rng, (1, 5), dtype), dtype=vec5, requires_grad=True, device=device)
|
|
1872
|
+
v20 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1873
|
+
v21 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1874
|
+
v30 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1875
|
+
v31 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1876
|
+
v32 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1877
|
+
v40 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1878
|
+
v41 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1879
|
+
v42 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1880
|
+
v43 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1881
|
+
v50 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1882
|
+
v51 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1883
|
+
v52 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1884
|
+
v53 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1885
|
+
v54 = wp.zeros(1, dtype=wptype, requires_grad=True, device=device)
|
|
1886
|
+
tape = wp.Tape()
|
|
1887
|
+
with tape:
|
|
1888
|
+
wp.launch(
|
|
1889
|
+
kernel,
|
|
1890
|
+
dim=1,
|
|
1891
|
+
inputs=[
|
|
1892
|
+
s2,
|
|
1893
|
+
s3,
|
|
1894
|
+
s4,
|
|
1895
|
+
s5,
|
|
1896
|
+
v2,
|
|
1897
|
+
v3,
|
|
1898
|
+
v4,
|
|
1899
|
+
v5,
|
|
1900
|
+
],
|
|
1901
|
+
outputs=[
|
|
1902
|
+
v20,
|
|
1903
|
+
v21,
|
|
1904
|
+
v30,
|
|
1905
|
+
v31,
|
|
1906
|
+
v32,
|
|
1907
|
+
v40,
|
|
1908
|
+
v41,
|
|
1909
|
+
v42,
|
|
1910
|
+
v43,
|
|
1911
|
+
v50,
|
|
1912
|
+
v51,
|
|
1913
|
+
v52,
|
|
1914
|
+
v53,
|
|
1915
|
+
v54,
|
|
1916
|
+
],
|
|
1917
|
+
device=device,
|
|
1918
|
+
)
|
|
1919
|
+
|
|
1920
|
+
assert_np_equal(v20.numpy()[0], 2.0 * np.fmod(v2.numpy(), s2.numpy())[0, 0], tol=10 * tol)
|
|
1921
|
+
assert_np_equal(v21.numpy()[0], 2.0 * np.fmod(v2.numpy(), s2.numpy())[0, 1], tol=10 * tol)
|
|
1922
|
+
assert_np_equal(v30.numpy()[0], 2.0 * np.fmod(v3.numpy(), s3.numpy())[0, 0], tol=10 * tol)
|
|
1923
|
+
assert_np_equal(v31.numpy()[0], 2.0 * np.fmod(v3.numpy(), s3.numpy())[0, 1], tol=10 * tol)
|
|
1924
|
+
assert_np_equal(v32.numpy()[0], 2.0 * np.fmod(v3.numpy(), s3.numpy())[0, 2], tol=10 * tol)
|
|
1925
|
+
assert_np_equal(v40.numpy()[0], 2.0 * np.fmod(v4.numpy(), s4.numpy())[0, 0], tol=10 * tol)
|
|
1926
|
+
assert_np_equal(v41.numpy()[0], 2.0 * np.fmod(v4.numpy(), s4.numpy())[0, 1], tol=10 * tol)
|
|
1927
|
+
assert_np_equal(v42.numpy()[0], 2.0 * np.fmod(v4.numpy(), s4.numpy())[0, 2], tol=10 * tol)
|
|
1928
|
+
assert_np_equal(v43.numpy()[0], 2.0 * np.fmod(v4.numpy(), s4.numpy())[0, 3], tol=10 * tol)
|
|
1929
|
+
assert_np_equal(v50.numpy()[0], 2.0 * np.fmod(v5.numpy(), s5.numpy())[0, 0], tol=10 * tol)
|
|
1930
|
+
assert_np_equal(v51.numpy()[0], 2.0 * np.fmod(v5.numpy(), s5.numpy())[0, 1], tol=10 * tol)
|
|
1931
|
+
assert_np_equal(v52.numpy()[0], 2.0 * np.fmod(v5.numpy(), s5.numpy())[0, 2], tol=10 * tol)
|
|
1932
|
+
assert_np_equal(v53.numpy()[0], 2.0 * np.fmod(v5.numpy(), s5.numpy())[0, 3], tol=10 * tol)
|
|
1933
|
+
assert_np_equal(v54.numpy()[0], 2.0 * np.fmod(v5.numpy(), s5.numpy())[0, 4], tol=10 * tol)
|
|
1934
|
+
|
|
1935
|
+
|
|
1800
1936
|
def test_equivalent_types(test, device, dtype, register_kernels=False):
|
|
1801
1937
|
wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)]
|
|
1802
1938
|
|
|
@@ -2150,6 +2286,9 @@ for dtype in np_scalar_types:
|
|
|
2150
2286
|
add_function_test_register_kernel(
|
|
2151
2287
|
TestVecScalarOps, f"test_addition_{dtype.__name__}", test_addition, devices=devices, dtype=dtype
|
|
2152
2288
|
)
|
|
2289
|
+
add_function_test_register_kernel(
|
|
2290
|
+
TestVecScalarOps, f"test_modulo_{dtype.__name__}", test_modulo, devices=devices, dtype=dtype
|
|
2291
|
+
)
|
|
2153
2292
|
add_function_test_register_kernel(
|
|
2154
2293
|
TestVecScalarOps, f"test_dotproduct_{dtype.__name__}", test_dotproduct, devices=devices, dtype=dtype
|
|
2155
2294
|
)
|
warp/tests/test_volume.py
CHANGED
|
@@ -843,6 +843,33 @@ def test_volume_from_numpy(test, device):
|
|
|
843
843
|
test.assertIsNone(sphere_vdb_array.deleter)
|
|
844
844
|
|
|
845
845
|
|
|
846
|
+
def test_volume_from_numpy_3d(test, device):
|
|
847
|
+
# Volume.allocate_from_tiles() is only available with CUDA
|
|
848
|
+
mins = np.array([-3.0, -3.0, -3.0])
|
|
849
|
+
voxel_size = 0.2
|
|
850
|
+
maxs = np.array([3.0, 3.0, 3.0])
|
|
851
|
+
nums = np.ceil((maxs - mins) / (voxel_size)).astype(dtype=int)
|
|
852
|
+
centers = np.array([[-1.0, -1.0, -1.0], [0.0, 0.0, 0.0], [1.0, 1.0, 1.0]])
|
|
853
|
+
rad = 2.5
|
|
854
|
+
sphere_sdf_np = np.zeros(tuple(nums) + (3,))
|
|
855
|
+
for x in range(nums[0]):
|
|
856
|
+
for y in range(nums[1]):
|
|
857
|
+
for z in range(nums[2]):
|
|
858
|
+
for k in range(3):
|
|
859
|
+
pos = mins + voxel_size * np.array([x, y, z])
|
|
860
|
+
dis = np.linalg.norm(pos - centers[k])
|
|
861
|
+
sphere_sdf_np[x, y, z, k] = dis - rad
|
|
862
|
+
sphere_vdb = wp.Volume.load_from_numpy(
|
|
863
|
+
sphere_sdf_np, mins, voxel_size, (rad + 3.0 * voxel_size,) * 3, device=device
|
|
864
|
+
)
|
|
865
|
+
|
|
866
|
+
test.assertNotEqual(sphere_vdb.id, 0)
|
|
867
|
+
|
|
868
|
+
sphere_vdb_array = sphere_vdb.array()
|
|
869
|
+
test.assertEqual(sphere_vdb_array.dtype, wp.uint8)
|
|
870
|
+
test.assertIsNone(sphere_vdb_array.deleter)
|
|
871
|
+
|
|
872
|
+
|
|
846
873
|
def test_volume_aniso_transform(test, device):
|
|
847
874
|
# XY-rotation + z scale
|
|
848
875
|
transform = [
|
|
@@ -894,6 +921,9 @@ add_function_test(TestVolume, "test_volume_introspection", test_volume_introspec
|
|
|
894
921
|
add_function_test(
|
|
895
922
|
TestVolume, "test_volume_from_numpy", test_volume_from_numpy, devices=get_selected_cuda_test_devices()
|
|
896
923
|
)
|
|
924
|
+
add_function_test(
|
|
925
|
+
TestVolume, "test_volume_from_numpy_3d", test_volume_from_numpy_3d, devices=get_selected_cuda_test_devices()
|
|
926
|
+
)
|
|
897
927
|
add_function_test(
|
|
898
928
|
TestVolume, "test_volume_aniso_transform", test_volume_aniso_transform, devices=get_selected_cuda_test_devices()
|
|
899
929
|
)
|
warp/tests/unittest_suites.py
CHANGED
|
@@ -98,6 +98,7 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
98
98
|
from warp.tests.test_bvh import TestBvh
|
|
99
99
|
from warp.tests.test_closest_point_edge_edge import TestClosestPointEdgeEdgeMethods
|
|
100
100
|
from warp.tests.test_codegen import TestCodeGen
|
|
101
|
+
from warp.tests.test_codegen_instancing import TestCodeGenInstancing
|
|
101
102
|
from warp.tests.test_compile_consts import TestConstants
|
|
102
103
|
from warp.tests.test_conditional import TestConditional
|
|
103
104
|
from warp.tests.test_copy import TestCopy
|
|
@@ -117,6 +118,7 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
117
118
|
from warp.tests.test_fem import TestFem, TestFemShapeFunctions
|
|
118
119
|
from warp.tests.test_fp16 import TestFp16
|
|
119
120
|
from warp.tests.test_func import TestFunc
|
|
121
|
+
from warp.tests.test_future_annotations import TestFutureAnnotations
|
|
120
122
|
from warp.tests.test_generics import TestGenerics
|
|
121
123
|
from warp.tests.test_grad import TestGrad
|
|
122
124
|
from warp.tests.test_grad_customs import TestGradCustoms
|
|
@@ -160,6 +162,7 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
160
162
|
from warp.tests.test_reload import TestReload
|
|
161
163
|
from warp.tests.test_rounding import TestRounding
|
|
162
164
|
from warp.tests.test_runlength_encode import TestRunlengthEncode
|
|
165
|
+
from warp.tests.test_scalar_ops import TestScalarOps
|
|
163
166
|
from warp.tests.test_sim_grad import TestSimGradients
|
|
164
167
|
from warp.tests.test_sim_kinematics import TestSimKinematics
|
|
165
168
|
from warp.tests.test_smoothstep import TestSmoothstep
|
|
@@ -172,8 +175,10 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
172
175
|
from warp.tests.test_tape import TestTape
|
|
173
176
|
from warp.tests.test_torch import TestTorch
|
|
174
177
|
from warp.tests.test_transient_module import TestTransientModule
|
|
178
|
+
from warp.tests.test_triangle_closest_point import TestTriangleClosestPoint
|
|
175
179
|
from warp.tests.test_types import TestTypes
|
|
176
180
|
from warp.tests.test_utils import TestUtils
|
|
181
|
+
from warp.tests.test_vbd import TestVBD
|
|
177
182
|
from warp.tests.test_vec import TestVec
|
|
178
183
|
from warp.tests.test_vec_lite import TestVecLite
|
|
179
184
|
from warp.tests.test_vec_scalar_ops import TestVecScalarOps
|
|
@@ -193,6 +198,7 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
193
198
|
TestBvh,
|
|
194
199
|
TestClosestPointEdgeEdgeMethods,
|
|
195
200
|
TestCodeGen,
|
|
201
|
+
TestCodeGenInstancing,
|
|
196
202
|
TestConstants,
|
|
197
203
|
TestConditional,
|
|
198
204
|
TestCopy,
|
|
@@ -211,6 +217,7 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
211
217
|
TestFemShapeFunctions,
|
|
212
218
|
TestFp16,
|
|
213
219
|
TestFunc,
|
|
220
|
+
TestFutureAnnotations,
|
|
214
221
|
TestGenerics,
|
|
215
222
|
TestGrad,
|
|
216
223
|
TestGradCustoms,
|
|
@@ -254,6 +261,7 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
254
261
|
TestReload,
|
|
255
262
|
TestRounding,
|
|
256
263
|
TestRunlengthEncode,
|
|
264
|
+
TestScalarOps,
|
|
257
265
|
TestSimGradients,
|
|
258
266
|
TestSimKinematics,
|
|
259
267
|
TestSmoothstep,
|
|
@@ -266,8 +274,10 @@ def default_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader)
|
|
|
266
274
|
TestTape,
|
|
267
275
|
TestTorch,
|
|
268
276
|
TestTransientModule,
|
|
277
|
+
TestTriangleClosestPoint,
|
|
269
278
|
TestTypes,
|
|
270
279
|
TestUtils,
|
|
280
|
+
TestVBD,
|
|
271
281
|
TestVec,
|
|
272
282
|
TestVecLite,
|
|
273
283
|
TestVecScalarOps,
|
|
@@ -288,6 +298,7 @@ def kit_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader):
|
|
|
288
298
|
from warp.tests.test_array_reduce import TestArrayReduce
|
|
289
299
|
from warp.tests.test_bvh import TestBvh
|
|
290
300
|
from warp.tests.test_codegen import TestCodeGen
|
|
301
|
+
from warp.tests.test_codegen_instancing import TestCodeGenInstancing
|
|
291
302
|
from warp.tests.test_compile_consts import TestConstants
|
|
292
303
|
from warp.tests.test_conditional import TestConditional
|
|
293
304
|
from warp.tests.test_ctypes import TestCTypes
|
|
@@ -332,6 +343,7 @@ def kit_suite(test_loader: unittest.TestLoader = unittest.defaultTestLoader):
|
|
|
332
343
|
TestArrayReduce,
|
|
333
344
|
TestBvh,
|
|
334
345
|
TestCodeGen,
|
|
346
|
+
TestCodeGenInstancing,
|
|
335
347
|
TestConstants,
|
|
336
348
|
TestConditional,
|
|
337
349
|
TestCTypes,
|
warp/tests/unittest_utils.py
CHANGED
|
@@ -198,11 +198,15 @@ class CheckOutput:
|
|
|
198
198
|
if s != "":
|
|
199
199
|
print(s.rstrip())
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
# fail if test produces unexpected output (e.g.: from wp.expect_eq() builtins)
|
|
202
|
+
# we allow strings starting of the form "Module xxx load on device xxx"
|
|
203
|
+
# for lazy loaded modules
|
|
204
|
+
filtered_s = "\n".join(
|
|
205
|
+
[line for line in s.splitlines() if not (line.startswith("Module") and "load on device" in line)]
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
if filtered_s.strip():
|
|
209
|
+
self.test.fail(f"Unexpected output:\n'{s.rstrip()}'")
|
|
206
210
|
|
|
207
211
|
|
|
208
212
|
def assert_array_equal(result: wp.array, expect: wp.array):
|
warp/thirdparty/dlpack.py
CHANGED
|
@@ -58,6 +58,7 @@ class DLDataTypeCode(ctypes.c_uint8):
|
|
|
58
58
|
kDLOpaquePointer = 3
|
|
59
59
|
kDLBfloat = 4
|
|
60
60
|
kDLComplex = 5
|
|
61
|
+
kDLBool = 6
|
|
61
62
|
|
|
62
63
|
def __str__(self):
|
|
63
64
|
return {
|
|
@@ -66,6 +67,7 @@ class DLDataTypeCode(ctypes.c_uint8):
|
|
|
66
67
|
self.kDLFloat: "float",
|
|
67
68
|
self.kDLBfloat: "bfloat",
|
|
68
69
|
self.kDLComplex: "complex",
|
|
70
|
+
self.kDLBool: "bool",
|
|
69
71
|
self.kDLOpaquePointer: "void_p",
|
|
70
72
|
}[self.value]
|
|
71
73
|
|
|
@@ -85,7 +87,7 @@ class DLDataType(ctypes.Structure):
|
|
|
85
87
|
("lanes", ctypes.c_uint16),
|
|
86
88
|
]
|
|
87
89
|
TYPE_MAP = {
|
|
88
|
-
"bool": (DLDataTypeCode.
|
|
90
|
+
"bool": (DLDataTypeCode.kDLBool, 8, 1),
|
|
89
91
|
"int8": (DLDataTypeCode.kDLInt, 8, 1),
|
|
90
92
|
"int16": (DLDataTypeCode.kDLInt, 16, 1),
|
|
91
93
|
"int32": (DLDataTypeCode.kDLInt, 32, 1),
|
warp/types.py
CHANGED
|
@@ -66,8 +66,8 @@ def constant(x):
|
|
|
66
66
|
x: Compile-time constant value, can be any of the built-in math types.
|
|
67
67
|
"""
|
|
68
68
|
|
|
69
|
-
if not
|
|
70
|
-
raise
|
|
69
|
+
if not is_value(x):
|
|
70
|
+
raise TypeError(f"Invalid constant type: {type(x)}")
|
|
71
71
|
|
|
72
72
|
return x
|
|
73
73
|
|
|
@@ -237,6 +237,12 @@ def vector(length, dtype):
|
|
|
237
237
|
def __rtruediv__(self, x):
|
|
238
238
|
return warp.div(x, self)
|
|
239
239
|
|
|
240
|
+
def __mod__(self, x):
|
|
241
|
+
return warp.mod(self, x)
|
|
242
|
+
|
|
243
|
+
def __rmod__(self, x):
|
|
244
|
+
return warp.mod(x, self)
|
|
245
|
+
|
|
240
246
|
def __pos__(self):
|
|
241
247
|
return warp.pos(self)
|
|
242
248
|
|
|
@@ -519,6 +525,12 @@ class scalar_base:
|
|
|
519
525
|
def __rtruediv__(self, x):
|
|
520
526
|
return warp.div(x, self)
|
|
521
527
|
|
|
528
|
+
def __mod__(self, x):
|
|
529
|
+
return warp.mod(self, x)
|
|
530
|
+
|
|
531
|
+
def __rmod__(self, x):
|
|
532
|
+
return warp.mod(x, self)
|
|
533
|
+
|
|
522
534
|
def __pos__(self):
|
|
523
535
|
return warp.pos(self)
|
|
524
536
|
|
|
@@ -979,6 +991,43 @@ vector_types = (
|
|
|
979
991
|
spatial_matrixd,
|
|
980
992
|
)
|
|
981
993
|
|
|
994
|
+
atomic_vector_types = (
|
|
995
|
+
vec2i,
|
|
996
|
+
vec2ui,
|
|
997
|
+
vec2l,
|
|
998
|
+
vec2ul,
|
|
999
|
+
vec2h,
|
|
1000
|
+
vec2f,
|
|
1001
|
+
vec2d,
|
|
1002
|
+
vec3i,
|
|
1003
|
+
vec3ui,
|
|
1004
|
+
vec3l,
|
|
1005
|
+
vec3ul,
|
|
1006
|
+
vec3h,
|
|
1007
|
+
vec3f,
|
|
1008
|
+
vec3d,
|
|
1009
|
+
vec4i,
|
|
1010
|
+
vec4ui,
|
|
1011
|
+
vec4l,
|
|
1012
|
+
vec4ul,
|
|
1013
|
+
vec4h,
|
|
1014
|
+
vec4f,
|
|
1015
|
+
vec4d,
|
|
1016
|
+
mat22h,
|
|
1017
|
+
mat22f,
|
|
1018
|
+
mat22d,
|
|
1019
|
+
mat33h,
|
|
1020
|
+
mat33f,
|
|
1021
|
+
mat33d,
|
|
1022
|
+
mat44h,
|
|
1023
|
+
mat44f,
|
|
1024
|
+
mat44d,
|
|
1025
|
+
quath,
|
|
1026
|
+
quatf,
|
|
1027
|
+
quatd,
|
|
1028
|
+
)
|
|
1029
|
+
atomic_types = float_types + (int32, uint32, int64, uint64) + atomic_vector_types
|
|
1030
|
+
|
|
982
1031
|
np_dtype_to_warp_type = {
|
|
983
1032
|
# Numpy scalar types
|
|
984
1033
|
np.bool_: bool,
|
|
@@ -1253,7 +1302,7 @@ def type_to_warp(dtype):
|
|
|
1253
1302
|
|
|
1254
1303
|
def type_typestr(dtype):
|
|
1255
1304
|
if dtype == bool:
|
|
1256
|
-
return "
|
|
1305
|
+
return "|b1"
|
|
1257
1306
|
elif dtype == float16:
|
|
1258
1307
|
return "<f2"
|
|
1259
1308
|
elif dtype == float32:
|
|
@@ -1261,9 +1310,9 @@ def type_typestr(dtype):
|
|
|
1261
1310
|
elif dtype == float64:
|
|
1262
1311
|
return "<f8"
|
|
1263
1312
|
elif dtype == int8:
|
|
1264
|
-
return "
|
|
1313
|
+
return "|i1"
|
|
1265
1314
|
elif dtype == uint8:
|
|
1266
|
-
return "
|
|
1315
|
+
return "|u1"
|
|
1267
1316
|
elif dtype == int16:
|
|
1268
1317
|
return "<i2"
|
|
1269
1318
|
elif dtype == uint16:
|
|
@@ -1335,7 +1384,7 @@ value_types = (int, float, builtins.bool) + scalar_types
|
|
|
1335
1384
|
|
|
1336
1385
|
# returns true for all value types (int, float, bool, scalars, vectors, matrices)
|
|
1337
1386
|
def type_is_value(x):
|
|
1338
|
-
return x in value_types or
|
|
1387
|
+
return x in value_types or hasattr(x, "_wp_scalar_type_")
|
|
1339
1388
|
|
|
1340
1389
|
|
|
1341
1390
|
# equivalent of the above but for values
|
|
@@ -1442,6 +1491,10 @@ def types_equal(a, b, match_generic=False):
|
|
|
1442
1491
|
if is_array(a) and type(a) is type(b):
|
|
1443
1492
|
return True
|
|
1444
1493
|
|
|
1494
|
+
# match NewStructInstance and Struct dtype
|
|
1495
|
+
if getattr(a, "cls", "a") is getattr(b, "cls", "b"):
|
|
1496
|
+
return True
|
|
1497
|
+
|
|
1445
1498
|
return scalars_equal(a, b, match_generic)
|
|
1446
1499
|
|
|
1447
1500
|
|
|
@@ -1486,7 +1539,7 @@ def array_ctype_from_interface(interface: dict, dtype=None, owner=None):
|
|
|
1486
1539
|
strides = strides_from_shape(shape, element_dtype)
|
|
1487
1540
|
|
|
1488
1541
|
if dtype is None:
|
|
1489
|
-
# accept
|
|
1542
|
+
# accept verbatim
|
|
1490
1543
|
pass
|
|
1491
1544
|
elif hasattr(dtype, "_shape_"):
|
|
1492
1545
|
# vector/matrix types, ensure element dtype matches
|
|
@@ -1601,6 +1654,9 @@ class array(Array):
|
|
|
1601
1654
|
self._array_interface = None
|
|
1602
1655
|
self.is_transposed = False
|
|
1603
1656
|
|
|
1657
|
+
# reference to other array
|
|
1658
|
+
self._ref = None
|
|
1659
|
+
|
|
1604
1660
|
# canonicalize dtype
|
|
1605
1661
|
if dtype == int:
|
|
1606
1662
|
dtype = int32
|
|
@@ -1652,9 +1708,6 @@ class array(Array):
|
|
|
1652
1708
|
if requires_grad:
|
|
1653
1709
|
self._alloc_grad()
|
|
1654
1710
|
|
|
1655
|
-
# reference to other array
|
|
1656
|
-
self._ref = None
|
|
1657
|
-
|
|
1658
1711
|
def _init_from_data(self, data, dtype, shape, device, copy, pinned):
|
|
1659
1712
|
if not hasattr(data, "__len__"):
|
|
1660
1713
|
raise RuntimeError(f"Data must be a sequence or array, got scalar {data}")
|
|
@@ -2005,24 +2058,27 @@ class array(Array):
|
|
|
2005
2058
|
if self.device is None:
|
|
2006
2059
|
raise RuntimeError("Array has no device assigned")
|
|
2007
2060
|
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2061
|
+
# check if synchronization is needed
|
|
2062
|
+
if stream != -1:
|
|
2063
|
+
if self.device.is_cuda:
|
|
2064
|
+
# validate stream argument
|
|
2065
|
+
if stream is None:
|
|
2066
|
+
stream = 1 # legacy default stream
|
|
2067
|
+
elif not isinstance(stream, int) or stream < -1:
|
|
2068
|
+
raise TypeError("DLPack stream must None or an integer >= -1")
|
|
2069
|
+
|
|
2070
|
+
# assume that the array is being used on its device's current stream
|
|
2071
|
+
array_stream = self.device.stream
|
|
2072
|
+
|
|
2073
|
+
# Performance note: avoid wrapping the external stream in a temporary Stream object
|
|
2074
|
+
if stream != array_stream.cuda_stream:
|
|
2075
|
+
warp.context.runtime.core.cuda_stream_wait_stream(
|
|
2076
|
+
stream, array_stream.cuda_stream, array_stream.cached_event.cuda_event
|
|
2077
|
+
)
|
|
2078
|
+
elif self.device.is_cpu:
|
|
2079
|
+
# on CPU, stream must be None or -1
|
|
2080
|
+
if stream is not None:
|
|
2081
|
+
raise TypeError("DLPack stream must be None or -1 for CPU device")
|
|
2026
2082
|
|
|
2027
2083
|
return warp.dlpack.to_dlpack(self)
|
|
2028
2084
|
|
|
@@ -2991,7 +3047,7 @@ class Mesh:
|
|
|
2991
3047
|
|
|
2992
3048
|
Args:
|
|
2993
3049
|
points (:class:`warp.array`): Array of vertex positions of type :class:`warp.vec3`
|
|
2994
|
-
indices (:class:`warp.array`): Array of triangle indices of type :class:`warp.int32`, should be a 1d array with shape (num_tris
|
|
3050
|
+
indices (:class:`warp.array`): Array of triangle indices of type :class:`warp.int32`, should be a 1d array with shape (num_tris * 3)
|
|
2995
3051
|
velocities (:class:`warp.array`): Array of vertex velocities of type :class:`warp.vec3` (optional)
|
|
2996
3052
|
support_winding_number (bool): If true the mesh will build additional datastructures to support `wp.mesh_query_point_sign_winding_number()` queries
|
|
2997
3053
|
"""
|
|
@@ -3012,8 +3068,8 @@ class Mesh:
|
|
|
3012
3068
|
raise RuntimeError("Mesh indices should be a flattened 1d array of indices")
|
|
3013
3069
|
|
|
3014
3070
|
self.device = points.device
|
|
3015
|
-
self.
|
|
3016
|
-
self.
|
|
3071
|
+
self._points = points
|
|
3072
|
+
self._velocities = velocities
|
|
3017
3073
|
self.indices = indices
|
|
3018
3074
|
|
|
3019
3075
|
self.runtime = warp.context.runtime
|
|
@@ -3058,6 +3114,72 @@ class Mesh:
|
|
|
3058
3114
|
self.runtime.core.mesh_refit_device(self.id)
|
|
3059
3115
|
self.runtime.verify_cuda_device(self.device)
|
|
3060
3116
|
|
|
3117
|
+
@property
|
|
3118
|
+
def points(self):
|
|
3119
|
+
"""The array of mesh's vertex positions of type :class:`warp.vec3`.
|
|
3120
|
+
|
|
3121
|
+
The `Mesh.points` property has a custom setter method. Users can modify the vertex positions in-place,
|
|
3122
|
+
but the `refit()` method must be called manually after such modifications. Alternatively, assigning a new array
|
|
3123
|
+
to this property is also supported. The new array must have the same shape as the original, and once assigned,
|
|
3124
|
+
the `Mesh` class will automatically perform a refit operation based on the new vertex positions.
|
|
3125
|
+
"""
|
|
3126
|
+
return self._points
|
|
3127
|
+
|
|
3128
|
+
@points.setter
|
|
3129
|
+
def points(self, points_new):
|
|
3130
|
+
if points_new.device != self._points.device:
|
|
3131
|
+
raise RuntimeError(
|
|
3132
|
+
"The new points and the original points must live on the same device, currently "
|
|
3133
|
+
"the new points lives on {} while the old points lives on {}.".format(
|
|
3134
|
+
points_new.device, self._points.device
|
|
3135
|
+
)
|
|
3136
|
+
)
|
|
3137
|
+
|
|
3138
|
+
if points_new.ndim != 1 or points_new.shape[0] != self._points.shape[0]:
|
|
3139
|
+
raise RuntimeError(
|
|
3140
|
+
"the new points and the original points must have the same shape, currently new points shape is: {},"
|
|
3141
|
+
" while the old points' shape is: {}".format(points_new.shape, self._points.shape)
|
|
3142
|
+
)
|
|
3143
|
+
|
|
3144
|
+
self._points = points_new
|
|
3145
|
+
if self.device.is_cpu:
|
|
3146
|
+
self.runtime.core.mesh_set_points_host(self.id, points_new.__ctype__())
|
|
3147
|
+
else:
|
|
3148
|
+
self.runtime.core.mesh_set_points_device(self.id, points_new.__ctype__())
|
|
3149
|
+
self.runtime.verify_cuda_device(self.device)
|
|
3150
|
+
|
|
3151
|
+
@property
|
|
3152
|
+
def velocities(self):
|
|
3153
|
+
"""The array of mesh's velocities of type :class:`warp.vec3`.
|
|
3154
|
+
|
|
3155
|
+
This is a property with a custom setter method. Users can modify the velocities in-place,
|
|
3156
|
+
or assigning a new array to this property. No refitting is needed for changing velocities.
|
|
3157
|
+
"""
|
|
3158
|
+
return self._velocities
|
|
3159
|
+
|
|
3160
|
+
@velocities.setter
|
|
3161
|
+
def velocities(self, velocities_new):
|
|
3162
|
+
if velocities_new.device != self._velocities.device:
|
|
3163
|
+
raise RuntimeError(
|
|
3164
|
+
"The new points and the original points must live on the same device, currently "
|
|
3165
|
+
"the new points lives on {} while the old points lives on {}.".format(
|
|
3166
|
+
velocities_new.device, self._velocities.device
|
|
3167
|
+
)
|
|
3168
|
+
)
|
|
3169
|
+
|
|
3170
|
+
if velocities_new.ndim != 1 or velocities_new.shape[0] != self._velocities.shape[0]:
|
|
3171
|
+
raise RuntimeError(
|
|
3172
|
+
"the new points and the original points must have the same shape, currently new points shape is: {},"
|
|
3173
|
+
" while the old points' shape is: {}".format(velocities_new.shape, self._velocities.shape)
|
|
3174
|
+
)
|
|
3175
|
+
|
|
3176
|
+
self._velocities = velocities_new
|
|
3177
|
+
if self.device.is_cpu:
|
|
3178
|
+
self.runtime.core.mesh_set_velocities_host(self.id, velocities_new.__ctype__())
|
|
3179
|
+
else:
|
|
3180
|
+
self.runtime.core.mesh_set_velocities_device(self.id, velocities_new.__ctype__())
|
|
3181
|
+
self.runtime.verify_cuda_device(self.device)
|
|
3182
|
+
|
|
3061
3183
|
|
|
3062
3184
|
class Volume:
|
|
3063
3185
|
#: Enum value to specify nearest-neighbor interpolation during sampling
|
|
@@ -3529,8 +3651,9 @@ class Volume:
|
|
|
3529
3651
|
)
|
|
3530
3652
|
if hasattr(bg_value, "__len__"):
|
|
3531
3653
|
# vec3, assuming the numpy array is 4D
|
|
3532
|
-
padded_array = np.
|
|
3533
|
-
|
|
3654
|
+
padded_array = np.full(
|
|
3655
|
+
shape=(target_shape[0], target_shape[1], target_shape[2], 3), fill_value=bg_value, dtype=np.single
|
|
3656
|
+
)
|
|
3534
3657
|
padded_array[0 : ndarray.shape[0], 0 : ndarray.shape[1], 0 : ndarray.shape[2], :] = ndarray
|
|
3535
3658
|
else:
|
|
3536
3659
|
padded_amount = (
|
|
@@ -5024,7 +5147,7 @@ def get_type_code(arg_type):
|
|
|
5024
5147
|
elif isinstance(arg_type, indexedfabricarray):
|
|
5025
5148
|
return f"ifa{arg_type.ndim}{get_type_code(arg_type.dtype)}"
|
|
5026
5149
|
elif isinstance(arg_type, warp.codegen.Struct):
|
|
5027
|
-
return
|
|
5150
|
+
return arg_type.native_name
|
|
5028
5151
|
elif arg_type == Scalar:
|
|
5029
5152
|
# generic scalar type
|
|
5030
5153
|
return "s?"
|