Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added test to verify program queries after recompiling and relinking #2272

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test_conformance/compiler/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ test_definition test_list[] = {
ADD_TEST(get_program_source),
ADD_TEST(get_program_build_info),
ADD_TEST(get_program_info),
ADD_TEST(get_linked_program_info_kernel_names),

ADD_TEST(large_compile),
ADD_TEST(async_build),
Expand Down
5 changes: 4 additions & 1 deletion test_conformance/compiler/procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ extern int test_get_program_build_info(cl_device_id deviceID,
int num_elements);
extern int test_get_program_info(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);

extern int test_get_linked_program_info_kernel_names(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_large_compile(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_async_build(cl_device_id deviceID, cl_context context,
Expand Down
158 changes: 156 additions & 2 deletions test_conformance/compiler/test_build_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const char *sample_kernel_code_two_line[] = {
"\n"
"}\n" };


const char *sample_kernel_code_bad_multi_line[] = {
"__kernel void sample_test(__global float *src, __global int *dst)",
"{",
Expand All @@ -61,6 +60,37 @@ const char *sample_kernel_code_bad_multi_line[] = {
"",
"}" };

const char *sample_multi_kernel_code_AB_with_makro = R"(
__kernel void sample_test_A(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}

#ifdef USE_SAMPLE_TEST_B
__kernel void sample_test_B(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}
#endif
)";

const char *sample_multi_kernel_code_CD_with_makro = R"(
__kernel void sample_test_C(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}

#ifdef USE_SAMPLE_TEST_D
__kernel void sample_test_D(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}
#endif
)";

int test_load_program_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
Expand Down Expand Up @@ -238,7 +268,6 @@ int test_load_null_terminated_multi_line_source(cl_device_id deviceID, cl_contex
return 0;
}


int test_load_discreet_length_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int error;
Expand Down Expand Up @@ -422,6 +451,131 @@ int test_get_program_info(cl_device_id deviceID, cl_context context, cl_command_
return 0;
}

int test_get_linked_program_info_kernel_names(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements)
{
int error = CL_SUCCESS;
size_t total_kernels = 0;
size_t kernel_names_len = 0;

clProgramWrapper program_AB = clCreateProgramWithSource(
context, 1, &sample_multi_kernel_code_AB_with_makro, nullptr, &error);
test_error(error, "clCreateProgramWithSource failed");

clProgramWrapper program_CD = clCreateProgramWithSource(
context, 1, &sample_multi_kernel_code_CD_with_makro, nullptr, &error);
test_error(error, "clCreateProgramWithSource failed");

clProgramWrapper program = nullptr;

// 1) Compile and link the programs with the preprocessor macro undefined.
// Query CL_PROGRAM_NUM_KERNELS and check that the correct number is
// returned. Query CL_PROGRAM_KERNEL_NAMES and check that the right
// kernel names are returned.
{
error =
clCompileProgram(program_AB, 1, &deviceID, nullptr, 0, 0, 0, 0, 0);
test_error(error, "clCompileProgram failed");

error =
clCompileProgram(program_CD, 1, &deviceID, nullptr, 0, 0, 0, 0, 0);
test_error(error, "clCompileProgram failed");

cl_program progs[] = { program_AB, program_CD };
program =
clLinkProgram(context, 1, &deviceID, "", 2, progs, 0, 0, &error);
test_error(error, "clLinkProgram failed");

error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS,
sizeof(size_t), &total_kernels, nullptr);
test_error(error, "clGetProgramInfo failed");

test_assert_error(total_kernels == 2,
"Unexpected clGetProgramInfo result");

error = clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, 0, nullptr,
&kernel_names_len);
test_error(error, "clGetProgramInfo failed");

const size_t len = kernel_names_len + 1;
std::vector<char> kernel_names(len, '\0');
error =
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
kernel_names.data(), &kernel_names_len);
Comment on lines +502 to +506
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're interested, it's possible to read into a std::string directly (for C++11 and newer, which we are), vs. reading into a std::vector and then creating a std::string from it.

Something like:

Suggested change
const size_t len = kernel_names_len + 1;
std::vector<char> kernel_names(len, '\0');
error =
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
kernel_names.data(), &kernel_names_len);
std::string kernel_names(kernel_names_len, '\0');
error =
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
&kernel_names[0], nullptr);
kernel_names.pop_back(); // remove the final '\0'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Obviously I can apply your suggestion but some time ago I was asked by one of reviewers here in CTS project to use std::vector<char> in such cases due to the concerns around spec requirement for std::string to have internally continuous chunk of memory. As far as I learnt later it was cleared up at some point in C++11 or 14 spec, still it seems like std::vector<char> delivers full control over underlying buffer. Just let me know to do the change.

test_error(error, "Unable to get kernel names list.");
std::string program_names = kernel_names.data();

std::vector<std::string> expected_names = { "sample_test_A",
"sample_test_C" };
for (const auto &name : expected_names)
{
test_assert_error(program_names.find(name) != std::string::npos,
"Unexpected kernel name");
}

std::vector<std::string> unexpected_names = { "sample_test_B",
"sample_test_D" };
for (const auto &name : unexpected_names)
{
test_assert_error(program_names.find(name) == std::string::npos,
"Unexpected kernel name");
}
}

// 2) Compile and link the programs with the preprocessor macro defined.
// Query CL_PROGRAM_NUM_KERNELS and check that the correct number is
// returned. Query CL_PROGRAM_KERNEL_NAMES and check that the right
// kernel names are returned.
{
const char *build_options_B = "-DUSE_SAMPLE_TEST_B";
error = clCompileProgram(program_AB, 1, &deviceID, build_options_B, 0,
0, 0, 0, 0);
test_error(error, "clCompileProgram failed");

const char *build_options_D = "-DUSE_SAMPLE_TEST_D";
error = clCompileProgram(program_CD, 1, &deviceID, build_options_D, 0,
0, 0, 0, 0);
test_error(error, "clCompileProgram failed");

cl_program progs[] = { program_AB, program_CD };
program =
clLinkProgram(context, 1, &deviceID, "", 2, progs, 0, 0, &error);
test_error(error, "clLinkProgram failed");

error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS,
sizeof(size_t), &total_kernels, nullptr);
test_error(error, "clGetProgramInfo failed");

test_assert_error(total_kernels == 4,
"Unexpected clGetProgramInfo result");

error = clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, 0, nullptr,
&kernel_names_len);
test_error(error, "clGetProgramInfo failed");

std::vector<std::string> expected_names = {
"sample_test_A", "sample_test_B", "sample_test_C", "sample_test_D"
};

const size_t len = kernel_names_len + 1;
std::vector<char> kernel_names(len, '\0');
error =
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
kernel_names.data(), &kernel_names_len);
test_error(error, "Unable to get kernel names list.");

std::string program_names = kernel_names.data();
for (const auto &name : expected_names)
{
test_assert_error(program_names.find(name) != std::string::npos,
"Unexpected kernel name");
}
}
return TEST_PASS;
}

int test_get_program_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_program program;
Expand Down
Loading