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