Hi!
I’m confused about the semantics of affine_maps
in memref
s, specifically the fact that these two are valid seems to imply either the codomain of the affine_map
is not uniquely determined, or there is something implicit going on:
memref<42x16xf32, affine_map<(i, j) -> (33 + i + 64 * j)>>
-
memref<42x16xf32>
which per the documentation meansmemref<42x16xf32, affine_map<(i, j) -> (i, j)>>
The codomain seems to be either one-dimensional, or two-dimensional, for this memref
.
As another motivating example, what are the semantics of an affine_map<(i, j) -> (i * 42, (i + j) * 3)>
, where the domain of (i, j)
is [0..5)x[0..5)
, when in a memref
? What memref
s can this be attached to?
To posit the question in full generality: Let v
be a value of type memref<d_1 x d_2 x ... x d_n, affine_map<f>>
, with f(x_1, x_2, ..., x_k) = (e_1, e_2, ..., e_m)
, where each e_i
is an expression of all of the x_j
. What can we say about the relation between variables, and what is the semantics that we should infer about reads into this memref?
One interpretation is that there’s an implicit linearization map attached to these memrefs
, that does range inference on the e_i
. That is, if the range of e_i
is [0 .. r_i)
, and we call the suffix sums s_i = \sum_{j = i + 1}^m r_j
, s
standing for “stride” here, then the implicit linearization map is g(y_1, y_2, ..., y_m) = \sum_{i = 1}^m y_i * s_i
, and this gives us an offset into the base of the memref. This assumes that the range of each e_i
is indeed computable as [0 .. r_i)
. The full affine map would then be the composition g \circ f
, giving us a coordinate map from the range of x_1, x_2, ..., x_k
, to the integers. A read into this memref
would then specify k
coordinates, matching the range of the x_1, x_2, ..., x_k
. Is this the right understanding?