Skip to content

Commit 8d96c5e

Browse files
[GPU] Integer abs support for activation
1 parent 11cacc9 commit 8d96c5e

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

src/plugins/intel_gpu/src/graph/activation.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ layout activation_inst::calc_output_layout(activation_node const& node, kernel_i
2626
activation_func::negation,
2727
activation_func::relu,
2828
activation_func::floor,
29-
activation_func::clamp };
29+
activation_func::clamp,
30+
activation_func::abs };
3031

3132
if (input_node_layout.data_type == data_types::i8 || input_node_layout.data_type == data_types::u8 ||
3233
input_node_layout.data_type == data_types::i32) {

src/plugins/intel_gpu/src/kernel_selector/kernels/activation/activation_kernel_opt.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ bool ActivationKernelOpt::Validate(const Params& p) const {
9090
(params.outputs[0].GetLayout() != DataLayout::bfyx && params.outputs[0].GetLayout() != DataLayout::bfzyx))
9191
return false;
9292

93+
auto input_dt = params.inputs[0].GetDType();
94+
if (input_dt == Datatype::INT8 || input_dt == Datatype::INT32) {
95+
for (auto act : params.activations) {
96+
if (act.function == ActivationFunction::ABS)
97+
return false;
98+
}
99+
}
100+
93101
return true;
94102
}
95103

src/plugins/intel_gpu/tests/unit/test_cases/activation_simple_gpu_test.cpp

+72-1
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,8 @@ TEST(activation_i32_fw_gpu, basic_yxfb_i32_funcs) {
15791579
activation_func::negation,
15801580
activation_func::relu,
15811581
activation_func::clamp,
1582-
activation_func::floor
1582+
activation_func::floor,
1583+
activation_func::abs
15831584
};
15841585

15851586
for (auto func : funcs) {
@@ -1620,6 +1621,76 @@ TEST(activation_i32_fw_gpu, basic_yxfb_i32_funcs) {
16201621
case activation_func::floor:
16211622
ASSERT_EQ((int32_t)std::floor(input_ptr[i]), output_ptr[i]);
16221623
break;
1624+
case activation_func::abs:
1625+
ASSERT_EQ(std::abs(static_cast<int32_t>(input_ptr[i])), output_ptr[i]);
1626+
break;
1627+
default:
1628+
break;
1629+
}
1630+
}
1631+
}
1632+
}
1633+
1634+
TEST(activation_i32_fw_gpu, basic_yxfb_u8_funcs) {
1635+
auto& engine = get_test_engine();
1636+
auto input = engine.allocate_memory({ data_types::u8, format::yxfb,{ 2, 2, 2, 2 } });
1637+
1638+
std::vector<uint8_t> input_vec = {
1639+
1, 0, 5, 1,
1640+
2, 0, 6, 5,
1641+
3, 0, 7, 12,
1642+
4, 0, 8, 8
1643+
};
1644+
set_values(input, input_vec);
1645+
1646+
// functions valid for uint8 type input
1647+
std::vector<activation_func> funcs = {
1648+
activation_func::none,
1649+
activation_func::negation,
1650+
activation_func::relu,
1651+
activation_func::clamp,
1652+
activation_func::floor,
1653+
activation_func::abs
1654+
};
1655+
1656+
for (auto func : funcs) {
1657+
topology topology;
1658+
activation_additional_params params = {0.0, 1.0};
1659+
topology.add(input_layout("input", input->get_layout()));
1660+
topology.add(activation("activation", input_info("input"), func, params));
1661+
1662+
network network(engine, topology, get_test_default_config(engine));
1663+
network.set_input_data("input", input);
1664+
auto outputs = network.execute();
1665+
1666+
ASSERT_EQ(outputs.size(), size_t(1));
1667+
ASSERT_EQ(outputs.begin()->first, "activation");
1668+
1669+
auto output_memory = outputs.at("activation").get_memory();
1670+
auto output_layout = output_memory->get_layout();
1671+
cldnn::mem_lock<uint8_t> output_ptr(output_memory, get_test_stream());
1672+
cldnn::mem_lock<uint8_t> input_ptr(input, get_test_stream());
1673+
1674+
for (size_t i = 0; i < output_layout.get_linear_size(); ++i) {
1675+
switch (func) {
1676+
case activation_func::none:
1677+
ASSERT_EQ((uint8_t)input_ptr[i], output_ptr[i]);
1678+
break;
1679+
case activation_func::negation:
1680+
ASSERT_EQ(!((uint8_t)input_ptr[i]), output_ptr[i]);
1681+
break;
1682+
case activation_func::relu:
1683+
ASSERT_EQ((uint8_t)(std::max(static_cast<int32_t>(input_ptr[i]), 0)), output_ptr[i]);
1684+
break;
1685+
case activation_func::clamp:
1686+
ASSERT_EQ(std::min(std::max(input_ptr[i], static_cast<uint8_t>(params.a)), static_cast<uint8_t>(params.b)), output_ptr[i]);
1687+
break;
1688+
case activation_func::floor:
1689+
ASSERT_EQ((uint8_t)std::floor(input_ptr[i]), output_ptr[i]);
1690+
break;
1691+
case activation_func::abs:
1692+
ASSERT_EQ(std::abs(static_cast<uint8_t>(input_ptr[i])), output_ptr[i]);
1693+
break;
16231694
default:
16241695
break;
16251696
}

0 commit comments

Comments
 (0)