Several samples moved to OpenVINO 2.0 (#7970)
* ngraph functio sample * Fixes * OV2.0: NV12 hello classification with new preprocessing API * Fix clang-format * Rewrote several samples * Some updates * clang-format * Fixed TODO * Fixed comments and improved samples * Preprocessing comments * clang-format * Fixed comment * Fixed Windows * Added back Blob support to ClassificationResult Co-authored-by: Michael Nosov <mikhail.nosov@intel.com>
This commit is contained in:
parent
c6eaa5d653
commit
eb7f261d15
@ -3,7 +3,7 @@
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief The entry point the Inference Engine sample application
|
||||
* @brief The entry point the OpenVINO Runtime sample application
|
||||
* @file classification_sample_async/main.cpp
|
||||
* @example classification_sample_async/main.cpp
|
||||
*/
|
||||
@ -25,8 +25,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "classification_sample_async.h"
|
||||
#include "openvino/openvino.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace ov::preprocess;
|
||||
|
||||
/**
|
||||
* @brief Checks input args
|
||||
@ -62,170 +63,135 @@ bool ParseAndCheckCommandLine(int argc, char* argv[]) {
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
// ------------------------------ Get Inference Engine version
|
||||
// ------------------------------------------------------
|
||||
slog::info << "InferenceEngine: " << GetInferenceEngineVersion() << slog::endl;
|
||||
// -------- Get OpenVINO Runtime version --------
|
||||
slog::info << "OpenVINO runtime: " << ov::get_openvino_version() << slog::endl;
|
||||
|
||||
// ------------------------------ Parsing and validation of input arguments
|
||||
// ---------------------------------
|
||||
// -------- Parsing and validation of input arguments --------
|
||||
if (!ParseAndCheckCommandLine(argc, argv)) {
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// ------------------------------ Read input
|
||||
// -----------------------------------------------------------
|
||||
/** This vector stores paths to the processed images **/
|
||||
std::vector<std::string> imageNames;
|
||||
parseInputFilesArguments(imageNames);
|
||||
if (imageNames.empty())
|
||||
throw std::logic_error("No suitable images were found");
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 1. Initialize inference engine core
|
||||
// -------------------------------------
|
||||
slog::info << "Loading Inference Engine" << slog::endl;
|
||||
Core ie;
|
||||
// ------------------------------ Get Available Devices
|
||||
// ------------------------------------------------------
|
||||
slog::info << "Device info: " << slog::endl;
|
||||
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
|
||||
// -------- Read input --------
|
||||
// This vector stores paths to the processed images
|
||||
std::vector<std::string> image_names;
|
||||
parseInputFilesArguments(image_names);
|
||||
if (image_names.empty())
|
||||
throw std::logic_error("No suitable images were found");
|
||||
|
||||
// -------- Step 1. Initialize OpenVINO Runtime Core --------
|
||||
ov::runtime::Core core;
|
||||
|
||||
if (!FLAGS_l.empty()) {
|
||||
// Custom CPU extension is loaded as a shared library and passed as a
|
||||
// pointer to base extension
|
||||
IExtensionPtr extension_ptr = std::make_shared<Extension>(FLAGS_l);
|
||||
ie.AddExtension(extension_ptr);
|
||||
slog::info << "CPU Extension loaded: " << FLAGS_l << slog::endl;
|
||||
auto extension_ptr = std::make_shared<InferenceEngine::Extension>(FLAGS_l);
|
||||
core.add_extension(extension_ptr);
|
||||
slog::info << "Extension loaded: " << FLAGS_l << slog::endl;
|
||||
}
|
||||
if (!FLAGS_c.empty() && (FLAGS_d == "GPU" || FLAGS_d == "MYRIAD" || FLAGS_d == "HDDL")) {
|
||||
// Config for device plugin custom extension is loaded from an .xml
|
||||
// description
|
||||
ie.SetConfig({{PluginConfigParams::KEY_CONFIG_FILE, FLAGS_c}}, FLAGS_d);
|
||||
core.set_config({{InferenceEngine::PluginConfigParams::KEY_CONFIG_FILE, FLAGS_c}}, FLAGS_d);
|
||||
slog::info << "Config for " << FLAGS_d << " device plugin custom extension loaded: " << FLAGS_c
|
||||
<< slog::endl;
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// Step 2. Read a model in OpenVINO Intermediate Representation (.xml and
|
||||
// .bin files) or ONNX (.onnx file) format
|
||||
slog::info << "Loading network files:" << slog::endl << FLAGS_m << slog::endl;
|
||||
// -------- Step 2. Read a model --------
|
||||
slog::info << "Loading model files:" << slog::endl << FLAGS_m << slog::endl;
|
||||
std::shared_ptr<ov::Function> model = core.read_model(FLAGS_m);
|
||||
|
||||
/** Read network model **/
|
||||
CNNNetwork network = ie.ReadNetwork(FLAGS_m);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
OPENVINO_ASSERT(model->get_parameters().size() == 1, "Sample supports models with 1 input only");
|
||||
OPENVINO_ASSERT(model->get_results().size() == 1, "Sample supports models with 1 output only");
|
||||
|
||||
// --------------------------- Step 3. Configure input & output
|
||||
// ---------------------------------------------
|
||||
if (network.getOutputsInfo().size() != 1)
|
||||
throw std::logic_error("Sample supports topologies with 1 output only");
|
||||
// -------- Step 3. Apply preprocessing --------
|
||||
const ov::Layout tensor_layout{"NHWC"};
|
||||
|
||||
// --------------------------- Prepare input blobs
|
||||
// -----------------------------------------------------
|
||||
slog::info << "Preparing input blobs" << slog::endl;
|
||||
// clang-format off
|
||||
model = PrePostProcessor().
|
||||
// 1) InputInfo() with no args assumes a model has a single input
|
||||
input(InputInfo().
|
||||
// 2) Set input tensor information:
|
||||
// - precision of tensor is supposed to be 'u8'
|
||||
// - layout of data is 'NHWC'
|
||||
tensor(InputTensorInfo().
|
||||
set_element_type(ov::element::u8).
|
||||
set_layout(tensor_layout)).
|
||||
// 3) Here we suppose model has 'NCHW' layout for input
|
||||
network(InputNetworkInfo().
|
||||
set_layout("NCHW"))).
|
||||
output(OutputInfo().
|
||||
// 4) Set output tensor information:
|
||||
// - precision of tensor is supposed to be 'f32'
|
||||
tensor(OutputTensorInfo().
|
||||
set_element_type(ov::element::f32))).
|
||||
// 5) Once the build() method is called, the preprocessing steps
|
||||
// for layout and precision conversions are inserted automatically
|
||||
build(model);
|
||||
// clang-format on
|
||||
|
||||
/** Taking information about all topology inputs **/
|
||||
InputsDataMap inputInfo(network.getInputsInfo());
|
||||
if (inputInfo.size() != 1)
|
||||
throw std::logic_error("Sample supports topologies with 1 input only");
|
||||
// -------- Step 4. read input images --------
|
||||
slog::info << "Read input images" << slog::endl;
|
||||
|
||||
auto inputInfoItem = *inputInfo.begin();
|
||||
ov::Shape input_shape = model->input().get_shape();
|
||||
const size_t width = input_shape[ov::layout::width(tensor_layout)];
|
||||
const size_t height = input_shape[ov::layout::height(tensor_layout)];
|
||||
|
||||
/** Specifying the precision and layout of input data provided by the user.
|
||||
* This should be called before load of the network to the device **/
|
||||
inputInfoItem.second->setPrecision(Precision::U8);
|
||||
inputInfoItem.second->setLayout(Layout::NCHW);
|
||||
|
||||
std::vector<std::shared_ptr<unsigned char>> imagesData = {};
|
||||
std::vector<std::string> validImageNames = {};
|
||||
for (const auto& i : imageNames) {
|
||||
std::vector<std::shared_ptr<unsigned char>> images_data;
|
||||
std::vector<std::string> valid_image_names;
|
||||
for (const auto& i : image_names) {
|
||||
FormatReader::ReaderPtr reader(i.c_str());
|
||||
if (reader.get() == nullptr) {
|
||||
slog::warn << "Image " + i + " cannot be read!" << slog::endl;
|
||||
continue;
|
||||
}
|
||||
/** Store image data **/
|
||||
std::shared_ptr<unsigned char> data(reader->getData(inputInfoItem.second->getTensorDesc().getDims()[3],
|
||||
inputInfoItem.second->getTensorDesc().getDims()[2]));
|
||||
// Store image data
|
||||
std::shared_ptr<unsigned char> data(reader->getData(width, height));
|
||||
if (data != nullptr) {
|
||||
imagesData.push_back(data);
|
||||
validImageNames.push_back(i);
|
||||
images_data.push_back(data);
|
||||
valid_image_names.push_back(i);
|
||||
}
|
||||
}
|
||||
if (imagesData.empty() || validImageNames.empty())
|
||||
if (images_data.empty() || valid_image_names.empty())
|
||||
throw std::logic_error("Valid input images were not found!");
|
||||
|
||||
/** Setting batch size using image count **/
|
||||
network.setBatchSize(imagesData.size());
|
||||
size_t batchSize = network.getBatchSize();
|
||||
// -------- Step 5. Loading model to the device --------
|
||||
// Setting batch size using image count
|
||||
const size_t batchSize = images_data.size();
|
||||
input_shape[ov::layout::batch(tensor_layout)] = batchSize;
|
||||
model->reshape({{model->input().get_any_name(), input_shape}});
|
||||
slog::info << "Batch size is " << std::to_string(batchSize) << slog::endl;
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// -------- Step 6. Loading model to the device --------
|
||||
slog::info << "Loading model to the device " << FLAGS_d << slog::endl;
|
||||
ov::runtime::ExecutableNetwork executable_network = core.compile_model(model, FLAGS_d);
|
||||
|
||||
// --------------------------- Step 4. Loading model to the device
|
||||
// ------------------------------------------
|
||||
slog::info << "Loading model to the device" << slog::endl;
|
||||
ExecutableNetwork executable_network = ie.LoadNetwork(network, FLAGS_d);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 5. Create infer request
|
||||
// -------------------------------------------------
|
||||
// -------- Step 6. Create infer request --------
|
||||
slog::info << "Create infer request" << slog::endl;
|
||||
InferRequest inferRequest = executable_network.CreateInferRequest();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
ov::runtime::InferRequest infer_request = executable_network.create_infer_request();
|
||||
|
||||
// --------------------------- Step 6. Prepare input
|
||||
// --------------------------------------------------------
|
||||
for (auto& item : inputInfo) {
|
||||
Blob::Ptr inputBlob = inferRequest.GetBlob(item.first);
|
||||
SizeVector dims = inputBlob->getTensorDesc().getDims();
|
||||
/** Fill input tensor with images. First b channel, then g and r channels
|
||||
* **/
|
||||
size_t num_channels = dims[1];
|
||||
size_t image_size = dims[3] * dims[2];
|
||||
// -------- Step 7. Combine multiple input images as batch --------
|
||||
ov::runtime::Tensor input_tensor = infer_request.get_input_tensor();
|
||||
|
||||
MemoryBlob::Ptr minput = as<MemoryBlob>(inputBlob);
|
||||
if (!minput) {
|
||||
slog::err << "We expect MemoryBlob from inferRequest, but by fact we "
|
||||
"were not able to cast inputBlob to MemoryBlob"
|
||||
<< slog::endl;
|
||||
return 1;
|
||||
}
|
||||
// locked memory holder should be alive all time while access to its
|
||||
// buffer happens
|
||||
auto minputHolder = minput->wmap();
|
||||
|
||||
auto data = minputHolder.as<PrecisionTrait<Precision::U8>::value_type*>();
|
||||
if (data == nullptr)
|
||||
throw std::runtime_error("Input blob has not allocated buffer");
|
||||
/** Iterate over all input images **/
|
||||
for (size_t image_id = 0; image_id < imagesData.size(); ++image_id) {
|
||||
/** Iterate over all pixel in image (b,g,r) **/
|
||||
for (size_t pid = 0; pid < image_size; pid++) {
|
||||
/** Iterate over all channels **/
|
||||
for (size_t ch = 0; ch < num_channels; ++ch) {
|
||||
/** [images stride + channels stride + pixel id ] all in
|
||||
* bytes **/
|
||||
data[image_id * image_size * num_channels + ch * image_size + pid] =
|
||||
imagesData.at(image_id).get()[pid * num_channels + ch];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t image_id = 0; image_id < images_data.size(); ++image_id) {
|
||||
const size_t image_size = shape_size(input_shape) / batchSize;
|
||||
std::memcpy(input_tensor.data<std::uint8_t>() + image_id * image_size,
|
||||
images_data[image_id].get(),
|
||||
image_size);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 7. Do inference
|
||||
// ---------------------------------------------------------
|
||||
size_t numIterations = 10;
|
||||
size_t curIteration = 0;
|
||||
// -------- Step 8. Do asynchronous inference --------
|
||||
size_t num_iterations = 10;
|
||||
size_t cur_iteration = 0;
|
||||
std::condition_variable condVar;
|
||||
|
||||
inferRequest.SetCompletionCallback([&] {
|
||||
curIteration++;
|
||||
slog::info << "Completed " << curIteration << " async request execution" << slog::endl;
|
||||
if (curIteration < numIterations) {
|
||||
infer_request.set_callback([&](std::exception_ptr ex) {
|
||||
if (ex)
|
||||
throw ex;
|
||||
|
||||
cur_iteration++;
|
||||
slog::info << "Completed " << cur_iteration << " async request execution" << slog::endl;
|
||||
if (cur_iteration < num_iterations) {
|
||||
/* here a user can read output containing inference results and put new
|
||||
input to repeat async request again */
|
||||
inferRequest.StartAsync();
|
||||
infer_request.start_async();
|
||||
} else {
|
||||
/* continue sample execution after last Asynchronous inference request
|
||||
* execution */
|
||||
@ -234,30 +200,23 @@ int main(int argc, char* argv[]) {
|
||||
});
|
||||
|
||||
/* Start async request for the first time */
|
||||
slog::info << "Start inference (" << numIterations << " asynchronous executions)" << slog::endl;
|
||||
inferRequest.StartAsync();
|
||||
slog::info << "Start inference (" << num_iterations << " asynchronous executions)" << slog::endl;
|
||||
infer_request.start_async();
|
||||
|
||||
/* Wait all repetitions of the async request */
|
||||
/* Wait all iterations of the async request */
|
||||
std::mutex mutex;
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
condVar.wait(lock, [&] {
|
||||
return curIteration == numIterations;
|
||||
return cur_iteration == num_iterations;
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 8. Process output
|
||||
// -------------------------------------------------------
|
||||
slog::info << "Processing output blobs" << slog::endl;
|
||||
OutputsDataMap outputInfo(network.getOutputsInfo());
|
||||
if (outputInfo.empty())
|
||||
throw std::runtime_error("Can't get output blobs");
|
||||
Blob::Ptr outputBlob = inferRequest.GetBlob(outputInfo.begin()->first);
|
||||
// -------- Step 9. Process output --------
|
||||
ov::runtime::Tensor output = infer_request.get_output_tensor();
|
||||
|
||||
/** Validating -nt value **/
|
||||
const size_t resultsCnt = outputBlob->size() / batchSize;
|
||||
const size_t resultsCnt = output.get_size() / batchSize;
|
||||
if (FLAGS_nt > resultsCnt || FLAGS_nt < 1) {
|
||||
slog::warn << "-nt " << FLAGS_nt << " is not available for this network (-nt should be less than "
|
||||
slog::warn << "-nt " << FLAGS_nt << " is not available for this model (-nt should be less than "
|
||||
<< resultsCnt + 1 << " and more than 0)\n Maximal value " << resultsCnt
|
||||
<< " will be used." << slog::endl;
|
||||
FLAGS_nt = resultsCnt;
|
||||
@ -276,16 +235,16 @@ int main(int argc, char* argv[]) {
|
||||
labels.push_back(strLine);
|
||||
}
|
||||
}
|
||||
|
||||
// Prints formatted classification results
|
||||
ClassificationResult classificationResult(outputBlob, validImageNames, batchSize, FLAGS_nt, labels);
|
||||
classificationResult.print();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
ClassificationResult classificationResult(output, valid_image_names, batchSize, FLAGS_nt, labels);
|
||||
classificationResult.show();
|
||||
} catch (const std::exception& error) {
|
||||
slog::err << error.what() << slog::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
slog::err << "Unknown/internal exception happened." << slog::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
slog::info << "Execution successful" << slog::endl;
|
||||
@ -293,5 +252,5 @@ int main(int argc, char* argv[]) {
|
||||
<< "This sample is an API example, for any performance measurements "
|
||||
"please use the dedicated benchmark_app tool"
|
||||
<< slog::endl;
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -9,13 +9,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <inference_engine.hpp>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "inference_engine.hpp"
|
||||
#include "openvino/openvino.hpp"
|
||||
|
||||
/**
|
||||
* @class ClassificationResult
|
||||
* @brief A ClassificationResult creates an output table with results
|
||||
@ -27,6 +29,7 @@ private:
|
||||
const std::string _probabilityStr = "probability";
|
||||
const std::string _labelStr = "label";
|
||||
size_t _nTop;
|
||||
ov::runtime::Tensor _outTensor;
|
||||
InferenceEngine::Blob::Ptr _outBlob;
|
||||
const std::vector<std::string> _labels;
|
||||
const std::vector<strType> _imageNames;
|
||||
@ -47,12 +50,41 @@ private:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the top n results from a tblob
|
||||
* @brief Gets the top n results from a tensor
|
||||
*
|
||||
* @param n Top n count
|
||||
* @param input 1D tblob that contains probabilities
|
||||
* @param input 1D tensor that contains probabilities
|
||||
* @param output Vector of indexes for the top n places
|
||||
*/
|
||||
template <class T>
|
||||
void topResults(unsigned int n, const ov::runtime::Tensor& input, std::vector<unsigned>& output) {
|
||||
ov::Shape shape = input.get_shape();
|
||||
size_t input_rank = shape.size();
|
||||
OPENVINO_ASSERT(input_rank != 0 && shape[0] != 0, "Input tensor has incorrect dimensions!");
|
||||
size_t batchSize = shape[0];
|
||||
std::vector<unsigned> indexes(input.get_size() / batchSize);
|
||||
|
||||
n = static_cast<unsigned>(std::min<size_t>((size_t)n, input.get_size()));
|
||||
output.resize(n * batchSize);
|
||||
|
||||
for (size_t i = 0; i < batchSize; i++) {
|
||||
const size_t offset = i * (input.get_size() / batchSize);
|
||||
const T* batchData = input.data<const T>();
|
||||
batchData += offset;
|
||||
|
||||
std::iota(std::begin(indexes), std::end(indexes), 0);
|
||||
std::partial_sort(std::begin(indexes),
|
||||
std::begin(indexes) + n,
|
||||
std::end(indexes),
|
||||
[&batchData](unsigned l, unsigned r) {
|
||||
return batchData[l] > batchData[r];
|
||||
});
|
||||
for (unsigned j = 0; j < n; j++) {
|
||||
output.at(i * n + j) = indexes.at(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void topResults(unsigned int n, InferenceEngine::Blob::Ptr& input, std::vector<unsigned>& output) {
|
||||
InferenceEngine::SizeVector dims = input->getTensorDesc().getDims();
|
||||
@ -97,6 +129,33 @@ private:
|
||||
* @param input 1D blob that contains probabilities
|
||||
* @param output Vector of indexes for the top n places
|
||||
*/
|
||||
void topResults(unsigned int n, const ov::runtime::Tensor& input, std::vector<unsigned>& output) {
|
||||
#define TENSOR_TOP_RESULT(elem_type) \
|
||||
case ov::element::Type_t::elem_type: { \
|
||||
using tensor_type = ov::fundamental_type_for<ov::element::Type_t::elem_type>; \
|
||||
topResults<tensor_type>(n, input, output); \
|
||||
break; \
|
||||
}
|
||||
|
||||
switch (input.get_element_type()) {
|
||||
TENSOR_TOP_RESULT(f32);
|
||||
TENSOR_TOP_RESULT(f64);
|
||||
TENSOR_TOP_RESULT(f16);
|
||||
TENSOR_TOP_RESULT(i16);
|
||||
TENSOR_TOP_RESULT(u8);
|
||||
TENSOR_TOP_RESULT(i8);
|
||||
TENSOR_TOP_RESULT(u16);
|
||||
TENSOR_TOP_RESULT(i32);
|
||||
TENSOR_TOP_RESULT(u32);
|
||||
TENSOR_TOP_RESULT(i64);
|
||||
TENSOR_TOP_RESULT(u64);
|
||||
default:
|
||||
OPENVINO_ASSERT(false, "cannot locate tensor with element type: ", input.get_element_type());
|
||||
}
|
||||
|
||||
#undef TENSOR_TOP_RESULT
|
||||
}
|
||||
|
||||
void topResults(unsigned int n, InferenceEngine::Blob::Ptr& input, std::vector<unsigned>& output) {
|
||||
#define TBLOB_TOP_RESULT(precision) \
|
||||
case InferenceEngine::Precision::precision: { \
|
||||
@ -143,9 +202,54 @@ public:
|
||||
topResults(_nTop, _outBlob, _results);
|
||||
}
|
||||
|
||||
explicit ClassificationResultT(const ov::runtime::Tensor& output_tensor,
|
||||
const std::vector<strType>& image_names = {},
|
||||
size_t batch_size = 1,
|
||||
size_t num_of_top = 10,
|
||||
const std::vector<std::string>& labels = {})
|
||||
: _nTop(num_of_top),
|
||||
_outTensor(output_tensor),
|
||||
_labels(labels),
|
||||
_imageNames(image_names),
|
||||
_batchSize(batch_size),
|
||||
_results() {
|
||||
OPENVINO_ASSERT(_imageNames.size() == _batchSize, "Batch size should be equal to the number of images.");
|
||||
|
||||
topResults(_nTop, _outTensor, _results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief prints formatted classification results
|
||||
*/
|
||||
void show() {
|
||||
/** Print the result iterating over each batch **/
|
||||
std::cout << std::endl << "Top " << _nTop << " results:" << std::endl << std::endl;
|
||||
for (unsigned int image_id = 0; image_id < _batchSize; ++image_id) {
|
||||
std::wstring out(_imageNames[image_id].begin(), _imageNames[image_id].end());
|
||||
std::wcout << L"Image " << out;
|
||||
std::wcout.flush();
|
||||
std::wcout.clear();
|
||||
std::wcout << std::endl << std::endl;
|
||||
printHeader();
|
||||
|
||||
for (size_t id = image_id * _nTop, cnt = 0; id < (image_id + 1) * _nTop; ++cnt, ++id) {
|
||||
std::cout.precision(7);
|
||||
/** Getting probability for resulting class **/
|
||||
const auto index = _results.at(id) + image_id * (_outTensor.get_size() / _batchSize);
|
||||
const auto result = _outTensor.data<const float>()[index];
|
||||
|
||||
std::cout << std::setw(static_cast<int>(_classidStr.length())) << std::left << _results.at(id) << " ";
|
||||
std::cout << std::left << std::setw(static_cast<int>(_probabilityStr.length())) << std::fixed << result;
|
||||
|
||||
if (!_labels.empty()) {
|
||||
std::cout << " " + _labels[_results.at(id)];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void print() {
|
||||
/** Print the result iterating over each batch **/
|
||||
std::cout << std::endl << "Top " << _nTop << " results:" << std::endl << std::endl;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "openvino/openvino.hpp"
|
||||
|
||||
#ifndef UNUSED
|
||||
# if defined(_MSC_VER) && !defined(__clang__)
|
||||
# define UNUSED
|
||||
@ -98,6 +100,16 @@ inline std::ostream& operator<<(std::ostream& os, const InferenceEngine::Version
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const ov::Version& version) {
|
||||
os << "\t" << version.description << " version ......... ";
|
||||
os << OPENVINO_VERSION_MAJOR << "." << OPENVINO_VERSION_MINOR << "." << OPENVINO_VERSION_PATCH;
|
||||
|
||||
os << "\n\tBuild ........... ";
|
||||
os << version.buildNumber;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const InferenceEngine::Version* version) {
|
||||
if (nullptr != version) {
|
||||
os << std::endl << *version;
|
||||
@ -114,6 +126,15 @@ inline std::ostream& operator<<(std::ostream& os, const std::map<std::string, In
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::map<std::string, ov::Version>& versions) {
|
||||
for (auto&& version : versions) {
|
||||
os << "\t" << version.first << std::endl;
|
||||
os << version.second << std::endl;
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class Color
|
||||
* @brief A Color class stores channels of a given color
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <samples/common.hpp>
|
||||
|
||||
#include "openvino/openvino.hpp"
|
||||
|
||||
/**
|
||||
* @brief Sets image data stored in cv::Mat object to a given Blob object.
|
||||
* @param orig_image - given cv::Mat object with an image data.
|
||||
@ -76,3 +78,17 @@ static UNUSED InferenceEngine::Blob::Ptr wrapMat2Blob(const cv::Mat& mat) {
|
||||
|
||||
return InferenceEngine::make_shared_blob<uint8_t>(tDesc, mat.data);
|
||||
}
|
||||
|
||||
static UNUSED ov::runtime::Tensor wrapMat2Tensor(const cv::Mat& mat) {
|
||||
const size_t channels = mat.channels();
|
||||
const size_t height = mat.size().height;
|
||||
const size_t width = mat.size().width;
|
||||
|
||||
const size_t strideH = mat.step.buf[0];
|
||||
const size_t strideW = mat.step.buf[1];
|
||||
|
||||
const bool is_dense = strideW == channels && strideH == channels * width;
|
||||
OPENVINO_ASSERT(is_dense, "Doesn't support conversion from not dense cv::Mat");
|
||||
|
||||
return ov::runtime::Tensor(ov::element::u8, ov::Shape{1, height, width, channels}, mat.data);
|
||||
}
|
||||
|
@ -2,17 +2,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <samples/classification_results.h>
|
||||
|
||||
#include <inference_engine.hpp>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <samples/common.hpp>
|
||||
#include <samples/ocv_common.hpp>
|
||||
#include <samples/slog.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace InferenceEngine;
|
||||
#include "openvino/core/layout.hpp"
|
||||
#include "openvino/openvino.hpp"
|
||||
#include "samples/classification_results.h"
|
||||
#include "samples/common.hpp"
|
||||
#include "samples/ocv_common.hpp"
|
||||
|
||||
using namespace ov::preprocess;
|
||||
|
||||
/**
|
||||
* @brief Define names based depends on Unicode path support
|
||||
@ -78,8 +80,10 @@ int wmain(int argc, wchar_t* argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
#endif
|
||||
try {
|
||||
// ------------------------------ Parsing and validation of input arguments
|
||||
// ---------------------------------
|
||||
// -------- Get OpenVINO Runtime version --------
|
||||
slog::info << "OpenVINO runtime: " << ov::get_openvino_version() << slog::endl;
|
||||
|
||||
// -------- Parsing and validation of input arguments --------
|
||||
if (argc != 4) {
|
||||
tcout << "Usage : " << argv[0] << " <path_to_model> <path_to_image> <device_name>" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
@ -92,81 +96,80 @@ int main(int argc, char* argv[]) {
|
||||
#else
|
||||
const std::string device_name{argv[3]};
|
||||
#endif
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 1. Initialize inference engine core
|
||||
// -------------------------------------
|
||||
Core ie;
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// -------- Step 1. Initialize OpenVINO Runtime Core --------
|
||||
ov::runtime::Core core;
|
||||
|
||||
// Step 2. Read a model in OpenVINO Intermediate Representation (.xml and
|
||||
// .bin files) or ONNX (.onnx file) format
|
||||
CNNNetwork network = ie.ReadNetwork(input_model);
|
||||
if (network.getOutputsInfo().size() != 1)
|
||||
throw std::logic_error("Sample supports topologies with 1 output only");
|
||||
if (network.getInputsInfo().size() != 1)
|
||||
throw std::logic_error("Sample supports topologies with 1 input only");
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// -------- Step 2. Read a model --------
|
||||
auto model = core.read_model(input_model);
|
||||
|
||||
// --------------------------- Step 3. Configure input & output
|
||||
// ---------------------------------------------
|
||||
// --------------------------- Prepare input blobs
|
||||
// -----------------------------------------------------
|
||||
InputInfo::Ptr input_info = network.getInputsInfo().begin()->second;
|
||||
std::string input_name = network.getInputsInfo().begin()->first;
|
||||
OPENVINO_ASSERT(model->get_parameters().size() == 1, "Sample supports models with 1 input only");
|
||||
OPENVINO_ASSERT(model->get_results().size() == 1, "Sample supports models with 1 output only");
|
||||
|
||||
/* Mark input as resizable by setting of a resize algorithm.
|
||||
* In this case we will be able to set an input blob of any shape to an
|
||||
* infer request. Resize and layout conversions are executed automatically
|
||||
* during inference */
|
||||
input_info->getPreProcess().setResizeAlgorithm(RESIZE_BILINEAR);
|
||||
input_info->setLayout(Layout::NHWC);
|
||||
input_info->setPrecision(Precision::U8);
|
||||
// -------- Step 3. Initialize inference engine core
|
||||
|
||||
// --------------------------- Prepare output blobs
|
||||
// ----------------------------------------------------
|
||||
if (network.getOutputsInfo().empty()) {
|
||||
std::cerr << "Network outputs info is empty" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
DataPtr output_info = network.getOutputsInfo().begin()->second;
|
||||
std::string output_name = network.getOutputsInfo().begin()->first;
|
||||
|
||||
output_info->setPrecision(Precision::FP32);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 4. Loading a model to the device
|
||||
// ------------------------------------------
|
||||
ExecutableNetwork executable_network = ie.LoadNetwork(network, device_name);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 5. Create an infer request
|
||||
// -------------------------------------------------
|
||||
InferRequest infer_request = executable_network.CreateInferRequest();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 6. Prepare input
|
||||
// --------------------------------------------------------
|
||||
/* Read input image to a blob and set it to an infer request without resize
|
||||
* and layout conversions. */
|
||||
// Read input image to a tensor and set it to an infer request
|
||||
// without resize and layout conversions
|
||||
cv::Mat image = imread_t(input_image_path);
|
||||
Blob::Ptr imgBlob = wrapMat2Blob(image); // just wrap Mat data by Blob::Ptr
|
||||
// without allocating of new memory
|
||||
infer_request.SetBlob(input_name, imgBlob); // infer_request accepts input blob of any size
|
||||
// just wrap Mat data by ov::runtime::Tensor without allocating of new memory
|
||||
ov::runtime::Tensor input_tensor = wrapMat2Tensor(image);
|
||||
const ov::Shape tensor_shape = input_tensor.get_shape();
|
||||
|
||||
// -------- Step 4. Apply preprocessing --------
|
||||
const ov::Layout tensor_layout{"NHWC"};
|
||||
|
||||
// clang-format off
|
||||
model = PrePostProcessor().
|
||||
// 1) InputInfo() with no args assumes a model has a single input
|
||||
input(InputInfo().
|
||||
// 2) Set input tensor information:
|
||||
// - precision of tensor is supposed to be 'u8'
|
||||
// - layout of data is 'NHWC'
|
||||
// - set static spatial dimensions to input tensor to resize from
|
||||
tensor(InputTensorInfo().
|
||||
set_element_type(ov::element::u8).
|
||||
set_spatial_static_shape(
|
||||
tensor_shape[ov::layout::height(tensor_layout)],
|
||||
tensor_shape[ov::layout::width(tensor_layout)]).
|
||||
set_layout(tensor_layout)).
|
||||
// 3) Adding explicit preprocessing steps:
|
||||
// - convert layout to 'NCHW' (from 'NHWC' specified above at tensor layout)
|
||||
// - apply linear resize from tensor spatial dims to model spatial dims
|
||||
preprocess(PreProcessSteps().
|
||||
convert_element_type(ov::element::f32). // WA for CPU plugin
|
||||
convert_layout("NCHW"). // WA for CPU plugin
|
||||
resize(ResizeAlgorithm::RESIZE_LINEAR)).
|
||||
// 4) Here we suppose model has 'NCHW' layout for input
|
||||
network(InputNetworkInfo().
|
||||
set_layout("NCHW"))).
|
||||
output(OutputInfo().
|
||||
// 5) Set output tensor information:
|
||||
// - precision of tensor is supposed to be 'f32'
|
||||
tensor(OutputTensorInfo().
|
||||
set_element_type(ov::element::f32))).
|
||||
// 6) Apply preprocessing modifing the original 'model'
|
||||
build(model);
|
||||
// clang-format on
|
||||
|
||||
// -------- Step 5. Loading a model to the device --------
|
||||
ov::runtime::ExecutableNetwork executable_network = core.compile_model(model, device_name);
|
||||
|
||||
// -------- Step 6. Create an infer request --------
|
||||
ov::runtime::InferRequest infer_request = executable_network.create_infer_request();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 7. Do inference
|
||||
// --------------------------------------------------------
|
||||
/* Running the request synchronously */
|
||||
infer_request.Infer();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// -------- Step 7. Prepare input --------
|
||||
infer_request.set_input_tensor(input_tensor);
|
||||
|
||||
// -------- Step 8. Do inference synchronously --------
|
||||
infer_request.infer();
|
||||
|
||||
// -------- Step 9. Process output
|
||||
ov::runtime::Tensor output_tensor = infer_request.get_output_tensor();
|
||||
|
||||
// --------------------------- Step 8. Process output
|
||||
// ------------------------------------------------------
|
||||
Blob::Ptr output = infer_request.GetBlob(output_name);
|
||||
// Print classification results
|
||||
ClassificationResult_t classificationResult(output, {input_image_path});
|
||||
classificationResult.print();
|
||||
ClassificationResult_t classification_result(output_tensor, {input_image_path});
|
||||
classification_result.show();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
} catch (const std::exception& ex) {
|
||||
std::cerr << ex.what() << std::endl;
|
||||
|
@ -3,8 +3,6 @@
|
||||
//
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ie_plugin_config.hpp>
|
||||
#include <inference_engine.hpp>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <samples/common.hpp>
|
||||
@ -13,7 +11,8 @@
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
using namespace InferenceEngine;
|
||||
#include "ie_plugin_config.hpp"
|
||||
#include "openvino/openvino.hpp"
|
||||
|
||||
namespace {
|
||||
/**
|
||||
@ -33,7 +32,7 @@ std::ostream& operator<<(std::ostream& stream, const std::vector<T>& v) {
|
||||
* @param reference on IE Parameter
|
||||
* @return void
|
||||
*/
|
||||
void printParameterValue(const Parameter& value) {
|
||||
void printParameterValue(const ov::runtime::Parameter& value) {
|
||||
if (value.empty()) {
|
||||
std::cout << "EMPTY VALUE" << std::endl;
|
||||
} else if (value.is<bool>()) {
|
||||
@ -65,8 +64,8 @@ void printParameterValue(const Parameter& value) {
|
||||
std::cout << std::get<2>(values);
|
||||
std::cout << " }";
|
||||
std::cout << std::endl;
|
||||
} else if (value.is<Metrics::DeviceType>()) {
|
||||
auto v = value.as<Metrics::DeviceType>();
|
||||
} else if (value.is<InferenceEngine::Metrics::DeviceType>()) {
|
||||
auto v = value.as<InferenceEngine::Metrics::DeviceType>();
|
||||
std::cout << v << std::endl;
|
||||
} else if (value.is<std::map<InferenceEngine::Precision, float>>()) {
|
||||
auto values = value.as<std::map<InferenceEngine::Precision, float>>();
|
||||
@ -92,46 +91,45 @@ void printParameterValue(const Parameter& value) {
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
// ------------------------------ Parsing and validation of input arguments
|
||||
// ---------------------------------
|
||||
// -------- Parsing and validation of input arguments --------
|
||||
if (argc != 1) {
|
||||
std::cout << "Usage : " << argv[0] << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// --------------------------- Step 1. Initialize inference engine core
|
||||
// -------------------------------------
|
||||
std::cout << "Loading Inference Engine" << std::endl;
|
||||
Core ie;
|
||||
// -------- Step 1. Initialize OpenVINO Runtime Core --------
|
||||
std::cout << "Loading OpenVINO Runtime" << std::endl;
|
||||
ov::runtime::Core core;
|
||||
|
||||
// --------------------------- Get list of available devices
|
||||
// -------------------------------------
|
||||
// -------- Step 2. Get list of available devices --------
|
||||
|
||||
std::vector<std::string> availableDevices = ie.GetAvailableDevices();
|
||||
std::vector<std::string> availableDevices = core.get_available_devices();
|
||||
|
||||
// --------------------------- Query and print supported metrics and config
|
||||
// keys--------------------
|
||||
// -------- Step 3. Query and print supported metrics and config keys --------
|
||||
|
||||
std::cout << "Available devices: " << std::endl;
|
||||
for (auto&& device : availableDevices) {
|
||||
std::cout << device << std::endl;
|
||||
|
||||
// Query supported metrics and print all of them
|
||||
std::cout << "\tSUPPORTED_METRICS: " << std::endl;
|
||||
std::vector<std::string> supportedMetrics = ie.GetMetric(device, METRIC_KEY(SUPPORTED_METRICS));
|
||||
std::vector<std::string> supportedMetrics = core.get_metric(device, METRIC_KEY(SUPPORTED_METRICS));
|
||||
for (auto&& metricName : supportedMetrics) {
|
||||
if (metricName != METRIC_KEY(SUPPORTED_METRICS) && metricName != METRIC_KEY(SUPPORTED_CONFIG_KEYS)) {
|
||||
std::cout << "\t\t" << metricName << " : " << std::flush;
|
||||
printParameterValue(ie.GetMetric(device, metricName));
|
||||
printParameterValue(core.get_metric(device, metricName));
|
||||
}
|
||||
}
|
||||
|
||||
// Query supported config keys and print all of them
|
||||
if (std::find(supportedMetrics.begin(), supportedMetrics.end(), METRIC_KEY(SUPPORTED_CONFIG_KEYS)) !=
|
||||
supportedMetrics.end()) {
|
||||
std::cout << "\tSUPPORTED_CONFIG_KEYS (default values): " << std::endl;
|
||||
std::vector<std::string> supportedConfigKeys = ie.GetMetric(device, METRIC_KEY(SUPPORTED_CONFIG_KEYS));
|
||||
std::vector<std::string> supportedConfigKeys =
|
||||
core.get_metric(device, METRIC_KEY(SUPPORTED_CONFIG_KEYS));
|
||||
for (auto&& configKey : supportedConfigKeys) {
|
||||
std::cout << "\t\t" << configKey << " : " << std::flush;
|
||||
printParameterValue(ie.GetConfig(device, configKey));
|
||||
printParameterValue(core.get_config(device, configKey));
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,5 +139,6 @@ int main(int argc, char* argv[]) {
|
||||
std::cerr << std::endl << "Exception occurred: " << ex.what() << std::endl << std::flush;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -2,24 +2,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <format_reader_ptr.h>
|
||||
#include <gflags/gflags.h>
|
||||
#include <samples/classification_results.h>
|
||||
|
||||
#include <inference_engine.hpp>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <samples/args_helper.hpp>
|
||||
#include <samples/common.hpp>
|
||||
#include <samples/slog.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "format_reader_ptr.h"
|
||||
#include "gflags/gflags.h"
|
||||
#include "ngraph/util.hpp"
|
||||
#include "ngraph_function_creation_sample.hpp"
|
||||
#include "openvino/openvino.hpp"
|
||||
#include "openvino/opsets/opset8.hpp"
|
||||
#include "samples/args_helper.hpp"
|
||||
#include "samples/classification_results.h"
|
||||
#include "samples/common.hpp"
|
||||
#include "samples/slog.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace ngraph;
|
||||
using namespace ov;
|
||||
|
||||
/**
|
||||
* @brief Checks input args
|
||||
@ -64,19 +66,19 @@ bool ParseAndCheckCommandLine(int argc, char* argv[]) {
|
||||
* @return none
|
||||
*/
|
||||
void readFile(const std::string& file_name, void* buffer, size_t maxSize) {
|
||||
std::ifstream inputFile;
|
||||
std::ifstream input_file;
|
||||
|
||||
inputFile.open(file_name, std::ios::binary | std::ios::in);
|
||||
if (!inputFile.is_open()) {
|
||||
input_file.open(file_name, std::ios::binary | std::ios::in);
|
||||
if (!input_file.is_open()) {
|
||||
throw std::logic_error("Cannot open weights file");
|
||||
}
|
||||
|
||||
if (!inputFile.read(reinterpret_cast<char*>(buffer), maxSize)) {
|
||||
inputFile.close();
|
||||
if (!input_file.read(reinterpret_cast<char*>(buffer), maxSize)) {
|
||||
input_file.close();
|
||||
throw std::logic_error("Cannot read bytes from weights file");
|
||||
}
|
||||
|
||||
inputFile.close();
|
||||
input_file.close();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -84,252 +86,222 @@ void readFile(const std::string& file_name, void* buffer, size_t maxSize) {
|
||||
* @param filepath string
|
||||
* @return weightsPtr tensor blob
|
||||
*/
|
||||
TBlob<uint8_t>::CPtr ReadWeights(std::string filepath) {
|
||||
ov::runtime::Tensor ReadWeights(const std::string& filepath) {
|
||||
std::ifstream weightFile(filepath, std::ifstream::ate | std::ifstream::binary);
|
||||
|
||||
int64_t fileSize = weightFile.tellg();
|
||||
OPENVINO_ASSERT(fileSize == 1724336,
|
||||
"Incorrect weights file. This sample works only with LeNet "
|
||||
"classification model.");
|
||||
|
||||
if (fileSize < 0) {
|
||||
throw std::logic_error("Incorrect weights file");
|
||||
}
|
||||
ov::runtime::Tensor weights(ov::element::u8, {static_cast<size_t>(fileSize)});
|
||||
readFile(filepath, weights.data(), weights.get_byte_size());
|
||||
|
||||
size_t ulFileSize = static_cast<size_t>(fileSize);
|
||||
|
||||
TBlob<uint8_t>::Ptr weightsPtr(new TBlob<uint8_t>({Precision::FP32, {ulFileSize}, Layout::C}));
|
||||
weightsPtr->allocate();
|
||||
readFile(filepath, weightsPtr->buffer(), ulFileSize);
|
||||
|
||||
return weightsPtr;
|
||||
return std::move(weights);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create ngraph function
|
||||
* @return Ptr to ngraph function
|
||||
*/
|
||||
std::shared_ptr<Function> createNgraphFunction() {
|
||||
TBlob<uint8_t>::CPtr weightsPtr = ReadWeights(FLAGS_m);
|
||||
|
||||
if (weightsPtr->byteSize() != 6897344)
|
||||
IE_THROW() << "Incorrect weights file. This sample works only with LeNet "
|
||||
"classification network.";
|
||||
std::shared_ptr<ov::Function> createNgraphFunction() {
|
||||
auto weights = ReadWeights(FLAGS_m);
|
||||
const std::uint8_t* data = weights.data<std::uint8_t>();
|
||||
|
||||
// -------input------
|
||||
std::vector<ptrdiff_t> padBegin{0, 0};
|
||||
std::vector<ptrdiff_t> padEnd{0, 0};
|
||||
|
||||
auto paramNode = std::make_shared<op::Parameter>(element::Type_t::f32, Shape(std::vector<size_t>{{64, 1, 28, 28}}));
|
||||
paramNode->set_friendly_name("Parameter");
|
||||
auto paramNode = std::make_shared<ov::opset8::Parameter>(ov::element::Type_t::f32, ov::Shape({64, 1, 28, 28}));
|
||||
|
||||
// -------convolution 1----
|
||||
auto convFirstShape = Shape{20, 1, 5, 5};
|
||||
std::shared_ptr<Node> convolutionFirstConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32, convFirstShape, weightsPtr->cbuffer().as<uint8_t*>());
|
||||
auto convolutionFirstConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, convFirstShape, data);
|
||||
|
||||
std::shared_ptr<Node> convolutionNodeFirst =
|
||||
std::make_shared<op::v1::Convolution>(paramNode->output(0),
|
||||
convolutionFirstConstantNode->output(0),
|
||||
Strides(SizeVector{1, 1}),
|
||||
CoordinateDiff(padBegin),
|
||||
CoordinateDiff(padEnd),
|
||||
Strides(SizeVector{1, 1}));
|
||||
auto convolutionNodeFirst = std::make_shared<opset8::Convolution>(paramNode->output(0),
|
||||
convolutionFirstConstantNode->output(0),
|
||||
Strides({1, 1}),
|
||||
CoordinateDiff(padBegin),
|
||||
CoordinateDiff(padEnd),
|
||||
Strides({1, 1}));
|
||||
|
||||
// -------Add--------------
|
||||
auto addFirstShape = Shape{1, 20, 1, 1};
|
||||
auto offset = shape_size(convFirstShape) * sizeof(float);
|
||||
std::shared_ptr<Node> addFirstConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
addFirstShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto addFirstConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, addFirstShape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> addNodeFirst =
|
||||
std::make_shared<op::v1::Add>(convolutionNodeFirst->output(0), addFirstConstantNode->output(0));
|
||||
auto addNodeFirst = std::make_shared<opset8::Add>(convolutionNodeFirst->output(0), addFirstConstantNode->output(0));
|
||||
|
||||
// -------MAXPOOL----------
|
||||
Shape padBeginShape{0, 0};
|
||||
Shape padEndShape{0, 0};
|
||||
|
||||
std::shared_ptr<Node> maxPoolingNodeFirst = std::make_shared<op::v1::MaxPool>(addNodeFirst->output(0),
|
||||
std::vector<size_t>{2, 2},
|
||||
padBeginShape,
|
||||
padEndShape,
|
||||
std::vector<size_t>{2, 2},
|
||||
op::RoundingType::CEIL,
|
||||
op::PadType::EXPLICIT);
|
||||
auto maxPoolingNodeFirst = std::make_shared<op::v1::MaxPool>(addNodeFirst->output(0),
|
||||
Strides{2, 2},
|
||||
padBeginShape,
|
||||
padEndShape,
|
||||
Shape{2, 2},
|
||||
op::RoundingType::CEIL);
|
||||
|
||||
// -------convolution 2----
|
||||
auto convSecondShape = Shape{50, 20, 5, 5};
|
||||
offset += shape_size(addFirstShape) * sizeof(float);
|
||||
std::shared_ptr<Node> convolutionSecondConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
convSecondShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto convolutionSecondConstantNode =
|
||||
std::make_shared<opset8::Constant>(element::Type_t::f32, convSecondShape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> convolutionNodeSecond =
|
||||
std::make_shared<op::v1::Convolution>(maxPoolingNodeFirst->output(0),
|
||||
convolutionSecondConstantNode->output(0),
|
||||
Strides({1, 1}),
|
||||
CoordinateDiff(padBegin),
|
||||
CoordinateDiff(padEnd),
|
||||
Strides({1, 1}));
|
||||
auto convolutionNodeSecond = std::make_shared<opset8::Convolution>(maxPoolingNodeFirst->output(0),
|
||||
convolutionSecondConstantNode->output(0),
|
||||
Strides({1, 1}),
|
||||
CoordinateDiff(padBegin),
|
||||
CoordinateDiff(padEnd),
|
||||
Strides({1, 1}));
|
||||
|
||||
// -------Add 2------------
|
||||
auto addSecondShape = Shape{1, 50, 1, 1};
|
||||
offset += shape_size(convSecondShape) * sizeof(float);
|
||||
std::shared_ptr<Node> addSecondConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
addSecondShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto addSecondConstantNode =
|
||||
std::make_shared<opset8::Constant>(element::Type_t::f32, addSecondShape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> addNodeSecond =
|
||||
std::make_shared<op::v1::Add>(convolutionNodeSecond->output(0), addSecondConstantNode->output(0));
|
||||
auto addNodeSecond =
|
||||
std::make_shared<opset8::Add>(convolutionNodeSecond->output(0), addSecondConstantNode->output(0));
|
||||
|
||||
// -------MAXPOOL 2--------
|
||||
std::shared_ptr<Node> maxPoolingNodeSecond = std::make_shared<op::v1::MaxPool>(addNodeSecond->output(0),
|
||||
Strides{2, 2},
|
||||
padBeginShape,
|
||||
padEndShape,
|
||||
Shape{2, 2},
|
||||
op::RoundingType::CEIL,
|
||||
op::PadType::EXPLICIT);
|
||||
auto maxPoolingNodeSecond = std::make_shared<op::v1::MaxPool>(addNodeSecond->output(0),
|
||||
Strides{2, 2},
|
||||
padBeginShape,
|
||||
padEndShape,
|
||||
Shape{2, 2},
|
||||
op::RoundingType::CEIL);
|
||||
|
||||
// -------Reshape----------
|
||||
auto reshapeFirstShape = Shape{2};
|
||||
auto reshapeOffset = shape_size(addSecondShape) * sizeof(float) + offset;
|
||||
std::shared_ptr<Node> reshapeFirstConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::i64,
|
||||
reshapeFirstShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + reshapeOffset));
|
||||
auto reshapeFirstConstantNode =
|
||||
std::make_shared<opset8::Constant>(element::Type_t::i64, reshapeFirstShape, data + reshapeOffset);
|
||||
|
||||
std::shared_ptr<Node> reshapeFirstNode =
|
||||
auto reshapeFirstNode =
|
||||
std::make_shared<op::v1::Reshape>(maxPoolingNodeSecond->output(0), reshapeFirstConstantNode->output(0), true);
|
||||
|
||||
// -------MatMul 1---------
|
||||
auto matMulFirstShape = Shape{500, 800};
|
||||
offset = shape_size(reshapeFirstShape) * sizeof(int64_t) + reshapeOffset;
|
||||
std::shared_ptr<Node> matMulFirstConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
matMulFirstShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto matMulFirstConstantNode =
|
||||
std::make_shared<opset8::Constant>(element::Type_t::f32, matMulFirstShape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> matMulFirstNode =
|
||||
std::make_shared<op::MatMul>(reshapeFirstNode->output(0), matMulFirstConstantNode->output(0), false, true);
|
||||
auto matMulFirstNode =
|
||||
std::make_shared<opset8::MatMul>(reshapeFirstNode->output(0), matMulFirstConstantNode->output(0), false, true);
|
||||
|
||||
// -------Add 3------------
|
||||
auto addThirdShape = Shape{1, 500};
|
||||
offset += shape_size(matMulFirstShape) * sizeof(float);
|
||||
std::shared_ptr<Node> addThirdConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
addThirdShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto addThirdConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, addThirdShape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> addThirdNode =
|
||||
std::make_shared<op::v1::Add>(matMulFirstNode->output(0), addThirdConstantNode->output(0));
|
||||
auto addThirdNode = std::make_shared<opset8::Add>(matMulFirstNode->output(0), addThirdConstantNode->output(0));
|
||||
|
||||
// -------Relu-------------
|
||||
std::shared_ptr<Node> reluNode = std::make_shared<op::Relu>(addThirdNode->output(0));
|
||||
auto reluNode = std::make_shared<opset8::Relu>(addThirdNode->output(0));
|
||||
|
||||
// -------Reshape 2--------
|
||||
auto reshapeSecondShape = Shape{2};
|
||||
std::shared_ptr<Node> reshapeSecondConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::i64,
|
||||
reshapeSecondShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + reshapeOffset));
|
||||
auto reshapeSecondConstantNode =
|
||||
std::make_shared<opset8::Constant>(element::Type_t::i64, reshapeSecondShape, data + reshapeOffset);
|
||||
|
||||
std::shared_ptr<Node> reshapeSecondNode =
|
||||
auto reshapeSecondNode =
|
||||
std::make_shared<op::v1::Reshape>(reluNode->output(0), reshapeSecondConstantNode->output(0), true);
|
||||
|
||||
// -------MatMul 2---------
|
||||
auto matMulSecondShape = Shape{10, 500};
|
||||
offset += shape_size(addThirdShape) * sizeof(float);
|
||||
std::shared_ptr<Node> matMulSecondConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
matMulSecondShape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto matMulSecondConstantNode =
|
||||
std::make_shared<opset8::Constant>(element::Type_t::f32, matMulSecondShape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> matMulSecondNode =
|
||||
std::make_shared<op::MatMul>(reshapeSecondNode->output(0), matMulSecondConstantNode->output(0), false, true);
|
||||
auto matMulSecondNode = std::make_shared<opset8::MatMul>(reshapeSecondNode->output(0),
|
||||
matMulSecondConstantNode->output(0),
|
||||
false,
|
||||
true);
|
||||
|
||||
// -------Add 4------------
|
||||
auto add4Shape = Shape{1, 10};
|
||||
offset += shape_size(matMulSecondShape) * sizeof(float);
|
||||
std::shared_ptr<Node> add4ConstantNode =
|
||||
std::make_shared<op::Constant>(element::Type_t::f32,
|
||||
add4Shape,
|
||||
(weightsPtr->cbuffer().as<uint8_t*>() + offset));
|
||||
auto add4ConstantNode = std::make_shared<opset8::Constant>(element::Type_t::f32, add4Shape, data + offset);
|
||||
|
||||
std::shared_ptr<Node> add4Node =
|
||||
std::make_shared<op::v1::Add>(matMulSecondNode->output(0), add4ConstantNode->output(0));
|
||||
auto add4Node = std::make_shared<opset8::Add>(matMulSecondNode->output(0), add4ConstantNode->output(0));
|
||||
|
||||
// -------softMax----------
|
||||
std::shared_ptr<Node> softMaxNode = std::make_shared<op::v1::Softmax>(add4Node->output(0), 1);
|
||||
auto softMaxNode = std::make_shared<opset8::Softmax>(add4Node->output(0), 1);
|
||||
softMaxNode->get_output_tensor(0).set_names({"output_tensor"});
|
||||
|
||||
// -------ngraph function--
|
||||
auto result_full = std::make_shared<op::Result>(softMaxNode->output(0));
|
||||
// ------- OpenVINO function--
|
||||
auto result_full = std::make_shared<opset8::Result>(softMaxNode->output(0));
|
||||
|
||||
std::shared_ptr<ngraph::Function> fnPtr =
|
||||
std::make_shared<ngraph::Function>(result_full, ngraph::ParameterVector{paramNode}, "lenet");
|
||||
std::shared_ptr<ov::Function> fnPtr =
|
||||
std::make_shared<ov::Function>(result_full, ov::ParameterVector{paramNode}, "lenet");
|
||||
|
||||
return fnPtr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The entry point for inference engine automatic ngraph function
|
||||
* @brief The entry point for inference engine automatic ov::Function
|
||||
* creation sample
|
||||
* @file ngraph_function_creation_sample/main.cpp
|
||||
* @example ngraph_function_creation_sample/main.cpp
|
||||
*/
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
// ------------------------------ Get Inference Engine version
|
||||
// ------------------------------------------------------
|
||||
slog::info << "InferenceEngine: " << GetInferenceEngineVersion() << slog::endl;
|
||||
// ------------------------------ Parsing and validation of input arguments
|
||||
// ---------------------------------
|
||||
// -------- Get OpenVINO runtime version --------
|
||||
slog::info << "OpenVINO Runtime: " << ov::get_openvino_version() << slog::endl;
|
||||
|
||||
// -------- Parsing and validation of input arguments --------
|
||||
if (!ParseAndCheckCommandLine(argc, argv)) {
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// ------------------------------ Read input
|
||||
// -----------------------------------------------------------
|
||||
/** This vector stores paths to the processed images **/
|
||||
|
||||
// -------- Read input --------
|
||||
std::vector<std::string> images;
|
||||
parseInputFilesArguments(images);
|
||||
if (images.empty()) {
|
||||
throw std::logic_error("No suitable images were found");
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
OPENVINO_ASSERT(!images.empty(), "No suitable images were found");
|
||||
|
||||
// -------- Step 1. Initialize OpenVINO Runtime Core object --------
|
||||
slog::info << "Loading OpenVINO runtime" << slog::endl;
|
||||
runtime::Core core;
|
||||
|
||||
// --------------------------- Step 1. Initialize inference engine core
|
||||
// -------------------------------------
|
||||
slog::info << "Loading Inference Engine" << slog::endl;
|
||||
Core ie;
|
||||
// ------------------------------ Get Available Devices
|
||||
// ------------------------------------------------------
|
||||
slog::info << "Device info: " << slog::endl;
|
||||
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
std::cout << core.get_versions(FLAGS_d) << std::endl;
|
||||
|
||||
//--------------------------- Step 2. Create network using ngraph function
|
||||
//-----------------------------------
|
||||
// -------- Step 2. Create network using ov::Function --------
|
||||
|
||||
CNNNetwork network(createNgraphFunction());
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
auto model = createNgraphFunction();
|
||||
|
||||
// --------------------------- Step 3. Configure input & output
|
||||
// ---------------------------------------------
|
||||
// --------------------------- Prepare input blobs
|
||||
// -----------------------------------------------------
|
||||
slog::info << "Preparing input blobs" << slog::endl;
|
||||
// -------- Step 3. Apply preprocessing --------
|
||||
const Layout tensor_layout{"NHWC"};
|
||||
|
||||
InputsDataMap inputInfo = network.getInputsInfo();
|
||||
if (inputInfo.size() != 1) {
|
||||
throw std::logic_error("Sample supports topologies only with 1 input");
|
||||
}
|
||||
// apply preprocessing
|
||||
// clang-format off
|
||||
using namespace ov::preprocess;
|
||||
model = PrePostProcessor()
|
||||
// 1) InputInfo() with no args assumes a model has a single input
|
||||
.input(InputInfo()
|
||||
// 2) Set input tensor information:
|
||||
// - precision of tensor is supposed to be 'u8'
|
||||
// - layout of data is 'NHWC'
|
||||
.tensor(InputTensorInfo()
|
||||
.set_layout(tensor_layout)
|
||||
.set_element_type(element::u8))
|
||||
// 3) Here we suppose model has 'NCHW' layout for input
|
||||
.network(InputNetworkInfo()
|
||||
.set_layout("NCHW")))
|
||||
// 4) Once the build() method is called, the preprocessing steps
|
||||
// for layout and precision conversions are inserted automatically
|
||||
.build(model);
|
||||
// clang-format on
|
||||
|
||||
auto inputInfoItem = *inputInfo.begin();
|
||||
// -------- Step 4. Read input images --------
|
||||
|
||||
/** Specifying the precision and layout of input data provided by the user.
|
||||
* Call this before loading the network to the device **/
|
||||
inputInfoItem.second->setPrecision(Precision::FP32);
|
||||
inputInfoItem.second->setLayout(Layout::NCHW);
|
||||
const auto input = model->input();
|
||||
|
||||
auto input_shape = input.get_shape();
|
||||
const size_t width = input_shape[layout::width(tensor_layout)];
|
||||
const size_t height = input_shape[layout::height(tensor_layout)];
|
||||
|
||||
std::vector<std::shared_ptr<unsigned char>> imagesData;
|
||||
for (auto& i : images) {
|
||||
@ -339,156 +311,95 @@ int main(int argc, char* argv[]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reader->size() != inputInfoItem.second->getTensorDesc().getDims()[2] *
|
||||
inputInfoItem.second->getTensorDesc().getDims()[3]) {
|
||||
if (reader->size() != width * height) {
|
||||
throw std::logic_error("Not supported format. Only MNist ubyte images supported.");
|
||||
}
|
||||
|
||||
/** Store image data **/
|
||||
std::shared_ptr<unsigned char> data(reader->getData(inputInfoItem.second->getTensorDesc().getDims()[3],
|
||||
inputInfoItem.second->getTensorDesc().getDims()[2]));
|
||||
// Store image data
|
||||
std::shared_ptr<unsigned char> data(reader->getData(width, height));
|
||||
if (data.get() != nullptr) {
|
||||
imagesData.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
if (imagesData.empty()) {
|
||||
throw std::logic_error("Valid input images were not found");
|
||||
}
|
||||
OPENVINO_ASSERT(!imagesData.empty(), "Valid input images were not found");
|
||||
|
||||
/** Setting batch size using image count **/
|
||||
network.setBatchSize(imagesData.size());
|
||||
size_t batchSize = network.getBatchSize();
|
||||
slog::info << "Batch size is " << std::to_string(batchSize) << slog::endl;
|
||||
// -------- Step 4. Reshape a model --------
|
||||
// Setting batch size using image count
|
||||
const size_t batch_size = imagesData.size();
|
||||
input_shape[layout::batch(tensor_layout)] = batch_size;
|
||||
model->reshape({{input.get_any_name(), input_shape}});
|
||||
slog::info << "Batch size is " << std::to_string(batch_size) << slog::endl;
|
||||
|
||||
// --------------------------- Prepare output blobs
|
||||
// -----------------------------------------------------
|
||||
slog::info << "Checking that the outputs are as the sample expects" << slog::endl;
|
||||
OutputsDataMap outputInfo(network.getOutputsInfo());
|
||||
std::string firstOutputName;
|
||||
const auto outputShape = model->output().get_shape();
|
||||
OPENVINO_ASSERT(outputShape.size() == 2, "Incorrect output dimensions for LeNet");
|
||||
|
||||
for (auto& item : outputInfo) {
|
||||
if (firstOutputName.empty()) {
|
||||
firstOutputName = item.first;
|
||||
}
|
||||
DataPtr outputData = item.second;
|
||||
if (!outputData) {
|
||||
throw std::logic_error("Output data pointer is not valid");
|
||||
}
|
||||
const auto classCount = outputShape[1];
|
||||
OPENVINO_ASSERT(classCount <= 10, "Incorrect number of output classes for LeNet model");
|
||||
|
||||
item.second->setPrecision(Precision::FP32);
|
||||
}
|
||||
// -------- Step 4. Compiling model for the device --------
|
||||
slog::info << "Compiling a model for the " << FLAGS_d << " device" << slog::endl;
|
||||
runtime::ExecutableNetwork exeNetwork = core.compile_model(model, FLAGS_d);
|
||||
|
||||
if (outputInfo.size() != 1) {
|
||||
throw std::logic_error("This demo accepts networks with a single output");
|
||||
}
|
||||
|
||||
DataPtr& output = outputInfo.begin()->second;
|
||||
auto outputName = outputInfo.begin()->first;
|
||||
|
||||
const SizeVector outputDims = output->getTensorDesc().getDims();
|
||||
const int classCount = outputDims[1];
|
||||
|
||||
if (classCount > 10) {
|
||||
throw std::logic_error("Incorrect number of output classes for LeNet network");
|
||||
}
|
||||
|
||||
if (outputDims.size() != 2) {
|
||||
throw std::logic_error("Incorrect output dimensions for LeNet");
|
||||
}
|
||||
output->setPrecision(Precision::FP32);
|
||||
output->setLayout(Layout::NC);
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 4. Loading model to the device
|
||||
// ------------------------------------------
|
||||
slog::info << "Loading model to the device" << slog::endl;
|
||||
ExecutableNetwork exeNetwork = ie.LoadNetwork(network, FLAGS_d);
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 5. Create infer request
|
||||
// -------------------------------------------------
|
||||
// -------- Step 5. Create infer request --------
|
||||
slog::info << "Create infer request" << slog::endl;
|
||||
InferRequest infer_request = exeNetwork.CreateInferRequest();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
runtime::InferRequest infer_request = exeNetwork.create_infer_request();
|
||||
|
||||
// --------------------------- Step 6. Prepare input
|
||||
// --------------------------------------------------------
|
||||
/** Iterate over all the input blobs **/
|
||||
for (const auto& item : inputInfo) {
|
||||
/** Creating input blob **/
|
||||
Blob::Ptr input = infer_request.GetBlob(item.first);
|
||||
// -------- Step 6. Combine multiple input images as batch --------
|
||||
slog::info << "Combining a batch and set input tensor" << slog::endl;
|
||||
runtime::Tensor input_tensor = infer_request.get_input_tensor();
|
||||
|
||||
/** Filling input tensor with images. First b channel, then g and r
|
||||
* channels **/
|
||||
size_t num_channels = input->getTensorDesc().getDims()[1];
|
||||
size_t image_size = input->getTensorDesc().getDims()[2] * input->getTensorDesc().getDims()[3];
|
||||
|
||||
auto data = input->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
|
||||
|
||||
/** Iterate over all input images **/
|
||||
for (size_t image_id = 0; image_id < imagesData.size(); ++image_id) {
|
||||
/** Iterate over all pixels in image (b,g,r) **/
|
||||
for (size_t pid = 0; pid < image_size; pid++) {
|
||||
/** Iterate over all channels **/
|
||||
for (size_t ch = 0; ch < num_channels; ++ch) {
|
||||
/** [images stride + channels stride + pixel id ] all in
|
||||
* bytes **/
|
||||
data[image_id * image_size * num_channels + ch * image_size + pid] =
|
||||
imagesData.at(image_id).get()[pid * num_channels + ch];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Iterate over all input images
|
||||
for (size_t image_id = 0; image_id < imagesData.size(); ++image_id) {
|
||||
const size_t image_size = shape_size(input_shape) / batch_size;
|
||||
std::memcpy(input_tensor.data<std::uint8_t>() + image_id * image_size,
|
||||
imagesData[image_id].get(),
|
||||
image_size);
|
||||
}
|
||||
inputInfo = {};
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------------- Step 7. Do inference
|
||||
// ---------------------------------------------------------
|
||||
slog::info << "Start inference" << slog::endl;
|
||||
infer_request.Infer();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
// -------- Step 7. Do sync inference --------
|
||||
slog::info << "Start sync inference" << slog::endl;
|
||||
infer_request.infer();
|
||||
|
||||
// --------------------------- Step 8. Process output
|
||||
// -------------------------------------------------------
|
||||
slog::info << "Processing output blobs" << slog::endl;
|
||||
// -------- Step 8. Process output --------
|
||||
slog::info << "Processing output tensor" << slog::endl;
|
||||
const runtime::Tensor output_tensor = infer_request.get_output_tensor();
|
||||
|
||||
const Blob::Ptr outputBlob = infer_request.GetBlob(firstOutputName);
|
||||
|
||||
/** Validating -nt value **/
|
||||
const size_t resultsCnt = outputBlob->size() / batchSize;
|
||||
if (FLAGS_nt > resultsCnt || FLAGS_nt < 1) {
|
||||
slog::warn << "-nt " << FLAGS_nt << " is not available for this network (-nt should be less than "
|
||||
<< resultsCnt + 1 << " and more than 0).\n Maximal value " << resultsCnt
|
||||
// Validating -nt value
|
||||
const size_t results_cnt = output_tensor.get_size() / batch_size;
|
||||
if (FLAGS_nt > results_cnt || FLAGS_nt < 1) {
|
||||
slog::warn << "-nt " << FLAGS_nt << " is not available for this model (-nt should be less than "
|
||||
<< results_cnt + 1 << " and more than 0).\n Maximal value " << results_cnt
|
||||
<< " will be used.";
|
||||
FLAGS_nt = resultsCnt;
|
||||
FLAGS_nt = results_cnt;
|
||||
}
|
||||
|
||||
/** Read labels from file (e.x. LeNet.labels) **/
|
||||
std::string labelFileName = fileNameNoExt(FLAGS_m) + ".labels";
|
||||
// Read labels from file (e.x. LeNet.labels) **/
|
||||
std::string label_file_name = fileNameNoExt(FLAGS_m) + ".labels";
|
||||
std::vector<std::string> labels;
|
||||
|
||||
std::ifstream inputFile;
|
||||
inputFile.open(labelFileName, std::ios::in);
|
||||
if (inputFile.is_open()) {
|
||||
std::ifstream input_file;
|
||||
input_file.open(label_file_name, std::ios::in);
|
||||
if (input_file.is_open()) {
|
||||
std::string strLine;
|
||||
while (std::getline(inputFile, strLine)) {
|
||||
while (std::getline(input_file, strLine)) {
|
||||
trim(strLine);
|
||||
labels.push_back(strLine);
|
||||
}
|
||||
inputFile.close();
|
||||
input_file.close();
|
||||
}
|
||||
|
||||
// Prints formatted classification results
|
||||
ClassificationResult classificationResult(outputBlob, images, batchSize, FLAGS_nt, labels);
|
||||
classificationResult.print();
|
||||
// -----------------------------------------------------------------------------------------------------
|
||||
ClassificationResult classification_result(output_tensor, images, batch_size, FLAGS_nt, labels);
|
||||
classification_result.show();
|
||||
} catch (const std::exception& ex) {
|
||||
slog::err << ex.what() << slog::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
slog::info << "This sample is an API example, for performance measurements, "
|
||||
"use the dedicated benchmark_app tool"
|
||||
<< slog::endl;
|
||||
return 0;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -89,11 +89,9 @@ int main(int argc, char* argv[]) {
|
||||
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
|
||||
|
||||
if (!FLAGS_l.empty()) {
|
||||
// Custom CPU extension is loaded as a shared library and passed as a
|
||||
// pointer to base extension
|
||||
IExtensionPtr extension_ptr = std::make_shared<Extension>(FLAGS_l);
|
||||
ie.AddExtension(extension_ptr);
|
||||
slog::info << "Custom extension loaded: " << FLAGS_l << slog::endl;
|
||||
slog::info << "Extension loaded: " << FLAGS_l << slog::endl;
|
||||
}
|
||||
|
||||
if (!FLAGS_c.empty() && (FLAGS_d == "GPU" || FLAGS_d == "MYRIAD" || FLAGS_d == "HDDL")) {
|
||||
|
@ -79,11 +79,9 @@ int main(int argc, char* argv[]) {
|
||||
std::cout << ie.GetVersions(FLAGS_d) << std::endl;
|
||||
|
||||
if (!FLAGS_l.empty()) {
|
||||
// Custom CPU extension is loaded as a shared library and passed as a
|
||||
// pointer to base extension
|
||||
IExtensionPtr extension_ptr = std::make_shared<Extension>(FLAGS_l);
|
||||
ie.AddExtension(extension_ptr);
|
||||
slog::info << "Custom Extension loaded: " << FLAGS_l << slog::endl;
|
||||
slog::info << "Extension loaded: " << FLAGS_l << slog::endl;
|
||||
}
|
||||
if (!FLAGS_c.empty() && (FLAGS_d == "GPU" || FLAGS_d == "MYRIAD" || FLAGS_d == "HDDL")) {
|
||||
// Config for device plugin custom extension is loaded from an .xml
|
||||
|
@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief This is a header file for the OpenVINO Runtime Components
|
||||
*
|
||||
* @file openvino/runtime/runtime.hpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/core.hpp"
|
||||
#include "openvino/runtime/runtime.hpp"
|
@ -7,6 +7,7 @@
|
||||
*
|
||||
* @file openvino/runtime/runtime.hpp
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/runtime/core.hpp"
|
||||
|
@ -2,6 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/core/core_visibility.hpp"
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user