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 "harness/compat.h"
17 #include "exceptions.h"
18 #include "datagen.h"
19
20 RandomGenerator gRG;
21
getGlobalWorkSize() const22 size_t WorkSizeInfo::getGlobalWorkSize() const
23 {
24 switch( work_dim )
25 {
26 case 1: return global_work_size[0];
27 case 2: return global_work_size[0] * global_work_size[1];
28 case 3: return global_work_size[0] * global_work_size[1] * global_work_size[2];
29 default:
30 throw Exceptions::TestError("wrong work dimention\n");
31 }
32 }
33
34 /*
35 * DataGenerator
36 */
37
38 DataGenerator* DataGenerator::Instance = NULL;
39
getInstance()40 DataGenerator* DataGenerator::getInstance()
41 {
42 if (!Instance)
43 Instance = new DataGenerator();
44
45 return Instance;
46 }
47
DataGenerator()48 DataGenerator::DataGenerator()
49 {
50 #define TYPE_HNDL( type, isBuffer, base_element_size, vector_size, min_value, max_value, Generator) \
51 assert(m_argGenerators.find(type) == m_argGenerators.end()) ; \
52 m_argGenerators[type] = new Generator( isBuffer, vector_size, min_value, max_value);
53 #include "typeinfo.h"
54 #undef TYPE_HNDL
55 }
56
~DataGenerator()57 DataGenerator::~DataGenerator()
58 {
59 ArgGeneratorsMap::iterator i = m_argGenerators.begin();
60 ArgGeneratorsMap::iterator e = m_argGenerators.end();
61
62 for(; i != e; ++i)
63 {
64 delete i->second;
65 }
66 }
67
getArgGenerator(const KernelArgInfo & argInfo)68 KernelArgGenerator* DataGenerator::getArgGenerator( const KernelArgInfo& argInfo )
69 {
70 //try to match the full type first
71 ArgGeneratorsMap::iterator i = m_argGenerators.find(argInfo.getTypeName());
72 ArgGeneratorsMap::iterator e = m_argGenerators.end();
73
74 if( i != e )
75 {
76 return i->second;
77 }
78 // search for the proper prefix of the type
79 for(i = m_argGenerators.begin(); i != e; ++i)
80 {
81 if( 0 == argInfo.getTypeName().find(i->first))
82 {
83 return i->second;
84 }
85 }
86 throw Exceptions::TestError(std::string("Can't find the generator for the type ")
87 + argInfo.getTypeName() + " for argument " + argInfo.getName() + "\n");
88 }
89
setArgGenerator(const KernelArgInfo & argInfo,KernelArgGenerator * pGen)90 void DataGenerator::setArgGenerator(const KernelArgInfo& argInfo,
91 KernelArgGenerator* pGen)
92 {
93 m_argGenerators[argInfo.getTypeName()] = pGen;
94 }
95
get_random_int32(int low,int high,MTdata d)96 size_t get_random_int32(int low, int high, MTdata d)
97 {
98 int v = genrand_int32(d);
99
100 assert(low <= high && "Invalid random number range specified");
101 size_t range = high - low;
102
103 return (range) ? low + ((v - low) % range) : low;
104 }
105
106 /*
107 * KernelArgGeneratorSampler
108 */
KernelArgGeneratorSampler(bool isBuffer,size_t vectorSize,int minValue,int maxValue)109 KernelArgGeneratorSampler::KernelArgGeneratorSampler(bool isBuffer,
110 size_t vectorSize,
111 int minValue,
112 int maxValue) {
113 initToDefaults();
114 }
115
initToDefaults()116 void KernelArgGeneratorSampler::initToDefaults() {
117 m_normalized = false;
118 m_addressingMode = CL_ADDRESS_NONE;
119 m_filterMode = CL_FILTER_NEAREST;
120 }
121
KernelArgGeneratorSampler()122 KernelArgGeneratorSampler::KernelArgGeneratorSampler() {
123 initToDefaults();
124
125 }
126
setNormalized(cl_bool isNormalized)127 void KernelArgGeneratorSampler::setNormalized(cl_bool isNormalized)
128 {
129 m_normalized = isNormalized;
130 }
131
setAddressingMode(cl_addressing_mode mode)132 void KernelArgGeneratorSampler::setAddressingMode(cl_addressing_mode mode)
133 {
134 m_addressingMode = mode;
135 }
136
setFiterMode(cl_filter_mode mode)137 void KernelArgGeneratorSampler::setFiterMode(cl_filter_mode mode)
138 {
139 m_filterMode = mode;
140 }
141
142
143 /*
144 * SamplerValuesGenerator.
145 */
146
147 /*
148 * Static fields initialization.
149 */
150 cl_bool SamplerValuesGenerator::coordNormalizations[] = {CL_TRUE, CL_FALSE};
151
152 cl_filter_mode SamplerValuesGenerator::filterModes[] = {
153 CL_FILTER_NEAREST,
154 CL_FILTER_LINEAR
155 };
156
157 cl_addressing_mode SamplerValuesGenerator::addressingModes[] = {
158 CL_ADDRESS_NONE,
159 CL_ADDRESS_CLAMP,
160 CL_ADDRESS_CLAMP_TO_EDGE,
161 CL_ADDRESS_REPEAT,
162 CL_ADDRESS_MIRRORED_REPEAT
163 };
164
165 const size_t NUM_NORM_MODES =
166 sizeof(SamplerValuesGenerator::coordNormalizations)/sizeof(cl_bool);
167
168 const size_t NUM_FILTER_MODES =
169 sizeof(SamplerValuesGenerator::filterModes)/sizeof(cl_filter_mode);
170
171 const size_t NUM_ADDR_MODES =
172 sizeof(SamplerValuesGenerator::addressingModes)/sizeof(cl_addressing_mode);
173
end()174 SamplerValuesGenerator::iterator SamplerValuesGenerator::end()
175 {
176 return iterator(NUM_NORM_MODES-1, NUM_FILTER_MODES-1, NUM_ADDR_MODES-1);
177 }
178
179 /*
180 * A constructor for generating an 'end iterator'.
181 */
iterator(size_t norm,size_t filter,size_t addressing)182 SamplerValuesGenerator::iterator::iterator(size_t norm, size_t filter,
183 size_t addressing):
184 m_normIndex(norm), m_filterIndex(filter), m_addressingModeIndex(addressing){}
185
186 /*
187 * A constructor for generating a 'begin iterator'.
188 */
iterator()189 SamplerValuesGenerator::iterator::iterator():
190 m_normIndex(0), m_filterIndex(0), m_addressingModeIndex(0){}
191
operator ++()192 SamplerValuesGenerator::iterator& SamplerValuesGenerator::iterator::operator ++()
193 {
194 if (incrementIndex(m_normIndex, NUM_NORM_MODES)) return *this;
195 if (incrementIndex(m_filterIndex, NUM_FILTER_MODES)) return *this;
196 if (incrementIndex(m_addressingModeIndex, NUM_ADDR_MODES)) return *this;
197
198 assert(false && "incrementing end iterator!");
199 return *this;
200 }
201
incrementIndex(size_t & i,const size_t limit)202 bool SamplerValuesGenerator::iterator::incrementIndex(size_t &i,
203 const size_t limit)
204 {
205 i = (i+1) % limit;
206 return i != 0;
207 }
208
operator ==(const iterator & other) const209 bool SamplerValuesGenerator::iterator::operator == (const iterator& other) const
210 {
211 return m_normIndex == other.m_normIndex &&
212 m_filterIndex == other.m_filterIndex &&
213 m_addressingModeIndex == other.m_addressingModeIndex;
214 }
215
operator !=(const iterator & other) const216 bool SamplerValuesGenerator::iterator::operator != (const iterator& other) const
217 {
218 return !(*this == other);
219 }
220
getNormalized() const221 cl_bool SamplerValuesGenerator::iterator::getNormalized() const
222 {
223 assert(m_normIndex < NUM_NORM_MODES && "illegal index");
224 return coordNormalizations[m_normIndex];
225 }
226
getFilterMode() const227 cl_filter_mode SamplerValuesGenerator::iterator::getFilterMode() const
228 {
229 assert(m_filterIndex < NUM_FILTER_MODES && "illegal index");
230 return filterModes[m_filterIndex];
231 }
232
getAddressingMode() const233 cl_addressing_mode SamplerValuesGenerator::iterator::getAddressingMode() const
234 {
235 assert(m_addressingModeIndex < NUM_ADDR_MODES && "illegal index");
236 return addressingModes[m_addressingModeIndex];
237 }
238
toBitmap() const239 unsigned SamplerValuesGenerator::iterator::toBitmap() const
240 {
241 unsigned norm, filter, addressingModes;
242 switch (getNormalized())
243 {
244 case CL_TRUE:
245 norm = 8;
246 break;
247 case CL_FALSE:
248 norm = 0;
249 break;
250 default:
251 assert(0 && "invalid normalize value");
252 }
253
254 switch (getFilterMode())
255 {
256 case CL_FILTER_NEAREST:
257 filter = 0;
258 break;
259 case CL_FILTER_LINEAR:
260 filter = 16;
261 break;
262 default:
263 assert(0 && "invalid filter value");
264 }
265
266 switch(getAddressingMode())
267 {
268 case CL_ADDRESS_NONE:
269 addressingModes = 0;
270 break;
271 case CL_ADDRESS_CLAMP:
272 addressingModes = 1;
273 break;
274 case CL_ADDRESS_CLAMP_TO_EDGE:
275 addressingModes = 2;
276 break;
277 case CL_ADDRESS_REPEAT:
278 addressingModes = 3;
279 break;
280 case CL_ADDRESS_MIRRORED_REPEAT:
281 addressingModes = 4;
282 break;
283 default:
284 assert(0 && "invalid filter value");
285 }
286
287 return norm | filter | addressingModes;
288 }
289
toString() const290 std::string SamplerValuesGenerator::iterator::toString() const
291 {
292 std::string ret("(");
293
294 switch (getNormalized())
295 {
296 case CL_TRUE:
297 ret.append("Normalized | ");
298 break;
299 case CL_FALSE:
300 ret.append("Not Normalized | ");
301 break;
302 default:
303 assert(0 && "invalid normalize value");
304 }
305
306 switch (getFilterMode())
307 {
308 case CL_FILTER_NEAREST:
309 ret.append("Filter Nearest | ");
310 break;
311 case CL_FILTER_LINEAR:
312 ret.append("Filter Linear | ");
313 break;
314 default:
315 assert(0 && "invalid filter value");
316 }
317
318 switch(getAddressingMode())
319 {
320 case CL_ADDRESS_NONE:
321 ret.append("Address None");
322 break;
323 case CL_ADDRESS_CLAMP:
324 ret.append("Address clamp");
325 break;
326 case CL_ADDRESS_CLAMP_TO_EDGE:
327 ret.append("Address clamp to edge");
328 break;
329 case CL_ADDRESS_REPEAT:
330 ret.append("Address repeat");
331 break;
332 case CL_ADDRESS_MIRRORED_REPEAT:
333 ret.append("Address mirrored repeat");
334 break;
335 default:
336 assert(0 && "invalid filter value");
337 }
338
339 ret.append(")");
340 return ret;
341 }
342
343 /*
344 * ImageValuesGenerator.
345 */
346
347 /*
348 * Static fields initialization.
349 */
350 const char* ImageValuesGenerator::imageTypes[] = {
351 "image1d_array_float",
352 "image1d_array_int",
353 "image1d_array_uint",
354 "image1d_buffer_float",
355 "image1d_buffer_int",
356 "image1d_buffer_uint",
357 "image1d_float",
358 "image1d_int",
359 "image1d_uint",
360 "image2d_array_float",
361 "image2d_array_int",
362 "image2d_array_uint",
363 "image2d_float",
364 "image2d_int",
365 "image2d_uint",
366 "image3d_float",
367 "image3d_int",
368 "image3d_uint"
369 };
370
371 cl_channel_order ImageValuesGenerator::channelOrders[] = {
372 CL_A,
373 CL_R,
374 CL_Rx,
375 CL_RG,
376 CL_RGx,
377 CL_RA,
378 CL_RGB,
379 CL_RGBx,
380 CL_RGBA,
381 CL_ARGB,
382 CL_BGRA,
383 CL_INTENSITY,
384 CL_LUMINANCE,
385 CL_DEPTH,
386 CL_DEPTH_STENCIL
387 };
388
389 const size_t NUM_CHANNEL_ORDERS = sizeof(ImageValuesGenerator::channelOrders)/sizeof(ImageValuesGenerator::channelOrders[0]);
390 const size_t NUM_IMG_TYS = sizeof(ImageValuesGenerator::imageTypes)/sizeof(ImageValuesGenerator::imageTypes[0]);
391
begin()392 ImageValuesGenerator::iterator ImageValuesGenerator::begin()
393 {
394 return ImageValuesGenerator::iterator(this);
395 }
396
end()397 ImageValuesGenerator::iterator ImageValuesGenerator::end()
398 {
399 return ImageValuesGenerator::iterator(0);
400 }
401 /*
402 * Class Iterator
403 */
iterator(ImageValuesGenerator * pParent)404 ImageValuesGenerator::iterator::iterator(ImageValuesGenerator *pParent):
405 m_parent(pParent), m_channelIndex(0), m_imgTyIndex(0)
406 {
407 }
408
409 /*
410 * Initializes an 'end' iterator.
411 */
iterator(int)412 ImageValuesGenerator::iterator::iterator(int):
413 m_parent(NULL),
414 m_channelIndex(NUM_CHANNEL_ORDERS),
415 m_imgTyIndex(NUM_IMG_TYS) {}
416
operator ++()417 ImageValuesGenerator::iterator& ImageValuesGenerator::iterator::operator ++()
418 {
419 assert(m_channelIndex < NUM_CHANNEL_ORDERS && m_imgTyIndex < NUM_IMG_TYS &&
420 "Attempt to increment an end iterator");
421
422 ImageValuesGenerator::iterator endIter = iterator(0);
423 // Incrementing untill we find the next legal combination, or we reach the
424 // end value.
425 while (incrementIndex(m_channelIndex,NUM_CHANNEL_ORDERS))
426 if (isLegalCombination())
427 return *this;
428
429 // We have reach to this line because last increment caused an 'oveflow'
430 // in data channel order index.
431 if (incrementIndex(m_imgTyIndex, NUM_IMG_TYS))
432 // In case this combination is not legal, we go on to the next legal
433 // combo.
434 return isLegalCombination() ? *this : ++(*this);
435
436 *this = endIter;
437 return *this;
438 }
439
operator ==(const ImageValuesGenerator::iterator & o) const440 bool ImageValuesGenerator::iterator::operator == (
441 const ImageValuesGenerator::iterator& o) const
442 {
443 return m_channelIndex == o.m_channelIndex &&
444 m_imgTyIndex == o.m_imgTyIndex;
445 }
446
operator !=(const ImageValuesGenerator::iterator & o) const447 bool ImageValuesGenerator::iterator::operator != (
448 const ImageValuesGenerator::iterator& o) const
449 {
450 return !(*this == o);
451 }
452
getDataTypeName() const453 std::string ImageValuesGenerator::iterator::getDataTypeName() const
454 {
455 assert(m_imgTyIndex < NUM_IMG_TYS && "image type index is out of bound");
456
457 std::string tyName(imageTypes[m_imgTyIndex]);
458 // Find the last '_' and remove it (the suffix is _<channel type>).
459 size_t pos = tyName.find_last_of('_');
460 assert (std::string::npos != pos && "no under score in type name?");
461 tyName = tyName.erase(0, pos+1);
462 return tyName;
463 }
464
getOpenCLChannelOrder() const465 int ImageValuesGenerator::iterator::getOpenCLChannelOrder() const
466 {
467 assert(m_channelIndex < NUM_CHANNEL_ORDERS && "channel index out of bound");
468 return channelOrders[m_channelIndex];
469 }
470
getSPIRChannelOrder() const471 int ImageValuesGenerator::iterator::getSPIRChannelOrder() const
472 {
473 return getOpenCLChannelOrder();
474 }
475
getImageTypeName() const476 std::string ImageValuesGenerator::iterator::getImageTypeName() const
477 {
478 assert(m_imgTyIndex < NUM_IMG_TYS && "image type index is out of bound");
479
480 std::string tyName = imageTypes[m_imgTyIndex];
481 // Find the last '_' and remove it (the suffix is _<channel type>).
482 size_t pos = tyName.find_last_of('_');
483 assert (std::string::npos != pos && "no under score in type name?");
484 tyName = tyName.erase(pos, tyName.size() - pos);
485
486 return tyName;
487 }
488
getImageGeneratorName() const489 std::string ImageValuesGenerator::iterator::getImageGeneratorName() const
490 {
491 assert(m_imgTyIndex < NUM_IMG_TYS && "image type index is out of bound");
492 return imageTypes[m_imgTyIndex];
493 }
494
getBaseImageGeneratorName() const495 std::string ImageValuesGenerator::iterator::getBaseImageGeneratorName() const
496 {
497 assert(m_imgTyIndex < NUM_IMG_TYS && "image type index is out of bound");
498 std::string tyName = getImageTypeName();
499 tyName.append("_t");
500 return tyName;
501 }
502
getDataType() const503 int ImageValuesGenerator::iterator::getDataType() const
504 {
505 assert(m_imgTyIndex < NUM_IMG_TYS && "image type index is out of bound");
506 std::string tyName = getDataTypeName();
507
508 if ("int" == tyName)
509 return SPIR_CLK_SIGNED_INT32;
510 if ("uint" == tyName)
511 return SPIR_CLK_UNSIGNED_INT32;
512 if ("float" == tyName)
513 return SPIR_CLK_FLOAT;
514 assert (false && "unkown image data type");
515 return -1;
516 }
517
toString() const518 std::string ImageValuesGenerator::iterator::toString() const
519 {
520 if (*this == m_parent->end())
521 return "End iterator";
522
523 // Sanity.
524 assert(m_imgTyIndex < NUM_IMG_TYS && "image type index is out of bound");
525 assert(m_channelIndex < NUM_CHANNEL_ORDERS && "channel index out of bound");
526
527 std::string str = imageTypes[m_imgTyIndex];
528 str.append("_");
529
530 switch (channelOrders[m_channelIndex])
531 {
532 case CL_R:
533 str.append("cl_r");
534 break;
535 case CL_A:
536 str.append("cl_a");
537 break;
538 case CL_RG:
539 str.append("cl_rg");
540 break;
541 case CL_RA:
542 str.append("cl_ra");
543 break;
544 case CL_RGB:
545 str.append("cl_rgb");
546 break;
547 case CL_RGBA:
548 str.append("cl_rgba");
549 break;
550 case CL_BGRA:
551 str.append("cl_bgra");
552 break;
553 case CL_ARGB:
554 str.append("cl_argb");
555 break;
556 case CL_INTENSITY:
557 str.append("cl_intensity");
558 break;
559 case CL_LUMINANCE:
560 str.append("cl_luminace");
561 break;
562 case CL_Rx:
563 str.append("cl_Rx");
564 break;
565 case CL_RGx:
566 str.append("cl_RGx");
567 break;
568 case CL_RGBx:
569 str.append("cl_RGBx");
570 break;
571 case CL_DEPTH:
572 str.append("cl_depth");
573 break;
574 case CL_DEPTH_STENCIL:
575 str.append( "cl_depth_stencil");
576 break;
577 default:
578 assert(false && "Invalid channel order");
579 str.append("<invalid channel order>");
580 break;
581 }
582
583 return str;
584 }
585
incrementIndex(size_t & index,size_t arrSize)586 bool ImageValuesGenerator::iterator::incrementIndex(size_t& index,
587 size_t arrSize)
588 {
589 index = (index + 1) % arrSize;
590 return index != 0;
591 }
592
isLegalCombination() const593 bool ImageValuesGenerator::iterator::isLegalCombination() const
594 {
595 cl_channel_order corder = channelOrders[m_channelIndex];
596 std::string strImgTy(imageTypes[m_imgTyIndex]);
597
598 if (corder == CL_INTENSITY || corder == CL_LUMINANCE)
599 {
600 return getDataTypeName() == std::string("float");
601 }
602
603 if (corder == CL_DEPTH)
604 return false;
605
606 if (corder == CL_RGBx || corder == CL_RGB // Can only be applied for int unorms.
607 || corder == CL_ARGB || corder == CL_BGRA) // Can only be applied for int8.
608 return false;
609
610 return true;
611 }
612
613