add daxpy, dgemv
[blas_decision:mainline.git] / bench.c
1 #include <libgen.h>             /* basename() */
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <dlfcn.h>
8 #include <string.h>
9 #include <omp.h>
10 #include "selection.h"
11
12
13
14 extern struct benchmark zgemm_bench;
15 extern struct benchmark dgemm_bench;
16 extern struct benchmark zaxpy_bench;
17 extern struct benchmark zgemv_bench;
18
19 struct benchmark *benchmarks[] = { &zgemv_bench, NULL };
20
21 static struct lib *libs;
22 static int libs_n;
23
24
25 /* benchmarks might have poor performance if numbers are not 
26  * proper double values. */
27 double *malloc_random_double(size_t size)
28 {
29         double *b;
30         size_t i;
31         
32         b = malloc(size);
33
34         if (!b)
35                 return NULL;
36
37         /* quality of random numbers is not important so far,
38          * otherwise we should change this to read from/dev/urandom 
39          * if we want to do regression checking, srand() should be useful. */
40 #pragma omp parallel for
41         for (i = 0; i < size/sizeof(double); i++) 
42                 b[i] = rand();
43
44         return b;
45
46 }
47
48 /* open libraries for testing */
49 void load_libraries(char *names[], int n)
50 {
51         int i;
52
53         libs_n = n;
54         libs = malloc(sizeof(struct lib) * libs_n);
55
56         for (i = 0; i < libs_n; i++) {
57
58                 libs[i].so_handle = dlopen(names[i], RTLD_NOW);
59                 libs[i].path = strdup(names[i]);
60                 libs[i].name = strdup(basename(names[i]));
61
62                 if (libs[i].so_handle == NULL) {
63                         printf("Sorry, could not dlopen(): %s\n", dlerror());
64                         exit(-1);
65                 }
66         }
67 }
68
69 int main(int argc, char *argv[]) 
70 {
71         struct benchmark *b;
72         char filename[1024];
73         int i, j, l, n;
74         double time;
75
76         if (argc < 2) {
77                 printf("usage: %s libblas1.so libblas2.so ...\n", argv[0]);
78                 exit(-1);
79         }
80
81         load_libraries(&argv[1], argc - 1);
82
83         for (i = 0, b = benchmarks[i] ; b != NULL ; b = benchmarks[ ++i ])
84         {
85                 printf("Benchmark for %s\n", b->name);
86                 b->prepare();
87
88                 for (l = 0; l < libs_n ; l++) {
89                         snprintf(filename, 1024, "%s_%s_output.txt", libs[l].name, b->name);
90                         libs[l].fd = fopen(filename, "w+");
91                         b->print_header(libs[l].fd);
92                 }
93
94                 do {
95                         for (l = 0; l < libs_n ; l++) 
96                         {
97                                 b->function = dlsym(libs[l].so_handle, b->name);
98         
99                                 if (b->function == NULL) {
100                                         printf("%s: Couldn't find function ...\n", libs[l].name);
101                                         continue;
102                                 }
103                 
104                                 /* one warm-up cycle, which is also used to estimate how many cycles we
105                                  * should take.*/
106                 
107                                 timer_start();
108                                 b->benchmark();
109                                 time = timer_stop();
110                 
111                                 /* use at least 100msec to benchmark */
112                                 n = 0.1 / time;
113                                 /* we want 3 rounds minimum */
114                                 if (n < 3)
115                                         n = 3;
116                 
117                                 timer_start();
118                                 for (j = 0; j < n; j++)
119                                         b->benchmark();
120                                 time = timer_stop();
121                 
122                                 b->print_parameters(libs[l].fd);
123                                 fprintf(libs[l].fd, "%3.3f\n", time/n * 1e3);
124                                 fflush(libs[l].fd);
125
126                                 b->print_parameters(stdout);
127                                 printf("% 20s: %3.3f msec (median from %d rounds)\n", libs[l].name, (time / n) * 1e3, n);
128                         }
129                 }
130                 while (b->next_parameter());
131
132                 for (l = 0; l < libs_n ; l++) 
133                         fclose(libs[l].fd);
134
135                 b->cleanup();
136         }
137         return 0;
138 }