Skip to content

Add native step_size support to RangeParameter (#5213)#5213

Open
saitcakmak wants to merge 1 commit into
facebook:mainfrom
saitcakmak:export-D107274057
Open

Add native step_size support to RangeParameter (#5213)#5213
saitcakmak wants to merge 1 commit into
facebook:mainfrom
saitcakmak:export-D107274057

Conversation

@saitcakmak
Copy link
Copy Markdown
Contributor

@saitcakmak saitcakmak commented Jun 2, 2026

Summary:

Adds a step_size arg to RangeParameter that snaps values to a grid anchored at lower (in cast()), for both FLOAT and INT parameters. This is the first diff in the step_size unification stack: step_size will subsume both the discrete-grid and limited-resolution (digits) use cases under one knob.

  • Next diff will add storage support. The internal DB has already been updated to include the new column.
  • We will then migrate all current usage off digits and onto step_size.
  • We will add support for treating low-cardinality float-range parameters as discrete in Adapter, so that it is efficiently optimized over the correct grid (rather than having to use continuous optimization + rounding).
  • At this point, we will have proper support for step_size, so we can update the ax/api usage to leverage it, rather than resolving to ChoiceParameter.
  • We can then deprecate digits and do any remaining clean-up.

In this diff step_size coexists with the existing digits arg (they are mutually exclusive at construction). Subsequent diffs in the stack migrate storage (JSON + SQA), transforms and utils, and the public API (RangeParameterConfig) to step_size, then deprecate digits in favor of it.

Behavior:

  • cast() rounds (value - lower) / step_size to the nearest integer and returns lower + n * step_size. It does NOT clamp to [lower, upper]: an out-of-bounds input (e.g. a historical observation recorded outside the current bounds) snaps to the nearest grid point, which may itself be out of bounds. This mirrors the non-step_size cast(), which leaves out-of-bounds values in place rather than silently moving them into range — range validity is enforced by validate(), not cast().
  • Both bounds must lie on the grid: (upper - lower) must be an integer multiple of step_size (within EPS). Off-grid bounds are rejected at construction. This guarantees upper is itself a feasible value, so a value near the upper bound snaps to upper rather than to a grid point short of it.
  • step_size must be strictly positive, and must be integer-valued for INT parameters.
  • cardinality() accounts for step_size: a grid-valued FLOAT reports the finite number of grid points instead of inf, and a grid-valued INT counts grid points rather than every integer in [lower, upper].

step_size defines a discrete grid but does not, by itself, force discrete acquisition optimization; how the optimizer treats the parameter depends on the grid cardinality and is determined at the generator level.

Differential Revision: D107274057

@meta-cla meta-cla Bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Jun 2, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented Jun 2, 2026

@saitcakmak has exported this pull request. If you are a Meta employee, you can view the originating Diff in D107274057.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jun 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.51%. Comparing base (d0ae700) to head (b575948).

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #5213    +/-   ##
========================================
  Coverage   96.50%   96.51%            
========================================
  Files         617      617            
  Lines       69776    69889   +113     
========================================
+ Hits        67339    67452   +113     
  Misses       2437     2437            

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Summary:

Adds a `step_size` arg to `RangeParameter` that snaps values to a grid anchored at `lower` (in `cast()`), for both FLOAT and INT parameters. This is the first diff in the step_size unification stack: `step_size` will subsume both the discrete-grid and limited-resolution (`digits`) use cases under one knob.
- Next diff will add storage support. The internal DB has already been updated to include the new column.
- We will then migrate all current usage off `digits` and onto `step_size`.
- We will add support for treating low-cardinality float-range parameters as discrete in `Adapter`, so that it is efficiently optimized over the correct grid (rather than having to use continuous optimization + rounding).
- At this point, we will have proper support for `step_size`, so we can update the ax/api usage to leverage it, rather than resolving to `ChoiceParameter`.
- We can then deprecate `digits` and do any remaining clean-up.

In this diff `step_size` coexists with the existing `digits` arg (they are mutually exclusive at construction). Subsequent diffs in the stack migrate storage (JSON + SQA), transforms and utils, and the public API (`RangeParameterConfig`) to `step_size`, then deprecate `digits` in favor of it.

Behavior:
- `cast()` rounds `(value - lower) / step_size` to the nearest integer and returns `lower + n * step_size`. It does NOT clamp to `[lower, upper]`: an out-of-bounds input (e.g. a historical observation recorded outside the current bounds) snaps to the nearest grid point, which may itself be out of bounds. This mirrors the non-`step_size` `cast()`, which leaves out-of-bounds values in place rather than silently moving them into range — range validity is enforced by `validate()`, not `cast()`.
- Both bounds must lie on the grid: `(upper - lower)` must be an integer multiple of `step_size` (within `EPS`). Off-grid bounds are rejected at construction. This guarantees `upper` is itself a feasible value, so a value near the upper bound snaps to `upper` rather than to a grid point short of it.
- `step_size` must be strictly positive, and must be integer-valued for INT parameters.
- `cardinality()` accounts for `step_size`: a grid-valued FLOAT reports the finite number of grid points instead of `inf`, and a grid-valued INT counts grid points rather than every integer in `[lower, upper]`.

`step_size` defines a discrete grid but does not, by itself, force discrete acquisition optimization; how the optimizer treats the parameter depends on the grid cardinality and is determined at the generator level.

Differential Revision: D107274057
@meta-codesync meta-codesync Bot changed the title Add native step_size support to RangeParameter Add native step_size support to RangeParameter (#5213) Jun 3, 2026
@saitcakmak saitcakmak force-pushed the export-D107274057 branch from c439254 to b575948 Compare June 3, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Do not delete this pull request or issue due to inactivity. fb-exported meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants