ScaLAPACK  2.0.2
ScaLAPACK: Scalable Linear Algebra PACKage
dgebr2d_.c
Go to the documentation of this file.
00001 #include "Bdef.h"
00002 
00003 #if (INTFACE == C_CALL)
00004 void Cdgebr2d(int ConTxt, char *scope, char *top, int m, int n, double *A,
00005               int lda, int rsrc, int csrc)
00006 #else
00007 F_VOID_FUNC dgebr2d_(int *ConTxt, F_CHAR scope, F_CHAR top, int *m, int *n,
00008                      double *A, int *lda, int *rsrc, int *csrc)
00009 #endif
00010 /*
00011  *  -- V1.1 BLACS routine --
00012  *  University of Tennessee, May 1, 1996
00013  *  Written by Clint Whaley.
00014  *
00015  *  Purpose
00016  *  =======
00017  *  Broadcast/receive for general double precision arrays.
00018  *
00019  *  Arguments
00020  *  =========
00021  *
00022  *  ConTxt  (input) Ptr to int
00023  *          Index into MyConTxts00 (my contexts array).
00024  *
00025  *  SCOPE   (input) Ptr to char
00026  *          Limit the scope of the operation.
00027  *          = 'R' :   Operation is performed by a process row.
00028  *          = 'C' :   Operation is performed by a process column.
00029  *          = 'A' :   Operation is performed by all processes in grid.
00030  *
00031  *  TOP     (input) Ptr to char
00032  *          Controls fashion in which messages flow within the operation.
00033  *
00034  *  M       (input) Ptr to int
00035  *          The number of rows of the matrix A.  M >= 0.
00036  *
00037  *  N       (input) Ptr to int
00038  *          The number of columns of the matrix A.  N >= 0.
00039  *
00040  *  A       (output) Ptr to double precision two dimensional array
00041  *          The m by n matrix A.  Fortran77 (column-major) storage
00042  *          assumed.
00043  *
00044  *  LDA     (input) Ptr to int
00045  *          The leading dimension of the array A.  LDA >= M.
00046  *
00047  *
00048  *  RSRC    (input) Ptr to int
00049  *          The process row of the source of the matrix.
00050  *
00051  *  CSRC    (input) Ptr to int
00052  *          The process column of the source of the matrix.
00053  *
00054  *
00055  * ------------------------------------------------------------------------
00056  */
00057 {
00058    void BI_ArgCheck(int, int, char *, char, char, char, int, int, int, int,
00059                     int *, int *);
00060    int BI_HypBR(BLACSCONTEXT *, BLACBUFF *, SDRVPTR, int);
00061    void BI_IdringBR(BLACSCONTEXT *, BLACBUFF *, SDRVPTR, int, int);
00062    void BI_SringBR(BLACSCONTEXT *, BLACBUFF *, SDRVPTR, int);
00063    void BI_MpathBR(BLACSCONTEXT *, BLACBUFF *, SDRVPTR, int, int);
00064    void BI_TreeBR(BLACSCONTEXT *, BLACBUFF *, SDRVPTR, int, int);
00065    void BI_UpdateBuffs(BLACBUFF *);
00066    BLACBUFF *BI_GetBuff(int);
00067    int BI_BuffIsFree(BLACBUFF *, int);
00068    MPI_Datatype BI_GetMpiGeType(BLACSCONTEXT *, int, int, int,
00069                                    MPI_Datatype, int *);
00070    void BI_Unpack(BLACSCONTEXT *, BVOID *, BLACBUFF *, MPI_Datatype);
00071    void BI_Ssend(BLACSCONTEXT *, int, int, BLACBUFF *);
00072    void BI_Asend(BLACSCONTEXT *, int, int, BLACBUFF *);
00073 
00074    BLACSCONTEXT *ctxt;
00075    BLACBUFF *bp=NULL;
00076    SDRVPTR send;
00077    MPI_Datatype MatTyp;
00078    int length, src, tlda, error, one=1;
00079    char ttop, tscope;
00080    extern BLACBUFF BI_AuxBuff, *BI_ActiveQ;
00081 
00082    MGetConTxt(Mpval(ConTxt), ctxt);
00083    ttop = F2C_CharTrans(top);
00084    ttop = Mlowcase(ttop);
00085    tscope = F2C_CharTrans(scope);
00086    tscope = Mlowcase(tscope);
00087 #if (BlacsDebugLvl > 0)
00088    BI_ArgCheck(Mpval(ConTxt), RT_BR, __FILE__, tscope, 'u', 'u', Mpval(m),
00089                Mpval(n), Mpval(lda), 1, Mpaddress(rsrc), Mpaddress(csrc));
00090 #endif
00091 /*
00092  *  If the user has set the default broadcast topology, use it instead of
00093  *  BLACS default
00094  */
00095 #ifdef DefBSTop
00096    if (ttop == ' ') ttop = DefBSTop;
00097 #endif
00098    if (Mpval(m) <= Mpval(lda)) tlda = Mpval(lda);
00099    else tlda = Mpval(m);
00100 
00101    switch(tscope)
00102    {
00103    case 'r':
00104       ctxt->scp = &ctxt->rscp;
00105       src = Mpval(csrc);
00106       break;
00107    case 'c':
00108       ctxt->scp = &ctxt->cscp;
00109       src = Mpval(rsrc);
00110       break;
00111    case 'a':
00112       ctxt->scp = &ctxt->ascp;
00113       src = Mvkpnum(ctxt, Mpval(rsrc), Mpval(csrc));
00114       break;
00115    default:
00116       BI_BlacsErr(Mpval(ConTxt), __LINE__, __FILE__, "Unknown scope '%c'",
00117                   tscope);
00118    }
00119 
00120    MatTyp = BI_GetMpiGeType(ctxt, Mpval(m), Mpval(n), tlda,
00121                             MPI_DOUBLE, &BI_AuxBuff.N);
00122 /*
00123  * If using default topology, use MPI native broadcast
00124  */
00125    if (ttop == ' ')
00126    {
00127       error=MPI_Bcast(A, BI_AuxBuff.N, MatTyp, src, ctxt->scp->comm);
00128       error=BI_MPI_TYPE_FREE(&MatTyp);
00129       if (BI_ActiveQ) BI_UpdateBuffs(NULL);
00130       return;
00131    }
00132 /*
00133  * If MPI handles non-contiguous buffering well, always use MPI data types
00134  * instead of packing
00135  */
00136 #ifndef MpiBuffGood
00137 /*
00138  * If A is contiguous, receive and send directly to/from it
00139  */
00140    else if ( (tlda == Mpval(m)) || (Mpval(n) == 1) )
00141    {
00142 #endif
00143       send = BI_Ssend;
00144       BI_AuxBuff.Buff = (char *) A;
00145       BI_AuxBuff.dtype = MatTyp;
00146       bp = &BI_AuxBuff;
00147 #ifndef MpiBuffGood
00148    }
00149 /*
00150  * If A is not contiguous, we receive message as packed so it can be
00151  * forwarded without further system intervention
00152  */
00153    else
00154    {
00155       send = BI_Asend;
00156       error=MPI_Pack_size(one, MatTyp, ctxt->scp->comm, &length);
00157       bp = BI_GetBuff(length);
00158       bp->N = length;
00159       bp->dtype = MPI_PACKED;
00160 #if ZeroByteTypeBug
00161       if (MatTyp == MPI_BYTE)
00162       {
00163          send = BI_Ssend;
00164          bp->N = 0;
00165          bp->dtype = MPI_BYTE;
00166       }
00167 #endif
00168    }
00169 #endif
00170 
00171    switch(ttop)
00172    {
00173    case 'h':
00174       error = BI_HypBR(ctxt, bp, send, src);
00175       if (error == NPOW2) BI_TreeBR(ctxt, bp, send, src, 2);
00176       break;
00177    case '1':
00178    case '2':
00179    case '3':
00180    case '4':
00181    case '5':
00182    case '6':
00183    case '7':
00184    case '8':
00185    case '9':
00186       BI_TreeBR(ctxt, bp, send, src, ttop-47);
00187       break;
00188    case 't':
00189       BI_TreeBR(ctxt, bp, send, src, ctxt->Nb_bs);
00190       break;
00191    case 'i':
00192       BI_IdringBR(ctxt, bp, send, src, 1);
00193       break;
00194    case 'd':
00195       BI_IdringBR(ctxt, bp, send, src, -1);
00196       break;
00197    case 's':
00198       BI_SringBR(ctxt, bp, send, src);
00199       break;
00200    case 'm':
00201       BI_MpathBR(ctxt, bp, send, src, ctxt->Nr_bs);
00202       break;
00203    case 'f':
00204       BI_MpathBR(ctxt, bp, send, src, FULLCON);
00205       break;
00206    default :
00207       BI_BlacsErr(Mpval(ConTxt), __LINE__, __FILE__, "Unknown topology '%c'",
00208                   ttop);
00209    }
00210 
00211 /*
00212  * If we buffered, unpack.
00213  */
00214 #ifndef MpiBuffGood
00215    if (bp != &BI_AuxBuff)
00216    {
00217       BI_Unpack(ctxt, (BVOID *) A, bp, MatTyp);
00218       BI_UpdateBuffs(bp);
00219    }
00220    else
00221 #endif
00222    {
00223       error=BI_MPI_TYPE_FREE(&MatTyp);
00224       if (BI_ActiveQ) BI_UpdateBuffs(NULL);
00225    }
00226 }