xref: /petsc/src/mat/utils/zerorows.c (revision 6e520ac86fd1984276935c8312606cbcba2a3c62)
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