1*db31f6deSJed Brown #include <../src/mat/impls/elemental/matelemimpl.h> /*I "petscmat.h" I*/ 2*db31f6deSJed Brown 3*db31f6deSJed Brown #undef __FUNCT__ 4*db31f6deSJed Brown #define __FUNCT__ "PetscElementalInitializePackage" 5*db31f6deSJed Brown /*@C 6*db31f6deSJed Brown PetscElementalInitializePackage - Initialize Elemental package 7*db31f6deSJed Brown 8*db31f6deSJed Brown Logically Collective 9*db31f6deSJed Brown 10*db31f6deSJed Brown Input Arguments: 11*db31f6deSJed Brown . path - the dynamic library path or PETSC_NULL 12*db31f6deSJed Brown 13*db31f6deSJed Brown Level: developer 14*db31f6deSJed Brown 15*db31f6deSJed Brown .seealso: MATELEMENTAL, PetscElementalFinalizePackage() 16*db31f6deSJed Brown @*/ 17*db31f6deSJed Brown PetscErrorCode PetscElementalInitializePackage(const char *path) 18*db31f6deSJed Brown { 19*db31f6deSJed Brown PetscErrorCode ierr; 20*db31f6deSJed Brown 21*db31f6deSJed Brown PetscFunctionBegin; 22*db31f6deSJed Brown if (elem::Initialized()) PetscFunctionReturn(0); 23*db31f6deSJed Brown { /* We have already initialized MPI, so this song and dance is just to pass these variables (which won't be used by Elemental) through the interface that needs references */ 24*db31f6deSJed Brown int zero = 0; 25*db31f6deSJed Brown char **nothing = 0; 26*db31f6deSJed Brown elem::Initialize(zero,nothing); 27*db31f6deSJed Brown } 28*db31f6deSJed Brown ierr = PetscRegisterFinalize(PetscElementalFinalizePackage);CHKERRQ(ierr); 29*db31f6deSJed Brown PetscFunctionReturn(0); 30*db31f6deSJed Brown } 31*db31f6deSJed Brown 32*db31f6deSJed Brown #undef __FUNCT__ 33*db31f6deSJed Brown #define __FUNCT__ "PetscElementalFinalizePackage" 34*db31f6deSJed Brown /*@C 35*db31f6deSJed Brown PetscElementalFinalizePackage - Finalize Elemental package 36*db31f6deSJed Brown 37*db31f6deSJed Brown Logically Collective 38*db31f6deSJed Brown 39*db31f6deSJed Brown Level: developer 40*db31f6deSJed Brown 41*db31f6deSJed Brown .seealso: MATELEMENTAL, PetscElementalInitializePackage() 42*db31f6deSJed Brown @*/ 43*db31f6deSJed Brown PetscErrorCode PetscElementalFinalizePackage(void) 44*db31f6deSJed Brown { 45*db31f6deSJed Brown 46*db31f6deSJed Brown PetscFunctionBegin; 47*db31f6deSJed Brown elem::Finalize(); 48*db31f6deSJed Brown PetscFunctionReturn(0); 49*db31f6deSJed Brown } 50*db31f6deSJed Brown 51*db31f6deSJed Brown #undef __FUNCT__ 52*db31f6deSJed Brown #define __FUNCT__ "MatView_Elemental" 53*db31f6deSJed Brown static PetscErrorCode MatView_Elemental(Mat A,PetscViewer viewer) 54*db31f6deSJed Brown { 55*db31f6deSJed Brown PetscErrorCode ierr; 56*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 57*db31f6deSJed Brown PetscBool iascii; 58*db31f6deSJed Brown 59*db31f6deSJed Brown PetscFunctionBegin; 60*db31f6deSJed Brown ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 61*db31f6deSJed Brown if (iascii) { 62*db31f6deSJed Brown PetscViewerFormat format; 63*db31f6deSJed Brown ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 64*db31f6deSJed Brown if (format == PETSC_VIEWER_ASCII_INFO) { 65*db31f6deSJed Brown SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Info viewer not implemented yet"); 66*db31f6deSJed Brown } else if (format == PETSC_VIEWER_DEFAULT) { 67*db31f6deSJed Brown ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 68*db31f6deSJed Brown ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 69*db31f6deSJed Brown a->emat->Print("Elemental matrix (cyclic ordering)"); 70*db31f6deSJed Brown ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 71*db31f6deSJed Brown } else SETERRQ(((PetscObject)viewer)->comm,PETSC_ERR_SUP,"Format"); 72*db31f6deSJed Brown } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by Elemental matrices",((PetscObject)viewer)->type_name); 73*db31f6deSJed Brown PetscFunctionReturn(0); 74*db31f6deSJed Brown } 75*db31f6deSJed Brown 76*db31f6deSJed Brown #undef __FUNCT__ 77*db31f6deSJed Brown #define __FUNCT__ "MatSetValues_Elemental" 78*db31f6deSJed Brown static PetscErrorCode MatSetValues_Elemental(Mat A,PetscInt nr,const PetscInt *rows,PetscInt nc,const PetscInt *cols,const PetscScalar *vals,InsertMode imode) 79*db31f6deSJed Brown { 80*db31f6deSJed Brown PetscErrorCode ierr; 81*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 82*db31f6deSJed Brown PetscMPIInt rank; 83*db31f6deSJed Brown PetscInt i,j,rrank,ridx,crank,cidx; 84*db31f6deSJed Brown 85*db31f6deSJed Brown PetscFunctionBegin; 86*db31f6deSJed Brown ierr = MPI_Comm_rank(((PetscObject)A)->comm,&rank);CHKERRQ(ierr); 87*db31f6deSJed Brown 88*db31f6deSJed Brown const elem::Grid &grid = a->emat->Grid(); 89*db31f6deSJed Brown for (i=0; i<nr; i++) { 90*db31f6deSJed Brown PetscInt erow,ecol,elrow,elcol; 91*db31f6deSJed Brown if (rows[i] < 0) continue; 92*db31f6deSJed Brown P2RO(A,0,rows[i],&rrank,&ridx); 93*db31f6deSJed Brown RO2E(A,0,rrank,ridx,&erow); 94*db31f6deSJed Brown if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Incorrect row translation"); 95*db31f6deSJed Brown for (j=0; j<nc; j++) { 96*db31f6deSJed Brown if (cols[j] < 0) continue; 97*db31f6deSJed Brown P2RO(A,1,cols[j],&crank,&cidx); 98*db31f6deSJed Brown RO2E(A,1,crank,cidx,&ecol); 99*db31f6deSJed Brown if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Incorrect col translation"); 100*db31f6deSJed Brown if (erow % grid.MCSize() != grid.MCRank() || ecol % grid.MRSize() != grid.MRRank()) 101*db31f6deSJed Brown SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for setting off-process entry (%D,%D), Elemental (%D,%D)",rows[i],cols[j],erow,ecol); 102*db31f6deSJed Brown elrow = erow / grid.MCSize(); 103*db31f6deSJed Brown elcol = ecol / grid.MRSize(); 104*db31f6deSJed Brown switch (imode) { 105*db31f6deSJed Brown case INSERT_VALUES: a->emat->SetLocal(elrow,elcol,vals[i*nc+j]); break; 106*db31f6deSJed Brown case ADD_VALUES: a->emat->UpdateLocal(elrow,elcol,vals[i*nc+j]); break; 107*db31f6deSJed Brown default: SETERRQ1(((PetscObject)A)->comm,PETSC_ERR_SUP,"No support for InsertMode %d",(int)imode); 108*db31f6deSJed Brown } 109*db31f6deSJed Brown } 110*db31f6deSJed Brown } 111*db31f6deSJed Brown PetscFunctionReturn(0); 112*db31f6deSJed Brown } 113*db31f6deSJed Brown 114*db31f6deSJed Brown #undef __FUNCT__ 115*db31f6deSJed Brown #define __FUNCT__ "MatMult_Elemental" 116*db31f6deSJed Brown static PetscErrorCode MatMult_Elemental(Mat A,Vec X,Vec Y) 117*db31f6deSJed Brown { 118*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 119*db31f6deSJed Brown PetscErrorCode ierr; 120*db31f6deSJed Brown const PetscScalar *x; 121*db31f6deSJed Brown PetscScalar *y; 122*db31f6deSJed Brown PetscScalar one = 1,zero = 0; 123*db31f6deSJed Brown 124*db31f6deSJed Brown PetscFunctionBegin; 125*db31f6deSJed Brown ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 126*db31f6deSJed Brown ierr = VecGetArray(Y,&y);CHKERRQ(ierr); 127*db31f6deSJed Brown { /* Scoping so that constructor is called before pointer is returned */ 128*db31f6deSJed Brown elem::DistMatrix<PetscScalar,elem::VC,elem::STAR> xe(A->cmap->N,1,0,x,A->cmap->n,*a->grid); 129*db31f6deSJed Brown elem::DistMatrix<PetscScalar,elem::VC,elem::STAR> ye(A->rmap->N,1,0,y,A->rmap->n,*a->grid); 130*db31f6deSJed Brown elem::Gemv(elem::NORMAL,one,*a->emat,xe,zero,ye); 131*db31f6deSJed Brown } 132*db31f6deSJed Brown ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 133*db31f6deSJed Brown ierr = VecRestoreArray(Y,&y);CHKERRQ(ierr); 134*db31f6deSJed Brown PetscFunctionReturn(0); 135*db31f6deSJed Brown } 136*db31f6deSJed Brown 137*db31f6deSJed Brown #undef __FUNCT__ 138*db31f6deSJed Brown #define __FUNCT__ "MatMultAdd_Elemental" 139*db31f6deSJed Brown static PetscErrorCode MatMultAdd_Elemental(Mat A,Vec X,Vec Y,Vec Z) 140*db31f6deSJed Brown { 141*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 142*db31f6deSJed Brown PetscErrorCode ierr; 143*db31f6deSJed Brown const PetscScalar *x; 144*db31f6deSJed Brown PetscScalar *z; 145*db31f6deSJed Brown PetscScalar one = 1; 146*db31f6deSJed Brown 147*db31f6deSJed Brown PetscFunctionBegin; 148*db31f6deSJed Brown if (Y != Z) {ierr = VecCopy(Y,Z);CHKERRQ(ierr);} 149*db31f6deSJed Brown ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 150*db31f6deSJed Brown ierr = VecGetArray(Z,&z);CHKERRQ(ierr); 151*db31f6deSJed Brown { /* Scoping so that constructor is called before pointer is returned */ 152*db31f6deSJed Brown elem::DistMatrix<PetscScalar,elem::VC,elem::STAR> xe(A->cmap->N,1,0,x,A->cmap->n,*a->grid); 153*db31f6deSJed Brown elem::DistMatrix<PetscScalar,elem::VC,elem::STAR> ze(A->rmap->N,1,0,z,A->rmap->n,*a->grid); 154*db31f6deSJed Brown elem::Gemv(elem::NORMAL,one,*a->emat,xe,one,ze); 155*db31f6deSJed Brown } 156*db31f6deSJed Brown ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 157*db31f6deSJed Brown ierr = VecRestoreArray(Z,&z);CHKERRQ(ierr); 158*db31f6deSJed Brown PetscFunctionReturn(0); 159*db31f6deSJed Brown } 160*db31f6deSJed Brown 161*db31f6deSJed Brown #undef __FUNCT__ 162*db31f6deSJed Brown #define __FUNCT__ "MatGetOwnershipIS_Elemental" 163*db31f6deSJed Brown static PetscErrorCode MatGetOwnershipIS_Elemental(Mat A,IS *rows,IS *cols) 164*db31f6deSJed Brown { 165*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 166*db31f6deSJed Brown PetscErrorCode ierr; 167*db31f6deSJed Brown PetscInt i,m,shift,stride,*idx; 168*db31f6deSJed Brown 169*db31f6deSJed Brown PetscFunctionBegin; 170*db31f6deSJed Brown if (rows) { 171*db31f6deSJed Brown m = a->emat->LocalHeight(); 172*db31f6deSJed Brown shift = a->emat->ColShift(); 173*db31f6deSJed Brown stride = a->emat->ColStride(); 174*db31f6deSJed Brown ierr = PetscMalloc(m*sizeof(PetscInt),&idx);CHKERRQ(ierr); 175*db31f6deSJed Brown for (i=0; i<m; i++) { 176*db31f6deSJed Brown PetscInt rank,offset; 177*db31f6deSJed Brown E2RO(A,0,shift+i*stride,&rank,&offset); 178*db31f6deSJed Brown RO2P(A,0,rank,offset,&idx[i]); 179*db31f6deSJed Brown } 180*db31f6deSJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,m,idx,PETSC_OWN_POINTER,rows);CHKERRQ(ierr); 181*db31f6deSJed Brown } 182*db31f6deSJed Brown if (cols) { 183*db31f6deSJed Brown m = a->emat->LocalWidth(); 184*db31f6deSJed Brown shift = a->emat->RowShift(); 185*db31f6deSJed Brown stride = a->emat->RowStride(); 186*db31f6deSJed Brown ierr = PetscMalloc(m*sizeof(PetscInt),&idx);CHKERRQ(ierr); 187*db31f6deSJed Brown for (i=0; i<m; i++) { 188*db31f6deSJed Brown PetscInt rank,offset; 189*db31f6deSJed Brown E2RO(A,1,shift+i*stride,&rank,&offset); 190*db31f6deSJed Brown RO2P(A,1,rank,offset,&idx[i]); 191*db31f6deSJed Brown } 192*db31f6deSJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,m,idx,PETSC_OWN_POINTER,cols);CHKERRQ(ierr); 193*db31f6deSJed Brown } 194*db31f6deSJed Brown PetscFunctionReturn(0); 195*db31f6deSJed Brown } 196*db31f6deSJed Brown 197*db31f6deSJed Brown #undef __FUNCT__ 198*db31f6deSJed Brown #define __FUNCT__ "MatDestroy_Elemental" 199*db31f6deSJed Brown static PetscErrorCode MatDestroy_Elemental(Mat A) 200*db31f6deSJed Brown { 201*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 202*db31f6deSJed Brown PetscErrorCode ierr; 203*db31f6deSJed Brown 204*db31f6deSJed Brown PetscFunctionBegin; 205*db31f6deSJed Brown delete a->emat; 206*db31f6deSJed Brown delete a->grid; 207*db31f6deSJed Brown ierr = MatStashDestroy_Private(&A->stash);CHKERRQ(ierr); 208*db31f6deSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatGetOwnershipIS_C","",PETSC_NULL);CHKERRQ(ierr); 209*db31f6deSJed Brown ierr = PetscFree(A->data);CHKERRQ(ierr); 210*db31f6deSJed Brown PetscFunctionReturn(0); 211*db31f6deSJed Brown } 212*db31f6deSJed Brown 213*db31f6deSJed Brown #undef __FUNCT__ 214*db31f6deSJed Brown #define __FUNCT__ "MatSetUp_Elemental" 215*db31f6deSJed Brown PetscErrorCode MatSetUp_Elemental(Mat A) 216*db31f6deSJed Brown { 217*db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 218*db31f6deSJed Brown PetscErrorCode ierr; 219*db31f6deSJed Brown PetscMPIInt rsize,csize; 220*db31f6deSJed Brown 221*db31f6deSJed Brown PetscFunctionBegin; 222*db31f6deSJed Brown ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 223*db31f6deSJed Brown ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 224*db31f6deSJed Brown 225*db31f6deSJed Brown a->emat->ResizeTo(A->rmap->N,A->cmap->N);CHKERRQ(ierr); 226*db31f6deSJed Brown elem::Zero(*a->emat); 227*db31f6deSJed Brown 228*db31f6deSJed Brown ierr = MPI_Comm_size(A->rmap->comm,&rsize);CHKERRQ(ierr); 229*db31f6deSJed Brown ierr = MPI_Comm_size(A->cmap->comm,&csize);CHKERRQ(ierr); 230*db31f6deSJed Brown if (csize != rsize) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_INCOMP,"Cannot use row and column communicators of different sizes"); 231*db31f6deSJed Brown a->commsize = rsize; 232*db31f6deSJed Brown a->mr[0] = A->rmap->N % rsize; if (!a->mr[0]) a->mr[0] = rsize; 233*db31f6deSJed Brown a->mr[1] = A->cmap->N % csize; if (!a->mr[1]) a->mr[1] = csize; 234*db31f6deSJed Brown a->m[0] = A->rmap->N / rsize + (a->mr[0] != rsize); 235*db31f6deSJed Brown a->m[1] = A->cmap->N / csize + (a->mr[1] != csize); 236*db31f6deSJed Brown PetscFunctionReturn(0); 237*db31f6deSJed Brown } 238*db31f6deSJed Brown 239*db31f6deSJed Brown #undef __FUNCT__ 240*db31f6deSJed Brown #define __FUNCT__ "MatCreate_Elemental" 241*db31f6deSJed Brown PETSC_EXTERN_C PetscErrorCode MatCreate_Elemental(Mat A) 242*db31f6deSJed Brown { 243*db31f6deSJed Brown Mat_Elemental *a; 244*db31f6deSJed Brown PetscErrorCode ierr; 245*db31f6deSJed Brown 246*db31f6deSJed Brown PetscFunctionBegin; 247*db31f6deSJed Brown ierr = PetscElementalInitializePackage(PETSC_NULL);CHKERRQ(ierr); 248*db31f6deSJed Brown 249*db31f6deSJed Brown ierr = PetscNewLog(A,Mat_Elemental,&a);CHKERRQ(ierr); 250*db31f6deSJed Brown A->data = (void*)a; 251*db31f6deSJed Brown 252*db31f6deSJed Brown A->ops->view = MatView_Elemental; 253*db31f6deSJed Brown A->ops->destroy = MatDestroy_Elemental; 254*db31f6deSJed Brown A->ops->setup = MatSetUp_Elemental; 255*db31f6deSJed Brown A->ops->setvalues = MatSetValues_Elemental; 256*db31f6deSJed Brown A->ops->mult = MatMult_Elemental; 257*db31f6deSJed Brown A->ops->multadd = MatMultAdd_Elemental; 258*db31f6deSJed Brown 259*db31f6deSJed Brown A->insertmode = NOT_SET_VALUES; 260*db31f6deSJed Brown 261*db31f6deSJed Brown /* Set up the elemental matrix */ 262*db31f6deSJed Brown elem::mpi::Comm cxxcomm(((PetscObject)A)->comm); 263*db31f6deSJed Brown a->grid = new elem::Grid(cxxcomm); 264*db31f6deSJed Brown a->emat = new elem::DistMatrix<PetscScalar>(*a->grid); 265*db31f6deSJed Brown 266*db31f6deSJed Brown /* build cache for off array entries formed */ 267*db31f6deSJed Brown ierr = MatStashCreate_Private(((PetscObject)A)->comm,1,&A->stash);CHKERRQ(ierr); 268*db31f6deSJed Brown ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatGetOwnershipIS_C","MatGetOwnershipIS_Elemental",MatGetOwnershipIS_Elemental);CHKERRQ(ierr); 269*db31f6deSJed Brown 270*db31f6deSJed Brown ierr = PetscObjectChangeTypeName((PetscObject)A,MATELEMENTAL);CHKERRQ(ierr); 271*db31f6deSJed Brown PetscFunctionReturn(0); 272*db31f6deSJed Brown } 273*db31f6deSJed Brown 274*db31f6deSJed Brown /*MC 275*db31f6deSJed Brown MATELEMENTAL = "elemental" - A matrix type for dense matrices using the Elemental package 276*db31f6deSJed Brown 277*db31f6deSJed Brown Options Database Keys: 278*db31f6deSJed Brown . -mat_type elemental - sets the matrix type to "elemental" during a call to MatSetFromOptions() 279*db31f6deSJed Brown 280*db31f6deSJed Brown Level: beginner 281*db31f6deSJed Brown 282*db31f6deSJed Brown 283*db31f6deSJed Brown .seealso: MATDENSE,MatCreateElemental() 284*db31f6deSJed Brown M*/ 285