Actual source code: pmap.c
petsc-3.5.4 2015-05-23
2: /*
3: This file contains routines for basic map object implementation.
4: */
6: #include <petscvec.h>
7: #include <petscsf.h>
8: #include <petsc-private/threadcommimpl.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: #if defined(PETSC_THREADCOMM_ACTIVE)
98: PetscFree((*map)->trstarts);
99: #endif
101: PetscFree((*map));
102: }
103: *map = NULL;
104: return(0);
105: }
107: /*@C
108: PetscLayoutSetUp - given a map where you have set either the global or local
109: size sets up the map so that it may be used.
111: Collective on MPI_Comm
113: Input Parameters:
114: . map - pointer to the map
116: Level: developer
118: Notes: Typical calling sequence
119: PetscLayoutCreate(MPI_Comm,PetscLayout *);
120: PetscLayoutSetBlockSize(PetscLayout,1);
121: PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
122: PetscLayoutSetUp(PetscLayout);
123: PetscLayoutGetSize(PetscLayout,PetscInt *);
126: If the local size, global size are already set and range exists then this does nothing.
128: Fortran Notes:
129: Not available from Fortran
131: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
132: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
134: @*/
137: PetscErrorCode PetscLayoutSetUp(PetscLayout map)
138: {
139: PetscMPIInt rank,size;
140: PetscInt p;
144: if ((map->n >= 0) && (map->N >= 0) && (map->range)) return(0);
146: MPI_Comm_size(map->comm, &size);
147: MPI_Comm_rank(map->comm, &rank);
148: if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
149: if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
150: PetscSplitOwnership(map->comm,&map->n,&map->N);
151: map->n = map->n*PetscAbs(map->bs);
152: map->N = map->N*PetscAbs(map->bs);
153: if (!map->range) {
154: PetscMalloc1((size+1), &map->range);
155: }
156: MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);
158: map->range[0] = 0;
159: for (p = 2; p <= size; p++) map->range[p] += map->range[p-1];
161: map->rstart = map->range[rank];
162: map->rend = map->range[rank+1];
163: #if defined(PETSC_THREADCOMM_ACTIVE)
164: /* Set the thread ownership ranges */
165: PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);
166: #endif
167: return(0);
168: }
172: /*@C
174: PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
176: Collective on PetscLayout
178: Input Parameter:
179: . in - input PetscLayout to be duplicated
181: Output Parameter:
182: . out - the copy
184: Level: developer
186: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
188: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
190: @*/
191: PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
192: {
193: PetscMPIInt size;
195: MPI_Comm comm = in->comm;
198: PetscLayoutDestroy(out);
199: PetscLayoutCreate(comm,out);
200: MPI_Comm_size(comm,&size);
201: PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
202: PetscMalloc1((size+1),&(*out)->range);
203: PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));
205: (*out)->refcnt = 0;
206: return(0);
207: }
211: /*@C
213: PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
215: Collective on PetscLayout
217: Input Parameter:
218: . in - input PetscLayout to be copied
220: Output Parameter:
221: . out - the reference location
223: Level: developer
225: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
227: If the out location already contains a PetscLayout it is destroyed
229: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
231: @*/
232: PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
233: {
237: in->refcnt++;
238: PetscLayoutDestroy(out);
239: *out = in;
240: return(0);
241: }
245: /*@C
247: PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
249: Collective on PetscLayout
251: Input Parameter:
252: + in - input PetscLayout
253: - ltog - the local to global mapping
256: Level: developer
258: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
260: If the ltog location already contains a PetscLayout it is destroyed
262: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
264: @*/
265: PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
266: {
268: PetscInt bs;
271: ISLocalToGlobalMappingGetBlockSize(ltog,&bs);
272: 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);
273: PetscObjectReference((PetscObject)ltog);
274: ISLocalToGlobalMappingDestroy(&in->mapping);
275: in->mapping = ltog;
276: return(0);
277: }
279: /*@C
280: PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
282: Collective on PetscLayout
284: Input Parameters:
285: + map - pointer to the map
286: - n - the local size
288: Level: developer
290: Notes:
291: Call this after the call to PetscLayoutCreate()
293: Fortran Notes:
294: Not available from Fortran
296: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
297: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
299: @*/
302: PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
303: {
305: 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);
306: map->n = n;
307: return(0);
308: }
310: /*@C
311: PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
313: Not Collective
315: Input Parameters:
316: . map - pointer to the map
318: Output Parameters:
319: . n - the local size
321: Level: developer
323: Notes:
324: Call this after the call to PetscLayoutSetUp()
326: Fortran Notes:
327: Not available from Fortran
329: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
330: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
332: @*/
335: PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
336: {
338: *n = map->n;
339: return(0);
340: }
342: /*@C
343: PetscLayoutSetSize - Sets the global size for a PetscLayout object.
345: Logically Collective on PetscLayout
347: Input Parameters:
348: + map - pointer to the map
349: - n - the global size
351: Level: developer
353: Notes:
354: Call this after the call to PetscLayoutCreate()
356: Fortran Notes:
357: Not available from Fortran
359: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
360: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
362: @*/
365: PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
366: {
368: map->N = n;
369: return(0);
370: }
372: /*@C
373: PetscLayoutGetSize - Gets the global size for a PetscLayout object.
375: Not Collective
377: Input Parameters:
378: . map - pointer to the map
380: Output Parameters:
381: . n - the global size
383: Level: developer
385: Notes:
386: Call this after the call to PetscLayoutSetUp()
388: Fortran Notes:
389: Not available from Fortran
391: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
392: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
394: @*/
397: PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
398: {
400: *n = map->N;
401: return(0);
402: }
404: /*@C
405: PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
407: Logically Collective on PetscLayout
409: Input Parameters:
410: + map - pointer to the map
411: - bs - the size
413: Level: developer
415: Notes:
416: Call this after the call to PetscLayoutCreate()
418: Fortran Notes:
419: Not available from Fortran
421: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
422: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
424: @*/
427: PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
428: {
430: if (bs < 0) return(0);
431: 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);
432: 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);
433: if (map->mapping) {
434: PetscInt lbs;
437: ISLocalToGlobalMappingGetBlockSize(map->mapping,&lbs);
438: if (lbs != bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Blocksize of localtoglobalmapping %D must match that of layout %D",lbs,bs);
439: }
440: map->bs = bs;
441: return(0);
442: }
444: /*@C
445: PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
447: Not Collective
449: Input Parameters:
450: . map - pointer to the map
452: Output Parameters:
453: . bs - the size
455: Level: developer
457: Notes:
458: Call this after the call to PetscLayoutSetUp()
460: Fortran Notes:
461: Not available from Fortran
463: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
464: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
466: @*/
469: PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
470: {
472: *bs = PetscAbs(map->bs);
473: return(0);
474: }
477: /*@C
478: PetscLayoutGetRange - gets the range of values owned by this process
480: Not Collective
482: Input Parameters:
483: . map - pointer to the map
485: Output Parameters:
486: + rstart - first index owned by this process
487: - rend - one more than the last index owned by this process
489: Level: developer
491: Notes:
492: Call this after the call to PetscLayoutSetUp()
494: Fortran Notes:
495: Not available from Fortran
497: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
498: PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
500: @*/
503: PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
504: {
506: if (rstart) *rstart = map->rstart;
507: if (rend) *rend = map->rend;
508: return(0);
509: }
511: /*@C
512: PetscLayoutGetRanges - gets the range of values owned by all processes
514: Not Collective
516: Input Parameters:
517: . map - pointer to the map
519: Output Parameters:
520: . range - start of each processors range of indices (the final entry is one more then the
521: last index on the last process)
523: Level: developer
525: Notes:
526: Call this after the call to PetscLayoutSetUp()
528: Fortran Notes:
529: Not available from Fortran
531: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
532: PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
534: @*/
537: PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
538: {
540: *range = map->range;
541: return(0);
542: }
546: /*@C
547: PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
549: Collective
551: Input Arguments:
552: + sf - star forest
553: . layout - PetscLayout defining the global space
554: . nleaves - number of leaf vertices on the current process, each of these references a root on any process
555: . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
556: - iremote - remote locations of root vertices for each leaf on the current process
558: Level: intermediate
560: .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
561: @*/
562: PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
563: {
565: PetscInt i,nroots;
566: PetscSFNode *remote;
569: PetscLayoutGetLocalSize(layout,&nroots);
570: PetscMalloc1(nleaves,&remote);
571: for (i=0; i<nleaves; i++) {
572: PetscInt owner = -1;
573: PetscLayoutFindOwner(layout,iremote[i],&owner);
574: remote[i].rank = owner;
575: remote[i].index = iremote[i] - layout->range[owner];
576: }
577: PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
578: return(0);
579: }