Advertisement
Guest User

PETSc Preallocation

a guest
Jul 7th, 2017
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.02 KB | None | 0 0
  1. #include "petscmat.h"  
  2. #include "petscviewer.h"
  3.  
  4. int main(int argc, char **argv)
  5. {
  6.   const int size = 10;
  7.   const double nz_ratio = 0.8;
  8.   const bool doPrealloc = true;
  9.   printf("nz_ratio = %f\n", nz_ratio);
  10.  
  11.   PetscInt colNum = 0;
  12.   PetscInt colIdx[size];
  13.   PetscScalar rowVals[size];
  14.  
  15.   PetscInt d_nnz[size], o_nnz[size];
  16.  
  17.   PetscInitialize(&argc, &argv, "", NULL);
  18.   PetscErrorCode ierr = 0;
  19.  
  20.   Mat A;
  21.   ierr = MatCreate(PETSC_COMM_WORLD, &A); CHKERRQ(ierr);
  22.   MatSetType(A, MATAIJ); CHKERRQ(ierr);
  23.   ierr = MatSetSizes(A, size, size, PETSC_DECIDE, PETSC_DECIDE); CHKERRQ(ierr);
  24.   ierr = MatSetUp(A); CHKERRQ(ierr);
  25.   MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
  26.  
  27.   PetscInt range_start, range_end;
  28.   MatGetOwnershipRange(A, &range_start, &range_end);
  29.  
  30.   PetscInt col_range_start, col_range_end;
  31.   MatGetOwnershipRangeColumn(A, &col_range_start, &col_range_end);
  32.   printf("Column Ownership Range = %i / %i\n", col_range_start, col_range_end);
  33.  
  34.   if (doPrealloc) {
  35.     for (int row = range_start; row < range_end; row++) {
  36.       // printf("Row %i\n", row);
  37.       d_nnz[row] = 0;
  38.       o_nnz[row] = 0;
  39.       int colStart = row - nz_ratio/2 * size;
  40.       int colEnd   = row + nz_ratio/2 * size;
  41.       colStart = (colStart < 0)    ? 0    : colStart;
  42.       colEnd   = (colEnd   > size) ? size : colEnd;
  43.       // printf("colStart = %i, colEnd = %i\n", colStart, colEnd);
  44.       for (int col = 0; col < size; col++) {
  45.         // printf("Column %i ", col);
  46.         if (col >= colStart and col < colEnd) {
  47.           // printf("\n");
  48.           if (col >= col_range_start and col < col_range_end) {
  49.             // printf("  Adding prealloc diagonal\n");
  50.             d_nnz[row]++;
  51.           } else {
  52.             // printf("  Adding prealloc non-diagonal\n");
  53.             o_nnz[row]++;
  54.           }
  55.         }    
  56.       }
  57.       // printf("d_nnz[row] = %i, o_nnz[row] = %i\n", d_nnz[row], o_nnz[row]);
  58.     }
  59.     ierr = MatMPIAIJSetPreallocation(A, 0, d_nnz, 0, o_nnz); CHKERRQ(ierr);
  60.   }
  61.  
  62.   // Printing the prealloc array
  63.   for (int i = 0; i < size; i++) {
  64.     printf("%i o_nnz = %i, d_nnz = %i\n", i, o_nnz[i], d_nnz[i]);
  65.   }
  66.  
  67.   printf("End preallocation loop\n");
  68.  
  69.   for (int row = range_start; row < range_end; row++) {
  70.     int colStart = row - nz_ratio/2 * size;
  71.     int colEnd   = row + nz_ratio/2 * size;
  72.     colStart = (colStart < 0)    ? 0      : colStart;
  73.     colEnd   = (colEnd   > size) ? size   : colEnd;
  74.     for (int col = 0; col < size; col++) {
  75.       if (col >= colStart and col < colEnd) {
  76.         colIdx[colNum] = col;
  77.         rowVals[colNum] = row * col;
  78.         // printf("colNum = %i\n", colNum);
  79.         colNum++;
  80.       }      
  81.     }
  82.     printf("Inserting %i elements in row %i\n", colNum, row);
  83.     ierr = MatSetValues(A, 1,  &row, colNum, colIdx, rowVals, INSERT_VALUES); CHKERRQ(ierr);
  84.     colNum = 0;
  85.   }
  86.  
  87.   ierr = MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  88.   ierr = MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  89.  
  90.   PetscFinalize();
  91.   return 0;
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement