[ML][single] Fix SingleShot.input attribute change 58/255458/1
authorRafal Walczyna <r.walczyna@samsung.com>
Thu, 18 Mar 2021 14:08:32 +0000 (15:08 +0100)
committerRafal Walczyna <r.walczyna@samsung.com>
Thu, 18 Mar 2021 15:11:27 +0000 (16:11 +0100)
Changing input attribute should enable invoking model with different tensor.
User should not be able to modify or dispose input by direct call.
Change is only possible by replacing whole object.

Code:

var ti1 = new tizen.ml.TensorsInfo()
ti1.addTensorInfo("three", "FLOAT32", [1, 1, 1, 1])
var td1 = ti1.getTensorsData(0);
var ti3 = new tizen.ml.TensorsInfo()
ti3.addTensorInfo("three", "FLOAT32", [3, 1, 1, 1])
var td3 = ti3.getTensorsData(0);

var model = tizen.ml.single.openModel("documents/add.tflite", null, null, "ANY", "ANY", false)
model.invoke(td1)
model.input = ti3
model.invoke(td3)

[Verification] Tested in Google Chrome console

Change-Id: Iac17fd72d7e417d30bad983f6c349bd5e5ef05ed
Signed-off-by: Rafal Walczyna <r.walczyna@samsung.com>
src/ml/js/ml_single.js
src/ml/ml_instance.cc
src/ml/ml_singleshot.cc

index f525303847ddbac8efa38627e490ba61d1fa07fd..b78c01003396b7508e891643fddc39e326a3444f 100755 (executable)
@@ -235,7 +235,7 @@ var SingleShot = function(id) {
                     }
                     _input = new TensorsInfo(result.id);
                 }
-                return _input;
+                return _input.clone();
             },
             set: function() {
                 checkSingleShotNotClosed(this);
@@ -260,7 +260,16 @@ var SingleShot = function(id) {
                         AbortError
                     );
                 }
-                _input = args.inTensorsInfo;
+                // dispose old input
+                if (_input instanceof tizen.ml.TensorsInfo) {
+                    _input.dispose();
+                }
+                _input = new TensorsInfo(result.id);
+                // we need to invalidate _output if input changes
+                if (_output instanceof tizen.ml.TensorsInfo) {
+                    _output.dispose();
+                    _output = null;
+                }
             }
         },
         output: {
index 37e70e81d952af386ee6136a59087e4f008f8f1c..07b8a81f8e509cf0ccb3140ad09877fb4c1556e4 100644 (file)
@@ -889,12 +889,15 @@ void MlInstance::MLSingleShotSetInputInfo(const picojson::value& args, picojson:
     return;
   }
 
+  TensorsInfo* clone = GetTensorsInfoManager().CloneTensorsInfo(in_tensors_info);
+
   auto ret = single_manager_.SetNativeInputInfo(id, in_tensors_info);
   if (!ret) {
     ReportError(ret, &out);
     return;
   }
 
+  out[kId] = picojson::value(static_cast<double>(clone->Id()));
   ReportSuccess(out);
 }
 
index 5bfb9e35f2655de7d7da950d7af2a783e4c48b62..da397f6a57cfcadadeeb3efb40c155c5607ed68b 100644 (file)
@@ -100,7 +100,23 @@ PlatformResult SingleShot::SetInputInfo(ml_tensors_info_h in_info) {
     LoggerE("ml_single_set_input_info failed: %d (%s)", ret, get_error_message(ret));
     return util::ToPlatformResult(ret, "Failed to set input info");
   }
-
+  // invalidate output info and data in case of input change
+  if (nullptr != tensor_info_out_handle_) {
+    int ret = ml_tensors_info_destroy(tensor_info_out_handle_);
+    if (ML_ERROR_NONE != ret) {
+      LoggerE("ml_tensors_info_destroy failed: %d (%s)", ret, get_error_message(ret));
+      return PlatformResult(ErrorCode::ABORT_ERR, "Internal SingleShot error");
+    }
+    tensor_info_out_handle_ = nullptr;
+  }
+  if (nullptr != tensor_data_out_handle_) {
+    int ret = ml_tensors_data_destroy(tensor_data_out_handle_);
+    if (ML_ERROR_NONE != ret) {
+      LoggerE("ml_tensors_data_destroy failed: %d (%s)", ret, get_error_message(ret));
+      return PlatformResult(ErrorCode::ABORT_ERR, "Internal SingleShot error");
+    }
+    tensor_data_out_handle_ = nullptr;
+  }
   return PlatformResult{};
 }