Skip to content

Commit

Permalink
Removed OpenCL 2.0 check and cl_khr_subgroups from blur sample
Browse files Browse the repository at this point in the history
  • Loading branch information
Beanavil committed Jul 5, 2024
1 parent 3a3b557 commit 36e199c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 58 deletions.
39 changes: 29 additions & 10 deletions samples/core/blur/blur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <map>
#include <random>
#include <sstream>
#include <string>

// C header includes
#include <math.h>
Expand Down Expand Up @@ -484,7 +485,13 @@ void BlurCppExample::prepare_output_image()
* output_image.pixel_size);
}

std::tuple<bool, bool, bool> BlurCppExample::query_capabilities()
bool opencl_version_contains(const cl::string& dev_version,
const cl::string& version_fragment)
{
return dev_version.find(version_fragment) != cl::string::npos;
}

std::tuple<bool, bool, bool, std::string> BlurCppExample::query_capabilities()
{
// 1) query image support
if (!device.getInfo<CL_DEVICE_IMAGE_SUPPORT>())
Expand All @@ -501,21 +508,33 @@ std::tuple<bool, bool, bool> BlurCppExample::query_capabilities()
(device.getInfo<CL_DEVICE_LOCAL_MEM_TYPE>() == CL_LOCAL);

// 4) query if device allow subgroup shuffle operations
bool use_subgroups =
cl::util::supports_extension(device, "cl_khr_subgroups");
bool use_subgroup_exchange =
cl::util::supports_extension(device, "cl_khr_subgroup_shuffle");
bool use_subgroup_exchange_relative = cl::util::supports_extension(
device, "cl_khr_subgroup_shuffle_relative");

return std::make_tuple(use_local_mem,
use_subgroups && use_subgroup_exchange,
use_subgroups && use_subgroup_exchange_relative);
}
// 5) Query OpenCL version to compile for.
// If no -cl-std option is specified then the highest 1.x version
// supported by each device is used to compile the program. Therefore,
// it's necessary to add the -cl-std option for 2.0 and 3.0 OpenCL
// versions.
const std::string dev_version = device.getInfo<CL_DEVICE_VERSION>();
cl::string compiler_options;
constexpr int max_major_version = 3;
for (auto i = 2; i <= max_major_version; ++i)
{
std::string version_str = std::to_string(i) + "."; // "i."
std::string compiler_opt_str =
"-cl-std=CL" + std::to_string(i) + ".0 "; // -cl-std=CLi.0

compiler_options +=
cl::string{ opencl_version_contains(dev_version, version_str)
? compiler_opt_str
: "" };
}

bool BlurCppExample::query_opencl_c_2_0_support()
{
return cl::util::opencl_c_version_contains(device, "2.0");
return std::make_tuple(use_local_mem, use_subgroup_exchange,
use_subgroup_exchange_relative, compiler_options);
}

void BlurCppExample::create_image_buffers()
Expand Down
6 changes: 2 additions & 4 deletions samples/core/blur/blur.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// STL includes
#include <fstream>
#include <string>

class BlurCppExample {
public:
Expand Down Expand Up @@ -39,10 +40,7 @@ class BlurCppExample {
void prepare_output_image();

// Query device and runtime capabilities
std::tuple<bool, bool, bool> query_capabilities();

// Query device support for OpenCL 2.0
bool query_opencl_c_2_0_support();
std::tuple<bool, bool, bool, std::string> query_capabilities();

void create_image_buffers();

Expand Down
66 changes: 37 additions & 29 deletions samples/core/blur/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,12 @@ cl_int dual_pass_subgroup_exchange_kernel_blur(state *const s, cl_int size,
return error;
}

cl_int opencl_version_contains(const char *dev_version,
const char *version_fragment)
{
char *found_version = strstr(dev_version, version_fragment);
return (found_version != NULL);
}

int main(int argc, char *argv[])
{
Expand Down Expand Up @@ -1051,16 +1057,23 @@ int main(int argc, char *argv[])
free(name);
}

// 5) query if OpenCL driver version is 2.0
bool opencl_c_version_2_0 = false;
// 5) Query OpenCL version to compile for.
// If no -cl-std option is specified then the highest 1.x version
// supported by each device is used to compile the program. Therefore,
// it's necessary to add the -cl-std option for 2.0 and 3.0 OpenCL
// versions.
char dev_version[64];
OCLERROR_RET(clGetDeviceInfo(s.device, CL_DEVICE_VERSION,
sizeof(dev_version), &dev_version, NULL),
error, end);
char compiler_options[1023] = "";
if (opencl_version_contains(dev_version, "3."))
{
strcat(compiler_options, "-cl-std=CL3.0 ");
}
else if (opencl_version_contains(dev_version, "2."))
{
char *driver_version = NULL;
OCLERROR_PAR(
driver_version = cl_util_get_device_info(s.device, CL_DRIVER_VERSION, &error),
error, clean);
opencl_c_version_2_0 = strcmp("2.0", driver_version) ? 0 : 1;
clean:
free(driver_version);
strcat(compiler_options, "-cl-std=CL2.0 ");
}

/// Create image buffers
Expand Down Expand Up @@ -1095,8 +1108,7 @@ int main(int argc, char *argv[])
/// Create OpenCL program
s.kernel = NULL;
s.program_size = 0;
char kernel_op[1024] = ""; // here we put some dynamic definitions
s.options = kernel_op;
s.options = compiler_options;

OCLERROR_PAR(s.kernel = cl_util_read_exe_relative_text_file(
"blur.cl", &s.program_size, &error),
Expand All @@ -1106,9 +1118,9 @@ int main(int argc, char *argv[])
(const char **)&s.kernel,
&s.program_size, &error),
error, ker);
OCLERROR_RET(cl_util_build_program(s.program, s.device, kernel_op), error,
OCLERROR_RET(cl_util_build_program(s.program, s.device, s.options), error,
prg);
kernel_op[0] = '\0';
s.options[0] = '\0';

/// Box blur
if (strstr(blur_opts.op, "box"))
Expand All @@ -1128,24 +1140,22 @@ int main(int argc, char *argv[])
error, prg);

/// Subgroup exchange in dual-pass blur
if (use_subgroup_exchange_relative && opencl_c_version_2_0)
if (use_subgroup_exchange_relative)
{
printf("Dual-pass subgroup relative exchange blur\n");

kernel_op[0] = '\0';
strcat(kernel_op, " -cl-std=CL2.0 ");
strcat(kernel_op, "-D USE_SUBGROUP_EXCHANGE_RELATIVE ");
s.options[0] = '\0';
strcat(s.options, "-D USE_SUBGROUP_EXCHANGE_RELATIVE ");
OCLERROR_RET(dual_pass_subgroup_exchange_box_blur(
&s, (cl_int)blur_opts.size),
error, prg);
}
if (use_subgroup_exchange && opencl_c_version_2_0)
if (use_subgroup_exchange)
{
printf("Dual-pass subgroup exchange blur\n");

kernel_op[0] = '\0';
strcat(kernel_op, " -cl-std=CL2.0 ");
strcat(kernel_op, "-D USE_SUBGROUP_EXCHANGE ");
s.options[0] = '\0';
strcat(s.options, "-D USE_SUBGROUP_EXCHANGE ");

OCLERROR_RET(dual_pass_subgroup_exchange_box_blur(
&s, (cl_int)blur_opts.size),
Expand Down Expand Up @@ -1183,25 +1193,23 @@ int main(int argc, char *argv[])
}

/// Subgroup exchange in dual-pass Gaussian blur
if (use_subgroup_exchange_relative && opencl_c_version_2_0)
if (use_subgroup_exchange_relative)
{
printf("Dual-pass subgroup relative exchange Gaussian blur\n");

kernel_op[0] = '\0';
strcat(kernel_op, " -cl-std=CL2.0 ");
strcat(kernel_op, "-D USE_SUBGROUP_EXCHANGE_RELATIVE ");
s.options[0] = '\0';
strcat(s.options, "-D USE_SUBGROUP_EXCHANGE_RELATIVE ");

OCLERROR_RET(dual_pass_subgroup_exchange_kernel_blur(&s, gauss_size,
gauss_kern),
error, gkrn);
}
if (use_subgroup_exchange && opencl_c_version_2_0)
if (use_subgroup_exchange)
{
printf("Dual-pass subgroup exchange Gaussian blur\n");

kernel_op[0] = '\0';
strcat(kernel_op, " -cl-std=CL2.0 ");
strcat(kernel_op, "-D USE_SUBGROUP_EXCHANGE ");
s.options[0] = '\0';
strcat(s.options, "-D USE_SUBGROUP_EXCHANGE ");

OCLERROR_RET(dual_pass_subgroup_exchange_kernel_blur(&s, gauss_size,
gauss_kern),
Expand Down
32 changes: 17 additions & 15 deletions samples/core/blur/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ int main(int argc, char* argv[])
// Query device and runtime capabilities
bool use_local_mem, use_subgroup_exchange,
use_subgroup_exchange_relative;
std::string compiler_options;
std::tie(use_local_mem, use_subgroup_exchange,
use_subgroup_exchange_relative) = blur.query_capabilities();

bool opencl_c_version_2_0 = blur.query_opencl_c_2_0_support();
use_subgroup_exchange_relative, compiler_options) =
blur.query_capabilities();

// Create image buffers used for operation. In this example input,
// output and temporary image buffers are used. Temporary buffer is used
Expand All @@ -61,7 +61,7 @@ int main(int argc, char* argv[])
// Create kernel and build program for selected device and blur.cl file
// without any options. If this function fails, ensure that the blur.cl
// file is available in place of execution.
blur.build_program("");
blur.build_program(compiler_options);

// The box blur operation will be performed if you pass "-b box" or
// don't select any option.
Expand All @@ -87,27 +87,28 @@ int main(int argc, char* argv[])
// file you can find 'USE_SUBGROUP_EXCHANGE_RELATIVE' C-like
// definition switch for blur_box_horizontal_subgroup_exchange
// function. In this case, 2 blur kernel functors are used.
if (use_subgroup_exchange_relative && opencl_c_version_2_0)
if (use_subgroup_exchange_relative)
{
std::cout << "Dual-pass subgroup relative exchange blur"
<< std::endl;
blur.build_program(
"-D USE_SUBGROUP_EXCHANGE_RELATIVE -cl-std=CL2.0 ");
blur.build_program(compiler_options
+ "-D USE_SUBGROUP_EXCHANGE_RELATIVE ");
blur.dual_pass_subgroup_exchange_box_blur();
}

// Same as the previous one, but with a different build switch. See
// the blur.cl file for more info about the switch.
if (use_subgroup_exchange && opencl_c_version_2_0)
if (use_subgroup_exchange)
{
std::cout << "Dual-pass subgroup exchange blur" << std::endl;
blur.build_program("-D USE_SUBGROUP_EXCHANGE -cl-std=CL2.0 ");
blur.build_program(compiler_options
+ "-D USE_SUBGROUP_EXCHANGE ");
blur.dual_pass_subgroup_exchange_box_blur();
}
} // Box blur

// Build default program with no kernel arguments.
blur.build_program("");
blur.build_program(compiler_options);

// The gauss blur operation is performed when the "-b gauss" option or
// no option is passed. The following examples use a manually created
Expand All @@ -133,23 +134,24 @@ int main(int argc, char* argv[])

// Similar to dual_pass_subgroup_exchange_box_blur but with a gauss
// kernel.
if (use_subgroup_exchange_relative && opencl_c_version_2_0)
if (use_subgroup_exchange_relative)
{
std::cout
<< "Dual-pass subgroup relative exchange Gaussian blur"
<< std::endl;
blur.build_program(
"-D USE_SUBGROUP_EXCHANGE_RELATIVE -cl-std=CL2.0 ");
blur.build_program(compiler_options
+ "-D USE_SUBGROUP_EXCHANGE_RELATIVE ");
blur.dual_pass_subgroup_exchange_kernel_blur();
}

// Same as the previous one, but with a different build switch. See
// the blur.cl file for more info about the switch.
if (use_subgroup_exchange && opencl_c_version_2_0)
if (use_subgroup_exchange)
{
std::cout << "Dual-pass subgroup exchange Gaussian blur"
<< std::endl;
blur.build_program("-D USE_SUBGROUP_EXCHANGE -cl-std=CL2.0 ");
blur.build_program(compiler_options
+ "-D USE_SUBGROUP_EXCHANGE ");
blur.dual_pass_subgroup_exchange_kernel_blur();
}
} // Gaussian blur
Expand Down

0 comments on commit 36e199c

Please sign in to comment.