10 #include "subr_random.h"
12 #define NSAMPLE (1*1000)
15 * They are esentially the same, but we still define them as if
16 * they were different, for conceptual consistency and clarity.
18 #define MARK_START(tv1) \
19 assert(gettimeofday(tv1, NULL) == 0);
21 #define MARK_END(tv2) \
22 assert(gettimeofday(tv2, NULL) == 0);
24 #define USECS(tv1, tv2) \
25 (((tv2).tv_sec - (tv1).tv_sec ) * 1000000 + \
26 ((tv2).tv_usec - (tv1).tv_usec))
29 * Make these globals, so that we allocate memory only once
30 * during the program's lifetime.
35 double complex *cdx = NULL;
36 double complex *cdy = NULL;
37 double complex *cdz = NULL;
38 struct timeval *start = NULL;
39 struct timeval *end = NULL;
44 dx = malloc(NSAMPLE * sizeof(double));
45 dy = malloc(NSAMPLE * sizeof(double));
46 dz = malloc(NSAMPLE * sizeof(double));
48 cdx = malloc(NSAMPLE * sizeof(double complex));
49 cdy = malloc(NSAMPLE * sizeof(double complex));
50 cdz = malloc(NSAMPLE * sizeof(double complex));
52 start = malloc(NSAMPLE * sizeof(struct timeval));
53 end = malloc(NSAMPLE * sizeof(struct timeval));
55 assert(dx && dy && dz && start && end);
61 assert(dx && dy && dz && start && end);
63 memset(dx, 0, NSAMPLE * sizeof(double));
64 memset(dy, 0, NSAMPLE * sizeof(double));
65 memset(dz, 0, NSAMPLE * sizeof(double));
67 memset(cdx, 0, NSAMPLE * sizeof(double complex));
68 memset(cdy, 0, NSAMPLE * sizeof(double complex));
69 memset(cdz, 0, NSAMPLE * sizeof(double complex));
71 memset(start, 0, NSAMPLE * sizeof(struct timeval));
72 memset(end, 0, NSAMPLE * sizeof(struct timeval));
78 assert(dx && dy && dz && start && end);
80 free(dx); free(dy); free(dz);
81 free(cdx); free(cdy); free(cdz);
86 cdx = cdy = cdz = NULL;
91 proffunc(const char *fname)
93 const struct fentry *f;
97 /* Lookup the function */
98 f = getfunctionbyname(fname);
102 /* Zero out the arrays we will be writing at */
105 /* Generate random input -- do it before hand */
106 for (i = 0; i < NSAMPLE; i++) {
108 if (f->f_narg == 1) {
110 dx[i] = random_double(FP_NORMAL);
111 } while (!f->f_u.fp1(dx[i]));
113 if (f->f_narg >= 2) {
115 dx[i] = random_double(FP_NORMAL);
116 dy[i] = random_double(FP_NORMAL);
117 } while (!f->f_u.fp2(dx[i], dy[i]));
120 if (f->f_narg == 1) {
122 cdx[i] = random_double_complex(FP_NORMAL);
123 } while (!f->f_uc.fp1(cdx[i]));
125 if (f->f_narg >= 2) {
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]));
135 for (i = 0; i < NSAMPLE; i++) {
136 MARK_START(&start[i]);
138 for (j = 0; j < 1000; j++) {
140 if (f->f_narg == 1) {
141 dz[i] = f->f_libm_real(dx[i]);
143 dz[i] = f->f_libm_real(dx[i], dy[i]);
146 if (f->f_narg == 1) {
147 cdz[i] = f->f_libm_complex(cdx[i]);
149 cdz[i] = f->f_libm_complex(cdx[i], cdy[i]);
157 /* Calculate diffs and dump them to the file */
159 snprintf(buf, sizeof(buf), "%s.csv", fname);
160 fp = fopen(buf, "w");
164 fprintf(fp, "#%d\n", f->f_narg);
166 fprintf(fp, "#%d\n", f->f_narg + 1);
168 for (i = 0; i < NSAMPLE; i++) {
170 if (fpclassify(dz[i]) != FP_NORMAL)
173 if (f->f_narg == 1) {
174 fprintf(fp, "% .16e % ld\n",
175 dx[i], USECS(start[i], end[i]));
177 fprintf(fp, "%.16e %.16e %ld\n",
178 dx[i], dy[i], USECS(start[i], end[i]));
181 if ((fpclassify(creal(cdz[i])) != FP_NORMAL) ||
182 fpclassify(cimag(cdz[i])) != FP_NORMAL)
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]));
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]));
203 main(int argc, char *argv[])
205 int i, rv, total, all;
207 const struct fentry *f;
209 /* Skip program name */
214 * If none argument or "all" is given, then we assume
215 * that all functions should be probed.
218 if (argc == 0 || (argc == 1 && !strcmp(argv[0], "all"))) {
225 /* Initialize random number generator */
228 /* Allocate memory */
231 total = all ? fsize : argc;
233 for (i = 0; i < total; i++) {
234 f = getfunctionbyidx(i);
235 target = all ? f->f_name : argv[i];
236 printf("[%2d/%2d] %-10s : ", i+1, total, target);
238 rv = proffunc(target);
242 fprintf(stderr, "function: %s not probed -- skipping\n",
248 /* Free up resources */
251 return (EXIT_SUCCESS);