diff --git a/include/onnxruntime/core/session/onnxruntime_c_api.h b/include/onnxruntime/core/session/onnxruntime_c_api.h index 82e782112974f..e56a779a9d8b8 100644 --- a/include/onnxruntime/core/session/onnxruntime_c_api.h +++ b/include/onnxruntime/core/session/onnxruntime_c_api.h @@ -5560,6 +5560,21 @@ struct OrtApi { */ ORT_API2_STATUS(Graph_GetName, _In_ const OrtGraph* graph, _Outptr_ const char** graph_name); + /** \brief Get the filepath to the model from which an OrtGraph is constructed. + * + * \note The model's filepath is empty if the filepath is unknown, such as when the model is loaded from bytes + * via CreateSessionFromArray. + * + * \param[in] graph The OrtGraph instance. + * \param[out] model_path Output parameter set to the model's null-terminated filepath. + * Set to an empty path string if unknown. + * + * \snippet{doc} snippets.dox OrtStatus Return Value + * + * \since Version 1.23. + */ + ORT_API2_STATUS(Graph_GetModelPath, _In_ const OrtGraph* graph, _Outptr_ const ORTCHAR_T** model_path); + /** \brief Returns the ONNX IR version. * * \param[in] graph The OrtGraph instance. diff --git a/onnxruntime/core/graph/abi_graph_types.h b/onnxruntime/core/graph/abi_graph_types.h index 47fbe08da41ff..0e939f7986aac 100644 --- a/onnxruntime/core/graph/abi_graph_types.h +++ b/onnxruntime/core/graph/abi_graph_types.h @@ -276,6 +276,12 @@ struct OrtGraph { /// The graph's name. virtual const std::string& GetName() const = 0; + /// + /// Returns the model's path, which is empty if unknown. + /// + /// The model path. + virtual const ORTCHAR_T* GetModelPath() const = 0; + /// /// Returns the model's ONNX IR version. Important in checking for optional graph inputs /// (aka non-constant initializers), which were introduced in ONNX IR version 4. diff --git a/onnxruntime/core/graph/ep_api_types.cc b/onnxruntime/core/graph/ep_api_types.cc index f57543416a68f..b7e5351556c61 100644 --- a/onnxruntime/core/graph/ep_api_types.cc +++ b/onnxruntime/core/graph/ep_api_types.cc @@ -692,6 +692,10 @@ Status EpGraph::CreateImpl(std::unique_ptr ep_graph, const GraphViewer& const std::string& EpGraph::GetName() const { return graph_viewer_.Name(); } +const ORTCHAR_T* EpGraph::GetModelPath() const { + return graph_viewer_.ModelPath().c_str(); +} + int64_t EpGraph::GetOnnxIRVersion() const { return graph_viewer_.GetOnnxIRVersion(); } Status EpGraph::GetNumOperatorSets(size_t& num_operator_sets) const { diff --git a/onnxruntime/core/graph/ep_api_types.h b/onnxruntime/core/graph/ep_api_types.h index d3921e051e18a..b9a494364a12e 100644 --- a/onnxruntime/core/graph/ep_api_types.h +++ b/onnxruntime/core/graph/ep_api_types.h @@ -290,6 +290,9 @@ struct EpGraph : public OrtGraph { // Returns the graph's name. const std::string& GetName() const override; + // Returns the model path. + const ORTCHAR_T* GetModelPath() const override; + // Returns the model's ONNX IR version. int64_t GetOnnxIRVersion() const override; diff --git a/onnxruntime/core/graph/model_editor_api_types.h b/onnxruntime/core/graph/model_editor_api_types.h index 6e7e17374bb59..07c7080d74c7c 100644 --- a/onnxruntime/core/graph/model_editor_api_types.h +++ b/onnxruntime/core/graph/model_editor_api_types.h @@ -173,6 +173,8 @@ struct ModelEditorGraph : public OrtGraph { const std::string& GetName() const override { return name; } + const ORTCHAR_T* GetModelPath() const override { return model_path.c_str(); } + int64_t GetOnnxIRVersion() const override { return ONNX_NAMESPACE::Version::IR_VERSION; } @@ -227,6 +229,7 @@ struct ModelEditorGraph : public OrtGraph { std::unordered_map> external_initializers; std::vector> nodes; std::string name = "ModelEditorGraph"; + std::filesystem::path model_path; }; } // namespace onnxruntime diff --git a/onnxruntime/core/session/onnxruntime_c_api.cc b/onnxruntime/core/session/onnxruntime_c_api.cc index db2a62c77d1bc..6cd518ccef950 100644 --- a/onnxruntime/core/session/onnxruntime_c_api.cc +++ b/onnxruntime/core/session/onnxruntime_c_api.cc @@ -2579,6 +2579,17 @@ ORT_API_STATUS_IMPL(OrtApis::Graph_GetName, _In_ const OrtGraph* graph, _Outptr_ API_IMPL_END } +ORT_API_STATUS_IMPL(OrtApis::Graph_GetModelPath, _In_ const OrtGraph* graph, _Outptr_ const ORTCHAR_T** model_path) { + API_IMPL_BEGIN + if (model_path == nullptr) { + return OrtApis::CreateStatus(ORT_INVALID_ARGUMENT, "'model_path' argument is NULL"); + } + + *model_path = graph->GetModelPath(); + return nullptr; + API_IMPL_END +} + ORT_API_STATUS_IMPL(OrtApis::Graph_GetOnnxIRVersion, _In_ const OrtGraph* graph, _Out_ int64_t* ir_version) { API_IMPL_BEGIN if (ir_version == nullptr) { @@ -3719,6 +3730,7 @@ static constexpr OrtApi ort_api_1_to_23 = { &OrtApis::ValueInfo_IsConstantInitializer, &OrtApis::ValueInfo_IsFromOuterScope, &OrtApis::Graph_GetName, + &OrtApis::Graph_GetModelPath, &OrtApis::Graph_GetOnnxIRVersion, &OrtApis::Graph_GetNumOperatorSets, &OrtApis::Graph_GetOperatorSets, diff --git a/onnxruntime/core/session/ort_apis.h b/onnxruntime/core/session/ort_apis.h index 9ab927006c320..81d6c39b4e7be 100644 --- a/onnxruntime/core/session/ort_apis.h +++ b/onnxruntime/core/session/ort_apis.h @@ -630,6 +630,7 @@ ORT_API_STATUS_IMPL(ValueInfo_IsFromOuterScope, _In_ const OrtValueInfo* value_i // OrtGraph ORT_API_STATUS_IMPL(Graph_GetName, _In_ const OrtGraph* graph, _Outptr_ const char** graph_name); +ORT_API_STATUS_IMPL(Graph_GetModelPath, _In_ const OrtGraph* graph, _Outptr_ const ORTCHAR_T** model_path); ORT_API_STATUS_IMPL(Graph_GetOnnxIRVersion, _In_ const OrtGraph* graph, _Out_ int64_t* onnx_ir_version); ORT_API_STATUS_IMPL(Graph_GetNumOperatorSets, _In_ const OrtGraph* graph, _Out_ size_t* num_operator_sets); ORT_API_STATUS_IMPL(Graph_GetOperatorSets, _In_ const OrtGraph* graph, diff --git a/onnxruntime/test/ep_graph/test_ep_graph.cc b/onnxruntime/test/ep_graph/test_ep_graph.cc index 17e829e37f729..3181e63c0fb52 100644 --- a/onnxruntime/test/ep_graph/test_ep_graph.cc +++ b/onnxruntime/test/ep_graph/test_ep_graph.cc @@ -535,6 +535,12 @@ static void Check_Graph_GetSubgraph(const OrtGraph& api_graph) { static void CheckGraphCApi(const GraphViewer& graph_viewer, const OrtGraph& api_graph) { const OrtApi& ort_api = Ort::GetApi(); + // Check the path to model. + const std::filesystem::path& model_path = graph_viewer.ModelPath(); + const ORTCHAR_T* api_model_path = nullptr; + ASSERT_ORTSTATUS_OK(ort_api.Graph_GetModelPath(&api_graph, &api_model_path)); + ASSERT_EQ(PathString(api_model_path), PathString(model_path.c_str())); + // Check graph inputs. const auto& graph_input_node_args = graph_viewer.GetInputsIncludingInitializers();