From b5db9a566a41f837c539a06d7cffc441afe018ae Mon Sep 17 00:00:00 2001 From: "Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics" Date: Fri, 6 May 2022 13:58:22 +0200 Subject: [PATCH] [ML][Train] Fixes for error types of compile() and run() Fixed error handling for compile() and run() - all errors were casted to AbortError. After fix, errors reported by native API are casted to proper Web type if possible. Added proper handling for null/undefined values passed as options. [Verification] modelFile = "/home/owner/media/Documents/test_model.ini" var Model = tizen.ml.trainer.createModel(modelFile); Model.compile({loss:"test"}) // InvalidValuesError // Model.compile({loss:true}) // InvalidValuesError // Model.compile(null) // success // Model.compile() // success sCb = (s) => console.log(s) eCb = (e) => console.log(e) Model.run({save_path:"not_a_virutal_path"}, sCb, eCb); //InvalidValuesError via eCb // Model.run({save_path:"/not_a_real_path"}, sCb, eCb); // InvalidValuesError via eCb // Model.run({epochs: "aaaa"}, sCb, eCb) // InvalidValuesError via eCb // Model.run({epochs: true}, sCb, eCb) // InvalidValuesError via eCb // Model.run(null, sCb, eCb) // success // Model.run("abcd", sCb, eCb) // TypeMismatchError Change-Id: Ibb59f7720048b499ce0d576666fad2d5764637e5 --- src/ml/js/ml_trainer.js | 71 ++++++++++++++++++++++-------------- src/ml/ml_trainer_manager.cc | 12 +++--- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/ml/js/ml_trainer.js b/src/ml/js/ml_trainer.js index 7938d951..f36d2df3 100755 --- a/src/ml/js/ml_trainer.js +++ b/src/ml/js/ml_trainer.js @@ -302,14 +302,16 @@ var Model = function(id) { function ValidateCompileOptions(options) { var args = {}; - if (options.hasOwnProperty('loss_val')) { - args.loss = options.loss_val; - } - if (options.hasOwnProperty('loss')) { - args.loss = options.loss; - } - if (options.hasOwnProperty('batch_size')) { - args.batch_size = options.batch_size; + if (!type_.isNullOrUndefined(options)) { + if (options.hasOwnProperty('loss_val')) { + args.loss = options.loss_val; + } + if (options.hasOwnProperty('loss')) { + args.loss = options.loss; + } + if (options.hasOwnProperty('batch_size')) { + args.batch_size = options.batch_size; + } } return args; } @@ -354,24 +356,29 @@ Model.prototype.compile = function() { function ValidateRunOptions(options) { var args = {}; - if (options.hasOwnProperty('batch_size')) { - args.batch_size = options.batch_size; - } - if (options.hasOwnProperty('epochs')) { - args.epochs = options.epochs; - } - if (options.hasOwnProperty('save_path')) { - // produce a global path without "file://" prefix - args.save_path = tizen.filesystem.toURI(options.save_path).substring("file://".length); + if (!type_.isNullOrUndefined(options)) { + if (options.hasOwnProperty('batch_size')) { + args.batch_size = options.batch_size; + } + if (options.hasOwnProperty('epochs')) { + args.epochs = options.epochs; + } + if (options.hasOwnProperty('save_path')) { + // produce a global path without "file://" prefix + args.save_path = tizen.filesystem.toURI(options.save_path).substring("file://".length); + } } return args; } var ValidModelRunExceptions = [ + 'TypeMismatchError' +]; + +var ValidModelRunCallbackErrors = [ 'InvalidValuesError', 'NotFoundError', 'InvalidStateError', - 'TypeMismatchError', 'AbortError' ]; @@ -394,15 +401,6 @@ Model.prototype.run = function() { nullable: true } ]); - var runOptions = {}; - if (args.has.options) { - runOptions = ValidateRunOptions(args.options); - } - - var callArgs = { - id: this._id, - options: runOptions - }; var callback = function (result) { if (native_.isFailure(result)) { @@ -410,7 +408,7 @@ Model.prototype.run = function() { args.errorCallback, native_.getErrorObjectAndValidate( result, - ValidModelRunExceptions, + ValidModelRunCallbackErrors, AbortError ) ); @@ -419,6 +417,23 @@ Model.prototype.run = function() { } }; + var runOptions = {}; + if (args.has.options) { + try { + runOptions = ValidateRunOptions(args.options); + } catch (e) { + // pass InvalidValuesError to callback + native_.callIfPossible(args.errorCallback, e); + return; + } + } + + var callArgs = { + id: this._id, + options: runOptions + }; + + var result = native_.call('MLTrainerModelRun', callArgs, callback); if (native_.isFailure(result)) { throw native_.getErrorObjectAndValidate( diff --git a/src/ml/ml_trainer_manager.cc b/src/ml/ml_trainer_manager.cc index 9b81d66e..41c77545 100644 --- a/src/ml/ml_trainer_manager.cc +++ b/src/ml/ml_trainer_manager.cc @@ -45,7 +45,7 @@ PlatformResult TrainerManager::CreateModel(int& id) { int ret_val = ml_train_model_construct(&n_model); if (ret_val != ML_ERROR_NONE) { LoggerE("Could not create model: %d (%s)", ret_val, ml_strerror(ret_val)); - return PlatformResult(ErrorCode::ABORT_ERR, ml_strerror(ret_val)); + return util::ToPlatformResult(ret_val, ml_strerror(ret_val)); } models_[next_model_id_] = std::make_shared(n_model); @@ -62,7 +62,7 @@ PlatformResult TrainerManager::CreateModel(int& id, const std::string config) { int ret_val = ml_train_model_construct_with_conf(config.c_str(), &n_model); if (ret_val != ML_ERROR_NONE) { LoggerE("Could not create model: %d (%s)", ret_val, ml_strerror(ret_val)); - return PlatformResult(ErrorCode::ABORT_ERR, ml_strerror(ret_val)); + return util::ToPlatformResult(ret_val, ml_strerror(ret_val)); } models_[next_model_id_] = std::make_shared(n_model); @@ -100,7 +100,7 @@ PlatformResult TrainerManager::ModelCompile(int id, ss << key << "=" << value << OPTION_SEPARATOR; } else { LoggerE("Unexpected param type for: %s", key.c_str()); - return PlatformResult(ErrorCode::ABORT_ERR, + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Unexpected param type for:" + key); } } @@ -122,7 +122,7 @@ PlatformResult TrainerManager::ModelCompile(int id, if (ret_val != ML_ERROR_NONE) { LoggerE("Could not compile model: %d (%s)", ret_val, ml_strerror(ret_val)); - return PlatformResult(ErrorCode::ABORT_ERR, ml_strerror(ret_val)); + return util::ToPlatformResult(ret_val, ml_strerror(ret_val)); } model->setCompiled(true); @@ -164,7 +164,7 @@ PlatformResult TrainerManager::ModelRun(int id, ss << key << "=" << value << OPTION_SEPARATOR; } else { LoggerE("Unexpected param type for: %s", key.c_str()); - return PlatformResult(ErrorCode::ABORT_ERR, + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Unexpected param type for:" + key); } } @@ -184,7 +184,7 @@ PlatformResult TrainerManager::ModelRun(int id, if (ret_val != ML_ERROR_NONE) { LoggerE("Could not run (train) model: %d (%s)", ret_val, ml_strerror(ret_val)); - return PlatformResult(ErrorCode::UNKNOWN_ERR, ml_strerror(ret_val)); + return util::ToPlatformResult(ret_val, ml_strerror(ret_val)); } return PlatformResult(); -- 2.34.1