• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #ifndef BOOST_COMPUTE_TEST_QUIRKS_HPP
12 #define BOOST_COMPUTE_TEST_QUIRKS_HPP
13 
14 #include <boost/compute/device.hpp>
15 #include <boost/compute/platform.hpp>
16 #include <boost/compute/detail/vendor.hpp>
17 
18 // this file contains functions which check for 'quirks' or buggy
19 // behavior in OpenCL implementations. this allows us to skip certain
20 // tests when running on buggy platforms.
21 
22 // returns true if the device is a POCL device
is_pocl_device(const boost::compute::device & device)23 inline bool is_pocl_device(const boost::compute::device &device)
24 {
25     return device.platform().name() == "Portable Computing Language";
26 }
27 
28 // returns true if the device is from Apple OpenCL platform
is_apple_device(const boost::compute::device & device)29 inline bool is_apple_device(const boost::compute::device &device)
30 {
31     return device.platform().name() == "Apple";
32 }
33 
34 // AMD platforms have a bug when using struct assignment. this affects
35 // algorithms like fill() when used with pairs/tuples.
36 //
37 // see: https://community.amd.com/thread/166622
bug_in_struct_assignment(const boost::compute::device & device)38 inline bool bug_in_struct_assignment(const boost::compute::device &device)
39 {
40     return boost::compute::detail::is_amd_device(device);
41 }
42 
43 // clEnqueueSVMMemcpy() operation does not work on AMD devices. This affects
44 // copy() algorithm. This bug was fixed in AMD drivers for Windows.
45 //
46 // see: https://community.amd.com/thread/190585
bug_in_svmmemcpy(const boost::compute::device & device)47 inline bool bug_in_svmmemcpy(const boost::compute::device &device)
48 {
49     #ifdef _WIN32
50     return false;
51     #else
52     return boost::compute::detail::is_amd_device(device);
53     #endif
54 }
55 
56 // For CPU devices on Apple platform local memory can not be used when work
57 // group size is not [1;1;1]. If work group size is greater "Invalid Work Group
58 // Size" error is thrown. (Apple OpenCL implementation can sometimes reduce
59 // max work group size for other reasons.)
60 // When local memory is not used max work group size for CPU devices on Apple
61 // platform should be [1024;1;1].
is_apple_cpu_device(const boost::compute::device & device)62 inline bool is_apple_cpu_device(const boost::compute::device &device)
63 {
64     return is_apple_device(device) && (device.type() & ::boost::compute::device::cpu);
65 }
66 
67 // On Apple devices clCreateBuffer does not return NULL and does no set error
68 // to CL_INVALID_BUFFER_SIZE when size of the buffer memory object is greater
69 // than CL_DEVICE_MAX_MEM_ALLOC_SIZE.
bug_in_clcreatebuffer(const boost::compute::device & device)70 inline bool bug_in_clcreatebuffer(const boost::compute::device &device)
71 {
72     return is_apple_device(device);
73 }
74 
75 // returns true if the device supports image samplers.
supports_image_samplers(const boost::compute::device & device)76 inline bool supports_image_samplers(const boost::compute::device &device)
77 {
78     // POCL does not yet support image samplers and gives the following
79     // error when attempting to create one:
80     //
81     // pocl error: encountered unimplemented part of the OpenCL specs
82     // in clCreateSampler.c:28
83     if(is_pocl_device(device)){
84         return false;
85     }
86 
87     return true;
88 }
89 
90 // returns true if the device has remquo() built-in OpenCL function implementation
has_remquo_func(const boost::compute::device & device)91 inline bool has_remquo_func(const boost::compute::device &device)
92 {
93     // POCL does not have it
94     if(is_pocl_device(device)){
95         return false;
96     }
97     return true;
98 }
99 
100 // returns true if the device supports clSetMemObjectDestructorCallback
supports_destructor_callback(const boost::compute::device & device)101 inline bool supports_destructor_callback(const boost::compute::device &device)
102 {
103     // unimplemented in POCL
104     return !is_pocl_device(device);
105 }
106 
107 // returns true if the device supports clCompileProgram
supports_compile_program(const boost::compute::device & device)108 inline bool supports_compile_program(const boost::compute::device &device)
109 {
110     // unimplemented in POCL
111     return !is_pocl_device(device);
112 }
113 
114 // returns true if the device supports clLinkProgram
supports_link_program(const boost::compute::device & device)115 inline bool supports_link_program(const boost::compute::device &device)
116 {
117     // unimplemented in POCL
118     return !is_pocl_device(device);
119 }
120 
121 // See https://github.com/pocl/pocl/issues/577, POCL fails when a program
122 // with incorrect code is built for the 2nd time
pocl_bug_issue_577(const boost::compute::device & device)123 inline bool pocl_bug_issue_577(const boost::compute::device &device)
124 {
125     return is_pocl_device(device);
126 }
127 
128 #endif // BOOST_COMPUTE_TEST_QUIRKS_HPP
129