Tensorvorgänge lehnen nicht unterstützte Speicherlayouts ab

Ab .NET 11 lehnen multidimensionale Tensor-Kopier- und Operationen mit Zielparameter nicht unterstützte überlappende Speicherlayouts mit ArgumentException ab, bevor sie die Ausgabe schreiben. Tensor-Span-Konstruktoren überprüfen auch den Elementtyp des System.Array-Storage.

Die Änderung wird im Paket System.Numerics.Tensors bereitgestellt, einschließlich der unterstützten Zielframeworks. Das Aktualisieren des Pakets kann sich auf Apps auswirken, die auf frühere .NET Versionen abzielen. Die separaten TensorPrimitives APIs behalten ihren bisherigen Overlap-Contract bei.

Eingeführt in Version

.NET 11

Bisheriges Verhalten

CopyTo, FlattenTo, TryCopyTo und TryFlattenTo dokumentierten die Unterstützung für überlappenden Quell- und Zielspeicher. Die Try Methoden beschrieben die Behandlung der Quelle, als wäre sie zuvor in temporären Speicher kopiert worden.

Die folgende Quelle und das folgende Ziel beziehen sich beispielsweise auf überlappende Bereiche desselben Arrays:

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);

Der dokumentierte Vertrag im Snapshot-Stil impliziert, dass der Zielort [1, 2, 4, 5] empfangen würde. Die tatsächlichen Ergebnisse bei nicht unterstützten Überlappungen können von der Layout- und Traversalreihenfolge abhängen; die Implementierung erfüllte diesen Vertrag nicht zuverlässig.

Konstruktoren, die System.Array annahmen, überprüften nicht konsistent, ob der Elementtyp des Arrays mit T kompatibel war.

Neues Verhalten

Im Beispiel wird vor dem Kopieren ArgumentException ausgelöst. Die gleiche nicht unterstützte Überlappung wird auch von TryCopyTo und TryFlattenTo ausgelöst, wenn ihre Form- und Kapazitätsüberprüfungen erfolgreich sind.

Die unterstützte Überlappung bleibt vorgangsspezifisch:

Operation Unterstützte Überschneidung
CopyTo und TryCopyTo Dicht gepackte Quelle und Ziel mit gleicher Elementanzahl oder exakt identischen Ansichten.
FlattenTo und TryFlattenTo Eine dichte Quelle und der Zielbereich.
Elementweise Operationen mit Zielparameter Identische Eingabe-/Ausgabeansichten ohne wiederholte logische Speicherpositionen. Verschobene Überlappungen und überlappende Broadcast-Eingaben werden abgelehnt.
Tensor.ResizeTo dichte Quelle und dichtes Ziel Nicht unterstützte Stride-Überlappungen werden abgelehnt.
Umkehrung in dieselbe Ansicht Dichte Umkehr an Ort und Stelle oder eine No-Op-Umkehr.

Die Try Kopiermethoden geben weiterhin false zurück, ohne zu kopieren, wenn das Ziel zu kurz ist. TryCopyTo gibt auch false für inkompatible Shapes zurück. Nicht unterstützte Überlappung ist ein ungültiges Layout, kein Kapazitätsfehler.

Tensor.ResizeTo und Verkettung in ein vorhandenes Ziel lehnen eine Null-Stride-Dimension ab, die mehr als ein logisches Element enthält. Leere Ziele und Nullschritte in Singleton-Dimensionen bleiben zulässig.

TensorSpan<T> und ReadOnlyTensorSpan<T> Konstruktoren, die System.Array annehmen, lösen bei inkompatiblen Arrayelementtypen ArrayTypeMismatchException aus. Schreibbare Tensorspannen weisen auch kovariante Arrays zurück; schreibgeschützte Tensorspannen erlauben kompatible Kovarianz von Referenztypen.

Art der einschneidenden Änderung

Dies ist eine Verhaltensänderung.

Grund für die Änderung

Bei korrekten Kopien zwischen willkürlich überlappenden gestrideten Tensoren kann eine temporäre Speicherung proportional zum gesamten Tensor erforderlich sein. Explizite Ablehnung vermeidet traversal abhängige Beschädigungen, ohne im Hintergrund vollständige Tensormomentaufnahmen zu allozieren.

Wiederholte Ausgabespeicherorte können keine verschiedenen logischen Ergebnisse darstellen. Die Überprüfung des Arrayelementtyps verhindert, dass der inkompatible Speicher als T interpretiert wird, und verhindert Schreibvorgänge über den kovarianten Arrayspeicher.

Verwenden Sie einen nicht überlappenden Ausgabespeicher oder erstellen Sie explizit eine Momentaufnahme der Quelle vor einer überlappenden Kopie. Im vorherigen Beispiel:

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

Die Momentaufnahme enthält [1, 2, 4, 5]. Bei elementweisen Zielvorgängen können Sie jede überlappende Eingabe sichern oder ein separates Ergebnis allokieren. Ersetzen Sie Broadcast-Ziele durch unabhängig adressierbaren Ausgabespeicher.

Stellen Sie für eine Tensor-Span eine kompatible System.ArrayElementspeicherung zur Verfügung. Verwenden Sie für eine schreibbare Ansicht ein Array, das nicht kovariant ist, oder kopieren Sie die Elemente in eine neue T[].

Gehen Sie nicht davon aus, dass eine Try-Kopiermethode keine Ausnahme auslösen kann. Ein false Ergebnis weist auf unzureichende Kapazität oder, für TryCopyTo, inkompatible Shapes hin. Kein Kompatibilitätsschalter stellt arbritäres Überlappungsverhalten wieder her.

Betroffene APIs

Siehe auch