Skip to content
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

Implement IsInf JIT Emitter for ARM64 SIMD in OpenVINO #24471

Merged
Merged
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 @@ -540,6 +540,105 @@ std::set<std::vector<element::Type>> jit_hswish_emitter::get_supported_precision
return {{element::f32}};
}

/// IS_INF ///

jit_is_inf_emitter::jit_is_inf_emitter(dnnl::impl::cpu::aarch64::jit_generator* host,
dnnl::impl::cpu::aarch64::cpu_isa_t host_isa,
const std::shared_ptr<ov::Node>& node)
: jit_emitter(host, host_isa, node, get_arithmetic_binary_exec_precision(node)) {

auto isInf = ov::as_type_ptr<ov::op::v10::IsInf>(node);
if (isInf == nullptr) {
OV_CPU_JIT_EMITTER_THROW("Can't cast to ov::op::v10::IsInf");
}

const auto& attributes = isInf->get_attributes();
detect_negative = attributes.detect_negative;
detect_positive = attributes.detect_positive;

prepare_table();
}

jit_is_inf_emitter::jit_is_inf_emitter(dnnl::impl::cpu::aarch64::jit_generator* host,
dnnl::impl::cpu::aarch64::cpu_isa_t host_isa,
const bool detect_negative,
const bool detect_positive,
const ov::element::Type exec_prc)
: jit_emitter(host, host_isa, exec_prc),
detect_negative{detect_negative},
detect_positive{detect_positive} {
prepare_table();
}

size_t jit_is_inf_emitter::get_inputs_count() const {
return 1;
}

size_t jit_is_inf_emitter::get_aux_vecs_count() const {
return 1;
}

size_t jit_is_inf_emitter::get_aux_gprs_count() const {
return 1;
}

std::set<std::vector<element::Type>> jit_is_inf_emitter::get_supported_precisions(
const std::shared_ptr<ov::Node>& node) {
return {{element::f32}};
}

void jit_is_inf_emitter::emit_impl(const std::vector<size_t>& in_vec_idxs,
const std::vector<size_t>& out_vec_idxs) const {
if (host_isa_ == dnnl::impl::cpu::aarch64::asimd) {
emit_isa<dnnl::impl::cpu::aarch64::asimd>(in_vec_idxs, out_vec_idxs);
} else {
OV_CPU_JIT_EMITTER_THROW("Can't create jit eltwise kernel");
}
}

template <dnnl::impl::cpu::aarch64::cpu_isa_t isa>
void jit_is_inf_emitter::emit_isa(const std::vector<size_t>& in_vec_idxs,
const std::vector<size_t>& out_vec_idxs) const {
OV_CPU_JIT_EMITTER_ASSERT(exec_prc_ == ov::element::f32, "unsupported precision: " + exec_prc_.to_string());

using TReg = typename dnnl::impl::cpu::aarch64::cpu_isa_traits<isa>::TReg;
const TReg src = TReg(in_vec_idxs[0]);
const TReg dst = TReg(out_vec_idxs[0]);
const TReg aux = TReg(aux_vec_idxs[0]);

if (detect_negative || detect_positive) {
if (detect_positive) {
if (detect_negative) {
// If both positive and negative infinity detection is requested
// calculate the absolute value of 'src'.
h->fabs(src.s, src.s);
}
// Load 'aux' with positive infinity.
h->ld1r(aux.s, table_val2("inf"));
} else if (detect_negative) {
// Load 'aux' with negative infinity.
h->ld1r(aux.s, table_val2("inf_neg"));
}
// Compare elements of 'src' with 'aux'.
h->fcmeq(dst.s, src.s, aux.s);
// Sets elements in 'dst' to 1.0 where the comparison was true.
h->ld1r(aux.s, table_val2("one"));
h->and_(dst.b16, dst.b16, aux.b16);

} else {
// If neither positive nor negative infinity detection is enabled,
// set 'dst' with zeros (a eor a is 0)
h->eor(dst.b16, dst.b16, dst.b16);
}
}

void jit_is_inf_emitter::register_table_entries() {
// Registers constant values that comply with the IEEE 754 standard.
push_arg_entry_of("one", 0x3F800000, true);
push_arg_entry_of("inf", 0x7F800000, true);
push_arg_entry_of("inf_neg", 0xFF800000, true);
}

/// MAX ///
jit_maximum_emitter::jit_maximum_emitter(dnnl::impl::cpu::aarch64::jit_generator* host,
dnnl::impl::cpu::aarch64::cpu_isa_t host_isa,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,39 @@ class jit_mish_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_is_inf_emitter : public jit_emitter {
public:
jit_is_inf_emitter(dnnl::impl::cpu::aarch64::jit_generator* host,
dnnl::impl::cpu::aarch64::cpu_isa_t host_isa,
const std::shared_ptr<ov::Node>& node);

jit_is_inf_emitter(dnnl::impl::cpu::aarch64::jit_generator* host,
dnnl::impl::cpu::aarch64::cpu_isa_t host_isa,
const bool detect_negative,
const bool detect_positive,
const ov::element::Type exec_prc = ov::element::f32);

size_t get_inputs_count() const override;

size_t get_aux_vecs_count() const override;

size_t get_aux_gprs_count() 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 <dnnl::impl::cpu::aarch64::cpu_isa_t isa>
void emit_isa(const std::vector<size_t>& in_vec_idxs, const std::vector<size_t>& out_vec_idxs) const;

void register_table_entries() override;

bool detect_negative;
bool detect_positive;
};

class jit_mod_emitter : public jit_emitter {
public:
jit_mod_emitter(dnnl::impl::cpu::aarch64::jit_generator *host,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bool JitEltwiseExecutor::isSupported(
Algorithm::EltwiseEqual,
Algorithm::EltwiseExp,
Algorithm::EltwiseHswish,
Algorithm::EltwiseIsInf,
Algorithm::EltwiseMaximum,
Algorithm::EltwiseMinimum,
Algorithm::EltwiseMish,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,17 @@ struct EltwiseEmitter<jit_power_static_emitter> {
}
};

template<>
struct EltwiseEmitter<jit_is_inf_emitter> {
void operator()(EltwiseEmitterContext& ctx) {
ctx.emitter = std::make_shared<jit_is_inf_emitter>(ctx.host,
ctx.host_isa,
ctx.opData.alpha,
ctx.opData.beta,
ctx.exec_prc);
}
};

template <dnnl::impl::cpu::aarch64::cpu_isa_t isa>
std::shared_ptr<jit_emitter> jit_uni_eltwise_generic<isa>::create_eltwise_emitter(const EltwiseData& data, const ov::element::Type& exec_prec) {
EltwiseEmitterContext ctx = {
Expand All @@ -637,6 +648,7 @@ std::shared_ptr<jit_emitter> jit_uni_eltwise_generic<isa>::create_eltwise_emitte
OV_CASE(Algorithm::EltwiseEqual, ov::intel_cpu::aarch64::jit_equal_emitter),
OV_CASE(Algorithm::EltwiseExp, ov::intel_cpu::aarch64::jit_exp_emitter),
OV_CASE(Algorithm::EltwiseHswish, ov::intel_cpu::aarch64::jit_hswish_emitter),
OV_CASE(Algorithm::EltwiseIsInf, ov::intel_cpu::aarch64::jit_is_inf_emitter),
OV_CASE(Algorithm::EltwiseMaximum, ov::intel_cpu::aarch64::jit_maximum_emitter),
OV_CASE(Algorithm::EltwiseMinimum, ov::intel_cpu::aarch64::jit_minimum_emitter),
OV_CASE(Algorithm::EltwiseMish, ov::intel_cpu::aarch64::jit_mish_emitter),
Expand Down Expand Up @@ -804,6 +816,7 @@ std::set<std::vector<element::Type>> eltwise_precision_helper::get_supported_pre
OV_CASE(Algorithm::EltwiseEqual, jit_equal_emitter),
OV_CASE(Algorithm::EltwiseExp, jit_exp_emitter),
OV_CASE(Algorithm::EltwiseHswish, jit_hswish_emitter),
OV_CASE(Algorithm::EltwiseIsInf, jit_is_inf_emitter),
OV_CASE(Algorithm::EltwiseMaximum, jit_maximum_emitter),
OV_CASE(Algorithm::EltwiseMinimum, jit_minimum_emitter),
OV_CASE(Algorithm::EltwiseMish, jit_mish_emitter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ std::string ActivationLayerCPUTest::getPrimitiveType(const utils::ActivationType
(activation_type == utils::ActivationTypes::Elu) ||
(activation_type == utils::ActivationTypes::Exp) ||
(activation_type == utils::ActivationTypes::HSwish) ||
(activation_type == utils::ActivationTypes::IsInf) ||
(activation_type == utils::ActivationTypes::HardSigmoid) ||
(activation_type == utils::ActivationTypes::Mish) ||
(activation_type == utils::ActivationTypes::Relu) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ const std::map<ActivationTypes, std::vector<std::vector<float>>> activationTypes
{ActivationTypes::RoundHalfAwayFromZero, {}},
{ActivationTypes::GeluErf, {}},
{ActivationTypes::GeluTanh, {}},
{ActivationTypes::Swish, {{0.4f}}}
{ActivationTypes::Swish, {{0.4f}}},
{ActivationTypes::IsInf, {}}
};

// List of operations that should be tested also with integer precision
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static std::map<ActivationTypes, std::string> activationNames = {
{ActivationTypes::GeluErf, "GeluErf"},
{ActivationTypes::GeluTanh, "GeluTanh"},
{ActivationTypes::SoftSign, "SoftSign"},
{ActivationTypes::IsInf, "IsInf"},
};

typedef std::tuple<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ enum ActivationTypes {
RoundHalfAwayFromZero,
GeluErf,
GeluTanh,
SoftSign
SoftSign,
IsInf
};

enum MinMaxOpType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "openvino/op/hard_sigmoid.hpp"
#include "openvino/op/hsigmoid.hpp"
#include "openvino/op/hswish.hpp"
#include "openvino/op/is_inf.hpp"
#include "openvino/op/log.hpp"
#include "openvino/op/mish.hpp"
#include "openvino/op/negative.hpp"
Expand Down Expand Up @@ -144,6 +145,8 @@ std::shared_ptr<ov::Node> make_activation(const ov::Output<Node>& in,
return std::make_shared<ov::op::v7::Gelu>(in, ov::op::GeluApproximationMode::TANH);
case ov::test::utils::ActivationTypes::SoftSign:
return std::make_shared<ov::op::v9::SoftSign>(in);
case ov::test::utils::ActivationTypes::IsInf:
return std::make_shared<ov::op::v10::IsInf>(in);
default:
OPENVINO_THROW("Can't create layer for this activation type");
}
Expand Down
Loading