diff --git a/test_common/harness/testHarness.cpp b/test_common/harness/testHarness.cpp index d6b747fb..b1dff655 100644 --- a/test_common/harness/testHarness.cpp +++ b/test_common/harness/testHarness.cpp @@ -891,6 +891,86 @@ Version get_device_cl_version(cl_device_id device) throw std::runtime_error(std::string("Unknown OpenCL version: ") + str.data()); } +bool check_device_spirv_il_support(cl_device_id device) { + size_t str_size; + cl_int err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, 0, NULL, &str_size); + if (err != CL_SUCCESS) { + log_error("clGetDeviceInfo: cannot read CL_DEVICE_IL_VERSION size;"); + return false; + } + + std::vector str(str_size); + err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, str_size, str.data(), NULL); + if (err != CL_SUCCESS) { + log_error("clGetDeviceInfo: cannot read CL_DEVICE_IL_VERSION value;"); + return false; + } + + if (strstr(str.data(), "SPIR-V") == NULL) { + log_info("This device does not support SPIR-V offline compilation.\n"); + return false; + } else { + Version spirv_version = get_device_spirv_il_version(device); + log_info("This device supports SPIR-V offline compilation. SPIR-V version is %s\n", spirv_version.to_string()); + } + return true; +} + +Version get_device_spirv_il_version(cl_device_id device) +{ + size_t str_size; + cl_int err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, 0, NULL, &str_size); + ASSERT_SUCCESS(err, "clGetDeviceInfo"); + + std::vector str(str_size); + err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, str_size, str.data(), NULL); + ASSERT_SUCCESS(err, "clGetDeviceInfo"); + + if (strstr(str.data(), "SPIR-V_1.0") != NULL) + return Version(1, 0); + else if (strstr(str.data(), "SPIR-V_1.1") != NULL) + return Version(1, 1); + else if (strstr(str.data(), "SPIR-V_1.2") != NULL) + return Version(1, 2); + else if (strstr(str.data(), "SPIR-V_1.3") != NULL) + return Version(1, 3); + else if (strstr(str.data(), "SPIR-V_1.4") != NULL) + return Version(1, 4); + else if (strstr(str.data(), "SPIR-V_1.5") != NULL) + return Version(1, 5); + + throw std::runtime_error(std::string("Unknown SPIR-V version: ") + str.data()); +} + +test_status check_spirv_compilation_readiness(cl_device_id device, bool force) +{ + if (gCompilationMode == kSpir_v || force) { + auto ocl_version = get_device_cl_version(device); + auto ocl_expected_min_version = Version(2, 1); + + if (ocl_version < ocl_expected_min_version) { + version_expected_info("Test", "OpenCL", ocl_expected_min_version.to_string().c_str(), ocl_version.to_string().c_str()); + return TEST_SKIP; + } + + bool spirv_supported = check_device_spirv_il_support(device); + if (ocl_version >= ocl_expected_min_version && ocl_version <= Version(2, 2)) { + if (spirv_supported == false) { + log_error("SPIR-V intermediate language not supported !!! OpenCL %s requires support.\n", ocl_version.to_string()); + return TEST_FAIL; + } + } + + if (ocl_version > Version(2, 2)) { + if (spirv_supported == false) { + log_info("SPIR-V intermediate language not supported in OpenCL %s. Test skipped.\n", ocl_version.to_string()); + return TEST_SKIP; + } + } + } + return TEST_PASS; +} + void PrintArch( void ) { vlog( "sizeof( void*) = %ld\n", sizeof( void *) ); diff --git a/test_common/harness/testHarness.h b/test_common/harness/testHarness.h index 68e808f0..d6aefb46 100644 --- a/test_common/harness/testHarness.h +++ b/test_common/harness/testHarness.h @@ -34,7 +34,7 @@ public: bool operator>=(const Version& rhs) const { return to_int() >= rhs.to_int(); } 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::string to_string() const { std::stringstream ss; ss << m_major << "." << m_minor; @@ -135,7 +135,10 @@ 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_spirv_il_version(cl_device_id device); +bool check_device_spirv_il_support(cl_device_id device); void version_expected_info(const char * test_name, const char * api_name, const char * expected_version, const char * device_version); +test_status check_spirv_compilation_readiness(cl_device_id device, bool force = false); extern int gFlushDenormsToZero; // This is set to 1 if the device does not support denorms (CL_FP_DENORM) diff --git a/test_conformance/math_brute_force/main.cpp b/test_conformance/math_brute_force/main.cpp index 2a343623..4d578ab7 100644 --- a/test_conformance/math_brute_force/main.cpp +++ b/test_conformance/math_brute_force/main.cpp @@ -1103,7 +1103,11 @@ test_status InitCL( cl_device_id device ) } gDevice = device; - + test_status spirv_status; + spirv_status = check_spirv_compilation_readiness(device); + if (spirv_status != TEST_PASS) { + return spirv_status; + } if( (error = clGetDeviceInfo( gDevice, CL_DEVICE_MAX_COMPUTE_UNITS, configSize, &gComputeDevices, NULL )) ) gComputeDevices = 1; diff --git a/test_conformance/spirv_new/main.cpp b/test_conformance/spirv_new/main.cpp index 42a1251e..0cd9f090 100644 --- a/test_conformance/spirv_new/main.cpp +++ b/test_conformance/spirv_new/main.cpp @@ -163,17 +163,24 @@ int get_program_with_il(clProgramWrapper &prog, return err; } -test_status checkAddressWidth(cl_device_id id) +test_status InitCL(cl_device_id id) { - cl_uint address_bits; - cl_uint err = clGetDeviceInfo(id, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &address_bits, NULL); - if(err != CL_SUCCESS){ + test_status spirv_status; + bool force = true; + spirv_status = check_spirv_compilation_readiness(id, force); + if (spirv_status != TEST_PASS) { + return spirv_status; + } + + cl_uint address_bits; + cl_uint err = clGetDeviceInfo(id, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), &address_bits, NULL); + if(err != CL_SUCCESS){ log_error("clGetDeviceInfo failed to get address bits!"); return TEST_FAIL; - } + } - gAddrWidth = address_bits == 32 ? "32" : "64"; - return TEST_PASS; + gAddrWidth = address_bits == 32 ? "32" : "64"; + return TEST_PASS; } void printUsage() { @@ -213,5 +220,5 @@ int main(int argc, const char *argv[]) return runTestHarnessWithCheck(argc, argv, spirvTestsRegistry::getInstance().getNumTests(), spirvTestsRegistry::getInstance().getTestDefinitions(), - false, 0, checkAddressWidth); + false, 0, InitCL); }