blob: 0932f229ccb6428c37864a2ffb587f9984f756d2 [file] [log] [blame]
Jan Eilerse339bf62020-11-10 18:43:23 +00001//
Teresa Charlinad1b3d72023-03-14 12:10:28 +00002// Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved.
Jan Eilerse339bf62020-11-10 18:43:23 +00003// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Narumol Prangnawarat4cf0fe32020-12-18 16:13:06 +00008#include <tensorflow/lite/c/common.h>
Jan Eilerse339bf62020-11-10 18:43:23 +00009#include <tensorflow/lite/interpreter.h>
10
Matthew Sloyan91c41712020-11-13 09:47:35 +000011#include <doctest/doctest.h>
12
Colm Donelaneff204a2023-11-28 15:46:09 +000013#include <armnn/BackendId.hpp>
Narumol Prangnawarat4cf0fe32020-12-18 16:13:06 +000014#include <half/half.hpp>
15
16using Half = half_float::half;
17
Colm Donelaneff204a2023-11-28 15:46:09 +000018namespace
19{
20/**
21 * Based on the compilation options capture subcases for the available backends. If "onlyTheseBackends" is NOT empty
22 * then we'll ignore any backend NOT listed in it.
23 *
24 * @param onlyTheseBackends limit the number of backends considered for sub casing. If empty all are considered.
25 * @return vector of backends that have been captured for sub casing.
26 */
27std::vector<armnn::BackendId> CaptureAvailableBackends(const std::vector<armnn::BackendId>& onlyTheseBackends)
28{
29 std::vector<armnn::BackendId> availableBackends;
30#if defined(ARMNNREF_ENABLED)
31 // Careful logic here. An empty onlyTheseBackends means we always evaluate.
32 if (onlyTheseBackends.empty() || (std::find(onlyTheseBackends.begin(), onlyTheseBackends.end(),
33 armnn::Compute::CpuRef) != onlyTheseBackends.end()))
34 {
35 SUBCASE("CpuRef")
36 {
37 availableBackends.push_back({ armnn::Compute::CpuRef });
38 }
39 }
40#endif
41#if defined(ARMCOMPUTENEON_ENABLED)
42 // Careful logic here. An empty onlyTheseBackends means we always evaluate.
43 if (onlyTheseBackends.empty() || (std::find(onlyTheseBackends.begin(), onlyTheseBackends.end(),
44 armnn::Compute::CpuAcc) != onlyTheseBackends.end()))
45 {
46 SUBCASE("CpuAcc")
47 {
48 availableBackends.push_back({ armnn::Compute::CpuAcc });
49 }
50 }
51#endif
52#if defined(ARMCOMPUTECL_ENABLED)
53 if (onlyTheseBackends.empty() || (std::find(onlyTheseBackends.begin(), onlyTheseBackends.end(),
54 armnn::Compute::GpuAcc) != onlyTheseBackends.end()))
55 {
56 SUBCASE("GpuAcc")
57 {
58 availableBackends.push_back({ armnn::Compute::GpuAcc });
59 }
60 }
61#endif
62 CAPTURE(availableBackends);
63 return availableBackends;
64}
65
66} // namespace
Jan Eilerse339bf62020-11-10 18:43:23 +000067namespace armnnDelegate
68{
69
Matthew Sloyanebe392d2023-03-30 10:12:08 +010070constexpr const char* FILE_IDENTIFIER = "TFL3";
Finn Williams63e6ace2021-02-17 18:12:39 +000071
Jan Eilersfe73b042020-11-18 10:36:46 +000072/// Can be used to compare bool data coming from a tflite interpreter
73/// Boolean types get converted to a bit representation in a vector. vector.data() returns a void pointer
74/// instead of a pointer to bool. Therefore a special function to compare to vector of bool is required
Matthew Sloyanebe392d2023-03-30 10:12:08 +010075void CompareData(std::vector<bool>& tensor1, std::vector<bool>& tensor2, size_t tensorSize);
Jan Eilersfe73b042020-11-18 10:36:46 +000076void CompareData(bool tensor1[], bool tensor2[], size_t tensorSize);
77
78/// Can be used to compare float data coming from a tflite interpreter with a tolerance of limit_of_float*100
Jan Eilers3812fbc2020-11-17 19:06:35 +000079void CompareData(float tensor1[], float tensor2[], size_t tensorSize);
Jan Eilersfe73b042020-11-18 10:36:46 +000080
Narumol Prangnawarat7684b182021-08-12 14:48:15 +010081/// Can be used to compare float data coming from a tflite interpreter with a given percentage tolerance
82void CompareData(float tensor1[], float tensor2[], size_t tensorSize, float percentTolerance);
83
Jan Eilersfe73b042020-11-18 10:36:46 +000084/// Can be used to compare int8_t data coming from a tflite interpreter with a tolerance of 1
Jan Eilers3812fbc2020-11-17 19:06:35 +000085void CompareData(int8_t tensor1[], int8_t tensor2[], size_t tensorSize);
Jan Eilersfe73b042020-11-18 10:36:46 +000086
87/// Can be used to compare uint8_t data coming from a tflite interpreter with a tolerance of 1
Jan Eilers3812fbc2020-11-17 19:06:35 +000088void CompareData(uint8_t tensor1[], uint8_t tensor2[], size_t tensorSize);
Jan Eilersfe73b042020-11-18 10:36:46 +000089
90/// Can be used to compare int16_t data coming from a tflite interpreter with a tolerance of 1
Jan Eilers3812fbc2020-11-17 19:06:35 +000091void CompareData(int16_t tensor1[], int16_t tensor2[], size_t tensorSize);
92
Sadik Armagan29b49cf2021-02-22 18:09:07 +000093/// Can be used to compare int32_t data coming from a tflite interpreter with a tolerance of 1
94void CompareData(int32_t tensor1[], int32_t tensor2[], size_t tensorSize);
95
Narumol Prangnawarat4cf0fe32020-12-18 16:13:06 +000096/// Can be used to compare Half (Float16) data with a tolerance of limit_of_float*100
97void CompareData(Half tensor1[], Half tensor2[], size_t tensorSize);
98
99/// Can be used to compare TfLiteFloat16 data coming from a tflite interpreter
100void CompareData(TfLiteFloat16 tensor1[], TfLiteFloat16 tensor2[], size_t tensorSize);
101
102/// Can be used to compare Half (Float16) data and TfLiteFloat16 data coming from a tflite interpreter
103void CompareData(TfLiteFloat16 tensor1[], Half tensor2[], size_t tensorSize);
Jan Eilers3812fbc2020-11-17 19:06:35 +0000104
Matthew Sloyanebe392d2023-03-30 10:12:08 +0100105/// Can be used to compare the output tensor shape
106/// Example usage can be found in ControlTestHelper.hpp
107void CompareOutputShape(const std::vector<int32_t>& tfLiteDelegateShape,
108 const std::vector<int32_t>& armnnDelegateShape,
109 const std::vector<int32_t>& expectedOutputShape);
110
111/// Can be used to compare the output tensor values
Jan Eilersfe73b042020-11-18 10:36:46 +0000112/// Example usage can be found in ControlTestHelper.hpp
Matthew Sloyan91c41712020-11-13 09:47:35 +0000113template <typename T>
Matthew Sloyanebe392d2023-03-30 10:12:08 +0100114void CompareOutputData(std::vector<T>& tfLiteDelegateOutputs,
115 std::vector<T>& armnnDelegateOutputs,
116 std::vector<T>& expectedOutputValues)
Matthew Sloyan91c41712020-11-13 09:47:35 +0000117{
Colm Donelaneff204a2023-11-28 15:46:09 +0000118 armnnDelegate::CompareData(expectedOutputValues.data(), armnnDelegateOutputs.data(), expectedOutputValues.size());
Matthew Sloyanebe392d2023-03-30 10:12:08 +0100119 armnnDelegate::CompareData(tfLiteDelegateOutputs.data(), expectedOutputValues.data(), expectedOutputValues.size());
120 armnnDelegate::CompareData(tfLiteDelegateOutputs.data(), armnnDelegateOutputs.data(), expectedOutputValues.size());
Matthew Sloyan91c41712020-11-13 09:47:35 +0000121}
122
Colm Donelaneff204a2023-11-28 15:46:09 +0000123} // namespace armnnDelegate