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