1 /*
2 * Copyright 1993-2006 NVIDIA Corporation.  All rights reserved.
3 *
4 * NOTICE TO USER:
5 *
6 * This source code is subject to NVIDIA ownership rights under U.S. and
7 * international Copyright laws.
8 *
9 * NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
10 * CODE FOR ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
11 * IMPLIED WARRANTY OF ANY KIND.  NVIDIA DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
14 * IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
15 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
16 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
17 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
18 * OR PERFORMANCE OF THIS SOURCE CODE.
19 *
20 * U.S. Government End Users.  This source code is a "commercial item" as
21 * that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting  of
22 * "commercial computer software" and "commercial computer software
23 * documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
24 * and is provided to the U.S. Government only as a commercial end item.
25 * Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
26 * 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
27 * source code with only those rights set forth herein.
28 */
29 
30 
31 /* CUda UTility Library */
32 
33 #ifndef _CUTIL_H_
34 #define _CUTIL_H_
35 
36 #include <cuda_runtime.h>
37 
38 #ifdef _WIN32
39 #   pragma warning( disable : 4996 ) // disable deprecated warning
40 #endif
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46     // helper typedefs for building DLL
47 #ifdef _WIN32
48 #  ifdef BUILD_DLL
49 #    define DLL_MAPPING  __declspec(dllexport)
50 #  else
51 #    define DLL_MAPPING  __declspec(dllimport)
52 #  endif
53 #else
54 #  define DLL_MAPPING
55 #endif
56 
57 #ifdef _WIN32
58     #define CUTIL_API __stdcall
59 #else
60     #define CUTIL_API
61 #endif
62 
63 
64     ////////////////////////////////////////////////////////////////////////////
65     //! CUT bool type
66     ////////////////////////////////////////////////////////////////////////////
67     enum CUTBoolean
68     {
69         CUTFalse = 0,
70         CUTTrue = 1
71     };
72 
73     ////////////////////////////////////////////////////////////////////////////
74     //! Deallocate memory allocated within Cutil
75     //! @param  pointer to memory
76     ////////////////////////////////////////////////////////////////////////////
77     DLL_MAPPING
78     void CUTIL_API
79         cutFree( void* ptr);
80 
81     ////////////////////////////////////////////////////////////////////////////
82     //! Helper for bank conflict checking (should only be used with the
83     //! CUT_BANK_CHECKER macro)
84     //! @param tidx  thread id in x dimension of block
85     //! @param tidy  thread id in y dimension of block
86     //! @param tidz  thread id in z dimension of block
87     //! @param bdimx block size in x dimension
88     //! @param bdimy block size in y dimension
89     //! @param bdimz block size in z dimension
90     //! @param file  name of the source file where the access takes place
91     //! @param line  line in the source file where the access takes place
92     //! @param aname name of the array which is accessed
93     //! @param index index into the array
94     ////////////////////////////////////////////////////////////////////////////
95     DLL_MAPPING
96     void CUTIL_API
97     cutCheckBankAccess( unsigned int tidx, unsigned int tidy, unsigned int tidz,
98                         unsigned int bdimx, unsigned int bdimy,
99                         unsigned int bdimz, const char* file, const int line,
100                         const char* aname, const int index);
101 
102     ////////////////////////////////////////////////////////////////////////////
103     //! Find the path for a filename within a hardcoded set of paths
104     //! @return the path if succeeded, otherwise 0
105     //! @param filename        name of the file
106     //! @param executablePath  optional absolute path of the executable
107     ////////////////////////////////////////////////////////////////////////////
108     DLL_MAPPING
109     char* CUTIL_API
110     cutFindFilePath(const char* filename, const char* executablePath);
111 
112     ////////////////////////////////////////////////////////////////////////////
113     //! Find the path for a filename within a specified directory tree
114     //! @return the path if succeeded, otherwise 0
115     //! @param filename        name of the file
116     //! @param executablePath  optional absolute path of the executable
117     ////////////////////////////////////////////////////////////////////////////
118     DLL_MAPPING
119     CUTBoolean CUTIL_API
120     cutFindFile(char * outputPath, const char * startDir, const char * dirName);
121 
122     ////////////////////////////////////////////////////////////////////////////
123     //! Find the path for a filename within a specified directory tree
124     //! @return the path if succeeded, otherwise 0
125     //! @param filename        name of the file
126     //! @param executablePath  optional absolute path of the executable
127     ////////////////////////////////////////////////////////////////////////////
128     DLL_MAPPING
129     CUTBoolean CUTIL_API
130     cutFindDir(char * outputPath, const char * startDir, const char * dirName);
131 
132     ////////////////////////////////////////////////////////////////////////////
133     //! Read file \filename containing single precision floating point data
134     //! @return CUTTrue if reading the file succeeded, otherwise false
135     //! @param filename name of the source file
136     //! @param data  uninitialized pointer, returned initialized and pointing to
137     //!        the data read
138     //! @param len  number of data elements in data, -1 on error
139     //! @note If a nullptr pointer is passed to this function and it is
140     //!       initialized within Cutil then cutFree() has to be used to
141     //!       deallocate the memory
142     ////////////////////////////////////////////////////////////////////////////
143     DLL_MAPPING
144     CUTBoolean CUTIL_API
145     cutReadFilef( const char* filename, float** data, unsigned int* len,
146                   bool verbose = false);
147 
148     ////////////////////////////////////////////////////////////////////////////
149     //! Read file \filename containing double precision floating point data
150     //! @return CUTTrue if reading the file succeeded, otherwise false
151     //! @param filename name of the source file
152     //! @param data  uninitialized pointer, returned initialized and pointing to
153     //!        the data read
154     //! @param len  number of data elements in data, -1 on error
155     //! @note If a nullptr pointer is passed to this function and it is
156     //!       initialized within Cutil then cutFree() has to be used to
157     //!       deallocate the memory
158     ////////////////////////////////////////////////////////////////////////////
159     DLL_MAPPING
160     CUTBoolean CUTIL_API
161     cutReadFiled( const char* filename, double** data, unsigned int* len,
162                   bool verbose = false);
163 
164     ////////////////////////////////////////////////////////////////////////////
165     //! Read file \filename containing integer data
166     //! @return CUTTrue if reading the file succeeded, otherwise false
167     //! @param filename name of the source file
168     //! @param data  uninitialized pointer, returned initialized and pointing to
169     //!        the data read
170     //! @param len  number of data elements in data, -1 on error
171     //! @note If a nullptr pointer is passed to this function and it is
172     //!       initialized within Cutil then cutFree() has to be used to
173     //!       deallocate the memory
174     ////////////////////////////////////////////////////////////////////////////
175     DLL_MAPPING
176     CUTBoolean CUTIL_API
177     cutReadFilei( const char* filename, int** data, unsigned int* len, bool verbose = false);
178 
179     ////////////////////////////////////////////////////////////////////////////
180     //! Read file \filename containing unsigned integer data
181     //! @return CUTTrue if reading the file succeeded, otherwise false
182     //! @param filename name of the source file
183     //! @param data  uninitialized pointer, returned initialized and pointing to
184     //!        the data read
185     //! @param len  number of data elements in data, -1 on error
186     //! @note If a nullptr pointer is passed to this function and it is
187     //!       initialized within Cutil then cutFree() has to be used to
188     //!       deallocate the memory
189     ////////////////////////////////////////////////////////////////////////////
190     DLL_MAPPING
191     CUTBoolean CUTIL_API
192     cutReadFileui( const char* filename, unsigned int** data,
193                    unsigned int* len, bool verbose = false);
194 
195     ////////////////////////////////////////////////////////////////////////////
196     //! Read file \filename containing char / byte data
197     //! @return CUTTrue if reading the file succeeded, otherwise false
198     //! @param filename name of the source file
199     //! @param data  uninitialized pointer, returned initialized and pointing to
200     //!        the data read
201     //! @param len  number of data elements in data, -1 on error
202     //! @note If a nullptr pointer is passed to this function and it is
203     //!       initialized within Cutil then cutFree() has to be used to
204     //!       deallocate the memory
205     ////////////////////////////////////////////////////////////////////////////
206     DLL_MAPPING
207     CUTBoolean CUTIL_API
208     cutReadFileb( const char* filename, char** data, unsigned int* len,
209                   bool verbose = false);
210 
211     ////////////////////////////////////////////////////////////////////////////
212     //! Read file \filename containing unsigned char / byte data
213     //! @return CUTTrue if reading the file succeeded, otherwise false
214     //! @param filename name of the source file
215     //! @param data  uninitialized pointer, returned initialized and pointing to
216     //!        the data read
217     //! @param len  number of data elements in data, -1 on error
218     //! @note If a nullptr pointer is passed to this function and it is
219     //!       initialized within Cutil then cutFree() has to be used to
220     //!       deallocate the memory
221     ////////////////////////////////////////////////////////////////////////////
222     DLL_MAPPING
223     CUTBoolean CUTIL_API
224     cutReadFileub( const char* filename, unsigned char** data,
225                    unsigned int* len, bool verbose = false);
226 
227     ////////////////////////////////////////////////////////////////////////////
228     //! Write a data file \filename containing single precision floating point
229     //! data
230     //! @return CUTTrue if writing the file succeeded, otherwise false
231     //! @param filename name of the file to write
232     //! @param data  pointer to data to write
233     //! @param len  number of data elements in data, -1 on error
234     //! @param epsilon  epsilon for comparison
235     ////////////////////////////////////////////////////////////////////////////
236     DLL_MAPPING
237     CUTBoolean CUTIL_API
238     cutWriteFilef( const char* filename, const float* data, unsigned int len,
239                    const float epsilon, bool verbose = false);
240 
241     ////////////////////////////////////////////////////////////////////////////
242     //! Write a data file \filename containing double precision floating point
243     //! data
244     //! @return CUTTrue if writing the file succeeded, otherwise false
245     //! @param filename name of the file to write
246     //! @param data  pointer to data to write
247     //! @param len  number of data elements in data, -1 on error
248     //! @param epsilon  epsilon for comparison
249     ////////////////////////////////////////////////////////////////////////////
250     DLL_MAPPING
251     CUTBoolean CUTIL_API
252     cutWriteFiled( const char* filename, const float* data, unsigned int len,
253                    const double epsilon, bool verbose = false);
254 
255     ////////////////////////////////////////////////////////////////////////////
256     //! Write a data file \filename containing integer data
257     //! @return CUTTrue if writing the file succeeded, otherwise false
258     //! @param filename name of the file to write
259     //! @param data  pointer to data to write
260     //! @param len  number of data elements in data, -1 on error
261     ////////////////////////////////////////////////////////////////////////////
262     DLL_MAPPING
263     CUTBoolean CUTIL_API
264     cutWriteFilei( const char* filename, const int* data, unsigned int len,
265                    bool verbose = false);
266 
267     ////////////////////////////////////////////////////////////////////////////
268     //! Write a data file \filename containing unsigned integer data
269     //! @return CUTTrue if writing the file succeeded, otherwise false
270     //! @param filename name of the file to write
271     //! @param data  pointer to data to write
272     //! @param len  number of data elements in data, -1 on error
273     ////////////////////////////////////////////////////////////////////////////
274     DLL_MAPPING
275     CUTBoolean CUTIL_API
276     cutWriteFileui( const char* filename,const unsigned int* data,
277                     unsigned int len, bool verbose = false);
278 
279     ////////////////////////////////////////////////////////////////////////////
280     //! Write a data file \filename containing char / byte data
281     //! @return CUTTrue if writing the file succeeded, otherwise false
282     //! @param filename name of the file to write
283     //! @param data  pointer to data to write
284     //! @param len  number of data elements in data, -1 on error
285     ////////////////////////////////////////////////////////////////////////////
286     DLL_MAPPING
287     CUTBoolean CUTIL_API
288     cutWriteFileb( const char* filename, const char* data, unsigned int len,
289                    bool verbose = false);
290 
291     ////////////////////////////////////////////////////////////////////////////
292     //! Write a data file \filename containing unsigned char / byte data
293     //! @return CUTTrue if writing the file succeeded, otherwise false
294     //! @param filename name of the file to write
295     //! @param data  pointer to data to write
296     //! @param len  number of data elements in data, -1 on error
297     ////////////////////////////////////////////////////////////////////////////
298     DLL_MAPPING
299     CUTBoolean CUTIL_API
300     cutWriteFileub( const char* filename,const unsigned char* data,
301                     unsigned int len, bool verbose = false);
302 
303     ////////////////////////////////////////////////////////////////////////////
304     //! Load PGM image file (with unsigned char as data element type)
305     //! @return CUTTrue if reading the file succeeded, otherwise false
306     //! @param file  name of the image file
307     //! @param data  handle to the data read
308     //! @param w     width of the image
309     //! @param h     height of the image
310     //! @note If a nullptr pointer is passed to this function and it is
311     //!       initialized within Cutil then cutFree() has to be used to
312     //!       deallocate the memory
313     ////////////////////////////////////////////////////////////////////////////
314     DLL_MAPPING
315     CUTBoolean CUTIL_API
316     cutLoadPGMub( const char* file, unsigned char** data,
317                   unsigned int *w,unsigned int *h);
318 
319     ////////////////////////////////////////////////////////////////////////////
320     //! Load PPM image file (with unsigned char as data element type)
321     //! @return CUTTrue if reading the file succeeded, otherwise false
322     //! @param file  name of the image file
323     //! @param data  handle to the data read
324     //! @param w     width of the image
325     //! @param h     height of the image
326     ////////////////////////////////////////////////////////////////////////////
327     DLL_MAPPING
328     CUTBoolean CUTIL_API
329     cutLoadPPMub( const char* file, unsigned char** data,
330                   unsigned int *w,unsigned int *h);
331 
332     ////////////////////////////////////////////////////////////////////////////
333     //! Load PPM image file (with unsigned char as data element type), padding
334     //! 4th component
335     //! @return CUTTrue if reading the file succeeded, otherwise false
336     //! @param file  name of the image file
337     //! @param data  handle to the data read
338     //! @param w     width of the image
339     //! @param h     height of the image
340     ////////////////////////////////////////////////////////////////////////////
341     DLL_MAPPING
342     CUTBoolean CUTIL_API
343     cutLoadPPM4ub( const char* file, unsigned char** data,
344                    unsigned int *w,unsigned int *h);
345 
346     ////////////////////////////////////////////////////////////////////////////
347     //! Load PGM image file (with unsigned int as data element type)
348     //! @return CUTTrue if reading the file succeeded, otherwise false
349     //! @param file  name of the image file
350     //! @param data  handle to the data read
351     //! @param w     width of the image
352     //! @param h     height of the image
353     //! @note If a nullptr pointer is passed to this function and it is
354     //!       initialized within Cutil then cutFree() has to be used to
355     //!       deallocate the memory
356     ////////////////////////////////////////////////////////////////////////////
357     DLL_MAPPING
358     CUTBoolean CUTIL_API
359         cutLoadPGMi( const char* file, unsigned int** data,
360                      unsigned int* w, unsigned int* h);
361 
362     ////////////////////////////////////////////////////////////////////////////
363     //! Load PGM image file (with unsigned short as data element type)
364     //! @return CUTTrue if reading the file succeeded, otherwise false
365     //! @param file  name of the image file
366     //! @param data  handle to the data read
367     //! @param w     width of the image
368     //! @param h     height of the image
369     //! @note If a nullptr pointer is passed to this function and it is
370     //!       initialized within Cutil then cutFree() has to be used to
371     //!       deallocate the memory
372     ////////////////////////////////////////////////////////////////////////////
373     DLL_MAPPING
374     CUTBoolean CUTIL_API
375         cutLoadPGMs( const char* file, unsigned short** data,
376                      unsigned int* w, unsigned int* h);
377 
378     ////////////////////////////////////////////////////////////////////////////
379     //! Load PGM image file (with float as data element type)
380     //! @param file  name of the image file
381     //! @param data  handle to the data read
382     //! @param w     width of the image
383     //! @param h     height of the image
384     //! @note If a nullptr pointer is passed to this function and it is
385     //!       initialized within Cutil then cutFree() has to be used to
386     //!       deallocate the memory
387     ////////////////////////////////////////////////////////////////////////////
388     DLL_MAPPING
389     CUTBoolean CUTIL_API
390         cutLoadPGMf( const char* file, float** data,
391                      unsigned int* w, unsigned int* h);
392 
393     ////////////////////////////////////////////////////////////////////////////
394     //! Save PGM image file (with unsigned char as data element type)
395     //! @param file  name of the image file
396     //! @param data  handle to the data read
397     //! @param w     width of the image
398     //! @param h     height of the image
399     ////////////////////////////////////////////////////////////////////////////
400     DLL_MAPPING
401     CUTBoolean CUTIL_API
402         cutSavePGMub( const char* file, unsigned char* data,
403                       unsigned int w, unsigned int h);
404 
405     ////////////////////////////////////////////////////////////////////////////
406     //! Save PPM image file (with unsigned char as data element type)
407     //! @param file  name of the image file
408     //! @param data  handle to the data read
409     //! @param w     width of the image
410     //! @param h     height of the image
411     ////////////////////////////////////////////////////////////////////////////
412     DLL_MAPPING
413     CUTBoolean CUTIL_API
414     cutSavePPMub( const char* file, unsigned char *data,
415                 unsigned int w, unsigned int h);
416 
417     ////////////////////////////////////////////////////////////////////////////
418     //! Save PPM image file (with unsigned char as data element type, padded to
419     //! 4 bytes)
420     //! @param file  name of the image file
421     //! @param data  handle to the data read
422     //! @param w     width of the image
423     //! @param h     height of the image
424     ////////////////////////////////////////////////////////////////////////////
425     DLL_MAPPING
426     CUTBoolean CUTIL_API
427     cutSavePPM4ub( const char* file, unsigned char *data,
428                    unsigned int w, unsigned int h);
429 
430     ////////////////////////////////////////////////////////////////////////////
431     //! Save PGM image file (with unsigned int as data element type)
432     //! @param file  name of the image file
433     //! @param data  handle to the data read
434     //! @param w     width of the image
435     //! @param h     height of the image
436     ////////////////////////////////////////////////////////////////////////////
437     DLL_MAPPING
438     CUTBoolean CUTIL_API
439     cutSavePGMi( const char* file, unsigned int* data,
440                  unsigned int w, unsigned int h);
441 
442     ////////////////////////////////////////////////////////////////////////////
443     //! Save PGM image file (with unsigned short as data element type)
444     //! @param file  name of the image file
445     //! @param data  handle to the data read
446     //! @param w     width of the image
447     //! @param h     height of the image
448     ////////////////////////////////////////////////////////////////////////////
449     DLL_MAPPING
450     CUTBoolean CUTIL_API
451     cutSavePGMs( const char* file, unsigned short* data,
452                  unsigned int w, unsigned int h);
453 
454     ////////////////////////////////////////////////////////////////////////////
455     //! Save PGM image file (with float as data element type)
456     //! @param file  name of the image file
457     //! @param data  handle to the data read
458     //! @param w     width of the image
459     //! @param h     height of the image
460     ////////////////////////////////////////////////////////////////////////////
461     DLL_MAPPING
462     CUTBoolean CUTIL_API
463     cutSavePGMf( const char* file, float* data,
464                  unsigned int w, unsigned int h);
465 
466     ////////////////////////////////////////////////////////////////////////////
467     // Command line arguments: General notes
468     // * All command line arguments begin with '--' followed by the token;
469     //   token and value are separated by '='; example --samples=50
470     // * Arrays have the form --model=[one.obj,two.obj,three.obj]
471     //   (without whitespaces)
472     ////////////////////////////////////////////////////////////////////////////
473 
474     ////////////////////////////////////////////////////////////////////////////
475     //! Check if command line argument \a flag-name is given
476     //! @return CUTTrue if command line argument \a flag_name has been given,
477     //!         otherwise 0
478     //! @param argc  argc as passed to main()
479     //! @param argv  argv as passed to main()
480     //! @param flag_name  name of command line flag
481     ////////////////////////////////////////////////////////////////////////////
482     DLL_MAPPING
483     CUTBoolean CUTIL_API
484     cutCheckCmdLineFlag( const int argc, const char** argv,
485                          const char* flag_name);
486 
487     ////////////////////////////////////////////////////////////////////////////
488     //! Get the value of a command line argument of type int
489     //! @return CUTTrue if command line argument \a arg_name has been given and
490     //!         is of the requested type, otherwise CUTFalse
491     //! @param argc  argc as passed to main()
492     //! @param argv  argv as passed to main()
493     //! @param arg_name  name of the command line argument
494     //! @param val  value of the command line argument
495     ////////////////////////////////////////////////////////////////////////////
496     DLL_MAPPING
497     CUTBoolean CUTIL_API
498     cutGetCmdLineArgumenti( const int argc, const char** argv,
499                             const char* arg_name, int* val);
500 
501     ////////////////////////////////////////////////////////////////////////////
502     //! Get the value of a command line argument of type float
503     //! @return CUTTrue if command line argument \a arg_name has been given and
504     //!         is of the requested type, otherwise CUTFalse
505     //! @param argc  argc as passed to main()
506     //! @param argv  argv as passed to main()
507     //! @param arg_name  name of the command line argument
508     //! @param val  value of the command line argument
509     ////////////////////////////////////////////////////////////////////////////
510     DLL_MAPPING
511     CUTBoolean CUTIL_API
512     cutGetCmdLineArgumentf( const int argc, const char** argv,
513                             const char* arg_name, float* val);
514 
515     ////////////////////////////////////////////////////////////////////////////
516     //! Get the value of a command line argument of type string
517     //! @return CUTTrue if command line argument \a arg_name has been given and
518     //!         is of the requested type, otherwise CUTFalse
519     //! @param argc  argc as passed to main()
520     //! @param argv  argv as passed to main()
521     //! @param arg_name  name of the command line argument
522     //! @param val  value of the command line argument
523     ////////////////////////////////////////////////////////////////////////////
524     DLL_MAPPING
525     CUTBoolean CUTIL_API
526     cutGetCmdLineArgumentstr( const int argc, const char** argv,
527                               const char* arg_name, char** val);
528 
529     ////////////////////////////////////////////////////////////////////////////
530     //! Get the value of a command line argument list those element are strings
531     //! @return CUTTrue if command line argument \a arg_name has been given and
532     //!         is of the requested type, otherwise CUTFalse
533     //! @param argc  argc as passed to main()
534     //! @param argv  argv as passed to main()
535     //! @param arg_name  name of the command line argument
536     //! @param val  command line argument list
537     //! @param len  length of the list / number of elements
538     ////////////////////////////////////////////////////////////////////////////
539     DLL_MAPPING
540     CUTBoolean CUTIL_API
541     cutGetCmdLineArgumentListstr( const int argc, const char** argv,
542                                   const char* arg_name, char** val,
543                                   unsigned int* len);
544 
545     ////////////////////////////////////////////////////////////////////////////
546     //! Extended assert
547     //! @return CUTTrue if the condition \a val holds, otherwise CUTFalse
548     //! @param val  condition to test
549     //! @param file  __FILE__ macro
550     //! @param line  __LINE__ macro
551     //! @note This function should be used via the CONDITION(val) macro
552     ////////////////////////////////////////////////////////////////////////////
553     DLL_MAPPING
554     CUTBoolean CUTIL_API
555     cutCheckCondition( int val, const char* file, const int line);
556 
557     ////////////////////////////////////////////////////////////////////////////
558     //! Compare two float arrays
559     //! @return  CUTTrue if \a reference and \a data are identical,
560     //!          otherwise CUTFalse
561     //! @param reference  handle to the reference data / gold image
562     //! @param data       handle to the computed data
563     //! @param len        number of elements in reference and data
564     ////////////////////////////////////////////////////////////////////////////
565     DLL_MAPPING
566     CUTBoolean CUTIL_API
567     cutComparef( const float* reference, const float* data,
568                  const unsigned int len);
569 
570     ////////////////////////////////////////////////////////////////////////////
571     //! Compare two integer arrays
572     //! @return  CUTTrue if \a reference and \a data are identical,
573     //!          otherwise CUTFalse
574     //! @param reference  handle to the reference data / gold image
575     //! @param data       handle to the computed data
576     //! @param len        number of elements in reference and data
577     ////////////////////////////////////////////////////////////////////////////
578     DLL_MAPPING
579     CUTBoolean CUTIL_API
580     cutComparei( const int* reference, const int* data,
581                  const unsigned int len );
582 
583     ////////////////////////////////////////////////////////////////////////////
584     //! Compare two unsigned char arrays
585     //! @return  CUTTrue if \a reference and \a data are identical,
586     //!          otherwise CUTFalse
587     //! @param reference  handle to the reference data / gold image
588     //! @param data       handle to the computed data
589     //! @param len        number of elements in reference and data
590     ////////////////////////////////////////////////////////////////////////////
591     DLL_MAPPING
592     CUTBoolean CUTIL_API
593     cutCompareub( const unsigned char* reference, const unsigned char* data,
594                   const unsigned int len );
595 
596     ////////////////////////////////////////////////////////////////////////////////
597     //! Compare two integer arrays witha n epsilon tolerance for equality
598     //! @return  CUTTrue if \a reference and \a data are identical,
599     //!          otherwise CUTFalse
600     //! @param reference  handle to the reference data / gold image
601     //! @param data       handle to the computed data
602     //! @param len        number of elements in reference and data
603     //! @param epsilon    epsilon to use for the comparison
604     ////////////////////////////////////////////////////////////////////////////////
605     DLL_MAPPING
606     CUTBoolean CUTIL_API
607     cutCompareube( const unsigned char* reference, const unsigned char* data,
608                  const unsigned int len, const int epsilon );
609 
610     ////////////////////////////////////////////////////////////////////////////
611     //! Compare two float arrays with an epsilon tolerance for equality
612     //! @return  CUTTrue if \a reference and \a data are identical,
613     //!          otherwise CUTFalse
614     //! @param reference  handle to the reference data / gold image
615     //! @param data       handle to the computed data
616     //! @param len        number of elements in reference and data
617     //! @param epsilon    epsilon to use for the comparison
618     ////////////////////////////////////////////////////////////////////////////
619     DLL_MAPPING
620     CUTBoolean CUTIL_API
621     cutComparefe( const float* reference, const float* data,
622                   const unsigned int len, const float epsilon );
623 
624     ////////////////////////////////////////////////////////////////////////////
625     //! Compare two float arrays using L2-norm with an epsilon tolerance for
626     //! equality
627     //! @return  CUTTrue if \a reference and \a data are identical,
628     //!          otherwise CUTFalse
629     //! @param reference  handle to the reference data / gold image
630     //! @param data       handle to the computed data
631     //! @param len        number of elements in reference and data
632     //! @param epsilon    epsilon to use for the comparison
633     ////////////////////////////////////////////////////////////////////////////
634     DLL_MAPPING
635     CUTBoolean CUTIL_API
636     cutCompareL2fe( const float* reference, const float* data,
637                     const unsigned int len, const float epsilon );
638 
639     ////////////////////////////////////////////////////////////////////////////
640     //! Timer functionality
641 
642     ////////////////////////////////////////////////////////////////////////////
643     //! Create a new timer
644     //! @return CUTTrue if a time has been created, otherwise false
645     //! @param  name of the new timer, 0 if the creation failed
646     ////////////////////////////////////////////////////////////////////////////
647     DLL_MAPPING
648     CUTBoolean CUTIL_API
649     cutCreateTimer( unsigned int* name);
650 
651     ////////////////////////////////////////////////////////////////////////////
652     //! Delete a timer
653     //! @return CUTTrue if a time has been deleted, otherwise false
654     //! @param  name of the timer to delete
655     ////////////////////////////////////////////////////////////////////////////
656     DLL_MAPPING
657     CUTBoolean CUTIL_API
658     cutDeleteTimer( unsigned int name);
659 
660     ////////////////////////////////////////////////////////////////////////////
661     //! Start the time with name \a name
662     //! @param name  name of the timer to start
663     ////////////////////////////////////////////////////////////////////////////
664     DLL_MAPPING
665     CUTBoolean CUTIL_API
666     cutStartTimer( const unsigned int name);
667 
668     ////////////////////////////////////////////////////////////////////////////
669     //! Stop the time with name \a name. Does not reset.
670     //! @param name  name of the timer to stop
671     ////////////////////////////////////////////////////////////////////////////
672     DLL_MAPPING
673     CUTBoolean CUTIL_API
674     cutStopTimer( const unsigned int name);
675 
676     ////////////////////////////////////////////////////////////////////////////
677     //! Resets the timer's counter.
678     //! @param name  name of the timer to reset.
679     ////////////////////////////////////////////////////////////////////////////
680     DLL_MAPPING
681     CUTBoolean CUTIL_API
682     cutResetTimer( const unsigned int name);
683 
684     ////////////////////////////////////////////////////////////////////////////
685     //! Returns total execution time in milliseconds for the timer over all
686     //! runs since the last reset or timer creation.
687     //! @param name  name of the timer to return the time of
688     ////////////////////////////////////////////////////////////////////////////
689     DLL_MAPPING
690     float CUTIL_API
691     cutGetTimerValue( const unsigned int name);
692 
693     ////////////////////////////////////////////////////////////////////////////
694     //! Return the average time in milliseconds for timer execution as the
695     //! total  time for the timer dividied by the number of completed (stopped)
696     //! runs the timer has made.
697     //! Excludes the current running time if the timer is currently running.
698     //! @param name  name of the timer to return the time of
699     ////////////////////////////////////////////////////////////////////////////
700     DLL_MAPPING
701     float CUTIL_API
702     cutGetAverageTimerValue( const unsigned int name);
703 
704     ////////////////////////////////////////////////////////////////////////////
705     //! Macros
706 
707 #ifdef _DEBUG
708 
709 #if __DEVICE_EMULATION__
710     // Interface for bank conflict checker
711 #define CUT_BANK_CHECKER( array, index)                                      \
712     (cutCheckBankAccess( threadIdx.x, threadIdx.y, threadIdx.z, blockDim.x,  \
713     blockDim.y, blockDim.z,                                                  \
714     __FILE__, __LINE__, #array, index ),                                     \
715     array[index])
716 #else
717 #define CUT_BANK_CHECKER( array, index)  array[index]
718 #endif
719 
720 #  define CU_SAFE_CALL_NO_SYNC( call ) do {                                  \
721     CUresult err = call;                                                     \
722     if( CUDA_SUCCESS != err) {                                               \
723         fprintf(stderr, "Cuda driver error %x in file '%s' in line %i.\n",   \
724                 err, __FILE__, __LINE__ );                                   \
725         exit(EXIT_FAILURE);                                                  \
726     } } while (0)
727 
728 #  define CU_SAFE_CALL( call ) do {                                          \
729     CU_SAFE_CALL_NO_SYNC(call);                                              \
730     CUresult err = cuCtxSynchronize();                                       \
731     if( CUDA_SUCCESS != err) {                                               \
732         fprintf(stderr, "Cuda driver error %x in file '%s' in line %i.\n",   \
733                 err, __FILE__, __LINE__ );                                   \
734         exit(EXIT_FAILURE);                                                  \
735     } } while (0)
736 
737 #  define CUDA_SAFE_CALL_NO_SYNC( call) do {                                 \
738     cudaError err = call;                                                    \
739     if( cudaSuccess != err) {                                                \
740         fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",        \
741                 __FILE__, __LINE__, cudaGetErrorString( err) );              \
742         exit(EXIT_FAILURE);                                                  \
743     } } while (0)
744 
745 #  define CUDA_SAFE_CALL( call) do {                                         \
746     CUDA_SAFE_CALL_NO_SYNC(call);                                            \
747     cudaError err = cudaThreadSynchronize();                                 \
748     if( cudaSuccess != err) {                                                \
749         fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",        \
750                 __FILE__, __LINE__, cudaGetErrorString( err) );              \
751         exit(EXIT_FAILURE);                                                  \
752     } } while (0)
753 
754 #  define CUFFT_SAFE_CALL( call) do {                                        \
755     cufftResult err = call;                                                  \
756     if( CUFFT_SUCCESS != err) {                                              \
757         fprintf(stderr, "CUFFT error in file '%s' in line %i.\n",            \
758                 __FILE__, __LINE__);                                         \
759         exit(EXIT_FAILURE);                                                  \
760     } } while (0)
761 
762 #  define CUT_SAFE_CALL( call)                                               \
763     if( CUTTrue != call) {                                                   \
764         fprintf(stderr, "Cut error in file '%s' in line %i.\n",              \
765                 __FILE__, __LINE__);                                         \
766         exit(EXIT_FAILURE);                                                  \
767     }
768 
769     //! Check for CUDA error
770 #  define CUT_CHECK_ERROR(errorMessage) do {                                 \
771     cudaError_t err = cudaGetLastError();                                    \
772     if( cudaSuccess != err) {                                                \
773         fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n",    \
774                 errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
775         exit(EXIT_FAILURE);                                                  \
776     }                                                                        \
777     err = cudaThreadSynchronize();                                           \
778     if( cudaSuccess != err) {                                                \
779         fprintf(stderr, "Cuda error: %s in file '%s' in line %i : %s.\n",    \
780                 errorMessage, __FILE__, __LINE__, cudaGetErrorString( err) );\
781         exit(EXIT_FAILURE);                                                  \
782     } } while (0)
783 
784     //! Check for malloc error
785 #  define CUT_SAFE_MALLOC( mallocCall ) do{                                  \
786     if( !(mallocCall)) {                                                     \
787         fprintf(stderr, "Host malloc failure in file '%s' in line %i\n",     \
788                 __FILE__, __LINE__);                                         \
789         exit(EXIT_FAILURE);                                                  \
790     } } while(0);
791 
792     //! Check if conditon is true (flexible assert)
793 #  define CUT_CONDITION( val)                                                \
794     if( CUTFalse == cutCheckCondition( val, __FILE__, __LINE__)) {           \
795         exit(EXIT_FAILURE);                                                  \
796     }
797 
798 #else  // not DEBUG
799 
800 #define CUT_BANK_CHECKER( array, index)  array[index]
801 
802     // void macros for performance reasons
803 #  define CUT_CHECK_ERROR(errorMessage)
804 #  define CUT_CHECK_ERROR_GL()
805 #  define CUT_CONDITION( val)
806 #  define CU_SAFE_CALL_NO_SYNC( call) call
807 #  define CU_SAFE_CALL( call) call
808 #  define CUDA_SAFE_CALL_NO_SYNC( call) call
809 #  define CUDA_SAFE_CALL( call) call
810 #  define CUT_SAFE_CALL( call) call
811 #  define CUFFT_SAFE_CALL( call) call
812 #  define CUT_SAFE_MALLOC( mallocCall ) mallocCall
813 
814 #endif
815 
816 #if __DEVICE_EMULATION__
817 
818 #  define CUT_DEVICE_INIT(ARGC, ARGV)
819 
820 #else
821 
822 #  define CUT_DEVICE_INIT(ARGC, ARGV) {                                      \
823     int deviceCount;                                                         \
824     CUDA_SAFE_CALL_NO_SYNC(cudaGetDeviceCount(&deviceCount));                \
825     if (deviceCount == 0) {                                                  \
826         fprintf(stderr, "cutil error: no devices supporting CUDA.\n");       \
827         exit(EXIT_FAILURE);                                                  \
828     }                                                                        \
829     int dev = 0;                                                             \
830     cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev);      \
831     if (dev > deviceCount-1) dev = deviceCount - 1;                          \
832     cudaDeviceProp deviceProp;                                               \
833     CUDA_SAFE_CALL_NO_SYNC(cudaGetDeviceProperties(&deviceProp, dev));       \
834     if (deviceProp.major < 1) {                                              \
835         fprintf(stderr, "cutil error: device does not support CUDA.\n");     \
836         exit(EXIT_FAILURE);                                                  \
837     }                                                                        \
838     if (cutCheckCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) \
839         fprintf(stderr, "Using device %d: %s\n", dev, deviceProp.name);       \
840     CUDA_SAFE_CALL(cudaSetDevice(dev));                                      \
841 }
842 
843 #endif
844 
845 #  define CUT_DEVICE_INIT_DRV(cuDevice, ARGC, ARGV) {                        \
846     cuDevice = 0;                                                            \
847     int deviceCount = 0;                                                     \
848     CUresult err = cuInit(0);                                                \
849     if (CUDA_SUCCESS == err)                                                 \
850         CU_SAFE_CALL_NO_SYNC(cuDeviceGetCount(&deviceCount));                \
851     if (deviceCount == 0) {                                                  \
852         fprintf(stderr, "cutil error: no devices supporting CUDA\n");        \
853         exit(EXIT_FAILURE);                                                  \
854     }                                                                        \
855     int dev = 0;                                                             \
856     cutGetCmdLineArgumenti(ARGC, (const char **) ARGV, "device", &dev);      \
857     if (dev > deviceCount-1) dev = deviceCount - 1;                          \
858     CU_SAFE_CALL_NO_SYNC(cuDeviceGet(&cuDevice, dev));                       \
859     char name[100];                                                          \
860     cuDeviceGetName(name, 100, cuDevice);                                    \
861     if (cutCheckCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == CUTFalse) \
862         fprintf(stderr, "Using device %d: %s\n", dev, name);                  \
863 }
864 
865 #define CUT_EXIT(argc, argv)                                                 \
866     if (!cutCheckCmdLineFlag(argc, (const char**)argv, "noprompt")) {        \
867         printf("\nPress ENTER to exit...\n");                                \
868         fflush( stdout);                                                     \
869         fflush( stderr);                                                     \
870         getchar();                                                           \
871     }                                                                        \
872     exit(EXIT_SUCCESS);
873 
874 
875 #ifdef __cplusplus
876 }
877 #endif  // #ifdef _DEBUG (else branch)
878 
879 #endif  // #ifndef _CUTIL_H_
880