[petsc-users] About MatGetOwnershipRange()

Joon Hee Choi choi240 at purdue.edu
Thu Sep 12 02:31:42 CDT 2013


Hello,

I am trying to set up a large MATMPIAIJ matrix from tuples. The tuples is pairs of (row, column, value). I will use 12~20 machines for this implementation. However, I think I need to know rows on each process before preallocation, because for large matrices the exact preallocation is important for good performance. Thus, I tried to use MatGetOwnershipRange(), but I found out that I cannot use it before preallocation. Could you let me know how to change my code? I am attaching the code.

Thank you,
Joon


PetscErrorCode SetUpMatrix(Mat *X, vector< std::tr1::tuple< PetscInt, PetscInt, PetscInt > >, PetscInt I, PetscInt J)
{
   PetscInt i, j;
   PetscScalar val;

   MatCreate(PETSC_COMM_WORLD, X);
   MatSetType(*X, MATMPIAIJ);
   MatSetSizes(*X, PETSC_DECIDE, PETSC_DECIDE, I, J);

   PetscInt begin, end;
   MatGetOwnershipRange(*X, &begin, &end);
   PetscInt localsize = end - begin;

   PetscInt d_nnz[localsize];
   PetscInt o_nnz[localsize];

   for (int x=0; x<tups.size(); x++) {
      i = std::tr1::get<0>(tups[x]);
      if (i>=end) break;
      if (i>=begin) {
         j = std::tr1::get<1>(tups[x]);
         if (j>=begin && j<end)  d_nnz[i-begin]++;
         else                    o_nnz[i-begin]++;
      }
   }
   MatMPIAIJSetPreallocation(*X, 0, d_nnz, 0, o_nnz);

   for (int x=0; x<tups.size(); x++) {
      i = std::tr1::get<0>(tups[x]);
      if (i>=end) break;
      if (i>=begin) {
         j = std::tr1::get<1>(tups[x]);
         val = std::tr1::get<2>(tups[x]);
         MatSetValues(*X, 1, &i, 1, &j, &val, INSERT_VALUES);
      }
   }
   MatAssemblyBegin(*X, MAT_FINAL_ASSEMBLY);
   MatAssemblyEnd(*X, MAT_FINAL_ASSEMBLY);
}


More information about the petsc-users mailing list