});
};
-// SingleShot::invoke()
+var ValidInvokeExceptions = [
+ 'TimeoutError',
+ 'TypeMismatchError',
+ 'NotSupportedError',
+ 'AbortError'
+];
+
+SingleShot.prototype.invoke = function() {
+ var args = validator_.validateArgs(arguments, [
+ {
+ name: 'inTensorsData',
+ type: types_.PLATFORM_OBJECT,
+ values: TensorsData
+ }
+ ]);
+
+ var nativeArgs = {
+ id: this._id,
+ tensorsDataId: args.inTensorsData._id
+ };
+
+ var result = native_.callSync('MLSingleShotInvoke', nativeArgs);
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObjectAndValidate(
+ result,
+ ValidInvokeExceptions,
+ AbortError
+ );
+ }
+
+ return new TensorsData(result.tensorsDataId, result.tensorsInfoId);
+};
var GetSetValueValidExceptions = [
'AbortError',
REGISTER_METHOD(MLSingleManagerOpenModel);
REGISTER_METHOD(MLSingleShotGetTensorsInfo);
REGISTER_METHOD(MLSingleShotSetInputInfo);
- // SingleShot::invoke()
+ REGISTER_METHOD(MLSingleShotInvoke);
REGISTER_METHOD(MLSingleShotGetValue);
REGISTER_METHOD(MLSingleShotSetValue);
// SingleShot::setTimeout()
ReportSuccess(out);
}
-// SingleShot::invoke()
+void MlInstance::MLSingleShotInvoke(const picojson::value& args, picojson::object& out) {
+ ScopeLogger("args: %s", args.serialize().c_str());
+ CHECK_ARGS(args, kId, double, out);
+ CHECK_ARGS(args, kTensorsDataId, double, out);
+
+ int id = static_cast<int>(args.get(kId).get<double>());
+ int tensors_data_id = static_cast<int>(args.get(kTensorsDataId).get<double>());
+
+ TensorsData* in_tensors_data = GetTensorsDataManager().GetTensorsData(tensors_data_id);
+ if (nullptr == in_tensors_data) {
+ LogAndReportError(PlatformResult(ErrorCode::ABORT_ERR, "Internal TensorsData error"), &out,
+ ("Could not find TensorsData handle with given id: %d", tensors_data_id));
+ return;
+ }
+
+ TensorsData* out_tensors_data = nullptr;
+ auto ret = single_manager_.Invoke(id, in_tensors_data, &out_tensors_data);
+ if (!ret) {
+ ReportError(ret, &out);
+ return;
+ }
+
+ out[kTensorsDataId] = picojson::value(static_cast<double>(out_tensors_data->Id()));
+ out[kTensorsInfoId] = picojson::value(static_cast<double>(out_tensors_data->TensorsInfoId()));
+ ReportSuccess(out);
+}
void MlInstance::MLSingleShotGetValue(const picojson::value& args, picojson::object& out) {
ScopeLogger("args: %s", args.serialize().c_str());
void MLSingleManagerOpenModel(const picojson::value& args, picojson::object& out);
void MLSingleShotGetTensorsInfo(const picojson::value& args, picojson::object& out);
void MLSingleShotSetInputInfo(const picojson::value& args, picojson::object& out);
- // SingleShot::invoke()
+ void MLSingleShotInvoke(const picojson::value& args, picojson::object& out);
void MLSingleShotGetValue(const picojson::value& args, picojson::object& out);
void MLSingleShotSetValue(const picojson::value& args, picojson::object& out);
// SingleShot::setTimeout()
std::lock_guard<std::mutex> singles_lock(singles_mutex_);
int id = nextId_++;
- singles_[id] = std::make_unique<SingleShot>(id, handle);
+ singles_[id] = std::make_unique<SingleShot>(id, handle, isDynamicMode);
*res_id = id;
return PlatformResult{};
}
return PlatformResult{};
}
-// SingleShot::invoke()
+PlatformResult SingleManager::Invoke(int id, TensorsData* in_tensors_data,
+ TensorsData** out_tensors_data) {
+ ScopeLogger();
+
+ SingleShot* single = GetSingleShot(id);
+ if (!single) {
+ LoggerE("Could not find SingleShot handle");
+ return PlatformResult(ErrorCode::ABORT_ERR, "Internal SingleShot error");
+ }
+
+ ml_tensors_info_h out_tensors_info_h = nullptr;
+ ml_tensors_data_h out_tensors_data_h = nullptr;
+ bool should_copy_data = false;
+ PlatformResult result =
+ single->Invoke(in_tensors_data->Handle(), in_tensors_data->GetTensorsInfo()->Handle(),
+ &out_tensors_data_h, &out_tensors_info_h, &should_copy_data);
+ if (!result) {
+ return result;
+ }
+ if (should_copy_data) {
+ *out_tensors_data = tim_->CloneNativeTensorWithData(out_tensors_info_h, out_tensors_data_h);
+ } else {
+ *out_tensors_data = tim_->CreateTensorsData(out_tensors_info_h, out_tensors_data_h);
+ }
+
+ if (*out_tensors_data == nullptr) {
+ LoggerE("out_tensors_data creation failed");
+ result = single->CleanUpAfterInvoke();
+ if (!result) {
+ LoggerE("CleanUpAfterInvoke failed");
+ }
+ return PlatformResult(ErrorCode::ABORT_ERR, "Internal SingleShot error");
+ }
+
+ return PlatformResult{};
+}
+
PlatformResult SingleManager::GetValue(int id, const std::string& name, std::string& value) {
ScopeLogger();
// OpenModelSuccessCallback
PlatformResult GetNativeTensorsInfo(int id, bool get_input_mode, int* res_id);
PlatformResult SetNativeInputInfo(int id, TensorsInfo* inTensorsInfo);
- // SingleShot::invoke()
+ PlatformResult Invoke(int id, TensorsData* in_tensors_data, TensorsData** out_tensors_data);
PlatformResult GetValue(int id, const std::string& name, std::string& value);
PlatformResult SetValue(int id, const std::string& name, const std::string& value);
// SingleShot::setTimeout()
namespace extension {
namespace ml {
-SingleShot::SingleShot(int id, ml_single_h handle) : id_{id}, handle_{handle} {
+SingleShot::SingleShot(int id, ml_single_h handle, bool dynamic_mode)
+ : id_{id},
+ handle_{handle},
+ dynamic_mode_{dynamic_mode},
+ tensor_data_out_handle_{nullptr},
+ tensor_info_out_handle_{nullptr} {
ScopeLogger("id: %d", id_);
}
// 'this' owns a handle_, and invalidates 'o'
-SingleShot::SingleShot(SingleShot&& o) : id_(o.id_), handle_(o.handle_) {
+SingleShot::SingleShot(SingleShot&& o)
+ : id_(o.id_), handle_(o.handle_), dynamic_mode_(o.dynamic_mode_) {
ScopeLogger("id: %d", id_);
o.handle_ = nullptr;
}
SingleShot::~SingleShot() {
ScopeLogger("id: %d", id_);
+ // not dynamic mode uses ml_single_invoke_fast, which reuses handles, so they need to be freed
+ if (!dynamic_mode_) {
+ if (nullptr != tensor_data_out_handle_) {
+ int ret = ml_tensors_data_destroy(tensor_data_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerW("ml_tensors_data_destroy failed: %d (%s)", ret, get_error_message(ret));
+ }
+ }
+
+ if (nullptr != tensor_info_out_handle_) {
+ int ret = ml_tensors_info_destroy(tensor_info_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerW("ml_tensors_info_destroy failed: %d (%s)", ret, get_error_message(ret));
+ }
+ }
+ }
+
int ret = ml_single_close(handle_);
if (ML_ERROR_NONE != ret) {
LoggerW("ml_single_close failed: %d (%s)", ret, get_error_message(ret));
return PlatformResult{};
}
-// SingleShot::invoke()
+PlatformResult SingleShot::Invoke(ml_tensors_data_h in_data, ml_tensors_info_h in_info,
+ ml_tensors_data_h* out_data, ml_tensors_info_h* out_info,
+ bool* should_copy_data) {
+ ScopeLogger();
+ PlatformResult result;
+ if (dynamic_mode_) {
+ result = InvokeDynamicInternal(in_data, in_info);
+ } else {
+ result = InvokeInternal(in_data, in_info);
+ }
+ if (!result) {
+ return result;
+ }
+
+ *out_data = tensor_data_out_handle_;
+ *out_info = tensor_info_out_handle_;
+ *should_copy_data = !dynamic_mode_;
+
+ return PlatformResult{};
+}
+
+PlatformResult SingleShot::InvokeInternal(ml_tensors_data_h in_data, ml_tensors_info_h in_info) {
+ ScopeLogger();
+ if (nullptr == tensor_info_out_handle_) {
+ PlatformResult result = GetTensorsInfo(false, &tensor_info_out_handle_);
+ if (!result) {
+ LoggerE("GetTensorsInfo failed");
+ return result;
+ }
+ }
+
+ if (nullptr == tensor_data_out_handle_) {
+ int ret = ml_tensors_data_create(tensor_info_out_handle_, &tensor_data_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerE("ml_tensors_data_create failed: %d (%s)", ret, get_error_message(ret));
+ return PlatformResult(ErrorCode::ABORT_ERR, "Internal SingleShot error");
+ }
+ }
+
+ int ret = ml_single_invoke_fast(handle_, in_data, tensor_data_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerE("ml_single_invoke failed: %d (%s)", ret, get_error_message(ret));
+ return util::ToPlatformResult(ret, "Failed to invoke");
+ }
+ return PlatformResult{};
+}
+
+PlatformResult SingleShot::InvokeDynamicInternal(ml_tensors_data_h in_data,
+ ml_tensors_info_h in_info) {
+ ScopeLogger();
+ int ret = ml_single_invoke_dynamic(handle_, in_data, in_info, &tensor_data_out_handle_,
+ &tensor_info_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerE("ml_single_invoke_dynamic failed: %d (%s)", ret, get_error_message(ret));
+ return util::ToPlatformResult(ret, "Failed to invoke");
+ }
+
+ return PlatformResult{};
+}
+
+PlatformResult SingleShot::CleanUpAfterInvoke() {
+ ScopeLogger();
+ if (dynamic_mode_) {
+ bool is_ok = true;
+ if (nullptr != tensor_data_out_handle_) {
+ int ret = ml_tensors_data_destroy(tensor_data_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ is_ok = false;
+ LoggerE("ml_tensors_data_destroy failed: %d (%s)", ret, get_error_message(ret));
+ } else {
+ tensor_data_out_handle_ = nullptr;
+ }
+ }
+
+ if (nullptr != tensor_info_out_handle_) {
+ int ret = ml_tensors_info_destroy(tensor_info_out_handle_);
+ if (ML_ERROR_NONE != ret) {
+ is_ok = false;
+ LoggerE("ml_tensors_info_destroy failed: %d (%s)", ret, get_error_message(ret));
+ } else {
+ tensor_info_out_handle_ = nullptr;
+ }
+ }
+ if (!is_ok) {
+ return PlatformResult(ErrorCode::ABORT_ERR, "Internal SingleShot error");
+ }
+ }
+
+ return PlatformResult{};
+}
PlatformResult SingleShot::GetValue(const std::string& name, std::string& value) {
ScopeLogger();
class SingleShot {
public:
- SingleShot(int id, ml_single_h handle);
+ SingleShot(int id, ml_single_h handle, bool dynamic_mode);
SingleShot() = delete;
// copy semantics
SingleShot(const SingleShot&) = delete;
PlatformResult GetTensorsInfo(bool get_input_mode, ml_tensors_info_h* result);
PlatformResult SetInputInfo(ml_tensors_info_h in_info);
- // SingleShot::invoke()
-
+ PlatformResult Invoke(ml_tensors_data_h in_data, ml_tensors_info_h in_info,
+ ml_tensors_data_h* out_data, ml_tensors_info_h* out_info,
+ bool* should_copy_data);
+ PlatformResult CleanUpAfterInvoke();
PlatformResult GetValue(const std::string& name, std::string& value);
PlatformResult SetValue(const std::string& name, const std::string& value);
// SingleShot::close()
private:
+ PlatformResult InvokeInternal(ml_tensors_data_h in_data, ml_tensors_info_h in_info);
+ PlatformResult InvokeDynamicInternal(ml_tensors_data_h in_data, ml_tensors_info_h in_info);
const int id_;
ml_single_h handle_;
+ const bool dynamic_mode_;
+ // below handles are reused by ml_single_invoke_fast when dynamic mode is off
+ ml_tensors_data_h tensor_data_out_handle_;
+ ml_tensors_info_h tensor_info_out_handle_;
};
} // namespace ml
map_.clear();
};
+TensorsData* TensorsDataManager::CreateTensorsData(TensorsInfo* tensors_info,
+ ml_tensors_data_h tensors_data_handle) {
+ ScopeLogger();
+ if (nullptr == tensors_info) {
+ LoggerE("Could not find tensor");
+ return nullptr;
+ }
+
+ std::lock_guard<std::mutex> lock{map_and_next_id_mutex_};
+ int id = nextId_++;
+ auto t = std::make_unique<TensorsData>(tensors_data_handle, id, tensors_info);
+ map_[id] = std::move(t);
+
+ return map_[id].get();
+}
+
TensorsData* TensorsDataManager::CreateTensorsData(TensorsInfo* tensors_info) {
ScopeLogger();
if (nullptr == tensors_info) {
~TensorsDataManager();
TensorsData* CreateTensorsData(TensorsInfo* tensors_info);
+ TensorsData* CreateTensorsData(TensorsInfo* tensors_info, ml_tensors_data_h tensors_data_handle);
TensorsData* GetTensorsData(int id);
PlatformResult DisposeTensorsData(int id);
return tensors_data_manager_->CreateTensorsData(t_info);
};
+TensorsData* TensorsInfoManager::CreateTensorsData(ml_tensors_info_h tensors_info_src,
+ ml_tensors_data_h tensors_data_src) {
+ ScopeLogger("tensors_info_src: [%p], tensors_data_src: [%p]", tensors_info_src, tensors_data_src);
+
+ TensorsInfo* t_info = CreateTensorsInfo(tensors_info_src);
+
+ return tensors_data_manager_->CreateTensorsData(t_info, tensors_data_src);
+};
+
TensorsData* TensorsInfoManager::CloneNativeTensorWithData(ml_tensors_info_h tensors_info_src,
ml_tensors_data_h tensors_data_src) {
ScopeLogger("tensors_info_src: [%p], tensors_data_src: [%p]", tensors_info_src, tensors_data_src);
PlatformResult DisposeTensorsInfo(TensorsInfo* t);
TensorsData* CreateTensorsData(TensorsInfo* tensors_info);
+ TensorsData* CreateTensorsData(ml_tensors_info_h tensors_info_src,
+ ml_tensors_data_h tensors_data_src);
TensorsData* CloneNativeTensorWithData(ml_tensors_info_h tensors_info_src,
ml_tensors_data_h tensors_data_src);