| Commit | Line | Data |
|---|---|---|
| 11518169 SK |
1 | #include <assert.h> |
| 2 | #include <math.h> | |
| 3 | #include <stdio.h> | |
| 4 | #include <stdlib.h> | |
| 5 | #include <string.h> | |
| 6 | #include <time.h> | |
| 7 | #include <sys/time.h> | |
| 8 | ||
| 9 | #include "gen.h" | |
| 10 | #include "subr_random.h" | |
| 11 | ||
| 7eb9c17b | 12 | #define NSAMPLE (1*1000) |
| 11518169 SK |
13 | |
| 14 | /* | |
| 15 | * They are esentially the same, but we still define them as if | |
| 16 | * they were different, for conceptual consistency and clarity. | |
| 17 | */ | |
| 18 | #define MARK_START(tv1) \ | |
| 19 | assert(gettimeofday(tv1, NULL) == 0); | |
| 20 | ||
| 21 | #define MARK_END(tv2) \ | |
| 22 | assert(gettimeofday(tv2, NULL) == 0); | |
| 23 | ||
| 24 | #define USECS(tv1, tv2) \ | |
| 25 | (((tv2).tv_sec - (tv1).tv_sec ) * 1000000 + \ | |
| 26 | ((tv2).tv_usec - (tv1).tv_usec)) | |
| 27 | ||
| 3cef403e SK |
28 | /* |
| 29 | * Make these globals, so that we allocate memory only once | |
| 30 | * during the program's lifetime. | |
| 31 | */ | |
| 11518169 SK |
32 | double *dx = NULL; |
| 33 | double *dy = NULL; | |
| 34 | double *dz = NULL; | |
| 7eb9c17b SK |
35 | double complex *cdx = NULL; |
| 36 | double complex *cdy = NULL; | |
| 37 | double complex *cdz = NULL; | |
| 11518169 SK |
38 | struct timeval *start = NULL; |
| 39 | struct timeval *end = NULL; | |
| 40 | ||
| 41 | static void | |
| 3cef403e | 42 | init_arrays(void) |
| 11518169 | 43 | { |
| 3f73d225 | 44 | dx = malloc(NSAMPLE * sizeof(double)); |
| 11518169 | 45 | dy = malloc(NSAMPLE * sizeof(double)); |
| 3f73d225 | 46 | dz = malloc(NSAMPLE * sizeof(double)); |
| 7eb9c17b SK |
47 | |
| 48 | cdx = malloc(NSAMPLE * sizeof(double complex)); | |
| 49 | cdy = malloc(NSAMPLE * sizeof(double complex)); | |
| 50 | cdz = malloc(NSAMPLE * sizeof(double complex)); | |
| 51 | ||
| 3f73d225 SK |
52 | start = malloc(NSAMPLE * sizeof(struct timeval)); |
| 53 | end = malloc(NSAMPLE * sizeof(struct timeval)); | |
| 11518169 | 54 | |
| 3f73d225 | 55 | assert(dx && dy && dz && start && end); |
| 11518169 SK |
56 | } |
| 57 | ||
| 58 | static void | |
| 59 | reset(void) | |
| 60 | { | |
| 61 | assert(dx && dy && dz && start && end); | |
| 62 | ||
| 63 | memset(dx, 0, NSAMPLE * sizeof(double)); | |
| 3f73d225 SK |
64 | memset(dy, 0, NSAMPLE * sizeof(double)); |
| 65 | memset(dz, 0, NSAMPLE * sizeof(double)); | |
| 7eb9c17b SK |
66 | |
| 67 | memset(cdx, 0, NSAMPLE * sizeof(double complex)); | |
| 68 | memset(cdy, 0, NSAMPLE * sizeof(double complex)); | |
| 69 | memset(cdz, 0, NSAMPLE * sizeof(double complex)); | |
| 70 | ||
| 3cef403e SK |
71 | memset(start, 0, NSAMPLE * sizeof(struct timeval)); |
| 72 | memset(end, 0, NSAMPLE * sizeof(struct timeval)); | |
| 11518169 SK |
73 | } |
| 74 | ||
| 75 | static void | |
| 76 | cleanup(void) | |
| 77 | { | |
| 78 | assert(dx && dy && dz && start && end); | |
| 79 | ||
| 7eb9c17b SK |
80 | free(dx); free(dy); free(dz); |
| 81 | free(cdx); free(cdy); free(cdz); | |
| 11518169 SK |
82 | free(start); |
| 83 | free(end); | |
| 84 | ||
| 85 | dx = dy = dz = NULL; | |
| 7eb9c17b | 86 | cdx = cdy = cdz = NULL; |
| 11518169 SK |
87 | start = end = NULL; |
| 88 | } | |
| 89 | ||
| 90 | static int | |
| 91 | proffunc(const char *fname) | |
| 92 | { | |
| 93 | const struct fentry *f; | |
| 94 | FILE *fp; | |
| 95 | size_t i, j; | |
| 96 | ||
| 97 | /* Lookup the function */ | |
| 98 | f = getfunctionbyname(fname); | |
| 99 | if (f == NULL) | |
| 100 | return (-1); | |
| 101 | ||
| 102 | /* Zero out the arrays we will be writing at */ | |
| 103 | reset(); | |
| 104 | ||
| 105 | /* Generate random input -- do it before hand */ | |
| 106 | for (i = 0; i < NSAMPLE; i++) { | |
| 7eb9c17b SK |
107 | if (f->f_mpfr) { |
| 108 | if (f->f_narg == 1) { | |
| 109 | do { | |
| 110 | dx[i] = random_double(FP_NORMAL); | |
| 111 | } while (!f->f_u.fp1(dx[i])); | |
| 112 | } | |
| 113 | if (f->f_narg >= 2) { | |
| 114 | do { | |
| 115 | dx[i] = random_double(FP_NORMAL); | |
| 116 | dy[i] = random_double(FP_NORMAL); | |
| 117 | } while (!f->f_u.fp2(dx[i], dy[i])); | |
| 118 | } | |
| 119 | } else { | |
| 120 | if (f->f_narg == 1) { | |
| 121 | do { | |
| 122 | cdx[i] = random_double_complex(FP_NORMAL); | |
| 123 | } while (!f->f_uc.fp1(cdx[i])); | |
| 124 | } | |
| 125 | if (f->f_narg >= 2) { | |
| 126 | do { | |
| 127 | cdx[i] = random_double_complex(FP_NORMAL); | |
| 128 | cdy[i] = random_double_complex(FP_NORMAL); | |
| 129 | } while (!f->f_uc.fp2(cdx[i], cdy[i])); | |
| 130 | } | |
| 11518169 SK |
131 | } |
| 132 | } | |
| 133 | ||
| 134 | /* Ready to go */ | |
| 135 | for (i = 0; i < NSAMPLE; i++) { | |
| 136 | MARK_START(&start[i]); | |
| 137 | ||
| 9acd27ff | 138 | for (j = 0; j < 1000; j++) { |
| 7eb9c17b SK |
139 | if (f->f_mpfr) { |
| 140 | if (f->f_narg == 1) { | |
| 141 | dz[i] = f->f_libm_real(dx[i]); | |
| 142 | } else { | |
| 143 | dz[i] = f->f_libm_real(dx[i], dy[i]); | |
| 144 | } | |
| 11518169 | 145 | } else { |
| 7eb9c17b SK |
146 | if (f->f_narg == 1) { |
| 147 | cdz[i] = f->f_libm_complex(cdx[i]); | |
| 148 | } else { | |
| 149 | cdz[i] = f->f_libm_complex(cdx[i], cdy[i]); | |
| 150 | } | |
| 11518169 SK |
151 | } |
| 152 | } | |
| 3f73d225 | 153 | |
| 11518169 SK |
154 | MARK_END(&end[i]); |
| 155 | } | |
| 156 | ||
| 157 | /* Calculate diffs and dump them to the file */ | |
| 9acd27ff | 158 | char buf[256]; |
| 159 | snprintf(buf, sizeof(buf), "%s.csv", fname); | |
| 160 | fp = fopen(buf, "w"); | |
| 3f73d225 | 161 | assert(fp); |
| 11518169 | 162 | |
| 7eb9c17b SK |
163 | if (f->f_mpfr) |
| 164 | fprintf(fp, "#%d\n", f->f_narg); | |
| 165 | else | |
| 166 | fprintf(fp, "#%d\n", f->f_narg + 1); | |
| 167 | ||
| 11518169 | 168 | for (i = 0; i < NSAMPLE; i++) { |
| 7eb9c17b SK |
169 | if (f->f_mpfr) { |
| 170 | if (fpclassify(dz[i]) != FP_NORMAL) | |
| 9acd27ff | 171 | continue; |
| 7eb9c17b SK |
172 | |
| 173 | if (f->f_narg == 1) { | |
| 174 | fprintf(fp, "% .16e % ld\n", | |
| 175 | dx[i], USECS(start[i], end[i])); | |
| 176 | } else { | |
| 177 | fprintf(fp, "%.16e %.16e %ld\n", | |
| 178 | dx[i], dy[i], USECS(start[i], end[i])); | |
| 179 | } | |
| 180 | } else { | |
| 181 | if ((fpclassify(creal(cdz[i])) != FP_NORMAL) || | |
| 182 | fpclassify(cimag(cdz[i])) != FP_NORMAL) | |
| 9acd27ff | 183 | continue; |
| 7eb9c17b SK |
184 | |
| 185 | if (f->f_narg == 1) { | |
| 186 | fprintf(fp, "% .16e % .16e % ld\n", | |
| 187 | creal(cdx[i]), cimag(cdx[i]), | |
| 188 | USECS(start[i], end[i])); | |
| 189 | } else { | |
| 190 | fprintf(fp, "%.16e %.16e %.16e %.16e %ld\n", | |
| 191 | creal(cdx[i]), cimag(cdx[i]), | |
| 192 | creal(cdy[i]), cimag(cdy[i]), | |
| 193 | USECS(start[i], end[i])); | |
| 194 | } | |
| 9acd27ff | 195 | } |
| 11518169 SK |
196 | } |
| 197 | ||
| 3cef403e | 198 | /* Success */ |
| 11518169 SK |
199 | return (0); |
| 200 | } | |
| 201 | ||
| 202 | int | |
| 203 | main(int argc, char *argv[]) | |
| 204 | { | |
| 205 | int i, rv, total, all; | |
| 206 | const char *target; | |
| 5d753d56 | 207 | const struct fentry *f; |
| 11518169 SK |
208 | |
| 209 | /* Skip program name */ | |
| 210 | argv++; | |
| 211 | argc--; | |
| 212 | ||
| 213 | /* | |
| 214 | * If none argument or "all" is given, then we assume | |
| 215 | * that all functions should be probed. | |
| 216 | */ | |
| 217 | all = 0; | |
| 218 | if (argc == 0 || (argc == 1 && !strcmp(argv[0], "all"))) { | |
| 219 | argv++; | |
| 220 | argc--; | |
| 221 | ||
| 222 | all = 1; | |
| 223 | } | |
| 224 | ||
| 225 | /* Initialize random number generator */ | |
| 226 | init_randgen(); | |
| 227 | ||
| 228 | /* Allocate memory */ | |
| 3cef403e | 229 | init_arrays(); |
| 11518169 SK |
230 | |
| 231 | total = all ? fsize : argc; | |
| 232 | ||
| 233 | for (i = 0; i < total; i++) { | |
| 5d753d56 | 234 | f = getfunctionbyidx(i); |
| 235 | target = all ? f->f_name : argv[i]; | |
| 262ef9e7 | 236 | printf("[%2d/%2d] %-10s : ", i+1, total, target); |
| 237 | fflush(stdout); | |
| 11518169 SK |
238 | rv = proffunc(target); |
| 239 | if (rv != -1) { | |
| 262ef9e7 | 240 | printf("OK\n"); |
| 11518169 SK |
241 | } else { |
| 242 | fprintf(stderr, "function: %s not probed -- skipping\n", | |
| 243 | argv[i]); | |
| 244 | continue; | |
| 245 | } | |
| 246 | } | |
| 247 | ||
| 248 | /* Free up resources */ | |
| 249 | cleanup(); | |
| 250 | ||
| 251 | return (EXIT_SUCCESS); | |
| 252 | } |