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: }