-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime.Intrinsics
Milestone
Description
Summary
We've exposed several APIs on Vector64/128/256 and recently approved Vector512. However, there are notably a few missing APIs that make it feel "incomplete". Such APIs were likely simply missed as part of previous review.
API Proposal
namespace System.Numerics
{
public static partial class Vector
{
// Has AsVectorByte and friends, not AsByte and friends
public static Vector<T> Divide(Vector<T> left, T right);
public static T GetElement<T>(this Vector<T> vector, int index) where T : struct;
public static Vector<T> Load<T>(T* source) where T : unmanaged;
public static Vector<T> LoadAligned<T>(T* source) where T : unmanaged;
public static Vector<T> LoadAlignedNonTemporal<T>(T* source) where T : unmanaged;
public static Vector<T> LoadUnsafe<T>(ref T source) where T : struct;
public static Vector<T> LoadUnsafe<T>(ref T source, nuint index) where T : struct;
// Shuffle is difficult to expose because the indices often should be "constant"
// Has SquareRoot, not Sqrt
public static unsafe void Store<T>(this Vector<T> source, T* destination) where T : unmanaged;
public static unsafe void StoreAligned<T>(this Vector<T> source, T* destination) where T : unmanaged;
public static unsafe void StoreAlignedNonTemporal<T>(this Vector<T> source, T* destination) where T : unmanaged;
public static unsafe void StoreUnsafe<T>(this Vector<T> source, ref T destination) where T : struct;
public static unsafe void StoreUnsafe<T>(this Vector<T> source, ref T destination, nuint index) where T : struct;
public static T ToScalar<T>(this Vector<T> vector) where T : struct;
public static Vector<T> WithElement<T> (this Vector<T> vector, int index, T value) where T : struct;
}
public partial struct Vector<T>
{
public static Vector<T> AllBitsSet { get; }
// Has constructors, not Vector.Create()
// Has explicit cast operators
public static Vector<T> operator /(Vector<T> left, T right);
public static Vector<T> operator +(Vector<T> value);
}
}
namespace System.Runtime.Intrinsics.X86
{
public static partial class Vector64
{
public static Vector64<T> CreateScalar<T>(T value) where T : struct;
public static Vector64<T> CreateScalarUnsafe<T>(T value) where T : struct;
public static Vector64<long> CreateScalarUnsafe (double value);
public static Vector64<long> CreateScalarUnsafe (long value);
public static Vector64<ulong> CreateScalarUnsafe (ulong value);
public static Vector64<T> Divide(Vector64<T> left, T right);
public static Vector64<ushort> WidenLower(Vector64<byte> value);
public static Vector64<int> WidenLower(Vector64<short> value);
public static Vector64<long> WidenLower(Vector64<int> value);
public static Vector64<short> WidenLower(Vector64<sbyte> value);
public static Vector64<double> WidenLower(Vector64<float> value);
public static Vector64<uint> WidenLower(Vector64<ushort> value);
public static Vector64<ulong> WidenLower(Vector64<uint> value);
public static Vector64<ushort> WidenUpper(Vector64<byte> value);
public static Vector64<int> WidenUpper(Vector64<short> value);
public static Vector64<long> WidenUpper(Vector64<int> value);
public static Vector64<short> WidenUpper(Vector64<sbyte> value);
public static Vector64<double> WidenUpper(Vector64<float> value);
public static Vector64<uint> WidenUpper(Vector64<ushort> value);
public static Vector64<ulong> WidenUpper(Vector64<uint> value);
}
public partial struct Vector64<T>
{
public static Vector64<T> One { get; }
public static Vector64<T> operator /(Vector64<T> left, T right);
public static Vector64<T> operator <<(Vector64<T> left, int shiftAmount);
public static Vector64<T> operator >>(Vector64<T> left, int shiftAmount);
public static Vector64<T> operator >>>(Vector64<T> left, int shiftAmount);
}
public static partial class Vector128
{
public static Vector128<T> Create<T>(Vector64<T> lower, Vector64<T> upper) where T : struct;
public static Vector128<nint> Create (Vector64<nint> lower, Vector64<nint> upper);
public static Vector128<nuint> Create (Vector64<nuint> lower, Vector64<nuint> upper);
public static Vector128<T> CreateScalar<T>(T value) where T : struct;
public static Vector128<T> CreateScalarUnsafe<T>(T value) where T : struct;
public static Vector128<T> Divide(Vector128<T> left, T right);
public static Vector128<ushort> WidenLower(Vector128<byte> value);
public static Vector128<int> WidenLower(Vector128<short> value);
public static Vector128<long> WidenLower(Vector128<int> value);
public static Vector128<short> WidenLower(Vector128<sbyte> value);
public static Vector128<double> WidenLower(Vector128<float> value);
public static Vector128<uint> WidenLower(Vector128<ushort> value);
public static Vector128<ulong> WidenLower(Vector128<uint> value);
public static Vector128<ushort> WidenUpper(Vector128<byte> value);
public static Vector128<int> WidenUpper(Vector128<short> value);
public static Vector128<long> WidenUpper(Vector128<int> value);
public static Vector128<short> WidenUpper(Vector128<sbyte> value);
public static Vector128<double> WidenUpper(Vector128<float> value);
public static Vector128<uint> WidenUpper(Vector128<ushort> value);
public static Vector128<ulong> WidenUpper(Vector128<uint> value);
}
public partial struct Vector128<T>
{
public static Vector128<T> One { get; }
public static Vector128<T> operator /(Vector128<T> left, T right);
public static Vector128<T> operator <<(Vector128<T> left, int shiftAmount);
public static Vector128<T> operator >>(Vector128<T> left, int shiftAmount);
public static Vector128<T> operator >>>(Vector128<T> left, int shiftAmount);
}
public static partial class Vector256
{
public static Vector256<T> Create<T>(Vector128<T> lower, Vector128<T> upper) where T : struct;
public static Vector256<nint> Create (Vector128<nint> lower, Vector128<nint> upper);
public static Vector256<nuint> Create (Vector128<nuint> lower, Vector128<nuint> upper);
public static Vector256<T> CreateScalar<T>(T value) where T : struct;
public static Vector256<T> CreateScalarUnsafe<T>(T value) where T : struct;
public static Vector256<T> Divide(Vector256<T> left, T right);
public static Vector256<ushort> WidenLower(Vector256<byte> value);
public static Vector256<int> WidenLower(Vector256<short> value);
public static Vector256<long> WidenLower(Vector256<int> value);
public static Vector256<short> WidenLower(Vector256<sbyte> value);
public static Vector256<double> WidenLower(Vector256<float> value);
public static Vector256<uint> WidenLower(Vector256<ushort> value);
public static Vector256<ulong> WidenLower(Vector256<uint> value);
public static Vector256<ushort> WidenUpper(Vector256<byte> value);
public static Vector256<int> WidenUpper(Vector256<short> value);
public static Vector256<long> WidenUpper(Vector256<int> value);
public static Vector256<short> WidenUpper(Vector256<sbyte> value);
public static Vector256<double> WidenUpper(Vector256<float> value);
public static Vector256<uint> WidenUpper(Vector256<ushort> value);
public static Vector256<ulong> WidenUpper(Vector256<uint> value);
}
public partial struct Vector256<T>
{
public static Vector256<T> One { get; }
public static Vector256<T> operator /(Vector256<T> left, T right);
public static Vector256<T> operator <<(Vector256<T> left, int shiftAmount);
public static Vector256<T> operator >>(Vector256<T> left, int shiftAmount);
public static Vector256<T> operator >>>(Vector256<T> left, int shiftAmount);
}
}Considerations
We expose == and != with the semantics of "All". Exposing <, <=, >, and >= with the same semantics likely makes sense. If we do this, then IComparable should likely also be implemented.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime.Intrinsics