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 @*/
PetscLayoutCreate(MPI_Comm comm,PetscLayout * map)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;
5658b7e2c1SStefano Zampini (*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:
87b44f4de4SBarry Smith .vb
88b44f4de4SBarry Smith PetscLayoutCreateFromSizes(comm, n, N, bs, &layout);
89b44f4de4SBarry Smith .ve
909621ec18SVaclav Hapla is a shorthand for
919621ec18SVaclav Hapla .vb
929621ec18SVaclav Hapla PetscLayoutCreate(comm, &layout);
939621ec18SVaclav Hapla PetscLayoutSetLocalSize(layout, n);
949621ec18SVaclav Hapla PetscLayoutSetSize(layout, N);
959621ec18SVaclav Hapla PetscLayoutSetBlockSize(layout, bs);
969621ec18SVaclav Hapla PetscLayoutSetUp(layout);
979621ec18SVaclav Hapla .ve
989621ec18SVaclav Hapla
99cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
100db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromRanges()`
1019621ec18SVaclav Hapla @*/
PetscLayoutCreateFromSizes(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt bs,PetscLayout * map)102d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm, PetscInt n, PetscInt N, PetscInt bs, PetscLayout *map)
103d71ae5a4SJacob Faibussowitsch {
1049621ec18SVaclav Hapla PetscFunctionBegin;
1059566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, map));
1069566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(*map, n));
1079566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetSize(*map, N));
1089566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(*map, bs));
1099566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(*map));
1103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1119621ec18SVaclav Hapla }
1129621ec18SVaclav Hapla
1139621ec18SVaclav Hapla /*@
114cab54364SBarry Smith PetscLayoutDestroy - Frees a `PetscLayout` object and frees its range if that exists.
11569ce434fSBarry Smith
116d083f849SBarry Smith Collective
11769ce434fSBarry Smith
1182fe279fdSBarry Smith Input Parameter:
119cab54364SBarry Smith . map - the `PetscLayout`
12069ce434fSBarry Smith
12169ce434fSBarry Smith Level: developer
12269ce434fSBarry Smith
123cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
124cab54364SBarry Smith `PetscLayout`, `PetscLayoutCreate()`,
125db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`
12669ce434fSBarry Smith @*/
PetscLayoutDestroy(PetscLayout * map)127d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
128d71ae5a4SJacob Faibussowitsch {
12969ce434fSBarry Smith PetscFunctionBegin;
1303ba16761SJacob Faibussowitsch if (!*map) PetscFunctionReturn(PETSC_SUCCESS);
13169ce434fSBarry Smith if (!(*map)->refcnt--) {
1329566063dSJacob Faibussowitsch if ((*map)->range_alloc) PetscCall(PetscFree((*map)->range));
1339566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&(*map)->mapping));
134f4f49eeaSPierre Jolivet PetscCall(PetscFree(*map));
13569ce434fSBarry Smith }
13669ce434fSBarry Smith *map = NULL;
1373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
13869ce434fSBarry Smith }
13969ce434fSBarry Smith
1409621ec18SVaclav Hapla /*@
141cab54364SBarry Smith PetscLayoutCreateFromRanges - Creates a new `PetscLayout` with the given ownership ranges and sets it up.
1429621ec18SVaclav Hapla
1439621ec18SVaclav Hapla Collective
1449621ec18SVaclav Hapla
1459621ec18SVaclav Hapla Input Parameters:
1469621ec18SVaclav Hapla + comm - the MPI communicator
1479621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1489621ec18SVaclav Hapla . mode - the copy mode for range
149cab54364SBarry Smith - bs - the block size (or `PETSC_DECIDE`)
1509621ec18SVaclav Hapla
1512fe279fdSBarry Smith Output Parameter:
152cab54364SBarry Smith . newmap - the new `PetscLayout`
1539621ec18SVaclav Hapla
1549621ec18SVaclav Hapla Level: developer
1559621ec18SVaclav Hapla
156cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`,
157cab54364SBarry Smith `PetscLayoutGetLocalSize()`, `PetscLayout`, `PetscLayoutDestroy()`,
158db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutSetUp()`, `PetscLayoutCreateFromSizes()`
1599621ec18SVaclav Hapla @*/
PetscLayoutCreateFromRanges(MPI_Comm comm,const PetscInt range[],PetscCopyMode mode,PetscInt bs,PetscLayout * newmap)160d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm, const PetscInt range[], PetscCopyMode mode, PetscInt bs, PetscLayout *newmap)
161d71ae5a4SJacob Faibussowitsch {
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;
174d71ae5a4SJacob Faibussowitsch case PETSC_USE_POINTER:
175f0edcda5SJames Wright map->range_alloc = PETSC_FALSE; /* fall through */
176f0edcda5SJames Wright case PETSC_OWN_POINTER:
177d71ae5a4SJacob Faibussowitsch map->range = (PetscInt *)range;
178d71ae5a4SJacob Faibussowitsch break;
179f0edcda5SJames Wright default:
180f0edcda5SJames Wright SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Received invalid PetscCopyMode somehow");
1819621ec18SVaclav Hapla }
1827b659617SVaclav Hapla map->rstart = map->range[rank];
1837b659617SVaclav Hapla map->rend = map->range[rank + 1];
1847b659617SVaclav Hapla map->n = map->rend - map->rstart;
185*83e31f1cSJames Wright map->N = map->range[map->size] - map->range[0];
18676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { /* just check that n, N and bs are consistent */
1877b659617SVaclav Hapla PetscInt tmp;
188462c564dSBarry Smith PetscCallMPI(MPIU_Allreduce(&map->n, &tmp, 1, MPIU_INT, MPI_SUM, map->comm));
18900045ab3SPierre 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 ". The provided PetscLayout is wrong.", tmp, map->N, map->n);
19058b7e2c1SStefano Zampini 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);
19158b7e2c1SStefano Zampini 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);
19276bd3646SJed Brown }
193ca5434daSLawrence Mitchell /* lock the layout */
194ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE;
195ca5434daSLawrence Mitchell map->oldn = map->n;
196ca5434daSLawrence Mitchell map->oldN = map->N;
197ca5434daSLawrence Mitchell map->oldbs = map->bs;
1989621ec18SVaclav Hapla *newmap = map;
1993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2007b659617SVaclav Hapla }
2017b659617SVaclav Hapla
202c3002683SMatthew G. Knepley /*@
20369ce434fSBarry Smith PetscLayoutSetUp - given a map where you have set either the global or local
20469ce434fSBarry Smith size sets up the map so that it may be used.
20569ce434fSBarry Smith
206d083f849SBarry Smith Collective
20769ce434fSBarry Smith
2082fe279fdSBarry Smith Input Parameter:
20969ce434fSBarry Smith . map - pointer to the map
21069ce434fSBarry Smith
21169ce434fSBarry Smith Level: developer
21269ce434fSBarry Smith
21395452b02SPatrick Sanan Notes:
21495452b02SPatrick Sanan Typical calling sequence
215cab54364SBarry Smith .vb
216cab54364SBarry Smith PetscLayoutCreate(MPI_Comm,PetscLayout *);
217cab54364SBarry Smith PetscLayoutSetBlockSize(PetscLayout,1);
218cab54364SBarry Smith PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
219cab54364SBarry Smith PetscLayoutSetUp(PetscLayout);
220cab54364SBarry Smith PetscLayoutGetSize(PetscLayout,PetscInt *);
221cab54364SBarry Smith .ve
22269ce434fSBarry Smith
2237b659617SVaclav Hapla If range exists, and local size is not set, everything gets computed from the range.
22469ce434fSBarry Smith
22569ce434fSBarry Smith If the local size, global size are already set and range exists then this does nothing.
22669ce434fSBarry Smith
227cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutSetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`,
228cab54364SBarry Smith `PetscLayout`, `PetscLayoutDestroy()`,
229f1f2ae84SBarry Smith `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`, `PetscLayoutCreate()`, `PetscSplitOwnership()`
23069ce434fSBarry Smith @*/
PetscLayoutSetUp(PetscLayout map)231d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetUp(PetscLayout map)
232d71ae5a4SJacob Faibussowitsch {
23338a25198SStefano Zampini PetscMPIInt rank;
23469ce434fSBarry Smith PetscInt p;
23569ce434fSBarry Smith
23669ce434fSBarry Smith PetscFunctionBegin;
2379371c9d4SSatish 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 ")",
2389371c9d4SSatish Balay map->oldn, map->oldN, map->n, map->N);
2393ba16761SJacob Faibussowitsch if (map->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
24069ce434fSBarry Smith
24158b7e2c1SStefano Zampini PetscCheck(map->n < 0 || 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);
24258b7e2c1SStefano Zampini PetscCheck(map->N < 0 || 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);
243b146b01cSBarry Smith
2449566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(map->comm, &rank));
24558b7e2c1SStefano Zampini if (map->n > 0) map->n = map->n / map->bs;
24658b7e2c1SStefano Zampini if (map->N > 0) map->N = map->N / map->bs;
2479566063dSJacob Faibussowitsch PetscCall(PetscSplitOwnership(map->comm, &map->n, &map->N));
24858b7e2c1SStefano Zampini map->n = map->n * map->bs;
24958b7e2c1SStefano Zampini map->N = map->N * map->bs;
25048a46eb9SPierre Jolivet if (!map->range) PetscCall(PetscMalloc1(map->size + 1, &map->range));
2519566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(&map->n, 1, MPIU_INT, map->range + 1, 1, MPIU_INT, map->comm));
25269ce434fSBarry Smith
25369ce434fSBarry Smith map->range[0] = 0;
25438a25198SStefano Zampini for (p = 2; p <= map->size; p++) map->range[p] += map->range[p - 1];
25569ce434fSBarry Smith
25669ce434fSBarry Smith map->rstart = map->range[rank];
25769ce434fSBarry Smith map->rend = map->range[rank + 1];
258ca5434daSLawrence Mitchell
259ca5434daSLawrence Mitchell /* lock the layout */
260ca5434daSLawrence Mitchell map->setupcalled = PETSC_TRUE;
261ca5434daSLawrence Mitchell map->oldn = map->n;
262ca5434daSLawrence Mitchell map->oldN = map->N;
263ca5434daSLawrence Mitchell map->oldbs = map->bs;
2643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
26569ce434fSBarry Smith }
26669ce434fSBarry Smith
267c3002683SMatthew G. Knepley /*@
268cab54364SBarry Smith PetscLayoutDuplicate - creates a new `PetscLayout` with the same information as a given one. If the `PetscLayout` already exists it is destroyed first.
26969ce434fSBarry Smith
270c3339decSBarry Smith Collective
27169ce434fSBarry Smith
27269ce434fSBarry Smith Input Parameter:
273cab54364SBarry Smith . in - input `PetscLayout` to be duplicated
27469ce434fSBarry Smith
27569ce434fSBarry Smith Output Parameter:
27669ce434fSBarry Smith . out - the copy
27769ce434fSBarry Smith
27869ce434fSBarry Smith Level: developer
27969ce434fSBarry Smith
280cab54364SBarry Smith Note:
281cab54364SBarry Smith `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
28269ce434fSBarry Smith
283cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutReference()`
28469ce434fSBarry Smith @*/
PetscLayoutDuplicate(PetscLayout in,PetscLayout * out)285d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutDuplicate(PetscLayout in, PetscLayout *out)
286d71ae5a4SJacob Faibussowitsch {
28769ce434fSBarry Smith MPI_Comm comm = in->comm;
28869ce434fSBarry Smith
28969ce434fSBarry Smith PetscFunctionBegin;
2909566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(out));
2919566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, out));
2929566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(*out, in, sizeof(struct _n_PetscLayout)));
293c168f6d8SVaclav Hapla if (in->range) {
2949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((*out)->size + 1, &(*out)->range));
2959566063dSJacob Faibussowitsch PetscCall(PetscArraycpy((*out)->range, in->range, (*out)->size + 1));
296c168f6d8SVaclav Hapla }
29769ce434fSBarry Smith (*out)->refcnt = 0;
2983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
29969ce434fSBarry Smith }
30069ce434fSBarry Smith
301c3002683SMatthew G. Knepley /*@
302cab54364SBarry Smith PetscLayoutReference - Causes a PETSc `Vec` or `Mat` to share a `PetscLayout` with one that already exists.
30369ce434fSBarry Smith
304c3339decSBarry Smith Collective
30569ce434fSBarry Smith
30669ce434fSBarry Smith Input Parameter:
307cab54364SBarry Smith . in - input `PetscLayout` to be copied
30869ce434fSBarry Smith
30969ce434fSBarry Smith Output Parameter:
31069ce434fSBarry Smith . out - the reference location
31169ce434fSBarry Smith
31269ce434fSBarry Smith Level: developer
31369ce434fSBarry Smith
31495452b02SPatrick Sanan Notes:
315cab54364SBarry Smith `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
31669ce434fSBarry Smith
317cab54364SBarry Smith If the out location already contains a `PetscLayout` it is destroyed
31869ce434fSBarry Smith
319cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
32069ce434fSBarry Smith @*/
PetscLayoutReference(PetscLayout in,PetscLayout * out)321d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutReference(PetscLayout in, PetscLayout *out)
322d71ae5a4SJacob Faibussowitsch {
32369ce434fSBarry Smith PetscFunctionBegin;
32469ce434fSBarry Smith in->refcnt++;
3259566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(out));
32669ce434fSBarry Smith *out = in;
3273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
32869ce434fSBarry Smith }
32969ce434fSBarry Smith
330c3002683SMatthew G. Knepley /*@
331cab54364SBarry Smith PetscLayoutSetISLocalToGlobalMapping - sets a `ISLocalGlobalMapping` into a `PetscLayout`
33269ce434fSBarry Smith
333c3339decSBarry Smith Collective
33469ce434fSBarry Smith
335d8d19677SJose E. Roman Input Parameters:
336cab54364SBarry Smith + in - input `PetscLayout`
33769ce434fSBarry Smith - ltog - the local to global mapping
33869ce434fSBarry Smith
33969ce434fSBarry Smith Level: developer
34069ce434fSBarry Smith
34195452b02SPatrick Sanan Notes:
342cab54364SBarry Smith `PetscLayoutSetUp()` does not need to be called on the resulting `PetscLayout`
34369ce434fSBarry Smith
344cab54364SBarry Smith If the `PetscLayout` already contains a `ISLocalGlobalMapping` it is destroyed
34569ce434fSBarry Smith
346cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutDestroy()`, `PetscLayoutSetUp()`, `PetscLayoutDuplicate()`
34769ce434fSBarry Smith @*/
PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)348d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in, ISLocalToGlobalMapping ltog)
349d71ae5a4SJacob Faibussowitsch {
35069ce434fSBarry Smith PetscFunctionBegin;
351fc989267SStefano Zampini if (ltog) {
352fc989267SStefano Zampini PetscInt bs;
353fc989267SStefano Zampini
3549566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetBlockSize(ltog, &bs));
35558b7e2c1SStefano Zampini PetscCheck(in->bs == 1 || 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);
356fc989267SStefano Zampini }
357da0802e2SStefano Zampini PetscCall(PetscObjectReference((PetscObject)ltog));
3589566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&in->mapping));
35969ce434fSBarry Smith in->mapping = ltog;
3603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
36169ce434fSBarry Smith }
36269ce434fSBarry Smith
363c3002683SMatthew G. Knepley /*@
364cab54364SBarry Smith PetscLayoutSetLocalSize - Sets the local size for a `PetscLayout` object.
36569ce434fSBarry Smith
366c3339decSBarry Smith Collective
36769ce434fSBarry Smith
36869ce434fSBarry Smith Input Parameters:
36969ce434fSBarry Smith + map - pointer to the map
370e1b2f275SBarry Smith - n - the local size, pass `PETSC_DECIDE` (the default) to have this value determined by the global size set with `PetscLayoutSetSize()`
37169ce434fSBarry Smith
37269ce434fSBarry Smith Level: developer
37369ce434fSBarry Smith
374cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetUp()`
375db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
37669ce434fSBarry Smith @*/
PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)377d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map, PetscInt n)
378d71ae5a4SJacob Faibussowitsch {
37969ce434fSBarry Smith PetscFunctionBegin;
38058b7e2c1SStefano Zampini PetscCheck(n % map->bs == 0, map->comm, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT, n, map->bs);
38169ce434fSBarry Smith map->n = n;
3823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
38369ce434fSBarry Smith }
38469ce434fSBarry Smith
3854ffacfe2SAlexis Marboeuf /*@
386cab54364SBarry Smith PetscLayoutGetLocalSize - Gets the local size for a `PetscLayout` object.
38769ce434fSBarry Smith
38869ce434fSBarry Smith Not Collective
38969ce434fSBarry Smith
3902fe279fdSBarry Smith Input Parameter:
39169ce434fSBarry Smith . map - pointer to the map
39269ce434fSBarry Smith
3932fe279fdSBarry Smith Output Parameter:
39469ce434fSBarry Smith . n - the local size
39569ce434fSBarry Smith
39669ce434fSBarry Smith Level: developer
39769ce434fSBarry Smith
398cab54364SBarry Smith Note:
399cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()`
40069ce434fSBarry Smith
40142747ad1SJacob Faibussowitsch .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
402db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
40369ce434fSBarry Smith @*/
PetscLayoutGetLocalSize(PetscLayout map,PetscInt * n)404d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetLocalSize(PetscLayout map, PetscInt *n)
405d71ae5a4SJacob Faibussowitsch {
40669ce434fSBarry Smith PetscFunctionBegin;
40769ce434fSBarry Smith *n = map->n;
4083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
40969ce434fSBarry Smith }
41069ce434fSBarry Smith
411c3002683SMatthew G. Knepley /*@
412cab54364SBarry Smith PetscLayoutSetSize - Sets the global size for a `PetscLayout` object.
41369ce434fSBarry Smith
414c3339decSBarry Smith Logically Collective
41569ce434fSBarry Smith
41669ce434fSBarry Smith Input Parameters:
41769ce434fSBarry Smith + map - pointer to the map
418e1b2f275SBarry Smith - n - the global size, use `PETSC_DETERMINE` (the default) to have this value computed as the sum of the local sizes set with `PetscLayoutSetLocalSize()`
41969ce434fSBarry Smith
42069ce434fSBarry Smith Level: developer
42169ce434fSBarry Smith
422cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
423db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
42469ce434fSBarry Smith @*/
PetscLayoutSetSize(PetscLayout map,PetscInt n)425d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetSize(PetscLayout map, PetscInt n)
426d71ae5a4SJacob Faibussowitsch {
42769ce434fSBarry Smith PetscFunctionBegin;
42869ce434fSBarry Smith map->N = n;
4293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
43069ce434fSBarry Smith }
43169ce434fSBarry Smith
432c3002683SMatthew G. Knepley /*@
433cab54364SBarry Smith PetscLayoutGetSize - Gets the global size for a `PetscLayout` object.
43469ce434fSBarry Smith
43569ce434fSBarry Smith Not Collective
43669ce434fSBarry Smith
4372fe279fdSBarry Smith Input Parameter:
43869ce434fSBarry Smith . map - pointer to the map
43969ce434fSBarry Smith
4402fe279fdSBarry Smith Output Parameter:
44169ce434fSBarry Smith . n - the global size
44269ce434fSBarry Smith
44369ce434fSBarry Smith Level: developer
44469ce434fSBarry Smith
445cab54364SBarry Smith Note:
446cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()`
44769ce434fSBarry Smith
448cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
449db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetBlockSize()`
45069ce434fSBarry Smith @*/
PetscLayoutGetSize(PetscLayout map,PetscInt * n)451d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetSize(PetscLayout map, PetscInt *n)
452d71ae5a4SJacob Faibussowitsch {
45369ce434fSBarry Smith PetscFunctionBegin;
45469ce434fSBarry Smith *n = map->N;
4553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
45669ce434fSBarry Smith }
45769ce434fSBarry Smith
458c3002683SMatthew G. Knepley /*@
459cab54364SBarry Smith PetscLayoutSetBlockSize - Sets the block size for a `PetscLayout` object.
46069ce434fSBarry Smith
461c3339decSBarry Smith Logically Collective
46269ce434fSBarry Smith
46369ce434fSBarry Smith Input Parameters:
46469ce434fSBarry Smith + map - pointer to the map
46569ce434fSBarry Smith - bs - the size
46669ce434fSBarry Smith
46769ce434fSBarry Smith Level: developer
46869ce434fSBarry Smith
469cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
470db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
47169ce434fSBarry Smith @*/
PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)472d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map, PetscInt bs)
473d71ae5a4SJacob Faibussowitsch {
47469ce434fSBarry Smith PetscFunctionBegin;
47558b7e2c1SStefano Zampini PetscCheck(bs > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Block size %" PetscInt_FMT " must be positive", bs);
476c9cc58a2SBarry 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);
477565245c5SBarry Smith if (map->mapping) {
478705e6b8bSstefano_zampini PetscInt obs;
479565245c5SBarry Smith
4809566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetBlockSize(map->mapping, &obs));
48148a46eb9SPierre Jolivet if (obs > 1) PetscCall(ISLocalToGlobalMappingSetBlockSize(map->mapping, bs));
482705e6b8bSstefano_zampini }
48369ce434fSBarry Smith map->bs = bs;
4843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
48569ce434fSBarry Smith }
48669ce434fSBarry Smith
487c3002683SMatthew G. Knepley /*@
488cab54364SBarry Smith PetscLayoutGetBlockSize - Gets the block size for a `PetscLayout` object.
48969ce434fSBarry Smith
49069ce434fSBarry Smith Not Collective
49169ce434fSBarry Smith
4922fe279fdSBarry Smith Input Parameter:
49369ce434fSBarry Smith . map - pointer to the map
49469ce434fSBarry Smith
4952fe279fdSBarry Smith Output Parameter:
49669ce434fSBarry Smith . bs - the size
49769ce434fSBarry Smith
49869ce434fSBarry Smith Level: developer
49969ce434fSBarry Smith
50069ce434fSBarry Smith Notes:
501cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()`
50269ce434fSBarry Smith
503cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`, `PetscLayoutSetUp()`
504db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutGetSize()`
50569ce434fSBarry Smith @*/
PetscLayoutGetBlockSize(PetscLayout map,PetscInt * bs)506d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map, PetscInt *bs)
507d71ae5a4SJacob Faibussowitsch {
50869ce434fSBarry Smith PetscFunctionBegin;
50958b7e2c1SStefano Zampini *bs = map->bs;
5103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
51169ce434fSBarry Smith }
51269ce434fSBarry Smith
513c3002683SMatthew G. Knepley /*@
51469ce434fSBarry Smith PetscLayoutGetRange - gets the range of values owned by this process
51569ce434fSBarry Smith
51669ce434fSBarry Smith Not Collective
51769ce434fSBarry Smith
518f899ff85SJose E. Roman Input Parameter:
51969ce434fSBarry Smith . map - pointer to the map
52069ce434fSBarry Smith
52169ce434fSBarry Smith Output Parameters:
52269ce434fSBarry Smith + rstart - first index owned by this process
52369ce434fSBarry Smith - rend - one more than the last index owned by this process
52469ce434fSBarry Smith
52569ce434fSBarry Smith Level: developer
52669ce434fSBarry Smith
527cab54364SBarry Smith Note:
528cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()`
52969ce434fSBarry Smith
530cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
53138b5cf2dSJacob Faibussowitsch `PetscLayoutGetSize()`, `PetscLayoutGetRanges()`, `PetscLayoutSetBlockSize()`, `PetscLayoutSetUp()`
53269ce434fSBarry Smith @*/
PetscLayoutGetRange(PetscLayout map,PetscInt * rstart,PetscInt * rend)533d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRange(PetscLayout map, PetscInt *rstart, PetscInt *rend)
534d71ae5a4SJacob Faibussowitsch {
53569ce434fSBarry Smith PetscFunctionBegin;
53669ce434fSBarry Smith if (rstart) *rstart = map->rstart;
53769ce434fSBarry Smith if (rend) *rend = map->rend;
5383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
53969ce434fSBarry Smith }
54069ce434fSBarry Smith
54169ce434fSBarry Smith /*@C
542cab54364SBarry Smith PetscLayoutGetRanges - gets the ranges of values owned by all processes
54369ce434fSBarry Smith
54469ce434fSBarry Smith Not Collective
54569ce434fSBarry Smith
5462fe279fdSBarry Smith Input Parameter:
54769ce434fSBarry Smith . map - pointer to the map
54869ce434fSBarry Smith
5492fe279fdSBarry Smith Output Parameter:
550c3b5f7baSPierre Jolivet . range - start of each processors range of indices (the final entry is one more than the
5512c9a7b26SBarry Smith last index on the last process). The length of the array is one more than the number of processes in the MPI
5522c9a7b26SBarry Smith communicator owned by `map`
55369ce434fSBarry Smith
55469ce434fSBarry Smith Level: developer
55569ce434fSBarry Smith
556cab54364SBarry Smith Note:
557cab54364SBarry Smith Call this after the call to `PetscLayoutSetUp()`
55869ce434fSBarry Smith
55938b5cf2dSJacob Faibussowitsch Fortran Notes:
560ce78bad3SBarry Smith .vb
561ce78bad3SBarry Smith PetscInt, pointer :: range(:)
562ce78bad3SBarry Smith .ve
563ce78bad3SBarry Smith
564ce78bad3SBarry Smith Call `PetscLayoutRestoreRanges()` when no longer needed.
56569ce434fSBarry Smith
566cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutSetSize()`,
56738b5cf2dSJacob Faibussowitsch `PetscLayoutGetSize()`, `PetscLayoutGetRange()`, `PetscLayoutSetBlockSize()`, `PetscLayoutSetUp()`
56869ce434fSBarry Smith @*/
PetscLayoutGetRanges(PetscLayout map,const PetscInt * range[])569d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutGetRanges(PetscLayout map, const PetscInt *range[])
570d71ae5a4SJacob Faibussowitsch {
57169ce434fSBarry Smith PetscFunctionBegin;
57269ce434fSBarry Smith *range = map->range;
5733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
57469ce434fSBarry Smith }
57569ce434fSBarry Smith
576f92d6284SStefano Zampini /*@
577f92d6284SStefano Zampini PetscLayoutCompare - Compares two layouts
578f92d6284SStefano Zampini
579f92d6284SStefano Zampini Not Collective
580f92d6284SStefano Zampini
581f92d6284SStefano Zampini Input Parameters:
582d11c674dSStefano Zampini + mapa - pointer to the first map
583f92d6284SStefano Zampini - mapb - pointer to the second map
584f92d6284SStefano Zampini
5852fe279fdSBarry Smith Output Parameter:
586cab54364SBarry Smith . congruent - `PETSC_TRUE` if the two layouts are congruent, `PETSC_FALSE` otherwise
587f92d6284SStefano Zampini
588f92d6284SStefano Zampini Level: beginner
589f92d6284SStefano Zampini
590cab54364SBarry Smith .seealso: [PetscLayout](sec_matlayout), `PetscLayoutCreate()`, `PetscLayoutSetLocalSize()`, `PetscLayoutGetLocalSize()`, `PetscLayoutGetBlockSize()`,
591db781477SPatrick Sanan `PetscLayoutGetRange()`, `PetscLayoutGetRanges()`, `PetscLayoutSetSize()`, `PetscLayoutGetSize()`, `PetscLayoutSetUp()`
592f92d6284SStefano Zampini @*/
PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool * congruent)593d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscLayoutCompare(PetscLayout mapa, PetscLayout mapb, PetscBool *congruent)
594d71ae5a4SJacob Faibussowitsch {
595f92d6284SStefano Zampini PetscFunctionBegin;
596f92d6284SStefano Zampini *congruent = PETSC_FALSE;
59748a46eb9SPierre Jolivet if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) PetscCall(PetscArraycmp(mapa->range, mapb->range, mapa->size + 1, congruent));
5983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
599f92d6284SStefano Zampini }
6005d83a8b1SBarry Smith
6015d83a8b1SBarry Smith /*@
6025d83a8b1SBarry Smith PetscLayoutFindOwner - Find the owning MPI process for a global index
6035d83a8b1SBarry Smith
6045d83a8b1SBarry Smith Not Collective; No Fortran Support
6055d83a8b1SBarry Smith
6065d83a8b1SBarry Smith Input Parameters:
6075d83a8b1SBarry Smith + map - the layout
6085d83a8b1SBarry Smith - idx - global index to find the owner of
6095d83a8b1SBarry Smith
6105d83a8b1SBarry Smith Output Parameter:
6115d83a8b1SBarry Smith . owner - the owning rank
6125d83a8b1SBarry Smith
6135d83a8b1SBarry Smith Level: developer
6145d83a8b1SBarry Smith
6155d83a8b1SBarry Smith .seealso: `PetscLayout`, `PetscLayoutFindOwnerIndex()`
6165d83a8b1SBarry Smith @*/
PetscLayoutFindOwner(PetscLayout map,PetscInt idx,PetscMPIInt * owner)6175d83a8b1SBarry Smith PetscErrorCode PetscLayoutFindOwner(PetscLayout map, PetscInt idx, PetscMPIInt *owner)
6185d83a8b1SBarry Smith {
6195d83a8b1SBarry Smith PetscMPIInt lo = 0, hi, t;
6205d83a8b1SBarry Smith
6215d83a8b1SBarry Smith PetscFunctionBegin;
6225d83a8b1SBarry Smith *owner = -1; /* GCC erroneously issues warning about possibly uninitialized use when error condition */
6235d83a8b1SBarry Smith PetscAssert((map->n >= 0) && (map->N >= 0) && (map->range), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscLayoutSetUp() must be called first");
6245d83a8b1SBarry Smith PetscAssert(idx >= 0 && idx <= map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is out of range", idx);
6255d83a8b1SBarry Smith hi = map->size;
6265d83a8b1SBarry Smith while (hi - lo > 1) {
6275d83a8b1SBarry Smith t = lo + (hi - lo) / 2;
6285d83a8b1SBarry Smith if (idx < map->range[t]) hi = t;
6295d83a8b1SBarry Smith else lo = t;
6305d83a8b1SBarry Smith }
6315d83a8b1SBarry Smith *owner = lo;
6325d83a8b1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS);
6335d83a8b1SBarry Smith }
6345d83a8b1SBarry Smith
6355d83a8b1SBarry Smith /*@
6365d83a8b1SBarry Smith PetscLayoutFindOwnerIndex - Find the owning MPI process and the local index on that process for a global index
6375d83a8b1SBarry Smith
6385d83a8b1SBarry Smith Not Collective; No Fortran Support
6395d83a8b1SBarry Smith
6405d83a8b1SBarry Smith Input Parameters:
6415d83a8b1SBarry Smith + map - the layout
6425d83a8b1SBarry Smith - idx - global index to find the owner of
6435d83a8b1SBarry Smith
6445d83a8b1SBarry Smith Output Parameters:
6455d83a8b1SBarry Smith + owner - the owning rank
6465d83a8b1SBarry Smith - lidx - local index used by the owner for `idx`
6475d83a8b1SBarry Smith
6485d83a8b1SBarry Smith Level: developer
6495d83a8b1SBarry Smith
6505d83a8b1SBarry Smith .seealso: `PetscLayout`, `PetscLayoutFindOwner()`
6515d83a8b1SBarry Smith @*/
PetscLayoutFindOwnerIndex(PetscLayout map,PetscInt idx,PetscMPIInt * owner,PetscInt * lidx)6525d83a8b1SBarry Smith PetscErrorCode PetscLayoutFindOwnerIndex(PetscLayout map, PetscInt idx, PetscMPIInt *owner, PetscInt *lidx)
6535d83a8b1SBarry Smith {
6545d83a8b1SBarry Smith PetscMPIInt lo = 0, hi, t;
6555d83a8b1SBarry Smith
6565d83a8b1SBarry Smith PetscFunctionBegin;
6575d83a8b1SBarry Smith PetscAssert((map->n >= 0) && (map->N >= 0) && (map->range), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "PetscLayoutSetUp() must be called first");
6585d83a8b1SBarry Smith PetscAssert(idx >= 0 && idx <= map->N, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is out of range", idx);
6595d83a8b1SBarry Smith hi = map->size;
6605d83a8b1SBarry Smith while (hi - lo > 1) {
6615d83a8b1SBarry Smith t = lo + (hi - lo) / 2;
6625d83a8b1SBarry Smith if (idx < map->range[t]) hi = t;
6635d83a8b1SBarry Smith else lo = t;
6645d83a8b1SBarry Smith }
6655d83a8b1SBarry Smith if (owner) *owner = lo;
6665d83a8b1SBarry Smith if (lidx) *lidx = idx - map->range[lo];
6675d83a8b1SBarry Smith PetscFunctionReturn(PETSC_SUCCESS);
6685d83a8b1SBarry Smith }
669