1 2 static char help[] = "Tests the use of interface functions for MATIS matrices.\n\ 3 This example tests: MatZeroRows(), MatZeroRowsLocal(), MatView(), MatDuplicate(),\n\ 4 MatCopy(), MatCreateSubMatrix(), MatGetLocalSubMatrix(), MatAXPY(), MatShift()\n\ 5 MatDiagonalSet(), MatTranspose() and MatPtAP(). It also tests some\n\ 6 conversion routines.\n"; 7 8 #include <petscmat.h> 9 10 PetscErrorCode TestMatZeroRows(Mat,Mat,PetscBool,IS,PetscScalar); 11 PetscErrorCode CheckMat(Mat,Mat,PetscBool,const char*); 12 13 int main(int argc,char **args) 14 { 15 Mat A,B,A2,B2,T; 16 Mat Aee,Aeo,Aoe,Aoo; 17 Mat *mats; 18 Vec x,y; 19 MatInfo info; 20 ISLocalToGlobalMapping cmap,rmap; 21 IS is,is2,reven,rodd,ceven,codd; 22 IS *rows,*cols; 23 MatType lmtype; 24 PetscScalar diag = 2.; 25 PetscInt n,m,i; 26 PetscInt rst,ren,cst,cen,nr,nc; 27 PetscMPIInt rank,size; 28 PetscBool testT,squaretest,isaij; 29 PetscBool permute = PETSC_FALSE; 30 PetscBool diffmap = PETSC_TRUE, symmetric = PETSC_FALSE; 31 PetscErrorCode ierr; 32 33 ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; 34 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 35 ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr); 36 m = n = 2*size; 37 ierr = PetscOptionsGetBool(NULL,NULL,"-symmetric",&symmetric,NULL);CHKERRQ(ierr); 38 ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr); 39 ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); 40 if (size > 1 && m < 4) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Number of rows should be larger or equal 4 for parallel runs"); 41 if (size == 1 && m < 2) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Number of rows should be larger or equal 2 for uniprocessor runs"); 42 if (n < 2) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Number of cols should be larger or equal 2"); 43 if (symmetric) m = n = PetscMax(m,n); 44 45 /* create a MATIS matrix */ 46 ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); 47 ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); 48 ierr = MatSetType(A,MATIS);CHKERRQ(ierr); 49 ierr = MatSetFromOptions(A);CHKERRQ(ierr); 50 /* This is not the proper setting for MATIS for finite elements, it is just used to test the routines */ 51 ierr = ISCreateStride(PETSC_COMM_WORLD,n,0,1,&is);CHKERRQ(ierr); 52 ierr = ISLocalToGlobalMappingCreateIS(is,&cmap);CHKERRQ(ierr); 53 ierr = ISDestroy(&is);CHKERRQ(ierr); 54 55 ierr = PetscOptionsGetBool(NULL,NULL,"-permmap",&permute,NULL);CHKERRQ(ierr); 56 ierr = PetscOptionsGetBool(NULL,NULL,"-diffmap",&diffmap,NULL);CHKERRQ(ierr); 57 if (!symmetric && (diffmap || m != n)) { 58 59 ierr = ISCreateStride(PETSC_COMM_WORLD,m,permute ? m -1 : 0,permute ? -1 : 1,&is);CHKERRQ(ierr); 60 ierr = ISLocalToGlobalMappingCreateIS(is,&rmap);CHKERRQ(ierr); 61 ierr = ISDestroy(&is);CHKERRQ(ierr); 62 if (m==n && !permute) squaretest = PETSC_TRUE; 63 else squaretest = PETSC_FALSE; 64 } else { 65 ierr = PetscObjectReference((PetscObject)cmap);CHKERRQ(ierr); 66 rmap = cmap; 67 squaretest = PETSC_TRUE; 68 } 69 ierr = MatSetLocalToGlobalMapping(A,rmap,cmap);CHKERRQ(ierr); 70 ierr = MatISStoreL2L(A,PETSC_FALSE);CHKERRQ(ierr); 71 ierr = MatISSetPreallocation(A,3,NULL,0,NULL);CHKERRQ(ierr); 72 for (i=0; i<m; i++) { 73 PetscScalar v[3]; 74 PetscInt cols[3]; 75 76 cols[0] = (i-1+n)%n; 77 cols[1] = i%n; 78 cols[2] = (i+1)%n; 79 v[0] = -1.*(symmetric ? PetscMin(i+1,cols[0]+1) : i+1); 80 v[1] = 2.*(symmetric ? PetscMin(i+1,cols[1]+1) : i+1); 81 v[2] = -1.*(symmetric ? PetscMin(i+1,cols[2]+1) : i+1); 82 ierr = MatSetValuesLocal(A,1,&i,3,cols,v,ADD_VALUES);CHKERRQ(ierr); 83 } 84 if (symmetric) { 85 ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 86 } 87 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 88 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 89 90 ierr = MatISGetLocalMat(A,&B);CHKERRQ(ierr); 91 ierr = MatGetType(B,&lmtype);CHKERRQ(ierr); 92 93 /* test MatGetInfo */ 94 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatGetInfo\n");CHKERRQ(ierr); 95 if (!PetscGlobalRank) { 96 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 97 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 98 } 99 ierr = MatGetInfo(A,MAT_LOCAL,&info);CHKERRQ(ierr); 100 ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 101 ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"Process %2d: %D %D %D %D %D\n",PetscGlobalRank,(PetscInt)info.nz_used, 102 (PetscInt)info.nz_allocated,(PetscInt)info.nz_unneeded,(PetscInt)info.assemblies,(PetscInt)info.mallocs);CHKERRQ(ierr); 103 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 104 ierr = MatGetInfo(A,MAT_GLOBAL_MAX,&info);CHKERRQ(ierr); 105 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"GlobalMax : %D %D %D %D %D\n",(PetscInt)info.nz_used, 106 (PetscInt)info.nz_allocated,(PetscInt)info.nz_unneeded,(PetscInt)info.assemblies,(PetscInt)info.mallocs);CHKERRQ(ierr); 107 ierr = MatGetInfo(A,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 108 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"GlobalSum : %D %D %D %D %D\n",(PetscInt)info.nz_used, 109 (PetscInt)info.nz_allocated,(PetscInt)info.nz_unneeded,(PetscInt)info.assemblies,(PetscInt)info.mallocs);CHKERRQ(ierr); 110 111 /* test MatView */ 112 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatView\n");CHKERRQ(ierr); 113 ierr = MatView(A,NULL);CHKERRQ(ierr); 114 115 /* Create a MPIAIJ matrix, same as A */ 116 ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); 117 ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); 118 ierr = MatSetType(B,MATAIJ);CHKERRQ(ierr); 119 ierr = MatSetFromOptions(B);CHKERRQ(ierr); 120 ierr = MatSetUp(B);CHKERRQ(ierr); 121 ierr = MatSetLocalToGlobalMapping(B,rmap,cmap);CHKERRQ(ierr); 122 ierr = MatMPIAIJSetPreallocation(B,3,NULL,3,NULL);CHKERRQ(ierr); 123 ierr = MatMPIBAIJSetPreallocation(B,1,3,NULL,3,NULL);CHKERRQ(ierr); 124 #if defined(PETSC_HAVE_HYPRE) 125 ierr = MatHYPRESetPreallocation(B,3,NULL,3,NULL);CHKERRQ(ierr); 126 #endif 127 ierr = MatISSetPreallocation(B,3,NULL,3,NULL);CHKERRQ(ierr); 128 for (i=0; i<m; i++) { 129 PetscScalar v[3]; 130 PetscInt cols[3]; 131 132 cols[0] = (i-1+n)%n; 133 cols[1] = i%n; 134 cols[2] = (i+1)%n; 135 v[0] = -1.*(symmetric ? PetscMin(i+1,cols[0]+1) : i+1); 136 v[1] = 2.*(symmetric ? PetscMin(i+1,cols[1]+1) : i+1); 137 v[2] = -1.*(symmetric ? PetscMin(i+1,cols[2]+1) : i+1); 138 ierr = MatSetValuesLocal(B,1,&i,3,cols,v,ADD_VALUES);CHKERRQ(ierr); 139 } 140 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 141 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 142 ierr = ISLocalToGlobalMappingDestroy(&cmap);CHKERRQ(ierr); 143 ierr = ISLocalToGlobalMappingDestroy(&rmap);CHKERRQ(ierr); 144 145 /* test CheckMat */ 146 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test CheckMat\n");CHKERRQ(ierr); 147 ierr = CheckMat(A,B,PETSC_FALSE,"CheckMat");CHKERRQ(ierr); 148 149 /* test MatDuplicate and MatAXPY */ 150 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatDuplicate and MatAXPY\n");CHKERRQ(ierr); 151 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 152 ierr = CheckMat(A,A2,PETSC_FALSE,"MatDuplicate and MatAXPY");CHKERRQ(ierr); 153 154 /* test MatConvert */ 155 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatConvert_IS_XAIJ\n");CHKERRQ(ierr); 156 ierr = MatConvert(A2,MATAIJ,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr); 157 ierr = CheckMat(B,B2,PETSC_TRUE,"MatConvert_IS_XAIJ MAT_INITIAL_MATRIX");CHKERRQ(ierr); 158 ierr = MatConvert(A2,MATAIJ,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr); 159 ierr = CheckMat(B,B2,PETSC_TRUE,"MatConvert_IS_XAIJ MAT_REUSE_MATRIX");CHKERRQ(ierr); 160 ierr = MatConvert(A2,MATAIJ,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 161 ierr = CheckMat(B,A2,PETSC_TRUE,"MatConvert_IS_XAIJ MAT_INPLACE_MATRIX");CHKERRQ(ierr); 162 ierr = MatDestroy(&A2);CHKERRQ(ierr); 163 ierr = MatDestroy(&B2);CHKERRQ(ierr); 164 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatConvert_XAIJ_IS\n");CHKERRQ(ierr); 165 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 166 ierr = MatConvert(B2,MATIS,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr); 167 ierr = CheckMat(A,A2,PETSC_TRUE,"MatConvert_XAIJ_IS MAT_INITIAL_MATRIX");CHKERRQ(ierr); 168 ierr = MatConvert(B2,MATIS,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr); 169 ierr = CheckMat(A,A2,PETSC_TRUE,"MatConvert_XAIJ_IS MAT_REUSE_MATRIX");CHKERRQ(ierr); 170 ierr = MatConvert(B2,MATIS,MAT_INPLACE_MATRIX,&B2);CHKERRQ(ierr); 171 ierr = CheckMat(A,B2,PETSC_TRUE,"MatConvert_XAIJ_IS MAT_INPLACE_MATRIX");CHKERRQ(ierr); 172 ierr = MatDestroy(&A2);CHKERRQ(ierr); 173 ierr = MatDestroy(&B2);CHKERRQ(ierr); 174 ierr = PetscStrcmp(lmtype,MATSEQAIJ,&isaij);CHKERRQ(ierr); 175 if (size == 1 && isaij) { /* tests special code paths in MatConvert_IS_XAIJ */ 176 PetscInt ri, ci, rr[3] = {0,1,0}, cr[4] = {1,2,0,1}, rk[3] = {0,2,1}, ck[4] = {1,0,3,2}; 177 178 for (ri = 0; ri < 2; ri++) { 179 PetscInt *r; 180 181 r = (PetscInt*)(ri == 0 ? rr : rk); 182 for (ci = 0; ci < 2; ci++) { 183 PetscInt *c,rb,cb; 184 185 c = (PetscInt*)(ci == 0 ? cr : ck); 186 for (rb = 1; rb < 4; rb++) { 187 ierr = ISCreateBlock(PETSC_COMM_SELF,rb,3,r,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 188 ierr = ISLocalToGlobalMappingCreateIS(is,&rmap);CHKERRQ(ierr); 189 ierr = ISDestroy(&is);CHKERRQ(ierr); 190 for (cb = 1; cb < 4; cb++) { 191 Mat T,lT,T2; 192 char testname[256]; 193 194 ierr = PetscSNPrintf(testname,sizeof(testname),"MatConvert_IS_XAIJ special case (%D %D, bs %D %D)",ri,ci,rb,cb);CHKERRQ(ierr); 195 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test %s\n",testname);CHKERRQ(ierr); 196 197 ierr = ISCreateBlock(PETSC_COMM_SELF,cb,4,c,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 198 ierr = ISLocalToGlobalMappingCreateIS(is,&cmap);CHKERRQ(ierr); 199 ierr = ISDestroy(&is);CHKERRQ(ierr); 200 201 ierr = MatCreate(PETSC_COMM_SELF,&T);CHKERRQ(ierr); 202 ierr = MatSetSizes(T,PETSC_DECIDE,PETSC_DECIDE,rb*3,cb*4);CHKERRQ(ierr); 203 ierr = MatSetType(T,MATIS);CHKERRQ(ierr); 204 ierr = MatSetLocalToGlobalMapping(T,rmap,cmap);CHKERRQ(ierr); 205 ierr = ISLocalToGlobalMappingDestroy(&cmap);CHKERRQ(ierr); 206 ierr = MatISGetLocalMat(T,&lT);CHKERRQ(ierr); 207 ierr = MatSetType(lT,MATSEQAIJ);CHKERRQ(ierr); 208 ierr = MatSeqAIJSetPreallocation(lT,cb*4,NULL);CHKERRQ(ierr); 209 ierr = MatSetRandom(lT,NULL);CHKERRQ(ierr); 210 ierr = MatConvert(lT,lmtype,MAT_INPLACE_MATRIX,&lT);CHKERRQ(ierr); 211 ierr = MatISRestoreLocalMat(T,&lT);CHKERRQ(ierr); 212 ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 213 ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 214 215 ierr = MatConvert(T,MATAIJ,MAT_INITIAL_MATRIX,&T2);CHKERRQ(ierr); 216 ierr = CheckMat(T,T2,PETSC_TRUE,"MAT_INITIAL_MATRIX");CHKERRQ(ierr); 217 ierr = MatConvert(T,MATAIJ,MAT_REUSE_MATRIX,&T2);CHKERRQ(ierr); 218 ierr = CheckMat(T,T2,PETSC_TRUE,"MAT_REUSE_MATRIX");CHKERRQ(ierr); 219 ierr = MatDestroy(&T2);CHKERRQ(ierr); 220 ierr = MatDuplicate(T,MAT_COPY_VALUES,&T2);CHKERRQ(ierr); 221 ierr = MatConvert(T2,MATAIJ,MAT_INPLACE_MATRIX,&T2);CHKERRQ(ierr); 222 ierr = CheckMat(T,T2,PETSC_TRUE,"MAT_INPLACE_MATRIX");CHKERRQ(ierr); 223 ierr = MatDestroy(&T);CHKERRQ(ierr); 224 ierr = MatDestroy(&T2);CHKERRQ(ierr); 225 } 226 ierr = ISLocalToGlobalMappingDestroy(&rmap);CHKERRQ(ierr); 227 } 228 } 229 } 230 } 231 232 /* test MatDiagonalScale */ 233 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatDiagonalScale\n");CHKERRQ(ierr); 234 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 235 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 236 ierr = MatCreateVecs(A,&x,&y);CHKERRQ(ierr); 237 ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 238 if (symmetric) { 239 ierr = VecCopy(x,y);CHKERRQ(ierr); 240 } else { 241 ierr = VecSetRandom(y,NULL);CHKERRQ(ierr); 242 ierr = VecScale(y,8.);CHKERRQ(ierr); 243 } 244 ierr = MatDiagonalScale(A2,y,x);CHKERRQ(ierr); 245 ierr = MatDiagonalScale(B2,y,x);CHKERRQ(ierr); 246 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatDiagonalScale");CHKERRQ(ierr); 247 ierr = MatDestroy(&A2);CHKERRQ(ierr); 248 ierr = MatDestroy(&B2);CHKERRQ(ierr); 249 ierr = VecDestroy(&x);CHKERRQ(ierr); 250 ierr = VecDestroy(&y);CHKERRQ(ierr); 251 252 /* test MatPtAP (A IS and B AIJ) */ 253 if (isaij && m == n) { 254 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatPtAP\n");CHKERRQ(ierr); 255 ierr = MatISStoreL2L(A,PETSC_TRUE);CHKERRQ(ierr); 256 ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&A2);CHKERRQ(ierr); 257 ierr = MatPtAP(B,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B2);CHKERRQ(ierr); 258 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatPtAP MAT_INITIAL_MATRIX");CHKERRQ(ierr); 259 ierr = MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&A2);CHKERRQ(ierr); 260 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatPtAP MAT_REUSE_MATRIX");CHKERRQ(ierr); 261 ierr = MatDestroy(&A2);CHKERRQ(ierr); 262 ierr = MatDestroy(&B2);CHKERRQ(ierr); 263 } 264 265 /* test MatGetLocalSubMatrix */ 266 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatGetLocalSubMatrix\n");CHKERRQ(ierr); 267 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&A2);CHKERRQ(ierr); 268 ierr = ISCreateStride(PETSC_COMM_WORLD,m/2+m%2,0,2,&reven);CHKERRQ(ierr); 269 ierr = ISCreateStride(PETSC_COMM_WORLD,m/2,1,2,&rodd);CHKERRQ(ierr); 270 ierr = ISCreateStride(PETSC_COMM_WORLD,n/2+n%2,0,2,&ceven);CHKERRQ(ierr); 271 ierr = ISCreateStride(PETSC_COMM_WORLD,n/2,1,2,&codd);CHKERRQ(ierr); 272 ierr = MatGetLocalSubMatrix(A2,reven,ceven,&Aee);CHKERRQ(ierr); 273 ierr = MatGetLocalSubMatrix(A2,reven,codd,&Aeo);CHKERRQ(ierr); 274 ierr = MatGetLocalSubMatrix(A2,rodd,ceven,&Aoe);CHKERRQ(ierr); 275 ierr = MatGetLocalSubMatrix(A2,rodd,codd,&Aoo);CHKERRQ(ierr); 276 for (i=0; i<m; i++) { 277 PetscInt j,je,jo,colse[3], colso[3]; 278 PetscScalar ve[3], vo[3]; 279 PetscScalar v[3]; 280 PetscInt cols[3]; 281 282 cols[0] = (i-1+n)%n; 283 cols[1] = i%n; 284 cols[2] = (i+1)%n; 285 v[0] = -1.*(symmetric ? PetscMin(i+1,cols[0]+1) : i+1); 286 v[1] = 2.*(symmetric ? PetscMin(i+1,cols[1]+1) : i+1); 287 v[2] = -1.*(symmetric ? PetscMin(i+1,cols[2]+1) : i+1); 288 for (j=0,je=0,jo=0;j<3;j++) { 289 if (cols[j]%2) { 290 vo[jo] = v[j]; 291 colso[jo++] = cols[j]/2; 292 } else { 293 ve[je] = v[j]; 294 colse[je++] = cols[j]/2; 295 } 296 } 297 if (i%2) { 298 PetscInt row = i/2; 299 ierr = MatSetValuesLocal(Aoe,1,&row,je,colse,ve,ADD_VALUES);CHKERRQ(ierr); 300 ierr = MatSetValuesLocal(Aoo,1,&row,jo,colso,vo,ADD_VALUES);CHKERRQ(ierr); 301 } else { 302 PetscInt row = i/2; 303 ierr = MatSetValuesLocal(Aee,1,&row,je,colse,ve,ADD_VALUES);CHKERRQ(ierr); 304 ierr = MatSetValuesLocal(Aeo,1,&row,jo,colso,vo,ADD_VALUES);CHKERRQ(ierr); 305 } 306 } 307 ierr = MatRestoreLocalSubMatrix(A2,reven,ceven,&Aee);CHKERRQ(ierr); 308 ierr = MatRestoreLocalSubMatrix(A2,reven,codd,&Aeo);CHKERRQ(ierr); 309 ierr = MatRestoreLocalSubMatrix(A2,rodd,ceven,&Aoe);CHKERRQ(ierr); 310 ierr = MatRestoreLocalSubMatrix(A2,rodd,codd,&Aoo);CHKERRQ(ierr); 311 ierr = ISDestroy(&reven);CHKERRQ(ierr); 312 ierr = ISDestroy(&ceven);CHKERRQ(ierr); 313 ierr = ISDestroy(&rodd);CHKERRQ(ierr); 314 ierr = ISDestroy(&codd);CHKERRQ(ierr); 315 ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 316 ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 317 ierr = MatAXPY(A2,-1.,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 318 ierr = CheckMat(A2,NULL,PETSC_FALSE,"MatGetLocalSubMatrix");CHKERRQ(ierr); 319 ierr = MatDestroy(&A2);CHKERRQ(ierr); 320 321 /* test MatConvert_Nest_IS */ 322 testT = PETSC_FALSE; 323 ierr = PetscOptionsGetBool(NULL,NULL,"-test_trans",&testT,NULL);CHKERRQ(ierr); 324 325 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatConvert_Nest_IS\n");CHKERRQ(ierr); 326 nr = 2; 327 nc = 2; 328 ierr = PetscOptionsGetInt(NULL,NULL,"-nr",&nr,NULL);CHKERRQ(ierr); 329 ierr = PetscOptionsGetInt(NULL,NULL,"-nc",&nc,NULL);CHKERRQ(ierr); 330 if (testT) { 331 ierr = MatGetOwnershipRange(A,&cst,&cen);CHKERRQ(ierr); 332 ierr = MatGetOwnershipRangeColumn(A,&rst,&ren);CHKERRQ(ierr); 333 } else { 334 ierr = MatGetOwnershipRange(A,&rst,&ren);CHKERRQ(ierr); 335 ierr = MatGetOwnershipRangeColumn(A,&cst,&cen);CHKERRQ(ierr); 336 } 337 ierr = PetscMalloc3(nr,&rows,nc,&cols,2*nr*nc,&mats);CHKERRQ(ierr); 338 for (i=0;i<nr*nc;i++) { 339 if (testT) { 340 ierr = MatCreateTranspose(A,&mats[i]);CHKERRQ(ierr); 341 ierr = MatTranspose(B,MAT_INITIAL_MATRIX,&mats[i+nr*nc]);CHKERRQ(ierr); 342 } else { 343 ierr = MatDuplicate(A,MAT_COPY_VALUES,&mats[i]);CHKERRQ(ierr); 344 ierr = MatDuplicate(B,MAT_COPY_VALUES,&mats[i+nr*nc]);CHKERRQ(ierr); 345 } 346 } 347 for (i=0;i<nr;i++) { 348 ierr = ISCreateStride(PETSC_COMM_WORLD,ren-rst,i+rst,nr,&rows[i]);CHKERRQ(ierr); 349 } 350 for (i=0;i<nc;i++) { 351 ierr = ISCreateStride(PETSC_COMM_WORLD,cen-cst,i+cst,nc,&cols[i]);CHKERRQ(ierr); 352 } 353 ierr = MatCreateNest(PETSC_COMM_WORLD,nr,rows,nc,cols,mats,&A2);CHKERRQ(ierr); 354 ierr = MatCreateNest(PETSC_COMM_WORLD,nr,rows,nc,cols,mats+nr*nc,&B2);CHKERRQ(ierr); 355 for (i=0;i<nr;i++) { 356 ierr = ISDestroy(&rows[i]);CHKERRQ(ierr); 357 } 358 for (i=0;i<nc;i++) { 359 ierr = ISDestroy(&cols[i]);CHKERRQ(ierr); 360 } 361 for (i=0;i<2*nr*nc;i++) { 362 ierr = MatDestroy(&mats[i]);CHKERRQ(ierr); 363 } 364 ierr = PetscFree3(rows,cols,mats);CHKERRQ(ierr); 365 ierr = MatConvert(B2,MATAIJ,MAT_INITIAL_MATRIX,&T);CHKERRQ(ierr); 366 ierr = MatDestroy(&B2);CHKERRQ(ierr); 367 ierr = MatConvert(A2,MATIS,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr); 368 ierr = CheckMat(B2,T,PETSC_TRUE,"MatConvert_Nest_IS MAT_INITIAL_MATRIX");CHKERRQ(ierr); 369 ierr = MatConvert(A2,MATIS,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr); 370 ierr = CheckMat(B2,T,PETSC_TRUE,"MatConvert_Nest_IS MAT_REUSE_MATRIX");CHKERRQ(ierr); 371 ierr = MatDestroy(&B2);CHKERRQ(ierr); 372 ierr = MatConvert(A2,MATIS,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 373 ierr = CheckMat(A2,T,PETSC_TRUE,"MatConvert_Nest_IS MAT_INPLACE_MATRIX");CHKERRQ(ierr); 374 ierr = MatDestroy(&T);CHKERRQ(ierr); 375 ierr = MatDestroy(&A2);CHKERRQ(ierr); 376 377 /* test MatCreateSubMatrix */ 378 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatCreateSubMatrix\n");CHKERRQ(ierr); 379 if (rank == 0) { 380 ierr = ISCreateStride(PETSC_COMM_WORLD,1,1,1,&is);CHKERRQ(ierr); 381 ierr = ISCreateStride(PETSC_COMM_WORLD,2,0,1,&is2);CHKERRQ(ierr); 382 } else if (rank == 1) { 383 ierr = ISCreateStride(PETSC_COMM_WORLD,1,0,1,&is);CHKERRQ(ierr); 384 if (n > 3) { 385 ierr = ISCreateStride(PETSC_COMM_WORLD,1,3,1,&is2);CHKERRQ(ierr); 386 } else { 387 ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is2);CHKERRQ(ierr); 388 } 389 } else if (rank == 2 && n > 4) { 390 ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is);CHKERRQ(ierr); 391 ierr = ISCreateStride(PETSC_COMM_WORLD,n-4,4,1,&is2);CHKERRQ(ierr); 392 } else { 393 ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is);CHKERRQ(ierr); 394 ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is2);CHKERRQ(ierr); 395 } 396 ierr = MatCreateSubMatrix(A,is,is,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr); 397 ierr = MatCreateSubMatrix(B,is,is,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr); 398 ierr = CheckMat(A2,B2,PETSC_TRUE,"first MatCreateSubMatrix");CHKERRQ(ierr); 399 400 ierr = MatCreateSubMatrix(A,is,is,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr); 401 ierr = MatCreateSubMatrix(B,is,is,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr); 402 ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse MatCreateSubMatrix");CHKERRQ(ierr); 403 ierr = MatDestroy(&A2);CHKERRQ(ierr); 404 ierr = MatDestroy(&B2);CHKERRQ(ierr); 405 406 if (!symmetric) { 407 ierr = MatCreateSubMatrix(A,is,is2,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr); 408 ierr = MatCreateSubMatrix(B,is,is2,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr); 409 ierr = MatCreateSubMatrix(A,is,is2,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr); 410 ierr = MatCreateSubMatrix(B,is,is2,MAT_REUSE_MATRIX,&B2);CHKERRQ(ierr); 411 ierr = CheckMat(A2,B2,PETSC_FALSE,"second MatCreateSubMatrix");CHKERRQ(ierr); 412 } 413 414 ierr = MatDestroy(&A2);CHKERRQ(ierr); 415 ierr = MatDestroy(&B2);CHKERRQ(ierr); 416 ierr = ISDestroy(&is);CHKERRQ(ierr); 417 ierr = ISDestroy(&is2);CHKERRQ(ierr); 418 419 /* Create an IS required by MatZeroRows(): just rank zero provides the rows to be eliminated */ 420 if (size > 1) { 421 if (rank == 0) { 422 PetscInt st,len; 423 424 st = (m+1)/2; 425 len = PetscMin(m/2,PetscMax(m-(m+1)/2-1,0)); 426 ierr = ISCreateStride(PETSC_COMM_WORLD,len,st,1,&is);CHKERRQ(ierr); 427 } else { 428 ierr = ISCreateStride(PETSC_COMM_WORLD,0,0,1,&is);CHKERRQ(ierr); 429 } 430 } else { 431 ierr = ISCreateStride(PETSC_COMM_WORLD,1,0,1,&is);CHKERRQ(ierr); 432 } 433 434 if (squaretest) { /* tests for square matrices only, with same maps for rows and columns */ 435 /* test MatDiagonalSet */ 436 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatDiagonalSet\n");CHKERRQ(ierr); 437 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 438 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 439 ierr = MatCreateVecs(A,NULL,&x);CHKERRQ(ierr); 440 ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 441 ierr = MatDiagonalSet(A2,x,INSERT_VALUES);CHKERRQ(ierr); 442 ierr = MatDiagonalSet(B2,x,INSERT_VALUES);CHKERRQ(ierr); 443 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatDiagonalSet");CHKERRQ(ierr); 444 ierr = VecDestroy(&x);CHKERRQ(ierr); 445 ierr = MatDestroy(&A2);CHKERRQ(ierr); 446 ierr = MatDestroy(&B2);CHKERRQ(ierr); 447 448 /* test MatShift (MatShift_IS internally uses MatDiagonalSet_IS with ADD_VALUES) */ 449 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatShift\n");CHKERRQ(ierr); 450 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 451 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 452 ierr = MatShift(A2,2.0);CHKERRQ(ierr); 453 ierr = MatShift(B2,2.0);CHKERRQ(ierr); 454 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatShift");CHKERRQ(ierr); 455 ierr = MatDestroy(&A2);CHKERRQ(ierr); 456 ierr = MatDestroy(&B2);CHKERRQ(ierr); 457 458 /* nonzero diag value is supported for square matrices only */ 459 ierr = TestMatZeroRows(A,B,PETSC_TRUE,is,diag);CHKERRQ(ierr); 460 } 461 ierr = TestMatZeroRows(A,B,squaretest,is,0.0);CHKERRQ(ierr); 462 ierr = ISDestroy(&is);CHKERRQ(ierr); 463 464 /* test MatTranspose */ 465 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatTranspose\n");CHKERRQ(ierr); 466 ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr); 467 ierr = MatTranspose(B,MAT_INITIAL_MATRIX,&B2);CHKERRQ(ierr); 468 ierr = CheckMat(A2,B2,PETSC_FALSE,"initial matrix MatTranspose");CHKERRQ(ierr); 469 470 ierr = MatTranspose(A,MAT_REUSE_MATRIX,&A2);CHKERRQ(ierr); 471 ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse matrix (not in place) MatTranspose");CHKERRQ(ierr); 472 ierr = MatDestroy(&A2);CHKERRQ(ierr); 473 474 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 475 ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 476 ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse matrix (in place) MatTranspose");CHKERRQ(ierr); 477 ierr = MatDestroy(&A2);CHKERRQ(ierr); 478 479 ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&A2);CHKERRQ(ierr); 480 ierr = CheckMat(A2,B2,PETSC_FALSE,"reuse matrix (different type) MatTranspose");CHKERRQ(ierr); 481 ierr = MatDestroy(&A2);CHKERRQ(ierr); 482 ierr = MatDestroy(&B2);CHKERRQ(ierr); 483 484 /* test MatISFixLocalEmpty */ 485 if (isaij) { 486 PetscInt r[2]; 487 488 r[0] = 0; 489 r[1] = PetscMin(m,n)-1; 490 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatISFixLocalEmpty\n");CHKERRQ(ierr); 491 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 492 ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr); 493 ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 494 ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 495 ierr = CheckMat(A2,B,PETSC_FALSE,"MatISFixLocalEmpty (null)");CHKERRQ(ierr); 496 497 ierr = MatZeroRows(A2,2,r,0.0,NULL,NULL);CHKERRQ(ierr); 498 ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr); 499 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 500 ierr = MatZeroRows(B2,2,r,0.0,NULL,NULL);CHKERRQ(ierr); 501 ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr); 502 ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 503 ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 504 ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr); 505 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatISFixLocalEmpty (rows)");CHKERRQ(ierr); 506 ierr = MatDestroy(&A2);CHKERRQ(ierr); 507 508 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 509 ierr = MatZeroRows(A2,2,r,0.0,NULL,NULL);CHKERRQ(ierr); 510 ierr = MatTranspose(A2,MAT_INPLACE_MATRIX,&A2);CHKERRQ(ierr); 511 ierr = MatTranspose(B2,MAT_INPLACE_MATRIX,&B2);CHKERRQ(ierr); 512 ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr); 513 ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr); 514 ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 515 ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 516 ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr); 517 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatISFixLocalEmpty (cols)");CHKERRQ(ierr); 518 519 ierr = MatDestroy(&A2);CHKERRQ(ierr); 520 ierr = MatDestroy(&B2);CHKERRQ(ierr); 521 522 if (squaretest) { 523 ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); 524 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 525 ierr = MatZeroRowsColumns(A2,2,r,0.0,NULL,NULL);CHKERRQ(ierr); 526 ierr = MatZeroRowsColumns(B2,2,r,0.0,NULL,NULL);CHKERRQ(ierr); 527 ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr); 528 ierr = MatISFixLocalEmpty(A2,PETSC_TRUE);CHKERRQ(ierr); 529 ierr = MatAssemblyBegin(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 530 ierr = MatAssemblyEnd(A2,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 531 ierr = MatViewFromOptions(A2,NULL,"-fixempty_view");CHKERRQ(ierr); 532 ierr = CheckMat(A2,B2,PETSC_FALSE,"MatISFixLocalEmpty (rows+cols)");CHKERRQ(ierr); 533 ierr = MatDestroy(&A2);CHKERRQ(ierr); 534 ierr = MatDestroy(&B2);CHKERRQ(ierr); 535 } 536 537 } 538 539 /* test MatInvertBlockDiagonal 540 special cases for block-diagonal matrices */ 541 if (m == n) { 542 ISLocalToGlobalMapping map; 543 Mat Abd,Bbd; 544 IS is,bis; 545 const PetscScalar *isbd,*aijbd; 546 PetscScalar *vals; 547 const PetscInt *sts,*idxs; 548 PetscInt *idxs2,diff,perm,nl,bs,st,en,in; 549 PetscBool ok; 550 551 for (diff = 0; diff < 3; diff++) { 552 for (perm = 0; perm < 3; perm++) { 553 for (bs = 1; bs < 4; bs++) { 554 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatInvertBlockDiagonal blockdiag %D %D %D %D\n",n,diff,perm,bs);CHKERRQ(ierr); 555 ierr = PetscMalloc1(bs*bs,&vals);CHKERRQ(ierr); 556 ierr = MatGetOwnershipRanges(A,&sts);CHKERRQ(ierr); 557 switch (diff) { 558 case 1: /* inverted layout by processes */ 559 in = 1; 560 st = sts[size - rank - 1]; 561 en = sts[size - rank]; 562 nl = en - st; 563 break; 564 case 2: /* round-robin layout */ 565 in = size; 566 st = rank; 567 nl = n/size; 568 if (rank < n%size) nl++; 569 break; 570 default: /* same layout */ 571 in = 1; 572 st = sts[rank]; 573 en = sts[rank + 1]; 574 nl = en - st; 575 break; 576 } 577 ierr = ISCreateStride(PETSC_COMM_WORLD,nl,st,in,&is);CHKERRQ(ierr); 578 ierr = ISGetLocalSize(is,&nl);CHKERRQ(ierr); 579 ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 580 ierr = PetscMalloc1(nl,&idxs2);CHKERRQ(ierr); 581 for (i=0;i<nl;i++) { 582 switch (perm) { /* invert some of the indices */ 583 case 2: 584 idxs2[i] = rank%2 ? idxs[i] : idxs[nl-i-1]; 585 break; 586 case 1: 587 idxs2[i] = rank%2 ? idxs[nl-i-1] : idxs[i]; 588 break; 589 default: 590 idxs2[i] = idxs[i]; 591 break; 592 } 593 } 594 ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 595 ierr = ISCreateBlock(PETSC_COMM_WORLD,bs,nl,idxs2,PETSC_OWN_POINTER,&bis);CHKERRQ(ierr); 596 ierr = ISLocalToGlobalMappingCreateIS(bis,&map);CHKERRQ(ierr); 597 ierr = MatCreateIS(PETSC_COMM_WORLD,bs,PETSC_DECIDE,PETSC_DECIDE,bs*n,bs*n,map,NULL,&Abd);CHKERRQ(ierr); 598 ierr = ISLocalToGlobalMappingDestroy(&map);CHKERRQ(ierr); 599 ierr = MatISSetPreallocation(Abd,bs,NULL,0,NULL);CHKERRQ(ierr); 600 for (i=0;i<nl;i++) { 601 PetscInt b1,b2; 602 603 for (b1=0;b1<bs;b1++) { 604 for (b2=0;b2<bs;b2++) { 605 vals[b1*bs + b2] = i*bs*bs + b1*bs + b2 + 1 + (b1 == b2 ? 1.0 : 0); 606 } 607 } 608 ierr = MatSetValuesBlockedLocal(Abd,1,&i,1,&i,vals,INSERT_VALUES);CHKERRQ(ierr); 609 } 610 ierr = MatAssemblyBegin(Abd,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 611 ierr = MatAssemblyEnd(Abd,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 612 ierr = MatConvert(Abd,MATAIJ,MAT_INITIAL_MATRIX,&Bbd);CHKERRQ(ierr); 613 ierr = MatInvertBlockDiagonal(Abd,&isbd);CHKERRQ(ierr); 614 ierr = MatInvertBlockDiagonal(Bbd,&aijbd);CHKERRQ(ierr); 615 ierr = MatGetLocalSize(Bbd,&nl,NULL);CHKERRQ(ierr); 616 ok = PETSC_TRUE; 617 for (i=0;i<nl/bs;i++) { 618 PetscInt b1,b2; 619 620 for (b1=0;b1<bs;b1++) { 621 for (b2=0;b2<bs;b2++) { 622 if (PetscAbsScalar(isbd[i*bs*bs+b1*bs + b2]-aijbd[i*bs*bs+b1*bs + b2]) > PETSC_SMALL) ok = PETSC_FALSE; 623 if (!ok) { 624 ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] ERROR block %d, entry %d %d: %g %g\n",rank,i,b1,b2,isbd[i*bs*bs+b1*bs + b2],aijbd[i*bs*bs+b1*bs + b2]);CHKERRQ(ierr); 625 break; 626 } 627 } 628 if (!ok) break; 629 } 630 if (!ok) break; 631 } 632 ierr = MatDestroy(&Abd);CHKERRQ(ierr); 633 ierr = MatDestroy(&Bbd);CHKERRQ(ierr); 634 ierr = PetscFree(vals);CHKERRQ(ierr); 635 ierr = ISDestroy(&is);CHKERRQ(ierr); 636 ierr = ISDestroy(&bis);CHKERRQ(ierr); 637 } 638 } 639 } 640 } 641 /* free testing matrices */ 642 ierr = MatDestroy(&A);CHKERRQ(ierr); 643 ierr = MatDestroy(&B);CHKERRQ(ierr); 644 ierr = PetscFinalize(); 645 return ierr; 646 } 647 648 PetscErrorCode CheckMat(Mat A, Mat B, PetscBool usemult, const char* func) 649 { 650 Mat Bcheck; 651 PetscReal error; 652 PetscErrorCode ierr; 653 654 PetscFunctionBeginUser; 655 if (!usemult && B) { 656 PetscBool hasnorm; 657 658 ierr = MatHasOperation(B,MATOP_NORM,&hasnorm);CHKERRQ(ierr); 659 if (!hasnorm) usemult = PETSC_TRUE; 660 } 661 if (!usemult) { 662 if (B) { 663 MatType Btype; 664 665 ierr = MatGetType(B,&Btype);CHKERRQ(ierr); 666 ierr = MatConvert(A,Btype,MAT_INITIAL_MATRIX,&Bcheck);CHKERRQ(ierr); 667 } else { 668 ierr = MatConvert(A,MATAIJ,MAT_INITIAL_MATRIX,&Bcheck);CHKERRQ(ierr); 669 } 670 if (B) { /* if B is present, subtract it */ 671 ierr = MatAXPY(Bcheck,-1.,B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 672 } 673 ierr = MatNorm(Bcheck,NORM_INFINITY,&error);CHKERRQ(ierr); 674 if (error > PETSC_SQRT_MACHINE_EPSILON) { 675 ISLocalToGlobalMapping rl2g,cl2g; 676 677 ierr = PetscObjectSetName((PetscObject)Bcheck,"Assembled Bcheck");CHKERRQ(ierr); 678 ierr = MatView(Bcheck,NULL);CHKERRQ(ierr); 679 if (B) { 680 ierr = PetscObjectSetName((PetscObject)B,"Assembled AIJ");CHKERRQ(ierr); 681 ierr = MatView(B,NULL);CHKERRQ(ierr); 682 ierr = MatDestroy(&Bcheck);CHKERRQ(ierr); 683 ierr = MatConvert(A,MATAIJ,MAT_INITIAL_MATRIX,&Bcheck);CHKERRQ(ierr); 684 ierr = PetscObjectSetName((PetscObject)Bcheck,"Assembled IS");CHKERRQ(ierr); 685 ierr = MatView(Bcheck,NULL);CHKERRQ(ierr); 686 } 687 ierr = MatDestroy(&Bcheck);CHKERRQ(ierr); 688 ierr = PetscObjectSetName((PetscObject)A,"MatIS");CHKERRQ(ierr); 689 ierr = MatView(A,NULL);CHKERRQ(ierr); 690 ierr = MatGetLocalToGlobalMapping(A,&rl2g,&cl2g);CHKERRQ(ierr); 691 ierr = ISLocalToGlobalMappingView(rl2g,NULL);CHKERRQ(ierr); 692 ierr = ISLocalToGlobalMappingView(cl2g,NULL);CHKERRQ(ierr); 693 SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR ON %s: %g",func,error); 694 } 695 ierr = MatDestroy(&Bcheck);CHKERRQ(ierr); 696 } else { 697 PetscBool ok,okt; 698 699 ierr = MatMultEqual(A,B,3,&ok);CHKERRQ(ierr); 700 ierr = MatMultTransposeEqual(A,B,3,&okt);CHKERRQ(ierr); 701 if (!ok || !okt) SETERRQ3(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR ON %s: mult ok ? %d, multtranspose ok ? %d",func,ok,okt); 702 } 703 PetscFunctionReturn(0); 704 } 705 706 PetscErrorCode TestMatZeroRows(Mat A, Mat Afull, PetscBool squaretest, IS is, PetscScalar diag) 707 { 708 Mat B,Bcheck,B2 = NULL,lB; 709 Vec x = NULL, b = NULL, b2 = NULL; 710 ISLocalToGlobalMapping l2gr,l2gc; 711 PetscReal error; 712 char diagstr[16]; 713 const PetscInt *idxs; 714 PetscInt rst,ren,i,n,N,d; 715 PetscMPIInt rank; 716 PetscBool miss,haszerorows; 717 PetscErrorCode ierr; 718 719 PetscFunctionBeginUser; 720 if (diag == 0.) { 721 ierr = PetscStrcpy(diagstr,"zero");CHKERRQ(ierr); 722 } else { 723 ierr = PetscStrcpy(diagstr,"nonzero");CHKERRQ(ierr); 724 } 725 ierr = ISView(is,NULL);CHKERRQ(ierr); 726 ierr = MatGetLocalToGlobalMapping(A,&l2gr,&l2gc);CHKERRQ(ierr); 727 /* tests MatDuplicate and MatCopy */ 728 if (diag == 0.) { 729 ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 730 } else { 731 ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,&B);CHKERRQ(ierr); 732 ierr = MatCopy(A,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 733 } 734 ierr = MatISGetLocalMat(B,&lB);CHKERRQ(ierr); 735 ierr = MatHasOperation(lB,MATOP_ZERO_ROWS,&haszerorows);CHKERRQ(ierr); 736 if (squaretest && haszerorows) { 737 738 ierr = MatCreateVecs(B,&x,&b);CHKERRQ(ierr); 739 ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr); 740 ierr = VecSetLocalToGlobalMapping(b,l2gr);CHKERRQ(ierr); 741 ierr = VecSetLocalToGlobalMapping(x,l2gc);CHKERRQ(ierr); 742 ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 743 ierr = VecSetRandom(b,NULL);CHKERRQ(ierr); 744 /* mimic b[is] = x[is] */ 745 ierr = VecDuplicate(b,&b2);CHKERRQ(ierr); 746 ierr = VecSetLocalToGlobalMapping(b2,l2gr);CHKERRQ(ierr); 747 ierr = VecCopy(b,b2);CHKERRQ(ierr); 748 ierr = ISGetLocalSize(is,&n);CHKERRQ(ierr); 749 ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 750 ierr = VecGetSize(x,&N);CHKERRQ(ierr); 751 for (i=0;i<n;i++) { 752 if (0 <= idxs[i] && idxs[i] < N) { 753 ierr = VecSetValue(b2,idxs[i],diag,INSERT_VALUES);CHKERRQ(ierr); 754 ierr = VecSetValue(x,idxs[i],1.,INSERT_VALUES);CHKERRQ(ierr); 755 } 756 } 757 ierr = VecAssemblyBegin(b2);CHKERRQ(ierr); 758 ierr = VecAssemblyEnd(b2);CHKERRQ(ierr); 759 ierr = VecAssemblyBegin(x);CHKERRQ(ierr); 760 ierr = VecAssemblyEnd(x);CHKERRQ(ierr); 761 ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 762 /* test ZeroRows on MATIS */ 763 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr); 764 ierr = MatZeroRowsIS(B,is,diag,x,b);CHKERRQ(ierr); 765 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRowsColumns (diag %s)\n",diagstr);CHKERRQ(ierr); 766 ierr = MatZeroRowsColumnsIS(B2,is,diag,NULL,NULL);CHKERRQ(ierr); 767 } else if (haszerorows) { 768 /* test ZeroRows on MATIS */ 769 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr); 770 ierr = MatZeroRowsIS(B,is,diag,NULL,NULL);CHKERRQ(ierr); 771 b = b2 = x = NULL; 772 } else { 773 ierr = PetscPrintf(PETSC_COMM_WORLD,"Skipping MatZeroRows (diag %s)\n",diagstr);CHKERRQ(ierr); 774 b = b2 = x = NULL; 775 } 776 777 if (squaretest && haszerorows) { 778 ierr = VecAXPY(b2,-1.,b);CHKERRQ(ierr); 779 ierr = VecNorm(b2,NORM_INFINITY,&error);CHKERRQ(ierr); 780 if (error > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"ERROR IN ZEROROWS ON B %g (diag %s)",error,diagstr); 781 } 782 783 /* test MatMissingDiagonal */ 784 ierr = PetscPrintf(PETSC_COMM_WORLD,"Test MatMissingDiagonal\n");CHKERRQ(ierr); 785 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 786 ierr = MatMissingDiagonal(B,&miss,&d);CHKERRQ(ierr); 787 ierr = MatGetOwnershipRange(B,&rst,&ren);CHKERRQ(ierr); 788 ierr = PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 789 ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD, "[%d] [%D,%D) Missing %d, row %D (diag %s)\n",rank,rst,ren,(int)miss,d,diagstr);CHKERRQ(ierr); 790 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 791 ierr = PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 792 793 ierr = VecDestroy(&x);CHKERRQ(ierr); 794 ierr = VecDestroy(&b);CHKERRQ(ierr); 795 ierr = VecDestroy(&b2);CHKERRQ(ierr); 796 797 /* check the result of ZeroRows with that from MPIAIJ routines 798 assuming that MatConvert_IS_XAIJ and MatZeroRows_MPIAIJ work fine */ 799 if (haszerorows) { 800 ierr = MatDuplicate(Afull,MAT_COPY_VALUES,&Bcheck);CHKERRQ(ierr); 801 ierr = MatSetOption(Bcheck,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 802 ierr = MatZeroRowsIS(Bcheck,is,diag,NULL,NULL);CHKERRQ(ierr); 803 ierr = CheckMat(B,Bcheck,PETSC_FALSE,"Zerorows");CHKERRQ(ierr); 804 ierr = MatDestroy(&Bcheck);CHKERRQ(ierr); 805 } 806 ierr = MatDestroy(&B);CHKERRQ(ierr); 807 808 if (B2) { /* test MatZeroRowsColumns */ 809 ierr = MatDuplicate(Afull,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 810 ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 811 ierr = MatZeroRowsColumnsIS(B,is,diag,NULL,NULL);CHKERRQ(ierr); 812 ierr = CheckMat(B2,B,PETSC_FALSE,"MatZeroRowsColumns");CHKERRQ(ierr); 813 ierr = MatDestroy(&B);CHKERRQ(ierr); 814 ierr = MatDestroy(&B2);CHKERRQ(ierr); 815 } 816 PetscFunctionReturn(0); 817 } 818 819 /*TEST 820 821 test: 822 args: -test_trans 823 824 test: 825 suffix: 2 826 nsize: 4 827 args: -matis_convert_local_nest -nr 3 -nc 4 828 829 test: 830 suffix: 3 831 nsize: 5 832 args: -m 11 -n 10 -matis_convert_local_nest -nr 2 -nc 1 833 834 test: 835 suffix: 4 836 nsize: 6 837 args: -m 9 -n 12 -test_trans -nr 2 -nc 7 838 839 test: 840 suffix: 5 841 nsize: 6 842 args: -m 12 -n 12 -test_trans -nr 3 -nc 1 843 844 test: 845 suffix: 6 846 args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap 847 848 test: 849 suffix: 7 850 args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap 851 852 test: 853 suffix: 8 854 args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap 855 856 test: 857 suffix: 9 858 nsize: 5 859 args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap 860 861 test: 862 suffix: 10 863 nsize: 5 864 args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap 865 866 test: 867 suffix: vscat_default 868 nsize: 5 869 args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap 870 output_file: output/ex23_11.out 871 872 test: 873 suffix: 12 874 nsize: 3 875 args: -m 12 -n 12 -symmetric -matis_localmat_type sbaij -test_trans -nr 2 -nc 3 876 877 testset: 878 output_file: output/ex23_13.out 879 nsize: 3 880 args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -diffmap -permmap 881 filter: grep -v "type:" 882 test: 883 suffix: baij 884 args: -matis_localmat_type baij 885 test: 886 requires: viennacl 887 suffix: viennacl 888 args: -matis_localmat_type aijviennacl 889 test: 890 requires: cuda 891 suffix: cusparse 892 args: -matis_localmat_type aijcusparse 893 894 TEST*/ 895