blob: a1a8d2a47539d5c0430ff1c48536701b762763c5 [file] [log] [blame]
telsoa01c577f2c2018-08-31 09:22:23 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa01c577f2c2018-08-31 09:22:23 +01004//
5
6#pragma once
7
telsoa01c577f2c2018-08-31 09:22:23 +01008#include "ITensorHandle.hpp"
Matteo Martincigh747ef822018-12-18 09:26:39 +00009#include "CpuTensorHandle.hpp"
telsoa01c577f2c2018-08-31 09:22:23 +010010
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000011#include <armnn/Tensor.hpp>
12
Matteo Martincigh747ef822018-12-18 09:26:39 +000013#include <Permute.hpp>
14#include <Profiling.hpp>
15#include <Half.hpp>
16
telsoa01c577f2c2018-08-31 09:22:23 +010017#include <boost/cast.hpp>
18
19namespace armnn
20{
21namespace
22{
Matteo Martincigh747ef822018-12-18 09:26:39 +000023
telsoa01c577f2c2018-08-31 09:22:23 +010024template<typename ArrayType, typename Arg>
25void AssignValues(unsigned int num, unsigned int& idx, const ArrayType& array, Arg& arg)
26{
Matteo Martincigh747ef822018-12-18 09:26:39 +000027 if (idx >= num)
28 {
29 return;
30 }
telsoa01c577f2c2018-08-31 09:22:23 +010031
Matteo Martincigh747ef822018-12-18 09:26:39 +000032 arg = array[(num - 1) - idx];
33 idx++;
34}
telsoa01c577f2c2018-08-31 09:22:23 +010035
36template<typename T, typename ArrayType, typename ...Args>
37void AssignValues(unsigned int num, unsigned int idx, const ArrayType& array, T& assignee, Args& ... args)
38{
Matteo Martincigh747ef822018-12-18 09:26:39 +000039 AssignValues(num, idx, array, assignee);
telsoa01c577f2c2018-08-31 09:22:23 +010040
Matteo Martincigh747ef822018-12-18 09:26:39 +000041 AssignValues(num, idx, array, args...);
telsoa01c577f2c2018-08-31 09:22:23 +010042}
Matteo Martincigh747ef822018-12-18 09:26:39 +000043
44} // anonymous namespace
telsoa01c577f2c2018-08-31 09:22:23 +010045
46template<typename CopyFunc>
47void CopyTensorContentsGeneric(const ITensorHandle* srcTensor, ITensorHandle* dstTensor, CopyFunc copy)
48{
49 static_assert(MaxNumOfTensorDimensions == 4, "Please update CopyTensorContents");
50
51 TensorShape srcStrides = srcTensor->GetStrides();
52 const TensorShape& srcShape = srcTensor->GetShape();
53 TensorShape dstStrides = dstTensor->GetStrides();
54 const TensorShape& dstShape = dstTensor->GetShape();
55
56 size_t srcBatches = 1;
57 size_t srcChannels = 1;
58 size_t srcHeight = 1;
59 size_t srcWidth = 1;
60 AssignValues(srcShape.GetNumDimensions(),0, srcShape,
61 srcWidth,
62 srcHeight,
63 srcChannels,
64 srcBatches);
65
66 size_t srcBatchStride = 0;
67 size_t srcChannelStride = 0;
68 size_t srcHeightStride = 0;
69 size_t srcWidthStride = 0;
70 AssignValues(srcStrides.GetNumDimensions(),0, srcStrides,
71 srcWidthStride,
72 srcHeightStride,
73 srcChannelStride,
74 srcBatchStride);
75
76 size_t dstBatches = 1;
77 size_t dstChannels = 1;
78 size_t dstHeight = 1;
79 size_t dstWidth = 1;
80 AssignValues(dstShape.GetNumDimensions(),0, dstShape,
81 dstWidth,
82 dstHeight,
83 dstChannels,
84 dstBatches);
85
86 size_t dstBatchStride = 0;
87 size_t dstChannelStride = 0;
88 size_t dstHeightStride = 0;
89 size_t dstWidthStride = 0;
90 AssignValues(dstStrides.GetNumDimensions(),0, dstStrides,
91 dstWidthStride,
92 dstHeightStride,
93 dstChannelStride,
94 dstBatchStride);
95
Sadik Armaganbf86d512018-12-24 09:01:31 +000096 const unsigned char* srcData;
97 unsigned char* dstData;
98 {
99 ARMNN_SCOPED_PROFILING_EVENT(Compute::Undefined, "Synchronize buffers");
100 srcData = static_cast<const uint8_t *>(srcTensor->Map());
101 dstData = static_cast<uint8_t *>(dstTensor->Map());
102 }
telsoa01c577f2c2018-08-31 09:22:23 +0100103
104 size_t copyLength = std::min(srcWidth*srcWidthStride, dstWidth*dstWidthStride);
105 size_t copyHeight = std::min(srcHeight, dstHeight);
106 size_t copyChannels = std::min(srcChannels, dstChannels);
107 size_t copyBatches = std::min(srcBatches, dstBatches);
108
109 for(unsigned int b=0; b < copyBatches; ++b)
110 {
111 auto srcPtrBatch = srcData;
112 auto dstPtrBatch = dstData;
113 for (unsigned int c=0; c< copyChannels; ++c)
114 {
115 auto srcPtrChannel = srcData;
116 auto dstPtrChannel = dstData;
117 for (unsigned int h=0; h < copyHeight; ++h)
118 {
119 copy(dstData, srcData, copyLength);
120 dstData += dstHeightStride;
121 srcData += srcHeightStride;
122 }
123 dstData += (static_cast<long>(dstChannelStride) - (dstData - dstPtrChannel));
124 srcData += (static_cast<long>(srcChannelStride) - (srcData - srcPtrChannel));
125 }
126 dstData += (static_cast<long>(dstBatchStride)-(dstData - dstPtrBatch));
127 srcData += (static_cast<long>(srcBatchStride)-(srcData - srcPtrBatch));
128 }
129
130 srcTensor->Unmap();
131 dstTensor->Unmap();
132}
133
134template <typename SrcTensorHandleType, typename DstTensorHandleType, typename DescriptorType>
135void GatherTensorHandlePairs(const DescriptorType& descriptor,
136 std::vector<std::pair<SrcTensorHandleType*, DstTensorHandleType*>>& tensorHandlePairs)
137{
138 const unsigned int numInputs = static_cast<unsigned int>(descriptor.m_Inputs.size());
139 tensorHandlePairs.reserve(numInputs);
140
141 for (unsigned int i = 0; i < numInputs; ++i)
142 {
143 SrcTensorHandleType* const srcTensorHandle = boost::polymorphic_downcast<SrcTensorHandleType*>(
144 descriptor.m_Inputs[i]);
145 DstTensorHandleType* const dstTensorHandle = boost::polymorphic_downcast<DstTensorHandleType*>(
146 descriptor.m_Outputs[i]);
147
148 tensorHandlePairs.emplace_back(srcTensorHandle, dstTensorHandle);
149 }
150}
151
Matteo Martincigh747ef822018-12-18 09:26:39 +0000152armnn::ConstTensor PermuteTensor(const ConstCpuTensorHandle* tensor,
153 const PermutationVector& permutationVector,
154 void* permuteBuffer);
155
156void ReshapeWeightsForAcl(TensorInfo& weightInfo, DataLayout dataLayout);
157
158TensorInfo ConvertWeightTensorInfoFromArmnnToAcl(const TensorInfo& weightInfo, DataLayout dataLayout);
159
160armnn::ConstTensor ConvertWeightTensorFromArmnnToAcl(const ConstCpuTensorHandle* weightTensor,
161 DataLayout dataLayout,
162 void* permuteBuffer);
163
164} //namespace armnn