mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-23 15:39:03 +00:00
Initial open source release of OpenCL 2.0 CTS.
This commit is contained in:
24
test_conformance/compiler/CMakeLists.txt
Normal file
24
test_conformance/compiler/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
set(MODULE_NAME COMPILER)
|
||||
|
||||
set(${MODULE_NAME}_SOURCES
|
||||
main.c
|
||||
test_build_helpers.c
|
||||
test_compile.c
|
||||
test_async_build.c
|
||||
test_build_options.cpp
|
||||
test_preprocessor.c
|
||||
test_image_macro.c
|
||||
test_compiler_defines_for_extensions.cpp
|
||||
test_pragma_unroll.c
|
||||
../../test_common/harness/errorHelpers.c
|
||||
../../test_common/harness/threadTesting.c
|
||||
../../test_common/harness/testHarness.c
|
||||
../../test_common/harness/kernelHelpers.c
|
||||
../../test_common/harness/typeWrappers.cpp
|
||||
../../test_common/harness/mt19937.c
|
||||
../../test_common/harness/conversions.c
|
||||
../../test_common/harness/msvc9.c
|
||||
../../test_common/harness/os_helpers.cpp
|
||||
)
|
||||
|
||||
include(../CMakeCommon.txt)
|
||||
27
test_conformance/compiler/Jamfile
Normal file
27
test_conformance/compiler/Jamfile
Normal file
@@ -0,0 +1,27 @@
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc:<cflags>-xc++
|
||||
<toolset>msvc:<cflags>"/TP"
|
||||
;
|
||||
|
||||
exe test_compiler
|
||||
: main.c
|
||||
test_async_build.c
|
||||
test_build_helpers.c
|
||||
test_build_options.cpp
|
||||
test_compile.c
|
||||
test_preprocessor.c
|
||||
test_pragma_unroll.c
|
||||
;
|
||||
|
||||
install dist
|
||||
: test_compiler
|
||||
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/compiler
|
||||
<variant>release:<location>$(DIST)/release/tests/test_conformance/compiler
|
||||
;
|
||||
|
||||
install data
|
||||
: includeTestDirectory/testIncludeFile.h
|
||||
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/compiler/includeTestDirectory
|
||||
<variant>release:<location>$(DIST)/release/tests/test_conformance/compiler/includeTestDirectory
|
||||
;
|
||||
51
test_conformance/compiler/Makefile
Normal file
51
test_conformance/compiler/Makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = main.c \
|
||||
test_build_helpers.c \
|
||||
test_compile.c \
|
||||
test_compiler_defines_for_extensions.cpp \
|
||||
test_async_build.c \
|
||||
test_build_options.cpp \
|
||||
test_preprocessor.c \
|
||||
test_image_macro.c \
|
||||
test_pragma_unroll.c \
|
||||
../../test_common/harness/errorHelpers.c \
|
||||
../../test_common/harness/threadTesting.c \
|
||||
../../test_common/harness/testHarness.c \
|
||||
../../test_common/harness/kernelHelpers.c \
|
||||
../../test_common/harness/typeWrappers.cpp \
|
||||
../../test_common/harness/mt19937.c \
|
||||
../../test_common/harness/os_helpers.cpp \
|
||||
../../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_compiler
|
||||
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.
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#define HEADER_FOUND 12
|
||||
168
test_conformance/compiler/main.c
Normal file
168
test_conformance/compiler/main.c
Normal file
@@ -0,0 +1,168 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "../../test_common/harness/compat.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "procs.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
basefn basefn_list[] = {
|
||||
test_load_program_source,
|
||||
test_load_multistring_source,
|
||||
test_load_two_kernel_source,
|
||||
test_load_null_terminated_source,
|
||||
test_load_null_terminated_multi_line_source,
|
||||
test_load_null_terminated_partial_multi_line_source,
|
||||
test_load_discreet_length_source,
|
||||
test_get_program_source,
|
||||
test_get_program_build_info,
|
||||
test_get_program_info,
|
||||
|
||||
test_large_compile,
|
||||
test_async_build_pieces,
|
||||
|
||||
test_options_optimizations,
|
||||
test_options_build_macro,
|
||||
test_options_build_macro_existence,
|
||||
test_options_include_directory,
|
||||
test_options_denorm_cache,
|
||||
|
||||
test_preprocessor_define_udef,
|
||||
test_preprocessor_include,
|
||||
test_preprocessor_line_error,
|
||||
test_preprocessor_pragma,
|
||||
|
||||
test_compiler_defines_for_extensions,
|
||||
test_image_macro,
|
||||
|
||||
test_simple_compile_only,
|
||||
test_simple_static_compile_only,
|
||||
test_simple_extern_compile_only,
|
||||
test_simple_compile_with_callback,
|
||||
test_simple_embedded_header_compile,
|
||||
test_simple_link_only,
|
||||
test_two_file_regular_variable_access,
|
||||
test_two_file_regular_struct_access,
|
||||
test_two_file_regular_function_access,
|
||||
test_simple_link_with_callback,
|
||||
test_simple_embedded_header_link,
|
||||
test_execute_after_simple_compile_and_link,
|
||||
test_execute_after_simple_compile_and_link_no_device_info,
|
||||
test_execute_after_simple_compile_and_link_with_defines,
|
||||
test_execute_after_simple_compile_and_link_with_callbacks,
|
||||
test_execute_after_simple_library_with_link,
|
||||
test_execute_after_two_file_link,
|
||||
test_execute_after_embedded_header_link,
|
||||
test_execute_after_included_header_link,
|
||||
test_execute_after_serialize_reload_object,
|
||||
test_execute_after_serialize_reload_library,
|
||||
test_simple_library_only,
|
||||
test_simple_library_with_callback,
|
||||
test_simple_library_with_link,
|
||||
test_two_file_link,
|
||||
test_multi_file_libraries,
|
||||
test_multiple_files,
|
||||
test_multiple_libraries,
|
||||
test_multiple_files_multiple_libraries,
|
||||
test_multiple_embedded_headers,
|
||||
|
||||
test_program_binary_type,
|
||||
test_compile_and_link_status_options_log,
|
||||
|
||||
test_pragma_unroll
|
||||
};
|
||||
|
||||
|
||||
const char *basefn_names[] = {
|
||||
"load_program_source",
|
||||
"load_multistring_source",
|
||||
"load_two_kernel_source",
|
||||
"load_null_terminated_source",
|
||||
"load_null_terminated_multi_line_source",
|
||||
"load_null_terminated_partial_multi_line_source",
|
||||
"load_discreet_length_source",
|
||||
"get_program_source",
|
||||
"get_program_build_info",
|
||||
"get_program_info",
|
||||
|
||||
"large_compile",
|
||||
"async_build",
|
||||
|
||||
"options_build_optimizations",
|
||||
"options_build_macro",
|
||||
"options_build_macro_existence",
|
||||
"options_include_directory",
|
||||
"options_denorm_cache",
|
||||
|
||||
"preprocessor_define_udef",
|
||||
"preprocessor_include",
|
||||
"preprocessor_line_error",
|
||||
"preprocessor_pragma",
|
||||
|
||||
"compiler_defines_for_extensions",
|
||||
"image_macro",
|
||||
|
||||
"simple_compile_only",
|
||||
"simple_static_compile_only",
|
||||
"simple_extern_compile_only",
|
||||
"simple_compile_with_callback",
|
||||
"simple_embedded_header_compile",
|
||||
"simple_link_only",
|
||||
"two_file_regular_variable_access",
|
||||
"two_file_regular_struct_access",
|
||||
"two_file_regular_function_access",
|
||||
"simple_link_with_callback",
|
||||
"simple_embedded_header_link",
|
||||
"execute_after_simple_compile_and_link",
|
||||
"execute_after_simple_compile_and_link_no_device_info",
|
||||
"execute_after_simple_compile_and_link_with_defines",
|
||||
"execute_after_simple_compile_and_link_with_callbacks",
|
||||
"execute_after_simple_library_with_link",
|
||||
"execute_after_two_file_link",
|
||||
"execute_after_embedded_header_link",
|
||||
"execute_after_included_header_link",
|
||||
"execute_after_serialize_reload_object",
|
||||
"execute_after_serialize_reload_library",
|
||||
"simple_library_only",
|
||||
"simple_library_with_callback",
|
||||
"simple_library_with_link",
|
||||
"two_file_link",
|
||||
"multi_file_libraries",
|
||||
"multiple_files",
|
||||
"multiple_libraries",
|
||||
"multiple_files_multiple_libraries",
|
||||
"multiple_embedded_headers",
|
||||
"program_binary_type",
|
||||
"compile_and_link_status_options_log",
|
||||
|
||||
"pragma_unroll",
|
||||
};
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
88
test_conformance/compiler/procs.h
Normal file
88
test_conformance/compiler/procs.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// 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/conversions.h"
|
||||
#include "../../test_common/harness/mt19937.h"
|
||||
|
||||
extern int test_load_program_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_multistring_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_two_kernel_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_null_terminated_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_null_terminated_multi_line_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_null_terminated_partial_multi_line_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_load_discreet_length_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_program_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_program_build_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_get_program_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_large_compile(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_async_build_pieces(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_options_optimizations(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_options_build_macro(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_options_build_macro_existence(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_options_include_directory(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_options_denorm_cache(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_preprocessor_define_udef(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_preprocessor_include(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_preprocessor_line_error(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_preprocessor_pragma(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_compiler_defines_for_extensions(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems );
|
||||
extern int test_image_macro(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_simple_compile_only(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_static_compile_only(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_extern_compile_only(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_compile_with_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_embedded_header_compile(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_simple_link_only(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_two_file_regular_variable_access(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_two_file_regular_struct_access(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_two_file_regular_function_access(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_simple_link_with_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_embedded_header_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_execute_after_simple_compile_and_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_simple_compile_and_link_no_device_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_simple_compile_and_link_with_defines(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_simple_compile_and_link_with_callbacks(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_simple_library_with_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_two_file_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_embedded_header_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_included_header_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_serialize_reload_object(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_execute_after_serialize_reload_library(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_simple_library_only(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_library_with_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_simple_library_with_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_two_file_link(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_multi_file_libraries(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_multiple_libraries(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_multiple_files(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_multiple_files_multiple_libraries(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_multiple_embedded_headers(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_program_binary_type(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_compile_and_link_status_options_log(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_pragma_unroll(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
#define HEADER_FOUND 42
|
||||
31
test_conformance/compiler/testBase.h
Normal file
31
test_conformance/compiler/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 <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "procs.h"
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
|
||||
|
||||
97
test_conformance/compiler/test_async_build.c
Normal file
97
test_conformance/compiler/test_async_build.c
Normal file
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
|
||||
const char *sample_async_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" };
|
||||
|
||||
volatile int buildNotificationSent;
|
||||
|
||||
void CL_CALLBACK test_notify_build_complete( cl_program program, void *userData )
|
||||
{
|
||||
if( userData == NULL || strcmp( (char *)userData, "userData" ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: User data passed in to build notify function was not correct!\n" );
|
||||
buildNotificationSent = -1;
|
||||
}
|
||||
else
|
||||
buildNotificationSent = 1;
|
||||
log_info( "\n <-- program successfully built\n" );
|
||||
}
|
||||
|
||||
int test_async_build_pieces(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
cl_build_status status;
|
||||
|
||||
|
||||
buildNotificationSent = 0;
|
||||
|
||||
/* First, test by doing the slow method of the individual calls */
|
||||
program = clCreateProgramWithSource( context, 1, sample_async_kernel, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS)
|
||||
{
|
||||
print_error( error, "Unable to create test program" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compile the program */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, test_notify_build_complete, (void *)"userData" );
|
||||
test_error( error, "Unable to build program source" );
|
||||
|
||||
/* Wait for build to complete (just keep polling, since we're just a test */
|
||||
if( ( error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL ) ) != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Unable to get program build status" );
|
||||
return -1;
|
||||
}
|
||||
while( (int)status == CL_BUILD_IN_PROGRESS )
|
||||
{
|
||||
log_info( "\n -- still waiting for build... (status is %d)", status );
|
||||
sleep( 1 );
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL );
|
||||
test_error( error, "Unable to get program build status" );
|
||||
}
|
||||
|
||||
if( status != CL_BUILD_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: build failed! (status: %d)\n", (int)status );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( buildNotificationSent == 0 )
|
||||
{
|
||||
log_error( "ERROR: Async build completed, but build notification was not sent!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
578
test_conformance/compiler/test_build_helpers.c
Normal file
578
test_conformance/compiler/test_build_helpers.c
Normal file
@@ -0,0 +1,578 @@
|
||||
//
|
||||
// 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"
|
||||
|
||||
|
||||
const char *sample_kernel_code_single_line[] = {
|
||||
"__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_line_lengths[1];
|
||||
|
||||
const char *sample_kernel_code_multi_line[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)",
|
||||
"{",
|
||||
" int tid = get_global_id(0);",
|
||||
"",
|
||||
" dst[tid] = (int)src[tid];",
|
||||
"",
|
||||
"}" };
|
||||
|
||||
size_t sample_multi_line_lengths[ 7 ];
|
||||
|
||||
const char *sample_kernel_code_two_line[] = {
|
||||
"__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_line_lengths[1];
|
||||
|
||||
const char *sample_kernel_code_bad_multi_line[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)",
|
||||
"{",
|
||||
" int tid = get_global_id(0);thisisanerror",
|
||||
"",
|
||||
" dst[tid] = (int)src[tid];",
|
||||
"",
|
||||
"}" };
|
||||
|
||||
size_t sample_bad_multi_line_lengths[ 7 ];
|
||||
|
||||
|
||||
int test_load_program_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
size_t length;
|
||||
char *buffer;
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
sample_single_line_lengths[ 0 ] = strlen( sample_kernel_code_single_line[ 0 ] );
|
||||
|
||||
/* New OpenCL API only has one entry point, so go ahead and just try it */
|
||||
program = clCreateProgramWithSource( context, 1, sample_kernel_code_single_line, sample_single_line_lengths, &error);
|
||||
test_error( error, "Unable to create reference program" );
|
||||
|
||||
/* Now get the source and compare against our original */
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_SOURCE, NULL, NULL, &length );
|
||||
test_error( error, "Unable to get length of first program source" );
|
||||
|
||||
// Note: according to spec section 5.4.5, the length returned should include the null terminator
|
||||
if( length != sample_single_line_lengths[0] + 1 )
|
||||
{
|
||||
log_error( "ERROR: Length of program (%ld) does not match reference length (%ld)!\n", length, sample_single_line_lengths[0] + 1 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer = (char *)malloc( length );
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_SOURCE, length, buffer, NULL );
|
||||
test_error( error, "Unable to get buffer of first program source" );
|
||||
|
||||
if( strcmp( (char *)buffer, sample_kernel_code_single_line[ 0 ] ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Program sources do not match!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
free( buffer );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_multistring_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
sample_multi_line_lengths[ i ] = strlen( sample_kernel_code_multi_line[ i ] );
|
||||
}
|
||||
|
||||
/* Create another program using the macro function */
|
||||
program = clCreateProgramWithSource( context, 7, sample_kernel_code_multi_line, sample_multi_line_lengths, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create reference program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try compiling */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build multi-line program source" );
|
||||
|
||||
/* Should probably check binary here to verify the same results... */
|
||||
|
||||
/* All done! */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_two_kernel_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
sample_two_line_lengths[ i ] = strlen( sample_kernel_code_two_line[ i ] );
|
||||
}
|
||||
|
||||
/* Now create a program using the macro function */
|
||||
program = clCreateProgramWithSource( context, 2, sample_kernel_code_two_line, sample_two_line_lengths, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create two-kernel program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try compiling */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build two-kernel program source" );
|
||||
|
||||
/* Should probably check binary here to verify the same results... */
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_null_terminated_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
|
||||
|
||||
/* Now create a program using the macro function */
|
||||
program = clCreateProgramWithSource( context, 1, sample_kernel_code_single_line, NULL, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create null-terminated program!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try compiling */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build null-terminated program source" );
|
||||
|
||||
/* Should probably check binary here to verify the same results... */
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_null_terminated_multi_line_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
|
||||
|
||||
/* Now create a program using the macro function */
|
||||
program = clCreateProgramWithSource( context, 7, sample_kernel_code_multi_line, NULL, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create null-terminated program!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try compiling */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build null-terminated program source" );
|
||||
|
||||
/* Should probably check binary here to verify the same results... */
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int test_load_discreet_length_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
sample_bad_multi_line_lengths[ i ] = strlen( sample_kernel_code_bad_multi_line[ i ] );
|
||||
}
|
||||
|
||||
/* Now force the length of the third line to skip the actual error */
|
||||
sample_bad_multi_line_lengths[2] -= strlen("thisisanerror");
|
||||
|
||||
/* Now create a program using the macro function */
|
||||
program = clCreateProgramWithSource( context, 7, sample_kernel_code_bad_multi_line, sample_bad_multi_line_lengths, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create null-terminated program!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try compiling */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build null-terminated program source" );
|
||||
|
||||
/* Should probably check binary here to verify the same results... */
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_load_null_terminated_partial_multi_line_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
int i;
|
||||
|
||||
/* Preprocess: calc the length of each source file line */
|
||||
for( i = 0; i < 7; i++ )
|
||||
{
|
||||
if( i & 0x01 )
|
||||
sample_multi_line_lengths[ i ] = 0; /* Should force for null-termination on this line only */
|
||||
else
|
||||
sample_multi_line_lengths[ i ] = strlen( sample_kernel_code_multi_line[ i ] );
|
||||
}
|
||||
|
||||
/* Now create a program using the macro function */
|
||||
program = clCreateProgramWithSource( context, 7, sample_kernel_code_multi_line, sample_multi_line_lengths, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create null-terminated program!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try compiling */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build null-terminated program source" );
|
||||
|
||||
/* Should probably check binary here to verify the same results... */
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_program_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_program program;
|
||||
cl_device_id device1;
|
||||
cl_context context1;
|
||||
size_t paramSize;
|
||||
cl_uint numInstances;
|
||||
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, sample_kernel_code_single_line, NULL, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create reference program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test that getting the device works. */
|
||||
device1 = (cl_device_id)0xbaadfeed;
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_DEVICES, sizeof( device1 ), &device1, NULL );
|
||||
test_error( error, "Unable to get device of program" );
|
||||
|
||||
/* Since the device IDs are opaque types we check the CL_DEVICE_VENDOR_ID which is unique for identical hardware. */
|
||||
cl_uint device1_vid, deviceID_vid;
|
||||
error = clGetDeviceInfo(device1, CL_DEVICE_VENDOR_ID, sizeof(device1_vid), &device1_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( device1_vid != deviceID_vid )
|
||||
{
|
||||
log_error( "ERROR: Incorrect device returned for program! (Expected vendor ID 0x%x, got 0x%x)\n", deviceID_vid, device1_vid );
|
||||
return -1;
|
||||
}
|
||||
|
||||
cl_uint devCount;
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_NUM_DEVICES, sizeof( devCount ), &devCount, NULL );
|
||||
test_error( error, "Unable to get device count of program" );
|
||||
|
||||
if( devCount != 1 )
|
||||
{
|
||||
log_error( "ERROR: Invalid device count returned for program! (Expected 1, got %d)\n", (int)devCount );
|
||||
return -1;
|
||||
}
|
||||
|
||||
context1 = (cl_context)0xbaadfeed;
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_CONTEXT, sizeof( context1 ), &context1, NULL );
|
||||
test_error( error, "Unable to get device of program" );
|
||||
|
||||
if( context1 != context )
|
||||
{
|
||||
log_error( "ERROR: Invalid context returned for program! (Expected %p, got %p)\n", context, context1 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_REFERENCE_COUNT, sizeof( numInstances ), &numInstances, NULL );
|
||||
test_error( error, "Unable to get instance count" );
|
||||
|
||||
/* While we're at it, test the sizes of programInfo too */
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_DEVICES, NULL, NULL, ¶mSize );
|
||||
test_error( error, "Unable to get device param size" );
|
||||
if( paramSize != sizeof( cl_device_id ) )
|
||||
{
|
||||
log_error( "ERROR: Size returned for device is wrong!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_CONTEXT, NULL, NULL, ¶mSize );
|
||||
test_error( error, "Unable to get context param size" );
|
||||
if( paramSize != sizeof( cl_context ) )
|
||||
{
|
||||
log_error( "ERROR: Size returned for context is wrong!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_REFERENCE_COUNT, NULL, NULL, ¶mSize );
|
||||
test_error( error, "Unable to get instance param size" );
|
||||
if( paramSize != sizeof( cl_uint ) )
|
||||
{
|
||||
log_error( "ERROR: Size returned for num instances is wrong!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_NUM_DEVICES, NULL, NULL, ¶mSize );
|
||||
test_error( error, "Unable to get device count param size" );
|
||||
if( paramSize != sizeof( cl_uint ) )
|
||||
{
|
||||
log_error( "ERROR: Size returned for device count is wrong!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_program_source(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_program program;
|
||||
int error;
|
||||
char buffer[10240];
|
||||
size_t length;
|
||||
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, sample_kernel_code_single_line, NULL, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create test program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try getting the length */
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_SOURCE, NULL, NULL, &length );
|
||||
test_error( error, "Unable to get program source length" );
|
||||
if( length != strlen( sample_kernel_code_single_line[0] ) + 1 )
|
||||
{
|
||||
log_error( "ERROR: Length returned for program source is incorrect!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try normal source */
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_SOURCE, sizeof( buffer ), buffer, NULL );
|
||||
test_error( error, "Unable to get program source" );
|
||||
if( strlen( buffer ) != strlen( sample_kernel_code_single_line[0] ) )
|
||||
{
|
||||
log_error( "ERROR: Length of program source is incorrect!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try both at once */
|
||||
error = clGetProgramInfo( program, CL_PROGRAM_SOURCE, sizeof( buffer ), buffer, &length );
|
||||
test_error( error, "Unable to get program source" );
|
||||
if( strlen( buffer ) != strlen( sample_kernel_code_single_line[0] ) )
|
||||
{
|
||||
log_error( "ERROR: Length of program source is incorrect!\n" );
|
||||
return -1;
|
||||
}
|
||||
if( length != strlen( sample_kernel_code_single_line[0] ) + 1 )
|
||||
{
|
||||
log_error( "ERROR: Returned length of program source is incorrect!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done! */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_get_program_build_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_program program;
|
||||
int error;
|
||||
char *buffer;
|
||||
size_t length, newLength;
|
||||
cl_build_status status;
|
||||
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, sample_kernel_code_single_line, NULL, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create test program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make sure getting the length works */
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, 0, NULL, &length );
|
||||
test_error( error, "Unable to get program build status length" );
|
||||
if( length != sizeof( status ) )
|
||||
{
|
||||
log_error( "ERROR: Returned length of program build status is invalid! (Expected %d, got %d)\n", (int)sizeof( status ), (int)length );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now actually build it and verify the status */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Unable to build program source" );
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL );
|
||||
test_error( error, "Unable to get program build status" );
|
||||
if( status != CL_BUILD_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: Getting built program build status did not return CL_BUILD_SUCCESS! (%d)\n", (int)status );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/***** Build log *****/
|
||||
|
||||
/* Try getting the length */
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &length );
|
||||
test_error( error, "Unable to get program build log length" );
|
||||
|
||||
log_info("Build log is %ld long.\n", length);
|
||||
|
||||
buffer = (char*)malloc(length);
|
||||
|
||||
/* Try normal source */
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_LOG, length, buffer, NULL );
|
||||
test_error( error, "Unable to get program build log" );
|
||||
|
||||
if( buffer[length-1] != '\0' )
|
||||
{
|
||||
log_error( "clGetProgramBuildInfo overwrote allocated space for build log! '%c'\n", buffer[length-1] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try both at once */
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_LOG, length, buffer, &newLength );
|
||||
test_error( error, "Unable to get program build log" );
|
||||
|
||||
free(buffer);
|
||||
|
||||
/***** Build options *****/
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_OPTIONS, 0, NULL, &length );
|
||||
test_error( error, "Unable to get program build options length" );
|
||||
|
||||
buffer = (char*)malloc(length);
|
||||
|
||||
/* Try normal source */
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_OPTIONS, length, buffer, NULL );
|
||||
test_error( error, "Unable to get program build options" );
|
||||
|
||||
/* Try both at once */
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_OPTIONS, length, buffer, &newLength );
|
||||
test_error( error, "Unable to get program build options" );
|
||||
|
||||
free(buffer);
|
||||
|
||||
/* Try with a valid option */
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, sample_kernel_code_single_line, NULL, &error );
|
||||
if( program == NULL )
|
||||
{
|
||||
log_error( "ERROR: Unable to create test program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clBuildProgram( program, 1, &deviceID, "-cl-opt-disable", NULL, NULL );
|
||||
if( error != CL_SUCCESS )
|
||||
{
|
||||
print_error( error, "Building with valid options failed!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_OPTIONS, NULL, NULL, &length );
|
||||
test_error( error, "Unable to get program build options" );
|
||||
|
||||
buffer = (char*)malloc(length);
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_OPTIONS, length, buffer, NULL );
|
||||
test_error( error, "Unable to get program build options" );
|
||||
if( strcmp( (char *)buffer, "-cl-opt-disable" ) != 0 )
|
||||
{
|
||||
log_error( "ERROR: Getting program build options for program with -cl-opt-disable build options did not return expected value (got %s)\n", buffer );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
free( buffer );
|
||||
|
||||
error = clReleaseProgram( program );
|
||||
test_error( error, "Unable to release program object" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
409
test_conformance/compiler/test_build_options.cpp
Normal file
409
test_conformance/compiler/test_build_options.cpp
Normal file
@@ -0,0 +1,409 @@
|
||||
//
|
||||
// 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/os_helpers.h"
|
||||
|
||||
const char *preprocessor_test_kernel[] = {
|
||||
"__kernel void sample_test(__global int *dst)\n"
|
||||
"{\n"
|
||||
" dst[0] = TEST_MACRO;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *preprocessor_existence_test_kernel[] = {
|
||||
"__kernel void sample_test(__global int *dst)\n"
|
||||
"{\n"
|
||||
"#ifdef TEST_MACRO\n"
|
||||
" dst[0] = 42;\n"
|
||||
"#else\n"
|
||||
" dst[0] = 24;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *include_test_kernel[] = {
|
||||
"#include \"./testIncludeFile.h\"\n"
|
||||
"__kernel void sample_test(__global int *dst)\n"
|
||||
"{\n"
|
||||
" dst[0] = HEADER_FOUND;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
const char *options_test_kernel[] = {
|
||||
"__kernel void sample_test(__global float *src, __global int *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" dst[tid] = src[tid];\n"
|
||||
"}\n" };
|
||||
|
||||
const char *optimization_options[] = {
|
||||
"-cl-single-precision-constant",
|
||||
"-cl-denorms-are-zero",
|
||||
"-cl-opt-disable",
|
||||
"-cl-mad-enable",
|
||||
"-cl-no-signed-zeros",
|
||||
"-cl-unsafe-math-optimizations",
|
||||
"-cl-finite-math-only",
|
||||
"-cl-fast-relaxed-math",
|
||||
"-w",
|
||||
"-Werror",
|
||||
#if defined( __APPLE__ )
|
||||
"-cl-opt-enable",
|
||||
"-cl-auto-vectorize-enable"
|
||||
#endif
|
||||
};
|
||||
|
||||
cl_int get_result_from_program( cl_context context, cl_command_queue queue, cl_program program, cl_int *outValue )
|
||||
{
|
||||
cl_int error;
|
||||
clKernelWrapper kernel = clCreateKernel( program, "sample_test", &error );
|
||||
test_error( error, "Unable to create kernel from program" );
|
||||
|
||||
clMemWrapper outStream;
|
||||
outStream = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int), NULL, &error );
|
||||
test_error( error, "Unable to create test buffer" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( outStream ), &outStream );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
|
||||
size_t threads[1] = { 1 };
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, outStream, true, 0, sizeof( cl_int ), outValue, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read output array!" );
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int test_options_optimizations(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
cl_build_status status;
|
||||
|
||||
for(size_t i = 0; i < sizeof(optimization_options) / (sizeof(char*)); i++) {
|
||||
|
||||
clProgramWrapper program = clCreateProgramWithSource( context, 1, options_test_kernel, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: Unable to create reference program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build with the macro defined */
|
||||
log_info("Testing optimization option '%s'\n", optimization_options[i]);
|
||||
error = clBuildProgram( program, 1, &deviceID, optimization_options[i], NULL, NULL );
|
||||
test_error( error, "Test program did not properly build" );
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL );
|
||||
test_error( error, "Unable to get program build status" );
|
||||
|
||||
if( (int)status != CL_BUILD_SUCCESS )
|
||||
{
|
||||
log_info("Building with optimization option '%s' failed to compile!\n", optimization_options[i]);
|
||||
print_error( error, "Failed to build with optimization defined")
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_options_build_macro(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
cl_build_status status;
|
||||
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, preprocessor_test_kernel, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: Unable to create reference program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build with the macro defined */
|
||||
error = clBuildProgram( program, 1, &deviceID, "-DTEST_MACRO=1 ", NULL, NULL );
|
||||
test_error( error, "Test program did not properly build" );
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL );
|
||||
test_error( error, "Unable to get program build status" );
|
||||
|
||||
if( (int)status != CL_BUILD_SUCCESS )
|
||||
{
|
||||
print_error( error, "Failed to build with macro defined" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// Go ahead and run the program to verify results
|
||||
cl_int firstResult, secondResult;
|
||||
|
||||
error = get_result_from_program( context, queue, program, &firstResult );
|
||||
test_error( error, "Unable to get result from first program" );
|
||||
|
||||
if( firstResult != 1 )
|
||||
{
|
||||
log_error( "ERROR: Result from first program did not validate! (Expected 1, got %d)\n", firstResult );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Rebuild with a different value for the define macro, to make sure caching behaves properly
|
||||
error = clBuildProgram( program, 1, &deviceID, "-DTEST_MACRO=5 ", NULL, NULL );
|
||||
test_error( error, "Test program did not properly rebuild" );
|
||||
|
||||
error = get_result_from_program( context, queue, program, &secondResult );
|
||||
test_error( error, "Unable to get result from second program" );
|
||||
|
||||
if( secondResult != 5 )
|
||||
{
|
||||
if( secondResult == firstResult )
|
||||
log_error( "ERROR: Program result did not change with device macro change (program was not recompiled)!\n" );
|
||||
else
|
||||
log_error( "ERROR: Result from second program did not validate! (Expected 5, got %d)\n", secondResult );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_options_build_macro_existence(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
clProgramWrapper program;
|
||||
|
||||
|
||||
// In this case, the program should still run without the macro, but it should give a different result
|
||||
program = clCreateProgramWithSource( context, 1, preprocessor_existence_test_kernel, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: Unable to create reference program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build without the macro defined */
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Test program did not properly build" );
|
||||
|
||||
// Go ahead and run the program to verify results
|
||||
cl_int firstResult, secondResult;
|
||||
|
||||
error = get_result_from_program( context, queue, program, &firstResult );
|
||||
test_error( error, "Unable to get result from first program" );
|
||||
|
||||
if( firstResult != 24 )
|
||||
{
|
||||
log_error( "ERROR: Result from first program did not validate! (Expected 24, got %d)\n", firstResult );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now compile again with the macro defined and verify a change in results
|
||||
error = clBuildProgram( program, 1, &deviceID, "-DTEST_MACRO", NULL, NULL );
|
||||
test_error( error, "Test program did not properly build" );
|
||||
|
||||
error = get_result_from_program( context, queue, program, &secondResult );
|
||||
test_error( error, "Unable to get result from second program" );
|
||||
|
||||
if( secondResult != 42 )
|
||||
{
|
||||
if( secondResult == firstResult )
|
||||
log_error( "ERROR: Program result did not change with device macro addition (program was not recompiled)!\n" );
|
||||
else
|
||||
log_error( "ERROR: Result from second program did not validate! (Expected 42, got %d)\n", secondResult );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_options_include_directory(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
|
||||
std::string sep = dir_sep();
|
||||
std::string path = exe_dir(); // Directory where test executable is located.
|
||||
std::string include_dir;
|
||||
|
||||
clProgramWrapper program;
|
||||
cl_build_status status;
|
||||
|
||||
/* Try compiling the program first without the directory included Should fail. */
|
||||
program = clCreateProgramWithSource( context, 1, include_test_kernel, NULL, &error );
|
||||
if( program == NULL || error != CL_SUCCESS )
|
||||
{
|
||||
log_error( "ERROR: Unable to create reference program!\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Build with the include directory defined */
|
||||
include_dir = "-I " + path + sep + "includeTestDirectory";
|
||||
|
||||
// log_info("%s\n", include_dir);
|
||||
error = clBuildProgram( program, 1, &deviceID, include_dir.c_str(), NULL, NULL );
|
||||
test_error( error, "Test program did not properly build" );
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL );
|
||||
test_error( error, "Unable to get program build status" );
|
||||
|
||||
if( (int)status != CL_BUILD_SUCCESS )
|
||||
{
|
||||
print_error( error, "Failed to build with include directory" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Go ahead and run the program to verify results
|
||||
cl_int firstResult, secondResult;
|
||||
|
||||
error = get_result_from_program( context, queue, program, &firstResult );
|
||||
test_error( error, "Unable to get result from first program" );
|
||||
|
||||
if( firstResult != 12 )
|
||||
{
|
||||
log_error( "ERROR: Result from first program did not validate! (Expected 12, got %d)\n", firstResult );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Rebuild with a different include directory
|
||||
include_dir = "-I " + path + sep + "secondIncludeTestDirectory";
|
||||
error = clBuildProgram( program, 1, &deviceID, include_dir.c_str(), NULL, NULL );
|
||||
test_error( error, "Test program did not properly rebuild" );
|
||||
|
||||
error = get_result_from_program( context, queue, program, &secondResult );
|
||||
test_error( error, "Unable to get result from second program" );
|
||||
|
||||
if( secondResult != 42 )
|
||||
{
|
||||
if( secondResult == firstResult )
|
||||
log_error( "ERROR: Program result did not change with include path change (program was not recompiled)!\n" );
|
||||
else
|
||||
log_error( "ERROR: Result from second program did not validate! (Expected 42, got %d)\n", secondResult );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *denorm_test_kernel[] = {
|
||||
"__kernel void sample_test( float src1, float src2, __global float *dst)\n"
|
||||
"{\n"
|
||||
" dst[ 0 ] = src1 + src2;\n"
|
||||
"\n"
|
||||
"}\n" };
|
||||
|
||||
cl_int get_float_result_from_program( cl_context context, cl_command_queue queue, cl_program program, cl_float inA, cl_float inB, cl_float *outValue )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
clKernelWrapper kernel = clCreateKernel( program, "sample_test", &error );
|
||||
test_error( error, "Unable to create kernel from program" );
|
||||
|
||||
clMemWrapper outStream = clCreateBuffer( context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float), NULL, &error );
|
||||
test_error( error, "Unable to create test buffer" );
|
||||
|
||||
error = clSetKernelArg( kernel, 0, sizeof( cl_float ), &inA );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
|
||||
error = clSetKernelArg( kernel, 1, sizeof( cl_float ), &inB );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
|
||||
error = clSetKernelArg( kernel, 2, sizeof( outStream ), &outStream );
|
||||
test_error( error, "Unable to set kernel argument" );
|
||||
|
||||
size_t threads[1] = { 1 };
|
||||
|
||||
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL );
|
||||
test_error( error, "Unable to execute test kernel" );
|
||||
|
||||
error = clEnqueueReadBuffer( queue, outStream, true, 0, sizeof( cl_float ), outValue, 0, NULL, NULL );
|
||||
test_error( error, "Unable to read output array!" );
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int test_options_denorm_cache(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
int error;
|
||||
|
||||
clProgramWrapper program;
|
||||
cl_build_status status;
|
||||
|
||||
|
||||
// If denorms aren't even supported, testing this flag is pointless
|
||||
cl_device_fp_config floatCaps = 0;
|
||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_SINGLE_FP_CONFIG, sizeof(floatCaps), &floatCaps, NULL);
|
||||
test_error( error, "Unable to get device FP config" );
|
||||
if( ( floatCaps & CL_FP_DENORM ) == 0 )
|
||||
{
|
||||
log_info( "Device does not support denormalized single-precision floats; skipping test.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
program = clCreateProgramWithSource( context, 1, denorm_test_kernel, NULL, &error );
|
||||
test_error( error, "Unable to create test program" );
|
||||
|
||||
// Build first WITH the denorm flush flag
|
||||
error = clBuildProgram( program, 1, &deviceID, "-cl-denorms-are-zero", NULL, NULL );
|
||||
test_error( error, "Test program did not properly build" );
|
||||
|
||||
error = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof( status ), &status, NULL );
|
||||
test_error( error, "Unable to get program build status" );
|
||||
|
||||
if( (int)status != CL_BUILD_SUCCESS )
|
||||
{
|
||||
print_error( error, "Failed to build with include directory" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note: the following in floating point is a subnormal number, thus adding two of them together
|
||||
// should give us a subnormalized result. If denormals are flushed to zero, however, it'll give us zero instead
|
||||
uint32_t intSubnormal = 0x00000001;
|
||||
cl_float *input = (cl_float *)&intSubnormal;
|
||||
cl_float firstResult, secondResult;
|
||||
|
||||
error = get_float_result_from_program( context, queue, program, *input, *input, &firstResult );
|
||||
test_error( error, "Unable to get result from first program" );
|
||||
|
||||
// Note: since -cl-denorms-are-zero is a HINT, not a requirement, the result we got could
|
||||
// either be subnormal (hint ignored) or zero (hint respected). Since either is technically
|
||||
// valid, there isn't anything we can to do validate results for now
|
||||
|
||||
// Rebuild without flushing flag set
|
||||
error = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
test_error( error, "Test program did not properly rebuild" );
|
||||
|
||||
error = get_float_result_from_program( context, queue, program, *input, *input, &secondResult );
|
||||
test_error( error, "Unable to get result from second program" );
|
||||
|
||||
// Now, there are three possiblities here:
|
||||
// 1. The denorms-are-zero hint is not respected, in which case the first and second result will be identical
|
||||
// 2. The hint is respected, and the program was properly rebuilt, in which case the first result will be zero and the second non-zero
|
||||
// 3. The hint is respected, but the program was not properly rebuilt, in which case both results will be zero
|
||||
// 3 is the only error condition we need to look for
|
||||
uint32_t *fPtr = (uint32_t *)&firstResult;
|
||||
uint32_t *sPtr = (uint32_t *)&secondResult;
|
||||
|
||||
if( ( *fPtr == 0 ) && ( *sPtr == 0 ) )
|
||||
{
|
||||
log_error( "ERROR: Program result didn't change when -cl-denorms-are-zero flag was removed.\n"
|
||||
"First result (should be zero): 0x%08x, Second result (should be non-zero): 0x%08x\n",
|
||||
*fPtr, *sPtr );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
3250
test_conformance/compiler/test_compile.c
Normal file
3250
test_conformance/compiler/test_compile.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,423 @@
|
||||
//
|
||||
// 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 <limits.h>
|
||||
#include <ctype.h>
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
const char *known_extensions[] = {
|
||||
"cl_khr_fp64",
|
||||
"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",
|
||||
"cl_khr_3d_image_writes",
|
||||
"cl_khr_byte_addressable_store",
|
||||
"cl_khr_fp16",
|
||||
"cl_khr_gl_sharing",
|
||||
"cl_khr_gl_event",
|
||||
"cl_khr_d3d10_sharing",
|
||||
"cl_khr_d3d11_sharing",
|
||||
"cl_khr_icd",
|
||||
"cl_khr_dx9_media_sharing",
|
||||
"cl_khr_depth_images",
|
||||
"cl_khr_gl_depth_images",
|
||||
"cl_khr_gl_msaa_sharing",
|
||||
"cl_khr_image2d_from_buffer",
|
||||
"cl_khr_initialize_memory",
|
||||
"cl_khr_terminate_context",
|
||||
"cl_khr_spir",
|
||||
"cl_khr_srgb_image_writes",
|
||||
"cl_khr_subgroups",
|
||||
"cl_khr_mipmap_image",
|
||||
"cl_khr_mipmap_image_writes",
|
||||
"cl_khr_egl_image",
|
||||
"cl_khr_egl_event",
|
||||
"cl_khr_il_program",
|
||||
};
|
||||
|
||||
size_t num_known_extensions = sizeof(known_extensions)/sizeof(char*);
|
||||
size_t first_API_extension = 10;
|
||||
|
||||
const char *known_embedded_extensions[] = {
|
||||
"cles_khr_int64",
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kUnsupported_extension = -1,
|
||||
kVendor_extension = 0,
|
||||
kLanguage_extension = 1,
|
||||
kAPI_extension = 2
|
||||
}Extension_Type;
|
||||
|
||||
const char *kernel_strings[] = {
|
||||
"kernel void test(global int *defines)\n{\n",
|
||||
"#pragma OPENCL EXTENSION %s : enable\n",
|
||||
"#ifdef %s\n"
|
||||
" defines[%d] = 1;\n"
|
||||
"#else\n"
|
||||
" defines[%d] = 0;\n"
|
||||
"#endif\n",
|
||||
"#pragma OPENCL EXTENSION %s : disable\n\n",
|
||||
"}\n"
|
||||
};
|
||||
|
||||
int test_compiler_defines_for_extensions(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems )
|
||||
{
|
||||
|
||||
int error;
|
||||
int total_errors = 0;
|
||||
|
||||
|
||||
// Get the extensions string for the device
|
||||
size_t size;
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, 0, NULL, &size);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS size failed");
|
||||
|
||||
char *extensions = (char*)malloc(sizeof(char)*(size + 1));
|
||||
if (extensions == 0) {
|
||||
log_error("Failed to allocate memory for extensions string.\n");
|
||||
return -1;
|
||||
}
|
||||
memset( extensions, CHAR_MIN, sizeof(char)*(size+1) );
|
||||
|
||||
error = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, sizeof(char)*size, extensions, NULL);
|
||||
test_error(error, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS failed");
|
||||
|
||||
// Check to make sure the extension string is NUL terminated.
|
||||
if( extensions[size] != CHAR_MIN )
|
||||
{
|
||||
test_error( -1, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS wrote past the end of the array!" );
|
||||
return -1;
|
||||
}
|
||||
extensions[size] = '\0'; // set last char to NUL to avoid problems with string functions later
|
||||
|
||||
// test for termination with '\0'
|
||||
size_t stringSize = strlen( extensions );
|
||||
if( stringSize == size )
|
||||
{
|
||||
test_error( -1, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS is not NUL terminated!" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Break up the extensions
|
||||
log_info("Device reports the following extensions:\n");
|
||||
char *extensions_supported[1024];
|
||||
Extension_Type extension_type[1024];
|
||||
int num_of_supported_extensions = 0;
|
||||
char *currentP = extensions;
|
||||
|
||||
memset( extension_type, 0, sizeof( extension_type) );
|
||||
|
||||
// loop over extension string
|
||||
while (currentP != extensions + stringSize)
|
||||
{
|
||||
// skip leading white space
|
||||
while( *currentP == ' ' )
|
||||
currentP++;
|
||||
|
||||
// Exit if end of string
|
||||
if( *currentP == '\0' )
|
||||
{
|
||||
if( currentP != extensions + stringSize)
|
||||
{
|
||||
test_error( -1, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS contains a NUL in the middle of the string!" );
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Not space, not end of string, so extension
|
||||
char *start = currentP; // start of extension name
|
||||
|
||||
// loop looking for the end
|
||||
while (*currentP != ' ' && currentP != extensions + stringSize)
|
||||
{
|
||||
// check for non-space white space in the extension name
|
||||
if( isspace(*currentP) )
|
||||
{
|
||||
test_error( -1, "clGetDeviceInfo for CL_DEVICE_EXTENSIONS contains a non-space whitespace in an extension name!" );
|
||||
return -1;
|
||||
}
|
||||
currentP++;
|
||||
}
|
||||
|
||||
// record the extension name
|
||||
uintptr_t extension_length = (uintptr_t) currentP - (uintptr_t) start;
|
||||
extensions_supported[ num_of_supported_extensions ] = (char*) malloc( (extension_length + 1) * sizeof( char ) );
|
||||
if( NULL == extensions_supported[ num_of_supported_extensions ] )
|
||||
{
|
||||
log_error( "Error: unable to allocate memory to hold extension name: %ld chars\n", extension_length );
|
||||
return -1;
|
||||
}
|
||||
memcpy( extensions_supported[ num_of_supported_extensions ], start, extension_length * sizeof( char ) );
|
||||
extensions_supported[ num_of_supported_extensions ][extension_length] = '\0';
|
||||
|
||||
// If the extension is a cl_khr extension, make sure it is an approved cl_khr extension -- looking for misspellings here
|
||||
if( extensions_supported[ num_of_supported_extensions ][0] == 'c' &&
|
||||
extensions_supported[ num_of_supported_extensions ][1] == 'l' &&
|
||||
extensions_supported[ num_of_supported_extensions ][2] == '_' &&
|
||||
extensions_supported[ num_of_supported_extensions ][3] == 'k' &&
|
||||
extensions_supported[ num_of_supported_extensions ][4] == 'h' &&
|
||||
extensions_supported[ num_of_supported_extensions ][5] == 'r' &&
|
||||
extensions_supported[ num_of_supported_extensions ][6] == '_' )
|
||||
{
|
||||
size_t ii;
|
||||
for( ii = 0; ii < num_known_extensions; ii++ )
|
||||
{
|
||||
if( 0 == strcmp( known_extensions[ii], extensions_supported[ num_of_supported_extensions ] ) )
|
||||
break;
|
||||
}
|
||||
if( ii == num_known_extensions )
|
||||
{
|
||||
log_error( "FAIL: Extension %s is not in the list of approved Khronos extensions!", extensions_supported[ num_of_supported_extensions ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// Is it an embedded extension?
|
||||
else if( memcmp( extensions_supported[ num_of_supported_extensions ], "cles_khr_", 9 ) == 0 )
|
||||
{
|
||||
// Yes, but is it a known one?
|
||||
size_t ii;
|
||||
for( ii = 0; known_embedded_extensions[ ii ] != NULL; ii++ )
|
||||
{
|
||||
if( strcmp( known_embedded_extensions[ ii ], extensions_supported[ num_of_supported_extensions ] ) == 0 )
|
||||
break;
|
||||
}
|
||||
if( known_embedded_extensions[ ii ] == NULL )
|
||||
{
|
||||
log_error( "FAIL: Extension %s is not in the list of approved Khronos embedded extensions!", extensions_supported[ num_of_supported_extensions ] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// It's approved, but are we even an embedded system?
|
||||
char profileStr[128] = "";
|
||||
error = clGetDeviceInfo( device, CL_DEVICE_PROFILE, sizeof( profileStr ), &profileStr, NULL );
|
||||
test_error( error, "Unable to get CL_DEVICE_PROFILE to validate embedded extension name" );
|
||||
|
||||
if( strcmp( profileStr, "EMBEDDED_PROFILE" ) != 0 )
|
||||
{
|
||||
log_error( "FAIL: Extension %s is an approved embedded extension, but on a non-embedded profile!", extensions_supported[ num_of_supported_extensions ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // All other extensions must be of the form cl_<vendor_name>_<name>
|
||||
if( extensions_supported[ num_of_supported_extensions ][0] != 'c' ||
|
||||
extensions_supported[ num_of_supported_extensions ][1] != 'l' ||
|
||||
extensions_supported[ num_of_supported_extensions ][2] != '_' )
|
||||
{
|
||||
log_error( "FAIL: Extension %s doesn't start with \"cl_\"!", extensions_supported[ num_of_supported_extensions ] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( extensions_supported[ num_of_supported_extensions ][3] == '_' || extensions_supported[ num_of_supported_extensions ][3] == '\0' )
|
||||
{
|
||||
log_error( "FAIL: Vendor name is missing in extension %s!", extensions_supported[ num_of_supported_extensions ] );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// look for the second underscore for name
|
||||
char *p = extensions_supported[ num_of_supported_extensions ] + 4;
|
||||
while( *p != '\0' && *p != '_' )
|
||||
p++;
|
||||
|
||||
if( *p != '_' || p[1] == '\0')
|
||||
{
|
||||
log_error( "FAIL: extension name is missing in extension %s!", extensions_supported[ num_of_supported_extensions ] );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
num_of_supported_extensions++;
|
||||
}
|
||||
|
||||
// Build a list of the known extensions that are not supported by the device
|
||||
char *extensions_not_supported[1024];
|
||||
int num_not_supported_extensions = 0;
|
||||
for( int i = 0; i < num_of_supported_extensions; i++ )
|
||||
{
|
||||
int is_supported = 0;
|
||||
for( size_t j = 0; j < num_known_extensions; j++ )
|
||||
{
|
||||
if( strcmp( extensions_supported[ i ], known_extensions[ j ] ) == 0 )
|
||||
{
|
||||
extension_type[ i ] = ( j < first_API_extension ) ? kLanguage_extension : kAPI_extension;
|
||||
is_supported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !is_supported )
|
||||
{
|
||||
for( int j = 0; known_embedded_extensions[ j ] != NULL; j++ )
|
||||
{
|
||||
if( strcmp( extensions_supported[ i ], known_embedded_extensions[ j ] ) == 0 )
|
||||
{
|
||||
extension_type[ i ] = kLanguage_extension;
|
||||
is_supported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_supported) {
|
||||
extensions_not_supported[num_not_supported_extensions] = (char*)malloc(strlen(extensions_supported[i])+1);
|
||||
strcpy(extensions_not_supported[num_not_supported_extensions], extensions_supported[i]);
|
||||
num_not_supported_extensions++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<num_of_supported_extensions; i++) {
|
||||
log_info("%40s -- Supported\n", extensions_supported[i]);
|
||||
}
|
||||
for (int i=0; i<num_not_supported_extensions; i++) {
|
||||
log_info("%40s -- Not Supported\n", extensions_not_supported[i]);
|
||||
}
|
||||
|
||||
// Build the kernel
|
||||
char *kernel_code = (char*)malloc(1025*256*(num_not_supported_extensions+num_of_supported_extensions));
|
||||
memset(kernel_code, 0, 1025*256*(num_not_supported_extensions+num_of_supported_extensions));
|
||||
|
||||
int i, index = 0;
|
||||
strcat(kernel_code, kernel_strings[0]);
|
||||
for (i=0; i<num_of_supported_extensions; i++, index++) {
|
||||
|
||||
if (extension_type[i] == kLanguage_extension)
|
||||
sprintf(kernel_code + strlen(kernel_code), kernel_strings[1], extensions_supported[i]);
|
||||
|
||||
sprintf(kernel_code + strlen(kernel_code), kernel_strings[2], extensions_supported[i], index, index );
|
||||
|
||||
if (extension_type[i] == kLanguage_extension)
|
||||
sprintf(kernel_code + strlen(kernel_code), kernel_strings[3], extensions_supported[i] );
|
||||
}
|
||||
for ( i = 0; i<num_not_supported_extensions; i++, index++) {
|
||||
sprintf(kernel_code + strlen(kernel_code), kernel_strings[2], extensions_not_supported[i], index, index );
|
||||
}
|
||||
strcat(kernel_code, kernel_strings[4]);
|
||||
|
||||
// Now we need to execute the kernel
|
||||
cl_mem defines;
|
||||
cl_int *data;
|
||||
cl_program program;
|
||||
cl_kernel kernel;
|
||||
|
||||
error = create_single_kernel_helper(context, &program, &kernel, 1, (const char **)&kernel_code, "test");
|
||||
test_error(error, "create_single_kernel_helper failed");
|
||||
|
||||
data = (cl_int*)malloc(sizeof(cl_int)*(num_not_supported_extensions+num_of_supported_extensions));
|
||||
memset(data, 0, sizeof(cl_int)*(num_not_supported_extensions+num_of_supported_extensions));
|
||||
defines = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR,
|
||||
sizeof(cl_int)*(num_not_supported_extensions+num_of_supported_extensions), data, &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(defines), &defines);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
size_t global_size = 1;
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_size, NULL, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, defines, CL_TRUE, 0, sizeof(cl_int)*(num_not_supported_extensions+num_of_supported_extensions),
|
||||
data, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
// Report what the compiler reported
|
||||
log_info("\nCompiler reported the following extensions defined in the OpenCL C kernel environment:\n");
|
||||
index = 0;
|
||||
int total_supported = 0;
|
||||
for (int i=0; i<num_of_supported_extensions; i++, index++) {
|
||||
if (data[index] == 1) {
|
||||
log_info("\t%s\n", extensions_supported[i]);
|
||||
total_supported++;
|
||||
}
|
||||
}
|
||||
for (int i=0; i<num_not_supported_extensions; i++, index++) {
|
||||
if (data[index] == 1) {
|
||||
log_info("\t%s\n", extensions_not_supported[i]);
|
||||
total_supported++;
|
||||
}
|
||||
}
|
||||
if (total_supported == 0)
|
||||
log_info("\t(none)\n");
|
||||
|
||||
// Count the errors
|
||||
index = 0;
|
||||
int unknown = 0;
|
||||
for ( i=0; i<num_of_supported_extensions; i++)
|
||||
{
|
||||
if (data[i] != 1)
|
||||
{
|
||||
switch( extension_type[i] )
|
||||
{
|
||||
case kLanguage_extension:
|
||||
log_error("ERROR: Supported extension %s not defined in kernel.\n", extensions_supported[i]);
|
||||
total_errors++;
|
||||
break;
|
||||
case kVendor_extension:
|
||||
unknown++;
|
||||
break;
|
||||
case kAPI_extension:
|
||||
break;
|
||||
default:
|
||||
log_error( "ERROR: internal test error in extension detection. This is probably a bug in the test.\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(unknown)
|
||||
{
|
||||
log_info( "\nThe following non-KHR extensions are supported but do not add a preprocessor symbol to OpenCL C.\n" );
|
||||
for (int z=0; z<num_of_supported_extensions; z++)
|
||||
{
|
||||
if (data[z] != 1 && extension_type[z] == kVendor_extension )
|
||||
log_info( "\t%s\n", extensions_supported[z]);
|
||||
}
|
||||
}
|
||||
|
||||
for ( ; i<num_not_supported_extensions; i++) {
|
||||
if (data[i] != 0) {
|
||||
log_error("ERROR: Unsupported extension %s is defined in kernel.\n", extensions_not_supported[i]);
|
||||
total_errors++;
|
||||
}
|
||||
}
|
||||
log_info("\n");
|
||||
|
||||
// cleanup
|
||||
free(data);
|
||||
free(kernel_code);
|
||||
for(i=0; i<num_of_supported_extensions; i++) {
|
||||
free(extensions_supported[i]);
|
||||
}
|
||||
free(extensions);
|
||||
if( defines ) {
|
||||
error = clReleaseMemObject( defines );
|
||||
test_error( error, "Unable to release memory object" );
|
||||
}
|
||||
|
||||
if (total_errors)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
101
test_conformance/compiler/test_image_macro.c
Normal file
101
test_conformance/compiler/test_image_macro.c
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// 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( __APPLE__ ) || defined( __linux__ ))
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
const char * image_supported_source = "kernel void enabled(global int * buf) { \r\n" \
|
||||
"int n = get_global_id(0); \r\n"\
|
||||
"buf[n] = 0; \r\n "\
|
||||
"#ifndef __IMAGE_SUPPORT__ \r\n" \
|
||||
"ERROR; \r\n"\
|
||||
"#endif \r\n"\
|
||||
"\r\n } \r\n";
|
||||
|
||||
|
||||
const char * image_not_supported_source = "kernel void not_enabled(global int * buf) { \r\n" \
|
||||
"int n = get_global_id(0); \r\n"\
|
||||
"buf[n] = 0; \r\n "\
|
||||
"#ifdef __IMAGE_SUPPORT__ \r\n" \
|
||||
"ERROR; \r\n"\
|
||||
"#endif \r\n"\
|
||||
"\r\n } \r\n";
|
||||
|
||||
|
||||
int test_image_macro(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
cl_bool image_support;
|
||||
char buf[256];
|
||||
int status;
|
||||
cl_program program;
|
||||
|
||||
status = clGetDeviceInfo( deviceID, CL_DEVICE_NAME, sizeof( buf ), buf, NULL );
|
||||
if( status )
|
||||
{
|
||||
log_error( "getting device info (name): %d\n", status );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
status = clGetDeviceInfo( deviceID, CL_DEVICE_IMAGE_SUPPORT, sizeof( image_support ), &image_support, NULL );
|
||||
if( status )
|
||||
{
|
||||
log_error( "getting device info (image support): %d\n", status );
|
||||
return status;
|
||||
}
|
||||
|
||||
if( (image_support == CL_TRUE) )
|
||||
{
|
||||
program = clCreateProgramWithSource( context, 1, (const char**) &image_supported_source, NULL, &status );
|
||||
|
||||
if( status )
|
||||
{
|
||||
log_error ("Failure creating program, [%d] \n", status );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
if( status )
|
||||
log_error("CL_DEVICE_IMAGE_SUPPORT is set, __IMAGE_SUPPORT__ macro not set \n");
|
||||
else
|
||||
log_info("CL_DEVICE_IMAGE_SUPPORT is set, __IMAGE_SUPPORT__ macro is set \n");
|
||||
}
|
||||
else
|
||||
{
|
||||
program = clCreateProgramWithSource( context, 1, (const char**) &image_not_supported_source, NULL, &status );
|
||||
if( status )
|
||||
{
|
||||
log_error ("Failure creating program, [%d] \n", status );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = clBuildProgram( program, 1, &deviceID, NULL, NULL, NULL );
|
||||
if( status )
|
||||
log_error("CL_DEVICE_IMAGE_SUPPORT not set, __IMAGE_SUPPORT__ macro is set \n");
|
||||
else
|
||||
log_info("CL_DEVICE_IMAGE_SUPPORT not set, __IMAGE_SUPPORT__ macro not set \n");
|
||||
}
|
||||
|
||||
status = clReleaseProgram( program );
|
||||
if( status )
|
||||
{
|
||||
log_error ("Unable to release program object, [%d] \n", status );
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
290
test_conformance/compiler/test_pragma_unroll.c
Normal file
290
test_conformance/compiler/test_pragma_unroll.c
Normal file
@@ -0,0 +1,290 @@
|
||||
//
|
||||
// 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 <vector>
|
||||
|
||||
const char *pragma_unroll_kernels[] = {
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" __attribute__((opencl_unroll_hint))\n"
|
||||
" for(size_t i = 0; i < 100; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" __attribute__((opencl_unroll_hint(1)))\n"
|
||||
" for(size_t i = 0; i < 100; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" __attribute__((opencl_unroll_hint(10)))\n"
|
||||
" for(size_t i = 0; i < 100; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" __attribute__((opencl_unroll_hint(100)))\n"
|
||||
" for(size_t i = 0; i < 100; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" __attribute__((opencl_unroll_hint))\n"
|
||||
" for(size_t i = 0; i < n; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" __attribute__((opencl_unroll_hint(1)))\n"
|
||||
" for(size_t i = 0; i < n; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" __attribute__((opencl_unroll_hint(10)))\n"
|
||||
" for(size_t i = 0; i < n; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" __attribute__((opencl_unroll_hint(100)))\n"
|
||||
" for(size_t i = 0; i < n; ++i)\n"
|
||||
" dst[i] = i;\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint))\n"
|
||||
" while(i < 100) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(1)))\n"
|
||||
" while(i < 100) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(10)))\n"
|
||||
" while(i < 100) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(100)))\n"
|
||||
" while(i < 100) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint))\n"
|
||||
" while(i < n) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(1)))\n"
|
||||
" while(i < n) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(10)))\n"
|
||||
" while(i < n) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(100)))\n"
|
||||
" while(i < n) {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < 100);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(1)))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < 100);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(10)))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < 100);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(100)))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < 100);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < n);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(1)))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < n);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(10)))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < n);\n"
|
||||
"}\n",
|
||||
"__kernel void pragma_unroll(__global uint *dst)\n"
|
||||
"{\n"
|
||||
" size_t tid = get_global_id(0);\n"
|
||||
" size_t n = (tid + 1) * 100;\n"
|
||||
" size_t i = 0;\n"
|
||||
" __attribute__((opencl_unroll_hint(100)))\n"
|
||||
" do {\n"
|
||||
" dst[i] = i;\n"
|
||||
" ++i;\n"
|
||||
" } while(i < n);\n"
|
||||
"}\n",
|
||||
};
|
||||
|
||||
int test_pragma_unroll(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) {
|
||||
const size_t ELEMENT_NUM = 100;
|
||||
const size_t KERNEL_NUM = 24;
|
||||
|
||||
cl_int error;
|
||||
|
||||
//execute all kernels and check if the results are as expected
|
||||
for (size_t kernelIdx = 0; kernelIdx < KERNEL_NUM; ++kernelIdx) {
|
||||
clProgramWrapper program;
|
||||
clKernelWrapper kernel;
|
||||
if( create_single_kernel_helper_with_build_options( context, &program, &kernel, 1, (const char **)&pragma_unroll_kernels[kernelIdx], "pragma_unroll", "-cl-std=CL2.0" ) ) {
|
||||
log_error("The program we attempted to compile was: \n%s\n", pragma_unroll_kernels[kernelIdx]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
clMemWrapper buffer = clCreateBuffer(context, CL_MEM_READ_WRITE, ELEMENT_NUM * sizeof(cl_uint), NULL, &error);
|
||||
test_error(error, "clCreateBuffer failed");
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(buffer), &buffer);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
//only one thread should be enough to verify if kernel is fully functional
|
||||
size_t workSize = 1;
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &workSize, NULL, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
std::vector<cl_uint> results(ELEMENT_NUM, 0);
|
||||
error = clEnqueueReadBuffer(queue, buffer, CL_TRUE, 0, ELEMENT_NUM * sizeof(cl_uint), &results[0], 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (size_t i = 0; i < ELEMENT_NUM; ++i) {
|
||||
if (results[i] != i) {
|
||||
log_error("Kernel %d returned invalid result. Test: %d, expected: %d\n", kernelIdx + 1, results[i], i);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
342
test_conformance/compiler/test_preprocessor.c
Normal file
342
test_conformance/compiler/test_preprocessor.c
Normal file
@@ -0,0 +1,342 @@
|
||||
//
|
||||
// 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/os_helpers.h"
|
||||
|
||||
extern cl_uint gRandomSeed;
|
||||
|
||||
const char *define_kernel_code[] = {
|
||||
" #define VALUE\n"
|
||||
"__kernel void define_test(__global int *src, __global int *dstA, __global int *dstB)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"#ifdef VALUE\n"
|
||||
" dstA[tid] = src[tid] * 2;\n"
|
||||
"#else\n"
|
||||
" dstA[tid] = src[tid] * 4;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#undef VALUE\n"
|
||||
"#ifdef VALUE\n"
|
||||
" dstB[tid] = src[tid] * 2;\n"
|
||||
"#else\n"
|
||||
" dstB[tid] = src[tid] * 4;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"}\n"};
|
||||
|
||||
|
||||
|
||||
|
||||
int test_preprocessor_define_udef(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) {
|
||||
|
||||
cl_int error;
|
||||
clKernelWrapper kernel;
|
||||
clProgramWrapper program;
|
||||
clMemWrapper buffer[3];
|
||||
cl_int *srcData, *resultData;
|
||||
int i;
|
||||
MTdata d;
|
||||
|
||||
error = create_single_kernel_helper(context, &program, &kernel, 1, define_kernel_code, "define_test");
|
||||
if (error)
|
||||
return -1;
|
||||
|
||||
buffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
buffer[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
buffer[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
srcData = (cl_int*)malloc(sizeof(cl_int)*num_elements);
|
||||
if (srcData == NULL) {
|
||||
log_error("Failed to allocate storage for source data (%d cl_ints).\n", num_elements);
|
||||
return -1;
|
||||
}
|
||||
|
||||
d = init_genrand( gRandomSeed );
|
||||
for (i=0; i<num_elements; i++)
|
||||
srcData[i] = (int)get_random_float(-1024, 1024,d);
|
||||
free_mtdata(d); d = NULL;
|
||||
|
||||
resultData = (cl_int*)malloc(sizeof(cl_int)*num_elements);
|
||||
if (resultData == NULL) {
|
||||
free(srcData);
|
||||
log_error("Failed to allocate storage for result data (%d cl_ints).\n", num_elements);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(buffer[0]), &buffer[0]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel, 1, sizeof(buffer[1]), &buffer[1]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel, 2, sizeof(buffer[2]), &buffer[2]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
|
||||
error = clEnqueueWriteBuffer(queue, buffer[0], CL_TRUE, 0, num_elements*sizeof(cl_int), srcData, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueWriteBuffer failed");
|
||||
|
||||
size_t threads[3] = {num_elements, 0, 0};
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, buffer[1], CL_TRUE, 0, num_elements*sizeof(cl_int), resultData, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
if (resultData[i] != srcData[i]*2) {
|
||||
free(srcData);
|
||||
free(resultData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clEnqueueReadBuffer(queue, buffer[2], CL_TRUE, 0, num_elements*sizeof(cl_int), resultData, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
if (resultData[i] != srcData[i]*4) {
|
||||
free(srcData);
|
||||
free(resultData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(srcData);
|
||||
free(resultData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *include_kernel_code =
|
||||
"#include \"%s\"\n"
|
||||
"__kernel void include_test(__global int *src, __global int *dstA)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"#ifdef HEADER_FOUND\n"
|
||||
" dstA[tid] = HEADER_FOUND;\n"
|
||||
"#else\n"
|
||||
" dstA[tid] = 0;\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
int test_preprocessor_include(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) {
|
||||
|
||||
cl_int error;
|
||||
clKernelWrapper kernel;
|
||||
clProgramWrapper program;
|
||||
clMemWrapper buffer[2];
|
||||
cl_int *resultData;
|
||||
int i;
|
||||
|
||||
char include_dir[4096] = {0};
|
||||
char include_kernel[4096] = {0};
|
||||
|
||||
char const * sep = get_dir_sep();
|
||||
char const * path = get_exe_dir();
|
||||
|
||||
/* Build with the include directory defined */
|
||||
sprintf(include_dir,"%s%sincludeTestDirectory%stestIncludeFile.h", path, sep, sep);
|
||||
sprintf(include_kernel, include_kernel_code, include_dir);
|
||||
free( (void *) sep );
|
||||
free( (void *) path );
|
||||
|
||||
const char* test_kernel[] = { include_kernel, 0 };
|
||||
error = create_single_kernel_helper(context, &program, &kernel, 1, test_kernel, "include_test");
|
||||
if (error)
|
||||
return -1;
|
||||
|
||||
buffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
buffer[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
resultData = (cl_int*)malloc(sizeof(cl_int)*num_elements);
|
||||
if (resultData == NULL) {
|
||||
log_error("Failed to allocate storage for result data (%d cl_ints).\n", num_elements);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(buffer[0]), &buffer[0]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
error = clSetKernelArg(kernel, 1, sizeof(buffer[1]), &buffer[1]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
size_t threads[3] = {num_elements, 0, 0};
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
error = clEnqueueReadBuffer(queue, buffer[1], CL_TRUE, 0, num_elements*sizeof(cl_int), resultData, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
if (resultData[i] != 12) {
|
||||
free(resultData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(resultData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const char *line_error_kernel_code[] = {
|
||||
"__kernel void line_error_test(__global int *dstA)\n"
|
||||
"{\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"#line 124 \"fictitious/file/name.c\" \n"
|
||||
"#error some error\n"
|
||||
" dstA[tid] = tid;\n"
|
||||
"\n"
|
||||
"}\n"};
|
||||
|
||||
|
||||
int test_preprocessor_line_error(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) {
|
||||
|
||||
cl_int error, error2;
|
||||
clKernelWrapper kernel;
|
||||
clProgramWrapper program;
|
||||
clMemWrapper buffer[2];
|
||||
|
||||
char buildLog[ 1024 * 128 ];
|
||||
|
||||
log_info("test_preprocessor_line_error may report spurious ERRORS in the conformance log.\n");
|
||||
|
||||
/* Create the program object from source */
|
||||
program = clCreateProgramWithSource( context, 1, line_error_kernel_code, NULL, &error );
|
||||
test_error(error, "clCreateProgramWithSource failed");
|
||||
|
||||
/* Compile the program */
|
||||
error2 = clBuildProgram( program, 0, NULL, NULL, NULL, NULL );
|
||||
if (error2) {
|
||||
log_info("Build error detected at clBuildProgram.");
|
||||
} else {
|
||||
log_info("Error not reported by clBuildProgram.\n");
|
||||
}
|
||||
|
||||
cl_build_status status;
|
||||
error = clGetProgramBuildInfo(program, deviceID, CL_PROGRAM_BUILD_STATUS, sizeof(status), &status, NULL);
|
||||
test_error(error, "clGetProgramBuildInfo failed for CL_PROGRAM_BUILD_STATUS");
|
||||
if (status != CL_BUILD_ERROR) {
|
||||
log_error("Build status did not return CL_BUILD_ERROR for a program with #error defined.\n");
|
||||
return -1;
|
||||
} else if (status == CL_BUILD_ERROR || error2) {
|
||||
error2 = clGetProgramBuildInfo( program, deviceID, CL_PROGRAM_BUILD_LOG, sizeof( buildLog ), buildLog, NULL );
|
||||
test_error( error2, "Unable to get program build log" );
|
||||
|
||||
log_info("Build failed as expected with #error in source:\n");
|
||||
log_info( "Build log is: ------------\n" );
|
||||
log_info( "%s\n", buildLog );
|
||||
log_info( "Original source is: ------------\n" );
|
||||
log_info( "%s", line_error_kernel_code[0] );
|
||||
log_info( "\n----------\n" );
|
||||
|
||||
if (strstr(buildLog, "fictitious/file/name.c")) {
|
||||
log_info("Found file name from #line param in log output.\n");
|
||||
} else {
|
||||
log_info("WARNING: Did not find file name from #line param in log output.\n");
|
||||
}
|
||||
|
||||
if (strstr(buildLog, "124")) {
|
||||
log_info("Found line number from #line param in log output.\n");
|
||||
} else {
|
||||
log_info("WARNING: Did not find line number from #line param in log output.\n");
|
||||
}
|
||||
|
||||
log_info("test_preprocessor_line_error PASSED.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* And create a kernel from it */
|
||||
kernel = clCreateKernel( program, "line_error_test", &error );
|
||||
test_error(error, "clCreateKernel failed");
|
||||
|
||||
buffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(buffer[0]), &buffer[0]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
size_t threads[3] = {num_elements, 0, 0};
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
log_error("Program built and ran with #error defined.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char *pragma_kernel_code[] = {
|
||||
"__kernel void pragma_test(__global int *dstA)\n"
|
||||
"{\n"
|
||||
"#pragma A fool thinks himself to be wise, but a wise man knows himself to be a fool.\n"
|
||||
" int tid = get_global_id(0);\n"
|
||||
"#pragma\n"
|
||||
" dstA[tid] = tid;\n"
|
||||
"#pragma mark Though I am not naturally honest, I am so sometimes by chance.\n"
|
||||
"\n"
|
||||
"}\n"};
|
||||
|
||||
|
||||
int test_preprocessor_pragma(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) {
|
||||
|
||||
cl_int error;
|
||||
clKernelWrapper kernel;
|
||||
clProgramWrapper program;
|
||||
clMemWrapper buffer[2];
|
||||
cl_int *resultData;
|
||||
int i;
|
||||
|
||||
error = create_single_kernel_helper(context, &program, &kernel, 1, pragma_kernel_code, "pragma_test");
|
||||
if (error)
|
||||
return -1;
|
||||
|
||||
buffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, num_elements*sizeof(cl_int), NULL, &error);
|
||||
test_error( error, "clCreateBuffer failed");
|
||||
|
||||
error = clSetKernelArg(kernel, 0, sizeof(buffer[0]), &buffer[0]);
|
||||
test_error(error, "clSetKernelArg failed");
|
||||
|
||||
size_t threads[3] = {num_elements, 0, 0};
|
||||
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueNDRangeKernel failed");
|
||||
|
||||
resultData = (cl_int*)malloc(sizeof(cl_int)*num_elements);
|
||||
if (resultData == NULL) {
|
||||
log_error("Failed to allocate storage for result data (%d cl_ints).\n", num_elements);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = clEnqueueReadBuffer(queue, buffer[0], CL_TRUE, 0, num_elements*sizeof(cl_int), resultData, 0, NULL, NULL);
|
||||
test_error(error, "clEnqueueReadBuffer failed");
|
||||
|
||||
for (i=0; i<num_elements; i++)
|
||||
if (resultData[i] != i) {
|
||||
free(resultData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(resultData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user