156fe5c5cSLois Curfman McInnes #ifndef lint 2*5615d1e5SSatish Balay static char vcid[] = "$Id: convert.c,v 1.56 1997/01/01 03:38:57 bsmith Exp balay $"; 356fe5c5cSLois Curfman McInnes #endif 456fe5c5cSLois Curfman McInnes 570f55243SBarry Smith #include "src/mat/impls/aij/mpi/mpiaij.h" 670f55243SBarry 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 11*5615d1e5SSatish Balay #undef __FUNC__ 12*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_Basic" 138b6375c0SLois Curfman McInnes /* 148b6375c0SLois Curfman McInnes MatConvert_Basic - Converts from any input format to another format. For 158b6375c0SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 168b6375c0SLois Curfman McInnes */ 178b6375c0SLois Curfman McInnes int MatConvert_Basic(Mat mat,MatType newtype,Mat *M) 188b6375c0SLois Curfman McInnes { 198b6375c0SLois Curfman McInnes Scalar *vwork; 2025cdf11fSBarry Smith int ierr, i, nz, m, n, *cwork, rstart, rend,flg; 2125cdf11fSBarry Smith 228b6375c0SLois Curfman McInnes ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr); 237181dc05SLois Curfman McInnes if (newtype == MATSAME) newtype = (MatType)mat->type; 248b6375c0SLois Curfman McInnes switch (newtype) { 258b6375c0SLois Curfman McInnes case MATSEQAIJ: 26b4fd4287SBarry Smith ierr = MatCreateSeqAIJ(mat->comm,m,n,0,PETSC_NULL,M); CHKERRQ(ierr); 278b6375c0SLois Curfman McInnes break; 288b6375c0SLois Curfman McInnes case MATMPIROWBS: 29e3372554SBarry Smith if (m != n) SETERRQ(1,0,"MATMPIROWBS matrix must be square"); 303b2fbd54SBarry Smith ierr = MatCreateMPIRowbs(mat->comm,PETSC_DECIDE,m,0,PETSC_NULL, 31b4fd4287SBarry Smith PETSC_NULL,M); CHKERRQ(ierr); 328b6375c0SLois Curfman McInnes break; 338b6375c0SLois Curfman McInnes case MATMPIAIJ: 343b2fbd54SBarry Smith ierr = MatCreateMPIAIJ(mat->comm,PETSC_DECIDE,PETSC_DECIDE, 35b4fd4287SBarry Smith m,n,0,PETSC_NULL,0,PETSC_NULL,M); CHKERRQ(ierr); 368b6375c0SLois Curfman McInnes break; 378b6375c0SLois Curfman McInnes case MATSEQDENSE: 38b4fd4287SBarry Smith ierr = MatCreateSeqDense(mat->comm,m,n,PETSC_NULL,M); CHKERRQ(ierr); 398b6375c0SLois Curfman McInnes break; 408b6375c0SLois Curfman McInnes case MATMPIDENSE: 413b2fbd54SBarry Smith ierr = MatCreateMPIDense(mat->comm,PETSC_DECIDE,PETSC_DECIDE, 42b4fd4287SBarry Smith m,n,PETSC_NULL,M); CHKERRQ(ierr); 438b6375c0SLois Curfman McInnes break; 448b6375c0SLois Curfman McInnes case MATSEQBDIAG: 458b6375c0SLois Curfman McInnes { 46537820f0SBarry Smith int bs = 1; /* Default block size = 1 */ 47537820f0SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 48537820f0SBarry Smith ierr = MatCreateSeqBDiag(mat->comm,m,n,0,bs,PETSC_NULL,PETSC_NULL,M);CHKERRQ(ierr); 498b6375c0SLois Curfman McInnes break; 508b6375c0SLois Curfman McInnes } 518b6375c0SLois Curfman McInnes case MATMPIBDIAG: 528b6375c0SLois Curfman McInnes { 53537820f0SBarry Smith int bs = 1; /* Default block size = 1 */ 54537820f0SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 553b2fbd54SBarry Smith ierr = MatCreateMPIBDiag(mat->comm,PETSC_DECIDE,m,n,0,bs,PETSC_NULL, 56b4fd4287SBarry Smith PETSC_NULL,M); CHKERRQ(ierr); 578b6375c0SLois Curfman McInnes break; 588b6375c0SLois Curfman McInnes } 598b6375c0SLois Curfman McInnes default: 60e3372554SBarry Smith SETERRQ(1,0,"Matrix type is not currently supported"); 618b6375c0SLois Curfman McInnes } 628b6375c0SLois Curfman McInnes ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr); 638b6375c0SLois Curfman McInnes for (i=rstart; i<rend; i++) { 648b6375c0SLois Curfman McInnes ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 658b6375c0SLois Curfman McInnes ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 668b6375c0SLois Curfman McInnes ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 678b6375c0SLois Curfman McInnes } 686d4a8577SBarry Smith ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 696d4a8577SBarry Smith ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 708b6375c0SLois Curfman McInnes return 0; 718b6375c0SLois Curfman McInnes } 728b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */ 73*5615d1e5SSatish Balay #undef __FUNC__ 74*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_SeqAIJ" 7556fe5c5cSLois Curfman McInnes /* 76ec8511deSBarry Smith MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For 7744ae05bdSLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 7856fe5c5cSLois Curfman McInnes */ 792399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B) 8056fe5c5cSLois Curfman McInnes { 812399e097SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 8256fe5c5cSLois Curfman McInnes Scalar *vwork; 835dd7a6c7SBarry Smith int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend,flg; 8456fe5c5cSLois Curfman McInnes 8556fe5c5cSLois Curfman McInnes switch (newtype) { 86ec8511deSBarry Smith case MATMPIROWBS: 87e3372554SBarry Smith if (m != n) SETERRQ(1,0,"MATMPIROWBS matrix must be square"); 883b2fbd54SBarry Smith ierr = MatCreateMPIRowbs(A->comm,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL,B); 89ed2daf61SLois Curfman McInnes CHKERRQ(ierr); 90416022c9SBarry Smith break; 9144ae05bdSLois Curfman McInnes case MATMPIAIJ: 923b2fbd54SBarry Smith ierr = MatCreateMPIAIJ(A->comm,PETSC_DECIDE,PETSC_DECIDE, 93b4fd4287SBarry Smith m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr); 94416022c9SBarry Smith break; 95ec8511deSBarry Smith case MATSEQDENSE: 96b4fd4287SBarry Smith ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr); 972399e097SLois Curfman McInnes break; 982399e097SLois Curfman McInnes case MATMPIDENSE: 993b2fbd54SBarry Smith ierr = MatCreateMPIDense(A->comm,PETSC_DECIDE,PETSC_DECIDE, 100b4fd4287SBarry Smith m,n,PETSC_NULL,B); CHKERRQ(ierr); 101416022c9SBarry Smith break; 102ec8511deSBarry Smith case MATSEQBDIAG: 103416022c9SBarry Smith { 104537820f0SBarry Smith int bs = 1; /* Default block size = 1 */ 105537820f0SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 106537820f0SBarry Smith ierr = MatCreateSeqBDiag(A->comm,m,n,0,bs,PETSC_NULL,PETSC_NULL,B); 107a2ce50c7SBarry Smith CHKERRQ(ierr); 10844ae05bdSLois Curfman McInnes break; 10944ae05bdSLois Curfman McInnes } 11044ae05bdSLois Curfman McInnes case MATMPIBDIAG: 111416022c9SBarry Smith { 112537820f0SBarry Smith int bs = 1; /* Default block size = 1 */ 113537820f0SBarry Smith ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr); 11435aab85fSBarry Smith CHKERRQ(ierr); 1153b2fbd54SBarry Smith ierr = MatCreateMPIBDiag(A->comm,PETSC_DECIDE,m,n,0,bs,PETSC_NULL, 116b4fd4287SBarry Smith PETSC_NULL,B); CHKERRQ(ierr); 117416022c9SBarry Smith break; 11856fe5c5cSLois Curfman McInnes } 119f3ba505bSLois Curfman McInnes default: 120e3372554SBarry Smith SETERRQ(1,0,"Matrix type is not currently supported"); 121f3ba505bSLois Curfman McInnes } 1222399e097SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 12344ae05bdSLois Curfman McInnes for (i=rstart; i<rend; i++) { 1242399e097SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 1252399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1262399e097SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 12756fe5c5cSLois Curfman McInnes } 1286d4a8577SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1296d4a8577SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 13056fe5c5cSLois Curfman McInnes return 0; 13156fe5c5cSLois Curfman McInnes } 13256fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */ 133*5615d1e5SSatish Balay #undef __FUNC__ 134*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_MPIAIJ" 13556fe5c5cSLois Curfman McInnes /* 1361fb19edaSLois Curfman McInnes MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another 13756fe5c5cSLois Curfman McInnes parallel format. 13856fe5c5cSLois Curfman McInnes */ 1392399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B) 14056fe5c5cSLois Curfman McInnes { 141e3372554SBarry Smith SETERRQ(1,0,"Not currently suported"); 142c456f294SBarry Smith 143abc0e9e4SLois Curfman McInnes /* Each processor converts its local rows */ 1440ff6cd27SBarry Smith /* ---------------------------------------------------- 145d9ce839aSLois Curfman McInnes Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data; 146d9ce839aSLois Curfman McInnes int ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork; 147d9ce839aSLois Curfman McInnes Scalar *vwork; 148d9ce839aSLois Curfman McInnes 14956fe5c5cSLois Curfman McInnes for (i=0; i<m; i++) { 15056fe5c5cSLois Curfman McInnes ig = i + rstart; 1512399e097SLois Curfman McInnes ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 1522399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1532399e097SLois Curfman McInnes ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 15456fe5c5cSLois Curfman McInnes } 1556d4a8577SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1566d4a8577SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 15756fe5c5cSLois Curfman McInnes return 0; 1580ff6cd27SBarry Smith ---------------------------------------------------------*/ 15956fe5c5cSLois Curfman McInnes } 1608b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */ 161*5615d1e5SSatish Balay #undef __FUNC__ 162*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_SeqBDiag" 163567e79a1SLois Curfman McInnes /* 164567e79a1SLois Curfman McInnes MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For 165567e79a1SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 166567e79a1SLois Curfman McInnes */ 167567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B) 168567e79a1SLois Curfman McInnes { 169567e79a1SLois Curfman McInnes Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data; 1708b6375c0SLois Curfman McInnes Scalar *vwork, *vw2; 171567e79a1SLois Curfman McInnes int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 1728b6375c0SLois Curfman McInnes int j, *cw2, ict; 173567e79a1SLois Curfman McInnes 174dad23ff5SLois Curfman McInnes /* rough over-estimate; could refine for individual rows */ 175537820f0SBarry Smith nz = PetscMin(n,a->nd*a->bs); 176567e79a1SLois Curfman McInnes switch (newtype) { 177567e79a1SLois Curfman McInnes case MATSEQAIJ: 178b4fd4287SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,nz,PETSC_NULL,B); CHKERRQ(ierr); 179567e79a1SLois Curfman McInnes break; 180567e79a1SLois Curfman McInnes case MATMPIROWBS: 181e3372554SBarry Smith if (m != n) SETERRQ(1,0,"MATMPIROWBS matrix must be square"); 1823b2fbd54SBarry Smith ierr = MatCreateMPIRowbs(A->comm,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL, 183ed2daf61SLois Curfman McInnes B); CHKERRQ(ierr); 184567e79a1SLois Curfman McInnes break; 185567e79a1SLois Curfman McInnes case MATMPIAIJ: 1863b2fbd54SBarry Smith ierr = MatCreateMPIAIJ(A->comm,PETSC_DECIDE,PETSC_DECIDE, 187b4fd4287SBarry Smith m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr); 188567e79a1SLois Curfman McInnes break; 189567e79a1SLois Curfman McInnes case MATSEQDENSE: 190b4fd4287SBarry Smith ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr); 191567e79a1SLois Curfman McInnes break; 192567e79a1SLois Curfman McInnes case MATMPIDENSE: 1933b2fbd54SBarry Smith ierr = MatCreateMPIDense(A->comm,PETSC_DECIDE,PETSC_DECIDE, 194b4fd4287SBarry Smith m,n,PETSC_NULL,B); CHKERRQ(ierr); 195567e79a1SLois Curfman McInnes break; 196567e79a1SLois Curfman McInnes case MATMPIBDIAG: 197567e79a1SLois Curfman McInnes { 1983b2fbd54SBarry Smith ierr = MatCreateMPIBDiag(A->comm,PETSC_DECIDE,m,n,a->nd,a->bs, 199b4fd4287SBarry Smith PETSC_NULL,PETSC_NULL,B); CHKERRQ(ierr); 200567e79a1SLois Curfman McInnes break; 201567e79a1SLois Curfman McInnes } 202567e79a1SLois Curfman McInnes default: 203e3372554SBarry Smith SETERRQ(1,0,"Matrix type is not currently supported"); 204567e79a1SLois Curfman McInnes } 205567e79a1SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 2068b6375c0SLois Curfman McInnes 2070452661fSBarry Smith cw2 = (int *)PetscMalloc( n * sizeof(int) ); CHKPTRQ(cw2); 2080452661fSBarry Smith vw2 = (Scalar *)PetscMalloc( n * sizeof(Scalar) ); CHKPTRQ(vw2); 209567e79a1SLois Curfman McInnes for (i=rstart; i<rend; i++) { 210567e79a1SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 2118b6375c0SLois Curfman McInnes ict = 0; /* strip out the zero elements ... is this what we really want? */ 2128b6375c0SLois Curfman McInnes for (j=0; j<nz; j++) { 2138b6375c0SLois Curfman McInnes if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;} 2148b6375c0SLois Curfman McInnes } 2156d84be18SBarry Smith if (ict) { 2166d84be18SBarry Smith ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr); 2176d84be18SBarry Smith } 218567e79a1SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 219567e79a1SLois Curfman McInnes } 2200452661fSBarry Smith PetscFree(cw2); PetscFree(vw2); 2216d4a8577SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 2226d4a8577SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 223567e79a1SLois Curfman McInnes return 0; 224567e79a1SLois Curfman McInnes } 225