diff --git a/test_common/harness/errorHelpers.h b/test_common/harness/errorHelpers.h index 95b66366..e85a53fe 100644 --- a/test_common/harness/errorHelpers.h +++ b/test_common/harness/errorHelpers.h @@ -16,6 +16,8 @@ #ifndef _errorHelpers_h #define _errorHelpers_h +#include + #ifdef __APPLE__ #include #else @@ -97,6 +99,19 @@ extern "C" { #define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } } #define print_failure_warning(errCode, expectedErrCode, msg) log_error( "WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ ); +#define ASSERT_SUCCESS(expr, msg) \ + do \ + { \ + cl_int _temp_retval = (expr); \ + if (_temp_retval != CL_SUCCESS) \ + { \ + std::stringstream ss; \ + ss << "ERROR: " << msg << "=" << IGetErrorString(_temp_retval) \ + << " at " << __FILE__ << ":" << __LINE__ << "\n"; \ + throw std::runtime_error(ss.str()); \ + } \ + } while (0) + extern const char *IGetErrorString( int clErrorCode ); extern float Ulp_Error_Half( cl_ushort test, float reference ); diff --git a/test_common/harness/testHarness.c b/test_common/harness/testHarness.c index edb5eb91..ab029b37 100644 --- a/test_common/harness/testHarness.c +++ b/test_common/harness/testHarness.c @@ -17,6 +17,9 @@ #include "compat.h" #include #include +#include +#include +#include #include "threadTesting.h" #include "errorHelpers.h" #include "kernelHelpers.h" @@ -703,11 +706,12 @@ test_status callSingleTestFunction( test_definition test, cl_device_id deviceToU log_info( "%s...\n", test.name ); fflush( stdout ); - error = check_opencl_version_with_testname(test.name, deviceToUse); - if( error != CL_SUCCESS ) - { - print_missing_feature( error, test.name ); - return TEST_SKIP; + const Version device_version = get_device_cl_version(deviceToUse); + if (test.min_version > device_version) + { + log_info("%s skipped (requires at least version %s, but the device reports version %s)\n", + test.name, test.min_version.to_string().c_str(), device_version.to_string().c_str()); + return TEST_SKIP; } error = check_functions_for_offline_compiler(test.name, deviceToUse); @@ -894,4 +898,28 @@ cl_device_id GetOpposingDevice( cl_device_id device ) return NULL; } +Version get_device_cl_version(cl_device_id device) +{ + size_t str_size; + cl_int err = clGetDeviceInfo(device, CL_DEVICE_VERSION, 0, NULL, &str_size); + ASSERT_SUCCESS(err, "clGetDeviceInfo"); + std::vector str(str_size); + err = clGetDeviceInfo(device, CL_DEVICE_VERSION, str_size, str.data(), NULL); + ASSERT_SUCCESS(err, "clGetDeviceInfo"); + + if (strstr(str.data(), "OpenCL 1.0") != NULL) + return Version(1, 0); + else if (strstr(str.data(), "OpenCL 1.1") != NULL) + return Version(1, 1); + else if (strstr(str.data(), "OpenCL 1.2") != NULL) + return Version(1, 2); + else if (strstr(str.data(), "OpenCL 2.0") != NULL) + return Version(2, 0); + else if (strstr(str.data(), "OpenCL 2.1") != NULL) + return Version(2, 1); + else if (strstr(str.data(), "OpenCL 2.2") != NULL) + return Version(2, 2); + + throw std::runtime_error(std::string("Unknown OpenCL version: ") + str.data()); +} diff --git a/test_common/harness/testHarness.h b/test_common/harness/testHarness.h index b988d679..9067d555 100644 --- a/test_common/harness/testHarness.h +++ b/test_common/harness/testHarness.h @@ -18,6 +18,8 @@ #include "threadTesting.h" #include "clImageHelper.h" +#include +#include #include @@ -25,15 +27,36 @@ extern "C" { #endif -#define ADD_TEST(fn) {test_##fn, #fn} -#define NOT_IMPLEMENTED_TEST(fn) {NULL, #fn} +#define ADD_TEST(fn) {test_##fn, #fn, Version(1, 0)} +#define ADD_TEST_VERSION(fn, ver) {test_##fn, #fn, ver} +#define NOT_IMPLEMENTED_TEST(fn) {NULL, #fn, Version(0, 0)} #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +class Version +{ +public: + Version() : m_major(0), m_minor(0) {} + Version(int major, int minor) : m_major(major), m_minor(minor) {} + bool operator>(const Version& rhs) const { return to_int() > rhs.to_int(); } + int to_int() const { return m_major * 10 + m_minor; } + std::string to_string() const + { + std::stringstream ss; + ss << m_major << "." << m_minor; + return ss.str(); + } + +private: + int m_major; + int m_minor; +}; + typedef struct test_definition { basefn func; const char* name; + Version min_version; } test_definition; @@ -99,6 +122,8 @@ extern cl_device_type GetDeviceType( cl_device_id ); // is the only device available, the SAME device is returned, so check! extern cl_device_id GetOpposingDevice( cl_device_id device ); +Version get_device_cl_version(cl_device_id device); + extern int gFlushDenormsToZero; // This is set to 1 if the device does not support denorms (CL_FP_DENORM) extern int gInfNanSupport; // This is set to 1 if the device supports infinities and NaNs diff --git a/test_conformance/compatibility/test_common/harness/errorHelpers.h b/test_conformance/compatibility/test_common/harness/errorHelpers.h index 9b5d7097..54e73b07 100644 --- a/test_conformance/compatibility/test_common/harness/errorHelpers.h +++ b/test_conformance/compatibility/test_common/harness/errorHelpers.h @@ -16,6 +16,8 @@ #ifndef _errorHelpers_h #define _errorHelpers_h +#include + #ifdef __APPLE__ #include #else @@ -85,6 +87,19 @@ extern "C" { #define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } } #define print_failure_warning(errCode, expectedErrCode, msg) log_error( "WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ ); +#define ASSERT_SUCCESS(expr, msg) \ + do \ + { \ + cl_int _temp_retval = (expr); \ + if (_temp_retval != CL_SUCCESS) \ + { \ + std::stringstream ss; \ + ss << "ERROR: " << msg << "=" << IGetErrorString(_temp_retval) \ + << " at " << __FILE__ << ":" << __LINE__ << "\n"; \ + throw std::runtime_error(ss.str()); \ + } \ + } while (0) + extern const char *IGetErrorString( int clErrorCode ); extern float Ulp_Error_Half( cl_ushort test, float reference ); diff --git a/test_conformance/compatibility/test_common/harness/testHarness.c b/test_conformance/compatibility/test_common/harness/testHarness.c index 2762dbeb..95b57f09 100644 --- a/test_conformance/compatibility/test_common/harness/testHarness.c +++ b/test_conformance/compatibility/test_common/harness/testHarness.c @@ -23,6 +23,9 @@ #endif #include +#include +#include +#include #include "threadTesting.h" #include "errorHelpers.h" #include "kernelHelpers.h" @@ -701,6 +704,14 @@ test_status callSingleTestFunction( test_definition test, cl_device_id deviceToU log_info( "%s...\n", test.name ); fflush( stdout ); + const Version device_version = get_device_cl_version(deviceToUse); + if (test.min_version > device_version) + { + log_info("%s skipped (requires at least version %s, but the device reports version %s)\n", + test.name, test.min_version.to_string().c_str(), device_version.to_string().c_str()); + return TEST_SKIP; + } + if( test.func == NULL ) { // Skip unimplemented test, can happen when all of the tests are selected @@ -881,4 +892,28 @@ cl_device_id GetOpposingDevice( cl_device_id device ) return NULL; } +Version get_device_cl_version(cl_device_id device) +{ + size_t str_size; + cl_int err = clGetDeviceInfo(device, CL_DEVICE_VERSION, 0, NULL, &str_size); + ASSERT_SUCCESS(err, "clGetDeviceInfo"); + std::vector str(str_size); + err = clGetDeviceInfo(device, CL_DEVICE_VERSION, str_size, str.data(), NULL); + ASSERT_SUCCESS(err, "clGetDeviceInfo"); + + if (strstr(str.data(), "OpenCL 1.0") != NULL) + return Version(1, 0); + else if (strstr(str.data(), "OpenCL 1.1") != NULL) + return Version(1, 1); + else if (strstr(str.data(), "OpenCL 1.2") != NULL) + return Version(1, 2); + else if (strstr(str.data(), "OpenCL 2.0") != NULL) + return Version(2, 0); + else if (strstr(str.data(), "OpenCL 2.1") != NULL) + return Version(2, 1); + else if (strstr(str.data(), "OpenCL 2.2") != NULL) + return Version(2, 2); + + throw std::runtime_error(std::string("Unknown OpenCL version: ") + str.data()); +} diff --git a/test_conformance/compatibility/test_common/harness/testHarness.h b/test_conformance/compatibility/test_common/harness/testHarness.h index a3bf9f4e..0a86d8dd 100644 --- a/test_conformance/compatibility/test_common/harness/testHarness.h +++ b/test_conformance/compatibility/test_common/harness/testHarness.h @@ -18,20 +18,43 @@ #include "threadTesting.h" #include "clImageHelper.h" +#include +#include #ifdef __cplusplus extern "C" { #endif -#define ADD_TEST(fn) {test_##fn, #fn} -#define NOT_IMPLEMENTED_TEST(fn) {NULL, #fn} +#define ADD_TEST(fn) {test_##fn, #fn, Version(1, 0)} +#define ADD_TEST_VERSION(fn, ver) {test_##fn, #fn, ver} +#define NOT_IMPLEMENTED_TEST(fn) {NULL, #fn, Version(0, 0)} #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +class Version +{ +public: + Version() : m_major(0), m_minor(0) {} + Version(int major, int minor) : m_major(major), m_minor(minor) {} + bool operator>(const Version& rhs) const { return to_int() > rhs.to_int(); } + int to_int() const { return m_major * 10 + m_minor; } + std::string to_string() const + { + std::stringstream ss; + ss << m_major << "." << m_minor; + return ss.str(); + } + +private: + int m_major; + int m_minor; +}; + typedef struct test_definition { basefn func; const char* name; + Version min_version; } test_definition; typedef enum test_status @@ -96,6 +119,8 @@ extern cl_device_type GetDeviceType( cl_device_id ); // is the only device available, the SAME device is returned, so check! extern cl_device_id GetOpposingDevice( cl_device_id device ); +Version get_device_cl_version(cl_device_id device); + extern int gFlushDenormsToZero; // This is set to 1 if the device does not support denorms (CL_FP_DENORM) extern int gInfNanSupport; // This is set to 1 if the device supports infinities and NaNs diff --git a/test_conformance/spirv_new/main.cpp b/test_conformance/spirv_new/main.cpp index a08bbe37..81e2dd12 100644 --- a/test_conformance/spirv_new/main.cpp +++ b/test_conformance/spirv_new/main.cpp @@ -79,6 +79,7 @@ void spirvTestsRegistry::addTestClass(baseTestClass *test, const char *testName) test_definition testDef; testDef.func = test->getFunction(); testDef.name = testName; + testDef.min_version = Version(2, 1); testDefinitions.push_back(testDef); }