Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e42c52f

Browse files
committedMar 5, 2018
Issue #24343 Vector Ctor using Span
1 parent ac312b6 commit e42c52f

10 files changed

+945
-7
lines changed
 

‎src/System.Numerics.Vectors/ref/System.Numerics.Vectors.cs

+3
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ public partial struct Vector<T> : System.IEquatable<System.Numerics.Vector<T>>,
301301
public Vector(T value) { throw null; }
302302
public Vector(T[] values) { throw null; }
303303
public Vector(T[] values, int index) { throw null; }
304+
#if netcoreapp
305+
public Vector(Span<T> values) { throw null; }
306+
#endif
304307
public static int Count { get { throw null; } }
305308
public T this[int index] { get { throw null; } }
306309
public static System.Numerics.Vector<T> One { get { throw null; } }

‎src/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<PropertyGroup>
55
<ProjectGuid>{650277B5-9423-4ACE-BB54-2659995B21C7}</ProjectGuid>
66
<IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netfx' OR '$(TargetGroup)' == 'net46'">true</IsPartialFacadeAssembly>
7+
<DefineConstants Condition="'$(TargetGroup)'=='netcoreapp'">$(DefineConstants);netcoreapp</DefineConstants>
78
</PropertyGroup>
89
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net46-Debug|AnyCPU'" />
910
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net46-Release|AnyCPU'" />

‎src/System.Numerics.Vectors/tests/GenericVectorTests.cs

+15-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace System.Numerics.Tests
1414
/// <summary>
1515
/// Vector{T} tests that use random number generation and a unified generic test structure
1616
/// </summary>
17-
public class GenericVectorTests
17+
public partial class GenericVectorTests
1818
{
1919
// Static constructor in top-level class\
2020
static System.Numerics.Vector<float> dummy;
@@ -2699,11 +2699,12 @@ private static void ValidateVector<T>(Vector<T> vector, Action<int, T> indexVali
26992699
}
27002700
}
27012701

2702-
internal static T[] GenerateRandomValuesForVector<T>() where T : struct
2702+
internal static T[] GenerateRandomValuesForVector<T>(int numValues = int.MinValue) where T : struct
27032703
{
27042704
int minValue = GetMinValue<T>();
27052705
int maxValue = GetMaxValue<T>();
2706-
return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue);
2706+
numValues = numValues == int.MinValue ? Vector<T>.Count : numValues;
2707+
return Util.GenerateRandomValues<T>(numValues, minValue, maxValue);
27072708
}
27082709

27092710
internal static int GetMinValue<T>() where T : struct
@@ -2774,6 +2775,16 @@ internal static T GetValueWithAllOnesSet<T>() where T : struct
27742775
}
27752776
throw new NotSupportedException();
27762777
}
2778+
2779+
internal static T[] GetArrayOfDefaultValues<T>(int count)
2780+
{
2781+
T[] arr = new T[count];
2782+
for (int index = 0; index < count; ++index)
2783+
{
2784+
arr[index] = default(T);
2785+
}
2786+
return arr;
2787+
}
27772788
#endregion
27782789
}
2779-
}
2790+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Globalization;
7+
using System.Linq;
8+
using System.Reflection;
9+
using Xunit;
10+
using Xunit.Sdk;
11+
12+
namespace System.Numerics.Tests
13+
{
14+
/// <summary>
15+
/// Vector{T} tests that use random number generation and a unified generic test structure
16+
/// </summary>
17+
public partial class GenericVectorTests
18+
{
19+
#region Constructor Tests
20+
21+
#region Tests for Span based constructor
22+
[Fact]
23+
public void ConstructorWithSpanByte() => TestConstructorWithSpan<Byte>();
24+
[Fact]
25+
public void ConstructorWithSpanSByte() => TestConstructorWithSpan<SByte>();
26+
[Fact]
27+
public void ConstructorWithSpanUInt16() => TestConstructorWithSpan<UInt16>();
28+
[Fact]
29+
public void ConstructorWithSpanInt16() => TestConstructorWithSpan<Int16>();
30+
[Fact]
31+
public void ConstructorWithSpanUInt32() => TestConstructorWithSpan<UInt32>();
32+
[Fact]
33+
public void ConstructorWithSpanInt32() => TestConstructorWithSpan<Int32>();
34+
[Fact]
35+
public void ConstructorWithSpanUInt64() => TestConstructorWithSpan<UInt64>();
36+
[Fact]
37+
public void ConstructorWithSpanInt64() => TestConstructorWithSpan<Int64>();
38+
[Fact]
39+
public void ConstructorWithSpanSingle() => TestConstructorWithSpan<Single>();
40+
[Fact]
41+
public void ConstructorWithSpanDouble() => TestConstructorWithSpan<Double>();
42+
43+
private void TestConstructorWithSpan<T>() where T : struct
44+
{
45+
T[] values = GenerateRandomValuesForVector<T>().ToArray();
46+
Span<T> valueSpan = new Span<T>(values);
47+
48+
var vector = new Vector<T>(valueSpan);
49+
ValidateVector(vector,
50+
(index, val) =>
51+
{
52+
Assert.Equal(values[index], val);
53+
});
54+
}
55+
56+
[Fact]
57+
public void SpanBasedConstructorWithLessElements_Byte() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Byte>());
58+
[Fact]
59+
public void SpanBasedConstructorWithLessElements_SByte() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<SByte>());
60+
[Fact]
61+
public void SpanBasedConstructorWithLessElements_UInt16() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<UInt16>());
62+
[Fact]
63+
public void SpanBasedConstructorWithLessElements_Int16() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Int16>());
64+
[Fact]
65+
public void SpanBasedConstructorWithLessElements_UInt32() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<UInt32>());
66+
[Fact]
67+
public void SpanBasedConstructorWithLessElements_Int32() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Int32>());
68+
[Fact]
69+
public void SpanBasedConstructorWithLessElements_UInt64() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<UInt64>());
70+
[Fact]
71+
public void SpanBasedConstructorWithLessElements_Int64() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Int64>());
72+
[Fact]
73+
public void SpanBasedConstructorWithLessElements_Single() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Single>());
74+
[Fact]
75+
public void SpanBasedConstructorWithLessElements_Double() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<Double>());
76+
77+
private void TestSpanBasedConstructorWithLessElements<T>() where T : struct
78+
{
79+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray();
80+
Span<T> valueSpan = new Span<T>(values);
81+
82+
Vector<T> v = new Vector<T>(valueSpan);
83+
}
84+
85+
#endregion Tests for Span based constructor
86+
87+
#region Tests for Array based constructor
88+
89+
[Fact]
90+
public void ArrayBasedConstructor_Byte() => TestArrayBasedConstructor<Byte>();
91+
[Fact]
92+
public void ArrayBasedConstructor_SByte() => TestArrayBasedConstructor<SByte>();
93+
[Fact]
94+
public void ArrayBasedConstructor_UInt16() => TestArrayBasedConstructor<UInt16>();
95+
[Fact]
96+
public void ArrayBasedConstructor_Int16() => TestArrayBasedConstructor<Int16>();
97+
[Fact]
98+
public void ArrayBasedConstructor_UInt32() => TestArrayBasedConstructor<UInt32>();
99+
[Fact]
100+
public void ArrayBasedConstructor_Int32() => TestArrayBasedConstructor<Int32>();
101+
[Fact]
102+
public void ArrayBasedConstructor_UInt64() => TestArrayBasedConstructor<UInt64>();
103+
[Fact]
104+
public void ArrayBasedConstructor_Int64() => TestArrayBasedConstructor<Int64>();
105+
[Fact]
106+
public void ArrayBasedConstructor_Single() => TestArrayBasedConstructor<Single>();
107+
[Fact]
108+
public void ArrayBasedConstructor_Double() => TestArrayBasedConstructor<Double>();
109+
110+
private void TestArrayBasedConstructor<T>() where T : struct
111+
{
112+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count).ToArray();
113+
Vector<T> vector = new Vector<T>(values);
114+
ValidateVector(vector,
115+
(index, val) =>
116+
{
117+
Assert.Equal(values[index], val);
118+
});
119+
}
120+
121+
[Fact]
122+
public void ArrayIndexBasedConstructor_Byte() => TestArrayIndexBasedConstructor<Byte>();
123+
[Fact]
124+
public void ArrayIndexBasedConstructor_SByte() => TestArrayIndexBasedConstructor<SByte>();
125+
[Fact]
126+
public void ArrayIndexBasedConstructor_UInt16() => TestArrayIndexBasedConstructor<UInt16>();
127+
[Fact]
128+
public void ArrayIndexBasedConstructor_Int16() => TestArrayIndexBasedConstructor<Int16>();
129+
[Fact]
130+
public void ArrayIndexBasedConstructor_UInt32() => TestArrayIndexBasedConstructor<UInt32>();
131+
[Fact]
132+
public void ArrayIndexBasedConstructor_Int32() => TestArrayIndexBasedConstructor<Int32>();
133+
[Fact]
134+
public void ArrayIndexBasedConstructor_UInt64() => TestArrayIndexBasedConstructor<UInt64>();
135+
[Fact]
136+
public void ArrayIndexBasedConstructor_Int64() => TestArrayIndexBasedConstructor<Int64>();
137+
[Fact]
138+
public void ArrayIndexBasedConstructor_Single() => TestArrayIndexBasedConstructor<Single>();
139+
[Fact]
140+
public void ArrayIndexBasedConstructor_Double() => TestArrayIndexBasedConstructor<Double>();
141+
142+
private void TestArrayIndexBasedConstructor<T>() where T : struct
143+
{
144+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray();
145+
int offset = Vector<T>.Count - 1;
146+
Vector<T> vector = new Vector<T>(values, offset);
147+
ValidateVector(vector,
148+
(index, val) =>
149+
{
150+
Assert.Equal(values[offset + index], val);
151+
});
152+
}
153+
154+
[Fact]
155+
public void ArrayBasedConstructorWithLessElements_Byte() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<Byte>());
156+
[Fact]
157+
public void ArrayBasedConstructorWithLessElements_SByte() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<SByte>());
158+
[Fact]
159+
public void ArrayBasedConstructorWithLessElements_UInt16() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<UInt16>());
160+
[Fact]
161+
public void ArrayBasedConstructorWithLessElements_Int16() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<Int16>());
162+
[Fact]
163+
public void ArrayBasedConstructorWithLessElements_UInt32() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<UInt32>());
164+
[Fact]
165+
public void ArrayBasedConstructorWithLessElements_Int32() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<Int32>());
166+
[Fact]
167+
public void ArrayBasedConstructorWithLessElements_UInt64() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<UInt64>());
168+
[Fact]
169+
public void ArrayBasedConstructorWithLessElements_Int64() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<Int64>());
170+
[Fact]
171+
public void ArrayBasedConstructorWithLessElements_Single() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<Single>());
172+
[Fact]
173+
public void ArrayBasedConstructorWithLessElements_Double() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<Double>());
174+
175+
private void TestArrayBasedConstructorWithLessElements<T>() where T : struct
176+
{
177+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray();
178+
Vector<T> v = new Vector<T>(values);
179+
}
180+
181+
[Fact]
182+
public void ArrayIndexBasedConstructorLessElements_Byte() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<Byte>());
183+
[Fact]
184+
public void ArrayIndexBasedConstructorLessElements_SByte() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<SByte>());
185+
[Fact]
186+
public void ArrayIndexBasedConstructorLessElements_UInt16() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<UInt16>());
187+
[Fact]
188+
public void ArrayIndexBasedConstructorLessElements_Int16() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<Int16>());
189+
[Fact]
190+
public void ArrayIndexBasedConstructorLessElements_UInt32() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<UInt32>());
191+
[Fact]
192+
public void ArrayIndexBasedConstructorLessElements_Int32() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<Int32>());
193+
[Fact]
194+
public void ArrayIndexBasedConstructorLessElements_UInt64() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<UInt64>());
195+
[Fact]
196+
public void ArrayIndexBasedConstructorLessElements_Int64() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<Int64>());
197+
[Fact]
198+
public void ArrayIndexBasedConstructorLessElements_Single() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<Single>());
199+
[Fact]
200+
public void ArrayIndexBasedConstructorLessElements_Double() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<Double>());
201+
202+
private void TestArrayIndexBasedConstructorLessElements<T>() where T : struct
203+
{
204+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray();
205+
Vector<T> v = new Vector<T>(values, Vector<T>.Count + 1);
206+
}
207+
208+
#endregion Tests for Array based constructor
209+
210+
#region Tests for constructors using unsupported types
211+
212+
[Fact]
213+
public void ConstructorWithUnsupportedTypes_Guid() => TestConstructorWithUnsupportedTypes<Guid>();
214+
[Fact]
215+
public void ConstructorWithUnsupportedTypes_DateTime() => TestConstructorWithUnsupportedTypes<DateTime>();
216+
[Fact]
217+
public void ConstructorWithUnsupportedTypes_Char() => TestConstructorWithUnsupportedTypes<Char>();
218+
219+
private void TestConstructorWithUnsupportedTypes<T>() where T : struct
220+
{
221+
Assert.Throws<NotSupportedException>(() =>
222+
{
223+
T[] arr = GetArrayOfDefaultValues<T>(4);
224+
Span<T> span = new Span<T>(arr);
225+
Vector<T> vector = new Vector<T>(span);
226+
});
227+
}
228+
229+
#endregion Tests for constructors using unsupported types
230+
231+
#endregion Constructor Tests
232+
}
233+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
<#@ template debug="true" hostSpecific="true" #>
2+
<#@ output extension=".cs" #>
3+
<#@ Assembly Name="System.Core.dll" #>
4+
<#@ Assembly Name="System.Xml.dll" #>
5+
<#@ import namespace="System" #>
6+
<#@ import namespace="System.Linq" #>
7+
<#@ import namespace="System.Runtime.InteropServices" #>
8+
<#@ include file="..\..\Common\src\CoreLib\System\Numerics\GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #>
9+
10+
using System;
11+
using System.Globalization;
12+
using System.Linq;
13+
using System.Reflection;
14+
using Xunit;
15+
using Xunit.Sdk;
16+
17+
namespace System.Numerics.Tests
18+
{
19+
/// <summary>
20+
/// Vector{T} tests that use random number generation and a unified generic test structure
21+
/// </summary>
22+
public partial class GenericVectorTests
23+
{
24+
#region Constructor Tests
25+
26+
#region Tests for Span based constructor
27+
<#
28+
foreach (var type in supportedTypes)
29+
{
30+
#>
31+
[Fact]
32+
public void ConstructorWithSpan<#=type.Name#>() => TestConstructorWithSpan<<#=type.Name#>>();
33+
<#
34+
}
35+
#>
36+
37+
private void TestConstructorWithSpan<T>() where T : struct
38+
{
39+
T[] values = GenerateRandomValuesForVector<T>().ToArray();
40+
Span<T> valueSpan = new Span<T>(values);
41+
42+
var vector = new Vector<T>(valueSpan);
43+
ValidateVector(vector,
44+
(index, val) =>
45+
{
46+
Assert.Equal(values[index], val);
47+
});
48+
}
49+
50+
<#
51+
foreach (var type in supportedTypes)
52+
{
53+
#>
54+
[Fact]
55+
public void SpanBasedConstructorWithLessElements_<#=type.Name#>() => Assert.Throws<IndexOutOfRangeException>(() => TestSpanBasedConstructorWithLessElements<<#=type.Name#>>());
56+
<#
57+
}
58+
#>
59+
60+
private void TestSpanBasedConstructorWithLessElements<T>() where T : struct
61+
{
62+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray();
63+
Span<T> valueSpan = new Span<T>(values);
64+
65+
Vector<T> v = new Vector<T>(valueSpan);
66+
}
67+
68+
#endregion Tests for Span based constructor
69+
70+
#region Tests for Array based constructor
71+
72+
<#
73+
foreach (var type in supportedTypes)
74+
{
75+
#>
76+
[Fact]
77+
public void ArrayBasedConstructor_<#=type.Name#>() => TestArrayBasedConstructor<<#=type.Name#>>();
78+
<#
79+
}
80+
#>
81+
82+
private void TestArrayBasedConstructor<T>() where T : struct
83+
{
84+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count).ToArray();
85+
Vector<T> vector = new Vector<T>(values);
86+
ValidateVector(vector,
87+
(index, val) =>
88+
{
89+
Assert.Equal(values[index], val);
90+
});
91+
}
92+
93+
<#
94+
foreach (var type in supportedTypes)
95+
{
96+
#>
97+
[Fact]
98+
public void ArrayIndexBasedConstructor_<#=type.Name#>() => TestArrayIndexBasedConstructor<<#=type.Name#>>();
99+
<#
100+
}
101+
#>
102+
103+
private void TestArrayIndexBasedConstructor<T>() where T : struct
104+
{
105+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray();
106+
int offset = Vector<T>.Count - 1;
107+
Vector<T> vector = new Vector<T>(values, offset);
108+
ValidateVector(vector,
109+
(index, val) =>
110+
{
111+
Assert.Equal(values[offset + index], val);
112+
});
113+
}
114+
115+
<#
116+
foreach (var type in supportedTypes)
117+
{
118+
#>
119+
[Fact]
120+
public void ArrayBasedConstructorWithLessElements_<#=type.Name#>() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayBasedConstructorWithLessElements<<#=type.Name#>>());
121+
<#
122+
}
123+
#>
124+
125+
private void TestArrayBasedConstructorWithLessElements<T>() where T : struct
126+
{
127+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count - 1).ToArray();
128+
Vector<T> v = new Vector<T>(values);
129+
}
130+
131+
<#
132+
foreach (var type in supportedTypes)
133+
{
134+
#>
135+
[Fact]
136+
public void ArrayIndexBasedConstructorLessElements_<#=type.Name#>() => Assert.Throws<IndexOutOfRangeException>(() => TestArrayIndexBasedConstructorLessElements<<#=type.Name#>>());
137+
<#
138+
}
139+
#>
140+
141+
private void TestArrayIndexBasedConstructorLessElements<T>() where T : struct
142+
{
143+
T[] values = GenerateRandomValuesForVector<T>(Vector<T>.Count * 2).ToArray();
144+
Vector<T> v = new Vector<T>(values, Vector<T>.Count + 1);
145+
}
146+
147+
#endregion Tests for Array based constructor
148+
149+
#region Tests for constructors using unsupported types
150+
151+
<#
152+
Type[] unsupportedTypes = new[]
153+
{
154+
typeof(Guid), typeof(DateTime), typeof(char)
155+
};
156+
157+
158+
foreach (var type in unsupportedTypes)
159+
{
160+
#>
161+
[Fact]
162+
public void ConstructorWithUnsupportedTypes_<#=type.Name#>() => TestConstructorWithUnsupportedTypes<<#=type.Name#>>();
163+
<#
164+
}
165+
#>
166+
167+
private void TestConstructorWithUnsupportedTypes<T>() where T : struct
168+
{
169+
Assert.Throws<NotSupportedException>(() =>
170+
{
171+
T[] arr = GetArrayOfDefaultValues<T>(4);
172+
Span<T> span = new Span<T>(arr);
173+
Vector<T> vector = new Vector<T>(span);
174+
});
175+
}
176+
177+
#endregion Tests for constructors using unsupported types
178+
179+
#endregion Constructor Tests
180+
}
181+
}

‎src/System.Numerics.Vectors/tests/GenericVectorTests.tt

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace System.Numerics.Tests
1919
/// <summary>
2020
/// Vector{T} tests that use random number generation and a unified generic test structure
2121
/// </summary>
22-
public class GenericVectorTests
22+
public partial class GenericVectorTests
2323
{
2424
// Static constructor in top-level class\
2525
static System.Numerics.Vector<float> dummy;
@@ -116,7 +116,7 @@ namespace System.Numerics.Tests
116116
});
117117
}
118118

119-
<#
119+
<#
120120
foreach (var type in supportedTypes)
121121
{
122122
#>
@@ -1869,4 +1869,4 @@ namespace System.Numerics.Tests
18691869
}
18701870
#endregion
18711871
}
1872-
}
1872+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Globalization;
7+
using System.Linq;
8+
using System.Reflection;
9+
using System.Runtime.InteropServices;
10+
using Xunit;
11+
using Xunit.Sdk;
12+
using Microsoft.Xunit.Performance;
13+
14+
namespace System.Numerics.Tests
15+
{
16+
public static class Constructor
17+
{
18+
private static Random s_random = new Random();
19+
20+
public const int DefaultInnerIterationsCount = 100000000;
21+
22+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
23+
public static void ConstructorBenchmark_Byte()
24+
{
25+
Byte[] arrValues = GenerateRandomValuesForVector<Byte>();
26+
var spanValues = new Span<Byte>(arrValues);
27+
foreach (var iteration in Benchmark.Iterations)
28+
{
29+
using (iteration.StartMeasurement())
30+
{
31+
Construct<Byte>(spanValues);
32+
}
33+
}
34+
}
35+
36+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
37+
public static void ConstructorBenchmark_SByte()
38+
{
39+
SByte[] arrValues = GenerateRandomValuesForVector<SByte>();
40+
var spanValues = new Span<SByte>(arrValues);
41+
foreach (var iteration in Benchmark.Iterations)
42+
{
43+
using (iteration.StartMeasurement())
44+
{
45+
Construct<SByte>(spanValues);
46+
}
47+
}
48+
}
49+
50+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
51+
public static void ConstructorBenchmark_UInt16()
52+
{
53+
UInt16[] arrValues = GenerateRandomValuesForVector<UInt16>();
54+
var spanValues = new Span<UInt16>(arrValues);
55+
foreach (var iteration in Benchmark.Iterations)
56+
{
57+
using (iteration.StartMeasurement())
58+
{
59+
Construct<UInt16>(spanValues);
60+
}
61+
}
62+
}
63+
64+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
65+
public static void ConstructorBenchmark_Int16()
66+
{
67+
Int16[] arrValues = GenerateRandomValuesForVector<Int16>();
68+
var spanValues = new Span<Int16>(arrValues);
69+
foreach (var iteration in Benchmark.Iterations)
70+
{
71+
using (iteration.StartMeasurement())
72+
{
73+
Construct<Int16>(spanValues);
74+
}
75+
}
76+
}
77+
78+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
79+
public static void ConstructorBenchmark_UInt32()
80+
{
81+
UInt32[] arrValues = GenerateRandomValuesForVector<UInt32>();
82+
var spanValues = new Span<UInt32>(arrValues);
83+
foreach (var iteration in Benchmark.Iterations)
84+
{
85+
using (iteration.StartMeasurement())
86+
{
87+
Construct<UInt32>(spanValues);
88+
}
89+
}
90+
}
91+
92+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
93+
public static void ConstructorBenchmark_Int32()
94+
{
95+
Int32[] arrValues = GenerateRandomValuesForVector<Int32>();
96+
var spanValues = new Span<Int32>(arrValues);
97+
foreach (var iteration in Benchmark.Iterations)
98+
{
99+
using (iteration.StartMeasurement())
100+
{
101+
Construct<Int32>(spanValues);
102+
}
103+
}
104+
}
105+
106+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
107+
public static void ConstructorBenchmark_UInt64()
108+
{
109+
UInt64[] arrValues = GenerateRandomValuesForVector<UInt64>();
110+
var spanValues = new Span<UInt64>(arrValues);
111+
foreach (var iteration in Benchmark.Iterations)
112+
{
113+
using (iteration.StartMeasurement())
114+
{
115+
Construct<UInt64>(spanValues);
116+
}
117+
}
118+
}
119+
120+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
121+
public static void ConstructorBenchmark_Int64()
122+
{
123+
Int64[] arrValues = GenerateRandomValuesForVector<Int64>();
124+
var spanValues = new Span<Int64>(arrValues);
125+
foreach (var iteration in Benchmark.Iterations)
126+
{
127+
using (iteration.StartMeasurement())
128+
{
129+
Construct<Int64>(spanValues);
130+
}
131+
}
132+
}
133+
134+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
135+
public static void ConstructorBenchmark_Single()
136+
{
137+
Single[] arrValues = GenerateRandomValuesForVector<Single>();
138+
var spanValues = new Span<Single>(arrValues);
139+
foreach (var iteration in Benchmark.Iterations)
140+
{
141+
using (iteration.StartMeasurement())
142+
{
143+
Construct<Single>(spanValues);
144+
}
145+
}
146+
}
147+
148+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
149+
public static void ConstructorBenchmark_Double()
150+
{
151+
Double[] arrValues = GenerateRandomValuesForVector<Double>();
152+
var spanValues = new Span<Double>(arrValues);
153+
foreach (var iteration in Benchmark.Iterations)
154+
{
155+
using (iteration.StartMeasurement())
156+
{
157+
Construct<Double>(spanValues);
158+
}
159+
}
160+
}
161+
162+
163+
public static void Construct<T>(Span<T> values) where T : struct
164+
{
165+
for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++)
166+
{
167+
Vector<T> vect = new Vector<T>(values);
168+
}
169+
}
170+
171+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
172+
public static void SpanCastBenchmark_Byte()
173+
{
174+
Byte[] arrValues = GenerateRandomValuesForVector<Byte>();
175+
var spanValues = new ReadOnlySpan<Byte>(arrValues);
176+
foreach (var iteration in Benchmark.Iterations)
177+
{
178+
using (iteration.StartMeasurement())
179+
{
180+
SpanCast<Byte>(spanValues);
181+
}
182+
}
183+
}
184+
185+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
186+
public static void SpanCastBenchmark_SByte()
187+
{
188+
SByte[] arrValues = GenerateRandomValuesForVector<SByte>();
189+
var spanValues = new ReadOnlySpan<SByte>(arrValues);
190+
foreach (var iteration in Benchmark.Iterations)
191+
{
192+
using (iteration.StartMeasurement())
193+
{
194+
SpanCast<SByte>(spanValues);
195+
}
196+
}
197+
}
198+
199+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
200+
public static void SpanCastBenchmark_UInt16()
201+
{
202+
UInt16[] arrValues = GenerateRandomValuesForVector<UInt16>();
203+
var spanValues = new ReadOnlySpan<UInt16>(arrValues);
204+
foreach (var iteration in Benchmark.Iterations)
205+
{
206+
using (iteration.StartMeasurement())
207+
{
208+
SpanCast<UInt16>(spanValues);
209+
}
210+
}
211+
}
212+
213+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
214+
public static void SpanCastBenchmark_Int16()
215+
{
216+
Int16[] arrValues = GenerateRandomValuesForVector<Int16>();
217+
var spanValues = new ReadOnlySpan<Int16>(arrValues);
218+
foreach (var iteration in Benchmark.Iterations)
219+
{
220+
using (iteration.StartMeasurement())
221+
{
222+
SpanCast<Int16>(spanValues);
223+
}
224+
}
225+
}
226+
227+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
228+
public static void SpanCastBenchmark_UInt32()
229+
{
230+
UInt32[] arrValues = GenerateRandomValuesForVector<UInt32>();
231+
var spanValues = new ReadOnlySpan<UInt32>(arrValues);
232+
foreach (var iteration in Benchmark.Iterations)
233+
{
234+
using (iteration.StartMeasurement())
235+
{
236+
SpanCast<UInt32>(spanValues);
237+
}
238+
}
239+
}
240+
241+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
242+
public static void SpanCastBenchmark_Int32()
243+
{
244+
Int32[] arrValues = GenerateRandomValuesForVector<Int32>();
245+
var spanValues = new ReadOnlySpan<Int32>(arrValues);
246+
foreach (var iteration in Benchmark.Iterations)
247+
{
248+
using (iteration.StartMeasurement())
249+
{
250+
SpanCast<Int32>(spanValues);
251+
}
252+
}
253+
}
254+
255+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
256+
public static void SpanCastBenchmark_UInt64()
257+
{
258+
UInt64[] arrValues = GenerateRandomValuesForVector<UInt64>();
259+
var spanValues = new ReadOnlySpan<UInt64>(arrValues);
260+
foreach (var iteration in Benchmark.Iterations)
261+
{
262+
using (iteration.StartMeasurement())
263+
{
264+
SpanCast<UInt64>(spanValues);
265+
}
266+
}
267+
}
268+
269+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
270+
public static void SpanCastBenchmark_Int64()
271+
{
272+
Int64[] arrValues = GenerateRandomValuesForVector<Int64>();
273+
var spanValues = new ReadOnlySpan<Int64>(arrValues);
274+
foreach (var iteration in Benchmark.Iterations)
275+
{
276+
using (iteration.StartMeasurement())
277+
{
278+
SpanCast<Int64>(spanValues);
279+
}
280+
}
281+
}
282+
283+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
284+
public static void SpanCastBenchmark_Single()
285+
{
286+
Single[] arrValues = GenerateRandomValuesForVector<Single>();
287+
var spanValues = new ReadOnlySpan<Single>(arrValues);
288+
foreach (var iteration in Benchmark.Iterations)
289+
{
290+
using (iteration.StartMeasurement())
291+
{
292+
SpanCast<Single>(spanValues);
293+
}
294+
}
295+
}
296+
297+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
298+
public static void SpanCastBenchmark_Double()
299+
{
300+
Double[] arrValues = GenerateRandomValuesForVector<Double>();
301+
var spanValues = new ReadOnlySpan<Double>(arrValues);
302+
foreach (var iteration in Benchmark.Iterations)
303+
{
304+
using (iteration.StartMeasurement())
305+
{
306+
SpanCast<Double>(spanValues);
307+
}
308+
}
309+
}
310+
311+
312+
public static void SpanCast<T>(ReadOnlySpan<T> values) where T : struct
313+
{
314+
for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++)
315+
{
316+
ReadOnlySpan<Vector<T>> vectors = MemoryMarshal.Cast<T, Vector<T>>(values);
317+
Vector<T> vector = vectors[0];
318+
}
319+
}
320+
321+
internal static T[] GenerateRandomValuesForVector<T>() where T : struct
322+
{
323+
int minValue = GetMinValue<T>();
324+
int maxValue = GetMaxValue<T>();
325+
return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue);
326+
}
327+
328+
internal static int GetMinValue<T>() where T : struct
329+
{
330+
if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64))
331+
{
332+
return int.MinValue;
333+
}
334+
var typeInfo = typeof(T).GetTypeInfo();
335+
var field = typeInfo.GetDeclaredField("MinValue");
336+
var value = field.GetValue(null);
337+
return (int)(dynamic)value;
338+
}
339+
340+
internal static int GetMaxValue<T>() where T : struct
341+
{
342+
if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64))
343+
{
344+
return int.MaxValue;
345+
}
346+
var typeInfo = typeof(T).GetTypeInfo();
347+
var field = typeInfo.GetDeclaredField("MaxValue");
348+
var value = field.GetValue(null);
349+
return (int)(dynamic)value;
350+
}
351+
352+
}
353+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<#@ template debug="true" hostSpecific="true" #>
2+
<#@ output extension=".cs" #>
3+
<#@ Assembly Name="System.Core.dll" #>
4+
<#@ Assembly Name="System.Xml.dll" #>
5+
<#@ import namespace="System" #>
6+
<#@ import namespace="System.Linq" #>
7+
<#@ import namespace="System.Runtime.InteropServices" #>
8+
<#@ include file="..\..\..\..\Common\src\CoreLib\System\Numerics\GenerationConfig.ttinclude" #><# GenerateCopyrightHeader(); #>
9+
10+
using System;
11+
using System.Globalization;
12+
using System.Linq;
13+
using System.Reflection;
14+
using System.Runtime.InteropServices;
15+
using Xunit;
16+
using Xunit.Sdk;
17+
using Microsoft.Xunit.Performance;
18+
19+
namespace System.Numerics.Tests
20+
{
21+
public static class Constructor
22+
{
23+
private static Random s_random = new Random();
24+
25+
public const int DefaultInnerIterationsCount = 100000000;
26+
27+
<#
28+
foreach (var type in supportedTypes)
29+
{
30+
#>
31+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
32+
public static void ConstructorBenchmark_<#=type.Name#>()
33+
{
34+
<#=type.Name#>[] arrValues = GenerateRandomValuesForVector<<#=type.Name#>>();
35+
var spanValues = new Span<<#=type.Name#>>(arrValues);
36+
foreach (var iteration in Benchmark.Iterations)
37+
{
38+
using (iteration.StartMeasurement())
39+
{
40+
Construct<<#=type.Name#>>(spanValues);
41+
}
42+
}
43+
}
44+
45+
<#
46+
}
47+
#>
48+
49+
public static void Construct<T>(Span<T> values) where T : struct
50+
{
51+
for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++)
52+
{
53+
Vector<T> vect = new Vector<T>(values);
54+
}
55+
}
56+
57+
<#
58+
foreach (var type in supportedTypes)
59+
{
60+
#>
61+
[Benchmark(InnerIterationCount = DefaultInnerIterationsCount)]
62+
public static void SpanCastBenchmark_<#=type.Name#>()
63+
{
64+
<#=type.Name#>[] arrValues = GenerateRandomValuesForVector<<#=type.Name#>>();
65+
var spanValues = new ReadOnlySpan<<#=type.Name#>>(arrValues);
66+
foreach (var iteration in Benchmark.Iterations)
67+
{
68+
using (iteration.StartMeasurement())
69+
{
70+
SpanCast<<#=type.Name#>>(spanValues);
71+
}
72+
}
73+
}
74+
75+
<#
76+
}
77+
#>
78+
79+
public static void SpanCast<T>(ReadOnlySpan<T> values) where T : struct
80+
{
81+
for (var iteration = 0; iteration < Benchmark.InnerIterationCount; iteration++)
82+
{
83+
ReadOnlySpan<Vector<T>> vectors = MemoryMarshal.Cast<T, Vector<T>>(values);
84+
Vector<T> vector = vectors[0];
85+
}
86+
}
87+
88+
internal static T[] GenerateRandomValuesForVector<T>() where T : struct
89+
{
90+
int minValue = GetMinValue<T>();
91+
int maxValue = GetMaxValue<T>();
92+
return Util.GenerateRandomValues<T>(Vector<T>.Count, minValue, maxValue);
93+
}
94+
95+
internal static int GetMinValue<T>() where T : struct
96+
{
97+
if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64))
98+
{
99+
return int.MinValue;
100+
}
101+
var typeInfo = typeof(T).GetTypeInfo();
102+
var field = typeInfo.GetDeclaredField("MinValue");
103+
var value = field.GetValue(null);
104+
return (int)(dynamic)value;
105+
}
106+
107+
internal static int GetMaxValue<T>() where T : struct
108+
{
109+
if (typeof(T) == typeof(Int64) || typeof(T) == typeof(Single) || typeof(T) == typeof(Double) || typeof(T) == typeof(UInt32) || typeof(T) == typeof(UInt64))
110+
{
111+
return int.MaxValue;
112+
}
113+
var typeInfo = typeof(T).GetTypeInfo();
114+
var field = typeInfo.GetDeclaredField("MaxValue");
115+
var value = field.GetValue(null);
116+
return (int)(dynamic)value;
117+
}
118+
119+
}
120+
}

‎src/System.Numerics.Vectors/tests/Performance/System.Numerics.Vectors.Performance.Tests.csproj

+22
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,29 @@
6363
</ProjectReference>
6464
</ItemGroup>
6565
<ItemGroup>
66+
<Content Include="Constructor\GenericVectorConstructorTests.tt">
67+
<Generator>TextTemplatingFileGenerator</Generator>
68+
<LastGenOutput>GenericVectorConstructorTests.cs</LastGenOutput>
69+
</Content>
70+
</ItemGroup>
71+
<ItemGroup>
72+
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
6673
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
6774
</ItemGroup>
75+
<ItemGroup>
76+
<Compile Include="..\Util.cs">
77+
<Link>Util.cs</Link>
78+
</Compile>
79+
<Compile Include="Constructor\GenericVectorConstructorTests.cs">
80+
<AutoGen>True</AutoGen>
81+
<DesignTime>True</DesignTime>
82+
<DependentUpon>GenericVectorConstructorTests.tt</DependentUpon>
83+
</Compile>
84+
</ItemGroup>
85+
<ItemGroup>
86+
<None Include="..\..\..\Common\src\CoreLib\System\Numerics\GenerationConfig.ttinclude">
87+
<Link>GenerationConfig.ttinclude</Link>
88+
</None>
89+
</ItemGroup>
6890
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
6991
</Project>

‎src/System.Numerics.Vectors/tests/System.Numerics.Vectors.Tests.csproj

+14
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535
<Link>System\MathF.netstandard.cs</Link>
3636
</Compile>
3737
</ItemGroup>
38+
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
39+
<Compile Include="GenericVectorTests.netcoreapp.cs">
40+
<AutoGen>True</AutoGen>
41+
<DesignTime>True</DesignTime>
42+
<DependentUpon>GenericVectorTests.netcoreapp.tt</DependentUpon>
43+
</Compile>
44+
</ItemGroup>
3845
<ItemGroup>
3946
<None Include="$(CommonPath)\CoreLib\System\Numerics\ConstantHelper.tt">
4047
<Link>ConstantHelper.tt</Link>
@@ -50,7 +57,14 @@
5057
</None>
5158
</ItemGroup>
5259
<ItemGroup>
60+
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
5361
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
5462
</ItemGroup>
63+
<ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
64+
<Content Include="GenericVectorTests.netcoreapp.tt">
65+
<Generator>TextTemplatingFileGenerator</Generator>
66+
<LastGenOutput>GenericVectorTests.netcoreapp.cs</LastGenOutput>
67+
</Content>
68+
</ItemGroup>
5569
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
5670
</Project>

0 commit comments

Comments
 (0)
Please sign in to comment.