warp-lang 1.7.0__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 (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,613 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ // The Apache 2 License
19
+
20
+ // Copyright 2023 Anka He Chen
21
+ //
22
+ // Licensed under the Apache License, Version 2.0 (the "License"); you may not
23
+ // use this file except in compliance with the License.You may obtain a copy of the License at
24
+ // http ://www.apache.org/licenses/LICENSE-2.0
25
+ // Unless required by applicable law or agreed to in writing, software distributed under the
26
+ // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
27
+ // either express or implied.See the License for the specific language governing permissions
28
+ // and limitations under the License.
29
+ //
30
+ // Source: https://github.com/AnkaChan/Gaia/blob/main/Simulator/Modules/GraphColoring/ColoringAlgorithms.cpp
31
+ // https://github.com/AnkaChan/Gaia/blob/main/Simulator/Modules/GraphColoring/ColoringAlgorithms.h
32
+ // https://github.com/AnkaChan/Gaia/blob/main/Simulator/Modules/GraphColoring/Graph.h
33
+
34
+
35
+
36
+ #include "warp.h"
37
+
38
+ #include <iostream>
39
+ #include <vector>
40
+ #include <array>
41
+ #include <queue>
42
+ #include <queue>
43
+ #include <unordered_set>
44
+ #include <random>
45
+ #include <algorithm>
46
+ #include <numeric>
47
+
48
+ #define SHRINK_GRAPH_PER_PERCENTAGE (5)
49
+ #define NODE_WEIGHTS_PREALLOC (64)
50
+ #define WEIGHT_BUCKET_PREALLOC (512)
51
+
52
+ namespace wp
53
+ {
54
+
55
+ struct Graph
56
+ {
57
+ Graph(int num_nodes_in, const wp::array_t<int>& edges)
58
+ : num_nodes(num_nodes_in)
59
+ {
60
+ node_offsets.resize(num_nodes + 1, 0);
61
+ node_colors.resize(num_nodes, -1);
62
+
63
+ std::vector<int> node_degrees(num_nodes, 0);
64
+
65
+ // count degrees
66
+ for (size_t edge_idx = 0; edge_idx < edges.shape[0]; edge_idx++)
67
+ {
68
+ int e0 = *address(edges, edge_idx, 0);
69
+ int e1 = *address(edges, edge_idx, 1);
70
+ node_degrees[e0] += 1;
71
+ node_degrees[e1] += 1;
72
+ }
73
+
74
+ int offset = 0;
75
+ for (size_t node = 0; node < num_nodes; node++)
76
+ {
77
+ offset += node_degrees[node];
78
+ node_offsets[node + 1] = offset;
79
+ }
80
+
81
+ // fill adjacency list
82
+ std::vector<int> node_adjacency_fill_count(num_nodes, 0);
83
+ graph_flatten.resize(offset, -1);
84
+ for (size_t edge_idx = 0; edge_idx < edges.shape[0]; edge_idx++)
85
+ {
86
+ int e0 = *address(edges, edge_idx, 0);
87
+ int e1 = *address(edges, edge_idx, 1);
88
+
89
+ int fill_count_e0 = node_adjacency_fill_count[e0];
90
+ graph_flatten[node_offsets[e0] + fill_count_e0] = e1;
91
+
92
+ int fill_count_e1 = node_adjacency_fill_count[e1];
93
+ graph_flatten[node_offsets[e1] + fill_count_e1] = e0;
94
+
95
+ node_adjacency_fill_count[e0] = fill_count_e0 + 1;
96
+ node_adjacency_fill_count[e1] = fill_count_e1 + 1;
97
+ }
98
+
99
+ }
100
+
101
+ int get_node_neighbor(int node, int neighbor_index) const {
102
+ return graph_flatten[node_offsets[node] + neighbor_index];
103
+ }
104
+
105
+ int get_node_degree(int node) const {
106
+ return node_offsets[node + 1] - node_offsets[node];
107
+ }
108
+
109
+
110
+ int num_nodes;
111
+ std::vector<int> graph_flatten;
112
+ std::vector<int> node_offsets;
113
+ std::vector<int> node_colors;
114
+ };
115
+
116
+ void convert_to_color_groups(const int num_colors, const std::vector<int>& node_colors, std::vector<std::vector<int>>& color_groups)
117
+ {
118
+ color_groups.resize(num_colors);
119
+
120
+ for (int node_idx = 0; node_idx < node_colors.size(); node_idx++) {
121
+ int color = node_colors[node_idx];
122
+ color_groups[color].push_back(node_idx);
123
+ }
124
+ }
125
+
126
+ float find_largest_smallest_groups(const std::vector<std::vector<int>>& color_groups, int& biggest_group, int& smallest_group)
127
+ {
128
+ if (color_groups.size() == 0)
129
+ {
130
+ biggest_group = -1;
131
+ smallest_group = -1;
132
+
133
+ return 1;
134
+ }
135
+
136
+ size_t max_size = color_groups[0].size();
137
+ biggest_group = 0;
138
+ size_t min_size = color_groups[0].size();
139
+ smallest_group = 0;
140
+
141
+ for (size_t color = 0; color < color_groups.size(); color++)
142
+ {
143
+ if (max_size < color_groups[color].size()) {
144
+ biggest_group = color;
145
+ max_size = color_groups[color].size();
146
+ }
147
+
148
+ if (min_size > color_groups[color].size())
149
+ {
150
+ smallest_group = color;
151
+ min_size = color_groups[color].size();
152
+ }
153
+ }
154
+
155
+ return float(color_groups[biggest_group].size()) / float(color_groups[smallest_group].size());
156
+ }
157
+
158
+ bool color_changeable(const Graph& graph, int node, int target_color){
159
+ // loop through node and see if it has target color
160
+ for (size_t i = 0; i < graph.get_node_degree(node); i++)
161
+ {
162
+ int nei_node_idx = graph.get_node_neighbor(node, i);
163
+ if (graph.node_colors[nei_node_idx] == target_color)
164
+ {
165
+ return false;
166
+ }
167
+ }
168
+ return true;
169
+ }
170
+
171
+ int find_changeable_node_in_category(
172
+ const Graph& graph,
173
+ const std::vector<std::vector<int>>& color_groups,
174
+ int source_color,
175
+ int target_color
176
+ )
177
+ {
178
+ auto& source_group = color_groups[source_color];
179
+ for (size_t node_idx = 0; node_idx < source_group.size(); node_idx++)
180
+ {
181
+ if (color_changeable(graph, source_group[node_idx], target_color)) {
182
+ return node_idx;
183
+ }
184
+ }
185
+ return -1;
186
+ }
187
+
188
+ void change_color(int color, int node_idx_in_group, int target_color, std::vector<int>& node_colors, std::vector<std::vector<int>>& color_groups)
189
+ {
190
+ int node_idx = color_groups[color][node_idx_in_group];
191
+ node_colors[node_idx] = target_color;
192
+
193
+ if (color_groups.size())
194
+ {
195
+ // O(1) erase
196
+ std::swap(color_groups[color][node_idx_in_group], color_groups[color].back());
197
+ color_groups[color].pop_back();
198
+
199
+ color_groups[target_color].push_back(node_idx);
200
+ }
201
+ }
202
+
203
+ float balance_color_groups(float target_max_min_ratio,
204
+ Graph& graph,
205
+ std::vector<std::vector<int>>& color_groups)
206
+ {
207
+ float max_min_ratio = -1.f;
208
+
209
+ do
210
+ {
211
+ int biggest_group = -1, smallest_group = -1;
212
+
213
+ max_min_ratio = find_largest_smallest_groups(color_groups, biggest_group, smallest_group);
214
+
215
+ // graph is not optimizable anymore or target ratio reached
216
+ if (color_groups[biggest_group].size() - color_groups[smallest_group].size() <= 2
217
+ || max_min_ratio < target_max_min_ratio)
218
+ {
219
+ return max_min_ratio;
220
+ }
221
+
222
+ // find a available vertex from the biggest category to move to the smallest category
223
+ int changeable_color_group_idx = biggest_group;
224
+ int changeable_node_idx = find_changeable_node_in_category(graph, color_groups, biggest_group, smallest_group);
225
+ if (changeable_node_idx == -1)
226
+ {
227
+ for (size_t color = 0; color < color_groups.size(); color++)
228
+ {
229
+ if (color == biggest_group || color == smallest_group)
230
+ {
231
+ continue;
232
+ }
233
+
234
+ changeable_node_idx = find_changeable_node_in_category(graph, color_groups, color, smallest_group);
235
+
236
+ if (changeable_node_idx != -1)
237
+ {
238
+ changeable_color_group_idx = color;
239
+
240
+ break;
241
+ }
242
+ }
243
+ }
244
+
245
+
246
+ if (changeable_node_idx == -1)
247
+ {
248
+ // fprintf(stderr, "The graph is not optimizable anymore, terminated with a max/min ratio: %f without reaching the target ratio: %f\n", max_min_ratio, target_max_min_ratio);
249
+ return max_min_ratio;
250
+ }
251
+ // change the color of changeable_color_idx in group changeable_color_group_idx to
252
+ change_color(changeable_color_group_idx, changeable_node_idx, smallest_group, graph.node_colors, color_groups);
253
+
254
+
255
+ } while (max_min_ratio > target_max_min_ratio);
256
+
257
+ return max_min_ratio;
258
+ }
259
+
260
+ int graph_coloring_ordered_greedy(const std::vector<int>& order, Graph& graph)
261
+ {
262
+ // greedy coloring
263
+ int max_color = -1;
264
+ int num_colored = 0;
265
+ std::vector<bool> color_used;
266
+ color_used.reserve(128);
267
+
268
+ for (size_t i = 0; i < order.size(); i++)
269
+ {
270
+ int node = order[i];
271
+
272
+ // first one
273
+ if (max_color == -1)
274
+ {
275
+ ++max_color;
276
+ graph.node_colors[node] = max_color;
277
+ }
278
+ else {
279
+ color_used.resize(max_color + 1);
280
+
281
+ for (int color_counter = 0; color_counter < color_used.size(); color_counter++)
282
+ {
283
+ color_used[color_counter] = false;
284
+ }
285
+
286
+ // see its neighbor's color
287
+ for (int nei_counter = 0; nei_counter < graph.get_node_degree(node); nei_counter++)
288
+ {
289
+ int nei_node_idx = graph.get_node_neighbor(node, nei_counter);
290
+ if (graph.node_colors[nei_node_idx] >= 0)
291
+ {
292
+ color_used[graph.node_colors[nei_node_idx]] = true;
293
+ }
294
+ }
295
+
296
+ // find the minimal usable color
297
+ int min_usable_color = -1;
298
+ for (int color_counter = 0; color_counter < color_used.size(); color_counter++)
299
+ {
300
+ if (!color_used[color_counter]) {
301
+ min_usable_color = color_counter;
302
+ break;
303
+ }
304
+ }
305
+ if (min_usable_color == -1)
306
+ {
307
+ ++max_color;
308
+ graph.node_colors[node] = max_color;
309
+ }
310
+ else
311
+ {
312
+ graph.node_colors[node] = min_usable_color;
313
+ }
314
+ }
315
+
316
+ num_colored++;
317
+ }
318
+ return (max_color + 1);
319
+ }
320
+
321
+ class NodeWeightBuckets
322
+ {
323
+ public:
324
+ NodeWeightBuckets(int num_nodes)
325
+ : node_weights(num_nodes, 0), node_indices_in_bucket(num_nodes, -1)
326
+ {
327
+ weight_buckets.resize(NODE_WEIGHTS_PREALLOC);
328
+ for (size_t i = 1; i < weight_buckets.size(); i++)
329
+ {
330
+ weight_buckets[i].reserve(WEIGHT_BUCKET_PREALLOC);
331
+ }
332
+ max_weight = 0;
333
+ }
334
+
335
+ int get_node_weight(int node_idx)
336
+ {
337
+ return node_weights[node_idx];
338
+ }
339
+
340
+ void add_node(int weight, int node_idx)
341
+ {
342
+ if (weight >= weight_buckets.size())
343
+ {
344
+ weight_buckets.resize(weight + 1);
345
+ }
346
+
347
+ node_indices_in_bucket[node_idx] = weight_buckets[weight].size();
348
+ node_weights[node_idx] = weight;
349
+ weight_buckets[weight].push_back(node_idx);
350
+
351
+ if (max_weight < weight)
352
+ {
353
+ max_weight = weight;
354
+ }
355
+ }
356
+
357
+ int pop_node_with_max_weight() {
358
+ int node_with_max_weight = weight_buckets[max_weight].front();
359
+ node_indices_in_bucket[node_with_max_weight] = -1;
360
+
361
+ // we pop the first element so it has a breadth-first like behavior, which is better than depth-first
362
+ if (weight_buckets[max_weight].size() > 1)
363
+ {
364
+ node_indices_in_bucket[weight_buckets[max_weight].back()] = 0;
365
+ weight_buckets[max_weight][0] = weight_buckets[max_weight].back();
366
+ }
367
+ weight_buckets[max_weight].pop_back();
368
+ // mark node deleted
369
+ node_weights[node_with_max_weight] = -1;
370
+
371
+ if (weight_buckets[max_weight].size() == 0)
372
+ // we need to update max_weight because weight_buckets[max_weight] became empty
373
+ {
374
+ int new_max_weight = 0;
375
+ for (size_t bucket_idx = max_weight - 1; bucket_idx >= 0; bucket_idx--)
376
+ {
377
+ if (weight_buckets[bucket_idx].size())
378
+ {
379
+ new_max_weight = bucket_idx;
380
+ break;
381
+ }
382
+ }
383
+
384
+ max_weight = new_max_weight;
385
+ }
386
+ // mark deleted
387
+ return node_with_max_weight;
388
+ }
389
+
390
+ void increase_node_weight(int node_idx)
391
+ {
392
+ int weight = node_weights[node_idx];
393
+ assert(weight < weight_buckets.size());
394
+ int node_idx_in_bucket = node_indices_in_bucket[node_idx];
395
+ assert(node_idx_in_bucket < weight_buckets[weight].size());
396
+
397
+ // swap index with the last element
398
+ node_indices_in_bucket[weight_buckets[weight].back()] = node_idx_in_bucket;
399
+ // O(1) erase
400
+ weight_buckets[weight][node_idx_in_bucket] = weight_buckets[weight].back();
401
+ weight_buckets[weight].pop_back();
402
+
403
+ add_node(weight + 1, node_idx);
404
+ }
405
+
406
+ bool empty()
407
+ {
408
+ return max_weight <= 0 && weight_buckets[0].size() == 0;
409
+ }
410
+
411
+
412
+ private:
413
+ int max_weight;
414
+ std::vector<std::vector<int>> weight_buckets;
415
+ std::vector<int> node_indices_in_bucket;
416
+ std::vector<int> node_weights;
417
+ };
418
+
419
+ // Pereira, F. M. Q., & Palsberg, J. (2005, November). Register allocation via coloring of chordal graphs. In Asian Symposium on Programming Languages and Systems (pp. 315-329). Berlin, Heidelberg: Springer Berlin Heidelberg.
420
+ int graph_coloring_mcs_vector(Graph& graph)
421
+ {
422
+ // Initially set the weight of each node to 0
423
+ std::vector<int> ordering;
424
+ ordering.reserve(graph.num_nodes);
425
+
426
+ NodeWeightBuckets weight_buckets(graph.num_nodes);
427
+ // add the first node
428
+ weight_buckets.add_node(0, 0);
429
+
430
+ for (int node_idx = 0; node_idx < graph.num_nodes; node_idx++)
431
+ {
432
+ // this might look like it's O(N^2) but this only happens once per connected components
433
+ if (weight_buckets.empty())
434
+ {
435
+ int non_negative_node = -1;
436
+ for (size_t i = 0; i < graph.num_nodes; i++)
437
+ {
438
+ if (weight_buckets.get_node_weight(i) >= 0) {
439
+ non_negative_node = i;
440
+ break;
441
+ }
442
+ }
443
+ assert(weight_buckets.get_node_weight(non_negative_node) == 0);
444
+ weight_buckets.add_node(0, non_negative_node);
445
+ }
446
+
447
+ int max_node = weight_buckets.pop_node_with_max_weight();
448
+
449
+ // Add highest weight node to the queue and increment all of its neighbors weights by 1
450
+ ordering.push_back(max_node);
451
+
452
+ for (unsigned j = 0; j < graph.get_node_degree(max_node); j++) {
453
+ int neighbor_node = graph.get_node_neighbor(max_node, j);
454
+ int old_weight = weight_buckets.get_node_weight(neighbor_node);
455
+
456
+ if (old_weight == 0)
457
+ // 0-weighted node is not in buckets by default
458
+ {
459
+ weight_buckets.add_node(old_weight + 1, neighbor_node);
460
+
461
+ }
462
+ else if (old_weight > 0) {
463
+ weight_buckets.increase_node_weight(neighbor_node);
464
+ }
465
+ // skip neighbor nodes with negative weight because they are visited
466
+ }
467
+ }
468
+
469
+ return graph_coloring_ordered_greedy(ordering, graph);
470
+ }
471
+
472
+ int next_node(const int num_nodes, const std::vector<int>& degrees)
473
+ {
474
+ int node_min_degrees = -1;
475
+ int min_degree = num_nodes + 1;
476
+ for (size_t node_idx = 0; node_idx < degrees.size(); node_idx++)
477
+ {
478
+ if (degrees[node_idx] == -1)
479
+ {
480
+ continue;
481
+ }
482
+ if (min_degree > degrees[node_idx]) {
483
+ min_degree = degrees[node_idx];
484
+ node_min_degrees = node_idx;
485
+ }
486
+ }
487
+ return node_min_degrees;
488
+ }
489
+
490
+ void reduce_degree(int node_idx, Graph& graph, std::vector<int>& degrees)
491
+ {
492
+ degrees[node_idx] = -1;
493
+ for (size_t nei_node_counter = 0; nei_node_counter < graph.get_node_degree(node_idx); nei_node_counter++)
494
+ {
495
+ int nei_node_idx = graph.get_node_neighbor(node_idx, nei_node_counter);
496
+
497
+ if (degrees[nei_node_idx] != -1)
498
+ {
499
+ degrees[nei_node_idx]--;
500
+ }
501
+ }
502
+ }
503
+
504
+
505
+ // Fratarcangeli, Marco, and Fabio Pellacini. "Scalable partitioning for parallel position based dynamics." Computer Graphics Forum. Vol. 34. No. 2. 2015.
506
+ int graph_coloring_degree_ordered_greedy(Graph& graph)
507
+ {
508
+ // initialize the degree
509
+ std::vector<int> degrees(graph.num_nodes, 0);
510
+ for (int node_idx = 0; node_idx < graph.num_nodes; node_idx++) {
511
+ degrees[node_idx] = graph.get_node_degree(node_idx);
512
+ }
513
+
514
+ // order them in a descending order
515
+ std::vector<int> ordering(graph.num_nodes);
516
+ std::iota(std::begin(ordering), std::end(ordering), 0);
517
+ std::sort(std::begin(ordering), std::end(ordering),
518
+ [&degrees](const auto& lhs, const auto& rhs)
519
+ {
520
+ return degrees[lhs] > degrees[rhs];
521
+ }
522
+ );
523
+
524
+ return graph_coloring_ordered_greedy(ordering, graph);
525
+ }
526
+
527
+ int graph_coloring_naive_greedy(Graph& graph)
528
+ {
529
+ std::vector<int> ordering(graph.num_nodes);
530
+ std::iota(std::begin(ordering), std::end(ordering), 0);
531
+ return graph_coloring_ordered_greedy(ordering, graph);
532
+ }
533
+ }
534
+ using namespace wp;
535
+
536
+ extern "C"
537
+ {
538
+ int graph_coloring(int num_nodes, wp::array_t<int> edges, int algorithm, wp::array_t<int> node_colors)
539
+ {
540
+ if (node_colors.ndim != 1 || node_colors.shape[0] != num_nodes)
541
+ {
542
+ fprintf(stderr, "The node_colors array must have the preallocated shape of (num_nodes,)!\n");
543
+ return -1;
544
+ }
545
+
546
+ if (edges.ndim != 2)
547
+ {
548
+ fprintf(stderr, "The edges array must have 2 dimensions!\n");
549
+ return -1;
550
+ }
551
+
552
+ if (num_nodes == 0)
553
+ {
554
+ fprintf(stderr, "Empty graph!\n");
555
+ return -1;
556
+ }
557
+
558
+ // convert to a format that coloring algorithm can recognize
559
+
560
+ Graph graph(num_nodes, edges);
561
+
562
+ int num_colors = -1;
563
+ switch (algorithm)
564
+ {
565
+ case 0:
566
+ // mcs algorithm
567
+ num_colors = graph_coloring_mcs_vector(graph);
568
+ break;
569
+ case 1:
570
+ // greedy
571
+ num_colors = graph_coloring_degree_ordered_greedy(graph);
572
+ break;
573
+ //case 2:
574
+ // // mcs algorithm
575
+ // num_colors = graph_coloring_mcs_set(graph);
576
+ // break;
577
+ //case 3:
578
+ // // naive greedy
579
+ // num_colors = graph_coloring_naive_greedy(graph);
580
+ // break;
581
+ default:
582
+ fprintf(stderr, "Unrecognized coloring algorithm number: %d!\n", algorithm);
583
+ return -1;
584
+ break;
585
+ }
586
+
587
+ // copy the color info back
588
+ memcpy(node_colors.data, graph.node_colors.data(), num_nodes * sizeof(int));
589
+
590
+ return num_colors;
591
+ }
592
+
593
+ float balance_coloring(int num_nodes, wp::array_t<int> edges, int num_colors,
594
+ float target_max_min_ratio, wp::array_t<int> node_colors)
595
+ {
596
+ Graph graph(num_nodes, edges);
597
+ // copy the color info to graph
598
+ memcpy(graph.node_colors.data(), node_colors.data, num_nodes * sizeof(int));
599
+ if (num_colors > 1) {
600
+ std::vector<std::vector<int>> color_groups;
601
+ convert_to_color_groups(num_colors, graph.node_colors, color_groups);
602
+
603
+ float max_min_ratio = balance_color_groups(target_max_min_ratio, graph, color_groups);
604
+ memcpy(node_colors.data, graph.node_colors.data(), num_nodes * sizeof(int));
605
+
606
+ return max_min_ratio;
607
+ }
608
+ else
609
+ {
610
+ return 1.f;
611
+ }
612
+ }
613
+ }
warp/native/crt.cpp ADDED
@@ -0,0 +1,51 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "crt.h"
19
+
20
+ #include <cmath>
21
+ #include <cstdio>
22
+ #include <cassert>
23
+
24
+ extern "C" WP_API int _wp_isfinite(double x)
25
+ {
26
+ return std::isfinite(x);
27
+ }
28
+
29
+ extern "C" WP_API int _wp_isnan(double x)
30
+ {
31
+ return std::isnan(x);
32
+ }
33
+
34
+ extern "C" WP_API int _wp_isinf(double x)
35
+ {
36
+ return std::isinf(x);
37
+ }
38
+
39
+ extern "C" WP_API void _wp_assert(const char* expression, const char* file, unsigned int line)
40
+ {
41
+ fflush(stdout);
42
+ fprintf(stderr,
43
+ "Assertion failed: '%s'\n"
44
+ "At '%s:%d'\n",
45
+ expression, file, line);
46
+ fflush(stderr);
47
+
48
+ // Now invoke the standard assert(), which may abort the program or break
49
+ // into the debugger as decided by the runtime environment.
50
+ assert(false && "assert() failed");
51
+ }