source: Sophya/trunk/Eval/Speed/tompCXX.cc@ 2365

Last change on this file since 2365 was 1572, checked in by ansari, 24 years ago

declaration de const char * pour PrtTim() - Reza 12/7/2001

File size: 8.7 KB
Line 
1/* ------ programme de test des capacites OpenMP ------ */
2/* Calcul parallele sur plusieurs processeurs */
3/* (C) R. Ansari LAL/IN2P3-CNRS 2000 */
4
5#include <stdlib.h>
6#include <stdio.h>
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 */
16extern "C" {
17void InitTim();
18void PrtTim(const char *);
19}
20
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;
44if (narg < 2) {
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
69InitTim();
70
71v1 = new double[M];
72v2 = new double[M];
73v3 = new double[M];
74v3ck = new double[M];
75
76/* Remplissage initiale */
77fillRandom(M, v1, v2);
78Mult(M, v1, v2, v3ck);
79
80PrtTim("End of Init ");
81
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 */
92if (*arg[1] == 'P') {
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 */
137 printf("Calling N=%d times Mult(Size= %d) \n", N, M);
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 ");
151
152delete[] v1;
153delete[] v2;
154delete[] v3;
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;
228for(k=0; k<n; k++)
229 v3[k] = v1[k] * v2[k];
230}
231
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
242for(k=0; k<n; k++)
243 v3[k] = v1[k] * v2[k];
244}
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 TracBrowser for help on using the repository browser.