Changeset 1127 in Sophya for trunk/Eval/Speed/tompCXX.cc


Ignore:
Timestamp:
Aug 7, 2000, 10:58:19 AM (25 years ago)
Author:
ansari
Message:

Ameliorations tests OpenMP - Reza 7/8/2000

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Eval/Speed/tompCXX.cc

    r1098 r1127  
     1/* ------ programme de test des capacites OpenMP ------ */
     2/*      Calcul parallele sur plusieurs processeurs      */
     3/* (C) R. Ansari     LAL/IN2P3-CNRS           2000      */
     4
    15#include <stdlib.h>
    26#include <stdio.h>
    3 
     7#include <math.h>
     8
     9#include <iostream.h>
     10
     11#ifdef _OPENMP
     12#include <omp.h>
     13#endif
     14
     15/* Declaration de fonctions de calcul de temps CPU - timg.h .c  */
    416extern "C" {
    517void InitTim();
     
    719}
    820
    9 void Mult(int n, double *v1, double *v2, double *v3);
    10 void MultOMP(int n, double *v1, double *v2, double *v3);
    11 void MultOMP2(int N, int n, double *v1, double *v2, double *v3);
    12 
    13 int main (int narg, char *arg[])
    14 {
    15 int i,j, N, M;
    16 
    17 double *v1, *v2, *v3;
    18 
     21/* Declaration des fonctions de ce fichier */
     22void Mult(long n, double *v1, double *v2, double *v3);
     23void MultB(long b, double *v1, double *v2, double *v3);
     24void Check(long n, double *v3, double *v3ck);
     25void Mult_OMP(long n, double *v1, double *v2, double *v3);
     26void MultB_OMP(long b, double *v1, double *v2, double *v3);
     27void MultB_OMP2(long b, double *v1, double *v2, double *v3);
     28void MultB_OMP3(long b, double *v1, double *v2, double *v3);
     29// void getBlock(long b, long* off1, long* off2, long* off3, long* sz);  C
     30void getBlock(long b, long& off1, long& off2, long& off3, long& sz);
     31void fillRandom(long n, double *v1, double *v2);
     32
     33
     34/* Variables statiques globales */
     35static long M,N,B,BSz;
     36static int omp_nthr = 4;
     37
     38/* --- main() --- */
     39int main (long narg, char *arg[])
     40{
     41long i;
     42
     43double *v1, *v2, *v3, *v3ck;
    1944if (narg < 2) {
    20   printf("\n Usage tompCXX P/x [N M] \n \n");
    21   printf(" P -> Calling MultOMP2 p -> Calling MultOMP, x -> Calling Mult \n");
    22   printf(" N (=100): External loop number   M : Array Size (500000) \n");
    23   exit(0);
    24 }
    25 N = 100;
    26 M = 500000;
    27 if (narg > 2) N = atoi(arg[2]);
    28 if (narg > 3) M = atoi(arg[3]);
    29 
     45  cout << "\n Usage tompCXX P/p/S/s [N BSz B OMP_NThr]  (Test OpenMP) \n \n"
     46       << " P /P2 /P3 -> Calling MultB_OMP /2/3  p -> Calling Mult_OMP \n"
     47       << " S -> Calling MultB , s -> Calling Mult \n"
     48       << " N (=10): External loop number  BSz : BlockSize Size (50000) \n"
     49       << " B : Nb of Blocks 100 \n"
     50       << " OMP_NThr : Number of OpenMP threads (def = 4) \n " << endl;
     51  return(0);
     52}
     53
     54N = 10;
     55BSz = 50000;
     56B = 100;
     57if (narg > 2) N = atol(arg[2]);
     58if (narg > 3) BSz = atol(arg[3]);
     59if (narg > 4) B = atol(arg[4]);
     60
     61M = B*BSz;
     62
     63omp_nthr = 4;
     64if (narg > 5) omp_nthr = atol(arg[5]);
     65
     66cout << " tompCXX :  M (ArrSize)= " << M << "  NLoop=" << N << "  NBlock=" << B
     67     << " BlockSize=" << BSz << endl;
     68 
    3069InitTim();
    3170
     
    3372v2 = new double[M];
    3473v3 = new double[M];
    35 
    36  for(i=0; i<M; i++) { v1[i] = random()%1000;  v2[i] = random()%5000; }
     74v3ck = new double[M];
     75
     76/*  Remplissage initiale   */
     77fillRandom(M, v1, v2);
     78Mult(M, v1, v2, v3ck);
     79
    3780PrtTim("End of Init ");
    3881
     82#ifdef _OPENMP
     83if ((*arg[1] == 'P') || (*arg[1] == 'p'))
     84  {
     85    omp_set_num_threads(omp_nthr);
     86    printf(" tompC NumThreads= %d (Max=%d)  NumProcs= %d \n", omp_get_num_threads(),
     87           omp_get_max_threads(), omp_get_num_procs());
     88  }
     89#endif
     90
     91/*  Fonctions avec OpenMP  */
    3992if (*arg[1] == 'P') {
    40   printf("Calling MultOMP2(N=%d, Size= %d) \n", N, M);
    41   MultOMP2(N, M, v1, v2, v3);
    42 }
    43 else if (*arg[1] == 'p') {
    44   printf("Calling N=%d times MultOMP(Size= %d) \n", N, M);
    45   for(i=0; i<N; i++) MultOMP(M, v1, v2, v3);
    46 }
    47 else {
     93  if (*(arg[2]+1) == '2') {   /* Double boucle - OpenMP parallel boucle externe */
     94    printf("Calling N=%d times MultB_OMP2(Size= %d) \n", N, M);
     95    for(i=0; i<N; i++) {
     96      MultB_OMP2(B, v1, v2, v3);
     97      printf("%d ", i);  fflush(stdout);
     98    }
     99    printf("  ... Done \n"); 
     100  }
     101  else if (*(arg[2]+1) == '3') { /* Double boucle - Nested parallel */
     102    printf("Calling N=%d times MultB_OMP3(Size= %d) \n", N, M);
     103    for(i=0; i<N; i++) {
     104      MultB_OMP3(B, v1, v2, v3); 
     105      printf("%d ", i);  fflush(stdout);
     106    }
     107    printf("  ... Done \n"); 
     108  }
     109  else {  /* boucle double - OpenMP parallel boucle externe  */
     110    printf("Calling N=%d times MultB_OMP(Size= %d) \n", N, M);
     111    for(i=0; i<N; i++) {
     112      MultB_OMP(B, v1, v2, v3);
     113      printf("%d ", i);  fflush(stdout);
     114    }
     115    printf("  ... Done \n"); 
     116  }
     117}
     118 else if (*arg[1] == 'p') { /* boucle simple - OpenMP */
     119  printf("Calling N=%d times Mult_OMP(Size= %d) \n", N, M);
     120  for(i=0; i<N; i++) {
     121    Mult_OMP(M, v1, v2, v3);
     122    printf("%d ", i);  fflush(stdout);
     123    }
     124  printf("  ... Done \n"); 
     125}
     126
     127/* Fonctions SANS OpenMP (scalaire)  */
     128else if (*arg[1] == 'S') { /* Double boucle  */
     129  printf("Calling N=%d times MultB(Size= %d) \n", N, M);
     130  for(i=0; i<N; i++) {
     131    MultB(B, v1, v2, v3);
     132    printf("%d ", i);  fflush(stdout);
     133    }
     134  printf("  ... Done \n"); 
     135}
     136 else if (*arg[1] == 's') { /* Boucle simple */
    48137  printf("Calling N=%d times Mult(Size= %d) \n", N, M);
    49   for(i=0; i<N; i++) Mult(M, v1, v2, v3);
    50 }
    51 
    52 PrtTim("End of Multiplication ");
     138  for(i=0; i<N; i++) {
     139    Mult(M, v1, v2, v3);
     140    printf("%d ", i);  fflush(stdout);
     141  }
     142  printf("  ... Done \n"); 
     143}
     144
     145
     146PrtTim("End of Mult-Operation ");
     147
     148Check(M, v3, v3ck);
     149
     150PrtTim("End of programme ");
    53151
    54152delete[] v1;
    55153delete[] v2;
    56154delete[] v3;
    57 exit(0);
    58 }
    59 
    60 
    61 void Mult(int n, double *v1, double *v2, double *v3)
    62 {
    63 int k;
     155delete[] v3ck;
     156
     157return(0);
     158}
     159
     160
     161/* --Fonction-- */
     162void fillRandom(long n, double *v1, double *v2)
     163/* Remplissage aleatoire de tableaux v1 v2 */
     164{
     165  long off,nn,k,i;
     166  double x1;
     167  long nbk = (B < 20) ? 20 : B;
     168  nn = n/nbk;
     169  for(k=0; k<nn; k++) {
     170    v1[k] = random()%10000;
     171    v2[k] = random()%14000;
     172  }
     173  for(i=1; i<nbk; i++) {
     174    off = i*nn;
     175    v1[k+off] = v1[k];
     176    v2[k+off] = v2[k];
     177  }
     178  x1 = random()%18000;
     179  if (nn*nbk < n)
     180    for(k=nn*nbk; k<n; k++) v1[k] = v2[k] = x1;
     181
     182  return;
     183}
     184
     185/* --Fonction-- */
     186void  getBlock(long b, long& off1, long& off2, long& off3, long& sz) 
     187// void  getBlock(long b, long* off1, long* off2, long* off3, long* sz)
     188/* Numero , offset de blocks */
     189{
     190  if ( (b < 0) || (b >= B) ) {
     191    cerr << " ERROR getBlock( b= " << b << " ??? " << endl;
     192    throw 999;
     193    //    printf(" ERROR getBlock( b= %ld ???? \n", b);
     194    //    exit(99); 
     195  }
     196  sz = BSz;
     197  off1 = off2 = off3 = b*BSz;
     198  //  *sz = BSz;
     199  //  *off1 = *off2 = *off3 = b*BSz;
     200 
     201  return ;
     202}
     203
     204/* --Fonction-- */
     205void Check(long n, double *v3, double *v3ck)
     206/*  Verification egalite v3 v3ck */
     207{
     208long npb;
     209long k;
     210 npb = 0;
     211for(k=0; k<n; k++)
     212  if (fabs(v3[k]-v3ck[k]) > 1.e-39)  npb++;
     213
     214 if (npb == 0)
     215   //   printf("  Check() - OK   NPB=0 / N= %ld\n", n);
     216   cout << "  Check() - OK   NPB=0 / N= " << n << endl;
     217 else
     218   //   printf("  PB Check() !!! - OK   NPB= %ld / N= %ld", npb,n);
     219   cout << "  PB Check() !!! - OK   NPB= " << npb << " / N= " << n << endl;
     220}
     221
     222
     223/* --Fonction-- */
     224void Mult(long n, double *v1, double *v2, double *v3)
     225/* Multiplication - boucle simple v3 = v1*v2  */
     226{
     227long k;
    64228for(k=0; k<n; k++)
    65229  v3[k] = v1[k] * v2[k];
    66230}
    67231
    68 void MultOMP(int n, double *v1, double *v2, double *v3)
    69 {
    70 int k;
    71 #pragma omp parallel for
     232
     233/* --Fonction-- */
     234void Mult_OMP(long n, double *v1, double *v2, double *v3)
     235/* Multiplication - boucle simple - OpenMP v3 = v1*v2  */
     236{
     237long k;
     238#ifdef _OPENMP
     239omp_set_num_threads(omp_nthr);   
     240#pragma omp parallel for schedule(static)
     241#endif
    72242for(k=0; k<n; k++)
    73243  v3[k] = v1[k] * v2[k];
    74244}
    75 void MultOMP2(int N, int n, double *v1, double *v2, double *v3)
    76 {
    77 int k;
    78 int i;
    79 #pragma omp parallel default(shared)
    80  {
    81 #pragma omp parallel for
    82 for(i=0; i<N; i++)
    83 #pragma omp parallel for
    84   for(k=0; k<n; k++)
    85      v3[k] = v1[k] * v2[k];
    86  }
    87 }
     245
     246
     247/* --Fonction-- */
     248void MultB(long b, double *vv1, double *vv2, double *vv3)
     249/* Multiplication - boucle double (par block) v3 = v1*v2  */
     250{
     251  long k,i;
     252  long sz, off1,off2,off3;
     253  double *v1, *v2, *v3;
     254  for(k=0; k<b; k++) {
     255    //    getBlock(k, &off1, &off2, &off3, &sz);
     256    getBlock(k, off1, off2, off3, sz);
     257    v1 = vv1+off1;
     258    v2 = vv2+off2;
     259    v3 = vv3+off3;
     260    for(i=0; i<sz; i++)
     261      v3[i] = v1[i] * v2[i];
     262  }
     263}
     264
     265/* --Fonction-- */
     266void MultB_OMP(long b, double *vv1, double *vv2, double *vv3)
     267/* Multiplication - boucle double (par block) - OpenMP v3 = v1*v2  */
     268{
     269  long k,i,ub;
     270  long sz, off1,off2,off3;
     271  double *v1, *v2, *v3;
     272
     273  ub = b;
     274#ifdef _OPENMP
     275  if (b>1)
     276    omp_set_num_threads((b<omp_nthr)?b:omp_nthr);   
     277#pragma omp parallel for if(b>1) private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static)
     278#endif
     279  for(k=0; k<ub; k++) {
     280    //    getBlock(k, &off1, &off2, &off3, &sz);
     281    getBlock(k, off1, off2, off3, sz);
     282    v1 = vv1+off1;
     283    v2 = vv2+off2;
     284    v3 = vv3+off3;
     285    for(i=0; i<sz; i++)
     286      v3[i] = v1[i] * v2[i];
     287  }
     288}
     289
     290/* --Fonction-- */
     291void MultB_OMP2(long b, double *vv1, double *vv2, double *vv3)
     292/* Multiplication - boucle double (par block) - OpenMP v3 = v1*v2  */
     293{
     294  long k,i;
     295  long sz, off1,off2,off3;
     296  double *v1, *v2, *v3;
     297#ifdef _OPENMP
     298  if (b>1)
     299    omp_set_num_threads((b<omp_nthr)?b:omp_nthr);   
     300#pragma omp  parallel  if(b>1)
     301{
     302#pragma omp  single
     303  printf("MultB_OMP2()  NumThr= %d \n", omp_get_num_threads());
     304#pragma omp for private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static)
     305#endif
     306  for(k=0; k<b; k++) {
     307    //    getBlock(k, &off1, &off2, &off3, &sz);
     308    getBlock(k, off1, off2, off3, sz);
     309    v1 = vv1+off1;
     310    v2 = vv2+off2;
     311    v3 = vv3+off3;
     312    for(i=0; i<sz; i++)
     313      v3[i] = v1[i] * v2[i];
     314  }
     315#ifdef _OPENMP
     316}
     317#endif
     318
     319}
     320
     321/* --Fonction-- */
     322void MultB_OMP3(long b, double *vv1, double *vv2, double *vv3)
     323/* Multiplication - boucle double (par block) - OpenMP v3 = v1*v2  */
     324{
     325  long k,i;
     326  long sz, off1,off2,off3;
     327  double *v1, *v2, *v3;
     328#ifdef _OPENMP
     329  if (b>1)
     330    omp_set_num_threads((b<omp_nthr)?b:omp_nthr);   
     331#pragma omp  parallel  if(b>1)
     332{
     333#pragma omp  single
     334  printf("MultB_OMP3()  NumThr= %d \n", omp_get_num_threads());
     335#pragma omp for private(v1,v2,v3,k,i,off1,off2,off3,sz) schedule(static)
     336#endif
     337  for(k=0; k<b; k++) {
     338    //    getBlock(k, &off1, &off2, &off3, &sz);
     339    getBlock(k, off1, off2, off3, sz);
     340    v1 = vv1+off1;
     341    v2 = vv2+off2;
     342    v3 = vv3+off3;
     343#ifdef _OPENMP
     344#pragma omp  parallel 
     345{
     346#pragma omp  single
     347  if (k==0) printf("MultB_OMP3() -pragma2- NumThr= %d \n", omp_get_num_threads());
     348#pragma omp for private(i) schedule(static)
     349#endif
     350    for(i=0; i<sz; i++)
     351      v3[i] = v1[i] * v2[i];
     352#ifdef _OPENMP
     353}
     354#endif
     355  }
     356#ifdef _OPENMP
     357}
     358#endif
     359
     360}
     361
Note: See TracChangeset for help on using the changeset viewer.