Move OrtModelPackageApi to the experimental C API#28990
Merged
Conversation
Move the model package C surface off the stable OrtApi onto the experimental name-based lookup added in #28746. Each function is registered individually in onnxruntime_experimental_c_api.inc with the OrtModelPackageApi_ prefix and the _SinceV28 version suffix, matching the lifecycle rules in docs/design/Experimental_C_API.md. - Drop the OrtModelPackageApi struct, OrtApi::GetModelPackageApi, the OrtModelPackageAPI namespace, model_package_api.h, and the C++ wrappers/release glue in onnxruntime_cxx_api.h. - Move the OrtModelPackageOptions/Context/ComponentContext opaque handle decls into onnxruntime_experimental_c_api.h. - Add forward decls in experimental_c_api.cc so the registration table can take addresses of bodies defined in model_package_api.cc. - Rename impls into namespace OrtExperimentalApis with the _SinceV28 suffix; bodies unchanged. - Drop the Python bindings; per the design doc we start the experimental API in C/C++ only and prove it out before exposing it to Python. - Update the autoep gtest to use a local ModelPackageFns struct populated through Ort::Experimental::Get_*_Fn lookups. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Drop the two CxxWrappers_* tests that depended on the removed Ort::ModelPackageContext / Ort::ModelPackageOptions C++ wrappers. - Replace remaining pkg_api->X call sites with pkg_api.X now that GetModelPackageFns() returns a struct by reference. - Replace ASSERT_NE(pkg_api, nullptr) with a null check on a canonical function pointer. - Capture pkg_api by reference in lambdas. - Drop a leftover Ort::ModelPackageOptions construction in FolderPath_ReturnsCorrectPath_WhenVariantJsonAbsent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
edgchen1
reviewed
Jun 10, 2026
Contributor
it is a starting point. if we have a need for exposing experimental APIs in Python, we can explore how to do that. |
chilo-ms
reviewed
Jun 10, 2026
…kageApi_* Mirror the documentation prose from the original OrtModelPackageApi struct in onnxruntime_c_api.h. Cross-references are updated to the new OrtModelPackageApi_* symbol names, and the OrtStatusPtr return boilerplate is pulled in via the snippets.dox helper to match the existing test sentinel's style. Addresses review feedback from edgchen1. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GetModelPackageFns() previously accepted a nullptr from any failed lookup, so a typo in the .inc symbol name would crash a test on a null function-pointer call rather than surface as a clear error. Centralize the validation in the lazy init via a small RESOLVE macro that throws std::runtime_error naming the missing entry. gtest reports the throw as a test failure with the symbol name in the message. The per-test ASSERT_NE(pkg_api.CreateModelPackageContext, ...) lines are now redundant and removed. Addresses review feedback from chilo-ms. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
edgchen1
reviewed
Jun 10, 2026
edgchen1
approved these changes
Jun 10, 2026
chilo-ms
approved these changes
Jun 10, 2026
jambayk
added a commit
that referenced
this pull request
Jul 1, 2026
### Description
Builds out the standalone `model_package/` C library so a single library
covers the full lifecycle of an ONNX Runtime model package: inspection,
authoring, content-addressed shared assets, commit, prune, and
validation.
The library remains free of any dependency on ONNX Runtime itself.
**Public C API (`model_package/include/model_package.h`)**
- Lifecycle: `ModelPackage_Open` / `ModelPackage_New` /
`ModelPackage_Close`,
with `ModelPackageOpenOptions` controlling external-path access, symlink
following, and strict unknown-field handling.
- Inspection: a POD `ModelPackageInfo` tree (`ModelPackage_Info`) plus
by-name lookups for components, variants, and per-namespace
`executor_info` entries, and round-trip JSON getters that preserve
fields unknown to the current build.
- Path resolution: `ModelPackage_ResolveStringRef` implements the
package's
resolution rules — relative paths anchored at a base directory,
`sha256:<hex>[/sub/path]` for shared-asset content, and portable vs
installed confinement (absolute paths and `..` segments only allowed
under `layout: "installed"`).
- Shared assets: SHA-256 directory hashing,
`ModelPackage_AddSharedAsset`
(with reproducible-build URI check and an optional `copy_in` staging
mode), `ModelPackage_RemoveSharedAsset`, and
`ModelPackage_ResolveAssetUri`. Assets under
`<package_root>/shared_assets/` are auto-discovered at `Open`.
- Authoring: inline/external component setters, variant upsert/remove,
per-namespace executor_info setters (inline and external), and
package-level metadata / layout / `additional_metadata` setters.
Mutations invalidate cached pointers in the mutated scope and its
descendants.
- Commit / prune / validate: `ModelPackage_Commit` writes the in-memory
model to disk either in place or to a fresh `dest_root` ("save as"),
with `PRESERVE` or `DENSE` write modes; `ModelPackage_Prune` reclaims
unreferenced files under `shared_assets/` and tracked orphan
variant/component directories left behind by removals; and
`ModelPackage_Validate` runs schema, path-reachability, asset-rehash,
and unknown-field checks and returns a JSON report.
- Errors: opaque `ModelPackageStatus*` with a stable additive
`ModelPackageErrorCode` enum (IO, schema, version, path confinement,
asset missing, asset hash mismatch, not found, invalid arg, state).
**Internal layout**
The implementation is split into focused translation units:
`manifest_parser`, `model_package_impl`, `authoring`,
`commit_prune_validate`, `path_resolver`, `asset_hasher`, and an
in-tree `sha256`. Shared error plumbing lives in `status_impl.h`.
**ONNX Runtime integration (`onnxruntime/core/session/model_package/`)**
The ORT-side glue is wired onto the library through the C inspection
and path-resolution entry points. `model_package_context` now translates
the library's info tree into ORT-internal structs and parses the
`executor_info["ort"]` payload (`model_file`, `external_data`,
`session_options`, `provider_options`). When a variant declares
`external_data`, `CreateSessionForModelPackage` loads the model from a
memory mapping and passes the resolved folder to the session via
`kOrtSessionOptionsModelExternalInitializersFileFolderPath`, so external
initializers — including those backed by a shared asset — are picked up
at `Initialize` time.
The experimental `OrtModelPackageApi_*_SinceV28` C entries introduced in
#28990 are unchanged.
**Documentation and tests**
- `model_package/README.md` documents the on-disk layout, manifest and
component schemas, shared-asset rules, path resolution, the authoring
flow, and commit / prune / validate semantics.
- `onnxruntime/core/session/model_package/README.md` documents the ORT
consumer-side glue: the `executor_info["ort"]` schema, the variant
selection algorithm, the session-creation contract, and the registered
experimental C entries.
- New library tests cover inspection, authoring, asset hashing, and
commit (`model_package/tests/`). The ORT integration tests in
`onnxruntime/test/autoep/test_model_package.cc` are reworked against
the current C API surface.
### Motivation and Context
ORT needs a single library that owns the model package format end to
end — not just reading it, but producing it, validating it, and
maintaining it on disk with content-addressed shared assets.
Consolidating this behind one C API lets ORT, publisher tooling, and
third-party consumers share the same parser, path-resolution rules, and
on-disk invariants without each reimplementing them, and keeps the
library independent of the ORT session runtime.
---------
Co-authored-by: jambayk <jambayk@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: jambayk <jambay@github.com>
feich-ms
pushed a commit
that referenced
this pull request
Jul 3, 2026
### Description
Builds out the standalone `model_package/` C library so a single library
covers the full lifecycle of an ONNX Runtime model package: inspection,
authoring, content-addressed shared assets, commit, prune, and
validation.
The library remains free of any dependency on ONNX Runtime itself.
**Public C API (`model_package/include/model_package.h`)**
- Lifecycle: `ModelPackage_Open` / `ModelPackage_New` /
`ModelPackage_Close`,
with `ModelPackageOpenOptions` controlling external-path access, symlink
following, and strict unknown-field handling.
- Inspection: a POD `ModelPackageInfo` tree (`ModelPackage_Info`) plus
by-name lookups for components, variants, and per-namespace
`executor_info` entries, and round-trip JSON getters that preserve
fields unknown to the current build.
- Path resolution: `ModelPackage_ResolveStringRef` implements the
package's
resolution rules — relative paths anchored at a base directory,
`sha256:<hex>[/sub/path]` for shared-asset content, and portable vs
installed confinement (absolute paths and `..` segments only allowed
under `layout: "installed"`).
- Shared assets: SHA-256 directory hashing,
`ModelPackage_AddSharedAsset`
(with reproducible-build URI check and an optional `copy_in` staging
mode), `ModelPackage_RemoveSharedAsset`, and
`ModelPackage_ResolveAssetUri`. Assets under
`<package_root>/shared_assets/` are auto-discovered at `Open`.
- Authoring: inline/external component setters, variant upsert/remove,
per-namespace executor_info setters (inline and external), and
package-level metadata / layout / `additional_metadata` setters.
Mutations invalidate cached pointers in the mutated scope and its
descendants.
- Commit / prune / validate: `ModelPackage_Commit` writes the in-memory
model to disk either in place or to a fresh `dest_root` ("save as"),
with `PRESERVE` or `DENSE` write modes; `ModelPackage_Prune` reclaims
unreferenced files under `shared_assets/` and tracked orphan
variant/component directories left behind by removals; and
`ModelPackage_Validate` runs schema, path-reachability, asset-rehash,
and unknown-field checks and returns a JSON report.
- Errors: opaque `ModelPackageStatus*` with a stable additive
`ModelPackageErrorCode` enum (IO, schema, version, path confinement,
asset missing, asset hash mismatch, not found, invalid arg, state).
**Internal layout**
The implementation is split into focused translation units:
`manifest_parser`, `model_package_impl`, `authoring`,
`commit_prune_validate`, `path_resolver`, `asset_hasher`, and an
in-tree `sha256`. Shared error plumbing lives in `status_impl.h`.
**ONNX Runtime integration (`onnxruntime/core/session/model_package/`)**
The ORT-side glue is wired onto the library through the C inspection
and path-resolution entry points. `model_package_context` now translates
the library's info tree into ORT-internal structs and parses the
`executor_info["ort"]` payload (`model_file`, `external_data`,
`session_options`, `provider_options`). When a variant declares
`external_data`, `CreateSessionForModelPackage` loads the model from a
memory mapping and passes the resolved folder to the session via
`kOrtSessionOptionsModelExternalInitializersFileFolderPath`, so external
initializers — including those backed by a shared asset — are picked up
at `Initialize` time.
The experimental `OrtModelPackageApi_*_SinceV28` C entries introduced in
#28990 are unchanged.
**Documentation and tests**
- `model_package/README.md` documents the on-disk layout, manifest and
component schemas, shared-asset rules, path resolution, the authoring
flow, and commit / prune / validate semantics.
- `onnxruntime/core/session/model_package/README.md` documents the ORT
consumer-side glue: the `executor_info["ort"]` schema, the variant
selection algorithm, the session-creation contract, and the registered
experimental C entries.
- New library tests cover inspection, authoring, asset hashing, and
commit (`model_package/tests/`). The ORT integration tests in
`onnxruntime/test/autoep/test_model_package.cc` are reworked against
the current C API surface.
### Motivation and Context
ORT needs a single library that owns the model package format end to
end — not just reading it, but producing it, validating it, and
maintaining it on disk with content-addressed shared assets.
Consolidating this behind one C API lets ORT, publisher tooling, and
third-party consumers share the same parser, path-resolution rules, and
on-disk invariants without each reimplementing them, and keeps the
library independent of the ORT session runtime.
---------
Co-authored-by: jambayk <jambayk@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: jambayk <jambay@github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Move the existing model package C API off the stable
OrtApionto the experimental name-based lookup mechanism added in #28746. Each model package function is registered individually ininclude/onnxruntime/core/session/onnxruntime_experimental_c_api.incwith theOrtModelPackageApi_prefix and the_SinceV28version suffix, following the lifecycle rules indocs/design/Experimental_C_API.md.Headline changes:
OrtApi::GetModelPackageApi, theOrtModelPackageApistruct,OrtApis::GetModelPackageApi, theOrtModelPackageAPInamespace,onnxruntime/core/session/model_package_api.h, and the C++ wrappers (Ort::GetModelPackageApi,ORT_DEFINE_RELEASE_FROM_API_STRUCT(ModelPackage*),ModelPackageOptions/Context/ComponentContext) are removed.OrtModelPackageOptions,OrtModelPackageContext,OrtModelPackageComponentContext) move intoonnxruntime_experimental_c_api.h.onnxruntime_experimental_c_api.inc. Impls move intonamespace OrtExperimentalApiswith_SinceV28-suffixed names inmodel_package_api.cc; bodies are unchanged.experimental_c_api.ccgains a forward-decl block (driven by the same.incX-macro) so the auto-generated registration table can take the address of every entry, even those defined inmodel_package_api.cc.PyModelPackageContext/PyModelPackageOptions/PyModelPackageComponentContextand theironnxruntime.__init__exports) are removed. Per the design doc we start the experimental API in C/C++ only.onnxruntime/test/autoep/test_model_package.ccswitches to a localModelPackageFnsstruct populated through theOrt::Experimental::Get_OrtModelPackageApi_*_Fn(api)typed accessors.Consumer usage going forward, in C++:
Motivation and Context
The model package API was added to the stable
OrtApiin 1.27 but has not shipped in a release yet. Now that #28746 has landed the experimental C API framework, the right home for an iterating preview surface like model package is behindOrtApi::GetExperimentalFunction, not on the stable struct.Moving it to experimental:
OrtApi, drop the_SinceV<N>suffix, remove the experimental entries).