Fix integer overflow in TensorPrimitives IndexOf methods#124274
Fix integer overflow in TensorPrimitives IndexOf methods#124274pine919 wants to merge 7 commits intodotnet:mainfrom
Conversation
|
@dotnet-policy-service agree |
|
@dhartglassMSFT Please review my PR |
| static abstract void Invoke(ref Vector128<T> result, Vector128<T> current, ref Vector128<int> resultIndex, Vector128<int> currentIndex); | ||
| static abstract void Invoke(ref Vector256<T> result, Vector256<T> current, ref Vector256<int> resultIndex, Vector256<int> currentIndex); | ||
| static abstract void Invoke(ref Vector512<T> result, Vector512<T> current, ref Vector512<int> resultIndex, Vector512<int> currentIndex); |
There was a problem hiding this comment.
There is a lot of extra churn here that makes it harder to see what is fix vs what is "cleanup" and which will make it harder to backport. Ideally you separate out such changes, particularly for bug fixes, so that we have the minimum churn possible.
Additionally, this particular approach is going to be more expensive and halve or quarter the throughput for the small integer types. It would likely be better to have an additional ref int baseIndex parameter that can be used to adjust resultIndex in the final step based on the T.MaxValue wraparound. This way the core of the logic doesn't change at all and instead we only have a correcting step at the end to account for the mod wraparound
This commit fixes integer overflow issues in IndexOf methods for byte and short types. Changes: - Reverted broken Vector<int> approach that couldn't track all elements - Added unsigned comparison for short types to handle wrapped indices correctly - Added overflow detection with scalar fallback for large arrays (>256 for byte, >65536 for short) - Applied fixes to all IndexOf variants (Max, Min, MaxMagnitude, MinMagnitude) The fix ensures correctness for arrays where indices exceed the storage capacity of byte (>255) or short (>32767/65535) types while maintaining performance for smaller arrays.
5ff8f2f to
e16748e
Compare
🤖 Copilot Code Review — PR #124274Holistic AssessmentMotivation: The bug is real and well-documented in issue #124233. The vectorized Approach: The PR takes a scalar-fallback approach rather than fixing the vectorized path to use wider index types. While this correctly fixes the bug, it abandons vectorization for larger arrays of small element types — a potentially significant performance regression for common use cases. Summary: Detailed Findings
|
- Separate signed short (>32768) and unsigned short (>65536) thresholds - Add explicit int cast for byte case for consistency - Improve comments to clarify index comparison vs value comparison - Maintain correct behavior while addressing reviewer concerns
Change overflow protection from > to >= to correctly handle edge cases. For byte types, max index is 255, so arrays with 256+ elements need scalar path. Similarly for short (32768) and ushort (65536). Fixes IndexOfMax_NoIntegerOverflow test failures on multiple platforms.
…NET481 compatibility
|
Tagging subscribers to this area: @dotnet/area-system-numerics-tensors |
Fixes #124233
Description
IndexOfMax,IndexOfMin,IndexOfMaxMagnitude, andIndexOfMinMagnitudewere usingVector<T>for index tracking, whereTis the element type. This caused integer overflow when the array length exceeded the maximum value thatTcould represent.For example:
bytearray with 258 elements would incorrectly return index 1 instead of 257shortarray with 32770 elements would incorrectly return index 1 instead of 32769Changes
Changed index tracking to use
Vector<int>throughout the implementation, preventing overflow regardless of array size.IIndexOfOperator<T>interface signatures to useVector128/256/512<int>for index parametersVector<int>for index trackingIndexLessThanhelper methods to returnVector<int>directlybyte,sbyte,short, andushorttypesTesting
Added
IndexOfMax_NoIntegerOverflowtest that verifies correct behavior for arrays exceeding the element type's maximum value:byte[258]→ expects index 257sbyte[258]→ expects index 257short[32770]→ expects index 32769ushort[65538]→ expects index 65537cc: @dotnet/area-system-numerics-tensors