@@ -40,70 +40,42 @@ std::vector<T> DilateReference(const std::vector<T>& input,
4040 const std::vector<int32_t >& shape,
4141 const std::vector<int32_t >& dilations,
4242 const T padding_value) {
43- constexpr int kMaxDilateDims = 6 ;
44-
4543 // Compute the output shape.
46- std::vector<int > output_shape (kMaxDilateDims , 0 );
44+ std::vector<int > output_shape (shape. size () , 0 );
4745 for (size_t i = 0 ; i < shape.size (); ++i) {
4846 output_shape[i] = (shape[i] - 1 ) * dilations[i] + 1 ;
4947 }
5048
5149 // Compute the input strides.
52- std::vector<int > strides (kMaxDilateDims , 0 );
50+ std::vector<int > strides (shape. size () , 0 );
5351 strides[shape.size () - 1 ] = 1 ;
5452 for (size_t i = shape.size () - 1 ; i > 0 ; --i) {
5553 strides[i - 1 ] = shape[i] * strides[i];
5654 }
5755
5856 // Compute the output strides.
59- std::vector<int > output_strides (kMaxDilateDims , 0 );
57+ std::vector<int > output_strides (shape. size () , 0 );
6058 output_strides[shape.size () - 1 ] = 1 ;
6159 for (size_t i = shape.size () - 1 ; i > 0 ; --i) {
6260 output_strides[i - 1 ] = output_shape[i] * output_strides[i];
6361 }
6462
65- // Copy the dilations to a buffer that can hold the maximum ranks.
66- std::vector<int > safe_dilations (kMaxDilateDims , 0 );
67- absl::c_copy (dilations, safe_dilations.begin ());
68-
69- // Copy the input shape to a buffer that can hold the maximum ranks.
70- std::vector<int > safe_input_shape (kMaxDilateDims , 0 );
71- absl::c_copy (shape, safe_input_shape.begin ());
72-
7363 // Create a buffer that can hold the output data filled with 0.
7464 std::vector<T> output (
75- std::accumulate (output_shape.begin (), output_shape.begin () + shape. size () ,
76- 1 , std::multiplies<>()),
65+ std::accumulate (output_shape.begin (), output_shape.end (), 1 ,
66+ std::multiplies<>()),
7767 padding_value);
7868
79- int a = 0 ;
80- do {
81- int b = 0 ;
82- do {
83- int c = 0 ;
84- do {
85- int d = 0 ;
86- do {
87- int e = 0 ;
88- do {
89- int f = 0 ;
90- do {
91- const int i_idx = a * strides[0 ] + b * strides[1 ] +
92- c * strides[2 ] + d * strides[3 ] +
93- e * strides[4 ] + f * strides[5 ];
94- const int o_idx = a * safe_dilations[0 ] * output_strides[0 ] +
95- b * safe_dilations[1 ] * output_strides[1 ] +
96- c * safe_dilations[2 ] * output_strides[2 ] +
97- d * safe_dilations[3 ] * output_strides[3 ] +
98- e * safe_dilations[4 ] * output_strides[4 ] +
99- f * safe_dilations[5 ] * output_strides[5 ];
100- output[o_idx] = input[i_idx];
101- } while (++f < safe_input_shape[5 ]);
102- } while (++e < safe_input_shape[4 ]);
103- } while (++d < safe_input_shape[3 ]);
104- } while (++c < safe_input_shape[2 ]);
105- } while (++b < safe_input_shape[1 ]);
106- } while (++a < safe_input_shape[0 ]);
69+ for (int input_index = 0 ; input_index < input.size (); ++input_index) {
70+ int remaining_index = input_index;
71+ int output_index = 0 ;
72+ for (int dim = 0 ; dim < shape.size (); ++dim) {
73+ const int coordinate = remaining_index / strides[dim];
74+ remaining_index %= strides[dim];
75+ output_index += coordinate * dilations[dim] * output_strides[dim];
76+ }
77+ output[output_index] = input[input_index];
78+ }
10779
10880 return output;
10981}
@@ -370,5 +342,19 @@ TYPED_TEST(DilateTest, CheckAgainstReferenceImplementation) {
370342 EXPECT_THAT (model.GetOutputData (), ElementsAreArray (expected));
371343}
372344
345+ TYPED_TEST (DilateTest, RankSeven) {
346+ auto & model = this ->model_ ;
347+ model.SetInput (/* shape=*/ {2 , 1 , 2 , 1 , 2 , 1 , 2 });
348+ model.SetDilations (/* dilations=*/ {2 , 1 , 2 , 1 , 1 , 1 , 2 });
349+ model.SetPaddingValue (-1 );
350+
351+ const auto expected =
352+ DilateReference (model.GetInput (), model.GetInputShape (),
353+ model.GetDilations (), model.GetPaddingValue ());
354+ EXPECT_EQ (model.BuildAndInvoke (), kTfLiteOk );
355+ EXPECT_THAT (model.GetOutputShape (), ElementsAreArray ({3 , 1 , 3 , 1 , 2 , 1 , 3 }));
356+ EXPECT_THAT (model.GetOutputData (), ElementsAreArray (expected));
357+ }
358+
373359} // namespace
374360} // namespace tflite
0 commit comments