aboutsummaryrefslogtreecommitdiff
path: root/src/armnn/Descriptors.cpp
diff options
context:
space:
mode:
authortelsoa01 <telmo.soares@arm.com>2018-03-09 14:13:49 +0000
committertelsoa01 <telmo.soares@arm.com>2018-03-09 14:13:49 +0000
commit4fcda0101ec3d110c1d6d7bee5c83416b645528a (patch)
treec9a70aeb2887006160c1b3d265c27efadb7bdbae /src/armnn/Descriptors.cpp
downloadarmnn-4fcda0101ec3d110c1d6d7bee5c83416b645528a.tar.gz
Release 18.02
Change-Id: Id3c11dc5ee94ef664374a988fcc6901e9a232fa6
Diffstat (limited to 'src/armnn/Descriptors.cpp')
-rw-r--r--src/armnn/Descriptors.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/src/armnn/Descriptors.cpp b/src/armnn/Descriptors.cpp
new file mode 100644
index 0000000000..0b11b44260
--- /dev/null
+++ b/src/armnn/Descriptors.cpp
@@ -0,0 +1,279 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// See LICENSE file in the project root for full license information.
+//
+#include "armnn/Descriptors.hpp"
+
+#include <algorithm>
+#include <array>
+#include <vector>
+
+#include <boost/format.hpp>
+#include <boost/log/trivial.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace armnn
+{
+
+PermutationVector::PermutationVector(const ValueType *dimMappings, const SizeType numDimMappings)
+{
+ // Validation
+
+ if (numDimMappings > MaxNumOfTensorDimensions)
+ {
+ boost::format fmt("The number of mappings (%1%) cannot be greater "
+ "than the maximum number of dimensions supported (%2%)");
+ throw InvalidArgumentException(boost::str(fmt % numDimMappings % MaxNumOfTensorDimensions));
+ }
+
+ if ((dimMappings == nullptr) && (numDimMappings != 0))
+ {
+ throw InvalidArgumentException("Dimension mappings must not be NULL if the number of mappings is positive");
+ }
+
+ for (SizeType i = 0; i < numDimMappings; ++i)
+ {
+ const ValueType dstIndex = dimMappings[i];
+ if (dstIndex >= numDimMappings)
+ {
+ boost::format fmt("Dimension mapping at index %1% is invalid: %2% is outside of the valid range [0,%3%]");
+ throw InvalidArgumentException(boost::str(fmt % i % dstIndex % (numDimMappings - 1)));
+ }
+ }
+
+ // Validation: Detect duplicates
+ {
+ std::array<bool, MaxNumOfTensorDimensions> observedDims;
+ observedDims.fill(false);
+
+ for (SizeType i = 0; i < numDimMappings; ++i)
+ {
+ const ValueType dstIndex = dimMappings[i];
+ if (observedDims[dstIndex])
+ {
+ throw InvalidArgumentException("Invalid dimension mappings: Two or more source dimensions are mapped "
+ "to the same output dimension");
+ }
+ observedDims[dstIndex] = true;
+ }
+ }
+
+ // Initialize
+ for (SizeType i = 0; i < numDimMappings; ++i)
+ {
+ m_DimMappings[i] = dimMappings[i];
+ }
+ m_NumDimMappings = numDimMappings;
+}
+
+PermutationVector::PermutationVector(std::initializer_list<ValueType> dimMappings)
+ : PermutationVector(dimMappings.begin(), boost::numeric_cast<SizeType>(dimMappings.size()))
+{
+}
+
+OriginsDescriptor::OriginsDescriptor()
+: m_NumViews(0)
+, m_NumDimensions(0)
+, m_ViewOrigins(nullptr)
+{}
+
+OriginsDescriptor::OriginsDescriptor(uint32_t numViews, uint32_t numDimensions /*= 4*/)
+: m_NumViews(numViews)
+, m_NumDimensions(numDimensions)
+, m_ViewOrigins(numViews && numDimensions > 0 ? new uint32_t *[numViews]() : nullptr)
+{
+ for (uint32_t i = 0; m_NumDimensions > 0 && i < m_NumViews; ++i)
+ {
+ m_ViewOrigins[i] = new uint32_t[m_NumDimensions]();
+ }
+}
+
+OriginsDescriptor::OriginsDescriptor(const OriginsDescriptor& other)
+: m_NumViews(other.m_NumViews)
+, m_NumDimensions(other.m_NumDimensions)
+, m_ViewOrigins(other.m_NumViews && other.m_NumDimensions > 0 ? new uint32_t *[other.m_NumViews]() : nullptr)
+{
+ for (uint32_t i = 0; m_NumDimensions > 0 && i < m_NumViews; ++i)
+ {
+ m_ViewOrigins[i] = new uint32_t[m_NumDimensions]();
+ memcpy(m_ViewOrigins[i], other.m_ViewOrigins[i], m_NumDimensions * sizeof(uint32_t));
+ }
+}
+
+OriginsDescriptor::OriginsDescriptor(OriginsDescriptor&& other)
+: OriginsDescriptor()
+{
+ swap(*this, other);
+}
+
+OriginsDescriptor::~OriginsDescriptor()
+{
+ for (uint32_t i = 0; m_NumDimensions > 0 && i < m_NumViews; ++i)
+ {
+ delete[] m_ViewOrigins[i];
+ }
+ delete[] m_ViewOrigins;
+}
+
+OriginsDescriptor& OriginsDescriptor::operator=(OriginsDescriptor rhs)
+{
+ swap(*this, rhs);
+ return *this;
+}
+
+Status OriginsDescriptor::SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
+{
+ if (view >= m_NumViews)
+ {
+ BOOST_LOG_TRIVIAL(error) << "OriginsDescriptor::SetViewOriginCoord: view argument:" << view <<
+ " is out of range";
+ return Status::Failure;
+ }
+ if (coord >= m_NumDimensions)
+ {
+ BOOST_LOG_TRIVIAL(error) << "OriginsDescriptor::SetViewOriginCoord: coord argument:" << coord <<
+ " is out of range";
+ return Status::Failure;
+ }
+
+ m_ViewOrigins[view][coord] = value;
+ return Status::Success;
+}
+
+
+uint32_t OriginsDescriptor::GetNumViews() const
+{
+ return m_NumViews;
+}
+
+uint32_t OriginsDescriptor::GetNumDimensions() const
+{
+ return m_NumDimensions;
+}
+
+const uint32_t* OriginsDescriptor::GetViewOrigin(uint32_t idx) const
+{
+ return m_ViewOrigins ? m_ViewOrigins[idx] : nullptr;
+}
+
+
+// Reorder the viewOrigins in accordance with the indices presented in newOrdering array
+void OriginsDescriptor::ReorderOrigins(unsigned int* newOrdering, unsigned int numNewOrdering)
+{
+ BOOST_ASSERT_MSG(m_NumViews == numNewOrdering, "number of views must match number of "
+ "elements in the new ordering array");
+ std::vector<uint32_t*> viewOrigins(&m_ViewOrigins[0], &m_ViewOrigins[m_NumViews]);
+
+ for (unsigned int i = 0; i < numNewOrdering; ++i)
+ {
+ m_ViewOrigins[i] = viewOrigins[newOrdering[i]];
+ }
+}
+
+ViewsDescriptor::ViewsDescriptor()
+: m_Origins()
+, m_ViewSizes(nullptr)
+{}
+
+ViewsDescriptor::ViewsDescriptor(uint32_t numViews, uint32_t numDimensions /*= 4*/)
+ : m_Origins(numViews, numDimensions)
+ , m_ViewSizes(numViews && numDimensions > 0 ? new uint32_t *[numViews]() : nullptr)
+{
+ for (uint32_t i = 0; GetNumDimensions() > 0 && i < GetNumViews(); ++i)
+ {
+ m_ViewSizes[i] = new uint32_t[GetNumDimensions()]();
+ }
+}
+
+ViewsDescriptor::ViewsDescriptor(const ViewsDescriptor& other)
+ : m_Origins(other.m_Origins)
+ , m_ViewSizes(other.GetNumViews() && other.GetNumDimensions() > 0 ? new uint32_t *[other.GetNumViews()]() : nullptr)
+{
+ for (uint32_t i = 0; GetNumDimensions() > 0 && i < GetNumViews(); ++i)
+ {
+ m_ViewSizes[i] = new uint32_t[GetNumDimensions()]();
+ memcpy(m_ViewSizes[i], other.m_ViewSizes[i], GetNumDimensions() * sizeof(uint32_t));
+ }
+}
+
+ViewsDescriptor::ViewsDescriptor(ViewsDescriptor&& other)
+ : ViewsDescriptor()
+{
+ swap(*this, other);
+}
+
+ViewsDescriptor::~ViewsDescriptor()
+{
+ for (uint32_t i = 0; GetNumDimensions() > 0 && i < GetNumViews(); ++i)
+ {
+ delete[] m_ViewSizes[i];
+ }
+ delete[] m_ViewSizes;
+}
+
+ViewsDescriptor& ViewsDescriptor::operator=(ViewsDescriptor rhs)
+{
+ swap(*this, rhs);
+ return *this;
+}
+
+uint32_t ViewsDescriptor::GetNumViews() const
+{
+ return m_Origins.GetNumViews();
+}
+
+uint32_t ViewsDescriptor::GetNumDimensions() const
+{
+ return m_Origins.GetNumDimensions();
+}
+
+const uint32_t* ViewsDescriptor::GetViewOrigin(uint32_t idx) const
+{
+ return m_Origins.GetViewOrigin(idx);
+}
+
+Status ViewsDescriptor::SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
+{
+ return m_Origins.SetViewOriginCoord(view, coord, value);
+}
+
+Status ViewsDescriptor::SetViewSize(uint32_t view, uint32_t coord, uint32_t value)
+{
+ if (view >= GetNumViews())
+ {
+ BOOST_LOG_TRIVIAL(error) << "ViewsDescriptor::SetViewSize: view argument:" << view <<
+ " is out of range";
+ return Status::Failure;
+ }
+ if (coord >= GetNumDimensions())
+ {
+ BOOST_LOG_TRIVIAL(error) << "ViewsDescriptor::SetViewSize: coord argument:" << coord <<
+ " is out of range";
+ return Status::Failure;
+ }
+
+ m_ViewSizes[view][coord] = value;
+ return Status::Success;
+}
+
+const uint32_t* ViewsDescriptor::GetViewSizes(uint32_t idx) const
+{
+ return m_ViewSizes ? m_ViewSizes[idx] : nullptr;
+}
+
+void swap(OriginsDescriptor& first, OriginsDescriptor& second)
+{
+ using std::swap;
+ swap(first.m_NumViews, second.m_NumViews);
+ swap(first.m_NumDimensions, second.m_NumDimensions);
+ swap(first.m_ViewOrigins, second.m_ViewOrigins);
+}
+
+void swap(ViewsDescriptor& first, ViewsDescriptor& second)
+{
+ using std::swap;
+ swap(first.m_Origins, second.m_Origins);
+ swap(first.m_ViewSizes, second.m_ViewSizes);
+}
+
+}