mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Initial open source release of OpenCL 2.2 CTS.
This commit is contained in:
22
test_conformance/pipes/CMakeLists.txt
Normal file
22
test_conformance/pipes/CMakeLists.txt
Normal 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)
|
||||
130
test_conformance/pipes/kernels.h
Normal file
130
test_conformance/pipes/kernels.h
Normal 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_
|
||||
147
test_conformance/pipes/main.c
Normal file
147
test_conformance/pipes/main.c
Normal 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 );
|
||||
}
|
||||
92
test_conformance/pipes/procs.h
Normal file
92
test_conformance/pipes/procs.h
Normal 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__
|
||||
|
||||
109
test_conformance/pipes/test_pipe_info.c
Normal file
109
test_conformance/pipes/test_pipe_info.c
Normal 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;
|
||||
|
||||
}
|
||||
1085
test_conformance/pipes/test_pipe_limits.c
Normal file
1085
test_conformance/pipes/test_pipe_limits.c
Normal file
File diff suppressed because it is too large
Load Diff
544
test_conformance/pipes/test_pipe_query_functions.c
Normal file
544
test_conformance/pipes/test_pipe_query_functions.c
Normal 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;
|
||||
}
|
||||
|
||||
1809
test_conformance/pipes/test_pipe_read_write.c
Normal file
1809
test_conformance/pipes/test_pipe_read_write.c
Normal file
File diff suppressed because it is too large
Load Diff
312
test_conformance/pipes/test_pipe_readwrite_errors.c
Normal file
312
test_conformance/pipes/test_pipe_readwrite_errors.c
Normal 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;
|
||||
}
|
||||
339
test_conformance/pipes/test_pipe_subgroups.c
Normal file
339
test_conformance/pipes/test_pipe_subgroups.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user