StanfordLegion / legion

The Legion Parallel Programming System
https://legion.stanford.edu
Apache License 2.0
675 stars 145 forks source link

regent: support for indirect copies (gather/scatter, both unstructured and affine) #704

Open streichler opened 4 years ago

streichler commented 4 years ago

We need to decide on the language syntax for this and then go implement it.

elliottslaughter commented 4 years ago

@streichler Can you please propose a syntax?

streichler commented 4 years ago

For unstructured copies, the syntax that seems intuitive to me is:

gather: copy(r.a->s.b, t.c, ...) === for i in t do t.c[i] = s.b[r.a[i]] end scatter: copy(r.a, s.b->t.c, ...) === for i in s do t.c[s.b[i]] = r.a[i] end both: copy(r.a->s.b, t.c->u.d, ...) === for i in t do u.d[t.c[i]] = s.b[r.a[i]] end

This keeps the existing rule that the destination's index space controls the copy, but it does deviate from most other regent syntax by using an operator (->) to signify indirection rather than a word. As with normal copies, more than one data field can be specified (or omitted to indicate all fields).

For structured copies, we don't have an indirection field to implicitly give us the copy domain, so we need an explicit index space argument but we'd also need a dummy iteration variable that we can do math on. For example: copy(p, r.a, s.b[{_i.x + 1, _i.y - 5}], ...) === for i in p do s.b[{i.x + 1, i.y - 5}] = r.a[i] end or maybe: copy(i in p, r.a, s.b[{i.x + 1, i.y - 5}], ...) or maybe just: for i in p do s.b[{i.x + 1, i.y - 5}] = r.a[i] end and rely on an index-launch-like analysis to turn it back into a copy? I'm not a huge fan of the magic variable name in the first one, and the third one needs to invent a syntax for barrier arrival, so I guess I'd vote for the second option as the least ugly, but I'm not wild about it.

streichler commented 4 years ago

Another idea for structured copy syntax, borrowed from ZPL (and also used in the deppart formalism):

direction foo = [ +1, -5 ];
copy(r.a, p.foo->s.b, ...)

with the thing to the left of the foo (i.e. p in the example above) being either an index space or a region (whose index space should be used as the domain of the structured transform).

For wrapping operations, ZPL controlled that on use (e.g. B@^east as the wrapping version of B@east), but that can be ambiguous when performing an operation on a subset of B (do you want to wrap around the original boundaries of B or the boundaries of the subset?), so I'd instead want to augment the direction syntax:

direction foo_wrapped = [ +1, 5 ] wrapped around p;

(with probably more concise syntax than that). Further syntactic additions would allow for the up/down-scaling needed for multi-resolution "directions" as well (e.g. {x,y} -> { (2*x+1)%16, floor(x/2) - 5 }).