Skip to content

Commit

Permalink
[ARM CPU] Add parallel reference power operation (openvinotoolkit#18093)
Browse files Browse the repository at this point in the history
  • Loading branch information
allnes authored Jun 22, 2023
1 parent 3276b8d commit ed087d9
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 15 deletions.
42 changes: 40 additions & 2 deletions src/plugins/intel_cpu/src/nodes/eltwise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1584,7 +1584,7 @@ class EltwiseRefExecutor : public Eltwise::IEltwiseExecutor {
EltwiseRefExecutor(Eltwise::EltwiseData opData,
const VectorDims& outBlkDims,
std::vector<VectorDims> 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()) {
Expand Down Expand Up @@ -1634,6 +1634,44 @@ class EltwiseRefExecutor : public Eltwise::IEltwiseExecutor {
});
return;
}
if (_opData.algo == Algorithm::EltwisePowerStatic) {
const float* src_ptr_f = reinterpret_cast<const float*>(args_ptrs.src_ptr[0]);
float* dst_ptr_f = reinterpret_cast<float*>(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<const float*>(args_ptrs.src_ptr[0]);
const float* src_ptr_f_pow = reinterpret_cast<const float*>(args_ptrs.src_ptr[1]);
float* dst_ptr_f = reinterpret_cast<float*>(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_scalar_fwd_t> ref_eltwise_injector = nullptr;
if (_opData.onednnAlgorithm != dnnl::algorithm::undef) {
Expand Down Expand Up @@ -1716,7 +1754,6 @@ class EltwiseRefExecutor : public Eltwise::IEltwiseExecutor {
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;
Expand Down Expand Up @@ -1749,6 +1786,7 @@ class EltwiseRefExecutor : public Eltwise::IEltwiseExecutor {
size_t _fullWorkAmount = 0;
size_t _inputNum = 0;
size_t _batchDimIdx = 0;
std::vector<VectorDims> _inpDims;
};

} // namespace
Expand Down
10 changes: 0 additions & 10 deletions src/plugins/intel_cpu/src/nodes/executors/acl/acl_eltwise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<NEElementwisePower>();
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -189,9 +195,7 @@ const std::vector<ngraph::helpers::EltwiseTypes>& eltwiseOpTypesBinInp() {

const std::vector<ngraph::helpers::EltwiseTypes>& eltwiseOpTypesDiffInp() {
static const std::vector<ngraph::helpers::EltwiseTypes> 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;
Expand Down

0 comments on commit ed087d9

Please sign in to comment.