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 + -
显示快捷键?