2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
6 #include "TensorUtils.hpp"
7 #include <backendsCommon/ITensorHandle.hpp>
9 #include <boost/assert.hpp>
10 #include <boost/format.hpp>
11 #include <boost/numeric/conversion/cast.hpp>
16 armnn::TensorShape GetTensorShape(unsigned int numberOfBatches,
17 unsigned int numberOfChannels,
20 const armnn::DataLayout dataLayout)
24 case armnn::DataLayout::NCHW:
25 return armnn::TensorShape({numberOfBatches, numberOfChannels, height, width});
26 case armnn::DataLayout::NHWC:
27 return armnn::TensorShape({numberOfBatches, height, width, numberOfChannels});
29 throw armnn::InvalidArgumentException("Unknown data layout ["
30 + std::to_string(static_cast<int>(dataLayout)) +
31 "]", CHECK_LOCATION());
35 armnn::TensorInfo GetTensorInfo(unsigned int numberOfBatches,
36 unsigned int numberOfChannels,
39 const armnn::DataLayout dataLayout,
40 const armnn::DataType dataType)
44 case armnn::DataLayout::NCHW:
45 return armnn::TensorInfo({numberOfBatches, numberOfChannels, height, width}, dataType);
46 case armnn::DataLayout::NHWC:
47 return armnn::TensorInfo({numberOfBatches, height, width, numberOfChannels}, dataType);
49 throw armnn::InvalidArgumentException("Unknown data layout ["
50 + std::to_string(static_cast<int>(dataLayout)) +
51 "]", CHECK_LOCATION());
55 std::pair<float, float> FindMinMax(armnn::ITensorHandle* tensorHandle)
57 auto tensor_data = static_cast<const float *>(tensorHandle->Map(true));
58 auto tensor_size = tensorHandle->GetShape().GetNumElements();
60 // Set min/max initially to first value in tensor
61 float min = tensor_data[0];
62 float max = tensor_data[0];
64 // Loop over rest of tensor and update min/max if necessary
65 for (unsigned int val = 1; val < tensor_size; val++)
67 if (tensor_data[val] < min)
69 min = tensor_data[val];
71 else if (tensor_data[val] > max)
73 max = tensor_data[val];
77 tensorHandle->Unmap();
79 return std::make_pair(min, max);
82 armnn::TensorShape ExpandDims(const armnn::TensorShape& tensorShape, int axis)
84 unsigned int outputDim = tensorShape.GetNumDimensions() + 1;
86 if (axis < -boost::numeric_cast<int>(outputDim) || axis > boost::numeric_cast<int>(tensorShape.GetNumDimensions()))
88 throw armnn::InvalidArgumentException(
89 boost::str(boost::format("Invalid expansion axis %1% for %2%D input tensor. %3%") %
91 tensorShape.GetNumDimensions() %
92 CHECK_LOCATION().AsString()));
97 axis = boost::numeric_cast<int>(outputDim) + axis;
100 std::vector<unsigned int> outputShape;
101 for (unsigned int i = 0; i < tensorShape.GetNumDimensions(); ++i)
103 outputShape.push_back(tensorShape[i]);
105 outputShape.insert(outputShape.begin() + axis, 1);
107 return armnn::TensorShape(outputDim, outputShape.data());