1db31f6deSJed Brown #include <../src/mat/impls/elemental/matelemimpl.h> /*I "petscmat.h" I*/ 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 /*@C 10db31f6deSJed Brown PetscElementalInitializePackage - Initialize Elemental package 11db31f6deSJed Brown 12db31f6deSJed Brown Logically Collective 13db31f6deSJed Brown 14db31f6deSJed Brown Level: developer 15db31f6deSJed Brown 16db31f6deSJed Brown .seealso: MATELEMENTAL, PetscElementalFinalizePackage() 17db31f6deSJed Brown @*/ 18607a6623SBarry Smith PetscErrorCode PetscElementalInitializePackage(void) 19db31f6deSJed Brown { 20db31f6deSJed Brown PetscErrorCode ierr; 21db31f6deSJed Brown 22db31f6deSJed Brown PetscFunctionBegin; 23e8146892SSatish Balay if (El::Initialized()) PetscFunctionReturn(0); 24e05a9d59SSatish Balay El::Initialize(); /* called by the 1st call of MatCreate_Elemental */ 25db31f6deSJed Brown ierr = PetscRegisterFinalize(PetscElementalFinalizePackage);CHKERRQ(ierr); 26db31f6deSJed Brown PetscFunctionReturn(0); 27db31f6deSJed Brown } 28db31f6deSJed Brown 29db31f6deSJed Brown /*@C 30db31f6deSJed Brown PetscElementalFinalizePackage - Finalize Elemental package 31db31f6deSJed Brown 32db31f6deSJed Brown Logically Collective 33db31f6deSJed Brown 34db31f6deSJed Brown Level: developer 35db31f6deSJed Brown 36db31f6deSJed Brown .seealso: MATELEMENTAL, PetscElementalInitializePackage() 37db31f6deSJed Brown @*/ 38db31f6deSJed Brown PetscErrorCode PetscElementalFinalizePackage(void) 39db31f6deSJed Brown { 40db31f6deSJed Brown PetscFunctionBegin; 41e8146892SSatish Balay El::Finalize(); /* called by PetscFinalize() */ 42db31f6deSJed Brown PetscFunctionReturn(0); 43db31f6deSJed Brown } 44db31f6deSJed Brown 45db31f6deSJed Brown static PetscErrorCode MatView_Elemental(Mat A,PetscViewer viewer) 46db31f6deSJed Brown { 47db31f6deSJed Brown PetscErrorCode ierr; 48db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 49db31f6deSJed Brown PetscBool iascii; 50db31f6deSJed Brown 51db31f6deSJed Brown PetscFunctionBegin; 52db31f6deSJed Brown ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 53db31f6deSJed Brown if (iascii) { 54db31f6deSJed Brown PetscViewerFormat format; 55db31f6deSJed Brown ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 56db31f6deSJed Brown if (format == PETSC_VIEWER_ASCII_INFO) { 5779673f7bSHong Zhang /* call elemental viewing function */ 582d8adcc7SHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"Elemental run parameters:\n");CHKERRQ(ierr); 59ed667823SXuan Zhou ierr = PetscViewerASCIIPrintf(viewer," allocated entries=%d\n",(*a->emat).AllocatedMemory());CHKERRQ(ierr); 60ed667823SXuan Zhou ierr = PetscViewerASCIIPrintf(viewer," grid height=%d, grid width=%d\n",(*a->emat).Grid().Height(),(*a->emat).Grid().Width());CHKERRQ(ierr); 614fe7bbcaSHong Zhang if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 6279673f7bSHong Zhang /* call elemental viewing function */ 63ce94432eSBarry Smith ierr = PetscPrintf(PetscObjectComm((PetscObject)viewer),"test matview_elemental 2\n");CHKERRQ(ierr); 644fe7bbcaSHong Zhang } 6579673f7bSHong Zhang 66db31f6deSJed Brown } else if (format == PETSC_VIEWER_DEFAULT) { 67db31f6deSJed Brown ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 68e8146892SSatish Balay El::Print( *a->emat, "Elemental matrix (cyclic ordering)" ); 69db31f6deSJed Brown ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 70834d3fecSHong Zhang if (A->factortype == MAT_FACTOR_NONE){ 7161119200SXuan Zhou Mat Adense; 72ce94432eSBarry Smith ierr = PetscPrintf(PetscObjectComm((PetscObject)viewer),"Elemental matrix (explicit ordering)\n");CHKERRQ(ierr); 7361119200SXuan Zhou ierr = MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&Adense);CHKERRQ(ierr); 7461119200SXuan Zhou ierr = MatView(Adense,viewer);CHKERRQ(ierr); 7561119200SXuan Zhou ierr = MatDestroy(&Adense);CHKERRQ(ierr); 76834d3fecSHong Zhang } 77ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Format"); 78d2daa67eSHong Zhang } else { 795cb544a0SHong Zhang /* convert to dense format and call MatView() */ 8061119200SXuan Zhou Mat Adense; 81ce94432eSBarry Smith ierr = PetscPrintf(PetscObjectComm((PetscObject)viewer),"Elemental matrix (explicit ordering)\n");CHKERRQ(ierr); 8261119200SXuan Zhou ierr = MatConvert(A,MATDENSE,MAT_INITIAL_MATRIX,&Adense);CHKERRQ(ierr); 8361119200SXuan Zhou ierr = MatView(Adense,viewer);CHKERRQ(ierr); 8461119200SXuan Zhou ierr = MatDestroy(&Adense);CHKERRQ(ierr); 85d2daa67eSHong Zhang } 86db31f6deSJed Brown PetscFunctionReturn(0); 87db31f6deSJed Brown } 88db31f6deSJed Brown 8915767789SHong Zhang static PetscErrorCode MatGetInfo_Elemental(Mat A,MatInfoType flag,MatInfo *info) 90180a43e4SHong Zhang { 9115767789SHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 9215767789SHong Zhang 93180a43e4SHong Zhang PetscFunctionBegin; 945cb544a0SHong Zhang info->block_size = 1.0; 9515767789SHong Zhang 9615767789SHong Zhang if (flag == MAT_LOCAL) { 9715767789SHong Zhang info->nz_allocated = (double)(*a->emat).AllocatedMemory(); /* locally allocated */ 9815767789SHong Zhang info->nz_used = info->nz_allocated; 9915767789SHong Zhang } else if (flag == MAT_GLOBAL_MAX) { 100b2566f29SBarry Smith //ierr = MPIU_Allreduce(isend,irecv,5,MPIU_REAL,MPIU_MAX,PetscObjectComm((PetscObject)matin));CHKERRQ(ierr); 10115767789SHong Zhang /* see MatGetInfo_MPIAIJ() for getting global info->nz_allocated! */ 10215767789SHong Zhang //SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP," MAT_GLOBAL_MAX not written yet"); 10315767789SHong Zhang } else if (flag == MAT_GLOBAL_SUM) { 10415767789SHong Zhang //SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP," MAT_GLOBAL_SUM not written yet"); 10515767789SHong Zhang info->nz_allocated = (double)(*a->emat).AllocatedMemory(); /* locally allocated */ 10615767789SHong Zhang info->nz_used = info->nz_allocated; /* assume Elemental does accurate allocation */ 107b2566f29SBarry Smith //ierr = MPIU_Allreduce(isend,irecv,1,MPIU_REAL,MPIU_SUM,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 10815767789SHong Zhang //PetscPrintf(PETSC_COMM_SELF," ... [%d] locally allocated %g\n",rank,info->nz_allocated); 10915767789SHong Zhang } 11015767789SHong Zhang 11115767789SHong Zhang info->nz_unneeded = 0.0; 11215767789SHong Zhang info->assemblies = (double)A->num_ass; 11315767789SHong Zhang info->mallocs = 0; 11415767789SHong Zhang info->memory = ((PetscObject)A)->mem; 11515767789SHong Zhang info->fill_ratio_given = 0; /* determined by Elemental */ 11615767789SHong Zhang info->fill_ratio_needed = 0; 11715767789SHong Zhang info->factor_mallocs = 0; 118180a43e4SHong Zhang PetscFunctionReturn(0); 119180a43e4SHong Zhang } 120180a43e4SHong Zhang 12132d7a744SHong Zhang PetscErrorCode MatSetOption_Elemental(Mat A,MatOption op,PetscBool flg) 12232d7a744SHong Zhang { 12332d7a744SHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 12432d7a744SHong Zhang 12532d7a744SHong Zhang PetscFunctionBegin; 12632d7a744SHong Zhang switch (op) { 12732d7a744SHong Zhang case MAT_NEW_NONZERO_LOCATIONS: 12832d7a744SHong Zhang case MAT_NEW_NONZERO_LOCATION_ERR: 12932d7a744SHong Zhang case MAT_NEW_NONZERO_ALLOCATION_ERR: 130891a0571SHong Zhang case MAT_SYMMETRIC: 131891a0571SHong Zhang break; 13232d7a744SHong Zhang case MAT_ROW_ORIENTED: 13332d7a744SHong Zhang a->roworiented = flg; 13432d7a744SHong Zhang break; 13532d7a744SHong Zhang default: 13632d7a744SHong Zhang SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]); 13732d7a744SHong Zhang } 13832d7a744SHong Zhang PetscFunctionReturn(0); 13932d7a744SHong Zhang } 14032d7a744SHong Zhang 141e6dea9dbSXuan Zhou static PetscErrorCode MatSetValues_Elemental(Mat A,PetscInt nr,const PetscInt *rows,PetscInt nc,const PetscInt *cols,const PetscScalar *vals,InsertMode imode) 142db31f6deSJed Brown { 143db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 144fbbcb730SJack Poulson PetscInt i,j,rrank,ridx,crank,cidx,erow,ecol,numQueues=0; 145db31f6deSJed Brown 146db31f6deSJed Brown PetscFunctionBegin; 147fbbcb730SJack Poulson // TODO: Initialize matrix to all zeros? 148fbbcb730SJack Poulson 149fbbcb730SJack Poulson // Count the number of queues from this process 15032d7a744SHong Zhang if (a->roworiented) { 151db31f6deSJed Brown for (i=0; i<nr; i++) { 152db31f6deSJed Brown if (rows[i] < 0) continue; 153db31f6deSJed Brown P2RO(A,0,rows[i],&rrank,&ridx); 154db31f6deSJed Brown RO2E(A,0,rrank,ridx,&erow); 155ce94432eSBarry Smith if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect row translation"); 156db31f6deSJed Brown for (j=0; j<nc; j++) { 157db31f6deSJed Brown if (cols[j] < 0) continue; 158db31f6deSJed Brown P2RO(A,1,cols[j],&crank,&cidx); 159db31f6deSJed Brown RO2E(A,1,crank,cidx,&ecol); 160ce94432eSBarry Smith if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect col translation"); 161fbbcb730SJack Poulson if (!a->emat->IsLocal(erow,ecol) ){ /* off-proc entry */ 162fbbcb730SJack Poulson /* printf("Will later remotely update (%d,%d)\n",erow,ecol); */ 163aae2c449SHong Zhang if (imode != ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ADD_VALUES to off-processor entry is supported"); 164fbbcb730SJack Poulson ++numQueues; 165aae2c449SHong Zhang continue; 166ed36708cSHong Zhang } 167fbbcb730SJack Poulson /* printf("Locally updating (%d,%d)\n",erow,ecol); */ 168db31f6deSJed Brown switch (imode) { 169fbbcb730SJack Poulson case INSERT_VALUES: a->emat->Set(erow,ecol,(PetscElemScalar)vals[i*nc+j]); break; 170fbbcb730SJack Poulson case ADD_VALUES: a->emat->Update(erow,ecol,(PetscElemScalar)vals[i*nc+j]); break; 171ce94432eSBarry Smith default: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for InsertMode %d",(int)imode); 172db31f6deSJed Brown } 173db31f6deSJed Brown } 174db31f6deSJed Brown } 175fbbcb730SJack Poulson 176fbbcb730SJack Poulson /* printf("numQueues=%d\n",numQueues); */ 177fbbcb730SJack Poulson a->emat->Reserve( numQueues ); 178fbbcb730SJack Poulson for (i=0; i<nr; i++) { 179fbbcb730SJack Poulson if (rows[i] < 0) continue; 180fbbcb730SJack Poulson P2RO(A,0,rows[i],&rrank,&ridx); 181fbbcb730SJack Poulson RO2E(A,0,rrank,ridx,&erow); 182fbbcb730SJack Poulson for (j=0; j<nc; j++) { 183fbbcb730SJack Poulson if (cols[j] < 0) continue; 184fbbcb730SJack Poulson P2RO(A,1,cols[j],&crank,&cidx); 185fbbcb730SJack Poulson RO2E(A,1,crank,cidx,&ecol); 186fbbcb730SJack Poulson if ( !a->emat->IsLocal(erow,ecol) ) { /*off-proc entry*/ 187fbbcb730SJack Poulson /* printf("Queueing remotely update of (%d,%d)\n",erow,ecol); */ 188fbbcb730SJack Poulson a->emat->QueueUpdate( erow, ecol, vals[i*nc+j] ); 189fbbcb730SJack Poulson } 190fbbcb730SJack Poulson } 191fbbcb730SJack Poulson } 19232d7a744SHong Zhang } else { /* columnoriented */ 19332d7a744SHong Zhang for (j=0; j<nc; j++) { 19432d7a744SHong Zhang if (cols[j] < 0) continue; 19532d7a744SHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 19632d7a744SHong Zhang RO2E(A,1,crank,cidx,&ecol); 19732d7a744SHong Zhang if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect col translation"); 19832d7a744SHong Zhang for (i=0; i<nr; i++) { 19932d7a744SHong Zhang if (rows[i] < 0) continue; 20032d7a744SHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); 20132d7a744SHong Zhang RO2E(A,0,rrank,ridx,&erow); 20232d7a744SHong Zhang if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Incorrect row translation"); 20332d7a744SHong Zhang if (!a->emat->IsLocal(erow,ecol) ){ /* off-proc entry */ 20432d7a744SHong Zhang /* printf("Will later remotely update (%d,%d)\n",erow,ecol); */ 20532d7a744SHong Zhang if (imode != ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ADD_VALUES to off-processor entry is supported"); 20632d7a744SHong Zhang ++numQueues; 20732d7a744SHong Zhang continue; 20832d7a744SHong Zhang } 20932d7a744SHong Zhang /* printf("Locally updating (%d,%d)\n",erow,ecol); */ 21032d7a744SHong Zhang switch (imode) { 21132d7a744SHong Zhang case INSERT_VALUES: a->emat->Set(erow,ecol,(PetscElemScalar)vals[i+j*nr]); break; 21232d7a744SHong Zhang case ADD_VALUES: a->emat->Update(erow,ecol,(PetscElemScalar)vals[i+j*nr]); break; 21332d7a744SHong Zhang default: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for InsertMode %d",(int)imode); 21432d7a744SHong Zhang } 21532d7a744SHong Zhang } 21632d7a744SHong Zhang } 21732d7a744SHong Zhang 21832d7a744SHong Zhang /* printf("numQueues=%d\n",numQueues); */ 21932d7a744SHong Zhang a->emat->Reserve( numQueues ); 22032d7a744SHong Zhang for (j=0; j<nc; j++) { 22132d7a744SHong Zhang if (cols[j] < 0) continue; 22232d7a744SHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 22332d7a744SHong Zhang RO2E(A,1,crank,cidx,&ecol); 22432d7a744SHong Zhang 22532d7a744SHong Zhang for (i=0; i<nr; i++) { 22632d7a744SHong Zhang if (rows[i] < 0) continue; 22732d7a744SHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); 22832d7a744SHong Zhang RO2E(A,0,rrank,ridx,&erow); 22932d7a744SHong Zhang if ( !a->emat->IsLocal(erow,ecol) ) { /*off-proc entry*/ 23032d7a744SHong Zhang /* printf("Queueing remotely update of (%d,%d)\n",erow,ecol); */ 23132d7a744SHong Zhang a->emat->QueueUpdate( erow, ecol, vals[i+j*nr] ); 23232d7a744SHong Zhang } 23332d7a744SHong Zhang } 23432d7a744SHong Zhang } 23532d7a744SHong Zhang } 236db31f6deSJed Brown PetscFunctionReturn(0); 237db31f6deSJed Brown } 238db31f6deSJed Brown 239db31f6deSJed Brown static PetscErrorCode MatMult_Elemental(Mat A,Vec X,Vec Y) 240db31f6deSJed Brown { 241db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 242db31f6deSJed Brown PetscErrorCode ierr; 243e6dea9dbSXuan Zhou const PetscElemScalar *x; 244e6dea9dbSXuan Zhou PetscElemScalar *y; 245df311e6cSXuan Zhou PetscElemScalar one = 1,zero = 0; 246db31f6deSJed Brown 247db31f6deSJed Brown PetscFunctionBegin; 248e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 249e6dea9dbSXuan Zhou ierr = VecGetArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 250db31f6deSJed Brown { /* Scoping so that constructor is called before pointer is returned */ 251e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ye; 2520c18141cSBarry Smith xe.LockedAttach(A->cmap->N,1,*a->grid,0,0,x,A->cmap->n); 2530c18141cSBarry Smith ye.Attach(A->rmap->N,1,*a->grid,0,0,y,A->rmap->n); 254e8146892SSatish Balay El::Gemv(El::NORMAL,one,*a->emat,xe,zero,ye); 255db31f6deSJed Brown } 256e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 257e6dea9dbSXuan Zhou ierr = VecRestoreArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 258db31f6deSJed Brown PetscFunctionReturn(0); 259db31f6deSJed Brown } 260db31f6deSJed Brown 2619426833fSXuan Zhou static PetscErrorCode MatMultTranspose_Elemental(Mat A,Vec X,Vec Y) 2629426833fSXuan Zhou { 2639426833fSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 2649426833fSXuan Zhou PetscErrorCode ierr; 265df311e6cSXuan Zhou const PetscElemScalar *x; 266df311e6cSXuan Zhou PetscElemScalar *y; 267e6dea9dbSXuan Zhou PetscElemScalar one = 1,zero = 0; 2689426833fSXuan Zhou 2699426833fSXuan Zhou PetscFunctionBegin; 270e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 271e6dea9dbSXuan Zhou ierr = VecGetArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 2729426833fSXuan Zhou { /* Scoping so that constructor is called before pointer is returned */ 273e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ye; 2740c18141cSBarry Smith xe.LockedAttach(A->rmap->N,1,*a->grid,0,0,x,A->rmap->n); 2750c18141cSBarry Smith ye.Attach(A->cmap->N,1,*a->grid,0,0,y,A->cmap->n); 276e8146892SSatish Balay El::Gemv(El::TRANSPOSE,one,*a->emat,xe,zero,ye); 2779426833fSXuan Zhou } 278e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 279e6dea9dbSXuan Zhou ierr = VecRestoreArray(Y,(PetscScalar **)&y);CHKERRQ(ierr); 2809426833fSXuan Zhou PetscFunctionReturn(0); 2819426833fSXuan Zhou } 2829426833fSXuan Zhou 283db31f6deSJed Brown static PetscErrorCode MatMultAdd_Elemental(Mat A,Vec X,Vec Y,Vec Z) 284db31f6deSJed Brown { 285db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 286db31f6deSJed Brown PetscErrorCode ierr; 287df311e6cSXuan Zhou const PetscElemScalar *x; 288df311e6cSXuan Zhou PetscElemScalar *z; 289e6dea9dbSXuan Zhou PetscElemScalar one = 1; 290db31f6deSJed Brown 291db31f6deSJed Brown PetscFunctionBegin; 292db31f6deSJed Brown if (Y != Z) {ierr = VecCopy(Y,Z);CHKERRQ(ierr);} 293e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 294e6dea9dbSXuan Zhou ierr = VecGetArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 295db31f6deSJed Brown { /* Scoping so that constructor is called before pointer is returned */ 296e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ze; 2970c18141cSBarry Smith xe.LockedAttach(A->cmap->N,1,*a->grid,0,0,x,A->cmap->n); 2980c18141cSBarry Smith ze.Attach(A->rmap->N,1,*a->grid,0,0,z,A->rmap->n); 299e8146892SSatish Balay El::Gemv(El::NORMAL,one,*a->emat,xe,one,ze); 300db31f6deSJed Brown } 301e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 302e6dea9dbSXuan Zhou ierr = VecRestoreArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 303db31f6deSJed Brown PetscFunctionReturn(0); 304db31f6deSJed Brown } 305db31f6deSJed Brown 306e883f9d5SXuan Zhou static PetscErrorCode MatMultTransposeAdd_Elemental(Mat A,Vec X,Vec Y,Vec Z) 307e883f9d5SXuan Zhou { 308e883f9d5SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 309e883f9d5SXuan Zhou PetscErrorCode ierr; 310df311e6cSXuan Zhou const PetscElemScalar *x; 311df311e6cSXuan Zhou PetscElemScalar *z; 312e6dea9dbSXuan Zhou PetscElemScalar one = 1; 313e883f9d5SXuan Zhou 314e883f9d5SXuan Zhou PetscFunctionBegin; 315e883f9d5SXuan Zhou if (Y != Z) {ierr = VecCopy(Y,Z);CHKERRQ(ierr);} 316e6dea9dbSXuan Zhou ierr = VecGetArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 317e6dea9dbSXuan Zhou ierr = VecGetArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 318e883f9d5SXuan Zhou { /* Scoping so that constructor is called before pointer is returned */ 319e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe, ze; 3200c18141cSBarry Smith xe.LockedAttach(A->rmap->N,1,*a->grid,0,0,x,A->rmap->n); 3210c18141cSBarry Smith ze.Attach(A->cmap->N,1,*a->grid,0,0,z,A->cmap->n); 322e8146892SSatish Balay El::Gemv(El::TRANSPOSE,one,*a->emat,xe,one,ze); 323e883f9d5SXuan Zhou } 324e6dea9dbSXuan Zhou ierr = VecRestoreArrayRead(X,(const PetscScalar **)&x);CHKERRQ(ierr); 325e6dea9dbSXuan Zhou ierr = VecRestoreArray(Z,(PetscScalar **)&z);CHKERRQ(ierr); 326e883f9d5SXuan Zhou PetscFunctionReturn(0); 327e883f9d5SXuan Zhou } 328e883f9d5SXuan Zhou 3299a9e8502SHong Zhang static PetscErrorCode MatMatMultNumeric_Elemental(Mat A,Mat B,Mat C) 330c1d1b975SXuan Zhou { 331c1d1b975SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 332c1d1b975SXuan Zhou Mat_Elemental *b = (Mat_Elemental*)B->data; 3339a9e8502SHong Zhang Mat_Elemental *c = (Mat_Elemental*)C->data; 334e6dea9dbSXuan Zhou PetscElemScalar one = 1,zero = 0; 335c1d1b975SXuan Zhou 336c1d1b975SXuan Zhou PetscFunctionBegin; 337aae2c449SHong Zhang { /* Scoping so that constructor is called before pointer is returned */ 338e8146892SSatish Balay El::Gemm(El::NORMAL,El::NORMAL,one,*a->emat,*b->emat,zero,*c->emat); 339aae2c449SHong Zhang } 3409a9e8502SHong Zhang C->assembled = PETSC_TRUE; 3419a9e8502SHong Zhang PetscFunctionReturn(0); 3429a9e8502SHong Zhang } 3439a9e8502SHong Zhang 3449a9e8502SHong Zhang static PetscErrorCode MatMatMultSymbolic_Elemental(Mat A,Mat B,PetscReal fill,Mat *C) 3459a9e8502SHong Zhang { 3469a9e8502SHong Zhang PetscErrorCode ierr; 3479a9e8502SHong Zhang Mat Ce; 348ce94432eSBarry Smith MPI_Comm comm; 3499a9e8502SHong Zhang 3509a9e8502SHong Zhang PetscFunctionBegin; 351ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 3529a9e8502SHong Zhang ierr = MatCreate(comm,&Ce);CHKERRQ(ierr); 3539a9e8502SHong Zhang ierr = MatSetSizes(Ce,A->rmap->n,B->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 3549a9e8502SHong Zhang ierr = MatSetType(Ce,MATELEMENTAL);CHKERRQ(ierr); 3559a9e8502SHong Zhang ierr = MatSetUp(Ce);CHKERRQ(ierr); 3569a9e8502SHong Zhang *C = Ce; 3579a9e8502SHong Zhang PetscFunctionReturn(0); 3589a9e8502SHong Zhang } 3599a9e8502SHong Zhang 3609a9e8502SHong Zhang static PetscErrorCode MatMatMult_Elemental(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3619a9e8502SHong Zhang { 3629a9e8502SHong Zhang PetscErrorCode ierr; 3639a9e8502SHong Zhang 3649a9e8502SHong Zhang PetscFunctionBegin; 3659a9e8502SHong Zhang if (scall == MAT_INITIAL_MATRIX){ 3663ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3679a9e8502SHong Zhang ierr = MatMatMultSymbolic_Elemental(A,B,1.0,C);CHKERRQ(ierr); 3683ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3699a9e8502SHong Zhang } 3703ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3719a9e8502SHong Zhang ierr = MatMatMultNumeric_Elemental(A,B,*C);CHKERRQ(ierr); 3723ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 373c1d1b975SXuan Zhou PetscFunctionReturn(0); 374c1d1b975SXuan Zhou } 375c1d1b975SXuan Zhou 376df311e6cSXuan Zhou static PetscErrorCode MatMatTransposeMultNumeric_Elemental(Mat A,Mat B,Mat C) 377df311e6cSXuan Zhou { 378df311e6cSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 379df311e6cSXuan Zhou Mat_Elemental *b = (Mat_Elemental*)B->data; 380df311e6cSXuan Zhou Mat_Elemental *c = (Mat_Elemental*)C->data; 381e6dea9dbSXuan Zhou PetscElemScalar one = 1,zero = 0; 382df311e6cSXuan Zhou 383df311e6cSXuan Zhou PetscFunctionBegin; 384df311e6cSXuan Zhou { /* Scoping so that constructor is called before pointer is returned */ 385e8146892SSatish Balay El::Gemm(El::NORMAL,El::TRANSPOSE,one,*a->emat,*b->emat,zero,*c->emat); 386df311e6cSXuan Zhou } 387df311e6cSXuan Zhou C->assembled = PETSC_TRUE; 388df311e6cSXuan Zhou PetscFunctionReturn(0); 389df311e6cSXuan Zhou } 390df311e6cSXuan Zhou 391df311e6cSXuan Zhou static PetscErrorCode MatMatTransposeMultSymbolic_Elemental(Mat A,Mat B,PetscReal fill,Mat *C) 392df311e6cSXuan Zhou { 393df311e6cSXuan Zhou PetscErrorCode ierr; 394df311e6cSXuan Zhou Mat Ce; 395ce94432eSBarry Smith MPI_Comm comm; 396df311e6cSXuan Zhou 397df311e6cSXuan Zhou PetscFunctionBegin; 398ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 399df311e6cSXuan Zhou ierr = MatCreate(comm,&Ce);CHKERRQ(ierr); 400df311e6cSXuan Zhou ierr = MatSetSizes(Ce,A->rmap->n,B->rmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 401df311e6cSXuan Zhou ierr = MatSetType(Ce,MATELEMENTAL);CHKERRQ(ierr); 402df311e6cSXuan Zhou ierr = MatSetUp(Ce);CHKERRQ(ierr); 403df311e6cSXuan Zhou *C = Ce; 404df311e6cSXuan Zhou PetscFunctionReturn(0); 405df311e6cSXuan Zhou } 406df311e6cSXuan Zhou 407df311e6cSXuan Zhou static PetscErrorCode MatMatTransposeMult_Elemental(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 408df311e6cSXuan Zhou { 409df311e6cSXuan Zhou PetscErrorCode ierr; 410df311e6cSXuan Zhou 411df311e6cSXuan Zhou PetscFunctionBegin; 412df311e6cSXuan Zhou if (scall == MAT_INITIAL_MATRIX){ 413df311e6cSXuan Zhou ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 414df311e6cSXuan Zhou ierr = MatMatMultSymbolic_Elemental(A,B,1.0,C);CHKERRQ(ierr); 415df311e6cSXuan Zhou ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 416df311e6cSXuan Zhou } 417df311e6cSXuan Zhou ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 418df311e6cSXuan Zhou ierr = MatMatTransposeMultNumeric_Elemental(A,B,*C);CHKERRQ(ierr); 419df311e6cSXuan Zhou ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 420df311e6cSXuan Zhou PetscFunctionReturn(0); 421df311e6cSXuan Zhou } 422df311e6cSXuan Zhou 423a9d89745SXuan Zhou static PetscErrorCode MatGetDiagonal_Elemental(Mat A,Vec D) 42461119200SXuan Zhou { 425a9d89745SXuan Zhou PetscInt i,nrows,ncols,nD,rrank,ridx,crank,cidx; 426a9d89745SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 42761119200SXuan Zhou PetscErrorCode ierr; 428a9d89745SXuan Zhou PetscElemScalar v; 429ce94432eSBarry Smith MPI_Comm comm; 43061119200SXuan Zhou 43161119200SXuan Zhou PetscFunctionBegin; 432ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 433a9d89745SXuan Zhou ierr = MatGetSize(A,&nrows,&ncols);CHKERRQ(ierr); 434a9d89745SXuan Zhou nD = nrows>ncols ? ncols : nrows; 435a9d89745SXuan Zhou for (i=0; i<nD; i++) { 436a9d89745SXuan Zhou PetscInt erow,ecol; 437a9d89745SXuan Zhou P2RO(A,0,i,&rrank,&ridx); 438a9d89745SXuan Zhou RO2E(A,0,rrank,ridx,&erow); 439a9d89745SXuan Zhou if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect row translation"); 440a9d89745SXuan Zhou P2RO(A,1,i,&crank,&cidx); 441a9d89745SXuan Zhou RO2E(A,1,crank,cidx,&ecol); 442a9d89745SXuan Zhou if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect col translation"); 443a9d89745SXuan Zhou v = a->emat->Get(erow,ecol); 4447c8b904fSSatish Balay ierr = VecSetValues(D,1,&i,(PetscScalar*)&v,INSERT_VALUES);CHKERRQ(ierr); 445ade3cc5eSXuan Zhou } 446a9d89745SXuan Zhou ierr = VecAssemblyBegin(D);CHKERRQ(ierr); 447a9d89745SXuan Zhou ierr = VecAssemblyEnd(D);CHKERRQ(ierr); 44861119200SXuan Zhou PetscFunctionReturn(0); 44961119200SXuan Zhou } 45061119200SXuan Zhou 451ade3cc5eSXuan Zhou static PetscErrorCode MatDiagonalScale_Elemental(Mat X,Vec L,Vec R) 452ade3cc5eSXuan Zhou { 453ade3cc5eSXuan Zhou Mat_Elemental *x = (Mat_Elemental*)X->data; 454ade3cc5eSXuan Zhou const PetscElemScalar *d; 455ade3cc5eSXuan Zhou PetscErrorCode ierr; 456ade3cc5eSXuan Zhou 457ade3cc5eSXuan Zhou PetscFunctionBegin; 4589065cd98SJed Brown if (R) { 459ade3cc5eSXuan Zhou ierr = VecGetArrayRead(R,(const PetscScalar **)&d);CHKERRQ(ierr); 460e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> de; 4610c18141cSBarry Smith de.LockedAttach(X->cmap->N,1,*x->grid,0,0,d,X->cmap->n); 462e8146892SSatish Balay El::DiagonalScale(El::RIGHT,El::NORMAL,de,*x->emat); 463ade3cc5eSXuan Zhou ierr = VecRestoreArrayRead(R,(const PetscScalar **)&d);CHKERRQ(ierr); 4649065cd98SJed Brown } 4659065cd98SJed Brown if (L) { 466ade3cc5eSXuan Zhou ierr = VecGetArrayRead(L,(const PetscScalar **)&d);CHKERRQ(ierr); 467e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> de; 4680c18141cSBarry Smith de.LockedAttach(X->rmap->N,1,*x->grid,0,0,d,X->rmap->n); 469e8146892SSatish Balay El::DiagonalScale(El::LEFT,El::NORMAL,de,*x->emat); 470ade3cc5eSXuan Zhou ierr = VecRestoreArrayRead(L,(const PetscScalar **)&d);CHKERRQ(ierr); 471ade3cc5eSXuan Zhou } 472ade3cc5eSXuan Zhou PetscFunctionReturn(0); 473ade3cc5eSXuan Zhou } 474ade3cc5eSXuan Zhou 47534fa46e1SFrancesco Ballarin static PetscErrorCode MatMissingDiagonal_Elemental(Mat A,PetscBool *missing,PetscInt *d) 47634fa46e1SFrancesco Ballarin { 47734fa46e1SFrancesco Ballarin PetscFunctionBegin; 47834fa46e1SFrancesco Ballarin *missing = PETSC_FALSE; 47934fa46e1SFrancesco Ballarin PetscFunctionReturn(0); 48034fa46e1SFrancesco Ballarin } 48134fa46e1SFrancesco Ballarin 482e6dea9dbSXuan Zhou static PetscErrorCode MatScale_Elemental(Mat X,PetscScalar a) 48365b78793SXuan Zhou { 48465b78793SXuan Zhou Mat_Elemental *x = (Mat_Elemental*)X->data; 48565b78793SXuan Zhou 48665b78793SXuan Zhou PetscFunctionBegin; 487e8146892SSatish Balay El::Scale((PetscElemScalar)a,*x->emat); 48865b78793SXuan Zhou PetscFunctionReturn(0); 48965b78793SXuan Zhou } 49065b78793SXuan Zhou 491f82baa17SHong Zhang /* 492f82baa17SHong Zhang MatAXPY - Computes Y = a*X + Y. 493f82baa17SHong Zhang */ 494e6dea9dbSXuan Zhou static PetscErrorCode MatAXPY_Elemental(Mat Y,PetscScalar a,Mat X,MatStructure str) 495e09a3074SHong Zhang { 496e09a3074SHong Zhang Mat_Elemental *x = (Mat_Elemental*)X->data; 497e09a3074SHong Zhang Mat_Elemental *y = (Mat_Elemental*)Y->data; 49868446cf8SJed Brown PetscErrorCode ierr; 499e09a3074SHong Zhang 500e09a3074SHong Zhang PetscFunctionBegin; 501e8146892SSatish Balay El::Axpy((PetscElemScalar)a,*x->emat,*y->emat); 50221f6c9c4SJed Brown ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 503e09a3074SHong Zhang PetscFunctionReturn(0); 504e09a3074SHong Zhang } 505e09a3074SHong Zhang 506d6223691SXuan Zhou static PetscErrorCode MatCopy_Elemental(Mat A,Mat B,MatStructure str) 507d6223691SXuan Zhou { 508d6223691SXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 509d6223691SXuan Zhou Mat_Elemental *b=(Mat_Elemental*)B->data; 510a4ee3bb6SSatish Balay PetscErrorCode ierr; 511d6223691SXuan Zhou 512d6223691SXuan Zhou PetscFunctionBegin; 513e8146892SSatish Balay El::Copy(*a->emat,*b->emat); 514cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 515d6223691SXuan Zhou PetscFunctionReturn(0); 516d6223691SXuan Zhou } 517d6223691SXuan Zhou 518df311e6cSXuan Zhou static PetscErrorCode MatDuplicate_Elemental(Mat A,MatDuplicateOption op,Mat *B) 519df311e6cSXuan Zhou { 520df311e6cSXuan Zhou Mat Be; 521ce94432eSBarry Smith MPI_Comm comm; 522df311e6cSXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 523df311e6cSXuan Zhou PetscErrorCode ierr; 524df311e6cSXuan Zhou 525df311e6cSXuan Zhou PetscFunctionBegin; 526ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 527df311e6cSXuan Zhou ierr = MatCreate(comm,&Be);CHKERRQ(ierr); 528df311e6cSXuan Zhou ierr = MatSetSizes(Be,A->rmap->n,A->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 529df311e6cSXuan Zhou ierr = MatSetType(Be,MATELEMENTAL);CHKERRQ(ierr); 530df311e6cSXuan Zhou ierr = MatSetUp(Be);CHKERRQ(ierr); 531df311e6cSXuan Zhou *B = Be; 532df311e6cSXuan Zhou if (op == MAT_COPY_VALUES) { 533df311e6cSXuan Zhou Mat_Elemental *b=(Mat_Elemental*)Be->data; 534e8146892SSatish Balay El::Copy(*a->emat,*b->emat); 535df311e6cSXuan Zhou } 536df311e6cSXuan Zhou Be->assembled = PETSC_TRUE; 537df311e6cSXuan Zhou PetscFunctionReturn(0); 538df311e6cSXuan Zhou } 539df311e6cSXuan Zhou 540d6223691SXuan Zhou static PetscErrorCode MatTranspose_Elemental(Mat A,MatReuse reuse,Mat *B) 541d6223691SXuan Zhou { 542ec8cb81fSBarry Smith Mat Be = *B; 5435262d616SXuan Zhou PetscErrorCode ierr; 544ce94432eSBarry Smith MPI_Comm comm; 5454fe7bbcaSHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data, *b; 546d6223691SXuan Zhou 547d6223691SXuan Zhou PetscFunctionBegin; 548ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 5495cb544a0SHong Zhang /* Only out-of-place supported */ 5502847e3fdSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) SETERRQ(comm,PETSC_ERR_SUP,"Only out-of-place supported"); 5515262d616SXuan Zhou if (reuse == MAT_INITIAL_MATRIX) { 5525262d616SXuan Zhou ierr = MatCreate(comm,&Be);CHKERRQ(ierr); 5535262d616SXuan Zhou ierr = MatSetSizes(Be,A->cmap->n,A->rmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 5545262d616SXuan Zhou ierr = MatSetType(Be,MATELEMENTAL);CHKERRQ(ierr); 5555262d616SXuan Zhou ierr = MatSetUp(Be);CHKERRQ(ierr); 5565262d616SXuan Zhou *B = Be; 5575262d616SXuan Zhou } 5584fe7bbcaSHong Zhang b = (Mat_Elemental*)Be->data; 559e8146892SSatish Balay El::Transpose(*a->emat,*b->emat); 5605262d616SXuan Zhou Be->assembled = PETSC_TRUE; 561d6223691SXuan Zhou PetscFunctionReturn(0); 562d6223691SXuan Zhou } 563d6223691SXuan Zhou 564dfcb0403SXuan Zhou static PetscErrorCode MatConjugate_Elemental(Mat A) 565dfcb0403SXuan Zhou { 566dfcb0403SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 567dfcb0403SXuan Zhou 568dfcb0403SXuan Zhou PetscFunctionBegin; 569e8146892SSatish Balay El::Conjugate(*a->emat); 570dfcb0403SXuan Zhou PetscFunctionReturn(0); 571dfcb0403SXuan Zhou } 572dfcb0403SXuan Zhou 5734a29722dSXuan Zhou static PetscErrorCode MatHermitianTranspose_Elemental(Mat A,MatReuse reuse,Mat *B) 5744a29722dSXuan Zhou { 575ec8cb81fSBarry Smith Mat Be = *B; 5764a29722dSXuan Zhou PetscErrorCode ierr; 577ce94432eSBarry Smith MPI_Comm comm; 5784a29722dSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data, *b; 5794a29722dSXuan Zhou 5804a29722dSXuan Zhou PetscFunctionBegin; 581ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 5825cb544a0SHong Zhang /* Only out-of-place supported */ 5834a29722dSXuan Zhou if (reuse == MAT_INITIAL_MATRIX){ 5844a29722dSXuan Zhou ierr = MatCreate(comm,&Be);CHKERRQ(ierr); 5854a29722dSXuan Zhou ierr = MatSetSizes(Be,A->cmap->n,A->rmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 5864a29722dSXuan Zhou ierr = MatSetType(Be,MATELEMENTAL);CHKERRQ(ierr); 5874a29722dSXuan Zhou ierr = MatSetUp(Be);CHKERRQ(ierr); 5884a29722dSXuan Zhou *B = Be; 5894a29722dSXuan Zhou } 5904a29722dSXuan Zhou b = (Mat_Elemental*)Be->data; 591e8146892SSatish Balay El::Adjoint(*a->emat,*b->emat); 5924a29722dSXuan Zhou Be->assembled = PETSC_TRUE; 5934a29722dSXuan Zhou PetscFunctionReturn(0); 5944a29722dSXuan Zhou } 5954a29722dSXuan Zhou 5961f881ff8SXuan Zhou static PetscErrorCode MatSolve_Elemental(Mat A,Vec B,Vec X) 5971f881ff8SXuan Zhou { 5981f881ff8SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 5991f881ff8SXuan Zhou PetscErrorCode ierr; 600df311e6cSXuan Zhou PetscElemScalar *x; 601ea394475SSatish Balay PetscInt pivoting = a->pivoting; 6021f881ff8SXuan Zhou 6031f881ff8SXuan Zhou PetscFunctionBegin; 60445cf121fSXuan Zhou ierr = VecCopy(B,X);CHKERRQ(ierr); 605e6dea9dbSXuan Zhou ierr = VecGetArray(X,(PetscScalar **)&x);CHKERRQ(ierr); 606ea394475SSatish Balay 607e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::VC,El::STAR> xe; 6080c18141cSBarry Smith xe.Attach(A->rmap->N,1,*a->grid,0,0,x,A->rmap->n); 609e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::MC,El::MR> xer(xe); 610fc54b460SXuan Zhou switch (A->factortype) { 611fc54b460SXuan Zhou case MAT_FACTOR_LU: 612ea394475SSatish Balay if (pivoting == 0) { 613e8146892SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,xer); 614ea394475SSatish Balay } else if (pivoting == 1) { 615ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,xer); 616ea394475SSatish Balay } else { /* pivoting == 2 */ 617ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,*a->Q,xer); 6181f881ff8SXuan Zhou } 619fc54b460SXuan Zhou break; 620fc54b460SXuan Zhou case MAT_FACTOR_CHOLESKY: 621e8146892SSatish Balay El::cholesky::SolveAfter(El::UPPER,El::NORMAL,*a->emat,xer); 622fc54b460SXuan Zhou break; 623fc54b460SXuan Zhou default: 6244fe7bbcaSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unfactored Matrix or Unsupported MatFactorType"); 625fc54b460SXuan Zhou break; 6261f881ff8SXuan Zhou } 627ea394475SSatish Balay El::Copy(xer,xe); 628ea394475SSatish Balay 629e6dea9dbSXuan Zhou ierr = VecRestoreArray(X,(PetscScalar **)&x);CHKERRQ(ierr); 6301f881ff8SXuan Zhou PetscFunctionReturn(0); 6311f881ff8SXuan Zhou } 6321f881ff8SXuan Zhou 633df311e6cSXuan Zhou static PetscErrorCode MatSolveAdd_Elemental(Mat A,Vec B,Vec Y,Vec X) 634df311e6cSXuan Zhou { 635df311e6cSXuan Zhou PetscErrorCode ierr; 636df311e6cSXuan Zhou 637df311e6cSXuan Zhou PetscFunctionBegin; 638df311e6cSXuan Zhou ierr = MatSolve_Elemental(A,B,X);CHKERRQ(ierr); 6393d7f40dbSXuan Zhou ierr = VecAXPY(X,1,Y);CHKERRQ(ierr); 640df311e6cSXuan Zhou PetscFunctionReturn(0); 641df311e6cSXuan Zhou } 642df311e6cSXuan Zhou 643ae844d54SHong Zhang static PetscErrorCode MatMatSolve_Elemental(Mat A,Mat B,Mat X) 644ae844d54SHong Zhang { 6451f0e42cfSHong Zhang Mat_Elemental *a=(Mat_Elemental*)A->data; 646d6223691SXuan Zhou Mat_Elemental *b=(Mat_Elemental*)B->data; 6471f0e42cfSHong Zhang Mat_Elemental *x=(Mat_Elemental*)X->data; 648ea394475SSatish Balay PetscInt pivoting = a->pivoting; 6491f0e42cfSHong Zhang 650ae844d54SHong Zhang PetscFunctionBegin; 651e8146892SSatish Balay El::Copy(*b->emat,*x->emat); 652fc54b460SXuan Zhou switch (A->factortype) { 653fc54b460SXuan Zhou case MAT_FACTOR_LU: 654ea394475SSatish Balay if (pivoting == 0) { 655e8146892SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*x->emat); 656ea394475SSatish Balay } else if (pivoting == 1) { 657ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,*x->emat); 658ea394475SSatish Balay } else { 659ea394475SSatish Balay El::lu::SolveAfter(El::NORMAL,*a->emat,*a->P,*a->Q,*x->emat); 660d6223691SXuan Zhou } 661fc54b460SXuan Zhou break; 662fc54b460SXuan Zhou case MAT_FACTOR_CHOLESKY: 663e8146892SSatish Balay El::cholesky::SolveAfter(El::UPPER,El::NORMAL,*a->emat,*x->emat); 664fc54b460SXuan Zhou break; 665fc54b460SXuan Zhou default: 6664fe7bbcaSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unfactored Matrix or Unsupported MatFactorType"); 667fc54b460SXuan Zhou break; 668fc54b460SXuan Zhou } 669ae844d54SHong Zhang PetscFunctionReturn(0); 670ae844d54SHong Zhang } 671ae844d54SHong Zhang 672ae844d54SHong Zhang static PetscErrorCode MatLUFactor_Elemental(Mat A,IS row,IS col,const MatFactorInfo *info) 673ae844d54SHong Zhang { 6747c920d81SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 675124af5d2SSatish Balay PetscErrorCode ierr; 676ea394475SSatish Balay PetscInt pivoting = a->pivoting; 6777c920d81SXuan Zhou 678ae844d54SHong Zhang PetscFunctionBegin; 679ea394475SSatish Balay if (pivoting == 0) { 680e8146892SSatish Balay El::LU(*a->emat); 681ea394475SSatish Balay } else if (pivoting == 1) { 682ea394475SSatish Balay El::LU(*a->emat,*a->P); 683ea394475SSatish Balay } else { 684ea394475SSatish Balay El::LU(*a->emat,*a->P,*a->Q); 685d6223691SXuan Zhou } 6861293973dSHong Zhang A->factortype = MAT_FACTOR_LU; 687834d3fecSHong Zhang A->assembled = PETSC_TRUE; 688f6224b95SHong Zhang 689f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 690f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERELEMENTAL,&A->solvertype);CHKERRQ(ierr); 691ae844d54SHong Zhang PetscFunctionReturn(0); 692ae844d54SHong Zhang } 693ae844d54SHong Zhang 694d7c3f9d8SHong Zhang static PetscErrorCode MatLUFactorNumeric_Elemental(Mat F,Mat A,const MatFactorInfo *info) 695d7c3f9d8SHong Zhang { 696d7c3f9d8SHong Zhang PetscErrorCode ierr; 697d7c3f9d8SHong Zhang 698d7c3f9d8SHong Zhang PetscFunctionBegin; 699d7c3f9d8SHong Zhang ierr = MatCopy(A,F,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 700d7c3f9d8SHong Zhang ierr = MatLUFactor_Elemental(F,0,0,info);CHKERRQ(ierr); 701d7c3f9d8SHong Zhang PetscFunctionReturn(0); 702d7c3f9d8SHong Zhang } 703d7c3f9d8SHong Zhang 704d7c3f9d8SHong Zhang static PetscErrorCode MatLUFactorSymbolic_Elemental(Mat F,Mat A,IS r,IS c,const MatFactorInfo *info) 705d7c3f9d8SHong Zhang { 706d7c3f9d8SHong Zhang PetscFunctionBegin; 707d7c3f9d8SHong Zhang /* F is create and allocated by MatGetFactor_elemental_petsc(), skip this routine. */ 708d7c3f9d8SHong Zhang PetscFunctionReturn(0); 709d7c3f9d8SHong Zhang } 710d7c3f9d8SHong Zhang 71145cf121fSXuan Zhou static PetscErrorCode MatCholeskyFactor_Elemental(Mat A,IS perm,const MatFactorInfo *info) 71245cf121fSXuan Zhou { 71345cf121fSXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 714e8146892SSatish Balay El::DistMatrix<PetscElemScalar,El::MC,El::STAR> d; 715124af5d2SSatish Balay PetscErrorCode ierr; 71645cf121fSXuan Zhou 71745cf121fSXuan Zhou PetscFunctionBegin; 718e8146892SSatish Balay El::Cholesky(El::UPPER,*a->emat); 719fc54b460SXuan Zhou A->factortype = MAT_FACTOR_CHOLESKY; 720834d3fecSHong Zhang A->assembled = PETSC_TRUE; 721f6224b95SHong Zhang 722f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 723f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERELEMENTAL,&A->solvertype);CHKERRQ(ierr); 72445cf121fSXuan Zhou PetscFunctionReturn(0); 72545cf121fSXuan Zhou } 72645cf121fSXuan Zhou 72779673f7bSHong Zhang static PetscErrorCode MatCholeskyFactorNumeric_Elemental(Mat F,Mat A,const MatFactorInfo *info) 72879673f7bSHong Zhang { 729cb76c1d8SXuan Zhou PetscErrorCode ierr; 730cb76c1d8SXuan Zhou 731cb76c1d8SXuan Zhou PetscFunctionBegin; 732cb76c1d8SXuan Zhou ierr = MatCopy(A,F,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 733cb76c1d8SXuan Zhou ierr = MatCholeskyFactor_Elemental(F,0,info);CHKERRQ(ierr); 734cb76c1d8SXuan Zhou PetscFunctionReturn(0); 73579673f7bSHong Zhang } 736cb76c1d8SXuan Zhou 73779673f7bSHong Zhang static PetscErrorCode MatCholeskyFactorSymbolic_Elemental(Mat F,Mat A,IS perm,const MatFactorInfo *info) 73879673f7bSHong Zhang { 73979673f7bSHong Zhang PetscFunctionBegin; 74079673f7bSHong Zhang /* F is create and allocated by MatGetFactor_elemental_petsc(), skip this routine. */ 74179673f7bSHong Zhang PetscFunctionReturn(0); 74279673f7bSHong Zhang } 74379673f7bSHong Zhang 744ea799195SBarry Smith PetscErrorCode MatFactorGetSolverType_elemental_elemental(Mat A,MatSolverType *type) 74515767789SHong Zhang { 74615767789SHong Zhang PetscFunctionBegin; 74715767789SHong Zhang *type = MATSOLVERELEMENTAL; 74815767789SHong Zhang PetscFunctionReturn(0); 74915767789SHong Zhang } 75015767789SHong Zhang 75115767789SHong Zhang static PetscErrorCode MatGetFactor_elemental_elemental(Mat A,MatFactorType ftype,Mat *F) 7521293973dSHong Zhang { 7531293973dSHong Zhang Mat B; 7541293973dSHong Zhang PetscErrorCode ierr; 7551293973dSHong Zhang 7561293973dSHong Zhang PetscFunctionBegin; 7571293973dSHong Zhang /* Create the factorization matrix */ 758ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 7591293973dSHong Zhang ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 7601293973dSHong Zhang ierr = MatSetType(B,MATELEMENTAL);CHKERRQ(ierr); 7611293973dSHong Zhang ierr = MatSetUp(B);CHKERRQ(ierr); 7621293973dSHong Zhang B->factortype = ftype; 76300c67f3bSHong Zhang ierr = PetscFree(B->solvertype);CHKERRQ(ierr); 76400c67f3bSHong Zhang ierr = PetscStrallocpy(MATSOLVERELEMENTAL,&B->solvertype);CHKERRQ(ierr); 76500c67f3bSHong Zhang 7663ca39a21SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatFactorGetSolverType_C",MatFactorGetSolverType_elemental_elemental);CHKERRQ(ierr); 7671293973dSHong Zhang *F = B; 7681293973dSHong Zhang PetscFunctionReturn(0); 7691293973dSHong Zhang } 7701293973dSHong Zhang 7713ca39a21SBarry Smith PETSC_EXTERN PetscErrorCode MatSolverTypeRegister_Elemental(void) 77242c9c57cSBarry Smith { 77318713533SBarry Smith PetscErrorCode ierr; 77418713533SBarry Smith 77542c9c57cSBarry Smith PetscFunctionBegin; 7763ca39a21SBarry Smith ierr = MatSolverTypeRegister(MATSOLVERELEMENTAL,MATELEMENTAL, MAT_FACTOR_LU,MatGetFactor_elemental_elemental);CHKERRQ(ierr); 7773ca39a21SBarry Smith ierr = MatSolverTypeRegister(MATSOLVERELEMENTAL,MATELEMENTAL, MAT_FACTOR_CHOLESKY,MatGetFactor_elemental_elemental);CHKERRQ(ierr); 77842c9c57cSBarry Smith PetscFunctionReturn(0); 77942c9c57cSBarry Smith } 78042c9c57cSBarry Smith 7811f881ff8SXuan Zhou static PetscErrorCode MatNorm_Elemental(Mat A,NormType type,PetscReal *nrm) 7821f881ff8SXuan Zhou { 7831f881ff8SXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 7841f881ff8SXuan Zhou 7851f881ff8SXuan Zhou PetscFunctionBegin; 7861f881ff8SXuan Zhou switch (type){ 7871f881ff8SXuan Zhou case NORM_1: 788e8146892SSatish Balay *nrm = El::OneNorm(*a->emat); 7891f881ff8SXuan Zhou break; 7901f881ff8SXuan Zhou case NORM_FROBENIUS: 791e8146892SSatish Balay *nrm = El::FrobeniusNorm(*a->emat); 7921f881ff8SXuan Zhou break; 7931f881ff8SXuan Zhou case NORM_INFINITY: 794e8146892SSatish Balay *nrm = El::InfinityNorm(*a->emat); 7951f881ff8SXuan Zhou break; 7961f881ff8SXuan Zhou default: 7971f881ff8SXuan Zhou printf("Error: unsupported norm type!\n"); 7981f881ff8SXuan Zhou } 7991f881ff8SXuan Zhou PetscFunctionReturn(0); 8001f881ff8SXuan Zhou } 8011f881ff8SXuan Zhou 8025262d616SXuan Zhou static PetscErrorCode MatZeroEntries_Elemental(Mat A) 8035262d616SXuan Zhou { 8045262d616SXuan Zhou Mat_Elemental *a=(Mat_Elemental*)A->data; 8055262d616SXuan Zhou 8065262d616SXuan Zhou PetscFunctionBegin; 807e8146892SSatish Balay El::Zero(*a->emat); 8085262d616SXuan Zhou PetscFunctionReturn(0); 8095262d616SXuan Zhou } 8105262d616SXuan Zhou 811db31f6deSJed Brown static PetscErrorCode MatGetOwnershipIS_Elemental(Mat A,IS *rows,IS *cols) 812db31f6deSJed Brown { 813db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 814db31f6deSJed Brown PetscErrorCode ierr; 815db31f6deSJed Brown PetscInt i,m,shift,stride,*idx; 816db31f6deSJed Brown 817db31f6deSJed Brown PetscFunctionBegin; 818db31f6deSJed Brown if (rows) { 819db31f6deSJed Brown m = a->emat->LocalHeight(); 820db31f6deSJed Brown shift = a->emat->ColShift(); 821db31f6deSJed Brown stride = a->emat->ColStride(); 822785e854fSJed Brown ierr = PetscMalloc1(m,&idx);CHKERRQ(ierr); 823db31f6deSJed Brown for (i=0; i<m; i++) { 824db31f6deSJed Brown PetscInt rank,offset; 825db31f6deSJed Brown E2RO(A,0,shift+i*stride,&rank,&offset); 826db31f6deSJed Brown RO2P(A,0,rank,offset,&idx[i]); 827db31f6deSJed Brown } 828db31f6deSJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,m,idx,PETSC_OWN_POINTER,rows);CHKERRQ(ierr); 829db31f6deSJed Brown } 830db31f6deSJed Brown if (cols) { 831db31f6deSJed Brown m = a->emat->LocalWidth(); 832db31f6deSJed Brown shift = a->emat->RowShift(); 833db31f6deSJed Brown stride = a->emat->RowStride(); 834785e854fSJed Brown ierr = PetscMalloc1(m,&idx);CHKERRQ(ierr); 835db31f6deSJed Brown for (i=0; i<m; i++) { 836db31f6deSJed Brown PetscInt rank,offset; 837db31f6deSJed Brown E2RO(A,1,shift+i*stride,&rank,&offset); 838db31f6deSJed Brown RO2P(A,1,rank,offset,&idx[i]); 839db31f6deSJed Brown } 840db31f6deSJed Brown ierr = ISCreateGeneral(PETSC_COMM_SELF,m,idx,PETSC_OWN_POINTER,cols);CHKERRQ(ierr); 841db31f6deSJed Brown } 842db31f6deSJed Brown PetscFunctionReturn(0); 843db31f6deSJed Brown } 844db31f6deSJed Brown 84519fd82e9SBarry Smith static PetscErrorCode MatConvert_Elemental_Dense(Mat A,MatType newtype,MatReuse reuse,Mat *B) 846af295397SXuan Zhou { 8472ef0cf24SXuan Zhou Mat Bmpi; 848af295397SXuan Zhou Mat_Elemental *a = (Mat_Elemental*)A->data; 849ce94432eSBarry Smith MPI_Comm comm; 8502ef0cf24SXuan Zhou PetscErrorCode ierr; 851fa9e26c8SHong Zhang IS isrows,iscols; 852fa9e26c8SHong Zhang PetscInt rrank,ridx,crank,cidx,nrows,ncols,i,j,erow,ecol,elrow,elcol; 853fa9e26c8SHong Zhang const PetscInt *rows,*cols; 854df311e6cSXuan Zhou PetscElemScalar v; 855fa9e26c8SHong Zhang const El::Grid &grid = a->emat->Grid(); 856af295397SXuan Zhou 857af295397SXuan Zhou PetscFunctionBegin; 858ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 859a000e53bSHong Zhang 860de0a22f0SHong Zhang if (reuse == MAT_REUSE_MATRIX) { 861de0a22f0SHong Zhang Bmpi = *B; 862de0a22f0SHong Zhang } else { 863af295397SXuan Zhou ierr = MatCreate(comm,&Bmpi);CHKERRQ(ierr); 864af295397SXuan Zhou ierr = MatSetSizes(Bmpi,A->rmap->n,A->cmap->n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 8652ef0cf24SXuan Zhou ierr = MatSetType(Bmpi,MATDENSE);CHKERRQ(ierr); 866af295397SXuan Zhou ierr = MatSetUp(Bmpi);CHKERRQ(ierr); 867de0a22f0SHong Zhang } 868fa9e26c8SHong Zhang 869fa9e26c8SHong Zhang /* Get local entries of A */ 870fa9e26c8SHong Zhang ierr = MatGetOwnershipIS(A,&isrows,&iscols);CHKERRQ(ierr); 871fa9e26c8SHong Zhang ierr = ISGetLocalSize(isrows,&nrows);CHKERRQ(ierr); 872fa9e26c8SHong Zhang ierr = ISGetIndices(isrows,&rows);CHKERRQ(ierr); 873fa9e26c8SHong Zhang ierr = ISGetLocalSize(iscols,&ncols);CHKERRQ(ierr); 874fa9e26c8SHong Zhang ierr = ISGetIndices(iscols,&cols);CHKERRQ(ierr); 875fa9e26c8SHong Zhang 87657299f2fSHong Zhang if (a->roworiented) { 8772ef0cf24SXuan Zhou for (i=0; i<nrows; i++) { 878fa9e26c8SHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); /* convert indices between PETSc <-> (Rank,Offset) <-> Elemental */ 8792ef0cf24SXuan Zhou RO2E(A,0,rrank,ridx,&erow); 8802ef0cf24SXuan Zhou if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect row translation"); 8812ef0cf24SXuan Zhou for (j=0; j<ncols; j++) { 882fa9e26c8SHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 8832ef0cf24SXuan Zhou RO2E(A,1,crank,cidx,&ecol); 8842ef0cf24SXuan Zhou if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect col translation"); 885fa9e26c8SHong Zhang 886fa9e26c8SHong Zhang elrow = erow / grid.MCSize(); /* Elemental local row index */ 887fa9e26c8SHong Zhang elcol = ecol / grid.MRSize(); /* Elemental local column index */ 888fa9e26c8SHong Zhang v = a->emat->GetLocal(elrow,elcol); 889fa9e26c8SHong Zhang ierr = MatSetValues(Bmpi,1,&rows[i],1,&cols[j],(PetscScalar *)&v,INSERT_VALUES);CHKERRQ(ierr); 8902ef0cf24SXuan Zhou } 8912ef0cf24SXuan Zhou } 89257299f2fSHong Zhang } else { /* column-oriented */ 89357299f2fSHong Zhang for (j=0; j<ncols; j++) { 89457299f2fSHong Zhang P2RO(A,1,cols[j],&crank,&cidx); 89557299f2fSHong Zhang RO2E(A,1,crank,cidx,&ecol); 89657299f2fSHong Zhang if (crank < 0 || cidx < 0 || ecol < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect col translation"); 89757299f2fSHong Zhang for (i=0; i<nrows; i++) { 89857299f2fSHong Zhang P2RO(A,0,rows[i],&rrank,&ridx); /* convert indices between PETSc <-> (Rank,Offset) <-> Elemental */ 89957299f2fSHong Zhang RO2E(A,0,rrank,ridx,&erow); 90057299f2fSHong Zhang if (rrank < 0 || ridx < 0 || erow < 0) SETERRQ(comm,PETSC_ERR_PLIB,"Incorrect row translation"); 90157299f2fSHong Zhang 90257299f2fSHong Zhang elrow = erow / grid.MCSize(); /* Elemental local row index */ 90357299f2fSHong Zhang elcol = ecol / grid.MRSize(); /* Elemental local column index */ 90457299f2fSHong Zhang v = a->emat->GetLocal(elrow,elcol); 90557299f2fSHong Zhang ierr = MatSetValues(Bmpi,1,&rows[i],1,&cols[j],(PetscScalar *)&v,INSERT_VALUES);CHKERRQ(ierr); 90657299f2fSHong Zhang } 90757299f2fSHong Zhang } 90857299f2fSHong Zhang } 909af295397SXuan Zhou ierr = MatAssemblyBegin(Bmpi,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 910af295397SXuan Zhou ierr = MatAssemblyEnd(Bmpi,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 911511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 91228be2f97SBarry Smith ierr = MatHeaderReplace(A,&Bmpi);CHKERRQ(ierr); 913c4ad791aSXuan Zhou } else { 914c4ad791aSXuan Zhou *B = Bmpi; 915c4ad791aSXuan Zhou } 916fa9e26c8SHong Zhang ierr = ISDestroy(&isrows);CHKERRQ(ierr); 917fa9e26c8SHong Zhang ierr = ISDestroy(&iscols);CHKERRQ(ierr); 918af295397SXuan Zhou PetscFunctionReturn(0); 919af295397SXuan Zhou } 920af295397SXuan Zhou 921cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 922af8000cdSHong Zhang { 923af8000cdSHong Zhang Mat mat_elemental; 924af8000cdSHong Zhang PetscErrorCode ierr; 925af8000cdSHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,row,ncols; 926af8000cdSHong Zhang const PetscInt *cols; 927af8000cdSHong Zhang const PetscScalar *vals; 928af8000cdSHong Zhang 929af8000cdSHong Zhang PetscFunctionBegin; 930*bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 931*bdeae278SStefano Zampini mat_elemental = *newmat; 932*bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 933*bdeae278SStefano Zampini } else { 934af8000cdSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 935af8000cdSHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 936af8000cdSHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 937af8000cdSHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 938*bdeae278SStefano Zampini } 939af8000cdSHong Zhang for (row=0; row<M; row++) { 940af8000cdSHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 941*bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 942af8000cdSHong Zhang ierr = MatSetValues(mat_elemental,1,&row,ncols,cols,vals,ADD_VALUES);CHKERRQ(ierr); 943af8000cdSHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 944af8000cdSHong Zhang } 945af8000cdSHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 946af8000cdSHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 947af8000cdSHong Zhang 948511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 94928be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 950af8000cdSHong Zhang } else { 951af8000cdSHong Zhang *newmat = mat_elemental; 952af8000cdSHong Zhang } 953af8000cdSHong Zhang PetscFunctionReturn(0); 954af8000cdSHong Zhang } 955af8000cdSHong Zhang 956cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 9575d7652ecSHong Zhang { 9585d7652ecSHong Zhang Mat mat_elemental; 9595d7652ecSHong Zhang PetscErrorCode ierr; 9605d7652ecSHong Zhang PetscInt row,ncols,rstart=A->rmap->rstart,rend=A->rmap->rend,j; 9615d7652ecSHong Zhang const PetscInt *cols; 9625d7652ecSHong Zhang const PetscScalar *vals; 9635d7652ecSHong Zhang 9645d7652ecSHong Zhang PetscFunctionBegin; 965*bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 966*bdeae278SStefano Zampini mat_elemental = *newmat; 967*bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 968*bdeae278SStefano Zampini } else { 9695d7652ecSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 9705d7652ecSHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 9715d7652ecSHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 9725d7652ecSHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 973*bdeae278SStefano Zampini } 9745d7652ecSHong Zhang for (row=rstart; row<rend; row++) { 9755d7652ecSHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 9765d7652ecSHong Zhang for (j=0; j<ncols; j++) { 977*bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 9785d7652ecSHong Zhang ierr = MatSetValues(mat_elemental,1,&row,1,&cols[j],&vals[j],ADD_VALUES);CHKERRQ(ierr); 9795d7652ecSHong Zhang } 9805d7652ecSHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 9815d7652ecSHong Zhang } 9825d7652ecSHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9835d7652ecSHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 9845d7652ecSHong Zhang 985511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 98628be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 9875d7652ecSHong Zhang } else { 9885d7652ecSHong Zhang *newmat = mat_elemental; 9895d7652ecSHong Zhang } 9905d7652ecSHong Zhang PetscFunctionReturn(0); 9915d7652ecSHong Zhang } 9925d7652ecSHong Zhang 993cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqSBAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 9946214f412SHong Zhang { 9956214f412SHong Zhang Mat mat_elemental; 9966214f412SHong Zhang PetscErrorCode ierr; 9976214f412SHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,row,ncols,j; 9986214f412SHong Zhang const PetscInt *cols; 9996214f412SHong Zhang const PetscScalar *vals; 10006214f412SHong Zhang 10016214f412SHong Zhang PetscFunctionBegin; 1002*bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1003*bdeae278SStefano Zampini mat_elemental = *newmat; 1004*bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 1005*bdeae278SStefano Zampini } else { 10066214f412SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 10076214f412SHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 10086214f412SHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 10096214f412SHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 1010*bdeae278SStefano Zampini } 10116214f412SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 10126214f412SHong Zhang for (row=0; row<M; row++) { 10136214f412SHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 1014*bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 10156214f412SHong Zhang ierr = MatSetValues(mat_elemental,1,&row,ncols,cols,vals,ADD_VALUES);CHKERRQ(ierr); 10166214f412SHong Zhang for (j=0; j<ncols; j++) { /* lower triangular part */ 10176214f412SHong Zhang if (cols[j] == row) continue; 10186214f412SHong Zhang ierr = MatSetValues(mat_elemental,1,&cols[j],1,&row,&vals[j],ADD_VALUES);CHKERRQ(ierr); 10196214f412SHong Zhang } 10206214f412SHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 10216214f412SHong Zhang } 10226214f412SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 10236214f412SHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10246214f412SHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10256214f412SHong Zhang 1026511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 102728be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 10286214f412SHong Zhang } else { 10296214f412SHong Zhang *newmat = mat_elemental; 10306214f412SHong Zhang } 10316214f412SHong Zhang PetscFunctionReturn(0); 10326214f412SHong Zhang } 10336214f412SHong Zhang 1034cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_MPISBAIJ_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 10356214f412SHong Zhang { 10366214f412SHong Zhang Mat mat_elemental; 10376214f412SHong Zhang PetscErrorCode ierr; 10386214f412SHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,row,ncols,j,rstart=A->rmap->rstart,rend=A->rmap->rend; 10396214f412SHong Zhang const PetscInt *cols; 10406214f412SHong Zhang const PetscScalar *vals; 10416214f412SHong Zhang 10426214f412SHong Zhang PetscFunctionBegin; 1043*bdeae278SStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1044*bdeae278SStefano Zampini mat_elemental = *newmat; 1045*bdeae278SStefano Zampini ierr = MatZeroEntries(mat_elemental);CHKERRQ(ierr); 1046*bdeae278SStefano Zampini } else { 10476214f412SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 10486214f412SHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 10496214f412SHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 10506214f412SHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 1051*bdeae278SStefano Zampini } 10526214f412SHong Zhang ierr = MatGetRowUpperTriangular(A);CHKERRQ(ierr); 10536214f412SHong Zhang for (row=rstart; row<rend; row++) { 10546214f412SHong Zhang ierr = MatGetRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 1055*bdeae278SStefano Zampini /* PETSc-Elemental interface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 10566214f412SHong Zhang ierr = MatSetValues(mat_elemental,1,&row,ncols,cols,vals,ADD_VALUES);CHKERRQ(ierr); 10576214f412SHong Zhang for (j=0; j<ncols; j++) { /* lower triangular part */ 10586214f412SHong Zhang if (cols[j] == row) continue; 10596214f412SHong Zhang ierr = MatSetValues(mat_elemental,1,&cols[j],1,&row,&vals[j],ADD_VALUES);CHKERRQ(ierr); 10606214f412SHong Zhang } 10616214f412SHong Zhang ierr = MatRestoreRow(A,row,&ncols,&cols,&vals);CHKERRQ(ierr); 10626214f412SHong Zhang } 10636214f412SHong Zhang ierr = MatRestoreRowUpperTriangular(A);CHKERRQ(ierr); 10646214f412SHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10656214f412SHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10666214f412SHong Zhang 1067511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 106828be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 10696214f412SHong Zhang } else { 10706214f412SHong Zhang *newmat = mat_elemental; 10716214f412SHong Zhang } 10726214f412SHong Zhang PetscFunctionReturn(0); 10736214f412SHong Zhang } 10746214f412SHong Zhang 1075db31f6deSJed Brown static PetscErrorCode MatDestroy_Elemental(Mat A) 1076db31f6deSJed Brown { 1077db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 1078db31f6deSJed Brown PetscErrorCode ierr; 10795e9f5b67SHong Zhang Mat_Elemental_Grid *commgrid; 10805e9f5b67SHong Zhang PetscBool flg; 10815e9f5b67SHong Zhang MPI_Comm icomm; 1082db31f6deSJed Brown 1083db31f6deSJed Brown PetscFunctionBegin; 1084db31f6deSJed Brown delete a->emat; 1085ea394475SSatish Balay delete a->P; 1086ea394475SSatish Balay delete a->Q; 10875e9f5b67SHong Zhang 1088e8146892SSatish Balay El::mpi::Comm cxxcomm(PetscObjectComm((PetscObject)A)); 10890c18141cSBarry Smith ierr = PetscCommDuplicate(cxxcomm.comm,&icomm,NULL);CHKERRQ(ierr); 109047435625SJed Brown ierr = MPI_Comm_get_attr(icomm,Petsc_Elemental_keyval,(void**)&commgrid,(int*)&flg);CHKERRQ(ierr); 10915e9f5b67SHong Zhang if (--commgrid->grid_refct == 0) { 10925e9f5b67SHong Zhang delete commgrid->grid; 10935e9f5b67SHong Zhang ierr = PetscFree(commgrid);CHKERRQ(ierr); 109447435625SJed Brown ierr = MPI_Comm_free_keyval(&Petsc_Elemental_keyval);CHKERRQ(ierr); 10955e9f5b67SHong Zhang } 10965e9f5b67SHong Zhang ierr = PetscCommDestroy(&icomm);CHKERRQ(ierr); 1097bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatGetOwnershipIS_C",NULL);CHKERRQ(ierr); 10983ca39a21SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatFactorGetSolverType_C",NULL);CHKERRQ(ierr); 1099db31f6deSJed Brown ierr = PetscFree(A->data);CHKERRQ(ierr); 1100db31f6deSJed Brown PetscFunctionReturn(0); 1101db31f6deSJed Brown } 1102db31f6deSJed Brown 1103db31f6deSJed Brown PetscErrorCode MatSetUp_Elemental(Mat A) 1104db31f6deSJed Brown { 1105db31f6deSJed Brown Mat_Elemental *a = (Mat_Elemental*)A->data; 1106db31f6deSJed Brown PetscErrorCode ierr; 1107f19600a0SHong Zhang MPI_Comm comm; 1108db31f6deSJed Brown PetscMPIInt rsize,csize; 1109f19600a0SHong Zhang PetscInt n; 1110db31f6deSJed Brown 1111db31f6deSJed Brown PetscFunctionBegin; 1112db31f6deSJed Brown ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 1113db31f6deSJed Brown ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 1114db31f6deSJed Brown 1115f19600a0SHong Zhang /* Check if local row and clomun sizes are equally distributed. 1116f19600a0SHong Zhang Jed: Elemental uses "element" cyclic ordering so the sizes need to match that 1117f19600a0SHong Zhang exactly. The strategy in MatElemental is for PETSc to implicitly permute to block ordering (like would be returned by 1118f19600a0SHong Zhang PetscSplitOwnership(comm,&n,&N)), at which point Elemental matrices can act on PETSc vectors without redistributing the vectors. */ 1119f19600a0SHong Zhang ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 1120f19600a0SHong Zhang n = PETSC_DECIDE; 1121f19600a0SHong Zhang ierr = PetscSplitOwnership(comm,&n,&A->rmap->N);CHKERRQ(ierr); 1122f19600a0SHong 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); 1123f19600a0SHong Zhang 1124f19600a0SHong Zhang n = PETSC_DECIDE; 1125f19600a0SHong Zhang ierr = PetscSplitOwnership(comm,&n,&A->cmap->N);CHKERRQ(ierr); 1126f19600a0SHong 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); 1127f19600a0SHong Zhang 1128efb79153SJack Poulson a->emat->Resize(A->rmap->N,A->cmap->N);CHKERRQ(ierr); 1129e8146892SSatish Balay El::Zero(*a->emat); 1130db31f6deSJed Brown 1131db31f6deSJed Brown ierr = MPI_Comm_size(A->rmap->comm,&rsize);CHKERRQ(ierr); 1132db31f6deSJed Brown ierr = MPI_Comm_size(A->cmap->comm,&csize);CHKERRQ(ierr); 1133ce94432eSBarry Smith if (csize != rsize) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"Cannot use row and column communicators of different sizes"); 1134db31f6deSJed Brown a->commsize = rsize; 1135db31f6deSJed Brown a->mr[0] = A->rmap->N % rsize; if (!a->mr[0]) a->mr[0] = rsize; 1136db31f6deSJed Brown a->mr[1] = A->cmap->N % csize; if (!a->mr[1]) a->mr[1] = csize; 1137db31f6deSJed Brown a->m[0] = A->rmap->N / rsize + (a->mr[0] != rsize); 1138db31f6deSJed Brown a->m[1] = A->cmap->N / csize + (a->mr[1] != csize); 1139db31f6deSJed Brown PetscFunctionReturn(0); 1140db31f6deSJed Brown } 1141db31f6deSJed Brown 1142aae2c449SHong Zhang PetscErrorCode MatAssemblyBegin_Elemental(Mat A, MatAssemblyType type) 1143aae2c449SHong Zhang { 1144aae2c449SHong Zhang Mat_Elemental *a = (Mat_Elemental*)A->data; 1145aae2c449SHong Zhang 1146aae2c449SHong Zhang PetscFunctionBegin; 1147fbbcb730SJack Poulson /* printf("Calling ProcessQueues\n"); */ 1148fbbcb730SJack Poulson a->emat->ProcessQueues(); 1149fbbcb730SJack Poulson /* printf("Finished ProcessQueues\n"); */ 1150aae2c449SHong Zhang PetscFunctionReturn(0); 1151aae2c449SHong Zhang } 1152aae2c449SHong Zhang 1153aae2c449SHong Zhang PetscErrorCode MatAssemblyEnd_Elemental(Mat A, MatAssemblyType type) 1154aae2c449SHong Zhang { 1155aae2c449SHong Zhang PetscFunctionBegin; 1156aae2c449SHong Zhang /* Currently does nothing */ 1157aae2c449SHong Zhang PetscFunctionReturn(0); 1158aae2c449SHong Zhang } 1159aae2c449SHong Zhang 11607b30e0f1SHong Zhang PetscErrorCode MatLoad_Elemental(Mat newMat, PetscViewer viewer) 11617b30e0f1SHong Zhang { 11627b30e0f1SHong Zhang PetscErrorCode ierr; 11637b30e0f1SHong Zhang Mat Adense,Ae; 11647b30e0f1SHong Zhang MPI_Comm comm; 11657b30e0f1SHong Zhang 11667b30e0f1SHong Zhang PetscFunctionBegin; 11677b30e0f1SHong Zhang ierr = PetscObjectGetComm((PetscObject)newMat,&comm);CHKERRQ(ierr); 11687b30e0f1SHong Zhang ierr = MatCreate(comm,&Adense);CHKERRQ(ierr); 11697b30e0f1SHong Zhang ierr = MatSetType(Adense,MATDENSE);CHKERRQ(ierr); 11707b30e0f1SHong Zhang ierr = MatLoad(Adense,viewer);CHKERRQ(ierr); 11717b30e0f1SHong Zhang ierr = MatConvert(Adense, MATELEMENTAL, MAT_INITIAL_MATRIX,&Ae);CHKERRQ(ierr); 11727b30e0f1SHong Zhang ierr = MatDestroy(&Adense);CHKERRQ(ierr); 117328be2f97SBarry Smith ierr = MatHeaderReplace(newMat,&Ae);CHKERRQ(ierr); 11747b30e0f1SHong Zhang PetscFunctionReturn(0); 11757b30e0f1SHong Zhang } 11767b30e0f1SHong Zhang 117740d92e34SHong Zhang /* -------------------------------------------------------------------*/ 117840d92e34SHong Zhang static struct _MatOps MatOps_Values = { 117940d92e34SHong Zhang MatSetValues_Elemental, 118040d92e34SHong Zhang 0, 118140d92e34SHong Zhang 0, 118240d92e34SHong Zhang MatMult_Elemental, 118340d92e34SHong Zhang /* 4*/ MatMultAdd_Elemental, 11849426833fSXuan Zhou MatMultTranspose_Elemental, 1185e883f9d5SXuan Zhou MatMultTransposeAdd_Elemental, 118640d92e34SHong Zhang MatSolve_Elemental, 1187df311e6cSXuan Zhou MatSolveAdd_Elemental, 11882ef15aa2SHong Zhang 0, 11892ef15aa2SHong Zhang /*10*/ 0, 119040d92e34SHong Zhang MatLUFactor_Elemental, 119140d92e34SHong Zhang MatCholeskyFactor_Elemental, 119240d92e34SHong Zhang 0, 119340d92e34SHong Zhang MatTranspose_Elemental, 119440d92e34SHong Zhang /*15*/ MatGetInfo_Elemental, 119540d92e34SHong Zhang 0, 119661119200SXuan Zhou MatGetDiagonal_Elemental, 1197ade3cc5eSXuan Zhou MatDiagonalScale_Elemental, 119840d92e34SHong Zhang MatNorm_Elemental, 119940d92e34SHong Zhang /*20*/ MatAssemblyBegin_Elemental, 120040d92e34SHong Zhang MatAssemblyEnd_Elemental, 120132d7a744SHong Zhang MatSetOption_Elemental, 120240d92e34SHong Zhang MatZeroEntries_Elemental, 120340d92e34SHong Zhang /*24*/ 0, 120440d92e34SHong Zhang MatLUFactorSymbolic_Elemental, 120540d92e34SHong Zhang MatLUFactorNumeric_Elemental, 120640d92e34SHong Zhang MatCholeskyFactorSymbolic_Elemental, 120740d92e34SHong Zhang MatCholeskyFactorNumeric_Elemental, 120840d92e34SHong Zhang /*29*/ MatSetUp_Elemental, 120940d92e34SHong Zhang 0, 121040d92e34SHong Zhang 0, 121140d92e34SHong Zhang 0, 121240d92e34SHong Zhang 0, 1213df311e6cSXuan Zhou /*34*/ MatDuplicate_Elemental, 121440d92e34SHong Zhang 0, 121540d92e34SHong Zhang 0, 121640d92e34SHong Zhang 0, 121740d92e34SHong Zhang 0, 121840d92e34SHong Zhang /*39*/ MatAXPY_Elemental, 121940d92e34SHong Zhang 0, 122040d92e34SHong Zhang 0, 122140d92e34SHong Zhang 0, 122240d92e34SHong Zhang MatCopy_Elemental, 122340d92e34SHong Zhang /*44*/ 0, 122440d92e34SHong Zhang MatScale_Elemental, 12257d68702bSBarry Smith MatShift_Basic, 122640d92e34SHong Zhang 0, 122740d92e34SHong Zhang 0, 122840d92e34SHong Zhang /*49*/ 0, 122940d92e34SHong Zhang 0, 123040d92e34SHong Zhang 0, 123140d92e34SHong Zhang 0, 123240d92e34SHong Zhang 0, 123340d92e34SHong Zhang /*54*/ 0, 123440d92e34SHong Zhang 0, 123540d92e34SHong Zhang 0, 123640d92e34SHong Zhang 0, 123740d92e34SHong Zhang 0, 123840d92e34SHong Zhang /*59*/ 0, 123940d92e34SHong Zhang MatDestroy_Elemental, 124040d92e34SHong Zhang MatView_Elemental, 124140d92e34SHong Zhang 0, 124240d92e34SHong Zhang 0, 124340d92e34SHong Zhang /*64*/ 0, 124440d92e34SHong Zhang 0, 124540d92e34SHong Zhang 0, 124640d92e34SHong Zhang 0, 124740d92e34SHong Zhang 0, 124840d92e34SHong Zhang /*69*/ 0, 124940d92e34SHong Zhang 0, 12502ef0cf24SXuan Zhou MatConvert_Elemental_Dense, 125140d92e34SHong Zhang 0, 125240d92e34SHong Zhang 0, 125340d92e34SHong Zhang /*74*/ 0, 125440d92e34SHong Zhang 0, 125540d92e34SHong Zhang 0, 125640d92e34SHong Zhang 0, 125740d92e34SHong Zhang 0, 125840d92e34SHong Zhang /*79*/ 0, 125940d92e34SHong Zhang 0, 126040d92e34SHong Zhang 0, 126140d92e34SHong Zhang 0, 12627b30e0f1SHong Zhang MatLoad_Elemental, 126340d92e34SHong Zhang /*84*/ 0, 126440d92e34SHong Zhang 0, 126540d92e34SHong Zhang 0, 126640d92e34SHong Zhang 0, 126740d92e34SHong Zhang 0, 126840d92e34SHong Zhang /*89*/ MatMatMult_Elemental, 126940d92e34SHong Zhang MatMatMultSymbolic_Elemental, 127040d92e34SHong Zhang MatMatMultNumeric_Elemental, 127140d92e34SHong Zhang 0, 127240d92e34SHong Zhang 0, 127340d92e34SHong Zhang /*94*/ 0, 1274df311e6cSXuan Zhou MatMatTransposeMult_Elemental, 1275df311e6cSXuan Zhou MatMatTransposeMultSymbolic_Elemental, 1276df311e6cSXuan Zhou MatMatTransposeMultNumeric_Elemental, 127740d92e34SHong Zhang 0, 127840d92e34SHong Zhang /*99*/ 0, 127940d92e34SHong Zhang 0, 128040d92e34SHong Zhang 0, 1281dfcb0403SXuan Zhou MatConjugate_Elemental, 128240d92e34SHong Zhang 0, 128340d92e34SHong Zhang /*104*/0, 128440d92e34SHong Zhang 0, 128540d92e34SHong Zhang 0, 128640d92e34SHong Zhang 0, 128740d92e34SHong Zhang 0, 128840d92e34SHong Zhang /*109*/MatMatSolve_Elemental, 128940d92e34SHong Zhang 0, 129040d92e34SHong Zhang 0, 129140d92e34SHong Zhang 0, 129234fa46e1SFrancesco Ballarin MatMissingDiagonal_Elemental, 129340d92e34SHong Zhang /*114*/0, 129440d92e34SHong Zhang 0, 129540d92e34SHong Zhang 0, 129640d92e34SHong Zhang 0, 129740d92e34SHong Zhang 0, 129840d92e34SHong Zhang /*119*/0, 12994a29722dSXuan Zhou MatHermitianTranspose_Elemental, 130040d92e34SHong Zhang 0, 130140d92e34SHong Zhang 0, 130240d92e34SHong Zhang 0, 130340d92e34SHong Zhang /*124*/0, 130440d92e34SHong Zhang 0, 130540d92e34SHong Zhang 0, 130640d92e34SHong Zhang 0, 130740d92e34SHong Zhang 0, 130840d92e34SHong Zhang /*129*/0, 130940d92e34SHong Zhang 0, 131040d92e34SHong Zhang 0, 131140d92e34SHong Zhang 0, 131240d92e34SHong Zhang 0, 131340d92e34SHong Zhang /*134*/0, 131440d92e34SHong Zhang 0, 131540d92e34SHong Zhang 0, 131640d92e34SHong Zhang 0, 131740d92e34SHong Zhang 0 131840d92e34SHong Zhang }; 131940d92e34SHong Zhang 1320ed36708cSHong Zhang /*MC 1321ed36708cSHong Zhang MATELEMENTAL = "elemental" - A matrix type for dense matrices using the Elemental package 1322ed36708cSHong Zhang 1323c2b89b5dSBarry Smith Use ./configure --download-elemental to install PETSc to use Elemental 1324c2b89b5dSBarry Smith 13253ca39a21SBarry Smith Use -pc_type lu -pc_factor_mat_solver_type elemental to use this direct solver 1326c2b89b5dSBarry Smith 1327ed36708cSHong Zhang Options Database Keys: 13285cc86fc1SJed Brown + -mat_type elemental - sets the matrix type to "elemental" during a call to MatSetFromOptions() 13295cc86fc1SJed Brown - -mat_elemental_grid_height - sets Grid Height for 2D cyclic ordering of internal matrix 1330ed36708cSHong Zhang 1331ed36708cSHong Zhang Level: beginner 1332ed36708cSHong Zhang 13335cb544a0SHong Zhang .seealso: MATDENSE 1334ed36708cSHong Zhang M*/ 13354a29722dSXuan Zhou 13368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_Elemental(Mat A) 1337db31f6deSJed Brown { 1338db31f6deSJed Brown Mat_Elemental *a; 1339db31f6deSJed Brown PetscErrorCode ierr; 13405682a260SJack Poulson PetscBool flg,flg1; 13415e9f5b67SHong Zhang Mat_Elemental_Grid *commgrid; 13425e9f5b67SHong Zhang MPI_Comm icomm; 13435682a260SJack Poulson PetscInt optv1; 1344db31f6deSJed Brown 1345db31f6deSJed Brown PetscFunctionBegin; 1346607a6623SBarry Smith ierr = PetscElementalInitializePackage();CHKERRQ(ierr); 134740d92e34SHong Zhang ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 134840d92e34SHong Zhang A->insertmode = NOT_SET_VALUES; 1349db31f6deSJed Brown 1350b00a9115SJed Brown ierr = PetscNewLog(A,&a);CHKERRQ(ierr); 1351db31f6deSJed Brown A->data = (void*)a; 1352db31f6deSJed Brown 1353db31f6deSJed Brown /* Set up the elemental matrix */ 1354e8146892SSatish Balay El::mpi::Comm cxxcomm(PetscObjectComm((PetscObject)A)); 13555e9f5b67SHong Zhang 13565e9f5b67SHong Zhang /* Grid needs to be shared between multiple Mats on the same communicator, implement by attribute caching on the MPI_Comm */ 13575e9f5b67SHong Zhang if (Petsc_Elemental_keyval == MPI_KEYVAL_INVALID) { 135812801b39SBarry Smith ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Elemental_keyval,(void*)0);CHKERRQ(ierr); 13595e9f5b67SHong Zhang } 13600c18141cSBarry Smith ierr = PetscCommDuplicate(cxxcomm.comm,&icomm,NULL);CHKERRQ(ierr); 136147435625SJed Brown ierr = MPI_Comm_get_attr(icomm,Petsc_Elemental_keyval,(void**)&commgrid,(int*)&flg);CHKERRQ(ierr); 13625e9f5b67SHong Zhang if (!flg) { 1363b00a9115SJed Brown ierr = PetscNewLog(A,&commgrid);CHKERRQ(ierr); 13645cb544a0SHong Zhang 1365ce94432eSBarry Smith ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)A),((PetscObject)A)->prefix,"Elemental Options","Mat");CHKERRQ(ierr); 1366e8146892SSatish Balay /* displayed default grid sizes (CommSize,1) are set by us arbitrarily until El::Grid() is called */ 1367e8146892SSatish Balay ierr = PetscOptionsInt("-mat_elemental_grid_height","Grid Height","None",El::mpi::Size(cxxcomm),&optv1,&flg1);CHKERRQ(ierr); 13685682a260SJack Poulson if (flg1) { 1369e8146892SSatish Balay if (El::mpi::Size(cxxcomm) % optv1 != 0) { 1370e8146892SSatish Balay SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"Grid Height %D must evenly divide CommSize %D",optv1,(PetscInt)El::mpi::Size(cxxcomm)); 1371ed667823SXuan Zhou } 1372e8146892SSatish Balay commgrid->grid = new El::Grid(cxxcomm,optv1); /* use user-provided grid height */ 13732ef0cf24SXuan Zhou } else { 1374e8146892SSatish Balay commgrid->grid = new El::Grid(cxxcomm); /* use Elemental default grid sizes */ 1375da0640a4SHong Zhang /* printf("new commgrid->grid = %p\n",commgrid->grid); -- memory leak revealed by valgrind? */ 1376ed667823SXuan Zhou } 13775e9f5b67SHong Zhang commgrid->grid_refct = 1; 137847435625SJed Brown ierr = MPI_Comm_set_attr(icomm,Petsc_Elemental_keyval,(void*)commgrid);CHKERRQ(ierr); 1379ea394475SSatish Balay 1380ea394475SSatish Balay a->pivoting = 1; 1381ea394475SSatish Balay ierr = PetscOptionsInt("-mat_elemental_pivoting","Pivoting","None",a->pivoting,&a->pivoting,NULL);CHKERRQ(ierr); 1382ea394475SSatish Balay 13832a808120SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 13845e9f5b67SHong Zhang } else { 13855e9f5b67SHong Zhang commgrid->grid_refct++; 13865e9f5b67SHong Zhang } 13875e9f5b67SHong Zhang ierr = PetscCommDestroy(&icomm);CHKERRQ(ierr); 13885e9f5b67SHong Zhang a->grid = commgrid->grid; 1389e8146892SSatish Balay a->emat = new El::DistMatrix<PetscElemScalar>(*a->grid); 139032d7a744SHong Zhang a->roworiented = PETSC_TRUE; 1391db31f6deSJed Brown 1392bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatGetOwnershipIS_C",MatGetOwnershipIS_Elemental);CHKERRQ(ierr); 1393db31f6deSJed Brown ierr = PetscObjectChangeTypeName((PetscObject)A,MATELEMENTAL);CHKERRQ(ierr); 1394db31f6deSJed Brown PetscFunctionReturn(0); 1395db31f6deSJed Brown } 1396