1 /* 2 * Copyright (c) 2020-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_LOGICAL_FIXTURE 25 #define ARM_COMPUTE_TEST_LOGICAL_FIXTURE 26 27 #include "arm_compute/core/TensorShape.h" 28 #include "arm_compute/core/Types.h" 29 #include "tests/AssetsLibrary.h" 30 #include "tests/Globals.h" 31 #include "tests/IAccessor.h" 32 #include "tests/framework/Asserts.h" 33 #include "tests/framework/Fixture.h" 34 #include "tests/validation/reference/Logical.h" 35 36 namespace arm_compute 37 { 38 namespace test 39 { 40 namespace validation 41 { 42 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 43 class LogicalOperationValidationFixtureBase : public framework::Fixture 44 { 45 protected: 46 template <typename U> fill(U && tensor,int i)47 void fill(U &&tensor, int i) 48 { 49 constexpr auto zero = static_cast<uint8_t>(0); 50 constexpr auto one = static_cast<uint8_t>(0x1); 51 constexpr auto mixed = static_cast<uint8_t>(0xAA); 52 constexpr auto mixed_bitwise_not = static_cast<uint8_t>((~0xAA)); 53 54 library->fill_static_values(tensor, i == 0 ? 55 std::vector<uint8_t> { zero, one, zero, one, mixed, zero, mixed } : 56 std::vector<uint8_t> { zero, zero, one, one, zero, mixed, mixed_bitwise_not }); 57 } 58 allocate_tensor(std::initializer_list<TensorType * > tensors)59 void allocate_tensor(std::initializer_list<TensorType *> tensors) 60 { 61 for(auto t : tensors) 62 { 63 ARM_COMPUTE_ASSERT(t->info()->is_resizable()); 64 t->allocator()->allocate(); 65 ARM_COMPUTE_ASSERT(!t->info()->is_resizable()); 66 } 67 } 68 69 TensorType _target{}; 70 SimpleTensor<T> _reference{}; 71 }; 72 73 template <typename T> 74 using LogicalBinaryRefFunctionPtrType = SimpleTensor<T>(const SimpleTensor<T> &, const SimpleTensor<T> &); 75 76 template <typename TensorType, typename AccessorType, typename FunctionType, typename T, LogicalBinaryRefFunctionPtrType<T> RefFunction> 77 class LogicalBinaryOperationValidationFixture : public LogicalOperationValidationFixtureBase<TensorType, AccessorType, FunctionType, T> 78 { 79 using Parent = LogicalOperationValidationFixtureBase<TensorType, AccessorType, FunctionType, T>; 80 81 public: 82 template <typename...> setup(TensorShape shape0,TensorShape shape1)83 void setup(TensorShape shape0, TensorShape shape1) 84 { 85 Parent::_target = compute_target(shape0, shape1); 86 Parent::_reference = compute_reference(shape0, shape1); 87 } 88 89 private: compute_target(const TensorShape & shape0,const TensorShape & shape1)90 TensorType compute_target(const TensorShape &shape0, const TensorShape &shape1) 91 { 92 TensorType src0 = create_tensor<TensorType>(shape0, _data_type); 93 TensorType src1 = create_tensor<TensorType>(shape1, _data_type); 94 TensorType dst = create_tensor<TensorType>(TensorShape::broadcast_shape(shape0, shape1), _data_type); 95 96 FunctionType logical_binary_op; 97 98 logical_binary_op.configure(&src0, &src1, &dst); 99 100 Parent::allocate_tensor({ &src0, &src1, &dst }); 101 102 Parent::fill(AccessorType(src0), 0); 103 Parent::fill(AccessorType(src1), 1); 104 105 logical_binary_op.run(); 106 107 return dst; 108 } 109 compute_reference(const TensorShape & shape0,const TensorShape & shape1)110 SimpleTensor<T> compute_reference(const TensorShape &shape0, const TensorShape &shape1) 111 { 112 // Create reference 113 SimpleTensor<T> src0{ shape0, _data_type }; 114 SimpleTensor<T> src1{ shape1, _data_type }; 115 116 // Fill reference 117 Parent::fill(src0, 0); 118 Parent::fill(src1, 1); 119 120 return RefFunction(src0, src1); 121 } 122 123 static constexpr auto _data_type = DataType::U8; 124 }; 125 126 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 127 using LogicalOrValidationFixture = LogicalBinaryOperationValidationFixture<TensorType, AccessorType, FunctionType, T, &reference::logical_or<T>>; 128 129 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 130 using LogicalAndValidationFixture = LogicalBinaryOperationValidationFixture<TensorType, AccessorType, FunctionType, T, &reference::logical_and<T>>; 131 132 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 133 class LogicalNotValidationFixture : public LogicalOperationValidationFixtureBase<TensorType, AccessorType, FunctionType, T> 134 { 135 using Parent = LogicalOperationValidationFixtureBase<TensorType, AccessorType, FunctionType, T>; 136 137 public: 138 template <typename...> setup(TensorShape shape,DataType data_type)139 void setup(TensorShape shape, DataType data_type) 140 { 141 Parent::_target = compute_target(shape, data_type); 142 Parent::_reference = compute_reference(shape, data_type); 143 } 144 145 private: compute_target(const TensorShape & shape,DataType data_type)146 TensorType compute_target(const TensorShape &shape, DataType data_type) 147 { 148 TensorType src = create_tensor<TensorType>(shape, data_type); 149 TensorType dst = create_tensor<TensorType>(shape, data_type); 150 151 FunctionType logical_not; 152 153 logical_not.configure(&src, &dst); 154 155 Parent::allocate_tensor({ &src, &dst }); 156 157 Parent::fill(AccessorType(src), 0); 158 159 logical_not.run(); 160 161 return dst; 162 } 163 compute_reference(const TensorShape & shape,DataType data_type)164 SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type) 165 { 166 // Create reference 167 SimpleTensor<T> src{ shape, data_type }; 168 169 // Fill reference 170 Parent::fill(src, 0); 171 172 return reference::logical_not<T>(src); 173 } 174 }; 175 } // namespace validation 176 } // namespace test 177 } // namespace arm_compute 178 #endif /* ARM_COMPUTE_TEST_LOGICAL_FIXTURE */ 179