From 70155a51c5bbcf79c389c0836d5a401ce862b652 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 20 Jul 2012 14:07:37 +0200 Subject: [PATCH] add isl_multi_aff_pullback_multi_aff Signed-off-by: Sven Verdoolaege --- doc/user.pod | 9 +++++++++ include/isl/aff.h | 3 +++ isl_aff.c | 34 ++++++++++++++++++++++++++++++++++ isl_test.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index 426a943..521773a 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -3932,6 +3932,15 @@ If the C argument of C is not C, then it is assigned the local space that lies at the basis of the lifting applied. + #include + __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, + __isl_take isl_multi_aff *ma2); + +The function C precomposes C by C. +In other words, C is plugged +into C. + __isl_give isl_set *isl_multi_aff_lex_le_set( __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); diff --git a/include/isl/aff.h b/include/isl/aff.h index d5527f9..3f548ff 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -333,6 +333,9 @@ __isl_give isl_multi_aff *isl_multi_aff_gist(__isl_take isl_multi_aff *maff, __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff, __isl_give isl_local_space **ls); +__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); + __isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2); __isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1, diff --git a/isl_aff.c b/isl_aff.c index 1117f4d..cfd08a7 100644 --- a/isl_aff.c +++ b/isl_aff.c @@ -3552,6 +3552,40 @@ error: return NULL; } +/* Compute the pullback of "ma1" by the function represented by "ma2". + * In other words, plug in "ma2" in "ma1". + */ +__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( + __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) +{ + int i; + isl_space *space = NULL; + + ma2 = isl_multi_aff_align_divs(ma2); + ma1 = isl_multi_aff_cow(ma1); + if (!ma1 || !ma2) + goto error; + + space = isl_space_join(isl_multi_aff_get_space(ma2), + isl_multi_aff_get_space(ma1)); + + for (i = 0; i < ma1->n; ++i) { + ma1->p[i] = isl_aff_pullback_multi_aff(ma1->p[i], + isl_multi_aff_copy(ma2)); + if (!ma1->p[i]) + goto error; + } + + ma1 = isl_multi_aff_reset_space(ma1, space); + isl_multi_aff_free(ma2); + return ma1; +error: + isl_space_free(space); + isl_multi_aff_free(ma2); + isl_multi_aff_free(ma1); + return NULL; +} + /* Extend the local space of "dst" to include the divs * in the local space of "src". */ diff --git a/isl_test.c b/isl_test.c index 60f70a5..17d9c83 100644 --- a/isl_test.c +++ b/isl_test.c @@ -3239,12 +3239,60 @@ int test_preimage(isl_ctx *ctx) } struct { + const char *ma1; + const char *ma; + const char *res; +} pullback_tests[] = { + { "{ B[i,j] -> C[i + 2j] }" , "{ A[a,b] -> B[b,a] }", + "{ A[a,b] -> C[b + 2a] }" }, + { "{ B[i] -> C[2i] }", "{ A[a] -> B[(a)/2] }", "{ A[a] -> C[a] }" }, + { "{ B[i] -> C[(i)/2] }", "{ A[a] -> B[2a] }", "{ A[a] -> C[a] }" }, + { "{ B[i] -> C[(i)/2] }", "{ A[a] -> B[(a)/3] }", + "{ A[a] -> C[(a)/6] }" }, + { "{ B[i] -> C[2i] }", "{ A[a] -> B[5a] }", "{ A[a] -> C[10a] }" }, + { "{ B[i] -> C[2i] }", "{ A[a] -> B[(a)/3] }", + "{ A[a] -> C[(2a)/3] }" }, + { "{ B[i,j] -> C[i + j] }", "{ A[a] -> B[a,a] }", "{ A[a] -> C[2a] }"}, + { "{ B[a] -> C[a,a] }", "{ A[i,j] -> B[i + j] }", + "{ A[i,j] -> C[i + j, i + j] }"}, + { "{ B[i] -> C[([i/2])] }", "{ B[5] }", "{ C[2] }" }, + { "[n] -> { B[i,j] -> C[([i/2]) + 2j] }", + "[n] -> { B[n,[n/3]] }", "[n] -> { C[([n/2]) + 2*[n/3]] }", }, +}; + +static int test_pullback(isl_ctx *ctx) +{ + int i; + isl_multi_aff *ma1, *ma2; + isl_multi_aff *ma; + int equal; + + for (i = 0; i < ARRAY_SIZE(pullback_tests); ++i) { + ma1 = isl_multi_aff_read_from_str(ctx, pullback_tests[i].ma1); + ma = isl_multi_aff_read_from_str(ctx, pullback_tests[i].ma); + ma2 = isl_multi_aff_read_from_str(ctx, pullback_tests[i].res); + ma1 = isl_multi_aff_pullback_multi_aff(ma1, ma); + equal = isl_multi_aff_plain_is_equal(ma1, ma2); + isl_multi_aff_free(ma1); + isl_multi_aff_free(ma2); + if (equal < 0) + return -1; + if (!equal) + isl_die(ctx, isl_error_unknown, "bad pullback", + return -1); + } + + return 0; +} + +struct { const char *name; int (*fn)(isl_ctx *ctx); } tests [] = { { "list", &test_list }, { "align parameters", &test_align_parameters }, { "preimage", &test_preimage }, + { "pullback", &test_pullback }, { "eliminate", &test_eliminate }, { "reisdue class", &test_residue_class }, { "div", &test_div }, -- 2.7.4