8e01ecd58b7b32d6577b7deecf3d8b9e2e88d72a
[platform/upstream/coreclr.git] / tests / src / JIT / HardwareIntrinsics / X86 / Avx / Permute.Single.1.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 PermuteSingle1()
23         {
24             var test = new ImmUnaryOpTest__PermuteSingle1();
25
26             if (test.IsSupported)
27             {
28                 // Validates basic functionality works, using Unsafe.Read
29                 test.RunBasicScenario_UnsafeRead();
30
31                 if (Avx.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 (Avx.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 (Avx.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 ImmUnaryOpTest__PermuteSingle1
93     {
94         private struct TestStruct
95         {
96             public Vector256<Single> _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] = (float)(random.NextDouble()); }
104                 Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
105
106                 return testStruct;
107             }
108
109             public void RunStructFldScenario(ImmUnaryOpTest__PermuteSingle1 testClass)
110             {
111                 var result = Avx.Permute(_fld, 1);
112
113                 Unsafe.Write(testClass._dataTable.outArrayPtr, result);
114                 testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
115             }
116         }
117
118         private static readonly int LargestVectorSize = 32;
119
120         private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
121         private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
122
123         private static Single[] _data = new Single[Op1ElementCount];
124
125         private static Vector256<Single> _clsVar;
126
127         private Vector256<Single> _fld;
128
129         private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
130
131         static ImmUnaryOpTest__PermuteSingle1()
132         {
133             var random = new Random();
134
135             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
136             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
137         }
138
139         public ImmUnaryOpTest__PermuteSingle1()
140         {
141             Succeeded = true;
142
143             var random = new Random();
144
145             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
146             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
147
148             for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (float)(random.NextDouble()); }
149             _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
150         }
151
152         public bool IsSupported => Avx.IsSupported;
153
154         public bool Succeeded { get; set; }
155
156         public void RunBasicScenario_UnsafeRead()
157         {
158             var result = Avx.Permute(
159                 Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
160                 1
161             );
162
163             Unsafe.Write(_dataTable.outArrayPtr, result);
164             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
165         }
166
167         public void RunBasicScenario_Load()
168         {
169             var result = Avx.Permute(
170                 Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
171                 1
172             );
173
174             Unsafe.Write(_dataTable.outArrayPtr, result);
175             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
176         }
177
178         public void RunBasicScenario_LoadAligned()
179         {
180             var result = Avx.Permute(
181                 Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
182                 1
183             );
184
185             Unsafe.Write(_dataTable.outArrayPtr, result);
186             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
187         }
188
189         public void RunReflectionScenario_UnsafeRead()
190         {
191             var result = typeof(Avx).GetMethod(nameof(Avx.Permute), new Type[] { typeof(Vector256<Single>), typeof(byte) })
192                                      .Invoke(null, new object[] {
193                                         Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr),
194                                         (byte)1
195                                      });
196
197             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
198             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
199         }
200
201         public void RunReflectionScenario_Load()
202         {
203             var result = typeof(Avx).GetMethod(nameof(Avx.Permute), new Type[] { typeof(Vector256<Single>), typeof(byte) })
204                                      .Invoke(null, new object[] {
205                                         Avx.LoadVector256((Single*)(_dataTable.inArrayPtr)),
206                                         (byte)1
207                                      });
208
209             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
210             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
211         }
212
213         public void RunReflectionScenario_LoadAligned()
214         {
215             var result = typeof(Avx).GetMethod(nameof(Avx.Permute), new Type[] { typeof(Vector256<Single>), typeof(byte) })
216                                      .Invoke(null, new object[] {
217                                         Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr)),
218                                         (byte)1
219                                      });
220
221             Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
222             ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
223         }
224
225         public void RunClsVarScenario()
226         {
227             var result = Avx.Permute(
228                 _clsVar,
229                 1
230             );
231
232             Unsafe.Write(_dataTable.outArrayPtr, result);
233             ValidateResult(_clsVar, _dataTable.outArrayPtr);
234         }
235
236         public void RunLclVarScenario_UnsafeRead()
237         {
238             var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
239             var result = Avx.Permute(firstOp, 1);
240
241             Unsafe.Write(_dataTable.outArrayPtr, result);
242             ValidateResult(firstOp, _dataTable.outArrayPtr);
243         }
244
245         public void RunLclVarScenario_Load()
246         {
247             var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
248             var result = Avx.Permute(firstOp, 1);
249
250             Unsafe.Write(_dataTable.outArrayPtr, result);
251             ValidateResult(firstOp, _dataTable.outArrayPtr);
252         }
253
254         public void RunLclVarScenario_LoadAligned()
255         {
256             var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
257             var result = Avx.Permute(firstOp, 1);
258
259             Unsafe.Write(_dataTable.outArrayPtr, result);
260             ValidateResult(firstOp, _dataTable.outArrayPtr);
261         }
262
263         public void RunClassLclFldScenario()
264         {
265             var test = new ImmUnaryOpTest__PermuteSingle1();
266             var result = Avx.Permute(test._fld, 1);
267
268             Unsafe.Write(_dataTable.outArrayPtr, result);
269             ValidateResult(test._fld, _dataTable.outArrayPtr);
270         }
271
272         public void RunClassFldScenario()
273         {
274             var result = Avx.Permute(_fld, 1);
275
276             Unsafe.Write(_dataTable.outArrayPtr, result);
277             ValidateResult(_fld, _dataTable.outArrayPtr);
278         }
279
280         public void RunStructLclFldScenario()
281         {
282             var test = TestStruct.Create();
283             var result = Avx.Permute(test._fld, 1);
284
285             Unsafe.Write(_dataTable.outArrayPtr, result);
286             ValidateResult(test._fld, _dataTable.outArrayPtr);
287         }
288
289         public void RunStructFldScenario()
290         {
291             var test = TestStruct.Create();
292             test.RunStructFldScenario(this);
293         }
294
295         public void RunUnsupportedScenario()
296         {
297             Succeeded = false;
298
299             try
300             {
301                 RunBasicScenario_UnsafeRead();
302             }
303             catch (PlatformNotSupportedException)
304             {
305                 Succeeded = true;
306             }
307         }
308
309         private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
310         {
311             Single[] inArray = new Single[Op1ElementCount];
312             Single[] outArray = new Single[RetElementCount];
313
314             Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
315             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
316
317             ValidateResult(inArray, outArray, method);
318         }
319
320         private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
321         {
322             Single[] inArray = new Single[Op1ElementCount];
323             Single[] outArray = new Single[RetElementCount];
324
325             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
326             Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
327
328             ValidateResult(inArray, outArray, method);
329         }
330
331         private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
332         {
333             if (BitConverter.SingleToInt32Bits(result[0]) != BitConverter.SingleToInt32Bits(firstOp[1]))
334             {
335                 Succeeded = false;
336             }
337             else
338             {
339                 for (var i = 1; i < RetElementCount; i++)
340                 {
341                     if (BitConverter.SingleToInt32Bits(result[4]) != BitConverter.SingleToInt32Bits(firstOp[5]))
342                     {
343                         Succeeded = false;
344                         break;
345                     }
346                 }
347             }
348
349             if (!Succeeded)
350             {
351                 Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Permute)}<Single>(Vector256<Single><9>): {method} failed:");
352                 Console.WriteLine($"  firstOp: ({string.Join(", ", firstOp)})");
353                 Console.WriteLine($"   result: ({string.Join(", ", result)})");
354                 Console.WriteLine();
355             }
356         }
357     }
358 }