Skip to content

Commit

Permalink
[CPU][RV64] Added jit_rvv impl type
Browse files Browse the repository at this point in the history
  • Loading branch information
a-sidorova committed Feb 5, 2025
1 parent 8cb856e commit 7e1a989
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 261 deletions.

This file was deleted.

2 changes: 2 additions & 0 deletions src/plugins/intel_cpu/src/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,8 @@ const std::vector<impl_desc_type>& Node::getDefaultImplPriority() {
impl_desc_type::jit_sse42_dw, impl_desc_type::jit_sse42_1x1, impl_desc_type::jit_sse42,
#if defined(OPENVINO_ARCH_ARM64)
impl_desc_type::jit_asimd,
#elif defined(OPENVINO_ARCH_RISCV64)
impl_desc_type::jit_rvv,
#endif
impl_desc_type::gemm_any, impl_desc_type::gemm_blas, impl_desc_type::gemm_avx512, impl_desc_type::gemm_avx2,
impl_desc_type::gemm_avx, impl_desc_type::gemm_sse42, impl_desc_type::gemm_acl, impl_desc_type::acl,
Expand Down
168 changes: 110 additions & 58 deletions src/plugins/intel_cpu/src/nodes/eltwise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@

#if defined(OPENVINO_ARCH_ARM64)
# include "cpu/aarch64/cpu_isa_traits.hpp"
# include "executors/aarch64/jit_eltwise.hpp"
# include "kernels/aarch64/jit_uni_eltwise_generic.hpp"
#elif defined(OPENVINO_ARCH_X86_64)
# include "cpu/x64/cpu_isa_traits.hpp"
Expand All @@ -55,6 +54,7 @@

#if defined(OPENVINO_ARCH_RISCV64)
# include "kernels/riscv64/jit_uni_eltwise_generic.hpp"
# include "kernels/riscv64/cpu_isa_traits.hpp"
#endif

using namespace dnnl::impl::utils;
Expand All @@ -74,24 +74,6 @@ namespace ov {
namespace intel_cpu {
namespace node {

#if defined(OPENVINO_ARCH_ARM64)
namespace {
bool jitIsSupported(const Node* node,
const float alpha,
const float beta,
const float gamma,
const std::vector<ov::element::Type>& input_precisions = {}) {
return executors::aarch64::JitEltwiseExecutor::isSupported(
node->getAlgorithm(),
input_precisions.empty() ? node->getOriginalInputPrecisions() : input_precisions,
node->getOriginalOutputPrecisions(),
alpha,
beta,
gamma);
}
} // namespace
#endif

Eltwise::BroadcastingPolicy Eltwise::determineBroadcastingPolicy(const std::shared_ptr<ov::Node>& op) {
const auto const1 = ov::as_type_ptr<ov::opset1::Constant>(op->get_input_node_shared_ptr(0));
const auto const2 = ov::as_type_ptr<ov::opset1::Constant>(op->get_input_node_shared_ptr(1));
Expand Down Expand Up @@ -760,6 +742,83 @@ class EltwiseJitExecutor : public Eltwise::IEltwiseExecutor {
return _batchDimIdx;
}

static bool IsSupportedOp(const Node* node,
const float alpha,
const float beta,
const float gamma,
const std::vector<ov::element::Type>& input_precisions = {}) {
const auto algorithm = node->getAlgorithm();
if (one_of(algorithm,
Algorithm::EltwiseLog,
Algorithm::EltwiseBitwiseAnd,
Algorithm::EltwiseBitwiseNot,
Algorithm::EltwiseBitwiseOr,
Algorithm::EltwiseBitwiseXor,
Algorithm::EltwiseBitwiseLeftShift,
Algorithm::EltwiseBitwiseRightShift))
return false;

#if defined(OPENVINO_ARCH_X86_64)
return true;
#elif !defined(OPENVINO_ARCH_ARM64) && !defined(OPENVINO_ARCH_RISCV64)
return false;
#endif

#if defined(OPENVINO_ARCH_ARM64)
if (one_of(algorithm,
EltwiseSquaredDifference,
EltwisePowerDynamic,
EltwiseSoftRelu,
EltwiseHsigmoid,
EltwiseErf))
return false;

if ((algorithm == Algorithm::EltwiseRelu) && ((alpha != 0.f) || (beta != 0.f) || (gamma != 0.f))) {
return false;
}

const std::set<ov::element::Type> supported_precisions =
// Divide and Floor (issue #138629) operations are supported for fp32 and fp16 only.
((algorithm == Algorithm::EltwiseDivide) || (algorithm == Algorithm::EltwiseFloor))
? std::set<ov::element::Type>{ov::element::f16, ov::element::f32}
: std::set<ov::element::Type>{ov::element::f16,
ov::element::f32,
ov::element::i32,
ov::element::i8,
ov::element::u8};
#elif defined(OPENVINO_ARCH_RISCV64)
if (!one_of(algorithm, Algorithm::EltwiseAdd))
return false;

const std::set<ov::element::Type> supported_precisions =
{ ov::element::f32, ov::element::i32, ov::element::i8, ov::element::u8 };
#endif

const auto check_precisions = [](const std::vector<ov::element::Type>& input_precisions,
const std::vector<ov::element::Type>& output_precisions,
const std::set<ov::element::Type>& supported_precisions) {
if (std::any_of(input_precisions.begin(),
input_precisions.end(),
[&supported_precisions](const ov::element::Type& precision) {
return supported_precisions.find(precision) == supported_precisions.end();
})) {
return false;
}

if (std::any_of(output_precisions.begin(),
output_precisions.end(),
[&supported_precisions](const ov::element::Type& precision) {
return supported_precisions.find(precision) == supported_precisions.end();
})) {
return false;
}

return true;
};

return check_precisions(input_precisions, node->getOriginalOutputPrecisions(), supported_precisions);
}

private:
std::unique_ptr<jit_uni_eltwise_kernel> _pKernel;
size_t _schedulerWorkAmount = 0;
Expand Down Expand Up @@ -1354,26 +1413,21 @@ void Eltwise::initSupportedPrimitiveDescriptors() {
return;
}

// if dim rank is greater than the maximum possible, we should use the reference execution
#if defined(OPENVINO_ARCH_ARM64)
bool canUseOptimizedImpl =
mayiuse(dnnl::impl::cpu::aarch64::asimd) && (getInputShapeAtPort(0).getRank() <= MAX_ELTWISE_DIM_RANK);
bool canUseOptimizedShapeAgnosticImpl = isDynamicNode() && canUseOptimizedImpl;
#elif defined(OPENVINO_ARCH_X86_64)
bool canUseOptimizedImpl =
mayiuse(dnnl::impl::cpu::x64::sse41) && getInputShapeAtPort(0).getRank() <= MAX_ELTWISE_DIM_RANK;
// TODO: Add EltwiseLog algorithm support for JIT implementation
canUseOptimizedImpl &= !one_of(getAlgorithm(),
Algorithm::EltwiseLog,
Algorithm::EltwiseBitwiseLeftShift,
Algorithm::EltwiseBitwiseRightShift);

bool canUseOptimizedShapeAgnosticImpl = isDynamicNode() && canUseOptimizedImpl;
#if defined(OPENVINO_ARCH_X86_64)
const auto isISASupportedByJIT = mayiuse(dnnl::impl::cpu::x64::sse41);
#elif defined(OPENVINO_ARCH_ARM64)
const auto isISASupportedByJIT = mayiuse(dnnl::impl::cpu::aarch64::asimd);
#elif defined(OPENVINO_ARCH_RISCV64)
const auto isISASupportedByJIT = mayiuse(ov::intel_cpu::riscv64::imafdcv);
#else
bool canUseOptimizedImpl = false;
bool canUseOptimizedShapeAgnosticImpl = false;
const auto isISASupportedByJIT = false;
#endif

// if dim rank is greater than the maximum possible, we should use the reference execution
bool canUseOptimizedImpl = EltwiseJitExecutor::IsSupportedOp(this, getAlpha(), getBeta(), getGamma()) &&
isISASupportedByJIT && (getInputShapeAtPort(0).getRank() <= MAX_ELTWISE_DIM_RANK);
bool canUseOptimizedShapeAgnosticImpl = isDynamicNode() && canUseOptimizedImpl;

if (!canUseOptimizedImpl && !fusedWith.empty()) {
OPENVINO_THROW("Unexpected: Eltwise node with name '",
getName(),
Expand Down Expand Up @@ -1436,11 +1490,17 @@ void Eltwise::initSupportedPrimitiveDescriptors() {
outputPrecision = fusedWith[fusedWith.size() - 1]->getOriginalOutputPrecisionAtPort(0);
}

#ifndef OPENVINO_ARCH_ARM64
implType = canUseOptimizedShapeAgnosticImpl ? EltwiseImplType::optimizedShapeAgnostic
: canUseOptimizedImpl ? EltwiseImplType::optimized
: EltwiseImplType::reference;

#if defined(OV_CPU_WITH_ACL)
const auto useJit = false;
#elif defined(OPENVINO_ARCH_ARM64)
const auto useJit = one_of(implType, EltwiseImplType::optimizedShapeAgnostic, EltwiseImplType::optimized);
#endif

#ifdef OPENVINO_ARCH_X86_64
if (!hasHardwareSupport(ov::element::bf16)) {
bool hasBF16 = false;
for (auto& inPrc : inputPrecisions) {
Expand All @@ -1453,26 +1513,8 @@ void Eltwise::initSupportedPrimitiveDescriptors() {
OPENVINO_THROW("Eltwise node with name `", getName(), "` doesn't support BF16 precision on this target.");
}
}
# if defined(OV_CPU_WITH_ACL)
const bool useJit = false;
# endif
#elif defined(OPENVINO_ARCH_ARM64)
const bool useJit = canUseOptimizedImpl && jitIsSupported(this, getAlpha(), getBeta(), getGamma());
if (!useJit) {
canUseOptimizedImpl = false;
}

implType =
(useJit && canUseOptimizedImpl)
? (canUseOptimizedShapeAgnosticImpl ? EltwiseImplType::optimizedShapeAgnostic : EltwiseImplType::optimized)
: EltwiseImplType::reference;
#else
OPENVINO_THROW("Unknow CPU architecture");
#endif

const bool useJit = getAlgorithm() == Algorithm::EltwiseAdd;
implType = useJit ? EltwiseImplType::optimized : EltwiseImplType::reference;

#if defined(OV_CPU_WITH_ACL)
auto filterPrecision = [&](const ov::element::Type& prc, const ov::element::Type& forcedPrec) {
if (isBitwise(algorithm)) {
Expand Down Expand Up @@ -1658,6 +1700,10 @@ void Eltwise::initSupportedPrimitiveDescriptors() {
if (useJit) {
impl_type = impl_desc_type::jit_asimd;
}
#elif defined(OPENVINO_ARCH_RISCV64)
if (useJit) {
impl_type = impl_desc_type::jit_rvv;
}
#else
impl_type = impl_desc_type::undef;
#endif
Expand Down Expand Up @@ -1687,6 +1733,12 @@ void Eltwise::initSupportedPrimitiveDescriptors() {
} else {
OPENVINO_THROW("not supported architecture");
}
#elif defined(OPENVINO_ARCH_RISCV64)
if (mayiuse(ov::intel_cpu::riscv64::imafdcv)) {
impl_type = impl_desc_type::jit_rvv;
} else {
OPENVINO_THROW("not supported architecture");
}
#elif defined(OPENVINO_ARCH_X86_64)
if (mayiuse(dnnl::impl::cpu::x64::avx512_core)) {
impl_type = impl_desc_type::jit_avx512;
Expand Down Expand Up @@ -2302,7 +2354,7 @@ bool Eltwise::canFuseParent(const NodePtr& parentNode) const {
return false;
}
const auto& input_precisions = parentNode->getOriginalInputPrecisions();
if (!jitIsSupported(this, getAlpha(), getBeta(), getGamma(), input_precisions)) {
if (!EltwiseJitExecutor::IsSupportedOp(this, getAlpha(), getBeta(), getGamma(), input_precisions)) {
return false;
}
#else
Expand Down Expand Up @@ -2350,12 +2402,12 @@ bool Eltwise::canFuse(const NodePtr& node) const {
if (!mayiuse(dnnl::impl::cpu::aarch64::asimd) || (getInputShapeAtPort(0).getRank() > MAX_ELTWISE_DIM_RANK))
return false;

if (!jitIsSupported(this, getAlpha(), getBeta(), getGamma())) {
if (!EltwiseJitExecutor::IsSupportedOp(this, getAlpha(), getBeta(), getGamma())) {
return false;
}
const auto eltwise = dynamic_cast<const Eltwise*>(node.get());
if ((eltwise == nullptr) ||
(!jitIsSupported(eltwise, eltwise->getAlpha(), eltwise->getBeta(), eltwise->getGamma()))) {
(!EltwiseJitExecutor::IsSupportedOp(eltwise, eltwise->getAlpha(), eltwise->getBeta(), eltwise->getGamma()))) {
return false;
}
#elif defined(OPENVINO_ARCH_X86_64)
Expand Down
Loading

0 comments on commit 7e1a989

Please sign in to comment.