1 // Copyright (C) 2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include <gtest/gtest.h>
6 #include <gmock/gmock-spec-builders.h>
7 #include "mkldnn_plugin/mkldnn_graph.h"
9 #include "test_graph.hpp"
11 #include "single_layer_common.hpp"
12 #include <mkldnn_plugin/mkldnn_extension_utils.h>
13 #include <extension/ext_list.hpp>
14 #include "tests_common.hpp"
17 using namespace ::testing;
19 using namespace mkldnn;
22 struct reverse_sequence_test_params {
23 std::string inIdxPrecision;
24 InferenceEngine::SizeVector in_out_shape;
25 std::vector<int32_t> seq_lengths;
28 std::vector<float> reference;
30 std::vector<std::function<void(MKLDNNPlugin::PrimitiveDescInfo)>> comp;
33 template <typename data_t>
34 void ref_reverse_sequence(
35 InferenceEngine::TBlob<float> &src,
36 InferenceEngine::TBlob<data_t> &seq_lengths,
37 InferenceEngine::TBlob<float> &dst,
42 const float *src_data = src.data();
43 InferenceEngine::SizeVector src_dims = src.getTensorDesc().getDims();
44 InferenceEngine::SizeVector srcStrides = src.getTensorDesc().getBlockingDesc().getStrides();
45 const data_t *seq_lengths_data = seq_lengths.data();
46 InferenceEngine::SizeVector seq_lengths_dims = seq_lengths.getTensorDesc().getDims();
47 float* dst_data = dst.data();
50 seq_axis += src_dims.size();
52 if (seq_axis < 0 || seq_axis >= src_dims.size())
53 FAIL() << "Incorrect 'seq_axis' parameters dimensions and axis number!";
56 batch_axis += src_dims.size();
58 if (batch_axis < 0 || batch_axis >= src_dims.size())
59 FAIL() << "Incorrect 'batch_axis' parameters dimensions and axis number!";
61 for (i = 0; i < src_dims[batch_axis]; i++) {
62 if (static_cast<int32_t>(seq_lengths_data[i]) > src_dims[seq_axis])
63 FAIL() << "Incorrect input 'seq_lengths' values!";
66 size_t work_amount_dst = srcStrides[0] * src_dims[0];
67 InferenceEngine::SizeVector counters(src_dims.size(), 0);
68 for (size_t iwork = 0; iwork < work_amount_dst; ++iwork) {
69 for (i = 0, src_idx = 0; i < src_dims.size(); ++i) {
70 size_t idx = counters[i];
71 if (i == seq_axis && idx < static_cast<int32_t>(seq_lengths_data[counters[batch_axis]])) {
72 idx = static_cast<int32_t>(seq_lengths_data[counters[batch_axis]]) - idx - 1;
74 src_idx += idx * srcStrides[i];
77 dst_data[iwork] = src_data[src_idx];
79 for (int j = src_dims.size() - 1; j >= 0; j--) {
80 counters[j] = (counters[j] + 1) % src_dims[j];
81 if (counters[j] != 0) break;
86 class MKLDNNCPUExtReverseSequenceTests : public TestsCommon, public WithParamInterface<reverse_sequence_test_params> {
87 std::string model_t = R"V0G0N(
88 <net Name="ReverseSequence_net" version="2" precision="FP32" batch="1">
90 <layer name="input" type="Input" precision="FP32" id="1">
97 <layer name="seq_lengths" type="Input" precision="_IIDXP_" id="2">
100 <dim>_DIM_SIZE_</dim>
104 <layer name="output" id="2" type="ReverseSequence" precision="FP32">
105 <data seq_axis="_SA_" batch_axis="_BA_"/>
111 <dim>_DIM_SIZE_</dim>
122 <edge from-layer="1" from-port="1" to-layer="2" to-port="1"/>
123 <edge from-layer="2" from-port="2" to-layer="2" to-port="2"/>
128 std::string getModel(reverse_sequence_test_params p) {
129 std::string model = model_t;
130 std::string in_out_shape;
131 for (size_t i = 0; i < p.in_out_shape.size(); i++) {
132 in_out_shape += "<dim>";
133 in_out_shape += std::to_string(p.in_out_shape[i]) + "</dim>\n";
135 REPLACE_WITH_STR(model, "_IIDXP_", p.inIdxPrecision);
136 REPLACE_WITH_STR(model, "_IN_OUT_", in_out_shape);
137 REPLACE_WITH_NUM(model, "_DIM_SIZE_", p.seq_lengths.size());
138 REPLACE_WITH_NUM(model, "_SA_", p.seq_axis);
139 REPLACE_WITH_NUM(model, "_BA_", p.batch_axis);
144 virtual void TearDown() {
147 virtual void SetUp() {
149 TestsCommon::SetUp();
150 reverse_sequence_test_params p = ::testing::WithParamInterface<reverse_sequence_test_params>::GetParam();
151 std::string model = getModel(p);
152 ////std::cout << model;
153 InferenceEngine::CNNNetReader net_reader;
154 ASSERT_NO_THROW(net_reader.ReadNetwork(model.data(), model.length()));
156 InferenceEngine::Extension cpuExt(make_so_name("cpu_extension"));
157 MKLDNNPlugin::MKLDNNExtensionManager::Ptr extMgr(new MKLDNNPlugin::MKLDNNExtensionManager());
158 extMgr->AddExtension(InferenceEngine::IExtensionPtr(&cpuExt, [](InferenceEngine::IExtension*){}));
160 MKLDNNGraphTestClass graph;
161 graph.CreateGraph(net_reader.getNetwork(), extMgr);
164 InferenceEngine::OutputsDataMap out;
165 out = net_reader.getNetwork().getOutputsInfo();
166 InferenceEngine::BlobMap outputBlobs;
168 std::pair<std::string, InferenceEngine::DataPtr> item = *out.begin();
170 InferenceEngine::TBlob<float>::Ptr output;
171 output = InferenceEngine::make_shared_blob<float>(item.second->getTensorDesc());
173 outputBlobs[item.first] = output;
176 InferenceEngine::TBlob<float> dst_ref(item.second->getTensorDesc());
180 InferenceEngine::Blob::Ptr src;
181 src = InferenceEngine::make_shared_blob<float>({ InferenceEngine::Precision::FP32, p.in_out_shape, InferenceEngine::TensorDesc::getLayoutByDims(p.in_out_shape) });
183 fill_data_dbgval(src->buffer(), src->size());
184 auto * srcPtr = dynamic_cast<InferenceEngine::TBlob<float>*>(src.get());
185 if (srcPtr == nullptr)
186 FAIL() << "Cannot cast blob to TBlob<float>.";
188 InferenceEngine::BlobMap srcs;
189 srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("input", src));
191 InferenceEngine::Blob::Ptr seq_lengthsIdx;
192 InferenceEngine::SizeVector seq_lengths_dim(1, p.seq_lengths.size());
193 if (p.inIdxPrecision == "I32") {
194 seq_lengthsIdx = InferenceEngine::make_shared_blob<int32_t>({ InferenceEngine::Precision::I32, seq_lengths_dim, InferenceEngine::TensorDesc::getLayoutByDims(seq_lengths_dim) });
195 seq_lengthsIdx->allocate();
196 if (p.seq_lengths.size())
197 memcpy(static_cast<int32_t*>(seq_lengthsIdx->buffer()), &p.seq_lengths[0], sizeof(int32_t)*p.seq_lengths.size());
198 auto * seq_lengthsIdxPtr = dynamic_cast<InferenceEngine::TBlob<int32_t>*>(seq_lengthsIdx.get());
199 if (seq_lengthsIdxPtr == nullptr)
200 FAIL() << "Cannot cast blob to TBlob<int32_t>.";
203 ref_reverse_sequence(*srcPtr, *seq_lengthsIdxPtr, dst_ref, p.seq_axis, p.batch_axis);
204 if (p.reference.size()) {
205 if (memcmp(dst_ref.data(), &p.reference[0], p.reference.size() * sizeof(float)) != 0)
206 FAIL() << "Wrong result with compare TF reference!";
208 srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("seq_lengths", seq_lengthsIdx));
209 } else if (p.inIdxPrecision == "FP32") {
210 seq_lengthsIdx = InferenceEngine::make_shared_blob<float>({ InferenceEngine::Precision::FP32, seq_lengths_dim, InferenceEngine::TensorDesc::getLayoutByDims(seq_lengths_dim) });
211 seq_lengthsIdx->allocate();
212 if (p.seq_lengths.size())
213 for (size_t i = 0; i < p.seq_lengths.size(); i++) {
214 static_cast<float *>(seq_lengthsIdx->buffer())[i] = static_cast<float>(p.seq_lengths[i]);
216 auto * seq_lengthsIdxPtr = dynamic_cast<InferenceEngine::TBlob<float>*>(seq_lengthsIdx.get());
217 if (seq_lengthsIdxPtr == nullptr)
218 FAIL() << "Cannot cast blob to TBlob<float>.";
221 ref_reverse_sequence(*srcPtr, *seq_lengthsIdxPtr, dst_ref, p.seq_axis, p.batch_axis);
222 if (p.reference.size()) {
223 if (memcmp(dst_ref.data(), &p.reference[0], p.reference.size() * sizeof(float)) != 0)
224 FAIL() << "Wrong result with compare TF reference!";
226 srcs.insert(std::pair<std::string, InferenceEngine::Blob::Ptr>("seq_lengths", seq_lengthsIdx));
232 graph.Infer(srcs, outputBlobs);
233 compare(*output, dst_ref);
234 } catch (const InferenceEngine::details::InferenceEngineException &e) {
241 static std::vector<float> test0 = { 9.f,10.f,11.f,12.f,13.f,14.f,15.f,16.f,17.f,0.f,1.f,2.f,3.f,4.f,5.f,6.f,7.f,8.f,18.f,19.f,20.f,21.f,22.f,23.f,24.f,25.f,26.f };
242 static std::vector<float> test2 = { 3.f,4.f,5.f,0.f,1.f,2.f,6.f,7.f,8.f,12.f,13.f,14.f,9.f,10.f,11.f,15.f,16.f,17.f,21.f,22.f,23.f,18.f,19.f,20.f,24.f,25.f,26.f };
243 static std::vector<float> test4 = { 1.f,0.f,2.f,4.f,3.f,5.f,7.f,6.f,8.f,10.f,9.f,11.f,13.f,12.f,14.f,16.f,15.f,17.f,19.f,18.f,20.f,22.f,21.f,23.f,25.f,24.f,26.f };
244 static std::vector<float> test6 = { 2.f,1.f,0.f,4.f,3.f,5.f };
245 static std::vector<float> test7 = { 0.f,1.f,2.f,3.f,4.f,5.f,6.f,7.f,8.f,12.f,13.f,14.f,9.f,10.f,11.f,15.f,16.f,17.f,24.f,25.f,26.f,21.f,22.f,23.f,18.f,19.f,20.f };
246 static std::vector<float> test8 = { 0.f,4.f,8.f,3.f,1.f,5.f,6.f,7.f,2.f,9.f,13.f,17.f,12.f,10.f,14.f,15.f,16.f,11.f,18.f,22.f,26.f,21.f,19.f,23.f,24.f,25.f,20.f };
248 TEST_P(MKLDNNCPUExtReverseSequenceTests, TestsReverseSequence) {}
249 INSTANTIATE_TEST_CASE_P(
250 TestsReverseSequence, MKLDNNCPUExtReverseSequenceTests,
252 // Params: in_out_shape, seq_lengths, seq_axis, batch_axis, reference
253 /* 0 */ reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 2, 2, 2 }, 0, 0, test0 },
254 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 2, 2, 2 }, -3, 0, test0 },
255 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 2, 2, 2 }, 1, 0, test2 },
256 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 2, 2, 2 }, -2, 0, test2 },
257 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 2, 2, 2 }, 2, 1, test4 },
258 /* 5 */ reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 2, 2, 2 }, -1, 1, test4 },
259 reverse_sequence_test_params{ "I32", { 2, 3 },{ 3, 2 }, 1, 0, test6 },
260 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 1, 2, 3 }, 1, 0, test7 },
261 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 1, 2, 3 }, 1,-3, test7 },
262 reverse_sequence_test_params{ "I32", { 3, 3, 3 },{ 1, 2, 3 }, 1, 2, test8 },
263 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 2, 2, 2 }, 0, 0, test0 },
264 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 2, 2, 2 }, -3, 0, test0 },
265 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 2, 2, 2 }, 1, 0, test2 },
266 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 2, 2, 2 }, -2, 0, test2 },
267 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 2, 2, 2 }, 2, 1, test4 },
268 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 2, 2, 2 }, -1, 1, test4 },
269 /* 15 */ reverse_sequence_test_params{"FP32", { 2, 3 },{ 3, 2 }, 1, 0, test6 },
270 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 1, 2, 3 }, 1, 0, test7 },
271 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 1, 2, 3 }, 1,-3, test7 },
272 reverse_sequence_test_params{"FP32", { 3, 3, 3 },{ 1, 2, 3 }, 1, 2, test8 }