xref: /petsc/src/vec/is/utils/pmap.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
169ce434fSBarry Smith 
269ce434fSBarry Smith /*
369ce434fSBarry Smith    This file contains routines for basic map object implementation.
469ce434fSBarry Smith */
569ce434fSBarry Smith 
657e2745dSVaclav Hapla #include <petsc/private/isimpl.h> /*I "petscis.h" I*/
75c25fcd7SBarry Smith 
8c3002683SMatthew G. Knepley /*@
9a8643c1eSVaclav Hapla   PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default.
1069ce434fSBarry Smith 
11d083f849SBarry Smith   Collective
1269ce434fSBarry Smith 
1369ce434fSBarry Smith   Input Parameters:
14a8643c1eSVaclav Hapla . comm - the MPI communicator
15a8643c1eSVaclav Hapla 
16a8643c1eSVaclav Hapla   Output Parameters:
17a8643c1eSVaclav Hapla . map - the new PetscLayout
1869ce434fSBarry Smith 
19456fcb79SJed Brown   Level: advanced
2069ce434fSBarry Smith 
21456fcb79SJed Brown   Notes:
22456fcb79SJed Brown   Typical calling sequence
23456fcb79SJed Brown .vb
2469ce434fSBarry Smith        PetscLayoutCreate(MPI_Comm,PetscLayout *);
25a8643c1eSVaclav Hapla        PetscLayoutSetBlockSize(PetscLayout,bs);
26a8643c1eSVaclav Hapla        PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n);
2769ce434fSBarry Smith        PetscLayoutSetUp(PetscLayout);
28456fcb79SJed Brown .ve
299621ec18SVaclav Hapla   Alternatively,
30147403d9SBarry Smith .vb
31147403d9SBarry Smith       PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
32147403d9SBarry Smith .ve
339621ec18SVaclav Hapla 
34147403d9SBarry Smith   Optionally use any of the following
35147403d9SBarry Smith .vb
36147403d9SBarry Smith   PetscLayoutGetSize(PetscLayout,PetscInt *);
37147403d9SBarry Smith   PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
38147403d9SBarry Smith   PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
39147403d9SBarry Smith   PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
40147403d9SBarry Smith   PetscLayoutDestroy(PetscLayout*);
41147403d9SBarry Smith .ve
4269ce434fSBarry Smith 
436aad120cSJose E. Roman   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementations; it is often not needed in
4469ce434fSBarry Smith   user codes unless you really gain something in their use.
4569ce434fSBarry Smith 
46db781477SPatrick Sanan .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
47db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`,
48db781477SPatrick Sanan           `PetscLayoutCreateFromSizes()`
4969ce434fSBarry Smith 
5069ce434fSBarry Smith @*/
519371c9d4SSatish Balay PetscErrorCode PetscLayoutCreate(MPI_Comm comm, PetscLayout *map) {
5269ce434fSBarry Smith   PetscFunctionBegin;
539566063dSJacob Faibussowitsch   PetscCall(PetscNew(map));
549566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &(*map)->size));
5569ce434fSBarry Smith   (*map)->comm        = comm;
5669ce434fSBarry Smith   (*map)->bs          = -1;
5769ce434fSBarry Smith   (*map)->n           = -1;
5869ce434fSBarry Smith   (*map)->N           = -1;
59f92d6284SStefano Zampini   (*map)->range       = NULL;
609621ec18SVaclav Hapla   (*map)->range_alloc = PETSC_TRUE;
6169ce434fSBarry Smith   (*map)->rstart      = 0;
6269ce434fSBarry Smith   (*map)->rend        = 0;
63ca5434daSLawrence Mitchell   (*map)->setupcalled = PETSC_FALSE;
64ca5434daSLawrence Mitchell   (*map)->oldn        = -1;
65ca5434daSLawrence Mitchell   (*map)->oldN        = -1;
66ca5434daSLawrence Mitchell   (*map)->oldbs       = -1;
6769ce434fSBarry Smith   PetscFunctionReturn(0);
6869ce434fSBarry Smith }
6969ce434fSBarry Smith 
70c3002683SMatthew G. Knepley /*@
719621ec18SVaclav Hapla   PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up.
729621ec18SVaclav Hapla 
739621ec18SVaclav Hapla   Collective
749621ec18SVaclav Hapla 
759621ec18SVaclav Hapla   Input Parameters:
769621ec18SVaclav Hapla + comm  - the MPI communicator
779621ec18SVaclav Hapla . n     - the local size (or PETSC_DECIDE)
789621ec18SVaclav Hapla . N     - the global size (or PETSC_DECIDE)
79f0fc11ceSJed Brown - bs    - the block size (or PETSC_DECIDE)
809621ec18SVaclav Hapla 
819621ec18SVaclav Hapla   Output Parameters:
829621ec18SVaclav Hapla . map - the new PetscLayout
839621ec18SVaclav Hapla 
849621ec18SVaclav Hapla   Level: advanced
859621ec18SVaclav Hapla 
869621ec18SVaclav Hapla   Notes:
879621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
889621ec18SVaclav Hapla   is a shorthand for
899621ec18SVaclav Hapla .vb
909621ec18SVaclav Hapla   PetscLayoutCreate(comm,&layout);
919621ec18SVaclav Hapla   PetscLayoutSetLocalSize(layout,n);
929621ec18SVaclav Hapla   PetscLayoutSetSize(layout,N);
939621ec18SVaclav Hapla   PetscLayoutSetBlockSize(layout,bs);
949621ec18SVaclav Hapla   PetscLayoutSetUp(layout);
959621ec18SVaclav Hapla .ve
969621ec18SVaclav Hapla 
97db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
98db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()`
999621ec18SVaclav Hapla 
1009621ec18SVaclav Hapla @*/
1019371c9d4SSatish Balay PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map) {
1029621ec18SVaclav Hapla   PetscFunctionBegin;
1039566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, map));
1049566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetLocalSize(*map, n));
1059566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetSize(*map, N));
1069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(*map, bs));
1079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(*map));
1089621ec18SVaclav Hapla   PetscFunctionReturn(0);
1099621ec18SVaclav Hapla }
1109621ec18SVaclav Hapla 
1119621ec18SVaclav Hapla /*@
11269ce434fSBarry Smith   PetscLayoutDestroy - Frees a map object and frees its range if that exists.
11369ce434fSBarry Smith 
114d083f849SBarry Smith   Collective
11569ce434fSBarry Smith 
11669ce434fSBarry Smith   Input Parameters:
11769ce434fSBarry Smith . map - the PetscLayout
11869ce434fSBarry Smith 
11969ce434fSBarry Smith   Level: developer
12069ce434fSBarry Smith 
121c3002683SMatthew G. Knepley   Note:
1226aad120cSJose E. Roman   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementations; it is
12369ce434fSBarry Smith   recommended they not be used in user codes unless you really gain something in their use.
12469ce434fSBarry Smith 
125db781477SPatrick Sanan .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutCreate()`,
126db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`
12769ce434fSBarry Smith 
12869ce434fSBarry Smith @*/
1299371c9d4SSatish Balay PetscErrorCode PetscLayoutDestroy(PetscLayout *map) {
13069ce434fSBarry Smith   PetscFunctionBegin;
13169ce434fSBarry Smith   if (!*map) PetscFunctionReturn(0);
13269ce434fSBarry Smith   if (!(*map)->refcnt--) {
1339566063dSJacob Faibussowitsch     if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range));
1349566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping));
1359566063dSJacob Faibussowitsch     PetscCall(PetscFree((*map)));
13669ce434fSBarry Smith   }
13769ce434fSBarry Smith   *map = NULL;
13869ce434fSBarry Smith   PetscFunctionReturn(0);
13969ce434fSBarry Smith }
14069ce434fSBarry Smith 
1419621ec18SVaclav Hapla /*@
1429621ec18SVaclav Hapla   PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up.
1439621ec18SVaclav Hapla 
1449621ec18SVaclav Hapla   Collective
1459621ec18SVaclav Hapla 
1469621ec18SVaclav Hapla   Input Parameters:
1479621ec18SVaclav Hapla + comm  - the MPI communicator
1489621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1499621ec18SVaclav Hapla . mode  - the copy mode for range
1509621ec18SVaclav Hapla - bs    - the block size (or PETSC_DECIDE)
1519621ec18SVaclav Hapla 
1529621ec18SVaclav Hapla   Output Parameters:
1539621ec18SVaclav Hapla . newmap - the new PetscLayout
1549621ec18SVaclav Hapla 
1559621ec18SVaclav Hapla   Level: developer
1569621ec18SVaclav Hapla 
157db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
158db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()`
1599621ec18SVaclav Hapla 
1609621ec18SVaclav Hapla @*/
1619371c9d4SSatish Balay PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap) {
1629621ec18SVaclav Hapla   PetscLayout map;
16338a25198SStefano Zampini   PetscMPIInt rank;
1647b659617SVaclav Hapla 
1657b659617SVaclav Hapla   PetscFunctionBegin;
1669566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1679566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, &map));
1689566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(map, bs));
1699621ec18SVaclav Hapla   switch (mode) {
1709621ec18SVaclav Hapla   case PETSC_COPY_VALUES:
1719566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(map->size + 1, &map->range));
1729566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(map->range, range, map->size + 1));
1739621ec18SVaclav Hapla     break;
1749371c9d4SSatish Balay   case PETSC_USE_POINTER: map->range_alloc = PETSC_FALSE;
1759371c9d4SSatish Balay   default: map->range = (PetscInt *)range; break;
1769621ec18SVaclav Hapla   }
1777b659617SVaclav Hapla   map->rstart = map->range[rank];
1787b659617SVaclav Hapla   map->rend   = map->range[rank + 1];
1797b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
18038a25198SStefano Zampini   map->N      = map->range[map->size];
18176bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */
1827b659617SVaclav Hapla     PetscInt tmp;
1831c2dc1cbSBarry Smith     PetscCall(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm));
18408401ef6SPierre Jolivet     PetscCheck(tmp == map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Sum of local lengths %" PetscInt_FMT " does not equal global length %" PetscInt_FMT ", my local length %" PetscInt_FMT ".\nThe provided PetscLayout is wrong.", tmp, map->N, map->n);
1859371c9d4SSatish Balay     if (map->bs > 1) { PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs); }
1869371c9d4SSatish Balay     if (map->bs > 1) { PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs); }
18776bd3646SJed Brown   }
188ca5434daSLawrence Mitchell   /* lock the layout */
189ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
190ca5434daSLawrence Mitchell   map->oldn        = map->n;
191ca5434daSLawrence Mitchell   map->oldN        = map->N;
192ca5434daSLawrence Mitchell   map->oldbs       = map->bs;
1939621ec18SVaclav Hapla   *newmap          = map;
1947b659617SVaclav Hapla   PetscFunctionReturn(0);
1957b659617SVaclav Hapla }
1967b659617SVaclav Hapla 
197c3002683SMatthew G. Knepley /*@
19869ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
19969ce434fSBarry Smith                      size sets up the map so that it may be used.
20069ce434fSBarry Smith 
201d083f849SBarry Smith   Collective
20269ce434fSBarry Smith 
20369ce434fSBarry Smith   Input Parameters:
20469ce434fSBarry Smith . map - pointer to the map
20569ce434fSBarry Smith 
20669ce434fSBarry Smith   Level: developer
20769ce434fSBarry Smith 
20895452b02SPatrick Sanan   Notes:
20995452b02SPatrick Sanan     Typical calling sequence
210c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *);
211c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1);
212c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
213c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout);
214c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *);
21569ce434fSBarry Smith 
2167b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
21769ce434fSBarry Smith 
21869ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
21969ce434fSBarry Smith 
220db781477SPatrick Sanan .seealso: `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
221f1f2ae84SBarry Smith           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()`
22269ce434fSBarry Smith @*/
2239371c9d4SSatish Balay PetscErrorCode PetscLayoutSetUp(PetscLayout map) {
22438a25198SStefano Zampini   PetscMPIInt rank;
22569ce434fSBarry Smith   PetscInt    p;
22669ce434fSBarry Smith 
22769ce434fSBarry Smith   PetscFunctionBegin;
2289371c9d4SSatish Balay   PetscCheck(!map->setupcalled || !(map->n != map->oldn || map->N != map->oldN), map->comm, PETSC_ERR_ARG_WRONGSTATE, "Layout is already setup with (local=%" PetscInt_FMT ",global=%" PetscInt_FMT "), cannot call setup again with (local=%" PetscInt_FMT ",global=%" PetscInt_FMT ")",
2299371c9d4SSatish Balay              map->oldn, map->oldN, map->n, map->N);
230ca5434daSLawrence Mitchell   if (map->setupcalled) PetscFunctionReturn(0);
23169ce434fSBarry Smith 
2329371c9d4SSatish Balay   if (map->n > 0 && map->bs > 1) { PetscCheck(map->n % map->bs == 0, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->n, map->bs); }
2339371c9d4SSatish Balay   if (map->N > 0 && map->bs > 1) { PetscCheck(map->N % map->bs == 0, map->comm, PETSC_ERR_PLIB, "Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT, map->N, map->bs); }
234b146b01cSBarry Smith 
2359566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(map->comm, &rank));
23633d57670SJed Brown   if (map->n > 0) map->n = map->n / PetscAbs(map->bs);
23733d57670SJed Brown   if (map->N > 0) map->N = map->N / PetscAbs(map->bs);
2389566063dSJacob Faibussowitsch   PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N));
23933d57670SJed Brown   map->n = map->n * PetscAbs(map->bs);
24033d57670SJed Brown   map->N = map->N * PetscAbs(map->bs);
241*48a46eb9SPierre Jolivet   if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range));
2429566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm));
24369ce434fSBarry Smith 
24469ce434fSBarry Smith   map->range[0] = 0;
24538a25198SStefano Zampini   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1];
24669ce434fSBarry Smith 
24769ce434fSBarry Smith   map->rstart = map->range[rank];
24869ce434fSBarry Smith   map->rend   = map->range[rank + 1];
249ca5434daSLawrence Mitchell 
250ca5434daSLawrence Mitchell   /* lock the layout */
251ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
252ca5434daSLawrence Mitchell   map->oldn        = map->n;
253ca5434daSLawrence Mitchell   map->oldN        = map->N;
254ca5434daSLawrence Mitchell   map->oldbs       = map->bs;
25569ce434fSBarry Smith   PetscFunctionReturn(0);
25669ce434fSBarry Smith }
25769ce434fSBarry Smith 
258c3002683SMatthew G. Knepley /*@
25969ce434fSBarry Smith   PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
26069ce434fSBarry Smith 
26169ce434fSBarry Smith   Collective on PetscLayout
26269ce434fSBarry Smith 
26369ce434fSBarry Smith   Input Parameter:
26469ce434fSBarry Smith . in - input PetscLayout to be duplicated
26569ce434fSBarry Smith 
26669ce434fSBarry Smith   Output Parameter:
26769ce434fSBarry Smith . out - the copy
26869ce434fSBarry Smith 
26969ce434fSBarry Smith   Level: developer
27069ce434fSBarry Smith 
27195452b02SPatrick Sanan   Notes:
27295452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
27369ce434fSBarry Smith 
274db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()`
27569ce434fSBarry Smith @*/
2769371c9d4SSatish Balay PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out) {
27769ce434fSBarry Smith   MPI_Comm comm = in->comm;
27869ce434fSBarry Smith 
27969ce434fSBarry Smith   PetscFunctionBegin;
2809566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(out));
2819566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, out));
2829566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout)));
283c168f6d8SVaclav Hapla   if (in->range) {
2849566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range));
2859566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1));
286c168f6d8SVaclav Hapla   }
28769ce434fSBarry Smith   (*out)->refcnt = 0;
28869ce434fSBarry Smith   PetscFunctionReturn(0);
28969ce434fSBarry Smith }
29069ce434fSBarry Smith 
291c3002683SMatthew G. Knepley /*@
29269ce434fSBarry Smith   PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
29369ce434fSBarry Smith 
29469ce434fSBarry Smith   Collective on PetscLayout
29569ce434fSBarry Smith 
29669ce434fSBarry Smith   Input Parameter:
29769ce434fSBarry Smith . in - input PetscLayout to be copied
29869ce434fSBarry Smith 
29969ce434fSBarry Smith   Output Parameter:
30069ce434fSBarry Smith . out - the reference location
30169ce434fSBarry Smith 
30269ce434fSBarry Smith   Level: developer
30369ce434fSBarry Smith 
30495452b02SPatrick Sanan   Notes:
30595452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
30669ce434fSBarry Smith 
30769ce434fSBarry Smith   If the out location already contains a PetscLayout it is destroyed
30869ce434fSBarry Smith 
309db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
31069ce434fSBarry Smith @*/
3119371c9d4SSatish Balay PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out) {
31269ce434fSBarry Smith   PetscFunctionBegin;
31369ce434fSBarry Smith   in->refcnt++;
3149566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(out));
31569ce434fSBarry Smith   *out = in;
31669ce434fSBarry Smith   PetscFunctionReturn(0);
31769ce434fSBarry Smith }
31869ce434fSBarry Smith 
319c3002683SMatthew G. Knepley /*@
32069ce434fSBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
32169ce434fSBarry Smith 
32269ce434fSBarry Smith   Collective on PetscLayout
32369ce434fSBarry Smith 
324d8d19677SJose E. Roman   Input Parameters:
32569ce434fSBarry Smith + in - input PetscLayout
32669ce434fSBarry Smith - ltog - the local to global mapping
32769ce434fSBarry Smith 
32869ce434fSBarry Smith   Level: developer
32969ce434fSBarry Smith 
33095452b02SPatrick Sanan   Notes:
33195452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
33269ce434fSBarry Smith 
33369ce434fSBarry Smith   If the ltog location already contains a PetscLayout it is destroyed
33469ce434fSBarry Smith 
335db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
33669ce434fSBarry Smith @*/
3379371c9d4SSatish Balay PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog) {
33869ce434fSBarry Smith   PetscFunctionBegin;
339fc989267SStefano Zampini   if (ltog) {
340fc989267SStefano Zampini     PetscInt bs;
341fc989267SStefano Zampini 
3429566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs));
343c9cc58a2SBarry Smith     PetscCheck(in->bs <= 0 || bs == 1 || in->bs == bs, in->comm, PETSC_ERR_PLIB, "Blocksize of layout %" PetscInt_FMT " must match that of mapping %" PetscInt_FMT " (or the latter must be 1)", in->bs, bs);
3449566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ltog));
345fc989267SStefano Zampini   }
3469566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping));
34769ce434fSBarry Smith   in->mapping = ltog;
34869ce434fSBarry Smith   PetscFunctionReturn(0);
34969ce434fSBarry Smith }
35069ce434fSBarry Smith 
351c3002683SMatthew G. Knepley /*@
35269ce434fSBarry Smith   PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
35369ce434fSBarry Smith 
35469ce434fSBarry Smith   Collective on PetscLayout
35569ce434fSBarry Smith 
35669ce434fSBarry Smith   Input Parameters:
35769ce434fSBarry Smith + map - pointer to the map
35869ce434fSBarry Smith - n - the local size
35969ce434fSBarry Smith 
36069ce434fSBarry Smith   Level: developer
36169ce434fSBarry Smith 
36269ce434fSBarry Smith   Notes:
36369ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
36469ce434fSBarry Smith 
365db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
366db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
36769ce434fSBarry Smith @*/
3689371c9d4SSatish Balay PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n) {
36969ce434fSBarry Smith   PetscFunctionBegin;
370c9cc58a2SBarry Smith   PetscCheck(map->bs <= 1 || (n % map->bs) == 0, map->comm, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, n, map->bs);
37169ce434fSBarry Smith   map->n = n;
37269ce434fSBarry Smith   PetscFunctionReturn(0);
37369ce434fSBarry Smith }
37469ce434fSBarry Smith 
3754ffacfe2SAlexis Marboeuf /*@
37669ce434fSBarry Smith      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
37769ce434fSBarry Smith 
37869ce434fSBarry Smith     Not Collective
37969ce434fSBarry Smith 
38069ce434fSBarry Smith    Input Parameters:
38169ce434fSBarry Smith .    map - pointer to the map
38269ce434fSBarry Smith 
38369ce434fSBarry Smith    Output Parameters:
38469ce434fSBarry Smith .    n - the local size
38569ce434fSBarry Smith 
38669ce434fSBarry Smith    Level: developer
38769ce434fSBarry Smith 
38869ce434fSBarry Smith     Notes:
38969ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
39069ce434fSBarry Smith 
39169ce434fSBarry Smith     Fortran Notes:
39269ce434fSBarry Smith       Not available from Fortran
39369ce434fSBarry Smith 
394db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
395db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
39669ce434fSBarry Smith 
39769ce434fSBarry Smith @*/
3989371c9d4SSatish Balay PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n) {
39969ce434fSBarry Smith   PetscFunctionBegin;
40069ce434fSBarry Smith   *n = map->n;
40169ce434fSBarry Smith   PetscFunctionReturn(0);
40269ce434fSBarry Smith }
40369ce434fSBarry Smith 
404c3002683SMatthew G. Knepley /*@
40569ce434fSBarry Smith   PetscLayoutSetSize - Sets the global size for a PetscLayout object.
40669ce434fSBarry Smith 
40769ce434fSBarry Smith   Logically Collective on PetscLayout
40869ce434fSBarry Smith 
40969ce434fSBarry Smith   Input Parameters:
41069ce434fSBarry Smith + map - pointer to the map
41169ce434fSBarry Smith - n - the global size
41269ce434fSBarry Smith 
41369ce434fSBarry Smith   Level: developer
41469ce434fSBarry Smith 
41569ce434fSBarry Smith   Notes:
41669ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
41769ce434fSBarry Smith 
418db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
419db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
42069ce434fSBarry Smith @*/
4219371c9d4SSatish Balay PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n) {
42269ce434fSBarry Smith   PetscFunctionBegin;
42369ce434fSBarry Smith   map->N = n;
42469ce434fSBarry Smith   PetscFunctionReturn(0);
42569ce434fSBarry Smith }
42669ce434fSBarry Smith 
427c3002683SMatthew G. Knepley /*@
42869ce434fSBarry Smith   PetscLayoutGetSize - Gets the global size for a PetscLayout object.
42969ce434fSBarry Smith 
43069ce434fSBarry Smith   Not Collective
43169ce434fSBarry Smith 
43269ce434fSBarry Smith   Input Parameters:
43369ce434fSBarry Smith . map - pointer to the map
43469ce434fSBarry Smith 
43569ce434fSBarry Smith   Output Parameters:
43669ce434fSBarry Smith . n - the global size
43769ce434fSBarry Smith 
43869ce434fSBarry Smith   Level: developer
43969ce434fSBarry Smith 
44069ce434fSBarry Smith   Notes:
44169ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
44269ce434fSBarry Smith 
443db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
444db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
44569ce434fSBarry Smith @*/
4469371c9d4SSatish Balay PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n) {
44769ce434fSBarry Smith   PetscFunctionBegin;
44869ce434fSBarry Smith   *n = map->N;
44969ce434fSBarry Smith   PetscFunctionReturn(0);
45069ce434fSBarry Smith }
45169ce434fSBarry Smith 
452c3002683SMatthew G. Knepley /*@
45369ce434fSBarry Smith   PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
45469ce434fSBarry Smith 
45569ce434fSBarry Smith   Logically Collective on PetscLayout
45669ce434fSBarry Smith 
45769ce434fSBarry Smith   Input Parameters:
45869ce434fSBarry Smith + map - pointer to the map
45969ce434fSBarry Smith - bs - the size
46069ce434fSBarry Smith 
46169ce434fSBarry Smith   Level: developer
46269ce434fSBarry Smith 
46369ce434fSBarry Smith   Notes:
46469ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
46569ce434fSBarry Smith 
466db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
467db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
46869ce434fSBarry Smith @*/
4699371c9d4SSatish Balay PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs) {
47069ce434fSBarry Smith   PetscFunctionBegin;
47169bbac97SJed Brown   if (bs < 0) PetscFunctionReturn(0);
472c9cc58a2SBarry Smith   PetscCheck(map->n <= 0 || (map->n % bs) == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, map->n, bs);
473565245c5SBarry Smith   if (map->mapping) {
474705e6b8bSstefano_zampini     PetscInt obs;
475565245c5SBarry Smith 
4769566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs));
477*48a46eb9SPierre Jolivet     if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs));
478705e6b8bSstefano_zampini   }
47969ce434fSBarry Smith   map->bs = bs;
48069ce434fSBarry Smith   PetscFunctionReturn(0);
48169ce434fSBarry Smith }
48269ce434fSBarry Smith 
483c3002683SMatthew G. Knepley /*@
48469ce434fSBarry Smith   PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
48569ce434fSBarry Smith 
48669ce434fSBarry Smith   Not Collective
48769ce434fSBarry Smith 
48869ce434fSBarry Smith   Input Parameters:
48969ce434fSBarry Smith . map - pointer to the map
49069ce434fSBarry Smith 
49169ce434fSBarry Smith   Output Parameters:
49269ce434fSBarry Smith . bs - the size
49369ce434fSBarry Smith 
49469ce434fSBarry Smith   Level: developer
49569ce434fSBarry Smith 
49669ce434fSBarry Smith   Notes:
49769ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
49869ce434fSBarry Smith 
499db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
500db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`
50169ce434fSBarry Smith @*/
5029371c9d4SSatish Balay PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs) {
50369ce434fSBarry Smith   PetscFunctionBegin;
50433d57670SJed Brown   *bs = PetscAbs(map->bs);
50569ce434fSBarry Smith   PetscFunctionReturn(0);
50669ce434fSBarry Smith }
50769ce434fSBarry Smith 
508c3002683SMatthew G. Knepley /*@
50969ce434fSBarry Smith   PetscLayoutGetRange - gets the range of values owned by this process
51069ce434fSBarry Smith 
51169ce434fSBarry Smith   Not Collective
51269ce434fSBarry Smith 
513f899ff85SJose E. Roman   Input Parameter:
51469ce434fSBarry Smith . map - pointer to the map
51569ce434fSBarry Smith 
51669ce434fSBarry Smith   Output Parameters:
51769ce434fSBarry Smith + rstart - first index owned by this process
51869ce434fSBarry Smith - rend   - one more than the last index owned by this process
51969ce434fSBarry Smith 
52069ce434fSBarry Smith   Level: developer
52169ce434fSBarry Smith 
52269ce434fSBarry Smith   Notes:
52369ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
52469ce434fSBarry Smith 
525db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
526db781477SPatrick Sanan           `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
52769ce434fSBarry Smith @*/
5289371c9d4SSatish Balay PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend) {
52969ce434fSBarry Smith   PetscFunctionBegin;
53069ce434fSBarry Smith   if (rstart) *rstart = map->rstart;
53169ce434fSBarry Smith   if (rend) *rend = map->rend;
53269ce434fSBarry Smith   PetscFunctionReturn(0);
53369ce434fSBarry Smith }
53469ce434fSBarry Smith 
53569ce434fSBarry Smith /*@C
53669ce434fSBarry Smith      PetscLayoutGetRanges - gets the range of values owned by all processes
53769ce434fSBarry Smith 
53869ce434fSBarry Smith     Not Collective
53969ce434fSBarry Smith 
54069ce434fSBarry Smith    Input Parameters:
54169ce434fSBarry Smith .    map - pointer to the map
54269ce434fSBarry Smith 
54369ce434fSBarry Smith    Output Parameters:
544c3b5f7baSPierre Jolivet .    range - start of each processors range of indices (the final entry is one more than the
54569ce434fSBarry Smith              last index on the last process)
54669ce434fSBarry Smith 
54769ce434fSBarry Smith    Level: developer
54869ce434fSBarry Smith 
54969ce434fSBarry Smith     Notes:
55069ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
55169ce434fSBarry Smith 
55269ce434fSBarry Smith     Fortran Notes:
55369ce434fSBarry Smith       Not available from Fortran
55469ce434fSBarry Smith 
555db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
556db781477SPatrick Sanan           `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
55769ce434fSBarry Smith 
55869ce434fSBarry Smith @*/
5599371c9d4SSatish Balay PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[]) {
56069ce434fSBarry Smith   PetscFunctionBegin;
56169ce434fSBarry Smith   *range = map->range;
56269ce434fSBarry Smith   PetscFunctionReturn(0);
56369ce434fSBarry Smith }
56469ce434fSBarry Smith 
565f92d6284SStefano Zampini /*@
566f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
567f92d6284SStefano Zampini 
568f92d6284SStefano Zampini   Not Collective
569f92d6284SStefano Zampini 
570f92d6284SStefano Zampini   Input Parameters:
571d11c674dSStefano Zampini + mapa - pointer to the first map
572f92d6284SStefano Zampini - mapb - pointer to the second map
573f92d6284SStefano Zampini 
574f92d6284SStefano Zampini   Output Parameters:
575f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise
576f92d6284SStefano Zampini 
577f92d6284SStefano Zampini   Level: beginner
578f92d6284SStefano Zampini 
579f92d6284SStefano Zampini   Notes:
580f92d6284SStefano Zampini 
581db781477SPatrick Sanan .seealso: `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
582db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
583f92d6284SStefano Zampini @*/
5849371c9d4SSatish Balay PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent) {
585f92d6284SStefano Zampini   PetscFunctionBegin;
586f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
587*48a46eb9SPierre Jolivet   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent));
588f92d6284SStefano Zampini   PetscFunctionReturn(0);
589f92d6284SStefano Zampini }
590