Skip to content

Commit 4004b84

Browse files
[GPU] Integer abs support for activation
1 parent 8db08c1 commit 4004b84

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
@@ -1639,7 +1639,8 @@ TEST(activation_i32_fw_gpu, basic_yxfb_i32_funcs) {
16391639
activation_func::negation,
16401640
activation_func::relu,
16411641
activation_func::clamp,
1642-
activation_func::floor
1642+
activation_func::floor,
1643+
activation_func::abs
16431644
};
16441645

16451646
for (auto func : funcs) {
@@ -1680,6 +1681,76 @@ TEST(activation_i32_fw_gpu, basic_yxfb_i32_funcs) {
16801681
case activation_func::floor:
16811682
ASSERT_EQ((int32_t)std::floor(input_ptr[i]), output_ptr[i]);
16821683
break;
1684+
case activation_func::abs:
1685+
ASSERT_EQ(std::abs(static_cast<int32_t>(input_ptr[i])), output_ptr[i]);
1686+
break;
1687+
default:
1688+
break;
1689+
}
1690+
}
1691+
}
1692+
}
1693+
1694+
TEST(activation_i32_fw_gpu, basic_yxfb_u8_funcs) {
1695+
auto& engine = get_test_engine();
1696+
auto input = engine.allocate_memory({ data_types::u8, format::yxfb,{ 2, 2, 2, 2 } });
1697+
1698+
std::vector<uint8_t> input_vec = {
1699+
1, 0, 5, 1,
1700+
2, 0, 6, 5,
1701+
3, 0, 7, 12,
1702+
4, 0, 8, 8
1703+
};
1704+
set_values(input, input_vec);
1705+
1706+
// functions valid for uint8 type input
1707+
std::vector<activation_func> funcs = {
1708+
activation_func::none,
1709+
activation_func::negation,
1710+
activation_func::relu,
1711+
activation_func::clamp,
1712+
activation_func::floor,
1713+
activation_func::abs
1714+
};
1715+
1716+
for (auto func : funcs) {
1717+
topology topology;
1718+
activation_additional_params params = {0.0, 1.0};
1719+
topology.add(input_layout("input", input->get_layout()));
1720+
topology.add(activation("activation", input_info("input"), func, params));
1721+
1722+
network network(engine, topology, get_test_default_config(engine));
1723+
network.set_input_data("input", input);
1724+
auto outputs = network.execute();
1725+
1726+
ASSERT_EQ(outputs.size(), size_t(1));
1727+
ASSERT_EQ(outputs.begin()->first, "activation");
1728+
1729+
auto output_memory = outputs.at("activation").get_memory();
1730+
auto output_layout = output_memory->get_layout();
1731+
cldnn::mem_lock<uint8_t> output_ptr(output_memory, get_test_stream());
1732+
cldnn::mem_lock<uint8_t> input_ptr(input, get_test_stream());
1733+
1734+
for (size_t i = 0; i < output_layout.get_linear_size(); ++i) {
1735+
switch (func) {
1736+
case activation_func::none:
1737+
ASSERT_EQ((uint8_t)input_ptr[i], output_ptr[i]);
1738+
break;
1739+
case activation_func::negation:
1740+
ASSERT_EQ(!((uint8_t)input_ptr[i]), output_ptr[i]);
1741+
break;
1742+
case activation_func::relu:
1743+
ASSERT_EQ((uint8_t)(std::max(static_cast<int32_t>(input_ptr[i]), 0)), output_ptr[i]);
1744+
break;
1745+
case activation_func::clamp:
1746+
ASSERT_EQ(std::min(std::max(input_ptr[i], static_cast<uint8_t>(params.a)), static_cast<uint8_t>(params.b)), output_ptr[i]);
1747+
break;
1748+
case activation_func::floor:
1749+
ASSERT_EQ((uint8_t)std::floor(input_ptr[i]), output_ptr[i]);
1750+
break;
1751+
case activation_func::abs:
1752+
ASSERT_EQ(std::abs(static_cast<uint8_t>(input_ptr[i])), output_ptr[i]);
1753+
break;
16831754
default:
16841755
break;
16851756
}

0 commit comments

Comments
 (0)