xref: /petsc/src/vec/is/is/utils/iscomp.c (revision 8112c1cbf372cb53bf7c5aca994a84a6a303db4d)
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