Remove random.NextDouble() from JIT/HardwareIntrinsics tests (#18838)
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Sse41 / RoundCurrentDirection.Double.cs
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 RoundCurrentDirectionDouble()
23         {
24             var test = new SimpleUnaryOpTest__RoundCurrentDirectionDouble();
25
26             if (test.IsSupported)
27             {
28                 // Validates basic functionality works, using Unsafe.Read
29                 test.RunBasicScenario_UnsafeRead();
30
31                 if (Sse2.IsSupported)
32                 {
33                     // Validates basic functionality works, using Load
34                     test.RunBasicScenario_Load();
35
36                     // Validates basic functionality works, using LoadAligned
37                     test.RunBasicScenario_LoadAligned();
38                 }
39
40                 // Validates calling via reflection works, using Unsafe.Read
41                 test.RunReflectionScenario_UnsafeRead();
42
43                 if (Sse2.IsSupported)
44                 {
45                     // Validates calling via reflection works, using Load
46                     test.RunReflectionScenario_Load();
47
48                     // Validates calling via reflection works, using LoadAligned
49                     test.RunReflectionScenario_LoadAligned();
50                 }
51
52                 // Validates passing a static member works
53                 test.RunClsVarScenario();
54
55                 // Validates passing a local works, using Unsafe.Read
56                 test.RunLclVarScenario_UnsafeRead();
57
58                 if (Sse2.IsSupported)
59                 {
60                     // Validates passing a local works, using Load
61                     test.RunLclVarScenario_Load();
62
63                     // Validates passing a local works, using LoadAligned
64                     test.RunLclVarScenario_LoadAligned();
65                 }
66
67                 // Validates passing the field of a local class works
68                 test.RunClassLclFldScenario();
69
70                 // Validates passing an instance member of a class works
71                 test.RunClassFldScenario();
72
73                 // Validates passing the field of a local struct works
74                 test.RunStructLclFldScenario();
75
76                 // Validates passing an instance member of a struct works
77                 test.RunStructFldScenario();
78             }
79             else
80             {
81                 // Validates we throw on unsupported hardware
82                 test.RunUnsupportedScenario();
83             }
84
85             if (!test.Succeeded)
86             {
87                 throw new Exception("One or more scenarios did not complete as expected.");
88             }
89         }
90     }
91
92     public sealed unsafe class SimpleUnaryOpTest__RoundCurrentDirectionDouble
93     {
94         private struct TestStruct
95         {
96             public Vector128<Double> _fld;
97
98             public static TestStruct Create()
99             {
100                 var testStruct = new TestStruct();
101                 var random = new Random();
102
103                 for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
104                 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
105
106                 return testStruct;
107             }
108
109             public void RunStructFldScenario(SimpleUnaryOpTest__RoundCurrentDirectionDouble testClass)
110             {
111                 var result = Sse41.RoundCurrentDirection(_fld);
112
113                 Unsafe.Write(testClass._dataTable.outArrayPtr, result);
114                 testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
115             }
116         }
117
118         private static readonly int LargestVectorSize = 16;
119
120         private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
121         private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
122
123         private static Double[] _data = new Double[Op1ElementCount];
124
125         private static Vector128<Double> _clsVar;
126
127         private Vector128<Double> _fld;
128
129         private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
130
131         static SimpleUnaryOpTest__RoundCurrentDirectionDouble()
132         {
133             var random = new Random();
134
135             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
136             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
137         }
138
139         public SimpleUnaryOpTest__RoundCurrentDirectionDouble()
140         {
141             Succeeded = true;
142
143             var random = new Random();
144
145             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
146             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
147
148             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
149             _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
150         }
151
152         public bool IsSupported => Sse41.IsSupported;
153
154         public bool Succeeded { get; set; }
155
156         public void RunBasicScenario_UnsafeRead()
157         {
158             var result = Sse41.RoundCurrentDirection(
159                 Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
160             );
161
162             Unsafe.Write(_dataTable.outArrayPtr, result);
163             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
164         }
165
166         public void RunBasicScenario_Load()
167         {
168             var result = Sse41.RoundCurrentDirection(
169                 Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
170             );
171
172             Unsafe.Write(_dataTable.outArrayPtr, result);
173             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
174         }
175
176         public void RunBasicScenario_LoadAligned()
177         {
178             var result = Sse41.RoundCurrentDirection(
179                 Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
180             );
181
182             Unsafe.Write(_dataTable.outArrayPtr, result);
183             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
184         }
185
186         public void RunReflectionScenario_UnsafeRead()
187         {
188             var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Double>) })
189                                      .Invoke(null, new object[] {
190                                         Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
191                                      });
192
193             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
194             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
195         }
196
197         public void RunReflectionScenario_Load()
198         {
199             var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Double>) })
200                                      .Invoke(null, new object[] {
201                                         Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
202                                      });
203
204             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
205             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
206         }
207
208         public void RunReflectionScenario_LoadAligned()
209         {
210             var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Double>) })
211                                      .Invoke(null, new object[] {
212                                         Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
213                                      });
214
215             Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
216             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
217         }
218
219         public void RunClsVarScenario()
220         {
221             var result = Sse41.RoundCurrentDirection(
222                 _clsVar
223             );
224
225             Unsafe.Write(_dataTable.outArrayPtr, result);
226             ValidateResult(_clsVar, _dataTable.outArrayPtr);
227         }
228
229         public void RunLclVarScenario_UnsafeRead()
230         {
231             var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
232             var result = Sse41.RoundCurrentDirection(firstOp);
233
234             Unsafe.Write(_dataTable.outArrayPtr, result);
235             ValidateResult(firstOp, _dataTable.outArrayPtr);
236         }
237
238         public void RunLclVarScenario_Load()
239         {
240             var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
241             var result = Sse41.RoundCurrentDirection(firstOp);
242
243             Unsafe.Write(_dataTable.outArrayPtr, result);
244             ValidateResult(firstOp, _dataTable.outArrayPtr);
245         }
246
247         public void RunLclVarScenario_LoadAligned()
248         {
249             var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
250             var result = Sse41.RoundCurrentDirection(firstOp);
251
252             Unsafe.Write(_dataTable.outArrayPtr, result);
253             ValidateResult(firstOp, _dataTable.outArrayPtr);
254         }
255
256         public void RunClassLclFldScenario()
257         {
258             var test = new SimpleUnaryOpTest__RoundCurrentDirectionDouble();
259             var result = Sse41.RoundCurrentDirection(test._fld);
260
261             Unsafe.Write(_dataTable.outArrayPtr, result);
262             ValidateResult(test._fld, _dataTable.outArrayPtr);
263         }
264
265         public void RunClassFldScenario()
266         {
267             var result = Sse41.RoundCurrentDirection(_fld);
268
269             Unsafe.Write(_dataTable.outArrayPtr, result);
270             ValidateResult(_fld, _dataTable.outArrayPtr);
271         }
272
273         public void RunStructLclFldScenario()
274         {
275             var test = TestStruct.Create();
276             var result = Sse41.RoundCurrentDirection(test._fld);
277
278             Unsafe.Write(_dataTable.outArrayPtr, result);
279             ValidateResult(test._fld, _dataTable.outArrayPtr);
280         }
281
282         public void RunStructFldScenario()
283         {
284             var test = TestStruct.Create();
285             test.RunStructFldScenario(this);
286         }
287
288         public void RunUnsupportedScenario()
289         {
290             Succeeded = false;
291
292             try
293             {
294                 RunBasicScenario_UnsafeRead();
295             }
296             catch (PlatformNotSupportedException)
297             {
298                 Succeeded = true;
299             }
300         }
301
302         private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
303         {
304             Double[] inArray = new Double[Op1ElementCount];
305             Double[] outArray = new Double[RetElementCount];
306
307             Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
308             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
309
310             ValidateResult(inArray, outArray, method);
311         }
312
313         private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
314         {
315             Double[] inArray = new Double[Op1ElementCount];
316             Double[] outArray = new Double[RetElementCount];
317
318             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
319             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
320
321             ValidateResult(inArray, outArray, method);
322         }
323
324         private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
325         {
326             if (BitConverter.DoubleToInt64Bits(result[0]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[0])))
327             {
328                 Succeeded = false;
329             }
330             else
331             {
332                 for (var i = 1; i < RetElementCount; i++)
333                 {
334                     if (BitConverter.DoubleToInt64Bits(result[i]) != BitConverter.DoubleToInt64Bits(Math.Round(firstOp[i])))
335                     {
336                         Succeeded = false;
337                         break;
338                     }
339                 }
340             }
341
342             if (!Succeeded)
343             {
344                 Console.WriteLine($"{nameof(Sse41)}.{nameof(Sse41.RoundCurrentDirection)}<Double>(Vector128<Double>): {method} failed:");
345                 Console.WriteLine($"  firstOp: ({string.Join(", ", firstOp)})");
346                 Console.WriteLine($"   result: ({string.Join(", ", result)})");
347                 Console.WriteLine();
348             }
349         }
350     }
351 }