| /* |
| * Copyright (c) 2022 Arm Limited. |
| * |
| * SPDX-License-Identifier: MIT |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to |
| * deal in the Software without restriction, including without limitation the |
| * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| * sell copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in all |
| * copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| */ |
| #ifndef SRC_DYNAMIC_FUSION_SKETCH_ARGUMENTPACK |
| #define SRC_DYNAMIC_FUSION_SKETCH_ARGUMENTPACK |
| |
| #include "arm_compute/core/experimental/Types.h" |
| #include <unordered_map> |
| #include <vector> |
| |
| namespace arm_compute |
| { |
| namespace experimental |
| { |
| namespace dynamic_fusion |
| { |
| /** This is a generic class that packs the arguments of an operator. For now, it is only used for tensor-related types |
| * Examples of "tensor-related types": @ref ITensorInfo, @ref ITensor, @ref ICLTensor |
| * |
| * The argument id is the position of the argument within the pack, and is represented by @ref TensorType |
| * |
| * @tparam T Tensor-related type |
| */ |
| template <typename T> |
| class ArgumentPack |
| { |
| public: |
| /** @ref TensorType encodes the position of a tensor argument within the pack */ |
| using Id = TensorType; |
| /** A single argument element within the pack |
| * It contains either a const pointer or a non-const pointer to the Tensor-related type T, but never at the same time |
| */ |
| struct PackElement |
| { |
| PackElement() = default; |
| PackElement(const PackElement &elem) = default; |
| PackElement &operator=(const PackElement &elem) = default; |
| PackElement(PackElement &&elem) = default; |
| PackElement &operator=(PackElement &&elem) = default; |
| PackElement(Id id, T *tensor) |
| : id(id), tensor(tensor), ctensor(nullptr) |
| { |
| } |
| PackElement(Id id, const T *ctensor) |
| : id(id), tensor(nullptr), ctensor(ctensor) |
| { |
| } |
| |
| Id id{ ACL_UNKNOWN }; /**< Argument id within the pack */ |
| T *tensor{ nullptr }; /**< Non-const pointer to tensor-related object */ |
| const T *ctensor |
| { |
| nullptr |
| }; /**< Const pointer to tensor-related object */ |
| }; |
| |
| public: |
| /** Default constructor */ |
| ArgumentPack() = default; |
| /** Destructor */ |
| ~ArgumentPack() = default; |
| /** Allow instances of this class to be copy constructed */ |
| ArgumentPack<T>(const ArgumentPack<T> &other) = default; |
| /** Allow instances of this class to be copied */ |
| ArgumentPack<T> &operator=(const ArgumentPack<T> &other) = default; |
| /** Allow instances of this class to be move constructed */ |
| ArgumentPack<T>(ArgumentPack<T> &&other) = default; |
| /** Allow instances of this class to be moved */ |
| ArgumentPack<T> &operator=(ArgumentPack<T> &&other) = default; |
| /** Initializer list Constructor */ |
| ArgumentPack(const std::initializer_list<PackElement> &l) |
| : _pack{} |
| { |
| for(const auto &e : l) |
| { |
| _pack[e.id] = e; |
| } |
| } |
| /** Add tensor to the pack |
| * |
| * @param[in] id ID of the tensor to add |
| * @param[in] tensor Tensor to add |
| */ |
| void add_tensor(Id id, T *tensor) |
| { |
| _pack[id] = PackElement(id, tensor); |
| } |
| /** Add const tensor to the pack |
| * |
| * @param[in] id ID of the tensor to add |
| * @param[in] tensor Tensor to add |
| */ |
| void add_const_tensor(Id id, const T *tensor) |
| { |
| _pack[id] = PackElement(id, tensor); |
| } |
| /** Get tensor of a given id from the pack |
| * |
| * @param[in] id ID of tensor to extract |
| * |
| * @return The pointer to the tensor if exist and is non-const else nullptr |
| */ |
| T *get_tensor(Id id) |
| { |
| auto it = _pack.find(id); |
| return it != _pack.end() ? it->second.tensor : nullptr; |
| } |
| /** Get constant tensor of a given id |
| * |
| * @param[in] id ID of tensor to extract |
| * |
| * @return The pointer to the tensor (const or not) if exist else nullptr |
| */ |
| const T *get_const_tensor(Id id) const |
| { |
| auto it = _pack.find(id); |
| if(it != _pack.end()) |
| { |
| return it->second.ctensor != nullptr ? it->second.ctensor : it->second.tensor; |
| } |
| return nullptr; |
| } |
| /** Remove the tensor stored with the given id |
| * |
| * @param[in] id ID of tensor to remove |
| */ |
| void remove_tensor(Id id) |
| { |
| _pack.erase(id); |
| } |
| /** Pack size accessor |
| * |
| * @return Number of tensors registered to the pack |
| */ |
| size_t size() const |
| { |
| return _pack.size(); |
| } |
| /** Checks if pack is empty |
| * |
| * @return True if empty else false |
| */ |
| bool empty() const |
| { |
| return _pack.empty(); |
| } |
| /** Get the ACL_SRC_* tensors |
| * |
| * @return std::vector<T *> |
| */ |
| std::vector<T *> get_src_tensors() |
| { |
| std::vector<T *> src_tensors{}; |
| for(int id = static_cast<int>(TensorType::ACL_SRC); id <= static_cast<int>(TensorType::ACL_SRC_END); ++id) |
| { |
| auto tensor = get_tensor(static_cast<TensorType>(id)); |
| if(tensor != nullptr) |
| { |
| src_tensors.push_back(tensor); |
| } |
| } |
| return src_tensors; |
| } |
| /** Get the const ACL_SRC_* tensors |
| * |
| * @return std::vector<const T *> |
| */ |
| std::vector<const T *> get_const_src_tensors() const |
| { |
| std::vector<const T *> src_tensors{}; |
| for(int id = static_cast<int>(TensorType::ACL_SRC); id <= static_cast<int>(TensorType::ACL_SRC_END); ++id) |
| { |
| auto tensor = get_const_tensor(static_cast<TensorType>(id)); |
| if(tensor != nullptr) |
| { |
| src_tensors.push_back(tensor); |
| } |
| } |
| return src_tensors; |
| } |
| /** Get the ACL_DST_* tensors |
| * |
| * @return std::vector<T *> |
| */ |
| std::vector<T *> get_dst_tensors() |
| { |
| std::vector<T *> dst_tensors{}; |
| for(int id = static_cast<int>(TensorType::ACL_DST); id <= static_cast<int>(TensorType::ACL_DST_END); ++id) |
| { |
| auto tensor = get_tensor(static_cast<TensorType>(id)); |
| if(tensor != nullptr) |
| { |
| dst_tensors.push_back(tensor); |
| } |
| } |
| return dst_tensors; |
| } |
| /** Get the const ACL_DST_* tensors |
| * |
| * @return std::vector<const T *> |
| */ |
| std::vector<const T *> get_const_dst_tensors() const |
| { |
| std::vector<const T *> dst_tensors{}; |
| for(int id = static_cast<int>(TensorType::ACL_DST); id <= static_cast<int>(TensorType::ACL_DST_END); ++id) |
| { |
| auto tensor = get_const_tensor(static_cast<TensorType>(id)); |
| if(tensor != nullptr) |
| { |
| dst_tensors.push_back(tensor); |
| } |
| } |
| return dst_tensors; |
| } |
| |
| private: |
| std::unordered_map<int, PackElement> _pack{}; /**< Container with the packed tensors */ |
| }; |
| } // namespace dynamic_fusion |
| } // namespace experimental |
| } // namespace arm_compute |
| #endif /* SRC_DYNAMIC_FUSION_SKETCH_ARGUMENTPACK */ |