1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include "ga.h"
5 #include "macdecls.h"
6 #include "testutil.h"
7 #define MPI
8 
9 #ifdef MPI
10 #  include <mpi.h>
11 #else
12 #  include <tcgmsg.h>
13 #endif
14 
15 #define MAXDIM 10
16 #define BASE 100
17 
18 #if defined(WIN32)
19 #  include <windows.h>
20 #  define sleep(x) Sleep(1000*(x))
21 #else
22 #include <unistd.h>
23 #endif
24 
25 /***************************** macros ************************/
26 #define COPY(src, dst, bytes) memcpy((dst),(src),(bytes))
27 #define MAX(a,b) (((a) >= (b)) ? (a) : (b))
28 #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
29 #define ABS(a) (((a) <0) ? -(a) : (a))
30 
31 
32 
ext_malloc(size_t bytes,int align,char * name)33 void *ext_malloc(size_t bytes, int align, char *name) {
34   return malloc(bytes);
35 }
36 
ext_free(void * ptr)37 void ext_free(void *ptr) {
38   free(ptr);
39 }
40 
41 /* void FATR register_ext_memory_() {
42   GA_Register_stack_memory(ext_malloc, ext_free);
43 }*/
44 
45 
46 /*\ generate random range for a section of multidimensional array
47 \*/
get_range(int ndim,int dims[],int lo[],int hi[])48 void get_range( int ndim, int dims[], int lo[], int hi[])
49 {
50 	int dim;
51 	for(dim=0; dim <ndim;dim++){
52 		int toss1, toss2;
53 		toss1 = rand()%dims[dim];
54 		toss2 = rand()%dims[dim];
55 		if(toss1<toss2){
56 			lo[dim]=toss1;
57 			hi[dim]=toss2;
58 		}else {
59   			hi[dim]=toss1;
60 			lo[dim]=toss2;
61 		}
62     }
63 }
64 
65 
66 
67 
68 /*\ generates a new random range similar (same size, different indices)
69  *  to the input range for an array with specified dimensions
70 \*/
new_range(int ndim,int dims[],int lo[],int hi[],int new_lo[],int new_hi[])71 void new_range(int ndim, int dims[], int lo[], int hi[],
72                              int new_lo[], int new_hi[])
73 {
74 	int dim;
75 	for(dim=0; dim <ndim;dim++){
76 		int toss, range;
77 		int diff = hi[dim] -lo[dim]+1;
78 		assert(diff <= dims[dim]);
79                 range = dims[dim]-diff;
80                 toss = (range > 0)? rand()%range : lo[dim];
81 		new_lo[dim] = toss;
82 		new_hi[dim] = toss + diff -1;
83 		assert(new_hi[dim] < dims[dim]);
84 		assert(diff == (new_hi[dim] -new_lo[dim]+1));
85 	}
86 }
87 
88 
89 
90 
91 
92 /*\ print range of n-dimensional array with two strings before and after
93 \*/
print_range(char * pre,int ndim,int lo[],int hi[],char * post)94 void print_range(char *pre,int ndim, int lo[], int hi[], char* post)
95 {
96 	int i;
97 
98 	printf("%s[",pre);
99 	for(i=0;i<ndim;i++){
100 		printf("%d:%d",lo[i],hi[i]);
101 		if(i==ndim-1)printf("] %s",post);
102 		else printf(",");
103 	}
104 }
105 
106 /*\ print subscript of ndim dimensional array with two strings before and after
107 \*/
print_subscript(char * pre,int ndim,int subscript[],char * post)108 void print_subscript(char *pre,int ndim, int subscript[], char* post)
109 {
110 	int i;
111 
112 	printf("%s [",pre);
113 	for(i=0;i<ndim;i++){
114 		printf("%d",subscript[i]);
115 		if(i==ndim-1)printf("] %s",post);
116 		else printf(",");
117 	}
118 }
119 
120 
121 /*\ print a section of a 2-D array of doubles
122 \*/
print_2D_double(double * a,int ld,int * lo,int * hi)123 void print_2D_double(double *a, int ld, int *lo, int *hi)
124 {
125 int i,j;
126      for(i=lo[0];i<=hi[0];i++){
127        for(j=lo[1];j<=hi[1];j++) printf("%13f ",a[ld*j+i]);
128        printf("\n");
129      }
130 }
131 
132 
133 /*\ initialize array: a[i,j,k,..]=i+100*j+10000*k+ ...
134 \*/
init_array(double * a,int ndim,int dims[])135 void init_array(double *a, int ndim, int dims[])
136 {
137 	int idx[MAXDIM];
138 	int i,dim, elems;
139 
140         elems = 1;
141         for(i=0;i<ndim;i++)elems *= dims[i];
142 
143  	for(i=0; i<elems; i++){
144 		int Index = i;
145 		double field, val;
146 
147 		for(dim = 0; dim < ndim; dim++){
148 			idx[dim] = Index%dims[dim];
149 			Index /= dims[dim];
150 		}
151 
152                 field=1.; val=0.;
153 		for(dim=0; dim< ndim;dim++){
154 			val += field*idx[dim];
155 			field *= BASE;
156 		}
157 		a[i] = val;
158 		/* printf("(%d,%d,%d)=%6.0f",idx[0],idx[1],idx[2],val); */
159 	}
160 }
161 
162 
163 /*\ compute Index from subscript
164  *  assume that first subscript component changes first
165 \*/
Index(int ndim,int subscript[],int dims[])166 int Index(int ndim, int subscript[], int dims[])
167 {
168 	int idx = 0, i, factor=1;
169 	for(i=0;i<ndim;i++){
170 		idx += subscript[i]*factor;
171 		factor *= dims[i];
172 	}
173 	return idx;
174 }
175 
176 
update_subscript(int ndim,int subscript[],int lo[],int hi[],int dims[])177 void update_subscript(int ndim, int subscript[], int lo[], int hi[], int dims[])
178 {
179 	int i;
180 	for(i=0;i<ndim;i++){
181 		if(subscript[i] < hi[i]) { subscript[i]++; return; }
182 		subscript[i] = lo[i];
183 	}
184 }
185 
186 
187 
compare_patches(int me,double eps,int ndim,double * array1,int lo1[],int hi1[],int dims1[],double * array2,int lo2[],int hi2[],int dims2[])188 int compare_patches(int me, double eps, int ndim, double *array1,
189                      int lo1[], int hi1[], int dims1[],
190 		     double *array2, int lo2[], int hi2[],
191                      int dims2[])
192 {
193 	int i,j, elems=1;
194 	int subscr1[MAXDIM], subscr2[MAXDIM];
195         double diff,max;
196         double *patch1, *patch2;
197 
198         /* compute pointer to first element in patch */
199 	patch1 = array1 +  Index(ndim, lo1, dims1);
200 	patch2 = array2 +  Index(ndim, lo2, dims2);
201 
202         /* count # of elements & verify consistency of both patches */
203 	for(i=0;i<ndim;i++){
204 		Integer diff = hi1[i]-lo1[i];
205 		assert(diff == (hi2[i]-lo2[i]));
206 		assert(diff < dims1[i]);
207 		assert(diff < dims2[i]);
208 		elems *= diff+1;
209 		subscr1[i]= lo1[i];
210 		subscr2[i]=lo2[i];
211 	}
212 
213 	/* compare element values in both patches */
214 	for(j=0; j< elems; j++){
215 		Integer idx1, idx2, offset1, offset2;
216                 /* calculate element Index from a subscript */
217 		idx1 = Index(ndim, subscr1, dims1);
218 		idx2 = Index(ndim, subscr2, dims2);
219 
220 		if(j==0){
221 			offset1 =idx1;
222 			offset2 =idx2;
223 		}
224 		idx1 -= offset1;
225 		idx2 -= offset2;
226 
227                 diff = patch1[idx1] - patch2[idx2];
228                 max  = MAX(ABS(patch1[idx1]),ABS(patch2[idx2]));
229                 if(max == 0. || max <eps) max = 1.;
230 
231 		if(eps < ABS(diff)/max){
232 			char msg[48], val[48];
233 			sprintf(msg,"ERROR (proc=%d): a",me);
234 			sprintf(val,"=%lf, ",patch1[idx1]);
235 			print_subscript(msg,ndim,subscr1,val);
236 			sprintf(msg,"=%lf\n",patch2[idx2]);
237 			print_subscript(" b",ndim,subscr2,msg);
238                         sleep(1);
239                         return(1);
240 		}
241 
242 		{ /* update subscript for the patches */
243 		   update_subscript(ndim, subscr1, lo1,hi1, dims1);
244 		   update_subscript(ndim, subscr2, lo2,hi2, dims2);
245 		}
246 	}
247 
248         return(0);
249 }
250 
251 
f2c_adj_indices(Integer fsubscript[],int csubscript[],int n)252 void f2c_adj_indices(Integer fsubscript[], int csubscript[], int n)
253 {
254 int i;
255     for(i=0;i<n; i++)csubscript[i]=(int)fsubscript[i] -1;
256 }
257 
f2c_copy_indices(Integer fsubscript[],int csubscript[],int n)258 void f2c_copy_indices(Integer fsubscript[], int csubscript[], int n)
259 {
260 int i;
261     for(i=0;i<n; i++)csubscript[i]=(int)fsubscript[i];
262 }
263 
264 
compare_patches_(Integer * me,double * eps,Integer * ndim,double * array1,Integer LO1[],Integer HI1[],Integer DIMS1[],double * array2,Integer LO2[],Integer HI2[],Integer DIMS2[])265 Integer FATR compare_patches_(Integer *me,
266                      double* eps, Integer *ndim, double *array1,
267                      Integer LO1[], Integer HI1[], Integer DIMS1[],
268                      double *array2, Integer LO2[], Integer HI2[],
269                      Integer DIMS2[])
270 {
271 int hi1[MAXDIM], lo1[MAXDIM], dims1[MAXDIM];
272 int hi2[MAXDIM], lo2[MAXDIM], dims2[MAXDIM];
273 
274     assert((int)*ndim < MAXDIM);
275 
276     f2c_adj_indices(HI1, hi1, (int)*ndim);
277     f2c_adj_indices(HI2, hi2, (int)*ndim);
278     f2c_adj_indices(LO1, lo1, (int)*ndim);
279     f2c_adj_indices(LO2, lo2, (int)*ndim);
280     f2c_copy_indices(DIMS1, dims1, (int)*ndim);
281     f2c_copy_indices(DIMS2, dims2, (int)*ndim);
282 
283     return (Integer) compare_patches((int)*me, *eps, (int)*ndim,
284                      array1, lo1, hi1, dims1, array2, lo2, hi2, dims2);
285 }
286 
287 
288 
scale_patch(double alpha,int ndim,double * patch1,int lo1[],int hi1[],int dims1[])289 void scale_patch(double alpha, int ndim, double *patch1,
290                  int lo1[], int hi1[], int dims1[])
291 {
292 	int i,j, elems=1;
293 	int subscr1[MAXDIM];
294 
295 	for(i=0;i<ndim;i++){   /* count # of elements in patch */
296 		int diff = hi1[i]-lo1[i];
297 		assert(diff < dims1[i]);
298 		elems *= diff+1;
299 		subscr1[i]= lo1[i];
300 	}
301 
302 	/* scale element values in both patches */
303 	for(j=0; j< elems; j++){
304 		Integer idx1, offset1;
305 
306                 /* calculate element Index from a subscript */
307 		idx1 = Index(ndim, subscr1, dims1);
308 
309 		if(j==0){
310 			offset1 =idx1;
311 		}
312 		idx1 -= offset1;
313 
314 		patch1[idx1] *= alpha;
315 		update_subscript(ndim, subscr1, lo1,hi1, dims1);
316 	}
317 }
318 
319 
scale_patch_(double * alpha,Integer * ndim,double * patch1,Integer LO1[],Integer HI1[],Integer DIMS1[])320 void FATR scale_patch_(double *alpha, Integer *ndim, double *patch1,
321                  Integer LO1[], Integer HI1[], Integer DIMS1[])
322 {
323 int hi1[MAXDIM], lo1[MAXDIM], dims1[MAXDIM];
324 
325     assert((int)*ndim < MAXDIM);
326     f2c_adj_indices(HI1, hi1, (int)*ndim);
327     f2c_adj_indices(LO1, lo1, (int)*ndim);
328     f2c_copy_indices(DIMS1, dims1, (int)*ndim);
329     scale_patch(*alpha, (int)*ndim, patch1, lo1, hi1, dims1);
330 }
331 
332 
init_array_(double * a,Integer * ndim,Integer DIMS[])333 void FATR init_array_(double *a, Integer *ndim, Integer DIMS[])
334 {
335 int dims[MAXDIM];
336     assert((int)*ndim < MAXDIM);
337 
338     f2c_copy_indices(DIMS, dims, (int)*ndim);
339     init_array(a, (int)*ndim, dims);
340 }
341 
print_range_(Integer * me,Integer LO[],Integer HI[],Integer * ndim)342 void FATR print_range_(Integer *me, Integer LO[], Integer HI[], Integer *ndim)
343 {
344 int hi[MAXDIM], lo[MAXDIM];
345 char msg[100];
346 
347     assert((int)*ndim < MAXDIM);
348     sprintf(msg,"%d: array section ",(int)*me);
349     f2c_copy_indices(HI, hi, (int)*ndim);
350     f2c_copy_indices(LO, lo, (int)*ndim);
351     print_range(msg,(int)*ndim, lo, hi, "\n");
352 }
353 
copy_range_(Integer * me,Integer LO1[],Integer HI1[],Integer * ndim1,Integer LO2[],Integer HI2[],Integer * ndim2)354 void FATR copy_range_(Integer *me, Integer LO1[], Integer HI1[], Integer *ndim1, Integer LO2[], Integer HI2[], Integer *ndim2)
355 {
356 int hi1[MAXDIM], lo1[MAXDIM], hi2[MAXDIM], lo2[MAXDIM];
357 char msg[100];
358 
359     assert((int)*ndim1 < MAXDIM);
360     assert((int)*ndim2 < MAXDIM);
361     sprintf(msg,"%d: copy ",(int)*me);
362     f2c_copy_indices(HI1, hi1, (int)*ndim1);
363     f2c_copy_indices(LO1, lo1, (int)*ndim1);
364     print_range(msg,(int)*ndim1, lo1, hi1, "");
365     sprintf(msg,"to ");
366     f2c_copy_indices(HI2, hi2, (int)*ndim2);
367     f2c_copy_indices(LO2, lo2, (int)*ndim2);
368     print_range(msg,(int)*ndim2, lo2, hi2, "\n");
369 }
370 
add_range_(Integer * me,Integer LO1[],Integer HI1[],Integer * ndim1,Integer LO2[],Integer HI2[],Integer * ndim2)371 void FATR add_range_(Integer *me, Integer LO1[], Integer HI1[], Integer *ndim1, Integer LO2[], Integer HI2[], Integer *ndim2)
372 {
373 int hi1[MAXDIM], lo1[MAXDIM], hi2[MAXDIM], lo2[MAXDIM];
374 char msg[100];
375 
376     assert((int)*ndim1 < MAXDIM);
377     assert((int)*ndim2 < MAXDIM);
378     sprintf(msg,"%d: ",(int)*me);
379     f2c_copy_indices(HI1, hi1, (int)*ndim1);
380     f2c_copy_indices(LO1, lo1, (int)*ndim1);
381     print_range(msg,(int)*ndim1, lo1, hi1, "");
382     sprintf(msg,"+= ");
383     f2c_copy_indices(HI2, hi2, (int)*ndim2);
384     f2c_copy_indices(LO2, lo2, (int)*ndim2);
385     print_range(msg,(int)*ndim2, lo2, hi2, "\n");
386 }
387 
dot_range_(Integer * me,Integer LO1[],Integer HI1[],Integer * ndim1,Integer LO2[],Integer HI2[],Integer * ndim2)388 void FATR dot_range_(Integer *me, Integer LO1[], Integer HI1[], Integer *ndim1, Integer LO2[], Integer HI2[], Integer *ndim2)
389 {
390 int hi1[MAXDIM], lo1[MAXDIM], hi2[MAXDIM], lo2[MAXDIM];
391 char msg[100];
392 
393     assert((int)*ndim1 < MAXDIM);
394     assert((int)*ndim2 < MAXDIM);
395     sprintf(msg,"%d: dot ",(int)*me);
396     f2c_copy_indices(HI1, hi1, (int)*ndim1);
397     f2c_copy_indices(LO1, lo1, (int)*ndim1);
398     print_range(msg,(int)*ndim1, lo1, hi1, "");
399     sprintf(msg,", ");
400     f2c_copy_indices(HI2, hi2, (int)*ndim2);
401     f2c_copy_indices(LO2, lo2, (int)*ndim2);
402     print_range(msg,(int)*ndim2, lo2, hi2, "\n");
403 }
404 
405 
406 /*
407  * Return the no. of bytes that n doubles occupy
408  */
util_mdtob_(Integer * n)409 Integer FATR util_mdtob_(Integer *n)
410 {
411   if (*n < 0)
412     GA_Error("util_MDTOB_: negative argument",*n);
413 
414   return (Integer) (*n * sizeof(double));
415 }
416 
417 
418 /*
419  * Return the no. of bytes that n ints=Integers occupy
420  */
util_mitob_(Integer * n)421 Integer FATR util_mitob_(Integer *n)
422 {
423   if (*n < 0)
424     GA_Error("util_MITOB_: negative argument",*n);
425 
426   return (Integer) (*n * sizeof(Integer));
427 }
428 
429 
_util_ran(unsigned int flag)430 double _util_ran(unsigned int flag)
431 {
432   static unsigned long seed = 76521;
433 
434   if(flag != 0) seed = flag;
435   seed = seed *1812433253 + 12345;
436 
437   return ((double) (seed & 0x7fffffff)) * 4.6566128752458e-10;
438 }
439 
440 
util_drand_(Integer * flag)441 double FATR util_drand_(Integer* flag)
442 {
443 /* on YMP/J90 need to use thread safe version of rand */
444     unsigned long fflag = (unsigned long)*flag;
445 #ifdef CRAY_YMP
446 
447   return _util_ran((unsigned int)fflag);
448 
449 #else
450 
451 #if defined(LINUX) || defined(SOLARIS)
452   if (fflag) srandom((unsigned) fflag);
453   return ((double) random()) * 4.6566128752458e-10;
454 #else
455   if (fflag) srand((unsigned) fflag);
456   return ((double) rand()) * 4.6566128752458e-10;
457 #endif
458 
459 #endif
460 }
461 
util_timer_()462 double FATR util_timer_()
463 {
464 #ifdef MPI
465        return MPI_Wtime();
466 #else
467        return tcg_time();
468 #endif
469 }
470 
471 
472 /* $Id$ */
473