diff --git a/src/plugins/intel_cpu/src/nodes/eltwise.cpp b/src/plugins/intel_cpu/src/nodes/eltwise.cpp index 746e560e44b..759501023a3 100644 --- a/src/plugins/intel_cpu/src/nodes/eltwise.cpp +++ b/src/plugins/intel_cpu/src/nodes/eltwise.cpp @@ -1584,7 +1584,7 @@ public: EltwiseRefExecutor(Eltwise::EltwiseData opData, const VectorDims& outBlkDims, std::vector inpDims) - : _opData(std::move(opData)) { + : _opData(std::move(opData)), _inpDims(inpDims) { if (inpDims.empty()) { IE_THROW() << "Can not make Eltwise executor from empty input dims array"; } else if (inpDims.front().empty()) { @@ -1634,6 +1634,44 @@ public: }); return; } + if (_opData.algo == Algorithm::EltwisePowerStatic) { + const float* src_ptr_f = reinterpret_cast(args_ptrs.src_ptr[0]); + float* dst_ptr_f = reinterpret_cast(args_ptrs.dst_ptr); + if (_opData.alpha == 2) { + parallel_for(_fullWorkAmount, [&](size_t i) { + dst_ptr_f[i] = (_opData.beta * src_ptr_f[i] + _opData.gamma) * + (_opData.beta * src_ptr_f[i] + _opData.gamma); + }); + } else { + parallel_for(_fullWorkAmount, [&](size_t i) { + dst_ptr_f[i] = powf(_opData.beta * src_ptr_f[i] + _opData.gamma, _opData.alpha); + }); + } + return; + } + if (_opData.algo == Algorithm::EltwisePowerDynamic) { + const float* src_ptr_f = reinterpret_cast(args_ptrs.src_ptr[0]); + const float* src_ptr_f_pow = reinterpret_cast(args_ptrs.src_ptr[1]); + float* dst_ptr_f = reinterpret_cast(args_ptrs.dst_ptr); + + uint32_t count_of_power_values = 1; + for (unsigned long i : _inpDims[1]) { + count_of_power_values *= i; + } + + if (count_of_power_values == 1) { + if (src_ptr_f_pow[0] != 2) { + parallel_for(_fullWorkAmount, [&](size_t i) { + dst_ptr_f[i] = powf(src_ptr_f[i], src_ptr_f_pow[0]); + }); + } else { + parallel_for(_fullWorkAmount, [&](size_t i) { + dst_ptr_f[i] = src_ptr_f[i] * src_ptr_f[i]; + }); + } + return; + } + } std::shared_ptr ref_eltwise_injector = nullptr; if (_opData.onednnAlgorithm != dnnl::algorithm::undef) { @@ -1716,7 +1754,6 @@ public: case Algorithm::EltwiseLogicalOr: *dst_ptr_f = src_f[0] || src_f[1]; break; case Algorithm::EltwiseLogicalXor: *dst_ptr_f = (src_f[0] || src_f[1]) - (src_f[0] && src_f[1]); break; case Algorithm::EltwiseLogicalNot: *dst_ptr_f = !src_f[0]; break; - case Algorithm::EltwisePowerStatic: *dst_ptr_f = powf(_opData.beta * src_f[0] + _opData.gamma, _opData.alpha); break; case Algorithm::EltwisePrelu: *dst_ptr_f = src_f[0] > 0 ? src_f[0] : src_f[0] * src_f[1]; break; case Algorithm::EltwiseErf: *dst_ptr_f = std::erf(src_f[0]); break; case Algorithm::EltwiseSoftSign: *dst_ptr_f = src_f[0] / (1 + std::fabs(src_f[0])); break; @@ -1749,6 +1786,7 @@ private: size_t _fullWorkAmount = 0; size_t _inputNum = 0; size_t _batchDimIdx = 0; + std::vector _inpDims; }; } // namespace diff --git a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_eltwise.cpp b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_eltwise.cpp index dca217ef2b1..77a86d2f6b1 100644 --- a/src/plugins/intel_cpu/src/nodes/executors/acl/acl_eltwise.cpp +++ b/src/plugins/intel_cpu/src/nodes/executors/acl/acl_eltwise.cpp @@ -48,7 +48,6 @@ bool AclEltwiseExecutorBuilder::isSupported(const EltwiseAttrs& eltwiseAttrs, case Algorithm::EltwiseElu: case Algorithm::EltwiseTanh: case Algorithm::EltwiseSigmoid: -// case Algorithm::EltwisePowerDynamic: // TODO: CVS-111880 case Algorithm::EltwiseSoftRelu: case Algorithm::EltwiseClamp: case Algorithm::EltwiseSwish: // TODO: CVS-109354: efficientdet-d0 accuracy drops if ACL Swish is used @@ -258,15 +257,6 @@ bool AclEltwiseExecutor::init(const EltwiseAttrs &eltwiseAttrs, const std::vecto acl_op->run(); }; break; - case Algorithm::EltwisePowerDynamic: - if (!NEElementwisePower::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0])) - return false; - exec_func = [this]{ - auto acl_op = std::make_unique(); - acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0]); - acl_op->run(); - }; - break; case Algorithm::EltwiseEqual: if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::Equal)) return false; diff --git a/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/eltwise.cpp b/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/eltwise.cpp index 7544ff31bab..d81de3af743 100644 --- a/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/eltwise.cpp +++ b/src/plugins/intel_cpu/tests/functional/single_layer_tests/classes/eltwise.cpp @@ -42,6 +42,7 @@ ov::Tensor EltwiseLayerCPUTest::generate_eltwise_input(const ov::element::Type& if (type.is_real()) { switch (eltwiseType) { case ngraph::helpers::EltwiseTypes::POWER: + params = gen_params(6, -3); case ngraph::helpers::EltwiseTypes::MOD: case ngraph::helpers::EltwiseTypes::FLOOR_MOD: params = gen_params(2, 2, 8); @@ -93,6 +94,11 @@ void EltwiseLayerCPUTest::SetUp() { std::tie(postOpMgrPtr, fusedOps) = fusingParams; selectedType = makeSelectedTypeStr(getPrimitiveType(), netType); + #if defined(OPENVINO_ARCH_ARM) || defined(OPENVINO_ARCH_ARM64) + if (eltwiseType == POWER) { + selectedType = std::regex_replace(selectedType, std::regex("acl"), "ref"); + } + #endif shapes.resize(2); switch (opType) { @@ -189,9 +195,7 @@ const std::vector& eltwiseOpTypesBinInp() { const std::vector& eltwiseOpTypesDiffInp() { static const std::vector eltwiseOpTypesDiffInp = { // Different number of input nodes depending on optimizations - #if defined(OPENVINO_ARCH_X86) || defined(OPENVINO_ARCH_X86_64) - ngraph::helpers::EltwiseTypes::POWER, //TODO: Fix CVS-111880 - #endif + ngraph::helpers::EltwiseTypes::POWER, // ngraph::helpers::EltwiseTypes::MOD // Does not execute because of transformations }; return eltwiseOpTypesDiffInp;