1 /* 2 * Copyright (c) 2020-2022 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 TESTS_DATASETS_SCALEVALIDATIONDATASET 25 #define TESTS_DATASETS_SCALEVALIDATIONDATASET 26 27 #include "arm_compute/core/Types.h" 28 #include "tests/datasets/BorderModeDataset.h" 29 #include "tests/datasets/SamplingPolicyDataset.h" 30 #include "tests/datasets/ShapeDatasets.h" 31 32 namespace arm_compute 33 { 34 namespace test 35 { 36 namespace datasets 37 { 38 /** Class to generate boundary values for the given template parameters 39 * including shapes with large differences between width and height. 40 * element_per_iteration is the number of elements processed by one iteration 41 * of an implementation. (E.g., if an iteration is based on a 16-byte vector 42 * and size of one element is 1-byte, this value would be 16.). 43 * iterations is the total number of complete iterations we want to test 44 * for the effect of larger shapes. 45 */ 46 template <uint32_t channel, uint32_t batch, uint32_t element_per_iteration, uint32_t iterations> 47 class ScaleShapesBaseDataSet : public ShapeDataset 48 { 49 static constexpr auto boundary_minus_one = element_per_iteration * iterations - 1; 50 static constexpr auto boundary_plus_one = element_per_iteration * iterations + 1; 51 static constexpr auto small_size = 3; 52 53 public: 54 // These tensor shapes are NCHW layout, fixture will convert to NHWC. ScaleShapesBaseDataSet()55 ScaleShapesBaseDataSet() 56 : ShapeDataset("Shape", 57 { 58 TensorShape{ small_size, boundary_minus_one, channel, batch }, 59 TensorShape{ small_size, boundary_plus_one, channel, batch }, 60 TensorShape{ boundary_minus_one, small_size, channel, batch }, 61 TensorShape{ boundary_plus_one, small_size, channel, batch }, 62 TensorShape{ boundary_minus_one, boundary_plus_one, channel, batch }, 63 TensorShape{ boundary_plus_one, boundary_minus_one, channel, batch }, 64 }) 65 { 66 } 67 }; 68 69 /** For the single vector, only larger value (+1) than boundary 70 * since smaller value (-1) could cause some invalid shapes like 71 * - invalid zero size 72 * - size 1 which isn't compatible with scale with aligned corners. 73 */ 74 template <uint32_t channel, uint32_t batch, uint32_t element_per_iteration> 75 class ScaleShapesBaseDataSet<channel, batch, element_per_iteration, 1> : public ShapeDataset 76 { 77 static constexpr auto small_size = 3; 78 static constexpr auto boundary_plus_one = element_per_iteration + 1; 79 80 public: 81 // These tensor shapes are NCHW layout, fixture will convert to NHWC. ScaleShapesBaseDataSet()82 ScaleShapesBaseDataSet() 83 : ShapeDataset("Shape", 84 { 85 TensorShape{ small_size, boundary_plus_one, channel, batch }, 86 TensorShape{ boundary_plus_one, small_size, channel, batch }, 87 }) 88 { 89 } 90 }; 91 92 /** For the shapes smaller than one vector, only pre-defined tiny shapes 93 * are tested (3x2, 2x3) as smaller shapes are more likely to cause 94 * issues and easier to debug. 95 */ 96 template <uint32_t channel, uint32_t batch, uint32_t element_per_iteration> 97 class ScaleShapesBaseDataSet<channel, batch, element_per_iteration, 0> : public ShapeDataset 98 { 99 static constexpr auto small_size = 3; 100 static constexpr auto zero_vector_boundary_value = 2; 101 102 public: 103 // These tensor shapes are NCHW layout, fixture will convert to NHWC. ScaleShapesBaseDataSet()104 ScaleShapesBaseDataSet() 105 : ShapeDataset("Shape", 106 { 107 TensorShape{ small_size, zero_vector_boundary_value, channel, batch }, 108 TensorShape{ zero_vector_boundary_value, small_size, channel, batch }, 109 }) 110 { 111 } 112 }; 113 114 /** Interpolation policy test set */ 115 const auto ScaleInterpolationPolicySet = framework::dataset::make("InterpolationPolicy", 116 { 117 InterpolationPolicy::NEAREST_NEIGHBOR, 118 InterpolationPolicy::BILINEAR, 119 }); 120 121 /** Scale data types */ 122 const auto ScaleDataLayouts = framework::dataset::make("DataLayout", 123 { 124 DataLayout::NCHW, 125 DataLayout::NHWC, 126 }); 127 128 /** Sampling policy data set */ 129 const auto ScaleSamplingPolicySet = combine(datasets::SamplingPolicies(), 130 framework::dataset::make("AlignCorners", { false })); 131 132 /** Sampling policy data set for Aligned Corners which only allows TOP_LEFT policy.*/ 133 const auto ScaleAlignCornersSamplingPolicySet = combine(framework::dataset::make("SamplingPolicy", 134 { 135 SamplingPolicy::TOP_LEFT, 136 }), 137 framework::dataset::make("AlignCorners", { true })); 138 139 /** Generated shapes: used by precommit and nightly for CPU tests 140 * - 2D shapes with 0, 1, 2 vector iterations 141 * - 3D shapes with 0, 1 vector iterations 142 * - 4D shapes with 0 vector iterations 143 */ 144 #define SCALE_SHAPE_DATASET(element_per_iteration) \ 145 concat(concat(concat(ScaleShapesBaseDataSet<1, 1, (element_per_iteration), 0>(), \ 146 ScaleShapesBaseDataSet<1, 1, (element_per_iteration), 2>()), \ 147 ScaleShapesBaseDataSet<3, 1, (element_per_iteration), 1>()), \ 148 ScaleShapesBaseDataSet<40, 3, (element_per_iteration), 0>()) 149 150 // To prevent long precommit time for OpenCL, shape set for OpenCL is separated into below two parts. 151 /** Generated shapes for precommits to achieve essential coverage. Used by CL precommit and nightly 152 * - 3D shapes with 1 vector iterations 153 * - 4D shapes with 1 vector iterations 154 */ 155 #define SCALE_PRECOMMIT_SHAPE_DATASET(element_per_iteration) \ 156 concat(ScaleShapesBaseDataSet<3, 1, (element_per_iteration), 1>(), ScaleShapesBaseDataSet<3, 3, (element_per_iteration), 1>()) 157 158 /** Generated shapes for nightly to achieve more small and variety shapes. Used by CL nightly 159 * - 2D shapes with 0, 1, 2 vector iterations 160 * - 3D shapes with 0 vector iterations (1 vector iteration is covered by SCALE_PRECOMMIT_SHAPE_DATASET) 161 * - 4D shapes with 0 vector iterations 162 */ 163 #define SCALE_NIGHTLY_SHAPE_DATASET(element_per_iteration) \ 164 concat(concat(concat(ScaleShapesBaseDataSet<1, 1, (element_per_iteration), 0>(), \ 165 ScaleShapesBaseDataSet<1, 1, (element_per_iteration), 1>()), \ 166 ScaleShapesBaseDataSet<3, 1, (element_per_iteration), 0>()), \ 167 ScaleShapesBaseDataSet<3, 3, (element_per_iteration), 0>()) 168 169 /** Generating dataset for non-quantized data types with the given shapes */ 170 #define ASSEMBLE_DATASET(shape, samping_policy_set) \ 171 combine(combine(combine(combine((shape), ScaleDataLayouts), \ 172 ScaleInterpolationPolicySet), \ 173 datasets::BorderModes()), \ 174 samping_policy_set) 175 176 #define ASSEMBLE_DATASET_DYNAMIC_FUSION(shape, samping_policy_set) \ 177 combine(combine(combine((shape), framework::dataset::make("DataLayout", { DataLayout::NHWC })), \ 178 ScaleInterpolationPolicySet), \ 179 samping_policy_set) 180 181 #define ASSEMBLE_S8_DATASET(shape, samping_policy_set) \ 182 combine(combine(combine(combine((shape), framework::dataset::make("DataLayout", DataLayout::NHWC)), \ 183 framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::BILINEAR })), \ 184 framework::dataset::make("BorderMode", { BorderMode::REPLICATE })), \ 185 samping_policy_set) 186 187 #define ASSEMBLE_NHWC_DATASET(shape, samping_policy_set) \ 188 combine(combine(combine(combine((shape), framework::dataset::make("DataLayout", DataLayout::NHWC)), \ 189 ScaleInterpolationPolicySet), \ 190 framework::dataset::make("BorderMode", { BorderMode::CONSTANT, BorderMode::REPLICATE })), \ 191 samping_policy_set) 192 193 /** Generating dataset for quantized data tyeps with the given shapes */ 194 #define ASSEMBLE_QUANTIZED_DATASET(shape, sampling_policy_set, quantization_info_set) \ 195 combine(combine(combine(combine(combine(shape, \ 196 quantization_info_set), \ 197 ScaleDataLayouts), \ 198 ScaleInterpolationPolicySet), \ 199 datasets::BorderModes()), \ 200 sampling_policy_set) 201 202 #define ASSEMBLE_QUANTIZED_DATASET_DYNAMIC_FUSION(shape, sampling_policy_set, quantization_info_set) \ 203 combine(combine(combine(combine(shape, \ 204 quantization_info_set), \ 205 framework::dataset::make("DataLayout", { DataLayout::NHWC })), \ 206 ScaleInterpolationPolicySet), \ 207 sampling_policy_set) 208 209 /** Generating dataset for quantized data tyeps with the given shapes */ 210 #define ASSEMBLE_DIFFERENTLY_QUANTIZED_DATASET(shape, sampling_policy_set, input_quant_info_set, output_quant_info_set) \ 211 combine(combine(combine(combine(combine(combine(shape, \ 212 input_quant_info_set), \ 213 output_quant_info_set), \ 214 framework::dataset::make("DataLayout", { DataLayout::NHWC })), \ 215 framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::BILINEAR })), \ 216 framework::dataset::make("BorderMode", { BorderMode::REPLICATE })), \ 217 sampling_policy_set) 218 219 } // namespace datasets 220 } // namespace test 221 } // namespace arm_compute 222 #endif /* TESTS_DATASETS_SCALEVALIDATIONDATASET */ 223