xref: /petsc/src/mat/utils/zerorows.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
16e520ac8SStefano Zampini #include <petsc/private/matimpl.h>
26e520ac8SStefano Zampini #include <petscsf.h>
36e520ac8SStefano Zampini 
46e520ac8SStefano Zampini /* this function maps rows to locally owned rows */
5*9371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatZeroRowsMapLocal_Private(Mat A, PetscInt N, const PetscInt *rows, PetscInt *nr, PetscInt **olrows) {
66e520ac8SStefano Zampini   PetscInt    *owners = A->rmap->range;
76e520ac8SStefano Zampini   PetscInt     n      = A->rmap->n;
86e520ac8SStefano Zampini   PetscSF      sf;
96e520ac8SStefano Zampini   PetscInt    *lrows;
106e520ac8SStefano Zampini   PetscSFNode *rrows;
11131c27b5Sprj-   PetscMPIInt  rank, p = 0;
12131c27b5Sprj-   PetscInt     r, len  = 0;
136e520ac8SStefano Zampini 
146e520ac8SStefano Zampini   PetscFunctionBegin;
156e520ac8SStefano Zampini   /* Create SF where leaves are input rows and roots are owned rows */
169566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)A), &rank));
179566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(n, &lrows));
186e520ac8SStefano Zampini   for (r = 0; r < n; ++r) lrows[r] = -1;
199566063dSJacob Faibussowitsch   if (!A->nooffproczerorows) PetscCall(PetscMalloc1(N, &rrows));
206e520ac8SStefano Zampini   for (r = 0; r < N; ++r) {
216e520ac8SStefano Zampini     const PetscInt idx = rows[r];
22aed4548fSBarry Smith     PetscCheck(idx >= 0 && A->rmap->N > idx, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row %" PetscInt_FMT " out of range [0,%" PetscInt_FMT ")", idx, A->rmap->N);
236e520ac8SStefano Zampini     if (idx < owners[p] || owners[p + 1] <= idx) { /* short-circuit the search if the last p owns this row too */
249566063dSJacob Faibussowitsch       PetscCall(PetscLayoutFindOwner(A->rmap, idx, &p));
256e520ac8SStefano Zampini     }
266e520ac8SStefano Zampini     if (A->nooffproczerorows) {
2708401ef6SPierre Jolivet       PetscCheck(p == rank, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "MAT_NO_OFF_PROC_ZERO_ROWS set, but row %" PetscInt_FMT " is not owned by rank %d", idx, rank);
286e520ac8SStefano Zampini       lrows[len++] = idx - owners[p];
296e520ac8SStefano Zampini     } else {
306e520ac8SStefano Zampini       rrows[r].rank  = p;
316e520ac8SStefano Zampini       rrows[r].index = rows[r] - owners[p];
326e520ac8SStefano Zampini     }
336e520ac8SStefano Zampini   }
346e520ac8SStefano Zampini   if (!A->nooffproczerorows) {
359566063dSJacob Faibussowitsch     PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)A), &sf));
369566063dSJacob Faibussowitsch     PetscCall(PetscSFSetGraph(sf, n, N, NULL, PETSC_OWN_POINTER, rrows, PETSC_OWN_POINTER));
376e520ac8SStefano Zampini     /* Collect flags for rows to be zeroed */
389566063dSJacob Faibussowitsch     PetscCall(PetscSFReduceBegin(sf, MPIU_INT, (PetscInt *)rows, lrows, MPI_LOR));
399566063dSJacob Faibussowitsch     PetscCall(PetscSFReduceEnd(sf, MPIU_INT, (PetscInt *)rows, lrows, MPI_LOR));
409566063dSJacob Faibussowitsch     PetscCall(PetscSFDestroy(&sf));
416e520ac8SStefano Zampini     /* Compress and put in row numbers */
42*9371c9d4SSatish Balay     for (r = 0; r < n; ++r)
43*9371c9d4SSatish Balay       if (lrows[r] >= 0) lrows[len++] = r;
446e520ac8SStefano Zampini   }
456e520ac8SStefano Zampini   if (nr) *nr = len;
466e520ac8SStefano Zampini   if (olrows) *olrows = lrows;
476e520ac8SStefano Zampini   PetscFunctionReturn(0);
486e520ac8SStefano Zampini }
49