mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-21 23:09:01 +00:00
Initial open source release of OpenCL 2.0 CTS.
This commit is contained in:
34
test_conformance/api/CMakeLists.txt
Normal file
34
test_conformance/api/CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
set(MODULE_NAME API)
|
||||
|
||||
set(${MODULE_NAME}_SOURCES
|
||||
main.c
|
||||
test_bool.c
|
||||
test_retain.cpp
|
||||
test_retain_program.c
|
||||
test_queries.cpp
|
||||
test_create_kernels.c
|
||||
test_kernels.c
|
||||
test_api_min_max.c
|
||||
test_kernel_arg_changes.cpp
|
||||
test_kernel_arg_multi_setup.cpp
|
||||
test_binary.cpp
|
||||
test_native_kernel.cpp
|
||||
test_mem_objects.cpp
|
||||
test_create_context_from_type.cpp
|
||||
test_device_min_data_type_align_size_alignment.cpp
|
||||
test_platform.cpp
|
||||
test_kernel_arg_info.c
|
||||
test_null_buffer_arg.c
|
||||
test_mem_object_info.cpp
|
||||
../../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/conversions.c
|
||||
../../test_common/harness/mt19937.c
|
||||
../../test_common/harness/msvc9.c
|
||||
../../test_common/harness/imageHelpers.cpp
|
||||
)
|
||||
|
||||
include(../CMakeCommon.txt)
|
||||
27
test_conformance/api/Jamfile
Normal file
27
test_conformance/api/Jamfile
Normal file
@@ -0,0 +1,27 @@
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc:<cflags>-xc++
|
||||
<toolset>msvc:<cflags>"/TP"
|
||||
;
|
||||
|
||||
|
||||
exe test_api
|
||||
: main.c
|
||||
test_api_min_max.c
|
||||
test_binary.cpp
|
||||
test_create_kernels.c
|
||||
test_create_context_from_type.cpp
|
||||
test_kernel_arg_changes.cpp
|
||||
test_kernel_arg_multi_setup.cpp
|
||||
test_kernels.c
|
||||
test_native_kernel.cpp
|
||||
test_queries.cpp
|
||||
test_retain_program.c
|
||||
test_platform.cpp
|
||||
;
|
||||
|
||||
install dist
|
||||
: test_api #test.lst
|
||||
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/api
|
||||
<variant>release:<location>$(DIST)/release/tests/test_conformance/api
|
||||
;
|
||||
61
test_conformance/api/Makefile
Normal file
61
test_conformance/api/Makefile
Normal file
@@ -0,0 +1,61 @@
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = main.c \
|
||||
test_retain_program.c \
|
||||
test_queries.cpp \
|
||||
test_create_kernels.c \
|
||||
test_kernels.c \
|
||||
test_kernel_arg_info.c \
|
||||
test_api_min_max.c \
|
||||
test_kernel_arg_changes.cpp \
|
||||
test_kernel_arg_multi_setup.cpp \
|
||||
test_binary.cpp \
|
||||
test_native_kernel.cpp \
|
||||
test_create_context_from_type.cpp \
|
||||
test_platform.cpp \
|
||||
test_retain.cpp \
|
||||
test_device_min_data_type_align_size_alignment.cpp \
|
||||
test_mem_objects.cpp \
|
||||
test_bool.c \
|
||||
test_null_buffer_arg.c \
|
||||
test_mem_object_info.cpp \
|
||||
../../test_common/harness/errorHelpers.c \
|
||||
../../test_common/harness/threadTesting.c \
|
||||
../../test_common/harness/testHarness.c \
|
||||
../../test_common/harness/imageHelpers.cpp \
|
||||
../../test_common/harness/kernelHelpers.c \
|
||||
../../test_common/harness/typeWrappers.cpp \
|
||||
../../test_common/harness/mt19937.c \
|
||||
../../test_common/harness/conversions.c
|
||||
|
||||
DEFINES = DONT_TEST_GARBAGE_POINTERS
|
||||
|
||||
SOURCES = $(abspath $(SRCS))
|
||||
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
|
||||
LIBPATH += -L.
|
||||
HEADERS =
|
||||
TARGET = test_api
|
||||
INCLUDE =
|
||||
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
|
||||
CC = c++
|
||||
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
|
||||
|
||||
OBJECTS := ${SOURCES:.c=.o}
|
||||
OBJECTS := ${OBJECTS:.cpp=.o}
|
||||
|
||||
TARGETOBJECT =
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(RC_CFLAGS) $(OBJECTS) -o $@ $(LIBPATH) $(LIBRARIES)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
.DEFAULT:
|
||||
@echo The target \"$@\" does not exist in Makefile.
|
||||
215
test_conformance/api/main.c
Normal file
215
test_conformance/api/main.c
Normal file
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "procs.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// FIXME: To use certain functions in ../../test_common/harness/imageHelpers.h
|
||||
// (for example, generate_random_image_data()), the tests are required to declare
|
||||
// the following variables (<rdar://problem/11111245>):
|
||||
cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
|
||||
bool gTestRounding = false;
|
||||
|
||||
basefn basefn_list[] = {
|
||||
test_get_platform_info,
|
||||
test_get_sampler_info,
|
||||
test_get_command_queue_info,
|
||||
test_get_context_info,
|
||||
test_get_device_info,
|
||||
test_enqueue_task,
|
||||
test_binary_get,
|
||||
test_program_binary_create,
|
||||
test_kernel_required_group_size,
|
||||
|
||||
test_release_kernel_order,
|
||||
test_release_during_execute,
|
||||
|
||||
test_load_single_kernel,
|
||||
test_load_two_kernels,
|
||||
test_load_two_kernels_in_one,
|
||||
test_load_two_kernels_manually,
|
||||
test_get_program_info_kernel_names,
|
||||
test_get_kernel_arg_info,
|
||||
test_create_kernels_in_program,
|
||||
test_get_kernel_info,
|
||||
test_execute_kernel_local_sizes,
|
||||
test_set_kernel_arg_by_index,
|
||||
test_set_kernel_arg_constant,
|
||||
test_set_kernel_arg_struct_array,
|
||||
test_kernel_global_constant,
|
||||
|
||||
test_min_max_thread_dimensions,
|
||||
test_min_max_work_items_sizes,
|
||||
test_min_max_work_group_size,
|
||||
test_min_max_read_image_args,
|
||||
test_min_max_write_image_args,
|
||||
test_min_max_mem_alloc_size,
|
||||
test_min_max_image_2d_width,
|
||||
test_min_max_image_2d_height,
|
||||
test_min_max_image_3d_width,
|
||||
test_min_max_image_3d_height,
|
||||
test_min_max_image_3d_depth,
|
||||
test_min_max_image_array_size,
|
||||
test_min_max_image_buffer_size,
|
||||
test_min_max_parameter_size,
|
||||
test_min_max_samplers,
|
||||
test_min_max_constant_buffer_size,
|
||||
test_min_max_constant_args,
|
||||
test_min_max_compute_units,
|
||||
test_min_max_address_bits,
|
||||
test_min_max_single_fp_config,
|
||||
test_min_max_double_fp_config,
|
||||
test_min_max_local_mem_size,
|
||||
test_min_max_kernel_preferred_work_group_size_multiple,
|
||||
test_min_max_execution_capabilities,
|
||||
test_min_max_queue_properties,
|
||||
test_min_max_device_version,
|
||||
test_min_max_language_version,
|
||||
|
||||
test_kernel_arg_changes,
|
||||
test_kernel_arg_multi_setup_random,
|
||||
|
||||
test_native_kernel,
|
||||
|
||||
test_create_context_from_type,
|
||||
|
||||
test_platform_extensions,
|
||||
test_get_platform_ids,
|
||||
test_for_bool_type,
|
||||
|
||||
test_repeated_setup_cleanup,
|
||||
|
||||
test_retain_queue_single,
|
||||
test_retain_queue_multiple,
|
||||
test_retain_mem_object_single,
|
||||
test_retain_mem_object_multiple,
|
||||
test_min_data_type_align_size_alignment,
|
||||
|
||||
test_mem_object_destructor_callback,
|
||||
test_null_buffer_arg,
|
||||
test_get_buffer_info,
|
||||
test_get_image2d_info,
|
||||
test_get_image3d_info,
|
||||
test_get_image1d_info,
|
||||
test_get_image1d_array_info,
|
||||
test_get_image2d_array_info,
|
||||
};
|
||||
|
||||
|
||||
const char *basefn_names[] = {
|
||||
"get_platform_info",
|
||||
"get_sampler_info",
|
||||
"get_command_queue_info",
|
||||
"get_context_info",
|
||||
"get_device_info",
|
||||
"enqueue_task",
|
||||
"binary_get",
|
||||
"binary_create",
|
||||
"kernel_required_group_size",
|
||||
|
||||
"release_kernel_order",
|
||||
"release_during_execute",
|
||||
|
||||
"load_single_kernel",
|
||||
"load_two_kernels",
|
||||
"load_two_kernels_in_one",
|
||||
"load_two_kernels_manually",
|
||||
"get_program_info_kernel_names",
|
||||
"get_kernel_arg_info",
|
||||
"create_kernels_in_program",
|
||||
"get_kernel_info",
|
||||
"execute_kernel_local_sizes",
|
||||
"set_kernel_arg_by_index",
|
||||
"set_kernel_arg_constant",
|
||||
"set_kernel_arg_struct_array",
|
||||
"kernel_global_constant",
|
||||
|
||||
"min_max_thread_dimensions",
|
||||
"min_max_work_items_sizes",
|
||||
"min_max_work_group_size",
|
||||
"min_max_read_image_args",
|
||||
"min_max_write_image_args",
|
||||
"min_max_mem_alloc_size",
|
||||
"min_max_image_2d_width",
|
||||
"min_max_image_2d_height",
|
||||
"min_max_image_3d_width",
|
||||
"min_max_image_3d_height",
|
||||
"min_max_image_3d_depth",
|
||||
"min_max_image_array_size",
|
||||
"min_max_image_buffer_size",
|
||||
"min_max_parameter_size",
|
||||
"min_max_samplers",
|
||||
"min_max_constant_buffer_size",
|
||||
"min_max_constant_args",
|
||||
"min_max_compute_units",
|
||||
"min_max_address_bits",
|
||||
"min_max_single_fp_config",
|
||||
"min_max_double_fp_config",
|
||||
"min_max_local_mem_size",
|
||||
"min_max_kernel_preferred_work_group_size_multiple",
|
||||
"min_max_execution_capabilities",
|
||||
"min_max_queue_properties",
|
||||
"min_max_device_version",
|
||||
"min_max_language_version",
|
||||
|
||||
"kernel_arg_changes",
|
||||
"kernel_arg_multi_setup_random",
|
||||
|
||||
"native_kernel",
|
||||
|
||||
"create_context_from_type",
|
||||
"platform_extensions",
|
||||
|
||||
"get_platform_ids",
|
||||
"bool_type",
|
||||
|
||||
"repeated_setup_cleanup",
|
||||
|
||||
"retain_queue_single",
|
||||
"retain_queue_multiple",
|
||||
"retain_mem_object_single",
|
||||
"retain_mem_object_multiple",
|
||||
|
||||
"min_data_type_align_size_alignment",
|
||||
|
||||
"mem_object_destructor_callback",
|
||||
"null_buffer_arg",
|
||||
"get_buffer_info",
|
||||
"get_image2d_info",
|
||||
"get_image3d_info",
|
||||
"get_image1d_info",
|
||||
"get_image1d_array_info",
|
||||
"get_image2d_array_info",
|
||||
};
|
||||
|
||||
ct_assert((sizeof(basefn_names) / sizeof(basefn_names[0])) == (sizeof(basefn_list) / sizeof(basefn_list[0])));
|
||||
|
||||
int num_fns = sizeof(basefn_names) / sizeof(char *);
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
return runTestHarness( argc, argv, num_fns, basefn_list, basefn_names, false, false, 0 );
|
||||
}
|
||||
|
||||
|
||||
108
test_conformance/api/procs.h
Normal file
108
test_conformance/api/procs.h
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// 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/errorHelpers.h"
|
||||
#include "../../test_common/harness/kernelHelpers.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/clImageHelper.h"
|
||||
#include "../../test_common/harness/imageHelpers.h"
|
||||
extern float calculate_ulperror(float a, float b);
|
||||
|
||||
extern int test_load_single_kernel(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_two_kernels(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_two_kernels_in_one(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_two_kernels_manually(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_program_info_kernel_names( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_create_kernels_in_program(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_enqueue_task(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_repeated_setup_cleanup(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_for_bool_type(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_platform_extensions(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_platform_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_sampler_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_command_queue_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_context_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_device_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_kernel_required_group_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_binary_get(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_program_binary_create(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_release_kernel_order(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_release_during_execute(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_get_kernel_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_set_kernel_arg_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_set_kernel_arg_struct_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_kernel_global_constant(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_min_max_thread_dimensions(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_work_items_sizes(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_work_group_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_read_image_args(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_write_image_args(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_2d_width(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_2d_height(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_3d_width(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_3d_height(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_3d_depth(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_array_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_image_buffer_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_parameter_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_samplers(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_constant_args(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_compute_units(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_address_bits(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_single_fp_config(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_double_fp_config(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_local_mem_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_kernel_preferred_work_group_size_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_execution_capabilities(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_queue_properties(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_device_version(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_max_language_version(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_native_kernel(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems );
|
||||
|
||||
extern int test_create_context_from_type(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_get_platform_ids(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_kernel_arg_changes(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_kernel_arg_multi_setup_random(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_retain_queue_single(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_retain_queue_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_retain_mem_object_single(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_retain_mem_object_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_min_data_type_align_size_alignment(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems );
|
||||
|
||||
extern int test_mem_object_destructor_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_null_buffer_arg( cl_device_id device_id, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
|
||||
extern int test_get_image2d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
|
||||
extern int test_get_image3d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
|
||||
extern int test_get_image1d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
|
||||
extern int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
|
||||
extern int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
|
||||
extern int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
|
||||
31
test_conformance/api/testBase.h
Normal file
31
test_conformance/api/testBase.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// 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 _testBase_h
|
||||
#define _testBase_h
|
||||
|
||||
#include "../../test_common/harness/compat.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "procs.h"
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
|
||||
|
||||
2122
test_conformance/api/test_api_min_max.c
Normal file
2122
test_conformance/api/test_api_min_max.c
Normal file
File diff suppressed because it is too large
Load Diff
226
test_conformance/api/test_binary.cpp
Normal file
226
test_conformance/api/test_binary.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
|
||||
static const char *sample_binary_kernel_source[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid] + 1;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
|
||||
int test_binary_get(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
size_t binarySize;
|
||||
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, sample_binary_kernel_source, NULL, &error );
|
||||
test_error( error, "Unable to create program from source" );
|
||||
|
||||
// Build so we have a binary to get
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build test program" );
|
||||
|
||||
// Get the size of the resulting binary (only one device)
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_BINARY_SIZES, sizeof( binarySize ), &binarySize, NULL );
|
||||
test_error( error, "Unable to get binary size" );
|
||||
|
||||
// Sanity check
|
||||
if( binarySize == 0 )
|
||||
{
|
||||
log_error( "ERROR: Binary size of program is zero\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a buffer and get the actual binary
|
||||
unsigned char *binary;
|
||||
binary = (unsigned char*)malloc(sizeof(unsigned char)*binarySize);
|
||||
unsigned char *buffers[ 1 ] = { binary };
|
||||
|
||||
// Do another sanity check here first
|
||||
size_t size;
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_BINARIES, 0, NULL, &size );
|
||||
test_error( error, "Unable to get expected size of binaries array" );
|
||||
if( size != sizeof( buffers ) )
|
||||
{
|
||||
log_error( "ERROR: Expected size of binaries array in clGetProgramInfo is incorrect (should be %d, got %d)\n", (int)sizeof( buffers ), (int)size );
|
||||
free(binary);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_BINARIES, sizeof( buffers ), &buffers, NULL );
|
||||
test_error( error, "Unable to get program binary" );
|
||||
|
||||
// No way to verify the binary is correct, so just be good with that
|
||||
free(binary);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int test_program_binary_create(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
/* To test this in a self-contained fashion, we have to create a program with
|
||||
source, then get the binary, then use that binary to reload the program, and then verify */
|
||||
|
||||
int error;
|
||||
clProgramWrapper program, program_from_binary;
|
||||
size_t binarySize;
|
||||
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, sample_binary_kernel_source, NULL, &error );
|
||||
test_error( error, "Unable to create program from source" );
|
||||
|
||||
// Build so we have a binary to get
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build test program" );
|
||||
|
||||
// Get the size of the resulting binary (only one device)
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_BINARY_SIZES, sizeof( binarySize ), &binarySize, NULL );
|
||||
test_error( error, "Unable to get binary size" );
|
||||
|
||||
// Sanity check
|
||||
if( binarySize == 0 )
|
||||
{
|
||||
log_error( "ERROR: Binary size of program is zero\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a buffer and get the actual binary
|
||||
unsigned char *binary = (unsigned char*)malloc(binarySize);
|
||||
const unsigned char *buffers[ 1 ] = { binary };
|
||||
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_BINARIES, sizeof( buffers ), &buffers, NULL );
|
||||
test_error( error, "Unable to get program binary" );
|
||||
|
||||
cl_int loadErrors[ 1 ];
|
||||
program_from_binary = clCreateProgramWithBinary( context, 1, &deviceID, &binarySize, buffers, loadErrors, &error );
|
||||
test_error( error, "Unable to load valid program binary" );
|
||||
test_error( loadErrors[ 0 ], "Unable to load valid device binary into program" );
|
||||
|
||||
error = clBuildProgram( program_from_binary, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build binary program" );
|
||||
|
||||
// Get the size of the binary built from the first binary
|
||||
size_t binary2Size;
|
||||
error = clGetProgramInfo( program_from_binary, CL_PROGRAM_BINARY_SIZES, sizeof( binary2Size ), &binary2Size, NULL );
|
||||
test_error( error, "Unable to get size for the binary program" );
|
||||
|
||||
// Now get the binary one more time and verify it loaded the right binary
|
||||
unsigned char *binary2 = (unsigned char*)malloc(binary2Size);
|
||||
buffers[ 0 ] = binary2;
|
||||
error = clGetProgramInfo( program_from_binary, CL_PROGRAM_BINARIES, sizeof( buffers ), &buffers, NULL );
|
||||
test_error( error, "Unable to get program binary second time" );
|
||||
|
||||
// Try again, this time without passing the status ptr in, to make sure we still
|
||||
// get a valid binary
|
||||
clProgramWrapper programWithoutStatus = clCreateProgramWithBinary( context, 1, &deviceID, &binary2Size, buffers, NULL, &error );
|
||||
test_error( error, "Unable to load valid program binary when binary_status pointer is NULL" );
|
||||
|
||||
error = clBuildProgram( programWithoutStatus, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build binary program created without binary_status" );
|
||||
|
||||
// Get the size of the binary created without passing binary_status
|
||||
size_t binary3Size;
|
||||
error = clGetProgramInfo( programWithoutStatus, CL_PROGRAM_BINARY_SIZES, sizeof( binary3Size ), &binary3Size, NULL );
|
||||
test_error( error, "Unable to get size for the binary program created without binary_status" );
|
||||
|
||||
// Now get the binary one more time
|
||||
unsigned char *binary3 = (unsigned char*)malloc(binary3Size);
|
||||
buffers[ 0 ] = binary3;
|
||||
error = clGetProgramInfo( programWithoutStatus, CL_PROGRAM_BINARIES, sizeof( buffers ), &buffers, NULL );
|
||||
test_error( error, "Unable to get program binary from the program created without binary_status" );
|
||||
|
||||
// We no longer need these intermediate binaries
|
||||
free(binary);
|
||||
free(binary2);
|
||||
free(binary3);
|
||||
|
||||
// Now execute them both to see that they both do the same thing.
|
||||
clMemWrapper in, out, out_binary;
|
||||
clKernelWrapper kernel, kernel_binary;
|
||||
cl_int *out_data, *out_data_binary;
|
||||
cl_float *in_data;
|
||||
size_t size_to_run = 1000;
|
||||
|
||||
// Allocate some data
|
||||
in_data = (cl_float*)malloc(sizeof(cl_float)*size_to_run);
|
||||
out_data = (cl_int*)malloc(sizeof(cl_int)*size_to_run);
|
||||
out_data_binary = (cl_int*)malloc(sizeof(cl_int)*size_to_run);
|
||||
memset(out_data, 0, sizeof(cl_int)*size_to_run);
|
||||
memset(out_data_binary, 0, sizeof(cl_int)*size_to_run);
|
||||
for (size_t i=0; i<size_to_run; i++)
|
||||
in_data[i] = (cl_float)i;
|
||||
|
||||
// Create the buffers
|
||||
in = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(cl_float)*size_to_run, in_data, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
out = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(cl_int)*size_to_run, out_data, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
out_binary = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(cl_int)*size_to_run, out_data_binary, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
// Create the kernels
|
||||
kernel = clCreateKernel(program, "sample_test", &error);
|
||||
test_error( error, "clCreateKernel failed");
|
||||
kernel_binary = clCreateKernel(program_from_binary, "sample_test", &error);
|
||||
test_error( error, "clCreateKernel from binary failed");
|
||||
|
||||
// Set the arguments
|
||||
error = clSetKernelArg(kernel, 0, sizeof(in), &in);
|
||||
test_error( error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel, 1, sizeof(out), &out);
|
||||
test_error( error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel_binary, 0, sizeof(in), &in);
|
||||
test_error( error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel_binary, 1, sizeof(out_binary), &out_binary);
|
||||
test_error( error, "clSetKernelArg failed");
|
||||
|
||||
// Execute the kernels
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &size_to_run, NULL, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueNDRangeKernel failed");
|
||||
error = clEnqueueNDRangeKernel(queue, kernel_binary, 1, NULL, &size_to_run, NULL, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueNDRangeKernel for binary kernel failed");
|
||||
|
||||
// Finish up
|
||||
error = clFinish(queue);
|
||||
test_error( error, "clFinish failed");
|
||||
|
||||
// Get the results back
|
||||
error = clEnqueueReadBuffer(queue, out, CL_TRUE, 0, sizeof(cl_int)*size_to_run, out_data, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueReadBuffer failed");
|
||||
error = clEnqueueReadBuffer(queue, out_binary, CL_TRUE, 0, sizeof(cl_int)*size_to_run, out_data_binary, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueReadBuffer failed");
|
||||
|
||||
// Compare the results
|
||||
if( memcmp( out_data, out_data_binary, sizeof(cl_int)*size_to_run ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Results from executing binary and regular kernel differ.\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// All done!
|
||||
free(in_data);
|
||||
free(out_data);
|
||||
free(out_data_binary);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
52
test_conformance/api/test_bool.c
Normal file
52
test_conformance/api/test_bool.c
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
|
||||
const char *kernel_with_bool[] = {
|
||||
"__kernel void kernel_with_bool(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" bool myBool = (src[tid] < 0.5f) && (src[tid] > -0.5f);\n"
|
||||
" if(myBool)\n"
|
||||
" {\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
" }\n"
|
||||
" else\n"
|
||||
" {\n"
|
||||
" dst[tid] = 0;\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
int test_for_bool_type(cl_device_id deviceID, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
{
|
||||
|
||||
cl_program program;
|
||||
cl_kernel kernel;
|
||||
|
||||
int err = create_single_kernel_helper(context,
|
||||
&program,
|
||||
&kernel,
|
||||
1, kernel_with_bool,
|
||||
"kernel_with_bool" );
|
||||
return err;
|
||||
}
|
||||
|
||||
130
test_conformance/api/test_create_context_from_type.cpp
Normal file
130
test_conformance/api/test_create_context_from_type.cpp
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.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
int test_create_context_from_type(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[2];
|
||||
clContextWrapper context_to_test;
|
||||
clCommandQueueWrapper queue_to_test;
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_float inputData[10];
|
||||
cl_int outputData[10];
|
||||
int i;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
const char *sample_single_test_kernel[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
cl_device_type type;
|
||||
error = clGetDeviceInfo(deviceID, CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_TYPE failed\n");
|
||||
|
||||
cl_platform_id platform;
|
||||
error = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM, sizeof(platform), &platform, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_PLATFORM failed\n");
|
||||
|
||||
cl_context_properties properties[3] = {
|
||||
(cl_context_properties)CL_CONTEXT_PLATFORM,
|
||||
(cl_context_properties)platform,
|
||||
NULL
|
||||
};
|
||||
|
||||
context_to_test = clCreateContextFromType(properties, type, notify_callback, NULL, &error);
|
||||
test_error(error, "clCreateContextFromType failed");
|
||||
if (context_to_test == NULL) {
|
||||
log_error("clCreateContextFromType returned NULL, but error was CL_SUCCESS.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
queue_to_test = clCreateCommandQueueWithProperties(context_to_test, deviceID, NULL, &error);
|
||||
test_error(error, "clCreateCommandQueue failed");
|
||||
if (queue_to_test == NULL) {
|
||||
log_error("clCreateCommandQueue returned NULL, but error was CL_SUCCESS.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context_to_test, &program, &kernel, 1, sample_single_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
streams[0] = clCreateBuffer(context_to_test, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context_to_test, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Write some test data */
|
||||
memset( outputData, 0, sizeof( outputData ) );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
inputData[i] = get_random_float(-(float) 0x7fffffff, (float) 0x7fffffff, seed);
|
||||
|
||||
error = clEnqueueWriteBuffer(queue_to_test, streams[0], CL_TRUE, 0, sizeof(cl_float)*10, (void *)inputData, 0, NULL, NULL);
|
||||
test_error( error, "Unable to set testing kernel data" );
|
||||
|
||||
/* Test setting the arguments by index manually */
|
||||
error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)10;
|
||||
|
||||
error = get_max_common_work_group_size( context_to_test, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue_to_test, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue_to_test, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if (outputData[i] != (int)inputData[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify on first pass!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
643
test_conformance/api/test_create_kernels.c
Normal file
643
test_conformance/api/test_create_kernels.c
Normal file
@@ -0,0 +1,643 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
|
||||
const char *sample_single_kernel[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
size_t sample_single_kernel_lengths[1];
|
||||
|
||||
const char *sample_two_kernels[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n",
|
||||
"__kernel void sample_test2(__global int *src, __global float *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (float)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
size_t sample_two_kernel_lengths[2];
|
||||
|
||||
const char *sample_two_kernels_in_1[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n"
|
||||
"__kernel void sample_test2(__global int *src, __global float *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (float)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
size_t sample_two_kernels_in_1_lengths[1];
|
||||
|
||||
|
||||
const char *repeate_test_kernel =
|
||||
"__kernel void test_kernel(__global int *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" dst[get_global_id(0)] = src[get_global_id(0)]+1;\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
|
||||
int test_load_single_kernel(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
cl_program testProgram;
|
||||
clKernelWrapper kernel;
|
||||
cl_context testContext;
|
||||
unsigned int numKernels;
|
||||
cl_char testName[512];
|
||||
cl_uint testArgCount;
|
||||
size_t realSize;
|
||||
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
sample_single_kernel_lengths[ 0 ] = strlen( sample_single_kernel[ 0 ] );
|
||||
|
||||
/* Create a program */
|
||||
program = clCreateProgramWithSource( context, 1, sample_single_kernel, sample_single_kernel_lengths, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create single kernel program" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build single kernel program" );
|
||||
error = clCreateKernelsInProgram(program, 1, &kernel, &numKernels);
|
||||
test_error( error, "Unable to create single kernel program" );
|
||||
|
||||
/* Check program and context pointers */
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_PROGRAM, sizeof( cl_program ), &testProgram, &realSize );
|
||||
test_error( error, "Unable to get kernel's program" );
|
||||
if( (cl_program)testProgram != (cl_program)program )
|
||||
{
|
||||
log_error( "ERROR: Returned kernel's program does not match program used to create it! (Got %p, expected %p)\n", (cl_program)testProgram, (cl_program)program );
|
||||
return -1;
|
||||
}
|
||||
if( realSize != sizeof( cl_program ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of kernel's program does not match expected size (expected %d, got %d)\n", (int)sizeof( cl_program ), (int)realSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_CONTEXT, sizeof( cl_context ), &testContext, &realSize );
|
||||
test_error( error, "Unable to get kernel's context" );
|
||||
if( (cl_context)testContext != (cl_context)context )
|
||||
{
|
||||
log_error( "ERROR: Returned kernel's context does not match program used to create it! (Got %p, expected %p)\n", (cl_context)testContext, (cl_context)context );
|
||||
return -1;
|
||||
}
|
||||
if( realSize != sizeof( cl_context ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of kernel's context does not match expected size (expected %d, got %d)\n", (int)sizeof( cl_context ), (int)realSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test arg count */
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_NUM_ARGS, 0, NULL, &realSize );
|
||||
test_error( error, "Unable to get size of arg count info from kernel" );
|
||||
|
||||
if( realSize != sizeof( testArgCount ) )
|
||||
{
|
||||
log_error( "ERROR: size of arg count not valid! %d\n", (int)realSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_NUM_ARGS, sizeof( testArgCount ), &testArgCount, NULL );
|
||||
test_error( error, "Unable to get arg count from kernel" );
|
||||
|
||||
if( testArgCount != 2 )
|
||||
{
|
||||
log_error( "ERROR: Kernel arg count does not match!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Test function name */
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_FUNCTION_NAME, sizeof( testName ), testName, &realSize );
|
||||
test_error( error, "Unable to get name from kernel" );
|
||||
|
||||
if( strcmp( (char *)testName, "sample_test" ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Kernel names do not match!\n" );
|
||||
return -1;
|
||||
}
|
||||
if( realSize != strlen( (char *)testName ) + 1 )
|
||||
{
|
||||
log_error( "ERROR: Length of kernel name returned does not validate (expected %d, got %d)\n", (int)strlen( (char *)testName ) + 1, (int)realSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_two_kernels(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel[2];
|
||||
unsigned int numKernels;
|
||||
cl_char testName[ 512 ];
|
||||
cl_uint testArgCount;
|
||||
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
sample_two_kernel_lengths[ 0 ] = strlen( sample_two_kernels[ 0 ] );
|
||||
sample_two_kernel_lengths[ 1 ] = strlen( sample_two_kernels[ 1 ] );
|
||||
|
||||
/* Now create a test program */
|
||||
program = clCreateProgramWithSource( context, 2, sample_two_kernels, sample_two_kernel_lengths, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create dual kernel program!" );
|
||||
return -1;
|
||||
}
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build dual kernel program" );
|
||||
error = clCreateKernelsInProgram(program, 2, &kernel[0], &numKernels);
|
||||
test_error( error, "Unable to create dual kernel program" );
|
||||
|
||||
if( numKernels != 2 )
|
||||
{
|
||||
log_error( "ERROR: wrong # of kernels! (%d)\n", numKernels );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check first kernel */
|
||||
error = clGetKernelInfo( kernel[0], CL_KERNEL_FUNCTION_NAME, sizeof( testName ), testName, NULL );
|
||||
test_error( error, "Unable to get function name from kernel" );
|
||||
|
||||
int found_kernel1 = 0, found_kernel2 = 0;
|
||||
|
||||
if( strcmp( (char *)testName, "sample_test" ) == 0 ) {
|
||||
found_kernel1 = 1;
|
||||
} else if( strcmp( (char *)testName, "sample_test2" ) == 0 ) {
|
||||
found_kernel2 = 1;
|
||||
} else {
|
||||
log_error( "ERROR: Invalid kernel name returned: \"%s\" expected \"%s\" or \"%s\".\n", testName, "sample_test", "sample_test2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel[1], CL_KERNEL_FUNCTION_NAME, sizeof( testName ), testName, NULL );
|
||||
test_error( error, "Unable to get function name from second kernel" );
|
||||
|
||||
if( strcmp( (char *)testName, "sample_test" ) == 0 ) {
|
||||
if (found_kernel1) {
|
||||
log_error("Kernel \"%s\" returned twice.\n", (char *)testName);
|
||||
return -1;
|
||||
}
|
||||
found_kernel1 = 1;
|
||||
} else if( strcmp( (char *)testName, "sample_test2" ) == 0 ) {
|
||||
if (found_kernel2) {
|
||||
log_error("Kernel \"%s\" returned twice.\n", (char *)testName);
|
||||
return -1;
|
||||
}
|
||||
found_kernel2 = 1;
|
||||
} else {
|
||||
log_error( "ERROR: Invalid kernel name returned: \"%s\" expected \"%s\" or \"%s\".\n", testName, "sample_test", "sample_test2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !found_kernel1 || !found_kernel2 )
|
||||
{
|
||||
log_error( "ERROR: Kernel names do not match.\n" );
|
||||
if (!found_kernel1)
|
||||
log_error("Kernel \"%s\" not returned.\n", "sample_test");
|
||||
if (!found_kernel2)
|
||||
log_error("Kernel \"%s\" not returned.\n", "sample_test");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel[0], CL_KERNEL_NUM_ARGS, sizeof( testArgCount ), &testArgCount, NULL );
|
||||
test_error( error, "Unable to get arg count from kernel" );
|
||||
|
||||
if( testArgCount != 2 )
|
||||
{
|
||||
log_error( "ERROR: wrong # of args for kernel\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_two_kernels_in_one(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel[2];
|
||||
unsigned int numKernels;
|
||||
cl_char testName[512];
|
||||
cl_uint testArgCount;
|
||||
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
sample_two_kernels_in_1_lengths[ 0 ] = strlen( sample_two_kernels_in_1[ 0 ] );
|
||||
|
||||
/* Now create a test program */
|
||||
program = clCreateProgramWithSource( context, 1, sample_two_kernels_in_1, sample_two_kernels_in_1_lengths, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create dual kernel program" );
|
||||
return -1;
|
||||
}
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build dual kernel program" );
|
||||
error = clCreateKernelsInProgram(program, 2, &kernel[0], &numKernels);
|
||||
test_error( error, "Unable to create dual kernel program" );
|
||||
|
||||
if( numKernels != 2 )
|
||||
{
|
||||
log_error( "ERROR: wrong # of kernels! (%d)\n", numKernels );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check first kernel */
|
||||
error = clGetKernelInfo( kernel[0], CL_KERNEL_FUNCTION_NAME, sizeof( testName ), testName, NULL );
|
||||
test_error( error, "Unable to get function name from kernel" );
|
||||
|
||||
int found_kernel1 = 0, found_kernel2 = 0;
|
||||
|
||||
if( strcmp( (char *)testName, "sample_test" ) == 0 ) {
|
||||
found_kernel1 = 1;
|
||||
} else if( strcmp( (char *)testName, "sample_test2" ) == 0 ) {
|
||||
found_kernel2 = 1;
|
||||
} else {
|
||||
log_error( "ERROR: Invalid kernel name returned: \"%s\" expected \"%s\" or \"%s\".\n", testName, "sample_test", "sample_test2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel[0], CL_KERNEL_NUM_ARGS, sizeof( testArgCount ), &testArgCount, NULL );
|
||||
test_error( error, "Unable to get arg count from kernel" );
|
||||
|
||||
if( testArgCount != 2 )
|
||||
{
|
||||
log_error( "ERROR: wrong # of args for kernel\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check second kernel */
|
||||
error = clGetKernelInfo( kernel[1], CL_KERNEL_FUNCTION_NAME, sizeof( testName ), testName, NULL );
|
||||
test_error( error, "Unable to get function name from kernel" );
|
||||
|
||||
if( strcmp( (char *)testName, "sample_test" ) == 0 ) {
|
||||
if (found_kernel1) {
|
||||
log_error("Kernel \"%s\" returned twice.\n", (char *)testName);
|
||||
return -1;
|
||||
}
|
||||
found_kernel1 = 1;
|
||||
} else if( strcmp( (char *)testName, "sample_test2" ) == 0 ) {
|
||||
if (found_kernel2) {
|
||||
log_error("Kernel \"%s\" returned twice.\n", (char *)testName);
|
||||
return -1;
|
||||
}
|
||||
found_kernel2 = 1;
|
||||
} else {
|
||||
log_error( "ERROR: Invalid kernel name returned: \"%s\" expected \"%s\" or \"%s\".\n", testName, "sample_test", "sample_test2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !found_kernel1 || !found_kernel2 )
|
||||
{
|
||||
log_error( "ERROR: Kernel names do not match.\n" );
|
||||
if (!found_kernel1)
|
||||
log_error("Kernel \"%s\" not returned.\n", "sample_test");
|
||||
if (!found_kernel2)
|
||||
log_error("Kernel \"%s\" not returned.\n", "sample_test");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_two_kernels_manually( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel1, kernel2;
|
||||
int error;
|
||||
|
||||
|
||||
/* Now create a test program */
|
||||
program = clCreateProgramWithSource( context, 1, sample_two_kernels_in_1, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create dual kernel program" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compile the program */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build kernel program" );
|
||||
|
||||
/* Try manually creating kernels (backwards just in case) */
|
||||
kernel1 = clCreateKernel( program, "sample_test2", &error );
|
||||
|
||||
if( kernel1 == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Could not get kernel 1" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
kernel2 = clCreateKernel( program, "sample_test", &error );
|
||||
|
||||
if( kernel2 == NULL )
|
||||
{
|
||||
print_error( error, "Could not get kernel 2" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_program_info_kernel_names( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel1, kernel2;
|
||||
int error;
|
||||
size_t i;
|
||||
|
||||
/* Now create a test program */
|
||||
program = clCreateProgramWithSource( context, 1, sample_two_kernels_in_1, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to create dual kernel program" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compile the program */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build kernel program" );
|
||||
|
||||
/* Lookup the number of kernels in the program. */
|
||||
size_t total_kernels = 0;
|
||||
error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS, sizeof(size_t),&total_kernels,NULL);
|
||||
test_error( error, "Unable to get program info num kernels");
|
||||
|
||||
if (total_kernels != 2)
|
||||
{
|
||||
print_error( error, "Program did not contain two kernels" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Lookup the kernel names. */
|
||||
const char* actual_names[] = { "sample_test;sample_test2", "sample_test2;sample_test"} ;
|
||||
|
||||
size_t kernel_names_len = 0;
|
||||
error = clGetProgramInfo(program,CL_PROGRAM_KERNEL_NAMES,0,NULL,&kernel_names_len);
|
||||
test_error( error, "Unable to get length of kernel names list." );
|
||||
|
||||
if (kernel_names_len != (strlen(actual_names[0])+1))
|
||||
{
|
||||
print_error( error, "Kernel names length did not match");
|
||||
return -1;
|
||||
}
|
||||
|
||||
const size_t len = (kernel_names_len+1)*sizeof(char);
|
||||
char* kernel_names = (char*)malloc(len);
|
||||
error = clGetProgramInfo(program,CL_PROGRAM_KERNEL_NAMES,len,kernel_names,&kernel_names_len);
|
||||
test_error( error, "Unable to get kernel names list." );
|
||||
|
||||
/* Check to see if the kernel name array is null terminated. */
|
||||
if (kernel_names[kernel_names_len-1] != '\0')
|
||||
{
|
||||
free(kernel_names);
|
||||
print_error( error, "Kernel name list was not null terminated");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check to see if the correct kernel name string was returned. */
|
||||
for( i = 0; i < sizeof( actual_names ) / sizeof( actual_names[0] ); i++ )
|
||||
if( 0 == strcmp(actual_names[i],kernel_names) )
|
||||
break;
|
||||
|
||||
if (i == sizeof( actual_names ) / sizeof( actual_names[0] ) )
|
||||
{
|
||||
free(kernel_names);
|
||||
log_error( "Kernel names \"%s\" did not match:\n", kernel_names );
|
||||
for( i = 0; i < sizeof( actual_names ) / sizeof( actual_names[0] ); i++ )
|
||||
log_error( "\t\t\"%s\"\n", actual_names[0] );
|
||||
return -1;
|
||||
}
|
||||
free(kernel_names);
|
||||
|
||||
/* Try manually creating kernels (backwards just in case) */
|
||||
kernel1 = clCreateKernel( program, "sample_test", &error );
|
||||
if( kernel1 == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Could not get kernel 1" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
kernel2 = clCreateKernel( program, "sample_test2", &error );
|
||||
if( kernel2 == NULL )
|
||||
{
|
||||
print_error( error, "Could not get kernel 2" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *single_task_kernel[] = {
|
||||
"__kernel void sample_test(__global int *dst, int count)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" for( int i = 0; i < count; i++ )\n"
|
||||
" dst[i] = tid + i;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
int test_enqueue_task(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper output;
|
||||
cl_int count;
|
||||
|
||||
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, single_task_kernel, "sample_test" ) )
|
||||
return -1;
|
||||
|
||||
// Create args
|
||||
count = 100;
|
||||
output = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof( cl_int ) * count, NULL, &error );
|
||||
test_error( error, "Unable to create output buffer" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( cl_mem ), &output );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
error = clSetKernelArg( kernel, 1, sizeof( cl_int ), &count );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
|
||||
// Run task
|
||||
error = clEnqueueTask( queue, kernel, 0, NULL, NULL );
|
||||
test_error( error, "Unable to run task" );
|
||||
|
||||
// Read results
|
||||
cl_int *results = (cl_int*)malloc(sizeof(cl_int)*count);
|
||||
error = clEnqueueReadBuffer( queue, output, CL_TRUE, 0, sizeof( cl_int ) * count, results, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read results" );
|
||||
|
||||
// Validate
|
||||
for( cl_int i = 0; i < count; i++ )
|
||||
{
|
||||
if( results[ i ] != i )
|
||||
{
|
||||
log_error( "ERROR: Task result value %d did not validate! Expected %d, got %d\n", (int)i, (int)i, (int)results[ i ] );
|
||||
free(results);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* All done */
|
||||
free(results);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define TEST_SIZE 1000
|
||||
int test_repeated_setup_cleanup(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
|
||||
cl_context local_context;
|
||||
cl_command_queue local_queue;
|
||||
cl_program local_program;
|
||||
cl_kernel local_kernel;
|
||||
cl_mem local_mem_in, local_mem_out;
|
||||
cl_event local_event;
|
||||
size_t global_dim[3];
|
||||
int i, j, error;
|
||||
global_dim[0] = TEST_SIZE;
|
||||
global_dim[1] = 1; global_dim[2] = 1;
|
||||
cl_int *inData, *outData;
|
||||
cl_int status;
|
||||
|
||||
inData = (cl_int*)malloc(sizeof(cl_int)*TEST_SIZE);
|
||||
outData = (cl_int*)malloc(sizeof(cl_int)*TEST_SIZE);
|
||||
for (i=0; i<TEST_SIZE; i++) {
|
||||
inData[i] = i;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<100; i++) {
|
||||
memset(outData, 0, sizeof(cl_int)*TEST_SIZE);
|
||||
|
||||
local_context = clCreateContext(NULL, 1, &deviceID, notify_callback, NULL, &error);
|
||||
test_error( error, "clCreateContext failed");
|
||||
|
||||
local_queue = clCreateCommandQueueWithProperties(local_context, deviceID, 0, &error);
|
||||
test_error( error, "clCreateCommandQueue failed");
|
||||
|
||||
local_program = clCreateProgramWithSource(local_context, 1, &repeate_test_kernel, NULL, &error);
|
||||
test_error( error, "clCreateProgramWithSource failed");
|
||||
|
||||
error = clBuildProgram(local_program, 0, NULL, NULL, NULL, NULL);
|
||||
test_error( error, "clBuildProgram failed");
|
||||
|
||||
local_kernel = clCreateKernel(local_program, "test_kernel", &error);
|
||||
test_error( error, "clCreateKernel failed");
|
||||
|
||||
local_mem_in = clCreateBuffer(local_context, CL_MEM_READ_ONLY, TEST_SIZE*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
local_mem_out = clCreateBuffer(local_context, CL_MEM_WRITE_ONLY, TEST_SIZE*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
error = clEnqueueWriteBuffer(local_queue, local_mem_in, CL_TRUE, 0, TEST_SIZE*sizeof(cl_int), inData, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueWriteBuffer failed");
|
||||
|
||||
error = clEnqueueWriteBuffer(local_queue, local_mem_out, CL_TRUE, 0, TEST_SIZE*sizeof(cl_int), outData, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueWriteBuffer failed");
|
||||
|
||||
error = clSetKernelArg(local_kernel, 0, sizeof(local_mem_in), &local_mem_in);
|
||||
test_error( error, "clSetKernelArg failed");
|
||||
|
||||
error = clSetKernelArg(local_kernel, 1, sizeof(local_mem_out), &local_mem_out);
|
||||
test_error( error, "clSetKernelArg failed");
|
||||
|
||||
error = clEnqueueNDRangeKernel(local_queue, local_kernel, 1, NULL, global_dim, NULL, 0, NULL, &local_event);
|
||||
test_error( error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
error = clWaitForEvents(1, &local_event);
|
||||
test_error( error, "clWaitForEvents failed");
|
||||
|
||||
error = clGetEventInfo(local_event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(status), &status, NULL);
|
||||
test_error( error, "clGetEventInfo failed");
|
||||
|
||||
if (status != CL_COMPLETE) {
|
||||
log_error( "Kernel execution not complete: status %d.\n", status);
|
||||
free(inData);
|
||||
free(outData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clEnqueueReadBuffer(local_queue, local_mem_out, CL_TRUE, 0, TEST_SIZE*sizeof(cl_int), outData, 0, NULL, NULL);
|
||||
test_error( error, "clEnqueueReadBuffer failed");
|
||||
|
||||
clReleaseEvent(local_event);
|
||||
clReleaseMemObject(local_mem_in);
|
||||
clReleaseMemObject(local_mem_out);
|
||||
clReleaseKernel(local_kernel);
|
||||
clReleaseProgram(local_program);
|
||||
clReleaseCommandQueue(local_queue);
|
||||
clReleaseContext(local_context);
|
||||
|
||||
for (j=0; j<TEST_SIZE; j++) {
|
||||
if (outData[j] != inData[j] + 1) {
|
||||
log_error("Results failed to validate at iteration %d. %d != %d.\n", i, outData[j], inData[j] + 1);
|
||||
free(inData);
|
||||
free(outData);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(inData);
|
||||
free(outData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int IsAPowerOfTwo( unsigned long x )
|
||||
{
|
||||
return 0 == (x & (x-1));
|
||||
}
|
||||
|
||||
|
||||
int test_min_data_type_align_size_alignment(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems )
|
||||
{
|
||||
cl_uint min_alignment;
|
||||
|
||||
if (gHasLong)
|
||||
min_alignment = sizeof(cl_long)*16;
|
||||
else
|
||||
min_alignment = sizeof(cl_int)*16;
|
||||
|
||||
int error = 0;
|
||||
cl_uint alignment;
|
||||
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(alignment), &alignment, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_MEM_BASE_ADDR_ALIGN failed");
|
||||
log_info("Device reported CL_DEVICE_MEM_BASE_ADDR_ALIGN = %lu bits.\n", (unsigned long)alignment);
|
||||
|
||||
// Verify the size is large enough
|
||||
if (alignment < min_alignment*8) {
|
||||
log_error("ERROR: alignment too small. Minimum alignment for %s16 is %lu bits, device reported %lu bits.",
|
||||
(gHasLong) ? "long" : "int",
|
||||
(unsigned long)(min_alignment*8), (unsigned long)alignment);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Verify the size is a power of two
|
||||
if (!IsAPowerOfTwo((unsigned long)alignment)) {
|
||||
log_error("ERROR: alignment is not a power of two.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
141
test_conformance/api/test_kernel_arg_changes.cpp
Normal file
141
test_conformance/api/test_kernel_arg_changes.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
|
||||
extern "C" { extern cl_uint gRandomSeed;}
|
||||
|
||||
// This test is designed to stress changing kernel arguments between execute calls (that are asynchronous and thus
|
||||
// potentially overlapping) to make sure each kernel gets the right arguments
|
||||
|
||||
// Note: put a delay loop in the kernel to make sure we have time to queue the next kernel before this one finishes
|
||||
const char *inspect_image_kernel_source[] = {
|
||||
"__kernel void sample_test(read_only image2d_t src, __global int *outDimensions )\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0), i;\n"
|
||||
" for( i = 0; i < 100000; i++ ); \n"
|
||||
" outDimensions[tid * 2] = get_image_width(src) * tid;\n"
|
||||
" outDimensions[tid * 2 + 1] = get_image_height(src) * tid;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
#define NUM_TRIES 100
|
||||
#define NUM_THREADS 2048
|
||||
|
||||
int test_kernel_arg_changes(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
int error, i;
|
||||
clMemWrapper images[ NUM_TRIES ];
|
||||
size_t sizes[ NUM_TRIES ][ 2 ];
|
||||
clMemWrapper results[ NUM_TRIES ];
|
||||
cl_image_format imageFormat;
|
||||
size_t maxWidth, maxHeight;
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_int resultArray[ NUM_THREADS * 2 ];
|
||||
char errStr[ 128 ];
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
|
||||
|
||||
// Just get any ol format to test with
|
||||
error = get_8_bit_image_format( context, CL_MEM_OBJECT_IMAGE2D, CL_MEM_READ_WRITE, 0, &imageFormat );
|
||||
test_error( error, "Unable to obtain suitable image format to test with!" );
|
||||
|
||||
// Create our testing kernel
|
||||
error = create_single_kernel_helper( context, &program, &kernel, 1, inspect_image_kernel_source, "sample_test" );
|
||||
test_error( error, "Unable to create testing kernel" );
|
||||
|
||||
// Get max dimensions for each of our images
|
||||
error = clGetDeviceInfo( device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( maxWidth ), &maxWidth, NULL );
|
||||
error |= clGetDeviceInfo( device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof( maxHeight ), &maxHeight, NULL );
|
||||
test_error( error, "Unable to get max image dimensions for device" );
|
||||
|
||||
// Get the number of threads we'll be able to run
|
||||
threads[0] = NUM_THREADS;
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size for kernel" );
|
||||
|
||||
// Create a variety of images and output arrays
|
||||
for( i = 0; i < NUM_TRIES; i++ )
|
||||
{
|
||||
sizes[ i ][ 0 ] = genrand_int32(seed) % (maxWidth/32) + 1;
|
||||
sizes[ i ][ 1 ] = genrand_int32(seed) % (maxHeight/32) + 1;
|
||||
|
||||
images[ i ] = create_image_2d( context, (cl_mem_flags)(CL_MEM_READ_ONLY),
|
||||
&imageFormat, sizes[ i ][ 0], sizes[ i ][ 1 ], 0, NULL, &error );
|
||||
if( images[i] == NULL )
|
||||
{
|
||||
log_error("Failed to create image %d of size %d x %d (%s).\n", i, (int)sizes[i][0], (int)sizes[i][1], IGetErrorString( error ));
|
||||
return -1;
|
||||
}
|
||||
results[ i ] = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof( cl_int ) * threads[0] * 2, NULL, &error );
|
||||
if( results[i] == NULL)
|
||||
{
|
||||
log_error("Failed to create array %d of size %d.\n", i, (int)threads[0]*2);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Start setting arguments and executing kernels
|
||||
for( i = 0; i < NUM_TRIES; i++ )
|
||||
{
|
||||
// Set the arguments for this try
|
||||
error = clSetKernelArg( kernel, 0, sizeof( cl_mem ), &images[ i ] );
|
||||
sprintf( errStr, "Unable to set argument 0 for kernel try %d", i );
|
||||
test_error( error, errStr );
|
||||
|
||||
error = clSetKernelArg( kernel, 1, sizeof( cl_mem ), &results[ i ] );
|
||||
sprintf( errStr, "Unable to set argument 1 for kernel try %d", i );
|
||||
test_error( error, errStr );
|
||||
|
||||
// Queue up execution
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
sprintf( errStr, "Unable to execute kernel try %d", i );
|
||||
test_error( error, errStr );
|
||||
}
|
||||
|
||||
// Read the results back out, one at a time, and verify
|
||||
for( i = 0; i < NUM_TRIES; i++ )
|
||||
{
|
||||
error = clEnqueueReadBuffer( queue, results[ i ], CL_TRUE, 0, sizeof( cl_int ) * threads[0] * 2, resultArray, 0, NULL, NULL );
|
||||
sprintf( errStr, "Unable to read results for kernel try %d", i );
|
||||
test_error( error, errStr );
|
||||
|
||||
// Verify. Each entry should be n * the (width/height) of image i
|
||||
for( int j = 0; j < NUM_THREADS; j++ )
|
||||
{
|
||||
if( resultArray[ j * 2 + 0 ] != (int)sizes[ i ][ 0 ] * j )
|
||||
{
|
||||
log_error( "ERROR: Verficiation for kernel try %d, sample %d FAILED, expected a width of %d, got %d\n",
|
||||
i, j, (int)sizes[ i ][ 0 ] * j, resultArray[ j * 2 + 0 ] );
|
||||
return -1;
|
||||
}
|
||||
if( resultArray[ j * 2 + 1 ] != (int)sizes[ i ][ 1 ] * j )
|
||||
{
|
||||
log_error( "ERROR: Verficiation for kernel try %d, sample %d FAILED, expected a height of %d, got %d\n",
|
||||
i, j, (int)sizes[ i ][ 1 ] * j, resultArray[ j * 2 + 1 ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, everything verified successfully
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
5976
test_conformance/api/test_kernel_arg_info.c
Normal file
5976
test_conformance/api/test_kernel_arg_info.c
Normal file
File diff suppressed because it is too large
Load Diff
277
test_conformance/api/test_kernel_arg_multi_setup.cpp
Normal file
277
test_conformance/api/test_kernel_arg_multi_setup.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
|
||||
// This test is designed to stress passing multiple vector parameters to kernels and verifying access between them all
|
||||
|
||||
const char *multi_arg_kernel_source_pattern =
|
||||
"__kernel void sample_test(__global %s *src1, __global %s *src2, __global %s *src3, __global %s *dst1, __global %s *dst2, __global %s *dst3 )\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
" dst1[tid] = src1[tid];\n"
|
||||
" dst2[tid] = src2[tid];\n"
|
||||
" dst3[tid] = src3[tid];\n"
|
||||
"}\n";
|
||||
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
#define MAX_ERROR_TOLERANCE 0.0005f
|
||||
|
||||
int test_multi_arg_set(cl_device_id device, cl_context context, cl_command_queue queue,
|
||||
ExplicitType vec1Type, int vec1Size,
|
||||
ExplicitType vec2Type, int vec2Size,
|
||||
ExplicitType vec3Type, int vec3Size, MTdata d)
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
int error, i, j;
|
||||
clMemWrapper streams[ 6 ];
|
||||
size_t threads[1], localThreads[1];
|
||||
char programSrc[ 10248 ], vec1Name[ 64 ], vec2Name[ 64 ], vec3Name[ 64 ];
|
||||
char sizeNames[][ 4 ] = { "", "2", "3", "4", "", "", "", "8" };
|
||||
const char *ptr;
|
||||
void *initData[3], *resultData[3];
|
||||
|
||||
|
||||
// Create the program source
|
||||
sprintf( vec1Name, "%s%s", get_explicit_type_name( vec1Type ), sizeNames[ vec1Size - 1 ] );
|
||||
sprintf( vec2Name, "%s%s", get_explicit_type_name( vec2Type ), sizeNames[ vec2Size - 1 ] );
|
||||
sprintf( vec3Name, "%s%s", get_explicit_type_name( vec3Type ), sizeNames[ vec3Size - 1 ] );
|
||||
|
||||
sprintf( programSrc, multi_arg_kernel_source_pattern,
|
||||
vec1Name, vec2Name, vec3Name, vec1Name, vec2Name, vec3Name,
|
||||
vec1Size, vec1Size, vec2Size, vec2Size, vec3Size, vec3Size );
|
||||
ptr = programSrc;
|
||||
|
||||
// Create our testing kernel
|
||||
error = create_single_kernel_helper( context, &program, &kernel, 1, &ptr, "sample_test" );
|
||||
test_error( error, "Unable to create testing kernel" );
|
||||
|
||||
// Get thread dimensions
|
||||
threads[0] = 1024;
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size for kernel" );
|
||||
|
||||
// Create input streams
|
||||
initData[ 0 ] = create_random_data( vec1Type, d, (unsigned int)threads[ 0 ] * vec1Size );
|
||||
streams[ 0 ] = clCreateBuffer( context, (cl_mem_flags)( CL_MEM_COPY_HOST_PTR ), get_explicit_type_size( vec1Type ) * threads[0] * vec1Size, initData[ 0 ], &error );
|
||||
test_error( error, "Unable to create testing stream" );
|
||||
|
||||
initData[ 1 ] = create_random_data( vec2Type, d, (unsigned int)threads[ 0 ] * vec2Size );
|
||||
streams[ 1 ] = clCreateBuffer( context, (cl_mem_flags)( CL_MEM_COPY_HOST_PTR ), get_explicit_type_size( vec2Type ) * threads[0] * vec2Size, initData[ 1 ], &error );
|
||||
test_error( error, "Unable to create testing stream" );
|
||||
|
||||
initData[ 2 ] = create_random_data( vec3Type, d, (unsigned int)threads[ 0 ] * vec3Size );
|
||||
streams[ 2 ] = clCreateBuffer( context, (cl_mem_flags)( CL_MEM_COPY_HOST_PTR ), get_explicit_type_size( vec3Type ) * threads[0] * vec3Size, initData[ 2 ], &error );
|
||||
test_error( error, "Unable to create testing stream" );
|
||||
|
||||
streams[ 3 ] = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), get_explicit_type_size( vec1Type ) * threads[0] * vec1Size, NULL, &error );
|
||||
test_error( error, "Unable to create testing stream" );
|
||||
|
||||
streams[ 4 ] = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), get_explicit_type_size( vec2Type ) * threads[0] * vec2Size, NULL, &error );
|
||||
test_error( error, "Unable to create testing stream" );
|
||||
|
||||
streams[ 5 ] = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), get_explicit_type_size( vec3Type ) * threads[0] * vec3Size, NULL, &error );
|
||||
test_error( error, "Unable to create testing stream" );
|
||||
|
||||
// Set the arguments
|
||||
error = 0;
|
||||
for( i = 0; i < 6; i++ )
|
||||
error |= clSetKernelArg( kernel, i, sizeof( cl_mem ), &streams[ i ] );
|
||||
test_error( error, "Unable to set arguments for kernel" );
|
||||
|
||||
// Execute!
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute kernel" );
|
||||
|
||||
// Read results
|
||||
resultData[0] = malloc( get_explicit_type_size( vec1Type ) * vec1Size * threads[0] );
|
||||
resultData[1] = malloc( get_explicit_type_size( vec2Type ) * vec2Size * threads[0] );
|
||||
resultData[2] = malloc( get_explicit_type_size( vec3Type ) * vec3Size * threads[0] );
|
||||
error = clEnqueueReadBuffer( queue, streams[ 3 ], CL_TRUE, 0, get_explicit_type_size( vec1Type ) * vec1Size * threads[ 0 ], resultData[0], 0, NULL, NULL );
|
||||
error |= clEnqueueReadBuffer( queue, streams[ 4 ], CL_TRUE, 0, get_explicit_type_size( vec2Type ) * vec2Size * threads[ 0 ], resultData[1], 0, NULL, NULL );
|
||||
error |= clEnqueueReadBuffer( queue, streams[ 5 ], CL_TRUE, 0, get_explicit_type_size( vec3Type ) * vec3Size * threads[ 0 ], resultData[2], 0, NULL, NULL );
|
||||
test_error( error, "Unable to read result stream" );
|
||||
|
||||
// Verify
|
||||
char *ptr1 = (char *)initData[ 0 ], *ptr2 = (char *)resultData[ 0 ];
|
||||
size_t span = get_explicit_type_size( vec1Type );
|
||||
for( i = 0; i < (int)threads[0]; i++ )
|
||||
{
|
||||
for( j = 0; j < vec1Size; j++ )
|
||||
{
|
||||
if( memcmp( ptr1 + span * j , ptr2 + span * j, span ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Value did not validate for component %d of item %d of stream 0!\n", j, i );
|
||||
free( initData[ 0 ] );
|
||||
free( initData[ 1 ] );
|
||||
free( initData[ 2 ] );
|
||||
free( resultData[ 0 ] );
|
||||
free( resultData[ 1 ] );
|
||||
free( resultData[ 2 ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ptr1 += span * vec1Size;
|
||||
ptr2 += span * vec1Size;
|
||||
}
|
||||
|
||||
ptr1 = (char *)initData[ 1 ];
|
||||
ptr2 = (char *)resultData[ 1 ];
|
||||
span = get_explicit_type_size( vec2Type );
|
||||
for( i = 0; i < (int)threads[0]; i++ )
|
||||
{
|
||||
for( j = 0; j < vec2Size; j++ )
|
||||
{
|
||||
if( memcmp( ptr1 + span * j , ptr2 + span * j, span ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Value did not validate for component %d of item %d of stream 1!\n", j, i );
|
||||
free( initData[ 0 ] );
|
||||
free( initData[ 1 ] );
|
||||
free( initData[ 2 ] );
|
||||
free( resultData[ 0 ] );
|
||||
free( resultData[ 1 ] );
|
||||
free( resultData[ 2 ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ptr1 += span * vec2Size;
|
||||
ptr2 += span * vec2Size;
|
||||
}
|
||||
|
||||
ptr1 = (char *)initData[ 2 ];
|
||||
ptr2 = (char *)resultData[ 2 ];
|
||||
span = get_explicit_type_size( vec3Type );
|
||||
for( i = 0; i < (int)threads[0]; i++ )
|
||||
{
|
||||
for( j = 0; j < vec3Size; j++ )
|
||||
{
|
||||
if( memcmp( ptr1 + span * j , ptr2 + span * j, span ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Value did not validate for component %d of item %d of stream 2!\n", j, i );
|
||||
free( initData[ 0 ] );
|
||||
free( initData[ 1 ] );
|
||||
free( initData[ 2 ] );
|
||||
free( resultData[ 0 ] );
|
||||
free( resultData[ 1 ] );
|
||||
free( resultData[ 2 ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ptr1 += span * vec3Size;
|
||||
ptr2 += span * vec3Size;
|
||||
}
|
||||
|
||||
// If we got here, everything verified successfully
|
||||
free( initData[ 0 ] );
|
||||
free( initData[ 1 ] );
|
||||
free( initData[ 2 ] );
|
||||
free( resultData[ 0 ] );
|
||||
free( resultData[ 1 ] );
|
||||
free( resultData[ 2 ] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kernel_arg_multi_setup_exhaustive(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
// Loop through every combination of input and output types
|
||||
ExplicitType types[] = { kChar, kShort, kInt, kFloat, kNumExplicitTypes };
|
||||
int type1, type2, type3;
|
||||
int size1, size2, size3;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
log_info( "\n" ); // for formatting
|
||||
|
||||
for( type1 = 0; types[ type1 ] != kNumExplicitTypes; type1++ )
|
||||
{
|
||||
for( type2 = 0; types[ type2 ] != kNumExplicitTypes; type2++ )
|
||||
{
|
||||
for( type3 = 0; types[ type3 ] != kNumExplicitTypes; type3++ )
|
||||
{
|
||||
log_info( "\n\ttesting %s, %s, %s...", get_explicit_type_name( types[ type1 ] ), get_explicit_type_name( types[ type2 ] ), get_explicit_type_name( types[ type3 ] ) );
|
||||
|
||||
// Loop through every combination of vector size
|
||||
for( size1 = 2; size1 <= 8; size1 <<= 1 )
|
||||
{
|
||||
for( size2 = 2; size2 <= 8; size2 <<= 1 )
|
||||
{
|
||||
for( size3 = 2; size3 <= 8; size3 <<= 1 )
|
||||
{
|
||||
log_info(".");
|
||||
fflush( stdout);
|
||||
if( test_multi_arg_set( device, context, queue,
|
||||
types[ type1 ], size1,
|
||||
types[ type2 ], size2,
|
||||
types[ type3 ], size3, seed ) )
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log_info( "\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kernel_arg_multi_setup_random(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
// Loop through a selection of combinations
|
||||
ExplicitType types[] = { kChar, kShort, kInt, kFloat, kNumExplicitTypes };
|
||||
int type1, type2, type3;
|
||||
int size1, size2, size3;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
|
||||
num_elements = 3*3*3*4;
|
||||
log_info( "Testing %d random configurations\n", num_elements );
|
||||
|
||||
// Loop through every combination of vector size
|
||||
for( size1 = 2; size1 <= 8; size1 <<= 1 )
|
||||
{
|
||||
for( size2 = 2; size2 <= 8; size2 <<= 1 )
|
||||
{
|
||||
for( size3 = 2; size3 <= 8; size3 <<= 1 )
|
||||
{
|
||||
// Loop through 4 type combinations for each size combination
|
||||
int n;
|
||||
for (n=0; n<4; n++) {
|
||||
type1 = (int)get_random_float(0,4, seed);
|
||||
type2 = (int)get_random_float(0,4, seed);
|
||||
type3 = (int)get_random_float(0,4, seed);
|
||||
|
||||
|
||||
log_info( "\ttesting %s%d, %s%d, %s%d...\n",
|
||||
get_explicit_type_name( types[ type1 ] ), size1,
|
||||
get_explicit_type_name( types[ type2 ] ), size2,
|
||||
get_explicit_type_name( types[ type3 ] ), size3 );
|
||||
|
||||
if( test_multi_arg_set( device, context, queue,
|
||||
types[ type1 ], size1,
|
||||
types[ type2 ], size2,
|
||||
types[ type3 ], size3, seed ) )
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
704
test_conformance/api/test_kernels.c
Normal file
704
test_conformance/api/test_kernels.c
Normal file
@@ -0,0 +1,704 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
const char *sample_single_test_kernel[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *sample_struct_test_kernel[] = {
|
||||
"typedef struct {\n"
|
||||
"__global int *A;\n"
|
||||
"__global int *B;\n"
|
||||
"} input_pair_t;\n"
|
||||
"\n"
|
||||
"__kernel void sample_test(__global input_pair_t *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = src->A[tid] + src->B[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *sample_struct_array_test_kernel[] = {
|
||||
"typedef struct {\n"
|
||||
"int A;\n"
|
||||
"int B;\n"
|
||||
"} input_pair_t;\n"
|
||||
"\n"
|
||||
"__kernel void sample_test(__global input_pair_t *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = src[tid].A + src[tid].B;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *sample_const_test_kernel[] = {
|
||||
"__kernel void sample_test(__constant int *src1, __constant int *src2, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = src1[tid] + src2[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *sample_const_global_test_kernel[] = {
|
||||
"__constant int addFactor = 1024;\n"
|
||||
"__kernel void sample_test(__global int *src1, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = src1[tid] + addFactor;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *sample_two_kernel_program[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n",
|
||||
"__kernel void sample_test2(__global int *src, __global float *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"\n"
|
||||
" dst[tid] = (float)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
|
||||
|
||||
|
||||
int test_get_kernel_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program, testProgram;
|
||||
cl_context testContext;
|
||||
cl_kernel kernel;
|
||||
cl_char name[ 512 ];
|
||||
cl_uint numArgs, numInstances;
|
||||
size_t paramSize;
|
||||
|
||||
|
||||
/* Create reference */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_single_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_FUNCTION_NAME, NULL, 0, ¶mSize );
|
||||
test_error( error, "Unable to get kernel function name param size" );
|
||||
if( paramSize != strlen( "sample_test" ) + 1 )
|
||||
{
|
||||
log_error( "ERROR: Kernel function name param returns invalid size (expected %d, got %d)\n", (int)strlen( "sample_test" ) + 1, (int)paramSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_FUNCTION_NAME, sizeof( name ), name, NULL );
|
||||
test_error( error, "Unable to get kernel function name" );
|
||||
if( strcmp( (char *)name, "sample_test" ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Kernel function name returned invalid value (expected sample_test, got %s)\n", (char *)name );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_NUM_ARGS, 0, NULL, ¶mSize );
|
||||
test_error( error, "Unable to get kernel arg count param size" );
|
||||
if( paramSize != sizeof( numArgs ) )
|
||||
{
|
||||
log_error( "ERROR: Kernel arg count param returns invalid size (expected %d, got %d)\n", (int)sizeof( numArgs ), (int)paramSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_NUM_ARGS, sizeof( numArgs ), &numArgs, NULL );
|
||||
test_error( error, "Unable to get kernel arg count" );
|
||||
if( numArgs != 2 )
|
||||
{
|
||||
log_error( "ERROR: Kernel arg count returned invalid value (expected %d, got %d)\n", 2, numArgs );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_REFERENCE_COUNT, 0, NULL, ¶mSize );
|
||||
test_error( error, "Unable to get kernel reference count param size" );
|
||||
if( paramSize != sizeof( numInstances ) )
|
||||
{
|
||||
log_error( "ERROR: Kernel reference count param returns invalid size (expected %d, got %d)\n", (int)sizeof( numInstances ), (int)paramSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_REFERENCE_COUNT, sizeof( numInstances ), &numInstances, NULL );
|
||||
test_error( error, "Unable to get kernel reference count" );
|
||||
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_PROGRAM, NULL, 0, ¶mSize );
|
||||
test_error( error, "Unable to get kernel program param size" );
|
||||
if( paramSize != sizeof( testProgram ) )
|
||||
{
|
||||
log_error( "ERROR: Kernel program param returns invalid size (expected %d, got %d)\n", (int)sizeof( testProgram ), (int)paramSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_PROGRAM, sizeof( testProgram ), &testProgram, NULL );
|
||||
test_error( error, "Unable to get kernel program" );
|
||||
if( testProgram != program )
|
||||
{
|
||||
log_error( "ERROR: Kernel program returned invalid value (expected %p, got %p)\n", program, testProgram );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetKernelInfo( kernel, CL_KERNEL_CONTEXT, sizeof( testContext ), &testContext, NULL );
|
||||
test_error( error, "Unable to get kernel context" );
|
||||
if( testContext != context )
|
||||
{
|
||||
log_error( "ERROR: Kernel context returned invalid value (expected %p, got %p)\n", context, testContext );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Release memory */
|
||||
clReleaseKernel( kernel );
|
||||
clReleaseProgram( program );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[2];
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_float inputData[100];
|
||||
cl_int outputData[100];
|
||||
RandomSeed seed( gRandomSeed );
|
||||
int i;
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_single_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float) * 100, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 100, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Write some test data */
|
||||
memset( outputData, 0, sizeof( outputData ) );
|
||||
|
||||
for (i=0; i<100; i++)
|
||||
inputData[i] = get_random_float(-(float) 0x7fffffff, (float) 0x7fffffff, seed);
|
||||
|
||||
error = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*100, (void *)inputData, 0, NULL, NULL);
|
||||
test_error( error, "Unable to set testing kernel data" );
|
||||
|
||||
/* Set the arguments */
|
||||
error = clSetKernelArg( kernel, 0, sizeof( streams[0] ), &streams[0] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
error = clSetKernelArg( kernel, 1, sizeof( streams[1] ), &streams[1] );
|
||||
test_error( error, "Unable to set kernel arguments" );
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)100;
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
if (outputData[i] != (int)inputData[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify on first pass!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try again */
|
||||
if( localThreads[0] > 1 )
|
||||
localThreads[0] /= 2;
|
||||
while( localThreads[0] > 1 && 0 != threads[0] % localThreads[0] )
|
||||
localThreads[0]--;
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
if (outputData[i] != (int)inputData[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify on first pass!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* And again */
|
||||
if( localThreads[0] > 1 )
|
||||
localThreads[0] /= 2;
|
||||
while( localThreads[0] > 1 && 0 != threads[0] % localThreads[0] )
|
||||
localThreads[0]--;
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
if (outputData[i] != (int)inputData[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify on first pass!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* One more time */
|
||||
localThreads[0] = (unsigned int)1;
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<100; i++)
|
||||
{
|
||||
if (outputData[i] != (int)inputData[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify on first pass!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[2];
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_float inputData[10];
|
||||
cl_int outputData[10];
|
||||
RandomSeed seed( gRandomSeed );
|
||||
int i;
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_single_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Write some test data */
|
||||
memset( outputData, 0, sizeof( outputData ) );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
inputData[i] = get_random_float(-(float) 0x7fffffff, (float) 0x7fffffff, seed);
|
||||
|
||||
error = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*10, (void *)inputData, 0, NULL, NULL);
|
||||
test_error( error, "Unable to set testing kernel data" );
|
||||
|
||||
/* Test setting the arguments by index manually */
|
||||
error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)10;
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if (outputData[i] != (int)inputData[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify on first pass!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_set_kernel_arg_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
cl_kernel kernel;
|
||||
void *args[2];
|
||||
cl_mem outStream;
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_int outputData[10];
|
||||
int i;
|
||||
cl_int randomTestDataA[10], randomTestDataB[10];
|
||||
MTdata d;
|
||||
|
||||
struct img_pair_t
|
||||
{
|
||||
cl_mem streamA;
|
||||
cl_mem streamB;
|
||||
} image_pair;
|
||||
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_struct_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
d = init_genrand( gRandomSeed );
|
||||
for( i = 0; i < 10; i++ )
|
||||
{
|
||||
randomTestDataA[i] = (cl_int)genrand_int32(d);
|
||||
randomTestDataB[i] = (cl_int)genrand_int32(d);
|
||||
}
|
||||
free_mtdata(d); d = NULL;
|
||||
|
||||
image_pair.streamA = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataA, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
image_pair.streamB = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataB, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
outStream = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Set the arguments */
|
||||
args[0] = &image_pair;
|
||||
args[1] = outStream;
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof( image_pair ), &image_pair);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 1, sizeof( cl_mem ), &args[1]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)10;
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, outStream, CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if (outputData[i] != randomTestDataA[i] + randomTestDataB[i])
|
||||
{
|
||||
log_error( "ERROR: Data did not verify!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
clReleaseMemObject( image_pair.streamA );
|
||||
clReleaseMemObject( image_pair.streamB );
|
||||
clReleaseMemObject( outStream );
|
||||
clReleaseKernel( kernel );
|
||||
clReleaseProgram( program );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[3];
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_int outputData[10];
|
||||
int i;
|
||||
cl_int randomTestDataA[10], randomTestDataB[10];
|
||||
cl_ulong maxSize;
|
||||
MTdata d;
|
||||
|
||||
/* Verify our test buffer won't be bigger than allowed */
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( maxSize ), &maxSize, 0 );
|
||||
test_error( error, "Unable to get max constant buffer size" );
|
||||
if( maxSize < sizeof( cl_int ) * 10 )
|
||||
{
|
||||
log_error( "ERROR: Unable to test constant argument to kernel: max size of constant buffer is reported as %d!\n", (int)maxSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_const_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
d = init_genrand( gRandomSeed );
|
||||
for( i = 0; i < 10; i++ )
|
||||
{
|
||||
randomTestDataA[i] = (cl_int)genrand_int32(d) & 0xffffff; /* Make sure values are positive, just so we don't have to */
|
||||
randomTestDataB[i] = (cl_int)genrand_int32(d) & 0xffffff; /* deal with overflow on the verification */
|
||||
}
|
||||
free_mtdata(d); d = NULL;
|
||||
|
||||
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataA, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataB, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[2] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Set the arguments */
|
||||
error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 2, sizeof( streams[2] ), &streams[2]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)10;
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[2], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if (outputData[i] != randomTestDataA[i] + randomTestDataB[i])
|
||||
{
|
||||
log_error( "ERROR: Data sample %d did not verify! %d does not match %d + %d (%d)\n", i, outputData[i], randomTestDataA[i], randomTestDataB[i], ( randomTestDataA[i] + randomTestDataB[i] ) );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_set_kernel_arg_struct_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[2];
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_int outputData[10];
|
||||
int i;
|
||||
MTdata d;
|
||||
|
||||
typedef struct img_pair_type
|
||||
{
|
||||
int A;
|
||||
int B;
|
||||
} image_pair_t;
|
||||
|
||||
image_pair_t image_pair[ 10 ];
|
||||
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_struct_array_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
d = init_genrand( gRandomSeed );
|
||||
for( i = 0; i < 10; i++ )
|
||||
{
|
||||
image_pair[i].A = (cl_int)genrand_int32(d);
|
||||
image_pair[i].A = (cl_int)genrand_int32(d);
|
||||
}
|
||||
free_mtdata(d); d = NULL;
|
||||
|
||||
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(image_pair_t) * 10, (void *)image_pair, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Set the arguments */
|
||||
error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)10;
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if (outputData[i] != image_pair[i].A + image_pair[i].B)
|
||||
{
|
||||
log_error( "ERROR: Data did not verify!\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_create_kernels_in_program(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
cl_kernel kernel[3];
|
||||
unsigned int kernelCount;
|
||||
|
||||
/* Create a test program */
|
||||
program = clCreateProgramWithSource( context, 2, sample_two_kernel_program, NULL, &error);
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: Unable to create test program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build test program" );
|
||||
|
||||
/* Try getting the kernel count */
|
||||
error = clCreateKernelsInProgram( program, 0, NULL, &kernelCount );
|
||||
test_error( error, "Unable to get kernel count for built program" );
|
||||
if( kernelCount != 2 )
|
||||
{
|
||||
log_error( "ERROR: Returned kernel count from clCreateKernelsInProgram is incorrect! (got %d, expected 2)\n", kernelCount );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try actually getting the kernels */
|
||||
error = clCreateKernelsInProgram( program, 2, kernel, NULL );
|
||||
test_error( error, "Unable to get kernels for built program" );
|
||||
clReleaseKernel( kernel[0] );
|
||||
clReleaseKernel( kernel[1] );
|
||||
|
||||
clReleaseProgram( program );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_kernel_global_constant(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper streams[2];
|
||||
size_t threads[1], localThreads[1];
|
||||
cl_int outputData[10];
|
||||
int i;
|
||||
cl_int randomTestDataA[10];
|
||||
MTdata d;
|
||||
|
||||
|
||||
/* Create a kernel to test with */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_const_global_test_kernel, "sample_test" ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create some I/O streams */
|
||||
d = init_genrand( gRandomSeed );
|
||||
for( i = 0; i < 10; i++ )
|
||||
{
|
||||
randomTestDataA[i] = (cl_int)genrand_int32(d) & 0xffff; /* Make sure values are positive and small, just so we don't have to */
|
||||
}
|
||||
free_mtdata(d); d = NULL;
|
||||
|
||||
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataA, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Set the arguments */
|
||||
error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[0]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[1]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
|
||||
/* Test running the kernel and verifying it */
|
||||
threads[0] = (size_t)10;
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
|
||||
test_error( error, "Unable to get work group size to use" );
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
|
||||
test_error( error, "Kernel execution failed" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
|
||||
test_error( error, "Unable to get result data" );
|
||||
|
||||
for (i=0; i<10; i++)
|
||||
{
|
||||
if (outputData[i] != randomTestDataA[i] + 1024)
|
||||
{
|
||||
log_error( "ERROR: Data sample %d did not verify! %d does not match %d + 1024 (%d)\n", i, outputData[i], randomTestDataA[i], ( randomTestDataA[i] + 1024 ) );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
756
test_conformance/api/test_mem_object_info.cpp
Normal file
756
test_conformance/api/test_mem_object_info.cpp
Normal file
@@ -0,0 +1,756 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
|
||||
#define TEST_MEM_OBJECT_PARAM( mem, paramName, val, expected, name, type, cast ) \
|
||||
error = clGetMemObjectInfo( mem, paramName, sizeof( val ), &val, &size ); \
|
||||
test_error( error, "Unable to get mem object " name ); \
|
||||
if( val != expected ) \
|
||||
{ \
|
||||
log_error( "ERROR: Mem object " name " did not validate! (expected " type ", got " type " from %s:%d)\n", \
|
||||
expected, (cast)val, __FILE__, __LINE__ ); \
|
||||
return -1; \
|
||||
} \
|
||||
if( size != sizeof( val ) ) \
|
||||
{ \
|
||||
log_error( "ERROR: Returned size of mem object " name " does not validate! (expected %d, got %d from %s:%d)\n", \
|
||||
(int)sizeof( val ), (int)size , __FILE__, __LINE__ ); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
static void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void * data )
|
||||
{
|
||||
free( data );
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
get_image_dim(MTdata *d, unsigned int mod)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
do
|
||||
{
|
||||
val = (unsigned int)genrand_int32(*d) % mod;
|
||||
} while (val == 0);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
void * buffer = NULL;
|
||||
|
||||
clMemWrapper bufferObject;
|
||||
clMemWrapper subBufferObject;
|
||||
|
||||
cl_mem_flags bufferFlags[] = {
|
||||
CL_MEM_READ_WRITE,
|
||||
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_READ_ONLY,
|
||||
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
};
|
||||
|
||||
cl_mem_flags subBufferFlags[] = {
|
||||
CL_MEM_READ_WRITE,
|
||||
CL_MEM_READ_ONLY,
|
||||
CL_MEM_WRITE_ONLY,
|
||||
0,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_READ_ONLY | 0,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_WRITE_ONLY | 0,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_NO_ACCESS | 0,
|
||||
};
|
||||
|
||||
|
||||
// Get the address alignment, so we can make sure the sub-buffer test later works properly.
|
||||
cl_uint addressAlignBits;
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(addressAlignBits), &addressAlignBits, NULL );
|
||||
|
||||
size_t addressAlign = addressAlignBits/8;
|
||||
if ( addressAlign < 128 )
|
||||
{
|
||||
addressAlign = 128;
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < sizeof(bufferFlags) / sizeof(cl_mem_flags); ++i )
|
||||
{
|
||||
//printf("@@@ bufferFlags[%u]=0x%x\n", i, bufferFlags[ i ]);
|
||||
if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR )
|
||||
{
|
||||
// Create a buffer object to test against.
|
||||
buffer = malloc( addressAlign * 4 );
|
||||
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( buffer );
|
||||
test_error( error, "Unable to create buffer (CL_MEM_USE_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
|
||||
void * ptr;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_HOST_PTR, ptr, buffer, "host pointer", "%p", void * )
|
||||
}
|
||||
else if ( (bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR) && (bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR) )
|
||||
{
|
||||
// Create a buffer object to test against.
|
||||
buffer = malloc( addressAlign * 4 );
|
||||
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( buffer );
|
||||
test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
}
|
||||
else if ( bufferFlags[ i ] & CL_MEM_ALLOC_HOST_PTR )
|
||||
{
|
||||
// Create a buffer object to test against.
|
||||
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
|
||||
test_error( error, "Unable to create buffer (CL_MEM_ALLOC_HOST_PTR) to test with" );
|
||||
}
|
||||
else if ( bufferFlags[ i ] & CL_MEM_COPY_HOST_PTR )
|
||||
{
|
||||
// Create a buffer object to test against.
|
||||
buffer = malloc( addressAlign * 4 );
|
||||
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, buffer, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( buffer );
|
||||
test_error( error, "Unable to create buffer (CL_MEM_COPY_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( bufferObject, mem_obj_destructor_callback, buffer );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a buffer object to test against.
|
||||
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
|
||||
test_error( error, "Unable to create buffer to test with" );
|
||||
}
|
||||
|
||||
// Perform buffer object queries.
|
||||
cl_mem_object_type type;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int )
|
||||
|
||||
cl_mem_flags flags;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_FLAGS, flags, (unsigned int)bufferFlags[ i ], "flags", "%d", unsigned int )
|
||||
|
||||
size_t sz;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign * 4 ), "size", "%ld", size_t )
|
||||
|
||||
cl_uint mapCount;
|
||||
error = clGetMemObjectInfo( bufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
|
||||
test_error( error, "Unable to get mem object map count" );
|
||||
if( size != sizeof( mapCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
|
||||
(int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_uint refCount;
|
||||
error = clGetMemObjectInfo( bufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
|
||||
test_error( error, "Unable to get mem object reference count" );
|
||||
if( size != sizeof( refCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
|
||||
(int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_context otherCtx;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
|
||||
|
||||
cl_mem origObj;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (void *)NULL, "associated mem object", "%p", void * )
|
||||
|
||||
size_t offset;
|
||||
TEST_MEM_OBJECT_PARAM( bufferObject, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t )
|
||||
|
||||
cl_buffer_region region;
|
||||
region.origin = addressAlign;
|
||||
region.size = addressAlign;
|
||||
|
||||
// Loop over possible sub-buffer objects to create.
|
||||
for ( unsigned int j = 0; j < sizeof(subBufferFlags) / sizeof(cl_mem_flags); ++j )
|
||||
{
|
||||
if ( subBufferFlags[ j ] & CL_MEM_READ_WRITE )
|
||||
{
|
||||
if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) )
|
||||
continue; // Buffer must be read_write for sub-buffer to be read_write.
|
||||
}
|
||||
if ( subBufferFlags[ j ] & CL_MEM_READ_ONLY )
|
||||
{
|
||||
if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_READ_ONLY) )
|
||||
continue; // Buffer must be read_write or read_only for sub-buffer to be read_only
|
||||
}
|
||||
if ( subBufferFlags[ j ] & CL_MEM_WRITE_ONLY )
|
||||
{
|
||||
if ( !(bufferFlags[ i ] & CL_MEM_READ_WRITE) && !(bufferFlags[ i ] & CL_MEM_WRITE_ONLY) )
|
||||
continue; // Buffer must be read_write or write_only for sub-buffer to be write_only
|
||||
}
|
||||
if ( subBufferFlags[ j ] & CL_MEM_HOST_READ_ONLY )
|
||||
{
|
||||
if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_WRITE_ONLY) )
|
||||
continue; // Buffer must be host all access or host read_only for sub-buffer to be host read_only
|
||||
}
|
||||
if ( subBufferFlags[ j ] & CL_MEM_HOST_WRITE_ONLY )
|
||||
{
|
||||
if ( (bufferFlags[ i ] & CL_MEM_HOST_NO_ACCESS) || (bufferFlags[ i ] & CL_MEM_HOST_READ_ONLY) )
|
||||
continue; // Buffer must be host all access or host write_only for sub-buffer to be host write_only
|
||||
}
|
||||
//printf("@@@ bufferFlags[%u]=0x%x subBufferFlags[%u]=0x%x\n", i, bufferFlags[ i ], j, subBufferFlags[ j ]);
|
||||
|
||||
subBufferObject = clCreateSubBuffer( bufferObject, subBufferFlags[ j ], CL_BUFFER_CREATE_TYPE_REGION, ®ion, &error );
|
||||
test_error( error, "Unable to create sub-buffer to test against" );
|
||||
|
||||
// Perform sub-buffer object queries.
|
||||
cl_mem_object_type type;
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_TYPE, type, CL_MEM_OBJECT_BUFFER, "type", "%d", int )
|
||||
|
||||
cl_mem_flags flags;
|
||||
cl_mem_flags inheritedFlags = subBufferFlags[ j ];
|
||||
if ( (subBufferFlags[ j ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY)) == 0 )
|
||||
{
|
||||
inheritedFlags |= bufferFlags[ i ] & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);
|
||||
}
|
||||
inheritedFlags |= bufferFlags[ i ] & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR);
|
||||
if ( (subBufferFlags[ j ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) == 0)
|
||||
{
|
||||
inheritedFlags |= bufferFlags[ i ] & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS);
|
||||
}
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_FLAGS, flags, (unsigned int)inheritedFlags, "flags", "%d", unsigned int )
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_SIZE, sz, (size_t)( addressAlign ), "size", "%ld", size_t )
|
||||
|
||||
if ( bufferFlags[ i ] & CL_MEM_USE_HOST_PTR )
|
||||
{
|
||||
void * ptr;
|
||||
void * offsetInBuffer = (char *)buffer + addressAlign;
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_HOST_PTR, ptr, offsetInBuffer, "host pointer", "%p", void * )
|
||||
}
|
||||
|
||||
cl_uint mapCount;
|
||||
error = clGetMemObjectInfo( subBufferObject, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
|
||||
test_error( error, "Unable to get mem object map count" );
|
||||
if( size != sizeof( mapCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
|
||||
(int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_uint refCount;
|
||||
error = clGetMemObjectInfo( subBufferObject, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
|
||||
test_error( error, "Unable to get mem object reference count" );
|
||||
if( size != sizeof( refCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
|
||||
(int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_context otherCtx;
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (cl_mem)bufferObject, "associated mem object", "%p", void * )
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_OFFSET, offset, (size_t)( addressAlign ), "offset", "%ld", size_t )
|
||||
|
||||
clReleaseMemObject( subBufferObject );
|
||||
subBufferObject = NULL;
|
||||
|
||||
}
|
||||
|
||||
clReleaseMemObject( bufferObject );
|
||||
bufferObject = NULL;
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int test_get_imageObject_info( cl_mem * image, cl_mem_flags objectFlags, cl_image_desc *imageInfo, cl_image_format *imageFormat, size_t pixelSize, cl_context context )
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
cl_mem_object_type type;
|
||||
cl_mem_flags flags;
|
||||
cl_uint mapCount;
|
||||
cl_uint refCount;
|
||||
size_t rowPitchMultiplier;
|
||||
size_t slicePitchMultiplier;
|
||||
cl_context otherCtx;
|
||||
size_t offset;
|
||||
size_t sz;
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_TYPE, type, imageInfo->image_type, "type", "%d", int )
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_FLAGS, flags, (unsigned int)objectFlags, "flags", "%d", unsigned int )
|
||||
|
||||
error = clGetMemObjectInfo( *image, CL_MEM_SIZE, sizeof( sz ), &sz, NULL );
|
||||
test_error( error, "Unable to get mem size" );
|
||||
|
||||
// The size returned is not constrained by the spec.
|
||||
|
||||
error = clGetMemObjectInfo( *image, CL_MEM_MAP_COUNT, sizeof( mapCount ), &mapCount, &size );
|
||||
test_error( error, "Unable to get mem object map count" );
|
||||
if( size != sizeof( mapCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of mem object map count does not validate! (expected %d, got %d from %s:%d)\n",
|
||||
(int)sizeof( mapCount ), (int)size, __FILE__, __LINE__ );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetMemObjectInfo( *image, CL_MEM_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
|
||||
test_error( error, "Unable to get mem object reference count" );
|
||||
if( size != sizeof( refCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of mem object reference count does not validate! (expected %d, got %d from %s:%d)\n",
|
||||
(int)sizeof( refCount ), (int)size, __FILE__, __LINE__ );
|
||||
return -1;
|
||||
}
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_CONTEXT, otherCtx, context, "context", "%p", cl_context )
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( *image, CL_MEM_OFFSET, offset, 0L, "offset", "%ld", size_t )
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_object_type type )
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
void * image = NULL;
|
||||
|
||||
cl_mem imageObject;
|
||||
cl_image_desc imageInfo;
|
||||
|
||||
cl_mem_flags imageFlags[] = {
|
||||
CL_MEM_READ_WRITE,
|
||||
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_READ_ONLY,
|
||||
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_READ_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_WRITE_ONLY | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
};
|
||||
MTdata d;
|
||||
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
|
||||
|
||||
cl_image_format imageFormat;
|
||||
size_t pixelSize = 4;
|
||||
|
||||
imageFormat.image_channel_order = CL_RGBA;
|
||||
imageFormat.image_channel_data_type = CL_UNORM_INT8;
|
||||
|
||||
imageInfo.image_width = imageInfo.image_height = imageInfo.image_depth = 1;
|
||||
imageInfo.image_array_size = 0;
|
||||
imageInfo.num_mip_levels = imageInfo.num_samples = 0;
|
||||
imageInfo.mem_object = NULL;
|
||||
|
||||
d = init_genrand( gRandomSeed );
|
||||
|
||||
for ( unsigned int i = 0; i < sizeof(imageFlags) / sizeof(cl_mem_flags); ++i )
|
||||
{
|
||||
imageInfo.image_row_pitch = 0;
|
||||
imageInfo.image_slice_pitch = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D:
|
||||
imageInfo.image_width = get_image_dim(&d, 1023);
|
||||
imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D;
|
||||
break;
|
||||
|
||||
case CL_MEM_OBJECT_IMAGE2D:
|
||||
imageInfo.image_width = get_image_dim(&d, 1023);
|
||||
imageInfo.image_height = get_image_dim(&d, 1023);
|
||||
imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D;
|
||||
break;
|
||||
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
error = checkFor3DImageSupport(deviceID);
|
||||
if (error == CL_IMAGE_FORMAT_NOT_SUPPORTED)
|
||||
{
|
||||
log_info("Device doesn't support 3D images. Skipping test.\n");
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
imageInfo.image_width = get_image_dim(&d, 127);
|
||||
imageInfo.image_height = get_image_dim(&d, 127);
|
||||
imageInfo.image_depth = get_image_dim(&d, 127);
|
||||
imageInfo.image_type = CL_MEM_OBJECT_IMAGE3D;
|
||||
break;
|
||||
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
imageInfo.image_width = get_image_dim(&d, 1023);
|
||||
imageInfo.image_array_size = get_image_dim(&d, 1023);
|
||||
imageInfo.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
|
||||
break;
|
||||
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
imageInfo.image_width = get_image_dim(&d, 255);
|
||||
imageInfo.image_height = get_image_dim(&d, 255);
|
||||
imageInfo.image_array_size = get_image_dim(&d, 255);
|
||||
imageInfo.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( imageFlags[i] & CL_MEM_USE_HOST_PTR )
|
||||
{
|
||||
// Create an image object to test against.
|
||||
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
|
||||
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( image );
|
||||
test_error( error, "Unable to create image with (CL_MEM_USE_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
|
||||
void * ptr;
|
||||
TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * )
|
||||
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
// release image object
|
||||
clReleaseMemObject(imageObject);
|
||||
|
||||
// Try again with non-zero rowPitch.
|
||||
imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
|
||||
switch (type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
|
||||
break;
|
||||
}
|
||||
|
||||
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
|
||||
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( image );
|
||||
test_error( error, "Unable to create image2d (CL_MEM_USE_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure image2d is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
|
||||
TEST_MEM_OBJECT_PARAM( imageObject, CL_MEM_HOST_PTR, ptr, image, "host pointer", "%p", void * )
|
||||
ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
}
|
||||
else if ( (imageFlags[i] & CL_MEM_ALLOC_HOST_PTR) && (imageFlags[i] & CL_MEM_COPY_HOST_PTR) )
|
||||
{
|
||||
// Create an image object to test against.
|
||||
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
|
||||
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( image );
|
||||
test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
int ret = test_get_imageObject_info( &imageObject, imageFlags[ i ], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
// release image object
|
||||
clReleaseMemObject(imageObject);
|
||||
|
||||
// Try again with non-zero rowPitch.
|
||||
imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
|
||||
switch (type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
|
||||
break;
|
||||
}
|
||||
|
||||
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
|
||||
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( image );
|
||||
test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
}
|
||||
else if ( imageFlags[i] & CL_MEM_ALLOC_HOST_PTR )
|
||||
{
|
||||
// Create an image object to test against.
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error );
|
||||
test_error( error, "Unable to create image with (CL_MEM_ALLOC_HOST_PTR) to test with" );
|
||||
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
}
|
||||
else if ( imageFlags[i] & CL_MEM_COPY_HOST_PTR )
|
||||
{
|
||||
// Create an image object to test against.
|
||||
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
|
||||
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( image );
|
||||
test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clReleaseMemObject(imageObject);
|
||||
|
||||
// Try again with non-zero rowPitch.
|
||||
imageInfo.image_row_pitch = imageInfo.image_width * pixelSize;
|
||||
switch (type)
|
||||
{
|
||||
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
||||
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
||||
case CL_MEM_OBJECT_IMAGE3D:
|
||||
imageInfo.image_slice_pitch = imageInfo.image_row_pitch * imageInfo.image_height;
|
||||
break;
|
||||
}
|
||||
|
||||
image = malloc( imageInfo.image_width * imageInfo.image_height * imageInfo.image_depth * pixelSize *
|
||||
((imageInfo.image_array_size == 0) ? 1 : imageInfo.image_array_size) );
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, image, &error );
|
||||
if ( error )
|
||||
{
|
||||
free( image );
|
||||
test_error( error, "Unable to create image with (CL_MEM_COPY_HOST_PTR) to test with" );
|
||||
}
|
||||
|
||||
// Make sure image is cleaned up appropriately if we encounter an error in the rest of the calls.
|
||||
error = clSetMemObjectDestructorCallback( imageObject, mem_obj_destructor_callback, image );
|
||||
test_error( error, "Unable to set mem object destructor callback" );
|
||||
ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create an image object to test against.
|
||||
imageObject = clCreateImage( context, imageFlags[i], &imageFormat, &imageInfo, NULL, &error );
|
||||
test_error( error, "Unable to create image to test with" );
|
||||
int ret = test_get_imageObject_info( &imageObject, imageFlags[i], &imageInfo, &imageFormat, pixelSize, context );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
clReleaseMemObject( imageObject );
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int test_get_image2d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
|
||||
{
|
||||
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D);
|
||||
}
|
||||
|
||||
int test_get_image3d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
|
||||
{
|
||||
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE3D);
|
||||
}
|
||||
|
||||
int test_get_image1d_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
|
||||
{
|
||||
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D);
|
||||
}
|
||||
|
||||
int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
|
||||
{
|
||||
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE1D_ARRAY);
|
||||
}
|
||||
|
||||
int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements )
|
||||
{
|
||||
return test_get_image_info(deviceID, context, CL_MEM_OBJECT_IMAGE2D_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
108
test_conformance/api/test_mem_objects.cpp
Normal file
108
test_conformance/api/test_mem_objects.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
|
||||
static volatile cl_int sDestructorIndex;
|
||||
|
||||
void CL_CALLBACK mem_destructor_callback( cl_mem memObject, void * userData )
|
||||
{
|
||||
int * userPtr = (int *)userData;
|
||||
|
||||
// ordering of callbacks is guaranteed, meaning we don't need to do atomic operation here
|
||||
*userPtr = ++sDestructorIndex;
|
||||
}
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS( x ) ( ( x < 0 ) ? -x : x )
|
||||
#endif
|
||||
|
||||
int test_mem_object_destructor_callback_single( clMemWrapper &memObject )
|
||||
{
|
||||
cl_int error;
|
||||
int i;
|
||||
|
||||
// Set up some variables to catch the order in which callbacks are called
|
||||
volatile int callbackOrders[ 3 ] = { 0, 0, 0 };
|
||||
sDestructorIndex = 0;
|
||||
|
||||
// Set up the callbacks
|
||||
error = clSetMemObjectDestructorCallback( memObject, mem_destructor_callback, (void*) &callbackOrders[ 0 ] );
|
||||
test_error( error, "Unable to set destructor callback" );
|
||||
|
||||
error = clSetMemObjectDestructorCallback( memObject, mem_destructor_callback, (void*) &callbackOrders[ 1 ] );
|
||||
test_error( error, "Unable to set destructor callback" );
|
||||
|
||||
error = clSetMemObjectDestructorCallback( memObject, mem_destructor_callback, (void*) &callbackOrders[ 2 ] );
|
||||
test_error( error, "Unable to set destructor callback" );
|
||||
|
||||
// Now release the buffer, which SHOULD call the callbacks
|
||||
error = clReleaseMemObject( memObject );
|
||||
test_error( error, "Unable to release test buffer" );
|
||||
|
||||
// Note: since we manually released the mem wrapper, we need to set it to NULL to prevent a double-release
|
||||
memObject = NULL;
|
||||
|
||||
// At this point, all three callbacks should have already been called
|
||||
int numErrors = 0;
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
// Spin waiting for the release to finish. If you don't call the mem_destructor_callback, you will not
|
||||
// pass the test. bugzilla 6316
|
||||
while( 0 == callbackOrders[i] )
|
||||
{}
|
||||
|
||||
if( ABS( callbackOrders[ i ] ) != 3-i )
|
||||
{
|
||||
log_error( "\tERROR: Callback %d was called in the wrong order! (Was called order %d, should have been order %d)\n",
|
||||
i+1, ABS( callbackOrders[ i ] ), i );
|
||||
numErrors++;
|
||||
}
|
||||
}
|
||||
|
||||
return ( numErrors > 0 ) ? -1 : 0;
|
||||
}
|
||||
|
||||
int test_mem_object_destructor_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
clMemWrapper testBuffer, testImage;
|
||||
cl_int error;
|
||||
|
||||
|
||||
// Create a buffer and an image to test callbacks against
|
||||
testBuffer = clCreateBuffer( context, CL_MEM_READ_WRITE, 1024, NULL, &error );
|
||||
test_error( error, "Unable to create testing buffer" );
|
||||
|
||||
if( test_mem_object_destructor_callback_single( testBuffer ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Destructor callbacks for buffer object FAILED\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( checkForImageSupport( deviceID ) == 0 )
|
||||
{
|
||||
cl_image_format imageFormat = { CL_RGBA, CL_SIGNED_INT8 };
|
||||
testImage = create_image_2d( context, CL_MEM_READ_ONLY, &imageFormat, 16, 16, 0, NULL, &error );
|
||||
test_error( error, "Unable to create testing image" );
|
||||
|
||||
if( test_mem_object_destructor_callback_single( testImage ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Destructor callbacks for image object FAILED\n" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
121
test_conformance/api/test_native_kernel.cpp
Normal file
121
test_conformance/api/test_native_kernel.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
static void CL_CALLBACK test_native_kernel_fn( void *userData )
|
||||
{
|
||||
struct arg_struct {
|
||||
cl_int * source;
|
||||
cl_int * dest;
|
||||
cl_int count;
|
||||
} *args = (arg_struct *)userData;
|
||||
|
||||
for( cl_int i = 0; i < args->count; i++ )
|
||||
args->dest[ i ] = args->source[ i ];
|
||||
}
|
||||
|
||||
int test_native_kernel(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems )
|
||||
{
|
||||
int error;
|
||||
RandomSeed seed( gRandomSeed );
|
||||
// Check if we support native kernels
|
||||
cl_device_exec_capabilities capabilities;
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_EXECUTION_CAPABILITIES, sizeof(capabilities), &capabilities, NULL);
|
||||
if (!(capabilities & CL_EXEC_NATIVE_KERNEL)) {
|
||||
log_info("Device does not support CL_EXEC_NATIVE_KERNEL.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
clMemWrapper streams[ 2 ];
|
||||
#if !(defined (_WIN32) && defined (_MSC_VER))
|
||||
cl_int inBuffer[ n_elems ], outBuffer[ n_elems ];
|
||||
#else
|
||||
cl_int* inBuffer = (cl_int *)_malloca( n_elems * sizeof(cl_int) );
|
||||
cl_int* outBuffer = (cl_int *)_malloca( n_elems * sizeof(cl_int) );
|
||||
#endif
|
||||
clEventWrapper finishEvent;
|
||||
|
||||
struct arg_struct
|
||||
{
|
||||
cl_mem inputStream;
|
||||
cl_mem outputStream;
|
||||
cl_int count;
|
||||
} args;
|
||||
|
||||
|
||||
// Create some input values
|
||||
generate_random_data( kInt, n_elems, seed, inBuffer );
|
||||
|
||||
|
||||
// Create I/O streams
|
||||
streams[ 0 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, n_elems * sizeof(cl_int), inBuffer, &error );
|
||||
test_error( error, "Unable to create I/O stream" );
|
||||
streams[ 1 ] = clCreateBuffer( context, 0, n_elems * sizeof(cl_int), NULL, &error );
|
||||
test_error( error, "Unable to create I/O stream" );
|
||||
|
||||
|
||||
// Set up the arrays to call with
|
||||
args.inputStream = streams[ 0 ];
|
||||
args.outputStream = streams[ 1 ];
|
||||
args.count = n_elems;
|
||||
|
||||
void * memLocs[ 2 ] = { &args.inputStream, &args.outputStream };
|
||||
|
||||
|
||||
// Run the kernel
|
||||
error = clEnqueueNativeKernel( queue, test_native_kernel_fn,
|
||||
&args, sizeof( args ),
|
||||
2, &streams[ 0 ],
|
||||
(const void **)memLocs,
|
||||
0, NULL, &finishEvent );
|
||||
test_error( error, "Unable to queue native kernel" );
|
||||
|
||||
// Finish and wait for the kernel to complete
|
||||
error = clFinish( queue );
|
||||
test_error(error, "clFinish failed");
|
||||
|
||||
error = clWaitForEvents( 1, &finishEvent );
|
||||
test_error(error, "clWaitForEvents failed");
|
||||
|
||||
// Now read the results and verify
|
||||
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, n_elems * sizeof(cl_int), outBuffer, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read results" );
|
||||
|
||||
for( int i = 0; i < n_elems; i++ )
|
||||
{
|
||||
if( inBuffer[ i ] != outBuffer[ i ] )
|
||||
{
|
||||
log_error( "ERROR: Data sample %d for native kernel did not validate (expected %d, got %d)\n",
|
||||
i, (int)inBuffer[ i ], (int)outBuffer[ i ] );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
208
test_conformance/api/test_null_buffer_arg.c
Normal file
208
test_conformance/api/test_null_buffer_arg.c
Normal file
@@ -0,0 +1,208 @@
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenCL/opencl.h>
|
||||
#include <OpenCL/cl_platform.h>
|
||||
#else
|
||||
#include <CL/opencl.h>
|
||||
#include <CL/cl_platform.h>
|
||||
#endif
|
||||
#include "testBase.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
#include "procs.h"
|
||||
|
||||
|
||||
enum { SUCCESS, FAILURE };
|
||||
typedef enum { NON_NULL_PATH, ADDROF_NULL_PATH, NULL_PATH } test_type;
|
||||
|
||||
#define NITEMS 4096
|
||||
|
||||
/* places the comparison result of value of the src ptr against 0 into each element of the output
|
||||
* array, to allow testing that the kernel actually _gets_ the NULL value */
|
||||
const char *kernel_string_long =
|
||||
"kernel void test_kernel(global float *src, global long *dst)\n"
|
||||
"{\n"
|
||||
" uint tid = get_global_id(0);\n"
|
||||
" dst[tid] = (long)(src != 0);\n"
|
||||
"}\n";
|
||||
|
||||
// For gIsEmbedded
|
||||
const char *kernel_string =
|
||||
"kernel void test_kernel(global float *src, global int *dst)\n"
|
||||
"{\n"
|
||||
" uint tid = get_global_id(0);\n"
|
||||
" dst[tid] = (int)(src != 0);\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
/*
|
||||
* The guts of the test:
|
||||
* call setKernelArgs with a regular buffer, &NULL, or NULL depending on
|
||||
* the value of 'test_type'
|
||||
*/
|
||||
static int test_setargs_and_execution(cl_command_queue queue, cl_kernel kernel,
|
||||
cl_mem test_buf, cl_mem result_buf, test_type type)
|
||||
{
|
||||
unsigned int test_success = 0;
|
||||
|
||||
unsigned int i;
|
||||
cl_int status;
|
||||
char *typestr;
|
||||
|
||||
if (type == NON_NULL_PATH) {
|
||||
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);
|
||||
typestr = "non-NULL";
|
||||
} else if (type == ADDROF_NULL_PATH) {
|
||||
test_buf = NULL;
|
||||
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);
|
||||
typestr = "&NULL";
|
||||
} else if (type == NULL_PATH) {
|
||||
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), NULL);
|
||||
typestr = "NULL";
|
||||
}
|
||||
|
||||
log_info("Testing setKernelArgs with %s buffer.\n", typestr);
|
||||
|
||||
if (status != CL_SUCCESS) {
|
||||
log_error("clSetKernelArg failed with status: %d\n", status);
|
||||
return FAILURE; // no point in continuing *this* test
|
||||
}
|
||||
|
||||
size_t global = NITEMS;
|
||||
status = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global,
|
||||
NULL, 0, NULL, NULL);
|
||||
test_error(status, "NDRangeKernel failed.");
|
||||
|
||||
if (gIsEmbedded)
|
||||
{
|
||||
cl_int* host_result = (cl_int*)malloc(NITEMS*sizeof(cl_int));
|
||||
status = clEnqueueReadBuffer(queue, result_buf, CL_TRUE, 0,
|
||||
sizeof(cl_int)*NITEMS, host_result, 0, NULL, NULL);
|
||||
test_error(status, "ReadBuffer failed.");
|
||||
// in the non-null case, we expect NONZERO values:
|
||||
if (type == NON_NULL_PATH) {
|
||||
for (i=0; i<NITEMS; i++) {
|
||||
if (host_result[i] == 0) {
|
||||
log_error("failure: item %d in the result buffer was unexpectedly NULL.\n", i);
|
||||
test_success = FAILURE; break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (type == ADDROF_NULL_PATH || type == NULL_PATH) {
|
||||
for (i=0; i<NITEMS; i++) {
|
||||
if (host_result[i] != 0) {
|
||||
log_error("failure: item %d in the result buffer was unexpectedly non-NULL.\n", i);
|
||||
test_success = FAILURE; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(host_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
cl_long* host_result = (cl_long*)malloc(NITEMS*sizeof(cl_long));
|
||||
status = clEnqueueReadBuffer(queue, result_buf, CL_TRUE, 0,
|
||||
sizeof(cl_long)*NITEMS, host_result, 0, NULL, NULL);
|
||||
test_error(status, "ReadBuffer failed.");
|
||||
// in the non-null case, we expect NONZERO values:
|
||||
if (type == NON_NULL_PATH) {
|
||||
for (i=0; i<NITEMS; i++) {
|
||||
if (host_result[i] == 0) {
|
||||
log_error("failure: item %d in the result buffer was unexpectedly NULL.\n", i);
|
||||
test_success = FAILURE; break;
|
||||
}
|
||||
}
|
||||
} else if (type == ADDROF_NULL_PATH || type == NULL_PATH) {
|
||||
for (i=0; i<NITEMS; i++) {
|
||||
if (host_result[i] != 0) {
|
||||
log_error("failure: item %d in the result buffer was unexpectedly non-NULL.\n", i);
|
||||
test_success = FAILURE; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(host_result);
|
||||
}
|
||||
|
||||
if (test_success == SUCCESS) {
|
||||
log_info("\t%s ok.\n", typestr);
|
||||
}
|
||||
|
||||
return test_success;
|
||||
}
|
||||
|
||||
int test_null_buffer_arg(cl_device_id device, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
{
|
||||
unsigned int test_success = 0;
|
||||
unsigned int i;
|
||||
unsigned int buffer_size;
|
||||
cl_int status;
|
||||
cl_program program;
|
||||
cl_kernel kernel;
|
||||
|
||||
// prep kernel:
|
||||
if (gIsEmbedded)
|
||||
program = clCreateProgramWithSource(context, 1, &kernel_string, NULL, &status);
|
||||
else
|
||||
program = clCreateProgramWithSource(context, 1, &kernel_string_long, NULL, &status);
|
||||
test_error(status, "CreateProgramWithSource failed.");
|
||||
|
||||
status = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
|
||||
test_error(status, "BuildProgram failed.");
|
||||
|
||||
kernel = clCreateKernel(program, "test_kernel", &status);
|
||||
test_error(status, "CreateKernel failed.");
|
||||
|
||||
cl_mem dev_src = clCreateBuffer(context, CL_MEM_READ_ONLY, NITEMS*sizeof(cl_float),
|
||||
NULL, NULL);
|
||||
|
||||
if (gIsEmbedded)
|
||||
buffer_size = NITEMS*sizeof(cl_int);
|
||||
else
|
||||
buffer_size = NITEMS*sizeof(cl_long);
|
||||
|
||||
cl_mem dev_dst = clCreateBuffer(context, CL_MEM_WRITE_ONLY, buffer_size,
|
||||
NULL, NULL);
|
||||
|
||||
// set the destination buffer normally:
|
||||
status = clSetKernelArg(kernel, 1, sizeof(cl_mem), &dev_dst);
|
||||
test_error(status, "SetKernelArg failed.");
|
||||
|
||||
//
|
||||
// we test three cases:
|
||||
//
|
||||
// - typical case, used everyday: non-null buffer
|
||||
// - the case of src as &NULL (the spec-compliance test)
|
||||
// - the case of src as NULL (the backwards-compatibility test, Apple only)
|
||||
//
|
||||
|
||||
test_success = test_setargs_and_execution(queue, kernel, dev_src, dev_dst, NON_NULL_PATH);
|
||||
test_success |= test_setargs_and_execution(queue, kernel, dev_src, dev_dst, ADDROF_NULL_PATH);
|
||||
|
||||
#ifdef __APPLE__
|
||||
test_success |= test_setargs_and_execution(queue, kernel, dev_src, dev_dst, NULL_PATH);
|
||||
#endif
|
||||
|
||||
// clean up:
|
||||
if (dev_src) clReleaseMemObject(dev_src);
|
||||
clReleaseMemObject(dev_dst);
|
||||
clReleaseKernel(kernel);
|
||||
clReleaseProgram(program);
|
||||
|
||||
return test_success;
|
||||
}
|
||||
289
test_conformance/api/test_platform.cpp
Normal file
289
test_conformance/api/test_platform.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define EXTENSION_NAME_BUF_SIZE 4096
|
||||
|
||||
#define PRINT_EXTENSION_INFO 0
|
||||
|
||||
int test_platform_extensions(cl_device_id deviceID, cl_context context,
|
||||
cl_command_queue queue, int num_elements)
|
||||
{
|
||||
const char * extensions[] = {
|
||||
"cl_khr_byte_addressable_store",
|
||||
// "cl_APPLE_SetMemObjectDestructor",
|
||||
"cl_khr_global_int32_base_atomics",
|
||||
"cl_khr_global_int32_extended_atomics",
|
||||
"cl_khr_local_int32_base_atomics",
|
||||
"cl_khr_local_int32_extended_atomics",
|
||||
"cl_khr_int64_base_atomics",
|
||||
"cl_khr_int64_extended_atomics",
|
||||
// need to put in entires for various atomics
|
||||
"cl_khr_3d_image_writes",
|
||||
"cl_khr_fp16",
|
||||
"cl_khr_fp64",
|
||||
NULL
|
||||
};
|
||||
|
||||
bool extensionsSupported[] = {
|
||||
false, //"cl_khr_byte_addressable_store",
|
||||
false, // need to put in entires for various atomics
|
||||
false, // "cl_khr_global_int32_base_atomics",
|
||||
false, // "cl_khr_global_int32_extended_atomics",
|
||||
false, // "cl_khr_local_int32_base_atomics",
|
||||
false, // "cl_khr_local_int32_extended_atomics",
|
||||
false, // "cl_khr_int64_base_atomics",
|
||||
false, // "cl_khr_int64_extended_atomics",
|
||||
false, //"cl_khr_3d_image_writes",
|
||||
false, //"cl_khr_fp16",
|
||||
false, //"cl_khr_fp64",
|
||||
false //NULL
|
||||
};
|
||||
|
||||
int extensionIndex;
|
||||
|
||||
cl_platform_id platformID;
|
||||
cl_int err;
|
||||
|
||||
char platform_extensions[EXTENSION_NAME_BUF_SIZE];
|
||||
char device_extensions[EXTENSION_NAME_BUF_SIZE];
|
||||
|
||||
// Okay, so what we're going to do is just check the device indicated by
|
||||
// deviceID against the platform that includes this device
|
||||
|
||||
|
||||
// pass CL_DEVICE_PLATFORM to clGetDeviceInfo
|
||||
// to get a result of type cl_platform_id
|
||||
|
||||
err = clGetDeviceInfo(deviceID,
|
||||
CL_DEVICE_PLATFORM,
|
||||
sizeof(cl_platform_id),
|
||||
(void *)(&platformID),
|
||||
NULL);
|
||||
|
||||
if(err != CL_SUCCESS)
|
||||
{
|
||||
vlog_error("test_platform_extensions : could not get platformID from device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// now we grab the set of extensions specified by the platform
|
||||
err = clGetPlatformInfo(platformID,
|
||||
CL_PLATFORM_EXTENSIONS,
|
||||
sizeof(platform_extensions),
|
||||
(void *)(&platform_extensions[0]),
|
||||
NULL);
|
||||
if(err != CL_SUCCESS)
|
||||
{
|
||||
vlog_error("test_platform_extensions : could not get extension string from platform\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if PRINT_EXTENSION_INFO
|
||||
log_info("Platform extensions include \"%s\"\n\n", platform_extensions);
|
||||
#endif
|
||||
|
||||
// here we parse the platform extensions, to look for the "important" ones
|
||||
for(extensionIndex=0; extensions[extensionIndex] != NULL; ++extensionIndex)
|
||||
{
|
||||
if(strstr(platform_extensions, extensions[extensionIndex]) != NULL)
|
||||
{
|
||||
// we found it
|
||||
#if PRINT_EXTENSION_INFO
|
||||
log_info("Found \"%s\" in platform extensions\n",
|
||||
extensions[extensionIndex]);
|
||||
#endif
|
||||
extensionsSupported[extensionIndex] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// and then we grab the set of extensions specified by the device
|
||||
// (this can be turned into a "loop over all devices in this platform")
|
||||
err = clGetDeviceInfo(deviceID,
|
||||
CL_DEVICE_EXTENSIONS,
|
||||
sizeof(device_extensions),
|
||||
(void *)(&device_extensions[0]),
|
||||
NULL);
|
||||
if(err != CL_SUCCESS)
|
||||
{
|
||||
vlog_error("test_platform_extensions : could not get extension string from device\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#if PRINT_EXTENSION_INFO
|
||||
log_info("Device extensions include \"%s\"\n\n", device_extensions);
|
||||
#endif
|
||||
|
||||
for(extensionIndex=0; extensions[extensionIndex] != NULL; ++extensionIndex)
|
||||
{
|
||||
if(extensionsSupported[extensionIndex] == false)
|
||||
{
|
||||
continue; // skip this one
|
||||
}
|
||||
|
||||
if(strstr(device_extensions, extensions[extensionIndex]) == NULL)
|
||||
{
|
||||
// device does not support it
|
||||
vlog_error("Platform supports extension \"%s\" but device does not\n",
|
||||
extensions[extensionIndex]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_platform_ids(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) {
|
||||
cl_platform_id platforms[16];
|
||||
cl_uint num_platforms;
|
||||
char *string_returned;
|
||||
|
||||
string_returned = (char*)malloc(8192);
|
||||
|
||||
int total_errors = 0;
|
||||
int err = CL_SUCCESS;
|
||||
|
||||
|
||||
err = clGetPlatformIDs(16, platforms, &num_platforms);
|
||||
test_error(err, "clGetPlatformIDs failed");
|
||||
|
||||
if (num_platforms <= 16) {
|
||||
// Try with NULL
|
||||
err = clGetPlatformIDs(num_platforms, platforms, NULL);
|
||||
test_error(err, "clGetPlatformIDs failed with NULL for return size");
|
||||
}
|
||||
|
||||
if (num_platforms < 1) {
|
||||
log_error("Found 0 platforms.\n");
|
||||
return -1;
|
||||
}
|
||||
log_info("Found %d platforms.\n", num_platforms);
|
||||
|
||||
|
||||
for (int p=0; p<(int)num_platforms; p++) {
|
||||
cl_device_id *devices;
|
||||
cl_uint num_devices;
|
||||
size_t size;
|
||||
|
||||
|
||||
log_info("Platform %d (%p):\n", p, platforms[p]);
|
||||
|
||||
memset(string_returned, 0, 8192);
|
||||
err = clGetPlatformInfo(platforms[p], CL_PLATFORM_PROFILE, 8192, string_returned, &size);
|
||||
test_error(err, "clGetPlatformInfo for CL_PLATFORM_PROFILE failed");
|
||||
log_info("\tCL_PLATFORM_PROFILE: %s\n", string_returned);
|
||||
if (strlen(string_returned)+1 != size) {
|
||||
log_error("Returned string length %ld does not equal reported one %ld.\n", strlen(string_returned)+1, size);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
memset(string_returned, 0, 8192);
|
||||
err = clGetPlatformInfo(platforms[p], CL_PLATFORM_VERSION, 8192, string_returned, &size);
|
||||
test_error(err, "clGetPlatformInfo for CL_PLATFORM_VERSION failed");
|
||||
log_info("\tCL_PLATFORM_VERSION: %s\n", string_returned);
|
||||
if (strlen(string_returned)+1 != size) {
|
||||
log_error("Returned string length %ld does not equal reported one %ld.\n", strlen(string_returned)+1, size);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
memset(string_returned, 0, 8192);
|
||||
err = clGetPlatformInfo(platforms[p], CL_PLATFORM_NAME, 8192, string_returned, &size);
|
||||
test_error(err, "clGetPlatformInfo for CL_PLATFORM_NAME failed");
|
||||
log_info("\tCL_PLATFORM_NAME: %s\n", string_returned);
|
||||
if (strlen(string_returned)+1 != size) {
|
||||
log_error("Returned string length %ld does not equal reported one %ld.\n", strlen(string_returned)+1, size);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
memset(string_returned, 0, 8192);
|
||||
err = clGetPlatformInfo(platforms[p], CL_PLATFORM_VENDOR, 8192, string_returned, &size);
|
||||
test_error(err, "clGetPlatformInfo for CL_PLATFORM_VENDOR failed");
|
||||
log_info("\tCL_PLATFORM_VENDOR: %s\n", string_returned);
|
||||
if (strlen(string_returned)+1 != size) {
|
||||
log_error("Returned string length %ld does not equal reported one %ld.\n", strlen(string_returned)+1, size);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
memset(string_returned, 0, 8192);
|
||||
err = clGetPlatformInfo(platforms[p], CL_PLATFORM_EXTENSIONS, 8192, string_returned, &size);
|
||||
test_error(err, "clGetPlatformInfo for CL_PLATFORM_EXTENSIONS failed");
|
||||
log_info("\tCL_PLATFORM_EXTENSIONS: %s\n", string_returned);
|
||||
if (strlen(string_returned)+1 != size) {
|
||||
log_error("Returned string length %ld does not equal reported one %ld.\n", strlen(string_returned)+1, size);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
err = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
|
||||
test_error(err, "clGetDeviceIDs size failed.\n");
|
||||
devices = (cl_device_id *)malloc(num_devices*sizeof(cl_device_id));
|
||||
memset(devices, 0, sizeof(cl_device_id)*num_devices);
|
||||
err = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
|
||||
test_error(err, "clGetDeviceIDs failed.\n");
|
||||
|
||||
log_info("\tPlatform has %d devices.\n", (int)num_devices);
|
||||
for (int d=0; d<(int)num_devices; d++) {
|
||||
size_t returned_size;
|
||||
cl_platform_id returned_platform;
|
||||
cl_context context;
|
||||
cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platforms[p], 0 };
|
||||
|
||||
err = clGetDeviceInfo(devices[d], CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &returned_platform, &returned_size);
|
||||
test_error(err, "clGetDeviceInfo failed for CL_DEVICE_PLATFORM\n");
|
||||
if (returned_size != sizeof(cl_platform_id)) {
|
||||
log_error("Reported return size (%ld) does not match expected size (%ld).\n", returned_size, sizeof(cl_platform_id));
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
memset(string_returned, 0, 8192);
|
||||
err = clGetDeviceInfo(devices[d], CL_DEVICE_NAME, 8192, string_returned, NULL);
|
||||
test_error(err, "clGetDeviceInfo failed for CL_DEVICE_NAME\n");
|
||||
|
||||
log_info("\t\tPlatform for device %d (%s) is %p.\n", d, string_returned, returned_platform);
|
||||
|
||||
log_info("\t\t\tTesting clCreateContext for the platform/device...\n");
|
||||
// Try creating a context for the platform
|
||||
context = clCreateContext(properties, 1, &devices[d], NULL, NULL, &err);
|
||||
test_error(err, "\t\tclCreateContext failed for device with platform properties\n");
|
||||
|
||||
memset(properties, 0, sizeof(cl_context_properties)*3);
|
||||
|
||||
err = clGetContextInfo(context, CL_CONTEXT_PROPERTIES, sizeof(cl_context_properties)*3, properties, &returned_size);
|
||||
test_error(err, "clGetContextInfo for CL_CONTEXT_PROPERTIES failed");
|
||||
if (returned_size != sizeof(cl_context_properties)*3) {
|
||||
log_error("Invalid size returned from clGetContextInfo for CL_CONTEXT_PROPERTIES. Got %ld, expected %ld.\n",
|
||||
returned_size, sizeof(cl_context_properties)*3);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
if (properties[0] != (cl_context_properties)CL_CONTEXT_PLATFORM || properties[1] != (cl_context_properties)platforms[p]) {
|
||||
log_error("Wrong properties returned. Expected: [%p %p], got [%p %p]\n",
|
||||
(void*)CL_CONTEXT_PLATFORM, platforms[p], (void*)properties[0], (void*)properties[1]);
|
||||
total_errors++;
|
||||
}
|
||||
|
||||
err = clReleaseContext(context);
|
||||
test_error(err, "clReleaseContext failed");
|
||||
}
|
||||
free(devices);
|
||||
}
|
||||
|
||||
free(string_returned);
|
||||
|
||||
return total_errors;
|
||||
}
|
||||
643
test_conformance/api/test_queries.cpp
Normal file
643
test_conformance/api/test_queries.cpp
Normal file
@@ -0,0 +1,643 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#include "../../test_common/harness/imageHelpers.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int test_get_platform_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_platform_id platform;
|
||||
cl_int error;
|
||||
char buffer[ 16384 ];
|
||||
size_t length;
|
||||
|
||||
// Get the platform to use
|
||||
error = clGetPlatformIDs(1, &platform, NULL);
|
||||
test_error( error, "Unable to get platform" );
|
||||
|
||||
// Platform profile should either be FULL_PROFILE or EMBEDDED_PROFILE
|
||||
error = clGetPlatformInfo(platform, CL_PLATFORM_PROFILE, sizeof( buffer ), buffer, &length );
|
||||
test_error( error, "Unable to get platform profile string" );
|
||||
|
||||
log_info("Returned CL_PLATFORM_PROFILE %s.\n", buffer);
|
||||
|
||||
if( strcmp( buffer, "FULL_PROFILE" ) != 0 && strcmp( buffer, "EMBEDDED_PROFILE" ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Returned platform profile string is not a valid string by OpenCL 1.2! (Returned: %s)\n", buffer );
|
||||
return -1;
|
||||
}
|
||||
if( strlen( buffer )+1 != length )
|
||||
{
|
||||
log_error( "ERROR: Returned length of profile string is incorrect (actual length: %d, returned length: %d)\n",
|
||||
(int)strlen( buffer )+1, (int)length );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check just length return
|
||||
error = clGetPlatformInfo(platform, CL_PLATFORM_PROFILE, 0, NULL, &length );
|
||||
test_error( error, "Unable to get platform profile length" );
|
||||
if( strlen( (char *)buffer )+1 != length )
|
||||
{
|
||||
log_error( "ERROR: Returned length of profile string is incorrect (actual length: %d, returned length: %d)\n",
|
||||
(int)strlen( (char *)buffer )+1, (int)length );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Platform version should fit the regex "OpenCL *[0-9]+\.[0-9]+"
|
||||
error = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, sizeof( buffer ), buffer, &length );
|
||||
test_error( error, "Unable to get platform version string" );
|
||||
|
||||
log_info("Returned CL_PLATFORM_VERSION %s.\n", buffer);
|
||||
|
||||
if( memcmp( buffer, "OpenCL ", strlen( "OpenCL " ) ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Initial part of platform version string does not match required format! (returned: %s)\n", (char *)buffer );
|
||||
return -1;
|
||||
}
|
||||
char *p1 = (char *)buffer + strlen( "OpenCL " );
|
||||
while( *p1 == ' ' )
|
||||
p1++;
|
||||
char *p2 = p1;
|
||||
while( isdigit( *p2 ) )
|
||||
p2++;
|
||||
if( *p2 != '.' )
|
||||
{
|
||||
log_error( "ERROR: Numeric part of platform version string does not match required format! (returned: %s)\n", (char *)buffer );
|
||||
return -1;
|
||||
}
|
||||
char *p3 = p2 + 1;
|
||||
while( isdigit( *p3 ) )
|
||||
p3++;
|
||||
if( *p3 != ' ' )
|
||||
{
|
||||
log_error( "ERROR: space expected after minor version number! (returned: %s)\n", (char *)buffer );
|
||||
return -1;
|
||||
}
|
||||
*p2 = ' '; // Put in a space for atoi below.
|
||||
p2++;
|
||||
|
||||
// make sure it is null terminated
|
||||
for( ; p3 != buffer + length; p3++ )
|
||||
if( *p3 == '\0' )
|
||||
break;
|
||||
if( p3 == buffer + length )
|
||||
{
|
||||
log_error( "ERROR: platform version string is not NUL terminated!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
int major = atoi( p1 );
|
||||
int minor = atoi( p2 );
|
||||
int minor_revision = 2;
|
||||
if( major * 10 + minor < 10 + minor_revision )
|
||||
{
|
||||
log_error( "ERROR: OpenCL profile version returned is less than 1.%d!\n", minor_revision );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Sanity checks on the returned values
|
||||
if( length != strlen( (char *)buffer ) + 1)
|
||||
{
|
||||
log_error( "ERROR: Returned length of version string does not match actual length (actual: %d, returned: %d)\n", (int)strlen( (char *)buffer )+1, (int)length );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check just length
|
||||
error = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, NULL, &length );
|
||||
test_error( error, "Unable to get platform version length" );
|
||||
if( length != strlen( (char *)buffer )+1 )
|
||||
{
|
||||
log_error( "ERROR: Returned length of version string does not match actual length (actual: %d, returned: %d)\n", (int)strlen( buffer )+1, (int)length );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_sampler_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
|
||||
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
|
||||
|
||||
cl_sampler_properties properties[] = {
|
||||
CL_SAMPLER_NORMALIZED_COORDS, CL_TRUE,
|
||||
CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_CLAMP,
|
||||
CL_SAMPLER_FILTER_MODE, CL_FILTER_LINEAR,
|
||||
0 };
|
||||
clSamplerWrapper sampler = clCreateSamplerWithProperties(context, properties, &error);
|
||||
test_error( error, "Unable to create sampler to test with" );
|
||||
|
||||
cl_uint refCount;
|
||||
error = clGetSamplerInfo( sampler, CL_SAMPLER_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
|
||||
test_error( error, "Unable to get sampler ref count" );
|
||||
if( size != sizeof( refCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of sampler refcount does not validate! (expected %d, got %d)\n", (int)sizeof( refCount ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_context otherCtx;
|
||||
error = clGetSamplerInfo( sampler, CL_SAMPLER_CONTEXT, sizeof( otherCtx ), &otherCtx, &size );
|
||||
test_error( error, "Unable to get sampler context" );
|
||||
if( otherCtx != context )
|
||||
{
|
||||
log_error( "ERROR: Sampler context does not validate! (expected %p, got %p)\n", context, otherCtx );
|
||||
return -1;
|
||||
}
|
||||
if( size != sizeof( otherCtx ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of sampler context does not validate! (expected %d, got %d)\n", (int)sizeof( otherCtx ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_addressing_mode mode;
|
||||
error = clGetSamplerInfo( sampler, CL_SAMPLER_ADDRESSING_MODE, sizeof( mode ), &mode, &size );
|
||||
test_error( error, "Unable to get sampler addressing mode" );
|
||||
if( mode != CL_ADDRESS_CLAMP )
|
||||
{
|
||||
log_error( "ERROR: Sampler addressing mode does not validate! (expected %d, got %d)\n", (int)CL_ADDRESS_CLAMP, (int)mode );
|
||||
return -1;
|
||||
}
|
||||
if( size != sizeof( mode ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of sampler addressing mode does not validate! (expected %d, got %d)\n", (int)sizeof( mode ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_filter_mode fmode;
|
||||
error = clGetSamplerInfo( sampler, CL_SAMPLER_FILTER_MODE, sizeof( fmode ), &fmode, &size );
|
||||
test_error( error, "Unable to get sampler filter mode" );
|
||||
if( fmode != CL_FILTER_LINEAR )
|
||||
{
|
||||
log_error( "ERROR: Sampler filter mode does not validate! (expected %d, got %d)\n", (int)CL_FILTER_LINEAR, (int)fmode );
|
||||
return -1;
|
||||
}
|
||||
if( size != sizeof( fmode ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of sampler filter mode does not validate! (expected %d, got %d)\n", (int)sizeof( fmode ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_int norm;
|
||||
error = clGetSamplerInfo( sampler, CL_SAMPLER_NORMALIZED_COORDS, sizeof( norm ), &norm, &size );
|
||||
test_error( error, "Unable to get sampler normalized flag" );
|
||||
if( norm != CL_TRUE )
|
||||
{
|
||||
log_error( "ERROR: Sampler normalized flag does not validate! (expected %d, got %d)\n", (int)CL_TRUE, (int)norm );
|
||||
return -1;
|
||||
}
|
||||
if( size != sizeof( norm ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of sampler normalized flag does not validate! (expected %d, got %d)\n", (int)sizeof( norm ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_COMMAND_QUEUE_PARAM( queue, paramName, val, expected, name, type, cast ) \
|
||||
error = clGetCommandQueueInfo( queue, paramName, sizeof( val ), &val, &size ); \
|
||||
test_error( error, "Unable to get command queue " name ); \
|
||||
if( val != expected ) \
|
||||
{ \
|
||||
log_error( "ERROR: Command queue " name " did not validate! (expected " type ", got " type ")\n", (cast)expected, (cast)val ); \
|
||||
return -1; \
|
||||
} \
|
||||
if( size != sizeof( val ) ) \
|
||||
{ \
|
||||
log_error( "ERROR: Returned size of command queue " name " does not validate! (expected %d, got %d)\n", (int)sizeof( val ), (int)size ); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
int test_get_command_queue_info(cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
|
||||
cl_queue_properties device_props;
|
||||
cl_queue_properties queue_props[] = {CL_QUEUE_PROPERTIES,0,0};
|
||||
|
||||
clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, sizeof(device_props), &device_props, NULL);
|
||||
log_info("CL_DEVICE_QUEUE_ON_HOST_PROPERTIES is %d\n", (int)device_props);
|
||||
|
||||
queue_props[1] = device_props;
|
||||
clCommandQueueWrapper queue = clCreateCommandQueueWithProperties( context, deviceID, &queue_props[0], &error );
|
||||
test_error( error, "Unable to create command queue to test with" );
|
||||
|
||||
cl_uint refCount;
|
||||
error = clGetCommandQueueInfo( queue, CL_QUEUE_REFERENCE_COUNT, sizeof( refCount ), &refCount, &size );
|
||||
test_error( error, "Unable to get command queue reference count" );
|
||||
if( size != sizeof( refCount ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of command queue reference count does not validate! (expected %d, got %d)\n", (int)sizeof( refCount ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_context otherCtx;
|
||||
TEST_COMMAND_QUEUE_PARAM( queue, CL_QUEUE_CONTEXT, otherCtx, context, "context", "%p", cl_context )
|
||||
|
||||
cl_device_id otherDevice;
|
||||
error = clGetCommandQueueInfo( queue, CL_QUEUE_DEVICE, sizeof(otherDevice), &otherDevice, &size);
|
||||
test_error(error, "clGetCommandQueue failed.");
|
||||
|
||||
if (size != sizeof(cl_device_id)) {
|
||||
log_error( " ERROR: Returned size of command queue CL_QUEUE_DEVICE does not validate! (expected %d, got %d)\n", (int)sizeof( otherDevice ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Since the device IDs are opaque types we check the CL_DEVICE_VENDOR_ID which is unique for identical hardware. */
|
||||
cl_uint otherDevice_vid, deviceID_vid;
|
||||
error = clGetDeviceInfo(otherDevice, CL_DEVICE_VENDOR_ID, sizeof(otherDevice_vid), &otherDevice_vid, NULL );
|
||||
test_error( error, "Unable to get device CL_DEVICE_VENDOR_ID" );
|
||||
error = clGetDeviceInfo(deviceID, CL_DEVICE_VENDOR_ID, sizeof(deviceID_vid), &deviceID_vid, NULL );
|
||||
test_error( error, "Unable to get device CL_DEVICE_VENDOR_ID" );
|
||||
|
||||
if( otherDevice_vid != deviceID_vid )
|
||||
{
|
||||
log_error( "ERROR: Incorrect device returned for queue! (Expected vendor ID 0x%x, got 0x%x)\n", deviceID_vid, otherDevice_vid );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_command_queue_properties props;
|
||||
TEST_COMMAND_QUEUE_PARAM( queue, CL_QUEUE_PROPERTIES, props, (unsigned int)( device_props ), "properties", "%d", unsigned int )
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_context_info(cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
cl_context_properties props;
|
||||
|
||||
error = clGetContextInfo( context, CL_CONTEXT_PROPERTIES, sizeof( props ), &props, &size );
|
||||
test_error( error, "Unable to get context props" );
|
||||
|
||||
if (size == 0) {
|
||||
// Valid size
|
||||
return 0;
|
||||
} else if (size == sizeof(cl_context_properties)) {
|
||||
// Data must be NULL
|
||||
if (props != 0) {
|
||||
log_error("ERROR: Returned properties is no NULL.\n");
|
||||
return -1;
|
||||
}
|
||||
// Valid data and size
|
||||
return 0;
|
||||
}
|
||||
// Size was not 0 or 1
|
||||
log_error( "ERROR: Returned size of context props is not valid! (expected 0 or %d, got %d)\n",
|
||||
(int)sizeof(cl_context_properties), (int)size );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define TEST_MEM_OBJECT_PARAM( mem, paramName, val, expected, name, type, cast ) \
|
||||
error = clGetMemObjectInfo( mem, paramName, sizeof( val ), &val, &size ); \
|
||||
test_error( error, "Unable to get mem object " name ); \
|
||||
if( val != expected ) \
|
||||
{ \
|
||||
log_error( "ERROR: Mem object " name " did not validate! (expected " type ", got " type ")\n", (cast)(expected), (cast)val ); \
|
||||
return -1; \
|
||||
} \
|
||||
if( size != sizeof( val ) ) \
|
||||
{ \
|
||||
log_error( "ERROR: Returned size of mem object " name " does not validate! (expected %d, got %d)\n", (int)sizeof( val ), (int)size ); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data )
|
||||
{
|
||||
free( data );
|
||||
}
|
||||
|
||||
// All possible combinations of valid cl_mem_flags.
|
||||
static cl_mem_flags all_flags[16] = {
|
||||
0,
|
||||
CL_MEM_READ_WRITE,
|
||||
CL_MEM_READ_ONLY,
|
||||
CL_MEM_WRITE_ONLY,
|
||||
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
|
||||
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
|
||||
};
|
||||
|
||||
#define TEST_DEVICE_PARAM( device, paramName, val, name, type, cast ) \
|
||||
error = clGetDeviceInfo( device, paramName, sizeof( val ), &val, &size ); \
|
||||
test_error( error, "Unable to get device " name ); \
|
||||
if( size != sizeof( val ) ) \
|
||||
{ \
|
||||
log_error( "ERROR: Returned size of device " name " does not validate! (expected %d, got %d)\n", (int)sizeof( val ), (int)size ); \
|
||||
return -1; \
|
||||
} \
|
||||
log_info( "\tReported device " name " : " type "\n", (cast)val );
|
||||
|
||||
#define TEST_DEVICE_PARAM_MEM( device, paramName, val, name, type, div ) \
|
||||
error = clGetDeviceInfo( device, paramName, sizeof( val ), &val, &size ); \
|
||||
test_error( error, "Unable to get device " name ); \
|
||||
if( size != sizeof( val ) ) \
|
||||
{ \
|
||||
log_error( "ERROR: Returned size of device " name " does not validate! (expected %d, got %d)\n", (int)sizeof( val ), (int)size ); \
|
||||
return -1; \
|
||||
} \
|
||||
log_info( "\tReported device " name " : " type "\n", (int)( val / div ) );
|
||||
|
||||
int test_get_device_info(cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
size_t size;
|
||||
|
||||
cl_uint vendorID;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_VENDOR_ID, vendorID, "vendor ID", "0x%08x", int )
|
||||
|
||||
char extensions[ 10240 ];
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_EXTENSIONS, sizeof( extensions ), &extensions, &size );
|
||||
test_error( error, "Unable to get device extensions" );
|
||||
if( size != strlen( extensions ) + 1 )
|
||||
{
|
||||
log_error( "ERROR: Returned size of device extensions does not validate! (expected %d, got %d)\n", (int)( strlen( extensions ) + 1 ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
log_info( "\tReported device extensions: %s \n", extensions );
|
||||
|
||||
cl_uint preferred;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, preferred, "preferred vector char width", "%d", int )
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, preferred, "preferred vector short width", "%d", int )
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, preferred, "preferred vector int width", "%d", int )
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, preferred, "preferred vector long width", "%d", int )
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, preferred, "preferred vector float width", "%d", int )
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, preferred, "preferred vector double width", "%d", int )
|
||||
|
||||
// Note that even if cl_khr_fp64, the preferred width for double can be non-zero. For example, vendors
|
||||
// extensions can support double but may not support cl_khr_fp64, which implies math library support.
|
||||
|
||||
cl_uint baseAddrAlign;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, baseAddrAlign, "base address alignment", "%d bytes", int )
|
||||
|
||||
cl_uint maxDataAlign;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, maxDataAlign, "min data type alignment", "%d bytes", int )
|
||||
|
||||
cl_device_mem_cache_type cacheType;
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, sizeof( cacheType ), &cacheType, &size );
|
||||
test_error( error, "Unable to get device global mem cache type" );
|
||||
if( size != sizeof( cacheType ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of device global mem cache type does not validate! (expected %d, got %d)\n", (int)sizeof( cacheType ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
const char *cacheTypeName = ( cacheType == CL_NONE ) ? "CL_NONE" : ( cacheType == CL_READ_ONLY_CACHE ) ? "CL_READ_ONLY_CACHE" : ( cacheType == CL_READ_WRITE_CACHE ) ? "CL_READ_WRITE_CACHE" : "<unknown>";
|
||||
log_info( "\tReported device global mem cache type: %s \n", cacheTypeName );
|
||||
|
||||
cl_uint cachelineSize;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cachelineSize, "global mem cacheline size", "%d bytes", int )
|
||||
|
||||
cl_ulong cacheSize;
|
||||
TEST_DEVICE_PARAM_MEM( deviceID, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cacheSize, "global mem cache size", "%d KB", 1024 )
|
||||
|
||||
cl_ulong memSize;
|
||||
TEST_DEVICE_PARAM_MEM( deviceID, CL_DEVICE_GLOBAL_MEM_SIZE, memSize, "global mem size", "%d MB", ( 1024 * 1024 ) )
|
||||
|
||||
cl_device_local_mem_type localMemType;
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_LOCAL_MEM_TYPE, sizeof( localMemType ), &localMemType, &size );
|
||||
test_error( error, "Unable to get device local mem type" );
|
||||
if( size != sizeof( cacheType ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of device local mem type does not validate! (expected %d, got %d)\n", (int)sizeof( localMemType ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
const char *localMemTypeName = ( localMemType == CL_LOCAL ) ? "CL_LOCAL" : ( cacheType == CL_GLOBAL ) ? "CL_GLOBAL" : "<unknown>";
|
||||
log_info( "\tReported device local mem type: %s \n", localMemTypeName );
|
||||
|
||||
|
||||
cl_bool errSupport;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_ERROR_CORRECTION_SUPPORT, errSupport, "error correction support", "%d", int )
|
||||
|
||||
size_t timerResolution;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_PROFILING_TIMER_RESOLUTION, timerResolution, "profiling timer resolution", "%ld nanoseconds", long )
|
||||
|
||||
cl_bool endian;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_ENDIAN_LITTLE, endian, "little endian flag", "%d", int )
|
||||
|
||||
cl_bool avail;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_AVAILABLE, avail, "available flag", "%d", int )
|
||||
|
||||
cl_bool compilerAvail;
|
||||
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_COMPILER_AVAILABLE, compilerAvail, "compiler available flag", "%d", int )
|
||||
|
||||
char profile[ 1024 ];
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_PROFILE, sizeof( profile ), &profile, &size );
|
||||
test_error( error, "Unable to get device profile" );
|
||||
if( size != strlen( profile ) + 1 )
|
||||
{
|
||||
log_error( "ERROR: Returned size of device profile does not validate! (expected %d, got %d)\n", (int)( strlen( profile ) + 1 ), (int)size );
|
||||
return -1;
|
||||
}
|
||||
if( strcmp( profile, "FULL_PROFILE" ) != 0 && strcmp( profile, "EMBEDDED_PROFILE" ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Returned profile of device not FULL or EMBEDDED as required by OpenCL 1.2! (Returned %s)\n", profile );
|
||||
return -1;
|
||||
}
|
||||
log_info( "\tReported device profile: %s \n", profile );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const char *sample_compile_size[2] = {
|
||||
"__kernel void sample_test(__global int *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
" dst[tid] = src[tid];\n"
|
||||
"\n"
|
||||
"}\n",
|
||||
"__kernel __attribute__((reqd_work_group_size(%d,%d,%d))) void sample_test(__global int *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
" dst[tid] = src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
int test_kernel_required_group_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
size_t realSize;
|
||||
size_t kernel_max_workgroup_size;
|
||||
size_t global[] = {64,14,10};
|
||||
size_t local[] = {0,0,0};
|
||||
|
||||
cl_uint max_dimensions;
|
||||
|
||||
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(max_dimensions), &max_dimensions, NULL);
|
||||
test_error(error, "clGetDeviceInfo failed for CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS");
|
||||
log_info("Device reported CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS = %d.\n", (int)max_dimensions);
|
||||
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
|
||||
error = create_single_kernel_helper( context, &program, &kernel, 1, &sample_compile_size[ 0 ], "sample_test" );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
error = clGetKernelWorkGroupInfo(kernel, deviceID, CL_KERNEL_WORK_GROUP_SIZE, sizeof(kernel_max_workgroup_size), &kernel_max_workgroup_size, NULL);
|
||||
test_error( error, "clGetKernelWorkGroupInfo failed for CL_KERNEL_WORK_GROUP_SIZE");
|
||||
log_info("The CL_KERNEL_WORK_GROUP_SIZE for the kernel is %d.\n", (int)kernel_max_workgroup_size);
|
||||
|
||||
size_t size[ 3 ];
|
||||
error = clGetKernelWorkGroupInfo( kernel, deviceID, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, sizeof( size ), size, &realSize );
|
||||
test_error( error, "Unable to get work group info" );
|
||||
|
||||
if( size[ 0 ] != 0 || size[ 1 ] != 0 || size[ 2 ] != 0 )
|
||||
{
|
||||
log_error( "ERROR: Nonzero compile work group size returned for nonspecified size! (returned %d,%d,%d)\n", (int)size[0], (int)size[1], (int)size[2] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( realSize != sizeof( size ) )
|
||||
{
|
||||
log_error( "ERROR: Returned size of compile work group size not valid! (Expected %d, got %d)\n", (int)sizeof( size ), (int)realSize );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Determine some local dimensions to use for the test.
|
||||
if (max_dimensions == 1) {
|
||||
error = get_max_common_work_group_size(context, kernel, global[0], &local[0]);
|
||||
test_error( error, "get_max_common_work_group_size failed");
|
||||
log_info("For global dimension %d, kernel will require local dimension %d.\n", (int)global[0], (int)local[0]);
|
||||
} else if (max_dimensions == 2) {
|
||||
error = get_max_common_2D_work_group_size(context, kernel, global, local);
|
||||
test_error( error, "get_max_common_2D_work_group_size failed");
|
||||
log_info("For global dimension %d x %d, kernel will require local dimension %d x %d.\n", (int)global[0], (int)global[1], (int)local[0], (int)local[1]);
|
||||
} else {
|
||||
error = get_max_common_3D_work_group_size(context, kernel, global, local);
|
||||
test_error( error, "get_max_common_3D_work_group_size failed");
|
||||
log_info("For global dimension %d x %d x %d, kernel will require local dimension %d x %d x %d.\n",
|
||||
(int)global[0], (int)global[1], (int)global[2], (int)local[0], (int)local[1], (int)local[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
clMemWrapper in, out;
|
||||
//char source[1024];
|
||||
char *source = (char*)malloc(1024);
|
||||
source[0] = '\0';
|
||||
|
||||
sprintf(source, sample_compile_size[1], local[0], local[1], local[2]);
|
||||
|
||||
error = create_single_kernel_helper( context, &program, &kernel, 1, (const char**)&source, "sample_test" );
|
||||
if( error != 0 )
|
||||
return error;
|
||||
|
||||
size_t size[ 3 ];
|
||||
error = clGetKernelWorkGroupInfo( kernel, deviceID, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, sizeof( size ), size, &realSize );
|
||||
test_error( error, "Unable to get work group info" );
|
||||
|
||||
if( size[ 0 ] != local[0] || size[ 1 ] != local[1] || size[ 2 ] != local[2] )
|
||||
{
|
||||
log_error( "ERROR: Incorrect compile work group size returned for specified size! (returned %d,%d,%d, expected %d,%d,%d)\n",
|
||||
(int)size[0], (int)size[1], (int)size[2], (int)local[0], (int)local[1], (int)local[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Verify that the kernel will only execute with that size.
|
||||
in = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(cl_int)*global[0], NULL, &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
out = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_int)*global[0], NULL, &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(in), &in);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel, 1, sizeof(out), &out);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global, local, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error(error, "clFinish failed");
|
||||
|
||||
log_info("kernel_required_group_size may report spurious ERRORS in the conformance log.\n");
|
||||
|
||||
local[0]++;
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global, local, 0, NULL, NULL);
|
||||
if (error != CL_INVALID_WORK_GROUP_SIZE) {
|
||||
log_error("Incorrect error returned for executing a kernel with the wrong required local work group size. (used %d,%d,%d, required %d,%d,%d)\n",
|
||||
(int)local[0], (int)local[1], (int)local[2], (int)local[0]-1, (int)local[1], (int)local[2] );
|
||||
print_error(error, "Expected: CL_INVALID_WORK_GROUP_SIZE.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error(error, "clFinish failed");
|
||||
|
||||
if (max_dimensions == 1) {
|
||||
free(source);
|
||||
return 0;
|
||||
}
|
||||
|
||||
local[0]--; local[1]++;
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global, local, 0, NULL, NULL);
|
||||
if (error != CL_INVALID_WORK_GROUP_SIZE) {
|
||||
log_error("Incorrect error returned for executing a kernel with the wrong required local work group size. (used %d,%d,%d, required %d,%d,%d)\n",
|
||||
(int)local[0], (int)local[1], (int)local[2], (int)local[0]-1, (int)local[1], (int)local[2]);
|
||||
print_error(error, "Expected: CL_INVALID_WORK_GROUP_SIZE.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error(error, "clFinish failed");
|
||||
|
||||
if (max_dimensions == 2) {
|
||||
return 0;
|
||||
free(source);
|
||||
}
|
||||
|
||||
local[1]--; local[2]++;
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 3, NULL, global, local, 0, NULL, NULL);
|
||||
if (error != CL_INVALID_WORK_GROUP_SIZE) {
|
||||
log_error("Incorrect error returned for executing a kernel with the wrong required local work group size. (used %d,%d,%d, required %d,%d,%d)\n",
|
||||
(int)local[0], (int)local[1], (int)local[2], (int)local[0]-1, (int)local[1], (int)local[2]);
|
||||
print_error(error, "Expected: CL_INVALID_WORK_GROUP_SIZE.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clFinish(queue);
|
||||
test_error(error, "clFinish failed");
|
||||
free(source);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
234
test_conformance/api/test_retain.cpp
Normal file
234
test_conformance/api/test_retain.cpp
Normal file
@@ -0,0 +1,234 @@
|
||||
//
|
||||
// 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 "testBase.h"
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif // !_WIN32
|
||||
|
||||
// Note: According to spec, the various functions to get instance counts should return an error when passed in an object
|
||||
// that has already been released. However, the spec is out of date. If it gets re-updated to allow such action, re-enable
|
||||
// this define.
|
||||
//#define VERIFY_AFTER_RELEASE 1
|
||||
|
||||
#define GET_QUEUE_INSTANCE_COUNT(p) numInstances = ( (err = clGetCommandQueueInfo(p, CL_QUEUE_REFERENCE_COUNT, sizeof( numInstances ), &numInstances, NULL)) == CL_SUCCESS ? numInstances : 0 )
|
||||
#define GET_MEM_INSTANCE_COUNT(p) numInstances = ( (err = clGetMemObjectInfo(p, CL_MEM_REFERENCE_COUNT, sizeof( numInstances ), &numInstances, NULL)) == CL_SUCCESS ? numInstances : 0 )
|
||||
|
||||
#define VERIFY_INSTANCE_COUNT(c,rightValue) if( c != rightValue ) { \
|
||||
log_error( "ERROR: Instance count for test object is not valid! (should be %d, really is %d)\n", rightValue, c ); \
|
||||
return -1; }
|
||||
|
||||
int test_retain_queue_single(cl_device_id deviceID, cl_context context, cl_command_queue queueNotUsed, int num_elements)
|
||||
{
|
||||
cl_command_queue queue;
|
||||
cl_uint numInstances;
|
||||
int err;
|
||||
|
||||
|
||||
/* Create a test queue */
|
||||
queue = clCreateCommandQueueWithProperties( context, deviceID, 0, &err );
|
||||
test_error( err, "Unable to create command queue to test with" );
|
||||
|
||||
/* Test the instance count */
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
test_error( err, "Unable to get queue instance count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 1 );
|
||||
|
||||
/* Now release the program */
|
||||
clReleaseCommandQueue( queue );
|
||||
#ifdef VERIFY_AFTER_RELEASE
|
||||
/* We're not allowed to get the instance count after the object has been completely released. But that's
|
||||
exactly how we can tell the release worked--by making sure getting the instance count fails! */
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
if( err != CL_INVALID_COMMAND_QUEUE )
|
||||
{
|
||||
print_error( err, "Command queue was not properly released" );
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_retain_queue_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queueNotUsed, int num_elements)
|
||||
{
|
||||
cl_command_queue queue;
|
||||
unsigned int numInstances, i;
|
||||
int err;
|
||||
|
||||
|
||||
/* Create a test program */
|
||||
queue = clCreateCommandQueueWithProperties( context, deviceID, 0, &err );
|
||||
test_error( err, "Unable to create command queue to test with" );
|
||||
|
||||
/* Increment 9 times, which should bring the count to 10 */
|
||||
for( i = 0; i < 9; i++ )
|
||||
{
|
||||
clRetainCommandQueue( queue );
|
||||
}
|
||||
|
||||
/* Test the instance count */
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
test_error( err, "Unable to get queue instance count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 10 );
|
||||
|
||||
/* Now release 5 times, which should take us to 5 */
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
clReleaseCommandQueue( queue );
|
||||
}
|
||||
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
test_error( err, "Unable to get queue instance count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 5 );
|
||||
|
||||
/* Retain again three times, which should take us to 8 */
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
clRetainCommandQueue( queue );
|
||||
}
|
||||
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
test_error( err, "Unable to get queue instance count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 8 );
|
||||
|
||||
/* Release 7 times, which should take it to 1 */
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
clReleaseCommandQueue( queue );
|
||||
}
|
||||
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
test_error( err, "Unable to get queue instance count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 1 );
|
||||
|
||||
/* And one last one */
|
||||
clReleaseCommandQueue( queue );
|
||||
|
||||
#ifdef VERIFY_AFTER_RELEASE
|
||||
/* We're not allowed to get the instance count after the object has been completely released. But that's
|
||||
exactly how we can tell the release worked--by making sure getting the instance count fails! */
|
||||
GET_QUEUE_INSTANCE_COUNT( queue );
|
||||
if( err != CL_INVALID_COMMAND_QUEUE )
|
||||
{
|
||||
print_error( err, "Command queue was not properly released" );
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_retain_mem_object_single(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_mem object;
|
||||
cl_uint numInstances;
|
||||
int err;
|
||||
|
||||
|
||||
/* Create a test object */
|
||||
object = clCreateBuffer( context, CL_MEM_READ_ONLY, 32, NULL, &err );
|
||||
test_error( err, "Unable to create buffer to test with" );
|
||||
|
||||
/* Test the instance count */
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
test_error( err, "Unable to get mem object count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 1 );
|
||||
|
||||
/* Now release the program */
|
||||
clReleaseMemObject( object );
|
||||
#ifdef VERIFY_AFTER_RELEASE
|
||||
/* We're not allowed to get the instance count after the object has been completely released. But that's
|
||||
exactly how we can tell the release worked--by making sure getting the instance count fails! */
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
if( err != CL_INVALID_MEM_OBJECT )
|
||||
{
|
||||
print_error( err, "Mem object was not properly released" );
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_retain_mem_object_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_mem object;
|
||||
unsigned int numInstances, i;
|
||||
int err;
|
||||
|
||||
|
||||
/* Create a test object */
|
||||
object = clCreateBuffer( context, CL_MEM_READ_ONLY, 32, NULL, &err );
|
||||
test_error( err, "Unable to create buffer to test with" );
|
||||
|
||||
/* Increment 9 times, which should bring the count to 10 */
|
||||
for( i = 0; i < 9; i++ )
|
||||
{
|
||||
clRetainMemObject( object );
|
||||
}
|
||||
|
||||
/* Test the instance count */
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
test_error( err, "Unable to get mem object count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 10 );
|
||||
|
||||
/* Now release 5 times, which should take us to 5 */
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
clReleaseMemObject( object );
|
||||
}
|
||||
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
test_error( err, "Unable to get mem object count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 5 );
|
||||
|
||||
/* Retain again three times, which should take us to 8 */
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
clRetainMemObject( object );
|
||||
}
|
||||
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
test_error( err, "Unable to get mem object count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 8 );
|
||||
|
||||
/* Release 7 times, which should take it to 1 */
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
clReleaseMemObject( object );
|
||||
}
|
||||
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
test_error( err, "Unable to get mem object count" );
|
||||
VERIFY_INSTANCE_COUNT( numInstances, 1 );
|
||||
|
||||
/* And one last one */
|
||||
clReleaseMemObject( object );
|
||||
|
||||
#ifdef VERIFY_AFTER_RELEASE
|
||||
/* We're not allowed to get the instance count after the object has been completely released. But that's
|
||||
exactly how we can tell the release worked--by making sure getting the instance count fails! */
|
||||
GET_MEM_INSTANCE_COUNT( object );
|
||||
if( err != CL_INVALID_MEM_OBJECT )
|
||||
{
|
||||
print_error( err, "Mem object was not properly released" );
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
109
test_conformance/api/test_retain_program.c
Normal file
109
test_conformance/api/test_retain_program.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 "testBase.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../../test_common/harness/compat.h"
|
||||
|
||||
int test_release_kernel_order(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_program program;
|
||||
cl_kernel kernel;
|
||||
int error;
|
||||
const char *testProgram[] = { "__kernel void sample_test(__global int *data){}" };
|
||||
|
||||
/* Create a test program */
|
||||
program = clCreateProgramWithSource( context, 1, testProgram, NULL, &error);
|
||||
test_error( error, "Unable to create program to test with" );
|
||||
|
||||
/* Compile the program */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build sample program to test with" );
|
||||
|
||||
/* And create a kernel from it */
|
||||
kernel = clCreateKernel( program, "sample_test", &error );
|
||||
test_error( error, "Unable to create kernel" );
|
||||
|
||||
/* Now try freeing the program first, then the kernel. If refcounts are right, this should work just fine */
|
||||
clReleaseProgram( program );
|
||||
clReleaseKernel( kernel );
|
||||
|
||||
/* If we got here fine, we succeeded. If not, well, we won't be able to return an error :) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *sample_delay_kernel[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
" for( int i = 0; i < 1000000; i++ ); \n"
|
||||
" dst[tid] = (int)src[tid];\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
int test_release_during_execute( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
cl_kernel kernel;
|
||||
cl_mem streams[2];
|
||||
size_t threads[1] = { 10 }, localThreadSize;
|
||||
|
||||
|
||||
/* We now need an event to test. So we'll execute a kernel to get one */
|
||||
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_delay_kernel, "sample_test" ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
|
||||
test_error( error, "Creating test array failed" );
|
||||
|
||||
/* Set the arguments */
|
||||
error = clSetKernelArg(kernel, 0, sizeof( streams[0] ), &streams[ 0 ]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
error = clSetKernelArg(kernel, 1, sizeof( streams[1] ), &streams[ 1 ]);
|
||||
test_error( error, "Unable to set indexed kernel arguments" );
|
||||
|
||||
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreadSize );
|
||||
test_error( error, "Unable to calc local thread size" );
|
||||
|
||||
|
||||
/* Execute the kernel */
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, &localThreadSize, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
/* The kernel should still be executing, but we should still be able to release it. It's not terribly
|
||||
useful, but we should be able to do it, if the internal refcounting is indeed correct. */
|
||||
|
||||
clReleaseMemObject( streams[ 1 ] );
|
||||
clReleaseMemObject( streams[ 0 ] );
|
||||
clReleaseKernel( kernel );
|
||||
clReleaseProgram( program );
|
||||
|
||||
/* Now make sure we're really finished before we go on. */
|
||||
error = clFinish(queue);
|
||||
test_error( error, "Unable to finish context.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user