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