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
8 * Use of this software is governed by the MIT license
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
27 #include <type_traits>
33 /* A binary isl function that appears in the C++ bindings
34 * as a unary method in a class T, taking an extra argument
35 * of type A1 and returning an object of type R.
37 template <typename A1
, typename R
, typename T
>
38 using binary_fn
= R (T::*)(A1
) const;
40 /* A function for selecting an overload of a pointer to a unary C++ method
41 * based on the single argument type.
42 * The object type and the return type are meant to be deduced.
44 template <typename A1
, typename R
, typename T
>
45 static binary_fn
<A1
, R
, T
> const arg(const binary_fn
<A1
, R
, T
> &fn
)
50 /* A ternary isl function that appears in the C++ bindings
51 * as a binary method in a class T, taking extra arguments
52 * of type A1 and A2 and returning an object of type R.
54 template <typename A1
, typename A2
, typename R
, typename T
>
55 using ternary_fn
= R (T::*)(A1
, A2
) const;
57 /* A function for selecting an overload of a pointer to a binary C++ method
58 * based on the (first) argument type(s).
59 * The object type and the return type are meant to be deduced.
61 template <typename A1
, typename A2
, typename R
, typename T
>
62 static ternary_fn
<A1
, A2
, R
, T
> const arg(const ternary_fn
<A1
, A2
, R
, T
> &fn
)
67 /* A description of the input and the output of a unary operation.
74 /* A description of the inputs and the output of a binary operation.
82 /* A description of the inputs and the output of a ternary operation.
91 /* A template function for checking whether two objects
92 * of the same (isl) type are (obviously) equal.
93 * The spelling depends on the isl type and
94 * in particular on whether an equality method is available or
95 * whether only obvious equality can be tested.
97 template <typename T
, typename
std::decay
<decltype(
98 std::declval
<T
>().is_equal(std::declval
<T
>()))>::type
= true>
99 static bool is_equal(const T
&a
, const T
&b
)
101 return a
.is_equal(b
);
103 template <typename T
, typename
std::decay
<decltype(
104 std::declval
<T
>().plain_is_equal(std::declval
<T
>()))>::type
= true>
105 static bool is_equal(const T
&a
, const T
&b
)
107 return a
.plain_is_equal(b
);
110 /* A helper macro for throwing an isl::exception_invalid with message "msg".
112 #define THROW_INVALID(msg) \
113 isl::exception::throw_error(isl_error_invalid, msg, __FILE__, __LINE__)
115 /* Run a sequence of tests of method "fn" with stringification "name" and
116 * with input and output described by "test",
117 * throwing an exception when an unexpected result is produced.
119 template <typename R
, typename T
>
120 static void test(isl::ctx ctx
, R (T::*fn
)() const, const std::string
&name
,
121 const std::vector
<unary
> &tests
)
123 for (const auto &test
: tests
) {
124 T
obj(ctx
, test
.arg
);
125 R
expected(ctx
, test
.res
);
126 const auto &res
= (obj
.*fn
)();
127 std::ostringstream ss
;
129 if (is_equal(expected
, res
))
132 ss
<< name
<< "(" << test
.arg
<< ") =\n"
136 THROW_INVALID(ss
.str().c_str());
140 /* Run a sequence of tests of method "fn" with stringification "name" and
141 * with inputs and output described by "test",
142 * throwing an exception when an unexpected result is produced.
144 template <typename R
, typename T
, typename A1
>
145 static void test(isl::ctx ctx
, R (T::*fn
)(A1
) const, const std::string
&name
,
146 const std::vector
<binary
> &tests
)
148 for (const auto &test
: tests
) {
149 T
obj(ctx
, test
.arg1
);
150 A1
arg1(ctx
, test
.arg2
);
151 R
expected(ctx
, test
.res
);
152 const auto &res
= (obj
.*fn
)(arg1
);
153 std::ostringstream ss
;
155 if (is_equal(expected
, res
))
158 ss
<< name
<< "(" << test
.arg1
<< ", " << test
.arg2
<< ") =\n"
162 THROW_INVALID(ss
.str().c_str());
166 /* Run a sequence of tests of method "fn" with stringification "name" and
167 * with inputs and output described by "test",
168 * throwing an exception when an unexpected result is produced.
170 template <typename R
, typename T
, typename A1
, typename A2
>
171 static void test(isl::ctx ctx
, R (T::*fn
)(A1
, A2
) const,
172 const std::string
&name
, const std::vector
<ternary
> &tests
)
174 for (const auto &test
: tests
) {
175 T
obj(ctx
, test
.arg1
);
176 A1
arg1(ctx
, test
.arg2
);
177 A2
arg2(ctx
, test
.arg3
);
178 R
expected(ctx
, test
.res
);
179 const auto &res
= (obj
.*fn
)(arg1
, arg2
);
180 std::ostringstream ss
;
182 if (is_equal(expected
, res
))
185 ss
<< name
<< "(" << test
.arg1
<< ", " << test
.arg2
<< ", "
186 << test
.arg3
<< ") =\n"
190 THROW_INVALID(ss
.str().c_str());
194 /* A helper macro that calls test with as implicit initial argument "ctx" and
195 * as extra argument a stringification of "FN".
197 #define C(FN, ...) test(ctx, FN, #FN, __VA_ARGS__)
199 /* Perform some basic isl::space tests.
201 static void test_space(isl::ctx ctx
)
203 C(&isl::space::domain
, {
204 { "{ A[] -> B[] }", "{ A[] }" },
205 { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ A[C[] -> D[]] }" },
208 C(&isl::space::range
, {
209 { "{ A[] -> B[] }", "{ B[] }" },
210 { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ B[E[] -> F[]] }" },
213 C(&isl::space::params
, {
214 { "{ A[] -> B[] }", "{ : }" },
215 { "{ A[C[] -> D[]] -> B[E[] -> F[]] }", "{ : }" },
219 /* Perform some basic conversion tests.
221 static void test_conversion(isl::ctx ctx
)
223 C(&isl::multi_pw_aff::as_set
, {
224 { "[n] -> { [] : n >= 0 } ",
225 "[n] -> { [] : n >= 0 } " },
229 /* Perform some basic preimage tests.
231 static void test_preimage(isl::ctx ctx
)
233 C(arg
<isl::multi_aff
>(&isl::set::preimage
), {
234 { "{ B[i,j] : 0 <= i < 10 and 0 <= j < 100 }",
235 "{ A[j,i] -> B[i,j] }",
236 "{ A[j,i] : 0 <= i < 10 and 0 <= j < 100 }" },
237 { "{ rat: B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
238 "{ A[a,b] -> B[a/2,b/6] }",
239 "{ rat: A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 }" },
240 { "{ B[i,j] : 0 <= i, j and 3 i + 5 j <= 100 }",
241 "{ A[a,b] -> B[a/2,b/6] }",
242 "{ A[a,b] : 0 <= a, b and 9 a + 5 b <= 600 and "
243 "exists i,j : a = 2 i and b = 6 j }" },
244 { "[n] -> { S[i] : 0 <= i <= 100 }", "[n] -> { S[n] }",
245 "[n] -> { : 0 <= n <= 100 }" },
246 { "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
248 "{ A[a] : 0 <= a < 50 and exists b : a = 2 b }" },
249 { "{ B[i] : 0 <= i < 100 and exists a : i = 4 a }",
250 "{ A[a] -> B[([a/2])] }",
251 "{ A[a] : 0 <= a < 200 and exists b : [a/2] = 4 b }" },
252 { "{ B[i,j,k] : 0 <= i,j,k <= 100 }",
253 "{ A[a] -> B[a,a,a/3] }",
254 "{ A[a] : 0 <= a <= 100 and exists b : a = 3 b }" },
255 { "{ B[i,j] : j = [(i)/2] } ", "{ A[i,j] -> B[i/3,j] }",
256 "{ A[i,j] : j = [(i)/6] and exists a : i = 3 a }" },
259 C(arg
<isl::multi_aff
>(&isl::union_map::preimage_domain
), {
260 { "{ B[i,j] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }",
261 "{ A[j,i] -> B[i,j] }",
262 "{ A[j,i] -> C[2i + 3j] : 0 <= i < 10 and 0 <= j < 100 }" },
263 { "{ B[i] -> C[i]; D[i] -> E[i] }",
264 "{ A[i] -> B[i + 1] }",
265 "{ A[i] -> C[i + 1] }" },
266 { "{ B[i] -> C[i]; B[i] -> E[i] }",
267 "{ A[i] -> B[i + 1] }",
268 "{ A[i] -> C[i + 1]; A[i] -> E[i + 1] }" },
269 { "{ B[i] -> C[([i/2])] }",
271 "{ A[i] -> C[i] }" },
272 { "{ B[i,j] -> C[([i/2]), ([(i+j)/3])] }",
273 "{ A[i] -> B[([i/5]), ([i/7])] }",
274 "{ A[i] -> C[([([i/5])/2]), ([(([i/5])+([i/7]))/3])] }" },
275 { "[N] -> { B[i] -> C[([N/2]), i, ([N/3])] }",
276 "[N] -> { A[] -> B[([N/5])] }",
277 "[N] -> { A[] -> C[([N/2]), ([N/5]), ([N/3])] }" },
278 { "{ B[i] -> C[i] : exists a : i = 5 a }",
280 "{ A[i] -> C[2i] : exists a : 2i = 5 a }" },
281 { "{ B[i] -> C[i] : exists a : i = 2 a; "
282 "B[i] -> D[i] : exists a : i = 2 a + 1 }",
284 "{ A[i] -> C[2i] }" },
285 { "{ A[i] -> B[i] }", "{ C[i] -> A[(i + floor(i/3))/2] }",
286 "{ C[i] -> B[j] : 2j = i + floor(i/3) }" },
289 C(arg
<isl::multi_aff
>(&isl::union_map::preimage_range
), {
290 { "[M] -> { A[a] -> B[a] }", "[M] -> { C[] -> B[floor(M/2)] }",
291 "[M] -> { A[floor(M/2)] -> C[] }" },
295 /* Perform some basic fixed power tests.
297 static void test_fixed_power(isl::ctx ctx
)
299 C(arg
<isl::val
>(&isl::map::fixed_power
), {
300 { "{ [i] -> [i + 1] }", "23",
301 "{ [i] -> [i + 23] }" },
302 { "{ [a = 0:1, b = 0:15, c = 0:1, d = 0:1, 0] -> [a, b, c, d, 1]; "
303 "[a = 0:1, b = 0:15, c = 0:1, 0, 1] -> [a, b, c, 1, 0]; "
304 "[a = 0:1, b = 0:15, 0, 1, 1] -> [a, b, 1, 0, 0]; "
305 "[a = 0:1, b = 0:14, 1, 1, 1] -> [a, 1 + b, 0, 0, 0]; "
306 "[0, 15, 1, 1, 1] -> [1, 0, 0, 0, 0] }",
308 "{ [0, b = 0:15, c = 0:1, d = 0:1, e = 0:1] -> [1, b, c, d, e] }" },
312 /* Perform some basic intersection tests.
314 static void test_intersect(isl::ctx ctx
)
316 C(&isl::union_map::intersect_domain_wrapped_domain
, {
317 { "{ [A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }",
319 "{ [A[0] -> B[y]] -> C[z] }" },
320 { "{ C[z] -> [A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }",
325 C(&isl::union_map::intersect_range_wrapped_domain
, {
326 { "{ [A[x] -> B[y]] -> C[z]; [D[x] -> A[y]] -> E[z] }",
329 { "{ C[z] -> [A[x] -> B[y]]; E[z] -> [D[x] -> A[y]] }",
331 "{ C[z] -> [A[0] -> B[y]] }" },
335 /* Perform some basic gist tests.
337 static void test_gist(isl::ctx ctx
)
339 C(&isl::pw_aff::gist_params
, {
340 { "[N] -> { D[x] -> [x] : N >= 0; D[x] -> [0] : N < 0 }",
341 "[N] -> { : N >= 0 }",
342 "[N] -> { D[x] -> [x] }" },
345 C(arg
<isl::set
>(&isl::multi_aff::gist
), {
346 { "{ A[i] -> B[i, i] }", "{ A[0] }",
347 "{ A[i] -> B[0, 0] }" },
348 { "[N] -> { A[i] -> B[i, N] }", "[N] -> { A[0] : N = 5 }",
349 "[N] -> { A[i] -> B[0, 5] }" },
350 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
351 "[N] -> { B[6, 5] }" },
352 { "[N] -> { A[i] -> B[] }", "[N] -> { A[0] : N = 5 }",
353 "[N] -> { A[i] -> B[] }" },
354 { "[N] -> { B[] }", "[N] -> { : N = 5 }",
358 C(&isl::multi_aff::gist_params
, {
359 { "[N] -> { A[i] -> B[i, N] }", "[N] -> { : N = 5 }",
360 "[N] -> { A[i] -> B[i, 5] }" },
361 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
362 "[N] -> { B[6, 5] }" },
363 { "[N] -> { A[i] -> B[] }", "[N] -> { : N = 5 }",
364 "[N] -> { A[i] -> B[] }" },
365 { "[N] -> { B[] }", "[N] -> { : N = 5 }",
369 C(arg
<isl::set
>(&isl::multi_pw_aff::gist
), {
370 { "{ A[i] -> B[i, i] : i >= 0 }", "{ A[0] }",
371 "{ A[i] -> B[0, 0] }" },
372 { "[N] -> { A[i] -> B[i, N] : N >= 0 }", "[N] -> { A[0] : N = 5 }",
373 "[N] -> { A[i] -> B[0, 5] }" },
374 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
375 "[N] -> { B[6, 5] }" },
376 { "[N] -> { A[i] -> B[] }", "[N] -> { A[0] : N = 5 }",
377 "[N] -> { A[i] -> B[] }" },
378 { "[N] -> { B[] }", "[N] -> { : N = 5 }",
380 { "{ A[i=0:10] -> B[i] }", "{ A[5] }",
381 "{ A[i] -> B[5] }" },
382 { "{ A[0:10] -> B[] }", "{ A[0:10] }",
384 { "[N] -> { A[i] -> B[] : N >= 0 }", "[N] -> { A[0] : N = 5 }",
385 "[N] -> { A[i] -> B[] }" },
386 { "[N] -> { B[] : N >= 0 }", "[N] -> { : N = 5 }",
388 { "[N] -> { B[] : N = 5 }", "[N] -> { : N >= 0 }",
389 "[N] -> { B[] : N = 5 }" },
392 C(&isl::multi_pw_aff::gist_params
, {
393 { "[N] -> { A[i] -> B[i, N] : N >= 0 }", "[N] -> { : N = 5 }",
394 "[N] -> { A[i] -> B[i, 5] }" },
395 { "[N] -> { B[N + 1, N] }", "[N] -> { : N = 5 }",
396 "[N] -> { B[6, 5] }" },
397 { "[N] -> { A[i] -> B[] : N >= 0 }", "[N] -> { : N = 5 }",
398 "[N] -> { A[i] -> B[] }" },
399 { "[N] -> { B[] : N >= 0 }", "[N] -> { : N = 5 }",
401 { "[N] -> { B[] : N >= 5 }", "[N] -> { : N >= 0 }",
402 "[N] -> { B[] : N >= 5 }" },
405 C(&isl::multi_union_pw_aff::gist
, {
406 { "C[{ B[i,i] -> [3i] }]", "{ B[i,i] }",
407 "C[{ B[i,j] -> [3i] }]" },
408 { "(C[] : { B[i,i] })", "{ B[i,i] }",
409 "(C[] : { B[i,j] })" },
410 { "[N] -> (C[] : { B[N,N] })", "[N] -> { B[N,N] }",
411 "[N] -> (C[] : { B[i,j] })" },
412 { "C[]", "{ B[i,i] }",
414 { "[N] -> (C[] : { B[i,i] : N >= 0 })", "{ B[i,i] }",
415 "[N] -> (C[] : { B[i,j] : N >= 0 })" },
416 { "[N] -> (C[] : { : N >= 0 })", "{ B[i,i] }",
417 "[N] -> (C[] : { : N >= 0 })" },
418 { "[N] -> (C[] : { : N >= 0 })", "[N] -> { B[i,i] : N >= 0 }",
422 C(&isl::multi_union_pw_aff::gist_params
, {
423 { "[N] -> C[{ B[i,i] -> [3i + N] }]", "[N] -> { : N = 1 }",
424 "[N] -> C[{ B[i,i] -> [3i + 1] }]" },
425 { "C[{ B[i,i] -> [3i] }]", "[N] -> { : N >= 0 }",
426 "[N] -> C[{ B[i,i] -> [3i] }]" },
427 { "[N] -> C[{ B[i,i] -> [3i] : N >= 0 }]", "[N] -> { : N >= 0 }",
428 "[N] -> C[{ B[i,i] -> [3i] }]" },
429 { "[N] -> C[{ B[i,i] -> [3i] : N >= 1 }]", "[N] -> { : N >= 0 }",
430 "[N] -> C[{ B[i,i] -> [3i] : N >= 1 }]" },
431 { "[N] -> (C[] : { B[i,i] : N >= 0 })", "[N] -> { : N >= 0 }",
432 "[N] -> (C[] : { B[i,i] })" },
433 { "[N] -> (C[] : { : N >= 0 })", "[N] -> { : N >= 0 }",
435 { "C[{ B[i,i] -> [3i] }]", "[N] -> { : N >= 0 }",
436 "[N] -> C[{ B[i,i] -> [3i] }]" },
440 /* Perform tests that project out parameters.
442 static void test_project(isl::ctx ctx
)
444 C(arg
<isl::id
>(&isl::union_map::project_out_param
), {
445 { "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }", "N",
446 "{ D[i] -> A[0:]; D[i] -> B[i] }" },
447 { "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }", "M",
448 "[N] -> { D[i] -> A[0:N-1]; D[i] -> B[i] }" },
451 C(arg
<isl::id_list
>(&isl::union_map::project_out_param
), {
452 { "[M, N, O] -> { D[i] -> A[j] : i <= j < M, N, O }", "(M, N)",
453 "[O] -> { D[i] -> A[j] : i <= j < O }" },
457 /* Perform some basic reverse tests.
459 static void test_reverse(isl::ctx ctx
)
461 C(&isl::aff::domain_reverse
, {
462 { "{ T[A[] -> B[*]] -> [0] }",
463 "{ [B[*] -> A[]] -> [0] }" },
464 { "{ T[A[] -> A[]] -> [0] }",
465 "{ T[A[] -> A[]] -> [0] }" },
466 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }",
467 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" },
470 C(&isl::multi_aff::domain_reverse
, {
471 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }",
472 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" },
473 { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3), 0] }",
474 "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3), 0] }" },
477 C(&isl::set::wrapped_reverse
, {
478 { "{ T[A[] -> B[*]] }",
479 "{ [B[*] -> A[]] }" },
480 { "{ T[A[] -> A[]] }",
481 "{ T[A[] -> A[]] }" },
482 { "{ [A[x] -> B[2x]] }",
483 "{ [B[y] -> A[x]] : y = 2x }" },
486 C(&isl::pw_aff::domain_reverse
, {
487 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }",
488 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" },
489 { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] : x > y }",
490 "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] : x > y }" },
491 { "{ [A[i] -> B[i + 1]] -> [i + 2] }",
492 "{ [B[i] -> A[i - 1]] -> [i + 1] }" },
495 C(&isl::pw_multi_aff::domain_reverse
, {
496 { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3), 0] : x > y }",
497 "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3), 0] : x > y }" },
498 { "{ [A[i] -> B[i + 1]] -> T[0, i + 2] }",
499 "{ [B[i] -> A[i - 1]] -> T[0, i + 1] }" },
502 C(&isl::multi_pw_aff::domain_reverse
, {
503 { "{ [A[x] -> B[y]] -> T[5*(x // 2) + 7*(y // 3) : x > y, 0] }",
504 "{ [B[y] -> A[x]] -> T[5*(x // 2) + 7*(y // 3) : x > y, 0] }" },
507 C(&isl::map::domain_reverse
, {
508 { "{ [A[] -> B[]] -> [C[] -> D[]] }",
509 "{ [B[] -> A[]] -> [C[] -> D[]] }" },
510 { "{ N[B[] -> C[]] -> A[] }",
511 "{ [C[] -> B[]] -> A[] }" },
512 { "{ N[B[x] -> B[y]] -> A[] }",
513 "{ N[B[*] -> B[*]] -> A[] }" },
516 C(&isl::union_map::domain_reverse
, {
517 { "{ [A[] -> B[]] -> [C[] -> D[]] }",
518 "{ [B[] -> A[]] -> [C[] -> D[]] }" },
519 { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }",
521 { "{ N[B[] -> C[]] -> A[] }",
522 "{ [C[] -> B[]] -> A[] }" },
523 { "{ N[B[x] -> B[y]] -> A[] }",
524 "{ N[B[*] -> B[*]] -> A[] }" },
527 C(&isl::union_map::range_reverse
, {
528 { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }",
529 "{ A[] -> [C[] -> B[]]; A[0] -> N[B[2] -> B[1]] }" },
530 { "{ A[] -> N[B[] -> C[]] }",
531 "{ A[] -> [C[] -> B[]] }" },
532 { "{ A[] -> N[B[x] -> B[y]] }",
533 "{ A[] -> N[B[*] -> B[*]] }" },
537 /* Perform some basic scaling tests.
539 static void test_scale(isl::ctx ctx
)
541 C(arg
<isl::multi_val
>(&isl::pw_multi_aff::scale
), {
542 { "{ A[a] -> B[a, a + 1, a - 1] : a >= 0 }", "{ B[2, 7, 0] }",
543 "{ A[a] -> B[2a, 7a + 7, 0] : a >= 0 }" },
545 C(arg
<isl::multi_val
>(&isl::pw_multi_aff::scale
), {
546 { "{ A[a] -> B[1, a - 1] : a >= 0 }", "{ B[1/2, 7] }",
547 "{ A[a] -> B[1/2, 7a - 7] : a >= 0 }" },
550 C(arg
<isl::multi_val
>(&isl::pw_multi_aff::scale_down
), {
551 { "{ A[a] -> B[a, a + 1] : a >= 0 }", "{ B[2, 7] }",
552 "{ A[a] -> B[a/2, (a + 1)/7] : a >= 0 }" },
554 C(arg
<isl::multi_val
>(&isl::pw_multi_aff::scale_down
), {
555 { "{ A[a] -> B[a, a - 1] : a >= 0 }", "{ B[2, 1/7] }",
556 "{ A[a] -> B[a/2, 7a - 7] : a >= 0 }" },
560 /* Perform some basic isl::id_to_id tests.
562 static void test_id_to_id(isl::ctx ctx
)
564 C((arg
<isl::id
, isl::id
>(&isl::id_to_id::set
)), {
567 { "{ a: b }", "a", "b",
569 { "{ a: c }", "a", "b",
571 { "{ a: b }", "b", "a",
573 { "{ a: b }", "b", "a",
578 /* The list of tests to perform.
580 static std::vector
<std::pair
<const char *, void (*)(isl::ctx
)>> tests
=
582 { "space", &test_space
},
583 { "conversion", &test_conversion
},
584 { "preimage", &test_preimage
},
585 { "fixed power", &test_fixed_power
},
586 { "intersect", &test_intersect
},
587 { "gist", &test_gist
},
588 { "project out parameters", &test_project
},
589 { "reverse", &test_reverse
},
590 { "scale", &test_scale
},
591 { "id-to-id", &test_id_to_id
},
594 /* Perform some basic checks by means of the C++ bindings.
596 int main(int argc
, char **argv
)
598 int ret
= EXIT_SUCCESS
;
600 struct isl_options
*options
;
602 options
= isl_options_new_with_defaults();
604 argc
= isl_options_parse(options
, argc
, argv
, ISL_ARG_ALL
);
605 ctx
= isl_ctx_alloc_with_options(&isl_options_args
, options
);
608 for (const auto &f
: tests
) {
609 std::cout
<< f
.first
<< "\n";
612 } catch (const isl::exception
&e
) {
613 std::cerr
<< e
.what() << "\n";