[IE CLDNN] Fix gather dimensions calculation (#960)
This commit is contained in:
@@ -88,7 +88,7 @@ static std::string GetDictionaryIndexOrder(const gather_params& params, size_t a
|
||||
const std::string zeroVal = "0";
|
||||
|
||||
size_t dictionary_dims_num = GetNonEmptyDimsNumber(params.inputs[0]);
|
||||
size_t indices_dims_num = GetNonEmptyDimsNumber(params.inputs[1]);
|
||||
size_t indices_dims_num = GetNonEmptyDimsNumber(params.output) - dictionary_dims_num + 1;
|
||||
|
||||
// Shift indices of Gather dictionary input related to output dims
|
||||
for (size_t i = axis + 1; i < dictionary_dims_num; i++)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019 Intel Corporation
|
||||
// Copyright (c) 2019-2020 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@@ -750,3 +750,191 @@ TEST(gather_gpu_int32, d22_axisY) {
|
||||
EXPECT_EQ(expected_results[i], output_ptr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(gather_gpu_fp32, d41_axisB) {
|
||||
// Dictionary : 2x2x3x1
|
||||
// Indexes : 4x1x1x1
|
||||
// Axis : 0
|
||||
// Output : 4x1x2x3
|
||||
// Input values in fp32, indices in i32
|
||||
|
||||
// Indexes:
|
||||
// 0, 1, 1, 0
|
||||
//
|
||||
// Dictionary:
|
||||
// 1, 2, 3, 4, 5, 6,
|
||||
// 7, 8, 9, 10, 11, 12
|
||||
//
|
||||
// Output:
|
||||
// 1, 2, 3, 4, 5, 6,
|
||||
// 7, 8, 9, 10, 11, 12
|
||||
// 7, 8, 9, 10, 11, 12
|
||||
// 1, 2, 3, 4, 5, 6,
|
||||
|
||||
engine engine;
|
||||
|
||||
auto input1 = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 2, 1, 3 } }); // Dictionary
|
||||
auto input2 = memory::allocate(engine, { data_types::i32, format::bfyx, { 4, 1, 1, 1 } }); // Indexes
|
||||
auto axis = cldnn::gather::gather_axis::along_b;
|
||||
|
||||
set_values(input1, {
|
||||
1.f, 2.f, 3.f,
|
||||
4.f, 5.f, 6.f,
|
||||
|
||||
7.f, 8.f, 9.f,
|
||||
10.f, 11.f, 12.f
|
||||
});
|
||||
|
||||
set_values(input2, {
|
||||
0, 1, 1, 0
|
||||
});
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("InputDictionary", input1.get_layout()));
|
||||
topology.add(input_layout("InputText", input2.get_layout()));
|
||||
topology.add(
|
||||
gather("gather", "InputDictionary", "InputText", axis, tensor(4, 1, 3, 2))
|
||||
);
|
||||
|
||||
network network(engine, topology);
|
||||
|
||||
network.set_input_data("InputDictionary", input1);
|
||||
network.set_input_data("InputText", input2);
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
auto output = outputs.at("gather").get_memory();
|
||||
auto output_ptr = output.pointer<float>();
|
||||
|
||||
std::vector<float> expected_results = {
|
||||
1.f, 2.f, 3.f, 4.f, 5.f, 6.f,
|
||||
7.f, 8.f, 9.f, 10.f, 11.f, 12.f,
|
||||
7.f, 8.f, 9.f, 10.f, 11.f, 12.f,
|
||||
1.f, 2.f, 3.f, 4.f, 5.f, 6.f
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected_results.size(), output_ptr.size());
|
||||
for (size_t i = 0; i < expected_results.size(); ++i) {
|
||||
EXPECT_EQ(expected_results[i], output_ptr[i]) << " at i=" << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(gather_gpu_fp32, d41_axisF) {
|
||||
// Dictionary : 2x3x2x1
|
||||
// Indexes : 4x1x1x1
|
||||
// Axis : 0
|
||||
// Output : 2x4x1x2
|
||||
// Input values in fp32, indices in i32
|
||||
|
||||
// Indexes:
|
||||
// 1, 0, 1, 2
|
||||
//
|
||||
// Dictionary:
|
||||
// 1, 2, 3, 4, 5, 6,
|
||||
// 7, 8, 9, 10, 11, 12
|
||||
//
|
||||
// Output:
|
||||
// 3, 4, 1, 2, 3, 4, 5, 6,
|
||||
// 9, 10, 7, 8, 9, 10, 11, 12
|
||||
|
||||
engine engine;
|
||||
|
||||
auto input1 = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 3, 1, 2 } }); // Dictionary
|
||||
auto input2 = memory::allocate(engine, { data_types::i32, format::bfyx, { 4, 1, 1, 1 } }); // Indexes
|
||||
auto axis = cldnn::gather::gather_axis::along_f;
|
||||
|
||||
set_values(input1, {
|
||||
1.f, 2.f, 3.f, 4.f, 5.f, 6.f,
|
||||
7.f, 8.f, 9.f, 10.f, 11.f, 12.f
|
||||
});
|
||||
|
||||
set_values(input2, {
|
||||
1, 0, 1, 2
|
||||
});
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("InputDictionary", input1.get_layout()));
|
||||
topology.add(input_layout("InputText", input2.get_layout()));
|
||||
topology.add(
|
||||
gather("gather", "InputDictionary", "InputText", axis, tensor(2, 4, 2, 1))
|
||||
);
|
||||
|
||||
network network(engine, topology);
|
||||
|
||||
network.set_input_data("InputDictionary", input1);
|
||||
network.set_input_data("InputText", input2);
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
auto output = outputs.at("gather").get_memory();
|
||||
auto output_ptr = output.pointer<float>();
|
||||
|
||||
std::vector<float> expected_results = {
|
||||
3.f, 4.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f,
|
||||
9.f, 10.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected_results.size(), output_ptr.size());
|
||||
for (size_t i = 0; i < expected_results.size(); ++i) {
|
||||
EXPECT_EQ(expected_results[i], output_ptr[i]) << " at i=" << i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(gather_gpu_fp32, d2_axisX) {
|
||||
// Dictionary : 2x2x1x1
|
||||
// Indexes : 2x1x1x1
|
||||
// Axis : 0
|
||||
// Output : 2x2x1x2
|
||||
// Input values in fp32, indices in i32
|
||||
|
||||
// Indexes:
|
||||
// 0, 0
|
||||
//
|
||||
// Dictionary:
|
||||
// 1, 2, 3, 4
|
||||
//
|
||||
// Output:
|
||||
// 1, 1, 2, 2, 3, 3, 4, 4
|
||||
|
||||
engine engine;
|
||||
|
||||
auto input1 = memory::allocate(engine, { data_types::f32, format::bfyx, { 2, 2, 1, 1 } }); // Dictionary
|
||||
auto input2 = memory::allocate(engine, { data_types::i32, format::bfyx, { 2, 1, 1, 1 } }); // Indexes
|
||||
auto axis = cldnn::gather::gather_axis::along_x;
|
||||
|
||||
set_values(input1, {
|
||||
1.f, 2.f,
|
||||
3.f, 4.f,
|
||||
});
|
||||
|
||||
set_values(input2, {
|
||||
0, 0
|
||||
});
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("InputDictionary", input1.get_layout()));
|
||||
topology.add(input_layout("InputText", input2.get_layout()));
|
||||
topology.add(
|
||||
gather("gather", "InputDictionary", "InputText", axis, tensor(2, 2, 2, 1))
|
||||
);
|
||||
|
||||
network network(engine, topology);
|
||||
|
||||
network.set_input_data("InputDictionary", input1);
|
||||
network.set_input_data("InputText", input2);
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
auto output = outputs.at("gather").get_memory();
|
||||
auto output_ptr = output.pointer<float>();
|
||||
|
||||
std::vector<float> expected_results = {
|
||||
1.f, 1.f, 2.f, 2.f,
|
||||
3.f, 3.f, 4.f, 4.f
|
||||
};
|
||||
|
||||
ASSERT_EQ(expected_results.size(), output_ptr.size());
|
||||
for (size_t i = 0; i < expected_results.size(); ++i) {
|
||||
EXPECT_EQ(expected_results[i], output_ptr[i]) << " at i=" << i;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user