1 /* 2 * Copyright (c) 2017-2020 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(23U, 27U, 5U), Size2D(3U, 5U), PadStrideInfo(2, 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 small, 3x3 depthwise convolution shapes. */ 159 class SmallDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 160 { 161 public: SmallDepthwiseConvolutionLayerDataset3x3()162 SmallDepthwiseConvolutionLayerDataset3x3() 163 { 164 add_config(TensorShape(3U, 3U, 2U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0)); 165 add_config(TensorShape(7U, 8U, 3U, 2U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0)); 166 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 0)); 167 // Asymmetric padding 168 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::FLOOR)); 169 } 170 }; 171 172 class SmallDepthwiseConvolutionLayerDataset3x3NCHW final : public DepthwiseConvolutionLayerDataset 173 { 174 public: SmallDepthwiseConvolutionLayerDataset3x3NCHW()175 SmallDepthwiseConvolutionLayerDataset3x3NCHW() 176 { 177 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(3, 2, 1, 1)); 178 // Asymmetric padding 179 add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(2, 2, 3, 1, 2, 1, DimensionRoundingType::FLOOR)); 180 } 181 }; 182 183 /** Dataset containing large, 3x3 depthwise convolution shapes. */ 184 class LargeDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 185 { 186 public: LargeDepthwiseConvolutionLayerDataset3x3()187 LargeDepthwiseConvolutionLayerDataset3x3() 188 { 189 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 1)); 190 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1)); 191 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 0)); 192 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 1)); 193 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1)); 194 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 0)); 195 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 1)); 196 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1)); 197 add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 0)); 198 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1)); 199 add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1)); 200 add_config(TensorShape(233U, 277U, 55U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 0)); 201 add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1)); 202 add_config(TensorShape(233U, 277U, 55U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 0)); 203 add_config(TensorShape(333U, 277U, 77U, 5U), Size2D(3U, 3U), PadStrideInfo(2, 3, 0, 1)); 204 add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1)); 205 } 206 }; 207 208 /** Dataset containing optimized, 3x3 depthwise convolution shapes. */ 209 class SmallOptimizedDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 210 { 211 public: SmallOptimizedDepthwiseConvolutionLayerDataset3x3()212 SmallOptimizedDepthwiseConvolutionLayerDataset3x3() 213 { 214 // Stride 1 215 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 216 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 217 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 218 add_config(TensorShape(7U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 2, 2, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 219 // Stride 2 220 add_config(TensorShape(9U, 9U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)); 221 add_config(TensorShape(9U, 9U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 222 add_config(TensorShape(9U, 9U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1, DimensionRoundingType::CEIL)); 223 // TODO(COMPMID-2464): Enable once dilated conv with stride 2 is supported 224 // add_config(TensorShape(9U, 9U, 1U), Size2D(3U, 3U), PadStrideInfo(2, 2, 2, 2, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 225 } 226 }; 227 /** Dataset containing optimized, 3x3 depthwise convolution shapes. */ 228 class LargeOptimizedDepthwiseConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset 229 { 230 public: LargeOptimizedDepthwiseConvolutionLayerDataset3x3()231 LargeOptimizedDepthwiseConvolutionLayerDataset3x3() 232 { 233 // Stride 1 234 add_config(TensorShape(233U, 277U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 235 add_config(TensorShape(233U, 7U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 236 add_config(TensorShape(7U, 7U, 21U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 237 add_config(TensorShape(28U, 28U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 238 add_config(TensorShape(28U, 28U, 16U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1, DimensionRoundingType::CEIL)); 239 // Stride 2 240 add_config(TensorShape(233U, 277U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)); 241 add_config(TensorShape(233U, 277U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1, 1, 1, DimensionRoundingType::CEIL)); 242 add_config(TensorShape(8U, 8U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::FLOOR)); 243 add_config(TensorShape(8U, 8U, 32U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL)); 244 add_config(TensorShape(8U, 8U, 33U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL)); 245 add_config(TensorShape(64U, 64U, 128U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::CEIL)); 246 } 247 }; 248 249 /** Dataset containing optimized, 5x5 depthwise convolution shapes. */ 250 class SmallOptimizedDepthwiseConvolutionLayerDataset5x5 final : public DepthwiseConvolutionLayerDataset 251 { 252 public: SmallOptimizedDepthwiseConvolutionLayerDataset5x5()253 SmallOptimizedDepthwiseConvolutionLayerDataset5x5() 254 { 255 // Stride 1 256 add_config(TensorShape(7U, 7U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL)); 257 add_config(TensorShape(11U, 11U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 258 add_config(TensorShape(7U, 7U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 2, 2, DimensionRoundingType::CEIL)); 259 add_config(TensorShape(7U, 7U, 16U), Size2D(5U, 5U), PadStrideInfo(1, 1, 4, 4, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 260 // Stride 2 261 add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL)); 262 // TODO(COMPMID-2464): Enable once dilated conv with stride 2 is supported 263 // add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 0, 0, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 264 add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 2, 2, 2, 2, DimensionRoundingType::CEIL)); 265 // TODO(COMPMID-2464): Enable once dilated conv with stride 2 is supported 266 // add_config(TensorShape(9U, 9U, 32U), Size2D(5U, 5U), PadStrideInfo(2, 2, 4, 4, 4, 4, DimensionRoundingType::CEIL), Size2D(2U, 2U)); 267 } 268 }; 269 } // namespace datasets 270 } // namespace test 271 } // namespace arm_compute 272 #endif /* ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_DATASET */ 273