Esempio n. 1
0
int mm_is_valid ( MM_typecode matcode )
/******************************************************************************/
/*
  Purpose:
    MM_IS_VALID checks whether the MM header information is valid.
  Modified:
    31 October 2008
  Parameters:
    Input, MM_typecode MATCODE, the header information.
    Output, int MM_IS_VALID, is TRUE if the matrix code is valid.
*/
{
  if ( !mm_is_matrix ( matcode ) ) 
  {
    return 0;
  }
  if ( mm_is_dense ( matcode ) && mm_is_pattern ( matcode ) ) 
  {
    return 0;
  }
  if ( mm_is_real ( matcode ) && mm_is_hermitian ( matcode ) ) 
  {
    return 0;
  }
  if ( mm_is_pattern ( matcode ) && 
      ( mm_is_hermitian ( matcode ) || mm_is_skew ( matcode ) ) ) 
  {
    return 0;
  }
  return 1;
}
Esempio n. 2
0
int mm_is_valid(MM_typecode matcode)
{
    if (!mm_is_matrix(matcode)) return 0;
    if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0;
    if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0;
    if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) || 
                mm_is_skew(matcode))) return 0;
    return 1;
}
Esempio n. 3
0
char  *mm_typecode_to_str(MM_typecode matcode)
{
    char buffer[MM_MAX_LINE_LENGTH];
    char *types[4];
    int error =0;
    int i;

    /* check for MTX type */
    if (mm_is_matrix(matcode))
        types[0] = MM_MTX_STR;
    else
        error=1;

    /* check for CRD or ARR matrix */
    if (mm_is_sparserow(matcode))
        types[1] = MM_SPARSEROW_STR;
    else
    if (mm_is_coordinate(matcode))
        types[1] = MM_COORDINATE_STR;
    else
    if (mm_is_dense(matcode))
        types[1] = MM_DENSE_STR;
    else
        return NULL;

    /* check for element data type */
    if (mm_is_real(matcode))
        types[2] = MM_REAL_STR;
    else
    if (mm_is_complex(matcode))
        types[2] = MM_COMPLEX_STR;
    else
    if (mm_is_pattern(matcode))
        types[2] = MM_PATTERN_STR;
    else
    if (mm_is_integer(matcode))
        types[2] = MM_INT_STR;
    else
        return NULL;


    /* check for symmetry type */
    if (mm_is_general(matcode))
        types[3] = MM_GENERAL_STR;
    else
    if (mm_is_symmetric(matcode))
        types[3] = MM_SYMM_STR;
    else
    if (mm_is_hermitian(matcode))
        types[3] = MM_HERM_STR;
    else
    if (mm_is_skew(matcode))
        types[3] = MM_SKEW_STR;
    else
        return NULL;

    sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
    return strdup(buffer);

}
Esempio n. 4
0
 void mm_typecode_to_str(MM_typecode matcode, char * buffer)
{
    char type0[20];
    char type1[20];
    char type2[20];
    char type3[20];
    int error =0;

    /* check for MTX type */
    if (mm_is_matrix(matcode))
        strcpy(type0, MM_MTX_STR);
    else
        error=1;

    /* check for CRD or ARR matrix */
    if (mm_is_sparse(matcode))
        strcpy(type1, MM_SPARSE_STR);
    else
    if (mm_is_dense(matcode))
        strcpy(type1, MM_DENSE_STR);
    else
        return;

    /* check for element data type */
    if (mm_is_real(matcode))
        strcpy(type2, MM_REAL_STR);
    else
    if (mm_is_complex(matcode))
        strcpy(type2, MM_COMPLEX_STR);
    else
    if (mm_is_pattern(matcode))
        strcpy(type2, MM_PATTERN_STR);
    else
    if (mm_is_integer(matcode))
        strcpy(type2, MM_INT_STR);
    else
        return;

    /* check for symmetry type */
    if (mm_is_general(matcode))
        strcpy(type3, MM_GENERAL_STR);
    else
    if (mm_is_symmetric(matcode))
        strcpy(type3, MM_SYMM_STR);
    else
    if (mm_is_hermitian(matcode))
        strcpy(type3, MM_HERM_STR);
    else
    if (mm_is_skew(matcode))
        strcpy(type3, MM_SKEW_STR);
    else
        return;

    sprintf(buffer,"%s %s %s %s", type0, type1, type2, type3);
    return;
}
Esempio n. 5
0
/* mm_real supports real symmetric/general sparse/dense matrix */
static bool
is_type_supported (const MM_typecode typecode)
{
	// invalid type
	if (!mm_is_valid (typecode)) return false;

	// pattern is not supported
	if (mm_is_pattern (typecode)) return false;

	// integer and complex matrix are not supported
	if (mm_is_integer (typecode) || mm_is_complex (typecode)) return false;

	// skew and hermitian are not supported
	if (mm_is_skew (typecode) || mm_is_hermitian (typecode)) return false;

	return true;
}
Esempio n. 6
0
bool loadMmProperties(int *rowsCount,
	int *columnsCount,
	int *nonZerosCount,
	bool *isStoredSparse,
	int* matrixStorage,
	int* matrixType,
	FILE *file)
{
	MM_typecode matcode;

	// supports only valid matrices
	if ((mm_read_banner(file, &matcode) != 0) 
		|| (!mm_is_matrix(matcode))
		|| (!mm_is_valid(matcode))) 
		return false;

	if ( mm_read_mtx_crd_size(file, rowsCount, columnsCount, nonZerosCount) != 0 ) 
		return false;

	// is it stored sparse?
	if (mm_is_sparse(matcode))
		*isStoredSparse = true;
	else
		*isStoredSparse = false;

	if (mm_is_integer(matcode))
		*matrixStorage = MATRIX_STORAGE_INTEGER;
	else if (mm_is_real(matcode))
		*matrixStorage = MATRIX_STORAGE_REAL;
	else if (mm_is_complex(matcode))
		*matrixStorage = MATRIX_STORAGE_COMPLEX;
	else if (mm_is_pattern(matcode))
		*matrixStorage = MATRIX_STORAGE_PATTERN;
	
	if (mm_is_general(matcode))
		*matrixType = MATRIX_TYPE_GENERAL;
	else if (mm_is_symmetric(matcode))
		*matrixType = MATRIX_TYPE_SYMMETRIC;
	else if (mm_is_skew(matcode))
		*matrixType = MATRIX_TYPE_SKEW;
	else if (mm_is_hermitian(matcode))
		*matrixType = MATRIX_TYPE_HERMITIAN;

	return true;
}
Esempio n. 7
0
/*
 *  Function: MatrixMarketRead
 *
 *  Reads a matrix in matrix market format
 *
 *  For more information about matrix market format see mmio.c/mmio.h
 *
 * Parameters:
 *   dirname - Path to the directory containing matrix
 *   Ncol    - Number of columns
 *   Nrow    - Number of rows
 *   Nnzero  - Number of non zeros
 *   col     - Index of first element of each column in *row* and *val*
 *   row     - Row of eah element
 *   val     - Value of each element
 *   Type    - Type of the matrix
 *   RhsType - Type of the right-hand-side.
 *
 */
void MatrixMarketRead(char const      *filename,
                      pastix_int_t    *Ncol,
                      pastix_int_t    *Nrow,
                      pastix_int_t    *Nnzero,
                      pastix_int_t   **col,
                      pastix_int_t   **row,
                      pastix_float_t **val,
                      char           **Type,
                      char           **RhsType)
{

  FILE * file;
  pastix_int_t * tempcol;
  pastix_int_t iter,baseval;
  pastix_int_t * temprow;
  pastix_float_t * tempval;
  pastix_int_t total;
  pastix_int_t tmp;
  pastix_int_t pos;
  pastix_int_t limit;
  MM_typecode matcode;
  int tmpncol,tmpnrow,tmpnnzero;

  *Type = (char *) malloc(4*sizeof(char));
  *RhsType = (char *) malloc(1*sizeof(char));
  (*RhsType)[0] = '\0';

  file = fopen (filename,"r");
  if (file==NULL)
  {
    fprintf(stderr,"cannot load %s\n", filename);
    EXIT(MOD_SI,FILE_ERR);
  }

  if (mm_read_banner(file, &matcode) != 0)
  {
    fprintf(stderr,"Could not process Matrix Market banner.\n");
    exit(1);
  }

#ifdef    TYPE_COMPLEX
  (*Type)[0] = 'C';
  if (!mm_is_complex(matcode))
  {
    fprintf(stderr, "\nWARNING : Matrix should be complex. Imaginary part will be 0.\n\n");
  }
#else  /* TYPE_COMPLEX */
  (*Type)[0] = 'R';
  if (mm_is_complex(matcode))
  {
    fprintf(stderr, "\nWARNING : Matrix should not be complex. Only real part will be taken.\n\n");
  }
#endif /* TYPE_COMPLEX */

  (*Type)[1] = 'U';
  if (mm_is_symmetric(matcode))
  {
    (*Type)[1] = 'S';
  }
  else {
    if (mm_is_hermitian(matcode))
    {
      (*Type)[1] = 'H';
    }
  }
  (*Type)[2] = 'A';
  (*Type)[3] = '\0';
  /* find out size of sparse matrix .... */

  if (mm_read_mtx_crd_size(file, &tmpnrow, &tmpncol, &tmpnnzero) !=0)
    exit(1);

  *Ncol = tmpncol;
  *Nrow = tmpnrow;
  *Nnzero = tmpnnzero;

  /* Allocation memoire */
  tempcol = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  temprow = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  tempval = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t));

  if ((tempcol==NULL) || (temprow == NULL) || (tempval == NULL))
  {
    fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",(long)*Nnzero);
    EXIT(MOD_SI,OUTOFMEMORY_ERR);
  }

  /* Remplissage */
  {
    long temp1,temp2;
    double re,im;
    im = 0.0;

    if (mm_is_complex(matcode))
    {
      for (iter=0; iter<(*Nnzero); iter++)
      {
        if (4 != fscanf(file,"%ld %ld %lg %lg\n", &temp1, &temp2, &re, &im))
        {
          fprintf(stderr, "ERROR: reading matrix (line %ld)\n",
                  (long int)iter);
          exit(1);
        }

        temprow[iter]=(pastix_int_t)temp1;
        tempcol[iter]=(pastix_int_t)temp2;
#ifdef    TYPE_COMPLEX
        tempval[iter]=(pastix_float_t)(re+im*I);
#else  /* TYPE_COMPLEX */
        tempval[iter]=(pastix_float_t)(re);
#endif /* TYPE_COMPLEX */
      }
    }
    else
    {
      for (iter=0; iter<(*Nnzero); iter++)
      {
        if (3 != fscanf(file,"%ld %ld %lg\n", &temp1, &temp2, &re))
        {
          fprintf(stderr, "ERROR: reading matrix (line %ld)\n",
                  (long int)iter);
          exit(1);
        }
        temprow[iter]=(pastix_int_t)temp1;
        tempcol[iter]=(pastix_int_t)temp2;
#ifdef    TYPE_COMPLEX
        tempval[iter]=(pastix_float_t)(re+im*I);
#else  /* TYPE_COMPLEX */
        tempval[iter]=(pastix_float_t)(re);
#endif /* TYPE_COMPLEX */
      }
    }
  }

  (*col) = (pastix_int_t *) malloc((*Nrow+1)*sizeof(pastix_int_t));
  memset(*col,0,(*Nrow+1)*sizeof(pastix_int_t));
  (*row) = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  memset(*row,0,(*Nnzero)*sizeof(pastix_int_t));
  (*val) = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t));
  if (((*col)==NULL) || ((*row) == NULL) || ((*val) == NULL))
  {
    fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",(long)*Nnzero);
    EXIT(MOD_SI,OUTOFMEMORY_ERR);
  }

  /* Detection de la base */
  baseval = 1;
  for(iter=0; iter<(*Nnzero); iter++)
    baseval = MIN(baseval, tempcol[iter]);
  if (baseval == 0)
  {
    for(iter=0; iter<(*Nnzero); iter++)
    {
      tempcol[iter]++;
      temprow[iter]++;
    }
  }

  for (iter = 0; iter < (*Nnzero); iter ++)
  {
    (*col)[tempcol[iter]-1]++;
  }

  baseval=1; /* Attention on base a 1 */
  total = baseval;

  for (iter = 0; iter < (*Ncol)+1; iter ++)
  {
    tmp = (*col)[iter];
    (*col)[iter]=total;
    total+=tmp;
  }

  for (iter = 0; iter < (*Nnzero); iter ++)
  {

    pos = (*col)[tempcol[iter]-1]-1;
    limit = (*col)[tempcol[iter]]-1;
    while((*row)[pos] != 0 && pos < limit)
    {
      pos++;
    }
    if (pos == limit)
      fprintf(stderr, "Erreur de lecture\n");

    (*row)[pos] = temprow[iter];
    (*val)[pos] = tempval[iter];
  }

  memFree_null(tempval);
  memFree_null(temprow);
  memFree_null(tempcol);
}
Esempio n. 8
0
/*
 *  Function: DistributedMatrixMarketRead
 *
 *  Reads a matrix in distributed matrix market format
 *
 *  For more information about matrix market format see mmio.c/mmio.h
 *
 * Parameters:
 *   dirname - Path to the directory containing matrix
 *   Ncol    - Number of columns
 *   Nrow    - Number of rows
 *   Nnzero  - Number of non zeros
 *   col     - Index of first element of each column in *row* and *val*
 *   row     - Row of eah element
 *   val     - Value of each element
 *   Type    - Type of the matrix
 *   RhsType - Type of the right-hand-side.
 *
 */
void DistributedMatrixMarketRead(char const      *filename,
                                 pastix_int_t    *Ncol,
                                 pastix_int_t    *Nrow,
                                 pastix_int_t    *Nnzero,
                                 pastix_int_t   **col,
                                 pastix_int_t   **row,
                                 pastix_float_t **val,
                                 pastix_int_t   **l2g,
                                 char           **Type,
                                 char           **RhsType)
{

  FILE * file;
  pastix_int_t * tempcol, *g2l, *templ2g;
  pastix_int_t iter, iter2, baseval, mincol, maxcol;
  pastix_int_t * temprow;
  pastix_float_t * tempval;
  pastix_int_t total;
  pastix_int_t tmp;
  pastix_int_t pos;
  pastix_int_t limit;
  MM_typecode matcode;
  int tmpncol,tmpnrow,tmpnnzero;
  int rank, size;
  int tmpint;
  pastix_int_t i, global_n_col;
  char line[BUFSIZ], my_filename_s[BUFSIZ];
  char * my_filename;
  pastix_int_t column;

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

  file = fopen (filename,"r");
  if (file==NULL)
  {
    fprintf(stderr,"cannot load %s\n", filename);
    EXIT(MOD_SI,FILE_ERR);
  }

  FGETS(line, BUFSIZ, file);
  sscanf(line, "%d", &tmpint); /* Read number of filename */
  fprintf(stdout, "%d files\n", tmpint);

  if (size != tmpint)
    {
      /* pour l'instant rien. au choix : recreer un nouveau comm mpi, refusionner la csc et la redecouper */
      if (rank == 0)
        fprintf(stderr, "Please rerun with %d processors\n", tmpint);
      exit(EXIT_FAILURE);
    }

  for (i = 0; i < rank+1; i++)
    {
      FGETS(line, BUFSIZ, file);
      sscanf(line, "%s", my_filename_s);
    }
  my_filename = (char*)malloc(sizeof(char)*(strlen(filename)+BUFSIZ));
  strcpy(my_filename, filename);
  sprintf(my_filename,"%s/%s", dirname(my_filename), my_filename_s);
  fclose(file);

  *Type = (char *) malloc(4*sizeof(char));
  *RhsType = (char *) malloc(1*sizeof(char));
  (*RhsType)[0] = '\0';

  file = fopen (my_filename,"r");
  if (file==NULL)
  {
    fprintf(stderr,"cannot load %s\n", my_filename);
    EXIT(MOD_SI,FILE_ERR);
  }

  if (mm_read_banner(file, &matcode) != 0)
  {
    fprintf(stderr,"Could not process Matrix Market banner.\n");
    exit(1);
  }

#ifdef    TYPE_COMPLEX
  (*Type)[0] = 'C';
  if (!mm_is_complex(matcode))
  {
    fprintf(stderr, "\nWARNING : Matrix should be complex. Imaginary part will be 0.\n\n");
  }
#else  /* TYPE_COMPLEX */
  (*Type)[0] = 'R';
  if (mm_is_complex(matcode))
  {
    fprintf(stderr, "\nWARNING : Matrix should not be complex. Only real part will be taken.\n\n");
  }
#endif /* TYPE_COMPLEX */

  (*Type)[1] = 'U';
  if (mm_is_symmetric(matcode))
  {
    (*Type)[1] = 'S';
  }
  else {
    if (mm_is_hermitian(matcode))
    {
      (*Type)[1] = 'H';
    }
  }
  (*Type)[2] = 'A';
  (*Type)[3] = '\0';
  /* find out size of sparse matrix .... */

  if (mm_read_mtx_crd_size(file, &tmpnrow, &tmpncol, &tmpnnzero) !=0)
    exit(1);

  *Ncol = 0;
  *Nrow = 0;
  *Nnzero = tmpnnzero;
  
  /* Allocation memoire */
  tempcol = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  templ2g = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  temprow = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  tempval = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t));

  if ((tempcol==NULL) || (temprow == NULL) || (tempval == NULL))
  {
    fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",(long)*Nnzero);
    EXIT(MOD_SI,OUTOFMEMORY_ERR);
  }

  /* Remplissage */
  {
    long temp1,temp2;
    double re,im;
    im = 0.0;

    if (mm_is_complex(matcode))
    {
      for (iter=0; iter<(*Nnzero); iter++)
      {
        if (4 != fscanf(file,"%ld %ld %lg %lg\n", &temp1, &temp2, &re, &im))
        {
          fprintf(stderr, "ERROR: reading matrix (line %ld)\n",
                  (long int)iter);
          exit(1);
        }

        iter2 = 0;
        column = temp2;
        while ( iter2 < *Ncol &&
                templ2g[iter2] < column)
          iter2++;
        if ( !(iter2 < *Ncol && (templ2g)[iter2] == column) )
          {
            while ( iter2 < *Ncol )
              {
                tmp = column;
                column = (templ2g)[iter2];
                (templ2g)[iter2] = tmp;
                iter2++;
              }
            (templ2g)[iter2] = column;
            (*Ncol)++;
          }

        temprow[iter]=(pastix_int_t)temp1;
        tempcol[iter]=(pastix_int_t)temp2;
#ifdef    TYPE_COMPLEX
        tempval[iter]=(pastix_float_t)(re+im*I);
#else  /* TYPE_COMPLEX */
        tempval[iter]=(pastix_float_t)(re);
#endif /* TYPE_COMPLEX */
      }
    }
    else
    {
      for (iter=0; iter<(*Nnzero); iter++)
      {
        if (3 != fscanf(file,"%ld %ld %lg\n", &temp1, &temp2, &re))
        {
          fprintf(stderr, "ERROR: reading matrix (line %ld)\n",
                  (long int)iter);
          exit(1);
        }

        iter2 = 0;
        column = temp2;
        while ( iter2 < *Ncol &&
                (templ2g)[iter2] < column)
          iter2++;
        if ( iter2 == *Ncol || (templ2g)[iter2] != column )
          {
            while ( iter2 < *Ncol )
              {
                tmp = (templ2g)[iter2];
                (templ2g)[iter2] = column;
                column = tmp;
                iter2++;
              }
            (templ2g)[iter2] = column;
            (*Ncol)++;
          }

        temprow[iter]=(pastix_int_t)temp1;
        tempcol[iter]=(pastix_int_t)temp2;
#ifdef    TYPE_COMPLEX
        tempval[iter]=(pastix_float_t)(re+im*I);
#else  /* TYPE_COMPLEX */
        tempval[iter]=(pastix_float_t)(re);
#endif /* TYPE_COMPLEX */
      }
    }
  }

  *Nrow = *Ncol;
  (*l2g) = (pastix_int_t *) malloc((*Ncol)*sizeof(pastix_int_t));
  memcpy(*l2g, templ2g, *Ncol*sizeof(pastix_int_t));
  free(templ2g);
  (*col) = (pastix_int_t *) malloc((*Ncol+1)*sizeof(pastix_int_t));
  memset(*col,0,(*Ncol+1)*sizeof(pastix_int_t));
  (*row) = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t));
  memset(*row,0,(*Nnzero)*sizeof(pastix_int_t));
  (*val) = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t));

  if (((*col)==NULL) || ((*row) == NULL) || ((*val) == NULL))
    {
      fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",
              (long)*Nnzero);
      EXIT(MOD_SI,OUTOFMEMORY_ERR);
    }

  /* Detection de la base */
  mincol = (*l2g)[0];
  maxcol = (*l2g)[*Ncol-1];
  if (sizeof(int) == sizeof(pastix_int_t))
    {
      MPI_Allreduce(&mincol, &baseval, 1,      MPI_INT, MPI_MIN, MPI_COMM_WORLD);
      MPI_Allreduce(&maxcol, &global_n_col, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
    }
  else
    {
      MPI_Allreduce(&mincol, &baseval, 1,      MPI_LONG, MPI_MIN, MPI_COMM_WORLD);
      MPI_Allreduce(&maxcol, &global_n_col, 1, MPI_LONG, MPI_MAX, MPI_COMM_WORLD);
    }
  *Nrow = global_n_col;
  if (baseval == 0)
    {
      for(iter=0; iter<(*Nnzero); iter++)
        {
          tempcol[iter]++;
          temprow[iter]++;
        }
      for (iter = 0; iter < *Ncol; iter++)
        {
          (*l2g)[iter]++;
        }
    }

  if (baseval > 1 || baseval < 0)
    {
      fprintf(stderr, "Baseval > 1 || baseval < 0\n");
      exit(1);
    }
  baseval = 1;
  {
    /* Build loc2gloab */
    int inserted_column = 0;
    int iter2;
    int column;
    for (iter = 0; iter < (*Nnzero); iter ++)
      {
        iter2 = 0;
        column = tempcol[iter];
        while ( iter2 < inserted_column &&
                (*l2g)[iter2] < column)
          iter2++;
        if (iter2 < inserted_column && (*l2g)[iter2] == column)
          continue;

        while ( iter2 < inserted_column )
          {
            tmp = column;
            column = (*l2g)[iter2];
            (*l2g)[iter2] = tmp;
            iter2++;
          }
        (*l2g)[iter2] = column;
        inserted_column++;
        if (inserted_column == *Ncol)
          break;
      }
    assert(inserted_column == *Ncol);
  }

  {
    /* Build loc2glob */
    g2l = malloc(global_n_col*sizeof(pastix_int_t));
    for (iter = 0; iter < global_n_col; iter++)
      g2l[iter] = -1;
    for (iter = 0; iter < (*Ncol); iter ++)
      g2l[(*l2g)[iter]-1] = iter+1;
  }

  for (iter = 0; iter < (*Nnzero); iter ++)
    {
      (*col)[g2l[tempcol[iter]-1]-1]++;
    }

  total = baseval;
  for (iter = 0; iter < (*Ncol)+1; iter ++)
    {
      tmp = (*col)[iter];
      (*col)[iter]=total;
      total+=tmp;
    }

  for (iter = 0; iter < (*Nnzero); iter ++)
    {

      pos = (*col)[g2l[tempcol[iter]-1]-1]-1;
      limit = (*col)[g2l[tempcol[iter]-1]]-1;
      while((*row)[pos] != 0 && pos < limit)
        {
          pos++;
        }
      if (pos == limit)
        fprintf(stderr, "Erreur de lecture %ld %ld %ld\n",
                (long int)(*col)[g2l[tempcol[iter]-1]-1]-1,
                (long int)pos, (long int)limit);

      (*row)[pos] = temprow[iter];
      (*val)[pos] = tempval[iter];
    }

  memFree_null(tempval);
  memFree_null(temprow);
  memFree_null(tempcol);

  free(my_filename);
}
Esempio n. 9
0
char  *mm_typecode_to_str(MM_typecode matcode)
{
    char buffer[MM_MAX_LINE_LENGTH];
    const char *types[4];
	char *mm_strdup(const char *);
    int error =0;

    /* check for MTX type */
    if (mm_is_matrix(matcode)) 
        types[0] = MM_MTX_STR;
    else {
        types[0] = NULL;
        error=1;
    }

    /* check for CRD or ARR matrix */
    if (mm_is_sparse(matcode))
        types[1] = MM_SPARSE_STR;
    else
    if (mm_is_dense(matcode))
        types[1] = MM_DENSE_STR;
    else
        return NULL;

    /* check for element data type */
    if (mm_is_real(matcode))
        types[2] = MM_REAL_STR;
    else
    if (mm_is_complex(matcode))
        types[2] = MM_COMPLEX_STR;
    else
    if (mm_is_pattern(matcode))
        types[2] = MM_PATTERN_STR;
    else
    if (mm_is_integer(matcode))
        types[2] = MM_INT_STR;
    else
        return NULL;


    /* check for symmetry type */
    if (mm_is_general(matcode))
        types[3] = MM_GENERAL_STR;
    else
    if (mm_is_symmetric(matcode))
        types[3] = MM_SYMM_STR;
    else 
    if (mm_is_hermitian(matcode))
        types[3] = MM_HERM_STR;
    else 
    if (mm_is_skew(matcode))
        types[3] = MM_SKEW_STR;
    else
        return NULL;

    if( error == 1 )
        sprintf(buffer,"Object to write is not a matrix; this is unsupported by the current mmio code.");
    else
        sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
    return mm_strdup(buffer);

}
Esempio n. 10
0
char *mm_typecode_to_str ( MM_typecode matcode )
/******************************************************************************/
/*
  Purpose:
    MM_TYPECODE_TO_STR converts the internal typecode to an MM header string.
  Modified:
    31 October 2008
*/
{
    char buffer[MM_MAX_LINE_LENGTH];
    char *types[4];
	char *mm_strdup(const char *);
	//int error =0;
/* 
  check for MTX type 
*/
    if (mm_is_matrix(matcode)) 
      types[0] = MM_MTX_STR;
    //    else
    //    error=1;
/* 
  check for CRD or ARR matrix 
*/
    if (mm_is_sparse(matcode))
        types[1] = MM_SPARSE_STR;
    else
    if (mm_is_dense(matcode))
        types[1] = MM_DENSE_STR;
    else
        return NULL;
/* 
  check for element data type 
*/
    if (mm_is_real(matcode))
        types[2] = MM_REAL_STR;
    else
    if (mm_is_complex(matcode))
        types[2] = MM_COMPLEX_STR;
    else
    if (mm_is_pattern(matcode))
        types[2] = MM_PATTERN_STR;
    else
    if (mm_is_integer(matcode))
        types[2] = MM_INT_STR;
    else
        return NULL;
/* 
  check for symmetry type 
*/
    if (mm_is_general(matcode))
        types[3] = MM_GENERAL_STR;
    else
    if (mm_is_symmetric(matcode))
        types[3] = MM_SYMM_STR;
    else 
    if (mm_is_hermitian(matcode))
        types[3] = MM_HERM_STR;
    else 
    if (mm_is_skew(matcode))
        types[3] = MM_SKEW_STR;
    else
        return NULL;
    sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]);
    return mm_strdup(buffer);
}
Esempio n. 11
0
int main(int argc, char ** argv)
{
    // report precision of floating-point
    printf("---------------------------------------------------------------------------------------------\n");
    char  *precision;
    if (sizeof(VALUE_TYPE) == 4)
    {
        precision = (char *)"32-bit Single Precision";
    }
    else if (sizeof(VALUE_TYPE) == 8)
    {
        precision = (char *)"64-bit Double Precision";
    }
    else
    {
        printf("Wrong precision. Program exit!\n");
        return 0;
    }

    printf("PRECISION = %s\n", precision);
    printf("Benchmark REPEAT = %i\n", BENCH_REPEAT);
    printf("---------------------------------------------------------------------------------------------\n");

    int m, n, nnzA;
    int *csrRowPtrA;
    int *csrColIdxA;
    VALUE_TYPE *csrValA;

    //ex: ./spmv webbase-1M.mtx
    int argi = 1;

    char  *filename;
    if(argc > argi)
    {
        filename = argv[argi];
        argi++;
    }
    printf("-------------- %s --------------\n", filename);

    // read matrix from mtx file
    int ret_code;
    MM_typecode matcode;
    FILE *f;

    int nnzA_mtx_report;
    int isInteger = 0, isReal = 0, isPattern = 0, isSymmetric = 0;

    // load matrix
    if ((f = fopen(filename, "r")) == NULL)
        return -1;

    if (mm_read_banner(f, &matcode) != 0)
    {
        printf("Could not process Matrix Market banner.\n");
        return -2;
    }

    if ( mm_is_complex( matcode ) )
    {
        printf("Sorry, data type 'COMPLEX' is not supported.\n");
        return -3;
    }

    if ( mm_is_pattern( matcode ) )  { isPattern = 1; /*printf("type = Pattern\n");*/ }
    if ( mm_is_real ( matcode) )     { isReal = 1; /*printf("type = real\n");*/ }
    if ( mm_is_integer ( matcode ) ) { isInteger = 1; /*printf("type = integer\n");*/ }

    /* find out size of sparse matrix .... */
    ret_code = mm_read_mtx_crd_size(f, &m, &n, &nnzA_mtx_report);
    if (ret_code != 0)
        return -4;

    if ( mm_is_symmetric( matcode ) || mm_is_hermitian( matcode ) )
    {
        isSymmetric = 1;
        printf("input matrix is symmetric = true\n");
    }
    else
    {
        printf("input matrix is symmetric = false\n");
    }

    int *csrRowPtrA_counter = (int *)malloc((m+1) * sizeof(int));
    memset(csrRowPtrA_counter, 0, (m+1) * sizeof(int));

    int *csrRowIdxA_tmp = (int *)malloc(nnzA_mtx_report * sizeof(int));
    int *csrColIdxA_tmp = (int *)malloc(nnzA_mtx_report * sizeof(int));
    VALUE_TYPE *csrValA_tmp    = (VALUE_TYPE *)malloc(nnzA_mtx_report * sizeof(VALUE_TYPE));

    /* NOTE: when reading in doubles, ANSI C requires the use of the "l"  */
    /*   specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
    /*  (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15)            */

    for (int i = 0; i < nnzA_mtx_report; i++)
    {
        int idxi, idxj;
        double fval;
        int ival;
        int returnvalue;

        if (isReal)
            returnvalue = fscanf(f, "%d %d %lg\n", &idxi, &idxj, &fval);
        else if (isInteger)
        {
            returnvalue = fscanf(f, "%d %d %d\n", &idxi, &idxj, &ival);
            fval = ival;
        }
        else if (isPattern)
        {
            returnvalue = fscanf(f, "%d %d\n", &idxi, &idxj);
            fval = 1.0;
        }

        // adjust from 1-based to 0-based
        idxi--;
        idxj--;

        csrRowPtrA_counter[idxi]++;
        csrRowIdxA_tmp[i] = idxi;
        csrColIdxA_tmp[i] = idxj;
        csrValA_tmp[i] = fval;
    }

    if (f != stdin)
        fclose(f);

    if (isSymmetric)
    {
        for (int i = 0; i < nnzA_mtx_report; i++)
        {
            if (csrRowIdxA_tmp[i] != csrColIdxA_tmp[i])
                csrRowPtrA_counter[csrColIdxA_tmp[i]]++;
        }
    }

    // exclusive scan for csrRowPtrA_counter
    int old_val, new_val;

    old_val = csrRowPtrA_counter[0];
    csrRowPtrA_counter[0] = 0;
    for (int i = 1; i <= m; i++)
    {
        new_val = csrRowPtrA_counter[i];
        csrRowPtrA_counter[i] = old_val + csrRowPtrA_counter[i-1];
        old_val = new_val;
    }

    nnzA = csrRowPtrA_counter[m];
    csrRowPtrA = (int *)malloc((m+1) * sizeof(int));
    memcpy(csrRowPtrA, csrRowPtrA_counter, (m+1) * sizeof(int));
    memset(csrRowPtrA_counter, 0, (m+1) * sizeof(int));

    csrColIdxA = (int *)malloc(nnzA * sizeof(int));
    csrValA    = (VALUE_TYPE *)malloc(nnzA * sizeof(VALUE_TYPE));

    if (isSymmetric)
    {
        for (int i = 0; i < nnzA_mtx_report; i++)
        {
            if (csrRowIdxA_tmp[i] != csrColIdxA_tmp[i])
            {
                int offset = csrRowPtrA[csrRowIdxA_tmp[i]] + csrRowPtrA_counter[csrRowIdxA_tmp[i]];
                csrColIdxA[offset] = csrColIdxA_tmp[i];
                csrValA[offset] = csrValA_tmp[i];
                csrRowPtrA_counter[csrRowIdxA_tmp[i]]++;

                offset = csrRowPtrA[csrColIdxA_tmp[i]] + csrRowPtrA_counter[csrColIdxA_tmp[i]];
                csrColIdxA[offset] = csrRowIdxA_tmp[i];
                csrValA[offset] = csrValA_tmp[i];
                csrRowPtrA_counter[csrColIdxA_tmp[i]]++;
            }
            else
            {
                int offset = csrRowPtrA[csrRowIdxA_tmp[i]] + csrRowPtrA_counter[csrRowIdxA_tmp[i]];
                csrColIdxA[offset] = csrColIdxA_tmp[i];
                csrValA[offset] = csrValA_tmp[i];
                csrRowPtrA_counter[csrRowIdxA_tmp[i]]++;
            }
        }
    }
    else
    {
        for (int i = 0; i < nnzA_mtx_report; i++)
        {
            int offset = csrRowPtrA[csrRowIdxA_tmp[i]] + csrRowPtrA_counter[csrRowIdxA_tmp[i]];
            csrColIdxA[offset] = csrColIdxA_tmp[i];
            csrValA[offset] = csrValA_tmp[i];
            csrRowPtrA_counter[csrRowIdxA_tmp[i]]++;
        }
    }

    // free tmp space
    free(csrColIdxA_tmp);
    free(csrValA_tmp);
    free(csrRowIdxA_tmp);
    free(csrRowPtrA_counter);
/*
    // a small matrix
    free(csrColIdxA);
    free(csrValA);
    free(csrRowPtrA);

    m = n = 8;
    nnzA = 17;
    csrRowPtrA = (int *)malloc(sizeof(int) * (m+1));
    csrColIdxA = (int *)malloc(sizeof(int) * nnzA);
    csrValA    = (VALUE_TYPE *)malloc(nnzA * sizeof(VALUE_TYPE));
    csrRowPtrA[0] = 0; csrRowPtrA[1] = 1; csrRowPtrA[2] = 2; csrRowPtrA[3] = 4; csrRowPtrA[4] = 6; 
    csrRowPtrA[5] = 10; csrRowPtrA[6] = 12; csrRowPtrA[7] = 15; csrRowPtrA[8] = nnzA;
    

    csrColIdxA[0] = 0;  csrColIdxA[1] = 1;  csrColIdxA[2] = 1;  csrColIdxA[3] = 2;  csrColIdxA[4] = 0;  
    csrColIdxA[5] = 3;  csrColIdxA[6] = 1;  csrColIdxA[7] = 2;  csrColIdxA[8] = 3;  csrColIdxA[9] = 4;  
    csrColIdxA[10] = 3;  csrColIdxA[11] = 5;  csrColIdxA[12] = 2;  csrColIdxA[13] = 5;  csrColIdxA[14] = 6;  
    csrColIdxA[15] = 6;  csrColIdxA[16] = 7;  
    // a small matrix stop
*/
    printf("input matrix A: ( %i, %i ) nnz = %i\n", m, n, nnzA);

    // extract L with the unit-lower triangular sparsity structure of A
    int nnzL = 0;
    int *csrRowPtrL_tmp = (int *)malloc((m+1) * sizeof(int));
    int *csrColIdxL_tmp = (int *)malloc(nnzA * sizeof(int));
    VALUE_TYPE *csrValL_tmp    = (VALUE_TYPE *)malloc(nnzA * sizeof(VALUE_TYPE));

    int nnz_pointer = 0;
    csrRowPtrL_tmp[0] = 0;
    for (int i = 0; i < m; i++)
    {
        for (int j = csrRowPtrA[i]; j < csrRowPtrA[i+1]; j++)
        {
            if (csrColIdxA[j] < i)
            {
                csrColIdxL_tmp[nnz_pointer] = csrColIdxA[j];
                csrValL_tmp[nnz_pointer] = 1.0; //csrValA[j];
                nnz_pointer++;
            }
            else
            {
                break;
            }
        }

        csrColIdxL_tmp[nnz_pointer] = i;
        csrValL_tmp[nnz_pointer] = 1.0;
        nnz_pointer++;

        csrRowPtrL_tmp[i+1] = nnz_pointer;
    }

    nnzL = csrRowPtrL_tmp[m];
    printf("A's unit-lower triangular L: ( %i, %i ) nnz = %i\n", m, n, nnzL);

    csrColIdxL_tmp = (int *)realloc(csrColIdxL_tmp, sizeof(int) * nnzL);
    csrValL_tmp = (VALUE_TYPE *)realloc(csrValL_tmp, sizeof(VALUE_TYPE) * nnzL);

    // run serial syncfree SpTS as a reference
    printf("---------------------------------------------------------------------------------------------\n");
    spts_syncfree_serialref(csrRowPtrL_tmp, csrColIdxL_tmp, csrValL_tmp, m, n, nnzL);

    // run cuda syncfree SpTS
    printf("---------------------------------------------------------------------------------------------\n");
    spts_syncfree_opencl(csrRowPtrL_tmp, csrColIdxL_tmp, csrValL_tmp, m, n, nnzL);

    printf("---------------------------------------------------------------------------------------------\n");

    // done!
    free(csrColIdxA);
    free(csrValA);
    free(csrRowPtrA);

    free(csrColIdxL_tmp);
    free(csrValL_tmp);
    free(csrRowPtrL_tmp);

    return 0;
}
Esempio n. 12
0
int main() {

   /* Host/device data structures */
   cl_platform_id platform;
   cl_device_id device;
   cl_context context;
   cl_command_queue queue;
   cl_int err, i;

   /* Program/kernel data structures */
   cl_program program;
   FILE *program_handle;
   char *program_buffer, *program_log;
   size_t program_size, log_size;
   cl_kernel kernel;
   size_t global_size, local_size;

   /* Data and buffers */
   int num_rows, num_cols, num_values;
   int *rows, *cols;
   float *values, *b_vec;
   float result[2];
   double value_double;
   cl_mem rows_buffer, cols_buffer, values_buffer, 
         b_buffer, result_buffer;

   /* Read sparse file */
   FILE *mm_handle;
   MM_typecode code;

   /* Read matrix file */   
   if ((mm_handle = fopen(MM_FILE, "r")) == NULL) {
      perror("Couldn't open the MatrixMarket file");
      exit(1);
   }
   mm_read_banner(mm_handle, &code);
   mm_read_mtx_crd_size(mm_handle, &num_rows, &num_cols, &num_values);

   /* Check for symmetry and allocate memory */
   if(mm_is_symmetric(code) || mm_is_skew(code) || mm_is_hermitian(code)) {
      num_values += num_values - num_rows;
   }
   rows = (int*) malloc(num_values * sizeof(int));
   cols = (int*) malloc(num_values * sizeof(int));
   values = (float*) malloc(num_values * sizeof(float));
   b_vec = (float*) malloc(num_rows * sizeof(float));

   /* Read matrix data and close file */
   i=0;
   while(i<num_values) {
      fscanf(mm_handle, "%d %d %lg\n", &rows[i], &cols[i], &value_double);
      values[i] = (float)value_double;
      cols[i]--;
      rows[i]--;
      if((rows[i] != cols[i]) && (mm_is_symmetric(code) || mm_is_skew(code) || mm_is_hermitian(code))) {
         i++;
         rows[i] = cols[i-1];
         cols[i] = rows[i-1];
         values[i] = values[i-1];
      }
      i++;
   }
   sort(num_values, rows, cols, values);
   fclose(mm_handle);

   /* Initialize the b vector */
   srand(time(0));
   for(i=0; i<num_rows; i++) {
      b_vec[i] = (float)(rand() - RAND_MAX/2);
   }

   /* Identify a platform */
   err = clGetPlatformIDs(1, &platform, NULL);
   if(err < 0) {
      perror("Couldn't identify a platform");
      exit(1);
   } 

   /* Access a device */
   err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
   if(err < 0) {
      perror("Couldn't access any devices");
      exit(1);   
   }

   /* Create a context */
   context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
   if(err < 0) {
      perror("Couldn't create a context");
      exit(1);   
   }

   /* Read program file and place content into buffer */
   program_handle = fopen(PROGRAM_FILE, "r");
   if(program_handle == NULL) {
      perror("Couldn't find the program file");
      exit(1);
   }
   fseek(program_handle, 0, SEEK_END);
   program_size = ftell(program_handle);
   rewind(program_handle);
   program_buffer = (char*)calloc(program_size+1, sizeof(char));
   fread(program_buffer, sizeof(char), program_size, program_handle);
   fclose(program_handle);

   /* Create program from file */
   program = clCreateProgramWithSource(context, 1, 
      (const char**)&program_buffer, &program_size, &err);
   if(err < 0) {
      perror("Couldn't create the program");
      exit(1);
   }
   free(program_buffer);

   /* Build program */
   err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
   if(err < 0) {
            
      /* Find size of log and print to std output */
      clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 
            0, NULL, &log_size);
      program_log = (char*) calloc(log_size+1, sizeof(char));
      clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 
            log_size+1, program_log, NULL);
      printf("%s\n", program_log);
      free(program_log);
      exit(1);
   }

   /* Create a kernel */
   kernel = clCreateKernel(program, KERNEL_FUNC, &err);
   if(err < 0) {
      printf("Couldn't create a kernel: %d", err);
      exit(1);
   };

   /* Create buffers to hold the text characters and count */
   rows_buffer = clCreateBuffer(context, 
         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 
         num_values*sizeof(int), rows, &err);
   if(err < 0) {
      perror("Couldn't create a buffer");
      exit(1);   
   };
   cols_buffer = clCreateBuffer(context,
         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 
         num_values*sizeof(int), cols, NULL);
   values_buffer = clCreateBuffer(context,
         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 
         num_values*sizeof(float), values, NULL);
   b_buffer = clCreateBuffer(context,
         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, 
         num_values*sizeof(float), b_vec, NULL);
   result_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, 
         2*sizeof(float), NULL, NULL);

   /* Create kernel argument */
   err = clSetKernelArg(kernel, 0, sizeof(num_rows), &num_rows);
   err |= clSetKernelArg(kernel, 1, sizeof(num_values), &num_values);
   err |= clSetKernelArg(kernel, 2, num_rows * sizeof(float), NULL);
   err |= clSetKernelArg(kernel, 3, num_rows * sizeof(float), NULL);
   err |= clSetKernelArg(kernel, 4, num_rows * sizeof(float), NULL);
   err |= clSetKernelArg(kernel, 5, num_rows * sizeof(float), NULL);
   err |= clSetKernelArg(kernel, 6, sizeof(cl_mem), &rows_buffer);
   err |= clSetKernelArg(kernel, 7, sizeof(cl_mem), &cols_buffer);
   err |= clSetKernelArg(kernel, 8, sizeof(cl_mem), &values_buffer);
   err |= clSetKernelArg(kernel, 9, sizeof(cl_mem), &b_buffer);
   err |= clSetKernelArg(kernel, 10, sizeof(cl_mem), &result_buffer);
   if(err < 0) {
      printf("Couldn't set a kernel argument");
      exit(1);   
   };

   /* Create a command queue */
   queue = clCreateCommandQueue(context, device, 0, &err);
   if(err < 0) {
      perror("Couldn't create a command queue");
      exit(1);   
   };

   /* Enqueue kernel */
   global_size = num_rows;
   local_size = num_rows;
   err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_size, 
         &local_size, 0, NULL, NULL);
   if(err < 0) {
      perror("Couldn't enqueue the kernel");
      printf("Error: %d\n", err);
      exit(1);
   }

   /* Read the results */
   err = clEnqueueReadBuffer(queue, result_buffer, CL_TRUE, 0, 
      2*sizeof(float), result, 0, NULL, NULL);
   if(err < 0) {
      perror("Couldn't read the buffer");
      exit(1);   
   }

   /* Print the result */
   printf("After %d iterations, the residual length is %f.\n", 
         (int)result[0], result[1]);

   /* Deallocate resources */
   free(b_vec);
   free(rows);
   free(cols);
   free(values);
   clReleaseMemObject(b_buffer);
   clReleaseMemObject(rows_buffer);
   clReleaseMemObject(cols_buffer);
   clReleaseMemObject(values_buffer);
   clReleaseMemObject(result_buffer);
   clReleaseKernel(kernel);
   clReleaseCommandQueue(queue);
   clReleaseProgram(program);
   clReleaseContext(context);
   return 0;
}
Esempio n. 13
0
static PetscErrorCode loadmtx(const char* filename, Mat *M, PetscBool *pattern) {
   PetscErrorCode ierr;
   FILE        *f;
   MM_typecode type;
   int         m,n,nz,i,j,k;
   PetscInt    low,high,lowj,highj,*d_nz,*o_nz;
   double      re,im;
   PetscScalar s;
   long        pos;

   PetscFunctionBegin;
   
   f = fopen(filename,"r");
   if (!f) SETERRQ2(PETSC_COMM_SELF,1,"fopen '%s': %s",filename,strerror(errno));
   
   /* first read to set matrix kind and size */
   ierr = mm_read_banner(f,&type);CHKERRQ(ierr);
   if (!mm_is_valid(type) || !mm_is_sparse(type) ||
       !(mm_is_real(type) || mm_is_complex(type) || mm_is_pattern(type) || mm_is_integer(type)))
      SETERRQ1(PETSC_COMM_SELF,1,"Matrix format '%s' not supported",mm_typecode_to_str(type)); 
#if !defined(PETSC_USE_COMPLEX)
   if (mm_is_complex(type)) SETERRQ(PETSC_COMM_SELF,1,"Complex matrix not supported in real configuration"); 
#endif
   if (pattern) *pattern = mm_is_pattern(type) ? PETSC_TRUE : PETSC_FALSE;
  
   ierr = mm_read_mtx_crd_size(f,&m,&n,&nz);CHKERRQ(ierr);
   pos = ftell(f);
   ierr = MatCreate(PETSC_COMM_WORLD,M);CHKERRQ(ierr);
   ierr = MatSetSizes(*M,PETSC_DECIDE,PETSC_DECIDE,(PetscInt)m,(PetscInt)n);CHKERRQ(ierr);
   ierr = MatSetFromOptions(*M);CHKERRQ(ierr);
   ierr = MatSetUp(*M);CHKERRQ(ierr);

   ierr = MatGetOwnershipRange(*M,&low,&high);CHKERRQ(ierr);  
   ierr = MatGetOwnershipRangeColumn(*M,&lowj,&highj);CHKERRQ(ierr);  
   ierr = PetscMalloc(sizeof(PetscInt)*(high-low),&d_nz);CHKERRQ(ierr);
   ierr = PetscMalloc(sizeof(PetscInt)*(high-low),&o_nz);CHKERRQ(ierr);
   for (i=0; i<high-low;i++) {
      d_nz[i] = (i+low>=lowj && i+low<highj) ? 1 : 0;
      o_nz[i] = (i+low>=lowj && i+low<highj) ? 0 : 1;
   }
   for (k=0;k<nz;k++) {
      ierr = mm_read_mtx_crd_entry(f,&i,&j,&re,&im,type);CHKERRQ(ierr);
      i--; j--;
      if (i!=j) {
         if (i>=low && i<high) {
            if (j>=lowj && j<highj) 
               d_nz[i-low]++;
            else
               o_nz[i-low]++;
         }
         if (j>=low && j<high && !mm_is_general(type)) {
            if (i>=low && i<high) 
               d_nz[j-low]++;
            else
               o_nz[j-low]++;        
         }
      }
   }
   ierr = preallocation(*M,d_nz,o_nz);CHKERRQ(ierr);
   ierr = PetscFree(d_nz);CHKERRQ(ierr);
   ierr = PetscFree(o_nz);CHKERRQ(ierr);
  
   /* second read to load the values */ 
   ierr = fseek(f, pos, SEEK_SET);
   if (ierr) SETERRQ1(PETSC_COMM_SELF,1,"fseek: %s",strerror(errno));
    
   re = 1.0;
   im = 0.0;
   /* Set the diagonal to zero */
   for (i=low; i<PetscMin(high,n); i++) {
      ierr = MatSetValue(*M,i,i,0.0,INSERT_VALUES);CHKERRQ(ierr);
   }
   for (k=0;k<nz;k++) {
      ierr = mm_read_mtx_crd_entry(f,&i,&j,&re,&im,type);
      i--; j--;
      if (i>=low && i<high) {
         s = re + IMAGINARY * im;
         ierr = MatSetValue(*M,i,j,s,INSERT_VALUES);CHKERRQ(ierr);
      }
      if (j>=low && j<high && i != j && !mm_is_general(type)) {
         if (mm_is_symmetric(type)) s = re + IMAGINARY * im;
         else if (mm_is_hermitian(type)) s = re - IMAGINARY * im;
         else if (mm_is_skew(type)) s = -re - IMAGINARY * im;
         else {
            SETERRQ1(PETSC_COMM_SELF,1,"Matrix format '%s' not supported",mm_typecode_to_str(type));
         }
         ierr = MatSetValue(*M,j,i,s,INSERT_VALUES);CHKERRQ(ierr);
      }
   }
   ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
   ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

   if (mm_is_symmetric(type)) { 
      ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
   }
   if ((mm_is_symmetric(type) && mm_is_real(type)) || mm_is_hermitian(type)) { 
      ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);
   }

   ierr = fclose(f);
   if (ierr) SETERRQ1(PETSC_COMM_SELF,1,"fclose: %s",strerror(errno));

   PetscFunctionReturn(0);
}