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.

Files changed (107) hide show
  1. warp/__init__.py +6 -0
  2. warp/autograd.py +59 -6
  3. warp/bin/warp.so +0 -0
  4. warp/build_dll.py +8 -10
  5. warp/builtins.py +126 -4
  6. warp/codegen.py +435 -53
  7. warp/config.py +1 -1
  8. warp/context.py +678 -403
  9. warp/dlpack.py +2 -0
  10. warp/examples/benchmarks/benchmark_cloth.py +10 -0
  11. warp/examples/core/example_render_opengl.py +12 -10
  12. warp/examples/fem/example_adaptive_grid.py +251 -0
  13. warp/examples/fem/example_apic_fluid.py +1 -1
  14. warp/examples/fem/example_diffusion_3d.py +2 -2
  15. warp/examples/fem/example_magnetostatics.py +1 -1
  16. warp/examples/fem/example_streamlines.py +1 -0
  17. warp/examples/fem/utils.py +23 -4
  18. warp/examples/sim/example_cloth.py +50 -6
  19. warp/fem/__init__.py +2 -0
  20. warp/fem/adaptivity.py +493 -0
  21. warp/fem/field/field.py +2 -1
  22. warp/fem/field/nodal_field.py +18 -26
  23. warp/fem/field/test.py +4 -4
  24. warp/fem/field/trial.py +4 -4
  25. warp/fem/geometry/__init__.py +1 -0
  26. warp/fem/geometry/adaptive_nanogrid.py +843 -0
  27. warp/fem/geometry/nanogrid.py +55 -28
  28. warp/fem/space/__init__.py +1 -1
  29. warp/fem/space/nanogrid_function_space.py +69 -35
  30. warp/fem/utils.py +113 -107
  31. warp/jax_experimental.py +28 -15
  32. warp/native/array.h +0 -1
  33. warp/native/builtin.h +103 -6
  34. warp/native/bvh.cu +2 -0
  35. warp/native/cuda_util.cpp +14 -0
  36. warp/native/cuda_util.h +2 -0
  37. warp/native/error.cpp +4 -2
  38. warp/native/exports.h +99 -17
  39. warp/native/mat.h +97 -0
  40. warp/native/mesh.cpp +36 -0
  41. warp/native/mesh.cu +51 -0
  42. warp/native/mesh.h +1 -0
  43. warp/native/quat.h +43 -0
  44. warp/native/spatial.h +6 -0
  45. warp/native/vec.h +74 -0
  46. warp/native/warp.cpp +2 -1
  47. warp/native/warp.cu +10 -3
  48. warp/native/warp.h +8 -1
  49. warp/paddle.py +382 -0
  50. warp/sim/__init__.py +1 -0
  51. warp/sim/collide.py +519 -0
  52. warp/sim/integrator_euler.py +18 -5
  53. warp/sim/integrator_featherstone.py +5 -5
  54. warp/sim/integrator_vbd.py +1026 -0
  55. warp/sim/model.py +49 -23
  56. warp/stubs.py +459 -0
  57. warp/tape.py +2 -0
  58. warp/tests/aux_test_dependent.py +1 -0
  59. warp/tests/aux_test_name_clash1.py +32 -0
  60. warp/tests/aux_test_name_clash2.py +32 -0
  61. warp/tests/aux_test_square.py +1 -0
  62. warp/tests/test_array.py +222 -0
  63. warp/tests/test_async.py +3 -3
  64. warp/tests/test_atomic.py +6 -0
  65. warp/tests/test_closest_point_edge_edge.py +93 -1
  66. warp/tests/test_codegen.py +62 -15
  67. warp/tests/test_codegen_instancing.py +1457 -0
  68. warp/tests/test_collision.py +486 -0
  69. warp/tests/test_compile_consts.py +3 -28
  70. warp/tests/test_dlpack.py +170 -0
  71. warp/tests/test_examples.py +22 -8
  72. warp/tests/test_fast_math.py +10 -4
  73. warp/tests/test_fem.py +64 -0
  74. warp/tests/test_func.py +46 -0
  75. warp/tests/test_implicit_init.py +49 -0
  76. warp/tests/test_jax.py +58 -0
  77. warp/tests/test_mat.py +84 -0
  78. warp/tests/test_mesh_query_point.py +188 -0
  79. warp/tests/test_module_hashing.py +40 -0
  80. warp/tests/test_multigpu.py +3 -3
  81. warp/tests/test_overwrite.py +8 -0
  82. warp/tests/test_paddle.py +852 -0
  83. warp/tests/test_print.py +89 -0
  84. warp/tests/test_quat.py +111 -0
  85. warp/tests/test_reload.py +31 -1
  86. warp/tests/test_scalar_ops.py +2 -0
  87. warp/tests/test_static.py +412 -0
  88. warp/tests/test_streams.py +64 -3
  89. warp/tests/test_struct.py +4 -4
  90. warp/tests/test_torch.py +24 -0
  91. warp/tests/test_triangle_closest_point.py +137 -0
  92. warp/tests/test_types.py +1 -1
  93. warp/tests/test_vbd.py +386 -0
  94. warp/tests/test_vec.py +143 -0
  95. warp/tests/test_vec_scalar_ops.py +139 -0
  96. warp/tests/test_volume.py +30 -0
  97. warp/tests/unittest_suites.py +12 -0
  98. warp/tests/unittest_utils.py +9 -5
  99. warp/thirdparty/dlpack.py +3 -1
  100. warp/types.py +157 -34
  101. warp/utils.py +37 -14
  102. {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/METADATA +10 -8
  103. {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/RECORD +106 -94
  104. warp/tests/test_point_triangle_closest_point.py +0 -143
  105. {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/LICENSE.md +0 -0
  106. {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/WHEEL +0 -0
  107. {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
  )
@@ -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,
@@ -198,11 +198,15 @@ class CheckOutput:
198
198
  if s != "":
199
199
  print(s.rstrip())
200
200
 
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
- if s != "" and not s.startswith("Module"):
205
- self.test.fail(f"Unexpected output:\n'{s.rstrip()}'")
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.kDLUInt, 1, 1),
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 isinstance(x, (builtins.bool, int, float, tuple(scalar_and_bool_types), ctypes.Array)):
70
- raise RuntimeError(f"Invalid constant type: {type(x)}")
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 "b"
1313
+ return "|i1"
1265
1314
  elif dtype == uint8:
1266
- return "B"
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 issubclass(x, ctypes.Array)
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 verbatum
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
- if self.device.is_cuda and stream != -1:
2009
- if not isinstance(stream, int):
2010
- raise TypeError("DLPack stream must be an integer or None")
2011
-
2012
- # assume that the array is being used on its device's current stream
2013
- array_stream = self.device.stream
2014
-
2015
- # the external stream should wait for outstanding operations to complete
2016
- if stream in (None, 0, 1):
2017
- external_stream = 0
2018
- else:
2019
- external_stream = stream
2020
-
2021
- # Performance note: avoid wrapping the external stream in a temporary Stream object
2022
- if external_stream != array_stream.cuda_stream:
2023
- warp.context.runtime.core.cuda_stream_wait_stream(
2024
- external_stream, array_stream.cuda_stream, array_stream.cached_event.cuda_event
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, 3)
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.points = points
3016
- self.velocities = velocities
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.array((target_shape[0], target_shape[1], target_shape[2], 3), dtype=np.single)
3533
- padded_array[:, :, :, :] = np.array(bg_value)
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 warp.codegen.make_full_qualified_name(arg_type.cls)
5150
+ return arg_type.native_name
5028
5151
  elif arg_type == Scalar:
5029
5152
  # generic scalar type
5030
5153
  return "s?"