From a1d8c3e41930a2fc81fa62fce14d954e6b424ac9 Mon Sep 17 00:00:00 2001 From: Ahmed <36049290+AhmedAmraniAkdi@users.noreply.github.com> Date: Tue, 21 Oct 2025 17:59:13 +0100 Subject: [PATCH] Remove spir half vloada_half tests as this builtin does not exist in OpenCL (#2552) The test was using vloada_half which does not exist for scalars. Also removed the files test.vloada_half_*.* from half.zip. For test.vloada_half3_global, changed the OpenCL kernel to use vload_half instead of vloada_half. Build failures will return a proper failure now, before, the test was passing in this case. More Info: https://github.com/KhronosGroup/OpenCL-Docs/issues/648 --- test_conformance/spir/half.zip | Bin 1270377 -> 1257839 bytes test_conformance/spir/main.cpp | 1286 +++++++++++----------- test_conformance/spir/run_build_test.cpp | 279 ++--- 3 files changed, 803 insertions(+), 762 deletions(-) mode change 100644 => 100755 test_conformance/spir/half.zip diff --git a/test_conformance/spir/half.zip b/test_conformance/spir/half.zip old mode 100644 new mode 100755 index 0b1deca1f18179bfd38378a156b5ba5bce5add0c..2f3f9bbd3a264e10f1291f247e800d605e7461d7 GIT binary patch delta 60336 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 delta 71298 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 0 && c < 256) ss.put(c); + if (c > 0 && c < 256) ss.put(c); return c; } @@ -77,12 +76,11 @@ private: } }; -class custom_cerr : public std::streambuf -{ +class custom_cerr : public std::streambuf { private: std::stringstream ss; - std::streamsize xsputn (const char* s, std::streamsize n) + std::streamsize xsputn(const char *s, std::streamsize n) { ss.write(s, n); return n; @@ -90,7 +88,7 @@ private: int overflow(int c) { - if(c > 0 && c < 256) ss.put(c); + if (c > 0 && c < 256) ss.put(c); return c; } @@ -102,29 +100,25 @@ private: } }; -class override_buff -{ - std::ostream* stream; - std::streambuf* buff; +class override_buff { + std::ostream *stream; + std::streambuf *buff; public: - override_buff(std::ostream& s, std::streambuf& b) + override_buff(std::ostream &s, std::streambuf &b) { stream = &s; buff = stream->rdbuf(); stream->rdbuf(&b); } - ~override_buff() - { - stream->rdbuf(buff); - } + ~override_buff() { stream->rdbuf(buff); } }; -typedef bool (*testfn)(cl_device_id device, cl_uint size_t_width, const char *folder); +typedef bool (*testfn)(cl_device_id device, cl_uint size_t_width, + const char *folder); -template -void dealloc(T *p) +template void dealloc(T *p) { if (p) delete p; } @@ -132,15 +126,15 @@ void dealloc(T *p) static void get_spir_version(cl_device_id device, std::vector &versions) { - char version[64] = {0}; + char version[64] = { 0 }; cl_int err; size_t size = 0; if ((err = clGetDeviceInfo(device, CL_DEVICE_SPIR_VERSIONS, sizeof(version), (void *)version, &size))) { - log_error( "Error: failed to obtain SPIR version at %s:%d (err = %d)\n", - __FILE__, __LINE__, err ); + log_error("Error: failed to obtain SPIR version at %s:%d (err = %d)\n", + __FILE__, __LINE__, err); return; } @@ -160,126 +154,133 @@ static void get_spir_version(cl_device_id device, } } -struct CounterEventHandler: EventHandler{ - unsigned int& Counter; +struct CounterEventHandler : EventHandler +{ + unsigned int &Counter; unsigned int TN; std::string LastTest; - //N - counter of successful tests. - //T - total number of tests in the suite - CounterEventHandler(unsigned int& N, unsigned int T): Counter(N), TN(T){} + // N - counter of successful tests. + // T - total number of tests in the suite + CounterEventHandler(unsigned int &N, unsigned int T): Counter(N), TN(T) {} - void operator ()(const std::string& testName, const std::string& kernelName) { - if (testName != LastTest){ + void operator()(const std::string &testName, const std::string &kernelName) + { + if (testName != LastTest) + { ++Counter; LastTest = testName; } } }; -class AccumulatorEventHandler: public EventHandler{ - std::list& m_list; - const std::string m_name; -public: - AccumulatorEventHandler(std::list& L, const std::string N): - m_list(L), m_name(N){} +class AccumulatorEventHandler : public EventHandler { + std::list &m_list; + const std::string m_name; - void operator ()(const std::string& T, const std::string& K){ - std::cerr << "\nTest " << T << "\t Kernel " << K << " failed" << std::endl; - m_list.push_back(m_name + "\t" + T + "\t" + K); - } +public: + AccumulatorEventHandler(std::list &L, const std::string N) + : m_list(L), m_name(N) + {} + + void operator()(const std::string &T, const std::string &K) + { + std::cerr << "\nTest " << T << "\t Kernel " << K << " failed" + << std::endl; + m_list.push_back(m_name + "\t" + T + "\t" + K); + } }; -static void printError(const std::string& S){ - std::cerr << S << std::endl; -} +static void printError(const std::string &S) { std::cerr << S << std::endl; } // Extracts suite with the given name, and saves it to disk. static void extract_suite(const char *suiteName) { - mz_zip_archive zip_archive; + mz_zip_archive zip_archive; - // Composing the name of the archive. - char* dir = get_exe_dir(); - std::string archiveName(dir); - archiveName.append(dir_sep()); - archiveName.append(suiteName); - archiveName.append(".zip"); - free(dir); + // Composing the name of the archive. + char *dir = get_exe_dir(); + std::string archiveName(dir); + archiveName.append(dir_sep()); + archiveName.append(suiteName); + archiveName.append(".zip"); + free(dir); #if defined(_WIN32) - _mkdir(suiteName); + _mkdir(suiteName); #else - mkdir(suiteName, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + mkdir(suiteName, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); #endif - memset(&zip_archive, 0, sizeof(zip_archive)); - if (!mz_zip_reader_init_file(&zip_archive, archiveName.c_str(), 0)) - throw Exceptions::ArchiveError(MZ_DATA_ERROR); + memset(&zip_archive, 0, sizeof(zip_archive)); + if (!mz_zip_reader_init_file(&zip_archive, archiveName.c_str(), 0)) + throw Exceptions::ArchiveError(MZ_DATA_ERROR); - // Get and print information about each file in the archive. - for (size_t i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) - { - mz_zip_archive_file_stat fileStat; - size_t fileSize = 0; + // Get and print information about each file in the archive. + for (size_t i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++) + { + mz_zip_archive_file_stat fileStat; + size_t fileSize = 0; - if (!mz_zip_reader_file_stat(&zip_archive, i, &fileStat)) - { - mz_zip_reader_end(&zip_archive); - throw Exceptions::ArchiveError(MZ_DATA_ERROR); - } - const std::string fileName = fileStat.m_filename; + if (!mz_zip_reader_file_stat(&zip_archive, i, &fileStat)) + { + mz_zip_reader_end(&zip_archive); + throw Exceptions::ArchiveError(MZ_DATA_ERROR); + } + const std::string fileName = fileStat.m_filename; - // If the file is a directory, skip it. We create suite folder at the beggining. - if (mz_zip_reader_is_file_a_directory(&zip_archive, fileStat.m_file_index)) - { - continue; - } + // If the file is a directory, skip it. We create suite folder at the + // beggining. + if (mz_zip_reader_is_file_a_directory(&zip_archive, + fileStat.m_file_index)) + { + continue; + } - // Extracting the file. - void *p = mz_zip_reader_extract_file_to_heap(&zip_archive, - fileName.c_str(), - &fileSize, 0); - if (!p) - { - mz_zip_reader_end(&zip_archive); - throw std::runtime_error("mz_zip_reader_extract_file_to_heap() failed!\n"); - } + // Extracting the file. + void *p = mz_zip_reader_extract_file_to_heap( + &zip_archive, fileName.c_str(), &fileSize, 0); + if (!p) + { + mz_zip_reader_end(&zip_archive); + throw std::runtime_error( + "mz_zip_reader_extract_file_to_heap() failed!\n"); + } - // Writing the file back to the disk - std::fstream file(fileName.c_str(), - std::ios_base::trunc | std::ios_base::in | - std::ios_base::out | std::ios_base::binary); - if (!file.is_open()) - { - std::string msg = "Failed to open "; - msg.append(fileName); - throw Exceptions::TestError(msg); - } + // Writing the file back to the disk + std::fstream file(fileName.c_str(), + std::ios_base::trunc | std::ios_base::in + | std::ios_base::out | std::ios_base::binary); + if (!file.is_open()) + { + std::string msg = "Failed to open "; + msg.append(fileName); + throw Exceptions::TestError(msg); + } - file.write((const char*)p, fileSize); - if (file.bad()) - { - std::string msg("Failed to write into "); - msg.append(fileName); - throw Exceptions::TestError(msg); - } + file.write((const char *)p, fileSize); + if (file.bad()) + { + std::string msg("Failed to write into "); + msg.append(fileName); + throw Exceptions::TestError(msg); + } - // Cleanup. - file.flush(); - file.close(); - free(p); - } - mz_zip_reader_end(&zip_archive); + // Cleanup. + file.flush(); + file.close(); + free(p); + } + mz_zip_reader_end(&zip_archive); } // // Extracts the given suite package if needed. // return true if the suite was extracted, false otherwise. // -static bool try_extract(const char* suite) +static bool try_extract(const char *suite) { - if(no_unzip == 0) + if (no_unzip == 0) { std::cout << "Extracting test suite " << suite << std::endl; extract_suite(suite); @@ -297,17 +298,22 @@ bool test_suite(cl_device_id device, cl_uint size_t_width, const char *folder, std::cout << "Running tests:" << std::endl; - OclExtensions deviceCapabilities = OclExtensions::getDeviceCapabilities(device); + OclExtensions deviceCapabilities = + OclExtensions::getDeviceCapabilities(device); unsigned int tests_passed = 0; CounterEventHandler SuccE(tests_passed, number_of_tests); std::list ErrList; for (unsigned int i = 0; i < number_of_tests; ++i) { AccumulatorEventHandler FailE(ErrList, test_name[i]); - if((strlen(extension) != 0) && (!is_extension_available(device, extension))) + if ((strlen(extension) != 0) + && (!is_extension_available(device, extension))) { (SuccE)(test_name[i], ""); - std::cout << test_name[i] << "... Skipped. (Cannot run on device due to missing extension: " << extension << " )." << std::endl; + std::cout << test_name[i] + << "... Skipped. (Cannot run on device due to missing " + "extension: " + << extension << " )." << std::endl; continue; } TestRunner testRunner(&SuccE, &FailE, deviceCapabilities); @@ -315,7 +321,9 @@ bool test_suite(cl_device_id device, cl_uint size_t_width, const char *folder, } std::cout << std::endl; - std::cout << "PASSED " << tests_passed << " of " << number_of_tests << " tests.\n" << std::endl; + std::cout << "PASSED " << tests_passed << " of " << number_of_tests + << " tests.\n" + << std::endl; if (!ErrList.empty()) { @@ -328,23 +336,21 @@ bool test_suite(cl_device_id device, cl_uint size_t_width, const char *folder, return true; } -static std::string getTestFolder(const std::string& TS) +static std::string getTestFolder(const std::string &TS) { - const std::string DOUBLE("_double"); - if (TS.size() < DOUBLE.size()) + const std::string DOUBLE("_double"); + if (TS.size() < DOUBLE.size()) return TS; + + const size_t prefixLen = TS.size() - DOUBLE.size(); + const std::string postfix = TS.substr(prefixLen, DOUBLE.size()); + if (DOUBLE == postfix) return TS.substr(0, prefixLen); + return TS; - - const size_t prefixLen = TS.size() - DOUBLE.size(); - const std::string postfix = TS.substr(prefixLen, DOUBLE.size()); - if (DOUBLE == postfix) - return TS.substr(0, prefixLen); - - return TS; } -bool test_api (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_api(cl_device_id device, cl_uint size_t_width, const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "const_derived_d", "const_scalar_d", "const_vector16_d", @@ -668,41 +674,32 @@ bool test_api (cl_device_id device, cl_uint size_t_width, const char *folder) }; log_info("test_api\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_api_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_api_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { - "double_scalar_p", - "double_scalar_p2", - "double_scalar_d", - "double_vector2_p", - "double_vector2_p2", - "double_vector2_d", - "double_vector3_p", - "double_vector3_p2", - "double_vector3_d", - "double_vector4_p", - "double_vector4_p2", - "double_vector4_d", - "double_vector8_p", - "double_vector8_p2", - "double_vector8_d", - "double_vector16_p", - "double_vector16_p2", - "double_vector16_d", + static const char *test_name[] = { + "double_scalar_p", "double_scalar_p2", "double_scalar_d", + "double_vector2_p", "double_vector2_p2", "double_vector2_d", + "double_vector3_p", "double_vector3_p2", "double_vector3_d", + "double_vector4_p", "double_vector4_p2", "double_vector4_d", + "double_vector8_p", "double_vector8_p2", "double_vector8_d", + "double_vector16_p", "double_vector16_p2", "double_vector16_d", }; log_info("test_api_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_atomics (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_atomics(cl_device_id device, cl_uint size_t_width, const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test_atomic_fn.atomic_add_global_int", "test_atomic_fn.atomic_add_global_uint", "test_atomic_fn.atomic_sub_global_int", @@ -752,13 +749,14 @@ bool test_atomics (cl_device_id device, cl_uint size_t_width, const char *folder }; log_info("test_atomics\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_basic (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_basic(cl_device_id device, cl_uint size_t_width, const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_kernel.work_item_functions", "test_sizeof.sizeof_char", "test_sizeof.sizeof_uchar", @@ -1424,12 +1422,14 @@ bool test_basic (cl_device_id device, cl_uint size_t_width, const char *folder) }; log_info("test_basic\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_basic_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_basic_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_test.vec_type_hint_double", "sample_test.vec_type_hint_double2", "sample_test.vec_type_hint_double4", @@ -1494,13 +1494,15 @@ bool test_basic_double (cl_device_id device, cl_uint size_t_width, const char *f }; log_info("test_basic_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_commonfns (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_commonfns(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test_clamp.test_clamp_float", "test_clamp.test_clamp_float2", "test_clamp.test_clamp_float4", @@ -1565,13 +1567,15 @@ bool test_commonfns (cl_device_id device, cl_uint size_t_width, const char *fold }; log_info("test_commonfns\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_commonfns_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_commonfns_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test_clamp.test_clamp_double", "test_clamp.test_clamp_double2", "test_clamp.test_clamp_double4", @@ -1617,12 +1621,14 @@ bool test_commonfns_double (cl_device_id device, cl_uint size_t_width, const cha }; log_info("test_commonfns_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_conversions (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_conversions(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "convert2_type_roundingmode_type_f", "convert3_type_roundingmode_type_f", "convert4_type_roundingmode_type_f", @@ -2482,13 +2488,15 @@ bool test_conversions (cl_device_id device, cl_uint size_t_width, const char *fo }; log_info("test_conversions\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_conversions_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_conversions_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "convert2_type_roundingmode_type_d", "convert3_type_roundingmode_type_d", "convert4_type_roundingmode_type_d", @@ -2651,13 +2659,15 @@ bool test_conversions_double (cl_device_id device, cl_uint size_t_width, const c }; log_info("test_conversions_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_geometrics (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_geometrics(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_test.geom_cross_float3", "sample_test.geom_cross_float4", "sample_test.geom_dot_float", @@ -2691,13 +2701,15 @@ bool test_geometrics (cl_device_id device, cl_uint size_t_width, const char *fol }; log_info("test_geometrics\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_geometrics_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_geometrics_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_test.geom_cross_double3", "sample_test.geom_cross_double4", "sample_test.geom_dot_double", @@ -2719,13 +2731,14 @@ bool test_geometrics_double (cl_device_id device, cl_uint size_t_width, const ch }; log_info("test_geometrics_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_half (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_half(cl_device_id device, cl_uint size_t_width, const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test.vload_half_global", "test.vload_half_private", "test.vload_half_local", @@ -2750,10 +2763,6 @@ bool test_half (cl_device_id device, cl_uint size_t_width, const char *folder) "test.vload_half3_private", "test.vload_half3_local", "test.vload_half3_constant", - "test.vloada_half_global", - "test.vloada_half_private", - "test.vloada_half_local", - "test.vloada_half_constant", "test.vloada_half2_global", "test.vloada_half2_private", "test.vloada_half2_local", @@ -2942,13 +2951,15 @@ bool test_half (cl_device_id device, cl_uint size_t_width, const char *folder) }; log_info("test_half\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_half_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_half_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test.vstore_half_global_double", "test.vstore_half_private_double", "test.vstore_half_local_double", @@ -3117,13 +3128,15 @@ bool test_half_double (cl_device_id device, cl_uint size_t_width, const char *fo }; log_info("test_half_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_kernel_image_methods (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_kernel_image_methods(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_kernel.get_image_info_1D", "sample_kernel.get_image_info_2D", "sample_kernel.get_image_info_3D", @@ -3132,13 +3145,15 @@ bool test_kernel_image_methods (cl_device_id device, cl_uint size_t_width, const }; log_info("test_kernel_image_methods\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_images_kernel_read_write (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_images_kernel_read_write(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_kernel.read_image_set_1D_fint", "sample_kernel.read_image_set_1D_ffloat", "sample_kernel.read_image_set_1D_iint", @@ -3184,13 +3199,15 @@ bool test_images_kernel_read_write (cl_device_id device, cl_uint size_t_width, c }; log_info("test_images_kernel_read_write\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_images_samplerless_read (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_images_samplerless_read(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_kernel.read_image_set_1D_float", "sample_kernel.read_image_set_1D_int", "sample_kernel.read_image_set_1D_uint", @@ -3212,13 +3229,15 @@ bool test_images_samplerless_read (cl_device_id device, cl_uint size_t_width, co }; log_info("test_images_samplerless_read\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_integer_ops (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_integer_ops(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_test.integer_clz_char", "sample_test.integer_clz_char2", "sample_test.integer_clz_char3", @@ -4002,13 +4021,15 @@ bool test_integer_ops (cl_device_id device, cl_uint size_t_width, const char *fo }; log_info("test_integer_ops\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_math_brute_force (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_math_brute_force(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "math_kernel.acos_float", "math_kernel3.acos_float3", "math_kernel16.acos_float16", @@ -4583,13 +4604,15 @@ bool test_math_brute_force (cl_device_id device, cl_uint size_t_width, const cha }; log_info("test_math_brute_force\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_math_brute_force_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_math_brute_force_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "math_kernel8.acos_double8", "math_kernel4.acos_double4", "math_kernel16.acos_double16", @@ -4638,7 +4661,7 @@ bool test_math_brute_force_double (cl_device_id device, cl_uint size_t_width, co "math_kernel3.atanh_double3", "math_kernel2.atanh_double2", "math_kernel.atanh_double", - "math_kernel8.atanpi_double8", + "math_kernel8.atanpi_double8", "math_kernel16.atanpi_double16", "math_kernel3.atanpi_double3", "math_kernel4.atanpi_double4", @@ -5067,13 +5090,14 @@ bool test_math_brute_force_double (cl_device_id device, cl_uint size_t_width, co }; log_info("test_math_brute_force_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_printf (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_printf(cl_device_id device, cl_uint size_t_width, const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test0.testCaseInt", "test1.testCaseFloat", "test5.testCaseChar", @@ -5089,25 +5113,29 @@ bool test_printf (cl_device_id device, cl_uint size_t_width, const char *folder) }; log_info("test_printf\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_profiling (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_profiling(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "testReadf", "image_filter", }; log_info("test_profiling\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_relationals (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_relationals(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_test.relational_any_char", "sample_test.relational_any_char2", "sample_test.relational_any_char3", @@ -5583,13 +5611,15 @@ bool test_relationals (cl_device_id device, cl_uint size_t_width, const char *fo }; log_info("test_relationals\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_relationals_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_relationals_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "sample_test.relational_bitselect_double", "sample_test.relational_bitselect_double2", "sample_test.relational_bitselect_double3", @@ -5673,152 +5703,97 @@ bool test_relationals_double (cl_device_id device, cl_uint size_t_width, const c }; log_info("test_relationals_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_select (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_select(cl_device_id device, cl_uint size_t_width, const char *folder) { - static const char* test_name[] = { - "select_uchar_uchar", - "select_uchar2_uchar2", - "select_uchar3_uchar3", - "select_uchar4_uchar4", - "select_uchar8_uchar8", - "select_uchar16_uchar16", - "select_uchar_char", - "select_uchar2_char2", - "select_uchar3_char3", - "select_uchar4_char4", - "select_uchar8_char8", - "select_uchar16_char16", - "select_char_uchar", - "select_char2_uchar2", - "select_char3_uchar3", - "select_char4_uchar4", - "select_char8_uchar8", - "select_char16_uchar16", - "select_char_char", - "select_char2_char2", - "select_char3_char3", - "select_char4_char4", - "select_char8_char8", - "select_char16_char16", - "select_ushort_ushort", - "select_ushort2_ushort2", - "select_ushort3_ushort3", - "select_ushort4_ushort4", - "select_ushort8_ushort8", - "select_ushort16_ushort16", - "select_ushort_short", - "select_ushort2_short2", - "select_ushort3_short3", - "select_ushort4_short4", - "select_ushort8_short8", - "select_ushort16_short16", - "select_short_ushort", - "select_short2_ushort2", - "select_short3_ushort3", - "select_short4_ushort4", - "select_short8_ushort8", - "select_short16_ushort16", - "select_short_short", - "select_short2_short2", - "select_short3_short3", - "select_short4_short4", - "select_short8_short8", - "select_short16_short16", - "select_uint_uint", - "select_uint2_uint2", - "select_uint3_uint3", - "select_uint4_uint4", - "select_uint8_uint8", - "select_uint16_uint16", - "select_uint_int", - "select_uint2_int2", - "select_uint3_int3", - "select_uint4_int4", - "select_uint8_int8", - "select_uint16_int16", - "select_int_uint", - "select_int2_uint2", - "select_int3_uint3", - "select_int4_uint4", - "select_int8_uint8", - "select_int16_uint16", - "select_int_int", - "select_int2_int2", - "select_int3_int3", - "select_int4_int4", - "select_int8_int8", - "select_int16_int16", - "select_float_uint", - "select_float2_uint2", - "select_float3_uint3", - "select_float4_uint4", - "select_float8_uint8", - "select_float16_uint16", - "select_float_int", - "select_float2_int2", - "select_float3_int3", - "select_float4_int4", - "select_float8_int8", - "select_float16_int16", - "select_ulong_ulong", - "select_ulong2_ulong2", - "select_ulong3_ulong3", - "select_ulong4_ulong4", - "select_ulong8_ulong8", - "select_ulong16_ulong16", - "select_ulong_long", - "select_ulong2_long2", - "select_ulong3_long3", - "select_ulong4_long4", - "select_ulong8_long8", - "select_ulong16_long16", - "select_long_ulong", - "select_long2_ulong2", - "select_long3_ulong3", - "select_long4_ulong4", - "select_long8_ulong8", - "select_long16_ulong16", - "select_long_long", - "select_long2_long2", - "select_long3_long3", - "select_long4_long4", - "select_long8_long8", - "select_long16_long16", + static const char *test_name[] = { + "select_uchar_uchar", "select_uchar2_uchar2", + "select_uchar3_uchar3", "select_uchar4_uchar4", + "select_uchar8_uchar8", "select_uchar16_uchar16", + "select_uchar_char", "select_uchar2_char2", + "select_uchar3_char3", "select_uchar4_char4", + "select_uchar8_char8", "select_uchar16_char16", + "select_char_uchar", "select_char2_uchar2", + "select_char3_uchar3", "select_char4_uchar4", + "select_char8_uchar8", "select_char16_uchar16", + "select_char_char", "select_char2_char2", + "select_char3_char3", "select_char4_char4", + "select_char8_char8", "select_char16_char16", + "select_ushort_ushort", "select_ushort2_ushort2", + "select_ushort3_ushort3", "select_ushort4_ushort4", + "select_ushort8_ushort8", "select_ushort16_ushort16", + "select_ushort_short", "select_ushort2_short2", + "select_ushort3_short3", "select_ushort4_short4", + "select_ushort8_short8", "select_ushort16_short16", + "select_short_ushort", "select_short2_ushort2", + "select_short3_ushort3", "select_short4_ushort4", + "select_short8_ushort8", "select_short16_ushort16", + "select_short_short", "select_short2_short2", + "select_short3_short3", "select_short4_short4", + "select_short8_short8", "select_short16_short16", + "select_uint_uint", "select_uint2_uint2", + "select_uint3_uint3", "select_uint4_uint4", + "select_uint8_uint8", "select_uint16_uint16", + "select_uint_int", "select_uint2_int2", + "select_uint3_int3", "select_uint4_int4", + "select_uint8_int8", "select_uint16_int16", + "select_int_uint", "select_int2_uint2", + "select_int3_uint3", "select_int4_uint4", + "select_int8_uint8", "select_int16_uint16", + "select_int_int", "select_int2_int2", + "select_int3_int3", "select_int4_int4", + "select_int8_int8", "select_int16_int16", + "select_float_uint", "select_float2_uint2", + "select_float3_uint3", "select_float4_uint4", + "select_float8_uint8", "select_float16_uint16", + "select_float_int", "select_float2_int2", + "select_float3_int3", "select_float4_int4", + "select_float8_int8", "select_float16_int16", + "select_ulong_ulong", "select_ulong2_ulong2", + "select_ulong3_ulong3", "select_ulong4_ulong4", + "select_ulong8_ulong8", "select_ulong16_ulong16", + "select_ulong_long", "select_ulong2_long2", + "select_ulong3_long3", "select_ulong4_long4", + "select_ulong8_long8", "select_ulong16_long16", + "select_long_ulong", "select_long2_ulong2", + "select_long3_ulong3", "select_long4_ulong4", + "select_long8_ulong8", "select_long16_ulong16", + "select_long_long", "select_long2_long2", + "select_long3_long3", "select_long4_long4", + "select_long8_long8", "select_long16_long16", }; log_info("test_select\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_select_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_select_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { - "select_double_ulong", - "select_double2_ulong2", - "select_double3_ulong3", - "select_double4_ulong4", - "select_double8_ulong8", - "select_double16_ulong16", - "select_double_long", - "select_double2_long2", - "select_double3_long3", - "select_double4_long4", - "select_double8_long8", - "select_double16_long16", + static const char *test_name[] = { + "select_double_ulong", "select_double2_ulong2", + "select_double3_ulong3", "select_double4_ulong4", + "select_double8_ulong8", "select_double16_ulong16", + "select_double_long", "select_double2_long2", + "select_double3_long3", "select_double4_long4", + "select_double8_long8", "select_double16_long16", }; log_info("test_select_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_vec_align (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_vec_align(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test_vec_align_packed_struct_arr.vec_align_packed_struct_arr_char2", "test_vec_align_packed_struct_arr.vec_align_packed_struct_arr_char3", "test_vec_align_packed_struct_arr.vec_align_packed_struct_arr_char4", @@ -5877,13 +5852,15 @@ bool test_vec_align (cl_device_id device, cl_uint size_t_width, const char *fold }; log_info("vec_align\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_vec_align_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_vec_align_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { + static const char *test_name[] = { "test_vec_align_packed_struct_arr.vec_align_packed_struct_arr_double2", "test_vec_align_packed_struct_arr.vec_align_packed_struct_arr_double3", "test_vec_align_packed_struct_arr.vec_align_packed_struct_arr_double4", @@ -5893,130 +5870,104 @@ bool test_vec_align_double (cl_device_id device, cl_uint size_t_width, const cha }; log_info("vec_align_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -bool test_vec_step (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_vec_step(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { - "test_step_var.step_var_char", - "test_step_var.step_var_char2", - "test_step_var.step_var_char3", - "test_step_var.step_var_char4", - "test_step_var.step_var_char8", - "test_step_var.step_var_char16", - "test_step_var.step_var_uchar", - "test_step_var.step_var_uchar2", - "test_step_var.step_var_uchar3", - "test_step_var.step_var_uchar4", - "test_step_var.step_var_uchar8", - "test_step_var.step_var_uchar16", - "test_step_var.step_var_short", - "test_step_var.step_var_short2", - "test_step_var.step_var_short3", - "test_step_var.step_var_short4", - "test_step_var.step_var_short8", - "test_step_var.step_var_short16", - "test_step_var.step_var_ushort", - "test_step_var.step_var_ushort2", - "test_step_var.step_var_ushort3", - "test_step_var.step_var_ushort4", - "test_step_var.step_var_ushort8", - "test_step_var.step_var_ushort16", - "test_step_var.step_var_int", - "test_step_var.step_var_int2", - "test_step_var.step_var_int3", - "test_step_var.step_var_int4", - "test_step_var.step_var_int8", - "test_step_var.step_var_int16", - "test_step_var.step_var_uint", - "test_step_var.step_var_uint2", - "test_step_var.step_var_uint3", - "test_step_var.step_var_uint4", - "test_step_var.step_var_uint8", - "test_step_var.step_var_uint16", - "test_step_var.step_var_long", - "test_step_var.step_var_long2", - "test_step_var.step_var_long3", - "test_step_var.step_var_long4", - "test_step_var.step_var_long8", - "test_step_var.step_var_long16", - "test_step_var.step_var_ulong", - "test_step_var.step_var_ulong2", - "test_step_var.step_var_ulong3", - "test_step_var.step_var_ulong4", - "test_step_var.step_var_ulong8", - "test_step_var.step_var_ulong16", - "test_step_var.step_var_float", - "test_step_var.step_var_float2", - "test_step_var.step_var_float3", - "test_step_var.step_var_float4", - "test_step_var.step_var_float8", - "test_step_var.step_var_float16", + static const char *test_name[] = { + "test_step_var.step_var_char", "test_step_var.step_var_char2", + "test_step_var.step_var_char3", "test_step_var.step_var_char4", + "test_step_var.step_var_char8", "test_step_var.step_var_char16", + "test_step_var.step_var_uchar", "test_step_var.step_var_uchar2", + "test_step_var.step_var_uchar3", "test_step_var.step_var_uchar4", + "test_step_var.step_var_uchar8", "test_step_var.step_var_uchar16", + "test_step_var.step_var_short", "test_step_var.step_var_short2", + "test_step_var.step_var_short3", "test_step_var.step_var_short4", + "test_step_var.step_var_short8", "test_step_var.step_var_short16", + "test_step_var.step_var_ushort", "test_step_var.step_var_ushort2", + "test_step_var.step_var_ushort3", "test_step_var.step_var_ushort4", + "test_step_var.step_var_ushort8", "test_step_var.step_var_ushort16", + "test_step_var.step_var_int", "test_step_var.step_var_int2", + "test_step_var.step_var_int3", "test_step_var.step_var_int4", + "test_step_var.step_var_int8", "test_step_var.step_var_int16", + "test_step_var.step_var_uint", "test_step_var.step_var_uint2", + "test_step_var.step_var_uint3", "test_step_var.step_var_uint4", + "test_step_var.step_var_uint8", "test_step_var.step_var_uint16", + "test_step_var.step_var_long", "test_step_var.step_var_long2", + "test_step_var.step_var_long3", "test_step_var.step_var_long4", + "test_step_var.step_var_long8", "test_step_var.step_var_long16", + "test_step_var.step_var_ulong", "test_step_var.step_var_ulong2", + "test_step_var.step_var_ulong3", "test_step_var.step_var_ulong4", + "test_step_var.step_var_ulong8", "test_step_var.step_var_ulong16", + "test_step_var.step_var_float", "test_step_var.step_var_float2", + "test_step_var.step_var_float3", "test_step_var.step_var_float4", + "test_step_var.step_var_float8", "test_step_var.step_var_float16", }; log_info("vec_step\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -bool test_vec_step_double (cl_device_id device, cl_uint size_t_width, const char *folder) +bool test_vec_step_double(cl_device_id device, cl_uint size_t_width, + const char *folder) { - static const char* test_name[] = { - "test_step_var.step_var_double", - "test_step_var.step_var_double2", - "test_step_var.step_var_double3", - "test_step_var.step_var_double4", - "test_step_var.step_var_double8", - "test_step_var.step_var_double16", + static const char *test_name[] = { + "test_step_var.step_var_double", "test_step_var.step_var_double2", + "test_step_var.step_var_double3", "test_step_var.step_var_double4", + "test_step_var.step_var_double8", "test_step_var.step_var_double16", }; log_info("vec_step_double\n"); - return test_suite(device, size_t_width, folder, test_name, sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); + return test_suite(device, size_t_width, folder, test_name, + sizeof(test_name) / sizeof(const char *), "cl_khr_fp64"); } -template -void getT(const TestResult& res, unsigned arg, T& out) +template void getT(const TestResult &res, unsigned arg, T &out) { - out = *(T*)(res.kernelArgs().getArg(arg)->getBuffer()); + out = *(T *)(res.kernelArgs().getArg(arg)->getBuffer()); } class LinkageTestService { - std::vector m_moduleNames; - const char* m_kernelName; + std::vector m_moduleNames; + const char *m_kernelName; int m_expectedResult; const char *m_name; public: LinkageTestService(const char **moduleNames, int numModules, - const char *kernelName) : - m_moduleNames(numModules), - m_kernelName(kernelName), - m_expectedResult(-1), - m_name(NULL) { - std::copy(moduleNames, moduleNames+numModules, m_moduleNames.begin()); + const char *kernelName) + : m_moduleNames(numModules), m_kernelName(kernelName), + m_expectedResult(-1), m_name(NULL) + { + std::copy(moduleNames, moduleNames + numModules, m_moduleNames.begin()); } - void setExpectedResult(int expectedRes) { - m_expectedResult = expectedRes; - } + void setExpectedResult(int expectedRes) { m_expectedResult = expectedRes; } - bool compareResult(cl_device_id dev, cl_uint width) { + bool compareResult(cl_device_id dev, cl_uint width) + { clContextWrapper context; clCommandQueueWrapper queue; size_t num_modules = m_moduleNames.size(); std::vector programs(num_modules); create_context_and_queue(dev, &context, &queue); - for (size_t i=0; i linkageTests; + std::vector linkageTests; linkageTests.push_back(new LinkageTestService(private_files, 2, "k")); - linkageTests.push_back(new LinkageTestService(internal_files, 2, "internal_linkage")); - linkageTests.push_back(new LinkageTestService(external_files, 2, "external_linkage")); - linkageTests.push_back(new LinkageTestService(available_externally_files, 2, "k")); + linkageTests.push_back( + new LinkageTestService(internal_files, 2, "internal_linkage")); + linkageTests.push_back( + new LinkageTestService(external_files, 2, "external_linkage")); + linkageTests.push_back( + new LinkageTestService(available_externally_files, 2, "k")); // Set tests Names. linkageTests[0]->setName("private_linkage"); linkageTests[1]->setName("internal_linkage"); @@ -6081,11 +6033,11 @@ bool test_compile_and_link (cl_device_id device, cl_uint width, const char *fold CounterEventHandler SuccE(tests_passed, linkageTests.size()); std::list ErrList; - for (size_t i=0; igetName()); std::cout << linkageTests[i]->getName() << "..." << std::endl; - if(linkageTests[i]->compareResult(device, width)) + if (linkageTests[i]->compareResult(device, width)) { (SuccE)(linkageTests[i]->getName(), ""); std::cout << linkageTests[i]->getName() << " passed." << std::endl; @@ -6099,54 +6051,52 @@ bool test_compile_and_link (cl_device_id device, cl_uint width, const char *fold } std::cout << std::endl; - std::cout << "PASSED " << tests_passed << " of " << SuccE.TN << " tests.\n" << std::endl; + std::cout << "PASSED " << tests_passed << " of " << SuccE.TN << " tests.\n" + << std::endl; // Deallocating. - std::for_each(linkageTests.begin(), linkageTests.end(), dealloc); + std::for_each(linkageTests.begin(), linkageTests.end(), + dealloc); return tests_passed == SuccE.TN; } -static bool test_sampler_enumeration(cl_device_id device, cl_uint width, const char *folder) +static bool test_sampler_enumeration(cl_device_id device, cl_uint width, + const char *folder) { - static const char* test_name[] = { - "sampler_NormF_AddrC_FilterL", - "sampler_NormF_AddrC_FilterN", - "sampler_NormF_AddrE_FilterL", - "sampler_NormF_AddrE_FilterN", - // "sampler_NormF_AddrM_FilterL" - Invalid combination - // "sampler_NormF_AddrM_FilterN" - Invalid combination - "sampler_NormF_AddrN_FilterL", - "sampler_NormF_AddrN_FilterN", - // "sampler_NormF_AddrR_FilterL" - Invalid combination - // "sampler_NormF_AddrR_FilterN" - Invalid combination - "sampler_NormT_AddrC_FilterL", - "sampler_NormT_AddrC_FilterN", - "sampler_NormT_AddrE_FilterL", - "sampler_NormT_AddrE_FilterN", - "sampler_NormT_AddrM_FilterL", - "sampler_NormT_AddrM_FilterN", - "sampler_NormT_AddrN_FilterL", - "sampler_NormT_AddrN_FilterN", - "sampler_NormT_AddrR_FilterL", - "sampler_NormT_AddrR_FilterN" - }; + static const char *test_name[] = { + "sampler_NormF_AddrC_FilterL", "sampler_NormF_AddrC_FilterN", + "sampler_NormF_AddrE_FilterL", "sampler_NormF_AddrE_FilterN", + // "sampler_NormF_AddrM_FilterL" - Invalid combination + // "sampler_NormF_AddrM_FilterN" - Invalid combination + "sampler_NormF_AddrN_FilterL", "sampler_NormF_AddrN_FilterN", + // "sampler_NormF_AddrR_FilterL" - Invalid combination + // "sampler_NormF_AddrR_FilterN" - Invalid combination + "sampler_NormT_AddrC_FilterL", "sampler_NormT_AddrC_FilterN", + "sampler_NormT_AddrE_FilterL", "sampler_NormT_AddrE_FilterN", + "sampler_NormT_AddrM_FilterL", "sampler_NormT_AddrM_FilterN", + "sampler_NormT_AddrN_FilterL", "sampler_NormT_AddrN_FilterN", + "sampler_NormT_AddrR_FilterL", "sampler_NormT_AddrR_FilterN" + }; - log_info("test_sampler_enum_values\n"); - return test_suite(device, width, folder, test_name, sizeof(test_name) / sizeof(const char *), ""); + log_info("test_sampler_enum_values\n"); + return test_suite(device, width, folder, test_name, + sizeof(test_name) / sizeof(const char *), ""); } -const char* HOSTVAL_SAMPLER = "hostval_sampler"; -const char* HOSTVAL_IMAGE_DESC = "hostval_image_desc"; -const char* HOSTVAL_IMAGE_DESC_3D = "hostval_image_desc_3d"; +const char *HOSTVAL_SAMPLER = "hostval_sampler"; +const char *HOSTVAL_IMAGE_DESC = "hostval_image_desc"; +const char *HOSTVAL_IMAGE_DESC_3D = "hostval_image_desc_3d"; static bool test_image_enumeration(cl_context context, cl_command_queue queue, cl_program prog, cl_device_id device, - CounterEventHandler &SuccE, std::list &ErrList) + CounterEventHandler &SuccE, + std::list &ErrList) { // Creating image descriptor value generator. ImageValuesGenerator imgVals; bool success = true; - for(ImageValuesGenerator::iterator it = imgVals.begin(), e = imgVals.end(); it != e; ++it) + for (ImageValuesGenerator::iterator it = imgVals.begin(), e = imgVals.end(); + it != e; ++it) { bool currentSuccess = true; AccumulatorEventHandler FailE(ErrList, it.toString()); @@ -6166,7 +6116,7 @@ static bool test_image_enumeration(cl_context context, cl_command_queue queue, KernelArgInfo baseInfo; baseInfo.setTypeName(baseGenName.c_str()); DataGenerator *pDataGen = DataGenerator::getInstance(); - KernelArgGenerator* pOrig = pDataGen->getArgGenerator(baseInfo); + KernelArgGenerator *pOrig = pDataGen->getArgGenerator(baseInfo); try { @@ -6174,23 +6124,26 @@ static bool test_image_enumeration(cl_context context, cl_command_queue queue, WorkSizeInfo ws; clKernelWrapper kernel = create_kernel_helper(prog, kernelName); - // Acquiring a reference to the image generator we need for this image - // type. + // Acquiring a reference to the image generator we need for this + // image type. KernelArgInfo typedInfo; const std::string tyName = it.getImageGeneratorName(); typedInfo.setTypeName(tyName.c_str()); - KernelArgGeneratorImage* pImgGen = (KernelArgGeneratorImage*)pDataGen->getArgGenerator(typedInfo); + KernelArgGeneratorImage *pImgGen = + (KernelArgGeneratorImage *)pDataGen->getArgGenerator(typedInfo); // If the channel order is not valid for the current image type, we // continue to the next one. - if (!pImgGen->isValidChannelOrder(context, it.getOpenCLChannelOrder())) + if (!pImgGen->isValidChannelOrder(context, + it.getOpenCLChannelOrder())) continue; - // Due to unknown number of types at the beggining count them on the fly + // Due to unknown number of types at the beggining count them on the + // fly SuccE.TN++; - // Configuring the image generator so it will produce the correct image - // descriptor. + // Configuring the image generator so it will produce the correct + // image descriptor. pImgGen->setChannelOrder(it.getOpenCLChannelOrder()); pDataGen->setArgGenerator(baseInfo, pImgGen); @@ -6205,8 +6158,9 @@ static bool test_image_enumeration(cl_context context, cl_command_queue queue, getT(res, 1U, actualOrder), getT(res, 2U, actualTy); if (actualOrder != it.getSPIRChannelOrder()) { - std::cout << " expected channel order: " << it.getSPIRChannelOrder() - << " but received " << actualOrder << "." << std::endl; + std::cout << " expected channel order: " + << it.getSPIRChannelOrder() << " but received " + << actualOrder << "." << std::endl; success = currentSuccess = false; } @@ -6220,7 +6174,8 @@ static bool test_image_enumeration(cl_context context, cl_command_queue queue, if (currentSuccess) { (SuccE)(it.toString(), kernelName); - std::cout << "enum_" << it.toString() << " passed." << std::endl; + std::cout << "enum_" << it.toString() << " passed." + << std::endl; } else { @@ -6241,15 +6196,18 @@ static bool test_image_enumeration(cl_context context, cl_command_queue queue, return success; } -static bool test_image_enumeration_3d(cl_context context, cl_command_queue queue, - cl_program prog, cl_device_id device, - CounterEventHandler &SuccE, std::list &ErrList) +static bool test_image_enumeration_3d(cl_context context, + cl_command_queue queue, cl_program prog, + cl_device_id device, + CounterEventHandler &SuccE, + std::list &ErrList) { // Creating image descriptor value generator. ImageValuesGenerator imgVals; bool success = true; - for(ImageValuesGenerator::iterator it = imgVals.begin(), e = imgVals.end(); it != e; ++it) + for (ImageValuesGenerator::iterator it = imgVals.begin(), e = imgVals.end(); + it != e; ++it) { bool currentSuccess = true; AccumulatorEventHandler FailE(ErrList, it.toString()); @@ -6269,7 +6227,7 @@ static bool test_image_enumeration_3d(cl_context context, cl_command_queue queue KernelArgInfo baseInfo; baseInfo.setTypeName(baseGenName.c_str()); DataGenerator *pDataGen = DataGenerator::getInstance(); - KernelArgGenerator* pOrig = pDataGen->getArgGenerator(baseInfo); + KernelArgGenerator *pOrig = pDataGen->getArgGenerator(baseInfo); try { @@ -6277,23 +6235,26 @@ static bool test_image_enumeration_3d(cl_context context, cl_command_queue queue WorkSizeInfo ws; clKernelWrapper kernel = create_kernel_helper(prog, kernelName); - // Acquiring a reference to the image generator we need for this image - // type. + // Acquiring a reference to the image generator we need for this + // image type. KernelArgInfo typedInfo; const std::string tyName = it.getImageGeneratorName(); typedInfo.setTypeName(tyName.c_str()); - KernelArgGeneratorImage* pImgGen = (KernelArgGeneratorImage*)pDataGen->getArgGenerator(typedInfo); + KernelArgGeneratorImage *pImgGen = + (KernelArgGeneratorImage *)pDataGen->getArgGenerator(typedInfo); // If the channel order is not valid for the current image type, we // continue to the next one. - if (!pImgGen->isValidChannelOrder(context, it.getOpenCLChannelOrder())) + if (!pImgGen->isValidChannelOrder(context, + it.getOpenCLChannelOrder())) continue; - // Due to unknown number of types at the beggining count them on the fly + // Due to unknown number of types at the beggining count them on the + // fly SuccE.TN++; - // Configuring the image generator so it will produce the correct image - // descriptor. + // Configuring the image generator so it will produce the correct + // image descriptor. pImgGen->setChannelOrder(it.getOpenCLChannelOrder()); pDataGen->setArgGenerator(baseInfo, pImgGen); @@ -6308,8 +6269,9 @@ static bool test_image_enumeration_3d(cl_context context, cl_command_queue queue getT(res, 1U, actualOrder), getT(res, 2U, actualTy); if (actualOrder != it.getSPIRChannelOrder()) { - std::cout << " expected channel order: " << it.getSPIRChannelOrder() - << " but received " << actualOrder << "." << std::endl; + std::cout << " expected channel order: " + << it.getSPIRChannelOrder() << " but received " + << actualOrder << "." << std::endl; success = currentSuccess = false; } @@ -6323,7 +6285,8 @@ static bool test_image_enumeration_3d(cl_context context, cl_command_queue queue if (currentSuccess) { (SuccE)(it.toString(), kernelName); - std::cout << "enum_" << it.toString() << " passed." << std::endl; + std::cout << "enum_" << it.toString() << " passed." + << std::endl; } else { @@ -6344,44 +6307,54 @@ static bool test_image_enumeration_3d(cl_context context, cl_command_queue queue return success; } -static bool test_enum_values(cl_device_id device, cl_uint width, const char *folder) +static bool test_enum_values(cl_device_id device, cl_uint width, + const char *folder) { try_extract(folder); std::cout << "Running tests:" << std::endl; bool success = true; - typedef bool (*EnumTest)(cl_context, cl_command_queue, cl_program, cl_device_id, CounterEventHandler &SuccE, std::list &ErrList); - EnumTest test_functions[] = { test_image_enumeration, test_image_enumeration_3d }; + typedef bool (*EnumTest)(cl_context, cl_command_queue, cl_program, + cl_device_id, CounterEventHandler & SuccE, + std::list & ErrList); + EnumTest test_functions[] = { test_image_enumeration, + test_image_enumeration_3d }; const char *enum_tests[] = { HOSTVAL_IMAGE_DESC, HOSTVAL_IMAGE_DESC_3D }; - const size_t TEST_NUM = sizeof(enum_tests)/sizeof(char*); + const size_t TEST_NUM = sizeof(enum_tests) / sizeof(char *); unsigned int tests_passed = 0; CounterEventHandler SuccE(tests_passed, 0); std::list ErrList; // Composing the name of the CSV file. - char* dir = get_exe_dir(); + char *dir = get_exe_dir(); std::string csvName(dir); csvName.append(dir_sep()); csvName.append("khr.csv"); free(dir); // Figure out whether the test can run on the device. If not, we skip it. - const KhrSupport& khrDb = *KhrSupport::get(csvName); + const KhrSupport &khrDb = *KhrSupport::get(csvName); - for (size_t i=0; i &split(const std::string &s, char delim, std::vector &elems) +std::vector &split(const std::string &s, char delim, + std::vector &elems) { std::stringstream ss(s); std::string item; - while (std::getline(ss, item, delim)) { + while (std::getline(ss, item, delim)) + { elems.push_back(item); } return elems; @@ -6516,7 +6493,8 @@ test_kernel_attributes(cl_device_id device, cl_uint width, const char *folder) } #endif -static bool test_binary_type(cl_device_id device, cl_uint width, const char *folder) +static bool test_binary_type(cl_device_id device, cl_uint width, + const char *folder) { std::string bc_file_path; clContextWrapper context; @@ -6541,23 +6519,24 @@ static bool test_binary_type(cl_device_id device, cl_uint width, const char *fol create_context_and_queue(device, &context, &queue); clProgramWrapper clprog = create_program_from_bc(context, bc_file_path); - // Checking the attribute matches the requierment in Section 9.15.2 of the - // extensions SPEC. + // Checking the attribute matches the requierment in Section 9.15.2 of + // the extensions SPEC. cl_int binary_type = 0; size_t ret_size = 0; - if (cl_int err_code = clGetProgramBuildInfo(clprog, device, CL_PROGRAM_BINARY_TYPE, sizeof(cl_int), &binary_type, &ret_size)) + if (cl_int err_code = + clGetProgramBuildInfo(clprog, device, CL_PROGRAM_BINARY_TYPE, + sizeof(cl_int), &binary_type, &ret_size)) { std::cerr << "Cannot run test_binary_type suite due to the " - << "following build error: " - << err_code << std::endl; + << "following build error: " << err_code << std::endl; throw std::exception(); } assert(ret_size == sizeof(cl_int) && "Return size doesn't match."); if (binary_type != CL_PROGRAM_BINARY_TYPE_INTERMEDIATE) { - std::cerr << "binary type is " << binary_type - << " as opposed to " << CL_PROGRAM_BINARY_TYPE_INTERMEDIATE + std::cerr << "binary type is " << binary_type << " as opposed to " + << CL_PROGRAM_BINARY_TYPE_INTERMEDIATE << " which is the expected value." << std::endl; throw std::exception(); } @@ -6572,7 +6551,8 @@ static bool test_binary_type(cl_device_id device, cl_uint width, const char *fol std::cout << std::endl; - std::cout << "PASSED " << tests_passed << " of " << 1 << " tests.\n" << std::endl; + std::cout << "PASSED " << tests_passed << " of " << 1 << " tests.\n" + << std::endl; if (!ErrList.empty()) { @@ -6635,9 +6615,10 @@ static const sub_suite spir_suites[] = { /** Utility function using to find a specific sub-suite name in the SPIR tests. -Called in case the user asked for running a specific sub-suite or specific tests. +Called in case the user asked for running a specific sub-suite or specific +tests. */ -static int find_suite_name (std::string suite_name) +static int find_suite_name(std::string suite_name) { for (unsigned int i = 0; i < sizeof(spir_suites) / sizeof(sub_suite); ++i) { @@ -6653,7 +6634,9 @@ static int find_suite_name (std::string suite_name) /** Look for the first device from the first platform . */ -cl_device_id get_platform_device (cl_device_type device_type, cl_uint choosen_device_index, cl_uint choosen_platform_index) +cl_device_id get_platform_device(cl_device_type device_type, + cl_uint choosen_device_index, + cl_uint choosen_platform_index) { int error = CL_SUCCESS; cl_uint num_platforms = 0; @@ -6663,51 +6646,58 @@ cl_device_id get_platform_device (cl_device_type device_type, cl_uint choosen_de /* Get the platform */ error = clGetPlatformIDs(0, NULL, &num_platforms); - if ( error != CL_SUCCESS ) + if (error != CL_SUCCESS) { - throw std::runtime_error("clGetPlatformIDs failed: " + std::string(IGetErrorString(error))); + throw std::runtime_error("clGetPlatformIDs failed: " + + std::string(IGetErrorString(error))); } - if ( choosen_platform_index >= num_platforms ) + if (choosen_platform_index >= num_platforms) { throw std::runtime_error("platform index out of range"); } - platforms = (cl_platform_id *) malloc( num_platforms * sizeof( cl_platform_id ) ); - if ( !platforms ) + platforms = + (cl_platform_id *)malloc(num_platforms * sizeof(cl_platform_id)); + if (!platforms) { throw std::runtime_error("platform malloc failed"); } BufferOwningPtr platformsBuf(platforms); error = clGetPlatformIDs(num_platforms, platforms, NULL); - if ( error != CL_SUCCESS ) + if (error != CL_SUCCESS) { - throw std::runtime_error("clGetPlatformIDs failed: " + std::string(IGetErrorString(error))); + throw std::runtime_error("clGetPlatformIDs failed: " + + std::string(IGetErrorString(error))); } /* Get the number of requested devices */ - error = clGetDeviceIDs(platforms[choosen_platform_index], device_type, 0, NULL, &num_devices ); - if ( error != CL_SUCCESS ) + error = clGetDeviceIDs(platforms[choosen_platform_index], device_type, 0, + NULL, &num_devices); + if (error != CL_SUCCESS) { - throw std::runtime_error("clGetDeviceIDs failed: " + std::string(IGetErrorString(error))); + throw std::runtime_error("clGetDeviceIDs failed: " + + std::string(IGetErrorString(error))); } - if ( choosen_device_index >= num_devices ) + if (choosen_device_index >= num_devices) { throw std::runtime_error("device index out of rangen"); } - devices = (cl_device_id *) malloc( num_devices * sizeof( cl_device_id ) ); - if ( !devices ) + devices = (cl_device_id *)malloc(num_devices * sizeof(cl_device_id)); + if (!devices) { throw std::runtime_error("device malloc failed"); } BufferOwningPtr devicesBuf(devices); /* Get the requested device */ - error = clGetDeviceIDs(platforms[choosen_platform_index], device_type, num_devices, devices, NULL ); - if ( error != CL_SUCCESS ) + error = clGetDeviceIDs(platforms[choosen_platform_index], device_type, + num_devices, devices, NULL); + if (error != CL_SUCCESS) { - throw std::runtime_error("clGetDeviceIDs failed: " + std::string(IGetErrorString(error))); + throw std::runtime_error("clGetDeviceIDs failed: " + + std::string(IGetErrorString(error))); } return devices[choosen_device_index]; @@ -6730,54 +6720,67 @@ static void ListTests() b) one argument (tests-suite name) - run one SPIR tests-suite c) two arguments (tests-suite name and test name) - run one SPIR test */ -static int ParseCommandLine (int argc, const char *argv[], - std::string& suite_name, std::string& test_name, cl_device_type *device_type, cl_uint *device_index, cl_uint *platform_index, cl_uint *size_t_width) +static int ParseCommandLine(int argc, const char *argv[], + std::string &suite_name, std::string &test_name, + cl_device_type *device_type, cl_uint *device_index, + cl_uint *platform_index, cl_uint *size_t_width) { int based_on_env_var = 0; /* Check for environment variable to set device type */ - char *env_mode = getenv( "CL_DEVICE_TYPE" ); - if( env_mode != NULL ) + char *env_mode = getenv("CL_DEVICE_TYPE"); + if (env_mode != NULL) { based_on_env_var = 1; - if( strcmp( env_mode, "gpu" ) == 0 || strcmp( env_mode, "CL_DEVICE_TYPE_GPU" ) == 0 ) + if (strcmp(env_mode, "gpu") == 0 + || strcmp(env_mode, "CL_DEVICE_TYPE_GPU") == 0) *device_type = CL_DEVICE_TYPE_GPU; - else if( strcmp( env_mode, "cpu" ) == 0 || strcmp( env_mode, "CL_DEVICE_TYPE_CPU" ) == 0 ) + else if (strcmp(env_mode, "cpu") == 0 + || strcmp(env_mode, "CL_DEVICE_TYPE_CPU") == 0) *device_type = CL_DEVICE_TYPE_CPU; - else if( strcmp( env_mode, "accelerator" ) == 0 || strcmp( env_mode, "CL_DEVICE_TYPE_ACCELERATOR" ) == 0 ) + else if (strcmp(env_mode, "accelerator") == 0 + || strcmp(env_mode, "CL_DEVICE_TYPE_ACCELERATOR") == 0) *device_type = CL_DEVICE_TYPE_ACCELERATOR; - else if( strcmp( env_mode, "default" ) == 0 || strcmp( env_mode, "CL_DEVICE_TYPE_DEFAULT" ) == 0 ) + else if (strcmp(env_mode, "default") == 0 + || strcmp(env_mode, "CL_DEVICE_TYPE_DEFAULT") == 0) *device_type = CL_DEVICE_TYPE_DEFAULT; else { - throw Exceptions::CmdLineError( "Unknown CL_DEVICE_TYPE env variable setting\n"); + throw Exceptions::CmdLineError( + "Unknown CL_DEVICE_TYPE env variable setting\n"); } } - env_mode = getenv( "CL_DEVICE_INDEX" ); - if( env_mode != NULL ) + env_mode = getenv("CL_DEVICE_INDEX"); + if (env_mode != NULL) { *device_index = atoi(env_mode); } - env_mode = getenv( "CL_PLATFORM_INDEX" ); - if( env_mode != NULL ) + env_mode = getenv("CL_PLATFORM_INDEX"); + if (env_mode != NULL) { *platform_index = atoi(env_mode); } - /* Process the command line arguments */ + /* Process the command line arguments */ /* Special case: just list the tests */ if ((argc > 1) && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) { - log_info( "Usage: %s [] [pid] [id] [] [w32] [no-unzip]\n", argv[0] ); - log_info( "\t\tOne or more of: (default all)\n"); - log_info( "\tpid\t\tIndicates platform at index should be used (default 0).\n" ); - log_info( "\tid\t\tIndicates device at index should be used (default 0).\n" ); - log_info( "\t\tcpu|gpu|accelerator| (default CL_DEVICE_TYPE_DEFAULT)\n" ); - log_info( "\tw32\t\tIndicates device address bits is 32.\n" ); - log_info( "\tno-unzip\t\tDo not extract test files from Zip; use existing.\n" ); + log_info("Usage: %s [] [pid] [id] [] [w32] [no-unzip]\n", + argv[0]); + log_info("\t\tOne or more of: (default all)\n"); + log_info("\tpid\t\tIndicates platform at index should be " + "used (default 0).\n"); + log_info("\tid\t\tIndicates device at index should be used " + "(default 0).\n"); + log_info("\t\tcpu|gpu|accelerator| " + "(default CL_DEVICE_TYPE_DEFAULT)\n"); + log_info("\tw32\t\tIndicates device address bits is 32.\n"); + log_info("\tno-unzip\t\tDo not extract test files from Zip; use " + "existing.\n"); ListTests(); return 0; @@ -6790,87 +6793,93 @@ static int ParseCommandLine (int argc, const char *argv[], } /* Do we have a CPU/GPU specification? */ - while( argc > 1 ) + while (argc > 1) { - if( strcmp( argv[ argc - 1 ], "gpu" ) == 0 || strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_GPU" ) == 0 ) + if (strcmp(argv[argc - 1], "gpu") == 0 + || strcmp(argv[argc - 1], "CL_DEVICE_TYPE_GPU") == 0) { *device_type = CL_DEVICE_TYPE_GPU; argc--; } - else if( strcmp( argv[ argc - 1 ], "cpu" ) == 0 || strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_CPU" ) == 0 ) + else if (strcmp(argv[argc - 1], "cpu") == 0 + || strcmp(argv[argc - 1], "CL_DEVICE_TYPE_CPU") == 0) { *device_type = CL_DEVICE_TYPE_CPU; argc--; } - else if( strcmp( argv[ argc - 1 ], "accelerator" ) == 0 || strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_ACCELERATOR" ) == 0 ) + else if (strcmp(argv[argc - 1], "accelerator") == 0 + || strcmp(argv[argc - 1], "CL_DEVICE_TYPE_ACCELERATOR") == 0) { *device_type = CL_DEVICE_TYPE_ACCELERATOR; argc--; } - else if( strcmp( argv[ argc - 1 ], "CL_DEVICE_TYPE_DEFAULT" ) == 0 ) + else if (strcmp(argv[argc - 1], "CL_DEVICE_TYPE_DEFAULT") == 0) { *device_type = CL_DEVICE_TYPE_DEFAULT; argc--; } - else if( strcmp( argv[ argc - 1 ], "w32" ) == 0 ) + else if (strcmp(argv[argc - 1], "w32") == 0) { *size_t_width = 32; argc--; } - else if( strcmp( argv[ argc - 1 ], "no-unzip" ) == 0 ) + else if (strcmp(argv[argc - 1], "no-unzip") == 0) { no_unzip = 1; argc--; } - else break; + else + break; } /* Did we choose a specific device index? */ - if( argc > 1 ) + if (argc > 1) { - if( strlen( argv[ argc - 1 ] ) >= 3 && argv[ argc - 1 ][0] == 'i' && argv[ argc - 1 ][1] == 'd' ) + if (strlen(argv[argc - 1]) >= 3 && argv[argc - 1][0] == 'i' + && argv[argc - 1][1] == 'd') { - *device_index = atoi( &(argv[ argc - 1 ][2]) ); + *device_index = atoi(&(argv[argc - 1][2])); argc--; } } /* Did we choose a specific platform index? */ - if( argc > 1 ) + if (argc > 1) { - if( strlen( argv[ argc - 1 ] ) >= 3 && argv[ argc - 1 ][0] == 'p' && argv[ argc - 1 ][1] == 'i' && argv[ argc - 1 ][2] == 'd') + if (strlen(argv[argc - 1]) >= 3 && argv[argc - 1][0] == 'p' + && argv[argc - 1][1] == 'i' && argv[argc - 1][2] == 'd') { - *platform_index = atoi( &(argv[ argc - 1 ][3]) ); + *platform_index = atoi(&(argv[argc - 1][3])); argc--; } } - switch( *device_type ) + switch (*device_type) { - case CL_DEVICE_TYPE_GPU: - log_info( "Requesting GPU device " ); - break; - case CL_DEVICE_TYPE_CPU: - log_info( "Requesting CPU device " ); - break; + case CL_DEVICE_TYPE_GPU: log_info("Requesting GPU device "); break; + case CL_DEVICE_TYPE_CPU: log_info("Requesting CPU device "); break; case CL_DEVICE_TYPE_ACCELERATOR: - log_info( "Requesting Accelerator device " ); + log_info("Requesting Accelerator device "); break; case CL_DEVICE_TYPE_DEFAULT: - log_info( "Requesting Default device " ); + log_info("Requesting Default device "); break; default: - throw Exceptions::CmdLineError( "Requesting unknown device "); + throw Exceptions::CmdLineError("Requesting unknown device "); break; } - log_info( based_on_env_var ? "based on environment variable " : "based on command line " ); - log_info( "for platform index %d and device index %d\n", *platform_index, *device_index); + log_info(based_on_env_var ? "based on environment variable " + : "based on command line "); + log_info("for platform index %d and device index %d\n", *platform_index, + *device_index); if (argc > 3) { - throw Exceptions::CmdLineError("Command line error. Unrecognized token\n"); + throw Exceptions::CmdLineError( + "Command line error. Unrecognized token\n"); } - else { + else + { if (argc > 1) { suite_name.assign(argv[1]); @@ -6884,27 +6893,29 @@ static int ParseCommandLine (int argc, const char *argv[], return 1; } -struct WLMsg: EventHandler +struct WLMsg : EventHandler { - const char* Msg; + const char *Msg; - WLMsg(const char* M): Msg(M){} + WLMsg(const char *M): Msg(M) {} - void operator()(const std::string& T, const std::string& K) + void operator()(const std::string &T, const std::string &K) { - std::cout << "Test " << T << " Kernel " << K << "\t" << Msg << std::endl; + std::cout << "Test " << T << " Kernel " << K << "\t" << Msg + << std::endl; } }; -int main (int argc, const char* argv[]) +int main(int argc, const char *argv[]) { - std::string test_suite_name; // name of the selected tests-suite (NULL for all) - std::string test_file_name; // name of the .selected test (NULL for all) + std::string + test_suite_name; // name of the selected tests-suite (NULL for all) + std::string test_file_name; // name of the .selected test (NULL for all) cl_device_type device_type = CL_DEVICE_TYPE_DEFAULT; cl_uint choosen_device_index = 0; cl_uint choosen_platform_index = 0; - cl_uint size_t_width = 0; // device address bits (32 or 64). + cl_uint size_t_width = 0; // device address bits (32 or 64). cl_int err; int failed = 0; size_t ntests = 0; @@ -6916,10 +6927,14 @@ int main (int argc, const char* argv[]) WLMsg Success("\t\tPassed"), Failure("\t\tFailure"); try { - if (ParseCommandLine(argc, argv, test_suite_name, test_file_name, &device_type, &choosen_device_index, &choosen_platform_index, &size_t_width) == 0) + if (ParseCommandLine(argc, argv, test_suite_name, test_file_name, + &device_type, &choosen_device_index, + &choosen_platform_index, &size_t_width) + == 0) return 0; - cl_device_id device = get_platform_device(device_type, choosen_device_index, choosen_platform_index); + cl_device_id device = get_platform_device( + device_type, choosen_device_index, choosen_platform_index); printDeviceHeader(device); REQUIRE_EXTENSION("cl_khr_spir"); @@ -6930,38 +6945,46 @@ int main (int argc, const char* argv[]) if (std::find(versions.begin(), versions.end(), Version{ 1, 2 }) == versions.end()) { - log_info("Spir extension version 1.2 is not supported by the device\n"); + log_info( + "Spir extension version 1.2 is not supported by the device\n"); return 0; } - // size_t_width <> 0 - device address bits is forced by command line argument - if ((0 == size_t_width) && ((err = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &size_t_width, NULL)))) + // size_t_width <> 0 - device address bits is forced by command line + // argument + if ((0 == size_t_width) + && ((err = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, + sizeof(cl_uint), &size_t_width, NULL)))) { - print_error( err, "Unable to obtain device address bits" ); + print_error(err, "Unable to obtain device address bits"); return -1; } - if (! test_suite_name.empty()) + if (!test_suite_name.empty()) { // command line is not empty - do not run all the tests int tsn = find_suite_name(test_suite_name); ntests = 1; if (tsn < 0) { - throw Exceptions::CmdLineError("Command line error. Error in SPIR sub-suite name\n"); + throw Exceptions::CmdLineError( + "Command line error. Error in SPIR sub-suite name\n"); } else if (test_file_name.empty()) { - if (!spir_suites[tsn].test_function(device, size_t_width, spir_suites[tsn].folder)) + if (!spir_suites[tsn].test_function(device, size_t_width, + spir_suites[tsn].folder)) failed++; } else { - OclExtensions devExt = OclExtensions::getDeviceCapabilities(device); + OclExtensions devExt = + OclExtensions::getDeviceCapabilities(device); TestRunner runner(&Success, &Failure, devExt); std::string folder = getTestFolder(test_suite_name.c_str()); try_extract(folder.c_str()); - if (!runner.runBuildTest(device, folder.c_str(), test_file_name.c_str(), size_t_width)) + if (!runner.runBuildTest(device, folder.c_str(), + test_file_name.c_str(), size_t_width)) failed++; } } @@ -6971,30 +6994,31 @@ int main (int argc, const char* argv[]) ntests = (sizeof(spir_suites) / sizeof(spir_suites[0])); for (unsigned int i = 0; i < ntests; ++i) { - if (!spir_suites[i].test_function(device, size_t_width, spir_suites[i].folder)) + if (!spir_suites[i].test_function(device, size_t_width, + spir_suites[i].folder)) failed++; } } if (failed) - std::cout << "FAILED " << failed << " of " << ntests << " test suites.\n" << std::endl; + std::cout << "FAILED " << failed << " of " << ntests + << " test suites.\n" + << std::endl; else - std::cout << "PASSED " << ntests << " of " << ntests << " test suites.\n" << std::endl; + std::cout << "PASSED " << ntests << " of " << ntests + << " test suites.\n" + << std::endl; return failed; - } - catch(const Exceptions::CmdLineError& e) + } catch (const Exceptions::CmdLineError &e) { print_error(1, e.what()); return 1; - } - catch(const std::runtime_error& e) + } catch (const std::runtime_error &e) { print_error(2, e.what()); return 2; - } - catch(const std::exception& e) + } catch (const std::exception &e) { print_error(3, e.what()); return 3; } } - diff --git a/test_conformance/spir/run_build_test.cpp b/test_conformance/spir/run_build_test.cpp index 46f9d022..697cd65c 100644 --- a/test_conformance/spir/run_build_test.cpp +++ b/test_conformance/spir/run_build_test.cpp @@ -1,6 +1,6 @@ // // 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 @@ -43,35 +43,37 @@ // // Task // -Task::Task(cl_device_id device, const char* options): -m_devid(device) { - if (options) - m_options = options; +Task::Task(cl_device_id device, const char* options): m_devid(device) +{ + if (options) m_options = options; } Task::~Task() {} -const char* Task::getErrorLog() const { - return m_log.c_str(); -} +const char* Task::getErrorLog() const { return m_log.c_str(); } -void Task::setErrorLog(cl_program prog) { +void Task::setErrorLog(cl_program prog) +{ size_t len = 0; std::vector log; - cl_int err_code = clGetProgramBuildInfo(prog, m_devid, CL_PROGRAM_BUILD_LOG, 0, NULL, &len); - if(err_code != CL_SUCCESS) + cl_int err_code = clGetProgramBuildInfo(prog, m_devid, CL_PROGRAM_BUILD_LOG, + 0, NULL, &len); + if (err_code != CL_SUCCESS) { - m_log = "Error: clGetProgramBuildInfo(CL_PROGRAM_BUILD_LOG, &len) failed.\n"; + m_log = "Error: clGetProgramBuildInfo(CL_PROGRAM_BUILD_LOG, &len) " + "failed.\n"; return; } log.resize(len, 0); - err_code = clGetProgramBuildInfo(prog, m_devid, CL_PROGRAM_BUILD_LOG, len, &log[0], NULL); - if(err_code != CL_SUCCESS) + err_code = clGetProgramBuildInfo(prog, m_devid, CL_PROGRAM_BUILD_LOG, len, + &log[0], NULL); + if (err_code != CL_SUCCESS) { - m_log = "Error: clGetProgramBuildInfo(CL_PROGRAM_BUILD_LOG, &log) failed.\n"; + m_log = "Error: clGetProgramBuildInfo(CL_PROGRAM_BUILD_LOG, &log) " + "failed.\n"; return; } m_log.append(&log[0]); @@ -84,10 +86,11 @@ BuildTask::BuildTask(cl_program prog, cl_device_id dev, const char* options) : Task(dev, options), m_program(prog) {} -bool BuildTask::execute() { - cl_int err_code = clBuildProgram(m_program, 0, NULL, m_options.c_str(), NULL, NULL); - if(CL_SUCCESS == err_code) - return true; +bool BuildTask::execute() +{ + cl_int err_code = + clBuildProgram(m_program, 0, NULL, m_options.c_str(), NULL, NULL); + if (CL_SUCCESS == err_code) return true; setErrorLog(m_program); return false; @@ -96,8 +99,10 @@ bool BuildTask::execute() { // // SpirBuildTask // -SpirBuildTask::SpirBuildTask(cl_program prog, cl_device_id dev, const char* options) : - BuildTask(prog, dev, options) {} +SpirBuildTask::SpirBuildTask(cl_program prog, cl_device_id dev, + const char* options) + : BuildTask(prog, dev, options) +{} // // CompileTask @@ -107,47 +112,43 @@ CompileTask::CompileTask(cl_program prog, cl_device_id dev, const char* options) : Task(dev, options), m_program(prog) {} -void CompileTask::addHeader(const char* hname, cl_program hprog) { +void CompileTask::addHeader(const char* hname, cl_program hprog) +{ m_headers.push_back(std::make_pair(hname, hprog)); } -const char* first(std::pair& p) { - return p.first; -} +const char* first(std::pair& p) { return p.first; } -cl_program second(const std::pair& p) { +cl_program second(const std::pair& p) +{ return p.second; } -bool CompileTask::execute() { +bool CompileTask::execute() +{ // Generating the header names vector. std::vector names; std::transform(m_headers.begin(), m_headers.end(), names.begin(), first); // Generating the header programs vector. std::vector programs; - std::transform(m_headers.begin(), m_headers.end(), programs.begin(), second); + std::transform(m_headers.begin(), m_headers.end(), programs.begin(), + second); const char** h_names = NULL; const cl_program* h_programs = NULL; if (!m_headers.empty()) { h_programs = &programs[0]; - h_names = &names[0]; + h_names = &names[0]; } // Compiling with the headers. - cl_int err_code = clCompileProgram( - m_program, - 1U, - &m_devid, - m_options.c_str(), - m_headers.size(), // # of headers - h_programs, - h_names, - NULL, NULL); - if (CL_SUCCESS == err_code) - return true; + cl_int err_code = + clCompileProgram(m_program, 1U, &m_devid, m_options.c_str(), + m_headers.size(), // # of headers + h_programs, h_names, NULL, NULL); + if (CL_SUCCESS == err_code) return true; setErrorLog(m_program); return false; @@ -156,8 +157,10 @@ bool CompileTask::execute() { // // SpirCompileTask // -SpirCompileTask::SpirCompileTask(cl_program prog, cl_device_id dev, const char* options) : - CompileTask(prog, dev, options) {} +SpirCompileTask::SpirCompileTask(cl_program prog, cl_device_id dev, + const char* options) + : CompileTask(prog, dev, options) +{} // @@ -169,13 +172,16 @@ LinkTask::LinkTask(cl_program* programs, int num_programs, cl_context ctxt, m_numPrograms(num_programs), m_context(ctxt) {} -bool LinkTask::execute() { +bool LinkTask::execute() +{ cl_int err_code; int i; - for(i = 0; i < m_numPrograms; ++i) + for (i = 0; i < m_numPrograms; ++i) { - err_code = clCompileProgram(m_programs[i], 1, &m_devid, "-x spir -spir-std=1.2 -cl-kernel-arg-info", 0, NULL, NULL, NULL, NULL); + err_code = clCompileProgram(m_programs[i], 1, &m_devid, + "-x spir -spir-std=1.2 -cl-kernel-arg-info", + 0, NULL, NULL, NULL, NULL); if (CL_SUCCESS != err_code) { setErrorLog(m_programs[i]); @@ -183,91 +189,78 @@ bool LinkTask::execute() { } } - m_executable = clLinkProgram(m_context, 1, &m_devid, m_options.c_str(), m_numPrograms, m_programs, NULL, NULL, &err_code); - if (CL_SUCCESS == err_code) - return true; + m_executable = + clLinkProgram(m_context, 1, &m_devid, m_options.c_str(), m_numPrograms, + m_programs, NULL, NULL, &err_code); + if (CL_SUCCESS == err_code) return true; - if(m_executable) setErrorLog(m_executable); + if (m_executable) setErrorLog(m_executable); return false; } -cl_program LinkTask::getExecutable() const { - return m_executable; -} +cl_program LinkTask::getExecutable() const { return m_executable; } -LinkTask::~LinkTask() { - if(m_executable) clReleaseProgram(m_executable); +LinkTask::~LinkTask() +{ + if (m_executable) clReleaseProgram(m_executable); } // // KernelEnumerator // -void KernelEnumerator::process(cl_program prog) { +void KernelEnumerator::process(cl_program prog) +{ const size_t MAX_KERNEL_NAME = 64; size_t num_kernels; - cl_int err_code = clGetProgramInfo( - prog, - CL_PROGRAM_NUM_KERNELS, - sizeof(size_t), - &num_kernels, - NULL - ); - if (CL_SUCCESS != err_code) - return; + cl_int err_code = clGetProgramInfo(prog, CL_PROGRAM_NUM_KERNELS, + sizeof(size_t), &num_kernels, NULL); + if (CL_SUCCESS != err_code) return; // Querying for the number of kernels. - size_t buffer_len = sizeof(char)*num_kernels*MAX_KERNEL_NAME; + size_t buffer_len = sizeof(char) * num_kernels * MAX_KERNEL_NAME; char* kernel_names = new char[buffer_len]; memset(kernel_names, '\0', buffer_len); size_t str_len = 0; - err_code = clGetProgramInfo( - prog, - CL_PROGRAM_KERNEL_NAMES, - buffer_len, - (void *)kernel_names, - &str_len - ); - if (CL_SUCCESS != err_code) - return; + err_code = clGetProgramInfo(prog, CL_PROGRAM_KERNEL_NAMES, buffer_len, + (void*)kernel_names, &str_len); + if (CL_SUCCESS != err_code) return; - //parsing the names and inserting them to the list + // parsing the names and inserting them to the list std::string names(kernel_names); - assert (str_len == 1+names.size() && "incompatible string lengths"); + assert(str_len == 1 + names.size() && "incompatible string lengths"); size_t offset = 0; - for(size_t i=0 ; iname); if (strstr(test_name, name)) { @@ -336,16 +330,17 @@ static float get_max_ulps(const char *test_name) return ulps; } -TestRunner::TestRunner(EventHandler *success, EventHandler *failure, - const OclExtensions& devExt): - m_successHandler(success), m_failureHandler(failure), m_devExt(&devExt) {} +TestRunner::TestRunner(EventHandler* success, EventHandler* failure, + const OclExtensions& devExt) + : m_successHandler(success), m_failureHandler(failure), m_devExt(&devExt) +{} /** Based on the test name build the cl file name, the bc file name and execute the kernel for both modes (cl and bc). */ -bool TestRunner::runBuildTest(cl_device_id device, const char *folder, - const char *test_name, cl_uint size_t_width) +bool TestRunner::runBuildTest(cl_device_id device, const char* folder, + const char* test_name, cl_uint size_t_width) { int failures = 0; // Composing the name of the CSV file. @@ -365,28 +360,35 @@ bool TestRunner::runBuildTest(cl_device_id device, const char *folder, cl_bool images3D = khrDb.isImages3DRequired(folder, test_name); char deviceProfile[64]; - clGetDeviceInfo(device, CL_DEVICE_PROFILE, sizeof(deviceProfile), &deviceProfile, NULL); + clGetDeviceInfo(device, CL_DEVICE_PROFILE, sizeof(deviceProfile), + &deviceProfile, NULL); std::string device_profile(deviceProfile, 64); - if(images == CL_TRUE && checkForImageSupport(device) != 0) + if (images == CL_TRUE && checkForImageSupport(device) != 0) { (*m_successHandler)(test_name, ""); - std::cout << "Skipped. (Cannot run on device due to Images is not supported)." << std::endl; + std::cout + << "Skipped. (Cannot run on device due to Images is not supported)." + << std::endl; return true; } - if(images3D == CL_TRUE && checkFor3DImageSupport(device) != 0) + if (images3D == CL_TRUE && checkFor3DImageSupport(device) != 0) { (*m_successHandler)(test_name, ""); - std::cout << "Skipped. (Cannot run on device as 3D images are not supported)." << std::endl; + std::cout + << "Skipped. (Cannot run on device as 3D images are not supported)." + << std::endl; return true; } OclExtensions requiredExt = khrDb.getRequiredExtensions(folder, test_name); - if(!m_devExt->supports(requiredExt)) + if (!m_devExt->supports(requiredExt)) { (*m_successHandler)(test_name, ""); - std::cout << "Skipped. (Cannot run on device due to missing extensions: " << m_devExt->get_missing(requiredExt) << " )." << std::endl; + std::cout + << "Skipped. (Cannot run on device due to missing extensions: " + << m_devExt->get_missing(requiredExt) << " )." << std::endl; return true; } @@ -409,17 +411,26 @@ bool TestRunner::runBuildTest(cl_device_id device, const char *folder, cl_device_fp_config gFloatCapabilities = 0; cl_int err; - if ((err = clGetDeviceInfo(device, CL_DEVICE_SINGLE_FP_CONFIG, sizeof(gFloatCapabilities), &gFloatCapabilities, NULL))) + if ((err = clGetDeviceInfo(device, CL_DEVICE_SINGLE_FP_CONFIG, + sizeof(gFloatCapabilities), &gFloatCapabilities, + NULL))) { - log_info("Unable to get device CL_DEVICE_SINGLE_FP_CONFIG. (%d)\n", err); + log_info("Unable to get device CL_DEVICE_SINGLE_FP_CONFIG. (%d)\n", + err); } - if (strstr(test_name, "div_cr") || strstr(test_name, "sqrt_cr")) { - if ((gFloatCapabilities & CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT) == 0) { + if (strstr(test_name, "div_cr") || strstr(test_name, "sqrt_cr")) + { + if ((gFloatCapabilities & CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT) == 0) + { (*m_successHandler)(test_name, ""); - std::cout << "Skipped. (Cannot run on device due to missing CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT property.)" << std::endl; + std::cout << "Skipped. (Cannot run on device due to missing " + "CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT property.)" + << std::endl; return true; - } else { + } + else + { bcoptions += " -cl-fp32-correctly-rounded-divide-sqrt"; cloptions += " -cl-fp32-correctly-rounded-divide-sqrt"; } @@ -427,33 +438,39 @@ bool TestRunner::runBuildTest(cl_device_id device, const char *folder, // Building the programs. BuildTask clBuild(clprog, device, cloptions.c_str()); - if (!clBuild.execute()) { + if (!clBuild.execute()) + { std::cerr << clBuild.getErrorLog() << std::endl; + (*m_failureHandler)(test_name, ""); return false; } SpirBuildTask bcBuild(bcprog, device, bcoptions.c_str()); - if (!bcBuild.execute()) { + if (!bcBuild.execute()) + { std::cerr << bcBuild.getErrorLog() << std::endl; + (*m_failureHandler)(test_name, ""); return false; } - KernelEnumerator clkernel_enumerator(clprog), - bckernel_enumerator(bcprog); - if (clkernel_enumerator.size() != bckernel_enumerator.size()) { + KernelEnumerator clkernel_enumerator(clprog), bckernel_enumerator(bcprog); + if (clkernel_enumerator.size() != bckernel_enumerator.size()) + { std::cerr << "number of kernels in test" << test_name << " doesn't match in bc and cl files" << std::endl; + (*m_failureHandler)(test_name, ""); return false; } KernelEnumerator::iterator it = clkernel_enumerator.begin(), - e = clkernel_enumerator.end(); + e = clkernel_enumerator.end(); while (it != e) { std::string kernel_name = *it++; std::string err; try { - bool success = run_test(context, queue, clprog, bcprog, kernel_name, err, device, ulps); + bool success = run_test(context, queue, clprog, bcprog, kernel_name, + err, device, ulps); if (success) { log_info("kernel '%s' passed.\n", kernel_name.c_str()); @@ -468,7 +485,8 @@ bool TestRunner::runBuildTest(cl_device_id device, const char *folder, } catch (const std::runtime_error& err) { ++failures; - log_info("kernel '%s' failed: %s\n", kernel_name.c_str(), err.what()); + log_info("kernel '%s' failed: %s\n", kernel_name.c_str(), + err.what()); (*m_failureHandler)(test_name, kernel_name); } } @@ -476,4 +494,3 @@ bool TestRunner::runBuildTest(cl_device_id device, const char *folder, log_info("%s %s\n", test_name, failures ? "FAILED" : "passed."); return failures == 0; } -