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