On 07/02/2012 01:32 PM, Michael Matz wrote:
Hi Tobi,
On Fri, 29 Jun 2012, Tobias Grosser wrote:
+static isl_constraint *
+build_linearized_memory_access (isl_map *map, poly_dr_p pdr)
+{
+}
The function itself looks correct. However, I would personally have returned
an isl_map instead of an isl_constraint.
As you noticed I modelled all my isl code after the existing PPL code
(which returned an expression here, turned into a conflict in the caller).
I couldn't learn the polyhedral basics, PPL basics, isl basics _and_ the
correct isl idioms on one weekend :) So many thanks for the hints.
No worries, I believe a direct translation is a good start. we can
improve later on that.
A map {A[i,j] -> [200 * i]} is probably a nicer way to represent a
transformation from the higher level array type to an actual memory
reference.
Hmm. This ignores the 'j' input dimension. Can I also have a map ala
{A[i,j] -> [200 * i + j]}? I don't directly see how, as for that I'd need
at least another dimension (the 'L' in the callers map).
Yes, you can have this: A[i,j] -> [200 * i + j]}
It is basically a pretty printing of:
{A[i,j] -> [o]: o = 200 * i + j}
The canonical way to express such transformations is to create a
new map and to "apply" this map on the set/map you want to modify. For this
algorithm, I would start with the pdr->accesses map and 'apply'
pbb->transformed to map the original iteration space into the scattering
space.
Let's see if I understand: So, we have [PI]->[aS] (Params, Iteration
domain, alias set, Subscript) as accesses, and we have [PI]->[T]
(Transformed) as the scattering. Indeed what I ideally wanted to have is
a [T]->[aS] mapping, but I couldn't see how to construct such. So you're
saying that I can apply the PI->T to the domain of PI->aS, and that gives
me the T->aS?
You start with a [P] -> {[I] -> [aS]} as accesses and a [P] -> {[I] ->
[T]}. To get [P] -> {[T] -> [aS]} you do the following:
isl_map *Accesses = "[P] -> {[I] -> [aS]}"
isl_map *Scattering = " [P] -> {[I] -> [T]}"
isl_map *TimeToAccess = isl_map_apply_domain(Accesses, Scattering)
isl_map_dump(TimeToAccess);
$ [P] { [T]->[aS] }
Probably I was confused by the functional syntax (the ->),
as in normal functions you can't simply apply a function to a functions
domain and expect to get anything sensible out of that.
No, all those are relations. Reverse and combine them works in general
very well.
> I see that in
your code you reverse the scattering first (T->PI), IIRC that's one thing
I also tried, but I got stuck somewhere.
I don't think reversing is necessary in your case. As the input space of
the scattering, which is "[I]", matches the domain of the access map. So
you can directly use isl_map_apply_domain.
I would than apply the isl_map calculated by
build_linearized_memory_access to map the array to the actual data
location accessed. Now you create a map 'scattering->scattering' that
maps from one scattering time point to the next. And apply the map
'scattering->memory' on both the range and the domain. You will end up
with a map memory -> memory.
Yeah. If my above understanding is correct the path is clear.
I believe it is.
Here you can use the deltas function to give you the distances. ;-)
I couldn't figure out from isls user manual what exactly the delta
functions do :) From the description above I think I understand now. Let
me experiment a bit more.
The delta function calculates the following:
Input: {[a1, a2, a3] -> [b1, b2, b3]: <constraints between a and b> }
Output {[x1, x2, x3] exists a1, a2, a3, b1, b2, b3 : x1 = b1 - a1 and x2
= b2 - a2 and x3 = b3 - a3 and <constraints between a and b> }
So basically it calculates the distances between each possible pair of
input and output values.
You can have a look in Polly, where I implement a similar calculation:
http://repo.or.cz/w/polly-mirror.git/blob/HEAD:/lib/Analysis/ScopInfo.cpp#l390
The games you play with projecting out some dimensions are related to
which dimension you want to calculate the stride, right? (As you always
calculate the next scatterting to have n+1 in the last dimension, not an
arbitrary one).
I always calculate the stride in the last dimension. This is less
general as what you are trying to calculate. The projecting out of
dimensions is just needed due to the ugly CLooG interface, which gives
me a mixture or scattering and domain dimensions. You should need it in gcc.
+print_isl_map (FILE *f, isl_map *map)
If this is the
case, you can either use isl_set_dump(set), isl_map_dump(map), ..
There functions weren't documented. Thanks. But I need a file argument
anyway as the plan is to use them also for debug dumps.
OK.
+ /* Even shorter and more correct method: map the iteration domain
+ through the current scatter, and work on the resulting set. */
+ isl_set_free (lbset);
+ lbset = isl_set_apply (isl_set_copy (pbb->domain),
+ isl_map_copy (pbb->transformed));
+ lpres = isl_set_min (lbset, aff,&isllb);
+ lpres = isl_set_max (lbset, aff,&islub);
+
+ isl_int_sub (islub, islub, isllb);
+ isl_int_add_ui (islub, islub, 1);
This is again modeling the PPL code.
Actually the PPL code translation is the one I removed from my reply here.
The above is what made that code dead and what is in the final version
(with renamed variables and such). Is using _deltas really better? I
would have to construct a map from
lexmin(transformed-domain)->lexmax(transformed-domain), then apply
_delts and the still extract the number.
Yes, you are right. For this specific case, the benefits are less clear.
Cheers
Tobi