1 #ifndef lint 2 static char vcid[] = "$Id: convert.c,v 1.31 1995/10/27 01:11:01 curfman Exp curfman $"; 3 #endif 4 5 /* This file contains implementation-specific matrix conversion routines. 6 For now, this has been implemented only for AIJ. See MatConvert() for 7 generic conversion code. */ 8 9 #include "mpiaij.h" 10 11 /* 12 MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For 13 parallel formats, the new matrix distribution is determined by PETSc. 14 */ 15 int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B) 16 { 17 Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 18 Scalar *vwork; 19 int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 20 21 switch (newtype) { 22 case MATSEQROW: 23 ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr); 24 break; 25 case MATMPIROW: 26 ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 27 m,n,0,0,0,0,B); CHKERRQ(ierr); 28 break; 29 case MATMPIROWBS: 30 if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square"); 31 ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr); 32 break; 33 case MATMPIAIJ: 34 ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 35 m,n,0,0,0,0,B); CHKERRQ(ierr); 36 break; 37 case MATSEQDENSE: 38 ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr); 39 break; 40 case MATMPIDENSE: 41 ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 42 m,n,B); CHKERRQ(ierr); 43 break; 44 case MATSEQBDIAG: 45 { 46 int nb = 1; /* Default block size = 1 */ 47 OptionsGetInt(0,"-mat_bdiag_bsize",&nb); 48 ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,0,0,B); CHKERRQ(ierr); 49 break; 50 } 51 case MATMPIBDIAG: 52 { 53 int nb = 1; /* Default block size = 1 */ 54 OptionsGetInt(0,"-mat_bdiag_bsize",&nb); 55 ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,B); 56 CHKERRQ(ierr); 57 break; 58 } 59 default: 60 SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported"); 61 } 62 ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 63 for (i=rstart; i<rend; i++) { 64 ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 65 ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 66 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 67 } 68 ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 69 ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 70 return 0; 71 } 72 /* ------------------------------------------------------------------ */ 73 /* 74 MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another 75 parallel format. 76 */ 77 int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B) 78 { 79 Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data; 80 Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data); 81 int ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork; 82 Scalar *vwork; 83 84 switch (newtype) { 85 case MATMPIROW: 86 ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen, 87 0,Bd->ilen,B); CHKERRQ(ierr); 88 break; 89 default: 90 SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported"); 91 } 92 /* Each processor converts its local rows */ 93 for (i=0; i<m; i++) { 94 ig = i + rstart; 95 ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 96 ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 97 ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr); 98 } 99 ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 100 ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 101 return 0; 102 } 103 104 #include "mpibdiag.h" 105 106 /* 107 MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For 108 parallel formats, the new matrix distribution is determined by PETSc. 109 */ 110 int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B) 111 { 112 Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data; 113 Scalar *vwork; 114 int i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend; 115 116 /* rough over-estimate; could refine for individual rows */ 117 nz = PETSCMIN(n,a->nd*a->nb); 118 switch (newtype) { 119 case MATSEQAIJ: 120 ierr = MatCreateSeqAIJ(A->comm,m,n,nz,0,B); CHKERRQ(ierr); 121 break; 122 case MATSEQROW: 123 ierr = MatCreateSeqRow(A->comm,m,n,nz,0,B); CHKERRQ(ierr); 124 break; 125 case MATMPIROW: 126 ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 127 m,n,0,0,0,0,B); CHKERRQ(ierr); 128 break; 129 case MATMPIROWBS: 130 if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square"); 131 ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr); 132 break; 133 case MATMPIAIJ: 134 ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 135 m,n,0,0,0,0,B); CHKERRQ(ierr); 136 break; 137 case MATSEQDENSE: 138 ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr); 139 break; 140 case MATMPIDENSE: 141 ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE, 142 m,n,B); CHKERRQ(ierr); 143 break; 144 case MATMPIBDIAG: 145 { 146 ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,0,0,B); 147 CHKERRQ(ierr); 148 break; 149 } 150 default: 151 SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported"); 152 } 153 ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr); 154 for (i=rstart; i<rend; i++) { 155 ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 156 ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr); 157 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 158 } 159 ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 160 ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr); 161 return 0; 162 } 163