blob: 256b2d8e2ea2ec4f9e550c96c3c1b92a84895cc4 [file] [log] [blame]
/*
* dnn_inference_engine.cpp - dnn inference engine
*
* Copyright (c) 2019 Intel Corporation
*
* 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.
*
* Author: Zong Wei <[email protected]>
*/
#include <format_reader_ptr.h>
#include "dnn_inference_engine.h"
using namespace std;
using namespace InferenceEngine;
namespace XCam {
DnnInferenceEngine::DnnInferenceEngine (DnnInferConfig& config)
: _model_created (false)
, _model_loaded (false)
, _input_image_width (0)
, _input_image_height (0)
{
XCAM_LOG_DEBUG ("DnnInferenceEngine::DnnInferenceEngine");
create_model (config);
}
DnnInferenceEngine::~DnnInferenceEngine ()
{
}
XCamReturn
DnnInferenceEngine::create_model (DnnInferConfig& config)
{
XCAM_LOG_DEBUG ("DnnInferenceEngine::create_model");
if (_model_created) {
XCAM_LOG_INFO ("model already created!");
return XCAM_RETURN_NO_ERROR;
}
// 1. Read the Intermediate Representation
XCAM_LOG_DEBUG ("pre-trained model file name: %s", config.model_filename);
if (NULL == config.model_filename) {
XCAM_LOG_ERROR ("Model file name is empty!");
return XCAM_RETURN_ERROR_PARAM;
}
_network_reader.ReadNetwork (get_filename_prefix (config.model_filename) + ".xml");
_network_reader.ReadWeights (get_filename_prefix (config.model_filename) + ".bin");
// 2. Prepare inputs and outputs format
_network = _network_reader.getNetwork ();
_inputs_info = _network.getInputsInfo ();
_outputs_info = _network.getOutputsInfo ();
// 3. Select Plugin - Select the plugin on which to load your network.
// 3.1. Create the plugin with the InferenceEngine::PluginDispatcher load helper class.
if (NULL == config.plugin_path) {
InferenceEngine::PluginDispatcher dispatcher ({""});
_plugin = dispatcher.getPluginByDevice (getDeviceName (get_device_from_id (config.target_id)));
} else {
InferenceEngine::PluginDispatcher dispatcher ({config.plugin_path});
_plugin = dispatcher.getPluginByDevice (getDeviceName (get_device_from_id (config.target_id)));
}
// 3.2. Pass per device loading configurations specific to this device,
// and register extensions to this device.
if (DnnInferDeviceCPU == config.target_id) {
/**
* cpu_extensions library is compiled from "extension" folder containing
* custom MKLDNNPlugin layer implementations. These layers are not supported
* by mkldnn, but they can be useful for inferring custom topologies.
**/
_plugin.AddExtension (std::make_shared<Extensions::Cpu::CpuExtensions>());
if (NULL != config.cpu_ext_path) {
std::string cpu_ext_path (config.cpu_ext_path);
// CPU(MKLDNN) extensions are loaded as a shared library and passed as a pointer to base extension
auto extensionPtr = InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(cpu_ext_path);
_plugin.AddExtension (extensionPtr);
XCAM_LOG_DEBUG ("CPU Extension loaded: %s", cpu_ext_path);
}
} else if (DnnInferDeviceGPU == config.target_id) {
if (NULL != config.cldnn_ext_path) {
std::string cldnn_ext_path (config.cldnn_ext_path);
// clDNN Extensions are loaded from an .xml description and OpenCL kernel files
_plugin.SetConfig ({ { InferenceEngine::PluginConfigParams::KEY_CONFIG_FILE, cldnn_ext_path } });
XCAM_LOG_DEBUG ("GPU Extension loaded: %s", cldnn_ext_path);
}
}
if (config.perf_counter > 0) {
_plugin.SetConfig ({ { InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, InferenceEngine::PluginConfigParams::YES } });
}
_model_created = true;
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::load_model (DnnInferConfig& config)
{
XCAM_LOG_DEBUG ("DnnInferenceEngine::load_model");
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
if (_model_loaded) {
XCAM_LOG_INFO ("model already loaded!");
return XCAM_RETURN_NO_ERROR;
}
InferenceEngine::ExecutableNetwork execute_network = _plugin.LoadNetwork (_network, {});
_infer_request = execute_network.CreateInferRequest ();
_model_loaded = true;
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::get_info (DnnInferenceEngineInfo& info, DnnInferInfoType type)
{
XCAM_LOG_DEBUG ("DnnInferenceEngine::get_info type %d", type);
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
info.type = type;
if (DnnInferInfoEngine == type) {
info.major = GetInferenceEngineVersion ()->apiVersion.major;
info.minor = GetInferenceEngineVersion ()->apiVersion.minor;
} else if (DnnInferInfoPlugin == type) {
const InferenceEngine::Version *plugin_version = NULL;
static_cast<InferenceEngine::InferenceEnginePluginPtr>(_plugin)->GetVersion (plugin_version);
info.major = plugin_version->apiVersion.major;
info.minor = plugin_version->apiVersion.minor;
info.desc = plugin_version->description;
} else if (DnnInferInfoNetwork == type) {
info.major = _network_reader.getVersion ();
info.desc = _network_reader.getDescription ().c_str ();
info.name = _network_reader.getName ().c_str ();
} else {
XCAM_LOG_WARNING ("DnnInferenceEngine::get_info type %d not supported!", type);
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::set_batch_size (const size_t size)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
_network.setBatchSize (size);
return XCAM_RETURN_NO_ERROR;
}
size_t
DnnInferenceEngine::get_batch_size ()
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return -1;
}
return _network.getBatchSize ();
}
XCamReturn
DnnInferenceEngine::start (bool sync)
{
XCAM_LOG_DEBUG ("Start inference sync(%d)", sync);
if (! _model_loaded) {
XCAM_LOG_ERROR ("Please load the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
if (sync) {
_infer_request.Infer ();
} else {
_infer_request.StartAsync ();
_infer_request.Wait (IInferRequest::WaitMode::RESULT_READY);
}
return XCAM_RETURN_NO_ERROR;
}
size_t
DnnInferenceEngine::get_input_size ()
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return -1;
}
InputsDataMap inputs_info (_network.getInputsInfo());
return inputs_info.size ();
}
size_t
DnnInferenceEngine::get_output_size ()
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return -1;
}
OutputsDataMap outputs_info (_network.getOutputsInfo());
return outputs_info.size ();
}
XCamReturn
DnnInferenceEngine::set_input_presion (uint32_t idx, DnnInferPrecisionType precision)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
uint32_t id = 0;
if (idx > _inputs_info.size ()) {
XCAM_LOG_ERROR ("Input is out of range");
return XCAM_RETURN_ERROR_PARAM;
}
for (auto & item : _inputs_info) {
if (id == idx) {
Precision input_precision = convert_precision_type (precision);
item.second->setPrecision (input_precision);
break;
}
id++;
}
return XCAM_RETURN_NO_ERROR;
}
DnnInferPrecisionType
DnnInferenceEngine::get_input_presion (uint32_t idx)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return DnnInferPrecisionUnspecified;
}
uint32_t id = 0;
if (idx > _inputs_info.size ()) {
XCAM_LOG_ERROR ("Input is out of range");
return DnnInferPrecisionUnspecified;
}
/** Iterating over all input blobs **/
for (auto & item : _inputs_info) {
if (id == idx) {
Precision input_precision = item.second->getPrecision ();
return convert_precision_type (input_precision);
}
id++;
}
return DnnInferPrecisionUnspecified;
}
XCamReturn
DnnInferenceEngine::set_output_presion (uint32_t idx, DnnInferPrecisionType precision)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
uint32_t id = 0;
if (idx > _outputs_info.size ()) {
XCAM_LOG_ERROR ("Output is out of range");
return XCAM_RETURN_ERROR_PARAM;
}
for (auto & item : _outputs_info) {
if (id == idx) {
Precision output_precision = convert_precision_type (precision);
item.second->setPrecision (output_precision);
break;
}
id++;
}
return XCAM_RETURN_NO_ERROR;
}
DnnInferPrecisionType
DnnInferenceEngine::get_output_presion (uint32_t idx)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return DnnInferPrecisionUnspecified;
}
uint32_t id = 0;
if (idx > _outputs_info.size ()) {
XCAM_LOG_ERROR ("Input is out of range");
return DnnInferPrecisionUnspecified;
}
/** Iterating over all output blobs **/
for (auto & item : _outputs_info) {
if (id == idx) {
Precision output_precision = item.second->getPrecision ();
return convert_precision_type (output_precision);
}
id++;
}
return DnnInferPrecisionUnspecified;
}
XCamReturn
DnnInferenceEngine::set_input_layout (uint32_t idx, DnnInferLayoutType layout)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
uint32_t id = 0;
if (idx > _inputs_info.size ()) {
XCAM_LOG_ERROR ("Input is out of range");
return XCAM_RETURN_ERROR_PARAM;
}
/** Iterating over all input blobs **/
for (auto & item : _inputs_info) {
if (id == idx) {
/** Creating first input blob **/
Layout input_layout = convert_layout_type (layout);
item.second->setLayout (input_layout);
break;
}
id++;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::set_output_layout (uint32_t idx, DnnInferLayoutType layout)
{
if (! _model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
uint32_t id = 0;
if (idx > _outputs_info.size ()) {
XCAM_LOG_ERROR ("Output is out of range");
return XCAM_RETURN_ERROR_PARAM;
}
/** Iterating over all output blobs **/
for (auto & item : _outputs_info) {
if (id == idx) {
Layout output_layout = convert_layout_type (layout);
item.second->setLayout (output_layout);
break;
}
id++;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::get_model_input_info (DnnInferInputOutputInfo& info)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
int id = 0;
for (auto & item : _inputs_info) {
auto& input = item.second;
const InferenceEngine::SizeVector input_dims = input->getDims ();
info.width[id] = input_dims[0];
info.height[id] = input_dims[1];
info.channels[id] = input_dims[2];
info.object_size[id] = input_dims[3];
info.precision[id] = convert_precision_type (input->getPrecision());
info.layout[id] = convert_layout_type (input->getLayout());
item.second->setPrecision(Precision::U8);
id++;
}
info.batch_size = get_batch_size ();
info.numbers = _inputs_info.size ();
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::set_model_input_info (DnnInferInputOutputInfo& info)
{
XCAM_LOG_DEBUG ("DnnInferenceEngine::set_model_input_info");
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
if (info.numbers != _inputs_info.size ()) {
XCAM_LOG_ERROR ("Input size is not matched with model info numbers %d !", info.numbers);
return XCAM_RETURN_ERROR_PARAM;
}
int id = 0;
for (auto & item : _inputs_info) {
Precision precision = convert_precision_type (info.precision[id]);
item.second->setPrecision (precision);
Layout layout = convert_layout_type (info.layout[id]);
item.second->setLayout (layout);
id++;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::get_model_output_info (DnnInferInputOutputInfo& info)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
int id = 0;
std::string output_name;
DataPtr output_info;
for (const auto& out : _outputs_info) {
if (out.second->creatorLayer.lock()->type == "DetectionOutput") {
output_name = out.first;
output_info = out.second;
}
}
if (output_info.get ()) {
const InferenceEngine::SizeVector output_dims = output_info->getTensorDesc().getDims();
info.width[id] = output_dims[0];
info.height[id] = output_dims[1];
info.channels[id] = output_dims[2];
info.object_size[id] = output_dims[3];
info.precision[id] = convert_precision_type (output_info->getPrecision());
info.layout[id] = convert_layout_type (output_info->getLayout());
info.batch_size = 1;
info.numbers = _outputs_info.size ();
} else {
XCAM_LOG_ERROR ("Get output info error!");
return XCAM_RETURN_ERROR_UNKNOWN;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::set_model_output_info (DnnInferInputOutputInfo& info)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
if (info.numbers != _outputs_info.size()) {
XCAM_LOG_ERROR ("Output size is not matched with model!");
return XCAM_RETURN_ERROR_PARAM;
}
int id = 0;
for (auto & item : _outputs_info) {
Precision precision = convert_precision_type (info.precision[id]);
item.second->setPrecision (precision);
Layout layout = convert_layout_type (info.layout[id]);
item.second->setLayout (layout);
id++;
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::set_input_blob (uint32_t idx, DnnInferData& data)
{
unsigned int id = 0;
std::string item_name;
if (idx > _inputs_info.size()) {
XCAM_LOG_ERROR ("Input is out of range");
return XCAM_RETURN_ERROR_PARAM;
}
for (auto & item : _inputs_info) {
if (id == idx) {
item_name = item.first;
break;
}
id++;
}
if (item_name.empty ()) {
XCAM_LOG_ERROR ("item name is empty!");
return XCAM_RETURN_ERROR_PARAM;
}
if (data.batch_idx > get_batch_size ()) {
XCAM_LOG_ERROR ("Too many input, it is bigger than batch size!");
return XCAM_RETURN_ERROR_PARAM;
}
Blob::Ptr blob = _infer_request.GetBlob (item_name);
if (data.precision == DnnInferPrecisionFP32) {
if (data.data_type == DnnInferDataTypeImage) {
copy_image_to_blob<PrecisionTrait<Precision::FP32>::value_type>(data, blob, data.batch_idx);
} else {
copy_data_to_blob<PrecisionTrait<Precision::FP32>::value_type>(data, blob, data.batch_idx);
}
} else {
if (data.data_type == DnnInferDataTypeImage) {
copy_image_to_blob<uint8_t>(data, blob, data.batch_idx);
} else {
copy_data_to_blob<uint8_t>(data, blob, data.batch_idx);
}
}
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DnnInferenceEngine::set_inference_data (std::vector<std::string> images)
{
if (!_model_created) {
XCAM_LOG_ERROR ("Please create the model firstly!");
return XCAM_RETURN_ERROR_ORDER;
}
uint32_t idx = 0;
for (auto & i : images) {
FormatReader::ReaderPtr reader (i.c_str ());
if (reader.get () == NULL) {
XCAM_LOG_WARNING ("Image %d cannot be read!", i);
continue;
}
_input_image_width = reader->width ();
_input_image_height = reader->height ();
uint32_t image_width = 0;
uint32_t image_height = 0;
for (auto & item : _inputs_info) {
image_width = _inputs_info[item.first]->getDims()[0];
image_height = _inputs_info[item.first]->getDims()[1];
}
std::shared_ptr<unsigned char> data (reader->getData (image_width, image_height));
if (data.get () != NULL) {
DnnInferData image;
image.width = image_width;
image.height = image_height;
image.width_stride = image_width;
image.height_stride = image_height;
image.buffer = data.get ();
image.channel_num = 3;
image.batch_idx = idx;
image.image_format = DnnInferImageFormatBGRPacked;
// set precision & data type
image.precision = get_input_presion (idx);
image.data_type = DnnInferDataTypeImage;
set_input_blob (idx, image);
idx ++;
} else {
XCAM_LOG_WARNING ("Valid input images were not found!");
continue;
}
}
return XCAM_RETURN_NO_ERROR;
}
std::shared_ptr<uint8_t>
DnnInferenceEngine::read_inference_image (std::string image)
{
FormatReader::ReaderPtr reader (image.c_str ());
if (reader.get () == NULL) {
XCAM_LOG_WARNING ("Image cannot be read!");
return NULL;
}
uint32_t image_width = reader->width ();
uint32_t image_height = reader->height ();
std::shared_ptr<uint8_t> data (reader->getData (image_width, image_height));
if (data.get () != NULL) {
return data;
} else {
XCAM_LOG_WARNING ("Valid input images were not found!");
return NULL;
}
}
void*
DnnInferenceEngine::get_inference_results (uint32_t idx, uint32_t& size)
{
if (! _model_created || ! _model_loaded) {
XCAM_LOG_ERROR ("Please create and load the model firstly!");
return NULL;
}
uint32_t id = 0;
std::string item_name;
if (idx > _outputs_info.size ()) {
XCAM_LOG_ERROR ("Output is out of range");
return NULL;
}
for (auto & item : _outputs_info) {
if (item.second->creatorLayer.lock()->type == "DetectionOutput") {
item_name = item.first;
break;
}
id++;
}
if (item_name.empty ()) {
XCAM_LOG_ERROR ("item name is empty!");
return NULL;
}
const Blob::Ptr blob = _infer_request.GetBlob (item_name);
float* output_result = static_cast<PrecisionTrait<Precision::FP32>::value_type*>(blob->buffer ());
size = blob->byteSize ();
return (reinterpret_cast<void *>(output_result));
}
InferenceEngine::TargetDevice
DnnInferenceEngine::get_device_from_string (const std::string &device_name)
{
return InferenceEngine::TargetDeviceInfo::fromStr (device_name);
}
InferenceEngine::TargetDevice
DnnInferenceEngine::get_device_from_id (DnnInferTargetDeviceType device)
{
switch (device) {
case DnnInferDeviceDefault:
return InferenceEngine::TargetDevice::eDefault;
case DnnInferDeviceBalanced:
return InferenceEngine::TargetDevice::eBalanced;
case DnnInferDeviceCPU:
return InferenceEngine::TargetDevice::eCPU;
case DnnInferDeviceGPU:
return InferenceEngine::TargetDevice::eGPU;
case DnnInferDeviceFPGA:
return InferenceEngine::TargetDevice::eFPGA;
case DnnInferDeviceMyriad:
return InferenceEngine::TargetDevice::eMYRIAD;
case DnnInferDeviceHetero:
return InferenceEngine::TargetDevice::eHETERO;
default:
return InferenceEngine::TargetDevice::eCPU;
}
}
InferenceEngine::Layout
DnnInferenceEngine::estimate_layout_type (const int ch_num)
{
if (ch_num == 4) {
return InferenceEngine::Layout::NCHW;
} else if (ch_num == 3) {
return InferenceEngine::Layout::CHW;
} else if (ch_num == 2) {
return InferenceEngine::Layout::NC;
} else {
return InferenceEngine::Layout::ANY;
}
}
InferenceEngine::Layout
DnnInferenceEngine::convert_layout_type (DnnInferLayoutType layout)
{
switch (layout) {
case DnnInferLayoutNCHW:
return InferenceEngine::Layout::NCHW;
case DnnInferLayoutNHWC:
return InferenceEngine::Layout::NHWC;
case DnnInferLayoutOIHW:
return InferenceEngine::Layout::OIHW;
case DnnInferLayoutC:
return InferenceEngine::Layout::C;
case DnnInferLayoutCHW:
return InferenceEngine::Layout::CHW;
case DnnInferLayoutHW:
return InferenceEngine::Layout::HW;
case DnnInferLayoutNC:
return InferenceEngine::Layout::NC;
case DnnInferLayoutCN:
return InferenceEngine::Layout::CN;
case DnnInferLayoutBlocked:
return InferenceEngine::Layout::BLOCKED;
case DnnInferLayoutAny:
return InferenceEngine::Layout::ANY;
default:
return InferenceEngine::Layout::ANY;
}
}
DnnInferLayoutType
DnnInferenceEngine::convert_layout_type (InferenceEngine::Layout layout)
{
switch (layout) {
case InferenceEngine::Layout::NCHW:
return DnnInferLayoutNCHW;
case InferenceEngine::Layout::NHWC:
return DnnInferLayoutNHWC;
case InferenceEngine::Layout::OIHW:
return DnnInferLayoutOIHW;
case InferenceEngine::Layout::C:
return DnnInferLayoutC;
case InferenceEngine::Layout::CHW:
return DnnInferLayoutCHW;
case InferenceEngine::Layout::HW:
return DnnInferLayoutHW;
case InferenceEngine::Layout::NC:
return DnnInferLayoutNC;
case InferenceEngine::Layout::CN:
return DnnInferLayoutCN;
case InferenceEngine::Layout::BLOCKED:
return DnnInferLayoutBlocked;
case InferenceEngine::Layout::ANY:
return DnnInferLayoutAny;
default:
return DnnInferLayoutAny;
}
}
InferenceEngine::Precision
DnnInferenceEngine::convert_precision_type (DnnInferPrecisionType precision)
{
switch (precision) {
case DnnInferPrecisionMixed:
return InferenceEngine::Precision::MIXED;
case DnnInferPrecisionFP32:
return InferenceEngine::Precision::FP32;
case DnnInferPrecisionFP16:
return InferenceEngine::Precision::FP16;
case DnnInferPrecisionQ78:
return InferenceEngine::Precision::Q78;
case DnnInferPrecisionI16:
return InferenceEngine::Precision::I16;
case DnnInferPrecisionU8:
return InferenceEngine::Precision::U8;
case DnnInferPrecisionI8:
return InferenceEngine::Precision::I8;
case DnnInferPrecisionU16:
return InferenceEngine::Precision::U16;
case DnnInferPrecisionI32:
return InferenceEngine::Precision::I32;
case DnnInferPrecisionCustom:
return InferenceEngine::Precision::CUSTOM;
case DnnInferPrecisionUnspecified:
return InferenceEngine::Precision::UNSPECIFIED;
default:
return InferenceEngine::Precision::UNSPECIFIED;
}
}
DnnInferPrecisionType
DnnInferenceEngine::convert_precision_type (InferenceEngine::Precision precision)
{
switch (precision) {
case InferenceEngine::Precision::MIXED:
return DnnInferPrecisionMixed;
case InferenceEngine::Precision::FP32:
return DnnInferPrecisionFP32;
case InferenceEngine::Precision::FP16:
return DnnInferPrecisionFP16;
case InferenceEngine::Precision::Q78:
return DnnInferPrecisionQ78;
case InferenceEngine::Precision::I16:
return DnnInferPrecisionI16;
case InferenceEngine::Precision::U8:
return DnnInferPrecisionU8;
case InferenceEngine::Precision::I8:
return DnnInferPrecisionI8;
case InferenceEngine::Precision::U16:
return DnnInferPrecisionU16;
case InferenceEngine::Precision::I32:
return DnnInferPrecisionI32;
case InferenceEngine::Precision::CUSTOM:
return DnnInferPrecisionCustom;
case InferenceEngine::Precision::UNSPECIFIED:
return DnnInferPrecisionUnspecified;
default:
return DnnInferPrecisionUnspecified;
}
}
std::string
DnnInferenceEngine::get_filename_prefix (const std::string &file_path)
{
auto pos = file_path.rfind ('.');
if (pos == std::string::npos) {
return file_path;
}
return file_path.substr (0, pos);
}
template <typename T> XCamReturn
DnnInferenceEngine::copy_image_to_blob (const DnnInferData& data, Blob::Ptr& blob, int batch_index)
{
SizeVector blob_size = blob.get()->dims ();
const size_t width = blob_size[0];
const size_t height = blob_size[1];
const size_t channels = blob_size[2];
const size_t image_size = width * height;
unsigned char* buffer = (unsigned char*)data.buffer;
T* blob_data = blob->buffer ().as<T*>();
if (width != data.width || height != data.height) {
XCAM_LOG_ERROR ("Input Image size (%dx%d) is not matched with model required size (%dx%d)!",
data.width, data.height, width, height);
return XCAM_RETURN_ERROR_PARAM;
}
int batch_offset = batch_index * height * width * channels;
if (DnnInferImageFormatBGRPlanar == data.image_format) {
// B G R planar input image
size_t image_stride_size = data.height_stride * data.width_stride;
if (data.width == data.width_stride &&
data.height == data.height_stride) {
std::memcpy (blob_data + batch_offset, buffer, image_size * channels);
} else if (data.width == data.width_stride) {
for (size_t ch = 0; ch < channels; ++ch) {
std::memcpy (blob_data + batch_offset + ch * image_size, buffer + ch * image_stride_size, image_size);
}
} else {
for (size_t ch = 0; ch < channels; ++ch) {
for (size_t h = 0; h < height; h++) {
std::memcpy (blob_data + batch_offset + ch * image_size + h * width, buffer + ch * image_stride_size + h * data.width_stride, width);
}
}
}
} else if (DnnInferImageFormatBGRPacked == data.image_format) {
for (size_t pid = 0; pid < image_size; pid++) {
for (size_t ch = 0; ch < channels; ++ch) {
blob_data[batch_offset + ch * image_size + pid] = buffer[pid * channels + ch];
}
}
}
return XCAM_RETURN_NO_ERROR;
}
template <typename T> XCamReturn
DnnInferenceEngine::copy_data_to_blob (const DnnInferData& data, Blob::Ptr& blob, int batch_index)
{
SizeVector blob_size = blob.get ()->dims ();
T * buffer = (T *)data.buffer;
T* blob_data = blob->buffer ().as<T*>();
int batch_offset = batch_index * data.size;
memcpy (blob_data + batch_offset, buffer, data.size);
return XCAM_RETURN_NO_ERROR;
}
void
DnnInferenceEngine::print_performance_counts (const std::map<std::string, InferenceEngine::InferenceEngineProfileInfo>& performance_map)
{
long long total_time = 0;
XCAM_LOG_DEBUG ("performance counts:");
for (const auto & it : performance_map) {
std::string to_print(it.first);
const int max_layer_name = 30;
if (it.first.length () >= max_layer_name) {
to_print = it.first.substr (0, max_layer_name - 4);
to_print += "...";
}
std::cout << std::setw(max_layer_name) << std::left << to_print;
switch (it.second.status) {
case InferenceEngine::InferenceEngineProfileInfo::EXECUTED:
std::cout << std::setw (15) << std::left << "EXECUTED";
break;
case InferenceEngine::InferenceEngineProfileInfo::NOT_RUN:
std::cout << std::setw (15) << std::left << "NOT_RUN";
break;
case InferenceEngine::InferenceEngineProfileInfo::OPTIMIZED_OUT:
std::cout << std::setw(15) << std::left << "OPTIMIZED_OUT";
break;
}
std::cout << std::setw (30) << std::left << "layerType: " + std::string (it.second.layer_type) + " ";
std::cout << std::setw (20) << std::left << "realTime: " + std::to_string (it.second.realTime_uSec);
std::cout << std::setw (20) << std::left << " cpu: " + std::to_string (it.second.cpu_uSec);
std::cout << " execType: " << it.second.exec_type << std::endl;
if (it.second.realTime_uSec > 0) {
total_time += it.second.realTime_uSec;
}
}
std::cout << std::setw (20) << std::left << "Total time: " + std::to_string (total_time) << " microseconds" << std::endl;
}
void
DnnInferenceEngine::print_log (uint32_t flag)
{
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> perfomance_map;
if (flag == DnnInferLogLevelNone) {
return;
}
if (flag & DnnInferLogLevelEngine) {
static_cast<InferenceEngine::InferenceEnginePluginPtr>(_plugin)->GetPerformanceCounts (perfomance_map, NULL);
print_performance_counts (perfomance_map);
}
if (flag & DnnInferLogLevelLayer) {
perfomance_map = _infer_request.GetPerformanceCounts ();
print_performance_counts (perfomance_map);
}
}
} // namespace XCam