Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b47ab22

Browse files
Merge pull request #15771 from tannergooding/hwintrin-tests
Update x86 HWIntrinsic Tests
2 parents e4d6e78 + 9bfca6a commit b47ab22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+7793
-2542
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
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+
/******************************************************************************
6+
* This file is auto-generated from a template file by the GenerateTests.csx *
7+
* script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
8+
* changes, please update the corresponding template and run according to the *
9+
* directions listed in the file. *
10+
******************************************************************************/
11+
12+
using System;
13+
using System.Runtime.CompilerServices;
14+
using System.Runtime.InteropServices;
15+
using System.Runtime.Intrinsics;
16+
using System.Runtime.Intrinsics.X86;
17+
18+
namespace JIT.HardwareIntrinsics.X86
19+
{
20+
public static partial class Program
21+
{
22+
private static void AddDouble()
23+
{
24+
var test = new SimpleBinaryOpTest__AddDouble();
25+
26+
if (test.IsSupported)
27+
{
28+
// Validates basic functionality works
29+
test.RunBasicScenario();
30+
31+
// Validates calling via reflection works
32+
test.RunReflectionScenario();
33+
34+
// Validates passing a static member works
35+
test.RunClsVarScenario();
36+
37+
// Validates passing a local works
38+
test.RunLclVarScenario();
39+
40+
// Validates passing the field of a local works
41+
test.RunLclFldScenario();
42+
43+
// Validates passing an instance member works
44+
test.RunFldScenario();
45+
}
46+
else
47+
{
48+
// Validates we throw on unsupported hardware
49+
test.RunUnsupportedScenario();
50+
}
51+
52+
if (!test.Succeeded)
53+
{
54+
throw new Exception("One or more scenarios did not complete as expected.");
55+
}
56+
}
57+
}
58+
59+
public sealed unsafe class SimpleBinaryOpTest__AddDouble
60+
{
61+
private const int VectorSize = 32;
62+
private const int ElementCount = VectorSize / sizeof(Double);
63+
64+
private static Double[] _data1 = new Double[ElementCount];
65+
private static Double[] _data2 = new Double[ElementCount];
66+
67+
private static Vector256<Double> _clsVar1;
68+
private static Vector256<Double> _clsVar2;
69+
70+
private Vector256<Double> _fld1;
71+
private Vector256<Double> _fld2;
72+
73+
private SimpleBinaryOpTest__DataTable<Double> _dataTable;
74+
75+
static SimpleBinaryOpTest__AddDouble()
76+
{
77+
var random = new Random();
78+
79+
for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
80+
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
81+
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
82+
}
83+
84+
public SimpleBinaryOpTest__AddDouble()
85+
{
86+
Succeeded = true;
87+
88+
var random = new Random();
89+
90+
for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
91+
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), VectorSize);
92+
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), VectorSize);
93+
94+
for (var i = 0; i < ElementCount; i++) { _data1[i] = (double)(random.NextDouble()); _data2[i] = (double)(random.NextDouble()); }
95+
_dataTable = new SimpleBinaryOpTest__DataTable<Double>(_data1, _data2, new Double[ElementCount]);
96+
}
97+
98+
public bool IsSupported => Avx.IsSupported;
99+
100+
public bool Succeeded { get; set; }
101+
102+
public void RunBasicScenario()
103+
{
104+
var result = Avx.Add(
105+
Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
106+
Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr)
107+
);
108+
109+
Unsafe.Write(_dataTable.outArrayPtr, result);
110+
ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
111+
}
112+
113+
public void RunReflectionScenario()
114+
{
115+
var result = typeof(Avx).GetMethod(nameof(Avx.Add), new Type[] { typeof(Vector256<Double>), typeof(Vector256<Double>) })
116+
.Invoke(null, new object[] {
117+
Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr),
118+
Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr)
119+
});
120+
121+
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
122+
ValidateResult(_dataTable.inArray1, _dataTable.inArray2, _dataTable.outArray);
123+
}
124+
125+
public void RunClsVarScenario()
126+
{
127+
var result = Avx.Add(
128+
_clsVar1,
129+
_clsVar2
130+
);
131+
132+
Unsafe.Write(_dataTable.outArrayPtr, result);
133+
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArray);
134+
}
135+
136+
public void RunLclVarScenario()
137+
{
138+
var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
139+
var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
140+
var result = Avx.Add(left, right);
141+
142+
Unsafe.Write(_dataTable.outArrayPtr, result);
143+
ValidateResult(left, right, _dataTable.outArray);
144+
}
145+
146+
public void RunLclFldScenario()
147+
{
148+
var test = new SimpleBinaryOpTest__AddDouble();
149+
var result = Avx.Add(test._fld1, test._fld2);
150+
151+
Unsafe.Write(_dataTable.outArrayPtr, result);
152+
ValidateResult(test._fld1, test._fld2, _dataTable.outArray);
153+
}
154+
155+
public void RunFldScenario()
156+
{
157+
var result = Avx.Add(_fld1, _fld2);
158+
159+
Unsafe.Write(_dataTable.outArrayPtr, result);
160+
ValidateResult(_fld1, _fld2, _dataTable.outArray);
161+
}
162+
163+
public void RunUnsupportedScenario()
164+
{
165+
Succeeded = false;
166+
167+
try
168+
{
169+
RunBasicScenario();
170+
}
171+
catch (PlatformNotSupportedException)
172+
{
173+
Succeeded = true;
174+
}
175+
}
176+
177+
private void ValidateResult(Vector256<Double> left, Vector256<Double> right, Double[] result, [CallerMemberName] string method = "")
178+
{
179+
Double[] inArray1 = new Double[ElementCount];
180+
Double[] inArray2 = new Double[ElementCount];
181+
182+
Unsafe.Write(Unsafe.AsPointer(ref inArray1[0]), left);
183+
Unsafe.Write(Unsafe.AsPointer(ref inArray2[0]), right);
184+
185+
ValidateResult(inArray1, inArray2, result, method);
186+
}
187+
188+
private void ValidateResult(Double[] left, Double[] right, Double[] result, [CallerMemberName] string method = "")
189+
{
190+
if (BitConverter.DoubleToInt64Bits(left[0] + right[0]) != BitConverter.DoubleToInt64Bits(result[0]))
191+
{
192+
Succeeded = false;
193+
}
194+
else
195+
{
196+
for (var i = 1; i < left.Length; i++)
197+
{
198+
if (BitConverter.DoubleToInt64Bits(left[i] + right[i]) != BitConverter.DoubleToInt64Bits(result[i]))
199+
{
200+
Succeeded = false;
201+
break;
202+
}
203+
}
204+
}
205+
206+
if (!Succeeded)
207+
{
208+
Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Add)}<Double>: {method} failed:");
209+
Console.WriteLine($" left: ({string.Join(", ", left)})");
210+
Console.WriteLine($" right: ({string.Join(", ", right)})");
211+
Console.WriteLine($" result: ({string.Join(", ", result)})");
212+
Console.WriteLine();
213+
}
214+
}
215+
}
216+
}

0 commit comments

Comments
 (0)