Skip to content

cp: fix: log metrics that can be coerced to scalars (1723) into r0.5.0#1730

Merged
yuki-97 merged 1 commit intor0.5.0from
cherry-pick-1723-r0.5.0
Jan 7, 2026
Merged

cp: fix: log metrics that can be coerced to scalars (1723) into r0.5.0#1730
yuki-97 merged 1 commit intor0.5.0from
cherry-pick-1723-r0.5.0

Conversation

@chtruong814
Copy link
Copy Markdown
Contributor

@chtruong814 chtruong814 commented Jan 6, 2026

beep boop [🤖]: Hi @terrykong 👋,

we've cherry picked #1723 into  for you! 🚀

Please review and approve this cherry pick by your convenience!

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved metric logging to properly handle various numeric types, including Python scalars, NumPy arrays, and PyTorch tensors, with graceful handling of incompatible types.
  • Tests

    • Added comprehensive unit tests for metric logging functionality and type coercion scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

Signed-off-by: Terry Kong <terryk@nvidia.com>
Signed-off-by: NeMo Bot <nemo-bot@nvidia.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 6, 2026

📝 Walkthrough

Walkthrough

Added a new static helper method _coerce_to_scalar to TensorboardLogger that converts various input types (Python scalars, NumPy scalars/arrays, PyTorch tensors) to Python scalars. Updated log_metrics to use this helper for robust scalar handling instead of direct type checking.

Changes

Cohort / File(s) Summary
Logger utility enhancement
nemo_rl/utils/logger.py
Added _coerce_to_scalar static method to handle conversion of Python primitives, NumPy scalars/arrays, and PyTorch tensors to scalar types (int, float, bool, str). Refactored log_metrics to use this helper for type coercion with warning logs for skipped non-scalar values.
Unit test coverage
tests/unit/utils/test_logger.py
Comprehensive test suite for _coerce_to_scalar covering Python primitives, NumPy scalar types and arrays (0-d, 1-element, multi-element), PyTorch scalar tensors, and unsupported types. Added integration tests verifying log_metrics correctly coerces and logs valid scalars while skipping incompatible entries.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

CI:L1

Suggested reviewers

  • terrykong
  • hemildesai

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Test Results For Major Changes ⚠️ Warning PR description lacks test results documentation for the scalar coercion helper method feature addition despite comprehensive unit tests in code changes. Update PR description to document testing performed, test cases added, scenarios covered, and confirmation that all tests pass.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: a fix to log metrics that can be coerced to scalars, referencing the original PR #1723 being cherry-picked into the r0.5.0 branch.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between edfc23d and 4d99d0b.

📒 Files selected for processing (2)
  • nemo_rl/utils/logger.py
  • tests/unit/utils/test_logger.py
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

**/*.py: Conform code to Python 3.12+
Indent code with 4 spaces. Do not use tabs
Use snake_case for file names
Use PascalCase for class names
Use snake_case for function and method names
Use snake_case for local variables
Prefix variable names that start with a number with 'k' (e.g., k_99th_percentile)
Use upper snake_case with 'G' prefix for global variables (e.g., G_MY_GLOBAL)
Use upper snake_case for constants
Avoid shadowing variables declared in an outer scope
Initialize all externally visible members of a class in the constructor
Prefer docstrings over comments for interfaces that may be used outside a file
Reserve comments for code within a function or interfaces that are local to a file
If a piece of code is commented out, include a comment describing its usage and why it's commented out. Remove debug comments before merging
Use Google style docstrings for classes and functions in Python, which can be parsed by Sphinx
Avoid using reflection when functionality can be easily achieved without reflection
When using try-except blocks, limit the except clause to the smallest set of specific errors possible
When using try-except blocks for duck-typing, keep the body of the try as small as possible and use the else block for logic
YAML is the single source of truth for configuration defaults. Do not set non-None defaults in code for configuration values
For required configuration attributes, access config directly and expect presence (e.g., policy_cfg['precision']) without hidden defaults
Use typing.NotRequired to mark optional attributes in TypedDict for configuration
When adding a new config key to a TypedDict subclass, document the key's purpose, valid values/types, and recommended default, and reflect the default in exemplar YAMLs under examples/configs/*.yaml
Follow the Google Python Style Guide for Python code

Files:

  • nemo_rl/utils/logger.py
  • tests/unit/utils/test_logger.py
nemo_rl/**/*.py

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

For any source file under nemo_rl/*.py that defines a class or function decorated with @ray.remote, add a coverage pragma (# pragma: no cover) because these run in separate Ray processes

Files:

  • nemo_rl/utils/logger.py
!(**/tests/**|**/test_*.py|**/test_*.sh)

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

Add the NVIDIA copyright header to all Python files and shell scripts (excluding tests). The header should include the current year

Files:

  • nemo_rl/utils/logger.py
  • tests/unit/utils/test_logger.py
**/*.{py,sh}

📄 CodeRabbit inference engine (CODING_GUIDELINES.md)

The NVIDIA copyright header should appear at the top of all Python files and shell scripts (excluding tests)

Files:

  • nemo_rl/utils/logger.py
  • tests/unit/utils/test_logger.py
🧬 Code graph analysis (1)
tests/unit/utils/test_logger.py (1)
nemo_rl/utils/logger.py (8)
  • TensorboardLogger (117-194)
  • _coerce_to_scalar (125-139)
  • log_metrics (96-104)
  • log_metrics (141-172)
  • log_metrics (329-356)
  • log_metrics (401-422)
  • log_metrics (778-796)
  • log_metrics (903-920)
🪛 Ruff (0.14.10)
tests/unit/utils/test_logger.py

132-132: Unused method argument: mock_summary_writer

(ARG002)


143-143: Unused method argument: mock_summary_writer

(ARG002)


166-166: Unused method argument: mock_summary_writer

(ARG002)


182-182: Unused method argument: mock_summary_writer

(ARG002)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Lint check
  • GitHub Check: Lint check
  • GitHub Check: Lint check
  • GitHub Check: Post automodel integration comment / Comment on PR
  • GitHub Check: Post submodule check comment / Comment on PR
🔇 Additional comments (3)
nemo_rl/utils/logger.py (2)

124-140: LGTM! Well-designed scalar coercion method.

The _coerce_to_scalar method correctly handles Python primitives, NumPy scalars/arrays, and PyTorch tensors. The logic appropriately converts 0-dimensional and 1-element arrays/tensors to scalars while returning None for incompatible types. The implementation is clean, well-documented, and follows Python 3.12+ conventions.


160-172: LGTM! Robust metric logging with proper type coercion.

The updated log_metrics method correctly uses _coerce_to_scalar to handle various input types gracefully. The warning messages are informative, helping users identify unsupported metric types. The existing exception handling around add_scalar provides additional resilience.

tests/unit/utils/test_logger.py (1)

131-225: LGTM! Excellent test coverage for scalar coercion.

The new tests comprehensively cover all aspects of the _coerce_to_scalar method:

  • Python primitives pass through unchanged
  • NumPy scalars and arrays (0-d, 1-element, multi-element) are handled correctly
  • PyTorch tensors (0-d, 1-element, multi-element) are coerced appropriately
  • Incompatible types correctly return None
  • Integration test verifies end-to-end behavior in log_metrics with mixed input types

The tests are well-structured and provide strong confidence in the implementation. The static analysis warnings about unused mock_summary_writer parameters are false positives—the mock is required for the @patch decorator to function correctly.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yuki-97 yuki-97 added the CI:L1 Run doctests, unit tests, and functional tests label Jan 7, 2026
@yuki-97 yuki-97 enabled auto-merge (squash) January 7, 2026 01:35
@yuki-97 yuki-97 merged commit 06584bb into r0.5.0 Jan 7, 2026
68 of 71 checks passed
@yuki-97 yuki-97 deleted the cherry-pick-1723-r0.5.0 branch January 7, 2026 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cherry-pick CI:L1 Run doctests, unit tests, and functional tests Run CICD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants