SPIR-V handling on different OpenCL devices version

Example usage for bruteforce and spirv_new
This commit is contained in:
Grzegorz Wawiorko
2020-03-27 19:32:19 +01:00
committed by Alastair Murray
parent d643dc5399
commit 3730bce4e8
4 changed files with 104 additions and 10 deletions

View File

@@ -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<char> 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<char> 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 *) );

View File

@@ -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)