Skip to content

feat: Infer DSE parameter encoding from candidate values at parse time#966

Open
KhushviB wants to merge 2 commits into
NVIDIA:mainfrom
KhushviB:feature/env-params-encoding-inference
Open

feat: Infer DSE parameter encoding from candidate values at parse time#966
KhushviB wants to merge 2 commits into
NVIDIA:mainfrom
KhushviB:feature/env-params-encoding-inference

Conversation

@KhushviB

Copy link
Copy Markdown

Summary (#956)

This pull request migrates DSE parameter encoding inference directly into the framework (cloudai), moving it out of individual optimizer agents (e.g., BO agents).
Previously, selecting a non-default encoding required an explicit encoding = { type = "log" } in the configuration TOML, and only the BO agent internally detected log scales. This led to agent-specific framework logic that was not reused by GA, MAB, or RL agents.
Changes introduced:

  • Defined the encoding stack by adding the missing LogEncoding class to encapsulate ObsLeafDescriptor and log-scaling logic.
  • Added an AnyEncoding discriminated union to seamlessly parse explicit configuration types (categorical or log).
  • Updated EnvParamSpec to make the encoding field optional.
  • Introduced _infer_encoding in env_params.py to automatically evaluate cmd_args candidates at parse time. Inference rules safely distinguish between categorical values, arithmetic series (linear), and geometric series (log).
  • Hooked the inference logic into EnvParams.from_test to apply when no explicit encoding is specified.
    These changes centralize parameter encoding logic, decouple it from optimizer agents, and make configuration easier for users.

Test Plan

Testing Environment:

  • Python 3.14.5
  • CloudAI Framework test suite
    Steps followed:
  1. Modified tests/test_env_params.py to add targeted unit tests for the _infer_encoding logic.
  2. Verified that string lists correctly fallback to CategoricalEncoding.
  3. Verified geometric series sequences (e.g., [1, 10, 100] and [2, 4, 8, 16]) correctly evaluate to LogEncoding.
  4. Verified that uniform arithmetic sequences (e.g., [1, 2, 3]) are correctly detected and fallback to CategoricalEncoding.
  5. Tested boundary conditions: arrays with length < 3 or lists with 0.0 or negative values correctly default to CategoricalEncoding.
  6. Verified that an explicit configuration override (e.g., { type = "log" }) safely bypasses the inference logic for edge cases.
    Results:
    The _infer_encoding heuristic strictly follows the mathematical properties of the candidate values and correctly creates the appropriate encoding object. The framework correctly defaults to inferred logic without crashing or overriding explicitly supplied TOML configurations.

Additional Notes

  • Future Considerations: The framework currently maps otherwise-numeric sequences (like ordinal or linear values) to CategoricalEncoding. The infrastructure is now properly set up to easily introduce a dedicated LinearEncoding or OrdinalEncoding block in the future if required.
  • Follow-up: Downstream optimizer agents (like the BO agent) should now be updated in a separate pull request to drop their ad-hoc _detect_log_scale heuristic and directly consume the framework-decided Encoding.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 01cfc57d-5f2f-494c-a83f-3560cc4f1484

📥 Commits

Reviewing files that changed from the base of the PR and between 9a70619 and 6d4e258.

📒 Files selected for processing (2)
  • src/cloudai/configurator/env_params.py
  • tests/test_env_params.py

📝 Walkthrough

Walkthrough

EnvParamSpec now supports optional categorical or logarithmic encoding. Candidate lists can infer an encoding, explicit encodings remain authoritative, and logarithmic candidates are validated during EnvParams.from_test(). Tests cover inference, overrides, defaults, and invalid values.

Changes

Environment parameter encoding

Layer / File(s) Summary
Encoding types and candidate inference
src/cloudai/configurator/env_params.py
Adds LogEncoding and AnyEncoding, makes EnvParamSpec.encoding optional, and infers encoding from candidate-list characteristics.
Parameter construction and validation
src/cloudai/configurator/env_params.py, tests/test_env_params.py
EnvParams.from_test() applies explicit or inferred encodings, validates logarithmic candidates, and tests inference patterns, overrides, defaults, and invalid values.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: jeffnvidia, podkidyshev, srivatsankrishnan, rutayan-nv

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: inferring DSE parameter encoding from candidate values during parsing.
Description check ✅ Passed The description matches the changeset and describes the new encoding inference, optional spec field, and tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cloudai/configurator/env_params.py`:
- Around line 146-156: Update the arithmetic and geometric-series checks in the
encoding-detection function to use scale-relative tolerances rather than the
fixed 1e-5 absolute comparison, so small values such as [1e-8, 1e-7, 1e-6] reach
LogEncoding() for their constant ×10 ratio. Add a regression test covering this
sequence and preserve the existing arithmetic and ratio direction checks.
- Around line 273-276: The EnvParams resolution path must validate explicit log
encoding candidates before constructing EnvParam, since `spec.encoding`
currently bypasses `_infer_encoding()`. In `EnvParams.from_test()`, reject zero,
negative, non-numeric, and non-finite values for explicit log overrides, while
preserving inferred-encoding behavior for unspecified encodings; add a
regression test covering the explicit override path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 7dd06e9f-56dc-4ca7-91ae-9f0120ad7203

📥 Commits

Reviewing files that changed from the base of the PR and between 0de6ca8 and af61b59.

📒 Files selected for processing (2)
  • src/cloudai/configurator/env_params.py
  • tests/test_env_params.py

Comment thread src/cloudai/configurator/env_params.py
Comment thread src/cloudai/configurator/env_params.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cloudai/configurator/env_params.py (1)

180-182: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update the stale default-value test.

EnvParamSpec.encoding now correctly defaults to None, but tests/test_env_params.py:415-417 still asserts CategoricalEncoding(). That test will fail immediately; update it to assert is None and keep categorical compatibility covered through EnvParams.from_test() inference.

Proposed test fix
-    assert EnvParamSpec().encoding == CategoricalEncoding()
+    assert EnvParamSpec().encoding is None
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cloudai/configurator/env_params.py` around lines 180 - 182, Update the
default-value assertion for EnvParamSpec.encoding in the relevant env-params
test to expect None instead of CategoricalEncoding(). Preserve categorical
compatibility coverage through EnvParams.from_test() inference rather than the
direct default-value test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/cloudai/configurator/env_params.py`:
- Around line 180-182: Update the default-value assertion for
EnvParamSpec.encoding in the relevant env-params test to expect None instead of
CategoricalEncoding(). Preserve categorical compatibility coverage through
EnvParams.from_test() inference rather than the direct default-value test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 9f9349aa-b0fb-4e78-bcb1-d86af9d3bc79

📥 Commits

Reviewing files that changed from the base of the PR and between af61b59 and e976078.

📒 Files selected for processing (2)
  • src/cloudai/configurator/env_params.py
  • tests/test_env_params.py

@KhushviB KhushviB force-pushed the feature/env-params-encoding-inference branch from e976078 to 9a70619 Compare July 13, 2026 17:12

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/cloudai/configurator/env_params.py (2)

180-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the stale EnvParamSpec docstring.

The class docstring still says omitted encoding defaults to a categorical index, but it now defaults to None and is inferred from candidates.

Proposed wording
-    ``encoding`` (optional) selects how the drawn value is exposed to the policy as an observation leaf, defaulting to a categorical index.
+    ``encoding`` (optional) selects how the drawn value is exposed to the policy as an observation leaf; when omitted, it is inferred from candidates.

Based on learnings, production classes should maintain meaningful and accurate docstrings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cloudai/configurator/env_params.py` around lines 180 - 182, Update the
EnvParamSpec class docstring to state that an omitted encoding defaults to None
and is inferred from candidates, replacing the stale categorical-index default
description. Keep the rest of the docstring unchanged.

Source: Learnings


138-139: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Exclude bool from inferred log encodings.

Because bool subclasses int, [True, 2, 4] is classified as geometric and produces LogEncoding. Treat any boolean-containing candidate list as categorical, matching the explicit-log validation path, and add a regression test.

Proposed fix
-    if not all(isinstance(c, (int, float)) and c > 0 for c in candidates):
+    if not all(
+        isinstance(c, (int, float))
+        and not isinstance(c, bool)
+        and c > 0
+        for c in candidates
+    ):
         return CategoricalEncoding()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cloudai/configurator/env_params.py` around lines 138 - 139, Update the
candidate validation in the inferred log-encoding logic to explicitly reject
bool values before accepting numeric candidates, so any list containing booleans
returns CategoricalEncoding. Keep valid int/float candidates eligible for
geometric inference, and add a regression test covering a boolean-containing
list such as [True, 2, 4].
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cloudai/configurator/env_params.py`:
- Around line 278-279: Update the candidate-type validation in the LogEncoding
configuration logic to raise TypeError, rather than ValueError, when a candidate
is a string, boolean, or otherwise non-numeric; update the corresponding
assertions in tests/test_env_params.py to expect TypeError while preserving
ValueError for other invalid-value cases.

---

Outside diff comments:
In `@src/cloudai/configurator/env_params.py`:
- Around line 180-182: Update the EnvParamSpec class docstring to state that an
omitted encoding defaults to None and is inferred from candidates, replacing the
stale categorical-index default description. Keep the rest of the docstring
unchanged.
- Around line 138-139: Update the candidate validation in the inferred
log-encoding logic to explicitly reject bool values before accepting numeric
candidates, so any list containing booleans returns CategoricalEncoding. Keep
valid int/float candidates eligible for geometric inference, and add a
regression test covering a boolean-containing list such as [True, 2, 4].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 7a21b3f7-deca-466a-9f32-be9d3a285d08

📥 Commits

Reviewing files that changed from the base of the PR and between e976078 and 9a70619.

📒 Files selected for processing (2)
  • src/cloudai/configurator/env_params.py
  • tests/test_env_params.py

Comment thread src/cloudai/configurator/env_params.py Outdated
@KhushviB KhushviB force-pushed the feature/env-params-encoding-inference branch from 9a70619 to 6d4e258 Compare July 13, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant