Compare commits

...

271 commits

Author SHA1 Message Date
paulfradgley
7420e22e1e
Pass 'flag' variable through to clGetImageRequirementsInfoEXT (attempt 2)
Some checks failed
Presubmit / Build ubuntu-20.04 gl (push) Failing after 1s
Presubmit / Build ubuntu-20.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-20.04 arm (push) Failing after 1s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
Presubmit / Build windows-latest (push) Has been cancelled
Rebase of my previous clGetImageRequirementsInfoEXT flag=0 fix PR: PR1632

Pass 'flag' variable through to clGetImageRequirementsInfoEXT:

Almost all of the image_from_buffer cl_ext_image_requirements_info tests pass '0' as the 'flags' to clGetImageRequirementsInfoEXT.
Passing '0' as the flags is valid according to the spec, but since the tests are calling clGetImageRequirementsInfoEXT in a loop over a list of flags it doesn't seem intended that all the tests pass '0'.

Fixed CL_MEM_KERNEL_READ_AND_WRITE flag override:

The mem_flags override for CL_MEM_KERNEL_READ_AND_WRITE was incorrectly affecting subsequent iterations of the image_format loop.
Fixed by using a separate variable inside the loop.
2023-04-11 16:49:13 +01:00
Sven van Haastregt
9772516c3f
cmake: Enable -Wall for non-release builds (#1686)
Enable a larger set of compiler warnings globally for gcc/clang-like
compilers.  This should help catch issues early and result in better
code quality.  These warnings are primarily aimed at OpenCL-CTS
developers, so only enable them for non-release builds.

Ensure `-Wall` and `-Werror` are set before any `-Wno-...` options, as
the `-Wall`/`-Werror` flags undo `-Wno-...` for some compilers.

The code base does not compile cleanly with `-Wall` yet, so disable
some warnings.  Do this globally for now, to keep this patch small and
localized.

Silence `-Wunknown-pragmas` (instead of only making them non-fatal),
to avoid verbose warning logs.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-04-05 09:39:38 +01:00
Marcin Hajder
f0f887d07f
printf test cases for cl_khr_command_buffer extenstion (#1592)
* Added printf test case for cl_khr_command_buffer extenstion according to point 1.6 from:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Corrections related to macos and windows build

* Added missing header

* Added corrections related to code review of draft PR:

https://github.com/KhronosGroup/OpenCL-CTS/pull/1592

refers to issue #1369, p.1.6:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* minor fix for previous commit

* printf capability condition moved to ::Skip method (#1369, p.1.6):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Applied minor corrections related to code review (#1369, p.1.6):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added correction to replace string literals with sequence of characters printf arguments (issue #1369, printf)

* Added clang formatting.

* Added header related to android build (issue #1369, printf)

* Fixed memory leak

* Fixed memory leak in test_printf

* Added cosmetic fix for last commit
2023-04-04 08:12:05 +01:00
Sven van Haastregt
605228ae7f
[NFC] api: Fix sign-compare warnings (#1692)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-04-03 16:29:51 +01:00
Sven van Haastregt
a70fa56003
Fix some Wunused-but-set warnings (#1666)
To the best of my understanding, these occurrences of the
`-Wunused-but-set` warnings do not reveal any underlying issues, so we
can safely remove these variables.  There are more occurrences of this
warning in other places (not touched by this commit) that require
further analysis.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-30 09:34:00 +01:00
Sven van Haastregt
8e74722a0a
cmake: Fix -Wno- handling in add_cxx_flag_if_supported (#1656)
The `-Wno-...` compiler flags only result in a diagnostic if another
diagnostic is emitted.  When passing such flags to
`add_cxx_flag_if_supported` (and `check_cxx_compiler_flag`), the test
would always succeed.  For such cases, test the `-W...` flag instead
of the `-Wno-...` flag.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-29 11:10:27 +01:00
Ahmed
9afb918bf5
Disable vendor extension formats from image_from_buffer_fill_positive as the verification step is incorrect and can cause seg fault, e.g. for YUV images (#1657) 2023-03-28 09:16:15 -07:00
Ahmed
14f421e54b
Fix slice pitch for 1D array images on image_from_buffer_read_positive kernel_read_write images subtest (#1654) 2023-03-28 09:15:33 -07:00
Sreelakshmi Haridas Maruthur
868de6c15e
test_harness: Update test status upon api failure (#1615)
Co-authored-by: Vasu Penugonda <vpenugon@qti.qualcomm.com>
2023-03-28 09:14:47 -07:00
Marcin Hajder
20ab003053
Added cl_half support for test_printf (#1622)
* Added support to test half floats with printf calls (issue #142, printf)

* Added corrections related to rounding and casting halfs (issue #142, printf)

* Reusing similar function (issue #142, printf)

* Corrected path without cl_khr_fp16 support (issue #142, printf)

* Cosmetic fix for order of vector tests (issue #142, printf)

* Added correction related to vendor test review (issue #142, printf)
2023-03-28 08:57:03 -07:00
Marcin Hajder
f537c40abc
clGetCommandBufferInfoKHR test cases for cl_khr_command_buffer extension (#1611)
* Added initial commit for issue #1369, p.1.4

* Added support for clGetCommandBufferInfoKHR test cases (issue #1369, p.1.3)

* Added correction for CL_COMMAND_BUFFER_QUEUES_KHR query test (issue #1369, p.1.4)

* Added corrections related to changed orders of operations Skip/SetUp and code review (issue #1369, clGetCommandBufferInfoKHR)

* Added cosmetic correction related to printout messages (issue #1369, clGetCommandBufferInfoKHR)

* Corrected info_prop_array test to accept scenario without simultaneous use (issue #1369, p.1.4)

* Added protection test agains POCL unexpected values (issue #1369, p.1.4)

* Added corrections related to Ben's code review
2023-03-28 08:41:41 -07:00
Sven van Haastregt
8352966818
[NFC] Remove unused imagePtr variable (#1682)
This variable is shadowed by another variable further down.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-27 12:03:07 +01:00
Sven van Haastregt
c3d36bf9fb
[CI] Upgrade to actions/checkout@v3 (#1677)
Node.js 12 actions are deprecated, so update to v3 which uses Node 16.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-22 11:21:23 +00:00
Paweł Jastrzębski
3478f3d304
Add mutable dispatch tests. (#1651)
* Add mutable dispatch tests.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Mutable dispatch buffer tests redesigned to inherit from command buffer tests.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Add remaining tests for clGetMutableCommandInfoKHR.

Added tests for missing queries:
* CL_MUTABLE_DISPATCH_PROPERTIES_ARRAY_KHR
* CL_MUTABLE_DISPATCH_KERNEL_KHR
* CL_MUTABLE_DISPATCH_DIMENSIONS_KHR

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Minor code cleanup.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Introduce review changes.

Introduce changes requested in review:
- Remove bitwise chceck for CL_DEVICE_MUTABLE_DISPATCH_CAPABILITIES_KHR
- Add error check for clFinalizeCommandBufferKHR
- Add global_work_size to clCommandNDRangeKernelKHR for CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR
- Move BasicMutableCommandBufferTest to a separate header file
- Change name of file command_buffer_test_mutable_dispatch.cpp to mutable_command_info.cpp

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Set global_work_size on every use of clCommandNDRangeKernelKHR.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Apply changes for review.

- Add error check for init_extension_functions()
- Check mutable_capabilities for non-zero
- Replace clKernelWrapper with cl_kernel for CL_MUTABLE_DISPATCH_KERNEL_KHR test
- Replace clCommandBufferWrapper with cl_command_buffer_khr for CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR test
- Remove unneded test_command_buffer declarations
- Check type for CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR
- Remove retain() from operator= in clCommandBufferWrapper

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Apply changes for review.

Apply changes for review:
- Fix header guards
- Add copyright header
- Change checks for test_kernel, test_queue

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-03-21 09:12:34 -07:00
Paweł Jastrzębski
63b0f441f1
Add external semaphore tests. (#1645)
* Add external semaphore tests.

Added basic test to check the functionality of cl_ext_external_semaphore_test extension.
Tests rely on Vulkan API as the producer of the external semaphore functionality. The
Vulkan wrapper has been copied from the Vulkan CTS tests and minor changes have been
introduced. A separate copy of the Vulkan wrapper is for breaking any dependencies
between different CTS modules and thus make the build system simpler.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Fix clang-format

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Move vulkan wrapper to a separate library.

Vulkan wrapper is extracted as a separate module and can be used in different
CTS tests as a shared library.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Add cl_ext_external_samaphore tests based on cl_khr_semaphore tests.

Added cl_khr_semaphore adjusted to creating semaphores in Vulkan context
and importing them through export semaphore functionality in OpenCL
(cl_ext_external_samaphore).

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Cleanup.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Fix build issues.

* Add missing directories for build cl_ext_external_semaphore.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Set Vulkan lib directory.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Change extension directory name.

Changed extensions directory name from cl_ext_external_semaphore to cl_khr_external_semaphore.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Remove unneeded compile options.

Removed VK_USE_PLATFORM_WIN32_KHR option from cl_khr_external_semaphore
compilation arguments.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-03-21 09:06:15 -07:00
Sven van Haastregt
b7f2dd58e9
math_brute_force: Drop BuildKernelInfo2 (#1634)
Replace occurrences of `BuildKernelInfo2` with `BuildKernelInfo`.
This aligns the kernel creation code of the non-threaded tests to
the kernel creation code of the threaded tests.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-20 09:44:25 +00:00
Kévin Petit
9755c7ac58
[NFC] Only assign gIsEmbedded in the test harness (#1672)
Signed-off-by: Kévin Petit <kpet@free.fr>
2023-03-16 12:15:51 +00:00
Kévin Petit
1f94b5748b
[NFC] Remove duplicate symbol declarations (#1671)
* [NFC] Remove duplicate symbol declarations

Those are provided by testHarness.h.

Signed-off-by: Kévin Petit <kpet@free.fr>

* add missing include

---------

Signed-off-by: Kévin Petit <kpet@free.fr>
2023-03-16 12:15:37 +00:00
Sven van Haastregt
9e0369b307
[NFC] Remove unused printMe variable (#1674)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-16 06:23:06 +00:00
Sven van Haastregt
9798a96a9f
[NFC] Fix some sign-compare warnings (#1670)
In `os_helpers.cpp`, the preceding `if` already handles negative
values, so cast to unsigned.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-12 11:06:55 +00:00
paulfradgley
5297ecd673
Add compiler test external memory/semaphore extensions (#1662)
The OpenCL Headers have cl_khr_external_memory_dx, cl_khr_external_memory_dma_buf and cl_khr_external_semaphore_dx_fence as extension strings, but CTS Compiler fails if an implementation says that it supports them.
2023-03-07 09:54:15 -08:00
Paweł Jastrzębski
e882a3dc5e
Move semaphore tests from api to extensions (#1646)
* Move semaphore tests from api to extensions

Moved cl_khr_semaphore tests from core api tests to a separate
extension test as suggested in
https://github.com/KhronosGroup/OpenCL-CTS/issues/1588 .

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Fix clang-format

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Remove unneeded comment.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-03-07 09:00:16 -08:00
Marcin Hajder
0b44338eda
clSetKernelArg test cases for cl_khr_command_buffer extenstion (#1593)
* Initial commit for clSetKernelArg test case (issue #1369, p.1.7):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added simultaneous version of clSetKernelArg test, (#1369, p.1.7):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added/corrected comments (#1369, p.1.7)

* Corrected logic of conditions of command-buffer simultaneous use (#1369, p.1.7):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added missing comment for consistency with other command-buffer tests

* Cleanup related to code review (#1369, p.1.7):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added clang format correction

* Removed redundant code (issue #1369 clSetKernelArg)
2023-03-06 10:30:27 +00:00
Sven van Haastregt
712eb4f988
gl: Fix array size expression (#1610)
`sizes` is a pointer argument, so the expression does not compute the
presumably intended number of elements in `sizes`.

Fixes a `-Wsizeof-pointer-div` warning.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-03 13:29:29 +00:00
Marcin Hajder
33285facbe
Command buffer event sync (#1606)
* Added initial commit for event sync test cases (issue #1369, p.3.3)

* Added test cases for return event scenarios with and without out-of-order, work in progress (#1369, p.3.3)

* Added support for return event test cases for both regular and out-of-order command queue (#1369, p.3.3)

* Added user event test cases, cosmetic corrections (#1369, p.3.3)

* Added correction for windows build (#1369, p.3.3)

* Corrected proper testing of test fail/skip conditions (#1369, p.3.3)

* Added corrections related to PR review (#1369, p.3.3)

* Added correction related to change of order Skip/SetUp (issue #1369, event sync)

* Added clang format correction for previous commit

* Reordered initialization of attributes.
2023-03-03 08:20:46 +00:00
Sven van Haastregt
dc8ee495bd
[NFC] Fix -Wmissing-braces warnings (#1643)
The `cl_*` types need two levels of braces for initialization: the
outer braces for the union and the inner braces for the array.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-03-02 09:28:51 +00:00
victzhan
75db137822
Change order of print statement (#1631)
* Change order of print statement

* Made change for test_imagearraycopy3d.cpp as well

* Update test_imagearraycopy.cpp
2023-03-02 09:26:49 +00:00
Marcin Hajder
531e5e82f9
Out-of-order command-queue test cases for cl_khr_command_buffer (#1596)
* Initial commit for out-of-order test cases (#1369, p.2):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added support for simultaneous test of out-of-order command buffers and queues (#1369, p.2.1):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Cosmetic fixes (#1369, p.2):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Corrected two bugs related to simultaneous test (#1369, p.2.1):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added additional event to synchronize symultaneous passes, cosmetic fixes (#1369, p.2.1):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Cosmetic fix due to consistency concerns (#1369, p.2):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Fix for prev commit

* Added corrections related to changed order of Skip/SetUp methods (issue #1369, 2.0 out-of-order)

* Reverted formating of unrelated header

* Reverted formating of unrelated header, correction

* Reordered initialization of attributes.
2023-03-02 09:16:32 +00:00
Ben Ashbaugh
e71a7bce68
Revert "Image streams optimization (#1616)" (#1638)
This reverts commit b73c3149ad.
2023-02-28 09:06:34 -08:00
Nikhil Joshi
df3c4fae95
Enable test_vulkan by default in presubmit (#1655)
test_vulkan is disabled by default as part of
PR #1530.
Given the ongoing development to test_vulkan,
it is important to have this enabled in CI builds
to avoid breaking test builds.
Enable the test build as part of presubmit script.
2023-02-28 08:51:22 -08:00
Sven van Haastregt
2c9526f9a5
[NFC] Fix multi-line comment warnings (#1641)
Disabling of frem and fmod by b81b49e1 ("spirv: disable frem and fmod
tests for now (#1614)", 2023-02-07) introduced some new warnings about
multi-line `//` comments due to the trailing backslashes.  Fix these.

Also fix a typo.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-02-24 15:44:59 +00:00
Marcin Hajder
296a7a574d
Command buffer profiling (#1598)
* Added test cases for profiling command-buffers according to issue description #1369, p.3.2:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added cosmetic fixes (#1369, p.3.2)

* Corrected the path of initialization profiling event for simultaneous test (#1369, p.3.2):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* clang format fix

* Added correction related to macos build error (#1369, p.3.2)

* Applied corrections related to code review (#1369, p.3.2)

* Corrected query of queue properies (issue #1369, command buffer profiling)

* Reverted formating of unrelated header

* Added code review corrections for type consistency and fail condition (issue #1369, p.3.2)

* Reordered initialization of attributes.

* Reverted correct order of initialization.
2023-02-21 09:05:17 +00:00
Paweł Jastrzębski
fa2c1d2417
Add test for clGetEventInfo info queries. (#1647)
* Add test for clGetEventInfo info queries.

Test clGetEventInfo() info queries from event returned by command-buffer
enqueue for the single command-queue to command-buffer case:
* CL_EVENT_COMMAND_TYPE is CL_COMMAND_COMMAND_BUFFER_KHR
* CL_EVENT_COMMAND_QUEUE
* CL_EVENT_CONTEXT
* CL_EVENT_COMMAND_EXECUTION_STATUS
* CL_EVENT_REFERENCE_COUNT

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

* Fix return TEST_FAIL instead of -1.

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-02-20 16:19:11 +00:00
Sven van Haastregt
61ec521b1c
[NFC] Fix BasicCommandBufferTest initialization order (#1628)
The `command_buffer` member is initialized with `this`, and should
thus be initialized after all other members have been initialized, to
avoid any potential uninitialized data accesses by `command_buffer`'s
constructor.  This is currently not a problem, but would become a
problem when `command_buffer`'s constructor accesses the object
through its parameter.

Fixes a -Wreorder warning.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-02-20 11:39:18 +00:00
Paweł Jastrzębski
560d6eafbd
Added tests for 1.1 individual command entry-points. (#1594)
* Added tests for 1.1 individual command entry-points.

* Adding fixes pointed out in review: checks for CL_DEVICE_IMAGE_SUPPORT, remove redundant buffers, synchronisation issues, fixed clang-format, other minor issues.

* Fix compilation issues for Windows and macOS, fix clang-format.

* Fix compilation issue for Windows.

* Removed redundant blocking and event operations.

* Style fixes for test skip conditions.

* Fix clang format.

* Fixed function names, file names, comments and barrier test.

* Restored Individual command entry-points tests after merge with main.

* Fix clang format.

* Superficial fixes for review.
* Fix Skip() condition for barrier test
* Fix typos
* Fix new line

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-02-20 08:36:34 +00:00
Karol Herbst
b81b49e10e
spirv: disable frem and fmod tests for now (#1614)
The OpenCL SPIR-V Environment Specification does not require the SPIR-V
opcodes `OpFMod` and `OpFRem` to match any OpenCL C semantics, so
implementations implementing those two instructions according to Vulkan
and/or OpenGL semantics will fail those tests without actually violating
any OpenCL specification.

We should keep those tests disabled until we figure out what the actual
precision requierement should be and update the test accordingly.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
2023-02-07 09:08:29 -08:00
Sven van Haastregt
1e5b5c96e2
math_brute_force: Remove unnecessary gotos (#1605)
Simplify code by returning directly instead of using goto statements.

Although intended as an NFC commit, this changes the behaviour around
clFlush calls.  Before this commit, failure of the third clFlush call
would print "clFlush 3 failed" and return the clFlush error code.
This behaviour is inconsistent with the other clFlush calls in
math_brute_force, which are not fatal.  The lack of a `goto exit`
makes me suspect that this 3rd clFlush call was intended to be
non-fatal too.  As such, this commit makes all clFlush calls non-fatal
by returning `CL_SUCCESS` even when the third clFlush call fails.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-02-07 09:01:07 -08:00
Paweł Jastrzębski
11782f7650
Fixed EnqueueAcquire and EnqueueRelease calls to be compliant with the spec. (#1629) 2023-02-07 08:58:48 -08:00
Chip Davis
b73c3149ad
Image streams optimization (#1616)
* Don't recalculate image parameters repeatedly in `test_read_image()`

We've already done this in the loop. There's no need to recalculate
those parameters over and over again in `sample_image_pixel*()` and
`read_image_pixel*()`. This should save some work during the image
streams test.

This only affects the 3D tests for now, but my time profiles indicate
this is where we spend the most time anyway.

* Vectorize read_image_pixel_float() and sample_image_pixel_float() for SSE/AVX

This shortens the image streams test time from 45 minutes without it to
37 minutes. Unfortunately, most of the time is now spent waiting for
memory, particularly in the 3D tests, because the 3D image doesn't
neatly fit in the cache, especially in the linear sampling case, where
pixels from two 2D slices must be sampled. Software prefetching won't
help; it only helps when execution time is dominated by operations, but
this is dominated by memory access. Randomized offsets are likely a
factor, because they throw off the hardware prefetcher.

One possible further optimization is, in the linear sampling case, to
load two sampled pixels at once. This is easy to do using AVX, which
extends SSE with 256-bit vectors.

Obviously, this only applies to x86 CPUs with SSE2. The greatest
performance gains, however, are seen with SSE4.1. Most modern x86 CPus
have SSE4. Work is needed to support other CPUs' vector units--ARM
Advanced SIMD/NEON is probably the most important one. Another
possibility is arranging the code so that the compiler's
autovectorization will kick in and do what I did here manually.
2023-02-07 08:46:15 -08:00
Sven van Haastregt
f46cca0f8f
[NFC] clang-format gl (#1612)
Add some clang-format off/on comments to keep kernel code readable.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-02-06 15:09:04 +00:00
Sven van Haastregt
2318cedb21
select: Use MTdataHolder (#1609)
Simplify code by avoiding manual resource management.

This fixes use of an uninitialized `d` in the `free_mtdata` call, in
the case a `goto exit` was executed before initializing `d`.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-01-31 09:50:21 -08:00
Finlay
691a45d605
c11 atomic fence: relaxed requirements for an auxiliary atomic_store (#1603) 2023-01-31 09:47:47 -08:00
Stuart Brady
68fcb5904f
Avoid use of rand in test_rw_image_access_qualifier (#1322)
There is no particular reason to limit the domain of unsigned 32-bit
integers in the input, so use genrand_int32 directly.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2023-01-31 09:42:45 -08:00
Sven van Haastregt
2cc8e2e593
Fix -Woverloaded-virtual warnings (#1599)
Align `verify_data` with `checker_image_mem_host_read_only.hpp`, that
is, take an explicit pointer to compare against.

Add a missing (but unused) `float` parameter to
`KernelArgSampler::compare`.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-01-27 16:34:22 +00:00
Sven van Haastregt
9eec8f3352
Suppress -Wdeprecated-declarations for macOS (#1627)
Xcode 14 deprecated functions such as `sprintf` which is used in many
places.  As an immediate fix for the pre-commit checks, disable
deprecated function warnings when building for macOS.

Contributes to https://github.com/KhronosGroup/OpenCL-CTS/issues/1626

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-01-27 13:34:50 +00:00
Marcin Hajder
afdd8b0058
Command buffer queue substitution (#1584)
* Added queue substitution CTS test based on issue: https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added cosmetic correction to properties_queue_substitution test, work in progress:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added support for simultaneous queue substitution test (1.3.3), more cosmetic corrections added:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added initial rearrangement of source files due to more test cases to be implemented.

* Corrected test with queue properties out-of-order:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added alternative temporary path for simultenaous pass (USE_COMMAND_BUF_KENEL_ARG):

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* applied git clang-format "origin/main"

* Added corrections for out-of-order property scenario, couple cosmetic fixes:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Replaced cl_command_queue with clCommandQueueWrapper for additional command queue with properties:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Removed unnecessary flag, additional cleanup:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added narrowing correction due to windows build fail:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Test simiplified in order to use only substitute queue on both simultaneous buffers:

https://github.com/KhronosGroup/OpenCL-CTS/issues/1369

* Added limitation to use only CL_QUEUE_PROFILING_ENABLE property, replaced cl_command_queue with related wrapper (#1369, p.1.4)

* Corrections related to order of operations due to code review (issue #1369, p.1.3)

* Cosmetic fix for prev commit

* Cosmetic fix for prev commit #2
2023-01-24 09:44:16 -08:00
Steven Winston
ea49084976
Conversions (#1555)
* grab latest from upstream OpenCL

* Removed events for host to device data transfers

* grab latest from upstream OpenCL

* 1.) revert changes to CMakeLists.txt and run_batch script in hopes this will solve the CI issues for the PR.
2.) resolve the merge conflict in test_conversions.cpp

* 1.) resolve 2 additional merge conflicts

* 1.) resolve 1 additional merge conflicts

* locally this fails clang-format but CI version seems to require it.

* fix the warning.

* Remove now-unused event

Also, cut down a comment that is no longer accurate.

Co-authored-by: Joshua Luceno <joshualuceno@gmail.com>
Co-authored-by: Chip Davis <chip@holochip.com>
Co-authored-by: Chip Davis <cdavis5x@gmail.com>
2023-01-24 08:53:18 -08:00
Steven Winston
4759159a50
Enqueue fill buffer (#1561)
* grab latest from upstream OpenCL

* Use clEnqueueFillBuffer rather than memset4 in all test files

* Cleanup leftover code from memset_pattern4

* Remove unnecessary map, unmap, writeBuffer from math_brute_force tests

* Remove extraneous build system change

* Appease clang-format

* Add option to perform buffer fills on the host

Co-authored-by: Taeten Prettyman <taeten.j@gmail.com>
Co-authored-by: taetenp <taet@holochip.com>
Co-authored-by: Chip Davis <chip@holochip.com>
2023-01-24 08:51:00 -08:00
Steven Winston
77e4fe5588
Half (#1554)
* Added on-device reset for half

* run clang-format.

* test_half - Reset buffer with ushort rather than half type

* Half - update type in secondary reset kernel src

* Remove useless memset() calls.

* Add an option to still perform buffer resets on the host

* Check for program generation failure before attempting to create the kernel

* Don't exceed the range of a ushort when storing

* Appease clang-format

Co-authored-by: Joshua Luceno <joshualuceno@gmail.com>
Co-authored-by: taetenp <taet@holochip.com>
Co-authored-by: Chip Davis <chip@holochip.com>
2023-01-24 08:48:53 -08:00
Sven van Haastregt
487dbd292e
relationals: Use stringstream in print_hex_mem_dump (#1597)
print_hex_mem_dump was calling `sprintf` with source and destination
buffers overlapping, which is explicitly forbidden.  Rewrite the
function to use C++ stringstreams instead.

This commit only affects the error path and does not change the
printed output.  Error logs before and after this commit should not
differ.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-01-20 15:11:31 +00:00
Kévin Petit
1eeb10296f
Get rid of threadTesting.h (#1604)
It only contains a pointer type definition for test functions that
really ought to be provided by testHarness.h.

Signed-off-by: Kévin Petit <kpet@free.fr>

Signed-off-by: Kévin Petit <kpet@free.fr>
2023-01-14 15:18:27 +00:00
Sven van Haastregt
896f43615d
basic: Return error on unhandled image format (#1613)
Fail when an unhandled image format is encountered instead of
continuing validation with uninitialized variables.

Fixes a `-Wsometimes-uninitialized` warning for e.g. the `tolerance`
variable.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-01-11 10:25:30 +00:00
Sven van Haastregt
4278d544dc
[NFC] clang-format mem_host_flags (#1607)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-01-09 16:07:09 +00:00
Sven van Haastregt
8066e69b11
[NFC] clang-format mem_host_flags/checker_image_mem_host_write_only.hpp (#1600)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-20 13:46:47 +00:00
Sven van Haastregt
59a1198e5f
[NFC] commonfns: Remove unused values arrays (#1595)
The arrays were assigned to, but the values were never used again.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-14 07:34:30 -08:00
Sven van Haastregt
884c736525
math_brute_force: Use clKernelWrapper in single-threaded tests (#1590)
Simplify code by relying on RAII to free resources.

This commit only affects tests that use `BuildKernelInfo2`, which are
the single-threaded tests.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-13 09:53:56 -08:00
Sven van Haastregt
fb949f9256
events: Remove unused BufferAction::Setup parameter (#1586)
`BufferAction::Setup` has an additional parameter `allocate` which
hides the virtual function `Action::Setup`.  The additional parameter
was unused anyway, so remove it.

Fixes a -Woverloaded-virtual warning.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-13 09:53:11 -08:00
Sven van Haastregt
f48dd72da8
Fix -Wreorder warnings (#1583)
Initialize class members in the order they are declared.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-13 09:49:38 -08:00
Stuart Brady
a25b9c4948
Partial clean up of test_compiler_defines_for_extensions (#1577)
Replace repetitions of extensions_supported[num_of_supported_extensions]
with a single pointer variable.

Replace character-by-character comparisons with a new string_has_prefix
function.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-12-13 09:48:35 -08:00
Sven van Haastregt
3cadff7115
Fix unused-function warnings and enable -Wunused-function (#1576)
Move functions in .h files to .cpp files where appropriate; align
prototypes and definitions; and remove functions that are not used.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-13 09:47:48 -08:00
Ben Ashbaugh
58eb3d776d
add tests for cl_khr_extended_bit_ops (#1232)
* very basic test infrastructure

* move test to integer_ops

* added bitfield_reverse test

* added test for bitfield insert

* add a separate file for bitfield_extract

* cleaned up implementation and all tests are passing

* rename helper file so it can be used by other tests

* remove temporary hacks

* fix formatting

* address code review comments

* remove duplicated code after rebase

* fix formatting

a few naming changes for consistency

more changes for consistency

* fix copyright dates

* remove unused variable
2022-12-13 09:46:42 -08:00
Kévin Petit
ed27a90775
samplerlessReads: split out 1D Buffer testing into a separate test (#1570)
So we get finer grain reporting and better parallelisation in the future.

Signed-off-by: Kévin Petit <kpet@free.fr>

Signed-off-by: Kévin Petit <kpet@free.fr>
2022-12-10 11:01:35 +00:00
Sven van Haastregt
73c6955068
[NFC] relationals: Tidy up get_order_string (#1591)
Remove a misleading comment at the end.  Improve comments in general,
and use `true`/`false` for `bool`s.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-08 12:08:56 +00:00
Sven van Haastregt
1c2c4581bd
mem_host_flags: Fix WRITE_ONLY typo (#1585)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-12-01 09:30:54 -08:00
Sven van Haastregt
ab338569aa
[NFC] clang-format mem_host_flags/mem_host_image.cpp (#1589)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-30 07:13:45 -08:00
Sven van Haastregt
0d24c6f69d
relationals: Fix vector component accessor selection (#1567)
It seems the intent was to use `.xyzw` vector component accessors in
the kernel whenever `vecSize` is 2, 3, or 4.  The condition was wrong
(i.e., always true for any value of `vecSize`), causing it to always
create a kernel with numeric (`.s0123...`) vector component accessors.

The restriction on the use of `.xyzw` for 8 and 16-component vectors
has been lifted a while ago (see
https://github.com/KhronosGroup/OpenCL-Docs/issues/549) so we do not
need this check at all.

Also, fix the `vecSize` argument of two calls of `get_order_string`
when getting the order string for the "in" kernel argument.  Pass
`inVecSize` in these cases, not `outVecSize`.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-27 13:26:23 -08:00
Sven van Haastregt
6ecf824122
math_brute_force: Use clKernelWrapper in threaded tests (#1562)
Simplify code by relying on RAII to free resources.  Reduce code
duplication.

This commit only affects tests that use `BuildKernelInfo`, which are
the multi-threaded tests.  Another patch will deal with the
single-threaded tests, i.e., those using `BuildKernelInfo2`.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-27 13:25:32 -08:00
Sven van Haastregt
e9d2abf705
spir: Fix -Wcatch-value warnings (#1565)
`std::exception` and `std::runtime_error` are polymorphic types and as
such they shouldn't be passed by value.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-24 11:43:51 +00:00
Jack Frankland
c6bb15c289
Remove invalid assumptions from sub-group tests (#1504)
* Remove invalid assumption from sub-group tests

The sub-group dispatch tests were making the invalid assumption that
querying the local size (via `CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT`)
for a sub-group count obtained from a
`CL_KERNEL_SUB_GROUP_COUNT_FOR_ND_RANGE` with local size `{x, y, z}`
will result in the same local size i.e. that
`CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT` is the inverse of
`CL_KERNEL_SUB_GROUP_COUNT_FOR_ND_RANGE`. To take a trivial example
consider the case that there is only ever one sub-group per work
group(i.e. sub-group == work-group). Then regardless of the local size
passed to `CL_KERNEL_SUB_GROUP_COUNT_FOR_ND_RANGE` the sub-group count
will always be `1`, and `CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT` can
return any valid local size since all local sizes result in `1`
sub-group.

* Format surrounding changes
2022-11-23 13:19:35 -08:00
Callum Fare
9137cb66ed
Test that cloned kernels can't be enqueued before all args are set (#1563) 2022-11-23 14:09:42 +00:00
Kenneth Benzie
def23dd6e6
Fix generic address space OpenCL 2.0 assumption (#1575)
Conformance tests should not assume support for OpenCL 2.0, or specific
features. This patch removes uses of
`__opencl_c_program_scope_global_variables` for devices which do not
support it in the generic address space conformance tests. Additionally,
the `clCompileProgram` options have been updated to select between
`CL2.0` and `CL3.0` depending on which the device under test supports.

Co-authored-by: Amy Worthington <amy@codeplay.com>
2022-11-23 14:08:30 +00:00
Sven van Haastregt
640f6e66c7
[NFC] workgroups: Remove unused array (#1572)
`value_range` was only used in an `NELEMS` expression; its values were
never read.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-23 14:04:31 +00:00
Marco Cattani
18dbf2f1c1
Added initial set of tests for the cl_khr_semaphore extension (#1428)
Some checks failed
Presubmit / Build ubuntu-20.04 gl (push) Failing after 2s
Presubmit / Build ubuntu-20.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-20.04 arm (push) Failing after 2s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
Presubmit / Build windows-latest (push) Has been cancelled
* Added initial set of tests for the cl_khr_semaphore extension

* Fixes to address first round of reviews for cl_khr_semaphore tests
2022-11-15 09:18:43 -08:00
Sven van Haastregt
fc4260bdae
subgroups: Fix Wformat warnings (#1549)
The main source of warnings was the use of `%d` for printing a
templated type `T`, where `T` could be any cl_ scalar or vector type.

Introduce `print_expected_obtained`.  It takes const references to
handle alignment of the cl_ types.

Define `operator<<` for all types used by the subgroup tests.  Ideally
those would be template functions enabled by TypeManager data, but
that requires some more work on the TypeManager (which we'd ideally do
after more warnings have been enabled).  So for now, define the
`operator<<` instances using preprocessor defines.

Also fix a few instances where the wrong format specifier was used for
`size_t` types.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-15 09:12:31 -08:00
John Kesapides
2110e45cce
Deduplicate write_image (#1536)
* Deduplicate write_image

Merge writeimage,writeimage_int16,writeimage_fp32
as they share a lot of common code.

Signed-off-by: John Kesapides <john.kesapides@arm.com>

* Test for CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE.

Signed-off-by: John Kesapides <john.kesapides@arm.com>

* Rename test_flags to img_flags

Signed-off-by: John Kesapides <john.kesapides@arm.com>

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2022-11-15 09:11:37 -08:00
Sven van Haastregt
524fcab7f3
[NFC] spir: Remove unused class member (#1568)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-10 14:23:47 +00:00
Kenneth Benzie
191fd0f9e5
Fix thread leaks in the thread pool (#1553)
While testing an OpenCL driver with ThreadSanitizer enabled the
OpenCL-CTS suffers from thread leaks in conversions and bruteforce on
posix systems. This is because `pthread_join` is never called in
`ThreadPool_Exit` for the `pthread_t`s created by the thread pool.
Instead, the threads are only informed to stop waiting on the condition
variable which unblocks the worker thread but does not clean up after
itself.

```
ThreadPool: thread 1 exiting.
ThreadPool: thread 5 exiting.
ThreadPool: thread 4 exiting.
ThreadPool: thread 2 exiting.
ThreadPool: thread 7 exiting.
ThreadPool: thread 0 exiting.
ThreadPool: thread 3 exiting.
ThreadPool: thread 6 exiting.
Thread pool exited in a orderly fashion.
==================
WARNING: ThreadSanitizer: thread leak (pid=2292842)
  Thread T9 (tid=2292855, finished) created by main thread at:
    #0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x5ad75)
    #1 ThreadPool_Init() <null> (test_conversions+0x35b2c)
    #2 pthread_once ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:1449 (libtsan.so.0+0x4057c)
    #3 GetThreadCount() <null> (test_conversions+0x36262)
    #4 DoTest(_cl_device_id*, Type, Type, SaturationMode, RoundingMode, _MTdata*) [clone .isra.0] <null> (test_conversions+0x10555)
    #5 test_conversions(_cl_device_id*, _cl_context*, _cl_command_queue*, int) <null> (test_conversions+0x13226)
    #6 callSingleTestFunction(test_definition, _cl_device_id*, int, int, unsigned long) <null> (test_conversions+0x2e66d)
    #7 parseAndCallCommandLineTests(int, char const**, _cl_device_id*, int, test_definition*, int, unsigned long, int) <null> (test_conversions+0x2fb3a)
    #8 runTestHarnessWithCheck(int, char const**, int, test_definition*, int, unsigned long, test_status (*)(_cl_device_id*)) <null> (test_conversions+0x349d8)
    #9 main <null> (test_conversions+0xd725)

  And 7 more similar thread leaks.

SUMMARY: ThreadSanitizer: thread leak (OpenCL-CTS/buildbin/conversions/test_conversions+0x35b2c) in ThreadPool_Init()
```

This patch adds global state to keep track of the `pthread_t`s created
by `pthread_create` in `ThreadPool_Init`. The list of `pthread_t`s is
then used by `ThreadPool_Exit` to call `pthread_join` to cleanup the
`pthread_t`s correctly.

A near identical example, and additional explanation, can be found on
[stackoverflow](https://stackoverflow.com/questions/72435574/thread-leak-detected-when-using-condition-variable-instead-of-join-with-pthrea).

On the Windows path, a similar change is not necessary because
`_beginthread` is used which automatically cleans up after itself when
the worker thread function returns.
2022-11-08 09:32:45 -08:00
Stuart Brady
77049a3a0f
Add missing newlines in log messages for image tests (#1564)
Also use log_info instead of printf for skipped tests, for consistency.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-11-08 09:28:30 -08:00
John Kesapides
aad303074c
Fix image type on format check for test_readimage. (#1566)
Signed-off-by: John Kesapides <john.kesapides@arm.com>

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2022-11-08 11:09:10 -05:00
Stuart Brady
133834615e
Improve logging of unknown extensions (#1556)
Add missing newlines, and log all unknown extensions instead of logging
only the first unknown extension found.
2022-11-04 11:26:19 -07:00
Sven van Haastregt
f29ebf0d59
[NFC] image_streams: Remove unused label (#1560)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-04 08:54:05 -07:00
Sven van Haastregt
a61fa63054
[NFC] cmake: Remove redundant CMAKE_CXX_STANDARD (#1558)
`CMAKE_CXX_STANDARD` is already set in the top-level CMakeLists.txt
file, so there is no need to have it repeated for individual modules.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-04 08:53:42 -07:00
John Kesapides
9794aaef04
Deduplicate test_basic read_image (#1535)
Merge readimage,readimage_int16,read_image_fp32,
readimage3d,readimage3d_int16,read_image3d_fp32
as they share a lot of common code.

Signed-off-by: John Kesapides <john.kesapides@arm.com>

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2022-11-01 13:26:09 -07:00
John Kesapides
bb54c435dc
Deduplicate test_basic test_fpmath (#1534)
Merge fpmath_float,fpmath_float2,fpmath_float4
as they share a lot of common code.

Signed-off-by: John Kesapides <john.kesapides@arm.com>

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2022-11-01 13:10:14 -07:00
Sven van Haastregt
8bb69ef665
Fix -Wformat-extra-args warnings (#1533)
Fix a few instances where an incorrect number of arguments was
supplied when calling (v)log_error.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-11-01 13:09:48 -07:00
John Kesapides
fb1e8fcf9b
Deduplicate test_basic arrayimagecopy (#1532)
Merge test_arrayimagecopy3d and test_arrayimagecopy
into a single test, as they share a lot of common code.
2022-11-01 13:09:12 -07:00
Sven van Haastregt
63274f97b7
math_brute_force: Factor out GetUnaryKernel and GetBinaryKernel (#1525)
Use common functions to create the kernel source code for testing
1-argument and 2-argument math builtins.  This reduces code duplication.

Use appropriate patterns to initialise variables to their full bit
widths.  For example, `0xdead` was previously used to initialise 32-bit
integers, while now a larger number spanning all bytes is used.

Co-authored-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
Co-authored-by: Marco Antognini <marco.antognini@arm.com>
2022-11-01 13:08:36 -07:00
Grzegorz Wawiorko
44fe72c2b9
Fix vulkan test build issue on Intel compiler (#1464) 2022-11-01 13:05:37 -07:00
Kenneth Benzie
babed4c175
Make building the Vulkan interop tests optional (#1530)
Some checks failed
Presubmit / Build ubuntu-20.04 gl (push) Failing after 2s
Presubmit / Build ubuntu-20.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-20.04 arm (push) Failing after 1s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
Presubmit / Build windows-latest (push) Has been cancelled
Allow enabling/disabling building of the Vulkan interop tests via CMake
option without modifying the CMake. This matches the optionality of the
D3D10, D3D11, GL, and GLES interop tests.
2022-10-27 10:16:16 +01:00
John Kesapides
90a5183ec4
Use CTS type wrappers for test_enqueued_local_size (#1544)
Signed-off-by: John Kesapides <john.kesapides@arm.com>

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2022-10-14 09:55:10 +01:00
John Kesapides
5e116e7b0d
Use CTS type wrappers for test_sizeof. (#1547)
Signed-off-by: John Kesapides <john.kesapides@arm.com>

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2022-10-14 09:53:33 +01:00
Sven van Haastregt
f6a963a583
harness: Fix -Wformat warnings (#1527)
The main sources of warnings were:

 * Printing of a `size_t` which requires the `%zu` specifier.

 * Printing of `cl_long`/`cl_ulong` which is now done using the
   `PRI*64` macros to ensure portability across 32 and 64-bit builds.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-10-13 10:02:40 +01:00
Sven van Haastregt
4b39b59469
[NFC] clang-format basic/test_progvar.cpp (#1528)
Manually reformat the `prog_src` variable which contains kernel code
and disable clang-format on it.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-10-13 10:01:53 +01:00
Sven van Haastregt
35cab9c85b
pipes: Fix readwrite verification function for fp64 (#1522)
Use the appropriate function for verifying double precision values in
the `pipe_readwrite_double` test.

Change `verify_readwrite_double` to use `cl_long`, as `long long int`
could be wider than 64 bits which would cause out-of-bound reads.
This leaves no functional differences between
`verify_readwrite_double` and `verify_readwrite_long`.

Found by compiling with `-Wunused-function`, which flagged
`verify_readwrite_double` as unused.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-10-11 09:36:33 -07:00
Kévin Petit
9e0ce2ba80
Produce JSON results even when a suite's init function reports SKIP or FAIL (#1521)
Also tidy-up some surrounding code.

Signed-off-by: Kévin Petit <kpet@free.fr>

Signed-off-by: Kévin Petit <kpet@free.fr>
2022-10-11 09:35:36 -07:00
Grzegorz Wawiorko
f6e37b17d2
Fix image test image2d_from_buffer_positive (#1515) 2022-10-11 09:34:33 -07:00
niranjanjoshi121
d285ebe5be
Fix memory oob problem in test conversions (#1513)
* Fix memory oob problem in test conversions

Allocate memory for argc arguments
instead of argc - 1.

* Fix formatting issue.
2022-10-11 09:32:47 -07:00
Sven van Haastregt
d9a938b698
Factor out GetTernaryKernel (#1511)
Some checks failed
Presubmit / Build ubuntu-20.04 gl (push) Failing after 2s
Presubmit / Build ubuntu-20.04 aarch64 debug (push) Failing after 0s
Presubmit / Build ubuntu-20.04 arm (push) Failing after 2s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
Presubmit / Build windows-latest (push) Has been cancelled
Use a common function to create the kernel source code for testing
3-argument math builtins.  This reduces code duplication.  1-argument
and 2-argument math kernel construction will be factored out in future
work.

Change the kernels to use preprocessor defines for argument types and
undef values, to make the CTS code easier to read.

Co-authored-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
Co-authored-by: Marco Antognini <marco.antognini@arm.com>
2022-10-04 09:28:29 -07:00
Nikhil Joshi
07b055cd68
Cap CL_DEVICE_MAX_MEM_ALLOC_SIZE to SIZE_MAX (#1501)
* Fix enqueue_flags test to use correct barrier type.

Currently, enqueue_flags test uses CLK_LOCAL_MEM_FENCE.
Use CLK_GLOBAL_MEM_FENCE instead as all threads across work-groups
need to wait here.

* Add check for support for Read-Wrie images

Read-Write images have required OpenCL 2.x.
Read-Write image tests are already being skipped
for 1.x devices.
With OpenCL 3.0, read-write images being optional,
the tests should be run or skipped
depending on the implementation support.

Add a check to decide if Read-Write images are
supported or required to be supported depending
on OpenCL version and decide if the tests should
be run on skipped.

Fixes issue #894

* Fix formatting in case of Read-Write image checks.

Fix formatting in case of Read-write image checks.
Also, combine two ifs into one in case of
kerne_read_write tests

* Fix some more formatting for RW-image checks

Remove unnecessary spaces at various places.
Also, fix lengthy lines.

* Fix malloc-size calculation in test imagedim

unsigned char size is silently assumed to be 1
in imagedim test of test_basic.
Pass sizeof(type) in malloc size calculation.
Also, change loop variable from signed to unsigned.
Add checks for null pointer for malloced memory.

* Cap CL_DEVICE_MAX_MEM_ALLOC_SIZE to SIZE_MAX

Cap CL_DEVICE_MAX_MEM_ALLOC_SIZE to SIZE_MAX
when CL_DEVICE_GLOBAL_MEM_SIZE is capped with SIZE_MAX.
test_allocation caps the value of GLOBAL_MEM_SIZE to SIZE_MAX
if it exceeds the value of SIZE_MAX(value depends on platform bitness),
but doesn’t modify MAX_ALLOC_SIZE the same way.
Due to this MAX_ALLOC_SIZE becomes greater than GLOBAL_MEM_SIZE
and the test fails.

Modify MAX_MEM_ALLOC_SIZE as GLOBAL_MEM_SIZE when it exceeds SIZE_MAX

OpenCL-CTS #1022
2022-10-04 09:13:18 -07:00
Ben Ashbaugh
6659a1b6b8
remove implicit conversion to pointer to fix 32-bit compile (#1488)
* remove implicit conversion to pointer to fix 32-bit compile

* fix formatting
2022-10-04 09:02:25 -07:00
Nikhil Joshi
dbd33bc9cf
External sharing new updates (#1482)
* Fix enqueue_flags test to use correct barrier type.

Currently, enqueue_flags test uses CLK_LOCAL_MEM_FENCE.
Use CLK_GLOBAL_MEM_FENCE instead as all threads across work-groups
need to wait here.

* Add check for support for Read-Wrie images

Read-Write images have required OpenCL 2.x.
Read-Write image tests are already being skipped
for 1.x devices.
With OpenCL 3.0, read-write images being optional,
the tests should be run or skipped
depending on the implementation support.

Add a check to decide if Read-Write images are
supported or required to be supported depending
on OpenCL version and decide if the tests should
be run on skipped.

Fixes issue #894

* Fix formatting in case of Read-Write image checks.

Fix formatting in case of Read-write image checks.
Also, combine two ifs into one in case of
kerne_read_write tests

* Fix some more formatting for RW-image checks

Remove unnecessary spaces at various places.
Also, fix lengthy lines.

* Fix malloc-size calculation in test imagedim

unsigned char size is silently assumed to be 1
in imagedim test of test_basic.
Pass sizeof(type) in malloc size calculation.
Also, change loop variable from signed to unsigned.
Add checks for null pointer for malloced memory.

* Initial CTS for external sharing extensions

Initial set of tests for below extensions
with Vulkan as producer
1. cl_khr_external_memory
2. cl_khr_external_memory_win32
3. cl_khr_external_memory_opaque_fd
4. cl_khr_external_semaphore
5. cl_khr_external_semaphore_win32
6. cl_khr_external_semaphore_opaque_fd

* Updates to external sharing CTS

Updates to external sharing CTS
1. Fix some build issues to remove unnecessary, non-existent files
2. Add new tests for platform and device queries.
3. Some added checks for VK Support.

* Update CTS build script for Vulkan Headers

Update CTS build to clone Vulkan Headers
repo and pass it to CTS build
in preparation for external memory
and semaphore tests

* Fix Vulkan header path

Fix Vulkan header include path.

* Add Vulkan loader dependency

Vulkan loader is required to build
test_vulkan of OpenCL-CTS.
Clone and build Vulkan loader as prerequisite
to OpenCL-CTS.

* Fix Vulkan loader path in test_vulkan

Remove arch/os suffix in Vulkan loader path
to match vulkan loader repo build.

* Fix warnings around getHandle API.

Return type of getHandle is defined
differently based on win or linux builds.
Use appropriate guards when using API
at other places.
While at it remove duplicate definition
of ARRAY_SIZE.

* Use ARRAY_SIZE in harness.

Use already defined ARRAY_SIZE macro
from test_harness.

* Fix build issues for test_vulkan

Fix build issues for test_vulkan
1. Add cl_ext.h in common files
2. Replace cl_mem_properties_khr with cl_mem_properties
3. Replace cl_external_mem_handle_type_khr with
cl_external_memory_handle_type_khr
4. Type-cast malloc as required.

* Fix code formatting.

Fix code formatting to
get CTS CI builds clean.

* Fix formatting fixes part-2

Another set of formatting fixes.

* Fix code formatting part-3

Some more code formatting fixes.

* Fix code formatting issues part-4

More code formatting fixes.

* Formatting fixes part-5

Some more formatting fixes

* Fix formatting part-6

More formatting fixes continued.

* Code formatting fixes part-7

Code formatting fixes for image

* Code formatting fixes part-8

Fixes for platform and device query tests.

* Code formatting fixes part-9

More formatting fixes for vulkan_wrapper

* Code formatting fixes part-10

More fixes to wrapper header

* Code formatting fixes part-11

Formatting fixes for api_list

* Code formatting fixes part-12

Formatting fixes for api_list_map.

* Code formatting changes part-13

Code formatting changes for utility.

* Code formatting fixes part-15
Formatting fixes for wrapper.

* Misc Code formatting fixes

Some more misc code formatting fixes.

* Fix build breaks due to code formatting

Fix build issues arised with recent
code formatting issues.

* Fix presubmit script after merge

Fix presubmit script after merge conflicts.

* Fix Vulkan loader build in presubmit script.

Use cmake ninja and appropriate toolchain
for Vulkan loader dependency to fix
linking issue on arm/aarch64.

* Use static array sizes

Use static array sizes to fix
windows builds.

* Some left-out formatting fixes.

Fix remaining formatting issues.

* Fix harness header path

Fix harness header path
While at it, remove Misc and test pragma.

* Add/Fix license information

Add Khronos License info for test_vulkan.
Replace Apple license with Khronos
as applicable.

* Fix headers for Mac OSX builds.

Use appropriate headers for
Mac OSX builds

* Fix Mac OSX builds.

Use appropriate headers for
Mac OSX builds.
Also, fix some build issues
due to type-casting.

* Fix new code formatting issues

Fix new code formatting issues
with recent MacOS fixes.

* Add back missing case statement

Add back missing case statement
that was accidentally removed.

* Disable USE_GAS for Vulkan Loader build.

Disable USE_GAS for Vulkan Loader build
to fix aarch64 build.

* Fixes to OpenCL external sharing tests

Fix clReleaseSemaphore() API.
Fix copyright year.
Some other minor fixes.

* Improvements to OpenCL external sharing CTS

Use SPIR-V shaders instead of NV extension path
from GLSL to Vulkan shaders.
Fixes for lower end GPUs to use limited memory.
Update copy-right year at some more places.

* Fix new code formatting issues.

Fix code formatting issues with
recent changes for external sharing
tests.

* More formatting fixes.

More formatting fixes for recent
updates to external sharing tests.

* Final code formatting fixes.

Minor formatting fixes to get
format checks clean.
2022-10-04 09:00:03 -07:00
Sven van Haastregt
30cc3db4ec
atomics: Fix -Wformat warnings (#1519)
The main sources of warnings were:

 * Printing of `i` which is a `size_t` requiring the `%zu` specifier.

 * Printing of `cl_long` which is now done using the `PRId64` macro
   to ensure portability across 32 and 64-bit builds.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-10-03 22:09:28 +01:00
Sven van Haastregt
18825769e5
pipes: Fix typos in skip messages (#1523)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-10-03 22:09:05 +01:00
Jack Frankland
28e76e532a
Add missing type declaration (#1520)
Add a missing type declaration to OpenCL C code strings in 2D async copy
tests.
2022-10-03 14:32:11 +01:00
victzhan
a3294d4c95
Add Python 3 support to run_conformance.py (#1470) 2022-10-03 14:26:43 +01:00
Sven van Haastregt
73f51ccff7
math_brute_force: Fix -Wformat warnings (#1518)
* math_brute_force: Fix -Wformat warnings

The main sources of warnings were:

 * Printing of 64-bit types, which is now done using the `PRI*64`
   macros from <cinttypes> to ensure portability across 32 and 64-bit
   builds.

 * Printing of `size_t` types that lacked a `z` length modifier.

 * Printing of values with a `z` length modifier that weren't a
   `size_t` type.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

* [NFC] math_brute_force: clang-format after -Wformat changes

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-10-01 10:14:32 +01:00
Sven van Haastregt
c69f6eec47
[NFC] atomics: Remove set-but-unused "succeed" variables (#1517)
The "succeed" variables are never read and they don't seem to serve
any purpose that's not already provided by the "fail" variables.

In `add_index_bin_test` the "fail" variable is also set but unused,
but that may require an actual fix, so leaving that out of this
commit.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-30 11:41:19 +01:00
Sven van Haastregt
9bf6486352
[NFC] clang-format test_atomics (#1516)
Add some clang-format off/on comments to keep lists and kernel code
readable.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-27 09:32:23 -07:00
Sven van Haastregt
9b21e9f06b
[NFC] Avoid mixing signed and unsigned in subhelpers run (#1505)
Fix a `-Wsign-compare` warning in the `run()` function, which resulted
in many repeated warnings when compiling with `-Wall` due to the many
template instantiations.

Both `clGetKernelSubGroupInfo` queries return a `size_t`, so it is
unclear why the results of these queries were being cast to `int`.
The `dynsc` uses don't seem to work with negative values, so make the
field unsigned.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-27 09:29:58 -07:00
Sreelakshmi Haridas Maruthur
30500fba06
SVM: Fix memory allocation size. (#1514)
* SVM: Fix memory allocation size.

9ad48998 generally made memory allocation and mapping consistent with a
size of size_t. Apply that fix to the final two allocations.

* check-format fixes

Co-authored-by: spauls <spauls@qti.qualcomm.com>
2022-09-27 09:28:57 -07:00
ellnor01
c014122742
Creating common functions for image/kernel_read_write read tests (#1141)
* Make InitFloatCoords suitable for all image types

Contributes #616

* Create common functions neutral for image types

Remove 3D specific code from common test_read_image so using
it for other image types is simpler in following patches

Contributes #616

* Removing unused code

Tidying commented out or unnecessary code

Contributes #616

Signed-off-by: Ellen Norris-Thompson <ellen.norris-thompson@arm.com>

* Restoring 'lod' variable name

Contributes #616

* Default cases to handle unsupported image types

Contributes #616

* Resolving build issues

Contributes #616

* Fix formatting

Contributes #616

* Using TEST_FAIL as an error code.

Contributes #616

* Add static keyword, improve error handling

Contributes #616

* Fix build errors with least disruption

Contributes #616

Signed-off-by: Ellen Norris-Thompson <ellen.norris-thompson@arm.com>
2022-09-26 12:57:42 +01:00
Sven van Haastregt
2012c6cadd [NFC] Fix typo in clang-format directive (#1512)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-23 10:08:10 -07:00
Krzysztof Kosiński
180adef84c
Remove __DATE__ and __TIME__ usage (#1506)
These macros make the build non-deterministic.
2022-09-23 17:29:18 +01:00
Sven van Haastregt
92285f7c9d
cmake: Add set_gnulike_module_compile_flags (#1510)
Factor out a macro to set module-specific compilation flags for
GNU-like compilers.  This simplifies setting compilation flags per
test.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-22 13:17:55 -07:00
Nikhil Joshi
86d5ee5414
Update extension list of test_compiler (#1507)
* Update extension list of test_compiler

Upate extension list of test_compiler
with missing external memory and semaphore
extensions
2022-09-20 09:07:14 -07:00
Sven van Haastregt
75edf2a881
[NFC] Enable -Wall for math_brute_force (#1477)
math_brute_force compiles cleanly with `-Wall` currently, so avoid
regressing from that state.  Ideally we would enable `-Wall` in the
top-level CMakeLists.txt, but other tests do not compile cleanly with
`-Wall` yet.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-20 08:55:51 -07:00
niranjanjoshi121
76bd9d3674
Fix memory oob problem in test half (#1489)
Allocate memory for argc arguments
instead of argc - 1.
2022-09-20 08:53:34 -07:00
Sven van Haastregt
8f9c1960ff
Improve MTdataHolder design and use it in math_brute_force (#1490)
Improve the design of the MTdataHolder wrapper:

 * Make it a class instead of a struct with a private member, to make
   it clearer that there is no direct access to the MTdata member.

 * Make the 1-arg constructor `explicit` to avoid unintended
   conversions.

 * Forbid copy construction/assignment as MTdataHolder is never
   initialised from an MTdataHolder object in the codebase.

 * Define move construction/assignment as per the "rule of five".

Use the MTdataHolder class throughout math_brute_force, to simplify
code by avoiding manual resource management.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-20 08:52:22 -07:00
Sven van Haastregt
a87e686757
Fix more warnings in math_brute_force (#1502)
* Fix "‘nadj’ may be used uninitialized in this function
   [-Werror=maybe-uninitialized]".

 * Fix "specified bound 4096 equals destination size
   [-Werror=stringop-truncation]".

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-16 13:34:36 +01:00
Stuart Brady
7859a33182
Include release builds in GitHub Actions (#1486)
The "Ninja" CMake generator does not support multiple configurations,
i.e. it does not support use of the '--config' option when running
'cmake --build'.  As such, the default configuration (i.e. Debug)
was getting used for all builds.

Use the CMAKE_BUILD_TYPE variable instead, so that we do release
builds, but change one build (ubuntu-20.04 aarch64) to use Debug
as its build type, to keep some build coverage for asserts, etc.

For Vulkan-Loader and OpenCL-ICD-Loader, we do release builds
unconditionally, as we assume there is no need in the CI workflow
to actually run the binaries that are built, and therefore no need
for any additional debug info.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-09-13 18:22:52 +01:00
Kévin Petit
c0a10f4e12
Tests for cl-ext-image-from-buffer and cl-ext-image-requirements-info (#1438)
* Add CTS tests for cl_ext_image_requirements_info

Change-Id: I20c1c77ff5ba88eb475801bafba30ef9caf82601

* Add CTS tests for cl_ext_image_from_buffer

Change-Id: Ic30429d77a1317d0fea7d9ecc6d603267fa6602f

* Fixes for image_from_buffer and image_requirements extension

* Use CL_MEM_READ_WRITE flag when creating images that support CL_MEM_KERNEL_READ_AND_WRITE (#1447)

* format fixes

Change-Id: I04d69720730440cb61e64fed2cb5065b2ff8bf90

Co-authored-by: Oualid Khelifi <oualid.khelifi@arm.com>
Co-authored-by: oramirez <oramirez@qti.qualcomm.com>
Co-authored-by: Sreelakshmi Haridas Maruthur <sharidas@quicinc.com>
2022-09-13 09:58:24 -07:00
Sreelakshmi Haridas Maruthur
426097cf7c
gles: Limit variable definition to the same scope as usage (#1495)
Fix unused-variable errors by limiting variable definition to the
case that would use it
2022-09-13 09:50:25 -07:00
Stuart Brady
d42b3dcfb6
[NFC] Fix typo (enevt_type -> event_type) (#1498)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-09-13 17:49:09 +01:00
Sven van Haastregt
5d5bffba13
[NFC] Declare format tables as const (#1493)
Without const, these variables would be flagged up by
`-Wunused-variable`.

Drop `struct` from the declarations as that is not needed in C++.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-13 14:48:54 +01:00
Stuart Brady
1d74c85ff3
[NFC] Reformat code in events test (#1497)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-09-13 13:42:32 +01:00
niranjanjoshi121
d928ac059c
Use correct size for memory allocation in SVM test (#1496)
Memory is allocated for cl_int, but mapped as size_t.

Use size_t instead of cl_int during allocation and mapping for consistency.
2022-09-12 12:42:06 +01:00
Stuart Brady
00f21739e5
Minor cleanups for run_conformance.py (#1492)
Use the print function from futures for Python 3 compatibility,
remove an unreachable statement, remove unused imports, and add
a missing sys.exit call when opening the log file fails.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-09-12 11:49:13 +01:00
Sven van Haastregt
89c8d87963
[NFC] Fix unused variable warning in Release builds (#1494)
The condition inside the assert is dropped in Release builds, so
`num_printed` becomes unused.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-09 17:58:31 +01:00
Sven van Haastregt
6554c49018
[NFCI] Remove unused variables and enable -Wunused-variable (#1483)
Remove unused variables throughout the code base and enable the
`-Wunused-variable` warning flag globally to prevent new unused
variable issues being introduced in the future.

This is mostly a non-functional change, with one exception:

 - In `test_conformance/api/test_kernel_arg_info.cpp`, an error check
   of the clGetDeviceInfo return value was added.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-09-08 12:54:36 +01:00
Stuart Brady
fec9d9a238
[NFC] Fix whitespace issues in run_conformance.py (#1491)
Fix whitespace issues and remove superfluous parens in the
run_conformance.py script.  This addresses 288 out of the 415
issues reported by pylint.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-09-07 17:28:29 +01:00
Ahmed
388944c01c
Minimum 2 non atomic variables per thread for the c11 atomic fence test for embedded profile devices. (#1452)
* Minimum 2 Non atomic variables per thread for an embedded profile device - https://github.com/KhronosGroup/OpenCL-CTS/issues/1274

* Formatting
2022-09-06 09:53:12 -07:00
Ewan Crawford
7caa4c4421
Update known extensions in compiler define test (#1480)
Add
[cl_khr_command_buffer_mutable_dispatch](https://github.com/KhronosGroup/OpenCL-Docs/pull/819),
[cl_khr_subgroup_rotate](https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#cl_khr_subgroup_rotate),
and [cl_khr_extended_async_copies](https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#cl_khr_extended_async_copies)
to the list of known extensions used in
`test_compiler_defines_for_extensions`
2022-09-01 15:13:01 -07:00
niranjanjoshi121
9ad4899862
Use size_t instead of cl_int (#1414)
* Use size_t instead of cl_int

Memory is allocated for cl_int,
but mapped as size_t.
Use size_t instead of cl_int during
allocation and mapping for consistency.

* Use size_t instead of cl_int

Memory is allocated for cl_int,
but mapped as size_t.
Use size_t instead of cl_int during
allocation and mapping for consistency.

* Use size_t instead of cl_int

Memory is allocated for cl_int,
but mapped as size_t.
Use size_t instead of cl_int during
allocation and mapping for consistency.

* Remove test_half changes.

Remove test_half changes from other fix
that got included in this commit.

* Final formatting fix.
2022-08-31 22:58:13 -07:00
Romaric Jodin
2dc2533130
fix test kernel attributes when api fcts are failing (#1449)
test_error returns the err given as the first argument. As the
run_test function returns a bool, we end up returning true (meaning
pass) when an api function fails.
Instead return explicitly false (meaning fail).
2022-08-31 22:56:10 -07:00
Sven van Haastregt
f94c135755
Use clMemWrapper in math_brute_force (#1476)
Simplify code by avoiding manual resource management.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-31 22:43:43 -07:00
Ewan Crawford
8f5a2f0ae8
Initial command-buffer extension tests (#1368)
* Initial command-buffer tests

Introduce some basic testing of the
[cl_khr_command_buffer](https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#cl_khr_command_buffer)
extension. This is intended as a starting point from which we can iteratively build up tests
for the extension collaboratively.

* Move tests into derived classes

* Move tests from methods into derived classes implementing
  a `Run()` interface.
* Fix memory leak when command_buffer isn't freed when a test
  is skipped.
* Print correct error code for
  `CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR`
* Pass `nullptr` for queue parameter to command recording entry-points

* Define command-buffer type wrapper

Other OpenCL object have a wrapper to reference count their use
and free the wrapped object. The command-buffer object can't use
the generic type wrappers which are templated on the appropriate
release/retain function, as the release/retain functions are
queried at runtime.

Instead, define our own command-buffer wrapper class where a base
object is passed on construction which contains function pointers
to the release/retain functions that can be used in the wrapper.

* Use create_single_kernel_helper_create_program

Use `create_single_kernel_helper_create_program` rather than
hardcoding `clCreateProgramWithSource` to allow for other types
of program input.

Also fix bug using wrong enum for passing properties on command-buffer
creation, should be `CL_COMMAND_BUFFER_FLAGS_KHR`

* Add out-of-order command-buffer test

Introduce a basic test for checking sync-point use
with out-of-order command-buffers.

This also includes better checking of required queue properties.
2022-08-30 09:54:50 -07:00
stoneforestwhu
f4eb852b6d
support format CL_ABGR (#1474)
* support format CL_ABGR

add code to handle format CL_ABGR

* Update imageHelpers.h

* fix format
2022-08-30 09:47:15 -07:00
Sven van Haastregt
afe4ef8b8f
Fix test skipping in math_brute_force (#1475)
Commit 9666ca3c ("[NFC] Fix sign-compare warnings in math_brute_force
(#1467)", 2022-08-23) inadvertently changed the semantics of the if
condition.  The `i > gEndTestNumber` comparison was relying on
`gEndTestNumber` being promoted to unsigned.  When casting `i` to
`int32_t`, this promotion no longer happens and as a result any tests
given on the command line were being skipped.

Use an unsigned type for `gStartTestNumber` and `gEndTestNumber` to
eliminate the casts and any implicit conversions between signed and
unsigned types.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-24 12:05:01 +01:00
Sven van Haastregt
c82dabd4bb
Use clCommandQueueWrapper in math_brute_force (#1463)
Simplify code by avoiding manual resource management.

This commit only modifies tests that use one queue per thread.  The
other unmodified tests are single-threaded and use the global
`gQueue`.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-24 10:31:32 +01:00
Sven van Haastregt
9666ca3c70
[NFC] Fix sign-compare warnings in math_brute_force (#1467)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-23 18:02:33 +01:00
Sven van Haastregt
e52a97e4e9
[NFC] Use Unix-style line endings (#1468)
Use the same line ending style across all source files.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-23 17:57:05 +01:00
Sven van Haastregt
d647529fec
[NFC] Fix missing double_double.lo initializer (#1466)
Fixes a missing-field-initializers warning.  The original intent was
most likely to initialize both fields (similar to other functions in
this file), but a `,` was missed.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-16 14:42:33 +01:00
Sven van Haastregt
38639f229d
Fix test_select verification failure reporting (#1462)
When verification of the computed result fails, the test would still
report as "passed".  This is because `s_test_fail` is only written to
and never read.

Fix the immediate issue by returning a failure value and incrementing
`gFailCount` if any error was detected.  The error handling can be
improved further, but I'm leaving that out of the scope of this fix.

Fixes https://github.com/KhronosGroup/OpenCL-CTS/issues/1445

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-04 15:05:10 +01:00
Stuart Brady
4ee8022230
Remove unused variables in subgroup tests (#1460)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-08-04 15:04:14 +01:00
Sven van Haastregt
c12bff46c6
Tidy up BuildKernelInfo (#1461)
Remove the `offset` field from both structures, because it was always
set to the global `gMinVectorSizeIndex`.

Improve documentation and rename some variables:
 - `i` becomes `vectorSize`;
 - `kernel_count` becomes `threadCount`.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-08-04 15:03:52 +01:00
Matthias Diener
c44b5b6ae3
Fix indentation of test_waitlists.cpp (#1459)
* fix indentation of test_waitlists.cpp

Followup of #1458

* run formatter
2022-08-02 20:31:24 +01:00
Stuart Brady
cdf5a105fc
Fix misleading indentation and enable -Wmisleading-indentation (#1458)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-08-02 18:16:03 +01:00
Kévin Petit
bd03e17a56
Add missing external memory/sync extensions to list of known khr extensions (#1455)
Signed-off-by: Kévin Petit <kpet@free.fr>
2022-08-01 10:18:53 +01:00
Stuart Brady
017f514c21
Tidy up subgroup log messages (#1454)
Add missing newlines and improve wording of messages.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-08-01 10:18:36 +01:00
Sven van Haastregt
b06ccc6cd9
Share BuildKernelInfo struct definition (#1453)
Move the main `BuildKernelInfo` definition into `common.h` to reduce
code duplication.

Some tests (e.g. `i_unary_double.cpp`) use a different struct; rename
those structs to `BuildKernelInfo2` for now to avoid ambiguity.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-07-29 18:22:18 +01:00
Sven van Haastregt
0a5a8f90c9
Use clProgramWrapper in math_brute_force (#1451)
Simplify code by avoiding manual resource management.

This allows removing clReleaseProgram from `MakeKernels` to reduce
behavioral differences between `MakeKernels` and `MakeKernel`.

Original patch by Marco Antognini.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-07-28 13:33:16 +01:00
Sven van Haastregt
2cf24e63b7
Fix function name in error messages (#1450)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2022-07-21 18:54:20 +01:00
Callum Fare
a37884fe44
Update cl_khr_extended_async_copies tests to the latest extension version (#1426)
* Update cl_khr_extended_async_copies tests to the latest version of the extension

Update the 2D and 3D extended async copies tests. Previously they were based on
an older provisional version of the extension.

Also update the variable names to only use 'stride' to refer to the actual
stride values. Previously the tests used 'stride' to refer to the end of one
line or plane and the start of the next. This is not the commonly understood
meaning.

* Address cl_khr_extended_async_copies PR feedback

* Remove unnecessary parenthesis in kernel code
* Make variables `const` and rearrange so that we can reuse
  variables, rather than repeating expressions.
* Add in missing vector size of 3 for 2D tests

* Use C++ String literals for kernel code

Rather than C strings use C++11 string literals to define the
kernel code in the extended async-copy tests. Doing this makes
the kernel code more readable.

Co-authored-by: Ewan Crawford <ewan@codeplay.com>
2022-07-19 17:43:36 +01:00
Nikhil Joshi
8d9d1f3e9d
Fix math tests to allow ftz in relaxed mode. (#1371)
* Fix math tests to allow ftz in relaxed mode.

In recent spec clarification, it is agreed that ftz is
a valid optimization in case of cl-fast-math-relaxed
and doesn't require cl-denorms-are-zero to be passed
explicitly to enforce ftz behavior for implementations
that already support this.

GitHub Spec Issue OpenCL-Docs#579
GitHub Spec Issue OpenCL-Docs#597
GitHub CTS Issue OpenCL-CTS#1267
2022-07-05 22:28:18 +05:30
Sven van Haastregt
e3e1786761
Fix newline in sample_image_pixel_float_offset log (#1446) 2022-07-01 15:38:42 +01:00
Stuart Brady
1c19a4cbdb
Add tests for cl_khr_subgroup_rotate (#1439)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-06-28 17:05:11 +01:00
Nikhil Joshi
0b7118186a
Initial CTS for external semaphore and memory extensions (#1390)
* Initial CTS for external sharing extensions

Initial set of tests for below extensions
with Vulkan as producer
1. cl_khr_external_memory
2. cl_khr_external_memory_win32
3. cl_khr_external_memory_opaque_fd
4. cl_khr_external_semaphore
5. cl_khr_external_semaphore_win32
6. cl_khr_external_semaphore_opaque_fd

* Updates to external sharing CTS

Updates to external sharing CTS
1. Fix some build issues to remove unnecessary, non-existent files
2. Add new tests for platform and device queries.
3. Some added checks for VK Support.

* Update CTS build script for Vulkan Headers

Update CTS build to clone Vulkan Headers
repo and pass it to CTS build
in preparation for external memory
and semaphore tests

* Fix Vulkan header path

Fix Vulkan header include path.

* Add Vulkan loader dependency

Vulkan loader is required to build
test_vulkan of OpenCL-CTS.
Clone and build Vulkan loader as prerequisite
to OpenCL-CTS.

* Fix Vulkan loader path in test_vulkan

Remove arch/os suffix in Vulkan loader path
to match vulkan loader repo build.

* Fix warnings around getHandle API.

Return type of getHandle is defined
differently based on win or linux builds.
Use appropriate guards when using API
at other places.
While at it remove duplicate definition
of ARRAY_SIZE.

* Use ARRAY_SIZE in harness.

Use already defined ARRAY_SIZE macro
from test_harness.

* Fix build issues for test_vulkan

Fix build issues for test_vulkan
1. Add cl_ext.h in common files
2. Replace cl_mem_properties_khr with cl_mem_properties
3. Replace cl_external_mem_handle_type_khr with
cl_external_memory_handle_type_khr
4. Type-cast malloc as required.

* Fix code formatting.

Fix code formatting to
get CTS CI builds clean.

* Fix formatting fixes part-2

Another set of formatting fixes.

* Fix code formatting part-3

Some more code formatting fixes.

* Fix code formatting issues part-4

More code formatting fixes.

* Formatting fixes part-5

Some more formatting fixes

* Fix formatting part-6

More formatting fixes continued.

* Code formatting fixes part-7

Code formatting fixes for image

* Code formatting fixes part-8

Fixes for platform and device query tests.

* Code formatting fixes part-9

More formatting fixes for vulkan_wrapper

* Code formatting fixes part-10

More fixes to wrapper header

* Code formatting fixes part-11

Formatting fixes for api_list

* Code formatting fixes part-12

Formatting fixes for api_list_map.

* Code formatting changes part-13

Code formatting changes for utility.

* Code formatting fixes part-15
Formatting fixes for wrapper.

* Misc Code formatting fixes

Some more misc code formatting fixes.

* Fix build breaks due to code formatting

Fix build issues arised with recent
code formatting issues.

* Fix presubmit script after merge

Fix presubmit script after merge conflicts.

* Fix Vulkan loader build in presubmit script.

Use cmake ninja and appropriate toolchain
for Vulkan loader dependency to fix
linking issue on arm/aarch64.

* Use static array sizes

Use static array sizes to fix
windows builds.

* Some left-out formatting fixes.

Fix remaining formatting issues.

* Fix harness header path

Fix harness header path
While at it, remove Misc and test pragma.

* Add/Fix license information

Add Khronos License info for test_vulkan.
Replace Apple license with Khronos
as applicable.

* Fix headers for Mac OSX builds.

Use appropriate headers for
Mac OSX builds

* Fix Mac OSX builds.

Use appropriate headers for
Mac OSX builds.
Also, fix some build issues
due to type-casting.

* Fix new code formatting issues

Fix new code formatting issues
with recent MacOS fixes.

* Add back missing case statement

Add back missing case statement
that was accidentally removed.

* Disable USE_GAS for Vulkan Loader build.

Disable USE_GAS for Vulkan Loader build
to fix aarch64 build.

* Update Copyright Year.

Update Copyright Year to 2022
for external memory sharing tests.

* Android specific fixes

Android specific fixes to
external sharing tests.
2022-06-21 21:51:47 +05:30
Wenju He
67ac6c8d2d
Fix test_half async_work_group_copy arguments (#1298) (#1299)
Workitems in the last workgroup calls async_work_group_copy with
different argument values depending on 'adjust'. According to spec,
this results in undefined values.
2022-06-14 08:51:39 -07:00
Ahmed
f1c051afb1
Added missing tests for integer_dot_product_input_4x8bit and integer_dot_product_input_4x8bit_packed on feature_macro compiler test. (#1432)
* Added integer_dot_product_input_4x8bit and integer_dot_product_input_4x8bit_packed tests to feature_macro_test

* clang formatting

* Now the test checks whether the array of optional features returned by clGetDeviceInfo contains the standard optional features we are testing.

* Update test_conformance/compiler/test_feature_macro.cpp

Added printing the missing standard feature it it is not found inside the optional features array returned by clGetDeviceInfo.

Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>

Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>
2022-06-14 08:48:59 -07:00
paulfradgley
c2aca7d8e6
Fix local memory out of bounds issue in atomic_fence (replaces PR #1285) (#1437)
* Fix local memory out of bounds in atomic_fence

In the error condition, the atomic_fence kernel can illegally access local memory addresses.

In this snippet, localValues is in the local address space and provided as a kernel argument. Its size is effectively get_local_size(0) * sizeof(int). The stores to localValues lead to OoB accesses.

  size_t myId = get_local_id(0);

  ...

  if(hisAtomicValue != hisValue)
  { // fail
    atomic_store(&destMemory[myId], myValue-1);
    hisId = (hisId+get_local_size(0)-1)%get_local_size(0);
    if(myValue+1 < 1)
      localValues[myId*1+myValue+1] = hisId;
    if(myValue+2 < 1)
      localValues[myId*1+myValue+2] = hisAtomicValue;
    if(myValue+3 < 1)
      localValues[myId*1+myValue+3] = hisValue;
  }

* Fix formatting

* Fix formatting again

* Formatting
2022-06-14 08:47:06 -07:00
jansol
7c65afc4e7
test_compiler_defines_for_extensions: fix overflow (#1430)
GCC 11.2.0 warns about a possible string overflow (when
num_not_supported_extensions+num_of_supported_extensions == 0)
since no space would be allocated for the terminating
null byte that string manipulation fns expect to find.

This unconditionally adds an extra byte to the allocation to silence
the warning and fix building with -Werror.
2022-06-07 08:55:43 -07:00
paulfradgley
3bf46004ef
Fixes incorrect slice pitch calculation in clCopyImage 1Darray (#1258)
The slice pitch/padding calculation assumed that the 'height' variable contained the pixel height of the image, which it doesn't for IMAGE1D_ARRAY.
Fixes #1257
2022-05-31 08:55:42 -07:00
Ewan Crawford
f32f1aeaa2
Add content to README (#1427)
Fill in the placeholder readme with some basic information on building and
running the project. Information on the conformance submission process and
contributing are also included.

Should help close a few issues referenced in
https://github.com/KhronosGroup/OpenCL-CTS/issues/1096

I don't think this is all the information we want, but is a starting point
from which we can progress. For example, adding the android build instructions
from https://github.com/KhronosGroup/OpenCL-CTS/pull/1021
2022-05-17 08:54:39 -07:00
Jeremy Kemp
d54954c7cf
Enable mipmap extension pragmas (#1349)
* Enable mipmap pragmas where appopriate.

* clang-format changes.
2022-05-17 08:52:40 -07:00
Jason Ekstrand
6e6249fb48
images: Stop checking gDeviceType != CL_DEVICE_TYPE_GPU (#1418)
* images: Stop checking gDeviceType != CL_DEVICE_TYPE_GPU

If the device type also advertises CL_DEVICE_TYPE_DEFAULT (which should
be valid), this causes it to be considered a CPU device and the tests
enforce different precision and rounding expectations.

* Fix clang-format

* Drop redundant NORM_OFFSET checks
2022-05-17 08:51:53 -07:00
Karol Herbst
5149de2277
api/kernel_arg_info: Check for read_write image support before testing it (#1420)
Code taken from api/test_min_image_formats.cpp
2022-05-17 08:51:10 -07:00
Kévin Petit
3662d17447
Update Github Actions CI and add Windows (#1413)
- Add one Windows build to Github Actions
- Remove Appveyor config
- Move a few build steps out of the script
- Use Ninja as the generator (makes for more readable logs)
- Add build cache (except on Windows where it seems to break)

Change-Id: Ida90ee1842af98aff86e5144ab7b9766480378c9
Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2022-04-29 10:42:27 -07:00
Jeremy Kemp
5d6ca3e9d1
Change memory order and scope for atomics that gate final results being stored. (#1377)
* Change memory order and scope for atomics that gate final results being stored.

memory_order_acq_rel with memory_scope_device is now used to guarantee that the correct memory consistency is observed before final results are stored.

Previously it was possible for kernels to be generated that all used relaxed memory ordering, which could lead to false-positive failures.

Fixes #1370

* Disable atomics tests with global, in-program atomics.

If the device does not support `memory_order_relaxed` or `memory_scope_device`, disable atomics tests that declare their atomics in-program with global memory.

There is now an implicit requirement to support `memory_order_relaxed` and `memory_scope_device` for these tests.

* Fix misplaced parentheses.

* Change memory scope for atomic fetch and load calls in kernel

Change the memory scope from memory_scope_work_group to
memory_scope_device so the ordering applies across all work items

Co-authored-by: Sreelakshmi Haridas <sharidas@quicinc.com>
2022-04-28 15:34:08 -07:00
Romaric Jodin
35c21a8e06
imageHelpers: add CL_UNORM_SHORT_{555, 565} in get_max_absolute_error (#1406)
* imageHelpers: add CL_UNORM_SHORT_{555, 565} in get_max_absolute_error

Working on a device supporting CL_UNORM_SHORT_565 image data type, I
noticed that the max absolute error authorized was not the right one
for such image data type.

Also because of normalization, there is always an absolute error
authorized whatever the filtering of the sampler.

Ref #1140

* put back if statement on filter_mode
2022-04-28 14:46:52 -07:00
Jason Ekstrand
13d1b01f65
test_basic/enqueue_map: Initialize all the data (#1417)
Some checks failed
Presubmit / Build ubuntu-20.04 (push) Failing after 5m3s
Presubmit / Build ubuntu-20.04 AArch64 (push) Failing after 3s
Presubmit / Build ubuntu-20.04 Arm (push) Failing after 3s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
2022-04-22 10:51:32 +01:00
Jim Lewis
03da14d6a9
Fix clang 10 build errors (#1387)
* Fix clang 10 build errors

Lossy casts due to inexact float representation of CL_INT_MAX

* Fix clang format

* Remove implicit-const-int-float-conversion flag
2022-04-19 09:57:15 -07:00
Grzegorz Wawiorko
d533472c27
Fix incorrect use image channel data type and filtering mode (#1375) 2022-04-19 17:55:03 +01:00
Stuart Brady
7a0e7e767a
Test all cluster sizes for cl_khr_subgroup_clustered_reduce (#1408)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-04-12 09:42:55 -07:00
Ben Ashbaugh
2fcdde96d2
refactor work group scan and reduction tests (#1401)
* updated reduce test

* switched all reduce tests to new framework

* switch over scans to new framework

* remove old files

* minor fixes

* add type type name to the kernel name

* fix Windows build and warnings

* address review comments
2022-04-04 13:19:30 -07:00
Stuart Brady
e121b9d1bf
Fix sub_group_ballot_find_msb/lsb tests (#1411)
As per the OpenCL Extension Specification § 38.6 Ballots:

   If no bits representing predicate values from all work items in
   the subgroup are set in the bitfield value then the return value
   is undefined.

The case with no bits set is still worth testing, as it does not result
in undefined behavior, but only an undefined return value.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-04-04 09:57:36 -07:00
Jason Tang
93f4f6a548
test_api_min_max.cpp: use size_t for get_global_id() value (#1410)
In some rare cases where get_global_id() is larger than 2G, the 32bit int type would convert the value into a negative integer.
2022-03-29 16:08:08 -07:00
Stuart Brady
c42cf518da
Improve cl_khr_subgroup_shuffle* test coverage (#1402)
Test cases where the index/mask/delta is greater than or equal to the
maximum subgroup size.  These are cases that return undefined results
but are not undefined behavior.

The index/mask/delta values now include values less than twice the
subgroup size, and 0xffffffff.

Testing for sub_group_shuffle_xor() already allowed inputs that were
greater or equal to the subgroup size for the last subgroup in a
workgroup, but did not properly account for this in the verification
function, potentially resulting in out of bounds accesses.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-03-29 11:39:06 -07:00
Stuart Brady
f6dbc5b9b5
Add cluster size handling in subgroup test helpers (#1394)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-03-22 09:21:09 -07:00
Sreelakshmi Haridas Maruthur
0f4dc3166c
conversions: Use volatile qualifier to prevent optimizations (#1399)
Use volatile to prevent clang optimizations, fix int2float
2022-03-17 13:27:24 -07:00
Ben Ashbaugh
bbc7ccfc58
add a prefix to OpenCL extension names (#1311)
* add a prefix to OpenCL extension names

* fix formatting
2022-03-02 18:34:06 +00:00
Jim Lewis
3c4a1a3ce6
Fix build error for linux with clang-8 (#1304)
-Wabsolute-value warning reported as error (long double truncated to
double)
2022-03-02 18:31:14 +00:00
Jack Frankland
ae217e8bd2
Check for non-uniform work-group support (#1383)
Only run sub-group tests with non-uniform work-groups on OpenCL 3.0 and
later if it is supported by the device.
2022-03-02 18:30:31 +00:00
Jeremy Kemp
e437acd908
Added simple test for CL_DEVICE_PRINTF_BUFFER_SIZE. (#1386)
* Added simple test for CL_DEVICE_PRINTF_BUFFER_SIZE.

* Clang format fix.
2022-03-02 18:28:12 +00:00
Alastair Murray
d36196b662
Update format script and drop Travis badge for branch rename (#1393)
`master` is now `main`, so update `check-format.sh` accordingly.

Also completely drop the Travis badge as we now use GitHub actions.  There is
no replacement badge as the current action is pre-submission, not
post-submission.
2022-03-02 18:27:52 +00:00
Stuart Brady
279803abab
Refactor kernel execution in subgroup tests (#1391)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-03-02 13:25:53 +00:00
Jim Lewis
2d93b122c3
Sync submission_details with conformance doc v26 (#1389)
Some checks failed
Presubmit / Build ubuntu-20.04 (push) Failing after 5m2s
Presubmit / Build ubuntu-20.04 AArch64 (push) Failing after 3s
Presubmit / Build ubuntu-20.04 Arm (push) Failing after 3s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
Add "Patches" field
2022-02-22 16:49:35 +00:00
Stuart Brady
6b14d408dc
Improve testing of kernel arg info in pipe_info test (#1326)
The test now checks that CL_KERNEL_ARG_INFO_NOT_AVAILABLE is returned
when calling clGetKernelArgInfo() with offline compilation modes.

The correct function name is printed if clGetKernelArgInfo() fails
when using online compilation (and not "clSetKernelArgInfo()").

When using online compilation, if the actual arg type is not as
expected, the actual arg type is now logged, and the return value
is now TEST_FAIL (-1) as per other failures (and not 1).

All other test pass/fail values used in the test now use TEST_PASS
and TEST_FAIL instead of 0 and -1 literals.

An unnecessary cast of pipe_kernel_code has been removed.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-02-09 22:24:33 -08:00
Stuart Brady
60471a5208
Improve testing of sub_group_ballot (#1382)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-01-28 09:15:44 +00:00
Stuart Brady
656886030b
Refactor divergence mask handling in subgroup tests (#1379)
This changes compilation of subgroup test kernels so that a separate
compilation is no longer performed for each divergence mask value.

The divergence mask is now passed as a kernel argument.

This also fixes all subgroup_functions_non_uniform_arithmetic testing
and the sub_group_elect and sub_group_any/all_equal subtests of the
subgroup_functions_non_uniform_vote test to use the correct order of
vector components for GPUs with a subgroup size greater than 64.

The conversion of divergence mask bitsets to uint4 vectors has been
corrected to match code comments in WorkGroupParams::load_masks()
in test_conformance/subgroups/subhelpers.h.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2022-01-19 14:17:54 +00:00
Sreelakshmi Haridas Maruthur
06415f8b79
Fix memory leaks (#1378)
* Fix memory leaks

Fixed memory leaks in: buffers, basic, and vectors

* Formatting fixes

Co-authored-by: oramirez <oramirez@qti.qualcomm.com>
2022-01-11 16:52:11 +00:00
Jim Lewis
51c6d97d2f
Fix test_api get_command_queue_info (#1324)
* Fix test_api get_command_queue_info

Decouple host and device out-of-order test enabling

* Rename property sets more generically

* Refactor to use std::vector to accumulate test permutations
2022-01-06 10:26:20 +00:00
Jim Lewis
f91daf3d06
Remove invalid negative_get_platform_info testcase (#1374)
* Remove invalid negative_get_platform_info testcase

* Implementations are only required to do null checks
* Fixes #1318

* Fix formatting
2022-01-06 10:23:07 +00:00
Grzegorz Wawiorko
b71c204794
test_subgroups - Set safe input values for half type and mul, add operations (#1346)
* Set safe input values for half type and mul, add operations

* Set safe values for all data types

* Typo fix

* Set constant seed for shuffle

* Change function name to more specific

* set_value takes an integer value, not a bit pattern
2022-01-05 08:08:52 -08:00
Sreelakshmi Haridas Maruthur
c2facedfa0
Remove dead threading code (#1339)
Remove unused code that hasn't been used for the last three years
and isn't included in makefiles.

Co-authored-by: oramirez <oramirez@qti.qualcomm.com>
2022-01-05 07:43:50 -08:00
Stuart Brady
1161d788dd
Refactor logging of subgroup test start/pass messages (#1361)
Note that this also corrects the start messages logged for the
sub_group_ballot_bit_count/find_msb/find_lsb tests.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-12-14 17:52:44 +00:00
Ewan Crawford
73d71b6a76
Add cl_khr_command_buffer to list of extensions (#1365)
cl_khr_command_buffer is now public as a provisional khr extension
which implementations may report.
2021-12-08 16:08:15 +00:00
Grzegorz Wawiorko
8ffecf27c2
Fix build, glext should not be used with GLEW (#1337)
* Fix build, glext should not be used with GLEW

* Remove additional define GL_GLEXT_PROTOTYPES

* Remove includes which already defined in setup.h
2021-12-08 16:07:42 +00:00
Grzegorz Wawiorko
e106be14f9
Test api min max - fix printing cl_ulong data type (#1212)
* test api - fix code formatting only

* Fix printing cl_ulong type to avoid overloading.

* Fix printing size_t data type

* Fix printing size_t data type - set unsinged

* Fix formatting for maxArgs (uint) and numberOfInts (size_t)
2021-12-04 09:55:17 -08:00
Stuart Brady
f8ec235d3c
Tidy up code to determine bit mask for ballot scans (#1363)
It seems more intuitive to set only the bits that are required, rather
than to set one more bit than is required, only to clear it again.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-12-02 15:27:30 +00:00
Stuart Brady
7625011b66
Remove unused inclusion of <cstdio> (#1362)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-11-26 15:30:23 +00:00
Grzegorz Wawiorko
6f50623ba8
Subgroups tests - sub_group_non_uniform_scan_exclusive function fixes (#1350)
* Fix - comparing results will never happen.

* No special action needed for one work item in the subgroup
2021-11-25 13:41:06 +00:00
BKoscielak
6dff4fdffa
Fix conversion data loss in test_api min_max_constant_args (#1355) 2021-11-25 13:40:19 +00:00
Stuart Brady
3eb0f50d85
Use maximum subgroup size in sub_group_ballot tests (#1344)
sub_group_ballot_bit_count() and sub_group_ballot_find_msb() mask
their input according to a subgroup size, which is assumed to be the
maximum subgroup size, and not the actual subgroup size excluding
non-existent work-items in the "remainder" subgroup.

Fix this as per the the clarification made to the OpenCL C specification
in revision 3.0.9 for issue KhronosGroup/OpenCL-Docs#626 by pull request
KhronosGroup/OpenCL-Docs#689.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-11-25 13:36:20 +00:00
James Price
c25709f396
Fix stack-use-after-scope crash in conversions (#1358)
The way that program sources were being constructed involved capturing
pointers to strings that were allocated on the stack, and then trying
to use them outside of that scope. This change uses a stringstream
defined in the outer scope to build the program instead.
2021-11-23 19:04:02 +00:00
marcat03
3cd906aa9b
Fix missing cl_khr_semaphore extensions in compiler tests (#1357)
* Added missing extensions related to cl_khr_semaphore

Signed-off-by: Marco Cattani <marco.cattani@arm.com>
2021-11-16 16:07:43 +00:00
Stuart Brady
1c6dbc23e7
Clean up logging in cl_khr_subgroup_ballot tests (#1351)
The tests were logging scalar results as vectors padded with zeroes for
no apparent benefit.  Fix this.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-11-16 14:03:06 +00:00
Stuart Brady
1116a71ba2
Improve error handling in subgroup tests (#1352)
* MPGCOMP-14761 Improve error handling in subgroup tests

Signed-off-by: Stuart Brady <stuart.brady@arm.com>

* Add missing newline
2021-11-16 11:27:04 +00:00
Stuart Brady
e9cd9a446e
Remove excessive logging in subgroup tests (#1343)
This also adds some missing data type logging to the
subgroup_functions_non_uniform_vote tests.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-11-08 11:00:50 +00:00
Stuart Brady
410f46f49f
Add testing of sub_group_broadcast for (u)char and (u)short types (#1347)
Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-11-03 16:36:36 +00:00
Grzegorz Wawiorko
7147d072c7
Remove space character from extension name (#1336)
Some checks failed
Presubmit / Build ubuntu-20.04 (push) Failing after 5m4s
Presubmit / Build ubuntu-20.04 AArch64 (push) Failing after 3s
Presubmit / Build ubuntu-20.04 Arm (push) Failing after 2s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
2021-10-04 14:42:44 +01:00
Grzegorz Wawiorko
92844bead1
Extended subgroups - use 128bit masks (#1215)
* Extended subgroups - use 128bit masks

* Refactoring to avoid kernels code duplication

* unification kernel names as test_ prefix +subgroups function name
* use string literals that improve readability
* use kernel templates that limit code duplication
* WorkGroupParams allows define default kernel - kernel template for multiple functions
* WorkGroupParams allows define  kernel for specific one subgroup function

Co-authored-by: Stuart Brady <stuart.brady@arm.com>
2021-10-01 11:28:37 +01:00
Kévin Petit
903f1bf65d
Report unsupported extended subgroup tests as skipped rather than passed (#1301)
* Report unsupported extended subgroup tests as skipped rather than passed

Also don't check the presence of extensions for each sub-test.

Signed-off-by: Kévin Petit <kpet@free.fr>

* address review comments
2021-09-30 13:33:18 +01:00
Kévin Petit
2b770c4f34
Update cl_khr_integer_dot_product tests for v2 (#1317)
* Update cl_khr_integer_dot_product tests for v2

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
Signed-off-by: Marco Cattani <marco.cattani@arm.com>
Change-Id: I97dbd820f1f32f6b377e47d0bf638f36bb91930a

* only query acceleration properties with v2+

Change-Id: I3f13a0cba7f1f686365b10adf81690e089cd3d74
2021-09-29 12:38:42 +01:00
Sreelakshmi Haridas Maruthur
4fb5deeec1
api: Enable cl_khr_fp16 when using half types in kernel (#1327) 2021-09-28 10:19:40 -07:00
Sreelakshmi Haridas Maruthur
ddca0f802b
gles: Fix double frees. (#1323)
* gles: Fix double frees.

Remove a few explicit frees in the redirect_buffers test which are
already handled by a wrapper.

* gles: Fix double frees

A recent update to the object wrapper classes (#1268) changed the
behavior of assigning to a wrapper, whereby the wrapped object is now
released upon assignment. A couple of tests were manually calling
clReleaseMemObject and then assigning `nullptr` to the wrapper,
resulting in the wrapper calling clReleaseMemObject on an object that
had already been destroyed.

Co-authored-by: spauls <spauls@qti.qualcomm.com>
2021-09-28 10:19:17 -07:00
Ben Ashbaugh
02bf24d2b1
remove min max macros (#1310)
* remove the MIN and MAX macros and use the std versions instead

* fix formatting

* fix Arm build

* remove additional MIN and MAX macros from compat.h
2021-09-13 13:25:32 +01:00
Jeremy Kemp
1f26e1d8ba
Fix memory model issue in atomic_flag. (#1283)
* Fix memory model issue in atomic_flag.

In atomic_flag sub-tests that modify local memory, compilers may re-order memory accesses between the local and global address spaces which can lead to incorrect test failures.

This commit ensures that both local and global memory operations are fenced to prevent this re-ordering from occurring.

Fixes #134.

* Clang format changes.

* Added missing global acquire which is necessary for the corresponding global release.

Thanks to @jlewis-austin for spotting.

* Clang format changes.

* Match the condition for applying acquire/release fences.
2021-09-07 12:47:44 +01:00
Senran (Stephen) Zhang
34e47322db
Limit workgroup size for atomics tests (#1197)
* Limit workgroup size for atomics tests

This avoids extremely large local buffer size and slow run

* Always limit workgroup size
2021-09-06 17:14:36 +01:00
James Price
0601c6f765
Add missing include for gRandomSeed (#1307) 2021-08-31 11:45:24 -07:00
Ben Ashbaugh
995c7dbfbb
suppress MSVC strdup warning (#1314) 2021-08-31 11:44:17 -07:00
Grzegorz Wawiorko
e27a97fbd8
Add cl_khr_integer_dot_product to known extensions in test compiler. (#1316) 2021-08-31 15:53:55 +01:00
Kévin Petit
7cfd3a6033
Report failures in simple_{read,write}_image_pitch tests (#1309) 2021-08-29 15:12:52 -07:00
Ben Ashbaugh
39fdb462be
define NOMINMAX in the CMakefile to fix std::min and std::max on MSVC (#1308) 2021-08-28 10:21:34 +01:00
Ben Ashbaugh
070f8c0c0e
add tests for cl_khr_integer_dot_product (#1276)
* cl_khr_integer_dot_product_tests

* remove emulated codepaths

* fix formatting

* address code review comments

* remove emulated codepaths again

* address one more review comment
2021-08-25 10:14:58 +01:00
Kévin Petit
6c3c7e5266
Remove unused definitions in CMakeLists.txt (#1302)
Signed-off-by: Kévin Petit <kpet@free.fr>
2021-08-19 12:15:47 +01:00
Kévin Petit
43e1397468
Fix kernel source for cl_khr_suggested_local_work_size (#1300)
Use ASCII '-' instead of unicode '–' as subtration operator.

Signed-off-by: Kévin Petit <kpet@free.fr>
2021-08-18 11:11:30 +01:00
Grzegorz Wawiorko
6da9c6b68f
Fix double free in c11_atomics tests for SVM allocations (#1286)
Some checks failed
Presubmit / Build ubuntu-20.04 (push) Failing after 5m3s
Presubmit / Build ubuntu-20.04 AArch64 (push) Failing after 3s
Presubmit / Build ubuntu-20.04 Arm (push) Failing after 2s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-latest (push) Has been cancelled
* Only Clang format changes

* Fix double free object for SVM allocations

* Fix double free - review fixes
2021-08-11 18:06:10 +01:00
Feng Zou
1aa930957a
Temporarily disable the test_kernel_attributes test case (#1297)
* Temporarily disable the test_kernel_attributes test case

Per OpenCL spec on CL_KERNEL_ATTRIBUTES, for kernels not created from OpenCL C
source and the clCreateProgramWithSource API call the string returned from this
query will be empty.
But in test_kernel_attributes test, it read from bc binary and expect to get
kernel attribute, which is not consistent with OpenCL spec.

* Fix clang format issue
2021-08-11 18:04:21 +01:00
Ben Ashbaugh
4759e5cae0
remove testing for scalar vloada_half (#1293) 2021-08-11 18:03:44 +01:00
kalchr01
cc0b46e457
Add tests for entrypoint cl_khr_suggested_local_work_size (#1264)
* Add tests for entrypoint cl_khr_suggested_local_work_size

Tests added within test_conformance/workgroups. The tests cover several
shapes (num dimensions) and sizes of global work size, kernels using
local memory (dynamic and static) and present/non-present global work
offset.

Signed-off-by: Kallia Chronaki <kallia.chronaki@arm.com>

* Fix in comparison for error checking

Signed-off-by: Kallia Chronaki <kallia.chronaki@arm.com>

* 'test_wg_suggested_local_work_size' fixes

* Refactoring of 'test_wg_suggested_local_work_size'

Modifications to reduce code duplication and minimize build time
2021-08-09 11:20:40 +01:00
Sreelakshmi Haridas Maruthur
79f692d8e5
subgroups: Fix setting cl_halfs and progress check. (#1278)
* subgroups: Fix setting cl_halfs and progress check.

cl_float testing uses set_value such that a generated cl_ulong of 1 is
stored as 1.0F in a logical sense. However, cl_half values aren't
intrinsic to C++ and generated cl_ulongs less than 1024 in particular
are interpreted bitwise as subnormals. The test fails on compute devices
lacking subnormal support. Perform the logical conversion to cl_half.

Fix independent forward progress check.

* subgroups_half: Address review comments

* subgroups_half: Formatting fixes required by check-format

* subgroups_half: Modified to query and use rounding mode supported by device

Co-authored-by: spauls <spauls@qti.qualcomm.com>
2021-07-21 08:51:29 +01:00
Grzegorz Wawiorko
12637114ac
Fix double release of object in test_api and test_gl (#1287)
* Fix clang format only

* Fix double release of objects
2021-07-21 08:50:22 +01:00
Ben Ashbaugh
b500da5fbc
add basic test for cl_khr_pci_bus_info (#1227)
* add basic test for cl_khr_pci_bus_info

* correctly use TEST_SKIPPED_ITSELF

Co-authored-by: Kévin Petit <kpet@free.fr>

* fix related usage of TEST_SKIPPED_ITSELF

Co-authored-by: Kévin Petit <kpet@free.fr>
2021-07-21 08:48:48 +01:00
BKoscielak
433974fd28
Fix check for image support in test_basic sizeof (#1269) 2021-07-13 17:15:33 +01:00
James Price
4a03bb79cb
Fix double-release of memory objects (#1277)
A recent update to the object wrapper classes (#1268) changed the
behavior of assigning to a wrapper, whereby the wrapped object is now
released upon assignment. A couple of tests were manually calling
clReleaseMemObject and then assigning `nullptr` to the wrapper,
resulting in the wrapper calling clReleaseMemObject on an object that
had already been destroyed.
2021-07-05 15:35:39 +01:00
Kévin Petit
236cd73fa1
Use macOS 10 in CI (#1282)
macOS jobs frequently fail. Since macos-11.0 support is considered experimental,
move to macos-10, using macos-latest so we automatically move to 11 when
stable.

See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2021-07-02 10:34:13 +01:00
Marco Antognini
69f0054001
Fix copy and move semantics of wrapper classes (#1268)
* Remove unnecessary code

These custom equality operators are not necessary because of the
conversion operators which already allow using the standard equality
operators between two pointers.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>

* Fix copy and move semantics of wrapper classes

Related to #465.

The Wrapper classes are rewritten to properly handle copy and move
semantics, while preserving the existing API and removing code
duplication.

Add error handling around clRelase* and clRetain*.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>

* Address build issue on 32-bit Windows

Include linkage in RetainReleaseType function type.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-06-17 14:05:05 +01:00
John Kesapides
80a4a833be
Minor fixes for CL_UNORM_SHORT_565, CL_UNORM_SHORT_555 (#1129)
Some checks failed
Presubmit / Build ubuntu-20.04 (push) Failing after 5m3s
Presubmit / Build ubuntu-20.04 AArch64 (push) Failing after 4s
Presubmit / Build ubuntu-20.04 Arm (push) Failing after 3s
Presubmit / Check code format (push) Failing after 5m1s
Presubmit / Build macos-11.0 (push) Has been cancelled
* Minor fixes for CL_UNORM_SHORT_565, CL_UNORM_SHORT_555

* Fix verification for undefined bit
* Relax current infinitely precision requirement for these formats
  and move check in common function.
* Add proper debug output.

Signed-off-by: John Kesapides <john.kesapides@arm.com>

* Minor Formating fix.

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2021-06-11 09:44:16 +01:00
Stuart Brady
277d029608
Run spirv-val for SPIR-V offline compilation (#1108)
The common --disable-spirv-validation option has been added to disable
this functionality.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-06-11 09:42:20 +01:00
Marco Antognini
76ace61314
Fix leaks in callSingleTestFunction (#1224)
The context and queue were not released when the test is not supported
in offline mode or the queue couldn't be created.

Inline test_missing_support_offline_cmpiler_ret macro, remove dead
parameter of check_functions_for_offline_compiler and slightly refactor
callSingleTestFunction to address leaks.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-06-09 11:08:08 +01:00
Marco Antognini
315998511a
Address data race in ThreadPool (#1265)
ThreadSanitizer detects some data race in ThreadPool. They stem from
inappropriate usage of volatile which are replaced with std::atomic
variables in this patch.

This patch focuses on data races identified while running the
math_brute_force component. For example, it doesn't fully remove usage
of ThreadPool_AtomicAdd from other components of the CTS. Furthermore,
thread leaks, most likely because threads are not joined, are not
addressed.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-27 09:06:13 +01:00
Grzegorz Wawiorko
bd3135dd01
Extend list of known extensions (#1262) 2021-05-27 09:05:27 +01:00
Stuart Brady
0876ea10be
Ignore padding bits in clCopyImage/clFillImage testing (#1184)
The CL_UNORM_SHORT_555 and CL_UNORM_INT_101010 formats contain padding
bits which need to be ignored in clCopyImage and clFillImage testing.

For clFillImage tests, padding was not ignored for the CL_UNORM_SHORT_555
format, and was ignored for CL_UNORM_INT_101010 by modifying actual and
reference data.  For clCopyImage tests, padding was not ignored, both for
CL_UNORM_SHORT_555 and for CL_UNORM_INT_101010.

Fix this by adding a new compare_scanlines() function, which is used for
both of these formats, and does not modify the actual or reference data.

Signed-off-by: Stuart Brady <stuart.brady@arm.com>
2021-05-24 16:59:03 +01:00
Marco Antognini
ed839ebf10
Avoid manual memory management (#1260)
* Avoid manual memory management

Prefer std::vector over malloc and free. This will allow removing goto
statements by leveraging RAII.

Use appropriate type (bool) to store overflow predicates and allocate
std::vector<bool> of appropriate sizes: before this change the
allocation was unnecessary bigger than required.

No longer attempt to catch "out of host memory" issues, given that in
such situation it is generally not possible to cleanly report an error.
Rely on std::bad_alloc exception to report such issues.

Introduce a new header for common code in the math_brute_force
component. It is currently complementary to utility.h and is expected to
hold cleaned up content extracted from future refactoring operations.

List all headers as source in CMake for better compatibility with IDEs.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>

* Remove manual or unnecessary memset

In order to use non-POD types as fields of TestInfo, memset must be
replaced with a compatible zero-initialisation.

Remove an unnecessary memset in MakeKernels.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-24 16:34:54 +01:00
ouakheli
a08cacc673
Fix clang-format-9 install (#1261) 2021-05-24 11:31:37 +01:00
Marco Antognini
ba9312e4a2
Fix ODR violations in math_brute_force (#1255)
A program having a type (such as ThreadInfo) defined differently in
multiple translation units exhibits undefined behaviour.

This commit fixes such issues in the math_brute_force component by
ensuring most types are local to their translation unit with the help of
anonymous namespaces. Later refactoring will be able to extract common
definitions to a single place.

This patch also removes unnecessary static and typedef keywords.
Otherwise, code is only moved around with no change.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-21 10:07:54 +01:00
James Price
ce1687a408
Add missing cstdint include (#1259) 2021-05-21 10:07:12 +01:00
Marco Antognini
01aa55029d
Update warning options (#1252)
Remove workaround for #783, this was fixed by #1237.

Remove workaround for overflow, #699 has been merged.

Disable errors from -Wimplicit-const-int-float-conversion, the issue is
covered by #1250.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-21 10:06:13 +01:00
Pierre Moreau
de49d59c8d
Allocations fixes (#1245)
* allocations: Run buffer non-blocking even without images

Testing buffer non-blocking should not be dependent on whether images
are supported by a device or not.

* allocations: Fix typos
2021-05-18 18:12:55 +01:00
Sreelakshmi Haridas Maruthur
6c8045911a
gles: Fix compile warnings. (#1070)
* gles: Fix compile warnings.

For 32 and 64-bit Visual Studio and the Android Q NDK.

* Fix formatting violations

Co-authored-by: spauls <spauls@qti.qualcomm.com>
2021-05-18 18:10:24 +01:00
Marco Antognini
17a0d09567
Cleanup usage of static, extern and typedef (#1256)
* Cleanup usage of static, extern and typedef

Remove static on functions defined headers, as it can result in
duplication in binaries.

Remove unnecessary extern keyword on a function declaration, as it is
the default behavior and can be puzzling when reading the code.

Remove the unused declaration of my_ilogb, which is never defined.

Remove unnecessary usage of typedef, as they are only increasing the
cognitive load of the code for no purpose.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>

* Improve usage of inline and static in harness

Functions declared in header as static can trigger unused warnings when
(indirectly) included in translation units that do not use such
functions. Use inline instead, which also avoids duplicating symbols in
binaries.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-18 18:09:46 +01:00
Pierre Moreau
6572837994
buffers: Switch from enqueueing to enqueuing (#1246)
OpenCL-Docs has 45 occurrences of “enqueuing” but a single one of
“enqueueing”.
2021-05-14 09:44:51 +01:00
Kévin Petit
e7c5694cf5
Fix image pixel reference calculation for CL_{INTENSITY,LUMINANCE} formats (#1247)
As per 6.15.15.7, the first three components have to be set to the luminance
value and all components to the intensity value.

Signed-off-by: Kévin Petit <kpet@free.fr>
2021-05-14 09:44:38 +01:00
Marco Antognini
02c2a424f7
Remove unnecessary code from unary_u_*.cpp (#1237)
Only nan() is tested by unary_u_float.cpp and unary_u_double.cpp.
Testing of half_sin, half_tan and half_cos is done in unary_float.cpp
and unary_double.cpp.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-13 09:31:13 +01:00
Grzegorz Wawiorko
db939bbb20
Fix test_buffer - undefined behavior in case of CL_MEM_USE_HOST_PTR (#1210) 2021-05-13 09:22:50 +01:00
Chetan Mistry
71e2681414
Add Test for CL_KERNEL_ATTRIBUTES (#832) (#1055)
* Improve Functionality of Harness

In the harness we previously were able to determine whether or
not a device supports the half or double data types, but doing so
required unintuitive function calls and would need to be repeated
per test.
A new pair of functions have been added which clearly state
what they do, and makes it easier to determine whether or not
a device supports the types.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* Add Test for CL_KERNEL_ATTRIBUTES (#832)

This test generates dummy kernels which have any
permutation combining the following attributes:

    * vec_type_hint
    * work_group_size_hint
    * reqd_work_group_size

It then gets the attributes by using clGetKernelInfo
and validates that the attributes returned are correct.
By matching the attributes which were used to generate
the kernel are present in the returned string from
clGetKernelInfo.
This test has been implemented as part of the
test_conformance/api suite.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Remove Signed Vector Attribute Hints

As per comments, SPIR-V does not distinguish the signedness
of an argument. This change removes the "signed" types
to ensure that the test passes in all scenarios.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Add TODO for Signed Vector Hints

As the current version only tests for unsigned
vector types (uchar/uint/etc), add a TODO in the code
as a reference to future work to introduce signed vector
tests

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>
2021-05-13 09:20:45 +01:00
Chetan Mistry
a43d96de69
Redesign clGetKernelArgInfo (#522) (#1056)
* Improve Functionality of Harness

In the harness we previously were able to determine whether or
not a device supports the half or double data types, but doing so
required unintuitive function calls and would need to be repeated
per test.
A new pair of functions have been added which clearly state
what they do, and makes it easier to determine whether or not
a device supports the types.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* Remove Old GetKernelArgInfo Tests (#522)

In the API test suite we have 2 versions which test the
clGetKernelArgInfo API. As part of this ticket we are redesigning
the implementation of this test. This change removes all of
the old code and makes it so that the tests simply pass. A later
commit will add the redesigned test

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* Redesign GetKernelArgInfo (#522)

The previous test for this API consisted of 5K+ lines
of code which would define the test kernels and the
expected outputs from this API. This redesign
instead generates the kernels and expected outputs
leading to incresased maintanability and a significantly
reduce line-of-code count.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Address Review Comments

This commit does the following:
    1) Update the Copyright to 2021
    2) Fixes a typo in a comment
    3) Explicitly declares a vector variable
       (previously auto)
    4) Output subtest result after completion rather than
       all of them at the end

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Ensure Kernel Arguments do not exceed CL_DEVICE_MAX_PARAMETER_SIZE

As per upstream comments, this change ensures that the total
size of parameters passed into a kernel does not exceed the
limit specified by CL_DEVICE_MAX_PARAMETER_SIZE for the device
used.
Additionally this change replaces ASSERT_SUCCESS() with test_error()
as per upstream requests.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Address Image and Vector Failures

This change aligns vector 3 types to be sized 4.
Additionally it ensures that image arguments do not
have the address space qualifier specified because
they are by default in the __global space.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Ensure that the size of pipe arguments are correct

As mentioned in PR comments, the test previously assumed that
sizeof(char) == sizeof(pipe char). The Clang implementation
treats a pipe to take the same size as a pointer, which
is now reflected in the code.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Ensure that CL_DEVICE_MAX_PIPE_ARGS is not Exceeded

This commit refactors the code so that Pipes are handled
separately.
Additionally, it removes signed char and char signed as
scalar types to test and removes some redundent code
for modifiying the expected type when processing unsigned
scalar types.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Remove compatibility test from skip-list

There is a list of tests which should be skipped when
using an offline compiler. As get_kernel_arg_compatibility
has been removed, it should also be removed here.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>

* [SQUASH] Disable Pipe Tests

This change disables the Pipe tests for clGetKernelArgInfo
as pipe metadata is not accurately reported on clang
which leads to the pipe tests failing.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>
2021-05-13 09:18:12 +01:00
Kévin Petit
ad8ab3fe90
Remove OpenCL C++ tests (#1241)
* Remove OpenCL C++ tests

Agreed in the 2021/05/11 teleconference.

Signed-off-by: Kevin Petit <kevin.petit@arm.com>

* fix CI
2021-05-13 09:13:03 +01:00
Pierre Moreau
d7f87492bd
testHarness: Print error string when clFinish fails (#1243) 2021-05-12 11:39:45 +01:00
Pierre Moreau
06f7661fdc
basic/async: Check for extension only once per test (#1242)
As the extension is vector size and type independent, we only need to
check for the extension once per test and not for every possible
combination of inputs, thereby drastically reducing the log output of
the test when the extension is not supported.
2021-05-12 11:39:17 +01:00
sravikumar3393
59a12047a8
Fix for test_conversions failure with Clang build on Linux #1057 (#1062)
* Avoid optimization by using volatile qualifier
    * Fix both uint2float and ulong2double
2021-05-11 18:17:48 +01:00
Marco Antognini
3dd6d4137d
Avoid manual memory management, fixes #975 (#1240)
Fix heap-buffer-overflow reported by AddressSanitizer: ensure the
appropriate number of elements are allocated for the list of tests.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-11 18:06:16 +01:00
Marco Antognini
3dab3df48d
Report inputs for worst errors (#1231)
Builtin functions producing two results can have their worst error, for
each result, on different inputs. Report both inputs.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-07 09:29:28 +01:00
Marco Antognini
5daca107ad
Remove dead variables and functions (#1238)
These were identified using Clang's -Wunused warning flag.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-05-07 09:28:38 +01:00
Marco Antognini
01497c402e
Reduce scope of variables (#1228)
Make variables local to loops, with appropriate types. These variables
are not read after the loop without being reset first, so this patch
doesn't change behaviour.

These variables should now be used for one purpose only, making it
easier to reason about the code. This will make future refactoring
easier.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-04-28 09:30:51 +01:00
Marco Antognini
cba7a8a537
Remove dead CMake code (#1230)
Remove CMake statements that have no effect in math_brute_force.

set_source_files_properties without a list of files has no effect.

When MODULE_NAME is FOO,
set_source_files_properties(${MODULE_NAME}_SOURCES ...) sets the
properties of "FOO_SOURCES", not of the files listed in the variable
named FOO_SOURCES.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-04-28 09:30:25 +01:00
Chetan Mistry
edc36b5d53
Remove NULL Platform Check for Negative clGetPlatformInfo (#1222) (#1229)
Part of the negative CTS test for clGetPlatformInfo
incorrectly tested with a NULL platform. As this is a
special case it meant that the test was not correct.
This change removes the incorrect part of the test so that
it conforms with the OpenCL specification.

Signed-off-by: Chetankumar Mistry <chetan.mistry@arm.com>
2021-04-27 15:43:39 +01:00
Marco Antognini
b8d1ea9962
Fold constant global variable (#1217)
gWimpyBufferSize is never modified and is actually not used to modify
the number of tests -- gWimpyReductionFactor is used for that purpose by
some tests, but not all.

This patch removes this unnecessary global variable to simplify the
codebase, and reduce differences between tests.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-04-21 10:45:34 +01:00
Marco Antognini
7542ae2443
Fold code into loop (#1218)
Use one loop to read buffers from device, with the last read operation
blocking until complete.

This pattern cannot be elegantly refactored just yet, mainly for two
reasons:
 - Some tests use goto statements to clean their resources.
 - Some tests (not modified in this patch) only use blocking read
   operations.

Once code is further unified, this pattern can be refactored into a
helper function.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-04-20 17:10:29 +01:00
Marco Antognini
6683fa91a9
Use lambda to reduce amount of code (#1219)
Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-04-20 17:10:06 +01:00
Marco Antognini
7286e06a94
Make variables and functions local to translation unit (#1216)
* Make variables and functions local to translation unit

Make some global variables local to function, or remove them when
actually dead.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>

* Address comments

Remove unused code.
Reduce scope of gDoubleCapabilities.

Signed-off-by: Marco Antognini <marco.antognini@arm.com>
2021-04-15 18:19:09 +01:00
592 changed files with 55216 additions and 69978 deletions

View file

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

View file

@ -3,38 +3,63 @@ on: [push, pull_request]
jobs:
build:
name: Build ${{ matrix.os }} ${{ matrix.name }}
name: Build ${{ matrix.os }} ${{ matrix.arch }}${{ matrix.extra }}
runs-on: ${{ matrix.os }}
env:
JOB_ARCHITECTURE: ${{ matrix.arch }}
JOB_ENABLE_GL: ${{ matrix.gl }}
JOB_ENABLE_DEBUG: ${{ matrix.debug }}
strategy:
fail-fast: false
matrix:
mainmatrix: [true]
os: [ubuntu-20.04, macos-11.0]
os: [ubuntu-20.04, macos-latest, windows-latest]
include:
- os: ubuntu-20.04
mainmatrix: true
gl: 1
extra: " gl"
- os: ubuntu-20.04
mainmatrix: false
name: Arm
arch: arm
- os: ubuntu-20.04
mainmatrix: false
name: AArch64
arch: aarch64
debug: 1
extra: " debug"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Ninja
uses: seanmiddleditch/gha-setup-ninja@master
- name: Setup OpenGL build dependencies
if: ${{ matrix.gl }}
run: |
sudo apt-get update
sudo apt-get -y install libglu1-mesa-dev freeglut3-dev mesa-common-dev libglew-dev
- name: Setup MSVC with Ninja
uses: ilammy/msvc-dev-cmd@v1
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
variant: sccache
key: ${{ matrix.os }}-${{ matrix.arch }}
- name: Fetch OpenCL Headers
shell: bash
run: |
git clone https://github.com/KhronosGroup/OpenCL-Headers.git
cd OpenCL-Headers
ln -s CL OpenCL # For OSX builds
cd ..
- name: Build
shell: bash
run: ./presubmit.sh
formatcheck:
name: Check code format
runs-on: ubuntu-20.04
steps:
- name: Install packages
run: sudo apt install -y clang-format
- uses: actions/checkout@v2
run: sudo apt install -y clang-format clang-format-9
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Check code format

View file

@ -10,12 +10,6 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_BUILD_TYPE STREQUAL "release")
set (BUILD_FLAVOR "release")
else(CMAKE_BUILD_TYPE STREQUAL "release")
set (BUILD_FLAVOR "debug")
endif(CMAKE_BUILD_TYPE STREQUAL "release")
add_definitions(-DCL_TARGET_OPENCL_VERSION=300)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_2_2_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_2_1_APIS=1)
@ -29,14 +23,6 @@ if(USE_CL_EXPERIMENTAL)
add_definitions(-DCL_EXPERIMENTAL)
endif(USE_CL_EXPERIMENTAL)
# Support both VS2008 and VS2012.
set(BUILD_DIR "$ENV{ADRENO_DRIVER}/build")
if(MSVC90)
set(VS_BUILD_DIR "${BUILD_DIR}/vs2008")
else(MSVC110)
set(VS_BUILD_DIR "${BUILD_DIR}/vs2012")
endif(MSVC90)
#-----------------------------------------------------------
# Default Configurable Test Set
#-----------------------------------------------------------
@ -44,6 +30,7 @@ option(D3D10_IS_SUPPORTED "Run DirectX 10 interop tests" OFF)
option(D3D11_IS_SUPPORTED "Run DirectX 11 interop tests" OFF)
option(GL_IS_SUPPORTED "Run OpenGL interop tests" OFF)
option(GLES_IS_SUPPORTED "Run OpenGL ES interop tests" OFF)
option(VULKAN_IS_SUPPORTED "Run Vulkan interop tests" OFF)
#-----------------------------------------------------------
@ -62,58 +49,13 @@ set(CONFORMANCE_SUFFIX "" )
#build driver as a dependency of the conformance tests, or other such CMake customization
include(CMakeVendor.txt OPTIONAL)
#-----------------------------------------------------------
# Development options for OpenCL C++ tests
#-----------------------------------------------------------
# Use OpenCL C kernels instead of OpenCL C++ kernels
option(CLPP_DEVELOPMENT_USE_OPENCLC_KERNELS "Use OpenCL C kernels in OpenCL C++ tests" OFF)
if(CLPP_DEVELOPMENT_USE_OPENCLC_KERNELS)
set(CLPP_DEVELOPMENT_OPTIONS ${CLPP_DEVELOPMENT_OPTIONS} -DCLPP_DEVELOPMENT_USE_OPENCLC_KERNELS)
endif(CLPP_DEVELOPMENT_USE_OPENCLC_KERNELS)
# Only check if OpenCL C++ kernels compile to SPIR-V
option(CLPP_DEVELOPMENT_ONLY_SPIRV_COMPILATION "Only check if OpenCL C++ kernels compile to SPIR-V" OFF)
if(CLPP_DEVELOPMENT_ONLY_SPIRV_COMPILATION)
if(CLPP_DEVELOPMENT_USE_OPENCLC_KERNELS)
message(FATAL_ERROR "Can't use OpenCL C kernels and compile to SPIR-V.")
endif(CLPP_DEVELOPMENT_USE_OPENCLC_KERNELS)
set(CLPP_DEVELOPMENT_OPTIONS ${CLPP_DEVELOPMENT_OPTIONS} -DCLPP_DEVELOPMENT_ONLY_SPIRV_COMPILATION)
endif(CLPP_DEVELOPMENT_ONLY_SPIRV_COMPILATION)
#
if(CLPP_DEVELOPMENT_OPTIONS)
add_definitions(-DCLPP_DEVELOPMENT_OPTIONS)
add_definitions(${CLPP_DEVELOPMENT_OPTIONS})
endif(CLPP_DEVELOPMENT_OPTIONS)
# Offline OpenCL C/C++ compiler provided by Khronos is the only supported
# offline compiler.
#
# Path to offline OpenCL C/C++ compiler provided by Khronos.
# See https://github.com/KhronosGroup/SPIR/ (spirv-1.1 branch or newer SPIR-V-ready
# branch should be used).
if(KHRONOS_OFFLINE_COMPILER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKHRONOS_OFFLINE_COMPILER=${KHRONOS_OFFLINE_COMPILER}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKHRONOS_OFFLINE_COMPILER=${KHRONOS_OFFLINE_COMPILER}")
# Additional OpenCL C/C++ compiler option.
if(KHRONOS_OFFLINE_COMPILER_OPTIONS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKHRONOS_OFFLINE_COMPILER_OPTIONS=${KHRONOS_OFFLINE_COMPILER_OPTIONS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKHRONOS_OFFLINE_COMPILER_OPTIONS=${KHRONOS_OFFLINE_COMPILER_OPTIONS}")
endif(KHRONOS_OFFLINE_COMPILER_OPTIONS)
else(KHRONOS_OFFLINE_COMPILER)
message(WARNING "KHRONOS_OFFLINE_COMPILER is not defined!")
message(WARNING "Running CL C++ tests will not be possible.")
endif(KHRONOS_OFFLINE_COMPILER)
# CL_LIBCLCXX_DIR - path to dir with OpenCL C++ STL (libclcxx)
# CL_INCLUDE_DIR - path to dir with OpenCL headers
# CL_LIBCLCXX_DIR - path to dir with OpenCL library
if(CL_INCLUDE_DIR AND CL_LIB_DIR AND CL_LIBCLCXX_DIR)
if(CL_INCLUDE_DIR AND CL_LIB_DIR)
link_directories(${CL_LIB_DIR})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCL_LIBCLCXX_DIR=${CL_LIBCLCXX_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCL_LIBCLCXX_DIR=${CL_LIBCLCXX_DIR}")
else(CL_INCLUDE_DIR AND CL_LIB_DIR AND CL_LIBCLCXX_DIR)
else(CL_INCLUDE_DIR AND CL_LIB_DIR)
message(STATUS "OpenCL hasn't been found!")
message(FATAL_ERROR "Either install OpenCL or pass -DCL_INCLUDE_DIR, -DCL_LIB_DIR and -DCL_LIBCLCXX_DIR")
endif(CL_INCLUDE_DIR AND CL_LIB_DIR AND CL_LIBCLCXX_DIR)
message(FATAL_ERROR "Either install OpenCL or pass -DCL_INCLUDE_DIR and -DCL_LIB_DIR")
endif(CL_INCLUDE_DIR AND CL_LIB_DIR)
# CLConform_GL_LIBRARIES_DIR - path to OpenGL libraries
if(GL_IS_SUPPORTED AND CLConform_GL_LIBRARIES_DIR)
@ -140,21 +82,37 @@ endif()
macro(add_cxx_flag_if_supported flag)
string(REGEX REPLACE "[-=+]" "" FLAG_NO_SIGNS ${flag})
check_cxx_compiler_flag(${flag} COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
set(FLAG_TO_TEST ${flag})
if((${flag} MATCHES "^-Wno-") AND NOT (${flag} MATCHES "^-Wno-error="))
# -Wno-... only causes a diagnostic if another diagnostic is emitted.
# Change such flags into a -W... flag to test if the warning is known.
string(REGEX REPLACE "^-Wno-" "-W" FLAG_TO_TEST ${flag})
endif()
check_cxx_compiler_flag(${FLAG_TO_TEST} COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
if(COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
endif()
endmacro(add_cxx_flag_if_supported)
if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang")
add_cxx_flag_if_supported(-Wmisleading-indentation)
add_cxx_flag_if_supported(-Wunused-function)
add_cxx_flag_if_supported(-Wunused-variable)
add_cxx_flag_if_supported(-Werror)
if(NOT CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo|MinSizeRel")
# Enable more warnings if not doing a release build.
add_cxx_flag_if_supported(-Wall)
# Suppress warnings that currently trigger on the code base.
# This list should shrink over time when warnings are fixed.
add_cxx_flag_if_supported(-Wno-unused-but-set-variable)
add_cxx_flag_if_supported(-Wno-sometimes-uninitialized)
add_cxx_flag_if_supported(-Wno-sign-compare)
endif()
add_cxx_flag_if_supported(-Wno-narrowing)
add_cxx_flag_if_supported(-Wno-format)
add_cxx_flag_if_supported(-Werror)
add_cxx_flag_if_supported(-Wno-error=cpp) # Allow #warning directive
add_cxx_flag_if_supported(-Wno-error=absolute-value) # Issue 783
add_cxx_flag_if_supported(-Wno-error=unknown-pragmas) # Issue #785
add_cxx_flag_if_supported(-Wno-unknown-pragmas) # Issue #785
add_cxx_flag_if_supported(-Wno-error=asm-operand-widths) # Issue #784
add_cxx_flag_if_supported(-Wno-error=overflow) # Fixed by #699
# -msse -mfpmath=sse to force gcc to use sse for float math,
# avoiding excess precision problems that cause tests like int2float
@ -172,9 +130,30 @@ else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D__SSE__")
endif()
# Set a module's COMPILE_FLAGS if using gcc or clang.
macro(set_gnulike_module_compile_flags flags)
if(CMAKE_COMPILER_IS_GNUCC OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?Clang")
SET_SOURCE_FILES_PROPERTIES(
${${MODULE_NAME}_SOURCES}
PROPERTIES
COMPILE_FLAGS ${flags}
)
endif()
endmacro(set_gnulike_module_compile_flags)
# Xcode 14.1 deprecated functions such as sprintf.
# Suppress such warnings for now, see Issue #1626
if(APPLE)
add_cxx_flag_if_supported(-Wno-deprecated-declarations)
endif(APPLE)
if(MSVC)
# Don't warn when using standard non-secure functions.
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
# Don't warn about using the portable "strdup" function.
add_compile_definitions(_CRT_NONSTDC_NO_DEPRECATE)
# Fix std::min and std::max handling with windows.harness.
add_compile_definitions(NOMINMAX)
endif()
if( WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" )
@ -197,10 +176,6 @@ if(LINK_PTHREAD)
list(APPEND CLConform_LIBRARIES pthread)
endif()
if(DEFINED USE_GLES3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGLES3")
endif()
if(APPLE)
find_library(corefoundation CoreFoundation)
find_library(iokit IOKit)
@ -214,38 +189,5 @@ include_directories(${CLConform_SOURCE_DIR}/test_common/harness
${CLConform_SOURCE_DIR}/test_common/gl
${CLConform_SOURCE_DIR}/test_common)
if(CMAKE_BUILD_TYPE STREQUAL "release")
set (BUILD_FLAVOR "release")
elseif (CMAKE_BUILD_TYPE STREQUAL "debug")
set (BUILD_FLAVOR "debug")
endif(CMAKE_BUILD_TYPE STREQUAL "release")
add_subdirectory(test_common)
add_subdirectory(test_conformance)
# Support both VS2008 and VS2012.
set (DLL_FILES "${VS_BUILD_DIR}/Debug/*.dll")
set (DST_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/")
if (WIN32)
set (COPY "echo")
add_custom_target(COPY_DLL${CONFORMANCE_SUFFIX} ALL
COMMAND ${COPY} "${DLL_FILES}" "${DST_DIR}"
COMMENT "Copying dll files.. ")
else (WIN32)
set (COPY cp)
add_custom_target(COPY_DLL${CONFORMANCE_SUFFIX})
endif(WIN32)
set_property(TARGET COPY_DLL${CONFORMANCE_SUFFIX} PROPERTY FOLDER "CONFORMANCE${CONFORMANCE_SUFFIX}")
if(WIN32)
add_custom_target( COPY_FILES${CONFORMANCE_SUFFIX} ALL
COMMAND ${COPY} ${DLL_FILES} ${DST_DIR}
COMMENT "Copying other files to output folder..." )
else(WIN32)
add_custom_target( COPY_FILES${CONFORMANCE_SUFFIX} )
endif(WIN32)
set_property(TARGET COPY_FILES${CONFORMANCE_SUFFIX} PROPERTY FOLDER "CONFORMANCE${CONFORMANCE_SUFFIX}")

117
README.md
View file

@ -1,2 +1,115 @@
# OpenCL-CTS [![Build Status](https://api.travis-ci.org/KhronosGroup/OpenCL-CTS.svg?branch=master)](https://travis-ci.org/KhronosGroup/OpenCL-CTS/branches)
The OpenCL Conformance Tests
# OpenCL Conformance Test Suite (CTS)
This it the OpenCL CTS for all versions of the Khronos
[OpenCL](https://www.khronos.org/opencl/) standard.
## Building the CTS
The CTS supports Linux, Windows, macOS, and Android platforms. In particular,
GitHub Actions CI builds against Ubuntu 20.04, Windows-latest, and
macos-latest.
Compiling the CTS requires the following CMake configuration options to be set:
* `CL_INCLUDE_DIR` Points to the unified
[OpenCL-Headers](https://github.com/KhronosGroup/OpenCL-Headers).
* `CL_LIB_DIR` Directory containing the OpenCL library to build against.
* `OPENCL_LIBRARIES` Name of the OpenCL library to link.
It is advised that the [OpenCL ICD-Loader](https://github.com/KhronosGroup/OpenCL-ICD-Loader)
is used as the OpenCL library to build against. Where `CL_LIB_DIR` points to a
build of the ICD loader and `OPENCL_LIBRARIES` is "OpenCL".
### Example Build
Steps on a Linux platform to clone dependencies from GitHub sources, configure
a build, and compile.
```sh
git clone https://github.com/KhronosGroup/OpenCL-CTS.git
git clone https://github.com/KhronosGroup/OpenCL-Headers.git
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
mkdir OpenCL-ICD-Loader/build
cmake -S OpenCL-ICD-Loader -B OpenCL-ICD-Loader/build \
-DOPENCL_ICD_LOADER_HEADERS_DIR=$PWD/OpenCL-Headers
cmake --build ./OpenCL-ICD-Loader/build --config Release
mkdir OpenCL-CTS/build
cmake -S OpenCL-CTS -B OpenCL-CTS/build \
-DCL_INCLUDE_DIR=$PWD/OpenCL-Headers \
-DCL_LIB_DIR=$PWD/OpenCL-ICD-Loader/build \
-DOPENCL_LIBRARIES=OpenCL
cmake --build OpenCL-CTS/build --config Release
```
## Running the CTS
A build of the CTS contains multiple executables representing the directories in
the `test_conformance` folder. Each of these executables contains sub-tests, and
possibly smaller granularities of testing within the sub-tests.
See the `--help` output on each executable for the list of sub-tests available,
as well as other options for configuring execution.
If the OpenCL library built against is the ICD Loader, and the vendor library to
be tested is not registered in the
[default ICD Loader location](https://github.com/KhronosGroup/OpenCL-ICD-Loader#registering-icds)
then the [OCL_ICD_FILENAMES](https://github.com/KhronosGroup/OpenCL-ICD-Loader#table-of-debug-environment-variables)
environment variable will need to be set for the ICD Loader to detect the OpenCL
library to use at runtime. For example, to run the basic tests on a Linux
platform:
```sh
OCL_ICD_FILENAMES=/path/to/vendor_lib.so ./test_basic
```
### Offline Compilation
Testing OpenCL drivers which do not have a runtime compiler can be done by using
additional command line arguments provided by the test harness for tests which
require compilation, these are:
* `--compilation-mode` Selects if OpenCL-C source code should be compiled using
an external tool before being passed on to the OpenCL driver in that form for
testing. Online is the default mode, but also accepts the values `spir-v`, and
`binary`.
* `--compilation-cache-mode` Controls how the compiled OpenCL-C source code
should be cached on disk.
* `--compilation-cache-path` Accepts a path to a directory where the compiled
binary cache should be stored on disk.
* `--compilation-program` Accepts a path to an executable (default:
cl_offline_compiler) invoked by the test harness to perform offline
compilation of OpenCL-C source code. This executable must match the
[interface description](test_common/harness/cl_offline_compiler-interface.txt).
## Generating a Conformance Report
The Khronos [Conformance Process Document](https://members.khronos.org/document/dl/911)
details the steps required for a conformance submissions.
In this repository [opencl_conformance_tests_full.csv](test_conformance/submission_details_template.txt)
defines the full list of tests which must be run for conformance. The output log
of which must be included alongside a filled in
[submission details template](test_conformance/submission_details_template.txt).
Utility script [run_conformance.py](test_conformance/run_conformance.py) can be
used to help generating the submission log, although it is not required.
Git [tags](https://github.com/KhronosGroup/OpenCL-CTS/tags) are used to define
the version of the repository conformance submissions are made against.
## Contributing
Contributions are welcome to the project from Khronos members and non-members
alike via GitHub Pull Requests (PR). Alternatively, if you've found a bug or have
a questions please file an issue in the GitHub project. First time contributors
will be required to sign the Khronos Contributor License Agreement (CLA) before
their PR can be merged.
PRs to the repository are required to be `clang-format` clean to pass CI.
Developers can either use the `git-clang-format` tool locally to verify this
before contributing, or update their PR based on the diff provided by a failing
CI job.

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Arg used to specify non-'origin/master' comparison branch
ORIGIN_BRANCH=${1:-"origin/master"}
# Arg used to specify non-'origin/main' comparison branch
ORIGIN_BRANCH=${1:-"origin/main"}
CLANG_BINARY=${2:-"`which clang-format-9`"}
# Run git-clang-format to check for violations

View file

@ -13,9 +13,13 @@ TOOLCHAIN_PREFIX_aarch64=aarch64-linux-gnu
TOOLCHAIN_FILE=${TOP}/toolchain.cmake
touch ${TOOLCHAIN_FILE}
BUILD_OPENGL_TEST="OFF"
BUILD_VULKAN_TEST="ON"
cmake --version
echo
# Prepare toolchain if needed
if [[ ${JOB_ARCHITECTURE} != "" ]]; then
if [[ ${JOB_ARCHITECTURE} != "" && ${RUNNER_OS} != "Windows" ]]; then
TOOLCHAIN_URL_VAR=TOOLCHAIN_URL_${JOB_ARCHITECTURE}
TOOLCHAIN_URL=${!TOOLCHAIN_URL_VAR}
wget ${TOOLCHAIN_URL}
@ -38,39 +42,68 @@ fi
if [[ ( ${JOB_ARCHITECTURE} == "" && ${JOB_ENABLE_GL} == "1" ) ]]; then
BUILD_OPENGL_TEST="ON"
sudo apt-get update
sudo apt-get -y install libglu1-mesa-dev freeglut3-dev mesa-common-dev libglew-dev
fi
# Prepare headers
git clone https://github.com/KhronosGroup/OpenCL-Headers.git
cd OpenCL-Headers
ln -s CL OpenCL # For OSX builds
cd ..
if [[ ${JOB_ENABLE_DEBUG} == 1 ]]; then
BUILD_CONFIG="Debug"
else
BUILD_CONFIG="Release"
fi
#Vulkan Headers
git clone https://github.com/KhronosGroup/Vulkan-Headers.git
# Get and build loader
git clone https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
cd ${TOP}/OpenCL-ICD-Loader
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DOPENCL_ICD_LOADER_HEADERS_DIR=${TOP}/OpenCL-Headers/ ..
make
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DOPENCL_ICD_LOADER_HEADERS_DIR=${TOP}/OpenCL-Headers/
cmake --build . -j2
# Get libclcxx
#Vulkan Loader
cd ${TOP}
git clone https://github.com/KhronosGroup/libclcxx.git
git clone https://github.com/KhronosGroup/Vulkan-Loader.git
cd Vulkan-Loader
mkdir build
cd build
python3 ../scripts/update_deps.py
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DBUILD_WSI_XLIB_SUPPORT=OFF \
-DBUILD_WSI_XCB_SUPPORT=OFF \
-DBUILD_WSI_WAYLAND_SUPPORT=OFF \
-DUSE_GAS=OFF \
-C helper.cmake ..
cmake --build . -j2
# Build CTS
cd ${TOP}
ls -l
mkdir build
cd build
cmake -DCL_INCLUDE_DIR=${TOP}/OpenCL-Headers \
if [[ ${RUNNER_OS} == "Windows" ]]; then
CMAKE_OPENCL_LIBRARIES_OPTION="OpenCL"
CMAKE_CACHE_OPTIONS=""
else
CMAKE_OPENCL_LIBRARIES_OPTION="-lOpenCL -lpthread"
CMAKE_CACHE_OPTIONS="-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache"
fi
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE="${BUILD_CONFIG}" \
${CMAKE_CACHE_OPTIONS} \
-DCL_INCLUDE_DIR=${TOP}/OpenCL-Headers \
-DCL_LIB_DIR=${TOP}/OpenCL-ICD-Loader/build \
-DCL_LIBCLCXX_DIR=${TOP}/libclcxx \
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=./bin \
-DOPENCL_LIBRARIES="-lOpenCL -lpthread" \
-DOPENCL_LIBRARIES="${CMAKE_OPENCL_LIBRARIES_OPTION}" \
-DUSE_CL_EXPERIMENTAL=ON \
-DGL_IS_SUPPORTED=${BUILD_OPENGL_TEST} \
..
make -j2
-DVULKAN_IS_SUPPORTED=${BUILD_VULKAN_TEST} \
-DVULKAN_INCLUDE_DIR=${TOP}/Vulkan-Headers/include/ \
-DVULKAN_LIB_DIR=${TOP}/Vulkan-Loader/build/loader/
cmake --build . -j3

View file

@ -1,6 +1,5 @@
set(HARNESS_SOURCES
harness/threadTesting.cpp
harness/typeWrappers.cpp
harness/mt19937.cpp
harness/conversions.cpp
@ -22,4 +21,3 @@ set(HARNESS_SOURCES
)
add_library(harness STATIC ${HARNESS_SOURCES})

View file

@ -49,9 +49,11 @@ namespace detail {
struct test_case_registration
{
test_case_registration(const std::string& name, const basefn ptr)
test_case_registration(const std::string& name,
const test_function_pointer ptr)
{
::autotest::test_suite::global_test_suite().add(test_definition({ptr, strdup(name.c_str())}));
::autotest::test_suite::global_test_suite().add(
test_definition({ ptr, strdup(name.c_str()) }));
}
};

View file

@ -1381,7 +1381,6 @@ void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
//calculating colors
double color_delta = 1.0 / (total_layers * samples);
double color = color_delta;
if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
glDisable(GL_DEPTH_TEST);

View file

@ -34,7 +34,6 @@
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/threadTesting.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
#include "harness/mt19937.h"

View file

@ -13,14 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#define GL_GLEXT_PROTOTYPES
#include "setup.h"
#include "testBase.h"
#include "harness/errorHelpers.h"
#include <GL/gl.h>
#include <GL/glut.h>
#include <CL/cl_ext.h>
typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)(

View file

@ -13,16 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#define GL_GLEXT_PROTOTYPES
#include "setup.h"
#include "testBase.h"
#include "harness/errorHelpers.h"
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include <GL/freeglut.h>
#include <GL/glx.h>
#include <CL/cl_ext.h>
@ -90,10 +85,17 @@ public:
}
for (int i=0; i<(int)num_of_devices; i++) {
if (!is_extension_available(devices[i], "cl_khr_gl_sharing ")) {
log_info("Device %d of %d does not support required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
} else {
log_info("Device %d of %d supports required extension cl_khr_gl_sharing.\n", i+1, num_of_devices);
if (!is_extension_available(devices[i], "cl_khr_gl_sharing"))
{
log_info("Device %d of %d does not support required extension "
"cl_khr_gl_sharing.\n",
i + 1, num_of_devices);
}
else
{
log_info("Device %d of %d supports required extension "
"cl_khr_gl_sharing.\n",
i + 1, num_of_devices);
found_valid_device = 1;
m_devices[m_device_count++] = devices[i];
}

View file

@ -22,7 +22,7 @@
{GLint __error = glGetError(); if(__error) {log_error( "GL ERROR: %s!\n", gluErrorString( err ));}}
#if defined(__linux__) || defined(GL_ES_VERSION_2_0)
// On linux we dont link to GLU library to avoid comaptibility issues with
// On linux we don't link to GLU library to avoid compatibility issues with
// libstdc++
// FIXME: Implement this
const GLubyte* gluErrorString (GLenum error)
@ -271,8 +271,6 @@ void * ReadGLTexture( GLenum glTarget, GLuint glTexture,
// Read results from the GL texture
glBindTexture(get_base_gl_target(glTarget), glTexture);
GLint realWidth, realHeight;
GLint realInternalFormat;
GLenum readBackFormat = GL_RGBA;
GLenum readBackType = glType;
glFramebufferWrapper glFramebuffer;
@ -301,7 +299,7 @@ void * ReadGLTexture( GLenum glTarget, GLuint glTexture,
GetGLFormatName(readBackFormat),
GetGLTypeName(readBackType));
DumpGLBuffer(readBackType, realWidth, realHeight, (void*)outBuffer);
DumpGLBuffer(readBackType, outWidth, outHeight, (void *)outBuffer);
#endif

View file

@ -30,15 +30,13 @@
#if !defined (__APPLE__)
#include <CL/cl.h>
#include "gl_headers.h"
#include <CL/cl_gl.h>
#else
#include "gl_headers.h"
#include <CL/cl_half.h>
#endif
#include "gl_headers.h"
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/threadTesting.h"
#include "harness/typeWrappers.h"
#include "harness/conversions.h"
#include "harness/mt19937.h"

View file

@ -22,6 +22,9 @@
#if defined(__APPLE__) || defined(__linux__) || defined(_WIN32)
// or any other POSIX system
#include <atomic>
#include <vector>
#if defined(_WIN32)
#include <windows.h>
#if defined(_MSC_VER)
@ -56,6 +59,12 @@ CRITICAL_SECTION gAtomicLock;
pthread_mutex_t gAtomicLock;
#endif
#if !defined(_WIN32)
// Keep track of pthread_t's created in ThreadPool_Init() so they can be joined
// in ThreadPool_Exit() and avoid thread leaks.
static std::vector<pthread_t> pthreads;
#endif
// Atomic add operator with mem barrier. Mem barrier needed to protect state
// modified by the worker functions.
cl_int ThreadPool_AtomicAdd(volatile cl_int *a, cl_int b)
@ -241,7 +250,7 @@ pthread_cond_t cond_var;
// Condition variable state. How many iterations on the function left to run,
// set to CL_INT_MAX to cause worker threads to exit. Note: this value might
// go negative.
volatile cl_int gRunCount = 0;
std::atomic<cl_int> gRunCount{ 0 };
// State that only changes when the threadpool is not working.
volatile TPFuncPtr gFunc_ptr = NULL;
@ -261,19 +270,20 @@ pthread_cond_t caller_cond_var;
// # of threads intended to be running. Running threads will decrement this
// as they discover they've run out of work to do.
volatile cl_int gRunning = 0;
std::atomic<cl_int> gRunning{ 0 };
// The total number of threads launched.
volatile cl_int gThreadCount = 0;
std::atomic<cl_int> gThreadCount{ 0 };
#ifdef _WIN32
void ThreadPool_WorkerFunc(void *p)
#else
void *ThreadPool_WorkerFunc(void *p)
#endif
{
cl_uint threadID = ThreadPool_AtomicAdd((volatile cl_int *)p, 1);
cl_int item = ThreadPool_AtomicAdd(&gRunCount, -1);
// log_info( "ThreadPool_WorkerFunc start: gRunning = %d\n", gRunning );
auto &tid = *static_cast<std::atomic<cl_uint> *>(p);
cl_uint threadID = tid++;
cl_int item = gRunCount--;
while (MAX_COUNT > item)
{
@ -282,8 +292,6 @@ void *ThreadPool_WorkerFunc(void *p)
// check for more work to do
if (0 >= item)
{
// log_info("Thread %d has run out of work.\n", threadID);
// No work to do. Attempt to block waiting for work
#if defined(_WIN32)
EnterCriticalSection(cond_lock);
@ -298,9 +306,7 @@ void *ThreadPool_WorkerFunc(void *p)
}
#endif // !_WIN32
cl_int remaining = ThreadPool_AtomicAdd(&gRunning, -1);
// log_info("ThreadPool_WorkerFunc: gRunning = %d\n",
// remaining - 1);
cl_int remaining = gRunning--;
if (1 == remaining)
{ // last thread out signal the main thread to wake up
#if defined(_WIN32)
@ -350,7 +356,7 @@ void *ThreadPool_WorkerFunc(void *p)
#endif // !_WIN32
// try again to get a valid item id
item = ThreadPool_AtomicAdd(&gRunCount, -1);
item = gRunCount--;
if (MAX_COUNT <= item) // exit if we are done
{
#if defined(_WIN32)
@ -362,8 +368,7 @@ void *ThreadPool_WorkerFunc(void *p)
}
}
ThreadPool_AtomicAdd(&gRunning, 1);
// log_info("Thread %d has found work.\n", threadID);
gRunning++;
#if defined(_WIN32)
LeaveCriticalSection(cond_lock);
@ -447,12 +452,12 @@ void *ThreadPool_WorkerFunc(void *p)
}
// get the next item
item = ThreadPool_AtomicAdd(&gRunCount, -1);
item = gRunCount--;
}
exit:
log_info("ThreadPool: thread %d exiting.\n", threadID);
ThreadPool_AtomicAdd(&gThreadCount, -1);
gThreadCount--;
#if !defined(_WIN32)
return NULL;
#endif
@ -487,7 +492,7 @@ void ThreadPool_Init(void)
{
cl_int i;
int err;
volatile cl_uint threadID = 0;
std::atomic<cl_uint> threadID{ 0 };
// Check for manual override of multithreading code. We add this for better
// debuggability.
@ -523,7 +528,7 @@ void ThreadPool_Init(void)
{
// Count the number of bits in ProcessorMask (number of
// logical cores)
ULONG mask = ptr->ProcessorMask;
ULONG_PTR mask = ptr->ProcessorMask;
while (mask)
{
++gThreadCount;
@ -624,7 +629,7 @@ void ThreadPool_Init(void)
}
#endif // !_WIN32
gRunning = gThreadCount;
gRunning = gThreadCount.load();
// init threads
for (i = 0; i < gThreadCount; i++)
{
@ -644,6 +649,9 @@ void ThreadPool_Init(void)
gThreadCount = i;
break;
}
#if !defined(_WIN32)
pthreads.push_back(tid);
#endif // !_WIN32
}
atexit(ThreadPool_Exit);
@ -688,7 +696,6 @@ static BOOL CALLBACK _ThreadPool_Init(_PINIT_ONCE InitOnce, PVOID Parameter,
void ThreadPool_Exit(void)
{
int err, count;
gRunCount = CL_INT_MAX;
#if defined(__GNUC__)
@ -702,13 +709,13 @@ void ThreadPool_Exit(void)
#endif
// spin waiting for threads to die
for (count = 0; 0 != gThreadCount && count < 1000; count++)
for (int count = 0; 0 != gThreadCount && count < 1000; count++)
{
#if defined(_WIN32)
_WakeAllConditionVariable(cond_var);
Sleep(1);
#else // !_WIN32
if ((err = pthread_cond_broadcast(&cond_var)))
if (int err = pthread_cond_broadcast(&cond_var))
{
log_error("Error %d from pthread_cond_broadcast. Unable to wake up "
"work threads. ThreadPool_Exit failed.\n",
@ -722,9 +729,22 @@ void ThreadPool_Exit(void)
if (gThreadCount)
log_error("Error: Thread pool timed out after 1 second with %d threads "
"still active.\n",
gThreadCount);
gThreadCount.load());
else
{
#if !defined(_WIN32)
for (pthread_t pthread : pthreads)
{
if (int err = pthread_join(pthread, nullptr))
{
log_error("Error from %d from pthread_join. Unable to join "
"work threads. ThreadPool_Exit failed.\n",
err);
}
}
#endif
log_info("Thread pool exited in a orderly fashion.\n");
}
}
@ -738,7 +758,9 @@ void ThreadPool_Exit(void)
// all available then it would make more sense to use those features.
cl_int ThreadPool_Do(TPFuncPtr func_ptr, cl_uint count, void *userInfo)
{
#ifndef _WIN32
cl_int newErr;
#endif
cl_int err = 0;
// Lazily set up our threads
#if defined(_MSC_VER) && (_WIN32_WINNT >= 0x600)
@ -913,7 +935,9 @@ cl_int ThreadPool_Do(TPFuncPtr func_ptr, cl_uint count, void *userInfo)
err = jobError;
#ifndef _WIN32
exit:
#endif
// exit critical region
#if defined(_WIN32)
LeaveCriticalSection(gThreadPoolLock);

View file

@ -29,7 +29,7 @@
#include "mingw_compat.h"
#endif
static void* align_malloc(size_t size, size_t alignment)
inline void* align_malloc(size_t size, size_t alignment)
{
#if defined(_WIN32) && defined(_MSC_VER)
return _aligned_malloc(size, alignment);
@ -53,7 +53,7 @@ static void* align_malloc(size_t size, size_t alignment)
#endif
}
static void align_free(void* ptr)
inline void align_free(void* ptr)
{
#if defined(_WIN32) && defined(_MSC_VER)
_aligned_free(ptr);

View file

@ -18,13 +18,13 @@
#if defined(_WIN32) && defined(_MSC_VER)
#include <Windows.h>
#endif
#else
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif
#endif
//
@ -309,13 +309,6 @@ EXTERN_C int __builtin_clz(unsigned int pattern);
#endif
#ifndef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
/*-----------------------------------------------------------------------------
WARNING: DO NOT USE THESE MACROS:

View file

@ -14,6 +14,7 @@
// limitations under the License.
//
#include "conversions.h"
#include <cinttypes>
#include <limits.h>
#include <time.h>
#include <assert.h>
@ -50,10 +51,10 @@ void print_type_to_string(ExplicitType type, void *data, char *string)
case kInt: sprintf(string, "%d", *((cl_int *)data)); return;
case kUInt:
case kUnsignedInt: sprintf(string, "%u", *((cl_uint *)data)); return;
case kLong: sprintf(string, "%lld", *((cl_long *)data)); return;
case kLong: sprintf(string, "%" PRId64 "", *((cl_long *)data)); return;
case kULong:
case kUnsignedLong:
sprintf(string, "%llu", *((cl_ulong *)data));
sprintf(string, "%" PRIu64 "", *((cl_ulong *)data));
return;
case kFloat: sprintf(string, "%f", *((cl_float *)data)); return;
case kHalf: sprintf(string, "half"); return;
@ -181,8 +182,8 @@ static ULong sUpperLimits[kNumExplicitTypes] = {
0xffffffffLL,
0xffffffffLL,
0x7fffffffffffffffLL,
0xffffffffffffffffLL,
0xffffffffffffffffLL,
0xffffffffffffffffULL,
0xffffffffffffffffULL,
0,
0
}; // Last two values aren't stored here

View file

@ -63,6 +63,40 @@ int is_extension_available(cl_device_id device, const char *extensionName)
return false;
}
cl_version get_extension_version(cl_device_id device, const char *extensionName)
{
cl_int err;
size_t size;
err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION, 0, nullptr,
&size);
if (err != CL_SUCCESS)
{
throw std::runtime_error("clGetDeviceInfo(CL_DEVICE_EXTENSIONS_WITH_"
"VERSION) failed to return size\n");
}
std::vector<cl_name_version> extensions(size / sizeof(cl_name_version));
err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION, size,
extensions.data(), &size);
if (err != CL_SUCCESS)
{
throw std::runtime_error("clGetDeviceInfo(CL_DEVICE_EXTENSIONS_WITH_"
"VERSION) failed to return value\n");
}
for (auto &ext : extensions)
{
if (!strcmp(extensionName, ext.name))
{
return ext.version;
}
}
throw std::runtime_error("Extension " + std::string(extensionName)
+ " not supported by device!");
}
/* Returns a string containing the supported extensions list for a device. */
std::string get_device_extensions_string(cl_device_id device)
{
@ -86,3 +120,15 @@ std::string get_device_name(cl_device_id device)
{
return get_device_info_string(device, CL_DEVICE_NAME);
}
size_t get_max_param_size(cl_device_id device)
{
size_t ret(0);
if (clGetDeviceInfo(device, CL_DEVICE_MAX_PARAMETER_SIZE, sizeof(ret), &ret,
nullptr)
!= CL_SUCCESS)
{
throw std::runtime_error("clGetDeviceInfo failed\n");
}
return ret;
}

View file

@ -31,6 +31,11 @@ std::string get_device_info_string(cl_device_id device,
/* Determines if an extension is supported by a device. */
int is_extension_available(cl_device_id device, const char *extensionName);
/* Returns the version of the extension the device supports or throws an
* exception if the extension is not supported by the device. */
cl_version get_extension_version(cl_device_id device,
const char *extensionName);
/* Returns a string containing the supported extensions list for a device. */
std::string get_device_extensions_string(cl_device_id device);
@ -42,4 +47,8 @@ std::string get_device_version_string(cl_device_id device);
/* Returns a string containing the device name. */
std::string get_device_name(cl_device_id device);
// Returns the maximum size in bytes for Kernel Parameters
size_t get_max_param_size(cl_device_id device);
#endif // _deviceInfo_h

View file

@ -18,9 +18,12 @@
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include "errorHelpers.h"
#include "parseParameters.h"
#include "testHarness.h"
#include <CL/cl_half.h>
@ -300,10 +303,6 @@ const char *GetQueuePropertyName(cl_command_queue_properties property)
}
}
#ifndef MAX
#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#endif
#if defined(_MSC_VER)
#define scalbnf(_a, _i) ldexpf(_a, _i)
#define scalbn(_a, _i) ldexp(_a, _i)
@ -356,7 +355,7 @@ static float Ulp_Error_Half_Float(float test, double reference)
// The unbiased exponent of the ulp unit place
int ulp_exp =
HALF_MANT_DIG - 1 - MAX(ilogb(reference), HALF_MIN_EXP - 1);
HALF_MANT_DIG - 1 - std::max(ilogb(reference), HALF_MIN_EXP - 1);
// Scale the exponent of the error
return (float)scalbn(testVal - reference, ulp_exp);
@ -364,7 +363,7 @@ static float Ulp_Error_Half_Float(float test, double reference)
// reference is a normal power of two or a zero
int ulp_exp =
HALF_MANT_DIG - 1 - MAX(ilogb(reference) - 1, HALF_MIN_EXP - 1);
HALF_MANT_DIG - 1 - std::max(ilogb(reference) - 1, HALF_MIN_EXP - 1);
// Scale the exponent of the error
return (float)scalbn(testVal - reference, ulp_exp);
@ -436,7 +435,8 @@ float Ulp_Error(float test, double reference)
return 0.0f; // if we are expecting a NaN, any NaN is fine
// The unbiased exponent of the ulp unit place
int ulp_exp = FLT_MANT_DIG - 1 - MAX(ilogb(reference), FLT_MIN_EXP - 1);
int ulp_exp =
FLT_MANT_DIG - 1 - std::max(ilogb(reference), FLT_MIN_EXP - 1);
// Scale the exponent of the error
return (float)scalbn(testVal - reference, ulp_exp);
@ -444,7 +444,8 @@ float Ulp_Error(float test, double reference)
// reference is a normal power of two or a zero
// The unbiased exponent of the ulp unit place
int ulp_exp = FLT_MANT_DIG - 1 - MAX(ilogb(reference) - 1, FLT_MIN_EXP - 1);
int ulp_exp =
FLT_MANT_DIG - 1 - std::max(ilogb(reference) - 1, FLT_MIN_EXP - 1);
// Scale the exponent of the error
return (float)scalbn(testVal - reference, ulp_exp);
@ -512,7 +513,7 @@ float Ulp_Error_Double(double test, long double reference)
// The unbiased exponent of the ulp unit place
int ulp_exp =
DBL_MANT_DIG - 1 - MAX(ilogbl(reference), DBL_MIN_EXP - 1);
DBL_MANT_DIG - 1 - std::max(ilogbl(reference), DBL_MIN_EXP - 1);
// Scale the exponent of the error
float result = (float)scalbnl(testVal - reference, ulp_exp);
@ -528,7 +529,7 @@ float Ulp_Error_Double(double test, long double reference)
// reference is a normal power of two or a zero
// The unbiased exponent of the ulp unit place
int ulp_exp =
DBL_MANT_DIG - 1 - MAX(ilogbl(reference) - 1, DBL_MIN_EXP - 1);
DBL_MANT_DIG - 1 - std::max(ilogbl(reference) - 1, DBL_MIN_EXP - 1);
// Scale the exponent of the error
float result = (float)scalbnl(testVal - reference, ulp_exp);
@ -564,7 +565,7 @@ cl_int OutputBuildLogs(cl_program program, cl_uint num_devices,
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL,
&size_ret);
test_error(error, "Unable to query context's device size");
num_devices = size_ret / sizeof(cl_device_id);
num_devices = static_cast<cl_uint>(size_ret / sizeof(cl_device_id));
device_list = (cl_device_id *)malloc(size_ret);
if (device_list == NULL)
{
@ -623,7 +624,6 @@ cl_int OutputBuildLogs(cl_program program, cl_uint num_devices,
const char *subtests_to_skip_with_offline_compiler[] = {
"get_kernel_arg_info",
"get_kernel_arg_info_compatibility",
"binary_create",
"load_program_source",
"load_multistring_source",
@ -691,21 +691,19 @@ const char *subtests_to_skip_with_offline_compiler[] = {
"library_function"
};
int check_functions_for_offline_compiler(const char *subtestname,
cl_device_id device)
bool check_functions_for_offline_compiler(const char *subtestname)
{
if (gCompilationMode != kOnline)
{
int nNotRequiredWithOfflineCompiler =
sizeof(subtests_to_skip_with_offline_compiler) / sizeof(char *);
size_t i;
for (i = 0; i < nNotRequiredWithOfflineCompiler; ++i)
size_t nNotRequiredWithOfflineCompiler =
ARRAY_SIZE(subtests_to_skip_with_offline_compiler);
for (size_t i = 0; i < nNotRequiredWithOfflineCompiler; ++i)
{
if (!strcmp(subtestname, subtests_to_skip_with_offline_compiler[i]))
{
return 1;
return false;
}
}
}
return 0;
return true;
}

View file

@ -56,17 +56,13 @@ static int vlog_win32(const char *format, ...);
#define vlog printf
#endif
#define ct_assert(b) ct_assert_i(b, __LINE__)
#define ct_assert_i(b, line) ct_assert_ii(b, line)
#define ct_assert_ii(b, line) \
int _compile_time_assertion_on_line_##line[b ? 1 : -1];
#define test_fail(msg, ...) \
{ \
log_error(msg, ##__VA_ARGS__); \
return TEST_FAIL; \
}
#define test_error(errCode, msg) test_error_ret(errCode, msg, errCode)
#define test_error_fail(errCode, msg) test_error_ret(errCode, msg, TEST_FAIL)
#define test_error_ret(errCode, msg, retValue) \
{ \
auto errCodeResult = errCode; \
@ -97,21 +93,6 @@ static int vlog_win32(const char *format, ...);
"the device version! (from %s:%d)\n", \
msg, __FILE__, __LINE__);
#define test_missing_support_offline_cmpiler(errCode, msg) \
test_missing_support_offline_cmpiler_ret(errCode, msg, errCode)
// this macro should always return CL_SUCCESS, but print the skip message on
// test not supported with offline compiler
#define test_missing_support_offline_cmpiler_ret(errCode, msg, retValue) \
{ \
if (errCode != CL_SUCCESS) \
{ \
log_info("INFO: Subtest %s tests is not supported in offline " \
"compiler execution path! (from %s:%d)\n", \
msg, __FILE__, __LINE__); \
return TEST_SKIP; \
} \
}
// expected error code vs. what we got
#define test_failure_error(errCode, expectedErrCode, msg) \
test_failure_error_ret(errCode, expectedErrCode, msg, \
@ -172,6 +153,21 @@ static int vlog_win32(const char *format, ...);
} \
} while (0)
#define test_assert_event_status(comparison_operator, event) \
do \
{ \
cl_int status; \
cl_int err = clGetEventInfo(event, CL_EVENT_COMMAND_EXECUTION_STATUS, \
sizeof(status), &status, nullptr); \
test_error(err, "Could not get " #event " info"); \
test_assert_error(status comparison_operator CL_COMPLETE, \
"Unexpected status for " #event); \
} while (false)
#define test_assert_event_inprogress(event) test_assert_event_status(>, event)
#define test_assert_event_terminated(event) test_assert_event_status(<, event)
#define test_assert_event_complete(event) test_assert_event_status(==, event)
extern const char *IGetErrorString(int clErrorCode);
extern float Ulp_Error_Half(cl_half test, float reference);
@ -186,8 +182,7 @@ extern const char *GetAddressModeName(cl_addressing_mode mode);
extern const char *GetQueuePropertyName(cl_command_queue_properties properties);
extern const char *GetDeviceTypeName(cl_device_type type);
int check_functions_for_offline_compiler(const char *subtestname,
cl_device_id device);
bool check_functions_for_offline_compiler(const char *subtestname);
cl_int OutputBuildLogs(cl_program program, cl_uint num_devices,
cl_device_id *device_list);

View file

@ -0,0 +1,36 @@
//
// Copyright (c) 2022 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 _extensionHelpers_h
#define _extensionHelpers_h
// Load a specific function that is part of an OpenCL extension
#define GET_PFN(device, fn_name) \
fn_name##_fn fn_name = reinterpret_cast<fn_name##_fn>( \
clGetExtensionFunctionAddressForPlatform( \
getPlatformFromDevice(device), #fn_name)); \
do \
{ \
if (!fn_name) \
{ \
log_error( \
"ERROR: Failed to get function pointer for %s at %s:%d\n", \
#fn_name, __FILE__, __LINE__); \
return TEST_FAIL; \
} \
} while (false)
#endif // _extensionHelpers_h

View file

@ -16,6 +16,8 @@
#ifndef _fpcontrol_h
#define _fpcontrol_h
#include <cstdint>
// In order to get tests for correctly rounded operations (e.g. multiply) to
// work properly we need to be able to set the reference hardware to FTZ mode if
// the device hardware is running in that mode. We have explored all other
@ -30,7 +32,11 @@
// that rounding mode.
#if defined(__APPLE__) || defined(_MSC_VER) || defined(__linux__) \
|| defined(__MINGW32__)
#ifdef _MSC_VER
typedef int FPU_mode_type;
#else
typedef int64_t FPU_mode_type;
#endif
#if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER) \
|| defined(__MINGW32__)
#include <xmmintrin.h>
@ -39,7 +45,7 @@ typedef int FPU_mode_type;
extern __thread fpu_control_t fpu_control;
#endif
// Set the reference hardware floating point unit to FTZ mode
static inline void ForceFTZ(FPU_mode_type *mode)
inline void ForceFTZ(FPU_mode_type *mode)
{
#if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER) \
|| defined(__MINGW32__)
@ -55,7 +61,7 @@ static inline void ForceFTZ(FPU_mode_type *mode)
__asm__ volatile("fmxr fpscr, %0" ::"r"(fpscr | (1U << 24)));
// Add 64 bit support
#elif defined(__aarch64__)
unsigned fpscr;
uint64_t fpscr;
__asm__ volatile("mrs %0, fpcr" : "=r"(fpscr));
*mode = fpscr;
__asm__ volatile("msr fpcr, %0" ::"r"(fpscr | (1U << 24)));
@ -65,7 +71,7 @@ static inline void ForceFTZ(FPU_mode_type *mode)
}
// Disable the denorm flush to zero
static inline void DisableFTZ(FPU_mode_type *mode)
inline void DisableFTZ(FPU_mode_type *mode)
{
#if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER) \
|| defined(__MINGW32__)
@ -81,7 +87,7 @@ static inline void DisableFTZ(FPU_mode_type *mode)
__asm__ volatile("fmxr fpscr, %0" ::"r"(fpscr & ~(1U << 24)));
// Add 64 bit support
#elif defined(__aarch64__)
unsigned fpscr;
uint64_t fpscr;
__asm__ volatile("mrs %0, fpcr" : "=r"(fpscr));
*mode = fpscr;
__asm__ volatile("msr fpcr, %0" ::"r"(fpscr & ~(1U << 24)));
@ -91,7 +97,7 @@ static inline void DisableFTZ(FPU_mode_type *mode)
}
// Restore the reference hardware to floating point state indicated by *mode
static inline void RestoreFPState(FPU_mode_type *mode)
inline void RestoreFPState(FPU_mode_type *mode)
{
#if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER) \
|| defined(__MINGW32__)

View file

@ -23,6 +23,7 @@
#include <malloc.h>
#endif
#include <algorithm>
#include <cinttypes>
#include <iterator>
#if !defined(_WIN32)
#include <cmath>
@ -421,7 +422,7 @@ void print_first_pixel_difference_error(size_t where, const char *sourcePixel,
(int)thirdDim, (int)imageInfo->rowPitch,
(int)imageInfo->rowPitch
- (int)imageInfo->width * (int)pixel_size);
log_error("Failed at column: %ld ", where);
log_error("Failed at column: %zu ", where);
switch (pixel_size)
{
@ -454,7 +455,7 @@ void print_first_pixel_difference_error(size_t where, const char *sourcePixel,
((cl_ushort *)destPixel)[1], ((cl_ushort *)destPixel)[2]);
break;
case 8:
log_error("*0x%16.16llx vs. 0x%16.16llx\n",
log_error("*0x%16.16" PRIx64 " vs. 0x%16.16" PRIx64 "\n",
((cl_ulong *)sourcePixel)[0], ((cl_ulong *)destPixel)[0]);
break;
case 12:
@ -473,12 +474,53 @@ void print_first_pixel_difference_error(size_t where, const char *sourcePixel,
((cl_uint *)destPixel)[2], ((cl_uint *)destPixel)[3]);
break;
default:
log_error("Don't know how to print pixel size of %ld\n",
log_error("Don't know how to print pixel size of %zu\n",
pixel_size);
break;
}
}
size_t compare_scanlines(const image_descriptor *imageInfo, const char *aPtr,
const char *bPtr)
{
size_t pixel_size = get_pixel_size(imageInfo->format);
size_t column;
for (column = 0; column < imageInfo->width; column++)
{
switch (imageInfo->format->image_channel_data_type)
{
// If the data type is 101010, then ignore bits 31 and 32 when
// comparing the row
case CL_UNORM_INT_101010: {
cl_uint aPixel = *(cl_uint *)aPtr;
cl_uint bPixel = *(cl_uint *)bPtr;
if ((aPixel & 0x3fffffff) != (bPixel & 0x3fffffff))
return column;
}
break;
// If the data type is 555, ignore bit 15 when comparing the row
case CL_UNORM_SHORT_555: {
cl_ushort aPixel = *(cl_ushort *)aPtr;
cl_ushort bPixel = *(cl_ushort *)bPtr;
if ((aPixel & 0x7fff) != (bPixel & 0x7fff)) return column;
}
break;
default:
if (memcmp(aPtr, bPtr, pixel_size) != 0) return column;
break;
}
aPtr += pixel_size;
bPtr += pixel_size;
}
// If we didn't find a difference, return the width of the image
return column;
}
int random_log_in_range(int minV, int maxV, MTdata d)
{
double v = log2(((double)genrand_int32(d) / (double)0xffffffff) + 1);
@ -554,8 +596,8 @@ struct AddressingTable
{
AddressingTable()
{
ct_assert((CL_ADDRESS_MIRRORED_REPEAT - CL_ADDRESS_NONE < 6));
ct_assert(CL_FILTER_NEAREST - CL_FILTER_LINEAR < 2);
static_assert(CL_ADDRESS_MIRRORED_REPEAT - CL_ADDRESS_NONE < 6, "");
static_assert(CL_FILTER_NEAREST - CL_FILTER_LINEAR < 2, "");
mTable[CL_ADDRESS_NONE - CL_ADDRESS_NONE]
[CL_FILTER_NEAREST - CL_FILTER_NEAREST] = NoAddressFn;
@ -649,9 +691,6 @@ int has_alpha(const cl_image_format *format)
_b ^= _a; \
_a ^= _b; \
} while (0)
#ifndef MAX
#define MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#endif
void get_max_sizes(
size_t *numberOfSizes, const int maxNumberOfSizes, size_t sizes[][3],
@ -719,7 +758,7 @@ void get_max_sizes(
if (usingMaxPixelSizeBuffer || raw_pixel_size == 12) raw_pixel_size = 16;
size_t max_pixels = (size_t)maxAllocSize / raw_pixel_size;
log_info("Maximums: [%ld x %ld x %ld], raw pixel size %lu bytes, "
log_info("Maximums: [%zu x %zu x %zu], raw pixel size %zu bytes, "
"per-allocation limit %gMB.\n",
maxWidth, maxHeight, isArray ? maxArraySize : maxDepth,
raw_pixel_size, (maxAllocSize / (1024.0 * 1024.0)));
@ -760,10 +799,10 @@ void get_max_sizes(
if (image_type == CL_MEM_OBJECT_IMAGE1D)
{
double M = maximum_sizes[0];
size_t M = maximum_sizes[0];
// Store the size
sizes[(*numberOfSizes)][0] = (size_t)M;
sizes[(*numberOfSizes)][0] = M;
sizes[(*numberOfSizes)][1] = 1;
sizes[(*numberOfSizes)][2] = 1;
++(*numberOfSizes);
@ -777,17 +816,17 @@ void get_max_sizes(
{
// Determine the size of the fixed dimension
double M = maximum_sizes[fixed_dim];
double A = max_pixels;
size_t M = maximum_sizes[fixed_dim];
size_t A = max_pixels;
int x0_dim = !fixed_dim;
double x0 =
size_t x0 = static_cast<size_t>(
fmin(fmin(other_sizes[(other_size++) % num_other_sizes], A / M),
maximum_sizes[x0_dim]);
maximum_sizes[x0_dim]));
// Store the size
sizes[(*numberOfSizes)][fixed_dim] = (size_t)M;
sizes[(*numberOfSizes)][x0_dim] = (size_t)x0;
sizes[(*numberOfSizes)][fixed_dim] = M;
sizes[(*numberOfSizes)][x0_dim] = x0;
sizes[(*numberOfSizes)][2] = 1;
++(*numberOfSizes);
}
@ -802,16 +841,17 @@ void get_max_sizes(
{
// Determine the size of the fixed dimension
double M = maximum_sizes[fixed_dim];
double A = max_pixels;
size_t M = maximum_sizes[fixed_dim];
size_t A = max_pixels;
// Find two other dimensions, x0 and x1
int x0_dim = (fixed_dim == 0) ? 1 : 0;
int x1_dim = (fixed_dim == 2) ? 1 : 2;
// Choose two other sizes for these dimensions
double x0 = fmin(fmin(A / M, maximum_sizes[x0_dim]),
other_sizes[(other_size++) % num_other_sizes]);
size_t x0 = static_cast<size_t>(
fmin(fmin(A / M, maximum_sizes[x0_dim]),
other_sizes[(other_size++) % num_other_sizes]));
// GPUs have certain restrictions on minimum width (row alignment)
// of images which has given us issues testing small widths in this
// test (say we set width to 3 for testing, and compute size based
@ -820,8 +860,9 @@ void get_max_sizes(
// width of 16 which doesnt fit in vram). For this purpose we are
// not testing width < 16 for this test.
if (x0_dim == 0 && x0 < 16) x0 = 16;
double x1 = fmin(fmin(A / M / x0, maximum_sizes[x1_dim]),
other_sizes[(other_size++) % num_other_sizes]);
size_t x1 = static_cast<size_t>(
fmin(fmin(A / M / x0, maximum_sizes[x1_dim]),
other_sizes[(other_size++) % num_other_sizes]));
// Valid image sizes cannot be below 1. Due to the workaround for
// the xo_dim where x0 is overidden to 16 there might not be enough
@ -834,9 +875,9 @@ void get_max_sizes(
assert(x0 > 0 && M > 0);
// Store the size
sizes[(*numberOfSizes)][fixed_dim] = (size_t)M;
sizes[(*numberOfSizes)][x0_dim] = (size_t)x0;
sizes[(*numberOfSizes)][x1_dim] = (size_t)x1;
sizes[(*numberOfSizes)][fixed_dim] = M;
sizes[(*numberOfSizes)][x0_dim] = x0;
sizes[(*numberOfSizes)][x1_dim] = x1;
++(*numberOfSizes);
}
}
@ -847,20 +888,20 @@ void get_max_sizes(
switch (image_type)
{
case CL_MEM_OBJECT_IMAGE1D:
log_info(" size[%d] = [%ld] (%g MB image)\n", j, sizes[j][0],
log_info(" size[%d] = [%zu] (%g MB image)\n", j, sizes[j][0],
raw_pixel_size * sizes[j][0] * sizes[j][1]
* sizes[j][2] / (1024.0 * 1024.0));
break;
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
case CL_MEM_OBJECT_IMAGE2D:
log_info(" size[%d] = [%ld %ld] (%g MB image)\n", j,
log_info(" size[%d] = [%zu %zu] (%g MB image)\n", j,
sizes[j][0], sizes[j][1],
raw_pixel_size * sizes[j][0] * sizes[j][1]
* sizes[j][2] / (1024.0 * 1024.0));
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
case CL_MEM_OBJECT_IMAGE3D:
log_info(" size[%d] = [%ld %ld %ld] (%g MB image)\n", j,
log_info(" size[%d] = [%zu %zu %zu] (%g MB image)\n", j,
sizes[j][0], sizes[j][1], sizes[j][2],
raw_pixel_size * sizes[j][0] * sizes[j][1]
* sizes[j][2] / (1024.0 * 1024.0));
@ -884,6 +925,8 @@ float get_max_absolute_error(const cl_image_format *format,
#ifdef CL_SFIXED14_APPLE
case CL_SFIXED14_APPLE: return 0x1.0p-14f;
#endif
case CL_UNORM_SHORT_555:
case CL_UNORM_SHORT_565: return 1.0f / 31.0f;
default: return 0.0f;
}
}
@ -1124,12 +1167,13 @@ void escape_inf_nan_values(char *data, size_t allocSize)
char *generate_random_image_data(image_descriptor *imageInfo,
BufferOwningPtr<char> &P, MTdata d)
{
size_t allocSize = get_image_size(imageInfo);
size_t allocSize = static_cast<size_t>(get_image_size(imageInfo));
size_t pixelRowBytes = imageInfo->width * get_pixel_size(imageInfo->format);
size_t i;
if (imageInfo->num_mip_levels > 1)
allocSize = compute_mipmapped_image_size(*imageInfo);
allocSize =
static_cast<size_t>(compute_mipmapped_image_size(*imageInfo));
#if defined(__APPLE__)
char *data = NULL;
@ -1161,7 +1205,7 @@ char *generate_random_image_data(image_descriptor *imageInfo,
if (data == NULL)
{
log_error("ERROR: Unable to malloc %lu bytes for "
log_error("ERROR: Unable to malloc %zu bytes for "
"generate_random_image_data\n",
allocSize);
return 0;
@ -1678,24 +1722,26 @@ bool get_integer_coords_offset(float x, float y, float z, float xAddressOffset,
// At this point, we're dealing with non-normalized coordinates.
outX = adFn(floorf(x), width);
outX = adFn(static_cast<int>(floorf(x)), width);
// 1D and 2D arrays require special care for the index coordinate:
switch (imageInfo->type)
{
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
outY = calculate_array_index(y, (float)imageInfo->arraySize - 1.0f);
outZ = 0.0f; /* don't care! */
outY = static_cast<int>(
calculate_array_index(y, (float)imageInfo->arraySize - 1.0f));
outZ = 0; /* don't care! */
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
outY = adFn(floorf(y), height);
outZ = calculate_array_index(z, (float)imageInfo->arraySize - 1.0f);
outY = adFn(static_cast<int>(floorf(y)), height);
outZ = static_cast<int>(
calculate_array_index(z, (float)imageInfo->arraySize - 1.0f));
break;
default:
// legacy path:
if (height != 0) outY = adFn(floorf(y), height);
if (depth != 0) outZ = adFn(floorf(z), depth);
if (height != 0) outY = adFn(static_cast<int>(floorf(y)), height);
if (depth != 0) outZ = adFn(static_cast<int>(floorf(z)), depth);
}
return !((int)refX == outX && (int)refY == outY && (int)refZ == outZ);
@ -1766,7 +1812,7 @@ static float unnormalize_coordinate(const char *name, float coord, float offset,
switch (addressing_mode)
{
case CL_ADDRESS_REPEAT:
ret = RepeatNormalizedAddressFn(coord, extent);
ret = RepeatNormalizedAddressFn(coord, static_cast<size_t>(extent));
if (verbose)
{
@ -1790,7 +1836,8 @@ static float unnormalize_coordinate(const char *name, float coord, float offset,
break;
case CL_ADDRESS_MIRRORED_REPEAT:
ret = MirroredRepeatNormalizedAddressFn(coord, extent);
ret = MirroredRepeatNormalizedAddressFn(
coord, static_cast<size_t>(extent));
if (verbose)
{
@ -1948,7 +1995,7 @@ FloatPixel sample_image_pixel_float_offset(
break;
case CL_MEM_OBJECT_IMAGE1D:
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
log_info("Starting coordinate: %f\b", x);
log_info("Starting coordinate: %f\n", x);
break;
case CL_MEM_OBJECT_IMAGE2D:
log_info("Starting coordinate: %f, %f\n", x, y);
@ -1968,13 +2015,13 @@ FloatPixel sample_image_pixel_float_offset(
// coordinates. Note that the array cases again require special
// care, per section 8.4 in the OpenCL 1.2 Specification.
ix = adFn(floorf(x), width_lod);
ix = adFn(static_cast<int>(floorf(x)), width_lod);
switch (imageInfo->type)
{
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
iy =
calculate_array_index(y, (float)(imageInfo->arraySize - 1));
iy = static_cast<int>(calculate_array_index(
y, (float)(imageInfo->arraySize - 1)));
iz = 0;
if (verbose)
{
@ -1982,18 +2029,18 @@ FloatPixel sample_image_pixel_float_offset(
}
break;
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
iy = adFn(floorf(y), height_lod);
iz =
calculate_array_index(z, (float)(imageInfo->arraySize - 1));
iy = adFn(static_cast<int>(floorf(y)), height_lod);
iz = static_cast<int>(calculate_array_index(
z, (float)(imageInfo->arraySize - 1)));
if (verbose)
{
log_info("\tArray index %f evaluates to %d\n", z, iz);
}
break;
default:
iy = adFn(floorf(y), height_lod);
iy = adFn(static_cast<int>(floorf(y)), height_lod);
if (depth_lod != 0)
iz = adFn(floorf(z), depth_lod);
iz = adFn(static_cast<int>(floorf(z)), depth_lod);
else
iz = 0;
}
@ -2047,16 +2094,16 @@ FloatPixel sample_image_pixel_float_offset(
height = 1;
}
int x1 = adFn(floorf(x - 0.5f), width);
int x1 = adFn(static_cast<int>(floorf(x - 0.5f)), width);
int y1 = 0;
int x2 = adFn(floorf(x - 0.5f) + 1, width);
int x2 = adFn(static_cast<int>(floorf(x - 0.5f) + 1), width);
int y2 = 0;
if ((imageInfo->type != CL_MEM_OBJECT_IMAGE1D)
&& (imageInfo->type != CL_MEM_OBJECT_IMAGE1D_ARRAY)
&& (imageInfo->type != CL_MEM_OBJECT_IMAGE1D_BUFFER))
{
y1 = adFn(floorf(y - 0.5f), height);
y2 = adFn(floorf(y - 0.5f) + 1, height);
y1 = adFn(static_cast<int>(floorf(y - 0.5f)), height);
y2 = adFn(static_cast<int>(floorf(y - 0.5f) + 1), height);
}
else
{
@ -2105,14 +2152,6 @@ FloatPixel sample_image_pixel_float_offset(
lowRight[2], lowRight[3]);
}
bool printMe = false;
if (x1 <= 0 || x2 <= 0 || x1 >= (int)width - 1
|| x2 >= (int)width - 1)
printMe = true;
if (y1 <= 0 || y2 <= 0 || y1 >= (int)height - 1
|| y2 >= (int)height - 1)
printMe = true;
double weights[2][2];
weights[0][0] = weights[0][1] = 1.0 - frac(x - 0.5f);
@ -2147,12 +2186,12 @@ FloatPixel sample_image_pixel_float_offset(
else
{
// 3D linear filtering
int x1 = adFn(floorf(x - 0.5f), width_lod);
int y1 = adFn(floorf(y - 0.5f), height_lod);
int z1 = adFn(floorf(z - 0.5f), depth_lod);
int x2 = adFn(floorf(x - 0.5f) + 1, width_lod);
int y2 = adFn(floorf(y - 0.5f) + 1, height_lod);
int z2 = adFn(floorf(z - 0.5f) + 1, depth_lod);
int x1 = adFn(static_cast<int>(floorf(x - 0.5f)), width_lod);
int y1 = adFn(static_cast<int>(floorf(y - 0.5f)), height_lod);
int z1 = adFn(static_cast<int>(floorf(z - 0.5f)), depth_lod);
int x2 = adFn(static_cast<int>(floorf(x - 0.5f) + 1), width_lod);
int y2 = adFn(static_cast<int>(floorf(y - 0.5f) + 1), height_lod);
int z2 = adFn(static_cast<int>(floorf(z - 0.5f) + 1), depth_lod);
if (verbose)
log_info("\tActual integer coords used (i = floor(x-.5)): "
@ -2580,11 +2619,11 @@ void pack_image_pixel(int *srcVector, const cl_image_format *imageFormat,
}
}
int round_to_even(float v)
cl_int round_to_even(float v)
{
// clamp overflow
if (v >= -(float)INT_MIN) return INT_MAX;
if (v <= (float)INT_MIN) return INT_MIN;
if (v >= -(float)CL_INT_MIN) return CL_INT_MAX;
if (v <= (float)CL_INT_MIN) return CL_INT_MIN;
// round fractional values to integer value
if (fabsf(v) < MAKE_HEX_FLOAT(0x1.0p23f, 0x1L, 23))
@ -2596,7 +2635,7 @@ int round_to_even(float v)
v -= magicVal;
}
return (int)v;
return (cl_int)v;
}
void pack_image_pixel(float *srcVector, const cl_image_format *imageFormat,
@ -2721,10 +2760,7 @@ void pack_image_pixel(float *srcVector, const cl_image_format *imageFormat,
case CL_SIGNED_INT32: {
cl_int *ptr = (cl_int *)outData;
for (unsigned int i = 0; i < channelCount; i++)
ptr[i] = (int)CONVERT_INT(
srcVector[i], MAKE_HEX_FLOAT(-0x1.0p31f, -1, 31),
MAKE_HEX_FLOAT(0x1.fffffep30f, 0x1fffffe, 30 - 23),
CL_INT_MAX);
ptr[i] = round_to_even(srcVector[i]);
break;
}
case CL_UNSIGNED_INT8: {
@ -2888,26 +2924,25 @@ void pack_image_pixel_error(const float *srcVector,
case CL_SIGNED_INT32: {
const cl_int *ptr = (const cl_int *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] = (cl_float)(
(cl_long)ptr[i]
- (cl_long)CONVERT_INT(
srcVector[i], MAKE_HEX_FLOAT(-0x1.0p31f, -1, 31),
MAKE_HEX_FLOAT(0x1.fffffep30f, 0x1fffffe, 30 - 23),
CL_INT_MAX));
errors[i] = (cl_float)((cl_long)ptr[i]
- (cl_long)round_to_even(srcVector[i]));
break;
}
case CL_UNSIGNED_INT8: {
const cl_uchar *ptr = (const cl_uchar *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] = (cl_int)ptr[i]
- (cl_int)CONVERT_UINT(srcVector[i], 255.f, CL_UCHAR_MAX);
errors[i] = static_cast<float>(
(cl_int)ptr[i]
- (cl_int)CONVERT_UINT(srcVector[i], 255.f, CL_UCHAR_MAX));
break;
}
case CL_UNSIGNED_INT16: {
const cl_ushort *ptr = (const cl_ushort *)results;
for (unsigned int i = 0; i < channelCount; i++)
errors[i] = (cl_int)ptr[i]
- (cl_int)CONVERT_UINT(srcVector[i], 32767.f, CL_USHRT_MAX);
errors[i] = static_cast<float>(
(cl_int)ptr[i]
- (cl_int)CONVERT_UINT(srcVector[i], 32767.f,
CL_USHRT_MAX));
break;
}
case CL_UNSIGNED_INT32: {
@ -3228,7 +3263,7 @@ char *create_random_image_data(ExplicitType dataType,
if (data == NULL)
{
log_error(
"ERROR: Unable to malloc %lu bytes for create_random_image_data\n",
"ERROR: Unable to malloc %zu bytes for create_random_image_data\n",
allocSize);
return NULL;
}
@ -3988,7 +4023,8 @@ bool is_image_format_required(cl_image_format format, cl_mem_flags flags,
cl_uint compute_max_mip_levels(size_t width, size_t height, size_t depth)
{
cl_uint retMaxMipLevels = 0, max_dim = 0;
cl_uint retMaxMipLevels = 0;
size_t max_dim = 0;
max_dim = width;
max_dim = height > max_dim ? height : max_dim;

View file

@ -63,7 +63,7 @@ typedef struct
bool normalized_coords;
} image_sampler_data;
int round_to_even(float v);
cl_int round_to_even(float v);
#define NORMALIZE(v, max) (v < 0 ? 0 : (v > 1.f ? max : round_to_even(v * max)))
#define NORMALIZE_UNROUNDED(v, max) (v < 0 ? 0 : (v > 1.f ? max : v * max))
@ -139,6 +139,9 @@ void print_first_pixel_difference_error(size_t where, const char *sourcePixel,
image_descriptor *imageInfo, size_t y,
size_t thirdDim);
size_t compare_scanlines(const image_descriptor *imageInfo, const char *aPtr,
const char *bPtr);
void get_max_sizes(size_t *numberOfSizes, const int maxNumberOfSizes,
size_t sizes[][3], size_t maxWidth, size_t maxHeight,
size_t maxDepth, size_t maxArraySize,
@ -479,6 +482,13 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
outData[2] = tempData[3];
outData[3] = tempData[0];
}
else if (format->image_channel_order == CL_ABGR)
{
outData[0] = tempData[3];
outData[1] = tempData[2];
outData[2] = tempData[1];
outData[3] = tempData[0];
}
else if ((format->image_channel_order == CL_BGRA)
|| (format->image_channel_order == CL_sBGRA))
{
@ -489,12 +499,14 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
}
else if (format->image_channel_order == CL_INTENSITY)
{
outData[0] = tempData[0];
outData[1] = tempData[0];
outData[2] = tempData[0];
outData[3] = tempData[0];
}
else if (format->image_channel_order == CL_LUMINANCE)
{
outData[0] = tempData[0];
outData[1] = tempData[0];
outData[2] = tempData[0];
}

View file

@ -0,0 +1,92 @@
//
// Copyright (c) 2021 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef INTEGER_OPS_TEST_INFO_H
#define INTEGER_OPS_TEST_INFO_H
#include "conversions.h"
#include "testHarness.h"
// TODO: expand usage to other tests.
template <typename T> struct TestInfo
{
};
template <> struct TestInfo<cl_char>
{
static const ExplicitType explicitType = kChar;
static constexpr const char* deviceTypeName = "char";
static constexpr const char* deviceTypeNameSigned = "char";
static constexpr const char* deviceTypeNameUnsigned = "uchar";
};
template <> struct TestInfo<cl_uchar>
{
static const ExplicitType explicitType = kUChar;
static constexpr const char* deviceTypeName = "uchar";
static constexpr const char* deviceTypeNameSigned = "char";
static constexpr const char* deviceTypeNameUnsigned = "uchar";
};
template <> struct TestInfo<cl_short>
{
static const ExplicitType explicitType = kShort;
static constexpr const char* deviceTypeName = "short";
static constexpr const char* deviceTypeNameSigned = "short";
static constexpr const char* deviceTypeNameUnsigned = "ushort";
};
template <> struct TestInfo<cl_ushort>
{
static const ExplicitType explicitType = kUShort;
static constexpr const char* deviceTypeName = "ushort";
static constexpr const char* deviceTypeNameSigned = "short";
static constexpr const char* deviceTypeNameUnsigned = "ushort";
};
template <> struct TestInfo<cl_int>
{
static const ExplicitType explicitType = kInt;
static constexpr const char* deviceTypeName = "int";
static constexpr const char* deviceTypeNameSigned = "int";
static constexpr const char* deviceTypeNameUnsigned = "uint";
};
template <> struct TestInfo<cl_uint>
{
static const ExplicitType explicitType = kUInt;
static constexpr const char* deviceTypeName = "uint";
static constexpr const char* deviceTypeNameSigned = "int";
static constexpr const char* deviceTypeNameUnsigned = "uint";
};
template <> struct TestInfo<cl_long>
{
static const ExplicitType explicitType = kLong;
static constexpr const char* deviceTypeName = "long";
static constexpr const char* deviceTypeNameSigned = "long";
static constexpr const char* deviceTypeNameUnsigned = "ulong";
};
template <> struct TestInfo<cl_ulong>
{
static const ExplicitType explicitType = kULong;
static constexpr const char* deviceTypeName = "ulong";
static constexpr const char* deviceTypeNameSigned = "long";
static constexpr const char* deviceTypeNameUnsigned = "ulong";
};
template <typename T>
static void fill_vector_with_random_data(std::vector<T>& v)
{
MTdataHolder d(gRandomSeed);
generate_random_data(TestInfo<T>::explicitType, v.size(), d, v.data());
}
#endif /* INTEGER_OPS_TEST_INFO_H */

View file

@ -312,57 +312,6 @@ get_compilation_mode_str(const CompilationMode compilationMode)
}
}
#ifdef KHRONOS_OFFLINE_COMPILER
static std::string
get_khronos_compiler_command(const cl_uint device_address_space_size,
const bool openclCXX, const std::string &bOptions,
const std::string &sourceFilename,
const std::string &outputFilename)
{
// Set compiler options
// Emit SPIR-V
std::string compilerOptions = " -cc1 -emit-spirv";
// <triple>: for 32 bit SPIR-V use spir-unknown-unknown, for 64 bit SPIR-V
// use spir64-unknown-unknown.
if (device_address_space_size == 32)
{
compilerOptions += " -triple=spir-unknown-unknown";
}
else
{
compilerOptions += " -triple=spir64-unknown-unknown";
}
// Set OpenCL C++ flag required by SPIR-V-ready clang (compiler provided by
// Khronos)
if (openclCXX)
{
compilerOptions = compilerOptions + " -cl-std=c++";
}
// Set correct includes
if (openclCXX)
{
compilerOptions += " -I ";
compilerOptions += STRINGIFY_VALUE(CL_LIBCLCXX_DIR);
}
else
{
compilerOptions += " -include opencl.h";
}
#ifdef KHRONOS_OFFLINE_COMPILER_OPTIONS
compilerOptions += STRINGIFY_VALUE(KHRONOS_OFFLINE_COMPILER_OPTIONS);
#endif
// Add build options passed to this function
compilerOptions += " " + bOptions;
compilerOptions += " " + sourceFilename + " -o " + outputFilename;
std::string runString =
STRINGIFY_VALUE(KHRONOS_OFFLINE_COMPILER) + compilerOptions;
return runString;
}
#endif // KHRONOS_OFFLINE_COMPILER
static cl_int get_cl_device_info_str(const cl_device_id device,
const cl_uint device_address_space_size,
const CompilationMode compilationMode,
@ -476,49 +425,27 @@ static int invoke_offline_compiler(const cl_device_id device,
const CompilationMode compilationMode,
const std::string &bOptions,
const std::string &sourceFilename,
const std::string &outputFilename,
const bool openclCXX)
const std::string &outputFilename)
{
std::string runString;
if (openclCXX)
std::string clDeviceInfoFilename;
// See cl_offline_compiler-interface.txt for a description of the
// format of the CL device information file generated below, and
// the internal command line interface for invoking the offline
// compiler.
cl_int err = write_cl_device_info(device, device_address_space_size,
compilationMode, clDeviceInfoFilename);
if (err != CL_SUCCESS)
{
#ifndef KHRONOS_OFFLINE_COMPILER
log_error("CL C++ compilation is not possible: "
"KHRONOS_OFFLINE_COMPILER was not defined.\n");
return CL_INVALID_OPERATION;
#else
if (compilationMode != kSpir_v)
{
log_error("Compilation mode must be SPIR-V for Khronos compiler");
return -1;
}
runString = get_khronos_compiler_command(
device_address_space_size, openclCXX, bOptions, sourceFilename,
outputFilename);
#endif
log_error("Failed writing CL device info file\n");
return err;
}
else
{
std::string clDeviceInfoFilename;
// See cl_offline_compiler-interface.txt for a description of the
// format of the CL device information file generated below, and
// the internal command line interface for invoking the offline
// compiler.
cl_int err =
write_cl_device_info(device, device_address_space_size,
compilationMode, clDeviceInfoFilename);
if (err != CL_SUCCESS)
{
log_error("Failed writing CL device info file\n");
return err;
}
runString = get_offline_compilation_command(
device_address_space_size, compilationMode, bOptions,
sourceFilename, outputFilename, clDeviceInfoFilename);
}
runString = get_offline_compilation_command(
device_address_space_size, compilationMode, bOptions, sourceFilename,
outputFilename, clDeviceInfoFilename);
// execute script
log_info("Executing command: %s\n", runString.c_str());
@ -577,9 +504,8 @@ static cl_int get_device_address_bits(const cl_device_id device,
static int get_offline_compiler_output(
std::ifstream &ifs, const cl_device_id device, cl_uint deviceAddrSpaceSize,
const bool openclCXX, const CompilationMode compilationMode,
const std::string &bOptions, const std::string &kernelPath,
const std::string &kernelNamePrefix)
const CompilationMode compilationMode, const std::string &bOptions,
const std::string &kernelPath, const std::string &kernelNamePrefix)
{
std::string sourceFilename =
get_cl_source_filename_with_path(kernelPath, kernelNamePrefix);
@ -599,12 +525,12 @@ static int get_offline_compiler_output(
}
else
{
int error = invoke_offline_compiler(
device, deviceAddrSpaceSize, compilationMode, bOptions,
sourceFilename, outputFilename, openclCXX);
int error = invoke_offline_compiler(device, deviceAddrSpaceSize,
compilationMode, bOptions,
sourceFilename, outputFilename);
if (error != CL_SUCCESS) return error;
// read output file
// open output file for reading
ifs.open(outputFilename.c_str(), std::ios::binary);
if (!ifs.good())
{
@ -614,14 +540,33 @@ static int get_offline_compiler_output(
}
}
}
if (compilationMode == kSpir_v && !gDisableSPIRVValidation)
{
std::string runString = gSPIRVValidator + " " + outputFilename;
int returnCode = system(runString.c_str());
if (returnCode == -1)
{
log_error("Error: failed to invoke SPIR-V validator\n");
return CL_COMPILE_PROGRAM_FAILURE;
}
else if (returnCode != 0)
{
log_error(
"Failed to validate SPIR-V file %s: system() returned 0x%x\n",
outputFilename.c_str(), returnCode);
return CL_COMPILE_PROGRAM_FAILURE;
}
}
return CL_SUCCESS;
}
static int create_single_kernel_helper_create_program_offline(
cl_context context, cl_device_id device, cl_program *outProgram,
unsigned int numKernelLines, const char *const *kernelProgram,
const char *buildOptions, const bool openclCXX,
CompilationMode compilationMode)
const char *buildOptions, CompilationMode compilationMode)
{
if (kCacheModeDumpCl == gCompilationCacheMode)
{
@ -649,24 +594,12 @@ static int create_single_kernel_helper_create_program_offline(
std::ifstream ifs;
error = get_offline_compiler_output(ifs, device, device_address_space_size,
openclCXX, compilationMode, bOptions,
compilationMode, bOptions,
gCompilationCachePath, kernelName);
if (error != CL_SUCCESS) return error;
// -----------------------------------------------------------------------------------
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT
// ------------------
// -----------------------------------------------------------------------------------
// Only OpenCL C++ to SPIR-V compilation
#if defined(DEVELOPMENT) && defined(ONLY_SPIRV_COMPILATION)
if (openclCXX)
{
return CL_SUCCESS;
}
#endif
ifs.seekg(0, ifs.end);
int length = ifs.tellg();
size_t length = static_cast<size_t>(ifs.tellg());
ifs.seekg(0, ifs.beg);
// treat modifiedProgram as input for clCreateProgramWithBinary
@ -748,8 +681,7 @@ static int create_single_kernel_helper_create_program_offline(
static int create_single_kernel_helper_create_program(
cl_context context, cl_device_id device, cl_program *outProgram,
unsigned int numKernelLines, const char **kernelProgram,
const char *buildOptions, const bool openclCXX,
CompilationMode compilationMode)
const char *buildOptions, CompilationMode compilationMode)
{
std::lock_guard<std::mutex> compiler_lock(gCompilerMutex);
@ -787,37 +719,39 @@ static int create_single_kernel_helper_create_program(
{
return create_single_kernel_helper_create_program_offline(
context, device, outProgram, numKernelLines, kernelProgram,
buildOptions, openclCXX, compilationMode);
buildOptions, compilationMode);
}
}
int create_single_kernel_helper_create_program(
cl_context context, cl_program *outProgram, unsigned int numKernelLines,
const char **kernelProgram, const char *buildOptions, const bool openclCXX)
int create_single_kernel_helper_create_program(cl_context context,
cl_program *outProgram,
unsigned int numKernelLines,
const char **kernelProgram,
const char *buildOptions)
{
return create_single_kernel_helper_create_program(
context, NULL, outProgram, numKernelLines, kernelProgram, buildOptions,
openclCXX, gCompilationMode);
gCompilationMode);
}
int create_single_kernel_helper_create_program_for_device(
cl_context context, cl_device_id device, cl_program *outProgram,
unsigned int numKernelLines, const char **kernelProgram,
const char *buildOptions, const bool openclCXX)
const char *buildOptions)
{
return create_single_kernel_helper_create_program(
context, device, outProgram, numKernelLines, kernelProgram,
buildOptions, openclCXX, gCompilationMode);
buildOptions, gCompilationMode);
}
int create_single_kernel_helper_with_build_options(
cl_context context, cl_program *outProgram, cl_kernel *outKernel,
unsigned int numKernelLines, const char **kernelProgram,
const char *kernelName, const char *buildOptions, const bool openclCXX)
const char *kernelName, const char *buildOptions)
{
return create_single_kernel_helper(context, outProgram, outKernel,
numKernelLines, kernelProgram,
kernelName, buildOptions, openclCXX);
kernelName, buildOptions);
}
// Creates and builds OpenCL C/C++ program, and creates a kernel
@ -826,7 +760,7 @@ int create_single_kernel_helper(cl_context context, cl_program *outProgram,
unsigned int numKernelLines,
const char **kernelProgram,
const char *kernelName,
const char *buildOptions, const bool openclCXX)
const char *buildOptions)
{
// For the logic that automatically adds -cl-std it is much cleaner if the
// build options have RAII. This buffer will store the potentially updated
@ -865,51 +799,14 @@ int create_single_kernel_helper(cl_context context, cl_program *outProgram,
build_options_internal += cl_std;
buildOptions = build_options_internal.c_str();
}
int error;
// Create OpenCL C++ program
if (openclCXX)
int error = create_single_kernel_helper_create_program(
context, outProgram, numKernelLines, kernelProgram, buildOptions);
if (error != CL_SUCCESS)
{
// -----------------------------------------------------------------------------------
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT
// ------------------
// -----------------------------------------------------------------------------------
// Only OpenCL C++ to SPIR-V compilation
#if defined(DEVELOPMENT) && defined(ONLY_SPIRV_COMPILATION)
// Save global variable
bool tempgCompilationCacheMode = gCompilationCacheMode;
// Force OpenCL C++ -> SPIR-V compilation on every run
gCompilationCacheMode = kCacheModeOverwrite;
#endif
error = create_openclcpp_program(context, outProgram, numKernelLines,
kernelProgram, buildOptions);
if (error != CL_SUCCESS)
{
log_error("Create program failed: %d, line: %d\n", error, __LINE__);
return error;
}
// -----------------------------------------------------------------------------------
// ------------- ONLY FOR OPENCL 22 CONFORMANCE TEST 22 DEVELOPMENT
// ------------------
// -----------------------------------------------------------------------------------
#if defined(DEVELOPMENT) && defined(ONLY_SPIRV_COMPILATION)
// Restore global variables
gCompilationCacheMode = tempgCompilationCacheMode;
log_info("WARNING: KERNEL %s WAS ONLY COMPILED TO SPIR-V\n",
kernelName);
log_error("Create program failed: %d, line: %d\n", error, __LINE__);
return error;
#endif
}
// Create OpenCL C program
else
{
error = create_single_kernel_helper_create_program(
context, outProgram, numKernelLines, kernelProgram, buildOptions);
if (error != CL_SUCCESS)
{
log_error("Create program failed: %d, line: %d\n", error, __LINE__);
return error;
}
}
// Remove offline-compiler-only build options
std::string newBuildOptions;
if (buildOptions != NULL)
@ -930,18 +827,6 @@ int create_single_kernel_helper(cl_context context, cl_program *outProgram,
kernelName, newBuildOptions.c_str());
}
// Creates OpenCL C++ program
int create_openclcpp_program(cl_context context, cl_program *outProgram,
unsigned int numKernelLines,
const char **kernelProgram,
const char *buildOptions)
{
// Create program
return create_single_kernel_helper_create_program(
context, NULL, outProgram, numKernelLines, kernelProgram, buildOptions,
true, kSpir_v);
}
// Builds OpenCL C/C++ program and creates
int build_program_create_kernel_helper(
cl_context context, cl_program *outProgram, cl_kernel *outKernel,
@ -1361,7 +1246,7 @@ int is_image_format_supported(cl_context context, cl_mem_flags flags,
list = (cl_image_format *)malloc(count * sizeof(cl_image_format));
if (NULL == list)
{
log_error("Error: unable to allocate %ld byte buffer for image format "
log_error("Error: unable to allocate %zu byte buffer for image format "
"list at %s:%d (err = %d)\n",
count * sizeof(cl_image_format), __FILE__, __LINE__, err);
return 0;
@ -1626,22 +1511,33 @@ size_t get_min_alignment(cl_context context)
return align_size;
}
cl_device_fp_config get_default_rounding_mode(cl_device_id device)
cl_device_fp_config get_default_rounding_mode(cl_device_id device,
const cl_uint &param)
{
if (param == CL_DEVICE_DOUBLE_FP_CONFIG)
test_error_ret(
-1,
"FAILURE: CL_DEVICE_DOUBLE_FP_CONFIG not supported by this routine",
0);
char profileStr[128] = "";
cl_device_fp_config single = 0;
int error = clGetDeviceInfo(device, CL_DEVICE_SINGLE_FP_CONFIG,
sizeof(single), &single, NULL);
int error = clGetDeviceInfo(device, param, sizeof(single), &single, NULL);
if (error)
test_error_ret(error, "Unable to get device CL_DEVICE_SINGLE_FP_CONFIG",
0);
{
std::string message = std::string("Unable to get device ")
+ std::string(param == CL_DEVICE_HALF_FP_CONFIG
? "CL_DEVICE_HALF_FP_CONFIG"
: "CL_DEVICE_SINGLE_FP_CONFIG");
test_error_ret(error, message.c_str(), 0);
}
if (single & CL_FP_ROUND_TO_NEAREST) return CL_FP_ROUND_TO_NEAREST;
if (0 == (single & CL_FP_ROUND_TO_ZERO))
test_error_ret(-1,
"FAILURE: device must support either "
"CL_DEVICE_SINGLE_FP_CONFIG or CL_FP_ROUND_TO_NEAREST",
"CL_FP_ROUND_TO_ZERO or CL_FP_ROUND_TO_NEAREST",
0);
// Make sure we are an embedded device before allowing a pass
@ -1776,8 +1672,10 @@ Version get_device_latest_cl_c_version(cl_device_id device)
Version max_supported_cl_c_version{};
for (const auto &name_version : name_versions)
{
Version current_version{ CL_VERSION_MAJOR(name_version.version),
CL_VERSION_MINOR(name_version.version) };
Version current_version{
static_cast<int>(CL_VERSION_MAJOR(name_version.version)),
static_cast<int>(CL_VERSION_MINOR(name_version.version))
};
max_supported_cl_c_version =
(current_version > max_supported_cl_c_version)
? current_version
@ -1822,7 +1720,7 @@ Version get_max_OpenCL_C_for_context(cl_context context)
else
{
current_version =
(std::min)(device_version, current_version);
std::min(device_version, current_version);
}
});
return current_version;
@ -1860,8 +1758,10 @@ bool device_supports_cl_c_version(cl_device_id device, Version version)
for (const auto &name_version : name_versions)
{
Version current_version{ CL_VERSION_MAJOR(name_version.version),
CL_VERSION_MINOR(name_version.version) };
Version current_version{
static_cast<int>(CL_VERSION_MAJOR(name_version.version)),
static_cast<int>(CL_VERSION_MINOR(name_version.version))
};
if (current_version == version)
{
return true;
@ -1891,3 +1791,26 @@ bool poll_until(unsigned timeout_ms, unsigned interval_ms,
return ret;
}
bool device_supports_double(cl_device_id device)
{
if (is_extension_available(device, "cl_khr_fp64"))
{
return true;
}
else
{
cl_device_fp_config double_fp_config;
cl_int err = clGetDeviceInfo(device, CL_DEVICE_DOUBLE_FP_CONFIG,
sizeof(double_fp_config),
&double_fp_config, nullptr);
test_error(err,
"clGetDeviceInfo for CL_DEVICE_DOUBLE_FP_CONFIG failed");
return double_fp_config != 0;
}
}
bool device_supports_half(cl_device_id device)
{
return is_extension_available(device, "cl_khr_fp16");
}

View file

@ -72,24 +72,21 @@ extern int
create_single_kernel_helper(cl_context context, cl_program *outProgram,
cl_kernel *outKernel, unsigned int numKernelLines,
const char **kernelProgram, const char *kernelName,
const char *buildOptions = NULL,
const bool openclCXX = false);
const char *buildOptions = NULL);
extern int create_single_kernel_helper_with_build_options(
cl_context context, cl_program *outProgram, cl_kernel *outKernel,
unsigned int numKernelLines, const char **kernelProgram,
const char *kernelName, const char *buildOptions,
const bool openclCXX = false);
const char *kernelName, const char *buildOptions);
extern int create_single_kernel_helper_create_program(
cl_context context, cl_program *outProgram, unsigned int numKernelLines,
const char **kernelProgram, const char *buildOptions = NULL,
const bool openclCXX = false);
const char **kernelProgram, const char *buildOptions = NULL);
extern int create_single_kernel_helper_create_program_for_device(
cl_context context, cl_device_id device, cl_program *outProgram,
unsigned int numKernelLines, const char **kernelProgram,
const char *buildOptions = NULL, const bool openclCXX = false);
const char *buildOptions = NULL);
/* Creates OpenCL C++ program. This one must be used for creating OpenCL C++
* program. */
@ -162,7 +159,9 @@ size_t get_min_alignment(cl_context context);
/* Helper to obtain the default rounding mode for single precision computation.
* (Double is always CL_FP_ROUND_TO_NEAREST.) Returns 0 on error. */
cl_device_fp_config get_default_rounding_mode(cl_device_id device);
cl_device_fp_config
get_default_rounding_mode(cl_device_id device,
const cl_uint &param = CL_DEVICE_SINGLE_FP_CONFIG);
#define PASSIVE_REQUIRE_IMAGE_SUPPORT(device) \
if (checkForImageSupport(device)) \
@ -181,7 +180,7 @@ cl_device_fp_config get_default_rounding_mode(cl_device_id device);
}
#define PASSIVE_REQUIRE_FP16_SUPPORT(device) \
if (!is_extension_available(device, "cl_khr_fp16")) \
if (!device_supports_half(device)) \
{ \
log_info( \
"\n\tNote: device does not support fp16. Skipping test...\n"); \
@ -211,4 +210,10 @@ bool device_supports_cl_c_version(cl_device_id device, Version version);
bool poll_until(unsigned timeout_ms, unsigned interval_ms,
std::function<bool()> fn);
// Checks whether the device supports double data types
bool device_supports_double(cl_device_id device);
// Checks whether the device supports half data types
bool device_supports_half(cl_device_id device);
#endif // _kernelHelpers_h

View file

@ -277,3 +277,5 @@ double genrand_res53(MTdata d)
unsigned long a = genrand_int32(d) >> 5, b = genrand_int32(d) >> 6;
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
}
bool genrand_bool(MTdata d) { return ((cl_uint)genrand_int32(d) & 1); }

View file

@ -90,24 +90,46 @@ double genrand_res53(MTdata /*data*/);
#ifdef __cplusplus
#include <cassert>
/* generates a random boolean */
bool genrand_bool(MTdata /*data*/);
struct MTdataHolder
{
MTdataHolder(cl_uint seed)
#include <cassert>
#include <utility>
class MTdataHolder {
public:
MTdataHolder() = default;
explicit MTdataHolder(cl_uint seed)
{
m_mtdata = init_genrand(seed);
assert(m_mtdata != nullptr);
}
MTdataHolder(MTdata mtdata): m_mtdata(mtdata) {}
// Forbid copy.
MTdataHolder(const MTdataHolder&) = delete;
MTdataHolder& operator=(const MTdataHolder&) = delete;
~MTdataHolder() { free_mtdata(m_mtdata); }
// Support move semantics.
MTdataHolder(MTdataHolder&& h) { std::swap(m_mtdata, h.m_mtdata); }
MTdataHolder& operator=(MTdataHolder&& h)
{
std::swap(m_mtdata, h.m_mtdata);
return *this;
}
operator MTdata() const { return m_mtdata; }
~MTdataHolder()
{
if (m_mtdata) free_mtdata(m_mtdata);
}
operator MTdata() const
{
assert(m_mtdata && "Object wasn't initialised");
return m_mtdata;
}
private:
MTdata m_mtdata;
MTdata m_mtdata = nullptr;
};
#endif // #ifdef __cplusplus

View file

@ -30,8 +30,17 @@
#if defined(__ANDROID__)
#include <android/api-level.h>
#include "harness/mt19937.h"
#endif
#if !defined(_WIN32)
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
#include <unistd.h>
#endif
#define CHECK_PTR(ptr) \
if ((ptr) == NULL) \
{ \
@ -283,7 +292,7 @@ std::string exe_path()
exit(2);
}; // if
if (len < path.size())
if (static_cast<size_t>(len) < path.size())
{
// We got the path.
path.resize(len);
@ -333,9 +342,6 @@ std::string exe_dir()
#include <windows.h>
#if defined(max)
#undef max
#endif
#include <cctype>
#include <algorithm>
@ -404,7 +410,8 @@ std::string exe_path()
for (;;)
{
DWORD len = GetModuleFileNameA(NULL, &path.front(), path.size());
DWORD len = GetModuleFileNameA(NULL, &path.front(),
static_cast<DWORD>(path.size()));
if (len == 0)
{
@ -558,4 +565,27 @@ char* get_exe_dir()
} // get_exe_dir
char* get_temp_filename()
{
char gFileName[256] = "";
// Create a unique temporary file to allow parallel executed tests.
#if (defined(__linux__) || defined(__APPLE__)) && (!defined(__ANDROID__))
sprintf(gFileName, "/tmp/tmpfile.XXXXXX");
int fd = mkstemp(gFileName);
if (fd == -1) return strdup(gFileName);
close(fd);
#elif defined(_WIN32)
UINT ret = GetTempFileName(".", "tmp", 0, gFileName);
if (ret == 0) return gFileName;
#else
MTdata d = init_genrand((cl_uint)time(NULL));
sprintf(gFileName, "tmpfile.%u", genrand_int32(d));
#endif
char* fn = strdup(gFileName);
CHECK_PTR(fn);
return fn;
}
// end of file //

View file

@ -41,5 +41,7 @@ char* get_err_msg(int err); // Returns system error message. Subject to free.
char* get_dir_sep(); // Returns dir separator. Subject to free.
char* get_exe_path(); // Returns path of current executable. Subject to free.
char* get_exe_dir(); // Returns dir of current executable. Subject to free.
char* get_temp_filename(); // returns temporary file name
#endif // __os_helpers_h__

View file

@ -28,11 +28,14 @@
using namespace std;
#define DEFAULT_COMPILATION_PROGRAM "cl_offline_compiler"
#define DEFAULT_SPIRV_VALIDATOR "spirv-val"
CompilationMode gCompilationMode = kOnline;
CompilationCacheMode gCompilationCacheMode = kCacheModeCompileIfAbsent;
std::string gCompilationCachePath = ".";
std::string gCompilationProgram = DEFAULT_COMPILATION_PROGRAM;
bool gDisableSPIRVValidation = false;
std::string gSPIRVValidator = DEFAULT_SPIRV_VALIDATOR;
void helpInfo()
{
@ -62,7 +65,14 @@ For offline compilation (binary and spir-v modes) only:
Path for offline compiler output and CL source
--compilation-program <prog>
Program to use for offline compilation, defaults to:
)" DEFAULT_COMPILATION_PROGRAM "\n\n");
)" DEFAULT_COMPILATION_PROGRAM R"(
For spir-v mode only:
--disable-spirv-validation
Disable validation of SPIR-V using the SPIR-V validator
--spirv-validator
Path for SPIR-V validator, defaults to )" DEFAULT_SPIRV_VALIDATOR "\n"
"\n");
}
int parseCustomParam(int argc, const char *argv[], const char *ignore)
@ -198,6 +208,26 @@ int parseCustomParam(int argc, const char *argv[], const char *ignore)
return -1;
}
}
else if (!strcmp(argv[i], "--disable-spirv-validation"))
{
delArg++;
gDisableSPIRVValidation = true;
}
else if (!strcmp(argv[i], "--spirv-validator"))
{
delArg++;
if ((i + 1) < argc)
{
delArg++;
gSPIRVValidator = argv[i + 1];
}
else
{
log_error("Program argument for --spirv-validator was not "
"specified.\n");
return -1;
}
}
// cleaning parameters from argv tab
for (int j = i; j < argc - delArg; j++) argv[j] = argv[j + delArg];

View file

@ -38,6 +38,8 @@ extern CompilationMode gCompilationMode;
extern CompilationCacheMode gCompilationCacheMode;
extern std::string gCompilationCachePath;
extern std::string gCompilationProgram;
extern bool gDisableSPIRVValidation;
extern std::string gSPIRVValidator;
extern int parseCustomParam(int argc, const char *argv[],
const char *ignore = 0);

View file

@ -19,6 +19,7 @@
#include <assert.h>
#include <algorithm>
#include <cinttypes>
#include <vector>
static bool findProperty(const std::vector<cl_properties>& props,
@ -97,14 +98,15 @@ int compareProperties(const std::vector<cl_properties>& queried,
if (!found)
{
log_error("ERROR: expected property 0x%x not found!\n",
log_error("ERROR: expected property 0x%" PRIx64 " not found!\n",
check_prop);
return TEST_FAIL;
}
else if (check_value != queried_value)
{
log_error("ERROR: mis-matched value for property 0x%x: wanted "
"0x%x, got 0x%x\n",
log_error("ERROR: mis-matched value for property 0x%" PRIx64
": wanted "
"0x%" PRIx64 ", got 0x%" PRIx64 "\n",
check_prop, check_value, queried_value);
return TEST_FAIL;
}
@ -113,7 +115,7 @@ int compareProperties(const std::vector<cl_properties>& queried,
if (queried.size() > check.size())
{
log_error("ERROR: all properties found but there are extra "
"properties: expected %d, got %d.\n",
"properties: expected %zu, got %zu.\n",
check.size(), queried.size());
return TEST_FAIL;
}

View file

@ -48,7 +48,7 @@ RoundingMode set_round(RoundingMode r, Type outType)
const int *p = int_rounds;
if (outType == kfloat || outType == kdouble) p = flt_rounds;
int fpscr = 0;
int64_t fpscr = 0;
RoundingMode oldRound = get_round();
_FPU_GETCW(fpscr);
@ -59,7 +59,7 @@ RoundingMode set_round(RoundingMode r, Type outType)
RoundingMode get_round(void)
{
int fpscr;
int64_t fpscr;
int oldRound;
_FPU_GETCW(fpscr);
@ -203,13 +203,13 @@ void *FlushToZero(void)
#if defined(__APPLE__) || defined(__linux__) || defined(_WIN32)
#if defined(__i386__) || defined(__x86_64__) || defined(_MSC_VER)
union {
int i;
unsigned int i;
void *p;
} u = { _mm_getcsr() };
_mm_setcsr(u.i | 0x8040);
return u.p;
#elif defined(__arm__) || defined(__aarch64__)
int fpscr;
int64_t fpscr;
_FPU_GETCW(fpscr);
_FPU_SETCW(fpscr | FPSCR_FZ);
return NULL;
@ -239,7 +239,7 @@ void UnFlushToZero(void *p)
} u = { p };
_mm_setcsr(u.i);
#elif defined(__arm__) || defined(__aarch64__)
int fpscr;
int64_t fpscr;
_FPU_GETCW(fpscr);
_FPU_SETCW(fpscr & ~FPSCR_FZ);
#elif defined(__PPC__)

View file

@ -16,8 +16,6 @@
#ifndef __ROUNDING_MODE_H__
#define __ROUNDING_MODE_H__
#pragma STDC FENV_ACCESS ON
#include "compat.h"
#if (defined(_WIN32) && defined(_MSC_VER))

View file

@ -22,7 +22,6 @@
#include <cassert>
#include <stdexcept>
#include <vector>
#include "threadTesting.h"
#include "errorHelpers.h"
#include "kernelHelpers.h"
#include "fpcontrol.h"
@ -60,6 +59,54 @@ bool gCoreILProgram = true;
#define DEFAULT_NUM_ELEMENTS 0x4000
static int saveResultsToJson(const char *suiteName, test_definition testList[],
unsigned char selectedTestList[],
test_status resultTestList[], int testNum)
{
char *fileName = getenv("CL_CONFORMANCE_RESULTS_FILENAME");
if (fileName == nullptr)
{
return EXIT_SUCCESS;
}
FILE *file = fopen(fileName, "w");
if (NULL == file)
{
log_error("ERROR: Failed to open '%s' for writing results.\n",
fileName);
return EXIT_FAILURE;
}
const char *save_map[] = { "success", "failure" };
const char *result_map[] = { "pass", "fail", "skip" };
const char *linebreak[] = { "", ",\n" };
int add_linebreak = 0;
fprintf(file, "{\n");
fprintf(file, "\t\"cmd\": \"%s\",\n", suiteName);
fprintf(file, "\t\"results\": {\n");
for (int i = 0; i < testNum; ++i)
{
if (selectedTestList[i])
{
fprintf(file, "%s\t\t\"%s\": \"%s\"", linebreak[add_linebreak],
testList[i].name, result_map[(int)resultTestList[i]]);
add_linebreak = 1;
}
}
fprintf(file, "\n");
fprintf(file, "\t}\n");
fprintf(file, "}\n");
int ret = fclose(file) ? EXIT_FAILURE : EXIT_SUCCESS;
log_info("Saving results to %s: %s!\n", fileName, save_map[ret]);
return ret;
}
int runTestHarness(int argc, const char *argv[], int testNum,
test_definition testList[], int forceNoContextCreation,
cl_command_queue_properties queueProps)
@ -68,19 +115,28 @@ int runTestHarness(int argc, const char *argv[], int testNum,
forceNoContextCreation, queueProps, NULL);
}
int skip_init_info(int count)
int suite_did_not_pass_init(const char *suiteName, test_status status,
int testNum, test_definition testList[])
{
log_info("Test skipped while initialization\n");
log_info("SKIPPED %d of %d tests.\n", count, count);
return EXIT_SUCCESS;
std::vector<unsigned char> selectedTestList(testNum, 1);
std::vector<test_status> resultTestList(testNum, status);
int ret = saveResultsToJson(suiteName, testList, selectedTestList.data(),
resultTestList.data(), testNum);
log_info("Test %s while initialization\n",
status == TEST_SKIP ? "skipped" : "failed");
log_info("%s %d of %d tests.\n", status == TEST_SKIP ? "SKIPPED" : "FAILED",
testNum, testNum);
if (ret != EXIT_SUCCESS)
{
return ret;
}
return status == TEST_SKIP ? EXIT_SUCCESS : EXIT_FAILURE;
}
int fail_init_info(int count)
{
log_info("Test failed while initialization\n");
log_info("FAILED %d of %d tests.\n", count, count);
return EXIT_FAILURE;
}
void version_expected_info(const char *test_name, const char *api_name,
const char *expected_version,
const char *device_version)
@ -470,6 +526,7 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
log_error("Invalid device address bit size returned by device.\n");
return EXIT_FAILURE;
}
const char *suiteName = argv[0];
if (gCompilationMode == kSpir_v)
{
test_status spirv_readiness = check_spirv_compilation_readiness(device);
@ -478,9 +535,15 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
switch (spirv_readiness)
{
case TEST_PASS: break;
case TEST_FAIL: return fail_init_info(testNum);
case TEST_SKIP: return skip_init_info(testNum);
case TEST_SKIPPED_ITSELF: return skip_init_info(testNum);
case TEST_FAIL:
return suite_did_not_pass_init(suiteName, TEST_FAIL,
testNum, testList);
case TEST_SKIP:
return suite_did_not_pass_init(suiteName, TEST_SKIP,
testNum, testList);
case TEST_SKIPPED_ITSELF:
return suite_did_not_pass_init(suiteName, TEST_SKIP,
testNum, testList);
}
}
}
@ -492,9 +555,15 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
switch (status)
{
case TEST_PASS: break;
case TEST_FAIL: return fail_init_info(testNum);
case TEST_SKIP: return skip_init_info(testNum);
case TEST_SKIPPED_ITSELF: return skip_init_info(testNum);
case TEST_FAIL:
return suite_did_not_pass_init(suiteName, TEST_FAIL, testNum,
testList);
case TEST_SKIP:
return suite_did_not_pass_init(suiteName, TEST_SKIP, testNum,
testList);
case TEST_SKIPPED_ITSELF:
return suite_did_not_pass_init(suiteName, TEST_SKIP, testNum,
testList);
}
}
@ -574,49 +643,6 @@ static int find_matching_tests(test_definition testList[],
return EXIT_SUCCESS;
}
static int saveResultsToJson(const char *fileName, const char *suiteName,
test_definition testList[],
unsigned char selectedTestList[],
test_status resultTestList[], int testNum)
{
FILE *file = fopen(fileName, "w");
if (NULL == file)
{
log_error("ERROR: Failed to open '%s' for writing results.\n",
fileName);
return EXIT_FAILURE;
}
const char *save_map[] = { "success", "failure" };
const char *result_map[] = { "pass", "fail", "skip" };
const char *linebreak[] = { "", ",\n" };
int add_linebreak = 0;
fprintf(file, "{\n");
fprintf(file, "\t\"cmd\": \"%s\",\n", suiteName);
fprintf(file, "\t\"results\": {\n");
for (int i = 0; i < testNum; ++i)
{
if (selectedTestList[i])
{
fprintf(file, "%s\t\t\"%s\": \"%s\"", linebreak[add_linebreak],
testList[i].name, result_map[(int)resultTestList[i]]);
add_linebreak = 1;
}
}
fprintf(file, "\n");
fprintf(file, "\t}\n");
fprintf(file, "}\n");
int ret = fclose(file) ? 1 : 0;
log_info("Saving results to %s: %s!\n", fileName, save_map[ret]);
return ret;
}
static void print_results(int failed, int count, const char *name)
{
if (count < failed)
@ -658,7 +684,6 @@ int parseAndCallCommandLineTests(int argc, const char *argv[],
int ret = EXIT_SUCCESS;
unsigned char *selectedTestList = (unsigned char *)calloc(testNum, 1);
test_status *resultTestList = NULL;
if (argc == 1)
{
@ -697,24 +722,19 @@ int parseAndCallCommandLineTests(int argc, const char *argv[],
if (ret == EXIT_SUCCESS)
{
resultTestList =
(test_status *)calloc(testNum, sizeof(*resultTestList));
std::vector<test_status> resultTestList(testNum, TEST_PASS);
callTestFunctions(testList, selectedTestList, resultTestList, testNum,
device, forceNoContextCreation, num_elements,
callTestFunctions(testList, selectedTestList, resultTestList.data(),
testNum, device, forceNoContextCreation, num_elements,
queueProps);
print_results(gFailCount, gTestCount, "sub-test");
print_results(gTestsFailed, gTestsFailed + gTestsPassed, "test");
char *filename = getenv("CL_CONFORMANCE_RESULTS_FILENAME");
if (filename != NULL)
{
ret = saveResultsToJson(filename, argv[0], testList,
selectedTestList, resultTestList, testNum);
}
ret = saveResultsToJson(argv[0], testList, selectedTestList,
resultTestList.data(), testNum);
if (std::any_of(resultTestList, resultTestList + testNum,
if (std::any_of(resultTestList.begin(), resultTestList.end(),
[](test_status result) {
switch (result)
{
@ -730,7 +750,6 @@ int parseAndCallCommandLineTests(int argc, const char *argv[],
}
free(selectedTestList);
free(resultTestList);
return ret;
}
@ -783,6 +802,14 @@ test_status callSingleTestFunction(test_definition test,
return TEST_SKIP;
}
if (!check_functions_for_offline_compiler(test.name))
{
log_info("Subtest %s tests is not supported in offline compiler "
"execution path!\n",
test.name);
return TEST_SKIP;
}
/* Create a context to work with, unless we're told not to */
if (!forceNoContextCreation)
{
@ -791,6 +818,8 @@ test_status callSingleTestFunction(test_definition test,
if (!context)
{
print_error(error, "Unable to create testing context");
gFailCount++;
gTestsFailed++;
return TEST_FAIL;
}
@ -812,14 +841,14 @@ test_status callSingleTestFunction(test_definition test,
if (queue == NULL)
{
print_error(error, "Unable to create testing command queue");
clReleaseContext(context);
gFailCount++;
gTestsFailed++;
return TEST_FAIL;
}
}
/* Run the test and print the result */
error = check_functions_for_offline_compiler(test.name, deviceToUse);
test_missing_support_offline_cmpiler(error, test.name);
if (test.func == NULL)
{
// Skip unimplemented test, can happen when all of the tests are
@ -861,7 +890,9 @@ test_status callSingleTestFunction(test_definition test,
int error = clFinish(queue);
if (error)
{
log_error("clFinish failed: %d", error);
log_error("clFinish failed: %s\n", IGetErrorString(error));
gFailCount++;
gTestsFailed++;
status = TEST_FAIL;
}
clReleaseCommandQueue(queue);
@ -1172,7 +1203,7 @@ cl_platform_id getPlatformFromDevice(cl_device_id deviceID)
void PrintArch(void)
{
vlog("sizeof( void*) = %ld\n", sizeof(void *));
vlog("sizeof( void*) = %zu\n", sizeof(void *));
#if defined(__ppc__)
vlog("ARCH:\tppc\n");
#elif defined(__ppc64__)

View file

@ -16,7 +16,6 @@
#ifndef _testHarness_h
#define _testHarness_h
#include "threadTesting.h"
#include "clImageHelper.h"
#include <string>
#include <sstream>
@ -67,9 +66,12 @@ Version get_device_cl_version(cl_device_id device);
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
typedef int (*test_function_pointer)(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
typedef struct test_definition
{
basefn func;
test_function_pointer func;
const char *name;
Version min_version;
} test_definition;

View file

@ -1,98 +0,0 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "compat.h"
#include "threadTesting.h"
#include "errorHelpers.h"
#include <stdio.h>
#include <string.h>
#if !defined(_WIN32)
#include <pthread.h>
#endif
#if 0 // Disabed for now
typedef struct
{
basefn mFunction;
cl_device_id mDevice;
cl_context mContext;
int mNumElements;
} TestFnArgs;
////////////////////////////////////////////////////////////////////////////////
// Thread-based testing. Spawns a new thread to run the given test function,
// then waits for it to complete. The entire idea is that, if the thread crashes,
// we can catch it and report it as a failure instead of crashing the entire suite
////////////////////////////////////////////////////////////////////////////////
void *test_thread_wrapper( void *data )
{
TestFnArgs *args;
int retVal;
cl_context context;
args = (TestFnArgs *)data;
/* Create a new context to use (contexts can't cross threads) */
context = clCreateContext(NULL, args->mDeviceGroup);
if( context == NULL )
{
log_error("clCreateContext failed for new thread\n");
return (void *)(-1);
}
/* Call function */
retVal = args->mFunction( args->mDeviceGroup, args->mDevice, context, args->mNumElements );
clReleaseContext( context );
return (void *)retVal;
}
int test_threaded_function( basefn fnToTest, cl_device_id device, cl_context context, cl_command_queue queue, int numElements )
{
int error;
pthread_t threadHdl;
void *retVal;
TestFnArgs args;
args.mFunction = fnToTest;
args.mDeviceGroup = deviceGroup;
args.mDevice = device;
args.mContext = context;
args.mNumElements = numElements;
error = pthread_create( &threadHdl, NULL, test_thread_wrapper, (void *)&args );
if( error != 0 )
{
log_error( "ERROR: Unable to create thread for testing!\n" );
return -1;
}
/* Thread has been started, now just wait for it to complete (or crash) */
error = pthread_join( threadHdl, &retVal );
if( error != 0 )
{
log_error( "ERROR: Unable to join testing thread!\n" );
return -1;
}
return (int)((intptr_t)retVal);
}
#endif

View file

@ -1,31 +0,0 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _threadTesting_h
#define _threadTesting_h
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/opencl.h>
#endif
typedef int (*basefn)(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_threaded_function(basefn fnToTest, cl_device_id device,
cl_context context, cl_command_queue queue,
int numElements);
#endif // _threadTesting_h

View file

@ -16,123 +16,135 @@
#ifndef _typeWrappers_h
#define _typeWrappers_h
#include <stdio.h>
#include <stdlib.h>
#if !defined(_WIN32)
#include <sys/mman.h>
#endif
#include "compat.h"
#include <stdio.h>
#include "mt19937.h"
#include "errorHelpers.h"
#include "kernelHelpers.h"
/* cl_context wrapper */
#include <cstdlib>
#include <type_traits>
class clContextWrapper {
public:
clContextWrapper() { mContext = NULL; }
clContextWrapper(cl_context program) { mContext = program; }
~clContextWrapper()
namespace wrapper_details {
// clRetain*() and clRelease*() functions share the same type.
template <typename T> // T should be cl_context, cl_program, ...
using RetainReleaseType = cl_int CL_API_CALL(T);
// A generic wrapper class that follows OpenCL retain/release semantics.
//
// This Wrapper class implement copy and move semantics, which makes it
// compatible with standard containers for example.
//
// Template parameters:
// - T is the cl_* type (e.g. cl_context, cl_program, ...)
// - Retain is the clRetain* function (e.g. clRetainContext, ...)
// - Release is the clRelease* function (e.g. clReleaseContext, ...)
template <typename T, RetainReleaseType<T> Retain, RetainReleaseType<T> Release>
class Wrapper {
static_assert(std::is_pointer<T>::value, "T should be a pointer type.");
T object = nullptr;
void retain()
{
if (mContext != NULL) clReleaseContext(mContext);
if (!object) return;
auto err = Retain(object);
if (err != CL_SUCCESS)
{
print_error(err, "clRetain*() failed");
std::abort();
}
}
clContextWrapper &operator=(const cl_context &rhs)
void release()
{
mContext = rhs;
if (!object) return;
auto err = Release(object);
if (err != CL_SUCCESS)
{
print_error(err, "clRelease*() failed");
std::abort();
}
}
public:
Wrapper() = default;
// On initialisation, assume the object has a refcount of one.
Wrapper(T object): object(object) {}
// On assignment, assume the object has a refcount of one.
Wrapper &operator=(T rhs)
{
reset(rhs);
return *this;
}
operator cl_context() const { return mContext; }
cl_context *operator&() { return &mContext; }
bool operator==(const cl_context &rhs) { return mContext == rhs; }
protected:
cl_context mContext;
};
/* cl_program wrapper */
class clProgramWrapper {
public:
clProgramWrapper() { mProgram = NULL; }
clProgramWrapper(cl_program program) { mProgram = program; }
~clProgramWrapper()
// Copy semantics, increase retain count.
Wrapper(Wrapper const &w) { *this = w; }
Wrapper &operator=(Wrapper const &w)
{
if (mProgram != NULL) clReleaseProgram(mProgram);
}
clProgramWrapper &operator=(const cl_program &rhs)
{
mProgram = rhs;
reset(w.object);
retain();
return *this;
}
operator cl_program() const { return mProgram; }
cl_program *operator&() { return &mProgram; }
bool operator==(const cl_program &rhs) { return mProgram == rhs; }
protected:
cl_program mProgram;
};
/* cl_kernel wrapper */
class clKernelWrapper {
public:
clKernelWrapper() { mKernel = NULL; }
clKernelWrapper(cl_kernel kernel) { mKernel = kernel; }
~clKernelWrapper()
// Move semantics, directly take ownership.
Wrapper(Wrapper &&w) { *this = std::move(w); }
Wrapper &operator=(Wrapper &&w)
{
if (mKernel != NULL) clReleaseKernel(mKernel);
}
clKernelWrapper &operator=(const cl_kernel &rhs)
{
mKernel = rhs;
reset(w.object);
w.object = nullptr;
return *this;
}
operator cl_kernel() const { return mKernel; }
cl_kernel *operator&() { return &mKernel; }
~Wrapper() { reset(); }
bool operator==(const cl_kernel &rhs) { return mKernel == rhs; }
protected:
cl_kernel mKernel;
};
/* cl_mem (stream) wrapper */
class clMemWrapper {
public:
clMemWrapper() { mMem = NULL; }
clMemWrapper(cl_mem mem) { mMem = mem; }
~clMemWrapper()
// Release the existing object, if any, and own the new one, if any.
void reset(T new_object = nullptr)
{
if (mMem != NULL) clReleaseMemObject(mMem);
release();
object = new_object;
}
clMemWrapper &operator=(const cl_mem &rhs)
{
mMem = rhs;
return *this;
}
operator cl_mem() const { return mMem; }
operator T() const { return object; }
cl_mem *operator&() { return &mMem; }
bool operator==(const cl_mem &rhs) { return mMem == rhs; }
protected:
cl_mem mMem;
// Ideally this function should not exist as it breaks encapsulation by
// allowing external mutation of the Wrapper internal state. However, too
// much code currently relies on this. For example, instead of using T* as
// output parameters, existing code can be updated to use Wrapper& instead.
T *operator&() { return &object; }
};
} // namespace wrapper_details
using clContextWrapper =
wrapper_details::Wrapper<cl_context, clRetainContext, clReleaseContext>;
using clProgramWrapper =
wrapper_details::Wrapper<cl_program, clRetainProgram, clReleaseProgram>;
using clKernelWrapper =
wrapper_details::Wrapper<cl_kernel, clRetainKernel, clReleaseKernel>;
using clMemWrapper =
wrapper_details::Wrapper<cl_mem, clRetainMemObject, clReleaseMemObject>;
using clCommandQueueWrapper =
wrapper_details::Wrapper<cl_command_queue, clRetainCommandQueue,
clReleaseCommandQueue>;
using clSamplerWrapper =
wrapper_details::Wrapper<cl_sampler, clRetainSampler, clReleaseSampler>;
using clEventWrapper =
wrapper_details::Wrapper<cl_event, clRetainEvent, clReleaseEvent>;
class clProtectedImage {
public:
clProtectedImage()
@ -183,92 +195,12 @@ public:
cl_mem *operator&() { return &image; }
bool operator==(const cl_mem &rhs) { return image == rhs; }
protected:
void *backingStore;
size_t backingStoreSize;
cl_mem image;
};
/* cl_command_queue wrapper */
class clCommandQueueWrapper {
public:
clCommandQueueWrapper() { mMem = NULL; }
clCommandQueueWrapper(cl_command_queue mem) { mMem = mem; }
~clCommandQueueWrapper()
{
if (mMem != NULL)
{
clReleaseCommandQueue(mMem);
}
}
clCommandQueueWrapper &operator=(const cl_command_queue &rhs)
{
mMem = rhs;
return *this;
}
operator cl_command_queue() const { return mMem; }
cl_command_queue *operator&() { return &mMem; }
bool operator==(const cl_command_queue &rhs) { return mMem == rhs; }
protected:
cl_command_queue mMem;
};
/* cl_sampler wrapper */
class clSamplerWrapper {
public:
clSamplerWrapper() { mMem = NULL; }
clSamplerWrapper(cl_sampler mem) { mMem = mem; }
~clSamplerWrapper()
{
if (mMem != NULL) clReleaseSampler(mMem);
}
clSamplerWrapper &operator=(const cl_sampler &rhs)
{
mMem = rhs;
return *this;
}
operator cl_sampler() const { return mMem; }
cl_sampler *operator&() { return &mMem; }
bool operator==(const cl_sampler &rhs) { return mMem == rhs; }
protected:
cl_sampler mMem;
};
/* cl_event wrapper */
class clEventWrapper {
public:
clEventWrapper() { mMem = NULL; }
clEventWrapper(cl_event mem) { mMem = mem; }
~clEventWrapper()
{
if (mMem != NULL) clReleaseEvent(mMem);
}
clEventWrapper &operator=(const cl_event &rhs)
{
mMem = rhs;
return *this;
}
operator cl_event() const { return mMem; }
cl_event *operator&() { return &mMem; }
bool operator==(const cl_event &rhs) { return mMem == rhs; }
protected:
cl_event mMem;
};
/* Generic protected memory buffer, for verifying access within bounds */
class clProtectedArray {
public:

View file

@ -50,11 +50,12 @@ add_subdirectory( subgroups )
add_subdirectory( workgroups )
add_subdirectory( pipes )
add_subdirectory( device_timer )
if(KHRONOS_OFFLINE_COMPILER)
add_subdirectory( clcpp )
endif()
add_subdirectory( spirv_new )
add_subdirectory( spir )
if(VULKAN_IS_SUPPORTED)
add_subdirectory( common/vulkan_wrapper )
add_subdirectory( vulkan )
endif()
file(GLOB CSV_FILES "opencl_conformance_tests_*.csv")

View file

@ -1,4 +1,3 @@
set(CMAKE_CXX_STANDARD 11)
set(MODULE_NAME SVM)
set(${MODULE_NAME}_SOURCES

View file

@ -58,7 +58,6 @@ int test_svm_byte_granularity(cl_device_id deviceID, cl_context c, cl_command_qu
cl_uint num_devices = 0;
cl_int err = CL_SUCCESS;
cl_int rval = CL_SUCCESS;
err = create_cl_objects(deviceID, &byte_manipulation_kernels[0], &context, &program, &queues[0], &num_devices, CL_DEVICE_SVM_FINE_GRAIN_BUFFER);
if(err == 1) return 0; // no devices capable of requested SVM level, so don't execute but count test as passing.

View file

@ -162,7 +162,8 @@ int test_svm_cross_buffer_pointers_coarse_grain(cl_device_id deviceID, cl_contex
test_error(error, "clCreateBuffer failed.");
// this buffer holds the index into the nodes buffer that is used for node allocation
clMemWrapper allocator = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int), NULL, &error);
clMemWrapper allocator = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(size_t), NULL, &error);
test_error(error, "clCreateBuffer failed.");
// this buffer holds the count of correct nodes which is computed by the verify kernel.

View file

@ -78,9 +78,6 @@ int test_svm_migrate(cl_device_id deviceID, cl_context c, cl_command_queue queue
cl_uint amem[GLOBAL_SIZE];
cl_uint bmem[GLOBAL_SIZE];
cl_uint cmem[GLOBAL_SIZE];
cl_uint ramem[GLOBAL_SIZE];
cl_uint rbmem[GLOBAL_SIZE];
cl_uint rcmem[GLOBAL_SIZE];
cl_event evs[20];
const size_t global_size = GLOBAL_SIZE;

View file

@ -57,7 +57,6 @@ cl_int create_linked_lists_on_host(cl_command_queue cmdq, cl_mem nodes, Node *pN
cl_int verify_linked_lists_on_host(int ci, cl_command_queue cmdq, cl_mem nodes, Node *pNodes2, cl_int ListLength, size_t numLists, cl_bool useNewAPI )
{
cl_int error = CL_SUCCESS;
cl_int correct_count;
Node *pNodes;
if (useNewAPI == CL_FALSE)
@ -72,8 +71,6 @@ cl_int verify_linked_lists_on_host(int ci, cl_command_queue cmdq, cl_mem nodes,
test_error2(error, pNodes, "clEnqueueSVMMap failed");
}
correct_count = 0;
error = verify_linked_lists(pNodes, numLists, ListLength);
if(error) return -1;
@ -98,7 +95,9 @@ cl_int create_linked_lists_on_device(int ci, cl_command_queue cmdq, cl_mem alloc
cl_int error = CL_SUCCESS;
log_info("SVM: creating linked list on device: %d ", ci);
size_t *pAllocator = (size_t*) clEnqueueMapBuffer(cmdq, allocator, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, sizeof(cl_int), 0, NULL,NULL, &error);
size_t *pAllocator = (size_t *)clEnqueueMapBuffer(
cmdq, allocator, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, sizeof(size_t),
0, NULL, NULL, &error);
test_error2(error, pAllocator, "clEnqueueMapBuffer failed");
// reset allocator index
*pAllocator = numLists; // the first numLists elements of the nodes array are already allocated (they hold the head of each list).
@ -206,7 +205,9 @@ int shared_address_space_coarse_grain(cl_device_id deviceID, cl_context context2
}
// this buffer holds an index into the nodes buffer, it is used for node allocation
clMemWrapper allocator = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int), NULL, &error);
clMemWrapper allocator = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(size_t), NULL, &error);
test_error(error, "clCreateBuffer failed.");
error = clGetMemObjectInfo(allocator, CL_MEM_USES_SVM_POINTER, sizeof(cl_bool), &usesSVMpointer, 0);

View file

@ -47,7 +47,7 @@ int test_svm_shared_address_space_fine_grain(cl_device_id deviceID, cl_context c
test_error2(error, pNodes, "malloc failed");
// this allocation holds an index into the nodes buffer, it is used for node allocation
size_t* pAllocator = (size_t*) align_malloc(sizeof(cl_int), 128);
size_t *pAllocator = (size_t *)align_malloc(sizeof(size_t), 128);
test_error2(error, pAllocator, "malloc failed");
// this allocation holds the count of correct nodes, which is computed by the verify kernel.

View file

@ -182,7 +182,8 @@ int test_svm_shared_sub_buffers(cl_device_id deviceID, cl_context context2, cl_c
// this buffer holds the index into the nodes buffer that is used for node allocation
clMemWrapper allocator = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int), NULL, &error);
clMemWrapper allocator = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(size_t), NULL, &error);
test_error(error, "clCreateBuffer failed.");
// this buffer holds the count of correct nodes which is computed by the verify kernel.

View file

@ -200,8 +200,10 @@ int fill_image_with_data(cl_context context, cl_device_id device_id, cl_command_
result = clFinish(*queue);
if (result != SUCCEEDED)
{
print_error(error, "clFinish failed after successful enquing filling buffer with data.");
return result;
print_error(error,
"clFinish failed after successful enqueuing filling "
"buffer with data.");
return result;
}
} else {
error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);

View file

@ -37,8 +37,8 @@ int find_good_image_size(cl_device_id device_id, size_t size_to_allocate, size_t
}
if (size_to_allocate == 0) {
log_error("Trying to allcoate a zero sized image.\n");
return FAILED_ABORT;
log_error("Trying to allocate a zero sized image.\n");
return FAILED_ABORT;
}
error = clGetDeviceInfo( device_id, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( max_width ), &max_width, NULL );

View file

@ -112,6 +112,8 @@ int doTest( cl_device_id device, cl_context context, cl_command_queue queue, All
int number_of_mems_used;
cl_ulong max_individual_allocation_size = g_max_individual_allocation_size;
cl_ulong global_mem_size = g_global_mem_size ;
const bool allocate_image =
(alloc_type != BUFFER) && (alloc_type != BUFFER_NON_BLOCKING);
static const char* alloc_description[] = {
"buffer(s)",
@ -123,7 +125,7 @@ int doTest( cl_device_id device, cl_context context, cl_command_queue queue, All
};
// Skip image tests if we don't support images on the device
if( alloc_type > BUFFER && checkForImageSupport( device ) )
if (allocate_image && checkForImageSupport(device))
{
log_info( "Can not test image allocation because device does not support images.\n" );
return 0;
@ -132,7 +134,7 @@ int doTest( cl_device_id device, cl_context context, cl_command_queue queue, All
// This section was added in order to fix a bug in the test
// If CL_DEVICE_MAX_MEM_ALLOC_SIZE is much grater than CL_DEVICE_IMAGE2D_MAX_WIDTH * CL_DEVICE_IMAGE2D_MAX_HEIGHT
// The test will fail in image allocations as the size requested for the allocation will be much grater than the maximum size allowed for image
if( ( alloc_type != BUFFER ) && ( alloc_type != BUFFER_NON_BLOCKING ) )
if (allocate_image)
{
size_t max_width, max_height;

View file

@ -14,6 +14,7 @@ set(${MODULE_NAME}_SOURCES
test_api_min_max.cpp
test_kernel_arg_changes.cpp
test_kernel_arg_multi_setup.cpp
test_kernel_attributes.cpp
test_binary.cpp
test_native_kernel.cpp
test_mem_objects.cpp
@ -21,7 +22,6 @@ set(${MODULE_NAME}_SOURCES
test_device_min_data_type_align_size_alignment.cpp
test_platform.cpp
test_kernel_arg_info.cpp
test_kernel_arg_info_compatibility.cpp
test_null_buffer_arg.cpp
test_mem_object_info.cpp
test_min_image_formats.cpp

View file

@ -51,7 +51,6 @@ test_definition test_list[] = {
ADD_TEST(load_two_kernels_manually),
ADD_TEST(get_program_info_kernel_names),
ADD_TEST(get_kernel_arg_info),
ADD_TEST(get_kernel_arg_info_compatibility),
ADD_TEST(create_kernels_in_program),
ADD_TEST(get_kernel_info),
ADD_TEST(kernel_private_memory_size),
@ -60,6 +59,7 @@ test_definition test_list[] = {
ADD_TEST(set_kernel_arg_constant),
ADD_TEST(set_kernel_arg_struct_array),
ADD_TEST(kernel_global_constant),
ADD_TEST(kernel_attributes),
ADD_TEST(min_max_thread_dimensions),
ADD_TEST(min_max_work_items_sizes),

View file

@ -42,26 +42,9 @@ int test_negative_get_platform_info(cl_device_id deviceID, cl_context context,
{
cl_platform_id platform = getPlatformFromDevice(deviceID);
cl_int err = clGetPlatformInfo(nullptr, CL_PLATFORM_VERSION, sizeof(char*),
nullptr, nullptr);
test_failure_error_ret(
err, CL_INVALID_PLATFORM,
"clGetPlatformInfo should return CL_INVALID_PLATFORM when: \"platform "
"is not a valid platform\" using a nullptr",
TEST_FAIL);
err =
clGetPlatformInfo(reinterpret_cast<cl_platform_id>(deviceID),
CL_PLATFORM_VERSION, sizeof(char*), nullptr, nullptr);
test_failure_error_ret(
err, CL_INVALID_PLATFORM,
"clGetPlatformInfo should return CL_INVALID_PLATFORM when: \"platform "
"is not a valid platform\" using a valid object which is NOT a "
"platform",
TEST_FAIL);
constexpr cl_platform_info INVALID_PARAM_VALUE = 0;
err = clGetPlatformInfo(platform, INVALID_PARAM_VALUE, 0, nullptr, nullptr);
cl_int err =
clGetPlatformInfo(platform, INVALID_PARAM_VALUE, 0, nullptr, nullptr);
test_failure_error_ret(
err, CL_INVALID_VALUE,
"clGetPlatformInfo should return CL_INVALID_VALUE when: \"param_name "

View file

@ -119,7 +119,6 @@ extern int test_get_image1d_info( cl_device_id deviceID, cl_context context
extern int test_get_image1d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
extern int test_get_image2d_array_info( cl_device_id deviceID, cl_context context, cl_command_queue ignoreQueue, int num_elements );
extern int test_get_kernel_arg_info( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_get_kernel_arg_info_compatibility( cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements );
extern int test_queue_hint(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
@ -203,3 +202,5 @@ extern int test_negative_get_platform_ids(cl_device_id deviceID,
cl_context context,
cl_command_queue queue,
int num_elements);
extern int test_kernel_attributes(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);

View file

@ -647,7 +647,7 @@ int test_consistency_read_write_images(cl_device_id deviceID,
CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE3D,
CL_MEM_OBJECT_IMAGE1D_ARRAY, CL_MEM_OBJECT_IMAGE2D_ARRAY,
};
for (int i = 0; i < ARRAY_SIZE(image_types); i++)
for (size_t i = 0; i < ARRAY_SIZE(image_types); i++)
{
cl_uint numImageFormats = 0;
error = clGetSupportedImageFormats(
@ -801,7 +801,7 @@ int test_consistency_depth_images(cl_device_id deviceID, cl_context context,
CL_MEM_READ_WRITE,
CL_MEM_KERNEL_READ_AND_WRITE,
};
for (int i = 0; i < ARRAY_SIZE(mem_flags); i++)
for (size_t i = 0; i < ARRAY_SIZE(mem_flags); i++)
{
cl_uint numImageFormats = 0;
error = clGetSupportedImageFormats(context, mem_flags[i],
@ -1114,7 +1114,7 @@ int test_consistency_3d_image_writes(cl_device_id deviceID, cl_context context,
CL_MEM_READ_WRITE,
CL_MEM_KERNEL_READ_AND_WRITE,
};
for (int i = 0; i < ARRAY_SIZE(mem_flags); i++)
for (size_t i = 0; i < ARRAY_SIZE(mem_flags); i++)
{
cl_uint numImageFormats = 0;
error = clGetSupportedImageFormats(context, mem_flags[i],

File diff suppressed because it is too large Load diff

View file

@ -94,18 +94,6 @@ struct structArg
float f;
};
static unsigned char *
generate_8888_image(int w, int h, MTdata d)
{
unsigned char *ptr = (unsigned char*)malloc(w * h * 4);
int i;
for (i=0; i<w*h*4; i++)
ptr[i] = (unsigned char)genrand_int32( d);
return ptr;
}
int test_image_arg_shallow_clone(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements, void* pbufRes, clMemWrapper& bufOut)
{
int error;
@ -323,6 +311,14 @@ int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queu
clKernelWrapper clonek = clCloneKernel(kernel, &error);
test_error( error, "clCloneKernel failed." );
// enqueue the kernel before the last arg is set
error = clEnqueueNDRangeKernel(queue, clonek, 1, NULL, &ndrange1, NULL, 0,
NULL, NULL);
test_failure_error(error, CL_INVALID_KERNEL_ARGS,
"A kernel cloned before all args are set should return "
"CL_INVALID_KERNEL_ARGS if enqueued before the "
"remaining args are set");
// set the last arg and enqueue
error = clSetKernelArg(clonek, 4, sizeof(cl_mem), &bufOut);
test_error( error, "clSetKernelArg failed." );

View file

@ -52,12 +52,7 @@ int test_context_destructor_callback(cl_device_id deviceID, cl_context context,
test_error(error, "Unable to set destructor callback");
// Now release the context, which SHOULD call the callbacks
error = clReleaseContext(localContext);
test_error(error, "Unable to release local context");
// Note: since we manually released the context, we need to set it to NULL
// to prevent a double-release
localContext = NULL;
localContext.reset();
// At this point, all three callbacks should have already been called
int numErrors = 0;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,339 @@
//
// Copyright (c) 2020 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include "procs.h"
#include "harness/errorHelpers.h"
#include "harness/typeWrappers.h"
#include "harness/parseParameters.h"
using KernelAttributes = std::vector<std::string>;
static std::string generate_kernel_source(const KernelAttributes& attributes)
{
std::string kernel;
for (auto attribute : attributes)
{
kernel += "__attribute__((" + attribute + "))\n";
}
kernel += "__kernel void test_kernel(){}";
return kernel;
}
using AttributePermutations = std::vector<KernelAttributes>;
// The following combinations have been chosen as they place each of the
// attribute types in the different orders that they can occur. While distinct
// permutations would provide a complete overview of the API the sheer number of
// combinations increases the runtime of this test by an unreasonable amount
AttributePermutations vect_tests;
AttributePermutations work_tests;
AttributePermutations reqd_tests;
AttributePermutations vect_reqd_tests;
AttributePermutations work_vect_tests;
AttributePermutations reqd_work_tests;
AttributePermutations vect_work_reqd_tests;
AttributePermutations work_reqd_vect_tests;
AttributePermutations reqd_vect_work_tests;
// Generate a vector with vec_type_hint(<data_type>) so that it can be used to
// generate different kernels
static KernelAttributes generate_vec_type_hint_data(cl_device_id deviceID)
{
KernelAttributes vec_type_hint_data;
// TODO Test for signed vectors (char/short/int/etc)
std::vector<std::string> vector_types = { "uchar", "ushort", "uint",
"float" };
if (gHasLong)
{
vector_types.push_back("ulong");
}
if (device_supports_half(deviceID))
{
vector_types.push_back("half");
}
if (device_supports_double(deviceID))
{
vector_types.push_back("double");
}
const auto vector_sizes = { "2", "3", "4", "8", "16" };
for (auto type : vector_types)
{
for (auto size : vector_sizes)
{
vec_type_hint_data.push_back("vec_type_hint(" + type + size + ")");
}
}
return vec_type_hint_data;
}
struct WorkGroupDimensions
{
int x;
int y;
int z;
};
// Generate vectors to store reqd_work_group_size(<dimensions>) and
// work_group_size_hint(<dimensions>) so that they can be used to generate
// different kernels
static KernelAttributes generate_reqd_work_group_size_data(
const std::vector<WorkGroupDimensions>& work_group_dimensions)
{
KernelAttributes reqd_work_group_size_data;
for (auto dimension : work_group_dimensions)
{
reqd_work_group_size_data.push_back(
"reqd_work_group_size(" + std::to_string(dimension.x) + ","
+ std::to_string(dimension.y) + "," + std::to_string(dimension.z)
+ ")");
}
return reqd_work_group_size_data;
}
static KernelAttributes generate_work_group_size_data(
const std::vector<WorkGroupDimensions>& work_group_dimensions)
{
KernelAttributes work_group_size_hint_data;
for (auto dimension : work_group_dimensions)
{
work_group_size_hint_data.push_back(
"work_group_size_hint(" + std::to_string(dimension.x) + ","
+ std::to_string(dimension.y) + "," + std::to_string(dimension.z)
+ ")");
}
return work_group_size_hint_data;
}
// Populate the Global Vectors which store individual Kernel Attributes
static void populate_single_attribute_tests(
// Vectors to store the different data that fill the attributes
const KernelAttributes& vec_type_hint_data,
const KernelAttributes& work_group_size_hint_data,
const KernelAttributes& reqd_work_group_size_data)
{
for (auto vector_test : vec_type_hint_data)
{
// Initialise vec_type_hint attribute tests
vect_tests.push_back({ vector_test });
}
for (auto work_group_test : work_group_size_hint_data)
{
// Initialise work_group_size_hint attribute test
work_tests.push_back({ work_group_test });
}
for (auto reqd_work_group_test : reqd_work_group_size_data)
{
// Initialise reqd_work_group_size attribute tests
reqd_tests.push_back({ reqd_work_group_test });
}
}
// Populate the Global Vectors which store the different permutations of 2
// Kernel Attributes
static void populate_double_attribute_tests(
const KernelAttributes& vec_type_hint_data,
const KernelAttributes& work_group_size_hint_data,
const KernelAttributes& reqd_work_group_size_data)
{
for (auto vector_test : vec_type_hint_data)
{
for (auto work_group_test : work_group_size_hint_data)
{
// Initialise the tests for the permutation of work_group_size_hint
// combined with vec_type_hint
work_vect_tests.push_back({ work_group_test, vector_test });
}
for (auto reqd_work_group_test : reqd_work_group_size_data)
{
// Initialise the tests for the permutation of vec_type_hint and
// reqd_work_group_size
vect_reqd_tests.push_back({ vector_test, reqd_work_group_test });
}
}
for (auto work_group_test : work_group_size_hint_data)
{
for (auto reqd_work_group_test : reqd_work_group_size_data)
{
// Initialse the tests for the permutation of reqd_work_group_size
// and work_group_size_hint
reqd_work_tests.push_back(
{ reqd_work_group_test, work_group_test });
}
}
}
// Populate the Global Vectors which store the different permutations of 3
// Kernel Attributes
static void populate_triple_attribute_tests(
const KernelAttributes& vec_type_hint_data,
const KernelAttributes& work_group_size_hint_data,
const KernelAttributes& reqd_work_group_size_data)
{
for (auto vector_test : vec_type_hint_data)
{
for (auto work_group_test : work_group_size_hint_data)
{
for (auto reqd_work_group_test : reqd_work_group_size_data)
{
// Initialise the chosen permutations of 3 attributes
vect_work_reqd_tests.push_back(
{ vector_test, work_group_test, reqd_work_group_test });
work_reqd_vect_tests.push_back(
{ work_group_test, reqd_work_group_test, vector_test });
reqd_vect_work_tests.push_back(
{ reqd_work_group_test, vector_test, work_group_test });
}
}
}
}
static const std::vector<AttributePermutations*>
generate_attribute_tests(const KernelAttributes& vec_type_hint_data,
const KernelAttributes& work_group_size_hint_data,
const KernelAttributes& reqd_work_group_size_data)
{
populate_single_attribute_tests(vec_type_hint_data,
work_group_size_hint_data,
reqd_work_group_size_data);
populate_double_attribute_tests(vec_type_hint_data,
work_group_size_hint_data,
reqd_work_group_size_data);
populate_triple_attribute_tests(vec_type_hint_data,
work_group_size_hint_data,
reqd_work_group_size_data);
// Store all of the filled vectors in a single structure
const std::vector<AttributePermutations*> all_tests = {
&vect_tests, &work_tests, &reqd_tests,
&work_vect_tests, &vect_reqd_tests, &reqd_work_tests,
&vect_work_reqd_tests, &work_reqd_vect_tests, &reqd_vect_work_tests
};
return all_tests;
}
static const std::vector<AttributePermutations*>
initialise_attribute_data(cl_device_id deviceID)
{
// This vector stores different work group dimensions that can be used by
// the reqd_work_group_size and work_group_size_hint attributes. It
// currently only has a single value to minimise time complexity of the
// overall test but can be easily changed.
static const std::vector<WorkGroupDimensions> work_group_dimensions = {
{ 1, 1, 1 }
};
KernelAttributes vec_type_hint_data = generate_vec_type_hint_data(deviceID);
KernelAttributes work_group_size_hint_data =
generate_work_group_size_data(work_group_dimensions);
KernelAttributes reqd_work_group_size_data =
generate_reqd_work_group_size_data(work_group_dimensions);
// Generate all the permutations of attributes to create different test
// suites
return generate_attribute_tests(vec_type_hint_data,
work_group_size_hint_data,
reqd_work_group_size_data);
}
static bool run_test(cl_context context, cl_device_id deviceID,
const AttributePermutations& permutations)
{
bool success = true;
for (auto attribute_permutation : permutations)
{
std::string kernel_source_string =
generate_kernel_source(attribute_permutation);
const char* kernel_src = kernel_source_string.c_str();
clProgramWrapper program;
clKernelWrapper kernel;
cl_int err = create_single_kernel_helper(context, &program, &kernel, 1,
&kernel_src, "test_kernel");
test_error_ret(err, "create_single_kernel_helper", false);
// Get the size of the kernel attribute string returned
size_t size = 0;
err = clGetKernelInfo(kernel, CL_KERNEL_ATTRIBUTES, 0, nullptr, &size);
test_error_ret(err, "clGetKernelInfo", false);
std::vector<char> attributes(size);
err = clGetKernelInfo(kernel, CL_KERNEL_ATTRIBUTES, attributes.size(),
attributes.data(), nullptr);
test_error_ret(err, "clGetKernelInfo", false);
std::string attribute_string(attributes.data());
attribute_string.erase(
std::remove(attribute_string.begin(), attribute_string.end(), ' '),
attribute_string.end());
if (gCompilationMode != kOnline)
{
if (!attribute_string.empty())
{
success = false;
log_error("Error: Expected an empty string\n");
log_error("Attribute string reported as: %s\n",
attribute_string.c_str());
}
}
else
{
bool permutation_success = true;
for (auto attribute : attribute_permutation)
{
if (attribute_string.find(attribute) == std::string::npos)
{
success = false;
permutation_success = false;
log_error("ERROR: did not find expected attribute: '%s'\n",
attribute.c_str());
}
}
if (!permutation_success)
{
log_error("Attribute string reported as: %s\n",
attribute_string.c_str());
}
}
}
return success;
}
int test_kernel_attributes(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
bool success = true;
// Vector to store all of the tests
const std::vector<AttributePermutations*> all_tests =
initialise_attribute_data(deviceID);
for (auto permutations : all_tests)
{
success = success && run_test(context, deviceID, *permutations);
}
return success ? TEST_PASS : TEST_FAIL;
}

View file

@ -348,14 +348,7 @@ int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_ASSOCIATED_MEMOBJECT, origObj, (cl_mem)bufferObject, "associated mem object", "%p", void * )
TEST_MEM_OBJECT_PARAM( subBufferObject, CL_MEM_OFFSET, offset, (size_t)( addressAlign ), "offset", "%ld", size_t )
clReleaseMemObject( subBufferObject );
subBufferObject = NULL;
}
clReleaseMemObject( bufferObject );
bufferObject = NULL;
}
return CL_SUCCESS;
@ -370,8 +363,6 @@ int test_get_imageObject_info( cl_mem * image, cl_mem_flags objectFlags, cl_imag
cl_mem_flags flags;
cl_uint mapCount;
cl_uint refCount;
size_t rowPitchMultiplier;
size_t slicePitchMultiplier;
cl_context otherCtx;
size_t offset;
size_t sz;

View file

@ -48,12 +48,7 @@ int test_mem_object_destructor_callback_single(clMemWrapper &memObject)
test_error(error, "Unable to set destructor callback");
// Now release the buffer, which SHOULD call the callbacks
error = clReleaseMemObject(memObject);
test_error(error, "Unable to release test buffer");
// Note: since we manually released the mem wrapper, we need to set it to
// NULL to prevent a double-release
memObject = NULL;
memObject.reset();
// At this point, all three callbacks should have already been called
int numErrors = 0;

View file

@ -71,11 +71,11 @@ int test_min_image_formats(cl_device_id device, cl_context context,
int supports_3D_image_writes =
is_extension_available(device, "cl_khr_3d_image_writes");
for (int t = 0; t < ARRAY_SIZE(image_types); t++)
for (size_t t = 0; t < ARRAY_SIZE(image_types); t++)
{
const cl_mem_object_type type = image_types[t];
log_info(" testing %s...\n", convert_image_type_to_string(type));
for (int f = 0; f < ARRAY_SIZE(mem_flags); f++)
for (size_t f = 0; f < ARRAY_SIZE(mem_flags); f++)
{
const cl_mem_flags flags = mem_flags[f];
const char* testTypeString = flags == CL_MEM_READ_ONLY

View file

@ -149,7 +149,6 @@ int test_null_buffer_arg(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
unsigned int test_success = 0;
unsigned int i;
unsigned int buffer_size;
cl_int status;
cl_program program;

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -19,6 +19,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <algorithm>
#include <vector>
int test_get_platform_info(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
@ -161,8 +162,8 @@ static cl_filter_mode filter_mode_values[] = { CL_FILTER_NEAREST,
CL_FILTER_LINEAR };
int test_sampler_params(cl_device_id deviceID, cl_context context,
bool is_compatibility, int norm_coord_num,
int addr_mod_num, int filt_mod_num)
bool is_compatibility, size_t norm_coord_num,
size_t addr_mod_num, size_t filt_mod_num)
{
cl_uint refCount;
size_t size;
@ -271,10 +272,10 @@ int test_sampler_params(cl_device_id deviceID, cl_context context,
int get_sampler_info_params(cl_device_id deviceID, cl_context context,
bool is_compatibility)
{
for (int norm_coord_num = 0;
for (size_t norm_coord_num = 0;
norm_coord_num < ARRAY_SIZE(normalized_coord_values); norm_coord_num++)
{
for (int addr_mod_num = 0;
for (size_t addr_mod_num = 0;
addr_mod_num < ARRAY_SIZE(addressing_mode_values); addr_mod_num++)
{
if ((normalized_coord_values[norm_coord_num] == CL_FALSE)
@ -284,7 +285,7 @@ int get_sampler_info_params(cl_device_id deviceID, cl_context context,
{
continue;
}
for (int filt_mod_num = 0;
for (size_t filt_mod_num = 0;
filt_mod_num < ARRAY_SIZE(filter_mode_values); filt_mod_num++)
{
int err = test_sampler_params(deviceID, context,
@ -345,87 +346,100 @@ int command_queue_param_test(cl_command_queue queue,
return 0;
}
#define MIN_NUM_COMMAND_QUEUE_PROPERTIES 2
#define OOO_NUM_COMMAND_QUEUE_PROPERTIES 4
static cl_command_queue_properties property_options[] = {
0,
CL_QUEUE_PROFILING_ENABLE,
CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_ON_DEVICE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_ON_DEVICE
| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT
| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT
| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
};
int check_get_command_queue_info_params(cl_device_id deviceID,
cl_context context,
bool is_compatibility)
{
int error;
size_t size;
const cl_command_queue_properties host_optional[] = {
CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
};
cl_queue_properties host_queue_props, device_queue_props;
cl_queue_properties queue_props[] = { CL_QUEUE_PROPERTIES, 0, 0 };
const cl_command_queue_properties device_required[] = {
CL_QUEUE_ON_DEVICE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_ON_DEVICE
| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT
| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_ON_DEVICE
| CL_QUEUE_ON_DEVICE_DEFAULT
| CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
};
clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES,
sizeof(host_queue_props), &host_queue_props, NULL);
log_info("CL_DEVICE_QUEUE_ON_HOST_PROPERTIES is %d\n",
(int)host_queue_props);
clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES,
sizeof(device_queue_props), &device_queue_props, NULL);
log_info("CL_DEVICE_QUEUE_ON_HOST_PROPERTIES is %d\n",
(int)device_queue_props);
const size_t host_optional_size = ARRAY_SIZE(host_optional);
const size_t device_required_size = ARRAY_SIZE(device_required);
auto version = get_device_cl_version(deviceID);
Version version = get_device_cl_version(deviceID);
const cl_device_info host_queue_query = version >= Version(2, 0)
? CL_DEVICE_QUEUE_ON_HOST_PROPERTIES
: CL_DEVICE_QUEUE_PROPERTIES;
cl_queue_properties host_queue_props = 0;
int error =
clGetDeviceInfo(deviceID, host_queue_query, sizeof(host_queue_props),
&host_queue_props, NULL);
test_error(error, "clGetDeviceInfo failed");
log_info("CL_DEVICE_QUEUE_ON_HOST_PROPERTIES is %d\n", host_queue_props);
cl_queue_properties device_queue_props = 0;
if (version >= Version(2, 0))
{
error = clGetDeviceInfo(deviceID, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES,
sizeof(device_queue_props), &device_queue_props,
NULL);
test_error(error, "clGetDeviceInfo failed");
log_info("CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES is %d\n",
device_queue_props);
}
bool out_of_order_supported =
host_queue_props & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
// Are on device queues supported
bool on_device_supported =
(version >= Version(2, 0) && version < Version(3, 0))
|| (version >= Version(3, 0) && device_queue_props != 0);
int num_test_options = MIN_NUM_COMMAND_QUEUE_PROPERTIES;
if (host_queue_props & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)
{
// Test out-of-order queues properties if supported
num_test_options = OOO_NUM_COMMAND_QUEUE_PROPERTIES;
}
if (on_device_supported && !is_compatibility)
{
// Test queue on device if supported (in this case out-of-order must
// also be supported)
num_test_options = ARRAY_SIZE(property_options);
}
// test device queues if the device and the API under test support it
bool test_on_device = on_device_supported && !is_compatibility;
for (int i = 0; i < num_test_options; i++)
std::vector<cl_queue_properties> queue_props{ 0,
CL_QUEUE_PROFILING_ENABLE };
if (out_of_order_supported)
{
queue_props[1] = property_options[i];
queue_props.insert(queue_props.end(), &host_optional[0],
&host_optional[host_optional_size]);
};
cl_queue_properties queue_props_arg[] = { CL_QUEUE_PROPERTIES, 0, 0 };
if (test_on_device)
{
queue_props.insert(queue_props.end(), &device_required[0],
&device_required[device_required_size]);
};
for (cl_queue_properties props : queue_props)
{
queue_props_arg[1] = props;
clCommandQueueWrapper queue;
if (is_compatibility)
{
queue =
clCreateCommandQueue(context, deviceID, queue_props[1], &error);
queue = clCreateCommandQueue(context, deviceID, props, &error);
test_error(error, "Unable to create command queue to test with");
}
else
{
queue = clCreateCommandQueueWithProperties(context, deviceID,
&queue_props[0], &error);
queue_props_arg, &error);
test_error(error, "Unable to create command queue to test with");
}
cl_uint refCount;
size_t size;
error = clGetCommandQueueInfo(queue, CL_QUEUE_REFERENCE_COUNT,
sizeof(refCount), &refCount, &size);
test_error(error, "Unable to get command queue reference count");
@ -442,11 +456,12 @@ int check_get_command_queue_info_params(cl_device_id deviceID,
test_error(error, "param checking failed");
error = command_queue_param_test(queue, CL_QUEUE_PROPERTIES,
queue_props[1], "properties");
queue_props_arg[1], "properties");
test_error(error, "param checking failed");
}
return 0;
}
int test_get_command_queue_info(cl_device_id deviceID, cl_context context,
cl_command_queue ignoreQueue, int num_elements)
{
@ -511,26 +526,6 @@ void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data )
free( data );
}
// All possible combinations of valid cl_mem_flags.
static cl_mem_flags all_flags[16] = {
0,
CL_MEM_READ_WRITE,
CL_MEM_READ_ONLY,
CL_MEM_WRITE_ONLY,
CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,
CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
};
#define TEST_DEVICE_PARAM( device, paramName, val, name, type, cast ) \
error = clGetDeviceInfo( device, paramName, sizeof( val ), &val, &size ); \
test_error( error, "Unable to get device " name ); \
@ -824,5 +819,3 @@ int test_kernel_required_group_size(cl_device_id deviceID, cl_context context, c
return 0;
}

View file

@ -60,7 +60,7 @@ int enqueue_kernel(cl_context context, const cl_queue_properties_khr *queue_prop
clCommandQueueWrapper queue = clCreateCommandQueueWithPropertiesKHR(context, deviceID, queue_prop_def, &error);
test_error(error, "clCreateCommandQueueWithPropertiesKHR failed");
for (int i = 0; i < num_elements; ++i)
for (size_t i = 0; i < num_elements; ++i)
{
buf[i] = i;
}
@ -85,9 +85,9 @@ int enqueue_kernel(cl_context context, const cl_queue_properties_khr *queue_prop
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, num_elements, buf.data(), 0, NULL, NULL);
test_error( error, "clEnqueueReadBuffer failed." );
for (int i = 0; i < num_elements; ++i)
for (size_t i = 0; i < num_elements; ++i)
{
if (buf[i] != i)
if (static_cast<size_t>(buf[i]) != i)
{
log_error("ERROR: Incorrect vector copy result.");
return -1;
@ -162,4 +162,4 @@ int test_queue_properties(cl_device_id deviceID, cl_context context, cl_command_
}
return 0;
}
}

View file

@ -56,11 +56,9 @@ cl_int get_sub_group_num(cl_command_queue queue, cl_kernel kernel, clMemWrapper&
int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
static const size_t gsize0 = 80;
int i, error;
int error;
size_t realSize;
size_t kernel_max_subgroup_size, kernel_subgroup_count;
size_t global[] = {1,1,1};
size_t max_local;
cl_platform_id platform;
@ -129,7 +127,9 @@ int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_comman
log_info("The CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE for the kernel is %d.\n", (int)kernel_subgroup_count);
if (realSize != sizeof(kernel_subgroup_count)) {
log_error( "ERROR: Returned size of sub group count not valid! (Expected %d, got %d)\n", (int)sizeof(kernel_subgroup_count), (int)realSize );
log_error("ERROR: Returned size of sub group count not valid! "
"(Expected %d, got %d)\n",
(int)sizeof(kernel_subgroup_count), (int)realSize);
return -1;
}
@ -137,7 +137,6 @@ int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_comman
for (size_t i = kernel_subgroup_count; i > 0; --i)
{
// test all 3 different dimention of requested local size
size_t expect_size = kernel_max_subgroup_size * i;
size_t kernel_ret_size = 0;
error = clGetKernelSubGroupInfo(kernel, deviceID, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, sizeof(i), &i, sizeof(ret_ndrange1d), &ret_ndrange1d, &realSize);
test_error(error, "clGetKernelSubGroupInfo failed for CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT");
@ -146,12 +145,6 @@ int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_comman
return -1;
}
if (ret_ndrange1d != expect_size)
{
log_error( "ERROR: Incorrect value returned for CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT! (Expected %d, got %d)\n", (int)expect_size, (int)ret_ndrange1d );
return -1;
}
error = get_sub_group_num(queue, kernel, out, kernel_ret_size, ret_ndrange1d, 1);
test_error(error, "Failed to query number of subgroups from kernel");
if (i != kernel_ret_size)
@ -168,12 +161,6 @@ int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_comman
}
ret_ndrange2d_flattened = flatten_ndrange(ret_ndrange2d, 2);
if (ret_ndrange2d_flattened != expect_size ||
ret_ndrange2d[1] != 1)
{
log_error( "ERROR: Incorrect value returned for CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT! (Expected %d, got %d)\n", (int)expect_size, (int)ret_ndrange2d_flattened );
return -1;
}
error = get_sub_group_num(queue, kernel, out, kernel_ret_size, ret_ndrange2d_flattened, 2);
test_error(error, "Failed to query number of subgroups from kernel");
@ -191,13 +178,6 @@ int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_comman
}
ret_ndrange3d_flattened = flatten_ndrange(ret_ndrange3d, 3);
if (ret_ndrange3d_flattened != expect_size ||
ret_ndrange3d[1] != 1 ||
ret_ndrange3d[2] != 1)
{
log_error( "ERROR: Incorrect value returned for CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT! (Expected %d, got %d)\n", (int)expect_size, (int)ret_ndrange3d_flattened );
return -1;
}
error = get_sub_group_num(queue, kernel, out, kernel_ret_size, ret_ndrange3d_flattened, 3);
test_error(error, "Failed to query number of subgroups from kernel");

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -24,6 +24,7 @@
#include <unistd.h>
#endif
// clang-format off
test_definition test_list[] = {
ADD_TEST( atomic_add ),
ADD_TEST( atomic_sub ),
@ -40,11 +41,11 @@ test_definition test_list[] = {
ADD_TEST( atomic_add_index ),
ADD_TEST( atomic_add_index_bin ),
};
// clang-format on
const int test_num = ARRAY_SIZE( test_list );
const int test_num = ARRAY_SIZE(test_list);
int main(int argc, const char *argv[])
{
return runTestHarness(argc, argv, test_num, test_list, false, 0);
}

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -15,25 +15,37 @@
//
#include "harness/errorHelpers.h"
#include "harness/kernelHelpers.h"
#include "harness/threadTesting.h"
#include "harness/typeWrappers.h"
extern int create_program_and_kernel(const char *source, const char *kernel_name, cl_program *program_ret, cl_kernel *kernel_ret);
extern int test_atomic_add(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_sub(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_xchg(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_min(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_max(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_inc(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_dec(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_cmpxchg(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_and(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_or(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_xor(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_add_index(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_atomic_add_index_bin(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int create_program_and_kernel(const char *source,
const char *kernel_name,
cl_program *program_ret,
cl_kernel *kernel_ret);
extern int test_atomic_add(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_sub(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_xchg(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_min(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_max(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_inc(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_dec(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_cmpxchg(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_and(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_or(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_xor(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_add_index(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_atomic_add_index_bin(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -26,6 +26,3 @@
#include "procs.h"
#endif // _testBase_h

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -16,48 +16,55 @@
#include "testBase.h"
#include "harness/conversions.h"
const char * atomic_index_source =
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
"// Counter keeps track of which index in counts we are using.\n"
"// We get that value, increment it, and then set that index in counts to our thread ID.\n"
"// At the end of this we should have all thread IDs in some random location in counts\n"
"// exactly once. If atom_add failed then we will write over various thread IDs and we\n"
"// will be missing some.\n"
"\n"
"__kernel void add_index_test(__global int *counter, __global int *counts) {\n"
" int tid = get_global_id(0);\n"
" \n"
" int counter_to_use = atom_add(counter, 1);\n"
" counts[counter_to_use] = tid;\n"
"}";
// clang-format off
const char *atomic_index_source =
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
"// Counter keeps track of which index in counts we are using.\n"
"// We get that value, increment it, and then set that index in counts to our thread ID.\n"
"// At the end of this we should have all thread IDs in some random location in counts\n"
"// exactly once. If atom_add failed then we will write over various thread IDs and we\n"
"// will be missing some.\n"
"\n"
"__kernel void add_index_test(__global int *counter, __global int *counts) {\n"
" int tid = get_global_id(0);\n"
" \n"
" int counter_to_use = atom_add(counter, 1);\n"
" counts[counter_to_use] = tid;\n"
"}";
// clang-format on
int test_atomic_add_index(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
int test_atomic_add_index(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
clProgramWrapper program;
clKernelWrapper kernel;
clMemWrapper counter, counters;
size_t numGlobalThreads, numLocalThreads;
int fail = 0, succeed = 0, err;
int fail = 0, err;
/* Check if atomics are supported. */
if (!is_extension_available(deviceID, "cl_khr_global_int32_base_atomics")) {
log_info("Base atomics not supported (cl_khr_global_int32_base_atomics). Skipping test.\n");
return 0;
}
/* Check if atomics are supported. */
if (!is_extension_available(deviceID, "cl_khr_global_int32_base_atomics"))
{
log_info("Base atomics not supported "
"(cl_khr_global_int32_base_atomics). Skipping test.\n");
return 0;
}
//===== add_index test
// The index test replicates what particles does.
// It uses one memory location to keep track of the current index and then each thread
// does an atomic add to it to get its new location. The threads then write to their
// assigned location. At the end we check to make sure that each thread's ID shows up
// exactly once in the output.
// It uses one memory location to keep track of the current index and then
// each thread does an atomic add to it to get its new location. The threads
// then write to their assigned location. At the end we check to make sure
// that each thread's ID shows up exactly once in the output.
numGlobalThreads = 2048;
if( create_single_kernel_helper( context, &program, &kernel, 1, &atomic_index_source, "add_index_test" ) )
if (create_single_kernel_helper(context, &program, &kernel, 1,
&atomic_index_source, "add_index_test"))
return -1;
if( get_max_common_work_group_size( context, kernel, numGlobalThreads, &numLocalThreads ) )
if (get_max_common_work_group_size(context, kernel, numGlobalThreads,
&numLocalThreads))
return -1;
log_info("Execute global_threads:%d local_threads:%d\n",
@ -72,103 +79,148 @@ int test_atomic_add_index(cl_device_id deviceID, cl_context context, cl_command_
sizeof(cl_int) * numGlobalThreads, NULL, NULL);
// Reset all those locations to -1 to indciate they have not been used.
cl_int *values = (cl_int*) malloc(sizeof(cl_int)*numGlobalThreads);
if (values == NULL) {
log_error("add_index_test FAILED to allocate memory for initial values.\n");
fail = 1; succeed = -1;
} else {
cl_int *values = (cl_int *)malloc(sizeof(cl_int) * numGlobalThreads);
if (values == NULL)
{
log_error(
"add_index_test FAILED to allocate memory for initial values.\n");
fail = 1;
}
else
{
memset(values, -1, numLocalThreads);
unsigned int i=0;
for (i=0; i<numGlobalThreads; i++)
values[i] = -1;
int init=0;
err = clEnqueueWriteBuffer(queue, counters, true, 0, numGlobalThreads*sizeof(cl_int), values, 0, NULL, NULL);
err |= clEnqueueWriteBuffer(queue, counter, true, 0,1*sizeof(cl_int), &init, 0, NULL, NULL);
if (err) {
log_error("add_index_test FAILED to write initial values to arrays: %d\n", err);
fail=1; succeed=-1;
} else {
unsigned int i = 0;
for (i = 0; i < numGlobalThreads; i++) values[i] = -1;
int init = 0;
err = clEnqueueWriteBuffer(queue, counters, true, 0,
numGlobalThreads * sizeof(cl_int), values, 0,
NULL, NULL);
err |= clEnqueueWriteBuffer(queue, counter, true, 0, 1 * sizeof(cl_int),
&init, 0, NULL, NULL);
if (err)
{
log_error(
"add_index_test FAILED to write initial values to arrays: %d\n",
err);
fail = 1;
}
else
{
err = clSetKernelArg(kernel, 0, sizeof(counter), &counter);
err |= clSetKernelArg(kernel, 1, sizeof(counters), &counters);
if (err) {
log_error("add_index_test FAILED to set kernel arguments: %d\n", err);
fail=1; succeed=-1;
} else {
err = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, &numGlobalThreads, &numLocalThreads, 0, NULL, NULL );
if (err) {
log_error("add_index_test FAILED to execute kernel: %d\n", err);
fail=1; succeed=-1;
} else {
err = clEnqueueReadBuffer( queue, counters, true, 0, sizeof(cl_int)*numGlobalThreads, values, 0, NULL, NULL );
if (err) {
log_error("add_index_test FAILED to read back results: %d\n", err);
fail = 1; succeed=-1;
} else {
if (err)
{
log_error("add_index_test FAILED to set kernel arguments: %d\n",
err);
fail = 1;
}
else
{
err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL,
&numGlobalThreads,
&numLocalThreads, 0, NULL, NULL);
if (err)
{
log_error("add_index_test FAILED to execute kernel: %d\n",
err);
fail = 1;
}
else
{
err = clEnqueueReadBuffer(queue, counters, true, 0,
sizeof(cl_int) * numGlobalThreads,
values, 0, NULL, NULL);
if (err)
{
log_error(
"add_index_test FAILED to read back results: %d\n",
err);
fail = 1;
}
else
{
unsigned int looking_for, index;
for (looking_for=0; looking_for<numGlobalThreads; looking_for++) {
int instances_found=0;
for (index=0; index<numGlobalThreads; index++) {
if (values[index]==(int)looking_for)
for (looking_for = 0; looking_for < numGlobalThreads;
looking_for++)
{
int instances_found = 0;
for (index = 0; index < numGlobalThreads; index++)
{
if (values[index] == (int)looking_for)
instances_found++;
}
if (instances_found != 1) {
log_error("add_index_test FAILED: wrong number of instances (%d!=1) for counter %d.\n", instances_found, looking_for);
fail = 1; succeed=-1;
if (instances_found != 1)
{
log_error(
"add_index_test FAILED: wrong number of "
"instances (%d!=1) for counter %d.\n",
instances_found, looking_for);
fail = 1;
}
}
}
}
}
}
if (!fail) {
log_info("add_index_test passed. Each thread used exactly one index.\n");
if (!fail)
{
log_info(
"add_index_test passed. Each thread used exactly one index.\n");
}
free(values);
}
return fail;
}
// clang-format off
const char *add_index_bin_kernel[] = {
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
"// This test assigns a bunch of values to bins and then tries to put them in the bins in parallel\n"
"// using an atomic add to keep track of the current location to write into in each bin.\n"
"// This is the same as the memory update for the particles demo.\n"
"\n"
"__kernel void add_index_bin_test(__global int *bin_counters, __global int *bins, __global int *bin_assignments, int max_counts_per_bin) {\n"
" int tid = get_global_id(0);\n"
"\n"
" int location = bin_assignments[tid];\n"
" int counter = atom_add(&bin_counters[location], 1);\n"
" bins[location*max_counts_per_bin + counter] = tid;\n"
"}" };
"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n"
"// This test assigns a bunch of values to bins and then tries to put them in the bins in parallel\n"
"// using an atomic add to keep track of the current location to write into in each bin.\n"
"// This is the same as the memory update for the particles demo.\n"
"\n"
"__kernel void add_index_bin_test(__global int *bin_counters, __global int *bins, __global int *bin_assignments, int max_counts_per_bin) {\n"
" int tid = get_global_id(0);\n"
"\n"
" int location = bin_assignments[tid];\n"
" int counter = atom_add(&bin_counters[location], 1);\n"
" bins[location*max_counts_per_bin + counter] = tid;\n"
"}" };
// clang-format on
// This test assigns a bunch of values to bins and then tries to put them in the bins in parallel
// using an atomic add to keep track of the current location to write into in each bin.
// This is the same as the memory update for the particles demo.
int add_index_bin_test(size_t *global_threads, cl_command_queue queue, cl_context context, MTdata d)
// This test assigns a bunch of values to bins and then tries to put them in the
// bins in parallel using an atomic add to keep track of the current location to
// write into in each bin. This is the same as the memory update for the
// particles demo.
int add_index_bin_test(size_t *global_threads, cl_command_queue queue,
cl_context context, MTdata d)
{
int number_of_items = (int)global_threads[0];
size_t local_threads[1];
int divisor = 12;
int number_of_bins = number_of_items/divisor;
int max_counts_per_bin = divisor*2;
int number_of_bins = number_of_items / divisor;
int max_counts_per_bin = divisor * 2;
int fail = 0;
int succeed = 0;
int err;
clProgramWrapper program;
clKernelWrapper kernel;
// log_info("add_index_bin_test: %d items, into %d bins, with a max of %d items per bin (bins is %d long).\n",
// number_of_items, number_of_bins, max_counts_per_bin, number_of_bins*max_counts_per_bin);
// log_info("add_index_bin_test: %d items, into %d bins, with a max of %d
// items per bin (bins is %d long).\n",
// number_of_items, number_of_bins, max_counts_per_bin,
// number_of_bins*max_counts_per_bin);
//===== add_index_bin test
// The index test replicates what particles does.
err = create_single_kernel_helper(context, &program, &kernel, 1, add_index_bin_kernel, "add_index_bin_test" );
test_error( err, "Unable to create testing kernel" );
err =
create_single_kernel_helper(context, &program, &kernel, 1,
add_index_bin_kernel, "add_index_bin_test");
test_error(err, "Unable to create testing kernel");
if( get_max_common_work_group_size( context, kernel, global_threads[0], &local_threads[0] ) )
if (get_max_common_work_group_size(context, kernel, global_threads[0],
&local_threads[0]))
return -1;
log_info("Execute global_threads:%d local_threads:%d\n",
@ -185,152 +237,228 @@ int add_index_bin_test(size_t *global_threads, cl_command_queue queue, cl_contex
clCreateBuffer(context, CL_MEM_READ_ONLY,
sizeof(cl_int) * number_of_items, NULL, NULL);
if (bin_counters == NULL) {
if (bin_counters == NULL)
{
log_error("add_index_bin_test FAILED to allocate bin_counters.\n");
return -1;
}
if (bins == NULL) {
if (bins == NULL)
{
log_error("add_index_bin_test FAILED to allocate bins.\n");
return -1;
}
if (bin_assignments == NULL) {
if (bin_assignments == NULL)
{
log_error("add_index_bin_test FAILED to allocate bin_assignments.\n");
return -1;
}
// Initialize our storage
cl_int *l_bin_counts = (cl_int*)malloc(sizeof(cl_int)*number_of_bins);
if (!l_bin_counts) {
log_error("add_index_bin_test FAILED to allocate initial values for bin_counters.\n");
cl_int *l_bin_counts = (cl_int *)malloc(sizeof(cl_int) * number_of_bins);
if (!l_bin_counts)
{
log_error("add_index_bin_test FAILED to allocate initial values for "
"bin_counters.\n");
return -1;
}
int i;
for (i=0; i<number_of_bins; i++)
l_bin_counts[i] = 0;
err = clEnqueueWriteBuffer(queue, bin_counters, true, 0, sizeof(cl_int)*number_of_bins, l_bin_counts, 0, NULL, NULL);
if (err) {
log_error("add_index_bin_test FAILED to set initial values for bin_counters: %d\n", err);
for (i = 0; i < number_of_bins; i++) l_bin_counts[i] = 0;
err = clEnqueueWriteBuffer(queue, bin_counters, true, 0,
sizeof(cl_int) * number_of_bins, l_bin_counts, 0,
NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to set initial values for "
"bin_counters: %d\n",
err);
return -1;
}
cl_int *values = (cl_int*)malloc(sizeof(cl_int)*number_of_bins*max_counts_per_bin);
if (!values) {
log_error("add_index_bin_test FAILED to allocate initial values for bins.\n");
cl_int *values =
(cl_int *)malloc(sizeof(cl_int) * number_of_bins * max_counts_per_bin);
if (!values)
{
log_error(
"add_index_bin_test FAILED to allocate initial values for bins.\n");
return -1;
}
for (i=0; i<number_of_bins*max_counts_per_bin; i++)
values[i] = -1;
err = clEnqueueWriteBuffer(queue, bins, true, 0, sizeof(cl_int)*number_of_bins*max_counts_per_bin, values, 0, NULL, NULL);
if (err) {
log_error("add_index_bin_test FAILED to set initial values for bins: %d\n", err);
for (i = 0; i < number_of_bins * max_counts_per_bin; i++) values[i] = -1;
err = clEnqueueWriteBuffer(queue, bins, true, 0,
sizeof(cl_int) * number_of_bins
* max_counts_per_bin,
values, 0, NULL, NULL);
if (err)
{
log_error(
"add_index_bin_test FAILED to set initial values for bins: %d\n",
err);
return -1;
}
free(values);
cl_int *l_bin_assignments = (cl_int*)malloc(sizeof(cl_int)*number_of_items);
if (!l_bin_assignments) {
log_error("add_index_bin_test FAILED to allocate initial values for l_bin_assignments.\n");
cl_int *l_bin_assignments =
(cl_int *)malloc(sizeof(cl_int) * number_of_items);
if (!l_bin_assignments)
{
log_error("add_index_bin_test FAILED to allocate initial values for "
"l_bin_assignments.\n");
return -1;
}
for (i=0; i<number_of_items; i++) {
int bin = random_in_range(0, number_of_bins-1, d);
while (l_bin_counts[bin] >= max_counts_per_bin) {
bin = random_in_range(0, number_of_bins-1, d);
for (i = 0; i < number_of_items; i++)
{
int bin = random_in_range(0, number_of_bins - 1, d);
while (l_bin_counts[bin] >= max_counts_per_bin)
{
bin = random_in_range(0, number_of_bins - 1, d);
}
if (bin >= number_of_bins)
log_error("add_index_bin_test internal error generating bin assignments: bin %d >= number_of_bins %d.\n", bin, number_of_bins);
if (l_bin_counts[bin]+1 > max_counts_per_bin)
log_error("add_index_bin_test internal error generating bin assignments: bin %d has more entries (%d) than max_counts_per_bin (%d).\n", bin, l_bin_counts[bin], max_counts_per_bin);
log_error("add_index_bin_test internal error generating bin "
"assignments: bin %d >= number_of_bins %d.\n",
bin, number_of_bins);
if (l_bin_counts[bin] + 1 > max_counts_per_bin)
log_error(
"add_index_bin_test internal error generating bin assignments: "
"bin %d has more entries (%d) than max_counts_per_bin (%d).\n",
bin, l_bin_counts[bin], max_counts_per_bin);
l_bin_counts[bin]++;
l_bin_assignments[i] = bin;
// log_info("item %d assigned to bin %d (%d items)\n", i, bin, l_bin_counts[bin]);
// log_info("item %d assigned to bin %d (%d items)\n", i, bin,
// l_bin_counts[bin]);
}
err = clEnqueueWriteBuffer(queue, bin_assignments, true, 0, sizeof(cl_int)*number_of_items, l_bin_assignments, 0, NULL, NULL);
if (err) {
log_error("add_index_bin_test FAILED to set initial values for bin_assignments: %d\n", err);
err = clEnqueueWriteBuffer(queue, bin_assignments, true, 0,
sizeof(cl_int) * number_of_items,
l_bin_assignments, 0, NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to set initial values for "
"bin_assignments: %d\n",
err);
return -1;
}
// Setup the kernel
err = clSetKernelArg(kernel, 0, sizeof(bin_counters), &bin_counters);
err |= clSetKernelArg(kernel, 1, sizeof(bins), &bins);
err |= clSetKernelArg(kernel, 2, sizeof(bin_assignments), &bin_assignments);
err |= clSetKernelArg(kernel, 3, sizeof(max_counts_per_bin), &max_counts_per_bin);
if (err) {
log_error("add_index_bin_test FAILED to set kernel arguments: %d\n", err);
fail=1; succeed=-1;
err |= clSetKernelArg(kernel, 3, sizeof(max_counts_per_bin),
&max_counts_per_bin);
if (err)
{
log_error("add_index_bin_test FAILED to set kernel arguments: %d\n",
err);
fail = 1;
return -1;
}
err = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, global_threads, local_threads, 0, NULL, NULL );
if (err) {
err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, global_threads,
local_threads, 0, NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to execute kernel: %d\n", err);
fail=1; succeed=-1;
fail = 1;
}
cl_int *final_bin_assignments = (cl_int*)malloc(sizeof(cl_int)*number_of_bins*max_counts_per_bin);
if (!final_bin_assignments) {
log_error("add_index_bin_test FAILED to allocate initial values for final_bin_assignments.\n");
cl_int *final_bin_assignments =
(cl_int *)malloc(sizeof(cl_int) * number_of_bins * max_counts_per_bin);
if (!final_bin_assignments)
{
log_error("add_index_bin_test FAILED to allocate initial values for "
"final_bin_assignments.\n");
return -1;
}
err = clEnqueueReadBuffer( queue, bins, true, 0, sizeof(cl_int)*number_of_bins*max_counts_per_bin, final_bin_assignments, 0, NULL, NULL );
if (err) {
err = clEnqueueReadBuffer(queue, bins, true, 0,
sizeof(cl_int) * number_of_bins
* max_counts_per_bin,
final_bin_assignments, 0, NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to read back bins: %d\n", err);
fail = 1; succeed=-1;
fail = 1;
}
cl_int *final_bin_counts = (cl_int*)malloc(sizeof(cl_int)*number_of_bins);
if (!final_bin_counts) {
log_error("add_index_bin_test FAILED to allocate initial values for final_bin_counts.\n");
cl_int *final_bin_counts =
(cl_int *)malloc(sizeof(cl_int) * number_of_bins);
if (!final_bin_counts)
{
log_error("add_index_bin_test FAILED to allocate initial values for "
"final_bin_counts.\n");
return -1;
}
err = clEnqueueReadBuffer( queue, bin_counters, true, 0, sizeof(cl_int)*number_of_bins, final_bin_counts, 0, NULL, NULL );
if (err) {
log_error("add_index_bin_test FAILED to read back bin_counters: %d\n", err);
fail = 1; succeed=-1;
err = clEnqueueReadBuffer(queue, bin_counters, true, 0,
sizeof(cl_int) * number_of_bins, final_bin_counts,
0, NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to read back bin_counters: %d\n",
err);
fail = 1;
}
// Verification.
int errors=0;
int errors = 0;
int current_bin;
int search;
// Print out all the contents of the bins.
// for (current_bin=0; current_bin<number_of_bins; current_bin++)
// for (search=0; search<max_counts_per_bin; search++)
// log_info("[bin %d, entry %d] = %d\n", current_bin, search, final_bin_assignments[current_bin*max_counts_per_bin+search]);
// log_info("[bin %d, entry %d] = %d\n", current_bin, search,
// final_bin_assignments[current_bin*max_counts_per_bin+search]);
// First verify that there are the correct number in each bin.
for (current_bin=0; current_bin<number_of_bins; current_bin++) {
for (current_bin = 0; current_bin < number_of_bins; current_bin++)
{
int expected_number = l_bin_counts[current_bin];
int actual_number = final_bin_counts[current_bin];
if (expected_number != actual_number) {
log_error("add_index_bin_test FAILED: bin %d reported %d entries when %d were expected.\n", current_bin, actual_number, expected_number);
if (expected_number != actual_number)
{
log_error("add_index_bin_test FAILED: bin %d reported %d entries "
"when %d were expected.\n",
current_bin, actual_number, expected_number);
errors++;
}
for (search=0; search<expected_number; search++) {
if (final_bin_assignments[current_bin*max_counts_per_bin+search] == -1) {
log_error("add_index_bin_test FAILED: bin %d had no entry at position %d when it should have had %d entries.\n", current_bin, search, expected_number);
for (search = 0; search < expected_number; search++)
{
if (final_bin_assignments[current_bin * max_counts_per_bin + search]
== -1)
{
log_error("add_index_bin_test FAILED: bin %d had no entry at "
"position %d when it should have had %d entries.\n",
current_bin, search, expected_number);
errors++;
}
}
for (search=expected_number; search<max_counts_per_bin; search++) {
if (final_bin_assignments[current_bin*max_counts_per_bin+search] != -1) {
log_error("add_index_bin_test FAILED: bin %d had an extra entry at position %d when it should have had only %d entries.\n", current_bin, search, expected_number);
for (search = expected_number; search < max_counts_per_bin; search++)
{
if (final_bin_assignments[current_bin * max_counts_per_bin + search]
!= -1)
{
log_error(
"add_index_bin_test FAILED: bin %d had an extra entry at "
"position %d when it should have had only %d entries.\n",
current_bin, search, expected_number);
errors++;
}
}
}
// Now verify that the correct ones are in each bin
int index;
for (index=0; index<number_of_items; index++) {
for (index = 0; index < number_of_items; index++)
{
int expected_bin = l_bin_assignments[index];
int found_it = 0;
for (search=0; search<l_bin_counts[expected_bin]; search++) {
if (final_bin_assignments[expected_bin*max_counts_per_bin+search] == index) {
for (search = 0; search < l_bin_counts[expected_bin]; search++)
{
if (final_bin_assignments[expected_bin * max_counts_per_bin
+ search]
== index)
{
found_it = 1;
}
}
if (found_it == 0) {
log_error("add_index_bin_test FAILED: did not find item %d in bin %d.\n", index, expected_bin);
if (found_it == 0)
{
log_error(
"add_index_bin_test FAILED: did not find item %d in bin %d.\n",
index, expected_bin);
errors++;
}
}
@ -341,41 +469,49 @@ int add_index_bin_test(size_t *global_threads, cl_command_queue queue, cl_contex
clReleaseMemObject(bin_counters);
clReleaseMemObject(bins);
clReleaseMemObject(bin_assignments);
if (errors == 0) {
log_info("add_index_bin_test passed. Each item was put in the correct bin in parallel.\n");
if (errors == 0)
{
log_info("add_index_bin_test passed. Each item was put in the correct "
"bin in parallel.\n");
return 0;
} else {
}
else
{
log_error("add_index_bin_test FAILED: %d errors.\n", errors);
return -1;
}
}
int test_atomic_add_index_bin(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
int test_atomic_add_index_bin(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
//===== add_index_bin test
size_t numGlobalThreads = 2048;
int iteration=0;
int iteration = 0;
int err, failed = 0;
MTdata d = init_genrand( gRandomSeed );
MTdata d = init_genrand(gRandomSeed);
/* Check if atomics are supported. */
if (!is_extension_available(deviceID, "cl_khr_global_int32_base_atomics")) {
log_info("Base atomics not supported (cl_khr_global_int32_base_atomics). Skipping test.\n");
free_mtdata( d );
return 0;
}
/* Check if atomics are supported. */
if (!is_extension_available(deviceID, "cl_khr_global_int32_base_atomics"))
{
log_info("Base atomics not supported "
"(cl_khr_global_int32_base_atomics). Skipping test.\n");
free_mtdata(d);
return 0;
}
for(iteration=0; iteration<10; iteration++) {
log_info("add_index_bin_test with %d elements:\n", (int)numGlobalThreads);
err = add_index_bin_test(&numGlobalThreads, queue, context, d);
if (err) {
for (iteration = 0; iteration < 10; iteration++)
{
log_info("add_index_bin_test with %d elements:\n",
(int)numGlobalThreads);
err = add_index_bin_test(&numGlobalThreads, queue, context, d);
if (err)
{
failed++;
break;
}
numGlobalThreads*=2;
numGlobalThreads *= 2;
}
free_mtdata( d );
free_mtdata(d);
return failed;
}

View file

@ -2,13 +2,12 @@ set(MODULE_NAME BASIC)
set(${MODULE_NAME}_SOURCES
main.cpp
test_fpmath_float.cpp test_fpmath_float2.cpp test_fpmath_float4.cpp
test_fpmath_float.cpp
test_intmath.cpp
test_hiloeo.cpp test_local.cpp test_pointercast.cpp
test_if.cpp test_loop.cpp
test_readimage.cpp test_readimage_int16.cpp test_readimage_fp32.cpp
test_readimage3d.cpp test_readimage3d_int16.cpp test_readimage3d_fp32.cpp
test_writeimage.cpp test_writeimage_int16.cpp test_writeimage_fp32.cpp
test_readimage.cpp
test_writeimage.cpp
test_multireadimageonefmt.cpp test_multireadimagemultifmt.cpp
test_imagedim.cpp
test_vloadstore.cpp
@ -31,7 +30,6 @@ set(${MODULE_NAME}_SOURCES
test_imagecopy.cpp
test_imagerandomcopy.cpp
test_arrayimagecopy.cpp
test_arrayimagecopy3d.cpp
test_imagecopy3d.cpp
test_enqueue_map.cpp
test_work_item_functions.cpp

View file

@ -20,8 +20,6 @@
#include "harness/conversions.h"
#include "harness/rounding_mode.h"
extern void memset_pattern4(void *dest, const void *src_pattern, size_t bytes );
extern int test_hostptr(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_fpmath_float(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_fpmath_float2(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);

View file

@ -181,9 +181,8 @@ test_arraycopy(cl_device_id device, cl_context context, cl_command_queue queue,
}
}
// Keep track of multiple errors.
if (error_count != 0)
err = error_count;
// Keep track of multiple errors.
if (error_count != 0) err = error_count;
if (err)
log_error("\tCL_MEM_USE_HOST_PTR buffer with kernel copy FAILED\n");

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -14,134 +14,173 @@
// limitations under the License.
//
#include "harness/compat.h"
#include "harness/imageHelpers.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include "procs.h"
int test_arrayimagecopy_single_format(cl_device_id device, cl_context context, cl_command_queue queue, cl_image_format *format)
int test_arrayimagecopy_single_format(cl_device_id device, cl_context context,
cl_command_queue queue,
cl_mem_flags flags,
cl_mem_object_type image_type,
const cl_image_format *format)
{
cl_uchar *bufptr, *imgptr;
clMemWrapper buffer, image;
int img_width = 512;
int img_height = 512;
size_t elem_size;
size_t buffer_size;
int i;
cl_int err;
MTdata d;
cl_event copyevent;
cl_uchar *bufptr, *imgptr;
clMemWrapper buffer, image;
int img_width = 512;
int img_height = 512;
int img_depth = (image_type == CL_MEM_OBJECT_IMAGE3D) ? 32 : 1;
size_t elem_size;
size_t buffer_size;
cl_int err;
cl_event copyevent;
log_info("Testing %s %s\n", GetChannelOrderName(format->image_channel_order), GetChannelTypeName(format->image_channel_data_type));
log_info("Testing %s %s\n",
GetChannelOrderName(format->image_channel_order),
GetChannelTypeName(format->image_channel_data_type));
image = create_image_2d(context, CL_MEM_READ_WRITE, format, img_width,
img_height, 0, NULL, &err);
test_error(err, "create_image_2d failed");
err = clGetImageInfo(image, CL_IMAGE_ELEMENT_SIZE, sizeof(size_t), &elem_size, NULL);
test_error(err, "clGetImageInfo failed");
buffer_size = sizeof(cl_uchar) * elem_size * img_width * img_height;
buffer = clCreateBuffer(context, CL_MEM_READ_WRITE, buffer_size, NULL, &err);
test_error(err, "clCreateBuffer failed");
d = init_genrand( gRandomSeed );
bufptr = (cl_uchar*)malloc(buffer_size);
for (i=0; i<(int)buffer_size; i++) {
bufptr[i] = (cl_uchar)genrand_int32(d);
}
free_mtdata(d); d = NULL;
size_t origin[3]={0,0,0}, region[3]={img_width,img_height,1};
err = clEnqueueWriteBuffer( queue, buffer, CL_TRUE, 0, buffer_size, bufptr, 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueCopyBufferToImage( queue, buffer, image, 0, origin, region, 0, NULL, &copyevent );
test_error(err, "clEnqueueCopyImageToBuffer failed");
imgptr = (cl_uchar*)malloc(buffer_size);
err = clEnqueueReadImage( queue, image, CL_TRUE, origin, region, 0, 0, imgptr, 1, &copyevent, NULL );
test_error(err, "clEnqueueReadBuffer failed");
err = clReleaseEvent(copyevent);
test_error(err, "clReleaseEvent failed");
if (memcmp(bufptr, imgptr, buffer_size) != 0) {
log_error( "ERROR: Results did not validate!\n" );
unsigned char * inchar = (unsigned char*)bufptr;
unsigned char * outchar = (unsigned char*)imgptr;
int failuresPrinted = 0;
int i;
for (i=0; i< (int)buffer_size; i+=(int)elem_size) {
int failed = 0;
int j;
for (j=0; j<(int)elem_size; j++)
if (inchar[i+j] != outchar[i+j])
failed = 1;
char values[4096];
values[0] = 0;
if (failed) {
sprintf(values + strlen(values), "%d(0x%x) -> actual [", i, i);
int j;
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", inchar[i+j]);
sprintf(values + strlen(values), "] != expected [");
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", outchar[i+j]);
sprintf(values + strlen(values), "]");
log_error("%s\n", values);
failuresPrinted++;
}
if (failuresPrinted > 5) {
log_error("Not printing further failures...\n");
break;
}
if (CL_MEM_OBJECT_IMAGE2D == image_type)
{
image = create_image_2d(context, flags, format, img_width, img_height,
0, nullptr, &err);
}
err = -1;
}
else
{
image = create_image_3d(context, flags, format, img_width, img_height,
img_depth, 0, 0, nullptr, &err);
}
test_error(err, "create_image_xd failed");
free(bufptr);
free(imgptr);
err = clGetImageInfo(image, CL_IMAGE_ELEMENT_SIZE, sizeof(size_t),
&elem_size, NULL);
test_error(err, "clGetImageInfo failed");
if (err)
log_error("ARRAY to IMAGE copy test failed for image_channel_order=0x%lx and image_channel_data_type=0x%lx\n",
(unsigned long)format->image_channel_order, (unsigned long)format->image_channel_data_type);
buffer_size =
sizeof(cl_uchar) * elem_size * img_width * img_height * img_depth;
return err;
buffer =
clCreateBuffer(context, CL_MEM_READ_WRITE, buffer_size, NULL, &err);
test_error(err, "clCreateBuffer failed");
RandomSeed seed(gRandomSeed);
bufptr =
static_cast<cl_uchar *>(create_random_data(kUChar, seed, buffer_size));
size_t origin[3] = { 0, 0, 0 },
region[3] = { img_width, img_height, img_depth };
err = clEnqueueWriteBuffer(queue, buffer, CL_TRUE, 0, buffer_size, bufptr,
0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueCopyBufferToImage(queue, buffer, image, 0, origin, region, 0,
NULL, &copyevent);
test_error(err, "clEnqueueCopyImageToBuffer failed");
imgptr = static_cast<cl_uchar *>(malloc(buffer_size));
err = clEnqueueReadImage(queue, image, CL_TRUE, origin, region, 0, 0,
imgptr, 1, &copyevent, NULL);
test_error(err, "clEnqueueReadImage failed");
err = clReleaseEvent(copyevent);
test_error(err, "clReleaseEvent failed");
if (memcmp(bufptr, imgptr, buffer_size) != 0)
{
log_error("ERROR: Results did not validate!\n");
auto inchar = static_cast<unsigned char *>(bufptr);
auto outchar = static_cast<unsigned char *>(imgptr);
int failuresPrinted = 0;
for (int i = 0; i < (int)buffer_size; i += (int)elem_size)
{
if (memcmp(&inchar[i], &outchar[i], elem_size) != 0)
{
log_error("%d(0x%x) -> actual [", i, i);
for (int j = 0; j < (int)elem_size; j++)
log_error("0x%02x ", inchar[i + j]);
log_error("] != expected [");
for (int j = 0; j < (int)elem_size; j++)
log_error("0x%02x ", outchar[i + j]);
log_error("]\n");
failuresPrinted++;
}
if (failuresPrinted > 5)
{
log_error("Not printing further failures...\n");
break;
}
}
err = -1;
}
free(bufptr);
free(imgptr);
if (err)
log_error(
"ARRAY to IMAGE copy test failed for image_channel_order=0x%lx and "
"image_channel_data_type=0x%lx\n",
(unsigned long)format->image_channel_order,
(unsigned long)format->image_channel_data_type);
return err;
}
int test_arrayimagecopy(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
int test_arrayimagecommon(cl_device_id device, cl_context context,
cl_command_queue queue, cl_mem_flags flags,
cl_mem_object_type image_type)
{
cl_int err;
cl_image_format *formats;
cl_uint num_formats;
cl_uint i;
cl_int err;
cl_uint num_formats;
PASSIVE_REQUIRE_IMAGE_SUPPORT( device )
err = clGetSupportedImageFormats(context, flags, image_type, 0, NULL,
&num_formats);
test_error(err, "clGetSupportedImageFormats failed");
err = clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D, 0, NULL, &num_formats);
test_error(err, "clGetSupportedImageFormats failed");
std::vector<cl_image_format> formats(num_formats);
formats = (cl_image_format *)malloc(num_formats * sizeof(cl_image_format));
err = clGetSupportedImageFormats(context, flags, image_type, num_formats,
formats.data(), NULL);
test_error(err, "clGetSupportedImageFormats failed");
err = clGetSupportedImageFormats(context, CL_MEM_READ_WRITE, CL_MEM_OBJECT_IMAGE2D, num_formats, formats, NULL);
test_error(err, "clGetSupportedImageFormats failed");
for (const auto &format : formats)
{
err |= test_arrayimagecopy_single_format(device, context, queue, flags,
image_type, &format);
}
for (i = 0; i < num_formats; i++) {
err |= test_arrayimagecopy_single_format(device, context, queue, &formats[i]);
}
if (err)
log_error("ARRAY to IMAGE%s copy test failed\n",
convert_image_type_to_string(image_type));
else
log_info("ARRAY to IMAGE%s copy test passed\n",
convert_image_type_to_string(image_type));
free(formats);
if (err)
log_error("ARRAY to IMAGE copy test failed\n");
else
log_info("ARRAY to IMAGE copy test passed\n");
return err;
return err;
}
int test_arrayimagecopy(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
PASSIVE_REQUIRE_IMAGE_SUPPORT(device)
return test_arrayimagecommon(device, context, queue, CL_MEM_READ_WRITE,
CL_MEM_OBJECT_IMAGE2D);
}
int test_arrayimagecopy3d(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT(device)
return test_arrayimagecommon(device, context, queue, CL_MEM_READ_ONLY,
CL_MEM_OBJECT_IMAGE3D);
}

View file

@ -1,151 +0,0 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
int test_arrayimagecopy3d_single_format(cl_device_id device, cl_context context, cl_command_queue queue, cl_image_format *format)
{
cl_uchar *bufptr, *imgptr;
clMemWrapper buffer, image;
int img_width = 128;
int img_height = 128;
int img_depth = 32;
size_t elem_size;
size_t buffer_size;
int i;
cl_int err;
MTdata d;
cl_event copyevent;
log_info("Testing %s %s\n", GetChannelOrderName(format->image_channel_order), GetChannelTypeName(format->image_channel_data_type));
image = create_image_3d(context, CL_MEM_READ_ONLY, format, img_width,
img_height, img_depth, 0, 0, NULL, &err);
test_error(err, "create_image_3d failed");
err = clGetImageInfo(image, CL_IMAGE_ELEMENT_SIZE, sizeof(size_t), &elem_size, NULL);
test_error(err, "clGetImageInfo failed");
buffer_size = sizeof(cl_uchar) * elem_size * img_width * img_height * img_depth;
buffer = clCreateBuffer(context, CL_MEM_READ_WRITE, buffer_size, NULL, &err);
test_error(err, "clCreateBuffer failed");
d = init_genrand( gRandomSeed );
bufptr = (cl_uchar*)malloc(buffer_size);
for (i=0; i<(int)buffer_size; i++) {
bufptr[i] = (cl_uchar)genrand_int32(d);
}
free_mtdata(d); d = NULL;
size_t origin[3]={0,0,0}, region[3]={img_width,img_height,img_depth};
err = clEnqueueWriteBuffer( queue, buffer, CL_TRUE, 0, buffer_size, bufptr, 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueCopyBufferToImage( queue, buffer, image, 0, origin, region, 0, NULL, &copyevent );
test_error(err, "clEnqueueCopyImageToBuffer failed");
imgptr = (cl_uchar*)malloc(buffer_size);
err = clEnqueueReadImage( queue, image, CL_TRUE, origin, region, 0, 0, imgptr, 1, &copyevent, NULL );
test_error(err, "clEnqueueReadBuffer failed");
err = clReleaseEvent(copyevent);
test_error(err, "clReleaseEvent failed");
if (memcmp(bufptr, imgptr, buffer_size) != 0) {
log_error( "ERROR: Results did not validate!\n" );
unsigned char * inchar = (unsigned char*)bufptr;
unsigned char * outchar = (unsigned char*)imgptr;
int failuresPrinted = 0;
int i;
for (i=0; i< (int)buffer_size; i+=(int)elem_size) {
int failed = 0;
int j;
for (j=0; j<(int)elem_size; j++)
if (inchar[i+j] != outchar[i+j])
failed = 1;
char values[4096];
values[0] = 0;
if (failed) {
sprintf(values + strlen(values), "%d(0x%x) -> actual [", i, i);
int j;
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", inchar[i+j]);
sprintf(values + strlen(values), "] != expected [");
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", outchar[i+j]);
sprintf(values + strlen(values), "]");
log_error("%s\n", values);
failuresPrinted++;
}
if (failuresPrinted > 5) {
log_error("Not printing further failures...\n");
break;
}
}
err = -1;
}
free(bufptr);
free(imgptr);
if (err)
log_error("ARRAY to IMAGE3D copy test failed for image_channel_order=0x%lx and image_channel_data_type=0x%lx\n",
(unsigned long)format->image_channel_order, (unsigned long)format->image_channel_data_type);
return err;
}
int test_arrayimagecopy3d(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
cl_int err;
cl_image_format *formats;
cl_uint num_formats;
cl_uint i;
PASSIVE_REQUIRE_3D_IMAGE_SUPPORT( device )
err = clGetSupportedImageFormats(
context, CL_MEM_READ_ONLY, CL_MEM_OBJECT_IMAGE3D, 0, NULL, &num_formats);
test_error(err, "clGetSupportedImageFormats failed");
formats = (cl_image_format *)malloc(num_formats * sizeof(cl_image_format));
err = clGetSupportedImageFormats(context, CL_MEM_READ_ONLY,
CL_MEM_OBJECT_IMAGE3D, num_formats, formats,
NULL);
test_error(err, "clGetSupportedImageFormats failed");
for (i = 0; i < num_formats; i++) {
err |= test_arrayimagecopy3d_single_format(device, context, queue, &formats[i]);
}
free(formats);
if (err)
log_error("ARRAY to IMAGE3D copy test failed\n");
else
log_info("ARRAY to IMAGE3D copy test passed\n");
return err;
}

View file

@ -25,77 +25,81 @@
#include "../../test_common/harness/conversions.h"
#include "procs.h"
static const char *async_global_to_local_kernel2D =
"#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable\n"
"%s\n" // optional pragma string
"__kernel void test_fn( const __global %s *src, __global %s *dst, __local "
"%s *localBuffer, int numElementsPerLine, int lineCopiesPerWorkgroup, int "
"lineCopiesPerWorkItem, int srcStride, int dstStride )\n"
"{\n"
" int i, j;\n"
// Zero the local storage first
" for(i=0; i<lineCopiesPerWorkItem; i++)\n"
" for(j=0; j<numElementsPerLine; j++)\n"
" localBuffer[ (get_local_id( 0 "
")*lineCopiesPerWorkItem+i)*(numElementsPerLine + dstStride)+j ] = "
"(%s)(%s)0;\n"
// Do this to verify all kernels are done zeroing the local buffer before we
// try the copy
" barrier( CLK_LOCAL_MEM_FENCE );\n"
" event_t event;\n"
" event = async_work_group_copy_2D2D( (__local %s*)localBuffer, "
"(__global const "
"%s*)(src+lineCopiesPerWorkgroup*get_group_id(0)*(numElementsPerLine + "
"srcStride)), (size_t)numElementsPerLine, (size_t)lineCopiesPerWorkgroup, "
"srcStride, dstStride, 0 );\n"
// Wait for the copy to complete, then verify by manually copying to the
// dest
" wait_group_events( 1, &event );\n"
" for(i=0; i<lineCopiesPerWorkItem; i++)\n"
" for(j=0; j<numElementsPerLine; j++)\n"
" dst[ (get_global_id( 0 "
")*lineCopiesPerWorkItem+i)*(numElementsPerLine + dstStride)+j ] = "
"localBuffer[ (get_local_id( 0 "
")*lineCopiesPerWorkItem+i)*(numElementsPerLine + dstStride)+j ];\n"
"}\n";
static const char *async_global_to_local_kernel2D = R"OpenCLC(
#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable
%s // optional pragma string
static const char *async_local_to_global_kernel2D =
"#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable\n"
"%s\n" // optional pragma string
"__kernel void test_fn( const __global %s *src, __global %s *dst, __local "
"%s *localBuffer, int numElementsPerLine, int lineCopiesPerWorkgroup, int "
"lineCopiesPerWorkItem, int srcStride, int dstStride )\n"
"{\n"
" int i, j;\n"
// Zero the local storage first
" for(i=0; i<lineCopiesPerWorkItem; i++)\n"
" for(j=0; j<numElementsPerLine; j++)\n"
" localBuffer[ (get_local_id( 0 "
")*lineCopiesPerWorkItem+i)*(numElementsPerLine + srcStride)+j ] = "
"(%s)(%s)0;\n"
// Do this to verify all kernels are done zeroing the local buffer before we
// try the copy
" barrier( CLK_LOCAL_MEM_FENCE );\n"
" for(i=0; i<lineCopiesPerWorkItem; i++)\n"
" for(j=0; j<numElementsPerLine; j++)\n"
" localBuffer[ (get_local_id( 0 "
")*lineCopiesPerWorkItem+i)*(numElementsPerLine + srcStride)+j ] = src[ "
"(get_global_id( 0 )*lineCopiesPerWorkItem+i)*(numElementsPerLine + "
"srcStride)+j ];\n"
// Do this to verify all kernels are done copying to the local buffer before
// we try the copy
" barrier( CLK_LOCAL_MEM_FENCE );\n"
" event_t event;\n"
" event = async_work_group_copy_2D2D((__global "
"%s*)(dst+lineCopiesPerWorkgroup*get_group_id(0)*(numElementsPerLine + "
"dstStride)), (__local const %s*)localBuffer, (size_t)numElementsPerLine, "
"(size_t)lineCopiesPerWorkgroup, srcStride, dstStride, 0 );\n"
" wait_group_events( 1, &event );\n"
"}\n";
__kernel void test_fn(const __global %s *src, __global %s *dst,
__local %s *localBuffer, int numElementsPerLine,
int lineCopiesPerWorkgroup, int lineCopiesPerWorkItem,
int srcStride, int dstStride) {
// Zero the local storage first
for (int i = 0; i < lineCopiesPerWorkItem; i++) {
for (int j = 0; j < numElementsPerLine; j++) {
const int index = (get_local_id(0) * lineCopiesPerWorkItem + i) * dstStride + j;
localBuffer[index] = (%s)(%s)0;
}
}
// Do this to verify all kernels are done zeroing the local buffer before we
// try the copy
barrier( CLK_LOCAL_MEM_FENCE );
event_t event = async_work_group_copy_2D2D(localBuffer, 0, src,
lineCopiesPerWorkgroup * get_group_id(0) * srcStride, sizeof(%s),
(size_t)numElementsPerLine, (size_t)lineCopiesPerWorkgroup, srcStride, dstStride, 0);
// Wait for the copy to complete, then verify by manually copying to the dest
wait_group_events(1, &event);
for (int i = 0; i < lineCopiesPerWorkItem; i++) {
for (int j = 0; j < numElementsPerLine; j++) {
const int local_index = (get_local_id(0) * lineCopiesPerWorkItem + i) * dstStride + j;
const int global_index = (get_global_id(0) * lineCopiesPerWorkItem + i) * dstStride + j;
dst[global_index] = localBuffer[local_index];
}
}
}
)OpenCLC";
static const char *async_local_to_global_kernel2D = R"OpenCLC(
#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable
%s // optional pragma string
__kernel void test_fn(const __global %s *src, __global %s *dst, __local %s *localBuffer,
int numElementsPerLine, int lineCopiesPerWorkgroup,
int lineCopiesPerWorkItem, int srcStride, int dstStride) {
// Zero the local storage first
for (int i = 0; i < lineCopiesPerWorkItem; i++) {
for (int j = 0; j < numElementsPerLine; j++) {
const int index = (get_local_id(0) * lineCopiesPerWorkItem + i) * srcStride + j;
localBuffer[index] = (%s)(%s)0;
}
}
// Do this to verify all kernels are done zeroing the local buffer before we try the copy
barrier(CLK_LOCAL_MEM_FENCE);
for (int i = 0; i < lineCopiesPerWorkItem; i++) {
for (int j = 0; j < numElementsPerLine; j++) {
const int local_index = (get_local_id(0) * lineCopiesPerWorkItem + i) * srcStride + j;
const int global_index = (get_global_id(0)*lineCopiesPerWorkItem + i) * srcStride + j;
localBuffer[local_index] = src[global_index];
}
}
// Do this to verify all kernels are done copying to the local buffer before we try the copy
barrier(CLK_LOCAL_MEM_FENCE);
event_t event = async_work_group_copy_2D2D(dst, lineCopiesPerWorkgroup * get_group_id(0) * dstStride,
localBuffer, 0, sizeof(%s), (size_t)numElementsPerLine, (size_t)lineCopiesPerWorkgroup, srcStride,
dstStride, 0 );
wait_group_events(1, &event);
};
)OpenCLC";
int test_copy2D(cl_device_id deviceID, cl_context context,
cl_command_queue queue, const char *kernelCode,
ExplicitType vecType, int vecSize, int srcStride, int dstStride,
ExplicitType vecType, int vecSize, int srcMargin, int dstMargin,
bool localIsDst)
{
int error;
@ -114,15 +118,8 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
vecSize);
size_t elementSize = get_explicit_type_size(vecType) * vecSize;
log_info("Testing %s with srcStride = %d, dstStride = %d\n", vecNameString,
srcStride, dstStride);
if (!is_extension_available(deviceID, "cl_khr_extended_async_copies"))
{
log_info(
"Device does not support extended async copies. Skipping test.\n");
return 0;
}
log_info("Testing %s with srcMargin = %d, dstMargin = %d\n", vecNameString,
srcMargin, dstMargin);
cl_long max_local_mem_size;
error =
@ -160,7 +157,7 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
vecType == kDouble ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable"
: "",
vecNameString, vecNameString, vecNameString, vecNameString,
get_explicit_type_name(vecType), vecNameString, vecNameString);
get_explicit_type_name(vecType), vecNameString);
// log_info("program: %s\n", programSource);
programPtr = programSource;
@ -187,12 +184,17 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
if (max_workgroup_size > max_local_workgroup_size[0])
max_workgroup_size = max_local_workgroup_size[0];
size_t numElementsPerLine = 10;
size_t lineCopiesPerWorkItem = 13;
const size_t numElementsPerLine = 10;
const cl_int dstStride = numElementsPerLine + dstMargin;
const cl_int srcStride = numElementsPerLine + srcMargin;
elementSize =
get_explicit_type_size(vecType) * ((vecSize == 3) ? 4 : vecSize);
size_t localStorageSpacePerWorkitem = lineCopiesPerWorkItem * elementSize
* (numElementsPerLine + (localIsDst ? dstStride : srcStride));
const size_t lineCopiesPerWorkItem = 13;
const size_t localStorageSpacePerWorkitem = lineCopiesPerWorkItem
* elementSize * (localIsDst ? dstStride : srcStride);
size_t maxLocalWorkgroupSize =
(((int)max_local_mem_size / 2) / localStorageSpacePerWorkitem);
@ -206,34 +208,39 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
if (maxLocalWorkgroupSize > max_workgroup_size)
localWorkgroupSize = max_workgroup_size;
size_t maxTotalLinesIn = (max_alloc_size / elementSize + srcStride)
/ (numElementsPerLine + srcStride);
size_t maxTotalLinesOut = (max_alloc_size / elementSize + dstStride)
/ (numElementsPerLine + dstStride);
size_t maxTotalLines = (std::min)(maxTotalLinesIn, maxTotalLinesOut);
size_t maxLocalWorkgroups =
const size_t maxTotalLinesIn =
(max_alloc_size / elementSize + srcMargin) / srcStride;
const size_t maxTotalLinesOut =
(max_alloc_size / elementSize + dstMargin) / dstStride;
const size_t maxTotalLines = std::min(maxTotalLinesIn, maxTotalLinesOut);
const size_t maxLocalWorkgroups =
maxTotalLines / (localWorkgroupSize * lineCopiesPerWorkItem);
size_t localBufferSize = localWorkgroupSize * localStorageSpacePerWorkitem
- (localIsDst ? dstStride : srcStride);
size_t numberOfLocalWorkgroups = (std::min)(1111, (int)maxLocalWorkgroups);
size_t totalLines =
const size_t localBufferSize =
localWorkgroupSize * localStorageSpacePerWorkitem
- (localIsDst ? dstMargin : srcMargin);
const size_t numberOfLocalWorkgroups =
std::min(1111, (int)maxLocalWorkgroups);
const size_t totalLines =
numberOfLocalWorkgroups * localWorkgroupSize * lineCopiesPerWorkItem;
size_t inBufferSize = elementSize
* (totalLines * numElementsPerLine + (totalLines - 1) * srcStride);
size_t outBufferSize = elementSize
* (totalLines * numElementsPerLine + (totalLines - 1) * dstStride);
size_t globalWorkgroupSize = numberOfLocalWorkgroups * localWorkgroupSize;
const size_t inBufferSize = elementSize
* (totalLines * numElementsPerLine + (totalLines - 1) * srcMargin);
const size_t outBufferSize = elementSize
* (totalLines * numElementsPerLine + (totalLines - 1) * dstMargin);
const size_t globalWorkgroupSize =
numberOfLocalWorkgroups * localWorkgroupSize;
inBuffer = (void *)malloc(inBufferSize);
outBuffer = (void *)malloc(outBufferSize);
outBufferCopy = (void *)malloc(outBufferSize);
cl_int lineCopiesPerWorkItemInt, numElementsPerLineInt,
lineCopiesPerWorkgroup;
lineCopiesPerWorkItemInt = (int)lineCopiesPerWorkItem;
numElementsPerLineInt = (int)numElementsPerLine;
lineCopiesPerWorkgroup = (int)(lineCopiesPerWorkItem * localWorkgroupSize);
const cl_int lineCopiesPerWorkItemInt =
static_cast<cl_int>(lineCopiesPerWorkItem);
const cl_int numElementsPerLineInt =
static_cast<cl_int>(numElementsPerLine);
const cl_int lineCopiesPerWorkgroup =
static_cast<cl_int>(lineCopiesPerWorkItem * localWorkgroupSize);
log_info(
"Global: %d, local %d, local buffer %db, global in buffer %db, "
@ -303,8 +310,8 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
for (int j = 0; j < (int)numElementsPerLine * elementSize;
j += elementSize)
{
int inIdx = i * (numElementsPerLine + srcStride) + j;
int outIdx = i * (numElementsPerLine + dstStride) + j;
int inIdx = i * srcStride + j;
int outIdx = i * dstStride + j;
if (memcmp(((char *)inBuffer) + inIdx, ((char *)outBuffer) + outIdx,
typeSize)
!= 0)
@ -339,11 +346,10 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
if (i < (int)(globalWorkgroupSize * lineCopiesPerWorkItem - 1)
* elementSize)
{
int outIdx = i * (numElementsPerLine + dstStride)
+ numElementsPerLine * elementSize;
int outIdx = i * dstStride + numElementsPerLine * elementSize;
if (memcmp(((char *)outBuffer) + outIdx,
((char *)outBufferCopy) + outIdx,
dstStride * elementSize)
dstMargin * elementSize)
!= 0)
{
if (failuresPrinted == 0)
@ -380,12 +386,22 @@ int test_copy2D_all_types(cl_device_id deviceID, cl_context context,
kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong,
kULong, kFloat, kDouble, kNumExplicitTypes
};
// The margins below represent the number of elements between the end of
// one line and the start of the next. The strides are equivalent to the
// length of the line plus the chosen margin.
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int smallTypesStrideSizes[] = { 0, 10, 100 };
unsigned int size, typeIndex, srcStride, dstStride;
unsigned int smallTypesMarginSizes[] = { 0, 10, 100 };
unsigned int size, typeIndex, srcMargin, dstMargin;
int errors = 0;
if (!is_extension_available(deviceID, "cl_khr_extended_async_copies"))
{
log_info(
"Device does not support extended async copies. Skipping test.\n");
return 0;
}
for (typeIndex = 0; vecType[typeIndex] != kNumExplicitTypes; typeIndex++)
{
if (vecType[typeIndex] == kDouble
@ -401,19 +417,19 @@ int test_copy2D_all_types(cl_device_id deviceID, cl_context context,
if (get_explicit_type_size(vecType[typeIndex]) * vecSizes[size]
<= 2) // small type
{
for (srcStride = 0; srcStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
srcStride++)
for (srcMargin = 0; srcMargin < sizeof(smallTypesMarginSizes)
/ sizeof(smallTypesMarginSizes[0]);
srcMargin++)
{
for (dstStride = 0;
dstStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
dstStride++)
for (dstMargin = 0;
dstMargin < sizeof(smallTypesMarginSizes)
/ sizeof(smallTypesMarginSizes[0]);
dstMargin++)
{
if (test_copy2D(deviceID, context, queue, kernelCode,
vecType[typeIndex], vecSizes[size],
smallTypesStrideSizes[srcStride],
smallTypesStrideSizes[dstStride],
smallTypesMarginSizes[srcMargin],
smallTypesMarginSizes[dstMargin],
localIsDst))
{
errors++;

View file

@ -25,96 +25,95 @@
#include "../../test_common/harness/conversions.h"
#include "procs.h"
static const char *async_global_to_local_kernel3D =
"#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable\n"
"%s\n" // optional pragma string
"__kernel void test_fn( const __global %s *src, __global %s *dst, __local "
"%s *localBuffer, int numElementsPerLine, int numLines, int "
"planesCopiesPerWorkgroup, int planesCopiesPerWorkItem, int srcLineStride, "
"int dstLineStride, int srcPlaneStride, int dstPlaneStride )\n"
"{\n"
" int i, j, k;\n"
// Zero the local storage first
" for(i=0; i<planesCopiesPerWorkItem; i++)\n"
" for(j=0; j<numLines; j++)\n"
" for(k=0; k<numElementsPerLine; k++)\n"
" localBuffer[ (get_local_id( 0 "
")*planesCopiesPerWorkItem+i)*(numLines*numElementsPerLine + "
"numLines*dstLineStride + dstPlaneStride) + j*(numElementsPerLine + "
"dstLineStride) + k ] = (%s)(%s)0;\n"
// Do this to verify all kernels are done zeroing the local buffer before we
// try the copy
" barrier( CLK_LOCAL_MEM_FENCE );\n"
" event_t event;\n"
" event = async_work_group_copy_3D3D( (__local %s*)localBuffer, "
"(__global const "
"%s*)(src+planesCopiesPerWorkgroup*get_group_id(0)*(numLines*"
"numElementsPerLine + numLines*srcLineStride + srcPlaneStride)), "
"(size_t)numElementsPerLine, (size_t)numLines, srcLineStride, "
"dstLineStride, planesCopiesPerWorkgroup, srcPlaneStride, dstPlaneStride, "
"0 );\n"
// Wait for the copy to complete, then verify by manually copying to the
// dest
" wait_group_events( 1, &event );\n"
" for(i=0; i<planesCopiesPerWorkItem; i++)\n"
" for(j=0; j<numLines; j++)\n"
" for(k=0; k<numElementsPerLine; k++)\n"
" dst[ (get_global_id( 0 "
")*planesCopiesPerWorkItem+i)*(numLines*numElementsPerLine + "
"numLines*dstLineStride + dstPlaneStride) + j*(numElementsPerLine + "
"dstLineStride) + k ] = localBuffer[ (get_local_id( 0 "
")*planesCopiesPerWorkItem+i)*(numLines*numElementsPerLine + "
"numLines*dstLineStride + dstPlaneStride) + j*(numElementsPerLine + "
"dstLineStride) + k ];\n"
"}\n";
static const char *async_global_to_local_kernel3D = R"OpenCLC(
#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable
%s // optional pragma string
static const char *async_local_to_global_kernel3D =
"#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable\n"
"%s\n" // optional pragma string
"__kernel void test_fn( const __global %s *src, __global %s *dst, __local "
"%s *localBuffer, int numElementsPerLine, int numLines, int "
"planesCopiesPerWorkgroup, int planesCopiesPerWorkItem, int srcLineStride, "
"int dstLineStride, int srcPlaneStride, int dstPlaneStride )\n"
"{\n"
" int i, j, k;\n"
// Zero the local storage first
" for(i=0; i<planesCopiesPerWorkItem; i++)\n"
" for(j=0; j<numLines; j++)\n"
" for(k=0; k<numElementsPerLine; k++)\n"
" localBuffer[ (get_local_id( 0 "
")*planesCopiesPerWorkItem+i)*(numLines*numElementsPerLine + "
"numLines*srcLineStride + srcPlaneStride) + j*(numElementsPerLine + "
"srcLineStride) + k ] = (%s)(%s)0;\n"
// Do this to verify all kernels are done zeroing the local buffer before we
// try the copy
" barrier( CLK_LOCAL_MEM_FENCE );\n"
" for(i=0; i<planesCopiesPerWorkItem; i++)\n"
" for(j=0; j<numLines; j++)\n"
" for(k=0; k<numElementsPerLine; k++)\n"
" localBuffer[ (get_local_id( 0 "
")*planesCopiesPerWorkItem+i)*(numLines*numElementsPerLine + "
"numLines*srcLineStride + srcPlaneStride) + j*(numElementsPerLine + "
"srcLineStride) + k ] = src[ (get_global_id( 0 "
")*planesCopiesPerWorkItem+i)*(numLines*numElementsPerLine + "
"numLines*srcLineStride + srcPlaneStride) + j*(numElementsPerLine + "
"srcLineStride) + k ];\n"
// Do this to verify all kernels are done copying to the local buffer before
// we try the copy
" barrier( CLK_LOCAL_MEM_FENCE );\n"
" event_t event;\n"
" event = async_work_group_copy_3D3D((__global "
"%s*)(dst+planesCopiesPerWorkgroup*get_group_id(0)*(numLines*"
"numElementsPerLine + numLines*dstLineStride + dstPlaneStride)), (__local "
"const %s*)localBuffer, (size_t)numElementsPerLine, (size_t)numLines, "
"srcLineStride, dstLineStride, planesCopiesPerWorkgroup, srcPlaneStride, "
"dstPlaneStride, 0 );\n"
" wait_group_events( 1, &event );\n"
"}\n";
__kernel void test_fn(const __global %s *src, __global %s *dst, __local %s *localBuffer,
int numElementsPerLine, int numLines, int planesCopiesPerWorkgroup,
int planesCopiesPerWorkItem, int srcLineStride,
int dstLineStride, int srcPlaneStride, int dstPlaneStride ) {
// Zero the local storage first
for (int i = 0; i < planesCopiesPerWorkItem; i++) {
for (int j = 0; j < numLines; j++) {
for (int k = 0; k < numElementsPerLine; k++) {
const int index = (get_local_id(0) * planesCopiesPerWorkItem + i) * dstPlaneStride + j * dstLineStride + k;
localBuffer[index] = (%s)(%s)0;
}
}
}
// Do this to verify all kernels are done zeroing the local buffer before we try the copy
barrier(CLK_LOCAL_MEM_FENCE);
event_t event = async_work_group_copy_3D3D(localBuffer, 0, src,
planesCopiesPerWorkgroup * get_group_id(0) * srcPlaneStride,
sizeof(%s), (size_t)numElementsPerLine, (size_t)numLines,
planesCopiesPerWorkgroup, srcLineStride, srcPlaneStride, dstLineStride,
dstPlaneStride, 0);
// Wait for the copy to complete, then verify by manually copying to the dest
wait_group_events(1, &event);
for (int i = 0; i < planesCopiesPerWorkItem; i++) {
for (int j = 0; j < numLines; j++) {
for(int k = 0; k < numElementsPerLine; k++) {
const int local_index = (get_local_id(0) * planesCopiesPerWorkItem + i) * dstPlaneStride + j * dstLineStride + k;
const int global_index = (get_global_id(0) * planesCopiesPerWorkItem + i) * dstPlaneStride + j * dstLineStride + k;
dst[global_index] = localBuffer[local_index];
}
}
}
}
)OpenCLC";
static const char *async_local_to_global_kernel3D = R"OpenCLC(
#pragma OPENCL EXTENSION cl_khr_extended_async_copies : enable
%s // optional pragma string
__kernel void test_fn(const __global %s *src, __global %s *dst, __local %s *localBuffer,
int numElementsPerLine, int numLines, int planesCopiesPerWorkgroup,
int planesCopiesPerWorkItem, int srcLineStride,
int dstLineStride, int srcPlaneStride, int dstPlaneStride) {
// Zero the local storage first
for (int i = 0; i < planesCopiesPerWorkItem; i++) {
for (int j = 0; j < numLines; j++) {
for (int k = 0; k < numElementsPerLine; k++) {
const int index = (get_local_id(0) * planesCopiesPerWorkItem + i) * srcPlaneStride + j * srcLineStride + k;
localBuffer[index] = (%s)(%s)0;
}
}
}
// Do this to verify all kernels are done zeroing the local buffer before we try the copy
barrier(CLK_LOCAL_MEM_FENCE);
for (int i=0; i < planesCopiesPerWorkItem; i++) {
for (int j=0; j < numLines; j++) {
for (int k=0; k < numElementsPerLine; k++) {
const int local_index = (get_local_id(0) * planesCopiesPerWorkItem + i) * srcPlaneStride + j * srcLineStride + k;
const int global_index = (get_global_id(0) * planesCopiesPerWorkItem + i) * srcPlaneStride + j*srcLineStride + k;
localBuffer[local_index] = src[global_index];
}
}
}
// Do this to verify all kernels are done copying to the local buffer before we try the copy
barrier(CLK_LOCAL_MEM_FENCE);
event_t event = async_work_group_copy_3D3D(dst,
planesCopiesPerWorkgroup * get_group_id(0) * dstPlaneStride, localBuffer, 0,
sizeof(%s), (size_t)numElementsPerLine, (size_t)numLines, planesCopiesPerWorkgroup,
srcLineStride, srcPlaneStride, dstLineStride, dstPlaneStride, 0);
wait_group_events(1, &event);
}
)OpenCLC";
int test_copy3D(cl_device_id deviceID, cl_context context,
cl_command_queue queue, const char *kernelCode,
ExplicitType vecType, int vecSize, int srcLineStride,
int dstLineStride, int srcPlaneStride, int dstPlaneStride,
ExplicitType vecType, int vecSize, int srcLineMargin,
int dstLineMargin, int srcPlaneMargin, int dstPlaneMargin,
bool localIsDst)
{
int error;
@ -133,17 +132,10 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
vecSize);
size_t elementSize = get_explicit_type_size(vecType) * vecSize;
log_info("Testing %s with srcLineStride = %d, dstLineStride = %d, "
"srcPlaneStride = %d, dstPlaneStride = %d\n",
vecNameString, srcLineStride, dstLineStride, srcPlaneStride,
dstPlaneStride);
if (!is_extension_available(deviceID, "cl_khr_extended_async_copies"))
{
log_info(
"Device does not support extended async copies. Skipping test.\n");
return 0;
}
log_info("Testing %s with srcLineMargin = %d, dstLineMargin = %d, "
"srcPlaneMargin = %d, dstPlaneMargin = %d\n",
vecNameString, srcLineMargin, dstLineMargin, srcPlaneMargin,
dstPlaneMargin);
cl_long max_local_mem_size;
error =
@ -208,16 +200,20 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
if (max_workgroup_size > max_local_workgroup_size[0])
max_workgroup_size = max_local_workgroup_size[0];
size_t numElementsPerLine = 10;
size_t numLines = 13;
size_t planesCopiesPerWorkItem = 2;
const size_t numElementsPerLine = 10;
const cl_int dstLineStride = numElementsPerLine + dstLineMargin;
const cl_int srcLineStride = numElementsPerLine + srcLineMargin;
const size_t numLines = 13;
const cl_int dstPlaneStride = (numLines * dstLineStride) + dstPlaneMargin;
const cl_int srcPlaneStride = (numLines * srcLineStride) + srcPlaneMargin;
elementSize =
get_explicit_type_size(vecType) * ((vecSize == 3) ? 4 : vecSize);
size_t localStorageSpacePerWorkitem = elementSize
* (planesCopiesPerWorkItem
* (numLines * numElementsPerLine
+ numLines * (localIsDst ? dstLineStride : srcLineStride)
+ (localIsDst ? dstPlaneStride : srcPlaneStride)));
const size_t planesCopiesPerWorkItem = 2;
const size_t localStorageSpacePerWorkitem = elementSize
* planesCopiesPerWorkItem
* (localIsDst ? dstPlaneStride : srcPlaneStride);
size_t maxLocalWorkgroupSize =
(((int)max_local_mem_size / 2) / localStorageSpacePerWorkitem);
@ -231,42 +227,41 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
if (maxLocalWorkgroupSize > max_workgroup_size)
localWorkgroupSize = max_workgroup_size;
size_t maxTotalPlanesIn = ((max_alloc_size / elementSize) + srcPlaneStride)
/ ((numLines * numElementsPerLine + numLines * srcLineStride)
+ srcPlaneStride);
size_t maxTotalPlanesOut = ((max_alloc_size / elementSize) + dstPlaneStride)
/ ((numLines * numElementsPerLine + numLines * dstLineStride)
+ dstPlaneStride);
size_t maxTotalPlanes = (std::min)(maxTotalPlanesIn, maxTotalPlanesOut);
size_t maxLocalWorkgroups =
const size_t maxTotalPlanesIn =
((max_alloc_size / elementSize) + srcPlaneMargin) / srcPlaneStride;
const size_t maxTotalPlanesOut =
((max_alloc_size / elementSize) + dstPlaneMargin) / dstPlaneStride;
const size_t maxTotalPlanes = std::min(maxTotalPlanesIn, maxTotalPlanesOut);
const size_t maxLocalWorkgroups =
maxTotalPlanes / (localWorkgroupSize * planesCopiesPerWorkItem);
size_t localBufferSize = localWorkgroupSize * localStorageSpacePerWorkitem
- (localIsDst ? dstPlaneStride : srcPlaneStride);
size_t numberOfLocalWorkgroups = (std::min)(1111, (int)maxLocalWorkgroups);
size_t totalPlanes =
const size_t localBufferSize =
localWorkgroupSize * localStorageSpacePerWorkitem
- (localIsDst ? dstPlaneMargin : srcPlaneMargin);
const size_t numberOfLocalWorkgroups =
std::min(1111, (int)maxLocalWorkgroups);
const size_t totalPlanes =
numberOfLocalWorkgroups * localWorkgroupSize * planesCopiesPerWorkItem;
size_t inBufferSize = elementSize
* (totalPlanes
* (numLines * numElementsPerLine + numLines * srcLineStride)
+ (totalPlanes - 1) * srcPlaneStride);
size_t outBufferSize = elementSize
* (totalPlanes
* (numLines * numElementsPerLine + numLines * dstLineStride)
+ (totalPlanes - 1) * dstPlaneStride);
size_t globalWorkgroupSize = numberOfLocalWorkgroups * localWorkgroupSize;
const size_t inBufferSize = elementSize
* (totalPlanes * numLines * srcLineStride
+ (totalPlanes - 1) * srcPlaneMargin);
const size_t outBufferSize = elementSize
* (totalPlanes * numLines * dstLineStride
+ (totalPlanes - 1) * dstPlaneMargin);
const size_t globalWorkgroupSize =
numberOfLocalWorkgroups * localWorkgroupSize;
inBuffer = (void *)malloc(inBufferSize);
outBuffer = (void *)malloc(outBufferSize);
outBufferCopy = (void *)malloc(outBufferSize);
cl_int planesCopiesPerWorkItemInt, numElementsPerLineInt, numLinesInt,
planesCopiesPerWorkgroup;
planesCopiesPerWorkItemInt = (int)planesCopiesPerWorkItem;
numElementsPerLineInt = (int)numElementsPerLine;
numLinesInt = (int)numLines;
planesCopiesPerWorkgroup =
(int)(planesCopiesPerWorkItem * localWorkgroupSize);
const cl_int planesCopiesPerWorkItemInt =
static_cast<cl_int>(planesCopiesPerWorkItem);
const cl_int numElementsPerLineInt =
static_cast<cl_int>(numElementsPerLine);
const cl_int numLinesInt = static_cast<cl_int>(numLines);
const cl_int planesCopiesPerWorkgroup =
static_cast<cl_int>(planesCopiesPerWorkItem * localWorkgroupSize);
log_info("Global: %d, local %d, local buffer %db, global in buffer %db, "
"global out buffer %db, each work group will copy %d planes and "
@ -343,14 +338,8 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
for (int k = 0; k < (int)numElementsPerLine * elementSize;
k += elementSize)
{
int inIdx = i
* (numLines * numElementsPerLine
+ numLines * srcLineStride + srcPlaneStride)
+ j * (numElementsPerLine + srcLineStride) + k;
int outIdx = i
* (numLines * numElementsPerLine
+ numLines * dstLineStride + dstPlaneStride)
+ j * (numElementsPerLine + dstLineStride) + k;
int inIdx = i * srcPlaneStride + j * srcLineStride + k;
int outIdx = i * dstPlaneStride + j * dstLineStride + k;
if (memcmp(((char *)inBuffer) + inIdx,
((char *)outBuffer) + outIdx, typeSize)
!= 0)
@ -385,14 +374,11 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
}
if (j < (int)numLines * elementSize)
{
int outIdx = i
* (numLines * numElementsPerLine
+ numLines * dstLineStride + dstPlaneStride)
+ j * (numElementsPerLine + dstLineStride)
int outIdx = i * dstPlaneStride + j * dstLineStride
+ numElementsPerLine * elementSize;
if (memcmp(((char *)outBuffer) + outIdx,
((char *)outBufferCopy) + outIdx,
dstLineStride * elementSize)
dstLineMargin * elementSize)
!= 0)
{
if (failuresPrinted == 0)
@ -416,14 +402,11 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
if (i < (int)(globalWorkgroupSize * planesCopiesPerWorkItem - 1)
* elementSize)
{
int outIdx = i
* (numLines * numElementsPerLine + numLines * dstLineStride
+ dstPlaneStride)
+ (numLines * elementSize) * (numElementsPerLine)
+ (numLines * elementSize) * (dstLineStride);
int outIdx =
i * dstPlaneStride + numLines * dstLineStride * elementSize;
if (memcmp(((char *)outBuffer) + outIdx,
((char *)outBufferCopy) + outIdx,
dstPlaneStride * elementSize)
dstPlaneMargin * elementSize)
!= 0)
{
if (failuresPrinted == 0)
@ -460,13 +443,23 @@ int test_copy3D_all_types(cl_device_id deviceID, cl_context context,
kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong,
kULong, kFloat, kDouble, kNumExplicitTypes
};
// The margins below represent the number of elements between the end of
// one line or plane and the start of the next. The strides are equivalent
// to the size of the line or plane plus the chosen margin.
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int smallTypesStrideSizes[] = { 0, 10, 100 };
unsigned int size, typeIndex, srcLineStride, dstLineStride, srcPlaneStride,
dstPlaneStride;
unsigned int smallTypesMarginSizes[] = { 0, 10, 100 };
unsigned int size, typeIndex, srcLineMargin, dstLineMargin, srcPlaneMargin,
dstPlaneMargin;
int errors = 0;
if (!is_extension_available(deviceID, "cl_khr_extended_async_copies"))
{
log_info(
"Device does not support extended async copies. Skipping test.\n");
return 0;
}
for (typeIndex = 0; vecType[typeIndex] != kNumExplicitTypes; typeIndex++)
{
if (vecType[typeIndex] == kDouble
@ -482,33 +475,33 @@ int test_copy3D_all_types(cl_device_id deviceID, cl_context context,
if (get_explicit_type_size(vecType[typeIndex]) * vecSizes[size]
<= 2) // small type
{
for (srcLineStride = 0;
srcLineStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
srcLineStride++)
for (srcLineMargin = 0;
srcLineMargin < sizeof(smallTypesMarginSizes)
/ sizeof(smallTypesMarginSizes[0]);
srcLineMargin++)
{
for (dstLineStride = 0;
dstLineStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
dstLineStride++)
for (dstLineMargin = 0;
dstLineMargin < sizeof(smallTypesMarginSizes)
/ sizeof(smallTypesMarginSizes[0]);
dstLineMargin++)
{
for (srcPlaneStride = 0;
srcPlaneStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
srcPlaneStride++)
for (srcPlaneMargin = 0;
srcPlaneMargin < sizeof(smallTypesMarginSizes)
/ sizeof(smallTypesMarginSizes[0]);
srcPlaneMargin++)
{
for (dstPlaneStride = 0;
dstPlaneStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
dstPlaneStride++)
for (dstPlaneMargin = 0;
dstPlaneMargin < sizeof(smallTypesMarginSizes)
/ sizeof(smallTypesMarginSizes[0]);
dstPlaneMargin++)
{
if (test_copy3D(
deviceID, context, queue, kernelCode,
vecType[typeIndex], vecSizes[size],
smallTypesStrideSizes[srcLineStride],
smallTypesStrideSizes[dstLineStride],
smallTypesStrideSizes[srcPlaneStride],
smallTypesStrideSizes[dstPlaneStride],
smallTypesMarginSizes[srcLineMargin],
smallTypesMarginSizes[dstLineMargin],
smallTypesMarginSizes[srcPlaneMargin],
smallTypesMarginSizes[dstPlaneMargin],
localIsDst))
{
errors++;

View file

@ -360,14 +360,6 @@ int test_copy_fence(cl_device_id deviceID, cl_context context,
size_t elementSize = get_explicit_type_size(vecType) * vecSize;
log_info("Testing %s\n", vecNameString);
if (!is_extension_available(deviceID, "cl_khr_async_work_group_copy_fence"))
{
log_info(
"Device does not support extended async copies fence. Skipping "
"test.\n");
return 0;
}
cl_long max_local_mem_size;
error =
clGetDeviceInfo(deviceID, CL_DEVICE_LOCAL_MEM_SIZE,
@ -732,6 +724,14 @@ int test_copy_fence_all_types(cl_device_id deviceID, cl_context context,
int errors = 0;
if (!is_extension_available(deviceID, "cl_khr_async_work_group_copy_fence"))
{
log_info(
"Device does not support extended async copies fence. Skipping "
"test.\n");
return 0;
}
for (typeIndex = 0; vecType[typeIndex] != kNumExplicitTypes; typeIndex++)
{
if (vecType[typeIndex] == kDouble

View file

@ -146,7 +146,7 @@ int test_enqueue_map_image(cl_device_id deviceID, cl_context context, cl_command
clMemWrapper memObject;
log_info("Testing with cl_mem_flags src: %s\n", flag_set_names[src_flag_id]);
generate_random_data(kUInt, (unsigned int)(imageSize * imageSize), d,
generate_random_data(kUInt, (unsigned int)(imageSize * imageSize * 4), d,
hostPtrData);
memcpy(referenceData, hostPtrData, imageDataSize);

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -14,42 +14,45 @@
// limitations under the License.
//
#include "harness/compat.h"
#include "harness/rounding_mode.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "harness/rounding_mode.h"
#include <algorithm>
#include "procs.h"
static const char *enqueued_local_size_2d_code =
"__kernel void test_enqueued_local_size_2d(global int *dst)\n"
"{\n"
" if ((get_global_id(0) == 0) && (get_global_id(1) == 0))\n"
" {\n"
" dst[0] = (int)get_enqueued_local_size(0)\n;"
" dst[1] = (int)get_enqueued_local_size(1)\n;"
" }\n"
"}\n";
static const char *enqueued_local_size_2d_code = R"(
__kernel void test_enqueued_local_size_2d(global int *dst)
{
if ((get_global_id(0) == 0) && (get_global_id(1) == 0))
{
dst[0] = (int)get_enqueued_local_size(0);
dst[1] = (int)get_enqueued_local_size(1);
}
}
)";
static const char *enqueued_local_size_1d_code =
"__kernel void test_enqueued_local_size_1d(global int *dst)\n"
"{\n"
" int tid_x = get_global_id(0);\n"
" if (get_global_id(0) == 0)\n"
" {\n"
" dst[tid_x] = (int)get_enqueued_local_size(0)\n;"
" }\n"
"}\n";
static const char *enqueued_local_size_1d_code = R"(
__kernel void test_enqueued_local_size_1d(global int *dst)
{
int tid_x = get_global_id(0);
if (get_global_id(0) == 0)
{
dst[tid_x] = (int)get_enqueued_local_size(0);
}
}
)";
static int
verify_enqueued_local_size(int *result, size_t *expected, int n)
static int verify_enqueued_local_size(int *result, size_t *expected, int n)
{
int i;
for (i=0; i<n; i++)
for (i = 0; i < n; i++)
{
if (result[i] != (int)expected[i])
{
@ -62,14 +65,14 @@ verify_enqueued_local_size(int *result, size_t *expected, int n)
}
int
test_enqueued_local_size(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
int test_enqueued_local_size(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
cl_mem streams;
cl_program program[2];
cl_kernel kernel[2];
clMemWrapper stream;
clProgramWrapper program[2];
clKernelWrapper kernel[2];
int *output_ptr;
cl_int output_ptr[2];
size_t globalsize[2];
size_t localsize[2];
int err;
@ -95,37 +98,36 @@ test_enqueued_local_size(cl_device_id device, cl_context context, cl_command_que
}
}
output_ptr = (int*)malloc(2 * sizeof(int));
streams =
clCreateBuffer(context, CL_MEM_READ_WRITE, 2 * sizeof(int), NULL, &err);
test_error( err, "clCreateBuffer failed.");
stream = clCreateBuffer(context, CL_MEM_READ_WRITE, 2 * sizeof(cl_int),
nullptr, &err);
test_error(err, "clCreateBuffer failed.");
std::string cl_std = "-cl-std=CL";
cl_std += (get_device_cl_version(device) == Version(3, 0)) ? "3.0" : "2.0";
err = create_single_kernel_helper_with_build_options(
context, &program[0], &kernel[0], 1, &enqueued_local_size_1d_code,
"test_enqueued_local_size_1d", cl_std.c_str());
test_error( err, "create_single_kernel_helper failed");
test_error(err, "create_single_kernel_helper failed");
err = create_single_kernel_helper_with_build_options(
context, &program[1], &kernel[1], 1, &enqueued_local_size_2d_code,
"test_enqueued_local_size_2d", cl_std.c_str());
test_error( err, "create_single_kernel_helper failed");
test_error(err, "create_single_kernel_helper failed");
err = clSetKernelArg(kernel[0], 0, sizeof streams, &streams);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[1], 0, sizeof streams, &streams);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[0], 0, sizeof stream, &stream);
test_error(err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[1], 0, sizeof stream, &stream);
test_error(err, "clSetKernelArgs failed.");
globalsize[0] = (size_t)num_elements;
globalsize[1] = (size_t)num_elements;
globalsize[0] = static_cast<size_t>(num_elements);
globalsize[1] = static_cast<size_t>(num_elements);
size_t max_wgs;
err = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(max_wgs), &max_wgs, NULL);
test_error( err, "clGetDeviceInfo failed.");
err = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE,
sizeof(max_wgs), &max_wgs, nullptr);
test_error(err, "clGetDeviceInfo failed.");
localsize[0] = MIN(16, max_wgs);
localsize[1] = MIN(11, max_wgs / localsize[0]);
localsize[0] = std::min<size_t>(16, max_wgs);
localsize[1] = std::min<size_t>(11, max_wgs / localsize[0]);
// If we need to use uniform workgroups because non-uniform workgroups are
// not supported, round up to the next global size that is divisible by the
// local size.
@ -141,35 +143,31 @@ test_enqueued_local_size(cl_device_id device, cl_context context, cl_command_que
}
}
err = clEnqueueNDRangeKernel(queue, kernel[1], 2, NULL, globalsize, localsize, 0, NULL, NULL);
test_error( err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueNDRangeKernel(queue, kernel[1], 2, nullptr, globalsize,
localsize, 0, nullptr, nullptr);
test_error(err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer(queue, streams, CL_TRUE, 0, 2*sizeof(int), output_ptr, 0, NULL, NULL);
test_error( err, "clEnqueueReadBuffer failed.");
err = clEnqueueReadBuffer(queue, stream, CL_BLOCKING, 0, 2 * sizeof(int),
output_ptr, 0, nullptr, nullptr);
test_error(err, "clEnqueueReadBuffer failed.");
err = verify_enqueued_local_size(output_ptr, localsize, 2);
globalsize[0] = (size_t)num_elements;
globalsize[0] = static_cast<size_t>(num_elements);
localsize[0] = 9;
if (use_uniform_work_groups && (globalsize[0] % localsize[0]))
{
globalsize[0] += (localsize[0] - (globalsize[0] % localsize[0]));
}
err = clEnqueueNDRangeKernel(queue, kernel[1], 1, NULL, globalsize, localsize, 0, NULL, NULL);
test_error( err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueNDRangeKernel(queue, kernel[1], 1, nullptr, globalsize,
localsize, 0, nullptr, nullptr);
test_error(err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer(queue, streams, CL_TRUE, 0, 2*sizeof(int), output_ptr, 0, NULL, NULL);
test_error( err, "clEnqueueReadBuffer failed.");
err = clEnqueueReadBuffer(queue, stream, CL_BLOCKING, 0, 2 * sizeof(int),
output_ptr, 0, nullptr, nullptr);
test_error(err, "clEnqueueReadBuffer failed.");
err = verify_enqueued_local_size(output_ptr, localsize, 1);
// cleanup
clReleaseMemObject(streams);
clReleaseKernel(kernel[0]);
clReleaseKernel(kernel[1]);
clReleaseProgram(program[0]);
clReleaseProgram(program[1]);
free(output_ptr);
return err;
}

View file

@ -61,7 +61,6 @@ test_float2int(cl_device_id device, cl_context context, cl_command_queue queue,
cl_int *output_ptr;
cl_program program;
cl_kernel kernel;
void *values[2];
size_t threads[1];
int err;
int i;
@ -103,8 +102,6 @@ test_float2int(cl_device_id device, cl_context context, cl_command_queue queue,
return -1;
}
values[0] = streams[0];
values[1] = streams[1];
err = clSetKernelArg(kernel, 0, sizeof streams[0], &streams[0]);
err = clSetKernelArg(kernel, 1, sizeof streams[1], &streams[1]);
if (err != CL_SUCCESS)

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -22,247 +22,175 @@
#include <sys/stat.h>
#include "harness/rounding_mode.h"
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
#include "procs.h"
static const char *fpadd_kernel_code =
"__kernel void test_fpadd(__global float *srcA, __global float *srcB, __global float *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] + srcB[tid];\n"
"}\n";
static const char *fpsub_kernel_code =
"__kernel void test_fpsub(__global float *srcA, __global float *srcB, __global float *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] - srcB[tid];\n"
"}\n";
static const char *fpmul_kernel_code =
"__kernel void test_fpmul(__global float *srcA, __global float *srcB, __global float *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] * srcB[tid];\n"
"}\n";
static const float MAX_ERR = 1e-5f;
static int
verify_fpadd(float *inptrA, float *inptrB, float *outptr, int n)
struct TestDef
{
float r;
int i;
const char op;
std::function<float(float, float)> ref;
};
for (i=0; i<n; i++)
static const char *fp_kernel_code = R"(
__kernel void test_fp(__global TYPE *srcA, __global TYPE *srcB, __global TYPE *dst)
{
int tid = get_global_id(0);
dst[tid] = srcA[tid] OP srcB[tid];
})";
static int verify_fp(std::vector<float> (&input)[2], std::vector<float> &output,
const TestDef &test)
{
auto &inA = input[0];
auto &inB = input[1];
for (int i = 0; i < output.size(); i++)
{
r = inptrA[i] + inptrB[i];
if (r != outptr[i])
float r = test.ref(inA[i], inB[i]);
if (r != output[i])
{
log_error("FP_ADD float test failed\n");
log_error("FP '%c' float test failed\n", test.op);
return -1;
}
}
log_info("FP_ADD float test passed\n");
log_info("FP '%c' float test passed\n", test.op);
return 0;
}
static int
verify_fpsub(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
void generate_random_inputs(std::vector<cl_float> (&input)[2])
{
RandomSeed seed(gRandomSeed);
auto random_generator = [&seed]() {
return get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31),
MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), seed);
};
for (auto &v : input)
{
r = inptrA[i] - inptrB[i];
if (r != outptr[i])
{
log_error("FP_SUB float test failed\n");
return -1;
}
std::generate(v.begin(), v.end(), random_generator);
}
log_info("FP_SUB float test passed\n");
return 0;
}
static int
verify_fpmul(float *inptrA, float *inptrB, float *outptr, int n)
template <size_t N>
int test_fpmath(cl_device_id device, cl_context context, cl_command_queue queue,
int num_elements, const std::string type_str,
const TestDef &test)
{
float r;
int i;
clMemWrapper streams[3];
clProgramWrapper program;
clKernelWrapper kernel;
for (i=0; i<n; i++)
{
r = inptrA[i] * inptrB[i];
if (r != outptr[i])
{
log_error("FP_MUL float test failed\n");
return -1;
}
}
int err;
log_info("FP_MUL float test passed\n");
return 0;
}
size_t length = sizeof(cl_float) * num_elements * N;
int
test_fpmath_float(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem streams[4];
cl_program program[3];
cl_kernel kernel[3];
float *input_ptr[3], *output_ptr, *p;
size_t threads[1];
int err, i;
MTdata d = init_genrand( gRandomSeed );
size_t length = sizeof(cl_float) * num_elements;
int isRTZ = 0;
RoundingMode oldMode = kDefaultRoundingMode;
// check for floating point capabilities
cl_device_fp_config single_config = 0;
err = clGetDeviceInfo( device, CL_DEVICE_SINGLE_FP_CONFIG, sizeof( single_config ), &single_config, NULL );
if (err) {
log_error("clGetDeviceInfo for CL_DEVICE_SINGLE_FP_CONFIG failed: %d", err);
return -1;
}
//If we only support rtz mode
if( CL_FP_ROUND_TO_ZERO == ( single_config & (CL_FP_ROUND_TO_ZERO|CL_FP_ROUND_TO_NEAREST) ) )
// If we only support rtz mode
if (CL_FP_ROUND_TO_ZERO == get_default_rounding_mode(device))
{
//Check to make sure we are an embedded device
char profile[32];
err = clGetDeviceInfo( device, CL_DEVICE_PROFILE, sizeof(profile), profile, NULL);
if( err )
{
log_error("clGetDeviceInfo for CL_DEVICE_PROFILE failed: %d", err);
return -1;
}
if( 0 != strcmp( profile, "EMBEDDED_PROFILE"))
{
log_error( "FAILURE: Device doesn't support CL_FP_ROUND_TO_NEAREST and isn't EMBEDDED_PROFILE\n" );
return -1;
}
isRTZ = 1;
oldMode = get_round();
}
input_ptr[0] = (cl_float*)malloc(length);
input_ptr[1] = (cl_float*)malloc(length);
input_ptr[2] = (cl_float*)malloc(length);
output_ptr = (cl_float*)malloc(length);
std::vector<cl_float> inputs[]{ std::vector<cl_float>(N * num_elements),
std::vector<cl_float>(N * num_elements) };
std::vector<cl_float> output = std::vector<cl_float>(N * num_elements);
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[3] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
generate_random_inputs(inputs);
p = input_ptr[0];
for (i=0; i<num_elements; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), d);
p = input_ptr[1];
for (i=0; i<num_elements; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), d);
p = input_ptr[2];
for (i=0; i<num_elements; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), d);
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, length, input_ptr[0], 0, NULL, NULL);
test_error( err, "clEnqueueWriteBuffer failed.");
err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0, length, input_ptr[1], 0, NULL, NULL);
test_error( err, "clEnqueueWriteBuffer failed.");
err = clEnqueueWriteBuffer(queue, streams[2], CL_TRUE, 0, length, input_ptr[2], 0, NULL, NULL);
test_error( err, "clEnqueueWriteBuffer failed.");
err = create_single_kernel_helper(context, &program[0], &kernel[0], 1, &fpadd_kernel_code, "test_fpadd");
test_error( err, "create_single_kernel_helper failed");
err = create_single_kernel_helper(context, &program[1], &kernel[1], 1, &fpsub_kernel_code, "test_fpsub");
test_error( err, "create_single_kernel_helper failed");
err = create_single_kernel_helper(context, &program[2], &kernel[2], 1, &fpmul_kernel_code, "test_fpmul");
test_error( err, "create_single_kernel_helper failed");
err = clSetKernelArg(kernel[0], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[0], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[0], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[1], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[1], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[1], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[2], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[2], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[2], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
threads[0] = (unsigned int)num_elements;
for (i=0; i<3; i++)
for (int i = 0; i < ARRAY_SIZE(streams); i++)
{
err = clEnqueueNDRangeKernel(queue, kernel[i], 1, NULL, threads, NULL, 0, NULL, NULL);
test_error( err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer(queue, streams[3], CL_TRUE, 0, length, output_ptr, 0, NULL, NULL);
test_error( err, "clEnqueueReadBuffer failed.");
if( isRTZ )
set_round( kRoundTowardZero, kfloat );
switch (i)
{
case 0:
err = verify_fpadd(input_ptr[0], input_ptr[1], output_ptr, num_elements);
break;
case 1:
err = verify_fpsub(input_ptr[0], input_ptr[1], output_ptr, num_elements);
break;
case 2:
err = verify_fpmul(input_ptr[0], input_ptr[1], output_ptr, num_elements);
break;
}
if( isRTZ )
set_round( oldMode, kfloat );
if (err)
break;
streams[i] =
clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error(err, "clCreateBuffer failed.");
}
for (int i = 0; i < ARRAY_SIZE(inputs); i++)
{
err = clEnqueueWriteBuffer(queue, streams[i], CL_TRUE, 0, length,
inputs[i].data(), 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed.");
}
// cleanup
clReleaseMemObject(streams[0]);
clReleaseMemObject(streams[1]);
clReleaseMemObject(streams[2]);
clReleaseMemObject(streams[3]);
for (i=0; i<3; i++)
std::string build_options = "-DTYPE=";
build_options.append(type_str).append(" -DOP=").append(1, test.op);
err = create_single_kernel_helper(context, &program, &kernel, 1,
&fp_kernel_code, "test_fp",
build_options.c_str());
test_error(err, "create_single_kernel_helper failed");
for (int i = 0; i < ARRAY_SIZE(streams); i++)
{
clReleaseKernel(kernel[i]);
clReleaseProgram(program[i]);
err = clSetKernelArg(kernel, i, sizeof(streams[i]), &streams[i]);
test_error(err, "clSetKernelArgs failed.");
}
free(input_ptr[0]);
free(input_ptr[1]);
free(input_ptr[2]);
free(output_ptr);
free_mtdata( d );
size_t threads[] = { static_cast<size_t>(num_elements) };
err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, threads, NULL, 0, NULL,
NULL);
test_error(err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer(queue, streams[2], CL_TRUE, 0, length,
output.data(), 0, NULL, NULL);
test_error(err, "clEnqueueReadBuffer failed.");
if (isRTZ) set_round(kRoundTowardZero, kfloat);
err = verify_fp(inputs, output, test);
if (isRTZ) set_round(oldMode, kfloat);
return err;
}
template <size_t N>
int test_fpmath_common(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements,
const std::string type_str)
{
TestDef tests[] = { { '+', std::plus<float>() },
{ '-', std::minus<float>() },
{ '*', std::multiplies<float>() } };
int err = TEST_PASS;
for (const auto &test : tests)
{
err |= test_fpmath<N>(device, context, queue, num_elements, type_str,
test);
}
return err;
}
int test_fpmath_float(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return test_fpmath_common<1>(device, context, queue, num_elements, "float");
}
int test_fpmath_float2(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return test_fpmath_common<2>(device, context, queue, num_elements,
"float2");
}
int test_fpmath_float4(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return test_fpmath_common<4>(device, context, queue, num_elements,
"float4");
}

View file

@ -1,266 +0,0 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "harness/rounding_mode.h"
#include "procs.h"
const char *fpadd2_kernel_code =
"__kernel void test_fpadd2(__global float2 *srcA, __global float2 *srcB, __global float2 *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] + srcB[tid];\n"
"}\n";
const char *fpsub2_kernel_code =
"__kernel void test_fpsub2(__global float2 *srcA, __global float2 *srcB, __global float2 *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] - srcB[tid];\n"
"}\n";
const char *fpmul2_kernel_code =
"__kernel void test_fpmul2(__global float2 *srcA, __global float2 *srcB, __global float2 *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] * srcB[tid];\n"
"}\n";
int
verify_fpadd2(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
{
r = inptrA[i] + inptrB[i];
if (r != outptr[i])
{
log_error("FP_ADD float2 test failed\n");
return -1;
}
}
log_info("FP_ADD float2 test passed\n");
return 0;
}
int
verify_fpsub2(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
{
r = inptrA[i] - inptrB[i];
if (r != outptr[i])
{
log_error("FP_SUB float2 test failed\n");
return -1;
}
}
log_info("FP_SUB float2 test passed\n");
return 0;
}
int
verify_fpmul2(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
{
r = inptrA[i] * inptrB[i];
if (r != outptr[i])
{
log_error("FP_MUL float2 test failed\n");
return -1;
}
}
log_info("FP_MUL float2 test passed\n");
return 0;
}
int
test_fpmath_float2(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem streams[4];
cl_program program[3];
cl_kernel kernel[3];
cl_float *input_ptr[3], *output_ptr, *p;
size_t threads[1];
int err, i;
MTdata d = init_genrand( gRandomSeed );
size_t length = sizeof(cl_float) * 2 * num_elements;
int isRTZ = 0;
RoundingMode oldMode = kDefaultRoundingMode;
// check for floating point capabilities
cl_device_fp_config single_config = 0;
err = clGetDeviceInfo( device, CL_DEVICE_SINGLE_FP_CONFIG, sizeof( single_config ), &single_config, NULL );
if (err) {
log_error("clGetDeviceInfo for CL_DEVICE_SINGLE_FP_CONFIG failed: %d", err);
return -1;
}
//If we only support rtz mode
if( CL_FP_ROUND_TO_ZERO == ( single_config & (CL_FP_ROUND_TO_ZERO|CL_FP_ROUND_TO_NEAREST) ) )
{
//Check to make sure we are an embedded device
char profile[32];
err = clGetDeviceInfo( device, CL_DEVICE_PROFILE, sizeof(profile), profile, NULL);
if( err )
{
log_error("clGetDeviceInfo for CL_DEVICE_PROFILE failed: %d", err);
return -1;
}
if( 0 != strcmp( profile, "EMBEDDED_PROFILE"))
{
log_error( "FAILURE: Device doesn't support CL_FP_ROUND_TO_NEAREST and isn't EMBEDDED_PROFILE\n" );
return -1;
}
isRTZ = 1;
oldMode = get_round();
}
input_ptr[0] = (cl_float*)malloc(length);
input_ptr[1] = (cl_float*)malloc(length);
input_ptr[2] = (cl_float*)malloc(length);
output_ptr = (cl_float*)malloc(length);
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[3] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
p = input_ptr[0];
for (i=0; i<num_elements*2; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), d);
p = input_ptr[1];
for (i=0; i<num_elements*2; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), d);
p = input_ptr[2];
for (i=0; i<num_elements*2; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), d);
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, length, input_ptr[0], 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0, length, input_ptr[1], 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueWriteBuffer(queue, streams[2], CL_TRUE, 0, length, input_ptr[2], 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = create_single_kernel_helper(context, &program[0], &kernel[0], 1, &fpadd2_kernel_code, "test_fpadd2");
test_error( err, "create_single_kernel_helper failed");
err = create_single_kernel_helper(context, &program[1], &kernel[1], 1, &fpsub2_kernel_code, "test_fpsub2");
test_error( err, "create_single_kernel_helper failed");
err = create_single_kernel_helper(context, &program[2], &kernel[2], 1, &fpmul2_kernel_code, "test_fpmul2");
test_error( err, "create_single_kernel_helper failed");
err = clSetKernelArg(kernel[0], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[0], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[0], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[1], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[1], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[1], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[2], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[2], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[2], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
free_mtdata(d);
d = NULL;
threads[0] = (unsigned int)num_elements;
for (i=0; i<3; i++)
{
err = clEnqueueNDRangeKernel(queue, kernel[i], 1, NULL, threads, NULL, 0, NULL, NULL);
test_error( err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer(queue, streams[3], CL_TRUE, 0, length, output_ptr, 0, NULL, NULL);
test_error( err, "clEnqueueReadBuffer failed.");
if( isRTZ )
set_round( kRoundTowardZero, kfloat );
switch (i)
{
case 0:
err = verify_fpadd2(input_ptr[0], input_ptr[1], output_ptr, num_elements*2);
break;
case 1:
err = verify_fpsub2(input_ptr[0], input_ptr[1], output_ptr, num_elements*2);
break;
case 2:
err = verify_fpmul2(input_ptr[0], input_ptr[1], output_ptr, num_elements*2);
break;
}
if( isRTZ )
set_round( oldMode, kfloat );
if (err)
break;
}
// cleanup
clReleaseMemObject(streams[0]);
clReleaseMemObject(streams[1]);
clReleaseMemObject(streams[2]);
clReleaseMemObject(streams[3]);
for (i=0; i<3; i++)
{
clReleaseKernel(kernel[i]);
clReleaseProgram(program[i]);
}
free(input_ptr[0]);
free(input_ptr[1]);
free(input_ptr[2]);
free(output_ptr);
return err;
}

View file

@ -1,267 +0,0 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "harness/compat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
#include "harness/rounding_mode.h"
const char *fpadd4_kernel_code =
"__kernel void test_fpadd4(__global float4 *srcA, __global float4 *srcB, __global float4 *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] + srcB[tid];\n"
"}\n";
const char *fpsub4_kernel_code =
"__kernel void test_fpsub4(__global float4 *srcA, __global float4 *srcB, __global float4 *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] - srcB[tid];\n"
"}\n";
const char *fpmul4_kernel_code =
"__kernel void test_fpmul4(__global float4 *srcA, __global float4 *srcB, __global float4 *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = srcA[tid] * srcB[tid];\n"
"}\n";
int
verify_fpadd4(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
{
r = inptrA[i] + inptrB[i];
if (r != outptr[i])
{
log_error("FP_ADD float4 test failed\n");
return -1;
}
}
log_info("FP_ADD float4 test passed\n");
return 0;
}
int
verify_fpsub4(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
{
r = inptrA[i] - inptrB[i];
if (r != outptr[i])
{
log_error("FP_SUB float4 test failed\n");
return -1;
}
}
log_info("FP_SUB float4 test passed\n");
return 0;
}
int
verify_fpmul4(float *inptrA, float *inptrB, float *outptr, int n)
{
float r;
int i;
for (i=0; i<n; i++)
{
r = inptrA[i] * inptrB[i];
if (r != outptr[i])
{
log_error("FP_MUL float4 test failed\n");
return -1;
}
}
log_info("FP_MUL float4 test passed\n");
return 0;
}
int
test_fpmath_float4(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem streams[4];
cl_program program[3];
cl_kernel kernel[3];
cl_float *input_ptr[3], *output_ptr, *p;
size_t threads[1];
int err, i;
MTdata d = init_genrand( gRandomSeed );
size_t length = sizeof(cl_float) * 4 * num_elements;
int isRTZ = 0;
RoundingMode oldMode = kDefaultRoundingMode;
// check for floating point capabilities
cl_device_fp_config single_config = 0;
err = clGetDeviceInfo( device, CL_DEVICE_SINGLE_FP_CONFIG, sizeof( single_config ), &single_config, NULL );
if (err) {
log_error("clGetDeviceInfo for CL_DEVICE_SINGLE_FP_CONFIG failed: %d", err);
return -1;
}
//If we only support rtz mode
if( CL_FP_ROUND_TO_ZERO == ( single_config & (CL_FP_ROUND_TO_ZERO|CL_FP_ROUND_TO_NEAREST) ) )
{
//Check to make sure we are an embedded device
char profile[32];
err = clGetDeviceInfo( device, CL_DEVICE_PROFILE, sizeof(profile), profile, NULL);
if( err )
{
log_error("clGetDeviceInfo for CL_DEVICE_PROFILE failed: %d", err);
return -1;
}
if( 0 != strcmp( profile, "EMBEDDED_PROFILE"))
{
log_error( "FAILURE: Device doesn't support CL_FP_ROUND_TO_NEAREST and isn't EMBEDDED_PROFILE\n" );
return -1;
}
isRTZ = 1;
oldMode = get_round();
}
input_ptr[0] = (cl_float*)malloc(length);
input_ptr[1] = (cl_float*)malloc(length);
input_ptr[2] = (cl_float*)malloc(length);
output_ptr = (cl_float*)malloc(length);
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[2] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
streams[3] = clCreateBuffer(context, CL_MEM_READ_WRITE, length, NULL, &err);
test_error( err, "clCreateBuffer failed.");
p = input_ptr[0];
for (i=0; i<num_elements*4; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), d);
p = input_ptr[1];
for (i=0; i<num_elements*4; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), d);
p = input_ptr[2];
for (i=0; i<num_elements*4; i++)
p[i] = get_random_float(-MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT(0x1.0p31f, 0x1, 31), d);
free_mtdata(d);
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, length, input_ptr[0], 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0, length, input_ptr[1], 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueWriteBuffer(queue, streams[2], CL_TRUE, 0, length, input_ptr[2], 0, NULL, NULL);
test_error(err, "clEnqueueWriteBuffer failed");
err = create_single_kernel_helper(context, &program[0], &kernel[0], 1, &fpadd4_kernel_code, "test_fpadd4");
test_error( err, "create_single_kernel_helper failed");
err = create_single_kernel_helper(context, &program[1], &kernel[1], 1, &fpsub4_kernel_code, "test_fpsub4");
test_error( err, "create_single_kernel_helper failed");
err = create_single_kernel_helper(context, &program[2], &kernel[2], 1, &fpmul4_kernel_code, "test_fpmul4");
test_error( err, "create_single_kernel_helper failed");
err = clSetKernelArg(kernel[0], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[0], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[0], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[1], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[1], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[1], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
err = clSetKernelArg(kernel[2], 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel[2], 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel[2], 2, sizeof streams[3], &streams[3]);
test_error( err, "clSetKernelArgs failed.");
threads[0] = (unsigned int)num_elements;
for (i=0; i<3; i++)
{
err = clEnqueueNDRangeKernel(queue, kernel[i], 1, NULL, threads, NULL, 0, NULL, NULL);
test_error( err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer(queue, streams[3], CL_TRUE, 0, length, output_ptr, 0, NULL, NULL);
test_error( err, "clEnqueueReadBuffer failed.");
if( isRTZ )
set_round( kRoundTowardZero, kfloat );
switch (i)
{
case 0:
err = verify_fpadd4(input_ptr[0], input_ptr[1], output_ptr, num_elements*4);
break;
case 1:
err = verify_fpsub4(input_ptr[0], input_ptr[1], output_ptr, num_elements*4);
break;
case 2:
err = verify_fpmul4(input_ptr[0], input_ptr[1], output_ptr, num_elements*4);
break;
}
if( isRTZ )
set_round( oldMode, kfloat );
if (err)
break;
}
// cleanup
clReleaseMemObject(streams[0]);
clReleaseMemObject(streams[1]);
clReleaseMemObject(streams[2]);
clReleaseMemObject(streams[3]);
for (i=0; i<3; i++)
{
clReleaseKernel(kernel[i]);
clReleaseProgram(program[i]);
}
free(input_ptr[0]);
free(input_ptr[1]);
free(input_ptr[2]);
free(output_ptr);
return err;
}

View file

@ -43,8 +43,6 @@ static const unsigned int out_vector_idx[] = { 0, 0, 1, 1, 3, 4};
// input type name is strcat(gentype, vector_size_names[i]);
// and output type name is
// strcat(gentype, vector_size_names[out_vector_idx[i]]);
static const int size_to_idx[] = {-1,0,1,2,3,-1,-1,-1,4,
-1,-1,-1,-1,-1,-1,-1,5};
static const char *vector_size_names[] = { "", "2", "3", "4", "8", "16"};
static const size_t kSizes[] = { 1, 1, 2, 2, 4, 4, 8, 8, 4, 8 };

View file

@ -32,8 +32,6 @@ const char *hostptr_kernel_code =
" dst[tid] = srcA[tid] + srcB[tid];\n"
"}\n";
static const float MAX_ERR = 1e-5f;
static int verify_hostptr(cl_float *inptrA, cl_float *inptrB, cl_float *outptr, int n)
{
cl_float r;

View file

@ -117,7 +117,8 @@ int validate_results( size_t width, size_t height, cl_image_format &format, char
}
default:
// Should never get here
break;
log_error("Unhandled channel data type\n");
return -1;
}
if( format.image_channel_order == CL_BGRA )

View file

@ -87,11 +87,11 @@ int test_imagearraycopy_single_format(cl_device_id device, cl_context context, c
char values[4096];
values[0] = 0;
if (failed) {
sprintf(values + strlen(values), "%d(0x%x) -> actual [", i, i);
sprintf(values + strlen(values), "%d(0x%x) -> expected [", i, i);
int j;
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", inchar[i+j]);
sprintf(values + strlen(values), "] != expected [");
sprintf(values + strlen(values), "] != actual [");
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", outchar[i+j]);
sprintf(values + strlen(values), "]");

View file

@ -84,11 +84,11 @@ int test_imagearraycopy3d_single_format(cl_device_id device, cl_context context,
char values[4096];
values[0] = 0;
if (failed) {
sprintf(values + strlen(values), "%d(0x%x) -> actual [", i, i);
sprintf(values + strlen(values), "%d(0x%x) -> expected [", i, i);
int j;
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", inchar[i+j]);
sprintf(values + strlen(values), "] != expected [");
sprintf(values + strlen(values), "] != actual [");
for (j=0; j<(int)elem_size; j++)
sprintf(values + strlen( values), "0x%02x ", outchar[i+j]);
sprintf(values + strlen(values), "]");

View file

@ -60,7 +60,6 @@ test_int2float(cl_device_id device, cl_context context, cl_command_queue queue,
cl_float *output_ptr;
cl_program program;
cl_kernel kernel;
void *values[2];
size_t threads[1];
int err;
int i;
@ -102,8 +101,6 @@ test_int2float(cl_device_id device, cl_context context, cl_command_queue queue,
return -1;
}
values[0] = streams[0];
values[1] = streams[1];
err = clSetKernelArg(kernel, 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel, 1, sizeof streams[1], &streams[1]);
if (err != CL_SUCCESS)

View file

@ -153,14 +153,14 @@ int test_mri_one(cl_device_id device, cl_context context, cl_command_queue queue
err = clSetKernelArg(kernel, 0, sizeof i, &i);
err |= clSetKernelArg(kernel, 1, sizeof err, &err);
err |= clSetKernelArg(kernel, 2, sizeof sampler, &sampler);
for (i=0; i<8; i++)
err |= clSetKernelArg(kernel, 3+i, sizeof streams[i], &streams[i]);
for (i = 0; i < 8; i++)
err |= clSetKernelArg(kernel, 3 + i, sizeof streams[i], &streams[i]);
if (err != CL_SUCCESS)
{
log_error("clSetKernelArgs failed\n");
return -1;
}
if (err != CL_SUCCESS)
{
log_error("clSetKernelArgs failed\n");
return -1;
}
threads[0] = (unsigned int)img_width;
threads[1] = (unsigned int)img_height;
@ -182,15 +182,13 @@ int test_mri_one(cl_device_id device, cl_context context, cl_command_queue queue
// cleanup
clReleaseSampler(sampler);
for (i=0; i<8; i++)
clReleaseMemObject(streams[i]);
for (i = 0; i < 8; i++) clReleaseMemObject(streams[i]);
clReleaseKernel(kernel);
clReleaseProgram(program);
for (i=0; i<7; i++)
free(input_ptr[i]);
free(output_ptr);
for (i = 0; i < 7; i++) free(input_ptr[i]);
free(output_ptr);
return err;
return err;
}

View file

@ -97,10 +97,10 @@ int test_kernel_preprocessor_macros(cl_device_id deviceID, cl_context context, c
char programSource[4096];
char curFileName[512];
char *programPtr = programSource;
int i = 0;
snprintf(curFileName, 512, "%s", __FILE__);
#ifdef _WIN32
// Replace "\" with "\\"
int i = 0;
while(curFileName[i] != '\0') {
if (curFileName[i] == '\\') {
int j = i + 1;

File diff suppressed because it is too large Load diff

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