warp-lang 1.3.3__py3-none-manylinux2014_x86_64.whl → 1.4.0__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.
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 +188 -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/unittest_suites.py +12 -0
- warp/tests/unittest_utils.py +9 -5
- warp/thirdparty/dlpack.py +3 -1
- warp/types.py +150 -28
- warp/utils.py +37 -14
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.0.dist-info}/METADATA +10 -8
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.0.dist-info}/RECORD +105 -93
- warp/tests/test_point_triangle_closest_point.py +0 -143
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.3.3.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/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
|
|
@@ -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
|
|
|
@@ -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
|
|
@@ -5025,7 +5147,7 @@ def get_type_code(arg_type):
|
|
|
5025
5147
|
elif isinstance(arg_type, indexedfabricarray):
|
|
5026
5148
|
return f"ifa{arg_type.ndim}{get_type_code(arg_type.dtype)}"
|
|
5027
5149
|
elif isinstance(arg_type, warp.codegen.Struct):
|
|
5028
|
-
return
|
|
5150
|
+
return arg_type.native_name
|
|
5029
5151
|
elif arg_type == Scalar:
|
|
5030
5152
|
# generic scalar type
|
|
5031
5153
|
return "s?"
|
warp/utils.py
CHANGED
|
@@ -11,7 +11,7 @@ import os
|
|
|
11
11
|
import sys
|
|
12
12
|
import time
|
|
13
13
|
import warnings
|
|
14
|
-
from typing import Any
|
|
14
|
+
from typing import Any, Optional
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
|
|
@@ -578,7 +578,32 @@ class ScopedDevice:
|
|
|
578
578
|
|
|
579
579
|
|
|
580
580
|
class ScopedStream:
|
|
581
|
-
|
|
581
|
+
"""A context manager to temporarily change the current stream on a device.
|
|
582
|
+
|
|
583
|
+
Attributes:
|
|
584
|
+
stream (Stream or None): The stream that will temporarily become the device's
|
|
585
|
+
default stream within the context.
|
|
586
|
+
saved_stream (Stream): The device's previous current stream. This is
|
|
587
|
+
restored as the device's current stream on exiting the context.
|
|
588
|
+
sync_enter (bool): Whether to synchronize this context's stream with
|
|
589
|
+
the device's previous current stream on entering the context.
|
|
590
|
+
sync_exit (bool): Whether to synchronize the device's previous current
|
|
591
|
+
with this context's stream on exiting the context.
|
|
592
|
+
device (Device): The device associated with the stream.
|
|
593
|
+
"""
|
|
594
|
+
|
|
595
|
+
def __init__(self, stream: Optional[wp.Stream], sync_enter: bool = True, sync_exit: bool = False):
|
|
596
|
+
"""Initializes the context manager with a stream and synchronization options.
|
|
597
|
+
|
|
598
|
+
Args:
|
|
599
|
+
stream: The stream that will temporarily become the device's
|
|
600
|
+
default stream within the context.
|
|
601
|
+
sync_enter (bool): Whether to synchronize this context's stream with
|
|
602
|
+
the device's previous current stream on entering the context.
|
|
603
|
+
sync_exit (bool): Whether to synchronize the device's previous current
|
|
604
|
+
with this context's stream on exiting the context.
|
|
605
|
+
"""
|
|
606
|
+
|
|
582
607
|
self.stream = stream
|
|
583
608
|
self.sync_enter = sync_enter
|
|
584
609
|
self.sync_exit = sync_exit
|
|
@@ -832,16 +857,22 @@ for T in [wp.float16, wp.float32, wp.float64]:
|
|
|
832
857
|
wp.overload(add_kernel_3d, [wp.array3d(dtype=T), wp.array3d(dtype=T), T])
|
|
833
858
|
|
|
834
859
|
|
|
835
|
-
def
|
|
836
|
-
"""Check if
|
|
860
|
+
def check_p2p():
|
|
861
|
+
"""Check if the machine is configured properly for peer-to-peer transfers.
|
|
837
862
|
|
|
838
863
|
Returns:
|
|
839
|
-
A Boolean indicating whether
|
|
864
|
+
A Boolean indicating whether the machine is configured properly for peer-to-peer transfers.
|
|
840
865
|
On Linux, this function attempts to determine if IOMMU is enabled and will return `False` if IOMMU is detected.
|
|
841
866
|
On other operating systems, it always return `True`.
|
|
842
867
|
"""
|
|
843
868
|
|
|
869
|
+
# HACK: allow disabling P2P tests using an environment variable
|
|
870
|
+
disable_p2p_tests = os.getenv("WARP_DISABLE_P2P_TESTS", default="0")
|
|
871
|
+
if int(disable_p2p_tests):
|
|
872
|
+
return False
|
|
873
|
+
|
|
844
874
|
if sys.platform == "linux":
|
|
875
|
+
# IOMMU enablement can affect peer-to-peer transfers.
|
|
845
876
|
# On modern Linux, there should be IOMMU-related entries in the /sys file system.
|
|
846
877
|
# This should be more reliable than checking kernel logs like dmesg.
|
|
847
878
|
if os.path.isdir("/sys/class/iommu") and os.listdir("/sys/class/iommu"):
|
|
@@ -849,15 +880,7 @@ def check_iommu():
|
|
|
849
880
|
if os.path.isdir("/sys/kernel/iommu_groups") and os.listdir("/sys/kernel/iommu_groups"):
|
|
850
881
|
return False
|
|
851
882
|
|
|
852
|
-
|
|
853
|
-
disable_p2p_tests = os.getenv("WARP_DISABLE_P2P_TESTS", default="0")
|
|
854
|
-
if int(disable_p2p_tests):
|
|
855
|
-
return False
|
|
856
|
-
|
|
857
|
-
return True
|
|
858
|
-
else:
|
|
859
|
-
# doesn't matter
|
|
860
|
-
return True
|
|
883
|
+
return True
|
|
861
884
|
|
|
862
885
|
|
|
863
886
|
class timing_result_t(ctypes.Structure):
|