ummsearch.c
来自「基于Blas CLapck的.用过的人知道是干啥的」· C语言 代码 · 共 1,470 行 · 第 1/3 页
C
1,470 行
/* * Automatically Tuned Linear Algebra Software v3.8.0 * (C) Copyright 2000 R. Clint Whaley * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions, and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the ATLAS group or the names of its contributers may * not be used to endorse or promote products derived from this * software without specific written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <string.h>#include "atlas_misc.h"#include "atlas_fopen.h"#include "atlas_prefetch.h"#define Mmin(x, y) ( (x) > (y) ? (y) : (x) )#define TOLERANCE 1.2#define MAX_NB 80int L1Elts(char pre, int MaxL1Size){ FILE *L1f; int L1Size, tsize; char ln[128]; if (!FileExists("res/L1CacheSize")) { sprintf(ln, "make RunL1 MaxL1=%d\n",MaxL1Size); if (system(ln) != 0) { remove("res/L1CacheSize"); fprintf(stderr, "Error in command: %s", ln); exit(-1); } } L1f = fopen("res/L1CacheSize", "r"); assert(L1f != NULL); fscanf(L1f, "%d", &L1Size); fclose(L1f); switch (pre) { case 's': tsize = sizeof(float); break; case 'd': tsize = sizeof(double); break; case 'q': tsize = sizeof(long double); break; case 'c': tsize = sizeof(float); break; case 'z': tsize = sizeof(double); break; } return( (L1Size*1024) / tsize);}int GetCacheSize(int MaxL1Size)/* * Returns L1 size in kilobytes */{ FILE *L1f; int L1Size; char ln[32]; if (!FileExists("res/L1CacheSize")) { sprintf(ln, "make RunL1 MaxL1=%d\n",MaxL1Size); if (system(ln) != 0) { remove("res/L1CacheSize"); fprintf(stderr, "Error in command: %s", ln); exit(-1); } } L1f = fopen("res/L1CacheSize", "r"); assert(L1f != NULL); fscanf(L1f, "%d", &L1Size); fclose(L1f); fprintf(stderr, "\n Read in L1 Cache size as = %dKB.\n",L1Size); return(L1Size);}int GetTypeSize(char pre){ int tsize; if (pre == 'c' || pre == 's') tsize = ATL_ssize; else tsize = ATL_dsize; return(tsize);}void findNBs(char prec, char *NBnam, int MaxL1Size){ FILE *NBf; char ln[80]; int i, L1Size, tmp, tsize, tL1Size, CL, nNB; int NB[100]; fprintf(stderr, "NB setting not supplied; calculating:\n"); L1Size = GetCacheSize(MaxL1Size); tsize = GetTypeSize(prec); tL1Size = L1Size * (1024 / tsize); tmp = CL = ATL_Cachelen / tsize; if (!tmp) tmp=1; nNB = 0; fprintf(stderr, "tmp=%d, tL1size=%d\n",tmp, tL1Size); while (tmp*tmp <= tL1Size) { if (tmp >= 16) /* no block sizes smaller than 16 */ NB[nNB++] = tmp; if (tmp >= 80) break; /* no block sizes bigger than 80 */ tmp += CL; } if (!nNB) /* this should never happen */ { nNB = 3; NB[0] = 8; NB[1] = 4; NB[2] = 16; } else if (nNB > 2) /* put second biggest blocking factor first in list */ { tmp = NB[nNB-2]; NB[nNB-2] = NB[0]; NB[0] = tmp; } NBf = fopen(NBnam, "w"); fprintf(NBf, "%d\n", nNB); for (i=0; i != nNB; i++) fprintf(NBf, "%d\n", NB[i]); fclose(NBf);}int GetSafeNB(char pre, int MaxL1){ int i, L1, tsize, inc; tsize = GetTypeSize(pre); inc = ATL_MinMMAlign / tsize; if (inc < 4) inc = 4; L1 = (GetCacheSize(MaxL1) * 1024) / tsize; for (i=inc; i*i < L1; i += inc); if (i*i > L1) i -= inc; if (pre == 'd' || pre == 's') { if (i*i == L1) i -= inc; } else { if (i*i == L1) i -= 2*inc; else i -= inc; } if (i < 16) i = 16; if (i > 80) i = 80; return(i);}double GetAvg(int n, double tolerance, double *mflop){ int i, j; double t0, tavg;/* * Sort results, largest first */ for (i=0; i != n; i++) { for (j=i+1; j < n; j++) { if (mflop[i] < mflop[j]) { t0 = mflop[i]; mflop[i] = mflop[j]; mflop[j] = t0; } } }/* * Not doing tolerance anymore, just take largest mflop rate if doing wall * times, or median value if doing CPU */#if 1 #ifdef WALL tavg = mflop[0]; #else tavg = mflop[n/2]; #endif#else/* * Throw out result if it is outside tolerance; rerun if two mflop not within * tolerance; this code assumes n == 3 */ if (tolerance*mflop[1] < mflop[0]) /* too big a range in results */ { if (tolerance*mflop[2] < mflop[1]) return(-1.0); tavg = (mflop[1] + mflop[2]) / 2.0; } else if (tolerance*mflop[2] < mflop[0]) tavg = (mflop[0] + mflop[1]) / 2.0; else tavg = (mflop[0] + mflop[1] + mflop[2]) / 3.0;#endif return(tavg);}void PutInstLogLine(FILE *fp, int muladd, int pfA, int lat, int nb, int mu, int nu, int ku, int ForceFetch, int ifetch, int nfetch, double mflop){ fprintf(fp, "%6d %3d %4d %3d %3d %3d %3d %5d %5d %5d %7.2lf\n", muladd, lat, pfA, nb, mu, nu, ku, ForceFetch, ifetch, nfetch, mflop);}void PutInstLogFile(FILE *fp, int muladd, int pfA, int lat, int nb, int mu, int nu, int ku, int ForceFetch, int ifetch, int nfetch, double mflop){ fprintf(fp, "MULADD LAT PREF NB MU NU KU FFTCH IFTCH NFTCH MFLOP\n"); PutInstLogLine(fp, muladd, pfA, lat, nb, mu, nu, ku, ForceFetch, ifetch, nfetch, mflop);}void PutInstLogFile1(char *fnam, char pre, int muladd, int pfA, int lat, int nb, int mu, int nu, int ku, int ForceFetch, int ifetch, int nfetch, double mflop){ FILE *fp; fp = fopen(fnam, "w"); assert(fp); PutInstLogFile(fp, muladd, pfA, lat, nb, mu, nu, ku, ForceFetch, ifetch, nfetch, mflop); fclose(fp);}void GetInstLogLine(FILE *fp, int *muladd, int *pfA, int *lat, int *nb, int *mu, int *nu, int *ku, int *ForceFetch, int *ifetch, int *nfetch, double *mflop){ assert(fscanf(fp, " %d %d %d %d %d %d %d %d %d %d %lf\n", muladd, lat, pfA, nb, mu, nu, ku, ForceFetch, ifetch, nfetch, mflop) == 11);}void GetInstLogFile(char *nam, char pre, int *muladd, int *pfA, int *lat, int *nb, int *mu, int *nu, int *ku, int *ForceFetch, int *ifetch, int *nfetch, double *mflop){ char ln[128]; FILE *fp; fp = fopen(nam, "r"); if (fp == NULL) fprintf(stderr, "file %s not found!!\n\n", nam); assert(fp); fgets(ln, 128, fp); GetInstLogLine(fp, muladd, pfA, lat, nb, mu, nu, ku, ForceFetch, ifetch, nfetch, mflop); fclose(fp);}#define AUTHLEN 256#define ROUTLEN 256#define NOTIMED -8.0#define ATL_MMNoClean(iflag_) ( ((iflag_) | 8) == (iflag_) )#define ATL_MMCleanOnly(iflag_) ( ((iflag_) | 16) == (iflag_) )#define ATL_MMVarLda(iflag_) ( ((iflag_) | 32) == (iflag_) )#define ATL_MMVarM(iflag_) ( ((iflag_) | 64) == (iflag_) )#define ATL_MMVarN(iflag_) ( ((iflag_) | 128) == (iflag_) )#define ATL_MMVarK(iflag_) ( ((iflag_) | 256) == (iflag_) )enum CLEAN_WHICH{CleanM=0, CleanN=1, CleanK=2, CleanNot=3};typedef struct RoutNode ROUTNODE;struct RoutNode{ double mflop; char *rout; ROUTNODE *next; int icase; int fixed; /* 0: pNB input para; 1: pNB=NB; 2: pNB=imult */};typedef struct MultHead MULTHEAD;struct MultHead{ int imult; MULTHEAD *next; ROUTNODE *rn;} *imhead=NULL;int LineIsCont(char *ln){ int i, iret=0; for(i=0; ln[i]; i++); if (i) { for(i--; isspace(ln[i]); i--); if (ln[i] == '\\') iret = 1; } return(iret);}int NumUserCases0(char *nam){ int iret=0; char ln[512]; FILE *fp; fp = fopen(nam, "r"); if (fp) { fgets(ln, 512, fp); /* skip comment line */ assert(fscanf(fp, " %d", &iret) == 1); fclose(fp); } return(iret);}int NumUserCases(char pre){ char ln[64]; sprintf(ln, "%ccases.dsc", pre); return(NumUserCases0(ln));}void NoEndLineWhiteSpace(char *ln){ int i; for (i=0; ln[i]; i++); if (i) for (i--; isspace(ln[i]); i--) ln[i] = '\0';}int GetUserCase(char pre, int icase, int *iflag, int *mb, int *nb, int *kb, int *ma, int *lat, int *mu, int *nu, int *ku, char *fnam, char *auth, char **MCC, char **MMFLAGS)/* * if icase < 0, go to that line in file; if icase > 0 find that ID in file * return ID of selected line */{ int i, n, ID; char ln[512]; static char sMCC[1024], sMMFLAGS[2048]; FILE *fp; n = NumUserCases(pre); sprintf(ln, "%ccases.dsc", pre); fp = fopen(ln, "r"); if (!fp) return(0); assert(fp); fgets(ln, 256, fp); /* skip comment line */ fgets(ln, 256, fp); /* skip number of cases */ for (i=0; i < n; i++) { if ( fgets(ln, 256, fp) == NULL ) { fclose(fp); return(0); } assert(sscanf(ln, " %d %d %d %d %d %d %d %d %d %d %s \"%[^\"]", &ID, iflag, mb, nb, kb, ma, lat, mu, nu, ku, fnam, auth) == 12); assert(ID > 0); if (i == -icase || ID == icase) { if (LineIsCont(ln)) { assert( fgets(ln, 256, fp) != NULL ); strcpy(sMCC, ln); NoEndLineWhiteSpace(sMCC); assert( fgets(ln, 512, fp) != NULL ); strcpy(sMMFLAGS, ln); NoEndLineWhiteSpace(sMMFLAGS); *MCC = sMCC; *MMFLAGS = sMMFLAGS; } else *MCC = *MMFLAGS = NULL; fclose(fp); return(ID); } if (i != icase && LineIsCont(ln)) { assert( fgets(ln, 256, fp) != NULL ); assert( fgets(ln, 256, fp) != NULL ); } } fclose(fp); return(0);}int IsCaseFixed(char pre, int icase, enum CLEAN_WHICH which){ char stmp[ROUTLEN], *MCC, *MMFLAGS; int iflag, ma, lat, mu, nu, ku, NB[3]; assert(GetUserCase(pre, icase, &iflag, NB, NB+1, NB+2, &ma, &lat, &mu, &nu, &ku, stmp, stmp, &MCC, &MMFLAGS)); if (NB[which] > 0) { if (which == CleanM && ATL_MMVarM(iflag)) ma = 0; else if (which == CleanN && ATL_MMVarN(iflag)) ma = 0; else if (which == CleanK && ATL_MMVarK(iflag) && ATL_MMVarLda(iflag)) ma = 0; else ma = 1; } else if (NB[which] < 0) ma = 2; else { if (which == CleanK && !ATL_MMVarLda(iflag)) ma = 1; else ma = 0; } return(ma);}ROUTNODE *CreateRoutNode(char *rout, int icase, double mflop){ ROUTNODE *rn; int i; rn = malloc(sizeof(ROUTNODE)); assert(rn); i = strlen(rout)+1; rn->rout = malloc(i * sizeof(char)); assert(rn->rout); strcpy(rn->rout, rout); rn->icase = icase; rn->mflop = mflop; rn->fixed = -1; rn->next = NULL; return(rn);}void KillRoutNode(ROUTNODE *rn){ free(rn->rout); free(rn);}void RemoveRoutNode(MULTHEAD *mh, ROUTNODE *rn0){ ROUTNODE *rn; if (rn0 == NULL) return; assert(mh->next); if (mh->rn != rn0) { for (rn=mh->rn; rn->next != rn0 && rn->next; rn = rn->next); assert(rn->next == rn0); rn->next = rn0->next; } else mh->rn = rn0->next; KillRoutNode(rn0);}void KillAllRoutNodes(ROUTNODE *rn0){ ROUTNODE *rn; while(rn0) { rn = rn0->next; KillRoutNode(rn0); rn0 = rn;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?