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,497 @@
|
|
|
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 Fluid Checkpoint
|
|
18
|
+
#
|
|
19
|
+
# Shows how to implement a differentiable 2D stable-fluids solver and
|
|
20
|
+
# optimize the initial velocity field to form the NVIDIA logo at the end
|
|
21
|
+
# of the simulation. Gradient checkpointing to reduce memory usage
|
|
22
|
+
# is manually implemented.
|
|
23
|
+
#
|
|
24
|
+
# References:
|
|
25
|
+
# https://github.com/HIPS/autograd/blob/master/examples/fluidsim/fluidsim.py
|
|
26
|
+
#
|
|
27
|
+
###########################################################################
|
|
28
|
+
|
|
29
|
+
import math
|
|
30
|
+
import os
|
|
31
|
+
|
|
32
|
+
import numpy as np
|
|
33
|
+
|
|
34
|
+
import warp as wp
|
|
35
|
+
import warp.examples
|
|
36
|
+
import warp.optim
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
from PIL import Image
|
|
40
|
+
except ImportError as err:
|
|
41
|
+
raise ImportError("This example requires the Pillow package. Please install it with 'pip install Pillow'.") from err
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
N_GRID = wp.constant(512)
|
|
45
|
+
DH = 1.0 / N_GRID # Grid spacing
|
|
46
|
+
FLUID_COLUMN_WIDTH = N_GRID / 10.0
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@wp.func
|
|
50
|
+
def cyclic_index(idx: wp.int32):
|
|
51
|
+
"""Helper function to index with periodic boundary conditions."""
|
|
52
|
+
ret_idx = idx % N_GRID
|
|
53
|
+
if ret_idx < 0:
|
|
54
|
+
ret_idx += N_GRID
|
|
55
|
+
return ret_idx
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@wp.kernel
|
|
59
|
+
def fill_initial_density(density: wp.array2d(dtype=wp.float32)):
|
|
60
|
+
"""Initialize the density array with three bands of fluid."""
|
|
61
|
+
i, j = wp.tid()
|
|
62
|
+
|
|
63
|
+
y_pos = wp.float32(i)
|
|
64
|
+
|
|
65
|
+
if FLUID_COLUMN_WIDTH <= y_pos < 2.0 * FLUID_COLUMN_WIDTH:
|
|
66
|
+
density[i, j] = 1.0
|
|
67
|
+
elif 4.5 * FLUID_COLUMN_WIDTH <= y_pos < 5.5 * FLUID_COLUMN_WIDTH:
|
|
68
|
+
density[i, j] = 1.0
|
|
69
|
+
elif 8.0 * FLUID_COLUMN_WIDTH <= y_pos < 9.0 * FLUID_COLUMN_WIDTH:
|
|
70
|
+
density[i, j] = 1.0
|
|
71
|
+
else:
|
|
72
|
+
density[i, j] = 0.0
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@wp.kernel
|
|
76
|
+
def advect(
|
|
77
|
+
dt: float,
|
|
78
|
+
vx: wp.array2d(dtype=float),
|
|
79
|
+
vy: wp.array2d(dtype=float),
|
|
80
|
+
f0: wp.array2d(dtype=float),
|
|
81
|
+
f1: wp.array2d(dtype=float),
|
|
82
|
+
):
|
|
83
|
+
"""Move field f0 according to vx and vy velocities using an implicit Euler integrator."""
|
|
84
|
+
|
|
85
|
+
i, j = wp.tid()
|
|
86
|
+
|
|
87
|
+
center_xs = wp.float32(i) - vx[i, j] * dt
|
|
88
|
+
center_ys = wp.float32(j) - vy[i, j] * dt
|
|
89
|
+
|
|
90
|
+
# Compute indices of source cells.
|
|
91
|
+
left_idx = wp.int32(wp.floor(center_xs))
|
|
92
|
+
bot_idx = wp.int32(wp.floor(center_ys))
|
|
93
|
+
|
|
94
|
+
s1 = center_xs - wp.float32(left_idx) # Relative weight of right cell
|
|
95
|
+
s0 = 1.0 - s1
|
|
96
|
+
t1 = center_ys - wp.float32(bot_idx) # Relative weight of top cell
|
|
97
|
+
t0 = 1.0 - t1
|
|
98
|
+
|
|
99
|
+
i0 = cyclic_index(left_idx)
|
|
100
|
+
i1 = cyclic_index(left_idx + 1)
|
|
101
|
+
j0 = cyclic_index(bot_idx)
|
|
102
|
+
j1 = cyclic_index(bot_idx + 1)
|
|
103
|
+
|
|
104
|
+
# Perform bilinear interpolation of the four cells bounding the back-in-time position
|
|
105
|
+
f1[i, j] = s0 * (t0 * f0[i0, j0] + t1 * f0[i0, j1]) + s1 * (t0 * f0[i1, j0] + t1 * f0[i1, j1])
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@wp.kernel
|
|
109
|
+
def divergence(wx: wp.array2d(dtype=float), wy: wp.array2d(dtype=float), div: wp.array2d(dtype=float)):
|
|
110
|
+
"""Compute div(w)."""
|
|
111
|
+
|
|
112
|
+
i, j = wp.tid()
|
|
113
|
+
|
|
114
|
+
div[i, j] = (
|
|
115
|
+
0.5
|
|
116
|
+
* (
|
|
117
|
+
wx[cyclic_index(i + 1), j]
|
|
118
|
+
- wx[cyclic_index(i - 1), j]
|
|
119
|
+
+ wy[i, cyclic_index(j + 1)]
|
|
120
|
+
- wy[i, cyclic_index(j - 1)]
|
|
121
|
+
)
|
|
122
|
+
/ DH
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@wp.kernel
|
|
127
|
+
def jacobi_iter(div: wp.array2d(dtype=float), p0: wp.array2d(dtype=float), p1: wp.array2d(dtype=float)):
|
|
128
|
+
"""Calculate a single Jacobi iteration for solving the pressure Poisson equation."""
|
|
129
|
+
|
|
130
|
+
i, j = wp.tid()
|
|
131
|
+
|
|
132
|
+
p1[i, j] = 0.25 * (
|
|
133
|
+
-DH * DH * div[i, j]
|
|
134
|
+
+ p0[cyclic_index(i - 1), j]
|
|
135
|
+
+ p0[cyclic_index(i + 1), j]
|
|
136
|
+
+ p0[i, cyclic_index(j - 1)]
|
|
137
|
+
+ p0[i, cyclic_index(j + 1)]
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@wp.kernel
|
|
142
|
+
def update_velocities(
|
|
143
|
+
p: wp.array2d(dtype=float),
|
|
144
|
+
wx: wp.array2d(dtype=float),
|
|
145
|
+
wy: wp.array2d(dtype=float),
|
|
146
|
+
vx: wp.array2d(dtype=float),
|
|
147
|
+
vy: wp.array2d(dtype=float),
|
|
148
|
+
):
|
|
149
|
+
"""Given p and (wx, wy), compute an 'incompressible' velocity field (vx, vy)."""
|
|
150
|
+
|
|
151
|
+
i, j = wp.tid()
|
|
152
|
+
|
|
153
|
+
vx[i, j] = wx[i, j] - 0.5 * (p[cyclic_index(i + 1), j] - p[cyclic_index(i - 1), j]) / DH
|
|
154
|
+
vy[i, j] = wy[i, j] - 0.5 * (p[i, cyclic_index(j + 1)] - p[i, cyclic_index(j - 1)]) / DH
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@wp.kernel
|
|
158
|
+
def compute_loss(
|
|
159
|
+
actual_state: wp.array2d(dtype=float), target_state: wp.array2d(dtype=float), loss: wp.array(dtype=float)
|
|
160
|
+
):
|
|
161
|
+
i, j = wp.tid()
|
|
162
|
+
|
|
163
|
+
loss_value = (
|
|
164
|
+
(actual_state[i, j] - target_state[i, j])
|
|
165
|
+
* (actual_state[i, j] - target_state[i, j])
|
|
166
|
+
/ wp.float32(N_GRID * N_GRID)
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
wp.atomic_add(loss, 0, loss_value)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class Example:
|
|
173
|
+
def __init__(self, sim_steps=1000):
|
|
174
|
+
self.pressure_arrays = []
|
|
175
|
+
self.wx_arrays = []
|
|
176
|
+
self.wy_arrays = []
|
|
177
|
+
self.vx_arrays = []
|
|
178
|
+
self.vy_arrays = []
|
|
179
|
+
self.density_arrays = []
|
|
180
|
+
self.div_arrays = []
|
|
181
|
+
|
|
182
|
+
# Memory usage is minimized when the segment size is approx. sqrt(sim_steps)
|
|
183
|
+
self.segment_size = math.ceil(math.sqrt(sim_steps))
|
|
184
|
+
|
|
185
|
+
# TODO: For now, let's just round up sim_steps so each segment is the same size
|
|
186
|
+
self.num_segments = math.ceil(sim_steps / self.segment_size)
|
|
187
|
+
self.sim_steps = self.segment_size * self.num_segments
|
|
188
|
+
|
|
189
|
+
self.pressure_iterations = 50
|
|
190
|
+
self.dt = 1.0
|
|
191
|
+
|
|
192
|
+
# Store enough arrays to step through a segment without overwriting arrays
|
|
193
|
+
# NOTE: Need an extra array to store the final time-advanced velocities and densities
|
|
194
|
+
for _step in range(self.segment_size + 1):
|
|
195
|
+
self.vx_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
196
|
+
self.vy_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
197
|
+
self.density_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
198
|
+
|
|
199
|
+
for _step in range(self.segment_size):
|
|
200
|
+
self.wx_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
201
|
+
self.wy_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
202
|
+
self.div_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
203
|
+
|
|
204
|
+
for _iter in range(self.pressure_iterations):
|
|
205
|
+
self.pressure_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
206
|
+
|
|
207
|
+
# Allocate one more pressure array for the final time step
|
|
208
|
+
self.pressure_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float, requires_grad=True))
|
|
209
|
+
|
|
210
|
+
# Allocate memory to save the fluid state at the start of each segment
|
|
211
|
+
self.segment_start_vx_arrays = []
|
|
212
|
+
self.segment_start_vy_arrays = []
|
|
213
|
+
self.segment_start_density_arrays = []
|
|
214
|
+
self.segment_start_pressure_arrays = []
|
|
215
|
+
|
|
216
|
+
for _segment_index in range(self.num_segments):
|
|
217
|
+
self.segment_start_vx_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float))
|
|
218
|
+
self.segment_start_vy_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float))
|
|
219
|
+
self.segment_start_density_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float))
|
|
220
|
+
self.segment_start_pressure_arrays.append(wp.zeros((N_GRID, N_GRID), dtype=float))
|
|
221
|
+
|
|
222
|
+
# To restore previously computed gradients before calling tape.backward()
|
|
223
|
+
self.vx_array_grad_saved = wp.zeros((N_GRID, N_GRID), dtype=float)
|
|
224
|
+
self.vy_array_grad_saved = wp.zeros((N_GRID, N_GRID), dtype=float)
|
|
225
|
+
self.density_array_grad_saved = wp.zeros((N_GRID, N_GRID), dtype=float)
|
|
226
|
+
self.pressure_array_grad_saved = wp.zeros((N_GRID, N_GRID), dtype=float)
|
|
227
|
+
|
|
228
|
+
wp.launch(fill_initial_density, (N_GRID, N_GRID), inputs=[self.density_arrays[0]])
|
|
229
|
+
|
|
230
|
+
target_base = Image.open(os.path.join(warp.examples.get_asset_directory(), "nvidia_logo.png"))
|
|
231
|
+
target_resized = target_base.resize((N_GRID, N_GRID))
|
|
232
|
+
|
|
233
|
+
target_np = np.array(target_resized)[:, :, 0] / 255.0
|
|
234
|
+
self.target_wp = wp.array(target_np, dtype=float)
|
|
235
|
+
|
|
236
|
+
self.loss = wp.zeros((1,), dtype=float, requires_grad=True)
|
|
237
|
+
|
|
238
|
+
self.train_rate = 0.01
|
|
239
|
+
self.optimizer = warp.optim.Adam([self.vx_arrays[0].flatten(), self.vy_arrays[0].flatten()], lr=self.train_rate)
|
|
240
|
+
|
|
241
|
+
# Capture forward/backward passes and tape.zero()
|
|
242
|
+
self.use_cuda_graph = wp.get_device().is_cuda
|
|
243
|
+
self.forward_graph = None
|
|
244
|
+
self.backward_graph = None
|
|
245
|
+
self.zero_tape_graph = None
|
|
246
|
+
|
|
247
|
+
if self.use_cuda_graph:
|
|
248
|
+
with wp.ScopedCapture() as capture:
|
|
249
|
+
self.forward()
|
|
250
|
+
self.forward_graph = capture.graph
|
|
251
|
+
|
|
252
|
+
with wp.ScopedCapture() as capture:
|
|
253
|
+
self.backward()
|
|
254
|
+
self.backward_graph = capture.graph
|
|
255
|
+
|
|
256
|
+
# tape.zero() launches many memsets, which can be a significant overhead for smaller problems
|
|
257
|
+
with wp.ScopedCapture() as capture:
|
|
258
|
+
self.tape.zero()
|
|
259
|
+
self.zero_tape_graph = capture.graph
|
|
260
|
+
|
|
261
|
+
def step(self, step_index) -> None:
|
|
262
|
+
"""Perform a single time step from t=step_index-1 to t=step_index.
|
|
263
|
+
|
|
264
|
+
1. Self-advection of velocity components (store output in wx_arrays and wy_arrays)
|
|
265
|
+
2. Incompressibility constraint (store output in vx_arrays and vy_arrays)
|
|
266
|
+
3. Advection of density using velocities (vx_arrays, vy_arrays)
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
wp.launch(
|
|
270
|
+
advect,
|
|
271
|
+
(N_GRID, N_GRID),
|
|
272
|
+
inputs=[
|
|
273
|
+
self.dt,
|
|
274
|
+
self.vx_arrays[step_index - 1],
|
|
275
|
+
self.vy_arrays[step_index - 1],
|
|
276
|
+
self.vx_arrays[step_index - 1],
|
|
277
|
+
],
|
|
278
|
+
outputs=[self.wx_arrays[step_index - 1]],
|
|
279
|
+
)
|
|
280
|
+
wp.launch(
|
|
281
|
+
advect,
|
|
282
|
+
(N_GRID, N_GRID),
|
|
283
|
+
inputs=[
|
|
284
|
+
self.dt,
|
|
285
|
+
self.vx_arrays[step_index - 1],
|
|
286
|
+
self.vy_arrays[step_index - 1],
|
|
287
|
+
self.vy_arrays[step_index - 1],
|
|
288
|
+
],
|
|
289
|
+
outputs=[self.wy_arrays[step_index - 1]],
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
# Pressure projection using a few Jacobi iterations
|
|
293
|
+
wp.launch(
|
|
294
|
+
divergence,
|
|
295
|
+
(N_GRID, N_GRID),
|
|
296
|
+
inputs=[self.wx_arrays[step_index - 1], self.wy_arrays[step_index - 1]],
|
|
297
|
+
outputs=[self.div_arrays[step_index - 1]],
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# NOTE: Uses previous step's final pressure as the initial guess
|
|
301
|
+
for k in range(self.pressure_iterations):
|
|
302
|
+
input_index = self.pressure_iterations * (step_index - 1) + k
|
|
303
|
+
output_index = input_index + 1
|
|
304
|
+
|
|
305
|
+
wp.launch(
|
|
306
|
+
jacobi_iter,
|
|
307
|
+
(N_GRID, N_GRID),
|
|
308
|
+
inputs=[self.div_arrays[step_index - 1], self.pressure_arrays[input_index]],
|
|
309
|
+
outputs=[self.pressure_arrays[output_index]],
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
# NOTE: output_index should be self.pressure_iterations*step_index at this point
|
|
313
|
+
wp.launch(
|
|
314
|
+
update_velocities,
|
|
315
|
+
(N_GRID, N_GRID),
|
|
316
|
+
inputs=[self.pressure_arrays[output_index], self.wx_arrays[step_index - 1], self.wy_arrays[step_index - 1]],
|
|
317
|
+
outputs=[self.vx_arrays[step_index], self.vy_arrays[step_index]],
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
wp.launch(
|
|
321
|
+
advect,
|
|
322
|
+
(N_GRID, N_GRID),
|
|
323
|
+
inputs=[
|
|
324
|
+
self.dt,
|
|
325
|
+
self.vx_arrays[step_index],
|
|
326
|
+
self.vy_arrays[step_index],
|
|
327
|
+
self.density_arrays[step_index - 1],
|
|
328
|
+
],
|
|
329
|
+
outputs=[self.density_arrays[step_index]],
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
def forward(self) -> None:
|
|
333
|
+
"""Advance the simulation forward in segments, storing the fluid state at the start of each segment.
|
|
334
|
+
|
|
335
|
+
The loss function is also evaluated at the end of the function.
|
|
336
|
+
"""
|
|
337
|
+
self.loss.zero_()
|
|
338
|
+
|
|
339
|
+
for segment_index in range(self.num_segments):
|
|
340
|
+
# Save start-of-segment values
|
|
341
|
+
wp.copy(self.segment_start_vx_arrays[segment_index], self.vx_arrays[0])
|
|
342
|
+
wp.copy(self.segment_start_vy_arrays[segment_index], self.vy_arrays[0])
|
|
343
|
+
wp.copy(self.segment_start_density_arrays[segment_index], self.density_arrays[0])
|
|
344
|
+
wp.copy(self.segment_start_pressure_arrays[segment_index], self.pressure_arrays[0])
|
|
345
|
+
|
|
346
|
+
for t in range(1, self.segment_size + 1):
|
|
347
|
+
# sim_t = (segment_index - 1) * self.segment_size + t
|
|
348
|
+
self.step(t)
|
|
349
|
+
|
|
350
|
+
# Set the initial conditions for the next segment
|
|
351
|
+
if segment_index < self.num_segments - 1:
|
|
352
|
+
wp.copy(self.vx_arrays[0], self.vx_arrays[-1])
|
|
353
|
+
wp.copy(self.vy_arrays[0], self.vy_arrays[-1])
|
|
354
|
+
wp.copy(self.density_arrays[0], self.density_arrays[-1])
|
|
355
|
+
wp.copy(self.pressure_arrays[0], self.pressure_arrays[-1])
|
|
356
|
+
|
|
357
|
+
wp.launch(
|
|
358
|
+
compute_loss,
|
|
359
|
+
(N_GRID, N_GRID),
|
|
360
|
+
inputs=[self.density_arrays[self.segment_size], self.target_wp],
|
|
361
|
+
outputs=[self.loss],
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
def backward(self) -> None:
|
|
365
|
+
"""Compute the adjoints using a checkpointing approach.
|
|
366
|
+
|
|
367
|
+
Starting from the final segment, the forward pass for the segment is
|
|
368
|
+
repeated, this time recording the kernel launches onto a tape. Any
|
|
369
|
+
previously computed adjoints are restored prior to evaluating the
|
|
370
|
+
backward pass for the segment. This process is repeated until the
|
|
371
|
+
adjoints of the initial state have been calculated.
|
|
372
|
+
"""
|
|
373
|
+
|
|
374
|
+
for segment_index in range(self.num_segments - 1, -1, -1):
|
|
375
|
+
# Restore state at the start of the segment
|
|
376
|
+
wp.copy(self.vx_arrays[0], self.segment_start_vx_arrays[segment_index])
|
|
377
|
+
wp.copy(self.vy_arrays[0], self.segment_start_vy_arrays[segment_index])
|
|
378
|
+
wp.copy(self.density_arrays[0], self.segment_start_density_arrays[segment_index])
|
|
379
|
+
wp.copy(self.pressure_arrays[0], self.segment_start_pressure_arrays[segment_index])
|
|
380
|
+
|
|
381
|
+
# Record operations on tape
|
|
382
|
+
with wp.Tape() as self.tape:
|
|
383
|
+
for t in range(1, self.segment_size + 1):
|
|
384
|
+
self.step(t)
|
|
385
|
+
|
|
386
|
+
if segment_index == self.num_segments - 1:
|
|
387
|
+
self.loss.grad.fill_(1.0)
|
|
388
|
+
|
|
389
|
+
wp.launch(
|
|
390
|
+
compute_loss,
|
|
391
|
+
(N_GRID, N_GRID),
|
|
392
|
+
inputs=[self.density_arrays[self.segment_size], self.target_wp],
|
|
393
|
+
outputs=[self.loss],
|
|
394
|
+
adj_inputs=[self.density_arrays[self.segment_size].grad, None],
|
|
395
|
+
adj_outputs=[self.loss.grad],
|
|
396
|
+
adjoint=True,
|
|
397
|
+
)
|
|
398
|
+
else:
|
|
399
|
+
# Fill in previously computed gradients from the last segment
|
|
400
|
+
wp.copy(self.vx_arrays[-1].grad, self.vx_array_grad_saved)
|
|
401
|
+
wp.copy(self.vy_arrays[-1].grad, self.vy_array_grad_saved)
|
|
402
|
+
wp.copy(self.density_arrays[-1].grad, self.density_array_grad_saved)
|
|
403
|
+
wp.copy(self.pressure_arrays[-1].grad, self.pressure_array_grad_saved)
|
|
404
|
+
|
|
405
|
+
self.tape.backward()
|
|
406
|
+
|
|
407
|
+
if segment_index > 0:
|
|
408
|
+
# Save the gradients to variables and zero-out the gradients for the next segment
|
|
409
|
+
wp.copy(self.vx_array_grad_saved, self.vx_arrays[0].grad)
|
|
410
|
+
wp.copy(self.vy_array_grad_saved, self.vy_arrays[0].grad)
|
|
411
|
+
wp.copy(self.density_array_grad_saved, self.density_arrays[0].grad)
|
|
412
|
+
wp.copy(self.pressure_array_grad_saved, self.pressure_arrays[0].grad)
|
|
413
|
+
|
|
414
|
+
self.tape.zero()
|
|
415
|
+
|
|
416
|
+
# Done with backward pass, we're interested in self.vx_arrays[0].grad and self.vy_arrays[0].grad
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
if __name__ == "__main__":
|
|
420
|
+
import argparse
|
|
421
|
+
|
|
422
|
+
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
423
|
+
parser.add_argument("--device", type=str, default=None, help="Override the default Warp device.")
|
|
424
|
+
parser.add_argument(
|
|
425
|
+
"--num_frames", type=int, default=1000, help="Number of frames to simulate before computing loss."
|
|
426
|
+
)
|
|
427
|
+
parser.add_argument("--train_iters", type=int, default=50, help="Total number of training iterations.")
|
|
428
|
+
parser.add_argument(
|
|
429
|
+
"--headless",
|
|
430
|
+
action="store_true",
|
|
431
|
+
help="Run in headless mode, suppressing the opening of any graphical windows.",
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
args = parser.parse_known_args()[0]
|
|
435
|
+
|
|
436
|
+
with wp.ScopedDevice(args.device):
|
|
437
|
+
example = Example(sim_steps=args.num_frames)
|
|
438
|
+
|
|
439
|
+
wp.synchronize_device()
|
|
440
|
+
|
|
441
|
+
if (device := wp.get_device()).is_cuda:
|
|
442
|
+
print(f"Current memory usage: {wp.get_mempool_used_mem_current(device) / (1024 * 1024 * 1024):.4f} GiB")
|
|
443
|
+
|
|
444
|
+
# Main training loop
|
|
445
|
+
for train_iter in range(args.train_iters):
|
|
446
|
+
if example.forward_graph:
|
|
447
|
+
wp.capture_launch(example.forward_graph)
|
|
448
|
+
else:
|
|
449
|
+
example.forward()
|
|
450
|
+
|
|
451
|
+
if example.backward_graph:
|
|
452
|
+
wp.capture_launch(example.backward_graph)
|
|
453
|
+
else:
|
|
454
|
+
example.backward()
|
|
455
|
+
|
|
456
|
+
example.optimizer.step([example.vx_arrays[0].grad.flatten(), example.vy_arrays[0].grad.flatten()])
|
|
457
|
+
|
|
458
|
+
# Clear grad arrays for next iteration
|
|
459
|
+
if example.zero_tape_graph:
|
|
460
|
+
wp.capture_launch(example.zero_tape_graph)
|
|
461
|
+
else:
|
|
462
|
+
example.tape.zero()
|
|
463
|
+
|
|
464
|
+
print(f"Iteration {train_iter:05d} loss: {example.loss.numpy()[0]:.6f}")
|
|
465
|
+
|
|
466
|
+
if not args.headless:
|
|
467
|
+
import matplotlib
|
|
468
|
+
import matplotlib.pyplot as plt
|
|
469
|
+
|
|
470
|
+
if matplotlib.rcParams["figure.raise_window"]:
|
|
471
|
+
matplotlib.rcParams["figure.raise_window"] = False
|
|
472
|
+
|
|
473
|
+
fig, ax = plt.subplots()
|
|
474
|
+
image = ax.imshow(example.density_arrays[-1].numpy(), cmap="viridis", origin="lower", vmin=0, vmax=1)
|
|
475
|
+
ax.set_xticks([])
|
|
476
|
+
ax.set_yticks([])
|
|
477
|
+
ax.set_title("Fluid Density")
|
|
478
|
+
|
|
479
|
+
# Run the final simulation to the stop time
|
|
480
|
+
for _ in range(args.num_frames):
|
|
481
|
+
example.step(1)
|
|
482
|
+
# Swap pointers
|
|
483
|
+
(example.vx_arrays[0], example.vx_arrays[1]) = (example.vx_arrays[1], example.vx_arrays[0])
|
|
484
|
+
(example.vy_arrays[0], example.vy_arrays[1]) = (example.vy_arrays[1], example.vy_arrays[0])
|
|
485
|
+
(example.density_arrays[0], example.density_arrays[1]) = (
|
|
486
|
+
example.density_arrays[1],
|
|
487
|
+
example.density_arrays[0],
|
|
488
|
+
)
|
|
489
|
+
(example.pressure_arrays[0], example.pressure_arrays[example.pressure_iterations]) = (
|
|
490
|
+
example.pressure_arrays[example.pressure_iterations],
|
|
491
|
+
example.pressure_arrays[0],
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
image.set_data(example.density_arrays[0].numpy())
|
|
495
|
+
plt.pause(0.001)
|
|
496
|
+
|
|
497
|
+
plt.show()
|