xref: /petsc/src/vec/is/utils/pmap.c (revision f4f49eeac7efa77fffa46b7ff95a3ed169f659ed)
169ce434fSBarry Smith /*
269ce434fSBarry Smith    This file contains routines for basic map object implementation.
369ce434fSBarry Smith */
469ce434fSBarry Smith 
557e2745dSVaclav Hapla #include <petsc/private/isimpl.h> /*I "petscis.h" I*/
65c25fcd7SBarry Smith 
7c3002683SMatthew G. Knepley /*@
8cab54364SBarry Smith   PetscLayoutCreate - Allocates `PetscLayout` object
969ce434fSBarry Smith 
10d083f849SBarry Smith   Collective
1169ce434fSBarry Smith 
122fe279fdSBarry Smith   Input Parameter:
13a8643c1eSVaclav Hapla . comm - the MPI communicator
14a8643c1eSVaclav Hapla 
152fe279fdSBarry Smith   Output Parameter:
16cab54364SBarry Smith . map - the new `PetscLayout`
1769ce434fSBarry Smith 
18456fcb79SJed Brown   Level: advanced
1969ce434fSBarry Smith 
20456fcb79SJed Brown   Notes:
21456fcb79SJed Brown   Typical calling sequence
22456fcb79SJed Brown .vb
2369ce434fSBarry Smith        PetscLayoutCreate(MPI_Comm,PetscLayout *);
24a8643c1eSVaclav Hapla        PetscLayoutSetBlockSize(PetscLayout,bs);
25a8643c1eSVaclav Hapla        PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n);
2669ce434fSBarry Smith        PetscLayoutSetUp(PetscLayout);
27456fcb79SJed Brown .ve
289621ec18SVaclav Hapla   Alternatively,
29147403d9SBarry Smith .vb
30147403d9SBarry Smith       PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
31147403d9SBarry Smith .ve
329621ec18SVaclav Hapla 
33147403d9SBarry Smith   Optionally use any of the following
34147403d9SBarry Smith .vb
35147403d9SBarry Smith   PetscLayoutGetSize(PetscLayout,PetscInt *);
36147403d9SBarry Smith   PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
37147403d9SBarry Smith   PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
38147403d9SBarry Smith   PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
39147403d9SBarry Smith   PetscLayoutDestroy(PetscLayout*);
40147403d9SBarry Smith .ve
4169ce434fSBarry Smith 
42cab54364SBarry Smith   The `PetscLayout` object and methods are intended to be used in the PETSc `Vec` and `Mat` implementations; it is often not needed in
4369ce434fSBarry Smith   user codes unless you really gain something in their use.
4469ce434fSBarry Smith 
45cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
46cab54364SBarry Smith           `PetscLayout`, `PetscLayoutDestroy()`,
47db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`,
48db781477SPatrick Sanan           `PetscLayoutCreateFromSizes()`
4969ce434fSBarry Smith @*/
50d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreate(MPI_Comm comm, PetscLayout *map)
51d71ae5a4SJacob Faibussowitsch {
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;
673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6869ce434fSBarry Smith }
6969ce434fSBarry Smith 
70c3002683SMatthew G. Knepley /*@
71cab54364SBarry Smith   PetscLayoutCreateFromSizes - Allocates `PetscLayout` object and 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
77cab54364SBarry Smith . n    - the local size (or `PETSC_DECIDE`)
78cab54364SBarry Smith . N    - the global size (or `PETSC_DECIDE`)
79cab54364SBarry Smith - bs   - the block size (or `PETSC_DECIDE`)
809621ec18SVaclav Hapla 
812fe279fdSBarry Smith   Output Parameter:
82cab54364SBarry Smith . map - the new `PetscLayout`
839621ec18SVaclav Hapla 
849621ec18SVaclav Hapla   Level: advanced
859621ec18SVaclav Hapla 
86cab54364SBarry Smith   Note:
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 
97cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
98db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()`
999621ec18SVaclav Hapla @*/
100d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map)
101d71ae5a4SJacob Faibussowitsch {
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));
1083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1099621ec18SVaclav Hapla }
1109621ec18SVaclav Hapla 
1119621ec18SVaclav Hapla /*@
112cab54364SBarry Smith   PetscLayoutDestroy - Frees a `PetscLayout` object and frees its range if that exists.
11369ce434fSBarry Smith 
114d083f849SBarry Smith   Collective
11569ce434fSBarry Smith 
1162fe279fdSBarry Smith   Input Parameter:
117cab54364SBarry Smith . map - the `PetscLayout`
11869ce434fSBarry Smith 
11969ce434fSBarry Smith   Level: developer
12069ce434fSBarry Smith 
121cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
122cab54364SBarry Smith           `PetscLayout`, `PetscLayoutCreate()`,
123db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`
12469ce434fSBarry Smith @*/
125d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
126d71ae5a4SJacob Faibussowitsch {
12769ce434fSBarry Smith   PetscFunctionBegin;
1283ba16761SJacob Faibussowitsch   if (!*map) PetscFunctionReturn(PETSC_SUCCESS);
12969ce434fSBarry Smith   if (!(*map)->refcnt--) {
1309566063dSJacob Faibussowitsch     if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range));
1319566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping));
132*f4f49eeaSPierre Jolivet     PetscCall(PetscFree(*map));
13369ce434fSBarry Smith   }
13469ce434fSBarry Smith   *map = NULL;
1353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13669ce434fSBarry Smith }
13769ce434fSBarry Smith 
1389621ec18SVaclav Hapla /*@
139cab54364SBarry Smith   PetscLayoutCreateFromRanges - Creates a new `PetscLayout` with the given ownership ranges and sets it up.
1409621ec18SVaclav Hapla 
1419621ec18SVaclav Hapla   Collective
1429621ec18SVaclav Hapla 
1439621ec18SVaclav Hapla   Input Parameters:
1449621ec18SVaclav Hapla + comm  - the MPI communicator
1459621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1469621ec18SVaclav Hapla . mode  - the copy mode for range
147cab54364SBarry Smith - bs    - the block size (or `PETSC_DECIDE`)
1489621ec18SVaclav Hapla 
1492fe279fdSBarry Smith   Output Parameter:
150cab54364SBarry Smith . newmap - the new `PetscLayout`
1519621ec18SVaclav Hapla 
1529621ec18SVaclav Hapla   Level: developer
1539621ec18SVaclav Hapla 
154cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`,
155cab54364SBarry Smith           `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
156db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()`
1579621ec18SVaclav Hapla @*/
158d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap)
159d71ae5a4SJacob Faibussowitsch {
1609621ec18SVaclav Hapla   PetscLayout map;
16138a25198SStefano Zampini   PetscMPIInt rank;
1627b659617SVaclav Hapla 
1637b659617SVaclav Hapla   PetscFunctionBegin;
1649566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
1659566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, &map));
1669566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetBlockSize(map, bs));
1679621ec18SVaclav Hapla   switch (mode) {
1689621ec18SVaclav Hapla   case PETSC_COPY_VALUES:
1699566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(map->size + 1, &map->range));
1709566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(map->range, range, map->size + 1));
1719621ec18SVaclav Hapla     break;
172d71ae5a4SJacob Faibussowitsch   case PETSC_USE_POINTER:
173d71ae5a4SJacob Faibussowitsch     map->range_alloc = PETSC_FALSE;
174d71ae5a4SJacob Faibussowitsch     break;
175d71ae5a4SJacob Faibussowitsch   default:
176d71ae5a4SJacob Faibussowitsch     map->range = (PetscInt *)range;
177d71ae5a4SJacob Faibussowitsch     break;
1789621ec18SVaclav Hapla   }
1797b659617SVaclav Hapla   map->rstart = map->range[rank];
1807b659617SVaclav Hapla   map->rend   = map->range[rank + 1];
1817b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
18238a25198SStefano Zampini   map->N      = map->range[map->size];
18376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */
1847b659617SVaclav Hapla     PetscInt tmp;
1851c2dc1cbSBarry Smith     PetscCall(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm));
18608401ef6SPierre 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);
187ad540459SPierre 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);
188ad540459SPierre 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);
18976bd3646SJed Brown   }
190ca5434daSLawrence Mitchell   /* lock the layout */
191ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
192ca5434daSLawrence Mitchell   map->oldn        = map->n;
193ca5434daSLawrence Mitchell   map->oldN        = map->N;
194ca5434daSLawrence Mitchell   map->oldbs       = map->bs;
1959621ec18SVaclav Hapla   *newmap          = map;
1963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1977b659617SVaclav Hapla }
1987b659617SVaclav Hapla 
199c3002683SMatthew G. Knepley /*@
20069ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
20169ce434fSBarry Smith   size sets up the map so that it may be used.
20269ce434fSBarry Smith 
203d083f849SBarry Smith   Collective
20469ce434fSBarry Smith 
2052fe279fdSBarry Smith   Input Parameter:
20669ce434fSBarry Smith . map - pointer to the map
20769ce434fSBarry Smith 
20869ce434fSBarry Smith   Level: developer
20969ce434fSBarry Smith 
21095452b02SPatrick Sanan   Notes:
21195452b02SPatrick Sanan   Typical calling sequence
212cab54364SBarry Smith .vb
213cab54364SBarry Smith   PetscLayoutCreate(MPI_Comm,PetscLayout *);
214cab54364SBarry Smith   PetscLayoutSetBlockSize(PetscLayout,1);
215cab54364SBarry Smith   PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
216cab54364SBarry Smith   PetscLayoutSetUp(PetscLayout);
217cab54364SBarry Smith   PetscLayoutGetSize(PetscLayout,PetscInt *);
218cab54364SBarry Smith .ve
21969ce434fSBarry Smith 
2207b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
22169ce434fSBarry Smith 
22269ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
22369ce434fSBarry Smith 
224cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
225cab54364SBarry Smith           `PetscLayout`, `PetscLayoutDestroy()`,
226f1f2ae84SBarry Smith           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()`
22769ce434fSBarry Smith @*/
228d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetUp(PetscLayout map)
229d71ae5a4SJacob Faibussowitsch {
23038a25198SStefano Zampini   PetscMPIInt rank;
23169ce434fSBarry Smith   PetscInt    p;
23269ce434fSBarry Smith 
23369ce434fSBarry Smith   PetscFunctionBegin;
2349371c9d4SSatish 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 ")",
2359371c9d4SSatish Balay              map->oldn, map->oldN, map->n, map->N);
2363ba16761SJacob Faibussowitsch   if (map->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
23769ce434fSBarry Smith 
238ad540459SPierre 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);
239ad540459SPierre 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);
240b146b01cSBarry Smith 
2419566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(map->comm, &rank));
24233d57670SJed Brown   if (map->n > 0) map->n = map->n / PetscAbs(map->bs);
24333d57670SJed Brown   if (map->N > 0) map->N = map->N / PetscAbs(map->bs);
2449566063dSJacob Faibussowitsch   PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N));
24533d57670SJed Brown   map->n = map->n * PetscAbs(map->bs);
24633d57670SJed Brown   map->N = map->N * PetscAbs(map->bs);
24748a46eb9SPierre Jolivet   if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range));
2489566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm));
24969ce434fSBarry Smith 
25069ce434fSBarry Smith   map->range[0] = 0;
25138a25198SStefano Zampini   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1];
25269ce434fSBarry Smith 
25369ce434fSBarry Smith   map->rstart = map->range[rank];
25469ce434fSBarry Smith   map->rend   = map->range[rank + 1];
255ca5434daSLawrence Mitchell 
256ca5434daSLawrence Mitchell   /* lock the layout */
257ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
258ca5434daSLawrence Mitchell   map->oldn        = map->n;
259ca5434daSLawrence Mitchell   map->oldN        = map->N;
260ca5434daSLawrence Mitchell   map->oldbs       = map->bs;
2613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26269ce434fSBarry Smith }
26369ce434fSBarry Smith 
264c3002683SMatthew G. Knepley /*@
265cab54364SBarry Smith   PetscLayoutDuplicate - creates a new `PetscLayout` with the same information as a given one. If the `PetscLayout` already exists it is destroyed first.
26669ce434fSBarry Smith 
267c3339decSBarry Smith   Collective
26869ce434fSBarry Smith 
26969ce434fSBarry Smith   Input Parameter:
270cab54364SBarry Smith . in - input `PetscLayout` to be duplicated
27169ce434fSBarry Smith 
27269ce434fSBarry Smith   Output Parameter:
27369ce434fSBarry Smith . out - the copy
27469ce434fSBarry Smith 
27569ce434fSBarry Smith   Level: developer
27669ce434fSBarry Smith 
277cab54364SBarry Smith   Note:
278cab54364SBarry Smith   `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
27969ce434fSBarry Smith 
280cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()`
28169ce434fSBarry Smith @*/
282d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out)
283d71ae5a4SJacob Faibussowitsch {
28469ce434fSBarry Smith   MPI_Comm comm = in->comm;
28569ce434fSBarry Smith 
28669ce434fSBarry Smith   PetscFunctionBegin;
2879566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(out));
2889566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(comm, out));
2899566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout)));
290c168f6d8SVaclav Hapla   if (in->range) {
2919566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range));
2929566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1));
293c168f6d8SVaclav Hapla   }
29469ce434fSBarry Smith   (*out)->refcnt = 0;
2953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29669ce434fSBarry Smith }
29769ce434fSBarry Smith 
298c3002683SMatthew G. Knepley /*@
299cab54364SBarry Smith   PetscLayoutReference - Causes a PETSc `Vec` or `Mat` to share a `PetscLayout` with one that already exists.
30069ce434fSBarry Smith 
301c3339decSBarry Smith   Collective
30269ce434fSBarry Smith 
30369ce434fSBarry Smith   Input Parameter:
304cab54364SBarry Smith . in - input `PetscLayout` to be copied
30569ce434fSBarry Smith 
30669ce434fSBarry Smith   Output Parameter:
30769ce434fSBarry Smith . out - the reference location
30869ce434fSBarry Smith 
30969ce434fSBarry Smith   Level: developer
31069ce434fSBarry Smith 
31195452b02SPatrick Sanan   Notes:
312cab54364SBarry Smith   `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
31369ce434fSBarry Smith 
314cab54364SBarry Smith   If the out location already contains a `PetscLayout` it is destroyed
31569ce434fSBarry Smith 
316cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
31769ce434fSBarry Smith @*/
318d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out)
319d71ae5a4SJacob Faibussowitsch {
32069ce434fSBarry Smith   PetscFunctionBegin;
32169ce434fSBarry Smith   in->refcnt++;
3229566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(out));
32369ce434fSBarry Smith   *out = in;
3243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32569ce434fSBarry Smith }
32669ce434fSBarry Smith 
327c3002683SMatthew G. Knepley /*@
328cab54364SBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a `ISLocalGlobalMapping` into a `PetscLayout`
32969ce434fSBarry Smith 
330c3339decSBarry Smith   Collective
33169ce434fSBarry Smith 
332d8d19677SJose E. Roman   Input Parameters:
333cab54364SBarry Smith + in   - input `PetscLayout`
33469ce434fSBarry Smith - ltog - the local to global mapping
33569ce434fSBarry Smith 
33669ce434fSBarry Smith   Level: developer
33769ce434fSBarry Smith 
33895452b02SPatrick Sanan   Notes:
339cab54364SBarry Smith   `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
34069ce434fSBarry Smith 
341cab54364SBarry Smith   If the `PetscLayout` already contains a `ISLocalGlobalMapping` it is destroyed
34269ce434fSBarry Smith 
343cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
34469ce434fSBarry Smith @*/
345d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog)
346d71ae5a4SJacob Faibussowitsch {
34769ce434fSBarry Smith   PetscFunctionBegin;
348fc989267SStefano Zampini   if (ltog) {
349fc989267SStefano Zampini     PetscInt bs;
350fc989267SStefano Zampini 
3519566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs));
352c9cc58a2SBarry 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);
3539566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)ltog));
354fc989267SStefano Zampini   }
3559566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping));
35669ce434fSBarry Smith   in->mapping = ltog;
3573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35869ce434fSBarry Smith }
35969ce434fSBarry Smith 
360c3002683SMatthew G. Knepley /*@
361cab54364SBarry Smith   PetscLayoutSetLocalSize - Sets the local size for a `PetscLayout` object.
36269ce434fSBarry Smith 
363c3339decSBarry Smith   Collective
36469ce434fSBarry Smith 
36569ce434fSBarry Smith   Input Parameters:
36669ce434fSBarry Smith + map - pointer to the map
36769ce434fSBarry Smith - n   - the local size
36869ce434fSBarry Smith 
36969ce434fSBarry Smith   Level: developer
37069ce434fSBarry Smith 
371cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
372db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
37369ce434fSBarry Smith @*/
374d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n)
375d71ae5a4SJacob Faibussowitsch {
37669ce434fSBarry Smith   PetscFunctionBegin;
377c9cc58a2SBarry 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);
37869ce434fSBarry Smith   map->n = n;
3793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38069ce434fSBarry Smith }
38169ce434fSBarry Smith 
3824ffacfe2SAlexis Marboeuf /*@
383cab54364SBarry Smith   PetscLayoutGetLocalSize - Gets the local size for a `PetscLayout` object.
38469ce434fSBarry Smith 
38569ce434fSBarry Smith   Not Collective
38669ce434fSBarry Smith 
3872fe279fdSBarry Smith   Input Parameter:
38869ce434fSBarry Smith . map - pointer to the map
38969ce434fSBarry Smith 
3902fe279fdSBarry Smith   Output Parameter:
39169ce434fSBarry Smith . n - the local size
39269ce434fSBarry Smith 
39369ce434fSBarry Smith   Level: developer
39469ce434fSBarry Smith 
395cab54364SBarry Smith   Note:
396cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
39769ce434fSBarry Smith 
39842747ad1SJacob Faibussowitsch .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
399db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
40069ce434fSBarry Smith @*/
401d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n)
402d71ae5a4SJacob Faibussowitsch {
40369ce434fSBarry Smith   PetscFunctionBegin;
40469ce434fSBarry Smith   *n = map->n;
4053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40669ce434fSBarry Smith }
40769ce434fSBarry Smith 
408c3002683SMatthew G. Knepley /*@
409cab54364SBarry Smith   PetscLayoutSetSize - Sets the global size for a `PetscLayout` object.
41069ce434fSBarry Smith 
411c3339decSBarry Smith   Logically Collective
41269ce434fSBarry Smith 
41369ce434fSBarry Smith   Input Parameters:
41469ce434fSBarry Smith + map - pointer to the map
41569ce434fSBarry Smith - n   - the global size
41669ce434fSBarry Smith 
41769ce434fSBarry Smith   Level: developer
41869ce434fSBarry Smith 
419cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
420db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
42169ce434fSBarry Smith @*/
422d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n)
423d71ae5a4SJacob Faibussowitsch {
42469ce434fSBarry Smith   PetscFunctionBegin;
42569ce434fSBarry Smith   map->N = n;
4263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42769ce434fSBarry Smith }
42869ce434fSBarry Smith 
429c3002683SMatthew G. Knepley /*@
430cab54364SBarry Smith   PetscLayoutGetSize - Gets the global size for a `PetscLayout` object.
43169ce434fSBarry Smith 
43269ce434fSBarry Smith   Not Collective
43369ce434fSBarry Smith 
4342fe279fdSBarry Smith   Input Parameter:
43569ce434fSBarry Smith . map - pointer to the map
43669ce434fSBarry Smith 
4372fe279fdSBarry Smith   Output Parameter:
43869ce434fSBarry Smith . n - the global size
43969ce434fSBarry Smith 
44069ce434fSBarry Smith   Level: developer
44169ce434fSBarry Smith 
442cab54364SBarry Smith   Note:
443cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
44469ce434fSBarry Smith 
445cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
446db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
44769ce434fSBarry Smith @*/
448d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n)
449d71ae5a4SJacob Faibussowitsch {
45069ce434fSBarry Smith   PetscFunctionBegin;
45169ce434fSBarry Smith   *n = map->N;
4523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45369ce434fSBarry Smith }
45469ce434fSBarry Smith 
455c3002683SMatthew G. Knepley /*@
456cab54364SBarry Smith   PetscLayoutSetBlockSize - Sets the block size for a `PetscLayout` object.
45769ce434fSBarry Smith 
458c3339decSBarry Smith   Logically Collective
45969ce434fSBarry Smith 
46069ce434fSBarry Smith   Input Parameters:
46169ce434fSBarry Smith + map - pointer to the map
46269ce434fSBarry Smith - bs  - the size
46369ce434fSBarry Smith 
46469ce434fSBarry Smith   Level: developer
46569ce434fSBarry Smith 
466cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
467db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
46869ce434fSBarry Smith @*/
469d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs)
470d71ae5a4SJacob Faibussowitsch {
47169ce434fSBarry Smith   PetscFunctionBegin;
4723ba16761SJacob Faibussowitsch   if (bs < 0) PetscFunctionReturn(PETSC_SUCCESS);
473c9cc58a2SBarry 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);
474565245c5SBarry Smith   if (map->mapping) {
475705e6b8bSstefano_zampini     PetscInt obs;
476565245c5SBarry Smith 
4779566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs));
47848a46eb9SPierre Jolivet     if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs));
479705e6b8bSstefano_zampini   }
48069ce434fSBarry Smith   map->bs = bs;
4813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
48269ce434fSBarry Smith }
48369ce434fSBarry Smith 
484c3002683SMatthew G. Knepley /*@
485cab54364SBarry Smith   PetscLayoutGetBlockSize - Gets the block size for a `PetscLayout` object.
48669ce434fSBarry Smith 
48769ce434fSBarry Smith   Not Collective
48869ce434fSBarry Smith 
4892fe279fdSBarry Smith   Input Parameter:
49069ce434fSBarry Smith . map - pointer to the map
49169ce434fSBarry Smith 
4922fe279fdSBarry Smith   Output Parameter:
49369ce434fSBarry Smith . bs - the size
49469ce434fSBarry Smith 
49569ce434fSBarry Smith   Level: developer
49669ce434fSBarry Smith 
49769ce434fSBarry Smith   Notes:
498cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
49969ce434fSBarry Smith 
500cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
501db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`
50269ce434fSBarry Smith @*/
503d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs)
504d71ae5a4SJacob Faibussowitsch {
50569ce434fSBarry Smith   PetscFunctionBegin;
50633d57670SJed Brown   *bs = PetscAbs(map->bs);
5073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50869ce434fSBarry Smith }
50969ce434fSBarry Smith 
510c3002683SMatthew G. Knepley /*@
51169ce434fSBarry Smith   PetscLayoutGetRange - gets the range of values owned by this process
51269ce434fSBarry Smith 
51369ce434fSBarry Smith   Not Collective
51469ce434fSBarry Smith 
515f899ff85SJose E. Roman   Input Parameter:
51669ce434fSBarry Smith . map - pointer to the map
51769ce434fSBarry Smith 
51869ce434fSBarry Smith   Output Parameters:
51969ce434fSBarry Smith + rstart - first index owned by this process
52069ce434fSBarry Smith - rend   - one more than the last index owned by this process
52169ce434fSBarry Smith 
52269ce434fSBarry Smith   Level: developer
52369ce434fSBarry Smith 
524cab54364SBarry Smith   Note:
525cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
52669ce434fSBarry Smith 
527cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
52838b5cf2dSJacob Faibussowitsch           `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutSetUp()`
52969ce434fSBarry Smith @*/
530d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend)
531d71ae5a4SJacob Faibussowitsch {
53269ce434fSBarry Smith   PetscFunctionBegin;
53369ce434fSBarry Smith   if (rstart) *rstart = map->rstart;
53469ce434fSBarry Smith   if (rend) *rend = map->rend;
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
53669ce434fSBarry Smith }
53769ce434fSBarry Smith 
53869ce434fSBarry Smith /*@C
539cab54364SBarry Smith   PetscLayoutGetRanges - gets the ranges of values owned by all processes
54069ce434fSBarry Smith 
54169ce434fSBarry Smith   Not Collective
54269ce434fSBarry Smith 
5432fe279fdSBarry Smith   Input Parameter:
54469ce434fSBarry Smith . map - pointer to the map
54569ce434fSBarry Smith 
5462fe279fdSBarry Smith   Output Parameter:
547c3b5f7baSPierre Jolivet . range - start of each processors range of indices (the final entry is one more than the
54869ce434fSBarry Smith              last index on the last process)
54969ce434fSBarry Smith 
55069ce434fSBarry Smith   Level: developer
55169ce434fSBarry Smith 
552cab54364SBarry Smith   Note:
553cab54364SBarry Smith   Call this after the call to `PetscLayoutSetUp()`
55469ce434fSBarry Smith 
55538b5cf2dSJacob Faibussowitsch   Fortran Notes:
55623e9620eSJunchao Zhang   In Fortran, use PetscLayoutGetRangesF90()
55769ce434fSBarry Smith 
558cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
55938b5cf2dSJacob Faibussowitsch           `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutSetUp()`
56069ce434fSBarry Smith @*/
561d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[])
562d71ae5a4SJacob Faibussowitsch {
56369ce434fSBarry Smith   PetscFunctionBegin;
56469ce434fSBarry Smith   *range = map->range;
5653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
56669ce434fSBarry Smith }
56769ce434fSBarry Smith 
568f92d6284SStefano Zampini /*@
569f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
570f92d6284SStefano Zampini 
571f92d6284SStefano Zampini   Not Collective
572f92d6284SStefano Zampini 
573f92d6284SStefano Zampini   Input Parameters:
574d11c674dSStefano Zampini + mapa - pointer to the first map
575f92d6284SStefano Zampini - mapb - pointer to the second map
576f92d6284SStefano Zampini 
5772fe279fdSBarry Smith   Output Parameter:
578cab54364SBarry Smith . congruent - `PETSC_TRUE` if the two layouts are congruent, `PETSC_FALSE` otherwise
579f92d6284SStefano Zampini 
580f92d6284SStefano Zampini   Level: beginner
581f92d6284SStefano Zampini 
582cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
583db781477SPatrick Sanan           `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
584f92d6284SStefano Zampini @*/
585d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent)
586d71ae5a4SJacob Faibussowitsch {
587f92d6284SStefano Zampini   PetscFunctionBegin;
588f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
58948a46eb9SPierre Jolivet   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent));
5903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
591f92d6284SStefano Zampini }
592