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: MPI_Comm comm;
40: PetscMPIInt mflg;
42: PetscFunctionBegin;
45: PetscAssertPointer(flg, 3);
47: if (is1 == is2) {
48: *flg = PETSC_TRUE;
49: PetscFunctionReturn(PETSC_SUCCESS);
50: }
52: PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)is1), PetscObjectComm((PetscObject)is2), &mflg));
53: if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
54: *flg = PETSC_FALSE;
55: PetscFunctionReturn(PETSC_SUCCESS);
56: }
58: PetscCall(ISGetSize(is1, &sz1));
59: PetscCall(ISGetSize(is2, &sz2));
60: if (sz1 != sz2) *flg = PETSC_FALSE;
61: else {
62: PetscCall(ISGetLocalSize(is1, &sz1));
63: PetscCall(ISGetLocalSize(is2, &sz2));
65: if (sz1 != sz2) *flg = PETSC_FALSE;
66: else {
67: PetscCall(ISGetIndices(is1, &ptr1));
68: PetscCall(ISGetIndices(is2, &ptr2));
70: PetscCall(PetscMalloc1(sz1, &a1));
71: PetscCall(PetscMalloc1(sz2, &a2));
73: PetscCall(PetscArraycpy(a1, ptr1, sz1));
74: PetscCall(PetscArraycpy(a2, ptr2, sz2));
76: PetscCall(PetscIntSortSemiOrdered(sz1, a1));
77: PetscCall(PetscIntSortSemiOrdered(sz2, a2));
78: PetscCall(PetscArraycmp(a1, a2, sz1, flg));
80: PetscCall(ISRestoreIndices(is1, &ptr1));
81: PetscCall(ISRestoreIndices(is2, &ptr2));
83: PetscCall(PetscFree(a1));
84: PetscCall(PetscFree(a2));
85: }
86: PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
87: PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
88: }
89: PetscFunctionReturn(PETSC_SUCCESS);
90: }
92: /*@
93: ISEqualUnsorted - Compares if two index sets have the same indices.
95: Collective
97: Input Parameters:
98: + is1 - first index set to compare
99: - is2 - second index set to compare
101: Output Parameter:
102: . flg - output flag, either `PETSC_TRUE` (if both index sets have the
103: same indices), or `PETSC_FALSE` if the index sets differ by size
104: or by the set of indices)
106: Level: intermediate
108: Note:
109: Unlike `ISEqual()`, this routine does NOT sort the contents of the index sets before
110: the comparison is made, i.e., the order of indices is important.
112: Each MPI rank must have the same indices.
114: .seealso: [](sec_scatter), `IS`, `ISEqual()`
115: @*/
116: PetscErrorCode ISEqualUnsorted(IS is1, IS is2, PetscBool *flg)
117: {
118: PetscInt sz1, sz2;
119: const PetscInt *ptr1, *ptr2;
120: MPI_Comm comm;
121: PetscMPIInt mflg;
123: PetscFunctionBegin;
126: PetscAssertPointer(flg, 3);
128: if (is1 == is2) {
129: *flg = PETSC_TRUE;
130: PetscFunctionReturn(PETSC_SUCCESS);
131: }
133: PetscCallMPI(MPI_Comm_compare(PetscObjectComm((PetscObject)is1), PetscObjectComm((PetscObject)is2), &mflg));
134: if (mflg != MPI_CONGRUENT && mflg != MPI_IDENT) {
135: *flg = PETSC_FALSE;
136: PetscFunctionReturn(PETSC_SUCCESS);
137: }
139: PetscCall(ISGetSize(is1, &sz1));
140: PetscCall(ISGetSize(is2, &sz2));
141: if (sz1 != sz2) *flg = PETSC_FALSE;
142: else {
143: PetscCall(ISGetLocalSize(is1, &sz1));
144: PetscCall(ISGetLocalSize(is2, &sz2));
146: if (sz1 != sz2) *flg = PETSC_FALSE;
147: else {
148: PetscCall(ISGetIndices(is1, &ptr1));
149: PetscCall(ISGetIndices(is2, &ptr2));
151: PetscCall(PetscArraycmp(ptr1, ptr2, sz1, flg));
153: PetscCall(ISRestoreIndices(is1, &ptr1));
154: PetscCall(ISRestoreIndices(is2, &ptr2));
155: }
156: PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
157: PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
158: }
159: PetscFunctionReturn(PETSC_SUCCESS);
160: }