diff --git a/0003-add-more-test-command-line-arguments.patch b/0003-add-more-test-command-line-arguments.patch deleted file mode 100644 index 06d4354..0000000 --- a/0003-add-more-test-command-line-arguments.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 964cb82f3b811aec6663255ab0aa589f0a3be0ee Mon Sep 17 00:00:00 2001 -From: Qin Su -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 ---- - 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 - diff --git a/0005-add-armnn-mobilenet-test-example.patch b/0005-add-armnn-mobilenet-test-example.patch deleted file mode 100644 index 987635c..0000000 --- a/0005-add-armnn-mobilenet-test-example.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 99a6c339f1828d3cd1b193cf702bada9011d900b Mon Sep 17 00:00:00 2001 -From: Djordje Senicic -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 -Signed-off-by: Djordje Senicic -[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 - diff --git a/0006-armnn-mobilenet-test-example.patch b/0006-armnn-mobilenet-test-example.patch deleted file mode 100644 index fd2e210..0000000 --- a/0006-armnn-mobilenet-test-example.patch +++ /dev/null @@ -1,680 +0,0 @@ -From 4d5e7db268a4f816e24449e8ad011e35890f0c7e Mon Sep 17 00:00:00 2001 -From: Qin Su -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 - -[Guillaume's update: s#Logging.hpp#armnn/Logging.hpp#] -[Guillaume's update: Add #include ] -[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 -+#include -+ -+#include -+#include -+ -+#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 /*#include "CsvReader.hpp"*/ -+#include "../InferenceTest.hpp" -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "opencv2/core.hpp" -+#include "opencv2/imgproc.hpp" -+#include "opencv2/highgui.hpp" -+#include "opencv2/videoio.hpp" -+#include -+ -+using namespace cv; -+ -+#define INPUT_IMAGE 0 -+#define INPUT_VIDEO 1 -+#define INPUT_CAMERA 2 -+ -+Mat test_image; -+Rect rectCrop; -+ -+time_point predictStart; -+time_point 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 m_image; -+}; -+// Load a single image -+std::unique_ptr 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 ret(new ImageData); -+ ret->m_width = static_cast(img.cols); -+ ret->m_height = static_cast(img.rows); -+ ret->m_chnum = static_cast(img.channels()); -+ ret->m_size = static_cast(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(img.data[i]); -+ } -+ return ret; -+} -+// to resize input tensor size -+std::vector ResizeBilinear(std::vector input, -+ const unsigned int inWidth, -+ const unsigned int inHeight, -+ const unsigned int inChnum, -+ const unsigned int outputWidth, -+ const unsigned int outputHeight) -+{ -+ std::vector 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(inputHeight) / boost::numeric_cast(outputHeight); -+ const float scaleX = boost::numeric_cast(inputWidth) / boost::numeric_cast(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(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(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(x) * scaleX; -+ const float fix = floorf(ix); -+ const unsigned int x0 = boost::numeric_cast(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(l)/255.0f; -+ } -+ } -+ } -+ return out; -+} -+ -+namespace -+{ -+ -+ // Configure boost::program_options for command-line parsing and validation. -+ namespace po = boost::program_options; -+ -+ template -+ std::vector ParseArrayImpl(std::istream& stream, TParseElementFunc parseElementFunc) -+ { -+ std::vector result; -+ // Processes line-by-line. -+ std::string line; -+ while (std::getline(stream, line)) -+ { -+ std::vector 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 -+ std::vector ParseArray(std::istream& stream); -+ template<> -+ std::vector ParseArray(std::istream& stream) -+ { -+ return ParseArrayImpl(stream, -+ [](const std::string& s) { return boost::numeric_cast(std::stoi(s)); }); -+ } -+ void RemoveDuplicateDevices(std::vector& 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 -+int MainImpl(const char* modelPath, -+ bool isModelBinary, -+ const std::vector& 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& runtime = nullptr) -+{ -+ // Loads input tensor. -+ std::vector input; -+ std::vector input_resized; -+ using TContainer = mapbox::util::variant, std::vector, std::vector>; -+ -+ try -+ { -+ // Creates an InferenceModel, which will parse the model and load it into an IRuntime. -+ typename InferenceModel::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 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 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 inputDataContainer(1, std::move(input_resized)); -+ -+ // Set up output data container -+ std::vector outputDataContainers; -+ outputDataContainers.push_back(std::vector(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(predictEnd - predictStart).count(); -+ double preformance_ret = static_cast(1.0/timeTakenS); -+ -+ //retrieve output -+ std::vector& outputData = (mapbox::util::get>(outputDataContainers[0])); -+ //output TOP predictions -+ std::string predict_target_name; -+ // find the out with the highest confidence -+ int label = static_cast(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(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(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& 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& 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 inputTensorShape; -+ if (!inputTensorShapeStr.empty()) -+ { -+ std::stringstream ss(inputTensorShapeStr); -+ std::vector dims = ParseArray(ss); -+ try -+ { -+ // Coverity fix: An exception of type armnn::InvalidArgumentException is thrown and never caught. -+ inputTensorShape = std::make_unique(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(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(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(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(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 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>()->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(&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 computeDevices = vm["compute"].as>(); -+ bool enableProfiling = vm["event-based-profiling"].as(); -+ -+ // Remove duplicates from the list of compute devices. -+ RemoveDuplicateDevices(computeDevices); -+ -+ return RunTest(modelFormat, inputTensorShapeStr, computeDevices, -+ modelPath, inputName, inputTensorDataFilePath, outputName, enableProfiling, subgraphId); -+ } -+} -+ --- -1.9.1 - diff --git a/0009-command-line-options-for-video-port-selection.patch b/0009-command-line-options-for-video-port-selection.patch deleted file mode 100644 index bb6b505..0000000 --- a/0009-command-line-options-for-video-port-selection.patch +++ /dev/null @@ -1,60 +0,0 @@ -From ee152f3b68f91c5fff336306d011becdcf3a6b17 Mon Sep 17 00:00:00 2001 -From: Djordje Senicic -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 ---- - 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 - diff --git a/0010-armnnexamples-update-for-19.08-modifications.patch b/0010-armnnexamples-update-for-19.08-modifications.patch deleted file mode 100644 index 60f36a4..0000000 --- a/0010-armnnexamples-update-for-19.08-modifications.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a3e266a2de7c45116428f4e21645a2657534191b Mon Sep 17 00:00:00 2001 -From: Djordje Senicic -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 ---- - 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 model(params, enableProfiling, runtime); -+ InferenceModel model(params, enableProfiling, "", runtime); - - VideoCapture cap; - int input_type = INPUT_IMAGE; --- -2.17.1 - diff --git a/armnn-24.08.tar.gz b/armnn-24.08.tar.gz deleted file mode 100644 index 82d2a31..0000000 --- a/armnn-24.08.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6af3453b6a0238f9734bbeb13e006f07f7a7a459a978a21423555819415fa328 -size 28695424 diff --git a/armnn-24.11.tar.gz b/armnn-24.11.tar.gz new file mode 100644 index 0000000..d4c9da2 --- /dev/null +++ b/armnn-24.11.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca85052373c19d6816e9842b732b5b3433fefddc302621adac897b1f5b64487a +size 29099331 diff --git a/armnn-fix-armv7.patch b/armnn-fix-armv7.patch deleted file mode 100644 index 3a33d9d..0000000 --- a/armnn-fix-armv7.patch +++ /dev/null @@ -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(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 diff --git a/armnn-fix_find_opencv.patch b/armnn-fix_find_opencv.patch deleted file mode 100644 index 68d6b94..0000000 --- a/armnn-fix_find_opencv.patch +++ /dev/null @@ -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) - diff --git a/armnn.changes b/armnn.changes index f781228..2341069 100644 --- a/armnn.changes +++ b/armnn.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Tue Dec 3 08:53:30 UTC 2024 - Guillaume GARDET + +- 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 + +- 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 diff --git a/armnn.spec b/armnn.spec index d1ec4e6..6b0880b 100644 --- a/armnn.spec +++ b/armnn.spec @@ -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.*