1 #include <petsc/private/matimpl.h> 2 #include <petscsf.h> 3 4 /* this function maps rows to locally owned rows */ 5 PETSC_INTERN PetscErrorCode MatZeroRowsMapLocal_Private(Mat A,PetscInt N,const PetscInt *rows,PetscInt *nr,PetscInt **olrows) 6 { 7 PetscInt *owners = A->rmap->range; 8 PetscInt n = A->rmap->n; 9 PetscSF sf; 10 PetscInt *lrows; 11 PetscSFNode *rrows; 12 PetscMPIInt rank, p = 0; 13 PetscInt r, len = 0; 14 PetscErrorCode ierr; 15 16 PetscFunctionBegin; 17 /* Create SF where leaves are input rows and roots are owned rows */ 18 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRMPI(ierr); 19 ierr = PetscMalloc1(n, &lrows);CHKERRQ(ierr); 20 for (r = 0; r < n; ++r) lrows[r] = -1; 21 if (!A->nooffproczerorows) {ierr = PetscMalloc1(N, &rrows);CHKERRQ(ierr);} 22 for (r = 0; r < N; ++r) { 23 const PetscInt idx = rows[r]; 24 if (idx < 0 || A->rmap->N <= idx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range [0,%D)",idx,A->rmap->N); 25 if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this row too */ 26 ierr = PetscLayoutFindOwner(A->rmap,idx,&p);CHKERRQ(ierr); 27 } 28 if (A->nooffproczerorows) { 29 if (p != rank) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"MAT_NO_OFF_PROC_ZERO_ROWS set, but row %D is not owned by rank %d",idx,rank); 30 lrows[len++] = idx - owners[p]; 31 } else { 32 rrows[r].rank = p; 33 rrows[r].index = rows[r] - owners[p]; 34 } 35 } 36 if (!A->nooffproczerorows) { 37 ierr = PetscSFCreate(PetscObjectComm((PetscObject) A), &sf);CHKERRQ(ierr); 38 ierr = PetscSFSetGraph(sf, n, N, NULL, PETSC_OWN_POINTER, rrows, PETSC_OWN_POINTER);CHKERRQ(ierr); 39 /* Collect flags for rows to be zeroed */ 40 ierr = PetscSFReduceBegin(sf, MPIU_INT, (PetscInt*)rows, lrows, MPI_LOR);CHKERRQ(ierr); 41 ierr = PetscSFReduceEnd(sf, MPIU_INT, (PetscInt*)rows, lrows, MPI_LOR);CHKERRQ(ierr); 42 ierr = PetscSFDestroy(&sf);CHKERRQ(ierr); 43 /* Compress and put in row numbers */ 44 for (r = 0; r < n; ++r) if (lrows[r] >= 0) lrows[len++] = r; 45 } 46 if (nr) *nr = len; 47 if (olrows) *olrows = lrows; 48 PetscFunctionReturn(0); 49 } 50