From: Sven Verdoolaege Date: Thu, 19 Apr 2012 19:55:09 +0000 (+0200) Subject: add isl_map_{lexmin,lexmax}_pw_multi_aff X-Git-Tag: isl-0.11~244 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca8de11cdbc31be5098bd60495406144696f4343;p=platform%2Fupstream%2Fisl.git add isl_map_{lexmin,lexmax}_pw_multi_aff Signed-off-by: Sven Verdoolaege --- diff --git a/Makefile.am b/Makefile.am index c650752..e1f26b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -239,6 +239,7 @@ EXTRA_DIST = \ basis_reduction_templ.c \ isl_list_templ.c \ isl_list_templ.h \ + isl_map_lexopt_templ.c \ isl_multi_templ.c \ isl_multi_templ.h \ print_templ.c \ diff --git a/doc/user.pod b/doc/user.pod index 12e5470..46e5a4c 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -2859,6 +2859,10 @@ returning a basic set or relation. __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom, __isl_give isl_set **empty); + __isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff( + __isl_take isl_map *map); + __isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff( + __isl_take isl_map *map); =head2 Lists diff --git a/include/isl/map.h b/include/isl/map.h index ecba464..7613b06 100644 --- a/include/isl/map.h +++ b/include/isl/map.h @@ -257,6 +257,10 @@ __isl_give isl_pw_multi_aff *isl_basic_map_partial_lexmax_pw_multi_aff( __isl_give isl_set **empty); __isl_give isl_pw_multi_aff *isl_basic_map_lexmin_pw_multi_aff( __isl_take isl_basic_map *bmap); +__isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff( + __isl_take isl_map *map); +__isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff( + __isl_take isl_map *map); void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap, FILE *out, int indent); diff --git a/isl_map.c b/isl_map.c index c1ab54a..290ee4e 100644 --- a/isl_map.c +++ b/isl_map.c @@ -5618,58 +5618,93 @@ __isl_give isl_pw_multi_aff *isl_basic_map_lexmin_pw_multi_aff( return isl_basic_map_lexopt_pw_multi_aff(bmap, 0); } -/* Given a basic map "bmap", compute the lexicographically minimal - * (or maximal) image element for each domain element in dom. +#undef TYPE +#define TYPE isl_pw_multi_aff +#undef SUFFIX +#define SUFFIX _pw_multi_aff +#undef EMPTY +#define EMPTY isl_pw_multi_aff_empty +#undef ADD +#define ADD isl_pw_multi_aff_union_add +#include "isl_map_lexopt_templ.c" + +/* Given a map "map", compute the lexicographically minimal + * (or maximal) image element for each domain element in dom, + * in the form of an isl_pw_multi_aff. * Set *empty to those elements in dom that do not have an image element. * - * We first make sure the basic sets in dom are disjoint and then - * simply collect the results over each of the basic sets separately. - * We could probably improve the efficiency a bit by moving the union - * domain down into the parametric integer programming. + * We first compute the lexicographically minimal or maximal element + * in the first basic map. This results in a partial solution "res" + * and a subset "todo" of dom that still need to be handled. + * We then consider each of the remaining maps in "map" and successively + * update both "res" and "todo". */ -static __isl_give isl_map *basic_map_partial_lexopt( - __isl_take isl_basic_map *bmap, __isl_take isl_set *dom, - __isl_give isl_set **empty, int max) +static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, int max) { int i; - struct isl_map *res; + isl_pw_multi_aff *res; + isl_set *todo; - dom = isl_set_make_disjoint(dom); - if (!dom) + if (!map || !dom) goto error; - if (isl_set_plain_is_empty(dom)) { - res = isl_map_empty_like_basic_map(bmap); - *empty = isl_set_empty_like(dom); - isl_set_free(dom); - isl_basic_map_free(bmap); - return res; + if (isl_map_plain_is_empty(map)) { + if (empty) + *empty = dom; + else + isl_set_free(dom); + return isl_pw_multi_aff_from_map(map); } - res = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap), - isl_basic_set_copy(dom->p[0]), empty, max); - - for (i = 1; i < dom->n; ++i) { - struct isl_map *res_i; - struct isl_set *empty_i; + res = basic_map_partial_lexopt_pw_multi_aff( + isl_basic_map_copy(map->p[0]), + isl_set_copy(dom), &todo, max); - res_i = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap), - isl_basic_set_copy(dom->p[i]), &empty_i, max); + for (i = 1; i < map->n; ++i) { + isl_pw_multi_aff *res_i; + isl_set *todo_i; - res = isl_map_union_disjoint(res, res_i); - *empty = isl_set_union_disjoint(*empty, empty_i); + res_i = basic_map_partial_lexopt_pw_multi_aff( + isl_basic_map_copy(map->p[i]), + isl_set_copy(dom), &todo_i, max); + + if (max) + res = isl_pw_multi_aff_union_lexmax(res, res_i); + else + res = isl_pw_multi_aff_union_lexmin(res, res_i); + + todo = isl_set_intersect(todo, todo_i); } isl_set_free(dom); - isl_basic_map_free(bmap); + isl_map_free(map); + + if (empty) + *empty = todo; + else + isl_set_free(todo); + return res; error: - *empty = NULL; + if (empty) + *empty = NULL; isl_set_free(dom); - isl_basic_map_free(bmap); + isl_map_free(map); return NULL; } +#undef TYPE +#define TYPE isl_map +#undef SUFFIX +#define SUFFIX +#undef EMPTY +#define EMPTY isl_map_empty +#undef ADD +#define ADD isl_map_union_disjoint +#include "isl_map_lexopt_templ.c" + /* Given a map "map", compute the lexicographically minimal * (or maximal) image element for each domain element in dom. * Set *empty to those elements in dom that do not have an image element. @@ -5678,7 +5713,7 @@ error: * in the first basic map. This results in a partial solution "res" * and a subset "todo" of dom that still need to be handled. * We then consider each of the remaining maps in "map" and successively - * improve both "res" and "todo". + * update both "res" and "todo". * * Let res^k and todo^k be the results after k steps and let i = k + 1. * Assume we are computing the lexicographical maximum. @@ -5797,35 +5832,6 @@ error: return NULL; } -/* Given a map "map", compute the lexicographically minimal - * (or maximal) image element for each domain element in dom. - * Set *empty to those elements in dom that do not have an image element. - * - * Align parameters if needed and then call isl_map_partial_lexopt_aligned. - */ -static __isl_give isl_map *isl_map_partial_lexopt( - __isl_take isl_map *map, __isl_take isl_set *dom, - __isl_give isl_set **empty, int max) -{ - if (!map || !dom) - goto error; - if (isl_space_match(map->dim, isl_dim_param, dom->dim, isl_dim_param)) - return isl_map_partial_lexopt_aligned(map, dom, empty, max); - if (!isl_space_has_named_params(map->dim) || - !isl_space_has_named_params(dom->dim)) - isl_die(map->ctx, isl_error_invalid, - "unaligned unnamed parameters", goto error); - map = isl_map_align_params(map, isl_map_get_space(dom)); - dom = isl_map_align_params(dom, isl_map_get_space(map)); - return isl_map_partial_lexopt_aligned(map, dom, empty, max); -error: - if (empty) - *empty = NULL; - isl_set_free(dom); - isl_map_free(map); - return NULL; -} - __isl_give isl_map *isl_map_partial_lexmax( __isl_take isl_map *map, __isl_take isl_set *dom, __isl_give isl_set **empty) @@ -5893,31 +5899,6 @@ __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset) return (isl_set *)isl_basic_map_lexmax((isl_basic_map *)bset); } -__isl_give isl_map *isl_map_lexopt(__isl_take isl_map *map, int max) -{ - struct isl_set *dom = NULL; - isl_space *dom_dim; - - if (!map) - goto error; - dom_dim = isl_space_domain(isl_space_copy(map->dim)); - dom = isl_set_universe(dom_dim); - return isl_map_partial_lexopt(map, dom, NULL, max); -error: - isl_map_free(map); - return NULL; -} - -__isl_give isl_map *isl_map_lexmin(__isl_take isl_map *map) -{ - return isl_map_lexopt(map, 0); -} - -__isl_give isl_map *isl_map_lexmax(__isl_take isl_map *map) -{ - return isl_map_lexopt(map, 1); -} - __isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set) { return (isl_set *)isl_map_lexmin((isl_map *)set); diff --git a/isl_map_lexopt_templ.c b/isl_map_lexopt_templ.c new file mode 100644 index 0000000..275c14f --- /dev/null +++ b/isl_map_lexopt_templ.c @@ -0,0 +1,132 @@ +/* + * Copyright 2010 INRIA Saclay + * Copyright 2012 Ecole Normale Superieure + * + * Use of this software is governed by the GNU LGPLv2.1 license + * + * Written by Sven Verdoolaege, + * INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, + * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France + * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France + */ + +/* Function for computing the lexicographic optimum of a map + * in the form of either an isl_map or an isl_pw_multi_aff. + */ + +#define xSF(TYPE,SUFFIX) TYPE ## SUFFIX +#define SF(TYPE,SUFFIX) xSF(TYPE,SUFFIX) + +/* Given a basic map "bmap", compute the lexicographically minimal + * (or maximal) image element for each domain element in dom. + * Set *empty to those elements in dom that do not have an image element. + * + * We first make sure the basic sets in dom are disjoint and then + * simply collect the results over each of the basic sets separately. + * We could probably improve the efficiency a bit by moving the union + * domain down into the parametric integer programming. + */ +static __isl_give TYPE *SF(basic_map_partial_lexopt,SUFFIX)( + __isl_take isl_basic_map *bmap, __isl_take isl_set *dom, + __isl_give isl_set **empty, int max) +{ + int i; + TYPE *res; + + dom = isl_set_make_disjoint(dom); + if (!dom) + goto error; + + if (isl_set_plain_is_empty(dom)) { + isl_space *space = isl_basic_map_get_space(bmap); + if (empty) + *empty = dom; + else + isl_set_free(dom); + isl_basic_map_free(bmap); + return EMPTY(space); + } + + res = SF(isl_basic_map_partial_lexopt,SUFFIX)(isl_basic_map_copy(bmap), + isl_basic_set_copy(dom->p[0]), empty, max); + + for (i = 1; i < dom->n; ++i) { + TYPE *res_i; + isl_set *empty_i; + + res_i = SF(isl_basic_map_partial_lexopt,SUFFIX)( + isl_basic_map_copy(bmap), + isl_basic_set_copy(dom->p[i]), &empty_i, max); + + res = ADD(res, res_i); + *empty = isl_set_union_disjoint(*empty, empty_i); + } + + isl_set_free(dom); + isl_basic_map_free(bmap); + return res; +error: + *empty = NULL; + isl_set_free(dom); + isl_basic_map_free(bmap); + return NULL; +} + +static __isl_give TYPE *SF(isl_map_partial_lexopt_aligned,SUFFIX)( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, int max); + +/* Given a map "map", compute the lexicographically minimal + * (or maximal) image element for each domain element in dom. + * Set *empty to those elements in dom that do not have an image element. + * + * Align parameters if needed and then call isl_map_partial_lexopt_aligned. + */ +static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)( + __isl_take isl_map *map, __isl_take isl_set *dom, + __isl_give isl_set **empty, int max) +{ + if (!map || !dom) + goto error; + if (isl_space_match(map->dim, isl_dim_param, dom->dim, isl_dim_param)) + return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom, + empty, max); + if (!isl_space_has_named_params(map->dim) || + !isl_space_has_named_params(dom->dim)) + isl_die(map->ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + map = isl_map_align_params(map, isl_map_get_space(dom)); + dom = isl_map_align_params(dom, isl_map_get_space(map)); + return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom, empty, max); +error: + if (empty) + *empty = NULL; + isl_set_free(dom); + isl_map_free(map); + return NULL; +} + +__isl_give TYPE *SF(isl_map_lexopt,SUFFIX)(__isl_take isl_map *map, int max) +{ + isl_set *dom = NULL; + isl_space *dom_space; + + if (!map) + goto error; + dom_space = isl_space_domain(isl_space_copy(map->dim)); + dom = isl_set_universe(dom_space); + return SF(isl_map_partial_lexopt,SUFFIX)(map, dom, NULL, max); +error: + isl_map_free(map); + return NULL; +} + +__isl_give TYPE *SF(isl_map_lexmin,SUFFIX)(__isl_take isl_map *map) +{ + return SF(isl_map_lexopt,SUFFIX)(map, 0); +} + +__isl_give TYPE *SF(isl_map_lexmax,SUFFIX)(__isl_take isl_map *map) +{ + return SF(isl_map_lexopt,SUFFIX)(map, 1); +}