1 //
2 // Copyright (c) 2017 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 #include "tools.h"
17 #include <sstream>
18 #include "harness/errorHelpers.h"
19
20 PrimeNumbersCollection PrimeNumbers::primeNumbers;
21 // Method generates prime numbers using Sieve of Eratosthenes algorithm
generatePrimeNumbers(unsigned int maxValue)22 void PrimeNumbers::generatePrimeNumbers (unsigned int maxValue) {
23
24 primeNumbers.clear();
25
26 for (unsigned int i=2; i < maxValue; i++)
27 primeNumbers.push_back(i);
28
29 PrimeNumbersCollection::iterator it, it2;
30 it = primeNumbers.begin();
31 it2 = primeNumbers.begin();
32
33 unsigned int maxValueSqrt = (unsigned int)sqrt((double)maxValue);
34
35 for (; it != primeNumbers.end(); it++) {
36 it2 = it;
37 ++it2;
38 if(*it>maxValueSqrt)
39 break;
40 for (;it2 != primeNumbers.end();)
41 if (*it2 % *it == 0)
42 it2 = primeNumbers.erase(it2);
43 else
44 ++it2;
45 }
46 }
47
48 // Returns prime number for specified range
getPrimeNumberInRange(size_t lowerValue,size_t higherValue)49 int PrimeNumbers::getPrimeNumberInRange (size_t lowerValue, size_t higherValue) {
50 if(lowerValue >= higherValue)
51 return -1;
52
53 if(primeNumbers.back() < lowerValue)
54 return -2;
55
56 PrimeNumbersCollection::iterator it = primeNumbers.begin();
57
58 for (; it != primeNumbers.end(); ++it) {
59 if (lowerValue<*it) {
60 if(higherValue>*it)
61 return *it;
62 else
63 return -3;
64 }
65 }
66 return -1;
67 }
68
69
getNextLowerPrimeNumber(size_t upperValue)70 int PrimeNumbers::getNextLowerPrimeNumber(size_t upperValue) {
71 size_t retVal = 1;
72
73 PrimeNumbersCollection::iterator it = primeNumbers.begin();
74
75 for (; it != primeNumbers.end(); ++it) {
76 if (upperValue > *it) {
77 retVal = *it;
78 } else {
79 break;
80 }
81 }
82 return retVal;
83 }
84
fitMaxPrime1d(size_t val1,size_t maxVal)85 PrimeNumbers::Result1d PrimeNumbers::fitMaxPrime1d(size_t val1, size_t maxVal){
86
87 PrimeNumbers::Result1d result;
88
89 if (maxVal == 1) {
90 result.Val1 = 1;
91 return result;
92 }
93
94 while(val1 > maxVal)
95 {
96 val1 = PrimeNumbers::getNextLowerPrimeNumber(val1);
97 }
98
99 result.Val1 = val1;
100 return result;
101 }
102
fitMaxPrime2d(size_t val1,size_t val2,size_t productMax)103 PrimeNumbers::Result2d PrimeNumbers::fitMaxPrime2d(size_t val1, size_t val2, size_t productMax) {
104
105 PrimeNumbers::Result2d result;
106
107 if (productMax == 1) {
108 result.Val1 = 1;
109 result.Val2 = 1;
110 return result;
111 }
112
113 while ((val2 * val1) > productMax) {
114 if ((val2 > val1) && (val2 > 1)) {
115 val2 = PrimeNumbers::getNextLowerPrimeNumber(val2);
116 continue;
117 }
118 if (val1 > 1) {
119 val1 = PrimeNumbers::getNextLowerPrimeNumber(val1);
120 continue;
121 }
122 break;
123 }
124 result.Val1 = val1;
125 result.Val2 = val2;
126 return result;
127 }
128
129
fitMaxPrime3d(size_t val1,size_t val2,size_t val3,size_t productMax)130 PrimeNumbers::Result3d PrimeNumbers::fitMaxPrime3d(size_t val1, size_t val2, size_t val3, size_t productMax) {
131
132 Result3d result;
133
134 if (productMax == 1) {
135 result.Val1 = 1;
136 result.Val2 = 1;
137 result.Val3 = 1;
138 return result;
139 }
140
141 while ((val3 * val2 * val1) > productMax) {
142 if ((val3 > val2) && (val3 > val1) && (val3 > 1)) {
143 val3 = PrimeNumbers::getNextLowerPrimeNumber(val3);
144 continue;
145 }
146 if ((val2 > val1) && (val2 > 1)) {
147 val2 = PrimeNumbers::getNextLowerPrimeNumber(val2);
148 continue;
149 }
150 if (val1 > 1) {
151 val1 = PrimeNumbers::getNextLowerPrimeNumber(val1);
152 continue;
153 }
154 break;
155 }
156 result.Val1 = val1;
157 result.Val2 = val2;
158 result.Val3 = val3;
159 return result;
160 }
161
162 namespace Error {
163 ErrorMap::value_type rawDataErrorString[] = {
164 ErrorMap::value_type(ERR_GLOBAL_SIZE, "global size"),
165 ErrorMap::value_type(ERR_GLOBAL_WORK_OFFSET, "global work offset"),
166 ErrorMap::value_type(ERR_LOCAL_SIZE, "local size"),
167 ErrorMap::value_type(ERR_GLOBAL_ID, "global id"),
168 ErrorMap::value_type(ERR_LOCAL_ID, "local id"),
169 ErrorMap::value_type(ERR_ENQUEUED_LOCAL_SIZE, "enqueued local size"),
170 ErrorMap::value_type(ERR_LOCAL_SIZE, "local size"),
171 ErrorMap::value_type(ERR_NUM_GROUPS, "num groups"),
172 ErrorMap::value_type(ERR_GROUP_ID, "group id"),
173 ErrorMap::value_type(ERR_WORK_DIM, "work dim"),
174 ErrorMap::value_type(ERR_GLOBAL_BARRIER, "global barrier"),
175 ErrorMap::value_type(ERR_LOCAL_BARRIER, "local barrier"),
176 ErrorMap::value_type(ERR_GLOBAL_ATOMIC, "global atomic"),
177 ErrorMap::value_type(ERR_LOCAL_ATOMIC, "local atomic"),
178 ErrorMap::value_type(ERR_STRICT_MODE, "strict requirements failed. Wrong local work group size"),
179 ErrorMap::value_type(ERR_BUILD_STATUS, "build status"),
180 ErrorMap::value_type(ERR_UNKNOWN, "[unknown]"),
181 ErrorMap::value_type(ERR_DIFFERENT, "[different]"),
182 };
183
184 const int numElems = sizeof(rawDataErrorString)/sizeof(rawDataErrorString[0]);
185 ErrorMap errorString (rawDataErrorString, rawDataErrorString+numElems);
186
ErrorClass()187 ErrorClass::ErrorClass() {
188 _overallNumberOfErrors = 0;
189 _stats.clear();
190 for (unsigned short i=0; i<sizeof(_errorArrayCounter)/sizeof(_errorArrayCounter[0]); i++) {
191 _errorArrayCounter[i] = 0;
192 }
193 }
194
show(Type err,std::string where,std::string additionalInfo)195 void ErrorClass::show(Type err, std::string where, std::string additionalInfo) {
196 ++_overallNumberOfErrors;
197
198 err = (errorString.find(err) == errorString.end())?ERR_UNKNOWN:err;
199 ++_stats[err];
200
201 if (_overallNumberOfErrors == MAX_NUMBER_OF_PRINTED_ERRORS)
202 printError("\t. . . Too many errors. Application will skip printing them.");
203
204 if (_overallNumberOfErrors >= MAX_NUMBER_OF_PRINTED_ERRORS)
205 return;
206
207 std::string errString = "Error ";
208 errString += errorString[err];
209 errString += " appeared";
210
211 if(where.compare("") != 0) {
212 errString += " in ";
213 errString += where;
214 }
215
216 if(additionalInfo.compare("") != 0) {
217 errString += " ";
218 errString += additionalInfo;
219 }
220 printError(errString);
221 }
222
show(Type whatErr,std::string where,cl_ulong valueIs,cl_ulong valueExpected)223 void ErrorClass::show(Type whatErr, std::string where, cl_ulong valueIs, cl_ulong valueExpected) {
224 std::ostringstream tmp;
225 tmp << "(is: " << valueIs << ", expected: " << valueExpected << ")";
226 show(whatErr, where, tmp.str());
227 }
228
229
show(std::string description)230 void ErrorClass::show(std::string description) {
231 ++_overallNumberOfErrors;
232 ++_stats[ERR_DIFFERENT];
233 if (_overallNumberOfErrors < MAX_NUMBER_OF_PRINTED_ERRORS)
234 printError(description);
235
236 if (_overallNumberOfErrors == MAX_NUMBER_OF_PRINTED_ERRORS)
237 printError("\t. . . Too many errors. Application will skip printing them.");
238 }
239
printError(std::string errString)240 void ErrorClass::printError(std::string errString) {
241 log_error ("%s\n", errString.c_str());
242 }
243
showStats()244 void ErrorClass::showStats() {
245
246 Type err;
247 log_info ("T E S T S U M M A R Y:\n");
248 for (ErrorStats::iterator it = _stats.begin(); it != _stats.end(); it++) {
249 err = (errorString.find(it->first) == errorString.end())?ERR_UNKNOWN:it->first;
250 std::string errName = errorString[err];
251 log_info("Error %s:\t%d\n", errName.c_str(), it->second);
252 }
253
254 log_info("Overall number of errors:\t%d\n", _overallNumberOfErrors);
255
256 }
257
checkError()258 bool ErrorClass::checkError() {
259 return _overallNumberOfErrors > 0;
260 }
261
262 // This method is required to synchronize errors counters between kernel and host
synchronizeStatsMap()263 void ErrorClass::synchronizeStatsMap() {
264 for (unsigned short i=0; i<sizeof(_errorArrayCounter)/sizeof(_errorArrayCounter[0]); i++) {
265 if(_errorArrayCounter[i] == 0)
266 continue;
267
268 _stats[static_cast<Type>(i)] += _errorArrayCounter[i];
269 _overallNumberOfErrors += _errorArrayCounter[i];
270 }
271
272 }
273
274 }
275