xref: /petsc/src/vec/is/utils/pmap.c (revision 147403d98689287189d69e47992b7c8152b2c9da)
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,
30*147403d9SBarry Smith .vb
31*147403d9SBarry Smith       PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
32*147403d9SBarry Smith .ve
339621ec18SVaclav Hapla 
34*147403d9SBarry Smith   Optionally use any of the following
35*147403d9SBarry Smith .vb
36*147403d9SBarry Smith   PetscLayoutGetSize(PetscLayout,PetscInt *);
37*147403d9SBarry Smith   PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
38*147403d9SBarry Smith   PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
39*147403d9SBarry Smith   PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
40*147403d9SBarry Smith   PetscLayoutDestroy(PetscLayout*);
41*147403d9SBarry Smith .ve
4269ce434fSBarry Smith 
4369ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
4469ce434fSBarry Smith   user codes unless you really gain something in their use.
4569ce434fSBarry Smith 
4669ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
479621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(),
489621ec18SVaclav Hapla           PetscLayoutCreateFromSizes()
4969ce434fSBarry Smith 
5069ce434fSBarry Smith @*/
5169ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
5269ce434fSBarry Smith {
5369ce434fSBarry Smith   PetscErrorCode ierr;
5469ce434fSBarry Smith 
5569ce434fSBarry Smith   PetscFunctionBegin;
56b00a9115SJed Brown   ierr = PetscNew(map);CHKERRQ(ierr);
5755b25c41SPierre Jolivet   ierr = MPI_Comm_size(comm, &(*map)->size);CHKERRMPI(ierr);
5869ce434fSBarry Smith   (*map)->comm        = comm;
5969ce434fSBarry Smith   (*map)->bs          = -1;
6069ce434fSBarry Smith   (*map)->n           = -1;
6169ce434fSBarry Smith   (*map)->N           = -1;
62f92d6284SStefano Zampini   (*map)->range       = NULL;
639621ec18SVaclav Hapla   (*map)->range_alloc = PETSC_TRUE;
6469ce434fSBarry Smith   (*map)->rstart      = 0;
6569ce434fSBarry Smith   (*map)->rend        = 0;
66ca5434daSLawrence Mitchell   (*map)->setupcalled = PETSC_FALSE;
67ca5434daSLawrence Mitchell   (*map)->oldn        = -1;
68ca5434daSLawrence Mitchell   (*map)->oldN        = -1;
69ca5434daSLawrence Mitchell   (*map)->oldbs       = -1;
7069ce434fSBarry Smith   PetscFunctionReturn(0);
7169ce434fSBarry Smith }
7269ce434fSBarry Smith 
73c3002683SMatthew G. Knepley /*@
749621ec18SVaclav Hapla   PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up.
759621ec18SVaclav Hapla 
769621ec18SVaclav Hapla   Collective
779621ec18SVaclav Hapla 
789621ec18SVaclav Hapla   Input Parameters:
799621ec18SVaclav Hapla + comm  - the MPI communicator
809621ec18SVaclav Hapla . n     - the local size (or PETSC_DECIDE)
819621ec18SVaclav Hapla . N     - the global size (or PETSC_DECIDE)
82f0fc11ceSJed Brown - bs    - the block size (or PETSC_DECIDE)
839621ec18SVaclav Hapla 
849621ec18SVaclav Hapla   Output Parameters:
859621ec18SVaclav Hapla . map - the new PetscLayout
869621ec18SVaclav Hapla 
879621ec18SVaclav Hapla   Level: advanced
889621ec18SVaclav Hapla 
899621ec18SVaclav Hapla   Notes:
909621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
919621ec18SVaclav Hapla   is a shorthand for
929621ec18SVaclav Hapla .vb
939621ec18SVaclav Hapla   PetscLayoutCreate(comm,&layout);
949621ec18SVaclav Hapla   PetscLayoutSetLocalSize(layout,n);
959621ec18SVaclav Hapla   PetscLayoutSetSize(layout,N);
969621ec18SVaclav Hapla   PetscLayoutSetBlockSize(layout,bs);
979621ec18SVaclav Hapla   PetscLayoutSetUp(layout);
989621ec18SVaclav Hapla .ve
999621ec18SVaclav Hapla 
1009621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
1019621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromRanges()
1029621ec18SVaclav Hapla 
1039621ec18SVaclav Hapla @*/
1049621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt bs,PetscLayout *map)
1059621ec18SVaclav Hapla {
1069621ec18SVaclav Hapla   PetscErrorCode ierr;
1079621ec18SVaclav Hapla 
1089621ec18SVaclav Hapla   PetscFunctionBegin;
1099621ec18SVaclav Hapla   ierr = PetscLayoutCreate(comm, map);CHKERRQ(ierr);
1109621ec18SVaclav Hapla   ierr = PetscLayoutSetLocalSize(*map, n);CHKERRQ(ierr);
1119621ec18SVaclav Hapla   ierr = PetscLayoutSetSize(*map, N);CHKERRQ(ierr);
1129621ec18SVaclav Hapla   ierr = PetscLayoutSetBlockSize(*map, bs);CHKERRQ(ierr);
1139621ec18SVaclav Hapla   ierr = PetscLayoutSetUp(*map);CHKERRQ(ierr);
1149621ec18SVaclav Hapla   PetscFunctionReturn(0);
1159621ec18SVaclav Hapla }
1169621ec18SVaclav Hapla 
1179621ec18SVaclav Hapla /*@
11869ce434fSBarry Smith   PetscLayoutDestroy - Frees a map object and frees its range if that exists.
11969ce434fSBarry Smith 
120d083f849SBarry Smith   Collective
12169ce434fSBarry Smith 
12269ce434fSBarry Smith   Input Parameters:
12369ce434fSBarry Smith . map - the PetscLayout
12469ce434fSBarry Smith 
12569ce434fSBarry Smith   Level: developer
12669ce434fSBarry Smith 
127c3002683SMatthew G. Knepley   Note:
12869ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
12969ce434fSBarry Smith   recommended they not be used in user codes unless you really gain something in their use.
13069ce434fSBarry Smith 
13169ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
13269ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
13369ce434fSBarry Smith 
13469ce434fSBarry Smith @*/
13569ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
13669ce434fSBarry Smith {
13769ce434fSBarry Smith   PetscErrorCode ierr;
13869ce434fSBarry Smith 
13969ce434fSBarry Smith   PetscFunctionBegin;
14069ce434fSBarry Smith   if (!*map) PetscFunctionReturn(0);
14169ce434fSBarry Smith   if (!(*map)->refcnt--) {
1429621ec18SVaclav Hapla     if ((*map)->range_alloc) {ierr = PetscFree((*map)->range);CHKERRQ(ierr);}
14369ce434fSBarry Smith     ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr);
14469ce434fSBarry Smith     ierr = PetscFree((*map));CHKERRQ(ierr);
14569ce434fSBarry Smith   }
14669ce434fSBarry Smith   *map = NULL;
14769ce434fSBarry Smith   PetscFunctionReturn(0);
14869ce434fSBarry Smith }
14969ce434fSBarry Smith 
1509621ec18SVaclav Hapla /*@
1519621ec18SVaclav Hapla   PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up.
1529621ec18SVaclav Hapla 
1539621ec18SVaclav Hapla   Collective
1549621ec18SVaclav Hapla 
1559621ec18SVaclav Hapla   Input Parameters:
1569621ec18SVaclav Hapla + comm  - the MPI communicator
1579621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1589621ec18SVaclav Hapla . mode  - the copy mode for range
1599621ec18SVaclav Hapla - bs    - the block size (or PETSC_DECIDE)
1609621ec18SVaclav Hapla 
1619621ec18SVaclav Hapla   Output Parameters:
1629621ec18SVaclav Hapla . newmap - the new PetscLayout
1639621ec18SVaclav Hapla 
1649621ec18SVaclav Hapla   Level: developer
1659621ec18SVaclav Hapla 
1669621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
1679621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromSizes()
1689621ec18SVaclav Hapla 
1699621ec18SVaclav Hapla @*/
1709621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm,const PetscInt range[],PetscCopyMode mode,PetscInt bs,PetscLayout *newmap)
1717b659617SVaclav Hapla {
1729621ec18SVaclav Hapla   PetscLayout    map;
17338a25198SStefano Zampini   PetscMPIInt    rank;
1747b659617SVaclav Hapla   PetscErrorCode ierr;
1757b659617SVaclav Hapla 
1767b659617SVaclav Hapla   PetscFunctionBegin;
177ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1789621ec18SVaclav Hapla   ierr = PetscLayoutCreate(comm, &map);CHKERRQ(ierr);
1799621ec18SVaclav Hapla   ierr = PetscLayoutSetBlockSize(map, bs);CHKERRQ(ierr);
1809621ec18SVaclav Hapla   switch (mode) {
1819621ec18SVaclav Hapla     case PETSC_COPY_VALUES:
18238a25198SStefano Zampini       ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
18338a25198SStefano Zampini       ierr = PetscArraycpy(map->range, range, map->size+1);CHKERRQ(ierr);
1849621ec18SVaclav Hapla       break;
1859621ec18SVaclav Hapla     case PETSC_USE_POINTER:
1869621ec18SVaclav Hapla       map->range_alloc = PETSC_FALSE;
1879621ec18SVaclav Hapla     default:
1889621ec18SVaclav Hapla       map->range = (PetscInt*) range;
1899621ec18SVaclav Hapla       break;
1909621ec18SVaclav Hapla   }
1917b659617SVaclav Hapla   map->rstart = map->range[rank];
1927b659617SVaclav Hapla   map->rend   = map->range[rank+1];
1937b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
19438a25198SStefano Zampini   map->N      = map->range[map->size];
19576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {  /* just check that n, N and bs are consistent */
1967b659617SVaclav Hapla     PetscInt tmp;
197820f2d46SBarry Smith     ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRMPI(ierr);
1982c71b3e2SJacob 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);
1997b659617SVaclav Hapla     if (map->bs > 1) {
2002c71b3e2SJacob 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);
2017b659617SVaclav Hapla     }
2027b659617SVaclav Hapla     if (map->bs > 1) {
2032c71b3e2SJacob 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);
2047b659617SVaclav Hapla     }
20576bd3646SJed Brown   }
206ca5434daSLawrence Mitchell   /* lock the layout */
207ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
208ca5434daSLawrence Mitchell   map->oldn = map->n;
209ca5434daSLawrence Mitchell   map->oldN = map->N;
210ca5434daSLawrence Mitchell   map->oldbs = map->bs;
2119621ec18SVaclav Hapla   *newmap = map;
2127b659617SVaclav Hapla   PetscFunctionReturn(0);
2137b659617SVaclav Hapla }
2147b659617SVaclav Hapla 
215c3002683SMatthew G. Knepley /*@
21669ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
21769ce434fSBarry Smith                      size sets up the map so that it may be used.
21869ce434fSBarry Smith 
219d083f849SBarry Smith   Collective
22069ce434fSBarry Smith 
22169ce434fSBarry Smith   Input Parameters:
22269ce434fSBarry Smith . map - pointer to the map
22369ce434fSBarry Smith 
22469ce434fSBarry Smith   Level: developer
22569ce434fSBarry Smith 
22695452b02SPatrick Sanan   Notes:
22795452b02SPatrick Sanan     Typical calling sequence
228c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *);
229c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1);
230c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
231c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout);
232c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *);
23369ce434fSBarry Smith 
2347b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
23569ce434fSBarry Smith 
23669ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
23769ce434fSBarry Smith 
23869ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
23969ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
24069ce434fSBarry Smith @*/
24169ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map)
24269ce434fSBarry Smith {
24338a25198SStefano Zampini   PetscMPIInt    rank;
24469ce434fSBarry Smith   PetscInt       p;
24569ce434fSBarry Smith   PetscErrorCode ierr;
24669ce434fSBarry Smith 
24769ce434fSBarry Smith   PetscFunctionBegin;
2482c71b3e2SJacob 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);
249ca5434daSLawrence Mitchell   if (map->setupcalled) PetscFunctionReturn(0);
25069ce434fSBarry Smith 
251b146b01cSBarry Smith   if (map->n > 0 && map->bs > 1) {
2522c71b3e2SJacob 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);
253b146b01cSBarry Smith   }
254b146b01cSBarry Smith   if (map->N > 0 && map->bs > 1) {
2552c71b3e2SJacob 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);
256b146b01cSBarry Smith   }
257b146b01cSBarry Smith 
258ffc4695bSBarry Smith   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRMPI(ierr);
25933d57670SJed Brown   if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
26033d57670SJed Brown   if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
26169ce434fSBarry Smith   ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr);
26233d57670SJed Brown   map->n = map->n*PetscAbs(map->bs);
26333d57670SJed Brown   map->N = map->N*PetscAbs(map->bs);
26469ce434fSBarry Smith   if (!map->range) {
26538a25198SStefano Zampini     ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
26669ce434fSBarry Smith   }
267ffc4695bSBarry Smith   ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRMPI(ierr);
26869ce434fSBarry Smith 
26969ce434fSBarry Smith   map->range[0] = 0;
27038a25198SStefano Zampini   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p-1];
27169ce434fSBarry Smith 
27269ce434fSBarry Smith   map->rstart = map->range[rank];
27369ce434fSBarry Smith   map->rend   = map->range[rank+1];
274ca5434daSLawrence Mitchell 
275ca5434daSLawrence Mitchell   /* lock the layout */
276ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
277ca5434daSLawrence Mitchell   map->oldn = map->n;
278ca5434daSLawrence Mitchell   map->oldN = map->N;
279ca5434daSLawrence Mitchell   map->oldbs = map->bs;
28069ce434fSBarry Smith   PetscFunctionReturn(0);
28169ce434fSBarry Smith }
28269ce434fSBarry Smith 
283c3002683SMatthew G. Knepley /*@
28469ce434fSBarry Smith   PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
28569ce434fSBarry Smith 
28669ce434fSBarry Smith   Collective on PetscLayout
28769ce434fSBarry Smith 
28869ce434fSBarry Smith   Input Parameter:
28969ce434fSBarry Smith . in - input PetscLayout to be duplicated
29069ce434fSBarry Smith 
29169ce434fSBarry Smith   Output Parameter:
29269ce434fSBarry Smith . out - the copy
29369ce434fSBarry Smith 
29469ce434fSBarry Smith   Level: developer
29569ce434fSBarry Smith 
29695452b02SPatrick Sanan   Notes:
29795452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
29869ce434fSBarry Smith 
29969ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
30069ce434fSBarry Smith @*/
30169ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
30269ce434fSBarry Smith {
30369ce434fSBarry Smith   PetscErrorCode ierr;
30469ce434fSBarry Smith   MPI_Comm       comm = in->comm;
30569ce434fSBarry Smith 
30669ce434fSBarry Smith   PetscFunctionBegin;
30769ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
30869ce434fSBarry Smith   ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr);
30969ce434fSBarry Smith   ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr);
310c168f6d8SVaclav Hapla   if (in->range) {
31138a25198SStefano Zampini     ierr = PetscMalloc1((*out)->size+1,&(*out)->range);CHKERRQ(ierr);
31238a25198SStefano Zampini     ierr = PetscArraycpy((*out)->range,in->range,(*out)->size+1);CHKERRQ(ierr);
313c168f6d8SVaclav Hapla   }
31469ce434fSBarry Smith   (*out)->refcnt = 0;
31569ce434fSBarry Smith   PetscFunctionReturn(0);
31669ce434fSBarry Smith }
31769ce434fSBarry Smith 
318c3002683SMatthew G. Knepley /*@
31969ce434fSBarry Smith   PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
32069ce434fSBarry Smith 
32169ce434fSBarry Smith   Collective on PetscLayout
32269ce434fSBarry Smith 
32369ce434fSBarry Smith   Input Parameter:
32469ce434fSBarry Smith . in - input PetscLayout to be copied
32569ce434fSBarry Smith 
32669ce434fSBarry Smith   Output Parameter:
32769ce434fSBarry Smith . out - the reference location
32869ce434fSBarry Smith 
32969ce434fSBarry Smith   Level: developer
33069ce434fSBarry Smith 
33195452b02SPatrick Sanan   Notes:
33295452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
33369ce434fSBarry Smith 
33469ce434fSBarry Smith   If the out location already contains a PetscLayout it is destroyed
33569ce434fSBarry Smith 
33669ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
33769ce434fSBarry Smith @*/
33869ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
33969ce434fSBarry Smith {
34069ce434fSBarry Smith   PetscErrorCode ierr;
34169ce434fSBarry Smith 
34269ce434fSBarry Smith   PetscFunctionBegin;
34369ce434fSBarry Smith   in->refcnt++;
34469ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
34569ce434fSBarry Smith   *out = in;
34669ce434fSBarry Smith   PetscFunctionReturn(0);
34769ce434fSBarry Smith }
34869ce434fSBarry Smith 
349c3002683SMatthew G. Knepley /*@
35069ce434fSBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
35169ce434fSBarry Smith 
35269ce434fSBarry Smith   Collective on PetscLayout
35369ce434fSBarry Smith 
354d8d19677SJose E. Roman   Input Parameters:
35569ce434fSBarry Smith + in - input PetscLayout
35669ce434fSBarry Smith - ltog - the local to global mapping
35769ce434fSBarry Smith 
35869ce434fSBarry Smith   Level: developer
35969ce434fSBarry Smith 
36095452b02SPatrick Sanan   Notes:
36195452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
36269ce434fSBarry Smith 
36369ce434fSBarry Smith   If the ltog location already contains a PetscLayout it is destroyed
36469ce434fSBarry Smith 
365a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
36669ce434fSBarry Smith @*/
36769ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
36869ce434fSBarry Smith {
36969ce434fSBarry Smith   PetscErrorCode ierr;
37069ce434fSBarry Smith 
37169ce434fSBarry Smith   PetscFunctionBegin;
372fc989267SStefano Zampini   if (ltog) {
373fc989267SStefano Zampini     PetscInt bs;
374fc989267SStefano Zampini 
37545b6f7e9SBarry Smith     ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr);
3762c71b3e2SJacob 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);
37769ce434fSBarry Smith     ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
378fc989267SStefano Zampini   }
37969ce434fSBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr);
38069ce434fSBarry Smith   in->mapping = ltog;
38169ce434fSBarry Smith   PetscFunctionReturn(0);
38269ce434fSBarry Smith }
38369ce434fSBarry Smith 
384c3002683SMatthew G. Knepley /*@
38569ce434fSBarry Smith   PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
38669ce434fSBarry Smith 
38769ce434fSBarry Smith   Collective on PetscLayout
38869ce434fSBarry Smith 
38969ce434fSBarry Smith   Input Parameters:
39069ce434fSBarry Smith + map - pointer to the map
39169ce434fSBarry Smith - n - the local size
39269ce434fSBarry Smith 
39369ce434fSBarry Smith   Level: developer
39469ce434fSBarry Smith 
39569ce434fSBarry Smith   Notes:
39669ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
39769ce434fSBarry Smith 
39869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
39969ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
40069ce434fSBarry Smith @*/
40169ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
40269ce434fSBarry Smith {
40369ce434fSBarry Smith   PetscFunctionBegin;
4042c71b3e2SJacob 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);
40569ce434fSBarry Smith   map->n = n;
40669ce434fSBarry Smith   PetscFunctionReturn(0);
40769ce434fSBarry Smith }
40869ce434fSBarry Smith 
40969ce434fSBarry Smith /*@C
41069ce434fSBarry Smith      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
41169ce434fSBarry Smith 
41269ce434fSBarry Smith     Not Collective
41369ce434fSBarry Smith 
41469ce434fSBarry Smith    Input Parameters:
41569ce434fSBarry Smith .    map - pointer to the map
41669ce434fSBarry Smith 
41769ce434fSBarry Smith    Output Parameters:
41869ce434fSBarry Smith .    n - the local size
41969ce434fSBarry Smith 
42069ce434fSBarry Smith    Level: developer
42169ce434fSBarry Smith 
42269ce434fSBarry Smith     Notes:
42369ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
42469ce434fSBarry Smith 
42569ce434fSBarry Smith     Fortran Notes:
42669ce434fSBarry Smith       Not available from Fortran
42769ce434fSBarry Smith 
42869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
42969ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
43069ce434fSBarry Smith 
43169ce434fSBarry Smith @*/
43269ce434fSBarry Smith PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
43369ce434fSBarry Smith {
43469ce434fSBarry Smith   PetscFunctionBegin;
43569ce434fSBarry Smith   *n = map->n;
43669ce434fSBarry Smith   PetscFunctionReturn(0);
43769ce434fSBarry Smith }
43869ce434fSBarry Smith 
439c3002683SMatthew G. Knepley /*@
44069ce434fSBarry Smith   PetscLayoutSetSize - Sets the global size for a PetscLayout object.
44169ce434fSBarry Smith 
44269ce434fSBarry Smith   Logically Collective on PetscLayout
44369ce434fSBarry Smith 
44469ce434fSBarry Smith   Input Parameters:
44569ce434fSBarry Smith + map - pointer to the map
44669ce434fSBarry Smith - n - the global size
44769ce434fSBarry Smith 
44869ce434fSBarry Smith   Level: developer
44969ce434fSBarry Smith 
45069ce434fSBarry Smith   Notes:
45169ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
45269ce434fSBarry Smith 
45369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
45469ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
45569ce434fSBarry Smith @*/
45669ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
45769ce434fSBarry Smith {
45869ce434fSBarry Smith   PetscFunctionBegin;
45969ce434fSBarry Smith   map->N = n;
46069ce434fSBarry Smith   PetscFunctionReturn(0);
46169ce434fSBarry Smith }
46269ce434fSBarry Smith 
463c3002683SMatthew G. Knepley /*@
46469ce434fSBarry Smith   PetscLayoutGetSize - Gets the global size for a PetscLayout object.
46569ce434fSBarry Smith 
46669ce434fSBarry Smith   Not Collective
46769ce434fSBarry Smith 
46869ce434fSBarry Smith   Input Parameters:
46969ce434fSBarry Smith . map - pointer to the map
47069ce434fSBarry Smith 
47169ce434fSBarry Smith   Output Parameters:
47269ce434fSBarry Smith . n - the global size
47369ce434fSBarry Smith 
47469ce434fSBarry Smith   Level: developer
47569ce434fSBarry Smith 
47669ce434fSBarry Smith   Notes:
47769ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
47869ce434fSBarry Smith 
47969ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
48069ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
48169ce434fSBarry Smith @*/
48269ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
48369ce434fSBarry Smith {
48469ce434fSBarry Smith   PetscFunctionBegin;
48569ce434fSBarry Smith   *n = map->N;
48669ce434fSBarry Smith   PetscFunctionReturn(0);
48769ce434fSBarry Smith }
48869ce434fSBarry Smith 
489c3002683SMatthew G. Knepley /*@
49069ce434fSBarry Smith   PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
49169ce434fSBarry Smith 
49269ce434fSBarry Smith   Logically Collective on PetscLayout
49369ce434fSBarry Smith 
49469ce434fSBarry Smith   Input Parameters:
49569ce434fSBarry Smith + map - pointer to the map
49669ce434fSBarry Smith - bs - the size
49769ce434fSBarry Smith 
49869ce434fSBarry Smith   Level: developer
49969ce434fSBarry Smith 
50069ce434fSBarry Smith   Notes:
50169ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
50269ce434fSBarry Smith 
50369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
50469ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
50569ce434fSBarry Smith @*/
50669ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
50769ce434fSBarry Smith {
50869ce434fSBarry Smith   PetscFunctionBegin;
50969bbac97SJed Brown   if (bs < 0) PetscFunctionReturn(0);
5102c71b3e2SJacob 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);
511565245c5SBarry Smith   if (map->mapping) {
512705e6b8bSstefano_zampini     PetscInt       obs;
513565245c5SBarry Smith     PetscErrorCode ierr;
514565245c5SBarry Smith 
515705e6b8bSstefano_zampini     ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr);
516705e6b8bSstefano_zampini     if (obs > 1) {
51763fa5c83Sstefano_zampini       ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr);
518565245c5SBarry Smith     }
519705e6b8bSstefano_zampini   }
52069ce434fSBarry Smith   map->bs = bs;
52169ce434fSBarry Smith   PetscFunctionReturn(0);
52269ce434fSBarry Smith }
52369ce434fSBarry Smith 
524c3002683SMatthew G. Knepley /*@
52569ce434fSBarry Smith   PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
52669ce434fSBarry Smith 
52769ce434fSBarry Smith   Not Collective
52869ce434fSBarry Smith 
52969ce434fSBarry Smith   Input Parameters:
53069ce434fSBarry Smith . map - pointer to the map
53169ce434fSBarry Smith 
53269ce434fSBarry Smith   Output Parameters:
53369ce434fSBarry Smith . bs - the size
53469ce434fSBarry Smith 
53569ce434fSBarry Smith   Level: developer
53669ce434fSBarry Smith 
53769ce434fSBarry Smith   Notes:
53869ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
53969ce434fSBarry Smith 
54069ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
54169ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
54269ce434fSBarry Smith @*/
54369ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
54469ce434fSBarry Smith {
54569ce434fSBarry Smith   PetscFunctionBegin;
54633d57670SJed Brown   *bs = PetscAbs(map->bs);
54769ce434fSBarry Smith   PetscFunctionReturn(0);
54869ce434fSBarry Smith }
54969ce434fSBarry Smith 
550c3002683SMatthew G. Knepley /*@
55169ce434fSBarry Smith   PetscLayoutGetRange - gets the range of values owned by this process
55269ce434fSBarry Smith 
55369ce434fSBarry Smith   Not Collective
55469ce434fSBarry Smith 
555f899ff85SJose E. Roman   Input Parameter:
55669ce434fSBarry Smith . map - pointer to the map
55769ce434fSBarry Smith 
55869ce434fSBarry Smith   Output Parameters:
55969ce434fSBarry Smith + rstart - first index owned by this process
56069ce434fSBarry Smith - rend   - one more than the last index owned by this process
56169ce434fSBarry Smith 
56269ce434fSBarry Smith   Level: developer
56369ce434fSBarry Smith 
56469ce434fSBarry Smith   Notes:
56569ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
56669ce434fSBarry Smith 
56769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
56869ce434fSBarry Smith           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
56969ce434fSBarry Smith @*/
57069ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
57169ce434fSBarry Smith {
57269ce434fSBarry Smith   PetscFunctionBegin;
57369ce434fSBarry Smith   if (rstart) *rstart = map->rstart;
57469ce434fSBarry Smith   if (rend)   *rend   = map->rend;
57569ce434fSBarry Smith   PetscFunctionReturn(0);
57669ce434fSBarry Smith }
57769ce434fSBarry Smith 
57869ce434fSBarry Smith /*@C
57969ce434fSBarry Smith      PetscLayoutGetRanges - gets the range of values owned by all processes
58069ce434fSBarry Smith 
58169ce434fSBarry Smith     Not Collective
58269ce434fSBarry Smith 
58369ce434fSBarry Smith    Input Parameters:
58469ce434fSBarry Smith .    map - pointer to the map
58569ce434fSBarry Smith 
58669ce434fSBarry Smith    Output Parameters:
58769ce434fSBarry Smith .    range - start of each processors range of indices (the final entry is one more then the
58869ce434fSBarry Smith              last index on the last process)
58969ce434fSBarry Smith 
59069ce434fSBarry Smith    Level: developer
59169ce434fSBarry Smith 
59269ce434fSBarry Smith     Notes:
59369ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
59469ce434fSBarry Smith 
59569ce434fSBarry Smith     Fortran Notes:
59669ce434fSBarry Smith       Not available from Fortran
59769ce434fSBarry Smith 
59869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
59969ce434fSBarry Smith           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
60069ce434fSBarry Smith 
60169ce434fSBarry Smith @*/
60269ce434fSBarry Smith PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
60369ce434fSBarry Smith {
60469ce434fSBarry Smith   PetscFunctionBegin;
60569ce434fSBarry Smith   *range = map->range;
60669ce434fSBarry Smith   PetscFunctionReturn(0);
60769ce434fSBarry Smith }
60869ce434fSBarry Smith 
609f92d6284SStefano Zampini /*@
610f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
611f92d6284SStefano Zampini 
612f92d6284SStefano Zampini   Not Collective
613f92d6284SStefano Zampini 
614f92d6284SStefano Zampini   Input Parameters:
615d11c674dSStefano Zampini + mapa - pointer to the first map
616f92d6284SStefano Zampini - mapb - pointer to the second map
617f92d6284SStefano Zampini 
618f92d6284SStefano Zampini   Output Parameters:
619f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise
620f92d6284SStefano Zampini 
621f92d6284SStefano Zampini   Level: beginner
622f92d6284SStefano Zampini 
623f92d6284SStefano Zampini   Notes:
624f92d6284SStefano Zampini 
625f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
626f92d6284SStefano Zampini           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
627f92d6284SStefano Zampini @*/
628f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent)
629f92d6284SStefano Zampini {
630f92d6284SStefano Zampini   PetscErrorCode ierr;
631f92d6284SStefano Zampini 
632f92d6284SStefano Zampini   PetscFunctionBegin;
633f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
63438a25198SStefano Zampini   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) {
63538a25198SStefano Zampini     ierr = PetscArraycmp(mapa->range,mapb->range,mapa->size+1,congruent);CHKERRQ(ierr);
636f92d6284SStefano Zampini   }
637f92d6284SStefano Zampini   PetscFunctionReturn(0);
638f92d6284SStefano Zampini }
639a72d46e8SStefano Zampini 
640