[ARM CPU] Remove configure from exec func in eltwise, reduce and pooling (#19071)

This commit is contained in:
Nesterov Alexander 2023-08-30 11:12:25 +02:00 committed by GitHub
parent 6b57360c55
commit f2167a9545
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 71 deletions

View File

@ -226,123 +226,124 @@ bool AclEltwiseExecutor::init(const EltwiseAttrs &eltwiseAttrs, const std::vecto
dstTensors[i].allocator()->init(dstTensorsInfo[i]);
}
std::function<std::unique_ptr<IFunction>(void)> exec_func;
switch (aclEltwiseAttrs.algorithm) {
case Algorithm::EltwiseAdd:
if (!NEArithmeticAddition::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ConvertPolicy::SATURATE))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEArithmeticAddition>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ConvertPolicy::SATURATE);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseMultiply:
if (!NEPixelWiseMultiplication::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0],
1.0f, ConvertPolicy::SATURATE, RoundingPolicy::TO_ZERO))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEPixelWiseMultiplication>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], 1.0f, ConvertPolicy::SATURATE, RoundingPolicy::TO_ZERO);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseSubtract:
if (!NEArithmeticSubtraction::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ConvertPolicy::SATURATE))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEArithmeticSubtraction>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ConvertPolicy::SATURATE);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseDivide:
if (!NEElementwiseDivision::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseDivision>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseMaximum:
if (!NEElementwiseMax::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseMax>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseMinimum:
if (!NEElementwiseMin::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseMin>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseSquaredDifference:
if (!NEElementwiseSquaredDiff::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseSquaredDiff>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseEqual:
if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::Equal))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseComparison>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ComparisonOperation::Equal);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseNotEqual:
if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::NotEqual))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseComparison>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ComparisonOperation::NotEqual);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseGreater:
if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::Greater))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseComparison>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ComparisonOperation::Greater);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseGreaterEqual:
if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::GreaterEqual))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseComparison>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ComparisonOperation::GreaterEqual);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseLess:
if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::Less))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseComparison>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ComparisonOperation::Less);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseLessEqual:
if (!NEElementwiseComparison::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0], ComparisonOperation::LessEqual))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEElementwiseComparison>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0], ComparisonOperation::LessEqual);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseRelu:
@ -355,7 +356,7 @@ bool AclEltwiseExecutor::init(const EltwiseAttrs &eltwiseAttrs, const std::vecto
{ActivationLayerInfo::ActivationFunction::LEAKY_RELU, aclEltwiseAttrs.alpha}))
return false;
}
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
if (aclEltwiseAttrs.alpha == 0) {
acl_op->configure(&srcTensors[0], &dstTensors[0], ActivationLayerInfo::ActivationFunction::RELU);
@ -363,136 +364,137 @@ bool AclEltwiseExecutor::init(const EltwiseAttrs &eltwiseAttrs, const std::vecto
acl_op->configure(&srcTensors[0], &dstTensors[0],
{ActivationLayerInfo::ActivationFunction::LEAKY_RELU, aclEltwiseAttrs.alpha});
}
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseGeluErf:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0], ActivationLayerInfo::ActivationFunction::GELU))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0], ActivationLayerInfo::ActivationFunction::GELU);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseElu:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0],
{ActivationLayerInfo::ActivationFunction::ELU, aclEltwiseAttrs.alpha}))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0], {ActivationLayerInfo::ActivationFunction::ELU, aclEltwiseAttrs.alpha});
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseTanh:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0],
{ActivationLayerInfo::ActivationFunction::TANH, 1.f, 1.f}))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0],
{ActivationLayerInfo::ActivationFunction::TANH, 1.f, 1.f});
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseSigmoid:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0], ActivationLayerInfo::ActivationFunction::LOGISTIC))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0], ActivationLayerInfo::ActivationFunction::LOGISTIC);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseAbs:
if (!NEAbsLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEAbsLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseSqrt:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0], ActivationLayerInfo::ActivationFunction::SQRT))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0], ActivationLayerInfo::ActivationFunction::SQRT);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseSoftRelu:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0], ActivationLayerInfo::ActivationFunction::SOFT_RELU))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0], ActivationLayerInfo::ActivationFunction::SOFT_RELU);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseExp:
if (!NEExpLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEExpLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseClamp:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0],
{ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, aclEltwiseAttrs.beta, aclEltwiseAttrs.alpha}))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0],
{ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, aclEltwiseAttrs.beta, aclEltwiseAttrs.alpha});
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseSwish:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0],
{ActivationLayerInfo::ActivationFunction::SWISH, aclEltwiseAttrs.alpha}))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0],
{ActivationLayerInfo::ActivationFunction::SWISH, aclEltwiseAttrs.alpha});
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwisePrelu:
if (!NEPReluLayer::validate(&srcTensorsInfo[0], &srcTensorsInfo[1], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEPReluLayer>();
acl_op->configure(&srcTensors[0], &srcTensors[1], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseHswish:
if (!NEActivationLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0], ActivationLayerInfo::ActivationFunction::HARD_SWISH))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NEActivationLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0], ActivationLayerInfo::ActivationFunction::HARD_SWISH);
acl_op->run();
return acl_op;
};
break;
case Algorithm::EltwiseLog:
if (!NELogLayer::validate(&srcTensorsInfo[0], &dstTensorsInfo[0]))
return false;
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<NELogLayer>();
acl_op->configure(&srcTensors[0], &dstTensors[0]);
acl_op->run();
return acl_op;
};
break;
default:
IE_THROW() << "Unsupported operation type for ACL Eltwise executor: " << static_cast<int>(aclEltwiseAttrs.algorithm);
}
ifunc = exec_func();
return true;
}
@ -505,7 +507,7 @@ void AclEltwiseExecutor::exec(const std::vector<MemoryCPtr> &src, const std::vec
dstTensors[i].allocator()->import_memory(dst[i]->getData());
}
exec_func();
ifunc->run();
for (size_t i = 0; i < src.size(); i++) {
srcTensors[i].allocator()->free();

View File

@ -34,7 +34,7 @@ private:
EltwiseAttrs aclEltwiseAttrs{};
impl_desc_type implType = impl_desc_type::acl;
std::vector<arm_compute::Tensor> srcTensors, dstTensors;
std::function<void()> exec_func;
std::unique_ptr<arm_compute::IFunction> ifunc;
};
class AclEltwiseExecutorBuilder : public EltwiseExecutorBuilder {

View File

@ -110,6 +110,7 @@ bool AclPoolingExecutor::init(const PoolingAttrs& poolingAttrs,
srcTensor.allocator()->init(srcTensorInfo);
dstTensor.allocator()->init(dstTensorInfo);
std::function<std::unique_ptr<IFunction>(void)> exec_func;
if (srcDims.size() == 5u) {
if (dstDescs.size() == 1u) {
Pooling3dLayerInfo pool_info;
@ -123,10 +124,10 @@ bool AclPoolingExecutor::init(const PoolingAttrs& poolingAttrs,
nullptr,
&pool_info))
return false;
exec_func = [this, pool_info]{
exec_func = [this, pool_info]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<arm_compute::NEPooling3dLayer>();
acl_op->configure(&srcTensor, &dstTensor, pool_info);
acl_op->run();
return acl_op;
};
}
} else {
@ -146,10 +147,10 @@ bool AclPoolingExecutor::init(const PoolingAttrs& poolingAttrs,
TensorInfo indTensorInfo = TensorInfo(shapeCast(indDims), 1, precisionToAclDataType(dstDescs[1]->getPrecision()),
getAclDataLayoutByMemoryDesc(dstDescs[1]));
indTensor.allocator()->init(indTensorInfo);
exec_func = [this, pool_info]{
exec_func = [this, pool_info]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<arm_compute::NEPoolingLayer>();
acl_op->configure(&srcTensor, &dstTensor, pool_info, &indTensor);
acl_op->run();
return acl_op;
};
} else {
if (!isSupported(srcTensorInfo,
@ -162,13 +163,14 @@ bool AclPoolingExecutor::init(const PoolingAttrs& poolingAttrs,
&pool_info,
nullptr))
return false;
exec_func = [this, pool_info]{
exec_func = [this, pool_info]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<arm_compute::NEPoolingLayer>();
acl_op->configure(&srcTensor, &dstTensor, pool_info);
acl_op->run();
return acl_op;
};
}
}
ifunc = exec_func();
return true;
}
@ -177,7 +179,7 @@ void AclPoolingExecutor::exec(const std::vector<MemoryCPtr>& src, const std::vec
dstTensor.allocator()->import_memory(dst[0]->getData());
if (dst.size() > 1u) indTensor.allocator()->import_memory(dst[1]->getData());
exec_func();
ifunc->run();
srcTensor.allocator()->free();
dstTensor.allocator()->free();

View File

@ -38,7 +38,7 @@ public:
}
private:
std::function<void()> exec_func;
std::unique_ptr<arm_compute::IFunction> ifunc;
PoolingAttrs poolingAttrs;
impl_desc_type implType = impl_desc_type::acl;

View File

@ -47,6 +47,7 @@ bool AclReduceExecutor::init(const ReduceAttrs& reduceAttrs,
srcTensor.allocator()->init(srcTensorInfo);
dstTensor.allocator()->init(dstTensorInfo);
std::function<std::unique_ptr<IFunction>(void)> exec_func;
switch (reduceAttrs.operation) {
case Algorithm::ReduceMean: {
for (size_t i = 0; i < reduceAttrs.axes.size(); ++i) {
@ -59,10 +60,10 @@ bool AclReduceExecutor::init(const ReduceAttrs& reduceAttrs,
DEBUG_LOG("NEReduceMean validation failed: ", reduceMeanStatus.error_description());
return false;
}
exec_func = [this]{
exec_func = [this]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<arm_compute::NEReduceMean>();
acl_op->configure(&srcTensor, axesMean, this->reduceAttrs.keepDims, &dstTensor);
acl_op->run();
return acl_op;
};
break;
}
@ -76,18 +77,18 @@ bool AclReduceExecutor::init(const ReduceAttrs& reduceAttrs,
DEBUG_LOG("NEReductionOperation validation with indices failed: ", reductionOperationStatus.error_description());
return false;
}
exec_func = [this, srcDims]{
exec_func = [this, srcDims]() -> std::unique_ptr<IFunction> {
auto acl_op = std::make_unique<arm_compute::NEReductionOperation>();
acl_op->configure(&srcTensor, &dstTensor, axisCast(this->reduceAttrs.axes[0], srcDims.size()),
getAclReductionOperationByAlgorithm(this->reduceAttrs.operation), this->reduceAttrs.keepDims);
acl_op->run();
return acl_op;
};
break;
}
default:
IE_THROW() << "Unsupported operation type for ACL Reduce executor: " << static_cast<int>(reduceAttrs.operation);
}
ifunc = exec_func();
return true;
}
@ -95,7 +96,7 @@ void AclReduceExecutor::exec(const std::vector<MemoryCPtr>& src, const std::vect
srcTensor.allocator()->import_memory(src[0]->getData());
dstTensor.allocator()->import_memory(dst[0]->getData());
exec_func();
ifunc->run();
srcTensor.allocator()->free();
dstTensor.allocator()->free();

View File

@ -30,7 +30,7 @@ public:
}
private:
std::function<void()> exec_func;
std::unique_ptr<arm_compute::IFunction> ifunc;
ReduceAttrs reduceAttrs;
impl_desc_type implType = impl_desc_type::acl;