mv_machine_learning: code refactoring to Inference class
authorInki Dae <inki.dae@samsung.com>
Thu, 11 Aug 2022 23:04:14 +0000 (08:04 +0900)
committerInki Dae <inki.dae@samsung.com>
Fri, 2 Sep 2022 08:09:25 +0000 (17:09 +0900)
[Issue type] : code refactoring

Did code refactoring to Inference class by doing,
- extracted a function - ConvertOutputDataTypeToFloat - from
  FillOutputResult function, which converts tensor data to float type.
  In fact, float data of output tensor is needed commonly so
  converted output tensor data to float type just after inference is
  completed. And finally, it changed FillOuputResult function name to
  GetTensorInfo and moved it to TensorBuffer class.
- renamed several variables and function with meaningful name properly.

This patch is just a step for next code refactoring.

Change-Id: I4fd808ef05dd69203eb815a8230595aa1f1b7e54
Signed-off-by: Inki Dae <inki.dae@samsung.com>
mv_machine_learning/face_recognition/src/face_recognition.cpp
mv_machine_learning/inference/include/Inference.h
mv_machine_learning/inference/include/TensorBuffer.h
mv_machine_learning/inference/src/Inference.cpp
mv_machine_learning/inference/src/TensorBuffer.cpp

index 5f21116..41a71ed 100644 (file)
@@ -28,6 +28,7 @@
 #include <mv_private.h>
 
 #include "machine_learning_exception.h"
+#include "TensorBuffer.h"
 #include "face_recognition.h"
 #include "nntrainer_fvm.h"
 #include "nntrainer_dsm.h"
@@ -342,7 +343,8 @@ int FaceRecognition::RegisterNewFace(mv_source_h img_src, string label_name)
 
                // 2. Get feature vector from a given vec through inference engine.
                // Ps. output layer size should be 1.
-               inference_engine_tensor_buffer *backbone_output_buffer = _backbone->GetOutputTensorBuffer(output_layer_info[0].layer_name);
+               TensorBuffer tensorBuffer = _backbone->GetOutputTensorBuffer();
+               inference_engine_tensor_buffer *backbone_output_buffer = tensorBuffer.getTensorBuffer(output_layer_info[0].layer_name);
                if (!backbone_output_buffer) {
                        LOGE("fail to get output tensor buffer.");
                        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -469,7 +471,8 @@ int FaceRecognition::RecognizeFace(mv_source_h img_src)
                // Get output layer info for facenet model.
                vector<model_layer_info>& output_layer_info = _backbone_model_info->GetOutputLayerInfo();
                // Get output tensor buffer to the output layer.
-               inference_engine_tensor_buffer *backbone_output_buffer = _backbone->GetOutputTensorBuffer(output_layer_info[0].layer_name);
+               TensorBuffer tensorBuffer = _backbone->GetOutputTensorBuffer();
+               inference_engine_tensor_buffer *backbone_output_buffer = tensorBuffer.getTensorBuffer(output_layer_info[0].layer_name);
                if (!backbone_output_buffer) {
                        LOGE("fail to get backbone output tensor buffer.");
                        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -504,7 +507,8 @@ int FaceRecognition::RecognizeFace(mv_source_h img_src)
                }
 
                // output layer size should be 1.
-               inference_engine_tensor_buffer *internal_output_buffer = _internal->GetOutputTensorBuffer(output_layers[0]);
+               tensorBuffer = _internal->GetOutputTensorBuffer();
+               inference_engine_tensor_buffer *internal_output_buffer = tensorBuffer.getTensorBuffer(output_layers[0]);
                if (!internal_output_buffer) {
                        LOGE("fail to get internal output tensor buffer.");
                        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
index 5db2092..7096094 100644 (file)
@@ -317,9 +317,9 @@ namespace inference
                        return mConfig.mTargetTypes;
                }
 
-               inference_engine_tensor_buffer* GetOutputTensorBuffer(std::string name)
+               TensorBuffer& GetOutputTensorBuffer()
                {
-                       return mOutputTensorBuffers.getTensorBuffer(name);
+                       return mOutputTensorBuffers;
                }
 
        private:
@@ -350,12 +350,12 @@ namespace inference
                int ConvertEngineErrorToVisionError(int error);
                int ConvertTargetTypes(int given_types);
                int ConvertToCv(int given_type);
+               int ConvertOutputDataTypeToFloat();
                inference_tensor_data_type_e ConvertToIE(int given_type);
                int Preprocess(cv::Mat cvImg, cv::Mat cvDst, int data_type);
                int PrepareTenosrBuffers(void);
                void CleanupTensorBuffers(void);
                int SetUserFile(std::string filename);
-               int FillOutputResult(tensor_t &outputData);
 
        };
 
index c7d4ba3..2f48d4c 100644 (file)
@@ -40,7 +40,7 @@ namespace inference
        class TensorBuffer
        {
        private:
-               IETensorBuffer mTensorBuffer;
+               IETensorBuffer _tensorBuffer;
 
        public:
                TensorBuffer() = default;
@@ -53,12 +53,12 @@ namespace inference
                void release();
                size_t size();
 
-               IETensorBuffer& getAllTensorBuffer();
-               inference_engine_tensor_buffer* getTensorBuffer(std::string name);
+               IETensorBuffer& getIETensorBuffer();
                bool addTensorBuffer(std::string name, inference_engine_tensor_buffer& buffer);
-
+               int GetTensorInfo(inference_engine_layer_property& layerProperty, tensor_t& tensorInfo);
+               inference_engine_tensor_buffer* getTensorBuffer(std::string name);
                template <typename T>
-               int convertToFloat(inference_engine_tensor_buffer *tensorBuffer, const inference_engine_tensor_info& tensor_info);
+               int convertToFloat(inference_engine_tensor_buffer *tensorBuffer);
 
                template <typename T>
                T getValue(std::string name, int idx);
index 478cd17..b655f22 100755 (executable)
@@ -665,7 +665,7 @@ namespace inference
                }
 
                // Get input tensor buffers from a backend engine if the backend engine allocated.
-               auto& inputTensorBuffers = mInputTensorBuffers.getAllTensorBuffer();
+               auto& inputTensorBuffers = mInputTensorBuffers.getIETensorBuffer();
                int ret = mBackend->GetInputTensorBuffers(inputTensorBuffers);
                if (ret != INFERENCE_ENGINE_ERROR_NONE) {
                        LOGE("Fail to get input tensor buffers from backend engine.");
@@ -698,7 +698,7 @@ namespace inference
                LOGI("Input tensor buffer count is %zu", mInputTensorBuffers.size());
 
                // Get output tensor buffers from a backend engine if the backend engine allocated.
-               auto& outputTensorBuffers = mOutputTensorBuffers.getAllTensorBuffer();
+               auto& outputTensorBuffers = mOutputTensorBuffers.getIETensorBuffer();
                ret = mBackend->GetOutputTensorBuffers(outputTensorBuffers);
                if (ret != INFERENCE_ENGINE_ERROR_NONE) {
                        LOGE("Fail to get output tensor buffers from backend engine.");
@@ -733,43 +733,29 @@ namespace inference
                return MEDIA_VISION_ERROR_NONE;
        }
 
-       int Inference::FillOutputResult(tensor_t &outputData)
+       int Inference::ConvertOutputDataTypeToFloat()
        {
-               for (auto& layer : mOutputLayerProperty.layers) {
-                       const inference_engine_tensor_info& tensor_info = layer.second;
+               IETensorBuffer& ieTensorBuffers = mOutputTensorBuffers.getIETensorBuffer();
 
-                       std::vector<int> tmpDimInfo;
-                       for (auto& dim : tensor_info.shape) {
-                               tmpDimInfo.push_back(dim);
-                       }
-
-                       outputData.dimInfo.push_back(tmpDimInfo);
-
-                       inference_engine_tensor_buffer* tensorBuffer =
-                                                               mOutputTensorBuffers.getTensorBuffer(layer.first);
-                       if (tensorBuffer == NULL) {
-                               LOGE("Fail to getTensorBuffer with name %s", layer.first.c_str());
-                               return MEDIA_VISION_ERROR_INVALID_OPERATION;
-                       }
+               for (auto& ieTensorBuffer : ieTensorBuffers) {
+                       auto& tensorBuffer = ieTensorBuffer.second;
 
                        // Normalize output tensor data converting it to float type in case of quantized model.
-                       if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
-                               int ret = mOutputTensorBuffers.convertToFloat<unsigned char>(tensorBuffer, tensor_info);
+                       if (tensorBuffer.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
+                               int ret = mOutputTensorBuffers.convertToFloat<unsigned char>(&tensorBuffer);
                                if (ret != MEDIA_VISION_ERROR_NONE) {
                                        LOGE("Fail to convert tensor data to float type.");
                                        return ret;
                                }
                        }
 
-                       if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT16) {
-                               int ret = mOutputTensorBuffers.convertToFloat<unsigned short>(tensorBuffer, tensor_info);
+                       if (tensorBuffer.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT16) {
+                               int ret = mOutputTensorBuffers.convertToFloat<unsigned short>(&tensorBuffer);
                                if (ret != MEDIA_VISION_ERROR_NONE) {
                                        LOGE("Fail to convert tensor data to float type.");
                                        return ret;
                                }
                        }
-
-                       outputData.data.push_back(static_cast<void *>(tensorBuffer->buffer));
                }
 
                return MEDIA_VISION_ERROR_NONE;
@@ -998,7 +984,7 @@ namespace inference
                }
 
                if (mMetadata.GetInputMeta().IsParsed()) {
-                       for (auto& buffer : mInputTensorBuffers.getAllTensorBuffer()) {
+                       for (auto& buffer : mInputTensorBuffers.getIETensorBuffer()) {
                                inference_engine_tensor_buffer& tensor_buffer = buffer.second;
                                const LayerInfo& layerInfo = mMetadata.GetInputMeta().GetLayer().at(buffer.first);
                                const Options& opt = mMetadata.GetInputMeta().GetOption().empty() ? Options() : mMetadata.GetInputMeta().GetOption().at(buffer.first);
@@ -1015,7 +1001,7 @@ namespace inference
                                }
                        }
                } else {
-                       for (auto& buffer : mInputTensorBuffers.getAllTensorBuffer()) {
+                       for (auto& buffer : mInputTensorBuffers.getIETensorBuffer()) {
                                inference_engine_tensor_buffer& tensor_buffer = buffer.second;
 
                                int data_type = ConvertToCv(tensor_buffer.data_type);
@@ -1033,10 +1019,12 @@ namespace inference
                        }
                }
 
-               ret = mBackend->Run(mInputTensorBuffers.getAllTensorBuffer(),
-                                                       mOutputTensorBuffers.getAllTensorBuffer());
+               ret = mBackend->Run(mInputTensorBuffers.getIETensorBuffer(),
+                                                       mOutputTensorBuffers.getIETensorBuffer());
+               if (ret != INFERENCE_ENGINE_ERROR_NONE)
+                       return ret;
 
-               return ConvertEngineErrorToVisionError(ret);
+               return ConvertOutputDataTypeToFloat();
        }
 
        int Inference::Run(std::vector<void *>& buffer_objs)
@@ -1059,14 +1047,14 @@ namespace inference
                        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
                }
 
-               if (mInputTensorBuffers.getAllTensorBuffer().size() != buffer_objs.size()) {
+               if (mInputTensorBuffers.getIETensorBuffer().size() != buffer_objs.size()) {
                        LOGE("Raw source count is not invalid.");
                        return MEDIA_VISION_ERROR_INVALID_PARAMETER;
                }
 
                unsigned int buffer_idx = 0;
 
-               for (auto& buffer : mInputTensorBuffers.getAllTensorBuffer()) {
+               for (auto& buffer : mInputTensorBuffers.getIETensorBuffer()) {
                        inference_engine_tensor_buffer& tensor_buffer = buffer.second;
                        inference_engine_tensor_buffer *buffer_obj = static_cast<inference_engine_tensor_buffer *>(buffer_objs[buffer_idx]);
 
@@ -1081,10 +1069,12 @@ namespace inference
                        buffer_idx++;
                }
 
-               ret = mBackend->Run(mInputTensorBuffers.getAllTensorBuffer(),
-                                                       mOutputTensorBuffers.getAllTensorBuffer());
+               ret = mBackend->Run(mInputTensorBuffers.getIETensorBuffer(),
+                                                       mOutputTensorBuffers.getIETensorBuffer());
+               if (ret != INFERENCE_ENGINE_ERROR_NONE)
+                       return ret;
 
-               return ConvertEngineErrorToVisionError(ret);
+               return ConvertOutputDataTypeToFloat();
        }
 
        std::pair<std::string, bool>
@@ -1099,17 +1089,17 @@ namespace inference
                std::vector<std::pair<float, int>> topScore;
                auto threadHold = mConfig.mConfidenceThresHold;
                constexpr unsigned int default_top_number = 5;
-               tensor_t outputData;
+               tensor_t outputTensorInfo;
 
-               // Get inference result and contain it to outputData.
-               int ret = FillOutputResult(outputData);
+               // Get inference result and contain it to outputTensorInfo.
+               int ret = mOutputTensorBuffers.GetTensorInfo(mOutputLayerProperty, outputTensorInfo);
                if (ret != MEDIA_VISION_ERROR_NONE) {
                        LOGE("Fail to get output result.");
                        return ret;
                }
 
                PostProcess postProc;
-               unsigned int classes = outputData.dimInfo[0][1];
+               unsigned int classes = outputTensorInfo.dimInfo[0][1];
                unsigned int top_number = default_top_number;
 
                if (mMetadata.GetOutputMeta().IsParsed()) {
@@ -1134,7 +1124,7 @@ namespace inference
 
                postProc.ScoreClear(top_number);
 
-               auto *prediction = reinterpret_cast<float *>(outputData.data[0]);
+               auto *prediction = reinterpret_cast<float *>(outputTensorInfo.data[0]);
 
                LOGI("class count: %d", classes);
 
@@ -1249,10 +1239,10 @@ namespace inference
 
                        LOGI("Inference: GetObjectDetectionResults: %d\n", results->number_of_objects);
                } else {
-                       tensor_t outputData;
+                       tensor_t outputTensorInfo;
 
-                       // Get inference result and contain it to outputData.
-                       int ret = FillOutputResult(outputData);
+                       // Get inference result and contain it to outputTensorInfo.
+                       int ret = mOutputTensorBuffers.GetTensorInfo(mOutputLayerProperty, outputTensorInfo);
                        if (ret != MEDIA_VISION_ERROR_NONE) {
                                LOGE("Fail to get output result.");
                                return ret;
@@ -1267,18 +1257,18 @@ namespace inference
                        float *scores = nullptr;
                        int number_of_detections = 0;
 
-                       if (outputData.dimInfo.size() == 1) {
+                       if (outputTensorInfo.dimInfo.size() == 1) {
                                // there is no way to know how many objects are detect unless the number of objects aren't
                                // provided. In the case, each backend should provide the number of results manually.
                                // For example, in OpenCV, MobilenetV1-SSD doesn't provide it so the number of objects are
-                               // written to the 1st element i.e., outputData.data[0] (the shape is 1x1xNx7 and the 1st of 7
+                               // written to the 1st element i.e., outputTensorInfo.data[0] (the shape is 1x1xNx7 and the 1st of 7
                                // indicates the image id. But it is useless if a batch mode isn't supported.
                                // So, use the 1st of 7.
 
                                number_of_detections = static_cast<int>(
-                                               *reinterpret_cast<float *>(outputData.data[0]));
-                               cv::Mat cvOutputData(number_of_detections, outputData.dimInfo[0][3],
-                                                                       CV_32F, outputData.data[0]);
+                                               *reinterpret_cast<float *>(outputTensorInfo.data[0]));
+                               cv::Mat cvOutputData(number_of_detections, outputTensorInfo.dimInfo[0][3],
+                                                                       CV_32F, outputTensorInfo.data[0]);
 
                                // boxes
                                cv::Mat cvLeft = cvOutputData.col(3).clone();
@@ -1300,10 +1290,10 @@ namespace inference
                                classes = cvClasses.ptr<float>(0);
                                scores = cvScores.ptr<float>(0);
                        } else {
-                               boxes = reinterpret_cast<float *>(outputData.data[0]);
-                               classes = reinterpret_cast<float *>(outputData.data[1]);
-                               scores = reinterpret_cast<float *>(outputData.data[2]);
-                               number_of_detections = (int) (*reinterpret_cast<float *>(outputData.data[3]));
+                               boxes = reinterpret_cast<float *>(outputTensorInfo.data[0]);
+                               classes = reinterpret_cast<float *>(outputTensorInfo.data[1]);
+                               scores = reinterpret_cast<float *>(outputTensorInfo.data[2]);
+                               number_of_detections = (int) (*reinterpret_cast<float *>(outputTensorInfo.data[3]));
                        }
 
                        LOGI("number_of_detections = %d", number_of_detections);
@@ -1404,10 +1394,10 @@ namespace inference
 
                        LOGE("Inference: GetFaceDetectionResults: %d\n", results->number_of_faces);
                } else {
-                       tensor_t outputData;
+                       tensor_t outputTensorInfo;
 
-                       // Get inference result and contain it to outputData.
-                       int ret = FillOutputResult(outputData);
+                       // Get inference result and contain it to outputTensorInfo.
+                       int ret = mOutputTensorBuffers.GetTensorInfo(mOutputLayerProperty, outputTensorInfo);
                        if (ret != MEDIA_VISION_ERROR_NONE) {
                                LOGE("Fail to get output result.");
                                return ret;
@@ -1423,16 +1413,16 @@ namespace inference
                        int number_of_detections = 0;
                        cv::Mat cvScores, cvClasses, cvBoxes;
 
-                       if (outputData.dimInfo.size() == 1) {
+                       if (outputTensorInfo.dimInfo.size() == 1) {
                                // there is no way to know how many objects are detect unless the number of objects aren't
                                // provided. In the case, each backend should provide the number of results manually.
                                // For example, in OpenCV, MobilenetV1-SSD doesn't provide it so the number of objects are
-                               // written to the 1st element i.e., outputData.data[0] (the shape is 1x1xNx7 and the 1st of 7
+                               // written to the 1st element i.e., outputTensorInfo.data[0] (the shape is 1x1xNx7 and the 1st of 7
                                // indicates the image id. But it is useless if a batch mode isn't supported.
                                // So, use the 1st of 7.
 
-                               number_of_detections = static_cast<int>(*reinterpret_cast<float *>(outputData.data[0]));
-                               cv::Mat cvOutputData(number_of_detections, outputData.dimInfo[0][3], CV_32F, outputData.data[0]);
+                               number_of_detections = static_cast<int>(*reinterpret_cast<float *>(outputTensorInfo.data[0]));
+                               cv::Mat cvOutputData(number_of_detections, outputTensorInfo.dimInfo[0][3], CV_32F, outputTensorInfo.data[0]);
 
                                // boxes
                                cv::Mat cvLeft = cvOutputData.col(3).clone();
@@ -1452,10 +1442,10 @@ namespace inference
                                classes = cvClasses.ptr<float>(0);
                                scores = cvScores.ptr<float>(0);
                        } else {
-                               boxes = reinterpret_cast<float *>(outputData.data[0]);
-                               classes = reinterpret_cast<float *>(outputData.data[1]);
-                               scores = reinterpret_cast<float *>(outputData.data[2]);
-                               number_of_detections = static_cast<int>(*reinterpret_cast<float *>(outputData.data[3]));
+                               boxes = reinterpret_cast<float *>(outputTensorInfo.data[0]);
+                               classes = reinterpret_cast<float *>(outputTensorInfo.data[1]);
+                               scores = reinterpret_cast<float *>(outputTensorInfo.data[2]);
+                               number_of_detections = static_cast<int>(*reinterpret_cast<float *>(outputTensorInfo.data[3]));
                        }
 
                        results->number_of_faces = 0;
@@ -1558,23 +1548,23 @@ namespace inference
 
                        results->number_of_landmarks = results->locations.size();
                } else {
-                       tensor_t outputData;
+                       tensor_t outputTensorInfo;
 
-                       // Get inference result and contain it to outputData.
-                       int ret = FillOutputResult(outputData);
+                       // Get inference result and contain it to outputTensorInfo.
+                       int ret = mOutputTensorBuffers.GetTensorInfo(mOutputLayerProperty, outputTensorInfo);
                        if (ret != MEDIA_VISION_ERROR_NONE) {
                                LOGE("Fail to get output result.");
                                return ret;
                        }
 
-                       int number_of_detections = outputData.dimInfo[0][1] >> 1;
+                       int number_of_detections = outputTensorInfo.dimInfo[0][1] >> 1;
 
                        results->number_of_landmarks = number_of_detections;
                        results->locations.resize(number_of_detections);
 
                        LOGI("imgW:%d, imgH:%d", mSourceSize.width, mSourceSize.height);
 
-                       float *loc = reinterpret_cast<float *>(outputData.data[0]);
+                       float *loc = reinterpret_cast<float *>(outputTensorInfo.data[0]);
 
                        for (auto& point : results->locations) {
                                point.x = static_cast<int>(*loc++ * mSourceSize.width);
@@ -1689,26 +1679,26 @@ namespace inference
 
                        detectionResults = std::move(poseResult);
                } else {
-                       tensor_t outputData;
+                       tensor_t outputTensorInfo;
 
-                       // Get inference result and contain it to outputData.
-                       int ret = FillOutputResult(outputData);
+                       // Get inference result and contain it to outputTensorInfo.
+                       int ret = mOutputTensorBuffers.GetTensorInfo(mOutputLayerProperty, outputTensorInfo);
                        if (ret != MEDIA_VISION_ERROR_NONE) {
                                        LOGE("Fail to get output result.");
                                        return ret;
                        }
 
-                       cv::Mat reShapeTest(cv::Size(outputData.dimInfo[0][2], outputData.dimInfo[0][1]),
-                                                                                CV_32FC(outputData.dimInfo[0][3]), outputData.data[0]);
-                       cv::Mat multiChannels[outputData.dimInfo[0][3]];
+                       cv::Mat reShapeTest(cv::Size(outputTensorInfo.dimInfo[0][2], outputTensorInfo.dimInfo[0][1]),
+                                                                                CV_32FC(outputTensorInfo.dimInfo[0][3]), outputTensorInfo.data[0]);
+                       cv::Mat multiChannels[outputTensorInfo.dimInfo[0][3]];
 
                        split(reShapeTest, multiChannels);
 
-                       float ratioX = static_cast<float>(outputData.dimInfo[0][2]);
-                       float ratioY = static_cast<float>(outputData.dimInfo[0][1]);
+                       float ratioX = static_cast<float>(outputTensorInfo.dimInfo[0][2]);
+                       float ratioY = static_cast<float>(outputTensorInfo.dimInfo[0][1]);
 
                        poseResult->number_of_poses = 1;
-                       poseResult->number_of_landmarks_per_pose = outputData.dimInfo[0][3];
+                       poseResult->number_of_landmarks_per_pose = outputTensorInfo.dimInfo[0][3];
 
                        if (poseResult->number_of_landmarks_per_pose >= MAX_NUMBER_OF_LANDMARKS_PER_POSE) {
                                LOGE("Exeeded maxinum number of landmarks per pose(%d >= %d).",
index e08e5d8..161f72f 100644 (file)
@@ -31,7 +31,7 @@ namespace inference
 
        bool TensorBuffer::empty()
        {
-               return mTensorBuffer.empty();
+               return _tensorBuffer.empty();
        }
 
        bool TensorBuffer::exist(std::string name)
@@ -78,7 +78,7 @@ namespace inference
 
        void TensorBuffer::release()
        {
-               for (auto& tensorBuffer : mTensorBuffer) {
+               for (auto& tensorBuffer : _tensorBuffer) {
                        auto& tBuffer = tensorBuffer.second;
                        if (tBuffer.owner_is_backend) {
                                continue;
@@ -97,27 +97,27 @@ namespace inference
                        }
                }
 
-               LOGI("Tensor(%zu) have been released.", mTensorBuffer.size());
-               IETensorBuffer().swap(mTensorBuffer);
+               LOGI("Tensor(%zu) have been released.", _tensorBuffer.size());
+               IETensorBuffer().swap(_tensorBuffer);
        }
 
        size_t TensorBuffer::size()
        {
-               return mTensorBuffer.size();
+               return _tensorBuffer.size();
        }
 
-       IETensorBuffer& TensorBuffer::getAllTensorBuffer()
+       IETensorBuffer& TensorBuffer::getIETensorBuffer()
        {
-               return mTensorBuffer;
+               return _tensorBuffer;
        }
 
        inference_engine_tensor_buffer* TensorBuffer::getTensorBuffer(std::string name)
        {
-               if (mTensorBuffer.find(name) == mTensorBuffer.end()){
+               if (_tensorBuffer.find(name) == _tensorBuffer.end()){
                        return nullptr;
                }
 
-               return &mTensorBuffer[name];
+               return &_tensorBuffer[name];
        }
 
        bool TensorBuffer::addTensorBuffer(std::string name, inference_engine_tensor_buffer& buffer)
@@ -127,7 +127,7 @@ namespace inference
                        return false;
                }
 
-               auto ret = mTensorBuffer.insert(std::make_pair(name, buffer));
+               auto ret = _tensorBuffer.insert(std::make_pair(name, buffer));
                if (ret.second == false) {
                        LOGE("Fail to insert %s with buffer %p", name.c_str(), buffer.buffer);
                        return false;
@@ -136,10 +136,35 @@ namespace inference
                return true;
        }
 
+       int TensorBuffer::GetTensorInfo(inference_engine_layer_property& layerProperty, tensor_t& outputTensorInfo)
+       {
+               for (auto& layer : layerProperty.layers) {
+                       const inference_engine_tensor_info& tensor_info = layer.second;
+
+                       std::vector<int> dimInfo;
+
+                       for (auto& dim : tensor_info.shape) {
+                               dimInfo.push_back(dim);
+                       }
+
+                       outputTensorInfo.dimInfo.push_back(dimInfo);
+
+                       inference_engine_tensor_buffer* tensorBuffer = getTensorBuffer(layer.first);
+                       if (tensorBuffer == NULL) {
+                               LOGE("Fail to getTensorBuffer with name %s", layer.first.c_str());
+                               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+                       }
+
+                       outputTensorInfo.data.push_back(static_cast<void *>(tensorBuffer->buffer));
+               }
+
+               return MEDIA_VISION_ERROR_NONE;
+       }
+
        template <typename T>
-       int TensorBuffer::convertToFloat(inference_engine_tensor_buffer *tensorBuffer, const inference_engine_tensor_info& tensor_info)
+       int TensorBuffer::convertToFloat(inference_engine_tensor_buffer *tensorBuffer)
        {
-               float *new_buf = new(std::nothrow) float[tensor_info.size];
+               float *new_buf = new(std::nothrow) float[tensorBuffer->size];
                if (new_buf == NULL) {
                        LOGE("Fail to allocate a new output tensor buffer.");
                        return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
@@ -147,7 +172,7 @@ namespace inference
 
                auto ori_buf = static_cast<T *>(tensorBuffer->buffer);
 
-               for (size_t idx = 0; idx < tensor_info.size; idx++)
+               for (size_t idx = 0; idx < tensorBuffer->size; idx++)
                        new_buf[idx] = static_cast<float>(ori_buf[idx]) / 255.0f;
 
                // replace original buffer with new one, and release origin one.
@@ -195,8 +220,8 @@ namespace inference
 
        template float TensorBuffer::getValue<float>(std::string, int);
        template int TensorBuffer::getValue<int>(std::string, int);
-       template int TensorBuffer::convertToFloat<unsigned char>(_inference_engine_tensor_buffer*, _inference_engine_tensor_info const&);
-       template int TensorBuffer::convertToFloat<unsigned short>(_inference_engine_tensor_buffer*, _inference_engine_tensor_info const&);
+       template int TensorBuffer::convertToFloat<unsigned char>(_inference_engine_tensor_buffer*);
+       template int TensorBuffer::convertToFloat<unsigned short>(_inference_engine_tensor_buffer*);
 
 } /* Inference */
 } /* MediaVision */