Actual source code: pmap.c
petsc-3.4.5 2014-06-29
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(struct _n_PetscLayout,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: ISLocalToGlobalMappingDestroy(&(*map)->bmapping);
98: #if defined(PETSC_THREADCOMM_ACTIVE)
99: PetscFree((*map)->trstarts);
100: #endif
102: PetscFree((*map));
103: }
104: *map = NULL;
105: return(0);
106: }
108: /*@C
109: PetscLayoutSetUp - given a map where you have set either the global or local
110: size sets up the map so that it may be used.
112: Collective on MPI_Comm
114: Input Parameters:
115: . map - pointer to the map
117: Level: developer
119: Notes: Typical calling sequence
120: PetscLayoutCreate(MPI_Comm,PetscLayout *);
121: PetscLayoutSetBlockSize(PetscLayout,1);
122: PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
123: PetscLayoutSetUp(PetscLayout);
124: PetscLayoutGetSize(PetscLayout,PetscInt *);
127: If the local size, global size are already set and range exists then this does nothing.
129: Fortran Notes:
130: Not available from Fortran
132: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
133: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
135: @*/
138: PetscErrorCode PetscLayoutSetUp(PetscLayout map)
139: {
140: PetscMPIInt rank,size;
141: PetscInt p;
145: if (map->bs <= 0) map->bs = 1;
146: if ((map->n >= 0) && (map->N >= 0) && (map->range)) return(0);
148: MPI_Comm_size(map->comm, &size);
149: MPI_Comm_rank(map->comm, &rank);
150: if (map->n > 0) map->n = map->n/map->bs;
151: if (map->N > 0) map->N = map->N/map->bs;
152: PetscSplitOwnership(map->comm,&map->n,&map->N);
153: map->n = map->n*map->bs;
154: map->N = map->N*map->bs;
155: if (!map->range) {
156: PetscMalloc((size+1)*sizeof(PetscInt), &map->range);
157: }
158: MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);
160: map->range[0] = 0;
161: for (p = 2; p <= size; p++) map->range[p] += map->range[p-1];
163: map->rstart = map->range[rank];
164: map->rend = map->range[rank+1];
165: #if defined(PETSC_THREADCOMM_ACTIVE)
166: /* Set the thread ownership ranges */
167: PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);
168: #endif
169: return(0);
170: }
174: /*@C
176: PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
178: Collective on PetscLayout
180: Input Parameter:
181: . in - input PetscLayout to be duplicated
183: Output Parameter:
184: . out - the copy
186: Level: developer
188: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
190: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
192: @*/
193: PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
194: {
195: PetscMPIInt size;
197: MPI_Comm comm = in->comm;
200: PetscLayoutDestroy(out);
201: PetscLayoutCreate(comm,out);
202: MPI_Comm_size(comm,&size);
203: PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
204: PetscMalloc((size+1)*sizeof(PetscInt),&(*out)->range);
205: PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));
207: (*out)->refcnt = 0;
208: return(0);
209: }
213: /*@C
215: PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
217: Collective on PetscLayout
219: Input Parameter:
220: . in - input PetscLayout to be copied
222: Output Parameter:
223: . out - the reference location
225: Level: developer
227: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
229: If the out location already contains a PetscLayout it is destroyed
231: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
233: @*/
234: PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
235: {
239: in->refcnt++;
240: PetscLayoutDestroy(out);
241: *out = in;
242: return(0);
243: }
247: /*@C
249: PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
251: Collective on PetscLayout
253: Input Parameter:
254: + in - input PetscLayout
255: - ltog - the local to global mapping
258: Level: developer
260: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
262: If the ltog location already contains a PetscLayout it is destroyed
264: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()
266: @*/
267: PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
268: {
272: PetscObjectReference((PetscObject)ltog);
273: ISLocalToGlobalMappingDestroy(&in->mapping);
275: in->mapping = ltog;
276: return(0);
277: }
281: /*@C
283: PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout
285: Collective on PetscLayout
287: Input Parameter:
288: + in - input PetscLayout
289: - ltog - the local to global block mapping
292: Level: developer
294: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
296: If the ltog location already contains a PetscLayout it is destroyed
298: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()
300: @*/
301: PetscErrorCode PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog)
302: {
306: PetscObjectReference((PetscObject)ltog);
307: ISLocalToGlobalMappingDestroy(&in->bmapping);
309: in->bmapping = ltog;
310: return(0);
311: }
313: /*@C
314: PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
316: Collective on PetscLayout
318: Input Parameters:
319: + map - pointer to the map
320: - n - the local size
322: Level: developer
324: Notes:
325: Call this after the call to PetscLayoutCreate()
327: Fortran Notes:
328: Not available from Fortran
330: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
331: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
333: @*/
336: PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
337: {
339: 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);
340: map->n = n;
341: return(0);
342: }
344: /*@C
345: PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
347: Not Collective
349: Input Parameters:
350: . map - pointer to the map
352: Output Parameters:
353: . n - the local size
355: Level: developer
357: Notes:
358: Call this after the call to PetscLayoutSetUp()
360: Fortran Notes:
361: Not available from Fortran
363: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
364: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
366: @*/
369: PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
370: {
372: *n = map->n;
373: return(0);
374: }
376: /*@C
377: PetscLayoutSetSize - Sets the global size for a PetscLayout object.
379: Logically Collective on PetscLayout
381: Input Parameters:
382: + map - pointer to the map
383: - n - the global size
385: Level: developer
387: Notes:
388: Call this after the call to PetscLayoutCreate()
390: Fortran Notes:
391: Not available from Fortran
393: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
394: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
396: @*/
399: PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
400: {
402: map->N = n;
403: return(0);
404: }
406: /*@C
407: PetscLayoutGetSize - Gets the global size for a PetscLayout object.
409: Not Collective
411: Input Parameters:
412: . map - pointer to the map
414: Output Parameters:
415: . n - the global size
417: Level: developer
419: Notes:
420: Call this after the call to PetscLayoutSetUp()
422: Fortran Notes:
423: Not available from Fortran
425: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
426: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
428: @*/
431: PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
432: {
434: *n = map->N;
435: return(0);
436: }
438: /*@C
439: PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
441: Logically Collective on PetscLayout
443: Input Parameters:
444: + map - pointer to the map
445: - bs - the size
447: Level: developer
449: Notes:
450: Call this after the call to PetscLayoutCreate()
452: Fortran Notes:
453: Not available from Fortran
455: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
456: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
458: @*/
461: PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
462: {
464: 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);
465: if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
466: map->bs = bs;
467: return(0);
468: }
470: /*@C
471: PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
473: Not Collective
475: Input Parameters:
476: . map - pointer to the map
478: Output Parameters:
479: . bs - the size
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(), PetscLayoutSetUp()
490: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
492: @*/
495: PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
496: {
498: *bs = map->bs;
499: return(0);
500: }
503: /*@C
504: PetscLayoutGetRange - gets the range of values owned by this process
506: Not Collective
508: Input Parameters:
509: . map - pointer to the map
511: Output Parameters:
512: + rstart - first index owned by this process
513: - rend - one more than the last index owned by this 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(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
526: @*/
529: PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
530: {
532: if (rstart) *rstart = map->rstart;
533: if (rend) *rend = map->rend;
534: return(0);
535: }
537: /*@C
538: PetscLayoutGetRanges - gets the range of values owned by all processes
540: Not Collective
542: Input Parameters:
543: . map - pointer to the map
545: Output Parameters:
546: . range - start of each processors range of indices (the final entry is one more then the
547: last index on the last process)
549: Level: developer
551: Notes:
552: Call this after the call to PetscLayoutSetUp()
554: Fortran Notes:
555: Not available from Fortran
557: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
558: PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
560: @*/
563: PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
564: {
566: *range = map->range;
567: return(0);
568: }
572: /*@C
573: PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
575: Collective
577: Input Arguments:
578: + sf - star forest
579: . layout - PetscLayout defining the global space
580: . nleaves - number of leaf vertices on the current process, each of these references a root on any process
581: . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
582: - iremote - remote locations of root vertices for each leaf on the current process
584: Level: intermediate
586: .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
587: @*/
588: PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
589: {
591: PetscInt i,nroots;
592: PetscSFNode *remote;
595: PetscLayoutGetLocalSize(layout,&nroots);
596: PetscMalloc(nleaves*sizeof(PetscSFNode),&remote);
597: for (i=0; i<nleaves; i++) {
598: PetscInt owner = -1;
599: PetscLayoutFindOwner(layout,iremote[i],&owner);
600: remote[i].rank = owner;
601: remote[i].index = iremote[i] - layout->range[owner];
602: }
603: PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
604: return(0);
605: }