diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h
index 0cdbfd7114cf0..0289bca5c84d2 100644
--- a/include/onnxruntime/core/session/onnxruntime_c_api.h
+++ b/include/onnxruntime/core/session/onnxruntime_c_api.h
@@ -348,9 +348,6 @@ ORT_RUNTIME_CLASS(ExternalSemaphoreHandle); // EP-imported view of shared exte
ORT_RUNTIME_CLASS(DeviceEpIncompatibilityDetails);
ORT_RUNTIME_CLASS(EpAssignedSubgraph);
ORT_RUNTIME_CLASS(EpAssignedNode);
-ORT_RUNTIME_CLASS(ModelPackageOptions);
-ORT_RUNTIME_CLASS(ModelPackageContext);
-ORT_RUNTIME_CLASS(ModelPackageComponentContext);
#ifdef _MSC_VER
typedef _Return_type_success_(return == 0) OrtStatus* OrtStatusPtr;
@@ -938,9 +935,6 @@ typedef struct OrtCompileApi OrtCompileApi;
struct OrtInteropApi;
typedef struct OrtInteropApi OrtInteropApi;
-struct OrtModelPackageApi;
-typedef struct OrtModelPackageApi OrtModelPackageApi;
-
struct OrtEpApi;
typedef struct OrtEpApi OrtEpApi;
@@ -7501,26 +7495,6 @@ struct OrtApi {
*/
ORT_API2_STATUS(SessionReleaseCapturedGraph, _In_ OrtSession* session, _In_ int graph_annotation_id);
- /** \brief Get the model package API table.
- *
- * Returns a pointer to the ::OrtModelPackageApi function table, which provides APIs to:
- * - create and release model package options and contexts,
- * - inspect model package metadata (components/variants),
- * - select a component/variant and query selected files/options,
- * - create a session from model package selection results.
- *
- * The returned pointer is owned by ONNX Runtime and is valid for the process lifetime.
- * Do not free it.
- *
- * \note May return NULL if model package support is not available in the current build
- * (for example, minimal builds).
- *
- * \return Pointer to ::OrtModelPackageApi, or NULL if unsupported.
- *
- * \since Version 1.27.
- */
- const OrtModelPackageApi*(ORT_API_CALL* GetModelPackageApi)(void);
-
/** \brief Retrieve an experimental function pointer by name.
*
* Experimental functions are not part of the stable ABI and may be added or removed between releases without notice.
@@ -8645,250 +8619,6 @@ struct OrtInteropApi {
/// @}
};
-/** \brief API table for model package workflows.
- *
- * A model package is a directory containing one or more *components* (logical models).
- * Each component has one or more *variants*, where each variant targets a single
- * execution provider (EP). The package manifest declares the EP name, device type,
- * and an optional compatibility string for every variant so that the runtime can
- * automatically select the best variant for the hardware and EPs available in the
- * caller's session options.
- *
- * Obtain this table from OrtApi::GetModelPackageApi(). The APIs support:
- * - creating model package options that capture EP configuration from OrtSessionOptions,
- * - loading a package context (manifest + metadata) from a package root path,
- * - querying component/variant metadata including per-variant EP information,
- * - selecting a component (which also resolves the best-matching variant),
- * - querying the selected variant's name and folder path,
- * - creating an OrtSession from the selected component context.
- *
- * Typical flow:
- * 1) Create model package options:
- * - CreateModelPackageOptionsFromSessionOptions()
- * 2) Load package metadata:
- * - CreateModelPackageContext()
- * 3) Query metadata (optional):
- * - ModelPackage_GetSchemaVersion()
- * - ModelPackage_GetComponentCount()
- * - ModelPackage_GetComponentNames()
- * - ModelPackage_GetVariantCount()
- * - ModelPackage_GetVariantNames()
- * - ModelPackage_GetVariantEpName()
- * 4) Select a component and resolve variant:
- * - SelectComponent()
- * 5) Query selected variant info (optional):
- * - ModelPackageComponent_GetSelectedVariantName()
- * - ModelPackageComponent_GetSelectedVariantFolderPath()
- * 6) Create session:
- * - CreateSession()
- *
- * Ownership:
- * - Release objects created by this API with the corresponding release methods:
- * ReleaseModelPackageOptions(), ReleaseModelPackageContext(),
- * ReleaseModelPackageComponentContext().
- *
- * \since Version 1.27.
- */
-struct OrtModelPackageApi {
- /// \name OrtModelPackageOptions
- /// @{
-
- /** \brief Create model package options from an existing OrtSessionOptions.
- *
- * Captures EP configuration (registered execution providers and their devices) from
- * the session options for use during variant selection. The resulting OrtModelPackageOptions
- * is passed to SelectComponent() to resolve the best variant for the available EPs.
- *
- * \param[in] env The ORT environment.
- * \param[in] session_options Session options containing registered EPs.
- * \param[out] out Receives the newly created OrtModelPackageOptions. Must be released
- * with ReleaseModelPackageOptions().
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(CreateModelPackageOptionsFromSessionOptions,
- _In_ const OrtEnv* env,
- _In_ const OrtSessionOptions* session_options,
- _Outptr_ OrtModelPackageOptions** out);
-
- ORT_CLASS_RELEASE(ModelPackageOptions);
- /// @}
- /// \name OrtModelPackageContext
- /// @{
-
- /** \brief Create a model package context by parsing the package at the given root path.
- *
- * Parses the manifest.json and component metadata from the specified directory.
- * The returned context provides read-only access to the package structure (components,
- * variants, EP declarations).
- *
- * \param[in] package_root Path to the model package root directory (containing manifest.json).
- * \param[out] out Receives the newly created OrtModelPackageContext. Must be released
- * with ReleaseModelPackageContext().
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(CreateModelPackageContext,
- _In_ const ORTCHAR_T* package_root,
- _Outptr_ OrtModelPackageContext** out);
-
- ORT_CLASS_RELEASE(ModelPackageContext);
-
- /** \brief Get the schema version declared in the model package manifest.
- *
- * \param[in] ctx The model package context.
- * \param[out] out_version Receives the schema version number.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackage_GetSchemaVersion,
- _In_ const OrtModelPackageContext* ctx,
- _Out_ int64_t* out_version);
-
- /** \brief Get the number of components in the model package.
- *
- * \param[in] ctx The model package context.
- * \param[out] out_count Receives the component count.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackage_GetComponentCount,
- _In_ const OrtModelPackageContext* ctx,
- _Out_ size_t* out_count);
-
- /** \brief Get the names of all components in the model package.
- *
- * Returns a pointer to an array of UTF-8 component name strings. The array and its
- * strings are owned by `ctx` and remain valid until the context is released.
- *
- * \param[in] ctx The model package context.
- * \param[out] out_names Receives a pointer to an array of component name strings.
- * \param[out] out_count Receives the number of elements in the array.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackage_GetComponentNames,
- _In_ const OrtModelPackageContext* ctx,
- _Outptr_result_buffer_maybenull_(*out_count) const char* const** out_names,
- _Out_ size_t* out_count);
-
- /** \brief Get the number of variants for a given component.
- *
- * \param[in] ctx The model package context.
- * \param[in] component_name Name of the component to query.
- * \param[out] out_count Receives the variant count.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackage_GetVariantCount,
- _In_ const OrtModelPackageContext* ctx,
- _In_ const char* component_name,
- _Out_ size_t* out_count);
-
- /** \brief Get the names of all variants for a given component.
- *
- * Returns a pointer to an array of UTF-8 variant name strings. The array and its
- * strings are owned by `ctx` and remain valid until the context is released.
- *
- * \param[in] ctx The model package context.
- * \param[in] component_name Name of the component to query.
- * \param[out] out_variant_names Receives a pointer to an array of variant name strings.
- * \param[out] out_count Receives the number of elements in the array.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackage_GetVariantNames,
- _In_ const OrtModelPackageContext* ctx,
- _In_ const char* component_name,
- _Outptr_result_buffer_maybenull_(*out_count) const char* const** out_variant_names,
- _Out_ size_t* out_count);
-
- /** \brief Get the EP name declared for a (component, variant) pair.
- *
- * Each variant targets a single EP. `out_ep` receives the EP name string.
- * When the variant does not declare an EP, the returned pointer is NULL.
- * String memory is owned by `ctx` and remains valid until the context is released.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackage_GetVariantEpName,
- _In_ const OrtModelPackageContext* ctx,
- _In_ const char* component_name,
- _In_ const char* variant_name,
- _Outptr_result_maybenull_ const char** out_ep);
-
- /** \brief Select a component model and return an opaque component instance.
- *
- * The variant selection is also performed during this call based on the component metadata and the provided options.
- * The returned `OrtModelPackgeComponentContext*` is independent of `context` lifetime and must be released via
- * `ReleaseComponentInstance`.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(SelectComponent,
- _In_ const OrtModelPackageContext* context,
- _In_ const char* component_name,
- _In_ const OrtModelPackageOptions* options,
- _Outptr_ OrtModelPackageComponentContext** out);
-
- ORT_CLASS_RELEASE(ModelPackageComponentContext);
-
- /** \brief Get the name of the selected variant after SelectComponent has been called.
- *
- * String memory is owned by `ctx` and remains valid until the context is released.
- *
- * \param[in] ctx The component context returned by SelectComponent().
- * \param[out] out_name Receives the selected variant's name string.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackageComponent_GetSelectedVariantName,
- _In_ const OrtModelPackageComponentContext* ctx,
- _Outptr_ const char** out_name);
-
- /** \brief Get the folder path of the selected variant.
- *
- * Returns the resolved absolute path to the variant's directory on disk.
- * The string is owned by `ctx` and remains valid until the context is released.
- *
- * \param[in] ctx The component context returned by SelectComponent().
- * \param[out] folder_path Receives the variant folder path string.
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(ModelPackageComponent_GetSelectedVariantFolderPath,
- _In_ const OrtModelPackageComponentContext* ctx,
- _Outptr_ const ORTCHAR_T** folder_path);
-
- /// @}
- /** \brief Create an OrtSession for a selected file within a component model variant.
- *
- * The chosen variant (and thus its EP selection) is determined by `context`, which
- * was built from an OrtSessionOptions via CreateModelPackageOptionsFromSessionOptions.
- *
- * Session options precedence:
- * 1. session_options == NULL (default path):
- * ORT uses the OrtSessionOptions that was captured when `context` was created.
- * Any variant-specific session and provider options declared in the package
- * metadata are merged on top.
- *
- * 2. session_options != NULL (advanced path):
- * ORT uses the caller-provided OrtSessionOptions as-is. Variant-specific
- * session and provider options from the package metadata are NOT applied.
- * Use this when custom EP setup is required (e.g., shared CUDA streams,
- * shared QNN EP contexts, custom allocators).
- *
- * \since Version 1.27.
- */
- ORT_API2_STATUS(CreateSession,
- _In_ const OrtEnv* env,
- _In_ OrtModelPackageComponentContext* context,
- _In_opt_ const OrtSessionOptions* session_options,
- _Outptr_ OrtSession** session);
-
- // End of Version 1.27 - DO NOT MODIFY ABOVE
-};
-
/*
* This is the old way to add the CUDA provider to the session, please use SessionOptionsAppendExecutionProvider_CUDA above to access the latest functionality
* This function always exists, but will only succeed if Onnxruntime was built with CUDA support and the CUDA provider shared library exists
diff --git a/include/onnxruntime/core/session/onnxruntime_cxx_api.h b/include/onnxruntime/core/session/onnxruntime_cxx_api.h
index a999ef5e0faf4..4798d3d4ad1b8 100644
--- a/include/onnxruntime/core/session/onnxruntime_cxx_api.h
+++ b/include/onnxruntime/core/session/onnxruntime_cxx_api.h
@@ -264,20 +264,6 @@ inline const OrtEpApi& GetEpApi() {
return *api;
}
-///
-/// This returns a reference to the ORT C Model Package API. Used for loading models from model packages.
-///
-/// ORT C Model Package API reference
-inline const OrtModelPackageApi& GetModelPackageApi() {
- auto* api = GetApi().GetModelPackageApi();
- if (api == nullptr) {
- // minimal build
- ORT_CXX_API_THROW("Model Package API is not available in this build", ORT_FAIL);
- }
-
- return *api;
-}
-
/** \brief IEEE 754 half-precision floating point data type
*
* \details This struct is used for converting float to float16 and back
@@ -678,9 +664,6 @@ ORT_DEFINE_RELEASE_FROM_API_STRUCT(KernelDefBuilder, GetEpApi);
ORT_DEFINE_RELEASE_FROM_API_STRUCT(KernelRegistry, GetEpApi);
ORT_DEFINE_RELEASE_FROM_API_STRUCT(OpSchema, GetEpApi);
ORT_DEFINE_RELEASE_FROM_API_STRUCT(ProfilingEvent, GetEpApi);
-ORT_DEFINE_RELEASE_FROM_API_STRUCT(ModelPackageOptions, GetModelPackageApi);
-ORT_DEFINE_RELEASE_FROM_API_STRUCT(ModelPackageContext, GetModelPackageApi);
-ORT_DEFINE_RELEASE_FROM_API_STRUCT(ModelPackageComponentContext, GetModelPackageApi);
// This is defined explicitly since OrtTensorRTProviderOptionsV2 is not a C API type,
// but the struct has V2 in its name to indicate that it is the second version of the options.
@@ -807,9 +790,6 @@ struct EpDevice;
struct ExternalInitializerInfo;
struct Graph;
struct Model;
-struct ModelPackageOptions;
-struct ModelPackageContext;
-struct ModelPackageComponentContext;
struct Node;
struct ModelMetadata;
struct TypeInfo;
@@ -1806,70 +1786,6 @@ struct ModelCompilationOptions : detail::Base {
*/
Status CompileModel(const Env& env, const ModelCompilationOptions& model_compilation_options);
-/** \brief Options for selecting a component from a model package.
- *
- * Wraps ::OrtModelPackageOptions. Created from an Env and SessionOptions, which captures the
- * EP configuration used for variant selection.
- */
-struct ModelPackageOptions : detail::Base {
- using Base = detail::Base;
- using Base::Base;
-
- explicit ModelPackageOptions(std::nullptr_t) {} ///< Create an empty object, must be assigned a valid one to be used.
-
- ModelPackageOptions(const Env& env, const SessionOptions& session_options); ///< Wraps OrtModelPackageApi::CreateModelPackageOptionsFromSessionOptions
- ModelPackageOptions(const Env& env, ConstSessionOptions session_options); ///< Wraps OrtModelPackageApi::CreateModelPackageOptionsFromSessionOptions
-};
-
-/** \brief Context for inspecting and selecting components from a model package.
- *
- * Wraps ::OrtModelPackageContext. Provides traversal APIs to enumerate components, variants,
- * and EP compatibility, as well as component selection.
- */
-struct ModelPackageContext : detail::Base {
- using Base = detail::Base;
- using Base::Base;
-
- explicit ModelPackageContext(std::nullptr_t) {} ///< Create an empty object, must be assigned a valid one to be used.
-
- explicit ModelPackageContext(const ORTCHAR_T* package_root); ///< Wraps OrtModelPackageApi::CreateModelPackageContext
-
- size_t GetComponentCount() const; ///< Wraps OrtModelPackageApi::ModelPackage_GetComponentCount
- std::vector GetComponentNames() const; ///< Wraps OrtModelPackageApi::ModelPackage_GetComponentNames
- size_t GetVariantCount(const char* component_name) const; ///< Wraps OrtModelPackageApi::ModelPackage_GetVariantCount
- std::vector GetVariantNames(const char* component_name) const; ///< Wraps OrtModelPackageApi::ModelPackage_GetVariantNames
-
- /// Get the EP name for a variant. Returns nullptr if not declared.
- /// Returned string is owned by this context and valid until it is released.
- const char* GetVariantEpName(const char* component_name,
- const char* variant_name) const; ///< Wraps OrtModelPackageApi::ModelPackage_GetVariantEpName
-
- int64_t GetSchemaVersion() const; ///< Wraps OrtModelPackageApi::ModelPackage_GetSchemaVersion
-
- ModelPackageComponentContext SelectComponent(const char* component_name,
- const ModelPackageOptions& options) const; ///< Wraps OrtModelPackageApi::SelectComponent
-};
-
-/** \brief Context for a selected component within a model package.
- *
- * Wraps ::OrtModelPackageComponentContext. Provides accessors for the selected variant's
- * folder path and variant name.
- */
-struct ModelPackageComponentContext : detail::Base {
- using Base = detail::Base;
- using Base::Base;
-
- explicit ModelPackageComponentContext(std::nullptr_t) {} ///< Create an empty object, must be assigned a valid one to be used.
-
- std::basic_string GetSelectedVariantFolderPath() const; ///< Wraps OrtModelPackageApi::ModelPackageComponent_GetSelectedVariantFolderPath
-
- std::string GetSelectedVariantName() const; ///< Wraps OrtModelPackageApi::ModelPackageComponent_GetSelectedVariantName
-
- Session CreateSession(const Env& env); ///< Wraps OrtModelPackageApi::CreateSession (default path, NULL session_options)
- Session CreateSession(const Env& env, const SessionOptions& session_options); ///< Wraps OrtModelPackageApi::CreateSession (advanced path)
- Session CreateSession(const Env& env, ConstSessionOptions session_options); ///< Wraps OrtModelPackageApi::CreateSession (advanced path)
-};
-
/** \brief Wrapper around ::OrtModelMetadata
*
*/
diff --git a/include/onnxruntime/core/session/onnxruntime_cxx_inline.h b/include/onnxruntime/core/session/onnxruntime_cxx_inline.h
index 51f99655121c6..d7439e7b356c6 100644
--- a/include/onnxruntime/core/session/onnxruntime_cxx_inline.h
+++ b/include/onnxruntime/core/session/onnxruntime_cxx_inline.h
@@ -1360,110 +1360,6 @@ inline ModelCompilationOptions& ModelCompilationOptions::SetInputModel(const Ort
return *this;
}
-// ModelPackageOptions
-inline ModelPackageOptions::ModelPackageOptions(const Env& env, const SessionOptions& session_options) {
- ThrowOnError(GetModelPackageApi().CreateModelPackageOptionsFromSessionOptions(env, session_options, &this->p_));
-}
-
-inline ModelPackageOptions::ModelPackageOptions(const Env& env, ConstSessionOptions session_options) {
- ThrowOnError(GetModelPackageApi().CreateModelPackageOptionsFromSessionOptions(env, session_options, &this->p_));
-}
-
-// ModelPackageContext
-inline ModelPackageContext::ModelPackageContext(const ORTCHAR_T* package_root) {
- ThrowOnError(GetModelPackageApi().CreateModelPackageContext(package_root, &this->p_));
-}
-
-inline size_t ModelPackageContext::GetComponentCount() const {
- size_t count = 0;
- ThrowOnError(GetModelPackageApi().ModelPackage_GetComponentCount(this->p_, &count));
- return count;
-}
-
-inline std::vector ModelPackageContext::GetComponentNames() const {
- const char* const* names = nullptr;
- size_t count = 0;
- ThrowOnError(GetModelPackageApi().ModelPackage_GetComponentNames(this->p_, &names, &count));
- std::vector result;
- result.reserve(count);
- for (size_t i = 0; i < count; ++i) {
- result.emplace_back(names[i]);
- }
- return result;
-}
-
-inline size_t ModelPackageContext::GetVariantCount(const char* component_name) const {
- size_t count = 0;
- ThrowOnError(GetModelPackageApi().ModelPackage_GetVariantCount(this->p_, component_name, &count));
- return count;
-}
-
-inline std::vector ModelPackageContext::GetVariantNames(const char* component_name) const {
- const char* const* names = nullptr;
- size_t count = 0;
- ThrowOnError(GetModelPackageApi().ModelPackage_GetVariantNames(this->p_, component_name, &names, &count));
- std::vector result;
- result.reserve(count);
- for (size_t i = 0; i < count; ++i) {
- result.emplace_back(names[i]);
- }
- return result;
-}
-
-inline const char* ModelPackageContext::GetVariantEpName(const char* component_name,
- const char* variant_name) const {
- const char* ep = nullptr;
- ThrowOnError(GetModelPackageApi().ModelPackage_GetVariantEpName(
- this->p_, component_name, variant_name, &ep));
- return ep;
-}
-
-inline int64_t ModelPackageContext::GetSchemaVersion() const {
- int64_t version = 0;
- ThrowOnError(GetModelPackageApi().ModelPackage_GetSchemaVersion(this->p_, &version));
- return version;
-}
-
-inline ModelPackageComponentContext ModelPackageContext::SelectComponent(
- const char* component_name, const ModelPackageOptions& options) const {
- OrtModelPackageComponentContext* out = nullptr;
- ThrowOnError(GetModelPackageApi().SelectComponent(this->p_, component_name, options, &out));
- return ModelPackageComponentContext{out};
-}
-
-// ModelPackageComponentContext
-inline std::basic_string ModelPackageComponentContext::GetSelectedVariantFolderPath() const {
- const ORTCHAR_T* path = nullptr;
- ThrowOnError(GetModelPackageApi().ModelPackageComponent_GetSelectedVariantFolderPath(this->p_, &path));
- return std::basic_string{path};
-}
-
-inline std::string ModelPackageComponentContext::GetSelectedVariantName() const {
- const char* name = nullptr;
- ThrowOnError(GetModelPackageApi().ModelPackageComponent_GetSelectedVariantName(this->p_, &name));
- return (name != nullptr) ? std::string{name} : std::string{};
-}
-
-inline Session ModelPackageComponentContext::CreateSession(const Env& env) {
- OrtSession* out = nullptr;
- ThrowOnError(GetModelPackageApi().CreateSession(env, this->p_, nullptr, &out));
- return Session{out};
-}
-
-inline Session ModelPackageComponentContext::CreateSession(const Env& env,
- const SessionOptions& session_options) {
- OrtSession* out = nullptr;
- ThrowOnError(GetModelPackageApi().CreateSession(env, this->p_, session_options, &out));
- return Session{out};
-}
-
-inline Session ModelPackageComponentContext::CreateSession(const Env& env,
- ConstSessionOptions session_options) {
- OrtSession* out = nullptr;
- ThrowOnError(GetModelPackageApi().CreateSession(env, this->p_, session_options, &out));
- return Session{out};
-}
-
namespace detail {
template
diff --git a/include/onnxruntime/core/session/onnxruntime_experimental_c_api.h b/include/onnxruntime/core/session/onnxruntime_experimental_c_api.h
index e943a5cf65b11..0dd87c10776d3 100644
--- a/include/onnxruntime/core/session/onnxruntime_experimental_c_api.h
+++ b/include/onnxruntime/core/session/onnxruntime_experimental_c_api.h
@@ -39,6 +39,10 @@
// ORT_RUNTIME_CLASS(ExperimentalType);
//
+ORT_RUNTIME_CLASS(ModelPackageOptions);
+ORT_RUNTIME_CLASS(ModelPackageContext);
+ORT_RUNTIME_CLASS(ModelPackageComponentContext);
+
//
// C: function pointer typedefs and name constants
//
diff --git a/include/onnxruntime/core/session/onnxruntime_experimental_c_api.inc b/include/onnxruntime/core/session/onnxruntime_experimental_c_api.inc
index 0123b02818584..57a4e472b6f6d 100644
--- a/include/onnxruntime/core/session/onnxruntime_experimental_c_api.inc
+++ b/include/onnxruntime/core/session/onnxruntime_experimental_c_api.inc
@@ -35,3 +35,250 @@
* \snippet{doc} snippets.dox OrtStatus Return Value
*/
ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtApi_ExperimentalApiTest, _Out_ int64_t* out)
+
+// ---------------------------------------------------------------------------
+// OrtModelPackageApi
+//
+// A model package is a directory containing one or more *components* (logical models).
+// Each component has one or more *variants*, where each variant targets a single
+// execution provider (EP). The package manifest declares the EP name, device type,
+// and an optional compatibility string for every variant so that the runtime can
+// automatically select the best variant for the hardware and EPs available in the
+// caller's session options.
+//
+// The functions below support:
+// - creating model package options that capture EP configuration from OrtSessionOptions,
+// - loading a package context (manifest + metadata) from a package root path,
+// - querying component/variant metadata including per-variant EP information,
+// - selecting a component (which also resolves the best-matching variant),
+// - querying the selected variant's name and folder path,
+// - creating an OrtSession from the selected component context.
+//
+// Typical flow:
+// 1) Create model package options:
+// - OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions
+// 2) Load package metadata:
+// - OrtModelPackageApi_CreateModelPackageContext
+// 3) Query metadata (optional):
+// - OrtModelPackageApi_ModelPackage_GetSchemaVersion
+// - OrtModelPackageApi_ModelPackage_GetComponentCount
+// - OrtModelPackageApi_ModelPackage_GetComponentNames
+// - OrtModelPackageApi_ModelPackage_GetVariantCount
+// - OrtModelPackageApi_ModelPackage_GetVariantNames
+// - OrtModelPackageApi_ModelPackage_GetVariantEpName
+// 4) Select a component and resolve variant:
+// - OrtModelPackageApi_SelectComponent
+// 5) Query selected variant info (optional):
+// - OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantName
+// - OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantFolderPath
+// 6) Create session:
+// - OrtModelPackageApi_CreateSession
+//
+// Ownership:
+// - Release objects created by this API with the corresponding release functions:
+// OrtModelPackageApi_ReleaseModelPackageOptions,
+// OrtModelPackageApi_ReleaseModelPackageContext,
+// OrtModelPackageApi_ReleaseModelPackageComponentContext.
+//
+// Opaque handles (OrtModelPackageOptions, OrtModelPackageContext, OrtModelPackageComponentContext)
+// are declared in onnxruntime_experimental_c_api.h.
+// ---------------------------------------------------------------------------
+
+/** \brief Create model package options from an existing OrtSessionOptions.
+ *
+ * Captures EP configuration (registered execution providers and their devices) from
+ * the session options for use during variant selection. The resulting OrtModelPackageOptions
+ * is passed to OrtModelPackageApi_SelectComponent to resolve the best variant for the
+ * available EPs.
+ *
+ * \param[in] env The ORT environment.
+ * \param[in] session_options Session options containing registered EPs.
+ * \param[out] out Receives the newly created OrtModelPackageOptions. Must be released
+ * with OrtModelPackageApi_ReleaseModelPackageOptions.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions,
+ _In_ const OrtEnv* env,
+ _In_ const OrtSessionOptions* session_options,
+ _Outptr_ OrtModelPackageOptions** out)
+
+/** \brief Release an OrtModelPackageOptions created by
+ * OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions.
+ */
+ORT_EXPERIMENTAL_API(28, void, OrtModelPackageApi_ReleaseModelPackageOptions,
+ _Frees_ptr_opt_ OrtModelPackageOptions* options)
+
+/** \brief Create a model package context by parsing the package at the given root path.
+ *
+ * Parses the manifest.json and component metadata from the specified directory.
+ * The returned context provides read-only access to the package structure (components,
+ * variants, EP declarations).
+ *
+ * \param[in] package_root Path to the model package root directory (containing manifest.json).
+ * \param[out] out Receives the newly created OrtModelPackageContext. Must be released
+ * with OrtModelPackageApi_ReleaseModelPackageContext.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_CreateModelPackageContext,
+ _In_ const ORTCHAR_T* package_root,
+ _Outptr_ OrtModelPackageContext** out)
+
+/** \brief Release an OrtModelPackageContext created by OrtModelPackageApi_CreateModelPackageContext. */
+ORT_EXPERIMENTAL_API(28, void, OrtModelPackageApi_ReleaseModelPackageContext,
+ _Frees_ptr_opt_ OrtModelPackageContext* ctx)
+
+/** \brief Get the schema version declared in the model package manifest.
+ *
+ * \param[in] ctx The model package context.
+ * \param[out] out_version Receives the schema version number.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackage_GetSchemaVersion,
+ _In_ const OrtModelPackageContext* ctx,
+ _Out_ int64_t* out_version)
+
+/** \brief Get the number of components in the model package.
+ *
+ * \param[in] ctx The model package context.
+ * \param[out] out_count Receives the component count.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackage_GetComponentCount,
+ _In_ const OrtModelPackageContext* ctx,
+ _Out_ size_t* out_count)
+
+/** \brief Get the names of all components in the model package.
+ *
+ * Returns a pointer to an array of UTF-8 component name strings. The array and its
+ * strings are owned by `ctx` and remain valid until the context is released.
+ *
+ * \param[in] ctx The model package context.
+ * \param[out] out_names Receives a pointer to an array of component name strings.
+ * \param[out] out_count Receives the number of elements in the array.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackage_GetComponentNames,
+ _In_ const OrtModelPackageContext* ctx,
+ _Outptr_result_buffer_maybenull_(*out_count) const char* const** out_names,
+ _Out_ size_t* out_count)
+
+/** \brief Get the number of variants for a given component.
+ *
+ * \param[in] ctx The model package context.
+ * \param[in] component_name Name of the component to query.
+ * \param[out] out_count Receives the variant count.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackage_GetVariantCount,
+ _In_ const OrtModelPackageContext* ctx,
+ _In_ const char* component_name,
+ _Out_ size_t* out_count)
+
+/** \brief Get the names of all variants for a given component.
+ *
+ * Returns a pointer to an array of UTF-8 variant name strings. The array and its
+ * strings are owned by `ctx` and remain valid until the context is released.
+ *
+ * \param[in] ctx The model package context.
+ * \param[in] component_name Name of the component to query.
+ * \param[out] out_variant_names Receives a pointer to an array of variant name strings.
+ * \param[out] out_count Receives the number of elements in the array.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackage_GetVariantNames,
+ _In_ const OrtModelPackageContext* ctx,
+ _In_ const char* component_name,
+ _Outptr_result_buffer_maybenull_(*out_count) const char* const** out_variant_names,
+ _Out_ size_t* out_count)
+
+/** \brief Get the EP name declared for a (component, variant) pair.
+ *
+ * Each variant targets a single EP. `out_ep` receives the EP name string.
+ * When the variant does not declare an EP, the returned pointer is NULL.
+ * String memory is owned by `ctx` and remains valid until the context is released.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackage_GetVariantEpName,
+ _In_ const OrtModelPackageContext* ctx,
+ _In_ const char* component_name,
+ _In_ const char* variant_name,
+ _Outptr_result_maybenull_ const char** out_ep)
+
+/** \brief Select a component model and return an opaque component instance.
+ *
+ * The variant selection is also performed during this call based on the component
+ * metadata and the provided options. The returned `OrtModelPackageComponentContext*` is
+ * independent of `context` lifetime and must be released via
+ * OrtModelPackageApi_ReleaseModelPackageComponentContext.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_SelectComponent,
+ _In_ const OrtModelPackageContext* context,
+ _In_ const char* component_name,
+ _In_ const OrtModelPackageOptions* options,
+ _Outptr_ OrtModelPackageComponentContext** out)
+
+/** \brief Release an OrtModelPackageComponentContext created by OrtModelPackageApi_SelectComponent. */
+ORT_EXPERIMENTAL_API(28, void, OrtModelPackageApi_ReleaseModelPackageComponentContext,
+ _Frees_ptr_opt_ OrtModelPackageComponentContext* ctx)
+
+/** \brief Get the name of the selected variant after OrtModelPackageApi_SelectComponent has been called.
+ *
+ * String memory is owned by `ctx` and remains valid until the context is released.
+ *
+ * \param[in] ctx The component context returned by OrtModelPackageApi_SelectComponent.
+ * \param[out] out_name Receives the selected variant's name string.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantName,
+ _In_ const OrtModelPackageComponentContext* ctx,
+ _Outptr_ const char** out_name)
+
+/** \brief Get the folder path of the selected variant.
+ *
+ * Returns the resolved absolute path to the variant's directory on disk.
+ * The string is owned by `ctx` and remains valid until the context is released.
+ *
+ * \param[in] ctx The component context returned by OrtModelPackageApi_SelectComponent.
+ * \param[out] folder_path Receives the variant folder path string.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantFolderPath,
+ _In_ const OrtModelPackageComponentContext* ctx,
+ _Outptr_ const ORTCHAR_T** folder_path)
+
+/** \brief Create an OrtSession for a selected file within a component model variant.
+ *
+ * The chosen variant (and thus its EP selection) is determined by `context`, which
+ * was built from an OrtSessionOptions via OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions.
+ *
+ * Session options precedence:
+ * 1. session_options == NULL (default path):
+ * ORT uses the OrtSessionOptions that was captured when `context` was created.
+ * Any variant-specific session and provider options declared in the package
+ * metadata are merged on top.
+ *
+ * 2. session_options != NULL (advanced path):
+ * ORT uses the caller-provided OrtSessionOptions as-is. Variant-specific
+ * session and provider options from the package metadata are NOT applied.
+ * Use this when custom EP setup is required (e.g., shared CUDA streams,
+ * shared QNN EP contexts, custom allocators).
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ORT_EXPERIMENTAL_API(28, OrtStatusPtr, OrtModelPackageApi_CreateSession,
+ _In_ const OrtEnv* env,
+ _In_ OrtModelPackageComponentContext* context,
+ _In_opt_ const OrtSessionOptions* session_options,
+ _Outptr_ OrtSession** session)
diff --git a/onnxruntime/__init__.py b/onnxruntime/__init__.py
index c26424a0ab9ec..df14bc8c57f24 100644
--- a/onnxruntime/__init__.py
+++ b/onnxruntime/__init__.py
@@ -29,9 +29,6 @@
GraphOptimizationLevel, # noqa: F401
LoraAdapter, # noqa: F401
ModelMetadata, # noqa: F401
- ModelPackageComponentContext, # noqa: F401
- ModelPackageContext, # noqa: F401
- ModelPackageOptions, # noqa: F401
NodeArg, # noqa: F401
OrtAllocatorType, # noqa: F401
OrtArenaCfg, # noqa: F401
diff --git a/onnxruntime/core/session/experimental_c_api.cc b/onnxruntime/core/session/experimental_c_api.cc
index d030b68abdb99..458c47bcb58cd 100644
--- a/onnxruntime/core/session/experimental_c_api.cc
+++ b/onnxruntime/core/session/experimental_c_api.cc
@@ -18,6 +18,14 @@
namespace OrtExperimentalApis {
+// Forward declarations driven by the .inc file so the registration table below
+// can take the address of every entry, including those defined in other
+// translation units linked into onnxruntime_session.
+#define ORT_EXPERIMENTAL_API(VER, RET, NAME, ...) \
+ RET ORT_API_CALL NAME##_SinceV##VER(__VA_ARGS__) NO_EXCEPTION;
+#include "onnxruntime_experimental_c_api.inc"
+#undef ORT_EXPERIMENTAL_API
+
// Test-only experimental function that writes a known sentinel value.
// Exists to exercise the experimental API mechanism end-to-end and to serve as a template for future experimental
// functions.
diff --git a/onnxruntime/core/session/model_package_api.cc b/onnxruntime/core/session/model_package_api.cc
index 27abb0f5f7a37..5fd25f9511eb9 100644
--- a/onnxruntime/core/session/model_package_api.cc
+++ b/onnxruntime/core/session/model_package_api.cc
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-#include "core/session/model_package_api.h"
+#include "core/session/onnxruntime_experimental_c_api.h"
#include "core/common/common.h"
#include "core/framework/error_code_helper.h"
@@ -23,7 +23,9 @@ using namespace onnxruntime;
return OrtApis::CreateStatus(ORT_NOT_IMPLEMENTED, \
"Model package API is not supported in this build")
-ORT_API(void, OrtModelPackageAPI::ReleaseModelPackageOptions,
+namespace OrtExperimentalApis {
+
+ORT_API(void, OrtModelPackageApi_ReleaseModelPackageOptions_SinceV28,
_Frees_ptr_opt_ OrtModelPackageOptions* options) {
#if !defined(ORT_MINIMAL_BUILD)
delete reinterpret_cast(options);
@@ -32,7 +34,7 @@ ORT_API(void, OrtModelPackageAPI::ReleaseModelPackageOptions,
#endif
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::CreateModelPackageOptionsFromSessionOptions,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions_SinceV28,
_In_ const OrtEnv* env,
_In_ const OrtSessionOptions* session_options,
_Outptr_ OrtModelPackageOptions** out) {
@@ -54,7 +56,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::CreateModelPackageOptionsFromSessionOpti
API_IMPL_END
}
-ORT_API(void, OrtModelPackageAPI::ReleaseModelPackageContext,
+ORT_API(void, OrtModelPackageApi_ReleaseModelPackageContext_SinceV28,
_Frees_ptr_opt_ OrtModelPackageContext* ctx) {
#if !defined(ORT_MINIMAL_BUILD)
delete reinterpret_cast(ctx);
@@ -63,7 +65,7 @@ ORT_API(void, OrtModelPackageAPI::ReleaseModelPackageContext,
#endif
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::CreateModelPackageContext,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_CreateModelPackageContext_SinceV28,
_In_ const ORTCHAR_T* package_root,
_Outptr_ OrtModelPackageContext** out) {
API_IMPL_BEGIN
@@ -89,7 +91,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::CreateModelPackageContext,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetComponentCount,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackage_GetComponentCount_SinceV28,
_In_ const OrtModelPackageContext* ctx,
_Out_ size_t* out_count) {
API_IMPL_BEGIN
@@ -107,7 +109,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetComponentCount,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetComponentNames,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackage_GetComponentNames_SinceV28,
_In_ const OrtModelPackageContext* ctx,
_Outptr_result_buffer_maybenull_(*out_count) const char* const** out_names,
_Out_ size_t* out_count) {
@@ -136,7 +138,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetComponentNames,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetVariantCount,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackage_GetVariantCount_SinceV28,
_In_ const OrtModelPackageContext* ctx,
_In_ const char* component_name,
_Out_ size_t* out_count) {
@@ -158,7 +160,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetVariantCount,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetVariantNames,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackage_GetVariantNames_SinceV28,
_In_ const OrtModelPackageContext* ctx,
_In_ const char* component_name,
_Outptr_result_buffer_maybenull_(*out_count) const char* const** out_variant_names,
@@ -190,7 +192,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetVariantNames,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::SelectComponent,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_SelectComponent_SinceV28,
_In_ const OrtModelPackageContext* context,
_In_ const char* component_name,
_In_ const OrtModelPackageOptions* options,
@@ -235,7 +237,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::SelectComponent,
API_IMPL_END
}
-ORT_API(void, OrtModelPackageAPI::ReleaseModelPackageComponentContext,
+ORT_API(void, OrtModelPackageApi_ReleaseModelPackageComponentContext_SinceV28,
_Frees_ptr_opt_ OrtModelPackageComponentContext* cix) {
#if !defined(ORT_MINIMAL_BUILD)
delete reinterpret_cast(cix);
@@ -244,7 +246,7 @@ ORT_API(void, OrtModelPackageAPI::ReleaseModelPackageComponentContext,
#endif
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackageComponent_GetSelectedVariantFolderPath,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantFolderPath_SinceV28,
_In_ const OrtModelPackageComponentContext* ctx,
_Outptr_ const ORTCHAR_T** folder_path) {
API_IMPL_BEGIN
@@ -269,7 +271,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackageComponent_GetSelectedVariant
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::CreateSession,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_CreateSession_SinceV28,
_In_ const OrtEnv* env,
_In_ OrtModelPackageComponentContext* ctx,
_In_opt_ const OrtSessionOptions* session_options,
@@ -383,7 +385,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::CreateSession,
// ---------- API table ------------------------------------------------------
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetVariantEpName,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackage_GetVariantEpName_SinceV28,
_In_ const OrtModelPackageContext* ctx,
_In_ const char* component_name,
_In_ const char* variant_name,
@@ -417,7 +419,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetVariantEpName,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetSchemaVersion,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackage_GetSchemaVersion_SinceV28,
_In_ const OrtModelPackageContext* ctx,
_Out_ int64_t* out_version) {
API_IMPL_BEGIN
@@ -437,7 +439,7 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackage_GetSchemaVersion,
API_IMPL_END
}
-ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackageComponent_GetSelectedVariantName,
+ORT_API_STATUS_IMPL(OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantName_SinceV28,
_In_ const OrtModelPackageComponentContext* ctx,
_Outptr_ const char** out_name) {
API_IMPL_BEGIN
@@ -461,40 +463,4 @@ ORT_API_STATUS_IMPL(OrtModelPackageAPI::ModelPackageComponent_GetSelectedVariant
API_IMPL_END
}
-// ---------- API table dispatch ---------------------------------------------
-
-static constexpr OrtModelPackageApi ort_model_package_api = {
- // Options
- &OrtModelPackageAPI::CreateModelPackageOptionsFromSessionOptions,
- &OrtModelPackageAPI::ReleaseModelPackageOptions,
-
- // Context
- &OrtModelPackageAPI::CreateModelPackageContext,
- &OrtModelPackageAPI::ReleaseModelPackageContext,
-
- // Package-level queries
- &OrtModelPackageAPI::ModelPackage_GetSchemaVersion,
- &OrtModelPackageAPI::ModelPackage_GetComponentCount,
- &OrtModelPackageAPI::ModelPackage_GetComponentNames,
- &OrtModelPackageAPI::ModelPackage_GetVariantCount,
- &OrtModelPackageAPI::ModelPackage_GetVariantNames,
- &OrtModelPackageAPI::ModelPackage_GetVariantEpName,
-
- // Variant selection and component queries
- &OrtModelPackageAPI::SelectComponent,
- &OrtModelPackageAPI::ReleaseModelPackageComponentContext,
- &OrtModelPackageAPI::ModelPackageComponent_GetSelectedVariantName,
- &OrtModelPackageAPI::ModelPackageComponent_GetSelectedVariantFolderPath,
-
- // Session
- &OrtModelPackageAPI::CreateSession,
-
- // End of Version 1.27 - DO NOT MODIFY ABOVE
-};
-
-static_assert(offsetof(OrtModelPackageApi, CreateSession) / sizeof(void*) == 14,
- "Size of initial OrtModelPackageApi cannot change");
-
-ORT_API(const OrtModelPackageApi*, OrtModelPackageAPI::GetModelPackageApi) {
- return &ort_model_package_api;
-}
+} // namespace OrtExperimentalApis
diff --git a/onnxruntime/core/session/model_package_api.h b/onnxruntime/core/session/model_package_api.h
deleted file mode 100644
index 435e3a521c24c..0000000000000
--- a/onnxruntime/core/session/model_package_api.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-#pragma once
-
-#include "core/session/onnxruntime_c_api.h"
-
-namespace OrtModelPackageAPI {
-
-ORT_API(const OrtModelPackageApi*, GetModelPackageApi);
-
-ORT_API(void, ReleaseModelPackageOptions, _Frees_ptr_opt_ OrtModelPackageOptions*);
-ORT_API_STATUS_IMPL(CreateModelPackageOptionsFromSessionOptions,
- _In_ const OrtEnv* env,
- _In_ const OrtSessionOptions* session_options,
- _Outptr_ OrtModelPackageOptions** out);
-
-ORT_API(void, ReleaseModelPackageContext, _Frees_ptr_opt_ OrtModelPackageContext*);
-ORT_API_STATUS_IMPL(CreateModelPackageContext,
- _In_ const ORTCHAR_T* package_root,
- _Outptr_ OrtModelPackageContext** out);
-
-ORT_API_STATUS_IMPL(ModelPackage_GetComponentCount,
- _In_ const OrtModelPackageContext* ctx,
- _Out_ size_t* out_count);
-
-ORT_API_STATUS_IMPL(ModelPackage_GetComponentNames,
- _In_ const OrtModelPackageContext* ctx,
- _Outptr_result_buffer_maybenull_(*out_count) const char* const** out_names,
- _Out_ size_t* out_count);
-
-ORT_API_STATUS_IMPL(ModelPackage_GetVariantCount,
- _In_ const OrtModelPackageContext* ctx,
- _In_ const char* component_name,
- _Out_ size_t* out_count);
-
-ORT_API_STATUS_IMPL(ModelPackage_GetVariantNames,
- _In_ const OrtModelPackageContext* ctx,
- _In_ const char* component_name,
- _Outptr_result_buffer_maybenull_(*out_count) const char* const** out_variant_names,
- _Out_ size_t* out_count);
-
-ORT_API_STATUS_IMPL(SelectComponent,
- _In_ const OrtModelPackageContext* context,
- _In_ const char* component_name,
- _In_ const OrtModelPackageOptions* options,
- _Outptr_ OrtModelPackageComponentContext** out);
-
-ORT_API(void, ReleaseModelPackageComponentContext,
- _Frees_ptr_opt_ OrtModelPackageComponentContext* ctx);
-
-ORT_API_STATUS_IMPL(ModelPackageComponent_GetSelectedVariantFolderPath,
- _In_ const OrtModelPackageComponentContext* ctx,
- _Outptr_ const ORTCHAR_T** folder_path);
-
-ORT_API_STATUS_IMPL(CreateSession,
- _In_ const OrtEnv* env,
- _In_ OrtModelPackageComponentContext* ctx,
- _In_opt_ const OrtSessionOptions* session_options,
- _Outptr_ OrtSession** session);
-
-ORT_API_STATUS_IMPL(ModelPackage_GetVariantEpName,
- _In_ const OrtModelPackageContext* ctx,
- _In_ const char* component_name,
- _In_ const char* variant_name,
- _Outptr_result_maybenull_ const char** out_ep);
-
-ORT_API_STATUS_IMPL(ModelPackage_GetSchemaVersion,
- _In_ const OrtModelPackageContext* ctx,
- _Out_ int64_t* out_version);
-
-ORT_API_STATUS_IMPL(ModelPackageComponent_GetSelectedVariantName,
- _In_ const OrtModelPackageComponentContext* ctx,
- _Outptr_ const char** out_name);
-
-} // namespace OrtModelPackageAPI
diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc
index 61a413d92e7fc..f451eaa401497 100644
--- a/onnxruntime/core/session/onnxruntime_c_api.cc
+++ b/onnxruntime/core/session/onnxruntime_c_api.cc
@@ -57,7 +57,6 @@
#include "core/session/ort_env.h"
#include "core/session/ort_version_check.h"
#include "core/session/utils.h"
-#include "core/session/model_package_api.h"
#if defined(USE_CUDA) || defined(USE_CUDA_PROVIDER_INTERFACE)
#include "core/providers/cuda/cuda_provider_factory.h"
@@ -3689,10 +3688,6 @@ ORT_API(const OrtCompileApi*, OrtApis::GetCompileApi) {
return OrtCompileAPI::GetCompileApi();
}
-ORT_API(const OrtModelPackageApi*, OrtApis::GetModelPackageApi) {
- return OrtModelPackageAPI::GetModelPackageApi();
-}
-
ORT_API(void, OrtApis::CreateKeyValuePairs, _Outptr_ OrtKeyValuePairs** out) {
auto kvps = std::make_unique();
*out = reinterpret_cast(kvps.release());
@@ -4911,7 +4906,6 @@ static constexpr OrtApi ort_api_1_to_28 = {
&OrtApis::GetMemPatternEnabled,
&OrtApis::GetSessionExecutionMode,
&OrtApis::SessionReleaseCapturedGraph,
- &OrtApis::GetModelPackageApi,
// End of Version 27 - DO NOT MODIFY ABOVE (see above text for more information)
&OrtApis::GetExperimentalFunction,
diff --git a/onnxruntime/core/session/ort_apis.h b/onnxruntime/core/session/ort_apis.h
index 250a2853a4777..61ece2dd9a682 100644
--- a/onnxruntime/core/session/ort_apis.h
+++ b/onnxruntime/core/session/ort_apis.h
@@ -825,9 +825,6 @@ ORT_API_STATUS_IMPL(GetTensorElementTypeAndShapeDataReference, _In_ const OrtVal
_Outptr_result_maybenull_ const int64_t** shape_data,
_Out_ size_t* shape_data_count);
-// Model Package API
-ORT_API(const OrtModelPackageApi*, GetModelPackageApi);
-
// Experimental API
ORT_API(OrtExperimentalFnPtr, GetExperimentalFunction, _In_ const char* name);
diff --git a/onnxruntime/python/onnxruntime_pybind_state.cc b/onnxruntime/python/onnxruntime_pybind_state.cc
index 77200ea84778e..2044a128d9540 100644
--- a/onnxruntime/python/onnxruntime_pybind_state.cc
+++ b/onnxruntime/python/onnxruntime_pybind_state.cc
@@ -3247,195 +3247,6 @@ including arg name, arg type (contains both type and shape).)pbdoc")
#endif
},
R"pbdoc(Compile an ONNX model into an output stream using the provided write functor.)pbdoc");
-
- // --- Model Package API ---
-#if !defined(ORT_MINIMAL_BUILD)
- // Helper to create a PyInferenceSession from a pre-initialized OrtSession* (C API handle).
- // PyInferenceSession's owning ctor is protected; this subclass provides access.
- struct PyModelPackageSession : PyInferenceSession {
- PyModelPackageSession(std::unique_ptr sess)
- : PyInferenceSession(std::move(sess)) {}
- };
-
- // Wrapper classes to manage opaque C handles with proper RAII
- struct PyModelPackageContext {
- OrtModelPackageContext* ctx_{nullptr};
- PyModelPackageContext(const std::string& package_path) {
- auto path = ToPathString(package_path);
- const auto* api = Ort::GetApi().GetModelPackageApi();
- Ort::ThrowOnError(api->CreateModelPackageContext(path.c_str(), &ctx_));
- }
- ~PyModelPackageContext() {
- if (ctx_) {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- api->ReleaseModelPackageContext(ctx_);
- }
- }
- PyModelPackageContext(const PyModelPackageContext&) = delete;
- PyModelPackageContext& operator=(const PyModelPackageContext&) = delete;
- };
-
- struct PyModelPackageComponentContext {
- OrtModelPackageComponentContext* ctx_{nullptr};
- ~PyModelPackageComponentContext() {
- if (ctx_) {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- api->ReleaseModelPackageComponentContext(ctx_);
- }
- }
- PyModelPackageComponentContext(const PyModelPackageComponentContext&) = delete;
- PyModelPackageComponentContext& operator=(const PyModelPackageComponentContext&) = delete;
- PyModelPackageComponentContext() = default;
- };
-
- struct PyModelPackageOptions {
- OrtModelPackageOptions* opts_{nullptr};
- ~PyModelPackageOptions() {
- if (opts_) {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- api->ReleaseModelPackageOptions(opts_);
- }
- }
- PyModelPackageOptions(const PyModelPackageOptions&) = delete;
- PyModelPackageOptions& operator=(const PyModelPackageOptions&) = delete;
- PyModelPackageOptions() = default;
- };
-
- py::class_(m, "ModelPackageContext",
- R"pbdoc(Represents an opened model package for inspection and component selection.)pbdoc")
- .def(py::init(), py::arg("package_path"),
- R"pbdoc(Open a model package from the given directory path.)pbdoc")
- .def(
- "get_component_names",
- [](PyModelPackageContext& self) -> std::vector {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- const char* const* names = nullptr;
- size_t count = 0;
- Ort::ThrowOnError(api->ModelPackage_GetComponentNames(self.ctx_, &names, &count));
- std::vector result;
- result.reserve(count);
- for (size_t i = 0; i < count; ++i) {
- result.emplace_back(names[i]);
- }
- return result;
- },
- R"pbdoc(Get the names of all components in the package.)pbdoc")
- .def(
- "get_variant_names",
- [](PyModelPackageContext& self, const std::string& component_name) -> std::vector {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- const char* const* names = nullptr;
- size_t count = 0;
- Ort::ThrowOnError(api->ModelPackage_GetVariantNames(
- self.ctx_, component_name.c_str(), &names, &count));
- std::vector result;
- result.reserve(count);
- for (size_t i = 0; i < count; ++i) {
- result.emplace_back(names[i]);
- }
- return result;
- },
- py::arg("component_name"),
- R"pbdoc(Get the variant names for a given component.)pbdoc")
- .def(
- "get_variant_ep_name",
- [](PyModelPackageContext& self, const std::string& component_name,
- const std::string& variant_name) -> std::optional {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- const char* ep = nullptr;
- Ort::ThrowOnError(api->ModelPackage_GetVariantEpName(
- self.ctx_, component_name.c_str(), variant_name.c_str(), &ep));
- if (ep) return std::string(ep);
- return std::nullopt;
- },
- py::arg("component_name"), py::arg("variant_name"),
- R"pbdoc(Get the EP name for a variant. Returns None if not declared.)pbdoc")
- .def(
- "get_schema_version",
- [](PyModelPackageContext& self) -> int64_t {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- int64_t version = 0;
- Ort::ThrowOnError(api->ModelPackage_GetSchemaVersion(self.ctx_, &version));
- return version;
- },
- R"pbdoc(Get the schema version declared in the model package manifest.)pbdoc")
- .def(
- "select_component",
- [](PyModelPackageContext& self, const std::string& component_name,
- PyModelPackageOptions& options) -> std::unique_ptr {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- auto result = std::make_unique();
- Ort::ThrowOnError(api->SelectComponent(
- self.ctx_, component_name.c_str(), options.opts_, &result->ctx_));
- return result;
- },
- py::arg("component_name"), py::arg("options"),
- R"pbdoc(Select a component and resolve its variant based on the provided options.
-Returns a ModelPackageComponentContext for inspecting the selected variant.)pbdoc");
-
- py::class_(m, "ModelPackageOptions",
- R"pbdoc(Options used for variant selection in a model package.
-Created from a SessionOptions to capture EP configuration for variant matching.)pbdoc")
- .def(py::init([](PySessionOptions& session_options) {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- auto result = std::make_unique();
- Ort::ThrowOnError(api->CreateModelPackageOptionsFromSessionOptions(
- GetOrtEnv(), &session_options, &result->opts_));
- return result;
- }),
- py::arg("session_options"),
- R"pbdoc(Create model package options from a SessionOptions instance.
-The EP configured on the session options is used for variant selection.)pbdoc");
-
- py::class_(m, "ModelPackageComponentContext",
- R"pbdoc(Represents a selected component within a model package.
-Provides access to the resolved variant's files, session options, and metadata.)pbdoc")
- .def(
- "get_selected_variant_folder_path",
- [](PyModelPackageComponentContext& self) -> std::string {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- const ORTCHAR_T* path = nullptr;
- Ort::ThrowOnError(api->ModelPackageComponent_GetSelectedVariantFolderPath(self.ctx_, &path));
- return PathToUTF8String(PathString(path));
- },
- R"pbdoc(Get the folder path of the selected variant.)pbdoc")
- .def(
- "get_selected_variant_name",
- [](PyModelPackageComponentContext& self) -> std::string {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- const char* name = nullptr;
- Ort::ThrowOnError(api->ModelPackageComponent_GetSelectedVariantName(
- self.ctx_, &name));
- return name ? std::string(name) : std::string();
- },
- R"pbdoc(Get the name of the selected variant.)pbdoc")
- .def(
- "create_session",
- [](PyModelPackageComponentContext& self, py::object session_options_obj) -> std::unique_ptr {
- const auto* api = Ort::GetApi().GetModelPackageApi();
- OrtSession* ort_session = nullptr;
- if (session_options_obj.is_none()) {
- Ort::ThrowOnError(api->CreateSession(GetOrtEnv(), self.ctx_, nullptr, &ort_session));
- } else {
- auto& so = session_options_obj.cast();
- Ort::ThrowOnError(api->CreateSession(GetOrtEnv(), self.ctx_, &so, &ort_session));
- }
- // OrtSession* is a reinterpret_cast of InferenceSession*
- auto* inference_session = reinterpret_cast(ort_session);
- std::unique_ptr session_ptr(inference_session);
- return std::make_unique(std::move(session_ptr));
- },
- py::arg("session_options") = py::none(),
- R"pbdoc(Create an InferenceSession from the selected component variant.
-
-Args:
- session_options: Optional SessionOptions override. If None, uses the options
- captured during variant selection with per-file options merged on top.
- If provided, variant-specific options are NOT applied.
-
-Returns:
- An InferenceSession ready for inference.)pbdoc");
-#endif // !defined(ORT_MINIMAL_BUILD)
}
bool InitArray() {
diff --git a/onnxruntime/test/autoep/test_model_package.cc b/onnxruntime/test/autoep/test_model_package.cc
index 6fb3f8e6ba82f..34f73eb69b149 100644
--- a/onnxruntime/test/autoep/test_model_package.cc
+++ b/onnxruntime/test/autoep/test_model_package.cc
@@ -12,6 +12,7 @@
#include "gtest/gtest.h"
#include "core/session/model_package/model_package_context.h"
+#include "core/session/onnxruntime_experimental_c_api.h"
#include "core/session/abi_devices.h"
#include "test/autoep/test_autoep_utils.h"
#include "test/util/include/asserts.h"
@@ -22,6 +23,90 @@ extern std::unique_ptr ort_env;
namespace onnxruntime {
namespace test {
namespace {
+
+// Typed function pointers for every OrtModelPackageApi_* experimental entry,
+// resolved once via the experimental name-based lookup.
+struct ModelPackageFns {
+ OrtExperimental_OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions_SinceV28_Fn
+ CreateModelPackageOptionsFromSessionOptions{nullptr};
+ OrtExperimental_OrtModelPackageApi_ReleaseModelPackageOptions_SinceV28_Fn
+ ReleaseModelPackageOptions{nullptr};
+ OrtExperimental_OrtModelPackageApi_CreateModelPackageContext_SinceV28_Fn
+ CreateModelPackageContext{nullptr};
+ OrtExperimental_OrtModelPackageApi_ReleaseModelPackageContext_SinceV28_Fn
+ ReleaseModelPackageContext{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackage_GetSchemaVersion_SinceV28_Fn
+ ModelPackage_GetSchemaVersion{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackage_GetComponentCount_SinceV28_Fn
+ ModelPackage_GetComponentCount{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackage_GetComponentNames_SinceV28_Fn
+ ModelPackage_GetComponentNames{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackage_GetVariantCount_SinceV28_Fn
+ ModelPackage_GetVariantCount{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackage_GetVariantNames_SinceV28_Fn
+ ModelPackage_GetVariantNames{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackage_GetVariantEpName_SinceV28_Fn
+ ModelPackage_GetVariantEpName{nullptr};
+ OrtExperimental_OrtModelPackageApi_SelectComponent_SinceV28_Fn
+ SelectComponent{nullptr};
+ OrtExperimental_OrtModelPackageApi_ReleaseModelPackageComponentContext_SinceV28_Fn
+ ReleaseModelPackageComponentContext{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantName_SinceV28_Fn
+ ModelPackageComponent_GetSelectedVariantName{nullptr};
+ OrtExperimental_OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantFolderPath_SinceV28_Fn
+ ModelPackageComponent_GetSelectedVariantFolderPath{nullptr};
+ OrtExperimental_OrtModelPackageApi_CreateSession_SinceV28_Fn
+ CreateSession{nullptr};
+};
+
+inline const ModelPackageFns& GetModelPackageFns() {
+ static const ModelPackageFns fns = []() {
+ const OrtApi* api = &Ort::GetApi();
+ ModelPackageFns f;
+#define RESOLVE(member, getter) \
+ do { \
+ f.member = Ort::Experimental::getter(api); \
+ if (f.member == nullptr) { \
+ throw std::runtime_error(std::string("Failed to resolve experimental " \
+ "OrtModelPackageApi_") + \
+ #member "_SinceV28"); \
+ } \
+ } while (0)
+ RESOLVE(CreateModelPackageOptionsFromSessionOptions,
+ Get_OrtModelPackageApi_CreateModelPackageOptionsFromSessionOptions_SinceV28_Fn);
+ RESOLVE(ReleaseModelPackageOptions,
+ Get_OrtModelPackageApi_ReleaseModelPackageOptions_SinceV28_Fn);
+ RESOLVE(CreateModelPackageContext,
+ Get_OrtModelPackageApi_CreateModelPackageContext_SinceV28_Fn);
+ RESOLVE(ReleaseModelPackageContext,
+ Get_OrtModelPackageApi_ReleaseModelPackageContext_SinceV28_Fn);
+ RESOLVE(ModelPackage_GetSchemaVersion,
+ Get_OrtModelPackageApi_ModelPackage_GetSchemaVersion_SinceV28_Fn);
+ RESOLVE(ModelPackage_GetComponentCount,
+ Get_OrtModelPackageApi_ModelPackage_GetComponentCount_SinceV28_Fn);
+ RESOLVE(ModelPackage_GetComponentNames,
+ Get_OrtModelPackageApi_ModelPackage_GetComponentNames_SinceV28_Fn);
+ RESOLVE(ModelPackage_GetVariantCount,
+ Get_OrtModelPackageApi_ModelPackage_GetVariantCount_SinceV28_Fn);
+ RESOLVE(ModelPackage_GetVariantNames,
+ Get_OrtModelPackageApi_ModelPackage_GetVariantNames_SinceV28_Fn);
+ RESOLVE(ModelPackage_GetVariantEpName,
+ Get_OrtModelPackageApi_ModelPackage_GetVariantEpName_SinceV28_Fn);
+ RESOLVE(SelectComponent,
+ Get_OrtModelPackageApi_SelectComponent_SinceV28_Fn);
+ RESOLVE(ReleaseModelPackageComponentContext,
+ Get_OrtModelPackageApi_ReleaseModelPackageComponentContext_SinceV28_Fn);
+ RESOLVE(ModelPackageComponent_GetSelectedVariantName,
+ Get_OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantName_SinceV28_Fn);
+ RESOLVE(ModelPackageComponent_GetSelectedVariantFolderPath,
+ Get_OrtModelPackageApi_ModelPackageComponent_GetSelectedVariantFolderPath_SinceV28_Fn);
+ RESOLVE(CreateSession,
+ Get_OrtModelPackageApi_CreateSession_SinceV28_Fn);
+#undef RESOLVE
+ return f;
+ }();
+ return fns;
+}
// ------------------------------------------------------------------
// Helpers to build a test model package on disk
// ------------------------------------------------------------------
@@ -233,26 +318,25 @@ std::filesystem::path CreateModelPackageApiTestPackage(bool multi_file_variant =
TEST(ModelPackageApiTest, PackageContextQueries) {
const auto package_root = CreateModelPackageApiTestPackage();
- const OrtModelPackageApi* pkg_api = Ort::GetApi().GetModelPackageApi();
- ASSERT_NE(pkg_api, nullptr);
+ const auto& pkg_api = GetModelPackageFns();
- auto context_deleter = [pkg_api](OrtModelPackageContext* p) {
- if (p) pkg_api->ReleaseModelPackageContext(p);
+ auto context_deleter = [&pkg_api](OrtModelPackageContext* p) {
+ if (p) pkg_api.ReleaseModelPackageContext(p);
};
std::unique_ptr model_pkg_context(nullptr, context_deleter);
OrtModelPackageContext* raw_context = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageContext(package_root.c_str(), &raw_context));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageContext(package_root.c_str(), &raw_context));
model_pkg_context.reset(raw_context);
// Query: component count + names
size_t component_count = 0;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetComponentCount(model_pkg_context.get(), &component_count));
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetComponentCount(model_pkg_context.get(), &component_count));
ASSERT_EQ(component_count, 1u);
const char* const* component_names = nullptr;
size_t component_name_count = 0;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetComponentNames(
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetComponentNames(
model_pkg_context.get(), &component_names, &component_name_count));
ASSERT_EQ(component_name_count, 1u);
ASSERT_NE(component_names, nullptr);
@@ -261,13 +345,13 @@ TEST(ModelPackageApiTest, PackageContextQueries) {
// Query: variant count + names
size_t variant_count = 0;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetVariantCount(
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetVariantCount(
model_pkg_context.get(), "model_1", &variant_count));
ASSERT_EQ(variant_count, 2u);
const char* const* variant_names = nullptr;
size_t variant_name_count = 0;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetVariantNames(
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetVariantNames(
model_pkg_context.get(), "model_1", &variant_names, &variant_name_count));
ASSERT_EQ(variant_name_count, 2u);
@@ -294,17 +378,16 @@ TEST(ModelPackageApiTest, SingleFileVariantInComponent_SelectComponentAndCreateS
std::unordered_map ep_options;
session_options.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options);
- const OrtModelPackageApi* pkg_api = Ort::GetApi().GetModelPackageApi();
- ASSERT_NE(pkg_api, nullptr);
+ const auto& pkg_api = GetModelPackageFns();
- auto options_deleter = [pkg_api](OrtModelPackageOptions* p) {
- if (p) pkg_api->ReleaseModelPackageOptions(p);
+ auto options_deleter = [&pkg_api](OrtModelPackageOptions* p) {
+ if (p) pkg_api.ReleaseModelPackageOptions(p);
};
- auto context_deleter = [pkg_api](OrtModelPackageContext* p) {
- if (p) pkg_api->ReleaseModelPackageContext(p);
+ auto context_deleter = [&pkg_api](OrtModelPackageContext* p) {
+ if (p) pkg_api.ReleaseModelPackageContext(p);
};
- auto component_context_deleter = [pkg_api](OrtModelPackageComponentContext* p) {
- if (p) pkg_api->ReleaseModelPackageComponentContext(p);
+ auto component_context_deleter = [&pkg_api](OrtModelPackageComponentContext* p) {
+ if (p) pkg_api.ReleaseModelPackageComponentContext(p);
};
std::unique_ptr model_pkg_options(nullptr, options_deleter);
@@ -312,25 +395,25 @@ TEST(ModelPackageApiTest, SingleFileVariantInComponent_SelectComponentAndCreateS
std::unique_ptr component_context(nullptr, component_context_deleter);
OrtModelPackageOptions* raw_options = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageOptionsFromSessionOptions(*ort_env, session_options, &raw_options));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageOptionsFromSessionOptions(*ort_env, session_options, &raw_options));
model_pkg_options.reset(raw_options);
OrtModelPackageContext* raw_context = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageContext(package_root.c_str(), &raw_context));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageContext(package_root.c_str(), &raw_context));
model_pkg_context.reset(raw_context);
OrtModelPackageComponentContext* raw_component_context = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->SelectComponent(model_pkg_context.get(),
- "model_1",
- model_pkg_options.get(),
- &raw_component_context));
+ ASSERT_ORTSTATUS_OK(pkg_api.SelectComponent(model_pkg_context.get(),
+ "model_1",
+ model_pkg_options.get(),
+ &raw_component_context));
component_context.reset(raw_component_context);
OrtSession* raw_session = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateSession(*ort_env,
- component_context.get(),
- session_options,
- &raw_session));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateSession(*ort_env,
+ component_context.get(),
+ session_options,
+ &raw_session));
Ort::Session session(raw_session);
Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
@@ -921,33 +1004,32 @@ TEST(ModelPackageApiTest, GetVariantEpName_ReturnsSingleEp) {
os << R"({"filename":"mul_1.onnx"})";
}
- const OrtModelPackageApi* pkg_api = Ort::GetApi().GetModelPackageApi();
- ASSERT_NE(pkg_api, nullptr);
+ const auto& pkg_api = GetModelPackageFns();
- auto context_deleter = [pkg_api](OrtModelPackageContext* p) {
- if (p) pkg_api->ReleaseModelPackageContext(p);
+ auto context_deleter = [&pkg_api](OrtModelPackageContext* p) {
+ if (p) pkg_api.ReleaseModelPackageContext(p);
};
std::unique_ptr ctx(nullptr, context_deleter);
OrtModelPackageContext* raw_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageContext(package_root.c_str(), &raw_ctx));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageContext(package_root.c_str(), &raw_ctx));
ctx.reset(raw_ctx);
// variant_1 targets example_ep
const char* ep1 = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetVariantEpName(
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetVariantEpName(
ctx.get(), "model_1", "variant_1", &ep1));
ASSERT_NE(ep1, nullptr);
EXPECT_STREQ(ep1, "example_ep");
// variant_2 targets other_ep
const char* ep2 = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetVariantEpName(
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetVariantEpName(
ctx.get(), "model_1", "variant_2", &ep2));
ASSERT_NE(ep2, nullptr);
EXPECT_STREQ(ep2, "other_ep");
// Optional out-parameter: callers can pass NULL.
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackage_GetVariantEpName(
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackage_GetVariantEpName(
ctx.get(), "model_1", "variant_1", nullptr));
std::filesystem::remove_all(package_root, ec);
@@ -990,32 +1072,31 @@ TEST(ModelPackageTest, VariantSelector_TieBreakIsDeterministic) {
std::unordered_map ep_options;
session_options.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options);
- const OrtModelPackageApi* pkg_api = Ort::GetApi().GetModelPackageApi();
- ASSERT_NE(pkg_api, nullptr);
+ const auto& pkg_api = GetModelPackageFns();
- auto options_deleter = [pkg_api](OrtModelPackageOptions* p) { if (p) pkg_api->ReleaseModelPackageOptions(p); };
- auto context_deleter = [pkg_api](OrtModelPackageContext* p) { if (p) pkg_api->ReleaseModelPackageContext(p); };
- auto component_context_deleter = [pkg_api](OrtModelPackageComponentContext* p) {
- if (p) pkg_api->ReleaseModelPackageComponentContext(p);
+ auto options_deleter = [&pkg_api](OrtModelPackageOptions* p) { if (p) pkg_api.ReleaseModelPackageOptions(p); };
+ auto context_deleter = [&pkg_api](OrtModelPackageContext* p) { if (p) pkg_api.ReleaseModelPackageContext(p); };
+ auto component_context_deleter = [&pkg_api](OrtModelPackageComponentContext* p) {
+ if (p) pkg_api.ReleaseModelPackageComponentContext(p);
};
std::unique_ptr mp_opts(nullptr, options_deleter);
std::unique_ptr ctx(nullptr, context_deleter);
std::unique_ptr comp_ctx(nullptr, component_context_deleter);
OrtModelPackageOptions* raw_mp_opts = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageOptionsFromSessionOptions(*ort_env, session_options, &raw_mp_opts));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageOptionsFromSessionOptions(*ort_env, session_options, &raw_mp_opts));
mp_opts.reset(raw_mp_opts);
OrtModelPackageContext* raw_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageContext(package_root.c_str(), &raw_ctx));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageContext(package_root.c_str(), &raw_ctx));
ctx.reset(raw_ctx);
OrtModelPackageComponentContext* raw_comp_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->SelectComponent(ctx.get(), "model_1", mp_opts.get(), &raw_comp_ctx));
+ ASSERT_ORTSTATUS_OK(pkg_api.SelectComponent(ctx.get(), "model_1", mp_opts.get(), &raw_comp_ctx));
comp_ctx.reset(raw_comp_ctx);
const ORTCHAR_T* selected_folder = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackageComponent_GetSelectedVariantFolderPath(comp_ctx.get(), &selected_folder));
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackageComponent_GetSelectedVariantFolderPath(comp_ctx.get(), &selected_folder));
ASSERT_NE(selected_folder, nullptr);
// Path looks like .../models/model_1/ -- the folder name is the variant.
@@ -1082,28 +1163,27 @@ TEST(ModelPackageTest, VariantSessionOptions_DispatchedThroughAddSessionConfigEn
std::unordered_map ep_options;
session_options.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options);
- const OrtModelPackageApi* pkg_api = Ort::GetApi().GetModelPackageApi();
- ASSERT_NE(pkg_api, nullptr);
+ const auto& pkg_api = GetModelPackageFns();
- auto options_deleter = [pkg_api](OrtModelPackageOptions* p) { if (p) pkg_api->ReleaseModelPackageOptions(p); };
- auto context_deleter = [pkg_api](OrtModelPackageContext* p) { if (p) pkg_api->ReleaseModelPackageContext(p); };
- auto component_context_deleter = [pkg_api](OrtModelPackageComponentContext* p) {
- if (p) pkg_api->ReleaseModelPackageComponentContext(p);
+ auto options_deleter = [&pkg_api](OrtModelPackageOptions* p) { if (p) pkg_api.ReleaseModelPackageOptions(p); };
+ auto context_deleter = [&pkg_api](OrtModelPackageContext* p) { if (p) pkg_api.ReleaseModelPackageContext(p); };
+ auto component_context_deleter = [&pkg_api](OrtModelPackageComponentContext* p) {
+ if (p) pkg_api.ReleaseModelPackageComponentContext(p);
};
std::unique_ptr mp_opts(nullptr, options_deleter);
std::unique_ptr ctx(nullptr, context_deleter);
std::unique_ptr comp_ctx(nullptr, component_context_deleter);
OrtModelPackageOptions* raw_mp_opts = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageOptionsFromSessionOptions(*ort_env, session_options, &raw_mp_opts));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageOptionsFromSessionOptions(*ort_env, session_options, &raw_mp_opts));
mp_opts.reset(raw_mp_opts);
OrtModelPackageContext* raw_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageContext(package_root.c_str(), &raw_ctx));
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageContext(package_root.c_str(), &raw_ctx));
ctx.reset(raw_ctx);
OrtModelPackageComponentContext* raw_comp_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->SelectComponent(ctx.get(), "model_1", mp_opts.get(), &raw_comp_ctx));
+ ASSERT_ORTSTATUS_OK(pkg_api.SelectComponent(ctx.get(), "model_1", mp_opts.get(), &raw_comp_ctx));
comp_ctx.reset(raw_comp_ctx);
// CreateSession iterates the per-file session_options and dispatches each through OrtApis::AddSessionConfigEntry.
@@ -1111,7 +1191,7 @@ TEST(ModelPackageTest, VariantSessionOptions_DispatchedThroughAddSessionConfigEn
// Pass nullptr for session_options so the metadata-merge path runs (it is skipped when the caller
// supplies their own session_options).
OrtSession* raw_session = nullptr;
- OrtStatus* st = pkg_api->CreateSession(*ort_env, comp_ctx.get(), /*session_options=*/nullptr, &raw_session);
+ OrtStatus* st = pkg_api.CreateSession(*ort_env, comp_ctx.get(), /*session_options=*/nullptr, &raw_session);
// Clean up session first to avoid leaks if assertion fails.
if (raw_session != nullptr) {
Ort::GetApi().ReleaseSession(raw_session);
@@ -1131,60 +1211,6 @@ TEST(ModelPackageTest, VariantSessionOptions_DispatchedThroughAddSessionConfigEn
std::filesystem::remove_all(package_root, ec);
}
-// Test that the C++ RAII wrappers (Ort::ModelPackageContext, etc.) work correctly.
-TEST(ModelPackageApiTest, CxxWrappers_PackageContextQueries) {
- const auto package_root = CreateModelPackageApiTestPackage();
-
- Ort::ModelPackageContext ctx(package_root.c_str());
-
- // Component queries
- EXPECT_EQ(ctx.GetComponentCount(), 1u);
- auto component_names = ctx.GetComponentNames();
- ASSERT_EQ(component_names.size(), 1u);
- EXPECT_EQ(component_names[0], "model_1");
-
- // Variant queries
- EXPECT_EQ(ctx.GetVariantCount("model_1"), 2u);
- auto variant_names = ctx.GetVariantNames("model_1");
- ASSERT_EQ(variant_names.size(), 2u);
- std::unordered_set variant_set(variant_names.begin(), variant_names.end());
- EXPECT_EQ(variant_set.count("variant_1"), 1u);
- EXPECT_EQ(variant_set.count("variant_2"), 1u);
-
- std::error_code ec;
- std::filesystem::remove_all(package_root, ec);
-}
-
-TEST(ModelPackageApiTest, CxxWrappers_SelectComponentAndQueryFileAccessors) {
- const auto package_root = CreateModelPackageApiTestPackage();
-
- RegisteredEpDeviceUniquePtr example_ep;
- ASSERT_NO_FATAL_FAILURE(Utils::RegisterAndGetExampleEp(*ort_env, Utils::example_ep_info, example_ep));
- Ort::ConstEpDevice plugin_ep_device(example_ep.get());
-
- Ort::SessionOptions so;
- std::unordered_map ep_options;
- so.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options);
- Ort::ModelPackageOptions pkg_opts(*ort_env, so);
-
- Ort::ModelPackageContext ctx(package_root.c_str());
- auto cix = ctx.SelectComponent("model_1", pkg_opts);
-
- // Folder path should be non-empty
- auto folder = cix.GetSelectedVariantFolderPath();
- EXPECT_FALSE(folder.empty());
-
- // Selected variant name should not throw
- auto variant_name = cix.GetSelectedVariantName();
- EXPECT_FALSE(variant_name.empty());
-
- // CreateSession via C++ wrapper
- auto session = cix.CreateSession(*ort_env, so);
-
- std::error_code ec;
- std::filesystem::remove_all(package_root, ec);
-}
-
// ------------------------------------------------------------------
// Test: GetSelectedVariantFolderPath returns correct path even when variant.json is absent.
// ------------------------------------------------------------------
@@ -1221,31 +1247,29 @@ TEST(ModelPackageApiTest, FolderPath_ReturnsCorrectPath_WhenVariantJsonAbsent) {
Ort::SessionOptions so;
std::unordered_map ep_options;
so.AppendExecutionProvider_V2(*ort_env, {plugin_ep_device}, ep_options);
- Ort::ModelPackageOptions pkg_opts(*ort_env, so);
- const OrtModelPackageApi* pkg_api = Ort::GetApi().GetModelPackageApi();
- ASSERT_NE(pkg_api, nullptr);
+ const auto& pkg_api = GetModelPackageFns();
OrtModelPackageOptions* raw_mp_opts = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageOptionsFromSessionOptions(*ort_env, so, &raw_mp_opts));
- auto options_deleter = [pkg_api](OrtModelPackageOptions* p) { if (p) pkg_api->ReleaseModelPackageOptions(p); };
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageOptionsFromSessionOptions(*ort_env, so, &raw_mp_opts));
+ auto options_deleter = [&pkg_api](OrtModelPackageOptions* p) { if (p) pkg_api.ReleaseModelPackageOptions(p); };
std::unique_ptr mp_opts(raw_mp_opts, options_deleter);
OrtModelPackageContext* raw_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->CreateModelPackageContext(package_root.c_str(), &raw_ctx));
- auto context_deleter = [pkg_api](OrtModelPackageContext* p) { if (p) pkg_api->ReleaseModelPackageContext(p); };
+ ASSERT_ORTSTATUS_OK(pkg_api.CreateModelPackageContext(package_root.c_str(), &raw_ctx));
+ auto context_deleter = [&pkg_api](OrtModelPackageContext* p) { if (p) pkg_api.ReleaseModelPackageContext(p); };
std::unique_ptr ctx(raw_ctx, context_deleter);
OrtModelPackageComponentContext* raw_comp_ctx = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->SelectComponent(ctx.get(), "model_1", mp_opts.get(), &raw_comp_ctx));
- auto component_context_deleter = [pkg_api](OrtModelPackageComponentContext* p) {
- if (p) pkg_api->ReleaseModelPackageComponentContext(p);
+ ASSERT_ORTSTATUS_OK(pkg_api.SelectComponent(ctx.get(), "model_1", mp_opts.get(), &raw_comp_ctx));
+ auto component_context_deleter = [&pkg_api](OrtModelPackageComponentContext* p) {
+ if (p) pkg_api.ReleaseModelPackageComponentContext(p);
};
std::unique_ptr comp_ctx(raw_comp_ctx, component_context_deleter);
// GetSelectedVariantFolderPath should return the variant directory even without variant.json.
const ORTCHAR_T* selected_folder = nullptr;
- ASSERT_ORTSTATUS_OK(pkg_api->ModelPackageComponent_GetSelectedVariantFolderPath(comp_ctx.get(), &selected_folder));
+ ASSERT_ORTSTATUS_OK(pkg_api.ModelPackageComponent_GetSelectedVariantFolderPath(comp_ctx.get(), &selected_folder));
ASSERT_NE(selected_folder, nullptr);
const auto result_path = std::filesystem::path(selected_folder);