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

« back to all changes in this revision

Viewing changes to tune/threads/tune_aff.c

  • Committer: Package Import Robot
  • Author(s): Sébastien Villemot, Sylvestre Ledru, Sébastien Villemot
  • Date: 2013-06-11 15:58:16 UTC
  • mfrom: (1.1.4) (25 sid)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: package-import@ubuntu.com-20130611155816-8xeeiziu1iml040c
Tags: 3.10.1-1
[ Sylvestre Ledru ]
* New upstream release (Closes: #609287)

[ Sébastien Villemot ]
* Provide architectural defaults (i.e. precomputed timings) for all
  release archs (except armel and mips for the time being, due to slow
  porterboxes). This will make the package build much faster and should
  eliminate transient build failures due to excessive variance in the
  timings.
* Move symlinks for lib{cblas,f77blas,atlas,lapack_atlas} out of the
  libblas.so.3 alternative and make them always present, so that
  software relying on these libs do not break when another alternative
  is selected for BLAS
* ATLAS now has improved ARM support with native asm constructs. This required
  the following tunes:
  + armel-is-v4t.diff: new patch, prevents FTBFS on armel; otherwise,
    ATLAS uses asm constructs too recent for the platform (armel is only v4t)
  + debian/rules: on armhf, define the ATL_ARM_HARDFP flag; otherwise the asm
    constructs use the soft-float ABI for passing floating points
  + on armhf, ensure that -mfloat-abi=softfp and -mcpu=vfpv3 flags are never
    used; this is implemented via a patch (armhf.diff) and by the use of fixed
    archdefs
* The generic package is now built without multi-threading, because otherwise
  the package fails to build on some single-processor machines (this required
  the introduction of a patch: fix-non-threaded-build.diff). As a side effect,
  the build of the custom package gracefully handles non-threaded
  builds. (Closes: #602524)
* Add libblas.a as slave in the libblas.so alternative (Closes: #701921)
* Add symlinks for lib{f77blas,atlas}.a in /usr/lib (Closes: #666203)
* Modify shlibs file of libatlas3-base, such that packages using
  libblas/liblapack depend on any BLAS/LAPACK alternative, while packages
  depending on ATLAS-specific libraries (e.g. libatlas.so) depend specifically
  on libatlas3-base.
* corei1.diff: remove patch, applied upstream
* Use my @debian.org email address
* Remove obsolete DM-Upload-Allowed flag
* Switch VCS to git
* Remove Conflicts/Replaces against pre-squeeze packages
* libatlas-base-dev now provides libblas.so, as libblas-dev
* No longer use -Wa,--noexecstack in CFLAGS, it makes the package FTBFS
* Do not use POWER3 arch for powerpcspe port (Closes: #701068)
* Bump to debhelper compat level 9
* README.Debian: mention that devscripts is needed to compile the custom
  package (Closes: #697431)
* Bump Standards-Version to 3.9.4. As a consequence, add Built-Using
  fields because the package embeds stuff from liblapack-pic

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "atlas_taffinity.h"
 
2
#include "atlas_threads.h"
 
3
#define DREAL
 
4
#include "atlas_misc.h"
 
5
 
 
6
void ATL_goparallel_noaff
 
7
   (const unsigned int P, void *DoWork, void *opstruct, void *DoComb);
 
8
 
 
9
typedef struct
 
10
{
 
11
   size_t nflops;               /* number of flops to perform */
 
12
   volatile double *V;          /* 16-length array of zeros */
 
13
   int rank, nthr;
 
14
} ATL_TUNE_T;
 
15
 
 
16
 
 
17
void InCacheGemm
 
18
(
 
19
   size_t nflops,               /* how many flops to do */
 
20
   volatile double *V           /* 16-length array of zeros */
 
21
)
 
22
/*
 
23
 * This routine emulates an in-cache 4x4 GEMM, but using only 16 registers
 
24
 * V is declared volatile so compiler doesn't get rid of the loop.
 
25
 */
 
26
{
 
27
   size_t i;
 
28
   register double c0, c1, c2, c3, c4, c5, c6, c7;
 
29
   register double a0, a1, a2, a3, b0, b1, b2, b3;
 
30
 
 
31
   a0 = *V;   b0 = V[4];
 
32
   a1 = V[1]; a2 = V[2];
 
33
   c0 = c1 = c2 = c3 = c4 = c5 = c6 = c7 = ATL_rzero;
 
34
   for (i=(nflops>>5); i; i--)
 
35
   {
 
36
      c0 += a0*b0; a3 = V[3];
 
37
      c1 += a1*b0;
 
38
      c2 += a2*b0; b1 = V[5];
 
39
      c3 += a3*b0;
 
40
      c4 += a0*b1; b2 = V[6];
 
41
      c5 += a1*b1;
 
42
      c6 += a2*b1;
 
43
      c7 += a3*b1;
 
44
      c0 += a0*b2; b3 = V[7];
 
45
      c1 += a1*b2;
 
46
      c2 += a2*b2; b0 = V[4];
 
47
      c3 += a3*b2;
 
48
      c4 += a0*b3; a0 = *V;
 
49
      c5 += a1*b3; a1 = V[1];
 
50
      c6 += a2*b3; a2 = V[2];
 
51
      c7 += a3*b3;
 
52
   }
 
53
   *V = c0;   V[1] = c1; V[2] = c2; V[3] = c3;
 
54
   V[4] = c4; V[5] = c5; V[6] = c6; V[7] = c7;
 
55
}
 
56
 
 
57
void TuneDoWork_gp(ATL_LAUNCHSTRUCT_t *lp, void *vp)
 
58
{
 
59
   ATL_TUNE_T *tp = lp->opstruct;
 
60
   int i;
 
61
   InCacheGemm(tp->nflops, tp->V);
 
62
}
 
63
 
 
64
void TuneDoWork(ATL_LAUNCHSTRUCT_t *lp, void *vp)
 
65
{
 
66
   ATL_TUNE_T *tp = lp->opstruct;
 
67
   int i;
 
68
   InCacheGemm(tp->nflops, tp->V);
 
69
}
 
70
 
 
71
void PrintUsage(char *exe)
 
72
{
 
73
   fprintf(stderr, "USAGE: %s [-r <reps>] -m/k/f [m/k/flops] -o outfile\n",
 
74
           exe);
 
75
   exit(-1);
 
76
}
 
77
 
 
78
int GetFlags(int nargs, char **args, size_t *nflop, char **outfile)
 
79
{
 
80
   int i, reps=50, imul;
 
81
 
 
82
   *outfile = NULL;
 
83
   *nflop = 2*300 * 300 * 300;  /* emulate 300x300 DGEMM */
 
84
   for (i=1; i < nargs; i++)
 
85
   {
 
86
      imul = 1;
 
87
      if (args[i][0] != '-')
 
88
         PrintUsage(args[0]);
 
89
      switch(args[i][1])
 
90
      {
 
91
      case 'r':
 
92
         if (++i >= nargs)
 
93
            PrintUsage(args[0]);
 
94
         reps = atoi(args[i]);
 
95
         break;
 
96
      case 'm':
 
97
         imul *= 1000;
 
98
      case 'k':
 
99
         imul *= 1000;
 
100
      case 'f':
 
101
         if (++i >= nargs)
 
102
            PrintUsage(args[0]);
 
103
         *nflop = atoll(args[i]) * imul;
 
104
         break;
 
105
      case 'o':
 
106
         if (++i >= nargs)
 
107
            PrintUsage(args[0]);
 
108
         *outfile = args[i];
 
109
         break;
 
110
      default:
 
111
         PrintUsage(args[0]);
 
112
      }
 
113
   }
 
114
   return(reps);
 
115
}
 
116
int main(int nargs, char **args)
 
117
{
 
118
#ifndef ATL_OMP_THREADS
 
119
   size_t nflops;
 
120
   int i, k, nreps = 200, opstride, which;
 
121
   double t0, taff, tnoa;
 
122
   ATL_TUNE_T ta[ATL_NTHREADS];
 
123
   volatile double *V;
 
124
   void *vp[ATL_NTHREADS];
 
125
   char *outfile;
 
126
 
 
127
 
 
128
   taff = tnoa = 0.0;
 
129
   nreps = GetFlags(nargs, args, &nflops, &outfile);
 
130
 
 
131
   for (i=0; i < ATL_NTHREADS; i++)
 
132
   {
 
133
      ta[i].rank = i;
 
134
      ta[i].nthr = ATL_NTHREADS;
 
135
      ta[i].nflops = nflops;
 
136
      vp[i] = malloc(sizeof(double)*16 + ATL_Cachelen);
 
137
      ATL_assert(vp[i]);
 
138
      ta[i].V = ATL_AlignPtr(vp[i]);
 
139
      ATL_dzero(16, (double*)ta[i].V, 1);  /* zero w/o telling compiler */
 
140
   }
 
141
   opstride = (int) ( ((char*)(ta+1)) - (char*)(ta) );
 
142
 
 
143
   printf("FINDING WHETHER AFFINITY IS HELPFUL USING FLOPS=%e NREPS=%d\n",
 
144
          (double)nflops, nreps);
 
145
 
 
146
   t0 = ATL_walltime();
 
147
   for (k=0; k < nreps; k++)
 
148
      ATL_goparallel(ATL_NTHREADS, TuneDoWork, ta, NULL);
 
149
   taff = ATL_walltime() - t0;
 
150
   printf("   Affinity    time = %e\n", (float)taff);
 
151
 
 
152
   t0 = ATL_walltime();
 
153
   for (k=0; k < nreps; k++)
 
154
      ATL_goparallel_noaff(ATL_NTHREADS, TuneDoWork, ta, NULL);
 
155
   tnoa = ATL_walltime() - t0;
 
156
   printf("   NO affinity time = %e\n", (float)tnoa);
 
157
 
 
158
   printf("Affinity speedup = %.2f\n", (float)(tnoa / taff));
 
159
 
 
160
   for (i=0; i < ATL_NTHREADS; i++)
 
161
      free(vp[i]);
 
162
 
 
163
   if (outfile)  /* if this is a real run where we want to change things */
 
164
   {
 
165
      if (tnoa*1.04 < taff)
 
166
      {
 
167
         FILE *fpout;
 
168
         printf(
 
169
       "Affinity is not helpful on your system, forcing ATLAS not to use it\n");
 
170
         fpout = fopen(outfile, "w");
 
171
         ATL_assert(fpout);
 
172
         fprintf(fpout, "#ifndef ATL_TAFFINITY_H\n   #define ATL_TAFFINITY_H\n");
 
173
         fprintf(fpout, "   #define ATL_NOAFFINITY 1\n");
 
174
         fprintf(fpout, "#endif\n");
 
175
         fclose(fpout);
 
176
         fpout = fopen("res/aff.h", "w");
 
177
         fprintf(fpout, "#define ATL_TAFFINITY 0\n");
 
178
         fclose(fpout);
 
179
      }
 
180
      else /* affinity was a win */
 
181
      {
 
182
         FILE *fpout;
 
183
         fpout = fopen("res/aff.h", "w");
 
184
         fprintf(fpout, "#define ATL_TAFFINITY 1\n");
 
185
         fclose(fpout);
 
186
      }
 
187
   }
 
188
#else
 
189
   FILE *fpout;
 
190
   char *outfile;
 
191
   size_t nflops;
 
192
   int nreps;
 
193
 
 
194
   nreps = GetFlags(nargs, args, &nflops, &outfile);
 
195
   if (outfile)
 
196
   {
 
197
      printf(
 
198
      "Not good idea to set affinity wt OpenMP; forcing ATLAS not to use it\n");
 
199
      fpout = fopen(outfile, "w");
 
200
      ATL_assert(fpout);
 
201
      fprintf(fpout, "#ifndef ATL_TAFFINITY_H\n   #define ATL_TAFFINITY_H\n");
 
202
      fprintf(fpout, "   #define ATL_NOAFFINITY 1\n");
 
203
      fprintf(fpout, "#endif\n");
 
204
      fclose(fpout);
 
205
      fpout = fopen("res/aff.h", "w");
 
206
      fprintf(fpout, "#define ATL_TAFFINITY 0\n");
 
207
      fclose(fpout);
 
208
   }
 
209
#endif
 
210
   return(0);
 
211
}