xref: /aosp_15_r20/external/ruy/ruy/block_map_test.cc (revision bb86c7ed5fb1b98a7eac808e443a46cc8b90dfc0)
1*bb86c7edSAndroid Build Coastguard Worker /* Copyright 2019 Google LLC. All Rights Reserved.
2*bb86c7edSAndroid Build Coastguard Worker 
3*bb86c7edSAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License");
4*bb86c7edSAndroid Build Coastguard Worker you may not use this file except in compliance with the License.
5*bb86c7edSAndroid Build Coastguard Worker You may obtain a copy of the License at
6*bb86c7edSAndroid Build Coastguard Worker 
7*bb86c7edSAndroid Build Coastguard Worker     http://www.apache.org/licenses/LICENSE-2.0
8*bb86c7edSAndroid Build Coastguard Worker 
9*bb86c7edSAndroid Build Coastguard Worker Unless required by applicable law or agreed to in writing, software
10*bb86c7edSAndroid Build Coastguard Worker distributed under the License is distributed on an "AS IS" BASIS,
11*bb86c7edSAndroid Build Coastguard Worker WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*bb86c7edSAndroid Build Coastguard Worker See the License for the specific language governing permissions and
13*bb86c7edSAndroid Build Coastguard Worker limitations under the License.
14*bb86c7edSAndroid Build Coastguard Worker ==============================================================================*/
15*bb86c7edSAndroid Build Coastguard Worker 
16*bb86c7edSAndroid Build Coastguard Worker #include "ruy/block_map.h"
17*bb86c7edSAndroid Build Coastguard Worker 
18*bb86c7edSAndroid Build Coastguard Worker #include <cstddef>
19*bb86c7edSAndroid Build Coastguard Worker #include <cstdint>
20*bb86c7edSAndroid Build Coastguard Worker #include <cstdlib>
21*bb86c7edSAndroid Build Coastguard Worker #include <limits>
22*bb86c7edSAndroid Build Coastguard Worker #include <vector>
23*bb86c7edSAndroid Build Coastguard Worker 
24*bb86c7edSAndroid Build Coastguard Worker #include "ruy/cpu_cache_params.h"
25*bb86c7edSAndroid Build Coastguard Worker #include "ruy/gtest_wrapper.h"
26*bb86c7edSAndroid Build Coastguard Worker #include "ruy/platform.h"
27*bb86c7edSAndroid Build Coastguard Worker #include "ruy/side_pair.h"
28*bb86c7edSAndroid Build Coastguard Worker 
29*bb86c7edSAndroid Build Coastguard Worker namespace ruy {
30*bb86c7edSAndroid Build Coastguard Worker namespace {
31*bb86c7edSAndroid Build Coastguard Worker 
32*bb86c7edSAndroid Build Coastguard Worker #if RUY_PLATFORM_NEON_64
33*bb86c7edSAndroid Build Coastguard Worker 
34*bb86c7edSAndroid Build Coastguard Worker // Unless otherwise specified, these tests have been tuned on ARM Cortex-A55.
MakeBlockMapTuningTest(int rows,int cols,int depth,int kernel_rows,int kernel_cols,int lhs_scalar_size,int rhs_scalar_size,int tentative_thread_count,int expected_num_blocks_base_log2,int expected_rectangularness_log2)35*bb86c7edSAndroid Build Coastguard Worker void MakeBlockMapTuningTest(int rows, int cols, int depth, int kernel_rows,
36*bb86c7edSAndroid Build Coastguard Worker                             int kernel_cols, int lhs_scalar_size,
37*bb86c7edSAndroid Build Coastguard Worker                             int rhs_scalar_size, int tentative_thread_count,
38*bb86c7edSAndroid Build Coastguard Worker                             int expected_num_blocks_base_log2,
39*bb86c7edSAndroid Build Coastguard Worker                             int expected_rectangularness_log2) {
40*bb86c7edSAndroid Build Coastguard Worker   // Plausible Cortex-A55 cache sizes.
41*bb86c7edSAndroid Build Coastguard Worker   CpuCacheParams cpu_cache_params;
42*bb86c7edSAndroid Build Coastguard Worker   cpu_cache_params.local_cache_size = 128 * 1024;
43*bb86c7edSAndroid Build Coastguard Worker   cpu_cache_params.last_level_cache_size = 1024 * 1024;
44*bb86c7edSAndroid Build Coastguard Worker   BlockMap block_map;
45*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMap(rows, cols, depth, kernel_rows, kernel_cols, lhs_scalar_size,
46*bb86c7edSAndroid Build Coastguard Worker                rhs_scalar_size, tentative_thread_count, cpu_cache_params,
47*bb86c7edSAndroid Build Coastguard Worker                &block_map);
48*bb86c7edSAndroid Build Coastguard Worker   EXPECT_EQ(block_map.num_blocks_base_log2, expected_num_blocks_base_log2);
49*bb86c7edSAndroid Build Coastguard Worker   EXPECT_EQ(std::min(block_map.rectangularness_log2[Side::kLhs],
50*bb86c7edSAndroid Build Coastguard Worker                      block_map.rectangularness_log2[Side::kRhs]),
51*bb86c7edSAndroid Build Coastguard Worker             0);
52*bb86c7edSAndroid Build Coastguard Worker   EXPECT_EQ(std::max(block_map.rectangularness_log2[Side::kLhs],
53*bb86c7edSAndroid Build Coastguard Worker                      block_map.rectangularness_log2[Side::kRhs]),
54*bb86c7edSAndroid Build Coastguard Worker             expected_rectangularness_log2);
55*bb86c7edSAndroid Build Coastguard Worker }
56*bb86c7edSAndroid Build Coastguard Worker 
TEST(BlockMapTest,MakeBlockMapTuningTest8bitCubicShapesOneThreadNeonDotprod)57*bb86c7edSAndroid Build Coastguard Worker TEST(BlockMapTest, MakeBlockMapTuningTest8bitCubicShapesOneThreadNeonDotprod) {
58*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(32, 32, 32, 8, 8, 1, 1, /* tentative_thread_count */ 1,
59*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
60*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
61*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(48, 48, 48, 8, 8, 1, 1, /* tentative_thread_count */ 1,
62*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
63*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
64*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(64, 64, 64, 8, 8, 1, 1, /* tentative_thread_count */ 1,
65*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
66*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
67*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(96, 96, 96, 8, 8, 1, 1, /* tentative_thread_count */ 1,
68*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
69*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
70*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(128, 128, 128, 8, 8, 1, 1,
71*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 1,
72*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
73*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
74*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(192, 192, 192, 8, 8, 1, 1,
75*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 1,
76*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
77*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
78*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(256, 256, 256, 8, 8, 1, 1,
79*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 1,
80*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
81*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
82*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(384, 384, 384, 8, 8, 1, 1,
83*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 1,
84*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
85*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
86*bb86c7edSAndroid Build Coastguard Worker }
87*bb86c7edSAndroid Build Coastguard Worker 
TEST(BlockMapTest,MakeBlockMapTuningTest8bitCubicShapesFourThreadsNeonDotprod)88*bb86c7edSAndroid Build Coastguard Worker TEST(BlockMapTest,
89*bb86c7edSAndroid Build Coastguard Worker      MakeBlockMapTuningTest8bitCubicShapesFourThreadsNeonDotprod) {
90*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(32, 32, 32, 8, 8, 1, 1, /* tentative_thread_count */ 4,
91*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
92*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
93*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(48, 48, 48, 8, 8, 1, 1, /* tentative_thread_count */ 4,
94*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
95*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
96*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(64, 64, 64, 8, 8, 1, 1, /* tentative_thread_count */ 4,
97*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
98*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
99*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(96, 96, 96, 8, 8, 1, 1, /* tentative_thread_count */ 4,
100*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
101*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
102*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(128, 128, 128, 8, 8, 1, 1,
103*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 4,
104*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
105*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
106*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(192, 192, 192, 8, 8, 1, 1,
107*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 4,
108*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 1,
109*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
110*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(256, 256, 256, 8, 8, 1, 1,
111*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 4,
112*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 2,
113*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
114*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(384, 384, 384, 8, 8, 1, 1,
115*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 4,
116*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 2,
117*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
118*bb86c7edSAndroid Build Coastguard Worker }
119*bb86c7edSAndroid Build Coastguard Worker 
TEST(BlockMapTest,MakeBlockMapTuningTest32bit)120*bb86c7edSAndroid Build Coastguard Worker TEST(BlockMapTest, MakeBlockMapTuningTest32bit) {
121*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(256, 256, 256, 8, 8, 4, 4,
122*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 4,
123*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 3,
124*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
125*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(4096, 4096, 4096, 8, 8, 4, 4,
126*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 4,
127*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 7,
128*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 0);
129*bb86c7edSAndroid Build Coastguard Worker }
130*bb86c7edSAndroid Build Coastguard Worker 
TEST(BlockMapTest,MakeBlockMapTuningTestRectangular)131*bb86c7edSAndroid Build Coastguard Worker TEST(BlockMapTest, MakeBlockMapTuningTestRectangular) {
132*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(256, 16, 256, 8, 8, 1, 1,
133*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 1,
134*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
135*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 3);
136*bb86c7edSAndroid Build Coastguard Worker   MakeBlockMapTuningTest(24, 2400, 256, 8, 8, 1, 1,
137*bb86c7edSAndroid Build Coastguard Worker                          /* tentative_thread_count */ 1,
138*bb86c7edSAndroid Build Coastguard Worker                          /* expected_num_blocks_base_log2 */ 0,
139*bb86c7edSAndroid Build Coastguard Worker                          /* expected_rectangularness_log2 */ 6);
140*bb86c7edSAndroid Build Coastguard Worker }
141*bb86c7edSAndroid Build Coastguard Worker 
142*bb86c7edSAndroid Build Coastguard Worker #endif
143*bb86c7edSAndroid Build Coastguard Worker 
L1Distance(const SidePair<int> & a,const SidePair<int> & b)144*bb86c7edSAndroid Build Coastguard Worker int L1Distance(const SidePair<int>& a, const SidePair<int>& b) {
145*bb86c7edSAndroid Build Coastguard Worker   return std::abs(a[Side::kLhs] - b[Side::kLhs]) +
146*bb86c7edSAndroid Build Coastguard Worker          std::abs(a[Side::kRhs] - b[Side::kRhs]);
147*bb86c7edSAndroid Build Coastguard Worker }
148*bb86c7edSAndroid Build Coastguard Worker 
GetBlockByIndexSquareTest(int num_blocks_base_log2,BlockMapTraversalOrder traversal_order)149*bb86c7edSAndroid Build Coastguard Worker void GetBlockByIndexSquareTest(int num_blocks_base_log2,
150*bb86c7edSAndroid Build Coastguard Worker                                BlockMapTraversalOrder traversal_order) {
151*bb86c7edSAndroid Build Coastguard Worker   // Arbitrary, does not affect this test. 3 is just a typical value.
152*bb86c7edSAndroid Build Coastguard Worker   constexpr int kKernelSizeLog2 = 3;
153*bb86c7edSAndroid Build Coastguard Worker 
154*bb86c7edSAndroid Build Coastguard Worker   const int size_log2 = num_blocks_base_log2 + kKernelSizeLog2;
155*bb86c7edSAndroid Build Coastguard Worker   BlockMap block_map;
156*bb86c7edSAndroid Build Coastguard Worker   block_map.thread_count = 1;
157*bb86c7edSAndroid Build Coastguard Worker   block_map.traversal_order = traversal_order;
158*bb86c7edSAndroid Build Coastguard Worker   block_map.num_blocks_base_log2 = num_blocks_base_log2;
159*bb86c7edSAndroid Build Coastguard Worker   for (Side side : {Side::kLhs, Side::kRhs}) {
160*bb86c7edSAndroid Build Coastguard Worker     block_map.dims[side] = 1 << size_log2;
161*bb86c7edSAndroid Build Coastguard Worker     block_map.rectangularness_log2[side] = 0;
162*bb86c7edSAndroid Build Coastguard Worker     block_map.kernel_dims[side] = 1 << kKernelSizeLog2;
163*bb86c7edSAndroid Build Coastguard Worker     block_map.small_block_dims[side] = block_map.kernel_dims[side];
164*bb86c7edSAndroid Build Coastguard Worker     block_map.large_blocks[side] = 0;
165*bb86c7edSAndroid Build Coastguard Worker   }
166*bb86c7edSAndroid Build Coastguard Worker 
167*bb86c7edSAndroid Build Coastguard Worker   const int num_blocks_per_side = 1 << num_blocks_base_log2;
168*bb86c7edSAndroid Build Coastguard Worker   const int num_blocks = num_blocks_per_side * num_blocks_per_side;
169*bb86c7edSAndroid Build Coastguard Worker   EXPECT_EQ(num_blocks, NumBlocks(block_map));
170*bb86c7edSAndroid Build Coastguard Worker 
171*bb86c7edSAndroid Build Coastguard Worker   // Perform a full traversal of all blocks, as if computing a whole matrix
172*bb86c7edSAndroid Build Coastguard Worker   // multiplication.
173*bb86c7edSAndroid Build Coastguard Worker   //
174*bb86c7edSAndroid Build Coastguard Worker   // Used to record how many times each block was hit by the traversal.
175*bb86c7edSAndroid Build Coastguard Worker   std::vector<int> block_hit_counts(num_blocks);
176*bb86c7edSAndroid Build Coastguard Worker   // Here we guard an assumption that all traversal orders start at (0, 0).
177*bb86c7edSAndroid Build Coastguard Worker   SidePair<int> previous_block_coords(0, 0);
178*bb86c7edSAndroid Build Coastguard Worker   // Sum of L1 norm of the coordinate change at every step of the traversal.
179*bb86c7edSAndroid Build Coastguard Worker   std::int64_t total_l1_distance = 0;
180*bb86c7edSAndroid Build Coastguard Worker   // Number of jumps i.e. traversal steps with a L1 norm greater than 1.
181*bb86c7edSAndroid Build Coastguard Worker   int discontinuity_count = 0;
182*bb86c7edSAndroid Build Coastguard Worker   for (int block_index = 0; block_index < num_blocks; block_index++) {
183*bb86c7edSAndroid Build Coastguard Worker     SidePair<int> block_coords;
184*bb86c7edSAndroid Build Coastguard Worker     GetBlockByIndex(block_map, block_index, &block_coords);
185*bb86c7edSAndroid Build Coastguard Worker     ++block_hit_counts[block_coords[Side::kLhs] +
186*bb86c7edSAndroid Build Coastguard Worker                        num_blocks_per_side * block_coords[Side::kRhs]];
187*bb86c7edSAndroid Build Coastguard Worker     int distance = L1Distance(block_coords, previous_block_coords);
188*bb86c7edSAndroid Build Coastguard Worker     total_l1_distance += distance;
189*bb86c7edSAndroid Build Coastguard Worker     discontinuity_count += (distance > 1);
190*bb86c7edSAndroid Build Coastguard Worker     previous_block_coords = block_coords;
191*bb86c7edSAndroid Build Coastguard Worker   }
192*bb86c7edSAndroid Build Coastguard Worker 
193*bb86c7edSAndroid Build Coastguard Worker   // Verify that each block was traversed exactly once.
194*bb86c7edSAndroid Build Coastguard Worker   for (int l = 0; l < num_blocks_per_side; l++) {
195*bb86c7edSAndroid Build Coastguard Worker     for (int r = 0; r < num_blocks_per_side; r++) {
196*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(block_hit_counts[l + num_blocks_per_side * r], 1);
197*bb86c7edSAndroid Build Coastguard Worker     }
198*bb86c7edSAndroid Build Coastguard Worker   }
199*bb86c7edSAndroid Build Coastguard Worker 
200*bb86c7edSAndroid Build Coastguard Worker   // Verify that the discontinuity_count and total_l1_distance are as expected
201*bb86c7edSAndroid Build Coastguard Worker   // for the given traversal_order.
202*bb86c7edSAndroid Build Coastguard Worker   switch (traversal_order) {
203*bb86c7edSAndroid Build Coastguard Worker     case BlockMapTraversalOrder::kFractalHilbert:
204*bb86c7edSAndroid Build Coastguard Worker       // No discontinuity at all with this space-filling continuous curve!
205*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(discontinuity_count, 0);
206*bb86c7edSAndroid Build Coastguard Worker       // Therefore, total_l1_distance has to be the number of blocks minus one.
207*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(total_l1_distance, num_blocks - 1);
208*bb86c7edSAndroid Build Coastguard Worker       break;
209*bb86c7edSAndroid Build Coastguard Worker     case BlockMapTraversalOrder::kLinear:
210*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(discontinuity_count, num_blocks_per_side - 1);
211*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(total_l1_distance,
212*bb86c7edSAndroid Build Coastguard Worker                 2 * num_blocks_per_side * (num_blocks_per_side - 1));
213*bb86c7edSAndroid Build Coastguard Worker       break;
214*bb86c7edSAndroid Build Coastguard Worker     case BlockMapTraversalOrder::kFractalZ:
215*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(discontinuity_count, num_blocks > 1 ? (num_blocks / 2 - 1) : 0);
216*bb86c7edSAndroid Build Coastguard Worker       EXPECT_EQ(total_l1_distance,
217*bb86c7edSAndroid Build Coastguard Worker                 2 * num_blocks_per_side * (num_blocks_per_side - 1));
218*bb86c7edSAndroid Build Coastguard Worker       break;
219*bb86c7edSAndroid Build Coastguard Worker     case BlockMapTraversalOrder::kFractalU: {
220*bb86c7edSAndroid Build Coastguard Worker       if (num_blocks_base_log2 == 0) {
221*bb86c7edSAndroid Build Coastguard Worker         EXPECT_EQ(discontinuity_count, 0);
222*bb86c7edSAndroid Build Coastguard Worker         EXPECT_EQ(total_l1_distance, 0);
223*bb86c7edSAndroid Build Coastguard Worker       } else {
224*bb86c7edSAndroid Build Coastguard Worker         int expected_discontinuity_count = 0;
225*bb86c7edSAndroid Build Coastguard Worker         int expected_total_l1_distance = 3;
226*bb86c7edSAndroid Build Coastguard Worker         for (int i = 2; i <= num_blocks_base_log2; i++) {
227*bb86c7edSAndroid Build Coastguard Worker           expected_discontinuity_count = 4 * expected_discontinuity_count + 2;
228*bb86c7edSAndroid Build Coastguard Worker           expected_total_l1_distance =
229*bb86c7edSAndroid Build Coastguard Worker               4 * expected_total_l1_distance + (1 << (i + 1)) - 1;
230*bb86c7edSAndroid Build Coastguard Worker         }
231*bb86c7edSAndroid Build Coastguard Worker         EXPECT_EQ(discontinuity_count, expected_discontinuity_count);
232*bb86c7edSAndroid Build Coastguard Worker         EXPECT_EQ(total_l1_distance, expected_total_l1_distance);
233*bb86c7edSAndroid Build Coastguard Worker       }
234*bb86c7edSAndroid Build Coastguard Worker       break;
235*bb86c7edSAndroid Build Coastguard Worker     }
236*bb86c7edSAndroid Build Coastguard Worker     default:
237*bb86c7edSAndroid Build Coastguard Worker       abort();
238*bb86c7edSAndroid Build Coastguard Worker   }
239*bb86c7edSAndroid Build Coastguard Worker }
240*bb86c7edSAndroid Build Coastguard Worker 
TEST(BlockMapTest,GetBlockByIndexSquare)241*bb86c7edSAndroid Build Coastguard Worker TEST(BlockMapTest, GetBlockByIndexSquare) {
242*bb86c7edSAndroid Build Coastguard Worker   for (int num_blocks_base_log2 = 0; num_blocks_base_log2 <= 10;
243*bb86c7edSAndroid Build Coastguard Worker        num_blocks_base_log2++) {
244*bb86c7edSAndroid Build Coastguard Worker     for (BlockMapTraversalOrder traversal_order :
245*bb86c7edSAndroid Build Coastguard Worker          {BlockMapTraversalOrder::kLinear, BlockMapTraversalOrder::kFractalZ,
246*bb86c7edSAndroid Build Coastguard Worker           BlockMapTraversalOrder::kFractalU,
247*bb86c7edSAndroid Build Coastguard Worker           BlockMapTraversalOrder::kFractalHilbert}) {
248*bb86c7edSAndroid Build Coastguard Worker       GetBlockByIndexSquareTest(num_blocks_base_log2, traversal_order);
249*bb86c7edSAndroid Build Coastguard Worker     }
250*bb86c7edSAndroid Build Coastguard Worker   }
251*bb86c7edSAndroid Build Coastguard Worker }
252*bb86c7edSAndroid Build Coastguard Worker 
253*bb86c7edSAndroid Build Coastguard Worker }  // namespace
254*bb86c7edSAndroid Build Coastguard Worker }  // namespace ruy
255*bb86c7edSAndroid Build Coastguard Worker 
main(int argc,char ** argv)256*bb86c7edSAndroid Build Coastguard Worker int main(int argc, char **argv) {
257*bb86c7edSAndroid Build Coastguard Worker   ::testing::InitGoogleTest(&argc, argv);
258*bb86c7edSAndroid Build Coastguard Worker   return RUN_ALL_TESTS();
259*bb86c7edSAndroid Build Coastguard Worker }
260