xref: /petsc/src/vec/is/utils/pmap.c (revision d9126033840fa4b9e125cadad06c85976e6bf099)
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