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