Tensor 操作は、サポートされていないストレージ レイアウトを拒否します

.NET 11 以降、多次元 Tensor のコピーと宛先指定操作では、出力書き込みの前に、ArgumentException によるサポートされていない重複するストレージ レイアウトを拒否します。 Tensor-span コンストラクターは、 System.Array ストレージの要素の種類も検証します。

この変更は、System.Numerics.Tensors パッケージとそのサポート対象のターゲット フレームワークに組み込まれています。 パッケージを更新すると、以前の.NETバージョンを対象とするアプリに影響する可能性があります。 個別の TensorPrimitives API は、既存の重複に関する取り決めを維持します。

導入されたバージョン

.NET 11

以前の動作

CopyTo、FlattenTo、TryCopyTo、TryFlattenTo では、送信元ストレージと宛先ストレージのオーバーラップに対するサポートがドキュメントに記載されています。 Try で説明した方法では、ソースをあたかも一時的な記憶領域にまずコピーされたかのように扱うことが説明しました。

たとえば、次のソースとコピー先は、同じ配列の重複する領域を参照します。

int[] storage = { 1, 2, 3, 4, 5, 6 };
ReadOnlyTensorSpan<int> source = new(storage, new nint[] { 2, 2 }, new nint[] { 3, 1 });
TensorSpan<int> destination = new(storage, new nint[] { 2, 2 });
source.CopyTo(destination);

ドキュメント化されたスナップショット形式の契約では、宛先が [1, 2, 4, 5] を受け取ることを示唆していました。 サポートされていない重複の実際の結果は、レイアウトとトラバーサルの順序によって異なる場合があります。実装がそのコントラクトを確実に満たしませんでした。

System.Arrayを受け取ったコンストラクターは、配列の要素型がTと互換性があるかどうかを一貫して検証しませんでした。

新しい動作

この例では、コピーする前に ArgumentException 例外をスローします。 このサポートされていないオーバーラップは、TryCopyTo と TryFlattenTo の形状と容量のチェックに成功した場合にも、同様に例外をスローします。

サポートされるオーバーラップは、操作ごとに異なります。

Operation サポートされるオーバーラップ
CopyTo と TryCopyTo 要素数が等しい高密度な送信元と宛先、あるいは完全に同一のビュー。
FlattenTo と TryFlattenTo 高密度な送信元と宛先のスパン。
宛先指定の要素ごとの操作 論理的な格納位置が重複しない、同一の入出力ビュー。 シフトされたオーバーラップと重複するブロードキャスト入力は拒否されます。
Tensor.ResizeTo 送信元と宛先の密度が高い。 サポートされていない strided overlap は拒否されます。
同じビューへの戻り 高密度のインプレース反転、あるいは no-op 反転。

宛先の長さが不足している場合、Try のコピー方法は依然として、コピーを行わずに false を返します。 TryCopyTo は、互換性のない形状に対しても false を返します。 サポートされていないオーバーラップは、レイアウトの不正であり、容量不足によるものではありません。

Tensor.ResizeTo および既存の宛先への連結では、複数の論理要素を含むゼ ロストライドのディメンションは拒否されます。 シングルトン ディメンションの空の宛先と 0 ストライドは引き続き許可されます。

ArrayTypeMismatchException を受け取る TensorSpan<T> と System.Array のコンストラクターは、互換性のない配列要素型に対して ReadOnlyTensorSpan<T> をスローします。 書き込み可能なテンソル スパンも共変配列を拒否しますが、読み取り専用のテンソル スパンでは、互換性のある参照型の共変性が許可されます。

破壊的変更の種類

これは動作の 変化です。

変更理由

任意に重複するストライド テンソル間の正しいコピーには、テンソル全体に比例した一時的なストレージが必要な場合があります。 明示的な拒否により、完全なテンソル スナップショットを暗黙的に割り当てることなく、トラバーサル依存の破損を回避できます。

重複した出力ストレージの場所では、個別の論理結果を表すことはできません。 配列要素型の検証により、互換性のない格納が T として解釈されるのを防ぎ、共変配列格納による書き込みを防ぐことができます。

出力先を重複しないように設定するか、重複するコピーを行う前にソースのスナップショットを明示的に取得してください。 前の例の場合:

int[] snapshot = new int[checked((int)source.FlattenedLength)];
source.FlattenTo(snapshot);
ReadOnlyTensorSpan<int> independentSource = new(snapshot, source.Lengths);
independentSource.CopyTo(destination);

スナップショットには [1, 2, 4, 5]が含まれています。 要素ごとの演算を行う場合は、重複する各入力に対してスナップショットを作成するか、個別の結果を割り当てます。 ブロードキャストの宛先を個別にアドレス指定可能な出力ストレージに置き換えます。

System.Array上のテンソル スパンの場合は、互換性のある要素ストレージを指定します。 書き込み可能なビューの場合は、共変ではない配列を使用するか、要素を新しい T[] にコピーします。

Tryコピーメソッドが例外をスローしないと想定しないでください。 false という結果は、容量不足を処理し、TryCopyTo の場合は、互換性のない形状を処理します。 任意の重複動作を復元する互換性スイッチはありません。

影響を受ける API

参照