warp-lang 1.5.0__py3-none-macosx_10_13_universal2.whl → 1.6.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 (132) hide show
  1. warp/__init__.py +5 -0
  2. warp/autograd.py +414 -191
  3. warp/bin/libwarp-clang.dylib +0 -0
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +40 -12
  6. warp/build_dll.py +13 -6
  7. warp/builtins.py +1124 -497
  8. warp/codegen.py +261 -136
  9. warp/config.py +1 -1
  10. warp/context.py +357 -119
  11. warp/examples/assets/square_cloth.usd +0 -0
  12. warp/examples/benchmarks/benchmark_gemm.py +27 -18
  13. warp/examples/benchmarks/benchmark_interop_paddle.py +3 -3
  14. warp/examples/benchmarks/benchmark_interop_torch.py +3 -3
  15. warp/examples/core/example_torch.py +18 -34
  16. warp/examples/fem/example_apic_fluid.py +1 -0
  17. warp/examples/fem/example_mixed_elasticity.py +1 -1
  18. warp/examples/optim/example_bounce.py +1 -1
  19. warp/examples/optim/example_cloth_throw.py +1 -1
  20. warp/examples/optim/example_diffray.py +4 -15
  21. warp/examples/optim/example_drone.py +1 -1
  22. warp/examples/optim/example_softbody_properties.py +392 -0
  23. warp/examples/optim/example_trajectory.py +1 -3
  24. warp/examples/optim/example_walker.py +5 -0
  25. warp/examples/sim/example_cartpole.py +0 -2
  26. warp/examples/sim/example_cloth.py +3 -1
  27. warp/examples/sim/example_cloth_self_contact.py +260 -0
  28. warp/examples/sim/example_granular_collision_sdf.py +4 -5
  29. warp/examples/sim/example_jacobian_ik.py +0 -2
  30. warp/examples/sim/example_quadruped.py +5 -2
  31. warp/examples/tile/example_tile_cholesky.py +79 -0
  32. warp/examples/tile/example_tile_convolution.py +2 -2
  33. warp/examples/tile/example_tile_fft.py +2 -2
  34. warp/examples/tile/example_tile_filtering.py +3 -3
  35. warp/examples/tile/example_tile_matmul.py +4 -4
  36. warp/examples/tile/example_tile_mlp.py +12 -12
  37. warp/examples/tile/example_tile_nbody.py +180 -0
  38. warp/examples/tile/example_tile_walker.py +319 -0
  39. warp/fem/geometry/geometry.py +0 -2
  40. warp/math.py +147 -0
  41. warp/native/array.h +12 -0
  42. warp/native/builtin.h +0 -1
  43. warp/native/bvh.cpp +149 -70
  44. warp/native/bvh.cu +287 -68
  45. warp/native/bvh.h +195 -85
  46. warp/native/clang/clang.cpp +5 -1
  47. warp/native/coloring.cpp +5 -1
  48. warp/native/cuda_util.cpp +91 -53
  49. warp/native/cuda_util.h +5 -0
  50. warp/native/exports.h +40 -40
  51. warp/native/intersect.h +17 -0
  52. warp/native/mat.h +41 -0
  53. warp/native/mathdx.cpp +19 -0
  54. warp/native/mesh.cpp +25 -8
  55. warp/native/mesh.cu +153 -101
  56. warp/native/mesh.h +482 -403
  57. warp/native/quat.h +40 -0
  58. warp/native/solid_angle.h +7 -0
  59. warp/native/sort.cpp +85 -0
  60. warp/native/sort.cu +34 -0
  61. warp/native/sort.h +3 -1
  62. warp/native/spatial.h +11 -0
  63. warp/native/tile.h +1187 -669
  64. warp/native/tile_reduce.h +8 -6
  65. warp/native/vec.h +41 -0
  66. warp/native/warp.cpp +8 -1
  67. warp/native/warp.cu +263 -40
  68. warp/native/warp.h +19 -5
  69. warp/optim/linear.py +22 -4
  70. warp/render/render_opengl.py +130 -64
  71. warp/sim/__init__.py +6 -1
  72. warp/sim/collide.py +270 -26
  73. warp/sim/import_urdf.py +8 -8
  74. warp/sim/integrator_euler.py +25 -7
  75. warp/sim/integrator_featherstone.py +154 -35
  76. warp/sim/integrator_vbd.py +842 -40
  77. warp/sim/model.py +134 -72
  78. warp/sparse.py +1 -1
  79. warp/stubs.py +265 -132
  80. warp/tape.py +28 -30
  81. warp/tests/aux_test_module_unload.py +15 -0
  82. warp/tests/{test_sim_grad.py → flaky_test_sim_grad.py} +104 -63
  83. warp/tests/test_array.py +74 -0
  84. warp/tests/test_assert.py +242 -0
  85. warp/tests/test_codegen.py +14 -61
  86. warp/tests/test_collision.py +2 -2
  87. warp/tests/test_coloring.py +12 -2
  88. warp/tests/test_examples.py +12 -1
  89. warp/tests/test_func.py +21 -4
  90. warp/tests/test_grad_debug.py +87 -2
  91. warp/tests/test_hash_grid.py +1 -1
  92. warp/tests/test_ipc.py +116 -0
  93. warp/tests/test_lerp.py +13 -87
  94. warp/tests/test_mat.py +138 -167
  95. warp/tests/test_math.py +47 -1
  96. warp/tests/test_matmul.py +17 -16
  97. warp/tests/test_matmul_lite.py +10 -15
  98. warp/tests/test_mesh.py +84 -60
  99. warp/tests/test_mesh_query_aabb.py +165 -0
  100. warp/tests/test_mesh_query_point.py +328 -286
  101. warp/tests/test_mesh_query_ray.py +134 -121
  102. warp/tests/test_mlp.py +2 -2
  103. warp/tests/test_operators.py +43 -0
  104. warp/tests/test_overwrite.py +47 -2
  105. warp/tests/test_quat.py +77 -0
  106. warp/tests/test_reload.py +29 -0
  107. warp/tests/test_sim_grad_bounce_linear.py +204 -0
  108. warp/tests/test_smoothstep.py +17 -83
  109. warp/tests/test_static.py +19 -3
  110. warp/tests/test_tape.py +25 -0
  111. warp/tests/test_tile.py +178 -191
  112. warp/tests/test_tile_load.py +356 -0
  113. warp/tests/test_tile_mathdx.py +61 -8
  114. warp/tests/test_tile_mlp.py +17 -17
  115. warp/tests/test_tile_reduce.py +24 -18
  116. warp/tests/test_tile_shared_memory.py +66 -17
  117. warp/tests/test_tile_view.py +165 -0
  118. warp/tests/test_torch.py +35 -0
  119. warp/tests/test_utils.py +36 -24
  120. warp/tests/test_vec.py +110 -0
  121. warp/tests/unittest_suites.py +29 -4
  122. warp/tests/unittest_utils.py +30 -13
  123. warp/thirdparty/unittest_parallel.py +2 -2
  124. warp/types.py +411 -101
  125. warp/utils.py +10 -7
  126. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/METADATA +92 -69
  127. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/RECORD +130 -119
  128. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/WHEEL +1 -1
  129. warp/examples/benchmarks/benchmark_tile.py +0 -179
  130. warp/native/tile_gemm.h +0 -341
  131. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/LICENSE.md +0 -0
  132. {warp_lang-1.5.0.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
- # create mesh
305
- mesh = wp.Mesh(points=mesh_points, velocities=None, indices=mesh_indices, support_winding_number=True)
306
-
307
- p = particle_grid(32, 32, 32, np.array([-1.1, -1.1, -1.1]), 0.05, 0.0)
308
-
309
- query_count = len(p)
310
- query_points = wp.array(p, dtype=wp.vec3, device=device)
311
-
312
- signs_query = wp.zeros(query_count, dtype=float, device=device)
313
- faces_query = wp.zeros(query_count, dtype=int, device=device)
314
- dist_query = wp.zeros(query_count, dtype=float, device=device)
315
-
316
- faces_query_no_sign = wp.zeros(query_count, dtype=int, device=device)
317
- dist_query_no_sign = wp.zeros(query_count, dtype=float, device=device)
318
-
319
- signs_query_normal = wp.zeros(query_count, dtype=float, device=device)
320
- faces_query_normal = wp.zeros(query_count, dtype=int, device=device)
321
- dist_query_normal = wp.zeros(query_count, dtype=float, device=device)
322
-
323
- signs_query_winding_number = wp.zeros(query_count, dtype=float, device=device)
324
- faces_query_winding_number = wp.zeros(query_count, dtype=int, device=device)
325
- dist_query_winding_number = wp.zeros(query_count, dtype=float, device=device)
326
-
327
- signs_brute = wp.zeros(query_count, dtype=float, device=device)
328
- faces_brute = wp.zeros(query_count, dtype=int, device=device)
329
- dist_brute = wp.zeros(query_count, dtype=float, device=device)
330
-
331
- wp.launch(
332
- kernel=sample_mesh_query,
333
- dim=query_count,
334
- inputs=[mesh.id, query_points, faces_query, signs_query, dist_query],
335
- device=device,
336
- )
337
-
338
- wp.launch(
339
- kernel=sample_mesh_query_no_sign,
340
- dim=query_count,
341
- inputs=[mesh.id, query_points, faces_query_no_sign, dist_query_no_sign],
342
- device=device,
343
- )
344
-
345
- wp.launch(
346
- kernel=sample_mesh_query_sign_normal,
347
- dim=query_count,
348
- inputs=[mesh.id, query_points, faces_query_normal, signs_query_normal, dist_query_normal],
349
- device=device,
350
- )
351
-
352
- wp.launch(
353
- kernel=sample_mesh_query_sign_winding_number,
354
- dim=query_count,
355
- inputs=[
356
- mesh.id,
357
- query_points,
358
- faces_query_winding_number,
359
- signs_query_winding_number,
360
- dist_query_winding_number,
361
- ],
362
- device=device,
363
- )
364
-
365
- wp.launch(
366
- kernel=sample_mesh_brute,
367
- dim=query_count,
368
- inputs=[
369
- mesh_points,
370
- mesh_indices,
371
- int(len(mesh_indices) / 3),
372
- query_points,
373
- faces_brute,
374
- signs_brute,
375
- dist_brute,
376
- ],
377
- device=device,
378
- )
379
-
380
- signs_query = signs_query.numpy()
381
- faces_query = faces_query.numpy()
382
- dist_query = dist_query.numpy()
383
-
384
- faces_query_no_sign = faces_query_no_sign.numpy()
385
- dist_query_no_sign = dist_query_no_sign.numpy()
386
-
387
- signs_query_normal = signs_query_normal.numpy()
388
- faces_query_normal = faces_query_normal.numpy()
389
- dist_query_normal = dist_query_normal.numpy()
390
-
391
- signs_query_winding_number = signs_query_winding_number.numpy()
392
- faces_query_winding_number = faces_query_winding_number.numpy()
393
- dist_query_winding_number = dist_query_winding_number.numpy()
394
-
395
- signs_brute = signs_brute.numpy()
396
- faces_brute = faces_brute.numpy()
397
- dist_brute = dist_brute.numpy()
398
-
399
- query_points = query_points.numpy()
400
-
401
- inside_query = [[0.0, 0.0, 0.0]]
402
- inside_query_normal = [[0.0, 0.0, 0.0]]
403
- inside_query_winding_number = [[0.0, 0.0, 0.0]]
404
- inside_brute = [[0.0, 0.0, 0.0]]
405
-
406
- for i in range(query_count):
407
- if signs_query[i] < 0.0:
408
- inside_query.append(query_points[i].tolist())
409
-
410
- if signs_query_normal[i] < 0.0:
411
- inside_query_normal.append(query_points[i].tolist())
412
-
413
- if signs_query_winding_number[i] < 0.0:
414
- inside_query_winding_number.append(query_points[i].tolist())
415
-
416
- if signs_brute[i] > math.pi * 2.0:
417
- inside_brute.append(query_points[i].tolist())
418
-
419
- inside_query = np.array(inside_query)
420
- inside_query_normal = np.array(inside_query_normal)
421
- inside_query_winding_number = np.array(inside_query_winding_number)
422
- inside_brute = np.array(inside_brute)
423
-
424
- # import warp.render
425
-
426
- # stage = warp.render.UsdRenderer("tests/outputs/test_mesh_query_point.usd")
427
-
428
- # radius = 0.1
429
- # stage.begin_frame(0.0)
430
- # stage.render_mesh(points=mesh_points.numpy(), indices=mesh_indices.numpy(), name="mesh")
431
- # stage.render_points(points=inside_query, radius=radius, name="query")
432
- # stage.render_points(points=inside_brute, radius=radius, name="brute")
433
- # stage.render_points(points=query_points, radius=radius, name="all")
434
- # stage.end_frame()
435
-
436
- # stage.save()
437
-
438
- test.assertTrue(len(inside_query) == len(inside_brute))
439
- test.assertTrue(len(inside_query_normal) == len(inside_brute))
440
- test.assertTrue(len(inside_query_winding_number) == len(inside_brute))
441
-
442
- tolerance = 1.5e-4
443
- dist_error = np.max(np.abs(dist_query - dist_brute))
444
- sign_error = np.max(np.abs(inside_query - inside_brute))
445
-
446
- test.assertTrue(dist_error < tolerance, f"mesh_query_point dist_error is {dist_error} which is >= {tolerance}")
447
- test.assertTrue(sign_error < tolerance, f"mesh_query_point sign_error is {sign_error} which is >= {tolerance}")
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
- dist_error = np.max(np.abs(dist_query_winding_number - dist_brute))
466
- sign_error = np.max(np.abs(inside_query_winding_number - inside_brute))
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
- test.assertTrue(
469
- dist_error < tolerance,
470
- f"mesh_query_point_sign_winding_number dist_error is {dist_error} which is >= {tolerance}",
471
- )
472
- test.assertTrue(
473
- sign_error < tolerance,
474
- f"mesh_query_point_sign_winding_number sign_error is {sign_error} which is >= {tolerance}",
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
- # test tri
521
- # print("Testing Single Triangle")
522
- # 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)
523
- # mesh_indices = wp.array(np.array([0,1,2]), dtype=int, device=device)
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
- # create mesh
526
- mesh = wp.Mesh(points=mesh_points, velocities=None, indices=mesh_indices, support_winding_number=True)
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
- # p = particle_grid(32, 32, 32, np.array([-5.0, -5.0, -5.0]), 0.1, 0.1)*100.0
529
- p = wp.vec3(50.0, 50.0, 50.0)
555
+ tape = wp.Tape()
530
556
 
531
- tape = wp.Tape()
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
- # analytic gradients
534
- with tape:
535
- query_points = wp.array(p, dtype=wp.vec3, device=device, requires_grad=True)
536
- projected_points = wp.zeros(n=1, dtype=wp.vec3, device=device)
537
- loss = wp.zeros(n=1, dtype=float, device=device, requires_grad=True)
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
- wp.launch(
540
- kernel=mesh_query_point_loss, dim=1, inputs=[mesh.id, query_points, projected_points, loss], device=device
541
- )
570
+ tape.backward(loss=loss)
571
+ analytic = tape.gradients[query_points].numpy().flatten()
542
572
 
543
- tape.backward(loss=loss)
544
- analytic = tape.gradients[query_points].numpy().flatten()
573
+ # numeric gradients
574
+ eps = 1.0e-3
575
+ loss_values = []
576
+ numeric = np.zeros(3)
545
577
 
546
- # numeric gradients
547
- eps = 1.0e-3
548
- loss_values = []
549
- numeric = np.zeros(3)
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
- offset_query_points = [
552
- wp.vec3(p[0] - eps, p[1], p[2]),
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
- for i in range(6):
561
- q = offset_query_points[i]
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
- query_points = wp.array(q, dtype=wp.vec3, device=device)
564
- projected_points = wp.zeros(n=1, dtype=wp.vec3, device=device)
565
- loss = wp.zeros(n=1, dtype=float, device=device)
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
- wp.launch(
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
- loss_values.append(loss.numpy()[0])
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
- for i in range(3):
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
- error = ((analytic - numeric) * (analytic - numeric)).sum(axis=0)
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
- # create mesh
640
- mesh = wp.Mesh(points=mesh_points, indices=mesh_indices)
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
- p = particle_grid(32, 32, 32, np.array([-1.1, -1.1, -1.1]), 0.05, 0.0)
678
+ p = particle_grid(32, 32, 32, np.array([-1.1, -1.1, -1.1]), 0.05, 0.0)
643
679
 
644
- query_count = len(p)
645
- query_points = wp.array(p, dtype=wp.vec3, device=device)
680
+ query_count = len(p)
681
+ query_points = wp.array(p, dtype=wp.vec3, device=device)
646
682
 
647
- dist_query = wp.zeros(query_count, dtype=float, device=device)
648
- dist_brute = wp.zeros(query_count, dtype=float, device=device)
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
- wp.launch(sample_furthest_points, dim=query_count, inputs=[mesh.id, query_points, dist_query], device=device)
651
- wp.launch(
652
- sample_furthest_points_brute, dim=query_count, inputs=[mesh_points, query_points, dist_brute], device=device
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
- assert_np_equal(dist_query.numpy(), dist_brute.numpy(), tol=1.0e-3)
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
- mesh = wp.Mesh(vertices1, faces, velocities=velocities1)
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
- wp.launch(
793
- kernel=point_query_aabb_and_closest,
794
- inputs=[
795
- query_radius,
796
- mesh.id,
797
- pts1,
798
- vertices1,
799
- fs_2D,
800
- query_results_num_cols1,
801
- query_results_min_dist1,
802
- query_results_closest_point_velocity1,
803
- ],
804
- dim=n,
805
- device=device,
806
- )
807
-
808
- shift = rng.standard_normal(size=3)
809
-
810
- vs_higher = vs + shift
811
- vertices2 = wp.array(vs_higher, dtype=wp.vec3, device=device)
812
-
813
- velocities2_np = velocities1_np + shift[None, ...]
814
- velocities2 = wp.array(velocities2_np, dtype=wp.vec3, device=device)
815
-
816
- pts2 = wp.array(pts1.numpy() + shift, dtype=wp.vec3, device=device)
817
-
818
- mesh.points = vertices2
819
- mesh.velocities = velocities2
820
-
821
- query_results_num_cols2 = wp.zeros(n, dtype=wp.int32, device=device)
822
- query_results_min_dist2 = wp.zeros(n, dtype=float, device=device)
823
- query_results_closest_point_velocity2 = wp.array([shift for i in range(n)], dtype=wp.vec3, device=device)
824
-
825
- wp.launch(
826
- kernel=point_query_aabb_and_closest,
827
- inputs=[
828
- query_radius,
829
- mesh.id,
830
- pts2,
831
- vertices2,
832
- fs_2D,
833
- query_results_num_cols2,
834
- query_results_min_dist2,
835
- query_results_closest_point_velocity2,
836
- ],
837
- dim=n,
838
- device=device,
839
- )
840
-
841
- test.assertTrue((query_results_num_cols1.numpy() == query_results_num_cols2.numpy()).all())
842
- test.assertTrue(((query_results_min_dist1.numpy() - query_results_min_dist2.numpy()) < 1e-5).all())
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()