• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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