warp-lang 1.7.0__py3-none-win_amd64.whl → 1.7.2rc1__py3-none-win_amd64.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/autograd.py +12 -2
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +1 -1
- warp/builtins.py +103 -66
- warp/codegen.py +48 -27
- warp/config.py +1 -1
- warp/context.py +112 -49
- warp/examples/benchmarks/benchmark_cloth.py +1 -1
- warp/examples/distributed/example_jacobi_mpi.py +507 -0
- warp/fem/cache.py +1 -1
- warp/fem/field/field.py +11 -1
- warp/fem/field/nodal_field.py +36 -22
- warp/fem/geometry/adaptive_nanogrid.py +7 -3
- warp/fem/geometry/trimesh.py +4 -12
- warp/jax_experimental/custom_call.py +14 -2
- warp/jax_experimental/ffi.py +100 -67
- warp/native/builtin.h +91 -65
- warp/native/svd.h +59 -49
- warp/native/tile.h +55 -26
- warp/native/volume.cpp +2 -2
- warp/native/volume_builder.cu +33 -22
- warp/native/warp.cu +1 -1
- warp/render/render_opengl.py +41 -34
- warp/render/render_usd.py +96 -6
- warp/sim/collide.py +11 -9
- warp/sim/inertia.py +189 -156
- warp/sim/integrator_euler.py +3 -0
- warp/sim/integrator_xpbd.py +3 -0
- warp/sim/model.py +56 -31
- warp/sim/render.py +4 -0
- warp/sparse.py +1 -1
- warp/stubs.py +73 -25
- warp/tests/assets/torus.usda +1 -1
- warp/tests/cuda/test_streams.py +1 -1
- warp/tests/sim/test_collision.py +237 -206
- warp/tests/sim/test_inertia.py +161 -0
- warp/tests/sim/test_model.py +5 -3
- warp/tests/sim/{flaky_test_sim_grad.py → test_sim_grad.py} +1 -4
- warp/tests/sim/test_xpbd.py +399 -0
- warp/tests/test_array.py +8 -7
- warp/tests/test_atomic.py +181 -2
- warp/tests/test_builtins_resolution.py +38 -38
- warp/tests/test_codegen.py +24 -3
- warp/tests/test_examples.py +16 -6
- warp/tests/test_fem.py +93 -14
- warp/tests/test_func.py +1 -1
- warp/tests/test_mat.py +416 -119
- warp/tests/test_quat.py +321 -137
- warp/tests/test_struct.py +116 -0
- warp/tests/test_vec.py +320 -174
- warp/tests/tile/test_tile.py +27 -0
- warp/tests/tile/test_tile_load.py +124 -0
- warp/tests/unittest_suites.py +2 -5
- warp/types.py +107 -9
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2rc1.dist-info}/METADATA +41 -19
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2rc1.dist-info}/RECORD +60 -57
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2rc1.dist-info}/WHEEL +1 -1
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2rc1.dist-info}/licenses/LICENSE.md +0 -26
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2rc1.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[
|
|
1087
|
+
wp.svd2(m2[tid], U, sigma, V) # Assuming there's a 2D SVD kernel
|
|
1070
1088
|
|
|
1071
|
-
Uout[
|
|
1072
|
-
sigmaout[
|
|
1073
|
-
Vout[
|
|
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
|
-
|
|
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(
|
|
1102
|
-
sigmaout = wp.zeros(
|
|
1103
|
-
Vout = wp.zeros(
|
|
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=
|
|
1145
|
+
wp.launch(kernel, dim=M, inputs=[m2], outputs=[Uout, sigmaout, Vout, outcomponents], device=device)
|
|
1106
1146
|
|
|
1107
|
-
Uout_np = Uout.numpy()
|
|
1108
|
-
sigmaout_np =
|
|
1109
|
-
Vout_np = Vout.numpy()
|
|
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.
|
|
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.
|
|
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.
|
|
1213
|
+
np.float16: 2.5e-3,
|
|
1168
1214
|
np.float32: 1.0e-6,
|
|
1169
|
-
np.float64: 1.0e-
|
|
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
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
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
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
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
|
-
|
|
1886
|
+
y.grad = wp.ones_like(y)
|
|
1887
|
+
tape.backward()
|
|
1886
1888
|
|
|
1887
|
-
|
|
1888
|
-
|
|
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
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1899
|
-
|
|
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
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
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
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
assert_np_equal(y.
|
|
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
|
-
|
|
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, "
|
|
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()
|