blob: 3bf3db7967b4689d696580805a28bee7a021ec0b [file] [log] [blame]
Derek Lambertif30f7d32019-04-09 10:25:02 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
8#include "BaseIterator.hpp"
Matteo Martincighe011d202019-11-28 11:35:47 +00009
10#include <armnnUtils/FloatingPointConverter.hpp>
11#include <armnnUtils/TensorUtils.hpp>
Derek Lambertif30f7d32019-04-09 10:25:02 +010012
13namespace armnn
14{
15
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +000016namespace
17{
18
19inline std::unique_ptr<Decoder<float>> MakeSigned32PerAxisDecoder(const TensorInfo& info, const void* data)
20{
Jan Eilers53ef7952021-06-02 12:01:25 +010021 return std::make_unique<ScaledInt32PerAxisDecoder>(static_cast<const int32_t*>(data), info);
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +000022}
23
24inline std::unique_ptr<Decoder<float>> MakeSigned32Decoder(const TensorInfo& info, const void* data)
25{
26 if(info.HasMultipleQuantizationScales())
27 {
28 // NOTE: If we have multiple quantization scales, we create a ScaledInt32PerAxisDecoder.
29 // This will be used to decode per-axis quantized convolution biases.
30 return MakeSigned32PerAxisDecoder(info, data);
31 }
32 else
33 {
34 if (info.GetQuantizationDim().has_value())
35 {
36 // NOTE: Even though we only have a single quantization scale, if the quantization
37 // dimension is set, the tensor has per-axis quantization and we need to create a
38 // ScaledInt32PerAxisDecoder
39 return MakeSigned32PerAxisDecoder(info, data);
40 }
41
42 const float scale = info.GetQuantizationScale();
43 if (scale == 0.f)
44 {
45 // NOTE:: If no quantization scale is set, we create an Int32Decoder, which simply
46 // casts the int value to float. This will be used for any INT32 data other than
47 // convolution biases.
48 return std::make_unique<Int32Decoder>(static_cast<const int32_t*>(data));
49 }
50
51 // NOTE: If we only have a single (non-zero) quantization scale and no quantization
52 // dimension is specified, we need to create a ScaledInt32Decoder. This will be used
53 // to decode per-tensor quantized convolution biases.
54 return std::make_unique<ScaledInt32Decoder>(static_cast<const int32_t*>(data), scale);
55 }
56}
57
58} // anonymous namespace
59
Derek Lambertif30f7d32019-04-09 10:25:02 +010060template<typename T>
Matthew Benthamc394a6d2019-06-24 12:51:25 +010061inline std::unique_ptr<Decoder<T>> MakeDecoder(const TensorInfo& info, const void* data = nullptr);
Derek Lambertif30f7d32019-04-09 10:25:02 +010062
63template<>
Nattapat Chaimanowongae2c5f02019-04-24 16:19:57 +010064inline std::unique_ptr<Decoder<float>> MakeDecoder(const TensorInfo& info, const void* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +010065{
66 switch(info.GetDataType())
67 {
Ryan OShea9add1202020-02-07 10:06:33 +000068 case DataType::QAsymmS8:
69 {
70 return std::make_unique<QASymmS8Decoder>(
71 static_cast<const int8_t*>(data),
72 info.GetQuantizationScale(),
73 info.GetQuantizationOffset());
74 }
Derek Lambertif90c56d2020-01-10 17:14:08 +000075 case DataType::QAsymmU8:
Derek Lambertif30f7d32019-04-09 10:25:02 +010076 {
77 return std::make_unique<QASymm8Decoder>(
78 static_cast<const uint8_t*>(data),
79 info.GetQuantizationScale(),
80 info.GetQuantizationOffset());
81 }
Derek Lambertif90c56d2020-01-10 17:14:08 +000082 case DataType::QSymmS16:
Derek Lambertif30f7d32019-04-09 10:25:02 +010083 {
84 return std::make_unique<QSymm16Decoder>(
85 static_cast<const int16_t*>(data),
86 info.GetQuantizationScale(),
87 info.GetQuantizationOffset());
88 }
Matthew Jacksone69c3992019-09-09 14:31:21 +010089 case DataType::Float16:
Derek Lambertif30f7d32019-04-09 10:25:02 +010090 {
Matthew Jacksone69c3992019-09-09 14:31:21 +010091 return std::make_unique<Float16Decoder>(static_cast<const Half*>(data));
Derek Lambertif30f7d32019-04-09 10:25:02 +010092 }
Matthew Jacksone69c3992019-09-09 14:31:21 +010093 case DataType::Float32:
94 {
95 return std::make_unique<Float32Decoder>(static_cast<const float*>(data));
96 }
97 case DataType::Signed32:
Mike Kelly9b398322019-05-22 17:21:49 +010098 {
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +000099 return MakeSigned32Decoder(info, data);
Mike Kelly9b398322019-05-22 17:21:49 +0100100 }
Finn Williamsfd271062019-12-04 14:27:27 +0000101 case DataType::QSymmS8:
102 {
Derek Lambertid466a542020-01-22 15:37:29 +0000103 if (info.HasPerAxisQuantization())
104 {
105 std::pair<unsigned int, std::vector<float>> params = armnnUtils::GetPerAxisParams(info);
Jan Eilers53ef7952021-06-02 12:01:25 +0100106 return std::make_unique<QSymm8PerAxisDecoder>(static_cast<const int8_t*>(data), info);
Derek Lambertid466a542020-01-22 15:37:29 +0000107 }
108 else
109 {
110 return std::make_unique<QSymmS8Decoder>(
111 static_cast<const int8_t*>(data),
112 info.GetQuantizationScale(),
113 info.GetQuantizationOffset());
114 }
Finn Williamsfd271062019-12-04 14:27:27 +0000115 }
Sadik Armaganb60dd242020-03-19 13:53:16 +0000116 case armnn::DataType::Boolean:
117 {
118 return std::make_unique<BooleanDecoder>(static_cast<const uint8_t*>(data));
119 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100120 default:
121 {
Teresa Charlin5306dc82023-10-30 22:29:58 +0000122 throw InvalidArgumentException("Unsupported target Data Type!");
123 break;
124 }
125 }
126 return nullptr;
127}
128
129template<>
130inline std::unique_ptr<Decoder<double_t>> MakeDecoder(const TensorInfo& info, const void* data)
131{
132 switch(info.GetDataType())
133 {
134 case DataType::Signed64:
135 {
136 return std::make_unique<Int64Decoder>(static_cast<const int64_t*>(data));
137 }
138 default:
139 {
140 throw InvalidArgumentException("Cannot decode to double. Unsupported origin Data Type!");
Derek Lambertif30f7d32019-04-09 10:25:02 +0100141 break;
142 }
143 }
144 return nullptr;
145}
146
Finn Williamscbd2c232020-06-22 15:58:32 +0100147template<>
James Conroyaba90cd2020-11-06 16:28:18 +0000148inline std::unique_ptr<Decoder<bool>> MakeDecoder(const TensorInfo& info, const void* data)
149{
150 switch(info.GetDataType())
151 {
152 case DataType::Boolean:
153 {
154 return std::make_unique<BooleanDecoderBool>(static_cast<const uint8_t*>(data));
155 }
156 default:
157 {
Teresa Charlin5306dc82023-10-30 22:29:58 +0000158 throw InvalidArgumentException("Cannot decode to bool. Unsupported origin Data Type!");
James Conroyaba90cd2020-11-06 16:28:18 +0000159 break;
160 }
161 }
162 return nullptr;
163}
164
165template<>
Finn Williamscbd2c232020-06-22 15:58:32 +0100166inline std::unique_ptr<Decoder<int32_t>> MakeDecoder(const TensorInfo& info, const void* data)
167{
168 switch(info.GetDataType())
169 {
170 case DataType::Signed32:
171 {
172 return std::make_unique<Int32ToInt32tDecoder>(static_cast<const int32_t*>(data));
173 }
174 default:
175 {
Teresa Charlin5306dc82023-10-30 22:29:58 +0000176 throw InvalidArgumentException("Cannot decode to int32. Unsupported origin Data Type!");
Finn Williamscbd2c232020-06-22 15:58:32 +0100177 break;
178 }
179 }
180 return nullptr;
181}
182
Nattapat Chaimanowongae2c5f02019-04-24 16:19:57 +0100183} //namespace armnn