xref: /petsc/src/vec/is/utils/pmap.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
169ce434fSBarry Smith 
269ce434fSBarry Smith /*
369ce434fSBarry Smith    This file contains routines for basic map object implementation.
469ce434fSBarry Smith */
569ce434fSBarry Smith 
657e2745dSVaclav Hapla #include <petsc/private/isimpl.h> /*I "petscis.h" I*/
75c25fcd7SBarry Smith 
8c3002683SMatthew G. Knepley /*@
9a8643c1eSVaclav Hapla   PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default.
1069ce434fSBarry Smith 
11d083f849SBarry Smith   Collective
1269ce434fSBarry Smith 
1369ce434fSBarry Smith   Input Parameters:
14a8643c1eSVaclav Hapla . comm - the MPI communicator
15a8643c1eSVaclav Hapla 
16a8643c1eSVaclav Hapla   Output Parameters:
17a8643c1eSVaclav Hapla . map - the new PetscLayout
1869ce434fSBarry Smith 
19456fcb79SJed Brown   Level: advanced
2069ce434fSBarry Smith 
21456fcb79SJed Brown   Notes:
22456fcb79SJed Brown   Typical calling sequence
23456fcb79SJed Brown .vb
2469ce434fSBarry Smith        PetscLayoutCreate(MPI_Comm,PetscLayout *);
25a8643c1eSVaclav Hapla        PetscLayoutSetBlockSize(PetscLayout,bs);
26a8643c1eSVaclav Hapla        PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n);
2769ce434fSBarry Smith        PetscLayoutSetUp(PetscLayout);
28456fcb79SJed Brown .ve
299621ec18SVaclav Hapla   Alternatively,
309621ec18SVaclav Hapla $      PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
319621ec18SVaclav Hapla 
3269ce434fSBarry Smith   Optionally use any of the following:
33456fcb79SJed Brown 
34456fcb79SJed Brown + PetscLayoutGetSize(PetscLayout,PetscInt *);
35456fcb79SJed Brown . PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
36456fcb79SJed Brown . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
37456fcb79SJed Brown . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
38456fcb79SJed Brown - PetscLayoutDestroy(PetscLayout*);
3969ce434fSBarry Smith 
4069ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
4169ce434fSBarry Smith   user codes unless you really gain something in their use.
4269ce434fSBarry Smith 
4369ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
449621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(),
459621ec18SVaclav Hapla           PetscLayoutCreateFromSizes()
4669ce434fSBarry Smith 
4769ce434fSBarry Smith @*/
4869ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
4969ce434fSBarry Smith {
5069ce434fSBarry Smith   PetscErrorCode ierr;
5169ce434fSBarry Smith 
5269ce434fSBarry Smith   PetscFunctionBegin;
53b00a9115SJed Brown   ierr = PetscNew(map);CHKERRQ(ierr);
5455b25c41SPierre Jolivet   ierr = MPI_Comm_size(comm, &(*map)->size);CHKERRMPI(ierr);
5569ce434fSBarry Smith   (*map)->comm        = comm;
5669ce434fSBarry Smith   (*map)->bs          = -1;
5769ce434fSBarry Smith   (*map)->n           = -1;
5869ce434fSBarry Smith   (*map)->N           = -1;
59f92d6284SStefano Zampini   (*map)->range       = NULL;
609621ec18SVaclav Hapla   (*map)->range_alloc = PETSC_TRUE;
6169ce434fSBarry Smith   (*map)->rstart      = 0;
6269ce434fSBarry Smith   (*map)->rend        = 0;
63ca5434daSLawrence Mitchell   (*map)->setupcalled = PETSC_FALSE;
64ca5434daSLawrence Mitchell   (*map)->oldn        = -1;
65ca5434daSLawrence Mitchell   (*map)->oldN        = -1;
66ca5434daSLawrence Mitchell   (*map)->oldbs       = -1;
6769ce434fSBarry Smith   PetscFunctionReturn(0);
6869ce434fSBarry Smith }
6969ce434fSBarry Smith 
70c3002683SMatthew G. Knepley /*@
719621ec18SVaclav Hapla   PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up.
729621ec18SVaclav Hapla 
739621ec18SVaclav Hapla   Collective
749621ec18SVaclav Hapla 
759621ec18SVaclav Hapla   Input Parameters:
769621ec18SVaclav Hapla + comm  - the MPI communicator
779621ec18SVaclav Hapla . n     - the local size (or PETSC_DECIDE)
789621ec18SVaclav Hapla . N     - the global size (or PETSC_DECIDE)
79f0fc11ceSJed Brown - bs    - the block size (or PETSC_DECIDE)
809621ec18SVaclav Hapla 
819621ec18SVaclav Hapla   Output Parameters:
829621ec18SVaclav Hapla . map - the new PetscLayout
839621ec18SVaclav Hapla 
849621ec18SVaclav Hapla   Level: advanced
859621ec18SVaclav Hapla 
869621ec18SVaclav Hapla   Notes:
879621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
889621ec18SVaclav Hapla   is a shorthand for
899621ec18SVaclav Hapla .vb
909621ec18SVaclav Hapla   PetscLayoutCreate(comm,&layout);
919621ec18SVaclav Hapla   PetscLayoutSetLocalSize(layout,n);
929621ec18SVaclav Hapla   PetscLayoutSetSize(layout,N);
939621ec18SVaclav Hapla   PetscLayoutSetBlockSize(layout,bs);
949621ec18SVaclav Hapla   PetscLayoutSetUp(layout);
959621ec18SVaclav Hapla .ve
969621ec18SVaclav Hapla 
979621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
989621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromRanges()
999621ec18SVaclav Hapla 
1009621ec18SVaclav Hapla @*/
1019621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt bs,PetscLayout *map)
1029621ec18SVaclav Hapla {
1039621ec18SVaclav Hapla   PetscErrorCode ierr;
1049621ec18SVaclav Hapla 
1059621ec18SVaclav Hapla   PetscFunctionBegin;
1069621ec18SVaclav Hapla   ierr = PetscLayoutCreate(comm, map);CHKERRQ(ierr);
1079621ec18SVaclav Hapla   ierr = PetscLayoutSetLocalSize(*map, n);CHKERRQ(ierr);
1089621ec18SVaclav Hapla   ierr = PetscLayoutSetSize(*map, N);CHKERRQ(ierr);
1099621ec18SVaclav Hapla   ierr = PetscLayoutSetBlockSize(*map, bs);CHKERRQ(ierr);
1109621ec18SVaclav Hapla   ierr = PetscLayoutSetUp(*map);CHKERRQ(ierr);
1119621ec18SVaclav Hapla   PetscFunctionReturn(0);
1129621ec18SVaclav Hapla }
1139621ec18SVaclav Hapla 
1149621ec18SVaclav Hapla /*@
11569ce434fSBarry Smith   PetscLayoutDestroy - Frees a map object and frees its range if that exists.
11669ce434fSBarry Smith 
117d083f849SBarry Smith   Collective
11869ce434fSBarry Smith 
11969ce434fSBarry Smith   Input Parameters:
12069ce434fSBarry Smith . map - the PetscLayout
12169ce434fSBarry Smith 
12269ce434fSBarry Smith   Level: developer
12369ce434fSBarry Smith 
124c3002683SMatthew G. Knepley   Note:
12569ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
12669ce434fSBarry Smith   recommended they not be used in user codes unless you really gain something in their use.
12769ce434fSBarry Smith 
12869ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
12969ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
13069ce434fSBarry Smith 
13169ce434fSBarry Smith @*/
13269ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
13369ce434fSBarry Smith {
13469ce434fSBarry Smith   PetscErrorCode ierr;
13569ce434fSBarry Smith 
13669ce434fSBarry Smith   PetscFunctionBegin;
13769ce434fSBarry Smith   if (!*map) PetscFunctionReturn(0);
13869ce434fSBarry Smith   if (!(*map)->refcnt--) {
1399621ec18SVaclav Hapla     if ((*map)->range_alloc) {ierr = PetscFree((*map)->range);CHKERRQ(ierr);}
14069ce434fSBarry Smith     ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr);
14169ce434fSBarry Smith     ierr = PetscFree((*map));CHKERRQ(ierr);
14269ce434fSBarry Smith   }
14369ce434fSBarry Smith   *map = NULL;
14469ce434fSBarry Smith   PetscFunctionReturn(0);
14569ce434fSBarry Smith }
14669ce434fSBarry Smith 
1479621ec18SVaclav Hapla /*@
1489621ec18SVaclav Hapla   PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up.
1499621ec18SVaclav Hapla 
1509621ec18SVaclav Hapla   Collective
1519621ec18SVaclav Hapla 
1529621ec18SVaclav Hapla   Input Parameters:
1539621ec18SVaclav Hapla + comm  - the MPI communicator
1549621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1559621ec18SVaclav Hapla . mode  - the copy mode for range
1569621ec18SVaclav Hapla - bs    - the block size (or PETSC_DECIDE)
1579621ec18SVaclav Hapla 
1589621ec18SVaclav Hapla   Output Parameters:
1599621ec18SVaclav Hapla . newmap - the new PetscLayout
1609621ec18SVaclav Hapla 
1619621ec18SVaclav Hapla   Level: developer
1629621ec18SVaclav Hapla 
1639621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
1649621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromSizes()
1659621ec18SVaclav Hapla 
1669621ec18SVaclav Hapla @*/
1679621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm,const PetscInt range[],PetscCopyMode mode,PetscInt bs,PetscLayout *newmap)
1687b659617SVaclav Hapla {
1699621ec18SVaclav Hapla   PetscLayout    map;
17038a25198SStefano Zampini   PetscMPIInt    rank;
1717b659617SVaclav Hapla   PetscErrorCode ierr;
1727b659617SVaclav Hapla 
1737b659617SVaclav Hapla   PetscFunctionBegin;
174ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1759621ec18SVaclav Hapla   ierr = PetscLayoutCreate(comm, &map);CHKERRQ(ierr);
1769621ec18SVaclav Hapla   ierr = PetscLayoutSetBlockSize(map, bs);CHKERRQ(ierr);
1779621ec18SVaclav Hapla   switch (mode) {
1789621ec18SVaclav Hapla     case PETSC_COPY_VALUES:
17938a25198SStefano Zampini       ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
18038a25198SStefano Zampini       ierr = PetscArraycpy(map->range, range, map->size+1);CHKERRQ(ierr);
1819621ec18SVaclav Hapla       break;
1829621ec18SVaclav Hapla     case PETSC_USE_POINTER:
1839621ec18SVaclav Hapla       map->range_alloc = PETSC_FALSE;
1849621ec18SVaclav Hapla     default:
1859621ec18SVaclav Hapla       map->range = (PetscInt*) range;
1869621ec18SVaclav Hapla       break;
1879621ec18SVaclav Hapla   }
1887b659617SVaclav Hapla   map->rstart = map->range[rank];
1897b659617SVaclav Hapla   map->rend   = map->range[rank+1];
1907b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
19138a25198SStefano Zampini   map->N      = map->range[map->size];
19276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {  /* just check that n, N and bs are consistent */
1937b659617SVaclav Hapla     PetscInt tmp;
194820f2d46SBarry Smith     ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRMPI(ierr);
195*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
1967b659617SVaclav Hapla     if (map->bs > 1) {
197*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(map->n % map->bs,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT,map->n,map->bs);
1987b659617SVaclav Hapla     }
1997b659617SVaclav Hapla     if (map->bs > 1) {
200*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(map->N % map->bs,map->comm,PETSC_ERR_PLIB,"Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT,map->N,map->bs);
2017b659617SVaclav Hapla     }
20276bd3646SJed Brown   }
203ca5434daSLawrence Mitchell   /* lock the layout */
204ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
205ca5434daSLawrence Mitchell   map->oldn = map->n;
206ca5434daSLawrence Mitchell   map->oldN = map->N;
207ca5434daSLawrence Mitchell   map->oldbs = map->bs;
2089621ec18SVaclav Hapla   *newmap = map;
2097b659617SVaclav Hapla   PetscFunctionReturn(0);
2107b659617SVaclav Hapla }
2117b659617SVaclav Hapla 
212c3002683SMatthew G. Knepley /*@
21369ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
21469ce434fSBarry Smith                      size sets up the map so that it may be used.
21569ce434fSBarry Smith 
216d083f849SBarry Smith   Collective
21769ce434fSBarry Smith 
21869ce434fSBarry Smith   Input Parameters:
21969ce434fSBarry Smith . map - pointer to the map
22069ce434fSBarry Smith 
22169ce434fSBarry Smith   Level: developer
22269ce434fSBarry Smith 
22395452b02SPatrick Sanan   Notes:
22495452b02SPatrick Sanan     Typical calling sequence
225c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *);
226c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1);
227c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
228c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout);
229c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *);
23069ce434fSBarry Smith 
2317b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
23269ce434fSBarry Smith 
23369ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
23469ce434fSBarry Smith 
23569ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
23669ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
23769ce434fSBarry Smith @*/
23869ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map)
23969ce434fSBarry Smith {
24038a25198SStefano Zampini   PetscMPIInt    rank;
24169ce434fSBarry Smith   PetscInt       p;
24269ce434fSBarry Smith   PetscErrorCode ierr;
24369ce434fSBarry Smith 
24469ce434fSBarry Smith   PetscFunctionBegin;
245*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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 ")", map->oldn, map->oldN, map->n, map->N);
246ca5434daSLawrence Mitchell   if (map->setupcalled) PetscFunctionReturn(0);
24769ce434fSBarry Smith 
248b146b01cSBarry Smith   if (map->n > 0 && map->bs > 1) {
249*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(map->n % map->bs,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT,map->n,map->bs);
250b146b01cSBarry Smith   }
251b146b01cSBarry Smith   if (map->N > 0 && map->bs > 1) {
252*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(map->N % map->bs,map->comm,PETSC_ERR_PLIB,"Global size %" PetscInt_FMT " must be divisible by blocksize %" PetscInt_FMT,map->N,map->bs);
253b146b01cSBarry Smith   }
254b146b01cSBarry Smith 
255ffc4695bSBarry Smith   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRMPI(ierr);
25633d57670SJed Brown   if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
25733d57670SJed Brown   if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
25869ce434fSBarry Smith   ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr);
25933d57670SJed Brown   map->n = map->n*PetscAbs(map->bs);
26033d57670SJed Brown   map->N = map->N*PetscAbs(map->bs);
26169ce434fSBarry Smith   if (!map->range) {
26238a25198SStefano Zampini     ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
26369ce434fSBarry Smith   }
264ffc4695bSBarry Smith   ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRMPI(ierr);
26569ce434fSBarry Smith 
26669ce434fSBarry Smith   map->range[0] = 0;
26738a25198SStefano Zampini   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p-1];
26869ce434fSBarry Smith 
26969ce434fSBarry Smith   map->rstart = map->range[rank];
27069ce434fSBarry Smith   map->rend   = map->range[rank+1];
271ca5434daSLawrence Mitchell 
272ca5434daSLawrence Mitchell   /* lock the layout */
273ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
274ca5434daSLawrence Mitchell   map->oldn = map->n;
275ca5434daSLawrence Mitchell   map->oldN = map->N;
276ca5434daSLawrence Mitchell   map->oldbs = map->bs;
27769ce434fSBarry Smith   PetscFunctionReturn(0);
27869ce434fSBarry Smith }
27969ce434fSBarry Smith 
280c3002683SMatthew G. Knepley /*@
28169ce434fSBarry Smith   PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
28269ce434fSBarry Smith 
28369ce434fSBarry Smith   Collective on PetscLayout
28469ce434fSBarry Smith 
28569ce434fSBarry Smith   Input Parameter:
28669ce434fSBarry Smith . in - input PetscLayout to be duplicated
28769ce434fSBarry Smith 
28869ce434fSBarry Smith   Output Parameter:
28969ce434fSBarry Smith . out - the copy
29069ce434fSBarry Smith 
29169ce434fSBarry Smith   Level: developer
29269ce434fSBarry Smith 
29395452b02SPatrick Sanan   Notes:
29495452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
29569ce434fSBarry Smith 
29669ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
29769ce434fSBarry Smith @*/
29869ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
29969ce434fSBarry Smith {
30069ce434fSBarry Smith   PetscErrorCode ierr;
30169ce434fSBarry Smith   MPI_Comm       comm = in->comm;
30269ce434fSBarry Smith 
30369ce434fSBarry Smith   PetscFunctionBegin;
30469ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
30569ce434fSBarry Smith   ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr);
30669ce434fSBarry Smith   ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr);
307c168f6d8SVaclav Hapla   if (in->range) {
30838a25198SStefano Zampini     ierr = PetscMalloc1((*out)->size+1,&(*out)->range);CHKERRQ(ierr);
30938a25198SStefano Zampini     ierr = PetscArraycpy((*out)->range,in->range,(*out)->size+1);CHKERRQ(ierr);
310c168f6d8SVaclav Hapla   }
31169ce434fSBarry Smith   (*out)->refcnt = 0;
31269ce434fSBarry Smith   PetscFunctionReturn(0);
31369ce434fSBarry Smith }
31469ce434fSBarry Smith 
315c3002683SMatthew G. Knepley /*@
31669ce434fSBarry Smith   PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
31769ce434fSBarry Smith 
31869ce434fSBarry Smith   Collective on PetscLayout
31969ce434fSBarry Smith 
32069ce434fSBarry Smith   Input Parameter:
32169ce434fSBarry Smith . in - input PetscLayout to be copied
32269ce434fSBarry Smith 
32369ce434fSBarry Smith   Output Parameter:
32469ce434fSBarry Smith . out - the reference location
32569ce434fSBarry Smith 
32669ce434fSBarry Smith   Level: developer
32769ce434fSBarry Smith 
32895452b02SPatrick Sanan   Notes:
32995452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
33069ce434fSBarry Smith 
33169ce434fSBarry Smith   If the out location already contains a PetscLayout it is destroyed
33269ce434fSBarry Smith 
33369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
33469ce434fSBarry Smith @*/
33569ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
33669ce434fSBarry Smith {
33769ce434fSBarry Smith   PetscErrorCode ierr;
33869ce434fSBarry Smith 
33969ce434fSBarry Smith   PetscFunctionBegin;
34069ce434fSBarry Smith   in->refcnt++;
34169ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
34269ce434fSBarry Smith   *out = in;
34369ce434fSBarry Smith   PetscFunctionReturn(0);
34469ce434fSBarry Smith }
34569ce434fSBarry Smith 
346c3002683SMatthew G. Knepley /*@
34769ce434fSBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
34869ce434fSBarry Smith 
34969ce434fSBarry Smith   Collective on PetscLayout
35069ce434fSBarry Smith 
351d8d19677SJose E. Roman   Input Parameters:
35269ce434fSBarry Smith + in - input PetscLayout
35369ce434fSBarry Smith - ltog - the local to global mapping
35469ce434fSBarry Smith 
35569ce434fSBarry Smith   Level: developer
35669ce434fSBarry Smith 
35795452b02SPatrick Sanan   Notes:
35895452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
35969ce434fSBarry Smith 
36069ce434fSBarry Smith   If the ltog location already contains a PetscLayout it is destroyed
36169ce434fSBarry Smith 
362a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
36369ce434fSBarry Smith @*/
36469ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
36569ce434fSBarry Smith {
36669ce434fSBarry Smith   PetscErrorCode ierr;
36769ce434fSBarry Smith 
36869ce434fSBarry Smith   PetscFunctionBegin;
369fc989267SStefano Zampini   if (ltog) {
370fc989267SStefano Zampini     PetscInt bs;
371fc989267SStefano Zampini 
37245b6f7e9SBarry Smith     ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr);
373*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
37469ce434fSBarry Smith     ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
375fc989267SStefano Zampini   }
37669ce434fSBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr);
37769ce434fSBarry Smith   in->mapping = ltog;
37869ce434fSBarry Smith   PetscFunctionReturn(0);
37969ce434fSBarry Smith }
38069ce434fSBarry Smith 
381c3002683SMatthew G. Knepley /*@
38269ce434fSBarry Smith   PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
38369ce434fSBarry Smith 
38469ce434fSBarry Smith   Collective on PetscLayout
38569ce434fSBarry Smith 
38669ce434fSBarry Smith   Input Parameters:
38769ce434fSBarry Smith + map - pointer to the map
38869ce434fSBarry Smith - n - the local size
38969ce434fSBarry Smith 
39069ce434fSBarry Smith   Level: developer
39169ce434fSBarry Smith 
39269ce434fSBarry Smith   Notes:
39369ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
39469ce434fSBarry Smith 
39569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
39669ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
39769ce434fSBarry Smith @*/
39869ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
39969ce434fSBarry Smith {
40069ce434fSBarry Smith   PetscFunctionBegin;
401*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(map->bs > 1 && n % map->bs,map->comm,PETSC_ERR_ARG_INCOMP,"Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT,n,map->bs);
40269ce434fSBarry Smith   map->n = n;
40369ce434fSBarry Smith   PetscFunctionReturn(0);
40469ce434fSBarry Smith }
40569ce434fSBarry Smith 
40669ce434fSBarry Smith /*@C
40769ce434fSBarry Smith      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
40869ce434fSBarry Smith 
40969ce434fSBarry Smith     Not Collective
41069ce434fSBarry Smith 
41169ce434fSBarry Smith    Input Parameters:
41269ce434fSBarry Smith .    map - pointer to the map
41369ce434fSBarry Smith 
41469ce434fSBarry Smith    Output Parameters:
41569ce434fSBarry Smith .    n - the local size
41669ce434fSBarry Smith 
41769ce434fSBarry Smith    Level: developer
41869ce434fSBarry Smith 
41969ce434fSBarry Smith     Notes:
42069ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
42169ce434fSBarry Smith 
42269ce434fSBarry Smith     Fortran Notes:
42369ce434fSBarry Smith       Not available from Fortran
42469ce434fSBarry Smith 
42569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
42669ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
42769ce434fSBarry Smith 
42869ce434fSBarry Smith @*/
42969ce434fSBarry Smith PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
43069ce434fSBarry Smith {
43169ce434fSBarry Smith   PetscFunctionBegin;
43269ce434fSBarry Smith   *n = map->n;
43369ce434fSBarry Smith   PetscFunctionReturn(0);
43469ce434fSBarry Smith }
43569ce434fSBarry Smith 
436c3002683SMatthew G. Knepley /*@
43769ce434fSBarry Smith   PetscLayoutSetSize - Sets the global size for a PetscLayout object.
43869ce434fSBarry Smith 
43969ce434fSBarry Smith   Logically Collective on PetscLayout
44069ce434fSBarry Smith 
44169ce434fSBarry Smith   Input Parameters:
44269ce434fSBarry Smith + map - pointer to the map
44369ce434fSBarry Smith - n - the global size
44469ce434fSBarry Smith 
44569ce434fSBarry Smith   Level: developer
44669ce434fSBarry Smith 
44769ce434fSBarry Smith   Notes:
44869ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
44969ce434fSBarry Smith 
45069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
45169ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
45269ce434fSBarry Smith @*/
45369ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
45469ce434fSBarry Smith {
45569ce434fSBarry Smith   PetscFunctionBegin;
45669ce434fSBarry Smith   map->N = n;
45769ce434fSBarry Smith   PetscFunctionReturn(0);
45869ce434fSBarry Smith }
45969ce434fSBarry Smith 
460c3002683SMatthew G. Knepley /*@
46169ce434fSBarry Smith   PetscLayoutGetSize - Gets the global size for a PetscLayout object.
46269ce434fSBarry Smith 
46369ce434fSBarry Smith   Not Collective
46469ce434fSBarry Smith 
46569ce434fSBarry Smith   Input Parameters:
46669ce434fSBarry Smith . map - pointer to the map
46769ce434fSBarry Smith 
46869ce434fSBarry Smith   Output Parameters:
46969ce434fSBarry Smith . n - the global size
47069ce434fSBarry Smith 
47169ce434fSBarry Smith   Level: developer
47269ce434fSBarry Smith 
47369ce434fSBarry Smith   Notes:
47469ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
47569ce434fSBarry Smith 
47669ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
47769ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
47869ce434fSBarry Smith @*/
47969ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
48069ce434fSBarry Smith {
48169ce434fSBarry Smith   PetscFunctionBegin;
48269ce434fSBarry Smith   *n = map->N;
48369ce434fSBarry Smith   PetscFunctionReturn(0);
48469ce434fSBarry Smith }
48569ce434fSBarry Smith 
486c3002683SMatthew G. Knepley /*@
48769ce434fSBarry Smith   PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
48869ce434fSBarry Smith 
48969ce434fSBarry Smith   Logically Collective on PetscLayout
49069ce434fSBarry Smith 
49169ce434fSBarry Smith   Input Parameters:
49269ce434fSBarry Smith + map - pointer to the map
49369ce434fSBarry Smith - bs - the size
49469ce434fSBarry Smith 
49569ce434fSBarry Smith   Level: developer
49669ce434fSBarry Smith 
49769ce434fSBarry Smith   Notes:
49869ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
49969ce434fSBarry Smith 
50069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
50169ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
50269ce434fSBarry Smith @*/
50369ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
50469ce434fSBarry Smith {
50569ce434fSBarry Smith   PetscFunctionBegin;
50669bbac97SJed Brown   if (bs < 0) PetscFunctionReturn(0);
507*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(map->n > 0 && map->n % bs,PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local size %" PetscInt_FMT " not compatible with block size %" PetscInt_FMT,map->n,bs);
508565245c5SBarry Smith   if (map->mapping) {
509705e6b8bSstefano_zampini     PetscInt       obs;
510565245c5SBarry Smith     PetscErrorCode ierr;
511565245c5SBarry Smith 
512705e6b8bSstefano_zampini     ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr);
513705e6b8bSstefano_zampini     if (obs > 1) {
51463fa5c83Sstefano_zampini       ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr);
515565245c5SBarry Smith     }
516705e6b8bSstefano_zampini   }
51769ce434fSBarry Smith   map->bs = bs;
51869ce434fSBarry Smith   PetscFunctionReturn(0);
51969ce434fSBarry Smith }
52069ce434fSBarry Smith 
521c3002683SMatthew G. Knepley /*@
52269ce434fSBarry Smith   PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
52369ce434fSBarry Smith 
52469ce434fSBarry Smith   Not Collective
52569ce434fSBarry Smith 
52669ce434fSBarry Smith   Input Parameters:
52769ce434fSBarry Smith . map - pointer to the map
52869ce434fSBarry Smith 
52969ce434fSBarry Smith   Output Parameters:
53069ce434fSBarry Smith . bs - the size
53169ce434fSBarry Smith 
53269ce434fSBarry Smith   Level: developer
53369ce434fSBarry Smith 
53469ce434fSBarry Smith   Notes:
53569ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
53669ce434fSBarry Smith 
53769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
53869ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
53969ce434fSBarry Smith @*/
54069ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
54169ce434fSBarry Smith {
54269ce434fSBarry Smith   PetscFunctionBegin;
54333d57670SJed Brown   *bs = PetscAbs(map->bs);
54469ce434fSBarry Smith   PetscFunctionReturn(0);
54569ce434fSBarry Smith }
54669ce434fSBarry Smith 
547c3002683SMatthew G. Knepley /*@
54869ce434fSBarry Smith   PetscLayoutGetRange - gets the range of values owned by this process
54969ce434fSBarry Smith 
55069ce434fSBarry Smith   Not Collective
55169ce434fSBarry Smith 
552f899ff85SJose E. Roman   Input Parameter:
55369ce434fSBarry Smith . map - pointer to the map
55469ce434fSBarry Smith 
55569ce434fSBarry Smith   Output Parameters:
55669ce434fSBarry Smith + rstart - first index owned by this process
55769ce434fSBarry Smith - rend   - one more than the last index owned by this process
55869ce434fSBarry Smith 
55969ce434fSBarry Smith   Level: developer
56069ce434fSBarry Smith 
56169ce434fSBarry Smith   Notes:
56269ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
56369ce434fSBarry Smith 
56469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
56569ce434fSBarry Smith           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
56669ce434fSBarry Smith @*/
56769ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
56869ce434fSBarry Smith {
56969ce434fSBarry Smith   PetscFunctionBegin;
57069ce434fSBarry Smith   if (rstart) *rstart = map->rstart;
57169ce434fSBarry Smith   if (rend)   *rend   = map->rend;
57269ce434fSBarry Smith   PetscFunctionReturn(0);
57369ce434fSBarry Smith }
57469ce434fSBarry Smith 
57569ce434fSBarry Smith /*@C
57669ce434fSBarry Smith      PetscLayoutGetRanges - gets the range of values owned by all processes
57769ce434fSBarry Smith 
57869ce434fSBarry Smith     Not Collective
57969ce434fSBarry Smith 
58069ce434fSBarry Smith    Input Parameters:
58169ce434fSBarry Smith .    map - pointer to the map
58269ce434fSBarry Smith 
58369ce434fSBarry Smith    Output Parameters:
58469ce434fSBarry Smith .    range - start of each processors range of indices (the final entry is one more then the
58569ce434fSBarry Smith              last index on the last process)
58669ce434fSBarry Smith 
58769ce434fSBarry Smith    Level: developer
58869ce434fSBarry Smith 
58969ce434fSBarry Smith     Notes:
59069ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
59169ce434fSBarry Smith 
59269ce434fSBarry Smith     Fortran Notes:
59369ce434fSBarry Smith       Not available from Fortran
59469ce434fSBarry Smith 
59569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
59669ce434fSBarry Smith           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
59769ce434fSBarry Smith 
59869ce434fSBarry Smith @*/
59969ce434fSBarry Smith PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
60069ce434fSBarry Smith {
60169ce434fSBarry Smith   PetscFunctionBegin;
60269ce434fSBarry Smith   *range = map->range;
60369ce434fSBarry Smith   PetscFunctionReturn(0);
60469ce434fSBarry Smith }
60569ce434fSBarry Smith 
606f92d6284SStefano Zampini /*@
607f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
608f92d6284SStefano Zampini 
609f92d6284SStefano Zampini   Not Collective
610f92d6284SStefano Zampini 
611f92d6284SStefano Zampini   Input Parameters:
612d11c674dSStefano Zampini + mapa - pointer to the first map
613f92d6284SStefano Zampini - mapb - pointer to the second map
614f92d6284SStefano Zampini 
615f92d6284SStefano Zampini   Output Parameters:
616f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise
617f92d6284SStefano Zampini 
618f92d6284SStefano Zampini   Level: beginner
619f92d6284SStefano Zampini 
620f92d6284SStefano Zampini   Notes:
621f92d6284SStefano Zampini 
622f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
623f92d6284SStefano Zampini           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
624f92d6284SStefano Zampini @*/
625f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent)
626f92d6284SStefano Zampini {
627f92d6284SStefano Zampini   PetscErrorCode ierr;
628f92d6284SStefano Zampini 
629f92d6284SStefano Zampini   PetscFunctionBegin;
630f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
63138a25198SStefano Zampini   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) {
63238a25198SStefano Zampini     ierr = PetscArraycmp(mapa->range,mapb->range,mapa->size+1,congruent);CHKERRQ(ierr);
633f92d6284SStefano Zampini   }
634f92d6284SStefano Zampini   PetscFunctionReturn(0);
635f92d6284SStefano Zampini }
636a72d46e8SStefano Zampini 
637