acl_tensor.cc 4.1 KB
Newer Older
S
sharper 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
/*!
 * Copyright (c) 2016 by Contributors
 * \file acl_tensor.cc
 * \brief
 * \author Joey
 */
#include "acl_tensor.h"

namespace paddle_mobile {
namespace operators {
namespace acl {

#ifdef USE_ACL
template <typename TensorType>
std::unique_ptr<arm_compute::ITensor> initialise_tensor(
    arm_compute::TensorInfo &info) {
  auto tensor = cpp14::make_unique<TensorType>();
  tensor->allocator()->init(info);
  return std::move(tensor);
}

template <typename TensorType>
void tensor_allocate(arm_compute::ITensor &tensor) {
  auto itensor = dynamic_cast<TensorType *>(&tensor);
  itensor->allocator()->allocate();
}

Tensor::Tensor(arm_compute::TensorInfo &info) noexcept
    : _target(TargetHint::DONT_CARE), _info(info), _tensor(nullptr) {}

Tensor::Tensor(Tensor &&src) noexcept
    : _target(src._target),
      _info(std::move(src._info)),
      _tensor(std::move(src._tensor)) {}

arm_compute::ITensor *Tensor::set_target(TargetHint target) {
  switch (target) {
#ifdef USE_OPENCL
    case TargetHint::OPENCL:
      _tensor = initialise_tensor<arm_compute::CLTensor>(_info);
      break;
#elif defined(USE_OPENGLES)
    case TargetHint::OPENGLES:
      _tensor = initialise_tensor<arm_compute::GCTensor>(_info);
      break;
#endif
    case TargetHint::NEON:
      _tensor = initialise_tensor<arm_compute::Tensor>(_info);
      break;
    default:
      break;
  }
  _target = target;
  return _tensor.get();
}

void Tensor::allocate() {
  switch (_target) {
#ifdef USE_OPENCL
    case TargetHint::OPENCL:
      tensor_allocate<arm_compute::CLTensor>(*_tensor);
      break;
#elif defined(USE_OPENGLES)
    case TargetHint::OPENGLES:
      tensor_allocate<arm_compute::GCTensor>(*_tensor);
      break;
#endif
    case TargetHint::NEON:
      tensor_allocate<arm_compute::Tensor>(*_tensor);
      break;
    default:
      break;
  }
}
void Tensor::map(bool blocking) {
#ifdef USE_OPENCL
  if (_target == TargetHint::OPENCL)
    dynamic_cast<arm_compute::CLTensor *>(tensor())->map(blocking);
#elif defined(USE_OPENGLES)
  if (_target == TargetHint::OPENGLES)
    dynamic_cast<arm_compute::GCTensor *>(tensor())->map(blocking);
#endif
}
void Tensor::unmap() {
#ifdef USE_OPENCL
  if (_target == TargetHint::OPENCL)
    dynamic_cast<arm_compute::CLTensor *>(tensor())->unmap();
#elif defined(USE_OPENGLES)
  if (_target == TargetHint::OPENGLES)
    dynamic_cast<arm_compute::GCTensor *>(tensor())->unmap();
#endif
}

template <typename SubTensorType, typename ParentTensorType>
std::unique_ptr<arm_compute::ITensor> initialise_subtensor(
    arm_compute::ITensor *parent, arm_compute::TensorShape shape,
    arm_compute::Coordinates coords) {
  auto ptensor = dynamic_cast<ParentTensorType *>(parent);
  auto subtensor = cpp14::make_unique<SubTensorType>(ptensor, shape, coords);
  return std::move(subtensor);
}
SubTensor::SubTensor(Tensor *parent, arm_compute::TensorShape &tensor_shape,
                     arm_compute::Coordinates &coords) noexcept
    : _target(TargetHint::DONT_CARE),
      _tensor_shape(tensor_shape),
      _coords(coords),
      _parent(nullptr),
      _subtensor(nullptr) {
  _parent = parent->tensor();
  _target = parent->target();

  instantiate_subtensor();
}
arm_compute::ITensor *SubTensor::set_target(TargetHint target) {
  return (target == _target) ? _subtensor.get() : nullptr;
}

arm_compute::ITensor *SubTensor::tensor() { return _subtensor.get(); }

const arm_compute::ITensor *SubTensor::tensor() const {
  return _subtensor.get();
}

TargetHint SubTensor::target() const { return _target; }

void SubTensor::allocate() {
  // NOP for sub-tensors
}

void SubTensor::instantiate_subtensor() {
  switch (_target) {
#ifdef USE_OPENCL
    case TargetHint::OPENCL:
      _subtensor = initialise_subtensor<arm_compute::CLSubTensor,
                                        arm_compute::ICLTensor>(
          _parent, _tensor_shape, _coords);
      break;
#endif
    default:
    case TargetHint::NEON:
      _subtensor =
          initialise_subtensor<arm_compute::SubTensor, arm_compute::ITensor>(
              _parent, _tensor_shape, _coords);
      break;
  }
}

#endif

}  // namespace acl
}  // namespace operators
}  // namespace paddle_mobile