1 /* 2 * Copyright (c) 2017-2021 Arm Limited. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 #ifndef ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_DATASET 25 #define ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_DATASET 26 27 #include "utils/TypePrinter.h" 28 29 #include "arm_compute/core/TensorShape.h" 30 #include "arm_compute/core/Types.h" 31 32 namespace arm_compute 33 { 34 namespace test 35 { 36 namespace datasets 37 { 38 class DepthwiseConvolutionLayerDataset 39 { 40 public: 41 using type = std::tuple<TensorShape, Size2D, PadStrideInfo, Size2D>; 42 43 struct iterator 44 { iteratoriterator45 iterator(std::vector<TensorShape>::const_iterator src_it, 46 std::vector<Size2D>::const_iterator weights_it, 47 std::vector<PadStrideInfo>::const_iterator infos_it, 48 std::vector<Size2D>::const_iterator dilation_it) 49 : _src_it{ std::move(src_it) }, 50 _weights_it{ std::move(weights_it) }, 51 _infos_it{ std::move(infos_it) }, 52 _dilation_it{ std::move(dilation_it) } 53 { 54 } 55 descriptioniterator56 std::string description() const 57 { 58 std::stringstream description; 59 description << "In=" << *_src_it << ":"; 60 description << "Weights=" << *_weights_it << ":"; 61 description << "Info=" << *_infos_it << ":"; 62 description << "Dilation=" << *_dilation_it; 63 return description.str(); 64 } 65 66 DepthwiseConvolutionLayerDataset::type operator*() const 67 { 68 return std::make_tuple(*_src_it, *_weights_it, *_infos_it, *_dilation_it); 69 } 70 71 iterator &operator++() 72 { 73 ++_src_it; 74 ++_weights_it; 75 ++_infos_it; 76 ++_dilation_it; 77 78 return *this; 79 } 80 81 private: 82 std::vector<TensorShape>::const_iterator _src_it; 83 std::vector<Size2D>::const_iterator _weights_it; 84 std::vector<PadStrideInfo>::const_iterator _infos_it; 85 std::vector<Size2D>::const_iterator _dilation_it; 86 }; 87 begin()88 iterator begin() const 89 { 90 return iterator(_src_shapes.begin(), _weight_shapes.begin(), _infos.begin(), _dilations.begin()); 91 } 92 size()93 int size() const 94 { 95 return std::min(_src_shapes.size(), std::min(_weight_shapes.size(), std::min(_infos.size(), _dilations.size()))); 96 } 97 98 void add_config(TensorShape src, Size2D weights, PadStrideInfo info, Size2D dilation = Size2D(1U, 1U)) 99 { 100 _src_shapes.emplace_back(std::move(src)); 101 _weight_shapes.emplace_back(std::move(weights)); 102 _infos.emplace_back(std::move(info)); 103 _dilations.emplace_back(std::move(dilation)); 104 } 105 106 protected: 107 DepthwiseConvolutionLayerDataset() = default; 108 DepthwiseConvolutionLayerDataset(DepthwiseConvolutionLayerDataset &&) = default; 109 110 private: 111 std::vector<TensorShape> _src_shapes{}; 112 std::vector<Size2D> _weight_shapes{}; 113 std::vector<PadStrideInfo> _infos{}; 114 std::vector<Size2D> _dilations{}; 115 }; 116 117 /** Dataset containing small, generic depthwise convolution shapes. */ 118 class SmallDepthwiseConvolutionLayerDataset final : public DepthwiseConvolutionLayerDataset 119 { 120 public: SmallDepthwiseConvolutionLayerDataset()121 SmallDepthwiseConvolutionLayerDataset() 122 { 123 add_config(TensorShape(7U, 7U, 1U), Size2D(1U, 1U), PadStrideInfo(1, 1, 0, 0)); 124 add_config(TensorShape(3U, 3U, 2U), Size2D(2U, 2U), PadStrideInfo(1, 1, 0, 0)); 125 add_config(TensorShape(33U, 27U, 7U), Size2D(7U, 3U), PadStrideInfo(3, 2, 1, 0)); 126 // Asymmetric padding 127 add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 1, 2, 0, DimensionRoundingType::FLOOR)); 128 add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 1, 0, 2, DimensionRoundingType::FLOOR)); 129 // Ceil rounding 130 add_config(TensorShape(7U, 8U, 5U, 9U), Size2D(8U, 6U), PadStrideInfo(2, 3, 1, 1, 1, 3, DimensionRoundingType::CEIL), Size2D(1U, 2U)); 131 } 132 }; 133 134 /** Dataset containing large, generic depthwise convolution shapes. */ 135 class LargeDepthwiseConvolutionLayerDataset final : public DepthwiseConvolutionLayerDataset 136 { 137 public: LargeDepthwiseConvolutionLayerDataset()138 LargeDepthwiseConvolutionLayerDataset() 139 { 140 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 4U), PadStrideInfo(1, 2, 0, 1)); 141 add_config(TensorShape(17U, 31U, 2U), Size2D(5U, 9U), PadStrideInfo(1, 2, 1, 1)); 142 add_config(TensorShape(23U, 27U, 5U), Size2D(11U, 3U), PadStrideInfo(1, 2, 0, 0)); 143 add_config(TensorShape(17U, 31U, 2U, 3U), Size2D(5U, 9U), PadStrideInfo(1, 2, 1, 1)); 144 add_config(TensorShape(233U, 277U, 55U), Size2D(1U, 1U), PadStrideInfo(2, 1, 0, 0)); 145 add_config(TensorShape(333U, 277U, 77U), Size2D(1U, 1U), PadStrideInfo(3, 2, 1, 0)); 146 add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 4U), PadStrideInfo(1, 2, 1, 1)); 147 add_config(TensorShape(233U, 277U, 55U), Size2D(3U, 4U), PadStrideInfo(1, 2, 0, 0)); 148 add_config(TensorShape(333U, 277U, 77U), Size2D(3U, 4U), PadStrideInfo(2, 3, 0, 1)); 149 add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 4U), PadStrideInfo(2, 1, 1, 1)); 150 // Asymmetric padding 151 add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 2, 1, 2, 0, DimensionRoundingType::FLOOR)); 152 add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 3, 0, 2, DimensionRoundingType::FLOOR)); 153 add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 0, 1, 0, DimensionRoundingType::FLOOR)); 154 add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 0, 1, 0, 1, DimensionRoundingType::FLOOR)); 155 } 156 }; 157 158 /** Dataset containing large kernel size for generic depthwise convolution. */ 159 class LargeKernelSizeDepthwiseConvolutionLayerNHWCDataset final : public DepthwiseConvolutionLayerDataset 160 { 161 public: LargeKernelSizeDepthwiseConvolutionLayerNHWCDataset()162 LargeKernelSizeDepthwiseConvolutionLayerNHWCDataset() 163 { 164 add_config(TensorShape(6U, 210U, 8U), Size2D(4U, 194U), PadStrideInfo(1, 1, 0, 0)); 165 } 166 }; 167 168 /** Dataset containing small, 3x3 depthwise convolution shapes. */ 169 class SmallDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 170 { 171 public: SmallDepthwiseConvolutionLayerDataset3x3()172 SmallDepthwiseConvolutionLayerDataset3x3() 173 { 174 add_config(TensorShape(1U, 1U, 2U), Size2D(3U, 3U), PadStrideInfo(1, 1, 2, 2)); 175 add_config(TensorShape(7U, 8U, 3U, 2U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0)); 176 add_config(TensorShape(32U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0)); 177 // Asymmetric padding 178 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::FLOOR)); 179 } 180 }; 181 182 class SmallDepthwiseConvolutionLayerDataset3x3NCHW final : public DepthwiseConvolutionLayerDataset 183 { 184 public: SmallDepthwiseConvolutionLayerDataset3x3NCHW()185 SmallDepthwiseConvolutionLayerDataset3x3NCHW() 186 { 187 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(3, 2, 1, 1)); 188 // Asymmetric padding 189 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(2, 2, 3, 1, 2, 1, DimensionRoundingType::FLOOR)); 190 } 191 }; 192 193 /** Dataset containing large, 3x3 depthwise convolution shapes. */ 194 class LargeDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 195 { 196 public: LargeDepthwiseConvolutionLayerDataset3x3()197 LargeDepthwiseConvolutionLayerDataset3x3() 198 { 199 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1)); 200 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 0)); 201 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 1)); 202 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1)); 203 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 0)); 204 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 1)); 205 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1)); 206 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 0)); 207 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1)); 208 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1)); 209 add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1)); 210 add_config(TensorShape(233U, 277U, 55U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 0)); 211 add_config(TensorShape(333U, 277U, 77U), Size2D(3U, 3U), PadStrideInfo(2, 3, 0, 0)); 212 add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1)); 213 // Width and height are a multipile of the processing tile size 214 add_config(TensorShape(32U, 21U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 1)); 215 } 216 }; 217 218 /** Dataset containing optimized, 3x3 depthwise convolution shapes. */ 219 class SmallOptimizedDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 220 { 221 public: SmallOptimizedDepthwiseConvolutionLayerDataset3x3()222 SmallOptimizedDepthwiseConvolutionLayerDataset3x3() 223 { 224 // Stride 1 225 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 226 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 227 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 228 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 2, 2, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 229 // Stride 2 230 add_config(TensorShape(9U, 9U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)); 231 add_config(TensorShape(9U, 9U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 232 add_config(TensorShape(9U, 9U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1, DimensionRoundingType::CEIL)); 233 } 234 }; 235 /** Dataset containing optimized, 3x3 depthwise convolution shapes. */ 236 class LargeOptimizedDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 237 { 238 public: LargeOptimizedDepthwiseConvolutionLayerDataset3x3()239 LargeOptimizedDepthwiseConvolutionLayerDataset3x3() 240 { 241 // Stride 1 242 add_config(TensorShape(233U, 277U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 243 add_config(TensorShape(233U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 244 add_config(TensorShape(7U, 7U, 21U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 245 add_config(TensorShape(28U, 28U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 246 add_config(TensorShape(28U, 28U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 247 // Stride 2 248 add_config(TensorShape(233U, 277U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)); 249 add_config(TensorShape(233U, 277U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1, 1, 1, DimensionRoundingType::CEIL)); 250 add_config(TensorShape(8U, 8U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::FLOOR)); 251 add_config(TensorShape(8U, 8U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL)); 252 add_config(TensorShape(8U, 8U, 33U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL)); 253 add_config(TensorShape(64U, 64U, 128U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL)); 254 } 255 }; 256 257 /** Dataset containing optimized, 5x5 depthwise convolution shapes. */ 258 class SmallOptimizedDepthwiseConvolutionLayerDataset5x5 final : public DepthwiseConvolutionLayerDataset 259 { 260 public: SmallOptimizedDepthwiseConvolutionLayerDataset5x5()261 SmallOptimizedDepthwiseConvolutionLayerDataset5x5() 262 { 263 // Stride 1 264 add_config(TensorShape(7U, 7U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 265 add_config(TensorShape(11U, 11U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 266 add_config(TensorShape(7U, 7U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 2, 2, DimensionRoundingType::CEIL)); 267 add_config(TensorShape(7U, 7U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 4, 4, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 268 // Stride 2 269 add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)); 270 add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 271 add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 2, 2, 2, 2, DimensionRoundingType::CEIL)); 272 add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 4, 4, 4, 4, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 273 } 274 }; 275 276 /** Dataset containing in-place 1x1 depthwise convolution shapes. 277 * 278 * For a depthwise convolution op to be in-place: 279 * * Output has the same shape as the input; 280 * * 1x1 filter 281 * * stride == 1 282 * * dilations == 1 283 * * No paddings 284 */ 285 class SmallInPlaceDepthwiseConvolutionLayerDataset final : public DepthwiseConvolutionLayerDataset 286 { 287 public: SmallInPlaceDepthwiseConvolutionLayerDataset()288 SmallInPlaceDepthwiseConvolutionLayerDataset() 289 { 290 add_config(TensorShape(7U, 7U, 1U), Size2D(1U, 1U), PadStrideInfo(1, 1, 0, 0)); 291 add_config(TensorShape(11U, 13U, 16U), Size2D(1U, 1U), PadStrideInfo(1, 1, 0, 0)); 292 } 293 }; 294 } // namespace datasets 295 } // namespace test 296 } // namespace arm_compute 297 #endif /* ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_DATASET */