156fe5c5cSLois Curfman McInnes #ifndef lint 2*8b6375c0SLois Curfman McInnes static char vcid[] = "$Id: convert.c,v 1.32 1995/10/27 01:26:46 curfman Exp curfman $"; 356fe5c5cSLois Curfman McInnes #endif 456fe5c5cSLois Curfman McInnes 556fe5c5cSLois Curfman McInnes #include "mpiaij.h" 6*8b6375c0SLois Curfman McInnes #include "mpibdiag.h" 756fe5c5cSLois Curfman McInnes 8*8b6375c0SLois Curfman McInnes /* This file contains a generic conversion routine and implementation specific 9*8b6375c0SLois Curfman McInnes versions for increased efficiency. */ 10*8b6375c0SLois Curfman McInnes 11*8b6375c0SLois Curfman McInnes /* 12*8b6375c0SLois Curfman McInnes MatConvert_Basic - Converts from any input format to another format. For 13*8b6375c0SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 14*8b6375c0SLois Curfman McInnes */ 15*8b6375c0SLois Curfman McInnes int MatConvert_Basic(Mat mat,MatType newtype,Mat *M) 16*8b6375c0SLois Curfman McInnes { 17*8b6375c0SLois Curfman McInnes Scalar *vwork; 18*8b6375c0SLois Curfman McInnes int ierr, i, nz, m, n, *cwork, rstart, rend; 19*8b6375c0SLois Curfman McInnes ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr); 20*8b6375c0SLois Curfman McInnes switch (newtype) { 21*8b6375c0SLois Curfman McInnes case MATSEQAIJ: 22*8b6375c0SLois Curfman McInnes ierr = MatCreateSeqAIJ(mat->comm,m,n,0,0,M); CHKERRQ(ierr); 23*8b6375c0SLois Curfman McInnes break; 24*8b6375c0SLois Curfman McInnes case MATSEQROW: 25*8b6375c0SLois Curfman McInnes ierr = MatCreateSeqRow(mat->comm,m,n,0,0,M); CHKERRQ(ierr); 26*8b6375c0SLois Curfman McInnes break; 27*8b6375c0SLois Curfman McInnes case MATMPIROW: 28*8b6375c0SLois Curfman McInnes ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 29*8b6375c0SLois Curfman McInnes m,n,0,0,0,0,M); CHKERRQ(ierr); 30*8b6375c0SLois Curfman McInnes break; 31*8b6375c0SLois Curfman McInnes case MATMPIROWBS: 32*8b6375c0SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert:MATMPIROWBS matrix must be square"); 33*8b6375c0SLois Curfman McInnes ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,M); 34*8b6375c0SLois Curfman McInnes CHKERRQ(ierr); 35*8b6375c0SLois Curfman McInnes break; 36*8b6375c0SLois Curfman McInnes case MATMPIAIJ: 37*8b6375c0SLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 38*8b6375c0SLois Curfman McInnes m,n,0,0,0,0,M); CHKERRQ(ierr); 39*8b6375c0SLois Curfman McInnes break; 40*8b6375c0SLois Curfman McInnes case MATSEQDENSE: 41*8b6375c0SLois Curfman McInnes ierr = MatCreateSeqDense(mat->comm,m,n,M); CHKERRQ(ierr); 42*8b6375c0SLois Curfman McInnes break; 43*8b6375c0SLois Curfman McInnes case MATMPIDENSE: 44*8b6375c0SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 45*8b6375c0SLois Curfman McInnes m,n,M); CHKERRQ(ierr); 46*8b6375c0SLois Curfman McInnes break; 47*8b6375c0SLois Curfman McInnes case MATSEQBDIAG: 48*8b6375c0SLois Curfman McInnes { 49*8b6375c0SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 50*8b6375c0SLois Curfman McInnes OptionsGetInt(0,"-mat_bdiag_bsize",&nb); 51*8b6375c0SLois Curfman McInnes ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,0,0,M); CHKERRQ(ierr); 52*8b6375c0SLois Curfman McInnes break; 53*8b6375c0SLois Curfman McInnes } 54*8b6375c0SLois Curfman McInnes case MATMPIBDIAG: 55*8b6375c0SLois Curfman McInnes { 56*8b6375c0SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 57*8b6375c0SLois Curfman McInnes OptionsGetInt(0,"-mat_bdiag_bsize",&nb); 58*8b6375c0SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,M); 59*8b6375c0SLois Curfman McInnes CHKERRQ(ierr); 60*8b6375c0SLois Curfman McInnes break; 61*8b6375c0SLois Curfman McInnes } 62*8b6375c0SLois Curfman McInnes default: 63*8b6375c0SLois Curfman McInnes SETERRQ(1,"MatConvert:Matrix type is not currently supported"); 64*8b6375c0SLois Curfman McInnes } 65*8b6375c0SLois Curfman McInnes ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr); 66*8b6375c0SLois Curfman McInnes for (i=rstart; i<rend; i++) { 67*8b6375c0SLois Curfman McInnes ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 68*8b6375c0SLois Curfman McInnes ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 69*8b6375c0SLois Curfman McInnes ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 70*8b6375c0SLois Curfman McInnes } 71*8b6375c0SLois Curfman McInnes ierr = MatAssemblyBegin(*M,FINAL_ASSEMBLY); CHKERRQ(ierr); 72*8b6375c0SLois Curfman McInnes ierr = MatAssemblyEnd(*M,FINAL_ASSEMBLY); CHKERRQ(ierr); 73*8b6375c0SLois Curfman McInnes return 0; 74*8b6375c0SLois Curfman McInnes } 75*8b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */ 7656fe5c5cSLois Curfman McInnes /* 77ec8511deSBarry Smith MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For 7844ae05bdSLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 7956fe5c5cSLois Curfman McInnes */ 802399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B) 8156fe5c5cSLois Curfman McInnes { 822399e097SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 8356fe5c5cSLois Curfman McInnes Scalar *vwork; 842399e097SLois Curfman McInnes int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 8556fe5c5cSLois Curfman McInnes 8656fe5c5cSLois Curfman McInnes switch (newtype) { 87ec8511deSBarry Smith case MATSEQROW: 882399e097SLois Curfman McInnes ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr); 89416022c9SBarry Smith break; 9044ae05bdSLois Curfman McInnes case MATMPIROW: 9144ae05bdSLois Curfman McInnes ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 922399e097SLois Curfman McInnes m,n,0,0,0,0,B); CHKERRQ(ierr); 93416022c9SBarry Smith break; 94ec8511deSBarry Smith case MATMPIROWBS: 952399e097SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square"); 962399e097SLois Curfman McInnes ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr); 97416022c9SBarry Smith break; 9844ae05bdSLois Curfman McInnes case MATMPIAIJ: 9944ae05bdSLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 1002399e097SLois Curfman McInnes m,n,0,0,0,0,B); CHKERRQ(ierr); 101416022c9SBarry Smith break; 102ec8511deSBarry Smith case MATSEQDENSE: 1032399e097SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr); 1042399e097SLois Curfman McInnes break; 1052399e097SLois Curfman McInnes case MATMPIDENSE: 1062399e097SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 1072399e097SLois Curfman McInnes m,n,B); CHKERRQ(ierr); 108416022c9SBarry Smith break; 109ec8511deSBarry Smith case MATSEQBDIAG: 110416022c9SBarry Smith { 11158154824SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 112df60cc22SBarry Smith OptionsGetInt(0,"-mat_bdiag_bsize",&nb); 1132399e097SLois Curfman McInnes ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,0,0,B); CHKERRQ(ierr); 11444ae05bdSLois Curfman McInnes break; 11544ae05bdSLois Curfman McInnes } 11644ae05bdSLois Curfman McInnes case MATMPIBDIAG: 117416022c9SBarry Smith { 11858154824SLois Curfman McInnes int nb = 1; /* Default block size = 1 */ 11944ae05bdSLois Curfman McInnes OptionsGetInt(0,"-mat_bdiag_bsize",&nb); 1202399e097SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,B); 12178b31e54SBarry Smith CHKERRQ(ierr); 122416022c9SBarry Smith break; 12356fe5c5cSLois Curfman McInnes } 124f3ba505bSLois Curfman McInnes default: 125ec8511deSBarry Smith SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported"); 126f3ba505bSLois Curfman McInnes } 1272399e097SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 12844ae05bdSLois Curfman McInnes for (i=rstart; i<rend; i++) { 1292399e097SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 1302399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1312399e097SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 13256fe5c5cSLois Curfman McInnes } 1332399e097SLois Curfman McInnes ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 1342399e097SLois Curfman McInnes ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 13556fe5c5cSLois Curfman McInnes return 0; 13656fe5c5cSLois Curfman McInnes } 13756fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */ 13856fe5c5cSLois Curfman McInnes /* 1391fb19edaSLois Curfman McInnes MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another 14056fe5c5cSLois Curfman McInnes parallel format. 14156fe5c5cSLois Curfman McInnes */ 1422399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B) 14356fe5c5cSLois Curfman McInnes { 1442399e097SLois Curfman McInnes Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data; 1452399e097SLois Curfman McInnes Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data); 1462399e097SLois Curfman McInnes int ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork; 14756fe5c5cSLois Curfman McInnes Scalar *vwork; 14856fe5c5cSLois Curfman McInnes 14956fe5c5cSLois Curfman McInnes switch (newtype) { 1501fb19edaSLois Curfman McInnes case MATMPIROW: 1512399e097SLois Curfman McInnes ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen, 1522399e097SLois Curfman McInnes 0,Bd->ilen,B); CHKERRQ(ierr); 153abc0e9e4SLois Curfman McInnes break; 15456fe5c5cSLois Curfman McInnes default: 155bbb6d6a8SBarry Smith SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported"); 15656fe5c5cSLois Curfman McInnes } 157abc0e9e4SLois Curfman McInnes /* Each processor converts its local rows */ 15856fe5c5cSLois Curfman McInnes for (i=0; i<m; i++) { 15956fe5c5cSLois Curfman McInnes ig = i + rstart; 1602399e097SLois Curfman McInnes ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 1612399e097SLois Curfman McInnes ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 1622399e097SLois Curfman McInnes ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 16356fe5c5cSLois Curfman McInnes } 1642399e097SLois Curfman McInnes ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 1652399e097SLois Curfman McInnes ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 16656fe5c5cSLois Curfman McInnes return 0; 16756fe5c5cSLois Curfman McInnes } 168*8b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */ 169567e79a1SLois Curfman McInnes /* 170567e79a1SLois Curfman McInnes MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For 171567e79a1SLois Curfman McInnes parallel formats, the new matrix distribution is determined by PETSc. 172567e79a1SLois Curfman McInnes */ 173567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B) 174567e79a1SLois Curfman McInnes { 175567e79a1SLois Curfman McInnes Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data; 176*8b6375c0SLois Curfman McInnes Scalar *vwork, *vw2; 177567e79a1SLois Curfman McInnes int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 178*8b6375c0SLois Curfman McInnes int j, *cw2, ict; 179567e79a1SLois Curfman McInnes 180dad23ff5SLois Curfman McInnes /* rough over-estimate; could refine for individual rows */ 181dad23ff5SLois Curfman McInnes nz = PETSCMIN(n,a->nd*a->nb); 182567e79a1SLois Curfman McInnes switch (newtype) { 183567e79a1SLois Curfman McInnes case MATSEQAIJ: 184567e79a1SLois Curfman McInnes ierr = MatCreateSeqAIJ(A->comm,m,n,nz,0,B); CHKERRQ(ierr); 185567e79a1SLois Curfman McInnes break; 186567e79a1SLois Curfman McInnes case MATSEQROW: 187567e79a1SLois Curfman McInnes ierr = MatCreateSeqRow(A->comm,m,n,nz,0,B); CHKERRQ(ierr); 188567e79a1SLois Curfman McInnes break; 189567e79a1SLois Curfman McInnes case MATMPIROW: 190567e79a1SLois Curfman McInnes ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 191567e79a1SLois Curfman McInnes m,n,0,0,0,0,B); CHKERRQ(ierr); 192567e79a1SLois Curfman McInnes break; 193567e79a1SLois Curfman McInnes case MATMPIROWBS: 194567e79a1SLois Curfman McInnes if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square"); 195567e79a1SLois Curfman McInnes ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr); 196567e79a1SLois Curfman McInnes break; 197567e79a1SLois Curfman McInnes case MATMPIAIJ: 198567e79a1SLois Curfman McInnes ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 199567e79a1SLois Curfman McInnes m,n,0,0,0,0,B); CHKERRQ(ierr); 200567e79a1SLois Curfman McInnes break; 201567e79a1SLois Curfman McInnes case MATSEQDENSE: 202567e79a1SLois Curfman McInnes ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr); 203567e79a1SLois Curfman McInnes break; 204567e79a1SLois Curfman McInnes case MATMPIDENSE: 205567e79a1SLois Curfman McInnes ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 206567e79a1SLois Curfman McInnes m,n,B); CHKERRQ(ierr); 207567e79a1SLois Curfman McInnes break; 208567e79a1SLois Curfman McInnes case MATMPIBDIAG: 209567e79a1SLois Curfman McInnes { 210567e79a1SLois Curfman McInnes ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,0,0,B); 211567e79a1SLois Curfman McInnes CHKERRQ(ierr); 212567e79a1SLois Curfman McInnes break; 213567e79a1SLois Curfman McInnes } 214567e79a1SLois Curfman McInnes default: 215567e79a1SLois Curfman McInnes SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported"); 216567e79a1SLois Curfman McInnes } 217567e79a1SLois Curfman McInnes ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 218*8b6375c0SLois Curfman McInnes 219*8b6375c0SLois Curfman McInnes cw2 = (int *)PETSCMALLOC( n * sizeof(int) ); CHKPTRQ(cw2); 220*8b6375c0SLois Curfman McInnes vw2 = (Scalar *)PETSCMALLOC( n * sizeof(Scalar) ); CHKPTRQ(vw2); 221567e79a1SLois Curfman McInnes for (i=rstart; i<rend; i++) { 222567e79a1SLois Curfman McInnes ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 223*8b6375c0SLois Curfman McInnes ict = 0; /* strip out the zero elements ... is this what we really want? */ 224*8b6375c0SLois Curfman McInnes for (j=0; j<nz; j++) { 225*8b6375c0SLois Curfman McInnes if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;} 226*8b6375c0SLois Curfman McInnes } 227*8b6375c0SLois Curfman McInnes if (ict) 228*8b6375c0SLois Curfman McInnes {ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr);} 229567e79a1SLois Curfman McInnes ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 230567e79a1SLois Curfman McInnes } 231*8b6375c0SLois Curfman McInnes PETSCFREE(cw2); PETSCFREE(vw2); 232567e79a1SLois Curfman McInnes ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 233567e79a1SLois Curfman McInnes ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 234567e79a1SLois Curfman McInnes return 0; 235567e79a1SLois Curfman McInnes } 236