Polly 23.0.0git
isl_test2.cc
Go to the documentation of this file.
1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
4 * Copyright 2012-2013 Ecole Normale Superieure
5 * Copyright 2014 INRIA Rocquencourt
6 * Copyright 2021-2022 Cerebras Systems
7 *
8 * Use of this software is governed by the MIT license
9 *
10 * Written by Sven Verdoolaege, K.U.Leuven, Departement
11 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
12 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
13 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
14 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
15 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
16 * B.P. 105 - 78153 Le Chesnay, France
17 * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
18 */
19
20#include <assert.h>
21#include <stdlib.h>
22
23#include <functional>
24#include <ios>
25#include <iostream>
26#include <sstream>
27#include <string>
28#include <type_traits>
29#include <utility>
30#include <vector>
31
32#include <isl/cpp.h>
33
34/* A binary isl function that appears in the C++ bindings
35 * as a unary method in a class T, taking an extra argument
36 * of type A1 and returning an object of type R.
37 */
38template <typename A1, typename R, typename T>
39using binary_fn = R (T::*)(A1) const;
40
41/* A function for selecting an overload of a pointer to a unary C++ method
42 * based on the single argument type.
43 * The object type and the return type are meant to be deduced.
44 */
45template <typename A1, typename R, typename T>
47{
48 return fn;
49}
50
51/* A ternary isl function that appears in the C++ bindings
52 * as a binary method in a class T, taking extra arguments
53 * of type A1 and A2 and returning an object of type R.
54 */
55template <typename A1, typename A2, typename R, typename T>
56using ternary_fn = R (T::*)(A1, A2) const;
57
58/* A function for selecting an overload of a pointer to a binary C++ method
59 * based on the (first) argument type(s).
60 * The object type and the return type are meant to be deduced.
61 */
62template <typename A1, typename A2, typename R, typename T>
64{
65 return fn;
66}
67
68/* A description of the input and the output of a unary property.
69 */
70struct unary_prop {
71 const char *arg;
72 bool res;
73};
74
75/* A description of the input and the output of a unary operation.
76 */
77struct unary {
78 const char *arg;
79 const char *res;
80};
81
82/* A description of the inputs and the output of a binary operation.
83 */
84struct binary {
85 const char *arg1;
86 const char *arg2;
87 const char *res;
88};
89
90/* A description of the inputs and the output of a ternary operation.
91 */
92struct ternary {
93 const char *arg1;
94 const char *arg2;
95 const char *arg3;
96 const char *res;
97};
98
99/* A template function for checking whether two objects
100 * of the same (isl) type are (obviously) equal.
101 * The spelling depends on the isl type and
102 * in particular on whether an equality method is available or
103 * whether only obvious equality can be tested.
104 *
105 * Since isl::multi_val has both an is_equal and a plain_is_equal,
106 * use a specific overload for isl::multi_val that calls is_equal.
107 */
108template <typename T, typename std::decay<decltype(
109 std::declval<T>().is_equal(std::declval<T>()))>::type = true>
110static bool is_equal(const T &a, const T &b)
111{
112 return a.is_equal(b);
113}
114template <typename T, typename std::decay<decltype(
115 std::declval<T>().plain_is_equal(std::declval<T>()))>::type = true>
116static bool is_equal(const T &a, const T &b)
117{
118 return a.plain_is_equal(b);
119}
120static bool is_equal(const isl::multi_val &a, const isl::multi_val &b)
121{
122 return a.is_equal(b);
123}
124
125/* A helper macro for throwing an isl::exception_invalid with message "msg".
126 */
127#define THROW_INVALID(msg) \
128 isl::exception::throw_error(isl_error_invalid, msg, __FILE__, __LINE__)
129
130/* Run a sequence of tests of function "fn" with stringification "name" and
131 * with input and output described by "tests",
132 * throwing an exception when an unexpected result is produced.
133 */
134template <typename T>
135static void test(isl::ctx ctx, bool fn(const T &), const std::string &name,
136 const std::vector<unary_prop> &tests)
137{
138 for (const auto &test : tests) {
139 T obj(ctx, test.arg);
140 bool res = fn(obj);
141 std::ostringstream ss;
142
143 if (test.res == res)
144 continue;
145
146 ss << name << "(" << test.arg << ") = "
147 << std::boolalpha << res << "\n"
148 << "expecting: "
149 << test.res;
150 THROW_INVALID(ss.str().c_str());
151 }
152}
153
154/* Run a sequence of tests of method "fn" with stringification "name" and
155 * with input and output described by "test",
156 * throwing an exception when an unexpected result is produced.
157 */
158template <typename R, typename T>
159static void test(isl::ctx ctx, R (T::*fn)() const, const std::string &name,
160 const std::vector<unary> &tests)
161{
162 for (const auto &test : tests) {
163 T obj(ctx, test.arg);
164 R expected(ctx, test.res);
165 const auto &res = (obj.*fn)();
166 std::ostringstream ss;
167
168 if (is_equal(expected, res))
169 continue;
170
171 ss << name << "(" << test.arg << ") =\n"
172 << res << "\n"
173 << "expecting:\n"
174 << expected;
175 THROW_INVALID(ss.str().c_str());
176 }
177}
178
179/* Run a sequence of tests of method "fn" with stringification "name" and
180 * with inputs and output described by "test",
181 * throwing an exception when an unexpected result is produced.
182 */
183template <typename R, typename T, typename A1>
184static void test(isl::ctx ctx, R (T::*fn)(A1) const, const std::string &name,
185 const std::vector<binary> &tests)
186{
187 for (const auto &test : tests) {
188 T obj(ctx, test.arg1);
189 A1 arg1(ctx, test.arg2);
190 R expected(ctx, test.res);
191 const auto &res = (obj.*fn)(arg1);
192 std::ostringstream ss;
193
194 if (is_equal(expected, res))
195 continue;
196
197 ss << name << "(" << test.arg1 << ", " << test.arg2 << ") =\n"
198 << res << "\n"
199 << "expecting:\n"
200 << expected;
201 THROW_INVALID(ss.str().c_str());
202 }
203}
204
205/* Run a sequence of tests of function "fn" with stringification "name" and
206 * with inputs and output described by "tests",
207 * throwing an exception when an unexpected result is produced.
208 */
209template <typename R, typename T, typename A1, typename A2, typename F>
210static void test_ternary(isl::ctx ctx, const F &fn,
211 const std::string &name, const std::vector<ternary> &tests)
212{
213 for (const auto &test : tests) {
214 T obj(ctx, test.arg1);
215 A1 arg1(ctx, test.arg2);
216 A2 arg2(ctx, test.arg3);
217 R expected(ctx, test.res);
218 const auto &res = fn(obj, arg1, arg2);
219 std::ostringstream ss;
220
221 if (is_equal(expected, res))
222 continue;
223
224 ss << name << "(" << test.arg1 << ", " << test.arg2 << ", "
225 << test.arg3 << ") =\n"
226 << res << "\n"
227 << "expecting:\n"
228 << expected;
229 THROW_INVALID(ss.str().c_str());
230 }
231}
232
233/* Run a sequence of tests of function "fn" with stringification "name" and
234 * with inputs and output described by "tests",
235 * throwing an exception when an unexpected result is produced.
236 *
237 * Simply call test_ternary.
238 */
239template <typename R, typename T, typename A1, typename A2>
240static void test(isl::ctx ctx, R fn(const T&, const A1&, const A2&),
241 const std::string &name, const std::vector<ternary> &tests)
242{
244}
245
246/* Run a sequence of tests of method "fn" with stringification "name" and
247 * with inputs and output described by "tests",
248 * throwing an exception when an unexpected result is produced.
249 *
250 * Wrap the method pointer into a function taking an object reference and
251 * call test_ternary.
252 */
253template <typename R, typename T, typename A1, typename A2>
254static void test(isl::ctx ctx, R (T::*fn)(A1, A2) const,
255 const std::string &name, const std::vector<ternary> &tests)
256{
257 const auto &wrap = [&] (const T &o, const A1 &arg1, const A2 &arg2) {
258 return (o.*fn)(arg1, arg2);
259 };
261}
262
263/* A helper macro that calls test with as implicit initial argument "ctx" and
264 * as extra argument a stringification of "FN".
265 */
266#define C(FN, ...) test(ctx, FN, #FN, __VA_ARGS__)
267
268/* Perform some basic isl::space tests.
269 */
270static void test_space(isl::ctx ctx)
271{
273 { "{ A[] -> B[] }", "{ A[] }" },
274 { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ A[C[] -> D[]] }" },
275 });
276
278 { "{ A[] -> B[] }", "{ B[] }" },
279 { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ B[E[] -> F[]] }" },
280 });
281
283 { "{ A[] -> B[] }", "{ : }" },
284 { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ : }" },
285 });
286}
287
288/* Is "fn" an expression defined over a single cell?
289 */
291{
292 const auto &domain = fn.domain();
293 return fn.gist(domain).isa_multi_aff();
294}
295
296/* Does the conversion of "obj" to an isl_pw_multi_aff
297 * result in an expression defined over a single cell?
298 */
299template <typename T>
300static bool has_single_cell_pma(const T &obj)
301{
302 return has_single_cell(obj.as_pw_multi_aff());
303}
304
305/* Perform some basic conversion tests.
306 *
307 * In particular, check that a map with an output dimension
308 * that is equal to some integer division over a domain involving
309 * a local variable without a known integer division expression or
310 * to some linear combination of integer divisions
311 * can be converted to a function expressed in the same way.
312 *
313 * Also, check that a nested modulo expression can be extracted
314 * from a set or binary relation representation, or at least
315 * that a conversion to a function does not result in multiple cells.
316 */
317static void test_conversion(isl::ctx ctx)
318{
320 { "[N=0:] -> { [] }",
321 "[N=0:] -> { [] }" },
322 });
323
325 { "[n] -> { [] : n >= 0 } ",
326 "[n] -> { [] : n >= 0 } " },
327 });
328
330 { "{ [a] -> [a//2] : "
331 "exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }",
332 "{ [a] -> [a//2] : "
333 "exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }" },
334 { "{ [a, b] -> [(2*floor((a)/8) + floor((b)/6))] }",
335 "{ [a, b] -> [(2*floor((a)/8) + floor((b)/6))] }" },
336 });
337
339 { "[s=0:23] -> { A[(s//4)%3, s%4, s//12] }", true },
340 });
341
343 { "{ [a] -> [a//2] : "
344 "exists (e0: 8*floor((-a + e0)/8) <= -8 - a + 8e0) }",
345 true },
346 { "{ [s=0:23, t] -> B[((s+1+2t)//4)%3, 2+(s+1+2t)%4, (s+1+2t)//12] }",
347 true },
348 { "{ [a=0:31] -> [b=0:3, c] : 4c = 28 - a + b }", true },
349 });
350}
351
352/* Perform some basic preimage tests.
353 */
354static void test_preimage(isl::ctx ctx)
355{
357 { "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }",
358 "{ A[j,i] -> B[i,j] }",
359 "{ A[j,i] : 0 <= i < 10 and 0 <= j < 100 }" },
360 { "{ rat: B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
361 "{ A[a,b] -> B[a/2,b/6] }",
362 "{ rat: A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 }" },
363 { "{ B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
364 "{ A[a,b] -> B[a/2,b/6] }",
365 "{ A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 and "
366 "exists i,j : a = 2 i and b = 6 j }" },
367 { "[n] -> { S[i] : 0 <= i <= 100 }", "[n] -> { S[n] }",
368 "[n] -> { : 0 <= n <= 100 }" },
369 { "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
370 "{ A[a] -> B[2a] }",
371 "{ A[a] : 0 <= a < 50 and exists b : a = 2 b }" },
372 { "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
373 "{ A[a] -> B[([a/2])] }",
374 "{ A[a] : 0 <= a < 200 and exists b : [a/2] = 4 b }" },
375 { "{ B[i,j,k] : 0 <= i,j,k <= 100 }",
376 "{ A[a] -> B[a,a,a/3] }",
377 "{ A[a] : 0 <= a <= 100 and exists b : a = 3 b }" },
378 { "{ B[i,j] : j = [(i)/2] } ", "{ A[i,j] -> B[i/3,j] }",
379 "{ A[i,j] : j = [(i)/6] and exists a : i = 3 a }" },
380 });
381
383 { "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }",
384 "{ A[j,i] -> B[i,j] : false }",
385 "{ A[j,i] : false }" },
386 });
387
389 { "{ B[i,j] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }",
390 "{ A[j,i] -> B[i,j] }",
391 "{ A[j,i] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }" },
392 { "{ B[i] -> C[i]; D[i] -> E[i] }",
393 "{ A[i] -> B[i + 1] }",
394 "{ A[i] -> C[i + 1] }" },
395 { "{ B[i] -> C[i]; B[i] -> E[i] }",
396 "{ A[i] -> B[i + 1] }",
397 "{ A[i] -> C[i + 1]; A[i] -> E[i + 1] }" },
398 { "{ B[i] -> C[([i/2])] }",
399 "{ A[i] -> B[2i] }",
400 "{ A[i] -> C[i] }" },
401 { "{ B[i,j] -> C[([i/2]), ([(i+j)/3])] }",
402 "{ A[i] -> B[([i/5]), ([i/7])] }",
403 "{ A[i] -> C[([([i/5])/2]), ([(([i/5])+([i/7]))/3])] }" },
404 { "[N] -> { B[i] -> C[([N/2]), i, ([N/3])] }",
405 "[N] -> { A[] -> B[([N/5])] }",
406 "[N] -> { A[] -> C[([N/2]), ([N/5]), ([N/3])] }" },
407 { "{ B[i] -> C[i] : exists a : i = 5 a }",
408 "{ A[i] -> B[2i] }",
409 "{ A[i] -> C[2i] : exists a : 2i = 5 a }" },
410 { "{ B[i] -> C[i] : exists a : i = 2 a; "
411 "B[i] -> D[i] : exists a : i = 2 a + 1 }",
412 "{ A[i] -> B[2i] }",
413 "{ A[i] -> C[2i] }" },
414 { "{ A[i] -> B[i] }", "{ C[i] -> A[(i + floor(i/3))/2] }",
415 "{ C[i] -> B[j] : 2j = i + floor(i/3) }" },
416 });
417
419 { "[M] -> { A[a] -> B[a] }", "[M] -> { C[] -> B[floor(M/2)] }",
420 "[M] -> { A[floor(M/2)] -> C[] }" },
421 });
422}
423
424/* Perform some basic fixed power tests.
425 */
427{
429 { "{ [i] -> [i + 1] }", "23",
430 "{ [i] -> [i + 23] }" },
431 { "{ [a = 0:1, b = 0:15, c = 0:1, d = 0:1, 0] -> [a, b, c, d, 1]; "
432 "[a = 0:1, b = 0:15, c = 0:1, 0, 1] -> [a, b, c, 1, 0]; "
433 "[a = 0:1, b = 0:15, 0, 1, 1] -> [a, b, 1, 0, 0]; "
434 "[a = 0:1, b = 0:14, 1, 1, 1] -> [a, 1 + b, 0, 0, 0]; "
435 "[0, 15, 1, 1, 1] -> [1, 0, 0, 0, 0] }",
436 "128",
437 "{ [0, b = 0:15, c = 0:1, d = 0:1, e = 0:1] -> [1, b, c, d, e] }" },
438 });
439}
440
441/* Perform basic simple fixed box hull tests.
442 */
443static void test_box_hull(isl::ctx ctx)
444{
446 { "{ S[x, y] : 0 <= x, y < 10 }",
447 "{ offset: { S[0, 0] }, size: { S[10, 10] } }" },
448 { "[N] -> { S[x, y] : N <= x, y < N + 10 }",
449 "{ offset: [N] -> { S[(N), (N)] }, size: { S[10, 10] } }" },
450 { "{ S[x, y] : 0 <= x + y, x - y < 10 }",
451 "{ offset: { S[0, -4] }, size: { S[10, 9] } }" },
452 { "{ [i=0:10] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
453 "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }",
454 "{ offset: { [3] }, size: { [8] } }" },
455 { "[N] -> { [w = 0:17] : exists (e0: w < 2N and "
456 "-1 + w <= e0 <= w and 2e0 >= N + w and w <= 2e0 <= 15 + w) }",
457 "{ offset: [N] -> { [N] }, size: { [9] } }" },
458 { "[N] -> { [N//2:N//2+4] }",
459 "{ offset: [N] -> { [N//2] }, size: { [5] } }" },
460 { "[N] -> { [N//2+N//3:N//2+N//3+4] }",
461 "{ offset: [N] -> { [N//2+N//3] }, size: { [5] } }" },
462 { "[N] -> { [a=0:59, b=0:1] : 15N - a <= 60b <= 59 + 15N - a and "
463 "-22 + 20b <= 20*floor((-1 + 15N - a)/60) < 20b and "
464 "60*floor((-1 + 15N - a)/60) <= -46 + 15N - a }",
465 "{ offset: [N] -> { [(15*((N) mod 4)), (floor((N)/4))] }, "
466 "size: { [15, 1] } }" },
467 { "{ [i=-3:7] : i mod 4 = 0 }",
468 "{ offset: { [(0)] }, size: { [5] } }" },
469 { "[N] -> { [i, N - 4i] : -14 + N <= 16i <= 1 + N }",
470 "{ offset: [N] -> { [(floor((1 + N)/16)), "
471 "(4 + N + 4*floor((-2 - N)/16))] }, "
472 "size: { [1, 1] } }" },
473 });
474
476 { "{ [N] -> [i, N - 4i] : -14 + N <= 16i <= 1 + N }",
477 "{ offset: { [N] -> [(floor((1 + N)/16)), "
478 "(4 + N + 4*floor((-2 - N)/16))] }, "
479 "size: { [1, 1] } }" },
480 { "{ [N] -> [i, j] : 4j = N - i and -1 + 3N <= 4i <= 14 + 3N }",
481 "{ offset: { [N] -> [(4 + N + 4*floor((-2 - N)/16)), "
482 "(floor((1 + N)/16))] }, "
483 "size: { [1, 1] } }" },
484 });
485}
486
487/* Perform some coalescing tests.
488 */
489static void test_coalesce(isl::ctx ctx)
490{
491 /* The following sequence can result in the same basic set
492 * appearing multiple times in the coalesced set.
493 * Check that the presence of such duplicates
494 * does not cause internal errors.
495 */
496 isl::set a(ctx, "[g, t] -> { [i] : "
497 "(exists (e0 = floor((1 + g)/2): 2e0 = 1 + g and 0 < i <= -t)) "
498 "or (exists (e0 = floor((1 + g)/2): i = 0 and 2e0 = 1 + g)) }");
499 a = a.coalesce();
500 isl::set b (ctx, "[g, t] -> { [i] : "
501 "(exists (e0 = floor((g)/2): 2e0 = g and 0 < i <= -t)) or "
502 "(exists (e0 = floor((g)/2): i = 0 and 2e0 = g)) }");
503 b.unite(a).unite(a).coalesce();
504}
505
506/* Perform some basic intersection tests.
507 */
508static void test_intersect(isl::ctx ctx)
509{
511 { "[n] -> { A[x] -> B[y] }", "[n] -> { : n >= 0 }",
512 "[n] -> { A[x] -> B[y] : n >= 0 }" },
513 });
514
516 { "{ [A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }",
517 "{ A[0] }",
518 "{ [A[0] -> B[y]] -> C[z] }" },
519 { "{ C[z] -> [A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }",
520 "{ A[0] }",
521 "{ }" },
522 { "{ T[A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }",
523 "{ A[0] }",
524 "{ T[A[0] -> B[y]] -> C[z] }" },
525 });
526
528 { "{ [A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }",
529 "{ A[0] }",
530 "{ }" },
531 { "{ C[z] -> [A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }",
532 "{ A[0] }",
533 "{ C[z] -> [A[0] -> B[y]] }" },
534 { "{ C[z] -> T[A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }",
535 "{ A[0] }",
536 "{ C[z] -> T[A[0] -> B[y]] }" },
537 });
538}
539
540/* Is the expression for the lexicographic minimum of "obj"
541 * defined over a single cell?
542 */
543template <typename T>
544static bool lexmin_has_single_cell(const T &obj)
545{
546 return has_single_cell(obj.lexmin_pw_multi_aff());
547}
548
549/* Perform some basic lexicographic minimization tests.
550 */
551static void test_lexmin(isl::ctx ctx)
552{
554 /* The following two inputs represent the same binary relation,
555 * the second with extra redundant constraints.
556 * The lexicographic minimum of both should consist of a single cell.
557 */
558 { "{ [a=0:11] -> [b] : -1 + b <= 2*floor((a)/6) <= b }", true },
559 { "{ [a=0:11] -> [b=0:3] : -1 + b <= 2*floor((a)/6) <= b }", true },
560
561 { "{ [a = 0:2, b = 0:1] -> [c = 0:9, d = (-a + b) mod 3] : "
562 "10a + 5b - 3c <= 5d <= 12 + 10a + 5b - 3c }", true },
563 { "{ [a=0:71] -> [(a//3)%8] }", true },
564 { "{ [a=0:71] -> [b=0:7] : (a - 3 * b + 21) % 24 >= 21 }", true },
565 { "{ [a=0:71] -> [b=0:7] : (a - 3 * b + 21) % 24 >= 20 }", false },
566 { "{ [a=0:71] -> [b=0:7] : (a - 3 * b + 21) % 24 >= 22 }", true },
567 { "{ [a=0:71] -> [b=-7:0] : (a + 3 * b + 21) % 24 >= 21 }", true },
568 { "{ [a=0:71] -> [b=-7:0] : (a + 3 * b + 21) % 24 >= 20 }", false },
569 { "{ [a=0:71] -> [b=-7:0] : (a + 3 * b + 21) % 24 >= 22 }", true },
570 });
571
573 /* The following two inputs represent the same binary relation,
574 * the second with some redundant constraints removed.
575 * The lexicographic minimum of both should consist of a single cell.
576 */
577 { "{ [a=0:3] -> [b=a//2] : 0 <= b <= 1 }",
578 "{ [a=0:3] -> [(floor((a)/2))] }" },
579 { "{ [a] -> [b=a//2] : 0 <= b <= 1 }",
580 "{ [a=0:3] -> [(floor((a)/2))] }" },
581
582 { "{ [a = 0:2, b = 0:1] -> [c = 0:9, d = (-a + b) mod 3] : "
583 "10a + 5b - 3c <= 5d <= 12 + 10a + 5b - 3c }",
584 "{ [a = 0:2, b = 0:1] -> [5*(2a + b)//3, (2a + b) mod 3] }" },
585 { "{ [a=0:71] -> [(a//3)%8] }",
586 "{ [a=0:71] -> [(a//3)%8] }" },
587 { "{ [a=0:71] -> [b=0:7] : (a - 3 * b + 21) % 24 >= 21 }",
588 "{ [a=0:71] -> [(a//3)%8] }" },
589 { "{ [a=0:71] -> [b=0:7] : (a - 3 * b + 21) % 24 >= 22 }",
590 "{ [a=0:71] -> [(a//3)%8] : a % 3 > 0 }" },
591 { "{ [a=0:71] -> [b=-7:0] : (a + 3 * b + 21) % 24 >= 21 }",
592 "{ [a=0:71] -> [(-7 + (-1 - floor((a)/3)) mod 8)] }" },
593 });
594
596 { "[a] -> { [b=a//2] : 0 <= b <= 1 }",
597 "[a=0:3] -> { [(floor((a)/2))] }" },
598 { "[a=0:71] -> { [(a//3)%8] }",
599 "[a=0:71] -> { [(a//3)%8] }" },
600 { "[a=0:71] -> { [b=0:7] : (a - 3 * b + 21) % 24 >= 21 }",
601 "[a=0:71] -> { [(a//3)%8] }" },
602 });
603}
604
605/* Compute the gist of "obj" with respect to "context",
606 * with "copy" an independent copy of "obj",
607 * but also check that applying the gist operation does
608 * not modify the input set (an earlier version of isl would do that) and
609 * that the test case is consistent, i.e., that the gist has the same
610 * intersection with the context as the input set.
611 */
612template <typename T>
613T gist(const T &obj, const T &copy, const T &context)
614{
615 const auto &res = obj.gist(context);
616 if (!is_equal(obj, copy)) {
617 std::ostringstream ss;
618 ss << "gist changed " << copy << " into " << obj;
619 THROW_INVALID(ss.str().c_str());
620 }
621 if (!is_equal(obj.intersect(context), res.intersect(context))) {
622 std::ostringstream ss;
623 ss << "inconsistent "
624 << obj << " % " << context << " = " << res;
625 THROW_INVALID(ss.str().c_str());
626 }
627 return res;
628}
629
630/* A helper macro for producing two instances of "x".
631 */
632#define TWO(x) (x), (x)
633
634/* Perform some basic gist tests.
635 *
636 * The gist() function is given two identical inputs so that
637 * it can check that the input to the call to the gist method
638 * is not modified.
639 */
640static void test_gist(isl::ctx ctx)
641{
643 { TWO("{ [i=100:] }"),
644 "{ [i] : exists a, b: 2b > 2i - 5a > 8b -3 i and 3b > 2a }",
645 "{ [i=100:] }" },
646 { TWO("{ [i=0:] }"),
647 "{ [i] : exists a, b: 2b > 2i - 5a > 8b -3 i and 3b > 2a }",
648 "{ [i] }" },
649 { TWO("{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
650 "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }"),
651 "{ [i] : i >= 0 }",
652 "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
653 "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }" },
654 { TWO("{ [i=0:10] : exists a, b: 2b > 2i - 5a > 8b -3 i and 3b > 2a }"),
655 "{ [i=0:10] }",
656 "{ [i] : exists a, b: 2b > 2i - 5a > 8b -3 i and 3b > 2a }" },
657 });
658
659 C(&gist<isl::set> , {
660 { TWO("{ [1, -1, 3] }"),
661 "{ [1, b, 2 - b] : -1 <= b <= 2 }",
662 "{ [a, -1, c] }" },
663 { TWO("{ [a, b, c] : a <= 15 and a >= 1 }"),
664 "{ [a, b, c] : exists (e0 = floor((-1 + a)/16): a >= 1 and "
665 "c <= 30 and 32e0 >= -62 + 2a + 2b - c and b >= 0) }",
666 "{ [a, b, c] : a <= 15 }" },
667 { TWO("{ : }"), "{ : 1 = 0 }", "{ : }" },
668 { TWO("{ : 1 = 0 }"), "{ : 1 = 0 }", "{ : }" },
669 { TWO("[M] -> { [x] : exists (e0 = floor((-2 + x)/3): 3e0 = -2 + x) }"),
670 "[M] -> { [3M] }" , "[M] -> { [x] : 1 = 0 }" },
671 { TWO("{ [m, n, a, b] : a <= 2147 + n }"),
672 "{ [m, n, a, b] : (m >= 1 and n >= 1 and a <= 2148 - m and "
673 "b <= 2148 - n and b >= 0 and b >= 2149 - n - a) or "
674 "(n >= 1 and a >= 0 and b <= 2148 - n - a and "
675 "b >= 0) }",
676 "{ [m, n, ku, kl] }" },
677 { TWO("{ [a, a, b] : a >= 10 }"),
678 "{ [a, b, c] : c >= a and c <= b and c >= 2 }",
679 "{ [a, a, b] : a >= 10 }" },
680 { TWO("{ [i, j] : i >= 0 and i + j >= 0 }"), "{ [i, j] : i <= 0 }",
681 "{ [0, j] : j >= 0 }" },
682 /* Check that no constraints on i6 are introduced in the gist */
683 { TWO("[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): "
684 "20e0 <= 1530 - 4t1 - 5i4 and 20e0 >= 1511 - 4t1 - 5i4 and "
685 "5e0 <= 381 - t1 and i4 <= 1) }"),
686 "[t1] -> { [i4, i6] : exists (e0 = floor((-t1 + i6)/5): "
687 "5e0 = -t1 + i6 and i6 <= 6 and i6 >= 3) }",
688 "[t1] -> { [i4, i6] : exists (e0 = floor((1530 - 4t1 - 5i4)/20): "
689 "i4 <= 1 and 5e0 <= 381 - t1 and 20e0 <= 1530 - 4t1 - 5i4 and "
690 "20e0 >= 1511 - 4t1 - 5i4) }" },
691 /* Check that no constraints on i6 are introduced in the gist */
692 { TWO("[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((1 + i4)/2), "
693 "e1 = floor((1530 - 4t1 - 5i4)/20), "
694 "e2 = floor((-4t1 - 5i4 + 10*floor((1 + i4)/2))/20), "
695 "e3 = floor((-1 + i4)/2): t2 = 0 and 2e3 = -1 + i4 and "
696 "20e2 >= -19 - 4t1 - 5i4 + 10e0 and 5e2 <= 1 - t1 and "
697 "2e0 <= 1 + i4 and 2e0 >= i4 and "
698 "20e1 <= 1530 - 4t1 - 5i4 and "
699 "20e1 >= 1511 - 4t1 - 5i4 and i4 <= 1 and "
700 "5e1 <= 381 - t1 and 20e2 <= -4t1 - 5i4 + 10e0) }"),
701 "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((-17 + i4)/2), "
702 "e1 = floor((-t1 + i6)/5): 5e1 = -t1 + i6 and "
703 "2e0 <= -17 + i4 and 2e0 >= -18 + i4 and "
704 "10e0 <= -91 + 5i4 + 4i6 and "
705 "10e0 >= -105 + 5i4 + 4i6) }",
706 "[t1, t2] -> { [i4, i5, i6] : exists (e0 = floor((381 - t1)/5), "
707 "e1 = floor((-1 + i4)/2): t2 = 0 and 2e1 = -1 + i4 and "
708 "i4 <= 1 and 5e0 <= 381 - t1 and 20e0 >= 1511 - 4t1 - 5i4) }" },
709 { TWO("{ [0, 0, q, p] : -5 <= q <= 5 and p >= 0 }"),
710 "{ [a, b, q, p] : b >= 1 + a }",
711 "{ [a, b, q, p] : false }" },
712 { TWO("[n] -> { [x] : x = n && x mod 32 = 0 }"),
713 "[n] -> { [x] : x mod 32 = 0 }",
714 "[n] -> { [x = n] }" },
715 { TWO("{ [x] : x mod 6 = 0 }"), "{ [x] : x mod 3 = 0 }",
716 "{ [x] : x mod 2 = 0 }" },
717 { TWO("{ [x] : x mod 3200 = 0 }"), "{ [x] : x mod 10000 = 0 }",
718 "{ [x] : x mod 128 = 0 }" },
719 { TWO("{ [x] : x mod 3200 = 0 }"), "{ [x] : x mod 10 = 0 }",
720 "{ [x] : x mod 3200 = 0 }" },
721 { TWO("{ [a, b, c] : a mod 2 = 0 and a = c }"),
722 "{ [a, b, c] : b mod 2 = 0 and b = c }",
723 "{ [a, b, c = a] }" },
724 { TWO("{ [a, b, c] : a mod 6 = 0 and a = c }"),
725 "{ [a, b, c] : b mod 2 = 0 and b = c }",
726 "{ [a, b, c = a] : a mod 3 = 0 }" },
727 { TWO("{ [x] : 0 <= x <= 4 or 6 <= x <= 9 }"),
728 "{ [x] : 1 <= x <= 3 or 7 <= x <= 8 }",
729 "{ [x] }" },
730 { TWO("{ [x,y] : x < 0 and 0 <= y <= 4 or "
731 "x >= -2 and -x <= y <= 10 + x }"),
732 "{ [x,y] : 1 <= y <= 3 }",
733 "{ [x,y] }" },
734 });
735
737 { "{ [x] -> [x] : x != 0 }", "{ [x] : x < -1 or x > 1 }",
738 "{ [x] -> [x] }" },
739 });
740
742 { "[N] -> { D[x] -> [x] : N >= 0; D[x] -> [0] : N < 0 }",
743 "[N] -> { : N >= 0 }",
744 "[N] -> { D[x] -> [x] }" },
745 });
746
748 { "{ A[i] -> B[i, i] }", "{ A[0] }",
749 "{ A[i] -> B[0, 0] }" },
750 { "[N] -> { A[i] -> B[i, N] }", "[N] -> { A[0] : N = 5 }",
751 "[N] -> { A[i] -> B[0, 5] }" },
752 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
753 "[N] -> { B[6, 5] }" },
754 { "[N] -> { A[i] -> B[] }", "[N] -> { A[0] : N = 5 }",
755 "[N] -> { A[i] -> B[] }" },
756 { "[N] -> { B[] }", "[N] -> { : N = 5 }",
757 "[N] -> { B[] }" },
758 });
759
761 { "[N] -> { A[i] -> B[i, N] }", "[N] -> { : N = 5 }",
762 "[N] -> { A[i] -> B[i, 5] }" },
763 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
764 "[N] -> { B[6, 5] }" },
765 { "[N] -> { A[i] -> B[] }", "[N] -> { : N = 5 }",
766 "[N] -> { A[i] -> B[] }" },
767 { "[N] -> { B[] }", "[N] -> { : N = 5 }",
768 "[N] -> { B[] }" },
769 });
770
772 { "{ A[i] -> B[i, i] : i >= 0 }", "{ A[0] }",
773 "{ A[i] -> B[0, 0] }" },
774 { "[N] -> { A[i] -> B[i, N] : N >= 0 }", "[N] -> { A[0] : N = 5 }",
775 "[N] -> { A[i] -> B[0, 5] }" },
776 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
777 "[N] -> { B[6, 5] }" },
778 { "[N] -> { A[i] -> B[] }", "[N] -> { A[0] : N = 5 }",
779 "[N] -> { A[i] -> B[] }" },
780 { "[N] -> { B[] }", "[N] -> { : N = 5 }",
781 "[N] -> { B[] }" },
782 { "{ A[i=0:10] -> B[i] }", "{ A[5] }",
783 "{ A[i] -> B[5] }" },
784 { "{ A[0:10] -> B[] }", "{ A[0:10] }",
785 "{ A[i] -> B[] }" },
786 { "[N] -> { A[i] -> B[] : N >= 0 }", "[N] -> { A[0] : N = 5 }",
787 "[N] -> { A[i] -> B[] }" },
788 { "[N] -> { B[] : N >= 0 }", "[N] -> { : N = 5 }",
789 "[N] -> { B[] }" },
790 { "[N] -> { B[] : N = 5 }", "[N] -> { : N >= 0 }",
791 "[N] -> { B[] : N = 5 }" },
792 });
793
795 { "[N] -> { A[i] -> B[i, N] : N >= 0 }", "[N] -> { : N = 5 }",
796 "[N] -> { A[i] -> B[i, 5] }" },
797 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
798 "[N] -> { B[6, 5] }" },
799 { "[N] -> { A[i] -> B[] : N >= 0 }", "[N] -> { : N = 5 }",
800 "[N] -> { A[i] -> B[] }" },
801 { "[N] -> { B[] : N >= 0 }", "[N] -> { : N = 5 }",
802 "[N] -> { B[] }" },
803 { "[N] -> { B[] : N >= 5 }", "[N] -> { : N >= 0 }",
804 "[N] -> { B[] : N >= 5 }" },
805 });
806
808 { "C[{ B[i,i] -> [3i] }]", "{ B[i,i] }",
809 "C[{ B[i,j] -> [3i] }]" },
810 { "(C[] : { B[i,i] })", "{ B[i,i] }",
811 "(C[] : { B[i,j] })" },
812 { "[N] -> (C[] : { B[N,N] })", "[N] -> { B[N,N] }",
813 "[N] -> (C[] : { B[i,j] })" },
814 { "C[]", "{ B[i,i] }",
815 "C[]" },
816 { "[N] -> (C[] : { B[i,i] : N >= 0 })", "{ B[i,i] }",
817 "[N] -> (C[] : { B[i,j] : N >= 0 })" },
818 { "[N] -> (C[] : { : N >= 0 })", "{ B[i,i] }",
819 "[N] -> (C[] : { : N >= 0 })" },
820 { "[N] -> (C[] : { : N >= 0 })", "[N] -> { B[i,i] : N >= 0 }",
821 "[N] -> C[]" },
822 });
823
825 { "[N] -> C[{ B[i,i] -> [3i + N] }]", "[N] -> { : N = 1 }",
826 "[N] -> C[{ B[i,i] -> [3i + 1] }]" },
827 { "C[{ B[i,i] -> [3i] }]", "[N] -> { : N >= 0 }",
828 "[N] -> C[{ B[i,i] -> [3i] }]" },
829 { "[N] -> C[{ B[i,i] -> [3i] : N >= 0 }]", "[N] -> { : N >= 0 }",
830 "[N] -> C[{ B[i,i] -> [3i] }]" },
831 { "[N] -> C[{ B[i,i] -> [3i] : N >= 1 }]", "[N] -> { : N >= 0 }",
832 "[N] -> C[{ B[i,i] -> [3i] : N >= 1 }]" },
833 { "[N] -> (C[] : { B[i,i] : N >= 0 })", "[N] -> { : N >= 0 }",
834 "[N] -> (C[] : { B[i,i] })" },
835 { "[N] -> (C[] : { : N >= 0 })", "[N] -> { : N >= 0 }",
836 "[N] -> C[]" },
837 { "C[{ B[i,i] -> [3i] }]", "[N] -> { : N >= 0 }",
838 "[N] -> C[{ B[i,i] -> [3i] }]" },
839 });
840}
841
842/* Perform tests that project out parameters.
843 */
844static void test_project(isl::ctx ctx)
845{
847 { "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }", "N",
848 "{ D[i] -> A[0:]; D[i] -> B[i] }" },
849 { "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }", "M",
850 "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }" },
851 });
852
854 { "[M, N, O] -> { D[i] -> A[j] : i <= j < M, N, O }", "(M, N)",
855 "[O] -> { D[i] -> A[j] : i <= j < O }" },
856 });
857}
858
859/* Perform some basic reverse tests.
860 */
861static void test_reverse(isl::ctx ctx)
862{
864 { "{ T[A[] -> B[*]] -> [0] }",
865 "{ [B[*] -> A[]] -> [0] }" },
866 { "{ T[A[] -> A[]] -> [0] }",
867 "{ T[A[] -> A[]] -> [0] }" },
868 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }",
869 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" },
870 });
871
873 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }",
874 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" },
875 { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3), 0] }",
876 "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3), 0] }" },
877 });
878
880 { "{ T[A[] -> B[*]] }",
881 "{ [B[*] -> A[]] }" },
882 { "{ T[A[] -> A[]] }",
883 "{ T[A[] -> A[]] }" },
884 { "{ [A[x] -> B[2x]] }",
885 "{ [B[y] -> A[x]] : y = 2x }" },
886 });
887
889 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }",
890 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" },
891 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] : x > y }",
892 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] : x > y }" },
893 { "{ [A[i] -> B[i + 1]] -> [i + 2] }",
894 "{ [B[i] -> A[i - 1]] -> [i + 1] }" },
895 });
896
898 { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3), 0] : x > y }",
899 "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3), 0] : x > y }" },
900 { "{ [A[i] -> B[i + 1]] -> T[0, i + 2] }",
901 "{ [B[i] -> A[i - 1]] -> T[0, i + 1] }" },
902 });
903
905 { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3) : x > y, 0] }",
906 "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3) : x > y, 0] }" },
907 });
908
910 { "{ [A[] -> B[]] -> [C[] -> D[]] }",
911 "{ [B[] -> A[]] -> [C[] -> D[]] }" },
912 { "{ N[B[] -> C[]] -> A[] }",
913 "{ [C[] -> B[]] -> A[] }" },
914 { "{ N[B[x] -> B[y]] -> A[] }",
915 "{ N[B[*] -> B[*]] -> A[] }" },
916 });
917
919 { "{ [A[] -> B[]] -> [C[] -> D[]] }",
920 "{ [B[] -> A[]] -> [C[] -> D[]] }" },
921 { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }",
922 "{ }" },
923 { "{ N[B[] -> C[]] -> A[] }",
924 "{ [C[] -> B[]] -> A[] }" },
925 { "{ N[B[x] -> B[y]] -> A[] }",
926 "{ N[B[*] -> B[*]] -> A[] }" },
927 });
928
930 { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }",
931 "{ A[] -> [C[] -> B[]]; A[0] -> N[B[2] -> B[1]] }" },
932 { "{ A[] -> N[B[] -> C[]] }",
933 "{ A[] -> [C[] -> B[]] }" },
934 { "{ A[] -> N[B[x] -> B[y]] }",
935 "{ A[] -> N[B[*] -> B[*]] }" },
936 });
937}
938
939/* Perform some basic scaling tests.
940 */
941static void test_scale(isl::ctx ctx)
942{
944 { "{ A[a] -> B[a, a + 1, a - 1] : a >= 0 }", "{ B[2, 7, 0] }",
945 "{ A[a] -> B[2a, 7a + 7, 0] : a >= 0 }" },
946 });
948 { "{ A[a] -> B[1, a - 1] : a >= 0 }", "{ B[1/2, 7] }",
949 "{ A[a] -> B[1/2, 7a - 7] : a >= 0 }" },
950 });
951
953 { "{ A[a] -> B[a, a + 1] : a >= 0 }", "{ B[2, 7] }",
954 "{ A[a] -> B[a/2, (a + 1)/7] : a >= 0 }" },
955 });
957 { "{ A[a] -> B[a, a - 1] : a >= 0 }", "{ B[2, 1/7] }",
958 "{ A[a] -> B[a/2, 7a - 7] : a >= 0 }" },
959 });
960}
961
962/* Perform some basic isl::id_to_id tests.
963 */
964static void test_id_to_id(isl::ctx ctx)
965{
967 { "{ }", "a", "b",
968 "{ a: b }" },
969 { "{ a: b }", "a", "b",
970 "{ a: b }" },
971 { "{ a: c }", "a", "b",
972 "{ a: b }" },
973 { "{ a: b }", "b", "a",
974 "{ a: b, b: a }" },
975 { "{ a: b }", "b", "a",
976 "{ b: a, a: b }" },
977 });
978}
979
980/* The list of tests to perform.
981 */
982static std::vector<std::pair<const char *, void (*)(isl::ctx)>> tests =
983{
984 { "space", &test_space },
985 { "conversion", &test_conversion },
986 { "preimage", &test_preimage },
987 { "fixed power", &test_fixed_power },
988 { "box hull", &test_box_hull },
989 { "coalesce", &test_coalesce },
990 { "intersect", &test_intersect },
991 { "lexmin", &test_lexmin },
992 { "gist", &test_gist },
993 { "project out parameters", &test_project },
994 { "reverse", &test_reverse },
995 { "scale", &test_scale },
996 { "id-to-id", &test_id_to_id },
997};
998
999/* Perform some basic checks by means of the C++ bindings.
1000 */
1001int main(int argc, char **argv)
1002{
1003 int ret = EXIT_SUCCESS;
1004 struct isl_ctx *ctx;
1005 struct isl_options *options;
1006
1007 options = isl_options_new_with_defaults();
1008 assert(options);
1009 argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL);
1010 ctx = isl_ctx_alloc_with_options(&isl_options_args, options);
1011
1012 try {
1013 for (const auto &f : tests) {
1014 std::cout << f.first << "\n";
1015 f.second(ctx);
1016 }
1017 } catch (const isl::exception &e) {
1018 std::cerr << e.what() << "\n";
1019 ret = EXIT_FAILURE;
1020 }
1021
1022 isl_ctx_free(ctx);
1023 return ret;
1024}
#define ISL_ARG_ALL
Definition arg.h:288
isl::aff domain_reverse() const
isl::basic_map intersect_params(isl::basic_set bset) const
isl::id_to_id set(isl::id key, isl::id val) const
isl::fixed_box range_simple_fixed_box_hull() const
isl::pw_multi_aff as_pw_multi_aff() const
isl::map domain_reverse() const
isl::map fixed_power(isl::val exp) const
isl::pw_multi_aff lexmin_pw_multi_aff() const
isl::multi_aff gist_params(isl::set context) const
isl::multi_aff domain_reverse() const
isl::multi_aff gist(isl::set context) const
isl::multi_pw_aff gist(isl::set set) const
isl::multi_pw_aff gist_params(isl::set set) const
isl::set as_set() const
isl::multi_pw_aff domain_reverse() const
isl::multi_union_pw_aff gist_params(isl::set context) const
isl::multi_union_pw_aff gist(isl::union_set context) const
isl::pw_aff domain_reverse() const
isl::pw_aff gist_params(isl::set context) const
isl::pw_aff gist(isl::set context) const
isl::pw_multi_aff scale_down(isl::multi_val mv) const
isl::pw_multi_aff domain_reverse() const
isl::pw_multi_aff scale(isl::multi_val mv) const
isl::pw_multi_aff lexmin_pw_multi_aff() const
isl::fixed_box simple_fixed_box_hull() const
isl::set wrapped_reverse() const
isl::set preimage(isl::multi_aff ma) const
isl::pw_multi_aff as_pw_multi_aff() const
isl::space params() const
isl::space domain() const
isl::space range() const
isl::union_map preimage_domain(isl::multi_aff ma) const
isl::union_map domain_reverse() const
isl::union_map intersect_domain_wrapped_domain(isl::union_set domain) const
isl::union_map preimage_range(isl::multi_aff ma) const
isl::union_map range_reverse() const
isl::union_map project_out_param(isl::id id) const
isl::union_map intersect_range_wrapped_domain(isl::union_set domain) const
isl_ctx * isl_ctx_alloc_with_options(struct isl_args *args, __isl_take void *opt)
void isl_ctx_free(isl_ctx *ctx)
Definition isl_ctx.c:300
isl_stat isl_stat(* fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, void *user)
Definition hmap.h:37
isl_bool isl_bool(* test)(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, void *user)
Definition hmap.h:41
static void test_preimage(isl::ctx ctx)
Definition isl_test2.cc:354
R(T::*)(A1, A2) const ternary_fn
Definition isl_test2.cc:56
static void test_id_to_id(isl::ctx ctx)
Definition isl_test2.cc:964
R(T::*)(A1) const binary_fn
Definition isl_test2.cc:39
static void test_project(isl::ctx ctx)
Definition isl_test2.cc:844
#define C(FN,...)
Definition isl_test2.cc:266
#define THROW_INVALID(msg)
Definition isl_test2.cc:127
static void test_gist(isl::ctx ctx)
Definition isl_test2.cc:640
static bool has_single_cell_pma(const T &obj)
Definition isl_test2.cc:300
static void test_intersect(isl::ctx ctx)
Definition isl_test2.cc:508
#define TWO(x)
Definition isl_test2.cc:632
static bool is_equal(const T &a, const T &b)
Definition isl_test2.cc:110
static bool has_single_cell(const isl::pw_multi_aff &fn)
Definition isl_test2.cc:290
static bool lexmin_has_single_cell(const T &obj)
Definition isl_test2.cc:544
static void test_scale(isl::ctx ctx)
Definition isl_test2.cc:941
static void test_lexmin(isl::ctx ctx)
Definition isl_test2.cc:551
static void test_space(isl::ctx ctx)
Definition isl_test2.cc:270
static void test_box_hull(isl::ctx ctx)
Definition isl_test2.cc:443
static void test_coalesce(isl::ctx ctx)
Definition isl_test2.cc:489
static void test_conversion(isl::ctx ctx)
Definition isl_test2.cc:317
static void test_ternary(isl::ctx ctx, const F &fn, const std::string &name, const std::vector< ternary > &tests)
Definition isl_test2.cc:210
static void test_fixed_power(isl::ctx ctx)
Definition isl_test2.cc:426
static void test_reverse(isl::ctx ctx)
Definition isl_test2.cc:861
struct @353313213005051113013213240171041254010167127320 tests[]
const char * arg1
Definition isl_test.c:871
enum isl_fold type
Definition isl_test.c:3810
static int test_lexmin(struct isl_ctx *ctx)
Definition isl_test.c:2875
static int test_gist(struct isl_ctx *ctx)
Definition isl_test.c:1782
const char * arg2
Definition isl_test.c:873
const char * name
Definition isl_test.c:10692
const char * context
Definition isl_test.c:1735
const char * obj
Definition isl_test.c:3109
const char * res
Definition isl_test.c:783
static int test_conversion(isl_ctx *ctx)
Definition isl_test.c:9167
const char * arg
Definition isl_test.c:782
const char * gist
Definition isl_test.c:1736
static int test_coalesce(struct isl_ctx *ctx)
Definition isl_test.c:2451
const char * f
Definition isl_test.c:8396
static int test_intersect(isl_ctx *ctx)
Definition isl_test.c:4184
#define assert(exp)
char * expected
a(0)
b(9)
const char * arg1
Definition isl_test2.cc:85
const char * res
Definition isl_test2.cc:87
const char * arg2
Definition isl_test2.cc:86
const char * res
Definition isl_test2.cc:96
const char * arg1
Definition isl_test2.cc:93
const char * arg3
Definition isl_test2.cc:95
const char * arg2
Definition isl_test2.cc:94
const char * arg
Definition isl_test2.cc:71
const char * res
Definition isl_test2.cc:79
const char * arg
Definition isl_test2.cc:78
static Signature wrap
static Signature domain