xref: /petsc/src/vec/is/utils/pmap.c (revision 8fa9e22e65c6f47173f479ecf868ef7fe40cdcbd)
1 
2 /*
3    This file contains routines for basic map object implementation.
4 */
5 
6 #include <petscis.h> /*I "petscis.h" I*/
7 #include <petsc/private/isimpl.h>
8 
9 /*@
10   PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default.
11 
12   Collective
13 
14   Input Parameters:
15 . comm - the MPI communicator
16 
17   Output Parameters:
18 . map - the new PetscLayout
19 
20   Level: advanced
21 
22   Notes:
23   Typical calling sequence
24 .vb
25        PetscLayoutCreate(MPI_Comm,PetscLayout *);
26        PetscLayoutSetBlockSize(PetscLayout,bs);
27        PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n);
28        PetscLayoutSetUp(PetscLayout);
29 .ve
30   Alternatively,
31 $      PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
32 
33   Optionally use any of the following:
34 
35 + PetscLayoutGetSize(PetscLayout,PetscInt *);
36 . PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
37 . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
38 . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
39 - PetscLayoutDestroy(PetscLayout*);
40 
41   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
42   user codes unless you really gain something in their use.
43 
44 .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
45           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(),
46           PetscLayoutCreateFromSizes()
47 
48 @*/
49 PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
50 {
51   PetscErrorCode ierr;
52 
53   PetscFunctionBegin;
54   ierr = PetscNew(map);CHKERRQ(ierr);
55   ierr = MPI_Comm_size(comm, &(*map)->size);CHKERRQ(ierr);
56   (*map)->comm        = comm;
57   (*map)->bs          = -1;
58   (*map)->n           = -1;
59   (*map)->N           = -1;
60   (*map)->range       = NULL;
61   (*map)->range_alloc = PETSC_TRUE;
62   (*map)->rstart      = 0;
63   (*map)->rend        = 0;
64   (*map)->setupcalled = PETSC_FALSE;
65   (*map)->oldn        = -1;
66   (*map)->oldN        = -1;
67   (*map)->oldbs       = -1;
68   PetscFunctionReturn(0);
69 }
70 
71 /*@
72   PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up.
73 
74   Collective
75 
76   Input Parameters:
77 + comm  - the MPI communicator
78 . n     - the local size (or PETSC_DECIDE)
79 . N     - the global size (or PETSC_DECIDE)
80 - bs    - the block size (or PETSC_DECIDE)
81 
82   Output Parameters:
83 . map - the new PetscLayout
84 
85   Level: advanced
86 
87   Notes:
88 $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
89   is a shorthand for
90 .vb
91   PetscLayoutCreate(comm,&layout);
92   PetscLayoutSetLocalSize(layout,n);
93   PetscLayoutSetSize(layout,N);
94   PetscLayoutSetBlockSize(layout,bs);
95   PetscLayoutSetUp(layout);
96 .ve
97 
98 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
99           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromRanges()
100 
101 @*/
102 PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt bs,PetscLayout *map)
103 {
104   PetscErrorCode ierr;
105 
106   PetscFunctionBegin;
107   ierr = PetscLayoutCreate(comm, map);CHKERRQ(ierr);
108   ierr = PetscLayoutSetLocalSize(*map, n);CHKERRQ(ierr);
109   ierr = PetscLayoutSetSize(*map, N);CHKERRQ(ierr);
110   ierr = PetscLayoutSetBlockSize(*map, bs);CHKERRQ(ierr);
111   ierr = PetscLayoutSetUp(*map);CHKERRQ(ierr);
112   PetscFunctionReturn(0);
113 }
114 
115 /*@
116   PetscLayoutDestroy - Frees a map object and frees its range if that exists.
117 
118   Collective
119 
120   Input Parameters:
121 . map - the PetscLayout
122 
123   Level: developer
124 
125   Note:
126   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
127   recommended they not be used in user codes unless you really gain something in their use.
128 
129 .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
130           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
131 
132 @*/
133 PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
134 {
135   PetscErrorCode ierr;
136 
137   PetscFunctionBegin;
138   if (!*map) PetscFunctionReturn(0);
139   if (!(*map)->refcnt--) {
140     if ((*map)->range_alloc) {ierr = PetscFree((*map)->range);CHKERRQ(ierr);}
141     ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr);
142     ierr = PetscFree((*map));CHKERRQ(ierr);
143   }
144   *map = NULL;
145   PetscFunctionReturn(0);
146 }
147 
148 /*@
149   PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up.
150 
151   Collective
152 
153   Input Parameters:
154 + comm  - the MPI communicator
155 . range - the array of ownership ranges for each rank with length commsize+1
156 . mode  - the copy mode for range
157 - bs    - the block size (or PETSC_DECIDE)
158 
159   Output Parameters:
160 . newmap - the new PetscLayout
161 
162   Level: developer
163 
164 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
165           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromSizes()
166 
167 @*/
168 PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm,const PetscInt range[],PetscCopyMode mode,PetscInt bs,PetscLayout *newmap)
169 {
170   PetscLayout    map;
171   PetscMPIInt    rank;
172   PetscErrorCode ierr;
173 
174   PetscFunctionBegin;
175   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
176   ierr = PetscLayoutCreate(comm, &map);CHKERRQ(ierr);
177   ierr = PetscLayoutSetBlockSize(map, bs);CHKERRQ(ierr);
178   switch (mode) {
179     case PETSC_COPY_VALUES:
180       ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
181       ierr = PetscArraycpy(map->range, range, map->size+1);CHKERRQ(ierr);
182       break;
183     case PETSC_USE_POINTER:
184       map->range_alloc = PETSC_FALSE;
185     default:
186       map->range = (PetscInt*) range;
187       break;
188   }
189   map->rstart = map->range[rank];
190   map->rend   = map->range[rank+1];
191   map->n      = map->rend - map->rstart;
192   map->N      = map->range[map->size];
193   if (PetscDefined(USE_DEBUG)) {  /* just check that n, N and bs are consistent */
194     PetscInt tmp;
195     ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr);
196     if (tmp != map->N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local lengths %D does not equal global length %D, my local length %D.\nThe provided PetscLayout is wrong.",tmp,map->N,map->n);
197     if (map->bs > 1) {
198       if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %D must be divisible by blocksize %D",map->n,map->bs);
199     }
200     if (map->bs > 1) {
201       if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global size %D must be divisible by blocksize %D",map->N,map->bs);
202     }
203   }
204   /* lock the layout */
205   map->setupcalled = PETSC_TRUE;
206   map->oldn = map->n;
207   map->oldN = map->N;
208   map->oldbs = map->bs;
209   *newmap = map;
210   PetscFunctionReturn(0);
211 }
212 
213 /*@
214   PetscLayoutSetUp - given a map where you have set either the global or local
215                      size sets up the map so that it may be used.
216 
217   Collective
218 
219   Input Parameters:
220 . map - pointer to the map
221 
222   Level: developer
223 
224   Notes:
225     Typical calling sequence
226 $ PetscLayoutCreate(MPI_Comm,PetscLayout *);
227 $ PetscLayoutSetBlockSize(PetscLayout,1);
228 $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
229 $ PetscLayoutSetUp(PetscLayout);
230 $ PetscLayoutGetSize(PetscLayout,PetscInt *);
231 
232   If range exists, and local size is not set, everything gets computed from the range.
233 
234   If the local size, global size are already set and range exists then this does nothing.
235 
236 .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
237           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
238 @*/
239 PetscErrorCode PetscLayoutSetUp(PetscLayout map)
240 {
241   PetscMPIInt    rank;
242   PetscInt       p;
243   PetscErrorCode ierr;
244 
245   PetscFunctionBegin;
246   if (map->setupcalled && (map->n != map->oldn || map->N != map->oldN)) SETERRQ4(map->comm,PETSC_ERR_ARG_WRONGSTATE,"Layout is already setup with (local=%D,global=%D), cannot call setup again with (local=%D,global=%D)", map->oldn, map->oldN, map->n, map->N);
247   if (map->setupcalled) PetscFunctionReturn(0);
248 
249   if (map->n > 0 && map->bs > 1) {
250     if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %D must be divisible by blocksize %D",map->n,map->bs);
251   }
252   if (map->N > 0 && map->bs > 1) {
253     if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global size %D must be divisible by blocksize %D",map->N,map->bs);
254   }
255 
256   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRMPI(ierr);
257   if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
258   if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
259   ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr);
260   map->n = map->n*PetscAbs(map->bs);
261   map->N = map->N*PetscAbs(map->bs);
262   if (!map->range) {
263     ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
264   }
265   ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRMPI(ierr);
266 
267   map->range[0] = 0;
268   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p-1];
269 
270   map->rstart = map->range[rank];
271   map->rend   = map->range[rank+1];
272 
273   /* lock the layout */
274   map->setupcalled = PETSC_TRUE;
275   map->oldn = map->n;
276   map->oldN = map->N;
277   map->oldbs = map->bs;
278   PetscFunctionReturn(0);
279 }
280 
281 /*@
282   PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
283 
284   Collective on PetscLayout
285 
286   Input Parameter:
287 . in - input PetscLayout to be duplicated
288 
289   Output Parameter:
290 . out - the copy
291 
292   Level: developer
293 
294   Notes:
295     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
296 
297 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
298 @*/
299 PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
300 {
301   PetscErrorCode ierr;
302   MPI_Comm       comm = in->comm;
303 
304   PetscFunctionBegin;
305   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
306   ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr);
307   ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr);
308   if (in->range) {
309     ierr = PetscMalloc1((*out)->size+1,&(*out)->range);CHKERRQ(ierr);
310     ierr = PetscArraycpy((*out)->range,in->range,(*out)->size+1);CHKERRQ(ierr);
311   }
312   (*out)->refcnt = 0;
313   PetscFunctionReturn(0);
314 }
315 
316 /*@
317   PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
318 
319   Collective on PetscLayout
320 
321   Input Parameter:
322 . in - input PetscLayout to be copied
323 
324   Output Parameter:
325 . out - the reference location
326 
327   Level: developer
328 
329   Notes:
330     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
331 
332   If the out location already contains a PetscLayout it is destroyed
333 
334 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
335 @*/
336 PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
337 {
338   PetscErrorCode ierr;
339 
340   PetscFunctionBegin;
341   in->refcnt++;
342   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
343   *out = in;
344   PetscFunctionReturn(0);
345 }
346 
347 /*@
348   PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
349 
350   Collective on PetscLayout
351 
352   Input Parameter:
353 + in - input PetscLayout
354 - ltog - the local to global mapping
355 
356 
357   Level: developer
358 
359   Notes:
360     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
361 
362   If the ltog location already contains a PetscLayout it is destroyed
363 
364 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
365 @*/
366 PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
367 {
368   PetscErrorCode ierr;
369   PetscInt       bs;
370 
371   PetscFunctionBegin;
372   ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr);
373   if (in->bs > 0 && (bs != 1) && in->bs != bs) SETERRQ2(in->comm,PETSC_ERR_PLIB,"Blocksize of layout %D must match that of mapping %D (or the latter must be 1)",in->bs,bs);
374   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
375   ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr);
376   in->mapping = ltog;
377   PetscFunctionReturn(0);
378 }
379 
380 /*@
381   PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
382 
383   Collective on PetscLayout
384 
385   Input Parameters:
386 + map - pointer to the map
387 - n - the local size
388 
389   Level: developer
390 
391   Notes:
392   Call this after the call to PetscLayoutCreate()
393 
394 .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
395           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
396 @*/
397 PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
398 {
399   PetscFunctionBegin;
400   if (map->bs > 1 && n % map->bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",n,map->bs);
401   map->n = n;
402   PetscFunctionReturn(0);
403 }
404 
405 /*@C
406      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
407 
408     Not Collective
409 
410    Input Parameters:
411 .    map - pointer to the map
412 
413    Output Parameters:
414 .    n - the local size
415 
416    Level: developer
417 
418     Notes:
419        Call this after the call to PetscLayoutSetUp()
420 
421     Fortran Notes:
422       Not available from Fortran
423 
424 .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
425           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
426 
427 @*/
428 PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
429 {
430   PetscFunctionBegin;
431   *n = map->n;
432   PetscFunctionReturn(0);
433 }
434 
435 /*@
436   PetscLayoutSetSize - Sets the global size for a PetscLayout object.
437 
438   Logically Collective on PetscLayout
439 
440   Input Parameters:
441 + map - pointer to the map
442 - n - the global size
443 
444   Level: developer
445 
446   Notes:
447   Call this after the call to PetscLayoutCreate()
448 
449 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
450           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
451 @*/
452 PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
453 {
454   PetscFunctionBegin;
455   map->N = n;
456   PetscFunctionReturn(0);
457 }
458 
459 /*@
460   PetscLayoutGetSize - Gets the global size for a PetscLayout object.
461 
462   Not Collective
463 
464   Input Parameters:
465 . map - pointer to the map
466 
467   Output Parameters:
468 . n - the global size
469 
470   Level: developer
471 
472   Notes:
473   Call this after the call to PetscLayoutSetUp()
474 
475 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
476           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
477 @*/
478 PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
479 {
480   PetscFunctionBegin;
481   *n = map->N;
482   PetscFunctionReturn(0);
483 }
484 
485 /*@
486   PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
487 
488   Logically Collective on PetscLayout
489 
490   Input Parameters:
491 + map - pointer to the map
492 - bs - the size
493 
494   Level: developer
495 
496   Notes:
497   Call this after the call to PetscLayoutCreate()
498 
499 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
500           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
501 @*/
502 PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
503 {
504   PetscFunctionBegin;
505   if (bs < 0) PetscFunctionReturn(0);
506   if (map->n > 0 && map->n % bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",map->n,bs);
507   if (map->mapping) {
508     PetscInt       obs;
509     PetscErrorCode ierr;
510 
511     ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr);
512     if (obs > 1) {
513       ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr);
514     }
515   }
516   map->bs = bs;
517   PetscFunctionReturn(0);
518 }
519 
520 /*@
521   PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
522 
523   Not Collective
524 
525   Input Parameters:
526 . map - pointer to the map
527 
528   Output Parameters:
529 . bs - the size
530 
531   Level: developer
532 
533   Notes:
534   Call this after the call to PetscLayoutSetUp()
535 
536 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
537           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
538 @*/
539 PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
540 {
541   PetscFunctionBegin;
542   *bs = PetscAbs(map->bs);
543   PetscFunctionReturn(0);
544 }
545 
546 /*@
547   PetscLayoutGetRange - gets the range of values owned by this process
548 
549   Not Collective
550 
551   Input Parameters:
552 . map - pointer to the map
553 
554   Output Parameters:
555 + rstart - first index owned by this process
556 - rend   - one more than the last index owned by this process
557 
558   Level: developer
559 
560   Notes:
561   Call this after the call to PetscLayoutSetUp()
562 
563 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
564           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
565 @*/
566 PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
567 {
568   PetscFunctionBegin;
569   if (rstart) *rstart = map->rstart;
570   if (rend)   *rend   = map->rend;
571   PetscFunctionReturn(0);
572 }
573 
574 /*@C
575      PetscLayoutGetRanges - gets the range of values owned by all processes
576 
577     Not Collective
578 
579    Input Parameters:
580 .    map - pointer to the map
581 
582    Output Parameters:
583 .    range - start of each processors range of indices (the final entry is one more then the
584              last index on the last process)
585 
586    Level: developer
587 
588     Notes:
589        Call this after the call to PetscLayoutSetUp()
590 
591     Fortran Notes:
592       Not available from Fortran
593 
594 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
595           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
596 
597 @*/
598 PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
599 {
600   PetscFunctionBegin;
601   *range = map->range;
602   PetscFunctionReturn(0);
603 }
604 
605 /*@
606   PetscLayoutCompare - Compares two layouts
607 
608   Not Collective
609 
610   Input Parameters:
611 + mapa - pointer to the first map
612 - mapb - pointer to the second map
613 
614   Output Parameters:
615 . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise
616 
617   Level: beginner
618 
619   Notes:
620 
621 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
622           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
623 @*/
624 PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent)
625 {
626   PetscErrorCode ierr;
627 
628   PetscFunctionBegin;
629   *congruent = PETSC_FALSE;
630   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) {
631     ierr = PetscArraycmp(mapa->range,mapb->range,mapa->size+1,congruent);CHKERRQ(ierr);
632   }
633   PetscFunctionReturn(0);
634 }
635 
636