1 // Copyright 2020 Google LLC
2 //
3 // This source code is licensed under the BSD-style license found in the
4 // LICENSE file in the root directory of this source tree.
5
6 #include <xnnpack.h>
7
8 #include "subgraph-tester.h"
9 #include <gtest/gtest.h>
10
11 namespace xnnpack {
12
TEST(SUBGRAPH_NCHW,single_conv)13 TEST(SUBGRAPH_NCHW, single_conv) {
14 auto tester = SubgraphTester(4);
15 tester
16 .AddDynamicTensorF32({1, 256, 256, 3}, 0)
17 .AddStaticTensorF32({32, 3, 3, 3}, TensorType::kDense, 1)
18 .AddStaticTensorF32({32}, TensorType::kDense, 2)
19 .AddDynamicTensorF32({1, 128, 128, 32}, 3)
20 .AddConvolution2D(
21 ConvolutionParams{
22 Padding{1, 1, 1, 1},
23 Kernel{3, 3},
24 Subsampling{2, 2},
25 Dilation{1, 1},
26 /*groups=*/ 1,
27 /*group_input_channels=*/ 3,
28 /*group_output_channels=*/ 32,
29 }, 0, 1, 2, 3)
30 .Optimize()
31 .RewriteForNchw();
32
33 ASSERT_EQ(tester.GetLayout(0), xnn_layout_type_nhwc);
34 ASSERT_EQ(tester.GetLayout(3), xnn_layout_type_nhwc);
35 }
36
TEST(SUBGRAPH_NCHW,single_conv_and_global_average_pooling)37 TEST(SUBGRAPH_NCHW, single_conv_and_global_average_pooling) {
38 auto tester = SubgraphTester(5);
39 tester
40 .AddDynamicTensorF32({1, 256, 256, 3}, 0)
41 .AddStaticTensorF32({32, 3, 3, 3}, TensorType::kDense, 1)
42 .AddStaticTensorF32({32}, TensorType::kDense, 2)
43 .AddDynamicTensorF32({1, 128, 128, 32}, 3)
44 .AddDynamicTensorF32({32}, 4)
45 .AddConvolution2D(
46 ConvolutionParams{
47 Padding{1, 1, 1, 1},
48 Kernel{3, 3},
49 Subsampling{2, 2},
50 Dilation{1, 1},
51 /*groups=*/ 1,
52 /*group_input_channels=*/ 3,
53 /*group_output_channels=*/ 32,
54 }, 0, 1, 2, 3)
55 .AddGlobalAveragePooling(3, 4)
56 .Optimize()
57 .RewriteForNchw();
58
59 ASSERT_EQ(tester.GetLayout(0), xnn_layout_type_nhwc);
60 ASSERT_EQ(tester.GetLayout(3), xnn_layout_type_nhwc);
61 ASSERT_EQ(tester.GetLayout(4), xnn_layout_type_nhwc);
62 }
63
TEST(SUBGRAPH_NCHW,pixelwise_conv_sandwich)64 TEST(SUBGRAPH_NCHW, pixelwise_conv_sandwich) {
65 auto tester = SubgraphTester(8);
66 tester
67 .AddDynamicTensorF32({1, 256, 256, 3}, 0)
68 .AddStaticTensorF32({8, 3, 3, 3}, TensorType::kDense, 1)
69 .AddStaticTensorF32({8}, TensorType::kDense, 2)
70 .AddDynamicTensorF32({1, 128, 128, 8}, 3)
71 .AddStaticTensorF32({4, 1, 1, 8}, TensorType::kSparse, 4)
72 .AddStaticTensorF32({4}, TensorType::kDense, 5)
73 .AddDynamicTensorF32({1, 128, 128, 4}, 6)
74 .AddDynamicTensorF32({1, 4}, 7)
75 .AddConvolution2D(
76 ConvolutionParams{
77 Padding{1, 1, 1, 1},
78 Kernel{3, 3},
79 Subsampling{2, 2},
80 Dilation{1, 1},
81 /*groups=*/ 1,
82 /*group_input_channels=*/ 3,
83 /*group_output_channels=*/ 8
84 }, 0, 1, 2, 3)
85 .AddConvolution2D(
86 ConvolutionParams{
87 Padding{0, 0, 0, 0},
88 Kernel{1, 1},
89 Subsampling{1, 1},
90 Dilation{1, 1},
91 /*groups=*/ 1,
92 /*group_input_channels=*/ 8,
93 /*group_output_channels=*/ 4
94 }, 3, 4, 5, 6)
95 .AddGlobalAveragePooling(6, 7)
96 .Optimize()
97 .RewriteForNchw();
98
99 ASSERT_EQ(tester.GetLayout(0), xnn_layout_type_nhwc);
100 ASSERT_EQ(tester.GetLayout(3), xnn_layout_type_nchw);
101 ASSERT_EQ(tester.GetLayout(6), xnn_layout_type_nchw);
102 ASSERT_EQ(tester.GetLayout(7), xnn_layout_type_nhwc);
103 }
104
TEST(SUBGRAPH_NCHW,bottleneck)105 TEST(SUBGRAPH_NCHW, bottleneck) {
106 auto tester = SubgraphTester(15);
107 tester
108 .AddDynamicTensorF32({1, 256, 256, 3}, 0)
109 .AddStaticTensorF32({8, 3, 3, 3}, TensorType::kDense, 1)
110 .AddStaticTensorF32({8}, TensorType::kDense, 2)
111 .AddDynamicTensorF32({1, 128, 128, 8}, 3)
112 .AddStaticTensorF32({4, 1, 1, 8}, TensorType::kSparse, 4)
113 .AddStaticTensorF32({4}, TensorType::kDense, 5)
114 .AddDynamicTensorF32({1, 128, 128, 4}, 6)
115 .AddStaticTensorF32({1, 3, 3, 4}, TensorType::kDense, 7)
116 .AddStaticTensorF32({4}, TensorType::kDense, 8)
117 .AddDynamicTensorF32({1, 128, 128, 4}, 9)
118 .AddStaticTensorF32({8, 1, 1, 4}, TensorType::kSparse, 10)
119 .AddStaticTensorF32({8}, TensorType::kDense, 11)
120 .AddDynamicTensorF32({1, 128, 128, 8}, 12)
121 .AddDynamicTensorF32({1, 128, 128, 8}, 13)
122 .AddDynamicTensorF32({1, 128, 128, 8}, 13)
123 .AddDynamicTensorF32({1, 8}, 14)
124 .AddConvolution2D(
125 ConvolutionParams{
126 Padding{1, 1, 1, 1},
127 Kernel{3, 3},
128 Subsampling{2, 2},
129 Dilation{1, 1},
130 /*groups=*/ 1,
131 /*group_input_channels=*/ 3,
132 /*group_output_channels=*/ 8
133 }, 0, 1, 2, 3)
134 .AddConvolution2D(
135 ConvolutionParams{
136 Padding{0, 0, 0, 0},
137 Kernel{1, 1},
138 Subsampling{1, 1},
139 Dilation{1, 1},
140 /*groups=*/ 1,
141 /*group_input_channels=*/ 8,
142 /*group_output_channels=*/ 4
143 }, 3, 4, 5, 6)
144 .AddDepthwiseConvolution2D(
145 DepthwiseConvolutionParams{
146 Padding{1, 1, 1, 1},
147 Kernel{3, 3},
148 Subsampling{1, 1},
149 Dilation{1, 1},
150 /*depth_multiplier=*/ 1,
151 /*input_channels=*/ 4
152 }, 6, 7, 8, 9)
153 .AddConvolution2D(
154 ConvolutionParams{
155 Padding{0, 0, 0, 0},
156 Kernel{1, 1},
157 Subsampling{1, 1},
158 Dilation{1, 1},
159 /*groups=*/ 1,
160 /*group_input_channels=*/ 8,
161 /*group_output_channels=*/ 4
162 }, 9, 10, 11, 12)
163 .AddAddition(3, 12, 13)
164 .AddGlobalAveragePooling(13, 14)
165 .Optimize()
166 .RewriteForNchw();
167
168 ASSERT_EQ(tester.GetLayout(0), xnn_layout_type_nhwc);
169 ASSERT_EQ(tester.GetLayout(3), xnn_layout_type_nchw);
170 ASSERT_EQ(tester.GetLayout(6), xnn_layout_type_nchw);
171 ASSERT_EQ(tester.GetLayout(9), xnn_layout_type_nchw);
172 ASSERT_EQ(tester.GetLayout(12), xnn_layout_type_nchw);
173 ASSERT_EQ(tester.GetLayout(13), xnn_layout_type_nchw);
174 ASSERT_EQ(tester.GetLayout(14), xnn_layout_type_nhwc);
175 }
176
177 } // namespace xnnpack
178