Initial open source release of OpenCL 2.2 CTS.

This commit is contained in:
Kedar Patil
2017-05-16 18:25:37 +05:30
parent 6911ba5116
commit 2821bf1323
1035 changed files with 343518 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
set(MODULE_NAME pipes)
set(${MODULE_NAME}_SOURCES
main.c
test_pipe_read_write.c
test_pipe_info.c
test_pipe_limits.c
test_pipe_query_functions.c
test_pipe_readwrite_errors.c
test_pipe_subgroups.c
../../test_common/harness/errorHelpers.c
../../test_common/harness/threadTesting.c
../../test_common/harness/testHarness.c
../../test_common/harness/kernelHelpers.c
../../test_common/harness/typeWrappers.cpp
../../test_common/harness/mt19937.c
../../test_common/harness/conversions.c
../../test_common/harness/msvc9.c
../../test_common/harness/parseParameters.cpp
)
include(../CMakeCommon.txt)

View File

@@ -0,0 +1,130 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _KERNELS_H_
#define _KERNELS_H_
static const char* pipe_readwrite_struct_kernel_code = {
"typedef struct{\n"
"char a;\n"
"int b;\n"
"}TestStruct;\n"
"__kernel void test_pipe_write_struct(__global TestStruct *src, __write_only pipe TestStruct out_pipe)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id; \n"
"\n"
" res_id = reserve_write_pipe(out_pipe, 1);\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" write_pipe(out_pipe, res_id, 0, &src[gid]);\n"
" commit_write_pipe(out_pipe, res_id);\n"
" }\n"
"}\n"
"\n"
"__kernel void test_pipe_read_struct(__read_only pipe TestStruct in_pipe, __global TestStruct *dst)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id; \n"
"\n"
" res_id = reserve_read_pipe(in_pipe, 1);\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" read_pipe(in_pipe, res_id, 0, &dst[gid]);\n"
" commit_read_pipe(in_pipe, res_id);\n"
" }\n"
"}\n" };
static const char* pipe_workgroup_readwrite_struct_kernel_code = {
"typedef struct{\n"
"char a;\n"
"int b;\n"
"}TestStruct;\n"
"__kernel void test_pipe_workgroup_write_struct(__global TestStruct *src, __write_only pipe TestStruct out_pipe)\n"
"{\n"
" int gid = get_global_id(0);\n"
" __local reserve_id_t res_id; \n"
"\n"
" res_id = work_group_reserve_write_pipe(out_pipe, get_local_size(0));\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" write_pipe(out_pipe, res_id, get_local_id(0), &src[gid]);\n"
" work_group_commit_write_pipe(out_pipe, res_id);\n"
" }\n"
"}\n"
"\n"
"__kernel void test_pipe_workgroup_read_struct(__read_only pipe TestStruct in_pipe, __global TestStruct *dst)\n"
"{\n"
" int gid = get_global_id(0);\n"
" __local reserve_id_t res_id; \n"
"\n"
" res_id = work_group_reserve_read_pipe(in_pipe, get_local_size(0));\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" read_pipe(in_pipe, res_id, get_local_id(0), &dst[gid]);\n"
" work_group_commit_read_pipe(in_pipe, res_id);\n"
" }\n"
"}\n" };
static const char* pipe_subgroup_readwrite_struct_kernel_code = {
"typedef struct{\n"
"char a;\n"
"int b;\n"
"}TestStruct;\n"
"#pragma OPENCL EXTENSION cl_khr_subgroups : enable\n"
"__kernel void test_pipe_subgroup_write_struct(__global TestStruct *src, __write_only pipe TestStruct out_pipe)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id; \n"
"\n"
" res_id = sub_group_reserve_write_pipe(out_pipe, get_sub_group_size());\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" write_pipe(out_pipe, res_id, get_sub_group_local_id(), &src[gid]);\n"
" sub_group_commit_write_pipe(out_pipe, res_id);\n"
" }\n"
"}\n"
"\n"
"__kernel void test_pipe_subgroup_read_struct(__read_only pipe TestStruct in_pipe, __global TestStruct *dst)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id; \n"
"\n"
" res_id = sub_group_reserve_read_pipe(in_pipe, get_sub_group_size());\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" read_pipe(in_pipe, res_id, get_sub_group_local_id(), &dst[gid]);\n"
" sub_group_commit_read_pipe(in_pipe, res_id);\n"
" }\n"
"}\n" };
static const char* pipe_convenience_readwrite_struct_kernel_code = {
"typedef struct{\n"
"char a;\n"
"int b;\n"
"}TestStruct;\n"
"__kernel void test_pipe_convenience_write_struct(__global TestStruct *src, __write_only pipe TestStruct out_pipe)\n"
"{\n"
" int gid = get_global_id(0);\n"
" write_pipe(out_pipe, &src[gid]);\n"
"}\n"
"\n"
"__kernel void test_pipe_convenience_read_struct(__read_only pipe TestStruct in_pipe, __global TestStruct *dst)\n"
"{\n"
" int gid = get_global_id(0);\n"
" read_pipe(in_pipe, &dst[gid]);\n"
"}\n" };
#endif //_KERNELS_H_

View File

@@ -0,0 +1,147 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/compat.h"
#include <stdio.h>
#include <string.h>
#include "procs.h"
#include "../../test_common/harness/testHarness.h"
basefn pipefn_list[] = {
test_pipe_readwrite_int,
test_pipe_readwrite_uint,
test_pipe_readwrite_long,
test_pipe_readwrite_ulong,
test_pipe_readwrite_short,
test_pipe_readwrite_ushort,
test_pipe_readwrite_float,
test_pipe_readwrite_half,
test_pipe_readwrite_char,
test_pipe_readwrite_uchar,
test_pipe_readwrite_double,
test_pipe_readwrite_struct,
test_pipe_workgroup_readwrite_int,
test_pipe_workgroup_readwrite_uint,
test_pipe_workgroup_readwrite_long,
test_pipe_workgroup_readwrite_ulong,
test_pipe_workgroup_readwrite_short,
test_pipe_workgroup_readwrite_ushort,
test_pipe_workgroup_readwrite_float,
test_pipe_workgroup_readwrite_half,
test_pipe_workgroup_readwrite_char,
test_pipe_workgroup_readwrite_uchar,
test_pipe_workgroup_readwrite_double,
test_pipe_workgroup_readwrite_struct,
test_pipe_subgroup_readwrite_int,
test_pipe_subgroup_readwrite_uint,
test_pipe_subgroup_readwrite_long,
test_pipe_subgroup_readwrite_ulong,
test_pipe_subgroup_readwrite_short,
test_pipe_subgroup_readwrite_ushort,
test_pipe_subgroup_readwrite_float,
test_pipe_subgroup_readwrite_half,
test_pipe_subgroup_readwrite_char,
test_pipe_subgroup_readwrite_uchar,
test_pipe_subgroup_readwrite_double,
test_pipe_subgroup_readwrite_struct,
test_pipe_convenience_readwrite_int,
test_pipe_convenience_readwrite_uint,
test_pipe_convenience_readwrite_long,
test_pipe_convenience_readwrite_ulong,
test_pipe_convenience_readwrite_short,
test_pipe_convenience_readwrite_ushort,
test_pipe_convenience_readwrite_float,
test_pipe_convenience_readwrite_half,
test_pipe_convenience_readwrite_char,
test_pipe_convenience_readwrite_uchar,
test_pipe_convenience_readwrite_double,
test_pipe_convenience_readwrite_struct,
test_pipe_info,
test_pipe_max_args,
test_pipe_max_packet_size,
test_pipe_max_active_reservations,
test_pipe_query_functions,
test_pipe_readwrite_errors,
test_pipe_subgroups_divergence
};
const char *pipefn_names[] = {
"pipe_readwrite_int",
"pipe_readwrite_uint",
"pipe_readwrite_long",
"pipe_readwrite_ulong",
"pipe_readwrite_short",
"pipe_readwrite_ushort",
"pipe_readwrite_float",
"pipe_readwrite_half",
"pipe_readwrite_char",
"pipe_readwrite_uchar",
"pipe_readwrite_double",
"pipe_readwrite_struct",
"pipe_workgroup_readwrite_int",
"pipe_workgroup_readwrite_uint",
"pipe_workgroup_readwrite_long",
"pipe_workgroup_readwrite_ulong",
"pipe_workgroup_readwrite_short",
"pipe_workgroup_readwrite_ushort",
"pipe_workgroup_readwrite_float",
"pipe_workgroup_readwrite_half",
"pipe_workgroup_readwrite_char",
"pipe_workgroup_readwrite_uchar",
"pipe_workgroup_readwrite_double",
"pipe_workgroup_readwrite_struct",
"pipe_subgroup_readwrite_int",
"pipe_subgroup_readwrite_uint",
"pipe_subgroup_readwrite_long",
"pipe_subgroup_readwrite_ulong",
"pipe_subgroup_readwrite_short",
"pipe_subgroup_readwrite_ushort",
"pipe_subgroup_readwrite_float",
"pipe_subgroup_readwrite_half",
"pipe_subgroup_readwrite_char",
"pipe_subgroup_readwrite_uchar",
"pipe_subgroup_readwrite_double",
"pipe_subgroup_readwrite_struct",
"pipe_convenience_readwrite_int",
"pipe_convenience_readwrite_uint",
"pipe_convenience_readwrite_long",
"pipe_convenience_readwrite_ulong",
"pipe_convenience_readwrite_short",
"pipe_convenience_readwrite_ushort",
"pipe_convenience_readwrite_float",
"pipe_convenience_readwrite_half",
"pipe_convenience_readwrite_char",
"pipe_convenience_readwrite_uchar",
"pipe_convenience_readwrite_double",
"pipe_convenience_readwrite_struct",
"pipe_info",
"pipe_max_args",
"pipe_max_packet_size",
"pipe_max_active_reservations",
"pipe_query_functions",
"pipe_readwrite_errors",
"pipe_subgroups_divergence",
};
ct_assert((sizeof(pipefn_names) / sizeof(pipefn_names[0])) == (sizeof(pipefn_list) / sizeof(pipefn_list[0])));
int num_pipefns = sizeof(pipefn_names) / sizeof(char *);
int main( int argc, const char *argv[] )
{
return runTestHarness( argc, argv, num_pipefns, pipefn_list, pipefn_names,
false, false, 0 );
}

View File

@@ -0,0 +1,92 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef __PROCS_H__
#define __PROCS_H__
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/testHarness.h"
#include "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/mt19937.h"
#include "../../test_common/harness/conversions.h"
#ifndef __APPLE__
#include <CL/cl.h>
#endif
extern int test_pipe_readwrite_int( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_uint( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_long( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_ulong( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_short( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_ushort( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_float( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_half( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_char( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_uchar( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_double( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_readwrite_struct( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_int( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_uint( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_long( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_ulong( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_short( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_ushort( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_float( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_half( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_char( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_uchar( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_double( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_workgroup_readwrite_struct( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_int( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_uint( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_long( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_ulong( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_short( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_ushort( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_float( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_half( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_char( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_uchar( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_double( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_subgroup_readwrite_struct( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_int( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_uint( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_long( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_ulong( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_short( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_ushort( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_float( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_half( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_char( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_uchar( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_double( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_convenience_readwrite_struct( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_pipe_max_args(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_pipe_max_packet_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_pipe_max_active_reservations(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_pipe_query_functions(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_pipe_readwrite_errors(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_pipe_subgroups_divergence(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
#endif // #ifndef __PROCS_H__

View File

@@ -0,0 +1,109 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "procs.h"
const char* pipe_kernel_code = {
"__kernel void pipe_kernel(__write_only pipe int out_pipe)\n"
"{}\n" };
int test_pipe_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
{
cl_mem pipe;
cl_int err;
cl_uint pipe_width = 512;
cl_uint pipe_depth = 1024;
cl_uint returnVal;
cl_program program;
cl_kernel kernel;
pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, pipe_width, pipe_depth, NULL, &err);
test_error(err, "clCreatePipe failed.");
err = clGetPipeInfo(pipe, CL_PIPE_PACKET_SIZE, sizeof(pipe_width), (void *)&returnVal, NULL);
if ( err )
{
log_error( "Error calling clGetPipeInfo(): %d\n", err );
clReleaseMemObject(pipe);
return -1;
}
if(pipe_width != returnVal)
{
log_error( "Error in clGetPipeInfo() check of pipe packet size\n" );
clReleaseMemObject(pipe);
return -1;
}
else
{
log_info( " CL_PIPE_PACKET_SIZE passed.\n" );
}
err = clGetPipeInfo(pipe, CL_PIPE_MAX_PACKETS, sizeof(pipe_depth), (void *)&returnVal, NULL);
if ( err )
{
log_error( "Error calling clGetPipeInfo(): %d\n", err );
clReleaseMemObject(pipe);
return -1;
}
if(pipe_depth != returnVal)
{
log_error( "Error in clGetPipeInfo() check of pipe max packets\n" );
clReleaseMemObject(pipe);
return -1;
}
else
{
log_info( " CL_PIPE_MAX_PACKETS passed.\n" );
}
err = create_single_kernel_helper_with_build_options(context, &program, &kernel, 1, (const char**)&pipe_kernel_code, "pipe_kernel", "-cl-std=CL2.0 -cl-kernel-arg-info");
if(err)
{
clReleaseMemObject(pipe);
print_error(err, "Error creating program\n");
return -1;
}
cl_kernel_arg_type_qualifier arg_type_qualifier = 0;
cl_kernel_arg_type_qualifier expected_type_qualifier = CL_KERNEL_ARG_TYPE_PIPE;
err = clGetKernelArgInfo( kernel, 0, CL_KERNEL_ARG_TYPE_QUALIFIER, sizeof(arg_type_qualifier), &arg_type_qualifier, NULL );
if(err)
{
clReleaseMemObject(pipe);
clReleaseKernel(kernel);
clReleaseProgram(program);
print_error(err, "clSetKernelArg failed\n");
return -1;
}
err = (arg_type_qualifier != expected_type_qualifier);
if(err)
{
clReleaseMemObject(pipe);
clReleaseKernel(kernel);
clReleaseProgram(program);
print_error(err, "ERROR: Bad type qualifier\n");
return -1;
}
// cleanup
clReleaseMemObject(pipe);
clReleaseKernel(kernel);
clReleaseProgram(program);
return err;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,544 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/compat.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
#include "../../test_common/harness/errorHelpers.h"
#define TEST_PRIME_INT ((1<<16)+1)
const char* pipe_query_functions_kernel_code = {
"__kernel void test_pipe_write(__global int *src, __write_only pipe int out_pipe)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id;\n"
" res_id = reserve_write_pipe(out_pipe, 1);\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" write_pipe(out_pipe, res_id, 0, &src[gid]);\n"
" commit_write_pipe(out_pipe, res_id);\n"
" }\n"
"}\n"
"\n"
"__kernel void test_pipe_query_functions(__write_only pipe int out_pipe, __global int *num_packets, __global int *max_packets)\n"
"{\n"
" *max_packets = get_pipe_max_packets(out_pipe);\n"
" *num_packets = get_pipe_num_packets(out_pipe);\n"
"}\n"
"\n"
"__kernel void test_pipe_read(__read_only pipe int in_pipe, __global int *dst)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id;\n"
" res_id = reserve_read_pipe(in_pipe, 1);\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" read_pipe(in_pipe, res_id, 0, &dst[gid]);\n"
" commit_read_pipe(in_pipe, res_id);\n"
" }\n"
"}\n" };
static int verify_result(void *ptr1, void *ptr2, int n)
{
int i, sum_output = 0;
cl_int *outptr1 = (int *)ptr1;
cl_int *outptr2 = (int *)ptr2;
int cmp_val = ((n*3)/2) * TEST_PRIME_INT;
for(i = 0; i < n/2; i++)
{
sum_output += outptr1[i];
}
for(i = 0; i < n; i++)
{
sum_output += outptr2[i];
}
if(sum_output != cmp_val){
return -1;
}
return 0;
}
int test_pipe_query_functions(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem pipe;
cl_mem buffers[4];
void *outptr1;
void *outptr2;
cl_int *inptr;
cl_program program;
cl_kernel kernel[3];
size_t global_work_size[3];
size_t half_global_work_size[3];
size_t global_work_size_pipe_query[3];
cl_int pipe_max_packets, pipe_num_packets;
cl_int err;
cl_int size;
cl_int i;
cl_event producer_sync_event = NULL;
cl_event consumer_sync_event = NULL;
cl_event pipe_query_sync_event = NULL;
cl_event pipe_read_sync_event = NULL;
MTdata d = init_genrand( gRandomSeed );
const char* kernelName[] = {"test_pipe_write", "test_pipe_read", "test_pipe_query_functions"};
size_t min_alignment = get_min_alignment(context);
size = sizeof(int) * num_elements;
global_work_size[0] = (cl_uint)num_elements;
half_global_work_size[0] = (cl_uint)(num_elements / 2);
global_work_size_pipe_query[0] = 1;
inptr = (int *)align_malloc(size, min_alignment);
for(i = 0; i < num_elements; i++){
inptr[i] = TEST_PRIME_INT;
}
buffers[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, inptr, &err);
if(err){
clReleaseMemObject(buffers[0]);
print_error(err, " clCreateBuffer failed\n");
return -1;
}
outptr1 = align_malloc(size/2, min_alignment);
outptr2 = align_malloc(size, min_alignment);
buffers[1] = clCreateBuffer(context, CL_MEM_HOST_READ_ONLY, size, NULL, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
align_free( outptr1 );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
buffers[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
align_free( outptr1 );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
buffers[3] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int), NULL, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
align_free( outptr1 );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, sizeof(int), num_elements, NULL, &err);
if(err){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
align_free( outptr1 );
clReleaseMemObject(pipe);
print_error(err, " clCreatePipe failed\n");
return -1;
}
// Create producer kernel
err = create_single_kernel_helper_with_build_options(context, &program, &kernel[0], 1, (const char**)&pipe_query_functions_kernel_code, kernelName[0], "-cl-std=CL2.0");
if(err){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
align_free(outptr1);
print_error(err, "Error creating program\n");
return -1;
}
//Create consumer kernel
kernel[1] = clCreateKernel(program, kernelName[1], &err);
if( kernel[1] == NULL || err != CL_SUCCESS)
{
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
align_free(outptr1);
print_error(err, "Error creating kernel\n");
return -1;
}
//Create pipe query functions kernel
kernel[2] = clCreateKernel(program, kernelName[2], &err);
if( kernel[1] == NULL || err != CL_SUCCESS)
{
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
align_free(outptr1);
print_error(err, "Error creating kernel\n");
return -1;
}
err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), (void*)&buffers[0]);
err |= clSetKernelArg(kernel[0], 1, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[1], 0, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[1], 1, sizeof(cl_mem), (void*)&buffers[1]);
err |= clSetKernelArg(kernel[2], 0, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[2], 1, sizeof(cl_mem), (void*)&buffers[2]);
err |= clSetKernelArg(kernel[2], 2, sizeof(cl_mem), (void*)&buffers[3]);
if ( err != CL_SUCCESS ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseProgram(program);
align_free(outptr1);
print_error(err, " clSetKernelArg failed\n");
return -1;
}
// Launch Producer kernel
err = clEnqueueNDRangeKernel( queue, kernel[0], 1, NULL, global_work_size, NULL, 0, NULL, &producer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
// Launch Pipe query kernel
err = clEnqueueNDRangeKernel( queue, kernel[2], 1, NULL, global_work_size_pipe_query, NULL, 1, &producer_sync_event, &pipe_query_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, sizeof(cl_int), &pipe_num_packets, 1, &pipe_query_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[3], true, 0, sizeof(cl_int), &pipe_max_packets, 1, &pipe_query_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
if(pipe_num_packets != num_elements || pipe_max_packets != num_elements)
{
log_error("test_pipe_query_functions failed\n");
return -1;
}
// Launch Consumer kernel with half the previous global size
err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, half_global_work_size, NULL, 1, &producer_sync_event, &consumer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[1], true, 0, size / 2, outptr1, 1, &consumer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
// Launch Pipe query kernel
err = clEnqueueNDRangeKernel( queue, kernel[2], 1, NULL, global_work_size_pipe_query, NULL, 1, &consumer_sync_event, &pipe_query_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, sizeof(cl_int), &pipe_num_packets, 1, &pipe_query_sync_event, &pipe_read_sync_event);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
// After consumer kernel consumes num_elements/2 from the pipe,
// there are (num_elements - num_elements/2) remaining package in the pipe.
if(pipe_num_packets != (num_elements - num_elements/2))
{
log_error("test_pipe_query_functions failed\n");
return -1;
}
// Launch Producer kernel to fill the pipe again
global_work_size[0] = pipe_num_packets;
err = clEnqueueNDRangeKernel( queue, kernel[0], 1, NULL, global_work_size, NULL, 1, &pipe_read_sync_event, &producer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
// Launch Pipe query kernel
err = clEnqueueNDRangeKernel( queue, kernel[2], 1, NULL, global_work_size_pipe_query, NULL, 1, &producer_sync_event, &pipe_query_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, sizeof(cl_int), &pipe_num_packets, 1, &pipe_query_sync_event, &pipe_read_sync_event);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
if(pipe_num_packets != num_elements)
{
log_error("test_pipe_query_functions failed\n");
return -1;
}
// Launch Consumer kernel to consume all packets from pipe
global_work_size[0] = pipe_num_packets;
err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, global_work_size, NULL, 1, &pipe_read_sync_event, &consumer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[1], true, 0, size, outptr2, 1, &consumer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed\n" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return -1;
}
if( verify_result(outptr1, outptr2, num_elements )){
log_error("test_pipe_query_functions failed\n");
return -1;
}
else {
log_info("test_pipe_query_functions passed\n");
}
//cleanup
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(buffers[3]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseKernel(kernel[2]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseEvent(pipe_query_sync_event);
clReleaseEvent(pipe_read_sync_event);
clReleaseProgram(program);
align_free(outptr1);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,312 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/compat.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
#include "../../test_common/harness/errorHelpers.h"
const char* pipe_readwrite_errors_kernel_code = {
"__kernel void test_pipe_write_error(__global int *src, __write_only pipe int out_pipe, __global int *status)\n"
"{\n"
" int gid = get_global_id(0);\n"
" int reserve_idx;\n"
" reserve_id_t res_id;\n"
"\n"
" res_id = reserve_write_pipe(out_pipe, 1);\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" write_pipe(out_pipe, res_id, 0, &src[gid]);\n"
" commit_write_pipe(out_pipe, res_id);\n"
" }\n"
" else\n"
" {\n"
" *status = -1;\n"
" }\n"
"}\n"
"\n"
"__kernel void test_pipe_read_error(__read_only pipe int in_pipe, __global int *dst, __global int *status)\n"
"{\n"
" int gid = get_global_id(0);\n"
" int reserve_idx;\n"
" reserve_id_t res_id;\n"
"\n"
" res_id = reserve_read_pipe(in_pipe, 1);\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" read_pipe(in_pipe, res_id, 0, &dst[gid]);\n"
" commit_read_pipe(in_pipe, res_id);\n"
" }\n"
" else\n"
" {\n"
" *status = -1;\n"
" }\n"
"}\n"
};
int test_pipe_readwrite_errors(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem pipe;
cl_mem buffers[3];
void *outptr;
cl_int *inptr;
cl_program program;
cl_kernel kernel[2];
size_t global_work_size[3];
cl_int err;
cl_int size;
cl_int i;
cl_int status = 0;
cl_event producer_sync_event;
cl_event consumer_sync_event;
MTdata d = init_genrand( gRandomSeed );
const char* kernelName[] = {"test_pipe_write_error", "test_pipe_read_error"};
size_t min_alignment = get_min_alignment(context);
global_work_size[0] = num_elements;
size = num_elements * sizeof(cl_int);
inptr = (cl_int *)align_malloc(size, min_alignment);
for(i = 0; i < (cl_int)(size / sizeof(int)); i++){
inptr[i] = (int)genrand_int32(d);
}
buffers[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, inptr, &err);
if(err){
clReleaseMemObject(buffers[0]);
print_error(err, " clCreateBuffer failed\n");
return -1;
}
outptr = align_malloc(size, min_alignment);
buffers[1] = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, size, outptr, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
align_free( outptr );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
buffers[2] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(int), &status, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
align_free( outptr );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
//Pipe created with max_packets less than global size
pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, sizeof(int), num_elements - (num_elements/2), NULL, &err);
if(err){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
align_free( outptr );
clReleaseMemObject(pipe);
print_error(err, " clCreatePipe failed\n");
return -1;
}
// Create producer kernel
err = create_single_kernel_helper_with_build_options(context, &program, &kernel[0], 1, (const char**)&pipe_readwrite_errors_kernel_code, kernelName[0], "-cl-std=CL2.0");
if(err){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
align_free(outptr);
print_error(err, "Error creating program\n");
return -1;
}
//Create consumer kernel
kernel[1] = clCreateKernel(program, kernelName[1], &err);
if( kernel[1] == NULL || err != CL_SUCCESS)
{
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
align_free(outptr);
print_error(err, "Error creating kernel\n");
return -1;
}
err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), (void*)&buffers[0]);
err |= clSetKernelArg(kernel[0], 1, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[0], 2, sizeof(cl_mem), (void*)&buffers[2]);
err |= clSetKernelArg(kernel[1], 0, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[1], 1, sizeof(cl_mem), (void*)&buffers[1]);
err |= clSetKernelArg(kernel[1], 2, sizeof(cl_mem), (void*)&buffers[2]);
if ( err != CL_SUCCESS ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program);
align_free(outptr);
print_error(err, " clSetKernelArg failed");
return -1;
}
// Launch Consumer kernel for empty pipe
err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, global_work_size, NULL, 0, NULL, &consumer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, sizeof(status), &status, 1, &consumer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
if(status == 0){
log_error("test_pipe_readwrite_errors failed\n");
return -1;
}
else{
status = 0;
}
// Launch Producer kernel
err = clEnqueueNDRangeKernel( queue, kernel[0], 1, NULL, global_work_size, NULL, 0, NULL, &producer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, sizeof(status), &status, 1, &producer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
if(status == 0){
log_error("test_pipe_readwrite_errors failed\n");
return -1;
}
else{
status = 0;
}
// Launch Consumer kernel
err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, global_work_size, NULL, 1, &producer_sync_event, &consumer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, sizeof(status), &status, 1, &consumer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
if(status == 0)
{
log_error("test_pipe_readwrite_errors failed\n");
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
log_info("test_pipe_readwrite_errors passed\n");
//cleanup
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return 0;
}

View File

@@ -0,0 +1,339 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/compat.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
#include "../../test_common/harness/errorHelpers.h"
#define TEST_INT_VALUE 100
const char* pipe_subgroups_kernel_code = {
"#pragma OPENCL EXTENSION cl_khr_subgroups : enable\n"
"__kernel void test_pipe_subgroups_divergence_write(__global int *src, __write_only pipe int out_pipe, __global int *active_work_item_buffer)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id; \n"
"\n"
" if(get_sub_group_id() % 2 == 0)\n"
" {\n"
" active_work_item_buffer[gid] = 1;\n"
" res_id = sub_group_reserve_write_pipe(out_pipe, get_sub_group_size());\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" write_pipe(out_pipe, res_id, get_sub_group_local_id(), &src[gid]);\n"
" sub_group_commit_write_pipe(out_pipe, res_id);\n"
" }\n"
" }\n"
"}\n"
"\n"
"__kernel void test_pipe_subgroups_divergence_read(__read_only pipe int in_pipe, __global int *dst)\n"
"{\n"
" int gid = get_global_id(0);\n"
" reserve_id_t res_id; \n"
"\n"
" if(get_sub_group_id() % 2 == 0)\n"
" {\n"
" res_id = sub_group_reserve_read_pipe(in_pipe, get_sub_group_size());\n"
" if(is_valid_reserve_id(res_id))\n"
" {\n"
" read_pipe(in_pipe, res_id, get_sub_group_local_id(), &dst[gid]);\n"
" sub_group_commit_read_pipe(in_pipe, res_id);\n"
" }\n"
" }\n"
"}\n"
};
static int verify_result(void *ptr1, void *ptr2, int n)
{
int i;
int sum_input = 0, sum_output = 0;
cl_int *inptr = (cl_int *)ptr1;
cl_int *outptr = (cl_int *)ptr2;
for(i = 0; i < n; i++)
{
sum_input += inptr[i];
}
sum_input *= TEST_INT_VALUE;
for(i = 0; i < n; i++)
{
if(outptr[i] == TEST_INT_VALUE){
sum_output += outptr[i];
}
}
if(sum_input != sum_output){
return -1;
}
return 0;
}
int test_pipe_subgroups_divergence(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem pipe;
cl_mem buffers[3];
cl_int *outptr;
cl_int *inptr;
cl_int *active_work_item_buffer;
cl_program program;
cl_kernel kernel[2];
size_t global_work_size[3];
size_t local_work_size[3];
cl_int err;
cl_int size;
int i;
size_t subgroup_count;
cl_event producer_sync_event = NULL;
cl_event consumer_sync_event = NULL;
const char* kernelName[] = {"test_pipe_subgroups_divergence_write", "test_pipe_subgroups_divergence_read"};
size_t min_alignment = get_min_alignment(context);
global_work_size[0] = (cl_uint)num_elements;
if(!is_extension_available(deviceID, "cl_khr_subgroups"))
{
log_info("cl_khr_subgroups is not supported on this platoform. Skipping test.\n");
return CL_SUCCESS;
}
size = sizeof(int) * num_elements;
inptr = (cl_int *)align_malloc(size, min_alignment);
outptr = (cl_int *)align_malloc(size, min_alignment);
active_work_item_buffer = (cl_int *)align_malloc(size, min_alignment);
for(i = 0; i < num_elements; i++){
inptr[i] = TEST_INT_VALUE;
outptr[i] = 0;
active_work_item_buffer[i] = 0;
}
buffers[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, inptr, &err);
if(err){
clReleaseMemObject(buffers[0]);
print_error(err, " clCreateBuffer failed\n");
return -1;
}
buffers[1] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, outptr, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
align_free( outptr );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
buffers[2] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, size, active_work_item_buffer, &err);
if ( err ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
align_free( outptr );
print_error(err, " clCreateBuffer failed\n" );
return -1;
}
pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, sizeof(int), num_elements, NULL, &err);
if(err){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
align_free( outptr );
clReleaseMemObject(pipe);
print_error(err, " clCreatePipe failed\n");
return -1;
}
// Create producer kernel
err = create_single_kernel_helper_with_build_options(context, &program, &kernel[0], 1, (const char**)&pipe_subgroups_kernel_code, kernelName[0], "-cl-std=CL2.0");
if(err){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
align_free(outptr);
print_error(err, "Error creating program\n");
return -1;
}
//Create consumer kernel
kernel[1] = clCreateKernel(program, kernelName[1], &err);
if( kernel[1] == NULL || err != CL_SUCCESS)
{
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
align_free(outptr);
print_error(err, "Error creating kernel\n");
return -1;
}
err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), (void*)&buffers[0]);
err |= clSetKernelArg(kernel[0], 1, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[0], 2, sizeof(cl_mem), (void*)&buffers[2]);
err |= clSetKernelArg(kernel[1], 0, sizeof(cl_mem), (void*)&pipe);
err |= clSetKernelArg(kernel[1], 1, sizeof(cl_mem), (void*)&buffers[1]);
if ( err != CL_SUCCESS ){
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program);
align_free(outptr);
print_error(err, " clSetKernelArg failed");
return -1;
}
err = get_max_common_work_group_size( context, kernel[0], global_work_size[0], &local_work_size[0] );
if( err != CL_SUCCESS)
{
test_error( err, "Unable to get work group size to use" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
cl_platform_id platform;
err = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL);
clGetKernelSubGroupInfoKHR_fn clGetKernelSubGroupInfoKHR = (clGetKernelSubGroupInfoKHR_fn) clGetExtensionFunctionAddressForPlatform(platform, "clGetKernelSubGroupInfoKHR");
err = clGetKernelSubGroupInfoKHR(kernel[0], deviceID, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, sizeof(local_work_size[0]), &local_work_size[0], sizeof(subgroup_count), &subgroup_count, NULL);
if(subgroup_count <= 1)
{
log_info("Only 1 subgroup per workgroup for the kernel. Hence no divergence among subgroups possible. Skipping test.\n");
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program);
align_free(outptr);
return CL_SUCCESS;
}
// Launch Producer kernel
err = clEnqueueNDRangeKernel( queue, kernel[0], 1, NULL, global_work_size, local_work_size, 0, NULL, &producer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[2], true, 0, size, active_work_item_buffer, 1, &producer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
// Launch Consumer kernel
err = clEnqueueNDRangeKernel( queue, kernel[1], 1, NULL, global_work_size, local_work_size, 1, &producer_sync_event, &consumer_sync_event );
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueNDRangeKernel failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
err = clEnqueueReadBuffer(queue, buffers[1], true, 0, size, outptr, 1, &consumer_sync_event, NULL);
if ( err != CL_SUCCESS ){
print_error( err, " clEnqueueReadBuffer failed" );
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
if( verify_result( active_work_item_buffer, outptr, num_elements)){
log_error("test_pipe_subgroups_divergence failed\n");
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return -1;
}
else {
log_info("test_pipe_subgroups_divergence passed\n");
}
//cleanup
clReleaseMemObject(buffers[0]);
clReleaseMemObject(buffers[1]);
clReleaseMemObject(buffers[2]);
clReleaseMemObject(pipe);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseEvent(producer_sync_event);
clReleaseEvent(consumer_sync_event);
clReleaseProgram(program);
align_free(outptr);
return 0;
}