int main(int argc,char **args) { Mat C; PetscErrorCode ierr; PetscInt i,m = 2,N,M,idx[4],Nsub1,Nsub2,ol=1,x1,x2; PetscScalar Ke[16]; PetscReal x,y,h; IS *is1,*is2; PetscBool flg; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL); CHKERRQ(ierr); N = (m+1)*(m+1); /* dimension of matrix */ M = m*m; /* number of elements */ h = 1.0/m; /* mesh width */ x1= (m+1)/2; x2= x1; ierr = PetscOptionsGetInt(PETSC_NULL,"-x1",&x1,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-x2",&x2,PETSC_NULL); CHKERRQ(ierr); /* create stiffness matrix */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,N,N,9,PETSC_NULL,&C); CHKERRQ(ierr); /* forms the element stiffness for the Laplacian */ ierr = FormElementStiffness(h*h,Ke); CHKERRQ(ierr); for (i=0; i<M; i++) { /* location of lower left corner of element */ x = h*(i % m); y = h*(i/m); /* node numbers for the four corners of element */ idx[0] = (m+1)*(i/m) + (i % m); idx[1] = idx[0]+1; idx[2] = idx[1] + m + 1; idx[3] = idx[2] - 1; ierr = MatSetValues(C,4,idx,4,idx,Ke,ADD_VALUES); CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); for (ol=0; ol<m+2; ++ol) { ierr = PCASMCreateSubdomains2D(m+1,m+1,x1,x2,1,0,&Nsub1,&is1); CHKERRQ(ierr); ierr = MatIncreaseOverlap(C,Nsub1,is1,ol); CHKERRQ(ierr); ierr = PCASMCreateSubdomains2D(m+1,m+1,x1,x2,1,ol,&Nsub2,&is2); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"flg == 1 => both index sets are same\n"); CHKERRQ(ierr); if(Nsub1 != Nsub2) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: No of indes sets don't match\n"); CHKERRQ(ierr); } for (i=0; i<Nsub1; ++i) { ierr = ISEqual(is1[i],is2[i],&flg); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"i = %D,flg = %d \n",i,(int)flg); CHKERRQ(ierr); } for (i=0; i<Nsub1; ++i) { ierr = ISDestroy(&&is1[i]); CHKERRQ(ierr); } for (i=0; i<Nsub2; ++i) { ierr = ISDestroy(&&is2[i]); CHKERRQ(ierr); } ierr = PetscFree(is1); CHKERRQ(ierr); ierr = PetscFree(is2); CHKERRQ(ierr); } ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat A,B,*submatA,*submatB; PetscInt bs=1,m=11,ov=1,i,j,k,*rows,*cols,nd=5,*idx,rstart,rend,sz,mm,nn,M,N,Mbs; PetscErrorCode ierr; PetscMPIInt size,rank; PetscScalar *vals,rval; IS *is1,*is2; PetscRandom rdm; Vec xx,s1,s2; PetscReal s1norm,s2norm,rnorm,tol = 100*PETSC_SMALL; PetscBool flg,test_nd0=PETSC_FALSE; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mat_block_size",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mat_size",&m,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ov",&ov,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nd",&nd,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_nd0",&test_nd0,NULL);CHKERRQ(ierr); /* Create a AIJ matrix A */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,m*bs,m*bs,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); /* Create a BAIJ matrix B */ ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,m*bs,m*bs,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(B,MATBAIJ);CHKERRQ(ierr); ierr = MatSeqBAIJSetPreallocation(B,bs,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = MatMPIBAIJSetPreallocation(B,bs,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); Mbs = M/bs; ierr = PetscMalloc1(bs,&rows);CHKERRQ(ierr); ierr = PetscMalloc1(bs,&cols);CHKERRQ(ierr); ierr = PetscMalloc1(bs*bs,&vals);CHKERRQ(ierr); ierr = PetscMalloc1(M,&idx);CHKERRQ(ierr); /* Now set blocks of values */ for (i=0; i<40*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = bs*(int)(PetscRealPart(rval)*Mbs); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = rstart + bs*(int)(PetscRealPart(rval)*m); for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } for (j=0; j<bs*bs; j++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); vals[j] = rval; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatIncreaseOverlap() */ ierr = PetscMalloc1(nd,&is1);CHKERRQ(ierr); ierr = PetscMalloc1(nd,&is2);CHKERRQ(ierr); if (!rank && test_nd0) nd = 0; /* test case */ for (i=0; i<nd; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); sz = (int)(PetscRealPart(rval)*m); for (j=0; j<sz; j++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); idx[j*bs] = bs*(int)(PetscRealPart(rval)*Mbs); for (k=1; k<bs; k++) idx[j*bs+k] = idx[j*bs]+k; } ierr = ISCreateGeneral(PETSC_COMM_SELF,sz*bs,idx,PETSC_COPY_VALUES,is1+i);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,sz*bs,idx,PETSC_COPY_VALUES,is2+i);CHKERRQ(ierr); } ierr = MatIncreaseOverlap(A,nd,is1,ov);CHKERRQ(ierr); ierr = MatIncreaseOverlap(B,nd,is2,ov);CHKERRQ(ierr); for (i=0; i<nd; ++i) { ierr = ISEqual(is1[i],is2[i],&flg);CHKERRQ(ierr); if (!flg) { ierr = PetscPrintf(PETSC_COMM_SELF,"i=%D, flg=%d :bs=%D m=%D ov=%D nd=%D np=%D\n",i,flg,bs,m,ov,nd,size);CHKERRQ(ierr); } } for (i=0; i<nd; ++i) { ierr = ISSort(is1[i]);CHKERRQ(ierr); ierr = ISSort(is2[i]);CHKERRQ(ierr); } ierr = MatCreateSubMatrices(B,nd,is2,is2,MAT_INITIAL_MATRIX,&submatB);CHKERRQ(ierr); ierr = MatCreateSubMatrices(A,nd,is1,is1,MAT_INITIAL_MATRIX,&submatA);CHKERRQ(ierr); /* Test MatMult() */ for (i=0; i<nd; i++) { ierr = MatGetSize(submatA[i],&mm,&nn);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,mm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); for (j=0; j<3; j++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatMult(submatA[i],xx,s1);CHKERRQ(ierr); ierr = MatMult(submatB[i],xx,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"[%d]Error:MatMult - Norm1=%16.14e Norm2=%16.14e\n",rank,s1norm,s2norm);CHKERRQ(ierr); } } ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&s1);CHKERRQ(ierr); ierr = VecDestroy(&s2);CHKERRQ(ierr); } /* Now test MatCreateSubmatrices with MAT_REUSE_MATRIX option */ ierr = MatCreateSubMatrices(A,nd,is1,is1,MAT_REUSE_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatCreateSubMatrices(B,nd,is2,is2,MAT_REUSE_MATRIX,&submatB);CHKERRQ(ierr); /* Test MatMult() */ for (i=0; i<nd; i++) { ierr = MatGetSize(submatA[i],&mm,&nn);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,mm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); for (j=0; j<3; j++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatMult(submatA[i],xx,s1);CHKERRQ(ierr); ierr = MatMult(submatB[i],xx,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"[%d]Error:MatMult - Norm1=%16.14e Norm2=%16.14e\n",rank,s1norm,s2norm);CHKERRQ(ierr); } } ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&s1);CHKERRQ(ierr); ierr = VecDestroy(&s2);CHKERRQ(ierr); } /* Free allocated memory */ for (i=0; i<nd; ++i) { ierr = ISDestroy(&is1[i]);CHKERRQ(ierr); ierr = ISDestroy(&is2[i]);CHKERRQ(ierr); } ierr = MatDestroySubMatrices(nd,&submatA);CHKERRQ(ierr); ierr = MatDestroySubMatrices(nd,&submatB);CHKERRQ(ierr); ierr = PetscFree(is1);CHKERRQ(ierr); ierr = PetscFree(is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = PetscFree(cols);CHKERRQ(ierr); ierr = PetscFree(vals);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Mat A,Atrans,sA,*submatA,*submatsA; PetscErrorCode ierr; PetscMPIInt size,rank; PetscInt bs=1,mbs=10,ov=1,i,j,k,*rows,*cols,nd=2,*idx,rstart,rend,sz,M,N,Mbs; PetscScalar *vals,rval,one=1.0; IS *is1,*is2; PetscRandom rand; PetscBool flg,TestOverlap,TestSubMat,TestAllcols,test_sorted=PETSC_FALSE; PetscInt vid = -1; #if defined(PETSC_USE_LOG) PetscLogStage stages[2]; #endif ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mat_block_size",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mat_mbs",&mbs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ov",&ov,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-nd",&nd,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-view_id",&vid,NULL);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL, "-test_overlap", &TestOverlap);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL, "-test_submat", &TestSubMat);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL, "-test_allcols", &TestAllcols);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-test_sorted",&test_sorted,NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,mbs*bs,mbs*bs,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(A,MATBAIJ);CHKERRQ(ierr); ierr = MatSeqBAIJSetPreallocation(A,bs,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = MatMPIBAIJSetPreallocation(A,bs,PETSC_DEFAULT,NULL,PETSC_DEFAULT,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); Mbs = M/bs; ierr = PetscMalloc1(bs,&rows);CHKERRQ(ierr); ierr = PetscMalloc1(bs,&cols);CHKERRQ(ierr); ierr = PetscMalloc1(bs*bs,&vals);CHKERRQ(ierr); ierr = PetscMalloc1(M,&idx);CHKERRQ(ierr); /* Now set blocks of values */ for (j=0; j<bs*bs; j++) vals[j] = 0.0; for (i=0; i<Mbs; i++) { cols[0] = i*bs; rows[0] = i*bs; for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } /* second, add random blocks */ for (i=0; i<20*bs; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); cols[0] = bs*(PetscInt)(PetscRealPart(rval)*Mbs); ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); rows[0] = rstart + bs*(PetscInt)(PetscRealPart(rval)*mbs); for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } for (j=0; j<bs*bs; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); vals[j] = rval; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* make A a symmetric matrix: A <- A^T + A */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,one,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Atrans);CHKERRQ(ierr); ierr = MatEqual(A, Atrans, &flg);CHKERRQ(ierr); if (flg) { ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } else SETERRQ(PETSC_COMM_SELF,1,"A+A^T is non-symmetric"); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); /* create a SeqSBAIJ matrix sA (= A) */ ierr = MatConvert(A,MATSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); if (vid >= 0 && vid < size) { if (!rank) printf("A: \n"); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); if (!rank) printf("sA: \n"); ierr = MatView(sA,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Test sA==A through MatMult() */ ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in MatConvert(): A != sA"); /* Test MatIncreaseOverlap() */ ierr = PetscMalloc1(nd,&is1);CHKERRQ(ierr); ierr = PetscMalloc1(nd,&is2);CHKERRQ(ierr); for (i=0; i<nd; i++) { if (!TestAllcols) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); sz = (PetscInt)((0.5+0.2*PetscRealPart(rval))*mbs); /* 0.5*mbs < sz < 0.7*mbs */ for (j=0; j<sz; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); idx[j*bs] = bs*(PetscInt)(PetscRealPart(rval)*Mbs); for (k=1; k<bs; k++) idx[j*bs+k] = idx[j*bs]+k; } ierr = ISCreateGeneral(PETSC_COMM_SELF,sz*bs,idx,PETSC_COPY_VALUES,is1+i);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,sz*bs,idx,PETSC_COPY_VALUES,is2+i);CHKERRQ(ierr); if (rank == vid) { ierr = PetscPrintf(PETSC_COMM_SELF," [%d] IS sz[%d]: %d\n",rank,i,sz);CHKERRQ(ierr); ierr = ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } } else { /* Test all rows and colums */ sz = M; ierr = ISCreateStride(PETSC_COMM_SELF,sz,0,1,is1+i);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,sz,0,1,is2+i);CHKERRQ(ierr); if (rank == vid) { PetscBool colflag; ierr = ISIdentity(is2[i],&colflag);CHKERRQ(ierr); printf("[%d] is2[%d], colflag %d\n",rank,(int)i,(int)colflag); ierr = ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } } } ierr = PetscLogStageRegister("MatOv_SBAIJ",&stages[0]);CHKERRQ(ierr); ierr = PetscLogStageRegister("MatOv_BAIJ",&stages[1]);CHKERRQ(ierr); /* Test MatIncreaseOverlap */ if (TestOverlap) { ierr = PetscLogStagePush(stages[0]);CHKERRQ(ierr); ierr = MatIncreaseOverlap(sA,nd,is2,ov);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); ierr = PetscLogStagePush(stages[1]);CHKERRQ(ierr); ierr = MatIncreaseOverlap(A,nd,is1,ov);CHKERRQ(ierr); ierr = PetscLogStagePop();CHKERRQ(ierr); if (rank == vid) { printf("\n[%d] IS from BAIJ:\n",rank); ierr = ISView(is1[0],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); printf("\n[%d] IS from SBAIJ:\n",rank); ierr = ISView(is2[0],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } for (i=0; i<nd; ++i) { ierr = ISEqual(is1[i],is2[i],&flg);CHKERRQ(ierr); if (!flg) { if (!rank) { ierr = ISSort(is1[i]);CHKERRQ(ierr); /* ISView(is1[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); */ ierr = ISSort(is2[i]);CHKERRQ(ierr); /* ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); */ } SETERRQ1(PETSC_COMM_SELF,1,"i=%D, is1 != is2",i); } } } /* Test MatCreateSubmatrices */ if (TestSubMat) { if (test_sorted) { for (i = 0; i < nd; ++i) { ierr = ISSort(is1[i]);CHKERRQ(ierr); } } ierr = MatCreateSubMatrices(A,nd,is1,is1,MAT_INITIAL_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatCreateSubMatrices(sA,nd,is1,is1,MAT_INITIAL_MATRIX,&submatsA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"A != sA"); /* Now test MatCreateSubmatrices with MAT_REUSE_MATRIX option */ ierr = MatCreateSubMatrices(A,nd,is1,is1,MAT_REUSE_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatCreateSubMatrices(sA,nd,is1,is1,MAT_REUSE_MATRIX,&submatsA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"MatCreateSubmatrices(): A != sA"); ierr = MatDestroySubMatrices(nd,&submatA);CHKERRQ(ierr); ierr = MatDestroySubMatrices(nd,&submatsA);CHKERRQ(ierr); } /* Free allocated memory */ for (i=0; i<nd; ++i) { ierr = ISDestroy(&is1[i]);CHKERRQ(ierr); ierr = ISDestroy(&is2[i]);CHKERRQ(ierr); } ierr = PetscFree(is1);CHKERRQ(ierr); ierr = PetscFree(is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = PetscFree(cols);CHKERRQ(ierr); ierr = PetscFree(vals);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&sA);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode PCGAMGProlongator_Classical_Standard(PC pc, const Mat A, const Mat G, PetscCoarsenData *agg_lists,Mat *P) { PetscErrorCode ierr; Mat *lA; Vec lv,v,cv; PetscScalar *lcid; IS lis; PetscInt fs,fe,cs,ce,nl,i,j,k,li,lni,ci; VecScatter lscat; PetscInt fn,cn,cid,c_indx; PetscBool iscoarse; PetscScalar c_scalar; const PetscScalar *vcol; const PetscInt *icol; const PetscInt *gidx; PetscInt ncols; PetscInt *lsparse,*gsparse; MatType mtype; PetscInt maxcols; PetscReal diag,jdiag,jwttotal; PetscScalar *pvcol,vi; PetscInt *picol; PetscInt pncols; PetscScalar *pcontrib,pentry,pjentry; /* PC_MG *mg = (PC_MG*)pc->data; */ /* PC_GAMG *gamg = (PC_GAMG*)mg->innerctx; */ PetscFunctionBegin; ierr = MatGetOwnershipRange(A,&fs,&fe);CHKERRQ(ierr); fn = fe-fs; ierr = MatGetVecs(A,NULL,&v);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,fe-fs,fs,1,&lis);CHKERRQ(ierr); /* increase the overlap by two to get neighbors of neighbors */ ierr = MatIncreaseOverlap(A,1,&lis,2);CHKERRQ(ierr); ierr = ISSort(lis);CHKERRQ(ierr); /* get the local part of A */ ierr = MatGetSubMatrices(A,1,&lis,&lis,MAT_INITIAL_MATRIX,&lA);CHKERRQ(ierr); /* build the scatter out of it */ ierr = ISGetLocalSize(lis,&nl);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,nl,&lv);CHKERRQ(ierr); ierr = VecScatterCreate(v,lis,lv,NULL,&lscat);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscInt)*fn,&lsparse);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscInt)*fn,&gsparse);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscScalar)*nl,&pcontrib);CHKERRQ(ierr); /* create coarse vector */ cn = 0; for (i=0;i<fn;i++) { ierr = PetscCDEmptyAt(agg_lists,i,&iscoarse);CHKERRQ(ierr); if (!iscoarse) { cn++; } } ierr = VecCreateMPI(PetscObjectComm((PetscObject)A),cn,PETSC_DECIDE,&cv);CHKERRQ(ierr); ierr = VecGetOwnershipRange(cv,&cs,&ce);CHKERRQ(ierr); cn = 0; for (i=0;i<fn;i++) { ierr = PetscCDEmptyAt(agg_lists,i,&iscoarse); CHKERRQ(ierr); if (!iscoarse) { cid = cs+cn; cn++; } else { cid = -1; } *(PetscInt*)&c_scalar = cid; c_indx = fs+i; ierr = VecSetValues(v,1,&c_indx,&c_scalar,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecScatterBegin(lscat,v,lv,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(lscat,v,lv,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); /* count to preallocate the prolongator */ ierr = ISGetIndices(lis,&gidx);CHKERRQ(ierr); ierr = VecGetArray(lv,&lcid);CHKERRQ(ierr); maxcols = 0; /* count the number of unique contributing coarse cells for each fine */ for (i=0;i<nl;i++) { pcontrib[i] = 0.; ierr = MatGetRow(lA[0],i,&ncols,&icol,NULL);CHKERRQ(ierr); if (gidx[i] >= fs && gidx[i] < fe) { li = gidx[i] - fs; lsparse[li] = 0; gsparse[li] = 0; cid = *(PetscInt*)&(lcid[i]); if (cid >= 0) { lsparse[li] = 1; } else { for (j=0;j<ncols;j++) { if (*(PetscInt*)&(lcid[icol[j]]) >= 0) { pcontrib[icol[j]] = 1.; } else { ci = icol[j]; ierr = MatRestoreRow(lA[0],i,&ncols,&icol,NULL);CHKERRQ(ierr); ierr = MatGetRow(lA[0],ci,&ncols,&icol,NULL);CHKERRQ(ierr); for (k=0;k<ncols;k++) { if (*(PetscInt*)&(lcid[icol[k]]) >= 0) { pcontrib[icol[k]] = 1.; } } ierr = MatRestoreRow(lA[0],ci,&ncols,&icol,NULL);CHKERRQ(ierr); ierr = MatGetRow(lA[0],i,&ncols,&icol,NULL);CHKERRQ(ierr); } } for (j=0;j<ncols;j++) { if (*(PetscInt*)&(lcid[icol[j]]) >= 0 && pcontrib[icol[j]] != 0.) { lni = *(PetscInt*)&(lcid[icol[j]]); if (lni >= cs && lni < ce) { lsparse[li]++; } else { gsparse[li]++; } pcontrib[icol[j]] = 0.; } else { ci = icol[j]; ierr = MatRestoreRow(lA[0],i,&ncols,&icol,NULL);CHKERRQ(ierr); ierr = MatGetRow(lA[0],ci,&ncols,&icol,NULL);CHKERRQ(ierr); for (k=0;k<ncols;k++) { if (*(PetscInt*)&(lcid[icol[k]]) >= 0 && pcontrib[icol[k]] != 0.) { lni = *(PetscInt*)&(lcid[icol[k]]); if (lni >= cs && lni < ce) { lsparse[li]++; } else { gsparse[li]++; } pcontrib[icol[k]] = 0.; } } ierr = MatRestoreRow(lA[0],ci,&ncols,&icol,NULL);CHKERRQ(ierr); ierr = MatGetRow(lA[0],i,&ncols,&icol,NULL);CHKERRQ(ierr); } } } if (lsparse[li] + gsparse[li] > maxcols) maxcols = lsparse[li]+gsparse[li]; } ierr = MatRestoreRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); } ierr = PetscMalloc(sizeof(PetscInt)*maxcols,&picol);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscScalar)*maxcols,&pvcol);CHKERRQ(ierr); ierr = MatCreate(PetscObjectComm((PetscObject)A),P);CHKERRQ(ierr); ierr = MatGetType(A,&mtype);CHKERRQ(ierr); ierr = MatSetType(*P,mtype);CHKERRQ(ierr); ierr = MatSetSizes(*P,fn,cn,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(*P,0,lsparse,0,gsparse);CHKERRQ(ierr); ierr = MatSeqAIJSetPreallocation(*P,0,lsparse);CHKERRQ(ierr); for (i=0;i<nl;i++) { diag = 0.; if (gidx[i] >= fs && gidx[i] < fe) { li = gidx[i] - fs; pncols=0; cid = *(PetscInt*)&(lcid[i]); if (cid >= 0) { pncols = 1; picol[0] = cid; pvcol[0] = 1.; } else { ierr = MatGetRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); for (j=0;j<ncols;j++) { pentry = vcol[j]; if (*(PetscInt*)&(lcid[icol[j]]) >= 0) { /* coarse neighbor */ pcontrib[icol[j]] += pentry; } else if (icol[j] != i) { /* the neighbor is a strongly connected fine node */ ci = icol[j]; vi = vcol[j]; ierr = MatRestoreRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); ierr = MatGetRow(lA[0],ci,&ncols,&icol,&vcol);CHKERRQ(ierr); jwttotal=0.; jdiag = 0.; for (k=0;k<ncols;k++) { if (ci == icol[k]) { jdiag = PetscRealPart(vcol[k]); } } for (k=0;k<ncols;k++) { if (*(PetscInt*)&(lcid[icol[k]]) >= 0 && jdiag*PetscRealPart(vcol[k]) < 0.) { pjentry = vcol[k]; jwttotal += PetscRealPart(pjentry); } } if (jwttotal != 0.) { jwttotal = PetscRealPart(vi)/jwttotal; for (k=0;k<ncols;k++) { if (*(PetscInt*)&(lcid[icol[k]]) >= 0 && jdiag*PetscRealPart(vcol[k]) < 0.) { pjentry = vcol[k]*jwttotal; pcontrib[icol[k]] += pjentry; } } } else { diag += PetscRealPart(vi); } ierr = MatRestoreRow(lA[0],ci,&ncols,&icol,&vcol);CHKERRQ(ierr); ierr = MatGetRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); } else { diag += PetscRealPart(vcol[j]); } } if (diag != 0.) { diag = 1./diag; for (j=0;j<ncols;j++) { if (*(PetscInt*)&(lcid[icol[j]]) >= 0 && pcontrib[icol[j]] != 0.) { /* the neighbor is a coarse node */ if (PetscAbsScalar(pcontrib[icol[j]]) > 0.0) { lni = *(PetscInt*)&(lcid[icol[j]]); pvcol[pncols] = -pcontrib[icol[j]]*diag; picol[pncols] = lni; pncols++; } pcontrib[icol[j]] = 0.; } else { /* the neighbor is a strongly connected fine node */ ci = icol[j]; ierr = MatRestoreRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); ierr = MatGetRow(lA[0],ci,&ncols,&icol,&vcol);CHKERRQ(ierr); for (k=0;k<ncols;k++) { if (*(PetscInt*)&(lcid[icol[k]]) >= 0 && pcontrib[icol[k]] != 0.) { if (PetscAbsScalar(pcontrib[icol[k]]) > 0.0) { lni = *(PetscInt*)&(lcid[icol[k]]); pvcol[pncols] = -pcontrib[icol[k]]*diag; picol[pncols] = lni; pncols++; } pcontrib[icol[k]] = 0.; } } ierr = MatRestoreRow(lA[0],ci,&ncols,&icol,&vcol);CHKERRQ(ierr); ierr = MatGetRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); } pcontrib[icol[j]] = 0.; } ierr = MatRestoreRow(lA[0],i,&ncols,&icol,&vcol);CHKERRQ(ierr); } } ci = gidx[i]; li = gidx[i] - fs; if (pncols > 0) { ierr = MatSetValues(*P,1,&ci,pncols,picol,pvcol,INSERT_VALUES);CHKERRQ(ierr); } } } ierr = ISRestoreIndices(lis,&gidx);CHKERRQ(ierr); ierr = VecRestoreArray(lv,&lcid);CHKERRQ(ierr); ierr = PetscFree(pcontrib);CHKERRQ(ierr); ierr = PetscFree(picol);CHKERRQ(ierr); ierr = PetscFree(pvcol);CHKERRQ(ierr); ierr = PetscFree(lsparse);CHKERRQ(ierr); ierr = PetscFree(gsparse);CHKERRQ(ierr); ierr = ISDestroy(&lis);CHKERRQ(ierr); ierr = MatDestroyMatrices(1,&lA);CHKERRQ(ierr); ierr = VecDestroy(&lv);CHKERRQ(ierr); ierr = VecDestroy(&cv);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = VecScatterDestroy(&lscat);CHKERRQ(ierr); ierr = MatAssemblyBegin(*P, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*P, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Mat Pold; ierr = PCGAMGProlongator_Classical(pc,A,G,agg_lists,&Pold);CHKERRQ(ierr); ierr = MatView(Pold,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatView(*P,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&Pold);CHKERRQ(ierr); */ PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat A,Atrans,sA,*submatA,*submatsA; PetscInt bs=1,m=43,ov=1,i,j,k,*rows,*cols,M,nd=5,*idx,mm,nn; PetscErrorCode ierr; PetscMPIInt size; PetscScalar *vals,rval,one=1.0; IS *is1,*is2; PetscRandom rand; Vec xx,s1,s2; PetscReal s1norm,s2norm,rnorm,tol = 1.e-10; PetscBool flg; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_size",&m,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-ov",&ov,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-nd",&nd,PETSC_NULL);CHKERRQ(ierr); /* create a SeqBAIJ matrix A */ M = m*bs; ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF,bs,M,M,1,PETSC_NULL,&A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = PetscMalloc(bs*sizeof(PetscInt),&rows);CHKERRQ(ierr); ierr = PetscMalloc(bs*sizeof(PetscInt),&cols);CHKERRQ(ierr); ierr = PetscMalloc(bs*bs*sizeof(PetscScalar),&vals);CHKERRQ(ierr); ierr = PetscMalloc(M*sizeof(PetscScalar),&idx);CHKERRQ(ierr); /* Now set blocks of random values */ /* first, set diagonal blocks as zero */ for (j=0; j<bs*bs; j++) vals[j] = 0.0; for (i=0; i<m; i++){ cols[0] = i*bs; rows[0] = i*bs; for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } /* second, add random blocks */ for (i=0; i<20*bs; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); cols[0] = bs*(int)(PetscRealPart(rval)*m); ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); rows[0] = bs*(int)(PetscRealPart(rval)*m); for (j=1; j<bs; j++) { rows[j] = rows[j-1]+1; cols[j] = cols[j-1]+1; } for (j=0; j<bs*bs; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); vals[j] = rval; } ierr = MatSetValues(A,bs,rows,bs,cols,vals,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* make A a symmetric matrix: A <- A^T + A */ ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Atrans);CHKERRQ(ierr); ierr = MatAXPY(A,one,Atrans,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatDestroy(&Atrans);CHKERRQ(ierr); ierr = MatTranspose(A,MAT_INITIAL_MATRIX, &Atrans); ierr = MatEqual(A, Atrans, &flg); if (!flg) { SETERRQ(PETSC_COMM_SELF,1,"A+A^T is non-symmetric"); } ierr = MatDestroy(&Atrans);CHKERRQ(ierr); /* create a SeqSBAIJ matrix sA (= A) */ ierr = MatConvert(A,MATSEQSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); /* Test sA==A through MatMult() */ for (i=0; i<nd; i++) { ierr = MatGetSize(A,&mm,&nn);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,mm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); for (j=0; j<3; j++) { ierr = VecSetRandom(xx,rand);CHKERRQ(ierr); ierr = MatMult(A,xx,s1);CHKERRQ(ierr); ierr = MatMult(sA,xx,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatMult - Norm1=%16.14e Norm2=%16.14e\n",s1norm,s2norm);CHKERRQ(ierr); } } ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&s1);CHKERRQ(ierr); ierr = VecDestroy(&s2);CHKERRQ(ierr); } /* Test MatIncreaseOverlap() */ ierr = PetscMalloc(nd*sizeof(IS **),&is1);CHKERRQ(ierr); ierr = PetscMalloc(nd*sizeof(IS **),&is2);CHKERRQ(ierr); for (i=0; i<nd; i++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); size = (int)(PetscRealPart(rval)*m); for (j=0; j<size; j++) { ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); idx[j*bs] = bs*(int)(PetscRealPart(rval)*m); for (k=1; k<bs; k++) idx[j*bs+k] = idx[j*bs]+k; } ierr = ISCreateGeneral(PETSC_COMM_SELF,size*bs,idx,PETSC_COPY_VALUES,is1+i);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,size*bs,idx,PETSC_COPY_VALUES,is2+i);CHKERRQ(ierr); } /* for debugging */ /* ierr = MatView(A,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = MatView(sA,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); */ ierr = MatIncreaseOverlap(A,nd,is1,ov);CHKERRQ(ierr); ierr = MatIncreaseOverlap(sA,nd,is2,ov);CHKERRQ(ierr); for (i=0; i<nd; ++i) { ierr = ISSort(is1[i]);CHKERRQ(ierr); ierr = ISSort(is2[i]);CHKERRQ(ierr); } for (i=0; i<nd; ++i) { ierr = ISEqual(is1[i],is2[i],&flg);CHKERRQ(ierr); if (!flg){ /* ISView(is1[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ISView(is2[i],PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); */ SETERRQ1(PETSC_COMM_SELF,1,"i=%d, is1 != is2",i); } } ierr = MatGetSubMatrices(A,nd,is1,is1,MAT_INITIAL_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatGetSubMatrices(sA,nd,is2,is2,MAT_INITIAL_MATRIX,&submatsA);CHKERRQ(ierr); /* Test MatMult() */ for (i=0; i<nd; i++) { ierr = MatGetSize(submatA[i],&mm,&nn);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,mm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); for (j=0; j<3; j++) { ierr = VecSetRandom(xx,rand);CHKERRQ(ierr); ierr = MatMult(submatA[i],xx,s1);CHKERRQ(ierr); ierr = MatMult(submatsA[i],xx,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatMult - Norm1=%16.14e Norm2=%16.14e\n",s1norm,s2norm);CHKERRQ(ierr); } } ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&s1);CHKERRQ(ierr); ierr = VecDestroy(&s2);CHKERRQ(ierr); } /* Now test MatGetSubmatrices with MAT_REUSE_MATRIX option */ ierr = MatGetSubMatrices(A,nd,is1,is1,MAT_REUSE_MATRIX,&submatA);CHKERRQ(ierr); ierr = MatGetSubMatrices(sA,nd,is2,is2,MAT_REUSE_MATRIX,&submatsA);CHKERRQ(ierr); /* Test MatMult() */ for (i=0; i<nd; i++) { ierr = MatGetSize(submatA[i],&mm,&nn);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,mm,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); for (j=0; j<3; j++) { ierr = VecSetRandom(xx,rand);CHKERRQ(ierr); ierr = MatMult(submatA[i],xx,s1);CHKERRQ(ierr); ierr = MatMult(submatsA[i],xx,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatMult - Norm1=%16.14e Norm2=%16.14e\n",s1norm,s2norm);CHKERRQ(ierr); } } ierr = VecDestroy(&xx);CHKERRQ(ierr); ierr = VecDestroy(&s1);CHKERRQ(ierr); ierr = VecDestroy(&s2);CHKERRQ(ierr); } /* Free allocated memory */ for (i=0; i<nd; ++i) { ierr = ISDestroy(&is1[i]);CHKERRQ(ierr); ierr = ISDestroy(&is2[i]);CHKERRQ(ierr); ierr = MatDestroy(&submatA[i]);CHKERRQ(ierr); ierr = MatDestroy(&submatsA[i]);CHKERRQ(ierr); } ierr = PetscFree(submatA);CHKERRQ(ierr); ierr = PetscFree(submatsA);CHKERRQ(ierr); ierr = PetscFree(is1);CHKERRQ(ierr); ierr = PetscFree(is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = PetscFree(cols);CHKERRQ(ierr); ierr = PetscFree(vals);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&sA);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
-ov <overlap> : >=0 amount of overlap between domains\n\n"; #include <petscmat.h> int main(int argc,char **args) { PetscErrorCode ierr; PetscInt nd = 2,ov=1,i,start,m,n,end,lsize; PetscMPIInt rank; PetscBool flg; Mat A,B; char file[PETSC_MAX_PATH_LEN]; PetscViewer fd; IS *is1,*is2; PetscRandom r; PetscScalar rand; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,1,"This example does not work with complex numbers"); #else ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetString(NULL,NULL,"-f",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must use -f filename to indicate a file containing a PETSc binary matrix"); ierr = PetscOptionsGetInt(NULL,NULL,"-nd",&nd,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ov",&ov,NULL);CHKERRQ(ierr); /* Read matrix and RHS */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetType(A,MATMPIAIJ);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); /* Read the matrix again as a sequential matrix */ ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&B);CHKERRQ(ierr); ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); ierr = MatLoad(B,fd);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); /* Create the IS corresponding to subdomains */ ierr = PetscMalloc1(nd,&is1);CHKERRQ(ierr); ierr = PetscMalloc1(nd,&is2);CHKERRQ(ierr); /* Create the random Index Sets */ ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); for (i=0; i<nd; i++) { ierr = PetscRandomGetValue(r,&rand);CHKERRQ(ierr); start = (PetscInt)(rand*m); ierr = PetscRandomGetValue(r,&rand);CHKERRQ(ierr); end = (PetscInt)(rand*m); lsize = end - start; if (start > end) { start = end; lsize = -lsize;} ierr = ISCreateStride(PETSC_COMM_SELF,lsize,start,1,is1+i);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,lsize,start,1,is2+i);CHKERRQ(ierr); } ierr = MatIncreaseOverlap(A,nd,is1,ov);CHKERRQ(ierr); ierr = MatIncreaseOverlap(B,nd,is2,ov);CHKERRQ(ierr); /* Now see if the serial and parallel case have the same answers */ for (i=0; i<nd; ++i) { ierr = ISEqual(is1[i],is2[i],&flg);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"proc:[%d], i=%D, flg =%d\n",rank,i,(int)flg);CHKERRQ(ierr); } /* Free allocated memory */ for (i=0; i<nd; ++i) { ierr = ISDestroy(&is1[i]);CHKERRQ(ierr); ierr = ISDestroy(&is2[i]);CHKERRQ(ierr); } ierr = PetscFree(is1);CHKERRQ(ierr); ierr = PetscFree(is2);CHKERRQ(ierr); ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); #endif ierr = PetscFinalize(); return ierr; }
PetscErrorCode MatColoringGetDegrees(Mat G,PetscInt distance,PetscInt *degrees) { PetscInt j,i,s,e,n,ln,lm,degree,bidx,idx,dist; Mat lG,*lGs; IS ris; PetscErrorCode ierr; PetscInt *seen; const PetscInt *gidx; PetscInt *idxbuf; PetscInt *distbuf; PetscInt ncols; const PetscInt *cols; PetscBool isSEQAIJ; Mat_SeqAIJ *aij; PetscInt *Gi,*Gj; PetscFunctionBegin; ierr = MatGetOwnershipRange(G,&s,&e);CHKERRQ(ierr); n=e-s; ierr = ISCreateStride(PetscObjectComm((PetscObject)G),n,s,1,&ris);CHKERRQ(ierr); ierr = MatIncreaseOverlap(G,1,&ris,distance);CHKERRQ(ierr); ierr = ISSort(ris);CHKERRQ(ierr); ierr = MatGetSubMatrices(G,1,&ris,&ris,MAT_INITIAL_MATRIX,&lGs);CHKERRQ(ierr); lG = lGs[0]; ierr = PetscObjectTypeCompare((PetscObject)lG,MATSEQAIJ,&isSEQAIJ);CHKERRQ(ierr); if (!isSEQAIJ) SETERRQ(PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"Requires an MPI/SEQAIJ Matrix"); ierr = MatGetSize(lG,&ln,&lm);CHKERRQ(ierr); aij = (Mat_SeqAIJ*)lG->data; Gi = aij->i; Gj = aij->j; ierr = PetscMalloc3(lm,&seen,lm,&idxbuf,lm,&distbuf);CHKERRQ(ierr); for (i=0;i<ln;i++) { seen[i]=-1; } ierr = ISGetIndices(ris,&gidx);CHKERRQ(ierr); for (i=0;i<ln;i++) { if (gidx[i] >= e || gidx[i] < s) continue; bidx=-1; ncols = Gi[i+1]-Gi[i]; cols = &(Gj[Gi[i]]); degree = 0; /* place the distance-one neighbors on the queue */ for (j=0;j<ncols;j++) { bidx++; seen[cols[j]] = i; distbuf[bidx] = 1; idxbuf[bidx] = cols[j]; } while (bidx >= 0) { /* pop */ idx = idxbuf[bidx]; dist = distbuf[bidx]; bidx--; degree++; if (dist < distance) { ncols = Gi[idx+1]-Gi[idx]; cols = &(Gj[Gi[idx]]); for (j=0;j<ncols;j++) { if (seen[cols[j]] != i) { bidx++; seen[cols[j]] = i; idxbuf[bidx] = cols[j]; distbuf[bidx] = dist+1; } } } } degrees[gidx[i]-s] = degree; } ierr = ISRestoreIndices(ris,&gidx);CHKERRQ(ierr); ierr = ISDestroy(&ris);CHKERRQ(ierr); ierr = PetscFree3(seen,idxbuf,distbuf);CHKERRQ(ierr); ierr = MatDestroyMatrices(1,&lGs);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatColoringCreateSmallestLastWeights(MatColoring mc,PetscReal *weights) { PetscInt *degrees,*degb,*llprev,*llnext; PetscInt j,i,s,e,n,nin,ln,lm,degree,maxdegree=0,bidx,idx,dist,distance=mc->dist; Mat lG,*lGs; IS ris; PetscErrorCode ierr; PetscInt *seen; const PetscInt *gidx; PetscInt *idxbuf; PetscInt *distbuf; PetscInt ncols,nxt,prv,cur; const PetscInt *cols; PetscBool isSEQAIJ; Mat_SeqAIJ *aij; PetscInt *Gi,*Gj,*rperm; Mat G = mc->mat; PetscReal *lweights,r; PetscRandom rand; PetscFunctionBegin; ierr = MatGetOwnershipRange(G,&s,&e);CHKERRQ(ierr); n=e-s; ierr = ISCreateStride(PetscObjectComm((PetscObject)G),n,s,1,&ris);CHKERRQ(ierr); ierr = MatIncreaseOverlap(G,1,&ris,distance+1);CHKERRQ(ierr); ierr = ISSort(ris);CHKERRQ(ierr); ierr = MatGetSubMatrices(G,1,&ris,&ris,MAT_INITIAL_MATRIX,&lGs);CHKERRQ(ierr); lG = lGs[0]; ierr = PetscObjectTypeCompare((PetscObject)lG,MATSEQAIJ,&isSEQAIJ);CHKERRQ(ierr); if (!isSEQAIJ) SETERRQ(PetscObjectComm((PetscObject)G),PETSC_ERR_ARG_WRONGSTATE,"Requires an MPI/SEQAIJ Matrix"); ierr = MatGetSize(lG,&ln,&lm);CHKERRQ(ierr); aij = (Mat_SeqAIJ*)lG->data; Gi = aij->i; Gj = aij->j; ierr = PetscMalloc3(lm,&seen,lm,&idxbuf,lm,&distbuf);CHKERRQ(ierr); ierr = PetscMalloc1(lm,°rees);CHKERRQ(ierr); ierr = PetscMalloc1(lm,&lweights);CHKERRQ(ierr); for (i=0;i<ln;i++) { seen[i]=-1; lweights[i] = 1.; } ierr = ISGetIndices(ris,&gidx);CHKERRQ(ierr); for (i=0;i<ln;i++) { bidx=-1; ncols = Gi[i+1]-Gi[i]; cols = &(Gj[Gi[i]]); degree = 0; /* place the distance-one neighbors on the queue */ for (j=0;j<ncols;j++) { bidx++; seen[cols[j]] = i; distbuf[bidx] = 1; idxbuf[bidx] = cols[j]; } while (bidx >= 0) { /* pop */ idx = idxbuf[bidx]; dist = distbuf[bidx]; bidx--; degree++; if (dist < distance) { ncols = Gi[idx+1]-Gi[idx]; cols = &(Gj[Gi[idx]]); for (j=0;j<ncols;j++) { if (seen[cols[j]] != i) { bidx++; seen[cols[j]] = i; idxbuf[bidx] = cols[j]; distbuf[bidx] = dist+1; } } } } degrees[i] = degree; if (degree > maxdegree) maxdegree = degree; } /* bucket by degree by some random permutation */ ierr = PetscRandomCreate(PetscObjectComm((PetscObject)mc),&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = PetscMalloc1(ln,&rperm);CHKERRQ(ierr); for (i=0;i<ln;i++) { ierr = PetscRandomGetValueReal(rand,&r);CHKERRQ(ierr); lweights[i] = r; rperm[i]=i; } ierr = PetscSortRealWithPermutation(lm,lweights,rperm);CHKERRQ(ierr); ierr = PetscMalloc1(maxdegree+1,°b);CHKERRQ(ierr); ierr = PetscMalloc2(ln,&llnext,ln,&llprev);CHKERRQ(ierr); for (i=0;i<maxdegree+1;i++) { degb[i] = -1; } for (i=0;i<ln;i++) { llnext[i] = -1; llprev[i] = -1; seen[i] = -1; } for (i=0;i<ln;i++) { idx = rperm[i]; llnext[idx] = degb[degrees[idx]]; if (degb[degrees[idx]] > 0) llprev[degb[degrees[idx]]] = idx; degb[degrees[idx]] = idx; } ierr = PetscFree(rperm);CHKERRQ(ierr); /* remove the lowest degree one */ i=0; nin=0; while (i != maxdegree+1) { for (i=1;i<maxdegree+1; i++) { if (degb[i] > 0) { cur = degb[i]; nin++; degrees[cur] = 0; degb[i] = llnext[cur]; bidx=-1; ncols = Gi[cur+1]-Gi[cur]; cols = &(Gj[Gi[cur]]); /* place the distance-one neighbors on the queue */ for (j=0;j<ncols;j++) { if (cols[j] != cur) { bidx++; seen[cols[j]] = i; distbuf[bidx] = 1; idxbuf[bidx] = cols[j]; } } while (bidx >= 0) { /* pop */ idx = idxbuf[bidx]; dist = distbuf[bidx]; bidx--; nxt=llnext[idx]; prv=llprev[idx]; if (degrees[idx] > 0) { /* change up the degree of the neighbors still in the graph */ if (lweights[idx] <= lweights[cur]) lweights[idx] = lweights[cur]+1; if (nxt > 0) { llprev[nxt] = prv; } if (prv > 0) { llnext[prv] = nxt; } else { degb[degrees[idx]] = nxt; } degrees[idx]--; llnext[idx] = degb[degrees[idx]]; llprev[idx] = -1; if (degb[degrees[idx]] >= 0) { llprev[degb[degrees[idx]]] = idx; } degb[degrees[idx]] = idx; if (dist < distance) { ncols = Gi[idx+1]-Gi[idx]; cols = &(Gj[Gi[idx]]); for (j=0;j<ncols;j++) { if (seen[cols[j]] != i) { bidx++; seen[cols[j]] = i; idxbuf[bidx] = cols[j]; distbuf[bidx] = dist+1; } } } } } break; } } } for (i=0;i<lm;i++) { if (gidx[i] >= s && gidx[i] < e) { weights[gidx[i]-s] = lweights[i]; } } ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFree(degb);CHKERRQ(ierr); ierr = PetscFree2(llnext,llprev);CHKERRQ(ierr); ierr = PetscFree(degrees);CHKERRQ(ierr); ierr = PetscFree(lweights);CHKERRQ(ierr); ierr = ISRestoreIndices(ris,&gidx);CHKERRQ(ierr); ierr = ISDestroy(&ris);CHKERRQ(ierr); ierr = PetscFree3(seen,idxbuf,distbuf);CHKERRQ(ierr); ierr = MatDestroyMatrices(1,&lGs);CHKERRQ(ierr); PetscFunctionReturn(0); }