diff options
author | WinCPP <mandards@gmail.com> | 2018-03-03 16:27:37 +0300 |
---|---|---|
committer | Eric Erhardt <eric.erhardt@microsoft.com> | 2018-03-09 18:27:10 +0300 |
commit | 82c6f6320aeb14186f0438e77bfdc383eb631d05 (patch) | |
tree | fc3e0bcd3b08f4aa94a9cbd053bd93a703628951 /src/System.Numerics.Vectors | |
parent | e1f304886a8315fd3303ff0e75dc7595c42b8cd0 (diff) |
Issue #24343 Vector Ctor using Span
Diffstat (limited to 'src/System.Numerics.Vectors')
11 files changed, 927 insertions, 13 deletions
diff --git a/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs b/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs index 486ad29db9..9936f66954 100644 --- a/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs +++ b/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs @@ -301,6 +301,9 @@ namespace System.Numerics public Vector(T value) { throw null; } public Vector(T[] values) { throw null; } public Vector(T[] values, int index) { throw null; } +#if netcoreapp + public Vector(Span<T> values) { throw null; } +#endif public static int Count { get { throw null; } } public T this[int index] { get { throw null; } } public static System.Numerics.Vector<T> One { get { throw null; } } diff --git a/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj b/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj index d27c9fb55b..ed07ba967e 100644 --- a/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj +++ b/src/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj @@ -3,7 +3,10 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{650277B5-9423-4ACE-BB54-2659995B21C7}</ProjectGuid> - <IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netfx' OR '$(TargetGroup)' == 'net46'">true</IsPartialFacadeAssembly> + <IsTargetingNetFx Condition="'$(TargetGroup)'=='netfx' OR '$(TargetGroup)'=='net46'">true</IsTargetingNetFx> + <IsTargetingNetCoreApp Condition="'$(TargetGroup)'=='netcoreapp' OR '$(TargetGroup)'=='uap'">true</IsTargetingNetCoreApp> + <IsPartialFacadeAssembly Condition="'$(IsTargetingNetFx)'=='true'">true</IsPartialFacadeAssembly> + <DefineConstants Condition="'$(IsTargetingNetCoreApp)'=='true'">$(DefineConstants);netcoreapp</DefineConstants> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net46-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net46-Release|AnyCPU'" /> @@ -20,14 +23,14 @@ <ItemGroup> <Compile Include="System.Numerics.Vectors.cs" /> </ItemGroup> - <ItemGroup Condition="'$(TargetGroup)' == 'netfx' OR '$(TargetGroup)' == 'net46'"> + <ItemGroup Condition="'$(IsTargetingNetFx)'=='true'"> <Reference Include="mscorlib" /> <Reference Include="System.Numerics" /> </ItemGroup> <ItemGroup Condition="'$(TargetGroup)' == 'netstandard1.0'"> <Reference Include="System.Runtime" /> </ItemGroup> - <ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp' OR '$(TargetGroup)' == 'uap' OR '$(TargetGroup)' == 'uapaot'"> + <ItemGroup Condition="'$(IsTargetingNetCoreApp)'=='true'"> <ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> diff --git a/src/System.Numerics.Vectors/src/ApiCompatBaseline.uapaot.txt b/src/System.Numerics.Vectors/src/ApiCompatBaseline.uapaot.txt new file mode 100644 index 0000000000..bc7a12f526 --- /dev/null +++ b/src/System.Numerics.Vectors/src/ApiCompatBaseline.uapaot.txt @@ -0,0 +1 @@ +MembersMustExist : Member 'System.Numerics.Vector<T>..ctor(System.Span<T>)' does not exist in the implementation but it does exist in the contract.
\ No newline at end of file diff --git a/src/System.Numerics.Vectors/tests/GenericVectorTests.cs b/src/System.Numerics.Vectors/tests/GenericVectorTests.cs index e03022a216..eb0e588d64 100644 --- a/src/System.Numerics.Vectors/tests/GenericVectorTests.cs +++ b/src/System.Numerics.Vectors/tests/GenericVectorTests.cs @@ -14,7 +14,7 @@ namespace System.Numerics.Tests /// <summary> /// Vector{T} tests that use random number generation and a unified generic test structure /// </summary> - public class GenericVectorTests + public partial class GenericVectorTests { // Static constructor in top-level class\ static System.Numerics.Vector<float> dummy; @@ -2699,11 +2699,11 @@ namespace System.Numerics.Tests } } - internal static T[] GenerateRandomValuesForVector<T>() where T : struct + internal static T[] GenerateRandomValuesForVector<T>(int? numValues = null) where T : struct { int minValue = GetMinValue<T>(); int maxValue = GetMaxValue<T>(); - return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue); + return Util.GenerateRandomValues<T>(numValues ?? Vector<T>.Count, minValue, maxValue); } internal static int GetMinValue<T>() where T : struct @@ -2776,4 +2776,4 @@ namespace System.Numerics.Tests } #endregion } -}
\ No newline at end of file +} diff --git a/src/System.Numerics.Vectors/tests/GenericVectorTests.netcoreapp.cs b/src/System.Numerics.Vectors/tests/GenericVectorTests.netcoreapp.cs new file mode 100644 index 0000000000..cb5ed7b81a --- /dev/null +++ b/src/System.Numerics.Vectors/tests/GenericVectorTests.netcoreapp.cs @@ -0,0 +1,226 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Xunit; +using Xunit.Sdk; + +namespace System.Numerics.Tests +{ + /// <summary> + /// Vector{T} tests that use random number generation and a unified generic test structure + /// </summary> + public partial class GenericVectorTests + { + #region Constructor Tests + + #region Tests for Span based constructor + [Fact] + public void ConstructorWithSpanByte() => TestConstructorWithSpan<Byte>(); + [Fact] + public void ConstructorWithSpanSByte() => TestConstructorWithSpan<SByte>(); + [Fact] + public void ConstructorWithSpanUInt16() => TestConstructorWithSpan<UInt16>(); + [Fact] + public void ConstructorWithSpanInt16() => TestConstructorWithSpan<Int16>(); + [Fact] + public void ConstructorWithSpanUInt32() => TestConstructorWithSpan<UInt32>(); + [Fact] + public void ConstructorWithSpanInt32() => TestConstructorWithSpan<Int32>(); + [Fact] + public void ConstructorWithSpanUInt64() => TestConstructorWithSpan<UInt64>(); + [Fact] + public void ConstructorWithSpanInt64() => TestConstructorWithSpan<Int64>(); + [Fact] + public void ConstructorWithSpanSingle() => TestConstructorWithSpan<Single>(); + [Fact] + public void ConstructorWithSpanDouble() => TestConstructorWithSpan<Double>(); + + private void TestConstructorWithSpan<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>().ToArray(); + var valueSpan = new Span<T>(values); + + var vector = new Vector<T>(valueSpan); + ValidateVector(vector, + (index, val) => + { + Assert.Equal(values[index], val); + }); + } + + [Fact] + public void SpanBasedConstructorWithLessElements_Byte() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Byte>()); + [Fact] + public void SpanBasedConstructorWithLessElements_SByte() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<SByte>()); + [Fact] + public void SpanBasedConstructorWithLessElements_UInt16() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<UInt16>()); + [Fact] + public void SpanBasedConstructorWithLessElements_Int16() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Int16>()); + [Fact] + public void SpanBasedConstructorWithLessElements_UInt32() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<UInt32>()); + [Fact] + public void SpanBasedConstructorWithLessElements_Int32() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Int32>()); + [Fact] + public void SpanBasedConstructorWithLessElements_UInt64() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<UInt64>()); + [Fact] + public void SpanBasedConstructorWithLessElements_Int64() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Int64>()); + [Fact] + public void SpanBasedConstructorWithLessElements_Single() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Single>()); + [Fact] + public void SpanBasedConstructorWithLessElements_Double() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Double>()); + + private void TestSpanBasedConstructorWithLessElements<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray(); + var vector = new Vector<T>(new Span<T>(values)); + } + + #endregion Tests for Span based constructor + + #region Tests for Array based constructor + + [Fact] + public void ArrayBasedConstructor_Byte() => TestArrayBasedConstructor<Byte>(); + [Fact] + public void ArrayBasedConstructor_SByte() => TestArrayBasedConstructor<SByte>(); + [Fact] + public void ArrayBasedConstructor_UInt16() => TestArrayBasedConstructor<UInt16>(); + [Fact] + public void ArrayBasedConstructor_Int16() => TestArrayBasedConstructor<Int16>(); + [Fact] + public void ArrayBasedConstructor_UInt32() => TestArrayBasedConstructor<UInt32>(); + [Fact] + public void ArrayBasedConstructor_Int32() => TestArrayBasedConstructor<Int32>(); + [Fact] + public void ArrayBasedConstructor_UInt64() => TestArrayBasedConstructor<UInt64>(); + [Fact] + public void ArrayBasedConstructor_Int64() => TestArrayBasedConstructor<Int64>(); + [Fact] + public void ArrayBasedConstructor_Single() => TestArrayBasedConstructor<Single>(); + [Fact] + public void ArrayBasedConstructor_Double() => TestArrayBasedConstructor<Double>(); + + private void TestArrayBasedConstructor<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count).ToArray(); + var vector = new Vector<T>(values); + ValidateVector(vector, + (index, val) => + { + Assert.Equal(values[index], val); + }); + } + + [Fact] + public void ArrayIndexBasedConstructor_Byte() => TestArrayIndexBasedConstructor<Byte>(); + [Fact] + public void ArrayIndexBasedConstructor_SByte() => TestArrayIndexBasedConstructor<SByte>(); + [Fact] + public void ArrayIndexBasedConstructor_UInt16() => TestArrayIndexBasedConstructor<UInt16>(); + [Fact] + public void ArrayIndexBasedConstructor_Int16() => TestArrayIndexBasedConstructor<Int16>(); + [Fact] + public void ArrayIndexBasedConstructor_UInt32() => TestArrayIndexBasedConstructor<UInt32>(); + [Fact] + public void ArrayIndexBasedConstructor_Int32() => TestArrayIndexBasedConstructor<Int32>(); + [Fact] + public void ArrayIndexBasedConstructor_UInt64() => TestArrayIndexBasedConstructor<UInt64>(); + [Fact] + public void ArrayIndexBasedConstructor_Int64() => TestArrayIndexBasedConstructor<Int64>(); + [Fact] + public void ArrayIndexBasedConstructor_Single() => TestArrayIndexBasedConstructor<Single>(); + [Fact] + public void ArrayIndexBasedConstructor_Double() => TestArrayIndexBasedConstructor<Double>(); + + private void TestArrayIndexBasedConstructor<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray(); + int offset = Vector<T>.Count - 1; + var vector = new Vector<T>(values, offset); + ValidateVector(vector, + (index, val) => + { + Assert.Equal(values[offset + index], val); + }); + } + + [Fact] + public void ArrayBasedConstructorWithLessElements_Byte() => TestArrayBasedConstructorWithLessElements<Byte>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_SByte() => TestArrayBasedConstructorWithLessElements<SByte>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_UInt16() => TestArrayBasedConstructorWithLessElements<UInt16>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_Int16() => TestArrayBasedConstructorWithLessElements<Int16>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_UInt32() => TestArrayBasedConstructorWithLessElements<UInt32>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_Int32() => TestArrayBasedConstructorWithLessElements<Int32>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_UInt64() => TestArrayBasedConstructorWithLessElements<UInt64>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_Int64() => TestArrayBasedConstructorWithLessElements<Int64>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_Single() => TestArrayBasedConstructorWithLessElements<Single>(); + [Fact] + public void ArrayBasedConstructorWithLessElements_Double() => TestArrayBasedConstructorWithLessElements<Double>(); + + private void TestArrayBasedConstructorWithLessElements<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray(); + Assert.Throws<IndexOutOfRangeException>(() => new Vector<T>(values)); + } + + [Fact] + public void ArrayIndexBasedConstructorLessElements_Byte() => TestArrayIndexBasedConstructorLessElements<Byte>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_SByte() => TestArrayIndexBasedConstructorLessElements<SByte>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_UInt16() => TestArrayIndexBasedConstructorLessElements<UInt16>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_Int16() => TestArrayIndexBasedConstructorLessElements<Int16>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_UInt32() => TestArrayIndexBasedConstructorLessElements<UInt32>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_Int32() => TestArrayIndexBasedConstructorLessElements<Int32>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_UInt64() => TestArrayIndexBasedConstructorLessElements<UInt64>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_Int64() => TestArrayIndexBasedConstructorLessElements<Int64>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_Single() => TestArrayIndexBasedConstructorLessElements<Single>(); + [Fact] + public void ArrayIndexBasedConstructorLessElements_Double() => TestArrayIndexBasedConstructorLessElements<Double>(); + + private void TestArrayIndexBasedConstructorLessElements<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray(); + Assert.Throws<IndexOutOfRangeException>(() => new Vector<T>(values, Vector<T>.Count + 1)); + } + + #endregion Tests for Array based constructor + + #region Tests for constructors using unsupported types + + [Fact] + public void ConstructorWithUnsupportedTypes_Guid() => TestConstructorWithUnsupportedTypes<Guid>(); + [Fact] + public void ConstructorWithUnsupportedTypes_DateTime() => TestConstructorWithUnsupportedTypes<DateTime>(); + [Fact] + public void ConstructorWithUnsupportedTypes_Char() => TestConstructorWithUnsupportedTypes<Char>(); + + private void TestConstructorWithUnsupportedTypes<T>() where T : struct + { + Assert.Throws<NotSupportedException>(() => new Vector<T>(new Span<T>(new T[4]))); + } + + #endregion Tests for constructors using unsupported types + + #endregion Constructor Tests + } +} diff --git a/src/System.Numerics.Vectors/tests/GenericVectorTests.netcoreapp.tt b/src/System.Numerics.Vectors/tests/GenericVectorTests.netcoreapp.tt new file mode 100644 index 0000000000..68a0c15077 --- /dev/null +++ b/src/System.Numerics.Vectors/tests/GenericVectorTests.netcoreapp.tt @@ -0,0 +1,174 @@ +<#@ template debug="true" hostSpecific="true" #> +<#@ output extension=".cs" #> +<#@ Assembly Name="System.Core.dll" #> +<#@ Assembly Name="System.Xml.dll" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ include file="..\..\Common\src\CoreLib\System\Numerics\GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #> + +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; +using Xunit; +using Xunit.Sdk; + +namespace System.Numerics.Tests +{ + /// <summary> + /// Vector{T} tests that use random number generation and a unified generic test structure + /// </summary> + public partial class GenericVectorTests + { + #region Constructor Tests + + #region Tests for Span based constructor +<# + foreach (var type in supportedTypes) + { +#> + [Fact] + public void ConstructorWithSpan<#=type.Name#>() => TestConstructorWithSpan<<#=type.Name#>>(); +<# + } +#> + + private void TestConstructorWithSpan<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>().ToArray(); + var valueSpan = new Span<T>(values); + + var vector = new Vector<T>(valueSpan); + ValidateVector(vector, + (index, val) => + { + Assert.Equal(values[index], val); + }); + } + +<# + foreach (var type in supportedTypes) + { +#> + [Fact] + public void SpanBasedConstructorWithLessElements_<#=type.Name#>() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<<#=type.Name#>>()); +<# + } +#> + + private void TestSpanBasedConstructorWithLessElements<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray(); + var vector = new Vector<T>(new Span<T>(values)); + } + + #endregion Tests for Span based constructor + + #region Tests for Array based constructor + +<# + foreach (var type in supportedTypes) + { +#> + [Fact] + public void ArrayBasedConstructor_<#=type.Name#>() => TestArrayBasedConstructor<<#=type.Name#>>(); +<# + } +#> + + private void TestArrayBasedConstructor<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count).ToArray(); + var vector = new Vector<T>(values); + ValidateVector(vector, + (index, val) => + { + Assert.Equal(values[index], val); + }); + } + +<# + foreach (var type in supportedTypes) + { +#> + [Fact] + public void ArrayIndexBasedConstructor_<#=type.Name#>() => TestArrayIndexBasedConstructor<<#=type.Name#>>(); +<# + } +#> + + private void TestArrayIndexBasedConstructor<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray(); + int offset = Vector<T>.Count - 1; + var vector = new Vector<T>(values, offset); + ValidateVector(vector, + (index, val) => + { + Assert.Equal(values[offset + index], val); + }); + } + +<# + foreach (var type in supportedTypes) + { +#> + [Fact] + public void ArrayBasedConstructorWithLessElements_<#=type.Name#>() => TestArrayBasedConstructorWithLessElements<<#=type.Name#>>(); +<# + } +#> + + private void TestArrayBasedConstructorWithLessElements<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray(); + Assert.Throws<IndexOutOfRangeException>(() => new Vector<T>(values)); + } + +<# + foreach (var type in supportedTypes) + { +#> + [Fact] + public void ArrayIndexBasedConstructorLessElements_<#=type.Name#>() => TestArrayIndexBasedConstructorLessElements<<#=type.Name#>>(); +<# + } +#> + + private void TestArrayIndexBasedConstructorLessElements<T>() where T : struct + { + T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray(); + Assert.Throws<IndexOutOfRangeException>(() => new Vector<T>(values, Vector<T>.Count + 1)); + } + + #endregion Tests for Array based constructor + + #region Tests for constructors using unsupported types + +<# + Type[] unsupportedTypes = new[] + { + typeof(Guid), typeof(DateTime), typeof(char) + }; + + + foreach (var type in unsupportedTypes) + { +#> + [Fact] + public void ConstructorWithUnsupportedTypes_<#=type.Name#>() => TestConstructorWithUnsupportedTypes<<#=type.Name#>>(); +<# + } +#> + + private void TestConstructorWithUnsupportedTypes<T>() where T : struct + { + Assert.Throws<NotSupportedException>(() => new Vector<T>(new Span<T>(new T[4]))); + } + + #endregion Tests for constructors using unsupported types + + #endregion Constructor Tests + } +} diff --git a/src/System.Numerics.Vectors/tests/GenericVectorTests.tt b/src/System.Numerics.Vectors/tests/GenericVectorTests.tt index 4790b1ac50..5fbd230724 100644 --- a/src/System.Numerics.Vectors/tests/GenericVectorTests.tt +++ b/src/System.Numerics.Vectors/tests/GenericVectorTests.tt @@ -5,7 +5,7 @@ <#@ import namespace="System" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Runtime.InteropServices" #> -<#@ include file="..\src\System\Numerics\GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #> +<#@ include file="..\..\common\src\corelib\System\Numerics\GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #> using System; using System.Globalization; @@ -19,7 +19,7 @@ namespace System.Numerics.Tests /// <summary> /// Vector{T} tests that use random number generation and a unified generic test structure /// </summary> - public class GenericVectorTests + public partial class GenericVectorTests { // Static constructor in top-level class\ static System.Numerics.Vector<float> dummy; @@ -116,7 +116,7 @@ namespace System.Numerics.Tests }); } -<# +<# foreach (var type in supportedTypes) { #> @@ -1792,11 +1792,11 @@ namespace System.Numerics.Tests } } - internal static T[] GenerateRandomValuesForVector<T>() where T : struct + internal static T[] GenerateRandomValuesForVector<T>(int? numValues = null) where T : struct { int minValue = GetMinValue<T>(); int maxValue = GetMaxValue<T>(); - return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue); + return Util.GenerateRandomValues<T>(numValues ?? Vector<T>.Count, minValue, maxValue); } internal static int GetMinValue<T>() where T : struct @@ -1869,4 +1869,4 @@ namespace System.Numerics.Tests } #endregion } -}
\ No newline at end of file +} diff --git a/src/System.Numerics.Vectors/tests/Performance/Constructor/GenericVectorConstructorTests.cs b/src/System.Numerics.Vectors/tests/Performance/Constructor/GenericVectorConstructorTests.cs new file mode 100644 index 0000000000..4220c38085 --- /dev/null +++ b/src/System.Numerics.Vectors/tests/Performance/Constructor/GenericVectorConstructorTests.cs @@ -0,0 +1,352 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using Xunit; +using Xunit.Sdk; +using Microsoft.Xunit.Performance; + +namespace System.Numerics.Tests +{ + public static class Constructor + { + private static Random s_random = new Random(); + + public const int DefaultInnerIterationsCount = 100000000; + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_Byte() + { + Byte[] arrValues = GenerateRandomValuesForVector<Byte>(); + var spanValues = new Span<Byte>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<Byte>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_SByte() + { + SByte[] arrValues = GenerateRandomValuesForVector<SByte>(); + var spanValues = new Span<SByte>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<SByte>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_UInt16() + { + UInt16[] arrValues = GenerateRandomValuesForVector<UInt16>(); + var spanValues = new Span<UInt16>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<UInt16>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_Int16() + { + Int16[] arrValues = GenerateRandomValuesForVector<Int16>(); + var spanValues = new Span<Int16>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<Int16>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_UInt32() + { + UInt32[] arrValues = GenerateRandomValuesForVector<UInt32>(); + var spanValues = new Span<UInt32>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<UInt32>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_Int32() + { + Int32[] arrValues = GenerateRandomValuesForVector<Int32>(); + var spanValues = new Span<Int32>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<Int32>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_UInt64() + { + UInt64[] arrValues = GenerateRandomValuesForVector<UInt64>(); + var spanValues = new Span<UInt64>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<UInt64>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_Int64() + { + Int64[] arrValues = GenerateRandomValuesForVector<Int64>(); + var spanValues = new Span<Int64>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<Int64>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_Single() + { + Single[] arrValues = GenerateRandomValuesForVector<Single>(); + var spanValues = new Span<Single>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<Single>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_Double() + { + Double[] arrValues = GenerateRandomValuesForVector<Double>(); + var spanValues = new Span<Double>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<Double>(spanValues); + } + } + } + + + public static void Construct<T>(Span<T> values) where T : struct + { + for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++) + { + Vector<T> vect = new Vector<T>(values); + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_Byte() + { + Byte[] arrValues = GenerateRandomValuesForVector<Byte>(); + var spanValues = new ReadOnlySpan<Byte>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<Byte>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_SByte() + { + SByte[] arrValues = GenerateRandomValuesForVector<SByte>(); + var spanValues = new ReadOnlySpan<SByte>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<SByte>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_UInt16() + { + UInt16[] arrValues = GenerateRandomValuesForVector<UInt16>(); + var spanValues = new ReadOnlySpan<UInt16>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<UInt16>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_Int16() + { + Int16[] arrValues = GenerateRandomValuesForVector<Int16>(); + var spanValues = new ReadOnlySpan<Int16>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<Int16>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_UInt32() + { + UInt32[] arrValues = GenerateRandomValuesForVector<UInt32>(); + var spanValues = new ReadOnlySpan<UInt32>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<UInt32>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_Int32() + { + Int32[] arrValues = GenerateRandomValuesForVector<Int32>(); + var spanValues = new ReadOnlySpan<Int32>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<Int32>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_UInt64() + { + UInt64[] arrValues = GenerateRandomValuesForVector<UInt64>(); + var spanValues = new ReadOnlySpan<UInt64>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<UInt64>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_Int64() + { + Int64[] arrValues = GenerateRandomValuesForVector<Int64>(); + var spanValues = new ReadOnlySpan<Int64>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<Int64>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_Single() + { + Single[] arrValues = GenerateRandomValuesForVector<Single>(); + var spanValues = new ReadOnlySpan<Single>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<Single>(spanValues); + } + } + } + + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_Double() + { + Double[] arrValues = GenerateRandomValuesForVector<Double>(); + var spanValues = new ReadOnlySpan<Double>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<Double>(spanValues); + } + } + } + + + public static void SpanCast<T>(ReadOnlySpan<T> values) where T : struct + { + for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++) + { + ReadOnlySpan<Vector<T>> vectors = MemoryMarshal.Cast<T, Vector<T>>(values); + Vector<T> vector = vectors[0]; + } + } + + internal static T[] GenerateRandomValuesForVector<T>() where T : struct + { + int minValue = GetMinValue<T>(); + int maxValue = GetMaxValue<T>(); + return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue); + } + + internal static int GetMinValue<T>() where T : struct + { + if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64)) + { + return int.MinValue; + } + TypeInfo typeInfo = typeof(T).GetTypeInfo(); + FieldInfo field = typeInfo.GetDeclaredField("MinValue"); + var value = field.GetValue(null); + return (int)(dynamic)value; + } + + internal static int GetMaxValue<T>() where T : struct + { + if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64)) + { + return int.MaxValue; + } + TypeInfo typeInfo = typeof(T).GetTypeInfo(); + FieldInfo field = typeInfo.GetDeclaredField("MaxValue"); + var value = field.GetValue(null); + return (int)(dynamic)value; + } + } +} diff --git a/src/System.Numerics.Vectors/tests/Performance/Constructor/GenericVectorConstructorTests.tt b/src/System.Numerics.Vectors/tests/Performance/Constructor/GenericVectorConstructorTests.tt new file mode 100644 index 0000000000..5fb58ea5a7 --- /dev/null +++ b/src/System.Numerics.Vectors/tests/Performance/Constructor/GenericVectorConstructorTests.tt @@ -0,0 +1,119 @@ +<#@ template debug="true" hostSpecific="true" #> +<#@ output extension=".cs" #> +<#@ Assembly Name="System.Core.dll" #> +<#@ Assembly Name="System.Xml.dll" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Runtime.InteropServices" #> +<#@ include file="..\..\..\..\Common\src\CoreLib\System\Numerics\GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #> + +using System; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using Xunit; +using Xunit.Sdk; +using Microsoft.Xunit.Performance; + +namespace System.Numerics.Tests +{ + public static class Constructor + { + private static Random s_random = new Random(); + + public const int DefaultInnerIterationsCount = 100000000; + +<# + foreach (var type in supportedTypes) + { +#> + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void ConstructorBenchmark_<#=type.Name#>() + { + <#=type.Name#>[] arrValues = GenerateRandomValuesForVector<<#=type.Name#>>(); + var spanValues = new Span<<#=type.Name#>>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + Construct<<#=type.Name#>>(spanValues); + } + } + } + +<# + } +#> + + public static void Construct<T>(Span<T> values) where T : struct + { + for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++) + { + Vector<T> vect = new Vector<T>(values); + } + } + +<# + foreach (var type in supportedTypes) + { +#> + [Benchmark(InnerIterationCount = DefaultInnerIterationsCount)] + public static void SpanCastBenchmark_<#=type.Name#>() + { + <#=type.Name#>[] arrValues = GenerateRandomValuesForVector<<#=type.Name#>>(); + var spanValues = new ReadOnlySpan<<#=type.Name#>>(arrValues); + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + SpanCast<<#=type.Name#>>(spanValues); + } + } + } + +<# + } +#> + + public static void SpanCast<T>(ReadOnlySpan<T> values) where T : struct + { + for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++) + { + ReadOnlySpan<Vector<T>> vectors = MemoryMarshal.Cast<T, Vector<T>>(values); + Vector<T> vector = vectors[0]; + } + } + + internal static T[] GenerateRandomValuesForVector<T>() where T : struct + { + int minValue = GetMinValue<T>(); + int maxValue = GetMaxValue<T>(); + return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue); + } + + internal static int GetMinValue<T>() where T : struct + { + if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64)) + { + return int.MinValue; + } + TypeInfo typeInfo = typeof(T).GetTypeInfo(); + FieldInfo field = typeInfo.GetDeclaredField("MinValue"); + var value = field.GetValue(null); + return (int)(dynamic)value; + } + + internal static int GetMaxValue<T>() where T : struct + { + if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64)) + { + return int.MaxValue; + } + TypeInfo typeInfo = typeof(T).GetTypeInfo(); + FieldInfo field = typeInfo.GetDeclaredField("MaxValue"); + var value = field.GetValue(null); + return (int)(dynamic)value; + } + } +} diff --git a/src/System.Numerics.Vectors/tests/Performance/System.Numerics.Vectors.Performance.Tests.csproj b/src/System.Numerics.Vectors/tests/Performance/System.Numerics.Vectors.Performance.Tests.csproj index 842a2b5a1c..318d8f0e62 100644 --- a/src/System.Numerics.Vectors/tests/Performance/System.Numerics.Vectors.Performance.Tests.csproj +++ b/src/System.Numerics.Vectors/tests/Performance/System.Numerics.Vectors.Performance.Tests.csproj @@ -63,7 +63,29 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <Content Include="Constructor\GenericVectorConstructorTests.tt"> + <Generator>TextTemplatingFileGenerator</Generator> + <LastGenOutput>GenericVectorConstructorTests.cs</LastGenOutput> + </Content> + </ItemGroup> + <ItemGroup> + <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> </ItemGroup> + <ItemGroup> + <Compile Include="..\Util.cs"> + <Link>Util.cs</Link> + </Compile> + <Compile Include="Constructor\GenericVectorConstructorTests.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>GenericVectorConstructorTests.tt</DependentUpon> + </Compile> + </ItemGroup> + <ItemGroup> + <None Include="..\..\..\Common\src\CoreLib\System\Numerics\GenerationConfig.ttinclude"> + <Link>GenerationConfig.ttinclude</Link> + </None> + </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Numerics.Vectors/tests/System.Numerics.Vectors.Tests.csproj b/src/System.Numerics.Vectors/tests/System.Numerics.Vectors.Tests.csproj index fc5d885a92..a79a3da3e2 100644 --- a/src/System.Numerics.Vectors/tests/System.Numerics.Vectors.Tests.csproj +++ b/src/System.Numerics.Vectors/tests/System.Numerics.Vectors.Tests.csproj @@ -35,6 +35,13 @@ <Link>System\MathF.netstandard.cs</Link> </Compile> </ItemGroup> + <ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp' OR '$(TargetGroup)' == 'uap'"> + <Compile Include="GenericVectorTests.netcoreapp.cs"> + <AutoGen>True</AutoGen> + <DesignTime>True</DesignTime> + <DependentUpon>GenericVectorTests.netcoreapp.tt</DependentUpon> + </Compile> + </ItemGroup> <ItemGroup> <None Include="$(CommonPath)\CoreLib\System\Numerics\ConstantHelper.tt"> <Link>ConstantHelper.tt</Link> @@ -50,7 +57,14 @@ </None> </ItemGroup> <ItemGroup> + <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> </ItemGroup> + <ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'"> + <Content Include="GenericVectorTests.netcoreapp.tt"> + <Generator>TextTemplatingFileGenerator</Generator> + <LastGenOutput>GenericVectorTests.netcoreapp.cs</LastGenOutput> + </Content> + </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file |