/****************************************************************** ** Matrix Matrix Multiply Contest Test Driver: ** U.C. Berkeley, Department of EECS, Computer Science Division ** CS 267, Applications of Parallel Processing ** Spring 1996 ** $Id: mm_contest.c,v 1.1 1995/01/23 12:29:27 bilmes Exp borisv $ ** ******************************************************************* */ #include #include #include #include #include #include #ifdef DOOURS extern void mul_mfmf_mf(int,int,int, const double *A, const double *B, const double *C); #define MUL_MFMF_MF(size,A,B,C) mul_mfmf_mf(size,size,size,A,B,C) #elif defined(DOESSL) const char N = 'N'; const double one = 1.0; #define MUL_MFMF_MF(size,A,B,C) dgemm(&N,&N, \ &size,&size,&size, \ &one, \ B,&size, \ A,&size, \ &one, \ C,&size) #else extern void mul_mfmf_mf(int matdim, const double *A, const double *B, const double *C); #define MUL_MFMF_MF(size,A,B,C) mul_mfmf_mf(size,A,B,C) #endif #define NUM_CORRECTNESS_CHECKS 10 #define MAX_ERROR 2.0 #define TEST_RUNS 10 /* number of runs of each size */ /* Arbitrary sized tests */ #define NUM_ATESTS (sizeof(atest_sizes)/sizeof(int)) int atest_sizes[] = { 23, 43, 61, 79, 99, 119, 151 }; int atest_iters[] = { 4000, 900, 500, 220, 130, 70, 35 }; /* The above iters are choosen so that dgemm from ESSL runs in >= .75 seconds. */ /* They are not yet set in stone, and they may change before the contest */ /* quad-word aligned tests */ #define NUM_QTESTS (sizeof(qtest_sizes)/sizeof(int)) int qtest_sizes[] = { 16, 32, 64, 128, 256 }; int qtest_iters[] = { 11000, 5000, 760, 110, 11 }; /* The above iters are choosen so that dgemm from ESSL runs in >= .75 seconds. */ /* They are not yet set in stone, and they may change before the contest */ extern double drand48(); extern unsigned short* seed48(); extern int getrussage(int,struct rusage*); struct rusage rus; /* starting time */ struct rusage rue; /* ending time */ #define START_TIMING getrusage(RUSAGE_SELF,&rus); #define STOP_TIMING getrusage(RUSAGE_SELF,&rue); #define ABS(val) ((val)>0?(val):-(val)) #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) #define SQ(a) ((a)*(a)) double reportTiming() { struct timeval utime; utime.tv_sec = rue.ru_utime.tv_sec - rus.ru_utime.tv_sec ; if ( rue.ru_utime.tv_usec < rus.ru_utime.tv_usec ) { utime.tv_sec--; utime.tv_usec = 1000000l - rus.ru_utime.tv_usec + rue.ru_utime.tv_usec; } else utime.tv_usec = rue.ru_utime.tv_usec - rus.ru_utime.tv_usec ; return ((double)utime.tv_sec + (double)utime.tv_usec*1e-6); } void myseed() { int i; unsigned short seed16v[3]; for (i=0;i<3;i++) seed16v[i] = time(0); seed48(seed16v); } /* ** A naive matrix multiply routine. ** Used to test for correctness. */ void naive_mm(int Sm,int Sk,int Sn, const double *A,const double *B,double *C) { int i,j,k; for (i=0;i MAX_ERROR) { printf("Error for test case %dx%d is %f > %f. DISQUALIFIED!!!\n", matdim,matdim,err,MAX_ERROR); exit(0); } free(A); free(B); free(C); free(cC); } fprintf(stderr,"\n"); fflush(stderr); /* quad-word aligned sizes */ fprintf(stderr,"Checking quad-word aligned sizes\n"); fflush(stderr); for (test=0;test max_mflops) max_mflops = mflops; } printf("%d %f\n",matdim,max_mflops); fflush(stdout); free(A); free(B); free(C); } /* arbitrary sizes */ fprintf(stderr,"Checking arbitrary sizes\n"); fflush(stderr); for (test=0;test max_mflops) max_mflops = mflops; } printf("%d %f\n",matdim,max_mflops); fflush(stdout); free(A); free(B); free(C); } }