int main(int argc,char **argv) { KSP solver; PC pc; Mat A,B; Vec X,Y,Z; MatScalar *a; PetscScalar *b,*x,*y,*z; PetscReal nrm; PetscErrorCode ierr,size=8,lda=10, i,j; PetscInitialize(&argc,&argv,0,help); /* Create matrix and three vectors: these are all normal */ ierr = PetscMalloc1(lda*size,&b);CHKERRQ(ierr); for (i=0; i<size; i++) { for (j=0; j<size; j++) { b[i+j*lda] = rand(); } } ierr = MatCreate(MPI_COMM_SELF,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,size,size,size,size);CHKERRQ(ierr); ierr = MatSetType(A,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr); ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr); for (i=0; i<size; i++) { for (j=0; j<size; j++) { a[i+j*size] = b[i+j*lda]; } } ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,size,size,size,size);CHKERRQ(ierr); ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(B,b);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(B,lda);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscMalloc1(size,&x);CHKERRQ(ierr); for (i=0; i<size; i++) x[i] = 1.0; ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size,x,&X);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = PetscMalloc1(size,&y);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size,y,&Y);CHKERRQ(ierr); ierr = VecAssemblyBegin(Y);CHKERRQ(ierr); ierr = VecAssemblyEnd(Y);CHKERRQ(ierr); ierr = PetscMalloc1(size,&z);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size,z,&Z);CHKERRQ(ierr); ierr = VecAssemblyBegin(Z);CHKERRQ(ierr); ierr = VecAssemblyEnd(Z);CHKERRQ(ierr); /* * Solve with A and B */ ierr = KSPCreate(MPI_COMM_SELF,&solver);CHKERRQ(ierr); ierr = KSPSetType(solver,KSPPREONLY);CHKERRQ(ierr); ierr = KSPGetPC(solver,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCLU);CHKERRQ(ierr); ierr = KSPSetOperators(solver,A,A);CHKERRQ(ierr); ierr = KSPSolve(solver,X,Y);CHKERRQ(ierr); ierr = KSPSetOperators(solver,B,B);CHKERRQ(ierr); ierr = KSPSolve(solver,X,Z);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); printf("Test1; error norm=%e\n",nrm); /* Free spaces */ ierr = PetscFree(b);CHKERRQ(ierr); ierr = PetscFree(x);CHKERRQ(ierr); ierr = PetscFree(y);CHKERRQ(ierr); ierr = PetscFree(z);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); ierr = VecDestroy(&Z);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = KSPDestroy(&solver);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { Mat A,A11,A12,A21,A22; Vec X,X1,X2,Y,Z,Z1,Z2; PetscScalar *a,*b,*x,*y,*z,v,one=1; PetscReal nrm; PetscErrorCode ierr; PetscInt size=8,size1=6,size2=2, i,j; PetscInitialize(&argc,&argv,0,help); /* * Create matrix and three vectors: these are all normal */ ierr = PetscMalloc(size*size*sizeof(PetscScalar),&a);CHKERRQ(ierr); ierr = PetscMalloc(size*size*sizeof(PetscScalar),&b);CHKERRQ(ierr); for (i=0; i<size; i++) { for (j=0; j<size; j++) { a[i+j*size] = rand(); b[i+j*size] = a[i+j*size]; } } ierr = MatCreate(MPI_COMM_SELF,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,size,size,size,size);CHKERRQ(ierr); ierr = MatSetType(A,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A,a);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(PetscScalar),&x);CHKERRQ(ierr); for (i=0; i<size; i++) { x[i] = one; } ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size,x,&X);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(PetscScalar),&y);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size,y,&Y);CHKERRQ(ierr); ierr = VecAssemblyBegin(Y);CHKERRQ(ierr); ierr = VecAssemblyEnd(Y);CHKERRQ(ierr); ierr = PetscMalloc(size*sizeof(PetscScalar),&z);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size,z,&Z);CHKERRQ(ierr); ierr = VecAssemblyBegin(Z);CHKERRQ(ierr); ierr = VecAssemblyEnd(Z);CHKERRQ(ierr); /* * Now create submatrices and subvectors */ ierr = MatCreate(MPI_COMM_SELF,&A11);CHKERRQ(ierr); ierr = MatSetSizes(A11,size1,size1,size1,size1);CHKERRQ(ierr); ierr = MatSetType(A11,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A11,b);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A11,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A11,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&A12);CHKERRQ(ierr); ierr = MatSetSizes(A12,size1,size2,size1,size2);CHKERRQ(ierr); ierr = MatSetType(A12,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A12,b+size1*size);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A12,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&A21);CHKERRQ(ierr); ierr = MatSetSizes(A21,size2,size1,size2,size1);CHKERRQ(ierr); ierr = MatSetType(A21,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A21,b+size1);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A21,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A21,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A21,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreate(MPI_COMM_SELF,&A22);CHKERRQ(ierr); ierr = MatSetSizes(A22,size2,size2,size2,size2);CHKERRQ(ierr); ierr = MatSetType(A22,MATSEQDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(A22,b+size1*size+size1);CHKERRQ(ierr); ierr = MatSeqDenseSetLDA(A22,size);CHKERRQ(ierr); ierr = MatAssemblyBegin(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size1,x,&X1);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size2,x+size1,&X2);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size1,z,&Z1);CHKERRQ(ierr); ierr = VecCreateSeqWithArray(MPI_COMM_SELF,1,size2,z+size1,&Z2);CHKERRQ(ierr); /* * Now multiple matrix times input in two ways; * compare the results */ ierr = MatMult(A,X,Y);CHKERRQ(ierr); ierr = MatMult(A11,X1,Z1);CHKERRQ(ierr); ierr = MatMultAdd(A12,X2,Z1,Z1);CHKERRQ(ierr); ierr = MatMult(A22,X2,Z2);CHKERRQ(ierr); ierr = MatMultAdd(A21,X1,Z2,Z2);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); ierr = PetscPrintf(PETSC_COMM_WORLD,"Test1; error norm=%G\n",nrm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"MatMult the usual way:\n");CHKERRQ(ierr); ierr = VecView(Y,0);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"MatMult by subblock:\n");CHKERRQ(ierr); ierr = VecView(Z,0);CHKERRQ(ierr); /* * Next test: change both matrices */ v = rand(); i=1; j=size-2; ierr = MatSetValues(A,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); j -= size1; ierr = MatSetValues(A12,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); v = rand(); i=j=size1+1; ierr = MatSetValues(A,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i =j=1; ierr = MatSetValues(A22,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A12,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A22,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,X,Y);CHKERRQ(ierr); ierr = MatMult(A11,X1,Z1);CHKERRQ(ierr); ierr = MatMultAdd(A12,X2,Z1,Z1);CHKERRQ(ierr); ierr = MatMult(A22,X2,Z2);CHKERRQ(ierr); ierr = MatMultAdd(A21,X1,Z2,Z2);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); ierr = PetscPrintf(PETSC_COMM_WORLD,"Test2; error norm=%G\n",nrm);CHKERRQ(ierr); /* * Transpose product */ ierr = MatMultTranspose(A,X,Y);CHKERRQ(ierr); ierr = MatMultTranspose(A11,X1,Z1);CHKERRQ(ierr); ierr = MatMultTransposeAdd(A21,X2,Z1,Z1);CHKERRQ(ierr); ierr = MatMultTranspose(A22,X2,Z2);CHKERRQ(ierr); ierr = MatMultTransposeAdd(A12,X1,Z2,Z2);CHKERRQ(ierr); ierr = VecAXPY(Z,-1.0,Y);CHKERRQ(ierr); ierr = VecNorm(Z,NORM_2,&nrm); ierr = PetscPrintf(PETSC_COMM_WORLD,"Test3; error norm=%G\n",nrm);CHKERRQ(ierr); ierr = PetscFree(a);CHKERRQ(ierr); ierr = PetscFree(b);CHKERRQ(ierr); ierr = PetscFree(x);CHKERRQ(ierr); ierr = PetscFree(y);CHKERRQ(ierr); ierr = PetscFree(z);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&A11);CHKERRQ(ierr); ierr = MatDestroy(&A12);CHKERRQ(ierr); ierr = MatDestroy(&A21);CHKERRQ(ierr); ierr = MatDestroy(&A22);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); ierr = VecDestroy(&Z);CHKERRQ(ierr); ierr = VecDestroy(&X1);CHKERRQ(ierr); ierr = VecDestroy(&X2);CHKERRQ(ierr); ierr = VecDestroy(&Z1);CHKERRQ(ierr); ierr = VecDestroy(&Z2);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static void PETScMatvecGenColumnMajor(void *x, PRIMME_INT ldx, void *y, PRIMME_INT ldy, int blockSize, int trans, Mat matrix, MPI_Comm comm) { PetscInt m, n, mLocal, nLocal; PetscErrorCode ierr; Mat X, Y, X0, Y0; int xcompact, ycompact; if (blockSize == 1) { PETScMatvecGenNoBlock(x, ldx, y, ldy, blockSize, trans, matrix, comm); return; } assert(sizeof(PetscScalar) == sizeof(SCALAR)); ierr = MatGetSize(matrix, &m, &n); CHKERRABORT(comm, ierr); ierr = MatGetLocalSize(matrix, &mLocal, &nLocal); CHKERRABORT(comm, ierr); if (trans == 0) { ierr = MatCreateDense(comm,nLocal,PETSC_DECIDE,n,blockSize,x,&X);CHKERRABORT(comm, ierr); ierr = MatCreateDense(comm,mLocal,PETSC_DECIDE,m,blockSize,y,&Y);CHKERRABORT(comm, ierr); xcompact = nLocal == ldx; ycompact = mLocal == ldy; } else { ierr = MatCreateDense(comm,mLocal,PETSC_DECIDE,m,blockSize,x,&X);CHKERRABORT(comm, ierr); ierr = MatCreateDense(comm,nLocal,PETSC_DECIDE,n,blockSize,y,&Y);CHKERRABORT(comm, ierr); xcompact = mLocal == ldx; ycompact = nLocal == ldy; } ierr = MatDenseGetLocalMatrix(X, &X0);CHKERRABORT(comm, ierr); ierr = MatSeqDenseSetLDA(X0, (PetscInt)ldx);CHKERRABORT(comm, ierr); ierr = MatDenseGetLocalMatrix(Y, &Y0);CHKERRABORT(comm, ierr); ierr = MatSeqDenseSetLDA(Y0, (PetscInt)ldy);CHKERRABORT(comm, ierr); /* MatMatMult doesn't support X to be non-contiguous */ if (xcompact) { X0 = X; } else { ierr = MatDuplicate(X, MAT_COPY_VALUES, &X0);CHKERRABORT(comm, ierr); } if (trans == 0) { if (ycompact) { ierr = MatMatMult(matrix, X0, MAT_REUSE_MATRIX, PETSC_DEFAULT, &Y); CHKERRABORT(comm, ierr); } else { ierr = MatMatMult(matrix, X0, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &Y0); CHKERRABORT(comm, ierr); ierr = MatCopy(Y0, Y, SAME_NONZERO_PATTERN); CHKERRABORT(comm, ierr); ierr = MatDestroy(&Y0); CHKERRABORT(comm, ierr); } } else { /* A^H*X is not implemented in PETSc, do instead (A^T*X^c)^c */ ierr = MatConjugate(X0); CHKERRABORT(comm, ierr); if (ycompact) { ierr = MatTransposeMatMult(matrix, X0, MAT_REUSE_MATRIX, PETSC_DEFAULT, &Y); CHKERRABORT(comm, ierr); } else { ierr = MatTransposeMatMult(matrix, X0, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &Y0); CHKERRABORT(comm, ierr); ierr = MatCopy(Y0, Y, SAME_NONZERO_PATTERN); CHKERRABORT(comm, ierr); ierr = MatDestroy(&Y0); CHKERRABORT(comm, ierr); } ierr = MatConjugate(Y); CHKERRABORT(comm, ierr); if (xcompact) { ierr = MatConjugate(X0); CHKERRABORT(comm, ierr); } } if (!xcompact) { ierr = MatDestroy(&X0);CHKERRABORT(comm, ierr); } ierr = MatDestroy(&X);CHKERRABORT(comm, ierr); ierr = MatDestroy(&Y);CHKERRABORT(comm, ierr); }