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