~ubuntu-branches/ubuntu/trusty/atlas/trusty

« back to all changes in this revision

Viewing changes to tune/blas/ger/s1nxtune.c

  • Committer: Package Import Robot
  • Author(s): Sébastien Villemot
  • Date: 2013-07-27 14:26:05 UTC
  • mfrom: (18.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20130727142605-5rh3p972h1whdo99
Tags: 3.10.1-2
* Allow the generic package to build on machines with CPU throttling
  enabled. Otherwise the package FTBFS on some buildds (e.g. biber).
  Implementation is done by reactivating the "-Si cputhrchk 0" flag
  (cpu-throtthling-check.diff), and using it in debian/rules.
* Add architectural defaults for armel and mips.
* armhf.diff: do not enforce 32-registers FPU for Fortran

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *             Automatically Tuned Linear Algebra Software v3.10.1
 
3
 * Copyright (C) 2010 R. Clint Whaley
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *   1. Redistributions of source code must retain the above copyright
 
9
 *      notice, this list of conditions and the following disclaimer.
 
10
 *   2. Redistributions in binary form must reproduce the above copyright
 
11
 *      notice, this list of conditions, and the following disclaimer in the
 
12
 *      documentation and/or other materials provided with the distribution.
 
13
 *   3. The name of the ATLAS group or the names of its contributers may
 
14
 *      not be used to endorse or promote products derived from this
 
15
 *      software without specific written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
18
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 
19
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS
 
21
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
27
 * POSSIBILITY OF SUCH DAMAGE.
 
28
 *
 
29
 */
 
30
 
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include <assert.h>
 
34
#include "atlas_misc.h"
 
35
#include "atlas_tst.h"
 
36
#include "atlas_lvl2.h"
 
37
#include "atlas_level1.h"
 
38
#include "atlas_genparse.h"
 
39
#include "atlas_gentesttime.h"
 
40
int ATL_KERN_NX=16;
 
41
 
 
42
#if defined(__MINGW32__) || defined(__MINGW64__)
 
43
 
 
44
int slashdrivesub(char *ln)
 
45
/*
 
46
 * replaces \\c\ with c:\, returns change in string length
 
47
 * this version required for older cygwins
 
48
 */
 
49
{
 
50
   char *sp, *lp=ln, ctmp;
 
51
   int nrep=0;
 
52
   do
 
53
   {
 
54
      sp = strstr(lp, "\\\\");
 
55
      if (sp && strlen(sp) > 3)
 
56
      {
 
57
         if (sp[2] == 'a' || sp[2] == 'b' || sp[2] == 'c' || sp[2] == 'd' ||
 
58
             sp[2] == 'e' || sp[2] == 'f' || sp[2] == 'g' || sp[2] == 'h')
 
59
         {
 
60
            if (sp[3] == '\\')
 
61
            {
 
62
               ctmp = sp[2];
 
63
               sp[0] = sp[2];
 
64
               sp[1] = ':';
 
65
               sp[2] = '\\';
 
66
               for (lp=sp+3; *lp = lp[1]; lp++);
 
67
               lp = sp + 3;
 
68
               nrep++;
 
69
            }
 
70
            else lp = sp + 2;
 
71
         }
 
72
         else lp = sp + 2;
 
73
      }
 
74
      else lp = sp + 2;
 
75
   }
 
76
   while (sp);
 
77
   return(-nrep);
 
78
}
 
79
 
 
80
int cygdrivesub(char *ln)
 
81
/*
 
82
 * replaces \cygdrive\c\ with c:\, returns change in string length
 
83
 * this version works cygnus version 1.1.0
 
84
 */
 
85
{
 
86
   char *sp;
 
87
   int i=0;
 
88
 
 
89
   while(sp = strstr(ln, "\\cygdrive\\"))
 
90
   {
 
91
      i++;
 
92
      sp[0] = sp[10];
 
93
      sp[1] = ':';
 
94
      sp[2] = '\\';
 
95
      sp += 3;
 
96
      while (*sp = sp[9]) sp++;
 
97
   }
 
98
   return( slashdrivesub(ln) - (i*9) );
 
99
}
 
100
 
 
101
void slashsub(char *ln)
 
102
/*
 
103
 * changes forward slash of unix to backslash of windoze
 
104
 */
 
105
{
 
106
   int i;
 
107
   for (i=0; ln[i]; i++) if (ln[i] == '/') ln[i] = '\\';
 
108
}
 
109
 
 
110
#endif
 
111
 
 
112
static double GetTime
 
113
(
 
114
   enum ATLAS_UPLO Uplo,/* which triangle? */
 
115
   int verb,            /* verbosity */
 
116
   int nreps,           /* number of reps to do for one timing sample */
 
117
   size_t flushelts,    /* size of area to flush to avoid cache reuse */
 
118
   ATL_CINT N,          /* matrix size */
 
119
   int NX               /* what to set ref/kernel crossover to */
 
120
)
 
121
{
 
122
   size_t setsz, nsets, accsz, Nt;
 
123
   double t0, t1;
 
124
   void *vp;
 
125
   TYPE *tp, *x, *y, *a;
 
126
   #ifdef TCPLX
 
127
      const TYPE one[2] = {ATL_rone, ATL_rzero};
 
128
   #else
 
129
      const TYPE one = ATL_rone;
 
130
   #endif
 
131
   int i, j;
 
132
 
 
133
   ATL_KERN_NX = NX;
 
134
   accsz = 1*N + ((size_t)N)*(N>>1);
 
135
   setsz = 1*N + ((size_t)N)*N;
 
136
   nsets = (flushelts + accsz-1)/accsz;
 
137
   nsets = (nsets) ? nsets : 1;
 
138
   Nt = nsets * setsz;
 
139
   tp = vp = malloc(ATL_MulBySize(Nt));
 
140
   assert(vp);
 
141
   Mjoin(PATL,gegen)(Nt, 1, tp, Nt, N+127*37);
 
142
   t0 = time00();
 
143
   for (j=0, i=nreps; i; i--)
 
144
   {
 
145
      x = tp + j*setsz;
 
146
      a = x + N;
 
147
   #ifdef TCPLX
 
148
      Mjoin(PATL,her)(Uplo, N, ATL_rone, x, 1, a, N);
 
149
   #else
 
150
      Mjoin(PATL,syr)(Uplo, N, ATL_rone, x, 1, a, N);
 
151
   #endif
 
152
      if (++j == nsets)
 
153
         j = 0;
 
154
   }
 
155
   t1 = time00();
 
156
   t1 = (t1 - t0) / nreps;
 
157
   free(vp);
 
158
   return(t1);
 
159
}
 
160
static double GetTimes
 
161
(
 
162
   enum ATLAS_UPLO Uplo,/* which triangle? */
 
163
   int verb,            /* verbosity */
 
164
   int nsample,         /* number of samples to take */
 
165
   int nreps,           /* number of reps to do for one timing sample */
 
166
   size_t flushelts,    /* size of area to flush to avoid cache reuse */
 
167
   ATL_CINT N,          /* matrix size */
 
168
   int NX               /* what to set ref/kernel crossover to */
 
169
)
 
170
{
 
171
   int i;
 
172
   double *times, t0;
 
173
 
 
174
   times = malloc(nsample*sizeof(double));
 
175
   assert(times);
 
176
   for (i=0; i < nsample; i++)
 
177
   {
 
178
      times[i] = GetTime(Uplo, verb, nreps, flushelts, N, NX);
 
179
      if (verb > 1)
 
180
         printf("      %d: %e\n", i, times[i]);
 
181
   }
 
182
   SortDoubles(nsample, times);
 
183
   #ifdef WALL
 
184
      t0 = times[0];
 
185
   #else
 
186
      i = (nsample > 1) ? (nsample>>1)+1 : 0;
 
187
      t0 = times[i];
 
188
   #endif
 
189
   free(times);
 
190
   if (verb > 1)
 
191
      printf("      RETURNING TIME: %e\n", t0);
 
192
   return(t0);
 
193
}
 
194
 
 
195
#define NX0 16
 
196
int RecDoubleNX
 
197
(
 
198
   enum ATLAS_UPLO Uplo,/* which triangle? */
 
199
   int verb,            /* verbosity */
 
200
   int nsample,         /* number of samples to take */
 
201
   int nreps,           /* number of reps to do for one timing sample */
 
202
   size_t flushelts,    /* size of area to flush to avoid cache reuse */
 
203
   ATL_CINT N           /* matrix size */
 
204
)
 
205
{
 
206
   double t0, tL, tN;  /* 0, Last, Next */
 
207
   double tB, tE, tM;  /* beginning, end, middle timings */
 
208
   ATL_INT n0, nL, nN;
 
209
   ATL_INT nB, nE, nM;
 
210
 
 
211
   t0 = GetTimes(Uplo, verb, nsample, nreps, flushelts, N, N);
 
212
   printf("\n   Time for N=NX=%d : %e\n", N, t0);
 
213
   printf("     N    NX    %% of N=%2d\n", NX0);
 
214
   printf("======  ====  ===========\n");
 
215
/*
 
216
 * Now halve NX until performance stops increasing
 
217
 */
 
218
   tL = t0;
 
219
   nL = N;
 
220
   do
 
221
   {
 
222
      nN = (nL>>4)<<3;
 
223
      tN = GetTimes(Uplo, verb, nsample, nreps, flushelts, N, nN);
 
224
      printf("%6d  %4d  %11.2f\n", N, nN, (tN/t0)*100.0);
 
225
      if (tN > tL) break;  /* stop if new time longer than last */
 
226
      nL = nN;
 
227
      tL = tN;
 
228
   }
 
229
   while (nN);  /* stop if NX = 0 */
 
230
   printf("\n");
 
231
 
 
232
   tE = tL;
 
233
   nE = nL;
 
234
   tB = tN;
 
235
   nB = nN;
 
236
   while (nE - nB > 8)
 
237
   {
 
238
      nM = nB + ((nE-nB)>>1);
 
239
      nM = (nM>>3) << 3;   /* keep mul of 8 for alignment, etc */
 
240
      tM = GetTimes(Uplo, verb, nsample, nreps, flushelts, N, nM);
 
241
      printf("%6d  %4d  %11.2f\n", N, nM, (tM/t0)*100.0);
 
242
      if (tE >= tB)
 
243
      {
 
244
         tE = tM;
 
245
         nE = nM;
 
246
      }
 
247
      else
 
248
      {
 
249
         tB = tM;
 
250
         nB = nM;
 
251
      }
 
252
   }
 
253
   if (tE < tB && tE < tM)
 
254
   {
 
255
      tM = tE;
 
256
      nM = nE;
 
257
   }
 
258
   else if (tB < tE && tB < tM)
 
259
   {
 
260
      tM = tB;
 
261
      nM = nB;
 
262
   }
 
263
   printf("NX selected as %d (%.2f%%)!\n", nM, (tM/t0)*100.0);
 
264
   return(nM);
 
265
}
 
266
 
 
267
void PrintUsage(char *name, int ierr, char *flag)
 
268
{
 
269
   if (ierr > 0)
 
270
      fprintf(stderr, "Bad argument #%d: '%s'\n",
 
271
              ierr, flag ? flag : "Not enough arguments");
 
272
   else if (ierr < 0)
 
273
      fprintf(stderr, "ERROR: %s\n", flag);
 
274
 
 
275
   fprintf(stderr, "USAGE: %s [flags]:\n", name);
 
276
   fprintf(stderr, "   -U <u/l>\n");
 
277
   fprintf(stderr, "   -n <N>\n");
 
278
   fprintf(stderr, "   -r <reps>\n");
 
279
   fprintf(stderr, "   -s <nsample>\n");
 
280
   fprintf(stderr, "   -v <verb>\n");
 
281
   fprintf(stderr, "   -C <flushKB>\n");
 
282
   fprintf(stderr, "   -o <outfile>\n");
 
283
   exit(ierr ? ierr : -1);
 
284
}
 
285
 
 
286
int GetFlags(int nargs, char **args, enum ATLAS_UPLO *Uplo, int *verb,
 
287
             int *nsample, int *nreps, size_t *flushelts, char **outfile)
 
288
{
 
289
   int N=2000, i;
 
290
   char ch;
 
291
   char *of;
 
292
 
 
293
   *flushelts = L2SIZE;
 
294
   *nsample = 10;
 
295
   *nreps = 1;
 
296
   *verb = 1;
 
297
   *Uplo = AtlasUpper;
 
298
   of = NULL;
 
299
   for (i=1; i < nargs; i++)
 
300
   {
 
301
      if (args[i][0] != '-')
 
302
         PrintUsage(args[0], i, "No '-' preceeding flag!");
 
303
      switch(args[i][1])
 
304
      {
 
305
      case 's' :
 
306
         if (++i >= nargs)
 
307
            PrintUsage(args[0], i-1, "out of flags in -s ");
 
308
         *nsample = atoi(args[i]);
 
309
         break;
 
310
      case 'v' :
 
311
         if (++i >= nargs)
 
312
            PrintUsage(args[0], i-1, "out of flags in -v ");
 
313
         *verb = atoi(args[i]);
 
314
         break;
 
315
      case 'r' :
 
316
         if (++i >= nargs)
 
317
            PrintUsage(args[0], i-1, "out of flags in -r ");
 
318
         *nreps = atoi(args[i]);
 
319
         break;
 
320
      case 'n' :
 
321
         if (++i >= nargs)
 
322
            PrintUsage(args[0], i-1, "out of flags in -n ");
 
323
         N = atoi(args[i]);
 
324
         break;
 
325
      case 'U':
 
326
         if (++i >= nargs)
 
327
            PrintUsage(args[0], i-1, "out of flags in -C) ");
 
328
         ch = args[i][0];
 
329
         *Uplo = (ch == 'l' || ch == 'L') ? AtlasLower : AtlasUpper;
 
330
         break;
 
331
      case 'C' :
 
332
         if (++i >= nargs)
 
333
            PrintUsage(args[0], i-1, "out of flags in -C) ");
 
334
         *flushelts = atoll(args[i])*1024;
 
335
         break;
 
336
      case 'o' :
 
337
         if (++i >= nargs)
 
338
            PrintUsage(args[0], i-1, "out of flags in -C) ");
 
339
         of = args[i];
 
340
         break;
 
341
      default:
 
342
         PrintUsage(args[0], i, args[i]);
 
343
      }
 
344
   }
 
345
   if (of)
 
346
   {
 
347
      *outfile = DupString(of);
 
348
      #if defined(__MINGW32__) || defined(__MINGW64__)
 
349
         slashsub(*outfile);
 
350
         cygdrivesub(*outfile);
 
351
      #endif
 
352
   }
 
353
   else
 
354
   {
 
355
      of = malloc(sizeof(char)*32);
 
356
      assert(of);
 
357
      #if defined(__MINGW32__) || defined(__MINGW64__)
 
358
         sprintf(of, "res\atlas_%ssyrNX.h", Mstr(PRE));
 
359
      #else
 
360
         sprintf(of, "res/atlas_%ssyrNX.h", Mstr(PRE));
 
361
      #endif
 
362
      *outfile = of;
 
363
   }
 
364
   return(N);
 
365
}
 
366
 
 
367
void GenIncFile(char *outfile, int NX)
 
368
{
 
369
   FILE *fpout;
 
370
   fpout = fopen(outfile, "w");
 
371
   assert(fpout);
 
372
   fprintf(fpout, "#ifndef ATLAS_%sSYR_H\n   #define ATLAS_%sSYR_H\n",
 
373
           Mstr(PREU), Mstr(PREU));
 
374
   fprintf(fpout, "   #define ATL_S1NX %d\n#endif\n", NX);
 
375
   fclose(fpout);
 
376
}
 
377
 
 
378
int main(int nargs, char **args)
 
379
{
 
380
   size_t flushelts;
 
381
   char *outfile;
 
382
   int N, verb, nsample, nreps, NX;
 
383
   enum ATLAS_UPLO Uplo;
 
384
 
 
385
   N = GetFlags(nargs, args, &Uplo, &verb, &nsample, &nreps, &flushelts,
 
386
                &outfile);
 
387
   NX = RecDoubleNX(Uplo, verb, nsample, nreps, flushelts, N);
 
388
   GenIncFile(outfile, NX);
 
389
   free(outfile);
 
390
   printf("\nNX=%d!\n", NX);
 
391
   return(0);
 
392
}