Skip to content

Conversation

@szkarpinski
Copy link
Collaborator

@szkarpinski szkarpinski commented Nov 17, 2025

Category:

Other (e.g. Documentation, Tests, Configuration)

Description:

New content

  • API reference, documenting classes such as Batch, Tensor, EvalContext and related functions.
  • Data reader reference, listing the available readers
  • Operator reference, with a table listing Dynamic Mode operators.

Internal changes

  • autodoc_submodules.py has been extended with dynamic_autodoc and dynamic_readers_autodoc, generating autodoc stubs for dynamic mode operators.
  • operations_table.py has been generalized, to be able to generate tables for dynamic ops & readers. Some functions now get additional api_name argument instead of hardcoding "fn".

Other changes

  • Small formatting fixes in existing docstrings to make RST render correctly

Additional information:

Affected modules and functionalities:

  • Sphinx documentation and the docs autogeneration scripts

Key points relevant for the review:

  • Does the organization of the docs make sense?
  • Are links clickable, do they redirect to correct pages, does page content match the title?
  • fn docs still look good? (the code is shared)
  • The docs are generated from whatever is in the signatures/function docstrings. There's definitely room for improvement there, but this is out of scope.

Tests:

  • Existing tests apply
  • New tests added
    • Python tests
    • GTests
    • Benchmark
    • Other
  • N/A

Checklist

Documentation

  • Existing documentation applies
  • Documentation updated
    • Docstring
    • Doxygen
    • RST
    • Jupyter
    • Other
  • N/A

DALI team only

Requirements

  • Implements new requirements
  • Affects existing requirements
  • N/A

REQ IDs: N/A

JIRA TASK: DALI-4446

Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
@szkarpinski szkarpinski marked this pull request as ready for review November 18, 2025 13:55
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
@greptile-apps
Copy link

greptile-apps bot commented Nov 18, 2025

Greptile Overview

Greptile Summary

This PR adds comprehensive documentation for DALI Dynamic Mode, including API references, operator listings, and data reader documentation. The implementation properly extends the existing documentation generation infrastructure to support the dynamic API alongside the traditional fn API.

Key changes:

  • Documentation structure: Creates new docs/dali_dynamic/ directory with index, overview, API reference, operators reference, and readers reference pages
  • Code generation: Adds dynamic_autodoc() and dynamic_readers_autodoc() functions in autodoc_submodules.py to generate RST stubs for dynamic mode operators and readers
  • Table generation: Generalizes operations_table.py to support multiple APIs by adding api_name parameter and to_other_module() helper
  • Docstring fixes: Improves RST formatting in Python source files (_batch.py, _tensor.py, _eval_context.py) to ensure proper rendering
  • Refactoring: Consolidates duplicate module creation logic in _op_builder.py to use shared _internal.get_submodule() utility

The documentation organization is logical and consistent with existing DALI docs. All links use proper Sphinx cross-references. The code properly handles the distinction between function-based operators (using single_fun_file) and class-based readers (using single_class_op_file).

Confidence Score: 5/5

  • This PR is safe to merge with no issues identified
  • The changes are well-structured documentation additions with proper code reuse and refactoring. All modifications follow existing patterns, RST formatting is correct, and the code properly handles both function-based and class-based documentation generation. No functional logic changes to runtime code.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
docs/autodoc_submodules.py 5/5 Adds dynamic_autodoc and dynamic_readers_autodoc functions to generate documentation for dynamic mode operators, with proper refactoring and code reuse
docs/operations_table.py 5/5 Generalizes table generation to support dynamic API with new api_name parameter and adds dynamic_readers_table function
docs/conf.py 5/5 Integrates dynamic mode documentation generation by creating output paths and calling new autodoc functions
docs/dali_dynamic/index.rst 5/5 New dynamic mode landing page with overview and toctree linking to API reference, readers, and operations
docs/dali_dynamic/api_reference.rst 5/5 New API reference documenting core classes like Batch, Tensor, EvalContext, and related functions
dali/python/nvidia/dali/experimental/dynamic/_batch.py 5/5 Fixes RST formatting in docstrings: adds cross-references, fixes code blocks, improves list formatting

Sequence Diagram

sequenceDiagram
    participant Sphinx as Sphinx Build
    participant conf.py as conf.py
    participant ops_table as operations_table.py
    participant autodoc as autodoc_submodules.py
    participant fs as File System
    
    Sphinx->>conf.py: Initialize documentation build
    conf.py->>fs: Create docs/dali_dynamic/operations/ directory
    
    conf.py->>ops_table: operations_table(dynamic_table, module="nvidia.dali.experimental.dynamic")
    ops_table->>ops_table: Detect api_name="dynamic" from module
    ops_table->>ops_table: Generate table for dynamic operators
    ops_table->>fs: Write dynamic_table
    
    conf.py->>ops_table: dynamic_readers_table(dynamic_readers_table)
    ops_table->>ops_table: Filter readers from dynamic ops
    ops_table->>ops_table: Generate readers table
    ops_table->>fs: Write dynamic_readers_table
    
    conf.py->>autodoc: dynamic_autodoc(dynamic_autodoc, paths, references)
    autodoc->>autodoc: get_modules(dynamic_modules)
    autodoc->>autodoc: Filter functions with schema attribute
    autodoc->>autodoc: write_module_file() for each module
    autodoc->>autodoc: write_function_files(single_fun_file) for operators
    autodoc->>fs: Write dynamic_autodoc and operator RST files
    
    conf.py->>autodoc: dynamic_readers_autodoc(dynamic_readers_autodoc, paths, references)
    autodoc->>autodoc: Filter modules with "readers"
    autodoc->>autodoc: Filter classes subclassing Reader
    autodoc->>autodoc: write_module_file() for each module
    autodoc->>autodoc: write_function_files(single_class_op_file) for readers
    autodoc->>fs: Write dynamic_readers_autodoc and reader RST files
    
    Sphinx->>fs: Read generated RST files
    Sphinx->>Sphinx: Render documentation
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile
React with 👍 or 👎 to share your feedback on this new summary format

DALI Dynamic does not replace the graph-based execution model. Instead, it provides
an alternative interface for a seamless Python experience. Prototyping and development
can be performed in DALI Dynamic using exactly the same operators as a pipeline mode
and transition between the two modes is straightforward. No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: missing newline at end of file

@rostan-t
Copy link
Collaborator

Nitpick: This would be nice occurrences of Tensor/Batch could reference the actual classes. This was not possible with the fn API as there's no TensorList class exposed in Python but it makes sense for dynamic mode.

not submodule_path
or (submodule_path[0] not in ["ops"] and "readers" not in submodule_path)
)
):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

):

The if condition is pretty big, and ideas on how to make it a tad more readable? Should we just split it to more conditions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Split, hope it's still equivalent :P

Comment on lines 6 to 25
Key features include:

- **Imperative programming with lazy execution**
In the original DALI execution model, operators were defined and executed within a static
pipeline graph. This often resulted in a steep learning curve, complex debugging, and
limited error visibility. DALI Dynamic introduces imperative programming with lazy operator
execution, aligning DALI more closely with standard Python workflows.

- **Minimal performance overhead**
DALI Dynamic is designed to deliver performance that is close to graph-based pipelines, incurring
only marginal overhead.

- **Batch processing support**
Batch processing remains a core concept in DALI. DALI Dynamic preserves this functionality and
introduces a dedicated API for batch-oriented workflows.

- **Framework interoperability**
DALI Dynamic provides type conversion support for major deep learning frameworks, including
PyTorch, CuPy, JAX, and Numba.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should maybe make the intro contain the code sample, rather than the key features? Or maybe just keep all of the introduction at the top page without repeat?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with sample, good point

Comment on lines +125 to +126
elif hasattr(obj, "schema"):
return obj.schema.Name()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet another way of accessing the schema?

Sidenote, if ndd operators have a public schema member, maybe they shouldn't.

return result


def single_class_op_file(full_name, references):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we plan to have any other classes than readers? If yes, I'm starting to spin the crank on our ski jumping hero. ⚠️ 📯

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random ops, I guess

f.write(all_modules_str)


def dynamic_autodoc(out_filename, generated_path, references):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost a copy of fn_autodoc. Same for dynamic_readers_autodoc. Can we generalize.

Maybe we can take out the filtering of what to document to the higher scope or make it a function, and the rest is the same - loop over filtered members -> generate doc -> write to a file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored. Thanks!

Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

16 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

DALI Dynamic does not replace the graph-based execution model. Instead, it provides
an alternative interface for a seamless Python experience. Prototyping and development
can be performed in DALI Dynamic using exactly the same operators as a pipeline mode
and transition between the two modes is straightforward. No newline at end of file
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: missing newline at end of file

Suggested change
and transition between the two modes is straightforward.
and transition between the two modes is straightforward.

Signed-off-by: Szymon Karpiński <[email protected]>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

16 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Signed-off-by: Szymon Karpiński <[email protected]>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

15 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@szkarpinski
Copy link
Collaborator Author

!build

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [39073360]: BUILD STARTED

@dali-automaton
Copy link
Collaborator

CI MESSAGE: [39073360]: BUILD PASSED

@szkarpinski szkarpinski merged commit 1018430 into NVIDIA:main Nov 26, 2025
7 checks passed
mdabek-nvidia pushed a commit to mdabek-nvidia/DALI that referenced this pull request Nov 27, 2025
Generate documentation section for the Dynamic Mode.

Signed-off-by: Szymon Karpiński <[email protected]>
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.

5 participants