This is an archive of the discontinued LLVM Phabricator instance.

[Polly] [DependenceInfo] Fix isParallel: accept dependences comprised of different spaces.
Needs ReviewPublic

Authored by bollu on May 23 2017, 7:34 AM.

Details

Summary
  • Sometimes, isParallel can receive dependences that are a union_map of

different looking spaces in the maps that correspond to it.

  • Code assumed that the isl_union_map of Dependences could be merged into

one isl_map.

  • Fix code so that we append dummy dimensions to equalize the spaces of

all isl_maps so that the merge is possible.

Event Timeline

bollu created this revision.May 23 2017, 7:34 AM
bollu updated this revision to Diff 100071.May 24 2017, 5:29 AM
  • minimize test case. Testcase is much more readable now.
Meinersbur added inline comments.May 24 2017, 8:50 AM
lib/Analysis/DependenceInfo.cpp
830–831

This adds unrestricted dimensions, i.e. the result is not bounded or single-valued anymore. Not a property a scatter function should have.

Btw, padding with constant 0 is also not generally safe. The other more-dimensional schedule can have positive and/or negative coordinates in the additional dimensions.

833–836

It might be more elegant to initialize info->map with an empty isl_union_map. An advantage is that you don't need special cases when the union_map you are iterating over is empty.

856–858

Did you consider using isl::union_map::foreach_map? It allows you to use C++11-style closures and a lot of boilerplate code.

893

In your test case, I get the following Schedule:

{ Stmt_for_body_inner[i0, i1] -> [o0, o1] : o0 = i0 and o1 = i1; Stmt_for_body[i0] -> [o0, o1, o2] : o0 = i0 and o1 = 0 and o2 = 0 }

I.e. one 2-dimensional and a 3-dimensional scatter space. As far as I know, this should not occur. How did this happen?

test/DependenceInfo/is_parallel_irregular_deps.ll
6

Use < %s instead of %s. Reason.

Even for testing crashes, Polly's regression test have some minimal CHECK to ensure that we don't regress to something trivial, e.g. a do-nothing bail-out. Suggestion:

CHECK: for.body:     Loop is not parallel.
CHECK: for.body.inner:       Loop is parallel.
bollu added inline comments.May 24 2017, 9:22 AM
lib/Analysis/DependenceInfo.cpp
893

Hm, that's strange. I'll check. Perhaps it flattened dimensions that were wrapped which increased the total dimensionality?

This entire flattening business is ugly.

test/DependenceInfo/is_parallel_irregular_deps.ll
6

I see, thank you for the pointer.

bollu added a comment.May 29 2017, 3:18 AM

@Meinersbur: I checked where the schedule is being generated from, and I have a couple questions. Could you please take a look?

lib/Analysis/DependenceInfo.cpp
830–831

In that case, how should I transform it to obtain a correct schedule? Would simply equating the extra dimensions to 0 work?

I'm not sure what you mean by:

The other more-dimensional schedule can have positive and/or negative coordinates in the additional dimensions.

How? since we are manually adding the extra dimensions, are those not automatically zeroed out? I would assume the map looks like this:

f: F^n -> F^(n + 1)
f((a_1, a_2, ..., a_n)) = (a_1, a_2, ..., a_n, 0)

am I mistaken?

893

Just to clarify, by "scatter space" you're referring to the output space of the schedule, right?

The original schedule is this:

child: 
  child: 
    sequence: 
      - 
        filter: "{ Stmt_for_body[i0] }"
      - 
        child: 
          schedule: "[{ Stmt_for_body_inner[i0, i1] -> [(i1)] }]"
        filter: "{ Stmt_for_body_inner[i0, i1] }"
  schedule: "[{ Stmt_for_body[i0] -> [(i0)]; Stmt_for_body_inner[i0, i1] -> [(i0)] }]"
domain: "{ Stmt_for_body[i0] : 0 <= i0 <= 199; Stmt_for_body_inner[i0, i1] : 0 <= i0 <= 199 and 0 <= i1 <= 199 }"

The schedule that is passed to this function arrives from PolyhedralInfo::getScheduleForLoop.

This is called in PolyhedralInfo::checkParallel.

It looks like I need to check why PolyhedralInfo::getScheduleForLoop is generating schedules whose output dimensions don't match?

annanay25 added inline comments.Jul 13 2017, 12:56 AM
lib/Analysis/DependenceInfo.cpp
893

PolyhedralInfo::getScheduleForLoop is generating schedules for 2 statements in its SCoP => one with a 2D scatter space and the other with a 3D scatter space.

This instruction -

ScheduleMap = isl_map_project_out(ScheduleMap, isl_dim_out, CurrDim + 1, MaxDim - CurrDim - 1);

would project the map onto MaxDim - CurrDim - 1 dimensional space which would be 1 and 2, for the two statements, respectively.

So, AFAIU this is correct behavior, but we need a way to canonicalize the generated spaces to the same dimension.

Meinersbur added inline comments.Jul 13 2017, 5:36 AM
lib/Analysis/DependenceInfo.cpp
830–831

Think of a statement and its domain and schedule of:

{ StmtA[i0] : -1 <= i0 <= 1 }
{ StmtA[i0] -> [0, i0] }

If you know have a second stmt

{ StmtB[] }
{ StmtB[] -> [0] }

and pad it with zero

{ StmtB[] -> [0, 0] }

The execution order would be

StmtA[-1]
StmtB[0], StmtA[0] (in parallel, if legal at all)
StmtA[1]

So we placed StmtB somewhere arbitrarily between StmtA instances.

Now, it is unclear what the relative execution order of StmtA and StmtB actually should be. I suggest to not generate such things in the first place, i.e. fix the bug in whoever calls isParallel and add an assertion that checks that there is just one schedule space.

Now it seems that Polly normalizes domains and schedules to start with 0. If that is contractual, then we still have StmtA[0] and StmtB[] in an undefined order. So you could pad with -1 to ensure that the padded schedule functions are executed before the non-padded ones. But be that, we violate that contract (that scatter dimensions are always >= 0).

893

Thank you Annanay.

isl_map_project_out removes information from the schedule, the inner dimensions of the scatter function.

By construction, these should be irrelevant. However, there is a reason why they are there in the first place: To make the schedule range lexicographically comparable. PolyhedralInfo::getScheduleForLoop removes that comparability and I don't see the motivation for that.

It is hard/impossible to restore the comparability without assuming that the removed dimensions are irrelevant.

Instead of deleting the dimensions and then trying to restore them, why not keeping them in the first place?

bollu added inline comments.Jul 18 2017, 1:33 AM
lib/Analysis/DependenceInfo.cpp
893

right, I'll look into fixing getScheduleForLoop in that case.
Thanks, the discussion helped clear this up :)

jdoerfert resigned from this revision.Jun 4 2019, 10:07 PM