[petsc-users] Speedup calculation of a high number of generalized eigenvalue problems
Thomas Hisch
t.hisch at gmail.com
Thu Aug 9 04:06:50 CDT 2012
On Wed, Aug 8, 2012 at 1:43 PM, Jose E. Roman <jroman at dsic.upv.es> wrote:
>
> El 08/08/2012, a las 11:52, Thomas Hisch escribió:
>
>> Hello list,
>>
>> What can be done to speedup the calculation of the eigenvals and
>> eigenvecs of many (~1000)!! generalized EVP, where the operator A is
>> constant for all GEVPs and only B is different (but the nonzero
>> pattern, size, type,.. are the same for all B). For now I create an
>> EPS object for every pair (A,B) like in the following code: (Note: B
>> is updated in other functions)
>>
>>
>> void SlepcEigenSolver::Solve(ngbla::Matrix<ngla::Complex> &evecs,
>> ngbla::Vector<ngla::Complex> &evals)
>> {
>> ....
>>
>> Vec xev;
>> MatGetVecs(A_,PETSC_NULL,&xev);
>> PetscPrintf(PETSC_COMM_WORLD,"Create EPS object and solve eigensystem\n");
>> EPSCreate(PETSC_COMM_WORLD, &eps_);
>> EPSSetOperators(eps_,A_,B_);
>> EPSSetDimensions(eps_, GetNev(), PETSC_DECIDE, PETSC_DECIDE);
>> EPSSetFromOptions(eps_);
>>
>> PetscScalar target = GetShift();
>> target *= target;
>>
>> EPSSetTarget(eps_,target);
>> EPSSetWhichEigenpairs(eps_,EPS_TARGET_MAGNITUDE);
>>
>> ST myst;
>> EPSGetST(eps_,&myst);
>> STSetType(myst,STSINVERT);
>>
>> PetscLogDouble t1,t2,t3;
>> PetscGetTime(&t1);
>> EPSSetUp(eps_);
>> PetscGetTime(&t2);
>> EPSSolve(eps_);
>> PetscGetTime(&t3);
>> PetscPrintf(PETSC_COMM_WORLD," -> EPS Solving Done\n\n");
>> PetscPrintf(PETSC_COMM_WORLD,"EPS: Elapsed time: %G (setup), %G
>> (solve)\n",t2-t1,t3-t2);
>>
>> PetscInt its;
>> EPSGetIterationNumber(eps_,&its);
>>
>> PetscPrintf(PETSC_COMM_WORLD, "number of iterations of the method %D\n", its);
>>
>> PetscInt nconv;
>> EPSGetConverged(eps_,&nconv);
>> PetscPrintf(PETSC_COMM_WORLD," Number of converged eigenpairs: %D\n\n",nconv);
>>
>> if (nconv>0) {
>> evals.SetSize(nconv);
>> if(!rank_) {
>> evecs.SetSize(matsize,nconv);
>> }
>>
>> PetscScalar lambda; // = k
>> PetscReal error,re,im;
>>
>> for (PetscInt i=0;i<nconv;i++) {
>> // Get converged eigenpairs: i-th eigenvalue is stored in kr
>> (real part) and
>> // ki (imaginary part)
>> EPSGetEigenpair(eps_,i,&lambda,PETSC_NULL,xev,PETSC_NULL);
>>
>> PetscScalar* tmpptr;
>>
>> // begin ugly inefficient(?) eigenvector gather code
>> {
>> VecScatter ctx;
>> Vec vout;
>> VecScatterCreateToZero(xev,&ctx,&vout);
>> // scatter as many times as you need
>> VecScatterBegin(ctx,xev,vout,INSERT_VALUES,SCATTER_FORWARD);
>> VecScatterEnd(ctx,xev,vout,INSERT_VALUES,SCATTER_FORWARD);
>>
>> int locsize;
>> VecGetLocalSize(vout,&locsize);
>> VecGetArray(vout,&tmpptr);
>> if(!rank_) {
>> const ngla::Complex *evecptr = static_cast<ngbla::Complex*>(tmpptr);
>>
>> for(size_t j = 0; j < matsize; j++) {
>> evecs(j,i) = evecptr[j];
>> }
>> }
>>
>> VecRestoreArray(xev, &tmpptr);
>> // destroy scatter context and local vector when no longer needed
>> VecScatterDestroy(&ctx);
>> VecDestroy(&vout);
>> }
>> /* end ugly inefficient(?) vector gather code */
>>
>> evals(i) = static_cast<ngla::Complex>(lambda);
>> }
>> PetscPrintf(PETSC_COMM_WORLD,"\n");
>> }
>>
>> VecDestroy(&xev);
>> EPSDestroy(&eps_);
>>
>> if(!nconv)
>> return;
>>
>> if(rank_)
>> evecs.SetSize(matsize,nconv);
>>
>> //every process already owns all the eigenvalues
>> //but not all eigenstates -> only bcast all eigenstates
>> MPI_Bcast(&evecs(0), nconv*matsize, MPI_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
>> }
>>
>> Here are some facts about my EVP:
>> The dimension of the Operators A & B is ~90000.
>> For nev=1 the setup time (EPSSetUp) is 18sec, and the solve time
>> 11sec. (on 16 nodes)
>> -> number of iterations of the method 2
>> number of converged eigenpairs: 6
>>
>> For nev=150 the setup time (EPSSetUp) is 18sec, and the solve time
>> 65sec. (on 16 nodes)
>> -> number of iterations of the method 1
>> number of converged eigenpairs: 155
>> (The output of -log_summary is attached)
>>
>>
>> Do you think that there is any benefit in creating the EPS object at
>> the beginning of my program and only call EPSSetOperators in my Solve
>> function?
>>
>> Regards
>> Thomas
>> <out_nodebugging_full.log>
>
> Yes, you can get some modest benefit. I would strongly suggest using a parallel linear solver such as MUMPS. See section 3.4.1 of SLEPc's manual.
> Jose
Thx. This does wonders!! The Setup time went down from 18sec to 1 sec
and the Solve time from 65sec to 10 sec.
Regards
Thomas
>
More information about the petsc-users
mailing list