xref: /petsc/src/vec/is/utils/pmap.c (revision 23e9620e96413bb85c73a2bb0682a0a769203c8d)
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 /*@
9cab54364SBarry Smith   PetscLayoutCreate - Allocates `PetscLayout` object
1069ce434fSBarry Smith 
11d083f849SBarry Smith   Collective
1269ce434fSBarry Smith 
1369ce434fSBarry Smith   Input Parameters:
14a8643c1eSVaclav Hapla . comm - the MPI communicator
15a8643c1eSVaclav Hapla 
16a8643c1eSVaclav Hapla   Output Parameters:
17cab54364SBarry Smith . 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 
43cab54364SBarry Smith   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 
46cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
47cab54364SBarry Smith           `PetscLayout`, `PetscLayoutDestroy()`,
48db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`,
49db781477SPatrick Sanan           `PetscLayoutCreateFromSizes()`
5069ce434fSBarry Smith @*/
51d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreate(MPI_Comm comm, PetscLayout *map)
52d71ae5a4SJacob Faibussowitsch {
5369ce434fSBarry Smith   PetscFunctionBegin;
549566063dSJacob Faibussowitsch   PetscCall(PetscNew(map));
559566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &(*map)->size));
5669ce434fSBarry Smith   (*map)->comm        = comm;
5769ce434fSBarry Smith   (*map)->bs          = -1;
5869ce434fSBarry Smith   (*map)->n           = -1;
5969ce434fSBarry Smith   (*map)->N           = -1;
60f92d6284SStefano Zampini   (*map)->range       = NULL;
619621ec18SVaclav Hapla   (*map)->range_alloc = PETSC_TRUE;
6269ce434fSBarry Smith   (*map)->rstart      = 0;
6369ce434fSBarry Smith   (*map)->rend        = 0;
64ca5434daSLawrence Mitchell   (*map)->setupcalled = PETSC_FALSE;
65ca5434daSLawrence Mitchell   (*map)->oldn        = -1;
66ca5434daSLawrence Mitchell   (*map)->oldN        = -1;
67ca5434daSLawrence Mitchell   (*map)->oldbs       = -1;
6869ce434fSBarry Smith   PetscFunctionReturn(0);
6969ce434fSBarry Smith }
7069ce434fSBarry Smith 
71c3002683SMatthew G. Knepley /*@
72cab54364SBarry Smith   PetscLayoutCreateFromSizes - Allocates `PetscLayout` object and sets the layout sizes, and sets the layout up.
739621ec18SVaclav Hapla 
749621ec18SVaclav Hapla   Collective
759621ec18SVaclav Hapla 
769621ec18SVaclav Hapla   Input Parameters:
779621ec18SVaclav Hapla + comm  - the MPI communicator
78cab54364SBarry Smith . n     - the local size (or `PETSC_DECIDE`)
79cab54364SBarry Smith . N     - the global size (or `PETSC_DECIDE`)
80cab54364SBarry Smith - bs    - the block size (or `PETSC_DECIDE`)
819621ec18SVaclav Hapla 
829621ec18SVaclav Hapla   Output Parameters:
83cab54364SBarry Smith . map - the new `PetscLayout`
849621ec18SVaclav Hapla 
859621ec18SVaclav Hapla   Level: advanced
869621ec18SVaclav Hapla 
87cab54364SBarry Smith   Note:
889621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
899621ec18SVaclav Hapla   is a shorthand for
909621ec18SVaclav Hapla .vb
919621ec18SVaclav Hapla   PetscLayoutCreate(comm,&layout);
929621ec18SVaclav Hapla   PetscLayoutSetLocalSize(layout,n);
939621ec18SVaclav Hapla   PetscLayoutSetSize(layout,N);
949621ec18SVaclav Hapla   PetscLayoutSetBlockSize(layout,bs);
959621ec18SVaclav Hapla   PetscLayoutSetUp(layout);
969621ec18SVaclav Hapla .ve
979621ec18SVaclav Hapla 
98cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
99db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()`
1009621ec18SVaclav Hapla @*/
101d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map)
102d71ae5a4SJacob Faibussowitsch {
1039621ec18SVaclav Hapla   PetscFunctionBegin;
1049566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, map));
1059566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetLocalSize(*map, n));
1069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetSize(*map, N));
1079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(*map, bs));
1089566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(*map));
1099621ec18SVaclav Hapla   PetscFunctionReturn(0);
1109621ec18SVaclav Hapla }
1119621ec18SVaclav Hapla 
1129621ec18SVaclav Hapla /*@
113cab54364SBarry Smith   PetscLayoutDestroy - Frees a `PetscLayout` object and frees its range if that exists.
11469ce434fSBarry Smith 
115d083f849SBarry Smith   Collective
11669ce434fSBarry Smith 
11769ce434fSBarry Smith   Input Parameters:
118cab54364SBarry Smith . map - the `PetscLayout`
11969ce434fSBarry Smith 
12069ce434fSBarry Smith   Level: developer
12169ce434fSBarry Smith 
122cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
123cab54364SBarry Smith           `PetscLayout`, `PetscLayoutCreate()`,
124db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`
12569ce434fSBarry Smith @*/
126d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
127d71ae5a4SJacob Faibussowitsch {
12869ce434fSBarry Smith   PetscFunctionBegin;
12969ce434fSBarry Smith   if (!*map) PetscFunctionReturn(0);
13069ce434fSBarry Smith   if (!(*map)->refcnt--) {
1319566063dSJacob Faibussowitsch     if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range));
1329566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping));
1339566063dSJacob Faibussowitsch     PetscCall(PetscFree((*map)));
13469ce434fSBarry Smith   }
13569ce434fSBarry Smith   *map = NULL;
13669ce434fSBarry Smith   PetscFunctionReturn(0);
13769ce434fSBarry Smith }
13869ce434fSBarry Smith 
1399621ec18SVaclav Hapla /*@
140cab54364SBarry Smith   PetscLayoutCreateFromRanges - Creates a new `PetscLayout` with the given ownership ranges and sets it up.
1419621ec18SVaclav Hapla 
1429621ec18SVaclav Hapla   Collective
1439621ec18SVaclav Hapla 
1449621ec18SVaclav Hapla   Input Parameters:
1459621ec18SVaclav Hapla + comm  - the MPI communicator
1469621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1479621ec18SVaclav Hapla . mode  - the copy mode for range
148cab54364SBarry Smith - bs    - the block size (or `PETSC_DECIDE`)
1499621ec18SVaclav Hapla 
1509621ec18SVaclav Hapla   Output Parameters:
151cab54364SBarry Smith . newmap - the new `PetscLayout`
1529621ec18SVaclav Hapla 
1539621ec18SVaclav Hapla   Level: developer
1549621ec18SVaclav Hapla 
155cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`,
156cab54364SBarry Smith           `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
157db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()`
1589621ec18SVaclav Hapla @*/
159d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap)
160d71ae5a4SJacob Faibussowitsch {
1619621ec18SVaclav Hapla   PetscLayout map;
16238a25198SStefano Zampini   PetscMPIInt rank;
1637b659617SVaclav Hapla 
1647b659617SVaclav Hapla   PetscFunctionBegin;
1659566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1669566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, &map));
1679566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(map, bs));
1689621ec18SVaclav Hapla   switch (mode) {
1699621ec18SVaclav Hapla   case PETSC_COPY_VALUES:
1709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(map->size + 1, &map->range));
1719566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(map->range, range, map->size + 1));
1729621ec18SVaclav Hapla     break;
173d71ae5a4SJacob Faibussowitsch   case PETSC_USE_POINTER:
174d71ae5a4SJacob Faibussowitsch     map->range_alloc = PETSC_FALSE;
175d71ae5a4SJacob Faibussowitsch     break;
176d71ae5a4SJacob Faibussowitsch   default:
177d71ae5a4SJacob Faibussowitsch     map->range = (PetscInt *)range;
178d71ae5a4SJacob Faibussowitsch     break;
1799621ec18SVaclav Hapla   }
1807b659617SVaclav Hapla   map->rstart = map->range[rank];
1817b659617SVaclav Hapla   map->rend   = map->range[rank + 1];
1827b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
18338a25198SStefano Zampini   map->N      = map->range[map->size];
18476bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */
1857b659617SVaclav Hapla     PetscInt tmp;
1861c2dc1cbSBarry Smith     PetscCall(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm));
18708401ef6SPierre 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);
188ad540459SPierre Jolivet     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);
189ad540459SPierre Jolivet     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);
19076bd3646SJed Brown   }
191ca5434daSLawrence Mitchell   /* lock the layout */
192ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
193ca5434daSLawrence Mitchell   map->oldn        = map->n;
194ca5434daSLawrence Mitchell   map->oldN        = map->N;
195ca5434daSLawrence Mitchell   map->oldbs       = map->bs;
1969621ec18SVaclav Hapla   *newmap          = map;
1977b659617SVaclav Hapla   PetscFunctionReturn(0);
1987b659617SVaclav Hapla }
1997b659617SVaclav Hapla 
200c3002683SMatthew G. Knepley /*@
20169ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
20269ce434fSBarry Smith                      size sets up the map so that it may be used.
20369ce434fSBarry Smith 
204d083f849SBarry Smith   Collective
20569ce434fSBarry Smith 
20669ce434fSBarry Smith   Input Parameters:
20769ce434fSBarry Smith . map - pointer to the map
20869ce434fSBarry Smith 
20969ce434fSBarry Smith   Level: developer
21069ce434fSBarry Smith 
21195452b02SPatrick Sanan   Notes:
21295452b02SPatrick Sanan     Typical calling sequence
213cab54364SBarry Smith .vb
214cab54364SBarry Smith   PetscLayoutCreate(MPI_Comm,PetscLayout *);
215cab54364SBarry Smith   PetscLayoutSetBlockSize(PetscLayout,1);
216cab54364SBarry Smith   PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
217cab54364SBarry Smith   PetscLayoutSetUp(PetscLayout);
218cab54364SBarry Smith   PetscLayoutGetSize(PetscLayout,PetscInt *);
219cab54364SBarry Smith .ve
22069ce434fSBarry Smith 
2217b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
22269ce434fSBarry Smith 
22369ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
22469ce434fSBarry Smith 
225cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
226cab54364SBarry Smith           `PetscLayout`, `PetscLayoutDestroy()`,
227f1f2ae84SBarry Smith           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()`
22869ce434fSBarry Smith @*/
229d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetUp(PetscLayout map)
230d71ae5a4SJacob Faibussowitsch {
23138a25198SStefano Zampini   PetscMPIInt rank;
23269ce434fSBarry Smith   PetscInt    p;
23369ce434fSBarry Smith 
23469ce434fSBarry Smith   PetscFunctionBegin;
2359371c9d4SSatish 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 ")",
2369371c9d4SSatish Balay              map->oldn, map->oldN, map->n, map->N);
237ca5434daSLawrence Mitchell   if (map->setupcalled) PetscFunctionReturn(0);
23869ce434fSBarry Smith 
239ad540459SPierre Jolivet   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);
240ad540459SPierre Jolivet   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);
241b146b01cSBarry Smith 
2429566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(map->comm, &rank));
24333d57670SJed Brown   if (map->n > 0) map->n = map->n / PetscAbs(map->bs);
24433d57670SJed Brown   if (map->N > 0) map->N = map->N / PetscAbs(map->bs);
2459566063dSJacob Faibussowitsch   PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N));
24633d57670SJed Brown   map->n = map->n * PetscAbs(map->bs);
24733d57670SJed Brown   map->N = map->N * PetscAbs(map->bs);
24848a46eb9SPierre Jolivet   if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range));
2499566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm));
25069ce434fSBarry Smith 
25169ce434fSBarry Smith   map->range[0] = 0;
25238a25198SStefano Zampini   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1];
25369ce434fSBarry Smith 
25469ce434fSBarry Smith   map->rstart = map->range[rank];
25569ce434fSBarry Smith   map->rend   = map->range[rank + 1];
256ca5434daSLawrence Mitchell 
257ca5434daSLawrence Mitchell   /* lock the layout */
258ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
259ca5434daSLawrence Mitchell   map->oldn        = map->n;
260ca5434daSLawrence Mitchell   map->oldN        = map->N;
261ca5434daSLawrence Mitchell   map->oldbs       = map->bs;
26269ce434fSBarry Smith   PetscFunctionReturn(0);
26369ce434fSBarry Smith }
26469ce434fSBarry Smith 
265c3002683SMatthew G. Knepley /*@
266cab54364SBarry Smith   PetscLayoutDuplicate - creates a new `PetscLayout` with the same information as a given one. If the `PetscLayout` already exists it is destroyed first.
26769ce434fSBarry Smith 
268c3339decSBarry Smith   Collective
26969ce434fSBarry Smith 
27069ce434fSBarry Smith   Input Parameter:
271cab54364SBarry Smith . in - input `PetscLayout` to be duplicated
27269ce434fSBarry Smith 
27369ce434fSBarry Smith   Output Parameter:
27469ce434fSBarry Smith . out - the copy
27569ce434fSBarry Smith 
27669ce434fSBarry Smith   Level: developer
27769ce434fSBarry Smith 
278cab54364SBarry Smith   Note:
279cab54364SBarry Smith     `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
28069ce434fSBarry Smith 
281cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()`
28269ce434fSBarry Smith @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out)
284d71ae5a4SJacob Faibussowitsch {
28569ce434fSBarry Smith   MPI_Comm comm = in->comm;
28669ce434fSBarry Smith 
28769ce434fSBarry Smith   PetscFunctionBegin;
2889566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(out));
2899566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, out));
2909566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout)));
291c168f6d8SVaclav Hapla   if (in->range) {
2929566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range));
2939566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1));
294c168f6d8SVaclav Hapla   }
29569ce434fSBarry Smith   (*out)->refcnt = 0;
29669ce434fSBarry Smith   PetscFunctionReturn(0);
29769ce434fSBarry Smith }
29869ce434fSBarry Smith 
299c3002683SMatthew G. Knepley /*@
300cab54364SBarry Smith   PetscLayoutReference - Causes a PETSc `Vec` or `Mat` to share a `PetscLayout` with one that already exists.
30169ce434fSBarry Smith 
302c3339decSBarry Smith   Collective
30369ce434fSBarry Smith 
30469ce434fSBarry Smith   Input Parameter:
305cab54364SBarry Smith . in - input `PetscLayout` to be copied
30669ce434fSBarry Smith 
30769ce434fSBarry Smith   Output Parameter:
30869ce434fSBarry Smith . out - the reference location
30969ce434fSBarry Smith 
31069ce434fSBarry Smith   Level: developer
31169ce434fSBarry Smith 
31295452b02SPatrick Sanan   Notes:
313cab54364SBarry Smith   `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
31469ce434fSBarry Smith 
315cab54364SBarry Smith   If the out location already contains a `PetscLayout` it is destroyed
31669ce434fSBarry Smith 
317cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
31869ce434fSBarry Smith @*/
319d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out)
320d71ae5a4SJacob Faibussowitsch {
32169ce434fSBarry Smith   PetscFunctionBegin;
32269ce434fSBarry Smith   in->refcnt++;
3239566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(out));
32469ce434fSBarry Smith   *out = in;
32569ce434fSBarry Smith   PetscFunctionReturn(0);
32669ce434fSBarry Smith }
32769ce434fSBarry Smith 
328c3002683SMatthew G. Knepley /*@
329cab54364SBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a `ISLocalGlobalMapping` into a `PetscLayout`
33069ce434fSBarry Smith 
331c3339decSBarry Smith   Collective
33269ce434fSBarry Smith 
333d8d19677SJose E. Roman   Input Parameters:
334cab54364SBarry Smith + in - input `PetscLayout`
33569ce434fSBarry Smith - ltog - the local to global mapping
33669ce434fSBarry Smith 
33769ce434fSBarry Smith   Level: developer
33869ce434fSBarry Smith 
33995452b02SPatrick Sanan   Notes:
340cab54364SBarry Smith   `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
34169ce434fSBarry Smith 
342cab54364SBarry Smith   If the `PetscLayout` already contains a `ISLocalGlobalMapping` it is destroyed
34369ce434fSBarry Smith 
344cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
34569ce434fSBarry Smith @*/
346d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog)
347d71ae5a4SJacob Faibussowitsch {
34869ce434fSBarry Smith   PetscFunctionBegin;
349fc989267SStefano Zampini   if (ltog) {
350fc989267SStefano Zampini     PetscInt bs;
351fc989267SStefano Zampini 
3529566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs));
353c9cc58a2SBarry 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);
3549566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ltog));
355fc989267SStefano Zampini   }
3569566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping));
35769ce434fSBarry Smith   in->mapping = ltog;
35869ce434fSBarry Smith   PetscFunctionReturn(0);
35969ce434fSBarry Smith }
36069ce434fSBarry Smith 
361c3002683SMatthew G. Knepley /*@
362cab54364SBarry Smith   PetscLayoutSetLocalSize - Sets the local size for a `PetscLayout` object.
36369ce434fSBarry Smith 
364c3339decSBarry Smith   Collective
36569ce434fSBarry Smith 
36669ce434fSBarry Smith   Input Parameters:
36769ce434fSBarry Smith + map - pointer to the map
36869ce434fSBarry Smith - n - the local size
36969ce434fSBarry Smith 
37069ce434fSBarry Smith   Level: developer
37169ce434fSBarry Smith 
372cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
373db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
37469ce434fSBarry Smith @*/
375d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n)
376d71ae5a4SJacob Faibussowitsch {
37769ce434fSBarry Smith   PetscFunctionBegin;
378c9cc58a2SBarry 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);
37969ce434fSBarry Smith   map->n = n;
38069ce434fSBarry Smith   PetscFunctionReturn(0);
38169ce434fSBarry Smith }
38269ce434fSBarry Smith 
3834ffacfe2SAlexis Marboeuf /*@
384cab54364SBarry Smith      PetscLayoutGetLocalSize - Gets the local size for a `PetscLayout` object.
38569ce434fSBarry Smith 
38669ce434fSBarry Smith     Not Collective
38769ce434fSBarry Smith 
38869ce434fSBarry Smith    Input Parameters:
38969ce434fSBarry Smith .    map - pointer to the map
39069ce434fSBarry Smith 
39169ce434fSBarry Smith    Output Parameters:
39269ce434fSBarry Smith .    n - the local size
39369ce434fSBarry Smith 
39469ce434fSBarry Smith    Level: developer
39569ce434fSBarry Smith 
396cab54364SBarry Smith     Note:
397cab54364SBarry Smith     Call this after the call to `PetscLayoutSetUp()`
39869ce434fSBarry Smith 
399cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
400db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
40169ce434fSBarry Smith @*/
402d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n)
403d71ae5a4SJacob Faibussowitsch {
40469ce434fSBarry Smith   PetscFunctionBegin;
40569ce434fSBarry Smith   *n = map->n;
40669ce434fSBarry Smith   PetscFunctionReturn(0);
40769ce434fSBarry Smith }
40869ce434fSBarry Smith 
409c3002683SMatthew G. Knepley /*@
410cab54364SBarry Smith   PetscLayoutSetSize - Sets the global size for a `PetscLayout` object.
41169ce434fSBarry Smith 
412c3339decSBarry Smith   Logically Collective
41369ce434fSBarry Smith 
41469ce434fSBarry Smith   Input Parameters:
41569ce434fSBarry Smith + map - pointer to the map
41669ce434fSBarry Smith - n - the global size
41769ce434fSBarry Smith 
41869ce434fSBarry Smith   Level: developer
41969ce434fSBarry Smith 
420cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
421db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
42269ce434fSBarry Smith @*/
423d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n)
424d71ae5a4SJacob Faibussowitsch {
42569ce434fSBarry Smith   PetscFunctionBegin;
42669ce434fSBarry Smith   map->N = n;
42769ce434fSBarry Smith   PetscFunctionReturn(0);
42869ce434fSBarry Smith }
42969ce434fSBarry Smith 
430c3002683SMatthew G. Knepley /*@
431cab54364SBarry Smith   PetscLayoutGetSize - Gets the global size for a `PetscLayout` object.
43269ce434fSBarry Smith 
43369ce434fSBarry Smith   Not Collective
43469ce434fSBarry Smith 
43569ce434fSBarry Smith   Input Parameters:
43669ce434fSBarry Smith . map - pointer to the map
43769ce434fSBarry Smith 
43869ce434fSBarry Smith   Output Parameters:
43969ce434fSBarry Smith . n - the global size
44069ce434fSBarry Smith 
44169ce434fSBarry Smith   Level: developer
44269ce434fSBarry Smith 
443cab54364SBarry Smith   Note:
444cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
44569ce434fSBarry Smith 
446cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
447db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
44869ce434fSBarry Smith @*/
449d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n)
450d71ae5a4SJacob Faibussowitsch {
45169ce434fSBarry Smith   PetscFunctionBegin;
45269ce434fSBarry Smith   *n = map->N;
45369ce434fSBarry Smith   PetscFunctionReturn(0);
45469ce434fSBarry Smith }
45569ce434fSBarry Smith 
456c3002683SMatthew G. Knepley /*@
457cab54364SBarry Smith   PetscLayoutSetBlockSize - Sets the block size for a `PetscLayout` object.
45869ce434fSBarry Smith 
459c3339decSBarry Smith   Logically Collective
46069ce434fSBarry Smith 
46169ce434fSBarry Smith   Input Parameters:
46269ce434fSBarry Smith + map - pointer to the map
46369ce434fSBarry Smith - bs - the size
46469ce434fSBarry Smith 
46569ce434fSBarry Smith   Level: developer
46669ce434fSBarry Smith 
467cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
468db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
46969ce434fSBarry Smith @*/
470d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs)
471d71ae5a4SJacob Faibussowitsch {
47269ce434fSBarry Smith   PetscFunctionBegin;
47369bbac97SJed Brown   if (bs < 0) PetscFunctionReturn(0);
474c9cc58a2SBarry 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);
475565245c5SBarry Smith   if (map->mapping) {
476705e6b8bSstefano_zampini     PetscInt obs;
477565245c5SBarry Smith 
4789566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs));
47948a46eb9SPierre Jolivet     if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs));
480705e6b8bSstefano_zampini   }
48169ce434fSBarry Smith   map->bs = bs;
48269ce434fSBarry Smith   PetscFunctionReturn(0);
48369ce434fSBarry Smith }
48469ce434fSBarry Smith 
485c3002683SMatthew G. Knepley /*@
486cab54364SBarry Smith   PetscLayoutGetBlockSize - Gets the block size for a `PetscLayout` object.
48769ce434fSBarry Smith 
48869ce434fSBarry Smith   Not Collective
48969ce434fSBarry Smith 
49069ce434fSBarry Smith   Input Parameters:
49169ce434fSBarry Smith . map - pointer to the map
49269ce434fSBarry Smith 
49369ce434fSBarry Smith   Output Parameters:
49469ce434fSBarry Smith . bs - the size
49569ce434fSBarry Smith 
49669ce434fSBarry Smith   Level: developer
49769ce434fSBarry Smith 
49869ce434fSBarry Smith   Notes:
499cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
50069ce434fSBarry Smith 
501cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
502db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`
50369ce434fSBarry Smith @*/
504d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs)
505d71ae5a4SJacob Faibussowitsch {
50669ce434fSBarry Smith   PetscFunctionBegin;
50733d57670SJed Brown   *bs = PetscAbs(map->bs);
50869ce434fSBarry Smith   PetscFunctionReturn(0);
50969ce434fSBarry Smith }
51069ce434fSBarry Smith 
511c3002683SMatthew G. Knepley /*@
51269ce434fSBarry Smith   PetscLayoutGetRange - gets the range of values owned by this process
51369ce434fSBarry Smith 
51469ce434fSBarry Smith   Not Collective
51569ce434fSBarry Smith 
516f899ff85SJose E. Roman   Input Parameter:
51769ce434fSBarry Smith . map - pointer to the map
51869ce434fSBarry Smith 
51969ce434fSBarry Smith   Output Parameters:
52069ce434fSBarry Smith + rstart - first index owned by this process
52169ce434fSBarry Smith - rend   - one more than the last index owned by this process
52269ce434fSBarry Smith 
52369ce434fSBarry Smith   Level: developer
52469ce434fSBarry Smith 
525cab54364SBarry Smith   Note:
526cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
52769ce434fSBarry Smith 
528cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
529db781477SPatrick Sanan           `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
53069ce434fSBarry Smith @*/
531d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend)
532d71ae5a4SJacob Faibussowitsch {
53369ce434fSBarry Smith   PetscFunctionBegin;
53469ce434fSBarry Smith   if (rstart) *rstart = map->rstart;
53569ce434fSBarry Smith   if (rend) *rend = map->rend;
53669ce434fSBarry Smith   PetscFunctionReturn(0);
53769ce434fSBarry Smith }
53869ce434fSBarry Smith 
53969ce434fSBarry Smith /*@C
540cab54364SBarry Smith      PetscLayoutGetRanges - gets the ranges of values owned by all processes
54169ce434fSBarry Smith 
54269ce434fSBarry Smith     Not Collective
54369ce434fSBarry Smith 
54469ce434fSBarry Smith    Input Parameters:
54569ce434fSBarry Smith .    map - pointer to the map
54669ce434fSBarry Smith 
54769ce434fSBarry Smith    Output Parameters:
548c3b5f7baSPierre Jolivet .    range - start of each processors range of indices (the final entry is one more than the
54969ce434fSBarry Smith              last index on the last process)
55069ce434fSBarry Smith 
55169ce434fSBarry Smith    Level: developer
55269ce434fSBarry Smith 
553cab54364SBarry Smith     Note:
554cab54364SBarry Smith     Call this after the call to `PetscLayoutSetUp()`
55569ce434fSBarry Smith 
556cab54364SBarry Smith     Fortran Note:
557*23e9620eSJunchao Zhang     In Fortran, use PetscLayoutGetRangesF90()
55869ce434fSBarry Smith 
559cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
560db781477SPatrick Sanan           `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
56169ce434fSBarry Smith @*/
562d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[])
563d71ae5a4SJacob Faibussowitsch {
56469ce434fSBarry Smith   PetscFunctionBegin;
56569ce434fSBarry Smith   *range = map->range;
56669ce434fSBarry Smith   PetscFunctionReturn(0);
56769ce434fSBarry Smith }
56869ce434fSBarry Smith 
569f92d6284SStefano Zampini /*@
570f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
571f92d6284SStefano Zampini 
572f92d6284SStefano Zampini   Not Collective
573f92d6284SStefano Zampini 
574f92d6284SStefano Zampini   Input Parameters:
575d11c674dSStefano Zampini + mapa - pointer to the first map
576f92d6284SStefano Zampini - mapb - pointer to the second map
577f92d6284SStefano Zampini 
578f92d6284SStefano Zampini   Output Parameters:
579cab54364SBarry Smith . congruent - `PETSC_TRUE` if the two layouts are congruent, `PETSC_FALSE` otherwise
580f92d6284SStefano Zampini 
581f92d6284SStefano Zampini   Level: beginner
582f92d6284SStefano Zampini 
583cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
584db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
585f92d6284SStefano Zampini @*/
586d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent)
587d71ae5a4SJacob Faibussowitsch {
588f92d6284SStefano Zampini   PetscFunctionBegin;
589f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
59048a46eb9SPierre Jolivet   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent));
591f92d6284SStefano Zampini   PetscFunctionReturn(0);
592f92d6284SStefano Zampini }
593