11673f470SJose E. Roman #include <petsc/private/petscelemental.h> 2db31f6deSJed Brown 35e9f5b67SHong Zhang /* 45e9f5b67SHong Zhang The variable Petsc_Elemental_keyval is used to indicate an MPI attribute that 55e9f5b67SHong Zhang is attached to a communicator, in this case the attribute is a Mat_Elemental_Grid 65e9f5b67SHong Zhang */ 75e9f5b67SHong Zhang static PetscMPIInt Petsc_Elemental_keyval = MPI_KEYVAL_INVALID; 85e9f5b67SHong Zhang 9db31f6deSJed Brown static PetscErrorCode MatView_Elemental(Mat A,PetscViewer viewer) 10db31f6deSJed Brown { 11db31f6deSJed Brown PetscErrorCode ierr; 12db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 13db31f6deSJed Brown PetscBool iascii; 14db31f6deSJed Brown 15db31f6deSJed Brown PetscFunctionBegin; 16db31f6deSJed Brown ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 17db31f6deSJed Brown if (iascii) { 18db31f6deSJed Brown PetscViewerFormat format; 19db31f6deSJed Brown ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 20db31f6deSJed Brown if (format == PETSC_VIEWER_ASCII_INFO) { 2179673f7bSHong Zhang /* call elemental viewing function */ 222d8adcc7SHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"Elemental run parameters:\n");CHKERRQ(ierr); 23ed667823SXuan Zhou ierr = PetscViewerASCIIPrintf(viewer," allocated entries=%d\n",(*a->emat).AllocatedMemory());CHKERRQ(ierr); 24ed667823SXuan Zhou ierr = PetscViewerASCIIPrintf(viewer," grid height=%d, grid width=%d\n",(*a->emat).Grid().Height(),(*a->emat).Grid().Width());CHKERRQ(ierr); 254fe7bbcaSHong Zhang if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 2679673f7bSHong Zhang /* call elemental viewing function */ 27ce94432eSBarry Smith ierr = PetscPrintf(PetscObjectComm((PetscObject)viewer),"test matview_elemental 2\n");CHKERRQ(ierr); 284fe7bbcaSHong Zhang } 2979673f7bSHong Zhang 30db31f6deSJed Brown } else if (format == PETSC_VIEWER_DEFAULT) { 31db31f6deSJed Brown ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 32e8146892SSatish Balay El::Print( *a->emat, "Elemental matrix (cyclic ordering)"); 33db31f6deSJed Brown ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 34834d3fecSHong Zhang if (A->factortype == MAT_FACTOR_NONE){ 3561119200SXuan Zhou Mat Adense; 3661119200SXuan Zhou ierr = MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&Adense);CHKERRQ(ierr); 3761119200SXuan Zhou ierr = MatView(Adense,viewer);CHKERRQ(ierr); 3861119200SXuan Zhou ierr = MatDestroy(&Adense);CHKERRQ(ierr); 39834d3fecSHong Zhang } 40ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Format"); 41d2daa67eSHong Zhang } else { 425cb544a0SHong Zhang /* convert to dense format and call MatView() */ 4361119200SXuan Zhou Mat Adense; 4461119200SXuan Zhou ierr = MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&Adense);CHKERRQ(ierr); 4561119200SXuan Zhou ierr = MatView(Adense,viewer);CHKERRQ(ierr); 4661119200SXuan Zhou ierr = MatDestroy(&Adense);CHKERRQ(ierr); 47d2daa67eSHong Zhang } 48db31f6deSJed Brown PetscFunctionReturn(0); 49db31f6deSJed Brown } 50db31f6deSJed Brown 5115767789SHong Zhang static PetscErrorCode MatGetInfo_Elemental(Mat A,MatInfoType flag,MatInfo *info) 52180a43e4SHong Zhang { 5315767789SHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 5415767789SHong Zhang 55180a43e4SHong Zhang PetscFunctionBegin; 565cb544a0SHong Zhang info->block_size = 1.0; 5715767789SHong Zhang 5815767789SHong Zhang if (flag == MAT_LOCAL) { 593966268fSBarry Smith info->nz_allocated = (*a->emat).AllocatedMemory(); /* locally allocated */ 6015767789SHong Zhang info->nz_used = info->nz_allocated; 6115767789SHong Zhang } else if (flag == MAT_GLOBAL_MAX) { 62820f2d46SBarry Smith //ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)matin));CHKERRMPI(ierr); 6315767789SHong Zhang /* see MatGetInfo_MPIAIJ() for getting global info->nz_allocated! */ 6415767789SHong Zhang //SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP," MAT_GLOBAL_MAX not written yet"); 6515767789SHong Zhang } else if (flag == MAT_GLOBAL_SUM) { 6615767789SHong Zhang //SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP," MAT_GLOBAL_SUM not written yet"); 673966268fSBarry Smith info->nz_allocated = (*a->emat).AllocatedMemory(); /* locally allocated */ 6815767789SHong Zhang info->nz_used = info->nz_allocated; /* assume Elemental does accurate allocation */ 69820f2d46SBarry Smith //ierr = MPIU_Allreduce(isend,irecv,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRMPI(ierr); 7015767789SHong Zhang //PetscPrintf(PETSC_COMM_SELF," ... [%d] locally allocated %g\n",rank,info->nz_allocated); 7115767789SHong Zhang } 7215767789SHong Zhang 7315767789SHong Zhang info->nz_unneeded = 0.0; 743966268fSBarry Smith info->assemblies = A->num_ass; 7515767789SHong Zhang info->mallocs = 0; 7615767789SHong Zhang info->memory = ((PetscObject)A)->mem; 7715767789SHong Zhang info->fill_ratio_given = 0; /* determined by Elemental */ 7815767789SHong Zhang info->fill_ratio_needed = 0; 7915767789SHong Zhang info->factor_mallocs = 0; 80180a43e4SHong Zhang PetscFunctionReturn(0); 81180a43e4SHong Zhang } 82180a43e4SHong Zhang 8332d7a744SHong Zhang PetscErrorCode MatSetOption_Elemental(Mat A,MatOption op,PetscBool flg) 8432d7a744SHong Zhang { 8532d7a744SHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 8632d7a744SHong Zhang 8732d7a744SHong Zhang PetscFunctionBegin; 8832d7a744SHong Zhang switch (op) { 8932d7a744SHong Zhang case MAT_NEW_NONZERO_LOCATIONS: 9032d7a744SHong Zhang case MAT_NEW_NONZERO_LOCATION_ERR: 9132d7a744SHong Zhang case MAT_NEW_NONZERO_ALLOCATION_ERR: 92891a0571SHong Zhang case MAT_SYMMETRIC: 93071fcb05SBarry Smith case MAT_SORTED_FULL: 94eb1ec7c1SStefano Zampini case MAT_HERMITIAN: 95891a0571SHong Zhang break; 9632d7a744SHong Zhang case MAT_ROW_ORIENTED: 9732d7a744SHong Zhang a->roworiented = flg; 9832d7a744SHong Zhang break; 9932d7a744SHong Zhang default: 10032d7a744SHong Zhang SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]); 10132d7a744SHong Zhang } 10232d7a744SHong Zhang PetscFunctionReturn(0); 10332d7a744SHong Zhang } 10432d7a744SHong Zhang 105e6dea9dbSXuan Zhou static PetscErrorCode MatSetValues_Elemental(Mat A,PetscInt nr,const PetscInt *rows,PetscInt nc,const PetscInt *cols,const PetscScalar *vals,InsertMode imode) 106db31f6deSJed Brown { 107db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 108fbbcb730SJack Poulson PetscInt i,j,rrank,ridx,crank,cidx,erow,ecol,numQueues=0; 109db31f6deSJed Brown 110db31f6deSJed Brown PetscFunctionBegin; 111fbbcb730SJack Poulson // TODO: Initialize matrix to all zeros? 112fbbcb730SJack Poulson 113fbbcb730SJack Poulson // Count the number of queues from this process 11432d7a744SHong Zhang if (a->roworiented) { 115db31f6deSJed Brown for (i=0; i<nr; i++) { 116db31f6deSJed Brown if (rows[i] < 0) continue; 117db31f6deSJed Brown P2RO(A,0,rows[i],&rrank,&ridx); 118db31f6deSJed Brown RO2E(A,0,rrank,ridx,&erow); 119ce94432eSBarry Smith if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect row translation"); 120db31f6deSJed Brown for (j=0; j<nc; j++) { 121db31f6deSJed Brown if (cols[j] < 0) continue; 122db31f6deSJed Brown P2RO(A,1,cols[j],&crank,&cidx); 123db31f6deSJed Brown RO2E(A,1,crank,cidx,&ecol); 124ce94432eSBarry Smith if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect col translation"); 125fbbcb730SJack Poulson if (!a->emat->IsLocal(erow,ecol)){ /* off-proc entry */ 126fbbcb730SJack Poulson /* printf("Will later remotely update (%d,%d)\n",erow,ecol); */ 127aae2c449SHong Zhang if (imode != ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ADD_VALUES to off-processor entry is supported"); 128fbbcb730SJack Poulson ++numQueues; 129aae2c449SHong Zhang continue; 130ed36708cSHong Zhang } 131fbbcb730SJack Poulson /* printf("Locally updating (%d,%d)\n",erow,ecol); */ 132db31f6deSJed Brown switch (imode) { 133fbbcb730SJack Poulson case INSERT_VALUES: a->emat->Set(erow,ecol,(PetscElemScalar)vals[i*nc+j]); break; 134fbbcb730SJack Poulson case ADD_VALUES: a->emat->Update(erow,ecol,(PetscElemScalar)vals[i*nc+j]); break; 135ce94432eSBarry Smith default: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for InsertMode %d",(int)imode); 136db31f6deSJed Brown } 137db31f6deSJed Brown } 138db31f6deSJed Brown } 139fbbcb730SJack Poulson 140fbbcb730SJack Poulson /* printf("numQueues=%d\n",numQueues); */ 141fbbcb730SJack Poulson a->emat->Reserve( numQueues); 142fbbcb730SJack Poulson for (i=0; i<nr; i++) { 143fbbcb730SJack Poulson if (rows[i] < 0) continue; 144fbbcb730SJack Poulson P2RO(A,0,rows[i],&rrank,&ridx); 145fbbcb730SJack Poulson RO2E(A,0,rrank,ridx,&erow); 146fbbcb730SJack Poulson for (j=0; j<nc; j++) { 147fbbcb730SJack Poulson if (cols[j] < 0) continue; 148fbbcb730SJack Poulson P2RO(A,1,cols[j],&crank,&cidx); 149fbbcb730SJack Poulson RO2E(A,1,crank,cidx,&ecol); 150fbbcb730SJack Poulson if (!a->emat->IsLocal(erow,ecol)) { /*off-proc entry*/ 151fbbcb730SJack Poulson /* printf("Queueing remotely update of (%d,%d)\n",erow,ecol); */ 152fbbcb730SJack Poulson a->emat->QueueUpdate( erow, ecol, vals[i*nc+j]); 153fbbcb730SJack Poulson } 154fbbcb730SJack Poulson } 155fbbcb730SJack Poulson } 15632d7a744SHong Zhang } else { /* columnoriented */ 15732d7a744SHong Zhang for (j=0; j<nc; j++) { 15832d7a744SHong Zhang if (cols[j] < 0) continue; 15932d7a744SHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 16032d7a744SHong Zhang RO2E(A,1,crank,cidx,&ecol); 16132d7a744SHong Zhang if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect col translation"); 16232d7a744SHong Zhang for (i=0; i<nr; i++) { 16332d7a744SHong Zhang if (rows[i] < 0) continue; 16432d7a744SHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); 16532d7a744SHong Zhang RO2E(A,0,rrank,ridx,&erow); 16632d7a744SHong Zhang if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect row translation"); 16732d7a744SHong Zhang if (!a->emat->IsLocal(erow,ecol)){ /* off-proc entry */ 16832d7a744SHong Zhang /* printf("Will later remotely update (%d,%d)\n",erow,ecol); */ 16932d7a744SHong Zhang if (imode != ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ADD_VALUES to off-processor entry is supported"); 17032d7a744SHong Zhang ++numQueues; 17132d7a744SHong Zhang continue; 17232d7a744SHong Zhang } 17332d7a744SHong Zhang /* printf("Locally updating (%d,%d)\n",erow,ecol); */ 17432d7a744SHong Zhang switch (imode) { 17532d7a744SHong Zhang case INSERT_VALUES: a->emat->Set(erow,ecol,(PetscElemScalar)vals[i+j*nr]); break; 17632d7a744SHong Zhang case ADD_VALUES: a->emat->Update(erow,ecol,(PetscElemScalar)vals[i+j*nr]); break; 17732d7a744SHong Zhang default: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for InsertMode %d",(int)imode); 17832d7a744SHong Zhang } 17932d7a744SHong Zhang } 18032d7a744SHong Zhang } 18132d7a744SHong Zhang 18232d7a744SHong Zhang /* printf("numQueues=%d\n",numQueues); */ 18332d7a744SHong Zhang a->emat->Reserve( numQueues); 18432d7a744SHong Zhang for (j=0; j<nc; j++) { 18532d7a744SHong Zhang if (cols[j] < 0) continue; 18632d7a744SHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 18732d7a744SHong Zhang RO2E(A,1,crank,cidx,&ecol); 18832d7a744SHong Zhang 18932d7a744SHong Zhang for (i=0; i<nr; i++) { 19032d7a744SHong Zhang if (rows[i] < 0) continue; 19132d7a744SHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); 19232d7a744SHong Zhang RO2E(A,0,rrank,ridx,&erow); 19332d7a744SHong Zhang if (!a->emat->IsLocal(erow,ecol)) { /*off-proc entry*/ 19432d7a744SHong Zhang /* printf("Queueing remotely update of (%d,%d)\n",erow,ecol); */ 19532d7a744SHong Zhang a->emat->QueueUpdate( erow, ecol, vals[i+j*nr]); 19632d7a744SHong Zhang } 19732d7a744SHong Zhang } 19832d7a744SHong Zhang } 19932d7a744SHong Zhang } 200db31f6deSJed Brown PetscFunctionReturn(0); 201db31f6deSJed Brown } 202db31f6deSJed Brown 203db31f6deSJed Brown static PetscErrorCode MatMult_Elemental(Mat A,Vec X,Vec Y) 204db31f6deSJed Brown { 205db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 206db31f6deSJed Brown PetscErrorCode ierr; 207e6dea9dbSXuan Zhou const PetscElemScalar *x; 208e6dea9dbSXuan Zhou PetscElemScalar *y; 209df311e6cSXuan Zhou PetscElemScalar one = 1,zero = 0; 210db31f6deSJed Brown 211db31f6deSJed Brown PetscFunctionBegin; 212e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 213e6dea9dbSXuan Zhou ierr = VecGetArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 214db31f6deSJed Brown { /* Scoping so that constructor is called before pointer is returned */ 215e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ye; 2160c18141cSBarry Smith xe.LockedAttach(A->cmap->N,1,*a->grid,0,0,x,A->cmap->n); 2170c18141cSBarry Smith ye.Attach(A->rmap->N,1,*a->grid,0,0,y,A->rmap->n); 218e8146892SSatish Balay El::Gemv(El::NORMAL,one,*a->emat,xe,zero,ye); 219db31f6deSJed Brown } 220e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 221e6dea9dbSXuan Zhou ierr = VecRestoreArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 222db31f6deSJed Brown PetscFunctionReturn(0); 223db31f6deSJed Brown } 224db31f6deSJed Brown 2259426833fSXuan Zhou static PetscErrorCode MatMultTranspose_Elemental(Mat A,Vec X,Vec Y) 2269426833fSXuan Zhou { 2279426833fSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 2289426833fSXuan Zhou PetscErrorCode ierr; 229df311e6cSXuan Zhou const PetscElemScalar *x; 230df311e6cSXuan Zhou PetscElemScalar *y; 231e6dea9dbSXuan Zhou PetscElemScalar one = 1,zero = 0; 2329426833fSXuan Zhou 2339426833fSXuan Zhou PetscFunctionBegin; 234e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 235e6dea9dbSXuan Zhou ierr = VecGetArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 2369426833fSXuan Zhou { /* Scoping so that constructor is called before pointer is returned */ 237e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ye; 2380c18141cSBarry Smith xe.LockedAttach(A->rmap->N,1,*a->grid,0,0,x,A->rmap->n); 2390c18141cSBarry Smith ye.Attach(A->cmap->N,1,*a->grid,0,0,y,A->cmap->n); 240e8146892SSatish Balay El::Gemv(El::TRANSPOSE,one,*a->emat,xe,zero,ye); 2419426833fSXuan Zhou } 242e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 243e6dea9dbSXuan Zhou ierr = VecRestoreArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 2449426833fSXuan Zhou PetscFunctionReturn(0); 2459426833fSXuan Zhou } 2469426833fSXuan Zhou 247db31f6deSJed Brown static PetscErrorCode MatMultAdd_Elemental(Mat A,Vec X,Vec Y,Vec Z) 248db31f6deSJed Brown { 249db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 250db31f6deSJed Brown PetscErrorCode ierr; 251df311e6cSXuan Zhou const PetscElemScalar *x; 252df311e6cSXuan Zhou PetscElemScalar *z; 253e6dea9dbSXuan Zhou PetscElemScalar one = 1; 254db31f6deSJed Brown 255db31f6deSJed Brown PetscFunctionBegin; 256db31f6deSJed Brown if (Y != Z) {ierr = VecCopy(Y,Z);CHKERRQ(ierr);} 257e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 258e6dea9dbSXuan Zhou ierr = VecGetArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 259db31f6deSJed Brown { /* Scoping so that constructor is called before pointer is returned */ 260e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ze; 2610c18141cSBarry Smith xe.LockedAttach(A->cmap->N,1,*a->grid,0,0,x,A->cmap->n); 2620c18141cSBarry Smith ze.Attach(A->rmap->N,1,*a->grid,0,0,z,A->rmap->n); 263e8146892SSatish Balay El::Gemv(El::NORMAL,one,*a->emat,xe,one,ze); 264db31f6deSJed Brown } 265e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 266e6dea9dbSXuan Zhou ierr = VecRestoreArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 267db31f6deSJed Brown PetscFunctionReturn(0); 268db31f6deSJed Brown } 269db31f6deSJed Brown 270e883f9d5SXuan Zhou static PetscErrorCode MatMultTransposeAdd_Elemental(Mat A,Vec X,Vec Y,Vec Z) 271e883f9d5SXuan Zhou { 272e883f9d5SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 273e883f9d5SXuan Zhou PetscErrorCode ierr; 274df311e6cSXuan Zhou const PetscElemScalar *x; 275df311e6cSXuan Zhou PetscElemScalar *z; 276e6dea9dbSXuan Zhou PetscElemScalar one = 1; 277e883f9d5SXuan Zhou 278e883f9d5SXuan Zhou PetscFunctionBegin; 279e883f9d5SXuan Zhou if (Y != Z) {ierr = VecCopy(Y,Z);CHKERRQ(ierr);} 280e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 281e6dea9dbSXuan Zhou ierr = VecGetArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 282e883f9d5SXuan Zhou { /* Scoping so that constructor is called before pointer is returned */ 283e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ze; 2840c18141cSBarry Smith xe.LockedAttach(A->rmap->N,1,*a->grid,0,0,x,A->rmap->n); 2850c18141cSBarry Smith ze.Attach(A->cmap->N,1,*a->grid,0,0,z,A->cmap->n); 286e8146892SSatish Balay El::Gemv(El::TRANSPOSE,one,*a->emat,xe,one,ze); 287e883f9d5SXuan Zhou } 288e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 289e6dea9dbSXuan Zhou ierr = VecRestoreArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 290e883f9d5SXuan Zhou PetscFunctionReturn(0); 291e883f9d5SXuan Zhou } 292e883f9d5SXuan Zhou 2934222ddf1SHong Zhang PetscErrorCode MatMatMultNumeric_Elemental(Mat A,Mat B,Mat C) 294c1d1b975SXuan Zhou { 295c1d1b975SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 296c1d1b975SXuan Zhou Mat_Elemental *b = (Mat_Elemental*)B->data; 2979a9e8502SHong Zhang Mat_Elemental *c = (Mat_Elemental*)C->data; 298e6dea9dbSXuan Zhou PetscElemScalar one = 1,zero = 0; 299c1d1b975SXuan Zhou 300c1d1b975SXuan Zhou PetscFunctionBegin; 301aae2c449SHong Zhang { /* Scoping so that constructor is called before pointer is returned */ 302e8146892SSatish Balay El::Gemm(El::NORMAL,El::NORMAL,one,*a->emat,*b->emat,zero,*c->emat); 303aae2c449SHong Zhang } 3049a9e8502SHong Zhang C->assembled = PETSC_TRUE; 3059a9e8502SHong Zhang PetscFunctionReturn(0); 3069a9e8502SHong Zhang } 3079a9e8502SHong Zhang 3084222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_Elemental(Mat A,Mat B,PetscReal fill,Mat Ce) 3099a9e8502SHong Zhang { 3109a9e8502SHong Zhang PetscErrorCode ierr; 3119a9e8502SHong Zhang 3129a9e8502SHong Zhang PetscFunctionBegin; 3139a9e8502SHong Zhang ierr = MatSetSizes(Ce,A->rmap->n,B->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3149a9e8502SHong Zhang ierr = MatSetType(Ce,MATELEMENTAL);CHKERRQ(ierr); 3159a9e8502SHong Zhang ierr = MatSetUp(Ce);CHKERRQ(ierr); 3164222ddf1SHong Zhang Ce->ops->matmultnumeric = MatMatMultNumeric_Elemental; 317c1d1b975SXuan Zhou PetscFunctionReturn(0); 318c1d1b975SXuan Zhou } 319c1d1b975SXuan Zhou 320df311e6cSXuan Zhou static PetscErrorCode MatMatTransposeMultNumeric_Elemental(Mat A,Mat B,Mat C) 321df311e6cSXuan Zhou { 322df311e6cSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 323df311e6cSXuan Zhou Mat_Elemental *b = (Mat_Elemental*)B->data; 324df311e6cSXuan Zhou Mat_Elemental *c = (Mat_Elemental*)C->data; 325e6dea9dbSXuan Zhou PetscElemScalar one = 1,zero = 0; 326df311e6cSXuan Zhou 327df311e6cSXuan Zhou PetscFunctionBegin; 328df311e6cSXuan Zhou { /* Scoping so that constructor is called before pointer is returned */ 329e8146892SSatish Balay El::Gemm(El::NORMAL,El::TRANSPOSE,one,*a->emat,*b->emat,zero,*c->emat); 330df311e6cSXuan Zhou } 331df311e6cSXuan Zhou C->assembled = PETSC_TRUE; 332df311e6cSXuan Zhou PetscFunctionReturn(0); 333df311e6cSXuan Zhou } 334df311e6cSXuan Zhou 3354222ddf1SHong Zhang static PetscErrorCode MatMatTransposeMultSymbolic_Elemental(Mat A,Mat B,PetscReal fill,Mat C) 336df311e6cSXuan Zhou { 337df311e6cSXuan Zhou PetscErrorCode ierr; 338df311e6cSXuan Zhou 339df311e6cSXuan Zhou PetscFunctionBegin; 3404222ddf1SHong Zhang ierr = MatSetSizes(C,A->rmap->n,B->rmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3414222ddf1SHong Zhang ierr = MatSetType(C,MATELEMENTAL);CHKERRQ(ierr); 3424222ddf1SHong Zhang ierr = MatSetUp(C);CHKERRQ(ierr); 343df311e6cSXuan Zhou PetscFunctionReturn(0); 344df311e6cSXuan Zhou } 345df311e6cSXuan Zhou 3464222ddf1SHong Zhang /* --------------------------------------- */ 3474222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_Elemental_AB(Mat C) 3484222ddf1SHong Zhang { 3494222ddf1SHong Zhang PetscFunctionBegin; 3504222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_Elemental; 3514222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 3524222ddf1SHong Zhang PetscFunctionReturn(0); 3534222ddf1SHong Zhang } 3544222ddf1SHong Zhang 3554222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_Elemental_ABt(Mat C) 3564222ddf1SHong Zhang { 3574222ddf1SHong Zhang PetscFunctionBegin; 3584222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_Elemental; 3594222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 3604222ddf1SHong Zhang PetscFunctionReturn(0); 3614222ddf1SHong Zhang } 3624222ddf1SHong Zhang 3634222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Elemental(Mat C) 3644222ddf1SHong Zhang { 3654222ddf1SHong Zhang PetscErrorCode ierr; 3664222ddf1SHong Zhang Mat_Product *product = C->product; 3674222ddf1SHong Zhang 3684222ddf1SHong Zhang PetscFunctionBegin; 3694222ddf1SHong Zhang switch (product->type) { 3704222ddf1SHong Zhang case MATPRODUCT_AB: 3714222ddf1SHong Zhang ierr = MatProductSetFromOptions_Elemental_AB(C);CHKERRQ(ierr); 3724222ddf1SHong Zhang break; 3734222ddf1SHong Zhang case MATPRODUCT_ABt: 3744222ddf1SHong Zhang ierr = MatProductSetFromOptions_Elemental_ABt(C);CHKERRQ(ierr); 3754222ddf1SHong Zhang break; 3766718818eSStefano Zampini default: 3776718818eSStefano Zampini break; 3784222ddf1SHong Zhang } 3794222ddf1SHong Zhang PetscFunctionReturn(0); 3804222ddf1SHong Zhang } 381f6e5db1bSPierre Jolivet 382f6e5db1bSPierre Jolivet PetscErrorCode MatMatMultNumeric_Elemental_MPIDense(Mat A,Mat B,Mat C) 383f6e5db1bSPierre Jolivet { 384f6e5db1bSPierre Jolivet Mat Be,Ce; 385f6e5db1bSPierre Jolivet PetscErrorCode ierr; 386f6e5db1bSPierre Jolivet 387f6e5db1bSPierre Jolivet PetscFunctionBegin; 388f6e5db1bSPierre Jolivet ierr = MatConvert(B,MATELEMENTAL,MAT_INITIAL_MATRIX,&Be);CHKERRQ(ierr); 389f6e5db1bSPierre Jolivet ierr = MatMatMult(A,Be,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&Ce);CHKERRQ(ierr); 390f6e5db1bSPierre Jolivet ierr = MatConvert(Ce,MATMPIDENSE,MAT_REUSE_MATRIX,&C);CHKERRQ(ierr); 391f6e5db1bSPierre Jolivet ierr = MatDestroy(&Be);CHKERRQ(ierr); 392f6e5db1bSPierre Jolivet ierr = MatDestroy(&Ce);CHKERRQ(ierr); 393f6e5db1bSPierre Jolivet PetscFunctionReturn(0); 394f6e5db1bSPierre Jolivet } 395f6e5db1bSPierre Jolivet 396f6e5db1bSPierre Jolivet PetscErrorCode MatMatMultSymbolic_Elemental_MPIDense(Mat A,Mat B,PetscReal fill,Mat C) 397f6e5db1bSPierre Jolivet { 398f6e5db1bSPierre Jolivet PetscErrorCode ierr; 399f6e5db1bSPierre Jolivet 400f6e5db1bSPierre Jolivet PetscFunctionBegin; 401f6e5db1bSPierre Jolivet ierr = MatSetSizes(C,A->rmap->n,B->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 402f6e5db1bSPierre Jolivet ierr = MatSetType(C,MATMPIDENSE);CHKERRQ(ierr); 403f6e5db1bSPierre Jolivet ierr = MatSetUp(C);CHKERRQ(ierr); 404f6e5db1bSPierre Jolivet C->ops->matmultnumeric = MatMatMultNumeric_Elemental_MPIDense; 405f6e5db1bSPierre Jolivet PetscFunctionReturn(0); 406f6e5db1bSPierre Jolivet } 407f6e5db1bSPierre Jolivet 408f6e5db1bSPierre Jolivet PetscErrorCode MatProductSetFromOptions_Elemental_MPIDense_AB(Mat C) 409f6e5db1bSPierre Jolivet { 410f6e5db1bSPierre Jolivet PetscFunctionBegin; 411f6e5db1bSPierre Jolivet C->ops->matmultsymbolic = MatMatMultSymbolic_Elemental_MPIDense; 412f6e5db1bSPierre Jolivet C->ops->productsymbolic = MatProductSymbolic_AB; 413f6e5db1bSPierre Jolivet PetscFunctionReturn(0); 414f6e5db1bSPierre Jolivet } 415f6e5db1bSPierre Jolivet 416f6e5db1bSPierre Jolivet PetscErrorCode MatProductSetFromOptions_Elemental_MPIDense(Mat C) 417f6e5db1bSPierre Jolivet { 418f6e5db1bSPierre Jolivet PetscErrorCode ierr; 419f6e5db1bSPierre Jolivet Mat_Product *product = C->product; 420f6e5db1bSPierre Jolivet 421f6e5db1bSPierre Jolivet PetscFunctionBegin; 422f6e5db1bSPierre Jolivet if (product->type == MATPRODUCT_AB) { 423f6e5db1bSPierre Jolivet ierr = MatProductSetFromOptions_Elemental_MPIDense_AB(C);CHKERRQ(ierr); 424f6e5db1bSPierre Jolivet } 425f6e5db1bSPierre Jolivet PetscFunctionReturn(0); 426f6e5db1bSPierre Jolivet } 4274222ddf1SHong Zhang /* --------------------------------------- */ 4284222ddf1SHong Zhang 429a9d89745SXuan Zhou static PetscErrorCode MatGetDiagonal_Elemental(Mat A,Vec D) 43061119200SXuan Zhou { 431a9d89745SXuan Zhou PetscInt i,nrows,ncols,nD,rrank,ridx,crank,cidx; 432a9d89745SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 43361119200SXuan Zhou PetscErrorCode ierr; 434a9d89745SXuan Zhou PetscElemScalar v; 435ce94432eSBarry Smith MPI_Comm comm; 43661119200SXuan Zhou 43761119200SXuan Zhou PetscFunctionBegin; 438ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 439a9d89745SXuan Zhou ierr = MatGetSize(A,&nrows,&ncols);CHKERRQ(ierr); 440a9d89745SXuan Zhou nD = nrows>ncols ? ncols : nrows; 441a9d89745SXuan Zhou for (i=0; i<nD; i++) { 442a9d89745SXuan Zhou PetscInt erow,ecol; 443a9d89745SXuan Zhou P2RO(A,0,i,&rrank,&ridx); 444a9d89745SXuan Zhou RO2E(A,0,rrank,ridx,&erow); 445a9d89745SXuan Zhou if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect row translation"); 446a9d89745SXuan Zhou P2RO(A,1,i,&crank,&cidx); 447a9d89745SXuan Zhou RO2E(A,1,crank,cidx,&ecol); 448a9d89745SXuan Zhou if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect col translation"); 449a9d89745SXuan Zhou v = a->emat->Get(erow,ecol); 4507c8b904fSSatish Balay ierr = VecSetValues(D,1,&i,(PetscScalar*)&v,INSERT_VALUES);CHKERRQ(ierr); 451ade3cc5eSXuan Zhou } 452a9d89745SXuan Zhou ierr = VecAssemblyBegin(D);CHKERRQ(ierr); 453a9d89745SXuan Zhou ierr = VecAssemblyEnd(D);CHKERRQ(ierr); 45461119200SXuan Zhou PetscFunctionReturn(0); 45561119200SXuan Zhou } 45661119200SXuan Zhou 457ade3cc5eSXuan Zhou static PetscErrorCode MatDiagonalScale_Elemental(Mat X,Vec L,Vec R) 458ade3cc5eSXuan Zhou { 459ade3cc5eSXuan Zhou Mat_Elemental *x = (Mat_Elemental*)X->data; 460ade3cc5eSXuan Zhou const PetscElemScalar *d; 461ade3cc5eSXuan Zhou PetscErrorCode ierr; 462ade3cc5eSXuan Zhou 463ade3cc5eSXuan Zhou PetscFunctionBegin; 4649065cd98SJed Brown if (R) { 465ade3cc5eSXuan Zhou ierr = VecGetArrayRead(R,(const PetscScalar **)&d);CHKERRQ(ierr); 466e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> de; 4670c18141cSBarry Smith de.LockedAttach(X->cmap->N,1,*x->grid,0,0,d,X->cmap->n); 468e8146892SSatish Balay El::DiagonalScale(El::RIGHT,El::NORMAL,de,*x->emat); 469ade3cc5eSXuan Zhou ierr = VecRestoreArrayRead(R,(const PetscScalar **)&d);CHKERRQ(ierr); 4709065cd98SJed Brown } 4719065cd98SJed Brown if (L) { 472ade3cc5eSXuan Zhou ierr = VecGetArrayRead(L,(const PetscScalar **)&d);CHKERRQ(ierr); 473e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> de; 4740c18141cSBarry Smith de.LockedAttach(X->rmap->N,1,*x->grid,0,0,d,X->rmap->n); 475e8146892SSatish Balay El::DiagonalScale(El::LEFT,El::NORMAL,de,*x->emat); 476ade3cc5eSXuan Zhou ierr = VecRestoreArrayRead(L,(const PetscScalar **)&d);CHKERRQ(ierr); 477ade3cc5eSXuan Zhou } 478ade3cc5eSXuan Zhou PetscFunctionReturn(0); 479ade3cc5eSXuan Zhou } 480ade3cc5eSXuan Zhou 48134fa46e1SFrancesco Ballarin static PetscErrorCode MatMissingDiagonal_Elemental(Mat A,PetscBool *missing,PetscInt *d) 48234fa46e1SFrancesco Ballarin { 48334fa46e1SFrancesco Ballarin PetscFunctionBegin; 48434fa46e1SFrancesco Ballarin *missing = PETSC_FALSE; 48534fa46e1SFrancesco Ballarin PetscFunctionReturn(0); 48634fa46e1SFrancesco Ballarin } 48734fa46e1SFrancesco Ballarin 488e6dea9dbSXuan Zhou static PetscErrorCode MatScale_Elemental(Mat X,PetscScalar a) 48965b78793SXuan Zhou { 49065b78793SXuan Zhou Mat_Elemental *x = (Mat_Elemental*)X->data; 49165b78793SXuan Zhou 49265b78793SXuan Zhou PetscFunctionBegin; 493e8146892SSatish Balay El::Scale((PetscElemScalar)a,*x->emat); 49465b78793SXuan Zhou PetscFunctionReturn(0); 49565b78793SXuan Zhou } 49665b78793SXuan Zhou 497f82baa17SHong Zhang /* 498f82baa17SHong Zhang MatAXPY - Computes Y = a*X + Y. 499f82baa17SHong Zhang */ 500e6dea9dbSXuan Zhou static PetscErrorCode MatAXPY_Elemental(Mat Y,PetscScalar a,Mat X,MatStructure str) 501e09a3074SHong Zhang { 502e09a3074SHong Zhang Mat_Elemental *x = (Mat_Elemental*)X->data; 503e09a3074SHong Zhang Mat_Elemental *y = (Mat_Elemental*)Y->data; 50468446cf8SJed Brown PetscErrorCode ierr; 505e09a3074SHong Zhang 506e09a3074SHong Zhang PetscFunctionBegin; 507e8146892SSatish Balay El::Axpy((PetscElemScalar)a,*x->emat,*y->emat); 50821f6c9c4SJed Brown ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 509e09a3074SHong Zhang PetscFunctionReturn(0); 510e09a3074SHong Zhang } 511e09a3074SHong Zhang 512d6223691SXuan Zhou static PetscErrorCode MatCopy_Elemental(Mat A,Mat B,MatStructure str) 513d6223691SXuan Zhou { 514d6223691SXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 515d6223691SXuan Zhou Mat_Elemental *b=(Mat_Elemental*)B->data; 516a4ee3bb6SSatish Balay PetscErrorCode ierr; 517d6223691SXuan Zhou 518d6223691SXuan Zhou PetscFunctionBegin; 519e8146892SSatish Balay El::Copy(*a->emat,*b->emat); 520cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 521d6223691SXuan Zhou PetscFunctionReturn(0); 522d6223691SXuan Zhou } 523d6223691SXuan Zhou 524df311e6cSXuan Zhou static PetscErrorCode MatDuplicate_Elemental(Mat A,MatDuplicateOption op,Mat *B) 525df311e6cSXuan Zhou { 526df311e6cSXuan Zhou Mat Be; 527ce94432eSBarry Smith MPI_Comm comm; 528df311e6cSXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 529df311e6cSXuan Zhou PetscErrorCode ierr; 530df311e6cSXuan Zhou 531df311e6cSXuan Zhou PetscFunctionBegin; 532ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 533df311e6cSXuan Zhou ierr = MatCreate(comm,&Be);CHKERRQ(ierr); 534df311e6cSXuan Zhou ierr = MatSetSizes(Be,A->rmap->n,A->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 535df311e6cSXuan Zhou ierr = MatSetType(Be,MATELEMENTAL);CHKERRQ(ierr); 536df311e6cSXuan Zhou ierr = MatSetUp(Be);CHKERRQ(ierr); 537df311e6cSXuan Zhou *B = Be; 538df311e6cSXuan Zhou if (op == MAT_COPY_VALUES) { 539df311e6cSXuan Zhou Mat_Elemental *b=(Mat_Elemental*)Be->data; 540e8146892SSatish Balay El::Copy(*a->emat,*b->emat); 541df311e6cSXuan Zhou } 542df311e6cSXuan Zhou Be->assembled = PETSC_TRUE; 543df311e6cSXuan Zhou PetscFunctionReturn(0); 544df311e6cSXuan Zhou } 545df311e6cSXuan Zhou 546d6223691SXuan Zhou static PetscErrorCode MatTranspose_Elemental(Mat A,MatReuse reuse,Mat *B) 547d6223691SXuan Zhou { 548ec8cb81fSBarry Smith Mat Be = *B; 5495262d616SXuan Zhou PetscErrorCode ierr; 550ce94432eSBarry Smith MPI_Comm comm; 5514fe7bbcaSHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data, *b; 552d6223691SXuan Zhou 553d6223691SXuan Zhou PetscFunctionBegin; 554ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 5555cb544a0SHong Zhang /* Only out-of-place supported */ 5562847e3fdSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) SETERRQ(comm,PETSC_ERR_SUP,"Only out-of-place supported"); 5575262d616SXuan Zhou if (reuse == MAT_INITIAL_MATRIX) { 5585262d616SXuan Zhou ierr = MatCreate(comm,&Be);CHKERRQ(ierr); 5595262d616SXuan Zhou ierr = MatSetSizes(Be,A->cmap->n,A->rmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 5605262d616SXuan Zhou ierr = MatSetType(Be,MATELEMENTAL);CHKERRQ(ierr); 5615262d616SXuan Zhou ierr = MatSetUp(Be);CHKERRQ(ierr); 5625262d616SXuan Zhou *B = Be; 5635262d616SXuan Zhou } 5644fe7bbcaSHong Zhang b = (Mat_Elemental*)Be->data; 565e8146892SSatish Balay El::Transpose(*a->emat,*b->emat); 5665262d616SXuan Zhou Be->assembled = PETSC_TRUE; 567d6223691SXuan Zhou PetscFunctionReturn(0); 568d6223691SXuan Zhou } 569d6223691SXuan Zhou 570dfcb0403SXuan Zhou static PetscErrorCode MatConjugate_Elemental(Mat A) 571dfcb0403SXuan Zhou { 572dfcb0403SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 573dfcb0403SXuan Zhou 574dfcb0403SXuan Zhou PetscFunctionBegin; 575e8146892SSatish Balay El::Conjugate(*a->emat); 576dfcb0403SXuan Zhou PetscFunctionReturn(0); 577dfcb0403SXuan Zhou } 578dfcb0403SXuan Zhou 5794a29722dSXuan Zhou static PetscErrorCode MatHermitianTranspose_Elemental(Mat A,MatReuse reuse,Mat *B) 5804a29722dSXuan Zhou { 581ec8cb81fSBarry Smith Mat Be = *B; 5824a29722dSXuan Zhou PetscErrorCode ierr; 583ce94432eSBarry Smith MPI_Comm comm; 5844a29722dSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data, *b; 5854a29722dSXuan Zhou 5864a29722dSXuan Zhou PetscFunctionBegin; 587ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 5885cb544a0SHong Zhang /* Only out-of-place supported */ 5894a29722dSXuan Zhou if (reuse == MAT_INITIAL_MATRIX){ 5904a29722dSXuan Zhou ierr = MatCreate(comm,&Be);CHKERRQ(ierr); 5914a29722dSXuan Zhou ierr = MatSetSizes(Be,A->cmap->n,A->rmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 5924a29722dSXuan Zhou ierr = MatSetType(Be,MATELEMENTAL);CHKERRQ(ierr); 5934a29722dSXuan Zhou ierr = MatSetUp(Be);CHKERRQ(ierr); 5944a29722dSXuan Zhou *B = Be; 5954a29722dSXuan Zhou } 5964a29722dSXuan Zhou b = (Mat_Elemental*)Be->data; 597e8146892SSatish Balay El::Adjoint(*a->emat,*b->emat); 5984a29722dSXuan Zhou Be->assembled = PETSC_TRUE; 5994a29722dSXuan Zhou PetscFunctionReturn(0); 6004a29722dSXuan Zhou } 6014a29722dSXuan Zhou 6021f881ff8SXuan Zhou static PetscErrorCode MatSolve_Elemental(Mat A,Vec B,Vec X) 6031f881ff8SXuan Zhou { 6041f881ff8SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 6051f881ff8SXuan Zhou PetscErrorCode ierr; 606df311e6cSXuan Zhou PetscElemScalar *x; 607ea394475SSatish Balay PetscInt pivoting = a->pivoting; 6081f881ff8SXuan Zhou 6091f881ff8SXuan Zhou PetscFunctionBegin; 61045cf121fSXuan Zhou ierr = VecCopy(B,X);CHKERRQ(ierr); 611e6dea9dbSXuan Zhou ierr = VecGetArray(X,(PetscScalar **)&x);CHKERRQ(ierr); 612ea394475SSatish Balay 613e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe; 6140c18141cSBarry Smith xe.Attach(A->rmap->N,1,*a->grid,0,0,x,A->rmap->n); 615e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::MC,El::MR> xer(xe); 616fc54b460SXuan Zhou switch (A->factortype) { 617fc54b460SXuan Zhou case MAT_FACTOR_LU: 618ea394475SSatish Balay if (pivoting == 0) { 619e8146892SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,xer); 620ea394475SSatish Balay } else if (pivoting == 1) { 621ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,xer); 622ea394475SSatish Balay } else { /* pivoting == 2 */ 623ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,*a->Q,xer); 6241f881ff8SXuan Zhou } 625fc54b460SXuan Zhou break; 626fc54b460SXuan Zhou case MAT_FACTOR_CHOLESKY: 627e8146892SSatish Balay El::cholesky::SolveAfter(El::UPPER,El::NORMAL,*a->emat,xer); 628fc54b460SXuan Zhou break; 629fc54b460SXuan Zhou default: 6304fe7bbcaSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unfactored Matrix or Unsupported MatFactorType"); 631fc54b460SXuan Zhou break; 6321f881ff8SXuan Zhou } 633ea394475SSatish Balay El::Copy(xer,xe); 634ea394475SSatish Balay 635e6dea9dbSXuan Zhou ierr = VecRestoreArray(X,(PetscScalar **)&x);CHKERRQ(ierr); 6361f881ff8SXuan Zhou PetscFunctionReturn(0); 6371f881ff8SXuan Zhou } 6381f881ff8SXuan Zhou 639df311e6cSXuan Zhou static PetscErrorCode MatSolveAdd_Elemental(Mat A,Vec B,Vec Y,Vec X) 640df311e6cSXuan Zhou { 641df311e6cSXuan Zhou PetscErrorCode ierr; 642df311e6cSXuan Zhou 643df311e6cSXuan Zhou PetscFunctionBegin; 644df311e6cSXuan Zhou ierr = MatSolve_Elemental(A,B,X);CHKERRQ(ierr); 6453d7f40dbSXuan Zhou ierr = VecAXPY(X,1,Y);CHKERRQ(ierr); 646df311e6cSXuan Zhou PetscFunctionReturn(0); 647df311e6cSXuan Zhou } 648df311e6cSXuan Zhou 649ae844d54SHong Zhang static PetscErrorCode MatMatSolve_Elemental(Mat A,Mat B,Mat X) 650ae844d54SHong Zhang { 6511f0e42cfSHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 65242ba530cSPierre Jolivet Mat_Elemental *x; 65342ba530cSPierre Jolivet Mat C; 654ea394475SSatish Balay PetscInt pivoting = a->pivoting; 65542ba530cSPierre Jolivet PetscBool flg; 65642ba530cSPierre Jolivet MatType type; 65742ba530cSPierre Jolivet PetscErrorCode ierr; 6581f0e42cfSHong Zhang 659ae844d54SHong Zhang PetscFunctionBegin; 66042ba530cSPierre Jolivet ierr = MatGetType(X,&type);CHKERRQ(ierr); 66142ba530cSPierre Jolivet ierr = PetscStrcmp(type,MATELEMENTAL,&flg);CHKERRQ(ierr); 66242ba530cSPierre Jolivet if (!flg) { 66342ba530cSPierre Jolivet ierr = MatConvert(B,MATELEMENTAL,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr); 66442ba530cSPierre Jolivet x = (Mat_Elemental*)C->data; 66542ba530cSPierre Jolivet } else { 66642ba530cSPierre Jolivet x = (Mat_Elemental*)X->data; 66742ba530cSPierre Jolivet El::Copy(*((Mat_Elemental*)B->data)->emat,*x->emat); 66842ba530cSPierre Jolivet } 669fc54b460SXuan Zhou switch (A->factortype) { 670fc54b460SXuan Zhou case MAT_FACTOR_LU: 671ea394475SSatish Balay if (pivoting == 0) { 672e8146892SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*x->emat); 673ea394475SSatish Balay } else if (pivoting == 1) { 674ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,*x->emat); 675ea394475SSatish Balay } else { 676ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,*a->Q,*x->emat); 677d6223691SXuan Zhou } 678fc54b460SXuan Zhou break; 679fc54b460SXuan Zhou case MAT_FACTOR_CHOLESKY: 680e8146892SSatish Balay El::cholesky::SolveAfter(El::UPPER,El::NORMAL,*a->emat,*x->emat); 681fc54b460SXuan Zhou break; 682fc54b460SXuan Zhou default: 6834fe7bbcaSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unfactored Matrix or Unsupported MatFactorType"); 684fc54b460SXuan Zhou break; 685fc54b460SXuan Zhou } 68642ba530cSPierre Jolivet if (!flg) { 68742ba530cSPierre Jolivet ierr = MatConvert(C,type,MAT_REUSE_MATRIX,&X);CHKERRQ(ierr); 68842ba530cSPierre Jolivet ierr = MatDestroy(&C);CHKERRQ(ierr); 68942ba530cSPierre Jolivet } 690ae844d54SHong Zhang PetscFunctionReturn(0); 691ae844d54SHong Zhang } 692ae844d54SHong Zhang 693ae844d54SHong Zhang static PetscErrorCode MatLUFactor_Elemental(Mat A,IS row,IS col,const MatFactorInfo *info) 694ae844d54SHong Zhang { 6957c920d81SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 696124af5d2SSatish Balay PetscErrorCode ierr; 697ea394475SSatish Balay PetscInt pivoting = a->pivoting; 6987c920d81SXuan Zhou 699ae844d54SHong Zhang PetscFunctionBegin; 700ea394475SSatish Balay if (pivoting == 0) { 701e8146892SSatish Balay El::LU(*a->emat); 702ea394475SSatish Balay } else if (pivoting == 1) { 703ea394475SSatish Balay El::LU(*a->emat,*a->P); 704ea394475SSatish Balay } else { 705ea394475SSatish Balay El::LU(*a->emat,*a->P,*a->Q); 706d6223691SXuan Zhou } 7071293973dSHong Zhang A->factortype = MAT_FACTOR_LU; 708834d3fecSHong Zhang A->assembled = PETSC_TRUE; 709f6224b95SHong Zhang 710f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 711f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERELEMENTAL,&A->solvertype);CHKERRQ(ierr); 712ae844d54SHong Zhang PetscFunctionReturn(0); 713ae844d54SHong Zhang } 714ae844d54SHong Zhang 715d7c3f9d8SHong Zhang static PetscErrorCode MatLUFactorNumeric_Elemental(Mat F,Mat A,const MatFactorInfo *info) 716d7c3f9d8SHong Zhang { 717d7c3f9d8SHong Zhang PetscErrorCode ierr; 718d7c3f9d8SHong Zhang 719d7c3f9d8SHong Zhang PetscFunctionBegin; 720d7c3f9d8SHong Zhang ierr = MatCopy(A,F,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 721d7c3f9d8SHong Zhang ierr = MatLUFactor_Elemental(F,0,0,info);CHKERRQ(ierr); 722d7c3f9d8SHong Zhang PetscFunctionReturn(0); 723d7c3f9d8SHong Zhang } 724d7c3f9d8SHong Zhang 725d7c3f9d8SHong Zhang static PetscErrorCode MatLUFactorSymbolic_Elemental(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 726d7c3f9d8SHong Zhang { 727d7c3f9d8SHong Zhang PetscFunctionBegin; 728d8304050SJose E. Roman /* F is created and allocated by MatGetFactor_elemental_petsc(), skip this routine. */ 729d7c3f9d8SHong Zhang PetscFunctionReturn(0); 730d7c3f9d8SHong Zhang } 731d7c3f9d8SHong Zhang 73245cf121fSXuan Zhou static PetscErrorCode MatCholeskyFactor_Elemental(Mat A,IS perm,const MatFactorInfo *info) 73345cf121fSXuan Zhou { 73445cf121fSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 735e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::MC,El::STAR> d; 736124af5d2SSatish Balay PetscErrorCode ierr; 73745cf121fSXuan Zhou 73845cf121fSXuan Zhou PetscFunctionBegin; 739e8146892SSatish Balay El::Cholesky(El::UPPER,*a->emat); 740fc54b460SXuan Zhou A->factortype = MAT_FACTOR_CHOLESKY; 741834d3fecSHong Zhang A->assembled = PETSC_TRUE; 742f6224b95SHong Zhang 743f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 744f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERELEMENTAL,&A->solvertype);CHKERRQ(ierr); 74545cf121fSXuan Zhou PetscFunctionReturn(0); 74645cf121fSXuan Zhou } 74745cf121fSXuan Zhou 74879673f7bSHong Zhang static PetscErrorCode MatCholeskyFactorNumeric_Elemental(Mat F,Mat A,const MatFactorInfo *info) 74979673f7bSHong Zhang { 750cb76c1d8SXuan Zhou PetscErrorCode ierr; 751cb76c1d8SXuan Zhou 752cb76c1d8SXuan Zhou PetscFunctionBegin; 753cb76c1d8SXuan Zhou ierr = MatCopy(A,F,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 754cb76c1d8SXuan Zhou ierr = MatCholeskyFactor_Elemental(F,0,info);CHKERRQ(ierr); 755cb76c1d8SXuan Zhou PetscFunctionReturn(0); 75679673f7bSHong Zhang } 757cb76c1d8SXuan Zhou 75879673f7bSHong Zhang static PetscErrorCode MatCholeskyFactorSymbolic_Elemental(Mat F,Mat A,IS perm,const MatFactorInfo *info) 75979673f7bSHong Zhang { 76079673f7bSHong Zhang PetscFunctionBegin; 761d8304050SJose E. Roman /* F is created and allocated by MatGetFactor_elemental_petsc(), skip this routine. */ 76279673f7bSHong Zhang PetscFunctionReturn(0); 76379673f7bSHong Zhang } 76479673f7bSHong Zhang 765ea799195SBarry Smith PetscErrorCode MatFactorGetSolverType_elemental_elemental(Mat A,MatSolverType *type) 76615767789SHong Zhang { 76715767789SHong Zhang PetscFunctionBegin; 76815767789SHong Zhang *type = MATSOLVERELEMENTAL; 76915767789SHong Zhang PetscFunctionReturn(0); 77015767789SHong Zhang } 77115767789SHong Zhang 77215767789SHong Zhang static PetscErrorCode MatGetFactor_elemental_elemental(Mat A,MatFactorType ftype,Mat *F) 7731293973dSHong Zhang { 7741293973dSHong Zhang Mat B; 7751293973dSHong Zhang PetscErrorCode ierr; 7761293973dSHong Zhang 7771293973dSHong Zhang PetscFunctionBegin; 7781293973dSHong Zhang /* Create the factorization matrix */ 779ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 7801293973dSHong Zhang ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 7811293973dSHong Zhang ierr = MatSetType(B,MATELEMENTAL);CHKERRQ(ierr); 7821293973dSHong Zhang ierr = MatSetUp(B);CHKERRQ(ierr); 7831293973dSHong Zhang B->factortype = ftype; 784*66e17bc3SBarry Smith B->trivialsymbolic = PETSC_TRUE; 78500c67f3bSHong Zhang ierr = PetscFree(B->solvertype);CHKERRQ(ierr); 78600c67f3bSHong Zhang ierr = PetscStrallocpy(MATSOLVERELEMENTAL,&B->solvertype);CHKERRQ(ierr); 78700c67f3bSHong Zhang 7883ca39a21SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_elemental_elemental);CHKERRQ(ierr); 7891293973dSHong Zhang *F = B; 7901293973dSHong Zhang PetscFunctionReturn(0); 7911293973dSHong Zhang } 7921293973dSHong Zhang 7933ca39a21SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Elemental(void) 79442c9c57cSBarry Smith { 79518713533SBarry Smith PetscErrorCode ierr; 79618713533SBarry Smith 79742c9c57cSBarry Smith PetscFunctionBegin; 7983ca39a21SBarry Smith ierr = MatSolverTypeRegister(MATSOLVERELEMENTAL,MATELEMENTAL, MAT_FACTOR_LU,MatGetFactor_elemental_elemental);CHKERRQ(ierr); 7993ca39a21SBarry Smith ierr = MatSolverTypeRegister(MATSOLVERELEMENTAL,MATELEMENTAL, MAT_FACTOR_CHOLESKY,MatGetFactor_elemental_elemental);CHKERRQ(ierr); 80042c9c57cSBarry Smith PetscFunctionReturn(0); 80142c9c57cSBarry Smith } 80242c9c57cSBarry Smith 8031f881ff8SXuan Zhou static PetscErrorCode MatNorm_Elemental(Mat A,NormType type,PetscReal *nrm) 8041f881ff8SXuan Zhou { 8051f881ff8SXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 8061f881ff8SXuan Zhou 8071f881ff8SXuan Zhou PetscFunctionBegin; 8081f881ff8SXuan Zhou switch (type){ 8091f881ff8SXuan Zhou case NORM_1: 810e8146892SSatish Balay *nrm = El::OneNorm(*a->emat); 8111f881ff8SXuan Zhou break; 8121f881ff8SXuan Zhou case NORM_FROBENIUS: 813e8146892SSatish Balay *nrm = El::FrobeniusNorm(*a->emat); 8141f881ff8SXuan Zhou break; 8151f881ff8SXuan Zhou case NORM_INFINITY: 816e8146892SSatish Balay *nrm = El::InfinityNorm(*a->emat); 8171f881ff8SXuan Zhou break; 8181f881ff8SXuan Zhou default: 819d8304050SJose E. Roman SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unsupported norm type"); 8201f881ff8SXuan Zhou } 8211f881ff8SXuan Zhou PetscFunctionReturn(0); 8221f881ff8SXuan Zhou } 8231f881ff8SXuan Zhou 8245262d616SXuan Zhou static PetscErrorCode MatZeroEntries_Elemental(Mat A) 8255262d616SXuan Zhou { 8265262d616SXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 8275262d616SXuan Zhou 8285262d616SXuan Zhou PetscFunctionBegin; 829e8146892SSatish Balay El::Zero(*a->emat); 8305262d616SXuan Zhou PetscFunctionReturn(0); 8315262d616SXuan Zhou } 8325262d616SXuan Zhou 833db31f6deSJed Brown static PetscErrorCode MatGetOwnershipIS_Elemental(Mat A,IS *rows,IS *cols) 834db31f6deSJed Brown { 835db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 836db31f6deSJed Brown PetscErrorCode ierr; 837db31f6deSJed Brown PetscInt i,m,shift,stride,*idx; 838db31f6deSJed Brown 839db31f6deSJed Brown PetscFunctionBegin; 840db31f6deSJed Brown if (rows) { 841db31f6deSJed Brown m = a->emat->LocalHeight(); 842db31f6deSJed Brown shift = a->emat->ColShift(); 843db31f6deSJed Brown stride = a->emat->ColStride(); 844785e854fSJed Brown ierr = PetscMalloc1(m,&idx);CHKERRQ(ierr); 845db31f6deSJed Brown for (i=0; i<m; i++) { 846db31f6deSJed Brown PetscInt rank,offset; 847db31f6deSJed Brown E2RO(A,0,shift+i*stride,&rank,&offset); 848db31f6deSJed Brown RO2P(A,0,rank,offset,&idx[i]); 849db31f6deSJed Brown } 850db31f6deSJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,m,idx,PETSC_OWN_POINTER,rows);CHKERRQ(ierr); 851db31f6deSJed Brown } 852db31f6deSJed Brown if (cols) { 853db31f6deSJed Brown m = a->emat->LocalWidth(); 854db31f6deSJed Brown shift = a->emat->RowShift(); 855db31f6deSJed Brown stride = a->emat->RowStride(); 856785e854fSJed Brown ierr = PetscMalloc1(m,&idx);CHKERRQ(ierr); 857db31f6deSJed Brown for (i=0; i<m; i++) { 858db31f6deSJed Brown PetscInt rank,offset; 859db31f6deSJed Brown E2RO(A,1,shift+i*stride,&rank,&offset); 860db31f6deSJed Brown RO2P(A,1,rank,offset,&idx[i]); 861db31f6deSJed Brown } 862db31f6deSJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,m,idx,PETSC_OWN_POINTER,cols);CHKERRQ(ierr); 863db31f6deSJed Brown } 864db31f6deSJed Brown PetscFunctionReturn(0); 865db31f6deSJed Brown } 866db31f6deSJed Brown 86719fd82e9SBarry Smith static PetscErrorCode MatConvert_Elemental_Dense(Mat A,MatType newtype,MatReuse reuse,Mat *B) 868af295397SXuan Zhou { 8692ef0cf24SXuan Zhou Mat Bmpi; 870af295397SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 871ce94432eSBarry Smith MPI_Comm comm; 8722ef0cf24SXuan Zhou PetscErrorCode ierr; 873fa9e26c8SHong Zhang IS isrows,iscols; 874fa9e26c8SHong Zhang PetscInt rrank,ridx,crank,cidx,nrows,ncols,i,j,erow,ecol,elrow,elcol; 875fa9e26c8SHong Zhang const PetscInt *rows,*cols; 876df311e6cSXuan Zhou PetscElemScalar v; 877fa9e26c8SHong Zhang const El::Grid &grid = a->emat->Grid(); 878af295397SXuan Zhou 879af295397SXuan Zhou PetscFunctionBegin; 880ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 881a000e53bSHong Zhang 882de0a22f0SHong Zhang if (reuse == MAT_REUSE_MATRIX) { 883de0a22f0SHong Zhang Bmpi = *B; 884de0a22f0SHong Zhang } else { 885af295397SXuan Zhou ierr = MatCreate(comm,&Bmpi);CHKERRQ(ierr); 886af295397SXuan Zhou ierr = MatSetSizes(Bmpi,A->rmap->n,A->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 8872ef0cf24SXuan Zhou ierr = MatSetType(Bmpi,MATDENSE);CHKERRQ(ierr); 888af295397SXuan Zhou ierr = MatSetUp(Bmpi);CHKERRQ(ierr); 889de0a22f0SHong Zhang } 890fa9e26c8SHong Zhang 891fa9e26c8SHong Zhang /* Get local entries of A */ 892fa9e26c8SHong Zhang ierr = MatGetOwnershipIS(A,&isrows,&iscols);CHKERRQ(ierr); 893fa9e26c8SHong Zhang ierr = ISGetLocalSize(isrows,&nrows);CHKERRQ(ierr); 894fa9e26c8SHong Zhang ierr = ISGetIndices(isrows,&rows);CHKERRQ(ierr); 895fa9e26c8SHong Zhang ierr = ISGetLocalSize(iscols,&ncols);CHKERRQ(ierr); 896fa9e26c8SHong Zhang ierr = ISGetIndices(iscols,&cols);CHKERRQ(ierr); 897fa9e26c8SHong Zhang 89857299f2fSHong Zhang if (a->roworiented) { 8992ef0cf24SXuan Zhou for (i=0; i<nrows; i++) { 900fa9e26c8SHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); /* convert indices between PETSc <-> (Rank,Offset) <-> Elemental */ 9012ef0cf24SXuan Zhou RO2E(A,0,rrank,ridx,&erow); 9022ef0cf24SXuan Zhou if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect row translation"); 9032ef0cf24SXuan Zhou for (j=0; j<ncols; j++) { 904fa9e26c8SHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 9052ef0cf24SXuan Zhou RO2E(A,1,crank,cidx,&ecol); 9062ef0cf24SXuan Zhou if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect col translation"); 907fa9e26c8SHong Zhang 908fa9e26c8SHong Zhang elrow = erow / grid.MCSize(); /* Elemental local row index */ 909fa9e26c8SHong Zhang elcol = ecol / grid.MRSize(); /* Elemental local column index */ 910fa9e26c8SHong Zhang v = a->emat->GetLocal(elrow,elcol); 911fa9e26c8SHong Zhang ierr = MatSetValues(Bmpi,1,&rows[i],1,&cols[j],(PetscScalar *)&v,INSERT_VALUES);CHKERRQ(ierr); 9122ef0cf24SXuan Zhou } 9132ef0cf24SXuan Zhou } 91457299f2fSHong Zhang } else { /* column-oriented */ 91557299f2fSHong Zhang for (j=0; j<ncols; j++) { 91657299f2fSHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 91757299f2fSHong Zhang RO2E(A,1,crank,cidx,&ecol); 91857299f2fSHong Zhang if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect col translation"); 91957299f2fSHong Zhang for (i=0; i<nrows; i++) { 92057299f2fSHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); /* convert indices between PETSc <-> (Rank,Offset) <-> Elemental */ 92157299f2fSHong Zhang RO2E(A,0,rrank,ridx,&erow); 92257299f2fSHong Zhang if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect row translation"); 92357299f2fSHong Zhang 92457299f2fSHong Zhang elrow = erow / grid.MCSize(); /* Elemental local row index */ 92557299f2fSHong Zhang elcol = ecol / grid.MRSize(); /* Elemental local column index */ 92657299f2fSHong Zhang v = a->emat->GetLocal(elrow,elcol); 92757299f2fSHong Zhang ierr = MatSetValues(Bmpi,1,&rows[i],1,&cols[j],(PetscScalar *)&v,INSERT_VALUES);CHKERRQ(ierr); 92857299f2fSHong Zhang } 92957299f2fSHong Zhang } 93057299f2fSHong Zhang } 931af295397SXuan Zhou ierr = MatAssemblyBegin(Bmpi,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 932af295397SXuan Zhou ierr = MatAssemblyEnd(Bmpi,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 933511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 93428be2f97SBarry Smith ierr = MatHeaderReplace(A,&Bmpi);CHKERRQ(ierr); 935c4ad791aSXuan Zhou } else { 936c4ad791aSXuan Zhou *B = Bmpi; 937c4ad791aSXuan Zhou } 938fa9e26c8SHong Zhang ierr = ISDestroy(&isrows);CHKERRQ(ierr); 939fa9e26c8SHong Zhang ierr = ISDestroy(&iscols);CHKERRQ(ierr); 940af295397SXuan Zhou PetscFunctionReturn(0); 941af295397SXuan Zhou } 942af295397SXuan Zhou 943cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 944af8000cdSHong Zhang { 945af8000cdSHong Zhang Mat mat_elemental; 946af8000cdSHong Zhang PetscErrorCode ierr; 947af8000cdSHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,row,ncols; 948af8000cdSHong Zhang const PetscInt *cols; 949af8000cdSHong Zhang const PetscScalar *vals; 950af8000cdSHong Zhang 951af8000cdSHong Zhang PetscFunctionBegin; 952bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 953bdeae278SStefano Zampini mat_elemental = *newmat; 954bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 955bdeae278SStefano Zampini } else { 956af8000cdSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 957af8000cdSHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 958af8000cdSHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 959af8000cdSHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 960bdeae278SStefano Zampini } 961af8000cdSHong Zhang for (row=0; row<M; row++) { 962af8000cdSHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 963bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 964af8000cdSHong Zhang ierr = MatSetValues(mat_elemental,1,&row,ncols,cols,vals,ADD_VALUES);CHKERRQ(ierr); 965af8000cdSHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 966af8000cdSHong Zhang } 967af8000cdSHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 968af8000cdSHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 969af8000cdSHong Zhang 970511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 97128be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 972af8000cdSHong Zhang } else { 973af8000cdSHong Zhang *newmat = mat_elemental; 974af8000cdSHong Zhang } 975af8000cdSHong Zhang PetscFunctionReturn(0); 976af8000cdSHong Zhang } 977af8000cdSHong Zhang 978cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 9795d7652ecSHong Zhang { 9805d7652ecSHong Zhang Mat mat_elemental; 9815d7652ecSHong Zhang PetscErrorCode ierr; 9825d7652ecSHong Zhang PetscInt row,ncols,rstart=A->rmap->rstart,rend=A->rmap->rend,j; 9835d7652ecSHong Zhang const PetscInt *cols; 9845d7652ecSHong Zhang const PetscScalar *vals; 9855d7652ecSHong Zhang 9865d7652ecSHong Zhang PetscFunctionBegin; 987bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 988bdeae278SStefano Zampini mat_elemental = *newmat; 989bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 990bdeae278SStefano Zampini } else { 9915d7652ecSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 9925d7652ecSHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 9935d7652ecSHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 9945d7652ecSHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 995bdeae278SStefano Zampini } 9965d7652ecSHong Zhang for (row=rstart; row<rend; row++) { 9975d7652ecSHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 9985d7652ecSHong Zhang for (j=0; j<ncols; j++) { 999bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 10005d7652ecSHong Zhang ierr = MatSetValues(mat_elemental,1,&row,1,&cols[j],&vals[j],ADD_VALUES);CHKERRQ(ierr); 10015d7652ecSHong Zhang } 10025d7652ecSHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 10035d7652ecSHong Zhang } 10045d7652ecSHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10055d7652ecSHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10065d7652ecSHong Zhang 1007511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 100828be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 10095d7652ecSHong Zhang } else { 10105d7652ecSHong Zhang *newmat = mat_elemental; 10115d7652ecSHong Zhang } 10125d7652ecSHong Zhang PetscFunctionReturn(0); 10135d7652ecSHong Zhang } 10145d7652ecSHong Zhang 1015cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 10166214f412SHong Zhang { 10176214f412SHong Zhang Mat mat_elemental; 10186214f412SHong Zhang PetscErrorCode ierr; 10196214f412SHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,row,ncols,j; 10206214f412SHong Zhang const PetscInt *cols; 10216214f412SHong Zhang const PetscScalar *vals; 10226214f412SHong Zhang 10236214f412SHong Zhang PetscFunctionBegin; 1024bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1025bdeae278SStefano Zampini mat_elemental = *newmat; 1026bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 1027bdeae278SStefano Zampini } else { 10286214f412SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 10296214f412SHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 10306214f412SHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 10316214f412SHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 1032bdeae278SStefano Zampini } 10336214f412SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 10346214f412SHong Zhang for (row=0; row<M; row++) { 10356214f412SHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 1036bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 10376214f412SHong Zhang ierr = MatSetValues(mat_elemental,1,&row,ncols,cols,vals,ADD_VALUES);CHKERRQ(ierr); 10386214f412SHong Zhang for (j=0; j<ncols; j++) { /* lower triangular part */ 1039eb1ec7c1SStefano Zampini PetscScalar v; 10406214f412SHong Zhang if (cols[j] == row) continue; 1041eb1ec7c1SStefano Zampini v = A->hermitian ? PetscConj(vals[j]) : vals[j]; 1042eb1ec7c1SStefano Zampini ierr = MatSetValues(mat_elemental,1,&cols[j],1,&row,&v,ADD_VALUES);CHKERRQ(ierr); 10436214f412SHong Zhang } 10446214f412SHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 10456214f412SHong Zhang } 10466214f412SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 10476214f412SHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10486214f412SHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10496214f412SHong Zhang 1050511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 105128be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 10526214f412SHong Zhang } else { 10536214f412SHong Zhang *newmat = mat_elemental; 10546214f412SHong Zhang } 10556214f412SHong Zhang PetscFunctionReturn(0); 10566214f412SHong Zhang } 10576214f412SHong Zhang 1058cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_MPISBAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 10596214f412SHong Zhang { 10606214f412SHong Zhang Mat mat_elemental; 10616214f412SHong Zhang PetscErrorCode ierr; 10626214f412SHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,row,ncols,j,rstart=A->rmap->rstart,rend=A->rmap->rend; 10636214f412SHong Zhang const PetscInt *cols; 10646214f412SHong Zhang const PetscScalar *vals; 10656214f412SHong Zhang 10666214f412SHong Zhang PetscFunctionBegin; 1067bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1068bdeae278SStefano Zampini mat_elemental = *newmat; 1069bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 1070bdeae278SStefano Zampini } else { 10716214f412SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 10726214f412SHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 10736214f412SHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 10746214f412SHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 1075bdeae278SStefano Zampini } 10766214f412SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 10776214f412SHong Zhang for (row=rstart; row<rend; row++) { 10786214f412SHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 1079bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 10806214f412SHong Zhang ierr = MatSetValues(mat_elemental,1,&row,ncols,cols,vals,ADD_VALUES);CHKERRQ(ierr); 10816214f412SHong Zhang for (j=0; j<ncols; j++) { /* lower triangular part */ 1082eb1ec7c1SStefano Zampini PetscScalar v; 10836214f412SHong Zhang if (cols[j] == row) continue; 1084eb1ec7c1SStefano Zampini v = A->hermitian ? PetscConj(vals[j]) : vals[j]; 1085eb1ec7c1SStefano Zampini ierr = MatSetValues(mat_elemental,1,&cols[j],1,&row,&v,ADD_VALUES);CHKERRQ(ierr); 10866214f412SHong Zhang } 10876214f412SHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 10886214f412SHong Zhang } 10896214f412SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 10906214f412SHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10916214f412SHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10926214f412SHong Zhang 1093511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 109428be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 10956214f412SHong Zhang } else { 10966214f412SHong Zhang *newmat = mat_elemental; 10976214f412SHong Zhang } 10986214f412SHong Zhang PetscFunctionReturn(0); 10996214f412SHong Zhang } 11006214f412SHong Zhang 1101db31f6deSJed Brown static PetscErrorCode MatDestroy_Elemental(Mat A) 1102db31f6deSJed Brown { 1103db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 1104db31f6deSJed Brown PetscErrorCode ierr; 11055e9f5b67SHong Zhang Mat_Elemental_Grid *commgrid; 11065e9f5b67SHong Zhang PetscBool flg; 11075e9f5b67SHong Zhang MPI_Comm icomm; 1108db31f6deSJed Brown 1109db31f6deSJed Brown PetscFunctionBegin; 1110db31f6deSJed Brown delete a->emat; 1111ea394475SSatish Balay delete a->P; 1112ea394475SSatish Balay delete a->Q; 11135e9f5b67SHong Zhang 1114e8146892SSatish Balay El::mpi::Comm cxxcomm(PetscObjectComm((PetscObject)A)); 11150c18141cSBarry Smith ierr = PetscCommDuplicate(cxxcomm.comm,&icomm,NULL);CHKERRQ(ierr); 1116ffc4695bSBarry Smith ierr = MPI_Comm_get_attr(icomm,Petsc_Elemental_keyval,(void**)&commgrid,(int*)&flg);CHKERRMPI(ierr); 11175e9f5b67SHong Zhang if (--commgrid->grid_refct == 0) { 11185e9f5b67SHong Zhang delete commgrid->grid; 11195e9f5b67SHong Zhang ierr = PetscFree(commgrid);CHKERRQ(ierr); 1120ffc4695bSBarry Smith ierr = MPI_Comm_free_keyval(&Petsc_Elemental_keyval);CHKERRMPI(ierr); 11215e9f5b67SHong Zhang } 11225e9f5b67SHong Zhang ierr = PetscCommDestroy(&icomm);CHKERRQ(ierr); 1123bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatGetOwnershipIS_C",NULL);CHKERRQ(ierr); 11243ca39a21SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorGetSolverType_C",NULL);CHKERRQ(ierr); 1125f6e5db1bSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_elemental_mpidense_C",NULL);CHKERRQ(ierr); 1126db31f6deSJed Brown ierr = PetscFree(A->data);CHKERRQ(ierr); 1127db31f6deSJed Brown PetscFunctionReturn(0); 1128db31f6deSJed Brown } 1129db31f6deSJed Brown 1130db31f6deSJed Brown PetscErrorCode MatSetUp_Elemental(Mat A) 1131db31f6deSJed Brown { 1132db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 1133db31f6deSJed Brown PetscErrorCode ierr; 1134f19600a0SHong Zhang MPI_Comm comm; 1135db31f6deSJed Brown PetscMPIInt rsize,csize; 1136f19600a0SHong Zhang PetscInt n; 1137db31f6deSJed Brown 1138db31f6deSJed Brown PetscFunctionBegin; 1139db31f6deSJed Brown ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1140db31f6deSJed Brown ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1141db31f6deSJed Brown 1142d8304050SJose E. Roman /* Check if local row and column sizes are equally distributed. 1143f19600a0SHong Zhang Jed: Elemental uses "element" cyclic ordering so the sizes need to match that 1144f19600a0SHong Zhang exactly. The strategy in MatElemental is for PETSc to implicitly permute to block ordering (like would be returned by 1145d8304050SJose E. Roman PetscSplitOwnership(comm,&n,&N), at which point Elemental matrices can act on PETSc vectors without redistributing the vectors. */ 1146f19600a0SHong Zhang ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 1147f19600a0SHong Zhang n = PETSC_DECIDE; 1148f19600a0SHong Zhang ierr = PetscSplitOwnership(comm,&n,&A->rmap->N);CHKERRQ(ierr); 1149f19600a0SHong Zhang if (n != A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local row size %D of ELEMENTAL matrix must be equally distributed",A->rmap->n); 1150f19600a0SHong Zhang 1151f19600a0SHong Zhang n = PETSC_DECIDE; 1152f19600a0SHong Zhang ierr = PetscSplitOwnership(comm,&n,&A->cmap->N);CHKERRQ(ierr); 1153f19600a0SHong Zhang if (n != A->cmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local column size %D of ELEMENTAL matrix must be equally distributed",A->cmap->n); 1154f19600a0SHong Zhang 1155efb79153SJack Poulson a->emat->Resize(A->rmap->N,A->cmap->N);CHKERRQ(ierr); 1156e8146892SSatish Balay El::Zero(*a->emat); 1157db31f6deSJed Brown 1158ffc4695bSBarry Smith ierr = MPI_Comm_size(A->rmap->comm,&rsize);CHKERRMPI(ierr); 1159ffc4695bSBarry Smith ierr = MPI_Comm_size(A->cmap->comm,&csize);CHKERRMPI(ierr); 1160ce94432eSBarry Smith if (csize != rsize) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"Cannot use row and column communicators of different sizes"); 1161db31f6deSJed Brown a->commsize = rsize; 1162db31f6deSJed Brown a->mr[0] = A->rmap->N % rsize; if (!a->mr[0]) a->mr[0] = rsize; 1163db31f6deSJed Brown a->mr[1] = A->cmap->N % csize; if (!a->mr[1]) a->mr[1] = csize; 1164db31f6deSJed Brown a->m[0] = A->rmap->N / rsize + (a->mr[0] != rsize); 1165db31f6deSJed Brown a->m[1] = A->cmap->N / csize + (a->mr[1] != csize); 1166db31f6deSJed Brown PetscFunctionReturn(0); 1167db31f6deSJed Brown } 1168db31f6deSJed Brown 1169aae2c449SHong Zhang PetscErrorCode MatAssemblyBegin_Elemental(Mat A, MatAssemblyType type) 1170aae2c449SHong Zhang { 1171aae2c449SHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 1172aae2c449SHong Zhang 1173aae2c449SHong Zhang PetscFunctionBegin; 1174fbbcb730SJack Poulson /* printf("Calling ProcessQueues\n"); */ 1175fbbcb730SJack Poulson a->emat->ProcessQueues(); 1176fbbcb730SJack Poulson /* printf("Finished ProcessQueues\n"); */ 1177aae2c449SHong Zhang PetscFunctionReturn(0); 1178aae2c449SHong Zhang } 1179aae2c449SHong Zhang 1180aae2c449SHong Zhang PetscErrorCode MatAssemblyEnd_Elemental(Mat A, MatAssemblyType type) 1181aae2c449SHong Zhang { 1182aae2c449SHong Zhang PetscFunctionBegin; 1183aae2c449SHong Zhang /* Currently does nothing */ 1184aae2c449SHong Zhang PetscFunctionReturn(0); 1185aae2c449SHong Zhang } 1186aae2c449SHong Zhang 11877b30e0f1SHong Zhang PetscErrorCode MatLoad_Elemental(Mat newMat, PetscViewer viewer) 11887b30e0f1SHong Zhang { 11897b30e0f1SHong Zhang PetscErrorCode ierr; 11907b30e0f1SHong Zhang Mat Adense,Ae; 11917b30e0f1SHong Zhang MPI_Comm comm; 11927b30e0f1SHong Zhang 11937b30e0f1SHong Zhang PetscFunctionBegin; 11947b30e0f1SHong Zhang ierr = PetscObjectGetComm((PetscObject)newMat,&comm);CHKERRQ(ierr); 11957b30e0f1SHong Zhang ierr = MatCreate(comm,&Adense);CHKERRQ(ierr); 11967b30e0f1SHong Zhang ierr = MatSetType(Adense,MATDENSE);CHKERRQ(ierr); 11977b30e0f1SHong Zhang ierr = MatLoad(Adense,viewer);CHKERRQ(ierr); 11987b30e0f1SHong Zhang ierr = MatConvert(Adense, MATELEMENTAL, MAT_INITIAL_MATRIX,&Ae);CHKERRQ(ierr); 11997b30e0f1SHong Zhang ierr = MatDestroy(&Adense);CHKERRQ(ierr); 120028be2f97SBarry Smith ierr = MatHeaderReplace(newMat,&Ae);CHKERRQ(ierr); 12017b30e0f1SHong Zhang PetscFunctionReturn(0); 12027b30e0f1SHong Zhang } 12037b30e0f1SHong Zhang 120440d92e34SHong Zhang /* -------------------------------------------------------------------*/ 120540d92e34SHong Zhang static struct _MatOps MatOps_Values = { 120640d92e34SHong Zhang MatSetValues_Elemental, 120740d92e34SHong Zhang 0, 120840d92e34SHong Zhang 0, 120940d92e34SHong Zhang MatMult_Elemental, 121040d92e34SHong Zhang /* 4*/ MatMultAdd_Elemental, 12119426833fSXuan Zhou MatMultTranspose_Elemental, 1212e883f9d5SXuan Zhou MatMultTransposeAdd_Elemental, 121340d92e34SHong Zhang MatSolve_Elemental, 1214df311e6cSXuan Zhou MatSolveAdd_Elemental, 12152ef15aa2SHong Zhang 0, 12162ef15aa2SHong Zhang /*10*/ 0, 121740d92e34SHong Zhang MatLUFactor_Elemental, 121840d92e34SHong Zhang MatCholeskyFactor_Elemental, 121940d92e34SHong Zhang 0, 122040d92e34SHong Zhang MatTranspose_Elemental, 122140d92e34SHong Zhang /*15*/ MatGetInfo_Elemental, 122240d92e34SHong Zhang 0, 122361119200SXuan Zhou MatGetDiagonal_Elemental, 1224ade3cc5eSXuan Zhou MatDiagonalScale_Elemental, 122540d92e34SHong Zhang MatNorm_Elemental, 122640d92e34SHong Zhang /*20*/ MatAssemblyBegin_Elemental, 122740d92e34SHong Zhang MatAssemblyEnd_Elemental, 122832d7a744SHong Zhang MatSetOption_Elemental, 122940d92e34SHong Zhang MatZeroEntries_Elemental, 123040d92e34SHong Zhang /*24*/ 0, 123140d92e34SHong Zhang MatLUFactorSymbolic_Elemental, 123240d92e34SHong Zhang MatLUFactorNumeric_Elemental, 123340d92e34SHong Zhang MatCholeskyFactorSymbolic_Elemental, 123440d92e34SHong Zhang MatCholeskyFactorNumeric_Elemental, 123540d92e34SHong Zhang /*29*/ MatSetUp_Elemental, 123640d92e34SHong Zhang 0, 123740d92e34SHong Zhang 0, 123840d92e34SHong Zhang 0, 123940d92e34SHong Zhang 0, 1240df311e6cSXuan Zhou /*34*/ MatDuplicate_Elemental, 124140d92e34SHong Zhang 0, 124240d92e34SHong Zhang 0, 124340d92e34SHong Zhang 0, 124440d92e34SHong Zhang 0, 124540d92e34SHong Zhang /*39*/ MatAXPY_Elemental, 124640d92e34SHong Zhang 0, 124740d92e34SHong Zhang 0, 124840d92e34SHong Zhang 0, 124940d92e34SHong Zhang MatCopy_Elemental, 125040d92e34SHong Zhang /*44*/ 0, 125140d92e34SHong Zhang MatScale_Elemental, 12527d68702bSBarry Smith MatShift_Basic, 125340d92e34SHong Zhang 0, 125440d92e34SHong Zhang 0, 125540d92e34SHong Zhang /*49*/ 0, 125640d92e34SHong Zhang 0, 125740d92e34SHong Zhang 0, 125840d92e34SHong Zhang 0, 125940d92e34SHong Zhang 0, 126040d92e34SHong Zhang /*54*/ 0, 126140d92e34SHong Zhang 0, 126240d92e34SHong Zhang 0, 126340d92e34SHong Zhang 0, 126440d92e34SHong Zhang 0, 126540d92e34SHong Zhang /*59*/ 0, 126640d92e34SHong Zhang MatDestroy_Elemental, 126740d92e34SHong Zhang MatView_Elemental, 126840d92e34SHong Zhang 0, 126940d92e34SHong Zhang 0, 127040d92e34SHong Zhang /*64*/ 0, 127140d92e34SHong Zhang 0, 127240d92e34SHong Zhang 0, 127340d92e34SHong Zhang 0, 127440d92e34SHong Zhang 0, 127540d92e34SHong Zhang /*69*/ 0, 127640d92e34SHong Zhang 0, 12772ef0cf24SXuan Zhou MatConvert_Elemental_Dense, 127840d92e34SHong Zhang 0, 127940d92e34SHong Zhang 0, 128040d92e34SHong Zhang /*74*/ 0, 128140d92e34SHong Zhang 0, 128240d92e34SHong Zhang 0, 128340d92e34SHong Zhang 0, 128440d92e34SHong Zhang 0, 128540d92e34SHong Zhang /*79*/ 0, 128640d92e34SHong Zhang 0, 128740d92e34SHong Zhang 0, 128840d92e34SHong Zhang 0, 12897b30e0f1SHong Zhang MatLoad_Elemental, 129040d92e34SHong Zhang /*84*/ 0, 129140d92e34SHong Zhang 0, 129240d92e34SHong Zhang 0, 129340d92e34SHong Zhang 0, 129440d92e34SHong Zhang 0, 12954222ddf1SHong Zhang /*89*/ 0, 12964222ddf1SHong Zhang 0, 129740d92e34SHong Zhang MatMatMultNumeric_Elemental, 129840d92e34SHong Zhang 0, 129940d92e34SHong Zhang 0, 130040d92e34SHong Zhang /*94*/ 0, 13014222ddf1SHong Zhang 0, 13024222ddf1SHong Zhang 0, 1303df311e6cSXuan Zhou MatMatTransposeMultNumeric_Elemental, 130440d92e34SHong Zhang 0, 13054222ddf1SHong Zhang /*99*/ MatProductSetFromOptions_Elemental, 130640d92e34SHong Zhang 0, 130740d92e34SHong Zhang 0, 1308dfcb0403SXuan Zhou MatConjugate_Elemental, 130940d92e34SHong Zhang 0, 131040d92e34SHong Zhang /*104*/0, 131140d92e34SHong Zhang 0, 131240d92e34SHong Zhang 0, 131340d92e34SHong Zhang 0, 131440d92e34SHong Zhang 0, 131540d92e34SHong Zhang /*109*/MatMatSolve_Elemental, 131640d92e34SHong Zhang 0, 131740d92e34SHong Zhang 0, 131840d92e34SHong Zhang 0, 131934fa46e1SFrancesco Ballarin MatMissingDiagonal_Elemental, 132040d92e34SHong Zhang /*114*/0, 132140d92e34SHong Zhang 0, 132240d92e34SHong Zhang 0, 132340d92e34SHong Zhang 0, 132440d92e34SHong Zhang 0, 132540d92e34SHong Zhang /*119*/0, 13264a29722dSXuan Zhou MatHermitianTranspose_Elemental, 132740d92e34SHong Zhang 0, 132840d92e34SHong Zhang 0, 132940d92e34SHong Zhang 0, 133040d92e34SHong Zhang /*124*/0, 133140d92e34SHong Zhang 0, 133240d92e34SHong Zhang 0, 133340d92e34SHong Zhang 0, 133440d92e34SHong Zhang 0, 133540d92e34SHong Zhang /*129*/0, 133640d92e34SHong Zhang 0, 133740d92e34SHong Zhang 0, 133840d92e34SHong Zhang 0, 133940d92e34SHong Zhang 0, 134040d92e34SHong Zhang /*134*/0, 134140d92e34SHong Zhang 0, 134240d92e34SHong Zhang 0, 134340d92e34SHong Zhang 0, 13444222ddf1SHong Zhang 0, 13454222ddf1SHong Zhang 0, 13464222ddf1SHong Zhang /*140*/0, 13474222ddf1SHong Zhang 0, 13484222ddf1SHong Zhang 0, 13494222ddf1SHong Zhang 0, 13504222ddf1SHong Zhang 0, 13514222ddf1SHong Zhang /*145*/0, 13524222ddf1SHong Zhang 0, 135340d92e34SHong Zhang 0 135440d92e34SHong Zhang }; 135540d92e34SHong Zhang 1356ed36708cSHong Zhang /*MC 1357ed36708cSHong Zhang MATELEMENTAL = "elemental" - A matrix type for dense matrices using the Elemental package 1358ed36708cSHong Zhang 1359c2b89b5dSBarry Smith Use ./configure --download-elemental to install PETSc to use Elemental 1360c2b89b5dSBarry Smith 13613ca39a21SBarry Smith Use -pc_type lu -pc_factor_mat_solver_type elemental to use this direct solver 1362c2b89b5dSBarry Smith 1363ed36708cSHong Zhang Options Database Keys: 13645cc86fc1SJed Brown + -mat_type elemental - sets the matrix type to "elemental" during a call to MatSetFromOptions() 13655cc86fc1SJed Brown - -mat_elemental_grid_height - sets Grid Height for 2D cyclic ordering of internal matrix 1366ed36708cSHong Zhang 1367ed36708cSHong Zhang Level: beginner 1368ed36708cSHong Zhang 13695cb544a0SHong Zhang .seealso: MATDENSE 1370ed36708cSHong Zhang M*/ 13714a29722dSXuan Zhou 13728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_Elemental(Mat A) 1373db31f6deSJed Brown { 1374db31f6deSJed Brown Mat_Elemental *a; 1375db31f6deSJed Brown PetscErrorCode ierr; 13765682a260SJack Poulson PetscBool flg,flg1; 13775e9f5b67SHong Zhang Mat_Elemental_Grid *commgrid; 13785e9f5b67SHong Zhang MPI_Comm icomm; 13795682a260SJack Poulson PetscInt optv1; 1380db31f6deSJed Brown 1381db31f6deSJed Brown PetscFunctionBegin; 138240d92e34SHong Zhang ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 138340d92e34SHong Zhang A->insertmode = NOT_SET_VALUES; 1384db31f6deSJed Brown 1385b00a9115SJed Brown ierr = PetscNewLog(A,&a);CHKERRQ(ierr); 1386db31f6deSJed Brown A->data = (void*)a; 1387db31f6deSJed Brown 1388db31f6deSJed Brown /* Set up the elemental matrix */ 1389e8146892SSatish Balay El::mpi::Comm cxxcomm(PetscObjectComm((PetscObject)A)); 13905e9f5b67SHong Zhang 13915e9f5b67SHong Zhang /* Grid needs to be shared between multiple Mats on the same communicator, implement by attribute caching on the MPI_Comm */ 13925e9f5b67SHong Zhang if (Petsc_Elemental_keyval == MPI_KEYVAL_INVALID) { 1393ffc4695bSBarry Smith ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Elemental_keyval,(void*)0);CHKERRMPI(ierr); 13945e9f5b67SHong Zhang } 13950c18141cSBarry Smith ierr = PetscCommDuplicate(cxxcomm.comm,&icomm,NULL);CHKERRQ(ierr); 1396ffc4695bSBarry Smith ierr = MPI_Comm_get_attr(icomm,Petsc_Elemental_keyval,(void**)&commgrid,(int*)&flg);CHKERRMPI(ierr); 13975e9f5b67SHong Zhang if (!flg) { 1398b00a9115SJed Brown ierr = PetscNewLog(A,&commgrid);CHKERRQ(ierr); 13995cb544a0SHong Zhang 1400ce94432eSBarry Smith ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"Elemental Options","Mat");CHKERRQ(ierr); 1401e8146892SSatish Balay /* displayed default grid sizes (CommSize,1) are set by us arbitrarily until El::Grid() is called */ 1402e8146892SSatish Balay ierr = PetscOptionsInt("-mat_elemental_grid_height","Grid Height","None",El::mpi::Size(cxxcomm),&optv1,&flg1);CHKERRQ(ierr); 14035682a260SJack Poulson if (flg1) { 1404d8304050SJose E. Roman if (El::mpi::Size(cxxcomm) % optv1) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"Grid Height %D must evenly divide CommSize %D",optv1,(PetscInt)El::mpi::Size(cxxcomm)); 1405e8146892SSatish Balay commgrid->grid = new El::Grid(cxxcomm,optv1); /* use user-provided grid height */ 14062ef0cf24SXuan Zhou } else { 1407e8146892SSatish Balay commgrid->grid = new El::Grid(cxxcomm); /* use Elemental default grid sizes */ 1408da0640a4SHong Zhang /* printf("new commgrid->grid = %p\n",commgrid->grid); -- memory leak revealed by valgrind? */ 1409ed667823SXuan Zhou } 14105e9f5b67SHong Zhang commgrid->grid_refct = 1; 1411ffc4695bSBarry Smith ierr = MPI_Comm_set_attr(icomm,Petsc_Elemental_keyval,(void*)commgrid);CHKERRMPI(ierr); 1412ea394475SSatish Balay 1413ea394475SSatish Balay a->pivoting = 1; 1414ea394475SSatish Balay ierr = PetscOptionsInt("-mat_elemental_pivoting","Pivoting","None",a->pivoting,&a->pivoting,NULL);CHKERRQ(ierr); 1415ea394475SSatish Balay 14162a808120SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 14175e9f5b67SHong Zhang } else { 14185e9f5b67SHong Zhang commgrid->grid_refct++; 14195e9f5b67SHong Zhang } 14205e9f5b67SHong Zhang ierr = PetscCommDestroy(&icomm);CHKERRQ(ierr); 14215e9f5b67SHong Zhang a->grid = commgrid->grid; 1422e8146892SSatish Balay a->emat = new El::DistMatrix<PetscElemScalar>(*a->grid); 142332d7a744SHong Zhang a->roworiented = PETSC_TRUE; 1424db31f6deSJed Brown 1425bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatGetOwnershipIS_C",MatGetOwnershipIS_Elemental);CHKERRQ(ierr); 1426f6e5db1bSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_elemental_mpidense_C",MatProductSetFromOptions_Elemental_MPIDense);CHKERRQ(ierr); 1427db31f6deSJed Brown ierr = PetscObjectChangeTypeName((PetscObject)A,MATELEMENTAL);CHKERRQ(ierr); 1428db31f6deSJed Brown PetscFunctionReturn(0); 1429db31f6deSJed Brown } 1430