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.
- warp/__init__.py +139 -0
- warp/__init__.pyi +1 -0
- warp/autograd.py +1142 -0
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +557 -0
- warp/build_dll.py +405 -0
- warp/builtins.py +6855 -0
- warp/codegen.py +3969 -0
- warp/config.py +158 -0
- warp/constants.py +57 -0
- warp/context.py +6812 -0
- warp/dlpack.py +462 -0
- warp/examples/__init__.py +24 -0
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cartpole.urdf +110 -0
- warp/examples/assets/crazyflie.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nonuniform.usd +0 -0
- warp/examples/assets/nv_ant.xml +92 -0
- warp/examples/assets/nv_humanoid.xml +183 -0
- warp/examples/assets/nvidia_logo.png +0 -0
- warp/examples/assets/pixel.jpg +0 -0
- warp/examples/assets/quadruped.urdf +268 -0
- warp/examples/assets/rocks.nvdb +0 -0
- warp/examples/assets/rocks.usd +0 -0
- warp/examples/assets/sphere.usd +0 -0
- warp/examples/assets/square_cloth.usd +0 -0
- warp/examples/benchmarks/benchmark_api.py +389 -0
- warp/examples/benchmarks/benchmark_cloth.py +296 -0
- warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
- warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
- warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
- warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
- warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
- warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
- warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
- warp/examples/benchmarks/benchmark_gemm.py +164 -0
- warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
- warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
- warp/examples/benchmarks/benchmark_launches.py +301 -0
- warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
- warp/examples/browse.py +37 -0
- warp/examples/core/example_cupy.py +86 -0
- warp/examples/core/example_dem.py +241 -0
- warp/examples/core/example_fluid.py +299 -0
- warp/examples/core/example_graph_capture.py +150 -0
- warp/examples/core/example_marching_cubes.py +194 -0
- warp/examples/core/example_mesh.py +180 -0
- warp/examples/core/example_mesh_intersect.py +211 -0
- warp/examples/core/example_nvdb.py +182 -0
- warp/examples/core/example_raycast.py +111 -0
- warp/examples/core/example_raymarch.py +205 -0
- warp/examples/core/example_render_opengl.py +193 -0
- warp/examples/core/example_sample_mesh.py +300 -0
- warp/examples/core/example_sph.py +411 -0
- warp/examples/core/example_torch.py +211 -0
- warp/examples/core/example_wave.py +269 -0
- warp/examples/fem/example_adaptive_grid.py +286 -0
- warp/examples/fem/example_apic_fluid.py +423 -0
- warp/examples/fem/example_burgers.py +261 -0
- warp/examples/fem/example_convection_diffusion.py +178 -0
- warp/examples/fem/example_convection_diffusion_dg.py +204 -0
- warp/examples/fem/example_deformed_geometry.py +172 -0
- warp/examples/fem/example_diffusion.py +196 -0
- warp/examples/fem/example_diffusion_3d.py +225 -0
- warp/examples/fem/example_diffusion_mgpu.py +220 -0
- warp/examples/fem/example_distortion_energy.py +228 -0
- warp/examples/fem/example_magnetostatics.py +240 -0
- warp/examples/fem/example_mixed_elasticity.py +291 -0
- warp/examples/fem/example_navier_stokes.py +261 -0
- warp/examples/fem/example_nonconforming_contact.py +298 -0
- warp/examples/fem/example_stokes.py +213 -0
- warp/examples/fem/example_stokes_transfer.py +262 -0
- warp/examples/fem/example_streamlines.py +352 -0
- warp/examples/fem/utils.py +1000 -0
- warp/examples/interop/example_jax_callable.py +116 -0
- warp/examples/interop/example_jax_ffi_callback.py +132 -0
- warp/examples/interop/example_jax_kernel.py +205 -0
- warp/examples/optim/example_bounce.py +266 -0
- warp/examples/optim/example_cloth_throw.py +228 -0
- warp/examples/optim/example_diffray.py +561 -0
- warp/examples/optim/example_drone.py +870 -0
- warp/examples/optim/example_fluid_checkpoint.py +497 -0
- warp/examples/optim/example_inverse_kinematics.py +182 -0
- warp/examples/optim/example_inverse_kinematics_torch.py +191 -0
- warp/examples/optim/example_softbody_properties.py +400 -0
- warp/examples/optim/example_spring_cage.py +245 -0
- warp/examples/optim/example_trajectory.py +227 -0
- warp/examples/sim/example_cartpole.py +143 -0
- warp/examples/sim/example_cloth.py +225 -0
- warp/examples/sim/example_cloth_self_contact.py +322 -0
- warp/examples/sim/example_granular.py +130 -0
- warp/examples/sim/example_granular_collision_sdf.py +202 -0
- warp/examples/sim/example_jacobian_ik.py +244 -0
- warp/examples/sim/example_particle_chain.py +124 -0
- warp/examples/sim/example_quadruped.py +203 -0
- warp/examples/sim/example_rigid_chain.py +203 -0
- warp/examples/sim/example_rigid_contact.py +195 -0
- warp/examples/sim/example_rigid_force.py +133 -0
- warp/examples/sim/example_rigid_gyroscopic.py +115 -0
- warp/examples/sim/example_rigid_soft_contact.py +140 -0
- warp/examples/sim/example_soft_body.py +196 -0
- warp/examples/tile/example_tile_cholesky.py +87 -0
- warp/examples/tile/example_tile_convolution.py +66 -0
- warp/examples/tile/example_tile_fft.py +55 -0
- warp/examples/tile/example_tile_filtering.py +113 -0
- warp/examples/tile/example_tile_matmul.py +85 -0
- warp/examples/tile/example_tile_mlp.py +383 -0
- warp/examples/tile/example_tile_nbody.py +199 -0
- warp/examples/tile/example_tile_walker.py +327 -0
- warp/fabric.py +355 -0
- warp/fem/__init__.py +106 -0
- warp/fem/adaptivity.py +508 -0
- warp/fem/cache.py +572 -0
- warp/fem/dirichlet.py +202 -0
- warp/fem/domain.py +411 -0
- warp/fem/field/__init__.py +125 -0
- warp/fem/field/field.py +619 -0
- warp/fem/field/nodal_field.py +326 -0
- warp/fem/field/restriction.py +37 -0
- warp/fem/field/virtual.py +848 -0
- warp/fem/geometry/__init__.py +32 -0
- warp/fem/geometry/adaptive_nanogrid.py +857 -0
- warp/fem/geometry/closest_point.py +84 -0
- warp/fem/geometry/deformed_geometry.py +221 -0
- warp/fem/geometry/element.py +776 -0
- warp/fem/geometry/geometry.py +362 -0
- warp/fem/geometry/grid_2d.py +392 -0
- warp/fem/geometry/grid_3d.py +452 -0
- warp/fem/geometry/hexmesh.py +911 -0
- warp/fem/geometry/nanogrid.py +571 -0
- warp/fem/geometry/partition.py +389 -0
- warp/fem/geometry/quadmesh.py +663 -0
- warp/fem/geometry/tetmesh.py +855 -0
- warp/fem/geometry/trimesh.py +806 -0
- warp/fem/integrate.py +2335 -0
- warp/fem/linalg.py +419 -0
- warp/fem/operator.py +293 -0
- warp/fem/polynomial.py +229 -0
- warp/fem/quadrature/__init__.py +17 -0
- warp/fem/quadrature/pic_quadrature.py +299 -0
- warp/fem/quadrature/quadrature.py +591 -0
- warp/fem/space/__init__.py +228 -0
- warp/fem/space/basis_function_space.py +468 -0
- warp/fem/space/basis_space.py +667 -0
- warp/fem/space/dof_mapper.py +251 -0
- warp/fem/space/function_space.py +309 -0
- warp/fem/space/grid_2d_function_space.py +177 -0
- warp/fem/space/grid_3d_function_space.py +227 -0
- warp/fem/space/hexmesh_function_space.py +257 -0
- warp/fem/space/nanogrid_function_space.py +201 -0
- warp/fem/space/partition.py +367 -0
- warp/fem/space/quadmesh_function_space.py +223 -0
- warp/fem/space/restriction.py +179 -0
- warp/fem/space/shape/__init__.py +143 -0
- warp/fem/space/shape/cube_shape_function.py +1105 -0
- warp/fem/space/shape/shape_function.py +133 -0
- warp/fem/space/shape/square_shape_function.py +926 -0
- warp/fem/space/shape/tet_shape_function.py +834 -0
- warp/fem/space/shape/triangle_shape_function.py +672 -0
- warp/fem/space/tetmesh_function_space.py +271 -0
- warp/fem/space/topology.py +424 -0
- warp/fem/space/trimesh_function_space.py +194 -0
- warp/fem/types.py +99 -0
- warp/fem/utils.py +420 -0
- warp/jax.py +187 -0
- warp/jax_experimental/__init__.py +16 -0
- warp/jax_experimental/custom_call.py +351 -0
- warp/jax_experimental/ffi.py +698 -0
- warp/jax_experimental/xla_ffi.py +602 -0
- warp/math.py +244 -0
- warp/native/array.h +1145 -0
- warp/native/builtin.h +1800 -0
- warp/native/bvh.cpp +492 -0
- warp/native/bvh.cu +791 -0
- warp/native/bvh.h +554 -0
- warp/native/clang/clang.cpp +536 -0
- warp/native/coloring.cpp +613 -0
- warp/native/crt.cpp +51 -0
- warp/native/crt.h +362 -0
- warp/native/cuda_crt.h +1058 -0
- warp/native/cuda_util.cpp +646 -0
- warp/native/cuda_util.h +307 -0
- warp/native/error.cpp +77 -0
- warp/native/error.h +36 -0
- warp/native/exports.h +1878 -0
- warp/native/fabric.h +245 -0
- warp/native/hashgrid.cpp +311 -0
- warp/native/hashgrid.cu +87 -0
- warp/native/hashgrid.h +240 -0
- warp/native/initializer_array.h +41 -0
- warp/native/intersect.h +1230 -0
- warp/native/intersect_adj.h +375 -0
- warp/native/intersect_tri.h +339 -0
- warp/native/marching.cpp +19 -0
- warp/native/marching.cu +514 -0
- warp/native/marching.h +19 -0
- warp/native/mat.h +2220 -0
- warp/native/mathdx.cpp +87 -0
- warp/native/matnn.h +343 -0
- warp/native/mesh.cpp +266 -0
- warp/native/mesh.cu +404 -0
- warp/native/mesh.h +1980 -0
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +6624 -0
- warp/native/nanovdb/PNanoVDB.h +3390 -0
- warp/native/noise.h +859 -0
- warp/native/quat.h +1371 -0
- warp/native/rand.h +342 -0
- warp/native/range.h +139 -0
- warp/native/reduce.cpp +174 -0
- warp/native/reduce.cu +364 -0
- warp/native/runlength_encode.cpp +79 -0
- warp/native/runlength_encode.cu +61 -0
- warp/native/scan.cpp +47 -0
- warp/native/scan.cu +53 -0
- warp/native/scan.h +23 -0
- warp/native/solid_angle.h +466 -0
- warp/native/sort.cpp +251 -0
- warp/native/sort.cu +277 -0
- warp/native/sort.h +33 -0
- warp/native/sparse.cpp +378 -0
- warp/native/sparse.cu +524 -0
- warp/native/spatial.h +657 -0
- warp/native/svd.h +702 -0
- warp/native/temp_buffer.h +46 -0
- warp/native/tile.h +2584 -0
- warp/native/tile_reduce.h +264 -0
- warp/native/vec.h +1426 -0
- warp/native/volume.cpp +501 -0
- warp/native/volume.cu +67 -0
- warp/native/volume.h +969 -0
- warp/native/volume_builder.cu +477 -0
- warp/native/volume_builder.h +52 -0
- warp/native/volume_impl.h +70 -0
- warp/native/warp.cpp +1082 -0
- warp/native/warp.cu +3636 -0
- warp/native/warp.h +381 -0
- warp/optim/__init__.py +17 -0
- warp/optim/adam.py +163 -0
- warp/optim/linear.py +1137 -0
- warp/optim/sgd.py +112 -0
- warp/paddle.py +407 -0
- warp/render/__init__.py +18 -0
- warp/render/render_opengl.py +3518 -0
- warp/render/render_usd.py +784 -0
- warp/render/utils.py +160 -0
- warp/sim/__init__.py +65 -0
- warp/sim/articulation.py +793 -0
- warp/sim/collide.py +2395 -0
- warp/sim/graph_coloring.py +300 -0
- warp/sim/import_mjcf.py +790 -0
- warp/sim/import_snu.py +227 -0
- warp/sim/import_urdf.py +579 -0
- warp/sim/import_usd.py +894 -0
- warp/sim/inertia.py +324 -0
- warp/sim/integrator.py +242 -0
- warp/sim/integrator_euler.py +1997 -0
- warp/sim/integrator_featherstone.py +2101 -0
- warp/sim/integrator_vbd.py +2048 -0
- warp/sim/integrator_xpbd.py +3292 -0
- warp/sim/model.py +4791 -0
- warp/sim/particles.py +121 -0
- warp/sim/render.py +427 -0
- warp/sim/utils.py +428 -0
- warp/sparse.py +2057 -0
- warp/stubs.py +3333 -0
- warp/tape.py +1203 -0
- warp/tests/__init__.py +1 -0
- warp/tests/__main__.py +4 -0
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/mlp_golden.npy +0 -0
- warp/tests/assets/pixel.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/assets/spiky.usd +0 -0
- warp/tests/assets/test_grid.nvdb +0 -0
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/assets/test_int32_grid.nvdb +0 -0
- warp/tests/assets/test_vec_grid.nvdb +0 -0
- warp/tests/assets/torus.nvdb +0 -0
- warp/tests/assets/torus.usda +105 -0
- warp/tests/aux_test_class_kernel.py +34 -0
- warp/tests/aux_test_compile_consts_dummy.py +18 -0
- warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
- warp/tests/aux_test_dependent.py +29 -0
- warp/tests/aux_test_grad_customs.py +29 -0
- warp/tests/aux_test_instancing_gc.py +26 -0
- warp/tests/aux_test_module_unload.py +23 -0
- warp/tests/aux_test_name_clash1.py +40 -0
- warp/tests/aux_test_name_clash2.py +40 -0
- warp/tests/aux_test_reference.py +9 -0
- warp/tests/aux_test_reference_reference.py +8 -0
- warp/tests/aux_test_square.py +16 -0
- warp/tests/aux_test_unresolved_func.py +22 -0
- warp/tests/aux_test_unresolved_symbol.py +22 -0
- warp/tests/cuda/__init__.py +0 -0
- warp/tests/cuda/test_async.py +676 -0
- warp/tests/cuda/test_ipc.py +124 -0
- warp/tests/cuda/test_mempool.py +233 -0
- warp/tests/cuda/test_multigpu.py +169 -0
- warp/tests/cuda/test_peer.py +139 -0
- warp/tests/cuda/test_pinned.py +84 -0
- warp/tests/cuda/test_streams.py +634 -0
- warp/tests/geometry/__init__.py +0 -0
- warp/tests/geometry/test_bvh.py +200 -0
- warp/tests/geometry/test_hash_grid.py +221 -0
- warp/tests/geometry/test_marching_cubes.py +74 -0
- warp/tests/geometry/test_mesh.py +316 -0
- warp/tests/geometry/test_mesh_query_aabb.py +399 -0
- warp/tests/geometry/test_mesh_query_point.py +932 -0
- warp/tests/geometry/test_mesh_query_ray.py +311 -0
- warp/tests/geometry/test_volume.py +1103 -0
- warp/tests/geometry/test_volume_write.py +346 -0
- warp/tests/interop/__init__.py +0 -0
- warp/tests/interop/test_dlpack.py +729 -0
- warp/tests/interop/test_jax.py +371 -0
- warp/tests/interop/test_paddle.py +800 -0
- warp/tests/interop/test_torch.py +1001 -0
- warp/tests/run_coverage_serial.py +39 -0
- warp/tests/sim/__init__.py +0 -0
- warp/tests/sim/disabled_kinematics.py +244 -0
- warp/tests/sim/flaky_test_sim_grad.py +290 -0
- warp/tests/sim/test_collision.py +604 -0
- warp/tests/sim/test_coloring.py +258 -0
- warp/tests/sim/test_model.py +224 -0
- warp/tests/sim/test_sim_grad_bounce_linear.py +212 -0
- warp/tests/sim/test_sim_kinematics.py +98 -0
- warp/tests/sim/test_vbd.py +597 -0
- warp/tests/test_adam.py +163 -0
- warp/tests/test_arithmetic.py +1096 -0
- warp/tests/test_array.py +2972 -0
- warp/tests/test_array_reduce.py +156 -0
- warp/tests/test_assert.py +250 -0
- warp/tests/test_atomic.py +153 -0
- warp/tests/test_bool.py +220 -0
- warp/tests/test_builtins_resolution.py +1298 -0
- warp/tests/test_closest_point_edge_edge.py +327 -0
- warp/tests/test_codegen.py +810 -0
- warp/tests/test_codegen_instancing.py +1495 -0
- warp/tests/test_compile_consts.py +215 -0
- warp/tests/test_conditional.py +252 -0
- warp/tests/test_context.py +42 -0
- warp/tests/test_copy.py +238 -0
- warp/tests/test_ctypes.py +638 -0
- warp/tests/test_dense.py +73 -0
- warp/tests/test_devices.py +97 -0
- warp/tests/test_examples.py +482 -0
- warp/tests/test_fabricarray.py +996 -0
- warp/tests/test_fast_math.py +74 -0
- warp/tests/test_fem.py +2003 -0
- warp/tests/test_fp16.py +136 -0
- warp/tests/test_func.py +454 -0
- warp/tests/test_future_annotations.py +98 -0
- warp/tests/test_generics.py +656 -0
- warp/tests/test_grad.py +893 -0
- warp/tests/test_grad_customs.py +339 -0
- warp/tests/test_grad_debug.py +341 -0
- warp/tests/test_implicit_init.py +411 -0
- warp/tests/test_import.py +45 -0
- warp/tests/test_indexedarray.py +1140 -0
- warp/tests/test_intersect.py +73 -0
- warp/tests/test_iter.py +76 -0
- warp/tests/test_large.py +177 -0
- warp/tests/test_launch.py +411 -0
- warp/tests/test_lerp.py +151 -0
- warp/tests/test_linear_solvers.py +193 -0
- warp/tests/test_lvalue.py +427 -0
- warp/tests/test_mat.py +2089 -0
- warp/tests/test_mat_lite.py +122 -0
- warp/tests/test_mat_scalar_ops.py +2913 -0
- warp/tests/test_math.py +178 -0
- warp/tests/test_mlp.py +282 -0
- warp/tests/test_module_hashing.py +258 -0
- warp/tests/test_modules_lite.py +44 -0
- warp/tests/test_noise.py +252 -0
- warp/tests/test_operators.py +299 -0
- warp/tests/test_options.py +129 -0
- warp/tests/test_overwrite.py +551 -0
- warp/tests/test_print.py +339 -0
- warp/tests/test_quat.py +2315 -0
- warp/tests/test_rand.py +339 -0
- warp/tests/test_reload.py +302 -0
- warp/tests/test_rounding.py +185 -0
- warp/tests/test_runlength_encode.py +196 -0
- warp/tests/test_scalar_ops.py +105 -0
- warp/tests/test_smoothstep.py +108 -0
- warp/tests/test_snippet.py +318 -0
- warp/tests/test_sparse.py +582 -0
- warp/tests/test_spatial.py +2229 -0
- warp/tests/test_special_values.py +361 -0
- warp/tests/test_static.py +592 -0
- warp/tests/test_struct.py +734 -0
- warp/tests/test_tape.py +204 -0
- warp/tests/test_transient_module.py +93 -0
- warp/tests/test_triangle_closest_point.py +145 -0
- warp/tests/test_types.py +562 -0
- warp/tests/test_utils.py +588 -0
- warp/tests/test_vec.py +1487 -0
- warp/tests/test_vec_lite.py +80 -0
- warp/tests/test_vec_scalar_ops.py +2327 -0
- warp/tests/test_verify_fp.py +100 -0
- warp/tests/tile/__init__.py +0 -0
- warp/tests/tile/test_tile.py +780 -0
- warp/tests/tile/test_tile_load.py +407 -0
- warp/tests/tile/test_tile_mathdx.py +208 -0
- warp/tests/tile/test_tile_mlp.py +402 -0
- warp/tests/tile/test_tile_reduce.py +447 -0
- warp/tests/tile/test_tile_shared_memory.py +247 -0
- warp/tests/tile/test_tile_view.py +173 -0
- warp/tests/unittest_serial.py +47 -0
- warp/tests/unittest_suites.py +427 -0
- warp/tests/unittest_utils.py +468 -0
- warp/tests/walkthrough_debug.py +93 -0
- warp/thirdparty/__init__.py +0 -0
- warp/thirdparty/appdirs.py +598 -0
- warp/thirdparty/dlpack.py +145 -0
- warp/thirdparty/unittest_parallel.py +570 -0
- warp/torch.py +391 -0
- warp/types.py +5230 -0
- warp/utils.py +1137 -0
- warp_lang-1.7.0.dist-info/METADATA +516 -0
- warp_lang-1.7.0.dist-info/RECORD +429 -0
- warp_lang-1.7.0.dist-info/WHEEL +5 -0
- warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
- warp_lang-1.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
// Copyright Contributors to the OpenVDB Project
|
|
2
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
3
|
+
|
|
4
|
+
/*!
|
|
5
|
+
@file nanovdb/HostBuffer.h
|
|
6
|
+
|
|
7
|
+
@date April 20, 2021
|
|
8
|
+
|
|
9
|
+
@brief HostBuffer - a buffer that contains a shared or private bump
|
|
10
|
+
pool to either externally or internally managed host memory.
|
|
11
|
+
|
|
12
|
+
@details This HostBuffer can be used in multiple ways, most of which are
|
|
13
|
+
demonstrated in the examples below. Memory in the pool can
|
|
14
|
+
be managed or unmanged (e.g. internal or external) and can
|
|
15
|
+
be shared between multiple buffers or belong to a single buffer.
|
|
16
|
+
|
|
17
|
+
Example that uses HostBuffer::create inside io::readGrids to create a
|
|
18
|
+
full self-managed buffer, i.e. not shared and without padding, per grid in the file.
|
|
19
|
+
@code
|
|
20
|
+
auto handles = nanovdb::io::readGrids("file.nvdb");
|
|
21
|
+
@endcode
|
|
22
|
+
|
|
23
|
+
Example that uses HostBuffer::createFull. Assuming you have a raw pointer
|
|
24
|
+
to a NanoVDB grid of unknown type, this examples shows how to create its
|
|
25
|
+
GridHandle which can be used to enquire about the grid type and meta data.
|
|
26
|
+
@code
|
|
27
|
+
void *data;// pointer to a NanoVDB grid of unknown type
|
|
28
|
+
uint64_t size;// byte size of NanoVDB grid of unknown type
|
|
29
|
+
auto buffer = nanovdb::HostBuffer::createFull(size, data);
|
|
30
|
+
nanovdb::GridHandle<> gridHandle(std::move(buffer));
|
|
31
|
+
@endcode
|
|
32
|
+
|
|
33
|
+
Example that uses HostBuffer::createPool for internally managed host memory.
|
|
34
|
+
Suppose you want to read multiple grids in multiple files, but reuse the same
|
|
35
|
+
fixed sized memory buffer to both avoid memory fragmentation as well as
|
|
36
|
+
exceeding the fixed memory ceiling!
|
|
37
|
+
@code
|
|
38
|
+
auto pool = nanovdb::HostBuffer::createPool(1 << 30);// 1 GB memory pool
|
|
39
|
+
std::vector<std::string>> frames;// vector of grid names
|
|
40
|
+
for (int i=0; i<frames.size(); ++i) {
|
|
41
|
+
auto handles = nanovdb::io::readGrids(frames[i], 0, pool);// throws if grids in file exceed 1 GB
|
|
42
|
+
...
|
|
43
|
+
pool.reset();// clears all handles and resets the memory pool for reuse
|
|
44
|
+
}
|
|
45
|
+
@endcode
|
|
46
|
+
|
|
47
|
+
Example that uses HostBuffer::createPool for externally managed host memory.
|
|
48
|
+
Note that in this example @c handles are allowed to outlive @c pool since
|
|
49
|
+
they internally store a shared pointer to the memory pool. However @c data
|
|
50
|
+
MUST outlive @c handles since the pool does not own its memory in this example.
|
|
51
|
+
@code
|
|
52
|
+
const size_t poolSize = 1 << 30;// 1 GB
|
|
53
|
+
void *data = std::malloc(size + NANOVDB_DATA_ALIGNMENT);// 1 GB pool with padding
|
|
54
|
+
void *buffer = nanovdb::alignPtr(data);// 32B aligned buffer
|
|
55
|
+
//void *buffer = std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, poolSize);// in C++17
|
|
56
|
+
auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
|
|
57
|
+
auto handles1 = nanovdb::io::readGrids("file1.nvdb", 0, pool);
|
|
58
|
+
auto handles2 = nanovdb::io::readGrids("file2.nvdb", 0, pool);
|
|
59
|
+
....
|
|
60
|
+
std::free(data);
|
|
61
|
+
//std::free(buffer);
|
|
62
|
+
@endcode
|
|
63
|
+
|
|
64
|
+
Example that uses HostBuffer::createPool for externally managed host memory.
|
|
65
|
+
Note that in this example @c handles are allowed to outlive @c pool since
|
|
66
|
+
they internally store a shared pointer to the memory pool. However @c array
|
|
67
|
+
MUST outlive @c handles since the pool does not own its memory in this example.
|
|
68
|
+
@code
|
|
69
|
+
const size_t poolSize = 1 << 30;// 1 GB
|
|
70
|
+
std::unique_ptr<char[]> array(new char[size + NANOVDB_DATA_ALIGNMENT]);// scoped pool of 1 GB with padding
|
|
71
|
+
void *buffer = nanovdb::alignPtr(array.get());// 32B aligned buffer
|
|
72
|
+
auto pool = nanovdb::HostBuffer::createPool(poolSize, buffer);
|
|
73
|
+
auto handles = nanovdb::io::readGrids("file.nvdb", 0, pool);
|
|
74
|
+
@endcode
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
#ifndef NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
|
|
78
|
+
#define NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
|
|
79
|
+
|
|
80
|
+
#include <nanovdb/NanoVDB.h>// for NANOVDB_DATA_ALIGNMENT;
|
|
81
|
+
#include <stdint.h> // for types like int32_t etc
|
|
82
|
+
#include <cstdio> // for fprintf
|
|
83
|
+
#include <cstdlib> // for std::malloc/std::realloc/std::free
|
|
84
|
+
#include <memory>// for std::make_shared
|
|
85
|
+
#include <mutex>// for std::mutex
|
|
86
|
+
#include <unordered_set>// for std::unordered_set
|
|
87
|
+
#include <cassert>// for assert
|
|
88
|
+
#include <sstream>// for std::stringstream
|
|
89
|
+
#include <cstring>// for memcpy
|
|
90
|
+
|
|
91
|
+
#define checkPtr(ptr, msg) \
|
|
92
|
+
{ \
|
|
93
|
+
ptrAssert((ptr), (msg), __FILE__, __LINE__); \
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
namespace nanovdb {
|
|
97
|
+
|
|
98
|
+
template<typename BufferT>
|
|
99
|
+
struct BufferTraits
|
|
100
|
+
{
|
|
101
|
+
static constexpr bool hasDeviceDual = false;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// ----------------------------> HostBuffer <--------------------------------------
|
|
105
|
+
|
|
106
|
+
/// @brief This is a buffer that contains a shared or private pool
|
|
107
|
+
/// to either externally or internally managed host memory.
|
|
108
|
+
///
|
|
109
|
+
/// @note Terminology:
|
|
110
|
+
/// Pool: 0 = buffer.size() < buffer.poolSize()
|
|
111
|
+
/// Buffer: 0 < buffer.size() < buffer.poolSize()
|
|
112
|
+
/// Full: 0 < buffer.size() = buffer.poolSize()
|
|
113
|
+
/// Empty: 0 = buffer.size() = buffer.poolSize()
|
|
114
|
+
class HostBuffer
|
|
115
|
+
{
|
|
116
|
+
struct Pool;// forward declaration of private pool struct
|
|
117
|
+
std::shared_ptr<Pool> mPool;
|
|
118
|
+
uint64_t mSize; // total number of bytes for the NanoVDB grid.
|
|
119
|
+
void* mData; // raw buffer for the NanoVDB grid.
|
|
120
|
+
|
|
121
|
+
#if defined(DEBUG) || defined(_DEBUG)
|
|
122
|
+
static inline void ptrAssert(void* ptr, const char* msg, const char* file, int line, bool abort = true)
|
|
123
|
+
{
|
|
124
|
+
if (ptr == nullptr) {
|
|
125
|
+
fprintf(stderr, "NULL pointer error: %s %s %d\n", msg, file, line);
|
|
126
|
+
if (abort)
|
|
127
|
+
exit(1);
|
|
128
|
+
}
|
|
129
|
+
if (uint64_t(ptr) % NANOVDB_DATA_ALIGNMENT) {
|
|
130
|
+
fprintf(stderr, "Alignment pointer error: %s %s %d\n", msg, file, line);
|
|
131
|
+
if (abort)
|
|
132
|
+
exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
#else
|
|
136
|
+
static inline void ptrAssert(void*, const char*, const char*, int, bool = true)
|
|
137
|
+
{
|
|
138
|
+
}
|
|
139
|
+
#endif
|
|
140
|
+
|
|
141
|
+
public:
|
|
142
|
+
/// @brief Return a full buffer or an empty buffer
|
|
143
|
+
HostBuffer(uint64_t bufferSize = 0);
|
|
144
|
+
|
|
145
|
+
/// @brief Move copy-constructor
|
|
146
|
+
HostBuffer(HostBuffer&& other);
|
|
147
|
+
|
|
148
|
+
/// @brief Custom descructor
|
|
149
|
+
~HostBuffer() { this->clear(); }
|
|
150
|
+
|
|
151
|
+
/// @brief Move copy assignment operation
|
|
152
|
+
HostBuffer& operator=(HostBuffer&& other);
|
|
153
|
+
|
|
154
|
+
/// @brief Disallow copy-construction
|
|
155
|
+
HostBuffer(const HostBuffer&) = delete;
|
|
156
|
+
|
|
157
|
+
/// @brief Disallow copy assignment operation
|
|
158
|
+
HostBuffer& operator=(const HostBuffer&) = delete;
|
|
159
|
+
|
|
160
|
+
/// @brief Return a pool buffer which satisfies: buffer.size == 0,
|
|
161
|
+
/// buffer.poolSize() == poolSize, and buffer.data() == nullptr.
|
|
162
|
+
/// If data==nullptr, memory for the pool will be allocated.
|
|
163
|
+
///
|
|
164
|
+
/// @throw If poolSize is zero.
|
|
165
|
+
static HostBuffer createPool(uint64_t poolSize, void *data = nullptr);
|
|
166
|
+
|
|
167
|
+
/// @brief Return a full buffer which satisfies: buffer.size == bufferSize,
|
|
168
|
+
/// buffer.poolSize() == bufferSize, and buffer.data() == data.
|
|
169
|
+
/// If data==nullptr, memory for the pool will be allocated.
|
|
170
|
+
///
|
|
171
|
+
/// @throw If bufferSize is zero.
|
|
172
|
+
static HostBuffer createFull(uint64_t bufferSize, void *data = nullptr);
|
|
173
|
+
|
|
174
|
+
/// @brief Return a buffer with @c bufferSize bytes managed by
|
|
175
|
+
/// the specified memory @c pool. If none is provided, i.e.
|
|
176
|
+
/// @c pool == nullptr or @c pool->poolSize() == 0, one is
|
|
177
|
+
/// created with size @c bufferSize, i.e. a full buffer is returned.
|
|
178
|
+
///
|
|
179
|
+
/// @throw If the specified @c pool has insufficient memory for
|
|
180
|
+
/// the requested buffer size.
|
|
181
|
+
static HostBuffer create(uint64_t bufferSize, const HostBuffer* pool = nullptr);
|
|
182
|
+
|
|
183
|
+
/// @brief Initialize as a full buffer with the specified size. If data is NULL
|
|
184
|
+
/// the memory is internally allocated.
|
|
185
|
+
void init(uint64_t bufferSize, void *data = nullptr);
|
|
186
|
+
|
|
187
|
+
//@{
|
|
188
|
+
/// @brief Retuns a pointer to the raw memory buffer managed by this allocator.
|
|
189
|
+
///
|
|
190
|
+
/// @warning Note that the pointer can be NULL if the allocator was not initialized!
|
|
191
|
+
const void* data() const { return mData; }
|
|
192
|
+
void* data() { return mData; }
|
|
193
|
+
//@}
|
|
194
|
+
|
|
195
|
+
//@{
|
|
196
|
+
/// @brief Returns the size in bytes associated with this buffer.
|
|
197
|
+
uint64_t bufferSize() const { return mSize; }
|
|
198
|
+
uint64_t size() const { return this->bufferSize(); }
|
|
199
|
+
//@}
|
|
200
|
+
|
|
201
|
+
/// @brief Returns the size in bytes of the memory pool shared with this instance.
|
|
202
|
+
uint64_t poolSize() const;
|
|
203
|
+
|
|
204
|
+
/// @brief Return true if memory is managed (using std::malloc and std:free) by the
|
|
205
|
+
/// shared pool in this buffer. Else memory is assumed to be managed externally.
|
|
206
|
+
bool isManaged() const;
|
|
207
|
+
|
|
208
|
+
//@{
|
|
209
|
+
/// @brief Returns true if this buffer has no memory associated with it
|
|
210
|
+
bool isEmpty() const { return !mPool || mSize == 0 || mData == nullptr; }
|
|
211
|
+
bool empty() const { return this->isEmpty(); }
|
|
212
|
+
//@}
|
|
213
|
+
|
|
214
|
+
/// @brief Return true if this is a pool, i.e. an empty buffer with a nonempty
|
|
215
|
+
/// internal pool, i.e. this->size() == 0 and this->poolSize() != 0
|
|
216
|
+
bool isPool() const { return mSize == 0 && this->poolSize() > 0; }
|
|
217
|
+
|
|
218
|
+
/// @brief Return true if the pool exists, is nonempty but has no more available memory
|
|
219
|
+
bool isFull() const;
|
|
220
|
+
|
|
221
|
+
/// @brief Clear this buffer so it is empty.
|
|
222
|
+
void clear();
|
|
223
|
+
|
|
224
|
+
/// @brief Clears all existing buffers that are registered against the memory pool
|
|
225
|
+
/// and resets the pool so it can be reused to create new buffers.
|
|
226
|
+
///
|
|
227
|
+
/// @throw If this instance is not empty or contains no pool.
|
|
228
|
+
///
|
|
229
|
+
/// @warning This method is not thread-safe!
|
|
230
|
+
void reset();
|
|
231
|
+
|
|
232
|
+
/// @brief Total number of bytes from the pool currently in use by buffers
|
|
233
|
+
uint64_t poolUsage() const;
|
|
234
|
+
|
|
235
|
+
/// @brief resize the pool size. It will attempt to resize the existing
|
|
236
|
+
/// memory block, but if that fails a deep copy is performed.
|
|
237
|
+
/// If @c data is not NULL it will be used as new externally
|
|
238
|
+
/// managed memory for the pool. All registered buffers are
|
|
239
|
+
/// updated so GridHandle::grid might return a new address (if
|
|
240
|
+
/// deep copy was performed).
|
|
241
|
+
///
|
|
242
|
+
/// @note This method can be use to resize the memory pool and even
|
|
243
|
+
/// change it from internally to externally managed memory or vice versa.
|
|
244
|
+
///
|
|
245
|
+
/// @throw if @c poolSize is less than this->poolUsage() the used memory
|
|
246
|
+
/// or allocations fail.
|
|
247
|
+
void resizePool(uint64_t poolSize, void *data = nullptr);
|
|
248
|
+
|
|
249
|
+
}; // HostBuffer class
|
|
250
|
+
|
|
251
|
+
// --------------------------> Implementation of HostBuffer::Pool <------------------------------------
|
|
252
|
+
|
|
253
|
+
// This is private struct of HostBuffer so you can safely ignore the API
|
|
254
|
+
struct HostBuffer::Pool
|
|
255
|
+
{
|
|
256
|
+
using HashTableT = std::unordered_set<HostBuffer*>;
|
|
257
|
+
std::mutex mMutex; // mutex for updating mRegister and mFree
|
|
258
|
+
HashTableT mRegister;
|
|
259
|
+
void *mData, *mFree;
|
|
260
|
+
uint64_t mSize, mPadding;
|
|
261
|
+
bool mManaged;
|
|
262
|
+
|
|
263
|
+
/// @brief External memory ctor
|
|
264
|
+
Pool(uint64_t size = 0, void* data = nullptr)
|
|
265
|
+
: mData(data)
|
|
266
|
+
, mFree(mData)
|
|
267
|
+
, mSize(size)
|
|
268
|
+
, mPadding(0)
|
|
269
|
+
, mManaged(data == nullptr)
|
|
270
|
+
{
|
|
271
|
+
if (mManaged) {
|
|
272
|
+
mData = Pool::alloc(mSize);
|
|
273
|
+
if (mData == nullptr) throw std::runtime_error("Pool::Pool malloc failed");
|
|
274
|
+
}
|
|
275
|
+
mPadding = alignmentPadding(mData);
|
|
276
|
+
if (!mManaged && mPadding != 0) {
|
|
277
|
+
throw std::runtime_error("Pool::Pool: external memory buffer is not aligned to " +
|
|
278
|
+
std::to_string(NANOVDB_DATA_ALIGNMENT) +
|
|
279
|
+
" bytes.\nHint: use nanovdb::alignPtr or std::aligned_alloc (C++17 only)");
|
|
280
|
+
}
|
|
281
|
+
mFree = util::PtrAdd(mData, mPadding);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/// @brief Custom destructor
|
|
285
|
+
~Pool()
|
|
286
|
+
{
|
|
287
|
+
assert(mRegister.empty());
|
|
288
|
+
if (mManaged) std::free(mData);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/// @brief Disallow copy-construction
|
|
292
|
+
Pool(const Pool&) = delete;
|
|
293
|
+
|
|
294
|
+
/// @brief Disallow move-construction
|
|
295
|
+
Pool(const Pool&&) = delete;
|
|
296
|
+
|
|
297
|
+
/// @brief Disallow copy assignment operation
|
|
298
|
+
Pool& operator=(const Pool&) = delete;
|
|
299
|
+
|
|
300
|
+
/// @brief Disallow move assignment operation
|
|
301
|
+
Pool& operator=(const Pool&&) = delete;
|
|
302
|
+
|
|
303
|
+
/// @brief Return the total number of bytes used from this Pool by buffers
|
|
304
|
+
uint64_t usage() const { return util::PtrDiff(mFree, mData) - mPadding; }
|
|
305
|
+
|
|
306
|
+
/// @brief Allocate a buffer of the specified size and add it to the register
|
|
307
|
+
void add(HostBuffer* buffer, uint64_t size)
|
|
308
|
+
{
|
|
309
|
+
void *alignedFree = util::PtrAdd(mFree, alignmentPadding(mFree));
|
|
310
|
+
|
|
311
|
+
if (util::PtrAdd(alignedFree, size) > util::PtrAdd(mData, mPadding + mSize)) {
|
|
312
|
+
std::stringstream ss;
|
|
313
|
+
ss << "HostBuffer::Pool: insufficient memory\n"
|
|
314
|
+
<< "\tA buffer requested " << size << " bytes with " << NANOVDB_DATA_ALIGNMENT
|
|
315
|
+
<< "-bytes alignment from a pool with "
|
|
316
|
+
<< mSize << " bytes of which\n\t" << (util::PtrDiff(alignedFree, mData) - mPadding)
|
|
317
|
+
<< " bytes are used by " << mRegister.size() << " other buffer(s). "
|
|
318
|
+
<< "Pool is " << (mManaged ? "internally" : "externally") << " managed.\n";
|
|
319
|
+
//std::cerr << ss.str();
|
|
320
|
+
throw std::runtime_error(ss.str());
|
|
321
|
+
}
|
|
322
|
+
buffer->mSize = size;
|
|
323
|
+
const std::lock_guard<std::mutex> lock(mMutex);
|
|
324
|
+
mRegister.insert(buffer);
|
|
325
|
+
buffer->mData = alignedFree;
|
|
326
|
+
mFree = util::PtrAdd(alignedFree, size);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/// @brief Remove the specified buffer from the register
|
|
330
|
+
void remove(HostBuffer *buffer)
|
|
331
|
+
{
|
|
332
|
+
const std::lock_guard<std::mutex> lock(mMutex);
|
|
333
|
+
mRegister.erase(buffer);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/// @brief Replaces buffer1 with buffer2 in the register
|
|
337
|
+
void replace(HostBuffer *buffer1, HostBuffer *buffer2)
|
|
338
|
+
{
|
|
339
|
+
const std::lock_guard<std::mutex> lock(mMutex);
|
|
340
|
+
mRegister.erase( buffer1);
|
|
341
|
+
mRegister.insert(buffer2);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/// @brief Reset the register and all its buffers
|
|
345
|
+
void reset()
|
|
346
|
+
{
|
|
347
|
+
for (HostBuffer *buffer : mRegister) {
|
|
348
|
+
buffer->mPool.reset();
|
|
349
|
+
buffer->mSize = 0;
|
|
350
|
+
buffer->mData = nullptr;
|
|
351
|
+
}
|
|
352
|
+
mRegister.clear();
|
|
353
|
+
mFree = util::PtrAdd(mData, mPadding);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/// @brief Resize this Pool and update registered buffers as needed. If data is no NULL
|
|
357
|
+
/// it is used as externally managed memory.
|
|
358
|
+
void resize(uint64_t size, void *data = nullptr)
|
|
359
|
+
{
|
|
360
|
+
const uint64_t memUsage = this->usage();
|
|
361
|
+
|
|
362
|
+
const bool managed = (data == nullptr);
|
|
363
|
+
|
|
364
|
+
if (!managed && alignmentPadding(data) != 0) {
|
|
365
|
+
throw std::runtime_error("Pool::resize: external memory buffer is not aligned to " +
|
|
366
|
+
std::to_string(NANOVDB_DATA_ALIGNMENT) + " bytes");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (memUsage > size) {
|
|
370
|
+
throw std::runtime_error("Pool::resize: insufficient memory");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
uint64_t padding = 0;
|
|
374
|
+
if (mManaged && managed && size != mSize) { // managed -> managed
|
|
375
|
+
padding = mPadding;
|
|
376
|
+
data = Pool::realloc(mData, memUsage, size, padding); // performs both copy and free of mData
|
|
377
|
+
} else if (!mManaged && managed) { // un-managed -> managed
|
|
378
|
+
data = Pool::alloc(size);
|
|
379
|
+
padding = alignmentPadding(data);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (data == nullptr) {
|
|
383
|
+
throw std::runtime_error("Pool::resize: allocation failed");
|
|
384
|
+
} else if (data != mData) {
|
|
385
|
+
void* paddedData = util::PtrAdd(data, padding);
|
|
386
|
+
|
|
387
|
+
if (!(mManaged && managed)) { // no need to copy if managed -> managed
|
|
388
|
+
memcpy(paddedData, util::PtrAdd(mData, mPadding), memUsage);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
for (HostBuffer* buffer : mRegister) { // update registered buffers
|
|
392
|
+
//buffer->mData = paddedData + ptrdiff_t(buffer->mData - (mData + mPadding));
|
|
393
|
+
buffer->mData = util::PtrAdd(paddedData, util::PtrDiff(buffer->mData, util::PtrAdd(mData, mPadding)));
|
|
394
|
+
}
|
|
395
|
+
mFree = util::PtrAdd(paddedData, memUsage); // update the free pointer
|
|
396
|
+
if (mManaged && !managed) {// only free if managed -> un-managed
|
|
397
|
+
std::free(mData);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
mData = data;
|
|
401
|
+
mPadding = padding;
|
|
402
|
+
}
|
|
403
|
+
mSize = size;
|
|
404
|
+
mManaged = managed;
|
|
405
|
+
}
|
|
406
|
+
/// @brief Return true is all the memory in this pool is in use.
|
|
407
|
+
bool isFull() const
|
|
408
|
+
{
|
|
409
|
+
assert(mFree <= util::PtrAdd(mData, mPadding + mSize));
|
|
410
|
+
return mSize > 0 ? mFree == util::PtrAdd(mData, mPadding + mSize) : false;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
private:
|
|
414
|
+
|
|
415
|
+
static void* alloc(uint64_t size)
|
|
416
|
+
{
|
|
417
|
+
//#if (__cplusplus >= 201703L)
|
|
418
|
+
// return std::aligned_alloc(NANOVDB_DATA_ALIGNMENT, size);//C++17 or newer
|
|
419
|
+
//#else
|
|
420
|
+
// make sure we alloc enough space to align the result
|
|
421
|
+
return std::malloc(size + NANOVDB_DATA_ALIGNMENT);
|
|
422
|
+
//#endif
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
static void* realloc(void* const origData,
|
|
426
|
+
uint64_t origSize,
|
|
427
|
+
uint64_t desiredSize,
|
|
428
|
+
uint64_t& padding)
|
|
429
|
+
{
|
|
430
|
+
// make sure we alloc enough space to align the result
|
|
431
|
+
void* data = std::realloc(origData, desiredSize + NANOVDB_DATA_ALIGNMENT);
|
|
432
|
+
|
|
433
|
+
if (data != nullptr && data != origData) {
|
|
434
|
+
uint64_t newPadding = alignmentPadding(data);
|
|
435
|
+
// Number of padding bytes may have changed -- move data if that's the case
|
|
436
|
+
if (newPadding != padding) {
|
|
437
|
+
// Realloc should not happen when shrinking down buffer, but let's be safe
|
|
438
|
+
std::memmove(util::PtrAdd(data, newPadding),
|
|
439
|
+
util::PtrAdd(data, padding),
|
|
440
|
+
math::Min(origSize, desiredSize));
|
|
441
|
+
padding = newPadding;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return data;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
};// struct HostBuffer::Pool
|
|
449
|
+
|
|
450
|
+
// --------------------------> Implementation of HostBuffer <------------------------------------
|
|
451
|
+
|
|
452
|
+
inline HostBuffer::HostBuffer(uint64_t size) : mPool(nullptr), mSize(size), mData(nullptr)
|
|
453
|
+
{
|
|
454
|
+
if (size>0) {
|
|
455
|
+
mPool = std::make_shared<Pool>(size);
|
|
456
|
+
mData = mPool->mFree;
|
|
457
|
+
mPool->mRegister.insert(this);
|
|
458
|
+
mPool->mFree = util::PtrAdd(mPool->mFree, size);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
inline HostBuffer::HostBuffer(HostBuffer&& other) : mPool(other.mPool), mSize(other.mSize), mData(other.mData)
|
|
463
|
+
{
|
|
464
|
+
if (mPool && mSize != 0) {
|
|
465
|
+
mPool->replace(&other, this);
|
|
466
|
+
}
|
|
467
|
+
other.mPool.reset();
|
|
468
|
+
other.mSize = 0;
|
|
469
|
+
other.mData = nullptr;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
inline void HostBuffer::init(uint64_t bufferSize, void *data)
|
|
473
|
+
{
|
|
474
|
+
if (bufferSize == 0) {
|
|
475
|
+
throw std::runtime_error("HostBuffer: invalid buffer size");
|
|
476
|
+
}
|
|
477
|
+
if (mPool) {
|
|
478
|
+
mPool.reset();
|
|
479
|
+
}
|
|
480
|
+
if (!mPool || mPool->mSize != bufferSize) {
|
|
481
|
+
mPool = std::make_shared<Pool>(bufferSize, data);
|
|
482
|
+
}
|
|
483
|
+
mPool->add(this, bufferSize);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
inline HostBuffer& HostBuffer::operator=(HostBuffer&& other)
|
|
487
|
+
{
|
|
488
|
+
if (mPool) {
|
|
489
|
+
mPool->remove(this);
|
|
490
|
+
}
|
|
491
|
+
mPool = other.mPool;
|
|
492
|
+
mSize = other.mSize;
|
|
493
|
+
mData = other.mData;
|
|
494
|
+
if (mPool && mSize != 0) {
|
|
495
|
+
mPool->replace(&other, this);
|
|
496
|
+
}
|
|
497
|
+
other.mPool.reset();
|
|
498
|
+
other.mSize = 0;
|
|
499
|
+
other.mData = nullptr;
|
|
500
|
+
return *this;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
inline uint64_t HostBuffer::poolSize() const
|
|
504
|
+
{
|
|
505
|
+
return mPool ? mPool->mSize : 0u;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
inline uint64_t HostBuffer::poolUsage() const
|
|
509
|
+
{
|
|
510
|
+
return mPool ? mPool->usage(): 0u;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
inline bool HostBuffer::isManaged() const
|
|
514
|
+
{
|
|
515
|
+
return mPool ? mPool->mManaged : false;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
inline bool HostBuffer::isFull() const
|
|
519
|
+
{
|
|
520
|
+
return mPool ? mPool->isFull() : false;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
inline HostBuffer HostBuffer::createPool(uint64_t poolSize, void *data)
|
|
524
|
+
{
|
|
525
|
+
if (poolSize == 0) {
|
|
526
|
+
throw std::runtime_error("HostBuffer: invalid pool size");
|
|
527
|
+
}
|
|
528
|
+
HostBuffer buffer;
|
|
529
|
+
buffer.mPool = std::make_shared<Pool>(poolSize, data);
|
|
530
|
+
// note the buffer is NOT registered by its pool since it is not using its memory
|
|
531
|
+
buffer.mSize = 0;
|
|
532
|
+
buffer.mData = nullptr;
|
|
533
|
+
return buffer;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
inline HostBuffer HostBuffer::createFull(uint64_t bufferSize, void *data)
|
|
537
|
+
{
|
|
538
|
+
if (bufferSize == 0) {
|
|
539
|
+
throw std::runtime_error("HostBuffer: invalid buffer size");
|
|
540
|
+
}
|
|
541
|
+
HostBuffer buffer;
|
|
542
|
+
buffer.mPool = std::make_shared<Pool>(bufferSize, data);
|
|
543
|
+
buffer.mPool->add(&buffer, bufferSize);
|
|
544
|
+
return buffer;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
inline HostBuffer HostBuffer::create(uint64_t bufferSize, const HostBuffer* pool)
|
|
548
|
+
{
|
|
549
|
+
HostBuffer buffer;
|
|
550
|
+
if (pool == nullptr || !pool->mPool) {
|
|
551
|
+
buffer.mPool = std::make_shared<Pool>(bufferSize);
|
|
552
|
+
} else {
|
|
553
|
+
buffer.mPool = pool->mPool;
|
|
554
|
+
}
|
|
555
|
+
buffer.mPool->add(&buffer, bufferSize);
|
|
556
|
+
return buffer;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
inline void HostBuffer::clear()
|
|
560
|
+
{
|
|
561
|
+
if (mPool) {// remove self from the buffer register in the pool
|
|
562
|
+
mPool->remove(this);
|
|
563
|
+
}
|
|
564
|
+
mPool.reset();
|
|
565
|
+
mSize = 0;
|
|
566
|
+
mData = nullptr;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
inline void HostBuffer::reset()
|
|
570
|
+
{
|
|
571
|
+
if (this->size()>0) {
|
|
572
|
+
throw std::runtime_error("HostBuffer: only empty buffers can call reset");
|
|
573
|
+
}
|
|
574
|
+
if (!mPool) {
|
|
575
|
+
throw std::runtime_error("HostBuffer: this buffer contains no pool to reset");
|
|
576
|
+
}
|
|
577
|
+
mPool->reset();
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
inline void HostBuffer::resizePool(uint64_t size, void *data)
|
|
581
|
+
{
|
|
582
|
+
if (!mPool) {
|
|
583
|
+
throw std::runtime_error("HostBuffer: this buffer contains no pool to resize");
|
|
584
|
+
}
|
|
585
|
+
mPool->resize(size, data);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
} // namespace nanovdb
|
|
589
|
+
|
|
590
|
+
#endif // end of NANOVDB_HOSTBUFFER_H_HAS_BEEN_INCLUDED
|