// // Copyright (c) 2017 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef TEST_CONFORMANCE_CLCPP_UTILS_TEST_GENERATE_INPUTS_HPP #define TEST_CONFORMANCE_CLCPP_UTILS_TEST_GENERATE_INPUTS_HPP #include #include #include #include #include #include "../common.hpp" template std::vector generate_input(size_t count, const type& min, const type& max, const std::vector special_cases, typename std::enable_if< is_vector_type::value && std::is_integral::type>::value // std::uniform_int_distribution<> does not work in VS2015 for cl_uchar and cl_char, // because VS2015 thinks that use cl_int, because VS2015 thinks cl_uchar cl_char are // not int types && !(std::is_same::type, cl_uchar>::value || std::is_same::type, cl_char>::value) >::type* = 0) { typedef typename scalar_type::type SCALAR; const size_t vec_size = vector_size::value; std::vector input(count); std::random_device rd; std::mt19937 gen(rd()); std::vector> dists(vec_size); for(size_t i = 0; i < vec_size; i++) { dists[i] = std::uniform_int_distribution(min.s[i], max.s[i]); } for(auto& i : input) { for(size_t j = 0; j < vec_size; j++) { i.s[j] = dists[j](gen); } } input.insert(input.begin(), special_cases.begin(), special_cases.end()); input.resize(count); return input; } template std::vector generate_input(size_t count, const type& min, const type& max, const std::vector special_cases, typename std::enable_if< is_vector_type::value && std::is_integral::type>::value // std::uniform_int_distribution<> does not work in VS2015 for cl_uchar and cl_char, // because VS2015 thinks that use cl_int, because VS2015 thinks cl_uchar cl_char are // not int types && (std::is_same::type, cl_uchar>::value || std::is_same::type, cl_char>::value) >::type* = 0) { typedef typename scalar_type::type SCALAR; const size_t vec_size = vector_size::value; std::vector input(count); std::random_device rd; std::mt19937 gen(rd()); std::vector> dists(vec_size); for(size_t i = 0; i < vec_size; i++) { dists[i] = std::uniform_int_distribution( static_cast(min.s[i]), static_cast(max.s[i]) ); } for(auto& i : input) { for(size_t j = 0; j < vec_size; j++) { i.s[j] = static_cast(dists[j](gen)); } } input.insert(input.begin(), special_cases.begin(), special_cases.end()); input.resize(count); return input; } template std::vector generate_input(size_t count, const type& min, const type& max, const std::vector special_cases, typename std::enable_if< !is_vector_type::value && std::is_integral::value // std::uniform_int_distribution<> does not work in VS2015 for cl_uchar and cl_char, // because VS2015 thinks that use cl_int, because VS2015 thinks cl_uchar cl_char are // not int types && !(std::is_same::value || std::is_same::value) >::type* = 0) { std::vector input(count); std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution dis(min, max); for(auto& i : input) { i = dis(gen); } input.insert(input.begin(), special_cases.begin(), special_cases.end()); input.resize(count); return input; } template std::vector generate_input(size_t count, const type& min, const type& max, const std::vector special_cases, typename std::enable_if< !is_vector_type::value && std::is_integral::value // std::uniform_int_distribution<> does not work in VS2015 for cl_uchar and cl_char, // because VS2015 thinks that use cl_int, because VS2015 thinks cl_uchar cl_char are // not int types && (std::is_same::value || std::is_same::value) >::type* = 0) { std::vector input(count); std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution dis( static_cast(min), static_cast(max) ); for(auto& i : input) { i = static_cast(dis(gen)); } input.insert(input.begin(), special_cases.begin(), special_cases.end()); input.resize(count); return input; } template std::vector generate_input(size_t count, const type& min, const type& max, const std::vector special_cases, typename std::enable_if< is_vector_type::value && std::is_floating_point::type>::value >::type* = 0) { typedef typename scalar_type::type SCALAR; const size_t vec_size = vector_size::value; std::vector input(count); std::random_device rd; std::mt19937 gen(rd()); std::vector> dists(vec_size); for(size_t i = 0; i < vec_size; i++) { // Fatal error if(std::fpclassify(max.s[i]) == FP_SUBNORMAL || std::fpclassify(min.s[i]) == FP_SUBNORMAL) { log_error("ERROR: min and max value for input generation CAN NOT BE subnormal\n"); } dists[i] = std::uniform_real_distribution(min.s[i], max.s[i]); } for(auto& i : input) { for(size_t j = 0; j < vec_size; j++) { SCALAR x = dists[j](gen); while(std::fpclassify(x) == FP_SUBNORMAL) { x = dists[j](gen); } i.s[j] = x; } } input.insert(input.begin(), special_cases.begin(), special_cases.end()); input.resize(count); return input; } template std::vector generate_input(size_t count, const type& min, const type& max, const std::vector special_cases, typename std::enable_if< !is_vector_type::value && std::is_floating_point::value >::type* = 0) { // Fatal error if(std::fpclassify(max) == FP_SUBNORMAL || std::fpclassify(min) == FP_SUBNORMAL) { log_error("ERROR: min and max value for input generation CAN NOT BE subnormal\n"); } std::vector input(count); std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution dis(min, max); for(auto& i : input) { type x = dis(gen); while(std::fpclassify(x) == FP_SUBNORMAL) { x = dis(gen); } i = x; } input.insert(input.begin(), special_cases.begin(), special_cases.end()); input.resize(count); return input; } template std::vector generate_output(size_t count, typename scalar_type::type svalue = typename scalar_type::type(0), typename std::enable_if::value>::type* = 0) { type value; for(size_t i = 0; i < vector_size::value; i++) value.s[i] = svalue; return std::vector(count, value); } template std::vector generate_output(size_t count, type svalue = type(0), typename std::enable_if::value>::type* = 0) { return std::vector(count, svalue); } template void prepare_special_cases(std::vector& in1_spec_cases, std::vector& in2_spec_cases) { if(in1_spec_cases.empty() || in2_spec_cases.empty()) { return; } size_t new_size = in1_spec_cases.size() * in2_spec_cases.size(); std::vector new_in1(new_size); std::vector new_in2(new_size); for(size_t i = 0; i < in1_spec_cases.size(); i++) { for(size_t j = 0; j < in2_spec_cases.size(); j++) { new_in1[(i * in2_spec_cases.size()) + j] = in1_spec_cases[i]; new_in2[(i * in2_spec_cases.size()) + j] = in2_spec_cases[j]; } } in1_spec_cases = new_in1; in2_spec_cases = new_in2; } template void prepare_special_cases(std::vector& in1_spec_cases, std::vector& in2_spec_cases, std::vector& in3_spec_cases) { if(in3_spec_cases.empty()) { return prepare_special_cases(in1_spec_cases, in2_spec_cases); } else if (in2_spec_cases.empty()) { return prepare_special_cases(in1_spec_cases, in3_spec_cases); } else if (in1_spec_cases.empty()) { return prepare_special_cases(in2_spec_cases, in3_spec_cases); } size_t new_size = in1_spec_cases.size() * in2_spec_cases.size() * in3_spec_cases.size(); std::vector new_in1(new_size); std::vector new_in2(new_size); std::vector new_in3(new_size); for(size_t i = 0; i < in1_spec_cases.size(); i++) { for(size_t j = 0; j < in2_spec_cases.size(); j++) { for(size_t k = 0; k < in3_spec_cases.size(); k++) { size_t idx = (i * in2_spec_cases.size() * in3_spec_cases.size()) + (j * in3_spec_cases.size()) + k; new_in1[idx] = in1_spec_cases[i]; new_in2[idx] = in2_spec_cases[j]; new_in3[idx] = in3_spec_cases[k]; } } } in1_spec_cases = new_in1; in2_spec_cases = new_in2; in3_spec_cases = new_in3; } #endif // TEST_CONFORMANCE_CLCPP_UTILS_TEST_GENERATE_INPUTS_HPP