diff options
-rw-r--r-- | arm_compute/core/CL/CLKernelLibrary.h | 11 | ||||
-rw-r--r-- | src/core/CL/CLKernelLibrary.cpp | 14 | ||||
-rw-r--r-- | src/core/CL/cl_kernels/fixed_point.h | 214 | ||||
-rw-r--r-- | tests/dataset/ShapeDatasets.h | 2 | ||||
-rw-r--r-- | tests/validation/CL/FixedPoint/FixedPoint_QS8.cpp | 225 |
5 files changed, 388 insertions, 78 deletions
diff --git a/arm_compute/core/CL/CLKernelLibrary.h b/arm_compute/core/CL/CLKernelLibrary.h index c29610c252..38cfad6c1d 100644 --- a/arm_compute/core/CL/CLKernelLibrary.h +++ b/arm_compute/core/CL/CLKernelLibrary.h @@ -174,6 +174,17 @@ public: { _kernel_path = kernel_path; }; + /** Gets the path that the kernels reside in. + */ + std::string get_kernel_path() + { + return _kernel_path; + }; + /** Gets the source of the selected program + * + * @param[in] program_name Program name. + */ + std::string get_program_source(const std::string &program_name); /** Sets the CL context used to create programs. * * @note Setting the context also resets the device to the diff --git a/src/core/CL/CLKernelLibrary.cpp b/src/core/CL/CLKernelLibrary.cpp index 6cf5ce2564..4a92bac23c 100644 --- a/src/core/CL/CLKernelLibrary.cpp +++ b/src/core/CL/CLKernelLibrary.cpp @@ -486,7 +486,7 @@ const std::map<std::string, std::string> CLKernelLibrary::_program_source_map = { "warp_perspective.cl", #include "./cl_kernels/warp_perspective.clembed" - } + }, #endif }; @@ -602,3 +602,15 @@ std::string CLKernelLibrary::stringify_set(const StringSet &s) const return concat_set; } + +std::string CLKernelLibrary::get_program_source(const std::string &program_name) +{ + const auto program_source_it = _program_source_map.find(program_name); + + if(program_source_it == _program_source_map.end()) + { + ARM_COMPUTE_ERROR("Embedded program for %s does not exist.", program_name.c_str()); + } + + return program_source_it->second; +} diff --git a/src/core/CL/cl_kernels/fixed_point.h b/src/core/CL/cl_kernels/fixed_point.h index c0855db056..32e49c2fad 100644 --- a/src/core/CL/cl_kernels/fixed_point.h +++ b/src/core/CL/cl_kernels/fixed_point.h @@ -60,6 +60,13 @@ TYPE_ALIAS(short, qs16) #define qs16x8_TYPE short8 #define qs16x16_TYPE short16 +/* All internal constants are represented in the maximum supported fixed point format (QS16), + * thus we define an additional shift parameter required to convert the constant + * from the maximum supported format to the require one. + */ +#define qs8_SHIFT 8 +#define qs16_SHIFT 0 + #undef VEC_DATA_TYPE_STR #undef VEC_DATA_TYPE #undef CONVERT_STR @@ -80,12 +87,12 @@ TYPE_ALIAS(short, qs16) #define CONVERT_SAT_STR(x, type) CONVERT_SAT_STR2(x, type, type##_TYPE) #define CONVERT_SAT(x, type) CONVERT_SAT_STR(x, type) -/* Computes max of fixed point types. - * - * @param[in] type the actual data type. - * - * @return The result of the fixed point maximum. - */ +/** Computes max of fixed point types. + * + * @param[in] type the actual data type. + * + * @return The result of the fixed point maximum. + */ #define MAXQ_IMPL(type) \ inline type max_##type(type VopA, type VopB) \ { \ @@ -101,12 +108,12 @@ MAXQ_IMPL(qs8x16) #define MAX_OP_EXPAND_STR(a, b, type, size) max_##type##x##size((a), (b)) #define MAX_OP_EXPAND(a, b, type, size) MAX_OP_EXPAND_STR(a, b, type, size) -/* Computes saturated addition of fixed point types. - * - * @param[in] type the actual data type. - * - * @return The result of the fixed point addition. The result is saturated in case of overflow - */ +/** Computes saturated addition of fixed point types. + * + * @param[in] type the actual data type. + * + * @return The result of the fixed point addition. The result is saturated in case of overflow + */ #define ADDQ_SAT_IMPL(type) \ inline type add_sat_##type(type VopA, type VopB) \ { \ @@ -122,12 +129,12 @@ ADDQ_SAT_IMPL(qs8x16) #define ADD_SAT_OP_EXPAND_STR(a, b, type, size) add_sat_##type##x##size((a), (b)) #define ADD_SAT_OP_EXPAND(a, b, type, size) ADD_SAT_OP_EXPAND_STR(a, b, type, size) -/* Computes saturated subtraction of fixed point types. - * - * @param[in] type the actual data type. - * - * @return The result of the fixed point subtraction. The result is saturated in case of overflow - */ +/** Computes saturated subtraction of fixed point types. + * + * @param[in] type the actual data type. + * + * @return The result of the fixed point subtraction. The result is saturated in case of overflow + */ #define SUBQ_SAT_IMPL(type) \ inline type sub_sat_##type(type VopA, type VopB) \ { \ @@ -143,13 +150,13 @@ SUBQ_SAT_IMPL(qs8x16) #define SUB_SAT_OP_EXPAND_STR(a, b, type, size) sub_sat_##type##x##size((a), (b)) #define SUB_SAT_OP_EXPAND(a, b, type, size) SUB_SAT_OP_EXPAND_STR(a, b, type, size) -/* Saturate multiply of two fixed point numbers - * - * @param[in] type the actual data type. - * @param[in] itype the intermediate data type. - * - * @return The result of the fixed point multiplication. The result is saturated in case of overflow - */ +/** Saturate multiply of two fixed point numbers + * + * @param[in] type the actual data type. + * @param[in] itype the intermediate data type. + * + * @return The result of the fixed point multiplication. The result is saturated in case of overflow + */ #define MULQ_SAT_IMPL(type, itype) \ inline type mul_sat_##type(type VopA, type VopB, int fixed_point_position) \ { \ @@ -163,13 +170,13 @@ MULQ_SAT_IMPL(qs8x16, qs16x16) #define MUL_SAT_OP_EXPAND_STR(a, b, type, size, position) mul_sat_##type##x##size((a), (b), (position)) #define MUL_SAT_OP_EXPAND(a, b, type, size, position) MUL_SAT_OP_EXPAND_STR(a, b, type, size, position) -/* Saturate multiply-accumulate - * - * @param[in] type the actual data type. - * @param[in] itype the intermediate data type. - * - * @return The result of the fixed point multiply-accumulate. The result is saturated in case of overflow - */ +/** Saturate multiply-accumulate + * + * @param[in] type the actual data type. + * @param[in] itype the intermediate data type. + * + * @return The result of the fixed point multiply-accumulate. The result is saturated in case of overflow + */ #define MLAQ_SAT_IMPL(type, itype) \ type mla_sat_##type(type VopA, type VopB, type VopC, int fixed_point_position) \ { \ @@ -183,13 +190,13 @@ MLAQ_SAT_IMPL(qs8x16, qs16x16) #define MLA_SAT_OP_EXPAND_STR(a, b, c, type, size, position) mla_sat_##type##x##size((a), (b), (c), (position)) #define MLA_SAT_OP_EXPAND(a, b, c, type, size, position) MLA_SAT_OP_EXPAND_STR(a, b, c, type, size, position) -/* Saturate multiply-accumulate long - * - * @param[in] type the actual data type. - * @param[in] itype the intermediate data type. - * - * @return The result of the fixed point multiply-accumulate long. The result is saturated in case of overflow - */ +/** Saturate multiply-accumulate long + * + * @param[in] type the actual data type. + * @param[in] itype the intermediate data type. + * + * @return The result of the fixed point multiply-accumulate long. The result is saturated in case of overflow + */ #define MLALQ_SAT_IMPL(type, itype) \ itype mlal_sat_##type(itype VopA, type VopB, type VopC, int fixed_point_position) \ { \ @@ -225,44 +232,99 @@ DIVQ_SAT_IMPL(qs8, qs8x16, qs16x16) #define DIV_SAT_OP_EXPAND_STR(a, b, type, size, position) div_sat_##type##x##size((a), (b), (position)) #define DIV_SAT_OP_EXPAND(a, b, type, size, position) DIV_SAT_OP_EXPAND_STR(a, b, type, size, position) -/** Saturate exponential fixed point 8 bit (16 elements) +/** Saturate exponential of a fixed point vector * - * @param[in] a 8 bit fixed point input vector - * @param[in] fixed_point_position Fixed point position that expresses the number of bits for the fractional part of the number - * - * @return The result of the 8 bit fixed point exponential. The result is saturated in case of overflow - */ -qs8x16 inline exp_qs8x16(qs8x16 a, int fixed_point_position) -{ - // Constants (literal constants are calculated by converting the respective float to the fixed point with the highest supported fixed point position) - char16 const_one = (char16)(1 << (fixed_point_position)); - char16 ln2 = (char16)(((0x58 >> (6 - fixed_point_position)) + 1) >> 1); // 0.693147 - char16 inv_ln2 = ((char16)(((0x38 >> (6 - (fixed_point_position))) + 1) >> 1)) | const_one; // 1.442695 - char16 A = (char16)(((0x7F >> (6 - (fixed_point_position))) + 1) >> 1); // 0.9978546 - char16 B = (char16)(((0x3F >> (6 - (fixed_point_position))) + 1) >> 1); // 0.4994721 - char16 C = (char16)(((0x16 >> (6 - (fixed_point_position))) + 1) >> 1); // 0.1763723 - char16 D = (char16)(((0x05 >> (6 - (fixed_point_position))) + 1) >> 1); // 0.0435108 - - // Perform range reduction [-log(2),log(2)] - char16 m = mul_sat_qs8x16(a, inv_ln2, fixed_point_position); - - // get decimal part of m - char16 dec_m = m >> (char16)fixed_point_position; - - char16 alpha = mul_sat_qs8x16(dec_m << (char16)fixed_point_position, ln2, fixed_point_position); - alpha = convert_char16(abs_diff(a, alpha)); - - // Polynomial expansion - char16 sum = add_sat_qs8x16(mul_sat_qs8x16(alpha, D, fixed_point_position), C); - sum = add_sat_qs8x16(mul_sat_qs8x16(alpha, sum, fixed_point_position), B); - sum = add_sat_qs8x16(mul_sat_qs8x16(alpha, sum, fixed_point_position), A); - sum = add_sat_qs8x16(mul_sat_qs8x16(alpha, sum, fixed_point_position), const_one); - - // Reconstruct and saturate result - return select(select(sum << dec_m, sum >> -dec_m, dec_m < (char16)0), (char16)0x7F, clz(sum) <= dec_m); -} - -#define EXP_OP_EXPAND_STR(a, type, size, position) exp_##type##x##size((a), (position)) + * @param[in] stype the actual scalar data type. + * @param[in] type the actual data type. + * @param[in] size the number of the calculated elements. + * + * @return The result of the fixed point exponential. The result is saturated in case of overflow + */ +#define EXPQ_IMPL(stype, type, size) \ + inline type exp_sat_##type(type VopA, int fixed_point_position) \ + { \ + type const_one = (type)(1 << (fixed_point_position)); \ + type ln2 = (type)((((0x58B9 >> (14 - fixed_point_position))) + 1) >> 1); \ + type inv_ln2 = (type)((((0x38AA >> (14 - fixed_point_position)) + 1) >> 1)) | const_one; \ + type A = (type)(((0x7FBA >> (14 - fixed_point_position)) + 1) >> 1); \ + type B = (type)(((0x3FE9 >> (14 - fixed_point_position)) + 1) >> 1); \ + type C = (type)(((0x1693 >> (14 - fixed_point_position)) + 1) >> 1); \ + type D = (type)(((0x0592 >> (14 - fixed_point_position)) + 1) >> 1); \ + type m = MUL_SAT_OP_EXPAND(VopA, inv_ln2, stype, size, fixed_point_position); \ + type dec_m = m >> (type)fixed_point_position; \ + type alpha = MUL_SAT_OP_EXPAND(dec_m << (type)fixed_point_position, ln2, stype, size, fixed_point_position); \ + alpha = CONVERT(abs_diff(VopA, alpha), type); \ + type sum = add_sat(MUL_SAT_OP_EXPAND(alpha, D, stype, size, fixed_point_position), C); \ + sum = add_sat(MUL_SAT_OP_EXPAND(alpha, sum, stype, size, fixed_point_position), B); \ + sum = add_sat(MUL_SAT_OP_EXPAND(alpha, sum, stype, size, fixed_point_position), A); \ + sum = add_sat(MUL_SAT_OP_EXPAND(alpha, sum, stype, size, fixed_point_position), const_one); \ + return select(select(sum << dec_m, sum >> -dec_m, dec_m < (type)0), (type)stype##_MAX, clz(sum) <= dec_m); \ + } + +EXPQ_IMPL(qs8, qs8x16, 16) + +#define EXP_OP_EXPAND_STR(a, type, size, position) exp_sat_##type##x##size((a), (position)) #define EXP_OP_EXPAND(a, type, size, position) EXP_OP_EXPAND_STR(a, type, size, position) +/** Saturate logarithm of a fixed point vector + * + * @param[in] stype the actual scalar data type. + * @param[in] type the actual data type. + * @param[in] size the number of the calculated elements. + * + * @return The result of the fixed point logarithm. The result is saturated in case of overflow + */ +#define LOGQ_IMPL(stype, type, size) \ + inline type log_sat_##type(type VopA, int fixed_point_position) \ + { \ + type const_one = (type)(1 << (fixed_point_position)); \ + type ln2 = (type)(0x58B9 >> (15 - fixed_point_position)); \ + type A = (type)(0x5C0F >> (14 - fixed_point_position)); \ + type B = -(type)(0x56AE >> (15 - fixed_point_position)); \ + type C = (type)(0x2933 >> (15 - fixed_point_position)); \ + type D = -(type)(0x0AA7 >> (15 - fixed_point_position)); \ + type inter_a = select(VopA, DIV_SAT_OP_EXPAND(const_one, VopA, stype, size, fixed_point_position), VopA < const_one); \ + type shift_val = (type)(15 - stype##_SHIFT) - clz(inter_a >> (type)fixed_point_position); \ + inter_a = inter_a >> shift_val; \ + inter_a = sub_sat(inter_a, const_one); \ + type sum = add_sat(MUL_SAT_OP_EXPAND(inter_a, D, stype, size, fixed_point_position), C); \ + sum = add_sat(MUL_SAT_OP_EXPAND(inter_a, sum, stype, size, fixed_point_position), B); \ + sum = add_sat(MUL_SAT_OP_EXPAND(inter_a, sum, stype, size, fixed_point_position), A); \ + sum = MUL_SAT_OP_EXPAND(inter_a, sum, stype, size, fixed_point_position); \ + sum = MUL_SAT_OP_EXPAND(add_sat(sum, shift_val << (type)fixed_point_position), ln2, stype, size, fixed_point_position); \ + return select(select(sum, -sum, VopA < const_one), (type)0, VopA < (type)0); \ + } + +LOGQ_IMPL(qs8, qs8x16, 16) + +#define LOG_OP_EXPAND_STR(a, type, size, position) log_sat_##type##x##size((a), (position)) +#define LOG_OP_EXPAND(a, type, size, position) LOG_OP_EXPAND_STR(a, type, size, position) + +/** Saturate inverse square root of a fixed point vector + * + * @param[in] stype the actual scalar data type. + * @param[in] type the actual data type. + * @param[in] size the number of the calculated elements. + * + * @return The result of the fixed point inverse square root. The result is saturated in case of overflow + */ +#define INVSQRTQ_IMPL(stype, type, size) \ + inline type invsqrt_sat_##type(type VopA, int fixed_point_position) \ + { \ + type const_three = (type)(3 << (fixed_point_position)); \ + type shift_value = (type)(16 - stype##_SHIFT) - (clz(VopA) + (type)fixed_point_position); \ + type temp = select(VopA >> shift_value, VopA << (-shift_value), shift_value < (type)0); \ + type x = temp; \ + x = MUL_SAT_OP_EXPAND(x, sub_sat(const_three, MUL_SAT_OP_EXPAND(MUL_SAT_OP_EXPAND(x, x, stype, size, fixed_point_position), temp, stype, size, fixed_point_position)), stype, size, fixed_point_position) >> 1; \ + x = MUL_SAT_OP_EXPAND(x, sub_sat(const_three, MUL_SAT_OP_EXPAND(MUL_SAT_OP_EXPAND(x, x, stype, size, fixed_point_position), temp, stype, size, fixed_point_position)), stype, size, fixed_point_position) >> 1; \ + x = MUL_SAT_OP_EXPAND(x, sub_sat(const_three, MUL_SAT_OP_EXPAND(MUL_SAT_OP_EXPAND(x, x, stype, size, fixed_point_position), temp, stype, size, fixed_point_position)), stype, size, fixed_point_position) >> 1; \ + type res = select(x >> (shift_value >> 1), x << ((-shift_value) >> 1), shift_value < (type)0); \ + return select(res, stype##_MAX, res < (type)0); \ + } + +INVSQRTQ_IMPL(qs8, qs8x16, 16) + +#define INVSQRT_OP_EXPAND_STR(a, type, size, position) invsqrt_sat_##type##x##size((a), (position)) +#define INVSQRT_OP_EXPAND(a, type, size, position) INVSQRT_OP_EXPAND_STR(a, type, size, position) + #endif // ARM_COMPUTE_FIXED_POINT_H diff --git a/tests/dataset/ShapeDatasets.h b/tests/dataset/ShapeDatasets.h index ecb478dbf0..1e9e5f139a 100644 --- a/tests/dataset/ShapeDatasets.h +++ b/tests/dataset/ShapeDatasets.h @@ -97,7 +97,7 @@ class Small1DShape final : public ShapeDataset<1> { public: Small1DShape() - : ShapeDataset(TensorShape(128U)) + : ShapeDataset(TensorShape(256U)) { } }; diff --git a/tests/validation/CL/FixedPoint/FixedPoint_QS8.cpp b/tests/validation/CL/FixedPoint/FixedPoint_QS8.cpp new file mode 100644 index 0000000000..fabd9ad161 --- /dev/null +++ b/tests/validation/CL/FixedPoint/FixedPoint_QS8.cpp @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "CL/CLAccessor.h" +#include "Globals.h" +#include "TensorLibrary.h" +#include "TypePrinter.h" +#include "Utils.h" +#include "validation/Datasets.h" +#include "validation/Reference.h" +#include "validation/Validation.h" + +#include "arm_compute/core/CL/CLKernelLibrary.h" +#include "arm_compute/core/CL/ICLKernel.h" +#include "arm_compute/core/CL/OpenCL.h" +#include "arm_compute/core/Helpers.h" +#include "arm_compute/core/Types.h" +#include "arm_compute/core/Window.h" +#include "arm_compute/runtime/CL/CLScheduler.h" +#include "arm_compute/runtime/CL/CLSubTensor.h" +#include "arm_compute/runtime/CL/CLTensor.h" +#include "arm_compute/runtime/CL/CLTensorAllocator.h" + +#include "arm_compute/core/CL/ICLTensor.h" + +#include "boost_wrapper.h" + +#include <random> +#include <string> + +using namespace arm_compute; +using namespace arm_compute::test; +using namespace arm_compute::test::cl; +using namespace arm_compute::test::validation; + +namespace +{ +const float tolerance_exp = 1.0f; /**< Tolerance value for comparing reference's output against implementation's output (exponential)*/ +const float tolerance_invsqrt = 4.0f; /**< Tolerance value for comparing reference's output against implementation's output (inverse square-root) */ +const float tolerance_log = 5.0f; /**< Tolerance value for comparing reference's output against implementation's output (logarithm) */ + +/** Compute Neon fixed point operation for signed 8bit fixed point. + * + * @param[in] shape Shape of the input and output tensors. + * + * @return Computed output tensor. + */ +CLTensor compute_fixed_point_op(const TensorShape &shape, int fixed_point_position, FixedPointOp op) +{ + std::string fixed_point_operation_kernel; +#ifndef EMBEDDED_KERNELS + fixed_point_operation_kernel += "#include \"fixed_point.h\"\n"; +#endif + fixed_point_operation_kernel += + "__kernel void fixed_point_operation_qs8( \n" + " __global char* src, \n" + " __global char* dst) \n" + "{ \n" + " char16 in = vload16(0, src + get_global_id(0) * 16); \n" + " if(FIXED_POINT_OP == 0) \n" + " { \n" + " vstore16(EXP_OP_EXPAND(in, DATA_TYPE, 16, FIXED_POINT_POS), 0, dst + get_global_id(0) * 16); \n" + " } \n" + " else if(FIXED_POINT_OP == 1) \n" + " { \n" + " vstore16(INVSQRT_OP_EXPAND(in, DATA_TYPE, 16, FIXED_POINT_POS), 0, dst + get_global_id(0) * 16); \n" + " } \n" + " else \n" + " { \n" + " vstore16(LOG_OP_EXPAND(in, DATA_TYPE, 16, FIXED_POINT_POS), 0, dst + get_global_id(0) * 16); \n" + " } \n" + "} \n" + "\n"; + + // Create tensors + CLTensor src = create_tensor<CLTensor>(shape, DataType::QS8, 1, fixed_point_position); + CLTensor dst = create_tensor<CLTensor>(shape, DataType::QS8, 1, fixed_point_position); + + // Allocate tensors + src.allocator()->allocate(); + dst.allocator()->allocate(); + + BOOST_TEST(!src.info()->is_resizable()); + BOOST_TEST(!dst.info()->is_resizable()); + + // Set build options + std::string build_opts = "-DFIXED_POINT_POS=" + val_to_string<int>(fixed_point_position); + build_opts += " -DDATA_TYPE=qs8"; + + // Fill tensors. + int min = 0; + int max = 0; + switch(op) + { + case FixedPointOp::EXP: + min = -(1 << (fixed_point_position - 1)); + max = (1 << (fixed_point_position - 1)); + build_opts += " -DFIXED_POINT_OP=0"; + break; + case FixedPointOp::INV_SQRT: + min = 1; + max = 0x7F; + build_opts += " -DFIXED_POINT_OP=1"; + break; + case FixedPointOp::LOG: + min = (1 << (fixed_point_position - 1)); + max = 0x3F; + build_opts += " -DFIXED_POINT_OP=2"; + break; + default: + ARM_COMPUTE_ERROR("Operation not supported"); + } + + std::uniform_int_distribution<> distribution(min, max); + library->fill(CLAccessor(src), distribution, 0); + + std::vector<std::string> sources; + +#ifndef EMBEDDED_KERNELS + build_opts += " -I" + CLKernelLibrary::get().get_kernel_path(); +#else + sources.push_back(CLKernelLibrary::get().get_program_source("fixed_point.h")); +#endif /* EMBEDDED_KERNELS */ + + sources.push_back(fixed_point_operation_kernel); + + // Create program + ::cl::Program program = ::cl::Program(sources); + + // Build program + program.build(build_opts.c_str()); + + ::cl::Kernel kernel = ::cl::Kernel(program, "fixed_point_operation_qs8", nullptr); + + unsigned int idx = 0; + kernel.setArg(idx++, src.cl_buffer()); + kernel.setArg(idx++, dst.cl_buffer()); + + ::cl::NDRange gws(shape[0] / 16, 1, 1); + CLScheduler::get().queue().enqueueNDRangeKernel(kernel, 0, gws); + + return dst; +} +} // namespace + +#ifndef DOXYGEN_SKIP_THIS +BOOST_AUTO_TEST_SUITE(CL) +BOOST_AUTO_TEST_SUITE(FixedPoint) +BOOST_AUTO_TEST_SUITE(QS8) + +BOOST_AUTO_TEST_SUITE(Exp) + +BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) +BOOST_DATA_TEST_CASE(RunSmall, Small1DShape() * boost::unit_test::data::xrange(1, 6), shape, fixed_point_position) +{ + // Compute function + CLTensor dst = compute_fixed_point_op(shape, fixed_point_position, FixedPointOp::EXP); + + // Compute reference + RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::EXP, fixed_point_position); + + // Validate output + validate(CLAccessor(dst), ref_dst, tolerance_exp); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(Log) + +BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) +BOOST_DATA_TEST_CASE(RunSmall, Small1DShape() * boost::unit_test::data::xrange(3, 6), shape, fixed_point_position) +{ + // Compute function + CLTensor dst = compute_fixed_point_op(shape, fixed_point_position, FixedPointOp::LOG); + + // Compute reference + RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::LOG, fixed_point_position); + + // Validate output + validate(CLAccessor(dst), ref_dst, tolerance_log); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(Invsqrt) + +BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) +BOOST_DATA_TEST_CASE(RunSmall, Small1DShape() * boost::unit_test::data::xrange(1, 6), shape, fixed_point_position) +{ + // Compute function + CLTensor dst = compute_fixed_point_op(shape, fixed_point_position, FixedPointOp::INV_SQRT); + + // Compute reference + RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::INV_SQRT, fixed_point_position); + + // Validate output + validate(CLAccessor(dst), ref_dst, tolerance_invsqrt); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() +#endif |