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