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