From: Lukasz Bardeli Date: Tue, 26 Jan 2021 12:56:06 +0000 (+0100) Subject: [ML][Pipeline] GetSource implementation X-Git-Tag: submit/tizen/20210202.064821~5^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=353eeed6c663a1bedbe819e2a9ae0405c72258ed;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [ML][Pipeline] GetSource implementation ACR: TWDAPI-274 [Verification] Code compiles without error. Tested in chrome console. var pipeline = tizen.ml.pipeline.createPipeline("appsrc name=appsrc ! other/tensor,dimension=(string)4:1:1:1, type=(string)uint8,framerate=(fraction)0/1 ! tensor_if name=tif compared-value=CUSTOM compared-value-option=tif_custom_cb_name ") var source = pipeline.getSource("appsrc") var tensor = source.inputTensorsInfo Change-Id: I3c09d2f91758c19e82ade9e6e5237ddc0a8ef76e Signed-off-by: Lukasz Bardeli --- diff --git a/src/ml/js/ml_pipeline.js b/src/ml/js/ml_pipeline.js index 425e34c0..16a18c9e 100755 --- a/src/ml/js/ml_pipeline.js +++ b/src/ml/js/ml_pipeline.js @@ -208,7 +208,75 @@ Pipeline.prototype.getNodeInfo = function() { //Pipeline::getNodeInfo() end //Pipeline::getSource() begin +var ValidInputTensorsInfoExceptions = ['NotFoundError', 'AbortError']; +function Source(name, pipeline_id) { + Object.defineProperties(this, { + name: { + enumerable: true, + value: name + }, + inputTensorsInfo: { + get: function() { + var result = native_.callSync('MLPipelineGetInputTensorsInfo', { + id: this._pipeline_id, + name: this.name + }); + if (native_.isFailure(result)) { + throw native_.getErrorObjectAndValidate( + result, + ValidInputTensorsInfoExceptions, + AbortError + ); + } + return new TensorsInfo(result.id); + } + }, + _pipeline_id: { + value: pipeline_id + } + }); +} + +var ValidPipelineGetSourceExceptions = [ + 'InvalidStateError', + 'InvalidValuesError', + 'NotFoundError', + 'NotSupportedError', + 'AbortError' +]; + +Pipeline.prototype.getSource = function() { + var args = validator_.validateArgs(arguments, [ + { + name: 'name', + type: validator_.Types.STRING + } + ]); + + if (!args.has.name) { + throw new WebAPIException( + WebAPIException.INVALID_VALUES_ERR, + 'Invalid parameter: name is mandatory' + ); + } + + var nativeArgs = { + id: this._id, + name: args.name + }; + + var result = native_.callSync('MLPipelineGetSource', nativeArgs); + if (native_.isFailure(result)) { + throw native_.getErrorObjectAndValidate( + result, + ValidPipelineGetSourceExceptions, + AbortError + ); + } + + return new Source(args.name, this._id); +}; //Pipeline::getSource() end //Pipeline::getSwitch() begin diff --git a/src/ml/ml.gyp b/src/ml/ml.gyp index 40aebd3f..0b085533 100644 --- a/src/ml/ml.gyp +++ b/src/ml/ml.gyp @@ -23,8 +23,8 @@ 'ml_pipeline_nodeinfo.h', 'ml_pipeline_switch.cc', 'ml_pipeline_switch.h', - #TODO pipeline Source - #TODO pipeline Valve + 'ml_pipeline_source.h', + 'ml_pipeline_source.cc', 'ml_pipeline_valve.h', 'ml_pipeline_valve.cc', 'ml_tensors_data_manager.cc', diff --git a/src/ml/ml_instance.cc b/src/ml/ml_instance.cc index e4c78333..72bef27c 100644 --- a/src/ml/ml_instance.cc +++ b/src/ml/ml_instance.cc @@ -76,7 +76,7 @@ using namespace common; MlInstance::MlInstance() : tensors_info_manager_{&tensors_data_manager_}, single_manager_{&tensors_info_manager_}, - pipeline_manager_{this} { + pipeline_manager_{this, &tensors_info_manager_} { ScopeLogger(); using namespace std::placeholders; @@ -128,6 +128,8 @@ MlInstance::MlInstance() REGISTER_METHOD(MLPipelineGetValve); REGISTER_METHOD(MLPipelineNodeInfoGetProperty); REGISTER_METHOD(MLPipelineNodeInfoSetProperty); + REGISTER_METHOD(MLPipelineGetSource); + REGISTER_METHOD(MLPipelineGetInputTensorsInfo); // Pipeline API end #undef REGISTER_METHOD @@ -901,7 +903,24 @@ void MlInstance::MLPipelineGetNodeInfo(const picojson::value& args, picojson::ob // Pipeline::getNodeInfo() end // Pipeline::getSource() begin +void MlInstance::MLPipelineGetSource(const picojson::value& args, picojson::object& out) { + ScopeLogger("args: %s", args.serialize().c_str()); + + CHECK_ARGS(args, kId, double, out); + CHECK_ARGS(args, kName, std::string, out); + + auto name = args.get(kName).get(); + auto id = static_cast(args.get(kId).get()); + + PlatformResult result = pipeline_manager_.GetSource(id, name); + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} // Pipeline::getSource() end // Pipeline::getSwitch() begin @@ -1030,7 +1049,24 @@ void MlInstance::MLPipelineNodeInfoSetProperty(const picojson::value& args, pico // NodeInfo::setProperty() end // Source::inputTensorsInfo begin +void MlInstance::MLPipelineGetInputTensorsInfo(const picojson::value& args, picojson::object& out) { + ScopeLogger("args: [%s]", args.serialize().c_str()); + + CHECK_ARGS(args, kId, double, out); + CHECK_ARGS(args, kName, std::string, out); + auto id = static_cast(args.get(kId).get()); + const auto& name = args.get(kName).get(); + + int res_id = -1; + PlatformResult result = pipeline_manager_.getInputTensorsInfo(id, name, &res_id); + if (!result) { + LogAndReportError(result, &out); + return; + } + + ReportSuccess(out); +} // Source::inputTensorsInfo end // Source::inputData() begin diff --git a/src/ml/ml_instance.h b/src/ml/ml_instance.h index 95125fb5..f0622576 100644 --- a/src/ml/ml_instance.h +++ b/src/ml/ml_instance.h @@ -103,7 +103,7 @@ class MlInstance : public common::ParsedInstance { // Pipeline::getNodeInfo() end // Pipeline::getSource() begin - + void MLPipelineGetSource(const picojson::value& args, picojson::object& out); // Pipeline::getSource() end // Pipeline::getSwitch() begin @@ -139,7 +139,7 @@ class MlInstance : public common::ParsedInstance { // NodeInfo::setProperty() end // Source::inputTensorsInfo begin - + void MLPipelineGetInputTensorsInfo(const picojson::value& args, picojson::object& out); // Source::inputTensorsInfo end // Source::inputData() begin diff --git a/src/ml/ml_pipeline.cc b/src/ml/ml_pipeline.cc index fe359489..c7e868d8 100644 --- a/src/ml/ml_pipeline.cc +++ b/src/ml/ml_pipeline.cc @@ -196,6 +196,8 @@ PlatformResult Pipeline::Dispose() { valves_.clear(); + sources_.clear(); + auto ret = ml_pipeline_destroy(pipeline_); if (ML_ERROR_NONE != ret) { LoggerE("ml_pipeline_destroy() failed: [%d] (%s)", ret, get_error_message(ret)); @@ -233,7 +235,22 @@ PlatformResult Pipeline::GetNodeInfo(std::string& name) { // Pipeline::getNodeInfo() end // Pipeline::getSource() begin +PlatformResult Pipeline::GetSource(const std::string& name) { + ScopeLogger("id: [%d], name: [%s]", id_, name.c_str()); + + auto source_it = sources_.find(name); + if (sources_.end() != source_it) { + LoggerD("Source [%s] found", name.c_str()); + return PlatformResult{}; + } + std::unique_ptr source_ptr; + auto ret = Source::CreateSource(name, pipeline_, &source_ptr); + if (ret) { + sources_.insert({name, std::move(source_ptr)}); + } + return ret; +} // Pipeline::getSource() end // Pipeline::getSwitch() begin @@ -305,9 +322,7 @@ PlatformResult Pipeline::getProperty(const std::string& node_name, const std::st return PlatformResult{ErrorCode::NOT_FOUND_ERR, "NodeInfo not found"}; } - auto ret = nodeinfo_it->second->getProperty(name, type, property); - - return ret; + return nodeinfo_it->second->getProperty(name, type, property); } // NodeInfo::getProperty() end @@ -322,13 +337,22 @@ PlatformResult Pipeline::setProperty(const std::string& node_name, const std::st return PlatformResult{ErrorCode::NOT_FOUND_ERR, "NodeInfo not found"}; } - auto ret = nodeinfo_it->second->setProperty(name, type, property); - return ret; + return nodeinfo_it->second->setProperty(name, type, property); } // NodeInfo::setProperty() end // Source::inputTensorsInfo begin +PlatformResult Pipeline::getInputTensorsInfo(const std::string& name, ml_tensors_info_h* result) { + ScopeLogger(); + auto source_it = sources_.find(name); + if (sources_.end() == source_it) { + LoggerD("Source [%s] not found", name.c_str()); + return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Source not found"}; + } + + return source_it->second->getInputTensorsInfo(result); +} // Source::inputTensorsInfo end // Source::inputData() begin diff --git a/src/ml/ml_pipeline.h b/src/ml/ml_pipeline.h index afe3fee4..59df3119 100644 --- a/src/ml/ml_pipeline.h +++ b/src/ml/ml_pipeline.h @@ -27,6 +27,7 @@ #include "common/picojson.h" #include "common/platform_result.h" #include "ml_pipeline_nodeinfo.h" +#include "ml_pipeline_source.h" #include "ml_pipeline_switch.h" #include "ml_pipeline_valve.h" @@ -76,7 +77,7 @@ class Pipeline { // Pipeline::getNodeInfo() end // Pipeline::getSource() begin - + PlatformResult GetSource(const std::string& name); // Pipeline::getSource() end // Pipeline::getSwitch() begin @@ -114,7 +115,7 @@ class Pipeline { // NodeInfo::setProperty() end // Source::inputTensorsInfo begin - + PlatformResult getInputTensorsInfo(const std::string& name, ml_tensors_info_h* result); // Source::inputTensorsInfo end // Source::inputData() begin @@ -152,6 +153,7 @@ class Pipeline { std::unordered_map> switches_; std::map> node_info_; std::unordered_map> valves_; + std::map> sources_; static void PipelineStateChangeListener(ml_pipeline_state_e state, void* user_data); }; diff --git a/src/ml/ml_pipeline_manager.cc b/src/ml/ml_pipeline_manager.cc index 3e1cc413..364426fc 100644 --- a/src/ml/ml_pipeline_manager.cc +++ b/src/ml/ml_pipeline_manager.cc @@ -26,7 +26,9 @@ using common::tools::ReportSuccess; namespace extension { namespace ml { -PipelineManager::PipelineManager(common::Instance* instance_ptr) : instance_ptr_{instance_ptr} { +PipelineManager::PipelineManager(common::Instance* instance_ptr, + TensorsInfoManager* tensors_info_manager) + : instance_ptr_{instance_ptr}, tensors_info_manager_{tensors_info_manager} { ScopeLogger(); } @@ -144,7 +146,17 @@ PlatformResult PipelineManager::GetNodeInfo(int id, std::string& name) { // Pipeline::getNodeInfo() end // Pipeline::getSource() begin +PlatformResult PipelineManager::GetSource(int pipeline_id, const std::string& name) { + ScopeLogger("name: [%s], pipeline_id: [%d]", name.c_str(), pipeline_id); + + auto pipeline_it = pipelines_.find(pipeline_id); + if (pipelines_.end() == pipeline_it) { + LoggerD("Pipeline not found: [%d]", pipeline_id); + return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"}; + } + return pipeline_it->second->GetSource(name); +} // Pipeline::getSource() end // Pipeline::getSwitch() begin @@ -227,7 +239,24 @@ PlatformResult PipelineManager::setProperty(int id, const std::string& node_name // NodeInfo::setProperty() end // Source::inputTensorsInfo begin +PlatformResult PipelineManager::getInputTensorsInfo(int id, const std::string& name, int* res_id) { + ScopeLogger(); + + auto pipeline_it = pipelines_.find(id); + if (pipelines_.end() == pipeline_it) { + LoggerD("Pipeline not found: [%d]", id); + return PlatformResult{ErrorCode::NOT_FOUND_ERR, "Pipeline not found"}; + } + ml_tensors_info_h in_info = nullptr; + PlatformResult ret = pipeline_it->second->getInputTensorsInfo(name, &in_info); + if (!ret) { + return ret; + } + auto tensor_info = tensors_info_manager_->CreateTensorsInfo(in_info); + *res_id = tensor_info->Id(); + return PlatformResult{}; +} // Source::inputTensorsInfo end // Source::inputData() begin diff --git a/src/ml/ml_pipeline_manager.h b/src/ml/ml_pipeline_manager.h index f9866248..6e363dd5 100644 --- a/src/ml/ml_pipeline_manager.h +++ b/src/ml/ml_pipeline_manager.h @@ -22,6 +22,7 @@ #include "common/platform_result.h" #include "ml_pipeline.h" +#include "ml_tensors_info_manager.h" using common::PlatformResult; @@ -30,7 +31,7 @@ namespace ml { class PipelineManager { public: - PipelineManager(common::Instance* instance_ptr); + PipelineManager(common::Instance* instance_ptr, TensorsInfoManager* tim); ~PipelineManager(); @@ -64,7 +65,7 @@ class PipelineManager { // Pipeline::getNodeInfo() end // Pipeline::getSource() begin - + PlatformResult GetSource(int pipeline_id, const std::string& name); // Pipeline::getSource() end // Pipeline::getSwitch() begin @@ -102,7 +103,7 @@ class PipelineManager { // NodeInfo::setProperty() end // Source::inputTensorsInfo begin - + PlatformResult getInputTensorsInfo(int id, const std::string& name, int* res_id); // Source::inputTensorsInfo end // Source::inputData() begin @@ -124,6 +125,7 @@ class PipelineManager { // Valve::setOpen() end private: common::Instance* instance_ptr_; + TensorsInfoManager* tensors_info_manager_; std::map> pipelines_; }; diff --git a/src/ml/ml_pipeline_source.cc b/src/ml/ml_pipeline_source.cc new file mode 100644 index 00000000..7ac0104b --- /dev/null +++ b/src/ml/ml_pipeline_source.cc @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ml_pipeline_source.h" +#include "ml_utils.h" + +using common::PlatformResult; +using common::ErrorCode; + +namespace extension { +namespace ml { +namespace pipeline { + +PlatformResult Source::CreateSource(const std::string& name, ml_pipeline_h pipeline, + std::unique_ptr* out) { + ScopeLogger("name: [%s], pipeline: [%p]", name.c_str(), pipeline); + ml_pipeline_src_h source_handle = nullptr; + auto ret = ml_pipeline_src_get_handle(pipeline, name.c_str(), &source_handle); + if (ML_ERROR_NONE != ret) { + LoggerE("ml_pipeline_src_get_handle() failed: [%d] (%s)", ret, get_error_message(ret)); + return util::ToPlatformResult(ret, "Could not get source"); + } + + out->reset(new (std::nothrow) Source{name, source_handle}); + if (!out) { + ret = ml_pipeline_src_release_handle(source_handle); + if (ML_ERROR_NONE != ret) { + LoggerE("ml_pipeline_src_release_handle() failed: [%d] (%s)", ret, get_error_message(ret)); + } else { + LoggerD("ml_pipeline_src_release_handle() succeeded"); + } + return LogAndCreateResult(ErrorCode::ABORT_ERR, "Could not get the source", + ("Could not allocate memory")); + } + + return PlatformResult{}; +} + +Source::Source(const std::string& name, ml_pipeline_src_h source_handle) + : name_{name}, source_{source_handle} { + ScopeLogger("name: [%s], handle: [%p]", name.c_str(), source_handle); +} + +Source::~Source() { + ScopeLogger("name: [%s], handle: [%p]", name_.c_str(), source_); + + auto ret = ml_pipeline_src_release_handle(source_); + if (ML_ERROR_NONE != ret) { + LoggerE("ml_pipeline_src_release_handle() failed: [%d] (%s)", ret, get_error_message(ret)); + } else { + LoggerD("ml_pipeline_src_release_handle() succeeded"); + } +} + +PlatformResult Source::getInputTensorsInfo(ml_tensors_info_h* result) { + ScopeLogger(); + + ml_tensors_info_h info = nullptr; + auto ret = ml_pipeline_src_get_tensors_info(source_, &info); + + if (ML_ERROR_NONE != ret) { + LoggerE(" ml_pipeline_src_get_tensors_info failed: %d (%s)", ret, get_error_message(ret)); + return util::ToPlatformResult(ret, "Failed to get tensor info"); + } + + *result = info; + + return PlatformResult{}; +} + +} // namespace pipeline +} // namespace ml +} // namespace extension \ No newline at end of file diff --git a/src/ml/ml_pipeline_source.h b/src/ml/ml_pipeline_source.h new file mode 100644 index 00000000..cdd0154e --- /dev/null +++ b/src/ml/ml_pipeline_source.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ML_ML_PIPELINE_SOURCE_H_ +#define ML_ML_PIPELINE_SOURCE_H_ + +#include +#include + +#include + +#include "common/platform_result.h" + +using common::PlatformResult; + +namespace extension { +namespace ml { +namespace pipeline { + +class Source { + public: + static PlatformResult CreateSource(const std::string& name, ml_pipeline_h pipeline, + std::unique_ptr* out); + + ~Source(); + + PlatformResult getInputTensorsInfo(ml_tensors_info_h* result); + + Source(const Source&) = delete; + Source& operator=(const Source&) = delete; + + private: + Source(const std::string& name, ml_pipeline_src_h source_handle); + const std::string name_; + const ml_pipeline_src_h source_; +}; + +} // namespace pipeline +} // namespace ml +} // namespace extension + +#endif // ML_ML_PIPELINE_SOURCE_H_ \ No newline at end of file