warp-lang 1.7.2rc1__py3-none-macosx_10_13_universal2.whl → 1.8.0__py3-none-macosx_10_13_universal2.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 (180) hide show
  1. warp/__init__.py +3 -1
  2. warp/__init__.pyi +3489 -1
  3. warp/autograd.py +45 -122
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +241 -252
  6. warp/build_dll.py +125 -26
  7. warp/builtins.py +1907 -384
  8. warp/codegen.py +257 -101
  9. warp/config.py +12 -1
  10. warp/constants.py +1 -1
  11. warp/context.py +657 -223
  12. warp/dlpack.py +1 -1
  13. warp/examples/benchmarks/benchmark_cloth.py +2 -2
  14. warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
  15. warp/examples/core/example_sample_mesh.py +1 -1
  16. warp/examples/core/example_spin_lock.py +93 -0
  17. warp/examples/core/example_work_queue.py +118 -0
  18. warp/examples/fem/example_adaptive_grid.py +5 -5
  19. warp/examples/fem/example_apic_fluid.py +1 -1
  20. warp/examples/fem/example_burgers.py +1 -1
  21. warp/examples/fem/example_convection_diffusion.py +9 -6
  22. warp/examples/fem/example_darcy_ls_optimization.py +489 -0
  23. warp/examples/fem/example_deformed_geometry.py +1 -1
  24. warp/examples/fem/example_diffusion.py +2 -2
  25. warp/examples/fem/example_diffusion_3d.py +1 -1
  26. warp/examples/fem/example_distortion_energy.py +1 -1
  27. warp/examples/fem/example_elastic_shape_optimization.py +387 -0
  28. warp/examples/fem/example_magnetostatics.py +5 -3
  29. warp/examples/fem/example_mixed_elasticity.py +5 -3
  30. warp/examples/fem/example_navier_stokes.py +11 -9
  31. warp/examples/fem/example_nonconforming_contact.py +5 -3
  32. warp/examples/fem/example_streamlines.py +8 -3
  33. warp/examples/fem/utils.py +9 -8
  34. warp/examples/interop/example_jax_ffi_callback.py +2 -2
  35. warp/examples/optim/example_drone.py +1 -1
  36. warp/examples/sim/example_cloth.py +1 -1
  37. warp/examples/sim/example_cloth_self_contact.py +48 -54
  38. warp/examples/tile/example_tile_block_cholesky.py +502 -0
  39. warp/examples/tile/example_tile_cholesky.py +2 -1
  40. warp/examples/tile/example_tile_convolution.py +1 -1
  41. warp/examples/tile/example_tile_filtering.py +1 -1
  42. warp/examples/tile/example_tile_matmul.py +1 -1
  43. warp/examples/tile/example_tile_mlp.py +2 -0
  44. warp/fabric.py +7 -7
  45. warp/fem/__init__.py +5 -0
  46. warp/fem/adaptivity.py +1 -1
  47. warp/fem/cache.py +152 -63
  48. warp/fem/dirichlet.py +2 -2
  49. warp/fem/domain.py +136 -6
  50. warp/fem/field/field.py +141 -99
  51. warp/fem/field/nodal_field.py +85 -39
  52. warp/fem/field/virtual.py +97 -52
  53. warp/fem/geometry/adaptive_nanogrid.py +91 -86
  54. warp/fem/geometry/closest_point.py +13 -0
  55. warp/fem/geometry/deformed_geometry.py +102 -40
  56. warp/fem/geometry/element.py +56 -2
  57. warp/fem/geometry/geometry.py +323 -22
  58. warp/fem/geometry/grid_2d.py +157 -62
  59. warp/fem/geometry/grid_3d.py +116 -20
  60. warp/fem/geometry/hexmesh.py +86 -20
  61. warp/fem/geometry/nanogrid.py +166 -86
  62. warp/fem/geometry/partition.py +59 -25
  63. warp/fem/geometry/quadmesh.py +86 -135
  64. warp/fem/geometry/tetmesh.py +47 -119
  65. warp/fem/geometry/trimesh.py +77 -270
  66. warp/fem/integrate.py +107 -52
  67. warp/fem/linalg.py +25 -58
  68. warp/fem/operator.py +124 -27
  69. warp/fem/quadrature/pic_quadrature.py +36 -14
  70. warp/fem/quadrature/quadrature.py +40 -16
  71. warp/fem/space/__init__.py +1 -1
  72. warp/fem/space/basis_function_space.py +66 -46
  73. warp/fem/space/basis_space.py +17 -4
  74. warp/fem/space/dof_mapper.py +1 -1
  75. warp/fem/space/function_space.py +2 -2
  76. warp/fem/space/grid_2d_function_space.py +4 -1
  77. warp/fem/space/hexmesh_function_space.py +4 -2
  78. warp/fem/space/nanogrid_function_space.py +3 -1
  79. warp/fem/space/partition.py +11 -2
  80. warp/fem/space/quadmesh_function_space.py +4 -1
  81. warp/fem/space/restriction.py +5 -2
  82. warp/fem/space/shape/__init__.py +10 -8
  83. warp/fem/space/tetmesh_function_space.py +4 -1
  84. warp/fem/space/topology.py +52 -21
  85. warp/fem/space/trimesh_function_space.py +4 -1
  86. warp/fem/utils.py +53 -8
  87. warp/jax.py +1 -2
  88. warp/jax_experimental/ffi.py +12 -17
  89. warp/jax_experimental/xla_ffi.py +37 -24
  90. warp/math.py +171 -1
  91. warp/native/array.h +99 -0
  92. warp/native/builtin.h +174 -31
  93. warp/native/coloring.cpp +1 -1
  94. warp/native/exports.h +118 -63
  95. warp/native/intersect.h +3 -3
  96. warp/native/mat.h +5 -10
  97. warp/native/mathdx.cpp +11 -5
  98. warp/native/matnn.h +1 -123
  99. warp/native/quat.h +28 -4
  100. warp/native/sparse.cpp +121 -258
  101. warp/native/sparse.cu +181 -274
  102. warp/native/spatial.h +305 -17
  103. warp/native/tile.h +583 -72
  104. warp/native/tile_radix_sort.h +1108 -0
  105. warp/native/tile_reduce.h +237 -2
  106. warp/native/tile_scan.h +240 -0
  107. warp/native/tuple.h +189 -0
  108. warp/native/vec.h +6 -16
  109. warp/native/warp.cpp +36 -4
  110. warp/native/warp.cu +574 -51
  111. warp/native/warp.h +47 -74
  112. warp/optim/linear.py +5 -1
  113. warp/paddle.py +7 -8
  114. warp/py.typed +0 -0
  115. warp/render/render_opengl.py +58 -29
  116. warp/render/render_usd.py +124 -61
  117. warp/sim/__init__.py +9 -0
  118. warp/sim/collide.py +252 -78
  119. warp/sim/graph_coloring.py +8 -1
  120. warp/sim/import_mjcf.py +4 -3
  121. warp/sim/import_usd.py +11 -7
  122. warp/sim/integrator.py +5 -2
  123. warp/sim/integrator_euler.py +1 -1
  124. warp/sim/integrator_featherstone.py +1 -1
  125. warp/sim/integrator_vbd.py +751 -320
  126. warp/sim/integrator_xpbd.py +1 -1
  127. warp/sim/model.py +265 -260
  128. warp/sim/utils.py +10 -7
  129. warp/sparse.py +303 -166
  130. warp/tape.py +52 -51
  131. warp/tests/cuda/test_conditional_captures.py +1046 -0
  132. warp/tests/cuda/test_streams.py +1 -1
  133. warp/tests/geometry/test_volume.py +2 -2
  134. warp/tests/interop/test_dlpack.py +9 -9
  135. warp/tests/interop/test_jax.py +0 -1
  136. warp/tests/run_coverage_serial.py +1 -1
  137. warp/tests/sim/disabled_kinematics.py +2 -2
  138. warp/tests/sim/{test_vbd.py → test_cloth.py} +296 -113
  139. warp/tests/sim/test_collision.py +159 -51
  140. warp/tests/sim/test_coloring.py +15 -1
  141. warp/tests/test_array.py +254 -2
  142. warp/tests/test_array_reduce.py +2 -2
  143. warp/tests/test_atomic_cas.py +299 -0
  144. warp/tests/test_codegen.py +142 -19
  145. warp/tests/test_conditional.py +47 -1
  146. warp/tests/test_ctypes.py +0 -20
  147. warp/tests/test_devices.py +8 -0
  148. warp/tests/test_fabricarray.py +4 -2
  149. warp/tests/test_fem.py +58 -25
  150. warp/tests/test_func.py +42 -1
  151. warp/tests/test_grad.py +1 -1
  152. warp/tests/test_lerp.py +1 -3
  153. warp/tests/test_map.py +481 -0
  154. warp/tests/test_mat.py +1 -24
  155. warp/tests/test_quat.py +6 -15
  156. warp/tests/test_rounding.py +10 -38
  157. warp/tests/test_runlength_encode.py +7 -7
  158. warp/tests/test_smoothstep.py +1 -1
  159. warp/tests/test_sparse.py +51 -2
  160. warp/tests/test_spatial.py +507 -1
  161. warp/tests/test_struct.py +2 -2
  162. warp/tests/test_tuple.py +265 -0
  163. warp/tests/test_types.py +2 -2
  164. warp/tests/test_utils.py +24 -18
  165. warp/tests/tile/test_tile.py +420 -1
  166. warp/tests/tile/test_tile_mathdx.py +518 -14
  167. warp/tests/tile/test_tile_reduce.py +213 -0
  168. warp/tests/tile/test_tile_shared_memory.py +130 -1
  169. warp/tests/tile/test_tile_sort.py +117 -0
  170. warp/tests/unittest_suites.py +4 -6
  171. warp/types.py +462 -308
  172. warp/utils.py +647 -86
  173. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/METADATA +20 -6
  174. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/RECORD +177 -165
  175. warp/stubs.py +0 -3381
  176. warp/tests/sim/test_xpbd.py +0 -399
  177. warp/tests/test_mlp.py +0 -282
  178. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/WHEEL +0 -0
  179. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/licenses/LICENSE.md +0 -0
  180. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/top_level.txt +0 -0
@@ -2030,6 +2030,486 @@ def test_transform_to_matrix(test, device, dtype, register_kernels=False):
2030
2030
  wp.launch(kernel, dim=1, device=device)
2031
2031
 
2032
2032
 
2033
+ def test_transform_compose(test, device, dtype, register_kernels=False):
2034
+ wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)]
2035
+ mat44 = wp.types.matrix((4, 4), wptype)
2036
+ vec3 = wp.types.vector(3, wptype)
2037
+ quat = wp.types.quaternion(wptype)
2038
+
2039
+ def transform_compose_kernel():
2040
+ p = vec3(wptype(1.0), wptype(2.0), wptype(3.0))
2041
+ q = quat(wptype(-0.4), wptype(0.2), wptype(-0.4), wptype(0.8))
2042
+ s = vec3(wptype(4.0), wptype(5.0), wptype(6.0))
2043
+ m = wp.transform_compose(p, q, s)
2044
+ # fmt: off
2045
+ wp.expect_near(
2046
+ m,
2047
+ mat44(
2048
+ wptype(0.6 * 4.0), wptype(0.48 * 5.0), wptype(0.64 * 6.0), wptype(1.0),
2049
+ wptype(-0.8 * 4.0), wptype(0.36 * 5.0), wptype(0.48 * 6.0), wptype(2.0),
2050
+ wptype(0.0 * 4.0), wptype(-0.8 * 5.0), wptype(0.6 * 6.0), wptype(3.0),
2051
+ wptype(0.0), wptype(0.0), wptype(0.0), wptype(1.0),
2052
+ ),
2053
+ tolerance=wptype(1e-2),
2054
+ )
2055
+ # fmt: on
2056
+
2057
+ kernel = getkernel(transform_compose_kernel, suffix=dtype.__name__)
2058
+
2059
+ if register_kernels:
2060
+ return
2061
+
2062
+ wp.launch(kernel, dim=1, device=device)
2063
+
2064
+
2065
+ def test_transform_decompose(test, device, dtype, register_kernels=False):
2066
+ wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)]
2067
+ mat44 = wp.types.matrix((4, 4), wptype)
2068
+ vec3 = wp.types.vector(3, wptype)
2069
+ quat = wp.types.quaternion(wptype)
2070
+
2071
+ def transform_decompose_kernel():
2072
+ # fmt: off
2073
+ m = mat44(
2074
+ wptype(0.6 * 4.0), wptype(0.48 * 5.0), wptype(0.64 * 6.0), wptype(1.0),
2075
+ wptype(-0.8 * 4.0), wptype(0.36 * 5.0), wptype(0.48 * 6.0), wptype(2.0),
2076
+ wptype(0.0 * 4.0), wptype(-0.8 * 5.0), wptype(0.6 * 6.0), wptype(3.0),
2077
+ wptype(0.0), wptype(0.0), wptype(0.0), wptype(1.0),
2078
+ )
2079
+ # fmt: on
2080
+ p, q, s = wp.transform_decompose(m)
2081
+ wp.expect_near(p, vec3(wptype(1.0), wptype(2.0), wptype(3.0)), tolerance=wptype(1e-2))
2082
+ wp.expect_near(q, quat(wptype(-0.4), wptype(0.2), wptype(-0.4), wptype(0.8)), tolerance=wptype(1e-2))
2083
+ wp.expect_near(s, vec3(wptype(4.0), wptype(5.0), wptype(6.0)), tolerance=wptype(1e-2))
2084
+
2085
+ kernel = getkernel(transform_decompose_kernel, suffix=dtype.__name__)
2086
+
2087
+ if register_kernels:
2088
+ return
2089
+
2090
+ wp.launch(kernel, dim=1, device=device)
2091
+
2092
+
2093
+ def test_transform_getter_setter(test, device):
2094
+ t = wp.transform()
2095
+
2096
+ a = wp.vec3(1.0, 2.0, 3.0)
2097
+ b = wp.quat(0.0, 0.0, 0.0, 1.0)
2098
+
2099
+ t.p = a
2100
+ t.q = b
2101
+
2102
+ c = t.p
2103
+ d = t.q
2104
+
2105
+ test.assertEqual(c, a)
2106
+ test.assertEqual(d, b)
2107
+
2108
+
2109
+ @wp.kernel
2110
+ def transform_extract_subscript(x: wp.array(dtype=wp.transform), y: wp.array(dtype=float)):
2111
+ tid = wp.tid()
2112
+
2113
+ a = x[tid]
2114
+ b = a[0] + 2.0 * a[1] + 3.0 * a[2] + 4.0 * a[3] + 5.0 * a[4] + 6.0 * a[5] + 7.0 * a[6]
2115
+ y[tid] = b
2116
+
2117
+
2118
+ @wp.kernel
2119
+ def transform_extract_attribute(
2120
+ x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.vec3), z: wp.array(dtype=wp.quat)
2121
+ ):
2122
+ tid = wp.tid()
2123
+
2124
+ a = x[tid]
2125
+ p = a.p
2126
+ q = a.q
2127
+
2128
+ y[tid] = p
2129
+ z[tid] = q
2130
+
2131
+
2132
+ def test_transform_extract(test, device):
2133
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2134
+ y = wp.zeros(1, dtype=float, requires_grad=True, device=device)
2135
+
2136
+ tape = wp.Tape()
2137
+ with tape:
2138
+ wp.launch(transform_extract_subscript, 1, inputs=[x], outputs=[y], device=device)
2139
+
2140
+ y.grad = wp.ones_like(y)
2141
+
2142
+ tape.backward()
2143
+
2144
+ assert_np_equal(y.numpy(), np.array([28.0], dtype=float))
2145
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]], dtype=float))
2146
+
2147
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2148
+ y = wp.zeros(1, dtype=wp.vec3, requires_grad=True, device=device)
2149
+ z = wp.zeros(1, dtype=wp.quat, requires_grad=True, device=device)
2150
+
2151
+ tape = wp.Tape()
2152
+ with tape:
2153
+ wp.launch(transform_extract_attribute, 1, inputs=[x], outputs=[y, z], device=device)
2154
+
2155
+ y.grad = wp.ones_like(y)
2156
+ z.grad = wp.ones_like(z)
2157
+
2158
+ tape.backward()
2159
+
2160
+ assert_np_equal(y.numpy(), np.array([[1.0, 1.0, 1.0]], dtype=float))
2161
+ assert_np_equal(z.numpy(), np.array([[1.0, 1.0, 1.0, 1.0]], dtype=float))
2162
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=float))
2163
+
2164
+
2165
+ @wp.kernel
2166
+ def transform_assign_subscript(x: wp.array(dtype=float), y: wp.array(dtype=wp.transform)):
2167
+ i = wp.tid()
2168
+
2169
+ a = wp.transform()
2170
+ a[0] = 1.0 * x[i]
2171
+ a[1] = 2.0 * x[i]
2172
+ a[2] = 3.0 * x[i]
2173
+ a[3] = 4.0 * x[i]
2174
+ a[4] = 5.0 * x[i]
2175
+ a[5] = 6.0 * x[i]
2176
+ a[6] = 7.0 * x[i]
2177
+ y[i] = a
2178
+
2179
+
2180
+ @wp.kernel
2181
+ def transform_assign_attribute(x: wp.array(dtype=wp.vec3), y: wp.array(dtype=wp.quat), z: wp.array(dtype=wp.transform)):
2182
+ i = wp.tid()
2183
+
2184
+ a = wp.transform()
2185
+ a.p = x[i]
2186
+ a.q = y[i]
2187
+ z[i] = a
2188
+
2189
+
2190
+ def test_transform_assign(test, device):
2191
+ x = wp.ones(1, dtype=float, requires_grad=True, device=device)
2192
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2193
+
2194
+ tape = wp.Tape()
2195
+ with tape:
2196
+ wp.launch(transform_assign_subscript, 1, inputs=[x], outputs=[y], device=device)
2197
+
2198
+ y.grad = wp.ones_like(y)
2199
+ tape.backward()
2200
+
2201
+ assert_np_equal(y.numpy(), np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]], dtype=float))
2202
+ assert_np_equal(x.grad.numpy(), np.array([28.0], dtype=float))
2203
+
2204
+ x = wp.ones(1, dtype=wp.vec3, requires_grad=True, device=device)
2205
+ y = wp.ones(1, dtype=wp.quat, requires_grad=True, device=device)
2206
+ z = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2207
+
2208
+ tape = wp.Tape()
2209
+ with tape:
2210
+ wp.launch(transform_assign_attribute, 1, inputs=[x, y], outputs=[z], device=device)
2211
+
2212
+ z.grad = wp.ones_like(z)
2213
+ tape.backward()
2214
+
2215
+ assert_np_equal(z.numpy(), np.array([[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=float))
2216
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 1.0, 1.0]], dtype=float))
2217
+ assert_np_equal(y.grad.numpy(), np.array([[1.0, 1.0, 1.0, 1.0]], dtype=float))
2218
+
2219
+
2220
+ def test_transform_assign_copy(test, device):
2221
+ saved_enable_vector_component_overwrites_setting = wp.config.enable_vector_component_overwrites
2222
+ try:
2223
+ wp.config.enable_vector_component_overwrites = True
2224
+
2225
+ @wp.kernel
2226
+ def transform_assign_overwrite(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2227
+ tid = wp.tid()
2228
+
2229
+ a = wp.transform()
2230
+ b = x[tid]
2231
+ a = b
2232
+ a[1] = 3.0
2233
+
2234
+ y[tid] = a
2235
+
2236
+ x = wp.ones(1, dtype=wp.transform, device=device, requires_grad=True)
2237
+ y = wp.zeros(1, dtype=wp.transform, device=device, requires_grad=True)
2238
+
2239
+ tape = wp.Tape()
2240
+ with tape:
2241
+ wp.launch(transform_assign_overwrite, dim=1, inputs=[x, y], device=device)
2242
+
2243
+ y.grad = wp.ones_like(y, requires_grad=False)
2244
+ tape.backward()
2245
+
2246
+ assert_np_equal(y.numpy(), np.array([[1.0, 3.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=float))
2247
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=float))
2248
+
2249
+ finally:
2250
+ wp.config.enable_vector_component_overwrites = saved_enable_vector_component_overwrites_setting
2251
+
2252
+
2253
+ @wp.kernel
2254
+ def transform_array_extract_subscript(x: wp.array2d(dtype=wp.transform), y: wp.array2d(dtype=float)):
2255
+ i, j = wp.tid()
2256
+ a = x[i, j][0]
2257
+ b = x[i, j][1]
2258
+ c = x[i, j][2]
2259
+ d = x[i, j][3]
2260
+ e = x[i, j][4]
2261
+ f = x[i, j][5]
2262
+ g = x[i, j][6]
2263
+ y[i, j] = 1.0 * a + 2.0 * b + 3.0 * c + 4.0 * d + 5.0 * e + 6.0 * f + 7.0 * g
2264
+
2265
+
2266
+ @wp.kernel
2267
+ def transform_array_extract_attribute(
2268
+ x: wp.array2d(dtype=wp.transform), y: wp.array2d(dtype=wp.vec3), z: wp.array2d(dtype=wp.quat)
2269
+ ):
2270
+ i, j = wp.tid()
2271
+ a = x[i, j].p
2272
+ b = x[i, j].q
2273
+ y[i, j] = a
2274
+ z[i, j] = b
2275
+
2276
+
2277
+ def test_transform_array_extract(test, device):
2278
+ x = wp.ones((1, 1), dtype=wp.transform, requires_grad=True, device=device)
2279
+ y = wp.zeros((1, 1), dtype=float, requires_grad=True, device=device)
2280
+
2281
+ tape = wp.Tape()
2282
+ with tape:
2283
+ wp.launch(transform_array_extract_subscript, (1, 1), inputs=[x], outputs=[y], device=device)
2284
+
2285
+ y.grad = wp.ones_like(y)
2286
+ tape.backward()
2287
+
2288
+ assert_np_equal(y.numpy(), np.array([[28.0]], dtype=float))
2289
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]]], dtype=float))
2290
+
2291
+ x = wp.ones((1, 1), dtype=wp.transform, requires_grad=True, device=device)
2292
+ y = wp.zeros((1, 1), dtype=wp.vec3, requires_grad=True, device=device)
2293
+ z = wp.zeros((1, 1), dtype=wp.quat, requires_grad=True, device=device)
2294
+
2295
+ tape = wp.Tape()
2296
+ with tape:
2297
+ wp.launch(transform_array_extract_attribute, (1, 1), inputs=[x], outputs=[y, z], device=device)
2298
+
2299
+ y.grad = wp.ones_like(y)
2300
+ z.grad = wp.ones_like(z)
2301
+ tape.backward()
2302
+
2303
+ assert_np_equal(y.numpy(), np.array([[[1.0, 1.0, 1.0]]], dtype=float))
2304
+ assert_np_equal(z.numpy(), np.array([[[1.0, 1.0, 1.0, 1.0]]], dtype=float))
2305
+ assert_np_equal(x.grad.numpy(), np.array([[[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]]], dtype=float))
2306
+
2307
+
2308
+ @wp.kernel
2309
+ def transform_array_assign_subscript(x: wp.array2d(dtype=float), y: wp.array2d(dtype=wp.transform)):
2310
+ i, j = wp.tid()
2311
+
2312
+ y[i, j][0] = 1.0 * x[i, j]
2313
+ y[i, j][1] = 2.0 * x[i, j]
2314
+ y[i, j][2] = 3.0 * x[i, j]
2315
+ y[i, j][3] = 4.0 * x[i, j]
2316
+ y[i, j][4] = 5.0 * x[i, j]
2317
+ y[i, j][5] = 6.0 * x[i, j]
2318
+ y[i, j][6] = 7.0 * x[i, j]
2319
+
2320
+
2321
+ # @wp.kernel
2322
+ # def transform_array_assign_attribute(x: wp.array2d(dtype=wp.vec3), y: wp.array2d(dtype=wp.quat), z: wp.array2d(dtype=wp.transform)):
2323
+ # i, j = wp.tid()
2324
+
2325
+ # z[i, j].p = x[i, j]
2326
+ # z[i, j].q = y[i, j]
2327
+
2328
+
2329
+ def test_transform_array_assign(test, device):
2330
+ x = wp.ones((1, 1), dtype=float, requires_grad=True, device=device)
2331
+ y = wp.zeros((1, 1), dtype=wp.transform, requires_grad=True, device=device)
2332
+
2333
+ tape = wp.Tape()
2334
+ with tape:
2335
+ wp.launch(transform_array_assign_subscript, (1, 1), inputs=[x], outputs=[y], device=device)
2336
+
2337
+ assert_np_equal(y.numpy(), np.array([[[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]]], dtype=float))
2338
+ # TODO: gradient propagation for in-place array assignment
2339
+
2340
+ x = wp.ones((1, 1), dtype=wp.vec3, requires_grad=True, device=device)
2341
+ y = wp.ones((1, 1), dtype=wp.quat, requires_grad=True, device=device)
2342
+ z = wp.zeros((1, 1), dtype=wp.transform, requires_grad=True, device=device)
2343
+
2344
+ # TODO: transform_array_assign_attribute
2345
+ # tape = wp.Tape()
2346
+ # with tape:
2347
+ # wp.launch(transform_array_assign_attribute, (1, 1), inputs=[x, y], outputs=[z], device=device)
2348
+
2349
+ # assert_np_equal(z.numpy(), np.array([[[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]]], dtype=float))
2350
+ # TODO: gradient propagation for in-place array assignment
2351
+
2352
+
2353
+ @wp.kernel
2354
+ def transform_add_inplace_subscript(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2355
+ i = wp.tid()
2356
+
2357
+ a = wp.transform()
2358
+ b = x[i]
2359
+
2360
+ a[0] += 1.0 * b[0]
2361
+ a[1] += 2.0 * b[1]
2362
+ a[2] += 3.0 * b[2]
2363
+ a[3] += 4.0 * b[3]
2364
+ a[4] += 5.0 * b[4]
2365
+ a[5] += 6.0 * b[5]
2366
+ a[6] += 7.0 * b[6]
2367
+
2368
+ y[i] = a
2369
+
2370
+
2371
+ @wp.kernel
2372
+ def transform_add_inplace_attribute(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2373
+ i = wp.tid()
2374
+
2375
+ a = wp.transform()
2376
+ b = x[i]
2377
+
2378
+ a.p += b.p
2379
+
2380
+ y[i] = a
2381
+
2382
+
2383
+ def test_transform_add_inplace(test, device):
2384
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2385
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2386
+
2387
+ tape = wp.Tape()
2388
+ with tape:
2389
+ wp.launch(transform_add_inplace_subscript, 1, inputs=[x], outputs=[y], device=device)
2390
+
2391
+ y.grad = wp.ones_like(y)
2392
+ tape.backward()
2393
+
2394
+ assert_np_equal(y.numpy(), np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]], dtype=float))
2395
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]], dtype=float))
2396
+
2397
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2398
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2399
+
2400
+ tape = wp.Tape()
2401
+ with tape:
2402
+ wp.launch(transform_add_inplace_attribute, 1, inputs=[x], outputs=[y], device=device)
2403
+
2404
+ y.grad = wp.ones_like(y)
2405
+ tape.backward()
2406
+
2407
+ assert_np_equal(y.numpy(), np.array([[1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]], dtype=float))
2408
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]], dtype=float))
2409
+
2410
+
2411
+ @wp.kernel
2412
+ def transform_sub_inplace_subscript(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2413
+ i = wp.tid()
2414
+
2415
+ a = wp.transform()
2416
+ b = x[i]
2417
+
2418
+ a[0] -= 1.0 * b[0]
2419
+ a[1] -= 2.0 * b[1]
2420
+ a[2] -= 3.0 * b[2]
2421
+ a[3] -= 4.0 * b[3]
2422
+ a[4] -= 5.0 * b[4]
2423
+ a[5] -= 6.0 * b[5]
2424
+ a[6] -= 7.0 * b[6]
2425
+
2426
+ y[i] = a
2427
+
2428
+
2429
+ @wp.kernel
2430
+ def transform_sub_inplace_attribute(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2431
+ i = wp.tid()
2432
+
2433
+ a = wp.transform()
2434
+ b = x[i]
2435
+
2436
+ a.p -= b.p
2437
+
2438
+ y[i] = a
2439
+
2440
+
2441
+ def test_transform_sub_inplace(test, device):
2442
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2443
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2444
+
2445
+ tape = wp.Tape()
2446
+ with tape:
2447
+ wp.launch(transform_sub_inplace_subscript, 1, inputs=[x], outputs=[y], device=device)
2448
+
2449
+ y.grad = wp.ones_like(y)
2450
+ tape.backward()
2451
+
2452
+ assert_np_equal(y.numpy(), np.array([[-1.0, -2.0, -3.0, -4.0, -5.0, -6.0, -7.0]], dtype=float))
2453
+ assert_np_equal(x.grad.numpy(), np.array([[-1.0, -2.0, -3.0, -4.0, -5.0, -6.0, -7.0]], dtype=float))
2454
+
2455
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2456
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2457
+
2458
+ tape = wp.Tape()
2459
+ with tape:
2460
+ wp.launch(transform_sub_inplace_attribute, 1, inputs=[x], outputs=[y], device=device)
2461
+
2462
+ y.grad = wp.ones_like(y)
2463
+ tape.backward()
2464
+
2465
+ assert_np_equal(y.numpy(), np.array([[-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0]], dtype=float))
2466
+ assert_np_equal(x.grad.numpy(), np.array([[-1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0]], dtype=float))
2467
+
2468
+
2469
+ @wp.kernel
2470
+ def transform_array_add_inplace(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2471
+ i = wp.tid()
2472
+
2473
+ y[i] += x[i]
2474
+
2475
+
2476
+ def test_transform_array_add_inplace(test, device):
2477
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2478
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2479
+
2480
+ tape = wp.Tape()
2481
+ with tape:
2482
+ wp.launch(transform_array_add_inplace, 1, inputs=[x], outputs=[y], device=device)
2483
+
2484
+ y.grad = wp.ones_like(y)
2485
+ tape.backward()
2486
+
2487
+ assert_np_equal(y.numpy(), np.array([[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=float))
2488
+ assert_np_equal(x.grad.numpy(), np.array([[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]], dtype=float))
2489
+
2490
+
2491
+ @wp.kernel
2492
+ def transform_array_sub_inplace(x: wp.array(dtype=wp.transform), y: wp.array(dtype=wp.transform)):
2493
+ i = wp.tid()
2494
+
2495
+ y[i] -= x[i]
2496
+
2497
+
2498
+ def test_transform_array_sub_inplace(test, device):
2499
+ x = wp.ones(1, dtype=wp.transform, requires_grad=True, device=device)
2500
+ y = wp.zeros(1, dtype=wp.transform, requires_grad=True, device=device)
2501
+
2502
+ tape = wp.Tape()
2503
+ with tape:
2504
+ wp.launch(transform_array_sub_inplace, 1, inputs=[x], outputs=[y], device=device)
2505
+
2506
+ y.grad = wp.ones_like(y)
2507
+ tape.backward()
2508
+
2509
+ assert_np_equal(y.numpy(), np.array([[-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0]], dtype=float))
2510
+ assert_np_equal(x.grad.numpy(), np.array([[-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0]], dtype=float))
2511
+
2512
+
2033
2513
  devices = get_test_devices()
2034
2514
 
2035
2515
 
@@ -2220,9 +2700,35 @@ for dtype in np_float_types:
2220
2700
  devices=devices,
2221
2701
  dtype=dtype,
2222
2702
  )
2223
-
2703
+ add_function_test_register_kernel(
2704
+ TestSpatial,
2705
+ f"test_transform_compose_{dtype.__name__}",
2706
+ test_transform_compose,
2707
+ devices=devices,
2708
+ dtype=dtype,
2709
+ )
2710
+ add_function_test_register_kernel(
2711
+ TestSpatial,
2712
+ f"test_transform_decompose_{dtype.__name__}",
2713
+ test_transform_decompose,
2714
+ devices=devices,
2715
+ dtype=dtype,
2716
+ )
2224
2717
  # \TODO: test spatial_mass and spatial_jacobian
2225
2718
 
2719
+ add_function_test(
2720
+ TestSpatial, "test_transform_getter_setter", test_transform_getter_setter, devices=wp.get_device("cpu")
2721
+ )
2722
+ add_function_test(TestSpatial, "test_transform_extract", test_transform_extract, devices=devices)
2723
+ add_function_test(TestSpatial, "test_transform_assign", test_transform_assign, devices=devices)
2724
+ add_function_test(TestSpatial, "test_transform_assign_copy", test_transform_assign_copy, devices=devices)
2725
+ add_function_test(TestSpatial, "test_transform_array_extract", test_transform_array_extract, devices=devices)
2726
+ add_function_test(TestSpatial, "test_transform_array_assign", test_transform_array_assign, devices=devices)
2727
+ add_function_test(TestSpatial, "test_transform_add_inplace", test_transform_add_inplace, devices=devices)
2728
+ add_function_test(TestSpatial, "test_transform_sub_inplace", test_transform_sub_inplace, devices=devices)
2729
+ add_function_test(TestSpatial, "test_transform_array_add_inplace", test_transform_array_add_inplace, devices=devices)
2730
+ add_function_test(TestSpatial, "test_transform_array_sub_inplace", test_transform_array_sub_inplace, devices=devices)
2731
+
2226
2732
 
2227
2733
  if __name__ == "__main__":
2228
2734
  wp.clear_kernel_cache()
warp/tests/test_struct.py CHANGED
@@ -768,8 +768,8 @@ class TestStruct(unittest.TestCase):
768
768
  v.value[2] = 3.0
769
769
 
770
770
  arr = wp.array([v], dtype=VecStruct)
771
- expected = np.array(([1.0, 2.0, 3.0],))
772
- assert np.all(arr.numpy().tolist() == expected)
771
+ expected = np.array([[[1.0, 2.0, 3.0]]])
772
+ np.testing.assert_equal(arr.numpy().tolist(), expected)
773
773
 
774
774
 
775
775
  add_function_test(TestStruct, "test_step", test_step, devices=devices)