Merge branch 'main' into cl_khr_unified_svm

This commit is contained in:
Ben Ashbaugh
2025-07-01 17:27:24 -07:00
547 changed files with 7396 additions and 6146 deletions

View File

@@ -5,34 +5,26 @@ jobs:
build:
name: Build ${{ matrix.os }} ${{ matrix.arch }}${{ matrix.extra }}
runs-on: ${{ matrix.os }}
env:
JOB_ARCHITECTURE: ${{ matrix.arch }}
JOB_ENABLE_GL: ${{ matrix.gl }}
JOB_ENABLE_DEBUG: ${{ matrix.debug }}
strategy:
fail-fast: false
matrix:
mainmatrix: [true]
build-type: [Release]
gl: [0]
os: [ubuntu-22.04, macos-latest, windows-latest]
include:
- os: ubuntu-22.04
mainmatrix: true
gl: 1
extra: " gl"
- os: ubuntu-22.04
mainmatrix: false
arch: arm
- os: ubuntu-22.04
mainmatrix: false
arch: aarch64
debug: 1
build-type: Debug
extra: " debug"
- os: ubuntu-22.04
mainmatrix: false
arch: android-arm
android_arch_abi: armeabi-v7a
- os: ubuntu-22.04
mainmatrix: false
arch: android-aarch64
android_arch_abi: arm64-v8a
steps:
@@ -84,9 +76,101 @@ jobs:
echo "ANDROID_NDK=$ANDROID_NDK" >> $GITHUB_ENV
export ANDROID_ARCH_ABI=${{ matrix.android_arch_abi }}
echo "ANDROID_ARCH_ABI=$ANDROID_ARCH_ABI" >> $GITHUB_ENV
- name: Build
- name: Prepare CMake Toolchain file
shell: bash
run: ./presubmit.sh
run: |
if [[ '${{ matrix.arch }}' == android-* ]]; then
TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake
else
TOOLCHAIN_FILE='${{ github.workspace }}'/toolchain.cmake
touch ${TOOLCHAIN_FILE}
fi
TOOLCHAIN_PREFIX_arm=arm-linux-gnueabihf
TOOLCHAIN_PREFIX_aarch64=aarch64-linux-gnu
if [[ '${{ matrix.arch }}' != android-* ]]; then
if [[ '${{ matrix.arch }}' != "" && ${RUNNER_OS} != "Windows" ]]; then
TOOLCHAIN_PREFIX_VAR=TOOLCHAIN_PREFIX_${{ matrix.arch }}
TOOLCHAIN_PREFIX=${!TOOLCHAIN_PREFIX_VAR}
echo "SET(CMAKE_SYSTEM_NAME Linux)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_SYSTEM_PROCESSOR ${{ matrix.arch }})" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" >> ${TOOLCHAIN_FILE}
fi
fi
echo "TOOLCHAIN_FILE=${TOOLCHAIN_FILE}" >> $GITHUB_ENV
- name: Prepare Android CMake arguments
if: ${{ matrix.arch == 'android-arm' || matrix.arch == 'android-aarch64' }}
shell: bash
run: |
echo "CMAKE_CONFIG_ARGS_ANDROID=-DCMAKE_ANDROID_ARCH_ABI=${ANDROID_ARCH_ABI}" >> $GITHUB_ENV
- name: Fetch and build OpenCL ICD Loader
shell: bash
run: |
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
cd OpenCL-ICD-Loader
mkdir build
cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DOPENCL_ICD_LOADER_HEADERS_DIR='${{ github.workspace }}'/OpenCL-Headers/ \
"${CMAKE_CONFIG_ARGS_ANDROID}"
cmake --build . --parallel
- name: Fetch Vulkan Headers
shell: bash
run: |
git clone https://github.com/KhronosGroup/Vulkan-Headers.git
- name: Fetch and build Vulkan Loader
if: ${{ matrix.arch != 'android-arm' && matrix.arch != 'android-aarch64' }}
shell: bash
run: |
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
cd Vulkan-Loader
mkdir build
cd build
python3 ../scripts/update_deps.py
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DBUILD_WSI_XLIB_SUPPORT=OFF \
-DBUILD_WSI_XCB_SUPPORT=OFF \
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
-C helper.cmake ..
cmake --build . --parallel
- name: Configure and build
shell: bash
run: |
mkdir build
cd build
if [[ ${RUNNER_OS} == "Windows" ]]; then
CMAKE_OPENCL_LIBRARIES_OPTION="OpenCL"
else
CMAKE_OPENCL_LIBRARIES_OPTION="-lOpenCL"
if [[ '${{ matrix.arch }}' != android-* ]]; then
CMAKE_OPENCL_LIBRARIES_OPTION="${CMAKE_OPENCL_LIBRARIES_OPTION} -lpthread"
fi
fi
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
-DCMAKE_CACHE_OPTIONS="-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache" \
-DCL_INCLUDE_DIR='${{ github.workspace }}'/OpenCL-Headers \
-DCL_LIB_DIR='${{ github.workspace }}'/OpenCL-ICD-Loader/build \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin \
-DOPENCL_LIBRARIES="${CMAKE_OPENCL_LIBRARIES_OPTION}" \
-DUSE_CL_EXPERIMENTAL=ON \
-DGL_IS_SUPPORTED=${{ matrix.gl }} \
-DVULKAN_IS_SUPPORTED=ON \
-DVULKAN_INCLUDE_DIR='${{ github.workspace }}'/Vulkan-Headers/include/ \
-DVULKAN_LIB_DIR='${{ github.workspace }}'/Vulkan-Loader/build/loader/ \
"${CMAKE_CONFIG_ARGS_ANDROID}"
cmake --build . --parallel
formatcheck:
name: Check code format
runs-on: ubuntu-22.04

View File

@@ -7,7 +7,7 @@ project(CLConform${CONFORMANCE_SUFFIX})
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_definitions(-DCL_TARGET_OPENCL_VERSION=300)
@@ -100,7 +100,11 @@ if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang"
add_cxx_flag_if_supported(-Wmisleading-indentation)
add_cxx_flag_if_supported(-Wunused-function)
add_cxx_flag_if_supported(-Wunused-variable)
add_cxx_flag_if_supported(-Werror)
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
else()
add_cxx_flag_if_supported(-Werror)
endif()
if(NOT CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo|MinSizeRel")
# Enable more warnings if not doing a release build.
add_cxx_flag_if_supported(-Wall)

View File

@@ -14,6 +14,9 @@ Compiling the CTS requires the following CMake configuration options to be set:
* `CL_INCLUDE_DIR` Points to the unified
[OpenCL-Headers](https://github.com/KhronosGroup/OpenCL-Headers).
* `CL_LIB_DIR` Directory containing the OpenCL library to build against.
* `SPIRV_TOOLS_DIR` Directory containing the `spirv-as` and `spirv-val` binaries
to be used in the CTS build process. Alternatively, the location to these binaries
can be provided via the `PATH` variable.
* `OPENCL_LIBRARIES` Name of the OpenCL library to link.
It is advised that the [OpenCL ICD-Loader](https://github.com/KhronosGroup/OpenCL-ICD-Loader)
@@ -29,16 +32,26 @@ a build, and compile.
git clone https://github.com/KhronosGroup/OpenCL-CTS.git
git clone https://github.com/KhronosGroup/OpenCL-Headers.git
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
git clone https://github.com/KhronosGroup/SPIRV-Tools.git
git clone https://github.com/KhronosGroup/SPIRV-Headers.git SPIRV-Tools/external/spirv-headers
git clone https://github.com/google/effcee.git SPIRV-Tools/external/effcee
git clone https://github.com/google/re2.git SPIRV-Tools/external/re2
mkdir OpenCL-ICD-Loader/build
cmake -S OpenCL-ICD-Loader -B OpenCL-ICD-Loader/build \
-DOPENCL_ICD_LOADER_HEADERS_DIR=$PWD/OpenCL-Headers
cmake --build ./OpenCL-ICD-Loader/build --config Release
mkdir SPIRV-Tools/build
cmake -S SPIRV-Tools -B SPIRV-Tools/build -DSPIRV_SKIP_TESTS=ON
cmake --build SPIRV-Tools/build --config Release
mkdir OpenCL-CTS/build
cmake -S OpenCL-CTS -B OpenCL-CTS/build \
-DCL_INCLUDE_DIR=$PWD/OpenCL-Headers \
-DCL_LIB_DIR=$PWD/OpenCL-ICD-Loader/build \
-DSPIRV_TOOLS_DIR=$PWD/SPIRV-Tools/build/tools/ \
-DOPENCL_LIBRARIES=OpenCL
cmake --build OpenCL-CTS/build --config Release
```

View File

@@ -1,112 +0,0 @@
#!/usr/bin/env bash
set -e
export TOP=$(pwd)
TOOLCHAIN_PREFIX_arm=arm-linux-gnueabihf
TOOLCHAIN_PREFIX_aarch64=aarch64-linux-gnu
if [[ ${JOB_ARCHITECTURE} == android-* ]]; then
TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake
CMAKE_CONFIG_ARGS_ANDROID="-DCMAKE_ANDROID_ARCH_ABI=${ANDROID_ARCH_ABI}"
else
TOOLCHAIN_FILE=${TOP}/toolchain.cmake
touch ${TOOLCHAIN_FILE}
fi
BUILD_OPENGL_TEST="OFF"
BUILD_VULKAN_TEST="ON"
cmake --version
echo
# Prepare toolchain if needed
if [[ ${JOB_ARCHITECTURE} != android-* ]]; then
if [[ ${JOB_ARCHITECTURE} != "" && ${RUNNER_OS} != "Windows" ]]; then
TOOLCHAIN_PREFIX_VAR=TOOLCHAIN_PREFIX_${JOB_ARCHITECTURE}
TOOLCHAIN_PREFIX=${!TOOLCHAIN_PREFIX_VAR}
echo "SET(CMAKE_SYSTEM_NAME Linux)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_SYSTEM_PROCESSOR ${JOB_ARCHITECTURE})" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)" >> ${TOOLCHAIN_FILE}
echo "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)" >> ${TOOLCHAIN_FILE}
fi
fi
if [[ ( ${JOB_ARCHITECTURE} == "" && ${JOB_ENABLE_GL} == "1" ) ]]; then
BUILD_OPENGL_TEST="ON"
fi
if [[ ${JOB_ENABLE_DEBUG} == 1 ]]; then
BUILD_CONFIG="Debug"
else
BUILD_CONFIG="Release"
fi
#Vulkan Headers
git clone https://github.com/KhronosGroup/Vulkan-Headers.git
# Get and build loader
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
cd ${TOP}/OpenCL-ICD-Loader
mkdir build
cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DOPENCL_ICD_LOADER_HEADERS_DIR=${TOP}/OpenCL-Headers/ \
"${CMAKE_CONFIG_ARGS_ANDROID}"
cmake --build . --parallel
#Vulkan Loader
if [[ ${JOB_ARCHITECTURE} != android-* ]]; then
# Building the Vulkan loader is not supported on Android,
# instead, the loader is shipped as part of the operating system
cd ${TOP}
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
cd Vulkan-Loader
mkdir build
cd build
python3 ../scripts/update_deps.py
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DBUILD_WSI_XLIB_SUPPORT=OFF \
-DBUILD_WSI_XCB_SUPPORT=OFF \
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
-C helper.cmake ..
cmake --build . --parallel
fi
# Build CTS
cd ${TOP}
ls -l
mkdir build
cd build
if [[ ${RUNNER_OS} == "Windows" ]]; then
CMAKE_OPENCL_LIBRARIES_OPTION="OpenCL"
else
CMAKE_OPENCL_LIBRARIES_OPTION="-lOpenCL"
if [[ ${JOB_ARCHITECTURE} != android-* ]]; then
CMAKE_OPENCL_LIBRARIES_OPTION="${CMAKE_OPENCL_LIBRARIES_OPTION} -lpthread"
fi
fi
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \
-DCMAKE_CACHE_OPTIONS="-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache" \
-DCL_INCLUDE_DIR=${TOP}/OpenCL-Headers \
-DCL_LIB_DIR=${TOP}/OpenCL-ICD-Loader/build \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin \
-DOPENCL_LIBRARIES="${CMAKE_OPENCL_LIBRARIES_OPTION}" \
-DUSE_CL_EXPERIMENTAL=ON \
-DGL_IS_SUPPORTED=${BUILD_OPENGL_TEST} \
-DVULKAN_IS_SUPPORTED=${BUILD_VULKAN_TEST} \
-DVULKAN_INCLUDE_DIR=${TOP}/Vulkan-Headers/include/ \
-DVULKAN_LIB_DIR=${TOP}/Vulkan-Loader/build/loader/ \
"${CMAKE_CONFIG_ARGS_ANDROID}"
cmake --build . --parallel

View File

@@ -13,12 +13,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _setup_h
#define _setup_h
#ifndef _gl_setup_h
#define _gl_setup_h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include "gl_headers.h"
#ifdef __APPLE__
#include <OpenCL/opencl.h>
@@ -36,13 +37,11 @@ class GLEnvironment
GLEnvironment() {}
virtual ~GLEnvironment() {}
virtual int Init( int *argc, char **argv, int use_opengl_32 ) = 0;
virtual int Init(int *argc, char **argv, int use_opengl_32) = 0;
virtual cl_context CreateCLContext( void ) = 0;
virtual int SupportsCLGLInterop( cl_device_type device_type) = 0;
static GLEnvironment * Instance( void );
static GLEnvironment *Instance(void);
};
#endif // _setup_h
#endif // _gl_setup_h

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2024 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
@@ -25,65 +25,74 @@ private:
public:
OSXGLEnvironment()
{
mCGLContext = NULL;
mIsGlutInit = false;
mCGLContext = NULL;
mShareGroup = NULL;
mPlatform = NULL;
}
virtual int Init( int *argc, char **argv, int use_opengl_32 )
int Init(int *argc, char **argv, int use_opengl_32) override
{
if (!use_opengl_32)
{
if (!use_opengl_32) {
if (!mIsGlutInit)
{
// Create a GLUT window to render into
glutInit(argc, argv);
glutInitWindowSize(512, 512);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("OpenCL <-> OpenGL Test");
mIsGlutInit = true;
}
}
else {
CGLPixelFormatAttribute attribs[] = {
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
kCGLPFAAllowOfflineRenderers,
kCGLPFANoRecovery,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
(CGLPixelFormatAttribute)0
};
CGLError err;
CGLPixelFormatObj pix;
GLint npix;
err = CGLChoosePixelFormat (attribs, &pix, &npix);
if(err != kCGLNoError)
{
log_error("Failed to choose pixel format\n");
return -1;
}
err = CGLCreateContext(pix, NULL, &mCGLContext);
if(err != kCGLNoError)
{
log_error("Failed to create GL context\n");
return -1;
}
CGLSetCurrentContext(mCGLContext);
}
return 0;
if (!mIsGlutInit)
{
// Create a GLUT window to render into
glutInit(argc, argv);
glutInitWindowSize(512, 512);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("OpenCL <-> OpenGL Test");
mIsGlutInit = true;
}
}
virtual cl_context CreateCLContext( void )
else
{
CGLPixelFormatAttribute attribs[] = {
kCGLPFAOpenGLProfile,
(CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
kCGLPFAAllowOfflineRenderers,
kCGLPFANoRecovery,
kCGLPFAAccelerated,
kCGLPFADoubleBuffer,
(CGLPixelFormatAttribute)0
};
CGLError err;
CGLPixelFormatObj pix;
GLint npix;
err = CGLChoosePixelFormat(attribs, &pix, &npix);
if (err != kCGLNoError)
{
log_error("Failed to choose pixel format\n");
return -1;
}
err = CGLCreateContext(pix, NULL, &mCGLContext);
if (err != kCGLNoError)
{
log_error("Failed to create GL context\n");
return -1;
}
CGLSetCurrentContext(mCGLContext);
}
return 0;
}
cl_context CreateCLContext(void) override
{
int error;
if( mCGLContext == NULL )
mCGLContext = CGLGetCurrentContext();
CGLShareGroupObj share_group = CGLGetShareGroup(mCGLContext);
cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)share_group, 0 };
mShareGroup = CGLGetShareGroup(mCGLContext);
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties)mPlatform,
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
(cl_context_properties)mShareGroup, 0
};
cl_context context = clCreateContext(properties, 0, 0, 0, 0, &error);
if (error) {
print_error(error, "clCreateContext failed");
@@ -108,16 +117,24 @@ public:
return context;
}
virtual int SupportsCLGLInterop( cl_device_type device_type )
int SupportsCLGLInterop(cl_device_type device_type) override
{
int found_valid_device = 0;
cl_device_id devices[64];
cl_uint num_of_devices;
int error;
error = clGetDeviceIDs(NULL, device_type, 64, devices, &num_of_devices);
error = clGetPlatformIDs(1, &mPlatform, NULL);
if (error)
{
print_error(error, "clGetPlatformIDs failed");
return 0;
}
error =
clGetDeviceIDs(mPlatform, device_type, 64, devices, &num_of_devices);
if (error) {
print_error(error, "clGetDeviceIDs failed");
return -1;
return 0;
}
for (int i=0; i<(int)num_of_devices; i++) {
@@ -131,13 +148,11 @@ public:
return found_valid_device;
}
virtual ~OSXGLEnvironment()
{
CGLDestroyContext( mCGLContext );
}
CGLContextObj mCGLContext;
virtual ~OSXGLEnvironment() { CGLDestroyContext(mCGLContext); }
CGLContextObj mCGLContext;
CGLShareGroupObj mShareGroup;
cl_platform_id mPlatform;
};
GLEnvironment * GLEnvironment::Instance( void )

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2024 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
@@ -42,14 +42,19 @@ private:
cl_platform_id m_platform;
bool m_is_glut_init;
HGLRC m_hGLRC;
HDC m_hDC;
public:
WGLEnvironment()
{
m_device_count = 0;
m_platform = 0;
m_is_glut_init = false;
m_hGLRC = 0;
m_hDC = 0;
}
virtual int Init( int *argc, char **argv, int use_opengl_32 )
int Init(int *argc, char **argv, int use_opengl_32) override
{
if (!m_is_glut_init)
{
@@ -64,21 +69,25 @@ public:
return 0;
}
virtual cl_context CreateCLContext( void )
cl_context CreateCLContext(void) override
{
HGLRC hGLRC = wglGetCurrentContext();
HDC hDC = wglGetCurrentDC();
m_hGLRC = wglGetCurrentContext();
m_hDC = wglGetCurrentDC();
cl_context_properties properties[] = {
CL_CONTEXT_PLATFORM, (cl_context_properties) m_platform,
CL_GL_CONTEXT_KHR, (cl_context_properties) hGLRC,
CL_WGL_HDC_KHR, (cl_context_properties) hDC,
CL_CONTEXT_PLATFORM,
(cl_context_properties)m_platform,
CL_GL_CONTEXT_KHR,
(cl_context_properties)m_hGLRC,
CL_WGL_HDC_KHR,
(cl_context_properties)m_hDC,
0
};
cl_device_id devices[MAX_DEVICES];
size_t dev_size;
cl_int status;
if (!hGLRC || !hDC) {
if (!m_hGLRC || !m_hDC)
{
print_error(CL_INVALID_CONTEXT, "No GL context bound");
return 0;
}
@@ -155,7 +164,7 @@ public:
return clCreateContext(properties, 1, &ctxDevice, NULL, NULL, &status);
}
virtual int SupportsCLGLInterop( cl_device_type device_type )
int SupportsCLGLInterop(cl_device_type device_type) override
{
cl_device_id devices[MAX_DEVICES];
cl_uint num_of_devices;

View File

@@ -28,13 +28,21 @@ private:
cl_uint m_device_count;
bool m_glut_init;
cl_platform_id m_platform;
GLXContext m_context;
Display *m_dpy;
public:
X11GLEnvironment()
{
m_device_count = 0;
m_glut_init = false;
m_platform = 0;
m_context = 0;
m_dpy = nullptr;
}
virtual int Init( int *argc, char **argv, int use_opencl_32 )
int Init(int *argc, char **argv, int use_opencl_32) override
{
// Create a GLUT window to render into
if (!m_glut_init)
@@ -49,19 +57,24 @@ public:
return 0;
}
virtual cl_context CreateCLContext( void )
cl_context CreateCLContext(void) override
{
GLXContext context = glXGetCurrentContext();
Display *dpy = glXGetCurrentDisplay();
m_context = glXGetCurrentContext();
m_dpy = glXGetCurrentDisplay();
cl_context_properties properties[] = {
CL_GL_CONTEXT_KHR, (cl_context_properties) context,
CL_GLX_DISPLAY_KHR, (cl_context_properties) dpy,
CL_CONTEXT_PLATFORM,
(cl_context_properties)m_platform,
CL_GL_CONTEXT_KHR,
(cl_context_properties)m_context,
CL_GLX_DISPLAY_KHR,
(cl_context_properties)m_dpy,
0
};
cl_int status;
if (!context || !dpy) {
if (!m_context || !m_dpy)
{
print_error(CL_INVALID_CONTEXT, "No GL context bound");
return 0;
}
@@ -69,19 +82,19 @@ public:
return clCreateContext(properties, 1, m_devices, NULL, NULL, &status);
}
virtual int SupportsCLGLInterop( cl_device_type device_type )
int SupportsCLGLInterop(cl_device_type device_type) override
{
int found_valid_device = 0;
cl_platform_id platform;
cl_device_id devices[64];
cl_uint num_of_devices;
int error;
error = clGetPlatformIDs(1, &platform, NULL);
error = clGetPlatformIDs(1, &m_platform, NULL);
if (error) {
print_error(error, "clGetPlatformIDs failed");
return -1;
}
error = clGetDeviceIDs(platform, device_type, 64, devices, &num_of_devices);
error = clGetDeviceIDs(m_platform, device_type, 64, devices,
&num_of_devices);
// If this platform doesn't have any of the requested device_type (namely GPUs) then return 0
if (error == CL_DEVICE_NOT_FOUND)
return 0;

View File

@@ -213,6 +213,12 @@ const char *GetChannelTypeName(cl_channel_type type)
case CL_UNORM_INT24: return "CL_UNORM_INT24";
case CL_UNSIGNED_INT_RAW10_EXT: return "CL_UNSIGNED_INT_RAW10_EXT";
case CL_UNSIGNED_INT_RAW12_EXT: return "CL_UNSIGNED_INT_RAW12_EXT";
case CL_UNSIGNED_INT10X6_EXT: return "CL_UNSIGNED_INT10X6_EXT";
case CL_UNSIGNED_INT12X4_EXT: return "CL_UNSIGNED_INT12X4_EXT";
case CL_UNSIGNED_INT14X2_EXT: return "CL_UNSIGNED_INT14X2_EXT";
case CL_UNORM_INT10X6_EXT: return "CL_UNORM_INT10X6_EXT";
case CL_UNORM_INT12X4_EXT: return "CL_UNORM_INT12X4_EXT";
case CL_UNORM_INT14X2_EXT: return "CL_UNORM_INT14X2_EXT";
default: return NULL;
}
}
@@ -238,10 +244,16 @@ int IsChannelTypeSupported(cl_channel_type type)
case CL_UNSIGNED_INT16:
case CL_UNSIGNED_INT32:
case CL_HALF_FLOAT:
case CL_FLOAT: return 1;
case CL_FLOAT:
#ifdef CL_SFIXED14_APPLE
case CL_SFIXED14_APPLE: return 1;
case CL_SFIXED14_APPLE:
#endif
case CL_UNSIGNED_INT10X6_EXT:
case CL_UNSIGNED_INT12X4_EXT:
case CL_UNSIGNED_INT14X2_EXT:
case CL_UNORM_INT10X6_EXT:
case CL_UNORM_INT12X4_EXT:
case CL_UNORM_INT14X2_EXT: return 1;
default: return 0;
}
}

View File

@@ -97,7 +97,13 @@ uint32_t get_channel_data_type_size(cl_channel_type channelType)
case CL_UNSIGNED_INT32: return sizeof(cl_int);
case CL_UNORM_SHORT_565:
case CL_UNORM_SHORT_555: return 2;
case CL_UNORM_SHORT_555:
case CL_UNSIGNED_INT10X6_EXT:
case CL_UNSIGNED_INT12X4_EXT:
case CL_UNSIGNED_INT14X2_EXT:
case CL_UNORM_INT10X6_EXT:
case CL_UNORM_INT12X4_EXT:
case CL_UNORM_INT14X2_EXT: return 2;
case CL_UNORM_INT_101010:
case CL_UNORM_INT_101010_2:
@@ -186,6 +192,12 @@ cl_channel_type get_channel_type_from_name(const char *name)
#ifdef CL_SFIXED14_APPLE
{ CL_SFIXED14_APPLE, "CL_SFIXED14_APPLE" }
#endif
{ CL_UNSIGNED_INT10X6_EXT, "CL_UNSIGNED_INT10X6_EXT" },
{ CL_UNSIGNED_INT12X4_EXT, "CL_UNSIGNED_INT12X4_EXT" },
{ CL_UNSIGNED_INT14X2_EXT, "CL_UNSIGNED_INT14X2_EXT" },
{ CL_UNORM_INT10X6_EXT, "CL_UNORM_INT10X6_EXT" },
{ CL_UNORM_INT12X4_EXT, "CL_UNORM_INT12X4_EXT" },
{ CL_UNORM_INT14X2_EXT, "CL_UNORM_INT14X2_EXT" },
};
for (size_t i = 0; i < sizeof(typeNames) / sizeof(typeNames[0]); i++)
{
@@ -278,6 +290,12 @@ uint32_t get_pixel_size(const cl_image_format *format)
#ifdef CL_SFIXED14_APPLE
case CL_SFIXED14_APPLE:
#endif
case CL_UNSIGNED_INT10X6_EXT:
case CL_UNSIGNED_INT12X4_EXT:
case CL_UNSIGNED_INT14X2_EXT:
case CL_UNORM_INT10X6_EXT:
case CL_UNORM_INT12X4_EXT:
case CL_UNORM_INT14X2_EXT:
return get_format_channel_count(format) * sizeof(cl_ushort);
case CL_SIGNED_INT32:
@@ -940,6 +958,9 @@ float get_max_absolute_error(const cl_image_format *format,
#endif
case CL_UNORM_SHORT_555:
case CL_UNORM_SHORT_565: return 1.0f / 31.0f;
case CL_UNORM_INT10X6_EXT: return 1.0f / 1023.0f;
case CL_UNORM_INT12X4_EXT: return 1.0f / 4095.0f;
case CL_UNORM_INT14X2_EXT: return 1.0f / 16383.0f;
default: return 0.0f;
}
}
@@ -968,6 +989,9 @@ float get_max_relative_error(const cl_image_format *format,
case CL_UNORM_INT_101010:
case CL_UNORM_INT_101010_2:
case CL_UNORM_INT_2_101010_EXT:
case CL_UNORM_INT10X6_EXT:
case CL_UNORM_INT12X4_EXT:
case CL_UNORM_INT14X2_EXT:
// Maximum sampling error for round to zero normalization based on
// multiplication by reciprocal (using reciprocal generated in
// round to +inf mode, so that 1.0 matches spec)
@@ -1053,7 +1077,15 @@ size_t get_format_max_int(const cl_image_format *format)
case CL_UNORM_INT_101010:
case CL_UNORM_INT_101010_2:
case CL_UNORM_INT_2_101010_EXT: return 1023;
case CL_UNORM_INT_2_101010_EXT:
case CL_UNSIGNED_INT10X6_EXT:
case CL_UNORM_INT10X6_EXT: return 1023;
case CL_UNSIGNED_INT12X4_EXT:
case CL_UNORM_INT12X4_EXT: return 4095;
case CL_UNSIGNED_INT14X2_EXT:
case CL_UNORM_INT14X2_EXT: return 16383;
case CL_HALF_FLOAT: return 1 << 10;
@@ -1087,7 +1119,13 @@ int get_format_min_int(const cl_image_format *format)
case CL_UNORM_SHORT_555:
case CL_UNORM_INT_101010:
case CL_UNORM_INT_101010_2:
case CL_UNORM_INT_2_101010_EXT: return 0;
case CL_UNORM_INT_2_101010_EXT:
case CL_UNSIGNED_INT10X6_EXT:
case CL_UNSIGNED_INT12X4_EXT:
case CL_UNSIGNED_INT14X2_EXT:
case CL_UNORM_INT10X6_EXT:
case CL_UNORM_INT12X4_EXT:
case CL_UNORM_INT14X2_EXT: return 0;
case CL_HALF_FLOAT: return -(1 << 10);
@@ -1521,6 +1559,30 @@ void read_image_pixel_float(void *imageData, image_descriptor *imageInfo, int x,
break;
}
case CL_UNORM_INT10X6_EXT: {
cl_ushort *dPtr = (cl_ushort *)ptr;
for (i = 0; i < channelCount; i++)
tempData[i] =
CLAMP_FLOAT((float)((dPtr[i] >> 6) & 0x3ff) / 1023.0f);
break;
}
case CL_UNORM_INT12X4_EXT: {
cl_ushort *dPtr = (cl_ushort *)ptr;
for (i = 0; i < channelCount; i++)
tempData[i] =
CLAMP_FLOAT((float)((dPtr[i] >> 4) & 0xfff) / 4095.0f);
break;
}
case CL_UNORM_INT14X2_EXT: {
cl_ushort *dPtr = (cl_ushort *)ptr;
for (i = 0; i < channelCount; i++)
tempData[i] =
CLAMP_FLOAT((float)((dPtr[i] >> 2) & 0x3fff) / 16383.0f);
break;
}
case CL_FLOAT: {
float *dPtr = (float *)ptr;
for (i = 0; i < channelCount; i++) tempData[i] = (float)dPtr[i];
@@ -2634,6 +2696,24 @@ void pack_image_pixel(unsigned int *srcVector,
ptr[i] = (unsigned int)srcVector[i];
break;
}
case CL_UNSIGNED_INT10X6_EXT: {
unsigned short *ptr = (unsigned short *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = (unsigned short)SATURATE(srcVector[i], 0, 1023) << 6;
break;
}
case CL_UNSIGNED_INT12X4_EXT: {
unsigned short *ptr = (unsigned short *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = (unsigned short)SATURATE(srcVector[i], 0, 4095) << 4;
break;
}
case CL_UNSIGNED_INT14X2_EXT: {
unsigned short *ptr = (unsigned short *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = (unsigned short)SATURATE(srcVector[i], 0, 16383) << 2;
break;
}
default: break;
}
}
@@ -2809,6 +2889,27 @@ void pack_image_pixel(float *srcVector, const cl_image_format *imageFormat,
| (((unsigned int)NORMALIZE(srcVector[3], 1023.f) & 1023) << 0);
break;
}
case CL_UNORM_INT10X6_EXT: {
cl_ushort *ptr = (cl_ushort *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 1023.f) & 1023)
<< 6;
break;
}
case CL_UNORM_INT12X4_EXT: {
cl_ushort *ptr = (cl_ushort *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 4095.f) & 4095)
<< 4;
break;
}
case CL_UNORM_INT14X2_EXT: {
cl_ushort *ptr = (cl_ushort *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 16383.f) & 16383)
<< 2;
break;
}
case CL_SIGNED_INT8: {
cl_char *ptr = (cl_char *)outData;
for (unsigned int i = 0; i < channelCount; i++)
@@ -2852,6 +2953,27 @@ void pack_image_pixel(float *srcVector, const cl_image_format *imageFormat,
CL_UINT_MAX);
break;
}
case CL_UNSIGNED_INT10X6_EXT: {
cl_ushort *ptr = (cl_ushort *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 1023.f) & 1023)
<< 6;
break;
}
case CL_UNSIGNED_INT12X4_EXT: {
cl_ushort *ptr = (cl_ushort *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 4095.f) & 4095)
<< 4;
break;
}
case CL_UNSIGNED_INT14X2_EXT: {
cl_ushort *ptr = (cl_ushort *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = ((cl_ushort)NORMALIZE(srcVector[i], 16383.f) & 16383)
<< 2;
break;
}
#ifdef CL_SFIXED14_APPLE
case CL_SFIXED14_APPLE: {
cl_ushort *ptr = (cl_ushort *)outData;
@@ -2999,6 +3121,33 @@ void pack_image_pixel_error(const float *srcVector,
break;
}
case CL_UNORM_INT10X6_EXT: {
const cl_ushort *ptr = (const cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] =
(ptr[i] >> 6) - NORMALIZE_UNROUNDED(srcVector[i], 1023.f);
break;
}
case CL_UNORM_INT12X4_EXT: {
const cl_ushort *ptr = (const cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] =
(ptr[i] >> 4) - NORMALIZE_UNROUNDED(srcVector[i], 4095.f);
break;
}
case CL_UNORM_INT14X2_EXT: {
const cl_ushort *ptr = (const cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] =
(ptr[i] >> 2) - NORMALIZE_UNROUNDED(srcVector[i], 16383.f);
break;
}
case CL_SIGNED_INT8: {
const cl_char *ptr = (const cl_char *)results;
@@ -3050,6 +3199,29 @@ void pack_image_pixel_error(const float *srcVector,
CL_UINT_MAX));
break;
}
case CL_UNSIGNED_INT10X6_EXT: {
cl_ushort *ptr = (cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] = static_cast<float>(
(cl_int)ptr[i] - (*((cl_int *)(&srcVector[i])) & 0xffc0));
break;
}
case CL_UNSIGNED_INT12X4_EXT: {
cl_ushort *ptr = (cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] = static_cast<float>(
(cl_int)ptr[i] - (*((cl_int *)(&srcVector[i])) & 0xfff0));
break;
}
case CL_UNSIGNED_INT14X2_EXT: {
cl_ushort *ptr = (cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] = static_cast<float>(
(cl_int)ptr[i]
- (cl_int)CONVERT_UINT(srcVector[i], 16383.f,
CL_USHRT_MAX));
break;
}
#ifdef CL_SFIXED14_APPLE
case CL_SFIXED14_APPLE: {
const cl_ushort *ptr = (const cl_ushort *)results;

View File

@@ -126,6 +126,7 @@ typedef struct
const cl_image_format *format;
cl_mem buffer;
cl_mem_object_type type;
cl_mem_flags mem_flags;
cl_uint num_mip_levels;
} image_descriptor;
@@ -447,6 +448,27 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
tempData[0] = (T)(hi_val | lo_val);
break;
}
case CL_UNSIGNED_INT10X6_EXT: {
cl_short *dPtr = (cl_short *)ptr;
const size_t channelCount = get_format_channel_count(format);
for (i = 0; i < channelCount; i++)
tempData[i] = (dPtr[i] >> 6) & 0x3ff;
break;
}
case CL_UNSIGNED_INT12X4_EXT: {
cl_short *dPtr = (cl_short *)ptr;
const size_t channelCount = get_format_channel_count(format);
for (i = 0; i < channelCount; i++)
tempData[i] = (dPtr[i] >> 4) & 0xfff;
break;
}
case CL_UNSIGNED_INT14X2_EXT: {
cl_short *dPtr = (cl_short *)ptr;
const size_t channelCount = get_format_channel_count(format);
for (i = 0; i < channelCount; i++)
tempData[i] = (dPtr[i] >> 2) & 0x3fff;
break;
}
}

View File

@@ -1328,6 +1328,12 @@ size_t get_pixel_bytes(const cl_image_format *fmt)
case CL_SIGNED_INT8:
case CL_UNSIGNED_INT8: return chanCount;
case CL_UNSIGNED_INT10X6_EXT:
case CL_UNSIGNED_INT12X4_EXT:
case CL_UNSIGNED_INT14X2_EXT:
case CL_UNORM_INT10X6_EXT:
case CL_UNORM_INT12X4_EXT:
case CL_UNORM_INT14X2_EXT:
case CL_SNORM_INT16:
case CL_UNORM_INT16:
case CL_HALF_FLOAT:

View File

@@ -377,4 +377,24 @@ public:
size_t getSize() const { return allocsize; };
};
// scope guard helper to ensure proper releasing of sub devices
struct SubDevicesScopeGuarded
{
SubDevicesScopeGuarded(const cl_int dev_count)
{
sub_devices.resize(dev_count);
}
~SubDevicesScopeGuarded()
{
for (auto &device : sub_devices)
{
cl_int err = clReleaseDevice(device);
if (err != CL_SUCCESS)
log_error("\n Releasing sub-device failed \n");
}
}
std::vector<cl_device_id> sub_devices;
};
#endif // _typeWrappers_h

View File

@@ -26,6 +26,8 @@ typedef long long unsigned llu;
#define REDUCTION_PERCENTAGE_DEFAULT 50
#define BYTES_PER_WORK_ITEM 2048ULL
int g_repetition_count = 1;
int g_reduction_percentage = REDUCTION_PERCENTAGE_DEFAULT;
int g_write_allocations = 1;
@@ -125,7 +127,7 @@ int doTest(cl_device_id device, cl_context context, cl_command_queue queue,
int number_of_mems_used;
cl_ulong max_individual_allocation_size = g_max_individual_allocation_size;
cl_ulong global_mem_size = g_global_mem_size;
unsigned int number_of_work_items = 8192 * 32;
unsigned int number_of_work_items;
const bool allocate_image =
(alloc_type != BUFFER) && (alloc_type != BUFFER_NON_BLOCKING);
@@ -183,12 +185,16 @@ int doTest(cl_device_id device, cl_context context, cl_command_queue queue,
g_reduction_percentage);
g_max_size = (size_t)((double)g_max_size
* (double)g_reduction_percentage / 100.0);
number_of_work_items = 8192 * 2;
}
// Round to nearest MB.
g_max_size &= (size_t)(0xFFFFFFFFFF00000ULL);
// Scales the number of work-items to keep the amount of bytes processed
// per work-item the same.
number_of_work_items =
std::max(g_max_size / BYTES_PER_WORK_ITEM, 8192ULL * 2ULL);
log_info("** Target allocation size (rounded to nearest MB) is: %llu bytes "
"(%gMB).\n",
llu(g_max_size), toMB(g_max_size));

View File

@@ -4,6 +4,7 @@ set(${MODULE_NAME}_SOURCES
main.cpp
negative_platform.cpp
negative_queue.cpp
negative_enqueue_map_image.cpp
test_api_consistency.cpp
test_bool.cpp
test_retain.cpp

View File

@@ -0,0 +1,191 @@
//
// Copyright (c) 2024 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/clImageHelper.h"
#include <array>
#include <vector>
#include <memory>
static constexpr cl_mem_object_type image_types[] = {
CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE3D, CL_MEM_OBJECT_IMAGE2D_ARRAY,
CL_MEM_OBJECT_IMAGE1D, CL_MEM_OBJECT_IMAGE1D_ARRAY
};
REGISTER_TEST(negative_enqueue_map_image)
{
constexpr size_t image_dim = 32;
REQUIRE_EXTENSION("cl_ext_immutable_memory_objects");
static constexpr cl_mem_flags mem_flags[]{
CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR,
CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR,
CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR
};
static constexpr const char *mem_flags_string[]{
"CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR",
"CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR",
"CL_MEM_IMMUTABLE_EXT | CL_MEM_COPY_HOST_PTR | "
"CL_MEM_ALLOC_HOST_PTR"
};
static_assert(ARRAY_SIZE(mem_flags) == ARRAY_SIZE(mem_flags_string),
"mem_flags and mem_flags_string must be of the same size");
using CLUCharPtr = std::unique_ptr<cl_uchar, decltype(&free)>;
for (size_t index = 0; index < ARRAY_SIZE(mem_flags); ++index)
{
cl_mem_flags mem_flag = mem_flags[index];
log_info("Testing memory flag: %s\n", mem_flags_string[index]);
for (cl_mem_object_type image_type : image_types)
{
// find supported image formats
cl_uint num_formats = 0;
cl_int error = clGetSupportedImageFormats(
context, mem_flag, image_type, 0, nullptr, &num_formats);
test_error(error,
"clGetSupportedImageFormats failed to return supported "
"formats");
std::vector<cl_image_format> formats(num_formats);
error = clGetSupportedImageFormats(context, mem_flag, image_type,
num_formats, formats.data(),
nullptr);
test_error(error,
"clGetSupportedImageFormats failed to return supported "
"formats");
clMemWrapper image;
for (cl_image_format &fmt : formats)
{
log_info("Testing %s %s\n",
GetChannelOrderName(fmt.image_channel_order),
GetChannelTypeName(fmt.image_channel_data_type));
RandomSeed seed(gRandomSeed);
size_t origin[3] = { 0, 0, 0 };
size_t region[3] = { image_dim, image_dim, image_dim };
switch (image_type)
{
case CL_MEM_OBJECT_IMAGE1D: {
const size_t pixel_size = get_pixel_size(&fmt);
const size_t image_size =
image_dim * pixel_size * sizeof(cl_uchar);
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
create_random_data(kUChar, seed,
image_size)),
free };
image =
create_image_1d(context, mem_flag, &fmt, image_dim,
0, imgptr.get(), nullptr, &error);
region[1] = 1;
region[2] = 1;
break;
}
case CL_MEM_OBJECT_IMAGE2D: {
const size_t pixel_size = get_pixel_size(&fmt);
const size_t image_size = image_dim * image_dim
* pixel_size * sizeof(cl_uchar);
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
create_random_data(kUChar, seed,
image_size)),
free };
image =
create_image_2d(context, mem_flag, &fmt, image_dim,
image_dim, 0, imgptr.get(), &error);
region[2] = 1;
break;
}
case CL_MEM_OBJECT_IMAGE3D: {
const size_t pixel_size = get_pixel_size(&fmt);
const size_t image_size = image_dim * image_dim
* image_dim * pixel_size * sizeof(cl_uchar);
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
create_random_data(kUChar, seed,
image_size)),
free };
image = create_image_3d(context, mem_flag, &fmt,
image_dim, image_dim, image_dim,
0, 0, imgptr.get(), &error);
break;
}
case CL_MEM_OBJECT_IMAGE1D_ARRAY: {
const size_t pixel_size = get_pixel_size(&fmt);
const size_t image_size = image_dim * image_dim
* pixel_size * sizeof(cl_uchar);
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
create_random_data(kUChar, seed,
image_size)),
free };
image = create_image_1d_array(context, mem_flag, &fmt,
image_dim, image_dim, 0,
0, imgptr.get(), &error);
region[1] = 1;
region[2] = 1;
break;
}
case CL_MEM_OBJECT_IMAGE2D_ARRAY: {
const size_t pixel_size = get_pixel_size(&fmt);
const size_t image_size = image_dim * image_dim
* image_dim * pixel_size * sizeof(cl_uchar);
CLUCharPtr imgptr{ static_cast<cl_uchar *>(
create_random_data(kUChar, seed,
image_size)),
free };
image = create_image_2d_array(
context, mem_flag, &fmt, image_dim, image_dim,
image_dim, 0, 0, imgptr.get(), &error);
region[2] = 1;
break;
}
}
test_error(error, "Failed to create image");
void *map = clEnqueueMapImage(
queue, image, CL_TRUE, CL_MAP_WRITE, origin, region,
nullptr, nullptr, 0, nullptr, nullptr, &error);
constexpr const char *write_err_msg =
"clEnqueueMapImage should return CL_INVALID_OPERATION "
"when: \"image has been created with CL_MEM_IMMUTABLE_EXT "
"and CL_MAP_WRITE is set in map_flags\"";
test_assert_error(map == nullptr, write_err_msg);
test_failure_error_ret(error, CL_INVALID_OPERATION,
write_err_msg, TEST_FAIL);
map = clEnqueueMapImage(queue, image, CL_TRUE,
CL_MAP_WRITE_INVALIDATE_REGION, origin,
region, nullptr, nullptr, 0, nullptr,
nullptr, &error);
constexpr const char *write_invalidate_err_msg =
"clEnqueueMapImage should return CL_INVALID_OPERATION "
"when: \"image has been created with CL_MEM_IMMUTABLE_EXT "
"and CL_MAP_WRITE_INVALIDATE_REGION is set in map_flags\"";
test_assert_error(map == nullptr, write_invalidate_err_msg);
test_failure_error_ret(error, CL_INVALID_OPERATION,
write_invalidate_err_msg, TEST_FAIL);
}
}
}
return TEST_PASS;
}

View File

@@ -27,24 +27,4 @@
#include <sys/types.h>
#include <sys/stat.h>
// scope guard helper to ensure proper releasing of sub devices
struct SubDevicesScopeGuarded
{
SubDevicesScopeGuarded(const cl_int dev_count)
{
sub_devices.resize(dev_count);
}
~SubDevicesScopeGuarded()
{
for (auto &device : sub_devices)
{
cl_int err = clReleaseDevice(device);
if (err != CL_SUCCESS)
log_error("\n Releasing sub-device failed \n");
}
}
std::vector<cl_device_id> sub_devices;
};
#endif // _testBase_h

View File

@@ -1243,13 +1243,6 @@ REGISTER_TEST(consistency_requirements_fp16)
}
else
{
error = clGetDeviceInfo(device, CL_DEVICE_HALF_FP_CONFIG, sizeof(value),
&value, nullptr);
test_failure_error(
error, CL_INVALID_VALUE,
"cl_khr_fp16 is not available; CL_DEVICE_HALF_FP_CONFIG must fail "
"with CL_INVALID_VALUE");
error = clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF,
sizeof(value), &value, nullptr);
test_error(

View File

@@ -153,6 +153,8 @@ REGISTER_TEST(kernel_local_memory_size)
"kernel local mem size failed");
program.reset();
kernel.reset();
// Check memory needed to execute empty kernel with __local parameter with
// setKernelArg
if (create_single_kernel_helper(context, &program, &kernel, 1,
@@ -225,6 +227,8 @@ REGISTER_TEST(kernel_local_memory_size)
"kernel local mem size failed");
program.reset();
kernel.reset();
// Check memory needed to execute kernel with __local variable and __local
// parameter with setKernelArg
if (create_single_kernel_helper(context, &program, &kernel, 1,

View File

@@ -16,6 +16,7 @@
#include "testBase.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
#include <vector>
const char *sample_single_test_kernel[] = {
"__kernel void sample_test(__global float *src, __global int *dst)\n"
@@ -49,6 +50,17 @@ const char *sample_const_test_kernel[] = {
"\n"
"}\n" };
const char *sample_image_test_kernel[] = {
"__kernel void sample_image_test(__read_only image2d_t src, __write_only "
"image2d_t dst)\n"
"{\n"
" int2 coord = (int2)(get_global_id(0), get_global_id(1));\n"
" uint4 value = read_imageui(src, coord);\n"
" write_imageui(dst, coord, value);\n"
"\n"
"}\n"
};
const char *sample_const_global_test_kernel[] = {
"__constant int addFactor = 1024;\n"
"__kernel void sample_test(__global int *src1, __global int *dst)\n"
@@ -631,3 +643,64 @@ REGISTER_TEST(kernel_global_constant)
return 0;
}
REGISTER_TEST(negative_set_immutable_memory_to_writeable_kernel_arg)
{
REQUIRE_EXTENSION("cl_ext_immutable_memory_objects");
cl_int error = CL_SUCCESS;
clProgramWrapper program;
clKernelWrapper kernels[2];
clMemWrapper image, buffer;
const char *test_kernels[2] = { sample_const_test_kernel[0],
sample_image_test_kernel[0] };
constexpr cl_image_format formats = { CL_RGBA, CL_UNSIGNED_INT8 };
constexpr size_t size_dim = 128;
// Setup the test
error = create_single_kernel_helper(context, &program, nullptr, 2,
test_kernels, nullptr);
test_error(error, "Unable to build test program");
kernels[0] = clCreateKernel(program, "sample_test", &error);
test_error(error, "Unable to get sample_test kernel for built program");
kernels[1] = clCreateKernel(program, "sample_image_test", &error);
test_error(error,
"Unable to get sample_image_test kernel for built program");
std::vector<cl_uchar> mem_data(size_dim * size_dim);
buffer = clCreateBuffer(context, CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR,
sizeof(cl_int) * size_dim, mem_data.data(), &error);
test_error(error, "clCreateBuffer failed");
image = create_image_2d(context, CL_MEM_IMMUTABLE_EXT | CL_MEM_USE_HOST_PTR,
&formats, size_dim, size_dim, 0, mem_data.data(),
&error);
test_error(error, "create_image_2d failed");
// Run the test
error = clSetKernelArg(kernels[0], 0, sizeof(buffer), &buffer);
test_error(error, "clSetKernelArg failed");
error = clSetKernelArg(kernels[0], 2, sizeof(buffer), &buffer);
test_failure_error_ret(error, CL_INVALID_ARG_VALUE,
"clSetKernelArg is supposed to fail "
"with CL_INVALID_ARG_VALUE when a buffer is "
"created with CL_MEM_IMMUTABLE_EXT is "
"passed to a non-constant kernel argument",
TEST_FAIL);
error = clSetKernelArg(kernels[1], 0, sizeof(image), &image);
test_error(error, "clSetKernelArg failed");
error = clSetKernelArg(kernels[1], 1, sizeof(image), &image);
test_failure_error_ret(error, CL_INVALID_ARG_VALUE,
"clSetKernelArg is supposed to fail "
"with CL_INVALID_ARG_VALUE when an image is "
"created with CL_MEM_IMMUTABLE_EXT is "
"passed to a write_only kernel argument",
TEST_FAIL);
return TEST_PASS;
}

View File

@@ -796,6 +796,60 @@ REGISTER_TEST(get_device_info)
return 0;
}
REGISTER_TEST(get_device_info_comparability)
{
int error = CL_SUCCESS;
// comparability test for CL_DEVICE_PLATFORM
// 1. find platform related to device without using query
cl_uint num_platforms = 0;
error = clGetPlatformIDs(16, nullptr, &num_platforms);
test_error(error, "clGetPlatformIDs failed");
std::vector<cl_platform_id> platforms(num_platforms);
error = clGetPlatformIDs(num_platforms, platforms.data(), &num_platforms);
test_error(error, "clGetPlatformIDs failed");
cl_uint num_devices = 0;
cl_platform_id comp_platform = nullptr;
for (int p = 0; p < (int)num_platforms && comp_platform == nullptr; p++)
{
error = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, 0, nullptr,
&num_devices);
if (error != CL_SUCCESS || num_devices == 0) continue;
std::vector<cl_device_id> devices(num_devices);
error = clGetDeviceIDs(platforms[p], CL_DEVICE_TYPE_ALL, num_devices,
devices.data(), nullptr);
if (error != CL_SUCCESS) continue;
// find correct device
for (auto did : devices)
{
if (did == device)
{
comp_platform = platforms[p];
break;
}
}
}
test_error_fail(comp_platform == nullptr,
"Test failed to locate platform for comparison!");
// 2. compare platforms found with and without using query
cl_platform_id plat = nullptr;
error =
clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(plat), &plat, NULL);
test_error(error, "clGetDeviceInfo failed");
test_assert_error(plat == comp_platform,
"Unexpected result returned by clGetDeviceInfo for "
"CL_DEVICE_PLATFORM query");
return TEST_PASS;
}
static const char *sample_compile_size[2] = {
"__kernel void sample_test(__global int *src, __global int *dst)\n"

View File

@@ -23,7 +23,8 @@ REGISTER_TEST(queue_flush_on_release)
cl_int err;
// Create a command queue
cl_command_queue cmd_queue = clCreateCommandQueue(context, device, 0, &err);
clCommandQueueWrapper cmd_queue =
clCreateCommandQueue(context, device, 0, &err);
test_error(err, "Could not create command queue");
// Create a kernel
@@ -42,7 +43,7 @@ REGISTER_TEST(queue_flush_on_release)
test_error(err, "Could not enqueue kernel");
// Release the queue
err = clReleaseCommandQueue(cmd_queue);
cmd_queue.reset();
// Wait for kernel to execute since the queue must flush on release
bool success = poll_until(2000, 50, [&event]() {
@@ -64,11 +65,13 @@ REGISTER_TEST(multi_queue_flush_on_release)
cl_int err;
// Create A command queue
cl_command_queue queue_A = clCreateCommandQueue(context, device, 0, &err);
clCommandQueueWrapper queue_A =
clCreateCommandQueue(context, device, 0, &err);
test_error(err, "Could not create command queue A");
// Create B command queue
cl_command_queue queue_B = clCreateCommandQueue(context, device, 0, &err);
clCommandQueueWrapper queue_B =
clCreateCommandQueue(context, device, 0, &err);
test_error(err, "Could not create command queue B");
// Create a kernel
@@ -96,8 +99,7 @@ REGISTER_TEST(multi_queue_flush_on_release)
// Release queue_A, which performs an implicit flush to issue any previously
// queued OpenCL commands
err = clReleaseCommandQueue(queue_A);
test_error(err, "clReleaseCommandQueue failed");
queue_A.reset();
err = clFlush(queue_B);
test_error(err, "clFlush failed");

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2017-2025 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,18 +14,14 @@
// limitations under the License.
//
#include "testBase.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
const char* zero_sized_enqueue_test_kernel[] = {
"__kernel void foo_kernel(__global int *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = 1;\n"
"\n"
"}\n"
};
const char* zero_sized_enqueue_test_kernel = R"(
__kernel void foo_kernel(__global int *dst)
{
int tid = get_global_id(0);
dst[tid] = 1;
}
)";
const int bufSize = 128;
@@ -81,15 +77,20 @@ int test_zero_sized_enqueue_helper(cl_device_id device, cl_context context,
output_stream =
clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
bufSize * sizeof(int), NULL, &error);
test_error(error, "clCreateBuffer failed.");
// Initialise output buffer.
int output_buffer_data = 0;
error = clEnqueueFillBuffer(queue, output_stream, &output_buffer_data,
sizeof(int), 0, sizeof(int) * bufSize, 0, NULL,
NULL);
test_error(error, "clEnqueueFillBuffer failed.");
/* Create a kernel to test with */
if( create_single_kernel_helper( context, &program, &kernel, 1, zero_sized_enqueue_test_kernel, "foo_kernel" ) != 0 )
if (create_single_kernel_helper(context, &program, &kernel, 1,
&zero_sized_enqueue_test_kernel,
"foo_kernel")
!= 0)
{
return -1;
}
@@ -98,6 +99,16 @@ int test_zero_sized_enqueue_helper(cl_device_id device, cl_context context,
test_error( error, "clSetKernelArg failed." );
// Simple API return code tests for 1D, 2D and 3D zero sized ND range.
error = test_zero_sized_enqueue_and_test_output_buffer(
queue, kernel, output_stream, 1, nullptr);
test_error(error, "1D null sized kernel enqueue failed.");
error = test_zero_sized_enqueue_and_test_output_buffer(
queue, kernel, output_stream, 2, nullptr);
test_error(error, "2D null sized kernel enqueue failed.");
error = test_zero_sized_enqueue_and_test_output_buffer(
queue, kernel, output_stream, 3, nullptr);
test_error(error, "3D null sized kernel enqueue failed.");
error = test_zero_sized_enqueue_and_test_output_buffer(
queue, kernel, output_stream, 1, &ndrange1);
test_error( error, "1D zero sized kernel enqueue failed." );
@@ -156,6 +167,17 @@ int test_zero_sized_enqueue_helper(cl_device_id device, cl_context context,
return -1;
}
cl_command_type cmdtype;
error = clGetEventInfo(ev, CL_EVENT_COMMAND_TYPE, sizeof(cmdtype), &cmdtype,
NULL);
test_error(error, "Failed to get event command type.");
if (cmdtype != CL_COMMAND_NDRANGE_KERNEL)
{
log_error(
"ERROR: incorrect zero sized kernel enqueue event command type.\n");
return -1;
}
cl_int sta;
error = clGetEventInfo(ev, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(cl_int), &sta, NULL);
test_error( error, "Failed to get event status.");

View File

@@ -71,6 +71,6 @@ if(APPLE)
list(APPEND ${MODULE_NAME}_SOURCES test_queue_priority.cpp)
endif(APPLE)
set_gnulike_module_compile_flags("-Wno-sign-compare -Wno-format")
set_gnulike_module_compile_flags("-Wno-sign-compare")
include(../CMakeCommon.txt)

View File

@@ -20,31 +20,42 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include "testBase.h"
REGISTER_TEST(arrayreadwrite)
static int test_arrayreadwrite_impl(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements,
cl_mem_flags flags)
{
cl_uint *inptr, *outptr;
cl_mem streams[1];
clMemWrapper buffer;
int num_tries = 400;
num_elements = 1024 * 1024 * 4;
int i, j, err;
MTdata d;
MTdataHolder d(gRandomSeed);
inptr = (cl_uint*)malloc(num_elements*sizeof(cl_uint));
outptr = (cl_uint*)malloc(num_elements*sizeof(cl_uint));
std::vector<cl_uint> reference_vals(num_elements);
std::vector<cl_uint> inptr(num_elements);
std::vector<cl_uint> outptr(num_elements);
// randomize data
d = init_genrand( gRandomSeed );
for (i=0; i<num_elements; i++)
for (int i = 0; i < num_elements; i++)
{
inptr[i] = (cl_uint)(genrand_int32(d) & 0x7FFFFFFF);
reference_vals[i] = (cl_uint)(genrand_int32(d) & 0x7FFFFFFF);
}
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_uint) * num_elements, NULL, &err);
void* host_ptr = nullptr;
if ((flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR))
{
host_ptr = inptr.data();
}
cl_int err = CL_SUCCESS;
buffer = clCreateBuffer(context, flags, sizeof(cl_uint) * num_elements,
host_ptr, &err);
test_error(err, "clCreateBuffer failed");
for (i=0; i<num_tries; i++)
for (int i = 0; i < num_tries; i++)
{
int offset;
int cb;
@@ -58,15 +69,19 @@ REGISTER_TEST(arrayreadwrite)
if (cb > (num_elements - offset))
cb = num_elements - offset;
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, offset*sizeof(cl_uint), sizeof(cl_uint)*cb,&inptr[offset], 0, NULL, NULL);
err = clEnqueueWriteBuffer(
queue, buffer, CL_TRUE, offset * sizeof(cl_uint),
sizeof(cl_uint) * cb, &reference_vals[offset], 0, nullptr, nullptr);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, offset*sizeof(cl_uint), cb*sizeof(cl_uint), &outptr[offset], 0, NULL, NULL );
err = clEnqueueReadBuffer(
queue, buffer, CL_TRUE, offset * sizeof(cl_uint),
cb * sizeof(cl_uint), &outptr[offset], 0, nullptr, nullptr);
test_error(err, "clEnqueueReadBuffer failed");
for (j=offset; j<offset+cb; j++)
for (int j = offset; j < offset + cb; j++)
{
if (inptr[j] != outptr[j])
if (reference_vals[j] != outptr[j])
{
log_error("ARRAY read, write test failed\n");
err = -1;
@@ -78,13 +93,15 @@ REGISTER_TEST(arrayreadwrite)
break;
}
free_mtdata(d);
clReleaseMemObject(streams[0]);
free(inptr);
free(outptr);
if (!err)
log_info("ARRAY read, write test passed\n");
return err;
}
REGISTER_TEST(arrayreadwrite)
{
return test_arrayreadwrite_impl(device, context, queue, num_elements,
CL_MEM_READ_WRITE);
}

View File

@@ -21,6 +21,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <cinttypes>
#include "testBase.h"
#define CL_EXIT_ERROR(cmd,format,...) \
@@ -340,8 +342,21 @@ void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data )
free( data );
}
// This is the main test function for the conformance test.
REGISTER_TEST(bufferreadwriterect)
using test_fn = int (*)(size_t, size_t[3], size_t[3], size_t, size_t[3],
size_t[3]);
struct TestFunctions
{
test_fn copy;
test_fn read;
test_fn write;
};
static int test_bufferreadwriterect_impl(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements,
cl_map_flags buffer_flags,
const TestFunctions& test_functions)
{
gQueue = queue;
cl_int err;
@@ -352,7 +367,8 @@ REGISTER_TEST(bufferreadwriterect)
// Compute a maximum buffer size based on the number of test images and the device maximum.
cl_ulong max_mem_alloc_size = 0;
CL_EXIT_ERROR(clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_mem_alloc_size, NULL),"Could not get device info");
log_info("CL_DEVICE_MAX_MEM_ALLOC_SIZE = %llu bytes.\n", max_mem_alloc_size);
log_info("CL_DEVICE_MAX_MEM_ALLOC_SIZE = %" PRIu64 " bytes.\n",
max_mem_alloc_size);
// Confirm that the maximum allocation size is not zero.
if (max_mem_alloc_size == 0) {
@@ -390,7 +406,7 @@ REGISTER_TEST(bufferreadwriterect)
// Check to see if adequately sized buffers were found.
if (tries >= max_tries) {
log_error("Error: Could not find random buffer sized less than "
"%llu bytes in %zu tries.\n",
"%" PRIu64 " bytes in %zu tries.\n",
max_mem_alloc_size, max_tries);
return -1;
}
@@ -431,7 +447,8 @@ REGISTER_TEST(bufferreadwriterect)
memcpy(backing[i], verify[i], size_bytes);
// Create the CL buffer.
buffer[i] = clCreateBuffer (context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size_bytes, backing[i], &err);
buffer[i] =
clCreateBuffer(context, buffer_flags, size_bytes, backing[i], &err);
CL_EXIT_ERROR(err,"clCreateBuffer failed for buffer %u", i);
// Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls.
@@ -496,7 +513,8 @@ REGISTER_TEST(bufferreadwriterect)
doffset[0], doffset[1], doffset[2], sregion[0],
sregion[1], sregion[2],
sregion[0] * sregion[1] * sregion[2]);
if ((err = copy_region(src, soffset, sregion, dst, doffset, dregion)))
if ((err = test_functions.copy(src, soffset, sregion, dst,
doffset, dregion)))
return err;
break;
case 1:
@@ -506,7 +524,8 @@ REGISTER_TEST(bufferreadwriterect)
doffset[0], doffset[1], doffset[2], sregion[0],
sregion[1], sregion[2],
sregion[0] * sregion[1] * sregion[2]);
if ((err = read_verify_region(src, soffset, sregion, dst, doffset, dregion)))
if ((err = test_functions.read(src, soffset, sregion, dst,
doffset, dregion)))
return err;
break;
case 2:
@@ -516,7 +535,8 @@ REGISTER_TEST(bufferreadwriterect)
doffset[0], doffset[1], doffset[2], sregion[0],
sregion[1], sregion[2],
sregion[0] * sregion[1] * sregion[2]);
if ((err = write_region(src, soffset, sregion, dst, doffset, dregion)))
if ((err = test_functions.write(src, soffset, sregion, dst,
doffset, dregion)))
return err;
break;
}
@@ -559,3 +579,15 @@ REGISTER_TEST(bufferreadwriterect)
return err;
}
// This is the main test function for the conformance test.
REGISTER_TEST(bufferreadwriterect)
{
TestFunctions test_functions;
test_functions.copy = copy_region;
test_functions.read = read_verify_region;
test_functions.write = write_region;
return test_bufferreadwriterect_impl(
device, context, queue, num_elements,
CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, test_functions);
}

View File

@@ -22,6 +22,7 @@
#include <sys/stat.h>
#include <algorithm>
#include <cinttypes>
#include <vector>
#include "testBase.h"
@@ -116,7 +117,8 @@ REGISTER_TEST(constant)
err = clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
sizeof(maxSize), &maxSize, 0);
test_error(err, "Unable to get max constant buffer size");
log_info("Device reports CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE %llu bytes.\n",
log_info("Device reports CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE %" PRIu64
" bytes.\n",
maxSize);
// Limit test buffer size to 1/4 of CL_DEVICE_GLOBAL_MEM_SIZE

View File

@@ -29,6 +29,9 @@ const cl_mem_flags flag_set[] = {
CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_USE_HOST_PTR,
CL_MEM_COPY_HOST_PTR,
CL_MEM_USE_HOST_PTR | CL_MEM_IMMUTABLE_EXT,
CL_MEM_COPY_HOST_PTR | CL_MEM_IMMUTABLE_EXT,
CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_IMMUTABLE_EXT,
0
};
@@ -37,6 +40,9 @@ const char *flag_set_names[] = {
"CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR",
"CL_MEM_USE_HOST_PTR",
"CL_MEM_COPY_HOST_PTR",
"CL_MEM_USE_HOST_PTR | CL_MEM_IMMUTABLE_EXT",
"CL_MEM_COPY_HOST_PTR | CL_MEM_IMMUTABLE_EXT",
"CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_IMMUTABLE_EXT",
"0"
};
// clang-format on
@@ -44,7 +50,7 @@ const char *flag_set_names[] = {
REGISTER_TEST(enqueue_map_buffer)
{
int error;
const size_t bufferSize = 256 * 256;
constexpr size_t bufferSize = 256 * 256;
MTdataHolder d{ gRandomSeed };
BufferOwningPtr<cl_char> hostPtrData{ malloc(bufferSize) };
BufferOwningPtr<cl_char> referenceData{ malloc(bufferSize) };
@@ -57,18 +63,28 @@ REGISTER_TEST(enqueue_map_buffer)
log_info("Testing with cl_mem_flags src: %s\n",
flag_set_names[src_flag_id]);
if ((flag_set[src_flag_id] & CL_MEM_IMMUTABLE_EXT)
&& !is_extension_available(device,
"cl_ext_immutable_memory_objects"))
{
log_info("Device does not support CL_MEM_IMMUTABLE_EXT. "
"Skipping the memory flag.\n");
continue;
}
generate_random_data(kChar, (unsigned int)bufferSize, d, hostPtrData);
memcpy(referenceData, hostPtrData, bufferSize);
void *hostPtr = nullptr;
cl_mem_flags flags = flag_set[src_flag_id];
const bool is_immutable_buffer = flags & CL_MEM_IMMUTABLE_EXT;
bool hasHostPtr =
(flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
if (hasHostPtr) hostPtr = hostPtrData;
memObject = clCreateBuffer(context, flags, bufferSize, hostPtr, &error);
test_error(error, "Unable to create testing buffer");
if (!hasHostPtr)
if (!hasHostPtr && !is_immutable_buffer)
{
error =
clEnqueueWriteBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
@@ -86,7 +102,18 @@ REGISTER_TEST(enqueue_map_buffer)
cl_char *mappedRegion = (cl_char *)clEnqueueMapBuffer(
queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
length, 0, NULL, NULL, &error);
if (error != CL_SUCCESS)
// Mapping should fail if the buffer is immutable
if (is_immutable_buffer)
{
test_failure_error_ret(
error, CL_INVALID_OPERATION,
"clEnqueueMapBuffer call was expected to fail "
"with CL_INVALID_OPERATION",
TEST_FAIL);
continue;
}
else if (error != CL_SUCCESS)
{
print_error(error, "clEnqueueMapBuffer call failed");
log_error("\tOffset: %d Length: %d\n", (int)offset,
@@ -122,6 +149,11 @@ REGISTER_TEST(enqueue_map_buffer)
finalData, 0, NULL, NULL);
test_error(error, "Unable to read results");
if (is_immutable_buffer && !hasHostPtr)
{
continue;
}
for (size_t q = 0; q < bufferSize; q++)
{
if (referenceData[q] != finalData[q])
@@ -140,9 +172,10 @@ REGISTER_TEST(enqueue_map_buffer)
REGISTER_TEST(enqueue_map_image)
{
int error;
cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
const size_t imageSize = 256;
const size_t imageDataSize = imageSize * imageSize * 4 * sizeof(cl_uint);
constexpr cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
constexpr size_t imageSize = 256;
constexpr size_t imageDataSize =
imageSize * imageSize * 4 * sizeof(cl_uint);
PASSIVE_REQUIRE_IMAGE_SUPPORT(device)
@@ -158,20 +191,30 @@ REGISTER_TEST(enqueue_map_image)
log_info("Testing with cl_mem_flags src: %s\n",
flag_set_names[src_flag_id]);
if ((flag_set[src_flag_id] & CL_MEM_IMMUTABLE_EXT)
&& !is_extension_available(device,
"cl_ext_immutable_memory_objects"))
{
log_info("Device does not support CL_MEM_IMMUTABLE_EXT. "
"Skipping the memory flag.\n");
continue;
}
generate_random_data(kUInt, (unsigned int)(imageSize * imageSize * 4),
d, hostPtrData);
memcpy(referenceData, hostPtrData, imageDataSize);
cl_mem_flags flags = flag_set[src_flag_id];
bool is_immutable_image = flags & CL_MEM_IMMUTABLE_EXT;
bool hasHostPtr =
(flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
void *hostPtr = nullptr;
if (hasHostPtr) hostPtr = hostPtrData;
memObject = create_image_2d(context, CL_MEM_READ_WRITE | flags, &format,
imageSize, imageSize, 0, hostPtr, &error);
memObject = create_image_2d(context, flags, &format, imageSize,
imageSize, 0, hostPtr, &error);
test_error(error, "Unable to create testing buffer");
if (!hasHostPtr)
if (!hasHostPtr && !is_immutable_image)
{
size_t write_origin[3] = { 0, 0, 0 },
write_region[3] = { imageSize, imageSize, 1 };
@@ -198,7 +241,17 @@ REGISTER_TEST(enqueue_map_image)
cl_uint *mappedRegion = (cl_uint *)clEnqueueMapImage(
queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
region, &rowPitch, NULL, 0, NULL, NULL, &error);
if (error != CL_SUCCESS)
if (is_immutable_image)
{
test_failure_error_ret(
error, CL_INVALID_OPERATION,
"clEnqueueMapImage call was expected to fail "
"with CL_INVALID_OPERATION",
TEST_FAIL);
continue;
}
else if (error != CL_SUCCESS)
{
print_error(error, "clEnqueueMapImage call failed");
log_error("\tOffset: %d,%d Region: %d,%d\n", (int)offset[0],
@@ -245,6 +298,11 @@ REGISTER_TEST(enqueue_map_image)
finalRegion, 0, 0, finalData, 0, NULL, NULL);
test_error(error, "Unable to read results");
if (is_immutable_image && !hasHostPtr)
{
continue;
}
for (size_t q = 0; q < imageSize * imageSize * 4; q++)
{
if (referenceData[q] != finalData[q])

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
@@ -20,213 +20,217 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <memory>
#include "testBase.h"
static unsigned char *
generate_rgba8_image(int w, int h, MTdata d)
static std::unique_ptr<unsigned char[]> generate_rgba8_image(int w, int h,
MTdata d)
{
unsigned char *ptr = (unsigned char*)malloc(w * h * 4);
int i;
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[w * h * 4] };
for (i=0; i<w*h*4; i++)
for (int i = 0; i < w * h * 4; i++)
ptr[i] = (unsigned char)genrand_int32(d);
return ptr;
}
static int
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
static int verify_rgba8_image(const unsigned char *image,
const unsigned char *outptr, int w, int h)
{
int i;
int i;
for (i=0; i<w*h*4; i++)
for (i = 0; i < w * h * 4; i++)
{
if (outptr[i] != image[i])
return -1;
if (outptr[i] != image[i]) return -1;
}
return 0;
}
static unsigned short *
generate_rgba16_image(int w, int h, MTdata d)
static std::unique_ptr<unsigned short[]> generate_rgba16_image(int w, int h,
MTdata d)
{
unsigned short *ptr = (unsigned short *)malloc(w * h * 4 * sizeof(unsigned short));
int i;
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[w * h * 4] };
for (i=0; i<w*h*4; i++)
for (int i = 0; i < w * h * 4; i++)
ptr[i] = (unsigned short)genrand_int32(d);
return ptr;
}
static int
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
static int verify_rgba16_image(const unsigned short *image,
const unsigned short *outptr, int w, int h)
{
int i;
int i;
for (i=0; i<w*h*4; i++)
for (i = 0; i < w * h * 4; i++)
{
if (outptr[i] != image[i])
return -1;
if (outptr[i] != image[i]) return -1;
}
return 0;
}
static float *
generate_rgbafp_image(int w, int h, MTdata d)
static std::unique_ptr<float[]> generate_rgbafp_image(int w, int h, MTdata d)
{
float *ptr = (float*)malloc(w * h * 4 * sizeof(float));
int i;
std::unique_ptr<float[]> ptr{ new float[w * h * 4] };
for (i=0; i<w*h*4; i++)
for (int i = 0; i < w * h * 4; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
return ptr;
}
static int
verify_rgbafp_image(float *image, float *outptr, int w, int h)
static int verify_rgbafp_image(const float *image, const float *outptr, int w,
int h)
{
int i;
int i;
for (i=0; i<w*h*4; i++)
for (i = 0; i < w * h * 4; i++)
{
if (outptr[i] != image[i])
return -1;
if (outptr[i] != image[i]) return -1;
}
return 0;
}
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA,
CL_UNORM_INT16 },
{ CL_RGBA, CL_FLOAT } };
REGISTER_TEST(imagecopy)
static int test_imagecopy_impl(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements,
cl_mem_flags src_image_flags)
{
cl_image_format img_format;
unsigned char *rgba8_inptr, *rgba8_outptr;
unsigned short *rgba16_inptr, *rgba16_outptr;
float *rgbafp_inptr, *rgbafp_outptr;
clMemWrapper streams[6];
int img_width = 512;
int img_height = 512;
int i, err;
MTdata d;
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
clMemWrapper streams[6];
int img_width = 512;
int img_height = 512;
int i, err;
MTdataHolder d(gRandomSeed);
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
rgba8_inptr = generate_rgba8_image(img_width, img_height, d);
rgba16_inptr = generate_rgba16_image(img_width, img_height, d);
rgbafp_inptr = generate_rgbafp_image(img_width, img_height, d);
d = init_genrand( gRandomSeed );
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, d);
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, d);
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, d);
free_mtdata(d); d = NULL;
rgba8_outptr.reset(new unsigned char[4 * img_width * img_height]);
rgba16_outptr.reset(new unsigned short[4 * img_width * img_height]);
rgbafp_outptr.reset(new float[4 * img_width * img_height]);
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height);
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height);
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height);
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT8;
streams[0] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
streams[1] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT16;
streams[2] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
streams[3] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_FLOAT;
streams[4] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
streams[5] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
for (i=0; i<3; i++)
for (size_t index = 0; index < image_formats_count; ++index)
{
void *p, *outp;
int x, y, delta_w = img_width/8, delta_h = img_height/16;
void *ptr = nullptr;
if (src_image_flags & CL_MEM_USE_HOST_PTR
|| src_image_flags & CL_MEM_COPY_HOST_PTR)
{
switch (index)
{
case 0: ptr = rgba8_inptr.get(); break;
case 1: ptr = rgba16_inptr.get(); break;
case 2: ptr = rgbafp_inptr.get(); break;
default: break;
}
}
streams[index * 2] =
create_image_2d(context, src_image_flags, &image_formats[index],
img_width, img_height, 0, ptr, &err);
test_error(err, "create_image_2d failed");
streams[index * 2 + 1] =
create_image_2d(context, CL_MEM_READ_WRITE, &image_formats[index],
img_width, img_height, 0, nullptr, &err);
test_error(err, "create_image_2d failed");
}
for (i = 0; i < 3; i++)
{
void *p, *outp;
int x, y, delta_w = img_width / 8, delta_h = img_height / 16;
switch (i)
{
case 0:
p = (void *)rgba8_inptr;
outp = (void *)rgba8_outptr;
log_info("Testing CL_RGBA CL_UNORM_INT8\n");
p = rgba8_inptr.get();
outp = rgba8_outptr.get();
log_info("Testing CL_RGBA CL_UNORM_INT8\n");
break;
case 1:
p = (void *)rgba16_inptr;
outp = (void *)rgba16_outptr;
log_info("Testing CL_RGBA CL_UNORM_INT16\n");
p = rgba16_inptr.get();
outp = rgba16_outptr.get();
log_info("Testing CL_RGBA CL_UNORM_INT16\n");
break;
case 2:
p = (void *)rgbafp_inptr;
outp = (void *)rgbafp_outptr;
log_info("Testing CL_RGBA CL_FLOAT\n");
p = rgbafp_inptr.get();
outp = rgbafp_outptr.get();
log_info("Testing CL_RGBA CL_FLOAT\n");
break;
}
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, 1};
err = clEnqueueWriteImage(queue, streams[i*2], CL_TRUE, origin, region, 0, 0, p, 0, NULL, NULL);
test_error(err, "create_image_2d failed");
size_t origin[3] = { 0, 0, 0 },
region[3] = { img_width, img_height, 1 };
if (!(src_image_flags & CL_MEM_USE_HOST_PTR
|| src_image_flags & CL_MEM_COPY_HOST_PTR))
{
err = clEnqueueWriteImage(queue, streams[i * 2], CL_TRUE, origin,
region, 0, 0, p, 0, nullptr, nullptr);
test_error(err, "create_image_2d failed");
}
int copy_number = 0;
for (y=0; y<img_height; y+=delta_h)
for (y = 0; y < img_height; y += delta_h)
{
for (x=0; x<img_width; x+=delta_w)
for (x = 0; x < img_width; x += delta_w)
{
copy_number++;
size_t copy_origin[3] = {x,y,0}, copy_region[3]={delta_w, delta_h, 1};
err = clEnqueueCopyImage(queue, streams[i*2], streams[i*2+1],
copy_origin, copy_origin, copy_region,
0, NULL, NULL);
if (err) {
log_error("Copy %d (origin [%d, %d], size [%d, %d], image size [%d x %d]) Failed\n", copy_number, x, y, delta_w, delta_h, img_width, img_height);
}
test_error(err, "clEnqueueCopyImage failed");
copy_number++;
size_t copy_origin[3] = { x, y, 0 },
copy_region[3] = { delta_w, delta_h, 1 };
err = clEnqueueCopyImage(
queue, streams[i * 2], streams[i * 2 + 1], copy_origin,
copy_origin, copy_region, 0, NULL, NULL);
if (err)
{
log_error("Copy %d (origin [%d, %d], size [%d, %d], image "
"size [%d x %d]) Failed\n",
copy_number, x, y, delta_w, delta_h, img_width,
img_height);
}
test_error(err, "clEnqueueCopyImage failed");
}
}
err = clEnqueueReadImage(queue, streams[i*2+1], CL_TRUE, origin, region, 0, 0, outp, 0, NULL, NULL);
err = clEnqueueReadImage(queue, streams[i * 2 + 1], CL_TRUE, origin,
region, 0, 0, outp, 0, NULL, NULL);
test_error(err, "clEnqueueReadImage failed");
switch (i)
{
case 0:
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height);
err = verify_rgba8_image(rgba8_inptr.get(), rgba8_outptr.get(),
img_width, img_height);
break;
case 1:
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height);
err =
verify_rgba16_image(rgba16_inptr.get(), rgba16_outptr.get(),
img_width, img_height);
break;
case 2:
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height);
err =
verify_rgbafp_image(rgbafp_inptr.get(), rgbafp_outptr.get(),
img_width, img_height);
break;
}
if (err)
break;
if (err) break;
}
free(rgba8_inptr);
free(rgba16_inptr);
free(rgbafp_inptr);
free(rgba8_outptr);
free(rgba16_outptr);
free(rgbafp_outptr);
if (err)
log_error("IMAGE copy test failed\n");
else
@@ -234,3 +238,11 @@ REGISTER_TEST(imagecopy)
return err;
}
REGISTER_TEST(imagecopy)
{
PASSIVE_REQUIRE_IMAGE_SUPPORT(device);
return test_imagecopy_impl(device, context, queue, num_elements,
CL_MEM_READ_WRITE);
}

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
@@ -20,213 +20,227 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <memory>
#include "testBase.h"
static unsigned char *
static std::unique_ptr<unsigned char[]>
generate_uint8_image(unsigned num_elements, MTdata d)
{
unsigned char *ptr = (unsigned char*)malloc(num_elements);
unsigned i;
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[num_elements] };
for (i=0; i<num_elements; i++)
for (unsigned i = 0; i < num_elements; i++)
ptr[i] = (unsigned char)genrand_int32(d);
return ptr;
}
static int
verify_uint8_image(unsigned char *image, unsigned char *outptr, unsigned num_elements)
static int verify_uint8_image(const unsigned char *image,
const unsigned char *outptr,
unsigned num_elements)
{
unsigned i;
for (i=0; i<num_elements; i++)
for (i = 0; i < num_elements; i++)
{
if (outptr[i] != image[i])
return -1;
if (outptr[i] != image[i]) return -1;
}
return 0;
}
static unsigned short *
static std::unique_ptr<unsigned short[]>
generate_uint16_image(unsigned num_elements, MTdata d)
{
unsigned short *ptr = (unsigned short *)malloc(num_elements * sizeof(unsigned short));
unsigned i;
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[num_elements] };
for (i=0; i<num_elements; i++)
for (unsigned i = 0; i < num_elements; i++)
ptr[i] = (unsigned short)genrand_int32(d);
return ptr;
}
static int
verify_uint16_image(unsigned short *image, unsigned short *outptr, unsigned num_elements)
static int verify_uint16_image(const unsigned short *image,
const unsigned short *outptr,
unsigned num_elements)
{
unsigned i;
for (i=0; i<num_elements; i++)
for (i = 0; i < num_elements; i++)
{
if (outptr[i] != image[i])
return -1;
if (outptr[i] != image[i]) return -1;
}
return 0;
}
static float *
generate_float_image(unsigned num_elements, MTdata d)
static std::unique_ptr<float[]> generate_float_image(unsigned num_elements,
MTdata d)
{
float *ptr = (float*)malloc(num_elements * sizeof(float));
unsigned i;
std::unique_ptr<float[]> ptr{ new float[num_elements] };
for (i=0; i<num_elements; i++)
for (unsigned i = 0; i < num_elements; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
return ptr;
}
static int
verify_float_image(float *image, float *outptr, unsigned num_elements)
static int verify_float_image(const float *image, const float *outptr,
unsigned num_elements)
{
unsigned i;
for (i=0; i<num_elements; i++)
for (i = 0; i < num_elements; i++)
{
if (outptr[i] != image[i])
return -1;
if (outptr[i] != image[i]) return -1;
}
return 0;
}
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA,
CL_UNORM_INT16 },
{ CL_RGBA, CL_FLOAT } };
REGISTER_TEST(imagecopy3d)
static int test_imagecopy3d_impl(cl_device_id device, cl_context context,
cl_command_queue queue,
int num_elements_ignored,
cl_mem_flags src_image_flags)
{
cl_image_format img_format;
unsigned char *rgba8_inptr, *rgba8_outptr;
unsigned short *rgba16_inptr, *rgba16_outptr;
float *rgbafp_inptr, *rgbafp_outptr;
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
clMemWrapper streams[6];
int img_width = 128;
int img_height = 128;
int img_depth = 64;
int i;
cl_int err;
unsigned num_elems = img_width * img_height * img_depth * 4;
MTdata d;
cl_int err;
unsigned num_elements = img_width * img_height * img_depth * 4;
MTdataHolder d(gRandomSeed);
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device )
rgba8_inptr = generate_uint8_image(num_elements, d);
rgba16_inptr = generate_uint16_image(num_elements, d);
rgbafp_inptr = generate_float_image(num_elements, d);
d = init_genrand( gRandomSeed );
rgba8_inptr = (unsigned char *)generate_uint8_image(num_elems, d);
rgba16_inptr = (unsigned short *)generate_uint16_image(num_elems, d);
rgbafp_inptr = (float *)generate_float_image(num_elems, d);
free_mtdata(d); d = NULL;
rgba8_outptr.reset(new unsigned char[num_elements]);
rgba16_outptr.reset(new unsigned short[num_elements]);
rgbafp_outptr.reset(new float[num_elements]);
rgba8_outptr = (unsigned char *)malloc(sizeof(unsigned char) * num_elems);
rgba16_outptr =
(unsigned short *)malloc(sizeof(unsigned short) * num_elems);
rgbafp_outptr = (float *)malloc(sizeof(float) * num_elems);
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT8;
streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
streams[1] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT16;
streams[2] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
streams[3] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_FLOAT;
streams[4] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
streams[5] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
for (i=0; i<3; i++)
for (size_t index = 0; index < image_formats_count; ++index)
{
void *p, *outp;
int x, y, z, delta_w = img_width/8, delta_h = img_height/16, delta_d = img_depth/4;
void *ptr = nullptr;
if (src_image_flags & CL_MEM_USE_HOST_PTR
|| src_image_flags & CL_MEM_COPY_HOST_PTR)
{
switch (index)
{
case 0: ptr = rgba8_inptr.get(); break;
case 1: ptr = rgba16_inptr.get(); break;
case 2: ptr = rgbafp_inptr.get(); break;
default: break;
}
}
streams[index * 2] =
create_image_3d(context, src_image_flags, &image_formats[index],
img_width, img_height, img_depth, 0, 0, ptr, &err);
test_error(err, "create_image_3d failed");
streams[index * 2 + 1] = create_image_3d(
context, CL_MEM_READ_ONLY, &image_formats[index], img_width,
img_height, img_depth, 0, 0, nullptr, &err);
test_error(err, "create_image_3d failed");
}
for (i = 0; i < image_formats_count; i++)
{
void *p, *outp;
int x, y, z, delta_w = img_width / 8, delta_h = img_height / 16,
delta_d = img_depth / 4;
switch (i)
{
case 0:
p = (void *)rgba8_inptr;
outp = (void *)rgba8_outptr;
p = rgba8_inptr.get();
outp = rgba8_outptr.get();
break;
case 1:
p = (void *)rgba16_inptr;
outp = (void *)rgba16_outptr;
p = rgba16_inptr.get();
outp = rgba16_outptr.get();
break;
case 2:
p = (void *)rgbafp_inptr;
outp = (void *)rgbafp_outptr;
p = rgbafp_inptr.get();
outp = rgbafp_outptr.get();
break;
}
size_t origin[3]={0,0,0}, region[3]={img_width, img_height, img_depth};
err = clEnqueueWriteImage(queue, streams[i*2], CL_TRUE, origin, region, 0, 0, p, 0, NULL, NULL);
test_error(err, "clEnqueueWriteImage failed");
for (z=0; z<img_depth; z+=delta_d)
size_t origin[3] = { 0, 0, 0 },
region[3] = { img_width, img_height, img_depth };
if (!(src_image_flags & CL_MEM_USE_HOST_PTR
|| src_image_flags & CL_MEM_COPY_HOST_PTR))
{
for (y=0; y<img_height; y+=delta_h)
{
for (x=0; x<img_width; x+=delta_w)
{
origin[0] = x; origin[1] = y; origin[2] = z;
region[0] = delta_w; region[1] = delta_h; region[2] = delta_d;
err = clEnqueueWriteImage(queue, streams[i * 2], CL_TRUE, origin,
region, 0, 0, p, 0, nullptr, nullptr);
test_error(err, "clEnqueueWriteImage failed");
}
err = clEnqueueCopyImage(queue, streams[i*2], streams[i*2+1], origin, origin, region, 0, NULL, NULL);
test_error(err, "clEnqueueCopyImage failed");
for (z = 0; z < img_depth; z += delta_d)
{
for (y = 0; y < img_height; y += delta_h)
{
for (x = 0; x < img_width; x += delta_w)
{
origin[0] = x;
origin[1] = y;
origin[2] = z;
region[0] = delta_w;
region[1] = delta_h;
region[2] = delta_d;
err = clEnqueueCopyImage(queue, streams[i * 2],
streams[i * 2 + 1], origin, origin,
region, 0, NULL, NULL);
test_error(err, "clEnqueueCopyImage failed");
}
}
}
origin[0] = 0; origin[1] = 0; origin[2] = 0;
region[0] = img_width; region[1] = img_height; region[2] = img_depth;
err = clEnqueueReadImage(queue, streams[i*2+1], CL_TRUE, origin, region, 0, 0, outp, 0, NULL, NULL);
origin[0] = 0;
origin[1] = 0;
origin[2] = 0;
region[0] = img_width;
region[1] = img_height;
region[2] = img_depth;
err = clEnqueueReadImage(queue, streams[i * 2 + 1], CL_TRUE, origin,
region, 0, 0, outp, 0, NULL, NULL);
test_error(err, "clEnqueueReadImage failed");
switch (i)
{
case 0:
err = verify_uint8_image(rgba8_inptr, rgba8_outptr, num_elems);
err = verify_uint8_image(rgba8_inptr.get(), rgba8_outptr.get(),
num_elements);
if (err) log_error("Failed uint8\n");
break;
case 1:
err =
verify_uint16_image(rgba16_inptr, rgba16_outptr, num_elems);
err = verify_uint16_image(rgba16_inptr.get(),
rgba16_outptr.get(), num_elements);
if (err) log_error("Failed uint16\n");
break;
case 2:
err =
verify_float_image(rgbafp_inptr, rgbafp_outptr, num_elems);
err = verify_float_image(rgbafp_inptr.get(),
rgbafp_outptr.get(), num_elements);
if (err) log_error("Failed float\n");
break;
}
if (err)
break;
if (err) break;
}
free(rgba8_inptr);
free(rgba16_inptr);
free(rgbafp_inptr);
free(rgba8_outptr);
free(rgba16_outptr);
free(rgbafp_outptr);
if (err)
log_error("IMAGE3D copy test failed\n");
else
@@ -234,3 +248,11 @@ REGISTER_TEST(imagecopy3d)
return err;
}
REGISTER_TEST(imagecopy3d)
{
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(device);
return test_imagecopy3d_impl(device, context, queue, num_elements,
CL_MEM_READ_WRITE);
}

View File

@@ -15,6 +15,7 @@
//
#include "harness/compat.h"
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -23,16 +24,15 @@
#include "testBase.h"
static unsigned char *
generate_rgba8_image(int w, int h, MTdata d)
static std::unique_ptr<unsigned char[]> generate_rgba8_image(int w, int h,
MTdata d)
{
unsigned char *ptr = (unsigned char*)malloc(w * h * 4);
int i;
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[w * h * 4] };
for (i=0; i<w*h*4; i++)
ptr[i] = (unsigned char)genrand_int32(d);
for (int i = 0; i < w * h * 4; i++)
ptr[i] = (unsigned char)genrand_int32(d);
return ptr;
return ptr;
}
static void
@@ -73,8 +73,8 @@ update_image_from_image(void *out, void *in, int x, int y, int w, int h, int img
}
}
static int
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
static int verify_rgba8_image(const unsigned char *image,
const unsigned char *outptr, int w, int h)
{
int i;
@@ -91,16 +91,15 @@ verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h)
}
static unsigned short *
generate_rgba16_image(int w, int h, MTdata d)
static std::unique_ptr<unsigned short[]> generate_rgba16_image(int w, int h,
MTdata d)
{
unsigned short *ptr = (unsigned short*)malloc(w * h * 4 * sizeof(unsigned short));
int i;
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[w * h * 4] };
for (i=0; i<w*h*4; i++)
ptr[i] = (unsigned short)genrand_int32(d);
for (int i = 0; i < w * h * 4; i++)
ptr[i] = (unsigned short)genrand_int32(d);
return ptr;
return ptr;
}
static void
@@ -121,8 +120,8 @@ update_rgba16_image(unsigned short *p, int x, int y, int w, int h, int img_width
}
}
static int
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
static int verify_rgba16_image(const unsigned short *image,
const unsigned short *outptr, int w, int h)
{
int i;
@@ -139,16 +138,14 @@ verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h)
}
static float *
generate_rgbafp_image(int w, int h, MTdata d)
static std::unique_ptr<float[]> generate_rgbafp_image(int w, int h, MTdata d)
{
float *ptr = (float*)malloc(w * h * 4 * sizeof(float));
int i;
std::unique_ptr<float[]> ptr{ new float[w * h * 4] };
for (i=0; i<w*h*4; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
for (int i = 0; i < w * h * 4; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, d);
return ptr;
return ptr;
}
static void
@@ -169,8 +166,8 @@ update_rgbafp_image(float *p, int x, int y, int w, int h, int img_width, MTdata
}
}
static int
verify_rgbafp_image(float *image, float *outptr, int w, int h)
static int verify_rgbafp_image(const float *image, const float *outptr, int w,
int h)
{
int i;
@@ -186,59 +183,52 @@ verify_rgbafp_image(float *image, float *outptr, int w, int h)
return 0;
}
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA,
CL_UNORM_INT16 },
{ CL_RGBA, CL_FLOAT } };
REGISTER_TEST(imagereadwrite)
{
cl_image_format img_format;
unsigned char *rgba8_inptr, *rgba8_outptr;
unsigned short *rgba16_inptr, *rgba16_outptr;
float *rgbafp_inptr, *rgbafp_outptr;
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
clMemWrapper streams[3];
int img_width = 512;
int img_height = 512;
int num_tries = 200;
int i, j, err;
MTdata d;
MTdataHolder d(gRandomSeed);
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
d = init_genrand( gRandomSeed );
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, d);
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, d);
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, d);
rgba8_inptr = generate_rgba8_image(img_width, img_height, d);
rgba16_inptr = generate_rgba16_image(img_width, img_height, d);
rgbafp_inptr = generate_rgbafp_image(img_width, img_height, d);
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height);
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height);
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height);
rgba8_outptr.reset(new unsigned char[4 * img_width * img_height]);
rgba16_outptr.reset(new unsigned short[4 * img_width * img_height]);
rgbafp_outptr.reset(new float[4 * img_width * img_height]);
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT8;
streams[0] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT16;
streams[1] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_FLOAT;
streams[2] = create_image_2d(context, CL_MEM_READ_WRITE, &img_format,
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
for (size_t index = 0; index < image_formats_count; ++index)
{
streams[index] =
create_image_2d(context, CL_MEM_READ_WRITE, &image_formats[index],
img_width, img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
}
for (i=0; i<3; i++)
{
void *p;
if (i == 0)
p = (void *)rgba8_inptr;
p = rgba8_inptr.get();
else if (i == 1)
p = (void *)rgba16_inptr;
p = rgba16_inptr.get();
else
p = (void *)rgbafp_inptr;
p = rgbafp_inptr.get();
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, 1};
err = clEnqueueWriteImage(queue, streams[i], CL_TRUE,
origin, region, 0, 0,
@@ -250,7 +240,7 @@ REGISTER_TEST(imagereadwrite)
}
}
for (i=0,j=0; i<num_tries*3; i++,j++)
for (i = 0, j = 0; i < num_tries * image_formats_count; i++, j++)
{
int x = (int)get_random_float(0, img_width, d);
int y = (int)get_random_float(0, img_height, d);
@@ -260,10 +250,12 @@ REGISTER_TEST(imagereadwrite)
int set_input_pitch = (int)(genrand_int32(d) & 0x01);
int packed_update = (int)(genrand_int32(d) & 0x01);
void *p, *outp;
std::unique_ptr<unsigned char[]> p_rgba8;
std::unique_ptr<unsigned short[]> p_rgba16;
std::unique_ptr<float[]> p_rgbaf;
int elem_size;
if (j == 3)
j = 0;
if (j == image_formats_count) j = 0;
switch (j)
{
@@ -272,45 +264,57 @@ REGISTER_TEST(imagereadwrite)
elem_size = 4;
if(packed_update)
{
p = generate_rgba8_image(w, h, d);
update_image_from_image(rgba8_inptr, p, x, y, w, h, img_width, elem_size);
p_rgba8 = generate_rgba8_image(w, h, d);
p = p_rgba8.get();
update_image_from_image(rgba8_inptr.get(), p, x, y, w, h,
img_width, elem_size);
}
else
{
update_rgba8_image(rgba8_inptr, x, y, w, h, img_width, d);
p = (void *)(rgba8_inptr + ((y * img_width + x) * 4));
update_rgba8_image(rgba8_inptr.get(), x, y, w, h, img_width,
d);
p = static_cast<void *>(rgba8_inptr.get()
+ ((y * img_width + x) * 4));
}
outp = (void *)rgba8_outptr;
outp = static_cast<void *>(rgba8_outptr.get());
break;
case 1:
//if ((w<=8) || (h<=8)) continue;
elem_size = 2*4;
if(packed_update)
{
p = generate_rgba16_image(w, h, d);
update_image_from_image(rgba16_inptr, p, x, y, w, h, img_width, elem_size);
p_rgba16 = generate_rgba16_image(w, h, d);
p = p_rgba16.get();
update_image_from_image(rgba16_inptr.get(), p, x, y, w, h,
img_width, elem_size);
}
else
{
update_rgba16_image(rgba16_inptr, x, y, w, h, img_width, d);
p = (void *)(rgba16_inptr + ((y * img_width + x) * 4));
update_rgba16_image(rgba16_inptr.get(), x, y, w, h,
img_width, d);
p = static_cast<void *>(rgba16_inptr.get()
+ ((y * img_width + x) * 4));
}
outp = (void *)rgba16_outptr;
outp = static_cast<void *>(rgba16_outptr.get());
break;
case 2:
//if ((w<=8) || (h<=8)) continue;
elem_size = 4*4;
if(packed_update)
{
p = generate_rgbafp_image(w, h, d);
update_image_from_image(rgbafp_inptr, p, x, y, w, h, img_width, elem_size);
p_rgbaf = generate_rgbafp_image(w, h, d);
p = p_rgbaf.get();
update_image_from_image(rgbafp_inptr.get(), p, x, y, w, h,
img_width, elem_size);
}
else
{
update_rgbafp_image(rgbafp_inptr, x, y, w, h, img_width, d);
p = (void *)(rgbafp_inptr + ((y * img_width + x) * 4));
update_rgbafp_image(rgbafp_inptr.get(), x, y, w, h,
img_width, d);
p = static_cast<void *>(rgbafp_inptr.get()
+ ((y * img_width + x) * 4));
}
outp = (void *)rgbafp_outptr;
outp = static_cast<void *>(rgbafp_outptr.get());
break;
default:
log_error("ERROR Invalid j = %d\n", j);
@@ -358,8 +362,7 @@ REGISTER_TEST(imagereadwrite)
if(packed_update)
{
free(p);
p = NULL;
p = nullptr;
}
memset(outp, 0x7, img_width*img_height*elem_size);
@@ -379,7 +382,8 @@ REGISTER_TEST(imagereadwrite)
switch (j)
{
case 0:
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height);
err = verify_rgba8_image(rgba8_inptr.get(), rgba8_outptr.get(),
img_width, img_height);
if (err)
{
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
@@ -387,7 +391,9 @@ REGISTER_TEST(imagereadwrite)
}
break;
case 1:
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height);
err =
verify_rgba16_image(rgba16_inptr.get(), rgba16_outptr.get(),
img_width, img_height);
if (err)
{
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
@@ -395,7 +401,9 @@ REGISTER_TEST(imagereadwrite)
}
break;
case 2:
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height);
err =
verify_rgbafp_image(rgbafp_inptr.get(), rgbafp_outptr.get(),
img_width, img_height);
if (err)
{
log_error("x=%d y=%d w=%d h=%d, pitch=%d, try=%d\n", x, y, w, h, (int)input_pitch, (int)i);
@@ -407,14 +415,6 @@ REGISTER_TEST(imagereadwrite)
if (err) break;
}
free_mtdata(d);
free(rgba8_inptr);
free(rgba16_inptr);
free(rgbafp_inptr);
free(rgba8_outptr);
free(rgba16_outptr);
free(rgbafp_outptr);
if (!err)
log_info("IMAGE read, write test passed\n");

View File

@@ -15,6 +15,7 @@
//
#include "harness/compat.h"
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -23,14 +24,13 @@
#include "testBase.h"
static unsigned char *
static std::unique_ptr<unsigned char[]>
generate_rgba8_image(int w, int h, int d, MTdata mtData)
{
unsigned char *ptr = (unsigned char*)malloc(w * h * d *4);
int i;
std::unique_ptr<unsigned char[]> ptr{ new unsigned char[w * h * d * 4] };
for (i=0; i<w*h*d*4; i++)
ptr[i] = (unsigned char)genrand_int32(mtData);
for (int i = 0; i < w * h * d * 4; i++)
ptr[i] = (unsigned char)genrand_int32(mtData);
return ptr;
}
@@ -77,8 +77,8 @@ update_image_from_image(void *out, void *in, int x, int y, int z, int w, int h,
}
}
static int
verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h, int d)
static int verify_rgba8_image(const unsigned char *image,
const unsigned char *outptr, int w, int h, int d)
{
int i;
@@ -95,14 +95,13 @@ verify_rgba8_image(unsigned char *image, unsigned char *outptr, int w, int h, in
}
static unsigned short *
static std::unique_ptr<unsigned short[]>
generate_rgba16_image(int w, int h, int d, MTdata mtData)
{
unsigned short *ptr = (unsigned short*)malloc(w * h * d * 4 * sizeof(unsigned short));
int i;
std::unique_ptr<unsigned short[]> ptr{ new unsigned short[w * h * d * 4] };
for (i=0; i<w*h*d*4; i++)
ptr[i] = (unsigned short)genrand_int32(mtData);
for (int i = 0; i < w * h * d * 4; i++)
ptr[i] = (unsigned short)genrand_int32(mtData);
return ptr;
}
@@ -127,8 +126,9 @@ update_rgba16_image(unsigned short *p, int x, int y, int z, int w, int h, int d,
}
}
static int
verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h, int d)
static int verify_rgba16_image(const unsigned short *image,
const unsigned short *outptr, int w, int h,
int d)
{
int i;
@@ -145,14 +145,13 @@ verify_rgba16_image(unsigned short *image, unsigned short *outptr, int w, int h,
}
static float *
generate_rgbafp_image(int w, int h, int d, MTdata mtData)
static std::unique_ptr<float[]> generate_rgbafp_image(int w, int h, int d,
MTdata mtData)
{
float *ptr = (float*)malloc(w * h * d *4 * sizeof(float));
int i;
std::unique_ptr<float[]> ptr{ new float[w * h * d * 4] };
for (i=0; i<w*h*d*4; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, mtData);
for (int i = 0; i < w * h * d * 4; i++)
ptr[i] = get_random_float(-0x40000000, 0x40000000, mtData);
return ptr;
}
@@ -177,8 +176,8 @@ update_rgbafp_image(float *p, int x, int y, int z, int w, int h, int d, int img_
}
}
static int
verify_rgbafp_image(float *image, float *outptr, int w, int h, int d)
static int verify_rgbafp_image(const float *image, const float *outptr, int w,
int h, int d)
{
int i;
@@ -194,13 +193,17 @@ verify_rgbafp_image(float *image, float *outptr, int w, int h, int d)
return 0;
}
static constexpr cl_image_format image_formats[] = { { CL_RGBA, CL_UNORM_INT8 },
{ CL_RGBA,
CL_UNORM_INT16 },
{ CL_RGBA, CL_FLOAT } };
REGISTER_TEST(imagereadwrite3d)
{
cl_image_format img_format;
unsigned char *rgba8_inptr, *rgba8_outptr;
unsigned short *rgba16_inptr, *rgba16_outptr;
float *rgbafp_inptr, *rgbafp_outptr;
constexpr size_t image_formats_count = ARRAY_SIZE(image_formats);
std::unique_ptr<unsigned char[]> rgba8_inptr, rgba8_outptr;
std::unique_ptr<unsigned short[]> rgba16_inptr, rgba16_outptr;
std::unique_ptr<float[]> rgbafp_inptr, rgbafp_outptr;
clMemWrapper streams[3];
int img_width = 64;
int img_height = 64;
@@ -208,44 +211,41 @@ REGISTER_TEST(imagereadwrite3d)
int img_slice = img_width * img_height;
int num_tries = 30;
int i, j, err;
MTdata mtData;
MTdataHolder mtData(gRandomSeed);
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device )
mtData = init_genrand( gRandomSeed );
rgba8_inptr = (unsigned char *)generate_rgba8_image(img_width, img_height, img_depth, mtData);
rgba16_inptr = (unsigned short *)generate_rgba16_image(img_width, img_height, img_depth, mtData);
rgbafp_inptr = (float *)generate_rgbafp_image(img_width, img_height, img_depth, mtData);
rgba8_inptr =
generate_rgba8_image(img_width, img_height, img_depth, mtData);
rgba16_inptr =
generate_rgba16_image(img_width, img_height, img_depth, mtData);
rgbafp_inptr =
generate_rgbafp_image(img_width, img_height, img_depth, mtData);
rgba8_outptr = (unsigned char*)malloc(sizeof(unsigned char) * 4 * img_width * img_height * img_depth);
rgba16_outptr = (unsigned short*)malloc(sizeof(unsigned short) * 4 * img_width * img_height * img_depth);
rgbafp_outptr = (float*)malloc(sizeof(float) * 4 * img_width * img_height * img_depth);
rgba8_outptr.reset(
new unsigned char[4 * img_width * img_height * img_depth]);
rgba16_outptr.reset(
new unsigned short[4 * img_width * img_height * img_depth]);
rgbafp_outptr.reset(new float[4 * img_width * img_height * img_depth]);
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT8;
streams[0] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
for (size_t index = 0; index < image_formats_count; ++index)
{
streams[index] = create_image_3d(
context, CL_MEM_READ_ONLY, &image_formats[index], img_width,
img_height, img_depth, 0, 0, nullptr, &err);
test_error(err, "create_image_3d failed");
}
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_UNORM_INT16;
streams[1] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
img_format.image_channel_order = CL_RGBA;
img_format.image_channel_data_type = CL_FLOAT;
streams[2] = create_image_3d(context, CL_MEM_READ_ONLY, &img_format, img_width, img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
for (i=0; i<3; i++)
for (i = 0; i < image_formats_count; i++)
{
void *p;
if (i == 0)
p = (void *)rgba8_inptr;
p = rgba8_inptr.get();
else if (i == 1)
p = (void *)rgba16_inptr;
p = rgba16_inptr.get();
else
p = (void *)rgbafp_inptr;
p = rgbafp_inptr.get();
size_t origin[3] = {0,0,0}, region[3] = {img_width, img_height, img_depth};
err = clEnqueueWriteImage(queue, streams[i], CL_TRUE,
@@ -255,7 +255,7 @@ REGISTER_TEST(imagereadwrite3d)
test_error(err, "clEnqueueWriteImage failed");
}
for (i=0,j=0; i<num_tries*3; i++,j++)
for (i = 0, j = 0; i < num_tries * image_formats_count; i++, j++)
{
int x = (int)get_random_float(0, (float)img_width - 1, mtData);
int y = (int)get_random_float(0, (float)img_height - 1, mtData);
@@ -267,10 +267,12 @@ REGISTER_TEST(imagereadwrite3d)
int set_input_pitch = (int)(genrand_int32(mtData) & 0x01);
int packed_update = (int)(genrand_int32(mtData) & 0x01);
void *p, *outp;
std::unique_ptr<unsigned char[]> p_rgba8;
std::unique_ptr<unsigned short[]> p_rgba16;
std::unique_ptr<float[]> p_rgbaf;
int elem_size;
if (j == 3)
j = 0;
if (j == image_formats_count) j = 0;
// packed: the source image for the write is a whole image .
// unpacked: the source image for the write is a subset within a larger image
@@ -280,43 +282,64 @@ REGISTER_TEST(imagereadwrite3d)
elem_size = 4;
if(packed_update)
{
p = generate_rgba8_image(w, h, d, mtData);
update_image_from_image(rgba8_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
p_rgba8 = generate_rgba8_image(w, h, d, mtData);
p = p_rgba8.get();
update_image_from_image(rgba8_inptr.get(), p, x, y, z, w, h,
d, img_width, img_height, img_depth,
elem_size);
}
else
{
update_rgba8_image(rgba8_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
p = (void *)(rgba8_inptr + ((z * img_slice + y * img_width + x) * 4));
update_rgba8_image(rgba8_inptr.get(), x, y, z, w, h, d,
img_width, img_height, img_depth,
mtData);
p = static_cast<void *>(
rgba8_inptr.get()
+ ((z * img_slice + y * img_width + x) * 4));
}
outp = (void *)rgba8_outptr;
outp = static_cast<void *>(rgba8_outptr.get());
break;
case 1:
elem_size = 2*4;
if(packed_update)
{
p = generate_rgba16_image(w, h, d, mtData);
update_image_from_image(rgba16_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
p_rgba16 = generate_rgba16_image(w, h, d, mtData);
p = p_rgba16.get();
update_image_from_image(rgba16_inptr.get(), p, x, y, z, w,
h, d, img_width, img_height,
img_depth, elem_size);
}
else
{
update_rgba16_image(rgba16_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
p = (void *)(rgba16_inptr + ((z * img_slice + y * img_width + x) * 4));
update_rgba16_image(rgba16_inptr.get(), x, y, z, w, h, d,
img_width, img_height, img_depth,
mtData);
p = static_cast<void *>(
rgba16_inptr.get()
+ ((z * img_slice + y * img_width + x) * 4));
}
outp = (void *)rgba16_outptr;
outp = static_cast<void *>(rgba16_outptr.get());
break;
case 2:
elem_size = 4*4;
if(packed_update)
{
p = generate_rgbafp_image(w, h, d, mtData);
update_image_from_image(rgbafp_inptr, p, x, y, z, w, h, d, img_width, img_height, img_depth, elem_size);
p_rgbaf = generate_rgbafp_image(w, h, d, mtData);
p = p_rgbaf.get();
update_image_from_image(rgbafp_inptr.get(), p, x, y, z, w,
h, d, img_width, img_height,
img_depth, elem_size);
}
else
{
update_rgbafp_image(rgbafp_inptr, x, y, z, w, h, d, img_width, img_height, img_depth, mtData);
p = (void *)(rgbafp_inptr + ((z * img_slice + y * img_width + x) * 4));
update_rgbafp_image(rgbafp_inptr.get(), x, y, z, w, h, d,
img_width, img_height, img_depth,
mtData);
p = static_cast<void *>(
rgbafp_inptr.get()
+ ((z * img_slice + y * img_width + x) * 4));
}
outp = (void *)rgbafp_outptr;
outp = static_cast<void *>(rgbafp_outptr.get());
break;
default:
log_error("ERROR Invalid j = %d\n", j);
@@ -360,8 +383,7 @@ REGISTER_TEST(imagereadwrite3d)
if(packed_update)
{
free(p);
p = NULL;
p = nullptr;
}
memset(outp, 0x7, img_width*img_height*img_depth*elem_size);
@@ -375,7 +397,8 @@ REGISTER_TEST(imagereadwrite3d)
switch (j)
{
case 0:
err = verify_rgba8_image(rgba8_inptr, rgba8_outptr, img_width, img_height, img_depth);
err = verify_rgba8_image(rgba8_inptr.get(), rgba8_outptr.get(),
img_width, img_height, img_depth);
if (err)
{
log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
@@ -383,7 +406,9 @@ REGISTER_TEST(imagereadwrite3d)
}
break;
case 1:
err = verify_rgba16_image(rgba16_inptr, rgba16_outptr, img_width, img_height, img_depth);
err =
verify_rgba16_image(rgba16_inptr.get(), rgba16_outptr.get(),
img_width, img_height, img_depth);
if (err)
{
log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
@@ -391,7 +416,9 @@ REGISTER_TEST(imagereadwrite3d)
}
break;
case 2:
err = verify_rgbafp_image(rgbafp_inptr, rgbafp_outptr, img_width, img_height, img_depth);
err =
verify_rgbafp_image(rgbafp_inptr.get(), rgbafp_outptr.get(),
img_width, img_height, img_depth);
if (err)
{
log_error("x=%d y=%d z=%d w=%d h=%d d=%d pitch=%d, slice_pitch=%d, try=%d\n", x, y, z, w, h, d, (int)input_pitch, (int)input_slice_pitch, (int)i);
@@ -404,14 +431,6 @@ REGISTER_TEST(imagereadwrite3d)
break;
}
free_mtdata(mtData);
free(rgba8_inptr);
free(rgba16_inptr);
free(rgbafp_inptr);
free(rgba8_outptr);
free(rgba16_outptr);
free(rgbafp_outptr);
if (!err)
log_info("IMAGE read, write test passed\n");

View File

@@ -14,6 +14,7 @@
// limitations under the License.
//
#include <cinttypes>
#include <functional>
#include <string>
#include <vector>
@@ -182,13 +183,13 @@ static int test_intmath(cl_device_id device, cl_context context,
if (r != output[i])
{
log_error("\n\nverification failed at index %d\n", i);
log_error("-> inputs: %llu, %llu, %llu\n",
static_cast<cl_uint>(inputA[i]),
static_cast<cl_uint>(inputB[i]),
static_cast<cl_uint>(inputC[i]));
log_error("-> expected %llu, got %llu\n\n",
static_cast<cl_uint>(r),
static_cast<cl_uint>(output[i]));
log_error("-> inputs: %" PRIu64 "%" PRIu64 "%" PRIu64 "\n",
static_cast<cl_ulong>(inputA[i]),
static_cast<cl_ulong>(inputB[i]),
static_cast<cl_ulong>(inputC[i]));
log_error("-> expected %" PRIu64 "%" PRIu64 "\n\n",
static_cast<cl_ulong>(r),
static_cast<cl_ulong>(output[i]));
return TEST_FAIL;
}
}

View File

@@ -17,6 +17,8 @@
#include <unistd.h>
#endif
#include <cinttypes>
#include "harness/conversions.h"
#include "harness/typeWrappers.h"
#include "harness/errorHelpers.h"
@@ -315,9 +317,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
for (int i = 0; i < 6; i++) {
if ((results_data[i] & alignments[i]) != 0) {
total_errors++;
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data[i]);
log_error("\tVector size %d failed: 0x%" PRIx64
" is not properly aligned.\n",
1 << i, results_data[i]);
} else {
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data[i]);
if (DEBUG)
log_info("\tVector size %d passed: 0x%" PRIx64
" is properly aligned.\n",
1 << i, results_data[i]);
}
}
}
@@ -328,9 +335,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
for (int i = 0; i < 6; i++) {
if ((results_data_no_long[i] & alignments[i]) != 0) {
total_errors++;
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data_no_long[i]);
log_error("\tVector size %d failed: 0x%x is not "
"properly aligned.\n",
1 << i, results_data_no_long[i]);
} else {
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data_no_long[i]);
if (DEBUG)
log_info("\tVector size %d passed: 0x%x is "
"properly aligned.\n",
1 << i, results_data_no_long[i]);
}
}
}
@@ -383,9 +395,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
for (int i = 0; i < 5; i++) {
if ((results_data[i] & alignments[i]) != 0) {
total_errors++;
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data[i]);
log_error("\tVector size %d failed: 0x%" PRIx64
" is not properly aligned.\n",
1 << i, results_data[i]);
} else {
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data[i]);
if (DEBUG)
log_info("\tVector size %d passed: 0x%" PRIx64
" is properly aligned.\n",
1 << i, results_data[i]);
}
}
}
@@ -396,9 +413,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
for (int i = 0; i < 5; i++) {
if ((results_data_no_long[i] & alignments[i]) != 0) {
total_errors++;
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data_no_long[i]);
log_error("\tVector size %d failed: 0x%x is not "
"properly aligned.\n",
1 << i, results_data_no_long[i]);
} else {
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data_no_long[i]);
if (DEBUG)
log_info("\tVector size %d passed: 0x%x is "
"properly aligned.\n",
1 << i, results_data_no_long[i]);
}
}
}
@@ -455,9 +477,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
for (int i = 0; i < 5; i++) {
if ((results_data[i] & alignments[i]) != 0) {
total_errors++;
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data[i]);
log_error("\tVector size %d failed: 0x%" PRIx64
" is not properly aligned.\n",
1 << i, results_data[i]);
} else {
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data[i]);
if (DEBUG)
log_info("\tVector size %d passed: 0x%" PRIx64
" is properly aligned.\n",
1 << i, results_data[i]);
}
}
}
@@ -468,9 +495,14 @@ static int test_kernel_memory_alignment(cl_device_id device, cl_context context,
for (int i = 0; i < 5; i++) {
if ((results_data_no_long[i] & alignments[i]) != 0) {
total_errors++;
log_error("\tVector size %d failed: 0x%llx is not properly aligned.\n", 1 << i, results_data_no_long[i]);
log_error("\tVector size %d failed: 0x%x is not "
"properly aligned.\n",
1 << i, results_data_no_long[i]);
} else {
if (DEBUG) log_info("\tVector size %d passed: 0x%llx is properly aligned.\n", 1 << i, results_data_no_long[i]);
if (DEBUG)
log_info("\tVector size %d passed: 0x%x is "
"properly aligned.\n",
1 << i, results_data_no_long[i]);
}
}
}

View File

@@ -15,6 +15,8 @@
//
#include "testBase.h"
#include <cinttypes>
#define TEST_VALUE_POSITIVE( string_name, name, value ) \
{ \
if (name < value) { \
@@ -528,7 +530,14 @@ const char *kernel_constant_double_limits[] = {
};
#define TEST_FLOAT_ASSERTION( a, msg, f ) if( !( a ) ) { log_error( "ERROR: Float constant failed requirement: %s (bitwise value is 0x%8.8x)\n", msg, *( (uint32_t *)&f ) ); return -1; }
#define TEST_DOUBLE_ASSERTION( a, msg, f ) if( !( a ) ) { log_error( "ERROR: Double constant failed requirement: %s (bitwise value is 0x%16.16llx)\n", msg, *( (uint64_t *)&f ) ); return -1; }
#define TEST_DOUBLE_ASSERTION(a, msg, f) \
if (!(a)) \
{ \
log_error("ERROR: Double constant failed requirement: %s (bitwise " \
"value is 0x%16.16" PRIx64 ")\n", \
msg, *((uint64_t *)&f)); \
return -1; \
}
REGISTER_TEST(kernel_limit_constants)
{

View File

@@ -21,6 +21,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <cinttypes>
#include "testBase.h"
cl_int get_type_size( cl_context context, cl_command_queue queue, const char *type, cl_ulong *size, cl_device_id device )
@@ -161,12 +163,16 @@ REGISTER_TEST(sizeof)
return err;
if( test != scalar_table[i].size )
{
log_error( "\nFAILED: Type %s has size %lld, but expected size %lld!\n", scalar_table[i].name, test, scalar_table[i].size );
log_error("\nFAILED: Type %s has size %" PRId64
", but expected size %" PRId64 "!\n",
scalar_table[i].name, test, scalar_table[i].size);
return -1;
}
if( test != scalar_table[i].cl_size )
{
log_error( "\nFAILED: Type %s has size %lld, but cl_ size is %lld!\n", scalar_table[i].name, test, scalar_table[i].cl_size );
log_error("\nFAILED: Type %s has size %" PRId64
", but cl_ size is %" PRId64 "!\n",
scalar_table[i].name, test, scalar_table[i].cl_size);
return -2;
}
log_info( "%16s", scalar_table[i].name );
@@ -196,16 +202,16 @@ REGISTER_TEST(sizeof)
return err;
if( test != j * vector_table[i].size )
{
log_error(
"\nFAILED: Type %s has size %lld, but expected size %zu!\n",
name, test, j * vector_table[i].size);
log_error("\nFAILED: Type %s has size %" PRId64
", but expected size %" PRIu64 "!\n",
name, test, j * vector_table[i].size);
return -1;
}
if( test != j * vector_table[i].cl_size )
{
log_error(
"\nFAILED: Type %s has size %lld, but cl_ size is %zu!\n",
name, test, j * vector_table[i].cl_size);
log_error("\nFAILED: Type %s has size %" PRId64
", but cl_ size is %" PRIu64 "!\n",
name, test, j * vector_table[i].cl_size);
return -2;
}
log_info( "%16s", name );
@@ -222,7 +228,9 @@ REGISTER_TEST(sizeof)
return err;
if( test != ptr_size )
{
log_error( "\nFAILED: Type %s has size %lld, but expected size %u!\n", ptr_table[i], test, ptr_size );
log_error("\nFAILED: Type %s has size %" PRId64
", but expected size %u!\n",
ptr_table[i], test, ptr_size);
return -1;
}
log_info( "%16s", ptr_table[i] );
@@ -235,12 +243,16 @@ REGISTER_TEST(sizeof)
return err;
if( test < ptr_size )
{
log_error( "\nFAILED: intptr_t has size %lld, but must be at least %u!\n", test, ptr_size );
log_error("\nFAILED: intptr_t has size %" PRId64
", but must be at least %u!\n",
test, ptr_size);
return -1;
}
if( ! IsPowerOfTwo( test ) )
{
log_error( "\nFAILED: sizeof(intptr_t) is %lld, but must be a power of two!\n", test );
log_error("\nFAILED: sizeof(intptr_t) is %" PRId64
", but must be a power of two!\n",
test);
return -2;
}
log_info( "%16s", "intptr_t" );
@@ -252,12 +264,16 @@ REGISTER_TEST(sizeof)
return err;
if( test < ptr_size )
{
log_error( "\nFAILED: uintptr_t has size %lld, but must be at least %u!\n", test, ptr_size );
log_error("\nFAILED: uintptr_t has size %" PRId64
", but must be at least %u!\n",
test, ptr_size);
return -1;
}
if( ! IsPowerOfTwo( test ) )
{
log_error( "\nFAILED: sizeof(uintptr_t) is %lld, but must be a power of two!\n", test );
log_error("\nFAILED: sizeof(uintptr_t) is %" PRId64
", but must be a power of two!\n",
test);
return -2;
}
log_info( "%16s\n", "uintptr_t" );
@@ -293,7 +309,9 @@ REGISTER_TEST(sizeof)
return err;
if( ! IsPowerOfTwo( test ) )
{
log_error( "\nFAILED: Type %s has size %lld, which is not a power of two (section 6.1.5)!\n", other_types[i], test );
log_error("\nFAILED: Type %s has size %" PRId64
", which is not a power of two (section 6.1.5)!\n",
other_types[i], test);
return -1;
}
log_info( "%16s", other_types[i] );
@@ -311,7 +329,8 @@ REGISTER_TEST(sizeof)
return err;
if( test != 8 )
{
log_error( "\nFAILED: double has size %lld, but must be 8!\n", test );
log_error("\nFAILED: double has size %" PRId64 ", but must be 8!\n",
test);
return -1;
}
log_info( "%16s", "double" );
@@ -328,7 +347,8 @@ REGISTER_TEST(sizeof)
return err;
if( test != 8*j )
{
log_error("\nFAILED: %s has size %lld, but must be %zu!\n",
log_error("\nFAILED: %s has size %" PRId64
", but must be %zu!\n",
name, test, 8 * j);
return -1;
}
@@ -347,7 +367,8 @@ REGISTER_TEST(sizeof)
return err;
if( test != 2 )
{
log_error( "\nFAILED: half has size %lld, but must be 2!\n", test );
log_error("\nFAILED: half has size %" PRId64 ", but must be 2!\n",
test);
return -1;
}
log_info( "%16s", "half" );
@@ -364,7 +385,8 @@ REGISTER_TEST(sizeof)
return err;
if( test != 2*j )
{
log_error("\nFAILED: %s has size %lld, but must be %zu!\n",
log_error("\nFAILED: %s has size %" PRId64
", but must be %zu!\n",
name, test, 2 * j);
return -1;
}

View File

@@ -605,7 +605,7 @@ template <typename T, size_t N>
static int test_vectype(const char* type_name, cl_device_id device,
cl_context context, cl_command_queue queue)
{
log_info(" testing type %s%d\n", type_name, N);
log_info(" testing type %s%zu\n", type_name, N);
cl_int error = CL_SUCCESS;
int result = TEST_PASS;

View File

@@ -15,6 +15,7 @@
//
#include "harness/compat.h"
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -36,210 +37,246 @@ static int verify_copy_buffer(int *inptr, int *outptr, int n)
return 0;
}
using alignedOwningPtr = std::unique_ptr<cl_int[], decltype(&align_free)>;
static int test_copy( cl_command_queue queue, cl_context context, int num_elements, MTdata d )
{
cl_mem buffers[2];
cl_int *int_input_ptr, *int_output_ptr;
cl_int err;
int i;
int src_flag_id, dst_flag_id;
int errors = 0;
clMemWrapper buffers[2];
cl_int err = CL_SUCCESS;
size_t min_alignment = get_min_alignment(context);
int_input_ptr = (cl_int*) align_malloc(sizeof(cl_int) * num_elements, min_alignment);
int_output_ptr = (cl_int*)align_malloc(sizeof(cl_int) * num_elements, min_alignment);
alignedOwningPtr invalid_ptr{
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
align_free
};
if (!invalid_ptr)
{
log_error(" unable to allocate %zu bytes of memory\n",
sizeof(cl_int) * num_elements);
return TEST_FAIL;
}
alignedOwningPtr out_ptr{ (cl_int *)align_malloc(
sizeof(cl_int) * num_elements, min_alignment),
align_free };
if (!out_ptr)
{
log_error(" unable to allocate %zu bytes of memory\n",
sizeof(cl_int) * num_elements);
return TEST_FAIL;
}
alignedOwningPtr reference_ptr{
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
align_free
};
if (!reference_ptr)
{
log_error(" unable to allocate %zu bytes of memory\n",
sizeof(cl_int) * num_elements);
return TEST_FAIL;
}
for (src_flag_id=0; src_flag_id < NUM_FLAGS; src_flag_id++) {
for (dst_flag_id=0; dst_flag_id < NUM_FLAGS; dst_flag_id++) {
for (int src_flag_id = 0; src_flag_id < NUM_FLAGS; src_flag_id++)
{
for (int dst_flag_id = 0; dst_flag_id < NUM_FLAGS; dst_flag_id++)
{
log_info("Testing with cl_mem_flags src: %s dst: %s\n", flag_set_names[src_flag_id], flag_set_names[dst_flag_id]);
for (i=0; i<num_elements; i++){
int_input_ptr[i] = (int)genrand_int32( d );
int_output_ptr[i] = 0xdeaddead; // seed with incorrect data
for (int i = 0; i < num_elements; i++)
{
invalid_ptr[i] = static_cast<int>(0xdeaddead);
out_ptr[i] = static_cast<int>(0xdeadbeef);
reference_ptr[i] = (int)genrand_int32(d);
}
if ((flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR))
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, int_input_ptr, &err);
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
sizeof(cl_int) * num_elements,
reference_ptr.get(), &err);
else
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
sizeof(cl_int) * num_elements,
nullptr, &err);
if ( err != CL_SUCCESS ){
print_error(err, " clCreateBuffer failed\n" );
align_free( (void *)int_input_ptr );
align_free( (void *)int_output_ptr );
return -1;
print_error(err, "clCreateBuffer failed\n");
return TEST_FAIL;
}
if ((flag_set[dst_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[dst_flag_id] & CL_MEM_COPY_HOST_PTR))
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, int_output_ptr, &err);
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
sizeof(cl_int) * num_elements,
invalid_ptr.get(), &err);
else
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
sizeof(cl_int) * num_elements,
nullptr, &err);
if ( err != CL_SUCCESS ){
print_error(err, " clCreateBuffer failed\n" );
clReleaseMemObject( buffers[0] );
align_free( (void *)int_input_ptr );
align_free( (void *)int_output_ptr );
return -1;
print_error(err, "clCreateBuffer failed\n");
return TEST_FAIL;
}
if (!(flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) && !(flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR)) {
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0, sizeof(cl_int)*num_elements, (void *)int_input_ptr, 0, NULL, NULL);
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
reference_ptr.get(), 0, nullptr,
nullptr);
if ( err != CL_SUCCESS ){
print_error( err, "clEnqueueWriteBuffer failed" );
clReleaseMemObject( buffers[0] );
clReleaseMemObject( buffers[1] );
align_free( (void *)int_output_ptr );
align_free( (void *)int_input_ptr );
return -1;
print_error(err, "clEnqueueWriteBuffer failed\n");
return TEST_FAIL;
}
}
err = clEnqueueCopyBuffer(queue, buffers[0], buffers[1], 0, 0, sizeof(cl_int)*num_elements, 0, NULL, NULL);
err = clEnqueueCopyBuffer(queue, buffers[0], buffers[1], 0, 0,
sizeof(cl_int) * num_elements, 0, nullptr,
nullptr);
if ( err != CL_SUCCESS ){
print_error( err, "clCopyArray failed" );
clReleaseMemObject( buffers[0] );
clReleaseMemObject( buffers[1] );
align_free( (void *)int_output_ptr );
align_free( (void *)int_input_ptr );
return -1;
print_error(err, "clCopyArray failed\n");
return TEST_FAIL;
}
err = clEnqueueReadBuffer( queue, buffers[1], true, 0, sizeof(int)*num_elements, (void *)int_output_ptr, 0, NULL, NULL );
err = clEnqueueReadBuffer(queue, buffers[1], true, 0,
sizeof(int) * num_elements, out_ptr.get(),
0, nullptr, nullptr);
if ( err != CL_SUCCESS ){
print_error( err, "clEnqueueReadBuffer failed" );
clReleaseMemObject( buffers[0] );
clReleaseMemObject( buffers[1] );
align_free( (void *)int_output_ptr );
align_free( (void *)int_input_ptr );
return -1;
print_error(err, "clEnqueueReadBuffer failed\n");
return TEST_FAIL;
}
if ( verify_copy_buffer(int_input_ptr, int_output_ptr, num_elements) ){
if (verify_copy_buffer(reference_ptr.get(), out_ptr.get(),
num_elements))
{
log_error( " test failed\n" );
errors++;
return TEST_FAIL;
}
else{
log_info( " test passed\n" );
}
// cleanup
clReleaseMemObject( buffers[0] );
clReleaseMemObject( buffers[1] );
} // dst flags
} // src flags
// cleanup
align_free( (void *)int_output_ptr );
align_free( (void *)int_input_ptr );
} // src flags
return errors;
return TEST_PASS;
} // end test_copy()
static int testPartialCopy( cl_command_queue queue, cl_context context, int num_elements, cl_uint srcStart, cl_uint dstStart, int size, MTdata d )
{
cl_mem buffers[2];
int *inptr, *outptr;
cl_int err;
int i;
int src_flag_id, dst_flag_id;
int errors = 0;
clMemWrapper buffers[2];
cl_int err = CL_SUCCESS;
size_t min_alignment = get_min_alignment(context);
inptr = (int *)align_malloc( sizeof(int) * num_elements, min_alignment);
if ( ! inptr ){
log_error( " unable to allocate %d bytes of memory\n", (int)sizeof(int) * num_elements );
return -1;
alignedOwningPtr invalid_ptr{
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
align_free
};
if (!invalid_ptr)
{
log_error(" unable to allocate %zu bytes of memory\n",
sizeof(cl_int) * num_elements);
return TEST_FAIL;
}
outptr = (int *)align_malloc( sizeof(int) * num_elements, min_alignment);
if ( ! outptr ){
log_error( " unable to allocate %d bytes of memory\n", (int)sizeof(int) * num_elements );
align_free( (void *)inptr );
return -1;
alignedOwningPtr out_ptr{ (cl_int *)align_malloc(
sizeof(cl_int) * num_elements, min_alignment),
align_free };
if (!out_ptr)
{
log_error(" unable to allocate %zu bytes of memory\n",
sizeof(cl_int) * num_elements);
return TEST_FAIL;
}
alignedOwningPtr reference_ptr{
(cl_int *)align_malloc(sizeof(cl_int) * num_elements, min_alignment),
align_free
};
if (!reference_ptr)
{
log_error(" unable to allocate %zu bytes of memory\n",
sizeof(cl_int) * num_elements);
return TEST_FAIL;
}
for (src_flag_id=0; src_flag_id < NUM_FLAGS; src_flag_id++) {
for (dst_flag_id=0; dst_flag_id < NUM_FLAGS; dst_flag_id++) {
for (int src_flag_id = 0; src_flag_id < NUM_FLAGS; src_flag_id++)
{
for (int dst_flag_id = 0; dst_flag_id < NUM_FLAGS; dst_flag_id++)
{
log_info("Testing with cl_mem_flags src: %s dst: %s\n", flag_set_names[src_flag_id], flag_set_names[dst_flag_id]);
for (i=0; i<num_elements; i++){
inptr[i] = (int)genrand_int32( d );
outptr[i] = (int)0xdeaddead; // seed with incorrect data
for (int i = 0; i < num_elements; i++)
{
invalid_ptr[i] = static_cast<int>(0xdeaddead);
out_ptr[i] = static_cast<int>(0xdeadbeef);
reference_ptr[i] = (int)genrand_int32(d);
}
if ((flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR))
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, inptr, &err);
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
sizeof(cl_int) * num_elements,
reference_ptr.get(), &err);
else
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
buffers[0] = clCreateBuffer(context, flag_set[src_flag_id],
sizeof(cl_int) * num_elements,
nullptr, &err);
if ( err != CL_SUCCESS ){
print_error(err, " clCreateBuffer failed\n" )
align_free( (void *)outptr );
align_free( (void *)inptr );
return -1;
print_error(err, "clCreateBuffer failed\n");
return TEST_FAIL;
}
if ((flag_set[dst_flag_id] & CL_MEM_USE_HOST_PTR) || (flag_set[dst_flag_id] & CL_MEM_COPY_HOST_PTR))
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, outptr, &err);
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
sizeof(cl_int) * num_elements,
invalid_ptr.get(), &err);
else
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id], sizeof(cl_int) * num_elements, NULL, &err);
buffers[1] = clCreateBuffer(context, flag_set[dst_flag_id],
sizeof(cl_int) * num_elements,
nullptr, &err);
if ( err != CL_SUCCESS ){
print_error(err, " clCreateBuffer failed\n" );
clReleaseMemObject( buffers[0] );
align_free( (void *)outptr );
align_free( (void *)inptr );
return -1;
print_error(err, "clCreateBuffer failed\n");
return TEST_FAIL;
}
if (!(flag_set[src_flag_id] & CL_MEM_USE_HOST_PTR) && !(flag_set[src_flag_id] & CL_MEM_COPY_HOST_PTR)){
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0, sizeof(cl_int)*num_elements, (void *)inptr, 0, NULL, NULL);
err = clEnqueueWriteBuffer(queue, buffers[0], CL_TRUE, 0,
sizeof(cl_int) * num_elements,
reference_ptr.get(), 0, nullptr,
nullptr);
if ( err != CL_SUCCESS ){
print_error( err, "clEnqueueWriteBuffer failed" );
clReleaseMemObject( buffers[1] );
clReleaseMemObject( buffers[0] );
align_free( (void *)outptr );
align_free( (void *)inptr );
return -1;
print_error(err, "clEnqueueWriteBuffer failed\n");
return TEST_FAIL;
}
}
err = clEnqueueCopyBuffer(queue, buffers[0], buffers[1], srcStart*sizeof(cl_int), dstStart*sizeof(cl_int), sizeof(cl_int)*size, 0, NULL, NULL);
err = clEnqueueCopyBuffer(
queue, buffers[0], buffers[1], srcStart * sizeof(cl_int),
dstStart * sizeof(cl_int), sizeof(cl_int) * size, 0, nullptr,
nullptr);
if ( err != CL_SUCCESS){
print_error( err, "clEnqueueCopyBuffer failed" );
clReleaseMemObject( buffers[1] );
clReleaseMemObject( buffers[0] );
align_free( (void *)outptr );
align_free( (void *)inptr );
return -1;
print_error(err, "clEnqueueCopyBuffer failed\n");
return TEST_FAIL;
}
err = clEnqueueReadBuffer( queue, buffers[1], true, 0, sizeof(int)*num_elements, (void *)outptr, 0, NULL, NULL );
err = clEnqueueReadBuffer(queue, buffers[1], true, 0,
sizeof(int) * num_elements, out_ptr.get(),
0, nullptr, nullptr);
if ( err != CL_SUCCESS){
print_error( err, "clEnqueueReadBuffer failed" );
clReleaseMemObject( buffers[1] );
clReleaseMemObject( buffers[0] );
align_free( (void *)outptr );
align_free( (void *)inptr );
return -1;
print_error(err, "clEnqueueReadBuffer failed\n");
return TEST_FAIL;
}
if ( verify_copy_buffer(inptr + srcStart, outptr + dstStart, size) ){
if (verify_copy_buffer(reference_ptr.get() + srcStart,
out_ptr.get() + dstStart, size))
{
log_error("buffer_COPY test failed\n");
errors++;
return TEST_FAIL;
}
else{
log_info("buffer_COPY test passed\n");
}
// cleanup
clReleaseMemObject( buffers[1] );
clReleaseMemObject( buffers[0] );
} // dst mem flags
} // src mem flags
// cleanup
align_free( (void *)outptr );
align_free( (void *)inptr );
return errors;
return TEST_PASS;
} // end testPartialCopy()
@@ -252,15 +289,19 @@ REGISTER_TEST(buffer_copy)
// test the preset size
log_info( "set size: %d: ", num_elements );
if (test_copy( queue, context, num_elements, d ))
if (test_copy(queue, context, num_elements, d) != TEST_PASS)
{
err++;
}
// now test random sizes
for ( i = 0; i < 8; i++ ){
size = (int)get_random_float(2.f,131072.f, d);
log_info( "random size: %d: ", size );
if (test_copy( queue, context, size, d ))
if (test_copy(queue, context, size, d) != TEST_PASS)
{
err++;
}
}
free_mtdata(d);
@@ -283,8 +324,12 @@ REGISTER_TEST(buffer_partial_copy)
size = (int)get_random_float( 8.f, (float)(num_elements - srcStart), d );
dstStart = (cl_uint)get_random_float( 0.f, (float)(num_elements - size), d );
log_info( "random partial copy from %d to %d, size: %d: ", (int)srcStart, (int)dstStart, size );
if (testPartialCopy( queue, context, num_elements, srcStart, dstStart, size, d ))
if (testPartialCopy(queue, context, num_elements, srcStart, dstStart,
size, d)
!= TEST_PASS)
{
err++;
}
}
free_mtdata(d);

View File

@@ -58,30 +58,28 @@ cl_uint AtomicTypeInfo::Size(cl_device_id device)
{
switch(_type)
{
case TYPE_ATOMIC_INT:
case TYPE_ATOMIC_UINT:
case TYPE_ATOMIC_FLOAT:
case TYPE_ATOMIC_FLAG:
return sizeof(cl_int);
case TYPE_ATOMIC_LONG:
case TYPE_ATOMIC_ULONG:
case TYPE_ATOMIC_DOUBLE:
return sizeof(cl_long);
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
case TYPE_ATOMIC_SIZE_T:
case TYPE_ATOMIC_PTRDIFF_T:
{
int error;
cl_uint addressBits = 0;
case TYPE_ATOMIC_HALF: return sizeof(cl_half);
case TYPE_ATOMIC_INT:
case TYPE_ATOMIC_UINT:
case TYPE_ATOMIC_FLOAT:
case TYPE_ATOMIC_FLAG: return sizeof(cl_int);
case TYPE_ATOMIC_LONG:
case TYPE_ATOMIC_ULONG:
case TYPE_ATOMIC_DOUBLE: return sizeof(cl_long);
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
case TYPE_ATOMIC_SIZE_T:
case TYPE_ATOMIC_PTRDIFF_T: {
int error;
cl_uint addressBits = 0;
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(addressBits), &addressBits, 0);
test_error_ret(error, "clGetDeviceInfo", 0);
error = clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS,
sizeof(addressBits), &addressBits, 0);
test_error_ret(error, "clGetDeviceInfo", 0);
return addressBits/8;
}
default:
return 0;
return addressBits / 8;
}
default: return 0;
}
}
@@ -93,6 +91,7 @@ const char *AtomicTypeInfo::AtomicTypeName()
return "atomic_int";
case TYPE_ATOMIC_UINT:
return "atomic_uint";
case TYPE_ATOMIC_HALF: return "atomic_half";
case TYPE_ATOMIC_FLOAT:
return "atomic_float";
case TYPE_ATOMIC_FLAG:
@@ -124,6 +123,7 @@ const char *AtomicTypeInfo::RegularTypeName()
return "int";
case TYPE_ATOMIC_UINT:
return "uint";
case TYPE_ATOMIC_HALF: return "half";
case TYPE_ATOMIC_FLOAT:
return "float";
case TYPE_ATOMIC_FLAG:
@@ -163,29 +163,30 @@ int AtomicTypeInfo::IsSupported(cl_device_id device)
{
switch(_type)
{
case TYPE_ATOMIC_INT:
case TYPE_ATOMIC_UINT:
case TYPE_ATOMIC_FLOAT:
case TYPE_ATOMIC_FLAG:
return 1;
case TYPE_ATOMIC_LONG:
case TYPE_ATOMIC_ULONG:
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
is_extension_available(device, "cl_khr_int64_extended_atomics");
case TYPE_ATOMIC_DOUBLE:
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
is_extension_available(device, "cl_khr_int64_extended_atomics") &&
is_extension_available(device, "cl_khr_fp64");
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
case TYPE_ATOMIC_SIZE_T:
case TYPE_ATOMIC_PTRDIFF_T:
if(Size(device) == 4)
return 1;
return is_extension_available(device, "cl_khr_int64_base_atomics") &&
is_extension_available(device, "cl_khr_int64_extended_atomics");
default:
return 0;
case TYPE_ATOMIC_HALF:
return is_extension_available(device, "cl_khr_fp16");
case TYPE_ATOMIC_INT:
case TYPE_ATOMIC_UINT:
case TYPE_ATOMIC_FLOAT:
case TYPE_ATOMIC_FLAG: return 1;
case TYPE_ATOMIC_LONG:
case TYPE_ATOMIC_ULONG:
return is_extension_available(device, "cl_khr_int64_base_atomics")
&& is_extension_available(device,
"cl_khr_int64_extended_atomics");
case TYPE_ATOMIC_DOUBLE:
return is_extension_available(device, "cl_khr_int64_base_atomics")
&& is_extension_available(device, "cl_khr_int64_extended_atomics")
&& is_extension_available(device, "cl_khr_fp64");
case TYPE_ATOMIC_INTPTR_T:
case TYPE_ATOMIC_UINTPTR_T:
case TYPE_ATOMIC_SIZE_T:
case TYPE_ATOMIC_PTRDIFF_T:
if (Size(device) == 4) return 1;
return is_extension_available(device, "cl_khr_int64_base_atomics")
&& is_extension_available(device,
"cl_khr_int64_extended_atomics");
default: return 0;
}
}

View File

@@ -22,6 +22,8 @@
#include "host_atomics.h"
#include "CL/cl_half.h"
#include <vector>
#include <sstream>
@@ -38,6 +40,7 @@ enum TExplicitAtomicType
TYPE_ATOMIC_UINT,
TYPE_ATOMIC_LONG,
TYPE_ATOMIC_ULONG,
TYPE_ATOMIC_HALF,
TYPE_ATOMIC_FLOAT,
TYPE_ATOMIC_DOUBLE,
TYPE_ATOMIC_INTPTR_T,
@@ -71,6 +74,9 @@ extern int
gMaxDeviceThreads; // maximum number of threads executed on OCL device
extern cl_device_atomic_capabilities gAtomicMemCap,
gAtomicFenceCap; // atomic memory and fence capabilities for this device
extern cl_half_rounding_mode gHalfRoundingMode;
extern bool gFloatAtomicsSupported;
extern cl_device_fp_atomic_capabilities_ext gHalfAtomicCaps;
extern const char *
get_memory_order_type_name(TExplicitMemoryOrderType orderType);
@@ -240,13 +246,13 @@ public:
int error = 0;
if (_maxDeviceThreads > 0 && !UseSVM())
{
LocalMemory(true);
SetLocalMemory(true);
EXECUTE_TEST(
error, ExecuteForEachDeclarationType(deviceID, context, queue));
}
if (_maxDeviceThreads + MaxHostThreads() > 0)
{
LocalMemory(false);
SetLocalMemory(false);
EXECUTE_TEST(
error, ExecuteForEachDeclarationType(deviceID, context, queue));
}
@@ -401,7 +407,7 @@ public:
bool UseSVM() { return _useSVM; }
void StartValue(HostDataType startValue) { _startValue = startValue; }
HostDataType StartValue() { return _startValue; }
void LocalMemory(bool local) { _localMemory = local; }
void SetLocalMemory(bool local) { _localMemory = local; }
bool LocalMemory() { return _localMemory; }
void DeclaredInProgram(bool declaredInProgram)
{
@@ -781,6 +787,8 @@ CBasicTest<HostAtomicType, HostDataType>::PragmaHeader(cl_device_id deviceID)
}
if (_dataType == TYPE_ATOMIC_DOUBLE)
pragma += "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
if (_dataType == TYPE_ATOMIC_HALF)
pragma += "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
return pragma;
}
@@ -875,7 +883,14 @@ CBasicTest<HostAtomicType, HostDataType>::ProgramHeader(cl_uint maxNumDestItems)
header += std::string("__global volatile ") + aTypeName + " destMemory["
+ ss.str() + "] = {\n";
ss.str("");
ss << _startValue;
if (CBasicTest<HostAtomicType, HostDataType>::DataType()._type
!= TYPE_ATOMIC_HALF)
ss << _startValue;
else
ss << static_cast<HostDataType>(
cl_half_to_float(static_cast<cl_half>(_startValue)));
for (cl_uint i = 0; i < maxNumDestItems; i++)
{
if (aTypeName == "atomic_flag")

View File

@@ -41,6 +41,7 @@ enum TExplicitMemoryOrderType
#define HOST_ATOMIC_UINT unsigned long
#define HOST_ATOMIC_LONG unsigned long long
#define HOST_ATOMIC_ULONG unsigned long long
#define HOST_ATOMIC_HALF unsigned short
#define HOST_ATOMIC_FLOAT float
#define HOST_ATOMIC_DOUBLE double
#else
@@ -48,6 +49,7 @@ enum TExplicitMemoryOrderType
#define HOST_ATOMIC_UINT cl_uint
#define HOST_ATOMIC_LONG cl_long
#define HOST_ATOMIC_ULONG cl_ulong
#define HOST_ATOMIC_HALF cl_half
#define HOST_ATOMIC_FLOAT cl_float
#define HOST_ATOMIC_DOUBLE cl_double
#endif
@@ -69,6 +71,7 @@ enum TExplicitMemoryOrderType
#define HOST_UINT cl_uint
#define HOST_LONG cl_long
#define HOST_ULONG cl_ulong
#define HOST_HALF cl_half
#define HOST_FLOAT cl_float
#define HOST_DOUBLE cl_double
@@ -120,9 +123,12 @@ CorrespondingType host_atomic_exchange(volatile AtomicType *a, CorrespondingType
TExplicitMemoryOrderType order)
{
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
return InterlockedExchange(a, c);
if (sizeof(CorrespondingType) == 2)
return InterlockedExchange16(reinterpret_cast<volatile SHORT *>(a), c);
else
return InterlockedExchange(reinterpret_cast<volatile LONG *>(a), c);
#elif defined(__GNUC__)
return __sync_lock_test_and_set(a, c);
return __sync_lock_test_and_set(a, c);
#else
log_info("Host function not implemented: atomic_exchange\n");
return 0;
@@ -158,7 +164,10 @@ CorrespondingType host_atomic_load(volatile AtomicType *a,
TExplicitMemoryOrderType order)
{
#if defined( _MSC_VER ) || (defined( __INTEL_COMPILER ) && defined(WIN32))
return InterlockedExchangeAdd(a, 0);
if (sizeof(CorrespondingType) == 2)
auto prev = InterlockedOr16(reinterpret_cast<volatile SHORT *>(a), 0);
else
return InterlockedExchangeAdd(reinterpret_cast<volatile LONG *>(a), 0);
#elif defined(__GNUC__)
return __sync_add_and_fetch(a, 0);
#else

View File

@@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2024 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,8 +14,11 @@
// limitations under the License.
//
#include "harness/testHarness.h"
#include "harness/deviceInfo.h"
#include "harness/kernelHelpers.h"
#include <iostream>
#include <string>
#include "CL/cl_half.h"
bool gHost = false; // flag for testing native host threads (test verification)
bool gOldAPI = false; // flag for testing with old API (OpenCL 1.2) - test verification
@@ -28,6 +31,9 @@ int gInternalIterations = 10000; // internal test iterations for atomic operatio
int gMaxDeviceThreads = 1024; // maximum number of threads executed on OCL device
cl_device_atomic_capabilities gAtomicMemCap,
gAtomicFenceCap; // atomic memory and fence capabilities for this device
cl_half_rounding_mode gHalfRoundingMode = CL_HALF_RTE;
bool gFloatAtomicsSupported = false;
cl_device_fp_atomic_capabilities_ext gHalfAtomicCaps = 0;
test_status InitCL(cl_device_id device) {
auto version = get_device_cl_version(device);
@@ -123,6 +129,34 @@ test_status InitCL(cl_device_id device) {
| CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES;
}
if (is_extension_available(device, "cl_ext_float_atomics"))
{
gFloatAtomicsSupported = true;
if (is_extension_available(device, "cl_khr_fp16"))
{
cl_int error = clGetDeviceInfo(
device, CL_DEVICE_HALF_FP_ATOMIC_CAPABILITIES_EXT,
sizeof(gHalfAtomicCaps), &gHalfAtomicCaps, nullptr);
test_error_ret(error, "clGetDeviceInfo failed!", TEST_FAIL);
const cl_device_fp_config fpConfigHalf =
get_default_rounding_mode(device, CL_DEVICE_HALF_FP_CONFIG);
if ((fpConfigHalf & CL_FP_ROUND_TO_NEAREST) != 0)
{
gHalfRoundingMode = CL_HALF_RTE;
}
else if ((fpConfigHalf & CL_FP_ROUND_TO_ZERO) != 0)
{
gHalfRoundingMode = CL_HALF_RTZ;
}
else
{
log_error("Error while acquiring half rounding mode\n");
return TEST_FAIL;
}
}
}
return TEST_PASS;
}

View File

@@ -1,5 +1,5 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2024 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.
@@ -33,6 +33,7 @@ public:
using CBasicTestMemOrderScope<HostAtomicType,
HostDataType>::MemoryOrderScopeStr;
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::LocalMemory;
CBasicTestStore(TExplicitAtomicType dataType, bool useSVM)
: CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType,
useSVM)
@@ -54,6 +55,21 @@ public:
== TEST_SKIPPED_ITSELF)
return 0; // skip test - not applicable
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
._type
== TYPE_ATOMIC_HALF)
{
if (LocalMemory()
&& (gHalfAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT)
== 0)
return 0; // skip test - not applicable
if (!LocalMemory()
&& (gHalfAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT)
== 0)
return 0;
}
return CBasicTestMemOrderScope<
HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context,
queue);
@@ -75,7 +91,13 @@ public:
HostDataType *startRefValues,
cl_uint whichDestValue)
{
expected = (HostDataType)whichDestValue;
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
._type
!= TYPE_ATOMIC_HALF)
expected = (HostDataType)whichDestValue;
else
expected = cl_half_from_float(static_cast<float>(whichDestValue),
gHalfRoundingMode);
return true;
}
};
@@ -109,6 +131,15 @@ static int test_atomic_store_generic(cl_device_id deviceID, cl_context context,
TYPE_ATOMIC_DOUBLE, useSVM);
EXECUTE_TEST(error,
test_double.Execute(deviceID, context, queue, num_elements));
if (gFloatAtomicsSupported)
{
CBasicTestStore<HOST_ATOMIC_HALF, HOST_HALF> test_half(TYPE_ATOMIC_HALF,
useSVM);
EXECUTE_TEST(error,
test_half.Execute(deviceID, context, queue, num_elements));
}
if (AtomicTypeInfo(TYPE_ATOMIC_SIZE_T).Size(deviceID) == 4)
{
CBasicTestStore<HOST_ATOMIC_INTPTR_T32, HOST_INTPTR_T32> test_intptr_t(
@@ -297,6 +328,7 @@ public:
HostDataType>::MemoryOrderScopeStr;
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::MemoryScopeStr;
using CBasicTest<HostAtomicType, HostDataType>::CheckCapabilities;
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::LocalMemory;
CBasicTestLoad(TExplicitAtomicType dataType, bool useSVM)
: CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType,
useSVM)
@@ -318,6 +350,21 @@ public:
== TEST_SKIPPED_ITSELF)
return 0; // skip test - not applicable
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
._type
== TYPE_ATOMIC_HALF)
{
if (LocalMemory()
&& (gHalfAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT)
== 0)
return 0; // skip test - not applicable
if (!LocalMemory()
&& (gHalfAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT)
== 0)
return 0;
}
return CBasicTestMemOrderScope<
HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context,
queue);
@@ -351,7 +398,13 @@ public:
HostDataType *startRefValues,
cl_uint whichDestValue)
{
expected = (HostDataType)whichDestValue;
if (CBasicTestMemOrderScope<HostAtomicType, HostDataType>::DataType()
._type
!= TYPE_ATOMIC_HALF)
expected = (HostDataType)whichDestValue;
else
expected = cl_half_from_float(static_cast<float>(whichDestValue),
gHalfRoundingMode);
return true;
}
virtual bool VerifyRefs(bool &correct, cl_uint threadCount,
@@ -361,11 +414,25 @@ public:
correct = true;
for (cl_uint i = 0; i < threadCount; i++)
{
if (refValues[i] != (HostDataType)i)
if constexpr (std::is_same<HostDataType, cl_half>::value)
{
log_error("Invalid value for thread %u\n", (cl_uint)i);
correct = false;
return true;
HostDataType test = cl_half_from_float(static_cast<float>(i),
gHalfRoundingMode);
if (refValues[i] != test)
{
log_error("Invalid value for thread %u\n", (cl_uint)i);
correct = false;
return true;
}
}
else
{
if (refValues[i] != (HostDataType)i)
{
log_error("Invalid value for thread %u\n", (cl_uint)i);
correct = false;
return true;
}
}
}
return true;
@@ -400,6 +467,15 @@ static int test_atomic_load_generic(cl_device_id deviceID, cl_context context,
TYPE_ATOMIC_DOUBLE, useSVM);
EXECUTE_TEST(error,
test_double.Execute(deviceID, context, queue, num_elements));
if (gFloatAtomicsSupported)
{
CBasicTestLoad<HOST_ATOMIC_HALF, HOST_HALF> test_half(TYPE_ATOMIC_HALF,
useSVM);
EXECUTE_TEST(error,
test_half.Execute(deviceID, context, queue, num_elements));
}
if (AtomicTypeInfo(TYPE_ATOMIC_SIZE_T).Size(deviceID) == 4)
{
CBasicTestLoad<HOST_ATOMIC_INTPTR_T32, HOST_INTPTR_T32> test_intptr_t(
@@ -469,11 +545,36 @@ public:
HostDataType>::MemoryOrderScopeStr;
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::Iterations;
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::IterationsStr;
using CBasicTestMemOrderScope<HostAtomicType, HostDataType>::LocalMemory;
CBasicTestExchange(TExplicitAtomicType dataType, bool useSVM)
: CBasicTestMemOrderScope<HostAtomicType, HostDataType>(dataType,
useSVM)
{
StartValue(123456);
if constexpr (std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
StartValue(cl_half_from_float(static_cast<float>(1234),
gHalfRoundingMode));
else
StartValue(123456);
}
virtual int ExecuteSingleTest(cl_device_id deviceID, cl_context context,
cl_command_queue queue)
{
if constexpr (std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
{
if (LocalMemory()
&& (gHalfAtomicCaps & CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT)
== 0)
return 0; // skip test - not applicable
if (!LocalMemory()
&& (gHalfAtomicCaps & CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT)
== 0)
return 0;
}
return CBasicTestMemOrderScope<
HostAtomicType, HostDataType>::ExecuteSingleTest(deviceID, context,
queue);
}
virtual std::string ProgramCore()
{
@@ -515,17 +616,35 @@ public:
/* Any repeated value is treated as an error */
std::vector<bool> tidFound(threadCount);
bool startValueFound = false;
cl_uint i;
cl_uint startVal = StartValue();
for (i = 0; i <= threadCount; i++)
if constexpr (std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
startVal = static_cast<cl_uint>(
cl_half_to_float(static_cast<cl_half>(StartValue())));
for (cl_uint i = 0; i <= threadCount; i++)
{
cl_uint value;
cl_uint value = 0;
if (i == threadCount)
value = (cl_uint)finalValues[0]; // additional value from atomic
{
if constexpr (!std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
value =
(cl_uint)finalValues[0]; // additional value from atomic
// variable (last written)
else
value =
cl_half_to_float(static_cast<cl_half>(finalValues[0]));
}
else
value = (cl_uint)refValues[i];
if (value == (cl_uint)StartValue())
{
if constexpr (!std::is_same_v<HostDataType, HOST_ATOMIC_HALF>)
value = (cl_uint)refValues[i];
else
value =
cl_half_to_float(static_cast<cl_half>(refValues[i]));
}
if (value == startVal)
{
// Special initial value
if (startValueFound)
@@ -590,6 +709,13 @@ static int test_atomic_exchange_generic(cl_device_id deviceID,
TYPE_ATOMIC_DOUBLE, useSVM);
EXECUTE_TEST(error,
test_double.Execute(deviceID, context, queue, num_elements));
if (gFloatAtomicsSupported)
{
CBasicTestExchange<HOST_ATOMIC_HALF, HOST_HALF> test_half(
TYPE_ATOMIC_HALF, useSVM);
EXECUTE_TEST(error,
test_half.Execute(deviceID, context, queue, num_elements));
}
if (AtomicTypeInfo(TYPE_ATOMIC_SIZE_T).Size(deviceID) == 4)
{
CBasicTestExchange<HOST_ATOMIC_INTPTR_T32, HOST_INTPTR_T32>

View File

@@ -6,6 +6,7 @@ set(VULKAN_WRAPPER_SOURCES
)
# needed by Vulkan wrapper to compile
set(CMAKE_COMPILE_WARNING_AS_ERROR OFF)
add_cxx_flag_if_supported(-Wmisleading-indentation)
add_cxx_flag_if_supported(-Wno-narrowing)
add_cxx_flag_if_supported(-Wno-format)

View File

@@ -428,38 +428,68 @@ size_t GetElementNBytes(const cl_image_format *format)
return result;
}
cl_int get2DImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
cl_image_format *img_fmt, size_t totalImageSize,
size_t &width, size_t &height)
cl_int getImageDimensions(const VkImageCreateInfo *VulkanImageCreateInfo,
cl_image_format *img_fmt, cl_image_desc *img_desc,
VkExtent3D max_ext, const VkSubresourceLayout *layout)
{
cl_int result = CL_SUCCESS;
if (totalImageSize == 0)
test_assert_error(
VulkanImageCreateInfo != nullptr,
"getImageDimensions: invalid VulkanImageCreateInfo pointer!");
test_assert_error(img_fmt != nullptr,
"getImageDimensions: invalid img_fmt pointer!");
test_assert_error(img_desc != nullptr,
"getImageDimensions: invalid img_desc pointer!");
img_desc->image_depth = VulkanImageCreateInfo->extent.depth;
img_desc->image_width = VulkanImageCreateInfo->extent.width;
img_desc->image_height = VulkanImageCreateInfo->extent.height;
if (layout != nullptr)
{
result = CL_INVALID_VALUE;
size_t element_size = GetElementNBytes(img_fmt);
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
row_pitch = row_pitch < layout->rowPitch ? layout->rowPitch : row_pitch;
img_desc->image_row_pitch = row_pitch;
size_t slice_pitch = row_pitch * VulkanImageCreateInfo->extent.height;
slice_pitch =
slice_pitch < layout->depthPitch ? layout->depthPitch : slice_pitch;
img_desc->image_slice_pitch = slice_pitch;
}
size_t element_size = GetElementNBytes(img_fmt);
size_t row_pitch = element_size * VulkanImageCreateInfo->extent.width;
row_pitch = row_pitch % 64 == 0 ? row_pitch : ((row_pitch / 64) + 1) * 64;
width = row_pitch / element_size;
height = totalImageSize / row_pitch;
switch (img_desc->image_type)
{
case CL_MEM_OBJECT_IMAGE3D:
test_assert_error(img_desc->image_depth >= 1
&& img_desc->image_depth <= max_ext.depth,
"getImageDimensions: invalid image depth!");
case CL_MEM_OBJECT_IMAGE2D:
test_assert_error(img_desc->image_height >= 1
&& img_desc->image_height <= max_ext.height,
"getImageDimensions: invalid image height!");
case CL_MEM_OBJECT_IMAGE1D:
test_assert_error(img_desc->image_width >= 1
&& img_desc->image_width <= max_ext.width,
"getImageDimensions: invalid image width!");
}
return result;
return CL_SUCCESS;
}
cl_int
getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
size_t totalImageSize, cl_image_format *img_fmt,
cl_image_desc *img_desc)
getCLImageInfoFromVkImageInfo(const cl_device_id device,
const VkImageCreateInfo *VulkanImageCreateInfo,
cl_image_format *img_fmt, cl_image_desc *img_desc,
const VkSubresourceLayout *layout)
{
cl_int result = CL_SUCCESS;
cl_int error = CL_SUCCESS;
cl_image_format clImgFormat = { 0 };
result =
error =
getCLFormatFromVkFormat(VulkanImageCreateInfo->format, &clImgFormat);
if (CL_SUCCESS != result)
if (CL_SUCCESS != error)
{
return result;
return error;
}
memcpy(img_fmt, &clImgFormat, sizeof(cl_image_format));
@@ -469,25 +499,57 @@ getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *VulkanImageCreateInfo,
return CL_INVALID_VALUE;
}
result =
get2DImageDimensions(VulkanImageCreateInfo, img_fmt, totalImageSize,
img_desc->image_width, img_desc->image_height);
if (CL_SUCCESS != result)
VkExtent3D max_ext = { 0, 0, 0 };
size_t width = 0, height = 0, depth = 0;
if (img_desc->image_type == CL_MEM_OBJECT_IMAGE3D)
{
throw std::runtime_error("get2DImageDimensions failed!!!");
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH,
sizeof(width), &width, NULL);
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_WIDTH");
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT,
sizeof(height), &height, NULL);
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_HEIGHT");
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH,
sizeof(depth), &depth, NULL);
test_error(error, "Unable to get CL_DEVICE_IMAGE3D_MAX_DEPTH");
}
else
{
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH,
sizeof(width), &width, NULL);
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_WIDTH");
error = clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT,
sizeof(height), &height, NULL);
test_error(error, "Unable to get CL_DEVICE_IMAGE2D_MAX_HEIGHT");
}
max_ext.depth = depth;
max_ext.height = height;
max_ext.width = width;
// If image_row_pitch is zero and the image is created from an external
// memory handle, then the image row pitch is implementation-defined
img_desc->image_row_pitch = 0;
// If image_slice_pitch is zero and the image is created from an external
// memory handle, then the image slice pitch is implementation-defined
img_desc->image_slice_pitch = 0;
error = getImageDimensions(VulkanImageCreateInfo, img_fmt, img_desc,
max_ext, layout);
if (CL_SUCCESS != error)
{
throw std::runtime_error("getImageDimensions failed!!!");
}
img_desc->image_depth =
static_cast<size_t>(VulkanImageCreateInfo->extent.depth);
img_desc->image_array_size = 0;
img_desc->image_row_pitch = 0; // Row pitch set to zero as host_ptr is NULL
img_desc->image_slice_pitch =
img_desc->image_row_pitch * img_desc->image_height;
img_desc->num_mip_levels = 0;
img_desc->num_samples = 0;
img_desc->buffer = NULL;
return result;
return error;
}
cl_int check_external_memory_handle_type(
@@ -529,8 +591,8 @@ cl_int check_external_memory_handle_type(
return CL_INVALID_VALUE;
}
cl_int check_external_semaphore_handle_type(
cl_device_id deviceID,
void check_external_semaphore_handle_type(
cl_device_id device,
cl_external_semaphore_handle_type_khr requiredHandleType,
cl_device_info queryParamName)
{
@@ -540,8 +602,8 @@ cl_int check_external_semaphore_handle_type(
cl_int errNum = CL_SUCCESS;
errNum =
clGetDeviceInfo(deviceID, queryParamName, 0, NULL, &handle_type_size);
test_error(errNum, "clGetDeviceInfo failed");
clGetDeviceInfo(device, queryParamName, 0, NULL, &handle_type_size);
ASSERT_SUCCESS(errNum, "clGetDeviceInfo");
if (handle_type_size == 0)
{
@@ -549,31 +611,37 @@ cl_int check_external_semaphore_handle_type(
queryParamName == CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR
? "importing"
: "exporting");
return CL_INVALID_VALUE;
throw std::runtime_error("");
}
handle_type =
(cl_external_semaphore_handle_type_khr *)malloc(handle_type_size);
errNum = clGetDeviceInfo(deviceID, queryParamName, handle_type_size,
errNum = clGetDeviceInfo(device, queryParamName, handle_type_size,
handle_type, NULL);
ASSERT_SUCCESS(errNum, "clGetDeviceInfo");
test_error(
errNum,
"Unable to query supported device semaphore handle types list\n");
bool found = false;
for (i = 0; i < handle_type_size; i++)
{
if (requiredHandleType == handle_type[i])
{
return CL_SUCCESS;
found = true;
break;
}
}
log_error("cl_khr_external_semaphore extension is missing support for %d\n",
requiredHandleType);
return CL_INVALID_VALUE;
if (!found)
{
log_error("cl_khr_external_semaphore extension is missing support for "
"handle type %d\n",
requiredHandleType);
throw std::runtime_error("");
}
}
clExternalMemory::clExternalMemory() {}
clExternalMemory::clExternalMemory(const clExternalMemory &externalMemory)
@@ -705,13 +773,17 @@ clExternalMemoryImage::clExternalMemoryImage(
std::vector<cl_mem_properties> extMemProperties1;
cl_device_id devList[] = { deviceId, NULL };
VulkanImageTiling vulkanImageTiling =
vkClExternalMemoryHandleTilingAssumption(
deviceId, externalMemoryHandleType, &errcode_ret);
auto vulkanImageTiling = vkClExternalMemoryHandleTilingAssumption(
deviceId, externalMemoryHandleType, &errcode_ret);
if (CL_SUCCESS != errcode_ret)
{
throw std::runtime_error("Failed to query OpenCL tiling mode");
}
if (vulkanImageTiling == std::nullopt)
{
throw std::runtime_error(
"Could not find image tiling supported by both Vulkan and OpenCL");
}
#ifdef _WIN32
if (!is_extension_available(devList[0], "cl_khr_external_memory_win32"))
@@ -796,7 +868,7 @@ clExternalMemoryImage::clExternalMemoryImage(
image2D.getVkImageCreateInfo();
errcode_ret = getCLImageInfoFromVkImageInfo(
&VulkanImageCreateInfo, image2D.getSize(), &img_format, &image_desc);
deviceId, &VulkanImageCreateInfo, &img_format, &image_desc);
if (CL_SUCCESS != errcode_ret)
{
throw std::runtime_error("getCLImageInfoFromVkImageInfo failed\n");
@@ -855,9 +927,15 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
cl_device_id deviceId)
: m_deviceSemaphore(semaphore)
{
cl_int err = 0;
cl_device_id devList[] = { deviceId, NULL };
cl_external_semaphore_handle_type_khr clSemaphoreHandleType =
getCLSemaphoreTypeFromVulkanType(externalSemaphoreHandleType);
check_external_semaphore_handle_type(
deviceId, clSemaphoreHandleType,
CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR);
m_externalHandleType = externalSemaphoreHandleType;
m_externalSemaphore = nullptr;
m_device = deviceId;
@@ -875,8 +953,6 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
ASSERT(0);
#else
fd = (int)semaphore.getHandle(externalSemaphoreHandleType);
err = check_external_semaphore_handle_type(
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
sema_props.push_back(
(cl_semaphore_properties_khr)CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR);
sema_props.push_back((cl_semaphore_properties_khr)fd);
@@ -888,8 +964,6 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
ASSERT(0);
#else
handle = semaphore.getHandle(externalSemaphoreHandleType);
err = check_external_semaphore_handle_type(
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
sema_props.push_back((cl_semaphore_properties_khr)
CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR);
sema_props.push_back((cl_semaphore_properties_khr)handle);
@@ -903,8 +977,6 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
const std::wstring &name = semaphore.getName();
if (name.size())
{
err = check_external_semaphore_handle_type(
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_NAME_KHR);
sema_props.push_back(
(cl_semaphore_properties_khr)
CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_NAME_KHR);
@@ -924,21 +996,17 @@ clExternalImportableSemaphore::clExternalImportableSemaphore(
ASSERT(0);
#else
handle = semaphore.getHandle(externalSemaphoreHandleType);
err = check_external_semaphore_handle_type(
devList[0], CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
sema_props.push_back((cl_semaphore_properties_khr)
CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR);
sema_props.push_back((cl_semaphore_properties_khr)handle);
#endif
break;
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD:
err = check_external_semaphore_handle_type(
devList[0], CL_SEMAPHORE_HANDLE_SYNC_FD_KHR);
sema_props.push_back(static_cast<cl_semaphore_properties_khr>(
CL_SEMAPHORE_HANDLE_SYNC_FD_KHR));
sema_props.push_back(static_cast<cl_semaphore_properties_khr>(-1));
break;
default:
log_error("Unsupported external memory handle type\n");
ASSERT(0);
@@ -1013,11 +1081,15 @@ clExternalExportableSemaphore::clExternalExportableSemaphore(
cl_device_id deviceId)
: m_deviceSemaphore(semaphore)
{
cl_int err = 0;
cl_device_id devList[] = { deviceId, NULL };
cl_external_semaphore_handle_type_khr clSemaphoreHandleType =
getCLSemaphoreTypeFromVulkanType(externalSemaphoreHandleType);
check_external_semaphore_handle_type(
deviceId, clSemaphoreHandleType,
CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR);
m_externalHandleType = externalSemaphoreHandleType;
m_externalSemaphore = nullptr;
m_device = deviceId;
@@ -1191,6 +1263,10 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType(
{
switch (vkExternalMemoryHandleType)
{
default:
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE:
log_error("Unexpected external memory handle type\n");
return 0;
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD:
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR;
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT:
@@ -1198,17 +1274,17 @@ cl_external_memory_handle_type_khr vkToOpenCLExternalMemoryHandleType(
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT:
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_KMT:
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR;
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: return 0;
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_NT_NAME:
return CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_NAME_KHR;
}
return 0;
}
VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
std::optional<VulkanImageTiling> vkClExternalMemoryHandleTilingAssumption(
cl_device_id deviceId,
VulkanExternalMemoryHandleType vkExternalMemoryHandleType, int *error_ret)
{
size_t size = 0;
VulkanImageTiling mode = VULKAN_IMAGE_TILING_OPTIMAL;
assert(error_ret
!= nullptr); // errcode_ret is not optional, it must be checked
@@ -1219,12 +1295,12 @@ VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
0, nullptr, &size);
if (*error_ret != CL_SUCCESS)
{
return mode;
return std::nullopt;
}
if (size == 0)
{
return mode;
return std::nullopt;
}
std::vector<cl_external_memory_handle_type_khr> assume_linear_types(
@@ -1236,7 +1312,7 @@ VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
size, assume_linear_types.data(), nullptr);
if (*error_ret != CL_SUCCESS)
{
return mode;
return std::nullopt;
}
if (std::find(
@@ -1244,8 +1320,8 @@ VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
vkToOpenCLExternalMemoryHandleType(vkExternalMemoryHandleType))
!= assume_linear_types.end())
{
mode = VULKAN_IMAGE_TILING_LINEAR;
return VULKAN_IMAGE_TILING_LINEAR;
}
return mode;
return std::nullopt;
}

View File

@@ -26,22 +26,7 @@
#include <OpenCL/cl_ext.h>
#endif
#define CREATE_OPENCL_SEMAPHORE(clSemaphore, vkSemaphore, ctx, handleType, \
devIdx, createExportable) \
if (!(createExportable \
&& (check_external_semaphore_handle_type( \
devIdx, getCLSemaphoreTypeFromVulkanType(handleType), \
CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR) \
== CL_SUCCESS))) \
{ \
clSemaphore = new clExternalImportableSemaphore(vkSemaphore, ctx, \
handleType, devIdx); \
} \
else \
{ \
clSemaphore = new clExternalExportableSemaphore(vkSemaphore, ctx, \
handleType, devIdx); \
}
#include <optional>
typedef cl_semaphore_khr (*pfnclCreateSemaphoreWithPropertiesKHR)(
cl_context context, cl_semaphore_properties_khr *sema_props,
@@ -86,16 +71,17 @@ extern pfnclEnqueueReleaseExternalMemObjectsKHR
extern pfnclReleaseSemaphoreKHR clReleaseSemaphoreKHRptr;
extern pfnclReImportSemaphoreSyncFdKHR pfnclReImportSemaphoreSyncFdKHRptr;
cl_int getCLImageInfoFromVkImageInfo(const VkImageCreateInfo *, size_t,
cl_image_format *, cl_image_desc *);
cl_int
getCLImageInfoFromVkImageInfo(const cl_device_id, const VkImageCreateInfo *,
cl_image_format *, cl_image_desc *,
const VkSubresourceLayout *layout = nullptr);
cl_int check_external_memory_handle_type(
cl_device_id deviceID,
cl_external_memory_handle_type_khr requiredHandleType);
cl_int check_external_semaphore_handle_type(
cl_device_id deviceID,
void check_external_semaphore_handle_type(
cl_device_id device,
cl_external_semaphore_handle_type_khr requiredHandleType,
cl_device_info queryParamName =
CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR);
cl_device_info queryParamName);
cl_int setMaxImageDimensions(cl_device_id deviceID, size_t &width,
size_t &height);
@@ -187,8 +173,8 @@ public:
extern void init_cl_vk_ext(cl_platform_id, cl_uint num_devices,
cl_device_id *deviceIds);
VulkanImageTiling vkClExternalMemoryHandleTilingAssumption(
std::optional<VulkanImageTiling> vkClExternalMemoryHandleTilingAssumption(
cl_device_id deviceId,
VulkanExternalMemoryHandleType vkExternalMemoryHandleType, int *error_ret);
#endif // _opencl_vulkan_wrapper_hpp_
#endif // _opencl_vulkan_wrapper_hpp_

View File

@@ -102,6 +102,8 @@
VK_FUNC_DECL(vkImportSemaphoreFdKHR) \
VK_FUNC_DECL(vkGetPhysicalDeviceExternalSemaphorePropertiesKHR) \
VK_FUNC_DECL(vkGetImageSubresourceLayout) \
VK_FUNC_DECL(vkCreateDebugUtilsMessengerEXT) \
VK_FUNC_DECL(vkDestroyDebugUtilsMessengerEXT) \
VK_FUNC_DECL(vkGetPhysicalDeviceExternalBufferProperties)
#define VK_WINDOWS_FUNC_LIST \
VK_FUNC_DECL(vkGetMemoryWin32HandleKHR) \
@@ -203,6 +205,8 @@
#define vkGetSemaphoreWin32HandleKHR _vkGetSemaphoreWin32HandleKHR
#define vkImportSemaphoreWin32HandleKHR _vkImportSemaphoreWin32HandleKHR
#define vkGetImageSubresourceLayout _vkGetImageSubresourceLayout
#define vkCreateDebugUtilsMessengerEXT _vkCreateDebugUtilsMessengerEXT
#define vkDestroyDebugUtilsMessengerEXT _vkDestroyDebugUtilsMessengerEXT
#define vkGetPhysicalDeviceExternalBufferProperties \
_vkGetPhysicalDeviceExternalBufferProperties

View File

@@ -32,13 +32,13 @@
#define BUFFERSIZE 3000
const VulkanInstance &getVulkanInstance()
const VulkanInstance &getVulkanInstance(bool useValidationLayers)
{
static VulkanInstance instance;
static VulkanInstance instance(useValidationLayers);
return instance;
}
const VulkanPhysicalDevice &getVulkanPhysicalDevice()
const VulkanPhysicalDevice &getVulkanPhysicalDevice(bool useValidationLayers)
{
size_t pdIdx = 0;
cl_int errNum = 0;
@@ -47,7 +47,7 @@ const VulkanPhysicalDevice &getVulkanPhysicalDevice()
cl_uint num_devices = 0;
cl_uint device_no = 0;
const size_t bufsize = BUFFERSIZE;
const VulkanInstance &instance = getVulkanInstance();
const VulkanInstance &instance = getVulkanInstance(useValidationLayers);
const VulkanPhysicalDeviceList &physicalDeviceList =
instance.getPhysicalDeviceList();
@@ -112,12 +112,13 @@ const VulkanPhysicalDevice &getVulkanPhysicalDevice()
}
const VulkanPhysicalDevice &
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId)
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId,
bool useValidationLayers)
{
size_t pdIdx;
cl_int errNum = 0;
cl_uchar uuid[CL_UUID_SIZE_KHR];
const VulkanInstance &instance = getVulkanInstance();
const VulkanInstance &instance = getVulkanInstance(useValidationLayers);
const VulkanPhysicalDeviceList &physicalDeviceList =
instance.getPhysicalDeviceList();
@@ -188,10 +189,10 @@ getVulkanMemoryType(const VulkanDevice &device,
return memoryTypeList[mtIdx];
}
bool checkVkSupport()
bool checkVkSupport(bool useValidationLayers)
{
bool result = true;
const VulkanInstance &instance = getVulkanInstance();
const VulkanInstance &instance = getVulkanInstance(useValidationLayers);
const VulkanPhysicalDeviceList &physicalDeviceList =
instance.getPhysicalDeviceList();
if (physicalDeviceList() == NULL)
@@ -711,6 +712,7 @@ operator<<(std::ostream &os,
{
switch (externalMemoryHandleType)
{
default:
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE: return os << "None";
case VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD:
return os << "Opaque file descriptor";
@@ -731,6 +733,7 @@ operator<<(std::ostream &os,
{
switch (externalSemaphoreHandleType)
{
default:
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_NONE: return os << "None";
case VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD:
return os << "Opaque file descriptor";

View File

@@ -30,10 +30,12 @@
#define ROUND_UP(n, multiple) \
(((n) + (multiple)-1) - ((((n) + (multiple)-1)) % (multiple)))
const VulkanInstance& getVulkanInstance();
const VulkanPhysicalDevice& getVulkanPhysicalDevice();
const VulkanInstance& getVulkanInstance(bool useValidationLayers = false);
const VulkanPhysicalDevice&
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId);
getVulkanPhysicalDevice(bool useValidationLayers = false);
const VulkanPhysicalDevice&
getAssociatedVulkanPhysicalDevice(cl_device_id deviceId,
bool useValidationLayers = false);
const VulkanQueueFamily& getVulkanQueueFamily(
const VulkanPhysicalDevice& physicalDevice = getVulkanPhysicalDevice(),
uint32_t queueFlags = VULKAN_QUEUE_FLAG_GRAPHICS
@@ -41,7 +43,7 @@ const VulkanQueueFamily& getVulkanQueueFamily(
const VulkanMemoryType&
getVulkanMemoryType(const VulkanDevice& device,
VulkanMemoryTypeProperty memoryTypeProperty);
bool checkVkSupport();
bool checkVkSupport(bool useValidationLayers = false);
const VulkanQueueFamilyList& getEmptyVulkanQueueFamilyList();
const VulkanDescriptorSetLayoutList& getEmptyVulkanDescriptorSetLayoutList();
const VulkanQueueFamilyToQueueCountMap&

View File

@@ -48,16 +48,38 @@ VK_WINDOWS_FUNC_LIST
#define CHECK_VK(call) \
if (call != VK_SUCCESS) return call;
static VKAPI_ATTR VkBool32 VKAPI_CALL logCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
{
switch (messageSeverity)
{
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
log_error("Vulkan validation layer: %s\n", pCallbackData->pMessage);
break;
default:
log_info("Vulkan validation layer: %s\n", pCallbackData->pMessage);
break;
}
return VK_FALSE;
}
///////////////////////////////////
// VulkanInstance implementation //
///////////////////////////////////
VulkanInstance::VulkanInstance(const VulkanInstance &instance)
: m_vkInstance(instance.m_vkInstance),
m_physicalDeviceList(instance.m_physicalDeviceList)
m_physicalDeviceList(instance.m_physicalDeviceList),
m_useValidationLayers(instance.m_useValidationLayers),
m_validationLayers(instance.m_validationLayers)
{}
VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
VulkanInstance::VulkanInstance(bool useValidationLayers)
: m_vkInstance(VK_NULL_HANDLE), m_useValidationLayers(useValidationLayers)
{
#if defined(__linux__) && !defined(__ANDROID__)
char *glibcVersion = strdup(gnu_get_libc_version());
@@ -130,6 +152,35 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
VK_GET_NULL_INSTANCE_PROC_ADDR(vkCreateInstance);
#undef VK_GET_NULL_INSTANCE_PROC_ADDR
if (m_useValidationLayers)
{
uint32_t layerCount = 0;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
std::vector<VkLayerProperties> layers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, layers.data());
for (auto it = m_validationLayers.begin();
it != m_validationLayers.end();)
{
bool found = false;
for (const auto &layerProps : layers)
if (strcmp(*it, layerProps.layerName) == 0)
{
found = true;
break;
}
if (!found)
{
log_info("Vulkan layer not found: %s\n", *it);
it = m_validationLayers.erase(it);
}
else
++it;
}
m_useValidationLayers = !m_validationLayers.empty();
}
VkApplicationInfo vkApplicationInfo = {};
vkApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
vkApplicationInfo.pNext = NULL;
@@ -147,6 +198,9 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
enabledExtensionNameList.push_back(
VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
if (m_useValidationLayers)
enabledExtensionNameList.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
std::vector<VkExtensionProperties> vkExtensionPropertiesList(
instanceExtensionPropertiesCount);
vkEnumerateInstanceExtensionProperties(NULL,
@@ -174,18 +228,51 @@ VulkanInstance::VulkanInstance(): m_vkInstance(VK_NULL_HANDLE)
VkInstanceCreateInfo vkInstanceCreateInfo = {};
vkInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
vkInstanceCreateInfo.pNext = NULL;
vkInstanceCreateInfo.flags = 0;
vkInstanceCreateInfo.pApplicationInfo = &vkApplicationInfo;
vkInstanceCreateInfo.enabledLayerCount = 0;
vkInstanceCreateInfo.ppEnabledLayerNames = NULL;
vkInstanceCreateInfo.enabledExtensionCount =
(uint32_t)enabledExtensionNameList.size();
vkInstanceCreateInfo.ppEnabledExtensionNames =
enabledExtensionNameList.data();
vkInstanceCreateInfo.enabledLayerCount = 0;
vkInstanceCreateInfo.pNext = NULL;
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
if (m_useValidationLayers)
{
vkInstanceCreateInfo.enabledLayerCount =
static_cast<uint32_t>(m_validationLayers.size());
vkInstanceCreateInfo.ppEnabledLayerNames = m_validationLayers.data();
debugCreateInfo.messageType =
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
debugCreateInfo.sType =
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
debugCreateInfo.messageSeverity =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT
| VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
debugCreateInfo.pfnUserCallback = logCallback;
vkInstanceCreateInfo.pNext =
(VkDebugUtilsMessengerCreateInfoEXT *)&debugCreateInfo;
}
vkCreateInstance(&vkInstanceCreateInfo, NULL, &m_vkInstance);
if (m_useValidationLayers)
{
_vkCreateDebugUtilsMessengerEXT =
(PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
m_vkInstance, "vkCreateDebugUtilsMessengerEXT");
if (_vkCreateDebugUtilsMessengerEXT != nullptr)
vkCreateDebugUtilsMessengerEXT(m_vkInstance, &debugCreateInfo,
nullptr, &m_debugMessenger);
}
#define VK_FUNC_DECL(name) \
_##name = (PFN_##name)vkGetInstanceProcAddr(m_vkInstance, #name); \
// ASSERT_NEQ((unsigned long long)name, 0ULL) << "Couldn't obtain address
@@ -228,6 +315,17 @@ VulkanInstance::~VulkanInstance()
m_physicalDeviceList[pdIdx];
delete &physicalDevice;
}
_vkDestroyDebugUtilsMessengerEXT =
(PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(
m_vkInstance, "vkDestroyDebugUtilsMessengerEXT");
if (_vkDestroyDebugUtilsMessengerEXT != nullptr)
{
vkDestroyDebugUtilsMessengerEXT(m_vkInstance, m_debugMessenger,
nullptr);
}
if (m_vkInstance)
{
vkDestroyInstance(m_vkInstance, NULL);
@@ -1741,7 +1839,13 @@ VulkanImage::VulkanImage(
vkImageCreateInfo.pNext = &vkExternalMemoryImageCreateInfo;
}
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
VkResult vkStatus =
vkCreateImage(m_device, &vkImageCreateInfo, NULL, &m_vkImage);
if (vkStatus != VK_SUCCESS)
{
throw std::runtime_error("Error: Failed create image.");
}
VulkanImageCreateInfo = vkImageCreateInfo;
VkMemoryDedicatedRequirements vkMemoryDedicatedRequirements = {};
@@ -1870,7 +1974,7 @@ VulkanExtent3D VulkanImage2D::getExtent3D(uint32_t mipLevel) const
return VulkanExtent3D(width, height, depth);
}
VkSubresourceLayout VulkanImage2D::getSubresourceLayout() const
VkSubresourceLayout VulkanImage::getSubresourceLayout() const
{
VkImageSubresource subresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };

View File

@@ -25,14 +25,21 @@
#include <cassert>
class VulkanInstance {
friend const VulkanInstance &getVulkanInstance();
friend const VulkanInstance &getVulkanInstance(bool useValidationLayers);
protected:
VkInstance m_vkInstance;
VulkanPhysicalDeviceList m_physicalDeviceList;
VkDebugUtilsMessengerEXT m_debugMessenger;
bool m_useValidationLayers;
std::vector<const char *> m_validationLayers = {
"VK_LAYER_KHRONOS_validation",
};
VulkanInstance();
VulkanInstance(const VulkanInstance &);
public:
VulkanInstance(bool useValidationLayers = false);
virtual ~VulkanInstance();
public:
@@ -478,12 +485,14 @@ public:
VulkanExternalMemoryHandleType externalMemoryHandleType =
VULKAN_EXTERNAL_MEMORY_HANDLE_TYPE_NONE,
VulkanImageCreateFlag imageCreateFlags = VULKAN_IMAGE_CREATE_FLAG_NONE,
VulkanImageTiling imageTiling = VULKAN_IMAGE_TILING_OPTIMAL,
VulkanImageTiling imageTiling = VULKAN_IMAGE_TILING_LINEAR,
VulkanImageUsage imageUsage =
VULKAN_IMAGE_USAGE_SAMPLED_STORAGE_TRANSFER_SRC_DST,
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
virtual ~VulkanImage();
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
virtual VkSubresourceLayout getSubresourceLayout() const;
VulkanFormat getFormat() const;
uint32_t getNumMipLevels() const;
uint32_t getNumLayers() const;
@@ -553,7 +562,6 @@ public:
VulkanSharingMode sharingMode = VULKAN_SHARING_MODE_EXCLUSIVE);
virtual ~VulkanImage2D();
virtual VulkanExtent3D getExtent3D(uint32_t mipLevel = 0) const;
virtual VkSubresourceLayout getSubresourceLayout() const;
VulkanImage2D(const VulkanImage2D &image2D);
};

View File

@@ -45,27 +45,4 @@
}
// scope guard helper to ensure proper releasing of sub devices
struct SubDevicesScopeGuarded
{
SubDevicesScopeGuarded(const cl_int dev_count)
{
sub_devices.resize(dev_count);
}
~SubDevicesScopeGuarded()
{
for (auto &device : sub_devices)
{
cl_int err = clReleaseDevice(device);
if (err != CL_SUCCESS)
log_error("\n Releasing sub-device failed \n");
}
}
std::vector<cl_device_id> sub_devices;
};
#endif // _testBase_h

View File

@@ -55,7 +55,6 @@ const char *sample_kernel_code_two_line[] = {
"\n"
"}\n" };
const char *sample_kernel_code_bad_multi_line[] = {
"__kernel void sample_test(__global float *src, __global int *dst)",
"{",
@@ -87,6 +86,35 @@ __kernel void sample_test_C(__global float *src, __global int *dst)
}
)";
const char *sample_multi_kernel_code_AB_with_macro = R"(
__kernel void sample_test_A(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}
#ifdef USE_SAMPLE_TEST_B
__kernel void sample_test_B(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}
#endif
)";
const char *sample_multi_kernel_code_CD_with_macro = R"(
__kernel void sample_test_C(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}
#ifdef USE_SAMPLE_TEST_D
__kernel void sample_test_D(__global float *src, __global int *dst)
{
size_t tid = get_global_id(0);
dst[tid] = (int)src[tid];
}
#endif
)";
REGISTER_TEST(load_program_source)
{
@@ -550,6 +578,128 @@ REGISTER_TEST(get_program_info_kernel_names)
return CL_SUCCESS;
}
REGISTER_TEST(get_linked_program_info_kernel_names)
{
int error = CL_SUCCESS;
size_t total_kernels = 0;
size_t kernel_names_len = 0;
clProgramWrapper program_AB = clCreateProgramWithSource(
context, 1, &sample_multi_kernel_code_AB_with_macro, nullptr, &error);
test_error(error, "clCreateProgramWithSource failed");
clProgramWrapper program_CD = clCreateProgramWithSource(
context, 1, &sample_multi_kernel_code_CD_with_macro, nullptr, &error);
test_error(error, "clCreateProgramWithSource failed");
clProgramWrapper program = nullptr;
// 1) Compile and link the programs with the preprocessor macro undefined.
// Query CL_PROGRAM_NUM_KERNELS and check that the correct number is
// returned. Query CL_PROGRAM_KERNEL_NAMES and check that the right
// kernel names are returned.
{
error =
clCompileProgram(program_AB, 1, &device, nullptr, 0, 0, 0, 0, 0);
test_error(error, "clCompileProgram failed");
error =
clCompileProgram(program_CD, 1, &device, nullptr, 0, 0, 0, 0, 0);
test_error(error, "clCompileProgram failed");
cl_program progs[] = { program_AB, program_CD };
program =
clLinkProgram(context, 1, &device, "", 2, progs, 0, 0, &error);
test_error(error, "clLinkProgram failed");
error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS,
sizeof(size_t), &total_kernels, nullptr);
test_error(error, "clGetProgramInfo failed");
test_assert_error(total_kernels == 2,
"Unexpected clGetProgramInfo result");
error = clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, 0, nullptr,
&kernel_names_len);
test_error(error, "clGetProgramInfo failed");
const size_t len = kernel_names_len + 1;
std::vector<char> kernel_names(len, '\0');
error =
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
kernel_names.data(), &kernel_names_len);
test_error(error, "Unable to get kernel names list.");
std::string program_names = kernel_names.data();
std::vector<std::string> expected_names = { "sample_test_A",
"sample_test_C" };
for (const auto &name : expected_names)
{
test_assert_error(program_names.find(name) != std::string::npos,
"Unexpected kernel name");
}
std::vector<std::string> unexpected_names = { "sample_test_B",
"sample_test_D" };
for (const auto &name : unexpected_names)
{
test_assert_error(program_names.find(name) == std::string::npos,
"Unexpected kernel name");
}
}
// 2) Compile and link the programs with the preprocessor macro defined.
// Query CL_PROGRAM_NUM_KERNELS and check that the correct number is
// returned. Query CL_PROGRAM_KERNEL_NAMES and check that the right
// kernel names are returned.
{
const char *build_options_B = "-DUSE_SAMPLE_TEST_B";
error = clCompileProgram(program_AB, 1, &device, build_options_B, 0, 0,
0, 0, 0);
test_error(error, "clCompileProgram failed");
const char *build_options_D = "-DUSE_SAMPLE_TEST_D";
error = clCompileProgram(program_CD, 1, &device, build_options_D, 0, 0,
0, 0, 0);
test_error(error, "clCompileProgram failed");
cl_program progs[] = { program_AB, program_CD };
program =
clLinkProgram(context, 1, &device, "", 2, progs, 0, 0, &error);
test_error(error, "clLinkProgram failed");
error = clGetProgramInfo(program, CL_PROGRAM_NUM_KERNELS,
sizeof(size_t), &total_kernels, nullptr);
test_error(error, "clGetProgramInfo failed");
test_assert_error(total_kernels == 4,
"Unexpected clGetProgramInfo result");
error = clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, 0, nullptr,
&kernel_names_len);
test_error(error, "clGetProgramInfo failed");
std::vector<std::string> expected_names = {
"sample_test_A", "sample_test_B", "sample_test_C", "sample_test_D"
};
const size_t len = kernel_names_len + 1;
std::vector<char> kernel_names(len, '\0');
error =
clGetProgramInfo(program, CL_PROGRAM_KERNEL_NAMES, kernel_names_len,
kernel_names.data(), &kernel_names_len);
test_error(error, "Could not find expected kernel name");
std::string program_names = kernel_names.data();
for (const auto &name : expected_names)
{
test_assert_error(program_names.find(name) != std::string::npos,
"Unexpected kernel name");
}
}
return TEST_PASS;
}
REGISTER_TEST(get_program_info_mult_devices)
{
size_t size = 0;
@@ -641,7 +791,7 @@ REGISTER_TEST(get_program_info_mult_devices)
if (program == nullptr)
{
log_error("ERROR: Unable to create reference program!\n");
return -1;
return TEST_FAIL;
}
err = clGetProgramInfo(program, CL_PROGRAM_NUM_DEVICES, sizeof(num_devices),
@@ -670,7 +820,7 @@ REGISTER_TEST(get_program_info_mult_devices)
}
}
test_error_fail(
!found, "Unexpected result returned by CL_CONTEXT_DEVICES query");
!found, "Unexpected result returned by CL_PROGRAM_DEVICES query");
}
return TEST_PASS;

View File

@@ -94,7 +94,8 @@ const char *known_extensions[] = {
"cl_khr_external_memory_dma_buf",
"cl_khr_command_buffer",
"cl_khr_command_buffer_mutable_dispatch",
"cl_khr_command_buffer_multi_device"
"cl_khr_command_buffer_multi_device",
"cl_khr_external_memory_android_hardware_buffer"
};
// clang-format on

View File

@@ -56,9 +56,9 @@ static int test_CL_DEVICE_OPENCL_C_VERSION(cl_device_id device,
// For OpenCL 2.x, the minimum required OpenCL C version is OpenCL C 2.0.
// For other OpenCL versions, the minimum required OpenCL C version is
// the same as the API version.
const Version min_clc_version = api_version == Version(3, 0)
? Version(1, 2)
: api_version >= Version(2, 0) ? Version(2, 0) : api_version;
const Version min_clc_version = api_version == Version(3, 0) ? Version(1, 2)
: api_version >= Version(2, 0) ? Version(2, 0)
: api_version;
if (clc_version < min_clc_version)
{
log_error("The minimum required OpenCL C version for API version %s is "
@@ -88,10 +88,10 @@ static int test_CL_DEVICE_OPENCL_C_VERSION(cl_device_id device,
if (clc_version >= testcase.version)
{
clProgramWrapper program;
cl_int error =
create_single_kernel_helper_create_program_for_device(
context, device, &program, 1, &test_kernel,
testcase.buildOptions);
clKernelWrapper kernel;
cl_int error = create_single_kernel_helper(
context, &program, &kernel, 1, &test_kernel, "test",
testcase.buildOptions);
test_error(error, "Unable to build program!");
log_info(" successfully built program with build options '%s'\n",
@@ -152,9 +152,10 @@ static int test_CL_DEVICE_OPENCL_C_ALL_VERSIONS(cl_device_id device,
buildOptions += std::to_string(minor);
clProgramWrapper program;
error = create_single_kernel_helper_create_program_for_device(
context, device, &program, 1, &test_kernel,
buildOptions.c_str());
clKernelWrapper kernel;
error = create_single_kernel_helper(context, &program, &kernel, 1,
&test_kernel, "test",
buildOptions.c_str());
test_error(error, "Unable to build program!");
log_info(" successfully built program with build options '%s'\n",

View File

@@ -12,6 +12,6 @@ if("${CLConform_TARGET_ARCH}" STREQUAL "ARM" OR "${CLConform_TARGET_ARCH}" STREQ
list(APPEND ${MODULE_NAME}_SOURCES fplib.cpp)
endif()
set_gnulike_module_compile_flags("-Wno-sign-compare -Wno-format")
set_gnulike_module_compile_flags("-Wno-sign-compare")
include(../CMakeCommon.txt)

View File

@@ -68,12 +68,6 @@ cl_context gContext = NULL;
cl_command_queue gQueue = NULL;
int gStartTestNumber = -1;
int gEndTestNumber = 0;
#if defined(__APPLE__)
int gTimeResults = 1;
#else
int gTimeResults = 0;
#endif
int gReportAverageTimes = 0;
void *gIn = NULL;
void *gRef = NULL;
void *gAllowZ = NULL;
@@ -103,8 +97,6 @@ const char **argList = NULL;
int argCount = 0;
double SubtractTime(uint64_t endTime, uint64_t startTime);
cl_half_rounding_mode DataInitInfo::halfRoundingMode = CL_HALF_RTE;
cl_half_rounding_mode ConversionsTest::defaultHalfRoundingMode = CL_HALF_RTE;
@@ -318,7 +310,7 @@ int CalcRefValsPat<InType, OutType, InFP, OutFP>::check_result(void *test,
{
const cl_uchar *a = (const cl_uchar *)gAllowZ;
if (is_half<OutType, OutFP>())
if constexpr (is_half<OutType, OutFP>())
{
const cl_half *t = (const cl_half *)test;
const cl_half *c = (const cl_half *)gRef;
@@ -335,7 +327,7 @@ int CalcRefValsPat<InType, OutType, InFP, OutFP>::check_result(void *test,
return i + 1;
}
}
else if (std::is_integral<OutType>::value)
else if constexpr (std::is_integral<OutType>::value)
{ // char/uchar/short/ushort/half/int/uint/long/ulong
const OutType *t = (const OutType *)test;
const OutType *c = (const OutType *)gRef;
@@ -350,7 +342,7 @@ int CalcRefValsPat<InType, OutType, InFP, OutFP>::check_result(void *test,
return i + 1;
}
}
else if (std::is_same<OutType, cl_float>::value)
else if constexpr (std::is_same<OutType, cl_float>::value)
{
// cast to integral - from original test
const cl_uint *t = (const cl_uint *)test;
@@ -904,61 +896,6 @@ int ConversionsTest::DoTest(Type outType, Type inType, SaturationMode sat,
log_info("done.\n");
if (gTimeResults)
{
// Kick off tests for the various vector lengths
for (vectorSize = gMinVectorSize; vectorSize < gMaxVectorSize;
vectorSize++)
{
size_t workItemCount = blockCount / vectorSizes[vectorSize];
if (vectorSizes[vectorSize] * gTypeSizes[outType] < 4)
workItemCount /=
4 / (vectorSizes[vectorSize] * gTypeSizes[outType]);
double sum = 0.0;
double bestTime = INFINITY;
cl_uint k;
for (k = 0; k < PERF_LOOP_COUNT; k++)
{
uint64_t startTime = conv_test::GetTime();
if ((error = conv_test::RunKernel(
writeInputBufferInfo.calcInfo[vectorSize]->kernel,
gInBuffer, gOutBuffers[vectorSize], workItemCount)))
{
gFailCount++;
return error;
}
// Make sure OpenCL is done
if ((error = clFinish(gQueue)))
{
vlog_error("Error %d at clFinish\n", error);
return error;
}
uint64_t endTime = conv_test::GetTime();
double time = SubtractTime(endTime, startTime);
sum += time;
if (time < bestTime) bestTime = time;
}
if (gReportAverageTimes) bestTime = sum / PERF_LOOP_COUNT;
double clocksPerOp = bestTime * (double)gDeviceFrequency
* gComputeDevices * gSimdSize * 1e6
/ (workItemCount * vectorSizes[vectorSize]);
if (0 == vectorSize)
vlog_perf(clocksPerOp, LOWER_IS_BETTER, "clocks / element",
"implicit convert %s -> %s", gTypeNames[inType],
gTypeNames[outType]);
else
vlog_perf(clocksPerOp, LOWER_IS_BETTER, "clocks / element",
"convert_%s%s%s%s( %s%s )", gTypeNames[outType],
sizeNames[vectorSize], gSaturationNames[sat],
gRoundingModeNames[round], gTypeNames[inType],
sizeNames[vectorSize]);
}
}
if (gWimpyMode)
vlog("\tWimp pass");
else
@@ -978,33 +915,6 @@ int ConversionsTest::DoTest(Type outType, Type inType, SaturationMode sat,
void memset_pattern4(void *dest, const void *src_pattern, size_t bytes);
#endif
#if defined(_MSC_VER)
/* function is defined in "compat.h" */
#else
double SubtractTime(uint64_t endTime, uint64_t startTime)
{
uint64_t diff = endTime - startTime;
static double conversion = 0.0;
if (0.0 == conversion)
{
#if defined(__APPLE__)
mach_timebase_info_data_t info = { 0, 0 };
kern_return_t err = mach_timebase_info(&info);
if (0 == err)
conversion = 1e-9 * (double)info.numer / (double)info.denom;
#else
// This function consumes output from GetTime() above, and converts the
// time to secionds.
#warning need accurate ticks to seconds conversion factor here. Times are invalid.
#endif
}
// strictly speaking we should also be subtracting out timer latency here
return conversion * (double)diff;
}
#endif
void MapResultValuesComplete(const std::unique_ptr<CalcRefValsBase> &ptr);
void CL_CALLBACK CalcReferenceValuesComplete(cl_event e, cl_int status,
@@ -1352,20 +1262,6 @@ cl_int PrepareReference(cl_uint job_id, cl_uint thread_id, void *p)
return CL_SUCCESS;
}
uint64_t GetTime(void)
{
#if defined(__APPLE__)
return mach_absolute_time();
#elif defined(_MSC_VER)
return ReadTime();
#else
// mach_absolute_time is a high precision timer with precision < 1
// microsecond.
#warning need accurate clock here. Times are invalid.
return 0;
#endif
}
// Note: not called reentrantly
void WriteInputBufferComplete(void *data)
{

View File

@@ -86,8 +86,6 @@ extern int gSkipTesting;
extern int gMinVectorSize;
extern int gMaxVectorSize;
extern int gForceFTZ;
extern int gTimeResults;
extern int gReportAverageTimes;
extern int gStartTestNumber;
extern int gEndTestNumber;
extern int gIsRTZ;

View File

@@ -226,8 +226,6 @@ static int ParseArgs(int argc, const char **argv)
gForceFTZ ^= 1;
gForceHalfFTZ ^= 1;
break;
case 't': gTimeResults ^= 1; break;
case 'a': gReportAverageTimes ^= 1; break;
case '1':
if (arg[1] == '6')
{

View File

@@ -8,6 +8,7 @@ add_subdirectory( cl_khr_dx9_media_sharing )
add_subdirectory( cl_khr_external_memory_dma_buf )
add_subdirectory( cl_khr_semaphore )
add_subdirectory( cl_khr_kernel_clock )
add_subdirectory( cl_ext_buffer_device_address )
if(VULKAN_IS_SUPPORTED)
add_subdirectory( cl_khr_external_semaphore )
endif()

View File

@@ -0,0 +1,7 @@
set(MODULE_NAME CL_EXT_BUFFER_DEVICE_ADDRESS)
set(${MODULE_NAME}_SOURCES
main.cpp buffer_device_address.cpp
)
include(../../CMakeCommon.txt)

View File

@@ -0,0 +1,437 @@
// Copyright (c) 2024 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/typeWrappers.h"
#include <cinttypes>
#define BUF_SIZE 1024
#define BUF_SIZE_STR "1024"
namespace {
static const char *program_source =
R"raw(
// A kernel that gets the device-seen address of the buffer.
__kernel void get_addr (__global int *buffer,
__global ulong* addr) {
for (int i = 0; i < BUF_SIZE; ++i)
buffer[i] += 1;
*addr = (ulong)buffer;
}
// A kernel that accesses another buffer indirectly.
__kernel void indirect_access (__global long* in_addr,
__global int* out) {
*out = **(int __global* __global*)in_addr;
}
// A kernel that gets passed a pointer to a middle of a buffer,
// with the data _before_ the passed pointer. Tests the property
// of sub-buffers to synchronize the whole parent buffer when
// using the CL_MEM_BUFFER_DEVICE_ADDRESS flag.
__kernel void ptr_arith (__global int* in_addr,
__global int* out) {
*out = *(in_addr - 2);
}
)raw";
class BufferDeviceAddressTest {
public:
BufferDeviceAddressTest(cl_device_id device, cl_context context,
cl_command_queue queue,
cl_mem_properties address_type)
: device(device), context(context), queue(queue),
address_type(address_type)
{}
bool Skip()
{
cl_int error = 0;
cl_mem_properties buf_props[] = { address_type, CL_TRUE, 0 };
clMemWrapper TempBuffer = clCreateBufferWithProperties(
context, buf_props, CL_MEM_READ_WRITE,
(size_t)BUF_SIZE * sizeof(cl_int), nullptr, &error);
return (error != CL_SUCCESS);
}
cl_int RunTest()
{
cl_int error;
clProgramWrapper program;
clKernelWrapper get_addr_kernel, indirect_access_kernel,
ptr_arith_kernel;
clMemWrapper dev_addr_buffer, buffer_long, buffer_int,
dev_addr_no_host_buffer;
error = create_single_kernel_helper(context, &program, &get_addr_kernel,
1, &program_source, "get_addr",
"-DBUF_SIZE=" BUF_SIZE_STR);
test_error(error, "Failed to create program with source\n");
indirect_access_kernel =
clCreateKernel(program, "indirect_access", &error);
test_error(error, "Failed to create kernel indirect_access\n");
ptr_arith_kernel = clCreateKernel(program, "ptr_arith", &error);
test_error(error, "Failed to create kernel ptr_arith\n");
buffer_long = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_ulong), nullptr, &error);
test_error(error, "clCreateBuffer failed\n");
buffer_int = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int),
nullptr, &error);
test_error(error, "clCreateBuffer failed\n");
// Test a buffer with hostptr copied data
cl_mem_properties buf_props[] = { address_type, CL_TRUE, 0 };
dev_addr_buffer = clCreateBufferWithProperties(
context, buf_props, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
sizeof(cl_int) * BUF_SIZE, BufferHost, &error);
test_error(error, "clCreateBuffer with device address 1 failed\n");
if (test_buffer(dev_addr_buffer, buffer_long, get_addr_kernel)
!= TEST_PASS)
test_fail("test_buffer_host failed\n");
// Test a buffer which doesn't have any hostptr associated with it.
dev_addr_no_host_buffer = clCreateBufferWithProperties(
context, buf_props, CL_MEM_READ_WRITE, sizeof(cl_int) * BUF_SIZE,
nullptr, &error);
test_error(error, "clCreateBuffer with device address 2 failed\n");
if (test_buffer(dev_addr_no_host_buffer, buffer_long, get_addr_kernel)
!= TEST_PASS)
test_fail("test_buffer_no_host failed\n");
// Test a buffer passed indirectly
if (test_indirect_buffer(dev_addr_buffer, buffer_long, buffer_int,
indirect_access_kernel)
!= TEST_PASS)
test_fail("test_indirect_buffer failed\n");
if (test_set_kernel_arg(dev_addr_buffer, buffer_int, ptr_arith_kernel)
!= TEST_PASS)
test_fail("test_set_kernel_arg failed\n");
if (test_svm_buffer() == TEST_FAIL)
test_fail("test_svm_buffer failed\n");
return TEST_PASS;
}
private:
int BufferHost[BUF_SIZE];
size_t global_size_one[3] = { 1, 1, 1 };
cl_device_id device;
cl_context context;
cl_command_queue queue;
cl_mem_properties address_type;
int check_device_address_from_api(cl_mem buf,
cl_mem_device_address_ext &Addr)
{
Addr = 0;
cl_int error = clGetMemObjectInfo(buf, CL_MEM_DEVICE_ADDRESS_EXT,
sizeof(Addr), &Addr, NULL);
test_error(error,
"clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) failed\n");
if (Addr == 0)
{
print_error(error,
"clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) "
"returned 0 as address\n");
return CL_INVALID_VALUE;
}
return CL_SUCCESS;
}
int test_svm_buffer()
{
clSVMWrapper svm_buffer;
clMemWrapper buffer;
cl_int error = 0;
cl_device_svm_capabilities svm_caps = 0;
error = clGetDeviceInfo(device, CL_DEVICE_SVM_CAPABILITIES,
sizeof(svm_caps), &svm_caps, NULL);
if (error != CL_SUCCESS)
{
print_missing_feature(error,
"Unable to get SVM capabilities, "
"skipping");
return TEST_SKIP;
}
if ((svm_caps & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER) == 0)
{
print_missing_feature(error,
"Device doesn't support "
"CL_DEVICE_SVM_COARSE_"
"GRAIN_BUFFER, skipping");
return TEST_SKIP;
}
svm_buffer =
clSVMWrapper(context, sizeof(cl_int) * BUF_SIZE,
CL_DEVICE_SVM_COARSE_GRAIN_BUFFER | CL_MEM_READ_WRITE);
if (svm_buffer() == nullptr)
{
test_error(CL_OUT_OF_RESOURCES, "SVM allocation failed");
}
cl_mem_properties buf_props[] = { address_type, CL_TRUE, 0 };
buffer = clCreateBufferWithProperties(
context, buf_props, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
sizeof(cl_int) * BUF_SIZE, svm_buffer(), &error);
test_error(error, "clCreateBuffer with device address 1 failed\n");
cl_mem_device_address_ext Addr = 0;
error = clGetMemObjectInfo(buffer, CL_MEM_DEVICE_ADDRESS_EXT,
sizeof(Addr), &Addr, NULL);
test_error(error,
"clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) failed\n");
if ((void *)Addr != svm_buffer())
{
test_fail("clGetMemObjectInfo(CL_MEM_DEVICE_ADDRESS_EXT) "
"returned different address than clSVMAlloc\n");
}
return TEST_PASS;
}
int test_buffer(clMemWrapper &dev_addr_buffer, clMemWrapper &plain_buffer,
clKernelWrapper &get_addr_kernel)
{
cl_int error = 0;
cl_ulong DeviceAddrFromKernel = 0;
cl_mem_device_address_ext DeviceAddrFromAPI = 0;
for (int i = 0; i < BUF_SIZE; ++i)
{
BufferHost[i] = i;
}
error =
check_device_address_from_api(dev_addr_buffer, DeviceAddrFromAPI);
test_error_fail(error,
"device address buffer does not have device address");
error = clEnqueueWriteBuffer(queue, dev_addr_buffer,
CL_FALSE, // block
0, BUF_SIZE * sizeof(cl_int), BufferHost,
0, NULL, NULL);
test_error_fail(error,
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
error = clSetKernelArg(get_addr_kernel, 0, sizeof(cl_mem),
&dev_addr_buffer);
test_error_fail(error, "clSetKernelArg 0 failed\n");
error =
clSetKernelArg(get_addr_kernel, 1, sizeof(cl_mem), &plain_buffer);
test_error_fail(error, "clSetKernelArg 1 failed\n");
error = clEnqueueNDRangeKernel(queue, get_addr_kernel, 1, NULL,
global_size_one, NULL, 0, NULL, NULL);
test_error_fail(error, "clNDRangeKernel failed\n");
error = clEnqueueReadBuffer(queue, dev_addr_buffer, CL_FALSE, 0,
sizeof(cl_int) * BUF_SIZE, BufferHost, 0,
NULL, NULL);
test_error_fail(error,
"clEnqueueReadBuffer of dev_addr_buffer failed\n");
error = clEnqueueReadBuffer(queue, plain_buffer, CL_FALSE, 0,
sizeof(cl_ulong), &DeviceAddrFromKernel, 0,
NULL, NULL);
test_error_fail(error, "clEnqueueReadBuffer of buffer failed\n");
error = clFinish(queue);
test_error_fail(error, "clFinish failed\n");
for (int i = 0; i < BUF_SIZE; ++i)
{
if (BufferHost[i] != (i + 1))
{
test_fail("BufferHost[%i] expected "
"to be: %i, but is: %i\n",
i, i + 1, BufferHost[i]);
}
}
if (DeviceAddrFromAPI != DeviceAddrFromKernel)
{
test_fail("DeviceAddrFromAPI(%" PRIu64
") != DeviceAddrFromKernel(%" PRIu64 ")\n",
(uint64_t)DeviceAddrFromAPI,
(uint64_t)DeviceAddrFromKernel);
}
return TEST_PASS;
}
int test_indirect_buffer(clMemWrapper &dev_addr_buffer,
clMemWrapper &buffer_in_long,
clMemWrapper &buffer_out_int,
clKernelWrapper &ind_access_kernel)
{
cl_int error = 0;
cl_mem_device_address_ext DeviceAddrFromAPI = 0;
int DataIn = 0x12348765;
int DataOut = -1;
// A devaddr buffer with the payload data.
error = clEnqueueWriteBuffer(queue, dev_addr_buffer,
CL_TRUE, // block
0, sizeof(cl_int), &DataIn, 0, NULL, NULL);
test_error_fail(error,
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
error =
check_device_address_from_api(dev_addr_buffer, DeviceAddrFromAPI);
test_error_fail(error,
"device address buffer does not have device address")
// A basic buffer used to pass the other buffer's address.
error = clEnqueueWriteBuffer(queue, buffer_in_long,
CL_TRUE, // block
0, sizeof(cl_long), &DeviceAddrFromAPI,
0, NULL, NULL);
test_error_fail(error,
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
error = clSetKernelArg(ind_access_kernel, 0, sizeof(cl_mem),
&buffer_in_long);
test_error_fail(error, "clSetKernelArg 0 failed\n");
error = clSetKernelArg(ind_access_kernel, 1, sizeof(cl_mem),
&buffer_out_int);
test_error_fail(error, "clSetKernelArg 1 failed\n");
error = clSetKernelExecInfo(ind_access_kernel,
CL_KERNEL_EXEC_INFO_DEVICE_PTRS_EXT,
sizeof(void *), &DeviceAddrFromAPI);
test_error_fail(error,
"Setting indirect access for "
"device ptrs failed!\n");
error = clEnqueueNDRangeKernel(queue, ind_access_kernel, 1, NULL,
global_size_one, NULL, 0, NULL, NULL);
test_error_fail(error, "clNDRangeKernel failed\n");
error = clEnqueueReadBuffer(queue, buffer_out_int, CL_FALSE, 0,
sizeof(cl_int), &DataOut, 0, NULL, NULL);
test_error_fail(error, "clEnqueueReadBuffer of buffer failed\n");
error = clFinish(queue);
test_error_fail(error, "clFinish failed\n");
for (int i = 0; i < BUF_SIZE; ++i)
{
if (BufferHost[i] != i + 1)
{
test_fail("PinnedBufferHost[%i] expected "
"to be: %i, but is: %i\n",
i, i + 1, BufferHost[i]);
}
}
if (DataIn != DataOut)
{
test_fail("Passing data via indirect buffers failed. "
"Got: %i expected: %i\n",
DataOut, DataIn);
}
return TEST_PASS;
}
int test_set_kernel_arg(clMemWrapper &dev_addr_buffer,
clMemWrapper &buffer_out_int,
clKernelWrapper &ptr_arith_kernel)
{
cl_int error = 0;
cl_mem_device_address_ext DeviceAddrFromAPI = 0;
int DataOut = -1;
int DataIn = 0x12348765;
clSetKernelArgDevicePointerEXT_fn clSetKernelArgDevicePointer =
(clSetKernelArgDevicePointerEXT_fn)
clGetExtensionFunctionAddressForPlatform(
getPlatformFromDevice(device),
"clSetKernelArgDevicePointerEXT");
if (clSetKernelArgDevicePointer == nullptr)
test_error_fail(
error, "Cannot get address of clSetKernelArgDevicePointerEXT");
error = clEnqueueWriteBuffer(queue, dev_addr_buffer,
CL_FALSE, // block
0, sizeof(cl_int), &DataIn, 0, NULL, NULL);
test_error_fail(error,
"clEnqueueWriteBuffer of dev_addr_buffer failed\n");
error =
check_device_address_from_api(dev_addr_buffer, DeviceAddrFromAPI);
test_error_fail(error, "dev_addr_buffer does not have device address");
cl_mem_device_address_ext DeviceAddrFromAPIP2 =
(cl_mem_device_address_ext)(((cl_uint *)DeviceAddrFromAPI) + 2);
error = clSetKernelArgDevicePointer(ptr_arith_kernel, 0,
DeviceAddrFromAPIP2);
test_error_fail(error, "clSetKernelArgDevicePointer failed\n");
error = clSetKernelArg(ptr_arith_kernel, 1, sizeof(cl_mem),
&buffer_out_int);
test_error_fail(error, "clSetKernelArg 1 failed\n");
error = clEnqueueNDRangeKernel(queue, ptr_arith_kernel, 1, NULL,
global_size_one, NULL, 0, NULL, NULL);
test_error_fail(error, "clNDRangeKernel failed\n");
error = clEnqueueReadBuffer(queue, buffer_out_int, CL_FALSE, 0,
sizeof(cl_int), &DataOut, 0, NULL, NULL);
test_error_fail(error, "clEnqueueReadBuffer of buffer failed\n");
error = clFinish(queue);
test_error_fail(error, "clFinish failed\n");
if (DataIn != DataOut)
{
test_fail("Negative offsetting from passed in pointer failed: "
"got: %i expected: %i",
DataOut, DataIn);
}
return TEST_PASS;
}
};
}
REGISTER_TEST(private_address)
{
BufferDeviceAddressTest test_fixture = BufferDeviceAddressTest(
device, context, queue, CL_MEM_DEVICE_PRIVATE_ADDRESS_EXT);
if (test_fixture.Skip())
{
log_info("Test fixture skip\n");
return TEST_SKIPPED_ITSELF;
}
cl_int error = test_fixture.RunTest();
test_error_ret(error, "Test Failed", TEST_FAIL);
return TEST_PASS;
}

View File

@@ -0,0 +1,58 @@
// Copyright (c) 2024 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/testHarness.h"
#include "harness/deviceInfo.h"
test_status InitCL(cl_device_id device)
{
auto version = get_device_cl_version(device);
auto expected_min_version = Version(3, 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;
}
if (!is_extension_available(device, "cl_ext_buffer_device_address"))
{
log_info("The device does not support the "
"cl_ext_buffer_device_address extension.\n");
return TEST_SKIPPED_ITSELF;
}
cl_version ext_version =
get_extension_version(device, "cl_ext_buffer_device_address");
if (ext_version != CL_MAKE_VERSION(1, 0, 2))
{
log_info("The test is written against cl_ext_buffer_device_address "
"extension version 1.0.2, device supports version: %u.%u.%u\n",
CL_VERSION_MAJOR(ext_version), CL_VERSION_MINOR(ext_version),
CL_VERSION_PATCH(ext_version));
return TEST_SKIPPED_ITSELF;
}
return TEST_PASS;
}
int main(int argc, const char *argv[])
{
return runTestHarnessWithCheck(
argc, argv, test_registry::getInstance().num_tests(),
test_registry::getInstance().definitions(), false, 0, InitCL);
}

View File

@@ -13,8 +13,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "procs.h"
#include <CL/cl.h>
#include "harness/typeWrappers.h"
int test_cxx_for_opencl(cl_device_id device, cl_context context,
cl_command_queue queue)
@@ -90,8 +91,7 @@ int test_cxx_for_opencl(cl_device_id device, cl_context context,
return TEST_PASS;
}
int test_cxx_for_opencl_ext(cl_device_id device, cl_context context,
cl_command_queue queue, int)
REGISTER_TEST_VERSION(cxx_for_opencl_ext, Version(2, 0))
{
if (!is_extension_available(device, "cl_ext_cxx_for_opencl"))
{

View File

@@ -13,8 +13,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "procs.h"
#include <CL/cl.h>
#include "harness/typeWrappers.h"
int test_cxx_for_opencl_version(cl_device_id device, cl_context context,
cl_command_queue queue)
@@ -88,8 +89,7 @@ int test_cxx_for_opencl_version(cl_device_id device, cl_context context,
return TEST_PASS;
}
int test_cxx_for_opencl_ver(cl_device_id device, cl_context context,
cl_command_queue queue, int)
REGISTER_TEST_VERSION(cxx_for_opencl_ver, Version(2, 0))
{
if (!is_extension_available(device, "cl_ext_cxx_for_opencl"))
{

View File

@@ -14,15 +14,11 @@
// limitations under the License.
//
#include "procs.h"
test_definition test_list[] = {
ADD_TEST_VERSION(cxx_for_opencl_ext, Version(2, 0)),
ADD_TEST_VERSION(cxx_for_opencl_ver, Version(2, 0))
};
#include "harness/testHarness.h"
int main(int argc, const char *argv[])
{
return runTestHarnessWithCheck(argc, argv, ARRAY_SIZE(test_list), test_list,
false, 0, nullptr);
return runTestHarnessWithCheck(
argc, argv, test_registry::getInstance().num_tests(),
test_registry::getInstance().definitions(), false, 0, nullptr);
}

View File

@@ -1,26 +0,0 @@
//
// Copyright (c) 2021 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _procs_h
#define _procs_h
#include "harness/typeWrappers.h"
extern int test_cxx_for_opencl_ext(cl_device_id device, cl_context context,
cl_command_queue queue, int);
extern int test_cxx_for_opencl_ver(cl_device_id device, cl_context context,
cl_command_queue queue, int);
#endif /*_procs_h*/

View File

@@ -3,6 +3,7 @@ set(MODULE_NAME CL_KHR_COMMAND_BUFFER)
set(${MODULE_NAME}_SOURCES
main.cpp
basic_command_buffer.cpp
basic_command_buffer_tests.cpp
svm_command_basic.cpp
command_buffer_printf.cpp
command_buffer_get_command_buffer_info.cpp

View File

@@ -14,7 +14,6 @@
// limitations under the License.
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <algorithm>
#include <cstring>
@@ -186,324 +185,253 @@ cl_int BasicCommandBufferTest::SetUp(int elements)
return CL_SUCCESS;
}
namespace {
// Test that the CL_COMMAND_BUFFER_FLAGS_KHR bitfield is parsed correctly when
// multiple flags are set.
struct MultiFlagCreationTest : public BasicCommandBufferTest
cl_int MultiFlagCreationTest::Run()
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_command_buffer_properties_khr flags = 0;
cl_int error = CL_SUCCESS;
cl_int Run() override
// First try to find multiple flags that are supported by the driver and
// device.
if (simultaneous_use_support)
{
cl_command_buffer_properties_khr flags = 0;
cl_int error = CL_SUCCESS;
// First try to find multiple flags that are supported by the driver and
// device.
if (simultaneous_use_support)
{
flags |= CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR;
}
if (is_extension_available(
device, CL_KHR_COMMAND_BUFFER_MULTI_DEVICE_EXTENSION_NAME))
{
flags |= CL_COMMAND_BUFFER_DEVICE_SIDE_SYNC_KHR;
}
if (is_extension_available(
device, CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME))
{
flags |= CL_COMMAND_BUFFER_MUTABLE_KHR;
}
cl_command_buffer_properties_khr props[] = {
CL_COMMAND_BUFFER_FLAGS_KHR, flags, 0
};
command_buffer = clCreateCommandBufferKHR(1, &queue, props, &error);
test_error(error, "clCreateCommandBufferKHR failed");
return CL_SUCCESS;
flags |= CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR;
}
if (is_extension_available(
device, CL_KHR_COMMAND_BUFFER_MULTI_DEVICE_EXTENSION_NAME))
{
flags |= CL_COMMAND_BUFFER_DEVICE_SIDE_SYNC_KHR;
}
if (is_extension_available(
device, CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME))
{
flags |= CL_COMMAND_BUFFER_MUTABLE_KHR;
}
cl_command_buffer_properties_khr props[] = { CL_COMMAND_BUFFER_FLAGS_KHR,
flags, 0 };
command_buffer = clCreateCommandBufferKHR(1, &queue, props, &error);
test_error(error, "clCreateCommandBufferKHR failed");
return CL_SUCCESS;
};
// Test enqueuing a command-buffer containing a single NDRange command once
struct BasicEnqueueTest : public BasicCommandBufferTest
cl_int BasicEnqueueTest::Run()
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
cl_int error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
const cl_int pattern = 42;
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> output_data_1(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_data_1.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
cl_int error = clCommandNDRangeKernelKHR(
CHECK_VERIFICATION_ERROR(pattern, output_data_1[i], i);
}
const cl_int new_pattern = 12;
error = clEnqueueFillBuffer(queue, in_mem, &new_pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> output_data_2(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_data_2.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(new_pattern, output_data_2[i], i);
}
return CL_SUCCESS;
};
cl_int MixedCommandsTest::Run()
{
cl_int error;
const size_t iterations = 4;
clMemWrapper result_mem =
clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int) * iterations,
nullptr, &error);
test_error(error, "clCreateBuffer failed");
const cl_int pattern_base = 42;
for (size_t i = 0; i < iterations; i++)
{
const cl_int pattern = pattern_base + i;
cl_int error = clCommandFillBufferKHR(
command_buffer, nullptr, nullptr, in_mem, &pattern, sizeof(cl_int),
0, data_size(), 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandFillBufferKHR failed");
error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
const cl_int pattern = 42;
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> output_data_1(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_data_1.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(pattern, output_data_1[i], i);
}
const cl_int new_pattern = 12;
error = clEnqueueFillBuffer(queue, in_mem, &new_pattern, sizeof(cl_int),
0, data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> output_data_2(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_data_2.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(new_pattern, output_data_2[i], i);
}
return CL_SUCCESS;
const size_t result_offset = i * sizeof(cl_int);
error = clCommandCopyBufferKHR(
command_buffer, nullptr, nullptr, out_mem, result_mem, 0,
result_offset, sizeof(cl_int), 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandCopyBufferKHR failed");
}
};
// Test enqueuing a command-buffer containing multiple command, including
// operations other than NDRange kernel execution.
struct MixedCommandsTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
cl_int Run() override
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> result_data(num_elements);
error = clEnqueueReadBuffer(queue, result_mem, CL_TRUE, 0,
iterations * sizeof(cl_int), result_data.data(),
0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < iterations; i++)
{
cl_int error;
const size_t iterations = 4;
clMemWrapper result_mem =
clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * iterations, nullptr, &error);
test_error(error, "clCreateBuffer failed");
const cl_int pattern_base = 42;
for (size_t i = 0; i < iterations; i++)
{
const cl_int pattern = pattern_base + i;
cl_int error = clCommandFillBufferKHR(
command_buffer, nullptr, nullptr, in_mem, &pattern,
sizeof(cl_int), 0, data_size(), 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandFillBufferKHR failed");
error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr,
&num_elements, nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
const size_t result_offset = i * sizeof(cl_int);
error = clCommandCopyBufferKHR(
command_buffer, nullptr, nullptr, out_mem, result_mem, 0,
result_offset, sizeof(cl_int), 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandCopyBufferKHR failed");
}
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> result_data(num_elements);
error = clEnqueueReadBuffer(queue, result_mem, CL_TRUE, 0,
iterations * sizeof(cl_int),
result_data.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < iterations; i++)
{
const cl_int ref = pattern_base + i;
CHECK_VERIFICATION_ERROR(ref, result_data[i], i);
}
return CL_SUCCESS;
}
};
// Test flushing the command-queue between command-buffer enqueues
struct ExplicitFlushTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
const cl_int pattern_A = 42;
error = clEnqueueFillBuffer(queue, in_mem, &pattern_A, sizeof(cl_int),
0, data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clFlush(queue);
test_error(error, "clFlush failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> output_data_A(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
output_data_A.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
const cl_int pattern_B = 0xA;
error = clEnqueueFillBuffer(queue, in_mem, &pattern_B, sizeof(cl_int),
0, data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clFlush(queue);
test_error(error, "clFlush failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
error = clFlush(queue);
test_error(error, "clFlush failed");
std::vector<cl_int> output_data_B(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
output_data_B.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
error = clFinish(queue);
test_error(error, "clFinish failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(pattern_A, output_data_A[i], i);
CHECK_VERIFICATION_ERROR(pattern_B, output_data_B[i], i);
}
return CL_SUCCESS;
const cl_int ref = pattern_base + i;
CHECK_VERIFICATION_ERROR(ref, result_data[i], i);
}
bool Skip() override
{
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
}
};
// Test enqueueing a command-buffer twice separated by another enqueue operation
struct InterleavedEnqueueTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override
{
cl_int error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
cl_int pattern = 42;
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
pattern = 0xABCD;
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0,
nullptr, nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
error = clEnqueueCopyBuffer(queue, in_mem, out_mem, 0, 0, data_size(),
0, nullptr, nullptr);
test_error(error, "clEnqueueCopyBuffer failed");
std::vector<cl_int> output_data(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_data.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(pattern, output_data[i], i);
}
return CL_SUCCESS;
}
bool Skip() override
{
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
}
};
} // anonymous namespace
int test_multi_flag_creation(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return MakeAndRunTest<MultiFlagCreationTest>(device, context, queue,
num_elements);
return CL_SUCCESS;
}
int test_single_ndrange(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
cl_int ExplicitFlushTest::Run()
{
return MakeAndRunTest<BasicEnqueueTest>(device, context, queue,
num_elements);
cl_int error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
const cl_int pattern_A = 42;
error = clEnqueueFillBuffer(queue, in_mem, &pattern_A, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clFlush(queue);
test_error(error, "clFlush failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
std::vector<cl_int> output_data_A(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
output_data_A.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
const cl_int pattern_B = 0xA;
error = clEnqueueFillBuffer(queue, in_mem, &pattern_B, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clFlush(queue);
test_error(error, "clFlush failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
error = clFlush(queue);
test_error(error, "clFlush failed");
std::vector<cl_int> output_data_B(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_FALSE, 0, data_size(),
output_data_B.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
error = clFinish(queue);
test_error(error, "clFinish failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(pattern_A, output_data_A[i], i);
CHECK_VERIFICATION_ERROR(pattern_B, output_data_B[i], i);
}
return CL_SUCCESS;
}
int test_interleaved_enqueue(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
bool ExplicitFlushTest::Skip()
{
return MakeAndRunTest<InterleavedEnqueueTest>(device, context, queue,
num_elements);
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
}
int test_mixed_commands(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
cl_int InterleavedEnqueueTest::Run()
{
return MakeAndRunTest<MixedCommandsTest>(device, context, queue,
num_elements);
cl_int error = clCommandNDRangeKernelKHR(
command_buffer, nullptr, nullptr, kernel, 1, nullptr, &num_elements,
nullptr, 0, nullptr, nullptr, nullptr);
test_error(error, "clCommandNDRangeKernelKHR failed");
error = clFinalizeCommandBufferKHR(command_buffer);
test_error(error, "clFinalizeCommandBufferKHR failed");
cl_int pattern = 42;
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
pattern = 0xABCD;
error = clEnqueueFillBuffer(queue, in_mem, &pattern, sizeof(cl_int), 0,
data_size(), 0, nullptr, nullptr);
test_error(error, "clEnqueueFillBuffer failed");
error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
nullptr);
test_error(error, "clEnqueueCommandBufferKHR failed");
error = clEnqueueCopyBuffer(queue, in_mem, out_mem, 0, 0, data_size(), 0,
nullptr, nullptr);
test_error(error, "clEnqueueCopyBuffer failed");
std::vector<cl_int> output_data(num_elements);
error = clEnqueueReadBuffer(queue, out_mem, CL_TRUE, 0, data_size(),
output_data.data(), 0, nullptr, nullptr);
test_error(error, "clEnqueueReadBuffer failed");
for (size_t i = 0; i < num_elements; i++)
{
CHECK_VERIFICATION_ERROR(pattern, output_data[i], i);
}
return CL_SUCCESS;
}
int test_explicit_flush(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
bool InterleavedEnqueueTest::Skip()
{
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
num_elements);
return BasicCommandBufferTest::Skip() || !simultaneous_use_support;
}

View File

@@ -84,6 +84,49 @@ protected:
clCommandBufferWrapper command_buffer;
};
// Test that CL_COMMAND_BUFFER_FLAGS_KHR bitfield is parsed correctly when
// multiple flags are set.
struct MultiFlagCreationTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override;
};
// Test enqueuing a command-buffer containing a single NDRange command once
struct BasicEnqueueTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override;
};
// Test enqueuing a command-buffer containing multiple command, including
// operations other than NDRange kernel execution.
struct MixedCommandsTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override;
};
// Test flushing the command-queue between command-buffer enqueues
struct ExplicitFlushTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override;
bool Skip() override;
};
// Test enqueueing a command-buffer twice separated by another enqueue operation
struct InterleavedEnqueueTest : public BasicCommandBufferTest
{
using BasicCommandBufferTest::BasicCommandBufferTest;
cl_int Run() override;
bool Skip() override;
};
template <class T>
int MakeAndRunTest(cl_device_id device, cl_context context,

View File

@@ -0,0 +1,46 @@
//
// Copyright (c) 2025 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 "basic_command_buffer.h"
REGISTER_TEST(multi_flag_creation)
{
return MakeAndRunTest<MultiFlagCreationTest>(device, context, queue,
num_elements);
}
REGISTER_TEST(single_ndrange)
{
return MakeAndRunTest<BasicEnqueueTest>(device, context, queue,
num_elements);
}
REGISTER_TEST(interleaved_enqueue)
{
return MakeAndRunTest<InterleavedEnqueueTest>(device, context, queue,
num_elements);
}
REGISTER_TEST(mixed_commands)
{
return MakeAndRunTest<MixedCommandsTest>(device, context, queue,
num_elements);
}
REGISTER_TEST(explicit_flush)
{
return MakeAndRunTest<ExplicitFlushTest>(device, context, queue,
num_elements);
}

View File

@@ -12,43 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "procs.h"
#include "harness/testHarness.h"
test_definition test_list[] = {
ADD_TEST(mutable_command_info_device_query),
ADD_TEST(mutable_command_info_buffer),
ADD_TEST(mutable_command_properties_array),
ADD_TEST(mutable_command_kernel),
ADD_TEST(mutable_command_dimensions),
ADD_TEST(mutable_command_info_type),
ADD_TEST(mutable_command_info_queue),
ADD_TEST(mutable_command_info_global_work_offset),
ADD_TEST(mutable_command_info_local_work_size),
ADD_TEST(mutable_command_info_global_work_size),
ADD_TEST(mutable_command_full_dispatch),
ADD_TEST(mutable_command_overwrite_update),
ADD_TEST(mutable_command_multiple_dispatches),
ADD_TEST(mutable_command_iterative_arg_update),
ADD_TEST(mutable_dispatch_image_1d_arguments),
ADD_TEST(mutable_dispatch_image_2d_arguments),
ADD_TEST(mutable_dispatch_out_of_order),
ADD_TEST(mutable_dispatch_simultaneous_out_of_order),
ADD_TEST(mutable_dispatch_simultaneous_in_order),
ADD_TEST(mutable_dispatch_simultaneous_cross_queue),
ADD_TEST(mutable_dispatch_global_size),
ADD_TEST(mutable_dispatch_local_size),
ADD_TEST(mutable_dispatch_global_offset),
ADD_TEST(mutable_dispatch_svm_arguments),
ADD_TEST(mutable_dispatch_local_arguments),
ADD_TEST(mutable_dispatch_global_arguments),
ADD_TEST(mutable_dispatch_pod_arguments),
ADD_TEST(mutable_dispatch_null_arguments),
ADD_TEST(command_buffer_with_no_additional_work_groups),
ADD_TEST(ndrange_with_no_additional_work_groups),
ADD_TEST(ndrange_command_buffer_with_no_additional_work_groups),
};
int main(int argc, const char *argv[])
{
// A device may report the required properties of a queue that
@@ -57,7 +22,9 @@ int main(int argc, const char *argv[])
// for this in the tests themselves, rather than here, where we have a
// device to query.
const cl_command_queue_properties queue_properties = 0;
return runTestHarnessWithCheck(argc, argv, ARRAY_SIZE(test_list), test_list,
return runTestHarnessWithCheck(argc, argv,
test_registry::getInstance().num_tests(),
test_registry::getInstance().definitions(),
false, queue_properties, nullptr);
return 0;
}

View File

@@ -826,44 +826,31 @@ struct MutableDispatchSVMArguments : public MutableDispatchArgumentsTest
}
int test_mutable_dispatch_local_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_local_arguments)
{
return MakeAndRunTest<MutableDispatchLocalArguments>(device, context, queue,
num_elements);
}
int test_mutable_dispatch_global_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_global_arguments)
{
return MakeAndRunTest<MutableDispatchGlobalArguments>(device, context,
queue, num_elements);
}
int test_mutable_dispatch_pod_arguments(cl_device_id device, cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_pod_arguments)
{
return MakeAndRunTest<MutableDispatchPODArguments>(device, context, queue,
num_elements);
}
int test_mutable_dispatch_null_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_null_arguments)
{
return MakeAndRunTest<MutableDispatchNullArguments>(device, context, queue,
num_elements);
}
int test_mutable_dispatch_svm_arguments(cl_device_id device, cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_svm_arguments)
{
return MakeAndRunTest<MutableDispatchSVMArguments>(device, context, queue,
num_elements);

View File

@@ -492,8 +492,7 @@ struct MutableCommandFullDispatch : InfoMutableCommandBufferTest
}
int test_mutable_command_full_dispatch(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_command_full_dispatch)
{
return MakeAndRunTest<MutableCommandFullDispatch>(device, context, queue,
num_elements);

View File

@@ -160,9 +160,7 @@ struct MutableDispatchGlobalOffset : InfoMutableCommandBufferTest
cl_mutable_command_khr command = nullptr;
};
int test_mutable_dispatch_global_offset(cl_device_id device, cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_global_offset)
{
return MakeAndRunTest<MutableDispatchGlobalOffset>(device, context, queue,

View File

@@ -159,8 +159,7 @@ struct MutableDispatchGlobalSize : public InfoMutableCommandBufferTest
cl_mutable_command_khr command = nullptr;
};
int test_mutable_dispatch_global_size(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_dispatch_global_size)
{
return MakeAndRunTest<MutableDispatchGlobalSize>(device, context, queue,
num_elements);

View File

@@ -412,19 +412,13 @@ struct MutableDispatchImage2DArguments : public BasicMutableCommandBufferTest
cl_mutable_command_khr command = nullptr;
};
int test_mutable_dispatch_image_1d_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_image_1d_arguments)
{
return MakeAndRunTest<MutableDispatchImage1DArguments>(device, context,
queue, num_elements);
}
int test_mutable_dispatch_image_2d_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_image_2d_arguments)
{
return MakeAndRunTest<MutableDispatchImage2DArguments>(device, context,
queue, num_elements);

View File

@@ -16,7 +16,6 @@
#include <extensionHelpers.h>
#include "typeWrappers.h"
#include "procs.h"
#include "testHarness.h"
#include <vector>
#include <iostream>
@@ -441,76 +440,56 @@ struct InfoLocalWorkSize : public InfoMutableCommandBufferTest
size_t test_local_work_size = 0;
};
int test_mutable_command_info_device_query(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_info_device_query)
{
return MakeAndRunTest<InfoDeviceQuery>(device, context, queue,
num_elements);
}
int test_mutable_command_info_buffer(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_command_info_buffer)
{
return MakeAndRunTest<InfoBuffer>(device, context, queue, num_elements);
}
int test_mutable_command_properties_array(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_properties_array)
{
return MakeAndRunTest<PropertiesArray>(device, context, queue,
num_elements);
}
int test_mutable_command_kernel(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_command_kernel)
{
return MakeAndRunTest<Kernel>(device, context, queue, num_elements);
}
int test_mutable_command_dimensions(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_command_dimensions)
{
return MakeAndRunTest<Dimensions>(device, context, queue, num_elements);
}
int test_mutable_command_info_type(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_command_info_type)
{
return MakeAndRunTest<InfoType>(device, context, queue, num_elements);
}
int test_mutable_command_info_queue(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_command_info_queue)
{
return MakeAndRunTest<InfoQueue>(device, context, queue, num_elements);
}
int test_mutable_command_info_global_work_offset(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_info_global_work_offset)
{
return MakeAndRunTest<InfoGlobalWorkOffset>(device, context, queue,
num_elements);
}
int test_mutable_command_info_global_work_size(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_info_global_work_size)
{
return MakeAndRunTest<InfoGlobalWorkSize>(device, context, queue,
num_elements);
}
int test_mutable_command_info_local_work_size(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_info_local_work_size)
{
return MakeAndRunTest<InfoLocalWorkSize>(device, context, queue,
num_elements);

View File

@@ -212,10 +212,7 @@ struct IterativeArgUpdateDispatch : BasicMutableCommandBufferTest
}
int test_mutable_command_iterative_arg_update(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_iterative_arg_update)
{
return MakeAndRunTest<IterativeArgUpdateDispatch>(device, context, queue,
num_elements);

View File

@@ -16,7 +16,6 @@
#include <extensionHelpers.h>
#include "typeWrappers.h"
#include "procs.h"
#include "testHarness.h"
#include "mutable_command_basic.h"
#include <vector>
@@ -166,8 +165,7 @@ struct MutableDispatchLocalSize : public InfoMutableCommandBufferTest
cl_mutable_command_khr command = nullptr;
};
int test_mutable_dispatch_local_size(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_dispatch_local_size)
{
return MakeAndRunTest<MutableDispatchLocalSize>(device, context, queue,
num_elements);

View File

@@ -207,10 +207,7 @@ struct MultipleCommandsDispatch : BasicMutableCommandBufferTest
}
int test_mutable_command_multiple_dispatches(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_multiple_dispatches)
{
return MakeAndRunTest<MultipleCommandsDispatch>(device, context, queue,
num_elements);

View File

@@ -215,10 +215,7 @@ struct OverwriteUpdateDispatch : BasicMutableCommandBufferTest
}
int test_mutable_command_overwrite_update(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_command_overwrite_update)
{
return MakeAndRunTest<OverwriteUpdateDispatch>(device, context, queue,
num_elements);

View File

@@ -605,35 +605,25 @@ struct CrossQueueSimultaneousMutableDispatchTest
} // anonymous namespace
int test_mutable_dispatch_out_of_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(mutable_dispatch_out_of_order)
{
return MakeAndRunTest<SimultaneousMutableDispatchTest<false, true>>(
device, context, queue, num_elements);
}
int test_mutable_dispatch_simultaneous_out_of_order(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_simultaneous_out_of_order)
{
return MakeAndRunTest<SimultaneousMutableDispatchTest<true, true>>(
device, context, queue, num_elements);
}
int test_mutable_dispatch_simultaneous_in_order(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_simultaneous_in_order)
{
return MakeAndRunTest<SimultaneousMutableDispatchTest<true, false>>(
device, context, queue, num_elements);
}
int test_mutable_dispatch_simultaneous_cross_queue(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(mutable_dispatch_simultaneous_cross_queue)
{
return MakeAndRunTest<CrossQueueSimultaneousMutableDispatchTest>(
device, context, queue, num_elements);

View File

@@ -284,29 +284,21 @@ struct MutableDispatchWorkGroups : public BasicMutableCommandBufferTest
const size_t sizeToAllocate = 64 * sizeof(cl_int);
};
int test_command_buffer_with_no_additional_work_groups(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(command_buffer_with_no_additional_work_groups)
{
return MakeAndRunTest<MutableDispatchWorkGroups<0>>(device, context, queue,
num_elements);
}
int test_ndrange_with_no_additional_work_groups(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(ndrange_with_no_additional_work_groups)
{
return MakeAndRunTest<MutableDispatchWorkGroups<1>>(device, context, queue,
num_elements);
}
int test_ndrange_command_buffer_with_no_additional_work_groups(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
REGISTER_TEST(ndrange_command_buffer_with_no_additional_work_groups)
{
return MakeAndRunTest<MutableDispatchWorkGroups<2>>(device, context, queue,

View File

@@ -1,143 +0,0 @@
//
// Copyright (c) 2023 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 CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_PROCS_H
#define CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_PROCS_H
#include <CL/cl.h>
// Basic mutable dispatch tests
extern int test_mutable_command_info_device_query(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_info_buffer(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_info_type(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_info_queue(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_properties_array(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_kernel(cl_device_id device, cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_dimensions(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_info_global_work_offset(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_info_local_work_size(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_info_global_work_size(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_image_1d_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_image_2d_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_global_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_local_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_pod_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_null_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_svm_arguments(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_out_of_order(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_simultaneous_out_of_order(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_simultaneous_in_order(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_simultaneous_cross_queue(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_global_size(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_local_size(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_dispatch_global_offset(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_full_dispatch(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_overwrite_update(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_multiple_dispatches(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_mutable_command_iterative_arg_update(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_command_buffer_with_no_additional_work_groups(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
extern int test_ndrange_with_no_additional_work_groups(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_ndrange_command_buffer_with_no_additional_work_groups(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements);
#endif /*_CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_PROCS_H*/

View File

@@ -15,7 +15,6 @@
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
#include <thread>
@@ -823,10 +822,7 @@ struct CommandBufferEventSync : public BasicCommandBufferTest
//--------------------------------------------------------------------------
// return-events test cases for regular queue
int test_regular_wait_for_command_buffer(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(regular_wait_for_command_buffer)
{
int status = TEST_PASS;
// The approach here is that test scenario which involves out-of-order
@@ -848,10 +844,7 @@ int test_regular_wait_for_command_buffer(cl_device_id device,
return status;
}
int test_command_buffer_wait_for_command_buffer(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(command_buffer_wait_for_command_buffer)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -871,10 +864,7 @@ int test_command_buffer_wait_for_command_buffer(cl_device_id device,
return status;
}
int test_command_buffer_wait_for_sec_command_buffer(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(command_buffer_wait_for_sec_command_buffer)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -894,8 +884,7 @@ int test_command_buffer_wait_for_sec_command_buffer(cl_device_id device,
return status;
}
int test_return_event_callback(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(return_event_callback)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -913,8 +902,7 @@ int test_return_event_callback(cl_device_id device, cl_context context,
return status;
}
int test_clwaitforevents_single(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(clwaitforevents_single)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -934,8 +922,7 @@ int test_clwaitforevents_single(cl_device_id device, cl_context context,
return status;
}
int test_clwaitforevents(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(clwaitforevents)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -953,10 +940,7 @@ int test_clwaitforevents(cl_device_id device, cl_context context,
return status;
}
int test_command_buffer_wait_for_regular(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(command_buffer_wait_for_regular)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -976,8 +960,7 @@ int test_command_buffer_wait_for_regular(cl_device_id device,
return status;
}
int test_wait_for_sec_queue_event(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(wait_for_sec_queue_event)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -1000,8 +983,7 @@ int test_wait_for_sec_queue_event(cl_device_id device, cl_context context,
//--------------------------------------------------------------------------
// user-events test cases
int test_user_event_wait(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(user_event_wait)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -1019,8 +1001,7 @@ int test_user_event_wait(cl_device_id device, cl_context context,
return status;
}
int test_user_events_wait(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(user_events_wait)
{
int status = TEST_PASS;
// out-of-order command queue test
@@ -1038,8 +1019,7 @@ int test_user_events_wait(cl_device_id device, cl_context context,
return status;
}
int test_user_event_callback(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(user_event_callback)
{
int status = TEST_PASS;
// out-of-order command queue test

View File

@@ -14,7 +14,6 @@
// limitations under the License.
#include "basic_command_buffer.h"
#include "procs.h"
namespace {
@@ -71,15 +70,13 @@ struct FinalizeEmpty : public BasicCommandBufferTest
};
} // anonymous namespace
int test_finalize_invalid(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(finalize_invalid)
{
return MakeAndRunTest<FinalizeInvalid>(device, context, queue,
num_elements);
}
int test_finalize_empty(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(finalize_empty)
{
return MakeAndRunTest<FinalizeEmpty>(device, context, queue, num_elements);
}

View File

@@ -15,7 +15,6 @@
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
@@ -374,40 +373,35 @@ struct CommandBufferGetCommandBufferInfo : public BasicCommandBufferTest
} // anonymous namespace
int test_info_queues(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(info_queues)
{
return MakeAndRunTest<
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_QUEUES>>(
device, context, queue, num_elements);
}
int test_info_ref_count(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(info_ref_count)
{
return MakeAndRunTest<
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_REF_COUNT>>(
device, context, queue, num_elements);
}
int test_info_state(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(info_state)
{
return MakeAndRunTest<
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_STATE>>(
device, context, queue, num_elements);
}
int test_info_prop_array(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(info_prop_array)
{
return MakeAndRunTest<
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_PROP_ARRAY>>(
device, context, queue, num_elements);
}
int test_info_context(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(info_context)
{
return MakeAndRunTest<
CommandBufferGetCommandBufferInfo<CombufInfoTestMode::CITM_CONTEXT>>(

View File

@@ -15,7 +15,6 @@
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
@@ -337,15 +336,13 @@ struct OutOfOrderTest : public BasicCommandBufferTest
} // anonymous namespace
int test_out_of_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(out_of_order)
{
return MakeAndRunTest<OutOfOrderTest<false>>(device, context, queue,
num_elements);
}
int test_simultaneous_out_of_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(simultaneous_out_of_order)
{
return MakeAndRunTest<OutOfOrderTest<true>>(device, context, queue,
num_elements);

View File

@@ -17,7 +17,6 @@
#include <harness/os_helpers.h>
#include "basic_command_buffer.h"
#include "procs.h"
#if !defined(_WIN32)
#if defined(__APPLE__)
@@ -524,15 +523,13 @@ struct CommandBufferPrintfTest : public BasicCommandBufferTest
} // anonymous namespace
int test_basic_printf(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(basic_printf)
{
return MakeAndRunTest<CommandBufferPrintfTest<false>>(device, context,
queue, num_elements);
}
int test_simultaneous_printf(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(simultaneous_printf)
{
return MakeAndRunTest<CommandBufferPrintfTest<true>>(device, context, queue,
num_elements);

View File

@@ -15,7 +15,6 @@
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
@@ -357,22 +356,19 @@ struct CommandBufferSubstituteQueueProfiling : public BasicCommandBufferTest
};
} // anonymous namespace
int test_basic_profiling(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(basic_profiling)
{
return MakeAndRunTest<CommandBufferProfiling<false>>(device, context, queue,
num_elements);
}
int test_simultaneous_profiling(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(simultaneous_profiling)
{
return MakeAndRunTest<CommandBufferProfiling<true>>(device, context, queue,
num_elements);
}
int test_substitute_queue_profiling(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(substitute_queue_profiling)
{
return MakeAndRunTest<CommandBufferSubstituteQueueProfiling>(
device, context, queue, num_elements);

View File

@@ -14,7 +14,6 @@
// limitations under the License.
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
@@ -396,38 +395,31 @@ struct QueueOrderTest : public BasicCommandBufferTest
};
} // anonymous namespace
int test_queue_substitution(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(queue_substitution)
{
return MakeAndRunTest<SubstituteQueueTest<false, false>>(
device, context, queue, num_elements);
}
int test_properties_queue_substitution(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(properties_queue_substitution)
{
return MakeAndRunTest<SubstituteQueueTest<true, false>>(
device, context, queue, num_elements);
}
int test_simultaneous_queue_substitution(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(simultaneous_queue_substitution)
{
return MakeAndRunTest<SubstituteQueueTest<false, true>>(
device, context, queue, num_elements);
}
int test_queue_substitute_in_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(queue_substitute_in_order)
{
return MakeAndRunTest<QueueOrderTest<false>>(device, context, queue,
num_elements);
}
int test_queue_substitute_out_of_order(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(queue_substitute_out_of_order)
{
return MakeAndRunTest<QueueOrderTest<true>>(device, context, queue,
num_elements);

View File

@@ -15,7 +15,6 @@
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
@@ -306,15 +305,13 @@ struct CommandBufferSetKernelArg : public BasicCommandBufferTest
} // anonymous namespace
int test_basic_set_kernel_arg(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(basic_set_kernel_arg)
{
return MakeAndRunTest<CommandBufferSetKernelArg<false>>(
device, context, queue, num_elements);
}
int test_pending_set_kernel_arg(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(pending_set_kernel_arg)
{
return MakeAndRunTest<CommandBufferSetKernelArg<true>>(device, context,
queue, num_elements);

View File

@@ -14,7 +14,6 @@
// limitations under the License.
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
@@ -146,8 +145,7 @@ struct BarrierWithWaitListKHR : public BasicCommandBufferTest
};
int test_barrier_wait_list(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(barrier_wait_list)
{
return MakeAndRunTest<BarrierWithWaitListKHR>(device, context, queue,
num_elements);

View File

@@ -16,7 +16,6 @@
#include "basic_command_buffer.h"
#include "svm_command_basic.h"
#include "harness/typeWrappers.h"
#include "procs.h"
#include <vector>
@@ -563,42 +562,36 @@ struct CopyBufferRectKHR : public BasicCommandBufferTest
};
};
int test_copy_image(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(copy_image)
{
return MakeAndRunTest<CopyImageKHR>(device, context, queue, num_elements);
}
int test_copy_buffer(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(copy_buffer)
{
return MakeAndRunTest<CopyBufferKHR>(device, context, queue, num_elements);
}
int test_copy_svm_buffer(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(copy_svm_buffer)
{
return MakeAndRunTest<CopySVMBufferKHR>(device, context, queue,
num_elements);
}
int test_copy_buffer_to_image(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(copy_buffer_to_image)
{
return MakeAndRunTest<CopyBufferToImageKHR>(device, context, queue,
num_elements);
}
int test_copy_image_to_buffer(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(copy_image_to_buffer)
{
return MakeAndRunTest<CopyImageToBufferKHR>(device, context, queue,
num_elements);
}
int test_copy_buffer_rect(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(copy_buffer_rect)
{
return MakeAndRunTest<CopyBufferRectKHR>(device, context, queue,
num_elements);

View File

@@ -14,7 +14,6 @@
// limitations under the License.
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
namespace {
@@ -222,33 +221,28 @@ struct ReferenceCount : public BasicCommandBufferTest
};
};
int test_event_info_command_type(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(event_info_command_type)
{
return MakeAndRunTest<CommandType>(device, context, queue, num_elements);
}
int test_event_info_command_queue(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(event_info_command_queue)
{
return MakeAndRunTest<CommandQueue>(device, context, queue, num_elements);
}
int test_event_info_context(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(event_info_context)
{
return MakeAndRunTest<Context>(device, context, queue, num_elements);
}
int test_event_info_execution_status(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(event_info_execution_status)
{
return MakeAndRunTest<ExecutionStatus>(device, context, queue,
num_elements);
}
int test_event_info_reference_count(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(event_info_reference_count)
{
return MakeAndRunTest<ReferenceCount>(device, context, queue, num_elements);
}

View File

@@ -16,7 +16,6 @@
#include "basic_command_buffer.h"
#include "svm_command_basic.h"
#include "harness/typeWrappers.h"
#include "procs.h"
#include <vector>
@@ -230,22 +229,19 @@ struct FillSVMBufferKHR : public BasicSVMCommandBufferTest
};
};
int test_fill_buffer(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(fill_buffer)
{
return MakeAndRunTest<FillBufferKHR>(device, context, queue, num_elements);
}
int test_fill_svm_buffer(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(fill_svm_buffer)
{
return MakeAndRunTest<FillSVMBufferKHR>(device, context, queue,
num_elements);
}
int test_fill_image(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
REGISTER_TEST(fill_image)
{
return MakeAndRunTest<FillImageKHR>(device, context, queue, num_elements);
}

View File

@@ -1,3 +1,4 @@
//
// Copyright (c) 2024 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -11,17 +12,25 @@
// 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 CL_KHR_KERNEL_CLOCK_PROCS_H
#define CL_KHR_KERNEL_CLOCK_PROCS_H
#include <CL/cl.h>
#pragma once
int test_device_scope(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements);
int test_workgroup_scope(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements);
int test_subgroup_scope(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements);
#include "basic_command_buffer.h"
#include <type_traits>
#endif /*CL_KHR_KERNEL_CLOCK_PROCS_H*/
template <class TBase>
struct CommandBufferWithImmutableMemoryObjectsTest : public TBase
{
using TBase::TBase;
static_assert(std::is_base_of<BasicCommandBufferTest, TBase>::value,
"TBase must be BasicCommandBufferTest or a derived class");
bool Skip() override
{
bool is_immutable_memory_objects_supported = is_extension_available(
BasicCommandBufferTest::device, "cl_ext_immutable_memory_objects");
return !is_immutable_memory_objects_supported || TBase::Skip();
}
};

View File

@@ -12,157 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "procs.h"
#include "harness/testHarness.h"
test_definition test_list[] = {
ADD_TEST(multi_flag_creation),
ADD_TEST(single_ndrange),
ADD_TEST(interleaved_enqueue),
ADD_TEST(mixed_commands),
ADD_TEST(explicit_flush),
ADD_TEST(out_of_order),
ADD_TEST(simultaneous_out_of_order),
ADD_TEST(info_queues),
ADD_TEST(info_ref_count),
ADD_TEST(info_state),
ADD_TEST(info_prop_array),
ADD_TEST(info_context),
ADD_TEST(basic_profiling),
ADD_TEST(simultaneous_profiling),
ADD_TEST(substitute_queue_profiling),
ADD_TEST(regular_wait_for_command_buffer),
ADD_TEST(command_buffer_wait_for_command_buffer),
ADD_TEST(command_buffer_wait_for_sec_command_buffer),
ADD_TEST(return_event_callback),
ADD_TEST(clwaitforevents_single),
ADD_TEST(clwaitforevents),
ADD_TEST(command_buffer_wait_for_regular),
ADD_TEST(wait_for_sec_queue_event),
ADD_TEST(user_event_wait),
ADD_TEST(user_events_wait),
ADD_TEST(user_event_callback),
ADD_TEST(queue_substitution),
ADD_TEST(properties_queue_substitution),
ADD_TEST(simultaneous_queue_substitution),
ADD_TEST(queue_substitute_in_order),
ADD_TEST(queue_substitute_out_of_order),
ADD_TEST(fill_image),
ADD_TEST(fill_buffer),
ADD_TEST(fill_svm_buffer),
ADD_TEST(copy_image),
ADD_TEST(copy_buffer),
ADD_TEST(copy_svm_buffer),
ADD_TEST(copy_buffer_to_image),
ADD_TEST(copy_image_to_buffer),
ADD_TEST(copy_buffer_rect),
ADD_TEST(barrier_wait_list),
ADD_TEST(basic_printf),
ADD_TEST(simultaneous_printf),
ADD_TEST(basic_set_kernel_arg),
ADD_TEST(pending_set_kernel_arg),
ADD_TEST(event_info_command_type),
ADD_TEST(event_info_command_queue),
ADD_TEST(event_info_execution_status),
ADD_TEST(event_info_context),
ADD_TEST(event_info_reference_count),
ADD_TEST(finalize_invalid),
ADD_TEST(finalize_empty),
// Command-buffer negative tests
ADD_TEST(negative_retain_command_buffer_invalid_command_buffer),
ADD_TEST(negative_release_command_buffer_invalid_command_buffer),
ADD_TEST(negative_finalize_command_buffer_invalid_command_buffer),
ADD_TEST(negative_finalize_command_buffer_not_recording_state),
ADD_TEST(negative_command_buffer_command_fill_buffer_queue_not_null),
ADD_TEST(negative_command_buffer_command_fill_buffer_context_not_same),
ADD_TEST(
negative_command_buffer_command_fill_buffer_sync_points_null_or_num_zero),
ADD_TEST(
negative_command_buffer_command_fill_buffer_invalid_command_buffer),
ADD_TEST(
negative_command_buffer_command_fill_buffer_finalized_command_buffer),
ADD_TEST(
negative_command_buffer_command_fill_buffer_mutable_handle_not_null),
ADD_TEST(negative_command_buffer_command_fill_image_queue_not_null),
ADD_TEST(negative_command_buffer_command_fill_image_context_not_same),
ADD_TEST(
negative_command_buffer_command_fill_image_sync_points_null_or_num_zero),
ADD_TEST(negative_command_buffer_command_fill_image_invalid_command_buffer),
ADD_TEST(
negative_command_buffer_command_fill_image_finalized_command_buffer),
ADD_TEST(
negative_command_buffer_command_fill_image_mutable_handle_not_null),
ADD_TEST(negative_create_command_buffer_num_queues),
ADD_TEST(negative_create_command_buffer_null_queues),
ADD_TEST(negative_create_command_buffer_repeated_properties),
ADD_TEST(negative_create_command_buffer_not_supported_properties),
ADD_TEST(negative_command_ndrange_queue_not_null),
ADD_TEST(negative_command_ndrange_kernel_with_different_context),
ADD_TEST(negative_command_ndrange_kernel_sync_points_null_or_num_zero),
ADD_TEST(negative_command_ndrange_kernel_invalid_command_buffer),
ADD_TEST(negative_command_ndrange_kernel_invalid_properties),
ADD_TEST(negative_command_ndrange_kernel_command_buffer_finalized),
ADD_TEST(negative_command_ndrange_kernel_mutable_handle_not_null),
ADD_TEST(negative_command_ndrange_kernel_not_support_printf),
ADD_TEST(negative_command_ndrange_kernel_with_enqueue_call),
ADD_TEST(negative_command_buffer_command_copy_buffer_queue_not_null),
ADD_TEST(negative_command_buffer_command_copy_buffer_different_contexts),
ADD_TEST(
negative_command_buffer_command_copy_buffer_sync_points_null_or_num_zero),
ADD_TEST(
negative_command_buffer_command_copy_buffer_invalid_command_buffer),
ADD_TEST(
negative_command_buffer_command_copy_buffer_finalized_command_buffer),
ADD_TEST(
negative_command_buffer_command_copy_buffer_mutable_handle_not_null),
ADD_TEST(negative_command_buffer_command_copy_image_queue_not_null),
ADD_TEST(negative_command_buffer_command_copy_image_different_contexts),
ADD_TEST(
negative_command_buffer_command_copy_image_sync_points_null_or_num_zero),
ADD_TEST(negative_command_buffer_command_copy_image_invalid_command_buffer),
ADD_TEST(
negative_command_buffer_command_copy_image_finalized_command_buffer),
ADD_TEST(
negative_command_buffer_command_copy_image_mutable_handle_not_null),
ADD_TEST(negative_get_command_buffer_info_invalid_command_buffer),
ADD_TEST(negative_get_command_buffer_info_not_supported_param_name),
ADD_TEST(negative_get_command_buffer_info_queues),
ADD_TEST(negative_get_command_buffer_info_ref_count),
ADD_TEST(negative_get_command_buffer_info_state),
ADD_TEST(negative_get_command_buffer_info_prop_array),
ADD_TEST(negative_get_command_buffer_info_context),
ADD_TEST(negative_command_buffer_command_svm_queue_not_null),
ADD_TEST(negative_command_buffer_command_svm_sync_points_null_or_num_zero),
ADD_TEST(negative_command_buffer_command_svm_invalid_command_buffer),
ADD_TEST(negative_command_buffer_command_svm_finalized_command_buffer),
ADD_TEST(negative_command_buffer_command_svm_mutable_handle_not_null),
ADD_TEST(negative_command_buffer_copy_image_queue_not_null),
ADD_TEST(negative_command_buffer_copy_image_context_not_same),
ADD_TEST(negative_command_buffer_copy_image_sync_points_null_or_num_zero),
ADD_TEST(negative_command_buffer_copy_image_invalid_command_buffer),
ADD_TEST(negative_command_buffer_copy_image_finalized_command_buffer),
ADD_TEST(negative_command_buffer_copy_image_mutable_handle_not_null),
ADD_TEST(negative_command_buffer_barrier_not_null_queue),
ADD_TEST(negative_command_buffer_barrier_invalid_command_buffer),
ADD_TEST(negative_command_buffer_barrier_buffer_finalized),
ADD_TEST(negative_command_buffer_barrier_mutable_handle_not_null),
ADD_TEST(negative_command_buffer_barrier_sync_points_null_or_num_zero),
ADD_TEST(negative_enqueue_command_buffer_invalid_command_buffer),
ADD_TEST(negative_enqueue_command_buffer_not_finalized),
ADD_TEST(
negative_enqueue_command_buffer_without_simultaneous_no_pending_state),
ADD_TEST(negative_enqueue_command_buffer_null_queues_num_queues),
ADD_TEST(
negative_enqueue_command_buffer_num_queues_not_zero_different_while_buffer_creation),
ADD_TEST(negative_enqueue_command_buffer_not_valid_queue_in_queues),
ADD_TEST(negative_enqueue_queue_with_different_context),
ADD_TEST(negative_enqueue_command_buffer_different_context_than_event),
ADD_TEST(negative_enqueue_event_wait_list_null_or_events_null),
ADD_TEST(negative_enqueue_queue_without_reqd_properties),
ADD_TEST(negative_enqueue_with_unsupported_queue_property),
ADD_TEST(negative_enqueue_inconsistent_device),
};
int main(int argc, const char *argv[])
{
// A device may report the required properties of a queue that
@@ -171,6 +22,8 @@ int main(int argc, const char *argv[])
// for this in the tests themselves, rather than here, where we have a
// device to query.
const cl_command_queue_properties queue_properties = 0;
return runTestHarnessWithCheck(argc, argv, ARRAY_SIZE(test_list), test_list,
return runTestHarnessWithCheck(argc, argv,
test_registry::getInstance().num_tests(),
test_registry::getInstance().definitions(),
false, queue_properties, nullptr);
}

View File

@@ -14,7 +14,6 @@
// limitations under the License.
//
#include "basic_command_buffer.h"
#include "procs.h"
#include <vector>
//--------------------------------------------------------------------------
@@ -159,42 +158,31 @@ struct CommandBufferBarrierSyncPointsNullOrNumZero
};
};
int test_negative_command_buffer_barrier_not_null_queue(cl_device_id device,
cl_context context,
cl_command_queue queue,
int num_elements)
REGISTER_TEST(negative_command_buffer_barrier_not_null_queue)
{
return MakeAndRunTest<CommandBufferBarrierNotNullQueue>(
device, context, queue, num_elements);
}
int test_negative_command_buffer_barrier_invalid_command_buffer(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
REGISTER_TEST(negative_command_buffer_barrier_invalid_command_buffer)
{
return MakeAndRunTest<CommandBufferBarrierInvalidCommandBuffer>(
device, context, queue, num_elements);
}
int test_negative_command_buffer_barrier_buffer_finalized(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
REGISTER_TEST(negative_command_buffer_barrier_buffer_finalized)
{
return MakeAndRunTest<CommandBufferBarrierBufferFinalized>(
device, context, queue, num_elements);
}
int test_negative_command_buffer_barrier_mutable_handle_not_null(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
REGISTER_TEST(negative_command_buffer_barrier_mutable_handle_not_null)
{
return MakeAndRunTest<CommandBufferBarrierMutableHandleNotNull>(
device, context, queue, num_elements);
}
int test_negative_command_buffer_barrier_sync_points_null_or_num_zero(
cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements)
REGISTER_TEST(negative_command_buffer_barrier_sync_points_null_or_num_zero)
{
return MakeAndRunTest<CommandBufferBarrierSyncPointsNullOrNumZero>(
device, context, queue, num_elements);

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