Skip to content

Rename ExaModelsC to ExaModelsCompiler; publish a model's named blocks - #311

Merged
sshin23 merged 2 commits into
mainfrom
anvil/rename-compiler
Aug 14, 2026
Merged

Rename ExaModelsC to ExaModelsCompiler; publish a model's named blocks#311
sshin23 merged 2 commits into
mainfrom
anvil/rename-compiler

Conversation

@sshin23

@sshin23 sshin23 commented Aug 14, 2026

Copy link
Copy Markdown
Member

Three changes that belong together, since they touch the same files.

Rename: ExaModelsCExaModelsCompiler

ExaModelsC sits one character from ExaModels, inside General's AutoMerge name-similarity cutoff (Damerau-Levenshtein 1, cutoff 2; lowercase cutoff 1) — registrable only with a maintainer waiver, as QiskitIBMRuntimeC needed. ExaModelsCompiler clears the check and says what the package does; the rest of the family already sits well clear (MadNLPGPU 3, ExaModelsPower 5). Git records it as a rename, so the diff is the real delta rather than a re-add.

Named blocks, published and queryable

@add_var(c, x, ...) registers x, and until now a consumer holding only a compiled library had no way to learn that. Each model now publishes its named variable, constraint and parameter blocks — kind, offset, length and dims — through P_nblocks / P_block / P_block_name, plus P_get_value / P_set_value for parameters. The layout is instance state: a recipe instantiated at another size reports that size's offsets, which is why every accessor takes an id.

In ExaModels itself:

get_vars(m)          # (x = Variable, y = Variable)   — named blocks, by kind
get_vars(m, :x)      # one of them; get_cons / get_pars likewise

A name of the wrong kind names the accessor that would work; a typo lists what exists — the blocks share one flat namespace, so both mistakes are easy and want different fixes.

The consumers mirror it exactly (CNLPModels.jl, cnlpmodels, both already on master), so a compiled model is addressed the way an in-Julia one is:

solution(result, get_vars(m, :pg))     # reshaped to the block's own dims
multipliers(result, get_cons(m, :balance))
set_value!(m, get_pars(m, :load), new_demand)

Named blocks are an optional ABI surface: a library that publishes none — a hand-written C library, say — reports empty tuples and is consumed exactly as before.

Parameters: one vocabulary, and a model owns its values

set_parameter! is gone; set_value! is the only spelling, paired with get_value, matching the two-stage methods that already used those names. Core-level methods were the ones missing and are now present.

A model copies the core's parameter vector when it is built. instantiate passes a placeholder-free container through by identity, so without the copy every model built from one core shared one θ — setting a parameter on one compiled instance set it on all, and two instances at different sizes would have shared one vector. The suite's assertion that instances are independent is what would catch losing this again.

The consequence is deliberate and user-visible: after a model is built, updates go to the model, not the core.

m = ExaModel(c)
set_value!(m, θ, [200.0, 1.0])   # not set_value!(c, θ, ...)

The parameters doc page and the "Modify after build" testset were the two places telling the old story and now tell this one. Calls that precede the build are unchanged, since the copy takes the values as they stand. What this buys: several models from one core, each with its own parameters — and several compiled instances in one library likewise.

Also dropped: the schema's ABI version field. Versioning an interface buys nothing before the packages are registered.

Verification

suite result
ExaModelsCompiler 236 / 236 (incl. a five-model library exercising all four instantiation surfaces, per-instance layout at unseen sizes, and a parameter write reaching evaluation)
CNLPModels.jl passed, named blocks 20/20
cnlpmodels-py 31 passed, 1 skipped
ExaModels re-running at the time of writing — the previous run was 1613/6, all six the "Modify after build" workflow this branch's last commit fixes. Do not merge before it reports green; I will post the number here.

🤖 Generated with Claude Code

sshin23 and others added 2 commits August 14, 2026 04:45
Three changes that belong together, since they touch the same files.

RENAME. ExaModelsC sat one character from ExaModels, which is inside
General's AutoMerge name-similarity cutoff (Damerau-Levenshtein 1,
cutoff 2) — registrable only with a maintainer waiver, as
QiskitIBMRuntimeC needed. ExaModelsCompiler clears it and says what the
package does; the ExaModels family already sits well clear
(MadNLPGPU 3, ExaModelsPower 5).

NAMED BLOCKS. A compiled library now publishes which named variable,
constraint and parameter blocks its model has — kind, offset, length
and dims — through P_nblocks / P_block / P_block_name, plus
P_get_value / P_set_value for parameters. The layout is instance state:
a recipe instantiated at another size reports that size's offsets.
In ExaModels itself, get_vars / get_cons / get_pars return the named
blocks of each kind, by name or all at once.

PARAMETERS ARE PER MODEL. set_parameter! is now set_value!, paired with
get_value, matching the two-stage vocabulary; and a model copies the
core's parameter vector when it is built. Without that copy every model
from one core shared one θ — instantiate passes a placeholder-free
container through by identity — so setting a parameter on one compiled
instance set it on all. The suite's assertion that instances are
independent is what would catch losing it.

The schema's version field is dropped: versioning an ABI buys nothing
before the packages are registered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A model copies the core's parameter vector when it is built, so after
that point the core is the blueprint and the model owns the values.
The two after-build sites — the parameter suite's "Modify after build"
testset and the parameters doc page — now call set_value! on the model;
calls that precede the build are unchanged, since the copy takes the
values as they stand.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Your PR requires formatting changes to meet the project's style guidelines.

Please run:

julia --project=@runic -e 'using Pkg; Pkg.add("Runic")'
julia --project=@runic -e "using Runic; exit(Runic.main(ARGS))" -- --fix <files>

(or git runic main if you have the git wrapper installed)

Note: the full diff is omitted because it can exceed GitHub Actions input limits.

@sshin23

sshin23 commented Aug 14, 2026

Copy link
Copy Markdown
Member Author

The ExaModels suite is green on the branch tip: 1619 passed, 0 failed, 2 broken (26m45s) — matching main's own baseline exactly.

The six failures on the previous run were all the Modify after build workflow, which updated parameters through the core after the model existed. That is the one behavior the per-model parameter copy deliberately ends; the testset and the parameters doc page now update through the model, and calls that precede the build are unchanged.

Full gate set for this branch:

suite result
ExaModels 1619 / 0 / 2 broken
ExaModelsCompiler 236 / 236
CNLPModels.jl passed (named blocks 20/20)
cnlpmodels-py 31 passed, 1 skipped

The two consumers are already on their masters, so this branch is the last piece.

🤖 Generated with Claude Code

@sshin23
sshin23 merged commit d103132 into main Aug 14, 2026
22 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results


Relative timing: current / main  (values < 1.0 are improvements)

================================================================================
  backend-instance-param          |      obj     cons     grad      jac     hess
================================================================================
  CUDA-OPF-case1354               |    0.956    0.998    0.973    0.982    0.996
  CUDA-OPF-case14                 |    0.998    0.978    0.969    0.973    0.995
  CUDA-OPF-case30000              |    0.961    0.996    0.977    0.981    0.988
  CUDA-chain-10                   |    0.930    0.971    0.971    0.977    0.968
  CUDA-chain-100                  |    0.924    0.965    0.974    0.974    0.964
  CUDA-chain-1000                 |    0.919    0.964    0.974    0.973    0.969
  CUDA-elec-10                    |    0.964    1.094    0.969    0.982    0.977
  CUDA-elec-100                   |    0.888    1.028    0.942    0.981    0.971
  CUDA-elec-1000                  |    0.922    0.968    0.120    0.938    1.311
  CUDA-rosenrock-1000             |    1.015    0.982    0.971    0.988    0.968
  CUDA-rosenrock-10000            |    0.964    1.091    1.000    0.990    0.969
  CUDA-rosenrock-100000           |    0.966    0.978    0.972    0.987    1.542
--------------------------------------------------------------------------------
  AMDGPU-OPF-case1354             |    0.977    1.054    1.036    1.023    1.040
  AMDGPU-OPF-case14               |    1.003    1.071    1.028    1.053    1.063
  AMDGPU-OPF-case30000            |    0.968    1.055    1.041    1.025    1.058
  AMDGPU-chain-10                 |    0.977    1.022    0.989    1.040    1.031
  AMDGPU-chain-100                |    0.952    1.025    1.036    1.039    1.060
  AMDGPU-chain-1000               |    0.968    1.037    1.029    1.046    1.053
  AMDGPU-elec-10                  |    0.973    1.026    1.017    0.978    1.050
  AMDGPU-elec-100                 |    0.976    1.010    1.018    1.023    1.040
  AMDGPU-elec-1000                |    0.969    1.028    0.806    0.972    1.004
  AMDGPU-rosenrock-1000           |    0.981    1.051    1.047    1.072    1.002
  AMDGPU-rosenrock-10000          |    0.943    0.961    0.982    1.024    1.029
  AMDGPU-rosenrock-100000         |    0.987    1.043    1.023    1.017    0.971
--------------------------------------------------------------------------------
  oneAPI-OPF-case1354             |    2.938    0.895    1.131    1.574    0.968
  oneAPI-OPF-case14               |    0.901    1.554    1.149    1.164    1.713
  oneAPI-OPF-case30000            |    1.004    0.830    1.426    0.836    1.882
  oneAPI-chain-10                 |    0.934    1.210    0.872    3.938    3.539
  oneAPI-chain-100                |    2.703    1.156    1.300   17.644    1.122
  oneAPI-chain-1000               |    0.853    1.469    1.492    3.118    2.116
  oneAPI-elec-10                  |    0.621    0.958    1.053    0.120    1.303
  oneAPI-elec-100                 |    0.318    2.042    1.304    1.216    1.034
  oneAPI-elec-1000                |    1.206   13.119    1.310    0.817    1.678
  oneAPI-rosenrock-1000           |    1.023    1.135    1.138    1.635    1.214
  oneAPI-rosenrock-10000          |    0.930    1.234    0.894    0.181    0.799
  oneAPI-rosenrock-100000         |    0.835    1.317    0.767    1.574    1.054
--------------------------------------------------------------------------------
  nothing-OPF-case1354            |    1.003    1.040    1.050    1.039    0.961
  nothing-OPF-case14              |    1.084    1.020    0.960    0.984    0.997
  nothing-OPF-case30000           |    0.997    1.005    1.041    0.982    1.003
  nothing-chain-10                |    1.745    0.989    1.545    0.968    1.041
  nothing-chain-100               |    1.804    1.042    1.101    0.937    3.016
  nothing-chain-1000              |    1.775    1.056    1.005    0.934    0.849
  nothing-elec-10                 |    0.999    0.913    0.999    1.054    1.015
  nothing-elec-100                |    0.998    1.005    1.001    0.994    1.001
  nothing-elec-1000               |    1.007    1.000    1.000    1.005    0.991
  nothing-rosenrock-1000          |    1.074    0.873    1.016    0.948    0.697
  nothing-rosenrock-10000         |    1.070    0.999    0.975    1.071    0.999
  nothing-rosenrock-100000        |    0.921    1.328    1.450    1.012    1.062
================================================================================

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