warp-lang 1.10.0__py3-none-macosx_11_0_arm64.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 +334 -0
- warp/__init__.pyi +5856 -0
- warp/_src/__init__.py +14 -0
- warp/_src/autograd.py +1077 -0
- warp/_src/build.py +620 -0
- warp/_src/build_dll.py +642 -0
- warp/_src/builtins.py +10555 -0
- warp/_src/codegen.py +4361 -0
- warp/_src/config.py +178 -0
- warp/_src/constants.py +59 -0
- warp/_src/context.py +8352 -0
- warp/_src/dlpack.py +464 -0
- warp/_src/fabric.py +362 -0
- warp/_src/fem/__init__.py +14 -0
- warp/_src/fem/adaptivity.py +510 -0
- warp/_src/fem/cache.py +689 -0
- warp/_src/fem/dirichlet.py +190 -0
- warp/_src/fem/domain.py +553 -0
- warp/_src/fem/field/__init__.py +131 -0
- warp/_src/fem/field/field.py +703 -0
- warp/_src/fem/field/nodal_field.py +403 -0
- warp/_src/fem/field/restriction.py +39 -0
- warp/_src/fem/field/virtual.py +1021 -0
- warp/_src/fem/geometry/__init__.py +32 -0
- warp/_src/fem/geometry/adaptive_nanogrid.py +782 -0
- warp/_src/fem/geometry/closest_point.py +99 -0
- warp/_src/fem/geometry/deformed_geometry.py +277 -0
- warp/_src/fem/geometry/element.py +854 -0
- warp/_src/fem/geometry/geometry.py +693 -0
- warp/_src/fem/geometry/grid_2d.py +478 -0
- warp/_src/fem/geometry/grid_3d.py +539 -0
- warp/_src/fem/geometry/hexmesh.py +956 -0
- warp/_src/fem/geometry/nanogrid.py +660 -0
- warp/_src/fem/geometry/partition.py +483 -0
- warp/_src/fem/geometry/quadmesh.py +597 -0
- warp/_src/fem/geometry/tetmesh.py +762 -0
- warp/_src/fem/geometry/trimesh.py +588 -0
- warp/_src/fem/integrate.py +2507 -0
- warp/_src/fem/linalg.py +385 -0
- warp/_src/fem/operator.py +398 -0
- warp/_src/fem/polynomial.py +231 -0
- warp/_src/fem/quadrature/__init__.py +17 -0
- warp/_src/fem/quadrature/pic_quadrature.py +318 -0
- warp/_src/fem/quadrature/quadrature.py +665 -0
- warp/_src/fem/space/__init__.py +248 -0
- warp/_src/fem/space/basis_function_space.py +499 -0
- warp/_src/fem/space/basis_space.py +681 -0
- warp/_src/fem/space/dof_mapper.py +253 -0
- warp/_src/fem/space/function_space.py +312 -0
- warp/_src/fem/space/grid_2d_function_space.py +179 -0
- warp/_src/fem/space/grid_3d_function_space.py +229 -0
- warp/_src/fem/space/hexmesh_function_space.py +255 -0
- warp/_src/fem/space/nanogrid_function_space.py +199 -0
- warp/_src/fem/space/partition.py +435 -0
- warp/_src/fem/space/quadmesh_function_space.py +222 -0
- warp/_src/fem/space/restriction.py +221 -0
- warp/_src/fem/space/shape/__init__.py +152 -0
- warp/_src/fem/space/shape/cube_shape_function.py +1107 -0
- warp/_src/fem/space/shape/shape_function.py +134 -0
- warp/_src/fem/space/shape/square_shape_function.py +928 -0
- warp/_src/fem/space/shape/tet_shape_function.py +829 -0
- warp/_src/fem/space/shape/triangle_shape_function.py +674 -0
- warp/_src/fem/space/tetmesh_function_space.py +270 -0
- warp/_src/fem/space/topology.py +461 -0
- warp/_src/fem/space/trimesh_function_space.py +193 -0
- warp/_src/fem/types.py +114 -0
- warp/_src/fem/utils.py +488 -0
- warp/_src/jax.py +188 -0
- warp/_src/jax_experimental/__init__.py +14 -0
- warp/_src/jax_experimental/custom_call.py +389 -0
- warp/_src/jax_experimental/ffi.py +1286 -0
- warp/_src/jax_experimental/xla_ffi.py +658 -0
- warp/_src/marching_cubes.py +710 -0
- warp/_src/math.py +416 -0
- warp/_src/optim/__init__.py +14 -0
- warp/_src/optim/adam.py +165 -0
- warp/_src/optim/linear.py +1608 -0
- warp/_src/optim/sgd.py +114 -0
- warp/_src/paddle.py +408 -0
- warp/_src/render/__init__.py +14 -0
- warp/_src/render/imgui_manager.py +291 -0
- warp/_src/render/render_opengl.py +3638 -0
- warp/_src/render/render_usd.py +939 -0
- warp/_src/render/utils.py +162 -0
- warp/_src/sparse.py +2718 -0
- warp/_src/tape.py +1208 -0
- warp/_src/thirdparty/__init__.py +0 -0
- warp/_src/thirdparty/appdirs.py +598 -0
- warp/_src/thirdparty/dlpack.py +145 -0
- warp/_src/thirdparty/unittest_parallel.py +676 -0
- warp/_src/torch.py +393 -0
- warp/_src/types.py +5888 -0
- warp/_src/utils.py +1695 -0
- warp/autograd.py +33 -0
- warp/bin/libwarp-clang.dylib +0 -0
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +29 -0
- warp/build_dll.py +24 -0
- warp/codegen.py +24 -0
- warp/constants.py +24 -0
- warp/context.py +33 -0
- warp/dlpack.py +24 -0
- warp/examples/__init__.py +24 -0
- warp/examples/assets/bear.usd +0 -0
- warp/examples/assets/bunny.usd +0 -0
- warp/examples/assets/cube.usd +0 -0
- warp/examples/assets/nonuniform.usd +0 -0
- warp/examples/assets/nvidia_logo.png +0 -0
- warp/examples/assets/pixel.jpg +0 -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/benchmarks/benchmark_tile_sort.py +155 -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 +195 -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 +290 -0
- warp/examples/core/example_sample_mesh.py +300 -0
- warp/examples/core/example_sph.py +411 -0
- warp/examples/core/example_spin_lock.py +93 -0
- warp/examples/core/example_torch.py +211 -0
- warp/examples/core/example_wave.py +269 -0
- warp/examples/core/example_work_queue.py +118 -0
- warp/examples/distributed/example_jacobi_mpi.py +506 -0
- warp/examples/fem/example_adaptive_grid.py +286 -0
- warp/examples/fem/example_apic_fluid.py +469 -0
- warp/examples/fem/example_burgers.py +261 -0
- warp/examples/fem/example_convection_diffusion.py +181 -0
- warp/examples/fem/example_convection_diffusion_dg.py +225 -0
- warp/examples/fem/example_darcy_ls_optimization.py +489 -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 +225 -0
- warp/examples/fem/example_distortion_energy.py +228 -0
- warp/examples/fem/example_elastic_shape_optimization.py +387 -0
- warp/examples/fem/example_magnetostatics.py +242 -0
- warp/examples/fem/example_mixed_elasticity.py +293 -0
- warp/examples/fem/example_navier_stokes.py +263 -0
- warp/examples/fem/example_nonconforming_contact.py +300 -0
- warp/examples/fem/example_stokes.py +213 -0
- warp/examples/fem/example_stokes_transfer.py +262 -0
- warp/examples/fem/example_streamlines.py +357 -0
- warp/examples/fem/utils.py +1047 -0
- warp/examples/interop/example_jax_callable.py +146 -0
- warp/examples/interop/example_jax_ffi_callback.py +132 -0
- warp/examples/interop/example_jax_kernel.py +232 -0
- warp/examples/optim/example_diffray.py +561 -0
- warp/examples/optim/example_fluid_checkpoint.py +497 -0
- warp/examples/tile/example_tile_block_cholesky.py +502 -0
- warp/examples/tile/example_tile_cholesky.py +88 -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_mcgp.py +191 -0
- warp/examples/tile/example_tile_mlp.py +385 -0
- warp/examples/tile/example_tile_nbody.py +199 -0
- warp/fabric.py +24 -0
- warp/fem/__init__.py +173 -0
- warp/fem/adaptivity.py +26 -0
- warp/fem/cache.py +30 -0
- warp/fem/dirichlet.py +24 -0
- warp/fem/field/__init__.py +24 -0
- warp/fem/field/field.py +26 -0
- warp/fem/geometry/__init__.py +21 -0
- warp/fem/geometry/closest_point.py +31 -0
- warp/fem/linalg.py +38 -0
- warp/fem/operator.py +32 -0
- warp/fem/polynomial.py +29 -0
- warp/fem/space/__init__.py +22 -0
- warp/fem/space/basis_space.py +24 -0
- warp/fem/space/shape/__init__.py +68 -0
- warp/fem/space/topology.py +24 -0
- warp/fem/types.py +24 -0
- warp/fem/utils.py +32 -0
- warp/jax.py +29 -0
- warp/jax_experimental/__init__.py +29 -0
- warp/jax_experimental/custom_call.py +29 -0
- warp/jax_experimental/ffi.py +39 -0
- warp/jax_experimental/xla_ffi.py +24 -0
- warp/marching_cubes.py +24 -0
- warp/math.py +37 -0
- warp/native/array.h +1687 -0
- warp/native/builtin.h +2327 -0
- warp/native/bvh.cpp +562 -0
- warp/native/bvh.cu +826 -0
- warp/native/bvh.h +555 -0
- warp/native/clang/clang.cpp +541 -0
- warp/native/coloring.cpp +622 -0
- warp/native/crt.cpp +51 -0
- warp/native/crt.h +568 -0
- warp/native/cuda_crt.h +1058 -0
- warp/native/cuda_util.cpp +677 -0
- warp/native/cuda_util.h +313 -0
- warp/native/error.cpp +77 -0
- warp/native/error.h +36 -0
- warp/native/exports.h +2023 -0
- warp/native/fabric.h +246 -0
- warp/native/hashgrid.cpp +311 -0
- warp/native/hashgrid.cu +89 -0
- warp/native/hashgrid.h +240 -0
- warp/native/initializer_array.h +41 -0
- warp/native/intersect.h +1253 -0
- warp/native/intersect_adj.h +375 -0
- warp/native/intersect_tri.h +348 -0
- warp/native/mat.h +5189 -0
- warp/native/mathdx.cpp +93 -0
- warp/native/matnn.h +221 -0
- warp/native/mesh.cpp +266 -0
- warp/native/mesh.cu +406 -0
- warp/native/mesh.h +2097 -0
- warp/native/nanovdb/GridHandle.h +533 -0
- warp/native/nanovdb/HostBuffer.h +591 -0
- warp/native/nanovdb/NanoVDB.h +6246 -0
- warp/native/nanovdb/NodeManager.h +323 -0
- warp/native/nanovdb/PNanoVDB.h +3390 -0
- warp/native/noise.h +859 -0
- warp/native/quat.h +1664 -0
- warp/native/rand.h +342 -0
- warp/native/range.h +145 -0
- warp/native/reduce.cpp +174 -0
- warp/native/reduce.cu +363 -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 +55 -0
- warp/native/scan.h +23 -0
- warp/native/solid_angle.h +466 -0
- warp/native/sort.cpp +251 -0
- warp/native/sort.cu +286 -0
- warp/native/sort.h +35 -0
- warp/native/sparse.cpp +241 -0
- warp/native/sparse.cu +435 -0
- warp/native/spatial.h +1306 -0
- warp/native/svd.h +727 -0
- warp/native/temp_buffer.h +46 -0
- warp/native/tile.h +4124 -0
- warp/native/tile_radix_sort.h +1112 -0
- warp/native/tile_reduce.h +838 -0
- warp/native/tile_scan.h +240 -0
- warp/native/tuple.h +189 -0
- warp/native/vec.h +2199 -0
- warp/native/version.h +23 -0
- warp/native/volume.cpp +501 -0
- warp/native/volume.cu +68 -0
- warp/native/volume.h +970 -0
- warp/native/volume_builder.cu +483 -0
- warp/native/volume_builder.h +52 -0
- warp/native/volume_impl.h +70 -0
- warp/native/warp.cpp +1143 -0
- warp/native/warp.cu +4604 -0
- warp/native/warp.h +358 -0
- warp/optim/__init__.py +20 -0
- warp/optim/adam.py +24 -0
- warp/optim/linear.py +35 -0
- warp/optim/sgd.py +24 -0
- warp/paddle.py +24 -0
- warp/py.typed +0 -0
- warp/render/__init__.py +22 -0
- warp/render/imgui_manager.py +29 -0
- warp/render/render_opengl.py +24 -0
- warp/render/render_usd.py +24 -0
- warp/render/utils.py +24 -0
- warp/sparse.py +51 -0
- warp/tape.py +24 -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_aot.py +7 -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_conditional_captures.py +1147 -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 +691 -0
- warp/tests/geometry/__init__.py +0 -0
- warp/tests/geometry/test_bvh.py +335 -0
- warp/tests/geometry/test_hash_grid.py +259 -0
- warp/tests/geometry/test_marching_cubes.py +294 -0
- warp/tests/geometry/test_mesh.py +318 -0
- warp/tests/geometry/test_mesh_query_aabb.py +392 -0
- warp/tests/geometry/test_mesh_query_point.py +935 -0
- warp/tests/geometry/test_mesh_query_ray.py +323 -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 +730 -0
- warp/tests/interop/test_jax.py +1673 -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/test_adam.py +162 -0
- warp/tests/test_arithmetic.py +1096 -0
- warp/tests/test_array.py +3756 -0
- warp/tests/test_array_reduce.py +156 -0
- warp/tests/test_assert.py +303 -0
- warp/tests/test_atomic.py +336 -0
- warp/tests/test_atomic_bitwise.py +209 -0
- warp/tests/test_atomic_cas.py +312 -0
- warp/tests/test_bool.py +220 -0
- warp/tests/test_builtins_resolution.py +732 -0
- warp/tests/test_closest_point_edge_edge.py +327 -0
- warp/tests/test_codegen.py +974 -0
- warp/tests/test_codegen_instancing.py +1495 -0
- warp/tests/test_compile_consts.py +215 -0
- warp/tests/test_conditional.py +298 -0
- warp/tests/test_context.py +35 -0
- warp/tests/test_copy.py +319 -0
- warp/tests/test_ctypes.py +618 -0
- warp/tests/test_dense.py +73 -0
- warp/tests/test_devices.py +127 -0
- warp/tests/test_enum.py +136 -0
- warp/tests/test_examples.py +424 -0
- warp/tests/test_fabricarray.py +998 -0
- warp/tests/test_fast_math.py +72 -0
- warp/tests/test_fem.py +2204 -0
- warp/tests/test_fixedarray.py +229 -0
- warp/tests/test_fp16.py +136 -0
- warp/tests/test_func.py +501 -0
- warp/tests/test_future_annotations.py +100 -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 +103 -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 +223 -0
- warp/tests/test_lvalue.py +427 -0
- warp/tests/test_map.py +526 -0
- warp/tests/test_mat.py +3515 -0
- warp/tests/test_mat_assign_copy.py +178 -0
- warp/tests/test_mat_constructors.py +573 -0
- warp/tests/test_mat_lite.py +122 -0
- warp/tests/test_mat_scalar_ops.py +2913 -0
- warp/tests/test_math.py +212 -0
- warp/tests/test_module_aot.py +287 -0
- warp/tests/test_module_hashing.py +258 -0
- warp/tests/test_modules_lite.py +70 -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 +408 -0
- warp/tests/test_quat.py +2653 -0
- warp/tests/test_quat_assign_copy.py +145 -0
- warp/tests/test_rand.py +339 -0
- warp/tests/test_reload.py +303 -0
- warp/tests/test_rounding.py +157 -0
- warp/tests/test_runlength_encode.py +196 -0
- warp/tests/test_scalar_ops.py +133 -0
- warp/tests/test_smoothstep.py +108 -0
- warp/tests/test_snippet.py +318 -0
- warp/tests/test_sparse.py +845 -0
- warp/tests/test_spatial.py +2859 -0
- warp/tests/test_spatial_assign_copy.py +160 -0
- warp/tests/test_special_values.py +361 -0
- warp/tests/test_static.py +640 -0
- warp/tests/test_struct.py +901 -0
- warp/tests/test_tape.py +242 -0
- warp/tests/test_transient_module.py +93 -0
- warp/tests/test_triangle_closest_point.py +192 -0
- warp/tests/test_tuple.py +361 -0
- warp/tests/test_types.py +615 -0
- warp/tests/test_utils.py +594 -0
- warp/tests/test_vec.py +1408 -0
- warp/tests/test_vec_assign_copy.py +143 -0
- warp/tests/test_vec_constructors.py +325 -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/test_version.py +75 -0
- warp/tests/tile/__init__.py +0 -0
- warp/tests/tile/test_tile.py +1519 -0
- warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
- warp/tests/tile/test_tile_cholesky.py +608 -0
- warp/tests/tile/test_tile_load.py +724 -0
- warp/tests/tile/test_tile_mathdx.py +156 -0
- warp/tests/tile/test_tile_matmul.py +179 -0
- warp/tests/tile/test_tile_mlp.py +400 -0
- warp/tests/tile/test_tile_reduce.py +950 -0
- warp/tests/tile/test_tile_shared_memory.py +376 -0
- warp/tests/tile/test_tile_sort.py +121 -0
- warp/tests/tile/test_tile_view.py +173 -0
- warp/tests/unittest_serial.py +47 -0
- warp/tests/unittest_suites.py +430 -0
- warp/tests/unittest_utils.py +469 -0
- warp/tests/walkthrough_debug.py +95 -0
- warp/torch.py +24 -0
- warp/types.py +51 -0
- warp/utils.py +31 -0
- warp_lang-1.10.0.dist-info/METADATA +459 -0
- warp_lang-1.10.0.dist-info/RECORD +468 -0
- warp_lang-1.10.0.dist-info/WHEEL +5 -0
- warp_lang-1.10.0.dist-info/licenses/LICENSE.md +176 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
- warp_lang-1.10.0.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
- warp_lang-1.10.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# Example Spin Lock
|
|
18
|
+
#
|
|
19
|
+
# Shows how to use a spin lock to synchronize access to a shared resource.
|
|
20
|
+
#
|
|
21
|
+
###########################################################################
|
|
22
|
+
|
|
23
|
+
import warp as wp
|
|
24
|
+
from warp.tests.unittest_utils import *
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@wp.func
|
|
28
|
+
def spinlock_acquire(lock: wp.array(dtype=wp.int32)):
|
|
29
|
+
# Try to acquire the lock by setting it to 1 if it's 0
|
|
30
|
+
while wp.atomic_cas(lock, 0, 0, 1) == 1:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@wp.func
|
|
35
|
+
def spinlock_release(lock: wp.array(dtype=wp.int32)):
|
|
36
|
+
# Release the lock by setting it back to 0
|
|
37
|
+
wp.atomic_exch(lock, 0, 0)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@wp.func
|
|
41
|
+
def volatile_read(ptr: wp.array(dtype=wp.int32), index: int):
|
|
42
|
+
value = wp.atomic_exch(ptr, index, 0)
|
|
43
|
+
wp.atomic_exch(ptr, index, value)
|
|
44
|
+
return value
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@wp.kernel
|
|
48
|
+
def test_spinlock_counter(
|
|
49
|
+
counter: wp.array(dtype=wp.int32), atomic_counter: wp.array(dtype=wp.int32), lock: wp.array(dtype=wp.int32)
|
|
50
|
+
):
|
|
51
|
+
# Try to acquire the lock
|
|
52
|
+
spinlock_acquire(lock)
|
|
53
|
+
|
|
54
|
+
# Critical section - increment counter
|
|
55
|
+
# counter[0] = counter[0] + 1 # This gives wrong results - counter should be marked as volatile
|
|
56
|
+
|
|
57
|
+
# Work around since warp arrays cannot be marked as volatile
|
|
58
|
+
value = volatile_read(counter, 0)
|
|
59
|
+
counter[0] = value + 1
|
|
60
|
+
|
|
61
|
+
# Release the lock
|
|
62
|
+
spinlock_release(lock)
|
|
63
|
+
|
|
64
|
+
# Increment atomic counter for comparison
|
|
65
|
+
wp.atomic_add(atomic_counter, 0, 1)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_spinlock(device):
|
|
69
|
+
# Create a lock array initialized to 0 (unlocked)
|
|
70
|
+
lock = wp.array([0], dtype=wp.int32, device=device)
|
|
71
|
+
|
|
72
|
+
# Create counter arrays initialized to 0
|
|
73
|
+
counter = wp.array([0], dtype=wp.int32, device=device)
|
|
74
|
+
atomic_counter = wp.array([0], dtype=wp.int32, device=device)
|
|
75
|
+
|
|
76
|
+
# Number of threads to test with
|
|
77
|
+
n = 1024
|
|
78
|
+
|
|
79
|
+
# Launch the test kernel
|
|
80
|
+
wp.launch(test_spinlock_counter, dim=n, inputs=[counter, atomic_counter, lock], device=device)
|
|
81
|
+
|
|
82
|
+
# Verify results
|
|
83
|
+
assert atomic_counter.numpy()[0] == n, f"Atomic counter should be {n}, got {atomic_counter.numpy()[0]}"
|
|
84
|
+
assert counter.numpy()[0] == n, f"Counter should be {n}, got {counter.numpy()[0]}"
|
|
85
|
+
assert lock.numpy()[0] == 0, "Lock was not properly released"
|
|
86
|
+
|
|
87
|
+
print(f"Final counter value: {counter.numpy()[0]}")
|
|
88
|
+
print(f"Final atomic counter value: {atomic_counter.numpy()[0]}")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
if __name__ == "__main__":
|
|
92
|
+
wp.clear_kernel_cache()
|
|
93
|
+
test_spinlock(device="cuda")
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 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
|
+
###########################################################################
|
|
17
|
+
# Example Torch
|
|
18
|
+
#
|
|
19
|
+
# Optimizes the Rosenbrock function using the PyTorch Adam optimizer
|
|
20
|
+
# The Rosenbrock function is a non-convex function, and is often used
|
|
21
|
+
# to test optimization algorithms. The function is defined as:
|
|
22
|
+
# f(x, y) = (a - x)^2 + b * (y - x^2)^2
|
|
23
|
+
# where a = 1 and b = 100. The minimum value of the function is 0 at (1, 1).
|
|
24
|
+
#
|
|
25
|
+
# The example demonstrates how to set up a torch.autograd.Function to
|
|
26
|
+
# incorporate Warp kernel launches within a PyTorch graph.
|
|
27
|
+
###########################################################################
|
|
28
|
+
|
|
29
|
+
import numpy as np
|
|
30
|
+
import torch
|
|
31
|
+
|
|
32
|
+
import warp as wp
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Define the Rosenbrock function
|
|
36
|
+
@wp.func
|
|
37
|
+
def rosenbrock(x: float, y: float):
|
|
38
|
+
return (1.0 - x) ** 2.0 + 100.0 * (y - x**2.0) ** 2.0
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@wp.kernel
|
|
42
|
+
def eval_rosenbrock(xs: wp.array(dtype=wp.vec2), z: wp.array(dtype=float)):
|
|
43
|
+
i = wp.tid()
|
|
44
|
+
x = xs[i]
|
|
45
|
+
z[i] = rosenbrock(x[0], x[1])
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class Rosenbrock(torch.autograd.Function):
|
|
49
|
+
@staticmethod
|
|
50
|
+
def forward(ctx, xy, num_particles):
|
|
51
|
+
ctx.xy = wp.from_torch(xy, dtype=wp.vec2, requires_grad=True)
|
|
52
|
+
ctx.num_particles = num_particles
|
|
53
|
+
|
|
54
|
+
# allocate output
|
|
55
|
+
ctx.z = wp.zeros(num_particles, requires_grad=True)
|
|
56
|
+
|
|
57
|
+
wp.launch(kernel=eval_rosenbrock, dim=ctx.num_particles, inputs=[ctx.xy], outputs=[ctx.z])
|
|
58
|
+
|
|
59
|
+
return wp.to_torch(ctx.z)
|
|
60
|
+
|
|
61
|
+
@staticmethod
|
|
62
|
+
def backward(ctx, adj_z):
|
|
63
|
+
# map incoming Torch grads to our output variables
|
|
64
|
+
ctx.z.grad = wp.from_torch(adj_z)
|
|
65
|
+
|
|
66
|
+
wp.launch(
|
|
67
|
+
kernel=eval_rosenbrock,
|
|
68
|
+
dim=ctx.num_particles,
|
|
69
|
+
inputs=[ctx.xy],
|
|
70
|
+
outputs=[ctx.z],
|
|
71
|
+
adj_inputs=[ctx.xy.grad],
|
|
72
|
+
adj_outputs=[ctx.z.grad],
|
|
73
|
+
adjoint=True,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# return adjoint w.r.t. inputs
|
|
77
|
+
return (wp.to_torch(ctx.xy.grad), None)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class Example:
|
|
81
|
+
def __init__(self, headless=False, train_iters=10, num_particles=1500):
|
|
82
|
+
self.num_particles = num_particles
|
|
83
|
+
self.train_iters = train_iters
|
|
84
|
+
self.train_iter = 0
|
|
85
|
+
|
|
86
|
+
self.learning_rate = 5e-2
|
|
87
|
+
|
|
88
|
+
self.torch_device = wp.device_to_torch(wp.get_device())
|
|
89
|
+
|
|
90
|
+
rng = np.random.default_rng(42)
|
|
91
|
+
self.xy = torch.tensor(
|
|
92
|
+
rng.normal(size=(self.num_particles, 2)), dtype=torch.float32, requires_grad=True, device=self.torch_device
|
|
93
|
+
)
|
|
94
|
+
self.xp_np = self.xy.numpy(force=True)
|
|
95
|
+
self.opt = torch.optim.Adam([self.xy], lr=self.learning_rate)
|
|
96
|
+
|
|
97
|
+
if headless:
|
|
98
|
+
self.scatter_plot = None
|
|
99
|
+
self.mean_marker = None
|
|
100
|
+
else:
|
|
101
|
+
self.scatter_plot = self.create_plot()
|
|
102
|
+
|
|
103
|
+
self.mean_pos = np.empty((2,))
|
|
104
|
+
|
|
105
|
+
def create_plot(self):
|
|
106
|
+
import matplotlib.pyplot as plt
|
|
107
|
+
|
|
108
|
+
min_x, max_x = -2.0, 2.0
|
|
109
|
+
min_y, max_y = -2.0, 2.0
|
|
110
|
+
|
|
111
|
+
# Create a grid of points
|
|
112
|
+
x = np.linspace(min_x, max_x, 100)
|
|
113
|
+
y = np.linspace(min_y, max_y, 100)
|
|
114
|
+
X, Y = np.meshgrid(x, y)
|
|
115
|
+
xy = np.column_stack((X.flatten(), Y.flatten()))
|
|
116
|
+
N = len(xy)
|
|
117
|
+
|
|
118
|
+
xy = wp.array(xy, dtype=wp.vec2)
|
|
119
|
+
Z = wp.empty(N, dtype=wp.float32)
|
|
120
|
+
|
|
121
|
+
wp.launch(eval_rosenbrock, dim=N, inputs=[xy], outputs=[Z])
|
|
122
|
+
Z = Z.numpy().reshape(X.shape)
|
|
123
|
+
|
|
124
|
+
# Plot the function as a heatmap
|
|
125
|
+
self.fig = plt.figure(figsize=(6, 6))
|
|
126
|
+
ax = plt.gca()
|
|
127
|
+
plt.imshow(Z, extent=[min_x, max_x, min_y, max_y], origin="lower", interpolation="bicubic", cmap="coolwarm")
|
|
128
|
+
plt.contour(X, Y, Z, extent=[min_x, max_x, min_y, max_y], levels=150, colors="k", alpha=0.5, linewidths=0.5)
|
|
129
|
+
|
|
130
|
+
# Plot optimum
|
|
131
|
+
plt.plot(1, 1, "*", color="r", markersize=10)
|
|
132
|
+
|
|
133
|
+
plt.title("Rosenbrock function")
|
|
134
|
+
plt.xlabel("x")
|
|
135
|
+
plt.ylabel("y")
|
|
136
|
+
|
|
137
|
+
(self.mean_marker,) = ax.plot([], [], "o", color="w", markersize=5)
|
|
138
|
+
|
|
139
|
+
# Create a scatter plot (initially empty)
|
|
140
|
+
return ax.scatter([], [], c="k", s=2)
|
|
141
|
+
|
|
142
|
+
def forward(self):
|
|
143
|
+
self.z = Rosenbrock.apply(self.xy, self.num_particles)
|
|
144
|
+
|
|
145
|
+
def step(self):
|
|
146
|
+
self.opt.zero_grad()
|
|
147
|
+
self.forward()
|
|
148
|
+
self.z.backward(torch.ones_like(self.z))
|
|
149
|
+
|
|
150
|
+
self.opt.step()
|
|
151
|
+
|
|
152
|
+
# Update the scatter plot
|
|
153
|
+
self.xy_np = self.xy.numpy(force=True)
|
|
154
|
+
|
|
155
|
+
# Compute mean
|
|
156
|
+
self.mean_pos = np.mean(self.xy_np, axis=0)
|
|
157
|
+
print(f"\rIter {self.train_iter:5d} particle mean: {self.mean_pos[0]:.8f}, {self.mean_pos[1]:.8f} ", end="")
|
|
158
|
+
|
|
159
|
+
self.train_iter += 1
|
|
160
|
+
|
|
161
|
+
def render(self):
|
|
162
|
+
if self.scatter_plot is None:
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
self.scatter_plot.set_offsets(np.c_[self.xy_np[:, 0], self.xy_np[:, 1]])
|
|
166
|
+
self.mean_marker.set_data([self.mean_pos[0]], [self.mean_pos[1]])
|
|
167
|
+
|
|
168
|
+
# Function to update the scatter plot
|
|
169
|
+
def step_and_render(self, frame):
|
|
170
|
+
for _ in range(self.train_iters):
|
|
171
|
+
self.step()
|
|
172
|
+
|
|
173
|
+
self.render()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
if __name__ == "__main__":
|
|
177
|
+
import argparse
|
|
178
|
+
|
|
179
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
180
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
181
|
+
parser.add_argument("--num_frames", type=int, default=10000, help="Total number of frames.")
|
|
182
|
+
parser.add_argument("--train_iters", type=int, default=10, help="Total number of training iterations per frame.")
|
|
183
|
+
parser.add_argument(
|
|
184
|
+
"--num_particles", type=int, default=1500, help="Total number of particles to use in optimization."
|
|
185
|
+
)
|
|
186
|
+
parser.add_argument(
|
|
187
|
+
"--headless",
|
|
188
|
+
action="store_true",
|
|
189
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
args = parser.parse_known_args()[0]
|
|
193
|
+
|
|
194
|
+
with wp.ScopedDevice(args.device):
|
|
195
|
+
example = Example(headless=args.headless, train_iters=args.train_iters, num_particles=args.num_particles)
|
|
196
|
+
|
|
197
|
+
if not args.headless:
|
|
198
|
+
import matplotlib.pyplot as plt
|
|
199
|
+
from matplotlib.animation import FuncAnimation
|
|
200
|
+
|
|
201
|
+
# Create the animation
|
|
202
|
+
ani = FuncAnimation(
|
|
203
|
+
example.fig, example.step_and_render, frames=args.num_frames, interval=100, repeat=False
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Display the animation
|
|
207
|
+
plt.show()
|
|
208
|
+
|
|
209
|
+
else:
|
|
210
|
+
for _ in range(args.num_frames):
|
|
211
|
+
example.step()
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2022 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
|
+
###########################################################################
|
|
17
|
+
# Example Wave
|
|
18
|
+
#
|
|
19
|
+
# Shows how to implement a simple 2D wave-equation solver with collision
|
|
20
|
+
# against a moving sphere.
|
|
21
|
+
#
|
|
22
|
+
###########################################################################
|
|
23
|
+
|
|
24
|
+
import math
|
|
25
|
+
|
|
26
|
+
import warp as wp
|
|
27
|
+
import warp.render
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@wp.func
|
|
31
|
+
def sample(f: wp.array(dtype=float), x: int, y: int, width: int, height: int):
|
|
32
|
+
# clamp texture coords
|
|
33
|
+
x = wp.clamp(x, 0, width - 1)
|
|
34
|
+
y = wp.clamp(y, 0, height - 1)
|
|
35
|
+
|
|
36
|
+
s = f[y * width + x]
|
|
37
|
+
return s
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@wp.func
|
|
41
|
+
def laplacian(f: wp.array(dtype=float), x: int, y: int, width: int, height: int):
|
|
42
|
+
ddx = sample(f, x + 1, y, width, height) - 2.0 * sample(f, x, y, width, height) + sample(f, x - 1, y, width, height)
|
|
43
|
+
ddy = sample(f, x, y + 1, width, height) - 2.0 * sample(f, x, y, width, height) + sample(f, x, y - 1, width, height)
|
|
44
|
+
|
|
45
|
+
return ddx + ddy
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@wp.kernel
|
|
49
|
+
def wave_displace(
|
|
50
|
+
hcurrent: wp.array(dtype=float),
|
|
51
|
+
hprevious: wp.array(dtype=float),
|
|
52
|
+
width: int,
|
|
53
|
+
height: int,
|
|
54
|
+
center_x: float,
|
|
55
|
+
center_y: float,
|
|
56
|
+
r: float,
|
|
57
|
+
mag: float,
|
|
58
|
+
t: float,
|
|
59
|
+
):
|
|
60
|
+
tid = wp.tid()
|
|
61
|
+
|
|
62
|
+
x = tid % width
|
|
63
|
+
y = tid // width
|
|
64
|
+
|
|
65
|
+
dx = float(x) - center_x
|
|
66
|
+
dy = float(y) - center_y
|
|
67
|
+
|
|
68
|
+
dist_sq = float(dx * dx + dy * dy)
|
|
69
|
+
|
|
70
|
+
if dist_sq < r * r:
|
|
71
|
+
h = mag * wp.sin(t)
|
|
72
|
+
|
|
73
|
+
hcurrent[tid] = h
|
|
74
|
+
hprevious[tid] = h
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@wp.kernel
|
|
78
|
+
def wave_solve(
|
|
79
|
+
hprevious: wp.array(dtype=float),
|
|
80
|
+
hcurrent: wp.array(dtype=float),
|
|
81
|
+
width: int,
|
|
82
|
+
height: int,
|
|
83
|
+
inv_cell: float,
|
|
84
|
+
k_speed: float,
|
|
85
|
+
k_damp: float,
|
|
86
|
+
dt: float,
|
|
87
|
+
):
|
|
88
|
+
tid = wp.tid()
|
|
89
|
+
|
|
90
|
+
x = tid % width
|
|
91
|
+
y = tid // width
|
|
92
|
+
|
|
93
|
+
l = laplacian(hcurrent, x, y, width, height) * inv_cell * inv_cell
|
|
94
|
+
|
|
95
|
+
# integrate
|
|
96
|
+
h1 = hcurrent[tid]
|
|
97
|
+
h0 = hprevious[tid]
|
|
98
|
+
|
|
99
|
+
h = 2.0 * h1 - h0 + dt * dt * (k_speed * l - k_damp * (h1 - h0))
|
|
100
|
+
|
|
101
|
+
# buffers get swapped each iteration
|
|
102
|
+
hprevious[tid] = h
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# simple kernel to apply height deltas to a vertex array
|
|
106
|
+
@wp.kernel
|
|
107
|
+
def grid_update(heights: wp.array(dtype=float), vertices: wp.array(dtype=wp.vec3)):
|
|
108
|
+
tid = wp.tid()
|
|
109
|
+
|
|
110
|
+
h = heights[tid]
|
|
111
|
+
v = vertices[tid]
|
|
112
|
+
|
|
113
|
+
v_new = wp.vec3(v[0], h, v[2])
|
|
114
|
+
|
|
115
|
+
vertices[tid] = v_new
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class Example:
|
|
119
|
+
def __init__(self, stage_path="example_wave.usd", verbose=False):
|
|
120
|
+
self.sim_width = 128
|
|
121
|
+
self.sim_height = 128
|
|
122
|
+
|
|
123
|
+
fps = 60
|
|
124
|
+
self.sim_substeps = 16
|
|
125
|
+
self.sim_dt = (1.0 / fps) / self.sim_substeps
|
|
126
|
+
self.sim_time = 0.0
|
|
127
|
+
|
|
128
|
+
# wave constants
|
|
129
|
+
self.k_speed = 1.0
|
|
130
|
+
self.k_damp = 0.0
|
|
131
|
+
|
|
132
|
+
# grid constants
|
|
133
|
+
self.grid_size = 0.1
|
|
134
|
+
self.grid_displace = 0.5
|
|
135
|
+
|
|
136
|
+
self.verbose = verbose
|
|
137
|
+
|
|
138
|
+
vertices = []
|
|
139
|
+
self.indices = []
|
|
140
|
+
|
|
141
|
+
def grid_index(x, y, stride):
|
|
142
|
+
return y * stride + x
|
|
143
|
+
|
|
144
|
+
for z in range(self.sim_height):
|
|
145
|
+
for x in range(self.sim_width):
|
|
146
|
+
pos = (
|
|
147
|
+
float(x) * self.grid_size,
|
|
148
|
+
0.0,
|
|
149
|
+
float(z) * self.grid_size,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# directly modifies verts_host memory since this is a numpy alias of the same buffer
|
|
153
|
+
vertices.append(pos)
|
|
154
|
+
|
|
155
|
+
if x > 0 and z > 0:
|
|
156
|
+
self.indices.append(grid_index(x - 1, z - 1, self.sim_width))
|
|
157
|
+
self.indices.append(grid_index(x, z, self.sim_width))
|
|
158
|
+
self.indices.append(grid_index(x, z - 1, self.sim_width))
|
|
159
|
+
|
|
160
|
+
self.indices.append(grid_index(x - 1, z - 1, self.sim_width))
|
|
161
|
+
self.indices.append(grid_index(x - 1, z, self.sim_width))
|
|
162
|
+
self.indices.append(grid_index(x, z, self.sim_width))
|
|
163
|
+
|
|
164
|
+
# simulation grids
|
|
165
|
+
self.sim_grid0 = wp.zeros(self.sim_width * self.sim_height, dtype=float)
|
|
166
|
+
self.sim_grid1 = wp.zeros(self.sim_width * self.sim_height, dtype=float)
|
|
167
|
+
self.sim_verts = wp.array(vertices, dtype=wp.vec3)
|
|
168
|
+
|
|
169
|
+
# create surface displacement around a point
|
|
170
|
+
self.cx = self.sim_width / 2 + math.sin(self.sim_time) * self.sim_width / 3
|
|
171
|
+
self.cy = self.sim_height / 2 + math.cos(self.sim_time) * self.sim_height / 3
|
|
172
|
+
|
|
173
|
+
if stage_path:
|
|
174
|
+
self.renderer = wp.render.UsdRenderer(stage_path)
|
|
175
|
+
else:
|
|
176
|
+
self.renderer = None
|
|
177
|
+
|
|
178
|
+
def step(self):
|
|
179
|
+
with wp.ScopedTimer("step"):
|
|
180
|
+
for _s in range(self.sim_substeps):
|
|
181
|
+
# create surface displacement around a point
|
|
182
|
+
self.cx = self.sim_width / 2 + math.sin(self.sim_time) * self.sim_width / 3
|
|
183
|
+
self.cy = self.sim_height / 2 + math.cos(self.sim_time) * self.sim_height / 3
|
|
184
|
+
|
|
185
|
+
wp.launch(
|
|
186
|
+
kernel=wave_displace,
|
|
187
|
+
dim=self.sim_width * self.sim_height,
|
|
188
|
+
inputs=[
|
|
189
|
+
self.sim_grid0,
|
|
190
|
+
self.sim_grid1,
|
|
191
|
+
self.sim_width,
|
|
192
|
+
self.sim_height,
|
|
193
|
+
self.cx,
|
|
194
|
+
self.cy,
|
|
195
|
+
10.0,
|
|
196
|
+
self.grid_displace,
|
|
197
|
+
-math.pi * 0.5,
|
|
198
|
+
],
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# integrate wave equation
|
|
202
|
+
wp.launch(
|
|
203
|
+
kernel=wave_solve,
|
|
204
|
+
dim=self.sim_width * self.sim_height,
|
|
205
|
+
inputs=[
|
|
206
|
+
self.sim_grid0,
|
|
207
|
+
self.sim_grid1,
|
|
208
|
+
self.sim_width,
|
|
209
|
+
self.sim_height,
|
|
210
|
+
1.0 / self.grid_size,
|
|
211
|
+
self.k_speed,
|
|
212
|
+
self.k_damp,
|
|
213
|
+
self.sim_dt,
|
|
214
|
+
],
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# swap grids
|
|
218
|
+
(self.sim_grid0, self.sim_grid1) = (self.sim_grid1, self.sim_grid0)
|
|
219
|
+
|
|
220
|
+
self.sim_time += self.sim_dt
|
|
221
|
+
|
|
222
|
+
with wp.ScopedTimer("mesh", self.verbose):
|
|
223
|
+
# update grid vertices from heights
|
|
224
|
+
wp.launch(kernel=grid_update, dim=self.sim_width * self.sim_height, inputs=[self.sim_grid0, self.sim_verts])
|
|
225
|
+
|
|
226
|
+
def render(self):
|
|
227
|
+
if self.renderer is None:
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
with wp.ScopedTimer("render"):
|
|
231
|
+
vertices = self.sim_verts.numpy()
|
|
232
|
+
|
|
233
|
+
self.renderer.begin_frame(self.sim_time)
|
|
234
|
+
self.renderer.render_mesh("surface", vertices, self.indices, colors=(0.35, 0.55, 0.9))
|
|
235
|
+
self.renderer.render_sphere(
|
|
236
|
+
"sphere",
|
|
237
|
+
(self.cx * self.grid_size, 0.0, self.cy * self.grid_size),
|
|
238
|
+
(0.0, 0.0, 0.0, 1.0),
|
|
239
|
+
10.0 * self.grid_size,
|
|
240
|
+
color=(1.0, 1.0, 1.0),
|
|
241
|
+
)
|
|
242
|
+
self.renderer.end_frame()
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
if __name__ == "__main__":
|
|
246
|
+
import argparse
|
|
247
|
+
|
|
248
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
249
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
250
|
+
parser.add_argument(
|
|
251
|
+
"--stage_path",
|
|
252
|
+
type=lambda x: None if x == "None" else str(x),
|
|
253
|
+
default="example_wave.usd",
|
|
254
|
+
help="Path to the output USD file.",
|
|
255
|
+
)
|
|
256
|
+
parser.add_argument("--num_frames", type=int, default=300, help="Total number of frames.")
|
|
257
|
+
parser.add_argument("--verbose", action="store_true", help="Print out additional status messages during execution.")
|
|
258
|
+
|
|
259
|
+
args = parser.parse_known_args()[0]
|
|
260
|
+
|
|
261
|
+
with wp.ScopedDevice(args.device):
|
|
262
|
+
example = Example(stage_path=args.stage_path, verbose=args.verbose)
|
|
263
|
+
|
|
264
|
+
for _ in range(args.num_frames):
|
|
265
|
+
example.step()
|
|
266
|
+
example.render()
|
|
267
|
+
|
|
268
|
+
if example.renderer:
|
|
269
|
+
example.renderer.save()
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
###########################################################################
|
|
17
|
+
# Example Work Queue
|
|
18
|
+
#
|
|
19
|
+
# Shows how to use a work queue to synchronize access to a shared resource.
|
|
20
|
+
#
|
|
21
|
+
###########################################################################
|
|
22
|
+
|
|
23
|
+
import warp as wp
|
|
24
|
+
from warp.tests.unittest_utils import *
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@wp.func
|
|
28
|
+
def volatile_read(ptr: wp.array(dtype=wp.int32), index: int):
|
|
29
|
+
value = wp.atomic_add(ptr, index, 0)
|
|
30
|
+
return value
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@wp.struct
|
|
34
|
+
class WorkQueue:
|
|
35
|
+
buffer: wp.array(dtype=wp.int32)
|
|
36
|
+
capacity: int
|
|
37
|
+
head: wp.array(dtype=wp.int32)
|
|
38
|
+
tail: wp.array(dtype=wp.int32)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@wp.func
|
|
42
|
+
def enqueue(queue: WorkQueue, item: int) -> bool:
|
|
43
|
+
while True:
|
|
44
|
+
# Read current head and tail atomically
|
|
45
|
+
current_tail = volatile_read(queue.tail, 0)
|
|
46
|
+
current_head = volatile_read(queue.head, 0)
|
|
47
|
+
|
|
48
|
+
# Check if queue is full
|
|
49
|
+
if (current_tail - current_head) >= queue.capacity:
|
|
50
|
+
return False
|
|
51
|
+
|
|
52
|
+
# Try to increment tail atomically
|
|
53
|
+
index = current_tail % queue.capacity
|
|
54
|
+
if wp.atomic_cas(queue.tail, 0, current_tail, current_tail + 1) == current_tail:
|
|
55
|
+
queue.buffer[index] = item
|
|
56
|
+
return True
|
|
57
|
+
|
|
58
|
+
# Retry if another thread changed tail
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@wp.func
|
|
62
|
+
def dequeue(queue: WorkQueue) -> tuple[bool, int]:
|
|
63
|
+
while True:
|
|
64
|
+
# Read current head and tail atomically
|
|
65
|
+
current_head = volatile_read(queue.head, 0)
|
|
66
|
+
current_tail = volatile_read(queue.tail, 0)
|
|
67
|
+
|
|
68
|
+
# Check if queue is empty
|
|
69
|
+
if current_head >= current_tail:
|
|
70
|
+
return False, 0
|
|
71
|
+
|
|
72
|
+
# Get item at current head
|
|
73
|
+
index = current_head % queue.capacity
|
|
74
|
+
item = queue.buffer[index]
|
|
75
|
+
|
|
76
|
+
# Try to increment head atomically
|
|
77
|
+
if wp.atomic_cas(queue.head, 0, current_head, current_head + 1) == current_head:
|
|
78
|
+
return True, item
|
|
79
|
+
|
|
80
|
+
# Retry if another thread changed head
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@wp.kernel
|
|
84
|
+
def process_queue(queue: WorkQueue):
|
|
85
|
+
counter = int(0)
|
|
86
|
+
while True:
|
|
87
|
+
success, item = dequeue(queue)
|
|
88
|
+
if not success:
|
|
89
|
+
break
|
|
90
|
+
wp.printf("Processed item: %d\n", item)
|
|
91
|
+
if item < 1000000:
|
|
92
|
+
if not enqueue(queue, item + 1000000):
|
|
93
|
+
wp.printf("Failed to enqueue item: %d\n", item + 1000000)
|
|
94
|
+
counter = counter + 1
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_work_queue(device):
|
|
98
|
+
# Create a work queue with capacity 1024
|
|
99
|
+
capacity = 8192
|
|
100
|
+
head = wp.array([0], dtype=wp.int32, device=device)
|
|
101
|
+
tail = wp.array([4096], dtype=wp.int32, device=device)
|
|
102
|
+
buffer = wp.array(np.arange(4096, dtype=np.int32), dtype=wp.int32, device=device)
|
|
103
|
+
|
|
104
|
+
queue = WorkQueue()
|
|
105
|
+
queue.capacity = capacity
|
|
106
|
+
queue.head = head
|
|
107
|
+
queue.tail = tail
|
|
108
|
+
queue.buffer = buffer
|
|
109
|
+
|
|
110
|
+
# Launch processing kernel
|
|
111
|
+
wp.launch(process_queue, dim=1024, inputs=[queue], device=device)
|
|
112
|
+
|
|
113
|
+
wp.synchronize()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
wp.clear_kernel_cache()
|
|
118
|
+
test_work_queue(device="cuda")
|