From 10bfde0b641978829ff355c7c743193dccb2b028 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sat, 21 Jun 2025 22:19:01 -0400 Subject: [PATCH 1/2] Enable vectorization of TensorPrimitives.ConvertTruncating for float/double These were disabled against a PR that has already been merged. --- .../Tensors/netcore/TensorPrimitives.ConvertTruncating.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs index 29edffd4bcec03..71c6c4911df881 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs @@ -103,7 +103,7 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (float)int private readonly struct ConvertSingleToInt32 : IUnaryOperator { - public static bool Vectorizable => false; // TODO https://github.com/dotnet/runtime/pull/97529: make this true once vectorized behavior matches scalar + public static bool Vectorizable => true; public static int Invoke(float x) => int.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToInt32(x); @@ -114,7 +114,7 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (float)uint private readonly struct ConvertSingleToUInt32 : IUnaryOperator { - public static bool Vectorizable => false; // TODO https://github.com/dotnet/runtime/pull/97529: make this true once vectorized behavior matches scalar + public static bool Vectorizable => true; public static uint Invoke(float x) => uint.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToUInt32(x); @@ -125,7 +125,7 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (ulong)double private readonly struct ConvertDoubleToUInt64 : IUnaryOperator { - public static bool Vectorizable => false; // TODO https://github.com/dotnet/runtime/pull/97529: make this true once vectorized behavior matches scalar + public static bool Vectorizable => true; public static ulong Invoke(double x) => ulong.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToUInt64(x); @@ -136,7 +136,7 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (long)double private readonly struct ConvertDoubleToInt64 : IUnaryOperator { - public static bool Vectorizable => false; // TODO https://github.com/dotnet/runtime/pull/97529: make this true once vectorized behavior matches scalar + public static bool Vectorizable => true; public static long Invoke(double x) => long.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToInt64(x); From 5d2ff095db167f6037bd54d91f280d9255f056dc Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sun, 22 Jun 2025 00:47:33 -0400 Subject: [PATCH 2/2] Address PR feedback --- .../TensorPrimitives.ConvertTruncating.cs | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs index 71c6c4911df881..0fc841e9bb59c4 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.ConvertTruncating.cs @@ -103,7 +103,12 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (float)int private readonly struct ConvertSingleToInt32 : IUnaryOperator { - public static bool Vectorizable => true; + public static bool Vectorizable => +#if NET9_0_OR_GREATER + true; // .NET 9+ includes https://github.com/dotnet/runtime/pull/97529 +#else + false; +#endif public static int Invoke(float x) => int.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToInt32(x); @@ -114,7 +119,12 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (float)uint private readonly struct ConvertSingleToUInt32 : IUnaryOperator { - public static bool Vectorizable => true; + public static bool Vectorizable => +#if NET9_0_OR_GREATER + true; // .NET 9+ includes https://github.com/dotnet/runtime/pull/97529 +#else + false; +#endif public static uint Invoke(float x) => uint.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToUInt32(x); @@ -125,7 +135,12 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (ulong)double private readonly struct ConvertDoubleToUInt64 : IUnaryOperator { - public static bool Vectorizable => true; + public static bool Vectorizable => +#if NET9_0_OR_GREATER + true; // .NET 9+ includes https://github.com/dotnet/runtime/pull/97529 +#else + false; +#endif public static ulong Invoke(double x) => ulong.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToUInt64(x); @@ -136,7 +151,12 @@ public static void ConvertTruncating(ReadOnlySpan source, Spa /// (long)double private readonly struct ConvertDoubleToInt64 : IUnaryOperator { - public static bool Vectorizable => true; + public static bool Vectorizable => +#if NET9_0_OR_GREATER + true; // .NET 9+ includes https://github.com/dotnet/runtime/pull/97529 +#else + false; +#endif public static long Invoke(double x) => long.CreateTruncating(x); public static Vector128 Invoke(Vector128 x) => Vector128.ConvertToInt64(x);