/******************************************************************** This benchmark test program is measuring a cpu performance of floating point operation by a Poisson equation solver. If you have any question, please ask me via email. written by Ryutaro HIMENO, November 26, 2001. Version 3.0 ---------------------------------------------- Ryutaro Himeno, Dr. of Eng. Head of Computer Information Division, RIKEN (The Institute of Pysical and Chemical Research) Email : himeno@postman.riken.go.jp --------------------------------------------------------------- You can adjust the size of this benchmark code to fit your target computer. In that case, please chose following sets of (mimax,mjmax,mkmax): small : 33,33,65 small : 65,65,129 midium: 129,129,257 large : 257,257,513 ext.large: 513,513,1025 This program is to measure a computer performance in MFLOPS by using a kernel which appears in a linear solver of pressure Poisson eq. which appears in an incompressible Navier-Stokes solver. A point-Jacobi method is employed in this solver as this method can be easyly vectrized and be parallelized. ------------------ Finite-difference method, curvilinear coodinate system Vectorizable and parallelizable on each grid point No. of grid points : imax x jmax x kmax including boundaries ------------------ A,B,C:coefficient matrix, wrk1: source term of Poisson equation wrk2 : working area, OMEGA : relaxation parameter BND:control variable for boundaries and objects ( = 0 or 1) P: pressure ********************************************************************/ #include #include #ifdef SSMALL #define MIMAX 33 #define MJMAX 33 #define MKMAX 65 #endif #ifdef SMALL #define MIMAX 65 #define MJMAX 65 #define MKMAX 129 #endif #ifdef MIDDLE #define MIMAX 129 #define MJMAX 129 #define MKMAX 257 #endif #ifdef LARGE #define MIMAX 257 #define MJMAX 257 #define MKMAX 513 #endif #ifdef ELARGE #define MIMAX 513 #define MJMAX 513 #define MKMAX 1025 #endif double second(); float jacobi(int); void initmt(); double fflop(int,int,int); double mflops(int,double,double); static float p[MIMAX][MJMAX][MKMAX]; static float a[4][MIMAX][MJMAX][MKMAX], b[3][MIMAX][MJMAX][MKMAX], c[3][MIMAX][MJMAX][MKMAX]; static float bnd[MIMAX][MJMAX][MKMAX]; static float wrk1[MIMAX][MJMAX][MKMAX], wrk2[MIMAX][MJMAX][MKMAX]; static int imax, jmax, kmax; static float omega; int main() { int i,j,k,nn; float gosa; double cpu,cpu0,cpu1,flop,target; target= 60.0; omega= 0.8; imax = MIMAX-1; jmax = MJMAX-1; kmax = MKMAX-1; #ifdef _OPENACC acc_set_device( acc_device_nvidia ); acc_init( acc_device_nvidia ); #endif /* * Initializing matrixes */ #pragma acc data create(a,b,c,bnd,wrk1,wrk2) copyout(p) { initmt(); printf("mimax = %d mjmax = %d mkmax = %d\n",MIMAX, MJMAX, MKMAX); printf("imax = %d jmax = %d kmax =%d\n",imax,jmax,kmax); nn= 3; printf(" Start rehearsal measurement process.\n"); printf(" Measure the performance in %d times.\n\n",nn); cpu0= second(); gosa= jacobi(nn); cpu1= second(); cpu= cpu1 - cpu0; flop= fflop(imax,jmax,kmax); printf(" MFLOPS: %f time(s): %f %e\n\n", mflops(nn,cpu,flop),cpu,gosa); /* nn= (int)(target/(cpu/3.0)); */ nn = 800; printf(" Now, start the actual measurement process.\n"); printf(" The loop will be excuted in %d times\n",nn); printf(" This will take about one minute.\n"); printf(" Wait for a while\n\n"); /* * Start measuring */ cpu0 = second(); gosa = jacobi(nn); cpu1 = second(); cpu= cpu1 - cpu0; } /* End openACC data region */ printf(" Loop executed for %d times\n",nn); printf(" Gosa : %e \n",gosa); printf(" MFLOPS measured : %f\tcpu : %f\n",mflops(nn,cpu,flop),cpu); printf(" Score based on Pentium III 600MHz : %f\n", mflops(nn,cpu,flop)/82,84); return (0); } void initmt() { int i,j,k; #pragma acc data present(a,b,c,p,bnd,wrk1) { #pragma acc kernels loop gang for(i=0 ; i ss*ss) ? a : b; */ wrk2[i][j][k] = p[i][j][k] + omega * ss; } } } #pragma acc kernels loop gang for(i=1 ; i struct timeval tm; double t ; static int base_sec = 0,base_usec = 0; gettimeofday(&tm, NULL); if(base_sec == 0 && base_usec == 0) { base_sec = tm.tv_sec; base_usec = tm.tv_usec; t = 0.0; } else { t = (double) (tm.tv_sec-base_sec) + ((double) (tm.tv_usec-base_usec))/1.0e6 ; } return t ; }