warp-lang 1.2.2__py3-none-macosx_10_13_universal2.whl → 1.3.1__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.
- warp/__init__.py +8 -6
- warp/autograd.py +823 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +6 -2
- warp/builtins.py +1412 -888
- warp/codegen.py +503 -166
- warp/config.py +48 -18
- warp/context.py +400 -198
- warp/dlpack.py +8 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +1 -1
- warp/examples/benchmarks/benchmark_interop_torch.py +158 -0
- warp/examples/benchmarks/benchmark_launches.py +1 -1
- warp/examples/core/example_cupy.py +78 -0
- warp/examples/fem/example_apic_fluid.py +17 -36
- warp/examples/fem/example_burgers.py +9 -18
- warp/examples/fem/example_convection_diffusion.py +7 -17
- warp/examples/fem/example_convection_diffusion_dg.py +27 -47
- warp/examples/fem/example_deformed_geometry.py +11 -22
- warp/examples/fem/example_diffusion.py +7 -18
- warp/examples/fem/example_diffusion_3d.py +24 -28
- warp/examples/fem/example_diffusion_mgpu.py +7 -14
- warp/examples/fem/example_magnetostatics.py +190 -0
- warp/examples/fem/example_mixed_elasticity.py +111 -80
- warp/examples/fem/example_navier_stokes.py +30 -34
- warp/examples/fem/example_nonconforming_contact.py +290 -0
- warp/examples/fem/example_stokes.py +17 -32
- warp/examples/fem/example_stokes_transfer.py +12 -21
- warp/examples/fem/example_streamlines.py +350 -0
- warp/examples/fem/utils.py +936 -0
- warp/fabric.py +5 -2
- warp/fem/__init__.py +13 -3
- warp/fem/cache.py +161 -11
- warp/fem/dirichlet.py +37 -28
- warp/fem/domain.py +105 -14
- warp/fem/field/__init__.py +14 -3
- warp/fem/field/field.py +454 -11
- warp/fem/field/nodal_field.py +33 -18
- warp/fem/geometry/deformed_geometry.py +50 -15
- warp/fem/geometry/hexmesh.py +12 -24
- warp/fem/geometry/nanogrid.py +106 -31
- warp/fem/geometry/quadmesh_2d.py +6 -11
- warp/fem/geometry/tetmesh.py +103 -61
- warp/fem/geometry/trimesh_2d.py +98 -47
- warp/fem/integrate.py +231 -186
- warp/fem/operator.py +14 -9
- warp/fem/quadrature/pic_quadrature.py +35 -9
- warp/fem/quadrature/quadrature.py +119 -32
- warp/fem/space/basis_space.py +98 -22
- warp/fem/space/collocated_function_space.py +3 -1
- warp/fem/space/function_space.py +7 -2
- warp/fem/space/grid_2d_function_space.py +3 -3
- warp/fem/space/grid_3d_function_space.py +4 -4
- warp/fem/space/hexmesh_function_space.py +3 -2
- warp/fem/space/nanogrid_function_space.py +12 -14
- warp/fem/space/partition.py +45 -47
- warp/fem/space/restriction.py +19 -16
- warp/fem/space/shape/cube_shape_function.py +91 -3
- warp/fem/space/shape/shape_function.py +7 -0
- warp/fem/space/shape/square_shape_function.py +32 -0
- warp/fem/space/shape/tet_shape_function.py +11 -7
- warp/fem/space/shape/triangle_shape_function.py +10 -1
- warp/fem/space/topology.py +116 -42
- warp/fem/types.py +8 -1
- warp/fem/utils.py +301 -83
- warp/native/array.h +16 -0
- warp/native/builtin.h +0 -15
- warp/native/cuda_util.cpp +14 -6
- warp/native/exports.h +1348 -1308
- warp/native/quat.h +79 -0
- warp/native/rand.h +27 -4
- warp/native/sparse.cpp +83 -81
- warp/native/sparse.cu +381 -453
- warp/native/vec.h +64 -0
- warp/native/volume.cpp +40 -49
- warp/native/volume_builder.cu +2 -3
- warp/native/volume_builder.h +12 -17
- warp/native/warp.cu +3 -3
- warp/native/warp.h +69 -59
- warp/render/render_opengl.py +17 -9
- warp/sim/articulation.py +117 -17
- warp/sim/collide.py +35 -29
- warp/sim/model.py +123 -18
- warp/sim/render.py +3 -1
- warp/sparse.py +867 -203
- warp/stubs.py +312 -541
- warp/tape.py +29 -1
- warp/tests/disabled_kinematics.py +1 -1
- warp/tests/test_adam.py +1 -1
- warp/tests/test_arithmetic.py +1 -1
- warp/tests/test_array.py +58 -1
- warp/tests/test_array_reduce.py +1 -1
- warp/tests/test_async.py +1 -1
- warp/tests/test_atomic.py +1 -1
- warp/tests/test_bool.py +1 -1
- warp/tests/test_builtins_resolution.py +1 -1
- warp/tests/test_bvh.py +6 -1
- warp/tests/test_closest_point_edge_edge.py +1 -1
- warp/tests/test_codegen.py +91 -1
- warp/tests/test_compile_consts.py +1 -1
- warp/tests/test_conditional.py +1 -1
- warp/tests/test_copy.py +1 -1
- warp/tests/test_ctypes.py +1 -1
- warp/tests/test_dense.py +1 -1
- warp/tests/test_devices.py +1 -1
- warp/tests/test_dlpack.py +1 -1
- warp/tests/test_examples.py +33 -4
- warp/tests/test_fabricarray.py +5 -2
- warp/tests/test_fast_math.py +1 -1
- warp/tests/test_fem.py +213 -6
- warp/tests/test_fp16.py +1 -1
- warp/tests/test_func.py +1 -1
- warp/tests/test_future_annotations.py +90 -0
- warp/tests/test_generics.py +1 -1
- warp/tests/test_grad.py +1 -1
- warp/tests/test_grad_customs.py +1 -1
- warp/tests/test_grad_debug.py +247 -0
- warp/tests/test_hash_grid.py +6 -1
- warp/tests/test_implicit_init.py +354 -0
- warp/tests/test_import.py +1 -1
- warp/tests/test_indexedarray.py +1 -1
- warp/tests/test_intersect.py +1 -1
- warp/tests/test_jax.py +1 -1
- warp/tests/test_large.py +1 -1
- warp/tests/test_launch.py +1 -1
- warp/tests/test_lerp.py +1 -1
- warp/tests/test_linear_solvers.py +1 -1
- warp/tests/test_lvalue.py +1 -1
- warp/tests/test_marching_cubes.py +5 -2
- warp/tests/test_mat.py +34 -35
- warp/tests/test_mat_lite.py +2 -1
- warp/tests/test_mat_scalar_ops.py +1 -1
- warp/tests/test_math.py +1 -1
- warp/tests/test_matmul.py +20 -16
- warp/tests/test_matmul_lite.py +1 -1
- warp/tests/test_mempool.py +1 -1
- warp/tests/test_mesh.py +5 -2
- warp/tests/test_mesh_query_aabb.py +1 -1
- warp/tests/test_mesh_query_point.py +1 -1
- warp/tests/test_mesh_query_ray.py +1 -1
- warp/tests/test_mlp.py +1 -1
- warp/tests/test_model.py +1 -1
- warp/tests/test_module_hashing.py +77 -1
- warp/tests/test_modules_lite.py +1 -1
- warp/tests/test_multigpu.py +1 -1
- warp/tests/test_noise.py +1 -1
- warp/tests/test_operators.py +1 -1
- warp/tests/test_options.py +1 -1
- warp/tests/test_overwrite.py +542 -0
- warp/tests/test_peer.py +1 -1
- warp/tests/test_pinned.py +1 -1
- warp/tests/test_print.py +1 -1
- warp/tests/test_quat.py +15 -1
- warp/tests/test_rand.py +1 -1
- warp/tests/test_reload.py +1 -1
- warp/tests/test_rounding.py +1 -1
- warp/tests/test_runlength_encode.py +1 -1
- warp/tests/test_scalar_ops.py +95 -0
- warp/tests/test_sim_grad.py +1 -1
- warp/tests/test_sim_kinematics.py +1 -1
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +82 -15
- warp/tests/test_spatial.py +1 -1
- warp/tests/test_special_values.py +2 -11
- warp/tests/test_streams.py +11 -1
- warp/tests/test_struct.py +1 -1
- warp/tests/test_tape.py +1 -1
- warp/tests/test_torch.py +194 -1
- warp/tests/test_transient_module.py +1 -1
- warp/tests/test_types.py +1 -1
- warp/tests/test_utils.py +1 -1
- warp/tests/test_vec.py +15 -63
- warp/tests/test_vec_lite.py +2 -1
- warp/tests/test_vec_scalar_ops.py +65 -1
- warp/tests/test_verify_fp.py +1 -1
- warp/tests/test_volume.py +28 -2
- warp/tests/test_volume_write.py +1 -1
- warp/tests/unittest_serial.py +1 -1
- warp/tests/unittest_suites.py +9 -1
- warp/tests/walkthrough_debug.py +1 -1
- warp/thirdparty/unittest_parallel.py +2 -5
- warp/torch.py +103 -41
- warp/types.py +341 -224
- warp/utils.py +11 -2
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.1.dist-info}/METADATA +99 -46
- warp_lang-1.3.1.dist-info/RECORD +368 -0
- warp/examples/fem/bsr_utils.py +0 -378
- warp/examples/fem/mesh_utils.py +0 -133
- warp/examples/fem/plot_utils.py +0 -292
- warp_lang-1.2.2.dist-info/RECORD +0 -359
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.2.2.dist-info → warp_lang-1.3.1.dist-info}/top_level.txt +0 -0
warp/tests/test_fem.py
CHANGED
|
@@ -18,7 +18,14 @@ from warp.fem.geometry import DeformedGeometry
|
|
|
18
18
|
from warp.fem.geometry.closest_point import project_on_tet_at_origin, project_on_tri_at_origin
|
|
19
19
|
from warp.fem.space import shape
|
|
20
20
|
from warp.fem.types import make_free_sample
|
|
21
|
-
from warp.fem.utils import
|
|
21
|
+
from warp.fem.utils import (
|
|
22
|
+
grid_to_hexes,
|
|
23
|
+
grid_to_quads,
|
|
24
|
+
grid_to_tets,
|
|
25
|
+
grid_to_tris,
|
|
26
|
+
inverse_qr,
|
|
27
|
+
symmetric_eigenvalues_qr,
|
|
28
|
+
)
|
|
22
29
|
from warp.tests.unittest_utils import *
|
|
23
30
|
|
|
24
31
|
|
|
@@ -872,7 +879,7 @@ def test_shape_function_weight(test, shape: shape.ShapeFunction, coord_sampler,
|
|
|
872
879
|
def node_unity_test():
|
|
873
880
|
n = wp.tid()
|
|
874
881
|
node_w = weight_fn(node_coords_fn(n), n)
|
|
875
|
-
wp.expect_near(node_w, 1.0,
|
|
882
|
+
wp.expect_near(node_w, 1.0, 1e-5)
|
|
876
883
|
|
|
877
884
|
wp.launch(node_unity_test, dim=NODE_COUNT, inputs=[])
|
|
878
885
|
|
|
@@ -1201,6 +1208,34 @@ def test_point_basis(test, device):
|
|
|
1201
1208
|
|
|
1202
1209
|
test.assertAlmostEqual(np.sum(zeros.numpy()), 0.0, places=5)
|
|
1203
1210
|
|
|
1211
|
+
# test point basis with variable points per cell
|
|
1212
|
+
points = wp.array([[0.25, 0.33], [0.33, 0.25], [0.8, 0.8]], dtype=wp.vec2)
|
|
1213
|
+
pic = fem.PicQuadrature(domain, positions=points)
|
|
1214
|
+
|
|
1215
|
+
test.assertEqual(pic.active_cell_count(), 2)
|
|
1216
|
+
test.assertEqual(pic.total_point_count(), 3)
|
|
1217
|
+
test.assertEqual(pic.max_points_per_element(), 2)
|
|
1218
|
+
|
|
1219
|
+
point_basis = fem.PointBasisSpace(pic)
|
|
1220
|
+
point_space = fem.make_collocated_function_space(point_basis)
|
|
1221
|
+
point_test = fem.make_test(point_space, domain=domain)
|
|
1222
|
+
test.assertEqual(point_test.space_restriction.node_count(), 3)
|
|
1223
|
+
|
|
1224
|
+
ones = fem.integrate(linear_form, fields={"u": point_test}, quadrature=pic)
|
|
1225
|
+
test.assertAlmostEqual(np.sum(ones.numpy()), pic.active_cell_count() / geo.cell_count(), places=5)
|
|
1226
|
+
|
|
1227
|
+
zeros = fem.integrate(linear_form, quadrature=other_quadrature, fields={"u": point_test})
|
|
1228
|
+
test.assertAlmostEqual(np.sum(zeros.numpy()), 0.0, places=5)
|
|
1229
|
+
|
|
1230
|
+
linear_vec = fem.make_polynomial_space(geo, dtype=wp.vec2)
|
|
1231
|
+
linear_test = fem.make_test(linear_vec)
|
|
1232
|
+
point_trial = fem.make_trial(point_space)
|
|
1233
|
+
|
|
1234
|
+
mat = fem.integrate(vector_divergence_form, fields={"u": linear_test, "q": point_trial}, quadrature=pic)
|
|
1235
|
+
test.assertEqual(mat.nrow, 9)
|
|
1236
|
+
test.assertEqual(mat.ncol, 3)
|
|
1237
|
+
test.assertEqual(mat.nnz_sync(), 12)
|
|
1238
|
+
|
|
1204
1239
|
|
|
1205
1240
|
@fem.integrand
|
|
1206
1241
|
def _bicubic(s: Sample, domain: Domain):
|
|
@@ -1228,7 +1263,7 @@ def test_particle_quadratures(test, device):
|
|
|
1228
1263
|
|
|
1229
1264
|
explicit_quadrature = fem.ExplicitQuadrature(domain, points, weights)
|
|
1230
1265
|
|
|
1231
|
-
test.assertEqual(explicit_quadrature.
|
|
1266
|
+
test.assertEqual(explicit_quadrature.max_points_per_element(), points_per_cell)
|
|
1232
1267
|
test.assertEqual(explicit_quadrature.total_point_count(), points_per_cell * geo.cell_count())
|
|
1233
1268
|
|
|
1234
1269
|
val = fem.integrate(_bicubic, quadrature=explicit_quadrature)
|
|
@@ -1247,13 +1282,182 @@ def test_particle_quadratures(test, device):
|
|
|
1247
1282
|
|
|
1248
1283
|
pic_quadrature = fem.PicQuadrature(domain, positions=(element_indices, element_coords))
|
|
1249
1284
|
|
|
1250
|
-
test.
|
|
1285
|
+
test.assertEqual(pic_quadrature.max_points_per_element(), 2)
|
|
1251
1286
|
test.assertEqual(pic_quadrature.total_point_count(), 3)
|
|
1252
1287
|
test.assertEqual(pic_quadrature.active_cell_count(), 2)
|
|
1253
1288
|
|
|
1254
1289
|
val = fem.integrate(_piecewise_constant, quadrature=pic_quadrature)
|
|
1255
1290
|
test.assertAlmostEqual(val, 1.25, places=5)
|
|
1256
1291
|
|
|
1292
|
+
# Test differentiability of PicQuadrature w.r.t positions and measures
|
|
1293
|
+
points = wp.array([[0.25, 0.33], [0.33, 0.25], [0.8, 0.8]], dtype=wp.vec2, device=device, requires_grad=True)
|
|
1294
|
+
measures = wp.ones(3, dtype=float, device=device, requires_grad=True)
|
|
1295
|
+
|
|
1296
|
+
tape = wp.Tape()
|
|
1297
|
+
with tape:
|
|
1298
|
+
pic = fem.PicQuadrature(domain, positions=points, measures=measures, requires_grad=True)
|
|
1299
|
+
|
|
1300
|
+
pic.arg_value(device).particle_coords.grad.fill_(1.0)
|
|
1301
|
+
pic.arg_value(device).particle_fraction.grad.fill_(1.0)
|
|
1302
|
+
tape.backward()
|
|
1303
|
+
|
|
1304
|
+
assert_np_equal(points.grad.numpy(), np.full((3, 2), 2.0)) # == 1.0 / cell_size
|
|
1305
|
+
assert_np_equal(measures.grad.numpy(), np.full(3, 4.0)) # == 1.0 / cell_area
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
@wp.func
|
|
1309
|
+
def aniso_bicubic_fn(x: wp.vec2, scale: wp.vec2):
|
|
1310
|
+
return wp.pow(x[0] * scale[0], 3.0) * wp.pow(x[1] * scale[1], 3.0)
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
@wp.func
|
|
1314
|
+
def aniso_bicubic_grad(x: wp.vec2, scale: wp.vec2):
|
|
1315
|
+
return wp.vec2(
|
|
1316
|
+
3.0 * scale[0] * wp.pow(x[0] * scale[0], 2.0) * wp.pow(x[1] * scale[1], 3.0),
|
|
1317
|
+
3.0 * scale[1] * wp.pow(x[0] * scale[0], 3.0) * wp.pow(x[1] * scale[1], 2.0),
|
|
1318
|
+
)
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
def test_implicit_fields(test, device):
|
|
1322
|
+
geo = fem.Grid2D(res=wp.vec2i(2))
|
|
1323
|
+
domain = fem.Cells(geo)
|
|
1324
|
+
boundary = fem.BoundarySides(geo)
|
|
1325
|
+
|
|
1326
|
+
space = fem.make_polynomial_space(geo)
|
|
1327
|
+
vec_space = fem.make_polynomial_space(geo, dtype=wp.vec2)
|
|
1328
|
+
discrete_field = fem.make_discrete_field(space)
|
|
1329
|
+
discrete_vec_field = fem.make_discrete_field(vec_space)
|
|
1330
|
+
|
|
1331
|
+
# Uniform
|
|
1332
|
+
|
|
1333
|
+
uniform = fem.UniformField(domain, 5.0)
|
|
1334
|
+
fem.interpolate(uniform, dest=discrete_field)
|
|
1335
|
+
assert_np_equal(discrete_field.dof_values.numpy(), np.full(9, 5.0))
|
|
1336
|
+
|
|
1337
|
+
fem.interpolate(grad_field, fields={"p": uniform}, dest=discrete_vec_field)
|
|
1338
|
+
assert_np_equal(discrete_vec_field.dof_values.numpy(), np.zeros((9, 2)))
|
|
1339
|
+
|
|
1340
|
+
uniform.value = 2.0
|
|
1341
|
+
fem.interpolate(uniform.trace(), dest=fem.make_restriction(discrete_field, domain=boundary))
|
|
1342
|
+
assert_np_equal(discrete_field.dof_values.numpy(), np.array([2.0] * 4 + [5.0] + [2.0] * 4))
|
|
1343
|
+
|
|
1344
|
+
# Implicit
|
|
1345
|
+
|
|
1346
|
+
implicit = fem.ImplicitField(
|
|
1347
|
+
domain, func=aniso_bicubic_fn, values={"scale": wp.vec2(2.0, 4.0)}, grad_func=aniso_bicubic_grad
|
|
1348
|
+
)
|
|
1349
|
+
fem.interpolate(implicit, dest=discrete_field)
|
|
1350
|
+
assert_np_equal(
|
|
1351
|
+
discrete_field.dof_values.numpy(),
|
|
1352
|
+
np.array([0.0, 0.0, 0.0, 0.0, 2.0**3, 4.0**3, 0.0, 2.0**3 * 2.0**3, 4.0**3 * 2.0**3]),
|
|
1353
|
+
)
|
|
1354
|
+
|
|
1355
|
+
fem.interpolate(grad_field, fields={"p": implicit}, dest=discrete_vec_field)
|
|
1356
|
+
assert_np_equal(discrete_vec_field.dof_values.numpy()[0], np.zeros(2))
|
|
1357
|
+
assert_np_equal(discrete_vec_field.dof_values.numpy()[-1], np.full(2, (2.0**9.0 * 3.0)))
|
|
1358
|
+
|
|
1359
|
+
implicit.values.scale = wp.vec2(-2.0, -2.0)
|
|
1360
|
+
fem.interpolate(implicit.trace(), dest=fem.make_restriction(discrete_field, domain=boundary))
|
|
1361
|
+
assert_np_equal(
|
|
1362
|
+
discrete_field.dof_values.numpy(),
|
|
1363
|
+
np.array([0.0, 0.0, 0.0, 0.0, 2.0**3, 2.0**3, 0.0, 2.0**3, 4.0**3]),
|
|
1364
|
+
)
|
|
1365
|
+
|
|
1366
|
+
# Nonconforming
|
|
1367
|
+
|
|
1368
|
+
geo2 = fem.Grid2D(res=wp.vec2i(1), bounds_lo=wp.vec2(0.25, 0.25), bounds_hi=wp.vec2(2.0, 2.0))
|
|
1369
|
+
domain2 = fem.Cells(geo2)
|
|
1370
|
+
boundary2 = fem.BoundarySides(geo2)
|
|
1371
|
+
space2 = fem.make_polynomial_space(geo2)
|
|
1372
|
+
vec_space2 = fem.make_polynomial_space(geo2, dtype=wp.vec2)
|
|
1373
|
+
discrete_field2 = fem.make_discrete_field(space2)
|
|
1374
|
+
discrete_vec_field2 = fem.make_discrete_field(vec_space2)
|
|
1375
|
+
|
|
1376
|
+
nonconforming = fem.NonconformingField(domain2, discrete_field, background=5.0)
|
|
1377
|
+
fem.interpolate(
|
|
1378
|
+
nonconforming,
|
|
1379
|
+
dest=discrete_field2,
|
|
1380
|
+
)
|
|
1381
|
+
assert_np_equal(discrete_field2.dof_values.numpy(), np.array([2.0] + [5.0] * 3))
|
|
1382
|
+
|
|
1383
|
+
fem.interpolate(grad_field, fields={"p": nonconforming}, dest=discrete_vec_field2)
|
|
1384
|
+
assert_np_equal(discrete_vec_field2.dof_values.numpy()[0], np.full(2, 8.0))
|
|
1385
|
+
assert_np_equal(discrete_vec_field2.dof_values.numpy()[-1], np.zeros(2))
|
|
1386
|
+
|
|
1387
|
+
discrete_field2.dof_values.zero_()
|
|
1388
|
+
fem.interpolate(
|
|
1389
|
+
nonconforming.trace(),
|
|
1390
|
+
dest=fem.make_restriction(discrete_field2, domain=boundary2),
|
|
1391
|
+
)
|
|
1392
|
+
assert_np_equal(discrete_field2.dof_values.numpy(), np.array([2.0] + [5.0] * 3))
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
@wp.kernel
|
|
1396
|
+
def test_qr_eigenvalues():
|
|
1397
|
+
tol = 1.0e-6
|
|
1398
|
+
|
|
1399
|
+
# zero
|
|
1400
|
+
Zero = wp.mat33(0.0)
|
|
1401
|
+
Id = wp.identity(n=3, dtype=float)
|
|
1402
|
+
D3, P3 = symmetric_eigenvalues_qr(Zero, tol * tol)
|
|
1403
|
+
wp.expect_eq(D3, wp.vec3(0.0))
|
|
1404
|
+
wp.expect_eq(P3, Id)
|
|
1405
|
+
|
|
1406
|
+
# Identity
|
|
1407
|
+
D3, P3 = symmetric_eigenvalues_qr(Id, tol * tol)
|
|
1408
|
+
wp.expect_eq(D3, wp.vec3(1.0))
|
|
1409
|
+
wp.expect_eq(wp.transpose(P3) * P3, Id)
|
|
1410
|
+
|
|
1411
|
+
# rank 1
|
|
1412
|
+
v = wp.vec4(0.0, 1.0, 1.0, 0.0)
|
|
1413
|
+
Rank1 = wp.outer(v, v)
|
|
1414
|
+
D4, P4 = symmetric_eigenvalues_qr(Rank1, tol * tol)
|
|
1415
|
+
wp.expect_near(wp.max(D4), wp.length_sq(v), tol)
|
|
1416
|
+
Err4 = wp.transpose(P4) * wp.diag(D4) * P4 - Rank1
|
|
1417
|
+
wp.expect_near(wp.ddot(Err4, Err4), 0.0, tol)
|
|
1418
|
+
|
|
1419
|
+
# rank 2
|
|
1420
|
+
v2 = wp.vec4(0.0, 0.5, -0.5, 0.0)
|
|
1421
|
+
Rank2 = Rank1 + wp.outer(v2, v2)
|
|
1422
|
+
D4, P4 = symmetric_eigenvalues_qr(Rank2, tol * tol)
|
|
1423
|
+
wp.expect_near(wp.max(D4), wp.length_sq(v), tol)
|
|
1424
|
+
wp.expect_near(D4[0] + D4[1] + D4[2] + D4[3], wp.length_sq(v) + wp.length_sq(v2), tol)
|
|
1425
|
+
Err4 = wp.transpose(P4) * wp.diag(D4) * P4 - Rank2
|
|
1426
|
+
wp.expect_near(wp.ddot(Err4, Err4), 0.0, tol)
|
|
1427
|
+
|
|
1428
|
+
# rank 4
|
|
1429
|
+
v3 = wp.vec4(1.0, 2.0, 3.0, 4.0)
|
|
1430
|
+
v4 = wp.vec4(2.0, 1.0, 0.0, -1.0)
|
|
1431
|
+
Rank4 = Rank2 + wp.outer(v3, v3) + wp.outer(v4, v4)
|
|
1432
|
+
D4, P4 = symmetric_eigenvalues_qr(Rank4, tol * tol)
|
|
1433
|
+
Err4 = wp.transpose(P4) * wp.diag(D4) * P4 - Rank4
|
|
1434
|
+
wp.expect_near(wp.ddot(Err4, Err4), 0.0, tol)
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
@wp.kernel
|
|
1438
|
+
def test_qr_inverse():
|
|
1439
|
+
rng = wp.rand_init(4356, wp.tid())
|
|
1440
|
+
M = wp.mat33(
|
|
1441
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1442
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1443
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1444
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1445
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1446
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1447
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1448
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1449
|
+
wp.randf(rng, 0.0, 10.0),
|
|
1450
|
+
)
|
|
1451
|
+
|
|
1452
|
+
if wp.determinant(M) != 0.0:
|
|
1453
|
+
tol = 1.0e-8
|
|
1454
|
+
Mi = inverse_qr(M)
|
|
1455
|
+
Id = wp.identity(n=3, dtype=float)
|
|
1456
|
+
Err = M * Mi - Id
|
|
1457
|
+
wp.expect_near(wp.ddot(Err, Err), 0.0, tol)
|
|
1458
|
+
Err = Mi * M - Id
|
|
1459
|
+
wp.expect_near(wp.ddot(Err, Err), 0.0, tol)
|
|
1460
|
+
|
|
1257
1461
|
|
|
1258
1462
|
devices = get_test_devices()
|
|
1259
1463
|
cuda_devices = get_selected_cuda_test_devices()
|
|
@@ -1281,6 +1485,9 @@ add_function_test(TestFem, "test_deformed_geometry", test_deformed_geometry, dev
|
|
|
1281
1485
|
add_function_test(TestFem, "test_dof_mapper", test_dof_mapper)
|
|
1282
1486
|
add_function_test(TestFem, "test_point_basis", test_point_basis)
|
|
1283
1487
|
add_function_test(TestFem, "test_particle_quadratures", test_particle_quadratures)
|
|
1488
|
+
add_function_test(TestFem, "test_implicit_fields", test_implicit_fields)
|
|
1489
|
+
add_kernel_test(TestFem, test_qr_eigenvalues, dim=1, devices=devices)
|
|
1490
|
+
add_kernel_test(TestFem, test_qr_inverse, dim=100, devices=devices)
|
|
1284
1491
|
|
|
1285
1492
|
|
|
1286
1493
|
class TestFemShapeFunctions(unittest.TestCase):
|
|
@@ -1294,5 +1501,5 @@ add_function_test(TestFemShapeFunctions, "test_tet_shape_functions", test_tet_sh
|
|
|
1294
1501
|
|
|
1295
1502
|
|
|
1296
1503
|
if __name__ == "__main__":
|
|
1297
|
-
wp.
|
|
1298
|
-
unittest.main(verbosity=2)
|
|
1504
|
+
wp.clear_kernel_cache()
|
|
1505
|
+
unittest.main(verbosity=2, failfast=True)
|
warp/tests/test_fp16.py
CHANGED
warp/tests/test_func.py
CHANGED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Copyright (c) 2024 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
# and proprietary rights in and to this software, related documentation
|
|
4
|
+
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
# distribution of this software and related documentation without an express
|
|
6
|
+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
# This is what we are actually testing.
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import unittest
|
|
12
|
+
|
|
13
|
+
import warp as wp
|
|
14
|
+
from warp.tests.unittest_utils import *
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@wp.struct
|
|
18
|
+
class FooData:
|
|
19
|
+
x: float
|
|
20
|
+
y: float
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Foo:
|
|
24
|
+
Data = FooData
|
|
25
|
+
|
|
26
|
+
@wp.func
|
|
27
|
+
def compute():
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@wp.kernel
|
|
32
|
+
def kernel_1(
|
|
33
|
+
out: wp.array(dtype=float),
|
|
34
|
+
):
|
|
35
|
+
tid = wp.tid()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@wp.kernel
|
|
39
|
+
def kernel_2(
|
|
40
|
+
out: wp.array(dtype=float),
|
|
41
|
+
):
|
|
42
|
+
tid = wp.tid()
|
|
43
|
+
out[tid] = 1.23
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def create_kernel_3(foo: Foo):
|
|
47
|
+
def fn(
|
|
48
|
+
data: foo.Data,
|
|
49
|
+
out: wp.array(dtype=float),
|
|
50
|
+
):
|
|
51
|
+
tid = wp.tid()
|
|
52
|
+
|
|
53
|
+
# Referencing a variable in a type hint like `foo.Data` isn't officially
|
|
54
|
+
# accepted by Python but it's still being used in some places (e.g.: `warp.fem`)
|
|
55
|
+
# where it works only because the variable being referenced within the function,
|
|
56
|
+
# which causes it to be promoted to a closure variable. Without that,
|
|
57
|
+
# it wouldn't be possible to resolve `foo` and to evaluate the `foo.Data`
|
|
58
|
+
# string to its corresponding type.
|
|
59
|
+
foo.compute()
|
|
60
|
+
|
|
61
|
+
out[tid] = data.x + data.y
|
|
62
|
+
|
|
63
|
+
return wp.Kernel(func=fn)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_future_annotations(test, device):
|
|
67
|
+
foo = Foo()
|
|
68
|
+
foo_data = FooData()
|
|
69
|
+
foo_data.x = 1.23
|
|
70
|
+
foo_data.y = 2.34
|
|
71
|
+
|
|
72
|
+
out = wp.empty(1, dtype=float)
|
|
73
|
+
|
|
74
|
+
kernel_3 = create_kernel_3(foo)
|
|
75
|
+
|
|
76
|
+
wp.launch(kernel_1, dim=out.shape, outputs=(out,))
|
|
77
|
+
wp.launch(kernel_2, dim=out.shape, outputs=(out,))
|
|
78
|
+
wp.launch(kernel_3, dim=out.shape, inputs=(foo_data,), outputs=(out,))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class TestFutureAnnotations(unittest.TestCase):
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
add_function_test(TestFutureAnnotations, "test_future_annotations", test_future_annotations)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
wp.clear_kernel_cache()
|
|
90
|
+
unittest.main(verbosity=2)
|
warp/tests/test_generics.py
CHANGED
|
@@ -592,5 +592,5 @@ add_function_test(TestGenerics, "test_type_operator_misspell", test_type_operato
|
|
|
592
592
|
add_function_test(TestGenerics, "test_type_attribute_error", test_type_attribute_error, devices=devices)
|
|
593
593
|
|
|
594
594
|
if __name__ == "__main__":
|
|
595
|
-
wp.
|
|
595
|
+
wp.clear_kernel_cache()
|
|
596
596
|
unittest.main(verbosity=2)
|
warp/tests/test_grad.py
CHANGED
warp/tests/test_grad_customs.py
CHANGED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Copyright (c) 2024 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
# and proprietary rights in and to this software, related documentation
|
|
4
|
+
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
# distribution of this software and related documentation without an express
|
|
6
|
+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
import unittest
|
|
9
|
+
|
|
10
|
+
import warp as wp
|
|
11
|
+
from warp.autograd import gradcheck, gradcheck_tape, jacobian, jacobian_fd
|
|
12
|
+
from warp.tests.unittest_utils import *
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@wp.kernel
|
|
16
|
+
def kernel_3d(
|
|
17
|
+
a: wp.array(dtype=float, ndim=3),
|
|
18
|
+
b: wp.array(dtype=float, ndim=3),
|
|
19
|
+
c: wp.array(dtype=float, ndim=3),
|
|
20
|
+
out1: wp.array(dtype=float, ndim=3),
|
|
21
|
+
out2: wp.array(dtype=float, ndim=3),
|
|
22
|
+
):
|
|
23
|
+
i, j, k = wp.tid()
|
|
24
|
+
out1[i, j, k] = a[i, j, k] * b[i, j, k] + c[i, j, k]
|
|
25
|
+
out2[i, j, k] = -a[i, j, k] * b[i, j, k] - c[i, j, k]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@wp.kernel
|
|
29
|
+
def kernel_mixed(
|
|
30
|
+
a: wp.array(dtype=float),
|
|
31
|
+
b: wp.array(dtype=wp.vec3),
|
|
32
|
+
out1: wp.array(dtype=wp.vec2),
|
|
33
|
+
out2: wp.array(dtype=wp.quat),
|
|
34
|
+
):
|
|
35
|
+
tid = wp.tid()
|
|
36
|
+
ai, bi = a[tid], b[tid]
|
|
37
|
+
out1[tid] = wp.vec2(ai * wp.length(bi), -ai * wp.dot(bi, wp.vec3(0.1, 1.0, -0.1)))
|
|
38
|
+
out2[tid] = wp.normalize(wp.quat(ai, bi[0], bi[1], bi[2]))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@wp.kernel
|
|
42
|
+
def vec_length_kernel(a: wp.array(dtype=wp.vec3), out: wp.array(dtype=float)):
|
|
43
|
+
tid = wp.tid()
|
|
44
|
+
v = a[tid]
|
|
45
|
+
# instead of wp.length(v), we use a trivial implementation that
|
|
46
|
+
# fails when a division by zero is occurs in the backward pass of sqrt
|
|
47
|
+
out[tid] = wp.sqrt(v[0] ** 2.0 + v[1] ** 2.0 + v[2] ** 2.0)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@wp.func
|
|
51
|
+
def wrong_grad_func(x: float):
|
|
52
|
+
return x * x
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@wp.func_grad(wrong_grad_func)
|
|
56
|
+
def adj_wrong_grad_func(x: float, adj: float):
|
|
57
|
+
wp.adjoint[x] -= 2.0 * x * adj
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@wp.kernel
|
|
61
|
+
def wrong_grad_kernel(a: wp.array(dtype=float), out: wp.array(dtype=float)):
|
|
62
|
+
tid = wp.tid()
|
|
63
|
+
out[tid] = wrong_grad_func(a[tid])
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_gradcheck_3d(test, device):
|
|
67
|
+
a_3d = wp.array([((2.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
68
|
+
b_3d = wp.array([((3.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
69
|
+
c_3d = wp.array([((4.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
70
|
+
|
|
71
|
+
out1_3d = wp.array([((3.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
72
|
+
out2_3d = wp.array([((4.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
73
|
+
|
|
74
|
+
jacs_ad = jacobian(
|
|
75
|
+
kernel_3d,
|
|
76
|
+
dim=a_3d.shape,
|
|
77
|
+
inputs=[a_3d, b_3d, c_3d],
|
|
78
|
+
outputs=[out1_3d, out2_3d],
|
|
79
|
+
max_outputs_per_var=4,
|
|
80
|
+
input_output_mask=[("a", "out1"), ("b", "out2")],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
assert sorted(jacs_ad.keys()) == [(0, 0), (1, 1)]
|
|
84
|
+
assert jacs_ad[(0, 0)].shape == (6, 6)
|
|
85
|
+
assert jacs_ad[(1, 1)].shape == (6, 6)
|
|
86
|
+
# all entries beyond the max_outputs_per_var are NaN
|
|
87
|
+
assert np.all(np.isnan(jacs_ad[(0, 0)].numpy()[4:]))
|
|
88
|
+
assert np.all(np.isnan(jacs_ad[(1, 1)].numpy()[4:]))
|
|
89
|
+
|
|
90
|
+
jacs_fd = jacobian_fd(
|
|
91
|
+
kernel_3d,
|
|
92
|
+
dim=a_3d.shape,
|
|
93
|
+
inputs=[a_3d, b_3d, c_3d],
|
|
94
|
+
outputs=[out1_3d, out2_3d],
|
|
95
|
+
max_inputs_per_var=4,
|
|
96
|
+
input_output_mask=[("a", "out1"), ("b", "out2")],
|
|
97
|
+
eps=1e-4,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
assert sorted(jacs_fd.keys()) == [(0, 0), (1, 1)]
|
|
101
|
+
assert jacs_fd[(0, 0)].shape == (6, 6)
|
|
102
|
+
assert jacs_fd[(1, 1)].shape == (6, 6)
|
|
103
|
+
# all entries beyond the max_inputs_per_var are NaN
|
|
104
|
+
assert np.all(np.isnan(jacs_fd[(0, 0)].numpy()[:, 4:]))
|
|
105
|
+
assert np.all(np.isnan(jacs_fd[(1, 1)].numpy()[:, 4:]))
|
|
106
|
+
|
|
107
|
+
# manual gradcheck
|
|
108
|
+
assert np.allclose(jacs_ad[(0, 0)].numpy()[:4, :4], jacs_fd[(0, 0)].numpy()[:4, :4], atol=1e-2, rtol=1e-2)
|
|
109
|
+
assert np.allclose(jacs_ad[(1, 1)].numpy()[:4, :4], jacs_fd[(1, 1)].numpy()[:4, :4], atol=1e-2, rtol=1e-2)
|
|
110
|
+
|
|
111
|
+
passed = gradcheck(
|
|
112
|
+
kernel_3d,
|
|
113
|
+
dim=a_3d.shape,
|
|
114
|
+
inputs=[a_3d, b_3d, c_3d],
|
|
115
|
+
outputs=[out1_3d, out2_3d],
|
|
116
|
+
max_inputs_per_var=4,
|
|
117
|
+
max_outputs_per_var=4,
|
|
118
|
+
input_output_mask=[("a", "out1"), ("b", "out2")],
|
|
119
|
+
show_summary=False,
|
|
120
|
+
)
|
|
121
|
+
assert passed
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_gradcheck_mixed(test, device):
|
|
125
|
+
a = wp.array([2.0, -1.0], dtype=wp.float32, requires_grad=True, device=device)
|
|
126
|
+
b = wp.array([wp.vec3(3.0, 1.0, 2.0), wp.vec3(-4.0, -1.0, 0.0)], dtype=wp.vec3, requires_grad=True, device=device)
|
|
127
|
+
out1 = wp.zeros(2, dtype=wp.vec2, requires_grad=True, device=device)
|
|
128
|
+
out2 = wp.zeros(2, dtype=wp.quat, requires_grad=True, device=device)
|
|
129
|
+
|
|
130
|
+
jacs_ad = jacobian(
|
|
131
|
+
kernel_mixed,
|
|
132
|
+
dim=len(a),
|
|
133
|
+
inputs=[a, b],
|
|
134
|
+
outputs=[out1, out2],
|
|
135
|
+
)
|
|
136
|
+
jacs_fd = jacobian_fd(
|
|
137
|
+
kernel_mixed,
|
|
138
|
+
dim=len(a),
|
|
139
|
+
inputs=[a, b],
|
|
140
|
+
outputs=[out1, out2],
|
|
141
|
+
eps=1e-4,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# manual gradcheck
|
|
145
|
+
for i in range(2):
|
|
146
|
+
for j in range(2):
|
|
147
|
+
assert np.allclose(jacs_ad[(i, j)].numpy(), jacs_fd[(i, j)].numpy(), atol=1e-2, rtol=1e-2)
|
|
148
|
+
|
|
149
|
+
passed = gradcheck(
|
|
150
|
+
kernel_mixed,
|
|
151
|
+
dim=len(a),
|
|
152
|
+
inputs=[a, b],
|
|
153
|
+
outputs=[out1, out2],
|
|
154
|
+
raise_exception=False,
|
|
155
|
+
show_summary=False,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
assert passed
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def test_gradcheck_nan(test, device):
|
|
162
|
+
a = wp.array([wp.vec3(1.0, 2.0, 3.0), wp.vec3(0.0, 0.0, 0.0)], dtype=wp.vec3, requires_grad=True, device=device)
|
|
163
|
+
out = wp.array([0.0, 0.0], dtype=float, requires_grad=True, device=device)
|
|
164
|
+
|
|
165
|
+
with test.assertRaises(ValueError):
|
|
166
|
+
gradcheck(
|
|
167
|
+
vec_length_kernel,
|
|
168
|
+
dim=a.shape,
|
|
169
|
+
inputs=[a],
|
|
170
|
+
outputs=[out],
|
|
171
|
+
raise_exception=True,
|
|
172
|
+
show_summary=False,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def test_gradcheck_incorrect(test, device):
|
|
177
|
+
a = wp.array([1.0, 2.0, 3.0], dtype=wp.float32, requires_grad=True, device=device)
|
|
178
|
+
out = wp.zeros_like(a)
|
|
179
|
+
|
|
180
|
+
with test.assertRaises(ValueError):
|
|
181
|
+
gradcheck(
|
|
182
|
+
wrong_grad_kernel,
|
|
183
|
+
dim=a.shape,
|
|
184
|
+
inputs=[a],
|
|
185
|
+
outputs=[out],
|
|
186
|
+
raise_exception=True,
|
|
187
|
+
show_summary=False,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def test_gradcheck_tape(test, device):
|
|
192
|
+
a = wp.array([2.0, -1.0], dtype=wp.float32, requires_grad=True, device=device)
|
|
193
|
+
b = wp.array([wp.vec3(3.0, 1.0, 2.0), wp.vec3(-4.0, -1.0, 0.0)], dtype=wp.vec3, requires_grad=True, device=device)
|
|
194
|
+
out1 = wp.zeros(2, dtype=wp.vec2, requires_grad=True, device=device)
|
|
195
|
+
out2 = wp.zeros(2, dtype=wp.quat, requires_grad=True, device=device)
|
|
196
|
+
|
|
197
|
+
a_3d = wp.array([((2.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
198
|
+
b_3d = wp.array([((3.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
199
|
+
c_3d = wp.array([((4.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
200
|
+
|
|
201
|
+
out1_3d = wp.array([((3.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
202
|
+
out2_3d = wp.array([((4.0, 0.0), (1.0, 0.0), (2.0, 0.0))], dtype=float, requires_grad=True, device=device)
|
|
203
|
+
|
|
204
|
+
tape = wp.Tape()
|
|
205
|
+
with tape:
|
|
206
|
+
wp.launch(
|
|
207
|
+
kernel_mixed,
|
|
208
|
+
dim=len(a),
|
|
209
|
+
inputs=[a, b],
|
|
210
|
+
outputs=[out1, out2],
|
|
211
|
+
device=device,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
wp.launch(
|
|
215
|
+
kernel_3d,
|
|
216
|
+
dim=a_3d.shape,
|
|
217
|
+
inputs=[a_3d, b_3d, c_3d],
|
|
218
|
+
outputs=[out1_3d, out2_3d],
|
|
219
|
+
device=device,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
passed = gradcheck_tape(
|
|
223
|
+
tape,
|
|
224
|
+
raise_exception=False,
|
|
225
|
+
show_summary=False,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
assert passed
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
devices = get_test_devices()
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class TestGradDebug(unittest.TestCase):
|
|
235
|
+
pass
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
add_function_test(TestGradDebug, "test_gradcheck_3d", test_gradcheck_3d, devices=devices)
|
|
239
|
+
add_function_test(TestGradDebug, "test_gradcheck_mixed", test_gradcheck_mixed, devices=devices)
|
|
240
|
+
add_function_test(TestGradDebug, "test_gradcheck_nan", test_gradcheck_nan, devices=devices)
|
|
241
|
+
add_function_test(TestGradDebug, "test_gradcheck_incorrect", test_gradcheck_incorrect, devices=devices)
|
|
242
|
+
add_function_test(TestGradDebug, "test_gradcheck_tape", test_gradcheck_tape, devices=devices)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
if __name__ == "__main__":
|
|
246
|
+
wp.build.clear_kernel_cache()
|
|
247
|
+
unittest.main(verbosity=2, failfast=False)
|
warp/tests/test_hash_grid.py
CHANGED
|
@@ -198,11 +198,16 @@ class TestHashGrid(unittest.TestCase):
|
|
|
198
198
|
|
|
199
199
|
wp.Kernel(func=kernel_fn)
|
|
200
200
|
|
|
201
|
+
def test_hashgrid_new_del(self):
|
|
202
|
+
# test the scenario in which a hashgrid is created but not initialized before gc
|
|
203
|
+
instance = wp.HashGrid.__new__(wp.HashGrid)
|
|
204
|
+
instance.__del__()
|
|
205
|
+
|
|
201
206
|
|
|
202
207
|
add_function_test(TestHashGrid, "test_hashgrid_query", test_hashgrid_query, devices=devices)
|
|
203
208
|
add_function_test(TestHashGrid, "test_hashgrid_inputs", test_hashgrid_inputs, devices=devices)
|
|
204
209
|
|
|
205
210
|
|
|
206
211
|
if __name__ == "__main__":
|
|
207
|
-
wp.
|
|
212
|
+
wp.clear_kernel_cache()
|
|
208
213
|
unittest.main(verbosity=2, failfast=False)
|