xref: /petsc/src/vec/is/utils/pmap.c (revision 9895aa37ac365bac650f6bd8bf977519f7222510)
1 
2 /*
3    This file contains routines for basic map object implementation.
4 */
5 
6 #include <petscvec.h>
7 #include <petsc-private/threadcommimpl.h>
8 #undef __FUNCT__
9 #define __FUNCT__ "PetscLayoutCreate"
10 /*@C
11      PetscLayoutCreate - Allocates PetscLayout space and sets the map contents to the default.
12 
13     Collective on MPI_Comm
14 
15    Input Parameters:
16 +    comm - the MPI communicator
17 -    map - pointer to the map
18 
19    Level: developer
20 
21     Notes: Typical calling sequence
22        PetscLayoutCreate(MPI_Comm,PetscLayout *);
23        PetscLayoutSetBlockSize(PetscLayout,1);
24        PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N);
25        PetscLayoutSetUp(PetscLayout);
26        Optionally use any of the following:
27           PetscLayoutGetSize(PetscLayout,PetscInt *); or PetscLayoutGetLocalSize(PetscLayout,PetscInt *;)
28           PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend); or PetscLayoutGetRanges(PetscLayout,const PetscInt *range[])
29        PetscLayoutDestroy(PetscLayout);
30 
31       The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
32       user codes unless you really gain something in their use.
33 
34     Fortran Notes:
35       Not available from Fortran
36 
37 .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
38           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
39 
40 @*/
41 PetscErrorCode  PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
42 {
43   PetscErrorCode ierr;
44 
45   PetscFunctionBegin;
46   ierr = PetscNew(struct _n_PetscLayout,map);CHKERRQ(ierr);
47 
48   (*map)->comm   = comm;
49   (*map)->bs     = -1;
50   (*map)->n      = -1;
51   (*map)->N      = -1;
52   (*map)->range  = 0;
53   (*map)->rstart = 0;
54   (*map)->rend   = 0;
55   (*map)->trstarts = 0;
56   PetscFunctionReturn(0);
57 }
58 
59 /*@C
60      PetscLayoutDestroy - Frees a map object and frees its range if that exists.
61 
62     Collective on MPI_Comm
63 
64    Input Parameters:
65 .    map - the PetscLayout
66 
67    Level: developer
68 
69       The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
70       recommended they not be used in user codes unless you really gain something in their use.
71 
72     Fortran Notes:
73       Not available from Fortran
74 
75 .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
76           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
77 
78 @*/
79 #undef __FUNCT__
80 #define __FUNCT__ "PetscLayoutDestroy"
81 PetscErrorCode  PetscLayoutDestroy(PetscLayout *map)
82 {
83   PetscErrorCode ierr;
84 
85   PetscFunctionBegin;
86   if (!*map) PetscFunctionReturn(0);
87   if (!(*map)->refcnt--) {
88     ierr = PetscFree((*map)->range);CHKERRQ(ierr);
89     ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr);
90     ierr = ISLocalToGlobalMappingDestroy(&(*map)->bmapping);CHKERRQ(ierr);
91 #if defined(PETSC_THREADCOMM_ACTIVE)
92     ierr = PetscFree((*map)->trstarts);CHKERRQ(ierr);
93 #endif
94 
95     ierr = PetscFree((*map));CHKERRQ(ierr);
96   }
97   *map = NULL;
98   PetscFunctionReturn(0);
99 }
100 
101 /*@C
102      PetscLayoutSetUp - given a map where you have set either the global or local
103            size sets up the map so that it may be used.
104 
105     Collective on MPI_Comm
106 
107    Input Parameters:
108 .    map - pointer to the map
109 
110    Level: developer
111 
112     Notes: Typical calling sequence
113        PetscLayoutCreate(MPI_Comm,PetscLayout *);
114        PetscLayoutSetBlockSize(PetscLayout,1);
115        PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
116        PetscLayoutSetUp(PetscLayout);
117        PetscLayoutGetSize(PetscLayout,PetscInt *);
118 
119 
120        If the local size, global size are already set and range exists then this does nothing.
121 
122     Fortran Notes:
123       Not available from Fortran
124 
125 .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
126           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
127 
128 @*/
129 #undef __FUNCT__
130 #define __FUNCT__ "PetscLayoutSetUp"
131 PetscErrorCode  PetscLayoutSetUp(PetscLayout map)
132 {
133   PetscMPIInt    rank,size;
134   PetscInt       p;
135   PetscErrorCode ierr;
136 
137   PetscFunctionBegin;
138   if (map->bs <= 0) map->bs = 1;
139   if ((map->n >= 0) && (map->N >= 0) && (map->range)) PetscFunctionReturn(0);
140 
141   ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr);
142   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr);
143   if (map->n > 0) map->n = map->n/map->bs;
144   if (map->N > 0) map->N = map->N/map->bs;
145   ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr);
146   map->n = map->n*map->bs;
147   map->N = map->N*map->bs;
148   if (!map->range) {
149     ierr = PetscMalloc((size+1)*sizeof(PetscInt), &map->range);CHKERRQ(ierr);
150   }
151   ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr);
152 
153   map->range[0] = 0;
154   for (p = 2; p <= size; p++) map->range[p] += map->range[p-1];
155 
156   map->rstart = map->range[rank];
157   map->rend   = map->range[rank+1];
158 #if defined(PETSC_THREADCOMM_ACTIVE)
159   /* Set the thread ownership ranges */
160   ierr = PetscThreadCommGetOwnershipRanges(map->comm,map->n,&map->trstarts);CHKERRQ(ierr);
161 #endif
162   PetscFunctionReturn(0);
163 }
164 
165 #undef __FUNCT__
166 #define __FUNCT__ "PetscLayoutDuplicate"
167 /*@C
168 
169     PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
170 
171      Collective on PetscLayout
172 
173     Input Parameter:
174 .     in - input PetscLayout to be duplicated
175 
176     Output Parameter:
177 .     out - the copy
178 
179    Level: developer
180 
181     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
182 
183 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
184 
185 @*/
186 PetscErrorCode  PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
187 {
188   PetscMPIInt    size;
189   PetscErrorCode ierr;
190   MPI_Comm       comm = in->comm;
191 
192   PetscFunctionBegin;
193   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
194   ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr);
195   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
196   ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr);
197   ierr = PetscMalloc((size+1)*sizeof(PetscInt),&(*out)->range);CHKERRQ(ierr);
198   ierr = PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));CHKERRQ(ierr);
199 
200   (*out)->refcnt = 0;
201   PetscFunctionReturn(0);
202 }
203 
204 #undef __FUNCT__
205 #define __FUNCT__ "PetscLayoutReference"
206 /*@C
207 
208     PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
209 
210      Collective on PetscLayout
211 
212     Input Parameter:
213 .     in - input PetscLayout to be copied
214 
215     Output Parameter:
216 .     out - the reference location
217 
218    Level: developer
219 
220     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
221 
222     If the out location already contains a PetscLayout it is destroyed
223 
224 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
225 
226 @*/
227 PetscErrorCode  PetscLayoutReference(PetscLayout in,PetscLayout *out)
228 {
229   PetscErrorCode ierr;
230 
231   PetscFunctionBegin;
232   in->refcnt++;
233   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
234   *out = in;
235   PetscFunctionReturn(0);
236 }
237 
238 #undef __FUNCT__
239 #define __FUNCT__ "PetscLayoutSetISLocalToGlobalMapping"
240 /*@C
241 
242     PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
243 
244      Collective on PetscLayout
245 
246     Input Parameter:
247 +     in - input PetscLayout
248 -     ltog - the local to global mapping
249 
250 
251    Level: developer
252 
253     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
254 
255     If the ltog location already contains a PetscLayout it is destroyed
256 
257 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()
258 
259 @*/
260 PetscErrorCode  PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
261 {
262   PetscErrorCode ierr;
263 
264   PetscFunctionBegin;
265   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
266   ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr);
267 
268   in->mapping = ltog;
269   PetscFunctionReturn(0);
270 }
271 
272 #undef __FUNCT__
273 #define __FUNCT__ "PetscLayoutSetISLocalToGlobalMappingBlock"
274 /*@C
275 
276     PetscLayoutSetISLocalToGlobalMappingBlock - sets a ISLocalGlobalMapping into a PetscLayout
277 
278      Collective on PetscLayout
279 
280     Input Parameter:
281 +     in - input PetscLayout
282 -     ltog - the local to global block mapping
283 
284 
285    Level: developer
286 
287     Notes: PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
288 
289     If the ltog location already contains a PetscLayout it is destroyed
290 
291 .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate(), PetscLayoutSetLocalToGlobalMappingBlock()
292 
293 @*/
294 PetscErrorCode  PetscLayoutSetISLocalToGlobalMappingBlock(PetscLayout in,ISLocalToGlobalMapping ltog)
295 {
296   PetscErrorCode ierr;
297 
298   PetscFunctionBegin;
299   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
300   ierr = ISLocalToGlobalMappingDestroy(&in->bmapping);CHKERRQ(ierr);
301 
302   in->bmapping = ltog;
303   PetscFunctionReturn(0);
304 }
305 
306 /*@C
307      PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
308 
309     Collective on PetscLayout
310 
311    Input Parameters:
312 +    map - pointer to the map
313 -    n - the local size
314 
315    Level: developer
316 
317     Notes:
318        Call this after the call to PetscLayoutCreate()
319 
320     Fortran Notes:
321       Not available from Fortran
322 
323 .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
324           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
325 
326 @*/
327 #undef __FUNCT__
328 #define __FUNCT__ "PetscLayoutSetLocalSize"
329 PetscErrorCode  PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
330 {
331   PetscFunctionBegin;
332   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);
333   map->n = n;
334   PetscFunctionReturn(0);
335 }
336 
337 /*@C
338      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
339 
340     Not Collective
341 
342    Input Parameters:
343 .    map - pointer to the map
344 
345    Output Parameters:
346 .    n - the local size
347 
348    Level: developer
349 
350     Notes:
351        Call this after the call to PetscLayoutSetUp()
352 
353     Fortran Notes:
354       Not available from Fortran
355 
356 .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
357           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
358 
359 @*/
360 #undef __FUNCT__
361 #define __FUNCT__ "PetscLayoutGetLocalSize"
362 PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
363 {
364   PetscFunctionBegin;
365   *n = map->n;
366   PetscFunctionReturn(0);
367 }
368 
369 /*@C
370      PetscLayoutSetSize - Sets the global size for a PetscLayout object.
371 
372     Logically Collective on PetscLayout
373 
374    Input Parameters:
375 +    map - pointer to the map
376 -    n - the global size
377 
378    Level: developer
379 
380     Notes:
381        Call this after the call to PetscLayoutCreate()
382 
383     Fortran Notes:
384       Not available from Fortran
385 
386 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
387           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
388 
389 @*/
390 #undef __FUNCT__
391 #define __FUNCT__ "PetscLayoutSetSize"
392 PetscErrorCode  PetscLayoutSetSize(PetscLayout map,PetscInt n)
393 {
394   PetscFunctionBegin;
395   map->N = n;
396   PetscFunctionReturn(0);
397 }
398 
399 /*@C
400      PetscLayoutGetSize - Gets the global size for a PetscLayout object.
401 
402     Not Collective
403 
404    Input Parameters:
405 .    map - pointer to the map
406 
407    Output Parameters:
408 .    n - the global size
409 
410    Level: developer
411 
412     Notes:
413        Call this after the call to PetscLayoutSetUp()
414 
415     Fortran Notes:
416       Not available from Fortran
417 
418 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
419           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
420 
421 @*/
422 #undef __FUNCT__
423 #define __FUNCT__ "PetscLayoutGetSize"
424 PetscErrorCode  PetscLayoutGetSize(PetscLayout map,PetscInt *n)
425 {
426   PetscFunctionBegin;
427   *n = map->N;
428   PetscFunctionReturn(0);
429 }
430 
431 /*@C
432      PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
433 
434     Logically Collective on PetscLayout
435 
436    Input Parameters:
437 +    map - pointer to the map
438 -    bs - the size
439 
440    Level: developer
441 
442     Notes:
443        Call this after the call to PetscLayoutCreate()
444 
445     Fortran Notes:
446       Not available from Fortran
447 
448 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
449           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
450 
451 @*/
452 #undef __FUNCT__
453 #define __FUNCT__ "PetscLayoutSetBlockSize"
454 PetscErrorCode  PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
455 {
456   PetscFunctionBegin;
457   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);
458   if (map->bs > 0 && map->bs != bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Cannot change block size %D to %D",map->bs,bs);
459   map->bs = bs;
460   PetscFunctionReturn(0);
461 }
462 
463 /*@C
464      PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
465 
466     Not Collective
467 
468    Input Parameters:
469 .    map - pointer to the map
470 
471    Output Parameters:
472 .    bs - the size
473 
474    Level: developer
475 
476     Notes:
477        Call this after the call to PetscLayoutSetUp()
478 
479     Fortran Notes:
480       Not available from Fortran
481 
482 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
483           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
484 
485 @*/
486 #undef __FUNCT__
487 #define __FUNCT__ "PetscLayoutGetBlockSize"
488 PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
489 {
490   PetscFunctionBegin;
491   *bs = map->bs;
492   PetscFunctionReturn(0);
493 }
494 
495 
496 /*@C
497      PetscLayoutGetRange - gets the range of values owned by this process
498 
499     Not Collective
500 
501    Input Parameters:
502 .    map - pointer to the map
503 
504    Output Parameters:
505 +    rstart - first index owned by this process
506 -    rend - one more than the last index owned by this process
507 
508    Level: developer
509 
510     Notes:
511        Call this after the call to PetscLayoutSetUp()
512 
513     Fortran Notes:
514       Not available from Fortran
515 
516 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
517           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
518 
519 @*/
520 #undef __FUNCT__
521 #define __FUNCT__ "PetscLayoutGetRange"
522 PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
523 {
524   PetscFunctionBegin;
525   if (rstart) *rstart = map->rstart;
526   if (rend)   *rend   = map->rend;
527   PetscFunctionReturn(0);
528 }
529 
530 /*@C
531      PetscLayoutGetRanges - gets the range of values owned by all processes
532 
533     Not Collective
534 
535    Input Parameters:
536 .    map - pointer to the map
537 
538    Output Parameters:
539 .    range - start of each processors range of indices (the final entry is one more then the
540              last index on the last process)
541 
542    Level: developer
543 
544     Notes:
545        Call this after the call to PetscLayoutSetUp()
546 
547     Fortran Notes:
548       Not available from Fortran
549 
550 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
551           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
552 
553 @*/
554 #undef __FUNCT__
555 #define __FUNCT__ "PetscLayoutGetRanges"
556 PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
557 {
558   PetscFunctionBegin;
559   *range = map->range;
560   PetscFunctionReturn(0);
561 }
562 
563 #undef __FUNCT__
564 #define __FUNCT__ "PetscSFSetGraphLayout"
565 /*@C
566    PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
567 
568    Collective
569 
570    Input Arguments:
571 +  sf - star forest
572 .  layout - PetscLayout defining the global space
573 .  nleaves - number of leaf vertices on the current process, each of these references a root on any process
574 .  ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
575 -  iremote - remote locations of root vertices for each leaf on the current process
576 
577    Level: intermediate
578 
579 .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
580 @*/
581 PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
582 {
583   PetscErrorCode ierr;
584   PetscInt       i,nroots;
585   PetscSFNode    *remote;
586 
587   PetscFunctionBegin;
588   ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr);
589   ierr = PetscMalloc(nleaves*sizeof(PetscSFNode),&remote);CHKERRQ(ierr);
590   for (i=0; i<nleaves; i++) {
591     PetscInt owner = -1;
592     ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr);
593     remote[i].rank  = owner;
594     remote[i].index = iremote[i] - layout->range[owner];
595   }
596   ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr);
597   PetscFunctionReturn(0);
598 }
599 
600