xref: /petsc/src/vec/is/utils/pmap.c (revision ff5033e020bfea91e1f5fd2c6c970922f9cc79c9)
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 (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   PetscFunctionReturn(0);
468 }
469 
470 /*@C
471      PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
472 
473     Not Collective
474 
475    Input Parameters:
476 .    map - pointer to the map
477 
478    Output Parameters:
479 .    bs - the size
480 
481    Level: developer
482 
483     Notes:
484        Call this after the call to PetscLayoutSetUp()
485 
486     Fortran Notes:
487       Not available from Fortran
488 
489 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
490           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
491 
492 @*/
493 #undef __FUNCT__
494 #define __FUNCT__ "PetscLayoutGetBlockSize"
495 PetscErrorCode  PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
496 {
497   PetscFunctionBegin;
498   *bs = map->bs;
499   PetscFunctionReturn(0);
500 }
501 
502 
503 /*@C
504      PetscLayoutGetRange - gets the range of values owned by this process
505 
506     Not Collective
507 
508    Input Parameters:
509 .    map - pointer to the map
510 
511    Output Parameters:
512 +    rstart - first index owned by this process
513 -    rend - one more than the last index owned by this process
514 
515    Level: developer
516 
517     Notes:
518        Call this after the call to PetscLayoutSetUp()
519 
520     Fortran Notes:
521       Not available from Fortran
522 
523 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
524           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
525 
526 @*/
527 #undef __FUNCT__
528 #define __FUNCT__ "PetscLayoutGetRange"
529 PetscErrorCode  PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
530 {
531   PetscFunctionBegin;
532   if (rstart) *rstart = map->rstart;
533   if (rend)   *rend   = map->rend;
534   PetscFunctionReturn(0);
535 }
536 
537 /*@C
538      PetscLayoutGetRanges - gets the range of values owned by all processes
539 
540     Not Collective
541 
542    Input Parameters:
543 .    map - pointer to the map
544 
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)
548 
549    Level: developer
550 
551     Notes:
552        Call this after the call to PetscLayoutSetUp()
553 
554     Fortran Notes:
555       Not available from Fortran
556 
557 .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
558           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
559 
560 @*/
561 #undef __FUNCT__
562 #define __FUNCT__ "PetscLayoutGetRanges"
563 PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
564 {
565   PetscFunctionBegin;
566   *range = map->range;
567   PetscFunctionReturn(0);
568 }
569 
570 #undef __FUNCT__
571 #define __FUNCT__ "PetscSFSetGraphLayout"
572 /*@C
573    PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
574 
575    Collective
576 
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
583 
584    Level: intermediate
585 
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 {
590   PetscErrorCode ierr;
591   PetscInt       i,nroots;
592   PetscSFNode    *remote;
593 
594   PetscFunctionBegin;
595   ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr);
596   ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr);
597   for (i=0; i<nleaves; i++) {
598     PetscInt owner = -1;
599     ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr);
600     remote[i].rank  = owner;
601     remote[i].index = iremote[i] - layout->range[owner];
602   }
603   ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr);
604   PetscFunctionReturn(0);
605 }
606 
607