~ubuntu-branches/ubuntu/vivid/atlas/vivid

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Sébastien Villemot
  • Date: 2013-06-11 15:58:16 UTC
  • mfrom: (1.1.3 upstream)
  • mto: (2.2.21 experimental)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: package-import@ubuntu.com-20130611155816-b72z8f621tuhbzn0
Tags: upstream-3.10.1
Import upstream version 3.10.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *             Automatically Tuned Linear Algebra Software v3.8.4
3
 
 *                    (C) Copyright 1999 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 "atlas_misc.h"
32
 
#include "atlas_lvl2.h"
33
 
#include "atlas_fopen.h"
34
 
 
35
 
int FAx=0, MAx=0, FAy=0, MAy=0, FAa=0, MAa=0;
36
 
#include <stdio.h>
37
 
#include <stdlib.h>
38
 
#include <assert.h>
39
 
 
40
 
struct FA_allocs
41
 
{
42
 
   void *mem, *memA;
43
 
   struct FA_allocs *next;
44
 
} *allocQ=NULL;
45
 
 
46
 
struct FA_allocs *NewAlloc(size_t size, struct FA_allocs *next,
47
 
                           int align, int misalign)
48
 
/*
49
 
 * Allocates size allocation that is aligned to [align], but not aligned
50
 
 * to [misalign].  Therefore, misalign > align.  Align must minimally be sizeof
51
 
 * while misalign may be 0 if we don't need to avoid a particular alignment.
52
 
 */
53
 
{
54
 
   void *vp;
55
 
   char *cp;
56
 
   struct FA_allocs *ap;
57
 
   int n, i;
58
 
   const int malign = align >= misalign ? align : misalign;
59
 
 
60
 
   n = size + align + malign;
61
 
   i = (n >> 3)<<3;
62
 
   if (n != i)
63
 
      n += n - i;
64
 
   cp = malloc(n + sizeof(struct FA_allocs));
65
 
   assert(cp);
66
 
   ap = (struct FA_allocs *) (cp + n);
67
 
   ap->mem = cp;
68
 
/*
69
 
 * Align to min alignment
70
 
 */
71
 
   ap->memA = align ? (void*) ((((size_t) cp)/align)*align + align) : cp;
72
 
/*
73
 
 * Misalign to misalign
74
 
 */
75
 
   if (misalign)
76
 
   {
77
 
      if (((size_t)ap->memA)%misalign == 0)
78
 
         ap->memA = ((char*)ap->memA) + align;
79
 
   }
80
 
   ap->next = next;
81
 
   return(ap);
82
 
}
83
 
 
84
 
/*
85
 
 * no-align malloc free retaining system default behavior
86
 
 */
87
 
void *NA_malloc(size_t size)
88
 
{
89
 
   return(malloc(size));
90
 
}
91
 
void *NA_calloc(size_t n, size_t size)
92
 
{
93
 
   return(calloc(n, size));
94
 
}
95
 
void NA_free(void *ptr)
96
 
{
97
 
   free(ptr);
98
 
}
99
 
 
100
 
 
101
 
/*
102
 
 * malloc/free pair that aligns data to align, but not to misalign
103
 
 */
104
 
void *FA_malloc(size_t size, int align, int misalign)
105
 
{
106
 
   if ((!misalign && align <= 8) || !size)
107
 
      return(malloc(size));
108
 
   else
109
 
   {
110
 
      allocQ = NewAlloc(size, allocQ, align, misalign);
111
 
      return(allocQ->memA);
112
 
   }
113
 
}
114
 
void *FA_calloc(size_t n, size_t size, int align, int misalign)
115
 
{
116
 
   char *cp;
117
 
   int *ip;
118
 
   double *dp;
119
 
   size_t i;
120
 
   size_t tsize;
121
 
   tsize = n * size;
122
 
   cp = FA_malloc(tsize, align, misalign);
123
 
   if (size == sizeof(int))
124
 
      for (ip=(int*)cp,i=0; i < n; i++)
125
 
        ip[i] = 0;
126
 
   else if (size == sizeof(double))
127
 
      for (dp=(double*)cp,i=0; i < n; i++)
128
 
        dp[i] = 0.0;
129
 
   else
130
 
      for (i=0; i < tsize; i++)
131
 
        cp[i] = 0;
132
 
   return(cp);
133
 
}
134
 
 
135
 
void FA_free(void *ptr, int align, int misalign)
136
 
/*
137
 
 * Part of malloc/free pair that aligns data to FALIGN
138
 
 */
139
 
{
140
 
   struct FA_allocs *ap, *prev;
141
 
   if (ptr)
142
 
   {
143
 
      if ((!misalign && align <= 8))
144
 
         free(ptr);
145
 
      else
146
 
      {
147
 
         for (ap=allocQ; ap && ap->memA != ptr; ap = ap->next) prev = ap;
148
 
         if (!ap)
149
 
         {
150
 
            fprintf(stderr, "Couldn't find mem=%ld\nmemQ=\n", ptr);
151
 
            for (ap=allocQ; ap; ap = ap->next)
152
 
               fprintf(stderr, "   %ld, %ld\n", ap->memA, ap->mem);
153
 
         }
154
 
         assert(ap);
155
 
         if (ap == allocQ)
156
 
            allocQ = allocQ->next;
157
 
         else
158
 
            prev->next = ap->next;
159
 
         free(ap->mem);
160
 
      }
161
 
   }
162
 
}
163
 
 
164
 
#define ATL_NoBlock(iflag_) ( ((iflag_) | 32) == (iflag_) )
165
 
 
166
 
double time00();
167
 
#ifdef TREAL
168
 
   #define test_ger(M, N, alpha, X, incX, Y, incY, A, lda) \
169
 
      Mjoin(PATL,ger)(M, N, alpha, X, incX, Y, incY, A, lda)
170
 
#else
171
 
   #define test_ger(M, N, alpha, X, incX, Y, incY, A, lda) \
172
 
      Mjoin(PATL,geru)(M, N, alpha, X, incX, Y, incY, A, lda)
173
 
#endif
174
 
 
175
 
double gercase(const int MFLOP, const int M, const int N, const SCALAR alpha,
176
 
               const int lda)
177
 
{
178
 
   unsigned long reps;
179
 
   const int aincX = 1, aincY = 1;
180
 
   const int incX = 1, incY = 1;
181
 
   int i, lx, ly, la;
182
 
   #ifdef TREAL
183
 
      const double flops = 2.0 * M * N;
184
 
   #else
185
 
      const double flops = 8.0 * M * N;
186
 
   #endif
187
 
   double ttest, mftest, t0;
188
 
   const int inca = lda*N SHIFT, incx = M*incX SHIFT, incy = N*incY SHIFT;
189
 
   TYPE *a, *A, *stA, *A0, *x, *X, *X0, *stX, *y, *Y, *Y0, *stY;
190
 
   #ifdef TREAL
191
 
      const TYPE nalpha = -alpha;
192
 
      TYPE alp = alpha;
193
 
   #else
194
 
      const TYPE *alp = alpha;
195
 
      TYPE nalpha[2];
196
 
   #endif
197
 
   #ifdef TCPLX
198
 
      nalpha[0] = -alpha[0]; nalpha[1] = alpha[1];
199
 
   #endif
200
 
 
201
 
   i = (ATL_DivBySize(L2SIZE)+M-1)/M;
202
 
   lx = i * M * aincX;
203
 
   X0 = X = x = FA_malloc(ATL_MulBySize(lx), FAx, MAx);
204
 
   if (x == NULL) return(-1);
205
 
 
206
 
   i = (ATL_DivBySize(L2SIZE)+N-1)/N;
207
 
   ly = i * N * aincY;
208
 
   Y0 = Y = y = FA_malloc(ATL_MulBySize(ly), FAy, MAy);
209
 
   if (y == NULL)
210
 
   {
211
 
      FA_free(x, FAx, MAx);
212
 
      return(-1);
213
 
   }
214
 
   i = (ATL_DivBySize(L2SIZE)+M*N)/(M*N);
215
 
   la = i * lda*N;
216
 
   A0 = A = a = FA_malloc(ATL_MulBySize(la), FAa, MAa);
217
 
   if (a == NULL)
218
 
   {
219
 
      FA_free(x, FAy, MAy);
220
 
      FA_free(y, FAy, MAy);
221
 
      return(-1);
222
 
   }
223
 
   if (incX < 1)
224
 
   {
225
 
      stX = x;
226
 
      x = X = x + (lx SHIFT);
227
 
   }
228
 
   else stX = x + (lx SHIFT);
229
 
   if (incY < 1)
230
 
   {
231
 
      stY = y;
232
 
      y = Y = y + (ly SHIFT);
233
 
   }
234
 
   else stY = y + (ly SHIFT);
235
 
   stA = a + (la SHIFT);
236
 
 
237
 
   reps = (MFLOP * 1000000.0) / flops;
238
 
   if (reps < 1) reps = 1;
239
 
   Mjoin(PATL,gegen)(ly, 1, Y0, ly, M*incY);
240
 
   Mjoin(PATL,gegen)(lx, 1, X0, lx, N*incY+127*50+77);
241
 
   Mjoin(PATL,gegen)(la, 1, A0, la, N*M+513*7+90);
242
 
 
243
 
   t0 = time00();
244
 
   for (i=reps; i; i--)
245
 
   {
246
 
      test_ger(M, N, alp, x, incX, y, incY, A0, lda);
247
 
      x += incx;
248
 
      y += incy;
249
 
      a += inca;
250
 
      if (x == stX) x = X;
251
 
      if (y == stY) y = Y;
252
 
      if (a == stA)
253
 
      {
254
 
         a = A;
255
 
         if (alp == alpha) alp = nalpha;
256
 
         else alp = alpha;
257
 
      }
258
 
   }
259
 
   ttest = time00() - t0;
260
 
 
261
 
   if (ttest > 0.0) mftest = (reps * flops) / (1000000.0 * ttest);
262
 
   else mftest = 0.0;
263
 
 
264
 
   FA_free(A0, FAa, MAa);
265
 
   FA_free(X0, FAx, MAx);
266
 
   FA_free(Y0, FAy, MAy);
267
 
   return(mftest);
268
 
}
269
 
 
270
 
void PrintUsage(char *nam)
271
 
{
272
 
   fprintf(stderr, "USAGE: %s -C <case #> -l <l1mul> -F <mflop> -m <M> -n <N> -f <iflag> -a <alpha> -o <outfile>\n\n", nam);
273
 
   exit(-1);
274
 
}
275
 
 
276
 
void GetFlags(int nargs, char **args, char *pre, int *MFLOP,
277
 
              int *M, int *N, TYPE *alpha, int *lda, char *outnam)
278
 
{
279
 
   int l1mul;
280
 
   int i, k, cas, iflag=0;
281
 
   char ch;
282
 
 
283
 
   l1mul = 75;
284
 
   outnam[0] = '\0';
285
 
   #if defined(DREAL)
286
 
      *pre = 'd';
287
 
   #elif defined(SREAL)
288
 
      *pre = 's';
289
 
   #elif defined(SCPLX)
290
 
      *pre = 'c';
291
 
   #elif defined(DCPLX)
292
 
      *pre = 'z';
293
 
   #endif
294
 
   #ifdef ATL_nkflop
295
 
      *MFLOP = (ATL_nkflop) / 2000.0;
296
 
      if (*MFLOP < 1) *MFLOP = 1;
297
 
   #else
298
 
      *MFLOP = 75;
299
 
   #endif
300
 
   *lda = *M = *N = 1000;
301
 
   *alpha = ATL_rone;
302
 
   #ifdef TCPLX
303
 
      alpha[1] = ATL_rzero;
304
 
   #endif
305
 
   cas = 1;
306
 
   for (i=1; i < nargs; i++)
307
 
   {
308
 
      if (args[i][0] != '-') PrintUsage(args[0]);
309
 
      switch(args[i][1])
310
 
      {
311
 
      case 'C': /* case */
312
 
         cas = atoi(args[++i]);
313
 
         break;
314
 
      case 'F': /* mflops */
315
 
         ch = args[i][2];
316
 
         k = atoi(args[++i]);
317
 
         if (ch == 'a')
318
 
         {
319
 
            if (k < 0)
320
 
              MAa = -k;
321
 
            else
322
 
              FAa = k;
323
 
         }
324
 
         else if (ch == 'y')
325
 
         {
326
 
            if (k < 0)
327
 
              MAy = -k;
328
 
            else
329
 
              FAy = k;
330
 
         }
331
 
         else if (ch == 'x')
332
 
         {
333
 
            if (k < 0)
334
 
              MAx = -k;
335
 
            else
336
 
              FAx = k;
337
 
         }
338
 
         else *MFLOP = k;
339
 
         break;
340
 
      case 'f': /* iflag */
341
 
         iflag = atoi(args[++i]);
342
 
         break;
343
 
      case 'm':
344
 
         *M = atoi(args[++i]);
345
 
         break;
346
 
      case 'n':
347
 
         *N = atoi(args[++i]);
348
 
         break;
349
 
      case 'l':
350
 
         l1mul = atoi(args[++i]);
351
 
         break;
352
 
      case 'a':
353
 
         *alpha = atof(args[++i]);
354
 
         #ifdef TCPLX
355
 
            alpha[1] = atof(args[++i]);
356
 
         #endif
357
 
         break;
358
 
      case 'o':
359
 
         strcpy(outnam, args[++i]);
360
 
         break;
361
 
      default:
362
 
         PrintUsage(args[0]);
363
 
      }
364
 
   }
365
 
   if (outnam[0] == '\0')
366
 
   {
367
 
      if (ATL_NoBlock(iflag))
368
 
         sprintf(outnam, "res/%cger1_%d_0", *pre, cas);
369
 
      else sprintf(outnam, "res/%cger1_%d_%d", *pre, cas, l1mul);
370
 
   }
371
 
}
372
 
 
373
 
main(int nargs, char **args)
374
 
{
375
 
   char pre, fnam[128];
376
 
   int MFLOP, M, N, lda, cas, i;
377
 
   double mf, mfs[3];
378
 
   #ifdef TREAL
379
 
      TYPE alpha;
380
 
   #else
381
 
      TYPE alpha[2];
382
 
   #endif
383
 
   FILE *fp;
384
 
 
385
 
   GetFlags(nargs, args, &pre, &MFLOP, &M, &N, SADD alpha, &lda, fnam);
386
 
 
387
 
   if (!FileExists(fnam))
388
 
   {
389
 
      fp = fopen(fnam, "w");
390
 
      ATL_assert(fp);
391
 
      for (i=0; i < 3; i++)
392
 
      {
393
 
         mf = gercase(MFLOP, M, N, alpha, lda);
394
 
         fprintf(stdout, "      %s : %f MFLOPS\n", fnam, mf);
395
 
         fprintf(fp, "%lf\n", mf);
396
 
         mfs[i] = mf;
397
 
      }
398
 
   }
399
 
   else
400
 
   {
401
 
      fp = fopen(fnam, "r");
402
 
      for (i=0; i < 3; i++) ATL_assert(fscanf(fp, " %lf", &mfs[i]) == 1);
403
 
   }
404
 
   fclose(fp);
405
 
   mf = (mfs[0] + mfs[1] + mfs[2]) / 3.0;
406
 
   fprintf(stdout, "   %s : %.2f MFLOPS\n", fnam, mf);
407
 
   exit(0);
408
 
}