emit_rmvt.c

来自「基于Blas CLapck的.用过的人知道是干啥的」· C语言 代码 · 共 594 行 · 第 1/2 页

C
594
字号
      fprintf(fpout,"%s   { /* lat=%d, ngap=%d, gap=%d, gapmul=%d, pfA=%d, pfX=%d, yregs=%d */\n",              spc, il, ngap, gap, gapmul, ia, ix, iy);      spc -= 3;      FetchAX(fpout, spc, nY, ngap, gap, gapmul, ia, ix);      if (il) StartPipe(fpout, spc, il, nY, ngap, gap, gapmul, pfX);      mvTXbody(fpout, spc, il, nY, ngap, gap, gapmul, ia, ix, iy, 1);      spc += 3;      fprintf(fpout, "%s   }\n", spc);      if (FirstTime) fprintf(fpout, "cu%d:\n", j>>1);      if (gapmul > 1) gapmul >>= 1;      else if (ngap > 2) ngap >>= 1;      else if (gap > mingap) gap >>= 1;      else if (ngap > 1) ngap >>= 1;      else if (gap > 1) gap >>= 1;      FirstTime = 0;   }   spc += 3;   fprintf(fpout, "%s   } /* done X cleanup */\n\n", spc);#else   int i;   fprintf(fpout, "%s   if (X != stXN)\n%s   {\n", spc, spc);   spc -= 3;   if (nY == 1) i = 1;   else for (i=pfA; nY % i; i--);   FetchAX(fpout, spc, nY, 1, 1, 1, i, 1);   fprintf(fpout, "%s   if (X != stXN_1)\n%s   {\n", spc, spc);   spc -= 3;   fprintf(fpout, "%s   do /* while (X != stXN_1) */\n%s   {\n", spc, spc);   spc -= 3;   mvTXbody(fpout, spc, lat, nY, 1, 1, 1, i, 1, nY, 0);   spc += 3;   fprintf(fpout, "%s   }\n%s   while(X != stXN_1);\n", spc, spc);   spc += 3;   fprintf(fpout, "%s   }\n", spc);   mvTXbody(fpout, spc, lat, nY, 1, 1, 1, i, 1, nY, 1);   spc += 3;   fprintf(fpout, "%s   } /* finish cleanup */\n\n", spc);#endif}static void Xloop(FILE *fpout, char *spc, char pre, int lat, int nY,                  int ngap, int gap, int gapmul, int pfA, int pfX, int Yregs){   int i, nu = ngap * gap * gapmul;   fprintf(fpout, "%s   if (N >= %d)\n%s   {\n", spc, 2*nu, spc);   spc -= 3;   FetchAX(fpout, spc, nY, ngap, gap, gapmul, pfA, pfX);   if (lat) StartPipe(fpout, spc, lat, nY, ngap, gap, gapmul, pfX);   fprintf(fpout, "%s   do /* while (X != stX) */\n%s   {\n", spc, spc);   spc -= 3;   mvTXbody(fpout, spc, lat, nY, ngap, gap, gapmul, pfA, pfX, Yregs, 0);   spc += 3;   fprintf(fpout, "%s   }\n%s   while(X != stX);\n", spc, spc);   mvTXbody(fpout, spc, lat, nY, ngap, gap, gapmul, pfA, pfX, Yregs, 1);   spc += 3;   fprintf(fpout, "%s   }\n\n", spc);   XCleanup(fpout, spc, pre, lat, nY, ngap, gap, gapmul, pfA, pfX, Yregs);   CombY(fpout, spc, nY, Yregs);}static void emit_mvT   (FILE *fpout, char *rout, char pre, char *styp, char *typ, int lat,    int beta, int nY, int ngap, int gap, int gapmul, int pfA, int pfX,    int Yregs){   char *spcs = "                                        ";   char *spc = spcs+40;   char ln[128];   char *bnam[3] = {"b0", "b1", "bX"};   int i, j, nu = ngap * gap * gapmul;   if (beta != 0 && beta != 1) beta = 2;   if (nY > 1) fprintf(fpout, "#include \"atlas_level1.h\"\n");   fprintf(fpout, "#include <stddef.h>\n");   if (rout == NULL)   {      rout = ln;      sprintf(ln, "ATL_%cgemvT_a1_x1_%s_y1\n", pre, bnam[beta]);   }   fprintf(fpout, "void %s", rout);   fprintf(fpout, "/*\n * lat=%d, beta=%s, nY=%d, ngap=%d, gap=%d, gapmul=%d, pfA=%d, pfX=%d\n */\n",           lat, bnam[beta], nY, ngap, gap, gapmul, pfA, pfX);   fprintf(fpout, "   (const int M, const int N, const %s alpha,\n", styp);   fprintf(fpout,           "   const %s *A, const int lda, const %s *X, const int incX,\n",           typ, typ);   fprintf(fpout, "   const %s beta, %s *Y, const int incY)\n", styp, typ);   fprintf(fpout, "{\n");   fprintf(fpout, "   register %s rX0", typ);   for (i=1; i < pfX; i++) fprintf(fpout, ", rX%d", i);   for (i=0; i < pfA; i++) fprintf(fpout, ", rA%d", i);   for (i=0; i < Yregs; i++) fprintf(fpout, ", rY%d", i);   fprintf(fpout, ";\n");   fprintf(fpout, "   const %s *pA0=A", typ);   for (i=1; i < nY; i++) fprintf(fpout, ", *pA%d=pA%d+lda", i, i-1);   fprintf(fpout, ";\n");   fprintf(fpout, "   const int n = %s;\n", GetInc(nu,GetDiv(nu, "N")));   fprintf(fpout, "   const int m = %s;\n", GetInc(nY,GetDiv(nY, "M")));   fprintf(fpout,           "   const %s *stX = X + n - %d, *stXN = X + N, *stXN_1 = stXN-1;\n",           typ, nu);   fprintf(fpout, "   %s *stY = Y + m;\n", typ);   fprintf(fpout, "%s   const int incA = %s - N;\n", spc, GetInc(nY, "lda"));   fprintf(fpout, "\n");   if (nY > 1)   {      fprintf(fpout, "%s   if (m)\n%s   {\n", spc, spc);      spc -= 3;   }   fprintf(fpout, "%s   do /* while (Y != stY) */\n%s   {\n", spc, spc);   spc -= 3;   FetchY(fpout, spc, pre, beta, nY, Yregs, "rX0");   Xloop(fpout, spc, pre, lat, nY, ngap, gap, gapmul, pfA, pfX, Yregs);   fprintf(fpout, "%s   X -= N;\n", spc);   for (j=0; j < nY; j++)   {      fprintf(fpout, "%s   pA%d += incA;\n", spc, j);      fprintf(fpout, "%s   Y[%d] = rY%d;\n", spc, j, j);   }   if (nY > 1) fprintf(fpout, "%s   Y += %d;\n", spc, nY);   spc += 3;   if (nY == 1) fprintf(fpout, "%s   }\n%s   while(++Y != stY);\n", spc, spc);   else fprintf(fpout, "%s   }\n%s   while(Y != stY);\n", spc, spc);   if (nY > 1)   {      spc += 3;      fprintf(fpout, "%s   }\n", spc);      fprintf(fpout, "%s   if (m != M)\n%s   {\n", spc, spc);      spc -= 3;      if (beta != 0 && beta != 1) fprintf(fpout, "%s   rX0 = beta;\n", spc);      if (nY > 2)      {         fprintf(fpout, "%s   stY += M-m;\n", spc);         fprintf(fpout, "%s   do /* while (Y != stY) */\n%s   {\n", spc, spc);         spc -= 3;      }      if (beta != 0) fprintf(fpout, "%s   rY0 = *Y;\n", spc);      if (beta != 0 && beta != 1) fprintf(fpout, "%s   rY0 *= rX0;\n", spc);      if (beta == 0) fprintf(fpout, "%s   rY0 = ", spc);      else fprintf(fpout, "%s   rY0 += ", spc);      fprintf(fpout, "ATL_%cdot(N, pA0, 1, X, 1);\n", pre);      fprintf(fpout, "%s   *Y = rY0;\n", spc);      if (nY > 2)      {         fprintf(fpout, "%s   pA0 += lda;\n", spc);         spc += 3;         fprintf(fpout, "%s   }\n%s   while (++Y != stY);\n", spc, spc);      }      spc += 3;      fprintf(fpout, "%s   } /* end Y cleanup */;\n", spc);   }   fprintf(fpout, "}\n");}void PrintUsage(char *nam){   fprintf(stderr, "USAGE: %s -l <latency> -Y <nY> -G <ngap> -g <gap> -M <gapmul> -A <# of regs for A> -X <# of regs for X> -y <# regs for Y> -f <file> -R <rout> -b <beta>\n", nam);   exit(-1);}void GetFlags(int nargs, char **args, int *lat, int *beta, int *nY,              int *ngap, int *gap, int *gapmul, int *pfA, int *pfX,              int *Yregs, char *pre, char *styp, char *typ,              FILE **fpout, char **rout){   int i;   *beta = -3;   *lat = 0;   *nY = *Yregs = *ngap = *gap = *gapmul = *pfA = *pfX = 1;   *pre = 'd';   *rout = NULL;   *fpout = stdout;   for (i=1; i < nargs; i++)   {      if (args[i][0] != '-') PrintUsage(args[0]);      switch(args[i][1])      {      case 'R':         *rout = args[++i];         break;      case 'f':         *fpout = fopen(args[++i], "w");         assert(*fpout);         break;      case 'b':         *beta = atoi(args[++i]);         break;      case 'l':         *lat = atoi(args[++i]);         break;      case 'y':         *nY = atoi(args[++i]);         break;      case 'G':         *ngap = atoi(args[++i]);         break;      case 'g':         *gap = atoi(args[++i]);         break;      case 'M':         *gapmul = atoi(args[++i]);         break;      case 'A':         *pfA = atoi(args[++i]);         break;      case 'X':         *pfX = atoi(args[++i]);         break;      case 'Y':         *Yregs = atoi(args[++i]);         break;      case 'p':         i++;         *pre = Mlowcase(args[i][0]);         break;      default:         PrintUsage(args[0]);      }   }   i = *nY * *ngap * *gap * *gapmul;   assert(i % *pfA == 0);   if (*lat)   {      assert(i % *lat == 0);      assert(*pfX + *lat / *nY <= i);      assert(*pfA > *lat);   }   assert((*ngap * *gap * *gapmul)% (*pfX)  == 0);   assert(*Yregs >= *nY);   switch (*pre)   {   case 'z':      sprintf(styp, "double*");      sprintf(typ, "double");      break;   case 'd':      sprintf(styp, "double");      sprintf(typ, "double");      break;   case 'c':      sprintf(styp, "float*");      sprintf(typ, "float");      break;   case 's':      sprintf(styp, "float");      sprintf(typ, "float");      break;   default:      PrintUsage(args[0]);   }}main(int nargs, char **args){   char pre, styp[32], typ[32], *rout;   int lat;     /* 0: combined muladd inst; X: seperate multiply & add, lat=X */   int nY;      /* number of columns of A to operate on (# of dot products) */   int Yregs;   /* number of registers to use for Y */   int ngap;    /* number of accumulaters to use within each dot prod */   int gap;     /* gap size in column */   int gapmul;  /* number of unrollings of whole mess to do */   int pfA;     /* number of registers to use in prefetching A */   int pfX;     /* number of registers to use in prefetching X */   int i, beta;   FILE *fpout;   GetFlags(nargs, args, &lat, &beta, &nY, &ngap, &gap, &gapmul, &pfA, &pfX,            &Yregs, &pre, styp, typ, &fpout, &rout);   if (beta == -3) /* generate all beta cases */   {      for (i=0; i < 3; i++)      {         if (i == 0 || i == 1) fprintf(fpout, "#ifdef BETA%d\n\n", i);         else fprintf(fpout, "#ifdef BETAX\n\n");         emit_mvT(fpout, rout, pre, styp, typ, lat, i, nY, ngap, gap, gapmul,                  pfA, pfX, Yregs);         fprintf(fpout, "\n\n#endif\n");      }   }   else emit_mvT(fpout, rout, pre, styp, typ, lat, beta, nY, ngap, gap,                 gapmul, pfA, pfX, Yregs);   exit(0);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?