warp-lang 1.3.2__py3-none-manylinux2014_x86_64.whl → 1.4.0__py3-none-manylinux2014_x86_64.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 +6 -0
- warp/autograd.py +59 -6
- warp/bin/warp.so +0 -0
- warp/build_dll.py +8 -10
- warp/builtins.py +126 -4
- warp/codegen.py +435 -53
- warp/config.py +1 -1
- warp/context.py +678 -403
- warp/dlpack.py +2 -0
- warp/examples/benchmarks/benchmark_cloth.py +10 -0
- warp/examples/core/example_render_opengl.py +12 -10
- warp/examples/fem/example_adaptive_grid.py +251 -0
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_diffusion_3d.py +2 -2
- warp/examples/fem/example_magnetostatics.py +1 -1
- warp/examples/fem/example_streamlines.py +1 -0
- warp/examples/fem/utils.py +23 -4
- warp/examples/sim/example_cloth.py +50 -6
- warp/fem/__init__.py +2 -0
- warp/fem/adaptivity.py +493 -0
- warp/fem/field/field.py +2 -1
- warp/fem/field/nodal_field.py +18 -26
- warp/fem/field/test.py +4 -4
- warp/fem/field/trial.py +4 -4
- warp/fem/geometry/__init__.py +1 -0
- warp/fem/geometry/adaptive_nanogrid.py +843 -0
- warp/fem/geometry/nanogrid.py +55 -28
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/nanogrid_function_space.py +69 -35
- warp/fem/utils.py +113 -107
- warp/jax_experimental.py +28 -15
- warp/native/array.h +0 -1
- warp/native/builtin.h +103 -6
- warp/native/bvh.cu +2 -0
- warp/native/cuda_util.cpp +14 -0
- warp/native/cuda_util.h +2 -0
- warp/native/error.cpp +4 -2
- warp/native/exports.h +99 -17
- warp/native/mat.h +97 -0
- warp/native/mesh.cpp +36 -0
- warp/native/mesh.cu +51 -0
- warp/native/mesh.h +1 -0
- warp/native/quat.h +43 -0
- warp/native/spatial.h +6 -0
- warp/native/vec.h +74 -0
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +10 -3
- warp/native/warp.h +8 -1
- warp/paddle.py +382 -0
- warp/sim/__init__.py +1 -0
- warp/sim/collide.py +519 -0
- warp/sim/integrator_euler.py +18 -5
- warp/sim/integrator_featherstone.py +5 -5
- warp/sim/integrator_vbd.py +1026 -0
- warp/sim/model.py +49 -23
- warp/stubs.py +459 -0
- warp/tape.py +2 -0
- warp/tests/aux_test_dependent.py +1 -0
- warp/tests/aux_test_name_clash1.py +32 -0
- warp/tests/aux_test_name_clash2.py +32 -0
- warp/tests/aux_test_square.py +1 -0
- warp/tests/test_array.py +222 -0
- warp/tests/test_async.py +3 -3
- warp/tests/test_atomic.py +6 -0
- warp/tests/test_closest_point_edge_edge.py +93 -1
- warp/tests/test_codegen.py +62 -15
- warp/tests/test_codegen_instancing.py +1457 -0
- warp/tests/test_collision.py +486 -0
- warp/tests/test_compile_consts.py +3 -28
- warp/tests/test_dlpack.py +170 -0
- warp/tests/test_examples.py +22 -8
- warp/tests/test_fast_math.py +10 -4
- warp/tests/test_fem.py +64 -0
- warp/tests/test_func.py +46 -0
- warp/tests/test_implicit_init.py +49 -0
- warp/tests/test_jax.py +58 -0
- warp/tests/test_mat.py +84 -0
- warp/tests/test_mesh_query_point.py +188 -0
- warp/tests/test_module_hashing.py +40 -0
- warp/tests/test_multigpu.py +3 -3
- warp/tests/test_overwrite.py +8 -0
- warp/tests/test_paddle.py +852 -0
- warp/tests/test_print.py +89 -0
- warp/tests/test_quat.py +111 -0
- warp/tests/test_reload.py +31 -1
- warp/tests/test_scalar_ops.py +2 -0
- warp/tests/test_static.py +412 -0
- warp/tests/test_streams.py +64 -3
- warp/tests/test_struct.py +4 -4
- warp/tests/test_torch.py +24 -0
- warp/tests/test_triangle_closest_point.py +137 -0
- warp/tests/test_types.py +1 -1
- warp/tests/test_vbd.py +386 -0
- warp/tests/test_vec.py +143 -0
- warp/tests/test_vec_scalar_ops.py +139 -0
- warp/tests/test_volume.py +30 -0
- warp/tests/unittest_suites.py +12 -0
- warp/tests/unittest_utils.py +9 -5
- warp/thirdparty/dlpack.py +3 -1
- warp/types.py +157 -34
- warp/utils.py +37 -14
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/METADATA +10 -8
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/RECORD +106 -94
- warp/tests/test_point_triangle_closest_point.py +0 -143
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.3.2.dist-info → warp_lang-1.4.0.dist-info}/top_level.txt +0 -0
warp/tests/test_array.py
CHANGED
|
@@ -2295,6 +2295,39 @@ def test_array_from_numpy(test, device):
|
|
|
2295
2295
|
assert_np_equal(result.numpy(), expected.numpy())
|
|
2296
2296
|
|
|
2297
2297
|
|
|
2298
|
+
def test_array_aliasing_from_numpy(test, device):
|
|
2299
|
+
device = wp.get_device(device)
|
|
2300
|
+
assert device.is_cpu
|
|
2301
|
+
|
|
2302
|
+
a_np = np.ones(8, dtype=np.int32)
|
|
2303
|
+
a_wp = wp.array(a_np, dtype=int, copy=False, device=device)
|
|
2304
|
+
test.assertIs(a_wp._ref, a_np) # check that some ref is kept to original array
|
|
2305
|
+
test.assertEqual(a_wp.ptr, a_np.ctypes.data)
|
|
2306
|
+
|
|
2307
|
+
a_np_2 = a_wp.numpy()
|
|
2308
|
+
test.assertTrue((a_np_2 == 1).all())
|
|
2309
|
+
|
|
2310
|
+
# updating source array should update aliased array
|
|
2311
|
+
a_np.fill(2)
|
|
2312
|
+
test.assertTrue((a_np_2 == 2).all())
|
|
2313
|
+
|
|
2314
|
+
# trying to alias from a different type should do a copy
|
|
2315
|
+
# do it twice to check that the copy buffer is not being reused for different arrays
|
|
2316
|
+
|
|
2317
|
+
b_np = np.ones(8, dtype=np.int64)
|
|
2318
|
+
c_np = np.zeros(8, dtype=np.int64)
|
|
2319
|
+
b_wp = wp.array(b_np, dtype=int, copy=False, device=device)
|
|
2320
|
+
c_wp = wp.array(c_np, dtype=int, copy=False, device=device)
|
|
2321
|
+
|
|
2322
|
+
test.assertNotEqual(b_wp.ptr, b_np.ctypes.data)
|
|
2323
|
+
test.assertNotEqual(b_wp.ptr, c_wp.ptr)
|
|
2324
|
+
|
|
2325
|
+
b_np_2 = b_wp.numpy()
|
|
2326
|
+
c_np_2 = c_wp.numpy()
|
|
2327
|
+
test.assertTrue((b_np_2 == 1).all())
|
|
2328
|
+
test.assertTrue((c_np_2 == 0).all())
|
|
2329
|
+
|
|
2330
|
+
|
|
2298
2331
|
def test_array_from_cai(test, device):
|
|
2299
2332
|
import torch
|
|
2300
2333
|
|
|
@@ -2328,6 +2361,173 @@ def test_array_from_cai(test, device):
|
|
|
2328
2361
|
assert_np_equal(arr_warp.numpy(), np.array([[2, 1, 1], [1, 0, 0], [1, 0, 0]]))
|
|
2329
2362
|
|
|
2330
2363
|
|
|
2364
|
+
def test_array_inplace_ops(test, device):
|
|
2365
|
+
@wp.kernel
|
|
2366
|
+
def inplace_add_1d(x: wp.array(dtype=float), y: wp.array(dtype=float)):
|
|
2367
|
+
i = wp.tid()
|
|
2368
|
+
x[i] += y[i]
|
|
2369
|
+
|
|
2370
|
+
@wp.kernel
|
|
2371
|
+
def inplace_add_2d(x: wp.array2d(dtype=float), y: wp.array2d(dtype=float)):
|
|
2372
|
+
i, j = wp.tid()
|
|
2373
|
+
x[i, j] += y[i, j]
|
|
2374
|
+
|
|
2375
|
+
@wp.kernel
|
|
2376
|
+
def inplace_add_3d(x: wp.array3d(dtype=float), y: wp.array3d(dtype=float)):
|
|
2377
|
+
i, j, k = wp.tid()
|
|
2378
|
+
x[i, j, k] += y[i, j, k]
|
|
2379
|
+
|
|
2380
|
+
@wp.kernel
|
|
2381
|
+
def inplace_add_4d(x: wp.array4d(dtype=float), y: wp.array4d(dtype=float)):
|
|
2382
|
+
i, j, k, l = wp.tid()
|
|
2383
|
+
x[i, j, k, l] += y[i, j, k, l]
|
|
2384
|
+
|
|
2385
|
+
@wp.kernel
|
|
2386
|
+
def inplace_sub_1d(x: wp.array(dtype=float), y: wp.array(dtype=float)):
|
|
2387
|
+
i = wp.tid()
|
|
2388
|
+
x[i] -= y[i]
|
|
2389
|
+
|
|
2390
|
+
@wp.kernel
|
|
2391
|
+
def inplace_sub_2d(x: wp.array2d(dtype=float), y: wp.array2d(dtype=float)):
|
|
2392
|
+
i, j = wp.tid()
|
|
2393
|
+
x[i, j] -= y[i, j]
|
|
2394
|
+
|
|
2395
|
+
@wp.kernel
|
|
2396
|
+
def inplace_sub_3d(x: wp.array3d(dtype=float), y: wp.array3d(dtype=float)):
|
|
2397
|
+
i, j, k = wp.tid()
|
|
2398
|
+
x[i, j, k] -= y[i, j, k]
|
|
2399
|
+
|
|
2400
|
+
@wp.kernel
|
|
2401
|
+
def inplace_sub_4d(x: wp.array4d(dtype=float), y: wp.array4d(dtype=float)):
|
|
2402
|
+
i, j, k, l = wp.tid()
|
|
2403
|
+
x[i, j, k, l] -= y[i, j, k, l]
|
|
2404
|
+
|
|
2405
|
+
@wp.kernel
|
|
2406
|
+
def inplace_add_vecs(x: wp.array(dtype=wp.vec3), y: wp.array(dtype=wp.vec3)):
|
|
2407
|
+
i = wp.tid()
|
|
2408
|
+
x[i] += y[i]
|
|
2409
|
+
|
|
2410
|
+
@wp.kernel
|
|
2411
|
+
def inplace_add_mats(x: wp.array(dtype=wp.mat33), y: wp.array(dtype=wp.mat33)):
|
|
2412
|
+
i = wp.tid()
|
|
2413
|
+
x[i] += y[i]
|
|
2414
|
+
|
|
2415
|
+
@wp.kernel
|
|
2416
|
+
def inplace_add_rhs(x: wp.array(dtype=float), y: wp.array(dtype=float), z: wp.array(dtype=float)):
|
|
2417
|
+
i = wp.tid()
|
|
2418
|
+
a = y[i]
|
|
2419
|
+
a += x[i]
|
|
2420
|
+
wp.atomic_add(z, 0, a)
|
|
2421
|
+
|
|
2422
|
+
N = 3
|
|
2423
|
+
x1 = wp.ones(N, dtype=float, requires_grad=True, device=device)
|
|
2424
|
+
x2 = wp.ones((N, N), dtype=float, requires_grad=True, device=device)
|
|
2425
|
+
x3 = wp.ones((N, N, N), dtype=float, requires_grad=True, device=device)
|
|
2426
|
+
x4 = wp.ones((N, N, N, N), dtype=float, requires_grad=True, device=device)
|
|
2427
|
+
|
|
2428
|
+
y1 = wp.clone(x1, requires_grad=True, device=device)
|
|
2429
|
+
y2 = wp.clone(x2, requires_grad=True, device=device)
|
|
2430
|
+
y3 = wp.clone(x3, requires_grad=True, device=device)
|
|
2431
|
+
y4 = wp.clone(x4, requires_grad=True, device=device)
|
|
2432
|
+
|
|
2433
|
+
v1 = wp.ones(1, dtype=wp.vec3, requires_grad=True, device=device)
|
|
2434
|
+
v2 = wp.clone(v1, requires_grad=True, device=device)
|
|
2435
|
+
|
|
2436
|
+
m1 = wp.ones(1, dtype=wp.mat33, requires_grad=True, device=device)
|
|
2437
|
+
m2 = wp.clone(m1, requires_grad=True, device=device)
|
|
2438
|
+
|
|
2439
|
+
x = wp.ones(1, dtype=float, requires_grad=True, device=device)
|
|
2440
|
+
y = wp.clone(x, requires_grad=True, device=device)
|
|
2441
|
+
z = wp.zeros(1, dtype=float, requires_grad=True, device=device)
|
|
2442
|
+
|
|
2443
|
+
np_ones_1d = np.ones(N, dtype=float)
|
|
2444
|
+
np_ones_2d = np.ones((N, N), dtype=float)
|
|
2445
|
+
np_ones_3d = np.ones((N, N, N), dtype=float)
|
|
2446
|
+
np_ones_4d = np.ones((N, N, N, N), dtype=float)
|
|
2447
|
+
|
|
2448
|
+
np_twos_1d = np.full(N, 2.0, dtype=float)
|
|
2449
|
+
np_twos_2d = np.full((N, N), 2.0, dtype=float)
|
|
2450
|
+
np_twos_3d = np.full((N, N, N), 2.0, dtype=float)
|
|
2451
|
+
np_twos_4d = np.full((N, N, N, N), 2.0, dtype=float)
|
|
2452
|
+
|
|
2453
|
+
tape = wp.Tape()
|
|
2454
|
+
with tape:
|
|
2455
|
+
wp.launch(inplace_add_1d, N, inputs=[x1, y1], device=device)
|
|
2456
|
+
wp.launch(inplace_add_2d, (N, N), inputs=[x2, y2], device=device)
|
|
2457
|
+
wp.launch(inplace_add_3d, (N, N, N), inputs=[x3, y3], device=device)
|
|
2458
|
+
wp.launch(inplace_add_4d, (N, N, N, N), inputs=[x4, y4], device=device)
|
|
2459
|
+
|
|
2460
|
+
tape.backward(grads={x1: wp.ones_like(x1), x2: wp.ones_like(x2), x3: wp.ones_like(x3), x4: wp.ones_like(x4)})
|
|
2461
|
+
|
|
2462
|
+
assert_np_equal(x1.grad.numpy(), np_ones_1d)
|
|
2463
|
+
assert_np_equal(x2.grad.numpy(), np_ones_2d)
|
|
2464
|
+
assert_np_equal(x3.grad.numpy(), np_ones_3d)
|
|
2465
|
+
assert_np_equal(x4.grad.numpy(), np_ones_4d)
|
|
2466
|
+
|
|
2467
|
+
assert_np_equal(y1.grad.numpy(), np_ones_1d)
|
|
2468
|
+
assert_np_equal(y2.grad.numpy(), np_ones_2d)
|
|
2469
|
+
assert_np_equal(y3.grad.numpy(), np_ones_3d)
|
|
2470
|
+
assert_np_equal(y4.grad.numpy(), np_ones_4d)
|
|
2471
|
+
|
|
2472
|
+
assert_np_equal(x1.numpy(), np_twos_1d)
|
|
2473
|
+
assert_np_equal(x2.numpy(), np_twos_2d)
|
|
2474
|
+
assert_np_equal(x3.numpy(), np_twos_3d)
|
|
2475
|
+
assert_np_equal(x4.numpy(), np_twos_4d)
|
|
2476
|
+
|
|
2477
|
+
x1.grad.zero_()
|
|
2478
|
+
x2.grad.zero_()
|
|
2479
|
+
x3.grad.zero_()
|
|
2480
|
+
x4.grad.zero_()
|
|
2481
|
+
tape.reset()
|
|
2482
|
+
|
|
2483
|
+
with tape:
|
|
2484
|
+
wp.launch(inplace_sub_1d, N, inputs=[x1, y1], device=device)
|
|
2485
|
+
wp.launch(inplace_sub_2d, (N, N), inputs=[x2, y2], device=device)
|
|
2486
|
+
wp.launch(inplace_sub_3d, (N, N, N), inputs=[x3, y3], device=device)
|
|
2487
|
+
wp.launch(inplace_sub_4d, (N, N, N, N), inputs=[x4, y4], device=device)
|
|
2488
|
+
|
|
2489
|
+
tape.backward(grads={x1: wp.ones_like(x1), x2: wp.ones_like(x2), x3: wp.ones_like(x3), x4: wp.ones_like(x4)})
|
|
2490
|
+
|
|
2491
|
+
assert_np_equal(x1.grad.numpy(), np_ones_1d)
|
|
2492
|
+
assert_np_equal(x2.grad.numpy(), np_ones_2d)
|
|
2493
|
+
assert_np_equal(x3.grad.numpy(), np_ones_3d)
|
|
2494
|
+
assert_np_equal(x4.grad.numpy(), np_ones_4d)
|
|
2495
|
+
|
|
2496
|
+
assert_np_equal(y1.grad.numpy(), -np_ones_1d)
|
|
2497
|
+
assert_np_equal(y2.grad.numpy(), -np_ones_2d)
|
|
2498
|
+
assert_np_equal(y3.grad.numpy(), -np_ones_3d)
|
|
2499
|
+
assert_np_equal(y4.grad.numpy(), -np_ones_4d)
|
|
2500
|
+
|
|
2501
|
+
assert_np_equal(x1.numpy(), np_ones_1d)
|
|
2502
|
+
assert_np_equal(x2.numpy(), np_ones_2d)
|
|
2503
|
+
assert_np_equal(x3.numpy(), np_ones_3d)
|
|
2504
|
+
assert_np_equal(x4.numpy(), np_ones_4d)
|
|
2505
|
+
|
|
2506
|
+
x1.grad.zero_()
|
|
2507
|
+
x2.grad.zero_()
|
|
2508
|
+
x3.grad.zero_()
|
|
2509
|
+
x4.grad.zero_()
|
|
2510
|
+
tape.reset()
|
|
2511
|
+
|
|
2512
|
+
with tape:
|
|
2513
|
+
wp.launch(inplace_add_vecs, 1, inputs=[v1, v2], device=device)
|
|
2514
|
+
wp.launch(inplace_add_mats, 1, inputs=[m1, m2], device=device)
|
|
2515
|
+
wp.launch(inplace_add_rhs, 1, inputs=[x, y, z], device=device)
|
|
2516
|
+
|
|
2517
|
+
tape.backward(loss=z, grads={v1: wp.ones_like(v1, requires_grad=False), m1: wp.ones_like(m1, requires_grad=False)})
|
|
2518
|
+
|
|
2519
|
+
assert_np_equal(v1.numpy(), np.full(shape=(1, 3), fill_value=2.0, dtype=float))
|
|
2520
|
+
assert_np_equal(v1.grad.numpy(), np.ones(shape=(1, 3), dtype=float))
|
|
2521
|
+
assert_np_equal(v2.grad.numpy(), np.ones(shape=(1, 3), dtype=float))
|
|
2522
|
+
|
|
2523
|
+
assert_np_equal(m1.numpy(), np.full(shape=(1, 3, 3), fill_value=2.0, dtype=float))
|
|
2524
|
+
assert_np_equal(m1.grad.numpy(), np.ones(shape=(1, 3, 3), dtype=float))
|
|
2525
|
+
assert_np_equal(m2.grad.numpy(), np.ones(shape=(1, 3, 3), dtype=float))
|
|
2526
|
+
|
|
2527
|
+
assert_np_equal(x.grad.numpy(), np.ones(1, dtype=float))
|
|
2528
|
+
assert_np_equal(y.grad.numpy(), np.ones(1, dtype=float))
|
|
2529
|
+
|
|
2530
|
+
|
|
2331
2531
|
@wp.kernel
|
|
2332
2532
|
def inc_scalar(a: wp.array(dtype=float)):
|
|
2333
2533
|
tid = wp.tid()
|
|
@@ -2390,6 +2590,25 @@ def test_array_from_int64_domain(test, device):
|
|
|
2390
2590
|
wp.zeros(np.array([1504, 1080, 520], dtype=np.int64), dtype=wp.float32, device=device)
|
|
2391
2591
|
|
|
2392
2592
|
|
|
2593
|
+
def test_numpy_array_interface(test, device):
|
|
2594
|
+
# We should be able to convert between NumPy and Warp arrays using __array_interface__ on CPU.
|
|
2595
|
+
# This tests all scalar types supported by both.
|
|
2596
|
+
|
|
2597
|
+
n = 10
|
|
2598
|
+
|
|
2599
|
+
scalar_types = wp.types.scalar_types
|
|
2600
|
+
|
|
2601
|
+
for dtype in scalar_types:
|
|
2602
|
+
# test round trip
|
|
2603
|
+
a1 = wp.zeros(n, dtype=dtype, device="cpu")
|
|
2604
|
+
na = np.array(a1)
|
|
2605
|
+
a2 = wp.array(na, device="cpu")
|
|
2606
|
+
|
|
2607
|
+
assert a1.dtype == a2.dtype
|
|
2608
|
+
assert a1.shape == a2.shape
|
|
2609
|
+
assert a1.strides == a2.strides
|
|
2610
|
+
|
|
2611
|
+
|
|
2393
2612
|
devices = get_test_devices()
|
|
2394
2613
|
|
|
2395
2614
|
|
|
@@ -2447,7 +2666,10 @@ add_function_test(TestArray, "test_array_of_structs_grad", test_array_of_structs
|
|
|
2447
2666
|
add_function_test(TestArray, "test_array_of_structs_from_numpy", test_array_of_structs_from_numpy, devices=devices)
|
|
2448
2667
|
add_function_test(TestArray, "test_array_of_structs_roundtrip", test_array_of_structs_roundtrip, devices=devices)
|
|
2449
2668
|
add_function_test(TestArray, "test_array_from_numpy", test_array_from_numpy, devices=devices)
|
|
2669
|
+
add_function_test(TestArray, "test_array_aliasing_from_numpy", test_array_aliasing_from_numpy, devices=["cpu"])
|
|
2670
|
+
add_function_test(TestArray, "test_numpy_array_interface", test_numpy_array_interface, devices=["cpu"])
|
|
2450
2671
|
|
|
2672
|
+
add_function_test(TestArray, "test_array_inplace_ops", test_array_inplace_ops, devices=devices)
|
|
2451
2673
|
add_function_test(TestArray, "test_direct_from_numpy", test_direct_from_numpy, devices=["cpu"])
|
|
2452
2674
|
add_function_test(TestArray, "test_kernel_array_from_ptr", test_kernel_array_from_ptr, devices=devices)
|
|
2453
2675
|
|
warp/tests/test_async.py
CHANGED
|
@@ -11,7 +11,7 @@ import numpy as np
|
|
|
11
11
|
|
|
12
12
|
import warp as wp
|
|
13
13
|
from warp.tests.unittest_utils import *
|
|
14
|
-
from warp.utils import
|
|
14
|
+
from warp.utils import check_p2p
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class Capturable:
|
|
@@ -507,8 +507,8 @@ for src_type, src_ctor in array_constructors.items():
|
|
|
507
507
|
copy_type = f"{array_type_codes[src_type]}2{array_type_codes[dst_type]}"
|
|
508
508
|
|
|
509
509
|
for transfer_type, device_pair in device_pairs.items():
|
|
510
|
-
# skip p2p tests if IOMMU is enabled on Linux
|
|
511
|
-
if transfer_type == "p2p" and not
|
|
510
|
+
# skip p2p tests if not supported (e.g., IOMMU is enabled on Linux)
|
|
511
|
+
if transfer_type == "p2p" and not check_p2p():
|
|
512
512
|
continue
|
|
513
513
|
|
|
514
514
|
src_device = device_pair[0]
|
warp/tests/test_atomic.py
CHANGED
|
@@ -45,6 +45,10 @@ def make_atomic_test(type):
|
|
|
45
45
|
base = rng.random(size=1, dtype=np.float32)
|
|
46
46
|
val = rng.random(size=n, dtype=np.float32)
|
|
47
47
|
|
|
48
|
+
elif type == wp.float64:
|
|
49
|
+
base = rng.random(size=1, dtype=np.float64)
|
|
50
|
+
val = rng.random(size=n, dtype=np.float64)
|
|
51
|
+
|
|
48
52
|
else:
|
|
49
53
|
base = rng.random(size=(1, *type._shape_), dtype=float)
|
|
50
54
|
val = rng.random(size=(n, *type._shape_), dtype=float)
|
|
@@ -109,6 +113,7 @@ def make_atomic_test(type):
|
|
|
109
113
|
# generate test functions for atomic types
|
|
110
114
|
test_atomic_int = make_atomic_test(wp.int32)
|
|
111
115
|
test_atomic_float = make_atomic_test(wp.float32)
|
|
116
|
+
test_atomic_double = make_atomic_test(wp.float64)
|
|
112
117
|
test_atomic_vec2 = make_atomic_test(wp.vec2)
|
|
113
118
|
test_atomic_vec3 = make_atomic_test(wp.vec3)
|
|
114
119
|
test_atomic_vec4 = make_atomic_test(wp.vec4)
|
|
@@ -126,6 +131,7 @@ class TestAtomic(unittest.TestCase):
|
|
|
126
131
|
|
|
127
132
|
add_function_test(TestAtomic, "test_atomic_int", test_atomic_int, devices=devices)
|
|
128
133
|
add_function_test(TestAtomic, "test_atomic_float", test_atomic_float, devices=devices)
|
|
134
|
+
add_function_test(TestAtomic, "test_atomic_double", test_atomic_double, devices=devices)
|
|
129
135
|
add_function_test(TestAtomic, "test_atomic_vec2", test_atomic_vec2, devices=devices)
|
|
130
136
|
add_function_test(TestAtomic, "test_atomic_vec3", test_atomic_vec3, devices=devices)
|
|
131
137
|
add_function_test(TestAtomic, "test_atomic_vec4", test_atomic_vec4, devices=devices)
|
|
@@ -170,6 +170,93 @@ def test_edge_edge_perpendicular_s0_t1(test, device):
|
|
|
170
170
|
test.assertAlmostEqual(st0[1], 1.0) # t value
|
|
171
171
|
|
|
172
172
|
|
|
173
|
+
@wp.func
|
|
174
|
+
def check_edge_closest_point_sufficient_necessary(c1: wp.vec3, c2: wp.vec3, t: float, p: wp.vec3, q: wp.vec3):
|
|
175
|
+
"""
|
|
176
|
+
This is a sufficient and necessary condition of closest point
|
|
177
|
+
c1: closest point on the other edge
|
|
178
|
+
c2: closest point on edge p-q
|
|
179
|
+
t: c2 = (1.0-t) * p + t * q
|
|
180
|
+
e1, e2: end points of the edge
|
|
181
|
+
"""
|
|
182
|
+
eps = 1e-5
|
|
183
|
+
e = p - q
|
|
184
|
+
if t == 0.0:
|
|
185
|
+
wp.expect_eq(wp.dot(c1 - p, p - q) > -eps, True)
|
|
186
|
+
wp.expect_eq(wp.abs(wp.length(c2 - p)) < eps, True)
|
|
187
|
+
elif t == 1.0:
|
|
188
|
+
wp.expect_eq(wp.dot(c1 - q, q - p) > -eps, True)
|
|
189
|
+
wp.expect_eq(wp.abs(wp.length(c2 - q)) < eps, True)
|
|
190
|
+
else:
|
|
191
|
+
# interior closest point, c1c2 must be perpendicular to e
|
|
192
|
+
c1c2 = c1 - c2
|
|
193
|
+
wp.expect_eq(wp.abs(wp.dot(c1c2, e)) < eps, True)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@wp.kernel
|
|
197
|
+
def check_edge_closest_point_sufficient_necessary_kernel(
|
|
198
|
+
p1s: wp.array(dtype=wp.vec3),
|
|
199
|
+
q1s: wp.array(dtype=wp.vec3),
|
|
200
|
+
p2s: wp.array(dtype=wp.vec3),
|
|
201
|
+
q2s: wp.array(dtype=wp.vec3),
|
|
202
|
+
epsilon: float,
|
|
203
|
+
):
|
|
204
|
+
tid = wp.tid()
|
|
205
|
+
|
|
206
|
+
p1 = p1s[tid]
|
|
207
|
+
q1 = q1s[tid]
|
|
208
|
+
p2 = p2s[tid]
|
|
209
|
+
q2 = q2s[tid]
|
|
210
|
+
|
|
211
|
+
st = wp.closest_point_edge_edge(p1, q1, p2, q2, epsilon)
|
|
212
|
+
s = st[0]
|
|
213
|
+
t = st[1]
|
|
214
|
+
c1 = p1 + (q1 - p1) * s
|
|
215
|
+
c2 = p2 + (q2 - p2) * t
|
|
216
|
+
|
|
217
|
+
check_edge_closest_point_sufficient_necessary(c1, c2, t, p2, q2)
|
|
218
|
+
check_edge_closest_point_sufficient_necessary(c2, c1, s, p1, q1)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def check_edge_closest_point_random(test, device):
|
|
222
|
+
num_tests = 100000
|
|
223
|
+
np.random.seed(12345)
|
|
224
|
+
p1 = wp.array(np.random.randn(num_tests, 3), dtype=wp.vec3, device=device)
|
|
225
|
+
q1 = wp.array(np.random.randn(num_tests, 3), dtype=wp.vec3, device=device)
|
|
226
|
+
|
|
227
|
+
p2 = wp.array(np.random.randn(num_tests, 3), dtype=wp.vec3, device=device)
|
|
228
|
+
q2 = wp.array(np.random.randn(num_tests, 3), dtype=wp.vec3, device=device)
|
|
229
|
+
|
|
230
|
+
wp.launch(
|
|
231
|
+
kernel=check_edge_closest_point_sufficient_necessary_kernel,
|
|
232
|
+
dim=num_tests,
|
|
233
|
+
inputs=[p1, q1, p2, q2, epsilon],
|
|
234
|
+
device=device,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# parallel edges
|
|
238
|
+
p1 = np.random.randn(num_tests, 3)
|
|
239
|
+
q1 = np.random.randn(num_tests, 3)
|
|
240
|
+
|
|
241
|
+
shifts = np.random.randn(num_tests, 3)
|
|
242
|
+
|
|
243
|
+
p2 = p1 + shifts
|
|
244
|
+
q2 = q1 + shifts
|
|
245
|
+
|
|
246
|
+
p1 = wp.array(p1, dtype=wp.vec3, device=device)
|
|
247
|
+
q1 = wp.array(q1, dtype=wp.vec3, device=device)
|
|
248
|
+
|
|
249
|
+
p2 = wp.array(p2, dtype=wp.vec3, device=device)
|
|
250
|
+
q2 = wp.array(q2, dtype=wp.vec3, device=device)
|
|
251
|
+
|
|
252
|
+
wp.launch(
|
|
253
|
+
kernel=check_edge_closest_point_sufficient_necessary_kernel,
|
|
254
|
+
dim=num_tests,
|
|
255
|
+
inputs=[p1, q1, p2, q2, epsilon],
|
|
256
|
+
device=device,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
|
|
173
260
|
devices = get_test_devices()
|
|
174
261
|
|
|
175
262
|
|
|
@@ -220,7 +307,12 @@ add_function_test(
|
|
|
220
307
|
test_edge_edge_perpendicular_s0_t1,
|
|
221
308
|
devices=devices,
|
|
222
309
|
)
|
|
223
|
-
|
|
310
|
+
add_function_test(
|
|
311
|
+
TestClosestPointEdgeEdgeMethods,
|
|
312
|
+
"test_edge_closest_point_random",
|
|
313
|
+
check_edge_closest_point_random,
|
|
314
|
+
devices=devices,
|
|
315
|
+
)
|
|
224
316
|
|
|
225
317
|
if __name__ == "__main__":
|
|
226
318
|
wp.clear_kernel_cache()
|
warp/tests/test_codegen.py
CHANGED
|
@@ -405,24 +405,24 @@ def test_error_global_var(test, device):
|
|
|
405
405
|
|
|
406
406
|
kernel = wp.Kernel(func=kernel_1_fn)
|
|
407
407
|
with test.assertRaisesRegex(
|
|
408
|
-
|
|
409
|
-
r"
|
|
408
|
+
TypeError,
|
|
409
|
+
r"Invalid external reference type: <class 'warp.types.array'>",
|
|
410
410
|
):
|
|
411
|
-
wp.launch(kernel, dim=out.shape, inputs=(), outputs=(out,))
|
|
411
|
+
wp.launch(kernel, dim=out.shape, inputs=(), outputs=(out,), device=device)
|
|
412
412
|
|
|
413
413
|
kernel = wp.Kernel(func=kernel_2_fn)
|
|
414
414
|
with test.assertRaisesRegex(
|
|
415
|
-
|
|
416
|
-
r"
|
|
415
|
+
TypeError,
|
|
416
|
+
r"Invalid external reference type: <class 'warp.types.array'>",
|
|
417
417
|
):
|
|
418
|
-
wp.launch(kernel, dim=out.shape, inputs=(), outputs=(out,))
|
|
418
|
+
wp.launch(kernel, dim=out.shape, inputs=(), outputs=(out,), device=device)
|
|
419
419
|
|
|
420
420
|
kernel = wp.Kernel(func=kernel_3_fn)
|
|
421
421
|
with test.assertRaisesRegex(
|
|
422
|
-
|
|
423
|
-
r"
|
|
422
|
+
TypeError,
|
|
423
|
+
r"Invalid external reference type: <class 'warp.types.array'>",
|
|
424
424
|
):
|
|
425
|
-
wp.launch(kernel, dim=out.shape, inputs=(), outputs=(out,))
|
|
425
|
+
wp.launch(kernel, dim=out.shape, inputs=(), outputs=(out,), device=device)
|
|
426
426
|
|
|
427
427
|
|
|
428
428
|
def test_error_collection_construct(test, device):
|
|
@@ -443,28 +443,28 @@ def test_error_collection_construct(test, device):
|
|
|
443
443
|
RuntimeError,
|
|
444
444
|
r"List constructs are not supported in kernels. Use vectors like `wp.vec3\(\)` for small collections instead.",
|
|
445
445
|
):
|
|
446
|
-
wp.launch(kernel, dim=1)
|
|
446
|
+
wp.launch(kernel, dim=1, device=device)
|
|
447
447
|
|
|
448
448
|
kernel = wp.Kernel(func=kernel_2_fn)
|
|
449
449
|
with test.assertRaisesRegex(
|
|
450
450
|
RuntimeError,
|
|
451
451
|
r"Tuple constructs are not supported in kernels. Use vectors like `wp.vec3\(\)` for small collections instead.",
|
|
452
452
|
):
|
|
453
|
-
wp.launch(kernel, dim=1)
|
|
453
|
+
wp.launch(kernel, dim=1, device=device)
|
|
454
454
|
|
|
455
455
|
kernel = wp.Kernel(func=kernel_3_fn)
|
|
456
456
|
with test.assertRaisesRegex(
|
|
457
457
|
RuntimeError,
|
|
458
458
|
r"Construct `ast.Dict` not supported in kernels.",
|
|
459
459
|
):
|
|
460
|
-
wp.launch(kernel, dim=1)
|
|
460
|
+
wp.launch(kernel, dim=1, device=device)
|
|
461
461
|
|
|
462
462
|
kernel = wp.Kernel(func=kernel_4_fn)
|
|
463
463
|
with test.assertRaisesRegex(
|
|
464
464
|
RuntimeError,
|
|
465
465
|
r"Tuple constructs are not supported in kernels. Use vectors like `wp.vec3\(\)` instead.",
|
|
466
466
|
):
|
|
467
|
-
wp.launch(kernel, dim=1)
|
|
467
|
+
wp.launch(kernel, dim=1, device=device)
|
|
468
468
|
|
|
469
469
|
|
|
470
470
|
def test_error_unmatched_arguments(test, device):
|
|
@@ -479,14 +479,29 @@ def test_error_unmatched_arguments(test, device):
|
|
|
479
479
|
RuntimeError,
|
|
480
480
|
r"Input types must be the same, got \['int32', 'float32'\]",
|
|
481
481
|
):
|
|
482
|
-
wp.launch(kernel, dim=1)
|
|
482
|
+
wp.launch(kernel, dim=1, device=device)
|
|
483
483
|
|
|
484
484
|
kernel = wp.Kernel(func=kernel_2_fn)
|
|
485
485
|
with test.assertRaisesRegex(
|
|
486
486
|
RuntimeError,
|
|
487
487
|
r"Input types must be exactly the same, got \[\"vector\(length=2, dtype=<class 'warp.types.float32'>\)\", \"vector\(length=2, dtype=<class 'warp.types.float16'>\)\"\]",
|
|
488
488
|
):
|
|
489
|
-
wp.launch(kernel, dim=1)
|
|
489
|
+
wp.launch(kernel, dim=1, device=device)
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
def test_error_mutating_constant_in_dynamic_loop(test, device):
|
|
493
|
+
@wp.kernel
|
|
494
|
+
def dynamic_loop_kernel(n: int, input: wp.array(dtype=float)):
|
|
495
|
+
my_constant = 0.0
|
|
496
|
+
for i in range(n):
|
|
497
|
+
my_constant += input[i]
|
|
498
|
+
|
|
499
|
+
inputs = wp.array([1.0, 2.0, 3.0], dtype=float, device=device)
|
|
500
|
+
with test.assertRaisesRegex(
|
|
501
|
+
wp.codegen.WarpCodegenError,
|
|
502
|
+
r"Error mutating a constant my_constant inside a dynamic loop, use the following syntax\: pi = float\(3\.141\) to declare a dynamic variable",
|
|
503
|
+
):
|
|
504
|
+
wp.launch(dynamic_loop_kernel, dim=1, inputs=[3, inputs], device=device)
|
|
490
505
|
|
|
491
506
|
|
|
492
507
|
@wp.kernel
|
|
@@ -507,6 +522,30 @@ def test_call_syntax():
|
|
|
507
522
|
wp.expect_eq(wp.matrix(rot=rot, pos=pos, dtype=wp.float32, scale=scale), expected_matrix)
|
|
508
523
|
|
|
509
524
|
|
|
525
|
+
# test shadowing builtin functions
|
|
526
|
+
@wp.func
|
|
527
|
+
def sum(a: wp.vec3) -> float:
|
|
528
|
+
return a[0] + a[1] + a[2]
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
@wp.kernel
|
|
532
|
+
def test_shadow_builtin():
|
|
533
|
+
wp.expect_eq(sum(wp.vec3(1.0)), 3.0)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
@wp.struct
|
|
537
|
+
class Iterator:
|
|
538
|
+
valid: wp.bool
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
@wp.kernel(enable_backward=False)
|
|
542
|
+
def test_while_condition_eval():
|
|
543
|
+
it = Iterator()
|
|
544
|
+
it.valid = True
|
|
545
|
+
while it.valid:
|
|
546
|
+
it.valid = False
|
|
547
|
+
|
|
548
|
+
|
|
510
549
|
class TestCodeGen(unittest.TestCase):
|
|
511
550
|
pass
|
|
512
551
|
|
|
@@ -643,8 +682,16 @@ add_function_test(
|
|
|
643
682
|
add_function_test(
|
|
644
683
|
TestCodeGen, func=test_error_unmatched_arguments, name="test_error_unmatched_arguments", devices=devices
|
|
645
684
|
)
|
|
685
|
+
add_function_test(
|
|
686
|
+
TestCodeGen,
|
|
687
|
+
func=test_error_mutating_constant_in_dynamic_loop,
|
|
688
|
+
name="test_error_mutating_constant_in_dynamic_loop",
|
|
689
|
+
devices=devices,
|
|
690
|
+
)
|
|
646
691
|
|
|
647
692
|
add_kernel_test(TestCodeGen, name="test_call_syntax", kernel=test_call_syntax, dim=1, devices=devices)
|
|
693
|
+
add_kernel_test(TestCodeGen, name="test_shadow_builtin", kernel=test_shadow_builtin, dim=1, devices=devices)
|
|
694
|
+
add_kernel_test(TestCodeGen, name="test_while_condition_eval", kernel=test_while_condition_eval, dim=1, devices=devices)
|
|
648
695
|
|
|
649
696
|
|
|
650
697
|
if __name__ == "__main__":
|