/* * Copyright (c) 2017 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. */ #include "arm_compute/graph/Tensor.h" #include "arm_compute/core/Error.h" #include "arm_compute/core/Helpers.h" #include "arm_compute/core/Validate.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/Tensor.h" #include "utils/TypePrinter.h" using namespace arm_compute::graph; namespace { template std::unique_ptr initialise_tensor(TensorInfo &info) { auto tensor = arm_compute::support::cpp14::make_unique(); tensor->allocator()->init(info); return std::move(tensor); } template void tensor_allocate(arm_compute::ITensor &tensor) { auto itensor = dynamic_cast(&tensor); ARM_COMPUTE_ERROR_ON_NULLPTR(itensor); itensor->allocator()->allocate(); } } // namespace Tensor::Tensor(TensorInfo &&info) : _target(TargetHint::DONT_CARE), _info(info), _accessor(nullptr), _tensor(nullptr) { } Tensor::Tensor(Tensor &&src) noexcept : _target(src._target), _info(std::move(src._info)), _accessor(std::move(src._accessor)), _tensor(std::move(src._tensor)) { } void Tensor::set_info(TensorInfo &&info) { _info = info; } bool Tensor::call_accessor() { ARM_COMPUTE_ERROR_ON_NULLPTR(_accessor.get()); auto cl_tensor = dynamic_cast(_tensor.get()); if(cl_tensor != nullptr && cl_tensor->buffer() == nullptr) { cl_tensor->map(); } bool retval = _accessor->access_tensor(*_tensor); if(cl_tensor != nullptr) { cl_tensor->unmap(); } return retval; } bool Tensor::has_accessor() const { return (_accessor != nullptr); } arm_compute::ITensor *Tensor::tensor() { return _tensor.get(); } const TensorInfo &Tensor::info() const { return _info; } arm_compute::ITensor *Tensor::set_target(TargetHint target) { if(_tensor != nullptr) { ARM_COMPUTE_ERROR_ON(target != _target); } else { switch(target) { case TargetHint::OPENCL: _tensor = initialise_tensor(_info); break; case TargetHint::NEON: _tensor = initialise_tensor(_info); break; default: ARM_COMPUTE_ERROR("Invalid TargetHint"); } _target = target; } return _tensor.get(); } void Tensor::allocate() { ARM_COMPUTE_ERROR_ON_NULLPTR(_tensor.get()); switch(_target) { case TargetHint::OPENCL: tensor_allocate(*_tensor); break; case TargetHint::NEON: tensor_allocate(*_tensor); break; default: ARM_COMPUTE_ERROR("Invalid TargetHint"); } } void Tensor::allocate_and_fill_if_needed() { allocate(); if(_accessor != nullptr) { call_accessor(); } } TargetHint Tensor::target() const { return _target; }