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();