warp-lang 1.1.0__py3-none-manylinux2014_aarch64.whl → 1.2.1__py3-none-manylinux2014_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 (218) hide show
  1. warp/bin/warp-clang.so +0 -0
  2. warp/bin/warp.so +0 -0
  3. warp/build.py +10 -37
  4. warp/build_dll.py +2 -2
  5. warp/builtins.py +274 -6
  6. warp/codegen.py +51 -4
  7. warp/config.py +2 -2
  8. warp/constants.py +4 -0
  9. warp/context.py +422 -203
  10. warp/examples/benchmarks/benchmark_api.py +0 -2
  11. warp/examples/benchmarks/benchmark_cloth_warp.py +0 -1
  12. warp/examples/benchmarks/benchmark_launches.py +0 -2
  13. warp/examples/core/example_dem.py +0 -2
  14. warp/examples/core/example_fluid.py +0 -2
  15. warp/examples/core/example_graph_capture.py +0 -2
  16. warp/examples/core/example_marching_cubes.py +0 -2
  17. warp/examples/core/example_mesh.py +0 -2
  18. warp/examples/core/example_mesh_intersect.py +0 -2
  19. warp/examples/core/example_nvdb.py +0 -2
  20. warp/examples/core/example_raycast.py +0 -2
  21. warp/examples/core/example_raymarch.py +0 -2
  22. warp/examples/core/example_render_opengl.py +0 -2
  23. warp/examples/core/example_sph.py +0 -2
  24. warp/examples/core/example_torch.py +0 -3
  25. warp/examples/core/example_wave.py +0 -2
  26. warp/examples/fem/example_apic_fluid.py +140 -115
  27. warp/examples/fem/example_burgers.py +262 -0
  28. warp/examples/fem/example_convection_diffusion.py +0 -2
  29. warp/examples/fem/example_convection_diffusion_dg.py +0 -2
  30. warp/examples/fem/example_deformed_geometry.py +0 -2
  31. warp/examples/fem/example_diffusion.py +0 -2
  32. warp/examples/fem/example_diffusion_3d.py +5 -4
  33. warp/examples/fem/example_diffusion_mgpu.py +0 -2
  34. warp/examples/fem/example_mixed_elasticity.py +0 -2
  35. warp/examples/fem/example_navier_stokes.py +0 -2
  36. warp/examples/fem/example_stokes.py +0 -2
  37. warp/examples/fem/example_stokes_transfer.py +0 -2
  38. warp/examples/optim/example_bounce.py +0 -2
  39. warp/examples/optim/example_cloth_throw.py +0 -2
  40. warp/examples/optim/example_diffray.py +0 -2
  41. warp/examples/optim/example_drone.py +0 -2
  42. warp/examples/optim/example_inverse_kinematics.py +0 -2
  43. warp/examples/optim/example_inverse_kinematics_torch.py +0 -2
  44. warp/examples/optim/example_spring_cage.py +0 -2
  45. warp/examples/optim/example_trajectory.py +0 -2
  46. warp/examples/optim/example_walker.py +0 -2
  47. warp/examples/sim/example_cartpole.py +0 -2
  48. warp/examples/sim/example_cloth.py +0 -2
  49. warp/examples/sim/example_granular.py +0 -2
  50. warp/examples/sim/example_granular_collision_sdf.py +0 -2
  51. warp/examples/sim/example_jacobian_ik.py +0 -2
  52. warp/examples/sim/example_particle_chain.py +0 -2
  53. warp/examples/sim/example_quadruped.py +0 -2
  54. warp/examples/sim/example_rigid_chain.py +0 -2
  55. warp/examples/sim/example_rigid_contact.py +0 -2
  56. warp/examples/sim/example_rigid_force.py +0 -2
  57. warp/examples/sim/example_rigid_gyroscopic.py +0 -2
  58. warp/examples/sim/example_rigid_soft_contact.py +0 -2
  59. warp/examples/sim/example_soft_body.py +0 -2
  60. warp/fem/__init__.py +1 -0
  61. warp/fem/cache.py +3 -1
  62. warp/fem/geometry/__init__.py +1 -0
  63. warp/fem/geometry/element.py +4 -0
  64. warp/fem/geometry/grid_3d.py +0 -4
  65. warp/fem/geometry/nanogrid.py +455 -0
  66. warp/fem/integrate.py +63 -9
  67. warp/fem/space/__init__.py +43 -158
  68. warp/fem/space/basis_space.py +34 -0
  69. warp/fem/space/collocated_function_space.py +1 -1
  70. warp/fem/space/grid_2d_function_space.py +13 -132
  71. warp/fem/space/grid_3d_function_space.py +16 -154
  72. warp/fem/space/hexmesh_function_space.py +37 -134
  73. warp/fem/space/nanogrid_function_space.py +202 -0
  74. warp/fem/space/quadmesh_2d_function_space.py +12 -119
  75. warp/fem/space/restriction.py +4 -1
  76. warp/fem/space/shape/__init__.py +77 -0
  77. warp/fem/space/shape/cube_shape_function.py +5 -15
  78. warp/fem/space/tetmesh_function_space.py +6 -76
  79. warp/fem/space/trimesh_2d_function_space.py +6 -76
  80. warp/native/array.h +12 -3
  81. warp/native/builtin.h +48 -5
  82. warp/native/bvh.cpp +14 -10
  83. warp/native/bvh.cu +23 -15
  84. warp/native/bvh.h +1 -0
  85. warp/native/clang/clang.cpp +2 -1
  86. warp/native/crt.cpp +11 -1
  87. warp/native/crt.h +18 -1
  88. warp/native/exports.h +187 -0
  89. warp/native/mat.h +47 -0
  90. warp/native/mesh.cpp +1 -1
  91. warp/native/mesh.cu +1 -2
  92. warp/native/nanovdb/GridHandle.h +366 -0
  93. warp/native/nanovdb/HostBuffer.h +590 -0
  94. warp/native/nanovdb/NanoVDB.h +3999 -2157
  95. warp/native/nanovdb/PNanoVDB.h +936 -99
  96. warp/native/quat.h +28 -1
  97. warp/native/rand.h +5 -1
  98. warp/native/vec.h +45 -1
  99. warp/native/volume.cpp +335 -103
  100. warp/native/volume.cu +39 -13
  101. warp/native/volume.h +725 -303
  102. warp/native/volume_builder.cu +381 -360
  103. warp/native/volume_builder.h +16 -1
  104. warp/native/volume_impl.h +61 -0
  105. warp/native/warp.cu +8 -2
  106. warp/native/warp.h +15 -7
  107. warp/render/render_opengl.py +191 -52
  108. warp/sim/integrator_featherstone.py +10 -3
  109. warp/sim/integrator_xpbd.py +16 -22
  110. warp/sparse.py +89 -27
  111. warp/stubs.py +83 -0
  112. warp/tests/assets/test_index_grid.nvdb +0 -0
  113. warp/tests/aux_test_dependent.py +0 -2
  114. warp/tests/aux_test_grad_customs.py +0 -2
  115. warp/tests/aux_test_reference.py +0 -2
  116. warp/tests/aux_test_reference_reference.py +0 -2
  117. warp/tests/aux_test_square.py +0 -2
  118. warp/tests/disabled_kinematics.py +0 -2
  119. warp/tests/test_adam.py +0 -2
  120. warp/tests/test_arithmetic.py +0 -36
  121. warp/tests/test_array.py +9 -11
  122. warp/tests/test_array_reduce.py +0 -2
  123. warp/tests/test_async.py +0 -2
  124. warp/tests/test_atomic.py +0 -2
  125. warp/tests/test_bool.py +58 -50
  126. warp/tests/test_builtins_resolution.py +0 -2
  127. warp/tests/test_bvh.py +0 -2
  128. warp/tests/test_closest_point_edge_edge.py +0 -1
  129. warp/tests/test_codegen.py +0 -4
  130. warp/tests/test_compile_consts.py +130 -10
  131. warp/tests/test_conditional.py +0 -2
  132. warp/tests/test_copy.py +0 -2
  133. warp/tests/test_ctypes.py +6 -8
  134. warp/tests/test_dense.py +0 -2
  135. warp/tests/test_devices.py +0 -2
  136. warp/tests/test_dlpack.py +9 -11
  137. warp/tests/test_examples.py +42 -39
  138. warp/tests/test_fabricarray.py +0 -3
  139. warp/tests/test_fast_math.py +0 -2
  140. warp/tests/test_fem.py +75 -54
  141. warp/tests/test_fp16.py +0 -2
  142. warp/tests/test_func.py +0 -2
  143. warp/tests/test_generics.py +27 -2
  144. warp/tests/test_grad.py +147 -8
  145. warp/tests/test_grad_customs.py +0 -2
  146. warp/tests/test_hash_grid.py +1 -3
  147. warp/tests/test_import.py +0 -2
  148. warp/tests/test_indexedarray.py +0 -2
  149. warp/tests/test_intersect.py +0 -2
  150. warp/tests/test_jax.py +0 -2
  151. warp/tests/test_large.py +11 -9
  152. warp/tests/test_launch.py +0 -2
  153. warp/tests/test_lerp.py +10 -54
  154. warp/tests/test_linear_solvers.py +3 -5
  155. warp/tests/test_lvalue.py +0 -2
  156. warp/tests/test_marching_cubes.py +0 -2
  157. warp/tests/test_mat.py +0 -2
  158. warp/tests/test_mat_lite.py +0 -2
  159. warp/tests/test_mat_scalar_ops.py +0 -2
  160. warp/tests/test_math.py +0 -2
  161. warp/tests/test_matmul.py +35 -37
  162. warp/tests/test_matmul_lite.py +29 -31
  163. warp/tests/test_mempool.py +0 -2
  164. warp/tests/test_mesh.py +0 -3
  165. warp/tests/test_mesh_query_aabb.py +0 -2
  166. warp/tests/test_mesh_query_point.py +0 -2
  167. warp/tests/test_mesh_query_ray.py +0 -2
  168. warp/tests/test_mlp.py +0 -2
  169. warp/tests/test_model.py +0 -2
  170. warp/tests/test_module_hashing.py +111 -0
  171. warp/tests/test_modules_lite.py +0 -3
  172. warp/tests/test_multigpu.py +0 -2
  173. warp/tests/test_noise.py +0 -4
  174. warp/tests/test_operators.py +0 -2
  175. warp/tests/test_options.py +0 -2
  176. warp/tests/test_peer.py +0 -2
  177. warp/tests/test_pinned.py +0 -2
  178. warp/tests/test_print.py +0 -2
  179. warp/tests/test_quat.py +0 -2
  180. warp/tests/test_rand.py +41 -5
  181. warp/tests/test_reload.py +0 -10
  182. warp/tests/test_rounding.py +0 -2
  183. warp/tests/test_runlength_encode.py +0 -2
  184. warp/tests/test_sim_grad.py +0 -2
  185. warp/tests/test_sim_kinematics.py +0 -2
  186. warp/tests/test_smoothstep.py +0 -2
  187. warp/tests/test_snippet.py +0 -2
  188. warp/tests/test_sparse.py +0 -2
  189. warp/tests/test_spatial.py +0 -2
  190. warp/tests/test_special_values.py +362 -0
  191. warp/tests/test_streams.py +0 -2
  192. warp/tests/test_struct.py +0 -2
  193. warp/tests/test_tape.py +0 -2
  194. warp/tests/test_torch.py +0 -2
  195. warp/tests/test_transient_module.py +0 -2
  196. warp/tests/test_types.py +0 -2
  197. warp/tests/test_utils.py +0 -2
  198. warp/tests/test_vec.py +0 -2
  199. warp/tests/test_vec_lite.py +0 -2
  200. warp/tests/test_vec_scalar_ops.py +0 -2
  201. warp/tests/test_verify_fp.py +0 -2
  202. warp/tests/test_volume.py +237 -13
  203. warp/tests/test_volume_write.py +86 -3
  204. warp/tests/unittest_serial.py +10 -9
  205. warp/tests/unittest_suites.py +6 -2
  206. warp/tests/unittest_utils.py +2 -171
  207. warp/tests/unused_test_misc.py +0 -2
  208. warp/tests/walkthrough_debug.py +1 -1
  209. warp/thirdparty/unittest_parallel.py +37 -40
  210. warp/types.py +526 -85
  211. {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/METADATA +61 -31
  212. warp_lang-1.2.1.dist-info/RECORD +359 -0
  213. warp/examples/fem/example_convection_diffusion_dg0.py +0 -204
  214. warp/native/nanovdb/PNanoVDBWrite.h +0 -295
  215. warp_lang-1.1.0.dist-info/RECORD +0 -352
  216. {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/LICENSE.md +0 -0
  217. {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/WHEEL +0 -0
  218. {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/top_level.txt +0 -0
warp/bin/warp-clang.so CHANGED
Binary file
warp/bin/warp.so CHANGED
Binary file
warp/build.py CHANGED
@@ -50,10 +50,6 @@ def build_cpu(obj_path, cpp_path, mode="release", verify_fp=False, fast_math=Fal
50
50
  raise Exception(f"CPU kernel build failed with error code {err}")
51
51
 
52
52
 
53
- kernel_bin_dir = None
54
- kernel_gen_dir = None
55
-
56
-
57
53
  def init_kernel_cache(path=None):
58
54
  """Initialize kernel cache directory.
59
55
 
@@ -70,46 +66,23 @@ def init_kernel_cache(path=None):
70
66
  else:
71
67
  cache_root_dir = appdirs.user_cache_dir(appname="warp", appauthor="NVIDIA", version=warp.config.version)
72
68
 
73
- cache_bin_dir = os.path.join(cache_root_dir, "bin")
74
- cache_gen_dir = os.path.join(cache_root_dir, "gen")
75
-
76
- if not os.path.isdir(cache_root_dir):
77
- # print("Creating cache directory '%s'" % cache_root_dir)
78
- os.makedirs(cache_root_dir, exist_ok=True)
79
-
80
- if not os.path.isdir(cache_gen_dir):
81
- # print("Creating codegen directory '%s'" % cache_gen_dir)
82
- os.makedirs(cache_gen_dir, exist_ok=True)
83
-
84
- if not os.path.isdir(cache_bin_dir):
85
- # print("Creating binary directory '%s'" % cache_bin_dir)
86
- os.makedirs(cache_bin_dir, exist_ok=True)
87
-
88
69
  warp.config.kernel_cache_dir = cache_root_dir
89
70
 
90
- global kernel_bin_dir, kernel_gen_dir
91
- kernel_bin_dir = cache_bin_dir
92
- kernel_gen_dir = cache_gen_dir
71
+ os.makedirs(warp.config.kernel_cache_dir, exist_ok=True)
93
72
 
94
73
 
95
74
  def clear_kernel_cache():
96
75
  """Clear the kernel cache."""
97
76
 
98
- is_intialized = kernel_bin_dir is not None and kernel_gen_dir is not None
99
- assert is_intialized, "The kernel cache directory is not configured; wp.init() has not been called yet or failed."
100
-
101
- import glob
77
+ warp.context.init()
102
78
 
103
- paths = []
79
+ import shutil
104
80
 
105
- if os.path.isdir(kernel_bin_dir):
106
- pattern = os.path.join(kernel_bin_dir, "wp_*")
107
- paths += glob.glob(pattern)
108
-
109
- if os.path.isdir(kernel_gen_dir):
110
- pattern = os.path.join(kernel_gen_dir, "wp_*")
111
- paths += glob.glob(pattern)
81
+ is_intialized = warp.context.runtime is not None
82
+ assert is_intialized, "The kernel cache directory is not configured; wp.init() has not been called yet or failed."
112
83
 
113
- for p in paths:
114
- if os.path.isfile(p):
115
- os.remove(p)
84
+ for item in os.listdir(warp.config.kernel_cache_dir):
85
+ item_path = os.path.join(warp.config.kernel_cache_dir, item)
86
+ if os.path.isdir(item_path) and item.startswith("wp_"):
87
+ # Remove the directory and its contents
88
+ shutil.rmtree(item_path, ignore_errors=True)
warp/build_dll.py CHANGED
@@ -330,10 +330,10 @@ def build_dll_for_arch(args, dll_path, cpp_paths, cu_path, libs, arch, mode=None
330
330
  cu_out = cu_path + ".o"
331
331
 
332
332
  if mode == "debug":
333
- cuda_cmd = f'"{cuda_home}/bin/nvcc" -g -G -O0 --compiler-options -fPIC,-fvisibility=hidden -D_DEBUG -D_ITERATOR_DEBUG_LEVEL=0 -line-info {" ".join(nvcc_opts)} -DWP_ENABLE_CUDA=1 -I"{native_dir}" -D{cutlass_enabled} {cutlass_includes} -o "{cu_out}" -c "{cu_path}"'
333
+ cuda_cmd = f'"{cuda_home}/bin/nvcc" --std=c++17 -g -G -O0 --compiler-options -fPIC,-fvisibility=hidden -D_DEBUG -D_ITERATOR_DEBUG_LEVEL=0 -line-info {" ".join(nvcc_opts)} -DWP_ENABLE_CUDA=1 -I"{native_dir}" -D{cutlass_enabled} {cutlass_includes} -o "{cu_out}" -c "{cu_path}"'
334
334
 
335
335
  elif mode == "release":
336
- cuda_cmd = f'"{cuda_home}/bin/nvcc" -O3 --compiler-options -fPIC,-fvisibility=hidden {" ".join(nvcc_opts)} -DNDEBUG -DWP_ENABLE_CUDA=1 -I"{native_dir}" -D{cutlass_enabled} {cutlass_includes} -o "{cu_out}" -c "{cu_path}"'
336
+ cuda_cmd = f'"{cuda_home}/bin/nvcc" --std=c++17 -O3 --compiler-options -fPIC,-fvisibility=hidden {" ".join(nvcc_opts)} -DNDEBUG -DWP_ENABLE_CUDA=1 -I"{native_dir}" -D{cutlass_enabled} {cutlass_includes} -o "{cu_out}" -c "{cu_path}"'
337
337
 
338
338
  with ScopedTimer("build_cuda", active=args.verbose):
339
339
  run_cmd(cuda_cmd)
warp/builtins.py CHANGED
@@ -284,6 +284,93 @@ add_builtin(
284
284
  In other words, it discards the integer part of x and is equivalent to ``x - trunc(x)``.""",
285
285
  )
286
286
 
287
+ add_builtin(
288
+ "isfinite",
289
+ input_types={"x": Scalar},
290
+ value_type=builtins.bool,
291
+ group="Scalar Math",
292
+ doc="""Return ``True`` if x is a finite number, otherwise return ``False``.""",
293
+ )
294
+ add_builtin(
295
+ "isfinite",
296
+ input_types={"x": vector(length=Any, dtype=Scalar)},
297
+ value_type=builtins.bool,
298
+ group="Vector Math",
299
+ doc="Return ``True`` if all elements of the vector ``x`` are finite, otherwise return ``False``.",
300
+ )
301
+ add_builtin(
302
+ "isfinite",
303
+ input_types={"x": quaternion(dtype=Scalar)},
304
+ value_type=builtins.bool,
305
+ group="Vector Math",
306
+ doc="Return ``True`` if all elements of the quaternion ``x`` are finite, otherwise return ``False``.",
307
+ )
308
+ add_builtin(
309
+ "isfinite",
310
+ input_types={"m": matrix(shape=(Any, Any), dtype=Scalar)},
311
+ value_type=builtins.bool,
312
+ group="Vector Math",
313
+ doc="Return ``True`` if all elements of the matrix ``m`` are finite, otherwise return ``False``.",
314
+ )
315
+
316
+ add_builtin(
317
+ "isnan",
318
+ input_types={"x": Scalar},
319
+ value_type=builtins.bool,
320
+ doc="Return ``True`` if ``x`` is NaN, otherwise return ``False``.",
321
+ group="Scalar Math",
322
+ )
323
+ add_builtin(
324
+ "isnan",
325
+ input_types={"x": vector(length=Any, dtype=Scalar)},
326
+ value_type=builtins.bool,
327
+ group="Vector Math",
328
+ doc="Return ``True`` if any element of the vector ``x`` is NaN, otherwise return ``False``.",
329
+ )
330
+ add_builtin(
331
+ "isnan",
332
+ input_types={"x": quaternion(dtype=Scalar)},
333
+ value_type=builtins.bool,
334
+ group="Vector Math",
335
+ doc="Return ``True`` if any element of the quaternion ``x`` is NaN, otherwise return ``False``.",
336
+ )
337
+ add_builtin(
338
+ "isnan",
339
+ input_types={"m": matrix(shape=(Any, Any), dtype=Scalar)},
340
+ value_type=builtins.bool,
341
+ group="Vector Math",
342
+ doc="Return ``True`` if any element of the matrix ``m`` is NaN, otherwise return ``False``.",
343
+ )
344
+
345
+ add_builtin(
346
+ "isinf",
347
+ input_types={"x": Scalar},
348
+ value_type=builtins.bool,
349
+ group="Scalar Math",
350
+ doc="""Return ``True`` if x is positive or negative infinity, otherwise return ``False``.""",
351
+ )
352
+ add_builtin(
353
+ "isinf",
354
+ input_types={"x": vector(length=Any, dtype=Scalar)},
355
+ value_type=builtins.bool,
356
+ group="Vector Math",
357
+ doc="Return ``True`` if any element of the vector ``x`` is positive or negative infinity, otherwise return ``False``.",
358
+ )
359
+ add_builtin(
360
+ "isinf",
361
+ input_types={"x": quaternion(dtype=Scalar)},
362
+ value_type=builtins.bool,
363
+ group="Vector Math",
364
+ doc="Return ``True`` if any element of the quaternion ``x`` is positive or negative infinity, otherwise return ``False``.",
365
+ )
366
+ add_builtin(
367
+ "isinf",
368
+ input_types={"m": matrix(shape=(Any, Any), dtype=Scalar)},
369
+ value_type=builtins.bool,
370
+ group="Vector Math",
371
+ doc="Return ``True`` if any element of the matrix ``m`` is positive or negative infinity, otherwise return ``False``.",
372
+ )
373
+
287
374
 
288
375
  def infer_scalar_type(arg_types):
289
376
  if arg_types is None:
@@ -2016,6 +2103,112 @@ add_builtin("iter_next", input_types={"query": mesh_query_aabb_t}, value_type=in
2016
2103
  # ---------------------------------
2017
2104
  # Volumes
2018
2105
 
2106
+ _volume_supported_value_types = {
2107
+ int32,
2108
+ int64,
2109
+ uint32,
2110
+ float32,
2111
+ float64,
2112
+ vec3f,
2113
+ vec3d,
2114
+ vec4f,
2115
+ vec4d,
2116
+ }
2117
+
2118
+
2119
+ def volume_value_func(arg_types, kwds, templates):
2120
+ try:
2121
+ dtype = kwds["dtype"]
2122
+ except KeyError as err:
2123
+ raise RuntimeError(
2124
+ "'dtype' keyword argument must be specified when calling generic volume lookup or sampling functions"
2125
+ ) from err
2126
+
2127
+ if dtype not in _volume_supported_value_types:
2128
+ raise RuntimeError(f"Unsupported volume type '{type_repr(dtype)}'")
2129
+
2130
+ templates.append(dtype)
2131
+
2132
+ return dtype
2133
+
2134
+
2135
+ add_builtin(
2136
+ "volume_sample",
2137
+ input_types={"id": uint64, "uvw": vec3, "sampling_mode": int, "dtype": Any},
2138
+ value_func=volume_value_func,
2139
+ export=False,
2140
+ group="Volumes",
2141
+ doc="""Sample the volume of type `dtype` given by ``id`` at the volume local-space point ``uvw``.
2142
+
2143
+ Interpolation should be :attr:`warp.Volume.CLOSEST` or :attr:`wp.Volume.LINEAR.`""",
2144
+ )
2145
+
2146
+
2147
+ def check_volume_value_grad_compatibility(dtype, grad_dtype):
2148
+ if type_is_vector(dtype):
2149
+ expected = matrix(shape=(type_length(dtype), 3), dtype=type_scalar_type(dtype))
2150
+ else:
2151
+ expected = vector(length=3, dtype=dtype)
2152
+
2153
+ if not types_equal(grad_dtype, expected):
2154
+ raise RuntimeError(f"Incompatible gradient type, expected {type_repr(expected)}, got {type_repr(grad_dtype)}")
2155
+
2156
+
2157
+ def volume_sample_grad_value_func(arg_types, kwds, templates):
2158
+ dtype = volume_value_func(arg_types, kwds, templates)
2159
+
2160
+ if len(arg_types) < 4:
2161
+ raise RuntimeError("'volume_sample_grad' requires 4 positional arguments")
2162
+
2163
+ grad_type = arg_types[3]
2164
+ check_volume_value_grad_compatibility(dtype, grad_type)
2165
+ return dtype
2166
+
2167
+
2168
+ add_builtin(
2169
+ "volume_sample_grad",
2170
+ input_types={"id": uint64, "uvw": vec3, "sampling_mode": int, "grad": Any, "dtype": Any},
2171
+ value_func=volume_sample_grad_value_func,
2172
+ export=False,
2173
+ group="Volumes",
2174
+ doc="""Sample the volume given by ``id`` and its gradient at the volume local-space point ``uvw``.
2175
+
2176
+ Interpolation should be :attr:`warp.Volume.CLOSEST` or :attr:`wp.Volume.LINEAR.`""",
2177
+ )
2178
+
2179
+ add_builtin(
2180
+ "volume_lookup",
2181
+ input_types={"id": uint64, "i": int, "j": int, "k": int, "dtype": Any},
2182
+ value_type=int,
2183
+ value_func=volume_value_func,
2184
+ export=False,
2185
+ group="Volumes",
2186
+ doc="""Returns the value of voxel with coordinates ``i``, ``j``, ``k`` for a volume of type type `dtype`.
2187
+
2188
+ If the voxel at this index does not exist, this function returns the background value.""",
2189
+ )
2190
+
2191
+
2192
+ def volume_store_value_func(arg_types, kwds, templates):
2193
+ if len(arg_types) < 4:
2194
+ raise RuntimeError("'volume_store' requires 5 positional arguments")
2195
+
2196
+ dtype = arg_types[4]
2197
+ if dtype not in _volume_supported_value_types:
2198
+ raise RuntimeError(f"Unsupported volume type '{type_repr(dtype)}'")
2199
+
2200
+ return None
2201
+
2202
+
2203
+ add_builtin(
2204
+ "volume_store",
2205
+ value_func=volume_store_value_func,
2206
+ input_types={"id": uint64, "i": int, "j": int, "k": int, "value": Any},
2207
+ export=False,
2208
+ group="Volumes",
2209
+ doc="""Store ``value`` at the voxel with coordinates ``i``, ``j``, ``k``.""",
2210
+ )
2211
+
2019
2212
  add_builtin(
2020
2213
  "volume_sample_f",
2021
2214
  input_types={"id": uint64, "uvw": vec3, "sampling_mode": int},
@@ -2105,6 +2298,81 @@ add_builtin(
2105
2298
  doc="""Store ``value`` at the voxel with coordinates ``i``, ``j``, ``k``.""",
2106
2299
  )
2107
2300
 
2301
+
2302
+ def volume_sample_index_value_func(arg_types, kwds, templates):
2303
+ if len(arg_types) != 5:
2304
+ raise RuntimeError("'volume_sample_index' requires 5 positional arguments")
2305
+
2306
+ dtype = arg_types[3].dtype
2307
+
2308
+ if not types_equal(dtype, arg_types[4]):
2309
+ raise RuntimeError("The 'voxel_data' array and the 'background' value must have the same dtype")
2310
+
2311
+ return dtype
2312
+
2313
+
2314
+ add_builtin(
2315
+ "volume_sample_index",
2316
+ input_types={"id": uint64, "uvw": vec3, "sampling_mode": int, "voxel_data": array(dtype=Any), "background": Any},
2317
+ value_func=volume_sample_index_value_func,
2318
+ export=False,
2319
+ group="Volumes",
2320
+ doc="""Sample the volume given by ``id`` at the volume local-space point ``uvw``.
2321
+
2322
+ Values for allocated voxels are read from the ``voxel_data`` array, and `background` is used as the value of non-existing voxels.
2323
+ Interpolation should be :attr:`warp.Volume.CLOSEST` or :attr:`wp.Volume.LINEAR`.
2324
+ This function is available for both index grids and classical volumes.
2325
+ """,
2326
+ )
2327
+
2328
+
2329
+ def volume_sample_grad_index_value_func(arg_types, kwds, templates):
2330
+ if len(arg_types) != 6:
2331
+ raise RuntimeError("'volume_sample_grad_index' requires 6 positional arguments")
2332
+
2333
+ dtype = arg_types[3].dtype
2334
+
2335
+ if not types_equal(dtype, arg_types[4]):
2336
+ raise RuntimeError("The 'voxel_data' array and the 'background' value must have the same dtype")
2337
+
2338
+ grad_type = arg_types[5]
2339
+ check_volume_value_grad_compatibility(dtype, grad_type)
2340
+ return dtype
2341
+
2342
+
2343
+ add_builtin(
2344
+ "volume_sample_grad_index",
2345
+ input_types={
2346
+ "id": uint64,
2347
+ "uvw": vec3,
2348
+ "sampling_mode": int,
2349
+ "voxel_data": array(dtype=Any),
2350
+ "background": Any,
2351
+ "grad": Any,
2352
+ },
2353
+ value_func=volume_sample_grad_index_value_func,
2354
+ export=False,
2355
+ group="Volumes",
2356
+ doc="""Sample the volume given by ``id`` and its gradient at the volume local-space point ``uvw``.
2357
+
2358
+ Values for allocated voxels are read from the ``voxel_data`` array, and `background` is used as the value of non-existing voxels.
2359
+ Interpolation should be :attr:`warp.Volume.CLOSEST` or :attr:`wp.Volume.LINEAR`.
2360
+ This function is available for both index grids and classical volumes.
2361
+ """,
2362
+ )
2363
+
2364
+ add_builtin(
2365
+ "volume_lookup_index",
2366
+ input_types={"id": uint64, "i": int, "j": int, "k": int},
2367
+ value_type=int32,
2368
+ group="Volumes",
2369
+ doc="""Returns the index associated to the voxel with coordinates ``i``, ``j``, ``k``.
2370
+
2371
+ If the voxel at this index does not exist, this function returns -1.
2372
+ This function is available for both index grids and classical volumes.
2373
+ """,
2374
+ )
2375
+
2108
2376
  add_builtin(
2109
2377
  "volume_index_to_world",
2110
2378
  input_types={"id": uint64, "uvw": vec3},
@@ -3067,7 +3335,7 @@ add_builtin(
3067
3335
  # ---------------------------------
3068
3336
  # Operators
3069
3337
 
3070
- add_builtin("add", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar))
3338
+ add_builtin("add", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar), group="Operators")
3071
3339
  add_builtin(
3072
3340
  "add",
3073
3341
  input_types={"x": vector(length=Any, dtype=Scalar), "y": vector(length=Any, dtype=Scalar)},
@@ -3099,7 +3367,7 @@ add_builtin(
3099
3367
  group="Operators",
3100
3368
  )
3101
3369
 
3102
- add_builtin("sub", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar))
3370
+ add_builtin("sub", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar), group="Operators")
3103
3371
  add_builtin(
3104
3372
  "sub",
3105
3373
  input_types={"x": vector(length=Any, dtype=Scalar), "y": vector(length=Any, dtype=Scalar)},
@@ -3214,7 +3482,7 @@ def mul_matmat_value_func(arg_types, kwds, _):
3214
3482
  return matrix(shape=(arg_types[0]._shape_[0], arg_types[1]._shape_[1]), dtype=arg_types[0]._wp_scalar_type_)
3215
3483
 
3216
3484
 
3217
- add_builtin("mul", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar))
3485
+ add_builtin("mul", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar), group="Operators")
3218
3486
  add_builtin(
3219
3487
  "mul",
3220
3488
  input_types={"x": vector(length=Any, dtype=Scalar), "y": Scalar},
@@ -3311,7 +3579,7 @@ add_builtin(
3311
3579
  group="Operators",
3312
3580
  )
3313
3581
 
3314
- add_builtin("mod", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar))
3582
+ add_builtin("mod", input_types={"x": Scalar, "y": Scalar}, value_func=sametype_value_func(Scalar), group="Operators")
3315
3583
 
3316
3584
  add_builtin(
3317
3585
  "div",
@@ -3372,7 +3640,7 @@ add_builtin(
3372
3640
  group="Operators",
3373
3641
  )
3374
3642
 
3375
- add_builtin("pos", input_types={"x": Scalar}, value_func=sametype_value_func(Scalar))
3643
+ add_builtin("pos", input_types={"x": Scalar}, value_func=sametype_value_func(Scalar), group="Operators")
3376
3644
  add_builtin(
3377
3645
  "pos",
3378
3646
  input_types={"x": vector(length=Any, dtype=Scalar)},
@@ -3394,7 +3662,7 @@ add_builtin(
3394
3662
  doc="",
3395
3663
  group="Operators",
3396
3664
  )
3397
- add_builtin("neg", input_types={"x": Scalar}, value_func=sametype_value_func(Scalar))
3665
+ add_builtin("neg", input_types={"x": Scalar}, value_func=sametype_value_func(Scalar), group="Operators")
3398
3666
  add_builtin(
3399
3667
  "neg",
3400
3668
  input_types={"x": vector(length=Any, dtype=Scalar)},
warp/codegen.py CHANGED
@@ -16,8 +16,7 @@ import re
16
16
  import sys
17
17
  import textwrap
18
18
  import types
19
- from types import ModuleType
20
- from typing import Any, Callable, Mapping
19
+ from typing import Any, Callable, Dict, Mapping
21
20
 
22
21
  import warp.config
23
22
  from warp.types import *
@@ -554,7 +553,7 @@ class Adjoint:
554
553
 
555
554
  def __init__(
556
555
  adj,
557
- func,
556
+ func: Callable[..., Any],
558
557
  overload_annotations=None,
559
558
  is_user_function=False,
560
559
  skip_forward_codegen=False,
@@ -1370,7 +1369,7 @@ class Adjoint:
1370
1369
  return obj
1371
1370
  if isinstance(obj, type):
1372
1371
  return obj
1373
- if isinstance(obj, ModuleType):
1372
+ if isinstance(obj, types.ModuleType):
1374
1373
  return obj
1375
1374
 
1376
1375
  raise RuntimeError("Cannot reference a global variable from a kernel unless `wp.constant()` is being used")
@@ -2203,6 +2202,51 @@ class Adjoint:
2203
2202
  # return the Python code corresponding to the given AST node
2204
2203
  return ast.get_source_segment(adj.source, node)
2205
2204
 
2205
+ def get_constant_references(adj) -> Dict[str, Any]:
2206
+ """Traverses ``adj.tree`` and returns a dictionary containing constant variable names and values.
2207
+
2208
+ This function is meant to be used to populate a module's constants dictionary, which then feeds
2209
+ into the computation of the module's ``content_hash``.
2210
+ """
2211
+
2212
+ local_variables = set() # Track local variables appearing on the LHS so we know when variables are shadowed
2213
+ constants_dict = {}
2214
+
2215
+ for node in ast.walk(adj.tree):
2216
+ if isinstance(node, ast.Name) and node.id not in local_variables:
2217
+ # This node could be a reference to a wp.constant defined or imported into the current namespace
2218
+
2219
+ # try and resolve the name using the function's globals context (used to lookup constants + functions)
2220
+ obj = adj.func.__globals__.get(node.id)
2221
+
2222
+ if obj is None:
2223
+ # Lookup constant in captured contents
2224
+ capturedvars = dict(
2225
+ zip(adj.func.__code__.co_freevars, [c.cell_contents for c in (adj.func.__closure__ or [])])
2226
+ )
2227
+ obj = capturedvars.get(str(node.id), None)
2228
+
2229
+ if warp.types.is_value(obj):
2230
+ constants_dict[node.id] = obj
2231
+
2232
+ elif isinstance(node, ast.Attribute):
2233
+ obj, path = adj.resolve_static_expression(node, eval_types=False)
2234
+
2235
+ if warp.types.is_value(obj):
2236
+ constants_dict[".".join(path)] = obj
2237
+ elif isinstance(node, ast.Assign):
2238
+ # Add the LHS names to the local_variables so we know any subsequent uses are shadowed
2239
+ lhs = node.targets[0]
2240
+
2241
+ if isinstance(lhs, ast.Tuple):
2242
+ for v in lhs.elts:
2243
+ if isinstance(v, ast.Name):
2244
+ local_variables.add(v.id)
2245
+ elif isinstance(lhs, ast.Name):
2246
+ local_variables.add(lhs.id)
2247
+
2248
+ return constants_dict
2249
+
2206
2250
 
2207
2251
  # ----------------
2208
2252
  # code generation
@@ -2454,6 +2498,9 @@ def constant_str(value):
2454
2498
  elif value == math.inf:
2455
2499
  return "INFINITY"
2456
2500
 
2501
+ elif math.isnan(value):
2502
+ return "NAN"
2503
+
2457
2504
  else:
2458
2505
  # otherwise just convert constant to string
2459
2506
  return str(value)
warp/config.py CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  from typing import Optional
9
9
 
10
- version: str = "1.1.0"
10
+ version: str = "1.2.1"
11
11
 
12
12
  verify_fp: bool = False # verify inputs and outputs are finite after each launch
13
13
  verify_cuda: bool = False # if true will check CUDA errors after each kernel launch / memory operation
@@ -25,7 +25,7 @@ cuda_output: Optional[str] = (
25
25
  None # preferred CUDA output format for kernels ("ptx" or "cubin"), determined automatically if unspecified
26
26
  )
27
27
 
28
- ptx_target_arch: int = 70 # target architecture for PTX generation, defaults to the lowest architecture that supports all of Warp's features
28
+ ptx_target_arch: int = 75 # target architecture for PTX generation, defaults to the lowest architecture that supports all of Warp's features
29
29
 
30
30
  enable_backward: bool = True # whether to compiler the backward passes of the kernels
31
31
 
warp/constants.py CHANGED
@@ -22,6 +22,8 @@ __all__ = [
22
22
  "ln2",
23
23
  "LN10",
24
24
  "ln10",
25
+ "NAN",
26
+ "nan",
25
27
  "PHI",
26
28
  "phi",
27
29
  "PI",
@@ -43,3 +45,5 @@ HALF_PI = half_pi = constant(1.57079632679489661923) # half pi
43
45
  TAU = tau = constant(6.28318530717958647692) # 2 * pi
44
46
 
45
47
  INF = inf = constant(math.inf)
48
+
49
+ NAN = nan = constant(float("nan"))