Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 28 additions & 25 deletions include/onnxruntime/core/session/onnxruntime_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -7697,7 +7697,7 @@ struct OrtModelEditorApi {
/** \brief Set the inputs for the OrtGraph.
*
* Set the graph inputs. This will replace any existing inputs with the new values.
* The OrtGraph takes ownership of the OrtValueInfo instances and you should NOT call ReleaseOrtValueInfo.
* The OrtGraph takes ownership of the OrtValueInfo instances and you should NOT call OrtApi::ReleaseValueInfo.
*
* \param[in] graph The OrtGraph instance to update.
* \param[in] inputs The input OrtValueInfo instances.
Expand All @@ -7713,7 +7713,7 @@ struct OrtModelEditorApi {
/** \brief Set the outputs for the OrtGraph.
*
* Set the graph outputs. This will replace any existing outputs with the new values.
* The OrtGraph takes ownership of the OrtValueInfo instances provided and you should NOT call ReleaseOrtValueInfo.
* The OrtGraph takes ownership of the OrtValueInfo instances provided and you should NOT call OrtApi::ReleaseValueInfo.
*
* \param[in] graph The OrtGraph instance to update.
* \param[in] outputs The output OrtValueInfo instances.
Expand All @@ -7728,27 +7728,30 @@ struct OrtModelEditorApi {

/** \brief Add an initializer to the OrtGraph
*
* ORT will take ownership of the OrtValue and you should NOT call ReleaseOrtValue.
* ORT will copy the OrtValue wrapper internally. The caller retains ownership of the OrtValue and should
* release it with OrtApi::ReleaseValue when done. Note that the underlying data buffer is not copied.
* If the OrtValue was created with a user-provided buffer (e.g., OrtApi::CreateTensorWithDataAsOrtValue),
* that buffer must remain valid for the duration of the inference session.
Comment thread
vraspar marked this conversation as resolved.
*
* Two options:
*
* Allocated memory:
* Use CreateTensorAsOrtValue (allocates memory) and populate the tensor with the data.
* Use OrtApi::CreateTensorAsOrtValue (allocates memory) and populate the tensor with the data.
* Set `data_is_external` to false.
*
* Pre-existing memory:
* Use CreateTensorWithDataAsOrtValue or CreateTensorWithDataAndDeleterAsOrtValue to create an OrtValue
* Use OrtApi::CreateTensorWithDataAsOrtValue or OrtApi::CreateTensorWithDataAndDeleterAsOrtValue to create an OrtValue
* with a tensor that contains a pointer to the existing data.
* Set `data_is_external` to true.
*
* The pointer must remain valid for the duration of the inference session.
* If using CreateTensorWithDataAsOrtValue you are responsible for freeing the memory after the inference session
* If using OrtApi::CreateTensorWithDataAsOrtValue you are responsible for freeing the memory after the inference session
* is released.
* If using CreateTensorWithDataAndDeleterAsOrtValue, ORT will free the memory using the provided deleter as
* If using OrtApi::CreateTensorWithDataAndDeleterAsOrtValue, ORT will free the memory using the provided deleter as
* soon as the OrtValue is no longer in use.
*
* NOTE: A tensor containing pre-existing memory MUST have 128 bytes of data or more.
* For smaller tensors use CreateTensorAsOrtValue.
* For smaller tensors use OrtApi::CreateTensorAsOrtValue.
*
* ONNX shape inferencing does not support external data. An initializer involved in shape inferencing is
* typically small (a single value or limited by the rank of a tensor) and uses less than 128 bytes of
Expand All @@ -7757,19 +7760,19 @@ struct OrtModelEditorApi {
*
* \param[in] graph The OrtGraph instance to update.
* \param[in] name The value name for the initializer.
* \param[in] tensor The OrtValue instance containing the tensor data.
* \param[in] data_is_external Set to true if the data is external and should not be copied.
* \param[in] ort_value The OrtValue instance containing the tensor data.
* \param[in] data_is_external Set to true if the data is external and should not be serialized into the model.
*
* \snippet{doc} snippets.dox OrtStatus Return Value
*
* \since Version 1.22.
*/
ORT_API2_STATUS(AddInitializerToGraph, _Inout_ OrtGraph* graph, _In_ const char* name, _In_ OrtValue* tensor,
bool data_is_external);
ORT_API2_STATUS(AddInitializerToGraph, _Inout_ OrtGraph* graph, _In_ const char* name,
_In_ const OrtValue* ort_value, bool data_is_external);

/** \brief Add an OrtNode to an OrtGraph
*
* Add the node to the graph. The OrtGraph will take ownership of OrtNode and you should NOT call ReleaseOrtNode.
* Add the node to the graph. The OrtGraph will take ownership of OrtNode and you should NOT call OrtApi::ReleaseNode.
*
* \param[in] graph The OrtGraph instance to update.
* \param[in] node The OrtNode instance to add to the graph.
Expand Down Expand Up @@ -7808,7 +7811,7 @@ struct OrtModelEditorApi {
*
* Add the graph to a model. This should be called once when creating a new model.
*
* The OrtModel takes ownership of the OrtGraph and you should NOT call ReleaseOrtGraph.
* The OrtModel takes ownership of the OrtGraph and you should NOT call OrtApi::ReleaseGraph.
*
* \param[in] model The OrtModel instance to update.
* \param[in] graph The OrtGraph instance to add to the model.
Expand All @@ -7826,7 +7829,7 @@ struct OrtModelEditorApi {
* and SetGraphOutputs must have been called.
* This will validate the model, run optimizers, and prepare the session for inferencing.
*
* ReleaseOrtModel must be called to free the OrtModel after session creation.
* OrtApi::ReleaseModel must be called to free the OrtModel after session creation.
*
* \param[in] env The OrtEnv instance.
* \param[in] model The OrtModel instance.
Expand All @@ -7846,13 +7849,13 @@ struct OrtModelEditorApi {
* Nodes can be added before or after the existing nodes in the model. ONNX Runtime will connect the nodes when the
* model is finalized.
*
* To add nodes and initializers to the existing model, first create an OrtModel using CreateModel.
* Add nodes and initializers to the OrtModel using AddNodeToGraph and AddInitializerToGraph.
* Graph inputs/outputs should be updated with SetGraphInputs and SetGraphOutputs as needed to reflect changes made
* To add nodes and initializers to the existing model, first create an OrtModel using CreateModel().
* Add nodes and initializers to the OrtModel using AddNodeToGraph() and AddInitializerToGraph().
* Graph inputs/outputs should be updated with SetGraphInputs() and SetGraphOutputs() as needed to reflect changes made
* by the new nodes. The list of graph inputs/outputs should be for the overall model and not just the new nodes.
*
* Add the new information from the OrtModel to the original model using ApplyModelToSession, and prepare the
* session for inferencing by calling FinalizeModelEditorSession.
* Add the new information from the OrtModel to the original model using ApplyModelToSession(), and prepare the
* session for inferencing by calling FinalizeModelEditorSession().
*
* \param{in} env The OrtEnv instance.
* \param{in} model_path The path to the existing ONNX model to augment.
Expand All @@ -7872,13 +7875,13 @@ struct OrtModelEditorApi {
* Nodes can be added before or after the existing nodes in the model. ONNX Runtime will connect the nodes when the
* model is finalized.
*
* To add nodes and initializers to the existing model, first create an OrtModel using CreateModel.
* Add nodes and initializers to the OrtModel using AddNodeToGraph and AddInitializerToGraph.
* Graph inputs/outputs should be updated with SetGraphInputs and SetGraphOutputs as needed to reflect changes made
* To add nodes and initializers to the existing model, first create an OrtModel using CreateModel().
* Add nodes and initializers to the OrtModel using AddNodeToGraph() and AddInitializerToGraph().
* Graph inputs/outputs should be updated with SetGraphInputs() and SetGraphOutputs() as needed to reflect changes made
* by the new nodes. The list of graph inputs/outputs should be for the overall model and not just the new nodes.
*
* Add the new information from the OrtModel to the original model using ApplyModelToSession, and prepare the
* session for inferencing by calling FinalizeModelEditorSession.
* Add the new information from the OrtModel to the original model using ApplyModelToSession(), and prepare the
* session for inferencing by calling FinalizeModelEditorSession().
*
* \param{in} env The OrtEnv instance.
* \param{in} model_data The model data for the existing model to augment.
Expand Down
2 changes: 1 addition & 1 deletion include/onnxruntime/core/session/onnxruntime_cxx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -3480,7 +3480,7 @@ struct GraphImpl : ConstGraphImpl<T> {
// <Wraps GetModelEditorApi().SetGraphOutputs()
void SetOutputs(std::vector<ValueInfo>& outputs);
// <Wraps GetModelEditorApi().AddInitializerToGraph()
void AddInitializer(const std::string& name, Value& initializer, bool data_is_external); // Graph takes ownership of Value
void AddInitializer(const std::string& name, const Value& initializer, bool data_is_external); // Graph copies the OrtValue internally
// <Wraps GetModelEditorApi().AddNodeToGraph()
void AddNode(Node& node); // Graph takes ownership of Node
#endif // !defined(ORT_MINIMAL_BUILD)
Expand Down
6 changes: 2 additions & 4 deletions include/onnxruntime/core/session/onnxruntime_cxx_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -3867,11 +3867,9 @@ inline void GraphImpl<T>::SetOutputs(std::vector<ValueInfo>& outputs) {
}

template <typename T>
inline void GraphImpl<T>::AddInitializer(const std::string& name, Value& initializer, bool data_is_external) {
// Graph takes ownership of `initializer`
// On error the ownership is not transferred.
inline void GraphImpl<T>::AddInitializer(const std::string& name, const Value& initializer, bool data_is_external) {
// Graph copies the OrtValue internally. Caller retains ownership of initializer.
Comment thread
vraspar marked this conversation as resolved.
ThrowOnError(GetModelEditorApi().AddInitializerToGraph(this->p_, name.c_str(), initializer, data_is_external));
initializer.release();
}

template <typename T>
Expand Down
6 changes: 3 additions & 3 deletions onnxruntime/core/graph/graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6716,12 +6716,12 @@ Status Graph::LoadFromModelEditorApiModel(const OrtGraph& api_graph, bool updati
}
};

auto add_initializers = [this](const std::unordered_map<std::string, std::unique_ptr<OrtValue>>& initializers,
auto add_initializers = [this](const std::unordered_map<std::string, OrtValue>& initializers,
bool is_external) {
for (auto& name_and_ortvalue : initializers) {
// convert from OrtValue to TensorProto
const std::string& name = name_and_ortvalue.first;
OrtValue& v = *name_and_ortvalue.second;
const OrtValue& v = name_and_ortvalue.second;

ORT_ENFORCE(v.IsTensor(), "Initializers must be Tensors");
const Tensor& t = v.Get<Tensor>();
Expand All @@ -6742,7 +6742,7 @@ Status Graph::LoadFromModelEditorApiModel(const OrtGraph& api_graph, bool updati
offset, t.SizeInBytes(), tensor_proto);

// add OrtValue to ortvalue_initializers_ to keep it alive and to store the deleter if provided.
ortvalue_initializers_.emplace(name, std::move(v));
ortvalue_initializers_.emplace(name, v);
} else {
onnxruntime::utils::SetRawDataInTensorProto(tensor_proto, t.DataRaw(), t.SizeInBytes());
}
Expand Down
7 changes: 5 additions & 2 deletions onnxruntime/core/graph/model_editor_api_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct ModelEditorValueInfo : public OrtValueInfo {
"OrtModelEditorApi does not support querying if a OrtValueInfo is defined in an outer scope.");
}

bool owned_ = false; // true after ownership transferred to a graph
std::string name;
std::unique_ptr<OrtTypeInfo> type_info;
};
Expand Down Expand Up @@ -154,6 +155,7 @@ struct ModelEditorNode : public OrtNode {
"OrtModelEditorApi does not support getting the parent graph for OrtNode");
}

bool owned_ = false; // true after ownership transferred to a graph
size_t id = 0;
std::string operator_name;
std::string domain_name;
Expand Down Expand Up @@ -235,8 +237,9 @@ struct ModelEditorGraph : public OrtGraph {

onnxruntime::InlinedVector<std::unique_ptr<onnxruntime::ModelEditorValueInfo>> inputs;
onnxruntime::InlinedVector<std::unique_ptr<onnxruntime::ModelEditorValueInfo>> outputs;
std::unordered_map<std::string, std::unique_ptr<OrtValue>> initializers;
std::unordered_map<std::string, std::unique_ptr<OrtValue>> external_initializers;
std::unordered_map<std::string, OrtValue> initializers;
std::unordered_map<std::string, OrtValue> external_initializers;
bool owned_ = false; // true after ownership transferred to a model
std::vector<std::unique_ptr<onnxruntime::ModelEditorNode>> nodes;
std::string name = "ModelEditorGraph";
std::filesystem::path model_path;
Expand Down
3 changes: 2 additions & 1 deletion onnxruntime/core/session/model_editor_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ ORT_API_STATUS_IMPL(SetGraphInputs, _In_ OrtGraph* graph,
_In_reads_(inputs_len) _In_ OrtValueInfo** inputs, _In_ size_t inputs_len);
ORT_API_STATUS_IMPL(SetGraphOutputs, _In_ OrtGraph* graph,
_In_reads_(outputs_len) _In_ OrtValueInfo** outputs, _In_ size_t outputs_len);
ORT_API_STATUS_IMPL(AddInitializerToGraph, _In_ OrtGraph* graph, _In_ const char* name, _Inout_ OrtValue* tensor,
ORT_API_STATUS_IMPL(AddInitializerToGraph, _In_ OrtGraph* graph, _In_ const char* name,
_In_ const OrtValue* ort_value,
bool data_is_external);
ORT_API_STATUS_IMPL(AddNodeToGraph, _In_ OrtGraph* graph, _Inout_ OrtNode* node);

Expand Down
Loading
Loading