Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Benchmarking/sources/HeuristicLab.Algorithms.Benchmarks/3.3/Linpack.cs @ 6934

Last change on this file since 6934 was 6934, checked in by ascheibe, 13 years ago

on behalf of spimming:
#1659

  • implemented abstract base class for benchmarking algorithms
  • added License information
  • corrected plugin dependencies
  • corrected descriptions
File size: 11.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Diagnostics;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Optimization;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Algorithms.Benchmarks {
31  [Item("Linpack Algorithm", "Linpack benchmarking algorithm.")]
32  [Creatable("Benchmarks")]
33  [StorableClass]
34  public class Linpack : Benchmark {
35
36    #region Benchmark Fields
37
38    private const int DEFAULT_PSIZE = 1500;
39
40    private double eps_result = 0.0;
41    private double mflops_result = 0.0;
42    private double residn_result = 0.0;
43    private double time_result = 0.0;
44    private double total = 0.0;
45
46    private Stopwatch sw = new Stopwatch();
47
48    #endregion
49
50    #region Costructors
51
52    public Linpack()
53      : base() {
54    }
55
56    private Linpack(Linpack original, Cloner cloner)
57      : base(original, cloner) {
58    }
59
60    #endregion
61
62    #region IDeepClonable Members
63
64    public override IDeepCloneable Clone(Cloner cloner) {
65      return new Linpack(this, cloner);
66    }
67
68    #endregion
69
70    #region Linpack Benchmark
71    // implementation based on Java version: http://www.netlib.org/benchmark/linpackjava/
72
73    protected override void RunBenchmark() {
74      int n = DEFAULT_PSIZE;
75      int ldaa = DEFAULT_PSIZE;
76      int lda = DEFAULT_PSIZE + 1;
77
78      double[][] a = new double[ldaa][];
79      double[] b = new double[ldaa];
80      double[] x = new double[ldaa];
81
82      double ops;
83      double norma;
84      double normx;
85      double resid;
86      int i;
87      int info;
88      int[] ipvt = new int[ldaa];
89
90      for (i = 0; i < ldaa; i++) {
91        a[i] = new double[lda];
92      }
93
94      ops = (2.0e0 * (((double)n) * n * n)) / 3.0 + 2.0 * (n * n);
95
96      norma = mathGen(a, lda, n, b);
97
98      sw.Reset();
99      sw.Start();
100
101      info = dgefa(a, lda, n, ipvt);
102
103      dgesl(a, lda, n, ipvt, b, 0);
104
105      sw.Stop();
106      total = sw.Elapsed.TotalMilliseconds / 1000;
107
108      for (i = 0; i < n; i++) {
109        x[i] = b[i];
110      }
111
112      norma = mathGen(a, lda, n, b);
113
114      for (i = 0; i < n; i++) {
115        b[i] = -b[i];
116      }
117
118      dmxpy(n, b, n, lda, x, a);
119
120      resid = 0.0;
121      normx = 0.0;
122
123      for (i = 0; i < n; i++) {
124        resid = (resid > abs(b[i])) ? resid : abs(b[i]);
125        normx = (normx > abs(x[i])) ? normx : abs(x[i]);
126      }
127
128      eps_result = epslon((double)1.0);
129
130      residn_result = resid / (n * norma * normx * eps_result);
131      residn_result += 0.005; // for rounding
132      residn_result = (int)(residn_result * 100);
133      residn_result /= 100;
134
135      time_result = total;
136      time_result += 0.005; // for rounding
137      time_result = (int)(time_result * 100);
138      time_result /= 100;
139
140      mflops_result = ops / (1.0e6 * total);
141      mflops_result += 0.0005; // for rounding
142      mflops_result = (int)(mflops_result * 1000);
143      mflops_result /= 1000;
144
145      Results.Add(new Result("Mflops/s", new DoubleValue(mflops_result)));
146      Results.Add(new Result("total Mflops/s", new DoubleValue(mflops_result * Environment.ProcessorCount)));
147    }
148
149    private double abs(double d) {
150      return (d >= 0) ? d : -d;
151    }
152
153    private double mathGen(double[][] a, int lda, int n, double[] b) {
154      Random gen;
155      double norma;
156      int init, i, j;
157
158      init = 1325;
159      norma = 0.0;
160
161      gen = new Random(init);
162
163      // Next two for() statements switched.  Solver wants
164      // matrix in column order. --dmd 3/3/97
165
166      for (i = 0; i < n; i++) {
167        for (j = 0; j < n; j++) {
168          a[j][i] = gen.NextDouble() - .5;
169          norma = (a[j][i] > norma) ? a[j][i] : norma;
170        }
171      }
172
173      for (i = 0; i < n; i++) {
174        b[i] = 0.0;
175      }
176
177      for (j = 0; j < n; j++) {
178        for (i = 0; i < n; i++) {
179          b[i] += a[j][i];
180        }
181      }
182
183      return norma;
184    }
185
186    private int dgefa(double[][] a, int lda, int n, int[] ipvt) {
187      double[] col_k, col_j;
188      double t;
189      int j, k, kp1, l, nm1;
190      int info;
191
192      // gaussian elimination with partial pivoting
193
194      info = 0;
195      nm1 = n - 1;
196      if (nm1 >= 0) {
197        for (k = 0; k < nm1; k++) {
198          col_k = a[k];
199          kp1 = k + 1;
200
201          // find l = pivot index
202
203          l = idamax(n - k, col_k, k, 1) + k;
204          ipvt[k] = l;
205
206          // zero pivot implies this column already triangularized
207
208          if (col_k[l] != 0) {
209            // interchange if necessary
210
211            if (l != k) {
212              t = col_k[l];
213              col_k[l] = col_k[k];
214              col_k[k] = t;
215            }
216
217            // compute multipliers
218
219            t = -1.0 / col_k[k];
220            dscal(n - (kp1), t, col_k, kp1, 1);
221
222            // row elimination with column indexing
223
224            for (j = kp1; j < n; j++) {
225              col_j = a[j];
226              t = col_j[l];
227              if (l != k) {
228                col_j[l] = col_j[k];
229                col_j[k] = t;
230              }
231              daxpy(n - (kp1), t, col_k, kp1, 1,
232                col_j, kp1, 1);
233            }
234          } else {
235            info = k;
236          }
237        }
238      }
239
240      ipvt[n - 1] = n - 1;
241      if (a[(n - 1)][(n - 1)] == 0) info = n - 1;
242
243      return info;
244    }
245
246    private void dgesl(double[][] a, int lda, int n, int[] ipvt, double[] b, int job) {
247      double t;
248      int k, kb, l, nm1, kp1;
249
250      nm1 = n - 1;
251      if (job == 0) {
252        // job = 0 , solve  a * x = b.  first solve  l*y = b
253
254        if (nm1 >= 1) {
255          for (k = 0; k < nm1; k++) {
256            l = ipvt[k];
257            t = b[l];
258            if (l != k) {
259              b[l] = b[k];
260              b[k] = t;
261            }
262            kp1 = k + 1;
263            daxpy(n - (kp1), t, a[k], kp1, 1, b, kp1, 1);
264          }
265        }
266
267        // now solve  u*x = y
268
269        for (kb = 0; kb < n; kb++) {
270          k = n - (kb + 1);
271          b[k] /= a[k][k];
272          t = -b[k];
273          daxpy(k, t, a[k], 0, 1, b, 0, 1);
274        }
275      } else {
276        // job = nonzero, solve  trans(a) * x = b.  first solve  trans(u)*y = b
277
278        for (k = 0; k < n; k++) {
279          t = ddot(k, a[k], 0, 1, b, 0, 1);
280          b[k] = (b[k] - t) / a[k][k];
281        }
282
283        // now solve trans(l)*x = y
284
285        if (nm1 >= 1) {
286          //for (kb = 1; kb < nm1; kb++) {
287          for (kb = 0; kb < nm1; kb++) {
288            k = n - (kb + 1);
289            kp1 = k + 1;
290            b[k] += ddot(n - (kp1), a[k], kp1, 1, b, kp1, 1);
291            l = ipvt[k];
292            if (l != k) {
293              t = b[l];
294              b[l] = b[k];
295              b[k] = t;
296            }
297          }
298        }
299      }
300    }
301
302    private void daxpy(int n, double da, double[] dx, int dx_off, int incx, double[] dy, int dy_off, int incy) {
303      int i, ix, iy;
304
305      if ((n > 0) && (da != 0)) {
306        if (incx != 1 || incy != 1) {
307
308          // code for unequal increments or equal increments not equal to 1
309
310          ix = 0;
311          iy = 0;
312          if (incx < 0) ix = (-n + 1) * incx;
313          if (incy < 0) iy = (-n + 1) * incy;
314          for (i = 0; i < n; i++) {
315            dy[iy + dy_off] += da * dx[ix + dx_off];
316            ix += incx;
317            iy += incy;
318          }
319          return;
320        } else {
321          // code for both increments equal to 1
322
323          for (i = 0; i < n; i++)
324            dy[i + dy_off] += da * dx[i + dx_off];
325        }
326      }
327    }
328
329    private double ddot(int n, double[] dx, int dx_off, int incx, double[] dy, int dy_off, int incy) {
330      double dtemp = 0;
331      int i, ix, iy;
332
333      if (n > 0) {
334        if (incx != 1 || incy != 1) {
335          // code for unequal increments or equal increments not equal to 1
336
337          ix = 0;
338          iy = 0;
339          if (incx < 0) ix = (-n + 1) * incx;
340          if (incy < 0) iy = (-n + 1) * incy;
341          for (i = 0; i < n; i++) {
342            dtemp += dx[ix + dx_off] * dy[iy + dy_off];
343            ix += incx;
344            iy += incy;
345          }
346        } else {
347          // code for both increments equal to 1
348
349          for (i = 0; i < n; i++)
350            dtemp += dx[i + dx_off] * dy[i + dy_off];
351        }
352      }
353      return (dtemp);
354    }
355
356    private void dscal(int n, double da, double[] dx, int dx_off, int incx) {
357      int i, nincx;
358
359      if (n > 0) {
360        if (incx != 1) {
361          // code for increment not equal to 1
362
363          nincx = n * incx;
364          for (i = 0; i < nincx; i += incx)
365            dx[i + dx_off] *= da;
366        } else {
367          // code for increment equal to 1
368
369          for (i = 0; i < n; i++)
370            dx[i + dx_off] *= da;
371        }
372      }
373    }
374
375    private int idamax(int n, double[] dx, int dx_off, int incx) {
376      double dmax, dtemp;
377      int i, ix, itemp = 0;
378
379      if (n < 1) {
380        itemp = -1;
381      } else if (n == 1) {
382        itemp = 0;
383      } else if (incx != 1) {
384        // code for increment not equal to 1
385
386        dmax = (dx[dx_off] < 0.0) ? -dx[dx_off] : dx[dx_off];
387        ix = 1 + incx;
388        for (i = 0; i < n; i++) {
389          dtemp = (dx[ix + dx_off] < 0.0) ? -dx[ix + dx_off] : dx[ix + dx_off];
390          if (dtemp > dmax) {
391            itemp = i;
392            dmax = dtemp;
393          }
394          ix += incx;
395        }
396      } else {
397        // code for increment equal to 1
398
399        itemp = 0;
400        dmax = (dx[dx_off] < 0.0) ? -dx[dx_off] : dx[dx_off];
401        for (i = 0; i < n; i++) {
402          dtemp = (dx[i + dx_off] < 0.0) ? -dx[i + dx_off] : dx[i + dx_off];
403          if (dtemp > dmax) {
404            itemp = i;
405            dmax = dtemp;
406          }
407        }
408      }
409      return (itemp);
410    }
411
412    private double epslon(double x) {
413      double a, b, c, eps;
414
415      a = 4.0e0 / 3.0e0;
416      eps = 0;
417      while (eps == 0) {
418        b = a - 1.0;
419        c = b + b + b;
420        eps = abs(c - 1.0);
421      }
422      return (eps * abs(x));
423    }
424
425    private void dmxpy(int n1, double[] y, int n2, int ldm, double[] x, double[][] m) {
426      int j, i;
427
428      // cleanup odd vector
429      for (j = 0; j < n2; j++) {
430        for (i = 0; i < n1; i++) {
431          y[i] += x[j] * m[j][i];
432        }
433      }
434    }
435
436    #endregion
437  }
438}
Note: See TracBrowser for help on using the repository browser.