Actual source code: iscomp.c

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

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

  6:   Collective

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

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

 17:   Level: intermediate

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

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

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

 41:   PetscFunctionBegin;
 44:   PetscAssertPointer(flg, 3);

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

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

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

 64:     if (sz1 != sz2) *flg = PETSC_FALSE;
 65:     else {
 66:       PetscCall(ISGetIndices(is1, &ptr1));
 67:       PetscCall(ISGetIndices(is2, &ptr2));

 69:       PetscCall(PetscMalloc1(sz1, &a1));
 70:       PetscCall(PetscMalloc1(sz2, &a2));

 72:       PetscCall(PetscArraycpy(a1, ptr1, sz1));
 73:       PetscCall(PetscArraycpy(a2, ptr2, sz2));

 75:       PetscCall(PetscIntSortSemiOrdered(sz1, a1));
 76:       PetscCall(PetscIntSortSemiOrdered(sz2, a2));
 77:       PetscCall(PetscArraycmp(a1, a2, sz1, flg));

 79:       PetscCall(ISRestoreIndices(is1, &ptr1));
 80:       PetscCall(ISRestoreIndices(is2, &ptr2));

 82:       PetscCall(PetscFree(a1));
 83:       PetscCall(PetscFree(a2));
 84:     }
 85:     PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
 86:     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
 87:   }
 88:   PetscFunctionReturn(PETSC_SUCCESS);
 89: }

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

 94:   Collective

 96:   Input Parameters:
 97: + is1 - first index set to compare
 98: - is2 - second index set to compare

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

105:   Level: intermediate

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

111:   Each MPI rank must have the same indices.

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

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

127:   if (is1 == is2) {
128:     *flg = PETSC_TRUE;
129:     PetscFunctionReturn(PETSC_SUCCESS);
130:   }

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

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

145:     if (sz1 != sz2) *flg = PETSC_FALSE;
146:     else {
147:       PetscCall(ISGetIndices(is1, &ptr1));
148:       PetscCall(ISGetIndices(is2, &ptr2));

150:       PetscCall(PetscArraycmp(ptr1, ptr2, sz1, flg));

152:       PetscCall(ISRestoreIndices(is1, &ptr1));
153:       PetscCall(ISRestoreIndices(is2, &ptr2));
154:     }
155:     PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
156:     PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
157:   }
158:   PetscFunctionReturn(PETSC_SUCCESS);
159: }