Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 48 additions & 49 deletions src/plugins/intel_cpu/src/nodes/executors/acl/acl_interpolate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,30 @@
#include "acl_utils.hpp"
#include "cpu_memory.h"
#include "memory_desc/cpu_memory_desc.h"
#include "nodes/executors/interpolate.hpp"
#include "openvino/core/except.hpp"
#include "utils/debug_capabilities.h"
#include "utils/general_utils.h"

bool ov::intel_cpu::ACLInterpolateExecutor::init(const InterpolateAttrs& interpolateAttrs,
const std::vector<MemoryDescPtr>& srcDescs,
const std::vector<MemoryDescPtr>& dstDescs,
const dnnl::primitive_attr& attr) {
aclInterpolateAttrs = interpolateAttrs;
InterpolateExecutor::init(aclInterpolateAttrs, srcDescs, dstDescs, attr);
bool ov::intel_cpu::AclInterpolateExecutor::update(const MemoryArgs& memory) {
std::vector<MemoryDescPtr> srcDescs{memory.at(ARG_SRC)->getDescPtr()};
std::vector<MemoryDescPtr> dstDescs{memory.at(ARG_DST)->getDescPtr()};
acl_coord = arm_compute::SamplingPolicy::TOP_LEFT;
const auto& out_shape = dstDescs[0]->getShape().getDims();

static const size_t index_h = 2;
static const size_t index_w = 3;
if ((aclInterpolateAttrs.coordTransMode == InterpolateCoordTransMode::pytorch_half_pixel &&
if ((aclInterpolateAttrs.coordTransMode == ov::intel_cpu::InterpolateCoordTransMode::pytorch_half_pixel &&
out_shape[index_h] > 1 && out_shape[index_w] > 1) ||
aclInterpolateAttrs.coordTransMode == InterpolateCoordTransMode::half_pixel) {
aclInterpolateAttrs.coordTransMode == ov::intel_cpu::InterpolateCoordTransMode::half_pixel) {
acl_coord = arm_compute::SamplingPolicy::CENTER;
}

switch (aclInterpolateAttrs.mode) {
case InterpolateMode::linear:
case InterpolateMode::linear_onnx:
case ov::intel_cpu::InterpolateMode::linear:
case ov::intel_cpu::InterpolateMode::linear_onnx:
acl_policy = arm_compute::InterpolationPolicy::BILINEAR;
break;
case InterpolateMode::nearest:
case ov::intel_cpu::InterpolateMode::nearest:
acl_policy = arm_compute::InterpolationPolicy::NEAREST_NEIGHBOR;
break;
default:
Expand Down Expand Up @@ -77,7 +73,7 @@ bool ov::intel_cpu::ACLInterpolateExecutor::init(const InterpolateAttrs& interpo
arm_compute::PixelValue(),
acl_coord,
false,
aclInterpolateAttrs.coordTransMode == InterpolateCoordTransMode::align_corners,
aclInterpolateAttrs.coordTransMode == ov::intel_cpu::InterpolateCoordTransMode::align_corners,
getAclDataLayoutByMemoryDesc(srcDescs[0])));
if (!status) {
DEBUG_LOG("NEScale validation failed: ", status.error_description());
Expand All @@ -97,29 +93,26 @@ bool ov::intel_cpu::ACLInterpolateExecutor::init(const InterpolateAttrs& interpo
arm_compute::PixelValue(),
acl_coord,
false,
aclInterpolateAttrs.coordTransMode == InterpolateCoordTransMode::align_corners,
aclInterpolateAttrs.coordTransMode == ov::intel_cpu::InterpolateCoordTransMode::align_corners,
getAclDataLayoutByMemoryDesc(srcDescs[0])));
});
return true;
}

void ov::intel_cpu::ACLInterpolateExecutor::exec(const std::vector<MemoryCPtr>& src,
const std::vector<MemoryPtr>& dst,
[[maybe_unused]] const void* post_ops_data_) {
const auto* in_ptr_ = padPreprocess(src, dst);
srcTensor.allocator()->import_memory(const_cast<void*>(reinterpret_cast<const void*>(in_ptr_)));
dstTensor.allocator()->import_memory(dst[0]->getData());
void ov::intel_cpu::AclInterpolateExecutor::execute(const MemoryArgs& memory) {
srcTensor.allocator()->import_memory(const_cast<void*>(memory.at(ARG_SRC)->getData()));
dstTensor.allocator()->import_memory(memory.at(ARG_DST)->getData());

acl_scale->run();

srcTensor.allocator()->free();
dstTensor.allocator()->free();
}

bool ov::intel_cpu::ACLInterpolateExecutorBuilder::isSupportedConfiguration(
static bool isSupportedConfiguration(
const ov::intel_cpu::InterpolateAttrs& interpolateAttrs,
const std::vector<MemoryDescPtr>& srcDescs,
const std::vector<MemoryDescPtr>& dstDescs) {
const std::vector<ov::intel_cpu::MemoryDescPtr>& srcDescs,
const std::vector<ov::intel_cpu::MemoryDescPtr>& dstDescs) {
OPENVINO_ASSERT(srcDescs[0]->getShape().getDims().size() == 4);

const auto& inp_shape = srcDescs[0]->getShape().getDims();
Expand All @@ -134,30 +127,32 @@ bool ov::intel_cpu::ACLInterpolateExecutorBuilder::isSupportedConfiguration(
const auto& coord_mode = interpolateAttrs.coordTransMode;
const auto& nearest_mode = interpolateAttrs.nearestMode;

if (coord_mode == InterpolateCoordTransMode::align_corners &&
nearest_mode == InterpolateNearestMode::round_prefer_ceil) {
if (coord_mode == ov::intel_cpu::InterpolateCoordTransMode::align_corners &&
nearest_mode == ov::intel_cpu::InterpolateNearestMode::round_prefer_ceil) {
DEBUG_LOG("InterpolateCoordTransMode::align_corners with InterpolateNearestMode::round_prefer_ceil supported");
return true;
}

if (coord_mode == InterpolateCoordTransMode::half_pixel &&
(nearest_mode == InterpolateNearestMode::simple || nearest_mode == InterpolateNearestMode::round_prefer_ceil)) {
if (coord_mode == ov::intel_cpu::InterpolateCoordTransMode::half_pixel &&
(nearest_mode == ov::intel_cpu::InterpolateNearestMode::simple ||
nearest_mode == ov::intel_cpu::InterpolateNearestMode::round_prefer_ceil)) {
DEBUG_LOG("InterpolateCoordTransMode half_pixel is not supported for InterpolateNearestMode simple and "
"round_prefer_ceil");
return false;
}

if (coord_mode == InterpolateCoordTransMode::asymmetric &&
(nearest_mode == InterpolateNearestMode::simple || nearest_mode == InterpolateNearestMode::floor)) {
if (coord_mode == ov::intel_cpu::InterpolateCoordTransMode::asymmetric &&
(nearest_mode == ov::intel_cpu::InterpolateNearestMode::simple ||
nearest_mode == ov::intel_cpu::InterpolateNearestMode::floor)) {
DEBUG_LOG("asymmetric && (simple || floor) mode with upsample: ", is_upsample);
return is_upsample;
}

if (is_upsample) {
bool int_factor = (scale_h == std::floor(scale_h)) && (scale_w == std::floor(scale_w));
if (int_factor && coord_mode != InterpolateCoordTransMode::asymmetric &&
(nearest_mode == InterpolateNearestMode::round_prefer_ceil ||
nearest_mode == InterpolateNearestMode::round_prefer_floor)) {
if (int_factor && coord_mode != ov::intel_cpu::InterpolateCoordTransMode::asymmetric &&
(nearest_mode == ov::intel_cpu::InterpolateNearestMode::round_prefer_ceil ||
nearest_mode == ov::intel_cpu::InterpolateNearestMode::round_prefer_floor)) {
DEBUG_LOG(
"upsample && int_factor && !asymmetric && (round_prefer_ceil || round_prefer_floor) case is supported");
return true;
Expand All @@ -167,15 +162,15 @@ bool ov::intel_cpu::ACLInterpolateExecutorBuilder::isSupportedConfiguration(
float down_scale_w = static_cast<float>(inp_shape[index_w]) / out_shape[index_w];
bool int_factor = (down_scale_h == std::floor(down_scale_h)) && (down_scale_w == std::floor(down_scale_w));

if (int_factor && coord_mode != InterpolateCoordTransMode::align_corners &&
nearest_mode == InterpolateNearestMode::simple) {
if (int_factor && coord_mode != ov::intel_cpu::InterpolateCoordTransMode::align_corners &&
nearest_mode == ov::intel_cpu::InterpolateNearestMode::simple) {
DEBUG_LOG("!upsample && int_factor && !align_corners && simple case is supported");
return true;
}

if (int_factor && nearest_mode == InterpolateNearestMode::round_prefer_ceil &&
if (int_factor && nearest_mode == ov::intel_cpu::InterpolateNearestMode::round_prefer_ceil &&
((out_shape[index_h] > 1 && out_shape[index_w] > 1) ||
coord_mode != InterpolateCoordTransMode::half_pixel)) {
coord_mode != ov::intel_cpu::InterpolateCoordTransMode::half_pixel)) {
DEBUG_LOG(
"!upsample && int_factor && round_prefer_ceil && (out_shape > 1 || half_pixel) case is supported");
return true;
Expand All @@ -194,9 +189,10 @@ bool ov::intel_cpu::ACLInterpolateExecutorBuilder::isSupportedConfiguration(
return false;
}

bool ov::intel_cpu::ACLInterpolateExecutorBuilder::isSupported(const ov::intel_cpu::InterpolateAttrs& interpolateAttrs,
const std::vector<MemoryDescPtr>& srcDescs,
const std::vector<MemoryDescPtr>& dstDescs) const {
bool ov::intel_cpu::AclInterpolateExecutor::supports(const ov::intel_cpu::InterpolateConfig& config) {
const auto& interpolateAttrs = config.attrs;
std::vector<MemoryDescPtr> srcDescs{config.descs.at(ARG_SRC)};
std::vector<MemoryDescPtr> dstDescs{config.descs.at(ARG_DST)};
if (srcDescs[0]->getShape().getDims().size() != 4U) {
DEBUG_LOG("ACL Interpolate does not support src shape rank: ", srcDescs[0]->getShape().getDims().size());
return false;
Expand All @@ -218,34 +214,37 @@ bool ov::intel_cpu::ACLInterpolateExecutorBuilder::isSupported(const ov::intel_c
}

if (interpolateAttrs.antialias ||
interpolateAttrs.coordTransMode == InterpolateCoordTransMode::tf_half_pixel_for_nn ||
interpolateAttrs.nearestMode == InterpolateNearestMode::ceil) {
interpolateAttrs.coordTransMode == ov::intel_cpu::InterpolateCoordTransMode::tf_half_pixel_for_nn ||
interpolateAttrs.nearestMode == ov::intel_cpu::InterpolateNearestMode::ceil) {
DEBUG_LOG("ACL Interpolate does not support antialias, tf_half_pixel_for_nn, ceil modes");
return false;
}

if (interpolateAttrs.mode == InterpolateMode::cubic || interpolateAttrs.mode == InterpolateMode::bilinear_pillow ||
interpolateAttrs.mode == InterpolateMode::bicubic_pillow) {
if (interpolateAttrs.mode == ov::intel_cpu::InterpolateMode::cubic ||
interpolateAttrs.mode == ov::intel_cpu::InterpolateMode::bilinear_pillow ||
interpolateAttrs.mode == ov::intel_cpu::InterpolateMode::bicubic_pillow) {
DEBUG_LOG("ACL Interpolate does not support cubic, bilinear_pillow, bicubic_pillow modes");
return false;
}

if (interpolateAttrs.shapeCalcMode == InterpolateShapeCalcMode::scales &&
if (interpolateAttrs.shapeCalcMode == ov::intel_cpu::InterpolateShapeCalcMode::scales &&
any_of(interpolateAttrs.coordTransMode,
InterpolateCoordTransMode::half_pixel,
InterpolateCoordTransMode::asymmetric) &&
any_of(interpolateAttrs.mode, InterpolateMode::linear, InterpolateMode::linear_onnx)) {
ov::intel_cpu::InterpolateCoordTransMode::half_pixel,
ov::intel_cpu::InterpolateCoordTransMode::asymmetric) &&
any_of(interpolateAttrs.mode,
ov::intel_cpu::InterpolateMode::linear,
ov::intel_cpu::InterpolateMode::linear_onnx)) {
DEBUG_LOG("ACL Interpolate does not support scales mode with linear/linear_onnx and half_pixel/asymmetric");
return false;
}

if (interpolateAttrs.mode == InterpolateMode::nearest &&
if (interpolateAttrs.mode == ov::intel_cpu::InterpolateMode::nearest &&
!isSupportedConfiguration(interpolateAttrs, srcDescs, dstDescs)) {
DEBUG_LOG("ACL Interpolate isSupportedConfiguration method fails for nearest mode");
return false;
}

if (interpolateAttrs.coordTransMode == InterpolateCoordTransMode::pytorch_half_pixel) {
if (interpolateAttrs.coordTransMode == ov::intel_cpu::InterpolateCoordTransMode::pytorch_half_pixel) {
DEBUG_LOG("ACL Interpolate does not support pytorch_half_pixel mode");
return false;
}
Expand Down
40 changes: 10 additions & 30 deletions src/plugins/intel_cpu/src/nodes/executors/acl/acl_interpolate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,29 @@

#include "arm_compute/runtime/NEON/functions/NEScale.h"
#include "arm_compute/runtime/Tensor.h"
#include "nodes/executors/interpolate.hpp"
#include "nodes/executors/executor.hpp"
#include "nodes/executors/interpolate_config.hpp"

namespace ov::intel_cpu {

class ACLInterpolateExecutor : public InterpolateExecutor {
class AclInterpolateExecutor : public Executor {
public:
explicit ACLInterpolateExecutor(const ExecutorContext::CPtr& context) : InterpolateExecutor(context) {}
AclInterpolateExecutor(InterpolateAttrs attrs, const MemoryArgs& /*memory*/, ExecutorContext::CPtr context)
: aclInterpolateAttrs(std::move(attrs)), context(std::move(context)) {}

bool init(const InterpolateAttrs& interpolateAttrs,
const std::vector<MemoryDescPtr>& srcDescs,
const std::vector<MemoryDescPtr>& dstDescs,
const dnnl::primitive_attr& attr) override;
static bool supports(const InterpolateConfig& config);

void exec(const std::vector<MemoryCPtr>& src,
const std::vector<MemoryPtr>& dst,
const void* post_ops_data_) override;
bool update(const MemoryArgs& memory) override;
void execute(const MemoryArgs& memory) override;

[[nodiscard]] impl_desc_type getImplType() const override {
return implType;
}
[[nodiscard]] impl_desc_type implType() const override { return impl_desc_type::acl; }

private:
impl_desc_type implType = impl_desc_type::acl;
InterpolateAttrs aclInterpolateAttrs;
const ExecutorContext::CPtr context;
arm_compute::SamplingPolicy acl_coord = arm_compute::SamplingPolicy::CENTER;
arm_compute::InterpolationPolicy acl_policy = arm_compute::InterpolationPolicy::NEAREST_NEIGHBOR;
arm_compute::Tensor srcTensor, dstTensor;
std::unique_ptr<arm_compute::NEScale> acl_scale;
};

class ACLInterpolateExecutorBuilder : public InterpolateExecutorBuilder {
public:
[[nodiscard]] bool isSupported(const InterpolateAttrs& interpolateAttrs,
const std::vector<MemoryDescPtr>& srcDescs,
const std::vector<MemoryDescPtr>& dstDescs) const override;

[[nodiscard]] InterpolateExecutorPtr makeExecutor(const ExecutorContext::CPtr context) const override {
return std::make_shared<ACLInterpolateExecutor>(context);
}

private:
static bool isSupportedConfiguration(const InterpolateAttrs& interpolateAttrs,
const std::vector<MemoryDescPtr>& srcDescs,
const std::vector<MemoryDescPtr>& dstDescs);
};
} // namespace ov::intel_cpu
Loading
Loading