Actual source code: pmap.c
petsc-3.6.1 2015-08-06
2: /*
3: This file contains routines for basic map object implementation.
4: */
6: #include <petscvec.h>
7: #include <petscsf.h>
11: /*@C
12: PetscLayoutCreate - Allocates PetscLayout space and sets the map contents to the default.
14: Collective on MPI_Comm
16: Input Parameters:
17: + comm - the MPI communicator
18: - map - pointer to the map
20: Level: advanced
22: Notes:
23: Typical calling sequence
24: .vb
25: PetscLayoutCreate(MPI_Comm,PetscLayout *);
26: PetscLayoutSetBlockSize(PetscLayout,1);
27: PetscLayoutSetSize(PetscLayout,N) // or PetscLayoutSetLocalSize(PetscLayout,n);
28: PetscLayoutSetUp(PetscLayout);
29: .ve
30: Optionally use any of the following:
32: + PetscLayoutGetSize(PetscLayout,PetscInt *);
33: . PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
34: . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
35: . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
36: - PetscLayoutDestroy(PetscLayout*);
38: The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
39: user codes unless you really gain something in their use.
41: Fortran Notes:
42: Not available from Fortran
44: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
45: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
47: @*/
48: PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
49: {
53: PetscNew(map);
55: (*map)->comm = comm;
56: (*map)->bs = -1;
57: (*map)->n = -1;
58: (*map)->N = -1;
59: (*map)->range = 0;
60: (*map)->rstart = 0;
61: (*map)->rend = 0;
62: (*map)->trstarts = 0;
63: return(0);
64: }
66: /*@C
67: PetscLayoutDestroy - Frees a map object and frees its range if that exists.
69: Collective on MPI_Comm
71: Input Parameters:
72: . map - the PetscLayout
74: Level: developer
76: The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
77: recommended they not be used in user codes unless you really gain something in their use.
79: Fortran Notes:
80: Not available from Fortran
82: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
83: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
85: @*/
88: PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
89: {
93: if (!*map) return(0);
94: if (!(*map)->refcnt--) {
95: PetscFree((*map)->range);
96: ISLocalToGlobalMappingDestroy(&(*map)->mapping);
97: PetscFree((*map));
98: }
99: *map = NULL;
100: return(0);
101: }
103: /*@C
104: PetscLayoutSetUp - given a map where you have set either the global or local
105: size sets up the map so that it may be used.
107: Collective on MPI_Comm
109: Input Parameters:
110: . map - pointer to the map
112: Level: developer
114: Notes: Typical calling sequence
115: PetscLayoutCreate(MPI_Comm,PetscLayout *);
116: PetscLayoutSetBlockSize(PetscLayout,1);
117: PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
118: PetscLayoutSetUp(PetscLayout);
119: PetscLayoutGetSize(PetscLayout,PetscInt *);
122: If the local size, global size are already set and range exists then this does nothing.
124: Fortran Notes:
125: Not available from Fortran
127: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
128: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
130: @*/
133: PetscErrorCode PetscLayoutSetUp(PetscLayout map)
134: {
135: PetscMPIInt rank,size;
136: PetscInt p;
140: if ((map->n >= 0) && (map->N >= 0) && (map->range)) return(0);
142: MPI_Comm_size(map->comm, &size);
143: MPI_Comm_rank(map->comm, &rank);
144: if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
145: if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
146: PetscSplitOwnership(map->comm,&map->n,&map->N);
147: map->n = map->n*PetscAbs(map->bs);
148: map->N = map->N*PetscAbs(map->bs);
149: if (!map->range) {
150: PetscMalloc1(size+1, &map->range);
151: }
152: MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);
154: map->range[0] = 0;
155: for (p = 2; p <= size; p++) map->range[p] += map->range[p-1];
157: map->rstart = map->range[rank];
158: map->rend = map->range[rank+1];
159: return(0);
160: }
164: /*@C
166: PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
168: Collective on PetscLayout
170: Input Parameter:
171: . in - input PetscLayout to be duplicated
173: Output Parameter:
174: . out - the copy
176: Level: developer
178: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
180: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
182: @*/
183: PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
184: {
185: PetscMPIInt size;
187: MPI_Comm comm = in->comm;
190: PetscLayoutDestroy(out);
191: PetscLayoutCreate(comm,out);
192: MPI_Comm_size(comm,&size);
193: PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
194: PetscMalloc1(size+1,&(*out)->range);
195: PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));
197: (*out)->refcnt = 0;
198: return(0);
199: }
203: /*@C
205: PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
207: Collective on PetscLayout
209: Input Parameter:
210: . in - input PetscLayout to be copied
212: Output Parameter:
213: . out - the reference location
215: Level: developer
217: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
219: If the out location already contains a PetscLayout it is destroyed
221: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
223: @*/
224: PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
225: {
229: in->refcnt++;
230: PetscLayoutDestroy(out);
231: *out = in;
232: return(0);
233: }
237: /*@C
239: PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
241: Collective on PetscLayout
243: Input Parameter:
244: + in - input PetscLayout
245: - ltog - the local to global mapping
248: Level: developer
250: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
252: If the ltog location already contains a PetscLayout it is destroyed
254: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
256: @*/
257: PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
258: {
260: PetscInt bs;
263: ISLocalToGlobalMappingGetBlockSize(ltog,&bs);
264: if (in->bs > 0 && in->bs != bs) SETERRQ2(in->comm,PETSC_ERR_PLIB,"Blocksize of layout %D must match that of mapping %D",in->bs,bs);
265: PetscObjectReference((PetscObject)ltog);
266: ISLocalToGlobalMappingDestroy(&in->mapping);
267: in->mapping = ltog;
268: return(0);
269: }
271: /*@C
272: PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
274: Collective on PetscLayout
276: Input Parameters:
277: + map - pointer to the map
278: - n - the local size
280: Level: developer
282: Notes:
283: Call this after the call to PetscLayoutCreate()
285: Fortran Notes:
286: Not available from Fortran
288: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
289: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
291: @*/
294: PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
295: {
297: 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);
298: map->n = n;
299: return(0);
300: }
302: /*@C
303: PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
305: Not Collective
307: Input Parameters:
308: . map - pointer to the map
310: Output Parameters:
311: . n - the local size
313: Level: developer
315: Notes:
316: Call this after the call to PetscLayoutSetUp()
318: Fortran Notes:
319: Not available from Fortran
321: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
322: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
324: @*/
327: PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
328: {
330: *n = map->n;
331: return(0);
332: }
334: /*@C
335: PetscLayoutSetSize - Sets the global size for a PetscLayout object.
337: Logically Collective on PetscLayout
339: Input Parameters:
340: + map - pointer to the map
341: - n - the global size
343: Level: developer
345: Notes:
346: Call this after the call to PetscLayoutCreate()
348: Fortran Notes:
349: Not available from Fortran
351: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
352: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
354: @*/
357: PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
358: {
360: map->N = n;
361: return(0);
362: }
364: /*@C
365: PetscLayoutGetSize - Gets the global size for a PetscLayout object.
367: Not Collective
369: Input Parameters:
370: . map - pointer to the map
372: Output Parameters:
373: . n - the global size
375: Level: developer
377: Notes:
378: Call this after the call to PetscLayoutSetUp()
380: Fortran Notes:
381: Not available from Fortran
383: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
384: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
386: @*/
389: PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
390: {
392: *n = map->N;
393: return(0);
394: }
396: /*@C
397: PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
399: Logically Collective on PetscLayout
401: Input Parameters:
402: + map - pointer to the map
403: - bs - the size
405: Level: developer
407: Notes:
408: Call this after the call to PetscLayoutCreate()
410: Fortran Notes:
411: Not available from Fortran
413: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
414: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
416: @*/
419: PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
420: {
422: if (bs < 0) return(0);
423: if (map->n > 0 && map->n % bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",map->n,bs);
424: if (map->range && map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
425: if (map->mapping) {
426: PetscInt lbs;
429: ISLocalToGlobalMappingGetBlockSize(map->mapping,&lbs);
430: if (lbs != bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Blocksize of localtoglobalmapping %D must match that of layout %D",lbs,bs);
431: }
432: map->bs = bs;
433: return(0);
434: }
436: /*@C
437: PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
439: Not Collective
441: Input Parameters:
442: . map - pointer to the map
444: Output Parameters:
445: . bs - the size
447: Level: developer
449: Notes:
450: Call this after the call to PetscLayoutSetUp()
452: Fortran Notes:
453: Not available from Fortran
455: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
456: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
458: @*/
461: PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
462: {
464: *bs = PetscAbs(map->bs);
465: return(0);
466: }
469: /*@C
470: PetscLayoutGetRange - gets the range of values owned by this process
472: Not Collective
474: Input Parameters:
475: . map - pointer to the map
477: Output Parameters:
478: + rstart - first index owned by this process
479: - rend - one more than the last index owned by this process
481: Level: developer
483: Notes:
484: Call this after the call to PetscLayoutSetUp()
486: Fortran Notes:
487: Not available from Fortran
489: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
490: PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
492: @*/
495: PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
496: {
498: if (rstart) *rstart = map->rstart;
499: if (rend) *rend = map->rend;
500: return(0);
501: }
503: /*@C
504: PetscLayoutGetRanges - gets the range of values owned by all processes
506: Not Collective
508: Input Parameters:
509: . map - pointer to the map
511: Output Parameters:
512: . range - start of each processors range of indices (the final entry is one more then the
513: last index on the last process)
515: Level: developer
517: Notes:
518: Call this after the call to PetscLayoutSetUp()
520: Fortran Notes:
521: Not available from Fortran
523: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
524: PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
526: @*/
529: PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
530: {
532: *range = map->range;
533: return(0);
534: }
538: /*@C
539: PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
541: Collective
543: Input Arguments:
544: + sf - star forest
545: . layout - PetscLayout defining the global space
546: . nleaves - number of leaf vertices on the current process, each of these references a root on any process
547: . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
548: - iremote - remote locations of root vertices for each leaf on the current process
550: Level: intermediate
552: .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
553: @*/
554: PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
555: {
557: PetscInt i,nroots;
558: PetscSFNode *remote;
561: PetscLayoutGetLocalSize(layout,&nroots);
562: PetscMalloc1(nleaves,&remote);
563: for (i=0; i<nleaves; i++) {
564: PetscInt owner = -1;
565: PetscLayoutFindOwner(layout,iremote[i],&owner);
566: remote[i].rank = owner;
567: remote[i].index = iremote[i] - layout->range[owner];
568: }
569: PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
570: return(0);
571: }