Accepting request 1227952 from science:machinelearning

OBS-URL: https://build.opensuse.org/request/show/1227952
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/armnn?expand=0&rev=13
This commit is contained in:
Ana Guerrero 2024-12-03 19:47:11 +00:00 committed by Git OBS Bridge
commit c147cab9f8
11 changed files with 25 additions and 1029 deletions

View File

@ -1,76 +0,0 @@
From 964cb82f3b811aec6663255ab0aa589f0a3be0ee Mon Sep 17 00:00:00 2001
From: Qin Su <qsu@ti.com>
Date: Fri, 22 Feb 2019 14:10:07 -0500
Subject: [PATCH] add more test command line arguments
Updated by Guillaume_G to apply properly (s/BOOST_ASSERT/ARMNN_ASSERT/)
Upstream-Status: Inappropriate [TI only test code]
Signed-off-by: Qin Su <qsu@ti.com>
---
tests/InferenceTest.inl | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/tests/InferenceTest.inl b/tests/InferenceTest.inl
index 538720b..6fd21b8 100644
--- a/tests/InferenceTest.inl
+++ b/tests/InferenceTest.inl
@@ -326,6 +326,55 @@ int ClassifierInferenceTestMain(int argc,
ARMNN_ASSERT(modelFilename);
ARMNN_ASSERT(inputBindingName);
ARMNN_ASSERT(outputBindingName);
+ int count;
+ const char *p_input;
+ char inmodelname[500];
+ char outtensorname[500];
+
+ /* parse command line */
+ for (count = 1; count < argc; count++)
+ {
+ if (*(argv[count]) == '+')
+ {
+ p_input = argv[count] + 1;
+ switch (*(p_input))
+ {
+ case 'i':
+ case 'I':
+ strcpy(inmodelname, p_input + 2);
+ modelFilename = &inmodelname[0];
+ std::cout << "Input model = " << modelFilename << std::endl;
+ break;
+ case 'o':
+ case 'O':
+ strcpy(outtensorname, p_input + 2);
+ outputBindingName = &outtensorname[0];
+ std::cout << "out tensor name = " << outputBindingName << std::endl;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (*(argv[count]) == '-')
+ {
+ p_input = argv[count] + 1;
+ switch (*(p_input))
+ {
+ case '-':
+ p_input = argv[count] + 2;
+ case 'h':
+ case 'H':
+ std::cout <<"\nAdditional Options: " << std::endl;
+ std::cout <<" +i Set user specified inference model name." << std::endl;
+ std::cout <<" If not set, default name is used." << std::endl;
+ std::cout <<" +o Set user specified output tensor name." << std::endl;
+ std::cout <<" If not set, default name is used.\n" << std::endl;
+ break;
+ default:
+ break;
+ }
+ }
+ }
return InferenceTestMain(argc, argv, defaultTestCaseIds,
[=]
--
1.9.1

View File

@ -1,71 +0,0 @@
From 99a6c339f1828d3cd1b193cf702bada9011d900b Mon Sep 17 00:00:00 2001
From: Djordje Senicic <x0157990@ti.com>
Date: Mon, 24 Jun 2019 14:29:19 -0400
Subject: [PATCH] add armnn mobilenet test example
Upstream-Status: Inappropriate [TI only test code]
Signed-off-by: Qin Su <qsu@ti.com>
Signed-off-by: Djordje Senicic <x0157990@ti.com>
[Guillaume's update: Add boost_log dep]
[Guillaume's update: Update to apply on top of 20.08]
---
tests/CMakeLists.txt | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index dfcf4b48..5a78d3a6 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,3 +1,6 @@
+find_package( OpenCV REQUIRED )
+include_directories( ${OpenCV_INCLUDE_DIRS} )
+
# UnitTests
include(CheckIncludeFiles)
@@ -348,3 +351,42 @@ if(BUILD_ARMNN_QUANTIZER)
target_include_directories(ImageCSVFileGenerator PRIVATE ../src/armnnUtils)
ImageTensorExecutor(ImageCSVFileGenerator)
endif()
+
+if (BUILD_ARMNN_EXAMPLES)
+ set(ArmnnExamples_sources
+ ArmnnExamples/ArmnnExamples.cpp)
+
+ add_executable_ex(ArmnnExamples ${ArmnnExamples_sources})
+
+ target_include_directories(ArmnnExamples PRIVATE ../src/armnnUtils)
+ target_include_directories(ArmnnExamples PRIVATE ../src/armnn)
+ target_include_directories(ArmnnExamples PRIVATE ../src/backends)
+
+ if (BUILD_CAFFE_PARSER)
+ target_link_libraries(ArmnnExamples armnnCaffeParser)
+ endif()
+ if (BUILD_TF_PARSER)
+ target_link_libraries(ArmnnExamples armnnTfParser)
+ endif()
+
+ if (BUILD_TF_LITE_PARSER)
+ target_link_libraries(ArmnnExamples armnnTfLiteParser)
+ endif()
+ if (BUILD_ONNX_PARSER)
+ target_link_libraries(ArmnnExamples armnnOnnxParser)
+ endif()
+
+ target_link_libraries(ArmnnExamples armnn)
+ target_link_libraries(ArmnnExamples ${CMAKE_THREAD_LIBS_INIT})
+ if(OPENCL_LIBRARIES)
+ target_link_libraries(ArmnnExamples ${OPENCL_LIBRARIES})
+ endif()
+
+ target_link_libraries(ArmnnExamples
+ ${Boost_LOG_LIBRARY}
+ ${Boost_SYSTEM_LIBRARY}
+ ${Boost_FILESYSTEM_LIBRARY}
+ ${Boost_PROGRAM_OPTIONS_LIBRARY}
+ ${OpenCV_LIBS})
+ addDllCopyCommands(ArmnnExamples)
+endif()
--
2.17.1

View File

@ -1,680 +0,0 @@
From 4d5e7db268a4f816e24449e8ad011e35890f0c7e Mon Sep 17 00:00:00 2001
From: Qin Su <qsu@ti.com>
Date: Fri, 22 Feb 2019 13:39:09 -0500
Subject: [PATCH] armnn mobilenet test example
Upstream-Status: Inappropriate [TI only test code]
Signed-off-by: Qin Su <qsu@ti.com>
[Guillaume's update: s#Logging.hpp#armnn/Logging.hpp#]
[Guillaume's update: Add #include <boost/log/trivial.hpp>]
[Guillaume's update: Drop armnnUtils::ConfigureLogging(...)]
[Guillaume's update: Handle boost::variant to mapbox::util::variant update]
---
tests/ArmnnExamples/ArmnnExamples.cpp | 654 ++++++++++++++++++++++++++++++++++
1 file changed, 654 insertions(+)
create mode 100644 tests/ArmnnExamples/ArmnnExamples.cpp
diff --git a/tests/ArmnnExamples/ArmnnExamples.cpp b/tests/ArmnnExamples/ArmnnExamples.cpp
new file mode 100644
index 0000000..53a11cc
--- /dev/null
+++ b/tests/ArmnnExamples/ArmnnExamples.cpp
@@ -0,0 +1,654 @@
+/******************************************************************************
+ * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Texas Instruments Incorporated nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************///
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#include <armnn/ArmNN.hpp>
+#include <boost/log/trivial.hpp>
+
+#include <utility>
+#include <armnn/TypesUtils.hpp>
+
+#if defined(ARMNN_CAFFE_PARSER)
+#include "armnnCaffeParser/ICaffeParser.hpp"
+#endif
+#if defined(ARMNN_TF_PARSER)
+#include "armnnTfParser/ITfParser.hpp"
+#endif
+#if defined(ARMNN_TF_LITE_PARSER)
+#include "armnnTfLiteParser/ITfLiteParser.hpp"
+#endif
+#if defined(ARMNN_ONNX_PARSER)
+#include "armnnOnnxParser/IOnnxParser.hpp"
+#endif
+#include <mapbox/variant.hpp> /*#include "CsvReader.hpp"*/
+#include "../InferenceTest.hpp"
+#include <armnn/Logging.hpp>
+#include <Profiling.hpp>
+
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/program_options.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <functional>
+#include <future>
+#include <algorithm>
+#include <iterator>
+#include<vector>
+
+#include <signal.h>
+#include "opencv2/core.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/highgui.hpp"
+#include "opencv2/videoio.hpp"
+#include <time.h>
+
+using namespace cv;
+
+#define INPUT_IMAGE 0
+#define INPUT_VIDEO 1
+#define INPUT_CAMERA 2
+
+Mat test_image;
+Rect rectCrop;
+
+time_point<high_resolution_clock> predictStart;
+time_point<high_resolution_clock> predictEnd;
+
+void imagenetCallBackFunc(int event, int x, int y, int flags, void* userdata)
+{
+ if ( event == EVENT_RBUTTONDOWN )
+ {
+ std::cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << " ... prepare to exit!" << std::endl;
+ exit(0);
+ }
+}
+
+inline float Lerpfloat(float a, float b, float w)
+{
+ return w * b + (1.f - w) * a;
+}
+
+// Load a single image
+struct ImageData
+{
+ unsigned int m_width;
+ unsigned int m_height;
+ unsigned int m_chnum;
+ unsigned int m_size;
+ std::vector<uint8_t> m_image;
+};
+// Load a single image
+std::unique_ptr<ImageData> loadImageData(std::string image_path, VideoCapture &cap, cv::Mat img, int input_type)
+{
+ //cv::Mat img;
+ if (input_type == INPUT_IMAGE)
+ {
+ /* use OpenCV to get the image */
+ img = cv::imread(image_path, CV_LOAD_IMAGE_COLOR);
+ }
+ cv::cvtColor(img, img, CV_BGR2RGB); //convert image format from BGR(openCV format) to RGB (armnn required format).
+
+ // store image and label in output Image
+ std::unique_ptr<ImageData> ret(new ImageData);
+ ret->m_width = static_cast<unsigned int>(img.cols);
+ ret->m_height = static_cast<unsigned int>(img.rows);
+ ret->m_chnum = static_cast<unsigned int>(img.channels());
+ ret->m_size = static_cast<unsigned int>(img.cols*img.rows*img.channels());
+ ret->m_image.resize(ret->m_size);
+
+ for (unsigned int i = 0; i < ret->m_size; i++)
+ {
+ ret->m_image[i] = static_cast<uint8_t>(img.data[i]);
+ }
+ return ret;
+}
+// to resize input tensor size
+std::vector<float> ResizeBilinear(std::vector<uint8_t> input,
+ const unsigned int inWidth,
+ const unsigned int inHeight,
+ const unsigned int inChnum,
+ const unsigned int outputWidth,
+ const unsigned int outputHeight)
+{
+ std::vector<float> out;
+ out.resize(outputWidth * outputHeight * 3);
+
+ // We follow the definition of TensorFlow and AndroidNN: the top-left corner of a texel in the output
+ // image is projected into the input image to figure out the interpolants and weights. Note that this
+ // will yield different results than if projecting the centre of output texels.
+
+ const unsigned int inputWidth = inWidth;
+ const unsigned int inputHeight = inHeight;
+
+ // How much to scale pixel coordinates in the output image to get the corresponding pixel coordinates
+ // in the input image.
+ const float scaleY = boost::numeric_cast<float>(inputHeight) / boost::numeric_cast<float>(outputHeight);
+ const float scaleX = boost::numeric_cast<float>(inputWidth) / boost::numeric_cast<float>(outputWidth);
+
+ uint8_t rgb_x0y0[3];
+ uint8_t rgb_x1y0[3];
+ uint8_t rgb_x0y1[3];
+ uint8_t rgb_x1y1[3];
+ unsigned int pixelOffset00, pixelOffset10, pixelOffset01, pixelOffset11;
+ for (unsigned int y = 0; y < outputHeight; ++y)
+ {
+ // Corresponding real-valued height coordinate in input image.
+ const float iy = boost::numeric_cast<float>(y) * scaleY;
+ // Discrete height coordinate of top-left texel (in the 2x2 texel area used for interpolation).
+ const float fiy = floorf(iy);
+ const unsigned int y0 = boost::numeric_cast<unsigned int>(fiy);
+
+ // Interpolation weight (range [0,1])
+ const float yw = iy - fiy;
+
+ for (unsigned int x = 0; x < outputWidth; ++x)
+ {
+ // Real-valued and discrete width coordinates in input image.
+ const float ix = boost::numeric_cast<float>(x) * scaleX;
+ const float fix = floorf(ix);
+ const unsigned int x0 = boost::numeric_cast<unsigned int>(fix);
+
+ // Interpolation weight (range [0,1]).
+ const float xw = ix - fix;
+
+ // Discrete width/height coordinates of texels below and to the right of (x0, y0).
+ const unsigned int x1 = std::min(x0 + 1, inputWidth - 1u);
+ const unsigned int y1 = std::min(y0 + 1, inputHeight - 1u);
+
+ pixelOffset00 = x0 * inChnum + y0 * inputWidth * inChnum;
+ pixelOffset10 = x1 * inChnum + y0 * inputWidth * inChnum;
+ pixelOffset01 = x0 * inChnum + y1 * inputWidth * inChnum;
+ pixelOffset11 = x1 * inChnum + y1 * inputWidth * inChnum;
+ for (unsigned int c = 0; c < 3; ++c)
+ {
+ rgb_x0y0[c] = input[pixelOffset00+c];
+ rgb_x1y0[c] = input[pixelOffset10+c];
+ rgb_x0y1[c] = input[pixelOffset01+c];
+ rgb_x1y1[c] = input[pixelOffset11+c];
+ }
+
+ for (unsigned c=0; c<3; ++c)
+ {
+ const float ly0 = Lerpfloat(float(rgb_x0y0[c]), float(rgb_x1y0[c]), xw);
+ const float ly1 = Lerpfloat(float(rgb_x0y1[c]), float(rgb_x1y1[c]), xw);
+ const float l = Lerpfloat(ly0, ly1, yw);
+ out[(3*((y*outputWidth)+x)) + c] = static_cast<float>(l)/255.0f;
+ }
+ }
+ }
+ return out;
+}
+
+namespace
+{
+
+ // Configure boost::program_options for command-line parsing and validation.
+ namespace po = boost::program_options;
+
+ template<typename T, typename TParseElementFunc>
+ std::vector<T> ParseArrayImpl(std::istream& stream, TParseElementFunc parseElementFunc)
+ {
+ std::vector<T> result;
+ // Processes line-by-line.
+ std::string line;
+ while (std::getline(stream, line))
+ {
+ std::vector<std::string> tokens;
+ try
+ {
+ // Coverity fix: boost::split() may throw an exception of type boost::bad_function_call.
+ boost::split(tokens, line, boost::algorithm::is_any_of("\t ,;:"), boost::token_compress_on);
+ }
+ catch (const std::exception& e)
+ {
+ BOOST_LOG_TRIVIAL(error) << "An error occurred when splitting tokens: " << e.what();
+ continue;
+ }
+ for (const std::string& token : tokens)
+ {
+ if (!token.empty())
+ {
+ try
+ {
+ result.push_back(parseElementFunc(token));
+ }
+ catch (const std::exception&)
+ {
+ BOOST_LOG_TRIVIAL(error) << "'" << token << "' is not a valid number. It has been ignored.";
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ template<typename T>
+ std::vector<T> ParseArray(std::istream& stream);
+ template<>
+ std::vector<unsigned int> ParseArray(std::istream& stream)
+ {
+ return ParseArrayImpl<unsigned int>(stream,
+ [](const std::string& s) { return boost::numeric_cast<unsigned int>(std::stoi(s)); });
+ }
+ void RemoveDuplicateDevices(std::vector<armnn::BackendId>& computeDevices)
+ {
+ // Mark the duplicate devices as 'Undefined'.
+ for (auto i = computeDevices.begin(); i != computeDevices.end(); ++i)
+ {
+ for (auto j = std::next(i); j != computeDevices.end(); ++j)
+ {
+ if (*j == *i)
+ {
+ *j = armnn::Compute::Undefined;
+ }
+ }
+ }
+
+ // Remove 'Undefined' devices.
+ computeDevices.erase(std::remove(computeDevices.begin(), computeDevices.end(), armnn::Compute::Undefined),
+ computeDevices.end());
+ }
+} // namespace
+
+template<typename TParser, typename TDataType>
+int MainImpl(const char* modelPath,
+ bool isModelBinary,
+ const std::vector<armnn::BackendId>& computeDevices,
+ const char* inputName,
+ const armnn::TensorShape* inputTensorShape,
+ const char* inputTensorDataFilePath,
+ const char* outputName,
+ bool enableProfiling,
+ const size_t number_frame,
+ const std::shared_ptr<armnn::IRuntime>& runtime = nullptr)
+{
+ // Loads input tensor.
+ std::vector<uint8_t> input;
+ std::vector<float> input_resized;
+ using TContainer = mapbox::util::variant<std::vector<float>, std::vector<int>, std::vector<unsigned char>>;
+
+ try
+ {
+ // Creates an InferenceModel, which will parse the model and load it into an IRuntime.
+ typename InferenceModel<TParser, TDataType>::Params params;
+ //const armnn::TensorShape inputTensorShape({ 1, 224, 224 3});
+
+ params.m_ModelPath = modelPath;
+ params.m_IsModelBinary = isModelBinary;
+ params.m_ComputeDevices = computeDevices;
+ params.m_InputBindings = { inputName };
+ params.m_InputShapes = { *inputTensorShape };
+ params.m_OutputBindings = { outputName };
+ //params.m_EnableProfiling = enableProfiling;
+ params.m_SubgraphId = 0;
+ InferenceModel<TParser, TDataType> model(params, enableProfiling, runtime);
+
+ VideoCapture cap;
+ int input_type = INPUT_IMAGE;
+ std::string filename = inputTensorDataFilePath;
+
+ size_t i = filename.rfind("camera_live_input", filename.length());
+ if (i != string::npos)
+ {
+ cap = VideoCapture(1);
+ namedWindow("ARMNN MobileNet Example", WINDOW_AUTOSIZE | CV_GUI_NORMAL);
+ input_type = INPUT_CAMERA; //camera input
+ }
+ else if((filename.substr(filename.find_last_of(".") + 1) == "mp4") ||
+ (filename.substr(filename.find_last_of(".") + 1) == "mov") ||
+ (filename.substr(filename.find_last_of(".") + 1) == "avi") )
+ {
+ cap = VideoCapture(inputTensorDataFilePath);
+ if (! cap.isOpened())
+ {
+ std::cout << "Cannot open video input: " << inputTensorDataFilePath << std::endl;
+ return (-1);
+ }
+
+ namedWindow("ARMNN MobileNet Example", WINDOW_AUTOSIZE | CV_GUI_NORMAL);
+ input_type = INPUT_VIDEO; //video clip input
+ }
+ if (input_type != INPUT_IMAGE)
+ {
+ //set the callback function for any mouse event. Used for right click mouse to exit the program.
+ setMouseCallback("ARMNN MobileNet Example", imagenetCallBackFunc, NULL);
+ }
+
+ for (unsigned int i=0; i < number_frame; i++)
+ {
+ if (input_type != INPUT_IMAGE)
+ {
+ cap.grab();
+ cap.retrieve(test_image);
+ }
+ std::unique_ptr<ImageData> inputData = loadImageData(inputTensorDataFilePath, cap, test_image, input_type);
+ input.resize(inputData->m_size);
+
+ input = std::move(inputData->m_image);
+ input_resized = ResizeBilinear(input, inputData->m_width, inputData->m_height, inputData->m_chnum, 224, 224);
+
+ // Set up input data container
+ std::vector<TContainer> inputDataContainer(1, std::move(input_resized));
+
+ // Set up output data container
+ std::vector<TContainer> outputDataContainers;
+ outputDataContainers.push_back(std::vector<float>(model.GetOutputSize()));
+
+ //profile start
+ predictStart = high_resolution_clock::now();
+ // Execute model
+ model.Run(inputDataContainer, outputDataContainers);
+ //profile end
+ predictEnd = high_resolution_clock::now();
+
+ double timeTakenS = duration<double>(predictEnd - predictStart).count();
+ double preformance_ret = static_cast<double>(1.0/timeTakenS);
+
+ //retrieve output
+ std::vector<float>& outputData = (mapbox::util::get<std::vector<float>>(outputDataContainers[0]));
+ //output TOP predictions
+ std::string predict_target_name;
+ // find the out with the highest confidence
+ int label = static_cast<int>(std::distance(outputData.begin(), std::max_element(outputData.begin(), outputData.end())));
+ std::fstream file("/usr/share/arm/armnn/models/labels.txt");
+ //std::string predict_target_name;
+ for (int i=0; i <= label; i++)
+ {
+ std::getline(file, predict_target_name);
+ }
+ //get the probability of the top prediction
+ float prob = 100*outputData.data()[label];
+ //clean the top one so as to find the second top prediction
+ outputData.data()[label] = 0;
+ std::cout << "Top(1) prediction is " << predict_target_name << " with confidence: " << prob << "%" << std::endl;
+ //output next TOP 4 predictions
+ for (int ii=1; ii<5; ii++)
+ {
+ std::string predict_target_name_n;
+ // find the out with the highest confidence
+ int label = static_cast<int>(std::distance(outputData.begin(), std::max_element(outputData.begin(), outputData.end())));
+ std::fstream file("/usr/share/arm/armnn/models/labels.txt");
+ //std::string predict_target_name;
+ for (int i=0; i <= label; i++)
+ {
+ std::getline(file, predict_target_name_n);
+ }
+ //get the probability of the prediction
+ float prob = 100*outputData.data()[label];
+ //clean the top one so as to find the second top prediction
+ outputData.data()[label] = 0;
+
+ std::cout << "Top(" << (ii+1) << ") prediction is " << predict_target_name_n << " with confidence: " << prob << "%" << std::endl;
+ }
+ std::cout << "Performance (FPS): " << preformance_ret << std::endl;
+
+ if (input_type != INPUT_IMAGE)
+ {
+ //convert image format back to BGR for OpenCV imshow from RGB format required by armnn.
+ cv::cvtColor(test_image, test_image, CV_RGB2BGR);
+ // output identified object name on top of input image
+ cv::putText(test_image, predict_target_name,
+ cv::Point(rectCrop.x + 5,rectCrop.y + 20), // Coordinates
+ cv::FONT_HERSHEY_COMPLEX_SMALL, // Font
+ 1.0, // Scale. 2.0 = 2x bigger
+ cv::Scalar(0,0,255), // Color
+ 1, // Thickness
+ 8); // Line type
+
+ // output preformance in FPS on top of input image
+ std::string preformance_ret_string = "Performance (FPS): " + boost::lexical_cast<std::string>(preformance_ret);
+ cv::putText(test_image, preformance_ret_string,
+ cv::Point(rectCrop.x + 5,rectCrop.y + 40), // Coordinates
+ cv::FONT_HERSHEY_COMPLEX_SMALL, // Font
+ 1.0, // Scale. 2.0 = 2x bigger
+ cv::Scalar(0,0,255), // Color
+ 1, // Thickness
+ 8); // Line type
+
+ cv::imshow("ARMNN MobileNet Example", test_image);
+ waitKey(2);
+ }
+ }
+ }
+ catch (armnn::Exception const& e)
+ {
+ BOOST_LOG_TRIVIAL(fatal) << "Armnn Error: " << e.what();
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+// This will run a test
+int RunTest(const std::string& modelFormat,
+ const std::string& inputTensorShapeStr,
+ const vector<armnn::BackendId>& computeDevice,
+ const std::string& modelPath,
+ const std::string& inputName,
+ const std::string& inputTensorDataFilePath,
+ const std::string& outputName,
+ bool enableProfiling,
+ const size_t subgraphId,
+ const std::shared_ptr<armnn::IRuntime>& runtime = nullptr)
+{
+ // Parse model binary flag from the model-format string we got from the command-line
+ bool isModelBinary;
+ if (modelFormat.find("bin") != std::string::npos)
+ {
+ isModelBinary = true;
+ }
+ else if (modelFormat.find("txt") != std::string::npos || modelFormat.find("text") != std::string::npos)
+ {
+ isModelBinary = false;
+ }
+ else
+ {
+ BOOST_LOG_TRIVIAL(fatal) << "Unknown model format: '" << modelFormat << "'. Please include 'binary' or 'text'";
+ return EXIT_FAILURE;
+ }
+
+ // Parse input tensor shape from the string we got from the command-line.
+ std::unique_ptr<armnn::TensorShape> inputTensorShape;
+ if (!inputTensorShapeStr.empty())
+ {
+ std::stringstream ss(inputTensorShapeStr);
+ std::vector<unsigned int> dims = ParseArray<unsigned int>(ss);
+ try
+ {
+ // Coverity fix: An exception of type armnn::InvalidArgumentException is thrown and never caught.
+ inputTensorShape = std::make_unique<armnn::TensorShape>(dims.size(), dims.data());
+ }
+ catch (const armnn::InvalidArgumentException& e)
+ {
+ BOOST_LOG_TRIVIAL(fatal) << "Cannot create tensor shape: " << e.what();
+ return EXIT_FAILURE;
+ }
+ }
+ // Forward to implementation based on the parser type
+ if (modelFormat.find("caffe") != std::string::npos)
+ {
+#if defined(ARMNN_CAFFE_PARSER)
+ return MainImpl<armnnCaffeParser::ICaffeParser, float>(modelPath.c_str(), isModelBinary, computeDevice,
+ inputName.c_str(), inputTensorShape.get(),
+ inputTensorDataFilePath.c_str(), outputName.c_str(),
+ enableProfiling, subgraphId, runtime);
+#else
+ BOOST_LOG_TRIVIAL(fatal) << "Not built with Caffe parser support.";
+ return EXIT_FAILURE;
+#endif
+ }
+ else if (modelFormat.find("onnx") != std::string::npos)
+ {
+#if defined(ARMNN_ONNX_PARSER)
+ return MainImpl<armnnOnnxParser::IOnnxParser, float>(modelPath.c_str(), isModelBinary, computeDevice,
+ inputName.c_str(), inputTensorShape.get(),
+ inputTensorDataFilePath.c_str(), outputName.c_str(),
+ enableProfiling, subgraphId, runtime);
+#else
+ BOOST_LOG_TRIVIAL(fatal) << "Not built with Onnx parser support.";
+ return EXIT_FAILURE;
+#endif
+ }
+ else if (modelFormat.find("tensorflow") != std::string::npos)
+ {
+#if defined(ARMNN_TF_PARSER)
+ return MainImpl<armnnTfParser::ITfParser, float>(modelPath.c_str(), isModelBinary, computeDevice,
+ inputName.c_str(), inputTensorShape.get(),
+ inputTensorDataFilePath.c_str(), outputName.c_str(),
+ enableProfiling, subgraphId, runtime);
+#else
+ BOOST_LOG_TRIVIAL(fatal) << "Not built with Tensorflow parser support.";
+ return EXIT_FAILURE;
+#endif
+ }
+ else if(modelFormat.find("tflite") != std::string::npos)
+ {
+#if defined(ARMNN_TF_LITE_PARSER)
+ if (! isModelBinary)
+ {
+ BOOST_LOG_TRIVIAL(fatal) << "Unknown model format: '" << modelFormat << "'. Only 'binary' format supported \
+ for tflite files";
+ return EXIT_FAILURE;
+ }
+ return MainImpl<armnnTfLiteParser::ITfLiteParser, float>(modelPath.c_str(), isModelBinary, computeDevice,
+ inputName.c_str(), inputTensorShape.get(),
+ inputTensorDataFilePath.c_str(), outputName.c_str(),
+ enableProfiling, subgraphId, runtime);
+#else
+ BOOST_LOG_TRIVIAL(fatal) << "Unknown model format: '" << modelFormat <<
+ "'. Please include 'caffe', 'tensorflow', 'tflite' or 'onnx'";
+ return EXIT_FAILURE;
+#endif
+ }
+ else
+ {
+ BOOST_LOG_TRIVIAL(fatal) << "Unknown model format: '" << modelFormat <<
+ "'. Please include 'caffe', 'tensorflow', 'tflite' or 'onnx'";
+ return EXIT_FAILURE;
+ }
+}
+
+int main(int argc, const char* argv[])
+{
+ // Configures logging for both the ARMNN library and this test program.
+#ifdef NDEBUG
+ armnn::LogSeverity level = armnn::LogSeverity::Info;
+#else
+ armnn::LogSeverity level = armnn::LogSeverity::Debug;
+#endif
+ armnn::ConfigureLogging(true, true, level);
+
+ std::string testCasesFile;
+
+ std::string modelFormat = "tensorflow-binary";
+ std::string modelPath = "/usr/share/arm/armnn/models/mobilenet_v1_1.0_224_frozen.pb";
+ std::string inputName = "input";
+ std::string inputTensorShapeStr = "1 224 224 3";
+ std::string inputTensorDataFilePath = "/usr/share/arm/armnn/testvecs/test2.mp4";
+ std::string outputName = "MobilenetV1/Predictions/Reshape_1";
+ std::vector<armnn::BackendId> computeDevices = {armnn::Compute::CpuAcc};
+ // Catch ctrl-c to ensure a clean exit
+ signal(SIGABRT, exit);
+ signal(SIGTERM, exit);
+
+ if (argc == 1)
+ {
+ return RunTest(modelFormat, inputTensorShapeStr, computeDevices,
+ modelPath, inputName, inputTensorDataFilePath, outputName, false, 1000);
+ }
+ else
+ {
+ size_t subgraphId = 0;
+ po::options_description desc("Options");
+ try
+ {
+ desc.add_options()
+ ("help", "Display usage information")
+ ("test-cases,t", po::value(&testCasesFile), "Path to a CSV file containing test cases to run. "
+ "If set, further parameters -- with the exception of compute device and concurrency -- will be ignored, "
+ "as they are expected to be defined in the file for each test in particular.")
+ ("concurrent,n", po::bool_switch()->default_value(false),
+ "Whether or not the test cases should be executed in parallel")
+ ("model-format,f", po::value(&modelFormat),
+ "caffe-binary, caffe-text, onnx-binary, onnx-text, tflite-binary, tensorflow-binary or tensorflow-text.")
+ ("model-path,m", po::value(&modelPath), "Path to model file, e.g. .caffemodel, .prototxt,"
+ " .tflite, .onnx")
+ ("compute,c", po::value<std::vector<armnn::BackendId>>()->multitoken(),
+ "The preferred order of devices to run layers on by default. Possible choices: CpuAcc, CpuRef, GpuAcc")
+ ("input-name,i", po::value(&inputName), "Identifier of the input tensor in the network.")
+ ("input-tensor-shape,s", po::value(&inputTensorShapeStr),
+ "The shape of the input tensor in the network as a flat array of integers separated by whitespace. "
+ "This parameter is optional, depending on the network.")
+ ("input-tensor-data,d", po::value(&inputTensorDataFilePath),
+ "Input test file name. It can be image/video clip file name or use 'camera_live_input' to select camera input.")
+ ("output-name,o", po::value(&outputName), "Identifier of the output tensor in the network.")
+ ("event-based-profiling,e", po::bool_switch()->default_value(false),
+ "Enables built in profiler. If unset, defaults to off.")
+ ("number_frame", po::value<size_t>(&subgraphId)->default_value(1), "Number of frames to process.");
+ }
+ catch (const std::exception& e)
+ {
+ // Coverity points out that default_value(...) can throw a bad_lexical_cast,
+ // and that desc.add_options() can throw boost::io::too_few_args.
+ // They really won't in any of these cases.
+ BOOST_ASSERT_MSG(false, "Caught unexpected exception");
+ BOOST_LOG_TRIVIAL(fatal) << "Fatal internal error: " << e.what();
+ return EXIT_FAILURE;
+ }
+
+ // Parses the command-line.
+ po::variables_map vm;
+ try
+ {
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+ }
+ catch (const po::error& e)
+ {
+ std::cerr << e.what() << std::endl << std::endl;
+ std::cerr << desc << std::endl;
+ return EXIT_FAILURE;
+ }
+
+ // Run single test
+ // Get the preferred order of compute devices.
+ std::vector<armnn::BackendId> computeDevices = vm["compute"].as<std::vector<armnn::BackendId>>();
+ bool enableProfiling = vm["event-based-profiling"].as<bool>();
+
+ // Remove duplicates from the list of compute devices.
+ RemoveDuplicateDevices(computeDevices);
+
+ return RunTest(modelFormat, inputTensorShapeStr, computeDevices,
+ modelPath, inputName, inputTensorDataFilePath, outputName, enableProfiling, subgraphId);
+ }
+}
+
--
1.9.1

View File

@ -1,60 +0,0 @@
From ee152f3b68f91c5fff336306d011becdcf3a6b17 Mon Sep 17 00:00:00 2001
From: Djordje Senicic <x0157990@ti.com>
Date: Sat, 24 Aug 2019 17:58:38 -0400
Subject: [PATCH] command line options for video port selection
- Add command line selection <0|1|2|3> of video port used for live camera input
Upstream-Status: Inappropriate [TI only test code]
Signed-off-by: Djordje Senicic <x0157990@ti.com>
---
tests/ArmnnExamples/ArmnnExamples.cpp | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/tests/ArmnnExamples/ArmnnExamples.cpp b/tests/ArmnnExamples/ArmnnExamples.cpp
index 638fc145..d1526539 100644
--- a/tests/ArmnnExamples/ArmnnExamples.cpp
+++ b/tests/ArmnnExamples/ArmnnExamples.cpp
@@ -316,10 +316,27 @@ int MainImpl(const char* modelPath,
int input_type = INPUT_IMAGE;
std::string filename = inputTensorDataFilePath;
- size_t i = filename.rfind("camera_live_input", filename.length());
+ size_t i = filename.rfind("camera_live_input", filename.length());
if (i != string::npos)
{
- cap = VideoCapture(1);
+ int vport = 1;
+ size_t loc_i = filename.rfind("camera_live_input0", filename.length());
+ if(loc_i != string::npos) vport = 0;
+ else {
+ loc_i = filename.rfind("camera_live_input1", filename.length());
+ if(loc_i != string::npos) vport = 1;
+ else {
+ loc_i = filename.rfind("camera_live_input2", filename.length());
+ if(loc_i != string::npos) vport = 2;
+ else {
+ loc_i = filename.rfind("camera_live_input3", filename.length());
+ if(loc_i != string::npos) vport = 3;
+ else std::cout << "Setting ports beyond 3 not supported - using default!" << std::endl;
+ }
+ }
+ }
+ std::cout << "Using video" << vport << std::endl;
+ cap = VideoCapture(vport);
namedWindow("ARMNN MobileNet Example", WINDOW_AUTOSIZE | CV_GUI_NORMAL);
input_type = INPUT_CAMERA; //camera input
}
@@ -609,7 +626,7 @@ int main(int argc, const char* argv[])
"The shape of the input tensor in the network as a flat array of integers separated by whitespace. "
"This parameter is optional, depending on the network.")
("input-tensor-data,d", po::value(&inputTensorDataFilePath),
- "Input test file name. It can be image/video clip file name or use 'camera_live_input' to select camera input.")
+ "Input test file name. It can be image/video clip file name or 'camera_live_input or camera_live_input<0|1|2|3>' to select camera input.")
("output-name,o", po::value(&outputName), "Identifier of the output tensor in the network.")
("event-based-profiling,e", po::bool_switch()->default_value(false),
"Enables built in profiler. If unset, defaults to off.")
--
2.17.1

View File

@ -1,28 +0,0 @@
From a3e266a2de7c45116428f4e21645a2657534191b Mon Sep 17 00:00:00 2001
From: Djordje Senicic <x0157990@ti.com>
Date: Mon, 26 Aug 2019 03:51:39 -0400
Subject: [PATCH] armnnexamples: update for 19.08 modifications
Upstream-Status: Inappropriate [TI only test code]
Signed-off-by: Djordje Senicic <x0157990@ti.com>
---
tests/ArmnnExamples/ArmnnExamples.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/ArmnnExamples/ArmnnExamples.cpp b/tests/ArmnnExamples/ArmnnExamples.cpp
index d1526539..c10a4fc0 100644
--- a/tests/ArmnnExamples/ArmnnExamples.cpp
+++ b/tests/ArmnnExamples/ArmnnExamples.cpp
@@ -310,7 +310,7 @@ int MainImpl(const char* modelPath,
params.m_OutputBindings = { outputName };
//params.m_EnableProfiling = enableProfiling;
params.m_SubgraphId = 0;
- InferenceModel<TParser, TDataType> model(params, enableProfiling, runtime);
+ InferenceModel<TParser, TDataType> model(params, enableProfiling, "", runtime);
VideoCapture cap;
int input_type = INPUT_IMAGE;
--
2.17.1

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6af3453b6a0238f9734bbeb13e006f07f7a7a459a978a21423555819415fa328
size 28695424

3
armnn-24.11.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ca85052373c19d6816e9842b732b5b3433fefddc302621adac897b1f5b64487a
size 29099331

View File

@ -1,18 +0,0 @@
--- armnn-24.08/include/armnn/Numpy.hpp.orig 2024-09-06 11:05:16.800066800 +0200
+++ armnn-24.08/include/armnn/Numpy.hpp 2024-09-06 11:05:58.717592900 +0200
@@ -157,7 +157,7 @@ namespace armnnNumpy
inline void CreateHeader(std::ifstream& ifStream, HeaderInfo& headerInfo, Header& header)
{
char stringBuffer[headerInfo.m_HeaderLen];
- ifStream.read(stringBuffer, headerInfo.m_HeaderLen);
+ ifStream.read(stringBuffer, static_cast<std::streamsize>(headerInfo.m_HeaderLen));
header.m_HeaderString = std::string(stringBuffer, headerInfo.m_HeaderLen);
// Remove new line character at the end of the string
@@ -403,4 +403,4 @@ namespace armnnNumpy
}
}
-#endif // NUMPY_HPP
\ No newline at end of file
+#endif // NUMPY_HPP

View File

@ -1,19 +0,0 @@
--- armnn-19.08.orig/tests/CMakeLists.txt 2019-10-17 09:11:02.836949176 +0200
+++ armnn-19.08/tests/CMakeLists.txt 2019-10-17 09:10:50.384869262 +0200
@@ -1,6 +1,3 @@
-find_package( OpenCV REQUIRED )
-include_directories( ${OpenCV_INCLUDE_DIRS} )
-
# UnitTests
include(CheckIncludeFiles)
@@ -368,6 +365,9 @@ if(BUILD_ARMNN_QUANTIZER)
endif()
if (BUILD_ARMNN_EXAMPLES)
+ find_package( OpenCV REQUIRED )
+ include_directories( ${OpenCV_INCLUDE_DIRS} )
+
set(ArmnnExamples_sources
ArmnnExamples/ArmnnExamples.cpp)

View File

@ -1,3 +1,22 @@
-------------------------------------------------------------------
Tue Dec 3 08:53:30 UTC 2024 - Guillaume GARDET <guillaume.gardet@opensuse.org>
- Remove downstream patches:
* 0003-add-more-test-command-line-arguments.patch
* 0005-add-armnn-mobilenet-test-example.patch
* 0006-armnn-mobilenet-test-example.patch
* 0009-command-line-options-for-video-port-selection.patch
* 0010-armnnexamples-update-for-19.08-modifications.patch
* armnn-fix_find_opencv.patch
-------------------------------------------------------------------
Mon Dec 2 12:59:30 UTC 2024 - Guillaume GARDET <guillaume.gardet@opensuse.org>
- Update to 24.11:
* Changelog: https://github.com/ARM-software/armnn/releases/tag/v24.11
- Drop upstream patch:
* armnn-fix-armv7.patch
-------------------------------------------------------------------
Fri Sep 6 13:29:47 UTC 2024 - Guillaume GARDET <guillaume.gardet@opensuse.org>

View File

@ -43,13 +43,6 @@
%else
%bcond_with armnn_tests
%endif
# Extra tests require opencv(3)-devel, but it is broken for Leap 15.1 - boo#1154091
%if 0%{?suse_version} > 1500 || 0%{?sle_version} >= 150200
# FIXME: disabled for now, as it fails since version 21.05
%bcond_with armnn_extra_tests
%else
%bcond_with armnn_extra_tests
%endif
# flatbuffers-devel is available on Leap 15.2+/SLE15SP2+
# But tensorflow-lite >= 2.10 is only avaialble on Tumbleweed
%if 0%{?suse_version} > 1500
@ -65,8 +58,8 @@
%bcond_with armnn_onnx
%endif
%define version_major 24
%define version_minor 08
%define version_lib 33
%define version_minor 11
%define version_lib 34
%define version_lib_testutils 3
%define version_lib_tfliteparser 24
%define version_lib_onnxparser 24
@ -79,15 +72,6 @@ Group: Development/Libraries/Other
URL: https://developer.arm.com/products/processors/machine-learning/arm-nn
Source0: https://github.com/ARM-software/armnn/archive/v%{version}.tar.gz#/armnn-%{version}.tar.gz
Source1: armnn-rpmlintrc
# PATCH-FIX-UPSTREAM - https://github.com/ARM-software/armnn/issues/786
Patch1: armnn-fix-armv7.patch
# PATCHES to add downstream ArmnnExamples binary - https://layers.openembedded.org/layerindex/recipe/87610/
Patch200: 0003-add-more-test-command-line-arguments.patch
Patch201: 0005-add-armnn-mobilenet-test-example.patch
Patch202: 0006-armnn-mobilenet-test-example.patch
Patch203: 0009-command-line-options-for-video-port-selection.patch
Patch204: 0010-armnnexamples-update-for-19.08-modifications.patch
Patch205: armnn-fix_find_opencv.patch
BuildRequires: ComputeLibrary-devel >= %{version_major}.%{version_minor}
BuildRequires: cmake >= 3.22
BuildRequires: gcc-c++
@ -105,10 +89,6 @@ BuildRequires: libboost_filesystem-devel >= 1.59
BuildRequires: libboost_program_options-devel >= 1.59
BuildRequires: libboost_system-devel >= 1.59
BuildRequires: libboost_test-devel >= 1.59
%if %{with armnn_extra_tests}
BuildRequires: libboost_log-devel >= 1.59
BuildRequires: libboost_thread-devel >= 1.59
%endif
%endif
%if %{with armnn_flatbuffers}
BuildRequires: flatbuffers-devel
@ -125,13 +105,6 @@ BuildRequires: ocl-icd-devel
BuildRequires: opencl-cpp-headers
BuildRequires: opencl-headers
%endif
%if %{with armnn_extra_tests}
%if 0%{?suse_version} > 1500
BuildRequires: opencv3-devel
%else
BuildRequires: opencv-devel
%endif
%endif
%if %{with armnn_onnx}
BuildRequires: python3-onnx
%endif
@ -201,29 +174,6 @@ modification across Arm Cortex CPUs and Arm Mali GPUs.
This package contains the development libraries and headers for armnn.
%if %{with armnn_extra_tests}
%package -n %{name}-extratests
Summary: Additionnal downstream tests for Arm NN
# Make sure we do not install both openCL and non-openCL (CPU only) versions.
Group: Development/Libraries/C and C++
Requires: %{name}
# Make sure we do not install both openCL and non-openCL (CPU only) versions.
%if "%{target}" == "opencl"
Conflicts: armnn-extratests
%else
Conflicts: armnn-opencl-extratests
%endif
%description -n %{name}-extratests
Arm NN is an inference engine for CPUs, GPUs and NPUs.
It bridges the gap between existing NN frameworks and the underlying IP.
It enables efficient translation of existing neural network frameworks,
such as TensorFlow Lite, allowing them to run efficiently without
modification across Arm Cortex CPUs and Arm Mali GPUs.
This package contains additionnal downstream tests for armnn.
%endif
%package -n libarmnn%{version_lib}%{?package_suffix}
Summary: libarmnn from armnn
Group: Development/Libraries/C and C++
@ -374,17 +324,6 @@ This package contains the libarmnnOnnxParser library from armnn.
%prep
%setup -q -n armnn-%{version}
%patch -P 1 -p1
%if %{with armnn_extra_tests}
%patch -P 200 -p1
%patch -P 201 -p1
%patch -P 202 -p1
%patch -P 203 -p1
%patch -P 204 -p1
%patch -P 205 -p1
# Add Boost log as downstream extra test requires it
sed -i 's/ find_package(Boost 1.59 REQUIRED COMPONENTS unit_test_framework)/find_package(Boost 1.59 REQUIRED COMPONENTS unit_test_framework filesystem system log program_options)/' ./cmake/GlobalConfig.cmake
%endif
%build
%if %{with armnn_onnx}
@ -451,11 +390,7 @@ protoc $PROTO --proto_path=. --proto_path=%{_includedir} --proto_path=$(dirname
-DBUILD_PYTHON_WHL=OFF \
-DBUILD_PYTHON_SRC=OFF \
%endif
%if %{with armnn_extra_tests}
-DBUILD_ARMNN_EXAMPLES=ON
%else
-DBUILD_ARMNN_EXAMPLES=OFF
%endif
%if 0%{?suse_version} > 1500
%cmake_build
@ -530,7 +465,6 @@ LD_LIBRARY_PATH="$(pwd)/build/" \
%if %{with armnn_tests}
%{_bindir}/ExecuteNetwork
%if %{with armnn_flatbuffers}
%{_bindir}/ArmnnConverter
%{_bindir}/TfLite*-Armnn
%endif
%if %{with armnn_onnx}
@ -541,11 +475,6 @@ LD_LIBRARY_PATH="$(pwd)/build/" \
%endif
%endif
%if %{with armnn_extra_tests}
%files -n %{name}-extratests
%{_bindir}/ArmnnExamples
%endif
%files -n libarmnn%{version_lib}%{?package_suffix}
%{_libdir}/libarmnn.so.*