1 // 2 // Copyright (c) 2017-2019 The Khronos Group Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 #ifndef _testHarness_h 17 #define _testHarness_h 18 19 #include "clImageHelper.h" 20 #include <string> 21 #include <sstream> 22 23 #include <string> 24 25 class Version { 26 public: Version()27 Version(): m_major(0), m_minor(0) {} Version(int major,int minor)28 Version(int major, int minor): m_major(major), m_minor(minor) {} 29 bool operator>(const Version &rhs) const { return to_int() > rhs.to_int(); } 30 bool operator<(const Version &rhs) const { return to_int() < rhs.to_int(); } 31 bool operator<=(const Version &rhs) const 32 { 33 return to_int() <= rhs.to_int(); 34 } 35 bool operator>=(const Version &rhs) const 36 { 37 return to_int() >= rhs.to_int(); 38 } 39 bool operator==(const Version &rhs) const 40 { 41 return to_int() == rhs.to_int(); 42 } to_int()43 int to_int() const { return m_major * 10 + m_minor; } to_string()44 std::string to_string() const 45 { 46 std::stringstream ss; 47 ss << m_major << "." << m_minor; 48 return ss.str(); 49 } 50 51 private: 52 int m_major; 53 int m_minor; 54 }; 55 56 Version get_device_cl_version(cl_device_id device); 57 58 #define ADD_TEST(fn) \ 59 { \ 60 test_##fn, #fn, Version(1, 0) \ 61 } 62 #define ADD_TEST_VERSION(fn, ver) \ 63 { \ 64 test_##fn, #fn, ver \ 65 } 66 67 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 68 69 typedef int (*test_function_pointer)(cl_device_id deviceID, cl_context context, 70 cl_command_queue queue, int num_elements); 71 72 typedef struct test_definition 73 { 74 test_function_pointer func; 75 const char *name; 76 Version min_version; 77 } test_definition; 78 79 80 typedef enum test_status 81 { 82 TEST_PASS = 0, 83 TEST_FAIL = 1, 84 TEST_SKIP = 2, 85 TEST_SKIPPED_ITSELF = -100, 86 } test_status; 87 88 struct test_harness_config 89 { 90 int forceNoContextCreation; 91 int numElementsToUse; 92 cl_command_queue_properties queueProps; 93 unsigned numWorkerThreads; 94 }; 95 96 extern int gFailCount; 97 extern int gTestCount; 98 extern cl_uint gReSeed; 99 extern cl_uint gRandomSeed; 100 101 // Supply a list of functions to test here. This will allocate a CL device, 102 // create a context, all that setup work, and then call each function in turn as 103 // dictatated by the passed arguments. Returns EXIT_SUCCESS iff all tests 104 // succeeded or the tests were listed, otherwise return EXIT_FAILURE. 105 extern int runTestHarness(int argc, const char *argv[], int testNum, 106 test_definition testList[], 107 int forceNoContextCreation, 108 cl_command_queue_properties queueProps); 109 110 // Device checking function. See runTestHarnessWithCheck. If this function 111 // returns anything other than TEST_PASS, the harness exits. 112 typedef test_status (*DeviceCheckFn)(cl_device_id device); 113 114 // Same as runTestHarness, but also supplies a function that checks the created 115 // device for required functionality. Returns EXIT_SUCCESS iff all tests 116 // succeeded or the tests were listed, otherwise return EXIT_FAILURE. 117 extern int runTestHarnessWithCheck(int argc, const char *argv[], int testNum, 118 test_definition testList[], 119 int forceNoContextCreation, 120 cl_command_queue_properties queueProps, 121 DeviceCheckFn deviceCheckFn); 122 123 // The command line parser used by runTestHarness to break up parameters into 124 // calls to callTestFunctions 125 extern int parseAndCallCommandLineTests(int argc, const char *argv[], 126 cl_device_id device, int testNum, 127 test_definition testList[], 128 const test_harness_config &config); 129 130 // Call this function if you need to do all the setup work yourself, and just 131 // need the function list called/ managed. 132 // testList is the data structure that contains test functions and its names 133 // selectedTestList is an array of integers (treated as bools) which tell 134 // which function is to be called, 135 // each element at index i, corresponds to the element in testList at 136 // index i 137 // resultTestList is an array of statuses which contain the result of each 138 // selected test testNum is the number of tests in testList, selectedTestList 139 // and resultTestList contextProps are used to create a testing context for 140 // each test deviceToUse and config are all just passed to each 141 // test function 142 extern void callTestFunctions(test_definition testList[], 143 unsigned char selectedTestList[], 144 test_status resultTestList[], int testNum, 145 cl_device_id deviceToUse, 146 const test_harness_config &config); 147 148 // This function is called by callTestFunctions, once per function, to do setup, 149 // call, logging and cleanup 150 extern test_status callSingleTestFunction(test_definition test, 151 cl_device_id deviceToUse, 152 const test_harness_config &config); 153 154 ///// Miscellaneous steps 155 156 // standard callback function for context pfn_notify 157 extern void CL_CALLBACK notify_callback(const char *errinfo, 158 const void *private_info, size_t cb, 159 void *user_data); 160 161 extern cl_device_type GetDeviceType(cl_device_id); 162 163 // Given a device (most likely passed in by the harness, but not required), will 164 // attempt to find a DIFFERENT device and return it. Useful for finding another 165 // device to run multi-device tests against. Note that returning NULL means an 166 // error was hit, but if no error was hit and the device passed in is the only 167 // device available, the SAME device is returned, so check! 168 extern cl_device_id GetOpposingDevice(cl_device_id device); 169 170 Version get_device_spirv_il_version(cl_device_id device); 171 bool check_device_spirv_il_support(cl_device_id device); 172 void version_expected_info(const char *test_name, const char *api_name, 173 const char *expected_version, 174 const char *device_version); 175 test_status check_spirv_compilation_readiness(cl_device_id device); 176 177 178 extern int gFlushDenormsToZero; // This is set to 1 if the device does not 179 // support denorms (CL_FP_DENORM) 180 extern int gInfNanSupport; // This is set to 1 if the device supports infinities 181 // and NaNs 182 extern int gIsEmbedded; // This is set to 1 if the device is an embedded device 183 extern int gHasLong; // This is set to 1 if the device suppots long and ulong 184 // types in OpenCL C. 185 extern bool gCoreILProgram; 186 187 extern cl_platform_id getPlatformFromDevice(cl_device_id deviceID); 188 189 #if !defined(__APPLE__) 190 void memset_pattern4(void *, const void *, size_t); 191 #endif 192 193 extern void PrintArch(void); 194 195 196 #endif // _testHarness_h 197