Skip to content

nanovdb/python: fix writeGrids dropping all but the last grid#2198

Open
swahtz wants to merge 1 commit intoAcademySoftwareFoundation:masterfrom
swahtz:fix/nanovdb_python_write_grids_drop
Open

nanovdb/python: fix writeGrids dropping all but the last grid#2198
swahtz wants to merge 1 commit intoAcademySoftwareFoundation:masterfrom
swahtz:fix/nanovdb_python_write_grids_drop

Conversation

@swahtz
Copy link
Copy Markdown
Contributor

@swahtz swahtz commented Apr 24, 2026

The Python binding for nanovdb.io.writeGrids iterated the handle list and called io::writeGrid(fileName, ...) per element. That file-level overload opens the path with std::ios::trunc, so every iteration wiped the previously written grid and the resulting .nvdb only ever contained the last handle in the list (same story for deviceWriteGrids on the CUDA side).

Mirror io::writeGrids(fileName, handles, codec, verbose) from nanovdb/io/IO.h directly in the wrapper: open the output stream once with trunc, then call the ostream overload of writeGrid for each handle cast from the nb::list. We can't simply forward to io::writeGrids because GridHandle<BufferT> is move-only and the nb::list holds references we must not invalidate.

Tests (nanovdb/python/test/TestNanoVDB.py):

  • TestGridHandleExchange.test_list_to_vector now reads the written file back via readGridMetaData and readGrids and asserts the full handle count is preserved.
  • Added TestDeviceReadWriteGrids.test_device_write_grids_multi as a CUDA-guarded regression for deviceWriteGrids with multiple handles.

The Python binding for nanovdb.io.writeGrids iterated the handle list
and called io::writeGrid(fileName, ...) per element. That file-level
overload opens the path with std::ios::trunc, so every iteration wiped
the previously written grid and the resulting .nvdb only ever contained
the last handle in the list (same story for deviceWriteGrids on the
CUDA side).

Mirror io::writeGrids(fileName, handles, codec, verbose) from
nanovdb/io/IO.h directly in the wrapper: open the output stream once
with trunc, then call the ostream overload of writeGrid for each handle
cast from the nb::list. We can't simply forward to io::writeGrids
because GridHandle<BufferT> is move-only (see GridHandle.h) and the
nb::list holds references we must not invalidate.

Tests (nanovdb/python/test/TestNanoVDB.py):
- TestGridHandleExchange.test_list_to_vector now reads the written
  file back via readGridMetaData and readGrids and asserts the full
  handle count is preserved.
- Added TestDeviceReadWriteGrids.test_device_write_grids_multi as a
  CUDA-guarded regression for deviceWriteGrids with multiple handles.

Signed-off-by: Jonathan Swartz <jonathan@jswartz.info>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant