IVGCVSW-2833 Add Dynamic Quantization
[platform/upstream/armnn.git] / src / armnnUtils / TensorUtils.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #include "TensorUtils.hpp"
7 #include <backendsCommon/ITensorHandle.hpp>
8
9 namespace armnnUtils
10 {
11
12 armnn::TensorShape GetTensorShape(unsigned int numberOfBatches,
13                                   unsigned int numberOfChannels,
14                                   unsigned int height,
15                                   unsigned int width,
16                                   const armnn::DataLayout dataLayout)
17 {
18     switch (dataLayout)
19     {
20         case armnn::DataLayout::NCHW:
21             return armnn::TensorShape({numberOfBatches, numberOfChannels, height, width});
22         case armnn::DataLayout::NHWC:
23             return armnn::TensorShape({numberOfBatches, height, width, numberOfChannels});
24         default:
25             throw armnn::InvalidArgumentException("Unknown data layout ["
26                                                   + std::to_string(static_cast<int>(dataLayout)) +
27                                                   "]", CHECK_LOCATION());
28     }
29 }
30
31 armnn::TensorInfo GetTensorInfo(unsigned int numberOfBatches,
32                                 unsigned int numberOfChannels,
33                                 unsigned int height,
34                                 unsigned int width,
35                                 const armnn::DataLayout dataLayout,
36                                 const armnn::DataType dataType)
37 {
38     switch (dataLayout)
39     {
40         case armnn::DataLayout::NCHW:
41             return armnn::TensorInfo({numberOfBatches, numberOfChannels, height, width}, dataType);
42         case armnn::DataLayout::NHWC:
43             return armnn::TensorInfo({numberOfBatches, height, width, numberOfChannels}, dataType);
44         default:
45             throw armnn::InvalidArgumentException("Unknown data layout ["
46                                                   + std::to_string(static_cast<int>(dataLayout)) +
47                                                   "]", CHECK_LOCATION());
48     }
49 }
50
51 std::pair<float, float> FindMinMax(armnn::ITensorHandle* tensorHandle)
52 {
53     auto tensor_data = static_cast<const float *>(tensorHandle->Map(true));
54     auto tensor_size = tensorHandle->GetShape().GetNumElements();
55
56     // Set min/max initially to first value in tensor
57     float min = tensor_data[0];
58     float max = tensor_data[0];
59
60     // Loop over rest of tensor and update min/max if necessary
61     for (unsigned int val = 1; val < tensor_size; val++)
62     {
63         if (tensor_data[val] < min)
64         {
65             min = tensor_data[val];
66         }
67         else if (tensor_data[val] > max)
68         {
69             max = tensor_data[val];
70         }
71     }
72
73     tensorHandle->Unmap();
74
75     return std::make_pair(min, max);
76 }
77
78 }