Hi,
On Mon, 2 Jul 2012, Tobias Grosser wrote:
> > Yeah. If my above understanding is correct the path is clear.
>
> I believe it is.
It somewhat works. It has problems in those cases where there are
dependencies between different input dimensions in the scattering, which
happens for strip-mining. interchange-8.c for instance.
The core is:
isl_map *subs = isl_map_copy (pdr->accesses);
subs = isl_map_intersect_range (subs, isl_set_copy (pdr->extent));
subs = isl_map_apply_domain (subs, isl_map_copy (pbb->transformed));
subs = isl_map_apply_range (subs, build_linearized_memory_access (pdr));
So, subs is now the [T]->address mapping.
space = isl_space_range (isl_map_get_space (pbb->transformed));
t_to_t1 = isl_map_universe (isl_space_map_from_set (space));
space = isl_map_get_space (t_to_t1);
c = isl_equality_alloc (isl_local_space_from_space (space));
c = isl_constraint_set_coefficient_si (c, isl_dim_in, time_depth, 1);
c = isl_constraint_set_coefficient_si (c, isl_dim_out, time_depth, -1);
c = isl_constraint_set_constant_si (c, 1);
t_to_t1 = isl_map_add_constraint (t_to_t1, c);
t_to_t1 is now the T_depth->T_depth+1 mapping, e.g.:
{ [i0, i1, i2, i3, i4] -> [o0, 1 + i1, o2, o3, o4] }
t_to_t1 = isl_map_apply_domain (t_to_t1, isl_map_copy (subs));
t_to_t1 = isl_map_apply_range (t_to_t1, subs);
Now it's mem_addr -> mem_addr' mapping.
deltas = isl_map_deltas (t_to_t1);
And deltas is the difference, mem_addr' - mem_addr
isl_int_init (islstride);
if (!isl_set_plain_is_fixed (deltas, isl_dim_set, 0, &islstride))
gcc_unreachable ();
So, I want to extract the difference, and that is what doesn't work. In
my initial tries I had this additional loop to construct t_to_t1:
for (i = 0; i < nt; i++)
if (i != time_depth)
t_to_t1 = isl_map_equate (t_to_t1, isl_dim_in, i, isl_dim_out, i);
That is, I enforced also equality on all dimensions except for the
T_depth's one. For interchange-0.c I got these sets:
T->addr: { [0, i1, 0, i3, 0] -> [i1 + 999i3]
: i1 >= 0 and i3 >= 0 and i1 <= 999 and i3 <= 999 }
t_to_t1: { [i0, i1, i2, i3, i4] -> [i0, 1 + i1, i2, i3, i4] }
mem->mem': { [i0] -> [1 + i0] : i0 <= 998999 and i0 >= 0 }
And hence deltas indeed contains a single fixed number that I could
extract. Of course forcing all transformed domains the same breaks
exactly where there are interdependencies, so e.g. interchange-8.c breaks.
So I thought I simply don't equate those. Now the sets for
interchange-0.c look like so:
T->addr: as above
t_to_t1: { [i0, i1, i2, i3, i4] -> [o0, 1 + i1, o2, o3, o4] }
Note how only dimension 1 is constrained.
mem->mem': { [i0] -> [o0]
: exists (e0, e1 = [(998 - i0 + o0 + 999e0)/999]
: 999e1 = 998 - i0 + o0 + 999e0
and 999e0 <= -999 + i0
and e0 >= -1 and 999e0 >= -1997 + i0
and e0 <= 998 and 999e0 <= 997003 + i0 - o0
and 999e0 >= -998 + i0 - o0) }
Doing deltas on that one gives:
{ [i0] :
exists (e0, e1 = [(998 + i0 + 999e0)/999]
: 999e1 = 998 + i0 + 999e0
and 999e0 >= -998 - i0 and e0 >= -1
and 999e0 <= 997003 - i0 and e0 <= 998) } >
So, no fixed number. Doing isl_set_max/min on that doesn't seem to give
sensible results (max=998002, min=-998000). For this specific instance
it's supposed to give '1'.
Hmm. Any thoughts? :)
Ciao,
Michael.