xref: /petsc/include/petscis.h (revision 66af8762ec03dbef0e079729eb2a1734a35ed7ff)
1 /*
2    An index set is a generalization of a subset of integers.  Index sets
3    are used for defining scatters and gathers.
4 */
5 #pragma once
6 
7 #include <petscsys.h>
8 #include <petscsftypes.h>
9 #include <petscsectiontypes.h>
10 #include <petscistypes.h> /*I  "petscis.h" I*/
11 
12 /* SUBMANSEC = IS */
13 
14 #define IS_FILE_CLASSID 1211218
15 PETSC_EXTERN PetscClassId IS_CLASSID;
16 
17 PETSC_EXTERN PetscErrorCode ISInitializePackage(void);
18 PETSC_EXTERN PetscErrorCode ISFinalizePackage(void);
19 
20 /*J
21     ISType - String with the name of a PETSc index set type
22 
23    Values:
24 +  `ISGENERAL` - the values are stored with an array of indices and generally have no structure
25 .  `ISSTRIDE` - the values have a simple structure of an initial offset and then a step size between values
26 -  `ISBLOCK` - values are an array of indices, each representing a block of values
27 
28    Level: beginner
29 
30 .seealso: `ISSetType()`, `IS`, `ISCreateGeneral()`, `ISCreateStride()`, `ISCreateBlock()`, `ISCreate()`, `ISRegister()`,
31           `VecScatterCreate()`, `MatGetSubMatrices()`
32 J*/
33 typedef const char *ISType;
34 #define ISGENERAL "general"
35 #define ISSTRIDE  "stride"
36 #define ISBLOCK   "block"
37 
38 /* Dynamic creation and loading functions */
39 PETSC_EXTERN PetscFunctionList ISList;
40 PETSC_EXTERN PetscErrorCode    ISSetType(IS, ISType);
41 PETSC_EXTERN PetscErrorCode    ISGetType(IS, ISType *);
42 PETSC_EXTERN PetscErrorCode    ISRegister(const char[], PetscErrorCode (*)(IS));
43 PETSC_EXTERN PetscErrorCode    ISRegisterAll(void);
44 PETSC_EXTERN PetscErrorCode    ISCreate(MPI_Comm, IS *);
45 
46 PETSC_EXTERN PetscErrorCode ISDestroy(IS *);
47 PETSC_EXTERN PetscErrorCode ISSetPermutation(IS);
48 PETSC_EXTERN PetscErrorCode ISPermutation(IS, PetscBool *);
49 PETSC_EXTERN PetscErrorCode ISSetIdentity(IS);
50 PETSC_EXTERN PetscErrorCode ISIdentity(IS, PetscBool *);
51 PETSC_EXTERN PetscErrorCode ISContiguousLocal(IS, PetscInt, PetscInt, PetscInt *, PetscBool *);
52 
53 /*E
54     ISInfo - Info that may either be computed or set as known for an index set
55 
56     Level: intermediate
57 
58    Developer Notes:
59    Entries that are negative need not be called collectively by all processes.
60 
61    Any additions/changes here MUST also be made in include/petsc/finclude/petscis.h
62 
63    Any additions/changes here must also be made in src/vec/vec/interface/dlregisvec.c in ISInfos[]
64 
65 .seealso: `IS`, `ISType`, `ISSetInfo()`
66 E*/
67 typedef enum {
68   IS_INFO_MIN    = -1,
69   IS_SORTED      = 0,
70   IS_UNIQUE      = 1,
71   IS_PERMUTATION = 2,
72   IS_INTERVAL    = 3,
73   IS_IDENTITY    = 4,
74   IS_INFO_MAX    = 5
75 } ISInfo;
76 
77 typedef enum {
78   IS_LOCAL,
79   IS_GLOBAL
80 } ISInfoType;
81 
82 PETSC_EXTERN PetscErrorCode ISSetInfo(IS, ISInfo, ISInfoType, PetscBool, PetscBool);
83 PETSC_EXTERN PetscErrorCode ISGetInfo(IS, ISInfo, ISInfoType, PetscBool, PetscBool *);
84 PETSC_EXTERN PetscErrorCode ISClearInfoCache(IS, PetscBool);
85 PETSC_EXTERN PetscErrorCode ISGetIndices(IS, const PetscInt *[]);
86 PETSC_EXTERN PetscErrorCode ISRestoreIndices(IS, const PetscInt *[]);
87 PETSC_EXTERN PetscErrorCode ISGetTotalIndices(IS, const PetscInt *[]);
88 PETSC_EXTERN PetscErrorCode ISRestoreTotalIndices(IS, const PetscInt *[]);
89 PETSC_EXTERN PetscErrorCode ISGetNonlocalIndices(IS, const PetscInt *[]);
90 PETSC_EXTERN PetscErrorCode ISRestoreNonlocalIndices(IS, const PetscInt *[]);
91 PETSC_EXTERN PetscErrorCode ISGetNonlocalIS(IS, IS *);
92 PETSC_EXTERN PetscErrorCode ISRestoreNonlocalIS(IS, IS *);
93 PETSC_EXTERN PetscErrorCode ISGetSize(IS, PetscInt *);
94 PETSC_EXTERN PetscErrorCode ISGetLocalSize(IS, PetscInt *);
95 PETSC_EXTERN PetscErrorCode ISInvertPermutation(IS, PetscInt, IS *);
96 PETSC_EXTERN PetscErrorCode ISView(IS, PetscViewer);
97 PETSC_EXTERN PetscErrorCode ISViewFromOptions(IS, PetscObject, const char[]);
98 PETSC_EXTERN PetscErrorCode ISLoad(IS, PetscViewer);
99 PETSC_EXTERN PetscErrorCode ISEqual(IS, IS, PetscBool *);
100 PETSC_EXTERN PetscErrorCode ISEqualUnsorted(IS, IS, PetscBool *);
101 PETSC_EXTERN PetscErrorCode ISSort(IS);
102 PETSC_EXTERN PetscErrorCode ISSortRemoveDups(IS);
103 PETSC_EXTERN PetscErrorCode ISSorted(IS, PetscBool *);
104 PETSC_EXTERN PetscErrorCode ISDifference(IS, IS, IS *);
105 PETSC_EXTERN PetscErrorCode ISSum(IS, IS, IS *);
106 PETSC_EXTERN PetscErrorCode ISExpand(IS, IS, IS *);
107 PETSC_EXTERN PetscErrorCode ISIntersect(IS, IS, IS *);
108 PETSC_EXTERN PetscErrorCode ISGetMinMax(IS, PetscInt *, PetscInt *);
109 
110 PETSC_EXTERN PetscErrorCode ISLocate(IS, PetscInt, PetscInt *);
111 PETSC_EXTERN PetscErrorCode ISGetPointRange(IS, PetscInt *, PetscInt *, const PetscInt **);
112 PETSC_EXTERN PetscErrorCode ISRestorePointRange(IS, PetscInt *, PetscInt *, const PetscInt **);
113 PETSC_EXTERN PetscErrorCode ISGetPointSubrange(IS, PetscInt, PetscInt, const PetscInt *);
114 
115 PETSC_EXTERN PetscErrorCode ISGetBlockSize(IS, PetscInt *);
116 PETSC_EXTERN PetscErrorCode ISSetBlockSize(IS, PetscInt);
117 
118 PETSC_EXTERN PetscErrorCode ISToGeneral(IS);
119 
120 PETSC_EXTERN PetscErrorCode ISDuplicate(IS, IS *);
121 PETSC_EXTERN PetscErrorCode ISCopy(IS, IS);
122 PETSC_EXTERN PetscErrorCode ISShift(IS, PetscInt, IS);
123 PETSC_EXTERN PetscErrorCode ISAllGather(IS, IS *);
124 PETSC_EXTERN PetscErrorCode ISComplement(IS, PetscInt, PetscInt, IS *);
125 PETSC_EXTERN PetscErrorCode ISConcatenate(MPI_Comm, PetscInt, const IS[], IS *);
126 PETSC_EXTERN PetscErrorCode ISListToPair(MPI_Comm, PetscInt, IS[], IS *, IS *);
127 PETSC_EXTERN PetscErrorCode ISPairToList(IS, IS, PetscInt *, IS *[]);
128 PETSC_EXTERN PetscErrorCode ISEmbed(IS, IS, PetscBool, IS *);
129 PETSC_EXTERN PetscErrorCode ISSortPermutation(IS, PetscBool, IS *);
130 PETSC_EXTERN PetscErrorCode ISOnComm(IS, MPI_Comm, PetscCopyMode, IS *);
131 PETSC_EXTERN PetscErrorCode ISRenumber(IS, IS, PetscInt *, IS *);
132 PETSC_EXTERN PetscErrorCode ISCreateSubIS(IS, IS, IS *);
133 
134 /* ISGENERAL specific */
135 PETSC_EXTERN PetscErrorCode ISCreateGeneral(MPI_Comm, PetscInt, const PetscInt[], PetscCopyMode, IS *);
136 PETSC_EXTERN PetscErrorCode ISGeneralSetIndices(IS, PetscInt, const PetscInt[], PetscCopyMode);
137 PETSC_EXTERN PetscErrorCode ISGeneralSetIndicesFromMask(IS, PetscInt, PetscInt, const PetscBool[]);
138 PETSC_EXTERN PetscErrorCode ISGeneralFilter(IS, PetscInt, PetscInt);
139 
140 /* ISBLOCK specific */
141 PETSC_EXTERN PetscErrorCode ISCreateBlock(MPI_Comm, PetscInt, PetscInt, const PetscInt[], PetscCopyMode, IS *);
142 PETSC_EXTERN PetscErrorCode ISBlockSetIndices(IS, PetscInt, PetscInt, const PetscInt[], PetscCopyMode);
143 PETSC_EXTERN PetscErrorCode ISBlockGetIndices(IS, const PetscInt *[]);
144 PETSC_EXTERN PetscErrorCode ISBlockRestoreIndices(IS, const PetscInt *[]);
145 PETSC_EXTERN PetscErrorCode ISBlockGetLocalSize(IS, PetscInt *);
146 PETSC_EXTERN PetscErrorCode ISBlockGetSize(IS, PetscInt *);
147 
148 /* ISSTRIDE specific */
149 PETSC_EXTERN PetscErrorCode ISCreateStride(MPI_Comm, PetscInt, PetscInt, PetscInt, IS *);
150 PETSC_EXTERN PetscErrorCode ISStrideSetStride(IS, PetscInt, PetscInt, PetscInt);
151 PETSC_EXTERN PetscErrorCode ISStrideGetInfo(IS, PetscInt *, PetscInt *);
152 
153 PETSC_EXTERN PetscClassId IS_LTOGM_CLASSID;
154 
155 /*E
156     ISGlobalToLocalMappingMode - Indicates mapping behavior if global indices are missing
157 
158    Values:
159 +   `IS_GTOLM_MASK` - missing global indices are masked by mapping them to a local index of -1
160 -   `IS_GTOLM_DROP` - missing global indices are dropped
161 
162    Level: beginner
163 
164 .seealso: `ISGlobalToLocalMappingApplyBlock()`, `ISGlobalToLocalMappingApply()`
165 E*/
166 typedef enum {
167   IS_GTOLM_MASK,
168   IS_GTOLM_DROP
169 } ISGlobalToLocalMappingMode;
170 
171 /*J
172     ISLocalToGlobalMappingType - String with the name of a mapping method
173 
174    Values:
175 +  `ISLOCALTOGLOBALMAPPINGBASIC` - a non-memory scalable way of storing `ISLocalToGlobalMapping` that allows applying `ISGlobalToLocalMappingApply()` efficiently
176 -  `ISLOCALTOGLOBALMAPPINGHASH` - a memory scalable way of storing `ISLocalToGlobalMapping` that allows applying `ISGlobalToLocalMappingApply()` reasonably efficiently
177 
178   Level: beginner
179 
180 .seealso: `ISLocalToGlobalMapping`, `ISLocalToGlobalMappingSetType()`, `ISLocalToGlobalSetFromOptions()`, `ISGlobalToLocalMappingMode`
181 J*/
182 typedef const char *ISLocalToGlobalMappingType;
183 #define ISLOCALTOGLOBALMAPPINGBASIC "basic"
184 #define ISLOCALTOGLOBALMAPPINGHASH  "hash"
185 
186 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingSetType(ISLocalToGlobalMapping, ISLocalToGlobalMappingType);
187 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetType(ISLocalToGlobalMapping, ISLocalToGlobalMappingType *);
188 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRegister(const char[], PetscErrorCode (*)(ISLocalToGlobalMapping));
189 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRegisterAll(void);
190 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm, PetscInt, PetscInt, const PetscInt[], PetscCopyMode, ISLocalToGlobalMapping *);
191 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreateIS(IS, ISLocalToGlobalMapping *);
192 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF, PetscInt, ISLocalToGlobalMapping *);
193 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingSetFromOptions(ISLocalToGlobalMapping);
194 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingSetUp(ISLocalToGlobalMapping);
195 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingView(ISLocalToGlobalMapping, PetscViewer);
196 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingViewFromOptions(ISLocalToGlobalMapping, PetscObject, const char[]);
197 
198 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingDestroy(ISLocalToGlobalMapping *);
199 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingApply(ISLocalToGlobalMapping, PetscInt, const PetscInt[], PetscInt[]);
200 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingApplyBlock(ISLocalToGlobalMapping, PetscInt, const PetscInt[], PetscInt[]);
201 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingApplyIS(ISLocalToGlobalMapping, IS, IS *);
202 PETSC_EXTERN PetscErrorCode ISGlobalToLocalMappingApply(ISLocalToGlobalMapping, ISGlobalToLocalMappingMode, PetscInt, const PetscInt[], PetscInt *, PetscInt[]);
203 PETSC_EXTERN PetscErrorCode ISGlobalToLocalMappingApplyBlock(ISLocalToGlobalMapping, ISGlobalToLocalMappingMode, PetscInt, const PetscInt[], PetscInt *, PetscInt[]);
204 PETSC_EXTERN PetscErrorCode ISGlobalToLocalMappingApplyIS(ISLocalToGlobalMapping, ISGlobalToLocalMappingMode, IS, IS *);
205 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetSize(ISLocalToGlobalMapping, PetscInt *);
206 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetNodeInfo(ISLocalToGlobalMapping, PetscInt *, PetscInt *[], PetscInt **[]);
207 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRestoreNodeInfo(ISLocalToGlobalMapping, PetscInt *, PetscInt *[], PetscInt **[]);
208 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetInfo(ISLocalToGlobalMapping, PetscInt *, PetscInt *[], PetscInt *[], PetscInt **[]);
209 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRestoreInfo(ISLocalToGlobalMapping, PetscInt *, PetscInt *[], PetscInt *[], PetscInt **[]);
210 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(ISLocalToGlobalMapping, PetscInt *, PetscInt *[], PetscInt *[], PetscInt **[]);
211 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(ISLocalToGlobalMapping, PetscInt *, PetscInt *[], PetscInt *[], PetscInt **[]);
212 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetIndices(ISLocalToGlobalMapping, const PetscInt **);
213 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRestoreIndices(ISLocalToGlobalMapping, const PetscInt **);
214 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(ISLocalToGlobalMapping, const PetscInt **);
215 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(ISLocalToGlobalMapping, const PetscInt **);
216 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingConcatenate(MPI_Comm, PetscInt, const ISLocalToGlobalMapping[], ISLocalToGlobalMapping *);
217 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingGetBlockSize(ISLocalToGlobalMapping, PetscInt *);
218 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingSetBlockSize(ISLocalToGlobalMapping, PetscInt);
219 PETSC_EXTERN PetscErrorCode ISLocalToGlobalMappingDuplicate(ISLocalToGlobalMapping, ISLocalToGlobalMapping *);
220 
221 /*E
222     ISColoringType - determines if the coloring is for the entire parallel grid/graph/matrix
223                      or for just the local ghosted portion
224 
225     Values:
226 +   `IS_COLORING_GLOBAL` - does not include the colors for ghost points, this is used when the function
227                         is called synchronously in parallel. This requires generating a "parallel coloring".
228 -   `IS_COLORING_LOCAL` - includes colors for ghost points, this is used when the function can be called
229                          separately on individual processes with the ghost points already filled in. Does not
230                          require a "parallel coloring", rather each process colors its local + ghost part.
231                          Using this can result in much less parallel communication. Currently only works
232                          with `DMDA` and if you call `MatFDColoringSetFunction()` with the local function.
233 
234    Level: beginner
235 
236 .seealso: `ISColoring`, `ISColoringSetType()`, `ISColoringGetType()`, `DMCreateColoring()`
237 E*/
238 typedef enum {
239   IS_COLORING_GLOBAL,
240   IS_COLORING_LOCAL
241 } ISColoringType;
242 PETSC_EXTERN const char *const                ISColoringTypes[];
243 typedef unsigned PETSC_IS_COLORING_VALUE_TYPE ISColoringValue;
244 #define IS_COLORING_MAX     PETSC_IS_COLORING_MAX
245 #define MPIU_COLORING_VALUE PETSC_MPIU_IS_COLORING_VALUE_TYPE
246 PETSC_EXTERN PetscErrorCode ISAllGatherColors(MPI_Comm, PetscInt, ISColoringValue *, PetscInt *, ISColoringValue *[]);
247 
248 PETSC_EXTERN PetscErrorCode ISColoringCreate(MPI_Comm, PetscInt, PetscInt, const ISColoringValue[], PetscCopyMode, ISColoring *);
249 PETSC_EXTERN PetscErrorCode ISColoringDestroy(ISColoring *);
250 PETSC_EXTERN PetscErrorCode ISColoringView(ISColoring, PetscViewer);
251 PETSC_EXTERN PetscErrorCode ISColoringViewFromOptions(ISColoring, PetscObject, const char[]);
252 PETSC_EXTERN PetscErrorCode ISColoringGetIS(ISColoring, PetscCopyMode, PetscInt *, IS *[]);
253 PETSC_EXTERN PetscErrorCode ISColoringRestoreIS(ISColoring, PetscCopyMode, IS *[]);
254 PETSC_EXTERN PetscErrorCode ISColoringReference(ISColoring);
255 PETSC_EXTERN PetscErrorCode ISColoringSetType(ISColoring, ISColoringType);
256 PETSC_EXTERN PetscErrorCode ISColoringGetType(ISColoring, ISColoringType *);
257 PETSC_EXTERN PetscErrorCode ISColoringGetColors(ISColoring, PetscInt *, PetscInt *, const ISColoringValue **);
258 
259 PETSC_EXTERN PetscErrorCode ISBuildTwoSided(IS, IS, IS *);
260 PETSC_EXTERN PetscErrorCode ISPartitioningToNumbering(IS, IS *);
261 PETSC_EXTERN PetscErrorCode ISPartitioningCount(IS, PetscInt, PetscInt[]);
262 
263 PETSC_EXTERN PetscErrorCode ISCompressIndicesGeneral(PetscInt, PetscInt, PetscInt, PetscInt, const IS[], IS[]);
264 PETSC_DEPRECATED_FUNCTION(3, 19, 0, "ISCompressIndicesGeneral()", ) static inline PetscErrorCode ISCompressIndicesSorted(PetscInt n, PetscInt bs, PetscInt imax, const IS is_in[], IS is_out[])
265 {
266   return ISCompressIndicesGeneral(n, bs, n, imax, is_in, is_out);
267 }
268 PETSC_EXTERN PetscErrorCode ISExpandIndicesGeneral(PetscInt, PetscInt, PetscInt, PetscInt, const IS[], IS[]);
269 
270 struct _n_PetscLayout {
271   MPI_Comm               comm;
272   PetscMPIInt            size;
273   PetscInt               n, N;         /* local, global vector size */
274   PetscInt               rstart, rend; /* local start, local end + 1 */
275   PetscInt              *range;        /* the offset of each processor */
276   PetscBool              range_alloc;  /* should range be freed in Destroy? */
277   PetscInt               bs;           /* number of elements in each block (generally for multi-component
278                                        * problems). Defaults to -1 and can be arbitrarily lazy so always use
279                                        * PetscAbs(map->bs) when accessing directly and expecting result to be
280                                        * positive. Do NOT multiply above numbers by bs */
281   PetscInt               refcnt;       /* MPI Vecs obtained with VecDuplicate() and from MatCreateVecs() reuse map of input object */
282   ISLocalToGlobalMapping mapping;      /* mapping used in Vec/MatSetValuesLocal() */
283   PetscBool              setupcalled;  /* Forbid setup more than once */
284   PetscInt               oldn, oldN;   /* Checking if setup is allowed */
285   PetscInt               oldbs;        /* And again */
286 };
287 
288 /*@C
289      PetscLayoutFindOwner - Find the owning rank for a global index
290 
291     Not Collective; No Fortran Support
292 
293    Input Parameters:
294 +    map - the layout
295 -    idx - global index to find the owner of
296 
297    Output Parameter:
298 .    owner - the owning rank
299 
300    Level: developer
301 
302 .seealso: `PetscLayout`, `PetscLayoutFindOwnerIndex()`
303 @*/
304 static inline PetscErrorCode PetscLayoutFindOwner(PetscLayout map, PetscInt idx, PetscMPIInt *owner)
305 {
306   PetscMPIInt lo = 0, hi, t;
307 
308   PetscFunctionBegin;
309   *owner = -1; /* GCC erroneously issues warning about possibly uninitialized use when error condition */
310 #if defined(PETSC_USE_DEBUG)
311   PetscCheck((map->n >= 0) && (map->N >= 0) && (map->range), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscLayoutSetUp() must be called first");
312   PetscCheck(idx >= 0 && idx <= map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is out of range", idx);
313 #endif
314   hi = map->size;
315   while (hi - lo > 1) {
316     t = lo + (hi - lo) / 2;
317     if (idx < map->range[t]) hi = t;
318     else lo = t;
319   }
320   *owner = lo;
321   PetscFunctionReturn(PETSC_SUCCESS);
322 }
323 
324 /*@C
325      PetscLayoutFindOwnerIndex - Find the owning MPI rank and the local index on that rank for a global index
326 
327     Not Collective; No Fortran Support
328 
329    Input Parameters:
330 +    map   - the layout
331 -    idx   - global index to find the owner of
332 
333    Output Parameters:
334 +    owner - the owning rank
335 -    lidx  - local index used by the owner for `idx`
336 
337    Level: developer
338 
339 .seealso: `PetscLayout`, `PetscLayoutFindOwner()`
340 @*/
341 static inline PetscErrorCode PetscLayoutFindOwnerIndex(PetscLayout map, PetscInt idx, PetscMPIInt *owner, PetscInt *lidx)
342 {
343   PetscMPIInt lo = 0, hi, t;
344 
345   PetscFunctionBegin;
346 #if defined(PETSC_USE_DEBUG)
347   PetscCheck((map->n >= 0) && (map->N >= 0) && (map->range), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscLayoutSetUp() must be called first");
348   PetscCheck(idx >= 0 && idx <= map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is out of range", idx);
349 #endif
350   hi = map->size;
351   while (hi - lo > 1) {
352     t = lo + (hi - lo) / 2;
353     if (idx < map->range[t]) hi = t;
354     else lo = t;
355   }
356   if (owner) *owner = lo;
357   if (lidx) *lidx = idx - map->range[lo];
358   PetscFunctionReturn(PETSC_SUCCESS);
359 }
360 
361 PETSC_EXTERN PetscErrorCode PetscLayoutCreate(MPI_Comm, PetscLayout *);
362 PETSC_EXTERN PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscLayout *);
363 PETSC_EXTERN PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm, const PetscInt[], PetscCopyMode, PetscInt, PetscLayout *);
364 PETSC_EXTERN PetscErrorCode PetscLayoutSetUp(PetscLayout);
365 PETSC_EXTERN PetscErrorCode PetscLayoutDestroy(PetscLayout *);
366 PETSC_EXTERN PetscErrorCode PetscLayoutDuplicate(PetscLayout, PetscLayout *);
367 PETSC_EXTERN PetscErrorCode PetscLayoutReference(PetscLayout, PetscLayout *);
368 PETSC_EXTERN PetscErrorCode PetscLayoutSetLocalSize(PetscLayout, PetscInt);
369 PETSC_EXTERN PetscErrorCode PetscLayoutGetLocalSize(PetscLayout, PetscInt *);
370 PETSC_EXTERN PetscErrorCode PetscLayoutSetSize(PetscLayout, PetscInt);
371 PETSC_EXTERN PetscErrorCode PetscLayoutGetSize(PetscLayout, PetscInt *);
372 PETSC_EXTERN PetscErrorCode PetscLayoutSetBlockSize(PetscLayout, PetscInt);
373 PETSC_EXTERN PetscErrorCode PetscLayoutGetBlockSize(PetscLayout, PetscInt *);
374 PETSC_EXTERN PetscErrorCode PetscLayoutGetRange(PetscLayout, PetscInt *, PetscInt *);
375 PETSC_EXTERN PetscErrorCode PetscLayoutGetRanges(PetscLayout, const PetscInt *[]);
376 PETSC_EXTERN PetscErrorCode PetscLayoutCompare(PetscLayout, PetscLayout, PetscBool *);
377 PETSC_EXTERN PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout, ISLocalToGlobalMapping);
378 PETSC_EXTERN PetscErrorCode PetscLayoutMapLocal(PetscLayout, PetscInt, const PetscInt[], PetscInt *, PetscInt **, PetscInt **);
379 
380 PETSC_EXTERN PetscErrorCode PetscParallelSortInt(PetscLayout, PetscLayout, PetscInt *, PetscInt *);
381 
382 PETSC_EXTERN PetscErrorCode ISGetLayout(IS, PetscLayout *);
383 PETSC_EXTERN PetscErrorCode ISSetLayout(IS, PetscLayout);
384