FK20 CUDA
test.h
Go to the documentation of this file.
1 // bls12_381: Arithmetic for BLS12-381
2 // Copyright 2022-2023 Dag Arne Osvik
3 // Copyright 2022-2023 Luan Cardoso dos Santos
4 
5 #ifndef TEST_H
6 #define TEST_H
7 
8 #include <stdio.h> // fileno(), stdout
9 #include <unistd.h> // isatty()
10 
11 extern __managed__ int stdout_isatty;
12 
13 extern void testinit();
14 
15 // Macros used in the testing functions
16 
17 // pretty print
18 #include <memory>
19 #define COLOR_RED "\x1b[31m"
20 #define COLOR_GREEN "\x1b[32m"
21 #define COLOR_RESET "\x1b[0m"
22 #define COLOR_BOLD "\x1b[1m"
23 
24 //Print test result
25 #define PRINTPASS(pass) if (stdout_isatty){ \
26  printf("--- %s\n", pass ? COLOR_GREEN "PASS" COLOR_RESET : COLOR_RED COLOR_BOLD "FAIL" COLOR_RESET);\
27  }else{ \
28  printf("--- %s\n", pass ? "PASS" : "FAIL" );\
29  }
30 
31 //Print false-positive test result
32 #define NEGPRINTPASS(pass) if (isatty(fileno(stdout))){ \
33  printf("--- %s (intentional error detected)\n", pass ? COLOR_RED COLOR_BOLD "FAIL" COLOR_RESET : COLOR_GREEN "PASS" COLOR_RESET);\
34  }else{\
35  printf("--- %s\n", pass ? "FAIL" : "PASS" );\
36  }
37 
38 
39 // Macros for writing memory values into a file. Only callable from HOST.
40 #define WRITEU64(writing_stream, var, nu64Elem) \
41  do { \
42  uint64_t *pointer = (uint64_t *)(*var); \
43  for (int count = 0; count < (nu64Elem); count++) { \
44  fprintf(writing_stream, "%016lx\n", pointer[count]); \
45  } \
46  } while (0)
47 
48 #define WRITEU64TOFILE(fileName, var, nu64Elem) \
49  do { \
50  FILE *filepointer = fopen(fileName, "w"); \
51  WRITEU64(filepointer, var, (nu64Elem)); \
52  fclose(filepointer); \
53  } while (0)
54 
55 // sadly CUDA doesn't allow fprintf inside a kernel, only printf.
56 // this can be used to dump memory values into stdout
57 #define WRITEU64STDOUT(var, nu64Elem) \
58  do { \
59  uint64_t *pointer = (uint64_t *)(var); \
60  for (int count = 0; count < (nu64Elem); count++) { \
61  printf("%016lx ", pointer[count]); \
62  if (count % 6 == 5) \
63  printf("\n"); \
64  } \
65  } while (0)
66 
67 // Syncronizes the Device, making sure that the kernel has finished the execution. Checks for any errors, and report if
68 // errors are found.
69 #ifndef CUDASYNC
70 #define CUDASYNC(fmt, ...) \
71  err = cudaDeviceSynchronize(); \
72  if (err != cudaSuccess) \
73  printf("%s:%d " fmt " Error: %d (%s)\n", __FILE__, __LINE__, err, cudaGetErrorName(err), ##__VA_ARGS__)
74 #endif
75 
76 // The necessary shared memory is larger than what we can statically allocate, hence it is allocated dynamically in the
77 // kernel call. Because cuda, we need to set the maximum allowed size using this macro.
78 #ifndef SET_SHAREDMEM
79 #define SET_SHAREDMEM(SZ, FN) \
80  err = cudaFuncSetAttribute(FN, cudaFuncAttributeMaxDynamicSharedMemorySize, SZ); \
81  cudaDeviceSynchronize(); \
82  if (err != cudaSuccess) \
83  printf("Error cudaFuncSetAttribute: %s:%d, error %d (%s)\n", __FILE__, __LINE__, err, cudaGetErrorName(err));
84 #endif
85 
86 // Clears the array used on the comparison kernel.
87 #define clearRes \
88  for (int i = 0; i < 16 * 512; i++) \
89  cmp[i] = 0; \
90  pass = true;
91 
92 #define clearRes512 \
93  for (int i = 0; i < rows * 16 * 512; i++) \
94  cmp[i] = 0; \
95  pass = true;
96 
97 // Simple timer. Full timing provided by benchmark.
98 #define CLOCKINIT clock_t start, end
99 #define CLOCKSTART start = clock()
100 #define CLOCKEND \
101  end = clock(); \
102  printf(" (%.1f ms)\n", (end - start) * (1000. / CLOCKS_PER_SEC))
103 
104 // Check if the array generated by the fr_eq() and g1p_eq() kernels have a failure, up to idx LENGTH. Reports only the
105 // first identified error to avoid clutter in the terminal.
106 #define CMPCHECK(LENGTH) \
107  for (int i = 0; pass && i < LENGTH; i++) { \
108  if (cmp[i] != 1) { \
109  printf("%s:%d %s() error idx %d...\n", __FILE__, __LINE__, __func__, i); \
110  pass = false; \
111  break; \
112  } \
113  }
114 
115 // Check if the array generated by the fr_eq() and g1p_eq() kernels have a failure. No print.
116 #define NEGCMPCHECK(LENGTH) \
117  for (int i = 0; pass && i < LENGTH; i++) { \
118  if (cmp[i] != 1) { \
119  pass = false; \
120  break; \
121  } \
122  }
123 
124 #endif
125 
126 // vim: ts=4 et sw=4 si
__managed__ int stdout_isatty
Definition: test.cu:8
void testinit()
Sets a global variable to true if the STDOUT is a terminal. Needs to be done like so because while a ...
Definition: test.cu:18