int main(int argc,char **argv) { Mat A,B,As; PetscInt i,j,k,nz,n,*ai,*aj,asi[]={0,2,3,4,6,7}; PetscInt asj[]={0,4,1,2,3,4,4}; PetscScalar asa[7],*aa; PetscRandom rctx; PetscErrorCode ierr; PetscMPIInt size; PetscBool flg; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!"); /* Create a aij matrix for checking */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,5,5,2,PETSC_NULL,&A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); k = 0; for (i=0; i<5; i++) { nz = asi[i+1] - asi[i]; /* length of i_th row of A */ for (j=0; j<nz; j++){ ierr = PetscRandomGetValue(rctx,&asa[k]);CHKERRQ(ierr); ierr = MatSetValues(A,1,&i,1,&asj[k],&asa[k],INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(A,1,&i,1,&asj[k],&asa[k],INSERT_VALUES);CHKERRQ(ierr); if (i != asj[k]){ /* insert symmetric entry */ ierr = MatSetValues(A,1,&asj[k],1,&i,&asa[k],INSERT_VALUES);CHKERRQ(ierr); } k++; } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create a baij matrix using MatCreateSeqBAIJWithArrays() */ ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ai,&aj,&flg);CHKERRQ(ierr); ierr = MatGetArray(A,&aa);CHKERRQ(ierr); ierr = MatCreateSeqBAIJWithArrays(PETSC_COMM_SELF,1,5,5,ai,aj,aa,&B);CHKERRQ(ierr); ierr = MatRestoreArray(A,&aa);CHKERRQ(ierr); ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ai,&aj,&flg);CHKERRQ(ierr); ierr = MatMultEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"MatMult(A,B) are NOT equal"); /* Create a sbaij matrix using MatCreateSeqSBAIJWithArrays() */ ierr = MatCreateSeqSBAIJWithArrays(PETSC_COMM_SELF,1,5,5,asi,asj,asa,&As);CHKERRQ(ierr); ierr = MatMultEqual(A,As,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"MatMult(A,As) are NOT equal"); /* Free spaces */ ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&As);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
void destroy() { if (valid) { //clean up the local array structures I allocated. MatRestoreArray(mat, &data); PetscTruth done = PETSC_FALSE; MatRestoreRowIJ(mat, 0, PETSC_FALSE, PETSC_FALSE, &nrows, &ia, &ja, &done); assert(done == PETSC_TRUE || "Unexpected error: can't return csr structure to matrix"); } valid = false; }
int main(int argc,char **argv) { Mat A,B,C,D; PetscInt i,j,k,M=10,N=5; PetscScalar *array,*a; PetscErrorCode ierr; PetscRandom r; PetscTruth equal=PETSC_FALSE; PetscReal fill = 1.0; PetscInt rstart,rend,nza,col,am,an,bm,bn; PetscInitialize(&argc,&argv,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-N",&N,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-fill",&fill,PETSC_NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); /* create a aij matrix A */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,N,M);CHKERRQ(ierr); ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); nza = (PetscInt)(.3*M); /* num of nozeros in each row of A */ ierr = MatSeqAIJSetPreallocation(A,nza,PETSC_NULL);CHKERRQ(ierr); ierr = MatMPIAIJSetPreallocation(A,nza,PETSC_NULL,nza,PETSC_NULL);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); ierr = PetscMalloc((nza+1)*sizeof(PetscScalar),&a);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { for (j=0; j<nza; j++) { ierr = PetscRandomGetValue(r,&a[j]);CHKERRQ(ierr); col = (PetscInt)(M*PetscRealPart(a[j])); ierr = MatSetValues(A,1,&i,1,&col,&a[j],ADD_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* create a dense matrix B */ ierr = MatGetLocalSize(A,&am,&an);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(B,PETSC_DECIDE,am,N,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetType(B,MATDENSE);CHKERRQ(ierr); ierr = MatSeqDenseSetPreallocation(B,PETSC_NULL);CHKERRQ(ierr); ierr = MatMPIDenseSetPreallocation(B,PETSC_NULL);CHKERRQ(ierr); ierr = MatGetLocalSize(B,&bm,&bn);CHKERRQ(ierr); ierr = MatGetArray(B,&array);CHKERRQ(ierr); k = 0; for (j=0; j<N; j++){ /* local column-wise entries */ for (i=0; i<bm; i++){ ierr = PetscRandomGetValue(r,&array[k++]);CHKERRQ(ierr); } } ierr = MatRestoreArray(B,&array);CHKERRQ(ierr); ierr = PetscRandomDestroy(r);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatMatMult() */ ierr = MatMatMult(B,A,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); /* ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_MATLAB); ierr = MatView(C,0);CHKERRQ(ierr); ierr = MatView(B,0);CHKERRQ(ierr); ierr = MatView(A,0);CHKERRQ(ierr); */ ierr = MatMatMultSymbolic(B,A,fill,&D);CHKERRQ(ierr); for (i=0; i<2; i++){ ierr = MatMatMultNumeric(B,A,D);CHKERRQ(ierr); } ierr = MatEqual(C,D,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"C != D"); ierr = MatDestroy(D);CHKERRQ(ierr); ierr = MatDestroy(C);CHKERRQ(ierr); ierr = MatDestroy(B);CHKERRQ(ierr); ierr = MatDestroy(A);CHKERRQ(ierr); ierr = PetscFree(a);CHKERRQ(ierr); PetscFinalize(); return(0); }
int main(int argc,char **args) { Mat C,C1,F; Vec u,x,b; PetscErrorCode ierr; PetscMPIInt rank,nproc; PetscInt i,M = 10,m,n,nfact,nsolve; PetscScalar *array,rval; PetscReal norm,tol=1.e-12; IS perm,iperm; MatFactorInfo info; PetscRandom rand; PetscTruth flg; PetscInitialize(&argc,&args,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nproc);CHKERRQ(ierr); /* Create matrix and vectors */ ierr = PetscOptionsGetInt(PETSC_NULL,"-M",&M,PETSC_NULL);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,M,M);CHKERRQ(ierr); ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatGetLocalSize(C,&m,&n);CHKERRQ(ierr); if (m != n) SETERRQ2(PETSC_ERR_ARG_WRONG,"Matrix local size m %d must equal n %d",m,n); ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,n,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecDuplicate(x,&u);CHKERRQ(ierr); /* save the true solution */ /* Assembly */ ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatGetArray(C,&array);CHKERRQ(ierr); for (i=0; i<m*M; i++){ ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[i] = rval; } ierr = MatRestoreArray(C,&array);CHKERRQ(ierr); ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /*if (!rank) {printf("main, C: \n");} ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /* Test MatDuplicate() */ ierr = MatDuplicate(C,MAT_COPY_VALUES,&C1);CHKERRQ(ierr); ierr = MatEqual(C,C1,&flg);CHKERRQ(ierr); if (!flg){ SETERRQ(PETSC_ERR_ARG_WRONG,"Duplicate C1 != C"); } /* Test LU Factorization */ ierr = MatGetOrdering(C1,MATORDERING_NATURAL,&perm,&iperm);CHKERRQ(ierr); if (nproc == 1){ ierr = MatGetFactor(C1,MAT_SOLVER_PETSC,MAT_FACTOR_LU,&F);CHKERRQ(ierr); } else { ierr = MatGetFactor(C1,MAT_SOLVER_PLAPACK,MAT_FACTOR_LU,&F);CHKERRQ(ierr); } ierr = MatLUFactorSymbolic(F,C1,perm,iperm,&info);CHKERRQ(ierr); for (nfact = 0; nfact < 2; nfact++){ if (!rank) printf(" LU nfact %d\n",nfact); ierr = MatLUFactorNumeric(F,C1,&info);CHKERRQ(ierr); /* Test MatSolve() */ for (nsolve = 0; nsolve < 5; nsolve++){ ierr = VecGetArray(x,&array);CHKERRQ(ierr); for (i=0; i<m; i++){ ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[i] = rval; } ierr = VecRestoreArray(x,&array);CHKERRQ(ierr); ierr = VecCopy(x,u);CHKERRQ(ierr); ierr = MatMult(C,x,b);CHKERRQ(ierr); ierr = MatSolve(F,b,x);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(u,-1.0,x);CHKERRQ(ierr); /* u <- (-1.0)x + u */ ierr = VecNorm(u,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol){ if (!rank){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: Norm of error %g, LU nfact %d\n",norm,nfact);CHKERRQ(ierr); } } } } ierr = MatDestroy(C1);CHKERRQ(ierr); ierr = MatDestroy(F);CHKERRQ(ierr); /* Test Cholesky Factorization */ ierr = MatTranspose(C,MAT_INITIAL_MATRIX,&C1);CHKERRQ(ierr); /* C1 = C^T */ ierr = MatAXPY(C,1.0,C1,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* make C symmetric: C <- C + C^T */ ierr = MatShift(C,M);CHKERRQ(ierr); /* make C positive definite */ ierr = MatDestroy(C1);CHKERRQ(ierr); ierr = MatSetOption(C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatSetOption(C,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); if (nproc == 1){ ierr = MatGetFactor(C,MAT_SOLVER_PETSC,MAT_FACTOR_CHOLESKY,&F);CHKERRQ(ierr); } else { ierr = MatGetFactor(C,MAT_SOLVER_PLAPACK,MAT_FACTOR_CHOLESKY,&F);CHKERRQ(ierr); } ierr = MatCholeskyFactorSymbolic(F,C,perm,&info);CHKERRQ(ierr); for (nfact = 0; nfact < 2; nfact++){ if (!rank) printf(" Cholesky nfact %d\n",nfact); ierr = MatCholeskyFactorNumeric(F,C,&info);CHKERRQ(ierr); /* Test MatSolve() */ for (nsolve = 0; nsolve < 5; nsolve++){ ierr = VecGetArray(x,&array);CHKERRQ(ierr); for (i=0; i<m; i++){ ierr = PetscRandomGetValue(rand,&rval);CHKERRQ(ierr); array[i] = rval; } ierr = VecRestoreArray(x,&array);CHKERRQ(ierr); ierr = VecCopy(x,u);CHKERRQ(ierr); ierr = MatMult(C,x,b);CHKERRQ(ierr); ierr = MatSolve(F,b,x);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(u,-1.0,x);CHKERRQ(ierr); /* u <- (-1.0)x + u */ ierr = VecNorm(u,NORM_2,&norm);CHKERRQ(ierr); if (norm > tol){ if (!rank){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: Norm of error %g, Cholesky nfact %d\n",norm,nfact);CHKERRQ(ierr); } } } } ierr = MatDestroy(F);CHKERRQ(ierr); /* Free data structures */ ierr = PetscRandomDestroy(rand);CHKERRQ(ierr); ierr = ISDestroy(perm);CHKERRQ(ierr); ierr = ISDestroy(iperm);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); ierr = VecDestroy(b);CHKERRQ(ierr); ierr = VecDestroy(u);CHKERRQ(ierr); ierr = MatDestroy(C);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode MatMatSolve_SuperLU_DIST(Mat A,Mat B_mpi,Mat X) { Mat_SuperLU_DIST *lu = (Mat_SuperLU_DIST*)A->spptr; PetscErrorCode ierr; PetscMPIInt size; PetscInt M=A->rmap->N,m=A->rmap->n,nrhs; SuperLUStat_t stat; double berr[1]; PetscScalar *bptr; int info; /* SuperLU_Dist info code is ALWAYS an int, even with long long indices */ PetscBool flg; PetscFunctionBegin; if (lu->options.Fact != FACTORED) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"SuperLU_DIST options.Fact mush equal FACTORED"); ierr = PetscObjectTypeCompareAny((PetscObject)B_mpi,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr); if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,PETSC_NULL);CHKERRQ(ierr); if (!flg) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); ierr = MPI_Comm_size(((PetscObject)A)->comm,&size);CHKERRQ(ierr); if (size > 1 && lu->MatInputMode == GLOBAL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatInputMode=GLOBAL for nproc %d>1 is not supported",size); /* size==1 or distributed mat input */ if (lu->options.SolveInitialized && !lu->matmatsolve_iscalled){ /* communication pattern of SOLVEstruct is unlikely created for matmatsolve, thus destroy it and create a new SOLVEstruct. Otherwise it may result in memory corruption or incorrect solution See src/mat/examples/tests/ex125.c */ #if defined(PETSC_USE_COMPLEX) zSolveFinalize(&lu->options, &lu->SOLVEstruct); #else dSolveFinalize(&lu->options, &lu->SOLVEstruct); #endif lu->options.SolveInitialized = NO; } ierr = MatCopy(B_mpi,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatGetSize(B_mpi,PETSC_NULL,&nrhs);CHKERRQ(ierr); PStatInit(&stat); /* Initialize the statistics variables. */ ierr = MatGetArray(X,&bptr);CHKERRQ(ierr); if (lu->MatInputMode == GLOBAL) { /* size == 1 */ #if defined(PETSC_USE_COMPLEX) pzgssvx_ABglobal(&lu->options, &lu->A_sup, &lu->ScalePermstruct,(doublecomplex*)bptr, M, nrhs, &lu->grid, &lu->LUstruct, berr, &stat, &info); #else pdgssvx_ABglobal(&lu->options, &lu->A_sup, &lu->ScalePermstruct,bptr, M, nrhs, &lu->grid, &lu->LUstruct, berr, &stat, &info); #endif } else { /* distributed mat input */ #if defined(PETSC_USE_COMPLEX) pzgssvx(&lu->options,&lu->A_sup,&lu->ScalePermstruct,(doublecomplex*)bptr,m,nrhs,&lu->grid, &lu->LUstruct,&lu->SOLVEstruct,berr,&stat,&info); #else pdgssvx(&lu->options,&lu->A_sup,&lu->ScalePermstruct,bptr,m,nrhs,&lu->grid, &lu->LUstruct,&lu->SOLVEstruct,berr,&stat,&info); #endif } if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"pdgssvx fails, info: %d\n",info); ierr = MatRestoreArray(X,&bptr);CHKERRQ(ierr); if (lu->options.PrintStat) { PStatPrint(&lu->options, &stat, &lu->grid); /* Print the statistics. */ } PStatFree(&stat); lu->matsolve_iscalled = PETSC_FALSE; lu->matmatsolve_iscalled = PETSC_TRUE; PetscFunctionReturn(0); }
nrecvs = from->n; while (nrecvs) { ierr = MPI_Waitany(from->n,rwaits,&imdex,&status);CHKERRQ(ierr); nrecvs--; /* unpack a message at a time */ CHKMEMQ; for (j=0; j<rstarts[imdex+1]-rstarts[imdex]; j++){ for (k=0; k<ncols; k++) { w[rindices[rstarts[imdex]+j] + nrows*k] = rvalues[ncols*(rstarts[imdex] + j) + k]; } } CHKMEMQ; } if (to->n) {ierr = MPI_Waitall(to->n,swaits,to->sstatus);CHKERRQ(ierr)} ierr = MatRestoreArray(B,&b);CHKERRQ(ierr); ierr = MatRestoreArray(workB,&w);CHKERRQ(ierr); ierr = MatAssemblyBegin(workB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(workB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); } extern PetscErrorCode MatMatMultNumericAdd_SeqAIJ_SeqDense(Mat,Mat,Mat); #undef __FUNCT__ #define __FUNCT__ "MatMatMultNumeric_MPIAIJ_MPIDense" PetscErrorCode MatMatMultNumeric_MPIAIJ_MPIDense(Mat A,Mat B,Mat C) { PetscErrorCode ierr; Mat_MPIAIJ *aij = (Mat_MPIAIJ*)A->data; Mat_MPIDense *bdense = (Mat_MPIDense*)B->data; Mat_MPIDense *cdense = (Mat_MPIDense*)C->data;