add_executable(${INFERENCE_TEST}
${INFER_GTEST_INC_LIST}
${PROJECT_SOURCE_DIR}/inference_engine_test.cpp
+ ${PROJECT_SOURCE_DIR}/inference_engine_test_common.cpp
)
target_link_libraries(${INFERENCE_TEST} ${GTEST_LIBRARY}
add_executable(${INFERENCE_ENGINE_TEST_CASE}
${INFER_GTEST_INC_LIST}
${PROJECT_SOURCE_DIR}/inference_engine_tc.cpp
+ ${PROJECT_SOURCE_DIR}/inference_engine_test_common.cpp
)
target_link_libraries(${INFERENCE_ENGINE_TEST_CASE} ${GTEST_LIBRARY}
#include "inference_engine_error.h"
#include "inference_engine_common_impl.h"
-
-using namespace InferenceEngineInterface::Common;
+#include "inference_engine_test_common.h"
typedef std::tuple<std::string, int> ParamType_Bind;
typedef std::tuple<std::string, int, std::vector<std::string>> ParamType_Load;
class InferenceEngineTestCase_G2 : public testing::TestWithParam<ParamType_Load> { };
class InferenceEngineTestCase_G3 : public testing::TestWithParam<ParamType_Infer> { };
-std::map<std::string, int> Model_Formats = {
- { "caffemodel", INFERENCE_MODEL_CAFFE },
- { "pb", INFERENCE_MODEL_TF },
- { "tflite", INFERENCE_MODEL_TFLITE },
- { "t7", INFERENCE_MODEL_TORCH },
- { "weights", INFERENCE_MODEL_DARKNET },
- { "xml", INFERENCE_MODEL_DLDT },
- { "onnx", INFERENCE_MODEL_ONNX }
-};
-
-std::map<int, std::string> Target_Formats = {
- { INFERENCE_TARGET_CPU, "cpu" },
- { INFERENCE_TARGET_GPU, "gpu" },
- { INFERENCE_TARGET_CUSTOM, "custom" }
-};
-
-enum {
- TEST_IMAGE_CLASSIFICATION = 0,
- TEST_OBJECT_DETECTION,
- TEST_FACE_DETECTION,
- TEST_FACIAL_LANDMARK_DETECTION,
- TEST_POSE_ESTIMATION
-};
-
TEST_P(InferenceEngineTestCase_G1, Bind_P)
{
std::string backend_name;
delete engine;
}
-int GetModelInfo(std::vector <std::string> &model_paths, std::vector<std::string> &models)
-{
- std::string model_path = model_paths[0];
- std::string ext_str = model_path.substr(model_path.find_last_of(".") + 1);
- std::map<std::string, int>::iterator key = Model_Formats.find(ext_str);
- int ret = key != Model_Formats.end() ? key->second : -1;
- EXPECT_NE(ret, -1);
-
- if (ret == -1) {
- return ret;
- }
-
- switch (ret) {
- case INFERENCE_MODEL_CAFFE:
- case INFERENCE_MODEL_TF:
- case INFERENCE_MODEL_DARKNET:
- case INFERENCE_MODEL_DLDT:
- case INFERENCE_MODEL_ONNX:
- models.push_back(model_paths[0]);
- models.push_back(model_paths[1]);
- break;
- case INFERENCE_MODEL_TFLITE:
- case INFERENCE_MODEL_TORCH:
- models.push_back(model_paths[0]);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-int PrepareTensorBuffers(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &inputs,
- std::vector<inference_engine_tensor_buffer> &outputs)
-{
- int ret = engine->GetInputTensorBuffers(inputs);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- if (inputs.empty()) {
- inference_engine_layer_property input_property;
- ret = engine->GetInputLayerProperty(input_property);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- // If backend is OpenCV then the buffers will be allocated out of this function.
- if (input_property.tensor_infos.empty()) {
- return INFERENCE_ENGINE_ERROR_NONE;
- }
-
- for (int i = 0; i < (int)input_property.tensor_infos.size(); ++i) {
- inference_engine_tensor_info tensor_info = input_property.tensor_infos[i];
- inference_engine_tensor_buffer tensor_buffer;
- if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32) {
- tensor_buffer.buffer = (void *)(new float[tensor_info.size]);
- tensor_buffer.size = tensor_info.size * 4;
- } else if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
- tensor_buffer.buffer = (void *)(new unsigned char[tensor_info.size]);
- tensor_buffer.size = tensor_info.size;
- }
-
- EXPECT_TRUE(tensor_buffer.buffer);
- tensor_buffer.owner_is_backend = 0;
- tensor_buffer.data_type = tensor_info.data_type;
- inputs.push_back(tensor_buffer);
- }
- }
-
- ret = engine->GetOutputTensorBuffers(outputs);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- if (outputs.empty()) {
- inference_engine_layer_property output_property;
- ret = engine->GetOutputLayerProperty(output_property);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- // If backend is OpenCV then the buffers will be allocated out of this function.
- if (output_property.tensor_infos.empty()) {
- return INFERENCE_ENGINE_ERROR_NONE;
- }
-
- for (int i = 0; i < (int)output_property.tensor_infos.size(); ++i) {
- inference_engine_tensor_info tensor_info = output_property.tensor_infos[i];
- inference_engine_tensor_buffer tensor_buffer;
- if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32) {
- tensor_buffer.buffer = (void *)(new float[tensor_info.size]);
- tensor_buffer.size = tensor_info.size * 4;
- } else if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
- tensor_buffer.buffer = (void *)(new unsigned char[tensor_info.size]);
- tensor_buffer.size = tensor_info.size;
- }
-
- EXPECT_TRUE(tensor_buffer.buffer);
- tensor_buffer.owner_is_backend = 0;
- tensor_buffer.data_type = tensor_info.data_type;
- outputs.push_back(tensor_buffer);
- }
- }
-
- return INFERENCE_ENGINE_ERROR_NONE;
-}
-
-void CleanupTensorBuffers(std::vector<inference_engine_tensor_buffer> &inputs, std::vector<inference_engine_tensor_buffer> &outputs)
-{
- if (!inputs.empty()) {
- std::vector<inference_engine_tensor_buffer>::iterator iter;
- for (iter = inputs.begin(); iter != inputs.end(); iter++) {
- inference_engine_tensor_buffer tensor_buffer = *iter;
-
- // If tensor buffer owner is a backend then skip to release the tensor buffer.
- // This tensor buffer will be released by the backend.
- if (tensor_buffer.owner_is_backend) {
- continue;
- }
-
- if (tensor_buffer.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32)
- delete[] (float *)tensor_buffer.buffer;
- else
- delete[] (unsigned char *)tensor_buffer.buffer;
- }
- std::vector<inference_engine_tensor_buffer>().swap(inputs);
- }
-
- if (!outputs.empty()) {
- std::vector<inference_engine_tensor_buffer>::iterator iter;
- for (iter = outputs.begin(); iter != outputs.end(); iter++) {
- inference_engine_tensor_buffer tensor_buffer = *iter;
-
- // If tensor buffer owner is a backend then skip to release the tensor buffer.
- // This tensor buffer will be released by the backend.
- if (tensor_buffer.owner_is_backend) {
- continue;
- }
-
- if (tensor_buffer.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32)
- delete[] (float *)tensor_buffer.buffer;
- else
- delete[] (unsigned char *)tensor_buffer.buffer;
- }
- std::vector<inference_engine_tensor_buffer>().swap(outputs);
- }
-}
-
-void CopyFileToMemory(const char *file_name, inference_engine_tensor_buffer &buffer, unsigned int size)
-{
- int fd = open(file_name, O_RDONLY);
- if (fd == -1) {
- ASSERT_NE(fd, -1);
- return;
- }
-
- int num = read(fd, buffer.buffer, size);
- if (num == -1) {
- close(fd);
- ASSERT_NE(num, -1);
- return;
- }
-
- close(fd);
-}
-
-
TEST_P(InferenceEngineTestCase_G2, Load_P)
{
std::string backend_name;
delete engine;
}
-void FillOutputResult(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &outputs, tensor_t &outputData)
-{
- inference_engine_layer_property property;
- int ret = engine->GetOutputLayerProperty(property);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- for (int i = 0; i < (int)property.tensor_infos.size(); ++i) {
- inference_engine_tensor_info tensor_info = property.tensor_infos[i];
-
- std::vector<int> tmpDimInfo;
- for (int i = 0; i < (int)tensor_info.shape.size(); i++) {
- tmpDimInfo.push_back(tensor_info.shape[i]);
- }
-
- outputData.dimInfo.push_back(tmpDimInfo);
-
- // Normalize output tensor data converting it to float type in case of quantized model.
- if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
- unsigned char *ori_buf = (unsigned char *)outputs[i].buffer;
- float *new_buf = new float[tensor_info.size];
- ASSERT_TRUE(new_buf);
-
- for (int j = 0; j < (int)tensor_info.size; j++) {
- new_buf[j] = (float)ori_buf[j] / 255.0f;
- }
-
- // replace original buffer with new one, and release origin one.
- outputs[i].buffer = new_buf;
- if (!outputs[i].owner_is_backend) {
- delete[] ori_buf;
- }
- }
-
- outputData.data.push_back((void *)outputs[i].buffer);
- }
-}
-
-int VerifyImageClassificationResults(tensor_t &outputData, int answer)
-{
- std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
- std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
-
- int idx = -1;
- int count = inferDimInfo[0][1];
- float value = 0.0f;
-
- float *prediction = reinterpret_cast<float*>(inferResults[0]);
- for (int i = 0; i < count; ++i) {
- if (value < prediction[i]) {
- value = prediction[i];
- idx = i;
- }
- }
-
- return idx == answer;
-}
-
TEST_P(InferenceEngineTestCase_G3, Inference)
{
std::string backend_name;
#include "inference_engine_error.h"
#include "inference_engine_common_impl.h"
-
-using namespace InferenceEngineInterface::Common;
+#include "inference_engine_test_common.h"
typedef std::tuple<std::string, int, int, int, int, std::vector<std::string>, int, int, int, std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<int>> ParamType_Infer;
class InferenceEngineCaffeTest : public testing::TestWithParam<ParamType_Infer> { };
class InferenceEngineDldtTest : public testing::TestWithParam<ParamType_Infer> { };
-std::map<std::string, int> Model_Formats = {
- { "caffemodel", INFERENCE_MODEL_CAFFE },
- { "pb", INFERENCE_MODEL_TF },
- { "tflite", INFERENCE_MODEL_TFLITE },
- { "t7", INFERENCE_MODEL_TORCH },
- { "weights", INFERENCE_MODEL_DARKNET },
- { "xml", INFERENCE_MODEL_DLDT },
- { "onnx", INFERENCE_MODEL_ONNX }
-};
-
-std::map<int, std::string> Target_Formats = {
- { INFERENCE_TARGET_CPU, "cpu" },
- { INFERENCE_TARGET_GPU, "gpu" },
- { INFERENCE_TARGET_CUSTOM, "custom" }
-};
-
-enum {
- TEST_IMAGE_CLASSIFICATION = 0,
- TEST_OBJECT_DETECTION,
- TEST_FACE_DETECTION,
- TEST_FACIAL_LANDMARK_DETECTION,
- TEST_POSE_ESTIMATION
-};
-
-int GetModelInfo(std::vector <std::string> &model_paths, std::vector<std::string> &models)
-{
- std::string model_path = model_paths[0];
- std::string ext_str = model_path.substr(model_path.find_last_of(".") + 1);
- std::map<std::string, int>::iterator key = Model_Formats.find(ext_str);
- int ret = key != Model_Formats.end() ? key->second : -1;
- EXPECT_NE(ret, -1);
-
- if (ret == -1) {
- return ret;
- }
-
- switch (ret) {
- case INFERENCE_MODEL_CAFFE:
- case INFERENCE_MODEL_TF:
- case INFERENCE_MODEL_DARKNET:
- case INFERENCE_MODEL_DLDT:
- case INFERENCE_MODEL_ONNX:
- models.push_back(model_paths[0]);
- models.push_back(model_paths[1]);
- break;
- case INFERENCE_MODEL_TFLITE:
- case INFERENCE_MODEL_TORCH:
- models.push_back(model_paths[0]);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-int PrepareTensorBuffers(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &inputs,
- std::vector<inference_engine_tensor_buffer> &outputs)
-{
- int ret = engine->GetInputTensorBuffers(inputs);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- if (inputs.empty()) {
- inference_engine_layer_property input_property;
- ret = engine->GetInputLayerProperty(input_property);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- // If backend is OpenCV then the buffers will be allocated out of this function.
- if (input_property.tensor_infos.empty()) {
- return INFERENCE_ENGINE_ERROR_NONE;
- }
-
- for (int i = 0; i < (int)input_property.tensor_infos.size(); ++i) {
- inference_engine_tensor_info tensor_info = input_property.tensor_infos[i];
- inference_engine_tensor_buffer tensor_buffer;
- if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32) {
- tensor_buffer.buffer = (void *)(new float[tensor_info.size]);
- tensor_buffer.size = tensor_info.size * 4;
- } else if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
- tensor_buffer.buffer = (void *)(new unsigned char[tensor_info.size]);
- tensor_buffer.size = tensor_info.size;
- }
-
- EXPECT_TRUE(tensor_buffer.buffer);
- tensor_buffer.owner_is_backend = 0;
- tensor_buffer.data_type = tensor_info.data_type;
- inputs.push_back(tensor_buffer);
- }
- }
-
- ret = engine->GetOutputTensorBuffers(outputs);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- if (outputs.empty()) {
- inference_engine_layer_property output_property;
- ret = engine->GetOutputLayerProperty(output_property);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- // If backend is OpenCV then the buffers will be allocated out of this function.
- if (output_property.tensor_infos.empty()) {
- return INFERENCE_ENGINE_ERROR_NONE;
- }
-
- for (int i = 0; i < (int)output_property.tensor_infos.size(); ++i) {
- inference_engine_tensor_info tensor_info = output_property.tensor_infos[i];
- inference_engine_tensor_buffer tensor_buffer;
- if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32) {
- tensor_buffer.buffer = (void *)(new float[tensor_info.size]);
- tensor_buffer.size = tensor_info.size * 4;
- } else if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
- tensor_buffer.buffer = (void *)(new unsigned char[tensor_info.size]);
- tensor_buffer.size = tensor_info.size;
- }
-
- EXPECT_TRUE(tensor_buffer.buffer);
- tensor_buffer.owner_is_backend = 0;
- tensor_buffer.data_type = tensor_info.data_type;
- outputs.push_back(tensor_buffer);
- }
- }
-
- return INFERENCE_ENGINE_ERROR_NONE;
-}
-
-void CleanupTensorBuffers(std::vector<inference_engine_tensor_buffer> &inputs, std::vector<inference_engine_tensor_buffer> &outputs)
-{
- if (!inputs.empty()) {
- std::vector<inference_engine_tensor_buffer>::iterator iter;
- for (iter = inputs.begin(); iter != inputs.end(); iter++) {
- inference_engine_tensor_buffer tensor_buffer = *iter;
-
- // If tensor buffer owner is a backend then skip to release the tensor buffer.
- // This tensor buffer will be released by the backend.
- if (tensor_buffer.owner_is_backend) {
- continue;
- }
-
- if (tensor_buffer.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32)
- delete[] (float *)tensor_buffer.buffer;
- else
- delete[] (unsigned char *)tensor_buffer.buffer;
- }
- std::vector<inference_engine_tensor_buffer>().swap(inputs);
- }
-
- if (!outputs.empty()) {
- std::vector<inference_engine_tensor_buffer>::iterator iter;
- for (iter = outputs.begin(); iter != outputs.end(); iter++) {
- inference_engine_tensor_buffer tensor_buffer = *iter;
-
- // If tensor buffer owner is a backend then skip to release the tensor buffer.
- // This tensor buffer will be released by the backend.
- if (tensor_buffer.owner_is_backend) {
- continue;
- }
-
- if (tensor_buffer.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32)
- delete[] (float *)tensor_buffer.buffer;
- else
- delete[] (unsigned char *)tensor_buffer.buffer;
- }
- std::vector<inference_engine_tensor_buffer>().swap(outputs);
- }
-}
-
-void CopyFileToMemory(const char *file_name, inference_engine_tensor_buffer &buffer, unsigned int size)
-{
- int fd = open(file_name, O_RDONLY);
- if (fd == -1) {
- ASSERT_NE(fd, -1);
- return;
- }
-
- int num = read(fd, buffer.buffer, size);
- if (num == -1) {
- close(fd);
- ASSERT_NE(num, -1);
- return;
- }
-
- close(fd);
-}
-
-void FillOutputResult(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &outputs, tensor_t &outputData)
-{
- inference_engine_layer_property property;
- int ret = engine->GetOutputLayerProperty(property);
- EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
-
- for (int i = 0; i < (int)property.tensor_infos.size(); ++i) {
- inference_engine_tensor_info tensor_info = property.tensor_infos[i];
-
- std::vector<int> tmpDimInfo;
- for (int i = 0; i < (int)tensor_info.shape.size(); i++) {
- tmpDimInfo.push_back(tensor_info.shape[i]);
- }
-
- outputData.dimInfo.push_back(tmpDimInfo);
-
- // Normalize output tensor data converting it to float type in case of quantized model.
- if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
- unsigned char *ori_buf = (unsigned char *)outputs[i].buffer;
- float *new_buf = new float[tensor_info.size];
- ASSERT_TRUE(new_buf);
-
- for (int j = 0; j < (int)tensor_info.size; j++) {
- new_buf[j] = (float)ori_buf[j] / 255.0f;
- }
-
- // replace original buffer with new one, and release origin one.
- outputs[i].buffer = new_buf;
- if (!outputs[i].owner_is_backend) {
- delete[] ori_buf;
- }
- }
-
- outputData.data.push_back((void *)outputs[i].buffer);
- }
-}
-
-int VerifyImageClassificationResults(tensor_t &outputData, int answer)
-{
- std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
- std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
-
- int idx = -1;
- int count = inferDimInfo[0][1];
- float value = 0.0f;
-
- float *prediction = reinterpret_cast<float*>(inferResults[0]);
- for (int i = 0; i < count; ++i) {
- if (value < prediction[i]) {
- value = prediction[i];
- idx = i;
- }
- }
-
- return idx == answer;
-}
-
-int VerifyObjectDetectionResults(tensor_t &outputData, std::vector<int> &answers, int height, int width)
-{
- std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
- std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
-
- float* boxes = nullptr;
- float* classes = nullptr;
- float* scores = nullptr;
- int num_of_detections = 0;
-
- if (outputData.dimInfo.size() == 1) {
- // there is no way to know how many objects are detect unless the number of objects aren't
- // provided. In the case, each backend should provide the number of results manually.
- // For example, in OpenCV, MobilenetV1-SSD doesn't provide it so the number of objects are
- // written to the 1st element i.e., outputData.data[0] (the shape is 1x1xNx7 and the 1st of 7
- // indicats the image id. But it is useless if a batch mode isn't supported.
- // So, use the 1st of 7.
-
- num_of_detections = (int)(*reinterpret_cast<float*>(outputData.data[0]));
-
- boxes = new float[num_of_detections * 4];
- classes = new float[num_of_detections];
- scores = new float[num_of_detections];
-
- for (int idx = 0; idx < num_of_detections; ++idx) {
- classes[idx] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 1];
- scores[idx] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 2];
-
- boxes[idx*4] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 4];
- boxes[idx*4 + 1] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 3];
- boxes[idx*4 + 2] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 6];
- boxes[idx*4 + 3] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 5];
- }
- } else {
- boxes = reinterpret_cast<float*>(inferResults[0]);
- classes = reinterpret_cast<float*>(inferResults[1]);
- scores = reinterpret_cast<float*>(inferResults[2]);
- num_of_detections = (int)(*reinterpret_cast<float*>(inferResults[3]));
- }
-
- int left = 0, top = 0, right = 0, bottom = 0;
- float max_score = 0.0f;
-
- for (int i = 0; i < num_of_detections; ++i) {
- if (max_score < scores[i]) {
- max_score = scores[i];
-
- left = (int)(boxes[i * 4 + 1] * width);
- top = (int)(boxes[i * 4 + 0] * height);
- right = (int)(boxes[i * 4 + 3] * width);
- bottom = (int)(boxes[i * 4 + 2] * height);
- }
- }
-
- if (outputData.dimInfo.size() == 1) {
- delete [] boxes;
- delete [] classes;
- delete [] scores;
- }
-
- return (answers[0] == left && answers[1] == top && answers[2] == right && answers[3] == bottom);
-}
-
-int VerifyFacialLandmarkDetectionResults(tensor_t &outputData, std::vector<int> &answers, int height, int width)
-{
- std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
- std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
- std::vector<int> result_x, result_y;
-
- long number_of_detections = inferDimInfo[0][1];
- float* loc = reinterpret_cast<float*>(inferResults[0]);
-
- for (int idx = 0; idx < number_of_detections; idx+=2) {
- result_x.push_back((int)(loc[idx] * width));
- result_y.push_back((int)(loc[idx+1] * height));
- }
-
- int ret = 1;
- for (int i = 0; i < (number_of_detections>>1); i++) {
- if (result_x[i] != answers[i*2] || result_y[i] != answers[i*2 + 1]) {
- ret = 0;
- break;
- }
- }
-
- return ret;
-}
-
-int VerifyPoseEstimationResults(tensor_t &outputData, std::vector<int> &answers, int height, int width)
-{
- std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
- std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
- std::vector<int> result_x, result_y;
-
- const int heat_map_width = 96, heat_map_height = 96;
- int num_of_pose = inferDimInfo[0][3];
- float *data = static_cast<float *>(inferResults[0]);
-
- float ratio_x = (float)width / (float)inferDimInfo[0][2];
- float ratio_y = (float)height / (float)inferDimInfo[0][1];
-
- for (int idx = 0; idx < num_of_pose; ++idx) {
- float max_score = 0.0f;
- int max_x = 0, max_y = 0;
-
- for (int y = 0; y < heat_map_height; ++y) {
- for (int x = 0; x < heat_map_width; ++x) {
- // head_map[Yy][Xx][Kidx] = (Yy * heat_map_height * num_of_pose) + (Xx * num_of_pose) + Kidx
- float score = data[(y * heat_map_width * num_of_pose) + (x * num_of_pose) + idx];
- if (score > max_score) {
- max_score = score;
- max_x = x;
- max_y = y;
- }
- }
- }
-
- result_x.push_back((int)((float)(max_x + 1) * ratio_x));
- result_y.push_back((int)((float)(max_y + 1) * ratio_y));
- }
-
- int ret = 1;
- for (int i = 0; i < num_of_pose; ++i) {
- if (result_x[i] != answers[i] || result_y[i] != answers[num_of_pose + i]) {
- ret = 0;
- break;
- }
- }
-
- return ret;
-}
-
TEST_P(InferenceEngineTfliteTest, Inference)
{
std::string backend_name;
// DLDT
ParamType_Infer("dldt", INFERENCE_TARGET_CUSTOM, TEST_IMAGE_CLASSIFICATION, 10, INFERENCE_TENSOR_DATA_TYPE_FLOAT32, { "/opt/usr/images/dldt_banana_classification.bin" }, 224, 224, 3, { "data" }, { "prob" }, { "/usr/share/capi-media-vision/models/IC/dldt/googlenet-v1.xml", "/usr/share/capi-media-vision/models/IC/dldt/googlenet-v1.bin" }, { 954 })
)
-);
\ No newline at end of file
+);
--- /dev/null
+/**
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <tuple>
+#include <map>
+#include <fcntl.h>
+#include <unistd.h>
+#include <queue>
+#include <algorithm>
+
+#include "gtest/gtest.h"
+
+#include "inference_engine_error.h"
+#include "inference_engine_common_impl.h"
+#include "inference_engine_test_common.h"
+
+static std::map<std::string, int> Model_Formats = {
+ { "caffemodel", INFERENCE_MODEL_CAFFE },
+ { "pb", INFERENCE_MODEL_TF },
+ { "tflite", INFERENCE_MODEL_TFLITE },
+ { "t7", INFERENCE_MODEL_TORCH },
+ { "weights", INFERENCE_MODEL_DARKNET },
+ { "xml", INFERENCE_MODEL_DLDT },
+ { "onnx", INFERENCE_MODEL_ONNX }
+};
+
+int GetModelInfo(std::vector <std::string> &model_paths, std::vector<std::string> &models)
+{
+ std::string model_path = model_paths[0];
+ std::string ext_str = model_path.substr(model_path.find_last_of(".") + 1);
+ std::map<std::string, int>::iterator key = Model_Formats.find(ext_str);
+ int ret = key != Model_Formats.end() ? key->second : -1;
+ EXPECT_NE(ret, -1);
+
+ if (ret == -1) {
+ return ret;
+ }
+
+ switch (ret) {
+ case INFERENCE_MODEL_CAFFE:
+ case INFERENCE_MODEL_TF:
+ case INFERENCE_MODEL_DARKNET:
+ case INFERENCE_MODEL_DLDT:
+ case INFERENCE_MODEL_ONNX:
+ models.push_back(model_paths[0]);
+ models.push_back(model_paths[1]);
+ break;
+ case INFERENCE_MODEL_TFLITE:
+ case INFERENCE_MODEL_TORCH:
+ models.push_back(model_paths[0]);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+int PrepareTensorBuffers(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &inputs,
+ std::vector<inference_engine_tensor_buffer> &outputs)
+{
+ int ret = engine->GetInputTensorBuffers(inputs);
+ EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
+
+ if (inputs.empty()) {
+ inference_engine_layer_property input_property;
+ ret = engine->GetInputLayerProperty(input_property);
+ EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
+
+ // If backend is OpenCV then the buffers will be allocated out of this function.
+ if (input_property.tensor_infos.empty()) {
+ return INFERENCE_ENGINE_ERROR_NONE;
+ }
+
+ for (int i = 0; i < (int)input_property.tensor_infos.size(); ++i) {
+ inference_engine_tensor_info tensor_info = input_property.tensor_infos[i];
+ inference_engine_tensor_buffer tensor_buffer;
+ if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32) {
+ tensor_buffer.buffer = (void *)(new float[tensor_info.size]);
+ tensor_buffer.size = tensor_info.size * 4;
+ } else if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
+ tensor_buffer.buffer = (void *)(new unsigned char[tensor_info.size]);
+ tensor_buffer.size = tensor_info.size;
+ }
+
+ EXPECT_TRUE(tensor_buffer.buffer);
+ tensor_buffer.owner_is_backend = 0;
+ tensor_buffer.data_type = tensor_info.data_type;
+ inputs.push_back(tensor_buffer);
+ }
+ }
+
+ ret = engine->GetOutputTensorBuffers(outputs);
+ EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
+
+ if (outputs.empty()) {
+ inference_engine_layer_property output_property;
+ ret = engine->GetOutputLayerProperty(output_property);
+ EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
+
+ // If backend is OpenCV then the buffers will be allocated out of this function.
+ if (output_property.tensor_infos.empty()) {
+ return INFERENCE_ENGINE_ERROR_NONE;
+ }
+
+ for (int i = 0; i < (int)output_property.tensor_infos.size(); ++i) {
+ inference_engine_tensor_info tensor_info = output_property.tensor_infos[i];
+ inference_engine_tensor_buffer tensor_buffer;
+ if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32) {
+ tensor_buffer.buffer = (void *)(new float[tensor_info.size]);
+ tensor_buffer.size = tensor_info.size * 4;
+ } else if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
+ tensor_buffer.buffer = (void *)(new unsigned char[tensor_info.size]);
+ tensor_buffer.size = tensor_info.size;
+ }
+
+ EXPECT_TRUE(tensor_buffer.buffer);
+ tensor_buffer.owner_is_backend = 0;
+ tensor_buffer.data_type = tensor_info.data_type;
+ outputs.push_back(tensor_buffer);
+ }
+ }
+
+ return INFERENCE_ENGINE_ERROR_NONE;
+}
+
+void CleanupTensorBuffers(std::vector<inference_engine_tensor_buffer> &inputs, std::vector<inference_engine_tensor_buffer> &outputs)
+{
+ if (!inputs.empty()) {
+ std::vector<inference_engine_tensor_buffer>::iterator iter;
+ for (iter = inputs.begin(); iter != inputs.end(); iter++) {
+ inference_engine_tensor_buffer tensor_buffer = *iter;
+
+ // If tensor buffer owner is a backend then skip to release the tensor buffer.
+ // This tensor buffer will be released by the backend.
+ if (tensor_buffer.owner_is_backend) {
+ continue;
+ }
+
+ if (tensor_buffer.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32)
+ delete[] (float *)tensor_buffer.buffer;
+ else
+ delete[] (unsigned char *)tensor_buffer.buffer;
+ }
+ std::vector<inference_engine_tensor_buffer>().swap(inputs);
+ }
+
+ if (!outputs.empty()) {
+ std::vector<inference_engine_tensor_buffer>::iterator iter;
+ for (iter = outputs.begin(); iter != outputs.end(); iter++) {
+ inference_engine_tensor_buffer tensor_buffer = *iter;
+
+ // If tensor buffer owner is a backend then skip to release the tensor buffer.
+ // This tensor buffer will be released by the backend.
+ if (tensor_buffer.owner_is_backend) {
+ continue;
+ }
+
+ if (tensor_buffer.data_type == INFERENCE_TENSOR_DATA_TYPE_FLOAT32)
+ delete[] (float *)tensor_buffer.buffer;
+ else
+ delete[] (unsigned char *)tensor_buffer.buffer;
+ }
+ std::vector<inference_engine_tensor_buffer>().swap(outputs);
+ }
+}
+
+void CopyFileToMemory(const char *file_name, inference_engine_tensor_buffer &buffer, unsigned int size)
+{
+ int fd = open(file_name, O_RDONLY);
+ if (fd == -1) {
+ ASSERT_NE(fd, -1);
+ return;
+ }
+
+ int num = read(fd, buffer.buffer, size);
+ if (num == -1) {
+ close(fd);
+ ASSERT_NE(num, -1);
+ return;
+ }
+
+ close(fd);
+}
+
+void FillOutputResult(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &outputs, tensor_t &outputData)
+{
+ inference_engine_layer_property property;
+ int ret = engine->GetOutputLayerProperty(property);
+ EXPECT_EQ(ret, INFERENCE_ENGINE_ERROR_NONE);
+
+ for (int i = 0; i < (int)property.tensor_infos.size(); ++i) {
+ inference_engine_tensor_info tensor_info = property.tensor_infos[i];
+
+ std::vector<int> tmpDimInfo;
+ for (int i = 0; i < (int)tensor_info.shape.size(); i++) {
+ tmpDimInfo.push_back(tensor_info.shape[i]);
+ }
+
+ outputData.dimInfo.push_back(tmpDimInfo);
+
+ // Normalize output tensor data converting it to float type in case of quantized model.
+ if (tensor_info.data_type == INFERENCE_TENSOR_DATA_TYPE_UINT8) {
+ unsigned char *ori_buf = (unsigned char *)outputs[i].buffer;
+ float *new_buf = new float[tensor_info.size];
+ ASSERT_TRUE(new_buf);
+
+ for (int j = 0; j < (int)tensor_info.size; j++) {
+ new_buf[j] = (float)ori_buf[j] / 255.0f;
+ }
+
+ // replace original buffer with new one, and release origin one.
+ outputs[i].buffer = new_buf;
+ if (!outputs[i].owner_is_backend) {
+ delete[] ori_buf;
+ }
+ }
+
+ outputData.data.push_back((void *)outputs[i].buffer);
+ }
+}
+
+int VerifyImageClassificationResults(tensor_t &outputData, int answer)
+{
+ std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
+ std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
+
+ int idx = -1;
+ int count = inferDimInfo[0][1];
+ float value = 0.0f;
+
+ float *prediction = reinterpret_cast<float*>(inferResults[0]);
+ for (int i = 0; i < count; ++i) {
+ if (value < prediction[i]) {
+ value = prediction[i];
+ idx = i;
+ }
+ }
+
+ return idx == answer;
+}
+
+int VerifyObjectDetectionResults(tensor_t &outputData, std::vector<int> &answers, int height, int width)
+{
+ std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
+ std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
+
+ float* boxes = nullptr;
+ float* classes = nullptr;
+ float* scores = nullptr;
+ int num_of_detections = 0;
+
+ if (outputData.dimInfo.size() == 1) {
+ // there is no way to know how many objects are detect unless the number of objects aren't
+ // provided. In the case, each backend should provide the number of results manually.
+ // For example, in OpenCV, MobilenetV1-SSD doesn't provide it so the number of objects are
+ // written to the 1st element i.e., outputData.data[0] (the shape is 1x1xNx7 and the 1st of 7
+ // indicats the image id. But it is useless if a batch mode isn't supported.
+ // So, use the 1st of 7.
+
+ num_of_detections = (int)(*reinterpret_cast<float*>(outputData.data[0]));
+
+ boxes = new float[num_of_detections * 4];
+ classes = new float[num_of_detections];
+ scores = new float[num_of_detections];
+
+ for (int idx = 0; idx < num_of_detections; ++idx) {
+ classes[idx] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 1];
+ scores[idx] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 2];
+
+ boxes[idx*4] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 4];
+ boxes[idx*4 + 1] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 3];
+ boxes[idx*4 + 2] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 6];
+ boxes[idx*4 + 3] = (reinterpret_cast<float*>(outputData.data[0]))[idx*inferDimInfo[0][3] + 5];
+ }
+ } else {
+ boxes = reinterpret_cast<float*>(inferResults[0]);
+ classes = reinterpret_cast<float*>(inferResults[1]);
+ scores = reinterpret_cast<float*>(inferResults[2]);
+ num_of_detections = (int)(*reinterpret_cast<float*>(inferResults[3]));
+ }
+
+ int left = 0, top = 0, right = 0, bottom = 0;
+ float max_score = 0.0f;
+
+ for (int i = 0; i < num_of_detections; ++i) {
+ if (max_score < scores[i]) {
+ max_score = scores[i];
+
+ left = (int)(boxes[i * 4 + 1] * width);
+ top = (int)(boxes[i * 4 + 0] * height);
+ right = (int)(boxes[i * 4 + 3] * width);
+ bottom = (int)(boxes[i * 4 + 2] * height);
+ }
+ }
+
+ if (outputData.dimInfo.size() == 1) {
+ delete [] boxes;
+ delete [] classes;
+ delete [] scores;
+ }
+
+ return (answers[0] == left && answers[1] == top && answers[2] == right && answers[3] == bottom);
+}
+
+int VerifyFacialLandmarkDetectionResults(tensor_t &outputData, std::vector<int> &answers, int height, int width)
+{
+ std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
+ std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
+ std::vector<int> result_x, result_y;
+
+ long number_of_detections = inferDimInfo[0][1];
+ float* loc = reinterpret_cast<float*>(inferResults[0]);
+
+ for (int idx = 0; idx < number_of_detections; idx+=2) {
+ result_x.push_back((int)(loc[idx] * width));
+ result_y.push_back((int)(loc[idx+1] * height));
+ }
+
+ int ret = 1;
+ for (int i = 0; i < (number_of_detections>>1); i++) {
+ if (result_x[i] != answers[i*2] || result_y[i] != answers[i*2 + 1]) {
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int VerifyPoseEstimationResults(tensor_t &outputData, std::vector<int> &answers, int height, int width)
+{
+ std::vector<std::vector<int>> inferDimInfo(outputData.dimInfo);
+ std::vector<void*> inferResults(outputData.data.begin(), outputData.data.end());
+ std::vector<int> result_x, result_y;
+
+ const int heat_map_width = 96, heat_map_height = 96;
+ int num_of_pose = inferDimInfo[0][3];
+ float *data = static_cast<float *>(inferResults[0]);
+
+ float ratio_x = (float)width / (float)inferDimInfo[0][2];
+ float ratio_y = (float)height / (float)inferDimInfo[0][1];
+
+ for (int idx = 0; idx < num_of_pose; ++idx) {
+ float max_score = 0.0f;
+ int max_x = 0, max_y = 0;
+
+ for (int y = 0; y < heat_map_height; ++y) {
+ for (int x = 0; x < heat_map_width; ++x) {
+ // head_map[Yy][Xx][Kidx] = (Yy * heat_map_height * num_of_pose) + (Xx * num_of_pose) + Kidx
+ float score = data[(y * heat_map_width * num_of_pose) + (x * num_of_pose) + idx];
+ if (score > max_score) {
+ max_score = score;
+ max_x = x;
+ max_y = y;
+ }
+ }
+ }
+
+ result_x.push_back((int)((float)(max_x + 1) * ratio_x));
+ result_y.push_back((int)((float)(max_y + 1) * ratio_y));
+ }
+
+ int ret = 1;
+ for (int i = 0; i < num_of_pose; ++i) {
+ if (result_x[i] != answers[i] || result_y[i] != answers[num_of_pose + i]) {
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
+}
--- /dev/null
+/**
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <unistd.h>
+
+#include "inference_engine_common_impl.h"
+
+using namespace InferenceEngineInterface::Common;
+
+static std::map<int, std::string> Target_Formats = {
+ { INFERENCE_TARGET_CPU, "cpu" },
+ { INFERENCE_TARGET_GPU, "gpu" },
+ { INFERENCE_TARGET_CUSTOM, "custom" }
+};
+
+enum {
+ TEST_IMAGE_CLASSIFICATION = 0,
+ TEST_OBJECT_DETECTION,
+ TEST_FACE_DETECTION,
+ TEST_FACIAL_LANDMARK_DETECTION,
+ TEST_POSE_ESTIMATION
+};
+
+int GetModelInfo(std::vector <std::string> &model_paths, std::vector<std::string> &models);
+
+int PrepareTensorBuffers(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &inputs,
+ std::vector<inference_engine_tensor_buffer> &outputs);
+
+void CleanupTensorBuffers(std::vector<inference_engine_tensor_buffer> &inputs, std::vector<inference_engine_tensor_buffer> &outputs);
+
+void CopyFileToMemory(const char *file_name, inference_engine_tensor_buffer &buffer, unsigned int size);
+
+void FillOutputResult(InferenceEngineCommon *engine, std::vector<inference_engine_tensor_buffer> &outputs, tensor_t &outputData);
+
+int VerifyImageClassificationResults(tensor_t &outputData, int answer);
+
+int VerifyObjectDetectionResults(tensor_t &outputData, std::vector<int> &answers, int height, int width);
+
+int VerifyFacialLandmarkDetectionResults(tensor_t &outputData, std::vector<int> &answers, int height, int width);
+
+int VerifyPoseEstimationResults(tensor_t &outputData, std::vector<int> &answers, int height, int width);
\ No newline at end of file