warp-lang 1.7.0__py3-none-manylinux_2_28_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.

Files changed (429) hide show
  1. warp/__init__.py +139 -0
  2. warp/__init__.pyi +1 -0
  3. warp/autograd.py +1142 -0
  4. warp/bin/warp-clang.so +0 -0
  5. warp/bin/warp.so +0 -0
  6. warp/build.py +557 -0
  7. warp/build_dll.py +405 -0
  8. warp/builtins.py +6855 -0
  9. warp/codegen.py +3969 -0
  10. warp/config.py +158 -0
  11. warp/constants.py +57 -0
  12. warp/context.py +6812 -0
  13. warp/dlpack.py +462 -0
  14. warp/examples/__init__.py +24 -0
  15. warp/examples/assets/bear.usd +0 -0
  16. warp/examples/assets/bunny.usd +0 -0
  17. warp/examples/assets/cartpole.urdf +110 -0
  18. warp/examples/assets/crazyflie.usd +0 -0
  19. warp/examples/assets/cube.usd +0 -0
  20. warp/examples/assets/nonuniform.usd +0 -0
  21. warp/examples/assets/nv_ant.xml +92 -0
  22. warp/examples/assets/nv_humanoid.xml +183 -0
  23. warp/examples/assets/nvidia_logo.png +0 -0
  24. warp/examples/assets/pixel.jpg +0 -0
  25. warp/examples/assets/quadruped.urdf +268 -0
  26. warp/examples/assets/rocks.nvdb +0 -0
  27. warp/examples/assets/rocks.usd +0 -0
  28. warp/examples/assets/sphere.usd +0 -0
  29. warp/examples/assets/square_cloth.usd +0 -0
  30. warp/examples/benchmarks/benchmark_api.py +389 -0
  31. warp/examples/benchmarks/benchmark_cloth.py +296 -0
  32. warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
  33. warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
  34. warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
  35. warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
  36. warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
  37. warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
  38. warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
  39. warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
  40. warp/examples/benchmarks/benchmark_gemm.py +164 -0
  41. warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
  42. warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
  43. warp/examples/benchmarks/benchmark_launches.py +301 -0
  44. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  45. warp/examples/browse.py +37 -0
  46. warp/examples/core/example_cupy.py +86 -0
  47. warp/examples/core/example_dem.py +241 -0
  48. warp/examples/core/example_fluid.py +299 -0
  49. warp/examples/core/example_graph_capture.py +150 -0
  50. warp/examples/core/example_marching_cubes.py +194 -0
  51. warp/examples/core/example_mesh.py +180 -0
  52. warp/examples/core/example_mesh_intersect.py +211 -0
  53. warp/examples/core/example_nvdb.py +182 -0
  54. warp/examples/core/example_raycast.py +111 -0
  55. warp/examples/core/example_raymarch.py +205 -0
  56. warp/examples/core/example_render_opengl.py +193 -0
  57. warp/examples/core/example_sample_mesh.py +300 -0
  58. warp/examples/core/example_sph.py +411 -0
  59. warp/examples/core/example_torch.py +211 -0
  60. warp/examples/core/example_wave.py +269 -0
  61. warp/examples/fem/example_adaptive_grid.py +286 -0
  62. warp/examples/fem/example_apic_fluid.py +423 -0
  63. warp/examples/fem/example_burgers.py +261 -0
  64. warp/examples/fem/example_convection_diffusion.py +178 -0
  65. warp/examples/fem/example_convection_diffusion_dg.py +204 -0
  66. warp/examples/fem/example_deformed_geometry.py +172 -0
  67. warp/examples/fem/example_diffusion.py +196 -0
  68. warp/examples/fem/example_diffusion_3d.py +225 -0
  69. warp/examples/fem/example_diffusion_mgpu.py +220 -0
  70. warp/examples/fem/example_distortion_energy.py +228 -0
  71. warp/examples/fem/example_magnetostatics.py +240 -0
  72. warp/examples/fem/example_mixed_elasticity.py +291 -0
  73. warp/examples/fem/example_navier_stokes.py +261 -0
  74. warp/examples/fem/example_nonconforming_contact.py +298 -0
  75. warp/examples/fem/example_stokes.py +213 -0
  76. warp/examples/fem/example_stokes_transfer.py +262 -0
  77. warp/examples/fem/example_streamlines.py +352 -0
  78. warp/examples/fem/utils.py +1000 -0
  79. warp/examples/interop/example_jax_callable.py +116 -0
  80. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  81. warp/examples/interop/example_jax_kernel.py +205 -0
  82. warp/examples/optim/example_bounce.py +266 -0
  83. warp/examples/optim/example_cloth_throw.py +228 -0
  84. warp/examples/optim/example_diffray.py +561 -0
  85. warp/examples/optim/example_drone.py +870 -0
  86. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  87. warp/examples/optim/example_inverse_kinematics.py +182 -0
  88. warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
  89. warp/examples/optim/example_softbody_properties.py +400 -0
  90. warp/examples/optim/example_spring_cage.py +245 -0
  91. warp/examples/optim/example_trajectory.py +227 -0
  92. warp/examples/sim/example_cartpole.py +143 -0
  93. warp/examples/sim/example_cloth.py +225 -0
  94. warp/examples/sim/example_cloth_self_contact.py +322 -0
  95. warp/examples/sim/example_granular.py +130 -0
  96. warp/examples/sim/example_granular_collision_sdf.py +202 -0
  97. warp/examples/sim/example_jacobian_ik.py +244 -0
  98. warp/examples/sim/example_particle_chain.py +124 -0
  99. warp/examples/sim/example_quadruped.py +203 -0
  100. warp/examples/sim/example_rigid_chain.py +203 -0
  101. warp/examples/sim/example_rigid_contact.py +195 -0
  102. warp/examples/sim/example_rigid_force.py +133 -0
  103. warp/examples/sim/example_rigid_gyroscopic.py +115 -0
  104. warp/examples/sim/example_rigid_soft_contact.py +140 -0
  105. warp/examples/sim/example_soft_body.py +196 -0
  106. warp/examples/tile/example_tile_cholesky.py +87 -0
  107. warp/examples/tile/example_tile_convolution.py +66 -0
  108. warp/examples/tile/example_tile_fft.py +55 -0
  109. warp/examples/tile/example_tile_filtering.py +113 -0
  110. warp/examples/tile/example_tile_matmul.py +85 -0
  111. warp/examples/tile/example_tile_mlp.py +383 -0
  112. warp/examples/tile/example_tile_nbody.py +199 -0
  113. warp/examples/tile/example_tile_walker.py +327 -0
  114. warp/fabric.py +355 -0
  115. warp/fem/__init__.py +106 -0
  116. warp/fem/adaptivity.py +508 -0
  117. warp/fem/cache.py +572 -0
  118. warp/fem/dirichlet.py +202 -0
  119. warp/fem/domain.py +411 -0
  120. warp/fem/field/__init__.py +125 -0
  121. warp/fem/field/field.py +619 -0
  122. warp/fem/field/nodal_field.py +326 -0
  123. warp/fem/field/restriction.py +37 -0
  124. warp/fem/field/virtual.py +848 -0
  125. warp/fem/geometry/__init__.py +32 -0
  126. warp/fem/geometry/adaptive_nanogrid.py +857 -0
  127. warp/fem/geometry/closest_point.py +84 -0
  128. warp/fem/geometry/deformed_geometry.py +221 -0
  129. warp/fem/geometry/element.py +776 -0
  130. warp/fem/geometry/geometry.py +362 -0
  131. warp/fem/geometry/grid_2d.py +392 -0
  132. warp/fem/geometry/grid_3d.py +452 -0
  133. warp/fem/geometry/hexmesh.py +911 -0
  134. warp/fem/geometry/nanogrid.py +571 -0
  135. warp/fem/geometry/partition.py +389 -0
  136. warp/fem/geometry/quadmesh.py +663 -0
  137. warp/fem/geometry/tetmesh.py +855 -0
  138. warp/fem/geometry/trimesh.py +806 -0
  139. warp/fem/integrate.py +2335 -0
  140. warp/fem/linalg.py +419 -0
  141. warp/fem/operator.py +293 -0
  142. warp/fem/polynomial.py +229 -0
  143. warp/fem/quadrature/__init__.py +17 -0
  144. warp/fem/quadrature/pic_quadrature.py +299 -0
  145. warp/fem/quadrature/quadrature.py +591 -0
  146. warp/fem/space/__init__.py +228 -0
  147. warp/fem/space/basis_function_space.py +468 -0
  148. warp/fem/space/basis_space.py +667 -0
  149. warp/fem/space/dof_mapper.py +251 -0
  150. warp/fem/space/function_space.py +309 -0
  151. warp/fem/space/grid_2d_function_space.py +177 -0
  152. warp/fem/space/grid_3d_function_space.py +227 -0
  153. warp/fem/space/hexmesh_function_space.py +257 -0
  154. warp/fem/space/nanogrid_function_space.py +201 -0
  155. warp/fem/space/partition.py +367 -0
  156. warp/fem/space/quadmesh_function_space.py +223 -0
  157. warp/fem/space/restriction.py +179 -0
  158. warp/fem/space/shape/__init__.py +143 -0
  159. warp/fem/space/shape/cube_shape_function.py +1105 -0
  160. warp/fem/space/shape/shape_function.py +133 -0
  161. warp/fem/space/shape/square_shape_function.py +926 -0
  162. warp/fem/space/shape/tet_shape_function.py +834 -0
  163. warp/fem/space/shape/triangle_shape_function.py +672 -0
  164. warp/fem/space/tetmesh_function_space.py +271 -0
  165. warp/fem/space/topology.py +424 -0
  166. warp/fem/space/trimesh_function_space.py +194 -0
  167. warp/fem/types.py +99 -0
  168. warp/fem/utils.py +420 -0
  169. warp/jax.py +187 -0
  170. warp/jax_experimental/__init__.py +16 -0
  171. warp/jax_experimental/custom_call.py +351 -0
  172. warp/jax_experimental/ffi.py +698 -0
  173. warp/jax_experimental/xla_ffi.py +602 -0
  174. warp/math.py +244 -0
  175. warp/native/array.h +1145 -0
  176. warp/native/builtin.h +1800 -0
  177. warp/native/bvh.cpp +492 -0
  178. warp/native/bvh.cu +791 -0
  179. warp/native/bvh.h +554 -0
  180. warp/native/clang/clang.cpp +536 -0
  181. warp/native/coloring.cpp +613 -0
  182. warp/native/crt.cpp +51 -0
  183. warp/native/crt.h +362 -0
  184. warp/native/cuda_crt.h +1058 -0
  185. warp/native/cuda_util.cpp +646 -0
  186. warp/native/cuda_util.h +307 -0
  187. warp/native/error.cpp +77 -0
  188. warp/native/error.h +36 -0
  189. warp/native/exports.h +1878 -0
  190. warp/native/fabric.h +245 -0
  191. warp/native/hashgrid.cpp +311 -0
  192. warp/native/hashgrid.cu +87 -0
  193. warp/native/hashgrid.h +240 -0
  194. warp/native/initializer_array.h +41 -0
  195. warp/native/intersect.h +1230 -0
  196. warp/native/intersect_adj.h +375 -0
  197. warp/native/intersect_tri.h +339 -0
  198. warp/native/marching.cpp +19 -0
  199. warp/native/marching.cu +514 -0
  200. warp/native/marching.h +19 -0
  201. warp/native/mat.h +2220 -0
  202. warp/native/mathdx.cpp +87 -0
  203. warp/native/matnn.h +343 -0
  204. warp/native/mesh.cpp +266 -0
  205. warp/native/mesh.cu +404 -0
  206. warp/native/mesh.h +1980 -0
  207. warp/native/nanovdb/GridHandle.h +366 -0
  208. warp/native/nanovdb/HostBuffer.h +590 -0
  209. warp/native/nanovdb/NanoVDB.h +6624 -0
  210. warp/native/nanovdb/PNanoVDB.h +3390 -0
  211. warp/native/noise.h +859 -0
  212. warp/native/quat.h +1371 -0
  213. warp/native/rand.h +342 -0
  214. warp/native/range.h +139 -0
  215. warp/native/reduce.cpp +174 -0
  216. warp/native/reduce.cu +364 -0
  217. warp/native/runlength_encode.cpp +79 -0
  218. warp/native/runlength_encode.cu +61 -0
  219. warp/native/scan.cpp +47 -0
  220. warp/native/scan.cu +53 -0
  221. warp/native/scan.h +23 -0
  222. warp/native/solid_angle.h +466 -0
  223. warp/native/sort.cpp +251 -0
  224. warp/native/sort.cu +277 -0
  225. warp/native/sort.h +33 -0
  226. warp/native/sparse.cpp +378 -0
  227. warp/native/sparse.cu +524 -0
  228. warp/native/spatial.h +657 -0
  229. warp/native/svd.h +702 -0
  230. warp/native/temp_buffer.h +46 -0
  231. warp/native/tile.h +2584 -0
  232. warp/native/tile_reduce.h +264 -0
  233. warp/native/vec.h +1426 -0
  234. warp/native/volume.cpp +501 -0
  235. warp/native/volume.cu +67 -0
  236. warp/native/volume.h +969 -0
  237. warp/native/volume_builder.cu +477 -0
  238. warp/native/volume_builder.h +52 -0
  239. warp/native/volume_impl.h +70 -0
  240. warp/native/warp.cpp +1082 -0
  241. warp/native/warp.cu +3636 -0
  242. warp/native/warp.h +381 -0
  243. warp/optim/__init__.py +17 -0
  244. warp/optim/adam.py +163 -0
  245. warp/optim/linear.py +1137 -0
  246. warp/optim/sgd.py +112 -0
  247. warp/paddle.py +407 -0
  248. warp/render/__init__.py +18 -0
  249. warp/render/render_opengl.py +3518 -0
  250. warp/render/render_usd.py +784 -0
  251. warp/render/utils.py +160 -0
  252. warp/sim/__init__.py +65 -0
  253. warp/sim/articulation.py +793 -0
  254. warp/sim/collide.py +2395 -0
  255. warp/sim/graph_coloring.py +300 -0
  256. warp/sim/import_mjcf.py +790 -0
  257. warp/sim/import_snu.py +227 -0
  258. warp/sim/import_urdf.py +579 -0
  259. warp/sim/import_usd.py +894 -0
  260. warp/sim/inertia.py +324 -0
  261. warp/sim/integrator.py +242 -0
  262. warp/sim/integrator_euler.py +1997 -0
  263. warp/sim/integrator_featherstone.py +2101 -0
  264. warp/sim/integrator_vbd.py +2048 -0
  265. warp/sim/integrator_xpbd.py +3292 -0
  266. warp/sim/model.py +4791 -0
  267. warp/sim/particles.py +121 -0
  268. warp/sim/render.py +427 -0
  269. warp/sim/utils.py +428 -0
  270. warp/sparse.py +2057 -0
  271. warp/stubs.py +3333 -0
  272. warp/tape.py +1203 -0
  273. warp/tests/__init__.py +1 -0
  274. warp/tests/__main__.py +4 -0
  275. warp/tests/assets/curlnoise_golden.npy +0 -0
  276. warp/tests/assets/mlp_golden.npy +0 -0
  277. warp/tests/assets/pixel.npy +0 -0
  278. warp/tests/assets/pnoise_golden.npy +0 -0
  279. warp/tests/assets/spiky.usd +0 -0
  280. warp/tests/assets/test_grid.nvdb +0 -0
  281. warp/tests/assets/test_index_grid.nvdb +0 -0
  282. warp/tests/assets/test_int32_grid.nvdb +0 -0
  283. warp/tests/assets/test_vec_grid.nvdb +0 -0
  284. warp/tests/assets/torus.nvdb +0 -0
  285. warp/tests/assets/torus.usda +105 -0
  286. warp/tests/aux_test_class_kernel.py +34 -0
  287. warp/tests/aux_test_compile_consts_dummy.py +18 -0
  288. warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
  289. warp/tests/aux_test_dependent.py +29 -0
  290. warp/tests/aux_test_grad_customs.py +29 -0
  291. warp/tests/aux_test_instancing_gc.py +26 -0
  292. warp/tests/aux_test_module_unload.py +23 -0
  293. warp/tests/aux_test_name_clash1.py +40 -0
  294. warp/tests/aux_test_name_clash2.py +40 -0
  295. warp/tests/aux_test_reference.py +9 -0
  296. warp/tests/aux_test_reference_reference.py +8 -0
  297. warp/tests/aux_test_square.py +16 -0
  298. warp/tests/aux_test_unresolved_func.py +22 -0
  299. warp/tests/aux_test_unresolved_symbol.py +22 -0
  300. warp/tests/cuda/__init__.py +0 -0
  301. warp/tests/cuda/test_async.py +676 -0
  302. warp/tests/cuda/test_ipc.py +124 -0
  303. warp/tests/cuda/test_mempool.py +233 -0
  304. warp/tests/cuda/test_multigpu.py +169 -0
  305. warp/tests/cuda/test_peer.py +139 -0
  306. warp/tests/cuda/test_pinned.py +84 -0
  307. warp/tests/cuda/test_streams.py +634 -0
  308. warp/tests/geometry/__init__.py +0 -0
  309. warp/tests/geometry/test_bvh.py +200 -0
  310. warp/tests/geometry/test_hash_grid.py +221 -0
  311. warp/tests/geometry/test_marching_cubes.py +74 -0
  312. warp/tests/geometry/test_mesh.py +316 -0
  313. warp/tests/geometry/test_mesh_query_aabb.py +399 -0
  314. warp/tests/geometry/test_mesh_query_point.py +932 -0
  315. warp/tests/geometry/test_mesh_query_ray.py +311 -0
  316. warp/tests/geometry/test_volume.py +1103 -0
  317. warp/tests/geometry/test_volume_write.py +346 -0
  318. warp/tests/interop/__init__.py +0 -0
  319. warp/tests/interop/test_dlpack.py +729 -0
  320. warp/tests/interop/test_jax.py +371 -0
  321. warp/tests/interop/test_paddle.py +800 -0
  322. warp/tests/interop/test_torch.py +1001 -0
  323. warp/tests/run_coverage_serial.py +39 -0
  324. warp/tests/sim/__init__.py +0 -0
  325. warp/tests/sim/disabled_kinematics.py +244 -0
  326. warp/tests/sim/flaky_test_sim_grad.py +290 -0
  327. warp/tests/sim/test_collision.py +604 -0
  328. warp/tests/sim/test_coloring.py +258 -0
  329. warp/tests/sim/test_model.py +224 -0
  330. warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
  331. warp/tests/sim/test_sim_kinematics.py +98 -0
  332. warp/tests/sim/test_vbd.py +597 -0
  333. warp/tests/test_adam.py +163 -0
  334. warp/tests/test_arithmetic.py +1096 -0
  335. warp/tests/test_array.py +2972 -0
  336. warp/tests/test_array_reduce.py +156 -0
  337. warp/tests/test_assert.py +250 -0
  338. warp/tests/test_atomic.py +153 -0
  339. warp/tests/test_bool.py +220 -0
  340. warp/tests/test_builtins_resolution.py +1298 -0
  341. warp/tests/test_closest_point_edge_edge.py +327 -0
  342. warp/tests/test_codegen.py +810 -0
  343. warp/tests/test_codegen_instancing.py +1495 -0
  344. warp/tests/test_compile_consts.py +215 -0
  345. warp/tests/test_conditional.py +252 -0
  346. warp/tests/test_context.py +42 -0
  347. warp/tests/test_copy.py +238 -0
  348. warp/tests/test_ctypes.py +638 -0
  349. warp/tests/test_dense.py +73 -0
  350. warp/tests/test_devices.py +97 -0
  351. warp/tests/test_examples.py +482 -0
  352. warp/tests/test_fabricarray.py +996 -0
  353. warp/tests/test_fast_math.py +74 -0
  354. warp/tests/test_fem.py +2003 -0
  355. warp/tests/test_fp16.py +136 -0
  356. warp/tests/test_func.py +454 -0
  357. warp/tests/test_future_annotations.py +98 -0
  358. warp/tests/test_generics.py +656 -0
  359. warp/tests/test_grad.py +893 -0
  360. warp/tests/test_grad_customs.py +339 -0
  361. warp/tests/test_grad_debug.py +341 -0
  362. warp/tests/test_implicit_init.py +411 -0
  363. warp/tests/test_import.py +45 -0
  364. warp/tests/test_indexedarray.py +1140 -0
  365. warp/tests/test_intersect.py +73 -0
  366. warp/tests/test_iter.py +76 -0
  367. warp/tests/test_large.py +177 -0
  368. warp/tests/test_launch.py +411 -0
  369. warp/tests/test_lerp.py +151 -0
  370. warp/tests/test_linear_solvers.py +193 -0
  371. warp/tests/test_lvalue.py +427 -0
  372. warp/tests/test_mat.py +2089 -0
  373. warp/tests/test_mat_lite.py +122 -0
  374. warp/tests/test_mat_scalar_ops.py +2913 -0
  375. warp/tests/test_math.py +178 -0
  376. warp/tests/test_mlp.py +282 -0
  377. warp/tests/test_module_hashing.py +258 -0
  378. warp/tests/test_modules_lite.py +44 -0
  379. warp/tests/test_noise.py +252 -0
  380. warp/tests/test_operators.py +299 -0
  381. warp/tests/test_options.py +129 -0
  382. warp/tests/test_overwrite.py +551 -0
  383. warp/tests/test_print.py +339 -0
  384. warp/tests/test_quat.py +2315 -0
  385. warp/tests/test_rand.py +339 -0
  386. warp/tests/test_reload.py +302 -0
  387. warp/tests/test_rounding.py +185 -0
  388. warp/tests/test_runlength_encode.py +196 -0
  389. warp/tests/test_scalar_ops.py +105 -0
  390. warp/tests/test_smoothstep.py +108 -0
  391. warp/tests/test_snippet.py +318 -0
  392. warp/tests/test_sparse.py +582 -0
  393. warp/tests/test_spatial.py +2229 -0
  394. warp/tests/test_special_values.py +361 -0
  395. warp/tests/test_static.py +592 -0
  396. warp/tests/test_struct.py +734 -0
  397. warp/tests/test_tape.py +204 -0
  398. warp/tests/test_transient_module.py +93 -0
  399. warp/tests/test_triangle_closest_point.py +145 -0
  400. warp/tests/test_types.py +562 -0
  401. warp/tests/test_utils.py +588 -0
  402. warp/tests/test_vec.py +1487 -0
  403. warp/tests/test_vec_lite.py +80 -0
  404. warp/tests/test_vec_scalar_ops.py +2327 -0
  405. warp/tests/test_verify_fp.py +100 -0
  406. warp/tests/tile/__init__.py +0 -0
  407. warp/tests/tile/test_tile.py +780 -0
  408. warp/tests/tile/test_tile_load.py +407 -0
  409. warp/tests/tile/test_tile_mathdx.py +208 -0
  410. warp/tests/tile/test_tile_mlp.py +402 -0
  411. warp/tests/tile/test_tile_reduce.py +447 -0
  412. warp/tests/tile/test_tile_shared_memory.py +247 -0
  413. warp/tests/tile/test_tile_view.py +173 -0
  414. warp/tests/unittest_serial.py +47 -0
  415. warp/tests/unittest_suites.py +427 -0
  416. warp/tests/unittest_utils.py +468 -0
  417. warp/tests/walkthrough_debug.py +93 -0
  418. warp/thirdparty/__init__.py +0 -0
  419. warp/thirdparty/appdirs.py +598 -0
  420. warp/thirdparty/dlpack.py +145 -0
  421. warp/thirdparty/unittest_parallel.py +570 -0
  422. warp/torch.py +391 -0
  423. warp/types.py +5230 -0
  424. warp/utils.py +1137 -0
  425. warp_lang-1.7.0.dist-info/METADATA +516 -0
  426. warp_lang-1.7.0.dist-info/RECORD +429 -0
  427. warp_lang-1.7.0.dist-info/WHEEL +5 -0
  428. warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
  429. warp_lang-1.7.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,592 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 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 importlib
17
+ import tempfile
18
+ import unittest
19
+ from typing import Dict, List
20
+
21
+ import numpy as np
22
+
23
+ import warp
24
+ import warp as wp
25
+ from warp.tests.unittest_utils import *
26
+
27
+ global_variable = 3
28
+
29
+
30
+ def load_code_as_module(code, name):
31
+ file, file_path = tempfile.mkstemp(suffix=".py")
32
+
33
+ try:
34
+ with os.fdopen(file, "w") as f:
35
+ f.write(code)
36
+
37
+ spec = importlib.util.spec_from_file_location(name, file_path)
38
+ module = importlib.util.module_from_spec(spec)
39
+ spec.loader.exec_module(module)
40
+ finally:
41
+ os.remove(file_path)
42
+
43
+ # return Warp module
44
+ return wp.get_module(module.__name__)
45
+
46
+
47
+ @wp.func
48
+ def static_global_variable_func():
49
+ static_var = warp.static(global_variable + 2)
50
+ return static_var
51
+
52
+
53
+ @wp.kernel
54
+ def static_global_variable_kernel(results: wp.array(dtype=int)):
55
+ # evaluate a constant expression at codegen time
56
+ static_var = static_global_variable_func()
57
+ const_var = 3
58
+ # call a function at codegen time
59
+ static_func_result = wp.static(static_global_variable_func() + const_var)
60
+ results[0] = static_var
61
+ results[1] = static_func_result
62
+
63
+
64
+ @wp.struct
65
+ class StaticallyConstructableStruct:
66
+ mat: wp.mat33
67
+ vec: wp.vec3
68
+ i: int
69
+
70
+
71
+ @wp.struct
72
+ class StaticallyConstructableNestedStruct:
73
+ s: StaticallyConstructableStruct
74
+ tf: wp.transform
75
+ quat: wp.quat
76
+
77
+
78
+ @wp.func
79
+ def construct_struct(mat: wp.mat33, vec: wp.vec3, i: int):
80
+ s = StaticallyConstructableStruct()
81
+ s.mat = mat
82
+ s.vec = vec
83
+ s.i = i
84
+ return s
85
+
86
+
87
+ @wp.func
88
+ def construct_nested_struct(mat: wp.mat33, vec: wp.vec3, i: int, tf: wp.transform, quat: wp.quat):
89
+ n = StaticallyConstructableNestedStruct()
90
+ n.s = construct_struct(mat, vec, i)
91
+ n.tf = tf
92
+ n.quat = quat
93
+ return n
94
+
95
+
96
+ @wp.kernel
97
+ def construct_static_struct_kernel(results: wp.array(dtype=StaticallyConstructableStruct)):
98
+ static_struct = wp.static(
99
+ construct_struct(
100
+ wp.mat33(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0),
101
+ wp.vec3(1.0, 2.0, 3.0),
102
+ 1,
103
+ )
104
+ )
105
+ results[0] = static_struct
106
+
107
+
108
+ @wp.kernel
109
+ def construct_static_nested_struct_kernel(results: wp.array(dtype=StaticallyConstructableNestedStruct)):
110
+ static_struct = wp.static(
111
+ construct_nested_struct(
112
+ wp.mat33(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0),
113
+ wp.vec3(1.0, 2.0, 3.0),
114
+ 1,
115
+ wp.transform(wp.vec3(1.0, 2.0, 3.0), wp.quat_from_axis_angle(wp.vec3(0.0, 1.0, 0.0), wp.pi / 2.0)),
116
+ wp.quat_from_axis_angle(wp.normalize(wp.vec3(1.0, 2.0, 3.0)), wp.pi / 2.0),
117
+ )
118
+ )
119
+ results[0] = static_struct
120
+
121
+
122
+ def test_static_global_variable(test, device):
123
+ results = wp.zeros(2, dtype=int, device=device)
124
+ wp.launch(static_global_variable_kernel, 1, [results], device=device)
125
+ assert_np_equal(results.numpy(), np.array([5, 8], dtype=int))
126
+
127
+
128
+ def test_construct_static_struct(test, device):
129
+ results = wp.zeros(1, dtype=StaticallyConstructableStruct, device=device)
130
+ wp.launch(construct_static_struct_kernel, 1, [results], device=device)
131
+ results = results.numpy()
132
+ assert_np_equal(results[0][0], np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]))
133
+ assert_np_equal(results[0][1], np.array([1.0, 2.0, 3.0]))
134
+ assert_np_equal(results[0][2], 1)
135
+
136
+
137
+ def test_construct_static_nested_struct(test, device):
138
+ results = wp.zeros(1, dtype=StaticallyConstructableNestedStruct, device=device)
139
+ wp.launch(construct_static_nested_struct_kernel, 1, [results], device=device)
140
+ results = results.numpy()
141
+
142
+ tf = wp.transform(wp.vec3(1.0, 2.0, 3.0), wp.quat_from_axis_angle(wp.vec3(0.0, 1.0, 0.0), wp.pi / 2.0))
143
+ quat = wp.quat_from_axis_angle(wp.normalize(wp.vec3(1.0, 2.0, 3.0)), wp.pi / 2.0)
144
+
145
+ assert_np_equal(results[0][0][0], np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]))
146
+ assert_np_equal(results[0][0][1], np.array([1.0, 2.0, 3.0]))
147
+ assert_np_equal(results[0][0][2], 1)
148
+ assert_np_equal(results[0][1], np.array(tf))
149
+ assert_np_equal(results[0][2], np.array(quat))
150
+
151
+
152
+ def test_invalid_static_expression(test, device):
153
+ @wp.kernel
154
+ def invalid_kernel():
155
+ wp.static(1.0 / 0.0)
156
+
157
+ with test.assertRaisesRegex(
158
+ warp.codegen.WarpCodegenError, r"Error evaluating static expression\: float division by zero"
159
+ ):
160
+ wp.launch(invalid_kernel, 1, device=device)
161
+
162
+ @wp.kernel
163
+ def invalid_kernel(i: int):
164
+ wp.static(i * 2)
165
+
166
+ with test.assertRaisesRegex(
167
+ wp.codegen.WarpCodegenError,
168
+ r"Error evaluating static expression\: name 'i' is not defined\. Make sure all variables used in the static expression are constant\.",
169
+ ):
170
+ wp.launch(invalid_kernel, 1, device=device, inputs=[3])
171
+
172
+
173
+ def test_static_expression_return_types(test, device):
174
+ @wp.kernel
175
+ def invalid_kernel():
176
+ wp.static(wp.zeros(3, device=device))
177
+
178
+ with test.assertRaisesRegex(
179
+ warp.codegen.WarpCodegenError,
180
+ r"Static expression returns an unsupported value\: a Warp array cannot be created inside Warp kernels",
181
+ ):
182
+ wp.launch(invalid_kernel, 1, device=device)
183
+
184
+ @wp.struct
185
+ class Baz:
186
+ data: wp.array(dtype=int)
187
+ z: wp.vec3
188
+
189
+ @wp.struct
190
+ class Bar:
191
+ baz: Baz
192
+ y: float
193
+
194
+ @wp.struct
195
+ class Foo:
196
+ bar: Bar
197
+ x: int
198
+
199
+ def create_struct():
200
+ foo = Foo()
201
+ foo.bar = Bar()
202
+ foo.bar.baz = Baz()
203
+ foo.bar.baz.data = wp.zeros(3, dtype=int, device=device)
204
+ foo.bar.baz.z = wp.vec3(1, 2, 3)
205
+ foo.bar.y = 1.23
206
+ foo.x = 123
207
+ return foo
208
+
209
+ @wp.kernel
210
+ def invalid_kernel():
211
+ wp.static(create_struct())
212
+
213
+ with test.assertRaisesRegex(
214
+ warp.codegen.WarpCodegenError,
215
+ r"Static expression returns an unsupported value: the returned Warp struct contains a data type that cannot be constructed inside Warp kernels\: a Warp array cannot be created inside Warp kernels at .*?Foo\.bar\.baz",
216
+ ):
217
+ wp.launch(invalid_kernel, 1, device=device)
218
+
219
+ def function_with_no_return_value():
220
+ pass
221
+
222
+ @wp.kernel
223
+ def invalid_kernel():
224
+ wp.static(function_with_no_return_value())
225
+
226
+ with test.assertRaisesRegex(
227
+ warp.codegen.WarpCodegenError,
228
+ r"Static expression returns an unsupported value\: None is returned",
229
+ ):
230
+ wp.launch(invalid_kernel, 1, device=device)
231
+
232
+ class MyClass:
233
+ pass
234
+
235
+ @wp.kernel
236
+ def invalid_kernel():
237
+ wp.static(MyClass())
238
+
239
+ with test.assertRaisesRegex(
240
+ warp.codegen.WarpCodegenError,
241
+ r"Static expression returns an unsupported value\: value of type .*?MyClass",
242
+ ):
243
+ wp.launch(invalid_kernel, 1, device=device)
244
+
245
+
246
+ def test_function_variable(test, device):
247
+ # create a function and pass it in as a static variable to the kernel
248
+ @wp.func
249
+ def func1(a: int, b: int):
250
+ return a + b
251
+
252
+ @wp.func
253
+ def func2(a: int, b: int):
254
+ return a - b
255
+
256
+ for func in [func1, func2]:
257
+ # note that this example also works without using wp.static()
258
+
259
+ @wp.kernel
260
+ def function_variable_kernel(results: wp.array(dtype=int)):
261
+ results[0] = wp.static(func)(3, 2) # noqa: B023
262
+
263
+ results = wp.zeros(1, dtype=int, device=device)
264
+ # note that the kernel has to be recompiled every time the value of func changes
265
+ wp.launch(function_variable_kernel, 1, [results], device=device)
266
+ assert_np_equal(results.numpy(), np.array([func(3, 2)], dtype=int))
267
+
268
+
269
+ def test_function_lookup(test, device):
270
+ @wp.func
271
+ def do_add(a: float, b: float):
272
+ return a + b
273
+
274
+ @wp.func
275
+ def do_sub(a: float, b: float):
276
+ return a - b
277
+
278
+ @wp.func
279
+ def do_mul(a: float, b: float):
280
+ return a * b
281
+
282
+ op_handlers = {
283
+ "add": do_add,
284
+ "sub": do_sub,
285
+ "mul": do_mul,
286
+ }
287
+
288
+ inputs = wp.array([[1, 2], [3, 0]], dtype=wp.float32)
289
+
290
+ outputs = wp.empty(2, dtype=wp.float32)
291
+
292
+ for _op, op_func in op_handlers.items():
293
+
294
+ @wp.kernel
295
+ def operate(input: wp.array(dtype=inputs.dtype, ndim=2), output: wp.array(dtype=wp.float32)):
296
+ tid = wp.tid()
297
+ a, b = input[tid, 0], input[tid, 1]
298
+ # retrieve the right function to use for the captured dtype variable
299
+ output[tid] = wp.static(op_func)(a, b) # noqa: B023
300
+
301
+ wp.launch(operate, dim=2, inputs=[inputs], outputs=[outputs])
302
+ outputs_np = outputs.numpy()
303
+ inputs_np = inputs.numpy()
304
+ for i in range(len(outputs_np)):
305
+ test.assertEqual(outputs_np[i], op_func(float(inputs_np[i][0]), float(inputs_np[i][1])))
306
+
307
+
308
+ def count_ssa_occurrences(kernel: wp.Kernel, ssas: List[str]) -> Dict[str, int]:
309
+ # analyze the generated code
310
+ counts = dict.fromkeys(ssas, 0)
311
+ for line in kernel.adj.blocks[0].body_forward:
312
+ for ssa in ssas:
313
+ if ssa in line:
314
+ counts[ssa] += 1
315
+ return counts
316
+
317
+
318
+ def test_static_for_loop(test, device):
319
+ @wp.kernel
320
+ def static_loop_variable(results: wp.array(dtype=int)):
321
+ s = 0
322
+ for i in range(wp.static(static_global_variable_func())):
323
+ s += wp.static(i)
324
+ results[0] = s
325
+
326
+ wp.set_module_options(
327
+ options={"max_unroll": static_global_variable_func()},
328
+ )
329
+
330
+ results = wp.zeros(1, dtype=int, device=device)
331
+ wp.launch(static_loop_variable, 1, [results], device=device)
332
+ results = results.numpy()
333
+
334
+ s = 0
335
+ for i in range(wp.static(static_global_variable_func())):
336
+ s += wp.static(i)
337
+
338
+ test.assertEqual(results[0], s, "Static for loop has to compute the correct solution")
339
+
340
+ # analyze the generated code
341
+ if hasattr(static_loop_variable.adj, "blocks"):
342
+ counts = count_ssa_occurrences(static_loop_variable, ["add", "for"])
343
+
344
+ test.assertEqual(counts["add"], static_global_variable_func(), "Static for loop must be unrolled")
345
+ # there is just one occurrence of "for" in the comment referring to the original Python code
346
+ test.assertEqual(counts["for"], 1, "Static for loop must be unrolled")
347
+
348
+
349
+ def test_static_if_else_elif(test, device):
350
+ @wp.kernel
351
+ def static_condition1(results: wp.array(dtype=int)):
352
+ if wp.static(static_global_variable_func() in {2, 3, 5}):
353
+ results[0] = 1
354
+ elif wp.static(static_global_variable_func() in {0, 1}):
355
+ results[0] = 2
356
+ else:
357
+ results[0] = 3
358
+
359
+ results = wp.zeros(1, dtype=int, device=device)
360
+ wp.launch(static_condition1, 1, [results], device=device)
361
+ results = results.numpy()
362
+ assert_np_equal(results[0], 1)
363
+ # TODO this needs fixing to ensure we can run these tests multiple times
364
+ if hasattr(static_condition1.adj, "blocks"):
365
+ counts = count_ssa_occurrences(static_condition1, ["if", "else"])
366
+
367
+ # if, else, elif can appear as comments but the generated code must not contain
368
+ # such keywords since the conditions are resolved at the time of code generation
369
+ assert_np_equal(counts["if"], 1)
370
+ assert_np_equal(counts["else"], 0)
371
+
372
+ captured_var = "hello"
373
+
374
+ @wp.kernel
375
+ def static_condition2(results: wp.array(dtype=int)):
376
+ if wp.static(captured_var == "world"):
377
+ results[0] = 1
378
+ else:
379
+ results[0] = 2
380
+
381
+ results = wp.zeros(1, dtype=int, device=device)
382
+ wp.launch(static_condition2, 1, [results], device=device)
383
+ results = results.numpy()
384
+ assert_np_equal(results[0], 2)
385
+ if hasattr(static_condition2.adj, "blocks"):
386
+ counts = count_ssa_occurrences(static_condition2, ["if", "else"])
387
+ assert_np_equal(counts["if"], 1)
388
+ assert_np_equal(counts["else"], 0)
389
+
390
+ my_list = [1, 2, 3]
391
+
392
+ @wp.kernel
393
+ def static_condition3(results: wp.array(dtype=int)):
394
+ if wp.static(len(my_list) == 0):
395
+ results[0] = 0
396
+ elif wp.static(len(my_list) == 1):
397
+ results[0] = 1
398
+ elif wp.static(len(my_list) == 2):
399
+ results[0] = 2
400
+ elif wp.static(len(my_list) == 3):
401
+ results[0] = 3
402
+
403
+ results = wp.zeros(1, dtype=int, device=device)
404
+ wp.launch(static_condition3, 1, [results], device=device)
405
+ results = results.numpy()
406
+ assert_np_equal(results[0], 3)
407
+ if hasattr(static_condition3.adj, "blocks"):
408
+ counts = count_ssa_occurrences(static_condition3, ["if", "else"])
409
+ assert_np_equal(counts["if"], 4)
410
+ assert_np_equal(counts["else"], 0)
411
+
412
+
413
+ static_builtin_constant_template = """
414
+ import warp as wp
415
+
416
+ # Python builtin literal like 17, 42.0, or True
417
+ C = {value}
418
+
419
+ @wp.kernel
420
+ def k():
421
+ print(wp.static(C))
422
+ """
423
+
424
+ static_warp_constant_template = """
425
+ import warp as wp
426
+
427
+ # Warp scalar value like wp.uint8(17)
428
+ C = wp.{dtype}({value})
429
+
430
+ @wp.kernel
431
+ def k():
432
+ print(wp.static(C))
433
+ """
434
+
435
+ static_struct_constant_template = """
436
+ import warp as wp
437
+
438
+ @wp.struct
439
+ class SimpleStruct:
440
+ x: float
441
+
442
+ C = SimpleStruct()
443
+ C.x = {value}
444
+
445
+ @wp.kernel
446
+ def k():
447
+ print(wp.static(C))
448
+ """
449
+
450
+ static_func_template = """
451
+ import warp as wp
452
+
453
+ @wp.func
454
+ def f():
455
+ # modify the function to verify hashing
456
+ return {value}
457
+
458
+ @wp.kernel
459
+ def k():
460
+ print(wp.static(f)())
461
+ """
462
+
463
+
464
+ def test_static_constant_hash(test, _):
465
+ # Python literals
466
+ # (type, value1, value2)
467
+ literals = [
468
+ (int, 17, 42),
469
+ (float, 17.5, 42.5),
470
+ (bool, True, False),
471
+ ]
472
+
473
+ for builtin_type, value1, value2 in literals:
474
+ type_name = builtin_type.__name__
475
+ with test.subTest(msg=f"{type_name}"):
476
+ source1 = static_builtin_constant_template.format(value=value1)
477
+ source2 = static_builtin_constant_template.format(value=value2)
478
+ source3 = static_builtin_constant_template.format(value=value1)
479
+
480
+ module1 = load_code_as_module(source1, f"aux_static_constant_builtin_{type_name}_1")
481
+ module2 = load_code_as_module(source2, f"aux_static_constant_builtin_{type_name}_2")
482
+ module3 = load_code_as_module(source3, f"aux_static_constant_builtin_{type_name}_3")
483
+
484
+ hash1 = module1.hash_module()
485
+ hash2 = module2.hash_module()
486
+ hash3 = module3.hash_module()
487
+
488
+ test.assertNotEqual(hash1, hash2)
489
+ test.assertEqual(hash1, hash3)
490
+
491
+ # Warp types (scalars, vectors, matrices)
492
+ for warp_type in [*wp.types.scalar_types, *wp.types.vector_types]:
493
+ type_name = warp_type.__name__
494
+ with test.subTest(msg=f"wp.{type_name}"):
495
+ value1 = ", ".join([str(17)] * warp_type._length_)
496
+ value2 = ", ".join([str(42)] * warp_type._length_)
497
+ source1 = static_warp_constant_template.format(dtype=type_name, value=value1)
498
+ source2 = static_warp_constant_template.format(dtype=type_name, value=value2)
499
+ source3 = static_warp_constant_template.format(dtype=type_name, value=value1)
500
+
501
+ module1 = load_code_as_module(source1, f"aux_static_constant_wp_{type_name}_1")
502
+ module2 = load_code_as_module(source2, f"aux_static_constant_wp_{type_name}_2")
503
+ module3 = load_code_as_module(source3, f"aux_static_constant_wp_{type_name}_3")
504
+
505
+ hash1 = module1.hash_module()
506
+ hash2 = module2.hash_module()
507
+ hash3 = module3.hash_module()
508
+
509
+ test.assertNotEqual(hash1, hash2)
510
+ test.assertEqual(hash1, hash3)
511
+
512
+ # structs
513
+ with test.subTest(msg="struct"):
514
+ source1 = static_struct_constant_template.format(value=17)
515
+ source2 = static_struct_constant_template.format(value=42)
516
+ source3 = static_struct_constant_template.format(value=17)
517
+
518
+ module1 = load_code_as_module(source1, "aux_static_constant_struct_1")
519
+ module2 = load_code_as_module(source2, "aux_static_constant_struct_2")
520
+ module3 = load_code_as_module(source3, "aux_static_constant_struct_3")
521
+
522
+ hash1 = module1.hash_module()
523
+ hash2 = module2.hash_module()
524
+ hash3 = module3.hash_module()
525
+
526
+ test.assertNotEqual(hash1, hash2)
527
+ test.assertEqual(hash1, hash3)
528
+
529
+
530
+ def test_static_function_hash(test, _):
531
+ source1 = static_func_template.format(value=17)
532
+ source2 = static_func_template.format(value=42)
533
+ source3 = static_func_template.format(value=17)
534
+
535
+ module1 = load_code_as_module(source1, "aux_static_func1")
536
+ module2 = load_code_as_module(source2, "aux_static_func2")
537
+ module3 = load_code_as_module(source3, "aux_static_func3")
538
+
539
+ hash1 = module1.hash_module()
540
+ hash2 = module2.hash_module()
541
+ hash3 = module3.hash_module()
542
+
543
+ test.assertNotEqual(hash1, hash2)
544
+ test.assertEqual(hash1, hash3)
545
+
546
+
547
+ @wp.kernel
548
+ def static_len_query_kernel(v1: wp.vec2):
549
+ v2 = wp.vec3()
550
+ m = wp.identity(n=wp.static(len(v1) + len(v2) + 1), dtype=float)
551
+ wp.expect_eq(wp.ddot(m, m), 6.0)
552
+
553
+ t = wp.transform_identity(float)
554
+ wp.expect_eq(wp.static(len(t)), 7)
555
+
556
+
557
+ def test_static_len_query(test, _):
558
+ v1 = wp.vec2()
559
+ wp.launch(static_len_query_kernel, 1, inputs=(v1,))
560
+
561
+
562
+ devices = get_test_devices()
563
+
564
+
565
+ class TestStatic(unittest.TestCase):
566
+ def test_static_python_call(self):
567
+ # ensure wp.static() works from a Python context
568
+ self.assertEqual(static_global_variable_func(), 5)
569
+
570
+
571
+ add_function_test(TestStatic, "test_static_global_variable", test_static_global_variable, devices=devices)
572
+ add_function_test(TestStatic, "test_construct_static_struct", test_construct_static_struct, devices=devices)
573
+ add_function_test(
574
+ TestStatic, "test_construct_static_nested_struct", test_construct_static_nested_struct, devices=devices
575
+ )
576
+ add_function_test(TestStatic, "test_function_variable", test_function_variable, devices=devices)
577
+ add_function_test(TestStatic, "test_function_lookup", test_function_lookup, devices=devices)
578
+ add_function_test(TestStatic, "test_invalid_static_expression", test_invalid_static_expression, devices=devices)
579
+ add_function_test(
580
+ TestStatic, "test_static_expression_return_types", test_static_expression_return_types, devices=devices
581
+ )
582
+ add_function_test(TestStatic, "test_static_for_loop", test_static_for_loop, devices=devices)
583
+ add_function_test(TestStatic, "test_static_if_else_elif", test_static_if_else_elif, devices=devices)
584
+
585
+ add_function_test(TestStatic, "test_static_constant_hash", test_static_constant_hash, devices=None)
586
+ add_function_test(TestStatic, "test_static_function_hash", test_static_function_hash, devices=None)
587
+ add_function_test(TestStatic, "test_static_len_query", test_static_len_query, devices=None)
588
+
589
+
590
+ if __name__ == "__main__":
591
+ wp.clear_kernel_cache()
592
+ unittest.main(verbosity=2)