warp-lang 1.7.0__py3-none-manylinux_2_34_aarch64.whl → 1.7.2__py3-none-manylinux_2_34_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 (60) hide show
  1. warp/autograd.py +12 -2
  2. warp/bin/warp-clang.so +0 -0
  3. warp/bin/warp.so +0 -0
  4. warp/build.py +1 -1
  5. warp/builtins.py +103 -66
  6. warp/codegen.py +48 -27
  7. warp/config.py +1 -1
  8. warp/context.py +112 -49
  9. warp/examples/benchmarks/benchmark_cloth.py +1 -1
  10. warp/examples/distributed/example_jacobi_mpi.py +507 -0
  11. warp/fem/cache.py +1 -1
  12. warp/fem/field/field.py +11 -1
  13. warp/fem/field/nodal_field.py +36 -22
  14. warp/fem/geometry/adaptive_nanogrid.py +7 -3
  15. warp/fem/geometry/trimesh.py +4 -12
  16. warp/jax_experimental/custom_call.py +14 -2
  17. warp/jax_experimental/ffi.py +100 -67
  18. warp/native/builtin.h +91 -65
  19. warp/native/svd.h +59 -49
  20. warp/native/tile.h +55 -26
  21. warp/native/volume.cpp +2 -2
  22. warp/native/volume_builder.cu +33 -22
  23. warp/native/warp.cu +1 -1
  24. warp/render/render_opengl.py +41 -34
  25. warp/render/render_usd.py +96 -6
  26. warp/sim/collide.py +11 -9
  27. warp/sim/inertia.py +189 -156
  28. warp/sim/integrator_euler.py +3 -0
  29. warp/sim/integrator_xpbd.py +3 -0
  30. warp/sim/model.py +56 -31
  31. warp/sim/render.py +4 -0
  32. warp/sparse.py +1 -1
  33. warp/stubs.py +73 -25
  34. warp/tests/assets/torus.usda +1 -1
  35. warp/tests/cuda/test_streams.py +1 -1
  36. warp/tests/sim/test_collision.py +237 -206
  37. warp/tests/sim/test_inertia.py +161 -0
  38. warp/tests/sim/test_model.py +5 -3
  39. warp/tests/sim/{flaky_test_sim_grad.py → test_sim_grad.py} +1 -4
  40. warp/tests/sim/test_xpbd.py +399 -0
  41. warp/tests/test_array.py +8 -7
  42. warp/tests/test_atomic.py +181 -2
  43. warp/tests/test_builtins_resolution.py +38 -38
  44. warp/tests/test_codegen.py +24 -3
  45. warp/tests/test_examples.py +16 -6
  46. warp/tests/test_fem.py +93 -14
  47. warp/tests/test_func.py +1 -1
  48. warp/tests/test_mat.py +416 -119
  49. warp/tests/test_quat.py +321 -137
  50. warp/tests/test_struct.py +116 -0
  51. warp/tests/test_vec.py +320 -174
  52. warp/tests/tile/test_tile.py +27 -0
  53. warp/tests/tile/test_tile_load.py +124 -0
  54. warp/tests/unittest_suites.py +2 -5
  55. warp/types.py +107 -9
  56. {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/METADATA +41 -19
  57. {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/RECORD +60 -57
  58. {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/WHEEL +1 -1
  59. {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/licenses/LICENSE.md +0 -26
  60. {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/top_level.txt +0 -0
warp/tests/test_mat.py CHANGED
@@ -50,6 +50,22 @@ def get_select_kernel(dtype):
50
50
  return getkernel(output_select_kernel_fn, suffix=dtype.__name__)
51
51
 
52
52
 
53
+ def test_shape_mismatch(test, device):
54
+ test.assertNotEqual(wp.mat33f(0.0), wp.mat22f(0.0))
55
+ test.assertNotEqual(wp.mat22f(0.0), wp.mat33f(0.0))
56
+
57
+ @wp.kernel
58
+ def kernel():
59
+ wp.expect_neq(wp.mat33f(0.0), wp.mat22f(0.0))
60
+ wp.expect_neq(wp.mat22f(0.0), wp.mat33f(0.0))
61
+
62
+ with test.assertRaisesRegex(
63
+ RuntimeError,
64
+ r"Can't test equality for objects with different types$",
65
+ ):
66
+ wp.launch(kernel, dim=1, inputs=[], device=device)
67
+
68
+
53
69
  def test_anon_constructor_error_shape_arg_missing(test, device):
54
70
  @wp.kernel
55
71
  def kernel():
@@ -1062,15 +1078,21 @@ def test_svd_2D(test, device, dtype, register_kernels=False):
1062
1078
  Vout: wp.array(dtype=mat22),
1063
1079
  outcomponents: wp.array(dtype=wptype),
1064
1080
  ):
1081
+ tid = wp.tid()
1082
+
1065
1083
  U = mat22()
1066
1084
  sigma = vec2()
1067
1085
  V = mat22()
1068
1086
 
1069
- wp.svd2(m2[0], U, sigma, V) # Assuming there's a 2D SVD kernel
1087
+ wp.svd2(m2[tid], U, sigma, V) # Assuming there's a 2D SVD kernel
1070
1088
 
1071
- Uout[0] = U
1072
- sigmaout[0] = sigma
1073
- Vout[0] = V
1089
+ Uout[tid] = U
1090
+ sigmaout[tid] = sigma
1091
+ Vout[tid] = V
1092
+
1093
+ # backprop test only for first input
1094
+ if tid > 0:
1095
+ return
1074
1096
 
1075
1097
  # multiply outputs by 2 so we've got something to backpropagate:
1076
1098
  idx = 0
@@ -1095,22 +1117,46 @@ def test_svd_2D(test, device, dtype, register_kernels=False):
1095
1117
  if register_kernels:
1096
1118
  return
1097
1119
 
1098
- m2 = wp.array(randvals(rng, [1, 2, 2], dtype) + np.eye(2), dtype=mat22, requires_grad=True, device=device)
1120
+ mats = np.concatenate(
1121
+ (
1122
+ randvals(rng, [24, 2, 2], dtype) + np.eye(2),
1123
+ # rng unlikely to hit edge cases, build them manually
1124
+ [
1125
+ np.zeros((2, 2)),
1126
+ np.eye(2),
1127
+ 5.0 * np.eye(2),
1128
+ np.array([[1.0, 0.0], [0.0, 0.0]]),
1129
+ np.array([[0.0, 0.0], [0.0, 2.0]]),
1130
+ np.array([[1.0, 1.0], [-1.0, -1.0]]),
1131
+ np.array([[3.0, 0.0], [4.0, 5.0]]),
1132
+ np.eye(2) + tol * np.array([[1.0, 1.0], [-1.0, -1.0]]),
1133
+ ],
1134
+ ),
1135
+ axis=0,
1136
+ )
1137
+ M = len(mats)
1138
+ m2 = wp.array(mats, dtype=mat22, requires_grad=True, device=device)
1099
1139
 
1100
1140
  outcomponents = wp.zeros(2 * 2 * 2 + 2, dtype=wptype, requires_grad=True, device=device)
1101
- Uout = wp.zeros(1, dtype=mat22, requires_grad=True, device=device)
1102
- sigmaout = wp.zeros(1, dtype=vec2, requires_grad=True, device=device)
1103
- Vout = wp.zeros(1, dtype=mat22, requires_grad=True, device=device)
1141
+ Uout = wp.zeros(M, dtype=mat22, requires_grad=True, device=device)
1142
+ sigmaout = wp.zeros(M, dtype=vec2, requires_grad=True, device=device)
1143
+ Vout = wp.zeros(M, dtype=mat22, requires_grad=True, device=device)
1104
1144
 
1105
- wp.launch(kernel, dim=1, inputs=[m2], outputs=[Uout, sigmaout, Vout, outcomponents], device=device)
1145
+ wp.launch(kernel, dim=M, inputs=[m2], outputs=[Uout, sigmaout, Vout, outcomponents], device=device)
1106
1146
 
1107
- Uout_np = Uout.numpy()[0].astype(np.float64)
1108
- sigmaout_np = np.diag(sigmaout.numpy()[0].astype(np.float64))
1109
- Vout_np = Vout.numpy()[0].astype(np.float64)
1147
+ Uout_np = Uout.numpy().astype(np.float64)
1148
+ sigmaout_np = sigmaout.numpy().astype(np.float64)
1149
+ Vout_np = Vout.numpy().astype(np.float64)
1150
+
1151
+ USVt_np = Uout_np @ (sigmaout_np[..., None] * np.transpose(Vout_np, axes=(0, 2, 1)))
1110
1152
 
1111
1153
  assert_np_equal(
1112
- np.matmul(Uout_np, np.matmul(sigmaout_np, Vout_np.T)), m2.numpy()[0].astype(np.float64), tol=30 * tol
1154
+ Uout_np @ np.transpose(Uout_np, axes=(0, 2, 1)), np.broadcast_to(np.eye(2), shape=(M, 2, 2)), tol=30 * tol
1113
1155
  )
1156
+ assert_np_equal(
1157
+ Vout_np @ np.transpose(Vout_np, axes=(0, 2, 1)), np.broadcast_to(np.eye(2), shape=(M, 2, 2)), tol=30 * tol
1158
+ )
1159
+ assert_np_equal(USVt_np, m2.numpy().astype(np.float64), tol=30 * tol)
1114
1160
 
1115
1161
  if dtype == np.float16:
1116
1162
  # Skip gradient check for float16 due to rounding errors
@@ -1129,7 +1175,7 @@ def test_svd_2D(test, device, dtype, register_kernels=False):
1129
1175
 
1130
1176
  tape.zero()
1131
1177
 
1132
- dx = 0.0001
1178
+ dx = 0.001
1133
1179
  fdtol = 5.0e-4 if dtype == np.float64 else 2.0e-2
1134
1180
  for ii in range(2):
1135
1181
  for jj in range(2):
@@ -1164,9 +1210,9 @@ def test_qr(test, device, dtype, register_kernels=False):
1164
1210
  rng = np.random.default_rng(123)
1165
1211
 
1166
1212
  tol = {
1167
- np.float16: 2.0e-3,
1213
+ np.float16: 2.5e-3,
1168
1214
  np.float32: 1.0e-6,
1169
- np.float64: 1.0e-6,
1215
+ np.float64: 1.0e-12,
1170
1216
  }.get(dtype, 0)
1171
1217
 
1172
1218
  wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)]
@@ -1607,60 +1653,6 @@ def test_transform_vector(test, device, dtype, register_kernels=False):
1607
1653
  tape.zero()
1608
1654
 
1609
1655
 
1610
- def test_matrix_assign_inplace(test, device, dtype, register_kernels=False):
1611
- np_type = np.dtype(dtype)
1612
- wp_type = wp.types.np_dtype_to_warp_type[np_type]
1613
-
1614
- vec2 = wp.types.vector(length=2, dtype=wp_type)
1615
- mat22 = wp.types.matrix(shape=(2, 2), dtype=wp_type)
1616
-
1617
- def mattest_read_write_store(x: wp.array(dtype=wp_type), a: wp.array(dtype=mat22)):
1618
- tid = wp.tid()
1619
-
1620
- t = a[tid]
1621
- t[0, 0] = x[tid]
1622
- a[tid] = t
1623
-
1624
- def mattest_in_register(x: wp.array2d(dtype=mat22), y: wp.array(dtype=vec2)):
1625
- i, j = wp.tid()
1626
-
1627
- a = mat22(wp_type(0.0))
1628
- a[0] = y[i]
1629
- a[1, 1] = wp_type(3.0)
1630
- x[i, j] = a
1631
-
1632
- kernel_read_write_store = getkernel(mattest_read_write_store, suffix=dtype.__name__)
1633
- kernel_in_register = getkernel(mattest_in_register, suffix=dtype.__name__)
1634
-
1635
- if register_kernels:
1636
- return
1637
-
1638
- a = wp.ones(1, dtype=mat22, device=device, requires_grad=True)
1639
- x = wp.full(1, value=2.0, dtype=wp_type, device=device, requires_grad=True)
1640
-
1641
- tape = wp.Tape()
1642
- with tape:
1643
- wp.launch(kernel_read_write_store, dim=1, inputs=[x, a], device=device)
1644
-
1645
- tape.backward(grads={a: wp.ones_like(a, requires_grad=False)})
1646
-
1647
- assert_np_equal(a.numpy(), np.array([[[2.0, 1.0], [1.0, 1.0]]], dtype=np_type))
1648
- assert_np_equal(x.grad.numpy(), np.array([1.0], dtype=np_type))
1649
-
1650
- tape.reset()
1651
-
1652
- x = wp.zeros((1, 1), dtype=mat22, device=device, requires_grad=True)
1653
- y = wp.ones(1, dtype=vec2, device=device, requires_grad=True)
1654
-
1655
- with tape:
1656
- wp.launch(kernel_in_register, dim=(1, 1), inputs=[x, y], device=device)
1657
-
1658
- tape.backward(grads={x: wp.ones_like(x, requires_grad=False)})
1659
-
1660
- assert_np_equal(x.numpy(), np.array([[[[1.0, 1.0], [0.0, 3.0]]]], dtype=np_type))
1661
- assert_np_equal(y.grad.numpy(), np.array([[1.0, 1.0]], dtype=np_type))
1662
-
1663
-
1664
1656
  # Test matrix constructors using explicit type (float16)
1665
1657
  # note that these tests are specifically not using generics / closure
1666
1658
  # args to create kernels dynamically (like the rest of this file)
@@ -1694,6 +1686,7 @@ def test_matrix_constructor_value_func():
1694
1686
  c = mat32d()
1695
1687
  d = mat32d(c, shape=(3, 2))
1696
1688
  e = mat32d(wp.float64(1.0), wp.float64(2.0), wp.float64(1.0), wp.float64(2.0), wp.float64(1.0), wp.float64(2.0))
1689
+ f = wp.matrix(1.0, 2.0, 3.0, 4.0, shape=(2, 2), dtype=float)
1697
1690
 
1698
1691
 
1699
1692
  @wp.kernel
@@ -1864,63 +1857,105 @@ def test_matrix_len(test, device):
1864
1857
 
1865
1858
 
1866
1859
  @wp.kernel
1867
- def matrix_augassign_kernel(
1868
- a: wp.array(dtype=wp.mat22),
1869
- b: wp.array(dtype=wp.mat22),
1870
- x: wp.array(dtype=wp.vec2),
1871
- c: wp.array(dtype=wp.mat22),
1872
- d: wp.array(dtype=wp.mat22),
1873
- y: wp.array(dtype=wp.vec2),
1874
- ):
1875
- i = wp.tid()
1860
+ def mat_extract_element(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=float)):
1861
+ tid = wp.tid()
1862
+
1863
+ a = x[tid]
1864
+ b = a[0, 0] + 2.0 * a[0, 1] + 3.0 * a[1, 0] + 4.0 * a[1, 1]
1865
+ y[tid] = b
1876
1866
 
1877
- m1 = wp.mat22()
1878
- m2 = b[i]
1879
- v2 = x[i]
1880
1867
 
1881
- m1[0] += v2
1882
- m1[1, 0] += m2[1, 0]
1883
- m1[1, 1] += m2[1, 1]
1868
+ @wp.kernel
1869
+ def mat_extract_row(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.vec2)):
1870
+ tid = wp.tid()
1871
+
1872
+ a = x[tid]
1873
+ b = a[0] + 2.0 * a[1]
1874
+ y[tid] = b
1875
+
1876
+
1877
+ def test_mat_extract(test, device):
1878
+ # matrix element
1879
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
1880
+ y = wp.zeros(1, dtype=float, requires_grad=True, device=device)
1881
+
1882
+ tape = wp.Tape()
1883
+ with tape:
1884
+ wp.launch(mat_extract_element, 1, inputs=[x], outputs=[y], device=device)
1884
1885
 
1885
- a[i] = m1
1886
+ y.grad = wp.ones_like(y)
1887
+ tape.backward()
1886
1888
 
1887
- m3 = wp.mat22()
1888
- m4 = d[i]
1889
- v4 = y[i]
1889
+ assert_np_equal(y.numpy(), np.array([10.0], dtype=float))
1890
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=float))
1890
1891
 
1891
- m3[0] -= v4
1892
- m3[1, 0] -= m4[1, 0]
1893
- m3[1, 1] -= m4[1, 1]
1892
+ # matrix row
1893
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
1894
+ y = wp.zeros(1, dtype=wp.vec2, requires_grad=True, device=device)
1894
1895
 
1895
- c[i] = m3
1896
+ tape = wp.Tape()
1897
+ with tape:
1898
+ wp.launch(mat_extract_row, 1, inputs=[x], outputs=[y], device=device)
1896
1899
 
1900
+ y.grad = wp.ones_like(y)
1901
+ tape.backward()
1897
1902
 
1898
- def test_matrix_augassign(test, device):
1899
- N = 1
1903
+ assert_np_equal(y.numpy(), np.array([[3.0, 3.0]], dtype=float))
1904
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 1.0], [2.0, 2.0]]], dtype=float))
1900
1905
 
1901
- a = wp.zeros(N, dtype=wp.mat22, requires_grad=True, device=device)
1902
- b = wp.ones(N, dtype=wp.mat22, requires_grad=True, device=device)
1903
- x = wp.ones(N, dtype=wp.vec2, requires_grad=True, device=device)
1904
1906
 
1905
- c = wp.zeros(N, dtype=wp.mat22, requires_grad=True, device=device)
1906
- d = wp.ones(N, dtype=wp.mat22, requires_grad=True, device=device)
1907
- y = wp.ones(N, dtype=wp.vec2, requires_grad=True, device=device)
1907
+ @wp.kernel
1908
+ def mat_assign_element(x: wp.array(dtype=float), y: wp.array(dtype=wp.mat22)):
1909
+ i = wp.tid()
1910
+
1911
+ a = wp.mat22()
1912
+ a[0, 0] = 1.0 * x[i]
1913
+ a[0, 1] = 2.0 * x[i]
1914
+ a[1, 0] = 3.0 * x[i]
1915
+ a[1, 1] = 4.0 * x[i]
1916
+
1917
+ y[i] = a
1918
+
1919
+
1920
+ @wp.kernel
1921
+ def mat_assign_row(x: wp.array(dtype=wp.vec2), y: wp.array(dtype=wp.mat22)):
1922
+ i = wp.tid()
1923
+
1924
+ a = wp.mat22()
1925
+ a[0] = 1.0 * x[i]
1926
+ a[1] = 2.0 * x[i]
1927
+
1928
+ y[i] = a
1929
+
1930
+
1931
+ def test_mat_assign(test, device):
1932
+ # matrix element
1933
+ x = wp.ones(1, dtype=float, requires_grad=True, device=device)
1934
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
1908
1935
 
1909
1936
  tape = wp.Tape()
1910
1937
  with tape:
1911
- wp.launch(matrix_augassign_kernel, N, inputs=[a, b, x, c, d, y], device=device)
1938
+ wp.launch(mat_assign_element, 1, inputs=[x], outputs=[y], device=device)
1939
+
1940
+ y.grad = wp.ones_like(y)
1941
+ tape.backward()
1912
1942
 
1913
- tape.backward(grads={a: wp.ones_like(a), c: wp.ones_like(c)})
1943
+ assert_np_equal(y.numpy(), np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=float))
1944
+ assert_np_equal(x.grad.numpy(), np.array([10.0], dtype=float))
1914
1945
 
1915
- assert_np_equal(a.numpy(), wp.ones_like(a).numpy())
1916
- assert_np_equal(a.grad.numpy(), wp.ones_like(a).numpy())
1917
- assert_np_equal(b.grad.numpy(), np.array([[[0, 0], [1, 1]]], dtype=float))
1918
- assert_np_equal(x.grad.numpy(), np.array([[1, 1]], dtype=float))
1946
+ # matrix row
1947
+ x = wp.ones(1, dtype=wp.vec2, requires_grad=True, device=device)
1948
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
1949
+
1950
+ tape = wp.Tape()
1951
+ with tape:
1952
+ wp.launch(mat_assign_row, 1, inputs=[x], outputs=[y], device=device)
1919
1953
 
1920
- assert_np_equal(c.numpy(), -wp.ones_like(c).numpy())
1921
- assert_np_equal(c.grad.numpy(), wp.ones_like(c).numpy())
1922
- assert_np_equal(d.grad.numpy(), np.array([[[0, 0], [-1, -1]]], dtype=float))
1923
- assert_np_equal(y.grad.numpy(), np.array([[-1, -1]], dtype=float))
1954
+ y.grad = wp.ones_like(y)
1955
+ tape.backward()
1956
+
1957
+ assert_np_equal(y.numpy(), np.array([[[1.0, 1.0], [2.0, 2.0]]], dtype=float))
1958
+ assert_np_equal(x.grad.numpy(), np.array([[3.0, 3.0]], dtype=float))
1924
1959
 
1925
1960
 
1926
1961
  def test_matrix_assign_copy(test, device):
@@ -1953,6 +1988,260 @@ def test_matrix_assign_copy(test, device):
1953
1988
  wp.config.enable_vector_component_overwrites = saved_enable_vector_component_overwrites_setting
1954
1989
 
1955
1990
 
1991
+ @wp.kernel
1992
+ def mat_array_extract_element(x: wp.array2d(dtype=wp.mat22), y: wp.array2d(dtype=float)):
1993
+ i, j = wp.tid()
1994
+ a = x[i, j][0, 0]
1995
+ b = x[i, j][0, 1]
1996
+ c = x[i, j][1, 0]
1997
+ d = x[i, j][1, 1]
1998
+ y[i, j] = 1.0 * a + 2.0 * b + 3.0 * c + 4.0 * d
1999
+
2000
+
2001
+ @wp.kernel
2002
+ def mat_array_extract_row(x: wp.array2d(dtype=wp.mat22), y: wp.array2d(dtype=wp.vec2)):
2003
+ i, j = wp.tid()
2004
+ a = x[i, j][0]
2005
+ b = x[i, j][1]
2006
+ y[i, j] = 1.0 * a + 2.0 * b
2007
+
2008
+
2009
+ def test_mat_array_extract(test, device):
2010
+ # matrix element
2011
+ x = wp.ones((1, 1), dtype=wp.mat22, requires_grad=True, device=device)
2012
+ y = wp.zeros((1, 1), dtype=float, requires_grad=True, device=device)
2013
+
2014
+ tape = wp.Tape()
2015
+ with tape:
2016
+ wp.launch(mat_array_extract_element, (1, 1), inputs=[x], outputs=[y], device=device)
2017
+
2018
+ y.grad = wp.ones_like(y)
2019
+ tape.backward()
2020
+
2021
+ assert_np_equal(y.numpy(), np.array([[10.0]], dtype=float))
2022
+ assert_np_equal(x.grad.numpy(), np.array([[[[1.0, 2.0], [3.0, 4.0]]]], dtype=float))
2023
+
2024
+ # matrix row
2025
+ x = wp.ones((1, 1), dtype=wp.mat22, requires_grad=True, device=device)
2026
+ y = wp.zeros((1, 1), dtype=wp.vec2, requires_grad=True, device=device)
2027
+
2028
+ tape = wp.Tape()
2029
+ with tape:
2030
+ wp.launch(mat_array_extract_row, (1, 1), inputs=[x], outputs=[y], device=device)
2031
+
2032
+ y.grad = wp.ones_like(y)
2033
+ tape.backward()
2034
+
2035
+ assert_np_equal(y.numpy(), np.array([[[3.0, 3.0]]], dtype=float))
2036
+ assert_np_equal(x.grad.numpy(), np.array([[[[1.0, 1.0], [2.0, 2.0]]]], dtype=float))
2037
+
2038
+
2039
+ """ TODO: gradient propagation for in-place array assignment
2040
+ @wp.kernel
2041
+ def mat_array_assign_element(x: wp.array2d(dtype=float), y: wp.array2d(dtype=wp.mat22)):
2042
+ i, j = wp.tid()
2043
+
2044
+ y[i, j][0, 0] = 1.0 * x[i, j]
2045
+ y[i, j][0, 1] = 2.0 * x[i, j]
2046
+ y[i, j][1, 0] = 3.0 * x[i, j]
2047
+ y[i, j][1, 1] = 4.0 * x[i, j]
2048
+
2049
+
2050
+ @wp.kernel
2051
+ def mat_array_assign_row(x: wp.array2d(dtype=wp.vec3), y: wp.array2d(dtype=wp.mat(shape=(2, 3), dtype=float))):
2052
+ i, j = wp.tid()
2053
+
2054
+ y[i, j][0] = 1.0 * x[i, j]
2055
+ y[i, j][1] = 2.0 * x[i, j]
2056
+
2057
+
2058
+ def test_mat_array_assign(test, device):
2059
+ # matrix element
2060
+ x = wp.ones((1, 1), dtype=float, requires_grad=True, device=device)
2061
+ y = wp.zeros((1, 1), dtype=wp.mat22, requires_grad=True, device=device)
2062
+
2063
+ tape = wp.Tape()
2064
+ with tape:
2065
+ wp.launch(mat_array_assign_element, (1, 1), inputs=[x], outputs=[y], device=device)
2066
+
2067
+ y.grad = wp.ones_like(y)
2068
+ tape.backward()
2069
+
2070
+ assert_np_equal(y.numpy(), np.array([[[[1.0, 2.0], [3.0, 4.0]]]], dtype=float))
2071
+ assert_np_equal(x.grad.numpy(), np.array([[10.0]], dtype=float))
2072
+
2073
+ # matrix row
2074
+ x = wp.ones((1, 1), dtype=wp.vec3, requires_grad=True, device=device)
2075
+ y = wp.zeros((1, 1), dtype=wp.mat(shape=(2, 3), dtype=float), requires_grad=True, device=device)
2076
+
2077
+ tape = wp.Tape()
2078
+ with tape:
2079
+ wp.launch(mat_array_assign_row, (1, 1), inputs=[x], outputs=[y], device=device)
2080
+
2081
+ y.grad = wp.ones_like(y)
2082
+ tape.backward()
2083
+
2084
+ assert_np_equal(y.numpy(), np.array([[[[1.0, 1.0, 1.0], [2.0, 2.0, 2.0]]]], dtype=float))
2085
+ assert_np_equal(x.grad.numpy(), np.array([[[3.0, 3.0, 3.0]]], dtype=float))
2086
+ """
2087
+
2088
+
2089
+ @wp.kernel
2090
+ def mat_add_inplace_element(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.mat22)):
2091
+ i = wp.tid()
2092
+
2093
+ a = wp.mat22()
2094
+ b = x[i]
2095
+
2096
+ a[0, 0] += 1.0 * b[0, 0]
2097
+ a[0, 1] += 2.0 * b[0, 1]
2098
+ a[1, 0] += 3.0 * b[1, 0]
2099
+ a[1, 1] += 4.0 * b[1, 1]
2100
+
2101
+ y[i] = a
2102
+
2103
+
2104
+ @wp.kernel
2105
+ def mat_add_inplace_row(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.mat22)):
2106
+ i = wp.tid()
2107
+
2108
+ a = wp.mat22()
2109
+ b = x[i]
2110
+
2111
+ a[0] += 1.0 * b[0]
2112
+ a[1] += 2.0 * b[1]
2113
+
2114
+ y[i] = a
2115
+
2116
+
2117
+ def test_mat_add_inplace(test, device):
2118
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
2119
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
2120
+
2121
+ tape = wp.Tape()
2122
+ with tape:
2123
+ wp.launch(mat_add_inplace_element, 1, inputs=[x], outputs=[y], device=device)
2124
+
2125
+ y.grad = wp.ones_like(y)
2126
+ tape.backward()
2127
+
2128
+ assert_np_equal(y.numpy(), np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=float))
2129
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 2.0], [3.0, 4.0]]], dtype=float))
2130
+
2131
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
2132
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
2133
+
2134
+ tape = wp.Tape()
2135
+ with tape:
2136
+ wp.launch(mat_add_inplace_row, 1, inputs=[x], outputs=[y], device=device)
2137
+
2138
+ y.grad = wp.ones_like(y)
2139
+ tape.backward()
2140
+
2141
+ assert_np_equal(y.numpy(), np.array([[[1.0, 1.0], [2.0, 2.0]]], dtype=float))
2142
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 1.0], [2.0, 2.0]]], dtype=float))
2143
+
2144
+
2145
+ @wp.kernel
2146
+ def mat_sub_inplace_element(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.mat22)):
2147
+ i = wp.tid()
2148
+
2149
+ a = wp.mat22()
2150
+ b = x[i]
2151
+
2152
+ a[0, 0] -= 1.0 * b[0, 0]
2153
+ a[0, 1] -= 2.0 * b[0, 1]
2154
+ a[1, 0] -= 3.0 * b[1, 0]
2155
+ a[1, 1] -= 4.0 * b[1, 1]
2156
+
2157
+ y[i] = a
2158
+
2159
+
2160
+ @wp.kernel
2161
+ def mat_sub_inplace_row(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.mat22)):
2162
+ i = wp.tid()
2163
+
2164
+ a = wp.mat22()
2165
+ b = x[i]
2166
+
2167
+ a[0] -= 1.0 * b[0]
2168
+ a[1] -= 2.0 * b[1]
2169
+
2170
+ y[i] = a
2171
+
2172
+
2173
+ def test_mat_sub_inplace(test, device):
2174
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
2175
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
2176
+
2177
+ tape = wp.Tape()
2178
+ with tape:
2179
+ wp.launch(mat_sub_inplace_element, 1, inputs=[x], outputs=[y], device=device)
2180
+
2181
+ y.grad = wp.ones_like(y)
2182
+ tape.backward()
2183
+
2184
+ assert_np_equal(y.numpy(), np.array([[[-1.0, -2.0], [-3.0, -4.0]]], dtype=float))
2185
+ assert_np_equal(x.grad.numpy(), np.array([[[-1.0, -2.0], [-3.0, -4.0]]], dtype=float))
2186
+
2187
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
2188
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
2189
+
2190
+ tape = wp.Tape()
2191
+ with tape:
2192
+ wp.launch(mat_sub_inplace_row, 1, inputs=[x], outputs=[y], device=device)
2193
+
2194
+ y.grad = wp.ones_like(y)
2195
+ tape.backward()
2196
+
2197
+ assert_np_equal(y.numpy(), np.array([[[-1.0, -1.0], [-2.0, -2.0]]], dtype=float))
2198
+ assert_np_equal(x.grad.numpy(), np.array([[[-1.0, -1.0], [-2.0, -2.0]]], dtype=float))
2199
+
2200
+
2201
+ @wp.kernel
2202
+ def mat_array_add_inplace(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.mat22)):
2203
+ i = wp.tid()
2204
+
2205
+ y[i] += x[i]
2206
+
2207
+
2208
+ def test_mat_array_add_inplace(test, device):
2209
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
2210
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
2211
+
2212
+ tape = wp.Tape()
2213
+ with tape:
2214
+ wp.launch(mat_array_add_inplace, 1, inputs=[x], outputs=[y], device=device)
2215
+
2216
+ y.grad = wp.ones_like(y)
2217
+ tape.backward()
2218
+
2219
+ assert_np_equal(y.numpy(), np.array([[[1.0, 1.0], [1.0, 1.0]]], dtype=float))
2220
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 1.0], [1.0, 1.0]]], dtype=float))
2221
+
2222
+
2223
+ @wp.kernel
2224
+ def mat_array_sub_inplace(x: wp.array(dtype=wp.mat22), y: wp.array(dtype=wp.mat22)):
2225
+ i = wp.tid()
2226
+
2227
+ y[i] -= x[i]
2228
+
2229
+
2230
+ def test_mat_array_sub_inplace(test, device):
2231
+ x = wp.ones(1, dtype=wp.mat22, requires_grad=True, device=device)
2232
+ y = wp.zeros(1, dtype=wp.mat22, requires_grad=True, device=device)
2233
+
2234
+ tape = wp.Tape()
2235
+ with tape:
2236
+ wp.launch(mat_array_sub_inplace, 1, inputs=[x], outputs=[y], device=device)
2237
+
2238
+ y.grad = wp.ones_like(y)
2239
+ tape.backward()
2240
+
2241
+ assert_np_equal(y.numpy(), np.array([[[-1.0, -1.0], [-1.0, -1.0]]], dtype=float))
2242
+ assert_np_equal(x.grad.numpy(), np.array([[[-1.0, -1.0], [-1.0, -1.0]]], dtype=float))
2243
+
2244
+
1956
2245
  devices = get_test_devices()
1957
2246
 
1958
2247
 
@@ -2010,6 +2299,12 @@ for dtype in np_signed_int_types + np_float_types:
2010
2299
  TestMat, f"test_matmul_{dtype.__name__}", test_matmul, devices=devices, dtype=dtype
2011
2300
  )
2012
2301
 
2302
+ add_function_test(
2303
+ TestMat,
2304
+ "test_shape_mismatch",
2305
+ test_shape_mismatch,
2306
+ devices=devices,
2307
+ )
2013
2308
  add_function_test(
2014
2309
  TestMat,
2015
2310
  "test_anon_constructor_error_shape_arg_missing",
@@ -2073,16 +2368,18 @@ for dtype in np_float_types:
2073
2368
  TestMat, f"test_determinant_{dtype.__name__}", test_determinant, devices=devices, dtype=dtype
2074
2369
  )
2075
2370
  add_function_test_register_kernel(TestMat, f"test_skew_{dtype.__name__}", test_skew, devices=devices, dtype=dtype)
2076
- add_function_test_register_kernel(
2077
- TestMat,
2078
- f"test_matrix_assign_inplace_{dtype.__name__}",
2079
- test_matrix_assign_inplace,
2080
- devices=devices,
2081
- dtype=dtype,
2082
- )
2371
+
2083
2372
  add_function_test(TestMat, "test_matrix_len", test_matrix_len, devices=devices)
2084
- add_function_test(TestMat, "test_matrix_augassign", test_matrix_augassign, devices=devices)
2373
+ add_function_test(TestMat, "test_mat_extract", test_mat_extract, devices=devices)
2374
+ add_function_test(TestMat, "test_mat_assign", test_mat_assign, devices=devices)
2085
2375
  add_function_test(TestMat, "test_matrix_assign_copy", test_matrix_assign_copy, devices=devices)
2376
+ add_function_test(TestMat, "test_mat_array_extract", test_mat_array_extract, devices=devices)
2377
+ # add_function_test(TestMat, "test_mat_array_assign", test_mat_array_assign, devices=devices)
2378
+ add_function_test(TestMat, "test_mat_add_inplace", test_mat_add_inplace, devices=devices)
2379
+ add_function_test(TestMat, "test_mat_sub_inplace", test_mat_sub_inplace, devices=devices)
2380
+ add_function_test(TestMat, "test_mat_array_add_inplace", test_mat_array_add_inplace, devices=devices)
2381
+ add_function_test(TestMat, "test_mat_array_sub_inplace", test_mat_array_sub_inplace, devices=devices)
2382
+
2086
2383
 
2087
2384
  if __name__ == "__main__":
2088
2385
  wp.clear_kernel_cache()