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

« back to all changes in this revision

Viewing changes to include/atlas_mvtesttime.h

  • 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
#ifndef ATLAS_MVTESTTIME_H
 
2
   #define ATLAS_MVTESTTIME_H
 
3
 
 
4
#include "atlas_mvparse.h"
 
5
#include "atlas_gentesttime.h"
 
6
 
 
7
static int SprintAlignStr
 
8
(
 
9
   char pre,            /* precision modifier */
 
10
   ATL_mvnode_t *kp, /* kernel pointer */
 
11
   char *str            /* (OUTPUT) string to print to */
 
12
)
 
13
/*
 
14
 * Prints alignment string to str, based on alignment setting.
 
15
 * This routine assumes to force the alignment to sizeof(TYPE) unless
 
16
 * restrictions are enabled.
 
17
 * RETURNS: number of chars added to str
 
18
 */
 
19
{
 
20
   const int size = (pre == 'd' || pre == 's') ? pre2size(pre)
 
21
                                                 : (pre2size(pre)>>1);
 
22
   int alignA, alignX, alignY, i;
 
23
 
 
24
   alignA = (kp->alignA) ? kp->alignA : size;
 
25
   alignX = (kp->alignX) ? kp->alignX : size;
 
26
   alignY = (kp->alignY) ? kp->alignY : size;
 
27
/*
 
28
 * If we are doing an AXPY-based No-Trans GEMV, it is Y, not X that must
 
29
 * be aligned to A.  Therefore, alignX/ALIGNX2A actually refer to Y, and
 
30
 * alignY refers to X.  Do this confusing transpose for the non-trans case.
 
31
 */
 
32
   if (kp->TA == AtlasNoTrans) /* ALIGNX* affects Y for No-Trans */
 
33
   {
 
34
      i = alignX;
 
35
      alignX = alignY;
 
36
      alignY = i;
 
37
      if (FLAG_IS_SET(kp->flag, MVF_ALIGNX2A))
 
38
         alignY = alignA; /* ALIGNX2A overrides alignY */
 
39
   }
 
40
   else if (FLAG_IS_SET(kp->flag, MVF_ALIGNX2A))
 
41
      alignX = alignA;
 
42
/*
 
43
 * If ALIGNX2A, we must force to vectors to have the same remainder when
 
44
 * divided by the vector length.  We do this by insisting they have the
 
45
 * the same modulo by ATL_Cachelen, which by definition is always a
 
46
 * multiple of the vector length (eg, veclen=16/32 (SSE/AVX), ATL_cl=32).
 
47
 */
 
48
   if (FLAG_IS_SET(kp->flag, MVF_ALIGNX2A))
 
49
   {
 
50
      int myalign = ATL_Cachelen - size;
 
51
      if (alignA)
 
52
      {
 
53
         myalign = ((ATL_Cachelen-size)/alignA)*alignA;
 
54
         if (!myalign)
 
55
            myalign = alignA;
 
56
      }
 
57
      if (kp->TA == AtlasNoTrans) /* ALIGNX* affects Y for No-Trans */
 
58
      {
 
59
         if (myalign < ATL_Cachelen)
 
60
            i = sprintf(str, " align=\"-Fa %d -Fa -%d -Fy %d -Fy -%d",
 
61
                        myalign, ATL_Cachelen, myalign, ATL_Cachelen);
 
62
         else
 
63
            i = sprintf(str, " align=\"-Fa %d -Fy %d", myalign, myalign);
 
64
         if (2*alignX <= ATL_Cachelen)
 
65
            i += sprintf(str+i, " -Fx %d -Fx -%d\"", alignX, 2*alignX);
 
66
         else
 
67
            i += sprintf(str+i, " -Fx %d\"", alignX);
 
68
      }
 
69
      else
 
70
      {
 
71
         if (myalign < ATL_Cachelen)
 
72
            i = sprintf(str, " align=\"-Fa %d -Fa -%d -Fx %d -Fx -%d",
 
73
                        myalign, ATL_Cachelen, myalign, ATL_Cachelen);
 
74
         else
 
75
            i = sprintf(str, " align=\"-Fa %d -Fx %d", myalign, myalign);
 
76
 
 
77
         if (2*alignY <= ATL_Cachelen)
 
78
            i += sprintf(str+i, " -Fy %d -Fy -%d\"", alignY, 2*alignY);
 
79
         else
 
80
            i += sprintf(str+i, " -Fy %d\"", alignY);
 
81
      }
 
82
   }
 
83
   else
 
84
   {
 
85
      if (2*alignA <= ATL_Cachelen)
 
86
         i = sprintf(str, " align=\"-Fa %d -Fa -%d", alignA, 2*alignA);
 
87
      else
 
88
         i = sprintf(str, " align=\"-Fa %d ", alignA);
 
89
      if (2*alignX <= ATL_Cachelen)
 
90
         i += sprintf(str+i, " -Fx %d -Fx -%d", alignX, 2*alignX);
 
91
      else
 
92
         i += sprintf(str+i, " -Fx %d", alignX);
 
93
      if (2*alignY <= ATL_Cachelen)
 
94
         i += sprintf(str+i, " -Fy %d -Fy -%d\"", alignY, 2*alignY);
 
95
      else
 
96
         i += sprintf(str+i, " -Fy %d\"", alignY);
 
97
   }
 
98
   return(i);
 
99
}
 
100
 
 
101
/* procedure 1 */
 
102
static int MVKernelFailsTest
 
103
   (int verb, char pre, ATL_INT M, ATL_INT N, ATL_INT lda, ATL_mvnode_t *kn)
 
104
{
 
105
   char ln[4096];
 
106
   char *sp;
 
107
   int i, lda0;
 
108
   static char outnam[L_tmpnam];
 
109
   static int FirstTime=1;
 
110
 
 
111
   if (FirstTime)
 
112
   {
 
113
 
 
114
      FirstTime = 0;
 
115
      assert(tmpnam(outnam));
 
116
   }
 
117
/*
 
118
 * If the file is generated, call generator to create it
 
119
 */
 
120
   if (kn->genstr)
 
121
   {
 
122
      i = sprintf(ln, "%s", kn->genstr);
 
123
      if (verb < 3)
 
124
         i += sprintf(ln+i, " > %s 2>&1\n", outnam);
 
125
      if (system(ln))
 
126
      {
 
127
         fprintf(stderr, "ERROR, LINE %d of %s\n", __LINE__, __FILE__);
 
128
         fprintf(stderr, "UNABLE TO GENERATE WITH COMMAND: %s\n", kn->genstr);
 
129
         if (verb < 3)
 
130
         {
 
131
            fprintf(stderr, "\nOUTPUT OF system():\n");
 
132
            sprintf(ln, "cat %s 1>&2\n", outnam);
 
133
            i = system(ln);
 
134
         }
 
135
         remove(outnam);
 
136
         exit(-1);
 
137
      }
 
138
   }
 
139
   assert(kn->rout);
 
140
   assert (M >= kn->minM);
 
141
   assert (N >= kn->minN);
 
142
   sp = (kn->TA == AtlasNoTrans) ? "mvn" : "mvt";
 
143
   if (kn->TA == AtlasNoTrans)
 
144
      i = sprintf(ln, "make %cmvnktest mvnrout=%s", pre, kn->rout);
 
145
   else
 
146
      i = sprintf(ln, "make %cmvtktest mvtrout=%s", pre, kn->rout);
 
147
   i += SprintAlignStr(pre, kn, ln+i);
 
148
   if (FLAG_IS_SET(kn->flag, MVF_FNU))
 
149
       i += sprintf(ln+i, " Nt=%d ", (1008/kn->NU)*kn->NU);
 
150
   if (kn->exflags)
 
151
      i += sprintf(ln+i, " %s", kn->exflags);
 
152
   if (1)   /* NOTE: replace with test on restrict or not! */
 
153
      i += sprintf(ln+i, " incy=1");
 
154
   if (kn->comp)
 
155
      i += sprintf(ln+i, " %cMVCC=\"%s\"", pre, kn->comp);
 
156
   if (kn->cflags)
 
157
      i += sprintf(ln+i, " %cMVFLAGS=\"%s\"", pre, kn->cflags);
 
158
   i += sprintf(ln+i, " Mt=%d Nt=%d ldat=%d", M, N, lda);
 
159
   if (verb < 3)
 
160
      i += sprintf(ln+i, " > %s 2>&1\n", outnam);
 
161
   else
 
162
      i += sprintf(ln+i, "\n");
 
163
   if (verb > 1)
 
164
      fprintf(stdout, "system call:%s\n", ln);
 
165
   i = system(ln);
 
166
   if (verb)
 
167
   {
 
168
      if (i)
 
169
      {
 
170
         fprintf(stderr, "\n%s(ID=%d) FAILS TESTER!!\n", kn->rout,kn->ID);
 
171
         fprintf(stderr, "FAILING CALL: '%s'\n", ln);
 
172
         if (verb < 3 && verb > 0)
 
173
         {
 
174
            int itmp;
 
175
            fprintf(stderr, "\nOUTPUT OF system():\n");
 
176
            sprintf(ln, "cat %s 1>&2\n", outnam);
 
177
            itmp = system(ln);
 
178
         }
 
179
      }
 
180
      else
 
181
         fprintf(stderr, "%s(ID=%d) *PASSES* TESTER!!\n", kn->rout,kn->ID);
 
182
   }
 
183
   if (verb < 3)
 
184
      remove(outnam);
 
185
   return(i);
 
186
}
 
187
 
 
188
 
 
189
/* procedure 2 */
 
190
static char *GetResIdStr(ATL_mvnode_t *r1p, ATL_INT M, ATL_INT N,
 
191
                         ATL_INT lda, ATL_INT percL1, int mflop)
 
192
{
 
193
/*
 
194
 * Return filename suffix that disambiguates most kernels:
 
195
 * <ID><TA>_<M>x<N>_<lda>-<ldamul>_<MU>x<NU>_<percL1>_a<alignA>x<aX>x<aY>_<flag>
 
196
 */
 
197
   static char ln[512];
 
198
   sprintf(ln, "%d%c_%dx%d_%d-%d_%dx%d_%d_a%dx%dx%d_%d", r1p->ID,
 
199
           (r1p->TA == AtlasNoTrans) ? 'N' : 'T', M, N, lda, r1p->ldamul,
 
200
            r1p->MU, r1p->NU, percL1, r1p->alignA, r1p->alignX, r1p->alignY,
 
201
            r1p->flag);
 
202
   return(ln);
 
203
}
 
204
 
 
205
/* procedure 3 */
 
206
static double TimeMVKernel
 
207
(int verb,              /* 0: no output, 1 min ouput, 2: full output */
 
208
 int FORCETIME,         /* if nonzero, ignore existing timing file */
 
209
                        /* if negative, don't retain timing file */
 
210
 ATL_mvnode_t *r1p,     /* ptr to kernel structure */
 
211
 char pre,              /* precision prefix */
 
212
 ATL_INT M, ATL_INT N,  /* dimensions to time */
 
213
 ATL_INT lda,           /* stride between row elements */
 
214
 ATL_INT percL1,        /* if 0, time kernel directly wt no blocking */
 
215
                        /* if non-zero, block for that % of L1 cache size */
 
216
 int nrep,              /* if >=1, # of trials, else use default (3) */
 
217
 int mflop,             /* force mflop flops in each timing interval */
 
218
 int cflush             /* if >= 0, size of cache flush area, else ignored */
 
219
)
 
220
{
 
221
   char ln[2048], resf[256], *sp;
 
222
   double *dp, mf;
 
223
   int i, align = pre2size(pre);
 
224
   static char outnam[L_tmpnam];
 
225
   static int FirstTime=1;
 
226
 
 
227
   if (FirstTime)
 
228
   {
 
229
 
 
230
      FirstTime = 0;
 
231
      assert(tmpnam(outnam));
 
232
   }
 
233
/*
 
234
 * If the file is generated, call generator to create it
 
235
 */
 
236
   if (r1p->genstr)
 
237
   {
 
238
      i = sprintf(ln, "%s", r1p->genstr);
 
239
      if (verb < 3)
 
240
         i += sprintf(ln+i, " > %s 2>&1\n", outnam);
 
241
      if (system(ln))
 
242
      {
 
243
         fprintf(stderr, "ERROR, LINE %d of %s\n", __LINE__, __FILE__);
 
244
         fprintf(stderr, "UNABLE TO GENERATE WITH COMMAND: %s\n", r1p->genstr);
 
245
         if (verb < 3)
 
246
         {
 
247
            int itmp;
 
248
            fprintf(stderr, "\nOUTPUT OF system():\n");
 
249
            sprintf(ln, "cat %s 1>&2\n", outnam);
 
250
            itmp = system(ln);
 
251
         }
 
252
         exit(-1);
 
253
      }
 
254
   }
 
255
 
 
256
   if (r1p->minN)
 
257
      N = Mmax(N, r1p->minN);
 
258
   if (r1p->minM)
 
259
   {
 
260
      M = Mmax(M, r1p->minM);
 
261
      if (lda < M)
 
262
         lda = M;
 
263
   }
 
264
   if (FLAG_IS_SET(r1p->flag, MVF_FNU))
 
265
      N = Mmax(r1p->NU, (N/r1p->NU)*r1p->NU);
 
266
   i = r1p->ldamul / pre2size(pre);
 
267
   lda = (i) ? ((lda+i-1)/i)*i : lda;
 
268
 
 
269
   if (FORCETIME < 0)
 
270
      sprintf(resf, "res/%cmvtmp", pre);
 
271
   else
 
272
      sprintf(resf, "res/%cmv%s", pre,
 
273
              GetResIdStr(r1p, M, N, lda, percL1, mflop));
 
274
   if (FORCETIME)
 
275
      remove(resf);
 
276
   dp = FORCETIME ? NULL : ReadResultsFile(0, nrep, resf);
 
277
   if (dp)
 
278
   {
 
279
      if (verb > 0)
 
280
         fprintf(stdout, "   %d:%s (M=%d, N=%d, lda=%d) gets %.2f MFLOPS\n",
 
281
                 r1p->ID, r1p->rout, M, N, lda, *dp);
 
282
      return(*dp);
 
283
   }
 
284
 
 
285
   sp = (r1p->TA == AtlasNoTrans || r1p->TA == AtlasConj) ? "mvn" : "mvt";
 
286
   if (percL1)
 
287
      i = sprintf(ln, "make %c%stime M=%d N=%d lda=%d l1mul=%d %srout=\"%s\"",
 
288
                  pre, sp, M, N, lda, percL1, sp, r1p->rout);
 
289
   else
 
290
      i = sprintf(ln, "make %c%sktime M=%d N=%d lda=%d %srout=\"%s\"",
 
291
                  pre, sp, M, N, lda, sp, r1p->rout);
 
292
   if (r1p->flag)
 
293
      i += sprintf(ln+i, " iflag=%d", r1p->flag);
 
294
   if (r1p->exflags)
 
295
      i += sprintf(ln+i, " %s", r1p->exflags);
 
296
   if (r1p->comp)
 
297
      i += sprintf(ln+i, " %cMVCC=\"%s\"", pre, r1p->comp);
 
298
   if (r1p->cflags)
 
299
      i += sprintf(ln+i, " %cMVFLAGS=\"%s\"", pre, r1p->cflags);
 
300
   i += SprintAlignStr(pre, r1p, ln+i);
 
301
   if (cflush >=0)
 
302
      i += sprintf(ln+i, " flushKB=%d", cflush);
 
303
   i += sprintf(ln+i, " tflags=\"-f %s", resf);
 
304
   if (nrep > 0)
 
305
      i += sprintf(ln+i, " -# %d", nrep);
 
306
 
 
307
   if (mflop >= 0)
 
308
      i += sprintf(ln+i, " -F %d", mflop);
 
309
   i += sprintf(ln+i, "\"");
 
310
   i += sprintf(ln+i, " mu=%d nu=%d", r1p->MU, r1p->NU);
 
311
   if (verb < 3)
 
312
      i += sprintf(ln+i, " > %s 2>&1\n", outnam);
 
313
   else
 
314
      i += sprintf(ln+i, "\n");
 
315
   i = system(ln);
 
316
   if (i)
 
317
   {
 
318
      fprintf(stderr, "\nERROR %d, LINE %d OF %s\n", i, __LINE__, __FILE__);
 
319
      fprintf(stderr, "SYSTEM CALL FAILED: %s\n", ln);
 
320
      if (verb < 3)
 
321
      {
 
322
         int itmp;
 
323
         fprintf(stderr, "\nOUTPUT OF system():\n");
 
324
         sprintf(ln, "cat %s 1>&2\n", outnam);
 
325
         itmp = system(ln);
 
326
         remove(outnam);
 
327
      }
 
328
      exit(-1);
 
329
   }
 
330
   if (verb < 3)
 
331
      remove(outnam);
 
332
   if (verb > 1)
 
333
   {
 
334
      dp = ReadResultsFile(1, nrep, resf);
 
335
      mf = PrintResultsFromFile(stdout, dp);
 
336
      free(dp);
 
337
      dp = &mf;
 
338
   }
 
339
   else
 
340
      dp = ReadResultsFile(0, nrep, resf);
 
341
   assert(dp);
 
342
   if (verb == 1)
 
343
      fprintf(stdout, "   %d:%s (M=%d, N=%d, lda=%d) gets %.2f MFLOPS\n",
 
344
              r1p->ID, r1p->rout, M, N, lda, *dp);
 
345
   return(*dp);
 
346
}
 
347
 
 
348
static void FillInMVExtractGenStrings(char pre, ATL_mvnode_t *kb)
 
349
/*
 
350
 * Creates generator strings to match kb settings
 
351
 */
 
352
{
 
353
   char ln[4096], *suff;
 
354
   int i, CL=8, mu;
 
355
   if (pre != 'd' && pre != 'c')
 
356
      CL = (pre == 'z') ? 4 : 16;
 
357
   while(kb)
 
358
   {
 
359
      if (kb->ID < 900000 || kb->ID >= 1000000)
 
360
      {
 
361
         kb = kb->next;
 
362
         continue;
 
363
      }
 
364
      if (kb->asmbits == asmNames2bitfield("GAS_x8664"))
 
365
      {
 
366
         assert(kb->MU%CL == 0);
 
367
         suff = "sse";
 
368
         mu = kb->MU/CL;
 
369
      }
 
370
      else
 
371
      {
 
372
         mu = kb->MU;
 
373
         if (kb->SSE)
 
374
            suff = "Csse";
 
375
         else
 
376
            suff = "C";
 
377
      }
 
378
      if (kb->TA == AtlasNoTrans)
 
379
         i = sprintf(ln, "make %cmvnext_%s order=clmajor mu=%d nu=%d", pre,
 
380
                     suff, mu, kb->NU);
 
381
      else
 
382
         i = sprintf(ln, "make %cmvtext_%s order=clmajor mu=%d nu=%d", pre,
 
383
                     suff, mu, kb->NU);
 
384
      if (kb->alignA && kb->alignA%16==0 && kb->ldamul && kb->ldamul%16==0)
 
385
         i += sprintf(ln+i, " genflags=\"-def ALIGNED 1\"");
 
386
 
 
387
      if (kb->genstr)
 
388
         free(kb->genstr);
 
389
      kb->genstr = DupString(ln);
 
390
      kb = kb->next;
 
391
   }
 
392
}
 
393
#endif  /* end guard around atlas_mvtesttime.h */