Add Experimental API for setting model name (#10518)

* Add experimental API for editing model name

* Change EditModelName to 'SetName'

* Change API to pass c_string

* Update SetName to edit the proto

* Test that the model proto gets changed

* Remove comments

* Skip inbox tests

* Use filehelper path

Co-authored-by: Numfor Mbiziwo-Tiapo <numform@microsoft.com>
This commit is contained in:
Numfor Tiapo 2022-02-25 14:23:49 -08:00 committed by GitHub
parent 36c3271546
commit 5fbfca3d58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 87 additions and 0 deletions

View file

@ -24,6 +24,7 @@ ORT_API_STATUS(CreateModelFromData, _In_ void* data, _In_ size_t size, _Outptr_
ORT_API_STATUS(CloneModel, _In_ const OrtModel* in, _Outptr_ OrtModel** out);
ORT_API_STATUS(ModelGetAuthor, _In_ const OrtModel* model, _Out_ const char** const author, _Out_ size_t* len);
ORT_API_STATUS(ModelGetName, _In_ const OrtModel* model, _Out_ const char** const name, _Out_ size_t* len);
ORT_API_STATUS(ModelSetName, _In_ const OrtModel* model, _In_ const char* name);
ORT_API_STATUS(ModelGetDomain, _In_ const OrtModel* model, _Out_ const char** const domain, _Out_ size_t* len);
ORT_API_STATUS(ModelGetDescription, _In_ const OrtModel* model, _Out_ const char** const description, _Out_ size_t* len);
ORT_API_STATUS(ModelGetVersion, _In_ const OrtModel* model, _Out_ int64_t* version);

View file

@ -26,6 +26,7 @@ static constexpr WinmlAdapterApi winml_adapter_api_1 = {
&winmla::CloneModel,
&winmla::ModelGetAuthor,
&winmla::ModelGetName,
&winmla::ModelSetName,
&winmla::ModelGetDomain,
&winmla::ModelGetDescription,
&winmla::ModelGetVersion,

View file

@ -102,6 +102,13 @@ struct WinmlAdapterApi {
*/
OrtStatus*(ORT_API_CALL* ModelGetName)(_In_ const OrtModel* model, _Out_ const char** const name, _Out_ size_t* len)NO_EXCEPTION;
/**
* ModelSetName
* This api set the model name from the OrtModel.
* This is used by the Windows ML Samples Gallery to change the model name for telemetry.
*/
OrtStatus*(ORT_API_CALL* ModelSetName)(_In_ const OrtModel* model, _In_ const char* name)NO_EXCEPTION;
/**
* ModelGetDomain
* This api gets the model domain from the OrtModel.

View file

@ -290,6 +290,15 @@ ORT_API_STATUS_IMPL(winmla::ModelGetName, _In_ const OrtModel* model, _Out_ cons
API_IMPL_END
}
ORT_API_STATUS_IMPL(winmla::ModelSetName, _In_ const OrtModel* model, _In_ const char* const name) {
API_IMPL_BEGIN
auto model_proto = model->UseModelProto();
ONNX_NAMESPACE::GraphProto& graph = *model_proto->mutable_graph();
graph.set_name(name);
return nullptr;
API_IMPL_END
}
ORT_API_STATUS_IMPL(winmla::ModelGetDomain, _In_ const OrtModel* model, _Out_ const char** const domain, _Out_ size_t* len) {
API_IMPL_BEGIN
*domain = model->UseModelInfo()->domain_.c_str();

View file

@ -141,6 +141,9 @@ namespace ROOT_NS.AI.MachineLearning.Experimental {
//! The JoinModel fuses two models by linking outputs from the first model, to inupts of the second.
ROOT_NS.AI.MachineLearning.LearningModel JoinModel(ROOT_NS.AI.MachineLearning.LearningModel other, LearningModelJoinOptions options);
//! The SetName function changes the model name to the specified string
void SetName(String model_name);
}
} // namespace Microsoft.AI.MachineLearning.Experimental

View file

@ -29,4 +29,9 @@ void LearningModelExperimental::Save(hstring const& file_name) {
modelp->SaveToFile(file_name);
}
void LearningModelExperimental::SetName(hstring const& model_name) {
auto modelp = model_.as<winmlp::LearningModel>();
modelp->SetName(model_name);
}
}

View file

@ -12,6 +12,8 @@ struct LearningModelExperimental : LearningModelExperimentalT<LearningModelExper
void Save(hstring const& file_name);
void SetName(hstring const& model_name);
private:
Microsoft::AI::MachineLearning::LearningModel model_;
};

View file

@ -130,6 +130,11 @@ STDMETHODIMP ModelInfo::GetName(const char** out, size_t* len) {
return S_OK;
}
STDMETHODIMP ModelInfo::SetName(const char* name) {
name_ = std::string(name);
return S_OK;
}
STDMETHODIMP ModelInfo::GetDomain(const char** out, size_t* len) {
*out = domain_.c_str();
*len = domain_.size();
@ -242,6 +247,14 @@ STDMETHODIMP OnnruntimeModel::SaveModel(_In_ const wchar_t* const file_name, _In
return S_OK;
}
STDMETHODIMP OnnruntimeModel::SetName(const char* name) {
auto winml_adapter_api = engine_factory_->UseWinmlAdapterApi();
RETURN_HR_IF_NOT_OK_MSG(winml_adapter_api->ModelSetName(ort_model_.get(), name),
engine_factory_->UseOrtApi());
info_->SetName(name);
return S_OK;
}
STDMETHODIMP OnnruntimeModel::DetachOrtModel(OrtModel** model) {
*model = ort_model_.release();
return S_OK;

View file

@ -26,6 +26,8 @@ class ModelInfo : public Microsoft::WRL::RuntimeClass<
(const char** out, size_t* len);
STDMETHOD(GetName)
(const char** out, size_t* len);
STDMETHOD(SetName)
(const char* name);
STDMETHOD(GetDomain)
(const char** out, size_t* len);
STDMETHOD(GetDescription)
@ -68,6 +70,8 @@ class OnnruntimeModel : public Microsoft::WRL::RuntimeClass<
STDMETHOD(SaveModel)
(_In_ const wchar_t* const file_name,
_In_ unsigned size);
STDMETHOD(SetName)
(const char* name);
STDMETHOD(DetachOrtModel)
(OrtModel** model);

View file

@ -279,6 +279,13 @@ LearningModel::OutputFeatures() try {
}
WINML_CATCH_ALL
void LearningModel::SetName(const hstring& name) try {
auto name_std_str = _winml::Strings::UTF8FromHString(name);
auto name_c_str = name_std_str.c_str();
WINML_THROW_IF_FAILED(model_->SetName(name_c_str));
}
WINML_CATCH_ALL
void LearningModel::Close() try {
// close the model
model_ = nullptr;

View file

@ -59,6 +59,8 @@ struct LearningModel : LearningModelT<LearningModel> {
wfc::IVectorView<winml::ILearningModelFeatureDescriptor>
OutputFeatures();
void SetName(const hstring& name);
/* IClosable methods. */
void Close();

View file

@ -66,6 +66,9 @@ IModelInfo : IUnknown {
STDMETHOD(GetName)
(const char** out, size_t* len) PURE;
STDMETHOD(SetName)
(const char* name) PURE;
STDMETHOD(GetDomain)
(const char** out, size_t* len) PURE;
@ -100,6 +103,9 @@ IModel : IUnknown {
(_In_ const wchar_t* const file_name,
_In_ unsigned size) PURE;
STDMETHOD(SetName)
(const char* name) PURE;
STDMETHOD(AddOperator)
(_In_ const char* const op_type, _In_ const char* const op_name, _In_ const char* const op_domain,
_In_ const char* const* op_input_names, _In_ const char* const* actual_input_names, size_t num_inputs,

View file

@ -1089,6 +1089,30 @@ static void SetIntraOpThreadSpinning() {
WINML_EXPECT_TRUE(allowSpinning);
}
static void SetName() {
// load the model with name 'squeezenet_old'
LearningModel model = nullptr;
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model.onnx", model));
auto model_name = model.Name();
auto squeezenet_old = to_hstring("squeezenet_old");
WINML_EXPECT_EQUAL(model_name, squeezenet_old);
// ensure the model name can be changed to 'new name'
auto experimental_model = winml_experimental::LearningModelExperimental(model);
auto new_name = to_hstring("new name");
experimental_model.SetName(new_name);
model_name = model.Name();
WINML_EXPECT_EQUAL(model_name, new_name);
// ensure the model protobuf was actually modified
std::wstring path = FileHelpers::GetModulePath() + L"model_name_changed.onnx";
experimental_model.Save(path);
LearningModel model_name_changed = nullptr;
WINML_EXPECT_NO_THROW(APITest::LoadModel(L"model_name_changed.onnx", model_name_changed));
model_name = model_name_changed.Name();
WINML_EXPECT_EQUAL(model_name, new_name);
}
const LearningModelSessionAPITestsApi& getapi() {
static LearningModelSessionAPITestsApi api =
@ -1123,6 +1147,7 @@ const LearningModelSessionAPITestsApi& getapi() {
ModelBuilding_STFT,
ModelBuilding_MelSpectrogramOnThreeToneSignal,
ModelBuilding_MelWeightMatrix,
SetName
};
if (SkipGpuTests()) {

View file

@ -34,6 +34,7 @@ struct LearningModelSessionAPITestsApi {
VoidTest ModelBuilding_STFT;
VoidTest ModelBuilding_MelSpectrogramOnThreeToneSignal;
VoidTest ModelBuilding_MelWeightMatrix;
VoidTest SetName;
};
const LearningModelSessionAPITestsApi& getapi();
@ -69,4 +70,5 @@ WINML_TEST(LearningModelSessionAPITests, ModelBuilding_BlackmanWindow)
WINML_TEST(LearningModelSessionAPITests, ModelBuilding_STFT)
WINML_TEST(LearningModelSessionAPITests, ModelBuilding_MelSpectrogramOnThreeToneSignal)
WINML_TEST(LearningModelSessionAPITests, ModelBuilding_MelWeightMatrix)
WINML_TEST(LearningModelSessionAPITests, SetName)
WINML_TEST_CLASS_END()