Compare commits

...

399 commits

Author SHA1 Message Date
Ben Ashbaugh
11e39f533b
remove special-case range clamps for the fp16 divide test (#1902)
Some checks failed
Presubmit / Build ubuntu-22.04 gl (push) Failing after 10s
Presubmit / Build ubuntu-22.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-22.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
In the fp32 divide test, the range clamps are needed for the "fast
relaxed math" testing, but there is no "fast relaxed math" testing
for fp16.  This means that the range clamps are unnecessary and can
be removed.
2024-04-09 09:58:37 -07:00
Sreelakshmi Haridas Maruthur
4019a26a5b
conversions: Fix verification of half subnormal cases with FTZ (#1914) 2024-04-09 08:58:33 -07:00
Ben Ashbaugh
620c689919
update fp16 staging branch from main (#1903)
* allocations: Move results array from stack to heap (#1857)

* allocations: Fix stack overflow

* check format fixes

* Fix windows stack overflow. (#1839)

* thread_dimensions: Avoid combinations of very small LWS and very large GWS (#1856)

Modify the existing condition to include extremely small LWS like
1x1 on large GWS values

* c11_atomics: Reduce the loopcounter for sequential consistency tests (#1853)

Reduce the loop from 1000000 to 500000 since the former value
makes the test run too long and cause system issues on certain
platforms

* Limit individual allocation size using the global memory size (#1835)

Signed-off-by: Ahmed Hesham <ahmed.hesham@arm.com>

* geometrics: fix Wsign-compare warnings (#1855)

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

* integer_ops: fix -Wformat warnings (#1860)

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>

* Replace OBSOLETE_FORAMT with OBSOLETE_FORMAT (#1776)

* Replace OBSOLETE_FORAMT with OBSOLETE_FORMAT

In imageHelpers.cpp and few other places in image tests, OBSOLETE_FORMAT is misspelled as OBSOLETE_FORAMT.
Fix misspelling by replcaing it with OBSOLETE_FORMAT.

Fixes #1769

* Remove code guarded by OBSOLETE_FORMAT

Remove code guarded by OBSOLETE_FORMAT
as suggested by review comments

Fixes #1769

* Fix formating issues for OBSOLETE_FORMAT changes

Fix formatting issues observed in files while removing
code guarded by OBSOLETE_FORMAT

Fixes #1769

* Some more formatting fixes

Some more formatting fixes to get CI clean

Fixes #1769

* Final Formating fixes

Final formatting fixes for #1769

* Enhancement: Thread dimensions user parameters (#1384)

* Fix format in the test scope

* Add user params to limit testing

Add parameters to reduce amount of testing.
Helpful for debugging or for machines with lower performance.

* Restore default value

* Print info only if testing params bigger than 0.

* [NFC] conversions: reenable Wunused-but-set-variable (#1845)

Remove an assigned-to but unused variable.

Reenable the Wunused-but-set-variable warning for the conversions
suite, as it now compiles cleanly with this warning enabled.

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

* Fix bug of conversion from long to double (#1847)

* Fix bug of conversion from long to double

It the input is long type, it should be load as long type, not ulong.

* update long2float

* math_brute_force: fix exp/exp2 rlx ULP calculation (#1848)

Fix the ULP error calculation for the `exp` and `exp2` builtins in
relaxed math mode for the full profile.

Previously, the `ulps` value kept being added to while verifying the
result buffer in a loop.  `ulps` could even become a `NaN` when the
input argument being tested was a `NaN`.

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

* Enable LARGEADDRESSAWARE for 32 bit compilation (#1858)

* Enable LARGEADDRESSAWARE for 32 bit compilation

32-bit executables built with MSVC linker have only 2GB virtual memory
address space by default, which might not be sufficient for some tests.

Enable LARGEADDRESSAWARE linker flag for 32-bit targets to allow tests
to handle addresses larger than 2 gigabytes.

https://learn.microsoft.com/en-us/cpp/build/reference/largeaddressaware-handle-large-addresses?view=msvc-170

Signed-off-by: Guo, Yilong <yilong.guo@intel.com>

* Apply suggestion

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

---------

Signed-off-by: Guo, Yilong <yilong.guo@intel.com>
Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>

* fix return code when readwrite image is not supported (#1873)

This function (do_test) starts by testing write and read individually.
Both of them can have errors.

When readwrite image is not supported, the function returns
TEST_SKIPPED_ITSELF potentially masking errors leading to the test
returning EXIT_SUCCESS even with errors along the way.

* fix macos builds by avoiding double compilation of function_list.cpp for test_spir (#1866)

* modernize CMakeLists for test_spir

* add the operating system release to the sccache key

* include the math brute force function list vs. building it twice

* fix the license header on the spirv-new tests (#1865)

The source files for the spirv-new tests were using the older Khronos
license instead of the proper Apache license.  Fixed the license in
all source files.

* compiler: fix grammar in error message (#1877)

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

* Updated semaphore tests to use clSemaphoreReImportSyncFdKHR. (#1854)

* Updated semaphore tests to use clSemaphoreReImportSyncFdKHR.

Additionally updated common semaphore code to handle spec updates
that restrict simultaneous importing/exporting of handles.

* Fix build issues on CI

* gcc build issues

* Make clReImportSemaphoreSyncFdKHR a required API
call if cl_khr_external_semaphore_sync_fd is present.

* Implement signal and wait for all semaphore types.

* subgroups: fix for testing too large WG sizes (#1620)

It seemed to be a typo; the comment says that it
tries to fetch local size for a subgroup count with
above max WG size, but it just used the previous
subgroup count.

The test on purpose sets a SG count to be a larger
number than the max work-items in the work group.
Given the minimum SG size is 1 WI, it means that there
can be a maximum of maximum work-group size of SGs (of
1 WI of size). Thus, if we request a number of SGs that
exceeds the local size, the query should fail as expected.

* add SPIR-V version testing (#1861)

* basic SPIR-V 1.3 testing support

* updated script to compile for more SPIR-V versions

* switch to general SPIR-V versions test

* update copyright text and fix license

* improve output while test is running

* check for higher SPIR-V versions first

* fix formatting

* fix the reported platform information for math brute force (#1884)

When the math brute force test printed the platform version it always
printed information for the first platform in the system, which could
be different than the platform for the passed-in device.  Fixed by
querying the platform from the passed-in device instead.

* api tests fix: Use MTdataHolder in test_get_image_info (#1871)

* Minor fixes in mutable dispatch tests. (#1829)

* Minor fixes in mutable dispatch tests.

* Fix size of newWrapper in MutableDispatchSVMArguments.
* Fix errnoneus clCommandNDRangeKernelKHR call.

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

* * Set the row_pitch for imageInfo in MutableDispatchImage1DArguments
and MutableDispatchImage2DArguments. The row_pitch is
used by get_image_size() to calculate the size of
the host pointers by generate_random_image_data.

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

---------

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

* add test for cl_khr_spirv_linkonce_odr (#1226)

* initial version of the test with placeholders for linkonce_odr linkage

* add OpExtension SPV_KHR_linkonce_odr extension

* add check for extension

* switch to actual LinkOnceODR linkage

* fix formatting

* add a test case to ensure a function with linkonce_odr is exported

* add back the extension check

* fix formatting

* undo compiler optimization and actually add the call to function a

* [NFC] subgroups: remove unnecessary extern keywords (#1892)

In C and C++ all functions have external linkage by default.

Also remove the unused `gMTdata` and `test_pipe_functions`
declarations.

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

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

* Added cl_khr_fp16 extension support for test_decorate from spirv_new (#1770)

* Added cl_khr_fp16 extension support for test_decorate from spirv_new, work in progres

* Complemented test_decorate saturation test to support cl_khr_fp16 extension (issue #142)

* Fixed clang format

* scope of modifications:

-changed naming convention of saturation .spvasm files related to
test_decorate of spirv_new
-restored float to char/uchar saturation tests
-few minor corrections

* fix ranges for half testing

* fix formating

* one more formatting fix

* remove unused function

* use isnan instead of std::isnan

isnan is currently implemented as a macro, not as a function, so
we can't use std::isnan.

* fix Clang warning about inexact conversion

---------

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

* add support for custom devices (#1891)

enable the CTS to run on custom devices

---------

Signed-off-by: Ahmed Hesham <ahmed.hesham@arm.com>
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
Signed-off-by: Guo, Yilong <yilong.guo@intel.com>
Signed-off-by: John Kesapides <john.kesapides@arm.com>
Co-authored-by: Sreelakshmi Haridas Maruthur <sharidas@quicinc.com>
Co-authored-by: Haonan Yang <haonan.yang@intel.com>
Co-authored-by: Ahmed Hesham <117350656+ahesham-arm@users.noreply.github.com>
Co-authored-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
Co-authored-by: niranjanjoshi121 <43807392+niranjanjoshi121@users.noreply.github.com>
Co-authored-by: Grzegorz Wawiorko <grzegorz.wawiorko@intel.com>
Co-authored-by: Wenwan Xing <wenwan.xing@intel.com>
Co-authored-by: Yilong Guo <yilong.guo@intel.com>
Co-authored-by: Romaric Jodin <89833130+rjodinchr@users.noreply.github.com>
Co-authored-by: joshqti <127994991+joshqti@users.noreply.github.com>
Co-authored-by: Pekka Jääskeläinen <pekka.jaaskelainen@tuni.fi>
Co-authored-by: imilenkovic00 <155085410+imilenkovic00@users.noreply.github.com>
Co-authored-by: John Kesapides <46718829+JohnKesapidesARM@users.noreply.github.com>
Co-authored-by: Marcin Hajder <marcin.hajder@gmail.com>
Co-authored-by: Aharon Abramson <aharon.abramson@mobileye.com>
2024-03-02 16:48:45 -08:00
Harald van Dijk
d338b42e8f
Fix testing of half-precision fma. (#1882)
Half-precision functions are generally tested against the
single-precision reference. This causes double rounding: first to single
precision, then from there to half precision. For the most part, it is
good enough, but specifically in the case of fma, a correctly rounded
result is required and is not obtained, for instance for arguments
0x1.eacp+7, 0x1.3f4p+4, 0x1.c04p+14, which produce an exact result of
0x1.065fffp+15 which should be rounded to half-prefcision 0x1.064p+15,
but was previously first rounded to single-precision 0x1.066p+15, and
from there to half-precision 0x1.068p+15. Testing against reference_fmal
gives us sufficient precision that double rounding does not cause
issues.

The f_fma(..., FLUSHED) calls for FTZ testing cannot be updated the same
way but do not need to be: these calls all have at least one constant
operand of zero. If one operand is zero, double rounding cannot be an
issue.
2024-02-06 09:25:31 -08:00
Sreelakshmi Haridas Maruthur
79fc236e4a
bruteforce: Remove unnecessary half to float conversion (#1874) 2024-01-16 09:50:07 -08:00
Marcin Hajder
87dc09c66f
Fp16 math bruteforce staging (#1863)
* Enable fp16 in math bruteforce

* Added modernization of remaining half tests for consistency (issue #142, bruteforce)

* Added kernel types related corrections

* Added more fixes and general cleanup

* Corrected ULP values for half tests (issue #142, bruteforce)

* Corrected presubmit check for clang format

* Added support for ternary, unary_two_result and unary_two_result_i tests for cl_half (issue #142, bruteforce)

* Added missing condition due to vendor's review

* code format correction

* Added check for lack of support for denormals in binary_half scenario

* Corrected procedure to compute nextafter cl_half for flush-to-zero mode

* Added correction for external check of reference value for nextafter test

* Added correction due to code review request

* Changed quantity of tests performed for half in unary and macro_unary procedures from basic

* Added corrections related to code review:

-added binary_operator_half.cpp and binary_two_results_i_half.cpp
-address sanitizer errors fixed
-extending list of special half values
-removed unnecessary relaxed math references in half tests
-corrected conditions to verify ulp narrowing of computation results
-several refactoring and cosmetics corrections

* Print format correction due to failed CI check

* Corrected bug found in code review (fp16 bruteforce)

* Corrections related to code review (cl_khr_fp16 support according to #142)

-gHostFill missing support added
-special half values array extended
-cosmetics and unifying

* clang format applied

* consistency correction

* more consistency corrections for cl_fp16_khr supported tests

* Corrections related to code review (bureforce #142)

* Correction for i_unary_half test capacity

* Corrections related to capacity of cl_khr_fp16 tests in bruteforce (#142)

---------

Co-authored-by: Wawiorko, Grzegorz <grzegorz.wawiorko@intel.com>
2023-12-18 10:15:31 -08:00
Marcin Hajder
4216c5323d
Fp16 conversions staging (#1864)
* Added unification of existing conversions test as preparation for cl_khr_fp16 adaptation

* Unified initialization procedures for conversions test.

* Completed unification of data structures to handle cl_khr_fp16

* Added support for selective launch of the test

* Added half support for test_conversions, work in progres (issue #142, conversions)

* Added more work on halfs support for conversions test (issue #142, conversions)

* Added cosmetic corrections

* Added more cosmetic corrections before opening draft PR

* Added corrections related to pre-submit windows build

* Added more pre-build related corrections

* Added pre-submit ubuntu build related correction

* Added more pre-submit related corrections

* Divided structures into separate source files (issue #142, conversions)

* Added more corrections related to presubmit check

* Removed redeclarations due to presubmit check

* Added more corrections related to presubmit check arm build

* Added cosmetic correction

* Adapted modifications from related PR #1719 to avoid merging conflicts

* fixed clang format

* Added corrections related to code review (cl_khr_fp16 suuport according to issue #142)

* Corrections related to macos CI check fail

* fix for unclear clang format discrepancy

* More corrections related to code review (cl_khr_fp16 for conversions #142)

---------

Co-authored-by: Ewan Crawford <ewan@codeplay.com>
2023-12-18 10:14:33 -08:00
Kévin Petit
0fa6f236be
Increase the number of work items used by the allocations test (#1852)
Some checks failed
Presubmit / Build ubuntu-22.04 gl (push) Failing after 1s
Presubmit / Build ubuntu-22.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-22.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
* Increase the number of work items used by the allocations test

The test uses a fixed number of work items to process very large
buffers and images. As devices support more and more memory, this
leads to an ever-increasing amount of work done in each work item.
This results in some implementations and devices hitting timeout
issues.

Furthermore, a greater number of work items can provide performance
benefits on some devices.

Long term, this test should be redesigned to scale the number
of threads dynamically as a function of the max allocation size.

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

* formatting and add parentheses

---------

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2023-12-05 17:09:22 +00:00
joshqti
f5bd92b83e
Semaphore types bug fixes revised (#1822)
* Added support for SYNC_FD and other handle types

* Fix consistency test

Deleted test cases that are no longer testable
according to the spec.

* Fix multi-import tests

-Delete obsolete code relating to offsets
-Propagate dedicated memory change

* Fix error handling

Some subtests did not fail on incorrect result.
Changes to macros to fail, so this does not occur
again.

* Delete invalid test cases

Test cases are not related to this extension.

* External memory test

Add support for any handle type supported by
the platform.

Change-Id: I6765fde5e7929988f49bfbf2df2f41d5263b6abc

* Update multi-import tests to use new semaphore types

* Fix formatting

* Addressed review comments. Deleted VULKAN_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_NT_KMT as it appears to be redundant.
2023-11-29 16:02:59 +05:30
Kévin Petit
5815e2ce33
Reduce the Vulkan interop buffer kernel workgroup size to 128 (#1846)
Vulkan guarantees 128 is always supported.

Relates to #1828

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2023-11-23 19:06:50 +05:30
Ben Ashbaugh
eec46a087a
switch to the new memory and semaphore specific device handle lists (#1814)
* switch to the new memory and semaphore specific device handle lists

* remove support for older headers

* dummy commit
2023-11-14 11:28:09 -08:00
Ahmed Hesham
8b1a44f93f
Reduce the Vulkan interop buffer kernel workgroup size to 256 (#1828)
Using `local_size_x = 512` in the shader used in the Vulkan interop
tests fails on older hardware because this exceeds the maximum barrier
size limit.

Changed to 256, which is still a multiple of 32 and 64,
and is below the hardware limitations. The tests are not performance
tests anyways, so the performance penalty, if any, is acceptable.

Signed-off-by: Ahmed Hesham <ahmed.hesham@arm.com>
2023-11-15 00:03:46 +05:30
StrahinjaStamenkovic
482126d611
subgroup_functions_ext: fix missing flag initialization (#1826) 2023-11-14 09:10:57 -08:00
Sven van Haastregt
ea6e536ed3
c11_atomics: align signedness of host types (#1816)
Some `HOST_` types were declared with signedness different from the
`HOST_ATOMIC_` counterparts, leading to sign-compare warnings when
comparing between types.  Fix by aligning the signedness.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-11-14 09:09:45 -08:00
Sven van Haastregt
f08b3f6aee
profiling: fix -Wformat warnings (#1838)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-11-09 10:27:44 +00:00
Aharon Abramson
be626ca1fa
add MIPS architecture (#1837) 2023-11-07 09:36:45 -08:00
Sven van Haastregt
42434d04d0
c11_atomics: fix uninitialized member accesses (#1819)
Initialize the `_memoryOrder` and `_memoryScope` members to avoid
`CBasicTestMemOrderScope::MaxHostThreads()` accessing uninitialized
data.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-11-07 09:32:16 -08:00
John Kesapides
115e999a38
Image2d_from_buffer_positive comparison fix (#1569)
Only check against 2D image types as per the spec.
Move some device checks out of the loop.
Only perform the checks when element_size is a power of two.

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-11-07 09:31:18 -08:00
John Kesapides
7e4b59dfaa
Delete unused file test_float2int.cpp (#1831)
Remove left over file from (#1537)

https://github.com/KhronosGroup/OpenCL-CTS/pull/1537#issuecomment-1642088122

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-10-30 13:01:34 +00:00
Sreelakshmi Haridas Maruthur
40aaa2bcf2
conversions: Build fix for x86 toolchain (#1827) 2023-10-17 09:49:35 -07:00
Karol Herbst
c6dd6f2aa3
make atomic tests in prog var testing optional (#1799)
This is helpful for testing progvars on implementations not implementing
all the optional atomic features.
2023-10-17 09:40:44 -07:00
Marcin Hajder
72bb711646
Added cl_khr_fp16 extension support for test_explicit_s2v from basic (#1713)
* Added cl_khr_fp16 support for test_explicit_s2v from basic (issue #142, basic)

* Cosmetic corrections

* cosmetic fix

* Added correction to distinguish signed and unsigned char types for ARM architecture tests

* Added missing pieces of convertion procedure to support half

* Corrected condition to verify if additional pragma is necessary (issue #142, basic)

* Add NaN check for half to float conversion

* check-format fixes

* Add NaN check for all float types

Use std::isnan for float/double types.

Change-Id: I005bddccaa3f8490ac59b2aa431ed315733ad143

* Fix Ubuntu build error with isnan macro definition

Change-Id: I671ed826a9631fbbc66d0aa9b674ab00124c7967

* Check format fixes

* NAN define not needed anymore

---------

Co-authored-by: Vasu Penugonda <vpenugon@qti.qualcomm.com>
Co-authored-by: Sreelakshmi Haridas <sharidas@quicinc.com>
2023-10-17 09:38:36 -07:00
niranjanjoshi121
c73d6a341b
Add NULL CL_MEM_HOST_PTR check for clGetMemObjectInfo (#1801)
Some checks failed
Presubmit / Build ubuntu-22.04 gl (push) Failing after 2s
Presubmit / Build ubuntu-22.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-22.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
The spec requires implementations return NULL for CL_MEM_HOST_PTR
when the flags passed at memory object creation time do not contain
CL_MEM_USE_HOST_PTR

CTS was not checking this. Add the same check.

Fixes #1752
2023-10-10 09:25:10 -07:00
Michal Babej
af2710355d
add tests for clCommandSVMMemcpyKHR & clCommandSVMMemfillKHR (#1821)
* add tests for clCommandSVMMemcpyKHR & clCommandSVMMemfillKHR

* Fix typo SVMMemfill -> SVMMemFill

* fix clCommandSVMMemFillKHR calls to match extension

* add Khronos license + minor fixes

* review fixes
2023-10-10 09:22:50 -07:00
Nikhil Joshi
a7c33f8dc4
Add ffp-contract=off Compilation flag for CTS build (#1824)
* 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.

* Update extension list of test_compiler

Upate extension list of test_compiler
with missing external memory and semaphore
extensions

* Add ffp-contract=off Compilation flag for CTS build.

GCC defaults to using ffp-contract=fast even when fast math is disabled in the
case of GNU C
This creates precision issues when comparing the results with that of x86_64.
GNU options reference:
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#

This fix is to disable floating-point expression contractions with
flag ffp-contract=off for math_brute_force tests

Fixes #1794

* Make fp-contract flag arch-independent, but compiler dependent

Use existing CMake constructs to add fp-contract flag
so that it automatically checks for compiler support.
Also, make this change arch-independent.

Fixes #1794

* Fix typo in earlier commit

Fix typo in earlier commit

Fixes #1794

* Remove duplicate addition of ffp-contract flag

ffp-contract flag is currently added via two macros
Retain add_cxx_flag_if_supported macro and remove
set_gnulike_module_compile_flags.

Fixes #1794

* Fix typo in earlier commit

Add closing " that was unintentionally removed in previous commit.
2023-10-10 09:21:23 -07:00
Aharon Abramson
60fc7fc844
Update test_compile.cpp (#1812)
* Update test_compile.cpp

Prevent the error:
"variable 'temp' is uninitialized when used here"

Since one of the generated kernels starts with:

__kernel void sample_test(__global float *src, __global int *dst)
{
    float temp;
    int  tid = get_global_id(0);
    dst[tid] = dst[tid] + temp;

* Update test_compile.cpp

clang format

* Update test_compile.cpp

Change the "0.0" literal to "0.0f" for devices that don't support FP64.
2023-10-10 09:18:22 -07:00
Sven van Haastregt
e3c8de8eb6
math_brute_force: don't set/restore FTZ mode twice (#1808)
The suite's `main()` function already disables the FTZ mode prior to
invoking `runTestHarnessWithCheck` and restores the FP state
afterwards, so tests don't have to do so themselves.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-10-03 09:36:01 -07:00
niranjanjoshi121
1fe72877d7
Check that CL_DEVICE_COMPILER_AVAILABLE is CL_TRUE for FULL_PROFILE (#1804)
OpenCL FULL profile requires that online compiler be available.
OpenCL-CTS currently queries profile as well as online compiler
availability via device queries, but doesn't check for the consistency.

Check for consistency that if CL_DEVICE_PROFILE is "FULL_PROFILE"
(or technically is not "EMBEDDED_PROFILE") then CL_DEVICE_COMPILER_AVAILABLE
is CL_TRUE for that device.

Fixes #1763
2023-10-03 09:33:47 -07:00
John Kesapides
4984196bcb
Fix CopyImage verification for 1D/2D images (#1791)
The verification uses a common function with nested loops to verify
the result of the copy operation. The upper loop limits thirdDim and
SecondDim should be set according to the image type under test. Previously
for 1D/2D they were set from dstImageInfo->depth and dstImageInfo->height.
The issue is that the depth and height are set to 0 when unused. This
caused the verification loop to be skipped.

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-10-03 09:30:46 -07:00
niranjanjoshi121
7f0c0aee05
Replace cl_queue_properties_khr with cl_command_queue_properties (#1768)
test_conformance/api/test_queue_properties.cpp uses a cl_queue_properties_khr value
to query CL_DEVICE_QUEUE_PROPERTIES, however this should be a cl_command_queue_properties
typed variable.

Fixes issue #1640
2023-10-03 09:29:20 -07:00
Steven Winston
43d6886810
rewrite test_select to run in a few seconds. (#1665)
* rewrite test_select to run in a few seconds.

* removing the threading; reverting to the original method.

* Merge from Master, remove all suggested changes and start with a simple change report on each change's cost savings:
 BEFORE:
        real    47m8.497s
        user    48m8.860s
        sys     0m14.952s
AFTER:
        real    17m53.383s
        user    18m53.342s
        sys     0m13.297s

initSrcBuffer generates the same random noise every iteration through the loop.  There is no change to the arguments, and the host data itself doesn't need to get rewritten.  Profiling realizes a 2 times speed accel from simply relying upon the buffer to remain randomized at the next loop iteration.

* BEFORE:
        real    17m53.383s
        user    18m53.342s
        sys     0m13.297s
AFTER:
real    12m26.035s
user    13m15.505s
sys     0m15.414s

rearrange a few things in the loops to allow for vectorized / interleaved loop traversal.  NB: not all loops are vectorizable obviously; but this addresses the worst offenders.  Also note, to enable compiler to generate vectorized and interleaved loop traversal build with -o3.

* address the CI format requirements.

* address the CI format requirements.

* address the CI format requirements.
2023-10-03 09:26:48 -07:00
Sven van Haastregt
f39685030f
gl: fix sometimes-uninitialized warning (#1815)
Bail out when hitting the default case, so that we don't attempt to
access the uninitialized `error` variable.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-10-02 08:11:55 -07:00
Sven van Haastregt
b143a990d9
select: fix -Wformat warnings (#1817)
* Printing of a `size_t` requires the `%z` specifier.

 * Printing of `cl_long`/`cl_ulong` 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>
2023-09-22 07:10:44 -07:00
Sreelakshmi Haridas Maruthur
7759c2669a
basic: fix more unused-but-set variables (#1811)
Some checks failed
Presubmit / Build ubuntu-22.04 gl (push) Failing after 1s
Presubmit / Build ubuntu-22.04 aarch64 debug (push) Failing after 1s
Presubmit / Build ubuntu-22.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
2023-09-21 08:30:32 -07:00
Sven van Haastregt
aa953aaa51
[NFC] cmake: do not suppress -Wsign-compare globally (#1810)
Only disable `-Wsign-compare` for tests that do not compile cleanly
with this warning enabled.  Re-enable the warning for the other tests,
so that it can catch any new occurrences.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-09-20 15:48:25 +01:00
Sven van Haastregt
1c616238bc
test_common: Capitalize macro and clang-format (#1813)
The `CHECK_GL_ERROR` macro was lowercase before, which confused
clang-format and resulted in some odd indentations.  Capitalize the
macro and run clang-format to fix the indentation.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-09-20 10:19:13 +01:00
Sven van Haastregt
d20913b4e3
test_common: fix -Wformat warnings (#1771)
In preparation of re-enabling -Wformat globally, fix format string
warnings in test_common.

Printing a `size_t` requires the `%zu` specifier.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-09-19 12:26:48 +01:00
Sven van Haastregt
d7f24a7986
Fix more -Wsign-compare warnings (#1779)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-09-14 11:00:30 +01:00
Sven van Haastregt
39cca992b8
math_brute_force: remove gotos in macro_unary_float (#1725)
Simplify code by returning directly instead of using goto statements.

Although intended as an NFC commit, this changes the behaviour when
verification fails: the output buffer is no longer unmapped.  Although
not ideal, this aligns the behaviour of `macro_unary_float` to the
other math_brute_force tests.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-09-06 13:32:19 +01:00
Ahmed
d20de8ddea
Command buffer wait_for_sec_queue_event subtest, call clFinish in the correct order. (#1758)
* Fix for Command buffer wait_for_sec_queue_event subtest, call clFinish in the correct order.

queue has a command that depends on a command that resides in queue_sec, calling clFinish(queue) before clFinish(queue_sec) causes the test to hang as the queue_sec command never got a chance to finish.

* Update PR change as per the suggestion.
2023-09-05 09:09:04 -07:00
Sreelakshmi Haridas Maruthur
15b54aa0bd
External memory updates (#1676)
* Vulkan: Fix descriptor sets

Use descriptor set arrays when programming
arrays for compute shader.

Change-Id: Idabab775a256a223660eb7a850e26f290453659e

* Vulkan: Fix queue propertyies

Transfer bit for queue family is not required
to be reported by the implementation, it is
implicit for compute.

Change-Id: I7424b00e25e35145433dd74b0b4dfe7eeeaf98c8

* Vulkan: Allow implementation to choose dedicated memory

Dedicated vs non-dedicated memory must be queried by
the app.  Implementations are not required to support
exportable non-dedicated memory.

Change-Id: Idbc46ace1be20f61d1b58b34756f6d79a7745911

* Fix formatting

Auto-generated formatting fix

* Fix bug in dedicated memory.

* Add check for if OpenCL assumes linear tiling

Change-Id: Idd2e24d9d69e1fbc3ccb4a279067533104185332

* Changed macro name to reflect spec

CL_DEVICE_EXTERNAL_MEMORY_IMPORT_ASSUME_LINEAR_HANDLE_TYPES_KHR to
CL_DEVICE_EXTERNAL_MEMORY_IMPORT_ASSUME_LINEAR_IMAGES_HANDLE_TYPES_KHR

Also changed some functions to not use the KHR variants.

---------

Co-authored-by: Joshua Kelly <joshkell@qti.qualcomm.com>
2023-09-05 09:04:38 -07:00
Vishal Patil
c511ac62b0
fix memory leak from argList and from wrong ordering of free and return statement (#1792) 2023-08-29 09:19:45 -07:00
John Kesapides
8fd55dc889
Fix minimum image size for cl_ext_image_requirements_info (#1790)
Some new extension formats require the width to be a multiple
of 4 or 2 (see cl_ext_image_raw10_raw12).
Change has not functional impact as the affected image is only used
for generic queries.

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-08-29 09:18:11 -07:00
Ben Ashbaugh
bd548e63e6
fix a sporadic failure in the mutable_command_dimensions test (#1785) 2023-08-29 09:16:53 -07:00
Ewan Crawford
a3262eb4b6
[Command-buffer] Test finalizing empty command-buffer (#1782)
This patch adds two test cases related to command-buffer finalization:

1) That it is an error to finalize and already finalized command-buffer.
See https://github.com/KhronosGroup/OpenCL-Docs/pull/817

2) That it is not an error to create, finalize, and execute an empty
command-buffer. Closes issue #1781
2023-08-29 09:15:39 -07:00
Sven van Haastregt
c23631c690
subgroups: fix Wsign-compare warnings (#1778)
The subgroup and workgroup sizes reported by clGetKernelSubGroupInfo
and clGetKernelWorkGroupInfo are of type `size_t`.  Avoid changing the
values to an `int` type as they are propagated through the tests and
then compared against `size_t` again.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-08-29 09:14:23 -07:00
Sven van Haastregt
46fde8d051
atomics: fix memory leaks on error paths (#1732)
Before this change, `add_index_bin_test` would not release `cl_mem`
resources or `malloc`ed memory when encountering an error.  Fix by
using `clMemWrapper` and `std::unique_ptr` to automatically release
resources.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-08-29 09:13:03 -07:00
Kévin Petit
ddbb0de4b9
ci: use ubuntu-22.04 instead of 20.04 (#1795)
* ci: use ubuntu-22.04 instead of 20.04

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

* bump clang-format version

Oldest supported by 22.04

* update check-format script

---------

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
2023-08-22 18:13:22 +01:00
Kévin Petit
0702f2ecee
Make genrand_int32 thread safe (#1797)
The initialisation code is clearly meant to be run once but the volatile
flag did not guarantee that at all:

- Volatile does not mean atomic and loading the flag vs. other writes
  was not safe.
- Multiple threads could have loaded 0 and performed the initialisation
  resulting in write collisions.

Rely on std::call_once to provide the guarantee.

This issue was flagged by TSAN.

Signed-off-by: Kévin Petit <kpet@free.fr>
2023-08-19 11:15:17 +01:00
Ewan Crawford
df53e02a12
[command-buffer] Remove deleted enum (#1798)
The enum value `CL_COMMAND_BUFFER_STATE_INVALID_KHR` no longer exists:
* https://github.com/KhronosGroup/OpenCL-Headers/pull/235
* https://github.com/KhronosGroup/OpenCL-Docs/pull/885

Replace variable initialization using this enum with a value where
all the bits are set, requiring the runtime to write to it for the
test to pass.
2023-08-17 11:15:59 +01:00
Sven van Haastregt
ddf46ca9e8
math_brute_force: always initialize oldMode (#1796)
Avoid a maybe-uninitialized warning by ensuring that `oldMode` is
always initialized to 0.  There is no need to use `memset` for this,
as `FPU_mode_type` is either an `int` or an `int64_t`.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-08-07 13:51:29 +01:00
Sreelakshmi Haridas Maruthur
aa23f345c3
Add testing for sync_fd (#1747)
Modify the external semaphore extension test
to use SYNC_FD, if available on the device.

Deleted tests that are not compatible with blocking
semaphores.
2023-08-01 11:03:00 -07:00
Sven van Haastregt
e29d0fd3a1
conversions: fix memory leak from excess gMTdata initialization (#1787)
`gMTdata` was initialized twice, but freed only once.

Drop the first initialization with a local seed, and initialize with
`gRandomSeed` instead.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-08-01 09:49:43 +01:00
John Kesapides
a01349c44e
Use CTS type wrappers for test_basic test_loop (#1541)
* Use CTS type wrappers for test_basic test_loop
* Move variable declaration to first use in verify_loop

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-07-27 14:00:03 +01:00
Sven van Haastregt
0460756f6e
basic/int2fp: fix missing include (#1789)
With GCC 13 some headers are no longer included transitively through
C++ Standard Library headers.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-07-23 09:36:23 +01:00
John Kesapides
25ce398037
Use CTS type wrappers for test_constant. (#1543)
Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-07-20 16:13:42 +01:00
John Kesapides
339c932c57
Use the CTS typewrappers in image_r8 (#1539)
Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-07-19 14:18:49 +01:00
John Kesapides
cd5c165946
Deduplicate test_barrier (#1542)
Merge test_barrier and test_wg_barrier.

Reformat using clang-format kernel source code.

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-07-19 13:51:30 +01:00
Kévin Petit
3a1daafd5a
harness: add missing stdexcept header (#1783)
Required for std::runtime_error.

Signed-off-by: Kévin Petit <kpet@free.fr>
2023-07-19 13:47:18 +01:00
Sven van Haastregt
c3babfeebb
conversions: fix undefined behaviour from shift by 64 (#1788)
Avoid a shift by 64 on a `uint64_t`.  The value resulting from the
spurious shift was overwritten later, so just avoid the shift in that
case.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-07-19 09:48:59 +01:00
Nora
3c1f2814b8
add cl_khr_expect_assume to test_compiler_defines_for_extensions (#1735) 2023-07-18 16:07:17 -07:00
Sven van Haastregt
19bddc90e4 conversions: restore optimization workaround
The refactoring of the conversions test dropped the workaround added
by 59a12047a ("Fix for test_conversions failure with Clang build on
Linux #1057 (#1062)", 2021-05-11).

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-07-14 15:50:41 +01:00
Sven van Haastregt
b32d566bca conversions: fix undefined behaviour in DataInfoSpec
For conversion from integers to float, the DataInfoSpec constructor
tries to convert `CL_FLT_MAX` to an integer.  The float value cannot
be represented as an integer, which is undefined behaviour.

Fix by only doing this conversion when `InType` is a floating point
value.

While at it, use `static_cast` for the conversions.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-07-14 15:50:41 +01:00
Paweł Jastrzębski
6c841fbad8
Add image arguments tests for cl_khr_command_buffer_mutable_dispatch. (#1750)
* Add image arguments tests for cl_khr_command_buffer_mutable_dispatch.

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

* Add fixes for MutableDispatchImage1DArguments and MutableDispatchImage2DArguments.

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

* Fix constant magic number.

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

* Fix review comments.

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

* Fix condition for result check.

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

* Fix review comments.

Changes made:
- Fix kernel parameters
- Fix indentation
- Add skip condition for CL_DEVICE_IMAGE_SUPPORT

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

* Change array data type.

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

* Fix review comments.

Changes made:
- Fix skip conditions
- Fix kernel arguments update
- Change random generated values for dst_image

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

* Fix review comments.

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

* Remove unneeded headers.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-07-11 13:52:16 -07:00
Paweł Jastrzębski
c69bc00b56
Add arguments tests for cl_khr_command_buffer_mutable_dispatch. (#1749)
* Add arguments tests for cl_khr_command_buffer_mutable_dispatch.

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

* Add clFinish and clEnqueueCommandBufferKHR to mutable dispatch global arguments test.

Applied review comments for mutable dispatch global arguments test:
- clFinish to ensure command-buffer has finished executing for calling clUpdateMutableCommandsKHR
- Add second clEnqueueCommandBufferKHR for the command-buffer again before calling clEnqueueReadBuffer so that the kernel runs with the new argument

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

* Add clFinish and clEnqueueCommandBufferKHR to remaining mutable dispatch arguments test.

Applied review comments for remaining mutable dispatch arguments test:
- clFinish to ensure command-buffer has finished executing for calling clUpdateMutableCommandsKHR

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>

* Fix clang format.

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

* Recover proper MutableDispatchGlobalArguments test.

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

* Recover proper MutableDispatchNullArguments test.

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

* Fix constant magic number.

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

* Fix review changes.

Changes made:
- Remove unneeded headers
- Remove unneeded variable
- Remove unneeded skip condition
- Fix type int -> cl_int

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

* Fix tests definitions.

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

* Fix compilation error.

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>

* Fix clang format.

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

* Fix review comments.

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

* Fix review comments.

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>

* Fix review comments.

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

* Fix review comments.

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

* Fix review comments.

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>

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-07-11 13:04:30 -07:00
Paweł Jastrzębski
ae1a712e3e
Add out of order tests for cl_khr_command_buffer_mutable_dispatch. (#1746)
* Add out of order tests for cl_khr_command_buffer_mutable_dispatch.

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

* Replace CL_KERNEL_EXEC_INFO_SVM_PTRS with cl_mutable_dispatch_arg_khr command-buffer mutable buffer update.

CL_KERNEL_EXEC_INFO_SVM_PTRS limits the test to devices which support SVM.
Updating arg_list with a cl_mutable_dispatch_arg_khr struct is one of the
best supported, and also easiest to verify, configurations to change.

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

* Fix skip condition.

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

* Fix review changes.

Changes made:
- Fix skip condition
- Add event
- Add memory verification

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

* Fix review comments.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-07-11 10:43:29 -07:00
Paweł Jastrzębski
64130824a8
Add global size tests for cl_khr_command_buffer_mutable_dispatch. (#1744)
* Add global size tests for cl_khr_command_buffer_mutable_dispatch.

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

* Add kernel with observable output.

We should check that's some observable output from the kernel
as a result of the change to global work size, not just that
clGetMutableCommandInfoKHR has been updated. For example,
getting every work-item to call get_global_size() inside of
the kernel and writing it to a buffer, then reading the buffer
after the command-buffer enqueue has finished and check it
matches what we expect.

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

* Fix review comments.

Applied review comments for mutable dispatch global arguments test:
- clFinish to ensure command-buffer has finished executing for calling clUpdateMutableCommandsKHR
- Change variable and constant names for global size

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

* Fix review comments.

Changes made:
- Fix skip conditions
- Remove obsolete variable
- Replace a variable with a constant

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

* Fix review comments.

Changes made:
- Remove explicit base class call
- Fix condition check
- Fix constant magic number

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

* Fix constant magic number.

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

* Remove uneeded comments.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-07-11 09:41:43 -07:00
Paweł Jastrzębski
3b7fda2071
Add local size tests for cl_khr_command_buffer_mutable_dispatch. (#1745)
* Add local size tests for cl_khr_command_buffer_mutable_dispatch.

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

* Add kernel with observable output.

We should check that's some observable output from the kernel
as a result of the change to local work size, not just that
clGetMutableCommandInfoKHR has been updated. For example,
getting every work-item to call get_local_size() inside of
the kernel and writing it to a buffer, then reading the buffer
after the command-buffer enqueue has finished and check it
matches what we expect.

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

* Fix review comments.

    Applied review comments for mutable dispatch local size test:
    - clFinish to ensure command-buffer has finished executing for calling clUpdateMutableCommandsKHR
    - Change variable and constant names for local size

Applied review comments for mutable dispatch global arguments test:
- clFinish to ensure command-buffer has finished executing for calling clUpdateMutableCommandsKHR

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

* Fix review comments.

Changes made:
- Fix skip conditions
- Remove obsolete variable
- Replace a variable with a constant

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

* Remove explicit base class call.

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

* Fix constant magic number.

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

* Update global size and local size to meet the spec requirements.

Make sure work-groups number is not increased after update of command-buffer.

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

* Remove uneeded includes.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-07-11 08:56:49 -07:00
Paweł Jastrzębski
1ab4b26821
Add tests for external sharing not dependant on semaphores. (#1648)
* Add tests for external sharing not dependant on semaphores.

Additional external sharing tests that use fences instead of semaphores.

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>

* Apply changes for review.

Apply changes for review:
- Make VkFence + clFinish a synchronization option to existing tests
instead of creating a separate test that uses fence.

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

* Fix build break.

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

* Fix resource release conditions.

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

* Fix fence usage.

Fixed following fence issues:
- Add missing link to command buffer
- Add fence reset before wait

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

* Add Vulkan wrapper for fence.

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

* Rework fence reset.

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

* Change synchronisation mechanisms.

Changes made:
- wait for fence with clFinish
- queue submit with wait for fence

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

* Replace clFinish with vkWaitForFences.

Replaced clFinish with vkWaitForFences in Vulkan exectution context.

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

* Replace remaining clFinish with vkWaitForFences.

Replaced remaining clFinish with vkWaitForFences in Vulkan exectution context.

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

* Fix review comments for synchoronisation simplification.

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

* Fix review comments for synchoronisation simplification for remaining tests.

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

* Fix condition check.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-07-11 08:55:37 -07:00
Marcin Hajder
2686b9e2c1
Modernization of conversions test (#1719)
* Modernization of conversions test, preparation to handle cl_khr_fp16 extension

* Added missing virtual descructor

* Added corrections due to code review

* More separators removed

* Fixed clang format

* Added multiple corrections related to code review

* Corrected missing implicit test lost after modernization corrections

* Corrected single, selected test to limit number of unnecessary operations
2023-07-11 08:52:25 -07:00
Marcin Hajder
3a1388a2b4
Added cl_khr_fp16 extension support for test_vloadstore from basic (#1734)
* Added cl_khr_fp16 support for test_vloadstore from basic (issue #142, basic)

* Moved string helper procedures due to request from test_commonfns PR #1695

* restored original test sizes

* Corrected invalid initialization of reference buffer
2023-07-11 08:51:05 -07:00
Marcin Hajder
40b3eb3f7f
Added cl_khr_fp16 extension support for test_op_vector_extract from spirv_new (#1765)
* Added cl_khr_fp16 extension support for test_op_vector_extract from spirv_new (issue #142)

* Added missing condition to test available cl_khr_fp16 extension
2023-07-11 08:49:44 -07:00
Marcin Hajder
1e2d3522cf
Added cl_khr_fp16 extension support for test_op_vector_insert from spirv_new (#1766)
* Added cl_khr_fp16 extension support for test_op_vector_insert from spirv_new, work in progress.

* Added cl_khr_fp16 extension support for test_op_vector_insert from spirv_new (issue #142)
2023-07-11 08:48:41 -07:00
Sven van Haastregt
9e8430a6a6
[NFC] clang-format basic/test_enqueue_map.cpp (#1777)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-07-03 10:07:32 +01:00
Sven van Haastregt
9b0f78549a
workgroups: fix program/kernel object leak (#1775)
`create_single_kernel_helper` is called in a loop, overwriting the
objects contained in the wrapper classes.  The wrapper class is not
aware of this, as the overwriting happens through its `operator&`.

Move the wrapper objects into the loop, so that the contained objects
get released as soon as the program and kernel objects are no longer
needed.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-30 11:22:43 +01:00
Sven van Haastregt
845ec694bb
workgroups: fix -Wsign-compare warnings (#1774)
In preparation of re-enabling -Wsign-compare globally, fix some
instances of this warning.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-29 12:20:15 +01:00
Sven van Haastregt
729cd8b7a9
[NFC] device_execution: use raw string literals for block kernels (#1767)
Modernize by using raw string literals, which makes the kernel sources
easier to read/extract.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-28 09:34:07 +01:00
Ewan Crawford
75aca34e60
Test CL_COMMAND_BUFFER_CONTEXT_KHR (#1697)
Test coverage for spec PR https://github.com/KhronosGroup/OpenCL-Docs/pull/899
which introduces a new cl_khr_command_buffer query for the cl_context
2023-06-28 08:13:15 +01:00
Paweł Jastrzębski
56974a5858
Add global offset tests for cl_khr_command_buffer_mutable_dispatch. (#1743)
* Add global offset tests for cl_khr_command_buffer_mutable_dispatch.

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

* Add kernel with observable output.

We should check that there's some observable output from the kernel
as a result of the change to global work offset, not just that
clGetMutableCommandInfoKHR has been updated. E.g we could call
get_global_offset() inside of the kernel, write something to a
buffer based on that, and read the buffer after the command-buffer
enqueue has finished.

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

* Fix review comments.

Applied review comments for mutable dispatch global offset test:
- clFinish to ensure command-buffer has finished executing for calling clUpdateMutableCommandsKHR
- Change variable and constant names for global offset
- Remove redundant return CL_SUCCESS

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

* Fix review comments.

Changes made:
- Fix skip conditions
- Remove obsolete variable
- Replace a variable with a constant

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

* Fix review comments.

Changes made:
- Remove explicit base class call
- Fix constant magic number

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

* Fix constant magic number.

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>

* Fix condition for result check.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-06-27 08:54:14 -07:00
Paweł Jastrzębski
fee6d6bb66
Command buffer re-enqueue testing. (#1738)
* Command buffer re-enqueue testing.

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

* Remove reenqueue tests and add reenqueue to existing tests.

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

* Add re-enqueue for copy and barrier tests.

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

* Fix review comments.

Applied review comments for command buffer re-enqueue testing:
- Add second clEnqueueCommandBufferKHR for all tests
- Reinitialise memory before second enqueue of command buffers
- Add different patterns for second enqueue of command buffers

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

* Fix verification patterns for second enqueue tests.

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

* Reinitialise output memory for second command buffer re-enqueue.

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

* Fix cast for conversion from 'const cl_char' to 'const cl_uint.

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

* Fix compilation error for MSVC.

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

* Reinitialise in_mem and out_mem with zero.

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

* Fix cast for conversion from 'const cl_int' to 'const cl_uint'.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-06-27 08:47:24 -07:00
Marcin Hajder
73ead9da04
Added cl_khr_fp16 extension support for test_op_negate from spirv_new (#1762)
* Added cl_khr_fp16 extension support for test_op_negate from spirv_new (issue #142)

* Added clang format fix
2023-06-27 08:43:44 -07:00
Marcin Hajder
43c244f01d
Added cl_khr_fp16 extension support for test vector_times_scalar from spirv_new (#1757)
* Added cl_khr_fp16 support for vector_times_scalar from spirv_new (issue #142, spirv_new)

* Logging correction
2023-06-27 08:42:56 -07:00
Marcin Hajder
2495eca9fa
Added cl_khr_fp16 extension support for test_commonfns (#1695)
* Added cl_khr_fp16 extension support for commonfns test (issue #142, commonfns)

* Added missing header due to presubmit check

* Corrected radians/degrees ulp calculations + cosmetic fixes

* Corrected presubmit code format

* Corrections related to code review

* Moved string format helper to test_common in separate header

* Added clang format for last commit

* Corrections related to code review

* Modified mix verification procedure for half type to only report max error

* Removed redundant condition for logging mix verification

* Corrected generator limits for half tests
2023-06-27 08:42:02 -07:00
Marcin Hajder
60f025a7da
Added cl_half support for test_select (#1617)
* Added cl_half support for test_select (issue #142, select)

* Added corrections due to code review + performance optimization + replaced C object with wrappers

* minor fix

* Corrected use of user event

* Removed unnecessary user event
2023-06-27 08:40:35 -07:00
Sven van Haastregt
2e88013b34
compiler: fix memory leak from unnecessary strdup (#1761)
The result of the `strdup` was never freed.  The string duplication
isn't necessary, so remove it.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-21 22:08:21 -07:00
Sven van Haastregt
50f9f06323
test_common: fix -Wsign-compare warnings (#1759)
In preparation of re-enabling `-Wsign-compare` globally, avoid mixing
signed and unsigned integers in comparisons in test_common.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-21 15:19:21 +01:00
Marcin Hajder
df3ec8deec
Added cl_khr_fp16 extension support for test_int2fp from basic (#1742)
* Added cl_khr_fp16 and cl_khr_fp64 support for float2int and int2float tests from basic

* removed debug output

* Replaced procedure to generate random half values in specific range (issue #142, basic)

* Added cosmetic fixes due to code review comments

* Moved string helper procedures due to request for test_commonfns PR #1695
2023-06-20 08:44:45 -07:00
Marcin Hajder
0e229b8f01
Added cl_khr_fp16 extension support for test_fpmath from basic (#1718)
* Added half and double support for fpmath test from basic (issue #142, basic)

* Cosmetic corrections due to code review

* Removed unnecessary casting

* Added corrections due to code review

* Tuning range of input generation to avoid hitting infinity

* Moved string helpers procedures due to request from test_commonfns PR #1695
2023-06-20 08:42:57 -07:00
Sven van Haastregt
44b2578ac7
basic: fix unused-but-set variables (#1764)
Remove the unused `numItems` variable.

As this fixes all occurrences of this warning in test_basic, remove
the suppression flag.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-16 10:53:08 +01:00
Marcin Hajder
16a75dc0af
Added cl_khr_fp16 extension support for test_vector_creation from basic (#1728)
* Added cl_khr_fp16 extension support for vector_creation test from basic

* Added corrections related to vendor's review

* Added protection to avoid similar creation cases

* Added comment for recent correction

* cosmetics

* Corrected factor array to restore lost capacity of original test..

leaving only 16-sizes vector tests limited.
2023-06-13 08:41:39 -07:00
Marcin Hajder
095091bc57
Added cl_khr_fp16 extension support for test_vec_type_hint from basic (#1724)
* Added cl_khr_fp16 extension support for test_vec_type_hint from basic (issue #142, basic)

* Added correction to fix casting problem
2023-06-12 23:39:22 -07:00
Sven van Haastregt
475a37abbf
[NFC] Do not use reserved names for include guards (#1737)
Names that begin with an underscore followed by an uppercase letter
are reserved for the C++ implementation.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-09 11:25:20 +01:00
Sven van Haastregt
c8061ab21a
mem_host_flags: use size_t for element count (#1755)
More recent GCC versions (e.g. 12.2, 13.1) report that the argument to
`new[]` in the `Init` methods exceeds the maximum object size,
seemingly related to the negative range of the widened `int`.

Use an unsigned type to avoid the warning and propagate the signedness
change to other uses of the `num_elements` member.

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

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-08 13:27:20 +01:00
Romaric Jodin
1011f8ea81
fix async strided test outputing error during verify (#1754)
This bug was introduced by
https://github.com/KhronosGroup/OpenCL-CTS/pull/1711

Ref google/clspv#1127
2023-06-07 15:53:12 +01:00
Sven van Haastregt
658a8b62fb
[CI] Build Vulkan loader with USE_GAS=ON (#1756)
https://github.com/KhronosGroup/Vulkan-Loader/pull/1212 broke builds
that set `USE_GAS=OFF`.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-07 15:07:25 +01:00
Sven van Haastregt
b843b3bd8c
relationals: fix missing includes (#1753)
With GCC 13 some headers are no longer included transitively through
C++ Standard Library headers.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-07 10:51:38 +01:00
Marcin Hajder
c467391680
Added support for cl_khr_fp16 extension in test_async_copy from basic (issue #142, basic) (#1707) 2023-06-06 08:46:56 -07:00
Sven van Haastregt
63a8cb6b9d
non_uniform_work_group: fix unused-but-set variables (#1733)
Remove the unused `nonRemainderGlobalSize` array.  Inspect the result
of the `clGetDeviceInfo` call.

As this fixes all occurrences of this warning, remove the suppression
flag from this test.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-05 11:45:25 +01:00
Sven van Haastregt
ce17549812
cmake: do not suppress -Wsometimes-uninitialized globally (#1741)
Fix an instance of this warning in mem_host_flags.

Only disable `-Wsometimes-uninitialized` for the SVM test, which does
not compile cleanly with this warning enabled.  Re-enable the warning
for the other tests, so that it can catch any new occurrences.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-06-02 10:57:10 +01:00
Sven van Haastregt
abd556f7a2
relationals: add missing virtual destructor (#1739)
`RelationalsFPTest` contains a vector of `RelTestBase` pointers to
`RelTestParams` instances, so the base class destructor should be
virtual to avoid undefined behaviour.

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

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-31 10:02:54 +01:00
Chris Gearing
19f4fc3f3d
Make extended_async_copy tests type agnostic (#1619)
The latest version of the cl_khr_extended_async_copies extension uses
element size rather the element type as its base. The means it can be
called with arbitrary and in particular non power of 2 sizes, such as 3
or 13.

Update the test_async_copy2D and test_async_copy3D tests to make them
element size based rather than type based.

As well as this run all tests that can fit into the memory of the
target rather than presumed large elements cannot fit.

Make some addtional good practice changes in terms of const usage,
declaring variables where they are use, and usage of iterators.

The test coverage increases from 1224 cases to 1332 cases for the
test_async_copy2D and test_async_copy3D cases.

Ticket: #1579

Signed-off-by: Chris Gearing <chris.gearing@mobileye.com>
Co-authored-by: Chris Gearing <chris.gearing@mobileye.com>
2023-05-30 09:05:18 -07:00
Zhaoyu Zhang
38abfc7d24
select: using clEnqueueReadBuffer rather than clEnqueueMapBuffer (#1712)
* select: using clEnqueueReadBuffer rather than clEnqueueMapBuffer

* Update code to be compatible with clang-format

* update code again to be compatible with clang-format

* update code again to comply with clang-format

* updata code again to be compatible with clang-format

The clang-format tool is so weird, it's not even consistent between runs...
2023-05-30 08:54:32 -07:00
Marcin Hajder
b3c1401d48
Added cl_khr_fp16 extension support for test_async_strided_copy from basic (issue #142, basic) (#1711) 2023-05-30 08:52:27 -07:00
Marcin Hajder
c58ead9aea
Added cl_khr_fp16 extension support for test_astype from basic (#1706)
* Added support for cl_khr_fp16 extenstion in test_astype from basic (issue #142, basic)

* Added correction to iterate over vector of types

* Fixed case with both fp16 and fp64 supported

* Cosmetic corrections due to code review

* Cosmetic corrections due to code review
2023-05-30 08:52:06 -07:00
Sreelakshmi Haridas Maruthur
9692380505
Semaphore test: Use blocking semaphores (#1675)
Semaphore spec has been updated to reflect the fact that semaphores
will be in the appropriate - pending signal or pending wait - state
when returning from clEnqueueSignalSemaphore or
clEnqueueWaitSemaphore commands: KhronosGroup/OpenCL-Docs#882

Deleted the following tests to match the updated spec:

semaphores_order_1 - Test calls EnqueueWaitSemaphore before calling
EnqueueSignalSemaphore and expects this wait to succeed.
This behavior is not compatible with the recent
spec updates to semaphores.

semaphores_order_2 & semaphores_order_3 - Calling
clEnqueueSignalSemaphoresKHR with a dependency on a user event may
cause the implementation to block until the user event is complete.
This is unsafe usage of clEnqueueSignalSemaphoresKHR and may
lead to deadlock.

semaphores_invalid_command - This test checks for specific behavior
when waiting on a semaphore in an invalid state.
According to the spec, this is undefined behavior,
and therefore cannot be tested directly.

Co-authored-by: Joshua Kelly <joshkell@qti.qualcomm.com>
2023-05-30 08:49:31 -07:00
Marcin Hajder
4cb39b8c14
Added cl_khr_fp16 extension support for test_hiloeo from basic (#1721)
* Added cl_khr_fp16 support for hiloeo test from basic (issue #142, basic)

* Added correction due to compiler warrning

* Cosmetic correction
2023-05-30 08:48:09 -07:00
Paweł Jastrzębski
35b8db35c6
Add check for CL_COMMAND_BUFFER_STATE_EXECUTABLE_KHR after completion. (#1740)
* Add check for CL_COMMAND_BUFFER_STATE_EXECUTABLE_KHR after completion.

Added check for state CL_COMMAND_BUFFER_STATE_EXECUTABLE_KHR in state info tests.

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

* Add wait for event.

Wait for event to guarantee that a command-buffer has finished executing by this point.

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

* Add new event to wait for.

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

---------

Signed-off-by: Paweł Jastrzębski <p.k.jastrzebski@gmail.com>
2023-05-30 08:43:58 -07:00
Marcin Hajder
4dece20f7d
Added cl_khr_fp16 extension support for test_vector_swizzle from basic (#1729)
* Added cl_khr_fp16 extension support for vector_swizzle from basic (issue #142, basic)

* Added code review related fix
2023-05-29 14:04:04 +01:00
John Kesapides
3e8898ffeb
Deduplicate test_basic int2float/float2int (#1537)
Merge int2float,float2int.

Signed-off-by: John Kesapides <john.kesapides@arm.com>
2023-05-24 16:55:25 +01:00
Sven van Haastregt
957e3b3985
Convert some if-else chains to switch statements (#1730)
All of these if-else chains compare against enums, which is better
done using switch statements.  This helps avoid some
`-Wsometimes-uninitialized` warnings of variables that are assigned
inside the switch.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-24 11:11:23 +01:00
Sven van Haastregt
4f62adf1ca
computeinfo: fix use of uninitialized config_size_ret (#1727)
The variable `config_size_ret` is only assigned to inside the `if`.
If the condition is false, we would read uninitialized data.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-23 09:43:25 +01:00
Sven van Haastregt
8f3027387a
Fix some Wformat size_t warnings (#1726)
Printing a `size_t` requires the `%zu` specifier.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-18 09:29:27 +01:00
Tuomas Lauttia
85c95297ac
Removed hardcoded -cl-std=CL2.0 build option from progvar tests (#1710)
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
* Removed hardcoded -cl-std=CL2.0 build option from progvar tests

Fixes issue #1380
https://github.com/KhronosGroup/OpenCL-CTS/issues/1380

These changes will query the device for the latest supported CL C
version instead of using a hardcoded value. The create_single_kernel_helper
function queries for the latest CL C version internally, so calls to
create_single_kernel_helper_with_build_options were replaced with calls
to create_single_kernel_helper instead.

* Fixed formatting
2023-05-16 08:46:28 -07:00
Marcin Hajder
32688a47b3
Complementation and modernization of commonfns tests (#1694)
* Unified common functions tests due to preparation for adding cl_khr_fp16 support

* Renamed base structure, few cosmetic corrections

* Added corrections due to code review

* Removed comment separators

* Added review related corrections
2023-05-16 08:44:42 -07:00
Juan Manuel Martinez Caamaño
0447b7a2c8
Avoid integer overflows when computing abs_diff (#1689)
After compiling OpenCL CTS with -fsanitize=undefined I stumbled upon
some signed integer overflows.

test_absdiff.cpp:103:24: runtime error: signed integer overflow:
  419625160 - -1937831252 cannot be represented in type 'int'
test_absdiff.cpp:101:28: runtime error: signed integer overflow:
  1277901399 - -1294103363 cannot be represented in type 'int'
test_absdiff.cpp:140:24: runtime error: signed integer overflow:
  8945130301981949496 - -2872789959208163723 cannot be represented in type
  'long int'
test_absdiff.cpp:138:29: runtime error: signed integer overflow:
  5488544718097069860 - -5558131619970145206 cannot be represented in type
  'long int'

The result from these operations was used to compare against the kernel result.

This patch replaces the abs_diff manual computations by a function that handles
the signed integer overflow case.
2023-05-16 08:44:15 -07:00
Marcin Hajder
f31b2f029c
Added cl_half support for test_relationals (#1623)
* Added cl_khr_fp16 support for test_relationals (issue #142, relationals)

* Added cl_khr_fp16 support for any and bitselect test cases (issue #142, relationals)

* correction related to automated travis build for macOS (issue #142, relationals)

* more corrections related to automated travis build for macOS (issue #142, relationals)

* Added few cosmetic corrections (issue #142, test_relationals)

* Added missing clang format

* Added corrections related to order of initialization

* Added corrections due to code review (issue #142, relationals)

* Correction for prev commit

* Added subnormals related condition for test verification (issue #142, relationals)

* Added indexing correction due to code review

* Replaced hardcoded iteration limit (issue #142, relationals)
2023-05-16 08:43:47 -07:00
Sven van Haastregt
1884042f5d
[NFC] cmake: do not suppress -Wunused-but-set-variable globally (#1723)
Only disable `-Wunused-but-set-variable` for tests that do not compile
cleanly with this warning enabled.  This re-enables the warning for
most other tests, so that it can catch any new occurrences.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-16 09:58:04 +01:00
Kévin Petit
06c0c99c2e
Enable clCopyImage suite to run in parallel (#1717)
Signed-off-by: Kévin Petit <kpet@free.fr>
2023-05-13 10:21:34 +01:00
Sven van Haastregt
b23268acf5
math_brute_force: don't get build log after clCreateKernel (#1722)
The OpenCL specification states that the build log is only for
clBuildProgram, clCompileProgram or clLinkProgram.  Calling it after
clCreateKernel should not give any additional information, so this is
effectively dead code.  In case building failed, any logs would
already have been printed by create_single_kernel_helper.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-13 10:21:13 +01:00
Sven van Haastregt
d223e46f20
atomics: Remove unused variable in atomic_add_index_bin (#1709)
Remove a variable that was set when an OpenCL API call failed, but
never read again.  Instead, return immediately upon failure.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-11 14:12:09 +01:00
Sven van Haastregt
8272c83c6f
math_brute_force: consider all types for extension pragmas (#1705)
When generating the kernel code, consider the return type(s) and the
types of all parameters, instead of only the first parameter type.
This fixes a missing extension pragma for certain cases (such as
`nan`).

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-10 10:45:44 +01:00
Sven van Haastregt
20afedbd4a
[NFC] math_brute_force: remove unused MakeKernel function (#1714)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-05-04 16:18:35 +01:00
Banan-Askhar-Mobileye
caa656c268
fixing test events (#1678) 2023-05-03 09:16:21 +01:00
Kévin Petit
ff1369d94e
Add basic support to the harness for parallel test execution (#1687)
This change introduces a new command-line parameter to enable
parallel execution by a specified number of worker threads. When
parallel execution is requested, tests are distributed across
the worker threads. This behaviour is disabled by default.

This does not currently work for all suites as some of them are
using global variables to configure tests. For the suites that
do not use global state, this change reduced the execution time
by up to 5x on an 8-core machine.

Signed-off-by: Kévin Petit <kpet@free.fr>
2023-04-25 19:30:42 +01:00
paulfradgley
033aa195c5
Pass 'flag' variable through to clGetImageRequirementsInfoEXT (attempt 2) (#1700)
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-25 09:17:22 -07:00
Sven van Haastregt
aa34b4b8c3
[NFC] Remove unused depth_lod variables (#1696)
Remove the remaining unused variables in the test harness.

Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-04-25 09:16:10 -07:00
Sven van Haastregt
b57445e56a
[NFC] README.md: fix typos (#1704)
Signed-off-by: Sven van Haastregt <sven.vanhaastregt@arm.com>
2023-04-24 11:39:27 +01:00
Tuomas Lauttia
4f5af72088
Fixed use-after-free and class-memaccess errors when compiling with GCC 12.2.0 (#1702) 2023-04-21 10:09:55 +01:00
Ben Ashbaugh
5b87f53fe8
define CL_NO_EXTENSION_PROTOTYPES (#1325)
* define CL_NO_PROTOTYPES

When we switch to generated headers this will suppress declaration
of extension functions, so we can continue to declare function
pointers with the same name.

* switch to CL_NO_EXTENSION_PROTOTYPES

CL_NO_PROTOTYPES will omit declarations of core OpenCL APIs also.
2023-04-11 09:30:01 -07: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
762 changed files with 81007 additions and 85556 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-22.04, macos-latest, windows-latest]
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
mainmatrix: true
gl: 1
- os: ubuntu-20.04
extra: " gl"
- os: ubuntu-22.04
mainmatrix: false
name: Arm
arch: arm
- os: ubuntu-20.04
- os: ubuntu-22.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
runs-on: ubuntu-22.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-11
- 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)
@ -23,20 +17,13 @@ add_definitions(-DCL_USE_DEPRECATED_OPENCL_2_0_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_2_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_1_APIS=1)
add_definitions(-DCL_USE_DEPRECATED_OPENCL_1_0_APIS=1)
add_definitions(-DCL_NO_EXTENSION_PROTOTYPES)
option(USE_CL_EXPERIMENTAL "Use Experimental definitions" OFF)
if(USE_CL_EXPERIMENTAL)
add_definitions(-DCL_EXPERIMENTAL)
endif(USE_CL_EXPERIMENTAL)
# Support both VS2008 and VS2012.
set(BUILD_DIR "$ENV{ADRENO_DRIVER}/build")
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 +31,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 +50,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 +83,32 @@ 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)
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 +126,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" )
@ -182,6 +157,11 @@ if( WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qlong-double -Qpc80 /DWIN32 /D_WINDOWS /W3 /GR /EHsc -nologo -Od -D_CRT_NONSTDC_NO_WARNINGS -EHsc -Wall -Qdiag-disable:68,111,177,186,161,869,1028,2259,2553,181,239,265,1188 -fp:strict -fp:source")
endif()
# To handle addresses larger than 2 gigabytes for 32bit targets
if(WIN32 AND ${CLConform_TARGET_ARCH} STREQUAL "x86")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
endif()
list(APPEND CLConform_LIBRARIES ${OPENCL_LIBRARIES})
if(ANDROID)
list(APPEND CLConform_LIBRARIES m)
@ -197,10 +177,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 +190,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 is 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 submission.
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 question 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,8 +1,8 @@
#!/usr/bin/env bash
# Arg used to specify non-'origin/master' comparison branch
ORIGIN_BRANCH=${1:-"origin/master"}
CLANG_BINARY=${2:-"`which clang-format-9`"}
# Arg used to specify non-'origin/main' comparison branch
ORIGIN_BRANCH=${1:-"origin/main"}
CLANG_BINARY=${2:-"`which clang-format-11`"}
# Run git-clang-format to check for violations
CLANG_FORMAT_OUTPUT=$(git-clang-format --diff $ORIGIN_BRANCH --extensions c,cpp,h,hpp --binary $CLANG_BINARY)

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,67 @@ 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 \
-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

@ -966,12 +966,13 @@ void reorder_verification_buffer(GLenum glFormat, GLenum glType, char* buffer, s
#ifdef GL_VERSION_3_2
#define check_gl_error() \
{ \
GLenum errnom = GL_NO_ERROR;\
if ((errnom = glGetError()) != GL_NO_ERROR)\
log_error("GL Error: 0x%04X at %s:%d\n", errnom, __FILE__, __LINE__);\
}
#define CHECK_GL_ERROR() \
{ \
GLenum errnom = GL_NO_ERROR; \
if ((errnom = glGetError()) != GL_NO_ERROR) \
log_error("GL Error: 0x%04X at %s:%d\n", errnom, __FILE__, \
__LINE__); \
}
const char *get_gl_vector_type( GLenum internalformat )
{
@ -1045,10 +1046,12 @@ void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples
// Check if the renderer supports enough samples
GLint max_samples = get_gl_max_samples(target, internalFormat);
check_gl_error()
CHECK_GL_ERROR()
if (max_samples < (GLint)samples)
log_error("GL error: requested samples (%d) exceeds renderer max samples (%d)\n", samples, max_samples);
log_error("GL error: requested samples (%zu) exceeds renderer max "
"samples (%d)\n",
samples, max_samples);
// Setup the GLSL program
const GLchar *vertex_source =
@ -1075,36 +1078,36 @@ void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples
glShaderWrapper vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_source, NULL);
glCompileShader(vertex_shader);
check_gl_error()
CHECK_GL_ERROR()
glShaderWrapper fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_source, NULL);
glCompileShader(fragment_shader);
check_gl_error()
CHECK_GL_ERROR()
GLuint prog = glCreateProgram();
glAttachShader(prog, vertex_shader);
glAttachShader(prog, fragment_shader);
check_gl_error()
CHECK_GL_ERROR()
glBindAttribLocation(prog, 0, "att0");
glLinkProgram(prog);
check_gl_error()
CHECK_GL_ERROR()
// Setup the FBO and texture
glFramebufferWrapper fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
check_gl_error()
CHECK_GL_ERROR()
glViewport(0, 0, width, height);
check_gl_error()
CHECK_GL_ERROR()
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, fixedSampleLocations);
check_gl_error()
CHECK_GL_ERROR()
GLint attachment;
switch (internalFormat) {
@ -1122,7 +1125,7 @@ void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples
}
glFramebufferTexture(GL_FRAMEBUFFER, attachment, tex, 0);
check_gl_error()
CHECK_GL_ERROR()
GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
@ -1142,22 +1145,24 @@ void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples
// Check if the framebuffer supports enough samples
GLint fbo_samples = 0;
glGetIntegerv(GL_SAMPLES, &fbo_samples);
check_gl_error();
CHECK_GL_ERROR();
if (fbo_samples < (GLint)samples)
log_error("GL Error: requested samples (%d) exceeds FBO capability (%d)\n", samples, fbo_samples);
log_error(
"GL Error: requested samples (%zu) exceeds FBO capability (%d)\n",
samples, fbo_samples);
glUseProgram(prog);
check_gl_error()
CHECK_GL_ERROR()
if (attachment != GL_DEPTH_ATTACHMENT && attachment != GL_DEPTH_STENCIL_ATTACHMENT) {
glDisable(GL_DEPTH_TEST);
check_gl_error()
CHECK_GL_ERROR()
}
else {
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
check_gl_error()
CHECK_GL_ERROR()
}
// Setup the VBO for rendering a quad
@ -1172,14 +1177,14 @@ void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
check_gl_error()
CHECK_GL_ERROR()
glVertexArraysWrapper vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
check_gl_error()
CHECK_GL_ERROR()
//clearing color and depth buffer
glClearColor(0, 0, 0, 0);
@ -1223,13 +1228,13 @@ void * CreateGLTexture2DMultisample( size_t width, size_t height, size_t samples
color += color_delta;
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
check_gl_error();
CHECK_GL_ERROR();
glFlush();
}
glDisable(GL_SAMPLE_MASK);
check_gl_error();
CHECK_GL_ERROR();
*outTextureID = tex;
@ -1306,7 +1311,9 @@ void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
GLint max_samples = get_gl_max_samples(target, internalFormat);
if (max_samples < (GLint)samples)
log_error("GL error: requested samples (%d) exceeds renderer max samples (%d)\n", samples, max_samples);
log_error("GL error: requested samples (%zu) exceeds renderer max "
"samples (%d)\n",
samples, max_samples);
// Setup the GLSL program
const GLchar *vertex_source =
@ -1333,36 +1340,36 @@ void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
glShaderWrapper vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_source, NULL);
glCompileShader(vertex_shader);
check_gl_error()
CHECK_GL_ERROR()
glShaderWrapper fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_source, NULL);
glCompileShader(fragment_shader);
check_gl_error()
CHECK_GL_ERROR()
glProgramWrapper prog = glCreateProgram();
glAttachShader(prog, vertex_shader);
glAttachShader(prog, fragment_shader);
check_gl_error()
CHECK_GL_ERROR()
glBindAttribLocation(prog, 0, "att0");
glLinkProgram(prog);
check_gl_error()
CHECK_GL_ERROR()
// Setup the FBO and texture
glFramebufferWrapper fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
check_gl_error()
CHECK_GL_ERROR()
glViewport(0, 0, width, height);
check_gl_error()
CHECK_GL_ERROR()
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex);
glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, internalFormat, width, height, total_layers, fixedSampleLocations);
check_gl_error()
CHECK_GL_ERROR()
GLint attachment;
switch (internalFormat) {
@ -1381,16 +1388,15 @@ 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);
check_gl_error()
CHECK_GL_ERROR()
}
else {
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
check_gl_error()
CHECK_GL_ERROR()
}
// Setup the VBO for rendering a quad
@ -1405,18 +1411,18 @@ void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STREAM_DRAW);
check_gl_error()
CHECK_GL_ERROR()
glVertexArraysWrapper vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, 0);
check_gl_error()
CHECK_GL_ERROR()
for (size_t l=0; l!=total_layers; ++l) {
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment, tex, 0, l);
check_gl_error()
CHECK_GL_ERROR()
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_UNSUPPORTED) {
@ -1436,13 +1442,15 @@ void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
// Check if the framebuffer supports enough samples
GLint fbo_samples = 0;
glGetIntegerv(GL_SAMPLES, &fbo_samples);
check_gl_error();
CHECK_GL_ERROR();
if (fbo_samples < (GLint)samples)
log_error("GL Error: requested samples (%d) exceeds FBO capability (%d)\n", samples, fbo_samples);
log_error(
"GL Error: requested samples (%zu) exceeds FBO capability (%d)\n",
samples, fbo_samples);
glUseProgram(prog);
check_gl_error()
CHECK_GL_ERROR()
//clearing color and depth buffer
glClearColor(0, 0, 0, 0);
@ -1483,13 +1491,13 @@ void * CreateGLTexture2DArrayMultisample(size_t width, size_t height,
glUniform1f(glGetUniformLocation(prog, "depthVal"), val);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
check_gl_error();
CHECK_GL_ERROR();
glFlush();
}
glDisable(GL_SAMPLE_MASK);
check_gl_error();
CHECK_GL_ERROR();
}
*outTextureID = tex;
@ -1716,7 +1724,7 @@ void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
// Reverse and reorder to validate since in the
// kernel the read_imagef() call always returns RGBA
cl_uchar *p = (cl_uchar *)buffer;
for( size_t i = 0; i < (size_t)width * height; i++ )
for (GLsizei i = 0; i < width * height; i++)
{
cl_uchar uc0 = p[i * 4 + 0];
cl_uchar uc1 = p[i * 4 + 1];
@ -1734,7 +1742,7 @@ void * CreateGLRenderbuffer( GLsizei width, GLsizei height,
// Reverse and reorder to validate since in the
// kernel the read_imagef() call always returns RGBA
cl_uchar *p = (cl_uchar *)buffer;
for( size_t i = 0; i < width * height; i++ )
for (GLsizei i = 0; i < width * height; i++)
{
cl_uchar uc0 = p[i * 4 + 0];
cl_uchar uc1 = p[i * 4 + 1];

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

@ -13,18 +13,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _COMPAT_H_
#define _COMPAT_H_
#ifndef COMPAT_H_
#define COMPAT_H_
#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:
@ -405,4 +398,4 @@ EXTERN_C int __builtin_clz(unsigned int pattern);
#define sleep(sec) Sleep((sec)*1000)
#endif
#endif // _COMPAT_H_
#endif // COMPAT_H_

View file

@ -14,12 +14,15 @@
// limitations under the License.
//
#include "conversions.h"
#include <cinttypes>
#include <limits.h>
#include <time.h>
#include <assert.h>
#include "mt19937.h"
#include "compat.h"
#include <CL/cl_half.h>
#if defined(__SSE__) || defined(_MSC_VER)
#include <xmmintrin.h>
#endif
@ -50,10 +53,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 +184,8 @@ static ULong sUpperLimits[kNumExplicitTypes] = {
0xffffffffLL,
0xffffffffLL,
0x7fffffffffffffffLL,
0xffffffffffffffffLL,
0xffffffffffffffffLL,
0xffffffffffffffffULL,
0xffffffffffffffffULL,
0,
0
}; // Last two values aren't stored here
@ -260,6 +263,11 @@ static Long sLowerLimits[kNumExplicitTypes] = {
} \
break;
#define TO_HALF_CASE(inType) \
case kHalf: \
halfPtr = (cl_half *)outRaw; \
*halfPtr = cl_half_from_float((float)(*inType##Ptr), CL_HALF_RTE); \
break;
#define TO_FLOAT_CASE(inType) \
case kFloat: \
floatPtr = (float *)outRaw; \
@ -280,6 +288,59 @@ static Long sLowerLimits[kNumExplicitTypes] = {
*outType##Ptr = (outType)lrintf_clamped(*floatPtr); \
break;
#define HALF_ROUND_CASE(outEnum, outType, rounding, sat) \
case outEnum: { \
outType##Ptr = (outType *)outRaw; \
/* Get the tens digit */ \
float fltEq = (Long)cl_half_to_float(*halfPtr); \
Long wholeValue = (Long)fltEq; \
float largeRemainder = (fltEq - (float)wholeValue) * 10.f; \
/* What do we do based on that? */ \
if (rounding == kRoundToEven) \
{ \
if (wholeValue & 1LL) /*between 1 and 1.99 */ \
wholeValue += 1LL; /* round up to even */ \
} \
else if (rounding == kRoundToZero) \
{ \
/* Nothing to do, round-to-zero is what C casting does */ \
} \
else if (rounding == kRoundToPosInf) \
{ \
/* Only positive numbers are wrong */ \
if (largeRemainder != 0.f && wholeValue >= 0) wholeValue++; \
} \
else if (rounding == kRoundToNegInf) \
{ \
/* Only negative numbers are off */ \
if (largeRemainder != 0.f && wholeValue < 0) wholeValue--; \
} \
else \
{ /* Default is round-to-nearest */ \
wholeValue = (Long)lrintf_clamped(fltEq); \
} \
/* Now apply saturation rules */ \
if (sat) \
{ \
if ((sLowerLimits[outEnum] < 0 \
&& wholeValue > (Long)sUpperLimits[outEnum]) \
|| (sLowerLimits[outEnum] == 0 \
&& (ULong)wholeValue > sUpperLimits[outEnum])) \
*outType##Ptr = (outType)sUpperLimits[outEnum]; \
else if (wholeValue < sLowerLimits[outEnum]) \
*outType##Ptr = (outType)sLowerLimits[outEnum]; \
else \
*outType##Ptr = (outType)wholeValue; \
} \
else \
{ \
*outType##Ptr = (outType)( \
wholeValue \
& (0xffffffffffffffffLL >> (64 - (sizeof(outType) * 8)))); \
} \
} \
break;
#define FLOAT_ROUND_CASE(outEnum, outType, rounding, sat) \
case outEnum: { \
outType##Ptr = (outType *)outRaw; \
@ -385,6 +446,7 @@ static Long sLowerLimits[kNumExplicitTypes] = {
break;
typedef unsigned char uchar;
typedef signed char schar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
@ -394,7 +456,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
ExplicitType outType)
{
bool *boolPtr;
char *charPtr;
schar *scharPtr;
uchar *ucharPtr;
short *shortPtr;
ushort *ushortPtr;
@ -402,6 +464,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
uint *uintPtr;
Long *LongPtr;
ULong *ULongPtr;
cl_half *halfPtr;
float *floatPtr;
double *doublePtr;
@ -432,6 +495,11 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
get_explicit_type_size(outType));
break;
case kHalf:
halfPtr = (cl_half *)outRaw;
*halfPtr =
(*boolPtr) ? cl_half_from_float(-1.f, CL_HALF_RTE) : 0;
break;
case kFloat:
floatPtr = (float *)outRaw;
*floatPtr = (*boolPtr) ? -1.f : 0.f;
@ -448,29 +516,30 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
break;
case kChar:
charPtr = (char *)inRaw;
scharPtr = (schar *)inRaw;
switch (outType)
{
BOOL_CASE(char)
BOOL_CASE(schar)
case kChar:
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(char, kUChar, uchar, saturate)
SIMPLE_CAST_CASE(char, kUnsignedChar, uchar)
SIMPLE_CAST_CASE(char, kShort, short)
SIMPLE_CAST_CASE(char, kUShort, ushort)
SIMPLE_CAST_CASE(char, kUnsignedShort, ushort)
SIMPLE_CAST_CASE(char, kInt, int)
SIMPLE_CAST_CASE(char, kUInt, uint)
SIMPLE_CAST_CASE(char, kUnsignedInt, uint)
SIMPLE_CAST_CASE(char, kLong, Long)
SIMPLE_CAST_CASE(char, kULong, ULong)
SIMPLE_CAST_CASE(char, kUnsignedLong, ULong)
DOWN_CAST_CASE(schar, kUChar, uchar, saturate)
SIMPLE_CAST_CASE(schar, kUnsignedChar, uchar)
SIMPLE_CAST_CASE(schar, kShort, short)
SIMPLE_CAST_CASE(schar, kUShort, ushort)
SIMPLE_CAST_CASE(schar, kUnsignedShort, ushort)
SIMPLE_CAST_CASE(schar, kInt, int)
SIMPLE_CAST_CASE(schar, kUInt, uint)
SIMPLE_CAST_CASE(schar, kUnsignedInt, uint)
SIMPLE_CAST_CASE(schar, kLong, Long)
SIMPLE_CAST_CASE(schar, kULong, ULong)
SIMPLE_CAST_CASE(schar, kUnsignedLong, ULong)
TO_FLOAT_CASE(char)
TO_DOUBLE_CASE(char)
TO_HALF_CASE(schar)
TO_FLOAT_CASE(schar)
TO_DOUBLE_CASE(schar)
default:
log_error("ERROR: Invalid type given to "
@ -490,7 +559,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(uchar, kChar, char, saturate)
DOWN_CAST_CASE(uchar, kChar, schar, saturate)
SIMPLE_CAST_CASE(uchar, kShort, short)
SIMPLE_CAST_CASE(uchar, kUShort, ushort)
SIMPLE_CAST_CASE(uchar, kUnsignedShort, ushort)
@ -501,6 +570,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(uchar, kULong, ULong)
SIMPLE_CAST_CASE(uchar, kUnsignedLong, ULong)
TO_HALF_CASE(uchar)
TO_FLOAT_CASE(uchar)
TO_DOUBLE_CASE(uchar)
@ -522,7 +592,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(uchar, kChar, char, saturate)
DOWN_CAST_CASE(uchar, kChar, schar, saturate)
SIMPLE_CAST_CASE(uchar, kShort, short)
SIMPLE_CAST_CASE(uchar, kUShort, ushort)
SIMPLE_CAST_CASE(uchar, kUnsignedShort, ushort)
@ -533,6 +603,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(uchar, kULong, ULong)
SIMPLE_CAST_CASE(uchar, kUnsignedLong, ULong)
TO_HALF_CASE(uchar)
TO_FLOAT_CASE(uchar)
TO_DOUBLE_CASE(uchar)
@ -553,7 +624,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(short, kChar, char, saturate)
DOWN_CAST_CASE(short, kChar, schar, saturate)
DOWN_CAST_CASE(short, kUChar, uchar, saturate)
DOWN_CAST_CASE(short, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(short, kUShort, ushort, saturate)
@ -565,6 +636,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(short, kULong, ULong)
SIMPLE_CAST_CASE(short, kUnsignedLong, ULong)
TO_HALF_CASE(short)
TO_FLOAT_CASE(short)
TO_DOUBLE_CASE(short)
@ -586,7 +658,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(ushort, kChar, char, saturate)
DOWN_CAST_CASE(ushort, kChar, schar, saturate)
DOWN_CAST_CASE(ushort, kUChar, uchar, saturate)
DOWN_CAST_CASE(ushort, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(ushort, kShort, short, saturate)
@ -597,6 +669,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(ushort, kULong, ULong)
SIMPLE_CAST_CASE(ushort, kUnsignedLong, ULong)
TO_HALF_CASE(ushort)
TO_FLOAT_CASE(ushort)
TO_DOUBLE_CASE(ushort)
@ -618,7 +691,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(ushort, kChar, char, saturate)
DOWN_CAST_CASE(ushort, kChar, schar, saturate)
DOWN_CAST_CASE(ushort, kUChar, uchar, saturate)
DOWN_CAST_CASE(ushort, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(ushort, kShort, short, saturate)
@ -629,6 +702,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(ushort, kULong, ULong)
SIMPLE_CAST_CASE(ushort, kUnsignedLong, ULong)
TO_HALF_CASE(ushort)
TO_FLOAT_CASE(ushort)
TO_DOUBLE_CASE(ushort)
@ -649,7 +723,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(int, kChar, char, saturate)
DOWN_CAST_CASE(int, kChar, schar, saturate)
DOWN_CAST_CASE(int, kUChar, uchar, saturate)
DOWN_CAST_CASE(int, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(int, kShort, short, saturate)
@ -661,6 +735,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(int, kULong, ULong)
SIMPLE_CAST_CASE(int, kUnsignedLong, ULong)
TO_HALF_CASE(int)
TO_FLOAT_CASE(int)
TO_DOUBLE_CASE(int)
@ -682,7 +757,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(uint, kChar, char, saturate)
DOWN_CAST_CASE(uint, kChar, schar, saturate)
DOWN_CAST_CASE(uint, kUChar, uchar, saturate)
DOWN_CAST_CASE(uint, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(uint, kShort, short, saturate)
@ -693,6 +768,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(uint, kULong, ULong)
SIMPLE_CAST_CASE(uint, kUnsignedLong, ULong)
TO_HALF_CASE(uint)
TO_FLOAT_CASE(uint)
TO_DOUBLE_CASE(uint)
@ -714,7 +790,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(uint, kChar, char, saturate)
DOWN_CAST_CASE(uint, kChar, schar, saturate)
DOWN_CAST_CASE(uint, kUChar, uchar, saturate)
DOWN_CAST_CASE(uint, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(uint, kShort, short, saturate)
@ -725,6 +801,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
SIMPLE_CAST_CASE(uint, kULong, ULong)
SIMPLE_CAST_CASE(uint, kUnsignedLong, ULong)
TO_HALF_CASE(uint)
TO_FLOAT_CASE(uint)
TO_DOUBLE_CASE(uint)
@ -745,7 +822,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
DOWN_CAST_CASE(Long, kChar, char, saturate)
DOWN_CAST_CASE(Long, kChar, schar, saturate)
DOWN_CAST_CASE(Long, kUChar, uchar, saturate)
DOWN_CAST_CASE(Long, kUnsignedChar, uchar, saturate)
DOWN_CAST_CASE(Long, kShort, short, saturate)
@ -757,6 +834,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
DOWN_CAST_CASE(Long, kULong, ULong, saturate)
DOWN_CAST_CASE(Long, kUnsignedLong, ULong, saturate)
TO_HALF_CASE(Long)
TO_FLOAT_CASE(Long)
TO_DOUBLE_CASE(Long)
@ -778,7 +856,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
U_DOWN_CAST_CASE(ULong, kChar, char, saturate)
U_DOWN_CAST_CASE(ULong, kChar, schar, saturate)
U_DOWN_CAST_CASE(ULong, kUChar, uchar, saturate)
U_DOWN_CAST_CASE(ULong, kUnsignedChar, uchar, saturate)
U_DOWN_CAST_CASE(ULong, kShort, short, saturate)
@ -789,6 +867,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
U_DOWN_CAST_CASE(ULong, kUnsignedInt, uint, saturate)
U_DOWN_CAST_CASE(ULong, kLong, Long, saturate)
TO_HALF_CASE(ULong)
TO_FLOAT_CASE(ULong)
TO_DOUBLE_CASE(ULong)
@ -810,7 +889,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
U_DOWN_CAST_CASE(ULong, kChar, char, saturate)
U_DOWN_CAST_CASE(ULong, kChar, schar, saturate)
U_DOWN_CAST_CASE(ULong, kUChar, uchar, saturate)
U_DOWN_CAST_CASE(ULong, kUnsignedChar, uchar, saturate)
U_DOWN_CAST_CASE(ULong, kShort, short, saturate)
@ -821,6 +900,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
U_DOWN_CAST_CASE(ULong, kUnsignedInt, uint, saturate)
U_DOWN_CAST_CASE(ULong, kLong, Long, saturate)
TO_HALF_CASE(ULong)
TO_FLOAT_CASE(ULong)
TO_DOUBLE_CASE(ULong)
@ -831,13 +911,52 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
}
break;
case kHalf:
halfPtr = (cl_half *)inRaw;
switch (outType)
{
BOOL_CASE(half)
HALF_ROUND_CASE(kChar, schar, roundType, saturate)
HALF_ROUND_CASE(kUChar, uchar, roundType, saturate)
HALF_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
HALF_ROUND_CASE(kShort, short, roundType, saturate)
HALF_ROUND_CASE(kUShort, ushort, roundType, saturate)
HALF_ROUND_CASE(kUnsignedShort, ushort, roundType, saturate)
HALF_ROUND_CASE(kInt, int, roundType, saturate)
HALF_ROUND_CASE(kUInt, uint, roundType, saturate)
HALF_ROUND_CASE(kUnsignedInt, uint, roundType, saturate)
HALF_ROUND_CASE(kLong, Long, roundType, saturate)
HALF_ROUND_CASE(kULong, ULong, roundType, saturate)
HALF_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
case kHalf:
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
case kFloat:
floatPtr = (float *)outRaw;
*floatPtr = cl_half_to_float(*halfPtr);
break;
case kDouble:
doublePtr = (double *)outRaw;
*doublePtr = cl_half_to_float(*halfPtr);
break;
default:
log_error("ERROR: Invalid type given to "
"convert_explicit_value!!\n");
break;
}
break;
case kFloat:
floatPtr = (float *)inRaw;
switch (outType)
{
BOOL_CASE(float)
FLOAT_ROUND_CASE(kChar, char, roundType, saturate)
FLOAT_ROUND_CASE(kChar, schar, roundType, saturate)
FLOAT_ROUND_CASE(kUChar, uchar, roundType, saturate)
FLOAT_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
FLOAT_ROUND_CASE(kShort, short, roundType, saturate)
@ -850,6 +969,8 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
FLOAT_ROUND_CASE(kULong, ULong, roundType, saturate)
FLOAT_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
TO_HALF_CASE(float)
case kFloat:
memcpy(outRaw, inRaw, get_explicit_type_size(inType));
break;
@ -869,7 +990,7 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
{
BOOL_CASE(double)
DOUBLE_ROUND_CASE(kChar, char, roundType, saturate)
DOUBLE_ROUND_CASE(kChar, schar, roundType, saturate)
DOUBLE_ROUND_CASE(kUChar, uchar, roundType, saturate)
DOUBLE_ROUND_CASE(kUnsignedChar, uchar, roundType, saturate)
DOUBLE_ROUND_CASE(kShort, short, roundType, saturate)
@ -882,6 +1003,8 @@ void convert_explicit_value(void *inRaw, void *outRaw, ExplicitType inType,
DOUBLE_ROUND_CASE(kULong, ULong, roundType, saturate)
DOUBLE_ROUND_CASE(kUnsignedLong, ULong, roundType, saturate)
TO_HALF_CASE(double)
TO_FLOAT_CASE(double);
case kDouble:

View file

@ -1,22 +1,21 @@
/******************************************************************
Copyright (c) 2016 The Khronos Group Inc.
All Rights Reserved. This code is protected by copyright laws and
contains material proprietary to the Khronos Group, Inc.
This is UNPUBLISHED PROPRIETARY SOURCE CODE that may not be disclosed
in whole or in part to third parties, and may not be reproduced, republished,
distributed, transmitted, displayed, broadcast or otherwise exploited in any
manner without the express prior written permission of Khronos Group.
//
// Copyright (c) 2016-2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
The receipt or possession of this code does not convey any rights to
reproduce, disclose, or distribute its contents, or to
manufacture, use, or sell anything that it may describe, in whole
or in part other than under the terms of the Khronos Adopters
Agreement or Khronos Conformance Test Source License Agreement as
executed between Khronos and the recipient.
******************************************************************/
#ifndef _CRC32_H_
#define _CRC32_H_
#ifndef CRC32_H_
#define CRC32_H_
#include <stdint.h>
#include <stddef.h>

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,13 +363,13 @@ 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);
}
float Ulp_Error_Half(cl_half test, float reference)
float Ulp_Error_Half(cl_half test, double reference)
{
return Ulp_Error_Half_Float(cl_half_to_float(test), reference);
}
@ -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,28 @@ 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_fail_and_cleanup(errRet, cleanup, msg, ...) \
{ \
log_error(msg, ##__VA_ARGS__); \
errRet = TEST_FAIL; \
goto cleanup; \
}
#define test_error_and_cleanup(errCode, cleanup, msg, ...) \
{ \
auto errCodeResult = errCode; \
if (errCodeResult != CL_SUCCESS) \
{ \
print_error(errCodeResult, msg); \
goto cleanup; \
} \
}
#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 +108,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,9 +168,24 @@ 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);
extern float Ulp_Error_Half(cl_half test, double reference);
extern float Ulp_Error(float test, double reference);
extern float Ulp_Error_Double(double test, long double reference);
@ -186,8 +197,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,16 +32,22 @@
// 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>
#elif defined(__PPC__)
#include <fpu_control.h>
extern __thread fpu_control_t fpu_control;
#elif defined(__mips__)
#include "mips/m32c1.h"
#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,17 +63,19 @@ 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)));
#elif defined(__mips__)
fpa_bissr(FPA_CSR_FS);
#else
#error ForceFTZ needs an implentation
#endif
}
// 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,17 +91,19 @@ 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)));
#elif defined(__mips__)
fpa_bicsr(FPA_CSR_FS);
#else
#error DisableFTZ needs an implentation
#endif
}
// 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__)
@ -103,6 +115,8 @@ static inline void RestoreFPState(FPU_mode_type *mode)
// Add 64 bit support
#elif defined(__aarch64__)
__asm__ volatile("msr fpcr, %0" ::"r"(*mode));
#elif defined(__mips__)
// Mips runs by default with DAZ=1 FTZ=1
#else
#error RestoreFPState needs an implementation
#endif

View file

@ -23,6 +23,7 @@
#include <malloc.h>
#endif
#include <algorithm>
#include <cinttypes>
#include <iterator>
#if !defined(_WIN32)
#include <cmath>
@ -96,23 +97,9 @@ uint32_t get_channel_data_type_size(cl_channel_type channelType)
case CL_UNSIGNED_INT32: return sizeof(cl_int);
case CL_UNORM_SHORT_565:
case CL_UNORM_SHORT_555:
#ifdef OBSOLETE_FORAMT
case CL_UNORM_SHORT_565_REV:
case CL_UNORM_SHORT_555_REV:
#endif
return 2;
case CL_UNORM_SHORT_555: return 2;
#ifdef OBSOLETE_FORAMT
case CL_UNORM_INT_8888:
case CL_UNORM_INT_8888_REV: return 4;
#endif
case CL_UNORM_INT_101010:
#ifdef OBSOLETE_FORAMT
case CL_UNORM_INT_101010_REV:
#endif
return 4;
case CL_UNORM_INT_101010: return 4;
case CL_FLOAT: return sizeof(cl_float);
@ -293,23 +280,9 @@ uint32_t get_pixel_size(const cl_image_format *format)
return get_format_channel_count(format) * sizeof(cl_int);
case CL_UNORM_SHORT_565:
case CL_UNORM_SHORT_555:
#ifdef OBSOLETE_FORAMT
case CL_UNORM_SHORT_565_REV:
case CL_UNORM_SHORT_555_REV:
#endif
return 2;
case CL_UNORM_SHORT_555: return 2;
#ifdef OBSOLETE_FORAMT
case CL_UNORM_INT_8888:
case CL_UNORM_INT_8888_REV: return 4;
#endif
case CL_UNORM_INT_101010:
#ifdef OBSOLETE_FORAMT
case CL_UNORM_INT_101010_REV:
#endif
return 4;
case CL_UNORM_INT_101010: return 4;
case CL_FLOAT:
return get_format_channel_count(format) * sizeof(cl_float);
@ -421,7 +394,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 +427,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 +446,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 +568,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 +663,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 +730,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 +771,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 +788,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 +813,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 +832,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 +847,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 +860,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 +897,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 +1139,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 +1177,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 +1694,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 +1784,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 +1808,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 +1967,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 +1987,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 +2001,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 +2066,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 +2124,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 +2158,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 +2591,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 +2607,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 +2732,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 +2896,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 +3235,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;
}
@ -3502,7 +3509,6 @@ void copy_image_data(image_descriptor *srcImageInfo,
{
size_t src_width_lod = 1 /*srcImageInfo->width*/;
size_t src_height_lod = 1 /*srcImageInfo->height*/;
size_t src_depth_lod = 1 /*srcImageInfo->depth*/;
switch (srcImageInfo->type)
{
@ -3537,10 +3543,6 @@ void copy_image_data(image_descriptor *srcImageInfo,
src_height_lod = (srcImageInfo->height >> src_lod)
? (srcImageInfo->height >> src_lod)
: 1;
if (srcImageInfo->type == CL_MEM_OBJECT_IMAGE3D)
src_depth_lod = (srcImageInfo->depth >> src_lod)
? (srcImageInfo->depth >> src_lod)
: 1;
break;
}
src_mip_level_offset = compute_mip_level_offset(srcImageInfo, src_lod);
@ -3553,7 +3555,6 @@ void copy_image_data(image_descriptor *srcImageInfo,
{
size_t dst_width_lod = 1 /*dstImageInfo->width*/;
size_t dst_height_lod = 1 /*dstImageInfo->height*/;
size_t dst_depth_lod = 1 /*dstImageInfo->depth*/;
switch (dstImageInfo->type)
{
case CL_MEM_OBJECT_IMAGE1D:
@ -3587,10 +3588,6 @@ void copy_image_data(image_descriptor *srcImageInfo,
dst_height_lod = (dstImageInfo->height >> dst_lod)
? (dstImageInfo->height >> dst_lod)
: 1;
if (dstImageInfo->type == CL_MEM_OBJECT_IMAGE3D)
dst_depth_lod = (dstImageInfo->depth >> dst_lod)
? (dstImageInfo->depth >> dst_lod)
: 1;
break;
}
dst_mip_level_offset = compute_mip_level_offset(dstImageInfo, dst_lod);
@ -3988,7 +3985,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,
@ -344,48 +347,6 @@ void read_image_pixel(void *imageData, image_descriptor *imageInfo, int x,
break;
}
#ifdef OBSOLETE_FORMAT
case CL_UNORM_SHORT_565_REV: {
unsigned short *dPtr = (unsigned short *)ptr;
tempData[2] = (T)(dPtr[0] >> 11);
tempData[1] = (T)((dPtr[0] >> 5) & 63);
tempData[0] = (T)(dPtr[0] & 31);
break;
}
case CL_UNORM_SHORT_555_REV: {
unsigned short *dPtr = (unsigned short *)ptr;
tempData[2] = (T)((dPtr[0] >> 10) & 31);
tempData[1] = (T)((dPtr[0] >> 5) & 31);
tempData[0] = (T)(dPtr[0] & 31);
break;
}
case CL_UNORM_INT_8888: {
unsigned int *dPtr = (unsigned int *)ptr;
tempData[3] = (T)(dPtr[0] >> 24);
tempData[2] = (T)((dPtr[0] >> 16) & 0xff);
tempData[1] = (T)((dPtr[0] >> 8) & 0xff);
tempData[0] = (T)(dPtr[0] & 0xff);
break;
}
case CL_UNORM_INT_8888_REV: {
unsigned int *dPtr = (unsigned int *)ptr;
tempData[0] = (T)(dPtr[0] >> 24);
tempData[1] = (T)((dPtr[0] >> 16) & 0xff);
tempData[2] = (T)((dPtr[0] >> 8) & 0xff);
tempData[3] = (T)(dPtr[0] & 0xff);
break;
}
case CL_UNORM_INT_101010_REV: {
unsigned int *dPtr = (unsigned int *)ptr;
tempData[2] = (T)((dPtr[0] >> 20) & 0x3ff);
tempData[1] = (T)((dPtr[0] >> 10) & 0x3ff);
tempData[0] = (T)(dPtr[0] & 0x3ff);
break;
}
#endif
case CL_UNORM_SHORT_555: {
cl_ushort *dPtr = (cl_ushort *)ptr;
tempData[0] = (T)((dPtr[0] >> 10) & 31);
@ -479,6 +440,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 +457,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

@ -51,6 +51,7 @@
#include "harness/alloc.h"
#ifdef __SSE2__
#include <mutex>
#include <emmintrin.h>
#endif
@ -107,7 +108,7 @@ cl_uint genrand_int32(MTdata d)
/* mag01[x] = x * MATRIX_A for x=0,1 */
static const cl_uint mag01[2] = { 0x0UL, MATRIX_A };
#ifdef __SSE2__
static volatile int init = 0;
static std::once_flag init_flag;
static union {
__m128i v;
cl_uint s[4];
@ -123,8 +124,7 @@ cl_uint genrand_int32(MTdata d)
int kk;
#ifdef __SSE2__
if (0 == init)
{
auto init_fn = []() {
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] =
upper_mask.s[3] = UPPER_MASK;
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] =
@ -134,8 +134,8 @@ cl_uint genrand_int32(MTdata d)
MATRIX_A;
c0.s[0] = c0.s[1] = c0.s[2] = c0.s[3] = (cl_uint)0x9d2c5680UL;
c1.s[0] = c1.s[1] = c1.s[2] = c1.s[3] = (cl_uint)0xefc60000UL;
init = 1;
}
};
std::call_once(init_flag, init_fn);
#endif
kk = 0;
@ -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,15 @@
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;
unsigned gNumWorkerThreads;
void helpInfo()
{
@ -45,6 +49,8 @@ void helpInfo()
online Use online compilation (default)
binary Use binary offline compilation
spir-v Use SPIR-V offline compilation
--num-worker-threads <num>
Select parallel execution with the specified number of worker threads.
For offline compilation (binary and spir-v modes) only:
--compilation-cache-mode <cache-mode>
@ -62,7 +68,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)
@ -127,6 +140,23 @@ int parseCustomParam(int argc, const char *argv[], const char *ignore)
return -1;
}
}
else if (!strcmp(argv[i], "--num-worker-threads"))
{
delArg++;
if ((i + 1) < argc)
{
delArg++;
const char *numthstr = argv[i + 1];
gNumWorkerThreads = atoi(numthstr);
}
else
{
log_error(
"A parameter to --num-worker-threads must be provided!\n");
return -1;
}
}
else if (!strcmp(argv[i], "--compilation-cache-mode"))
{
delArg++;
@ -198,6 +228,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);
@ -197,19 +197,21 @@ RoundingMode get_round(void)
#include <xmmintrin.h>
#elif defined(__PPC__)
#include <fpu_control.h>
#elif defined(__mips__)
#include "mips/m32c1.h"
#endif
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;
@ -219,6 +221,9 @@ void *FlushToZero(void)
flags |= _FPU_MASK_NI;
_FPU_SETCW(flags);
return NULL;
#elif defined(__mips__)
fpa_bissr(FPA_CSR_FS);
return NULL;
#else
#error Unknown arch
#endif
@ -239,7 +244,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__)
@ -247,6 +252,8 @@ void UnFlushToZero(void *p)
_FPU_GETCW(flags);
flags &= ~_FPU_MASK_NI;
_FPU_SETCW(flags);
#elif defined(__mips__)
fpa_bicsr(FPA_CSR_FS);
#else
#error Unknown arch
#endif

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))
@ -44,10 +42,11 @@ typedef enum
kshort = 3,
kuint = 4,
kint = 5,
kfloat = 6,
kdouble = 7,
kulong = 8,
klong = 9,
khalf = 6,
kfloat = 7,
kdouble = 8,
kulong = 9,
klong = 10,
// This goes last
kTypeCount

View file

@ -0,0 +1,42 @@
//
// Copyright (c) 2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef STRING_HELPERS_H
#define STRING_HELPERS_H
#include <memory>
#include <stdexcept>
#include <string>
inline std::string concat_kernel(const char *sstr[], int num)
{
std::string res;
for (int i = 0; i < num; i++) res += std::string(sstr[i]);
return res;
}
template <typename... Args>
inline std::string str_sprintf(const std::string &str, Args... args)
{
int str_size = std::snprintf(nullptr, 0, str.c_str(), args...) + 1;
if (str_size <= 0) throw std::runtime_error("Formatting error.");
size_t s = static_cast<size_t>(str_size);
std::unique_ptr<char[]> buffer(new char[s]);
std::snprintf(buffer.get(), s, str.c_str(), args...);
return std::string(buffer.get(), buffer.get() + s - 1);
}
#endif // STRING_HELPERS_H

View file

@ -20,9 +20,11 @@
#include <stdlib.h>
#include <string.h>
#include <cassert>
#include <deque>
#include <mutex>
#include <stdexcept>
#include <thread>
#include <vector>
#include "threadTesting.h"
#include "errorHelpers.h"
#include "kernelHelpers.h"
#include "fpcontrol.h"
@ -60,6 +62,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 +118,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)
@ -126,6 +185,9 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
else if (strcmp(env_mode, "accelerator") == 0
|| strcmp(env_mode, "CL_DEVICE_TYPE_ACCELERATOR") == 0)
device_type = CL_DEVICE_TYPE_ACCELERATOR;
else if (strcmp(env_mode, "custom") == 0
|| strcmp(env_mode, "CL_DEVICE_TYPE_CUSTOM") == 0)
device_type = CL_DEVICE_TYPE_CUSTOM;
else if (strcmp(env_mode, "default") == 0
|| strcmp(env_mode, "CL_DEVICE_TYPE_DEFAULT") == 0)
device_type = CL_DEVICE_TYPE_DEFAULT;
@ -255,6 +317,12 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
device_type = CL_DEVICE_TYPE_ACCELERATOR;
argc--;
}
else if (strcmp(argv[argc - 1], "custom") == 0
|| strcmp(argv[argc - 1], "CL_DEVICE_TYPE_CUSTOM") == 0)
{
device_type = CL_DEVICE_TYPE_CUSTOM;
argc--;
}
else if (strcmp(argv[argc - 1], "CL_DEVICE_TYPE_DEFAULT") == 0)
{
device_type = CL_DEVICE_TYPE_DEFAULT;
@ -292,6 +360,9 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
case CL_DEVICE_TYPE_ACCELERATOR:
log_info("Requesting Accelerator device ");
break;
case CL_DEVICE_TYPE_CUSTOM:
log_info("Requesting Custom device ");
break;
case CL_DEVICE_TYPE_DEFAULT:
log_info("Requesting Default device ");
break;
@ -470,6 +541,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 +550,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 +570,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);
}
}
@ -514,10 +598,12 @@ int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
FPU_mode_type oldMode;
DisableFTZ(&oldMode);
#endif
extern unsigned gNumWorkerThreads;
test_harness_config config = { forceNoContextCreation, num_elements,
queueProps, gNumWorkerThreads };
int error = parseAndCallCommandLineTests(argc, argv, device, testNum,
testList, forceNoContextCreation,
queueProps, num_elements);
testList, config);
#if defined(__APPLE__) && defined(__arm__)
// Restore the old FP mode before leaving.
@ -574,49 +660,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)
@ -651,14 +694,11 @@ static void print_results(int failed, int count, const char *name)
int parseAndCallCommandLineTests(int argc, const char *argv[],
cl_device_id device, int testNum,
test_definition testList[],
int forceNoContextCreation,
cl_command_queue_properties queueProps,
int num_elements)
const test_harness_config &config)
{
int ret = EXIT_SUCCESS;
unsigned char *selectedTestList = (unsigned char *)calloc(testNum, 1);
test_status *resultTestList = NULL;
if (argc == 1)
{
@ -697,24 +737,18 @@ 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,
queueProps);
callTestFunctions(testList, selectedTestList, resultTestList.data(),
testNum, device, config);
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,26 +764,101 @@ int parseAndCallCommandLineTests(int argc, const char *argv[],
}
free(selectedTestList);
free(resultTestList);
return ret;
}
struct test_harness_state
{
test_definition *tests;
test_status *results;
cl_device_id device;
test_harness_config config;
};
static std::deque<int> gTestQueue;
static std::mutex gTestStateMutex;
void test_function_runner(test_harness_state *state)
{
int testID;
test_definition test;
while (true)
{
// Attempt to get a test
{
std::lock_guard<std::mutex> lock(gTestStateMutex);
// The queue is empty, we're done
if (gTestQueue.size() == 0)
{
return;
}
// Get the test at the front of the queue
testID = gTestQueue.front();
gTestQueue.pop_front();
test = state->tests[testID];
}
// Execute test
auto status =
callSingleTestFunction(test, state->device, state->config);
// Store result
{
std::lock_guard<std::mutex> lock(gTestStateMutex);
state->results[testID] = status;
}
}
}
void callTestFunctions(test_definition testList[],
unsigned char selectedTestList[],
test_status resultTestList[], int testNum,
cl_device_id deviceToUse, int forceNoContextCreation,
int numElementsToUse,
cl_command_queue_properties queueProps)
cl_device_id deviceToUse,
const test_harness_config &config)
{
for (int i = 0; i < testNum; ++i)
// Execute tests serially
if (config.numWorkerThreads == 0)
{
if (selectedTestList[i])
for (int i = 0; i < testNum; ++i)
{
resultTestList[i] = callSingleTestFunction(
testList[i], deviceToUse, forceNoContextCreation,
numElementsToUse, queueProps);
if (selectedTestList[i])
{
resultTestList[i] =
callSingleTestFunction(testList[i], deviceToUse, config);
}
}
// Execute tests in parallel with the specified number of worker threads
}
else
{
// Queue all tests that need to run
for (int i = 0; i < testNum; ++i)
{
if (selectedTestList[i])
{
gTestQueue.push_back(i);
}
}
// Spawn thread pool
std::vector<std::thread *> threads;
test_harness_state state = { testList, resultTestList, deviceToUse,
config };
for (unsigned i = 0; i < config.numWorkerThreads; i++)
{
log_info("Spawning worker thread %u\n", i);
threads.push_back(new std::thread(test_function_runner, &state));
}
// Wait for all threads to complete
for (auto th : threads)
{
th->join();
}
assert(gTestQueue.size() == 0);
}
}
@ -762,9 +871,7 @@ void CL_CALLBACK notify_callback(const char *errinfo, const void *private_info,
// Actual function execution
test_status callSingleTestFunction(test_definition test,
cl_device_id deviceToUse,
int forceNoContextCreation,
int numElementsToUse,
const cl_queue_properties queueProps)
const test_harness_config &config)
{
test_status status;
cl_int error;
@ -783,28 +890,39 @@ 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)
if (!config.forceNoContextCreation)
{
context = clCreateContext(NULL, 1, &deviceToUse, notify_callback, NULL,
&error);
if (!context)
{
print_error(error, "Unable to create testing context");
gFailCount++;
gTestsFailed++;
return TEST_FAIL;
}
if (device_version < Version(2, 0))
{
queue =
clCreateCommandQueue(context, deviceToUse, queueProps, &error);
queue = clCreateCommandQueue(context, deviceToUse,
config.queueProps, &error);
}
else
{
const cl_command_queue_properties cmd_queueProps =
(queueProps) ? CL_QUEUE_PROPERTIES : 0;
cl_command_queue_properties queueCreateProps[] = { cmd_queueProps,
queueProps, 0 };
(config.queueProps) ? CL_QUEUE_PROPERTIES : 0;
cl_command_queue_properties queueCreateProps[] = {
cmd_queueProps, config.queueProps, 0
};
queue = clCreateCommandQueueWithProperties(
context, deviceToUse, &queueCreateProps[0], &error);
}
@ -812,14 +930,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
@ -829,7 +947,8 @@ test_status callSingleTestFunction(test_definition test,
}
else
{
int ret = test.func(deviceToUse, context, queue, numElementsToUse);
int ret =
test.func(deviceToUse, context, queue, config.numElementsToUse);
if (ret == TEST_SKIPPED_ITSELF)
{
/* Tests can also let us know they're not supported by the
@ -856,12 +975,14 @@ test_status callSingleTestFunction(test_definition test,
}
/* Release the context */
if (!forceNoContextCreation)
if (!config.forceNoContextCreation)
{
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);
@ -1087,18 +1208,21 @@ Version get_device_spirv_il_version(cl_device_id device)
ASSERT_SUCCESS(err, "clGetDeviceInfo");
}
if (strstr(str.data(), "SPIR-V_1.0") != NULL)
return Version(1, 0);
else if (strstr(str.data(), "SPIR-V_1.1") != NULL)
return Version(1, 1);
else if (strstr(str.data(), "SPIR-V_1.2") != NULL)
return Version(1, 2);
else if (strstr(str.data(), "SPIR-V_1.3") != NULL)
return Version(1, 3);
// Because this query returns a space-separated list of IL version strings
// we should check for SPIR-V versions in reverse order, to return the
// highest version supported.
if (strstr(str.data(), "SPIR-V_1.5") != NULL)
return Version(1, 5);
else if (strstr(str.data(), "SPIR-V_1.4") != NULL)
return Version(1, 4);
else if (strstr(str.data(), "SPIR-V_1.5") != NULL)
return Version(1, 5);
else if (strstr(str.data(), "SPIR-V_1.3") != NULL)
return Version(1, 3);
else if (strstr(str.data(), "SPIR-V_1.2") != NULL)
return Version(1, 2);
else if (strstr(str.data(), "SPIR-V_1.1") != NULL)
return Version(1, 1);
else if (strstr(str.data(), "SPIR-V_1.0") != NULL)
return Version(1, 0);
throw std::runtime_error(std::string("Unknown SPIR-V version: ")
+ str.data());
@ -1172,7 +1296,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__)
@ -1189,6 +1313,8 @@ void PrintArch(void)
vlog("ARCH:\taarch64\n");
#elif defined(_WIN32)
vlog("ARCH:\tWindows\n");
#elif defined(__mips__)
vlog("ARCH:\tmips\n");
#else
#error unknown arch
#endif

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;
@ -83,6 +85,14 @@ typedef enum test_status
TEST_SKIPPED_ITSELF = -100,
} test_status;
struct test_harness_config
{
int forceNoContextCreation;
int numElementsToUse;
cl_command_queue_properties queueProps;
unsigned numWorkerThreads;
};
extern int gFailCount;
extern int gTestCount;
extern cl_uint gReSeed;
@ -115,9 +125,7 @@ extern int runTestHarnessWithCheck(int argc, const char *argv[], int testNum,
extern int parseAndCallCommandLineTests(int argc, const char *argv[],
cl_device_id device, int testNum,
test_definition testList[],
int forceNoContextCreation,
cl_command_queue_properties queueProps,
int num_elements);
const test_harness_config &config);
// Call this function if you need to do all the setup work yourself, and just
// need the function list called/ managed.
@ -129,21 +137,19 @@ extern int parseAndCallCommandLineTests(int argc, const char *argv[],
// resultTestList is an array of statuses which contain the result of each
// selected test testNum is the number of tests in testList, selectedTestList
// and resultTestList contextProps are used to create a testing context for
// each test deviceToUse and numElementsToUse are all just passed to each
// each test deviceToUse and config are all just passed to each
// test function
extern void callTestFunctions(test_definition testList[],
unsigned char selectedTestList[],
test_status resultTestList[], int testNum,
cl_device_id deviceToUse,
int forceNoContextCreation, int numElementsToUse,
cl_command_queue_properties queueProps);
const test_harness_config &config);
// This function is called by callTestFunctions, once per function, to do setup,
// call, logging and cleanup
extern test_status
callSingleTestFunction(test_definition test, cl_device_id deviceToUse,
int forceNoContextCreation, int numElementsToUse,
cl_command_queue_properties queueProps);
extern test_status callSingleTestFunction(test_definition test,
cl_device_id deviceToUse,
const test_harness_config &config);
///// Miscellaneous steps

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,177 @@
#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)
operator T() const { return object; }
// 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 clSVMWrapper {
void *Ptr = nullptr;
cl_context Ctx = nullptr;
public:
clSVMWrapper() = default;
clSVMWrapper(cl_context C, size_t Size,
cl_svm_mem_flags F = CL_MEM_READ_WRITE)
: Ctx(C)
{
mMem = rhs;
Ptr = clSVMAlloc(C, F, Size, 0);
}
clSVMWrapper &operator=(void *other) = delete;
clSVMWrapper(clSVMWrapper const &other) = delete;
clSVMWrapper &operator=(clSVMWrapper const &other) = delete;
clSVMWrapper(clSVMWrapper &&other)
{
Ptr = other.Ptr;
Ctx = other.Ctx;
other.Ptr = nullptr;
other.Ctx = nullptr;
}
clSVMWrapper &operator=(clSVMWrapper &&other)
{
Ptr = other.Ptr;
Ctx = other.Ctx;
other.Ptr = nullptr;
other.Ctx = nullptr;
return *this;
}
operator cl_mem() const { return mMem; }
cl_mem *operator&() { return &mMem; }
~clSVMWrapper()
{
if (Ptr) clSVMFree(Ctx, Ptr);
}
bool operator==(const cl_mem &rhs) { return mMem == rhs; }
protected:
cl_mem mMem;
void *operator()() const { return Ptr; }
};
class clProtectedImage {
public:
clProtectedImage()
@ -183,92 +237,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
@ -18,4 +17,6 @@ set(${MODULE_NAME}_SOURCES
test_migrate.cpp
)
set_gnulike_module_compile_flags("-Wno-sometimes-uninitialized -Wno-sign-compare")
include(../CMakeCommon.txt)

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

@ -16,6 +16,8 @@
#include "common.h"
#include "harness/mt19937.h"
#include <vector>
#define GLOBAL_SIZE 65536
static const char *sources[] = {
@ -75,12 +77,9 @@ wait_and_release(const char* s, cl_event* evs, int n)
int test_svm_migrate(cl_device_id deviceID, cl_context c, cl_command_queue queue, int num_elements)
{
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];
std::vector<cl_uint> amem(GLOBAL_SIZE);
std::vector<cl_uint> bmem(GLOBAL_SIZE);
std::vector<cl_uint> cmem(GLOBAL_SIZE);
cl_event evs[20];
const size_t global_size = GLOBAL_SIZE;
@ -148,9 +147,9 @@ int test_svm_migrate(cl_device_id deviceID, cl_context c, cl_command_queue queue
test_error(error, "clSetKernelArgSVMPointer failed");
// Initialize host copy of data (and result)
fill_buffer(amem, global_size, seed);
fill_buffer(bmem, global_size, seed);
fill_buffer(cmem, global_size, seed);
fill_buffer(amem.data(), global_size, seed);
fill_buffer(bmem.data(), global_size, seed);
fill_buffer(cmem.data(), global_size, seed);
// Now we're ready to start
{
@ -221,9 +220,9 @@ int test_svm_migrate(cl_device_id deviceID, cl_context c, cl_command_queue queue
if (error)
return -1;
memcpy((void *)asvm, (void *)amem, global_size*sizeof(cl_uint));
memcpy((void *)bsvm, (void *)bmem, global_size*sizeof(cl_uint));
memcpy((void *)csvm, (void *)cmem, global_size*sizeof(cl_uint));
memcpy((void *)asvm, (void *)amem.data(), global_size * sizeof(cl_uint));
memcpy((void *)bsvm, (void *)bmem.data(), global_size * sizeof(cl_uint));
memcpy((void *)csvm, (void *)cmem.data(), global_size * sizeof(cl_uint));
{
error = clEnqueueSVMUnmap(queues[1], (void *)asvm, 0, NULL, &evs[0]);
@ -307,9 +306,9 @@ int test_svm_migrate(cl_device_id deviceID, cl_context c, cl_command_queue queue
return -1;
// Check kernel results
bool ok = check("memory a", (cl_uint *)asvm, amem, global_size);
ok &= check("memory b", (cl_uint *)bsvm, bmem, global_size);
ok &= check("memory c", (cl_uint *)csvm, cmem, global_size);
bool ok = check("memory a", (cl_uint *)asvm, amem.data(), global_size);
ok &= check("memory b", (cl_uint *)bsvm, bmem.data(), global_size);
ok &= check("memory c", (cl_uint *)csvm, cmem.data(), global_size);
{
void *ptrs[] = { asvm, bsvm, csvm };

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

@ -8,4 +8,6 @@ set(${MODULE_NAME}_SOURCES
allocation_utils.cpp
)
set_gnulike_module_compile_flags("-Wno-sign-compare")
include(../CMakeCommon.txt)

View file

@ -16,6 +16,8 @@
#include "allocation_execute.h"
#include "allocation_functions.h"
#include <vector>
const char *buffer_kernel_pattern = {
"__kernel void sample_test(%s __global uint *result, __global %s *array_sizes, uint per_item)\n"
@ -79,20 +81,30 @@ int check_image(cl_command_queue queue, cl_mem mem) {
return -1;
}
if (type == CL_MEM_OBJECT_BUFFER) {
log_error("Expected image object, not buffer.\n");
return -1;
} else if (type == CL_MEM_OBJECT_IMAGE2D) {
error = clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL);
if (error) {
print_error(error, "clGetMemObjectInfo failed for CL_IMAGE_WIDTH.");
switch (type)
{
case CL_MEM_OBJECT_BUFFER:
log_error("Expected image object, not buffer.\n");
return -1;
}
error = clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL);
if (error) {
print_error(error, "clGetMemObjectInfo failed for CL_IMAGE_HEIGHT.");
return -1;
}
case CL_MEM_OBJECT_IMAGE2D:
error = clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width,
NULL);
if (error)
{
print_error(error,
"clGetMemObjectInfo failed for CL_IMAGE_WIDTH.");
return -1;
}
error = clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height),
&height, NULL);
if (error)
{
print_error(error,
"clGetMemObjectInfo failed for CL_IMAGE_HEIGHT.");
return -1;
}
break;
default: log_error("unexpected object type"); return -1;
}
@ -130,7 +142,7 @@ int check_image(cl_command_queue queue, cl_mem mem) {
}
#define NUM_OF_WORK_ITEMS 8192*2
#define NUM_OF_WORK_ITEMS (8192 * 32)
int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id device_id, int test, cl_mem mems[], int number_of_mems_used, int verify_checksum) {
@ -145,7 +157,8 @@ int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id dev
size_t global_dims[3];
cl_uint per_item;
cl_uint per_item_uint;
cl_uint returned_results[NUM_OF_WORK_ITEMS], final_result;
cl_uint final_result;
std::vector<cl_uint> returned_results(NUM_OF_WORK_ITEMS);
clEventWrapper event;
cl_int event_status;
@ -226,7 +239,9 @@ int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id dev
}
// Set the result
result_mem = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(cl_uint)*NUM_OF_WORK_ITEMS, &returned_results, &error);
result_mem = clCreateBuffer(
context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
sizeof(cl_uint) * NUM_OF_WORK_ITEMS, returned_results.data(), &error);
test_error(error, "clCreateBuffer failed");
error = clSetKernelArg(kernel, i, sizeof(result_mem), &result_mem);
test_error(error, "clSetKernelArg failed");
@ -332,7 +347,9 @@ int execute_kernel(cl_context context, cl_command_queue *queue, cl_device_id dev
// Verify the checksum.
// Read back the result
error = clEnqueueReadBuffer(*queue, result_mem, CL_TRUE, 0, sizeof(cl_uint)*NUM_OF_WORK_ITEMS, &returned_results, 0, NULL, NULL);
error = clEnqueueReadBuffer(*queue, result_mem, CL_TRUE, 0,
sizeof(cl_uint) * NUM_OF_WORK_ITEMS,
returned_results.data(), 0, NULL, NULL);
test_error_abort(error, "clEnqueueReadBuffer failed");
final_result = 0;
if (test == BUFFER || test == IMAGE_READ || test == BUFFER_NON_BLOCKING || test == IMAGE_READ_NON_BLOCKING) {

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

@ -93,6 +93,11 @@ test_status init_cl( cl_device_id device ) {
// queue, kernel code on GPU.
g_global_mem_size *= 0.60;
}
/* Cap the allocation size as the global size was deduced */
if (g_max_individual_allocation_size > g_global_mem_size)
{
g_max_individual_allocation_size = g_global_mem_size;
}
if( gReSeed )
{
@ -112,6 +117,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 +130,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 +139,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;
@ -324,6 +331,7 @@ int main(int argc, const char *argv[])
else if ( strcmp( argv[i], "--help" ) == 0 || strcmp( argv[i], "-h" ) == 0 )
{
printUsage( argv[0] );
free(argList);
return -1;
}

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;

View file

@ -406,8 +406,8 @@ int test_get_program_info_kernel_names( cl_device_id deviceID, cl_context contex
if (i == sizeof( actual_names ) / sizeof( actual_names[0] ) )
{
free(kernel_names);
log_error( "Kernel names \"%s\" did not match:\n", kernel_names );
free(kernel_names);
for( i = 0; i < sizeof( actual_names ) / sizeof( actual_names[0] ); i++ )
log_error( "\t\t\"%s\"\n", actual_names[0] );
return -1;

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

@ -217,6 +217,9 @@ int test_get_buffer_info( cl_device_id deviceID, cl_context context, cl_command_
// Create a buffer object to test against.
bufferObject = clCreateBuffer( context, bufferFlags[ i ], addressAlign * 4, NULL, &error );
test_error( error, "Unable to create buffer to test with" );
void *ptr;
TEST_MEM_OBJECT_PARAM(bufferObject, CL_MEM_HOST_PTR, ptr, NULL,
"host pointer", "%p", void *)
}
// Perform buffer object queries.
@ -348,14 +351,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 +366,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;
@ -482,7 +476,8 @@ int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_objec
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
CL_MEM_HOST_NO_ACCESS | CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
};
MTdata d;
MTdataHolder d_holder(gRandomSeed);
MTdata d = static_cast<MTdata>(d_holder);
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
@ -501,8 +496,6 @@ int test_get_image_info( cl_device_id deviceID, cl_context context, cl_mem_objec
imageInfo.buffer = NULL;
#endif
d = init_genrand( gRandomSeed );
for ( unsigned int i = 0; i < sizeof(imageFlags) / sizeof(cl_mem_flags); ++i )
{
imageInfo.image_row_pitch = 0;

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

@ -64,16 +64,21 @@ static int test_setargs_and_execution(cl_command_queue queue, cl_kernel kernel,
cl_int status;
const char *typestr;
if (type == NON_NULL_PATH) {
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);
typestr = "non-NULL";
} else if (type == ADDROF_NULL_PATH) {
test_buf = NULL;
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);
typestr = "&NULL";
} else if (type == NULL_PATH) {
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), NULL);
typestr = "NULL";
switch (type)
{
case NON_NULL_PATH:
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);
typestr = "non-NULL";
break;
case ADDROF_NULL_PATH:
test_buf = NULL;
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), &test_buf);
typestr = "&NULL";
break;
case NULL_PATH:
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), NULL);
typestr = "NULL";
break;
}
log_info("Testing setKernelArgs with %s buffer.\n", typestr);
@ -149,7 +154,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 ); \
@ -649,6 +644,13 @@ int test_get_device_info(cl_device_id deviceID, cl_context context, cl_command_q
}
log_info( "\tReported device profile: %s \n", profile );
if (strcmp(profile, "FULL_PROFILE") == 0 && compilerAvail != CL_TRUE)
{
log_error("ERROR: Returned profile of device is FULL , but "
"CL_DEVICE_COMPILER_AVAILABLE is not CL_TRUE as required by "
"OpenCL 1.2!");
return -1;
}
return 0;
}
@ -804,8 +806,8 @@ int test_kernel_required_group_size(cl_device_id deviceID, cl_context context, c
test_error(error, "clFinish failed");
if (max_dimensions == 2) {
return 0;
free(source);
return 0;
}
local[1]--; local[2]++;
@ -824,5 +826,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;
@ -107,8 +107,9 @@ int test_queue_properties(cl_device_id deviceID, cl_context context, cl_command_
clProgramWrapper program;
clKernelWrapper kernel;
cl_queue_properties_khr device_props = 0;
cl_queue_properties_khr queue_prop_def[] = { CL_QUEUE_PROPERTIES, 0, 0 };
cl_command_queue_properties device_props = 0;
cl_command_queue_properties queue_prop_def[] = { CL_QUEUE_PROPERTIES, 0,
0 };
// Query extension
if (!is_extension_available(deviceID, "cl_khr_create_command_queue"))
@ -162,4 +163,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");
@ -208,8 +188,9 @@ int test_sub_group_dispatch(cl_device_id deviceID, cl_context context, cl_comman
}
}
// test when input subgroup count exceeds max wg size
size_t large_sg_size = kernel_subgroup_count + 1;
// test when input subgroup count exceeds max wg size:
// there can be at most the local size of (1 WI) subgroups
size_t large_sg_size = max_local + 1;
error = clGetKernelSubGroupInfo(kernel, deviceID, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, sizeof(size_t), &large_sg_size, sizeof(ret_ndrange1d), &ret_ndrange1d, &realSize);
test_error(error, "clGetKernelSubGroupInfo failed for CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT");
if (ret_ndrange1d != 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
@ -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
@ -13,51 +13,61 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <memory>
#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,310 +82,428 @@ 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",
(int)global_threads[0], (int)local_threads[0]);
// Allocate our storage
cl_mem bin_counters =
clMemWrapper bin_counters =
clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * number_of_bins, NULL, NULL);
cl_mem bins = clCreateBuffer(
clMemWrapper bins = clCreateBuffer(
context, CL_MEM_READ_WRITE,
sizeof(cl_int) * number_of_bins * max_counts_per_bin, NULL, NULL);
cl_mem bin_assignments =
clMemWrapper bin_assignments =
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");
std::unique_ptr<cl_int[]> l_bin_counts(new 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.get(), 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");
std::unique_ptr<cl_int[]> values(
new 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.get(), 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");
std::unique_ptr<cl_int[]> l_bin_assignments(new 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.get(), 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);
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;
}
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) {
std::unique_ptr<cl_int[]> final_bin_assignments(
new 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.get(), 0, NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to read back bins: %d\n", err);
fail = 1; succeed=-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");
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;
std::unique_ptr<cl_int[]> final_bin_counts(new 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.get(), 0, NULL, NULL);
if (err)
{
log_error("add_index_bin_test FAILED to read back bin_counters: %d\n",
err);
return -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++;
}
}
free(l_bin_counts);
free(l_bin_assignments);
free(final_bin_assignments);
free(final_bin_counts);
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,17 +2,16 @@ set(MODULE_NAME BASIC)
set(${MODULE_NAME}_SOURCES
main.cpp
test_fpmath_float.cpp test_fpmath_float2.cpp test_fpmath_float4.cpp
test_fpmath.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
test_int2float.cpp test_float2int.cpp
test_int2fp.cpp
test_createkernelsinprogram.cpp
test_hostptr.cpp
test_explicit_s2v.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
@ -54,14 +52,12 @@ set(${MODULE_NAME}_SOURCES
test_kernel_call_kernel_function.cpp
test_local_kernel_scope.cpp
test_progvar.cpp
test_wg_barrier.cpp
test_global_linear_id.cpp
test_local_linear_id.cpp
test_enqueued_local_size.cpp
test_simple_image_pitch.cpp
test_get_linear_ids.cpp
test_rw_image_access_qualifier.cpp
test_wg_barrier.cpp
test_enqueued_local_size.cpp
test_global_linear_id.cpp
test_local_linear_id.cpp
@ -72,4 +68,6 @@ if(APPLE)
list(APPEND ${MODULE_NAME}_SOURCES test_queue_priority.cpp)
endif(APPLE)
set_gnulike_module_compile_flags("-Wno-sign-compare")
include(../CMakeCommon.txt)

View file

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -22,14 +22,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <CL/cl_half.h>
#include "harness/testHarness.h"
#include "procs.h"
test_definition test_list[] = {
ADD_TEST(hostptr),
ADD_TEST(fpmath_float),
ADD_TEST(fpmath_float2),
ADD_TEST(fpmath_float4),
ADD_TEST(fpmath),
ADD_TEST(intmath_int),
ADD_TEST(intmath_int2),
ADD_TEST(intmath_int4),
@ -58,8 +59,8 @@ test_definition test_list[] = {
ADD_TEST(image_r8),
ADD_TEST(barrier),
ADD_TEST_VERSION(wg_barrier, Version(2, 0)),
ADD_TEST(int2float),
ADD_TEST(float2int),
ADD_TEST(int2fp),
ADD_TEST(fp2int),
ADD_TEST(imagereadwrite),
ADD_TEST(imagereadwrite3d),
ADD_TEST(readimage3d),
@ -91,16 +92,8 @@ test_definition test_list[] = {
ADD_TEST(image_param),
ADD_TEST(image_multipass_integer_coord),
ADD_TEST(image_multipass_float_coord),
ADD_TEST(explicit_s2v_char),
ADD_TEST(explicit_s2v_uchar),
ADD_TEST(explicit_s2v_short),
ADD_TEST(explicit_s2v_ushort),
ADD_TEST(explicit_s2v_int),
ADD_TEST(explicit_s2v_uint),
ADD_TEST(explicit_s2v_long),
ADD_TEST(explicit_s2v_ulong),
ADD_TEST(explicit_s2v_float),
ADD_TEST(explicit_s2v_double),
ADD_TEST(explicit_s2v),
ADD_TEST(enqueue_map_buffer),
ADD_TEST(enqueue_map_image),
@ -155,7 +148,7 @@ test_definition test_list[] = {
ADD_TEST(simple_read_image_pitch),
ADD_TEST(simple_write_image_pitch),
#if defined( __APPLE__ )
#if defined(__APPLE__)
ADD_TEST(queue_priority),
#endif
@ -164,9 +157,35 @@ test_definition test_list[] = {
};
const int test_num = ARRAY_SIZE( test_list );
cl_half_rounding_mode halfRoundingMode = CL_HALF_RTE;
test_status InitCL(cl_device_id device)
{
if (is_extension_available(device, "cl_khr_fp16"))
{
const cl_device_fp_config fpConfigHalf =
get_default_rounding_mode(device, CL_DEVICE_HALF_FP_CONFIG);
if ((fpConfigHalf & CL_FP_ROUND_TO_NEAREST) != 0)
{
halfRoundingMode = CL_HALF_RTE;
}
else if ((fpConfigHalf & CL_FP_ROUND_TO_ZERO) != 0)
{
halfRoundingMode = CL_HALF_RTZ;
}
else
{
log_error("Error while acquiring half rounding mode");
return TEST_FAIL;
}
}
return TEST_PASS;
}
int main(int argc, const char *argv[])
{
return runTestHarness(argc, argv, test_num, test_list, false, 0);
return runTestHarnessWithCheck(argc, argv, test_num, test_list, false, 0,
InitCL);
}

View file

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "harness/kernelHelpers.h"
#include "harness/testHarness.h"
#include "harness/errorHelpers.h"
@ -20,12 +21,9 @@
#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);
extern int test_fpmath_float4(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_fpmath(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_intmath_int(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_intmath_int2(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_intmath_int4(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
@ -54,8 +52,10 @@ extern int test_image_r8(cl_device_id deviceID, cl_context context, cl_comm
extern int test_simplebarrier(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_barrier(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_wg_barrier(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_int2float(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_float2int(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_int2fp(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_fp2int(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_imagearraycopy(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_imagearraycopy3d(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_imagereadwrite(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
@ -91,16 +91,8 @@ extern int test_vstore_global(cl_device_id deviceID, cl_context context, cl
extern int test_vstore_local(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_vstore_private(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_char(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_uchar(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_short(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_ushort(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_int(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_uint(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_long(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_ulong(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_float(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v_double(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_explicit_s2v(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements);
extern int test_enqueue_map_buffer(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements);
extern int test_enqueue_map_image(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

@ -14,62 +14,39 @@
// limitations under the License.
//
#include "harness/compat.h"
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "procs.h"
#include "harness/conversions.h"
#include "harness/stringHelpers.h"
#include "harness/typeWrappers.h"
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
static const char *astype_kernel_pattern =
"%s\n"
#include "procs.h"
// clang-format off
static char extension[128] = { 0 };
static char strLoad[128] = { 0 };
static char strStore[128] = { 0 };
static const char *regLoad = "as_%s%s(src[tid]);\n";
static const char *v3Load = "as_%s%s(vload3(tid,(__global %s*)src));\n";
static const char *regStore = "dst[tid] = tmp;\n";
static const char *v3Store = "vstore3(tmp, tid, (__global %s*)dst);\n";
static const char* astype_kernel_pattern[] = {
extension,
"__kernel void test_fn( __global %s%s *src, __global %s%s *dst )\n"
"{\n"
" int tid = get_global_id( 0 );\n"
" %s%s tmp = as_%s%s( src[ tid ] );\n"
" dst[ tid ] = tmp;\n"
"}\n";
static const char *astype_kernel_pattern_V3srcV3dst =
"%s\n"
"__kernel void test_fn( __global %s *src, __global %s *dst )\n"
"{\n"
" int tid = get_global_id( 0 );\n"
" %s%s tmp = as_%s%s( vload3(tid,src) );\n"
" vstore3(tmp,tid,dst);\n"
"}\n";
// in the printf, remove the third and fifth argument, each of which
// should be a "3", when copying from the printf for astype_kernel_pattern
static const char *astype_kernel_pattern_V3dst =
"%s\n"
"__kernel void test_fn( __global %s%s *src, __global %s *dst )\n"
"{\n"
" int tid = get_global_id( 0 );\n"
" %s3 tmp = as_%s3( src[ tid ] );\n"
" vstore3(tmp,tid,dst);\n"
"}\n";
// in the printf, remove the fifth argument, which
// should be a "3", when copying from the printf for astype_kernel_pattern
static const char *astype_kernel_pattern_V3src =
"%s\n"
"__kernel void test_fn( __global %s *src, __global %s%s *dst )\n"
"{\n"
" int tid = get_global_id( 0 );\n"
" %s%s tmp = as_%s%s( vload3(tid,src) );\n"
" dst[ tid ] = tmp;\n"
"}\n";
// in the printf, remove the third argument, which
// should be a "3", when copying from the printf for astype_kernel_pattern
" int tid = get_global_id( 0 );\n",
" %s%s tmp = ", strLoad,
" ", strStore,
"}\n"};
// clang-format on
int test_astype_set( cl_device_id device, cl_context context, cl_command_queue queue, ExplicitType inVecType, ExplicitType outVecType,
unsigned int vecSize, unsigned int outVecSize,
@ -81,68 +58,60 @@ int test_astype_set( cl_device_id device, cl_context context, cl_command_queue q
clKernelWrapper kernel;
clMemWrapper streams[ 2 ];
char programSrc[ 10240 ];
size_t threads[ 1 ], localThreads[ 1 ];
size_t typeSize = get_explicit_type_size( inVecType );
size_t outTypeSize = get_explicit_type_size(outVecType);
char sizeNames[][ 3 ] = { "", "", "2", "3", "4", "", "", "", "8", "", "", "", "", "", "", "", "16" };
MTdata d;
MTdataHolder d(gRandomSeed);
std::ostringstream sstr;
if (outVecType == kDouble || inVecType == kDouble)
sstr << "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
if (outVecType == kHalf || inVecType == kHalf)
sstr << "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
// Create program
if(outVecSize == 3 && vecSize == 3) {
// astype_kernel_pattern_V3srcV3dst
sprintf( programSrc, astype_kernel_pattern_V3srcV3dst,
(outVecType == kDouble || inVecType == kDouble) ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable" : "",
get_explicit_type_name( inVecType ), // sizeNames[ vecSize ],
get_explicit_type_name( outVecType ), // sizeNames[ outVecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ] );
} else if(outVecSize == 3) {
// astype_kernel_pattern_V3dst
sprintf( programSrc, astype_kernel_pattern_V3dst,
(outVecType == kDouble || inVecType == kDouble) ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable" : "",
get_explicit_type_name( inVecType ), sizeNames[ vecSize ],
get_explicit_type_name( outVecType ),
get_explicit_type_name( outVecType ),
get_explicit_type_name( outVecType ));
strcpy(extension, sstr.str().c_str());
} else if(vecSize == 3) {
// astype_kernel_pattern_V3src
sprintf( programSrc, astype_kernel_pattern_V3src,
(outVecType == kDouble || inVecType == kDouble) ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable" : "",
get_explicit_type_name( inVecType ),// sizeNames[ vecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ]);
} else {
sprintf( programSrc, astype_kernel_pattern,
(outVecType == kDouble || inVecType == kDouble) ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable" : "",
get_explicit_type_name( inVecType ), sizeNames[ vecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ],
get_explicit_type_name( outVecType ), sizeNames[ outVecSize ]);
}
if (vecSize == 3)
std::snprintf(strLoad, sizeof(strLoad), v3Load,
get_explicit_type_name(outVecType), sizeNames[outVecSize],
get_explicit_type_name(inVecType));
else
std::snprintf(strLoad, sizeof(strLoad), regLoad,
get_explicit_type_name(outVecType),
sizeNames[outVecSize]);
const char *ptr = programSrc;
if (outVecSize == 3)
std::snprintf(strStore, sizeof(strStore), v3Store,
get_explicit_type_name(outVecType));
else
std::snprintf(strStore, sizeof(strStore), "%s", regStore);
auto str =
concat_kernel(astype_kernel_pattern,
sizeof(astype_kernel_pattern) / sizeof(const char *));
std::string kernelSource =
str_sprintf(str, get_explicit_type_name(inVecType), sizeNames[vecSize],
get_explicit_type_name(outVecType), sizeNames[outVecSize],
get_explicit_type_name(outVecType), sizeNames[outVecSize]);
const char *ptr = kernelSource.c_str();
error = create_single_kernel_helper( context, &program, &kernel, 1, &ptr, "test_fn" );
test_error( error, "Unable to create testing kernel" );
// Create some input values
size_t inBufferSize = sizeof(char)* numElements * get_explicit_type_size( inVecType ) * vecSize;
char *inBuffer = (char*)malloc( inBufferSize );
std::vector<char> inBuffer(inBufferSize);
size_t outBufferSize = sizeof(char)* numElements * get_explicit_type_size( outVecType ) *outVecSize;
char *outBuffer = (char*)malloc( outBufferSize );
std::vector<char> outBuffer(outBufferSize);
d = init_genrand( gRandomSeed );
generate_random_data( inVecType, numElements * vecSize,
d, inBuffer );
free_mtdata(d); d = NULL;
generate_random_data(inVecType, numElements * vecSize, d,
&inBuffer.front());
// Create I/O streams and set arguments
streams[ 0 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, inBufferSize, inBuffer, &error );
streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, inBufferSize,
&inBuffer.front(), &error);
test_error( error, "Unable to create I/O stream" );
streams[ 1 ] = clCreateBuffer( context, CL_MEM_READ_WRITE, outBufferSize, NULL, &error );
test_error( error, "Unable to create I/O stream" );
@ -161,15 +130,15 @@ int test_astype_set( cl_device_id device, cl_context context, cl_command_queue q
error = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, localThreads, 0, NULL, NULL );
test_error( error, "Unable to run kernel" );
// Get the results and compare
// The beauty is that astype is supposed to return the bit pattern as a different type, which means
// the output should have the exact same bit pattern as the input. No interpretation necessary!
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, outBufferSize, outBuffer, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, outBufferSize,
&outBuffer.front(), 0, NULL, NULL);
test_error( error, "Unable to read results" );
char *expected = inBuffer;
char *actual = outBuffer;
char *expected = &inBuffer.front();
char *actual = &outBuffer.front();
size_t compSize = typeSize*vecSize;
if(outTypeSize*outVecSize < compSize) {
compSize = outTypeSize*outVecSize;
@ -178,8 +147,6 @@ int test_astype_set( cl_device_id device, cl_context context, cl_command_queue q
if(outVecSize == 4 && vecSize == 3)
{
// as_type4(vec3) should compile but produce undefined results??
free(inBuffer);
free(outBuffer);
return 0;
}
@ -188,8 +155,6 @@ int test_astype_set( cl_device_id device, cl_context context, cl_command_queue q
// as_typen(vecm) should compile and run but produce
// implementation-defined results for m != n
// and n*sizeof(type) = sizeof(vecm)
free(inBuffer);
free(outBuffer);
return 0;
}
@ -203,17 +168,14 @@ int test_astype_set( cl_device_id device, cl_context context, cl_command_queue q
GetDataVectorString( expected, typeSize, vecSize, expectedString ),
GetDataVectorString( actual, typeSize, vecSize, actualString ) );
log_error("Src is :\n%s\n----\n%d threads %d localthreads\n",
programSrc, (int)threads[0],(int) localThreads[0]);
free(inBuffer);
free(outBuffer);
kernelSource.c_str(), (int)threads[0],
(int)localThreads[0]);
return 1;
}
expected += typeSize * vecSize;
actual += outTypeSize * outVecSize;
}
free(inBuffer);
free(outBuffer);
return 0;
}
@ -223,31 +185,39 @@ int test_astype(cl_device_id device, cl_context context, cl_command_queue queue,
// legal in OpenCL 1.0, the result is dependent on the device it runs on, which means there's no actual way
// for us to verify what is "valid". So the only thing we can test are types that match in size independent
// of the element count (char -> uchar, etc)
ExplicitType vecTypes[] = { kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong, kULong, kFloat, kDouble, kNumExplicitTypes };
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
const std::vector<ExplicitType> vecTypes = { kChar, kUChar, kShort,
kUShort, kInt, kUInt,
kLong, kULong, kFloat,
kHalf, kDouble };
const unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int inTypeIdx, outTypeIdx, sizeIdx, outSizeIdx;
size_t inTypeSize, outTypeSize;
int error = 0;
for( inTypeIdx = 0; vecTypes[ inTypeIdx ] != kNumExplicitTypes; inTypeIdx++ )
bool fp16Support = is_extension_available(device, "cl_khr_fp16");
bool fp64Support = is_extension_available(device, "cl_khr_fp64");
auto skip_type = [&](ExplicitType et) {
if ((et == kLong || et == kULong) && !gHasLong)
return true;
else if (et == kDouble && !fp64Support)
return true;
else if (et == kHalf && !fp16Support)
return true;
return false;
};
for (inTypeIdx = 0; inTypeIdx < vecTypes.size(); inTypeIdx++)
{
inTypeSize = get_explicit_type_size(vecTypes[inTypeIdx]);
if( vecTypes[ inTypeIdx ] == kDouble && !is_extension_available( device, "cl_khr_fp64" ) )
continue;
if (skip_type(vecTypes[inTypeIdx])) continue;
if (( vecTypes[ inTypeIdx ] == kLong || vecTypes[ inTypeIdx ] == kULong ) && !gHasLong )
continue;
for( outTypeIdx = 0; vecTypes[ outTypeIdx ] != kNumExplicitTypes; outTypeIdx++ )
for (outTypeIdx = 0; outTypeIdx < vecTypes.size(); outTypeIdx++)
{
outTypeSize = get_explicit_type_size(vecTypes[outTypeIdx]);
if( vecTypes[ outTypeIdx ] == kDouble && !is_extension_available( device, "cl_khr_fp64" ) ) {
continue;
}
if (( vecTypes[ outTypeIdx ] == kLong || vecTypes[ outTypeIdx ] == kULong ) && !gHasLong )
continue;
if (skip_type(vecTypes[outTypeIdx])) continue;
// change this check
if( inTypeIdx == outTypeIdx ) {
@ -259,7 +229,6 @@ int test_astype(cl_device_id device, cl_context context, cl_command_queue queue,
for( sizeIdx = 0; vecSizes[ sizeIdx ] != 0; sizeIdx++ )
{
for(outSizeIdx = 0; vecSizes[outSizeIdx] != 0; outSizeIdx++)
{
if(vecSizes[sizeIdx]*inTypeSize !=
@ -268,10 +237,7 @@ int test_astype(cl_device_id device, cl_context context, cl_command_queue queue,
continue;
}
error += test_astype_set( device, context, queue, vecTypes[ inTypeIdx ], vecTypes[ outTypeIdx ], vecSizes[ sizeIdx ], vecSizes[outSizeIdx], n_elems );
}
}
if(get_explicit_type_size(vecTypes[inTypeIdx]) ==
get_explicit_type_size(vecTypes[outTypeIdx])) {

View file

@ -20,8 +20,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include "procs.h"
#include "harness/conversions.h"
@ -86,8 +85,7 @@ int test_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue,
clKernelWrapper kernel;
clMemWrapper streams[ 2 ];
size_t threads[ 1 ], localThreads[ 1 ];
void *inBuffer, *outBuffer;
MTdata d;
MTdataHolder d(gRandomSeed);
char vecNameString[64]; vecNameString[0] = 0;
if (vecSize == 1)
sprintf(vecNameString, "%s", get_explicit_type_name(vecType));
@ -109,9 +107,15 @@ int test_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue,
char programSource[4096]; programSource[0]=0;
char *programPtr;
sprintf(programSource, kernelCode,
vecType == kDouble ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable" : "",
vecNameString, vecNameString, vecNameString, vecNameString, get_explicit_type_name(vecType), vecNameString, vecNameString);
std::string extStr = "";
if (vecType == kDouble)
extStr = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable";
else if (vecType == kHalf)
extStr = "#pragma OPENCL EXTENSION cl_khr_fp16 : enable";
sprintf(programSource, kernelCode, extStr.c_str(), vecNameString,
vecNameString, vecNameString, vecNameString,
get_explicit_type_name(vecType), vecNameString, vecNameString);
//log_info("program: %s\n", programSource);
programPtr = programSource;
@ -150,9 +154,10 @@ int test_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue,
size_t globalBufferSize = numberOfLocalWorkgroups*localBufferSize;
size_t globalWorkgroupSize = numberOfLocalWorkgroups*localWorkgroupSize;
inBuffer = (void*)malloc(globalBufferSize);
outBuffer = (void*)malloc(globalBufferSize);
memset(outBuffer, 0, globalBufferSize);
std::vector<unsigned char> inBuffer(globalBufferSize);
std::vector<unsigned char> outBuffer(globalBufferSize);
outBuffer.assign(globalBufferSize, 0);
cl_int copiesPerWorkItemInt, copiesPerWorkgroup;
copiesPerWorkItemInt = (int)numberOfCopiesPerWorkitem;
@ -164,13 +169,15 @@ int test_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue,
threads[0] = globalWorkgroupSize;
localThreads[0] = localWorkgroupSize;
d = init_genrand( gRandomSeed );
generate_random_data( vecType, globalBufferSize/get_explicit_type_size(vecType), d, inBuffer );
free_mtdata(d); d = NULL;
generate_random_data(vecType,
globalBufferSize / get_explicit_type_size(vecType), d,
&inBuffer.front());
streams[ 0 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, globalBufferSize, inBuffer, &error );
streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, globalBufferSize,
&inBuffer.front(), &error);
test_error( error, "Unable to create input buffer" );
streams[ 1 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, globalBufferSize, outBuffer, &error );
streams[1] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, globalBufferSize,
&outBuffer.front(), &error);
test_error( error, "Unable to create output buffer" );
error = clSetKernelArg( kernel, 0, sizeof( streams[ 0 ] ), &streams[ 0 ] );
@ -189,16 +196,18 @@ int test_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue,
test_error( error, "Unable to queue kernel" );
// Read
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, globalBufferSize, outBuffer, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, globalBufferSize,
&outBuffer.front(), 0, NULL, NULL);
test_error( error, "Unable to read results" );
// Verify
int failuresPrinted = 0;
if( memcmp( inBuffer, outBuffer, globalBufferSize ) != 0 )
if (memcmp(&inBuffer.front(), &outBuffer.front(), globalBufferSize) != 0)
{
size_t typeSize = get_explicit_type_size(vecType)* vecSize;
unsigned char * inchar = (unsigned char*)inBuffer;
unsigned char * outchar = (unsigned char*)outBuffer;
unsigned char *inchar = static_cast<unsigned char *>(&inBuffer.front());
unsigned char *outchar =
static_cast<unsigned char *>(&outBuffer.front());
for (int i=0; i< (int)globalBufferSize; i+=(int)elementSize) {
if (memcmp( ((char *)inchar)+i, ((char *)outchar)+i, typeSize) != 0 )
{
@ -226,26 +235,29 @@ int test_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue,
}
}
free(inBuffer);
free(outBuffer);
return failuresPrinted ? -1 : 0;
}
int test_copy_all_types(cl_device_id deviceID, cl_context context, cl_command_queue queue, const char *kernelCode) {
ExplicitType vecType[] = { kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong, kULong, kFloat, kDouble, kNumExplicitTypes };
const std::vector<ExplicitType> vecType = { kChar, kUChar, kShort, kUShort,
kInt, kUInt, kLong, kULong,
kFloat, kHalf, kDouble };
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int size, typeIndex;
int errors = 0;
for( typeIndex = 0; vecType[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
{
if( vecType[ typeIndex ] == kDouble && !is_extension_available( deviceID, "cl_khr_fp64" ) )
continue;
bool fp16Support = is_extension_available(deviceID, "cl_khr_fp16");
bool fp64Support = is_extension_available(deviceID, "cl_khr_fp64");
for (typeIndex = 0; typeIndex < vecType.size(); typeIndex++)
{
if (( vecType[ typeIndex ] == kLong || vecType[ typeIndex ] == kULong ) && !gHasLong )
continue;
else if (vecType[typeIndex] == kDouble && !fp64Support)
continue;
else if (vecType[typeIndex] == kHalf && !fp16Support)
continue;
for( size = 0; vecSizes[ size ] != 0; size++ )
{
@ -259,9 +271,6 @@ int test_copy_all_types(cl_device_id deviceID, cl_context context, cl_command_qu
return 0;
}
int test_async_copy_global_to_local(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
return test_copy_all_types( deviceID, context, queue, async_global_to_local_kernel );

View file

@ -25,104 +25,103 @@
#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
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";
#define STRUCT_SIZE %d
typedef struct __attribute__((packed))
{
uchar byte[STRUCT_SIZE];
} VarSizeStruct __attribute__((aligned(1)));
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,
bool localIsDst)
__kernel void test_fn(const __global VarSizeStruct *src, __global VarSizeStruct *dst,
__local VarSizeStruct *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;
for (int k = 0; k < STRUCT_SIZE; k++) {
localBuffer[index].byte[k] = 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(VarSizeStruct),
(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
#define STRUCT_SIZE %d
typedef struct __attribute__((packed))
{
uchar byte[STRUCT_SIZE];
} VarSizeStruct __attribute__((aligned(1)));
__kernel void test_fn(const __global VarSizeStruct *src, __global VarSizeStruct *dst, __local VarSizeStruct *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;
for (int k = 0; k < STRUCT_SIZE; k++) {
localBuffer[index].byte[k] = 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(VarSizeStruct), (size_t)numElementsPerLine, (size_t)lineCopiesPerWorkgroup, srcStride,
dstStride, 0 );
wait_group_events(1, &event);
};
)OpenCLC";
int test_copy2D(const cl_device_id deviceID, const cl_context context,
const cl_command_queue queue, const char *const kernelCode,
const size_t elementSize, const int srcMargin,
const int dstMargin, const bool localIsDst)
{
int error;
clProgramWrapper program;
clKernelWrapper kernel;
clMemWrapper streams[2];
size_t threads[1], localThreads[1];
void *inBuffer, *outBuffer, *outBufferCopy;
MTdata d;
char vecNameString[64];
vecNameString[0] = 0;
if (vecSize == 1)
sprintf(vecNameString, "%s", get_explicit_type_name(vecType));
else
sprintf(vecNameString, "%s%d", get_explicit_type_name(vecType),
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 %d byte element with srcMargin = %d, dstMargin = %d\n",
elementSize, srcMargin, dstMargin);
cl_long max_local_mem_size;
error =
@ -142,6 +141,13 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
test_error(error,
"clGetDeviceInfo for CL_DEVICE_MAX_MEM_ALLOC_SIZE failed.");
cl_long max_work_group_size;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE,
sizeof(max_work_group_size), &max_work_group_size,
NULL);
test_error(error,
"clGetDeviceInfo for CL_DEVICE_MAX_WORK_GROUP_SIZE failed.");
if (max_alloc_size > max_global_mem_size / 2)
max_alloc_size = max_global_mem_size / 2;
@ -152,20 +158,17 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
test_error(error,
"clGetDeviceInfo for CL_DEVICE_MAX_COMPUTE_UNITS failed.");
char programSource[4096];
programSource[0] = 0;
char *programPtr;
char programSource[4096] = { 0 };
const char *programPtr = programSource;
sprintf(programSource, kernelCode,
vecType == kDouble ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable"
: "",
vecNameString, vecNameString, vecNameString, vecNameString,
get_explicit_type_name(vecType), vecNameString, vecNameString);
sprintf(programSource, kernelCode, elementSize);
// log_info("program: %s\n", programSource);
programPtr = programSource;
clProgramWrapper program;
clKernelWrapper kernel;
error = create_single_kernel_helper(context, &program, &kernel, 1,
(const char **)&programPtr, "test_fn");
&programPtr, "test_fn");
test_error(error, "Unable to create testing kernel");
size_t max_workgroup_size;
@ -187,12 +190,14 @@ 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;
elementSize =
get_explicit_type_size(vecType) * ((vecSize == 3) ? 4 : vecSize);
size_t localStorageSpacePerWorkitem = lineCopiesPerWorkItem * elementSize
* (numElementsPerLine + (localIsDst ? dstStride : srcStride));
const size_t numElementsPerLine = 10;
const cl_int dstStride = numElementsPerLine + dstMargin;
const cl_int srcStride = numElementsPerLine + srcMargin;
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 +211,46 @@ 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);
if ((localBufferSize / 4) > max_work_group_size)
{
log_info("Skipping due to resource requirements local:%db "
"max_work_group_size:%d\n",
localBufferSize, max_work_group_size);
return 0;
}
cl_int lineCopiesPerWorkItemInt, numElementsPerLineInt,
lineCopiesPerWorkgroup;
lineCopiesPerWorkItemInt = (int)lineCopiesPerWorkItem;
numElementsPerLineInt = (int)numElementsPerLine;
lineCopiesPerWorkgroup = (int)(lineCopiesPerWorkItem * localWorkgroupSize);
void *const inBuffer = (void *)malloc(inBufferSize);
void *const outBuffer = (void *)malloc(outBufferSize);
void *const outBufferCopy = (void *)malloc(outBufferSize);
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, "
@ -243,18 +260,20 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
(int)inBufferSize, (int)outBufferSize, lineCopiesPerWorkgroup,
lineCopiesPerWorkItemInt);
size_t threads[1], localThreads[1];
threads[0] = globalWorkgroupSize;
localThreads[0] = localWorkgroupSize;
d = init_genrand(gRandomSeed);
generate_random_data(
vecType, inBufferSize / get_explicit_type_size(vecType), d, inBuffer);
generate_random_data(
vecType, outBufferSize / get_explicit_type_size(vecType), d, outBuffer);
MTdata d = init_genrand(gRandomSeed);
generate_random_data(kChar, inBufferSize, d, inBuffer);
generate_random_data(kChar, outBufferSize, d, outBuffer);
free_mtdata(d);
d = NULL;
memcpy(outBufferCopy, outBuffer, outBufferSize);
clMemWrapper streams[2];
streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, inBufferSize,
inBuffer, &error);
test_error(error, "Unable to create input buffer");
@ -294,8 +313,7 @@ int test_copy2D(cl_device_id deviceID, cl_context context,
// Verify
int failuresPrinted = 0;
// Verify
size_t typeSize = get_explicit_type_size(vecType) * vecSize;
for (int i = 0;
i < (int)globalWorkgroupSize * lineCopiesPerWorkItem * elementSize;
i += elementSize)
@ -303,16 +321,15 @@ 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)
elementSize)
!= 0)
{
unsigned char *inchar = (unsigned char *)inBuffer + inIdx;
unsigned char *outchar = (unsigned char *)outBuffer + outIdx;
char values[4096];
values[0] = 0;
char values[4096] = { 0 };
if (failuresPrinted == 0)
{
@ -339,11 +356,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)
@ -376,62 +392,42 @@ int test_copy2D_all_types(cl_device_id deviceID, cl_context context,
cl_command_queue queue, const char *kernelCode,
bool localIsDst)
{
ExplicitType vecType[] = {
kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong,
kULong, kFloat, kDouble, kNumExplicitTypes
};
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int smallTypesStrideSizes[] = { 0, 10, 100 };
unsigned int size, typeIndex, srcStride, dstStride;
const unsigned int elemSizes[] = { 1, 2, 3, 4, 5, 6, 7,
8, 13, 16, 32, 47, 64 };
// 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.
// These have to be multipliers, because the margin must be a multiple of
// element size.
const unsigned int marginMultipliers[] = { 0, 10, 100 };
int errors = 0;
for (typeIndex = 0; vecType[typeIndex] != kNumExplicitTypes; typeIndex++)
if (!is_extension_available(deviceID, "cl_khr_extended_async_copies"))
{
if (vecType[typeIndex] == kDouble
&& !is_extension_available(deviceID, "cl_khr_fp64"))
continue;
if ((vecType[typeIndex] == kLong || vecType[typeIndex] == kULong)
&& !gHasLong)
continue;
for (size = 0; vecSizes[size] != 0; size++)
log_info(
"Device does not support extended async copies. Skipping test.\n");
}
else
{
for (const unsigned int elemSize : elemSizes)
{
if (get_explicit_type_size(vecType[typeIndex]) * vecSizes[size]
<= 2) // small type
for (const unsigned int srcMarginMultiplier : marginMultipliers)
{
for (srcStride = 0; srcStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
srcStride++)
for (const unsigned int dstMarginMultiplier : marginMultipliers)
{
for (dstStride = 0;
dstStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
dstStride++)
if (test_copy2D(deviceID, context, queue, kernelCode,
elemSize, srcMarginMultiplier * elemSize,
dstMarginMultiplier * elemSize, localIsDst))
{
if (test_copy2D(deviceID, context, queue, kernelCode,
vecType[typeIndex], vecSizes[size],
smallTypesStrideSizes[srcStride],
smallTypesStrideSizes[dstStride],
localIsDst))
{
errors++;
}
errors++;
}
}
}
// not a small type, check only zero stride
else if (test_copy2D(deviceID, context, queue, kernelCode,
vecType[typeIndex], vecSizes[size], 0, 0,
localIsDst))
{
errors++;
}
}
}
if (errors) return -1;
return 0;
return errors ? -1 : 0;
}
int test_async_copy_global_to_local2D(cl_device_id deviceID, cl_context context,

View file

@ -25,125 +25,118 @@
#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
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";
#define STRUCT_SIZE %d
typedef struct __attribute__((packed))
{
uchar byte[STRUCT_SIZE];
} VarSizeStruct __attribute__((aligned(1)));
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,
bool localIsDst)
__kernel void test_fn(const __global VarSizeStruct *src, __global VarSizeStruct *dst, __local VarSizeStruct *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;
for (int k = 0; k < STRUCT_SIZE; k++) {
localBuffer[index].byte[k] = 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(VarSizeStruct), (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
#define STRUCT_SIZE %d
typedef struct __attribute__((packed))
{
uchar byte[STRUCT_SIZE];
} VarSizeStruct __attribute__((aligned(1)));
__kernel void test_fn(const __global VarSizeStruct *src, __global VarSizeStruct *dst, __local VarSizeStruct *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;
for (int k = 0; k < STRUCT_SIZE; k++) {
localBuffer[index].byte[k] = 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(VarSizeStruct), (size_t)numElementsPerLine, (size_t)numLines, planesCopiesPerWorkgroup,
srcLineStride, srcPlaneStride, dstLineStride, dstPlaneStride, 0);
wait_group_events(1, &event);
}
)OpenCLC";
int test_copy3D(const cl_device_id deviceID, const cl_context context,
const cl_command_queue queue, const char *const kernelCode,
const size_t elementSize, const int srcLineMargin,
const int dstLineMargin, const int srcPlaneMargin,
const int dstPlaneMargin, const bool localIsDst)
{
int error;
clProgramWrapper program;
clKernelWrapper kernel;
clMemWrapper streams[2];
size_t threads[1], localThreads[1];
void *inBuffer, *outBuffer, *outBufferCopy;
MTdata d;
char vecNameString[64];
vecNameString[0] = 0;
if (vecSize == 1)
sprintf(vecNameString, "%s", get_explicit_type_name(vecType));
else
sprintf(vecNameString, "%s%d", get_explicit_type_name(vecType),
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 %d byte element with srcLineMargin = %d, dstLineMargin = %d, "
"srcPlaneMargin = %d, dstPlaneMargin = %d\n",
elementSize, srcLineMargin, dstLineMargin, srcPlaneMargin,
dstPlaneMargin);
cl_long max_local_mem_size;
error =
@ -173,20 +166,16 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
test_error(error,
"clGetDeviceInfo for CL_DEVICE_MAX_COMPUTE_UNITS failed.");
char programSource[4096];
programSource[0] = 0;
char *programPtr;
char programSource[4096] = { 0 };
const char *programPtr = programSource;
sprintf(programSource, kernelCode,
vecType == kDouble ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable"
: "",
vecNameString, vecNameString, vecNameString, vecNameString,
get_explicit_type_name(vecType), vecNameString, vecNameString);
sprintf(programSource, kernelCode, elementSize);
// log_info("program: %s\n", programSource);
programPtr = programSource;
clProgramWrapper program;
clKernelWrapper kernel;
error = create_single_kernel_helper(context, &program, &kernel, 1,
(const char **)&programPtr, "test_fn");
&programPtr, "test_fn");
test_error(error, "Unable to create testing kernel");
size_t max_workgroup_size;
@ -204,20 +193,29 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
test_error(error,
"clGetDeviceInfo failed for CL_DEVICE_MAX_WORK_ITEM_SIZES");
cl_long max_work_group_size;
error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE,
sizeof(max_work_group_size), &max_work_group_size,
NULL);
test_error(error,
"clGetDeviceInfo for CL_DEVICE_MAX_WORK_GROUP_SIZE failed.");
// Pick the minimum of the device and the kernel
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;
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 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;
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 +229,49 @@ 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);
if ((localBufferSize / 4) > max_work_group_size)
{
log_info("Skipping due to resource requirements local:%db "
"max_work_group_size:%d\n",
localBufferSize, max_work_group_size);
return 0;
}
cl_int planesCopiesPerWorkItemInt, numElementsPerLineInt, numLinesInt,
planesCopiesPerWorkgroup;
planesCopiesPerWorkItemInt = (int)planesCopiesPerWorkItem;
numElementsPerLineInt = (int)numElementsPerLine;
numLinesInt = (int)numLines;
planesCopiesPerWorkgroup =
(int)(planesCopiesPerWorkItem * localWorkgroupSize);
void *const inBuffer = (void *)malloc(inBufferSize);
void *const outBuffer = (void *)malloc(outBufferSize);
void *const outBufferCopy = (void *)malloc(outBufferSize);
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 "
@ -275,18 +280,20 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
(int)localBufferSize, (int)inBufferSize, (int)outBufferSize,
planesCopiesPerWorkgroup, planesCopiesPerWorkItemInt);
size_t threads[1], localThreads[1];
threads[0] = globalWorkgroupSize;
localThreads[0] = localWorkgroupSize;
d = init_genrand(gRandomSeed);
generate_random_data(
vecType, inBufferSize / get_explicit_type_size(vecType), d, inBuffer);
generate_random_data(
vecType, outBufferSize / get_explicit_type_size(vecType), d, outBuffer);
MTdata d = init_genrand(gRandomSeed);
generate_random_data(kChar, inBufferSize, d, inBuffer);
generate_random_data(kChar, outBufferSize, d, outBuffer);
free_mtdata(d);
d = NULL;
memcpy(outBufferCopy, outBuffer, outBufferSize);
clMemWrapper streams[2];
streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, inBufferSize,
inBuffer, &error);
test_error(error, "Unable to create input buffer");
@ -332,8 +339,7 @@ int test_copy3D(cl_device_id deviceID, cl_context context,
// Verify
int failuresPrinted = 0;
// Verify
size_t typeSize = get_explicit_type_size(vecType) * vecSize;
for (int i = 0;
i < (int)globalWorkgroupSize * planesCopiesPerWorkItem * elementSize;
i += elementSize)
@ -343,23 +349,16 @@ 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)
((char *)outBuffer) + outIdx, elementSize)
!= 0)
{
unsigned char *inchar = (unsigned char *)inBuffer + inIdx;
unsigned char *outchar =
(unsigned char *)outBuffer + outIdx;
char values[4096];
values[0] = 0;
char values[4096] = { 0 };
if (failuresPrinted == 0)
{
@ -385,14 +384,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 +412,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)
@ -456,75 +449,51 @@ int test_copy3D_all_types(cl_device_id deviceID, cl_context context,
cl_command_queue queue, const char *kernelCode,
bool localIsDst)
{
ExplicitType vecType[] = {
kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong,
kULong, kFloat, kDouble, kNumExplicitTypes
};
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int smallTypesStrideSizes[] = { 0, 10, 100 };
unsigned int size, typeIndex, srcLineStride, dstLineStride, srcPlaneStride,
dstPlaneStride;
const unsigned int elemSizes[] = { 1, 2, 3, 4, 5, 6, 7,
8, 13, 16, 32, 47, 64 };
// 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
// size of the line or plane plus the chosen margin.
// These have to be multipliers, because the margin must be a multiple of
// element size.
const unsigned int marginMultipliers[] = { 0, 10, 100 };
int errors = 0;
for (typeIndex = 0; vecType[typeIndex] != kNumExplicitTypes; typeIndex++)
if (!is_extension_available(deviceID, "cl_khr_extended_async_copies"))
{
if (vecType[typeIndex] == kDouble
&& !is_extension_available(deviceID, "cl_khr_fp64"))
continue;
if ((vecType[typeIndex] == kLong || vecType[typeIndex] == kULong)
&& !gHasLong)
continue;
for (size = 0; vecSizes[size] != 0; size++)
log_info(
"Device does not support extended async copies. Skipping test.\n");
}
else
{
for (const unsigned int elemSize : elemSizes)
{
if (get_explicit_type_size(vecType[typeIndex]) * vecSizes[size]
<= 2) // small type
for (const unsigned int srcLineMarginMultiplier : marginMultipliers)
{
for (srcLineStride = 0;
srcLineStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
srcLineStride++)
for (const unsigned int dstLineMarginMultiplier :
marginMultipliers)
{
for (dstLineStride = 0;
dstLineStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
dstLineStride++)
for (const unsigned int srcPlaneMarginMultiplier :
marginMultipliers)
{
for (srcPlaneStride = 0;
srcPlaneStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
srcPlaneStride++)
for (const unsigned int dstPlaneMarginMultiplier :
marginMultipliers)
{
for (dstPlaneStride = 0;
dstPlaneStride < sizeof(smallTypesStrideSizes)
/ sizeof(smallTypesStrideSizes[0]);
dstPlaneStride++)
if (test_copy3D(deviceID, context, queue,
kernelCode, elemSize,
srcLineMarginMultiplier * elemSize,
dstLineMarginMultiplier * elemSize,
srcPlaneMarginMultiplier * elemSize,
dstPlaneMarginMultiplier * elemSize,
localIsDst))
{
if (test_copy3D(
deviceID, context, queue, kernelCode,
vecType[typeIndex], vecSizes[size],
smallTypesStrideSizes[srcLineStride],
smallTypesStrideSizes[dstLineStride],
smallTypesStrideSizes[srcPlaneStride],
smallTypesStrideSizes[dstPlaneStride],
localIsDst))
{
errors++;
}
errors++;
}
}
}
}
}
// not a small type, check only zero stride
else if (test_copy3D(deviceID, context, queue, kernelCode,
vecType[typeIndex], vecSizes[size], 0, 0, 0, 0,
localIsDst))
{
errors++;
}
}
}
if (errors) return -1;

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

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -20,15 +20,16 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include "procs.h"
#include "harness/conversions.h"
// clang-format off
static const char *async_strided_global_to_local_kernel =
"%s\n" // optional pragma string
"%s__kernel void test_fn( const __global %s *src, __global %s *dst, __local %s *localBuffer, int copiesPerWorkgroup, int copiesPerWorkItem, int stride )\n"
"__kernel void test_fn( const __global %s *src, __global %s *dst, __local %s *localBuffer, int copiesPerWorkgroup, int copiesPerWorkItem, int stride )\n"
"{\n"
" int i;\n"
// Zero the local storage first
@ -46,7 +47,7 @@ static const char *async_strided_global_to_local_kernel =
static const char *async_strided_local_to_global_kernel =
"%s\n" // optional pragma string
"%s__kernel void test_fn( const __global %s *src, __global %s *dst, __local %s *localBuffer, int copiesPerWorkgroup, int copiesPerWorkItem, int stride )\n"
"__kernel void test_fn( const __global %s *src, __global %s *dst, __local %s *localBuffer, int copiesPerWorkgroup, int copiesPerWorkItem, int stride )\n"
"{\n"
" int i;\n"
// Zero the local storage first
@ -63,6 +64,7 @@ static const char *async_strided_local_to_global_kernel =
" wait_group_events( 1, &event );\n"
"}\n" ;
// clang-format on
int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queue queue, const char *kernelCode, ExplicitType vecType, int vecSize, int stride)
{
@ -71,8 +73,7 @@ int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queu
clKernelWrapper kernel;
clMemWrapper streams[ 2 ];
size_t threads[ 1 ], localThreads[ 1 ];
void *inBuffer, *outBuffer;
MTdata d;
MTdataHolder d(gRandomSeed);
char vecNameString[64]; vecNameString[0] = 0;
if (vecSize == 1)
@ -94,10 +95,15 @@ int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queu
char programSource[4096]; programSource[0]=0;
char *programPtr;
sprintf(programSource, kernelCode,
vecType == kDouble ? "#pragma OPENCL EXTENSION cl_khr_fp64 : enable" : "",
"",
vecNameString, vecNameString, vecNameString, vecNameString, get_explicit_type_name(vecType), vecNameString, vecNameString);
std::string extStr = "";
if (vecType == kDouble)
extStr = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable";
else if (vecType == kHalf)
extStr = "#pragma OPENCL EXTENSION cl_khr_fp16 : enable";
sprintf(programSource, kernelCode, extStr.c_str(), vecNameString,
vecNameString, vecNameString, vecNameString,
get_explicit_type_name(vecType), vecNameString, vecNameString);
//log_info("program: %s\n", programSource);
programPtr = programSource;
@ -151,9 +157,9 @@ int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queu
size_t globalBufferSize = numberOfLocalWorkgroups*localBufferSize*stride;
size_t globalWorkgroupSize = numberOfLocalWorkgroups*localWorkgroupSize;
inBuffer = (void*)malloc(globalBufferSize);
outBuffer = (void*)malloc(globalBufferSize);
memset(outBuffer, 0, globalBufferSize);
std::vector<unsigned char> inBuffer(globalBufferSize);
std::vector<unsigned char> outBuffer(globalBufferSize);
memset(outBuffer.data(), 0, globalBufferSize);
cl_int copiesPerWorkItemInt, copiesPerWorkgroup;
copiesPerWorkItemInt = (int)numberOfCopiesPerWorkitem;
@ -165,13 +171,15 @@ int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queu
threads[0] = globalWorkgroupSize;
localThreads[0] = localWorkgroupSize;
d = init_genrand( gRandomSeed );
generate_random_data( vecType, globalBufferSize/get_explicit_type_size(vecType), d, inBuffer );
free_mtdata(d); d = NULL;
generate_random_data(vecType,
globalBufferSize / get_explicit_type_size(vecType), d,
inBuffer.data());
streams[ 0 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, globalBufferSize, inBuffer, &error );
streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, globalBufferSize,
inBuffer.data(), &error);
test_error( error, "Unable to create input buffer" );
streams[ 1 ] = clCreateBuffer( context, CL_MEM_COPY_HOST_PTR, globalBufferSize, outBuffer, &error );
streams[1] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, globalBufferSize,
outBuffer.data(), &error);
test_error( error, "Unable to create output buffer" );
error = clSetKernelArg( kernel, 0, sizeof( streams[ 0 ] ), &streams[ 0 ] );
@ -192,17 +200,20 @@ int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queu
test_error( error, "Unable to queue kernel" );
// Read
error = clEnqueueReadBuffer( queue, streams[ 1 ], CL_TRUE, 0, globalBufferSize, outBuffer, 0, NULL, NULL );
error = clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, globalBufferSize,
outBuffer.data(), 0, NULL, NULL);
test_error( error, "Unable to read results" );
// Verify
size_t typeSize = get_explicit_type_size(vecType)* vecSize;
for (int i=0; i<(int)globalBufferSize; i+=(int)elementSize*(int)stride)
{
if (memcmp( ((char *)inBuffer)+i, ((char *)outBuffer)+i, typeSize) != 0 )
if (memcmp(&inBuffer.at(i), &outBuffer.at(i), typeSize) != 0)
{
unsigned char * inchar = (unsigned char*)inBuffer + i;
unsigned char * outchar = (unsigned char*)outBuffer + i;
unsigned char *inchar =
static_cast<unsigned char *>(&inBuffer.at(i));
unsigned char *outchar =
static_cast<unsigned char *>(&outBuffer.at(i));
char values[4096];
values[0] = 0;
@ -215,34 +226,35 @@ int test_strided_copy(cl_device_id deviceID, cl_context context, cl_command_queu
sprintf(values + strlen( values), "%2x ", outchar[j]);
sprintf(values + strlen(values), "]");
log_error("%s\n", values);
free(inBuffer);
free(outBuffer);
return -1;
}
}
free(inBuffer);
free(outBuffer);
return 0;
}
int test_strided_copy_all_types(cl_device_id deviceID, cl_context context, cl_command_queue queue, const char *kernelCode)
{
ExplicitType vecType[] = { kChar, kUChar, kShort, kUShort, kInt, kUInt, kLong, kULong, kFloat, kDouble, kNumExplicitTypes };
unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
unsigned int strideSizes[] = { 1, 3, 4, 5, 0 };
const std::vector<ExplicitType> vecType = { kChar, kUChar, kShort, kUShort,
kInt, kUInt, kLong, kULong,
kFloat, kHalf, kDouble };
const unsigned int vecSizes[] = { 1, 2, 3, 4, 8, 16, 0 };
const unsigned int strideSizes[] = { 1, 3, 4, 5, 0 };
unsigned int size, typeIndex, stride;
int errors = 0;
for( typeIndex = 0; vecType[ typeIndex ] != kNumExplicitTypes; typeIndex++ )
{
if( vecType[ typeIndex ] == kDouble && !is_extension_available( deviceID, "cl_khr_fp64" ) )
continue;
bool fp16Support = is_extension_available(deviceID, "cl_khr_fp16");
bool fp64Support = is_extension_available(deviceID, "cl_khr_fp64");
for (typeIndex = 0; typeIndex < vecType.size(); typeIndex++)
{
if (( vecType[ typeIndex ] == kLong || vecType[ typeIndex ] == kULong ) && !gHasLong )
continue;
else if (vecType[typeIndex] == kDouble && !fp64Support)
continue;
else if (vecType[typeIndex] == kHalf && !fp16Support)
continue;
for( size = 0; vecSizes[ size ] != 0; size++ )
{
@ -260,9 +272,6 @@ int test_strided_copy_all_types(cl_device_id deviceID, cl_context context, cl_co
return 0;
}
int test_async_strided_copy_global_to_local(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
return test_strided_copy_all_types( deviceID, context, queue, async_strided_global_to_local_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
@ -21,143 +21,136 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <algorithm>
#include <numeric>
#include <vector>
#include "procs.h"
const char *barrier_kernel_code =
"__kernel void compute_sum(__global int *a, int n, __global int *tmp_sum, __global int *sum)\n"
"{\n"
" int tid = get_local_id(0);\n"
" int lsize = get_local_size(0);\n"
" int i;\n"
"\n"
" tmp_sum[tid] = 0;\n"
" for (i=tid; i<n; i+=lsize)\n"
" tmp_sum[tid] += a[i];\n"
" \n"
" // updated to work for any workgroup size \n"
" for (i=hadd(lsize,1); lsize>1; i = hadd(i,1))\n"
" {\n"
" barrier(CLK_GLOBAL_MEM_FENCE);\n"
" if (tid + i < lsize)\n"
" tmp_sum[tid] += tmp_sum[tid + i];\n"
" lsize = i; \n"
" }\n"
"\n"
" //no barrier is required here because last person to write to tmp_sum[0] was tid 0 \n"
" if (tid == 0)\n"
" *sum = tmp_sum[0];\n"
"}\n";
static int
verify_sum(int *inptr, int *outptr, int n)
namespace {
const char *barrier_kernel_code = R"(
__kernel void compute_sum(__global int *a, int n, __global int *tmp_sum,
__global int *sum)
{
int r = 0;
int i;
int tid = get_local_id(0);
int lsize = get_local_size(0);
int i;
for (i=0; i<n; i++)
{
r += inptr[i];
}
tmp_sum[tid] = 0;
for (i = tid; i < n; i += lsize) tmp_sum[tid] += a[i];
if (r != outptr[0])
// updated to work for any workgroup size
for (i = hadd(lsize, 1); lsize > 1; i = hadd(i, 1))
{
log_error("BARRIER test failed\n");
return -1;
BARRIER(CLK_GLOBAL_MEM_FENCE);
if (tid + i < lsize) tmp_sum[tid] += tmp_sum[tid + i];
lsize = i;
}
log_info("BARRIER test passed\n");
return 0;
// no barrier is required here because last person to write to tmp_sum[0]
// was tid 0
if (tid == 0) *sum = tmp_sum[0];
}
)";
void generate_random_inputs(std::vector<cl_int> &v)
{
RandomSeed seed(gRandomSeed);
auto random_generator = [&seed]() {
return static_cast<cl_int>(
get_random_float(-0x01000000, 0x01000000, seed));
};
std::generate(v.begin(), v.end(), random_generator);
}
int
test_barrier(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
int test_barrier_common(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements,
std::string barrier_str)
{
cl_mem streams[3];
cl_int *input_ptr = NULL, *output_ptr = NULL;
cl_program program;
cl_kernel kernel;
size_t global_threads[3];
size_t local_threads[3];
int err;
int i;
size_t max_local_workgroup_size[3];
size_t max_threadgroup_size = 0;
MTdata d;
clMemWrapper streams[3];
clProgramWrapper program;
clKernelWrapper kernel;
err = create_single_kernel_helper(context, &program, &kernel, 1, &barrier_kernel_code, "compute_sum" );
cl_int output;
int err;
size_t max_threadgroup_size = 0;
std::string build_options = std::string("-DBARRIER=") + barrier_str;
err = create_single_kernel_helper(context, &program, &kernel, 1,
&barrier_kernel_code, "compute_sum",
build_options.c_str());
test_error(err, "Failed to build kernel/program.");
err = clGetKernelWorkGroupInfo(kernel, device, CL_KERNEL_WORK_GROUP_SIZE,
sizeof(max_threadgroup_size), &max_threadgroup_size, NULL);
test_error(err, "clGetKernelWorkgroupInfo failed.");
err = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(max_local_workgroup_size), max_local_workgroup_size, NULL);
test_error(err, "clGetDeviceInfo failed for CL_DEVICE_MAX_WORK_ITEM_SIZES");
// Pick the minimum of the device and the kernel
if (max_threadgroup_size > max_local_workgroup_size[0])
max_threadgroup_size = max_local_workgroup_size[0];
err = get_max_allowed_1d_work_group_size_on_device(device, kernel,
&max_threadgroup_size);
test_error(err, "get_max_allowed_1d_work_group_size_on_device failed.");
// work group size must divide evenly into the global size
while( num_elements % max_threadgroup_size )
max_threadgroup_size--;
while (num_elements % max_threadgroup_size) max_threadgroup_size--;
input_ptr = (int*)malloc(sizeof(int) * num_elements);
output_ptr = (int*)malloc(sizeof(int));
std::vector<cl_int> input(num_elements);
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * num_elements, NULL, &err);
sizeof(cl_int) * num_elements, nullptr, &err);
test_error(err, "clCreateBuffer failed.");
streams[1] =
clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int), NULL, &err);
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_int),
nullptr, &err);
test_error(err, "clCreateBuffer failed.");
streams[2] =
clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * max_threadgroup_size, NULL, &err);
sizeof(cl_int) * max_threadgroup_size, nullptr, &err);
test_error(err, "clCreateBuffer failed.");
d = init_genrand( gRandomSeed );
for (i=0; i<num_elements; i++)
input_ptr[i] = (int)get_random_float(-0x01000000, 0x01000000, d);
free_mtdata(d); d = NULL;
generate_random_inputs(input);
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, sizeof(cl_int)*num_elements, (void *)input_ptr, 0, NULL, NULL);
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0,
sizeof(cl_int) * num_elements, input.data(), 0,
nullptr, nullptr);
test_error(err, "clEnqueueWriteBuffer failed.");
err = clSetKernelArg(kernel, 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel, 1, sizeof num_elements, &num_elements);
err |= clSetKernelArg(kernel, 2, sizeof streams[2], &streams[2]);
err |= clSetKernelArg(kernel, 3, sizeof streams[1], &streams[1]);
err = clSetKernelArg(kernel, 0, sizeof(streams[0]), &streams[0]);
err |= clSetKernelArg(kernel, 1, sizeof(num_elements), &num_elements);
err |= clSetKernelArg(kernel, 2, sizeof(streams[2]), &streams[2]);
err |= clSetKernelArg(kernel, 3, sizeof(streams[1]), &streams[1]);
test_error(err, "clSetKernelArg failed.");
global_threads[0] = max_threadgroup_size;
local_threads[0] = max_threadgroup_size;
size_t global_threads[] = { max_threadgroup_size };
size_t local_threads[] = { max_threadgroup_size };
err = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, global_threads, local_threads, 0, NULL, NULL );
err = clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, global_threads,
local_threads, 0, nullptr, nullptr);
test_error(err, "clEnqueueNDRangeKernel failed.");
err = clEnqueueReadBuffer( queue, streams[1], true, 0, sizeof(cl_int), (void *)output_ptr, 0, NULL, NULL );
err = clEnqueueReadBuffer(queue, streams[1], true, 0, sizeof(cl_int),
&output, 0, nullptr, nullptr);
test_error(err, "clEnqueueReadBuffer failed.");
err = verify_sum(input_ptr, output_ptr, num_elements);
// cleanup
clReleaseMemObject(streams[0]);
clReleaseMemObject(streams[1]);
clReleaseMemObject(streams[2]);
clReleaseKernel(kernel);
clReleaseProgram(program);
free(input_ptr);
free(output_ptr);
if (std::accumulate(input.begin(), input.end(), 0) != output)
{
log_error("%s test failed\n", barrier_str.c_str());
err = -1;
}
else
{
log_info("%s test passed\n", barrier_str.c_str());
}
return err;
}
}
int test_barrier(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return test_barrier_common(device, context, queue, num_elements, "barrier");
}
int test_wg_barrier(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
return test_barrier_common(device, context, queue, num_elements,
"work_group_barrier");
}

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
@ -21,41 +21,44 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <algorithm>
#include <vector>
#include "procs.h"
const char *constant_kernel_code =
"__kernel void constant_kernel(__global float *out, __constant float *tmpF, __constant int *tmpI)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" float ftmp = tmpF[tid]; \n"
" float Itmp = tmpI[tid]; \n"
" out[tid] = ftmp * Itmp; \n"
"}\n";
const char *loop_constant_kernel_code =
"kernel void loop_constant_kernel(global float *out, constant float *i_pos, int num)\n"
"{\n"
" int tid = get_global_id(0);\n"
" float sum = 0;\n"
" for (int i = 0; i < num; i++) {\n"
" float pos = i_pos[i*3];\n"
" sum += pos;\n"
" }\n"
" out[tid] = sum;\n"
"}\n";
static int
verify(cl_float *tmpF, cl_int *tmpI, cl_float *out, int n)
namespace {
const char* constant_kernel_code = R"(
__kernel void constant_kernel(__global float *out, __constant float *tmpF, __constant int *tmpI)
{
int i;
int tid = get_global_id(0);
for (i=0; i < n; i++)
float ftmp = tmpF[tid];
float Itmp = tmpI[tid];
out[tid] = ftmp * Itmp;
}
)";
const char* loop_constant_kernel_code = R"(
kernel void loop_constant_kernel(global float *out, constant float *i_pos, int num)
{
int tid = get_global_id(0);
float sum = 0;
for (int i = 0; i < num; i++) {
float pos = i_pos[i*3];
sum += pos;
}
out[tid] = sum;
}
)";
int verify(std::vector<cl_float>& tmpF, std::vector<cl_int>& tmpI,
std::vector<cl_float>& out)
{
for (int i = 0; i < out.size(); i++)
{
float f = tmpF[i] * tmpI[i];
if( out[i] != f )
if (out[i] != f)
{
log_error("CONSTANT test failed\n");
return -1;
@ -66,214 +69,172 @@ verify(cl_float *tmpF, cl_int *tmpI, cl_float *out, int n)
return 0;
}
static int
verify_loop_constant(const cl_float *tmp, cl_float *out, cl_int l, int n)
int verify_loop_constant(const std::vector<cl_float>& tmp,
std::vector<cl_float>& out, cl_int l)
{
int i;
cl_int j;
for (i=0; i < n; i++)
{
float sum = 0;
for (j=0; j < l; ++j)
sum += tmp[j*3];
float sum = 0;
for (int j = 0; j < l; ++j) sum += tmp[j * 3];
if( out[i] != sum )
{
log_error("loop CONSTANT test failed\n");
return -1;
}
auto predicate = [&sum](cl_float elem) { return sum != elem; };
if (std::any_of(out.cbegin(), out.cend(), predicate))
{
log_error("loop CONSTANT test failed\n");
return -1;
}
log_info("loop CONSTANT test passed\n");
return 0;
}
int
test_constant(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
template <typename T> void generate_random_inputs(std::vector<T>& v)
{
cl_mem streams[3];
cl_int *tmpI;
cl_float *tmpF, *out;
cl_program program;
cl_kernel kernel;
size_t global_threads[3];
int err;
unsigned int i;
RandomSeed seed(gRandomSeed);
auto random_generator = [&seed]() {
return static_cast<T>(get_random_float(-0x02000000, 0x02000000, seed));
};
std::generate(v.begin(), v.end(), random_generator);
}
}
int test_constant(cl_device_id device, cl_context context,
cl_command_queue queue, int num_elements)
{
clMemWrapper streams[3];
clProgramWrapper program;
clKernelWrapper kernel;
size_t global_threads[3];
int err;
cl_ulong maxSize, maxGlobalSize, maxAllocSize;
size_t num_floats, num_ints, constant_values;
MTdata d;
RoundingMode oldRoundMode;
RoundingMode oldRoundMode;
int isRTZ = 0;
/* Verify our test buffer won't be bigger than allowed */
err = clGetDeviceInfo( device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( maxSize ), &maxSize, 0 );
test_error( err, "Unable to get max constant buffer size" );
/* Verify our test buffer won't be bigger than allowed */
err = clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
sizeof(maxSize), &maxSize, 0);
test_error(err, "Unable to get max constant buffer size");
log_info("Device reports CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE %llu bytes.\n",
maxSize);
log_info("Device reports CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE %llu bytes.\n", maxSize);
// Limit test buffer size to 1/4 of CL_DEVICE_GLOBAL_MEM_SIZE
err = clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(maxGlobalSize), &maxGlobalSize, 0);
test_error(err, "Unable to get CL_DEVICE_GLOBAL_MEM_SIZE");
// Limit test buffer size to 1/4 of CL_DEVICE_GLOBAL_MEM_SIZE
err = clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE,
sizeof(maxGlobalSize), &maxGlobalSize, 0);
test_error(err, "Unable to get CL_DEVICE_GLOBAL_MEM_SIZE");
if (maxSize > maxGlobalSize / 4)
maxSize = maxGlobalSize / 4;
maxSize = std::min(maxSize, maxGlobalSize / 4);
err = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE , sizeof(maxAllocSize), &maxAllocSize, 0);
test_error(err, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE ");
err = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
sizeof(maxAllocSize), &maxAllocSize, 0);
test_error(err, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE");
if (maxSize > maxAllocSize)
maxSize = maxAllocSize;
maxSize/=4;
num_ints = (size_t)maxSize/sizeof(cl_int);
num_floats = (size_t)maxSize/sizeof(cl_float);
if (num_ints >= num_floats) {
constant_values = num_floats;
} else {
constant_values = num_ints;
}
maxSize = std::min(maxSize, maxAllocSize);
log_info("Test will attempt to use %lu bytes with one %lu byte constant int buffer and one %lu byte constant float buffer.\n",
constant_values*sizeof(cl_int) + constant_values*sizeof(cl_float), constant_values*sizeof(cl_int), constant_values*sizeof(cl_float));
maxSize /= 4;
num_ints = static_cast<size_t>(maxSize / sizeof(cl_int));
num_floats = static_cast<size_t>(maxSize / sizeof(cl_float));
constant_values = std::min(num_floats, num_ints);
tmpI = (cl_int*)malloc(sizeof(cl_int) * constant_values);
tmpF = (cl_float*)malloc(sizeof(cl_float) * constant_values);
out = (cl_float*)malloc(sizeof(cl_float) * constant_values);
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_float) * constant_values, NULL, NULL);
if (!streams[0])
{
log_error("clCreateBuffer failed\n");
return -1;
}
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_float) * constant_values, NULL, NULL);
if (!streams[1])
{
log_error("clCreateBuffer failed\n");
return -1;
}
streams[2] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * constant_values, NULL, NULL);
if (!streams[2])
{
log_error("clCreateBuffer failed\n");
return -1;
}
d = init_genrand( gRandomSeed );
for (i=0; i<constant_values; i++) {
tmpI[i] = (int)get_random_float(-0x02000000, 0x02000000, d);
tmpF[i] = get_random_float(-0x02000000, 0x02000000, d);
}
free_mtdata(d); d = NULL;
log_info(
"Test will attempt to use %lu bytes with one %lu byte constant int "
"buffer and one %lu byte constant float buffer.\n",
constant_values * sizeof(cl_int) + constant_values * sizeof(cl_float),
constant_values * sizeof(cl_int), constant_values * sizeof(cl_float));
err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0, sizeof(cl_float)*constant_values, (void *)tmpF, 0, NULL, NULL);
if (err != CL_SUCCESS)
{
log_error("clWriteArray failed\n");
return -1;
}
err = clEnqueueWriteBuffer(queue, streams[2], CL_TRUE, 0, sizeof(cl_int)*constant_values, (void *)tmpI, 0, NULL, NULL);
if (err != CL_SUCCESS)
{
log_error("clWriteArray failed\n");
return -1;
}
std::vector<cl_int> tmpI(constant_values);
std::vector<cl_float> tmpF(constant_values);
std::vector<cl_float> out(constant_values);
err = create_single_kernel_helper(context, &program, &kernel, 1, &constant_kernel_code, "constant_kernel" );
if (err) {
log_error("Failed to create kernel and program: %d\n", err);
return -1;
}
streams[0] =
clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_float) * constant_values, nullptr, &err);
test_error(err, "clCreateBuffer failed");
streams[1] =
clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_float) * constant_values, nullptr, &err);
test_error(err, "clCreateBuffer failed");
streams[2] =
clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * constant_values, nullptr, &err);
test_error(err, "clCreateBuffer failed");
generate_random_inputs(tmpI);
generate_random_inputs(tmpF);
err = clEnqueueWriteBuffer(queue, streams[1], CL_TRUE, 0,
sizeof(cl_float) * constant_values, tmpF.data(),
0, nullptr, nullptr);
test_error(err, "clEnqueueWriteBuffer failed");
err = clEnqueueWriteBuffer(queue, streams[2], CL_TRUE, 0,
sizeof(cl_int) * constant_values, tmpI.data(), 0,
nullptr, nullptr);
test_error(err, "clEnqueueWriteBuffer faile.");
err = create_single_kernel_helper(context, &program, &kernel, 1,
&constant_kernel_code, "constant_kernel");
test_error(err, "Failed to create kernel and program");
err = clSetKernelArg(kernel, 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(kernel, 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(kernel, 2, sizeof streams[2], &streams[2]);
if (err != CL_SUCCESS)
{
log_error("clSetKernelArgs failed\n");
return -1;
}
test_error(err, "clSetKernelArgs failed");
global_threads[0] = constant_values;
err = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, global_threads, NULL, 0, NULL, NULL );
if (err != CL_SUCCESS)
{
log_error("clEnqueueNDRangeKernel failed: %d\n", err);
return -1;
}
err = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*constant_values, (void *)out, 0, NULL, NULL );
if (err != CL_SUCCESS)
{
log_error("clEnqueueReadBuffer failed\n");
return -1;
}
err = clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, global_threads,
nullptr, 0, nullptr, nullptr);
test_error(err, "clEnqueueNDRangeKernel failed");
//If we only support rtz mode
if( CL_FP_ROUND_TO_ZERO == get_default_rounding_mode(device) && gIsEmbedded)
err = clEnqueueReadBuffer(queue, streams[0], CL_TRUE, 0,
sizeof(cl_float) * constant_values, out.data(), 0,
nullptr, nullptr);
test_error(err, "clEnqueueReadBuffer failed");
// If we only support rtz mode
if (CL_FP_ROUND_TO_ZERO == get_default_rounding_mode(device) && gIsEmbedded)
{
oldRoundMode = set_round(kRoundTowardZero, kfloat);
isRTZ = 1;
}
err = verify(tmpF, tmpI, out, (int)constant_values);
err = verify(tmpF, tmpI, out);
if (isRTZ)
(void)set_round(oldRoundMode, kfloat);
if (isRTZ) (void)set_round(oldRoundMode, kfloat);
// Loop constant buffer test
cl_program loop_program;
cl_kernel loop_kernel;
clProgramWrapper loop_program;
clKernelWrapper loop_kernel;
cl_int limit = 2;
memset(out, 0, sizeof(cl_float) * constant_values);
memset(out.data(), 0, sizeof(cl_float) * constant_values);
err = create_single_kernel_helper(context, &loop_program, &loop_kernel, 1,
&loop_constant_kernel_code, "loop_constant_kernel" );
if (err) {
log_error("Failed to create loop kernel and program: %d\n", err);
return -1;
}
&loop_constant_kernel_code,
"loop_constant_kernel");
test_error(err, "Failed to create kernel and program");
err = clSetKernelArg(loop_kernel, 0, sizeof streams[0], &streams[0]);
err |= clSetKernelArg(loop_kernel, 1, sizeof streams[1], &streams[1]);
err |= clSetKernelArg(loop_kernel, 2, sizeof(limit), &limit);
if (err != CL_SUCCESS) {
log_error("clSetKernelArgs for loop kernel failed\n");
return -1;
}
test_error(err, "clSetKernelArgs failed");
err = clEnqueueNDRangeKernel( queue, loop_kernel, 1, NULL, global_threads, NULL, 0, NULL, NULL );
if (err != CL_SUCCESS) {
log_error("clEnqueueNDRangeKernel failed: %d\n", err);
return -1;
}
err = clEnqueueReadBuffer( queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*constant_values, (void *)out, 0, NULL, NULL );
if (err != CL_SUCCESS) {
log_error("clEnqueueReadBuffer failed\n");
return -1;
}
err = clEnqueueNDRangeKernel(queue, loop_kernel, 1, nullptr, global_threads,
nullptr, 0, nullptr, nullptr);
test_error(err, "clEnqueueNDRangeKernel failed");
err = verify_loop_constant(tmpF, out, limit, (int)constant_values);
err = clEnqueueReadBuffer(queue, streams[0], CL_TRUE, 0,
sizeof(cl_float) * constant_values, out.data(), 0,
nullptr, nullptr);
test_error(err, "clEnqueueReadBuffer failed");
err = verify_loop_constant(tmpF, out, limit);
// cleanup
clReleaseMemObject(streams[0]);
clReleaseMemObject(streams[1]);
clReleaseMemObject(streams[2]);
clReleaseKernel(kernel);
clReleaseProgram(program);
clReleaseKernel(loop_kernel);
clReleaseProgram(loop_program);
free(tmpI);
free(tmpF);
free(out);
return err;
}

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,7 @@
#include "harness/conversions.h"
#include "harness/typeWrappers.h"
// clang-format off
const cl_mem_flags flag_set[] = {
CL_MEM_ALLOC_HOST_PTR,
CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR,
@ -33,93 +34,105 @@ const cl_mem_flags flag_set[] = {
CL_MEM_COPY_HOST_PTR,
0
};
const char* flag_set_names[] = {
const char *flag_set_names[] = {
"CL_MEM_ALLOC_HOST_PTR",
"CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR",
"CL_MEM_USE_HOST_PTR",
"CL_MEM_COPY_HOST_PTR",
"0"
};
// clang-format on
int test_enqueue_map_buffer(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
int test_enqueue_map_buffer(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
int error;
const size_t bufferSize = 256*256;
MTdataHolder d{gRandomSeed};
const size_t bufferSize = 256 * 256;
MTdataHolder d{ gRandomSeed };
BufferOwningPtr<cl_char> hostPtrData{ malloc(bufferSize) };
BufferOwningPtr<cl_char> referenceData{ malloc(bufferSize) };
BufferOwningPtr<cl_char> finalData{malloc(bufferSize)};
BufferOwningPtr<cl_char> finalData{ malloc(bufferSize) };
for (int src_flag_id=0; src_flag_id < ARRAY_SIZE(flag_set); src_flag_id++)
for (size_t src_flag_id = 0; src_flag_id < ARRAY_SIZE(flag_set);
src_flag_id++)
{
clMemWrapper memObject;
log_info("Testing with cl_mem_flags src: %s\n", flag_set_names[src_flag_id]);
log_info("Testing with cl_mem_flags src: %s\n",
flag_set_names[src_flag_id]);
generate_random_data(kChar, (unsigned int)bufferSize, d, hostPtrData);
memcpy(referenceData, hostPtrData, bufferSize);
void *hostPtr = nullptr;
cl_mem_flags flags = flag_set[src_flag_id];
bool hasHostPtr = (flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
bool hasHostPtr =
(flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
if (hasHostPtr) hostPtr = hostPtrData;
memObject = clCreateBuffer(context, flags, bufferSize, hostPtr, &error);
test_error( error, "Unable to create testing buffer" );
memObject = clCreateBuffer(context, flags, bufferSize, hostPtr, &error);
test_error(error, "Unable to create testing buffer");
if (!hasHostPtr)
{
error =
clEnqueueWriteBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
hostPtrData, 0, NULL, NULL);
test_error( error, "clEnqueueWriteBuffer failed");
clEnqueueWriteBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
hostPtrData, 0, NULL, NULL);
test_error(error, "clEnqueueWriteBuffer failed");
}
for( int i = 0; i < 128; i++ )
for (int i = 0; i < 128; i++)
{
size_t offset = (size_t)random_in_range( 0, (int)bufferSize - 1, d );
size_t length = (size_t)random_in_range( 1, (int)( bufferSize - offset ), d );
size_t offset = (size_t)random_in_range(0, (int)bufferSize - 1, d);
size_t length =
(size_t)random_in_range(1, (int)(bufferSize - offset), d);
cl_char *mappedRegion = (cl_char *)clEnqueueMapBuffer( queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE,
offset, length, 0, NULL, NULL, &error );
if( error != CL_SUCCESS )
{
print_error( error, "clEnqueueMapBuffer call failed" );
log_error( "\tOffset: %d Length: %d\n", (int)offset, (int)length );
return -1;
}
cl_char *mappedRegion = (cl_char *)clEnqueueMapBuffer(
queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
length, 0, NULL, NULL, &error);
if (error != CL_SUCCESS)
{
print_error(error, "clEnqueueMapBuffer call failed");
log_error("\tOffset: %d Length: %d\n", (int)offset,
(int)length);
return -1;
}
// Write into the region
for( size_t j = 0; j < length; j++ )
{
cl_char spin = (cl_char)genrand_int32( d );
// Write into the region
for (size_t j = 0; j < length; j++)
{
cl_char spin = (cl_char)genrand_int32(d);
// Test read AND write in one swipe
cl_char value = mappedRegion[ j ];
value = spin - value;
mappedRegion[ j ] = value;
// Test read AND write in one swipe
cl_char value = mappedRegion[j];
value = spin - value;
mappedRegion[j] = value;
// Also update the initial data array
value = referenceData[offset + j];
value = spin - value;
referenceData[offset + j] = value;
}
// Also update the initial data array
value = referenceData[offset + j];
value = spin - value;
referenceData[offset + j] = value;
}
// Unmap
error = clEnqueueUnmapMemObject( queue, memObject, mappedRegion, 0, NULL, NULL );
test_error( error, "Unable to unmap buffer" );
// Unmap
error = clEnqueueUnmapMemObject(queue, memObject, mappedRegion, 0,
NULL, NULL);
test_error(error, "Unable to unmap buffer");
}
// Final validation: read actual values of buffer and compare against our reference
error = clEnqueueReadBuffer( queue, memObject, CL_TRUE, 0, bufferSize, finalData, 0, NULL, NULL );
test_error( error, "Unable to read results" );
// Final validation: read actual values of buffer and compare against
// our reference
error = clEnqueueReadBuffer(queue, memObject, CL_TRUE, 0, bufferSize,
finalData, 0, NULL, NULL);
test_error(error, "Unable to read results");
for( size_t q = 0; q < bufferSize; q++ )
for (size_t q = 0; q < bufferSize; q++)
{
if (referenceData[q] != finalData[q])
{
log_error(
"ERROR: Sample %d did not validate! Got %d, expected %d\n",
(int)q, (int)finalData[q], (int)referenceData[q]);
"ERROR: Sample %d did not validate! Got %d, expected %d\n",
(int)q, (int)finalData[q], (int)referenceData[q]);
return -1;
}
}
@ -128,112 +141,129 @@ int test_enqueue_map_buffer(cl_device_id deviceID, cl_context context, cl_comman
return 0;
}
int test_enqueue_map_image(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
int test_enqueue_map_image(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
int error;
cl_image_format format = { CL_RGBA, CL_UNSIGNED_INT32 };
const size_t imageSize = 256;
const size_t imageDataSize = imageSize * imageSize * 4 * sizeof(cl_uint);
PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID )
PASSIVE_REQUIRE_IMAGE_SUPPORT(deviceID)
BufferOwningPtr<cl_uint> hostPtrData{ malloc(imageDataSize) };
BufferOwningPtr<cl_uint> referenceData{ malloc(imageDataSize) };
BufferOwningPtr<cl_uint> finalData{malloc(imageDataSize)};
BufferOwningPtr<cl_uint> finalData{ malloc(imageDataSize) };
MTdataHolder d{gRandomSeed};
for (int src_flag_id=0; src_flag_id < ARRAY_SIZE(flag_set); src_flag_id++) {
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,
hostPtrData);
memcpy(referenceData, hostPtrData, imageDataSize);
cl_mem_flags flags = flag_set[src_flag_id];
bool hasHostPtr = (flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
void *hostPtr = nullptr;
if (hasHostPtr) hostPtr = hostPtrData;
memObject = create_image_2d(context, CL_MEM_READ_WRITE | flags, &format,
imageSize, imageSize, 0, hostPtr, &error );
test_error( error, "Unable to create testing buffer" );
if (!hasHostPtr) {
size_t write_origin[3]={0,0,0}, write_region[3]={imageSize, imageSize, 1};
error =
clEnqueueWriteImage(queue, memObject, CL_TRUE, write_origin, write_region,
0, 0, hostPtrData, 0, NULL, NULL);
test_error( error, "Unable to write to testing buffer" );
}
for( int i = 0; i < 128; i++ )
MTdataHolder d{ gRandomSeed };
for (size_t src_flag_id = 0; src_flag_id < ARRAY_SIZE(flag_set);
src_flag_id++)
{
clMemWrapper memObject;
log_info("Testing with cl_mem_flags src: %s\n",
flag_set_names[src_flag_id]);
size_t offset[3], region[3];
size_t rowPitch;
generate_random_data(kUInt, (unsigned int)(imageSize * imageSize * 4),
d, hostPtrData);
memcpy(referenceData, hostPtrData, imageDataSize);
offset[ 0 ] = (size_t)random_in_range( 0, (int)imageSize - 1, d );
region[ 0 ] = (size_t)random_in_range( 1, (int)( imageSize - offset[ 0 ] - 1), d );
offset[ 1 ] = (size_t)random_in_range( 0, (int)imageSize - 1, d );
region[ 1 ] = (size_t)random_in_range( 1, (int)( imageSize - offset[ 1 ] - 1), d );
offset[ 2 ] = 0;
region[ 2 ] = 1;
cl_uint *mappedRegion = (cl_uint *)clEnqueueMapImage( queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE,
offset, region, &rowPitch, NULL, 0, NULL, NULL, &error );
if( error != CL_SUCCESS )
{
print_error( error, "clEnqueueMapImage call failed" );
log_error( "\tOffset: %d,%d Region: %d,%d\n", (int)offset[0], (int)offset[1], (int)region[0], (int)region[1] );
return -1;
}
cl_mem_flags flags = flag_set[src_flag_id];
bool hasHostPtr =
(flags & CL_MEM_USE_HOST_PTR) || (flags & CL_MEM_COPY_HOST_PTR);
void *hostPtr = nullptr;
if (hasHostPtr) hostPtr = hostPtrData;
memObject = create_image_2d(context, CL_MEM_READ_WRITE | flags, &format,
imageSize, imageSize, 0, hostPtr, &error);
test_error(error, "Unable to create testing buffer");
// Write into the region
cl_uint *mappedPtr = mappedRegion;
for( size_t y = 0; y < region[ 1 ]; y++ )
{
for( size_t x = 0; x < region[ 0 ] * 4; x++ )
if (!hasHostPtr)
{
cl_int spin = (cl_int)random_in_range( 16, 1024, d );
cl_int value;
// Test read AND write in one swipe
value = mappedPtr[ ( y * rowPitch/sizeof(cl_uint) ) + x ];
value = spin - value;
mappedPtr[ ( y * rowPitch/sizeof(cl_uint) ) + x ] = value;
// Also update the initial data array
value =
referenceData[((offset[1] + y) * imageSize + offset[0]) * 4 + x];
value = spin - value;
referenceData[((offset[1] + y) * imageSize + offset[0]) * 4 + x] =
value;
size_t write_origin[3] = { 0, 0, 0 },
write_region[3] = { imageSize, imageSize, 1 };
error = clEnqueueWriteImage(queue, memObject, CL_TRUE, write_origin,
write_region, 0, 0, hostPtrData, 0,
NULL, NULL);
test_error(error, "Unable to write to testing buffer");
}
}
// Unmap
error = clEnqueueUnmapMemObject( queue, memObject, mappedRegion, 0, NULL, NULL );
test_error( error, "Unable to unmap buffer" );
}
// Final validation: read actual values of buffer and compare against our reference
size_t finalOrigin[3] = { 0, 0, 0 }, finalRegion[3] = { imageSize, imageSize, 1 };
error = clEnqueueReadImage( queue, memObject, CL_TRUE, finalOrigin, finalRegion, 0, 0, finalData, 0, NULL, NULL );
test_error( error, "Unable to read results" );
for( size_t q = 0; q < imageSize * imageSize * 4; q++ )
{
if (referenceData[q] != finalData[q])
for (int i = 0; i < 128; i++)
{
log_error("ERROR: Sample %d (coord %d,%d) did not validate! Got "
"%d, expected %d\n",
(int)q, (int)((q / 4) % imageSize),
(int)((q / 4) / imageSize), (int)finalData[q],
(int)referenceData[q]);
return -1;
size_t offset[3], region[3];
size_t rowPitch;
offset[0] = (size_t)random_in_range(0, (int)imageSize - 1, d);
region[0] =
(size_t)random_in_range(1, (int)(imageSize - offset[0] - 1), d);
offset[1] = (size_t)random_in_range(0, (int)imageSize - 1, d);
region[1] =
(size_t)random_in_range(1, (int)(imageSize - offset[1] - 1), d);
offset[2] = 0;
region[2] = 1;
cl_uint *mappedRegion = (cl_uint *)clEnqueueMapImage(
queue, memObject, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, offset,
region, &rowPitch, NULL, 0, NULL, NULL, &error);
if (error != CL_SUCCESS)
{
print_error(error, "clEnqueueMapImage call failed");
log_error("\tOffset: %d,%d Region: %d,%d\n", (int)offset[0],
(int)offset[1], (int)region[0], (int)region[1]);
return -1;
}
// Write into the region
cl_uint *mappedPtr = mappedRegion;
for (size_t y = 0; y < region[1]; y++)
{
for (size_t x = 0; x < region[0] * 4; x++)
{
cl_int spin = (cl_int)random_in_range(16, 1024, d);
cl_int value;
// Test read AND write in one swipe
value = mappedPtr[(y * rowPitch / sizeof(cl_uint)) + x];
value = spin - value;
mappedPtr[(y * rowPitch / sizeof(cl_uint)) + x] = value;
// Also update the initial data array
value =
referenceData[((offset[1] + y) * imageSize + offset[0])
* 4
+ x];
value = spin - value;
referenceData[((offset[1] + y) * imageSize + offset[0]) * 4
+ x] = value;
}
}
// Unmap
error = clEnqueueUnmapMemObject(queue, memObject, mappedRegion, 0,
NULL, NULL);
test_error(error, "Unable to unmap buffer");
}
}
} // cl_mem_flags
// Final validation: read actual values of buffer and compare against
// our reference
size_t finalOrigin[3] = { 0, 0, 0 },
finalRegion[3] = { imageSize, imageSize, 1 };
error = clEnqueueReadImage(queue, memObject, CL_TRUE, finalOrigin,
finalRegion, 0, 0, finalData, 0, NULL, NULL);
test_error(error, "Unable to read results");
for (size_t q = 0; q < imageSize * imageSize * 4; q++)
{
if (referenceData[q] != finalData[q])
{
log_error(
"ERROR: Sample %d (coord %d,%d) did not validate! Got "
"%d, expected %d\n",
(int)q, (int)((q / 4) % imageSize),
(int)((q / 4) / imageSize), (int)finalData[q],
(int)referenceData[q]);
return -1;
}
}
} // cl_mem_flags
return 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
@ -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

@ -1,6 +1,6 @@
//
// Copyright (c) 2017 The Khronos Group Inc.
//
// Copyright (c) 2023 The Khronos Group Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@ -13,6 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <cmath>
using std::isnan;
#include "harness/compat.h"
#include <stdio.h>
@ -20,131 +22,112 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <vector>
#include "procs.h"
#include "harness/conversions.h"
#include "harness/typeWrappers.h"
namespace {
// clang-format off
#define DECLARE_S2V_IDENT_KERNEL(srctype,dsttype,size) \
"__kernel void test_conversion(__global " srctype " *sourceValues, __global " dsttype #size " *destValues )\n" \
"{\n" \
" int tid = get_global_id(0);\n" \
" " srctype " src = sourceValues[tid];\n" \
"\n" \
" destValues[tid] = (" dsttype #size ")src;\n" \
"\n" \
"{\n" \
" int tid = get_global_id(0);\n" \
" " srctype " src = sourceValues[tid];\n" \
"\n" \
" destValues[tid] = (" dsttype #size ")src;\n" \
"\n" \
"}\n"
#define DECLARE_S2V_IDENT_KERNELS(srctype,dsttype) \
{ \
DECLARE_S2V_IDENT_KERNEL(srctype,#dsttype,2), \
DECLARE_S2V_IDENT_KERNEL(srctype,#dsttype,4), \
DECLARE_S2V_IDENT_KERNEL(srctype,#dsttype,8), \
DECLARE_S2V_IDENT_KERNEL(srctype,#dsttype,16) \
}
#define DECLARE_S2V_IDENT_KERNELS(srctype, dsttype) \
{ \
DECLARE_S2V_IDENT_KERNEL(srctype, #dsttype, 2), \
DECLARE_S2V_IDENT_KERNEL(srctype, #dsttype, 4), \
DECLARE_S2V_IDENT_KERNEL(srctype, #dsttype, 8), \
DECLARE_S2V_IDENT_KERNEL(srctype, #dsttype, 16) \
}
#define DECLARE_EMPTY { NULL, NULL, NULL, NULL, NULL }
#define DECLARE_EMPTY \
{ \
NULL, NULL, NULL, NULL, NULL \
}
/* Note: the next four arrays all must match in order and size to the ExplicitTypes enum in conversions.h!!! */
/* Note: the next four arrays all must match in order and size to the
* ExplicitTypes enum in conversions.h!!! */
#define DECLARE_S2V_IDENT_KERNELS_SET(srctype) \
{ \
DECLARE_S2V_IDENT_KERNELS(#srctype,bool), \
DECLARE_S2V_IDENT_KERNELS(#srctype,char), \
DECLARE_S2V_IDENT_KERNELS(#srctype,uchar), \
DECLARE_S2V_IDENT_KERNELS(#srctype,unsigned char), \
DECLARE_S2V_IDENT_KERNELS(#srctype,short), \
DECLARE_S2V_IDENT_KERNELS(#srctype,ushort), \
DECLARE_S2V_IDENT_KERNELS(#srctype,unsigned short), \
DECLARE_S2V_IDENT_KERNELS(#srctype,int), \
DECLARE_S2V_IDENT_KERNELS(#srctype,uint), \
DECLARE_S2V_IDENT_KERNELS(#srctype,unsigned int), \
DECLARE_S2V_IDENT_KERNELS(#srctype,long), \
DECLARE_S2V_IDENT_KERNELS(#srctype,ulong), \
DECLARE_S2V_IDENT_KERNELS(#srctype,unsigned long), \
DECLARE_S2V_IDENT_KERNELS(#srctype,float), \
DECLARE_EMPTY \
}
#define DECLARE_S2V_IDENT_KERNELS_SET(srctype) \
{ \
DECLARE_S2V_IDENT_KERNELS(#srctype, char), \
DECLARE_S2V_IDENT_KERNELS(#srctype, uchar), \
DECLARE_S2V_IDENT_KERNELS(#srctype, short), \
DECLARE_S2V_IDENT_KERNELS(#srctype, ushort), \
DECLARE_S2V_IDENT_KERNELS(#srctype, int), \
DECLARE_S2V_IDENT_KERNELS(#srctype, uint), \
DECLARE_S2V_IDENT_KERNELS(#srctype, long), \
DECLARE_S2V_IDENT_KERNELS(#srctype, ulong), \
DECLARE_S2V_IDENT_KERNELS(#srctype, float), \
DECLARE_S2V_IDENT_KERNELS(#srctype, half), \
DECLARE_S2V_IDENT_KERNELS(#srctype, double) \
}
#define DECLARE_EMPTY_SET \
{ \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY, \
DECLARE_EMPTY \
}
#define DECLARE_EMPTY_SET \
{ \
DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY, \
DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY, \
DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY, \
DECLARE_EMPTY, DECLARE_EMPTY, DECLARE_EMPTY \
}
#define NUM_VEC_TYPES 11
/* The overall array */
const char * kernel_explicit_s2v_set[kNumExplicitTypes][kNumExplicitTypes][5] = {
DECLARE_S2V_IDENT_KERNELS_SET(bool),
const char * kernel_explicit_s2v_set[NUM_VEC_TYPES][NUM_VEC_TYPES][5] = {
DECLARE_S2V_IDENT_KERNELS_SET(char),
DECLARE_S2V_IDENT_KERNELS_SET(uchar),
DECLARE_S2V_IDENT_KERNELS_SET(unsigned char),
DECLARE_S2V_IDENT_KERNELS_SET(short),
DECLARE_S2V_IDENT_KERNELS_SET(ushort),
DECLARE_S2V_IDENT_KERNELS_SET(unsigned short),
DECLARE_S2V_IDENT_KERNELS_SET(int),
DECLARE_S2V_IDENT_KERNELS_SET(uint),
DECLARE_S2V_IDENT_KERNELS_SET(unsigned int),
DECLARE_S2V_IDENT_KERNELS_SET(long),
DECLARE_S2V_IDENT_KERNELS_SET(ulong),
DECLARE_S2V_IDENT_KERNELS_SET(unsigned long),
DECLARE_S2V_IDENT_KERNELS_SET(float),
DECLARE_EMPTY_SET
DECLARE_S2V_IDENT_KERNELS_SET(half),
DECLARE_S2V_IDENT_KERNELS_SET(double)
};
int test_explicit_s2v_function(cl_device_id deviceID, cl_context context, cl_command_queue queue, const char *programSrc,
ExplicitType srcType, unsigned int count, ExplicitType destType, unsigned int vecSize, void *inputData )
// clang-format on
bool IsHalfNaN(cl_half v)
{
// Extract FP16 exponent and mantissa
uint16_t h_exp = (((cl_half)v) >> (CL_HALF_MANT_DIG - 1)) & 0x1F;
uint16_t h_mant = ((cl_half)v) & 0x3FF;
// NaN test
return (h_exp == 0x1F && h_mant != 0);
}
int test_explicit_s2v_function(cl_context context, cl_command_queue queue,
cl_kernel kernel, ExplicitType srcType,
unsigned int count, ExplicitType destType,
unsigned int vecSize, void *inputData)
{
clProgramWrapper program;
clKernelWrapper kernel;
int error;
clMemWrapper streams[2];
void *outData;
unsigned char convertedData[ 8 ]; /* Max type size is 8 bytes */
size_t threadSize[3], groupSize[3];
unsigned char convertedData[8]; /* Max type size is 8 bytes */
unsigned int i, s;
unsigned char *inPtr, *outPtr;
size_t paramSize, destTypeSize;
const char* finalProgramSrc[2] = {
"", // optional pragma
programSrc
};
if (srcType == kDouble || destType == kDouble) {
finalProgramSrc[0] = "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
}
if( programSrc == NULL )
return 0;
paramSize = get_explicit_type_size( srcType );
destTypeSize = get_explicit_type_size( destType );
size_t destStride = destTypeSize * vecSize;
outData = malloc( destStride * count );
if( create_single_kernel_helper( context, &program, &kernel, 2, finalProgramSrc, "test_conversion" ) )
{
log_info( "****** %s%s *******\n", finalProgramSrc[0], finalProgramSrc[1] );
return -1;
}
std::vector<char> outData(destStride * count);
streams[0] = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR,
paramSize * count, inputData, &error);
@ -170,11 +153,13 @@ int test_explicit_s2v_function(cl_device_id deviceID, cl_context context, cl_com
/* Now verify the results. Each value should have been duplicated four times, and we should be able to just
do a memcpy instead of relying on the actual type of data */
error = clEnqueueReadBuffer( queue, streams[1], CL_TRUE, 0, destStride * count, outData, 0, NULL, NULL );
error =
clEnqueueReadBuffer(queue, streams[1], CL_TRUE, 0, destStride * count,
outData.data(), 0, NULL, NULL);
test_error( error, "Unable to read output values!" );
inPtr = (unsigned char *)inputData;
outPtr = (unsigned char *)outData;
outPtr = (unsigned char *)outData.data();
for( i = 0; i < count; i++ )
{
@ -186,6 +171,28 @@ int test_explicit_s2v_function(cl_device_id deviceID, cl_context context, cl_com
{
if( memcmp( convertedData, outPtr + destTypeSize * s, destTypeSize ) != 0 )
{
bool isSrcNaN =
(((srcType == kHalf)
&& IsHalfNaN(*reinterpret_cast<cl_half *>(inPtr)))
|| ((srcType == kFloat)
&& isnan(*reinterpret_cast<cl_float *>(inPtr)))
|| ((srcType == kDouble)
&& isnan(*reinterpret_cast<cl_double *>(inPtr))));
bool isDestNaN = (((destType == kHalf)
&& IsHalfNaN(*reinterpret_cast<cl_half *>(
outPtr + destTypeSize * s)))
|| ((destType == kFloat)
&& isnan(*reinterpret_cast<cl_float *>(
outPtr + destTypeSize * s)))
|| ((destType == kDouble)
&& isnan(*reinterpret_cast<cl_double *>(
outPtr + destTypeSize * s))));
if (isSrcNaN && isDestNaN)
{
continue;
}
unsigned int *p = (unsigned int *)outPtr;
log_error( "ERROR: Output value %d:%d does not validate for size %d:%d!\n", i, s, vecSize, (int)destTypeSize );
log_error( " Input: 0x%0*x\n", (int)( paramSize * 2 ), *(unsigned int *)inPtr & ( 0xffffffff >> ( 32 - paramSize * 8 ) ) );
@ -196,179 +203,185 @@ int test_explicit_s2v_function(cl_device_id deviceID, cl_context context, cl_com
inPtr += paramSize;
outPtr += destStride;
}
free( outData );
return 0;
}
int test_explicit_s2v_function_set(cl_device_id deviceID, cl_context context, cl_command_queue queue, ExplicitType srcType,
unsigned int count, void *inputData )
struct TypesIterator
{
unsigned int sizes[] = { 2, 4, 8, 16, 0 };
int i, dstType, failed = 0;
using TypeIter =
std::tuple<cl_char, cl_uchar, cl_short, cl_ushort, cl_int, cl_uint,
cl_long, cl_ulong, cl_float, cl_half, cl_double>;
for( dstType = kBool; dstType < kNumExplicitTypes; dstType++ )
TypesIterator(cl_device_id deviceID, cl_context context,
cl_command_queue queue)
: dstType(0), srcType(0), context(context), queue(queue)
{
if( dstType == kDouble && !is_extension_available( deviceID, "cl_khr_fp64" ) )
continue;
vecTypes = { kChar, kUChar, kShort, kUShort, kInt, kUInt,
kLong, kULong, kFloat, kHalf, kDouble };
fp16Support = is_extension_available(deviceID, "cl_khr_fp16");
fp64Support = is_extension_available(deviceID, "cl_khr_fp64");
if (( dstType == kLong || dstType == kULong ) && !gHasLong )
continue;
for_each_src_elem(it);
}
for( i = 0; sizes[i] != 0; i++ )
bool skip_type(ExplicitType type)
{
if ((type == kLong || type == kULong) && !gHasLong)
return true;
else if (type == kDouble && !fp64Support)
return true;
else if (type == kHalf && !fp16Support)
return true;
else if (strchr(get_explicit_type_name(type), ' ') != 0)
return true;
return false;
}
template <std::size_t Src = 0, typename SrcType>
void iterate_src_type(const SrcType &t)
{
bool doTest = !skip_type(vecTypes[srcType]);
if (doTest)
{
if( dstType != srcType )
continue;
if( strchr( get_explicit_type_name( (ExplicitType)srcType ), ' ' ) != NULL ||
strchr( get_explicit_type_name( (ExplicitType)dstType ), ' ' ) != NULL )
continue;
SrcType inputData[sample_count];
RandomSeed seed(gRandomSeed);
generate_random_data(vecTypes[srcType], 128, seed, inputData);
if( test_explicit_s2v_function( deviceID, context, queue, kernel_explicit_s2v_set[ srcType ][ dstType ][ i ],
srcType, count, (ExplicitType)dstType, sizes[ i ], inputData ) != 0 )
for_each_dst_elem<0, Src, SrcType>(it, inputData);
}
srcType++;
dstType = 0;
}
// crucial to keep it in-sync with ExplicitType
bool isExplicitTypeFloating(ExplicitType type) { return (type >= kFloat); }
template <std::size_t Dst, std::size_t Src, typename SrcType,
typename DstType>
void iterate_dst_type(const DstType &t, SrcType *inputData)
{
bool doTest = !skip_type(vecTypes[dstType]);
doTest = doTest
&& ((isExplicitTypeFloating(vecTypes[srcType])
&& isExplicitTypeFloating(vecTypes[dstType]))
|| (!isExplicitTypeFloating(vecTypes[srcType])
&& !isExplicitTypeFloating(vecTypes[dstType])));
if (doTest)
test_explicit_s2v_function_set<SrcType, DstType>(
vecTypes[srcType], vecTypes[dstType], inputData);
dstType++;
}
template <std::size_t Out = 0, typename... Tp>
inline typename std::enable_if<Out == sizeof...(Tp), void>::type
for_each_src_elem(
const std::tuple<Tp...> &) // Unused arguments are given no names.
{}
template <std::size_t Out = 0, typename... Tp>
inline typename std::enable_if < Out<sizeof...(Tp), void>::type
for_each_src_elem(const std::tuple<Tp...> &t)
{
iterate_src_type<Out>(std::get<Out>(t));
for_each_src_elem<Out + 1, Tp...>(t);
}
template <std::size_t In = 0, std::size_t Out, typename SrcType,
typename... Tp>
inline typename std::enable_if<In == sizeof...(Tp), void>::type
for_each_dst_elem(const std::tuple<Tp...> &, SrcType *)
{}
template <std::size_t In = 0, std::size_t Out, typename SrcType,
typename... Tp>
inline typename std::enable_if < In<sizeof...(Tp), void>::type
for_each_dst_elem(const std::tuple<Tp...> &t, SrcType *inputData)
{
iterate_dst_type<In, Out, SrcType>(std::get<In>(t), inputData);
for_each_dst_elem<In + 1, Out, SrcType, Tp...>(t, inputData);
}
template <typename SrcType, typename DstType>
void test_explicit_s2v_function_set(ExplicitType srcT, ExplicitType dstT,
SrcType *inputData)
{
unsigned int sizes[] = { 2, 4, 8, 16, 0 };
for (int i = 0; sizes[i] != 0; i++)
{
clProgramWrapper program;
clKernelWrapper kernel;
char pragma[256] = { 0 };
const char *finalProgramSrc[2] = {
pragma, // optional pragma
kernel_explicit_s2v_set[srcType][dstType][i]
};
std::stringstream sstr;
if (srcT == kDouble || dstT == kDouble)
sstr << "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n";
if (srcT == kHalf || dstT == kHalf)
sstr << "#pragma OPENCL EXTENSION cl_khr_fp16 : enable\n";
snprintf(pragma, sizeof(pragma), "%s", sstr.str().c_str());
if (create_single_kernel_helper(context, &program, &kernel, 2,
finalProgramSrc, "test_conversion"))
{
log_error( "ERROR: Explicit cast of scalar %s to vector %s%d FAILED; skipping other %s vector tests\n",
get_explicit_type_name(srcType), get_explicit_type_name((ExplicitType)dstType), sizes[i], get_explicit_type_name((ExplicitType)dstType) );
failed = -1;
break;
log_info("****** %s%s *******\n", finalProgramSrc[0],
finalProgramSrc[1]);
throw std::runtime_error(
"create_single_kernel_helper failed\n");
}
if (test_explicit_s2v_function(context, queue, kernel, srcT,
sample_count, dstT, sizes[i],
inputData)
!= 0)
{
log_error("ERROR: Explicit cast of scalar %s to vector %s%d "
"FAILED; skipping other %s vector tests\n",
get_explicit_type_name(srcT),
get_explicit_type_name(dstT), sizes[i],
get_explicit_type_name(dstT));
throw std::runtime_error("test_explicit_s2v_function failed\n");
}
}
}
return failed;
}
protected:
bool fp16Support;
bool fp64Support;
int test_explicit_s2v_char(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
TypeIter it;
unsigned int dstType, srcType;
cl_context context;
cl_command_queue queue;
std::vector<ExplicitType> vecTypes;
constexpr static unsigned int sample_count =
128; // hardcoded in original test
};
} // anonymous namespace
int test_explicit_s2v(cl_device_id deviceID, cl_context context,
cl_command_queue queue, int num_elements)
{
char data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kChar, 128, seed, data );
return test_explicit_s2v_function_set( deviceID, context, queue, kChar, 128, data );
}
int test_explicit_s2v_uchar(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
unsigned char data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kUChar, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kUChar, 128, data ) != 0 )
return -1;
if( test_explicit_s2v_function_set( deviceID, context, queue, kUnsignedChar, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_short(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
short data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kShort, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kShort, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_ushort(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
unsigned short data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kUShort, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kUShort, 128, data ) != 0 )
return -1;
if( test_explicit_s2v_function_set( deviceID, context, queue, kUnsignedShort, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_int(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kInt, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kInt, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_uint(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
unsigned int data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kUInt, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kUInt, 128, data ) != 0 )
return -1;
if( test_explicit_s2v_function_set( deviceID, context, queue, kUnsignedInt, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_long(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_long data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kLong, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kLong, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_ulong(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
cl_ulong data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kULong, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kULong, 128, data ) != 0 )
return -1;
if( test_explicit_s2v_function_set( deviceID, context, queue, kUnsignedLong, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_float(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
float data[128];
RandomSeed seed(gRandomSeed);
generate_random_data( kFloat, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kFloat, 128, data ) != 0 )
return -1;
return 0;
}
int test_explicit_s2v_double(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
double data[128];
RandomSeed seed(gRandomSeed);
if( !is_extension_available( deviceID, "cl_khr_fp64" ) ) {
log_info("Extension cl_khr_fp64 not supported. Skipping test.\n");
return 0;
try
{
TypesIterator(deviceID, context, queue);
} catch (const std::runtime_error &e)
{
log_error("%s", e.what());
return TEST_FAIL;
}
generate_random_data( kDouble, 128, seed, data );
if( test_explicit_s2v_function_set( deviceID, context, queue, kDouble, 128, data ) != 0 )
return -1;
return 0;
return TEST_PASS;
}

View file

@ -1,147 +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"
const char *float2int_kernel_code =
"__kernel void test_float2int(__global float *src, __global int *dst)\n"
"{\n"
" int tid = get_global_id(0);\n"
"\n"
" dst[tid] = (int)src[tid];\n"
"\n"
"}\n";
int
verify_float2int(cl_float *inptr, cl_int *outptr, int n)
{
int i;
for (i=0; i<n; i++)
{
if (outptr[i] != (int)inptr[i])
{
log_error("FLOAT2INT test failed\n");
return -1;
}
}
log_info("FLOAT2INT test passed\n");
return 0;
}
int
test_float2int(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements)
{
cl_mem streams[2];
cl_float *input_ptr;
cl_int *output_ptr;
cl_program program;
cl_kernel kernel;
void *values[2];
size_t threads[1];
int err;
int i;
MTdata d;
input_ptr = (cl_float*)malloc(sizeof(cl_float) * num_elements);
output_ptr = (cl_int*)malloc(sizeof(cl_int) * num_elements);
streams[0] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_float) * num_elements, NULL, NULL);
if (!streams[0])
{
log_error("clCreateBuffer failed\n");
return -1;
}
streams[1] = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(cl_int) * num_elements, NULL, NULL);
if (!streams[1])
{
log_error("clCreateBuffer failed\n");
return -1;
}
d = init_genrand( gRandomSeed );
for (i=0; i<num_elements; i++)
input_ptr[i] = get_random_float(-MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), MAKE_HEX_FLOAT( 0x1.0p31f, 0x1, 31), d);
free_mtdata(d); d = NULL;
err = clEnqueueWriteBuffer(queue, streams[0], CL_TRUE, 0, sizeof(cl_float)*num_elements, (void *)input_ptr, 0, NULL, NULL);
if (err != CL_SUCCESS)
{
log_error("clWriteArray failed\n");
return -1;
}
err = create_single_kernel_helper(context, &program, &kernel, 1, &float2int_kernel_code, "test_float2int");
if (err != CL_SUCCESS)
{
log_error("create_single_kernel_helper failed\n");
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)
{
log_error("clSetKernelArgs failed\n");
return -1;
}
threads[0] = (size_t)num_elements;
err = clEnqueueNDRangeKernel( queue, kernel, 1, NULL, threads, NULL, 0, NULL, NULL );
if (err != CL_SUCCESS)
{
log_error("clEnqueueNDRangeKernel failed\n");
return -1;
}
err = clEnqueueReadBuffer( queue, streams[1], true, 0, sizeof(cl_int)*num_elements, (void *)output_ptr, 0, NULL, NULL );
if (err != CL_SUCCESS)
{
log_error("clEnqueueReadBuffer failed\n");
return -1;
}
err = verify_float2int(input_ptr, output_ptr, num_elements);
// cleanup
clReleaseMemObject(streams[0]);
clReleaseMemObject(streams[1]);
clReleaseKernel(kernel);
clReleaseProgram(program);
free(input_ptr);
free(output_ptr);
return err;
}

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