warp-lang 1.5.1__py3-none-win_amd64.whl → 1.6.0__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/__init__.py +5 -0
- warp/autograd.py +414 -191
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +40 -12
- warp/build_dll.py +13 -6
- warp/builtins.py +1076 -480
- warp/codegen.py +240 -119
- warp/config.py +1 -1
- warp/context.py +298 -84
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_gemm.py +27 -18
- warp/examples/benchmarks/benchmark_interop_paddle.py +3 -3
- warp/examples/benchmarks/benchmark_interop_torch.py +3 -3
- warp/examples/core/example_torch.py +18 -34
- warp/examples/fem/example_apic_fluid.py +1 -0
- warp/examples/fem/example_mixed_elasticity.py +1 -1
- warp/examples/optim/example_bounce.py +1 -1
- warp/examples/optim/example_cloth_throw.py +1 -1
- warp/examples/optim/example_diffray.py +4 -15
- warp/examples/optim/example_drone.py +1 -1
- warp/examples/optim/example_softbody_properties.py +392 -0
- warp/examples/optim/example_trajectory.py +1 -3
- warp/examples/optim/example_walker.py +5 -0
- warp/examples/sim/example_cartpole.py +0 -2
- warp/examples/sim/example_cloth_self_contact.py +260 -0
- warp/examples/sim/example_granular_collision_sdf.py +4 -5
- warp/examples/sim/example_jacobian_ik.py +0 -2
- warp/examples/sim/example_quadruped.py +5 -2
- warp/examples/tile/example_tile_cholesky.py +79 -0
- warp/examples/tile/example_tile_convolution.py +2 -2
- warp/examples/tile/example_tile_fft.py +2 -2
- warp/examples/tile/example_tile_filtering.py +3 -3
- warp/examples/tile/example_tile_matmul.py +4 -4
- warp/examples/tile/example_tile_mlp.py +12 -12
- warp/examples/tile/example_tile_nbody.py +180 -0
- warp/examples/tile/example_tile_walker.py +319 -0
- warp/math.py +147 -0
- warp/native/array.h +12 -0
- warp/native/builtin.h +0 -1
- warp/native/bvh.cpp +149 -70
- warp/native/bvh.cu +287 -68
- warp/native/bvh.h +195 -85
- warp/native/clang/clang.cpp +5 -1
- warp/native/cuda_util.cpp +35 -0
- warp/native/cuda_util.h +5 -0
- warp/native/exports.h +40 -40
- warp/native/intersect.h +17 -0
- warp/native/mat.h +41 -0
- warp/native/mathdx.cpp +19 -0
- warp/native/mesh.cpp +25 -8
- warp/native/mesh.cu +153 -101
- warp/native/mesh.h +482 -403
- warp/native/quat.h +40 -0
- warp/native/solid_angle.h +7 -0
- warp/native/sort.cpp +85 -0
- warp/native/sort.cu +34 -0
- warp/native/sort.h +3 -1
- warp/native/spatial.h +11 -0
- warp/native/tile.h +1185 -664
- warp/native/tile_reduce.h +8 -6
- warp/native/vec.h +41 -0
- warp/native/warp.cpp +8 -1
- warp/native/warp.cu +263 -40
- warp/native/warp.h +19 -5
- warp/optim/linear.py +22 -4
- warp/render/render_opengl.py +124 -59
- warp/sim/__init__.py +6 -1
- warp/sim/collide.py +270 -26
- warp/sim/integrator_euler.py +25 -7
- warp/sim/integrator_featherstone.py +154 -35
- warp/sim/integrator_vbd.py +842 -40
- warp/sim/model.py +111 -53
- warp/stubs.py +248 -115
- warp/tape.py +28 -30
- warp/tests/aux_test_module_unload.py +15 -0
- warp/tests/{test_sim_grad.py → flaky_test_sim_grad.py} +104 -63
- warp/tests/test_array.py +74 -0
- warp/tests/test_assert.py +242 -0
- warp/tests/test_codegen.py +14 -61
- warp/tests/test_collision.py +2 -2
- warp/tests/test_examples.py +9 -0
- warp/tests/test_grad_debug.py +87 -2
- warp/tests/test_hash_grid.py +1 -1
- warp/tests/test_ipc.py +116 -0
- warp/tests/test_mat.py +138 -167
- warp/tests/test_math.py +47 -1
- warp/tests/test_matmul.py +11 -7
- warp/tests/test_matmul_lite.py +4 -4
- warp/tests/test_mesh.py +84 -60
- warp/tests/test_mesh_query_aabb.py +165 -0
- warp/tests/test_mesh_query_point.py +328 -286
- warp/tests/test_mesh_query_ray.py +134 -121
- warp/tests/test_mlp.py +2 -2
- warp/tests/test_operators.py +43 -0
- warp/tests/test_overwrite.py +2 -2
- warp/tests/test_quat.py +77 -0
- warp/tests/test_reload.py +29 -0
- warp/tests/test_sim_grad_bounce_linear.py +204 -0
- warp/tests/test_static.py +16 -0
- warp/tests/test_tape.py +25 -0
- warp/tests/test_tile.py +134 -191
- warp/tests/test_tile_load.py +356 -0
- warp/tests/test_tile_mathdx.py +61 -8
- warp/tests/test_tile_mlp.py +17 -17
- warp/tests/test_tile_reduce.py +24 -18
- warp/tests/test_tile_shared_memory.py +66 -17
- warp/tests/test_tile_view.py +165 -0
- warp/tests/test_torch.py +35 -0
- warp/tests/test_utils.py +36 -24
- warp/tests/test_vec.py +110 -0
- warp/tests/unittest_suites.py +29 -4
- warp/tests/unittest_utils.py +30 -11
- warp/thirdparty/unittest_parallel.py +2 -2
- warp/types.py +409 -99
- warp/utils.py +9 -5
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.0.dist-info}/METADATA +68 -44
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.0.dist-info}/RECORD +121 -110
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.0.dist-info}/WHEEL +1 -1
- warp/examples/benchmarks/benchmark_tile.py +0 -179
- warp/native/tile_gemm.h +0 -341
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.5.1.dist-info → warp_lang-1.6.0.dist-info}/top_level.txt +0 -0
|
@@ -301,178 +301,190 @@ def test_mesh_query_point(test, device):
|
|
|
301
301
|
mesh_points = wp.array(np.array(mesh_geom.GetPointsAttr().Get()), dtype=wp.vec3, device=device)
|
|
302
302
|
mesh_indices = wp.array(np.array(tri_indices), dtype=int, device=device)
|
|
303
303
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
device=device
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
dist_error = np.max(np.abs(dist_query_no_sign - dist_brute))
|
|
450
|
-
|
|
451
|
-
test.assertTrue(
|
|
452
|
-
dist_error < tolerance, f"mesh_query_point_no_sign dist_error is {dist_error} which is >= {tolerance}"
|
|
453
|
-
)
|
|
454
|
-
|
|
455
|
-
dist_error = np.max(np.abs(dist_query_normal - dist_brute))
|
|
456
|
-
sign_error = np.max(np.abs(inside_query_normal - inside_brute))
|
|
457
|
-
|
|
458
|
-
test.assertTrue(
|
|
459
|
-
dist_error < tolerance, f"mesh_query_point_sign_normal dist_error is {dist_error} which is >= {tolerance}"
|
|
460
|
-
)
|
|
461
|
-
test.assertTrue(
|
|
462
|
-
sign_error < tolerance, f"mesh_query_point_sign_normal sign_error is {sign_error} which is >= {tolerance}"
|
|
463
|
-
)
|
|
304
|
+
if device.is_cpu:
|
|
305
|
+
constructors = ["sah", "median"]
|
|
306
|
+
else:
|
|
307
|
+
constructors = ["sah", "median", "lbvh"]
|
|
308
|
+
|
|
309
|
+
for constructor in constructors:
|
|
310
|
+
# create mesh
|
|
311
|
+
mesh = wp.Mesh(
|
|
312
|
+
points=mesh_points,
|
|
313
|
+
velocities=None,
|
|
314
|
+
indices=mesh_indices,
|
|
315
|
+
support_winding_number=True,
|
|
316
|
+
bvh_constructor=constructor,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
p = particle_grid(32, 32, 32, np.array([-1.1, -1.1, -1.1]), 0.05, 0.0)
|
|
320
|
+
|
|
321
|
+
query_count = len(p)
|
|
322
|
+
query_points = wp.array(p, dtype=wp.vec3, device=device)
|
|
323
|
+
|
|
324
|
+
signs_query = wp.zeros(query_count, dtype=float, device=device)
|
|
325
|
+
faces_query = wp.zeros(query_count, dtype=int, device=device)
|
|
326
|
+
dist_query = wp.zeros(query_count, dtype=float, device=device)
|
|
327
|
+
|
|
328
|
+
faces_query_no_sign = wp.zeros(query_count, dtype=int, device=device)
|
|
329
|
+
dist_query_no_sign = wp.zeros(query_count, dtype=float, device=device)
|
|
330
|
+
|
|
331
|
+
signs_query_normal = wp.zeros(query_count, dtype=float, device=device)
|
|
332
|
+
faces_query_normal = wp.zeros(query_count, dtype=int, device=device)
|
|
333
|
+
dist_query_normal = wp.zeros(query_count, dtype=float, device=device)
|
|
334
|
+
|
|
335
|
+
signs_query_winding_number = wp.zeros(query_count, dtype=float, device=device)
|
|
336
|
+
faces_query_winding_number = wp.zeros(query_count, dtype=int, device=device)
|
|
337
|
+
dist_query_winding_number = wp.zeros(query_count, dtype=float, device=device)
|
|
338
|
+
|
|
339
|
+
signs_brute = wp.zeros(query_count, dtype=float, device=device)
|
|
340
|
+
faces_brute = wp.zeros(query_count, dtype=int, device=device)
|
|
341
|
+
dist_brute = wp.zeros(query_count, dtype=float, device=device)
|
|
342
|
+
|
|
343
|
+
wp.launch(
|
|
344
|
+
kernel=sample_mesh_query,
|
|
345
|
+
dim=query_count,
|
|
346
|
+
inputs=[mesh.id, query_points, faces_query, signs_query, dist_query],
|
|
347
|
+
device=device,
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
wp.launch(
|
|
351
|
+
kernel=sample_mesh_query_no_sign,
|
|
352
|
+
dim=query_count,
|
|
353
|
+
inputs=[mesh.id, query_points, faces_query_no_sign, dist_query_no_sign],
|
|
354
|
+
device=device,
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
wp.launch(
|
|
358
|
+
kernel=sample_mesh_query_sign_normal,
|
|
359
|
+
dim=query_count,
|
|
360
|
+
inputs=[mesh.id, query_points, faces_query_normal, signs_query_normal, dist_query_normal],
|
|
361
|
+
device=device,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
wp.launch(
|
|
365
|
+
kernel=sample_mesh_query_sign_winding_number,
|
|
366
|
+
dim=query_count,
|
|
367
|
+
inputs=[
|
|
368
|
+
mesh.id,
|
|
369
|
+
query_points,
|
|
370
|
+
faces_query_winding_number,
|
|
371
|
+
signs_query_winding_number,
|
|
372
|
+
dist_query_winding_number,
|
|
373
|
+
],
|
|
374
|
+
device=device,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
wp.launch(
|
|
378
|
+
kernel=sample_mesh_brute,
|
|
379
|
+
dim=query_count,
|
|
380
|
+
inputs=[
|
|
381
|
+
mesh_points,
|
|
382
|
+
mesh_indices,
|
|
383
|
+
int(len(mesh_indices) / 3),
|
|
384
|
+
query_points,
|
|
385
|
+
faces_brute,
|
|
386
|
+
signs_brute,
|
|
387
|
+
dist_brute,
|
|
388
|
+
],
|
|
389
|
+
device=device,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
signs_query = signs_query.numpy()
|
|
393
|
+
faces_query = faces_query.numpy()
|
|
394
|
+
dist_query = dist_query.numpy()
|
|
395
|
+
|
|
396
|
+
faces_query_no_sign = faces_query_no_sign.numpy()
|
|
397
|
+
dist_query_no_sign = dist_query_no_sign.numpy()
|
|
398
|
+
|
|
399
|
+
signs_query_normal = signs_query_normal.numpy()
|
|
400
|
+
faces_query_normal = faces_query_normal.numpy()
|
|
401
|
+
dist_query_normal = dist_query_normal.numpy()
|
|
402
|
+
|
|
403
|
+
signs_query_winding_number = signs_query_winding_number.numpy()
|
|
404
|
+
faces_query_winding_number = faces_query_winding_number.numpy()
|
|
405
|
+
dist_query_winding_number = dist_query_winding_number.numpy()
|
|
406
|
+
|
|
407
|
+
signs_brute = signs_brute.numpy()
|
|
408
|
+
faces_brute = faces_brute.numpy()
|
|
409
|
+
dist_brute = dist_brute.numpy()
|
|
410
|
+
|
|
411
|
+
query_points = query_points.numpy()
|
|
412
|
+
|
|
413
|
+
inside_query = [[0.0, 0.0, 0.0]]
|
|
414
|
+
inside_query_normal = [[0.0, 0.0, 0.0]]
|
|
415
|
+
inside_query_winding_number = [[0.0, 0.0, 0.0]]
|
|
416
|
+
inside_brute = [[0.0, 0.0, 0.0]]
|
|
417
|
+
|
|
418
|
+
for i in range(query_count):
|
|
419
|
+
if signs_query[i] < 0.0:
|
|
420
|
+
inside_query.append(query_points[i].tolist())
|
|
421
|
+
|
|
422
|
+
if signs_query_normal[i] < 0.0:
|
|
423
|
+
inside_query_normal.append(query_points[i].tolist())
|
|
424
|
+
|
|
425
|
+
if signs_query_winding_number[i] < 0.0:
|
|
426
|
+
inside_query_winding_number.append(query_points[i].tolist())
|
|
427
|
+
|
|
428
|
+
if signs_brute[i] > math.pi * 2.0:
|
|
429
|
+
inside_brute.append(query_points[i].tolist())
|
|
430
|
+
|
|
431
|
+
inside_query = np.array(inside_query)
|
|
432
|
+
inside_query_normal = np.array(inside_query_normal)
|
|
433
|
+
inside_query_winding_number = np.array(inside_query_winding_number)
|
|
434
|
+
inside_brute = np.array(inside_brute)
|
|
435
|
+
|
|
436
|
+
# import warp.render
|
|
437
|
+
|
|
438
|
+
# stage = warp.render.UsdRenderer("tests/outputs/test_mesh_query_point.usd")
|
|
439
|
+
|
|
440
|
+
# radius = 0.1
|
|
441
|
+
# stage.begin_frame(0.0)
|
|
442
|
+
# stage.render_mesh(points=mesh_points.numpy(), indices=mesh_indices.numpy(), name="mesh")
|
|
443
|
+
# stage.render_points(points=inside_query, radius=radius, name="query")
|
|
444
|
+
# stage.render_points(points=inside_brute, radius=radius, name="brute")
|
|
445
|
+
# stage.render_points(points=query_points, radius=radius, name="all")
|
|
446
|
+
# stage.end_frame()
|
|
447
|
+
|
|
448
|
+
# stage.save()
|
|
464
449
|
|
|
465
|
-
|
|
466
|
-
|
|
450
|
+
test.assertTrue(len(inside_query) == len(inside_brute))
|
|
451
|
+
test.assertTrue(len(inside_query_normal) == len(inside_brute))
|
|
452
|
+
test.assertTrue(len(inside_query_winding_number) == len(inside_brute))
|
|
467
453
|
|
|
468
|
-
|
|
469
|
-
dist_error
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
sign_error < tolerance,
|
|
474
|
-
|
|
475
|
-
|
|
454
|
+
tolerance = 1.5e-4
|
|
455
|
+
dist_error = np.max(np.abs(dist_query - dist_brute))
|
|
456
|
+
sign_error = np.max(np.abs(inside_query - inside_brute))
|
|
457
|
+
|
|
458
|
+
test.assertTrue(dist_error < tolerance, f"mesh_query_point dist_error is {dist_error} which is >= {tolerance}")
|
|
459
|
+
test.assertTrue(sign_error < tolerance, f"mesh_query_point sign_error is {sign_error} which is >= {tolerance}")
|
|
460
|
+
|
|
461
|
+
dist_error = np.max(np.abs(dist_query_no_sign - dist_brute))
|
|
462
|
+
|
|
463
|
+
test.assertTrue(
|
|
464
|
+
dist_error < tolerance, f"mesh_query_point_no_sign dist_error is {dist_error} which is >= {tolerance}"
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
dist_error = np.max(np.abs(dist_query_normal - dist_brute))
|
|
468
|
+
sign_error = np.max(np.abs(inside_query_normal - inside_brute))
|
|
469
|
+
|
|
470
|
+
test.assertTrue(
|
|
471
|
+
dist_error < tolerance, f"mesh_query_point_sign_normal dist_error is {dist_error} which is >= {tolerance}"
|
|
472
|
+
)
|
|
473
|
+
test.assertTrue(
|
|
474
|
+
sign_error < tolerance, f"mesh_query_point_sign_normal sign_error is {sign_error} which is >= {tolerance}"
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
dist_error = np.max(np.abs(dist_query_winding_number - dist_brute))
|
|
478
|
+
sign_error = np.max(np.abs(inside_query_winding_number - inside_brute))
|
|
479
|
+
|
|
480
|
+
test.assertTrue(
|
|
481
|
+
dist_error < tolerance,
|
|
482
|
+
f"mesh_query_point_sign_winding_number dist_error is {dist_error} which is >= {tolerance}",
|
|
483
|
+
)
|
|
484
|
+
test.assertTrue(
|
|
485
|
+
sign_error < tolerance,
|
|
486
|
+
f"mesh_query_point_sign_winding_number sign_error is {sign_error} which is >= {tolerance}",
|
|
487
|
+
)
|
|
476
488
|
|
|
477
489
|
|
|
478
490
|
@wp.kernel
|
|
@@ -517,69 +529,87 @@ def test_adj_mesh_query_point(test, device):
|
|
|
517
529
|
mesh_points = wp.array(np.array(mesh_geom.GetPointsAttr().Get()), dtype=wp.vec3, device=device)
|
|
518
530
|
mesh_indices = wp.array(np.array(tri_indices), dtype=int, device=device)
|
|
519
531
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
532
|
+
if device.is_cpu:
|
|
533
|
+
constructors = ["sah", "median"]
|
|
534
|
+
else:
|
|
535
|
+
constructors = ["sah", "median", "lbvh"]
|
|
536
|
+
|
|
537
|
+
for constructor in constructors:
|
|
538
|
+
# test tri
|
|
539
|
+
# print("Testing Single Triangle")
|
|
540
|
+
# mesh_points = wp.array(np.array([[0.0, 0.0, 0.0], [2.0, 0.0, 0.0], [0.0, 2.0, 0.0]]), dtype=wp.vec3, device=device)
|
|
541
|
+
# mesh_indices = wp.array(np.array([0,1,2]), dtype=int, device=device)
|
|
542
|
+
|
|
543
|
+
# create mesh
|
|
544
|
+
mesh = wp.Mesh(
|
|
545
|
+
points=mesh_points,
|
|
546
|
+
velocities=None,
|
|
547
|
+
indices=mesh_indices,
|
|
548
|
+
support_winding_number=True,
|
|
549
|
+
bvh_constructor=constructor,
|
|
550
|
+
)
|
|
524
551
|
|
|
525
|
-
|
|
526
|
-
|
|
552
|
+
# p = particle_grid(32, 32, 32, np.array([-5.0, -5.0, -5.0]), 0.1, 0.1)*100.0
|
|
553
|
+
p = wp.vec3(50.0, 50.0, 50.0)
|
|
527
554
|
|
|
528
|
-
|
|
529
|
-
p = wp.vec3(50.0, 50.0, 50.0)
|
|
555
|
+
tape = wp.Tape()
|
|
530
556
|
|
|
531
|
-
|
|
557
|
+
# analytic gradients
|
|
558
|
+
with tape:
|
|
559
|
+
query_points = wp.array(p, dtype=wp.vec3, device=device, requires_grad=True)
|
|
560
|
+
projected_points = wp.zeros(n=1, dtype=wp.vec3, device=device)
|
|
561
|
+
loss = wp.zeros(n=1, dtype=float, device=device, requires_grad=True)
|
|
532
562
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
563
|
+
wp.launch(
|
|
564
|
+
kernel=mesh_query_point_loss,
|
|
565
|
+
dim=1,
|
|
566
|
+
inputs=[mesh.id, query_points, projected_points, loss],
|
|
567
|
+
device=device,
|
|
568
|
+
)
|
|
538
569
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
)
|
|
570
|
+
tape.backward(loss=loss)
|
|
571
|
+
analytic = tape.gradients[query_points].numpy().flatten()
|
|
542
572
|
|
|
543
|
-
|
|
544
|
-
|
|
573
|
+
# numeric gradients
|
|
574
|
+
eps = 1.0e-3
|
|
575
|
+
loss_values = []
|
|
576
|
+
numeric = np.zeros(3)
|
|
545
577
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
578
|
+
offset_query_points = [
|
|
579
|
+
wp.vec3(p[0] - eps, p[1], p[2]),
|
|
580
|
+
wp.vec3(p[0] + eps, p[1], p[2]),
|
|
581
|
+
wp.vec3(p[0], p[1] - eps, p[2]),
|
|
582
|
+
wp.vec3(p[0], p[1] + eps, p[2]),
|
|
583
|
+
wp.vec3(p[0], p[1], p[2] - eps),
|
|
584
|
+
wp.vec3(p[0], p[1], p[2] + eps),
|
|
585
|
+
]
|
|
550
586
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
wp.vec3(p[0] + eps, p[1], p[2]),
|
|
554
|
-
wp.vec3(p[0], p[1] - eps, p[2]),
|
|
555
|
-
wp.vec3(p[0], p[1] + eps, p[2]),
|
|
556
|
-
wp.vec3(p[0], p[1], p[2] - eps),
|
|
557
|
-
wp.vec3(p[0], p[1], p[2] + eps),
|
|
558
|
-
]
|
|
587
|
+
for i in range(6):
|
|
588
|
+
q = offset_query_points[i]
|
|
559
589
|
|
|
560
|
-
|
|
561
|
-
|
|
590
|
+
query_points = wp.array(q, dtype=wp.vec3, device=device)
|
|
591
|
+
projected_points = wp.zeros(n=1, dtype=wp.vec3, device=device)
|
|
592
|
+
loss = wp.zeros(n=1, dtype=float, device=device)
|
|
562
593
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
594
|
+
wp.launch(
|
|
595
|
+
kernel=mesh_query_point_loss,
|
|
596
|
+
dim=1,
|
|
597
|
+
inputs=[mesh.id, query_points, projected_points, loss],
|
|
598
|
+
device=device,
|
|
599
|
+
)
|
|
566
600
|
|
|
567
|
-
|
|
568
|
-
kernel=mesh_query_point_loss, dim=1, inputs=[mesh.id, query_points, projected_points, loss], device=device
|
|
569
|
-
)
|
|
601
|
+
loss_values.append(loss.numpy()[0])
|
|
570
602
|
|
|
571
|
-
|
|
603
|
+
for i in range(3):
|
|
604
|
+
l_0 = loss_values[i * 2]
|
|
605
|
+
l_1 = loss_values[i * 2 + 1]
|
|
606
|
+
gradient = (l_1 - l_0) / (2.0 * eps)
|
|
607
|
+
numeric[i] = gradient
|
|
572
608
|
|
|
573
|
-
|
|
574
|
-
l_0 = loss_values[i * 2]
|
|
575
|
-
l_1 = loss_values[i * 2 + 1]
|
|
576
|
-
gradient = (l_1 - l_0) / (2.0 * eps)
|
|
577
|
-
numeric[i] = gradient
|
|
609
|
+
error = ((analytic - numeric) * (analytic - numeric)).sum(axis=0)
|
|
578
610
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
tolerance = 1.0e-3
|
|
582
|
-
test.assertTrue(error < tolerance, f"error is {error} which is >= {tolerance}")
|
|
611
|
+
tolerance = 1.0e-3
|
|
612
|
+
test.assertTrue(error < tolerance, f"error is {error} which is >= {tolerance}")
|
|
583
613
|
|
|
584
614
|
|
|
585
615
|
@wp.kernel
|
|
@@ -636,23 +666,29 @@ def test_mesh_query_furthest_point(test, device):
|
|
|
636
666
|
mesh_points = wp.array(np.array(mesh_geom.GetPointsAttr().Get()), dtype=wp.vec3, device=device)
|
|
637
667
|
mesh_indices = wp.array(np.array(tri_indices), dtype=int, device=device)
|
|
638
668
|
|
|
639
|
-
|
|
640
|
-
|
|
669
|
+
if device.is_cpu:
|
|
670
|
+
constructors = ["sah", "median"]
|
|
671
|
+
else:
|
|
672
|
+
constructors = ["sah", "median", "lbvh"]
|
|
673
|
+
|
|
674
|
+
for constructor in constructors:
|
|
675
|
+
# create mesh
|
|
676
|
+
mesh = wp.Mesh(points=mesh_points, indices=mesh_indices, bvh_constructor=constructor)
|
|
641
677
|
|
|
642
|
-
|
|
678
|
+
p = particle_grid(32, 32, 32, np.array([-1.1, -1.1, -1.1]), 0.05, 0.0)
|
|
643
679
|
|
|
644
|
-
|
|
645
|
-
|
|
680
|
+
query_count = len(p)
|
|
681
|
+
query_points = wp.array(p, dtype=wp.vec3, device=device)
|
|
646
682
|
|
|
647
|
-
|
|
648
|
-
|
|
683
|
+
dist_query = wp.zeros(query_count, dtype=float, device=device)
|
|
684
|
+
dist_brute = wp.zeros(query_count, dtype=float, device=device)
|
|
649
685
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
686
|
+
wp.launch(sample_furthest_points, dim=query_count, inputs=[mesh.id, query_points, dist_query], device=device)
|
|
687
|
+
wp.launch(
|
|
688
|
+
sample_furthest_points_brute, dim=query_count, inputs=[mesh_points, query_points, dist_brute], device=device
|
|
689
|
+
)
|
|
654
690
|
|
|
655
|
-
|
|
691
|
+
assert_np_equal(dist_query.numpy(), dist_brute.numpy(), tol=1.0e-3)
|
|
656
692
|
|
|
657
693
|
|
|
658
694
|
@wp.func
|
|
@@ -769,77 +805,83 @@ def point_query_aabb_and_closest(
|
|
|
769
805
|
|
|
770
806
|
@unittest.skipUnless(USD_AVAILABLE, "Requires usd-core")
|
|
771
807
|
def test_set_mesh_points(test, device):
|
|
808
|
+
if device.is_cpu:
|
|
809
|
+
constructors = ["sah", "median"]
|
|
810
|
+
else:
|
|
811
|
+
constructors = ["sah", "median", "lbvh"]
|
|
812
|
+
|
|
772
813
|
rng = np.random.default_rng(123)
|
|
773
814
|
|
|
774
815
|
vs, fs = load_mesh()
|
|
775
|
-
|
|
776
816
|
vertices1 = wp.array(vs, dtype=wp.vec3, device=device)
|
|
777
817
|
velocities1_np = rng.standard_normal(size=(vertices1.shape[0], 3))
|
|
778
818
|
velocities1 = wp.array(velocities1_np, dtype=wp.vec3, device=device)
|
|
779
819
|
|
|
780
820
|
faces = wp.array(fs, dtype=wp.int32, device=device)
|
|
781
|
-
|
|
782
|
-
fs_2D = faces.reshape((-1, 3))
|
|
821
|
+
|
|
783
822
|
n = 1000
|
|
784
823
|
query_radius = 0.2
|
|
785
|
-
|
|
786
824
|
pts1 = wp.array(rng.standard_normal(size=(n, 3)), dtype=wp.vec3, device=device)
|
|
787
825
|
|
|
788
826
|
query_results_num_cols1 = wp.zeros(n, dtype=wp.int32, device=device)
|
|
789
827
|
query_results_min_dist1 = wp.zeros(n, dtype=float, device=device)
|
|
790
828
|
query_results_closest_point_velocity1 = wp.zeros(n, dtype=wp.vec3, device=device)
|
|
791
829
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
830
|
+
for constructor in constructors:
|
|
831
|
+
mesh = wp.Mesh(vertices1, faces, velocities=velocities1, bvh_constructor=constructor)
|
|
832
|
+
fs_2D = faces.reshape((-1, 3))
|
|
833
|
+
|
|
834
|
+
wp.launch(
|
|
835
|
+
kernel=point_query_aabb_and_closest,
|
|
836
|
+
inputs=[
|
|
837
|
+
query_radius,
|
|
838
|
+
mesh.id,
|
|
839
|
+
pts1,
|
|
840
|
+
vertices1,
|
|
841
|
+
fs_2D,
|
|
842
|
+
query_results_num_cols1,
|
|
843
|
+
query_results_min_dist1,
|
|
844
|
+
query_results_closest_point_velocity1,
|
|
845
|
+
],
|
|
846
|
+
dim=n,
|
|
847
|
+
device=device,
|
|
848
|
+
)
|
|
849
|
+
|
|
850
|
+
shift = rng.standard_normal(size=3)
|
|
851
|
+
|
|
852
|
+
vs_higher = vs + shift
|
|
853
|
+
vertices2 = wp.array(vs_higher, dtype=wp.vec3, device=device)
|
|
854
|
+
|
|
855
|
+
velocities2_np = velocities1_np + shift[None, ...]
|
|
856
|
+
velocities2 = wp.array(velocities2_np, dtype=wp.vec3, device=device)
|
|
857
|
+
|
|
858
|
+
pts2 = wp.array(pts1.numpy() + shift, dtype=wp.vec3, device=device)
|
|
859
|
+
|
|
860
|
+
mesh.points = vertices2
|
|
861
|
+
mesh.velocities = velocities2
|
|
862
|
+
|
|
863
|
+
query_results_num_cols2 = wp.zeros(n, dtype=wp.int32, device=device)
|
|
864
|
+
query_results_min_dist2 = wp.zeros(n, dtype=float, device=device)
|
|
865
|
+
query_results_closest_point_velocity2 = wp.array([shift for i in range(n)], dtype=wp.vec3, device=device)
|
|
866
|
+
|
|
867
|
+
wp.launch(
|
|
868
|
+
kernel=point_query_aabb_and_closest,
|
|
869
|
+
inputs=[
|
|
870
|
+
query_radius,
|
|
871
|
+
mesh.id,
|
|
872
|
+
pts2,
|
|
873
|
+
vertices2,
|
|
874
|
+
fs_2D,
|
|
875
|
+
query_results_num_cols2,
|
|
876
|
+
query_results_min_dist2,
|
|
877
|
+
query_results_closest_point_velocity2,
|
|
878
|
+
],
|
|
879
|
+
dim=n,
|
|
880
|
+
device=device,
|
|
881
|
+
)
|
|
882
|
+
|
|
883
|
+
test.assertTrue((query_results_num_cols1.numpy() == query_results_num_cols2.numpy()).all())
|
|
884
|
+
test.assertTrue(((query_results_min_dist1.numpy() - query_results_min_dist2.numpy()) < 1e-5).all())
|
|
843
885
|
|
|
844
886
|
|
|
845
887
|
devices = get_test_devices()
|