diff options
Diffstat (limited to 'src/armnn/Descriptors.cpp')
-rw-r--r-- | src/armnn/Descriptors.cpp | 279 |
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); +} + +} |