1 #include <petsc/private/isimpl.h> /*I "petscis.h" I*/
2 #include <petscviewer.h>
3
4 /*@
5 ISEqual - Compares if two index sets have the same set of indices.
6
7 Collective
8
9 Input Parameters:
10 + is1 - first index set to compare
11 - is2 - second index set to compare
12
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)
17
18 Level: intermediate
19
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.
23
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.
32
33 .seealso: [](sec_scatter), `IS`, `ISEqualUnsorted()`
34 @*/
ISEqual(IS is1,IS is2,PetscBool * flg)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;
42
43 PetscFunctionBegin;
44 PetscValidHeaderSpecific(is1, IS_CLASSID, 1);
45 PetscValidHeaderSpecific(is2, IS_CLASSID, 2);
46 PetscAssertPointer(flg, 3);
47
48 if (is1 == is2) {
49 *flg = PETSC_TRUE;
50 PetscFunctionReturn(PETSC_SUCCESS);
51 }
52
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 }
58
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));
65
66 if (sz1 != sz2) flag = PETSC_FALSE;
67 else {
68 PetscCall(ISGetIndices(is1, &ptr1));
69 PetscCall(ISGetIndices(is2, &ptr2));
70
71 PetscCall(PetscMalloc1(sz1, &a1));
72 PetscCall(PetscMalloc1(sz2, &a2));
73
74 PetscCall(PetscArraycpy(a1, ptr1, sz1));
75 PetscCall(PetscArraycpy(a2, ptr2, sz2));
76
77 PetscCall(PetscIntSortSemiOrdered(sz1, a1));
78 PetscCall(PetscIntSortSemiOrdered(sz2, a2));
79 PetscCall(PetscArraycmp(a1, a2, sz1, &flag));
80
81 PetscCall(ISRestoreIndices(is1, &ptr1));
82 PetscCall(ISRestoreIndices(is2, &ptr2));
83
84 PetscCall(PetscFree(a1));
85 PetscCall(PetscFree(a2));
86 }
87 PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
88 PetscCallMPI(MPIU_Allreduce(&flag, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
89 }
90 PetscFunctionReturn(PETSC_SUCCESS);
91 }
92
93 /*@
94 ISEqualUnsorted - Compares if two index sets have the same indices.
95
96 Collective
97
98 Input Parameters:
99 + is1 - first index set to compare
100 - is2 - second index set to compare
101
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)
106
107 Level: intermediate
108
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.
112
113 Each MPI rank must have the same indices.
114
115 .seealso: [](sec_scatter), `IS`, `ISEqual()`
116 @*/
ISEqualUnsorted(IS is1,IS is2,PetscBool * flg)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;
124
125 PetscFunctionBegin;
126 PetscValidHeaderSpecific(is1, IS_CLASSID, 1);
127 PetscValidHeaderSpecific(is2, IS_CLASSID, 2);
128 PetscAssertPointer(flg, 3);
129
130 if (is1 == is2) {
131 *flg = PETSC_TRUE;
132 PetscFunctionReturn(PETSC_SUCCESS);
133 }
134
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 }
140
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));
147
148 if (sz1 != sz2) flag = PETSC_FALSE;
149 else {
150 PetscCall(ISGetIndices(is1, &ptr1));
151 PetscCall(ISGetIndices(is2, &ptr2));
152
153 PetscCall(PetscArraycmp(ptr1, ptr2, sz1, &flag));
154
155 PetscCall(ISRestoreIndices(is1, &ptr1));
156 PetscCall(ISRestoreIndices(is2, &ptr2));
157 }
158 PetscCall(PetscObjectGetComm((PetscObject)is1, &comm));
159 PetscCallMPI(MPIU_Allreduce(&flag, flg, 1, MPI_C_BOOL, MPI_LAND, comm));
160 }
161 PetscFunctionReturn(PETSC_SUCCESS);
162 }
163