156fe5c5cSLois Curfman McInnes #ifndef lint 2*ed2daf61SLois Curfman McInnes static char vcid[] = "$Id: convert.c,v 1.38 1995/11/30 22:34:51 bsmith Exp curfman $"; 356fe5c5cSLois Curfman McInnes #endif 456fe5c5cSLois Curfman McInnes 556fe5c5cSLois Curfman McInnes #include "mpiaij.h" 68b6375c0SLois Curfman McInnes #include "mpibdiag.h" 756fe5c5cSLois Curfman McInnes 88b6375c0SLois Curfman McInnes /* This file contains a generic conversion routine and implementation specific 98b6375c0SLois Curfman McInnes versions for increased efficiency. */ 108b6375c0SLois Curfman McInnes 118b6375c0SLois Curfman McInnes /* 128b6375c0SLois Curfman McInnes MatConvert_Basic - Converts from any input format to another format. For 138b6375c0SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 148b6375c0SLois Curfman McInnes */ 158b6375c0SLois Curfman McInnes int MatConvert_Basic(Mat mat,MatType newtype,Mat *M) 168b6375c0SLois Curfman McInnes { 178b6375c0SLois Curfman McInnes Scalar *vwork; 188b6375c0SLois Curfman McInnes int ierr, i, nz, m, n, *cwork, rstart, rend; 198b6375c0SLois Curfman McInnes ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr); 207181dc05SLois Curfman McInnes if (newtype == MATSAME) newtype = (MatType)mat->type; 218b6375c0SLois Curfman McInnes switch (newtype) { 228b6375c0SLois Curfman McInnes case MATSEQAIJ: 23*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqAIJ(mat->comm,m,n,0,PetscNull,M); CHKERRQ(ierr); 248b6375c0SLois Curfman McInnes break; 258b6375c0SLois Curfman McInnes case MATSEQROW: 26*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqRow(mat->comm,m,n,0,PetscNull,M); CHKERRQ(ierr); 278b6375c0SLois Curfman McInnes break; 288b6375c0SLois Curfman McInnes case MATMPIROW: 298b6375c0SLois Curfman McInnes ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 30*ed2daf61SLois Curfman McInnes m,n,0,PetscNull,0,PetscNull,M); CHKERRQ(ierr); 318b6375c0SLois Curfman McInnes break; 328b6375c0SLois Curfman McInnes case MATMPIROWBS: 338b6375c0SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert:MATMPIROWBS matrix must be square"); 34*ed2daf61SLois Curfman McInnes ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PetscNull, 35*ed2daf61SLois Curfman McInnes PetscNull,M); CHKERRQ(ierr); 368b6375c0SLois Curfman McInnes break; 378b6375c0SLois Curfman McInnes case MATMPIAIJ: 388b6375c0SLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 39*ed2daf61SLois Curfman McInnes m,n,0,PetscNull,0,PetscNull,M); CHKERRQ(ierr); 408b6375c0SLois Curfman McInnes break; 418b6375c0SLois Curfman McInnes case MATSEQDENSE: 42*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqDense(mat->comm,m,n,PetscNull,M); CHKERRQ(ierr); 438b6375c0SLois Curfman McInnes break; 448b6375c0SLois Curfman McInnes case MATMPIDENSE: 458b6375c0SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 46*ed2daf61SLois Curfman McInnes m,n,PetscNull,M); CHKERRQ(ierr); 478b6375c0SLois Curfman McInnes break; 488b6375c0SLois Curfman McInnes case MATSEQBDIAG: 498b6375c0SLois Curfman McInnes { 508b6375c0SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 512f8a729cSBarry Smith OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb); 52*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,PetscNull,PetscNull,M); CHKERRQ(ierr); 538b6375c0SLois Curfman McInnes break; 548b6375c0SLois Curfman McInnes } 558b6375c0SLois Curfman McInnes case MATMPIBDIAG: 568b6375c0SLois Curfman McInnes { 578b6375c0SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 582f8a729cSBarry Smith OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb); 59*ed2daf61SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PetscNull, 60*ed2daf61SLois Curfman McInnes PetscNull,M); CHKERRQ(ierr); 618b6375c0SLois Curfman McInnes break; 628b6375c0SLois Curfman McInnes } 638b6375c0SLois Curfman McInnes default: 648b6375c0SLois Curfman McInnes SETERRQ(1,"MatConvert:Matrix type is not currently supported"); 658b6375c0SLois Curfman McInnes } 668b6375c0SLois Curfman McInnes ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr); 678b6375c0SLois Curfman McInnes for (i=rstart; i<rend; i++) { 688b6375c0SLois Curfman McInnes ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 698b6375c0SLois Curfman McInnes ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 708b6375c0SLois Curfman McInnes ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 718b6375c0SLois Curfman McInnes } 728b6375c0SLois Curfman McInnes ierr = MatAssemblyBegin(*M,FINAL_ASSEMBLY); CHKERRQ(ierr); 738b6375c0SLois Curfman McInnes ierr = MatAssemblyEnd(*M,FINAL_ASSEMBLY); CHKERRQ(ierr); 748b6375c0SLois Curfman McInnes return 0; 758b6375c0SLois Curfman McInnes } 768b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */ 7756fe5c5cSLois Curfman McInnes /* 78ec8511deSBarry Smith MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For 7944ae05bdSLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 8056fe5c5cSLois Curfman McInnes */ 812399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B) 8256fe5c5cSLois Curfman McInnes { 832399e097SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 8456fe5c5cSLois Curfman McInnes Scalar *vwork; 852399e097SLois Curfman McInnes int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 8656fe5c5cSLois Curfman McInnes 8756fe5c5cSLois Curfman McInnes switch (newtype) { 88ec8511deSBarry Smith case MATSEQROW: 892399e097SLois Curfman McInnes ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr); 90416022c9SBarry Smith break; 9144ae05bdSLois Curfman McInnes case MATMPIROW: 9244ae05bdSLois Curfman McInnes ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 93*ed2daf61SLois Curfman McInnes m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr); 94416022c9SBarry Smith break; 95ec8511deSBarry Smith case MATMPIROWBS: 962399e097SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square"); 97*ed2daf61SLois Curfman McInnes ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PetscNull,PetscNull,B); 98*ed2daf61SLois Curfman McInnes CHKERRQ(ierr); 99416022c9SBarry Smith break; 10044ae05bdSLois Curfman McInnes case MATMPIAIJ: 10144ae05bdSLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 102*ed2daf61SLois Curfman McInnes m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr); 103416022c9SBarry Smith break; 104ec8511deSBarry Smith case MATSEQDENSE: 105*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,m,n,PetscNull,B); CHKERRQ(ierr); 1062399e097SLois Curfman McInnes break; 1072399e097SLois Curfman McInnes case MATMPIDENSE: 1082399e097SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 109*ed2daf61SLois Curfman McInnes m,n,PetscNull,B); CHKERRQ(ierr); 110416022c9SBarry Smith break; 111ec8511deSBarry Smith case MATSEQBDIAG: 112416022c9SBarry Smith { 11358154824SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 1142f8a729cSBarry Smith OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb); 115*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,PetscNull,PetscNull,B); CHKERRQ(ierr); 11644ae05bdSLois Curfman McInnes break; 11744ae05bdSLois Curfman McInnes } 11844ae05bdSLois Curfman McInnes case MATMPIBDIAG: 119416022c9SBarry Smith { 12058154824SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 1212f8a729cSBarry Smith OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb); 122*ed2daf61SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PetscNull, 123*ed2daf61SLois Curfman McInnes PetscNull,B); CHKERRQ(ierr); 124416022c9SBarry Smith break; 12556fe5c5cSLois Curfman McInnes } 126f3ba505bSLois Curfman McInnes default: 127ec8511deSBarry Smith SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported"); 128f3ba505bSLois Curfman McInnes } 1292399e097SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 13044ae05bdSLois Curfman McInnes for (i=rstart; i<rend; i++) { 1312399e097SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 1322399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1332399e097SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 13456fe5c5cSLois Curfman McInnes } 1352399e097SLois Curfman McInnes ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 1362399e097SLois Curfman McInnes ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 13756fe5c5cSLois Curfman McInnes return 0; 13856fe5c5cSLois Curfman McInnes } 13956fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */ 14056fe5c5cSLois Curfman McInnes /* 1411fb19edaSLois Curfman McInnes MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another 14256fe5c5cSLois Curfman McInnes parallel format. 14356fe5c5cSLois Curfman McInnes */ 1442399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B) 14556fe5c5cSLois Curfman McInnes { 1462399e097SLois Curfman McInnes Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data; 1472399e097SLois Curfman McInnes Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data); 1482399e097SLois Curfman McInnes int ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork; 14956fe5c5cSLois Curfman McInnes Scalar *vwork; 15056fe5c5cSLois Curfman McInnes 15156fe5c5cSLois Curfman McInnes switch (newtype) { 1521fb19edaSLois Curfman McInnes case MATMPIROW: 1532399e097SLois Curfman McInnes ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen, 1542399e097SLois Curfman McInnes 0,Bd->ilen,B); CHKERRQ(ierr); 155abc0e9e4SLois Curfman McInnes break; 15656fe5c5cSLois Curfman McInnes default: 157bbb6d6a8SBarry Smith SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported"); 15856fe5c5cSLois Curfman McInnes } 159abc0e9e4SLois Curfman McInnes /* Each processor converts its local rows */ 16056fe5c5cSLois Curfman McInnes for (i=0; i<m; i++) { 16156fe5c5cSLois Curfman McInnes ig = i + rstart; 1622399e097SLois Curfman McInnes ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 1632399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1642399e097SLois Curfman McInnes ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 16556fe5c5cSLois Curfman McInnes } 1662399e097SLois Curfman McInnes ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 1672399e097SLois Curfman McInnes ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 16856fe5c5cSLois Curfman McInnes return 0; 16956fe5c5cSLois Curfman McInnes } 1708b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */ 171567e79a1SLois Curfman McInnes /* 172567e79a1SLois Curfman McInnes MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For 173567e79a1SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 174567e79a1SLois Curfman McInnes */ 175567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B) 176567e79a1SLois Curfman McInnes { 177567e79a1SLois Curfman McInnes Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data; 1788b6375c0SLois Curfman McInnes Scalar *vwork, *vw2; 179567e79a1SLois Curfman McInnes int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 1808b6375c0SLois Curfman McInnes int j, *cw2, ict; 181567e79a1SLois Curfman McInnes 182dad23ff5SLois Curfman McInnes /* rough over-estimate; could refine for individual rows */ 1830452661fSBarry Smith nz = PetscMin(n,a->nd*a->nb); 184567e79a1SLois Curfman McInnes switch (newtype) { 185567e79a1SLois Curfman McInnes case MATSEQAIJ: 186*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqAIJ(A->comm,m,n,nz,PetscNull,B); CHKERRQ(ierr); 187567e79a1SLois Curfman McInnes break; 188567e79a1SLois Curfman McInnes case MATSEQROW: 189*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqRow(A->comm,m,n,nz,PetscNull,B); CHKERRQ(ierr); 190567e79a1SLois Curfman McInnes break; 191567e79a1SLois Curfman McInnes case MATMPIROW: 192567e79a1SLois Curfman McInnes ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 193*ed2daf61SLois Curfman McInnes m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr); 194567e79a1SLois Curfman McInnes break; 195567e79a1SLois Curfman McInnes case MATMPIROWBS: 196567e79a1SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square"); 197*ed2daf61SLois Curfman McInnes ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PetscNull,PetscNull, 198*ed2daf61SLois Curfman McInnes B); CHKERRQ(ierr); 199567e79a1SLois Curfman McInnes break; 200567e79a1SLois Curfman McInnes case MATMPIAIJ: 201567e79a1SLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 202*ed2daf61SLois Curfman McInnes m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr); 203567e79a1SLois Curfman McInnes break; 204567e79a1SLois Curfman McInnes case MATSEQDENSE: 205*ed2daf61SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,m,n,PetscNull,B); CHKERRQ(ierr); 206567e79a1SLois Curfman McInnes break; 207567e79a1SLois Curfman McInnes case MATMPIDENSE: 208567e79a1SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 209*ed2daf61SLois Curfman McInnes m,n,PetscNull,B); CHKERRQ(ierr); 210567e79a1SLois Curfman McInnes break; 211567e79a1SLois Curfman McInnes case MATMPIBDIAG: 212567e79a1SLois Curfman McInnes { 213*ed2daf61SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb, 214*ed2daf61SLois Curfman McInnes PetscNull,PetscNull,B); CHKERRQ(ierr); 215567e79a1SLois Curfman McInnes break; 216567e79a1SLois Curfman McInnes } 217567e79a1SLois Curfman McInnes default: 218567e79a1SLois Curfman McInnes SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported"); 219567e79a1SLois Curfman McInnes } 220567e79a1SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 2218b6375c0SLois Curfman McInnes 2220452661fSBarry Smith cw2 = (int *)PetscMalloc( n * sizeof(int) ); CHKPTRQ(cw2); 2230452661fSBarry Smith vw2 = (Scalar *)PetscMalloc( n * sizeof(Scalar) ); CHKPTRQ(vw2); 224567e79a1SLois Curfman McInnes for (i=rstart; i<rend; i++) { 225567e79a1SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 2268b6375c0SLois Curfman McInnes ict = 0; /* strip out the zero elements ... is this what we really want? */ 2278b6375c0SLois Curfman McInnes for (j=0; j<nz; j++) { 2288b6375c0SLois Curfman McInnes if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;} 2298b6375c0SLois Curfman McInnes } 2308b6375c0SLois Curfman McInnes if (ict) 2318b6375c0SLois Curfman McInnes {ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr);} 232567e79a1SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 233567e79a1SLois Curfman McInnes } 2340452661fSBarry Smith PetscFree(cw2); PetscFree(vw2); 235567e79a1SLois Curfman McInnes ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 236567e79a1SLois Curfman McInnes ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 237567e79a1SLois Curfman McInnes return 0; 238567e79a1SLois Curfman McInnes } 239