PtMatrix MatrixMultiplication (PtMatrix pmat1, PtMatrix pmat2)
{
  PtMatrix multiplication_result;
  int i, j, k;

  /* Vê se as matrizes existem */
  if ((pmat1 == NULL) || (pmat2 == NULL)) { Error = NO_MATRIX; return 0; }

  /* Ver se pmat1->NC == pmat2->NL */
  if(pmat1->NC==pmat2->NL){
    Error = BAD_SIZE;
    return 0;
  }

  if ((multiplication_result = MatrixCreate (pmat1->NL, pmat1->NC)) == NULL)
    return NULL;

  for(k=0; k < pmat1->NC; k++){
    for(i=0; i < pmat1->NL; i++){
      for(j=0; j < pmat2->NC; j++){
        multiplication_result->Matrix[i][j] = pmat1->Matrix[i][k] * pmat2->Matrix[k][j];
      }
    }
  }

  Error = OK;
  return multiplication_result;
}
Пример #2
0
/******************************************************************************
 * Convert CSR matrix format to Parasails matrix format 
 *
******************************************************************************/
Matrix* csrToParaSails(int procID, int *map, int *fg2or, int *or2fg, int *IA,
   int *JA, double *AElts, MPI_Comm comm) {

   int i, j;
   int ncols;
   int origRow;
   int rowStart, rangeStart;
   int rowEnd, rangeEnd;
   Matrix *newMatrix;

   rangeStart = map[procID];
   rangeEnd = map[procID+1]-1;
   newMatrix = MatrixCreate(comm, rangeStart, rangeEnd);

   for (i = rangeStart; i <= rangeEnd; i++) {
      origRow = fg2or[i];
      rowStart = IA[origRow];
      rowEnd = IA[origRow+1]-1;
      ncols = rowEnd - rowStart + 1;

      for (j=rowStart; j <= rowEnd; j++) {
         JA[j] = or2fg[JA[j]];
      }

      MatrixSetRow(newMatrix, i, ncols, &JA[rowStart], &AElts[rowStart]);

      for (j=rowStart; j <= rowEnd; j++) {
         JA[j] = fg2or[JA[j]];
      }
   }

   MatrixComplete(newMatrix);

   return newMatrix;
}
PtMatrix MatrixCreateFile (char *pnomef)
{
  PtMatrix Mat; FILE *PtF; unsigned int NL, NC, I, J;

  /* abertura com validacao do ficheiro para leitura */
  if ( (PtF = fopen (pnomef, "r")) == NULL)
  { Error = NO_FILE; return NULL; }

  /* leitura da dimensão da matriz do ficheiro e criação da matriz */
  fscanf (PtF, "%d%d", &NL, &NC);
  if ((NL < 1) || (NC < 1)) { Error = BAD_SIZE; fclose (PtF); return NULL; }

  if ((Mat = MatrixCreate (NL, NC)) == NULL)
  { fclose (PtF); return NULL; }

  /* leitura das componentes da matriz do ficheiro */
  for (I = 0; I < NL; I++) 
  {
    for (J = 0; J < NC; J++) fscanf (PtF, "%d", &Mat->Matrix[I][J]);
    fscanf (PtF, "%*[^\n]"); fscanf (PtF, "%*c");
  }

  fclose (PtF);  /* fecho do ficheiro */

  return Mat;  /* devolve a matriz criada */
}
Пример #4
0
static Matrix *convert_matrix(MPI_Comm comm, HYPRE_DistributedMatrix *distmat)
{
   HYPRE_Int beg_row, end_row, row, dummy;
   HYPRE_Int len, *ind;
   HYPRE_Real *val;
   Matrix *mat;

   HYPRE_DistributedMatrixGetLocalRange(distmat, &beg_row, &end_row,
                                        &dummy, &dummy);

   mat = MatrixCreate(comm, beg_row, end_row);

   for (row=beg_row; row<=end_row; row++)
   {
      HYPRE_DistributedMatrixGetRow(distmat, row, &len, &ind, &val);
      MatrixSetRow(mat, row, len, ind, val);
      HYPRE_DistributedMatrixRestoreRow(distmat, row, &len, &ind, &val);
   }

   MatrixComplete(mat);

#ifdef BALANCE_INFO
   matvec_timing(comm, mat);
   balance_info(comm, mat);
#endif

   return mat;
}
Пример #5
0
PtMatrix MatrixCreateFile (char *pnomef)
{
  PtMatrix Mat; FILE *PtF; unsigned int NL, NC, l, c;

  /* abertura com validacao do ficheiro para leitura - opening the text file for reading */
  if ( (PtF = fopen (pnomef, "r")) == NULL)
  { Error = NO_FILE; return NULL; }

  /* leitura da dimensão da matriz do ficheiro - reading the matrix's size from the text file */
  fscanf (PtF, "%d%d", &NL, &NC);
  if ((NL < 1) || (NC < 1)) { Error = BAD_SIZE; fclose (PtF); return NULL; }

  /* criação da matriz nula - creating an empty matrix */
  if ((Mat = MatrixCreate (NL, NC)) == NULL)
  { fclose (PtF); return NULL; }

  /* leitura dos elementos da matriz do ficheiro - reading the matrix's elements from the text file */
  for (l = 0; l < NL; l++)
  {
    for (c = 0; c < NC; c++) fscanf (PtF, "%lf", &Mat->Matrix[l][c]);
    fscanf (PtF, "%*[^\n]"); fscanf (PtF, "%*c");
  }

  fclose (PtF);  /* fecho do ficheiro - closing the text file */
  return Mat;  /* devolve a matriz criada - returning the new matrix */
}
Пример #6
0
void PETScLinearSolver::Init(const int *sparse_index)
{
   if(sparse_index)
   {
      d_nz = sparse_index[0];
      o_nz = sparse_index[1];
      nz = sparse_index[2]; 
      m_size_loc = sparse_index[3];
   }   
    
   VectorCreate(m_size);   
   MatrixCreate(m_size, m_size);

   global_x = new PetscScalar[m_size];

}
Пример #7
0
PtMatrix MatrixSubtraction (PtMatrix pmat1, PtMatrix pmat2)
{
    PtMatrix sub;
    unsigned int i, j;

    /* Verifies if matrices have the same dimensions */
    if (!EqualSizeMatrices(pmat1, pmat2))
        return NULL;

    /* Call the constructor */
    if ((sub = MatrixCreate(pmat1->NL, pmat1->NC)) == NULL)
        return NULL;

    /* Subtract the elements */
    for (i = 0; i < sub->NL; i++)
        for (j = 0; j < sub->NC; j++)
            sub->Matrix[i][j] = pmat1->Matrix[i][j] - pmat2->Matrix[i][j];

    return sub;
}
Пример #8
0
PtMatrix MatrixAddition (PtMatrix pmat1, PtMatrix pmat2)
{
    PtMatrix add;
    unsigned int i, j;

    /* Verifies if matrices have the same dimensions */
    if (!EqualSizeMatrices(pmat1, pmat2))
        return NULL;

    /* Call the constructor */
    if ((add = MatrixCreate(pmat1->NL, pmat1->NC)) == NULL)
        return NULL;

    /* Sum the elements */
    for (i = 0; i < add->NL; i++)
        for (j = 0; j < add->NC; j++)
            add->Matrix[i][j] = pmat1->Matrix[i][j] + pmat2->Matrix[i][j];

    return add;
}
Пример #9
0
int main(int argc, char *argv[])
{
  Matrix image;
  int i,y,x;
  int width,height,channels;
  int **histo;
  double *p, r,g,b;

  if(argc != 4) {
    fprintf(stderr, "Usage:\n%s <width> <height> <channels> < image_file > output\n", argv[0]);
    fprintf(stderr, "To compute the histogram of an image.\n", argv[0]);
    fprintf(stderr, "Output is the concatenation of 256 bins for each channel.\n");
    exit(1);
  }

  width = atoi(argv[1]);
  height = atoi(argv[2]);
  channels = atoi(argv[3]);
  image = MatrixCreate(height, width*channels);
  MatrixReadImage(image, stdin);

  histo = Allocate(channels, int*);
  for(i=0;i<channels;i++) {
    histo[i] = Allocate(256, int);
    for(x=0;x<256;x++) histo[i][x] = 0;
  }
  p = image->data[0];
  for(y=0;y<height;y++) {
    for(x=0;x<width;x++) {
      for(i=0;i<channels;i++)
	histo[i][ (unsigned char)*p++ ]++;
    }
  }

  for(i=0;i<channels;i++) {
    for(x=0;x<256;x++) {
      printf("%d\n", histo[i][x]);
    }
  }
  exit(0);
}
Пример #10
0
PtMatrix MatrixSubMatrix (PtMatrix pmat, unsigned int pl, unsigned int pc)
{
    PtMatrix subMatrix;
    unsigned int i, j, l, c;

    /* Verifies if matrix exists */
    if (pmat == NULL) {
        Error = NO_MATRIX;
        return NULL;
    }

    /* Verifies if values of pl and pc are within NL anc NC */
    if (pl < 1 || pl > pmat->NL) {
        Error = BAD_ROW;
        return NULL;
    }

    if (pc < 1 || pc > pmat->NC) {
        Error = BAD_COLUMN;
        return NULL;
    }

    /* Calls the constructor of the submatrix */
    if ((subMatrix = MatrixCreate(pmat->NL - 1, pmat->NC - 1)) == NULL)
        return NULL;

    /* Copy the elements to submatrix */
    for (i = 0, l = 0; i < pmat->NL; i++) {
        if (i == pl - 1)
            continue;
        for (j = 0, c = 0; j < pmat->NC; j++) {
            if (j == pc - 1)
                continue;
            subMatrix->Matrix[l][c] = pmat->Matrix[i][j];
            c++;
        }
        l++;
    }

    return subMatrix;
}
Пример #11
0
PtMatrix MatrixTranspose (PtMatrix pmat)
{
    PtMatrix transposedMatrix;
    unsigned int i, j;

    /* Verifies if matrix exists */
    if (pmat == NULL) {
        Error = NO_MATRIX;
        return NULL;
    }

    /* Call matrix constructor */
    if ((transposedMatrix = MatrixCreate(pmat->NC, pmat->NL)) == NULL)
        return NULL;

    for (i = 0; i < pmat->NL; i++)
        for (j = 0; j < pmat->NC; j++)
            transposedMatrix->Matrix[j][i] = pmat->Matrix[i][j];

    return transposedMatrix;
}
Пример #12
0
PtMatrix MatrixCopy (PtMatrix pmat)
{
    PtMatrix matrixCopy;
    unsigned int i, j;

    /* Verifies if matrix exists */
    if (pmat == NULL) {
        Error = NO_MATRIX;
        return NULL;
    }

    /* Call matrix constructor */
    if ((matrixCopy = MatrixCreate(pmat->NL, pmat->NC)) == NULL)
        return NULL;

    /* Copy elements to new matrix */
    for (i = 0; i < pmat->NL; i++)
        for (j = 0; j < pmat->NC; j++)
            matrixCopy->Matrix[i][j] = pmat->Matrix[i][j];

    return matrixCopy;
}
PtMatrix MatrixCopy (PtMatrix pmat){
  PtMatrix Matrix;
  unsigned int l, i;

  /* verifica se a matrix existe */
  if (pmat == NULL) {
    Error = NO_MATRIX;
    return NULL;
  }

  /* criação do matrix copia nulo */
  if ((Matrix = MatrixCreate(pmat->NL, pmat->NC)) == NULL)
    return NULL;

  for(l=0; l<Matrix->NL; l++){
    for (i = 0; i < Matrix->NC; ++i){
      Matrix->Matrix[l][i] = pmat->Matrix[l][i];
    }
  }

  return Matrix;
}
PtMatrix MatrixSubtraction (PtMatrix pmat1, PtMatrix pmat2)
{
  PtMatrix Sub;
  int I, J;

  if(!EqualDimensionMatrixes(pmat1, pmat2)) {
    return NULL;
  }

  if((Sub = MatrixCreate(pmat1->NL, pmat1->NC)) == NULL) {
    return NULL;
  }

  for(I = 0; I < pmat1->NL; ++I) {
    for(J = 0; J < pmat1->NC; ++J) {
      Sub->Matrix[I][J] = pmat1->Matrix[I][J] - pmat2->Matrix[I][J];
    }
  }

  Error = OK;
  return Sub;
}
PtMatrix MatrixAddition (PtMatrix pmat1, PtMatrix pmat2)
{
  PtMatrix Add;
  int I, J;

  if(!EqualDimensionMatrixes(pmat1, pmat2)) {
    return NULL;
  }

  if((Add = MatrixCreate(pmat1->NL, pmat1->NC)) == NULL) {
    return NULL;
  }

  for(I = 0; I < pmat1->NL; ++I) {
    for(J = 0; J < pmat1->NC; ++J) {
      Add->Matrix[I][J] = pmat1->Matrix[I][J] + pmat2->Matrix[I][J];
    }
  }

  Error = OK;
  return Add;
}
Пример #16
0
PtMatrix MatrixMultByScalar (PtMatrix pmat, double pvalue)
{
    PtMatrix multScalar;
    unsigned int i, j;

    /* Verifies if matrix exists */
    if (pmat == NULL) {
        Error = NO_MATRIX;
        return NULL;
    }

    /* Call the constructor */
    if ((multScalar = MatrixCreate(pmat->NL, pmat->NC)) == NULL)
        return NULL;

    /* Do the operations over the elements */
    for (i = 0; i < multScalar->NL; i++)
        for (j = 0; j < multScalar->NC; j++)
            multScalar->Matrix[i][j] = pmat->Matrix[i][j] * pvalue;

    return multScalar;
}
PtMatrix MatrixSubtraction (PtMatrix pmat1, PtMatrix pmat2)
{
  if(!EqualDimensionMatrixes(pmat1,pmat2)){
    Error = BAD_SIZE;
    return NULL;
  }

  PtMatrix Result;
  unsigned int l, c;

  /* criação do matrix copia nulo */
  if ((Result = MatrixCreate(pmat1->NC, pmat1->NL)) == NULL)
    return NULL;

  for(l=0; l<Result->NL; l++){
    for(c=0; c<Result->NC; c++){
      Result->Matrix[l][c] = MatrixObserveElement(pmat1, l, c) - MatrixObserveElement(pmat1, c, l);
    }
  }

  Error = OK;
  return Result;
}
PtMatrix MatrixTranspose (PtMatrix pmat)
{
  PtMatrix Transpose;
  int I, J;

  if(pmat == NULL) {
    Error = NO_MATRIX;
    return NULL;
  }

  if((Transpose = MatrixCreate(pmat->NC, pmat->NL)) == NULL) {
    return NULL;
  }

  for(I = 0; I < pmat->NL; ++I) {
    for(J = 0; J < pmat->NC; ++J) {
      Transpose->Matrix[J][I] = pmat->Matrix[I][J];
    }
  }

  Error = OK;
  return Transpose;
}
PtMatrix MatrixCopy (PtMatrix pmat)
{
  PtMatrix Copy;
  int I, J;

  if(pmat == NULL) {
    Error = NO_MATRIX;
    return NULL;
  }

  if((Copy = MatrixCreate(pmat->NL, pmat->NC)) == NULL) {
    return NULL;
  }

  for(I = 0; I < pmat->NL; ++I) {
    for(J = 0; J < pmat->NC; ++J) {
      Copy->Matrix[I][J] = pmat->Matrix[I][J];
    }
  }

  Error = OK;
  return Copy;
}
PtMatrix MatrixMultiplication (PtMatrix pmat1, PtMatrix pmat2)
{
  PtMatrix Mul;
  int I, J, K;

  if(!ChainedMatrixes(pmat1, pmat2)) {
    return NULL;
  }

  if((Mul = MatrixCreate(pmat1->NL, pmat2->NC)) == NULL) {
    return NULL;
  }

  for(I = 0; I < pmat1->NL; ++I) {
    for(J = 0; J < pmat2->NC; ++J) {
      for(K = 0; K < pmat1->NC; ++K) {
        Mul->Matrix[I][J] += pmat1->Matrix[I][K] * pmat2->Matrix[K][J];
      }
    }
  }

  Error = OK;
  return Mul;
}
Пример #21
0
PtMatrix MatrixMultiplication (PtMatrix pmat1, PtMatrix pmat2)
{
    PtMatrix mult;
    unsigned int i, j, k;

    /* Verifies if matrices have the same dimensions */
    if (!ChainedMatrices(pmat1, pmat2))
        return NULL;

    /* Call the constructor */
    if ((mult = MatrixCreate(pmat1->NL, pmat2->NC)) == NULL)
        return NULL;

    /* Do the operations over the elements */
    for (i = 0; i < pmat1->NL; i++) {
        for (j = 0; j < pmat2->NC; j++) {
            mult->Matrix[i][j] = 0;
            for (k = 0; k < pmat1->NC; k++)
                mult->Matrix[i][j] += pmat1->Matrix[i][k] * pmat2->Matrix[k][j];
        }
    }

    return mult;
}
Пример #22
0
   /*-----------------------------------------------------------------
    * fetch machine and matrix parameters
    *-----------------------------------------------------------------*/

   comm = hypre_ParCSRMatrixComm(A);
   MPI_Comm_rank(comm,&mypid);  
   HYPRE_ParCSRMatrixGetRowPartitioning((HYPRE_ParCSRMatrix) A, &partition);
   start_row = partition[mypid];
   end_row   = partition[mypid+1] - 1;

   /*-----------------------------------------------------------------
    * construct a ParaSails matrix
    *-----------------------------------------------------------------*/

   mat = MatrixCreate(comm, start_row, end_row);
   for (row = start_row; row <= end_row; row++)
   {
      hypre_ParCSRMatrixGetRow(A, row, &row_length, &col_indices, &col_values);
      MatrixSetRow(mat, row, row_length, col_indices, col_values);
      hypre_ParCSRMatrixRestoreRow(A,row,&row_length,&col_indices,&col_values);
   }
   MatrixComplete(mat);

   /*-----------------------------------------------------------------
    * construct a ParaSails smoother object
    *-----------------------------------------------------------------*/

   smoother = hypre_CTAlloc( MLI_Smoother_ParaSails, 1 );
   if ( smoother == NULL ) { (*smoother_obj) = NULL; return 1; }
   ps = ParaSailsCreate(comm, start_row, end_row, parasails_factorized);
Пример #23
0
HYPRE_Int main(HYPRE_Int argc, char *argv[])
{
    HYPRE_Int mype, npes;
    HYPRE_Int symmetric;
    HYPRE_Int num_runs;
    Matrix *A;
    ParaSails *ps;
    FILE *file;
    HYPRE_Int n, beg_row, end_row;
    HYPRE_Real time0, time1;
    HYPRE_Real setup_time, solve_time;
    HYPRE_Real max_setup_time, max_solve_time;
    HYPRE_Real cost;

    HYPRE_Real *x, *b;
    HYPRE_Int i, niter;
    HYPRE_Real thresh;
    HYPRE_Real threshg;
    HYPRE_Int nlevels;
    HYPRE_Real filter;
    HYPRE_Real loadbal;

    hypre_MPI_Init(&argc, &argv);
    hypre_MPI_Comm_rank(hypre_MPI_COMM_WORLD, &mype);
    hypre_MPI_Comm_size(hypre_MPI_COMM_WORLD, &npes);

    /* Read number of rows in matrix */
    symmetric = atoi(argv[1]);
    num_runs  = atoi(argv[2]);

    file = fopen(argv[3], "r");
    assert(file != NULL);
#ifdef EMSOLVE
    hypre_fscanf(file, "%*d %d\n", &n);
#else
    hypre_fscanf(file, "%d\n", &n);
#endif
    fclose(file);
    assert(n >= npes);

    beg_row = (HYPRE_Int) ((HYPRE_Real)(mype*n) / npes) + 1; /* assumes 1-based */
    end_row = (HYPRE_Int) ((HYPRE_Real)((mype+1)* n) / npes);

    if (mype == 0)
        assert(beg_row == 1);
    if (mype == npes-1)
        assert(end_row == n);

#ifdef EMSOLVE
    beg_row--;
    end_row--;
#endif

    x = (HYPRE_Real *) malloc((end_row-beg_row+1) * sizeof(HYPRE_Real));
    b = (HYPRE_Real *) malloc((end_row-beg_row+1) * sizeof(HYPRE_Real));

    A = MatrixCreate(hypre_MPI_COMM_WORLD, beg_row, end_row);

    MatrixRead(A, argv[3]);
    if (mype == 0) 
        hypre_printf("%s\n", argv[3]);

    /* MatrixPrint(A, "A"); */

    /* Right-hand side */
    if (argc > 4)
    {
        RhsRead(b, A, argv[4]);
        if (mype == 0) 
            hypre_printf("Using rhs from %s\n", argv[4]);
    }
    else
    {
        for (i=0; i<end_row-beg_row+1; i++)
            b[i] = (HYPRE_Real) (2*rand()) / (HYPRE_Real) RAND_MAX - 1.0;
    }

    while (num_runs && num_runs >= -1)
    {
        /* Initial guess */
        for (i=0; i<end_row-beg_row+1; i++)
            x[i] = 0.0;

	if (num_runs == -1)
	{
            thresh = 0.0;
	    nlevels = 0;
	    filter = 0.0;
            loadbal = 0.0;
	}
	else
	{
            if (mype == 0)
            {
#if PARASAILS_EXT_PATTERN
                hypre_printf("Enter parameters threshg, thresh, nlevels, "
	            "filter, beta:\n");
	        fflush(stdout);
                hypre_scanf("%lf %lf %d %lf %lf", &threshg, &thresh, &nlevels, 
		    &filter, &loadbal);
#else
                hypre_printf("Enter parameters thresh, nlevels, "
	            "filter, beta:\n");
	        fflush(stdout);
                hypre_scanf("%lf %d %lf %lf", &thresh, &nlevels, 
		    &filter, &loadbal);
#endif
	    }

	    hypre_MPI_Bcast(&threshg, 1, hypre_MPI_DOUBLE, 0, hypre_MPI_COMM_WORLD);
	    hypre_MPI_Bcast(&thresh,  1, hypre_MPI_DOUBLE, 0, hypre_MPI_COMM_WORLD);
	    hypre_MPI_Bcast(&nlevels, 1, HYPRE_MPI_INT,    0, hypre_MPI_COMM_WORLD);
	    hypre_MPI_Bcast(&filter,  1, hypre_MPI_DOUBLE, 0, hypre_MPI_COMM_WORLD);
	    hypre_MPI_Bcast(&loadbal, 1, hypre_MPI_DOUBLE, 0, hypre_MPI_COMM_WORLD);

            if (nlevels < 0)
                break;
	}

        /**************
	 * Setup phase   
	 **************/

        hypre_MPI_Barrier(hypre_MPI_COMM_WORLD);
        time0 = hypre_MPI_Wtime();

        ps = ParaSailsCreate(hypre_MPI_COMM_WORLD, beg_row, end_row, symmetric);

        ps->loadbal_beta = loadbal;

#if PARASAILS_EXT_PATTERN
        ParaSailsSetupPatternExt(ps, A, threshg, thresh, nlevels);
#else
        ParaSailsSetupPattern(ps, A, thresh, nlevels);
#endif

        time1 = hypre_MPI_Wtime();
	setup_time = time1-time0;

        cost = ParaSailsStatsPattern(ps, A);
	if (cost > 5.e11)
	{
            hypre_printf("Aborting setup and solve due to high cost.\n");
	    goto cleanup;
	}

        hypre_MPI_Barrier(hypre_MPI_COMM_WORLD);
        time0 = hypre_MPI_Wtime();

        err = ParaSailsSetupValues(ps, A, filter);
        if (err != 0)
	{
            hypre_printf("ParaSailsSetupValues returned error.\n");
	    goto cleanup;
	}

        time1 = hypre_MPI_Wtime();
	setup_time += (time1-time0);

        ParaSailsStatsValues(ps, A);

	if (!strncmp(argv[3], "testpsmat", 8))
            MatrixPrint(ps->M, "M");

#if 0
        if (mype == 0) 
            hypre_printf("SETTING UP VALUES AGAIN WITH FILTERED PATTERN\n");
        ps->loadbal_beta = 0;
        ParaSailsSetupValues(ps, A, 0.0);
#endif

        /*****************
	 * Solution phase
	 *****************/

	niter = 3000;
        if (MatrixNnz(ps->M) == n) /* if diagonal preconditioner */
	    niter = 5000;

        hypre_MPI_Barrier(hypre_MPI_COMM_WORLD);
        time0 = hypre_MPI_Wtime();

        if (symmetric == 1)
            PCG_ParaSails(A, ps, b, x, 1.e-8, niter);
	else
            FGMRES_ParaSails(A, ps, b, x, 50, 1.e-8, niter);

        time1 = hypre_MPI_Wtime();
	solve_time = time1-time0;

        hypre_MPI_Reduce(&setup_time, &max_setup_time, 1, hypre_MPI_DOUBLE, hypre_MPI_MAX, 0, 
	    hypre_MPI_COMM_WORLD);
        hypre_MPI_Reduce(&solve_time, &max_solve_time, 1, hypre_MPI_DOUBLE, hypre_MPI_MAX, 0, 
	    hypre_MPI_COMM_WORLD);

	if (mype == 0)
	{
            hypre_printf("**********************************************\n");
            hypre_printf("***    Setup    Solve    Total\n");
            hypre_printf("III %8.1f %8.1f %8.1f\n", max_setup_time, max_solve_time, 
		max_setup_time+max_solve_time);
            hypre_printf("**********************************************\n");
	}

cleanup:
        ParaSailsDestroy(ps);

        num_runs--;
    }

    free(x);
    free(b);

    MatrixDestroy(A);
    hypre_MPI_Finalize();

    return 0;
}