/* ------ programme de test des capacites OpenMP ------ */ /* Calcul parallele sur plusieurs processeurs */ /* (C) R. Ansari LAL/IN2P3-CNRS 2000 */ #include #include #include #ifdef _OPENMP #include #endif /* Declaration de fonctions de calcul de temps CPU - timg.h .c */ void InitTim(); void PrtTim(char *); /* Declaration des fonctions de ce fichier */ void Mult(long n, double *v1, double *v2, double *v3); void MultB(long b, double *v1, double *v2, double *v3); void Check(long n, double *v3, double *v3ck); void Mult_OMP(long n, double *v1, double *v2, double *v3); void MultB_OMP(long b, double *v1, double *v2, double *v3); void MultB_OMP2(long b, double *v1, double *v2, double *v3); void MultB_OMP3(long b, double *v1, double *v2, double *v3); void getBlock(long b, long* off1, long* off2, long* off3, long* sz); /* void getBlock(long b, long& off1, long& off2, long& off3, long& sz); C++ */ void fillRandom(long n, double *v1, double *v2); /* Variables statiques globales */ static long M,N,B,BSz; static int omp_nthr = 4; /* --- main() --- */ int main (long narg, char *arg[]) { long i; double *v1, *v2, *v3, *v3ck; if (narg < 2) { printf("\n Usage tompC P/p/S/s [N BSz B OMP_NThr] (Test OpenMP) \n \n"); printf(" P /P2 /P3 -> Calling MultB_OMP /2/3 p -> Calling Mult_OMP \n"); printf(" S -> Calling MultB , s -> Calling Mult \n"); printf(" N (=10): External loop number BSz : BlockSize Size (50000) \n"); printf(" B : Nb of Blocks 100 \n"); printf(" OMP_NThr : Number of OpenMP threads (def = 4) \n \n"); return(0); } N = 10; BSz = 50000; B = 100; if (narg > 2) N = atol(arg[2]); if (narg > 3) BSz = atol(arg[3]); if (narg > 4) B = atol(arg[4]); M = B*BSz; omp_nthr = 4; if (narg > 5) omp_nthr = atol(arg[5]); printf("\n tompC : M (ArrSize)= %ld NLoop= %ld NBlock= %ld BlockSize=%ld \n", M,N,B,BSz); InitTim(); v1 = malloc (M*sizeof(double)); v2 = malloc (M*sizeof(double)); v3 = malloc (M*sizeof(double)); v3ck = malloc (M*sizeof(double)); /* Remplissage initiale */ fillRandom(M, v1, v2); Mult(M, v1, v2, v3ck); PrtTim("End of Init "); #ifdef _OPENMP if ((*arg[1] == 'P') || (*arg[1] == 'p')) { omp_set_num_threads(omp_nthr); printf(" tompC NumThreads= %d (Max=%d) NumProcs= %d \n", omp_get_num_threads(), omp_get_max_threads(), omp_get_num_procs()); } #endif /* Fonctions avec OpenMP */ if (*arg[1] == 'P') { if (*(arg[2]+1) == '2') { /* Double boucle - OpenMP parallel boucle externe */ printf("Calling N=%d times MultB_OMP2(Size= %d) \n", N, M); for(i=0; i= B) ) { /* cerr << " ERROR getBlock( b= " << b << " ??? " << endl; throw 999; C++ */ printf(" ERROR getBlock( b= %ld ???? \n", b); exit(99); } /* sz = BSz; off1 = off2 = off3 = b*BSz; C++ */ *sz = BSz; *off1 = *off2 = *off3 = b*BSz; return ; } /* --Fonction-- */ void Check(long n, double *v3, double *v3ck) /* Verification egalite v3 v3ck */ { long npb; long k; npb = 0; for(k=0; k 1.e-39) npb++; if (npb == 0) printf(" Check() - OK NPB=0 / N= %ld\n", n); /* cout << " Check() - OK NPB=0 / N= " << n << endl; C++ */ else printf(" PB Check() !!! - OK NPB= %ld / N= %ld", npb,n); /* cout << " PB Check() !!! - OK NPB= " << npb << " / N= " << n << endl; C++ */ } /* --Fonction-- */ void Mult(long n, double *v1, double *v2, double *v3) /* Multiplication - boucle simple v3 = v1*v2 */ { long k; for(k=0; k1) omp_set_num_threads((b1) private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static) #endif for(k=0; k1) omp_set_num_threads((b1) { #pragma omp single printf("MultB_OMP2() NumThr= %d \n", omp_get_num_threads()); #pragma omp for private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static) #endif for(k=0; k1) omp_set_num_threads((b1) { #pragma omp single printf("MultB_OMP3() NumThr= %d \n", omp_get_num_threads()); #pragma omp for private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static) #endif for(k=0; k