從 .NET 11 開始,張量運算使用一致的形狀對齊規則。 預設的秩為零的空張量與跨度在計算過程中具有有效形狀 [0],且操作在對齊形狀時可忽略冗餘的前置單例維度。
此變更是在 System.Numerics.Tensors 套件中提供,包含其支援的目標框架。 更新套件可能會影響針對較早期 .NET 版本的應用程式。
所推出的版本
.NET 11
以前的行為
張量運算對形狀的處理不一致。 有些操作需要精確的形狀匹配,而其他操作則以不同方式對齊各維度。 因此,具有冗餘前導單元素維度的等價形狀,如 [1, 1, 3] 和 [3],可能會被拒絕或在不同操作間有不同的解釋。
預設的空張量與跨度保留秩為零的中繼資料,但操作並不一致地將它們視為有效形狀為 [0] 的向量。 堆疊與串接操作也可能根據輸入秩對軸有不同解釋。
部分操作也會將邏輯元素計數或偏移量縮減至 int,這使得原生支援的、包含超過 int.MaxValue 個元素的張量跨度無法被正確周遊。
EqualsAny、GreaterThanAny、GreaterThanOrEqualAny、LessThanAny 和 LessThanOrEqualAny 這些運算並未一致檢查完整的邏輯輸入長度,即使對於空輸入也是如此。
新行為
張量運算現在使用共享的形狀對齊規則:
- 預設的秩為零的空張量與跨度在計算中具有有效形狀
[0]。 其儲存的Rank、Lengths和Strides不會改變,且明確排序的空形狀會保持其維度。 - 操作可以在對齊形狀時新增或移除冗餘的前導單元素尺寸。 例如,
[1, 1, 3]與[3]對齊,但[2, 1]和[1, 2]保持不同。 零長度維度與非前導單元素維度仍然有意義。 - 形狀相等性僅忽略冗餘的前導單元素維度。 它不會套用到其他維度。
- 堆疊與串聯操作則透過第一個輸入的有效形狀來解釋軸線。 其他輸入和目的地則對齊該形狀。
- 預設的空值可以廣播到
[2, 0]。 有效形狀[0]與[0, 2]之間的二元運算會拒絕不相容的尾隨尺寸。 - 當操作對齊來源與目的地時,來源與目的地會保留其請求的形狀元資料。
原生支援的張量範圍現在可以使用原生大小的長度和位移進行周遊,包括包含超過 int.MaxValue 個邏輯項目的範圍。 空視圖在其來源中也會保留儲存來源。
EqualsAny、GreaterThanAny、GreaterThanOrEqualAny、LessThanAny 及 LessThanOrEqualAny 操作現在能檢查完整的邏輯輸入範圍,並正確處理空輸入。
破壞性變更的類型
這是一種 行為改變。
變更原因
一致的形狀規則使張量運算更具可預測性,並保留明確要求的維度,同時允許等價形狀協同運作。 原生大小遍歷也讓操作能涵蓋由較大儲存體支援的跨度之完整邏輯範圍。
更多資訊請參見 dotnet/runtime#135060。
建議的動作
檢視依賴張量運算接受或拒絕特定形狀組合的程式碼。 將預設的秩為零的空值視為有效形狀為 [0],並在對齊與形狀比較時忽略冗餘的前導單例維度。 明確的零長度維度與非前導單例維度仍然顯著。
對於堆疊與串接操作,將軸理解為相對於第一個輸入的有效形狀。 如果你的程式碼需要精確的已儲存階數或長度,請在呼叫操作前驗證這些中繼資料。 預設空值的儲存元資料不會改變。
受影響的 API
- Tensor.Broadcast、Tensor.BroadcastTo 和 Tensor.TryBroadcastTo
- 在 Tensor 上對齊張量形狀或寫入呼叫者提供之目的地的逐元素與複製操作
- Tensor.Concatenate、Tensor.ConcatenateOnDimension、Tensor.Stack 和 Tensor.StackAlongDimension
- Tensor.Reshape、Tensor.Split、Tensor.SqueezeDimension、Tensor.Unsqueeze、Tensor.PermuteDimensions、Tensor.SequenceEqual、Tensor.ResizeTo、Tensor.Reverse、Tensor.SetSlice和Tensor.ReverseDimension
- Tensor.EqualsAny、Tensor.GreaterThanAny、Tensor.GreaterThanOrEqualAny、Tensor.LessThanAny 和 Tensor.LessThanOrEqualAny
- Tensor.IndexOfMax、Tensor.IndexOfMaxMagnitude、Tensor.IndexOfMin 和 Tensor.IndexOfMinMagnitude