Skip to content

implemented eltwise 'Equal' operation #30293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,41 @@ std::set<std::vector<element::Type>> jit_divide_emitter::get_supported_precision
return {{element::f32, element::f32}};
}

/// Equal ///
jit_equal_emitter::jit_equal_emitter(ov::intel_cpu::riscv64::jit_generator* host, ov::intel_cpu::riscv64::cpu_isa_t host_isa,
const std::shared_ptr<ov::Node>& node, const ov::element::Type exec_prc)
: jit_emitter(host, host_isa, exec_prc) {}

jit_equal_emitter::jit_equal_emitter(ov::intel_cpu::riscv64::jit_generator* host, ov::intel_cpu::riscv64::cpu_isa_t host_isa,
const ov::element::Type exec_prc)
: jit_emitter(host, host_isa, exec_prc) {}

size_t jit_equal_emitter::get_inputs_num() const {
return 2; // Equal operation requires two inputs
}

void jit_equal_emitter::emit_impl(const std::vector<size_t>& in_vec_idxs, const std::vector<size_t>& out_vec_idxs) const {
if (host_isa_ == ov::intel_cpu::riscv64::cpu_isa_t::gv) {
emit_isa<ov::intel_cpu::riscv64::cpu_isa_t::gv>(in_vec_idxs, out_vec_idxs);
} else {
OPENVINO_THROW("Can't create jit eltwise kernel");
}
}

template <ov::intel_cpu::riscv64::cpu_isa_t isa>
void jit_equal_emitter::emit_isa(const std::vector<size_t>& in_vec_idxs, const std::vector<size_t>& out_vec_idxs) const {
VReg src0 = VReg(in_vec_idxs[0]);
VReg src1 = VReg(in_vec_idxs[1]);
VReg dst = VReg(out_vec_idxs[0]);

// Use the RISC-V vector instruction for equality comparison
h->vmseq_vv(dst, src0, src1); // Set dst[i] = 1 if src0[i] == src1[i], else 0
Comment on lines +209 to +210
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're closer to the right implementation! But:

  • The current JIT emitter should work with FP32 values (floating points values). We should use instructions which works with such values (not integer). Please take a look at section "13.13. Vector Floating-Point Compare Instructions" in the doc. Currently you use vmseq instruction which should be used for comparison of integer values. Please replace it with correct instruction.
  • Also since we work with FP32 values here, the destination vector should store values in FP32 format where True = 1 = 0x3f800000 and False = 0 = 0x0. Please take a look at he impl on ARM64 using SIMD. It might be useful for you.
  • Some hint: probably you need to use mask vector register (mask_vreg())

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Launched GHA, many Equal tests are failed:

[ RUN      ] smoke_CompareWithRefs/ComparisonLayerTest.Inference/IS=([]_[])_TS={(1)_(1)}_comparisonOpType=Equal_secondInputType=PARAMETER_in_type=f32_targetDevice=CPU

MEM_USAGE=4401632KB

Expected: 1 Actual: 0 Coordinate: 0 Diff: 1 calculated_abs_threshold: 0.000100119 abs_threshold: 1.19209e-07 rel_threshold: 0.0001
src/tests/functional/shared_test_classes/src/base/ov_subgraph.cpp:97: Failure
[ COMPARATION ] COMPARATION IS FAILED!
[  FAILED  ] smoke_CompareWithRefs/ComparisonLayerTest.Inference/IS=([]_[])_TS={(1)_(1)}_comparisonOpType=Equal_secondInputType=PARAMETER_in_type=f32_targetDevice=CPU, where GetParam() = ({ ({}, { { 1 } }), ({}, { { 1 } }) }, Equal, PARAMETER, f32, "CPU", {}) (119 ms)

I believe that my previous comment will help you to fix it 😊

}

std::set<std::vector<element::Type>> jit_equal_emitter::get_supported_precisions(const std::shared_ptr<ov::Node>& node) {
return {{element::f32, element::f32}}; // Support fp32 precision
}

/// Exp ///
jit_exp_emitter::jit_exp_emitter(ov::intel_cpu::riscv64::jit_generator* host, ov::intel_cpu::riscv64::cpu_isa_t host_isa,
const std::shared_ptr<ov::Node>& node, const ov::element::Type exec_prc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,23 @@ class jit_subtract_emitter : public jit_emitter {
void emit_isa(const std::vector<size_t>& in_vec_idxs, const std::vector<size_t>& out_vec_idxs) const;
};

class jit_equal_emitter : public jit_emitter {
public:
jit_equal_emitter(ov::intel_cpu::riscv64::jit_generator* host, ov::intel_cpu::riscv64::cpu_isa_t host_isa,
const std::shared_ptr<ov::Node>& node, const ov::element::Type exec_prc);
jit_equal_emitter(ov::intel_cpu::riscv64::jit_generator* host, ov::intel_cpu::riscv64::cpu_isa_t host_isa,
const ov::element::Type exec_prc);

size_t get_inputs_num() const override;

static std::set<std::vector<element::Type>> get_supported_precisions(const std::shared_ptr<ov::Node>& node = nullptr);

private:
void emit_impl(const std::vector<size_t>& in_vec_idxs, const std::vector<size_t>& out_vec_idxs) const override;

template <ov::intel_cpu::riscv64::cpu_isa_t isa>
void emit_isa(const std::vector<size_t>& in_vec_idxs, const std::vector<size_t>& out_vec_idxs) const;
};

} // ov::intel_cpu::riscv64

1 change: 1 addition & 0 deletions src/plugins/intel_cpu/src/nodes/eltwise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ class EltwiseJitExecutor : public Eltwise::IEltwiseExecutor {

#elif defined(OPENVINO_ARCH_RISCV64)
if (!one_of(algorithm,
Algorithm::EltwiseEqual,
Algorithm::EltwiseAbs,
Algorithm::EltwiseAdd,
Algorithm::EltwiseClamp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ struct EltwiseEmitter<jit_relu_emitter> {
ctx.emitter = std::make_shared<jit_relu_emitter>(ctx.host, ctx.host_isa, ctx.opData.alpha, ctx.exec_prc);
}
};
} // namespace
} //namespace

template <ov::intel_cpu::riscv64::cpu_isa_t isa>
std::shared_ptr<jit_emitter> jit_uni_eltwise_generic<isa>::create_eltwise_emitter(const EltwiseData& data,
Expand All @@ -418,7 +418,8 @@ std::shared_ptr<jit_emitter> jit_uni_eltwise_generic<isa>::create_eltwise_emitte
OV_CASE(Algorithm::EltwisePrelu, jit_prelu_emitter),
OV_CASE(Algorithm::EltwiseRelu, jit_relu_emitter),
OV_CASE(Algorithm::EltwiseSigmoid, jit_sigmoid_emitter),
OV_CASE(Algorithm::EltwiseSubtract, jit_subtract_emitter));
OV_CASE(Algorithm::EltwiseSubtract, jit_subtract_emitter),
OV_CASE(Algorithm::EltwiseEqual, jit_equal_emitter));

if (!ctx.emitter) {
OPENVINO_THROW("Unsupported operation type '" + algToString(data.algo) + "' for Eltwise emitter");
Expand Down Expand Up @@ -544,7 +545,8 @@ std::set<std::vector<element::Type>> eltwise_precision_helper::get_supported_pre
OV_CASE(Algorithm::EltwisePrelu, jit_prelu_emitter),
OV_CASE(Algorithm::EltwiseRelu, jit_relu_emitter),
OV_CASE(Algorithm::EltwiseSigmoid, jit_sigmoid_emitter),
OV_CASE(Algorithm::EltwiseSubtract, jit_subtract_emitter));
OV_CASE(Algorithm::EltwiseSubtract, jit_subtract_emitter),
OV_CASE(Algorithm::EltwiseEqual, jit_equal_emitter));

if (precisions.empty()) {
OPENVINO_THROW("Unsupported operation type for Eltwise emitter");
Expand Down
Loading