Move Gaussian splatting autograd and pipeline logic from C++ to Python#595
Conversation
8ba5156 to
6c2f995
Compare
|
Thanks, looks good. Do we want to add a Python test for deduplicate pixels since we've removed the C++ test (and implementation)? |
6c2f995 to
aaf4caf
Compare
|
Good call — added a |
Eliminate the C++ GaussianSplat3d class and its associated autograd functions,
replacing them with pure Python torch.autograd.Function implementations in a new
_gaussian_autograd.py module. The Python GaussianSplat3d class now directly manages
torch.Tensor attributes instead of delegating to a C++ _impl object.
Key changes:
- Port all C++ autograd ops (projection, rasterization, SH evaluation) to Python
- Rewrite deduplicatePixels as a pure Python function using PyTorch ops
- Refactor PLY I/O to return a flat tuple of tensors instead of a C++ struct
- Update viewer integration to accept individual tensors directly
- Remove ~7,600 lines of dead C++ code (GaussianSplat3d.{h,cpp}, autograd/*, tests)
- Simplify pybind bindings to only expose low-level dispatch functions
Signed-off-by: Francis Williams <francis@fwilliams.info>
Made-with: Cursor
Signed-off-by: Francis Williams <francis@fwilliams.info>
Made-with: Cursor
Signed-off-by: Francis Williams <francis@fwilliams.info>
Made-with: Cursor
Signed-off-by: Francis Williams <francis@fwilliams.info>
Made-with: Cursor
aaf4caf to
7a18210
Compare
There was a problem hiding this comment.
Pull request overview
This PR migrates Gaussian splatting autograd and pipeline orchestration from a C++ GaussianSplat3d implementation to Python torch.autograd.Function wrappers over lower-level C++ dispatch kernels, while simplifying viewer and PLY I/O APIs to operate on raw tensors.
Changes:
- Introduces
fvdb/_gaussian_autograd.pywith Python autograd wrappers for projection, rasterization, and SH evaluation dispatch functions. - Refactors viewer + bindings to accept individual Gaussian tensors (instead of a C++
GaussianSplat3dobject) and updates tests accordingly. - Refactors Gaussian PLY I/O to return/accept a flat tuple of tensors + metadata, and removes now-dead C++ autograd/test code.
Reviewed changes
Copilot reviewed 30 out of 32 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
fvdb/_gaussian_autograd.py |
New Python autograd wrappers calling pybind-exposed forward/backward dispatch functions. |
fvdb/__init__.py |
Reimplements gaussian_render_jagged in Python using the new autograd wrappers; re-exports evaluate_spherical_harmonics. |
fvdb/__init__.pyi |
Updates public stubs (but currently diverges from __init__.py exports/signatures). |
fvdb/_fvdb_cpp.pyi |
Removes C++ GaussianSplat3d/projected types from stubs; adds raw dispatch + PLY I/O function stubs and viewer tensor-based API. |
fvdb/viz/_scene.py |
Passes raw Gaussian tensors into visualization views instead of ._impl. |
fvdb/viz/_gaussian_splat_3d_view.py |
Updates view construction to call viewer binding with individual tensors. |
src/python/GaussianSplatBinding.cpp |
Replaces high-level C++ class bindings with enums + low-level dispatch functions and PLY I/O bindings. |
src/python/ViewerBinding.cpp |
Updates viewer binding to accept raw tensors for Gaussian splat views and uses ops camera enums. |
src/fvdb/detail/viewer/Viewer.h/.cpp |
Changes viewer API to accept raw tensors and updates camera model type alias. |
src/fvdb/detail/io/GaussianPlyIO.h/.cpp |
Changes PLY load/save to operate on flat tensor tuples + metadata (no GaussianSplat3d object). |
src/tests/ViewerTest.cpp |
Adjusts viewer test to the new PLY return type + tensor-based viewer APIs. |
tests/unit/test_gaussian_splat_3d.py |
Adds Python unit tests for the new pure-Python pixel deduplication path. |
src/tests/CMakeLists.txt / deleted tests |
Removes now-obsolete C++ tests for removed C++ APIs. |
src/CMakeLists.txt |
Removes deleted C++ autograd sources and GaussianSplat3d.cpp from the build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| assert grad_means2d is not None | ||
| assert grad_depths is not None | ||
| assert grad_conics is not None |
There was a problem hiding this comment.
backward() asserts that grad_means2d, grad_depths, and grad_conics are non-None. In PyTorch autograd these grads can be None when a particular output isn’t used in the loss, which would make this custom Function crash at runtime. Replace the asserts by treating missing grads as zero tensors (or returning early when all required grads are None) before calling into _C.project_gaussians_analytic_bwd.
…d.cpp were not carried over during PR openvdb#595, this attempts to restore those back to appropriate locations Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
|
I didn't have a chance to review this PR because this was over the weekend, but here are some notes on things that changed in this port we should address. It's also useful to know we don't have coverage to catch some of these situations and we should get an LLM friend to write us some pytests to make sure we have coverage going forward. Python autograd backward() asserts on None gradientsThis is pointed out by Copilot above, but all 5 Python assert grad_means2d is not None
assert grad_depths is not None
assert grad_conics is not NoneIn PyTorch autograd, these grads can be No input shape/contiguity validation in
|
Several useful comments/todos/fixmes that were part of GaussianSplat3d.cpp were not carried over during PR #595, this attempts to restore those back to appropriate locations Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Summary
torch.autograd.Functionimplementations in a new_gaussian_autograd.pymodule, making the differentiable pipeline easier to extend and debug.GaussianSplat3dclass entirely: the PythonGaussianSplat3dclass now directly managestorch.Tensorattributes instead of delegating to a C++_implobject.deduplicatePixelsas a pure Python function using PyTorch ops, removing its C++ binding and implementation.GaussianSplat3d.{h,cpp},detail/autograd/*,DeduplicatePixelsTest.cpp,GaussianSplat3dCameraApiTest.cpp).Test plan
cd tests && pytest unit/test_gaussian_splat_3d.py -v)ctest --test-dir build/.../src/tests)