OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
pdgemr.c File Reference
#include "redist.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

Go to the source code of this file.

Data Structures

struct  MDESC
struct  IDESC

Macros

#define static2   static
#define fortran_mr2d   pdgemr2do
#define fortran_mr2dnew   pdgemr2d
#define dcopy_   dcopy
#define dlacpy_   dlacpy
#define Clacpy   Cdgelacpy
#define BLOCK_CYCLIC_2D   1
#define SHIFT(row, sprow, nbrow)
#define max(A, B)
#define min(A, B)
#define DIVUP(a, b)
#define ROUNDUP(a, b)
#define scanD0   dgescanD0
#define dispmat   dgedispmat
#define setmemory   dgesetmemory
#define freememory   dgefreememory
#define scan_intervals   dgescan_intervals
#define SENDBUFF   0
#define RECVBUFF   1
#define SIZEBUFF   2
#define NDEBUG
#define DESCLEN   9
#define NBPARAM
#define MAGIC_MAX   100000000
#define Mlacpy(mo, no, ao, ldao, bo, ldbo)

Functions

void Cblacs_pcoord ()
Int Cblacs_pnum ()
void Csetpvmtids ()
void Cblacs_get ()
void Cblacs_pinfo ()
void Cblacs_gridinfo ()
void Cblacs_gridinit ()
void Cblacs_exit ()
void Cblacs_gridexit ()
void Cblacs_setup ()
void Cigebs2d ()
void Cigebr2d ()
void Cigesd2d ()
void Cigerv2d ()
void Cigsum2d ()
void Cigamn2d ()
void Cigamx2d ()
void Cdgesd2d ()
void Cdgerv2d ()
Int localindice ()
void * mr2d_malloc ()
Int ppcm ()
Int localsize ()
Int memoryblocksize ()
Int changeorigin ()
void paramcheck ()
void Cpdgemr2do ()
void Cpdgemr2d ()
void fortran_mr2d (Int *m, Int *n, double *A, Int *ia, Int *ja, Int desc_A[DESCLEN], double *B, Int *ib, Int *jb, Int desc_B[DESCLEN])
void fortran_mr2dnew (Int *m, Int *n, double *A, Int *ia, Int *ja, Int desc_A[DESCLEN], double *B, Int *ib, Int *jb, Int desc_B[DESCLEN], Int *gcontext)
static2 void init_chenille ()
static2 Int inter_len ()
static2 Int block2buff ()
static2 void buff2block ()
static2 void gridreshape ()
void Cpdgemr2do (Int m, Int n, double *ptrmyblock, Int ia, Int ja, MDESC *ma, double *ptrmynewblock, Int ib, Int jb, MDESC *mb)
void Cpdgemr2d (Int m, Int n, double *ptrmyblock, Int ia, Int ja, MDESC *ma, double *ptrmynewblock, Int ib, Int jb, MDESC *mb, Int globcontext)
static2 void init_chenille (Int mypnum, Int nprocs, Int n0, Int *proc0, Int n1, Int *proc1, Int **psend, Int **precv, Int *myrang)
static2 Int block2buff (IDESC *vi, Int vinb, IDESC *hi, Int hinb, double *ptra, MDESC *ma, double *buff)
static2 void buff2block (IDESC *vi, Int vinb, IDESC *hi, Int hinb, double *buff, double *ptrb, MDESC *mb)
static2 Int inter_len (Int hinb, IDESC *hi, Int vinb, IDESC *vi)
void Clacpy (Int m, Int n, double *a, Int lda, double *b, Int ldb)
static2 void gridreshape (Int *ctxtp)

Macro Definition Documentation

◆ BLOCK_CYCLIC_2D

#define BLOCK_CYCLIC_2D   1

Definition at line 171 of file pdgemr.c.

◆ Clacpy

#define Clacpy   Cdgelacpy

Definition at line 158 of file pdgemr.c.

◆ dcopy_

#define dcopy_   dcopy

Definition at line 155 of file pdgemr.c.

◆ DESCLEN

#define DESCLEN   9

Definition at line 242 of file pdgemr.c.

◆ dispmat

#define dispmat   dgedispmat

Definition at line 218 of file pdgemr.c.

◆ DIVUP

#define DIVUP ( a,
b )
Value:
( ((a)-1) /(b)+1)

Definition at line 179 of file pdgemr.c.

◆ dlacpy_

void dlacpy_   dlacpy

Definition at line 156 of file pdgemr.c.

◆ fortran_mr2d

#define fortran_mr2d   pdgemr2do

Definition at line 153 of file pdgemr.c.

◆ fortran_mr2dnew

#define fortran_mr2dnew   pdgemr2d

Definition at line 154 of file pdgemr.c.

◆ freememory

#define freememory   dgefreememory

Definition at line 220 of file pdgemr.c.

◆ MAGIC_MAX

#define MAGIC_MAX   100000000

Definition at line 286 of file pdgemr.c.

◆ max

#define max ( A,
B )
Value:
((A)>(B)?(A):(B))

Definition at line 177 of file pdgemr.c.

◆ min

#define min ( A,
B )
Value:
((A)>(B)?(B):(A))

Definition at line 178 of file pdgemr.c.

◆ Mlacpy

#define Mlacpy ( mo,
no,
ao,
ldao,
bo,
ldbo )
Value:
{ \
double *_a,*_b; \
Int _m,_n,_lda,_ldb; \
Int _i,_j; \
_m = (mo);_n = (no); \
_a = (ao);_b = (bo); \
_lda = (ldao) - _m; \
_ldb = (ldbo) - _m; \
assert(_lda >= 0 && _ldb >= 0); \
for (_j=0;_j<_n;_j++) { \
for (_i=0;_i<_m;_i++) \
*_b++ = *_a++; \
_b += _ldb; \
_a += _lda; \
} \
}
#define Int
Definition Bconfig.h:22

Definition at line 619 of file pdgemr.c.

619}
620#define Mlacpy(mo,no,ao,ldao,bo,ldbo) \
621{ \
622double *_a,*_b; \
623Int _m,_n,_lda,_ldb; \
624 Int _i,_j; \
625 _m = (mo);_n = (no); \
626 _a = (ao);_b = (bo); \
627 _lda = (ldao) - _m; \
628 _ldb = (ldbo) - _m; \
629 assert(_lda >= 0 && _ldb >= 0); \
630 for (_j=0;_j<_n;_j++) { \
631 for (_i=0;_i<_m;_i++) \
632 *_b++ = *_a++; \
633 _b += _ldb; \
634 _a += _lda; \
635 } \

◆ NBPARAM

#define NBPARAM
Value:
20 /* p0,q0,p1,q1, puis ma,na,mba,nba,rowa,cola puis
* idem B puis ia,ja puis ib,jb */

Definition at line 285 of file pdgemr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 237 of file pdgemr.c.

◆ RECVBUFF

#define RECVBUFF   1

Definition at line 231 of file pdgemr.c.

◆ ROUNDUP

#define ROUNDUP ( a,
b )
Value:
(DIVUP(a,b)*(b))
#define DIVUP(a, b)
Definition pcgemr.c:182

Definition at line 180 of file pdgemr.c.

◆ scan_intervals

#define scan_intervals   dgescan_intervals

Definition at line 221 of file pdgemr.c.

◆ scanD0

#define scanD0   dgescanD0

Definition at line 217 of file pdgemr.c.

◆ SENDBUFF

#define SENDBUFF   0

Definition at line 230 of file pdgemr.c.

◆ setmemory

#define setmemory   dgesetmemory

Definition at line 219 of file pdgemr.c.

◆ SHIFT

#define SHIFT ( row,
sprow,
nbrow )
Value:
((row)-(sprow)+ ((row) >= (sprow) ? 0 : (nbrow)))

Definition at line 176 of file pdgemr.c.

◆ SIZEBUFF

#define SIZEBUFF   2

Definition at line 232 of file pdgemr.c.

◆ static2

#define static2   static

Id
pdgemr.c,v 1.1.1.1 2000/02/15 18:04:09 susan Exp

– ScaLAPACK routine (version 1.7) – Oak Ridge National Laboratory, Univ. of Tennessee, and Univ. of California, Berkeley. October 31, 1994.

SUBROUTINE PDGEMR2D( M, N, $ A, IA, JA, ADESC, $ B, IB, JB, BDESC,

$ CTXT)

Purpose

PDGEMR2D copies a submatrix of A on a submatrix of B. A and B can have different distributions: they can be on different processor grids, they can have different blocksizes, the beginning of the area to be copied can be at a different places on A and B.

The parameters can be confusing when the grids of A and B are partially or completly disjoint, in the case a processor calls this routines but is either not in the A context or B context, the ADESC[CTXT] or BDESC[CTXT] must be equal to -1, to ensure the routine recognise this situation. To summarize the rule:

  • If a processor is in A context, all parameters related to A must be valid.
  • If a processor is in B context, all parameters related to B must be valid.
  • ADESC[CTXT] and BDESC[CTXT] must be either valid contexts or equal to -1.
  • M and N must be valid for everyone.
  • other parameters are not examined.

Notes

A description vector is associated with each 2D block-cyclicly dis- tributed matrix. This vector stores the information required to establish the mapping between a matrix entry and its corresponding process and memory location.

In the following comments, the character _ should be read as "of the distributed matrix". Let A be a generic term for any 2D block cyclicly distributed matrix. Its description vector is DESC_A:

NOTATION STORED IN EXPLANATION


DT_A (global) DESCA( DT_ ) The descriptor type. CTXT_A (global) DESCA( CTXT_ ) The BLACS context handle, indicating the BLACS process grid A is distribu- ted over. The context itself is glo- bal, but the handle (the integer value) may vary. M_A (global) DESCA( M_ ) The number of rows in the distributed matrix A. N_A (global) DESCA( N_ ) The number of columns in the distri- buted matrix A. MB_A (global) DESCA( MB_ ) The blocking factor used to distribute the rows of A. NB_A (global) DESCA( NB_ ) The blocking factor used to distribute the columns of A. RSRC_A (global) DESCA( RSRC_ ) The process row over which the first row of the matrix A is distributed. CSRC_A (global) DESCA( CSRC_ ) The process column over which the first column of A is distributed. LLD_A (local) DESCA( LLD_ ) The leading dimension of the local array storing the local blocks of the distributed matrix A. LLD_A >= MAX(1,LOCp(M_A)).

Important notice

The parameters of the routine have changed in April 1996 There is a new last argument. It must be a context englobing all processors involved in the initial and final distribution.

Be aware that all processors included in this context must call the redistribution routine.

Parameters

M (input) INTEGER. On entry, M specifies the number of rows of the submatrix to be copied. M must be at least zero. Unchanged on exit.

N (input) INTEGER. On entry, N specifies the number of cols of the submatrix to be redistributed.rows of B. M must be at least zero. Unchanged on exit.

A (input) DOUBLE PRECISION On entry, the source matrix. Unchanged on exit.

IA,JA (input) INTEGER On entry,the coordinates of the beginning of the submatrix of A to copy. 1 <= IA <= M_A - M + 1,1 <= JA <= N_A - N + 1, Unchanged on exit.

ADESC (input) A description vector (see Notes above) If the current processor is not part of the context of A the ADESC[CTXT] must be equal to -1.

B (output) DOUBLE PRECISION On entry, the destination matrix. The portion corresponding to the defined submatrix are updated.

IB,JB (input) INTEGER On entry,the coordinates of the beginning of the submatrix of B that will be updated. 1 <= IB <= M_B - M + 1,1 <= JB <= N_B - N + 1, Unchanged on exit.

BDESC (input) B description vector (see Notes above) For processors not part of the context of B BDESC[CTXT] must be equal to -1.

CTXT (input) a context englobing at least all processors included in either A context or B context

Memory requirement :

for the processors belonging to grid 0, one buffer of size block 0 and for the processors belonging to grid 1, also one buffer of size block 1.


Created March 1993 by B. Tourancheau (See sccs for modifications).

Modifications by Loic PRYLLI 1995

Definition at line 143 of file pdgemr.c.

Function Documentation

◆ block2buff() [1/2]

static2 Int block2buff ( )

◆ block2buff() [2/2]

static2 Int block2buff ( IDESC * vi,
Int vinb,
IDESC * hi,
Int hinb,
double * ptra,
MDESC * ma,
double * buff )

Definition at line 637 of file pdgemr.c.

643{
644 Int h, v, sizebuff;
645 double *ptr2;
646 sizebuff = 0;
647 for (h = 0; h < hinb; h++) {
648 ptr2 = ptra + hi[h].lstart * ma->lda;
649 for (v = 0; v < vinb; v++) {
650 Mlacpy(vi[v].len, hi[h].len,
651 ptr2 + vi[v].lstart,
652 ma->lda,
653 buff + sizebuff, vi[v].len);
654 sizebuff += hi[h].len * vi[v].len;
655 }
656 }
657 return sizebuff;
#define Mlacpy(mo, no, ao, ldao, bo, ldbo)
Definition pdgemr.c:619
Int lstart
Definition pcgemr.c:176
Int len
Definition pcgemr.c:177
Int lda
Definition pcgemr.c:172

◆ buff2block() [1/2]

static2 void buff2block ( )

◆ buff2block() [2/2]

static2 void buff2block ( IDESC * vi,
Int vinb,
IDESC * hi,
Int hinb,
double * buff,
double * ptrb,
MDESC * mb )

Definition at line 659 of file pdgemr.c.

665{
666 Int h, v, sizebuff;
667 double *ptr2;
668 sizebuff = 0;
669 for (h = 0; h < hinb; h++) {
670 ptr2 = ptrb + hi[h].lstart * mb->lda;
671 for (v = 0; v < vinb; v++) {
672 Mlacpy(vi[v].len, hi[h].len,
673 buff + sizebuff, vi[v].len,
674 ptr2 + vi[v].lstart,
675 mb->lda);
676 sizebuff += hi[h].len * vi[v].len;
677 }
678 }

◆ Cblacs_exit()

void Cblacs_exit ( )
extern

◆ Cblacs_get()

void Cblacs_get ( )
extern

◆ Cblacs_gridexit()

void Cblacs_gridexit ( )
extern

◆ Cblacs_gridinfo()

void Cblacs_gridinfo ( )
extern

◆ Cblacs_gridinit()

void Cblacs_gridinit ( )
extern

◆ Cblacs_pcoord()

void Cblacs_pcoord ( )
extern

◆ Cblacs_pinfo()

void Cblacs_pinfo ( )
extern

◆ Cblacs_pnum()

Int Cblacs_pnum ( )
extern

◆ Cblacs_setup()

void Cblacs_setup ( )
extern

◆ Cdgerv2d()

void Cdgerv2d ( )
extern

◆ Cdgesd2d()

void Cdgesd2d ( )
extern

◆ changeorigin()

Int changeorigin ( )
extern

◆ Cigamn2d()

void Cigamn2d ( )
extern

◆ Cigamx2d()

void Cigamx2d ( )
extern

◆ Cigebr2d()

void Cigebr2d ( )
extern

◆ Cigebs2d()

void Cigebs2d ( )
extern

◆ Cigerv2d()

void Cigerv2d ( )
extern

◆ Cigesd2d()

void Cigesd2d ( )
extern

◆ Cigsum2d()

void Cigsum2d ( )
extern

◆ Clacpy()

void Clacpy ( Int m,
Int n,
double * a,
Int lda,
double * b,
Int ldb )

Definition at line 692 of file pdgemr.c.

694{
695 Int i, j;
696 lda -= m;
697 ldb -= m;
698 assert(lda >= 0 && ldb >= 0);
699 for (j = 0; j < n; j++) {
700 for (i = 0; i < m; i++)
701 *b++ = *a++;
702 b += ldb;
703 a += lda;
704 }
n

◆ Cpdgemr2d() [1/2]

void Cpdgemr2d ( )
extern

◆ Cpdgemr2d() [2/2]

void Cpdgemr2d ( Int m,
Int n,
double * ptrmyblock,
Int ia,
Int ja,
MDESC * ma,
double * ptrmynewblock,
Int ib,
Int jb,
MDESC * mb,
Int globcontext )

Definition at line 288 of file pdgemr.c.

297{
298 double *ptrsendbuff, *ptrrecvbuff, *ptrNULL = 0;
299 double *recvptr;
300 MDESC newa, newb;
301 Int *proc0, *proc1, *param;
302 Int mypnum, myprow0, mypcol0, myprow1, mypcol1, nprocs;
303 Int i, j;
304 Int nprow, npcol, gcontext;
305 Int recvsize, sendsize;
306 IDESC *h_inter; /* to store the horizontal intersections */
307 IDESC *v_inter; /* to store the vertical intersections */
308 Int hinter_nb, vinter_nb; /* number of intrsections in both directions */
309 Int dummy;
310 Int p0, q0, p1, q1;
311 Int *ra, *ca;
312 /* end of variables */
313 /* To simplify further calcul we change the matrix indexation from
314 * 1..m,1..n (fortran) to 0..m-1,0..n-1 */
315 if (m == 0 || n == 0)
316 return;
317 ia -= 1;
318 ja -= 1;
319 ib -= 1;
320 jb -= 1;
321 Cblacs_gridinfo(globcontext, &nprow, &npcol, &dummy, &mypnum);
322 gcontext = globcontext;
323 nprocs = nprow * npcol;
324 /* if the global context that is given to us has not the shape of a line
325 * (nprow != 1), create a new context. TODO: to be optimal, we should
326 * avoid this because it is an uncessary synchronisation */
327 if (nprow != 1) {
328 gridreshape(&gcontext);
329 Cblacs_gridinfo(gcontext, &dummy, &dummy, &dummy, &mypnum);
330 }
331 Cblacs_gridinfo(ma->ctxt, &p0, &q0, &myprow0, &mypcol0);
332 /* compatibility T3D, must check myprow and mypcol are within bounds */
333 if (myprow0 >= p0 || mypcol0 >= q0)
334 myprow0 = mypcol0 = -1;
335 assert((myprow0 < p0 && mypcol0 < q0) || (myprow0 == -1 && mypcol0 == -1));
336 Cblacs_gridinfo(mb->ctxt, &p1, &q1, &myprow1, &mypcol1);
337 if (myprow1 >= p1 || mypcol1 >= q1)
338 myprow1 = mypcol1 = -1;
339 assert((myprow1 < p1 && mypcol1 < q1) || (myprow1 == -1 && mypcol1 == -1));
340 /* exchange the missing parameters among the processors: shape of grids and
341 * location of the processors */
342 param = (Int *) mr2d_malloc(3 * (nprocs * 2 + NBPARAM) * sizeof(Int));
343 ra = param + nprocs * 2 + NBPARAM;
344 ca = param + (nprocs * 2 + NBPARAM) * 2;
345 for (i = 0; i < nprocs * 2 + NBPARAM; i++)
346 param[i] = MAGIC_MAX;
347 proc0 = param + NBPARAM;
348 proc1 = param + NBPARAM + nprocs;
349 /* we calulate proc0 and proc1 that will give the number of a proc in
350 * respectively a or b in the global context */
351 if (myprow0 >= 0) {
352 proc0[myprow0 * q0 + mypcol0] = mypnum;
353 param[0] = p0;
354 param[1] = q0;
355 param[4] = ma->m;
356 param[5] = ma->n;
357 param[6] = ma->nbrow;
358 param[7] = ma->nbcol;
359 param[8] = ma->sprow;
360 param[9] = ma->spcol;
361 param[10] = ia;
362 param[11] = ja;
363 }
364 if (myprow1 >= 0) {
365 proc1[myprow1 * q1 + mypcol1] = mypnum;
366 param[2] = p1;
367 param[3] = q1;
368 param[12] = mb->m;
369 param[13] = mb->n;
370 param[14] = mb->nbrow;
371 param[15] = mb->nbcol;
372 param[16] = mb->sprow;
373 param[17] = mb->spcol;
374 param[18] = ib;
375 param[19] = jb;
376 }
377 Cigamn2d(gcontext, "All", "H", 2 * nprocs + NBPARAM, (Int)1, param, 2 * nprocs + NBPARAM,
378 ra, ca, 2 * nprocs + NBPARAM, (Int)-1, (Int)-1);
379 newa = *ma;
380 newb = *mb;
381 ma = &newa;
382 mb = &newb;
383 if (myprow0 == -1) {
384 p0 = param[0];
385 q0 = param[1];
386 ma->m = param[4];
387 ma->n = param[5];
388 ma->nbrow = param[6];
389 ma->nbcol = param[7];
390 ma->sprow = param[8];
391 ma->spcol = param[9];
392 ia = param[10];
393 ja = param[11];
394 }
395 if (myprow1 == -1) {
396 p1 = param[2];
397 q1 = param[3];
398 mb->m = param[12];
399 mb->n = param[13];
400 mb->nbrow = param[14];
401 mb->nbcol = param[15];
402 mb->sprow = param[16];
403 mb->spcol = param[17];
404 ib = param[18];
405 jb = param[19];
406 }
407 for (i = 0; i < NBPARAM; i++) {
408 if (param[i] == MAGIC_MAX) {
409 fprintf(stderr, "xxGEMR2D:something wrong in the parameters\n");
410 exit(1);
411 }
412 }
413#ifndef NDEBUG
414 for (i = 0; i < p0 * q0; i++)
415 assert(proc0[i] >= 0 && proc0[i] < nprocs);
416 for (i = 0; i < p1 * q1; i++)
417 assert(proc1[i] >= 0 && proc1[i] < nprocs);
418#endif
419 /* check the validity of the parameters */
420 paramcheck(ma, ia, ja, m, n, p0, q0, gcontext);
421 paramcheck(mb, ib, jb, m, n, p1, q1, gcontext);
422 /* we change the problem so that ia < a->nbrow ... andia + m = a->m ... */
423 {
424 Int decal;
425 ia = changeorigin(myprow0, ma->sprow, p0,
426 ma->nbrow, ia, &decal, &ma->sprow);
427 ptrmyblock += decal;
428 ja = changeorigin(mypcol0, ma->spcol, q0,
429 ma->nbcol, ja, &decal, &ma->spcol);
430 ptrmyblock += decal * ma->lda;
431 ma->m = ia + m;
432 ma->n = ja + n;
433 ib = changeorigin(myprow1, mb->sprow, p1,
434 mb->nbrow, ib, &decal, &mb->sprow);
435 ptrmynewblock += decal;
436 jb = changeorigin(mypcol1, mb->spcol, q1,
437 mb->nbcol, jb, &decal, &mb->spcol);
438 ptrmynewblock += decal * mb->lda;
439 mb->m = ib + m;
440 mb->n = jb + n;
441 if (p0 == 1)
442 ma->nbrow = ma->m;
443 if (q0 == 1)
444 ma->nbcol = ma->n;
445 if (p1 == 1)
446 mb->nbrow = mb->m;
447 if (q1 == 1)
448 mb->nbcol = mb->n;
449#ifndef NDEBUG
450 paramcheck(ma, ia, ja, m, n, p0, q0, gcontext);
451 paramcheck(mb, ib, jb, m, n, p1, q1, gcontext);
452#endif
453 }
454 /* We compute the size of the memory buffer ( we choose the worst case,
455 * when the buffer sizes == the memory block sizes). */
456 if (myprow0 >= 0 && mypcol0 >= 0) {
457 /* Initialize pointer variables */
458 setmemory(&ptrsendbuff, memoryblocksize(ma));
459 }; /* if (mypnum < p0 * q0) */
460 if (myprow1 >= 0 && mypcol1 >= 0) {
461 /* Initialize pointer variables */
462 setmemory(&ptrrecvbuff, memoryblocksize(mb));
463 }; /* if (mypnum < p1 * q1) */
464 /* allocing room for the tabs, alloc for the worst case,local_n or local_m
465 * intervals, in fact the worst case should be less, perhaps half that,I
466 * should think of that one day. */
467 h_inter = (IDESC *) mr2d_malloc(DIVUP(ma->n, q0 * ma->nbcol) *
468 ma->nbcol * sizeof(IDESC));
469 v_inter = (IDESC *) mr2d_malloc(DIVUP(ma->m, p0 * ma->nbrow)
470 * ma->nbrow * sizeof(IDESC));
471 /* We go for the scanning of indices. For each processor including mypnum,
472 * we fill the sendbuff buffer (scanD0(SENDBUFF)) and when it is done send
473 * it. Then for each processor, we compute the size of message to be
474 * receive scanD0(SIZEBUFF)), post a receive and then allocate the elements
475 * of recvbuff the right place (scanD)(RECVBUFF)) */
476 recvptr = ptrrecvbuff;
477 {
478 Int tot, myrang, step, sens;
479 Int *sender, *recver;
480 Int mesending, merecving;
481 tot = max(p0 * q0, p1 * q1);
482 init_chenille(mypnum, nprocs, p0 * q0, proc0, p1 * q1, proc1,
483 &sender, &recver, &myrang);
484 if (myrang == -1)
485 goto after_comm;
486 mesending = myprow0 >= 0;
487 assert(sender[myrang] >= 0 || !mesending);
488 assert(!mesending || proc0[sender[myrang]] == mypnum);
489 merecving = myprow1 >= 0;
490 assert(recver[myrang] >= 0 || !merecving);
491 assert(!merecving || proc1[recver[myrang]] == mypnum);
492 step = tot - 1 - myrang;
493 do {
494 for (sens = 0; sens < 2; sens++) {
495 /* be careful here, when we communicating with ourselves, we must
496 * send first (myrang > step == 0) */
497 if (mesending && recver[step] >= 0 &&
498 (sens == 0)) {
499 i = recver[step] / q1;
500 j = recver[step] % q1;
501 vinter_nb = scan_intervals('r', ia, ib, m, ma, mb, p0, p1, myprow0, i,
502 v_inter);
503 hinter_nb = scan_intervals('c', ja, jb, n, ma, mb, q0, q1, mypcol0, j,
504 h_inter);
505 sendsize = block2buff(v_inter, vinter_nb, h_inter, hinter_nb,
506 ptrmyblock, ma, ptrsendbuff);
507 } /* if (mesending...) { */
508 if (mesending && recver[step] >= 0 &&
509 (sens == myrang > step)) {
510 i = recver[step] / q1;
511 j = recver[step] % q1;
512 if (sendsize > 0
513 && (step != myrang || !merecving)
514 ) {
515 Cdgesd2d(gcontext, sendsize, (Int)1, ptrsendbuff, sendsize,
516 (Int)0, proc1[i * q1 + j]);
517 } /* sendsize > 0 */
518 } /* if (mesending ... */
519 if (merecving && sender[step] >= 0 &&
520 (sens == myrang <= step)) {
521 i = sender[step] / q0;
522 j = sender[step] % q0;
523 vinter_nb = scan_intervals('r', ib, ia, m, mb, ma, p1, p0, myprow1, i,
524 v_inter);
525 hinter_nb = scan_intervals('c', jb, ja, n, mb, ma, q1, q0, mypcol1, j,
526 h_inter);
527 recvsize = inter_len(hinter_nb, h_inter, vinter_nb, v_inter);
528 if (recvsize > 0) {
529 if (step == myrang && mesending) {
530 Clacpy(recvsize, 1,
531 ptrsendbuff, recvsize,
532 ptrrecvbuff, recvsize);
533 } else {
534 Cdgerv2d(gcontext, recvsize, (Int)1, ptrrecvbuff, recvsize,
535 (Int)0, proc0[i * q0 + j]);
536 }
537 } /* recvsize > 0 */
538 } /* if (merecving ...) */
539 if (merecving && sender[step] >= 0 && sens == 1) {
540 buff2block(v_inter, vinter_nb, h_inter, hinter_nb,
541 recvptr, ptrmynewblock, mb);
542 } /* if (merecving...) */
543 } /* for (sens = 0) */
544 step -= 1;
545 if (step < 0)
546 step = tot - 1;
547 } while (step != tot - 1 - myrang);
548after_comm:
549 free(sender);
550 } /* { int tot,nr,ns ...} */
551 /* don't forget to clean up things! */
552 if (myprow1 >= 0 && mypcol1 >= 0) {
553 freememory((char *) ptrrecvbuff);
554 };
555 if (myprow0 >= 0 && mypcol0 >= 0) {
556 freememory((char *) ptrsendbuff);
557 };
558 if (nprow != 1)
559 Cblacs_gridexit(gcontext);
560 free(v_inter);
561 free(h_inter);
562 free(param);
integer, save, private nprocs
Definition cmumps_load.F:57
#define NBPARAM
Definition pcgemr.c:288
#define MAGIC_MAX
Definition pcgemr.c:289
static2 Int inter_len()
Int memoryblocksize()
Int changeorigin()
#define freememory
Definition pdgemr.c:220
#define scan_intervals
Definition pdgemr.c:221
void Cblacs_gridexit()
#define max(A, B)
Definition pdgemr.c:177
void Cdgerv2d()
static2 void gridreshape()
#define DIVUP(a, b)
Definition pdgemr.c:179
#define Clacpy
Definition pdgemr.c:158
void Cigamn2d()
#define setmemory
Definition pdgemr.c:219
static2 void buff2block()
void Cdgesd2d()
void paramcheck()
static2 Int block2buff()
void Cblacs_gridinfo()
void * mr2d_malloc()
static2 void init_chenille()
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 n
Definition pcgemr.c:167

◆ Cpdgemr2do() [1/2]

void Cpdgemr2do ( )
extern

◆ Cpdgemr2do() [2/2]

void Cpdgemr2do ( Int m,
Int n,
double * ptrmyblock,
Int ia,
Int ja,
MDESC * ma,
double * ptrmynewblock,
Int ib,
Int jb,
MDESC * mb )

Definition at line 265 of file pdgemr.c.

273{
274 Int dummy, nprocs;
275 Int gcontext;
276 /* first we initialize a global grid which serve as a reference to
277 * communicate from grid a to grid b */
278 Cblacs_pinfo(&dummy, &nprocs);
279 Cblacs_get((Int)0, (Int)0, &gcontext);
280 Cblacs_gridinit(&gcontext, "R", (Int)1, nprocs);
281 Cpdgemr2d(m, n, ptrmyblock, ia, ja, ma,
282 ptrmynewblock, ib, jb, mb, gcontext);
283 Cblacs_gridexit(gcontext);
284}
void Cblacs_pinfo()
void Cblacs_get()
void Cblacs_gridinit()
void Cpdgemr2d()

◆ Csetpvmtids()

void Csetpvmtids ( )
extern

◆ fortran_mr2d()

void fortran_mr2d ( Int * m,
Int * n,
double * A,
Int * ia,
Int * ja,
Int desc_A[DESCLEN],
double * B,
Int * ib,
Int * jb,
Int desc_B[DESCLEN] )

Definition at line 244 of file pdgemr.c.

246{
247 Cpdgemr2do(*m, *n, A, *ia, *ja, (MDESC *) desc_A,
248 B, *ib, *jb, (MDESC *) desc_B);
249 return;
250}
void Cpdgemr2do()

◆ fortran_mr2dnew()

void fortran_mr2dnew ( Int * m,
Int * n,
double * A,
Int * ia,
Int * ja,
Int desc_A[DESCLEN],
double * B,
Int * ib,
Int * jb,
Int desc_B[DESCLEN],
Int * gcontext )

Definition at line 252 of file pdgemr.c.

254{
255 Cpdgemr2d(*m, *n, A, *ia, *ja, (MDESC *) desc_A,
256 B, *ib, *jb, (MDESC *) desc_B, *gcontext);
257 return;
258}

◆ gridreshape() [1/2]

static2 void gridreshape ( )

◆ gridreshape() [2/2]

static2 void gridreshape ( Int * ctxtp)

Definition at line 706 of file pdgemr.c.

708{
709 Int ori, final; /* original context, and new context created, with
710 * line form */
711 Int nprow, npcol, myrow, mycol;
712 Int *usermap;
713 Int i, j;
714 ori = *ctxtp;
715 Cblacs_gridinfo(ori, &nprow, &npcol, &myrow, &mycol);
716 usermap = mr2d_malloc(sizeof(Int) * nprow * npcol);
717 for (i = 0; i < nprow; i++)
718 for (j = 0; j < npcol; j++) {
719 usermap[i + j * nprow] = Cblacs_pnum(ori, i, j);
720 }
721 /* Cblacs_get(0, 0, &final); */
722 Cblacs_get(ori, (Int)10, &final);
723 Cblacs_gridmap(&final, usermap, (Int)1, (Int)1, nprow * npcol);
724 *ctxtp = final;
725 free(usermap);
void Cblacs_gridmap()
Int Cblacs_pnum()

◆ init_chenille() [1/2]

static2 void init_chenille ( )

◆ init_chenille() [2/2]

static2 void init_chenille ( Int mypnum,
Int nprocs,
Int n0,
Int * proc0,
Int n1,
Int * proc1,
Int ** psend,
Int ** precv,
Int * myrang )

Definition at line 564 of file pdgemr.c.

568{
569 Int ns, nr, i, tot;
570 Int *sender, *recver, *g0, *g1;
571 tot = max(n0, n1);
572 sender = (Int *) mr2d_malloc((nprocs + tot) * sizeof(Int) * 2);
573 recver = sender + tot;
574 *psend = sender;
575 *precv = recver;
576 g0 = recver + tot;
577 g1 = g0 + nprocs;
578 for (i = 0; i < nprocs; i++) {
579 g0[i] = -1;
580 g1[i] = -1;
581 }
582 for (i = 0; i < tot; i++) {
583 sender[i] = -1;
584 recver[i] = -1;
585 }
586 for (i = 0; i < n0; i++)
587 g0[proc0[i]] = i;
588 for (i = 0; i < n1; i++)
589 g1[proc1[i]] = i;
590 ns = 0;
591 nr = 0;
592 *myrang = -1;
593 for (i = 0; i < nprocs; i++)
594 if (g0[i] >= 0 && g1[i] >= 0) {
595 if (i == mypnum)
596 *myrang = nr;
597 sender[ns] = g0[i];
598 ns += 1;
599 recver[nr] = g1[i];
600 nr += 1;
601 assert(ns <= n0 && nr <= n1 && nr == ns);
602 }
603 for (i = 0; i < nprocs; i++)
604 if (g0[i] >= 0 && g1[i] < 0) {
605 if (i == mypnum)
606 *myrang = ns;
607 sender[ns] = g0[i];
608 ns += 1;
609 assert(ns <= n0);
610 }
611 for (i = 0; i < nprocs; i++)
612 if (g1[i] >= 0 && g0[i] < 0) {
613 if (i == mypnum)
614 *myrang = nr;
615 recver[nr] = g1[i];
616 nr += 1;
617 assert(nr <= n1);
618 }

◆ inter_len() [1/2]

static2 Int inter_len ( )

◆ inter_len() [2/2]

static2 Int inter_len ( Int hinb,
IDESC * hi,
Int vinb,
IDESC * vi )

Definition at line 680 of file pdgemr.c.

682{
683 Int hlen, vlen, h, v;
684 hlen = 0;
685 for (h = 0; h < hinb; h++)
686 hlen += hi[h].len;
687 vlen = 0;
688 for (v = 0; v < vinb; v++)
689 vlen += vi[v].len;
690 return hlen * vlen;

◆ localindice()

Int localindice ( )
extern

◆ localsize()

Int localsize ( )
extern

◆ memoryblocksize()

Int memoryblocksize ( )
extern

◆ mr2d_malloc()

void * mr2d_malloc ( )
extern

◆ paramcheck()

void paramcheck ( )
extern

◆ ppcm()

Int ppcm ( )
extern