156fe5c5cSLois Curfman McInnes #ifndef lint 2*70f55243SBarry Smith static char vcid[] = "$Id: convert.c,v 1.50 1996/07/08 22:20:46 bsmith Exp bsmith $"; 356fe5c5cSLois Curfman McInnes #endif 456fe5c5cSLois Curfman McInnes 5*70f55243SBarry Smith #include "src/mat/impls/aij/mpi/mpiaij.h" 6*70f55243SBarry Smith #include "src/mat/impls/bdiag/mpi/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; 1825cdf11fSBarry Smith int ierr, i, nz, m, n, *cwork, rstart, rend,flg; 1925cdf11fSBarry Smith 208b6375c0SLois Curfman McInnes ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr); 217181dc05SLois Curfman McInnes if (newtype == MATSAME) newtype = (MatType)mat->type; 228b6375c0SLois Curfman McInnes switch (newtype) { 238b6375c0SLois Curfman McInnes case MATSEQAIJ: 24b4fd4287SBarry Smith ierr = MatCreateSeqAIJ(mat->comm,m,n,0,PETSC_NULL,M); CHKERRQ(ierr); 258b6375c0SLois Curfman McInnes break; 268b6375c0SLois Curfman McInnes case MATMPIROWBS: 278b6375c0SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert:MATMPIROWBS matrix must be square"); 28b4fd4287SBarry Smith ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PETSC_NULL, 29b4fd4287SBarry Smith PETSC_NULL,M); CHKERRQ(ierr); 308b6375c0SLois Curfman McInnes break; 318b6375c0SLois Curfman McInnes case MATMPIAIJ: 328b6375c0SLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 33b4fd4287SBarry Smith m,n,0,PETSC_NULL,0,PETSC_NULL,M); CHKERRQ(ierr); 348b6375c0SLois Curfman McInnes break; 358b6375c0SLois Curfman McInnes case MATSEQDENSE: 36b4fd4287SBarry Smith ierr = MatCreateSeqDense(mat->comm,m,n,PETSC_NULL,M); CHKERRQ(ierr); 378b6375c0SLois Curfman McInnes break; 388b6375c0SLois Curfman McInnes case MATMPIDENSE: 398b6375c0SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 40b4fd4287SBarry Smith m,n,PETSC_NULL,M); CHKERRQ(ierr); 418b6375c0SLois Curfman McInnes break; 428b6375c0SLois Curfman McInnes case MATSEQBDIAG: 438b6375c0SLois Curfman McInnes { 448b6375c0SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 4535aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr); 46b4fd4287SBarry Smith ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,PETSC_NULL,PETSC_NULL,M);CHKERRQ(ierr); 478b6375c0SLois Curfman McInnes break; 488b6375c0SLois Curfman McInnes } 498b6375c0SLois Curfman McInnes case MATMPIBDIAG: 508b6375c0SLois Curfman McInnes { 518b6375c0SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 5235aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr); 53b4fd4287SBarry Smith ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PETSC_NULL, 54b4fd4287SBarry Smith PETSC_NULL,M); CHKERRQ(ierr); 558b6375c0SLois Curfman McInnes break; 568b6375c0SLois Curfman McInnes } 578b6375c0SLois Curfman McInnes default: 588b6375c0SLois Curfman McInnes SETERRQ(1,"MatConvert:Matrix type is not currently supported"); 598b6375c0SLois Curfman McInnes } 608b6375c0SLois Curfman McInnes ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr); 618b6375c0SLois Curfman McInnes for (i=rstart; i<rend; i++) { 628b6375c0SLois Curfman McInnes ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 638b6375c0SLois Curfman McInnes ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 648b6375c0SLois Curfman McInnes ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 658b6375c0SLois Curfman McInnes } 666d4a8577SBarry Smith ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 676d4a8577SBarry Smith ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 688b6375c0SLois Curfman McInnes return 0; 698b6375c0SLois Curfman McInnes } 708b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */ 7156fe5c5cSLois Curfman McInnes /* 72ec8511deSBarry Smith MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For 7344ae05bdSLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 7456fe5c5cSLois Curfman McInnes */ 752399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B) 7656fe5c5cSLois Curfman McInnes { 772399e097SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7856fe5c5cSLois Curfman McInnes Scalar *vwork; 795dd7a6c7SBarry Smith int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend,flg; 8056fe5c5cSLois Curfman McInnes 8156fe5c5cSLois Curfman McInnes switch (newtype) { 82ec8511deSBarry Smith case MATMPIROWBS: 832399e097SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square"); 84b4fd4287SBarry Smith ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL,B); 85ed2daf61SLois Curfman McInnes CHKERRQ(ierr); 86416022c9SBarry Smith break; 8744ae05bdSLois Curfman McInnes case MATMPIAIJ: 8844ae05bdSLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 89b4fd4287SBarry Smith m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr); 90416022c9SBarry Smith break; 91ec8511deSBarry Smith case MATSEQDENSE: 92b4fd4287SBarry Smith ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr); 932399e097SLois Curfman McInnes break; 942399e097SLois Curfman McInnes case MATMPIDENSE: 952399e097SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 96b4fd4287SBarry Smith m,n,PETSC_NULL,B); CHKERRQ(ierr); 97416022c9SBarry Smith break; 98ec8511deSBarry Smith case MATSEQBDIAG: 99416022c9SBarry Smith { 10058154824SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 10135aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr); 102a2ce50c7SBarry Smith ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,PETSC_NULL,PETSC_NULL,B); 103a2ce50c7SBarry Smith CHKERRQ(ierr); 10444ae05bdSLois Curfman McInnes break; 10544ae05bdSLois Curfman McInnes } 10644ae05bdSLois Curfman McInnes case MATMPIBDIAG: 107416022c9SBarry Smith { 10858154824SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 10935aab85fSBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr); 11035aab85fSBarry Smith CHKERRQ(ierr); 111b4fd4287SBarry Smith ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PETSC_NULL, 112b4fd4287SBarry Smith PETSC_NULL,B); CHKERRQ(ierr); 113416022c9SBarry Smith break; 11456fe5c5cSLois Curfman McInnes } 115f3ba505bSLois Curfman McInnes default: 116ec8511deSBarry Smith SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported"); 117f3ba505bSLois Curfman McInnes } 1182399e097SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 11944ae05bdSLois Curfman McInnes for (i=rstart; i<rend; i++) { 1202399e097SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 1212399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1222399e097SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 12356fe5c5cSLois Curfman McInnes } 1246d4a8577SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1256d4a8577SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 12656fe5c5cSLois Curfman McInnes return 0; 12756fe5c5cSLois Curfman McInnes } 12856fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */ 12956fe5c5cSLois Curfman McInnes /* 1301fb19edaSLois Curfman McInnes MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another 13156fe5c5cSLois Curfman McInnes parallel format. 13256fe5c5cSLois Curfman McInnes */ 1332399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B) 13456fe5c5cSLois Curfman McInnes { 135c456f294SBarry Smith SETERRQ(1,"MatConvert_MPIAIJ:Not currently suported"); 136c456f294SBarry Smith 137abc0e9e4SLois Curfman McInnes /* Each processor converts its local rows */ 1380ff6cd27SBarry Smith /* ---------------------------------------------------- 139d9ce839aSLois Curfman McInnes Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data; 140d9ce839aSLois Curfman McInnes int ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork; 141d9ce839aSLois Curfman McInnes Scalar *vwork; 142d9ce839aSLois Curfman McInnes 14356fe5c5cSLois Curfman McInnes for (i=0; i<m; i++) { 14456fe5c5cSLois Curfman McInnes ig = i + rstart; 1452399e097SLois Curfman McInnes ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 1462399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1472399e097SLois Curfman McInnes ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 14856fe5c5cSLois Curfman McInnes } 1496d4a8577SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1506d4a8577SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 15156fe5c5cSLois Curfman McInnes return 0; 1520ff6cd27SBarry Smith ---------------------------------------------------------*/ 15356fe5c5cSLois Curfman McInnes } 1548b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */ 155567e79a1SLois Curfman McInnes /* 156567e79a1SLois Curfman McInnes MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For 157567e79a1SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 158567e79a1SLois Curfman McInnes */ 159567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B) 160567e79a1SLois Curfman McInnes { 161567e79a1SLois Curfman McInnes Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data; 1628b6375c0SLois Curfman McInnes Scalar *vwork, *vw2; 163567e79a1SLois Curfman McInnes int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 1648b6375c0SLois Curfman McInnes int j, *cw2, ict; 165567e79a1SLois Curfman McInnes 166dad23ff5SLois Curfman McInnes /* rough over-estimate; could refine for individual rows */ 1670452661fSBarry Smith nz = PetscMin(n,a->nd*a->nb); 168567e79a1SLois Curfman McInnes switch (newtype) { 169567e79a1SLois Curfman McInnes case MATSEQAIJ: 170b4fd4287SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,nz,PETSC_NULL,B); CHKERRQ(ierr); 171567e79a1SLois Curfman McInnes break; 172567e79a1SLois Curfman McInnes case MATMPIROWBS: 173567e79a1SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square"); 174b4fd4287SBarry Smith ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL, 175ed2daf61SLois Curfman McInnes B); CHKERRQ(ierr); 176567e79a1SLois Curfman McInnes break; 177567e79a1SLois Curfman McInnes case MATMPIAIJ: 178567e79a1SLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 179b4fd4287SBarry Smith m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr); 180567e79a1SLois Curfman McInnes break; 181567e79a1SLois Curfman McInnes case MATSEQDENSE: 182b4fd4287SBarry Smith ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr); 183567e79a1SLois Curfman McInnes break; 184567e79a1SLois Curfman McInnes case MATMPIDENSE: 185567e79a1SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 186b4fd4287SBarry Smith m,n,PETSC_NULL,B); CHKERRQ(ierr); 187567e79a1SLois Curfman McInnes break; 188567e79a1SLois Curfman McInnes case MATMPIBDIAG: 189567e79a1SLois Curfman McInnes { 190ed2daf61SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb, 191b4fd4287SBarry Smith PETSC_NULL,PETSC_NULL,B); CHKERRQ(ierr); 192567e79a1SLois Curfman McInnes break; 193567e79a1SLois Curfman McInnes } 194567e79a1SLois Curfman McInnes default: 195567e79a1SLois Curfman McInnes SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported"); 196567e79a1SLois Curfman McInnes } 197567e79a1SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 1988b6375c0SLois Curfman McInnes 1990452661fSBarry Smith cw2 = (int *)PetscMalloc( n * sizeof(int) ); CHKPTRQ(cw2); 2000452661fSBarry Smith vw2 = (Scalar *)PetscMalloc( n * sizeof(Scalar) ); CHKPTRQ(vw2); 201567e79a1SLois Curfman McInnes for (i=rstart; i<rend; i++) { 202567e79a1SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 2038b6375c0SLois Curfman McInnes ict = 0; /* strip out the zero elements ... is this what we really want? */ 2048b6375c0SLois Curfman McInnes for (j=0; j<nz; j++) { 2058b6375c0SLois Curfman McInnes if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;} 2068b6375c0SLois Curfman McInnes } 2076d84be18SBarry Smith if (ict) { 2086d84be18SBarry Smith ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr); 2096d84be18SBarry Smith } 210567e79a1SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 211567e79a1SLois Curfman McInnes } 2120452661fSBarry Smith PetscFree(cw2); PetscFree(vw2); 2136d4a8577SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2146d4a8577SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 215567e79a1SLois Curfman McInnes return 0; 216567e79a1SLois Curfman McInnes } 217