Actual source code: iscomp.c

  1: #include <petsc/private/isimpl.h>
  2: #include <petscviewer.h>

  4: /*@
  5:   ISEqual  - Compares if two index sets have the same set of indices.

  7:   Collective

  9:   Input Parameters:
 10: + is1 - first index set to compare
 11: - is2 - second index set to compare

 13:   Output Parameter:
 14: . flg - output flag, either `PETSC_TRUE` (if both index sets have the
 15:          same indices), or `PETSC_FALSE` if the index sets differ by size
 16:          or by the set of indices)

 18:   Level: intermediate

 20:   Note:
 21:   Unlike `ISEqualUnsorted()`, this routine sorts the contents of the index sets (only within each MPI rank) before
 22:   the comparison is made, so the order of the indices on a processor is immaterial.

 24:   Each processor has to have the same indices in the two sets, for example,
 25: .vb
 26:            Processor
 27:              0      1
 28:     is1 = {0, 1} {2, 3}
 29:     is2 = {2, 3} {0, 1}
 30: .ve
 31:   will return false.

 33: .seealso: [](sec_scatter), `IS`, `ISEqualUnsorted()`
 34: @*/
 35: PetscErrorCode ISEqual(IS is1, IS is2, PetscBool *flg)
 36: {
 37:   PetscInt        sz1, sz2, *a1, *a2;
 38:   const PetscInt *ptr1, *ptr2;
 39:   PetscBool       flag;
 40:   MPI_Comm        comm;
 41:   PetscMPIInt     mflg;

 43:   PetscFunctionBegin;
 46:   PetscAssertPointer(flg, 3);

 48:   if (is1 == is2) {
 49:     *flg = PETSC_TRUE;
 50:     PetscFunctionReturn(PETSC_SUCCESS);
 51:   }

 53:   PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)is1), PetscObjectComm((PetscObject)is2), &mflg));
 54:   if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
 55:     *flg = PETSC_FALSE;
 56:     PetscFunctionReturn(PETSC_SUCCESS);
 57:   }

 59:   PetscCall(ISGetSize(is1, &sz1));
 60:   PetscCall(ISGetSize(is2, &sz2));
 61:   if (sz1 != sz2) *flg = PETSC_FALSE;
 62:   else {
 63:     PetscCall(ISGetLocalSize(is1, &sz1));
 64:     PetscCall(ISGetLocalSize(is2, &sz2));

 66:     if (sz1 != sz2) flag = PETSC_FALSE;
 67:     else {
 68:       PetscCall(ISGetIndices(is1, &ptr1));
 69:       PetscCall(ISGetIndices(is2, &ptr2));

 71:       PetscCall(PetscMalloc1(sz1, &a1));
 72:       PetscCall(PetscMalloc1(sz2, &a2));

 74:       PetscCall(PetscArraycpy(a1, ptr1, sz1));
 75:       PetscCall(PetscArraycpy(a2, ptr2, sz2));

 77:       PetscCall(PetscIntSortSemiOrdered(sz1, a1));
 78:       PetscCall(PetscIntSortSemiOrdered(sz2, a2));
 79:       PetscCall(PetscArraycmp(a1, a2, sz1, &flag));

 81:       PetscCall(ISRestoreIndices(is1, &ptr1));
 82:       PetscCall(ISRestoreIndices(is2, &ptr2));

 84:       PetscCall(PetscFree(a1));
 85:       PetscCall(PetscFree(a2));
 86:     }
 87:     PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
 88:     PetscCallMPI(MPIU_Allreduce(&flag, flg, 1, MPIU_BOOL, MPI_MIN, comm));
 89:   }
 90:   PetscFunctionReturn(PETSC_SUCCESS);
 91: }

 93: /*@
 94:   ISEqualUnsorted  - Compares if two index sets have the same indices.

 96:   Collective

 98:   Input Parameters:
 99: + is1 - first index set to compare
100: - is2 - second index set to compare

102:   Output Parameter:
103: . flg - output flag, either `PETSC_TRUE` (if both index sets have the
104:          same indices), or `PETSC_FALSE` if the index sets differ by size
105:          or by the set of indices)

107:   Level: intermediate

109:   Note:
110:   Unlike `ISEqual()`, this routine does NOT sort the contents of the index sets before
111:   the comparison is made, i.e., the order of indices is important.

113:   Each MPI rank must have the same indices.

115: .seealso: [](sec_scatter), `IS`, `ISEqual()`
116: @*/
117: PetscErrorCode ISEqualUnsorted(IS is1, IS is2, PetscBool *flg)
118: {
119:   PetscInt        sz1, sz2;
120:   const PetscInt *ptr1, *ptr2;
121:   PetscBool       flag;
122:   MPI_Comm        comm;
123:   PetscMPIInt     mflg;

125:   PetscFunctionBegin;
128:   PetscAssertPointer(flg, 3);

130:   if (is1 == is2) {
131:     *flg = PETSC_TRUE;
132:     PetscFunctionReturn(PETSC_SUCCESS);
133:   }

135:   PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)is1), PetscObjectComm((PetscObject)is2), &mflg));
136:   if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
137:     *flg = PETSC_FALSE;
138:     PetscFunctionReturn(PETSC_SUCCESS);
139:   }

141:   PetscCall(ISGetSize(is1, &sz1));
142:   PetscCall(ISGetSize(is2, &sz2));
143:   if (sz1 != sz2) *flg = PETSC_FALSE;
144:   else {
145:     PetscCall(ISGetLocalSize(is1, &sz1));
146:     PetscCall(ISGetLocalSize(is2, &sz2));

148:     if (sz1 != sz2) flag = PETSC_FALSE;
149:     else {
150:       PetscCall(ISGetIndices(is1, &ptr1));
151:       PetscCall(ISGetIndices(is2, &ptr2));

153:       PetscCall(PetscArraycmp(ptr1, ptr2, sz1, &flag));

155:       PetscCall(ISRestoreIndices(is1, &ptr1));
156:       PetscCall(ISRestoreIndices(is2, &ptr2));
157:     }
158:     PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
159:     PetscCallMPI(MPIU_Allreduce(&flag, flg, 1, MPIU_BOOL, MPI_MIN, comm));
160:   }
161:   PetscFunctionReturn(PETSC_SUCCESS);
162: }