4 #include <isl/stream.h>
5 #include <isl/options.h>
6 #include <barvinok/options.h>
7 #include <barvinok/util.h>
11 #ifdef HAVE_SYS_TIMES_H
13 #include <sys/times.h>
15 typedef clock_t my_clock_t
;
17 static my_clock_t
time_diff(struct tms
*before
, struct tms
*after
)
19 return after
->tms_utime
- before
->tms_utime
;
24 typedef int my_clock_t
;
27 static void times(struct tms
* time
)
30 static my_clock_t
time_diff(struct tms
*before
, struct tms
*after
)
40 { ISL_BOUND_BERNSTEIN
},
44 #define nr_methods (sizeof(methods)/sizeof(*methods))
47 struct verify_options
*verify
;
51 ISL_ARGS_START(struct options
, options_args
)
52 ISL_ARG_CHILD(struct options
, verify
, NULL
, &verify_options_args
, NULL
)
53 ISL_ARG_BOOL(struct options
, quiet
, 'q', "quiet", 0, NULL
)
56 ISL_ARG_DEF(options
, struct options
, options_args
)
60 double RE_sum
[nr_methods
];
62 my_clock_t ticks
[nr_methods
];
63 size_t size
[nr_methods
];
66 void result_data_init(isl_ctx
*ctx
, struct result_data
*result
)
69 for (i
= 0; i
< nr_methods
; ++i
) {
70 result
->RE_sum
[i
] = 0;
74 result
->n
= isl_val_zero(ctx
);
77 void result_data_clear(struct result_data
*result
)
79 isl_val_free(result
->n
);
82 void result_data_print(struct result_data
*result
, int n
)
86 fprintf(stderr
, "%g", (double)result
->ticks
[0]/n
);
87 for (i
= 1; i
< nr_methods
; ++i
)
88 fprintf(stderr
, ", %g", (double)result
->ticks
[i
]/n
);
89 fprintf(stderr
, "\n");
91 fprintf(stderr
, "%zd/%d", result
->size
[0], n
);
92 for (i
= 1; i
< nr_methods
; ++i
)
93 fprintf(stderr
, ", %zd/%d", result
->size
[i
], n
);
94 fprintf(stderr
, "\n");
96 fprintf(stderr
, "%g\n", isl_val_get_d(result
->n
));
97 fprintf(stderr
, "%g", result
->RE_sum
[0]/isl_val_get_d(result
->n
));
98 for (i
= 1; i
< nr_methods
; ++i
)
99 fprintf(stderr
, ", %g", result
->RE_sum
[i
]/isl_val_get_d(result
->n
));
100 fprintf(stderr
, "\n");
103 struct verify_point_bound
{
104 struct verify_point_data vpd
;
105 struct result_data
*result
;
106 isl_pw_qpolynomial
*pwqp
;
107 isl_pw_qpolynomial_fold
**pwf
;
110 static int verify_point(__isl_take isl_point
*pnt
, void *user
)
112 struct verify_point_bound
*vpb
= (struct verify_point_bound
*) user
;
113 const struct verify_options
*options
= vpb
->vpd
.options
;
116 isl_val
*max
, *min
, *exact
, *approx
, *t
;
117 isl_pw_qpolynomial
*pwqp
;
122 pwqp
= isl_pw_qpolynomial_copy(vpb
->pwqp
);
124 nparam
= isl_pw_qpolynomial_dim(pwqp
, isl_dim_param
);
125 for (i
= 0; i
< nparam
; ++i
) {
126 t
= isl_point_get_coordinate_val(pnt
, isl_dim_param
, i
);
127 pwqp
= isl_pw_qpolynomial_fix_val(pwqp
, isl_dim_param
, i
, t
);
130 max
= isl_pw_qpolynomial_max(isl_pw_qpolynomial_copy(pwqp
));
131 max
= isl_val_floor(max
);
133 min
= isl_pw_qpolynomial_min(pwqp
);
134 min
= isl_val_ceil(min
);
136 exact
= isl_val_sub(isl_val_copy(max
), isl_val_copy(min
));
137 exact
= isl_val_add_ui(exact
, 1);
139 if (options
->print_all
) {
140 p
= isl_printer_to_file(isl_point_get_ctx(pnt
), stderr
);
141 p
= isl_printer_print_str(p
, "max: ");
142 p
= isl_printer_print_val(p
, max
);
143 p
= isl_printer_print_str(p
, ", min: ");
144 p
= isl_printer_print_val(p
, min
);
145 p
= isl_printer_print_str(p
, ", range: ");
146 p
= isl_printer_print_val(p
, exact
);
151 for (i
= 0; i
< nr_methods
; ++i
) {
154 max
= isl_pw_qpolynomial_fold_eval(
155 isl_pw_qpolynomial_fold_copy(vpb
->pwf
[2 * i
]),
156 isl_point_copy(pnt
));
157 max
= isl_val_floor(max
);
159 min
= isl_pw_qpolynomial_fold_eval(
160 isl_pw_qpolynomial_fold_copy(vpb
->pwf
[2 * i
+ 1]),
161 isl_point_copy(pnt
));
162 min
= isl_val_ceil(min
);
164 approx
= isl_val_sub(max
, min
);
165 approx
= isl_val_add_ui(approx
, 1);
166 if (options
->print_all
) {
167 p
= isl_printer_print_str(p
, ", ");
168 p
= isl_printer_print_val(p
, approx
);
171 assert(isl_val_ge(approx
, exact
));
172 approx
= isl_val_sub(approx
, isl_val_copy(exact
));
174 error
= fabs(isl_val_get_d(approx
)) / isl_val_get_d(exact
);
175 if (options
->print_all
)
176 fprintf(stderr
, " (%g)", error
);
177 vpb
->result
->RE_sum
[i
] += error
;
179 isl_val_free(approx
);
182 if (options
->print_all
) {
183 p
= isl_printer_end_line(p
);
185 } else if ((vpb
->vpd
.n
% vpb
->vpd
.s
) == 0) {
193 return vpb
->vpd
.n
>= 1 ? 0 : -1;
196 static void test(__isl_keep isl_pw_qpolynomial
*pwqp
,
197 __isl_keep isl_pw_qpolynomial_fold
**pwf
, struct result_data
*result
,
198 struct verify_options
*options
)
200 struct verify_point_bound vpb
= { { options
}, result
};
206 context
= isl_pw_qpolynomial_domain(isl_pw_qpolynomial_copy(vpb
.pwqp
));
207 context
= isl_set_params(context
);
208 context
= verify_context_set_bounds(context
, options
);
210 r
= verify_point_data_init(&vpb
.vpd
, context
);
212 result
->n
= isl_val_set_si(result
->n
, vpb
.vpd
.n
);
214 isl_set_foreach_point(context
, verify_point
, &vpb
);
215 assert(!vpb
.vpd
.error
);
217 isl_set_free(context
);
219 verify_point_data_fini(&vpb
.vpd
);
222 static void handle(isl_ctx
*ctx
, FILE *in
, struct result_data
*result
,
223 struct verify_options
*options
)
226 isl_pw_qpolynomial
*pwqp
, *upper
, *lower
;
227 isl_pw_qpolynomial_fold
*pwf
[2*nr_methods
];
228 struct isl_stream
*s
;
230 s
= isl_stream_new_file(ctx
, in
);
231 pwqp
= isl_stream_read_pw_qpolynomial(s
);
233 upper
= isl_pw_qpolynomial_to_polynomial(isl_pw_qpolynomial_copy(pwqp
), 1);
234 lower
= isl_pw_qpolynomial_to_polynomial(isl_pw_qpolynomial_copy(pwqp
), -1);
236 for (i
= 0; i
< nr_methods
; ++i
) {
242 for (j
= 0; j
< 2; ++j
) {
243 isl_pw_qpolynomial
*poly
= j
== 0 ? upper
: lower
;
244 enum isl_fold type
= j
== 0 ? isl_fold_max
: isl_fold_min
;
245 isl_options_set_bound(ctx
, methods
[i
].method
);
246 poly
= isl_pw_qpolynomial_copy(poly
);
247 pwf
[2*i
+j
] = isl_pw_qpolynomial_bound(poly
, type
, NULL
);
250 result
->ticks
[i
] = time_diff(&en_cpu
, &st_cpu
);
251 result
->size
[i
] = isl_pw_qpolynomial_fold_size(pwf
[2*i
]);
252 result
->size
[i
] = isl_pw_qpolynomial_fold_size(pwf
[2*i
+1]);
253 if (options
->barvinok
->verbose
) {
254 isl_printer
*p
= isl_printer_to_file(ctx
, stdout
);
255 for (j
= 0; j
< 2; ++j
) {
256 p
= isl_printer_print_pw_qpolynomial_fold(p
, pwf
[2*i
+j
]);
257 p
= isl_printer_end_line(p
);
262 test(pwqp
, pwf
, result
, options
);
264 for (i
= 0; i
< 2*nr_methods
; ++i
)
265 isl_pw_qpolynomial_fold_free(pwf
[i
]);
266 isl_pw_qpolynomial_free(pwqp
);
267 isl_pw_qpolynomial_free(lower
);
268 isl_pw_qpolynomial_free(upper
);
273 int main(int argc
, char **argv
)
275 char path
[PATH_MAX
+1];
276 struct result_data all_result
;
278 struct options
*options
= options_new_with_defaults();
279 isl_ctx
*ctx
= isl_ctx_alloc();
281 argc
= options_parse(options
, argc
, argv
, ISL_ARG_ALL
);
283 if (options
->verify
->M
== INT_MIN
)
284 options
->verify
->M
= 100;
285 if (options
->verify
->m
== INT_MAX
)
286 options
->verify
->m
= -100;
288 result_data_init(ctx
, &all_result
);
290 while (fgets(path
, sizeof(path
), stdin
)) {
291 struct result_data result
;
296 result_data_init(ctx
, &result
);
297 fprintf(stderr
, "%s", path
);
298 *strchr(path
, '\n') = '\0';
299 in
= fopen(path
, "r");
301 handle(ctx
, in
, &result
, options
->verify
);
305 result_data_print(&result
, 1);
307 all_result
.n
= isl_val_add(all_result
.n
, isl_val_copy(result
.n
));
308 for (i
= 0; i
< nr_methods
; ++i
) {
309 all_result
.RE_sum
[i
] += result
.RE_sum
[i
];
310 all_result
.ticks
[i
] += result
.ticks
[i
];
311 all_result
.size
[i
] += result
.size
[i
];
314 result_data_clear(&result
);
316 if (!options
->quiet
) {
317 fprintf(stderr
, "average\n");
318 result_data_print(&all_result
, n
);
322 result_data_clear(&all_result
);
324 options_free(options
);