Commits

Jed Brown  committed 0c6fd35 Merge

Merge branch 'jed/mat-convert-preallocate'

* jed/mat-convert-preallocate:
MatConvert_Basic(): preallocate for DENSE
MatConvert_Basic: preallocate for AIJ, BAIJ, and SBAIJ

  • Participants
  • Parent commits 95e2ec2, 7f5be9a

Comments (0)

Files changed (3)

File src/mat/examples/tests/output/ex114_2.out

File contents unchanged.

File src/mat/examples/tests/output/ex114_3.out

File contents unchanged.

File src/mat/utils/convert.c

   Mat               M;
   const PetscScalar *vwork;
   PetscErrorCode    ierr;
-  PetscInt          i,nz,m,n,rstart,rend,lm,ln;
+  PetscInt          i,j,nz,m,n,rstart,rend,lm,ln,prbs,pcbs,cstart,cend,*dnz,*onz;
   const PetscInt    *cwork;
-  PetscBool         isseqsbaij,ismpisbaij;
+  PetscBool         isseqsbaij,ismpisbaij,isseqbaij,ismpibaij,isseqdense,ismpidense;
 
   PetscFunctionBegin;
   ierr = MatGetSize(mat,&m,&n);CHKERRQ(ierr);
 
   ierr = MatCreate(PetscObjectComm((PetscObject)mat),&M);CHKERRQ(ierr);
   ierr = MatSetSizes(M,lm,ln,m,n);CHKERRQ(ierr);
-  ierr = MatSetBlockSize(M,mat->rmap->bs);CHKERRQ(ierr);
+  ierr = MatSetBlockSizes(M,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr);
   ierr = MatSetType(M,newtype);CHKERRQ(ierr);
+  ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
+
   ierr = PetscObjectTypeCompare((PetscObject)M,MATSEQSBAIJ,&isseqsbaij);CHKERRQ(ierr);
   ierr = PetscObjectTypeCompare((PetscObject)M,MATMPISBAIJ,&ismpisbaij);CHKERRQ(ierr);
-  ierr = MatSetUp(M);CHKERRQ(ierr);
   if (isseqsbaij || ismpisbaij) {ierr = MatSetOption(M,MAT_IGNORE_LOWER_TRIANGULAR,PETSC_TRUE);CHKERRQ(ierr);}
+  ierr = PetscObjectTypeCompare((PetscObject)M,MATSEQBAIJ,&isseqbaij);CHKERRQ(ierr);
+  ierr = PetscObjectTypeCompare((PetscObject)M,MATMPIBAIJ,&ismpibaij);CHKERRQ(ierr);
+  ierr = PetscObjectTypeCompare((PetscObject)M,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
+  ierr = PetscObjectTypeCompare((PetscObject)M,MATMPIDENSE,&ismpidense);CHKERRQ(ierr);
 
-  ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr);
+  if (isseqdense) {
+    ierr = MatSeqDenseSetPreallocation(M,NULL);CHKERRQ(ierr);
+  } else if (ismpidense) {
+    ierr = MatMPIDenseSetPreallocation(M,NULL);CHKERRQ(ierr);
+  } else {
+    /* Preallocation block sizes.  (S)BAIJ matrices will have one index per block. */
+    prbs = (isseqbaij || ismpibaij || isseqsbaij || ismpisbaij) ? M->rmap->bs : 1;
+    pcbs = (isseqbaij || ismpibaij || isseqsbaij || ismpisbaij) ? M->cmap->bs : 1;
+
+    ierr = PetscMalloc2(lm/prbs,PetscInt,&dnz,lm/prbs,PetscInt,&onz);CHKERRQ(ierr);
+    ierr = MatGetOwnershipRangeColumn(mat,&cstart,&cend);CHKERRQ(ierr);
+    for (i=0; i<lm; i+=prbs) {
+      ierr = MatGetRow(mat,rstart+i,&nz,&cwork,NULL);CHKERRQ(ierr);
+      dnz[i] = 0;
+      onz[i] = 0;
+      for (j=0; j<nz; j+=pcbs) {
+        if ((isseqsbaij || ismpisbaij) && cwork[j] < rstart+i) continue;
+        if (cstart <= cwork[j] && cwork[j] < cend) dnz[i]++;
+        else                                       onz[i]++;
+      }
+      ierr = MatRestoreRow(mat,rstart+i,&nz,&cwork,NULL);CHKERRQ(ierr);
+    }
+    ierr = MatXAIJSetPreallocation(M,M->rmap->bs,dnz,onz,dnz,onz);CHKERRQ(ierr);
+    ierr = PetscFree2(dnz,onz);CHKERRQ(ierr);
+  }
+
   for (i=rstart; i<rend; i++) {
     ierr = MatGetRow(mat,i,&nz,&cwork,&vwork);CHKERRQ(ierr);
     ierr = MatSetValues(M,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr);