錯誤代碼:E2003

類別:編譯時間:Mosaic 未經證明的記憶體存取對齊

當編譯器分析記憶體存取作業 (例如 vector.loadvector.storetpu.loadtpu.store),但無法靜態證明特定維度使用的動態索引是必要分塊大小的倍數時,就會發生這個錯誤。

錯誤訊息示例:

INTERNAL: Mosaic failed to compile TPU kernel: cannot statically prove that index in dimension 1 is a multiple of 128

at location: ...

The MLIR operation involved:
  %14372 = "vector.load"(%14371, %93, %14363) : (memref<4x256xf32, #tpu.memory_space<vmem>>, index, index) -> vector<1x32xf32>

XLA 後端:TPU

總覽

當核心載入或儲存向量時,記憶體位址 (從基本指標加上動態索引計算而來) 必須與硬體上的向量分塊大小對齊。舉例來說,如果某個維度以 128 個元素平鋪,用於存取該維度的動態索引必須是 0128256 等。請注意,許多作業 (例如向量載入和儲存) 對靜態索引沒有這類要求。

編譯器會使用靜態分析強制執行這項規定。這項功能會追蹤索引變數的歷史記錄,回溯產生該變數的算術運算 (例如乘法、加法)。如果編譯器無法保證 (在編譯時) 結果值一律可除以圖塊大小,就會引發這項錯誤。

編譯器會將「已證實的對齊方式不一致」和「不明的對齊方式」視為相同。 因此,如果您使用的索引在數學上保證會錯位 (例如i * 128 + 32),編譯器會引發相同的錯誤。

因此,如果

  1. 您可以使用執行階段變數 (動態索引) 存取記憶體。
  2. 編譯器無法分析索引計算邏輯,因為該邏輯過於複雜。
  3. 索引在數學上有效,但程式碼中缺少明確的證明。
  4. 靜態分析判定「已證實的錯位」。

偵錯

如要解決這項錯誤,請採取下列任一做法:

1. 明確斷言對齊

如果您知道索引有效,但編譯器無法證明,請使用 tpu.assume_multiple 作業。這會向編譯器保證值可除以特定因數。

2. 使用「對齊載入」和「旋轉」

如果刻意不對齊,請勿載入小型未對齊的向量區隔,而是:

  • 載入較大的完整對齊圖塊,然後以動態量旋轉值,將所需資料移至適當位置 (因為系統不支援具有動態開始索引的向量切片)。或
  • 重塑或填補張量,使資料從索引 0 開始,且存取之間的步幅符合硬體對齊方式。
    • 舉例來說,如果您從位移 1 開始,以大小為 32 的區塊進行疊代,位移會是 1、33、65... (未對齊)。
    • 修正方式:將資料重新封裝到新張量中,其中第一個區塊位於 0,且維度會填補至 128。您的位移會變成 0、128、256...,符合對齊規定。

這些方法會耗用較多記憶體,但通常可簡化核心邏輯,且不必手動進行對齊斷言。