2 * Copyright 2011 INRIA Saclay
3 * Copyright 2012-2013 Ecole Normale Superieure
4 * Copyright 2016 Sven Verdoolaege
6 * Use of this software is governed by the MIT license
8 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
9 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
15 #include <isl/space.h>
16 #include <isl/local_space.h>
17 #include <isl/union_map.h>
18 #include <isl_map_private.h>
19 #include <isl_aff_private.h>
20 #include <isl_vec_private.h>
23 #include <set_from_map.c>
25 /* Check that the input living in "space" lives in a map space.
26 * That is, check that "space" is a map space.
28 static isl_stat
check_input_is_map(__isl_keep isl_space
*space
)
32 is_set
= isl_space_is_set(space
);
34 return isl_stat_error
;
36 isl_die(isl_space_get_ctx(space
), isl_error_invalid
,
37 "space of input is not a map", return isl_stat_error
);
41 /* Check that the input living in "space" lives in a set space.
42 * That is, check that "space" is a set space.
44 static isl_stat
check_input_is_set(__isl_keep isl_space
*space
)
48 is_set
= isl_space_is_set(space
);
50 return isl_stat_error
;
52 isl_die(isl_space_get_ctx(space
), isl_error_invalid
,
53 "space of input is not a set", return isl_stat_error
);
57 /* Construct a basic map mapping the domain of the affine expression
58 * to a one-dimensional range prescribed by the affine expression.
59 * If "rational" is set, then construct a rational basic map.
61 * A NaN affine expression cannot be converted to a basic map.
63 static __isl_give isl_basic_map
*isl_basic_map_from_aff2(
64 __isl_take isl_aff
*aff
, int rational
)
70 isl_basic_map
*bmap
= NULL
;
74 is_nan
= isl_aff_is_nan(aff
);
78 isl_die(isl_aff_get_ctx(aff
), isl_error_invalid
,
79 "cannot convert NaN", goto error
);
81 ls
= isl_aff_get_local_space(aff
);
82 bmap
= isl_basic_map_from_local_space(ls
);
83 bmap
= isl_basic_map_extend_constraints(bmap
, 1, 0);
84 k
= isl_basic_map_alloc_equality(bmap
);
88 pos
= isl_basic_map_offset(bmap
, isl_dim_out
);
89 isl_seq_cpy(bmap
->eq
[k
], aff
->v
->el
+ 1, pos
);
90 isl_int_neg(bmap
->eq
[k
][pos
], aff
->v
->el
[0]);
91 isl_seq_cpy(bmap
->eq
[k
] + pos
+ 1, aff
->v
->el
+ 1 + pos
,
92 aff
->v
->size
- (pos
+ 1));
96 bmap
= isl_basic_map_set_rational(bmap
);
97 bmap
= isl_basic_map_gauss(bmap
, NULL
);
98 bmap
= isl_basic_map_finalize(bmap
);
102 isl_basic_map_free(bmap
);
106 /* Construct a basic map mapping the domain of the affine expression
107 * to a one-dimensional range prescribed by the affine expression.
109 __isl_give isl_basic_map
*isl_basic_map_from_aff(__isl_take isl_aff
*aff
)
111 return isl_basic_map_from_aff2(aff
, 0);
114 /* Construct a map mapping the domain of the affine expression
115 * to a one-dimensional range prescribed by the affine expression.
117 __isl_give isl_map
*isl_map_from_aff(__isl_take isl_aff
*aff
)
121 bmap
= isl_basic_map_from_aff(aff
);
122 return isl_map_from_basic_map(bmap
);
125 /* Construct a basic map mapping the domain of the multi-affine expression
126 * to its range, with each dimension in the range equated to the
127 * corresponding affine expression.
128 * If "rational" is set, then construct a rational basic map.
130 __isl_give isl_basic_map
*isl_basic_map_from_multi_aff2(
131 __isl_take isl_multi_aff
*maff
, int rational
)
140 if (isl_space_dim(maff
->space
, isl_dim_out
) != maff
->n
)
141 isl_die(isl_multi_aff_get_ctx(maff
), isl_error_internal
,
142 "invalid space", goto error
);
144 space
= isl_space_domain(isl_multi_aff_get_space(maff
));
145 bmap
= isl_basic_map_universe(isl_space_from_domain(space
));
147 bmap
= isl_basic_map_set_rational(bmap
);
149 for (i
= 0; i
< maff
->n
; ++i
) {
151 isl_basic_map
*bmap_i
;
153 aff
= isl_aff_copy(maff
->u
.p
[i
]);
154 bmap_i
= isl_basic_map_from_aff2(aff
, rational
);
156 bmap
= isl_basic_map_flat_range_product(bmap
, bmap_i
);
159 bmap
= isl_basic_map_reset_space(bmap
, isl_multi_aff_get_space(maff
));
161 isl_multi_aff_free(maff
);
164 isl_multi_aff_free(maff
);
168 /* Construct a basic map mapping the domain of the multi-affine expression
169 * to its range, with each dimension in the range equated to the
170 * corresponding affine expression.
171 * If "ma" lives in a set space, then the result is actually a set.
173 static __isl_give isl_basic_map
*basic_map_from_multi_aff(
174 __isl_take isl_multi_aff
*ma
)
176 return isl_basic_map_from_multi_aff2(ma
, 0);
179 /* Construct a basic map mapping the domain of the multi-affine expression
180 * to its range, with each dimension in the range equated to the
181 * corresponding affine expression.
183 __isl_give isl_basic_map
*isl_basic_map_from_multi_aff(
184 __isl_take isl_multi_aff
*ma
)
186 if (check_input_is_map(isl_multi_aff_peek_space(ma
)) < 0)
187 ma
= isl_multi_aff_free(ma
);
188 return basic_map_from_multi_aff(ma
);
191 /* Construct a map mapping the domain of the multi-affine expression
192 * to its range, with each dimension in the range equated to the
193 * corresponding affine expression.
194 * If "maff" lives in a set space, then the result is actually a set.
196 __isl_give isl_map
*isl_map_from_multi_aff_internal(
197 __isl_take isl_multi_aff
*maff
)
201 bmap
= basic_map_from_multi_aff(maff
);
202 return isl_map_from_basic_map(bmap
);
205 /* Construct a map mapping the domain the multi-affine expression
206 * to its range, with each dimension in the range equated to the
207 * corresponding affine expression.
209 __isl_give isl_map
*isl_map_from_multi_aff(__isl_take isl_multi_aff
*ma
)
211 if (check_input_is_map(isl_multi_aff_peek_space(ma
)) < 0)
212 ma
= isl_multi_aff_free(ma
);
213 return isl_map_from_multi_aff_internal(ma
);
216 /* Construct a basic map mapping a domain in the given space to
217 * to an n-dimensional range, with n the number of elements in the list,
218 * where each coordinate in the range is prescribed by the
219 * corresponding affine expression.
220 * The domains of all affine expressions in the list are assumed to match
223 __isl_give isl_basic_map
*isl_basic_map_from_aff_list(
224 __isl_take isl_space
*domain_space
, __isl_take isl_aff_list
*list
)
233 space
= isl_space_from_domain(domain_space
);
234 bmap
= isl_basic_map_universe(space
);
236 for (i
= 0; i
< list
->n
; ++i
) {
238 isl_basic_map
*bmap_i
;
240 aff
= isl_aff_copy(list
->p
[i
]);
241 bmap_i
= isl_basic_map_from_aff(aff
);
243 bmap
= isl_basic_map_flat_range_product(bmap
, bmap_i
);
246 isl_aff_list_free(list
);
250 /* Construct a map with as domain the domain of pwaff and
251 * one-dimensional range corresponding to the affine expressions.
252 * If "pwaff" lives in a set space, then the result is actually a set.
254 __isl_give isl_map
*isl_map_from_pw_aff_internal(__isl_take isl_pw_aff
*pwaff
)
263 space
= isl_pw_aff_get_space(pwaff
);
264 map
= isl_map_empty(space
);
266 for (i
= 0; i
< pwaff
->n
; ++i
) {
270 bmap
= isl_basic_map_from_aff(isl_aff_copy(pwaff
->p
[i
].aff
));
271 map_i
= isl_map_from_basic_map(bmap
);
272 map_i
= isl_map_intersect_domain(map_i
,
273 isl_set_copy(pwaff
->p
[i
].set
));
274 map
= isl_map_union_disjoint(map
, map_i
);
277 isl_pw_aff_free(pwaff
);
282 /* Construct a map with as domain the domain of pwaff and
283 * one-dimensional range corresponding to the affine expressions.
285 __isl_give isl_map
*isl_map_from_pw_aff(__isl_take isl_pw_aff
*pwaff
)
287 if (check_input_is_map(isl_pw_aff_peek_space(pwaff
)) < 0)
288 pwaff
= isl_pw_aff_free(pwaff
);
289 return isl_map_from_pw_aff_internal(pwaff
);
292 /* Construct a one-dimensional set with as parameter domain
293 * the domain of pwaff and the single set dimension
294 * corresponding to the affine expressions.
296 __isl_give isl_set
*isl_set_from_pw_aff(__isl_take isl_pw_aff
*pwaff
)
298 if (check_input_is_set(isl_pw_aff_peek_space(pwaff
)) < 0)
299 pwaff
= isl_pw_aff_free(pwaff
);
300 return set_from_map(isl_map_from_pw_aff_internal(pwaff
));
303 /* Construct a map mapping the domain of the piecewise multi-affine expression
304 * to its range, with each dimension in the range equated to the
305 * corresponding affine expression on its cell.
307 * If the domain of "pma" is rational, then so is the constructed "map".
309 __isl_give isl_map
*isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff
*pma
)
317 map
= isl_map_empty(isl_pw_multi_aff_get_space(pma
));
319 for (i
= 0; i
< pma
->n
; ++i
) {
325 rational
= isl_set_is_rational(pma
->p
[i
].set
);
327 map
= isl_map_free(map
);
328 maff
= isl_multi_aff_copy(pma
->p
[i
].maff
);
329 bmap
= isl_basic_map_from_multi_aff2(maff
, rational
);
330 map_i
= isl_map_from_basic_map(bmap
);
331 map_i
= isl_map_intersect_domain(map_i
,
332 isl_set_copy(pma
->p
[i
].set
));
333 map
= isl_map_union_disjoint(map
, map_i
);
336 isl_pw_multi_aff_free(pma
);
340 __isl_give isl_set
*isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff
*pma
)
342 if (check_input_is_set(isl_pw_multi_aff_peek_space(pma
)) < 0)
343 pma
= isl_pw_multi_aff_free(pma
);
344 return set_from_map(isl_map_from_pw_multi_aff(pma
));
347 /* Construct a set or map mapping the shared (parameter) domain
348 * of the piecewise affine expressions to the range of "mpa"
349 * with each dimension in the range equated to the
350 * corresponding piecewise affine expression.
352 static __isl_give isl_map
*map_from_multi_pw_aff(
353 __isl_take isl_multi_pw_aff
*mpa
)
362 if (isl_space_dim(mpa
->space
, isl_dim_out
) != mpa
->n
)
363 isl_die(isl_multi_pw_aff_get_ctx(mpa
), isl_error_internal
,
364 "invalid space", goto error
);
366 space
= isl_multi_pw_aff_get_domain_space(mpa
);
367 map
= isl_map_universe(isl_space_from_domain(space
));
369 for (i
= 0; i
< mpa
->n
; ++i
) {
373 pa
= isl_pw_aff_copy(mpa
->u
.p
[i
]);
374 map_i
= isl_map_from_pw_aff_internal(pa
);
376 map
= isl_map_flat_range_product(map
, map_i
);
379 map
= isl_map_reset_space(map
, isl_multi_pw_aff_get_space(mpa
));
381 isl_multi_pw_aff_free(mpa
);
384 isl_multi_pw_aff_free(mpa
);
388 /* Construct a map mapping the shared domain
389 * of the piecewise affine expressions to the range of "mpa"
390 * with each dimension in the range equated to the
391 * corresponding piecewise affine expression.
393 __isl_give isl_map
*isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff
*mpa
)
395 if (check_input_is_map(isl_multi_pw_aff_peek_space(mpa
)) < 0)
396 mpa
= isl_multi_pw_aff_free(mpa
);
397 return map_from_multi_pw_aff(mpa
);
400 /* Construct a set mapping the shared parameter domain
401 * of the piecewise affine expressions to the space of "mpa"
402 * with each dimension in the range equated to the
403 * corresponding piecewise affine expression.
405 __isl_give isl_set
*isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff
*mpa
)
407 if (check_input_is_set(isl_multi_pw_aff_peek_space(mpa
)) < 0)
408 mpa
= isl_multi_pw_aff_free(mpa
);
409 return set_from_map(map_from_multi_pw_aff(mpa
));
412 /* Convert "pa" to an isl_map and add it to *umap.
414 static isl_stat
map_from_pw_aff_entry(__isl_take isl_pw_aff
*pa
, void *user
)
416 isl_union_map
**umap
= user
;
419 map
= isl_map_from_pw_aff(pa
);
420 *umap
= isl_union_map_add_map(*umap
, map
);
422 return *umap
? isl_stat_ok
: isl_stat_error
;
425 /* Construct a union map mapping the domain of the union
426 * piecewise affine expression to its range, with the single output dimension
427 * equated to the corresponding affine expressions on their cells.
429 __isl_give isl_union_map
*isl_union_map_from_union_pw_aff(
430 __isl_take isl_union_pw_aff
*upa
)
438 space
= isl_union_pw_aff_get_space(upa
);
439 umap
= isl_union_map_empty(space
);
441 if (isl_union_pw_aff_foreach_pw_aff(upa
, &map_from_pw_aff_entry
,
443 umap
= isl_union_map_free(umap
);
445 isl_union_pw_aff_free(upa
);
449 /* Convert "pma" to an isl_map and add it to *umap.
451 static isl_stat
map_from_pw_multi_aff(__isl_take isl_pw_multi_aff
*pma
,
454 isl_union_map
**umap
= user
;
457 map
= isl_map_from_pw_multi_aff(pma
);
458 *umap
= isl_union_map_add_map(*umap
, map
);
463 /* Construct a union map mapping the domain of the union
464 * piecewise multi-affine expression to its range, with each dimension
465 * in the range equated to the corresponding affine expression on its cell.
467 __isl_give isl_union_map
*isl_union_map_from_union_pw_multi_aff(
468 __isl_take isl_union_pw_multi_aff
*upma
)
476 space
= isl_union_pw_multi_aff_get_space(upma
);
477 umap
= isl_union_map_empty(space
);
479 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma
,
480 &map_from_pw_multi_aff
, &umap
) < 0)
483 isl_union_pw_multi_aff_free(upma
);
486 isl_union_pw_multi_aff_free(upma
);
487 isl_union_map_free(umap
);