Update CoreClr, PgoData to preview1-26004-01, master-20171204-0047, respectively...
[platform/upstream/coreclr.git] / tests / src / JIT / Performance / CodeQuality / BenchF / Adams / Adams.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 // The Adams-Moulton Predictor Corrector Method adapted from Conte and de Boor
6 // original source: adams_d.c
7
8 using System;
9 using System.Runtime.CompilerServices;
10 using System.Diagnostics;
11 #if XUNIT_PERF
12 using Xunit;
13 using Microsoft.Xunit.Performance;
14 #endif // XUNIT_PERF
15
16 #if XUNIT_PERF
17 [assembly: OptimizeForBenchmarks]
18 #endif // XUNIT_PERF
19
20 namespace Benchstone.BenchF
21 {
22 public static class Adams
23 {
24 #if DEBUG
25     public static int Iterations = 1;
26 #else
27     public static int Iterations = 200000;
28 #endif // DEBUG
29
30     static double g_xn, g_yn, g_dn, g_en;
31     const double g_xn_base = 0.09999999E+01;
32     const double g_yn_base = 0.71828180E+00;
33     const double g_dn_base = 0.21287372E-08;
34     const double g_en_base = 0.74505806E-08;
35
36     [MethodImpl(MethodImplOptions.NoInlining)]
37     private static void Bench()
38     {
39         double[] f = new double[5];
40         double xn, yn, dn, en, yxn, h, fnp, ynp, y0, x0, nz;
41         int i, k, n, nstep;
42
43 #if VERBOSE
44         Console.WriteLine(" ADAMS-MOULTON METHOD ");
45 #endif // VERBOSE
46
47         n = 4;
48         h = 1.0 / 32.0;
49         nstep = 32;
50         y0 = 0.0;
51         x0 = 0.0;
52         xn = 0.0;
53         yn = 0.0;
54         dn = 0.0;
55         en = 0.0;
56         nz = 0;
57
58         f[1] = x0 + y0;
59 #if VERBOSE
60         Console.WriteLine("{0},  {1},  {2},  {3},  {4}", nz, x0, y0, dn, en);
61 #endif // VERBOSE
62         xn = x0;
63         for (i = 2; i <= 4; i++)
64         {
65             k = i - 1;
66             xn = xn + h;
67             yn = Soln(xn);
68             f[i] = xn + yn;
69 #if VERBOSE
70             Console.WriteLine("{0},  {1},  {2},  {3},  {4}", k, xn, yn, dn, en);
71 #endif // VERBOSE
72         }
73
74         for (k = 4; k <= nstep; k++)
75         {
76             ynp = yn + (h / 24) * (55 * f[n] - 59 * f[n - 1] + 37 * f[n - 2] - 9 * f[n - 3]);
77             xn = xn + h;
78             fnp = xn + ynp;
79             yn = yn + (h / 24) * (9 * fnp + 19 * f[n] - 5 * f[n - 1] + f[n - 2]);
80             dn = (yn - ynp) / 14;
81             f[n - 3] = f[n - 2];
82             f[n - 2] = f[n - 1];
83             f[n - 1] = f[n];
84             f[n] = xn + yn;
85             yxn = Soln(xn);
86             en = yn - yxn;
87 #if VERBOSE
88             Console.WriteLine("{0},  {1},  {2},  {3},  {4}", k, xn, yn, dn, en);
89 #endif // VERBOSE
90         }
91
92         // Escape calculated values:
93         g_xn = xn;
94         g_yn = yn;
95         g_dn = dn;
96         g_en = en;
97     }
98
99     private static double Soln(double x)
100     {
101         return (System.Math.Exp(x) - 1.0 - (x));
102     }
103
104     [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
105     private static void TestBench()
106     {
107         for (int l = 1; l <= Iterations; l++)
108         {
109             Bench();
110         }
111     }
112
113 #if XUNIT_PERF
114     [Benchmark]
115     public static void Test()
116     {
117         foreach (var iteration in Benchmark.Iterations)
118         {
119             using (iteration.StartMeasurement())
120             {
121                 TestBench();
122             }
123         }
124     }
125 #endif // XUNIT_PERF
126
127     [MethodImpl(MethodImplOptions.NoOptimization)]
128     public static int Main(string[] argv)
129     {
130         if (argv.Length > 0)
131         {
132             Iterations = Int32.Parse(argv[0]);
133         }
134
135         Stopwatch sw = Stopwatch.StartNew();
136         TestBench();
137         sw.Stop();
138
139         bool result = true;
140         // Note: we can't check xn or yn better because of the precision
141         // with which original results are given
142         result &= System.Math.Abs(g_xn_base - g_xn) <= 1.5e-7;
143         result &= System.Math.Abs(g_yn_base - g_yn) <= 1.5e-7;
144         result &= System.Math.Abs(g_dn) <= 2.5e-9;
145         // Actual error is much bigger than base error;
146         // this is likely due to the fact that the original program was written in Fortran
147         // and was running on a mainframe with a non-IEEE floating point arithmetic
148         // (it's still beyond the published precision of yn)
149         result &= System.Math.Abs(g_en) <= 5.5e-8;
150         Console.WriteLine(result ? "Passed" : "Failed");
151
152         Console.WriteLine(" BASE.....P1 1/4 (ADAMS-MOULTON), XN = {0}", g_xn_base);
153         Console.WriteLine(" VERIFY...P1 1/4 (ADAMS-MOULTON), XN = {0}\n", g_xn);
154         Console.WriteLine(" BASE.....P1 2/4 (ADAMS-MOULTON), YN = {0}", g_yn_base);
155         Console.WriteLine(" VERIFY...P1 2/4 (ADAMS-MOULTON), YN = {0}\n", g_yn);
156         Console.WriteLine(" BASE.....P1 3/4 (ADAMS-MOULTON), DN = {0}", g_dn_base);
157         Console.WriteLine(" VERIFY...P1 3/4 (ADAMS-MOULTON), DN = {0}\n", g_dn);
158         Console.WriteLine(" BASE.....P1 4/4 (ADAMS-MOULTON), EN = {0}", g_en_base);
159         Console.WriteLine(" VERIFY...P1 4/4 (ADAMS-MOULTON), EN = {0}\n", g_en);
160
161         Console.WriteLine("Test iterations: {0}; Total time: {1} sec", Iterations, sw.Elapsed.TotalSeconds);
162         return (result ? 100 : -1);
163     }
164 }
165 }