warp-lang 1.8.1__py3-none-manylinux_2_34_aarch64.whl → 1.9.1__py3-none-manylinux_2_34_aarch64.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 (141) hide show
  1. warp/__init__.py +282 -103
  2. warp/__init__.pyi +1904 -114
  3. warp/bin/warp-clang.so +0 -0
  4. warp/bin/warp.so +0 -0
  5. warp/build.py +93 -30
  6. warp/build_dll.py +331 -101
  7. warp/builtins.py +1244 -160
  8. warp/codegen.py +317 -206
  9. warp/config.py +1 -1
  10. warp/context.py +1465 -789
  11. warp/examples/core/example_marching_cubes.py +1 -0
  12. warp/examples/core/example_render_opengl.py +100 -3
  13. warp/examples/fem/example_apic_fluid.py +98 -52
  14. warp/examples/fem/example_convection_diffusion_dg.py +25 -4
  15. warp/examples/fem/example_diffusion_mgpu.py +8 -3
  16. warp/examples/fem/utils.py +68 -22
  17. warp/examples/interop/example_jax_kernel.py +2 -1
  18. warp/fabric.py +1 -1
  19. warp/fem/cache.py +27 -19
  20. warp/fem/domain.py +2 -2
  21. warp/fem/field/nodal_field.py +2 -2
  22. warp/fem/field/virtual.py +264 -166
  23. warp/fem/geometry/geometry.py +5 -5
  24. warp/fem/integrate.py +129 -51
  25. warp/fem/space/restriction.py +4 -0
  26. warp/fem/space/shape/tet_shape_function.py +3 -10
  27. warp/jax_experimental/custom_call.py +25 -2
  28. warp/jax_experimental/ffi.py +22 -1
  29. warp/jax_experimental/xla_ffi.py +16 -7
  30. warp/marching_cubes.py +708 -0
  31. warp/native/array.h +99 -4
  32. warp/native/builtin.h +86 -9
  33. warp/native/bvh.cpp +64 -28
  34. warp/native/bvh.cu +58 -58
  35. warp/native/bvh.h +2 -2
  36. warp/native/clang/clang.cpp +7 -7
  37. warp/native/coloring.cpp +8 -2
  38. warp/native/crt.cpp +2 -2
  39. warp/native/crt.h +3 -5
  40. warp/native/cuda_util.cpp +41 -10
  41. warp/native/cuda_util.h +10 -4
  42. warp/native/exports.h +1842 -1908
  43. warp/native/fabric.h +2 -1
  44. warp/native/hashgrid.cpp +37 -37
  45. warp/native/hashgrid.cu +2 -2
  46. warp/native/initializer_array.h +1 -1
  47. warp/native/intersect.h +2 -2
  48. warp/native/mat.h +1910 -116
  49. warp/native/mathdx.cpp +43 -43
  50. warp/native/mesh.cpp +24 -24
  51. warp/native/mesh.cu +26 -26
  52. warp/native/mesh.h +4 -2
  53. warp/native/nanovdb/GridHandle.h +179 -12
  54. warp/native/nanovdb/HostBuffer.h +8 -7
  55. warp/native/nanovdb/NanoVDB.h +517 -895
  56. warp/native/nanovdb/NodeManager.h +323 -0
  57. warp/native/nanovdb/PNanoVDB.h +2 -2
  58. warp/native/quat.h +331 -14
  59. warp/native/range.h +7 -1
  60. warp/native/reduce.cpp +10 -10
  61. warp/native/reduce.cu +13 -14
  62. warp/native/runlength_encode.cpp +2 -2
  63. warp/native/runlength_encode.cu +5 -5
  64. warp/native/scan.cpp +3 -3
  65. warp/native/scan.cu +4 -4
  66. warp/native/sort.cpp +10 -10
  67. warp/native/sort.cu +40 -31
  68. warp/native/sort.h +2 -0
  69. warp/native/sparse.cpp +8 -8
  70. warp/native/sparse.cu +13 -13
  71. warp/native/spatial.h +366 -17
  72. warp/native/temp_buffer.h +2 -2
  73. warp/native/tile.h +471 -82
  74. warp/native/vec.h +328 -14
  75. warp/native/volume.cpp +54 -54
  76. warp/native/volume.cu +1 -1
  77. warp/native/volume.h +2 -1
  78. warp/native/volume_builder.cu +30 -37
  79. warp/native/warp.cpp +150 -149
  80. warp/native/warp.cu +377 -216
  81. warp/native/warp.h +227 -226
  82. warp/optim/linear.py +736 -271
  83. warp/render/imgui_manager.py +289 -0
  84. warp/render/render_opengl.py +99 -18
  85. warp/render/render_usd.py +1 -0
  86. warp/sim/graph_coloring.py +2 -2
  87. warp/sparse.py +558 -175
  88. warp/tests/aux_test_module_aot.py +7 -0
  89. warp/tests/cuda/test_async.py +3 -3
  90. warp/tests/cuda/test_conditional_captures.py +101 -0
  91. warp/tests/geometry/test_hash_grid.py +38 -0
  92. warp/tests/geometry/test_marching_cubes.py +233 -12
  93. warp/tests/interop/test_jax.py +608 -28
  94. warp/tests/sim/test_coloring.py +6 -6
  95. warp/tests/test_array.py +58 -5
  96. warp/tests/test_codegen.py +4 -3
  97. warp/tests/test_context.py +8 -15
  98. warp/tests/test_enum.py +136 -0
  99. warp/tests/test_examples.py +2 -2
  100. warp/tests/test_fem.py +49 -6
  101. warp/tests/test_fixedarray.py +229 -0
  102. warp/tests/test_func.py +18 -15
  103. warp/tests/test_future_annotations.py +7 -5
  104. warp/tests/test_linear_solvers.py +30 -0
  105. warp/tests/test_map.py +15 -1
  106. warp/tests/test_mat.py +1518 -378
  107. warp/tests/test_mat_assign_copy.py +178 -0
  108. warp/tests/test_mat_constructors.py +574 -0
  109. warp/tests/test_module_aot.py +287 -0
  110. warp/tests/test_print.py +69 -0
  111. warp/tests/test_quat.py +140 -34
  112. warp/tests/test_quat_assign_copy.py +145 -0
  113. warp/tests/test_reload.py +2 -1
  114. warp/tests/test_sparse.py +71 -0
  115. warp/tests/test_spatial.py +140 -34
  116. warp/tests/test_spatial_assign_copy.py +160 -0
  117. warp/tests/test_struct.py +43 -3
  118. warp/tests/test_tuple.py +96 -0
  119. warp/tests/test_types.py +61 -20
  120. warp/tests/test_vec.py +179 -34
  121. warp/tests/test_vec_assign_copy.py +143 -0
  122. warp/tests/tile/test_tile.py +245 -18
  123. warp/tests/tile/test_tile_cholesky.py +605 -0
  124. warp/tests/tile/test_tile_load.py +169 -0
  125. warp/tests/tile/test_tile_mathdx.py +2 -558
  126. warp/tests/tile/test_tile_matmul.py +1 -1
  127. warp/tests/tile/test_tile_mlp.py +1 -1
  128. warp/tests/tile/test_tile_shared_memory.py +5 -5
  129. warp/tests/unittest_suites.py +6 -0
  130. warp/tests/walkthrough_debug.py +1 -1
  131. warp/thirdparty/unittest_parallel.py +108 -9
  132. warp/types.py +571 -267
  133. warp/utils.py +68 -86
  134. {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/METADATA +29 -69
  135. {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/RECORD +138 -128
  136. warp/native/marching.cpp +0 -19
  137. warp/native/marching.cu +0 -514
  138. warp/native/marching.h +0 -19
  139. {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/WHEEL +0 -0
  140. {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/licenses/LICENSE.md +0 -0
  141. {warp_lang-1.8.1.dist-info → warp_lang-1.9.1.dist-info}/top_level.txt +0 -0
@@ -150,7 +150,7 @@ def test_coloring_trimesh(test, device):
150
150
  edge_indices_cpu = wp.array(model.edge_indices.numpy()[:, 2:], dtype=int, device="cpu")
151
151
 
152
152
  # coloring without bending
153
- num_colors_greedy = wp.context.runtime.core.graph_coloring(
153
+ num_colors_greedy = wp.context.runtime.core.wp_graph_coloring(
154
154
  model.particle_count,
155
155
  edge_indices_cpu.__ctype__(),
156
156
  ColoringAlgorithm.GREEDY.value,
@@ -163,7 +163,7 @@ def test_coloring_trimesh(test, device):
163
163
  device="cpu",
164
164
  )
165
165
 
166
- num_colors_mcs = wp.context.runtime.core.graph_coloring(
166
+ num_colors_mcs = wp.context.runtime.core.wp_graph_coloring(
167
167
  model.particle_count,
168
168
  edge_indices_cpu.__ctype__(),
169
169
  ColoringAlgorithm.MCS.value,
@@ -178,13 +178,13 @@ def test_coloring_trimesh(test, device):
178
178
 
179
179
  # coloring with bending
180
180
  edge_indices_cpu_with_bending = construct_trimesh_graph_edges(model.edge_indices, True)
181
- num_colors_greedy = wp.context.runtime.core.graph_coloring(
181
+ num_colors_greedy = wp.context.runtime.core.wp_graph_coloring(
182
182
  model.particle_count,
183
183
  edge_indices_cpu_with_bending.__ctype__(),
184
184
  ColoringAlgorithm.GREEDY.value,
185
185
  particle_colors.__ctype__(),
186
186
  )
187
- wp.context.runtime.core.balance_coloring(
187
+ wp.context.runtime.core.wp_balance_coloring(
188
188
  model.particle_count,
189
189
  edge_indices_cpu_with_bending.__ctype__(),
190
190
  num_colors_greedy,
@@ -198,13 +198,13 @@ def test_coloring_trimesh(test, device):
198
198
  device="cpu",
199
199
  )
200
200
 
201
- num_colors_mcs = wp.context.runtime.core.graph_coloring(
201
+ num_colors_mcs = wp.context.runtime.core.wp_graph_coloring(
202
202
  model.particle_count,
203
203
  edge_indices_cpu_with_bending.__ctype__(),
204
204
  ColoringAlgorithm.MCS.value,
205
205
  particle_colors.__ctype__(),
206
206
  )
207
- max_min_ratio = wp.context.runtime.core.balance_coloring(
207
+ max_min_ratio = wp.context.runtime.core.wp_balance_coloring(
208
208
  model.particle_count,
209
209
  edge_indices_cpu_with_bending.__ctype__(),
210
210
  num_colors_mcs,
warp/tests/test_array.py CHANGED
@@ -364,6 +364,7 @@ def test_slicing(test, device):
364
364
  slice_e = arr[-1:3, :, :] # test mixed slicing
365
365
  slice_e2 = slice_e[0, 0, :] # test 2x slicing
366
366
  slice_f = arr[0:3:2, 0, :] # test step
367
+ slice_g = arr[1:1, :0, -1:-1] # test empty slice
367
368
 
368
369
  assert_array_equal(slice_a, wp.array(np_arr[1, :, :], dtype=float, device=device))
369
370
  assert_array_equal(slice_b, wp.array(np_arr[1:2, :, :], dtype=float, device=device))
@@ -371,6 +372,7 @@ def test_slicing(test, device):
371
372
  assert_array_equal(slice_d, wp.array(np_arr[-2:-1, :, :], dtype=float, device=device))
372
373
  assert_array_equal(slice_e, wp.array(np_arr[-1:3, :, :], dtype=float, device=device))
373
374
  assert_array_equal(slice_e2, wp.array(np_arr[2, 0, :], dtype=float, device=device))
375
+ assert slice_g.shape == np_arr[1:1, :0, -1:-1].shape == (0, 0, 0)
374
376
 
375
377
  # wp does not support copying from/to non-contiguous arrays
376
378
  # stepped windows must read on the device the original array was created on
@@ -2902,10 +2904,8 @@ def test_direct_from_numpy(test, device):
2902
2904
 
2903
2905
 
2904
2906
  @wp.kernel
2905
- def kernel_array_from_ptr(
2906
- ptr: wp.uint64,
2907
- ):
2908
- arr = wp.array(ptr=ptr, shape=(2, 3), dtype=wp.float32)
2907
+ def kernel_array_from_ptr(arr_orig: wp.array2d(dtype=wp.float32)):
2908
+ arr = wp.array(ptr=arr_orig.ptr, shape=(2, 3), dtype=wp.float32)
2909
2909
  arr[0, 0] = 1.0
2910
2910
  arr[0, 1] = 2.0
2911
2911
  arr[0, 2] = 3.0
@@ -2913,7 +2913,56 @@ def kernel_array_from_ptr(
2913
2913
 
2914
2914
  def test_kernel_array_from_ptr(test, device):
2915
2915
  arr = wp.zeros(shape=(2, 3), dtype=wp.float32, device=device)
2916
- wp.launch(kernel_array_from_ptr, dim=(1,), inputs=(arr.ptr,), device=device)
2916
+ wp.launch(kernel_array_from_ptr, dim=(1,), inputs=(arr,), device=device)
2917
+ assert_np_equal(arr.numpy(), np.array(((1.0, 2.0, 3.0), (0.0, 0.0, 0.0))))
2918
+
2919
+
2920
+ @wp.struct
2921
+ class MyStruct:
2922
+ a: wp.float32
2923
+ b: wp.float32
2924
+ c: wp.float32
2925
+
2926
+
2927
+ @wp.kernel
2928
+ def kernel_array_from_ptr_struct(arr_orig: wp.array(dtype=MyStruct)):
2929
+ arr = wp.array(ptr=arr_orig.ptr, shape=(2,), dtype=MyStruct)
2930
+ arr[0].a = 1.0
2931
+ arr[0].b = 2.0
2932
+ arr[0].c = 3.0
2933
+ arr[1].a = 4.0
2934
+ arr[1].b = 5.0
2935
+ arr[1].c = 6.0
2936
+
2937
+
2938
+ def test_kernel_array_from_ptr_struct(test, device):
2939
+ arr = wp.zeros(shape=(2,), dtype=MyStruct, device=device)
2940
+ wp.launch(kernel_array_from_ptr_struct, dim=(1,), inputs=(arr,), device=device)
2941
+ arr_np = arr.numpy()
2942
+ expected = np.zeros_like(arr_np)
2943
+ expected[0] = (1.0, 2.0, 3.0)
2944
+ expected[1] = (4.0, 5.0, 6.0)
2945
+ assert_np_equal(arr_np, expected)
2946
+
2947
+
2948
+ @wp.kernel
2949
+ def kernel_array_from_ptr_variable_shape(
2950
+ ptr: wp.uint64,
2951
+ shape_x: int,
2952
+ shape_y: int,
2953
+ ):
2954
+ arr = wp.array(ptr=ptr, shape=(shape_x, shape_y), dtype=wp.float32)
2955
+ arr[0, 0] = 1.0
2956
+ arr[0, 1] = 2.0
2957
+ if shape_y > 2:
2958
+ arr[0, 2] = 3.0
2959
+
2960
+
2961
+ def test_kernel_array_from_ptr_variable_shape(test, device):
2962
+ arr = wp.zeros(shape=(2, 3), dtype=wp.float32, device=device)
2963
+ wp.launch(kernel_array_from_ptr_variable_shape, dim=(1,), inputs=(arr.ptr, 2, 2), device=device)
2964
+ assert_np_equal(arr.numpy(), np.array(((1.0, 2.0, 0.0), (0.0, 0.0, 0.0))))
2965
+ wp.launch(kernel_array_from_ptr_variable_shape, dim=(1,), inputs=(arr.ptr, 2, 3), device=device)
2917
2966
  assert_np_equal(arr.numpy(), np.array(((1.0, 2.0, 3.0), (0.0, 0.0, 0.0))))
2918
2967
 
2919
2968
 
@@ -3185,6 +3234,10 @@ add_function_test(TestArray, "test_array_inplace_diff_ops", test_array_inplace_d
3185
3234
  add_function_test(TestArray, "test_array_inplace_non_diff_ops", test_array_inplace_non_diff_ops, devices=devices)
3186
3235
  add_function_test(TestArray, "test_direct_from_numpy", test_direct_from_numpy, devices=["cpu"])
3187
3236
  add_function_test(TestArray, "test_kernel_array_from_ptr", test_kernel_array_from_ptr, devices=devices)
3237
+ add_function_test(TestArray, "test_kernel_array_from_ptr_struct", test_kernel_array_from_ptr_struct, devices=devices)
3238
+ add_function_test(
3239
+ TestArray, "test_kernel_array_from_ptr_variable_shape", test_kernel_array_from_ptr_variable_shape, devices=devices
3240
+ )
3188
3241
 
3189
3242
  add_function_test(TestArray, "test_array_from_int32_domain", test_array_from_int32_domain, devices=devices)
3190
3243
  add_function_test(TestArray, "test_array_from_int64_domain", test_array_from_int64_domain, devices=devices)
@@ -463,7 +463,7 @@ def test_error_unmatched_arguments(test, device):
463
463
  kernel = wp.Kernel(func=kernel_2_fn)
464
464
  with test.assertRaisesRegex(
465
465
  RuntimeError,
466
- r"Input types must be exactly the same, got \['vec2f', 'vector\(length=2, dtype=float16\)'\]",
466
+ r"Input types must be exactly the same, got \['vec2f', 'vec2h'\]",
467
467
  ):
468
468
  wp.launch(kernel, dim=1, device=device)
469
469
 
@@ -756,6 +756,7 @@ def test_multiple_return_values(test, device):
756
756
  test_multiple_return_values_quat_to_axis_angle_kernel,
757
757
  dim=1,
758
758
  inputs=(q, expected_axis, expected_angle),
759
+ device=device,
759
760
  )
760
761
 
761
762
  # fmt: off
@@ -791,9 +792,9 @@ def test_multiple_return_values(test, device):
791
792
 
792
793
  test.assertAlmostEqual(V[0][0], expected_V[0][0], places=5)
793
794
  test.assertAlmostEqual(V[0][1], expected_V[0][1], places=5)
794
- test.assertAlmostEqual(V[0][2], expected_V[0][2], places=5)
795
+ test.assertAlmostEqual(V[0][2], expected_V[0][2], places=4) # precision issue on ARM64 (GH-905)
795
796
  test.assertAlmostEqual(V[1][0], expected_V[1][0], places=5)
796
- test.assertAlmostEqual(V[1][1], expected_V[1][1], places=5)
797
+ test.assertAlmostEqual(V[1][1], expected_V[1][1], places=4) # precision issue on ARM64 (GH-905)
797
798
  test.assertAlmostEqual(V[1][2], expected_V[1][2], places=5)
798
799
  test.assertAlmostEqual(V[2][0], expected_V[2][0], places=5)
799
800
  test.assertAlmostEqual(V[2][1], expected_V[2][1], places=5)
@@ -17,24 +17,17 @@ import unittest
17
17
  from typing import List, Tuple
18
18
 
19
19
  import warp as wp
20
- from warp.tests.unittest_utils import *
21
-
22
-
23
- def test_context_type_str(test, device):
24
- assert wp.context.type_str(List[int]) == "List[int]"
25
- assert wp.context.type_str(List[float]) == "List[float]"
26
-
27
- assert wp.context.type_str(Tuple[int]) == "Tuple[int]"
28
- assert wp.context.type_str(Tuple[float]) == "Tuple[float]"
29
- assert wp.context.type_str(Tuple[int, float]) == "Tuple[int, float]"
30
- assert wp.context.type_str(Tuple[int, ...]) == "Tuple[int, ...]"
31
20
 
32
21
 
33
22
  class TestContext(unittest.TestCase):
34
- pass
35
-
36
-
37
- add_function_test(TestContext, "test_context_type_str", test_context_type_str)
23
+ def test_context_type_str(self):
24
+ self.assertEqual(wp.context.type_str(List[int]), "List[int]")
25
+ self.assertEqual(wp.context.type_str(List[float]), "List[float]")
26
+
27
+ self.assertEqual(wp.context.type_str(Tuple[int]), "Tuple[int]")
28
+ self.assertEqual(wp.context.type_str(Tuple[float]), "Tuple[float]")
29
+ self.assertEqual(wp.context.type_str(Tuple[int, float]), "Tuple[int, float]")
30
+ self.assertEqual(wp.context.type_str(Tuple[int, ...]), "Tuple[int, ...]")
38
31
 
39
32
 
40
33
  if __name__ == "__main__":
@@ -0,0 +1,136 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import enum
17
+ import unittest
18
+
19
+ import warp as wp
20
+ from warp.tests.unittest_utils import *
21
+
22
+
23
+ class MyIntEnum(enum.IntEnum):
24
+ A = 1
25
+ B = 2
26
+ C = 3
27
+
28
+
29
+ class MyIntFlag(enum.IntFlag):
30
+ A = 1
31
+ B = enum.auto()
32
+ C = enum.auto()
33
+
34
+
35
+ def test_intenum_ints(test, device):
36
+ @wp.kernel
37
+ def expect_intenum_ints():
38
+ wp.expect_eq(MyIntEnum.A, 1)
39
+ wp.expect_eq(MyIntEnum.B, 2)
40
+ wp.expect_eq(MyIntEnum.C, 3)
41
+ wp.expect_eq(MyIntEnum.A + MyIntEnum.B, MyIntEnum.C)
42
+
43
+ wp.launch(expect_intenum_ints, dim=1, device=device)
44
+
45
+
46
+ def test_intflag_ints(test, device):
47
+ @wp.kernel
48
+ def expect_intflag_ints():
49
+ wp.expect_eq(MyIntFlag.A, 1)
50
+ wp.expect_eq(MyIntFlag.B, 2)
51
+ wp.expect_eq(MyIntFlag.C, 4)
52
+ wp.expect_eq(MyIntFlag.A | MyIntFlag.B, 3)
53
+ wp.expect_eq(MyIntFlag.A | MyIntFlag.B | MyIntFlag.C, 7)
54
+
55
+ wp.launch(expect_intflag_ints, dim=1, device=device)
56
+
57
+
58
+ def test_alternative_accessors(test, device):
59
+ @wp.kernel
60
+ def expect_alternative_accessors():
61
+ wp.expect_eq(int(MyIntEnum.A), 1)
62
+ wp.expect_eq(int(MyIntEnum.B.value), 2)
63
+ wp.expect_eq(MyIntEnum.C.value, 3)
64
+ wp.expect_eq(MyIntEnum.A + int(MyIntEnum.B) + 0, MyIntEnum.C)
65
+ wp.expect_eq(int(MyIntFlag.A), 1)
66
+ wp.expect_eq(int(MyIntFlag.B.value), 2)
67
+ wp.expect_eq(MyIntFlag.C.value, 4)
68
+ wp.expect_eq(MyIntFlag.A | int(MyIntFlag.B), 3)
69
+ wp.expect_eq(MyIntFlag.A | MyIntFlag.B.value | MyIntFlag.C, 7)
70
+
71
+ wp.launch(expect_alternative_accessors, dim=1, device=device)
72
+
73
+
74
+ def test_static_accessors(test, device):
75
+ @wp.kernel
76
+ def expect_static_accessors():
77
+ wp.expect_eq(wp.static(MyIntEnum.A), 1)
78
+ wp.expect_eq(wp.static(int(MyIntEnum.A)), 1)
79
+ wp.expect_eq(wp.static(MyIntEnum.A.value), 1)
80
+ wp.expect_eq(wp.static(MyIntFlag.A), 1)
81
+ wp.expect_eq(wp.static(int(MyIntFlag.A)), 1)
82
+ wp.expect_eq(wp.static(MyIntFlag.A.value), 1)
83
+
84
+ wp.launch(expect_static_accessors, dim=1, device=device)
85
+
86
+
87
+ def test_intflag_compare(test, device):
88
+ @wp.kernel
89
+ def compute_intflag_compare(ins: wp.array(dtype=wp.int32), outs: wp.array(dtype=wp.int32)):
90
+ tid = wp.tid()
91
+ if ins[tid] & MyIntFlag.A:
92
+ outs[tid] += MyIntFlag.A
93
+ if ins[tid] & MyIntFlag.B:
94
+ outs[tid] += MyIntFlag.B
95
+ if ins[tid] & MyIntFlag.C:
96
+ outs[tid] += MyIntFlag.C
97
+
98
+ with wp.ScopedDevice(device):
99
+ ins = wp.array(
100
+ [
101
+ 0,
102
+ MyIntFlag.A,
103
+ MyIntFlag.B,
104
+ MyIntFlag.C,
105
+ MyIntFlag.A | MyIntFlag.B,
106
+ MyIntFlag.A | MyIntFlag.B | MyIntFlag.C,
107
+ ],
108
+ dtype=wp.int32,
109
+ )
110
+ outs = wp.zeros(len(ins), dtype=wp.int32)
111
+ wp.launch(compute_intflag_compare, dim=len(ins), inputs=[ins], outputs=[outs])
112
+ outs = outs.numpy()
113
+ test.assertEqual(outs[0], 0)
114
+ test.assertEqual(outs[1], 1)
115
+ test.assertEqual(outs[2], 2)
116
+ test.assertEqual(outs[3], 4)
117
+ test.assertEqual(outs[4], 3)
118
+ test.assertEqual(outs[5], 7)
119
+
120
+
121
+ class TestEnum(unittest.TestCase):
122
+ pass
123
+
124
+
125
+ devices = get_test_devices()
126
+
127
+ add_function_test(TestEnum, "test_intenum_ints", test_intenum_ints, devices=devices)
128
+ add_function_test(TestEnum, "test_intflag_ints", test_intflag_ints, devices=devices)
129
+ add_function_test(TestEnum, "test_intflag_compare", test_intflag_compare, devices=devices)
130
+ add_function_test(TestEnum, "test_alternative_accessors", test_alternative_accessors, devices=devices)
131
+ add_function_test(TestEnum, "test_static_accessors", test_static_accessors, devices=devices)
132
+
133
+
134
+ if __name__ == "__main__":
135
+ wp.clear_kernel_cache()
136
+ unittest.main(verbosity=2)
@@ -52,7 +52,7 @@ from warp.tests.unittest_utils import (
52
52
  )
53
53
  from warp.utils import check_p2p
54
54
 
55
- wp.init() # For wp.context.runtime.core.is_debug_enabled()
55
+ wp.init() # For wp.context.runtime.core.wp_is_debug_enabled()
56
56
 
57
57
 
58
58
  def _build_command_line_options(test_options: Dict[str, Any]) -> list:
@@ -331,7 +331,7 @@ add_example_test(
331
331
  name="optim.example_softbody_properties",
332
332
  devices=test_devices,
333
333
  test_options_cuda={
334
- "train_iters": 1 if warp.context.runtime.core.is_debug_enabled() else 3,
334
+ "train_iters": 1 if warp.context.runtime.core.wp_is_debug_enabled() else 3,
335
335
  },
336
336
  test_options_cpu={"train_iters": 1},
337
337
  )
warp/tests/test_fem.py CHANGED
@@ -46,6 +46,11 @@ def linear_form(s: Sample, u: Field):
46
46
  return u(s)
47
47
 
48
48
 
49
+ @integrand
50
+ def bilinear_form(s: Sample, u: Field, v: Field):
51
+ return u(s) * v(s)
52
+
53
+
49
54
  @integrand
50
55
  def scaled_linear_form(s: Sample, u: Field, scale: wp.array(dtype=float)):
51
56
  return u(s) * scale[0]
@@ -869,7 +874,7 @@ def test_deformed_geometry(test, device):
869
874
  np.sum(side_measures.numpy()), scale**2 * (0.5 * 6 * (N + 1) + N * 2 * math.sqrt(3.0)), places=4
870
875
  )
871
876
 
872
- @wp.kernel
877
+ @fem.cache.dynamic_kernel(suffix=deformed_geo.name, kernel_options={"enable_backward": False})
873
878
  def _test_deformed_geometry_normal(
874
879
  geo_index_arg: geo.SideIndexArg, geo_arg: geo.SideArg, def_arg: deformed_geo.SideArg, rotation: wp.vec3
875
880
  ):
@@ -921,7 +926,7 @@ def test_deformed_geometry_codimensional(test, device):
921
926
 
922
927
  deformed_geo = pos_field.make_deformed_geometry()
923
928
 
924
- @wp.kernel
929
+ @fem.cache.dynamic_kernel(suffix=deformed_geo.name, kernel_options={"enable_backward": False})
925
930
  def _test_deformed_geometry_normal_codimensional(
926
931
  geo_arg: geo.CellArg, def_arg: deformed_geo.CellArg, rotation: wp.vec3
927
932
  ):
@@ -1868,8 +1873,6 @@ def test_vector_spaces(test, device):
1868
1873
  fields={"field": div_field.trace()},
1869
1874
  )
1870
1875
 
1871
- return
1872
-
1873
1876
  with wp.ScopedDevice(device):
1874
1877
  positions, tri_vidx = _gen_trimesh(3, 5)
1875
1878
 
@@ -1953,7 +1956,7 @@ def test_vector_spaces(test, device):
1953
1956
  )
1954
1957
 
1955
1958
 
1956
- @wp.kernel
1959
+ @wp.kernel(enable_backward=False)
1957
1960
  def test_qr_eigenvalues():
1958
1961
  tol = 5.0e-7
1959
1962
 
@@ -2008,7 +2011,7 @@ def test_qr_eigenvalues():
2008
2011
  wp.expect_near(wp.ddot(Err6, Err6), 0.0, 1.0e-13)
2009
2012
 
2010
2013
 
2011
- @wp.kernel
2014
+ @wp.kernel(enable_backward=False)
2012
2015
  def test_qr_inverse():
2013
2016
  rng = wp.rand_init(4356, wp.tid())
2014
2017
  M = wp.mat33(
@@ -2055,6 +2058,45 @@ def test_array_axpy(test, device):
2055
2058
  assert_np_equal(y.grad.numpy(), beta * np.ones(N))
2056
2059
 
2057
2060
 
2061
+ def test_integrate_high_order(test_field, device):
2062
+ with wp.ScopedDevice(device):
2063
+ geo = fem.Grid3D(res=(1, 1, 1))
2064
+ space = fem.make_polynomial_space(geo, degree=4)
2065
+ test_field = fem.make_test(space)
2066
+ trial_field = fem.make_trial(space)
2067
+
2068
+ # compare consistency of tile-based "dispatch" assembly and generic
2069
+ v0 = fem.integrate(
2070
+ linear_form, fields={"u": test_field}, assembly="dispatch", kernel_options={"enable_backward": False}
2071
+ )
2072
+ v1 = fem.integrate(
2073
+ linear_form, fields={"u": test_field}, assembly="generic", kernel_options={"enable_backward": False}
2074
+ )
2075
+
2076
+ assert_np_equal(v0.numpy(), v1.numpy(), tol=1.0e-6)
2077
+
2078
+ h0 = fem.integrate(
2079
+ bilinear_form,
2080
+ fields={"v": test_field, "u": trial_field},
2081
+ assembly="dispatch",
2082
+ kernel_options={"enable_backward": False},
2083
+ )
2084
+ h1 = fem.integrate(
2085
+ bilinear_form,
2086
+ fields={"v": test_field, "u": trial_field},
2087
+ assembly="generic",
2088
+ kernel_options={"enable_backward": False},
2089
+ )
2090
+
2091
+ h0_nnz = h0.nnz_sync()
2092
+ h1_nnz = h1.nnz_sync()
2093
+ assert h0.shape == h1.shape
2094
+ assert h0_nnz == h1_nnz
2095
+ assert_array_equal(h0.offsets[: h0.nrow + 1], h1.offsets[: h1.nrow + 1])
2096
+ assert_array_equal(h0.columns[:h0_nnz], h1.columns[:h1_nnz])
2097
+ assert_np_equal(h0.values[:h0_nnz].numpy(), h1.values[:h1_nnz].numpy(), tol=1.0e-6)
2098
+
2099
+
2058
2100
  devices = get_test_devices()
2059
2101
  cuda_devices = get_selected_cuda_test_devices()
2060
2102
 
@@ -2088,6 +2130,7 @@ add_function_test(TestFem, "test_point_basis", test_point_basis)
2088
2130
  add_function_test(TestFem, "test_particle_quadratures", test_particle_quadratures)
2089
2131
  add_function_test(TestFem, "test_nodal_quadrature", test_nodal_quadrature)
2090
2132
  add_function_test(TestFem, "test_implicit_fields", test_implicit_fields)
2133
+ add_function_test(TestFem, "test_integrate_high_order", test_integrate_high_order, devices=cuda_devices)
2091
2134
 
2092
2135
 
2093
2136
  class TestFemUtilities(unittest.TestCase):