Actual source code: pmap.c
petsc-3.4.2 2013-07-02
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: developer
22: Notes: Typical calling sequence
23: PetscLayoutCreate(MPI_Comm,PetscLayout *);
24: PetscLayoutSetBlockSize(PetscLayout,1);
25: PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N);
26: PetscLayoutSetUp(PetscLayout);
27: Optionally use any of the following:
28: PetscLayoutGetSize(PetscLayout,PetscInt *); or PetscLayoutGetLocalSize(PetscLayout,PetscInt *;)
29: PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); or PetscLayoutGetRanges(PetscLayout,const PetscInt *range[])
30: PetscLayoutDestroy(PetscLayout);
32: The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
33: user codes unless you really gain something in their use.
35: Fortran Notes:
36: Not available from Fortran
38: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
39: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
41: @*/
42: PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
43: {
47: PetscNew(struct _n_PetscLayout,map);
49: (*map)->comm = comm;
50: (*map)->bs = -1;
51: (*map)->n = -1;
52: (*map)->N = -1;
53: (*map)->range = 0;
54: (*map)->rstart = 0;
55: (*map)->rend = 0;
56: (*map)->trstarts = 0;
57: return(0);
58: }
60: /*@C
61: PetscLayoutDestroy - Frees a map object and frees its range if that exists.
63: Collective on MPI_Comm
65: Input Parameters:
66: . map - the PetscLayout
68: Level: developer
70: The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
71: recommended they not be used in user codes unless you really gain something in their use.
73: Fortran Notes:
74: Not available from Fortran
76: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
77: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
79: @*/
82: PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
83: {
87: if (!*map) return(0);
88: if (!(*map)->refcnt--) {
89: PetscFree((*map)->range);
90: ISLocalToGlobalMappingDestroy(&(*map)->mapping);
91: ISLocalToGlobalMappingDestroy(&(*map)->bmapping);
92: #if defined(PETSC_THREADCOMM_ACTIVE)
93: PetscFree((*map)->trstarts);
94: #endif
96: PetscFree((*map));
97: }
98: *map = NULL;
99: return(0);
100: }
102: /*@C
103: PetscLayoutSetUp - given a map where you have set either the global or local
104: size sets up the map so that it may be used.
106: Collective on MPI_Comm
108: Input Parameters:
109: . map - pointer to the map
111: Level: developer
113: Notes: Typical calling sequence
114: PetscLayoutCreate(MPI_Comm,PetscLayout *);
115: PetscLayoutSetBlockSize(PetscLayout,1);
116: PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
117: PetscLayoutSetUp(PetscLayout);
118: PetscLayoutGetSize(PetscLayout,PetscInt *);
121: If the local size, global size are already set and range exists then this does nothing.
123: Fortran Notes:
124: Not available from Fortran
126: .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
127: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
129: @*/
132: PetscErrorCode PetscLayoutSetUp(PetscLayout map)
133: {
134: PetscMPIInt rank,size;
135: PetscInt p;
139: if (map->bs <= 0) map->bs = 1;
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/map->bs;
145: if (map->N > 0) map->N = map->N/map->bs;
146: PetscSplitOwnership(map->comm,&map->n,&map->N);
147: map->n = map->n*map->bs;
148: map->N = map->N*map->bs;
149: if (!map->range) {
150: PetscMalloc((size+1)*sizeof(PetscInt), &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: #if defined(PETSC_THREADCOMM_ACTIVE)
160: /* Set the thread ownership ranges */
161: PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);
162: #endif
163: return(0);
164: }
168: /*@C
170: PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
172: Collective on PetscLayout
174: Input Parameter:
175: . in - input PetscLayout to be duplicated
177: Output Parameter:
178: . out - the copy
180: Level: developer
182: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
184: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
186: @*/
187: PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
188: {
189: PetscMPIInt size;
191: MPI_Comm comm = in->comm;
194: PetscLayoutDestroy(out);
195: PetscLayoutCreate(comm,out);
196: MPI_Comm_size(comm,&size);
197: PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));
198: PetscMalloc((size+1)*sizeof(PetscInt),&(*out)->range);
199: PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));
201: (*out)->refcnt = 0;
202: return(0);
203: }
207: /*@C
209: PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
211: Collective on PetscLayout
213: Input Parameter:
214: . in - input PetscLayout to be copied
216: Output Parameter:
217: . out - the reference location
219: Level: developer
221: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
223: If the out location already contains a PetscLayout it is destroyed
225: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
227: @*/
228: PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
229: {
233: in->refcnt++;
234: PetscLayoutDestroy(out);
235: *out = in;
236: return(0);
237: }
241: /*@C
243: PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
245: Collective on PetscLayout
247: Input Parameter:
248: + in - input PetscLayout
249: - ltog - the local to global mapping
252: Level: developer
254: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
256: If the ltog location already contains a PetscLayout it is destroyed
258: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()
260: @*/
261: PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
262: {
266: PetscObjectReference((PetscObject)ltog);
267: ISLocalToGlobalMappingDestroy(&in->mapping);
269: in->mapping = ltog;
270: return(0);
271: }
275: /*@C
277: PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout
279: Collective on PetscLayout
281: Input Parameter:
282: + in - input PetscLayout
283: - ltog - the local to global block mapping
286: Level: developer
288: Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
290: If the ltog location already contains a PetscLayout it is destroyed
292: .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()
294: @*/
295: PetscErrorCode PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog)
296: {
300: PetscObjectReference((PetscObject)ltog);
301: ISLocalToGlobalMappingDestroy(&in->bmapping);
303: in->bmapping = ltog;
304: return(0);
305: }
307: /*@C
308: PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
310: Collective on PetscLayout
312: Input Parameters:
313: + map - pointer to the map
314: - n - the local size
316: Level: developer
318: Notes:
319: Call this after the call to PetscLayoutCreate()
321: Fortran Notes:
322: Not available from Fortran
324: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
325: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
327: @*/
330: PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
331: {
333: 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);
334: map->n = n;
335: return(0);
336: }
338: /*@C
339: PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
341: Not Collective
343: Input Parameters:
344: . map - pointer to the map
346: Output Parameters:
347: . n - the local size
349: Level: developer
351: Notes:
352: Call this after the call to PetscLayoutSetUp()
354: Fortran Notes:
355: Not available from Fortran
357: .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
358: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
360: @*/
363: PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
364: {
366: *n = map->n;
367: return(0);
368: }
370: /*@C
371: PetscLayoutSetSize - Sets the global size for a PetscLayout object.
373: Logically Collective on PetscLayout
375: Input Parameters:
376: + map - pointer to the map
377: - n - the global size
379: Level: developer
381: Notes:
382: Call this after the call to PetscLayoutCreate()
384: Fortran Notes:
385: Not available from Fortran
387: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
388: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
390: @*/
393: PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
394: {
396: map->N = n;
397: return(0);
398: }
400: /*@C
401: PetscLayoutGetSize - Gets the global size for a PetscLayout object.
403: Not Collective
405: Input Parameters:
406: . map - pointer to the map
408: Output Parameters:
409: . n - the global size
411: Level: developer
413: Notes:
414: Call this after the call to PetscLayoutSetUp()
416: Fortran Notes:
417: Not available from Fortran
419: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
420: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
422: @*/
425: PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
426: {
428: *n = map->N;
429: return(0);
430: }
432: /*@C
433: PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
435: Logically Collective on PetscLayout
437: Input Parameters:
438: + map - pointer to the map
439: - bs - the size
441: Level: developer
443: Notes:
444: Call this after the call to PetscLayoutCreate()
446: Fortran Notes:
447: Not available from Fortran
449: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
450: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
452: @*/
455: PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
456: {
458: 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);
459: if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
460: map->bs = bs;
461: return(0);
462: }
464: /*@C
465: PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
467: Not Collective
469: Input Parameters:
470: . map - pointer to the map
472: Output Parameters:
473: . bs - the size
475: Level: developer
477: Notes:
478: Call this after the call to PetscLayoutSetUp()
480: Fortran Notes:
481: Not available from Fortran
483: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
484: PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
486: @*/
489: PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
490: {
492: *bs = map->bs;
493: return(0);
494: }
497: /*@C
498: PetscLayoutGetRange - gets the range of values owned by this process
500: Not Collective
502: Input Parameters:
503: . map - pointer to the map
505: Output Parameters:
506: + rstart - first index owned by this process
507: - rend - one more than the last index owned by this process
509: Level: developer
511: Notes:
512: Call this after the call to PetscLayoutSetUp()
514: Fortran Notes:
515: Not available from Fortran
517: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
518: PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
520: @*/
523: PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
524: {
526: if (rstart) *rstart = map->rstart;
527: if (rend) *rend = map->rend;
528: return(0);
529: }
531: /*@C
532: PetscLayoutGetRanges - gets the range of values owned by all processes
534: Not Collective
536: Input Parameters:
537: . map - pointer to the map
539: Output Parameters:
540: . range - start of each processors range of indices (the final entry is one more then the
541: last index on the last process)
543: Level: developer
545: Notes:
546: Call this after the call to PetscLayoutSetUp()
548: Fortran Notes:
549: Not available from Fortran
551: .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
552: PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
554: @*/
557: PetscErrorCode PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
558: {
560: *range = map->range;
561: return(0);
562: }
566: /*@C
567: PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
569: Collective
571: Input Arguments:
572: + sf - star forest
573: . layout - PetscLayout defining the global space
574: . nleaves - number of leaf vertices on the current process, each of these references a root on any process
575: . ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
576: - iremote - remote locations of root vertices for each leaf on the current process
578: Level: intermediate
580: .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
581: @*/
582: PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
583: {
585: PetscInt i,nroots;
586: PetscSFNode *remote;
589: PetscLayoutGetLocalSize(layout,&nroots);
590: PetscMalloc(nleaves*sizeof(PetscSFNode),&remote);
591: for (i=0; i<nleaves; i++) {
592: PetscInt owner = -1;
593: PetscLayoutFindOwner(layout,iremote[i],&owner);
594: remote[i].rank = owner;
595: remote[i].index = iremote[i] - layout->range[owner];
596: }
597: PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);
598: return(0);
599: }