mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-23 07:39:01 +00:00
Synchronise with Khronos-private Gitlab branch
The maintenance of the conformance tests is moving to Github. This commit contains all the changes that have been done in Gitlab since the first public release of the conformance tests. Signed-off-by: Kevin Petit <kevin.petit@arm.com>
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc:<cflags>-xc++
|
||||
<toolset>msvc:<cflags>"/TP"
|
||||
;
|
||||
|
||||
exe test_events
|
||||
: main.c
|
||||
test_event_dependencies.cpp
|
||||
test_events.cpp
|
||||
test_waitlists.cpp
|
||||
;
|
||||
|
||||
install dist
|
||||
: test_events
|
||||
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/events
|
||||
<variant>release:<location>$(DIST)/release/tests/test_conformance/events
|
||||
;
|
||||
project
|
||||
: requirements
|
||||
<toolset>gcc:<cflags>-xc++
|
||||
<toolset>msvc:<cflags>"/TP"
|
||||
;
|
||||
|
||||
exe test_events
|
||||
: main.c
|
||||
test_event_dependencies.cpp
|
||||
test_events.cpp
|
||||
test_waitlists.cpp
|
||||
;
|
||||
|
||||
install dist
|
||||
: test_events
|
||||
: <variant>debug:<location>$(DIST)/debug/tests/test_conformance/events
|
||||
<variant>release:<location>$(DIST)/release/tests/test_conformance/events
|
||||
;
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = main.c \
|
||||
test_events.cpp \
|
||||
test_event_dependencies.cpp \
|
||||
test_userevents.cpp \
|
||||
test_waitlists.cpp \
|
||||
test_callbacks.cpp \
|
||||
action_classes.cpp \
|
||||
test_userevents_multithreaded.cpp \
|
||||
../../test_common/harness/errorHelpers.c \
|
||||
../../test_common/harness/threadTesting.c \
|
||||
../../test_common/harness/testHarness.c \
|
||||
../../test_common/harness/genericThread.cpp \
|
||||
../../test_common/harness/kernelHelpers.c \
|
||||
../../test_common/harness/typeWrappers.cpp \
|
||||
../../test_common/harness/mt19937.c \
|
||||
../../test_common/harness/conversions.c \
|
||||
../../test_common/harness/ThreadPool.c \
|
||||
|
||||
DEFINES = DONT_TEST_GARBAGE_POINTERS
|
||||
|
||||
SOURCES = $(abspath $(SRCS))
|
||||
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
|
||||
LIBPATH += -L.
|
||||
HEADERS =
|
||||
TARGET = test_events
|
||||
INCLUDE =
|
||||
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
|
||||
CC = c++
|
||||
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
|
||||
|
||||
OBJECTS := ${SOURCES:.c=.o}
|
||||
OBJECTS := ${OBJECTS:.cpp=.o}
|
||||
|
||||
TARGETOBJECT =
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(RC_CFLAGS) $(OBJECTS) -o $@ $(LIBPATH) $(LIBRARIES)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
.DEFAULT:
|
||||
@echo The target \"$@\" does not exist in Makefile.
|
||||
ifdef BUILD_WITH_ATF
|
||||
ATF = -framework ATF
|
||||
USE_ATF = -DUSE_ATF
|
||||
endif
|
||||
|
||||
SRCS = main.c \
|
||||
test_events.cpp \
|
||||
test_event_dependencies.cpp \
|
||||
test_userevents.cpp \
|
||||
test_waitlists.cpp \
|
||||
test_callbacks.cpp \
|
||||
action_classes.cpp \
|
||||
test_userevents_multithreaded.cpp \
|
||||
../../test_common/harness/errorHelpers.c \
|
||||
../../test_common/harness/threadTesting.c \
|
||||
../../test_common/harness/testHarness.c \
|
||||
../../test_common/harness/genericThread.cpp \
|
||||
../../test_common/harness/kernelHelpers.c \
|
||||
../../test_common/harness/typeWrappers.cpp \
|
||||
../../test_common/harness/mt19937.c \
|
||||
../../test_common/harness/conversions.c \
|
||||
../../test_common/harness/ThreadPool.c \
|
||||
|
||||
DEFINES = DONT_TEST_GARBAGE_POINTERS
|
||||
|
||||
SOURCES = $(abspath $(SRCS))
|
||||
LIBPATH += -L/System/Library/Frameworks/OpenCL.framework/Libraries
|
||||
LIBPATH += -L.
|
||||
HEADERS =
|
||||
TARGET = test_events
|
||||
INCLUDE =
|
||||
COMPILERFLAGS = -c -Wall -g -Wshorten-64-to-32
|
||||
CC = c++
|
||||
CFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
CXXFLAGS = $(COMPILERFLAGS) ${RC_CFLAGS} ${USE_ATF} $(DEFINES:%=-D%) $(INCLUDE)
|
||||
LIBRARIES = -framework OpenCL -framework OpenGL -framework GLUT -framework AppKit ${ATF}
|
||||
|
||||
OBJECTS := ${SOURCES:.c=.o}
|
||||
OBJECTS := ${OBJECTS:.cpp=.o}
|
||||
|
||||
TARGETOBJECT =
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJECTS)
|
||||
$(CC) $(RC_CFLAGS) $(OBJECTS) -o $@ $(LIBPATH) $(LIBRARIES)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJECTS)
|
||||
|
||||
.DEFAULT:
|
||||
@echo The target \"$@\" does not exist in Makefile.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,326 +1,326 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _action_classes_h
|
||||
#define _action_classes_h
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
// This is a base class from which all actions are born
|
||||
// Note: No actions should actually feed I/O to each other, because then
|
||||
// it would potentially be possible for an implementation to make actions
|
||||
// wait on one another based on their shared I/O, not because of their
|
||||
// wait lists!
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
Action() {}
|
||||
virtual ~Action() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue ) = 0;
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent ) = 0;
|
||||
|
||||
virtual const char * GetName( void ) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
cl_int IGetPreferredImageSize2D( cl_device_id device, size_t &outWidth, size_t &outHeight );
|
||||
cl_int IGetPreferredImageSize3D( cl_device_id device, size_t &outWidth, size_t &outHeight, size_t &outDepth );
|
||||
};
|
||||
|
||||
// Simple NDRangeKernel execution that takes a noticable amount of time
|
||||
class NDRangeKernelAction : public Action
|
||||
{
|
||||
public:
|
||||
NDRangeKernelAction() {}
|
||||
virtual ~NDRangeKernelAction() {}
|
||||
|
||||
size_t mLocalThreads[ 1 ];
|
||||
clMemWrapper mStreams[ 2 ];
|
||||
clProgramWrapper mProgram;
|
||||
clKernelWrapper mKernel;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "NDRangeKernel"; }
|
||||
};
|
||||
|
||||
// Base action for buffer actions
|
||||
class BufferAction : public Action
|
||||
{
|
||||
public:
|
||||
clMemWrapper mBuffer;
|
||||
size_t mSize;
|
||||
void *mOutBuffer;
|
||||
|
||||
BufferAction() { mOutBuffer = NULL; }
|
||||
virtual ~BufferAction() { free( mOutBuffer ); }
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue, bool allocate );
|
||||
};
|
||||
|
||||
class ReadBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
ReadBufferAction() {}
|
||||
virtual ~ReadBufferAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "ReadBuffer"; }
|
||||
};
|
||||
|
||||
class WriteBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
WriteBufferAction() {}
|
||||
virtual ~WriteBufferAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "WriteBuffer"; }
|
||||
};
|
||||
|
||||
class MapBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
MapBufferAction() : mQueue(0) {}
|
||||
|
||||
cl_command_queue mQueue;
|
||||
void *mMappedPtr;
|
||||
|
||||
virtual ~MapBufferAction();
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "MapBuffer"; }
|
||||
};
|
||||
|
||||
class UnmapBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
UnmapBufferAction() {}
|
||||
virtual ~UnmapBufferAction() {}
|
||||
|
||||
void *mMappedPtr;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "UnmapBuffer"; }
|
||||
};
|
||||
|
||||
class ReadImage2DAction : public Action
|
||||
{
|
||||
public:
|
||||
ReadImage2DAction() { mOutput = NULL; }
|
||||
virtual ~ReadImage2DAction() { free( mOutput ); }
|
||||
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight;
|
||||
void *mOutput;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "ReadImage2D"; }
|
||||
};
|
||||
|
||||
class ReadImage3DAction : public Action
|
||||
{
|
||||
public:
|
||||
ReadImage3DAction() { mOutput = NULL; }
|
||||
virtual ~ReadImage3DAction() { free( mOutput ); }
|
||||
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
void *mOutput;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "ReadImage3D"; }
|
||||
};
|
||||
|
||||
class WriteImage2DAction : public Action
|
||||
{
|
||||
public:
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight;
|
||||
void *mOutput;
|
||||
|
||||
WriteImage2DAction() { mOutput = NULL; }
|
||||
virtual ~WriteImage2DAction() { free( mOutput ); }
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "WriteImage2D"; }
|
||||
};
|
||||
|
||||
class WriteImage3DAction : public Action
|
||||
{
|
||||
public:
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
void *mOutput;
|
||||
|
||||
WriteImage3DAction() { mOutput = NULL; }
|
||||
virtual ~WriteImage3DAction() { free( mOutput ); }
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "WriteImage3D"; }
|
||||
};
|
||||
|
||||
class CopyImageAction : public Action
|
||||
{
|
||||
public:
|
||||
CopyImageAction() {}
|
||||
virtual ~CopyImageAction() {}
|
||||
|
||||
clMemWrapper mSrcImage, mDstImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
};
|
||||
|
||||
class CopyImage2Dto2DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage2Dto2DAction() {}
|
||||
virtual ~CopyImage2Dto2DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage2Dto2D"; }
|
||||
};
|
||||
|
||||
class CopyImage2Dto3DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage2Dto3DAction() {}
|
||||
virtual ~CopyImage2Dto3DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage2Dto3D"; }
|
||||
};
|
||||
|
||||
class CopyImage3Dto2DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage3Dto2DAction() {}
|
||||
virtual ~CopyImage3Dto2DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage3Dto2D"; }
|
||||
};
|
||||
|
||||
class CopyImage3Dto3DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage3Dto3DAction() {}
|
||||
virtual ~CopyImage3Dto3DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage3Dto3D"; }
|
||||
};
|
||||
|
||||
class Copy2DImageToBufferAction : public Action
|
||||
{
|
||||
public:
|
||||
Copy2DImageToBufferAction() {}
|
||||
virtual ~Copy2DImageToBufferAction() {}
|
||||
|
||||
clMemWrapper mSrcImage, mDstBuffer;
|
||||
size_t mWidth, mHeight;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "Copy2DImageToBuffer"; }
|
||||
};
|
||||
|
||||
class Copy3DImageToBufferAction : public Action
|
||||
{
|
||||
public:
|
||||
Copy3DImageToBufferAction() {}
|
||||
virtual ~Copy3DImageToBufferAction() {}
|
||||
|
||||
clMemWrapper mSrcImage, mDstBuffer;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "Copy3DImageToBuffer"; }
|
||||
};
|
||||
|
||||
class CopyBufferTo2DImageAction : public Action
|
||||
{
|
||||
public:
|
||||
CopyBufferTo2DImageAction() {}
|
||||
virtual ~CopyBufferTo2DImageAction() {}
|
||||
|
||||
clMemWrapper mSrcBuffer, mDstImage;
|
||||
size_t mWidth, mHeight;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyBufferTo2D"; }
|
||||
};
|
||||
|
||||
class CopyBufferTo3DImageAction : public Action
|
||||
{
|
||||
public:
|
||||
CopyBufferTo3DImageAction() {}
|
||||
virtual ~CopyBufferTo3DImageAction() {}
|
||||
|
||||
clMemWrapper mSrcBuffer, mDstImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyBufferTo3D"; }
|
||||
};
|
||||
|
||||
class MapImageAction : public Action
|
||||
{
|
||||
public:
|
||||
MapImageAction() : mQueue(0) {}
|
||||
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight;
|
||||
void *mMappedPtr;
|
||||
cl_command_queue mQueue;
|
||||
|
||||
virtual ~MapImageAction();
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "MapImage"; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _action_classes_h
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _action_classes_h
|
||||
#define _action_classes_h
|
||||
|
||||
#include "testBase.h"
|
||||
|
||||
// This is a base class from which all actions are born
|
||||
// Note: No actions should actually feed I/O to each other, because then
|
||||
// it would potentially be possible for an implementation to make actions
|
||||
// wait on one another based on their shared I/O, not because of their
|
||||
// wait lists!
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
Action() {}
|
||||
virtual ~Action() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue ) = 0;
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent ) = 0;
|
||||
|
||||
virtual const char * GetName( void ) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
cl_int IGetPreferredImageSize2D( cl_device_id device, size_t &outWidth, size_t &outHeight );
|
||||
cl_int IGetPreferredImageSize3D( cl_device_id device, size_t &outWidth, size_t &outHeight, size_t &outDepth );
|
||||
};
|
||||
|
||||
// Simple NDRangeKernel execution that takes a noticable amount of time
|
||||
class NDRangeKernelAction : public Action
|
||||
{
|
||||
public:
|
||||
NDRangeKernelAction() {}
|
||||
virtual ~NDRangeKernelAction() {}
|
||||
|
||||
size_t mLocalThreads[ 1 ];
|
||||
clMemWrapper mStreams[ 2 ];
|
||||
clProgramWrapper mProgram;
|
||||
clKernelWrapper mKernel;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "NDRangeKernel"; }
|
||||
};
|
||||
|
||||
// Base action for buffer actions
|
||||
class BufferAction : public Action
|
||||
{
|
||||
public:
|
||||
clMemWrapper mBuffer;
|
||||
size_t mSize;
|
||||
void *mOutBuffer;
|
||||
|
||||
BufferAction() { mOutBuffer = NULL; }
|
||||
virtual ~BufferAction() { free( mOutBuffer ); }
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue, bool allocate );
|
||||
};
|
||||
|
||||
class ReadBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
ReadBufferAction() {}
|
||||
virtual ~ReadBufferAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "ReadBuffer"; }
|
||||
};
|
||||
|
||||
class WriteBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
WriteBufferAction() {}
|
||||
virtual ~WriteBufferAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "WriteBuffer"; }
|
||||
};
|
||||
|
||||
class MapBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
MapBufferAction() : mQueue(0) {}
|
||||
|
||||
cl_command_queue mQueue;
|
||||
void *mMappedPtr;
|
||||
|
||||
virtual ~MapBufferAction();
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "MapBuffer"; }
|
||||
};
|
||||
|
||||
class UnmapBufferAction : public BufferAction
|
||||
{
|
||||
public:
|
||||
UnmapBufferAction() {}
|
||||
virtual ~UnmapBufferAction() {}
|
||||
|
||||
void *mMappedPtr;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "UnmapBuffer"; }
|
||||
};
|
||||
|
||||
class ReadImage2DAction : public Action
|
||||
{
|
||||
public:
|
||||
ReadImage2DAction() { mOutput = NULL; }
|
||||
virtual ~ReadImage2DAction() { free( mOutput ); }
|
||||
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight;
|
||||
void *mOutput;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "ReadImage2D"; }
|
||||
};
|
||||
|
||||
class ReadImage3DAction : public Action
|
||||
{
|
||||
public:
|
||||
ReadImage3DAction() { mOutput = NULL; }
|
||||
virtual ~ReadImage3DAction() { free( mOutput ); }
|
||||
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
void *mOutput;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "ReadImage3D"; }
|
||||
};
|
||||
|
||||
class WriteImage2DAction : public Action
|
||||
{
|
||||
public:
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight;
|
||||
void *mOutput;
|
||||
|
||||
WriteImage2DAction() { mOutput = NULL; }
|
||||
virtual ~WriteImage2DAction() { free( mOutput ); }
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "WriteImage2D"; }
|
||||
};
|
||||
|
||||
class WriteImage3DAction : public Action
|
||||
{
|
||||
public:
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
void *mOutput;
|
||||
|
||||
WriteImage3DAction() { mOutput = NULL; }
|
||||
virtual ~WriteImage3DAction() { free( mOutput ); }
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "WriteImage3D"; }
|
||||
};
|
||||
|
||||
class CopyImageAction : public Action
|
||||
{
|
||||
public:
|
||||
CopyImageAction() {}
|
||||
virtual ~CopyImageAction() {}
|
||||
|
||||
clMemWrapper mSrcImage, mDstImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
};
|
||||
|
||||
class CopyImage2Dto2DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage2Dto2DAction() {}
|
||||
virtual ~CopyImage2Dto2DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage2Dto2D"; }
|
||||
};
|
||||
|
||||
class CopyImage2Dto3DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage2Dto3DAction() {}
|
||||
virtual ~CopyImage2Dto3DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage2Dto3D"; }
|
||||
};
|
||||
|
||||
class CopyImage3Dto2DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage3Dto2DAction() {}
|
||||
virtual ~CopyImage3Dto2DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage3Dto2D"; }
|
||||
};
|
||||
|
||||
class CopyImage3Dto3DAction : public CopyImageAction
|
||||
{
|
||||
public:
|
||||
CopyImage3Dto3DAction() {}
|
||||
virtual ~CopyImage3Dto3DAction() {}
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyImage3Dto3D"; }
|
||||
};
|
||||
|
||||
class Copy2DImageToBufferAction : public Action
|
||||
{
|
||||
public:
|
||||
Copy2DImageToBufferAction() {}
|
||||
virtual ~Copy2DImageToBufferAction() {}
|
||||
|
||||
clMemWrapper mSrcImage, mDstBuffer;
|
||||
size_t mWidth, mHeight;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "Copy2DImageToBuffer"; }
|
||||
};
|
||||
|
||||
class Copy3DImageToBufferAction : public Action
|
||||
{
|
||||
public:
|
||||
Copy3DImageToBufferAction() {}
|
||||
virtual ~Copy3DImageToBufferAction() {}
|
||||
|
||||
clMemWrapper mSrcImage, mDstBuffer;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "Copy3DImageToBuffer"; }
|
||||
};
|
||||
|
||||
class CopyBufferTo2DImageAction : public Action
|
||||
{
|
||||
public:
|
||||
CopyBufferTo2DImageAction() {}
|
||||
virtual ~CopyBufferTo2DImageAction() {}
|
||||
|
||||
clMemWrapper mSrcBuffer, mDstImage;
|
||||
size_t mWidth, mHeight;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyBufferTo2D"; }
|
||||
};
|
||||
|
||||
class CopyBufferTo3DImageAction : public Action
|
||||
{
|
||||
public:
|
||||
CopyBufferTo3DImageAction() {}
|
||||
virtual ~CopyBufferTo3DImageAction() {}
|
||||
|
||||
clMemWrapper mSrcBuffer, mDstImage;
|
||||
size_t mWidth, mHeight, mDepth;
|
||||
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "CopyBufferTo3D"; }
|
||||
};
|
||||
|
||||
class MapImageAction : public Action
|
||||
{
|
||||
public:
|
||||
MapImageAction() : mQueue(0) {}
|
||||
|
||||
clMemWrapper mImage;
|
||||
size_t mWidth, mHeight;
|
||||
void *mMappedPtr;
|
||||
cl_command_queue mQueue;
|
||||
|
||||
virtual ~MapImageAction();
|
||||
virtual cl_int Setup( cl_device_id device, cl_context context, cl_command_queue queue );
|
||||
virtual cl_int Execute( cl_command_queue queue, cl_uint numWaits, cl_event *waits, cl_event *outEvent );
|
||||
|
||||
virtual const char * GetName( void ) const { return "MapImage"; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _action_classes_h
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "procs.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
basefn basefn_list[] = {
|
||||
test_event_get_execute_status,
|
||||
test_event_get_write_array_status,
|
||||
test_event_get_read_array_status,
|
||||
test_event_get_info,
|
||||
test_event_wait_for_execute,
|
||||
test_event_wait_for_array,
|
||||
test_event_flush,
|
||||
test_event_finish_execute,
|
||||
test_event_finish_array,
|
||||
test_event_release_before_done,
|
||||
test_event_enqueue_marker,
|
||||
#ifdef CL_VERSION_1_2
|
||||
test_event_enqueue_marker_with_list,
|
||||
test_event_enqueue_barrier_with_list,
|
||||
#endif
|
||||
|
||||
|
||||
test_event_waitlist_single_queue,
|
||||
test_event_waitlist_multi_queue,
|
||||
test_event_waitlist_multi_queue_multi_device,
|
||||
test_event_enqueue_wait_for_events_single_queue,
|
||||
test_event_enqueue_wait_for_events_multi_queue,
|
||||
test_event_enqueue_wait_for_events_multi_queue_multi_device,
|
||||
test_event_enqueue_marker_single_queue,
|
||||
test_event_enqueue_marker_multi_queue,
|
||||
test_event_enqueue_marker_multi_queue_multi_device,
|
||||
test_event_enqueue_barrier_single_queue,
|
||||
|
||||
test_waitlists,
|
||||
test_userevents,
|
||||
test_callbacks,
|
||||
test_callbacks_simultaneous,
|
||||
test_userevents_multithreaded,
|
||||
};
|
||||
|
||||
const char *basefn_names[] = {
|
||||
"event_get_execute_status",
|
||||
"event_get_write_array_status",
|
||||
"event_get_read_array_status",
|
||||
"event_get_info",
|
||||
"event_wait_for_execute",
|
||||
"event_wait_for_array",
|
||||
"event_flush",
|
||||
"event_finish_execute",
|
||||
"event_finish_array",
|
||||
"event_release_before_done",
|
||||
"event_enqueue_marker",
|
||||
#ifdef CL_VERSION_1_2
|
||||
"event_enqueue_marker_with_event_list",
|
||||
"event_enqueue_barrier_with_event_list",
|
||||
#endif
|
||||
|
||||
"out_of_order_event_waitlist_single_queue",
|
||||
"out_of_order_event_waitlist_multi_queue",
|
||||
"out_of_order_event_waitlist_multi_queue_multi_device",
|
||||
"out_of_order_event_enqueue_wait_for_events_single_queue",
|
||||
"out_of_order_event_enqueue_wait_for_events_multi_queue",
|
||||
"out_of_order_event_enqueue_wait_for_events_multi_queue_multi_device",
|
||||
"out_of_order_event_enqueue_marker_single_queue",
|
||||
"out_of_order_event_enqueue_marker_multi_queue",
|
||||
"out_of_order_event_enqueue_marker_multi_queue_multi_device",
|
||||
"out_of_order_event_enqueue_barrier_single_queue",
|
||||
|
||||
"waitlists",
|
||||
"test_userevents",
|
||||
|
||||
"callbacks",
|
||||
"callbacks_simultaneous",
|
||||
|
||||
"userevents_multithreaded",
|
||||
|
||||
"all",
|
||||
};
|
||||
|
||||
ct_assert((sizeof(basefn_names) / sizeof(basefn_names[0]) - 1) == (sizeof(basefn_list) / sizeof(basefn_list[0])));
|
||||
|
||||
int num_fns = sizeof(basefn_names) / sizeof(char *);
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
return runTestHarness( argc, argv, num_fns, basefn_list, basefn_names, false, false, 0 );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "procs.h"
|
||||
#include "../../test_common/harness/testHarness.h"
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
basefn basefn_list[] = {
|
||||
test_event_get_execute_status,
|
||||
test_event_get_write_array_status,
|
||||
test_event_get_read_array_status,
|
||||
test_event_get_info,
|
||||
test_event_wait_for_execute,
|
||||
test_event_wait_for_array,
|
||||
test_event_flush,
|
||||
test_event_finish_execute,
|
||||
test_event_finish_array,
|
||||
test_event_release_before_done,
|
||||
test_event_enqueue_marker,
|
||||
#ifdef CL_VERSION_1_2
|
||||
test_event_enqueue_marker_with_list,
|
||||
test_event_enqueue_barrier_with_list,
|
||||
#endif
|
||||
|
||||
|
||||
test_event_waitlist_single_queue,
|
||||
test_event_waitlist_multi_queue,
|
||||
test_event_waitlist_multi_queue_multi_device,
|
||||
test_event_enqueue_wait_for_events_single_queue,
|
||||
test_event_enqueue_wait_for_events_multi_queue,
|
||||
test_event_enqueue_wait_for_events_multi_queue_multi_device,
|
||||
test_event_enqueue_marker_single_queue,
|
||||
test_event_enqueue_marker_multi_queue,
|
||||
test_event_enqueue_marker_multi_queue_multi_device,
|
||||
test_event_enqueue_barrier_single_queue,
|
||||
|
||||
test_waitlists,
|
||||
test_userevents,
|
||||
test_callbacks,
|
||||
test_callbacks_simultaneous,
|
||||
test_userevents_multithreaded,
|
||||
};
|
||||
|
||||
const char *basefn_names[] = {
|
||||
"event_get_execute_status",
|
||||
"event_get_write_array_status",
|
||||
"event_get_read_array_status",
|
||||
"event_get_info",
|
||||
"event_wait_for_execute",
|
||||
"event_wait_for_array",
|
||||
"event_flush",
|
||||
"event_finish_execute",
|
||||
"event_finish_array",
|
||||
"event_release_before_done",
|
||||
"event_enqueue_marker",
|
||||
#ifdef CL_VERSION_1_2
|
||||
"event_enqueue_marker_with_event_list",
|
||||
"event_enqueue_barrier_with_event_list",
|
||||
#endif
|
||||
|
||||
"out_of_order_event_waitlist_single_queue",
|
||||
"out_of_order_event_waitlist_multi_queue",
|
||||
"out_of_order_event_waitlist_multi_queue_multi_device",
|
||||
"out_of_order_event_enqueue_wait_for_events_single_queue",
|
||||
"out_of_order_event_enqueue_wait_for_events_multi_queue",
|
||||
"out_of_order_event_enqueue_wait_for_events_multi_queue_multi_device",
|
||||
"out_of_order_event_enqueue_marker_single_queue",
|
||||
"out_of_order_event_enqueue_marker_multi_queue",
|
||||
"out_of_order_event_enqueue_marker_multi_queue_multi_device",
|
||||
"out_of_order_event_enqueue_barrier_single_queue",
|
||||
|
||||
"waitlists",
|
||||
"test_userevents",
|
||||
|
||||
"callbacks",
|
||||
"callbacks_simultaneous",
|
||||
|
||||
"userevents_multithreaded",
|
||||
|
||||
"all",
|
||||
};
|
||||
|
||||
ct_assert((sizeof(basefn_names) / sizeof(basefn_names[0]) - 1) == (sizeof(basefn_list) / sizeof(basefn_list[0])));
|
||||
|
||||
int num_fns = sizeof(basefn_names) / sizeof(char *);
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
return runTestHarness( argc, argv, num_fns, basefn_list, basefn_names, false, false, 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include "../../test_common/harness/kernelHelpers.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/clImageHelper.h"
|
||||
|
||||
extern float random_float(float low, float high);
|
||||
extern float calculate_ulperror(float a, float b);
|
||||
|
||||
|
||||
extern int test_event_get_execute_status(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_get_write_array_status(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_get_read_array_status(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_get_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_wait_for_execute(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_wait_for_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_flush(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_finish_execute(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_finish_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_release_before_done(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_marker(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
#ifdef CL_VERSION_1_2
|
||||
extern int test_event_enqueue_marker_with_list(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_barrier_with_list(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
#endif
|
||||
|
||||
extern int test_event_waitlist_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_waitlist_multi_queue( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_waitlist_multi_queue_multi_device(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_event_enqueue_wait_for_events_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_wait_for_events_multi_queue( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_wait_for_events_multi_queue_multi_device(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_event_enqueue_barrier_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_event_enqueue_marker_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_marker_multi_queue( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_marker_multi_queue_multi_device(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_waitlists( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_userevents( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_callbacks( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_callbacks_simultaneous( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_userevents_multithreaded( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "../../test_common/harness/errorHelpers.h"
|
||||
#include "../../test_common/harness/kernelHelpers.h"
|
||||
#include "../../test_common/harness/typeWrappers.h"
|
||||
#include "../../test_common/harness/clImageHelper.h"
|
||||
|
||||
extern float random_float(float low, float high);
|
||||
extern float calculate_ulperror(float a, float b);
|
||||
|
||||
|
||||
extern int test_event_get_execute_status(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_get_write_array_status(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_get_read_array_status(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_get_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_wait_for_execute(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_wait_for_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_flush(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_finish_execute(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_finish_array(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_release_before_done(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_marker(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
#ifdef CL_VERSION_1_2
|
||||
extern int test_event_enqueue_marker_with_list(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_barrier_with_list(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
#endif
|
||||
|
||||
extern int test_event_waitlist_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_waitlist_multi_queue( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_waitlist_multi_queue_multi_device(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_event_enqueue_wait_for_events_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_wait_for_events_multi_queue( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_wait_for_events_multi_queue_multi_device(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_event_enqueue_barrier_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_event_enqueue_marker_single_queue(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_marker_multi_queue( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
extern int test_event_enqueue_marker_multi_queue_multi_device(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
|
||||
|
||||
extern int test_waitlists( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_userevents( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_callbacks( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_callbacks_simultaneous( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
extern int test_userevents_multithreaded( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
|
||||
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _testBase_h
|
||||
#define _testBase_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "procs.h"
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#ifndef _testBase_h
|
||||
#define _testBase_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "procs.h"
|
||||
|
||||
#endif // _testBase_h
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,334 +1,334 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "action_classes.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/ThreadPool.h"
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif // !_MSC_VER
|
||||
|
||||
extern const char *IGetStatusString( cl_int status );
|
||||
|
||||
#define PRINT_OPS 0
|
||||
|
||||
// Yes, this is somewhat nasty, in that we're relying on the CPU (the real CPU, not the OpenCL device)
|
||||
// to be atomic w.r.t. boolean values. Although if it isn't, we'll just miss the check on this bool
|
||||
// until the next time around, so it's not that big of a deal. Ideally, we'd be using a semaphore with
|
||||
// a trywait on it, but then that introduces the fun issue of what to do on Win32, etc. This way is
|
||||
// far more portable, and worst case of failure is a slightly longer test run.
|
||||
static bool sCallbackTriggered = false;
|
||||
|
||||
|
||||
#define EVENT_CALLBACK_TYPE_TOTAL 3
|
||||
static bool sCallbackTriggered_flag[ EVENT_CALLBACK_TYPE_TOTAL ] ={ false,false, false };
|
||||
cl_int event_callback_types[EVENT_CALLBACK_TYPE_TOTAL] ={ CL_SUBMITTED, CL_RUNNING, CL_COMPLETE};
|
||||
|
||||
// Our callback function
|
||||
/*void CL_CALLBACK single_event_callback_function( cl_event event, cl_int commandStatus, void * userData )
|
||||
{
|
||||
int i=*static_cast<int *>(userData);
|
||||
log_info( "\tEvent callback %d triggered\n", i);
|
||||
sCallbackTriggered_flag [ i ] = true;
|
||||
}*/
|
||||
|
||||
/* use struct as call back para */
|
||||
typedef struct { cl_int enevt_type; int index; } CALL_BACK_USER_DATA;
|
||||
|
||||
void CL_CALLBACK single_event_callback_function_flags( cl_event event, cl_int commandStatus, void * userData )
|
||||
{
|
||||
// int i=*static_cast<int *>(userData);
|
||||
CALL_BACK_USER_DATA *pdata= static_cast<CALL_BACK_USER_DATA *>(userData);
|
||||
|
||||
log_info( "\tEvent callback %d of type %d triggered\n", pdata->index, pdata->enevt_type);
|
||||
sCallbackTriggered_flag [pdata->index ] = true;
|
||||
}
|
||||
|
||||
int test_callback_event_single( cl_device_id device, cl_context context, cl_command_queue queue, Action *actionToTest )
|
||||
{
|
||||
// Note: we don't use the waiting feature here. We just want to verify that we get a callback called
|
||||
// when the given event finishes
|
||||
|
||||
cl_int error = actionToTest->Setup( device, context, queue );
|
||||
test_error( error, "Unable to set up test action" );
|
||||
|
||||
// Set up a user event, which we use as a gate for the second event
|
||||
clEventWrapper gateEvent = clCreateUserEvent( context, &error );
|
||||
test_error( error, "Unable to set up user gate event" );
|
||||
|
||||
// Set up the execution of the action with its actual event
|
||||
clEventWrapper actualEvent;
|
||||
error = actionToTest->Execute( queue, 1, &gateEvent, &actualEvent );
|
||||
test_error( error, "Unable to set up action execution" );
|
||||
|
||||
// Set up the callback on the actual event
|
||||
|
||||
/* use struct as call back para */
|
||||
CALL_BACK_USER_DATA user_data[EVENT_CALLBACK_TYPE_TOTAL];
|
||||
int index [EVENT_CALLBACK_TYPE_TOTAL]={ 0,1,2};
|
||||
for( int i=0;i< EVENT_CALLBACK_TYPE_TOTAL; i++)
|
||||
{
|
||||
user_data[i].enevt_type=event_callback_types[i];
|
||||
user_data[i].index =i;
|
||||
error = clSetEventCallback( actualEvent, event_callback_types[i], single_event_callback_function_flags, user_data+i );
|
||||
|
||||
}
|
||||
|
||||
// Now release the user event, which will allow our actual action to run
|
||||
error = clSetUserEventStatus( gateEvent, CL_COMPLETE );
|
||||
test_error( error, "Unable to trigger gate event" );
|
||||
|
||||
// Now we wait for completion. Note that we can actually wait on the event itself, at least at first
|
||||
error = clWaitForEvents( 1, &actualEvent );
|
||||
test_error( error, "Unable to wait for actual test event" );
|
||||
|
||||
// Note: we can check our callback now, and it MIGHT have been triggered, but that's not guaranteed
|
||||
if( sCallbackTriggered )
|
||||
{
|
||||
// We're all good, so return success
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The callback has not yet been called, but that doesn't mean it won't be. So wait for it
|
||||
log_info( "\tWaiting for callback..." );
|
||||
fflush( stdout );
|
||||
for( int i = 0; i < 10 * 10; i++ )
|
||||
{
|
||||
usleep( 100000 ); // 1/10th second
|
||||
|
||||
int cc=0;
|
||||
for( int k=0;k< EVENT_CALLBACK_TYPE_TOTAL;k++)
|
||||
if (sCallbackTriggered_flag[k]) {
|
||||
cc++;
|
||||
}
|
||||
|
||||
if (cc== EVENT_CALLBACK_TYPE_TOTAL )
|
||||
{
|
||||
log_info( "\n" );
|
||||
return 0;
|
||||
}
|
||||
log_info( "." );
|
||||
fflush( stdout );
|
||||
}
|
||||
|
||||
// If we got here, we never got the callback
|
||||
log_error( "\nCallback not called within 10 seconds! (assuming failure)\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define TEST_ACTION( name ) \
|
||||
{ \
|
||||
name##Action action; \
|
||||
log_info( "-- Testing " #name "...\n" ); \
|
||||
if( ( error = test_callback_event_single( deviceID, context, queue, &action ) ) != CL_SUCCESS ) \
|
||||
retVal++; \
|
||||
clFinish( queue ); \
|
||||
}
|
||||
|
||||
int test_callbacks( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
int retVal = 0;
|
||||
|
||||
log_info( "\n" );
|
||||
|
||||
TEST_ACTION( NDRangeKernel )
|
||||
|
||||
TEST_ACTION( ReadBuffer )
|
||||
TEST_ACTION( WriteBuffer )
|
||||
TEST_ACTION( MapBuffer )
|
||||
TEST_ACTION( UnmapBuffer )
|
||||
|
||||
if( checkForImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
log_info( "\nNote: device does not support images. Skipping remainder of callback tests...\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage2D )
|
||||
TEST_ACTION( WriteImage2D )
|
||||
TEST_ACTION( CopyImage2Dto2D )
|
||||
TEST_ACTION( Copy2DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo2DImage )
|
||||
TEST_ACTION( MapImage )
|
||||
|
||||
if( checkFor3DImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
log_info( "\nNote: device does not support 3D images. Skipping remainder of waitlist tests...\n" );
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage3D )
|
||||
TEST_ACTION( WriteImage3D )
|
||||
TEST_ACTION( CopyImage2Dto3D )
|
||||
TEST_ACTION( CopyImage3Dto2D )
|
||||
TEST_ACTION( CopyImage3Dto3D )
|
||||
TEST_ACTION( Copy3DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo3DImage )
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#define SIMUTANEOUS_ACTION_TOTAL 18
|
||||
static bool sSimultaneousFlags[ 54 ];// for 18 actions with 3 callback status
|
||||
static volatile int sSimultaneousCount;
|
||||
|
||||
Action * actions[ 19 ] = { 0 };
|
||||
|
||||
// Callback for the simultaneous tests
|
||||
void CL_CALLBACK simultaneous_event_callback_function( cl_event event, cl_int commandStatus, void * userData )
|
||||
{
|
||||
int eventIndex = (int)(size_t)userData;
|
||||
int actionIndex = eventIndex/EVENT_CALLBACK_TYPE_TOTAL;
|
||||
int statusIndex = eventIndex%EVENT_CALLBACK_TYPE_TOTAL;
|
||||
log_info( "\tEvent callback triggered for action %s callback type %s \n", actions[actionIndex]->GetName(), IGetStatusString(statusIndex) );
|
||||
sSimultaneousFlags[ actionIndex ] = true;
|
||||
ThreadPool_AtomicAdd(&sSimultaneousCount,1);
|
||||
}
|
||||
|
||||
int test_callbacks_simultaneous( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
// Unlike the singles test, in this one, we run a bunch of events all at once, to verify that
|
||||
// the callbacks do get called once-and-only-once for each event, even if the run out of order or
|
||||
// are dependent on each other
|
||||
|
||||
// First, the list of actions to run
|
||||
int actionCount = 0, index = 0;
|
||||
|
||||
actions[ index++ ] = new NDRangeKernelAction();
|
||||
actions[ index++ ] = new ReadBufferAction();
|
||||
actions[ index++ ] = new WriteBufferAction();
|
||||
actions[ index++ ] = new MapBufferAction();
|
||||
actions[ index++ ] = new UnmapBufferAction();
|
||||
|
||||
if( checkForImageSupport( deviceID ) != CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
actions[ index++ ] = new ReadImage2DAction();
|
||||
actions[ index++ ] = new WriteImage2DAction();
|
||||
actions[ index++ ] = new CopyImage2Dto2DAction();
|
||||
actions[ index++ ] = new Copy2DImageToBufferAction();
|
||||
actions[ index++ ] = new CopyBufferTo2DImageAction();
|
||||
actions[ index++ ] = new MapImageAction();
|
||||
|
||||
if( checkFor3DImageSupport( deviceID ) != CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
actions[ index++ ] = new ReadImage3DAction();
|
||||
actions[ index++ ] = new WriteImage3DAction();
|
||||
actions[ index++ ] = new CopyImage2Dto3DAction();
|
||||
actions[ index++ ] = new CopyImage3Dto2DAction();
|
||||
actions[ index++ ] = new CopyImage3Dto3DAction();
|
||||
actions[ index++ ] = new Copy3DImageToBufferAction();
|
||||
actions[ index++ ] = new CopyBufferTo3DImageAction();
|
||||
}
|
||||
}
|
||||
actionCount = index;
|
||||
actions[ index++ ] = NULL;
|
||||
|
||||
// Now set them all up
|
||||
log_info( "\tSetting up test events...\n" );
|
||||
for( index = 0; actions[ index ] != NULL; index++ )
|
||||
{
|
||||
error = actions[ index ]->Setup( deviceID, context, queue );
|
||||
test_error( error, "Unable to set up test action" );
|
||||
sSimultaneousFlags[ index ] = false;
|
||||
}
|
||||
sSimultaneousCount = 0;
|
||||
|
||||
// Set up the user event to start them all
|
||||
clEventWrapper gateEvent = clCreateUserEvent( context, &error );
|
||||
test_error( error, "Unable to set up user gate event" );
|
||||
|
||||
// Start executing, all tied to the gate event
|
||||
//clEventWrapper actionEvents[ 18 ];// current actionCount is 18
|
||||
clEventWrapper *actionEvents= new clEventWrapper[actionCount];
|
||||
if (actionEvents == NULL)
|
||||
{
|
||||
log_error(" memory error in test_callbacks_simultaneous \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
for( index = 0; actions[ index ] != NULL; index++ )
|
||||
{
|
||||
// Randomly choose to wait on the gate, or wait on the previous event
|
||||
cl_event * eventPtr = &gateEvent;
|
||||
if( ( index > 0 ) && ( random_in_range( 0, 255, seed ) & 1 ) )
|
||||
eventPtr = &actionEvents[ index - 1 ];
|
||||
|
||||
error = actions[ index ]->Execute( queue, 1, eventPtr, &actionEvents[ index ] );
|
||||
test_error( error, "Unable to execute test action" );
|
||||
|
||||
|
||||
for( int k=0; k< EVENT_CALLBACK_TYPE_TOTAL; k++)
|
||||
{
|
||||
error = clSetEventCallback( actionEvents[index], event_callback_types[k], simultaneous_event_callback_function, (void *)(size_t)(index*EVENT_CALLBACK_TYPE_TOTAL+k ) );
|
||||
test_error( error, "Unable to set event callback function" );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int total_callbacks= actionCount * EVENT_CALLBACK_TYPE_TOTAL;
|
||||
|
||||
// Now release the user event, which will allow our actual action to run
|
||||
error = clSetUserEventStatus( gateEvent, CL_COMPLETE );
|
||||
test_error( error, "Unable to trigger gate event" );
|
||||
|
||||
// Wait on the actual action events now
|
||||
log_info( "\tWaiting for test completions...\n" );
|
||||
error = clWaitForEvents( actionCount, &actionEvents[ 0 ] );
|
||||
test_error( error, "Unable to wait for actual test events" );
|
||||
|
||||
// Note: we can check our callback now, and it MIGHT have been triggered, but that's not guaranteed
|
||||
int last_count = 0;
|
||||
if( ((last_count = sSimultaneousCount)) == total_callbacks)
|
||||
{
|
||||
// We're all good, so return success
|
||||
log_info( "\t%d of %d callbacks received\n", sSimultaneousCount, total_callbacks );
|
||||
|
||||
if (actionEvents) delete [] actionEvents;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We haven't gotten (all) of the callbacks, so wait for them
|
||||
log_info( "\tWe've only received %d of the %d callbacks we expected; waiting for more...\n", last_count, total_callbacks );
|
||||
|
||||
for( int i = 0; i < 10 * 10; i++ )
|
||||
{
|
||||
usleep( 100000 ); // 1/10th second
|
||||
if( ((last_count = sSimultaneousCount)) == total_callbacks )
|
||||
{
|
||||
// All of the callbacks were executed
|
||||
if (actionEvents) delete [] actionEvents;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, some of the callbacks did not occur in time
|
||||
log_error( "\nError: We only ever received %d of our %d callbacks!\n", last_count, total_callbacks );
|
||||
log_error( "Events that did not receive callbacks:\n" );
|
||||
for( index = 0; actions[ index ] != NULL; index++ )
|
||||
{
|
||||
if( !sSimultaneousFlags[ index ] )
|
||||
log_error( "\t%s\n", actions[ index ]->GetName() );
|
||||
}
|
||||
|
||||
if (actionEvents) delete [] actionEvents;
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "action_classes.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/ThreadPool.h"
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif // !_MSC_VER
|
||||
|
||||
extern const char *IGetStatusString( cl_int status );
|
||||
|
||||
#define PRINT_OPS 0
|
||||
|
||||
// Yes, this is somewhat nasty, in that we're relying on the CPU (the real CPU, not the OpenCL device)
|
||||
// to be atomic w.r.t. boolean values. Although if it isn't, we'll just miss the check on this bool
|
||||
// until the next time around, so it's not that big of a deal. Ideally, we'd be using a semaphore with
|
||||
// a trywait on it, but then that introduces the fun issue of what to do on Win32, etc. This way is
|
||||
// far more portable, and worst case of failure is a slightly longer test run.
|
||||
static bool sCallbackTriggered = false;
|
||||
|
||||
|
||||
#define EVENT_CALLBACK_TYPE_TOTAL 3
|
||||
static bool sCallbackTriggered_flag[ EVENT_CALLBACK_TYPE_TOTAL ] ={ false,false, false };
|
||||
cl_int event_callback_types[EVENT_CALLBACK_TYPE_TOTAL] ={ CL_SUBMITTED, CL_RUNNING, CL_COMPLETE};
|
||||
|
||||
// Our callback function
|
||||
/*void CL_CALLBACK single_event_callback_function( cl_event event, cl_int commandStatus, void * userData )
|
||||
{
|
||||
int i=*static_cast<int *>(userData);
|
||||
log_info( "\tEvent callback %d triggered\n", i);
|
||||
sCallbackTriggered_flag [ i ] = true;
|
||||
}*/
|
||||
|
||||
/* use struct as call back para */
|
||||
typedef struct { cl_int enevt_type; int index; } CALL_BACK_USER_DATA;
|
||||
|
||||
void CL_CALLBACK single_event_callback_function_flags( cl_event event, cl_int commandStatus, void * userData )
|
||||
{
|
||||
// int i=*static_cast<int *>(userData);
|
||||
CALL_BACK_USER_DATA *pdata= static_cast<CALL_BACK_USER_DATA *>(userData);
|
||||
|
||||
log_info( "\tEvent callback %d of type %d triggered\n", pdata->index, pdata->enevt_type);
|
||||
sCallbackTriggered_flag [pdata->index ] = true;
|
||||
}
|
||||
|
||||
int test_callback_event_single( cl_device_id device, cl_context context, cl_command_queue queue, Action *actionToTest )
|
||||
{
|
||||
// Note: we don't use the waiting feature here. We just want to verify that we get a callback called
|
||||
// when the given event finishes
|
||||
|
||||
cl_int error = actionToTest->Setup( device, context, queue );
|
||||
test_error( error, "Unable to set up test action" );
|
||||
|
||||
// Set up a user event, which we use as a gate for the second event
|
||||
clEventWrapper gateEvent = clCreateUserEvent( context, &error );
|
||||
test_error( error, "Unable to set up user gate event" );
|
||||
|
||||
// Set up the execution of the action with its actual event
|
||||
clEventWrapper actualEvent;
|
||||
error = actionToTest->Execute( queue, 1, &gateEvent, &actualEvent );
|
||||
test_error( error, "Unable to set up action execution" );
|
||||
|
||||
// Set up the callback on the actual event
|
||||
|
||||
/* use struct as call back para */
|
||||
CALL_BACK_USER_DATA user_data[EVENT_CALLBACK_TYPE_TOTAL];
|
||||
int index [EVENT_CALLBACK_TYPE_TOTAL]={ 0,1,2};
|
||||
for( int i=0;i< EVENT_CALLBACK_TYPE_TOTAL; i++)
|
||||
{
|
||||
user_data[i].enevt_type=event_callback_types[i];
|
||||
user_data[i].index =i;
|
||||
error = clSetEventCallback( actualEvent, event_callback_types[i], single_event_callback_function_flags, user_data+i );
|
||||
|
||||
}
|
||||
|
||||
// Now release the user event, which will allow our actual action to run
|
||||
error = clSetUserEventStatus( gateEvent, CL_COMPLETE );
|
||||
test_error( error, "Unable to trigger gate event" );
|
||||
|
||||
// Now we wait for completion. Note that we can actually wait on the event itself, at least at first
|
||||
error = clWaitForEvents( 1, &actualEvent );
|
||||
test_error( error, "Unable to wait for actual test event" );
|
||||
|
||||
// Note: we can check our callback now, and it MIGHT have been triggered, but that's not guaranteed
|
||||
if( sCallbackTriggered )
|
||||
{
|
||||
// We're all good, so return success
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The callback has not yet been called, but that doesn't mean it won't be. So wait for it
|
||||
log_info( "\tWaiting for callback..." );
|
||||
fflush( stdout );
|
||||
for( int i = 0; i < 10 * 10; i++ )
|
||||
{
|
||||
usleep( 100000 ); // 1/10th second
|
||||
|
||||
int cc=0;
|
||||
for( int k=0;k< EVENT_CALLBACK_TYPE_TOTAL;k++)
|
||||
if (sCallbackTriggered_flag[k]) {
|
||||
cc++;
|
||||
}
|
||||
|
||||
if (cc== EVENT_CALLBACK_TYPE_TOTAL )
|
||||
{
|
||||
log_info( "\n" );
|
||||
return 0;
|
||||
}
|
||||
log_info( "." );
|
||||
fflush( stdout );
|
||||
}
|
||||
|
||||
// If we got here, we never got the callback
|
||||
log_error( "\nCallback not called within 10 seconds! (assuming failure)\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define TEST_ACTION( name ) \
|
||||
{ \
|
||||
name##Action action; \
|
||||
log_info( "-- Testing " #name "...\n" ); \
|
||||
if( ( error = test_callback_event_single( deviceID, context, queue, &action ) ) != CL_SUCCESS ) \
|
||||
retVal++; \
|
||||
clFinish( queue ); \
|
||||
}
|
||||
|
||||
int test_callbacks( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
int retVal = 0;
|
||||
|
||||
log_info( "\n" );
|
||||
|
||||
TEST_ACTION( NDRangeKernel )
|
||||
|
||||
TEST_ACTION( ReadBuffer )
|
||||
TEST_ACTION( WriteBuffer )
|
||||
TEST_ACTION( MapBuffer )
|
||||
TEST_ACTION( UnmapBuffer )
|
||||
|
||||
if( checkForImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
log_info( "\nNote: device does not support images. Skipping remainder of callback tests...\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage2D )
|
||||
TEST_ACTION( WriteImage2D )
|
||||
TEST_ACTION( CopyImage2Dto2D )
|
||||
TEST_ACTION( Copy2DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo2DImage )
|
||||
TEST_ACTION( MapImage )
|
||||
|
||||
if( checkFor3DImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
log_info( "\nNote: device does not support 3D images. Skipping remainder of waitlist tests...\n" );
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage3D )
|
||||
TEST_ACTION( WriteImage3D )
|
||||
TEST_ACTION( CopyImage2Dto3D )
|
||||
TEST_ACTION( CopyImage3Dto2D )
|
||||
TEST_ACTION( CopyImage3Dto3D )
|
||||
TEST_ACTION( Copy3DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo3DImage )
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#define SIMUTANEOUS_ACTION_TOTAL 18
|
||||
static bool sSimultaneousFlags[ 54 ];// for 18 actions with 3 callback status
|
||||
static volatile int sSimultaneousCount;
|
||||
|
||||
Action * actions[ 19 ] = { 0 };
|
||||
|
||||
// Callback for the simultaneous tests
|
||||
void CL_CALLBACK simultaneous_event_callback_function( cl_event event, cl_int commandStatus, void * userData )
|
||||
{
|
||||
int eventIndex = (int)(size_t)userData;
|
||||
int actionIndex = eventIndex/EVENT_CALLBACK_TYPE_TOTAL;
|
||||
int statusIndex = eventIndex%EVENT_CALLBACK_TYPE_TOTAL;
|
||||
log_info( "\tEvent callback triggered for action %s callback type %s \n", actions[actionIndex]->GetName(), IGetStatusString(statusIndex) );
|
||||
sSimultaneousFlags[ actionIndex ] = true;
|
||||
ThreadPool_AtomicAdd(&sSimultaneousCount,1);
|
||||
}
|
||||
|
||||
int test_callbacks_simultaneous( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
// Unlike the singles test, in this one, we run a bunch of events all at once, to verify that
|
||||
// the callbacks do get called once-and-only-once for each event, even if the run out of order or
|
||||
// are dependent on each other
|
||||
|
||||
// First, the list of actions to run
|
||||
int actionCount = 0, index = 0;
|
||||
|
||||
actions[ index++ ] = new NDRangeKernelAction();
|
||||
actions[ index++ ] = new ReadBufferAction();
|
||||
actions[ index++ ] = new WriteBufferAction();
|
||||
actions[ index++ ] = new MapBufferAction();
|
||||
actions[ index++ ] = new UnmapBufferAction();
|
||||
|
||||
if( checkForImageSupport( deviceID ) != CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
actions[ index++ ] = new ReadImage2DAction();
|
||||
actions[ index++ ] = new WriteImage2DAction();
|
||||
actions[ index++ ] = new CopyImage2Dto2DAction();
|
||||
actions[ index++ ] = new Copy2DImageToBufferAction();
|
||||
actions[ index++ ] = new CopyBufferTo2DImageAction();
|
||||
actions[ index++ ] = new MapImageAction();
|
||||
|
||||
if( checkFor3DImageSupport( deviceID ) != CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
actions[ index++ ] = new ReadImage3DAction();
|
||||
actions[ index++ ] = new WriteImage3DAction();
|
||||
actions[ index++ ] = new CopyImage2Dto3DAction();
|
||||
actions[ index++ ] = new CopyImage3Dto2DAction();
|
||||
actions[ index++ ] = new CopyImage3Dto3DAction();
|
||||
actions[ index++ ] = new Copy3DImageToBufferAction();
|
||||
actions[ index++ ] = new CopyBufferTo3DImageAction();
|
||||
}
|
||||
}
|
||||
actionCount = index;
|
||||
actions[ index++ ] = NULL;
|
||||
|
||||
// Now set them all up
|
||||
log_info( "\tSetting up test events...\n" );
|
||||
for( index = 0; actions[ index ] != NULL; index++ )
|
||||
{
|
||||
error = actions[ index ]->Setup( deviceID, context, queue );
|
||||
test_error( error, "Unable to set up test action" );
|
||||
sSimultaneousFlags[ index ] = false;
|
||||
}
|
||||
sSimultaneousCount = 0;
|
||||
|
||||
// Set up the user event to start them all
|
||||
clEventWrapper gateEvent = clCreateUserEvent( context, &error );
|
||||
test_error( error, "Unable to set up user gate event" );
|
||||
|
||||
// Start executing, all tied to the gate event
|
||||
//clEventWrapper actionEvents[ 18 ];// current actionCount is 18
|
||||
clEventWrapper *actionEvents= new clEventWrapper[actionCount];
|
||||
if (actionEvents == NULL)
|
||||
{
|
||||
log_error(" memory error in test_callbacks_simultaneous \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
RandomSeed seed( gRandomSeed );
|
||||
for( index = 0; actions[ index ] != NULL; index++ )
|
||||
{
|
||||
// Randomly choose to wait on the gate, or wait on the previous event
|
||||
cl_event * eventPtr = &gateEvent;
|
||||
if( ( index > 0 ) && ( random_in_range( 0, 255, seed ) & 1 ) )
|
||||
eventPtr = &actionEvents[ index - 1 ];
|
||||
|
||||
error = actions[ index ]->Execute( queue, 1, eventPtr, &actionEvents[ index ] );
|
||||
test_error( error, "Unable to execute test action" );
|
||||
|
||||
|
||||
for( int k=0; k< EVENT_CALLBACK_TYPE_TOTAL; k++)
|
||||
{
|
||||
error = clSetEventCallback( actionEvents[index], event_callback_types[k], simultaneous_event_callback_function, (void *)(size_t)(index*EVENT_CALLBACK_TYPE_TOTAL+k ) );
|
||||
test_error( error, "Unable to set event callback function" );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int total_callbacks= actionCount * EVENT_CALLBACK_TYPE_TOTAL;
|
||||
|
||||
// Now release the user event, which will allow our actual action to run
|
||||
error = clSetUserEventStatus( gateEvent, CL_COMPLETE );
|
||||
test_error( error, "Unable to trigger gate event" );
|
||||
|
||||
// Wait on the actual action events now
|
||||
log_info( "\tWaiting for test completions...\n" );
|
||||
error = clWaitForEvents( actionCount, &actionEvents[ 0 ] );
|
||||
test_error( error, "Unable to wait for actual test events" );
|
||||
|
||||
// Note: we can check our callback now, and it MIGHT have been triggered, but that's not guaranteed
|
||||
int last_count = 0;
|
||||
if( ((last_count = sSimultaneousCount)) == total_callbacks)
|
||||
{
|
||||
// We're all good, so return success
|
||||
log_info( "\t%d of %d callbacks received\n", sSimultaneousCount, total_callbacks );
|
||||
|
||||
if (actionEvents) delete [] actionEvents;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We haven't gotten (all) of the callbacks, so wait for them
|
||||
log_info( "\tWe've only received %d of the %d callbacks we expected; waiting for more...\n", last_count, total_callbacks );
|
||||
|
||||
for( int i = 0; i < 10 * 10; i++ )
|
||||
{
|
||||
usleep( 100000 ); // 1/10th second
|
||||
if( ((last_count = sSimultaneousCount)) == total_callbacks )
|
||||
{
|
||||
// All of the callbacks were executed
|
||||
if (actionEvents) delete [] actionEvents;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, some of the callbacks did not occur in time
|
||||
log_error( "\nError: We only ever received %d of our %d callbacks!\n", last_count, total_callbacks );
|
||||
log_error( "Events that did not receive callbacks:\n" );
|
||||
for( index = 0; actions[ index ] != NULL; index++ )
|
||||
{
|
||||
if( !sSimultaneousFlags[ index ] )
|
||||
log_error( "\t%s\n", actions[ index ]->GetName() );
|
||||
}
|
||||
|
||||
if (actionEvents) delete [] actionEvents;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,291 +1,291 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenCL/opencl.h>
|
||||
#include <mach/mach_time.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ATF performance framework.
|
||||
|
||||
#if USE_ATF
|
||||
#include <ATF/ATF.h>
|
||||
#define test_start() ATFTestStart()
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format,##__VA_ARGS__)
|
||||
#define log_info ATFLogInfo
|
||||
#define log_error ATFLogError
|
||||
#define log_no_atf
|
||||
#define test_finish() ATFTestFinish()
|
||||
#else
|
||||
#define test_start()
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, _higherBetter?"higher is better":"lower is better" , _number)
|
||||
#define log_info(...) fprintf(stdout, ## __VA_ARGS__ )
|
||||
#define log_error(...) fprintf(stderr, ## __VA_ARGS__ )
|
||||
#define log_info_no_atf(...) log_info(## __VA_ARGS__ )
|
||||
#define test_finish()
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CL error checking.
|
||||
|
||||
#define CL_DEVICE_TYPE_ENV_MUST_BE( bitfield_ )\
|
||||
{\
|
||||
cl_device_type device_type = CL_DEVICE_TYPE_DEFAULT;\
|
||||
const char* device_env = getenv("CL_DEVICE_TYPE");\
|
||||
if (device_env != NULL) {\
|
||||
if (!strcmp( device_env, "gpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_GPU" ))\
|
||||
device_type = CL_DEVICE_TYPE_GPU;\
|
||||
else if(!strcmp( device_env, "cpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_CPU" ))\
|
||||
device_type = CL_DEVICE_TYPE_CPU;\
|
||||
else if(!strcmp( device_env, "default" ) || !strcmp( device_env, "CL_DEVICE_TYPE_DEFAULT" ))\
|
||||
device_type = CL_DEVICE_TYPE_DEFAULT;\
|
||||
if (!(device_type & bitfield_)) {\
|
||||
log_error( "CL_DEVICE_TYPE environment variable \"%s\" must be \"%s\".", device_env, #bitfield_ );\
|
||||
abort();\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define CL_DEVICE_TYPE_ENV( device_type_ )\
|
||||
{\
|
||||
const char* device_env = getenv("CL_DEVICE_TYPE");\
|
||||
if (device_env != NULL) {\
|
||||
if (!strcmp( device_env, "gpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_GPU" ))\
|
||||
device_type_ = CL_DEVICE_TYPE_GPU;\
|
||||
else if(!strcmp( device_env, "cpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_CPU" ))\
|
||||
device_type_ = CL_DEVICE_TYPE_CPU;\
|
||||
else if(!strcmp( device_env, "default" ) || !strcmp( device_env, "CL_DEVICE_TYPE_DEFAULT" ))\
|
||||
device_type_ = CL_DEVICE_TYPE_DEFAULT;\
|
||||
}\
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define CL_EXIT_ERROR(cmd,...) \
|
||||
{ \
|
||||
if ((cmd) != CL_SUCCESS) { \
|
||||
log_error("CL ERROR: %s %u: ", __FILE__,__LINE__);\
|
||||
log_error(## __VA_ARGS__ );\
|
||||
log_error("\n");\
|
||||
return -1;\
|
||||
}\
|
||||
}
|
||||
#else
|
||||
#define CL_EXIT_ERROR(cmd,format,...) \
|
||||
{ \
|
||||
if ((cmd) != CL_SUCCESS) { \
|
||||
log_error("CL ERROR: %s %u: ", __FILE__,__LINE__);\
|
||||
log_error(format,## __VA_ARGS__ );\
|
||||
log_error("\n");\
|
||||
return -1;\
|
||||
}\
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CL_EXIT_BUILD_ERROR(cmd,program,format,...) \
|
||||
{ \
|
||||
if ((cmd) != CL_SUCCESS) { \
|
||||
cl_uint num_devices_;\
|
||||
clGetProgramInfo(program,CL_PROGRAM_NUM_DEVICES,sizeof(num_devices_),&num_devices_,NULL);\
|
||||
cl_device_id *device_list;\
|
||||
device_list=(cl_device_id *)malloc(num_devices_*sizeof(cl_device_id));\
|
||||
clGetProgramInfo(program,CL_PROGRAM_DEVICES,num_devices_*sizeof(cl_device_id),device_list,NULL);\
|
||||
for (unsigned i=0;i<num_devices_;++i) {\
|
||||
size_t len;\
|
||||
char buffer[2048];\
|
||||
clGetProgramBuildInfo(program,device_list[i],CL_PROGRAM_BUILD_LOG,sizeof(buffer),buffer,&len);\
|
||||
log_error("DEVICE %u CL BUILD ERROR: %s(%u): ",i,__FILE__,__LINE__);\
|
||||
log_error(format,## __VA_ARGS__ );\
|
||||
log_error("\n");\
|
||||
}\
|
||||
free(device_list);\
|
||||
return -1;\
|
||||
}\
|
||||
}
|
||||
|
||||
const char* src[] = {
|
||||
"__kernel void simple_task(__global float* output) {\n"
|
||||
" output[0] += 1;\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
enum { MaxDevices = 8 };
|
||||
|
||||
int test_userevents( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
cl_event u1 = clCreateUserEvent( context, &err );
|
||||
CL_EXIT_ERROR(err,"clCreateUserEvent failed");
|
||||
|
||||
// Test event properties.
|
||||
cl_int s;
|
||||
size_t sizeofs;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof s, &s, &sizeofs),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof s == sizeofs) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_COMMAND_EXECUTION_STATUS");
|
||||
CL_EXIT_ERROR((s == CL_SUBMITTED) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_COMMAND_EXECUTION_STATUS");
|
||||
|
||||
cl_command_type t;
|
||||
size_t sizeoft;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_TYPE, sizeof t, &t, &sizeoft),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof t == sizeoft) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_COMMAND_TYPE");
|
||||
CL_EXIT_ERROR((t == CL_COMMAND_USER) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_COMMAND_TYPE");
|
||||
|
||||
cl_command_queue q;
|
||||
size_t sizeofq;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_QUEUE, sizeof q, &q, &sizeofq),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof q == sizeofq) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_COMMAND_QUEUE");
|
||||
CL_EXIT_ERROR((q == NULL) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_COMMAND_QUEUE");
|
||||
|
||||
cl_context c;
|
||||
size_t sizeofc;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_CONTEXT, sizeof c, &c, &sizeofc),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof c == sizeofc) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_CONTEXT");
|
||||
CL_EXIT_ERROR((c == context) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_CONTEXT");
|
||||
|
||||
cl_ulong p;
|
||||
err = clGetEventProfilingInfo(u1,CL_PROFILING_COMMAND_QUEUED,sizeof p,&p,0);
|
||||
CL_EXIT_ERROR((err != CL_SUCCESS) ? CL_SUCCESS : -1,"clGetEventProfilingInfo returned wrong error.");
|
||||
|
||||
// Test semantics.
|
||||
cl_program program = clCreateProgramWithSource(context,1,src,NULL,&err);
|
||||
CL_EXIT_ERROR(err,"clCreateProgramWithSource failed");
|
||||
|
||||
CL_EXIT_BUILD_ERROR(clBuildProgram(program,0,NULL,"",NULL,NULL),program,"Building program from inline src:\t%s",src[0]);
|
||||
|
||||
cl_kernel k0 = clCreateKernel(program,"simple_task",&err);
|
||||
CL_EXIT_ERROR(err,"clCreateKernel failed");
|
||||
|
||||
float buffer[1];
|
||||
cl_mem output = clCreateBuffer(context,CL_MEM_USE_HOST_PTR,sizeof buffer, buffer, &err);
|
||||
CL_EXIT_ERROR(err,"clCreateBuffer failed.");
|
||||
|
||||
CL_EXIT_ERROR(clSetKernelArg(k0,0,sizeof(output),&output),"clSetKernelArg failed");
|
||||
|
||||
|
||||
// Successful case. //////////////////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
cl_event e[4];
|
||||
cl_uint N = sizeof e / sizeof(cl_event);
|
||||
|
||||
log_info("Enqueuing tasks\n");
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clEnqueueTask(queue,k0,1,&u1,&e[i]),"clEnqueueTaskFailed");
|
||||
|
||||
log_info("Checking task status before setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s >= CL_SUBMITTED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status before user event",i);
|
||||
}
|
||||
|
||||
log_info("Setting user event status to complete\n");
|
||||
CL_EXIT_ERROR(clSetUserEventStatus(u1,CL_COMPLETE),"clSetUserEventStatus failed");
|
||||
|
||||
log_info("Waiting for tasks to finish executing\n");
|
||||
CL_EXIT_ERROR(clWaitForEvents( 1, &e[N-1] ),"clWaitForEvent failed");
|
||||
|
||||
log_info("Checking task status after setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s != CL_QUEUED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status %04x after successful user event",i,s);
|
||||
}
|
||||
|
||||
CL_EXIT_ERROR(clReleaseEvent(u1),"clReleaseEvent failed");
|
||||
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clReleaseEvent(e[i]),"clReleaseEvent failed");
|
||||
|
||||
log_info("Successful user event case passed.\n");
|
||||
|
||||
}
|
||||
|
||||
// Test unsuccessful user event case. ///////////////////////////////////////////////////////////////////
|
||||
{
|
||||
cl_event u2 = clCreateUserEvent( context, &err );
|
||||
CL_EXIT_ERROR(err,"clCreateUserEvent failed");
|
||||
|
||||
cl_event e[4];
|
||||
cl_uint N = sizeof e / sizeof(cl_event);
|
||||
|
||||
log_info("Enqueuing tasks\n");
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clEnqueueTask(queue,k0,1,&u2,&e[i]),"clEnqueueTaskFailed");
|
||||
|
||||
log_info("Checking task status before setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s == CL_QUEUED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status before user event",i);
|
||||
}
|
||||
|
||||
log_info("Setting user event status to unsuccessful result\n");
|
||||
CL_EXIT_ERROR(clSetUserEventStatus(u2,-1),"clSetUserEventStatus failed");
|
||||
|
||||
log_info("Waiting for tasks to finish executing\n");
|
||||
CL_EXIT_ERROR((clWaitForEvents( N, &e[0] )!=CL_SUCCESS) ? CL_SUCCESS : -1,"clWaitForEvent succeeded when it should have failed");
|
||||
|
||||
log_info("Checking task status after setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s != CL_QUEUED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status %04x after unsuccessful user event",i,s);
|
||||
}
|
||||
|
||||
CL_EXIT_ERROR(clReleaseEvent(u2),"clReleaseEvent failed");
|
||||
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clReleaseEvent(e[i]),"clReleaseEvent failed");
|
||||
|
||||
log_info("Unsuccessful user event case passed.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
test_start();
|
||||
|
||||
cl_device_type device_type;
|
||||
CL_DEVICE_TYPE_ENV( device_type );
|
||||
|
||||
cl_device_id device_id;
|
||||
CL_EXIT_ERROR(clGetDeviceIDs(NULL, device_type, 1, &device_id, NULL),"GetDeviceIDs");
|
||||
|
||||
// Create a context.
|
||||
cl_context context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
|
||||
CL_EXIT_ERROR(err,"CreateContext");
|
||||
|
||||
// Create a command queue.
|
||||
q = clCreateCommandQueue(context,device_id,0,&err);
|
||||
CL_EXIT_ERROR(err,"clCreateCommandQueue failed");
|
||||
|
||||
int ret = test_userevents( device_type, context, queue, 0 );
|
||||
|
||||
test_finish();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenCL/opencl.h>
|
||||
#include <mach/mach_time.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ATF performance framework.
|
||||
|
||||
#if USE_ATF
|
||||
#include <ATF/ATF.h>
|
||||
#define test_start() ATFTestStart()
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) ATFLogPerformanceNumber(_number, _higherBetter, _numType, _format,##__VA_ARGS__)
|
||||
#define log_info ATFLogInfo
|
||||
#define log_error ATFLogError
|
||||
#define log_no_atf
|
||||
#define test_finish() ATFTestFinish()
|
||||
#else
|
||||
#define test_start()
|
||||
#define log_perf(_number, _higherBetter, _numType, _format, ...) printf("Performance Number " _format " (in %s, %s): %g\n",##__VA_ARGS__, _numType, _higherBetter?"higher is better":"lower is better" , _number)
|
||||
#define log_info(...) fprintf(stdout, ## __VA_ARGS__ )
|
||||
#define log_error(...) fprintf(stderr, ## __VA_ARGS__ )
|
||||
#define log_info_no_atf(...) log_info(## __VA_ARGS__ )
|
||||
#define test_finish()
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CL error checking.
|
||||
|
||||
#define CL_DEVICE_TYPE_ENV_MUST_BE( bitfield_ )\
|
||||
{\
|
||||
cl_device_type device_type = CL_DEVICE_TYPE_DEFAULT;\
|
||||
const char* device_env = getenv("CL_DEVICE_TYPE");\
|
||||
if (device_env != NULL) {\
|
||||
if (!strcmp( device_env, "gpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_GPU" ))\
|
||||
device_type = CL_DEVICE_TYPE_GPU;\
|
||||
else if(!strcmp( device_env, "cpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_CPU" ))\
|
||||
device_type = CL_DEVICE_TYPE_CPU;\
|
||||
else if(!strcmp( device_env, "default" ) || !strcmp( device_env, "CL_DEVICE_TYPE_DEFAULT" ))\
|
||||
device_type = CL_DEVICE_TYPE_DEFAULT;\
|
||||
if (!(device_type & bitfield_)) {\
|
||||
log_error( "CL_DEVICE_TYPE environment variable \"%s\" must be \"%s\".", device_env, #bitfield_ );\
|
||||
abort();\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
|
||||
#define CL_DEVICE_TYPE_ENV( device_type_ )\
|
||||
{\
|
||||
const char* device_env = getenv("CL_DEVICE_TYPE");\
|
||||
if (device_env != NULL) {\
|
||||
if (!strcmp( device_env, "gpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_GPU" ))\
|
||||
device_type_ = CL_DEVICE_TYPE_GPU;\
|
||||
else if(!strcmp( device_env, "cpu" ) || !strcmp( device_env, "CL_DEVICE_TYPE_CPU" ))\
|
||||
device_type_ = CL_DEVICE_TYPE_CPU;\
|
||||
else if(!strcmp( device_env, "default" ) || !strcmp( device_env, "CL_DEVICE_TYPE_DEFAULT" ))\
|
||||
device_type_ = CL_DEVICE_TYPE_DEFAULT;\
|
||||
}\
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define CL_EXIT_ERROR(cmd,...) \
|
||||
{ \
|
||||
if ((cmd) != CL_SUCCESS) { \
|
||||
log_error("CL ERROR: %s %u: ", __FILE__,__LINE__);\
|
||||
log_error(## __VA_ARGS__ );\
|
||||
log_error("\n");\
|
||||
return -1;\
|
||||
}\
|
||||
}
|
||||
#else
|
||||
#define CL_EXIT_ERROR(cmd,format,...) \
|
||||
{ \
|
||||
if ((cmd) != CL_SUCCESS) { \
|
||||
log_error("CL ERROR: %s %u: ", __FILE__,__LINE__);\
|
||||
log_error(format,## __VA_ARGS__ );\
|
||||
log_error("\n");\
|
||||
return -1;\
|
||||
}\
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CL_EXIT_BUILD_ERROR(cmd,program,format,...) \
|
||||
{ \
|
||||
if ((cmd) != CL_SUCCESS) { \
|
||||
cl_uint num_devices_;\
|
||||
clGetProgramInfo(program,CL_PROGRAM_NUM_DEVICES,sizeof(num_devices_),&num_devices_,NULL);\
|
||||
cl_device_id *device_list;\
|
||||
device_list=(cl_device_id *)malloc(num_devices_*sizeof(cl_device_id));\
|
||||
clGetProgramInfo(program,CL_PROGRAM_DEVICES,num_devices_*sizeof(cl_device_id),device_list,NULL);\
|
||||
for (unsigned i=0;i<num_devices_;++i) {\
|
||||
size_t len;\
|
||||
char buffer[2048];\
|
||||
clGetProgramBuildInfo(program,device_list[i],CL_PROGRAM_BUILD_LOG,sizeof(buffer),buffer,&len);\
|
||||
log_error("DEVICE %u CL BUILD ERROR: %s(%u): ",i,__FILE__,__LINE__);\
|
||||
log_error(format,## __VA_ARGS__ );\
|
||||
log_error("\n");\
|
||||
}\
|
||||
free(device_list);\
|
||||
return -1;\
|
||||
}\
|
||||
}
|
||||
|
||||
const char* src[] = {
|
||||
"__kernel void simple_task(__global float* output) {\n"
|
||||
" output[0] += 1;\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
enum { MaxDevices = 8 };
|
||||
|
||||
int test_userevents( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
cl_event u1 = clCreateUserEvent( context, &err );
|
||||
CL_EXIT_ERROR(err,"clCreateUserEvent failed");
|
||||
|
||||
// Test event properties.
|
||||
cl_int s;
|
||||
size_t sizeofs;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof s, &s, &sizeofs),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof s == sizeofs) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_COMMAND_EXECUTION_STATUS");
|
||||
CL_EXIT_ERROR((s == CL_SUBMITTED) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_COMMAND_EXECUTION_STATUS");
|
||||
|
||||
cl_command_type t;
|
||||
size_t sizeoft;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_TYPE, sizeof t, &t, &sizeoft),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof t == sizeoft) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_COMMAND_TYPE");
|
||||
CL_EXIT_ERROR((t == CL_COMMAND_USER) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_COMMAND_TYPE");
|
||||
|
||||
cl_command_queue q;
|
||||
size_t sizeofq;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_COMMAND_QUEUE, sizeof q, &q, &sizeofq),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof q == sizeofq) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_COMMAND_QUEUE");
|
||||
CL_EXIT_ERROR((q == NULL) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_COMMAND_QUEUE");
|
||||
|
||||
cl_context c;
|
||||
size_t sizeofc;
|
||||
CL_EXIT_ERROR(clGetEventInfo(u1, CL_EVENT_CONTEXT, sizeof c, &c, &sizeofc),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((sizeof c == sizeofc) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong size for CL_EVENT_CONTEXT");
|
||||
CL_EXIT_ERROR((c == context) ? CL_SUCCESS : -1,"clGetEventInfo returned wrong value for CL_EVENT_CONTEXT");
|
||||
|
||||
cl_ulong p;
|
||||
err = clGetEventProfilingInfo(u1,CL_PROFILING_COMMAND_QUEUED,sizeof p,&p,0);
|
||||
CL_EXIT_ERROR((err != CL_SUCCESS) ? CL_SUCCESS : -1,"clGetEventProfilingInfo returned wrong error.");
|
||||
|
||||
// Test semantics.
|
||||
cl_program program = clCreateProgramWithSource(context,1,src,NULL,&err);
|
||||
CL_EXIT_ERROR(err,"clCreateProgramWithSource failed");
|
||||
|
||||
CL_EXIT_BUILD_ERROR(clBuildProgram(program,0,NULL,"",NULL,NULL),program,"Building program from inline src:\t%s",src[0]);
|
||||
|
||||
cl_kernel k0 = clCreateKernel(program,"simple_task",&err);
|
||||
CL_EXIT_ERROR(err,"clCreateKernel failed");
|
||||
|
||||
float buffer[1];
|
||||
cl_mem output = clCreateBuffer(context,CL_MEM_USE_HOST_PTR,sizeof buffer, buffer, &err);
|
||||
CL_EXIT_ERROR(err,"clCreateBuffer failed.");
|
||||
|
||||
CL_EXIT_ERROR(clSetKernelArg(k0,0,sizeof(output),&output),"clSetKernelArg failed");
|
||||
|
||||
|
||||
// Successful case. //////////////////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
cl_event e[4];
|
||||
cl_uint N = sizeof e / sizeof(cl_event);
|
||||
|
||||
log_info("Enqueuing tasks\n");
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clEnqueueTask(queue,k0,1,&u1,&e[i]),"clEnqueueTaskFailed");
|
||||
|
||||
log_info("Checking task status before setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s >= CL_SUBMITTED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status before user event",i);
|
||||
}
|
||||
|
||||
log_info("Setting user event status to complete\n");
|
||||
CL_EXIT_ERROR(clSetUserEventStatus(u1,CL_COMPLETE),"clSetUserEventStatus failed");
|
||||
|
||||
log_info("Waiting for tasks to finish executing\n");
|
||||
CL_EXIT_ERROR(clWaitForEvents( 1, &e[N-1] ),"clWaitForEvent failed");
|
||||
|
||||
log_info("Checking task status after setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s != CL_QUEUED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status %04x after successful user event",i,s);
|
||||
}
|
||||
|
||||
CL_EXIT_ERROR(clReleaseEvent(u1),"clReleaseEvent failed");
|
||||
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clReleaseEvent(e[i]),"clReleaseEvent failed");
|
||||
|
||||
log_info("Successful user event case passed.\n");
|
||||
|
||||
}
|
||||
|
||||
// Test unsuccessful user event case. ///////////////////////////////////////////////////////////////////
|
||||
{
|
||||
cl_event u2 = clCreateUserEvent( context, &err );
|
||||
CL_EXIT_ERROR(err,"clCreateUserEvent failed");
|
||||
|
||||
cl_event e[4];
|
||||
cl_uint N = sizeof e / sizeof(cl_event);
|
||||
|
||||
log_info("Enqueuing tasks\n");
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clEnqueueTask(queue,k0,1,&u2,&e[i]),"clEnqueueTaskFailed");
|
||||
|
||||
log_info("Checking task status before setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s == CL_QUEUED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status before user event",i);
|
||||
}
|
||||
|
||||
log_info("Setting user event status to unsuccessful result\n");
|
||||
CL_EXIT_ERROR(clSetUserEventStatus(u2,-1),"clSetUserEventStatus failed");
|
||||
|
||||
log_info("Waiting for tasks to finish executing\n");
|
||||
CL_EXIT_ERROR((clWaitForEvents( N, &e[0] )!=CL_SUCCESS) ? CL_SUCCESS : -1,"clWaitForEvent succeeded when it should have failed");
|
||||
|
||||
log_info("Checking task status after setting user event status\n");
|
||||
for (cl_uint i = 0; i != N; ++i) {
|
||||
CL_EXIT_ERROR(clGetEventInfo(e[i],CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof s,&s,0),"clGetEventInfo failed");
|
||||
CL_EXIT_ERROR((s != CL_QUEUED) ? CL_SUCCESS : -1,"clGetEventInfo %u returned wrong status %04x after unsuccessful user event",i,s);
|
||||
}
|
||||
|
||||
CL_EXIT_ERROR(clReleaseEvent(u2),"clReleaseEvent failed");
|
||||
|
||||
for (cl_uint i = 0; i != N; ++i)
|
||||
CL_EXIT_ERROR(clReleaseEvent(e[i]),"clReleaseEvent failed");
|
||||
|
||||
log_info("Unsuccessful user event case passed.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
test_start();
|
||||
|
||||
cl_device_type device_type;
|
||||
CL_DEVICE_TYPE_ENV( device_type );
|
||||
|
||||
cl_device_id device_id;
|
||||
CL_EXIT_ERROR(clGetDeviceIDs(NULL, device_type, 1, &device_id, NULL),"GetDeviceIDs");
|
||||
|
||||
// Create a context.
|
||||
cl_context context = clCreateContext(0, 1, &device_id, NULL, NULL, &err);
|
||||
CL_EXIT_ERROR(err,"CreateContext");
|
||||
|
||||
// Create a command queue.
|
||||
q = clCreateCommandQueue(context,device_id,0,&err);
|
||||
CL_EXIT_ERROR(err,"clCreateCommandQueue failed");
|
||||
|
||||
int ret = test_userevents( device_type, context, queue, 0 );
|
||||
|
||||
test_finish();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,82 +1,82 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "action_classes.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/genericThread.h"
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif // !_MSC_VER
|
||||
|
||||
class releaseEvent_thread : public genericThread
|
||||
{
|
||||
public:
|
||||
releaseEvent_thread( cl_event *event ) : mEvent( event ) {}
|
||||
|
||||
cl_event * mEvent;
|
||||
|
||||
protected:
|
||||
virtual void * IRun( void )
|
||||
{
|
||||
usleep( 1000000 );
|
||||
log_info( "\tTriggering gate from separate thread...\n" );
|
||||
clSetUserEventStatus( *mEvent, CL_COMPLETE );
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
int test_userevents_multithreaded( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
|
||||
// Set up a user event to act as a gate
|
||||
clEventWrapper gateEvent = clCreateUserEvent( context, &error );
|
||||
test_error( error, "Unable to create user gate event" );
|
||||
|
||||
// Set up a few actions gated on the user event
|
||||
NDRangeKernelAction action1;
|
||||
ReadBufferAction action2;
|
||||
WriteBufferAction action3;
|
||||
|
||||
clEventWrapper actionEvents[ 3 ];
|
||||
Action * actions[] = { &action1, &action2, &action3, NULL };
|
||||
|
||||
for( int i = 0; actions[ i ] != NULL; i++ )
|
||||
{
|
||||
error = actions[ i ]->Setup( deviceID, context, queue );
|
||||
test_error( error, "Unable to set up test action" );
|
||||
|
||||
error = actions[ i ]->Execute( queue, 1, &gateEvent, &actionEvents[ i ] );
|
||||
test_error( error, "Unable to execute test action" );
|
||||
}
|
||||
|
||||
// Now, instead of releasing the gate, we spawn a separate thread to do so
|
||||
releaseEvent_thread thread( &gateEvent );
|
||||
log_info( "\tStarting trigger thread...\n" );
|
||||
thread.Start();
|
||||
|
||||
log_info( "\tWaiting for actions...\n" );
|
||||
error = clWaitForEvents( 3, &actionEvents[ 0 ] );
|
||||
test_error( error, "Unable to wait for action events" );
|
||||
|
||||
log_info( "\tActions completed.\n" );
|
||||
|
||||
// If we got here without error, we're good
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "action_classes.h"
|
||||
#include "../../test_common/harness/conversions.h"
|
||||
#include "../../test_common/harness/genericThread.h"
|
||||
|
||||
#if !defined (_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif // !_MSC_VER
|
||||
|
||||
class releaseEvent_thread : public genericThread
|
||||
{
|
||||
public:
|
||||
releaseEvent_thread( cl_event *event ) : mEvent( event ) {}
|
||||
|
||||
cl_event * mEvent;
|
||||
|
||||
protected:
|
||||
virtual void * IRun( void )
|
||||
{
|
||||
usleep( 1000000 );
|
||||
log_info( "\tTriggering gate from separate thread...\n" );
|
||||
clSetUserEventStatus( *mEvent, CL_COMPLETE );
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
int test_userevents_multithreaded( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
|
||||
|
||||
// Set up a user event to act as a gate
|
||||
clEventWrapper gateEvent = clCreateUserEvent( context, &error );
|
||||
test_error( error, "Unable to create user gate event" );
|
||||
|
||||
// Set up a few actions gated on the user event
|
||||
NDRangeKernelAction action1;
|
||||
ReadBufferAction action2;
|
||||
WriteBufferAction action3;
|
||||
|
||||
clEventWrapper actionEvents[ 3 ];
|
||||
Action * actions[] = { &action1, &action2, &action3, NULL };
|
||||
|
||||
for( int i = 0; actions[ i ] != NULL; i++ )
|
||||
{
|
||||
error = actions[ i ]->Setup( deviceID, context, queue );
|
||||
test_error( error, "Unable to set up test action" );
|
||||
|
||||
error = actions[ i ]->Execute( queue, 1, &gateEvent, &actionEvents[ i ] );
|
||||
test_error( error, "Unable to execute test action" );
|
||||
}
|
||||
|
||||
// Now, instead of releasing the gate, we spawn a separate thread to do so
|
||||
releaseEvent_thread thread( &gateEvent );
|
||||
log_info( "\tStarting trigger thread...\n" );
|
||||
thread.Start();
|
||||
|
||||
log_info( "\tWaiting for actions...\n" );
|
||||
error = clWaitForEvents( 3, &actionEvents[ 0 ] );
|
||||
test_error( error, "Unable to wait for action events" );
|
||||
|
||||
log_info( "\tActions completed.\n" );
|
||||
|
||||
// If we got here without error, we're good
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,322 +1,322 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "action_classes.h"
|
||||
|
||||
|
||||
extern const char *IGetStatusString( cl_int status );
|
||||
|
||||
#define PRINT_OPS 0
|
||||
|
||||
int test_waitlist( cl_device_id device, cl_context context, cl_command_queue queue, Action *actionToTest, bool multiple )
|
||||
{
|
||||
NDRangeKernelAction actions[ 2 ];
|
||||
clEventWrapper events[ 3 ];
|
||||
cl_int status[ 3 ];
|
||||
cl_int error;
|
||||
|
||||
if (multiple)
|
||||
log_info("\tExecuting reference event 0, then reference event 1 with reference event 0 in its waitlist, then test event 2 with reference events 0 and 1 in its waitlist.\n");
|
||||
else
|
||||
log_info("\tExecuting reference event 0, then test event 2 with reference event 0 in its waitlist.\n");
|
||||
|
||||
// Set up the first base action to wait against
|
||||
error = actions[ 0 ].Setup( device, context, queue );
|
||||
test_error( error, "Unable to setup base event to wait against" );
|
||||
|
||||
if( multiple )
|
||||
{
|
||||
// Set up a second event to wait against
|
||||
error = actions[ 1 ].Setup( device, context, queue );
|
||||
test_error( error, "Unable to setup second base event to wait against" );
|
||||
}
|
||||
|
||||
// Now set up the actual action to test
|
||||
error = actionToTest->Setup( device, context, queue );
|
||||
test_error( error, "Unable to set up test event" );
|
||||
|
||||
// Execute all events now
|
||||
if (PRINT_OPS) log_info("\tExecuting action 0...\n");
|
||||
error = actions[ 0 ].Execute( queue, 0, NULL, &events[ 0 ] );
|
||||
test_error( error, "Unable to execute first event" );
|
||||
|
||||
if( multiple )
|
||||
{
|
||||
if (PRINT_OPS) log_info("\tExecuting action 1...\n");
|
||||
error = actions[ 1 ].Execute( queue, 1, &events[0], &events[ 1 ] );
|
||||
test_error( error, "Unable to execute second event" );
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after starting reference events: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), "N/A");
|
||||
|
||||
if( ( status[ 0 ] == CL_COMPLETE ) || ( multiple && status[ 1 ] == CL_COMPLETE ) )
|
||||
{
|
||||
log_info( "WARNING: Reference event(s) already completed before we could execute test event! Possible that the reference event blocked (implicitly passing)\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PRINT_OPS) log_info("\tExecuting action to test...\n");
|
||||
error = actionToTest->Execute( queue, ( multiple ) ? 2 : 1, &events[ 0 ], &events[ 2 ] );
|
||||
test_error( error, "Unable to execute test event" );
|
||||
|
||||
// Hopefully, the first event is still running
|
||||
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
||||
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after starting test event: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
if( multiple )
|
||||
{
|
||||
if( status[ 0 ] == CL_COMPLETE && status[ 1 ] == CL_COMPLETE )
|
||||
{
|
||||
log_info( "WARNING: Both events completed, so unable to test further (implicitly passing).\n" );
|
||||
clFinish( queue );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(status[1] == CL_COMPLETE && status[0] != CL_COMPLETE)
|
||||
{
|
||||
log_error("ERROR: Test failed because the second wait event is complete and the first is not.(status: 0: %s and 1: %s)\n", IGetStatusString( status[ 0 ] ), IGetStatusString( status[ 1 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( status[ 0 ] == CL_COMPLETE )
|
||||
{
|
||||
log_info( "WARNING: Reference event completed, so unable to test further (implicitly passing).\n" );
|
||||
clFinish( queue );
|
||||
return 0;
|
||||
}
|
||||
if( status[ 0 ] != CL_RUNNING && status[ 0 ] != CL_QUEUED && status[ 0 ] != CL_SUBMITTED )
|
||||
{
|
||||
log_error( "ERROR: Test failed because first wait event is not currently running, queued, or submitted! (status: 0: %s)\n", IGetStatusString( status[ 0 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( status[ 2 ] != CL_QUEUED && status[ 2 ] != CL_SUBMITTED )
|
||||
{
|
||||
log_error( "ERROR: Test event is not waiting to run! (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now wait for the first reference event
|
||||
if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
|
||||
error = clWaitForEvents( 1, &events[ 0 ] );
|
||||
test_error( error, "Unable to wait for reference event" );
|
||||
|
||||
// Grab statuses again
|
||||
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
||||
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after waiting for reference event 0: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
// Sanity
|
||||
if( status[ 0 ] != CL_COMPLETE )
|
||||
{
|
||||
log_error( "ERROR: Waited for first event but it's not complete (status: 0: %s)\n", IGetStatusString( status[ 0 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If we're multiple, and the second event isn't complete, then our test event should still be queued
|
||||
if( multiple && status[ 1 ] != CL_COMPLETE )
|
||||
{
|
||||
if( status[ 1 ] == CL_RUNNING && status[ 2 ] == CL_RUNNING ) {
|
||||
log_error("ERROR: Test event and second event are both running.\n");
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
if( status[ 2 ] != CL_QUEUED && status[ 2 ] != CL_SUBMITTED )
|
||||
{
|
||||
log_error( "ERROR: Test event did not wait for second event before starting! (status of ref: 1: %s, of test: 2: %s)\n", IGetStatusString( status[ 1 ] ), IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now wait for second event to complete, too
|
||||
if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
|
||||
error = clWaitForEvents( 1, &events[ 1 ] );
|
||||
test_error( error, "Unable to wait for second reference event" );
|
||||
|
||||
// Grab statuses again
|
||||
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
||||
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after waiting for reference event 1: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
// Sanity
|
||||
if( status[ 1 ] != CL_COMPLETE )
|
||||
{
|
||||
log_error( "ERROR: Waited for second reference event but it didn't complete (status: 1: %s)\n", IGetStatusString( status[ 1 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the test event SHOULD be running, but if it completed, we consider it a pass
|
||||
if( status[ 2 ] == CL_COMPLETE )
|
||||
{
|
||||
log_info( "WARNING: Test event already completed. Assumed valid.\n" );
|
||||
clFinish( queue );
|
||||
return 0;
|
||||
}
|
||||
if( status[ 2 ] != CL_RUNNING && status[ 2 ] != CL_SUBMITTED && status[ 2 ] != CL_QUEUED)
|
||||
{
|
||||
log_error( "ERROR: Second event did not start running after reference event(s) completed! (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Wait for the test event, then return
|
||||
if (PRINT_OPS) log_info("\tWaiting for action 2 to test to finish...\n");
|
||||
error = clWaitForEvents( 1, &events[ 2 ] );
|
||||
test_error( error, "Unable to wait for test event" );
|
||||
|
||||
error |= clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after waiting for test event: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
// Sanity
|
||||
if( status[ 2 ] != CL_COMPLETE )
|
||||
{
|
||||
log_error( "ERROR: Test event didn't complete (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
clFinish(queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_ACTION( name ) \
|
||||
{ \
|
||||
name##Action action; \
|
||||
log_info( "-- Testing " #name " (waiting on 1 event)...\n" ); \
|
||||
if( ( error = test_waitlist( deviceID, context, queue, &action, false ) ) != CL_SUCCESS ) \
|
||||
retVal++; \
|
||||
clFinish( queue ); \
|
||||
} \
|
||||
if( error == CL_SUCCESS ) /* Only run multiples test if single test passed */ \
|
||||
{ \
|
||||
name##Action action; \
|
||||
log_info( "-- Testing " #name " (waiting on 2 events)...\n" ); \
|
||||
if( ( error = test_waitlist( deviceID, context, queue, &action, true ) ) != CL_SUCCESS ) \
|
||||
retVal++; \
|
||||
clFinish( queue ); \
|
||||
}
|
||||
|
||||
int test_waitlists( cl_device_id deviceID, cl_context context, cl_command_queue oldQueue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
int retVal = 0;
|
||||
|
||||
if( !checkDeviceForQueueSupport( deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ) )
|
||||
{
|
||||
log_info( "WARNING: Device does not support out-of-order exec mode; skipping test.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
clCommandQueueWrapper queue = clCreateCommandQueue( context, deviceID,
|
||||
(cl_command_queue_properties)CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &error );
|
||||
test_error(error, "Unable to create out-of-order queue");
|
||||
|
||||
log_info( "\n" );
|
||||
|
||||
TEST_ACTION( NDRangeKernel )
|
||||
|
||||
TEST_ACTION( ReadBuffer )
|
||||
TEST_ACTION( WriteBuffer )
|
||||
TEST_ACTION( MapBuffer )
|
||||
TEST_ACTION( UnmapBuffer )
|
||||
|
||||
if( checkForImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
log_info( "\nNote: device does not support images. Skipping remainder of waitlist tests...\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage2D )
|
||||
TEST_ACTION( WriteImage2D )
|
||||
TEST_ACTION( CopyImage2Dto2D )
|
||||
TEST_ACTION( Copy2DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo2DImage )
|
||||
TEST_ACTION( MapImage )
|
||||
|
||||
if( checkFor3DImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
log_info("Device does not support 3D images. Skipping remainder of waitlist tests...\n");
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage3D )
|
||||
TEST_ACTION( WriteImage3D )
|
||||
TEST_ACTION( CopyImage2Dto3D )
|
||||
TEST_ACTION( CopyImage3Dto2D )
|
||||
TEST_ACTION( CopyImage3Dto3D )
|
||||
TEST_ACTION( Copy3DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo3DImage )
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "testBase.h"
|
||||
#include "action_classes.h"
|
||||
|
||||
|
||||
extern const char *IGetStatusString( cl_int status );
|
||||
|
||||
#define PRINT_OPS 0
|
||||
|
||||
int test_waitlist( cl_device_id device, cl_context context, cl_command_queue queue, Action *actionToTest, bool multiple )
|
||||
{
|
||||
NDRangeKernelAction actions[ 2 ];
|
||||
clEventWrapper events[ 3 ];
|
||||
cl_int status[ 3 ];
|
||||
cl_int error;
|
||||
|
||||
if (multiple)
|
||||
log_info("\tExecuting reference event 0, then reference event 1 with reference event 0 in its waitlist, then test event 2 with reference events 0 and 1 in its waitlist.\n");
|
||||
else
|
||||
log_info("\tExecuting reference event 0, then test event 2 with reference event 0 in its waitlist.\n");
|
||||
|
||||
// Set up the first base action to wait against
|
||||
error = actions[ 0 ].Setup( device, context, queue );
|
||||
test_error( error, "Unable to setup base event to wait against" );
|
||||
|
||||
if( multiple )
|
||||
{
|
||||
// Set up a second event to wait against
|
||||
error = actions[ 1 ].Setup( device, context, queue );
|
||||
test_error( error, "Unable to setup second base event to wait against" );
|
||||
}
|
||||
|
||||
// Now set up the actual action to test
|
||||
error = actionToTest->Setup( device, context, queue );
|
||||
test_error( error, "Unable to set up test event" );
|
||||
|
||||
// Execute all events now
|
||||
if (PRINT_OPS) log_info("\tExecuting action 0...\n");
|
||||
error = actions[ 0 ].Execute( queue, 0, NULL, &events[ 0 ] );
|
||||
test_error( error, "Unable to execute first event" );
|
||||
|
||||
if( multiple )
|
||||
{
|
||||
if (PRINT_OPS) log_info("\tExecuting action 1...\n");
|
||||
error = actions[ 1 ].Execute( queue, 1, &events[0], &events[ 1 ] );
|
||||
test_error( error, "Unable to execute second event" );
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after starting reference events: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), "N/A");
|
||||
|
||||
if( ( status[ 0 ] == CL_COMPLETE ) || ( multiple && status[ 1 ] == CL_COMPLETE ) )
|
||||
{
|
||||
log_info( "WARNING: Reference event(s) already completed before we could execute test event! Possible that the reference event blocked (implicitly passing)\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PRINT_OPS) log_info("\tExecuting action to test...\n");
|
||||
error = actionToTest->Execute( queue, ( multiple ) ? 2 : 1, &events[ 0 ], &events[ 2 ] );
|
||||
test_error( error, "Unable to execute test event" );
|
||||
|
||||
// Hopefully, the first event is still running
|
||||
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
||||
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after starting test event: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
if( multiple )
|
||||
{
|
||||
if( status[ 0 ] == CL_COMPLETE && status[ 1 ] == CL_COMPLETE )
|
||||
{
|
||||
log_info( "WARNING: Both events completed, so unable to test further (implicitly passing).\n" );
|
||||
clFinish( queue );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(status[1] == CL_COMPLETE && status[0] != CL_COMPLETE)
|
||||
{
|
||||
log_error("ERROR: Test failed because the second wait event is complete and the first is not.(status: 0: %s and 1: %s)\n", IGetStatusString( status[ 0 ] ), IGetStatusString( status[ 1 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( status[ 0 ] == CL_COMPLETE )
|
||||
{
|
||||
log_info( "WARNING: Reference event completed, so unable to test further (implicitly passing).\n" );
|
||||
clFinish( queue );
|
||||
return 0;
|
||||
}
|
||||
if( status[ 0 ] != CL_RUNNING && status[ 0 ] != CL_QUEUED && status[ 0 ] != CL_SUBMITTED )
|
||||
{
|
||||
log_error( "ERROR: Test failed because first wait event is not currently running, queued, or submitted! (status: 0: %s)\n", IGetStatusString( status[ 0 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if( status[ 2 ] != CL_QUEUED && status[ 2 ] != CL_SUBMITTED )
|
||||
{
|
||||
log_error( "ERROR: Test event is not waiting to run! (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now wait for the first reference event
|
||||
if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
|
||||
error = clWaitForEvents( 1, &events[ 0 ] );
|
||||
test_error( error, "Unable to wait for reference event" );
|
||||
|
||||
// Grab statuses again
|
||||
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
||||
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after waiting for reference event 0: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
// Sanity
|
||||
if( status[ 0 ] != CL_COMPLETE )
|
||||
{
|
||||
log_error( "ERROR: Waited for first event but it's not complete (status: 0: %s)\n", IGetStatusString( status[ 0 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If we're multiple, and the second event isn't complete, then our test event should still be queued
|
||||
if( multiple && status[ 1 ] != CL_COMPLETE )
|
||||
{
|
||||
if( status[ 1 ] == CL_RUNNING && status[ 2 ] == CL_RUNNING ) {
|
||||
log_error("ERROR: Test event and second event are both running.\n");
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
if( status[ 2 ] != CL_QUEUED && status[ 2 ] != CL_SUBMITTED )
|
||||
{
|
||||
log_error( "ERROR: Test event did not wait for second event before starting! (status of ref: 1: %s, of test: 2: %s)\n", IGetStatusString( status[ 1 ] ), IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now wait for second event to complete, too
|
||||
if (PRINT_OPS) log_info("\tWaiting for action 1 to finish...\n");
|
||||
error = clWaitForEvents( 1, &events[ 1 ] );
|
||||
test_error( error, "Unable to wait for second reference event" );
|
||||
|
||||
// Grab statuses again
|
||||
if (PRINT_OPS) log_info("\tChecking status of action to test 2...\n");
|
||||
error = clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
if( multiple ) {
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 1...\n");
|
||||
error = clGetEventInfo( events[ 1 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 1 ] ), &status[ 1 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
}
|
||||
if (PRINT_OPS) log_info("\tChecking status of action 0...\n");
|
||||
error = clGetEventInfo( events[ 0 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 0 ] ), &status[ 0 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after waiting for reference event 1: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
// Sanity
|
||||
if( status[ 1 ] != CL_COMPLETE )
|
||||
{
|
||||
log_error( "ERROR: Waited for second reference event but it didn't complete (status: 1: %s)\n", IGetStatusString( status[ 1 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, the test event SHOULD be running, but if it completed, we consider it a pass
|
||||
if( status[ 2 ] == CL_COMPLETE )
|
||||
{
|
||||
log_info( "WARNING: Test event already completed. Assumed valid.\n" );
|
||||
clFinish( queue );
|
||||
return 0;
|
||||
}
|
||||
if( status[ 2 ] != CL_RUNNING && status[ 2 ] != CL_SUBMITTED && status[ 2 ] != CL_QUEUED)
|
||||
{
|
||||
log_error( "ERROR: Second event did not start running after reference event(s) completed! (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Wait for the test event, then return
|
||||
if (PRINT_OPS) log_info("\tWaiting for action 2 to test to finish...\n");
|
||||
error = clWaitForEvents( 1, &events[ 2 ] );
|
||||
test_error( error, "Unable to wait for test event" );
|
||||
|
||||
error |= clGetEventInfo( events[ 2 ], CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof( status[ 2 ] ), &status[ 2 ], NULL );
|
||||
test_error( error, "Unable to get event status" );
|
||||
|
||||
log_info("\t\tEvent status after waiting for test event: reference event 0: %s, reference event 1: %s, test event 2: %s.\n",
|
||||
IGetStatusString( status[ 0 ] ), (multiple ? IGetStatusString( status[ 1 ] ) : "N/A"), IGetStatusString( status[ 2 ] ));
|
||||
|
||||
// Sanity
|
||||
if( status[ 2 ] != CL_COMPLETE )
|
||||
{
|
||||
log_error( "ERROR: Test event didn't complete (status: 2: %s)\n", IGetStatusString( status[ 2 ] ) );
|
||||
clFinish( queue );
|
||||
return -1;
|
||||
}
|
||||
|
||||
clFinish(queue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_ACTION( name ) \
|
||||
{ \
|
||||
name##Action action; \
|
||||
log_info( "-- Testing " #name " (waiting on 1 event)...\n" ); \
|
||||
if( ( error = test_waitlist( deviceID, context, queue, &action, false ) ) != CL_SUCCESS ) \
|
||||
retVal++; \
|
||||
clFinish( queue ); \
|
||||
} \
|
||||
if( error == CL_SUCCESS ) /* Only run multiples test if single test passed */ \
|
||||
{ \
|
||||
name##Action action; \
|
||||
log_info( "-- Testing " #name " (waiting on 2 events)...\n" ); \
|
||||
if( ( error = test_waitlist( deviceID, context, queue, &action, true ) ) != CL_SUCCESS ) \
|
||||
retVal++; \
|
||||
clFinish( queue ); \
|
||||
}
|
||||
|
||||
int test_waitlists( cl_device_id deviceID, cl_context context, cl_command_queue oldQueue, int num_elements )
|
||||
{
|
||||
cl_int error;
|
||||
int retVal = 0;
|
||||
|
||||
if( !checkDeviceForQueueSupport( deviceID, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ) )
|
||||
{
|
||||
log_info( "WARNING: Device does not support out-of-order exec mode; skipping test.\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
clCommandQueueWrapper queue = clCreateCommandQueue( context, deviceID,
|
||||
(cl_command_queue_properties)CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &error );
|
||||
test_error(error, "Unable to create out-of-order queue");
|
||||
|
||||
log_info( "\n" );
|
||||
|
||||
TEST_ACTION( NDRangeKernel )
|
||||
|
||||
TEST_ACTION( ReadBuffer )
|
||||
TEST_ACTION( WriteBuffer )
|
||||
TEST_ACTION( MapBuffer )
|
||||
TEST_ACTION( UnmapBuffer )
|
||||
|
||||
if( checkForImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
{
|
||||
log_info( "\nNote: device does not support images. Skipping remainder of waitlist tests...\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage2D )
|
||||
TEST_ACTION( WriteImage2D )
|
||||
TEST_ACTION( CopyImage2Dto2D )
|
||||
TEST_ACTION( Copy2DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo2DImage )
|
||||
TEST_ACTION( MapImage )
|
||||
|
||||
if( checkFor3DImageSupport( deviceID ) == CL_IMAGE_FORMAT_NOT_SUPPORTED )
|
||||
log_info("Device does not support 3D images. Skipping remainder of waitlist tests...\n");
|
||||
else
|
||||
{
|
||||
TEST_ACTION( ReadImage3D )
|
||||
TEST_ACTION( WriteImage3D )
|
||||
TEST_ACTION( CopyImage2Dto3D )
|
||||
TEST_ACTION( CopyImage3Dto2D )
|
||||
TEST_ACTION( CopyImage3Dto3D )
|
||||
TEST_ACTION( Copy3DImageToBuffer )
|
||||
TEST_ACTION( CopyBufferTo3DImage )
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user