SCALAPACK 2.2.2
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
pdtrmrdrv.c
Go to the documentation of this file.
1#include "redist.h"
2/* $Id: pdtrmrdrv.c,v 1.1.1.1 2000/02/15 18:04:11 susan Exp $
3 *
4 * pdtrmrdrv.c :
5 *
6 *
7 * PURPOSE:
8 *
9 * this driver is testing the PDTRMR2D routine. It calls it to obtain a new
10 * scattered block data decomposition of a distributed DOUBLE PRECISION
11 * (block scattered) matrix. Then it calls PDTRMR2D for the inverse
12 * redistribution and checks the results with the initial data.
13 *
14 * Data are going from a Block Scattered nbrow0 x nbcol0 decomposition on the
15 * processor grid p0 x q0, to data distributed in a BS nbrow1 x nbcol1 on the
16 * processor grid p1 x q1, then back to the BS nbrow0 x nbcol0 decomposition
17 * on the processor grid p0 x q0.
18 *
19 * See pdtrmr.c file for detailed info on the PDTRMR2D function.
20 *
21 *
22 * The testing parameters are read from the file TRMR2D.dat, see the file in the
23 * distribution to have an example.
24 *
25 * created by Bernard Tourancheau in April 1994.
26 *
27 * modifications : see sccs history
28 *
29 * ===================================
30 *
31 *
32 * NOTE :
33 *
34 * - the matrix elements are DOUBLE PRECISION
35 *
36 * - memory requirements : this procedure requires approximately 3 times the
37 * memory space of the initial data block in grid 0 (initial block, copy for
38 * test and second redistribution result) and 1 time the memory space of the
39 * result data block in grid 1. with the element size = sizeof(double)
40 * bytes,
41 *
42 *
43 * - use the procedures of the files:
44 *
45 * pdtrmr.o pdtrmr2.o pdtrmraux.o
46 *
47 *
48 * ======================================
49 *
50 * WARNING ASSUMPTIONS :
51 *
52 *
53 * ========================================
54 *
55 *
56 * Planned changes:
57 *
58 *
59 *
60 * ========================================= */
61#define static2 static
62#if defined(Add_) || defined(f77IsF2C)
63#define fortran_mr2d pdtrmr2do_
64#define fortran_mr2dnew pdtrmr2d_
65#elif defined(UpCase)
66#define fortran_mr2dnew PDTRMR2D
67#define fortran_mr2d PDTRMR2DO
68#define dcopy_ DCOPY
69#define dlacpy_ DLACPY
70#else
71#define fortran_mr2d pdtrmr2do
72#define fortran_mr2dnew pdtrmr2d
73#define dcopy_ dcopy
74#define dlacpy_ dlacpy
75#endif
76#define Clacpy Cdtrlacpy
77void Clacpy();
78typedef struct {
79 Int desctype;
80 Int ctxt;
81 Int m;
82 Int n;
83 Int nbrow;
84 Int nbcol;
85 Int sprow;
86 Int spcol;
87 Int lda;
88} MDESC;
89#define BLOCK_CYCLIC_2D 1
90typedef struct {
91 Int gstart;
92 Int len;
93} IDESC;
94#define SHIFT(row,sprow,nbrow) ((row)-(sprow)+ ((row) >= (sprow) ? 0 : (nbrow)))
95#define max(A,B) ((A)>(B)?(A):(B))
96#define min(A,B) ((A)>(B)?(B):(A))
97#define DIVUP(a,b) ( ((a)-1) /(b)+1)
98#define ROUNDUP(a,b) (DIVUP(a,b)*(b))
99#ifdef MALLOCDEBUG
100#define malloc mymalloc
101#define free myfree
102#define realloc myrealloc
103#endif
104/* Cblacs */
105extern void Cblacs_pcoord();
107extern void Csetpvmtids();
108extern void Cblacs_get();
109extern void Cblacs_pinfo();
110extern void Cblacs_gridinfo();
111extern void Cblacs_gridinit();
112extern void Cblacs_exit();
113extern void Cblacs_gridexit();
114extern void Cblacs_setup();
115extern void Cigebs2d();
116extern void Cigebr2d();
117extern void Cigesd2d();
118extern void Cigerv2d();
119extern void Cigsum2d();
120extern void Cigamn2d();
121extern void Cigamx2d();
122extern void Cdgesd2d();
123extern void Cdgerv2d();
124/* lapack */
125void dlacpy_();
126/* aux fonctions */
128extern void *mr2d_malloc();
129extern Int ppcm();
130extern Int localsize();
133extern void paramcheck();
134/* tools and others function */
135#define scanD0 dtrscanD0
136#define dispmat dtrdispmat
137#define setmemory dtrsetmemory
138#define freememory dtrfreememory
139#define scan_intervals dtrscan_intervals
140extern void scanD0();
141extern void dispmat();
142extern void setmemory();
143extern void freememory();
144extern Int scan_intervals();
145extern void Cpdtrmr2do();
146extern void Cpdtrmr2d();
147/* some defines for Cpdtrmr2do */
148#define SENDBUFF 0
149#define RECVBUFF 1
150#define SIZEBUFF 2
151#if 0
152#define DEBUG
153#endif
154#ifndef DEBUG
155#define NDEBUG
156#endif
157#include <stdio.h>
158#include <stdlib.h>
159#include <string.h>
160#include <ctype.h>
161#include <assert.h>
162/* initblock: intialize the local part of a matrix with random data (well,
163 * not very random) */
164static2 void
165initblock(double *block, Int m, Int n)
166{
167 double *pdata;
168 Int i;
169 pdata = block;
170 for (i = 0; i < m * n; i++, pdata++) {
171 (*pdata) = i;
172 };
173}
174/* getparam:read from a file a list of integer parameters, the end of the
175 * parameters to read is given by a NULL at the end of the args list */
176#ifdef __STDC__
177#include <stdarg.h>
178static void
179getparam(FILE * f,...)
180{
181#else
182#include <varargs.h>
183static void
184getparam(va_alist)
185va_dcl
186{
187 FILE *f;
188#endif
189 va_list ap;
190 Int i;
191 static Int nbline;
192 char *ptr, *next;
193 Int *var;
194 static char buffer[200];
195#ifdef __STDC__
196 va_start(ap, f);
197#else
198 va_start(ap);
199 f = va_arg(ap, FILE *);
200#endif
201 do {
202 next = fgets(buffer, 200, f);
203 if (next == NULL) {
204 fprintf(stderr, "bad configuration driver file:after line %d\n", nbline);
205 exit(1);
206 }
207 nbline += 1;
208 } while (buffer[0] == '#');
209 ptr = buffer;
210 var = va_arg(ap, Int *);
211 while (var != NULL) {
212 *var = strtol(ptr, &next, 10);
213 if (ptr == next) {
214 fprintf(stderr, "bad configuration driver file:error line %d\n", nbline);
215 exit(1);
216 }
217 ptr = next;
218 var = va_arg(ap, Int *);
219 }
220 va_end(ap);
221}
222void
223initforpvm(Int argc, char *argv[])
224{
225 Int pnum, nproc;
226 Cblacs_pinfo(&pnum, &nproc);
227 if (nproc < 1) { /* we are with PVM */
228 if (pnum == 0) {
229 if (argc < 2) {
230 fprintf(stderr, "usage with PVM:xdtrmr nbproc\n\
231\t where nbproc is the number of nodes to initialize\n");
232 exit(1);
233 }
234 nproc = atoi(argv[1]);
235 }
236 Cblacs_setup(&pnum, &nproc);
237 }
238}
239int
240main(int argc, char *argv[])
241{
242 /* We initialize the data-block on the current processor, then redistribute
243 * it, and perform the inverse redistribution to compare the local memory
244 * with the initial one. */
245 /* Data file */
246 FILE *fp;
247 Int nbre, nbremax;
248 /* Data distribution 0 parameters */
249 Int p0, /* # of rows in the processor grid */
250 q0; /* # of columns in the processor grid */
251 /* Data distribution 1 parameters */
252 Int p1, q1;
253 /* # of parameter to be read on the keyboard */
254#define nbparameter 24
255 /* General variables */
256 Int blocksize0;
257 Int mypnum, nprocs;
258 Int parameters[nbparameter], nberrors;
259 Int i;
260 Int ia, ja, ib, jb, m, n;
261 Int gcontext, context0, context1;
262 Int myprow1, myprow0, mypcol0, mypcol1;
263 Int dummy;
264 MDESC ma, mb;
265 char *uplo, *diag;
266 double *ptrmyblock, *ptrsavemyblock, *ptrmyblockcopy, *ptrmyblockvide;
267#ifdef UsingMpiBlacs
268 MPI_Init(&argc, &argv);
269#endif
270 setvbuf(stdout, NULL, _IOLBF, 0);
271 setvbuf(stderr, NULL, _IOLBF, 0);
272#ifdef T3D
273 free(malloc(14000000));
274#endif
275 initforpvm(argc, argv);
276 /* Read physical parameters */
277 Cblacs_pinfo(&mypnum, &nprocs);
278 /* initialize BLACS for the parameter communication */
279 Cblacs_get((Int)0, (Int)0, &gcontext);
280 Cblacs_gridinit(&gcontext, "R", nprocs, (Int)1);
281 Cblacs_gridinfo(gcontext, &dummy, &dummy, &mypnum, &dummy);
282 if (mypnum == 0) {
283 if ((fp = fopen("TRMR2D.dat", "r")) == NULL) {
284 fprintf(stderr, "Can't open TRMR2D.dat\n");
285 exit(1);
286 };
287 printf("\n// DTRMR2D TESTER for DOUBLE PRECISION //\n");
288 getparam(fp, &nbre, NULL);
289 printf("////////// %d tests \n\n", nbre);
290 parameters[0] = nbre;
291 Cigebs2d(gcontext, "All", "H", (Int)1, (Int)1, parameters, (Int)1);
292 } else {
293 Cigebr2d(gcontext, "All", "H", (Int)1, (Int)1, parameters, (Int)1, (Int)0, (Int)0);
294 nbre = parameters[0];
295 };
296 if (mypnum == 0) {
297 printf("\n m n m0 n0 sr0 sc0 i0 j0 p0 q0 nbr0 nbc0 \
298m1 n1 sr1 sc1 i1 j1 p1 q1 nbr1 nbc1\n\n");
299 };
300 /****** TEST LOOP *****/
301 /* Here we are in grip 1xnprocs */
302 nbremax = nbre;
303#ifdef DEBUG
304 fprintf(stderr, "bonjour,je suis le noeud %d\n", mypnum);
305#endif
306 while (nbre-- != 0) { /* Loop on the serie of tests */
307 /* All the processors read the parameters so we have to be in a 1xnprocs
308 * grid at each iteration */
309 /* Read processors grid and matrices parameters */
310 if (mypnum == 0) {
311 Int u, d;
312 getparam(fp,
313 &m, &n,
314 &ma.m, &ma.n, &ma.sprow, &ma.spcol,
315 &ia, &ja, &p0, &q0, &ma.nbrow, &ma.nbcol,
316 &mb.m, &mb.n, &mb.sprow, &mb.spcol,
317 &ib, &jb, &p1, &q1, &mb.nbrow, &mb.nbcol,
318 &u, &d,
319 NULL);
320 uplo = u ? "UPPER" : "LOWER";
321 diag = d ? "UNIT" : "NONUNIT";
322 printf("\t\t************* TEST # %d **********\n",
323 nbremax - nbre);
324 printf(" %3d %3d %3d %3d %3d %3d %3d %3d \
325%3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d %3d",
326 m, n,
327 ma.m, ma.n, ma.sprow, ma.spcol,
328 ia, ja, p0, q0, ma.nbrow, ma.nbcol,
329 mb.m, mb.n, mb.sprow, mb.spcol,
330 ib, jb, p1, q1, mb.nbrow, mb.nbcol);
331 printf(" %s %s", toupper(*uplo) == 'U' ? "up" : "low",
332 toupper(*diag) == 'U' ? "unit" : "nonunit");
333 printf("\n");
334 if (p0 * q0 > nprocs || p1 * q1 > nprocs) {
335 fprintf(stderr, "not enough nodes:%d processors required\n",
336 max(p0 * q0, p1 * q1));
337 exit(1);
338 }
339 parameters[0] = p0;
340 parameters[1] = q0;
341 parameters[2] = ma.nbrow;
342 parameters[3] = ma.nbcol;
343 parameters[4] = p1;
344 parameters[5] = q1;
345 parameters[6] = mb.nbrow;
346 parameters[7] = mb.nbcol;
347 parameters[8] = ma.m;
348 parameters[9] = ma.n;
349 parameters[10] = ma.sprow;
350 parameters[11] = ma.spcol;
351 parameters[12] = mb.sprow;
352 parameters[13] = mb.spcol;
353 parameters[14] = ia;
354 parameters[15] = ja;
355 parameters[16] = ib;
356 parameters[17] = jb;
357 parameters[18] = m;
358 parameters[19] = n;
359 parameters[20] = mb.m;
360 parameters[21] = mb.n;
361 parameters[22] = *uplo == 'U';
362 parameters[23] = *diag == 'U';
363 Cigebs2d(gcontext, "All", "H", (Int)1, nbparameter, parameters, (Int)1);
364 } else {
365 Cigebr2d(gcontext, "All", "H", (Int)1, nbparameter, parameters, (Int)1, (Int)0, (Int)0);
366 p0 = parameters[0];
367 q0 = parameters[1];
368 ma.nbrow = parameters[2];
369 ma.nbcol = parameters[3];
370 p1 = parameters[4];
371 q1 = parameters[5];
372 mb.nbrow = parameters[6];
373 mb.nbcol = parameters[7];
374 ma.m = parameters[8];
375 ma.n = parameters[9];
376 ma.sprow = parameters[10];
377 ma.spcol = parameters[11];
378 mb.sprow = parameters[12];
379 mb.spcol = parameters[13];
380 ia = parameters[14];
381 ja = parameters[15];
382 ib = parameters[16];
383 jb = parameters[17];
384 m = parameters[18];
385 n = parameters[19];
386 mb.m = parameters[20];
387 mb.n = parameters[21];
390 uplo = parameters[22] ? "UPPER" : "LOWER";
391 diag = parameters[23] ? "UNIT" : "NONUNIT";
392 };
393 Cblacs_get((Int)0, (Int)0, &context0);
394 Cblacs_gridinit(&context0, "R", p0, q0);
395 Cblacs_get((Int)0, (Int)0, &context1);
396 Cblacs_gridinit(&context1, "R", p1, q1);
397 Cblacs_gridinfo(context0, &dummy, &dummy, &myprow0, &mypcol0);
398 if (myprow0 >= p0 || mypcol0 >= q0)
399 myprow0 = mypcol0 = -1;
400 Cblacs_gridinfo(context1, &dummy, &dummy, &myprow1, &mypcol1);
401 if (myprow1 >= p1 || mypcol1 >= q1)
402 myprow1 = mypcol1 = -1;
403 assert((myprow0 < p0 && mypcol0 < q0) || (myprow0 == -1 && mypcol0 == -1));
404 assert((myprow1 < p1 && mypcol1 < q1) || (myprow1 == -1 && mypcol1 == -1));
405 ma.ctxt = context0;
406 mb.ctxt = context1;
407 /* From here, we are not assuming that only the processors working in the
408 * redistribution are calling xxMR2D, but the ones not concerned will do
409 * nothing. */
410 /* We compute the exact size of the local memory block for the memory
411 * allocations */
412 if (myprow0 >= 0 && mypcol0 >= 0) {
413 blocksize0 = memoryblocksize(&ma);
414 ma.lda = localsize(SHIFT(myprow0, ma.sprow, p0), p0, ma.nbrow, ma.m);
415 setmemory(&ptrmyblock, blocksize0);
416 initblock(ptrmyblock, 1, blocksize0);
417 setmemory(&ptrmyblockcopy, blocksize0);
418 memcpy((char *) ptrmyblockcopy, (char *) ptrmyblock,
419 blocksize0 * sizeof(double));
420 setmemory(&ptrmyblockvide, blocksize0);
421 for (i = 0; i < blocksize0; i++)
422 ptrmyblockvide[i] = -1;
423 }; /* if (mypnum < p0 * q0) */
424 if (myprow1 >= 0 && mypcol1 >= 0) {
425 setmemory(&ptrsavemyblock, memoryblocksize(&mb));
426 mb.lda = localsize(SHIFT(myprow1, mb.sprow, p1), p1, mb.nbrow, mb.m);
427 }; /* if (mypnum < p1 * q1) */
428 /* Redistribute the matrix from grid 0 to grid 1 (memory location
429 * ptrmyblock to ptrsavemyblock) */
430 Cpdtrmr2d(uplo, diag, m, n,
431 ptrmyblock, ia, ja, &ma,
432 ptrsavemyblock, ib, jb, &mb, gcontext);
433 /* Perform the inverse redistribution of the matrix from grid 1 to grid 0
434 * (memory location ptrsavemyblock to ptrmyblockvide) */
435 Cpdtrmr2d(uplo, diag, m, n,
436 ptrsavemyblock, ib, jb, &mb,
437 ptrmyblockvide, ia, ja, &ma, gcontext);
438 /* Check the differences */
439 nberrors = 0;
440 if (myprow0 >= 0 && mypcol0 >= 0) {
441 /* only for the processors that do have data at the begining */
442 for (i = 0; i < blocksize0; i++) {
443 Int li, lj, gi, gj;
444 Int in;
445 in = 1;
446 li = i % ma.lda;
447 lj = i / ma.lda;
448 gi = (li / ma.nbrow) * p0 * ma.nbrow +
449 SHIFT(myprow0, ma.sprow, p0) * ma.nbrow + li % ma.nbrow;
450 gj = (lj / ma.nbcol) * q0 * ma.nbcol +
451 SHIFT(mypcol0, ma.spcol, q0) * ma.nbcol + lj % ma.nbcol;
452 assert(gi < ma.m && gj < ma.n);
453 gi -= (ia - 1);
454 gj -= (ja - 1);
455 if (gi < 0 || gj < 0 || gi >= m || gj >= n)
456 in = 0;
457 else if (toupper(*uplo) == 'U')
458 in = (gi <= gj + max(0, m - n) - (toupper(*diag) == 'U'));
459 else
460 in = (gi >= gj - max(0, n - m) + (toupper(*diag) == 'U'));
461 if (!in) {
462 ptrmyblockcopy[i] = -1;
463 }
464 if (ptrmyblockvide[i] != ptrmyblockcopy[i]) {
465 nberrors++;
466 printf("Proc %d : Error element number %d, value = %f , initvalue =%f \n"
467 ,mypnum, i,
468 ptrmyblockvide[i], ptrmyblockcopy[i]);
469 };
470 };
471 if (nberrors > 0) {
472 printf("Processor %d, has tested %d DOUBLE PRECISION elements,\
473Number of redistribution errors = %d \n",
474 mypnum, blocksize0, nberrors);
475 }
476 }
477 /* Look at the errors on all the processors at this point. */
478 Cigsum2d(gcontext, "All", "H", (Int)1, (Int)1, &nberrors, (Int)1, (Int)0, (Int)0);
479 if (mypnum == 0)
480 if (nberrors)
481 printf(" => Total number of redistribution errors = %d \n",
482 nberrors);
483 else
484 printf("TEST PASSED OK\n");
485 /* release memory for the next iteration */
486 if (myprow0 >= 0 && mypcol0 >= 0) {
487 freememory((char *) ptrmyblock);
488 freememory((char *) ptrmyblockvide);
489 freememory((char *) ptrmyblockcopy);
490 }; /* if (mypnum < p0 * q0) */
491 /* release memory for the next iteration */
492 if (myprow1 >= 0 && mypcol1 >= 0) {
493 freememory((char *) ptrsavemyblock);
494 };
495 if (myprow0 >= 0)
496 Cblacs_gridexit(context0);
497 if (myprow1 >= 0)
498 Cblacs_gridexit(context1);
499 }; /* while nbre != 0 */
500 if (mypnum == 0) {
501 fclose(fp);
502 };
503 Cblacs_exit((Int)0);
504 return 0;
505}/* main */
#define Int
Definition Bconfig.h:22
Int memoryblocksize()
Int changeorigin()
#define freememory
Definition pdtrmrdrv.c:138
#define scan_intervals
Definition pdtrmrdrv.c:139
#define dlacpy_
Definition pdtrmrdrv.c:74
#define SHIFT(row, sprow, nbrow)
Definition pdtrmrdrv.c:94
void Cblacs_gridexit()
#define max(A, B)
Definition pdtrmrdrv.c:95
static2 void initblock(double *block, Int m, Int n)
Definition pdtrmrdrv.c:165
void Cigsum2d()
void Cpdtrmr2d()
#define static2
Definition pdtrmrdrv.c:61
#define scanD0
Definition pdtrmrdrv.c:135
Int Cblacs_pnum()
void Cdgerv2d()
#define Clacpy
Definition pdtrmrdrv.c:76
void Cigamx2d()
void Cpdtrmr2do()
void Cblacs_pinfo()
void Cblacs_pcoord()
void Cigamn2d()
Int localsize()
#define setmemory
Definition pdtrmrdrv.c:137
void Cblacs_get()
void Cigerv2d()
void Cigebs2d()
#define dispmat
Definition pdtrmrdrv.c:136
void Cdgesd2d()
void paramcheck()
void Cblacs_setup()
#define BLOCK_CYCLIC_2D
Definition pdtrmrdrv.c:89
void Cblacs_gridinit()
void Cblacs_gridinfo()
void Csetpvmtids()
Int localindice()
void Cigesd2d()
void initforpvm(Int argc, char *argv[])
Definition pdtrmrdrv.c:223
Int ppcm()
void Cigebr2d()
void Cblacs_exit()
void * mr2d_malloc()
#define nbparameter
main()
Definition size.c:2
Int m
Definition pcgemr.c:166
Int spcol
Definition pcgemr.c:171
Int nbcol
Definition pcgemr.c:169
Int sprow
Definition pcgemr.c:170
Int nbrow
Definition pcgemr.c:168
Int ctxt
Definition pcgemr.c:165
Int desctype
Definition pcgemr.c:164
Int n
Definition pcgemr.c:167
Int lda
Definition pcgemr.c:172