Example #1
0
/******************************************************************************
 * Applies the PARALLEL matrix vector mulitplication of a block of vectors.
 * Because a block function is not available, we call blockSize times
 * the Parasails function MatrixMatvec()
 *
******************************************************************************/
void par_MatrixMatvec(void *x, void *y, int *blockSize, 
   primme_params *primme) {
   
   int i;
   double *xvec, *yvec;
   xvec = (double *)x;
   yvec = (double *)y;

   for (i=0;i<*blockSize;i++) {
      MatrixMatvec(primme->matrix, &xvec[primme->nLocal*i], 
		      		   &yvec[primme->nLocal*i]);
   }

}
Example #2
0
void PCG_ParaSails(Matrix *mat, ParaSails *ps, double *b, double *x,
   double tol, HYPRE_Int max_iter)
{
   double *p, *s, *r;
   double alpha, beta;
   double gamma, gamma_old;
   double bi_prod, i_prod, eps;
   HYPRE_Int i = 0;
   HYPRE_Int mype;

   /* local problem size */
   HYPRE_Int n = mat->end_row - mat->beg_row + 1;

   MPI_Comm comm = mat->comm;
   hypre_MPI_Comm_rank(comm, &mype);

   /* compute square of absolute stopping threshold  */
   /* bi_prod = <b,b> */
   bi_prod = InnerProd(n, b, b, comm);
   eps = (tol*tol)*bi_prod;

   /* Check to see if the rhs vector b is zero */
   if (bi_prod == 0.0)
   {
      /* Set x equal to zero and return */
      CopyVector(n, b, x);
      return;
   }

   p = (double *) malloc(n * sizeof(double));
   s = (double *) malloc(n * sizeof(double));
   r = (double *) malloc(n * sizeof(double));

   /* r = b - Ax */
   MatrixMatvec(mat, x, r);  /* r = Ax */
   ScaleVector(n, -1.0, r);  /* r = -r */
   Axpy(n, 1.0, b, r);       /* r = r + b */
 
   /* p = C*r */
   if (ps != NULL)
      ParaSailsApply(ps, r, p);
   else
      CopyVector(n, r, p);

   /* gamma = <r,p> */
   gamma = InnerProd(n, r, p, comm);

   while ((i+1) <= max_iter)
   {
      i++;

      /* s = A*p */
      MatrixMatvec(mat, p, s);

      /* alpha = gamma / <s,p> */
      alpha = gamma / InnerProd(n, s, p, comm);

      gamma_old = gamma;

      /* x = x + alpha*p */
      Axpy(n, alpha, p, x);

      /* r = r - alpha*s */
      Axpy(n, -alpha, s, r);
         
      /* s = C*r */
      if (ps != NULL)
         ParaSailsApply(ps, r, s);
      else
         CopyVector(n, r, s);

      /* gamma = <r,s> */
      gamma = InnerProd(n, r, s, comm);

      /* set i_prod for convergence test */
      i_prod = InnerProd(n, r, r, comm);

#ifdef PARASAILS_CG_PRINT
      if (mype == 0 && i % 100 == 0)
         hypre_printf("Iter (%d): rel. resid. norm: %e\n", i, sqrt(i_prod/bi_prod));
#endif

      /* check for convergence */
      if (i_prod < eps)
         break;

      /* non-convergence test */
      if (i >= 1000 && i_prod/bi_prod > 0.01)
      {
         if (mype == 0)
            hypre_printf("Aborting solve due to slow or no convergence.\n");
         break;
      }
 
      /* beta = gamma / gamma_old */
      beta = gamma / gamma_old;

      /* p = s + beta p */
      ScaleVector(n, beta, p);   
      Axpy(n, 1.0, s, p);
   }

   free(p);
   free(s);

   /* compute exact relative residual norm */
   MatrixMatvec(mat, x, r);  /* r = Ax */
   ScaleVector(n, -1.0, r);  /* r = -r */
   Axpy(n, 1.0, b, r);       /* r = r + b */
   i_prod = InnerProd(n, r, r, comm);

   free(r);

   if (mype == 0)
      hypre_printf("Iter (%4d): computed rrn    : %e\n", i, sqrt(i_prod/bi_prod));
}
Example #3
0
static void matvec_timing(MPI_Comm comm, Matrix *mat)
{
   HYPRE_Real time0, time1;
   HYPRE_Real trial1, trial2, trial3, trial4, trial5, trial6;
   HYPRE_Real *temp1, *temp2;
   HYPRE_Int i, mype;
   HYPRE_Int n = mat->end_row - mat->beg_row + 1;

   temp1 = (HYPRE_Real *) calloc(n, sizeof(HYPRE_Real));
   temp2 = (HYPRE_Real *) calloc(n, sizeof(HYPRE_Real));

   /* warm-up */
   hypre_MPI_Barrier(comm);
   for (i=0; i<100; i++)
      MatrixMatvec(mat, temp1, temp2);

   hypre_MPI_Barrier(comm);
   time0 = hypre_MPI_Wtime();
   for (i=0; i<100; i++)
      MatrixMatvec(mat, temp1, temp2);
   hypre_MPI_Barrier(comm);
   time1 = hypre_MPI_Wtime();
   trial1 = time1-time0;

   hypre_MPI_Barrier(comm);
   time0 = hypre_MPI_Wtime();
   for (i=0; i<100; i++)
      MatrixMatvec(mat, temp1, temp2);
   hypre_MPI_Barrier(comm);
   time1 = hypre_MPI_Wtime();
   trial2 = time1-time0;

   hypre_MPI_Barrier(comm);
   time0 = hypre_MPI_Wtime();
   for (i=0; i<100; i++)
      MatrixMatvec(mat, temp1, temp2);
   hypre_MPI_Barrier(comm);
   time1 = hypre_MPI_Wtime();
   trial3 = time1-time0;

   hypre_MPI_Barrier(comm);
   time0 = hypre_MPI_Wtime();
   for (i=0; i<100; i++)
      MatrixMatvecSerial(mat, temp1, temp2);
   hypre_MPI_Barrier(comm);
   time1 = hypre_MPI_Wtime();
   trial4 = time1-time0;

   hypre_MPI_Barrier(comm);
   time0 = hypre_MPI_Wtime();
   for (i=0; i<100; i++)
      MatrixMatvecSerial(mat, temp1, temp2);
   hypre_MPI_Barrier(comm);
   time1 = hypre_MPI_Wtime();
   trial5 = time1-time0;

   hypre_MPI_Barrier(comm);
   time0 = hypre_MPI_Wtime();
   for (i=0; i<100; i++)
      MatrixMatvecSerial(mat, temp1, temp2);
   hypre_MPI_Barrier(comm);
   time1 = hypre_MPI_Wtime();
   trial6 = time1-time0;

   hypre_MPI_Comm_rank(comm, &mype);
   if (mype == 0)
      hypre_printf("Timings: %f %f %f Serial: %f %f %f\n", 
                   trial1, trial2, trial3, trial4, trial5, trial6);

   fflush(stdout);

   /* this is all we wanted, so don't waste any more cycles */
   exit(0);
}