advanced26 min studyLesson 521 in Engineering

Affine accesses and legal execution order

Separate analyzable index expressions from permission to reorder dependent operations.

On this page

What you’ll understand

  • Recognize an affine index expression under declared constant coefficients.
  • Interpret a dependence direction before interchanging loops.
  • Distinguish structural analyzability from transformation legality.

A compiler can represent many loop accesses as affine expressions and use that structure to analyze iteration domains and dependencies. Being affine does not mean iterations are independent. A later iteration may require a value produced earlier, and a seemingly harmless change of loop order can reverse that relationship. Follow concrete source and destination iterations before deciding whether a schedule transformation preserves the computation.

An access function describes where an iteration reads

For fixed integer coefficients, an expression such as 32 i+j+4 maps loop coordinates to a linearized element index. Multiplying two varying induction variables, such as i×j, is not affine. MLIR's Affine dialect also distinguishes dimensions and symbols under defined validity rules; do not assume every loop-invariant expression is automatically a legal symbol. Dynamic strides can require a different representation or stronger assumptions than a constant-coefficient example. The lesson uses mathematical index expressions rather than version-sensitive parser syntax.

The iteration domain matters as much as the subscript. Bounds, guards, and shape assumptions determine which operations actually execute and whether addresses are in range. Two distinct logical accesses may alias through views or shared buffers, so different variable names are not proof of independence. Analysis must include relevant reads, writes, and effects. Affine structure makes some questions tractable; it does not erase unknown calls or permit unsupported assumptions about external memory.

a(i,j)=32i+j+4a(i,j)=32i+j+4
i and j are integer iteration coordinates and all coefficients are fixed integers. a is an element index, not a byte address. Valid bounds and backing storage must be supplied separately; the constant 32 is not a varying symbolic stride.↔ Scroll wide equations horizontally.

A dependence constrains the schedule

A flow dependence connects a write that produces a value to a later read that must observe it. Anti-dependences and output dependences also constrain transformations when buffers are reused. For lexicographic loop execution, a legal schedule keeps every required source before its destination. An interchange permutes schedule coordinates and can turn a previously positive dependence into a negative one. Inspect the first nonzero component after permutation rather than merely observing that the loop bounds remain unchanged.

For a recurrence reading A[i−1, j+1], the dependence from its producer to consumer has displacement(1, −1). With i outermost, the positive first component preserves row-to-row production. Swapping to an increasing j-outer schedule makes the first component negative and can read a value before its producer runs. Some transformations can repair a schedule through skewing or other changes, but an unmodified interchange is not justified by a locality benefit alone.

Δ=(1,−1),swap⁡(Δ)=(−1,1)\Delta=(1,-1),\qquad\operatorname{swap}(\Delta)=(-1,1)
Δ is destination minus source iteration coordinate for the stated recurrence. Its lexicographic sign depends on loop order. This example assumes increasing loops, the specified domain, and no transformation that otherwise repairs the dependence.↔ Scroll wide equations horizontally.

State semantics before optimizing the schedule

Integer overflow, floating-point reductions, exceptions, and side effects can impose constraints beyond ordinary array dependences. Mathematical equality over real numbers does not establish identical IEEE floating-point behavior. LLVM 20.1.0 documents explicit fast-math permissions; changing reduction order needs the relevant source and IR contract rather than an assumption that neural workloads tolerate anything. Save the original domain, alias assumptions, and numeric mode with a transformation test so a passing easy input is not mistaken for a proof.

The matrix lab illustrates an affine-looking geometric map only. Reset and set both diagonal scale a=1 and shear b=1, predict determinant 1 and the unit-square shear, then Step. Its selected matrix is [[a, b], [0,1]], and readouts describe that final matrix while playback interpolates geometry. It does not analyze loop domains, integer lattices, aliases, or dependences. Explain why a visually invertible map cannot certify that a reordered recurrence reads the same versions of memory.

An interchange that reads too early

Initialize a 3×3 array to zero. For i=1,2 outermost and j=0,1 innermost, execute A[i, j]=A[i−1, j+1]+1 using exact integers. Compare A[2,0] after interchanging the increasing loops.

  1. In the original order, row 1 positions 0 and 1 become 1 before row 2 begins. A[2,0] then reads A[1,1]=1 and becomes 2.

  2. With j outermost, j=0 runs i=1 and then i=2 before j=1. A[2,0] reads the still-zero A[1,1] and becomes 1.

  3. The two results differ despite identical domains and affine-looking accesses. The dependence displacement(1, −1) becomes lexicographically negative under the swapped increasing schedule, explaining the failure.

The result

The schedule must preserve dependence order. Faster contiguous traversal cannot justify changing a required producer-consumer relationship.

Explore the model

Interactive lab

Interactive lab · matrix

A map is not a dependence proof

Reset, set a=1, b=1;predict determinant 1 and a sheared unit square, then Step. This two-dimensional matrix family does not solve loop legality, aliases, or iteration dependencies; readouts always describe the selected final map.

A map is not a dependence proofThe selected matrix is A = [[a,b],[0,1]]. Playback interpolates geometry between the identity and A; readouts always describe A. Its determinant is a and its singular values come from AᵀA. Positive a makes every supported matrix invertible. This two-dimensional family is not a general eigensolver or a learned network. Current readings: Area scale · det A: 1.4; Singular values · σmax, σmin: 1.597, 0.876; Condition number · κ₂(A): 1.823. All parameters are adjustable with the labeled controls below.Matrix A with first row 1.4, 0.6 and second row zero, one; display interpolates between identity and A while final determinant remains 1.4.−4−2024−2−1012x · equal geometric scaleyA = [ 1.4 0.6 ; 0 1 ]Display blend: 0% · final values below
Interpolated geometryOriginal unit squareSelected final transform
Area scale · det A
1.4
Singular values · σmax, σmin
1.597, 0.876
Condition number · κ₂(A)
1.823
t = 0 s

The selected matrix is A = [[a,b],[0,1]]. Playback interpolates geometry between the identity and A; readouts always describe A. Its determinant is a and its singular values come from AᵀA. Positive a makes every supported matrix invertible. This two-dimensional family is not a general eigensolver or a learned network. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.

Look forAnalyze operation order and memory versions separately from geometric index transformations.

Check your understanding

Why can loop interchange be illegal even when all access expressions are affine?

Try it yourself

An increasing two-loop nest has a dependence displacement(0,1). What happens to its lexicographic direction after swapping the coordinates, and what additional information is still needed for full legality?

Take a moment to make a prediction or work it out on paper. Open a hint when you need one.

Give me a hint

Permute the displacement and inspect its first nonzero component.

Compare with the solution

The swapped displacement is(1,0), still lexicographically positive, so this one dependence is preserved. That does not prove the entire interchange legal: analyze all other dependences, alias relationships, domain constraints, effects, and numerical semantics. One safe edge or one passing example cannot stand in for the full transformation contract.

Take it with you

  • Affine access structure does not imply independent iterations.
  • A legal schedule preserves every required dependence and effect.
  • Real-number algebra and strict floating-point semantics are different contracts.

Read further

Original sources and deeper explanations to follow at your own pace.

Optional progress, saved in this browser when available. Revisit any lesson at any time.

Lesson not marked complete.