Actual source code: pmap.c
2: /*
3: This file contains routines for basic map object implementation.
4: */
6: #include <petsc/private/isimpl.h>
8: /*@
9: PetscLayoutCreate - Allocates `PetscLayout` object
11: Collective
13: Input Parameter:
14: . comm - the MPI communicator
16: Output Parameter:
17: . map - the new `PetscLayout`
19: Level: advanced
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
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
43: The `PetscLayout` object and methods are intended to be used in the PETSc `Vec` and `Mat` implementations; it is often not needed in
44: user codes unless you really gain something in their use.
46: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
47: `PetscLayout`, `PetscLayoutDestroy()`,
48: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`,
49: `PetscLayoutCreateFromSizes()`
50: @*/
51: PetscErrorCode PetscLayoutCreate(MPI_Comm comm, PetscLayout *map)
52: {
53: PetscFunctionBegin;
54: PetscCall(PetscNew(map));
55: PetscCallMPI(MPI_Comm_size(comm, &(*map)->size));
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(PETSC_SUCCESS);
69: }
71: /*@
72: PetscLayoutCreateFromSizes - Allocates `PetscLayout` object and sets the layout sizes, and sets the layout up.
74: Collective
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`)
82: Output Parameter:
83: . map - the new `PetscLayout`
85: Level: advanced
87: Note:
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
98: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
99: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()`
100: @*/
101: PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map)
102: {
103: PetscFunctionBegin;
104: PetscCall(PetscLayoutCreate(comm, map));
105: PetscCall(PetscLayoutSetLocalSize(*map, n));
106: PetscCall(PetscLayoutSetSize(*map, N));
107: PetscCall(PetscLayoutSetBlockSize(*map, bs));
108: PetscCall(PetscLayoutSetUp(*map));
109: PetscFunctionReturn(PETSC_SUCCESS);
110: }
112: /*@
113: PetscLayoutDestroy - Frees a `PetscLayout` object and frees its range if that exists.
115: Collective
117: Input Parameter:
118: . map - the `PetscLayout`
120: Level: developer
122: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
123: `PetscLayout`, `PetscLayoutCreate()`,
124: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`
125: @*/
126: PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
127: {
128: PetscFunctionBegin;
129: if (!*map) PetscFunctionReturn(PETSC_SUCCESS);
130: if (!(*map)->refcnt--) {
131: if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range));
132: PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping));
133: PetscCall(PetscFree((*map)));
134: }
135: *map = NULL;
136: PetscFunctionReturn(PETSC_SUCCESS);
137: }
139: /*@
140: PetscLayoutCreateFromRanges - Creates a new `PetscLayout` with the given ownership ranges and sets it up.
142: Collective
144: Input Parameters:
145: + comm - the MPI communicator
146: . range - the array of ownership ranges for each rank with length commsize+1
147: . mode - the copy mode for range
148: - bs - the block size (or `PETSC_DECIDE`)
150: Output Parameter:
151: . newmap - the new `PetscLayout`
153: Level: developer
155: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`,
156: `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
157: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()`
158: @*/
159: PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap)
160: {
161: PetscLayout map;
162: PetscMPIInt rank;
164: PetscFunctionBegin;
165: PetscCallMPI(MPI_Comm_rank(comm, &rank));
166: PetscCall(PetscLayoutCreate(comm, &map));
167: PetscCall(PetscLayoutSetBlockSize(map, bs));
168: switch (mode) {
169: case PETSC_COPY_VALUES:
170: PetscCall(PetscMalloc1(map->size + 1, &map->range));
171: PetscCall(PetscArraycpy(map->range, range, map->size + 1));
172: break;
173: case PETSC_USE_POINTER:
174: map->range_alloc = PETSC_FALSE;
175: break;
176: default:
177: map->range = (PetscInt *)range;
178: break;
179: }
180: map->rstart = map->range[rank];
181: map->rend = map->range[rank + 1];
182: map->n = map->rend - map->rstart;
183: map->N = map->range[map->size];
184: if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */
185: PetscInt tmp;
186: PetscCall(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm));
187: PetscCheck(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);
188: if (map->bs > 1) PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs);
189: if (map->bs > 1) PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs);
190: }
191: /* lock the layout */
192: map->setupcalled = PETSC_TRUE;
193: map->oldn = map->n;
194: map->oldN = map->N;
195: map->oldbs = map->bs;
196: *newmap = map;
197: PetscFunctionReturn(PETSC_SUCCESS);
198: }
200: /*@
201: PetscLayoutSetUp - given a map where you have set either the global or local
202: size sets up the map so that it may be used.
204: Collective
206: Input Parameter:
207: . map - pointer to the map
209: Level: developer
211: Notes:
212: Typical calling sequence
213: .vb
214: PetscLayoutCreate(MPI_Comm,PetscLayout *);
215: PetscLayoutSetBlockSize(PetscLayout,1);
216: PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
217: PetscLayoutSetUp(PetscLayout);
218: PetscLayoutGetSize(PetscLayout,PetscInt *);
219: .ve
221: If range exists, and local size is not set, everything gets computed from the range.
223: If the local size, global size are already set and range exists then this does nothing.
225: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
226: `PetscLayout`, `PetscLayoutDestroy()`,
227: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()`
228: @*/
229: PetscErrorCode PetscLayoutSetUp(PetscLayout map)
230: {
231: PetscMPIInt rank;
232: PetscInt p;
234: PetscFunctionBegin;
235: PetscCheck(!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 ")",
236: map->oldn, map->oldN, map->n, map->N);
237: if (map->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
239: if (map->n > 0 && map->bs > 1) PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs);
240: if (map->N > 0 && map->bs > 1) PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs);
242: PetscCallMPI(MPI_Comm_rank(map->comm, &rank));
243: if (map->n > 0) map->n = map->n / PetscAbs(map->bs);
244: if (map->N > 0) map->N = map->N / PetscAbs(map->bs);
245: PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N));
246: map->n = map->n * PetscAbs(map->bs);
247: map->N = map->N * PetscAbs(map->bs);
248: if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range));
249: PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm));
251: map->range[0] = 0;
252: for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1];
254: map->rstart = map->range[rank];
255: map->rend = map->range[rank + 1];
257: /* lock the layout */
258: map->setupcalled = PETSC_TRUE;
259: map->oldn = map->n;
260: map->oldN = map->N;
261: map->oldbs = map->bs;
262: PetscFunctionReturn(PETSC_SUCCESS);
263: }
265: /*@
266: PetscLayoutDuplicate - creates a new `PetscLayout` with the same information as a given one. If the `PetscLayout` already exists it is destroyed first.
268: Collective
270: Input Parameter:
271: . in - input `PetscLayout` to be duplicated
273: Output Parameter:
274: . out - the copy
276: Level: developer
278: Note:
279: `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
281: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()`
282: @*/
283: PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out)
284: {
285: MPI_Comm comm = in->comm;
287: PetscFunctionBegin;
288: PetscCall(PetscLayoutDestroy(out));
289: PetscCall(PetscLayoutCreate(comm, out));
290: PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout)));
291: if (in->range) {
292: PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range));
293: PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1));
294: }
295: (*out)->refcnt = 0;
296: PetscFunctionReturn(PETSC_SUCCESS);
297: }
299: /*@
300: PetscLayoutReference - Causes a PETSc `Vec` or `Mat` to share a `PetscLayout` with one that already exists.
302: Collective
304: Input Parameter:
305: . in - input `PetscLayout` to be copied
307: Output Parameter:
308: . out - the reference location
310: Level: developer
312: Notes:
313: `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
315: If the out location already contains a `PetscLayout` it is destroyed
317: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
318: @*/
319: PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out)
320: {
321: PetscFunctionBegin;
322: in->refcnt++;
323: PetscCall(PetscLayoutDestroy(out));
324: *out = in;
325: PetscFunctionReturn(PETSC_SUCCESS);
326: }
328: /*@
329: PetscLayoutSetISLocalToGlobalMapping - sets a `ISLocalGlobalMapping` into a `PetscLayout`
331: Collective
333: Input Parameters:
334: + in - input `PetscLayout`
335: - ltog - the local to global mapping
337: Level: developer
339: Notes:
340: `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
342: If the `PetscLayout` already contains a `ISLocalGlobalMapping` it is destroyed
344: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
345: @*/
346: PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog)
347: {
348: PetscFunctionBegin;
349: if (ltog) {
350: PetscInt bs;
352: PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs));
353: PetscCheck(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);
354: PetscCall(PetscObjectReference((PetscObject)ltog));
355: }
356: PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping));
357: in->mapping = ltog;
358: PetscFunctionReturn(PETSC_SUCCESS);
359: }
361: /*@
362: PetscLayoutSetLocalSize - Sets the local size for a `PetscLayout` object.
364: Collective
366: Input Parameters:
367: + map - pointer to the map
368: - n - the local size
370: Level: developer
372: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
373: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
374: @*/
375: PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n)
376: {
377: PetscFunctionBegin;
378: PetscCheck(map->bs <= 1 || (n % map->bs) == 0, map->comm, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, n, map->bs);
379: map->n = n;
380: PetscFunctionReturn(PETSC_SUCCESS);
381: }
383: /*@
384: PetscLayoutGetLocalSize - Gets the local size for a `PetscLayout` object.
386: Not Collective
388: Input Parameter:
389: . map - pointer to the map
391: Output Parameter:
392: . n - the local size
394: Level: developer
396: Note:
397: Call this after the call to `PetscLayoutSetUp()`
399: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
400: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
401: @*/
402: PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n)
403: {
404: PetscFunctionBegin;
405: *n = map->n;
406: PetscFunctionReturn(PETSC_SUCCESS);
407: }
409: /*@
410: PetscLayoutSetSize - Sets the global size for a `PetscLayout` object.
412: Logically Collective
414: Input Parameters:
415: + map - pointer to the map
416: - n - the global size
418: Level: developer
420: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
421: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
422: @*/
423: PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n)
424: {
425: PetscFunctionBegin;
426: map->N = n;
427: PetscFunctionReturn(PETSC_SUCCESS);
428: }
430: /*@
431: PetscLayoutGetSize - Gets the global size for a `PetscLayout` object.
433: Not Collective
435: Input Parameter:
436: . map - pointer to the map
438: Output Parameter:
439: . n - the global size
441: Level: developer
443: Note:
444: Call this after the call to `PetscLayoutSetUp()`
446: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
447: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
448: @*/
449: PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n)
450: {
451: PetscFunctionBegin;
452: *n = map->N;
453: PetscFunctionReturn(PETSC_SUCCESS);
454: }
456: /*@
457: PetscLayoutSetBlockSize - Sets the block size for a `PetscLayout` object.
459: Logically Collective
461: Input Parameters:
462: + map - pointer to the map
463: - bs - the size
465: Level: developer
467: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
468: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
469: @*/
470: PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs)
471: {
472: PetscFunctionBegin;
473: if (bs < 0) PetscFunctionReturn(PETSC_SUCCESS);
474: PetscCheck(map->n <= 0 || (map->n % bs) == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, map->n, bs);
475: if (map->mapping) {
476: PetscInt obs;
478: PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs));
479: if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs));
480: }
481: map->bs = bs;
482: PetscFunctionReturn(PETSC_SUCCESS);
483: }
485: /*@
486: PetscLayoutGetBlockSize - Gets the block size for a `PetscLayout` object.
488: Not Collective
490: Input Parameter:
491: . map - pointer to the map
493: Output Parameter:
494: . bs - the size
496: Level: developer
498: Notes:
499: Call this after the call to `PetscLayoutSetUp()`
501: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
502: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`
503: @*/
504: PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs)
505: {
506: PetscFunctionBegin;
507: *bs = PetscAbs(map->bs);
508: PetscFunctionReturn(PETSC_SUCCESS);
509: }
511: /*@
512: PetscLayoutGetRange - gets the range of values owned by this process
514: Not Collective
516: Input Parameter:
517: . map - pointer to the map
519: Output Parameters:
520: + rstart - first index owned by this process
521: - rend - one more than the last index owned by this process
523: Level: developer
525: Note:
526: Call this after the call to `PetscLayoutSetUp()`
528: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
529: `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
530: @*/
531: PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend)
532: {
533: PetscFunctionBegin;
534: if (rstart) *rstart = map->rstart;
535: if (rend) *rend = map->rend;
536: PetscFunctionReturn(PETSC_SUCCESS);
537: }
539: /*@C
540: PetscLayoutGetRanges - gets the ranges of values owned by all processes
542: Not Collective
544: Input Parameter:
545: . map - pointer to the map
547: Output Parameter:
548: . range - start of each processors range of indices (the final entry is one more than the
549: last index on the last process)
551: Level: developer
553: Note:
554: Call this after the call to `PetscLayoutSetUp()`
556: Fortran Note:
557: In Fortran, use PetscLayoutGetRangesF90()
559: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
560: `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
561: @*/
562: PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[])
563: {
564: PetscFunctionBegin;
565: *range = map->range;
566: PetscFunctionReturn(PETSC_SUCCESS);
567: }
569: /*@
570: PetscLayoutCompare - Compares two layouts
572: Not Collective
574: Input Parameters:
575: + mapa - pointer to the first map
576: - mapb - pointer to the second map
578: Output Parameter:
579: . congruent - `PETSC_TRUE` if the two layouts are congruent, `PETSC_FALSE` otherwise
581: Level: beginner
583: .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
584: `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
585: @*/
586: PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent)
587: {
588: PetscFunctionBegin;
589: *congruent = PETSC_FALSE;
590: if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent));
591: PetscFunctionReturn(PETSC_SUCCESS);
592: }