Merge pull request #2 from KhronosGroup/master

Update nikhilj-nv/OpenCL-CTS:master with KhronosGroup/OpenCL-CTS:master
This commit is contained in:
Nikhil Joshi
2020-09-16 17:17:30 +05:30
committed by GitHub
1555 changed files with 77439 additions and 62162 deletions

54
.appveyor.yml Normal file
View File

@@ -0,0 +1,54 @@
os:
- Visual Studio 2017
shallow_clone: true
platform:
- Win32
- x64
configuration:
- Release
environment:
matrix:
- SETARCH: i686
- SETARCH: x86_64
matrix:
exclude:
- platform: Win32
SETARCH: x86_64
- platform: x64
SETARCH: i686
before_build:
# Setup environment:
- ps: $env:TOP = $env:APPVEYOR_BUILD_FOLDER
- ps: $env:TOP
- echo %TOP%
# Get the OpenCL Headers:
- git clone --depth=1 https://github.com/KhronosGroup/OpenCL-Headers OpenCL-Headers
# Get and build the OpenCL ICD Loader:
- git clone --depth=1 https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
- ps: cd OpenCL-ICD-Loader
- ps: mkdir build
- ps: cd build
- cmake -A%PLATFORM% -DENABLE_OPENCL30_PROVISIONAL=1 -DOPENCL_ICD_LOADER_HEADERS_DIR=%TOP%/OpenCL-Headers/ ..
- cmake --build . --config %CONFIGURATION%
- ps: cd $env:TOP
# Get the libclcxx standard library:
- git clone --depth=1 https://github.com/KhronosGroup/libclcxx.git libclcxx
# Generate the CTS solution file:
- cmake -DCL_INCLUDE_DIR=%TOP%/OpenCL-Headers
-DCL_LIB_DIR=%TOP%/OpenCL-ICD-Loader/build
-DCL_LIBCLCXX_DIR=%TOP%/libclcxx
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin
-DOPENCL_LIBRARIES="OpenCL"
-H. -Bbuild_win -A%PLATFORM%
-DD3D10_IS_SUPPORTED=ON -DD3D11_IS_SUPPORTED=ON -DARCH=%SETARCH%
build:
project: build_win\CLConform.sln
parallel: true
verbosity: normal

124
.clang-format Normal file
View File

@@ -0,0 +1,124 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: false
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseTab: Never
...

View File

@@ -4,28 +4,19 @@ os:
- linux
- osx
jobs:
include:
- os: linux
dist: bionic
env: JOB_CHECK_FORMAT=1
addons:
apt:
packages:
- clang-format-9
- os: linux
env: JOB_ARCHITECTURE=arm
- os: linux
env: JOB_ARCHITECTURE=aarch64
script:
- export TOP=$(pwd)
- git clone https://github.com/KhronosGroup/OpenCL-Headers.git
- cd OpenCL-Headers
- ln -s CL OpenCL # For OSX builds
- cd ..
- git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
- cd ${TOP}/OpenCL-ICD-Loader
- mkdir build
- cd build
- cmake -DOPENCL_ICD_LOADER_HEADERS_DIR=${TOP}/OpenCL-Headers/ ..
- make
- cd ${TOP}
- git clone https://github.com/KhronosGroup/libclcxx.git
- ls -l
- mkdir build
- cd build
- cmake -DCL_INCLUDE_DIR=${TOP}/OpenCL-Headers
-DCL_LIB_DIR=${TOP}/OpenCL-ICD-Loader/build
-DCL_LIBCLCXX_DIR=${TOP}/libclcxx
-DCL_OFFLINE_COMPILER=/dummy/path/to/compiler
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin
-DOPENCL_LIBRARIES="-lOpenCL -lpthread"
..
- make -j2
- ./travis.sh

View File

@@ -5,28 +5,29 @@ set(CLConform_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
project(CLConform${CONFORMANCE_SUFFIX})
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_BUILD_TYPE STREQUAL "release")
set (BUILD_FLAVOR "release")
else(CMAKE_BUILD_TYPE STREQUAL "release")
set (BUILD_FLAVOR "debug")
endif(CMAKE_BUILD_TYPE STREQUAL "release")
set(CLConform_VERSION_MAJOR "2")
set(CLConform_VERSION_MINOR "2")
set(CLConform_VERSION_MICRO "0")
set(CLConform_VERSION_EXTRA "")
set(CLConform_VERSION "${CLConform_VERSION_MAJOR}.${CLConform_VERSION_MINOR}")
set(CLConform_VERSION_FULL
"${CLConform_VERSION}.${CLConform_VERSION_MICRO}${CLConform_VERSION_EXTRA}")
add_definitions(-DCL_TARGET_OPENCL_VERSION=220)
add_definitions(-DCL_TARGET_OPENCL_VERSION=300)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_2_2_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_2_1_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_2_0_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_2_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_1_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_0_APIS=1)
option(USE_CL_EXPERIMENTAL "Use Experimental definitions" OFF)
if(USE_CL_EXPERIMENTAL)
add_definitions(-DCL_EXPERIMENTAL)
endif(USE_CL_EXPERIMENTAL)
# Support both VS2008 and VS2012.
set(BUILD_DIR "$ENV{ADRENO_DRIVER}/build")
@@ -92,24 +93,23 @@ endif(CLPP_DEVELOPMENT_OPTIONS)
# Path to offline OpenCL C/C++ compiler provided by Khronos.
# See https://github.com/KhronosGroup/SPIR/ (spirv-1.1 branch or newer SPIR-V-ready
# branch should be used).
if(CL_OFFLINE_COMPILER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCL_OFFLINE_COMPILER=${CL_OFFLINE_COMPILER}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_OFFLINE_COMPILER=${CL_OFFLINE_COMPILER}")
if(KHRONOS_OFFLINE_COMPILER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKHRONOS_OFFLINE_COMPILER=${KHRONOS_OFFLINE_COMPILER}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKHRONOS_OFFLINE_COMPILER=${KHRONOS_OFFLINE_COMPILER}")
# Additional OpenCL C/C++ compiler option.
if(CL_OFFLINE_COMPILER_OPTIONS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCL_OFFLINE_COMPILER_OPTIONS=${CL_OFFLINE_COMPILER_OPTIONS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_OFFLINE_COMPILER_OPTIONS=${CL_OFFLINE_COMPILER_OPTIONS}")
endif(CL_OFFLINE_COMPILER_OPTIONS)
else(CL_OFFLINE_COMPILER)
message(STATUS "OpenCL C/C++ compiler hasn't been found!")
message(FATAL_ERROR "Pass path to OpenCL C/C++ compiler in CL_OFFLINE_COMPILER")
endif(CL_OFFLINE_COMPILER)
if(KHRONOS_OFFLINE_COMPILER_OPTIONS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKHRONOS_OFFLINE_COMPILER_OPTIONS=${KHRONOS_OFFLINE_COMPILER_OPTIONS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKHRONOS_OFFLINE_COMPILER_OPTIONS=${KHRONOS_OFFLINE_COMPILER_OPTIONS}")
endif(KHRONOS_OFFLINE_COMPILER_OPTIONS)
else(KHRONOS_OFFLINE_COMPILER)
message(WARNING "KHRONOS_OFFLINE_COMPILER is not defined!")
message(WARNING "Running CL C++ tests will not be possible.")
endif(KHRONOS_OFFLINE_COMPILER)
# CL_LIBCLCXX_DIR - path to dir with OpenCL C++ STL (libclcxx)
# CL_INCLUDE_DIR - path to dir with OpenCL headers
# CL_LIBCLCXX_DIR - path to dir with OpenCL library
if(CL_INCLUDE_DIR AND CL_LIB_DIR AND CL_LIBCLCXX_DIR)
set(OPENCL_INCLUDE_DIR ${CL_INCLUDE_DIR})
link_directories(${CL_LIB_DIR})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCL_LIBCLCXX_DIR=${CL_LIBCLCXX_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_LIBCLCXX_DIR=${CL_LIBCLCXX_DIR}")
@@ -118,26 +118,68 @@ else(CL_INCLUDE_DIR AND CL_LIB_DIR AND CL_LIBCLCXX_DIR)
message(FATAL_ERROR "Either install OpenCL or pass -DCL_INCLUDE_DIR, -DCL_LIB_DIR and -DCL_LIBCLCXX_DIR")
endif(CL_INCLUDE_DIR AND CL_LIB_DIR AND CL_LIBCLCXX_DIR)
# CLConform_GL_LIBRARIES_DIR - path to OpenGL libraries
if(GL_IS_SUPPORTED AND CLConform_GL_LIBRARIES_DIR)
link_directories(${CLConform_GL_LIBRARIES_DIR})
endif (GL_IS_SUPPORTED AND CLConform_GL_LIBRARIES_DIR)
include(CheckFunctionExists)
include(CheckIncludeFiles)
include(CheckCXXCompilerFlag)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
set(CLConform_TARGET_ARCH ARM)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)")
set(CLConform_TARGET_ARCH ARM64)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
set(CLConform_TARGET_ARCH x86_64)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*")
set(CLConform_TARGET_ARCH x86)
endif()
if(NOT DEFINED CLConform_TARGET_ARCH)
message (FATAL_ERROR "Target architecture not recognised. Exiting.")
endif()
macro(add_cxx_flag_if_supported flag)
string(REGEX REPLACE "[-=+]" "" FLAG_NO_SIGNS ${flag})
check_cxx_compiler_flag(${flag} COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
if(COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
endif()
endmacro(add_cxx_flag_if_supported)
if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang")
add_cxx_flag_if_supported(-Wno-narrowing)
add_cxx_flag_if_supported(-Wno-format)
add_cxx_flag_if_supported(-Werror)
add_cxx_flag_if_supported(-Wno-error=cpp) # Allow #warning directive
add_cxx_flag_if_supported(-Wno-error=absolute-value) # Issue 783
add_cxx_flag_if_supported(-Wno-error=unknown-pragmas) # Issue #785
add_cxx_flag_if_supported(-Wno-error=asm-operand-widths) # Issue #784
add_cxx_flag_if_supported(-Wno-error=overflow) # Fixed by #699
# -msse -mfpmath=sse to force gcc to use sse for float math,
# avoiding excess precision problems that cause tests like int2float
# to falsely fail. -ffloat-store also works, but WG suggested
# that sse would be better.
if(CMAKE_ARM_COMPILER OR ANDROID)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -std=gnu99 -Wno-narrowing")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=gnu++11 -Wno-narrowing")
else(CMAKE_ARM_COMPILER OR ANDROID)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -std=gnu99 -msse -mfpmath=sse -Wno-narrowing")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -msse -mfpmath=sse -std=gnu++11 -Wno-narrowing")
endif(CMAKE_ARM_COMPILER OR ANDROID)
if(${CLConform_TARGET_ARCH} STREQUAL "x86_64" OR ${CLConform_TARGET_ARCH}
STREQUAL "x86")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse -msse2 -mfpmath=sse")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse -msse2 -mfpmath=sse")
add_cxx_flag_if_supported(-frounding-math)
endif()
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D__SSE__")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D__SSE__")
endif()
if( WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qlong-double -Qpc80 /DWIN32 /D_WINDOWS /W3 /GR /EHsc -nologo -Od -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -EHsc -Wall -Qdiag-disable:68,111,177,186,161,869,1028,2259,2553,181,239,265,1188 -fp:strict -fp:source")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qlong-double -Qpc80 /DWIN32 /D_WINDOWS /W3 /GR /EHsc -nologo -Od -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -EHsc -Wall -Qdiag-disable:68,111,177,186,161,869,1028,2259,2553,181,239,265,1188 -fp:strict -fp:source")
endif()
list(APPEND CLConform_LIBRARIES ${OPENCL_LIBRARIES})
if(ANDROID)
list(APPEND CLConform_LIBRARIES m)
@@ -152,11 +194,11 @@ if(APPLE)
list(APPEND CLConform_LIBRARIES ${iokit})
endif(APPLE)
include_directories(SYSTEM ${OPENCL_INCLUDE_DIR})
include_directories(SYSTEM ${CL_INCLUDE_DIR})
include_directories(${CLConform_SOURCE_DIR}/test_common/harness
${CLConform_SOURCE_DIR}/test_common/gles
${CLConform_SOURCE_DIR}/test_common/gl
${CMAKE_CURRENT_SOURCE_DIR}/test_common/harness)
${CLConform_SOURCE_DIR}/test_common)
if(CMAKE_BUILD_TYPE STREQUAL "release")
set (BUILD_FLAVOR "release")
@@ -165,10 +207,10 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "debug")
endif(CMAKE_BUILD_TYPE STREQUAL "release")
add_subdirectory(test_common)
add_subdirectory(test_conformance)
add_subdirectory(test_extensions)
set (PY_PATH "${CLConform_SOURCE_DIR}/test_conformance/*.py")
set (CSV_PATH "${CLConform_SOURCE_DIR}/test_conformance/*.csv")
# Support both VS2008 and VS2012.
set (DLL_FILES "${VS_BUILD_DIR}/Debug/*.dll")
set (DST_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/")
@@ -187,25 +229,10 @@ set_property(TARGET COPY_DLL${CONFORMANCE_SUFFIX} PROPERTY FOLDER "CONFORMANCE${
if(WIN32)
add_custom_target( COPY_FILES${CONFORMANCE_SUFFIX} ALL
COMMAND ${COPY} ${PY_PATH} ${DST_DIR}
COMMAND ${COPY} ${CSV_PATH} ${DST_DIR}
COMMAND ${COPY} ${DLL_FILES} ${DST_DIR}
COMMENT "Copying other files to output folder..." )
else(WIN32)
add_custom_target( COPY_FILES${CONFORMANCE_SUFFIX} )
endif(WIN32)
# Copy required CL include directories into the build directory
# as required for the compiler testing.
# ... For running the compiler test on the command line.
file(COPY "${CLConform_SOURCE_DIR}/test_conformance/compiler/includeTestDirectory" DESTINATION ${DST_DIR})
file(COPY "${CLConform_SOURCE_DIR}/test_conformance/compiler/secondIncludeTestDirectory" DESTINATION ${DST_DIR})
# ... For running the compiler test with VisualStudio.
if(MSVC)
file(COPY "${CLConform_SOURCE_DIR}/test_conformance/compiler/includeTestDirectory" DESTINATION "${CLConform_SOURCE_DIR}/build/test_conformance/compiler")
file(COPY "${CLConform_SOURCE_DIR}/test_conformance/compiler/secondIncludeTestDirectory" DESTINATION "${CLConform_SOURCE_DIR}/build/test_conformance/compiler")
endif(MSVC)
set_property(TARGET COPY_FILES${CONFORMANCE_SUFFIX} PROPERTY FOLDER "CONFORMANCE${CONFORMANCE_SUFFIX}")

View File

@@ -108,7 +108,9 @@ def install_android_cmake():
print "input: "
if get_input():
print("installing android-cmake")
subprocess.call(['git', 'clone', 'https://github.com/taka-no-me/android-cmake'])
#subprocess.call(['git', 'clone', 'https://github.com/taka-no-me/android-cmake'])
# Use a newer fork of android-cmake which has been updated to support Clang. GCC is deprecated in newer NDKs and C11 atomics conformance doesn't build with NDK > 10.
subprocess.call(['git', 'clone', 'https://github.com/daewoong-jang/android-cmake'])
args.android_cmake = os.path.join(args.src_dir,"android-cmake")
else:
exit()

View File

@@ -2,5 +2,11 @@
mkdir -p build_lnx
cd build_lnx
cmake -g "Unix Makefiles" ../ -DCL_OFFLINE_COMPILER=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
cmake -G "Unix Makefiles" ../ \
-DKHRONOS_OFFLINE_COMPILER=<TO_SET> \
-DCL_LIBCLCXX_DIR=<TO_SET> \
-DCL_INCLUDE_DIR=<TO_SET> \
-DCL_LIB_DIR=<TO_SET> \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. \
-DOPENCL_LIBRARIES=OpenCL
make --jobs 8

View File

@@ -20,7 +20,7 @@ mkdir build_win
pushd build_win
IF NOT EXIST CLConform.sln (
echo "Solution file not found, running Cmake"
cmake -G "Visual Studio 14 2015 Win64" ..\. -DCL_OFFLINE_COMPILER=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
cmake -G "Visual Studio 14 2015 Win64" ..\. -DKHRONOS_OFFLINE_COMPILER=<TO_SET> -DCL_LIBCLCXX_DIR=<TO_SET> -DCL_INCLUDE_DIR=<TO_SET> -DCL_LIB_DIR=<TO_SET> -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=. -DOPENCL_LIBRARIES=OpenCL
) else (
echo "Solution file found CLConform.sln "
)

19
check-format.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# Arg used to specify non-'origin/master' comparison branch
ORIGIN_BRANCH=${1:-"origin/master"}
# Run git-clang-format to check for violations
if [ "$TRAVIS" == "true" ]; then
EXTRA_OPTS="--binary `which clang-format-9`"
fi
CLANG_FORMAT_OUTPUT=$(git-clang-format --diff $ORIGIN_BRANCH --extensions c,cpp,h,hpp $EXTRA_OPTS)
# Check for no-ops
grep '^no modified files to format$' <<<"$CLANG_FORMAT_OUTPUT" && exit 0
grep '^clang-format did not modify any files$' <<<"$CLANG_FORMAT_OUTPUT" && exit 0
# Dump formatting diff and signal failure
echo -e "\n==== FORMATTING VIOLATIONS DETECTED ====\n"
echo "$CLANG_FORMAT_OUTPUT"
exit 1

View File

@@ -1,104 +0,0 @@
#!/usr/bin/python
import sys, os, re
from subprocess import Popen, PIPE
from optparse import OptionParser
# trail_spaces: This method removes the trailing whitespaces and trailing tabs
def trail_spaces(line):
newline=line
carreturn = 0
if re.search("\r\n",line):
carreturn = 1
status = re.search("\s+$",line)
if status:
if carreturn:
newline = re.sub("\s+$","\r\n",line)
else:
newline = re.sub("\s+$","\n",line)
status = re.search("\t+$",newline)
if status:
newline = re.sub("\t+$","",newline)
return newline
#convert_tabs: This methos converts tabs to 4 spaces
def convert_tabs(line):
newline=line
status = re.search("\t",line)
if status:
newline = re.sub("\t"," ",line)
return newline
#convert_lineends: This method converts lineendings from DOS to Unix
def convert_lineends(line):
newline=line
status = re.search("\r\n",line)
if status:
newline = re.sub("\r\n","\n",line)
return newline
#processfile: This method processes each file passed to it depending
# on the flags passed
def processfile(file,tabs, lineends,trails,verbose):
processed_data = []
if verbose:
print "processing file: "+file
with open(file,'r') as fr:
data = fr.readlines()
for line in data:
if tabs:
line = convert_tabs(line)
if lineends:
line = convert_lineends(line)
if trails:
line = trail_spaces(line)
processed_data.append(line)
with open(file,'w') as fw:
fw.writelines(processed_data)
#findfiles: This method finds all the code files present in current
# directory and subdirectories.
def findfiles(tabs,lineends,trails,verbose):
testfiles = []
for root, dirs, files in os.walk("./"):
for file in files:
for extn in ('.c','.cpp','.h','.hpp'):
if file.endswith(extn):
testfiles.append(os.path.join(root, file))
for file in testfiles:
processfile(file,tabs,lineends,trails,verbose)
# Main function
def main():
parser = OptionParser()
parser.add_option("--notabs", dest="tabs", action="store_false", default=True, help="Disable converting tabs to 4 spaces.")
parser.add_option("--notrails", dest="trails", action="store_false", default=True, help="Disable removing trailing whitespaces and trailing tabs.")
parser.add_option("--nolineends", dest="lineends", action="store_false", default=True, help=" Disable converting line endings to Unix from DOS.")
parser.add_option("--verbose", dest="verbose", action="store_true", default=False, help="Prints out the files being processed.")
parser.add_option("--git", dest="SHA1", default="", help="Processes only the files present in the particular <SHA1> commit.")
parser.add_option('-o', action="store", default=True, help="Default: All the code files (.c,.cpp,.h,.hpp) in the current directory and subdirectories will be processed")
(options, args) = parser.parse_args()
if options.SHA1:
pl = Popen(["git","show", "--pretty=format:", "--name-only",options.SHA1], stdout=PIPE)
cmdout = pl.communicate()[0]
gitout=cmdout.split("\n")
for file in gitout:
print file
if file:
processfile(file,options.tabs,options.lineends,options.trails,options.verbose)
if not options.SHA1:
findfiles(options.tabs,options.lineends,options.trails,options.verbose)
# start the process by calling main
main()

View File

@@ -1,7 +1,6 @@
To run the 2.2 conformance tests test suite for the C++ features you need
SPIR-V binaries.
To run the conformance tests you need SPIR-V binaries.
If you are using a conformance package then the binaries are included in the
If you are using a conformance package then the binaries are included in the
package. If you are using conformance tests from gitlab repositories then the
binaries need to be picked up from Khronos SVN URL mentioned below:
@@ -39,4 +38,4 @@ Branch: opencl22
5. OpenCL ICD (with 2.2 support)
OpenCL ICD
Repository: https://gitlab.khronos.org/opencl/icd
Branch: dev_cl22
Branch: dev_cl22

View File

@@ -0,0 +1,24 @@
set(HARNESS_SOURCES
harness/threadTesting.cpp
harness/typeWrappers.cpp
harness/mt19937.cpp
harness/conversions.cpp
harness/rounding_mode.cpp
harness/msvc9.c
harness/crc32.cpp
harness/errorHelpers.cpp
harness/genericThread.cpp
harness/imageHelpers.cpp
harness/kernelHelpers.cpp
harness/deviceInfo.cpp
harness/os_helpers.cpp
harness/parseParameters.cpp
harness/propertyHelpers.cpp
harness/testHarness.cpp
harness/ThreadPool.cpp
miniz/miniz.c
)
add_library(harness STATIC ${HARNESS_SOURCES})

View File

@@ -51,7 +51,7 @@ struct test_case_registration
{
test_case_registration(const std::string& name, const basefn ptr)
{
::autotest::test_suite::global_test_suite().add(test_definition({ptr, name.c_str()}));
::autotest::test_suite::global_test_suite().add(test_definition({ptr, strdup(name.c_str())}));
}
};

View File

@@ -37,9 +37,8 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
#else
#include <GL/glew.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glext.h>
#endif
#ifdef _WIN32
#include <GL/glut.h>

View File

@@ -14,11 +14,7 @@
// limitations under the License.
//
#include "helpers.h"
#include "../harness/imageHelpers.h"
// convert_float_to_half and convert_half_to_float may be found in test_conformance/images/image_helpers.cpp
cl_ushort convert_float_to_half( cl_float f );
cl_float convert_half_to_float( cl_ushort h );
#include "harness/imageHelpers.h"
#if defined( __APPLE__ )
#include <OpenGL/glu.h>

View File

@@ -32,12 +32,12 @@
#include "gl_headers.h"
#endif
#include "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/threadTesting.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/conversions.h"
#include "../../test_common/harness/mt19937.h"
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/threadTesting.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
#include "harness/mt19937.h"
typedef cl_mem
(CL_API_CALL *clCreateFromGLBuffer_fn)(cl_context context,

View File

@@ -14,7 +14,7 @@
// limitations under the License.
//
#include "setup.h"
#include "../../test_common/harness/errorHelpers.h"
#include "harness/errorHelpers.h"
#include <OpenGL/CGLDevice.h>
class OSXGLEnvironment : public GLEnvironment
@@ -92,16 +92,9 @@ class OSXGLEnvironment : public GLEnvironment
return NULL;
}
char extensions[8192];
for (int i=0; i<(int)(size_out/sizeof(cl_device_id)); i++) {
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
if (error) {
print_error(error, "clGetDeviceInfo failed");
return NULL;
}
if (strstr(extensions, "cl_APPLE_gl_sharing") == NULL) {
log_error("Device %d does not supporte required extension cl_APPLE_gl_sharing.\n", i);
if (!is_extension_available(devices[i], "cl_APPLE_gl_sharing")) {
log_error("Device %d does not support required extension cl_APPLE_gl_sharing.\n", i);
return NULL;
}
}
@@ -120,15 +113,8 @@ class OSXGLEnvironment : public GLEnvironment
return -1;
}
char extensions[8192];
for (int i=0; i<(int)num_of_devices; i++) {
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
if (error) {
print_error(error, "clGetDeviceInfo failed");
return -1;
}
if (strstr(extensions, "cl_APPLE_gl_sharing") == NULL) {
if (!is_extension_available(devices[i], "cl_APPLE_gl_sharing")) {
log_info("Device %d of %d does not support required extension cl_APPLE_gl_sharing.\n", i, num_of_devices);
} else {
log_info("Device %d of %d does support required extension cl_APPLE_gl_sharing.\n", i, num_of_devices);

View File

@@ -17,12 +17,10 @@
#include "setup.h"
#include "testBase.h"
#include "../../test_common/harness/errorHelpers.h"
#include "harness/errorHelpers.h"
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include <GL/glut.h>
#include <CL/cl_ext.h>
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(
@@ -177,15 +175,8 @@ public:
}
// Check all devices, search for one that supports cl_khr_gl_sharing
char extensions[8192];
for (int i=0; i<(int)num_of_devices; i++) {
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
if (error) {
print_error(error, "clGetDeviceInfo failed");
return -1;
}
if (strstr(extensions, "cl_khr_gl_sharing") == NULL) {
if (!is_extension_available(devices[i], "cl_khr_gl_sharing")) {
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
} else {
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);

View File

@@ -17,7 +17,7 @@
#include "setup.h"
#include "testBase.h"
#include "../../test_common/harness/errorHelpers.h"
#include "harness/errorHelpers.h"
#include <GL/gl.h>
#include <GL/glut.h>
@@ -89,15 +89,8 @@ public:
return -1;
}
char extensions[8192];
for (int i=0; i<(int)num_of_devices; i++) {
error = clGetDeviceInfo(devices[i], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL);
if (error) {
print_error(error, "clGetDeviceInfo failed");
return -1;
}
if (strstr(extensions, "cl_khr_gl_sharing ") == NULL) {
if (!is_extension_available(devices[i], "cl_khr_gl_sharing ")) {
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
} else {
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);

View File

@@ -961,49 +961,6 @@ const char *GetGLFormatName( GLenum format )
}
}
cl_ushort float2half_rte( float f )
{
union{ float f; cl_uint u; } u = {f};
cl_uint sign = (u.u >> 16) & 0x8000;
float x = fabsf(f);
//Nan
if( x != x )
{
u.u >>= (24-11);
u.u &= 0x7fff;
u.u |= 0x0200; //silence the NaN
return u.u | sign;
}
// overflow
if( x >= MAKE_HEX_FLOAT(0x1.ffep15f, 0x1ffeL, 3) )
return 0x7c00 | sign;
// underflow
if( x <= MAKE_HEX_FLOAT(0x1.0p-25f, 0x1L, -25) )
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
// very small
if( x < MAKE_HEX_FLOAT(0x1.8p-24f, 0x18L, -28) )
return sign | 1;
// half denormal
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
{
u.f = x * MAKE_HEX_FLOAT(0x1.0p-125f, 0x1L, -125);
return sign | u.u;
}
u.f *= MAKE_HEX_FLOAT(0x1.0p13f, 0x1L, 13);
u.u &= 0x7f800000;
x += u.f;
u.f = x - u.f;
u.f *= MAKE_HEX_FLOAT(0x1.0p-112f, 0x1L, -112);
return (u.u >> (24-11)) | sign;
}
void* CreateRandomData( ExplicitType type, size_t count, MTdata d )
{
switch(type)
@@ -1100,7 +1057,8 @@ void* CreateRandomData( ExplicitType type, size_t count, MTdata d )
for( size_t i = 0; i < count; i++ )
{
p[ i ] = float2half_rte(get_random_float( 0.f, 1.f, d ));
p[i] = cl_half_from_float(get_random_float(0.f, 1.f, d),
CL_HALF_RTE);
}
return (void*)p;

View File

@@ -36,12 +36,12 @@
#include "gl_headers.h"
#endif
#include "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/threadTesting.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/conversions.h"
#include "../../test_common/harness/mt19937.h"
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/threadTesting.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
#include "harness/mt19937.h"
typedef cl_mem
(CL_API_CALL *clCreateFromGLBuffer_fn)(cl_context context,

View File

@@ -371,8 +371,7 @@ void *ThreadPool_WorkerFunc( void *p )
{
#if (__MINGW32__)
EnterCriticalSection(&gAtomicLock);
if( jobError == CL_SUCCESS );
jobError = err;
if (jobError == CL_SUCCESS) jobError = err;
gRunCount = 0;
LeaveCriticalSection(&gAtomicLock);
#elif defined( __GNUC__ )
@@ -393,8 +392,7 @@ void *ThreadPool_WorkerFunc( void *p )
#else
if( pthread_mutex_lock(&gAtomicLock) )
log_error( "Atomic operation failed. pthread_mutex_lock(&gAtomicLock) returned an error\n");
if( jobError == CL_SUCCESS );
jobError = err;
if (jobError == CL_SUCCESS) jobError = err;
gRunCount = 0;
if( pthread_mutex_unlock(&gAtomicLock) )
log_error( "Failed to release gAtomicLock. Further atomic operations may deadlock\n");
@@ -446,6 +444,7 @@ void ThreadPool_Init(void)
// Check for manual override of multithreading code. We add this for better debuggability.
if( getenv( "CL_TEST_SINGLE_THREADED" ) )
{
log_error("ERROR: CL_TEST_SINGLE_THREADED is set in the environment. Running single threaded.\n*** TEST IS INVALID! ***\n");
gThreadCount = 1;
return;
}

View File

@@ -22,10 +22,6 @@
#include <CL/cl.h>
#endif
#if defined(__cplusplus)
extern "C" {
#endif
//
// An atomic add operator
cl_int ThreadPool_AtomicAdd( volatile cl_int *a, cl_int b ); // returns old value
@@ -68,9 +64,5 @@ cl_uint GetThreadCount( void );
// otherwise the behavior is indefined. It may not be called from a TPFuncPtr.
void SetThreadCount( int count );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* THREAD_POOL_H */

View File

@@ -0,0 +1,71 @@
//
// Copyright (c) 2020 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 HARNESS_ALLOC_H_
#define HARNESS_ALLOC_H_
#if defined(__linux__) || defined (linux) || defined(__APPLE__)
#if defined(__ANDROID__)
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#endif
#if defined(__MINGW32__)
#include "mingw_compat.h"
#endif
static void * align_malloc(size_t size, size_t alignment)
{
#if defined(_WIN32) && defined(_MSC_VER)
return _aligned_malloc(size, alignment);
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
void * ptr = NULL;
#if defined(__ANDROID__)
ptr = memalign(alignment, size);
if ( ptr )
return ptr;
#else
if (alignment < sizeof(void*)) {
alignment = sizeof(void*);
}
if (0 == posix_memalign(&ptr, alignment, size))
return ptr;
#endif
return NULL;
#elif defined(__MINGW32__)
return __mingw_aligned_malloc(size, alignment);
#else
#error "Please add support OS for aligned malloc"
#endif
}
static void align_free(void * ptr)
{
#if defined(_WIN32) && defined(_MSC_VER)
_aligned_free(ptr);
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
return free(ptr);
#elif defined(__MINGW32__)
return __mingw_aligned_free(ptr);
#else
#error "Please add support OS for aligned free"
#endif
}
#endif // #ifndef HARNESS_ALLOC_H_

View File

@@ -25,10 +25,6 @@
#include <stdio.h>
#include "errorHelpers.h"
#ifdef __cplusplus
extern "C" {
#endif
// helper function to replace clCreateImage2D , to make the existing code use
// the functions of version 1.2 and veriosn 1.1 respectively
@@ -46,7 +42,7 @@ extern "C" {
#ifdef CL_VERSION_1_2
cl_image_desc image_desc_dest;
image_desc_dest.image_type = CL_MEM_OBJECT_IMAGE2D;;
image_desc_dest.image_type = CL_MEM_OBJECT_IMAGE2D;
image_desc_dest.image_width = image_width;
image_desc_dest.image_height = image_height;
image_desc_dest.image_depth= 0;// not usedfor 2d
@@ -90,7 +86,7 @@ extern "C" {
cl_mem mImage = NULL;
cl_image_desc image_desc_dest;
image_desc_dest.image_type = CL_MEM_OBJECT_IMAGE2D;;
image_desc_dest.image_type = CL_MEM_OBJECT_IMAGE2D;
image_desc_dest.image_width = image_width;
image_desc_dest.image_height = image_height;
image_desc_dest.image_depth= 0;// not usedfor 2d
@@ -283,8 +279,4 @@ extern "C" {
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,27 @@
The cl_offline_compiler program used for offline compilation must
implement the following interface.
usage: cl_offline_compiler --source FILE --output FILE
--cl-device-info FILE --mode MODE
-- [BUILD_OPTIONS [BUILD_OPTIONS ...]]
positional arguments:
BUILD_OPTIONS additional options to pass to the compiler
optional arguments:
--source FILE OpenCL C source file to compile
--output FILE SPIR-V or binary file to create
--cl-device-info FILE OpenCL device info file
--mode compilation mode (spir-v or binary)
The --cl-device-info file is a list of KEY=VALUE pairs containing device
information relevant to the mode of offline compilation in question.
It is of the following form:
# OpenCL device info affecting <SPIR-V|binary> offline compilation:
CL_DEVICE_ADDRESS_BITS=<32|64>
CL_DEVICE_EXTENSIONS="<space separated list of CL extensions>"
CL_DEVICE_IL_VERSION="<space separated list of IL versions>"
CL_DEVICE_VERSION="OpenCL <version> <vendor info>"
CL_DEVICE_IMAGE_SUPPORT=<0|1>
CL_DEVICE_NAME="device name"

View File

@@ -117,112 +117,117 @@ typedef long long int64_t;
#include <math.h>
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#if defined( _MSC_VER )
#ifdef __cplusplus
extern "C" {
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
#ifndef NAN
#define NAN (INFINITY - INFINITY)
#endif
#if ! defined( __INTEL_COMPILER )
#ifndef HUGE_VALF
#define HUGE_VALF (float)HUGE_VAL
#endif
#ifndef NAN
#define NAN (INFINITY - INFINITY)
#endif
#ifndef HUGE_VALF
#define HUGE_VALF (float)HUGE_VAL
#endif
#ifndef INFINITY
#define INFINITY (FLT_MAX + FLT_MAX)
#endif
#ifndef isfinite
#define isfinite(x) _finite(x)
#endif
#ifndef isnan
#define isnan( x ) ((x) != (x))
#endif
#ifndef isinf
#define isinf( _x) ((_x) == INFINITY || (_x) == -INFINITY)
#endif
#ifndef INFINITY
#define INFINITY (FLT_MAX + FLT_MAX)
#endif
double rint( double x);
float rintf( float x);
long double rintl( long double x);
#ifndef isfinite
#define isfinite(x) _finite(x)
#endif
float cbrtf( float );
double cbrt( double );
#ifndef isnan
#define isnan( x ) ((x) != (x))
#endif
int ilogb( double x);
int ilogbf (float x);
int ilogbl(long double x);
#ifndef isinf
#define isinf( _x) ((_x) == INFINITY || (_x) == -INFINITY)
#endif
#if _MSC_VER < 1900 && ! defined( __INTEL_COMPILER )
double fmax(double x, double y);
double fmin(double x, double y);
float fmaxf( float x, float y );
float fminf(float x, float y);
double rint( double x);
float rintf( float x);
long double rintl( long double x);
double log2(double x);
long double log2l(long double x);
float cbrtf( float );
double cbrt( double );
double exp2(double x);
long double exp2l(long double x);
int ilogb( double x);
int ilogbf (float x);
int ilogbl(long double x);
double fdim(double x, double y);
float fdimf(float x, float y);
long double fdiml(long double x, long double y);
double fmax(double x, double y);
double fmin(double x, double y);
float fmaxf( float x, float y );
float fminf(float x, float y);
double remquo( double x, double y, int *quo);
float remquof( float x, float y, int *quo);
long double remquol( long double x, long double y, int *quo);
double log2(double x);
long double log2l(long double x);
long double scalblnl(long double x, long n);
double exp2(double x);
long double exp2l(long double x);
float hypotf(float x, float y);
long double hypotl(long double x, long double y) ;
double lgamma(double x);
float lgammaf(float x);
double fdim(double x, double y);
float fdimf(float x, float y);
long double fdiml(long double x, long double y);
double trunc(double x);
float truncf(float x);
double remquo( double x, double y, int *quo);
float remquof( float x, float y, int *quo);
long double remquol( long double x, long double y, int *quo);
double log1p(double x);
float log1pf(float x);
long double log1pl(long double x);
long double scalblnl(long double x, long n);
double copysign(double x, double y);
float copysignf(float x, float y);
long double copysignl(long double x, long double y);
float hypotf(float x, float y);
long double hypotl(long double x, long double y) ;
double lgamma(double x);
float lgammaf(float x);
long lround(double x);
long lroundf(float x);
//long lroundl(long double x)
double trunc(double x);
float truncf(float x);
double round(double x);
float roundf(float x);
long double roundl(long double x);
double log1p(double x);
float log1pf(float x);
long double log1pl(long double x);
double copysign(double x, double y);
float copysignf(float x, float y);
long double copysignl(long double x, long double y);
long lround(double x);
long lroundf(float x);
//long lroundl(long double x)
double round(double x);
float roundf(float x);
long double roundl(long double x);
int cf_signbit(double x);
int cf_signbitf(float x);
// Added in _MSC_VER == 1800 (Visual Studio 2013)
#if _MSC_VER < 1800
static int signbit(double x) { return cf_signbit(x); }
#endif
// Added in _MSC_VER == 1800 (Visual Studio 2013)
#if _MSC_VER < 1800
static int signbit(double x) { return cf_signbit(x); }
#endif
static int signbitf(float x) { return cf_signbitf(x); }
long int lrint (double flt);
long int lrintf (float flt);
long int lrint (double flt);
long int lrintf (float flt);
float int2float (int32_t ix);
int32_t float2int (float fx);
float int2float (int32_t ix);
int32_t float2int (float fx);
#endif
#endif // _MSC_VER < 1900 && ! defined( __INTEL_COMPILER )
#if ! defined( __INTEL_COMPILER ) || __INTEL_COMPILER < 1300
// These functions appeared in Intel C v13.
#if _MSC_VER < 1900 && ( ! defined( __INTEL_COMPILER ) || __INTEL_COMPILER < 1300 )
// These functions appeared in Intel C v13 and Visual Studio 2015
float nanf( const char* str);
double nan( const char* str);
long double nanl( const char* str);
@@ -253,6 +258,16 @@ int32_t float2int (float fx);
//
// string.h
//
#if defined(_MSC_VER)
#define strtok_r strtok_s
#endif
//
// unistd.h
//

View File

@@ -25,10 +25,6 @@
#include <string.h>
#include <sys/types.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Note: the next three all have to match in size and order!! */
enum ExplicitTypes
@@ -117,9 +113,11 @@ static inline int IsDoubleSubnormal( double x )
#endif
}
#if defined(__cplusplus)
static inline int IsHalfSubnormal( cl_half x )
{
// this relies on interger overflow to exclude 0 as a subnormal
return ( ( x & 0x7fffU ) - 1U ) < 0x03ffU;
}
#endif
#endif // _conversions_h

View File

@@ -1,104 +0,0 @@
/*-
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*
* First, the polynomial itself and its table of feedback terms. The
* polynomial is
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
*
* Note that we take it "backwards" and put the highest-order term in
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
* the MSB being 1
*
* Note that the usual hardware shift register implementation, which
* is what we're using (we're merely optimizing it by doing eight-bit
* chunks at a time) shifts bits into the lowest-order term. In our
* implementation, that means shifting towards the right. Why do we
* do it this way? Because the calculated CRC must be transmitted in
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to hight-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly
*
* The feedback terms table consists of 256, 32-bit entries. Notes
*
* The table can be generated at runtime if desired; code to do so
* is shown later. It might not be obvious, but the feedback
* terms simply represent the results of eight shift/xor opera
* tions for all combinations of data and CRC register values
*
* The values must be right-shifted by eight bits by the "updcrc
* logic; the shift must be unsigned (bring in zeroes). On some
* hardware you could probably optimize the shift in assembler by
* using byte-swap instructions
* polynomial $edb88320
*
*
* CRC32 code derived from work by Gary S. Brown.
*/
#include "crc32.h"
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t
crc32(const void *buf, size_t size)
{
const uint8_t *p;
p = (const uint8_t*)buf;
uint32_t crc = ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}

View File

@@ -0,0 +1,101 @@
/*-
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*
* First, the polynomial itself and its table of feedback terms. The
* polynomial is
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
*
* Note that we take it "backwards" and put the highest-order term in
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
* the MSB being 1
*
* Note that the usual hardware shift register implementation, which
* is what we're using (we're merely optimizing it by doing eight-bit
* chunks at a time) shifts bits into the lowest-order term. In our
* implementation, that means shifting towards the right. Why do we
* do it this way? Because the calculated CRC must be transmitted in
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to hight-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly
*
* The feedback terms table consists of 256, 32-bit entries. Notes
*
* The table can be generated at runtime if desired; code to do so
* is shown later. It might not be obvious, but the feedback
* terms simply represent the results of eight shift/xor opera
* tions for all combinations of data and CRC register values
*
* The values must be right-shifted by eight bits by the "updcrc
* logic; the shift must be unsigned (bring in zeroes). On some
* hardware you could probably optimize the shift in assembler by
* using byte-swap instructions
* polynomial $edb88320
*
*
* CRC32 code derived from work by Gary S. Brown.
*/
#include "crc32.h"
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t crc32(const void *buf, size_t size)
{
const uint8_t *p;
p = (const uint8_t *)buf;
uint32_t crc = ~0U;
while (size--) crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}

View File

@@ -21,14 +21,6 @@ executed between Khronos and the recipient.
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
uint32_t crc32(const void *buf, size_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,88 @@
//
// Copyright (c) 2017-2019 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 <sstream>
#include <stdexcept>
#include <vector>
#include "deviceInfo.h"
#include "errorHelpers.h"
#include "typeWrappers.h"
/* Helper to return a string containing device information for the specified
* device info parameter. */
static std::string get_device_info_string(cl_device_id device,
cl_device_info param_name)
{
size_t size = 0;
int err;
if ((err = clGetDeviceInfo(device, param_name, 0, NULL, &size))
!= CL_SUCCESS
|| size == 0)
{
throw std::runtime_error("clGetDeviceInfo failed\n");
}
std::vector<char> info(size);
if ((err = clGetDeviceInfo(device, param_name, size, info.data(), NULL))
!= CL_SUCCESS)
{
throw std::runtime_error("clGetDeviceInfo failed\n");
}
/* The returned string does not include the null terminator. */
return std::string(info.data(), size - 1);
}
/* Determines if an extension is supported by a device. */
int is_extension_available(cl_device_id device, const char *extensionName)
{
std::string extString = get_device_extensions_string(device);
std::istringstream ss(extString);
while (ss)
{
std::string found;
ss >> found;
if (found == extensionName) return true;
}
return false;
}
/* Returns a string containing the supported extensions list for a device. */
std::string get_device_extensions_string(cl_device_id device)
{
return get_device_info_string(device, CL_DEVICE_EXTENSIONS);
}
/* Returns a string containing the supported IL version(s) for a device. */
std::string get_device_il_version_string(cl_device_id device)
{
return get_device_info_string(device, CL_DEVICE_IL_VERSION);
}
/* Returns a string containing the supported OpenCL version for a device. */
std::string get_device_version_string(cl_device_id device)
{
return get_device_info_string(device, CL_DEVICE_VERSION);
}
/* Returns a string containing the device name. */
std::string get_device_name(cl_device_id device)
{
return get_device_info_string(device, CL_DEVICE_NAME);
}

View File

@@ -0,0 +1,40 @@
//
// Copyright (c) 2017-2019 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 _deviceInfo_h
#define _deviceInfo_h
// Configuration
#include "../config.hpp"
#include <string>
#include <CL/opencl.h>
/* Determines if an extension is supported by a device. */
int is_extension_available(cl_device_id device, const char *extensionName);
/* Returns a string containing the supported extensions list for a device. */
std::string get_device_extensions_string(cl_device_id device);
/* Returns a string containing the supported IL version(s) for a device. */
std::string get_device_il_version_string(cl_device_id device);
/* Returns a string containing the supported OpenCL version for a device. */
std::string get_device_version_string(cl_device_id device);
/* Returns a string containing the device name. */
std::string get_device_name(cl_device_id device);
#endif // _deviceInfo_h

View File

@@ -20,7 +20,9 @@
#include "errorHelpers.h"
extern bool gOfflineCompiler;
#include "parseParameters.h"
#include <CL/cl_half.h>
const char *IGetErrorString( int clErrorCode )
{
@@ -83,7 +85,13 @@ const char *IGetErrorString( int clErrorCode )
case CL_INVALID_IMAGE_DESCRIPTOR: return "CL_INVALID_IMAGE_DESCRIPTOR";
case CL_INVALID_COMPILER_OPTIONS: return "CL_INVALID_COMPILER_OPTIONS";
case CL_INVALID_LINKER_OPTIONS: return "CL_INVALID_LINKER_OPTIONS";
case CL_INVALID_DEVICE_PARTITION_COUNT: return "CL_INVALID_DEVICE_PARTITION_COUNT";
case CL_INVALID_DEVICE_PARTITION_COUNT:
return "CL_INVALID_DEVICE_PARTITION_COUNT";
case CL_INVALID_PIPE_SIZE: return "CL_INVALID_PIPE_SIZE";
case CL_INVALID_DEVICE_QUEUE: return "CL_INVALID_DEVICE_QUEUE";
case CL_INVALID_SPEC_ID: return "CL_INVALID_SPEC_ID";
case CL_MAX_SIZE_RESTRICTION_EXCEEDED:
return "CL_MAX_SIZE_RESTRICTION_EXCEEDED";
default: return "(unknown)";
}
}
@@ -276,6 +284,19 @@ const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSi
return buffer;
}
const char *GetQueuePropertyName(cl_command_queue_properties property)
{
switch (property)
{
case CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE:
return "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE";
case CL_QUEUE_PROFILING_ENABLE: return "CL_QUEUE_PROFILING_ENABLE";
case CL_QUEUE_ON_DEVICE: return "CL_QUEUE_ON_DEVICE";
case CL_QUEUE_ON_DEVICE_DEFAULT: return "CL_QUEUE_ON_DEVICE_DEFAULT";
default: return "(unknown)";
}
}
#ifndef MAX
#define MAX( _a, _b ) ((_a) > (_b) ? (_a) : (_b))
#endif
@@ -287,7 +308,6 @@ const char *GetDataVectorString( void *dataBuffer, size_t typeSize, size_t vecSi
#endif
static float Ulp_Error_Half_Float( float test, double reference );
static inline float half2float( cl_ushort half );
// taken from math tests
#define HALF_MIN_EXP -13
@@ -334,49 +354,9 @@ static float Ulp_Error_Half_Float( float test, double reference )
return (float) scalbn( testVal - reference, ulp_exp );
}
// Taken from vLoadHalf test
static inline float half2float( cl_ushort us )
{
uint32_t u = us;
uint32_t sign = (u << 16) & 0x80000000;
int32_t exponent = (u & 0x7c00) >> 10;
uint32_t mantissa = (u & 0x03ff) << 13;
union{ unsigned int u; float f;}uu;
if( exponent == 0 )
{
if( mantissa == 0 )
return sign ? -0.0f : 0.0f;
int shift = __builtin_clz( mantissa ) - 8;
exponent -= shift-1;
mantissa <<= shift;
mantissa &= 0x007fffff;
}
else
if( exponent == 31)
{
uu.u = mantissa | sign;
if( mantissa )
uu.u |= 0x7fc00000;
else
uu.u |= 0x7f800000;
return uu.f;
}
exponent += 127 - 15;
exponent <<= 23;
exponent |= mantissa;
uu.u = exponent | sign;
return uu.f;
}
float Ulp_Error_Half( cl_ushort test, float reference )
{
return Ulp_Error_Half_Float( half2float(test), reference );
return Ulp_Error_Half_Float(cl_half_to_float(test), reference);
}
@@ -707,100 +687,69 @@ const char * subtests_requiring_opencl_1_2[] = {
"popcount"
};
const char * subtests_to_skip_with_offline_compiler[] = {
"get_kernel_arg_info",
"binary_create",
"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",
"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_extern_compile_only",
"simple_embedded_header_compile",
"two_file_regular_variable_access",
"two_file_regular_struct_access",
"two_file_regular_function_access",
"simple_embedded_header_link",
"execute_after_simple_compile_and_link_with_defines",
"execute_after_simple_compile_and_link_with_callbacks",
"execute_after_embedded_header_link",
"execute_after_included_header_link",
"multi_file_libraries",
"multiple_files",
"multiple_libraries",
"multiple_files_multiple_libraries",
"multiple_embedded_headers",
"program_binary_type",
"compile_and_link_status_options_log",
"kernel_preprocessor_macros",
const char *subtests_to_skip_with_offline_compiler[] = {
"get_kernel_arg_info",
"get_kernel_arg_info_compatibility",
"binary_create",
"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",
"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_extern_compile_only",
"simple_embedded_header_compile",
"two_file_regular_variable_access",
"two_file_regular_struct_access",
"two_file_regular_function_access",
"simple_embedded_header_link",
"execute_after_simple_compile_and_link_with_defines",
"execute_after_simple_compile_and_link_with_callbacks",
"execute_after_embedded_header_link",
"execute_after_included_header_link",
"multi_file_libraries",
"multiple_files",
"multiple_libraries",
"multiple_files_multiple_libraries",
"multiple_embedded_headers",
"program_binary_type",
"compile_and_link_status_options_log",
"kernel_preprocessor_macros",
"execute_after_serialize_reload_library",
"execute_after_serialize_reload_object",
"execute_after_simple_compile_and_link",
"execute_after_simple_compile_and_link_no_device_info",
"execute_after_simple_library_with_link",
"execute_after_two_file_link",
"simple_compile_only",
"simple_compile_with_callback",
"simple_library_only",
"simple_library_with_callback",
"simple_library_with_link",
"simple_link_only",
"simple_link_with_callback",
"simple_static_compile_only",
"two_file_link",
"async_build",
};
int check_opencl_version_with_testname(const char *subtestname, cl_device_id device)
{
int nRequiring12 = sizeof(subtests_requiring_opencl_1_2)/sizeof(char *);
size_t i;
for(i=0; i < nRequiring12; ++i) {
if(!strcmp(subtestname, subtests_requiring_opencl_1_2[i])) {
return check_opencl_version(device, 1, 2);
}
}
return 0;
}
int check_opencl_version(cl_device_id device, cl_uint requestedMajorVersion, cl_uint requestedMinorVersion) {
int error;
char device_version[1024];
cl_uint majorVersion = 0, minorVersion = 0;
const char * required_version_ocl_12="OpenCL 1.2 ";
memset( device_version, 0, sizeof( device_version ) );
error = clGetDeviceInfo( device, CL_DEVICE_VERSION, sizeof(device_version), device_version, NULL );
test_error(error, "unable to get CL_DEVICE_VERSION");
if ( strncmp( device_version, "OpenCL 1.2", 10 ) == 0 && ( device_version[ 10 ] == 0 || device_version[ 10 ] == ' ' ) ) {
majorVersion = 1;
minorVersion = 2;
} else if ( strncmp( device_version, "OpenCL 1.1", 10 ) == 0 && ( device_version[ 10 ] == 0 || device_version[ 10 ] == ' ' ) ) {
majorVersion = 1;
minorVersion = 1;
} else if ( strncmp( device_version, "OpenCL 2.0", 10 ) == 0 && ( device_version[ 10 ] == 0 || device_version[ 10 ] == ' ' ) ) {
majorVersion = 2;
minorVersion = 0;
} else if ( strncmp( device_version, "OpenCL 2.1", 10 ) == 0 && ( device_version[ 10 ] == 0 || device_version[ 10 ] == ' ' ) ) {
majorVersion = 2;
minorVersion = 1;
} else {
log_error( "ERROR: Unexpected version string: `%s'.\n", device_version );
return 1;
};
if (majorVersion >= requestedMajorVersion)
return 0;
if (minorVersion >= requestedMinorVersion)
return 0;
return 1;
}
int check_functions_for_offline_compiler(const char *subtestname, cl_device_id device)
{
if(gOfflineCompiler)
if (gCompilationMode != kOnline)
{
int nNotRequiredWithOfflineCompiler = sizeof(subtests_to_skip_with_offline_compiler)/sizeof(char *);
size_t i;

View File

@@ -16,66 +16,51 @@
#ifndef _errorHelpers_h
#define _errorHelpers_h
#include <sstream>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/opencl.h>
#endif
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#define LOWER_IS_BETTER 0
#define HIGHER_IS_BETTER 1
// If USE_ATF is defined, all log_error and log_info calls can be routed to test library
// functions as described below. This is helpful for integration into an automated testing
// system.
#if USE_ATF
// export BUILD_WITH_ATF=1
#include <ATF/ATF.h>
#define test_start() ATFTestStart()
#define log_info ATFLogInfo
#define log_error ATFLogError
#define log_missing_feature ATFLogMissingFeature
#define log_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format, ##__VA_ARGS__)
#define test_finish() ATFTestFinish()
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format,##__VA_ARGS__)
#define vlog ATFLogInfo
#define vlog_error ATFLogError
#else
#include <stdio.h>
#define test_start()
#define log_info printf
#define log_error printf
#define log_missing_feature printf
#define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
_higherBetter?"higher is better":"lower is better", _number )
#define test_finish()
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
_higherBetter?"higher is better":"lower is better" , _number)
#ifdef _WIN32
#ifdef __MINGW32__
// Use __mingw_printf since it supports "%a" format specifier
#define vlog __mingw_printf
#define vlog_error __mingw_printf
#else
// Use home-baked function that treats "%a" as "%f"
static int vlog_win32(const char *format, ...);
#define vlog vlog_win32
#define vlog_error vlog_win32
#endif
#include <stdio.h>
#define test_start()
#define log_info printf
#define log_error printf
#define log_missing_feature printf
#define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
_higherBetter?"higher is better":"lower is better", _number )
#define vlog_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, \
_higherBetter?"higher is better":"lower is better" , _number)
#ifdef _WIN32
#ifdef __MINGW32__
// Use __mingw_printf since it supports "%a" format specifier
#define vlog __mingw_printf
#define vlog_error __mingw_printf
#else
#define vlog_error printf
#define vlog printf
// Use home-baked function that treats "%a" as "%f"
static int vlog_win32(const char *format, ...);
#define vlog vlog_win32
#define vlog_error vlog_win32
#endif
#else
#define vlog_error printf
#define vlog printf
#endif
#define ct_assert(b) ct_assert_i(b, __LINE__)
#define ct_assert_i(b, line) ct_assert_ii(b, line)
#define ct_assert_ii(b, line) int _compile_time_assertion_on_line_##line[b ? 1 : -1];
#define test_fail(msg, ...) \
{ \
log_error(msg, ##__VA_ARGS__); \
return TEST_FAIL; \
}
#define test_error(errCode,msg) test_error_ret(errCode,msg,errCode)
#define test_error_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { print_error( errCode, msg ); return retValue ; } }
#define print_error(errCode,msg) log_error( "ERROR: %s! (%s from %s:%d)\n", msg, IGetErrorString( errCode ), __FILE__, __LINE__ );
@@ -87,7 +72,7 @@ extern "C" {
#define test_missing_support_offline_cmpiler(errCode, msg) test_missing_support_offline_cmpiler_ret(errCode, msg, errCode)
// this macro should always return CL_SUCCESS, but print the skip message on test not supported with offline compiler
#define test_missing_support_offline_cmpiler_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { log_info( "INFO: Subtest %s tests is not supported in offline compiler execution path! (from %s:%d)\n", msg, __FILE__, __LINE__ ); return CL_SUCCESS ; } }
#define test_missing_support_offline_cmpiler_ret(errCode,msg,retValue) { if( errCode != CL_SUCCESS ) { log_info( "INFO: Subtest %s tests is not supported in offline compiler execution path! (from %s:%d)\n", msg, __FILE__, __LINE__ ); return TEST_SKIP ; } }
// expected error code vs. what we got
#define test_failure_error(errCode, expectedErrCode, msg) test_failure_error_ret(errCode, expectedErrCode, msg, errCode != expectedErrCode)
@@ -97,6 +82,34 @@ extern "C" {
#define test_failure_warning_ret(errCode, expectedErrCode, msg, retValue) { if( errCode != expectedErrCode ) { print_failure_warning( errCode, expectedErrCode, msg ); warnings++ ; } }
#define print_failure_warning(errCode, expectedErrCode, msg) log_error( "WARNING: %s! (Got %s, expected %s from %s:%d)\n", msg, IGetErrorString( errCode ), IGetErrorString( expectedErrCode ), __FILE__, __LINE__ );
// generate an error when an assertion is false (not error code related)
#define test_assert_error(condition, msg) \
test_assert_error_ret(condition, msg, TEST_FAIL)
#define test_assert_error_ret(condition, msg, retValue) \
{ \
if (!(condition)) \
{ \
print_assertion_error(condition, msg); \
return retValue; \
} \
}
#define print_assertion_error(condition, msg) \
log_error("ERROR: %s! (!(%s) from %s:%d)\n", msg, #condition, __FILE__, \
__LINE__);
#define ASSERT_SUCCESS(expr, msg) \
do \
{ \
cl_int _temp_retval = (expr); \
if (_temp_retval != CL_SUCCESS) \
{ \
std::stringstream ss; \
ss << "ERROR: " << msg << "=" << IGetErrorString(_temp_retval) \
<< " at " << __FILE__ << ":" << __LINE__ << "\n"; \
throw std::runtime_error(ss.str()); \
} \
} while (0)
extern const char *IGetErrorString( int clErrorCode );
extern float Ulp_Error_Half( cl_ushort test, float reference );
@@ -108,10 +121,9 @@ extern int IsChannelTypeSupported( cl_channel_type type );
extern const char *GetChannelOrderName( cl_channel_order order );
extern int IsChannelOrderSupported( cl_channel_order order );
extern const char *GetAddressModeName( cl_addressing_mode mode );
extern const char *GetQueuePropertyName(cl_command_queue_properties properties);
extern const char *GetDeviceTypeName( cl_device_type type );
int check_opencl_version_with_testname(const char *subtestname, cl_device_id device);
int check_opencl_version(cl_device_id device, cl_uint requestedMajorVersion, cl_uint requestedMinorVersion);
int check_functions_for_offline_compiler(const char *subtestname, cl_device_id device);
// NON-REENTRANT UNLESS YOU PROVIDE A BUFFER PTR (pass null to use static storage, but it's not reentrant then!)
@@ -155,10 +167,6 @@ static int vlog_win32(const char *format, ...)
#endif
#ifdef __cplusplus
}
#endif
#endif // _errorHelpers_h

View File

@@ -15,27 +15,30 @@
//
#include "imageHelpers.h"
#include <limits.h>
#include <assert.h>
#if defined( __APPLE__ )
#include <sys/mman.h>
#endif
#if !defined (_WIN32) && !defined(__APPLE__)
#include <malloc.h>
#endif
#include <algorithm>
#include <iterator>
#if !defined (_WIN32)
#include <cmath>
#endif
int gTestCount = 0;
int gTestFailure = 0;
RoundingMode gFloatToHalfRoundingMode = kDefaultRoundingMode;
static cl_ushort float2half_rte( float f );
static cl_ushort float2half_rtz( float f );
cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
bool gTestRounding = false;
double
sRGBmap(float fc)
{
double c = (double)fc;
#if !defined (_WIN32)
if (isnan(c))
if (std::isnan(c))
c = 0.0;
#else
if (_isnan(c))
@@ -69,12 +72,12 @@ sRGBunmap(float fc)
}
size_t get_format_type_size( const cl_image_format *format )
uint32_t get_format_type_size(const cl_image_format *format)
{
return get_channel_data_type_size( format->image_channel_data_type );
}
size_t get_channel_data_type_size( cl_channel_type channelType )
uint32_t get_channel_data_type_size(cl_channel_type channelType)
{
switch( channelType )
{
@@ -126,12 +129,12 @@ size_t get_channel_data_type_size( cl_channel_type channelType )
}
}
size_t get_format_channel_count( const cl_image_format *format )
uint32_t get_format_channel_count(const cl_image_format *format)
{
return get_channel_order_channel_count( format->image_channel_order );
}
size_t get_channel_order_channel_count( cl_channel_order order )
uint32_t get_channel_order_channel_count(cl_channel_order order)
{
switch( order )
{
@@ -278,7 +281,7 @@ int is_format_signed( const cl_image_format *format )
}
}
size_t get_pixel_size( cl_image_format *format )
uint32_t get_pixel_size(cl_image_format *format)
{
switch( format->image_channel_data_type )
{
@@ -330,6 +333,23 @@ size_t get_pixel_size( cl_image_format *format )
}
}
uint32_t next_power_of_two(uint32_t v)
{
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
uint32_t get_pixel_alignment(cl_image_format *format)
{
return next_power_of_two(get_pixel_size(format));
}
int get_8_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat )
{
cl_image_format formatList[ 128 ];
@@ -682,6 +702,16 @@ void get_max_sizes(size_t *numberOfSizes, const int maxNumberOfSizes,
if(x0_dim == 0 && x0 < 16)
x0 = 16;
double x1 = fmin(fmin(A/M/x0,maximum_sizes[x1_dim]),other_sizes[(other_size++)%num_other_sizes]);
// Valid image sizes cannot be below 1. Due to the workaround for the xo_dim where x0 is overidden to 16
// there might not be enough space left for x1 dimension. This could be a fractional 0.x size that when cast to
// integer would result in a value 0. In these cases we clamp the size to a minimum of 1.
if ( x1 < 1 )
x1 = 1;
// M and x0 cannot be '0' as they derive from clDeviceInfo calls
assert(x0 > 0 && M > 0);
// Store the size
sizes[(*numberOfSizes)][fixed_dim] = (size_t)M;
sizes[(*numberOfSizes)][x0_dim] = (size_t)x0;
@@ -775,7 +805,6 @@ float get_max_relative_error( cl_image_format *format, image_sampler_data *sampl
{
if( sampler->filter_mode != CL_FILTER_NEAREST )
{
extern cl_device_type gDeviceType;
// The maximum
if( gDeviceType == CL_DEVICE_TYPE_GPU )
maxError += MAKE_HEX_FLOAT(0x1.0p-4f, 0x1L, -4); // Some GPUs ain't so accurate
@@ -884,8 +913,7 @@ int get_format_min_int( cl_image_format *format )
case CL_UNORM_INT_101010:
return 0;
case CL_HALF_FLOAT:
return -1<<10;
case CL_HALF_FLOAT: return -(1 << 10);
#ifdef CL_SFIXED14_APPLE
case CL_SFIXED14_APPLE:
@@ -897,72 +925,12 @@ int get_format_min_int( cl_image_format *format )
}
}
float convert_half_to_float( unsigned short halfValue )
{
// We have to take care of a few special cases, but in general, we just extract
// the same components from the half that exist in the float and re-stuff them
// For a description of the actual half format, see http://en.wikipedia.org/wiki/Half_precision
// Note: we store these in 32-bit ints to make the bit manipulations easier later
int sign = ( halfValue >> 15 ) & 0x0001;
int exponent = ( halfValue >> 10 ) & 0x001f;
int mantissa = ( halfValue ) & 0x03ff;
// Note: we use a union here to be able to access the bits of a float directly
union
{
unsigned int bits;
float floatValue;
} outFloat;
// Special cases first
if( exponent == 0 )
{
if( mantissa == 0 )
{
// If both exponent and mantissa are 0, the number is +/- 0
outFloat.bits = sign << 31;
return outFloat.floatValue; // Already done!
}
// If exponent is 0, it's a denormalized number, so we renormalize it
// Note: this is not terribly efficient, but oh well
while( ( mantissa & 0x00000400 ) == 0 )
{
mantissa <<= 1;
exponent--;
}
// The first bit is implicit, so we take it off and inc the exponent accordingly
exponent++;
mantissa &= ~(0x00000400);
}
else if( exponent == 31 ) // Special-case "numbers"
{
// If the exponent is 31, it's a special case number (+/- infinity or NAN).
// If the mantissa is 0, it's infinity, else it's NAN, but in either case, the packing
// method is the same
outFloat.bits = ( sign << 31 ) | 0x7f800000 | ( mantissa << 13 );
return outFloat.floatValue;
}
// Plain ol' normalized number, so adjust to the ranges a 32-bit float expects and repack
exponent += ( 127 - 15 );
mantissa <<= 13;
outFloat.bits = ( sign << 31 ) | ( exponent << 23 ) | mantissa;
return outFloat.floatValue;
}
cl_ushort convert_float_to_half( float f )
{
switch( gFloatToHalfRoundingMode )
{
case kRoundToNearestEven:
return float2half_rte( f );
case kRoundTowardZero:
return float2half_rtz( f );
case kRoundToNearestEven: return cl_half_from_float(f, CL_HALF_RTE);
case kRoundTowardZero: return cl_half_from_float(f, CL_HALF_RTZ);
default:
log_error( "ERROR: Test internal error -- unhandled or unknown float->half rounding mode.\n" );
exit(-1);
@@ -971,173 +939,6 @@ cl_ushort convert_float_to_half( float f )
}
cl_ushort float2half_rte( float f )
{
union{ float f; cl_uint u; } u = {f};
cl_uint sign = (u.u >> 16) & 0x8000;
float x = fabsf(f);
//Nan
if( x != x )
{
u.u >>= (24-11);
u.u &= 0x7fff;
u.u |= 0x0200; //silence the NaN
return u.u | sign;
}
// overflow
if( x >= MAKE_HEX_FLOAT(0x1.ffep15f, 0x1ffeL, 3) )
return 0x7c00 | sign;
// underflow
if( x <= MAKE_HEX_FLOAT(0x1.0p-25f, 0x1L, -25) )
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
// very small
if( x < MAKE_HEX_FLOAT(0x1.8p-24f, 0x18L, -28) )
return sign | 1;
// half denormal
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
{
u.f = x * MAKE_HEX_FLOAT(0x1.0p-125f, 0x1L, -125);
return sign | u.u;
}
u.f *= MAKE_HEX_FLOAT(0x1.0p13f, 0x1L, 13);
u.u &= 0x7f800000;
x += u.f;
u.f = x - u.f;
u.f *= MAKE_HEX_FLOAT(0x1.0p-112f, 0x1L, -112);
return (u.u >> (24-11)) | sign;
}
cl_ushort float2half_rtz( float f )
{
union{ float f; cl_uint u; } u = {f};
cl_uint sign = (u.u >> 16) & 0x8000;
float x = fabsf(f);
//Nan
if( x != x )
{
u.u >>= (24-11);
u.u &= 0x7fff;
u.u |= 0x0200; //silence the NaN
return u.u | sign;
}
// overflow
if( x >= MAKE_HEX_FLOAT(0x1.0p16f, 0x1L, 16) )
{
if( x == INFINITY )
return 0x7c00 | sign;
return 0x7bff | sign;
}
// underflow
if( x < MAKE_HEX_FLOAT(0x1.0p-24f, 0x1L, -24) )
return sign; // The halfway case can return 0x0001 or 0. 0 is even.
// half denormal
if( x < MAKE_HEX_FLOAT(0x1.0p-14f, 0x1L, -14) )
{
x *= MAKE_HEX_FLOAT(0x1.0p24f, 0x1L, 24);
return (cl_ushort)((int) x | sign);
}
u.u &= 0xFFFFE000U;
u.u -= 0x38000000U;
return (u.u >> (24-11)) | sign;
}
class TEST
{
public:
TEST();
};
static TEST t;
void __vstore_half_rte(float f, size_t index, uint16_t *p)
{
union{ unsigned int u; float f;} u;
u.f = f;
unsigned short r = (u.u >> 16) & 0x8000;
u.u &= 0x7fffffff;
if( u.u >= 0x33000000U )
{
if( u.u >= 0x47800000 )
{
if( u.u <= 0x7f800000 )
r |= 0x7c00;
else
{
r |= 0x7e00 | ( (u.u >> 13) & 0x3ff );
}
}
else
{
float x = u.f;
if( u.u < 0x38800000 )
u.u = 0x3f000000;
else
u.u += 0x06800000;
u.u &= 0x7f800000U;
x += u.f;
x -= u.f;
u.f = x * MAKE_HEX_FLOAT(0x1.0p-112f, 0x1L, -112);
u.u >>= 13;
r |= (unsigned short) u.u;
}
}
((unsigned short*)p)[index] = r;
}
TEST::TEST()
{
return;
union
{
float f;
uint32_t i;
} test;
uint16_t control, myval;
log_info(" &&&&&&&&&&&&&&&&&&&&&&&&&&&& TESTING HALFS &&&&&&&&&&&&&&&&&&&&\n" );
test.i = 0;
do
{
if( ( test.i & 0xffffff ) == 0 )
{
if( ( test.i & 0xfffffff ) == 0 )
log_info( "*" );
else
log_info( "." );
fflush(stdout);
}
__vstore_half_rte( test.f, 0, &control );
myval = convert_float_to_half( test.f );
if( myval != control )
{
log_info( "\n******** ERROR: MyVal %04x control %04x source %12.24f\n", myval, control, test.f );
log_info( " source bits: %08x %a\n", test.i, test.f );
float t, c;
c = convert_half_to_float( control );
t = convert_half_to_float( myval );
log_info( " converted control: %12.24f myval: %12.24f\n", c, t );
}
test.i++;
} while( test.i != 0 );
log_info("\n &&&&&&&&&&&&&&&&&&&&&&&&&&&& TESTING HALFS &&&&&&&&&&&&&&&&&&&&\n" );
}
cl_ulong get_image_size( image_descriptor const *imageInfo )
{
cl_ulong imageSize;
@@ -1187,7 +988,6 @@ cl_ulong get_image_size_mb( image_descriptor const *imageInfo )
}
extern bool gTestRounding;
uint64_t gRoundingStartValue = 0;
@@ -1236,13 +1036,8 @@ char * generate_random_image_data( image_descriptor *imageInfo, BufferOwningPtr<
}
#else
P.reset( NULL ); // Free already allocated memory first, then try to allocate new block.
#if defined (_WIN32) && defined(_MSC_VER)
char *data = (char *)_aligned_malloc(allocSize, get_pixel_size(imageInfo->format));
#elif defined(__MINGW32__)
char *data = (char *)__mingw_aligned_malloc(allocSize, get_pixel_size(imageInfo->format));
#else
char *data = (char *)memalign(get_pixel_size(imageInfo->format), allocSize);
#endif
char *data =
(char *)align_malloc(allocSize, get_pixel_alignment(imageInfo->format));
P.reset(data,NULL,0,allocSize, true);
#endif
@@ -1490,7 +1285,7 @@ void read_image_pixel_float( void *imageData, image_descriptor *imageInfo,
{
cl_ushort *dPtr = (cl_ushort *)ptr;
for( i = 0; i < channelCount; i++ )
tempData[ i ] = convert_half_to_float( dPtr[ i ] );
tempData[i] = cl_half_to_float(dPtr[i]);
break;
}
@@ -1810,7 +1605,7 @@ static inline void check_for_denorms(float a[4], int *containsDenorms )
{
for( int i = 0; i < 4; i++ )
{
if( fabsf(a[i]) < FLT_MIN )
if( IsFloatSubnormal( a[i] ) )
a[i] = copysignf( 0.0f, a[i] );
}
}
@@ -1818,7 +1613,7 @@ static inline void check_for_denorms(float a[4], int *containsDenorms )
{
for( int i = 0; i < 4; i++ )
{
if( fabs(a[i]) < FLT_MIN )
if( IsFloatSubnormal( a[i] ) )
{
*containsDenorms = 1;
break;
@@ -2610,11 +2405,11 @@ void pack_image_pixel( float *srcVector, const cl_image_format *imageFormat, voi
{
case kRoundToNearestEven:
for( unsigned int i = 0; i < channelCount; i++ )
ptr[ i ] = float2half_rte( srcVector[ i ] );
ptr[i] = cl_half_from_float(srcVector[i], CL_HALF_RTE);
break;
case kRoundTowardZero:
for( unsigned int i = 0; i < channelCount; i++ )
ptr[ i ] = float2half_rtz( srcVector[ i ] );
ptr[i] = cl_half_from_float(srcVector[i], CL_HALF_RTZ);
break;
default:
log_error( "ERROR: Test internal error -- unhandled or unknown float->half rounding mode.\n" );
@@ -3063,8 +2858,8 @@ int DetectFloatToHalfRoundingMode( cl_command_queue q ) // Returns CL_SUCCESS
cl_ushort rtz_ref[count*4];
for( size_t i = 0; i < 4 * count; i++ )
{
rte_ref[i] = float2half_rte( inp[i] );
rtz_ref[i] = float2half_rtz( inp[i] );
rte_ref[i] = cl_half_from_float(inp[i], CL_HALF_RTE);
rtz_ref[i] = cl_half_from_float(inp[i], CL_HALF_RTZ);
}
// Verify that we got something in either rtz or rte mode
@@ -3165,15 +2960,9 @@ char *create_random_image_data( ExplicitType dataType, image_descriptor *imageIn
P.reset(data);
}
#else
#if defined (_WIN32) && defined(_MSC_VER)
char *data = (char *)_aligned_malloc(allocSize, get_pixel_size(imageInfo->format));
#elif defined(__MINGW32__)
char *data = (char *)__mingw_aligned_malloc(allocSize, get_pixel_size(imageInfo->format));
#else
char *data = (char *)memalign(get_pixel_size(imageInfo->format), allocSize);
#endif
P.reset(data,NULL,0,allocSize,true);
char *data =
(char *)align_malloc(allocSize, get_pixel_alignment(imageInfo->format));
P.reset(data, NULL, 0, allocSize, true);
#endif
if (data == NULL) {
@@ -3289,6 +3078,7 @@ char *create_random_image_data( ExplicitType dataType, image_descriptor *imageIn
}
break;
}
break;
}
case kInt:
@@ -3672,59 +3462,170 @@ bool find_format( cl_image_format *formatList, unsigned int numFormats, cl_image
return false;
}
bool check_minimum_supported( cl_image_format *formatList, unsigned int numFormats, cl_mem_flags flags )
void build_required_image_formats(cl_mem_flags flags,
cl_mem_object_type image_type,
cl_device_id device,
std::vector<cl_image_format>& formatsToSupport)
{
cl_image_format readFormatsToSupport[] = { { CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA, CL_UNORM_INT16 },
{ CL_RGBA, CL_SIGNED_INT8 },
{ CL_RGBA, CL_SIGNED_INT16 },
{ CL_RGBA, CL_SIGNED_INT32 },
{ CL_RGBA, CL_UNSIGNED_INT8 },
{ CL_RGBA, CL_UNSIGNED_INT16 },
{ CL_RGBA, CL_UNSIGNED_INT32 },
{ CL_RGBA, CL_HALF_FLOAT },
{ CL_RGBA, CL_FLOAT },
{ CL_BGRA, CL_UNORM_INT8} };
Version version = get_device_cl_version(device);
cl_image_format writeFormatsToSupport[] = { { CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA, CL_UNORM_INT16 },
{ CL_RGBA, CL_SIGNED_INT8 },
{ CL_RGBA, CL_SIGNED_INT16 },
{ CL_RGBA, CL_SIGNED_INT32 },
{ CL_RGBA, CL_UNSIGNED_INT8 },
{ CL_RGBA, CL_UNSIGNED_INT16 },
{ CL_RGBA, CL_UNSIGNED_INT32 },
{ CL_RGBA, CL_HALF_FLOAT },
{ CL_RGBA, CL_FLOAT },
{ CL_BGRA, CL_UNORM_INT8} };
formatsToSupport.clear();
cl_image_format *formatsToTest;
unsigned int testCount;
bool passed = true;
// Required embedded formats.
static std::vector<cl_image_format> embeddedProfReadOrWriteFormats
{
{ CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA, CL_UNORM_INT16 },
{ CL_RGBA, CL_SIGNED_INT8 },
{ CL_RGBA, CL_SIGNED_INT16 },
{ CL_RGBA, CL_SIGNED_INT32 },
{ CL_RGBA, CL_UNSIGNED_INT8 },
{ CL_RGBA, CL_UNSIGNED_INT16 },
{ CL_RGBA, CL_UNSIGNED_INT32 },
{ CL_RGBA, CL_HALF_FLOAT },
{ CL_RGBA, CL_FLOAT },
};
if( flags == CL_MEM_READ_ONLY )
{
formatsToTest = readFormatsToSupport;
testCount = sizeof( readFormatsToSupport ) / sizeof( readFormatsToSupport[ 0 ] );
}
else
{
formatsToTest = writeFormatsToSupport;
testCount = sizeof( writeFormatsToSupport ) / sizeof( writeFormatsToSupport[ 0 ] );
}
/*
Required full profile formats.
This array does not contain any full profile
formats that have restrictions on when they
are required.
*/
static std::vector<cl_image_format> fullProfReadOrWriteFormats
{
{ CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA, CL_UNORM_INT16 },
{ CL_RGBA, CL_SIGNED_INT8 },
{ CL_RGBA, CL_SIGNED_INT16 },
{ CL_RGBA, CL_SIGNED_INT32 },
{ CL_RGBA, CL_UNSIGNED_INT8 },
{ CL_RGBA, CL_UNSIGNED_INT16 },
{ CL_RGBA, CL_UNSIGNED_INT32 },
{ CL_RGBA, CL_HALF_FLOAT },
{ CL_RGBA, CL_FLOAT },
{ CL_BGRA, CL_UNORM_INT8 },
};
for( unsigned int i = 0; i < testCount; i++ )
{
if( !find_format( formatList, numFormats, &formatsToTest[ i ] ) )
{
log_error( "ERROR: Format required by OpenCL 1.0 is not supported: " );
print_header( &formatsToTest[ i ], true );
gTestCount++;
gTestFailure++;
passed = false;
}
}
return passed;
/*
Required full profile formats specifically for 2.x.
This array does not contain any full profile
formats that have restrictions on when they
are required.
*/
static std::vector<cl_image_format> fullProf2XReadOrWriteFormats
{
{ CL_R, CL_UNORM_INT8 },
{ CL_R, CL_UNORM_INT16 },
{ CL_R, CL_SNORM_INT8 },
{ CL_R, CL_SNORM_INT16 },
{ CL_R, CL_SIGNED_INT8 },
{ CL_R, CL_SIGNED_INT16 },
{ CL_R, CL_SIGNED_INT32 },
{ CL_R, CL_UNSIGNED_INT8 },
{ CL_R, CL_UNSIGNED_INT16 },
{ CL_R, CL_UNSIGNED_INT32 },
{ CL_R, CL_HALF_FLOAT },
{ CL_R, CL_FLOAT },
{ CL_RG, CL_UNORM_INT8 },
{ CL_RG, CL_UNORM_INT16 },
{ CL_RG, CL_SNORM_INT8 },
{ CL_RG, CL_SNORM_INT16 },
{ CL_RG, CL_SIGNED_INT8 },
{ CL_RG, CL_SIGNED_INT16 },
{ CL_RG, CL_SIGNED_INT32 },
{ CL_RG, CL_UNSIGNED_INT8 },
{ CL_RG, CL_UNSIGNED_INT16 },
{ CL_RG, CL_UNSIGNED_INT32 },
{ CL_RG, CL_HALF_FLOAT },
{ CL_RG, CL_FLOAT },
{ CL_RGBA, CL_SNORM_INT8 },
{ CL_RGBA, CL_SNORM_INT16 },
};
/*
Required full profile formats for CL_DEPTH
(specifically 2.x).
There are cases whereby the format isn't required.
*/
static std::vector<cl_image_format> fullProf2XReadOrWriteDepthFormats
{
{ CL_DEPTH, CL_UNORM_INT16 },
{ CL_DEPTH, CL_FLOAT },
};
/*
Required full profile formats for CL_sRGB
(specifically 2.x).
There are cases whereby the format isn't required.
*/
static std::vector<cl_image_format> fullProf2XSRGBFormats
{
{ CL_sRGBA, CL_UNORM_INT8 },
};
// Embedded profile
if (gIsEmbedded)
{
copy(embeddedProfReadOrWriteFormats.begin(),
embeddedProfReadOrWriteFormats.end(),
back_inserter(formatsToSupport));
}
// Full profile
else
{
copy(fullProfReadOrWriteFormats.begin(),
fullProfReadOrWriteFormats.end(),
back_inserter(formatsToSupport));
}
// Full profile, OpenCL 2.0, 2.1, 2.2
if (!gIsEmbedded && version >= Version(2, 0) && version <= Version(2, 2))
{
copy(fullProf2XReadOrWriteFormats.begin(),
fullProf2XReadOrWriteFormats.end(),
back_inserter(formatsToSupport));
// Depth images are only required for 2DArray and 2D images
if (image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY || image_type == CL_MEM_OBJECT_IMAGE2D)
{
copy(fullProf2XReadOrWriteDepthFormats.begin(),
fullProf2XReadOrWriteDepthFormats.end(),
back_inserter(formatsToSupport));
}
// sRGB is not required for 1DImage Buffers
if (image_type != CL_MEM_OBJECT_IMAGE1D_BUFFER)
{
// sRGB is only required for reading
if (flags == CL_MEM_READ_ONLY)
{
copy(fullProf2XSRGBFormats.begin(),
fullProf2XSRGBFormats.end(),
back_inserter(formatsToSupport));
}
}
}
}
bool is_image_format_required(cl_image_format format,
cl_mem_flags flags,
cl_mem_object_type image_type,
cl_device_id device)
{
std::vector<cl_image_format> formatsToSupport;
build_required_image_formats(flags, image_type, device, formatsToSupport);
for (auto &formatItr: formatsToSupport)
{
if (formatItr.image_channel_order == format.image_channel_order &&
formatItr.image_channel_data_type == format.image_channel_data_type)
{
return true;
}
}
return false;
}
cl_uint compute_max_mip_levels( size_t width, size_t height, size_t depth)

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#if !defined(_WIN32)
#include <unistd.h>
@@ -40,9 +41,10 @@
#include "rounding_mode.h"
#include "clImageHelper.h"
extern int gTestCount;
extern int gTestFailure;
#include <CL/cl_half.h>
extern cl_device_type gDeviceType;
extern bool gTestRounding;
// Number of iterations per image format to test if not testing max images, rounding, or small images
#define NUM_IMAGE_ITERATIONS 3
@@ -72,16 +74,23 @@ extern void print_read_header( cl_image_format *format, image_sampler_data *samp
extern void print_write_header( cl_image_format *format, bool err);
extern void print_header( cl_image_format *format, bool err );
extern bool find_format( cl_image_format *formatList, unsigned int numFormats, cl_image_format *formatToFind );
extern bool check_minimum_supported( cl_image_format *formatList, unsigned int numFormats, cl_mem_flags flags );
extern bool is_image_format_required(cl_image_format format,
cl_mem_flags flags,
cl_mem_object_type image_type,
cl_device_id device);
extern void build_required_image_formats(cl_mem_flags flags,
cl_mem_object_type image_type,
cl_device_id device,
std::vector<cl_image_format>& formatsToSupport);
extern size_t get_format_type_size( const cl_image_format *format );
extern size_t get_channel_data_type_size( cl_channel_type channelType );
extern size_t get_format_channel_count( const cl_image_format *format );
extern size_t get_channel_order_channel_count( cl_channel_order order );
extern uint32_t get_format_type_size(const cl_image_format *format);
extern uint32_t get_channel_data_type_size(cl_channel_type channelType);
extern uint32_t get_format_channel_count(const cl_image_format *format);
extern uint32_t get_channel_order_channel_count(cl_channel_order order);
cl_channel_type get_channel_type_from_name( const char *name );
cl_channel_order get_channel_order_from_name( const char *name );
extern int is_format_signed( const cl_image_format *format );
extern size_t get_pixel_size( cl_image_format *format );
extern uint32_t get_pixel_size(cl_image_format *format);
/* Helper to get any ol image format as long as it is 8-bits-per-channel */
extern int get_8_bit_image_format( cl_context context, cl_mem_object_type objType, cl_mem_flags flags, size_t channelCount, cl_image_format *outFormat );
@@ -147,7 +156,6 @@ size_t compute_mip_level_offset( image_descriptor * imageInfo , size_t lod);
template <class T> void read_image_pixel( void *imageData, image_descriptor *imageInfo,
int x, int y, int z, T *outData, int lod )
{
float convert_half_to_float( unsigned short halfValue );
size_t width_lod = imageInfo->width, height_lod = imageInfo->height, depth_lod = imageInfo->depth, slice_pitch_lod = 0/*imageInfo->slicePitch*/ , row_pitch_lod = 0/*imageInfo->rowPitch*/;
width_lod = ( imageInfo->width >> lod) ?( imageInfo->width >> lod):1;
@@ -271,7 +279,7 @@ template <class T> void read_image_pixel( void *imageData, image_descriptor *ima
{
cl_ushort *dPtr = (cl_ushort *)ptr;
for( i = 0; i < get_format_channel_count( format ); i++ )
tempData[ i ] = (T)convert_half_to_float( dPtr[ i ] );
tempData[i] = (T)cl_half_to_float(dPtr[i]);
break;
}
@@ -631,12 +639,17 @@ protected:
size_t mVecSize;
};
extern cl_ushort convert_float_to_half(float f);
extern int DetectFloatToHalfRoundingMode( cl_command_queue ); // Returns CL_SUCCESS on success
int inline is_half_nan( cl_ushort half ){ return (half & 0x7fff) > 0x7c00; }
// sign bit: don't care, exponent: maximum value, significand: non-zero
static int inline is_half_nan( cl_ushort half ){ return ( half & 0x7fff ) > 0x7c00; }
cl_ushort convert_float_to_half( cl_float f );
cl_float convert_half_to_float( cl_ushort h );
// sign bit: don't care, exponent: zero, significand: non-zero
static int inline is_half_denorm( cl_ushort half ){ return IsHalfSubnormal( half ); }
// sign bit: don't care, exponent: zero, significand: zero
static int inline is_half_zero( cl_ushort half ){ return ( half & 0x7fff ) == 0; }
extern double sRGBmap(float fc);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -37,9 +37,10 @@
#include <CL/opencl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "deviceInfo.h"
#include "harness/alloc.h"
#include <functional>
/*
* The below code is intended to be used at the top of kernels that appear inline in files to set line and file info for the kernel:
@@ -89,6 +90,14 @@ extern int create_single_kernel_helper_create_program(cl_context context,
const char *buildOptions = NULL,
const bool openclCXX = false);
extern int create_single_kernel_helper_create_program_for_device(cl_context context,
cl_device_id device,
cl_program *outProgram,
unsigned int numKernelLines,
const char **kernelProgram,
const char *buildOptions = NULL,
const bool openclCXX = false);
/* Creates OpenCL C++ program. This one must be used for creating OpenCL C++ program. */
extern int create_openclcpp_program(cl_context context,
cl_program *outProgram,
@@ -114,14 +123,11 @@ extern int get_max_common_2D_work_group_size( cl_context context, cl_kernel kern
/* Helper to obtain the biggest fit work group size for all the devices in a given group and for the given global thread size */
extern int get_max_common_3D_work_group_size( cl_context context, cl_kernel kernel, size_t *globalThreadSize, size_t *outSizes );
/* Helper to get major/minor number for a device */
extern int get_device_version( cl_device_id id, size_t* major, size_t* minor);
/* Helper to obtain the biggest allowed work group size for all the devices in a given group */
extern int get_max_allowed_work_group_size( cl_context context, cl_kernel kernel, size_t *outSize, size_t *outLimits );
/* Helper to determine if an extension is supported by a device */
extern int is_extension_available( cl_device_id device, const char *extensionName );
/* Helper to obtain the biggest allowed 1D work group size on a given device */
extern int get_max_allowed_1d_work_group_size_on_device( cl_device_id device, cl_kernel kernel, size_t *outSize );
/* Helper to determine if a device supports an image format */
extern int is_image_format_supported( cl_context context, cl_mem_flags flags, cl_mem_object_type image_type, const cl_image_format *fmt );
@@ -139,10 +145,6 @@ extern int checkFor3DImageSupport( cl_device_id device );
/* Checks that a given queue property is supported on the specified device. Returns 1 if supported, 0 if not or an error. */
extern int checkDeviceForQueueSupport( cl_device_id device, cl_command_queue_properties prop );
/* Helper for aligned memory allocation */
void * align_malloc(size_t size, size_t alignment);
void align_free(void *);
/* Helper to obtain the min alignment for a given context, i.e the max of all min alignments for devices attached to the context*/
size_t get_min_alignment(cl_context context);
@@ -163,11 +165,26 @@ cl_device_fp_config get_default_rounding_mode( cl_device_id device );
return 0; \
}
#define PASSIVE_REQUIRE_FP16_SUPPORT(device) \
if (!is_extension_available(device, "cl_khr_fp16")) \
{ \
log_info("\n\tNote: device does not support fp16. Skipping test...\n"); \
return 0; \
}
/* Prints out the standard device header for all tests given the device to print for */
extern int printDeviceHeader( cl_device_id device );
#ifdef __cplusplus
}
#endif // __cplusplus
// Gets the latest (potentially non-backward compatible) OpenCL C version
// supported by the device.
Version get_device_cl_c_version(cl_device_id device);
// Gets the maximum universally supported OpenCL C version in a context, i.e.
// the OpenCL C version supported by all devices in a context.
Version get_max_OpenCL_C_for_context(cl_context context);
// Poll fn every interval_ms until timeout_ms or it returns true
bool poll_until(unsigned timeout_ms, unsigned interval_ms,
std::function<bool()> fn);
#endif // _kernelHelpers_h

View File

@@ -24,7 +24,7 @@
#include <windows.h>
#if ! defined( __INTEL_COMPILER )
#if _MSC_VER < 1900 && ! defined( __INTEL_COMPILER )
///////////////////////////////////////////////////////////////////
//
@@ -276,6 +276,8 @@ int SIGNBIT_DP64(double x )
}
#endif
#if _MSC_VER < 1900
/* fmax(x, y) returns the larger (more positive) of x and y.
NaNs are treated as missing values: if one argument is NaN,
the other argument is returned. If both arguments are NaN,
@@ -560,6 +562,7 @@ long int lrintf (float x)
return (long int) x;
}
#endif // _MSC_VER < 1900
///////////////////////////////////////////////////////////////////
//
@@ -589,20 +592,7 @@ int feclearexcept(int excepts)
#endif // __INTEL_COMPILER
#if ! defined( __INTEL_COMPILER ) || __INTEL_COMPILER < 1300
float make_nan()
{
/* This is the IEEE 754 single-precision format:
unsigned int mantissa: 22;
unsigned int quiet_nan: 1;
unsigned int exponent: 8;
unsigned int negative: 1;
*/
//const static unsigned
static const int32_t _nan = 0x7fc00000;
return *(const float*)(&_nan);
}
#if _MSC_VER < 1900 && ( ! defined( __INTEL_COMPILER ) || __INTEL_COMPILER < 1300 )
float nanf( const char* str)
{

View File

@@ -1,280 +0,0 @@
/*
A C-program for MT19937, with initialization improved 2002/1/26.
Coded by Takuji Nishimura and Makoto Matsumoto.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Any feedback is very welcome.
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
Modifications for use in OpenCL by Ian Ollmann, Apple Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include "mt19937.h"
#include "mingw_compat.h"
#ifdef __SSE2__
#include <emmintrin.h>
#endif
static void * align_malloc(size_t size, size_t alignment)
{
#if defined(_WIN32) && defined(_MSC_VER)
return _aligned_malloc(size, alignment);
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
void * ptr = NULL;
#if defined(__ANDROID__)
ptr = memalign(alignment, size);
if ( ptr )
return ptr;
#else
if (0 == posix_memalign(&ptr, alignment, size))
return ptr;
#endif
return NULL;
#elif defined(__MINGW32__)
return __mingw_aligned_malloc(size, alignment);
#else
#error "Please add support OS for aligned malloc"
#endif
}
static void align_free(void * ptr)
{
#if defined(_WIN32) && defined(_MSC_VER)
_aligned_free(ptr);
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
return free(ptr);
#elif defined(__MINGW32__)
return __mingw_aligned_free(ptr);
#else
#error "Please add support OS for aligned free"
#endif
}
/* Period parameters */
#define N 624 /* vector code requires multiple of 4 here */
#define M 397
#define MATRIX_A (cl_uint) 0x9908b0dfUL /* constant vector a */
#define UPPER_MASK (cl_uint) 0x80000000UL /* most significant w-r bits */
#define LOWER_MASK (cl_uint) 0x7fffffffUL /* least significant r bits */
typedef struct _MTdata
{
cl_uint mt[N];
#ifdef __SSE2__
cl_uint cache[N];
#endif
cl_int mti;
}_MTdata;
/* initializes mt[N] with a seed */
MTdata init_genrand(cl_uint s)
{
MTdata r = (MTdata) align_malloc( sizeof( _MTdata ), 16 );
if( NULL != r )
{
cl_uint *mt = r->mt;
int mti = 0;
mt[0]= s; // & 0xffffffffUL;
for (mti=1; mti<N; mti++) {
mt[mti] = (cl_uint)
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
// mt[mti] &= 0xffffffffUL;
/* for >32 bit machines */
}
r->mti = mti;
}
return r;
}
void free_mtdata( MTdata d )
{
if(d)
align_free(d);
}
/* generates a random number on [0,0xffffffff]-interval */
cl_uint genrand_int32( MTdata d)
{
/* mag01[x] = x * MATRIX_A for x=0,1 */
static const cl_uint mag01[2]={0x0UL, MATRIX_A};
#ifdef __SSE2__
static volatile int init = 0;
static union{ __m128i v; cl_uint s[4]; } upper_mask, lower_mask, one, matrix_a, c0, c1;
#endif
cl_uint *mt = d->mt;
cl_uint y;
if (d->mti == N)
{ /* generate N words at one time */
int kk;
#ifdef __SSE2__
if( 0 == init )
{
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] = upper_mask.s[3] = UPPER_MASK;
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] = lower_mask.s[3] = LOWER_MASK;
one.s[0] = one.s[1] = one.s[2] = one.s[3] = 1;
matrix_a.s[0] = matrix_a.s[1] = matrix_a.s[2] = matrix_a.s[3] = MATRIX_A;
c0.s[0] = c0.s[1] = c0.s[2] = c0.s[3] = (cl_uint) 0x9d2c5680UL;
c1.s[0] = c1.s[1] = c1.s[2] = c1.s[3] = (cl_uint) 0xefc60000UL;
init = 1;
}
#endif
kk = 0;
#ifdef __SSE2__
// vector loop
for( ; kk + 4 <= N-M; kk += 4 )
{
__m128i vy = _mm_or_si128( _mm_and_si128( _mm_load_si128( (__m128i*)(mt + kk) ), upper_mask.v ),
_mm_and_si128( _mm_loadu_si128( (__m128i*)(mt + kk + 1) ), lower_mask.v )); // ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK))
__m128i mask = _mm_cmpeq_epi32( _mm_and_si128( vy, one.v), one.v ); // y & 1 ? -1 : 0
__m128i vmag01 = _mm_and_si128( mask, matrix_a.v ); // y & 1 ? MATRIX_A, 0 = mag01[y & (cl_uint) 0x1UL]
__m128i vr = _mm_xor_si128( _mm_loadu_si128( (__m128i*)(mt + kk + M)), (__m128i) _mm_srli_epi32( vy, 1 ) ); // mt[kk+M] ^ (y >> 1)
vr = _mm_xor_si128( vr, vmag01 ); // mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL]
_mm_store_si128( (__m128i*) (mt + kk ), vr );
}
#endif
for ( ;kk<N-M;kk++) {
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
}
#ifdef __SSE2__
// advance to next aligned location
for (;kk<N-1 && (kk & 3);kk++) {
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
}
// vector loop
for( ; kk + 4 <= N-1; kk += 4 )
{
__m128i vy = _mm_or_si128( _mm_and_si128( _mm_load_si128( (__m128i*)(mt + kk) ), upper_mask.v ),
_mm_and_si128( _mm_loadu_si128( (__m128i*)(mt + kk + 1) ), lower_mask.v )); // ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK))
__m128i mask = _mm_cmpeq_epi32( _mm_and_si128( vy, one.v), one.v ); // y & 1 ? -1 : 0
__m128i vmag01 = _mm_and_si128( mask, matrix_a.v ); // y & 1 ? MATRIX_A, 0 = mag01[y & (cl_uint) 0x1UL]
__m128i vr = _mm_xor_si128( _mm_loadu_si128( (__m128i*)(mt + kk + M - N)), _mm_srli_epi32( vy, 1 ) ); // mt[kk+M-N] ^ (y >> 1)
vr = _mm_xor_si128( vr, vmag01 ); // mt[kk+M] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL]
_mm_store_si128( (__m128i*) (mt + kk ), vr );
}
#endif
for (;kk<N-1;kk++) {
y = (cl_uint) ((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
}
y = (cl_uint)((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK));
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & (cl_uint) 0x1UL];
#ifdef __SSE2__
// Do the tempering ahead of time in vector code
for( kk = 0; kk + 4 <= N; kk += 4 )
{
__m128i vy = _mm_load_si128( (__m128i*)(mt + kk ) ); // y = mt[k];
vy = _mm_xor_si128( vy, _mm_srli_epi32( vy, 11 ) ); // y ^= (y >> 11);
vy = _mm_xor_si128( vy, _mm_and_si128( _mm_slli_epi32( vy, 7 ), c0.v) ); // y ^= (y << 7) & (cl_uint) 0x9d2c5680UL;
vy = _mm_xor_si128( vy, _mm_and_si128( _mm_slli_epi32( vy, 15 ), c1.v) ); // y ^= (y << 15) & (cl_uint) 0xefc60000UL;
vy = _mm_xor_si128( vy, _mm_srli_epi32( vy, 18 ) ); // y ^= (y >> 18);
_mm_store_si128( (__m128i*)(d->cache+kk), vy );
}
#endif
d->mti = 0;
}
#ifdef __SSE2__
y = d->cache[d->mti++];
#else
y = mt[d->mti++];
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & (cl_uint) 0x9d2c5680UL;
y ^= (y << 15) & (cl_uint) 0xefc60000UL;
y ^= (y >> 18);
#endif
return y;
}
cl_ulong genrand_int64( MTdata d)
{
return ((cl_ulong) genrand_int32(d) << 32) | (cl_uint) genrand_int32(d);
}
/* generates a random number on [0,1]-real-interval */
double genrand_real1(MTdata d)
{
return genrand_int32(d)*(1.0/4294967295.0);
/* divided by 2^32-1 */
}
/* generates a random number on [0,1)-real-interval */
double genrand_real2(MTdata d)
{
return genrand_int32(d)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on (0,1)-real-interval */
double genrand_real3(MTdata d)
{
return (((double)genrand_int32(d)) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on [0,1) with 53-bit resolution*/
double genrand_res53(MTdata d)
{
unsigned long a=genrand_int32(d)>>5, b=genrand_int32(d)>>6;
return(a*67108864.0+b)*(1.0/9007199254740992.0);
}

View File

@@ -48,41 +48,12 @@
#include <stdlib.h>
#include "mt19937.h"
#include "mingw_compat.h"
#include "harness/alloc.h"
#ifdef __SSE2__
#include <emmintrin.h>
#endif
static void * align_malloc(size_t size, size_t alignment)
{
#if defined(_WIN32) && defined(_MSC_VER)
return _aligned_malloc(size, alignment);
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
void * ptr = NULL;
if (0 == posix_memalign(&ptr, alignment, size))
return ptr;
return NULL;
#elif defined(__MINGW32__)
return __mingw_aligned_malloc(size, alignment);
#else
#error "Please add support OS for aligned malloc"
#endif
}
static void align_free(void * ptr)
{
#if defined(_WIN32) && defined(_MSC_VER)
_aligned_free(ptr);
#elif defined(__linux__) || defined (linux) || defined(__APPLE__)
return free(ptr);
#elif defined(__MINGW32__)
return __mingw_aligned_free(ptr);
#else
#error "Please add support OS for aligned free"
#endif
}
/* Period parameters */
#define N 624 /* vector code requires multiple of 4 here */
#define M 397

View File

@@ -55,10 +55,6 @@
#include <CL/cl_platform.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Interfaces here have been modified from original sources so that they
* are safe to call reentrantly, so long as a different MTdata is used
@@ -93,7 +89,29 @@ double genrand_res53( MTdata /*data*/ );
#ifdef __cplusplus
#include <cassert>
struct MTdataHolder {
MTdataHolder(cl_uint seed) {
m_mtdata = init_genrand(seed);
assert(m_mtdata != nullptr);
}
#endif
MTdataHolder(MTdata mtdata) : m_mtdata(mtdata) {}
~MTdataHolder() {
free_mtdata(m_mtdata);
}
operator MTdata () const {
return m_mtdata;
}
private:
MTdata m_mtdata;
};
#endif // #ifdef __cplusplus
#endif /* MT19937_H */

View File

@@ -28,6 +28,10 @@
#include <vector>
#if defined(__ANDROID__)
#include <android/api-level.h>
#endif
#define CHECK_PTR( ptr ) \
if ( (ptr) == NULL ) { \
abort(); \
@@ -187,7 +191,7 @@ int const _count = 8; // How many times we will try to double buff
*/
#if defined(__ANDROID__) || ( ( _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 ) && ! _GNU_SOURCE )
#if (defined(__ANDROID__) && __ANDROID_API__ < 23) || ( ( _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 ) && ! _GNU_SOURCE )
// XSI version of strerror_r.
#warning Not tested!

View File

@@ -37,17 +37,9 @@
// C interface.
// -------------------------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
char * get_err_msg( int err ); // Returns system error message. Subject to free.
char * get_dir_sep(); // Returns dir separator. Subject to free.
char * get_exe_path(); // Returns path of current executable. Subject to free.
char * get_exe_dir(); // Returns dir of current executable. Subject to free.
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // __os_helpers_h__

View File

@@ -27,105 +27,177 @@
using namespace std;
bool gOfflineCompiler = false;
bool gForceSpirVCache = false;
bool gForceSpirVGenerate = false;
std::string gSpirVPath = ".";
OfflineCompilerOutputType gOfflineCompilerOutputType;
#define DEFAULT_COMPILATION_PROGRAM "cl_offline_compiler"
CompilationMode gCompilationMode = kOnline;
CompilationCacheMode gCompilationCacheMode = kCacheModeCompileIfAbsent;
std::string gCompilationCachePath = ".";
std::string gCompilationProgram = DEFAULT_COMPILATION_PROGRAM;
void helpInfo ()
{
log_info(" '-offlineCompiler <output_type:binary|source|spir_v>': use offline compiler\n");
log_info(" ' output_type binary - \"../build_script_binary.py\" is invoked\n");
log_info(" ' output_type source - \"../build_script_source.py\" is invoked\n");
log_info(" ' output_type spir_v <mode:generate|cache> - \"../cl_build_script_spir_v.py\" is invoked, optional modes: generate, cache\n");
log_info(" ' mode generate <path> - force binary generation\n");
log_info(" ' mode cache <path> - force reading binary files from cache\n");
log_info("\n");
log_info("Common options:\n"
" -h, --help This help\n"
" --compilation-mode <mode> Specify a compilation mode. Mode can be:\n"
" online Use online compilation (default)\n"
" binary Use binary offline compilation\n"
" spir-v Use SPIR-V offline compilation\n"
"\n"
" For offline compilation (binary and spir-v modes) only:\n"
" --compilation-cache-mode <cache-mode> Specify a compilation caching mode:\n"
" compile-if-absent Read from cache if already populated, or\n"
" else perform offline compilation (default)\n"
" force-read Force reading from the cache\n"
" overwrite Disable reading from the cache\n"
" dump-cl-files Dumps the .cl and build .options files used by the test suite\n"
" --compilation-cache-path <path> Path for offline compiler output and CL source\n"
" --compilation-program <prog> Program to use for offline compilation,\n"
" defaults to " DEFAULT_COMPILATION_PROGRAM "\n"
"\n");
}
int parseCustomParam (int argc, const char *argv[], const char *ignore)
{
int delArg = 0;
int delArg = 0;
for (int i=1; i<argc; i++)
{
if(ignore != 0)
for (int i=1; i<argc; i++)
{
// skip parameters that require special/different treatment in application
// (generic interpretation and parameter removal will not be performed)
const char * ptr = strstr(ignore, argv[i]);
if(ptr != 0 &&
(ptr == ignore || ptr[-1] == ' ') && //first on list or ' ' before
(ptr[strlen(argv[i])] == 0 || ptr[strlen(argv[i])] == ' ')) // last on list or ' ' after
continue;
}
if (i < 0) i = 0;
delArg = 0;
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
helpInfo ();
else if (!strcmp(argv[i], "-offlineCompiler"))
{
log_info(" Offline Compiler enabled\n");
delArg = 1;
if ((i + 1) < argc)
if(ignore != 0)
{
gOfflineCompiler = true;
// skip parameters that require special/different treatment in application
// (generic interpretation and parameter removal will not be performed)
const char * ptr = strstr(ignore, argv[i]);
if(ptr != 0 &&
(ptr == ignore || ptr[-1] == ' ') && //first on list or ' ' before
(ptr[strlen(argv[i])] == 0 || ptr[strlen(argv[i])] == ' ')) // last on list or ' ' after
continue;
}
if (!strcmp(argv[i + 1], "binary"))
delArg = 0;
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
{
// Note: we don't increment delArg to delete this argument,
// to allow the caller's argument parsing routine to see the
// option and print its own help.
helpInfo ();
}
else if (!strcmp(argv[i], "--compilation-mode"))
{
delArg++;
if ((i + 1) < argc)
{
gOfflineCompilerOutputType = kBinary;
delArg++;
}
else if (!strcmp(argv[i + 1], "source"))
{
gOfflineCompilerOutputType = kSource;
delArg++;
}
else if (!strcmp(argv[i + 1], "spir_v"))
{
gOfflineCompilerOutputType = kSpir_v;
delArg++;
if ((i + 3) < argc)
const char *mode = argv[i + 1];
if (!strcmp(mode, "online"))
{
if (!strcmp(argv[i + 2], "cache"))
{
gForceSpirVCache = true;
gSpirVPath = argv[i + 3];
log_info(" SpirV reading from cache enabled.\n");
delArg += 2;
}
else if (!strcmp(argv[i + 2], "generate"))
{
gForceSpirVGenerate = true;
gSpirVPath = argv[i + 3];
log_info(" SpirV force generate binaries enabled.\n");
delArg += 2;
}
gCompilationMode = kOnline;
}
else if (!strcmp(mode, "binary"))
{
gCompilationMode = kBinary;
}
else if (!strcmp(mode, "spir-v"))
{
gCompilationMode = kSpir_v;
}
else
{
log_error("Compilation mode not recognized: %s\n", mode);
return -1;
}
log_info("Compilation mode specified: %s\n", mode);
}
else
{
log_error(" Offline Compiler output type not supported: %s\n", argv[i + 1]);
log_error("Compilation mode parameters are incorrect. Usage:\n"
" --compilation-mode <online|binary|spir-v>\n");
return -1;
}
}
else
else if (!strcmp(argv[i], "--compilation-cache-mode"))
{
log_error(" Offline Compiler parameters are incorrect. Usage:\n");
log_error(" -offlineCompiler <input> <output> <output_type:binary | source | spir_v>\n");
return -1;
delArg++;
if ((i + 1) < argc)
{
delArg++;
const char *mode = argv[i + 1];
if (!strcmp(mode, "compile-if-absent"))
{
gCompilationCacheMode = kCacheModeCompileIfAbsent;
}
else if (!strcmp(mode, "force-read"))
{
gCompilationCacheMode = kCacheModeForceRead;
}
else if (!strcmp(mode, "overwrite"))
{
gCompilationCacheMode = kCacheModeOverwrite;
}
else if (!strcmp(mode, "dump-cl-files"))
{
gCompilationCacheMode = kCacheModeDumpCl;
}
else
{
log_error("Compilation cache mode not recognized: %s\n", mode);
return -1;
}
log_info("Compilation cache mode specified: %s\n", mode);
}
else
{
log_error("Compilation cache mode parameters are incorrect. Usage:\n"
" --compilation-cache-mode <compile-if-absent|force-read|overwrite>\n");
return -1;
}
}
else if (!strcmp(argv[i], "--compilation-cache-path"))
{
delArg++;
if ((i + 1) < argc)
{
delArg++;
gCompilationCachePath = argv[i + 1];
}
else
{
log_error("Path argument for --compilation-cache-path was not specified.\n");
return -1;
}
}
else if (!strcmp(argv[i], "--compilation-program"))
{
delArg++;
if ((i + 1) < argc)
{
delArg++;
gCompilationProgram = argv[i + 1];
}
else
{
log_error("Program argument for --compilation-program was not specified.\n");
return -1;
}
}
//cleaning parameters from argv tab
for (int j = i; j < argc - delArg; j++)
argv[j] = argv[j + delArg];
argc -= delArg;
i -= delArg;
}
//cleaning parameters from argv tab
for (int j=i; j<argc-delArg; j++)
argv[j] = argv[j+delArg];
argc -= delArg ;
i -= delArg;
}
return argc;
if ((gCompilationCacheMode == kCacheModeForceRead || gCompilationCacheMode == kCacheModeOverwrite)
&& gCompilationMode == kOnline)
{
log_error("Compilation cache mode can only be specified when using an offline compilation mode.\n");
return -1;
}
return argc;
}
bool is_power_of_two(int number)
@@ -141,13 +213,13 @@ extern void parseWimpyReductionFactor(const char *&arg, int &wimpyReductionFacto
int new_factor = atoi(&arg[1]);
arg = arg_temp; // Advance until ']'
if (is_power_of_two(new_factor))
{
log_info("\n Wimpy reduction factor changed from %d to %d \n", wimpyReductionFactor, new_factor);
wimpyReductionFactor = new_factor;
}
else
{
log_info("\n WARNING: Incorrect wimpy reduction factor %d, must be power of 2. The default value will be used.\n", new_factor);
{
log_info("\n Wimpy reduction factor changed from %d to %d \n", wimpyReductionFactor, new_factor);
wimpyReductionFactor = new_factor;
}
else
{
log_info("\n WARNING: Incorrect wimpy reduction factor %d, must be power of 2. The default value will be used.\n", new_factor);
}
}
}

View File

@@ -19,19 +19,25 @@
#include "compat.h"
#include <string>
extern bool gOfflineCompiler;
extern bool gForceSpirVCache;
extern bool gForceSpirVGenerate;
extern std::string gSpirVPath;
enum OfflineCompilerOutputType
enum CompilationMode
{
kBinary = 0,
kSource,
kOnline = 0,
kBinary,
kSpir_v
};
extern OfflineCompilerOutputType gOfflineCompilerOutputType;
enum CompilationCacheMode
{
kCacheModeCompileIfAbsent = 0,
kCacheModeForceRead,
kCacheModeOverwrite,
kCacheModeDumpCl
};
extern CompilationMode gCompilationMode;
extern CompilationCacheMode gCompilationCacheMode;
extern std::string gCompilationCachePath;
extern std::string gCompilationProgram;
extern int parseCustomParam (int argc, const char *argv[], const char *ignore = 0 );

View File

@@ -0,0 +1,126 @@
//
// Copyright (c) 2020 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 "propertyHelpers.h"
#include "errorHelpers.h"
#include <assert.h>
#include <algorithm>
#include <vector>
static bool findProperty(const std::vector<cl_properties>& props,
cl_properties prop, cl_properties& value)
{
// This function assumes properties are valid:
assert(props.size() == 0 || props.back() == 0);
assert(props.size() == 0 || props.size() % 2 == 1);
for (cl_uint i = 0; i < props.size(); i = i + 2)
{
cl_properties check_prop = props[i];
if (check_prop == 0)
{
break;
}
if (check_prop == prop)
{
value = props[i + 1];
return true;
}
}
return false;
}
int compareProperties(const std::vector<cl_properties>& queried,
const std::vector<cl_properties>& check)
{
if (queried.size() != 0)
{
if (queried.back() != 0)
{
log_error("ERROR: queried properties do not end with 0!\n");
return TEST_FAIL;
}
if (queried.size() % 2 != 1)
{
log_error("ERROR: queried properties does not consist of "
"property-value pairs!\n");
return TEST_FAIL;
}
}
if (check.size() != 0)
{
if (check.back() != 0)
{
log_error("ERROR: check properties do not end with 0!\n");
return TEST_FAIL;
}
if (check.size() % 2 != 1)
{
log_error("ERROR: check properties does not consist of "
"property-value pairs!\n");
return TEST_FAIL;
}
}
if (queried != check)
{
for (cl_uint i = 0; i < check.size(); i = i + 2)
{
cl_properties check_prop = check[i];
if (check_prop == 0)
{
break;
}
cl_properties check_value = check[i + 1];
cl_properties queried_value = 0;
bool found = findProperty(queried, check_prop, queried_value);
if (!found)
{
log_error("ERROR: expected property 0x%x not found!\n",
check_prop);
return TEST_FAIL;
}
else if (check_value != queried_value)
{
log_error("ERROR: mis-matched value for property 0x%x: wanted "
"0x%x, got 0x%x\n",
check_prop, check_value, queried_value);
return TEST_FAIL;
}
}
if (queried.size() > check.size())
{
log_error("ERROR: all properties found but there are extra "
"properties: expected %d, got %d.\n",
check.size(), queried.size());
return TEST_FAIL;
}
log_error("ERROR: properties were returned in the wrong order.\n");
return TEST_FAIL;
}
return TEST_PASS;
}

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2020 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
@@ -13,19 +13,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _testBase_h
#define _testBase_h
#ifndef _propertyHelpers_h
#define _propertyHelpers_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
#include "compat.h"
#include "testHarness.h"
#include <vector>
int compareProperties(const std::vector<cl_properties>& queried,
const std::vector<cl_properties>& check);
#endif // _propertyHelpers_h

View File

@@ -16,6 +16,8 @@
#ifndef __ROUNDING_MODE_H__
#define __ROUNDING_MODE_H__
#pragma STDC FENV_ACCESS ON
#include "compat.h"
#if (defined(_WIN32) && defined (_MSC_VER))
@@ -51,19 +53,11 @@ typedef enum
kTypeCount
}Type;
#ifdef __cplusplus
extern "C" {
#endif
extern RoundingMode set_round( RoundingMode r, Type outType );
extern RoundingMode get_round( void );
extern void *FlushToZero( void );
extern void UnFlushToZero( void *p);
#ifdef __cplusplus
}
#endif
#endif /* __ROUNDING_MODE_H__ */

View File

@@ -1,5 +1,5 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017-2019 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.
@@ -16,18 +16,28 @@
#include "testHarness.h"
#include "compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cassert>
#include <stdexcept>
#include <vector>
#include "threadTesting.h"
#include "errorHelpers.h"
#include "kernelHelpers.h"
#include "fpcontrol.h"
#include "typeWrappers.h"
#include "imageHelpers.h"
#include "parseParameters.h"
#if !defined(_WIN32)
#include <sys/utsname.h>
#include <unistd.h>
#endif
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
#include <time.h>
#if !defined (__APPLE__)
@@ -36,6 +46,8 @@
int gTestsPassed = 0;
int gTestsFailed = 0;
int gFailCount;
int gTestCount;
cl_uint gRandomSeed = 0;
cl_uint gReSeed = 0;
@@ -45,18 +57,38 @@ int gIsEmbedded = 0;
int gIsOpenCL_C_1_0_Device = 0;
int gIsOpenCL_1_0_Device = 0;
int gHasLong = 1;
bool gCoreILProgram = true;
#define DEFAULT_NUM_ELEMENTS 0x4000
int runTestHarness( int argc, const char *argv[], int testNum, test_definition testList[],
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps )
{
return runTestHarnessWithCheck( argc, argv, testNum, testList, imageSupportRequired, forceNoContextCreation, queueProps,
return runTestHarnessWithCheck( argc, argv, testNum, testList, forceNoContextCreation, queueProps,
( imageSupportRequired ) ? verifyImageSupport : NULL );
}
int skip_init_info(int count) {
log_info("Test skipped while initialization\n");
log_info("SKIPPED %d of %d tests.\n", count, count);
return EXIT_SUCCESS;
}
int fail_init_info(int count) {
log_info("Test failed while initialization\n");
log_info("FAILED %d of %d tests.\n", count, count);
return EXIT_FAILURE;
}
void version_expected_info(const char *test_name, const char *api_name,
const char *expected_version,
const char *device_version)
{
log_info("%s skipped (requires at least %s version %s, but the device "
"reports %s version %s)\n",
test_name, api_name, expected_version, api_name, device_version);
}
int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_definition testList[],
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps,
int forceNoContextCreation, cl_command_queue_properties queueProps,
DeviceCheckFn deviceCheckFn )
{
test_start();
@@ -127,8 +159,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
argc = parseCustomParam(argc, argv);
if (argc == -1)
{
test_finish();
return 0;
return EXIT_FAILURE;
}
/* Special case: just list the tests */
@@ -152,8 +183,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
{
log_info( "\t%s\n", testList[i].name );
}
test_finish();
return 0;
return EXIT_SUCCESS;
}
/* How are we supposed to seed the random # generators? */
@@ -228,16 +258,18 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
}
}
switch( device_type )
{
case CL_DEVICE_TYPE_GPU: log_info( "Requesting GPU device " ); break;
case CL_DEVICE_TYPE_CPU: log_info( "Requesting CPU device " ); break;
case CL_DEVICE_TYPE_ACCELERATOR: log_info( "Requesting Accelerator device " ); break;
case CL_DEVICE_TYPE_DEFAULT: log_info( "Requesting Default device " ); break;
default: log_error( "Requesting unknown device "); return -1;
}
log_info( based_on_env_var ? "based on environment variable " : "based on command line " );
log_info( "for platform index %d and device index %d\n", choosen_platform_index, choosen_device_index);
switch (device_type)
{
case CL_DEVICE_TYPE_GPU: log_info("Requesting GPU device "); break;
case CL_DEVICE_TYPE_CPU: log_info("Requesting CPU device "); break;
case CL_DEVICE_TYPE_ACCELERATOR: log_info("Requesting Accelerator device "); break;
case CL_DEVICE_TYPE_DEFAULT: log_info("Requesting Default device "); break;
default: log_error("Requesting unknown device "); return EXIT_FAILURE;
}
log_info(based_on_env_var ? "based on environment variable " : "based on command line ");
log_info("for platform index %d and device index %d\n", choosen_platform_index, choosen_device_index);
#if defined( __APPLE__ )
#if defined( __i386__ ) || defined( __x86_64__ )
@@ -263,7 +295,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
else
{
log_error( "Error: Unknown CL_MAX_SSE setting: %s\n", env );
return -2;
return EXIT_FAILURE;
}
log_info( "*** Environment: CL_MAX_SSE = %s ***\n", env );
@@ -277,38 +309,33 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
err = clGetPlatformIDs(0, NULL, &num_platforms);
if (err) {
print_error(err, "clGetPlatformIDs failed");
test_finish();
return -1;
return EXIT_FAILURE;
}
platforms = (cl_platform_id *) malloc( num_platforms * sizeof( cl_platform_id ) );
if (!platforms || choosen_platform_index >= num_platforms) {
log_error( "platform index out of range -- choosen_platform_index (%d) >= num_platforms (%d)\n", choosen_platform_index, num_platforms );
test_finish();
return -1;
return EXIT_FAILURE;
}
BufferOwningPtr<cl_platform_id> platformsBuf(platforms);
err = clGetPlatformIDs(num_platforms, platforms, NULL);
if (err) {
print_error(err, "clGetPlatformIDs failed");
test_finish();
return -1;
return EXIT_FAILURE;
}
/* Get the number of requested devices */
err = clGetDeviceIDs(platforms[choosen_platform_index], device_type, 0, NULL, &num_devices );
if (err) {
print_error(err, "clGetDeviceIDs failed");
test_finish();
return -1;
return EXIT_FAILURE;
}
devices = (cl_device_id *) malloc( num_devices * sizeof( cl_device_id ) );
if (!devices || choosen_device_index >= num_devices) {
log_error( "device index out of range -- choosen_device_index (%d) >= num_devices (%d)\n", choosen_device_index, num_devices );
test_finish();
return -1;
return EXIT_FAILURE;
}
BufferOwningPtr<cl_device_id> devicesBuf(devices);
@@ -317,24 +344,28 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
err = clGetDeviceIDs(platforms[choosen_platform_index], device_type, num_devices, devices, NULL );
if (err) {
print_error(err, "clGetDeviceIDs failed");
test_finish();
return -1;
return EXIT_FAILURE;
}
device = devices[choosen_device_index];
err = clGetDeviceInfo( device, CL_DEVICE_TYPE, sizeof(gDeviceType), &gDeviceType, NULL );
if( err )
{
print_error( err, "Unable to get device type" );
return TEST_FAIL;
}
if( printDeviceHeader( device ) != CL_SUCCESS )
{
test_finish();
return -1;
return EXIT_FAILURE;
}
cl_device_fp_config fpconfig = 0;
err = clGetDeviceInfo( device, CL_DEVICE_SINGLE_FP_CONFIG, sizeof( fpconfig ), &fpconfig, NULL );
if (err) {
print_error(err, "clGetDeviceInfo for CL_DEVICE_SINGLE_FP_CONFIG failed");
test_finish();
return -1;
return EXIT_FAILURE;
}
gFlushDenormsToZero = ( 0 == (fpconfig & CL_FP_DENORM));
@@ -347,8 +378,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
if (err)
{
print_error(err, "clGetDeviceInfo for CL_DEVICE_PROFILE failed\n" );
test_finish();
return -1;
return EXIT_FAILURE;
}
gIsEmbedded = NULL != strstr(profile, "EMBEDDED_PROFILE");
@@ -358,8 +388,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
if (err)
{
print_error(err, "clGetDeviceInfo for CL_DEVICE_SINGLE_FP_CONFIG failed\n");
test_finish();
return -1;
return EXIT_FAILURE;
}
// Check for problems that only embedded will have
@@ -370,37 +399,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
gInfNanSupport = 0;
// check the extensions list to see if ulong and long are supported
size_t extensionsStringSize = 0;
if( (err = clGetDeviceInfo( device, CL_DEVICE_EXTENSIONS, 0, NULL, &extensionsStringSize ) ))
{
print_error( err, "Unable to get extensions string size for embedded device" );
test_finish();
return -1;
}
char *extensions_string = (char*) malloc(extensionsStringSize);
if( NULL == extensions_string )
{
print_error( CL_OUT_OF_HOST_MEMORY, "Unable to allocate storage for extensions string for embedded device" );
test_finish();
return -1;
}
BufferOwningPtr<char> extensions_stringBuf(extensions_string);
if( (err = clGetDeviceInfo( device, CL_DEVICE_EXTENSIONS, extensionsStringSize, extensions_string, NULL ) ))
{
print_error( err, "Unable to get extensions string for embedded device" );
test_finish();
return -1;
}
if( extensions_string[extensionsStringSize-1] != '\0' )
{
log_error( "FAILURE: extensions string for embedded device is not NUL terminated" );
test_finish();
return -1;
}
if( NULL == strstr( extensions_string, "cles_khr_int64" ))
if( !is_extension_available(device, "cles_khr_int64" ))
gHasLong = 0;
}
@@ -413,8 +412,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
if( (err = clGetDeviceInfo( device, CL_DEVICE_OPENCL_C_VERSION, sizeof(c_version), c_version, NULL )) )
{
log_error( "FAILURE: unable to get CL_DEVICE_OPENCL_C_VERSION on 1.0 device. (%d)\n", err );
test_finish();
return -1;
return EXIT_FAILURE;
}
if( 0 == strncmp( c_version, "OpenCL C 1.0 ", strlen( "OpenCL C 1.0 " ) ) )
@@ -430,18 +428,28 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
if( (err = clGetDeviceInfo( device, CL_DEVICE_ADDRESS_BITS, sizeof( device_address_bits ), &device_address_bits, NULL ) ))
{
print_error( err, "Unable to obtain device address bits" );
test_finish();
return -1;
return EXIT_FAILURE;
}
if( device_address_bits )
log_info( "sizeof( void*) = %d (device)\n", device_address_bits/8 );
else
{
log_error("Invalid device address bit size returned by device.\n");
test_finish();
return -1;
return EXIT_FAILURE;
}
if (gCompilationMode == kSpir_v)
{
test_status spirv_readiness = check_spirv_compilation_readiness(device);
if (spirv_readiness != TEST_PASS)
{
switch (spirv_readiness)
{
case TEST_PASS: break;
case TEST_FAIL: return fail_init_info(testNum);
case TEST_SKIP: return skip_init_info(testNum);
}
}
}
/* If we have a device checking function, run it */
if( ( deviceCheckFn != NULL ) )
@@ -452,9 +460,9 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
case TEST_PASS:
break;
case TEST_FAIL:
return 1;
return fail_init_info(testNum);
case TEST_SKIP:
return 0;
return skip_init_info(testNum);
}
}
@@ -480,7 +488,7 @@ int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_def
RestoreFPState( &oldMode );
#endif
return error;
return (error == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
static int find_matching_tests( test_definition testList[], unsigned char selectedTestList[], int testNum,
@@ -526,7 +534,7 @@ static int find_matching_tests( test_definition testList[], unsigned char select
}
static int saveResultsToJson( const char *fileName, const char *suiteName, test_definition testList[],
unsigned char selectedTestList[], int resultTestList[], int testNum )
unsigned char selectedTestList[], test_status resultTestList[], int testNum )
{
FILE *file = fopen( fileName, "w" );
if( NULL == file )
@@ -536,7 +544,7 @@ static int saveResultsToJson( const char *fileName, const char *suiteName, test_
}
const char *save_map[] = { "success", "failure" };
const char *result_map[] = { "pass", "fail" };
const char *result_map[] = { "pass", "fail", "skip" };
const char *linebreak[] = { "", ",\n" };
int add_linebreak = 0;
@@ -548,7 +556,7 @@ static int saveResultsToJson( const char *fileName, const char *suiteName, test_
{
if( selectedTestList[i] )
{
fprintf( file, "%s\t\t\"%s\": \"%s\"", linebreak[add_linebreak], testList[i].name, result_map[(bool)resultTestList[i]] );
fprintf( file, "%s\t\t\"%s\": \"%s\"", linebreak[add_linebreak], testList[i].name, result_map[(int)resultTestList[i]] );
add_linebreak = 1;
}
}
@@ -564,6 +572,37 @@ static int saveResultsToJson( const char *fileName, const char *suiteName, test_
return ret;
}
static void print_results( int failed, int count, const char* name )
{
if( count < failed )
{
count = failed;
}
if( failed == 0 )
{
if( count > 1 )
{
log_info( "PASSED %d of %d %ss.\n", count, count, name );
}
else
{
log_info( "PASSED %s.\n", name );
}
}
else if( failed > 0 )
{
if( count > 1 )
{
log_error( "FAILED %d of %d %ss.\n", failed, count, name );
}
else
{
log_error( "FAILED %s.\n", name );
}
}
}
int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device_id device, int testNum,
test_definition testList[], int forceNoContextCreation,
cl_command_queue_properties queueProps, int num_elements )
@@ -571,7 +610,7 @@ int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device_id dev
int ret = EXIT_SUCCESS;
unsigned char *selectedTestList = ( unsigned char* ) calloc( testNum, 1 );
int *resultTestList = NULL;
test_status *resultTestList = NULL;
if( argc == 1 )
{
@@ -608,74 +647,39 @@ int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device_id dev
if( ret == EXIT_SUCCESS )
{
resultTestList = ( int* ) calloc( testNum, sizeof(int) );
resultTestList = ( test_status* ) calloc( testNum, sizeof(*resultTestList) );
ret = callTestFunctions( testList, selectedTestList, resultTestList, testNum, device, forceNoContextCreation, num_elements, queueProps );
callTestFunctions( testList, selectedTestList, resultTestList, testNum, device,
forceNoContextCreation, num_elements, queueProps );
if( gTestsFailed == 0 )
{
if( gTestsPassed > 1 )
{
log_info("PASSED %d of %d tests.\n", gTestsPassed, gTestsPassed);
}
else if( gTestsPassed > 0 )
{
log_info("PASSED test.\n");
}
}
else if( gTestsFailed > 0 )
{
if( gTestsFailed+gTestsPassed > 1 )
{
log_error("FAILED %d of %d tests.\n", gTestsFailed, gTestsFailed+gTestsPassed);
}
else
{
log_error("FAILED test.\n");
}
}
print_results( gFailCount, gTestCount, "sub-test" );
print_results( gTestsFailed, gTestsFailed + gTestsPassed, "test" );
char *filename = getenv( "CL_CONFORMANCE_RESULTS_FILENAME" );
if( filename != NULL )
{
ret += saveResultsToJson( filename, argv[0], testList, selectedTestList, resultTestList, testNum );
ret = saveResultsToJson( filename, argv[0], testList, selectedTestList, resultTestList, testNum );
}
}
test_finish();
free( selectedTestList );
free( resultTestList );
return ret;
}
int callTestFunctions( test_definition testList[], unsigned char selectedTestList[], int resultTestList[],
int testNum, cl_device_id deviceToUse, int forceNoContextCreation, int numElementsToUse,
cl_command_queue_properties queueProps )
void callTestFunctions( test_definition testList[], unsigned char selectedTestList[], test_status resultTestList[],
int testNum, cl_device_id deviceToUse, int forceNoContextCreation, int numElementsToUse,
cl_command_queue_properties queueProps )
{
int totalErrors = 0;
for( int i = 0; i < testNum; ++i )
{
if( selectedTestList[i] )
{
// Skip unimplemented test (can happen when you select all of the tests)
if( testList[i].func != NULL )
{
int errors = callSingleTestFunction( testList[i], deviceToUse, forceNoContextCreation,
numElementsToUse, queueProps );
resultTestList[i] = errors;
totalErrors += errors;
}
else
{
log_info( "Skipping %s. Test currently not implemented.\n", testList[i].name );
}
resultTestList[i] = callSingleTestFunction( testList[i], deviceToUse, forceNoContextCreation,
numElementsToUse, queueProps );
}
}
return totalErrors;
}
void CL_CALLBACK notify_callback(const char *errinfo, const void *private_info, size_t cb, void *user_data)
@@ -684,15 +688,25 @@ void CL_CALLBACK notify_callback(const char *errinfo, const void *private_info,
}
// Actual function execution
int callSingleTestFunction( test_definition test, cl_device_id deviceToUse, int forceNoContextCreation,
int numElementsToUse, const cl_queue_properties queueProps )
test_status callSingleTestFunction( test_definition test, cl_device_id deviceToUse, int forceNoContextCreation,
int numElementsToUse, const cl_queue_properties queueProps )
{
int numErrors = 0, ret;
test_status status;
cl_int error;
cl_context context = NULL;
cl_command_queue queue = NULL;
const cl_command_queue_properties cmd_queueProps = (queueProps)?CL_QUEUE_PROPERTIES:0;
cl_command_queue_properties queueCreateProps[] = {cmd_queueProps, queueProps, 0};
log_info( "%s...\n", test.name );
fflush( stdout );
const Version device_version = get_device_cl_version(deviceToUse);
if (test.min_version > device_version)
{
version_expected_info(test.name, "OpenCL",
test.min_version.to_string().c_str(),
device_version.to_string().c_str());
return TEST_SKIP;
}
/* Create a context to work with, unless we're told not to */
if( !forceNoContextCreation )
@@ -701,45 +715,63 @@ int callSingleTestFunction( test_definition test, cl_device_id deviceToUse, int
if (!context)
{
print_error( error, "Unable to create testing context" );
return 1;
return TEST_FAIL;
}
if (device_version < Version(2, 0)) {
queue = clCreateCommandQueue(context, deviceToUse, queueProps, &error);
} else {
const cl_command_queue_properties cmd_queueProps = (queueProps)?CL_QUEUE_PROPERTIES:0;
cl_command_queue_properties queueCreateProps[] = {cmd_queueProps, queueProps, 0};
queue = clCreateCommandQueueWithProperties( context, deviceToUse, &queueCreateProps[0], &error );
}
queue = clCreateCommandQueueWithProperties( context, deviceToUse, &queueCreateProps[0], &error );
if( queue == NULL )
{
print_error( error, "Unable to create testing command queue" );
return 1;
return TEST_FAIL;
}
}
/* Run the test and print the result */
log_info( "%s...\n", test.name );
fflush( stdout );
error = check_opencl_version_with_testname(test.name, deviceToUse);
test_missing_feature(error, test.name);
error = check_functions_for_offline_compiler(test.name, deviceToUse);
test_missing_support_offline_cmpiler(error, test.name);
ret = test.func(deviceToUse, context, queue, numElementsToUse); //test_threaded_function( ptr_basefn_list[i], group, context, num_elements);
if( ret == TEST_NOT_IMPLEMENTED )
if( test.func == NULL )
{
/* Tests can also let us know they're not implemented yet */
log_info("%s test currently not implemented\n\n", test.name);
// Skip unimplemented test, can happen when all of the tests are selected
log_info("%s test currently not implemented\n", test.name);
status = TEST_SKIP;
}
else
{
/* Print result */
if( ret == 0 ) {
log_info( "%s passed\n", test.name );
gTestsPassed++;
int ret = test.func(deviceToUse, context, queue, numElementsToUse); //test_threaded_function( ptr_basefn_list[i], group, context, num_elements);
if( ret == TEST_NOT_IMPLEMENTED )
{
/* Tests can also let us know they're not implemented yet */
log_info("%s test currently not implemented\n", test.name);
status = TEST_SKIP;
}
else if (ret == TEST_SKIPPED_ITSELF)
{
/* Tests can also let us know they're not supported by the implementation */
log_info("%s test not supported\n", test.name);
status = TEST_SKIP;
}
else
{
numErrors++;
log_error( "%s FAILED\n", test.name );
gTestsFailed++;
/* Print result */
if( ret == 0 ) {
log_info( "%s passed\n", test.name );
gTestsPassed++;
status = TEST_PASS;
}
else
{
log_error( "%s FAILED\n", test.name );
gTestsFailed++;
status = TEST_FAIL;
}
}
}
@@ -749,55 +781,13 @@ int callSingleTestFunction( test_definition test, cl_device_id deviceToUse, int
int error = clFinish(queue);
if (error) {
log_error("clFinish failed: %d", error);
numErrors++;
status = TEST_FAIL;
}
clReleaseCommandQueue( queue );
clReleaseContext( context );
}
return numErrors;
}
void checkDeviceTypeOverride( cl_device_type *inOutType )
{
/* Check if we are forced to CPU mode */
char *force_cpu = getenv( "CL_DEVICE_TYPE" );
if( force_cpu != NULL )
{
if( strcmp( force_cpu, "gpu" ) == 0 || strcmp( force_cpu, "CL_DEVICE_TYPE_GPU" ) == 0 )
*inOutType = CL_DEVICE_TYPE_GPU;
else if( strcmp( force_cpu, "cpu" ) == 0 || strcmp( force_cpu, "CL_DEVICE_TYPE_CPU" ) == 0 )
*inOutType = CL_DEVICE_TYPE_CPU;
else if( strcmp( force_cpu, "accelerator" ) == 0 || strcmp( force_cpu, "CL_DEVICE_TYPE_ACCELERATOR" ) == 0 )
*inOutType = CL_DEVICE_TYPE_ACCELERATOR;
else if( strcmp( force_cpu, "CL_DEVICE_TYPE_DEFAULT" ) == 0 )
*inOutType = CL_DEVICE_TYPE_DEFAULT;
}
switch( *inOutType )
{
case CL_DEVICE_TYPE_GPU: log_info( "Requesting GPU device " ); break;
case CL_DEVICE_TYPE_CPU: log_info( "Requesting CPU device " ); break;
case CL_DEVICE_TYPE_ACCELERATOR: log_info( "Requesting Accelerator device " ); break;
case CL_DEVICE_TYPE_DEFAULT: log_info( "Requesting Default device " ); break;
default: break;
}
log_info( force_cpu != NULL ? "based on environment variable\n" : "based on command line\n" );
#if defined( __APPLE__ )
{
// report on any unusual library search path indirection
char *libSearchPath = getenv( "DYLD_LIBRARY_PATH");
if( libSearchPath )
log_info( "*** DYLD_LIBRARY_PATH = \"%s\"\n", libSearchPath );
// report on any unusual framework search path indirection
char *frameworkSearchPath = getenv( "DYLD_FRAMEWORK_PATH");
if( libSearchPath )
log_info( "*** DYLD_FRAMEWORK_PATH = \"%s\"\n", frameworkSearchPath );
}
#endif
return status;
}
#if ! defined( __APPLE__ )
@@ -891,3 +881,244 @@ cl_device_id GetOpposingDevice( cl_device_id device )
// Should never get here
return NULL;
}
Version get_device_cl_version(cl_device_id device)
{
size_t str_size;
cl_int err = clGetDeviceInfo(device, CL_DEVICE_VERSION, 0, NULL, &str_size);
ASSERT_SUCCESS(err, "clGetDeviceInfo");
std::vector<char> str(str_size);
err = clGetDeviceInfo(device, CL_DEVICE_VERSION, str_size, str.data(), NULL);
ASSERT_SUCCESS(err, "clGetDeviceInfo");
if (strstr(str.data(), "OpenCL 1.0") != NULL)
return Version(1, 0);
else if (strstr(str.data(), "OpenCL 1.1") != NULL)
return Version(1, 1);
else if (strstr(str.data(), "OpenCL 1.2") != NULL)
return Version(1, 2);
else if (strstr(str.data(), "OpenCL 2.0") != NULL)
return Version(2, 0);
else if (strstr(str.data(), "OpenCL 2.1") != NULL)
return Version(2, 1);
else if (strstr(str.data(), "OpenCL 2.2") != NULL)
return Version(2, 2);
else if (strstr(str.data(), "OpenCL 3.0") != NULL)
return Version(3, 0);
throw std::runtime_error(std::string("Unknown OpenCL version: ") + str.data());
}
bool check_device_spirv_version_reported(cl_device_id device)
{
size_t str_size;
cl_int err;
std::vector<char> str;
if (gCoreILProgram)
{
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, 0, NULL, &str_size);
if (err != CL_SUCCESS)
{
log_error(
"clGetDeviceInfo: cannot read CL_DEVICE_IL_VERSION size;");
return false;
}
str.resize(str_size);
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, str_size,
str.data(), NULL);
if (err != CL_SUCCESS)
{
log_error(
"clGetDeviceInfo: cannot read CL_DEVICE_IL_VERSION value;");
return false;
}
}
else
{
cl_int err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION_KHR, 0, NULL,
&str_size);
if (err != CL_SUCCESS)
{
log_error(
"clGetDeviceInfo: cannot read CL_DEVICE_IL_VERSION_KHR size;");
return false;
}
str.resize(str_size);
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION_KHR, str_size,
str.data(), NULL);
if (err != CL_SUCCESS)
{
log_error(
"clGetDeviceInfo: cannot read CL_DEVICE_IL_VERSION_KHR value;");
return false;
}
}
if (strstr(str.data(), "SPIR-V") == NULL)
{
log_info("This device does not support SPIR-V offline compilation.\n");
return false;
}
else
{
Version spirv_version = get_device_spirv_il_version(device);
log_info("This device supports SPIR-V offline compilation. SPIR-V "
"version is %s\n",
spirv_version.to_string().c_str());
}
return true;
}
Version get_device_spirv_il_version(cl_device_id device)
{
size_t str_size;
cl_int err;
std::vector<char> str;
if (gCoreILProgram)
{
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, 0, NULL, &str_size);
ASSERT_SUCCESS(err, "clGetDeviceInfo");
str.resize(str_size);
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION, str_size,
str.data(), NULL);
ASSERT_SUCCESS(err, "clGetDeviceInfo");
}
else
{
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION_KHR, 0, NULL,
&str_size);
ASSERT_SUCCESS(err, "clGetDeviceInfo");
str.resize(str_size);
err = clGetDeviceInfo(device, CL_DEVICE_IL_VERSION_KHR, str_size,
str.data(), NULL);
ASSERT_SUCCESS(err, "clGetDeviceInfo");
}
if (strstr(str.data(), "SPIR-V_1.0") != NULL)
return Version(1, 0);
else if (strstr(str.data(), "SPIR-V_1.1") != NULL)
return Version(1, 1);
else if (strstr(str.data(), "SPIR-V_1.2") != NULL)
return Version(1, 2);
else if (strstr(str.data(), "SPIR-V_1.3") != NULL)
return Version(1, 3);
else if (strstr(str.data(), "SPIR-V_1.4") != NULL)
return Version(1, 4);
else if (strstr(str.data(), "SPIR-V_1.5") != NULL)
return Version(1, 5);
throw std::runtime_error(std::string("Unknown SPIR-V version: ")
+ str.data());
}
test_status check_spirv_compilation_readiness(cl_device_id device)
{
auto ocl_version = get_device_cl_version(device);
auto ocl_expected_min_version = Version(2, 1);
if (ocl_version < ocl_expected_min_version)
{
if (is_extension_available(device, "cl_khr_il_program"))
{
gCoreILProgram = false;
bool spirv_supported = check_device_spirv_version_reported(device);
if (spirv_supported == false)
{
log_error("SPIR-V intermediate language not supported !!! "
"OpenCL %s requires support.\n",
ocl_version.to_string().c_str());
return TEST_FAIL;
}
else
{
return TEST_PASS;
}
}
else
{
log_error("SPIR-V intermediate language support on OpenCL version "
"%s requires cl_khr_il_program extension.\n",
ocl_version.to_string().c_str());
return TEST_SKIP;
}
}
bool spirv_supported = check_device_spirv_version_reported(device);
if (ocl_version >= ocl_expected_min_version && ocl_version <= Version(2, 2))
{
if (spirv_supported == false)
{
log_error("SPIR-V intermediate language not supported !!! OpenCL "
"%s requires support.\n",
ocl_version.to_string().c_str());
return TEST_FAIL;
}
}
if (ocl_version > Version(2, 2))
{
if (spirv_supported == false)
{
log_info("SPIR-V intermediate language not supported in OpenCL %s. "
"Test skipped.\n",
ocl_version.to_string().c_str());
return TEST_SKIP;
}
}
return TEST_PASS;
}
void PrintArch( void )
{
vlog( "sizeof( void*) = %ld\n", sizeof( void *) );
#if defined( __ppc__ )
vlog( "ARCH:\tppc\n" );
#elif defined( __ppc64__ )
vlog( "ARCH:\tppc64\n" );
#elif defined( __PPC__ )
vlog( "ARCH:\tppc\n" );
#elif defined( __i386__ )
vlog( "ARCH:\ti386\n" );
#elif defined( __x86_64__ )
vlog( "ARCH:\tx86_64\n" );
#elif defined( __arm__ )
vlog( "ARCH:\tarm\n" );
#elif defined(__aarch64__)
vlog( "ARCH:\taarch64\n" );
#elif defined (_WIN32)
vlog( "ARCH:\tWindows\n" );
#else
#error unknown arch
#endif
#if defined( __APPLE__ )
int type = 0;
size_t typeSize = sizeof( type );
sysctlbyname( "hw.cputype", &type, &typeSize, NULL, 0 );
vlog( "cpu type:\t%d\n", type );
typeSize = sizeof( type );
sysctlbyname( "hw.cpusubtype", &type, &typeSize, NULL, 0 );
vlog( "cpu subtype:\t%d\n", type );
#elif defined( __linux__ )
struct utsname buffer;
if (uname(&buffer) != 0) {
vlog("uname error");
}
else {
vlog("system name = %s\n", buffer.sysname);
vlog("node name = %s\n", buffer.nodename);
vlog("release = %s\n", buffer.release);
vlog("version = %s\n", buffer.version);
vlog("machine = %s\n", buffer.machine);
}
#endif
}

View File

@@ -1,5 +1,5 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2017-2019 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.
@@ -18,15 +18,48 @@
#include "threadTesting.h"
#include "clImageHelper.h"
#include <string>
#include <sstream>
#include <string>
#ifdef __cplusplus
extern "C" {
#endif
class Version
{
public:
Version() : m_major(0), m_minor(0) {}
Version(int major, int minor) : m_major(major), m_minor(minor) {}
bool operator>(const Version& rhs) const { return to_int() > rhs.to_int(); }
bool operator<(const Version& rhs) const { return to_int() < rhs.to_int(); }
bool operator<=(const Version& rhs) const { return to_int() <= rhs.to_int(); }
bool operator>=(const Version& rhs) const { return to_int() >= rhs.to_int(); }
bool operator==(const Version& rhs) const { return to_int() == rhs.to_int(); }
int to_int() const { return m_major * 10 + m_minor; }
std::string to_string() const
{
std::stringstream ss;
ss << m_major << "." << m_minor;
return ss.str();
}
#define ADD_TEST(fn) {test_##fn, #fn}
#define NOT_IMPLEMENTED_TEST(fn) {NULL, #fn}
private:
int m_major;
int m_minor;
};
Version get_device_cl_version(cl_device_id device);
#define ADD_TEST(fn) \
{ \
test_##fn, #fn, Version(1, 0) \
}
#define ADD_TEST_VERSION(fn, ver) \
{ \
test_##fn, #fn, ver \
}
#define NOT_IMPLEMENTED_TEST(fn) \
{ \
NULL, #fn, Version(0, 0) \
}
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
@@ -34,6 +67,7 @@ typedef struct test_definition
{
basefn func;
const char* name;
Version min_version;
} test_definition;
@@ -44,11 +78,15 @@ typedef enum test_status
TEST_SKIP = 2,
} test_status;
extern int gFailCount;
extern int gTestCount;
extern cl_uint gReSeed;
extern cl_uint gRandomSeed;
// Supply a list of functions to test here. This will allocate a CL device, create a context, all that
// setup work, and then call each function in turn as dictatated by the passed arguments.
// Returns EXIT_SUCCESS iff all tests succeeded or the tests were listed,
// otherwise return EXIT_FAILURE.
extern int runTestHarness( int argc, const char *argv[], int testNum, test_definition testList[],
int imageSupportRequired, int forceNoContextCreation, cl_command_queue_properties queueProps );
@@ -56,9 +94,11 @@ extern int runTestHarness( int argc, const char *argv[], int testNum, test_defin
typedef test_status (*DeviceCheckFn)( cl_device_id device );
// Same as runTestHarness, but also supplies a function that checks the created device for required functionality.
// Returns EXIT_SUCCESS iff all tests succeeded or the tests were listed,
// otherwise return EXIT_FAILURE.
extern int runTestHarnessWithCheck( int argc, const char *argv[], int testNum, test_definition testList[],
int imageSupportRequired, int forceNoContextCreation,
cl_command_queue_properties queueProps, DeviceCheckFn deviceCheckFn );
int forceNoContextCreation, cl_command_queue_properties queueProps,
DeviceCheckFn deviceCheckFn );
// The command line parser used by runTestHarness to break up parameters into calls to callTestFunctions
extern int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device_id device, int testNum,
@@ -70,24 +110,20 @@ extern int parseAndCallCommandLineTests( int argc, const char *argv[], cl_device
// testList is the data structure that contains test functions and its names
// selectedTestList is an array of integers (treated as bools) which tell which function is to be called,
// each element at index i, corresponds to the element in testList at index i
// resultTestList is an array of integers which contains the result of each selected test
// resultTestList is an array of statuses which contain the result of each selected test
// testNum is the number of tests in testList, selectedTestList and resultTestList
// contextProps are used to create a testing context for each test
// deviceToUse and numElementsToUse are all just passed to each test function
extern int callTestFunctions( test_definition testList[], unsigned char selectedTestList[], int resultTestList[],
int testNum, cl_device_id deviceToUse, int forceNoContextCreation, int numElementsToUse,
cl_command_queue_properties queueProps );
extern void callTestFunctions( test_definition testList[], unsigned char selectedTestList[], test_status resultTestList[],
int testNum, cl_device_id deviceToUse, int forceNoContextCreation, int numElementsToUse,
cl_command_queue_properties queueProps );
// This function is called by callTestFunctions, once per function, to do setup, call, logging and cleanup
extern int callSingleTestFunction( test_definition test, cl_device_id deviceToUse, int forceNoContextCreation,
int numElementsToUse, cl_command_queue_properties queueProps );
extern test_status callSingleTestFunction( test_definition test, cl_device_id deviceToUse, int forceNoContextCreation,
int numElementsToUse, cl_command_queue_properties queueProps );
///// Miscellaneous steps
// Given a pre-existing device type choice, check the environment for an override, then print what
// choice was made and how (and return the overridden choice, if there is one)
extern void checkDeviceTypeOverride( cl_device_type *inOutType );
// standard callback function for context pfn_notify
extern void CL_CALLBACK notify_callback(const char *errinfo, const void *private_info, size_t cb, void *user_data);
@@ -99,20 +135,27 @@ extern cl_device_type GetDeviceType( cl_device_id );
// is the only device available, the SAME device is returned, so check!
extern cl_device_id GetOpposingDevice( cl_device_id device );
Version get_device_spirv_il_version(cl_device_id device);
bool check_device_spirv_il_support(cl_device_id device);
void version_expected_info(const char *test_name, const char *api_name,
const char *expected_version,
const char *device_version);
test_status check_spirv_compilation_readiness(cl_device_id device);
extern int gFlushDenormsToZero; // This is set to 1 if the device does not support denorms (CL_FP_DENORM)
extern int gInfNanSupport; // This is set to 1 if the device supports infinities and NaNs
extern int gIsEmbedded; // This is set to 1 if the device is an embedded device
extern int gHasLong; // This is set to 1 if the device suppots long and ulong types in OpenCL C.
extern int gIsOpenCL_C_1_0_Device; // This is set to 1 if the device supports only OpenCL C 1.0.
extern bool gCoreILProgram;
#if ! defined( __APPLE__ )
void memset_pattern4(void *, const void *, size_t);
#endif
#ifdef __cplusplus
}
#endif
extern void PrintArch(void);
#endif // _testHarness_h

View File

@@ -23,6 +23,7 @@
#endif
#define TEST_NOT_IMPLEMENTED -99
#define TEST_SKIPPED_ITSELF -100
typedef int (*basefn)(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_threaded_function( basefn fnToTest, cl_device_id device, cl_context context, cl_command_queue queue, int numElements );

View File

@@ -390,7 +390,8 @@ cl_int clProtectedImage::Create( cl_context context, cl_mem_object_type imageTyp
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
break;
case CL_MEM_OBJECT_IMAGE3D:
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );;
image = create_image_3d(context, mem_flags, fmt, width, height,
depth, 0, 0, NULL, &error);
break;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
image = create_image_1d_array( context, mem_flags, fmt, width, arraySize, 0, 0, NULL, &error );
@@ -413,7 +414,8 @@ cl_int clProtectedImage::Create( cl_context context, cl_mem_object_type imageTyp
image = create_image_2d( context, mem_flags, fmt, width, height, 0, NULL, &error );
break;
case CL_MEM_OBJECT_IMAGE3D:
image = create_image_3d( context, mem_flags, fmt, width, height, depth, 0, 0, NULL, &error );;
image = create_image_3d(context, mem_flags, fmt, width, height,
depth, 0, 0, NULL, &error);
break;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
image = create_image_1d_array( context, mem_flags, fmt, width, arraySize, 0, 0, NULL, &error );

View File

@@ -29,9 +29,6 @@
#include "errorHelpers.h"
#include "kernelHelpers.h"
extern "C" cl_uint gReSeed;
extern "C" cl_uint gRandomSeed;
/* cl_context wrapper */
class clContextWrapper

View File

@@ -1,13 +1,9 @@
set_source_files_properties(COMPILE_FLAGS -msse2)
string(TOLOWER ${MODULE_NAME} MODULE_NAME_LOWER)
set(${MODULE_NAME}_OUT ${CONFORMANCE_PREFIX}${MODULE_NAME_LOWER}${CONFORMANCE_SUFFIX})
add_executable(${${MODULE_NAME}_OUT} ${${MODULE_NAME}_SOURCES})
set_source_files_properties(${${MODULE_NAME}_SOURCES} PROPERTIES LANGUAGE CXX)
set_property(TARGET ${${MODULE_NAME}_OUT} PROPERTY FOLDER "CONFORMANCE${CONFORMANCE_SUFFIX}")
TARGET_LINK_LIBRARIES(${${MODULE_NAME}_OUT} ${CLConform_LIBRARIES})
TARGET_LINK_LIBRARIES(${${MODULE_NAME}_OUT} ${HARNESS_LIB} ${CLConform_LIBRARIES})

View File

@@ -1,13 +1,14 @@
# Remember current source directory (`test_conformance').
set( CLConf_Install_Base_Dir "${CMAKE_CURRENT_SOURCE_DIR}" )
set(HARNESS_LIB harness)
add_subdirectory( allocations )
add_subdirectory( api )
add_subdirectory( atomics )
add_subdirectory( basic )
add_subdirectory( buffers )
add_subdirectory( commonfns )
add_subdirectory( compatibility )
add_subdirectory( compiler )
add_subdirectory( computeinfo )
add_subdirectory( contractions )
@@ -28,7 +29,6 @@ if(GLES_IS_SUPPORTED)
add_subdirectory(gles)
endif(GLES_IS_SUPPORTED)
add_subdirectory( half )
add_subdirectory( headers )
add_subdirectory( images )
add_subdirectory( integer_ops )
add_subdirectory( math_brute_force )
@@ -39,8 +39,7 @@ add_subdirectory( profiling )
add_subdirectory( relationals )
add_subdirectory( select )
add_subdirectory( thread_dimensions )
add_subdirectory( vec_align )
add_subdirectory( vec_step )
add_subdirectory( vectors )
add_subdirectory( c11_atomics )
add_subdirectory( device_execution )
add_subdirectory( non_uniform_work_group )
@@ -51,26 +50,17 @@ add_subdirectory( workgroups )
add_subdirectory( pipes )
add_subdirectory( device_timer )
add_subdirectory( clcpp )
add_subdirectory( spirv_new )
add_subdirectory( spir )
set(CSV_FILES
opencl_conformance_tests_21_full_spirv.csv
opencl_conformance_tests_21_legacy_wimpy.csv
opencl_conformance_tests_22.csv
opencl_conformance_tests_generate_spirv.csv
opencl_conformance_tests_conversions.csv
opencl_conformance_tests_d3d.csv
opencl_conformance_tests_full.csv
opencl_conformance_tests_full_no_math_or_conversions.csv
opencl_conformance_tests_math.csv
opencl_conformance_tests_quick.csv
)
set(PY_FILES
run_conformance.py
)
file(GLOB CSV_FILES "opencl_conformance_tests_*.csv")
set(PY_FILES run_conformance.py)
# Copy .csv files
foreach(FILE ${CSV_FILES})
configure_file(${FILE} ${FILE} COPYONLY)
get_filename_component(strippedName ${FILE} NAME)
configure_file(${strippedName} ${strippedName} COPYONLY)
endforeach()
# Copy test run script
@@ -89,4 +79,4 @@ foreach(FILE ${PY_FILES})
endforeach()
foreach(FILE test_conformance/${PY_FILES})
endforeach()
endforeach()

View File

@@ -16,13 +16,6 @@ set(${MODULE_NAME}_SOURCES
test_shared_address_space_fine_grain_buffers.cpp
test_shared_sub_buffers.cpp
test_migrate.cpp
../../test_common/harness/testHarness.c
../../test_common/harness/errorHelpers.c
../../test_common/harness/kernelHelpers.c
../../test_common/harness/mt19937.c
../../test_common/harness/msvc9.c
../../test_common/harness/parseParameters.cpp
../../test_common/harness/crc32.c
)
include(../CMakeCommon.txt)

View File

@@ -16,11 +16,13 @@
#ifndef __COMMON_H__
#define __COMMON_H__
#include "../../test_common/harness/compat.h"
#include "../../test_common/harness/testHarness.h"
#include "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/typeWrappers.h"
#include "harness/compat.h"
#include "harness/testHarness.h"
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/typeWrappers.h"
#include <vector>
#include <string>
#if (defined(_WIN32) || defined(_WIN64)) && defined(_MSC_VER)
#include <windows.h>
@@ -44,7 +46,8 @@ bool AtomicCompareExchangeStrongExplicit(volatile T *a, T *expected, T desired,
{
T tmp;
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
tmp = (T)InterlockedCompareExchange((volatile LONG *)a, (LONG)desired, *(LONG *)expected);
tmp = (sizeof(void*) == 8) ? (T)InterlockedCompareExchange64((volatile LONG64 *)a, (LONG64)desired, *(LONG64 *)expected) :
(T)InterlockedCompareExchange((volatile LONG*)a, (LONG)desired, *(LONG*)expected);
#elif defined(__GNUC__)
tmp = (T)__sync_val_compare_and_swap((volatile intptr_t*)a, (intptr_t)(*expected), (intptr_t)desired);
#else
@@ -93,7 +96,7 @@ extern int test_svm_shared_sub_buffers(cl_device_id deviceID, cl_context cont
extern int test_svm_enqueue_api(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_svm_migrate(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeString, cl_context* context, cl_program *program, cl_command_queue *queues, cl_uint *num_devices, cl_device_svm_capabilities required_svm_caps);
extern cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeString, cl_context* context, cl_program *program, cl_command_queue *queues, cl_uint *num_devices, cl_device_svm_capabilities required_svm_caps, std::vector<std::string> extensions_list = std::vector<std::string>());
extern const char *linked_list_create_and_verify_kernels[];

View File

@@ -13,13 +13,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/compat.h"
#include "harness/compat.h"
#include <stdio.h>
#include <vector>
#include <sstream>
#include "../../test_common/harness/testHarness.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "harness/testHarness.h"
#include "harness/kernelHelpers.h"
#include "common.h"
@@ -168,7 +168,7 @@ cl_int verify_linked_lists(Node* pNodes, size_t num_lists, int list_length)
// Note that we don't use the context provided by the test harness since it doesn't support multiple devices,
// so we create are own context here that has all devices, we use the same platform that the harness used.
cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeString, cl_context* context, cl_program *program, cl_command_queue *queues, cl_uint *num_devices, cl_device_svm_capabilities required_svm_caps)
cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeString, cl_context* context, cl_program *program, cl_command_queue *queues, cl_uint *num_devices, cl_device_svm_capabilities required_svm_caps, std::vector<std::string> extensions_list)
{
cl_int error;
@@ -198,30 +198,9 @@ cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeSt
cl_uint num_capable_devices = 0;
for(cl_uint i = 0; i < *num_devices; i++)
{
size_t ret_len = 0;
error = clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, 0, 0, &ret_len);
if (error != CL_SUCCESS)
{
log_error("clGetDeviceInfo failed %s\n", IGetErrorString(error));
return -1;
}
Version version = get_device_cl_version(devices[i]);
std::vector<char> oclVersion(ret_len + 1);
error = clGetDeviceInfo(devices[i], CL_DEVICE_VERSION, sizeof(char) * oclVersion.size(), &oclVersion[0], 0);
if (error != CL_SUCCESS)
{
log_error("clGetDeviceInfo failed %s\n", IGetErrorString(error));
return -1;
}
std::string versionStr(&oclVersion[7]);
std::stringstream stream;
stream << versionStr;
double version = 0.0;
stream >> version;
if(device_from_harness != devices[i] && version < 2.0)
if(device_from_harness != devices[i] && version < Version(2,0))
{
continue;
}
@@ -233,7 +212,17 @@ cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeSt
log_error("clGetDeviceInfo returned an invalid cl_device_svm_capabilities value");
return -1;
}
if((caps & required_svm_caps) == required_svm_caps)
bool extensions_supported = true;
for (auto extension : extensions_list)
{
if (!is_extension_available(devices[i], extension.c_str()))
{
log_error("Required extension not found - device id %d - %s\n", i, extension.c_str());
extensions_supported = false;
break;
}
}
if((caps & required_svm_caps) == required_svm_caps && extensions_supported)
{
capable_devices.push_back(devices[i]);
++num_capable_devices;
@@ -244,11 +233,11 @@ cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeSt
if(num_capable_devices == 0)
// if(svm_level > CL_DEVICE_COARSE_SVM && 0 == num_capable_devices)
{
log_info("Requested SVM level not supported by any device on this platform, test not executed.\n");
log_info("Requested SVM level or required extensions not supported by any device on this platform, test not executed.\n");
return 1; // 1 indicates do not execute, but counts as passing.
}
cl_context_properties context_properties[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, NULL };
cl_context_properties context_properties[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, 0 };
*context = clCreateContext(context_properties, *num_devices, &devices[0], NULL, NULL, &error);
test_error(error, "Unable to create context" );
@@ -270,7 +259,7 @@ cl_int create_cl_objects(cl_device_id device_from_harness, const char** ppCodeSt
}
test_definition test_list[] = {
ADD_TEST( svm_byte_granularity ),
ADD_TEST( svm_byte_granularity),
ADD_TEST( svm_set_kernel_exec_info_svm_ptrs ),
ADD_TEST( svm_fine_grain_memory_consistency ),
ADD_TEST( svm_fine_grain_sync_buffers ),
@@ -283,13 +272,41 @@ test_definition test_list[] = {
ADD_TEST( svm_cross_buffer_pointers_coarse_grain ),
ADD_TEST( svm_pointer_passing ),
ADD_TEST( svm_enqueue_api ),
ADD_TEST( svm_migrate ),
ADD_TEST_VERSION( svm_migrate, Version(2, 1)),
};
const int test_num = ARRAY_SIZE( test_list );
int main(int argc, const char *argv[])
{
return runTestHarness( argc, argv, test_num, test_list, false, true, 0 );
test_status InitCL(cl_device_id device) {
auto version = get_device_cl_version(device);
auto expected_min_version = Version(2, 0);
if (version < expected_min_version)
{
version_expected_info("Test", "OpenCL",
expected_min_version.to_string().c_str(),
version.to_string().c_str());
return TEST_SKIP;
}
int error;
cl_device_svm_capabilities svm_caps;
error = clGetDeviceInfo(device, CL_DEVICE_SVM_CAPABILITIES,
sizeof(svm_caps), &svm_caps, NULL);
if (error != CL_SUCCESS) {
print_error(error, "Unable to get svm capabilities");
return TEST_FAIL;
}
if ((svm_caps == 0) && (version >= Version(3, 0)))
{
return TEST_SKIP;
}
return TEST_PASS;
}
int main(int argc, const char *argv[])
{
return runTestHarnessWithCheck(argc, argv, test_num, test_list, true, 0, InitCL);
}

View File

@@ -1,6 +1,6 @@
//
// 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
@@ -14,14 +14,14 @@
// limitations under the License.
//
#include "common.h"
#include "../../test_common/harness/mt19937.h"
#include "harness/mt19937.h"
#include <vector>
#include <atomic>
#if !defined(_WIN32)
#include <unistd.h>
#endif
#endif
typedef struct
{
@@ -81,7 +81,7 @@ int test_svm_enqueue_api(cl_device_id deviceID, cl_context c, cl_command_queue q
RandomSeed seed(0);
error = create_cl_objects(deviceID, NULL, &context, NULL, &queues[0], &num_devices, CL_DEVICE_SVM_COARSE_GRAIN_BUFFER);
if(error) return -1;
if(error) return TEST_FAIL;
queue = queues[0];
@@ -113,115 +113,163 @@ int test_svm_enqueue_api(cl_device_id deviceID, cl_context c, cl_command_queue q
sizeof(cl_ulong16),
};
for (size_t i = 0; i < ( sizeof(typeSizes) / sizeof(typeSizes[0]) ); ++i)
enum allocationTypes {
host,
svm
};
struct TestType {
allocationTypes srcAlloc;
allocationTypes dstAlloc;
TestType(allocationTypes type1, allocationTypes type2): srcAlloc(type1), dstAlloc(type2){}
};
std::vector<TestType> testTypes;
testTypes.push_back(TestType(host, host));
testTypes.push_back(TestType(host, svm));
testTypes.push_back(TestType(svm, host));
testTypes.push_back(TestType(svm, svm));
for (const auto test_case : testTypes)
{
//generate initial data
std::vector<cl_uchar> fillData0(typeSizes[i]), fillData1(typeSizes[i], 0), fillData2(typeSizes[i]);
generate_data(fillData0, typeSizes[i], seed);
generate_data(fillData2, typeSizes[i], seed);
cl_uchar *srcBuffer = (cl_uchar *)clSVMAlloc(context, CL_MEM_READ_WRITE, elementNum * typeSizes[i], 0);
cl_uchar *dstBuffer = (cl_uchar *)clSVMAlloc(context, CL_MEM_READ_WRITE, elementNum * typeSizes[i], 0);
clEventWrapper userEvent = clCreateUserEvent(context, &error);
test_error(error, "clCreateUserEvent failed");
clEventWrapper eventMemFill;
error = clEnqueueSVMMemFill(queue, srcBuffer, &fillData0[0], typeSizes[i], elementNum * typeSizes[i], 1, &userEvent, &eventMemFill);
test_error(error, "clEnqueueSVMMemFill failed");
clEventWrapper eventMemcpy;
error = clEnqueueSVMMemcpy(queue, CL_FALSE, dstBuffer, srcBuffer, elementNum * typeSizes[i], 1, &eventMemFill, &eventMemcpy);
test_error(error, "clEnqueueSVMMemcpy failed");
error = clSetUserEventStatus(userEvent, CL_COMPLETE);
test_error(error, "clSetUserEventStatus failed");
clEventWrapper eventMap;
error = clEnqueueSVMMap(queue, CL_FALSE, CL_MAP_READ | CL_MAP_WRITE, dstBuffer, elementNum * typeSizes[i], 1, &eventMemcpy, &eventMap);
test_error(error, "clEnqueueSVMMap failed");
error = clWaitForEvents(1, &eventMap);
test_error(error, "clWaitForEvents failed");
//data verification
for (size_t j = 0; j < elementNum * typeSizes[i]; ++j)
log_info("clEnqueueSVMMemcpy case: src_alloc = %s, dst_alloc = %s\n", test_case.srcAlloc == svm ? "svm" : "host", test_case.dstAlloc == svm ? "svm" : "host");
for (size_t i = 0; i < ARRAY_SIZE(typeSizes); ++i)
{
if (dstBuffer[j] != fillData0[j % typeSizes[i]])
//generate initial data
std::vector<cl_uchar> fillData0(typeSizes[i]), fillData1(typeSizes[i]);
generate_data(fillData0, typeSizes[i], seed);
generate_data(fillData1, typeSizes[i], seed);
size_t data_size = elementNum * typeSizes[i];
std::vector<cl_uchar> srcHostData(data_size, 0);
std::vector<cl_uchar> dstHostData(data_size, 0);
generate_data(srcHostData, srcHostData.size(), seed);
generate_data(dstHostData, dstHostData.size(), seed);
cl_uchar *srcBuffer = (cl_uchar *)clSVMAlloc(context, CL_MEM_READ_WRITE, data_size, 0);
cl_uchar *dstBuffer = (cl_uchar *)clSVMAlloc(context, CL_MEM_READ_WRITE, data_size, 0);
clEventWrapper userEvent = clCreateUserEvent(context, &error);
test_error(error, "clCreateUserEvent failed");
clEventWrapper eventMemFillList[2];
error = clEnqueueSVMMemFill(queue, srcBuffer, &fillData0[0], typeSizes[i], data_size, 1, &userEvent, &eventMemFillList[0]);
test_error(error, "clEnqueueSVMMemFill failed");
error = clEnqueueSVMMemFill(queue, dstBuffer, &fillData1[0], typeSizes[i], data_size, 1, &userEvent, &eventMemFillList[1]);
test_error(error, "clEnqueueSVMMemFill failed");
error = clSetUserEventStatus(userEvent, CL_COMPLETE);
test_error(error, "clSetUserEventStatus failed");
cl_uchar * src_ptr;
cl_uchar * dst_ptr;
if (test_case.srcAlloc == host) {
src_ptr = srcHostData.data();
} else if (test_case.srcAlloc == svm) {
src_ptr = srcBuffer;
}
if (test_case.dstAlloc == host) {
dst_ptr = dstHostData.data();
} else if (test_case.dstAlloc == svm) {
dst_ptr = dstBuffer;
}
clEventWrapper eventMemcpy;
error = clEnqueueSVMMemcpy(queue, CL_FALSE, dst_ptr, src_ptr, data_size, 2, &eventMemFillList[0], &eventMemcpy);
test_error(error, "clEnqueueSVMMemcpy failed");
//coarse grain only supported. Synchronization required using map
clEventWrapper eventMap[2];
error = clEnqueueSVMMap(queue, CL_FALSE, CL_MAP_READ, srcBuffer, data_size, 1, &eventMemcpy, &eventMap[0]);
test_error(error, "clEnqueueSVMMap srcBuffer failed");
error = clEnqueueSVMMap(queue, CL_FALSE, CL_MAP_READ, dstBuffer, data_size, 1, &eventMemcpy, &eventMap[1]);
test_error(error, "clEnqueueSVMMap dstBuffer failed");
error = clWaitForEvents(2, &eventMap[0]);
test_error(error, "clWaitForEvents failed");
//data verification
for (size_t j = 0; j < data_size; ++j)
{
log_error("Invalid data at index %ld, expected %d, got %d\n", j, fillData0[j % typeSizes[i]], dstBuffer[j]);
return -1;
if (dst_ptr[j] != src_ptr[j]) {
log_error("Invalid data at index %ld, dst_ptr %d, src_ptr %d\n", j, dst_ptr[j], src_ptr[j]);
return TEST_FAIL;
}
}
clEventWrapper eventUnmap[2];
error = clEnqueueSVMUnmap(queue, srcBuffer, 0, nullptr, &eventUnmap[0]);
test_error(error, "clEnqueueSVMUnmap srcBuffer failed");
error = clEnqueueSVMUnmap(queue, dstBuffer, 0, nullptr, &eventUnmap[1]);
test_error(error, "clEnqueueSVMUnmap dstBuffer failed");
error = clEnqueueSVMMemFill(queue, srcBuffer, &fillData1[0], typeSizes[i], data_size / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemFill failed");
error = clEnqueueSVMMemFill(queue, dstBuffer + data_size / 2, &fillData1[0], typeSizes[i], data_size / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemFill failed");
error = clEnqueueSVMMemcpy(queue, CL_FALSE, dstBuffer, srcBuffer, data_size / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemcpy failed");
error = clEnqueueSVMMemcpy(queue, CL_TRUE, dstBuffer + data_size / 2, srcBuffer + data_size / 2, data_size / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemcpy failed");
void *ptrs[] = { (void *)srcBuffer, (void *)dstBuffer };
clEventWrapper eventFree;
error = clEnqueueSVMFree(queue, 2, ptrs, 0, 0, 0, 0, &eventFree);
test_error(error, "clEnqueueSVMFree failed");
error = clWaitForEvents(1, &eventFree);
test_error(error, "clWaitForEvents failed");
//event info verification for new SVM commands
cl_command_type commandType;
for (auto &check_event : eventMemFillList) {
error = clGetEventInfo(check_event, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MEMFILL)
{
log_error("Invalid command type returned for clEnqueueSVMMemFill\n");
return TEST_FAIL;
}
}
error = clGetEventInfo(eventMemcpy, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MEMCPY)
{
log_error("Invalid command type returned for clEnqueueSVMMemcpy\n");
return TEST_FAIL;
}
for (size_t map_id = 0; map_id < ARRAY_SIZE(eventMap); map_id++) {
error = clGetEventInfo(eventMap[map_id], CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MAP)
{
log_error("Invalid command type returned for clEnqueueSVMMap\n");
return TEST_FAIL;
}
error = clGetEventInfo(eventUnmap[map_id], CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_UNMAP)
{
log_error("Invalid command type returned for clEnqueueSVMUnmap\n");
return TEST_FAIL;
}
}
error = clGetEventInfo(eventFree, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_FREE)
{
log_error("Invalid command type returned for clEnqueueSVMFree\n");
return TEST_FAIL;
}
}
clEventWrapper eventUnmap;
error = clEnqueueSVMUnmap(queue, dstBuffer, 0, 0, &eventUnmap);
test_error(error, "clEnqueueSVMUnmap failed");
error = clEnqueueSVMMemFill(queue, srcBuffer, &fillData2[0], typeSizes[i], elementNum * typeSizes[i] / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemFill failed");
error = clEnqueueSVMMemFill(queue, dstBuffer + elementNum * typeSizes[i] / 2, &fillData2[0], typeSizes[i], elementNum * typeSizes[i] / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemFill failed");
error = clEnqueueSVMMemcpy(queue, CL_FALSE, dstBuffer, srcBuffer, elementNum * typeSizes[i] / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemcpy failed");
error = clEnqueueSVMMemcpy(queue, CL_TRUE, dstBuffer + elementNum * typeSizes[i] / 2, srcBuffer + elementNum * typeSizes[i] / 2, elementNum * typeSizes[i] / 2, 0, 0, 0);
test_error(error, "clEnqueueSVMMemcpy failed");
void *ptrs[] = {(void *)srcBuffer, (void *)dstBuffer};
clEventWrapper eventFree;
error = clEnqueueSVMFree(queue, 2, ptrs, 0, 0, 0, 0, &eventFree);
test_error(error, "clEnqueueSVMFree failed");
error = clWaitForEvents(1, &eventFree);
test_error(error, "clWaitForEvents failed");
//event info verification for new SVM commands
cl_command_type commandType;
error = clGetEventInfo(eventMemFill, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MEMFILL)
{
log_error("Invalid command type returned for clEnqueueSVMMemFill\n");
return -1;
}
error = clGetEventInfo(eventMemcpy, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MEMCPY)
{
log_error("Invalid command type returned for clEnqueueSVMMemcpy\n");
return -1;
}
error = clGetEventInfo(eventMap, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MAP)
{
log_error("Invalid command type returned for clEnqueueSVMMap\n");
return -1;
}
error = clGetEventInfo(eventUnmap, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_UNMAP)
{
log_error("Invalid command type returned for clEnqueueSVMUnmap\n");
return -1;
}
error = clGetEventInfo(eventFree, CL_EVENT_COMMAND_TYPE, sizeof(cl_command_type), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_FREE)
{
log_error("Invalid command type returned for clEnqueueSVMFree\n");
return -1;
}
}
std::vector<void *> buffers(numSVMBuffers, 0);
for(size_t i = 0; i < numSVMBuffers; ++i) buffers[i] = clSVMAlloc(context, CL_MEM_READ_WRITE, elementNum, 0);
@@ -236,7 +284,7 @@ int test_svm_enqueue_api(cl_device_id deviceID, cl_context c, cl_command_queue q
test_error(error, "clFinish failed");
//wait for the callback
while(data.status.load(std::memory_order_acquire) == 0) {
while(data.status.load(std::memory_order_acquire) == 0) {
usleep(1);
}
@@ -244,7 +292,7 @@ int test_svm_enqueue_api(cl_device_id deviceID, cl_context c, cl_command_queue q
if (data.num_svm_pointers != buffers.size())
{
log_error("Invalid number of SVM pointers returned in the callback, expected: %ld, got: %d\n", buffers.size(), data.num_svm_pointers);
return -1;
return TEST_FAIL;
}
//check if pointers returned in callback are correct
@@ -253,9 +301,9 @@ int test_svm_enqueue_api(cl_device_id deviceID, cl_context c, cl_command_queue q
if (data.svm_pointers[i] != buffers[i])
{
log_error("Invalid SVM pointer returned in the callback, idx: %ld\n", i);
return -1;
return TEST_FAIL;
}
}
return 0;
}
}

View File

@@ -15,7 +15,11 @@
//
#include "common.h"
const char *hash_table_kernel[] = {
static char hash_table_kernel[] =
"#if 0\n"
"#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable\n"
"#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable\n"
"#endif\n"
"typedef struct BinNode {\n"
" int value;\n"
" atomic_uintptr_t pNext;\n"
@@ -32,8 +36,7 @@ const char *hash_table_kernel[] = {
" {\n"
" atomic_store_explicit(&(pNew->pNext), next, memory_order_seq_cst, memory_scope_all_svm_devices);\n" // always inserting at head of list
" } while(!atomic_compare_exchange_strong_explicit(&(pNodes[b].pNext), &next, (uintptr_t)pNew, memory_order_seq_cst, memory_order_relaxed, memory_scope_all_svm_devices));\n"
"}\n"
};
"}\n";
typedef struct BinNode{
cl_uint value;
@@ -110,6 +113,7 @@ int launch_kernels_and_verify(clContextWrapper &context, clCommandQueueWrapper*
}
}
clReleaseEvent(done);
clSVMFree(context, pInputImage);
clSVMFree(context, pNodes);
clSVMFree(context, pNumNodes);
@@ -136,14 +140,16 @@ int test_svm_fine_grain_memory_consistency(cl_device_id deviceID, cl_context c,
cl_uint num_devices = 0;
cl_int err = CL_SUCCESS;
std::vector<std::string> required_extensions;
required_extensions.push_back("cl_khr_int64_base_atomics");
required_extensions.push_back("cl_khr_int64_extended_atomics");
if (sizeof(void *) == 8 && (!is_extension_available(deviceID, "cl_khr_int64_base_atomics") || !is_extension_available(deviceID, "cl_khr_int64_extended_atomics")))
{
log_info("WARNING: test skipped. 'cl_khr_int64_base_atomics' and 'cl_khr_int64_extended_atomics' extensions are not supported\n");
return 0;
}
// Make pragmas visible for 64-bit addresses
hash_table_kernel[4] = sizeof(void *) == 8 ? '1' : '0';
err = create_cl_objects(deviceID, &hash_table_kernel[0], &context, &program, &queues[0], &num_devices, CL_DEVICE_SVM_FINE_GRAIN_BUFFER | CL_DEVICE_SVM_ATOMICS);
char *source[] = { hash_table_kernel };
err = create_cl_objects(deviceID, (const char**)source, &context, &program, &queues[0], &num_devices, CL_DEVICE_SVM_FINE_GRAIN_BUFFER | CL_DEVICE_SVM_ATOMICS, required_extensions);
if(err == 1) return 0; // no devices capable of requested SVM level, so don't execute but count test as passing.
if(err < 0) return -1; // fail test.

View File

@@ -96,6 +96,7 @@ int test_svm_fine_grain_sync_buffers(cl_device_id deviceID, cl_context c, cl_com
}
} while (status != CL_COMPLETE || AtomicLoadExplicit(&pTargetLocations[i], memory_order_relaxed) != -1);
clReleaseEvent(done);
clSVMFree(context, pInputImage);
clSVMFree(context, pNumTargetsFound);
clSVMFree(context, pTargetLocations);

View File

@@ -14,7 +14,7 @@
// limitations under the License.
//
#include "common.h"
#include "../../test_common/harness/mt19937.h"
#include "harness/mt19937.h"
#define GLOBAL_SIZE 65536
@@ -199,6 +199,24 @@ int test_svm_migrate(cl_device_id deviceID, cl_context c, cl_command_queue queue
error = clFlush(queues[1]);
test_error(error, "clFlush failed");
// Check the event command type for clEnqueueSVMMigrateMem (OpenCL 3.0 and
// newer)
Version version = get_device_cl_version(deviceID);
if (version >= Version(3, 0))
{
cl_command_type commandType;
error = clGetEventInfo(evs[3], CL_EVENT_COMMAND_TYPE,
sizeof(commandType), &commandType, NULL);
test_error(error, "clGetEventInfo failed");
if (commandType != CL_COMMAND_SVM_MIGRATE_MEM)
{
log_error("Invalid command type returned for "
"clEnqueueSVMMigrateMem: %X\n",
commandType);
return TEST_FAIL;
}
}
error = wait_and_release("first batch", evs, 8);
if (error)
return -1;

View File

@@ -50,13 +50,13 @@ int test_svm_pointer_passing(cl_device_id deviceID, cl_context context2, cl_comm
test_error(error,"clCreateKernel failed");
size_t bufSize = 256;
char *pbuf = (char*) clSVMAlloc(context, CL_MEM_READ_WRITE, sizeof(cl_uchar)*bufSize, 0);
cl_uchar *pbuf_svm_alloc = (cl_uchar*) clSVMAlloc(context, CL_MEM_READ_WRITE, sizeof(cl_uchar)*bufSize, 0);
cl_int *pNumCorrect = NULL;
pNumCorrect = (cl_int*) clSVMAlloc(context, CL_MEM_READ_WRITE, sizeof(cl_int), 0);
{
clMemWrapper buf = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(cl_uchar)*bufSize, pbuf, &error);
clMemWrapper buf = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(cl_uchar)*bufSize, pbuf_svm_alloc, &error);
test_error(error, "clCreateBuffer failed.");
clMemWrapper num_correct = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(cl_int), pNumCorrect, &error);
@@ -67,13 +67,13 @@ int test_svm_pointer_passing(cl_device_id deviceID, cl_context context2, cl_comm
// put values into buf so that we can expect to see these values in the kernel when we pass a pointer to them.
cl_command_queue cmdq = queues[0];
cl_uchar* pBuf = (cl_uchar*) clEnqueueMapBuffer(cmdq, buf, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, sizeof(cl_uchar)*bufSize, 0, NULL,NULL, &error);
test_error2(error, pBuf, "clEnqueueMapBuffer failed");
cl_uchar* pbuf_map_buffer = (cl_uchar*) clEnqueueMapBuffer(cmdq, buf, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, sizeof(cl_uchar)*bufSize, 0, NULL,NULL, &error);
test_error2(error, pbuf_map_buffer, "clEnqueueMapBuffer failed");
for(int i = 0; i<(int)bufSize; i++)
{
pBuf[i]= (cl_uchar)i;
pbuf_map_buffer[i]= (cl_uchar)i;
}
error = clEnqueueUnmapMemObject(cmdq, buf, pBuf, 0,NULL,NULL);
error = clEnqueueUnmapMemObject(cmdq, buf, pbuf_map_buffer, 0,NULL,NULL);
test_error(error, "clEnqueueUnmapMemObject failed.");
for (cl_uint ii = 0; ii<num_devices; ++ii) // iterate over all devices in the platform.
@@ -81,7 +81,7 @@ int test_svm_pointer_passing(cl_device_id deviceID, cl_context context2, cl_comm
cmdq = queues[ii];
for(int i = 0; i<(int)bufSize; i++)
{
cl_uchar* pChar = &pBuf[i];
cl_uchar* pChar = &pbuf_svm_alloc[i];
error = clSetKernelArgSVMPointer(kernel_verify_char, 0, pChar); // pass a pointer to a location within the buffer
test_error(error, "clSetKernelArg failed");
error = clSetKernelArg(kernel_verify_char, 2, sizeof(cl_uchar), (void *) &i ); // pass the expected value at the above location.
@@ -108,7 +108,7 @@ int test_svm_pointer_passing(cl_device_id deviceID, cl_context context2, cl_comm
}
clSVMFree(context, pbuf);
clSVMFree(context, pbuf_svm_alloc);
clSVMFree(context, pNumCorrect);
return 0;

View File

@@ -6,15 +6,6 @@ set(${MODULE_NAME}_SOURCES
allocation_fill.cpp
allocation_functions.cpp
allocation_utils.cpp
../../test_common/harness/errorHelpers.c
../../test_common/harness/threadTesting.c
../../test_common/harness/kernelHelpers.c
../../test_common/harness/testHarness.c
../../test_common/harness/typeWrappers.cpp
../../test_common/harness/mt19937.c
../../test_common/harness/msvc9.c
../../test_common/harness/parseParameters.cpp
../../test_common/harness/crc32.c
)
include(../CMakeCommon.txt)

View File

@@ -18,12 +18,12 @@
const char *buffer_kernel_pattern = {
"__kernel void sample_test(%s __global uint *result, __global uint *array_sizes, uint per_item)\n"
"__kernel void sample_test(%s __global uint *result, __global %s *array_sizes, uint per_item)\n"
"{\n"
"\tint tid = get_global_id(0);\n"
"\tuint r = 0;\n"
"\tuint i;\n"
"\tfor(i=tid*per_item; i<(1+tid)*per_item; i++) {\n"
"\t%s i;\n"
"\tfor(i=(%s)tid*(%s)per_item; i<(%s)(1+tid)*(%s)per_item; i++) {\n"
"%s"
"\t}\n"
"\tresult[tid] = r;\n"
@@ -161,13 +161,31 @@ int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id dev
for (i=0; i<NUM_OF_WORK_ITEMS; i++)
returned_results[i] = 0;
// detect if device supports ulong/int64
//detect whether profile of the device is embedded
bool support64 = true;
char profile[1024] = "";
error = clGetDeviceInfo(device_id, CL_DEVICE_PROFILE, sizeof(profile), profile, NULL);
test_error(error, "clGetDeviceInfo for CL_DEVICE_PROFILE failed\n" );
if ((NULL != strstr(profile, "EMBEDDED_PROFILE")) &&
(!is_extension_available(device_id, "cles_khr_int64"))) {
support64 = false;
}
// Build the kernel source
if (test == BUFFER || test == BUFFER_NON_BLOCKING) {
for(i=0; i<number_of_mems_used; i++) {
sprintf(argument_string + strlen(argument_string), " __global uint *buffer%d, ", i);
sprintf(access_string + strlen( access_string), "\t\tif (i<array_sizes[%d]) r += buffer%d[i];\n", i, i);
}
sprintf(kernel_string, buffer_kernel_pattern, argument_string, access_string);
char type[10];
if (support64) {
sprintf(type, "ulong");
}
else {
sprintf(type, "uint");
}
sprintf(kernel_string, buffer_kernel_pattern, argument_string, type, type, type, type, type, type, access_string);
}
else if (test == IMAGE_READ || test == IMAGE_READ_NON_BLOCKING) {
for(i=0; i<number_of_mems_used; i++) {
@@ -217,19 +235,36 @@ int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id dev
global_dims[0] = NUM_OF_WORK_ITEMS; global_dims[1] = 1; global_dims[2] = 1;
// We have extra arguments for the buffer kernel because we need to pass in the buffer sizes
cl_uint *sizes = (cl_uint*)malloc(sizeof(cl_uint)*number_of_mems_used);
cl_uint max_size = 0;
cl_ulong *ulSizes = NULL;
cl_uint *uiSizes = NULL;
if (support64) {
ulSizes = (cl_ulong*)malloc(sizeof(cl_ulong)*number_of_mems_used);
}
else {
uiSizes = (cl_uint*)malloc(sizeof(cl_uint)*number_of_mems_used);
}
cl_ulong max_size = 0;
clMemWrapper buffer_sizes;
if (test == BUFFER || test == BUFFER_NON_BLOCKING) {
for (i=0; i<number_of_mems_used; i++) {
size_t size;
error = clGetMemObjectInfo(mems[i], CL_MEM_SIZE, sizeof(size), &size, NULL);
test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_SIZE.");
sizes[i] = (cl_uint)(size/sizeof(cl_uint));
if (support64) {
ulSizes[i] = size/sizeof(cl_uint);
}
else {
uiSizes[i] = (cl_uint)size/sizeof(cl_uint);
}
if (size/sizeof(cl_uint) > max_size)
max_size = (cl_uint)(size/sizeof(cl_uint));
max_size = size/sizeof(cl_uint);
}
if (support64) {
buffer_sizes = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(cl_ulong)*number_of_mems_used, ulSizes, &error);
}
else {
buffer_sizes = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(cl_uint)*number_of_mems_used, uiSizes, &error);
}
buffer_sizes = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(cl_uint)*number_of_mems_used, sizes, &error);
test_error_abort(error, "clCreateBuffer failed");
error = clSetKernelArg(kernel, number_of_mems_used+1, sizeof(cl_mem), &buffer_sizes);
test_error(error, "clSetKernelArg failed");
@@ -239,7 +274,12 @@ int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id dev
per_item_uint = (cl_uint)per_item;
error = clSetKernelArg(kernel, number_of_mems_used+2, sizeof(per_item_uint), &per_item_uint);
test_error(error, "clSetKernelArg failed");
free(sizes);
}
if (ulSizes) {
free(ulSizes);
}
if (uiSizes) {
free(uiSizes);
}
size_t local_dims[3] = {1,1,1};

View File

@@ -18,7 +18,7 @@
#define BUFFER_CHUNK_SIZE 8*1024*1024
#define IMAGE_LINES 8
#include "../../test_common/harness/compat.h"
#include "harness/compat.h"
int fill_buffer_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t size, MTdata d, cl_bool blocking_write) {
size_t i, j;

View File

@@ -48,7 +48,10 @@ int find_good_image_size(cl_device_id device_id, size_t size_to_allocate, size_t
num_pixels = size_to_allocate / (sizeof(cl_uint)*4);
if (num_pixels > (max_width*max_height)) {
// Use a 64-bit variable to avoid overflow in 32-bit architectures
long long unsigned max_pixels = (long long unsigned)max_width * max_height;
if (num_pixels > max_pixels) {
if(NULL != max_size) {
*max_size = max_width * max_height * sizeof(cl_uint) * 4;
}
@@ -272,7 +275,6 @@ int allocate_size(cl_context context, cl_command_queue *queue, cl_device_id devi
// Otherwise we succeeded
if (result != SUCCEEDED) {
log_error("Test logic error.");
test_finish();
exit(-1);
}
amount_allocated += allocation_this_time;

View File

@@ -19,7 +19,7 @@ cl_command_queue reset_queue(cl_context context, cl_device_id device_id, cl_comm
{
log_info("Invalid command queue. Releasing and recreating the command queue.\n");
clReleaseCommandQueue(*queue);
*queue = clCreateCommandQueueWithProperties(context, device_id, 0, error);
*queue = clCreateCommandQueue(context, device_id, 0, error);
return *queue;
}

View File

@@ -18,8 +18,8 @@
#include "allocation_functions.h"
#include "allocation_fill.h"
#include "allocation_execute.h"
#include "../../test_common/harness/testHarness.h"
#include "../../test_common/harness/parseParameters.h"
#include "harness/testHarness.h"
#include "harness/parseParameters.h"
#include <time.h>
typedef long long unsigned llu;
@@ -277,7 +277,6 @@ int main(int argc, const char *argv[])
argc = parseCustomParam(argc, argv);
if (argc == -1)
{
test_finish();
return 1;
}
@@ -335,7 +334,7 @@ int main(int argc, const char *argv[])
}
}
int ret = runTestHarnessWithCheck( argCount, argList, test_num, test_list, false, false, 0, init_cl );
int ret = runTestHarnessWithCheck( argCount, argList, test_num, test_list, false, 0, init_cl );
free(argList);
return ret;

View File

@@ -16,7 +16,7 @@
#ifndef _testBase_h
#define _testBase_h
#include "../../test_common/harness/compat.h"
#include "harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -28,10 +28,10 @@
#include <unistd.h>
#endif
#include "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/typeWrappers.h"
#include "harness/testHarness.h"
#define MAX_NUMBER_TO_ALLOCATE 100

View File

@@ -1,14 +1,16 @@
set(MODULE_NAME API)
set(${MODULE_NAME}_SOURCES
main.c
test_bool.c
main.cpp
test_api_consistency.cpp
test_bool.cpp
test_retain.cpp
test_retain_program.c
test_retain_program.cpp
test_queries.cpp
test_create_kernels.c
test_kernels.c
test_api_min_max.c
test_queries_compatibility.cpp
test_create_kernels.cpp
test_kernels.cpp
test_api_min_max.cpp
test_kernel_arg_changes.cpp
test_kernel_arg_multi_setup.cpp
test_binary.cpp
@@ -17,24 +19,19 @@ set(${MODULE_NAME}_SOURCES
test_create_context_from_type.cpp
test_device_min_data_type_align_size_alignment.cpp
test_platform.cpp
test_kernel_arg_info.c
test_null_buffer_arg.c
test_kernel_arg_info.cpp
test_kernel_arg_info_compatibility.cpp
test_null_buffer_arg.cpp
test_mem_object_info.cpp
test_queue.cpp
test_queue_hint.cpp
test_queue_properties.cpp
test_sub_group_dispatch.cpp
test_clone_kernel.cpp
test_zero_sized_enqueue.cpp
../../test_common/harness/errorHelpers.c
../../test_common/harness/threadTesting.c
../../test_common/harness/testHarness.c
../../test_common/harness/kernelHelpers.c
../../test_common/harness/typeWrappers.cpp
../../test_common/harness/conversions.c
../../test_common/harness/mt19937.c
../../test_common/harness/msvc9.c
../../test_common/harness/imageHelpers.cpp
../../test_common/harness/parseParameters.cpp
../../test_common/harness/crc32.c
test_context_destructor_callback.cpp
test_mem_object_properties_queries.cpp
test_queue_properties_queries.cpp
)
include(../CMakeCommon.txt)

View File

@@ -1,129 +0,0 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "procs.h"
#include "../../test_common/harness/testHarness.h"
#if !defined(_WIN32)
#include <unistd.h>
#endif
// FIXME: To use certain functions in ../../test_common/harness/imageHelpers.h
// (for example, generate_random_image_data()), the tests are required to declare
// the following variables (<rdar://problem/11111245>):
cl_device_type gDeviceType = CL_DEVICE_TYPE_DEFAULT;
bool gTestRounding = false;
test_definition test_list[] = {
ADD_TEST( get_platform_info ),
ADD_TEST( get_sampler_info ),
ADD_TEST( get_command_queue_info ),
ADD_TEST( get_context_info ),
ADD_TEST( get_device_info ),
ADD_TEST( enqueue_task ),
ADD_TEST( binary_get ),
ADD_TEST( binary_create ),
ADD_TEST( kernel_required_group_size ),
ADD_TEST( release_kernel_order ),
ADD_TEST( release_during_execute ),
ADD_TEST( load_single_kernel ),
ADD_TEST( load_two_kernels ),
ADD_TEST( load_two_kernels_in_one ),
ADD_TEST( load_two_kernels_manually ),
ADD_TEST( get_program_info_kernel_names ),
ADD_TEST( get_kernel_arg_info ),
ADD_TEST( create_kernels_in_program ),
ADD_TEST( get_kernel_info ),
ADD_TEST( execute_kernel_local_sizes ),
ADD_TEST( set_kernel_arg_by_index ),
ADD_TEST( set_kernel_arg_constant ),
ADD_TEST( set_kernel_arg_struct_array ),
ADD_TEST( kernel_global_constant ),
ADD_TEST( min_max_thread_dimensions ),
ADD_TEST( min_max_work_items_sizes ),
ADD_TEST( min_max_work_group_size ),
ADD_TEST( min_max_read_image_args ),
ADD_TEST( min_max_write_image_args ),
ADD_TEST( min_max_mem_alloc_size ),
ADD_TEST( min_max_image_2d_width ),
ADD_TEST( min_max_image_2d_height ),
ADD_TEST( min_max_image_3d_width ),
ADD_TEST( min_max_image_3d_height ),
ADD_TEST( min_max_image_3d_depth ),
ADD_TEST( min_max_image_array_size ),
ADD_TEST( min_max_image_buffer_size ),
ADD_TEST( min_max_parameter_size ),
ADD_TEST( min_max_samplers ),
ADD_TEST( min_max_constant_buffer_size ),
ADD_TEST( min_max_constant_args ),
ADD_TEST( min_max_compute_units ),
ADD_TEST( min_max_address_bits ),
ADD_TEST( min_max_single_fp_config ),
ADD_TEST( min_max_double_fp_config ),
ADD_TEST( min_max_local_mem_size ),
ADD_TEST( min_max_kernel_preferred_work_group_size_multiple ),
ADD_TEST( min_max_execution_capabilities ),
ADD_TEST( min_max_queue_properties ),
ADD_TEST( min_max_device_version ),
ADD_TEST( min_max_language_version ),
ADD_TEST( kernel_arg_changes ),
ADD_TEST( kernel_arg_multi_setup_random ),
ADD_TEST( native_kernel ),
ADD_TEST( create_context_from_type ),
ADD_TEST( platform_extensions ),
ADD_TEST( get_platform_ids ),
ADD_TEST( bool_type ),
ADD_TEST( repeated_setup_cleanup ),
ADD_TEST( retain_queue_single ),
ADD_TEST( retain_queue_multiple ),
ADD_TEST( retain_mem_object_single ),
ADD_TEST( retain_mem_object_multiple ),
ADD_TEST( min_data_type_align_size_alignment ),
ADD_TEST( mem_object_destructor_callback ),
ADD_TEST( null_buffer_arg ),
ADD_TEST( get_buffer_info ),
ADD_TEST( get_image2d_info ),
ADD_TEST( get_image3d_info ),
ADD_TEST( get_image1d_info ),
ADD_TEST( get_image1d_array_info ),
ADD_TEST( get_image2d_array_info ),
ADD_TEST( queue_hint ),
ADD_TEST( sub_group_dispatch ),
ADD_TEST( clone_kernel ),
ADD_TEST( zero_sized_enqueue ),
};
const int test_num = ARRAY_SIZE( test_list );
int main(int argc, const char *argv[])
{
return runTestHarness( argc, argv, test_num, test_list, false, false, 0 );
}

View File

@@ -0,0 +1,152 @@
//
// 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 "harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "procs.h"
#include "harness/testHarness.h"
#if !defined(_WIN32)
#include <unistd.h>
#endif
// FIXME: To use certain functions in harness/imageHelpers.h
// (for example, generate_random_image_data()), the tests are required to
// declare the following variables (<rdar://problem/11111245>):
test_definition test_list[] = {
ADD_TEST(get_platform_info),
ADD_TEST_VERSION(get_sampler_info, Version(2, 0)),
ADD_TEST(get_sampler_info_compatibility),
ADD_TEST_VERSION(get_command_queue_info, Version(2, 0)),
ADD_TEST(get_command_queue_info_compatibility),
ADD_TEST(get_context_info),
ADD_TEST(get_device_info),
ADD_TEST(enqueue_task),
ADD_TEST(binary_get),
ADD_TEST(binary_create),
ADD_TEST(kernel_required_group_size),
ADD_TEST(release_kernel_order),
ADD_TEST(release_during_execute),
ADD_TEST(load_single_kernel),
ADD_TEST(load_two_kernels),
ADD_TEST(load_two_kernels_in_one),
ADD_TEST(load_two_kernels_manually),
ADD_TEST(get_program_info_kernel_names),
ADD_TEST(get_kernel_arg_info),
ADD_TEST(get_kernel_arg_info_compatibility),
ADD_TEST(create_kernels_in_program),
ADD_TEST(get_kernel_info),
ADD_TEST(execute_kernel_local_sizes),
ADD_TEST(set_kernel_arg_by_index),
ADD_TEST(set_kernel_arg_constant),
ADD_TEST(set_kernel_arg_struct_array),
ADD_TEST(kernel_global_constant),
ADD_TEST(min_max_thread_dimensions),
ADD_TEST(min_max_work_items_sizes),
ADD_TEST(min_max_work_group_size),
ADD_TEST(min_max_read_image_args),
ADD_TEST(min_max_write_image_args),
ADD_TEST(min_max_mem_alloc_size),
ADD_TEST(min_max_image_2d_width),
ADD_TEST(min_max_image_2d_height),
ADD_TEST(min_max_image_3d_width),
ADD_TEST(min_max_image_3d_height),
ADD_TEST(min_max_image_3d_depth),
ADD_TEST(min_max_image_array_size),
ADD_TEST(min_max_image_buffer_size),
ADD_TEST(min_max_parameter_size),
ADD_TEST(min_max_samplers),
ADD_TEST(min_max_constant_buffer_size),
ADD_TEST(min_max_constant_args),
ADD_TEST(min_max_compute_units),
ADD_TEST(min_max_address_bits),
ADD_TEST(min_max_single_fp_config),
ADD_TEST(min_max_double_fp_config),
ADD_TEST(min_max_local_mem_size),
ADD_TEST(min_max_kernel_preferred_work_group_size_multiple),
ADD_TEST(min_max_execution_capabilities),
ADD_TEST(min_max_queue_properties),
ADD_TEST(min_max_device_version),
ADD_TEST(min_max_language_version),
ADD_TEST(kernel_arg_changes),
ADD_TEST(kernel_arg_multi_setup_random),
ADD_TEST(native_kernel),
ADD_TEST(create_context_from_type),
ADD_TEST(platform_extensions),
ADD_TEST(get_platform_ids),
ADD_TEST(bool_type),
ADD_TEST(repeated_setup_cleanup),
ADD_TEST(retain_queue_single),
ADD_TEST(retain_queue_multiple),
ADD_TEST(retain_mem_object_single),
ADD_TEST(retain_mem_object_multiple),
ADD_TEST(retain_mem_object_set_kernel_arg),
ADD_TEST(min_data_type_align_size_alignment),
ADD_TEST_VERSION(context_destructor_callback, Version(3, 0)),
ADD_TEST(mem_object_destructor_callback),
ADD_TEST(null_buffer_arg),
ADD_TEST(get_buffer_info),
ADD_TEST(get_image2d_info),
ADD_TEST(get_image3d_info),
ADD_TEST(get_image1d_info),
ADD_TEST(get_image1d_array_info),
ADD_TEST(get_image2d_array_info),
ADD_TEST(queue_flush_on_release),
ADD_TEST(queue_hint),
ADD_TEST(queue_properties),
ADD_TEST_VERSION(sub_group_dispatch, Version(2, 1)),
ADD_TEST_VERSION(clone_kernel, Version(2, 1)),
ADD_TEST_VERSION(zero_sized_enqueue, Version(2, 1)),
ADD_TEST_VERSION(buffer_properties_queries, Version(3, 0)),
ADD_TEST_VERSION(image_properties_queries, Version(3, 0)),
ADD_TEST_VERSION(queue_properties_queries, Version(3, 0)),
ADD_TEST_VERSION(consistency_svm, Version(3, 0)),
ADD_TEST_VERSION(consistency_memory_model, Version(3, 0)),
ADD_TEST_VERSION(consistency_device_enqueue, Version(3, 0)),
ADD_TEST_VERSION(consistency_pipes, Version(3, 0)),
ADD_TEST_VERSION(consistency_progvar, Version(3, 0)),
ADD_TEST_VERSION(consistency_non_uniform_work_group, Version(3, 0)),
ADD_TEST_VERSION(consistency_read_write_images, Version(3, 0)),
ADD_TEST_VERSION(consistency_2d_image_from_buffer, Version(3, 0)),
ADD_TEST_VERSION(consistency_depth_images, Version(3, 0)),
ADD_TEST_VERSION(consistency_device_and_host_timer, Version(3, 0)),
ADD_TEST_VERSION(consistency_il_programs, Version(3, 0)),
ADD_TEST_VERSION(consistency_subgroups, Version(3, 0)),
ADD_TEST_VERSION(consistency_prog_ctor_dtor, Version(3, 0)),
ADD_TEST_VERSION(consistency_3d_image_writes, Version(3, 0)),
};
const int test_num = ARRAY_SIZE(test_list);
int main(int argc, const char *argv[])
{
return runTestHarness(argc, argv, test_num, test_list, false, false, 0);
}

View File

@@ -13,11 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "../../test_common/harness/errorHelpers.h"
#include "../../test_common/harness/kernelHelpers.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/clImageHelper.h"
#include "../../test_common/harness/imageHelpers.h"
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/typeWrappers.h"
#include "harness/clImageHelper.h"
#include "harness/imageHelpers.h"
extern float calculate_ulperror(float a, float b);
extern int test_load_single_kernel(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
@@ -33,7 +33,9 @@ extern int test_bool_type(cl_device_id deviceID, cl_context context, cl_c
extern int test_platform_extensions(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_platform_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_sampler_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_sampler_info_compatibility(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_command_queue_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_command_queue_info_compatibility(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_context_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_get_device_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_kernel_required_group_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
@@ -93,9 +95,17 @@ extern int test_retain_queue_single(cl_device_id deviceID, cl_context con
extern int test_retain_queue_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_retain_mem_object_single(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_retain_mem_object_multiple(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_retain_mem_object_set_kernel_arg(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_min_data_type_align_size_alignment(cl_device_id device, cl_context context, cl_command_queue queue, int n_elems );
extern int test_mem_object_destructor_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_context_destructor_callback(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mem_object_destructor_callback(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_null_buffer_arg( cl_device_id device_id, cl_context context, cl_command_queue queue, int num_elements );
extern int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
@@ -105,7 +115,74 @@ extern int test_get_image1d_info( cl_device_id deviceID, cl_context context
extern int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
extern int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
extern int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_get_kernel_arg_info_compatibility( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_queue_hint(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_zero_sized_enqueue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_queue_properties( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_queue_flush_on_release(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_buffer_properties_queries(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_image_properties_queries(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_queue_properties_queries(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_svm(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_consistency_memory_model(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_device_enqueue(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_pipes(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_consistency_progvar(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_consistency_non_uniform_work_group(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_read_write_images(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_2d_image_from_buffer(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_depth_images(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_device_and_host_timer(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_il_programs(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_subgroups(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_consistency_prog_ctor_dtor(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_consistency_3d_image_writes(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);

View File

@@ -16,7 +16,7 @@
#ifndef _testBase_h
#define _testBase_h
#include "../../test_common/harness/compat.h"
#include "harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,13 +14,11 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/typeWrappers.h"
#include "harness/testHarness.h"
#include <ctype.h>
#include <string.h>
extern cl_uint gRandomSeed;
const char *sample_single_param_kernel[] = {
"__kernel void sample_test(__global int *src)\n"
"{\n"
@@ -241,6 +239,7 @@ int test_min_max_read_image_args(cl_device_id deviceID, cl_context context, cl_c
{
int error;
unsigned int maxReadImages, i;
unsigned int deviceAddressSize;
clProgramWrapper program;
char readArgLine[128], *programSrc;
const char *readArgPattern = ", read_only image2d_t srcimg%d";
@@ -273,6 +272,11 @@ int test_min_max_read_image_args(cl_device_id deviceID, cl_context context, cl_c
log_info("Reported %d max read image args.\n", maxReadImages);
error = clGetDeviceInfo( deviceID, CL_DEVICE_ADDRESS_BITS, sizeof( deviceAddressSize ), &deviceAddressSize, NULL );
test_error( error, "Unable to query CL_DEVICE_ADDRESS_BITS for device" );
deviceAddressSize /= 8; // convert from bits to bytes
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_PARAMETER_SIZE, sizeof( maxParameterSize ), &maxParameterSize, NULL );
test_error( error, "Unable to get max parameter size from device" );
@@ -286,14 +290,13 @@ int test_min_max_read_image_args(cl_device_id deviceID, cl_context context, cl_c
maxReadImages = 127;
}
}
// Subtract the size of the result
maxParameterSize -= sizeof(cl_mem);
maxParameterSize -= deviceAddressSize;
// Calculate the number we can use
if (maxParameterSize/sizeof(cl_mem) < maxReadImages) {
log_info("WARNING: Max parameter size of %d bytes limits test to %d max image arguments.\n", (int)maxParameterSize, (int)(maxParameterSize/sizeof(cl_mem)));
maxReadImages = (unsigned int)(maxParameterSize/sizeof(cl_mem));
if (maxParameterSize/deviceAddressSize < maxReadImages) {
log_info("WARNING: Max parameter size of %d bytes limits test to %d max image arguments.\n", (int)maxParameterSize, (int)(maxParameterSize/deviceAddressSize));
maxReadImages = (unsigned int)(maxParameterSize/deviceAddressSize);
}
/* Create a program with that many read args */
@@ -496,6 +499,7 @@ int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context, cl_co
if (memSize > (cl_ulong)SIZE_MAX) {
memSize = (cl_ulong)SIZE_MAX;
}
if( maxAllocSize < requiredAllocSize)
{
log_error( "ERROR: Reported max allocation size is less than required %lldMB! (%llu or %lluMB, from a total mem size of %lldMB)\n", (requiredAllocSize / 1024) / 1024, maxAllocSize, (maxAllocSize / 1024)/1024, (memSize / 1024)/1024 );
@@ -503,10 +507,12 @@ int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context, cl_co
}
requiredAllocSize = ((memSize / 4) > (1024 * 1024 * 1024)) ? 1024 * 1024 * 1024 : memSize / 4;
if (gIsEmbedded)
requiredAllocSize = (requiredAllocSize < 1 * 1024 * 1024) ? 1 * 1024 * 1024 : requiredAllocSize;
else
requiredAllocSize = (requiredAllocSize < 128 * 1024 * 1024) ? 128 * 1024 * 1024 : requiredAllocSize;
if( maxAllocSize < requiredAllocSize )
{
log_error( "ERROR: Reported max allocation size is less than required of total memory! (%llu or %lluMB, from a total mem size of %lluMB)\n", maxAllocSize, (maxAllocSize / 1024)/1024, (requiredAllocSize / 1024)/1024 );
@@ -519,7 +525,6 @@ int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context, cl_co
if ( memSize < maxAllocSize ) {
log_info("Global memory size is less than max allocation size, using that.\n");
maxAllocSize = memSize;
}
minSizeToTry = maxAllocSize/16;
@@ -547,29 +552,19 @@ int test_min_max_image_2d_width(cl_device_id deviceID, cl_context context, cl_co
cl_image_format image_format_desc;
cl_ulong maxAllocSize;
cl_uint minRequiredDimension;
cl_char buffer[ 4098 ];
size_t length;
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
// Device version should fit the regex "OpenCL [0-9]+\.[0-9]+ *.*"
error = clGetDeviceInfo( deviceID, CL_DEVICE_VERSION, sizeof( buffer ), buffer, &length );
test_error( error, "Unable to get device version string" );
if( memcmp( buffer, "OpenCL 2.1", strlen( "OpenCL 2.1" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if( memcmp( buffer, "OpenCL 2.0", strlen( "OpenCL 2.0" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if( memcmp( buffer, "OpenCL 1.2", strlen( "OpenCL 1.2" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if( memcmp( buffer, "OpenCL 1.1", strlen( "OpenCL 1.1" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if ( memcmp( buffer, "OpenCL 1.0", strlen( "OpenCL 1.0" ) ) == 0 )
auto version = get_device_cl_version(deviceID);
if (version == Version(1, 0))
{
minRequiredDimension = gIsEmbedded ? 2048 : 4096;
}
else
{
log_error( "ERROR: device version string does not match required format! (returned: %s)\n", (char *)buffer );
return -1;
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
}
@@ -626,28 +621,18 @@ int test_min_max_image_2d_height(cl_device_id deviceID, cl_context context, cl_c
cl_image_format image_format_desc;
cl_ulong maxAllocSize;
cl_uint minRequiredDimension;
cl_char buffer[ 4098 ];
size_t length;
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
// Device version should fit the regex "OpenCL [0-9]+\.[0-9]+ *.*"
error = clGetDeviceInfo( deviceID, CL_DEVICE_VERSION, sizeof( buffer ), buffer, &length );
test_error( error, "Unable to get device version string" );
if( memcmp( buffer, "OpenCL 2.1", strlen( "OpenCL 2.1" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if( memcmp( buffer, "OpenCL 2.0", strlen( "OpenCL 2.0" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if( memcmp( buffer, "OpenCL 1.2", strlen( "OpenCL 1.2" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if( memcmp( buffer, "OpenCL 1.1", strlen( "OpenCL 1.1" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
else if ( memcmp( buffer, "OpenCL 1.0", strlen( "OpenCL 1.0" ) ) == 0 )
minRequiredDimension = gIsEmbedded ? 2048 : 4096;
auto version = get_device_cl_version(deviceID);
if (version == Version(1, 0))
{
minRequiredDimension = gIsEmbedded ? 2048 : 4096;
}
else
{
log_error( "ERROR: device version string does not match required format! (returned: %s)\n", (char *)buffer );
return -1;
minRequiredDimension = gIsEmbedded ? 2048 : 8192;
}
/* Just get any ol format to test with */
@@ -1012,6 +997,7 @@ int test_min_max_parameter_size(cl_device_id deviceID, cl_context context, cl_co
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_PARAMETER_SIZE, sizeof( maxSize ), &maxSize, NULL );
test_error( error, "Unable to get max parameter size from device" );
if( ((!gIsEmbedded) && (maxSize < 1024)) || ((gIsEmbedded) && (maxSize < 256)) )
{
log_error( "ERROR: Reported max parameter size is less than required! (%d)\n", (int)maxSize );
@@ -1299,7 +1285,6 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
int error;
clProgramWrapper program;
clKernelWrapper kernel;
clMemWrapper streams[3];
size_t threads[1], localThreads[1];
cl_int *constantData, *resultData;
cl_ulong maxSize, stepSize, currentSize, maxGlobalSize, maxAllocSize;
@@ -1320,14 +1305,19 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
log_info("Reported max constant buffer size of %lld bytes.\n", maxSize);
// Limit test buffer size to 1/8 of CL_DEVICE_GLOBAL_MEM_SIZE
error = clGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(maxGlobalSize), &maxGlobalSize, 0);
test_error(error, "Unable to get CL_DEVICE_GLOBAL_MEM_SIZE");
if (maxSize > maxGlobalSize / 8)
maxSize = maxGlobalSize / 8;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE , sizeof(maxAllocSize), &maxAllocSize, 0);
test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE ");
if (maxSize > maxAllocSize)
maxSize = maxAllocSize;
/* Create a kernel to test with */
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_const_arg_kernel, "sample_test" ) != 0 )
{
@@ -1346,9 +1336,17 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
size_t sizeToAllocate = ((size_t)currentSize/sizeof( cl_int ))*sizeof(cl_int);
size_t numberOfInts = sizeToAllocate/sizeof(cl_int);
constantData = (cl_int *)malloc( sizeToAllocate);
if (constantData == NULL)
{
log_error("Failed to allocate memory for constantData!\n");
free_mtdata(d);
return EXIT_FAILURE;
}
for(i=0; i<(int)(numberOfInts); i++)
constantData[i] = (int)genrand_int32(d);
clMemWrapper streams[3];
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeToAllocate, constantData, &error);
test_error( error, "Creating test array failed" );
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeToAllocate, NULL, &error);
@@ -1398,6 +1396,14 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
allocPassed = 1;
resultData = (cl_int *)malloc(sizeToAllocate);
if (resultData == NULL)
{
log_error("Failed to allocate memory for resultData!\n");
free(constantData);
free_mtdata(d);
return EXIT_FAILURE;
}
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, sizeToAllocate, resultData, 0, NULL, NULL);
test_error( error, "clEnqueueReadBuffer failed");
@@ -1418,7 +1424,7 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
if (allocPassed) {
if (currentSize < maxSize/PASSING_FRACTION) {
log_error("Failed to allocate at least 1/4 of the reported constant size.\n");
log_error("Failed to allocate at least 1/8 of the reported constant size.\n");
return -1;
} else if (currentSize != maxSize) {
log_info("Passed at reduced size. (%lld of %lld bytes)\n", currentSize, maxSize);
@@ -1669,6 +1675,8 @@ int test_min_max_local_mem_size(cl_device_id deviceID, cl_context context, cl_co
{
if( memcmp( buffer, "OpenCL 2.0", strlen( "OpenCL 2.0" ) ) == 0 )
min_max_local_mem_size = 16L * 1024L;
else if( memcmp( buffer, "OpenCL 2.1", strlen( "OpenCL 2.1" ) ) != 0 )
min_max_local_mem_size = 16L * 1024L;
else if( memcmp( buffer, "OpenCL 1.2", strlen( "OpenCL 1.2" ) ) != 0 )
min_max_local_mem_size = 16L * 1024L;
else if( memcmp( buffer, "OpenCL 1.1", strlen( "OpenCL 1.1" ) ) != 0 )
@@ -1829,7 +1837,7 @@ int test_min_max_queue_properties(cl_device_id deviceID, cl_context context, cl_
cl_command_queue_properties value;
error = clGetDeviceInfo( deviceID, CL_DEVICE_QUEUE_PROPERTIES, sizeof( value ), &value, 0 );
error = clGetDeviceInfo( deviceID, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, sizeof( value ), &value, 0 );
test_error( error, "Unable to get queue properties" );
if( ( value & CL_QUEUE_PROFILING_ENABLE ) != CL_QUEUE_PROFILING_ENABLE )
@@ -1842,153 +1850,97 @@ int test_min_max_queue_properties(cl_device_id deviceID, cl_context context, cl_
int test_min_max_device_version(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_int error, i;
cl_char buffer[ 4098 ];
size_t length;
// Query for the device version.
Version device_cl_version = get_device_cl_version(deviceID);
log_info("Returned version %s.\n", device_cl_version.to_string().c_str());
// Device version should fit the regex "OpenCL [0-9]+\.[0-9]+ *.*"
error = clGetDeviceInfo( deviceID, CL_DEVICE_VERSION, sizeof( buffer ), buffer, &length );
test_error( error, "Unable to get device version string" );
if( memcmp( buffer, "OpenCL ", strlen( "OpenCL " ) ) != 0 )
{
log_error( "ERROR: Initial part of device version string does not match required format! (returned: %s)\n", (char *)buffer );
return -1;
}
log_info("Returned version %s.\n", buffer);
char *p1 = (char *)buffer + strlen( "OpenCL " );
while( *p1 == ' ' )
p1++;
char *p2 = p1;
if( ! isdigit(*p2) )
{
log_error( "ERROR: Major revision number must follow space behind OpenCL! (returned %s)\n", (char*) buffer );
return -1;
}
while( isdigit( *p2 ) )
p2++;
if( *p2 != '.' )
{
log_error( "ERROR: Version number must contain a decimal point! (returned: %s)\n", (char *)buffer );
return -1;
}
char *p3 = p2 + 1;
if( ! isdigit(*p3) )
{
log_error( "ERROR: Minor revision number is missing or does not abut the decimal point! (returned %s)\n", (char*) buffer );
return -1;
}
while( isdigit( *p3 ) )
p3++;
if( *p3 != ' ' )
{
log_error( "ERROR: A space must appear after the minor version! (returned: %s)\n", (char *)buffer );
return -1;
}
*p2 = ' '; // Put in a space for atoi below.
p2++;
int major = atoi( p1 );
int minor = atoi( p2 );
int minor_revision = 2;
if( getenv("OPENCL_1_0_DEVICE"))
{
minor_revision = 0;
log_info( "WARNING: This test was run with OPENCL_1_0_DEVICE defined! This is not a OpenCL 1.1 or OpenCL 1.2 compatible device!!!\n" );
}
else if( getenv("OPENCL_1_1_DEVICE"))
{
minor_revision = 1;
log_info( "WARNING: This test was run with OPENCL_1_1_DEVICE defined! This is not a OpenCL 1.2 compatible device!!!\n" );
}
if( major * 10 + minor < 10 + minor_revision )
{
log_error( "ERROR: OpenCL device version returned is less than 1.%d! (Returned: %s)\n", minor_revision, (char *)buffer );
return -1;
}
// Sanity checks on the returned values
if( length != (strlen( (char *)buffer ) + 1 ))
{
log_error( "ERROR: Returned length of version string does not match actual length (actual: %d, returned: %d)\n", (int)strlen( (char *)buffer ), (int)length );
return -1;
}
// Make sure 2.x devices support required extensions for 2.x
// note: these extensions are **not** required for devices
// supporting OpenCL-3.0
const char *requiredExtensions2x[] = {
"cl_khr_3d_image_writes",
"cl_khr_image2d_from_buffer",
"cl_khr_depth_images",
};
// Make sure 1.1 devices support required extensions for 1.1
const char *requiredExtensions[] =
{
const char *requiredExtensions11[] = {
"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_byte_addressable_store",
NULL
};
if( major * 10 + minor >= 11 )
if (device_cl_version >= Version(1, 1))
{
char *extensions;
size_t extensions_size = 0;
log_info( "Checking for required extensions for OpenCL 1.1 and later devices...\n" );
if( (error = clGetDeviceInfo(deviceID, CL_DEVICE_EXTENSIONS, 0, NULL, &extensions_size)))
log_info("Checking for required extensions for OpenCL 1.1 and later "
"devices...\n");
for (int i = 0; i < ARRAY_SIZE(requiredExtensions11); i++)
{
log_error( "ERROR: could not get extensions size. Err # %d\n", error );
return -1;
}
if( extensions_size < 1 )
{
log_error( "ERROR: invalid extensions size. Err # %d\n", error );
return -1;
}
extensions = (char*) malloc(extensions_size);
if( NULL == extensions )
{
log_error( "ERROR: cannot allocate %ld bytes to hold extension string.\n", extensions_size );
return -1;
}
memset( extensions, -1, extensions_size );
if( (error = clGetDeviceInfo(deviceID, CL_DEVICE_EXTENSIONS, extensions_size, extensions, NULL)))
{
log_error( "ERROR: could not get extensions. Err # %d\n", error );
free( extensions );
return -1;
}
if( '\0' != extensions[ extensions_size - 1 ] )
{
if( -1 == extensions[ extensions_size - 1 ] )
log_error( "ERROR: extensions size reported incorrectly. Last byte is not NUL. Size too big. Reported: %ld. Should be: %ld\n", extensions_size, strlen(extensions) + 1 );
else
log_error( "ERROR: extensions size reported incorrectly. Last byte is not NUL. Size too small. \n" );
free( extensions );
return -1;
}
for( i = 0; NULL != requiredExtensions[i]; i++ )
{
if( NULL == strstr( extensions, requiredExtensions[i] ) )
if (!is_extension_available(deviceID, requiredExtensions11[i]))
{
log_error( "ERROR: Required extension for 1.1 and greater devices is not in extension string: %s\n", requiredExtensions[i] );
free( extensions );
log_error("ERROR: Required extension for 1.1 and greater "
"devices is not in extension string: %s\n",
requiredExtensions11[i]);
return -1;
}
else
log_info( "\t%s\n", requiredExtensions[i] );
log_info("\t%s\n", requiredExtensions11[i]);
}
if (device_cl_version >= Version(1, 2))
{
log_info("Checking for required extensions for OpenCL 1.2 and "
"later devices...\n");
// The only required extension for an OpenCL-1.2 device is
// cl_khr_fp64 and it is only required if double precision is
// supported.
cl_device_fp_config doubles_supported;
cl_int error = clGetDeviceInfo(deviceID, CL_DEVICE_DOUBLE_FP_CONFIG,
sizeof(doubles_supported),
&doubles_supported, 0);
test_error(error, "Unable to get device double fp config");
if (doubles_supported)
{
if (!is_extension_available(deviceID, "cl_khr_fp64"))
{
log_error(
"ERROR: Required extension for 1.2 and greater devices "
"is not in extension string: cl_khr_fp64\n");
}
else
{
log_info("\t%s\n", "cl_khr_fp64");
}
}
}
if (device_cl_version >= Version(2, 0)
&& device_cl_version < Version(3, 0))
{
log_info("Checking for required extensions for OpenCL 2.0, 2.1 and "
"2.2 devices...\n");
for (int i = 0; i < ARRAY_SIZE(requiredExtensions2x); i++)
{
if (!is_extension_available(deviceID, requiredExtensions2x[i]))
{
log_error("ERROR: Required extension for 2.0, 2.1 and 2.2 "
"devices is not in extension string: %s\n",
requiredExtensions2x[i]);
return -1;
}
else
{
log_info("\t%s\n", requiredExtensions2x[i]);
}
}
}
free( extensions );
}
else
log_info( "WARNING: skipping required extension test -- OpenCL 1.0 device.\n" );
log_info("WARNING: skipping required extension test -- OpenCL 1.0 "
"device.\n");
return 0;
}

View File

@@ -14,7 +14,7 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/testHarness.h"
const char *kernel_with_bool[] = {
@@ -38,8 +38,8 @@ const char *kernel_with_bool[] = {
int test_bool_type(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_program program;
cl_kernel kernel;
clProgramWrapper program;
clKernelWrapper kernel;
int err = create_single_kernel_helper(context,
&program,

View File

@@ -14,8 +14,8 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/conversions.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
#include <sstream>
#include <string>
#include <cmath>
@@ -261,28 +261,9 @@ int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queu
test_error( error, "clGetDeviceInfo failed." );
// test double support
size_t ext_str_size;
error = clGetDeviceInfo(deviceID, CL_DEVICE_EXTENSIONS, 0, NULL, &ext_str_size);
test_error( error, "clGetDeviceInfo failed." );
char* ext_str = new char[ext_str_size+1];
error = clGetDeviceInfo(deviceID, CL_DEVICE_EXTENSIONS, ext_str_size, ext_str, NULL);
test_error( error, "clGetDeviceInfo failed." );
ext_str[ext_str_size] = '\0';
stringstream ss;
ss << ext_str;
while (!ss.eof())
if (is_extension_available(deviceID, "cl_khr_fp64"))
{
string s;
ss >> s;
if (s == "cl_khr_fp64")
{
bdouble = CL_TRUE;
break;
}
bdouble = CL_TRUE;
}
/* Create kernels to test with */
@@ -318,9 +299,6 @@ int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queu
bufOut = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, BUF_SIZE, NULL, &error);
test_error( error, "clCreateBuffer failed." );
clMemWrapper pipe = clCreatePipe(context, CL_MEM_HOST_NO_ACCESS, sizeof(int), 16, NULL, &error);
test_error( error, "clCreatePipe failed." );
error = clSetKernelArg(kernel, 0, sizeof(int), &intarg);
error += clSetKernelArg(kernel, 1, sizeof(float), &farg);
error += clSetKernelArg(kernel, 2, sizeof(structArg), &sa);
@@ -338,7 +316,7 @@ int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queu
error = clEnqueueNDRangeKernel(queue, clonek, 1, NULL, &ndrange1, NULL, 0, NULL, NULL);
test_error( error, "clEnqueueNDRangeKernel failed." );
// shallow clone tests for buffer, svm and pipes
// shallow clone tests for buffer
error = clSetKernelArg(kernel_buf_write, 0, sizeof(cl_mem), &buf);
error += clSetKernelArg(kernel_buf_write, 1, sizeof(int), &write_val);
test_error( error, "clSetKernelArg failed." );
@@ -404,7 +382,6 @@ int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queu
delete [] pbuf;
delete [] pbufRes;
delete [] ext_str;
return 0;
}

View File

@@ -0,0 +1,93 @@
//
// Copyright (c) 2020 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "testBase.h"
static volatile cl_int sDestructorIndex;
void CL_CALLBACK context_destructor_callback(cl_context context, void *userData)
{
int *userPtr = (int *)userData;
// ordering of callbacks is guaranteed, meaning we don't need to do atomic
// operation here
*userPtr = ++sDestructorIndex;
}
int test_context_destructor_callback(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_int error;
clContextWrapper localContext =
clCreateContext(NULL, 1, &deviceID, NULL, NULL, &error);
test_error(error, "Unable to create local context");
// Set up some variables to catch the order in which callbacks are called
volatile int callbackOrders[3] = { 0, 0, 0 };
sDestructorIndex = 0;
// Set up the callbacks
error = clSetContextDestructorCallback(
localContext, context_destructor_callback, (void *)&callbackOrders[0]);
test_error(error, "Unable to set destructor callback");
error = clSetContextDestructorCallback(
localContext, context_destructor_callback, (void *)&callbackOrders[1]);
test_error(error, "Unable to set destructor callback");
error = clSetContextDestructorCallback(
localContext, context_destructor_callback, (void *)&callbackOrders[2]);
test_error(error, "Unable to set destructor callback");
// Now release the context, which SHOULD call the callbacks
error = clReleaseContext(localContext);
test_error(error, "Unable to release local context");
// Note: since we manually released the context, we need to set it to NULL
// to prevent a double-release
localContext = NULL;
// At this point, all three callbacks should have already been called
int numErrors = 0;
for (int i = 0; i < 3; i++)
{
// Spin waiting for the release to finish. If you don't call the
// context_destructor_callback, you will not pass the test.
log_info("\tWaiting for callback %d...\n", i);
int wait = 0;
while (0 == callbackOrders[i])
{
usleep(100000); // 1/10th second
if (++wait >= 10 * 10)
{
log_error("\tERROR: Callback %d was not called within 10 "
"seconds! Assuming failure.\n",
i + 1);
numErrors++;
break;
}
}
if (callbackOrders[i] != 3 - i)
{
log_error("\tERROR: Callback %d was called in the wrong order! "
"(Was called order %d, should have been order %d)\n",
i + 1, callbackOrders[i], 3 - i);
numErrors++;
}
}
return (numErrors > 0) ? TEST_FAIL : TEST_PASS;
}

View File

@@ -14,15 +14,13 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/testHarness.h"
#ifndef _WIN32
#include <unistd.h>
#endif
#include "../../test_common/harness/conversions.h"
extern cl_uint gRandomSeed;
#include "harness/conversions.h"
int test_create_context_from_type(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
@@ -58,7 +56,7 @@ int test_create_context_from_type(cl_device_id deviceID, cl_context context, cl_
cl_context_properties properties[3] = {
(cl_context_properties)CL_CONTEXT_PLATFORM,
(cl_context_properties)platform,
NULL
0
};
context_to_test = clCreateContextFromType(properties, type, notify_callback, NULL, &error);
@@ -68,7 +66,7 @@ int test_create_context_from_type(cl_device_id deviceID, cl_context context, cl_
return -1;
}
queue_to_test = clCreateCommandQueueWithProperties(context_to_test, deviceID, NULL, &error);
queue_to_test = clCreateCommandQueue(context_to_test, deviceID, 0, &error);
test_error(error, "clCreateCommandQueue failed");
if (queue_to_test == NULL) {
log_error("clCreateCommandQueue returned NULL, but error was CL_SUCCESS.");

View File

@@ -14,7 +14,7 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/testHarness.h"
const char *sample_single_kernel[] = {
@@ -521,7 +521,7 @@ int test_repeated_setup_cleanup(cl_device_id deviceID, cl_context context, cl_co
local_context = clCreateContext(NULL, 1, &deviceID, notify_callback, NULL, &error);
test_error( error, "clCreateContext failed");
local_queue = clCreateCommandQueueWithProperties(local_context, deviceID, 0, &error);
local_queue = clCreateCommandQueue(local_context, deviceID, 0, &error);
test_error( error, "clCreateCommandQueue failed");
error = create_single_kernel_helper(local_context, &local_program, NULL, 1, &repeate_test_kernel, NULL);

View File

@@ -14,7 +14,7 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/testHarness.h"
#ifndef _WIN32
#include <unistd.h>
#endif

View File

@@ -15,8 +15,6 @@
//
#include "testBase.h"
extern "C" { extern cl_uint gRandomSeed;}
// This test is designed to stress changing kernel arguments between execute calls (that are asynchronous and thus
// potentially overlapping) to make sure each kernel gets the right arguments

View File

@@ -5585,15 +5585,14 @@ const char * long_arg_info[][72] = {
template<typename arg_info_t>
int test(cl_device_id deviceID, cl_context context, kernel_args_t kernel_args, cl_uint lines_count, arg_info_t arg_info, size_t total_kernels_in_program) {
cl_program program;
cl_kernel kernel;
const size_t max_name_len = 512;
cl_char name[ max_name_len ];
cl_uint arg_count, numArgs;
size_t i, j, size;
int error;
program = clCreateProgramWithSource( context, lines_count, kernel_args, NULL, &error );
clProgramWrapper program =
clCreateProgramWithSource(context, lines_count, kernel_args, NULL, &error);
if ( program == NULL || error != CL_SUCCESS )
{
print_error( error, "Unable to create required arguments kernel program" );
@@ -5704,7 +5703,7 @@ int test(cl_device_id deviceID, cl_context context, kernel_args_t kernel_args, c
{
int kernel_rc = 0;
const char* kernel_name = arg_info[ i ][ 0 ];
kernel = clCreateKernel( program, kernel_name, &error );
clKernelWrapper kernel = clCreateKernel(program, kernel_name, &error);
if( kernel == NULL || error != CL_SUCCESS )
{
log_error( "ERROR: Could not get kernel: %s\n", kernel_name );
@@ -5824,8 +5823,6 @@ int test(cl_device_id deviceID, cl_context context, kernel_args_t kernel_args, c
int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
{
clProgramWrapper program;
clKernelWrapper kernel;
size_t size;
int error;
@@ -5848,37 +5845,7 @@ int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_c
log_info(" o Not testing image kernel arguments.\n");
}
// Get the extensions string for the device
error = clGetDeviceInfo(deviceID, 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(deviceID, 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;
}
if (strstr(extensions, "cl_khr_fp64")) {
if (is_extension_available(deviceID, "cl_khr_fp64")) {
log_info(" o Device claims extension 'cl_khr_fp64'\n");
log_info(" o Expecting SUCCESS when testing double kernel arguments.\n");
supports_double = 1;
@@ -5895,7 +5862,7 @@ int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_c
}
}
if (strstr(extensions, "cl_khr_fp16")) {
if (is_extension_available(deviceID, "cl_khr_fp16")) {
log_info(" o Device claims extension 'cl_khr_fp16'\n");
log_info(" o Expecting SUCCESS when testing halfn* kernel arguments.\n");
supports_half = 1;
@@ -5905,7 +5872,7 @@ int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_c
supports_half = 0;
}
if (strstr(extensions, "cl_khr_int64"))
if (is_extension_available(deviceID, "cl_khr_int64"))
{
log_info(" o Device claims extension 'cl_khr_int64'\n");
log_info(" o Expecting SUCCESS when testing long kernel arguments.\n");

View File

@@ -30,7 +30,7 @@
typedef char const * kernel_args_t[];
kernel_args_t required_kernel_args = {
static kernel_args_t required_kernel_args = {
"typedef float4 typedef_type;\n"
"\n"
"typedef struct struct_type {\n"
@@ -1857,7 +1857,7 @@ kernel_args_t required_kernel_args = {
"\n"
};
const char * required_arg_info[][72] = {
static const char * required_arg_info[][72] = {
// The minimum value of CL_DEVICE_MAX_CONSTANT_ARGS is 4
{
"constant_scalar_p0",
@@ -4038,7 +4038,7 @@ const char * required_arg_info[][72] = {
};
// Support for optional image data type
const char * image_kernel_args[] = {
static const char * image_kernel_args[] = {
"#pragma OPENCL EXTENSION cl_khr_3d_image_writes: enable\n"
"kernel void image_d(read_only image2d_t image2d_td0,\n"
" write_only image2d_t image2d_td1,\n"
@@ -4057,7 +4057,7 @@ const char * image_kernel_args[] = {
"\n"
};
const char * image_arg_info[][67] = {
static const char * image_arg_info[][67] = {
{
"image_d",
(const char *)CL_KERNEL_ARG_ADDRESS_GLOBAL, (const char *)CL_KERNEL_ARG_ACCESS_READ_ONLY, (const char *)(CL_KERNEL_ARG_TYPE_NONE), "image2d_t", "image2d_td0",
@@ -4078,7 +4078,7 @@ const char * image_arg_info[][67] = {
};
// Support for optional double data type
const char * double_kernel_args[] = {
static const char * double_kernel_args[] = {
"kernel void double_scalar_p(constant double*constantdoublep,\n"
" constant double *restrict constantdoublerestrictp,\n"
" global double*globaldoublep,\n"
@@ -4249,7 +4249,7 @@ const char * double_kernel_args[] = {
"\n"
};
const char * double_arg_info[][77] = {
static const char * double_arg_info[][77] = {
{
"double_scalar_p",
(const char *)CL_KERNEL_ARG_ADDRESS_CONSTANT, (const char *)CL_KERNEL_ARG_ACCESS_NONE, (const char *)(CL_KERNEL_ARG_TYPE_CONST), "double*", "constantdoublep",
@@ -4458,7 +4458,7 @@ const char * double_arg_info[][77] = {
// Support for optional half data type
const char * half_kernel_args[] = {
static const char * half_kernel_args[] = {
"#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n"
"\n"
"kernel void half_scalar_p(constant half*constanthalfp,\n"
@@ -4631,7 +4631,7 @@ const char * half_kernel_args[] = {
"\n"
};
const char * half_arg_info[][77] = {
static const char * half_arg_info[][77] = {
{
"half_scalar_p",
(const char *)CL_KERNEL_ARG_ADDRESS_CONSTANT, (const char *)CL_KERNEL_ARG_ACCESS_NONE, (const char *)(CL_KERNEL_ARG_TYPE_CONST), "half*", "constanthalfp",
@@ -4842,15 +4842,14 @@ const char * half_arg_info[][77] = {
template<typename arg_info_t>
int test(cl_device_id deviceID, cl_context context, kernel_args_t kernel_args, cl_uint lines_count, arg_info_t arg_info, size_t total_kernels_in_program) {
cl_program program;
cl_kernel kernel;
const size_t max_name_len = 512;
cl_char name[ max_name_len ];
cl_uint arg_count, numArgs;
size_t i, j, size;
int error;
program = clCreateProgramWithSource( context, lines_count, kernel_args, NULL, &error );
clProgramWrapper program =
clCreateProgramWithSource(context, lines_count, kernel_args, NULL, &error);
if ( program == NULL || error != CL_SUCCESS )
{
print_error( error, "Unable to create required arguments kernel program" );
@@ -4961,7 +4960,7 @@ int test(cl_device_id deviceID, cl_context context, kernel_args_t kernel_args, c
{
int kernel_rc = 0;
const char* kernel_name = arg_info[ i ][ 0 ];
kernel = clCreateKernel( program, kernel_name, &error );
clKernelWrapper kernel = clCreateKernel(program, kernel_name, &error);
if( kernel == NULL || error != CL_SUCCESS )
{
log_error( "ERROR: Could not get kernel: %s\n", kernel_name );
@@ -5079,10 +5078,8 @@ int test(cl_device_id deviceID, cl_context context, kernel_args_t kernel_args, c
}
int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
int test_get_kernel_arg_info_compatibility( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
{
clProgramWrapper program;
clKernelWrapper kernel;
size_t size;
int error;
@@ -5103,37 +5100,7 @@ int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_c
log_info(" o Not testing image kernel arguments.\n");
}
// Get the extensions string for the device
error = clGetDeviceInfo(deviceID, 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(deviceID, 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;
}
if (strstr(extensions, "cl_khr_fp64")) {
if (is_extension_available(deviceID, "cl_khr_fp64")) {
log_info(" o Device claims extension 'cl_khr_fp64'\n");
log_info(" o Expecting SUCCESS when testing double kernel arguments.\n");
supports_double = 1;
@@ -5150,7 +5117,7 @@ int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_c
}
}
if (strstr(extensions, "cl_khr_fp16")) {
if (is_extension_available(deviceID, "cl_khr_fp16")) {
log_info(" o Device claims extension 'cl_khr_fp16'\n");
log_info(" o Expecting SUCCESS when testing halfn* kernel arguments.\n");
supports_half = 1;

View File

@@ -14,7 +14,7 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/conversions.h"
#include "harness/conversions.h"
// This test is designed to stress passing multiple vector parameters to kernels and verifying access between them all
@@ -27,8 +27,6 @@ const char *multi_arg_kernel_source_pattern =
" dst3[tid] = src3[tid];\n"
"}\n";
extern cl_uint gRandomSeed;
#define MAX_ERROR_TOLERANCE 0.0005f
int test_multi_arg_set(cl_device_id device, cl_context context, cl_command_queue queue,

View File

@@ -14,10 +14,8 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/conversions.h"
extern cl_uint gRandomSeed;
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
const char *sample_single_test_kernel[] = {
"__kernel void sample_test(__global float *src, __global int *dst)\n"
@@ -28,20 +26,6 @@ const char *sample_single_test_kernel[] = {
"\n"
"}\n" };
const char *sample_struct_test_kernel[] = {
"typedef struct {\n"
"__global int *A;\n"
"__global int *B;\n"
"} input_pair_t;\n"
"\n"
"__kernel void sample_test(__global input_pair_t *src, __global int *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = src->A[tid] + src->B[tid];\n"
"\n"
"}\n" };
const char *sample_struct_array_test_kernel[] = {
"typedef struct {\n"
"int A;\n"
@@ -111,7 +95,7 @@ int test_get_kernel_info(cl_device_id deviceID, cl_context context, cl_command_q
return -1;
}
error = clGetKernelInfo( kernel, CL_KERNEL_FUNCTION_NAME, NULL, 0, &paramSize );
error = clGetKernelInfo( kernel, CL_KERNEL_FUNCTION_NAME, 0, NULL, &paramSize );
test_error( error, "Unable to get kernel function name param size" );
if( paramSize != strlen( "sample_test" ) + 1 )
{
@@ -157,7 +141,7 @@ int test_get_kernel_info(cl_device_id deviceID, cl_context context, cl_command_q
test_error( error, "Unable to get kernel reference count" );
error = clGetKernelInfo( kernel, CL_KERNEL_PROGRAM, NULL, 0, &paramSize );
error = clGetKernelInfo( kernel, CL_KERNEL_PROGRAM, 0, NULL, &paramSize );
test_error( error, "Unable to get kernel program param size" );
if( paramSize != sizeof( testProgram ) )
{
@@ -194,11 +178,13 @@ int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, c
clKernelWrapper kernel;
clMemWrapper streams[2];
size_t threads[1], localThreads[1];
cl_float inputData[100];
cl_int outputData[100];
RandomSeed seed( gRandomSeed );
int i;
num_elements = 100;
std::vector<cl_float> inputData(num_elements);
std::vector<cl_int> outputData(num_elements);
/* Create a kernel to test with */
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_single_test_kernel, "sample_test" ) != 0 )
{
@@ -206,18 +192,20 @@ int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, c
}
/* Create some I/O streams */
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float) * 100, NULL, &error);
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_float) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 100, NULL, &error);
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_int) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
/* Write some test data */
memset( outputData, 0, sizeof( outputData ) );
for (i=0; i<100; i++)
for (i = 0; i < num_elements; i++)
inputData[i] = get_random_float(-(float) 0x7fffffff, (float) 0x7fffffff, seed);
error = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*100, (void *)inputData, 0, NULL, NULL);
error = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0,
sizeof(cl_float) * num_elements,
(void *)inputData.data(), 0, NULL, NULL);
test_error( error, "Unable to set testing kernel data" );
/* Set the arguments */
@@ -227,17 +215,19 @@ int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, c
test_error( error, "Unable to set kernel arguments" );
/* Test running the kernel and verifying it */
threads[0] = (size_t)100;
threads[0] = (size_t)num_elements;
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
test_error( error, "Unable to get work group size to use" );
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<100; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != (int)inputData[i])
{
@@ -254,10 +244,12 @@ int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, c
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<100; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != (int)inputData[i])
{
@@ -274,10 +266,12 @@ int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, c
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<100; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != (int)inputData[i])
{
@@ -291,10 +285,12 @@ int test_execute_kernel_local_sizes(cl_device_id deviceID, cl_context context, c
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*100, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<100; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != (int)inputData[i])
{
@@ -313,11 +309,13 @@ int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_c
clKernelWrapper kernel;
clMemWrapper streams[2];
size_t threads[1], localThreads[1];
cl_float inputData[10];
cl_int outputData[10];
RandomSeed seed( gRandomSeed );
int i;
num_elements = 10;
std::vector<cl_float> inputData(num_elements);
std::vector<cl_int> outputData(num_elements);
/* Create a kernel to test with */
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_single_test_kernel, "sample_test" ) != 0 )
{
@@ -325,18 +323,20 @@ int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_c
}
/* Create some I/O streams */
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_float) * 10, NULL, &error);
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_float) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_int) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
/* Write some test data */
memset( outputData, 0, sizeof( outputData ) );
for (i=0; i<10; i++)
for (i = 0; i < num_elements; i++)
inputData[i] = get_random_float(-(float) 0x7fffffff, (float) 0x7fffffff, seed);
error = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*10, (void *)inputData, 0, NULL, NULL);
error = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0,
sizeof(cl_float) * num_elements,
(void *)inputData.data(), 0, NULL, NULL);
test_error( error, "Unable to set testing kernel data" );
/* Test setting the arguments by index manually */
@@ -347,7 +347,7 @@ int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_c
/* Test running the kernel and verifying it */
threads[0] = (size_t)10;
threads[0] = (size_t)num_elements;
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
test_error( error, "Unable to get work group size to use" );
@@ -355,10 +355,12 @@ int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_c
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<10; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != (int)inputData[i])
{
@@ -370,88 +372,6 @@ int test_set_kernel_arg_by_index(cl_device_id deviceID, cl_context context, cl_c
return 0;
}
int test_set_kernel_arg_struct(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int error;
cl_program program;
cl_kernel kernel;
void *args[2];
cl_mem outStream;
size_t threads[1], localThreads[1];
cl_int outputData[10];
int i;
cl_int randomTestDataA[10], randomTestDataB[10];
MTdata d;
struct img_pair_t
{
cl_mem streamA;
cl_mem streamB;
} image_pair;
/* Create a kernel to test with */
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_struct_test_kernel, "sample_test" ) != 0 )
{
return -1;
}
/* Create some I/O streams */
d = init_genrand( gRandomSeed );
for( i = 0; i < 10; i++ )
{
randomTestDataA[i] = (cl_int)genrand_int32(d);
randomTestDataB[i] = (cl_int)genrand_int32(d);
}
free_mtdata(d); d = NULL;
image_pair.streamA = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataA, &error);
test_error( error, "Creating test array failed" );
image_pair.streamB = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataB, &error);
test_error( error, "Creating test array failed" );
outStream = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
test_error( error, "Creating test array failed" );
/* Set the arguments */
args[0] = &image_pair;
args[1] = outStream;
error = clSetKernelArg(kernel, 0, sizeof( image_pair ), &image_pair);
test_error( error, "Unable to set indexed kernel arguments" );
error = clSetKernelArg(kernel, 1, sizeof( cl_mem ), &args[1]);
test_error( error, "Unable to set indexed kernel arguments" );
/* Test running the kernel and verifying it */
threads[0] = (size_t)10;
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
test_error( error, "Unable to get work group size to use" );
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, outStream, CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
test_error( error, "Unable to get result data" );
for (i=0; i<10; i++)
{
if (outputData[i] != randomTestDataA[i] + randomTestDataB[i])
{
log_error( "ERROR: Data did not verify!\n" );
return -1;
}
}
clReleaseMemObject( image_pair.streamA );
clReleaseMemObject( image_pair.streamB );
clReleaseMemObject( outStream );
clReleaseKernel( kernel );
clReleaseProgram( program );
return 0;
}
int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int error;
@@ -459,16 +379,19 @@ int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_c
clKernelWrapper kernel;
clMemWrapper streams[3];
size_t threads[1], localThreads[1];
cl_int outputData[10];
int i;
cl_int randomTestDataA[10], randomTestDataB[10];
cl_ulong maxSize;
MTdata d;
num_elements = 10;
std::vector<cl_int> outputData(num_elements);
std::vector<cl_int> randomTestDataA(num_elements);
std::vector<cl_int> randomTestDataB(num_elements);
/* Verify our test buffer won't be bigger than allowed */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( maxSize ), &maxSize, 0 );
test_error( error, "Unable to get max constant buffer size" );
if( maxSize < sizeof( cl_int ) * 10 )
if (maxSize < sizeof(cl_int) * num_elements)
{
log_error( "ERROR: Unable to test constant argument to kernel: max size of constant buffer is reported as %d!\n", (int)maxSize );
return -1;
@@ -482,18 +405,23 @@ int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_c
/* Create some I/O streams */
d = init_genrand( gRandomSeed );
for( i = 0; i < 10; i++ )
for (i = 0; i < num_elements; i++)
{
randomTestDataA[i] = (cl_int)genrand_int32(d) & 0xffffff; /* Make sure values are positive, just so we don't have to */
randomTestDataB[i] = (cl_int)genrand_int32(d) & 0xffffff; /* deal with overflow on the verification */
}
free_mtdata(d); d = NULL;
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataA, &error);
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR),
sizeof(cl_int) * num_elements,
randomTestDataA.data(), &error);
test_error( error, "Creating test array failed" );
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataB, &error);
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR),
sizeof(cl_int) * num_elements,
randomTestDataB.data(), &error);
test_error( error, "Creating test array failed" );
streams[2] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
streams[2] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_int) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
/* Set the arguments */
@@ -506,7 +434,7 @@ int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_c
/* Test running the kernel and verifying it */
threads[0] = (size_t)10;
threads[0] = (size_t)num_elements;
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
test_error( error, "Unable to get work group size to use" );
@@ -514,10 +442,12 @@ int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_c
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[2], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[2], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<10; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != randomTestDataA[i] + randomTestDataB[i])
{
@@ -536,17 +466,19 @@ int test_set_kernel_arg_struct_array(cl_device_id deviceID, cl_context context,
clKernelWrapper kernel;
clMemWrapper streams[2];
size_t threads[1], localThreads[1];
cl_int outputData[10];
int i;
MTdata d;
num_elements = 10;
std::vector<cl_int> outputData(num_elements);
typedef struct img_pair_type
{
int A;
int B;
} image_pair_t;
image_pair_t image_pair[ 10 ];
std::vector<image_pair_t> image_pair(num_elements);
/* Create a kernel to test with */
@@ -557,16 +489,19 @@ int test_set_kernel_arg_struct_array(cl_device_id deviceID, cl_context context,
/* Create some I/O streams */
d = init_genrand( gRandomSeed );
for( i = 0; i < 10; i++ )
for (i = 0; i < num_elements; i++)
{
image_pair[i].A = (cl_int)genrand_int32(d);
image_pair[i].A = (cl_int)genrand_int32(d);
image_pair[i].B = (cl_int)genrand_int32(d);
}
free_mtdata(d); d = NULL;
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(image_pair_t) * 10, (void *)image_pair, &error);
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR),
sizeof(image_pair_t) * num_elements,
(void *)image_pair.data(), &error);
test_error( error, "Creating test array failed" );
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_int) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
/* Set the arguments */
@@ -576,7 +511,7 @@ int test_set_kernel_arg_struct_array(cl_device_id deviceID, cl_context context,
test_error( error, "Unable to set indexed kernel arguments" );
/* Test running the kernel and verifying it */
threads[0] = (size_t)10;
threads[0] = (size_t)num_elements;
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
test_error( error, "Unable to get work group size to use" );
@@ -584,10 +519,12 @@ int test_set_kernel_arg_struct_array(cl_device_id deviceID, cl_context context,
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<10; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != image_pair[i].A + image_pair[i].B)
{
@@ -635,11 +572,12 @@ int test_kernel_global_constant(cl_device_id deviceID, cl_context context, cl_co
clKernelWrapper kernel;
clMemWrapper streams[2];
size_t threads[1], localThreads[1];
cl_int outputData[10];
int i;
cl_int randomTestDataA[10];
MTdata d;
num_elements = 10;
std::vector<cl_int> outputData(num_elements);
std::vector<cl_int> randomTestDataA(num_elements);
/* Create a kernel to test with */
if( create_single_kernel_helper( context, &program, &kernel, 1, sample_const_global_test_kernel, "sample_test" ) != 0 )
@@ -649,15 +587,18 @@ int test_kernel_global_constant(cl_device_id deviceID, cl_context context, cl_co
/* Create some I/O streams */
d = init_genrand( gRandomSeed );
for( i = 0; i < 10; i++ )
for (i = 0; i < num_elements; i++)
{
randomTestDataA[i] = (cl_int)genrand_int32(d) & 0xffff; /* Make sure values are positive and small, just so we don't have to */
}
free_mtdata(d); d = NULL;
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR), sizeof(cl_int) * 10, randomTestDataA, &error);
streams[0] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_COPY_HOST_PTR),
sizeof(cl_int) * num_elements,
randomTestDataA.data(), &error);
test_error( error, "Creating test array failed" );
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE), sizeof(cl_int) * 10, NULL, &error);
streams[1] = clCreateBuffer(context, (cl_mem_flags)(CL_MEM_READ_WRITE),
sizeof(cl_int) * num_elements, NULL, &error);
test_error( error, "Creating test array failed" );
/* Set the arguments */
@@ -668,7 +609,7 @@ int test_kernel_global_constant(cl_device_id deviceID, cl_context context, cl_co
/* Test running the kernel and verifying it */
threads[0] = (size_t)10;
threads[0] = (size_t)num_elements;
error = get_max_common_work_group_size( context, kernel, threads[0], &localThreads[0] );
test_error( error, "Unable to get work group size to use" );
@@ -676,10 +617,12 @@ int test_kernel_global_constant(cl_device_id deviceID, cl_context context, cl_co
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Kernel execution failed" );
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, sizeof(cl_int)*10, (void *)outputData, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
(void *)outputData.data(), 0, NULL, NULL);
test_error( error, "Unable to get result data" );
for (i=0; i<10; i++)
for (i = 0; i < num_elements; i++)
{
if (outputData[i] != randomTestDataA[i] + 1024)
{

View File

@@ -14,10 +14,8 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/testHarness.h"
extern cl_uint gRandomSeed;
#include "harness/typeWrappers.h"
#include "harness/testHarness.h"
#define TEST_MEM_OBJECT_PARAM( mem, paramName, val, expected, name, type, cast ) \
@@ -497,7 +495,11 @@ int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_objec
imageInfo.image_width = imageInfo.image_height = imageInfo.image_depth = 1;
imageInfo.image_array_size = 0;
imageInfo.num_mip_levels = imageInfo.num_samples = 0;
#ifdef CL_VERSION_2_0
imageInfo.mem_object = NULL;
#else
imageInfo.buffer = NULL;
#endif
d = init_genrand( gRandomSeed );

View File

@@ -0,0 +1,275 @@
//
// Copyright (c) 2020 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 "harness/propertyHelpers.h"
#include "harness/typeWrappers.h"
#include <vector>
#include <algorithm>
typedef enum
{
image,
buffer
} mem_obj_type;
struct test_data
{
mem_obj_type obj_t;
std::vector<cl_mem_properties> properties;
std::string description;
std::string src;
std::string kernel_name;
};
static int create_object_and_check_properties(cl_context context,
clMemWrapper& test_object,
test_data test_case,
cl_mem_flags flags,
std::vector<cl_uint> local_data,
cl_uint size_x, cl_uint size_y)
{
cl_int error = CL_SUCCESS;
if (test_case.obj_t == image)
{
cl_image_format format;
format.image_channel_order = CL_RGBA;
format.image_channel_data_type = CL_UNSIGNED_INT32;
cl_image_desc desc;
memset(&desc, 0x0, sizeof(cl_image_desc));
desc.image_type = CL_MEM_OBJECT_IMAGE2D;
desc.image_width = size_x;
desc.image_height = size_y;
if (test_case.properties.size() == 0)
{
test_object =
clCreateImageWithProperties(context, NULL, flags, &format,
&desc, local_data.data(), &error);
}
else
{
test_object = clCreateImageWithProperties(
context, test_case.properties.data(), flags, &format, &desc,
local_data.data(), &error);
}
test_error(error, "clCreateImageWithProperties failed");
}
if (test_case.obj_t == buffer)
{
if (test_case.properties.size() == 0)
{
test_object = clCreateBufferWithProperties(
context, NULL, flags, local_data.size() * sizeof(cl_uint),
local_data.data(), &error);
}
else
{
test_object = clCreateBufferWithProperties(
context, test_case.properties.data(), flags,
local_data.size() * sizeof(cl_uint), local_data.data(), &error);
}
test_error(error, "clCreateBufferWithProperties failed.");
}
std::vector<cl_mem_properties> check_properties;
size_t set_size = 0;
error =
clGetMemObjectInfo(test_object, CL_MEM_PROPERTIES, 0, NULL, &set_size);
test_error(error,
"clGetMemObjectInfo failed asking for CL_MEM_PROPERTIES size.");
if (set_size == 0 && test_case.properties.size() == 0)
{
return TEST_PASS;
}
if (set_size != test_case.properties.size() * sizeof(cl_mem_properties))
{
log_error("ERROR: CL_MEM_PROPERTIES size is %d, expected %d.\n",
set_size,
test_case.properties.size() * sizeof(cl_queue_properties));
return TEST_FAIL;
}
cl_uint number_of_props = set_size / sizeof(cl_mem_properties);
check_properties.resize(number_of_props);
error = clGetMemObjectInfo(test_object, CL_MEM_PROPERTIES, set_size,
check_properties.data(), NULL);
test_error(error,
"clGetMemObjectInfo failed asking for CL_MEM_PROPERTIES.");
error = compareProperties(check_properties, test_case.properties);
return error;
}
static int run_test_query_properties(cl_context context, cl_command_queue queue,
test_data test_case)
{
int error = CL_SUCCESS;
log_info("\nTC description: %s\n", test_case.description.c_str());
clProgramWrapper program;
clKernelWrapper kernel;
clMemWrapper obj_src;
clMemWrapper obj_dst;
clEventWrapper event;
MTdata init_generator = init_genrand(gRandomSeed);
cl_mem_flags flags;
cl_uint size_x = 4;
cl_uint size_y = 4;
size_t size = size_x * size_y * 4;
size_t global_dim[2] = { size_x, size_y };
const size_t origin[3] = { 0, 0, 0 };
const size_t region[3] = { size_x, size_y, 1 };
std::vector<cl_uint> src_data(size);
std::vector<cl_uint> dst_data(size);
generate_random_data(kUInt, size, init_generator, src_data.data());
generate_random_data(kUInt, size, init_generator, dst_data.data());
free_mtdata(init_generator);
init_generator = NULL;
const char* kernel_src = test_case.src.c_str();
error =
create_single_kernel_helper(context, &program, &kernel, 1, &kernel_src,
test_case.kernel_name.c_str());
test_error(error, "create_single_kernel_helper failed");
flags = (cl_mem_flags)(CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR);
error = create_object_and_check_properties(context, obj_src, test_case,
flags, src_data, size_x, size_y);
test_error(error, "create_object_and_check_properties obj_src failed.");
flags = (cl_mem_flags)(CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR);
error = create_object_and_check_properties(context, obj_dst, test_case,
flags, dst_data, size_x, size_y);
test_error(error, "create_object_and_check_properties obj_dst failed.");
error = clSetKernelArg(kernel, 0, sizeof(obj_src), &obj_src);
test_error(error, "clSetKernelArg 0 failed.");
error = clSetKernelArg(kernel, 1, sizeof(obj_dst), &obj_dst);
test_error(error, "clSetKernelArg 1 failed.");
if (test_case.obj_t == image)
{
error = clEnqueueNDRangeKernel(queue, kernel, 2, NULL, global_dim, NULL,
0, NULL, &event);
test_error(error, "clEnqueueNDRangeKernel failed.");
error = clWaitForEvents(1, &event);
test_error(error, "clWaitForEvents failed.");
error = clEnqueueReadImage(queue, obj_dst, CL_TRUE, origin, region, 0,
0, dst_data.data(), 0, NULL, NULL);
test_error(error, "clEnqueueReadImage failed.");
}
if (test_case.obj_t == buffer)
{
error = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &size, NULL, 0,
NULL, &event);
test_error(error, "clEnqueueNDRangeKernel failed.");
error = clWaitForEvents(1, &event);
test_error(error, "clWaitForEvents failed.");
error = clEnqueueReadBuffer(queue, obj_dst, CL_TRUE, 0,
dst_data.size() * sizeof(cl_uint),
dst_data.data(), 0, NULL, NULL);
test_error(error, "clEnqueueReadBuffer failed.");
}
for (size_t i = 0; i < size; ++i)
{
if (dst_data[i] != src_data[i])
{
log_error("ERROR: Output results mismatch.");
return TEST_FAIL;
}
}
log_info("TC result: passed\n");
return TEST_PASS;
}
int test_image_properties_queries(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
int error = CL_SUCCESS;
cl_bool supports_images = CL_TRUE;
error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE_SUPPORT,
sizeof(supports_images), &supports_images, NULL);
test_error(error, "clGetDeviceInfo for CL_DEVICE_IMAGE_SUPPORT failed");
if (supports_images == CL_FALSE)
{
log_info("No image support on current device - skipped\n");
return TEST_SKIPPED_ITSELF;
}
std::vector<test_data> test_cases;
std::string test_kernel = { "__kernel void data_copy(read_only image2d_t "
"src, write_only image2d_t dst)\n"
"{\n"
" int tid_x = get_global_id(0);\n"
" int tid_y = get_global_id(1);\n"
" int2 coords = (int2)(tid_x, tid_y);\n"
" uint4 val = read_imageui(src, coords);\n"
" write_imageui(dst, coords, val);\n"
"\n"
"}\n" };
test_cases.push_back(
{ image, { 0 }, "image, 0 properties", test_kernel, "data_copy" });
test_cases.push_back(
{ image, {}, "image, NULL properties", test_kernel, "data_copy" });
for (auto test_case : test_cases)
{
error |= run_test_query_properties(context, queue, test_case);
}
return error;
}
int test_buffer_properties_queries(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
int error = CL_SUCCESS;
std::vector<test_data> test_cases;
std::string test_kernel = {
"__kernel void data_copy(__global int *src, __global int *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = src[tid];\n"
"\n"
"}\n"
};
test_cases.push_back(
{ buffer, { 0 }, "buffer, 0 properties", test_kernel, "data_copy" });
test_cases.push_back(
{ buffer, {}, "buffer, NULL properties", test_kernel, "data_copy" });
for (auto test_case : test_cases)
{
error |= run_test_query_properties(context, queue, test_case);
}
return error;
}

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2020 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
@@ -17,92 +17,109 @@
static volatile cl_int sDestructorIndex;
void CL_CALLBACK mem_destructor_callback( cl_mem memObject, void * userData )
void CL_CALLBACK mem_destructor_callback(cl_mem memObject, void *userData)
{
int * userPtr = (int *)userData;
int *userPtr = (int *)userData;
// ordering of callbacks is guaranteed, meaning we don't need to do atomic operation here
// ordering of callbacks is guaranteed, meaning we don't need to do atomic
// operation here
*userPtr = ++sDestructorIndex;
}
#ifndef ABS
#define ABS( x ) ( ( x < 0 ) ? -x : x )
#endif
int test_mem_object_destructor_callback_single( clMemWrapper &memObject )
int test_mem_object_destructor_callback_single(clMemWrapper &memObject)
{
cl_int error;
int i;
// Set up some variables to catch the order in which callbacks are called
volatile int callbackOrders[ 3 ] = { 0, 0, 0 };
volatile int callbackOrders[3] = { 0, 0, 0 };
sDestructorIndex = 0;
// Set up the callbacks
error = clSetMemObjectDestructorCallback( memObject, mem_destructor_callback, (void*) &callbackOrders[ 0 ] );
test_error( error, "Unable to set destructor callback" );
error = clSetMemObjectDestructorCallback(memObject, mem_destructor_callback,
(void *)&callbackOrders[0]);
test_error(error, "Unable to set destructor callback");
error = clSetMemObjectDestructorCallback( memObject, mem_destructor_callback, (void*) &callbackOrders[ 1 ] );
test_error( error, "Unable to set destructor callback" );
error = clSetMemObjectDestructorCallback(memObject, mem_destructor_callback,
(void *)&callbackOrders[1]);
test_error(error, "Unable to set destructor callback");
error = clSetMemObjectDestructorCallback( memObject, mem_destructor_callback, (void*) &callbackOrders[ 2 ] );
test_error( error, "Unable to set destructor callback" );
error = clSetMemObjectDestructorCallback(memObject, mem_destructor_callback,
(void *)&callbackOrders[2]);
test_error(error, "Unable to set destructor callback");
// Now release the buffer, which SHOULD call the callbacks
error = clReleaseMemObject( memObject );
test_error( error, "Unable to release test buffer" );
error = clReleaseMemObject(memObject);
test_error(error, "Unable to release test buffer");
// Note: since we manually released the mem wrapper, we need to set it to NULL to prevent a double-release
// Note: since we manually released the mem wrapper, we need to set it to
// NULL to prevent a double-release
memObject = NULL;
// At this point, all three callbacks should have already been called
int numErrors = 0;
for( i = 0; i < 3; i++ )
for (int i = 0; i < 3; i++)
{
// Spin waiting for the release to finish. If you don't call the mem_destructor_callback, you will not
// pass the test. bugzilla 6316
while( 0 == callbackOrders[i] )
{}
if( ABS( callbackOrders[ i ] ) != 3-i )
// Spin waiting for the release to finish. If you don't call the
// mem_destructor_callback, you will not pass the test. bugzilla 6316
log_info("\tWaiting for callback %d...\n", i);
int wait = 0;
while (0 == callbackOrders[i])
{
log_error( "\tERROR: Callback %d was called in the wrong order! (Was called order %d, should have been order %d)\n",
i+1, ABS( callbackOrders[ i ] ), i );
usleep(100000); // 1/10th second
if (++wait >= 10 * 10)
{
log_error("\tERROR: Callback %d was not called within 10 "
"seconds! Assuming failure.\n",
i + 1);
numErrors++;
break;
}
}
if (callbackOrders[i] != 3 - i)
{
log_error("\tERROR: Callback %d was called in the wrong order! "
"(Was called order %d, should have been order %d)\n",
i + 1, callbackOrders[i], 3 - i);
numErrors++;
}
}
return ( numErrors > 0 ) ? -1 : 0;
return (numErrors > 0) ? TEST_FAIL : TEST_PASS;
}
int test_mem_object_destructor_callback(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
int test_mem_object_destructor_callback(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements)
{
clMemWrapper testBuffer, testImage;
cl_int error;
// Create a buffer and an image to test callbacks against
testBuffer = clCreateBuffer( context, CL_MEM_READ_WRITE, 1024, NULL, &error );
test_error( error, "Unable to create testing buffer" );
testBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE, 1024, NULL, &error);
test_error(error, "Unable to create testing buffer");
if( test_mem_object_destructor_callback_single( testBuffer ) != 0 )
if (test_mem_object_destructor_callback_single(testBuffer) != TEST_PASS)
{
log_error( "ERROR: Destructor callbacks for buffer object FAILED\n" );
return -1;
log_error("ERROR: Destructor callbacks for buffer object FAILED\n");
return TEST_FAIL;
}
if( checkForImageSupport( deviceID ) == 0 )
if (checkForImageSupport(deviceID) == 0)
{
cl_image_format imageFormat = { CL_RGBA, CL_SIGNED_INT8 };
testImage = create_image_2d( context, CL_MEM_READ_ONLY, &imageFormat, 16, 16, 0, NULL, &error );
test_error( error, "Unable to create testing image" );
testImage = create_image_2d(context, CL_MEM_READ_ONLY, &imageFormat, 16,
16, 0, NULL, &error);
test_error(error, "Unable to create testing image");
if( test_mem_object_destructor_callback_single( testImage ) != 0 )
if (test_mem_object_destructor_callback_single(testImage) != TEST_PASS)
{
log_error( "ERROR: Destructor callbacks for image object FAILED\n" );
return -1;
log_error("ERROR: Destructor callbacks for image object FAILED\n");
return TEST_FAIL;
}
}
return 0;
return TEST_PASS;
}

View File

@@ -19,9 +19,7 @@
#include <unistd.h>
#endif
#include "../../test_common/harness/conversions.h"
extern cl_uint gRandomSeed;
#include "harness/conversions.h"
static void CL_CALLBACK test_native_kernel_fn( void *userData )
{

View File

@@ -22,8 +22,8 @@
#include <CL/cl_platform.h>
#endif
#include "testBase.h"
#include "../../test_common/harness/typeWrappers.h"
#include "../../test_common/harness/testHarness.h"
#include "harness/typeWrappers.h"
#include "harness/testHarness.h"
#include "procs.h"
@@ -62,7 +62,7 @@ static int test_setargs_and_execution(cl_command_queue queue, cl_kernel kernel,
unsigned int i;
cl_int status;
char *typestr;
const char *typestr;
if (type == NON_NULL_PATH) {
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);

View File

@@ -14,9 +14,11 @@
// limitations under the License.
//
#include "testBase.h"
#include "../../test_common/harness/imageHelpers.h"
#include "harness/imageHelpers.h"
#include "harness/propertyHelpers.h"
#include <stdlib.h>
#include <ctype.h>
#include <algorithm>
int test_get_platform_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
@@ -209,6 +211,40 @@ int test_get_sampler_info(cl_device_id deviceID, cl_context context, cl_command_
return -1;
}
Version version = get_device_cl_version(deviceID);
if (version >= Version(3, 0))
{
std::vector<cl_sampler_properties> test_properties(
properties, properties + ARRAY_SIZE(properties));
std::vector<cl_sampler_properties> check_properties;
size_t set_size;
error = clGetSamplerInfo(sampler, CL_SAMPLER_PROPERTIES, 0, NULL,
&set_size);
test_error(
error,
"clGetSamplerInfo failed asking for CL_SAMPLER_PROPERTIES size.");
if (set_size != test_properties.size() * sizeof(cl_sampler_properties))
{
log_error("ERROR: CL_SAMPLER_PROPERTIES size is %d, expected %d.\n",
set_size,
test_properties.size() * sizeof(cl_sampler_properties));
return TEST_FAIL;
}
cl_uint number_of_props = set_size / sizeof(cl_sampler_properties);
check_properties.resize(number_of_props);
error = clGetSamplerInfo(sampler, CL_SAMPLER_PROPERTIES, set_size,
check_properties.data(), 0);
test_error(error,
"clGetSamplerInfo failed asking for CL_SAMPLER_PROPERTIES.");
error = compareProperties(check_properties, test_properties);
test_error(error, "checkProperties mismatch.");
}
return 0;
}
@@ -237,6 +273,9 @@ int test_get_command_queue_info(cl_device_id deviceID, cl_context context, cl_co
clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, sizeof(device_props), &device_props, NULL);
log_info("CL_DEVICE_QUEUE_ON_HOST_PROPERTIES is %d\n", (int)device_props);
// Mask off vendor extension properties. Only test standard OpenCL properties
device_props &= CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE|CL_QUEUE_PROFILING_ENABLE;
queue_props[1] = device_props;
clCommandQueueWrapper queue = clCreateCommandQueueWithProperties( context, deviceID, &queue_props[0], &error );
test_error( error, "Unable to create command queue to test with" );
@@ -397,7 +436,8 @@ int test_get_device_info(cl_device_id deviceID, cl_context context, cl_command_q
// extensions can support double but may not support cl_khr_fp64, which implies math library support.
cl_uint baseAddrAlign;
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, baseAddrAlign, "base address alignment", "%d bytes", int )
TEST_DEVICE_PARAM(deviceID, CL_DEVICE_MEM_BASE_ADDR_ALIGN, baseAddrAlign,
"base address alignment", "%d bits", int)
cl_uint maxDataAlign;
TEST_DEVICE_PARAM( deviceID, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, maxDataAlign, "min data type alignment", "%d bytes", int )

Some files were not shown because too many files have changed in this diff Show More