xref: /petsc/src/vec/is/utils/pmap.c (revision 38a251981c7f9aceca5179b53bf56d5ac9cf2dfa)
169ce434fSBarry Smith 
269ce434fSBarry Smith /*
369ce434fSBarry Smith    This file contains routines for basic map object implementation.
469ce434fSBarry Smith */
569ce434fSBarry Smith 
6c3002683SMatthew G. Knepley #include <petscis.h> /*I "petscis.h" I*/
70c312b8eSJed Brown #include <petscsf.h>
807acc2aeSBarry Smith #include <petsc/private/isimpl.h>
95c25fcd7SBarry Smith 
10c3002683SMatthew G. Knepley /*@
11a8643c1eSVaclav Hapla   PetscLayoutCreate - Allocates PetscLayout space and sets the PetscLayout contents to the default.
1269ce434fSBarry Smith 
13d083f849SBarry Smith   Collective
1469ce434fSBarry Smith 
1569ce434fSBarry Smith   Input Parameters:
16a8643c1eSVaclav Hapla . comm - the MPI communicator
17a8643c1eSVaclav Hapla 
18a8643c1eSVaclav Hapla   Output Parameters:
19a8643c1eSVaclav Hapla . map - the new PetscLayout
2069ce434fSBarry Smith 
21456fcb79SJed Brown   Level: advanced
2269ce434fSBarry Smith 
23456fcb79SJed Brown   Notes:
24456fcb79SJed Brown   Typical calling sequence
25456fcb79SJed Brown .vb
2669ce434fSBarry Smith        PetscLayoutCreate(MPI_Comm,PetscLayout *);
27a8643c1eSVaclav Hapla        PetscLayoutSetBlockSize(PetscLayout,bs);
28a8643c1eSVaclav Hapla        PetscLayoutSetSize(PetscLayout,N); // or PetscLayoutSetLocalSize(PetscLayout,n);
2969ce434fSBarry Smith        PetscLayoutSetUp(PetscLayout);
30456fcb79SJed Brown .ve
319621ec18SVaclav Hapla   Alternatively,
329621ec18SVaclav Hapla $      PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
339621ec18SVaclav Hapla 
3469ce434fSBarry Smith   Optionally use any of the following:
35456fcb79SJed Brown 
36456fcb79SJed Brown + PetscLayoutGetSize(PetscLayout,PetscInt *);
37456fcb79SJed Brown . PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
38456fcb79SJed Brown . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
39456fcb79SJed Brown . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
40456fcb79SJed Brown - PetscLayoutDestroy(PetscLayout*);
4169ce434fSBarry Smith 
4269ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
4369ce434fSBarry Smith   user codes unless you really gain something in their use.
4469ce434fSBarry Smith 
4569ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
469621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(),
479621ec18SVaclav Hapla           PetscLayoutCreateFromSizes()
4869ce434fSBarry Smith 
4969ce434fSBarry Smith @*/
5069ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
5169ce434fSBarry Smith {
5269ce434fSBarry Smith   PetscErrorCode ierr;
5369ce434fSBarry Smith 
5469ce434fSBarry Smith   PetscFunctionBegin;
55b00a9115SJed Brown   ierr = PetscNew(map);CHKERRQ(ierr);
56*38a25198SStefano Zampini   ierr = MPI_Comm_size(comm, &(*map)->size);CHKERRQ(ierr);
5769ce434fSBarry Smith   (*map)->comm        = comm;
5869ce434fSBarry Smith   (*map)->bs          = -1;
5969ce434fSBarry Smith   (*map)->n           = -1;
6069ce434fSBarry Smith   (*map)->N           = -1;
61f92d6284SStefano Zampini   (*map)->range       = NULL;
629621ec18SVaclav Hapla   (*map)->range_alloc = PETSC_TRUE;
6369ce434fSBarry Smith   (*map)->rstart      = 0;
6469ce434fSBarry Smith   (*map)->rend        = 0;
65ca5434daSLawrence Mitchell   (*map)->setupcalled = PETSC_FALSE;
66ca5434daSLawrence Mitchell   (*map)->oldn        = -1;
67ca5434daSLawrence Mitchell   (*map)->oldN        = -1;
68ca5434daSLawrence Mitchell   (*map)->oldbs       = -1;
6969ce434fSBarry Smith   PetscFunctionReturn(0);
7069ce434fSBarry Smith }
7169ce434fSBarry Smith 
72c3002683SMatthew G. Knepley /*@
739621ec18SVaclav Hapla   PetscLayoutCreateFromSizes - Allocates PetscLayout space, sets the layout sizes, and sets the layout up.
749621ec18SVaclav Hapla 
759621ec18SVaclav Hapla   Collective
769621ec18SVaclav Hapla 
779621ec18SVaclav Hapla   Input Parameters:
789621ec18SVaclav Hapla + comm  - the MPI communicator
799621ec18SVaclav Hapla . n     - the local size (or PETSC_DECIDE)
809621ec18SVaclav Hapla . N     - the global size (or PETSC_DECIDE)
81f0fc11ceSJed Brown - bs    - the block size (or PETSC_DECIDE)
829621ec18SVaclav Hapla 
839621ec18SVaclav Hapla   Output Parameters:
849621ec18SVaclav Hapla . map - the new PetscLayout
859621ec18SVaclav Hapla 
869621ec18SVaclav Hapla   Level: advanced
879621ec18SVaclav Hapla 
889621ec18SVaclav Hapla   Notes:
899621ec18SVaclav Hapla $ PetscLayoutCreateFromSizes(comm,n,N,bs,&layout);
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 
999621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
1009621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromRanges()
1019621ec18SVaclav Hapla 
1029621ec18SVaclav Hapla @*/
1039621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromSizes(MPI_Comm comm,PetscInt n,PetscInt N,PetscInt bs,PetscLayout *map)
1049621ec18SVaclav Hapla {
1059621ec18SVaclav Hapla   PetscErrorCode ierr;
1069621ec18SVaclav Hapla 
1079621ec18SVaclav Hapla   PetscFunctionBegin;
1089621ec18SVaclav Hapla   ierr = PetscLayoutCreate(comm, map);CHKERRQ(ierr);
1099621ec18SVaclav Hapla   ierr = PetscLayoutSetLocalSize(*map, n);CHKERRQ(ierr);
1109621ec18SVaclav Hapla   ierr = PetscLayoutSetSize(*map, N);CHKERRQ(ierr);
1119621ec18SVaclav Hapla   ierr = PetscLayoutSetBlockSize(*map, bs);CHKERRQ(ierr);
1129621ec18SVaclav Hapla   ierr = PetscLayoutSetUp(*map);CHKERRQ(ierr);
1139621ec18SVaclav Hapla   PetscFunctionReturn(0);
1149621ec18SVaclav Hapla }
1159621ec18SVaclav Hapla 
1169621ec18SVaclav Hapla /*@
11769ce434fSBarry Smith   PetscLayoutDestroy - Frees a map object and frees its range if that exists.
11869ce434fSBarry Smith 
119d083f849SBarry Smith   Collective
12069ce434fSBarry Smith 
12169ce434fSBarry Smith   Input Parameters:
12269ce434fSBarry Smith . map - the PetscLayout
12369ce434fSBarry Smith 
12469ce434fSBarry Smith   Level: developer
12569ce434fSBarry Smith 
126c3002683SMatthew G. Knepley   Note:
12769ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
12869ce434fSBarry Smith   recommended they not be used in user codes unless you really gain something in their use.
12969ce434fSBarry Smith 
13069ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
13169ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
13269ce434fSBarry Smith 
13369ce434fSBarry Smith @*/
13469ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
13569ce434fSBarry Smith {
13669ce434fSBarry Smith   PetscErrorCode ierr;
13769ce434fSBarry Smith 
13869ce434fSBarry Smith   PetscFunctionBegin;
13969ce434fSBarry Smith   if (!*map) PetscFunctionReturn(0);
14069ce434fSBarry Smith   if (!(*map)->refcnt--) {
1419621ec18SVaclav Hapla     if ((*map)->range_alloc) {ierr = PetscFree((*map)->range);CHKERRQ(ierr);}
14269ce434fSBarry Smith     ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr);
14369ce434fSBarry Smith     ierr = PetscFree((*map));CHKERRQ(ierr);
14469ce434fSBarry Smith   }
14569ce434fSBarry Smith   *map = NULL;
14669ce434fSBarry Smith   PetscFunctionReturn(0);
14769ce434fSBarry Smith }
14869ce434fSBarry Smith 
1499621ec18SVaclav Hapla /*@
1509621ec18SVaclav Hapla   PetscLayoutCreateFromRanges - Creates a new PetscLayout with the given ownership ranges and sets it up.
1519621ec18SVaclav Hapla 
1529621ec18SVaclav Hapla   Collective
1539621ec18SVaclav Hapla 
1549621ec18SVaclav Hapla   Input Parameters:
1559621ec18SVaclav Hapla + comm  - the MPI communicator
1569621ec18SVaclav Hapla . range - the array of ownership ranges for each rank with length commsize+1
1579621ec18SVaclav Hapla . mode  - the copy mode for range
1589621ec18SVaclav Hapla - bs    - the block size (or PETSC_DECIDE)
1599621ec18SVaclav Hapla 
1609621ec18SVaclav Hapla   Output Parameters:
1619621ec18SVaclav Hapla . newmap - the new PetscLayout
1629621ec18SVaclav Hapla 
1639621ec18SVaclav Hapla   Level: developer
1649621ec18SVaclav Hapla 
1659621ec18SVaclav Hapla .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
1669621ec18SVaclav Hapla           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp(), PetscLayoutCreateFromSizes()
1679621ec18SVaclav Hapla 
1689621ec18SVaclav Hapla @*/
1699621ec18SVaclav Hapla PetscErrorCode PetscLayoutCreateFromRanges(MPI_Comm comm,const PetscInt range[],PetscCopyMode mode,PetscInt bs,PetscLayout *newmap)
1707b659617SVaclav Hapla {
1719621ec18SVaclav Hapla   PetscLayout    map;
172*38a25198SStefano Zampini   PetscMPIInt    rank;
1737b659617SVaclav Hapla   PetscErrorCode ierr;
1747b659617SVaclav Hapla 
1757b659617SVaclav Hapla   PetscFunctionBegin;
176ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
1779621ec18SVaclav Hapla   ierr = PetscLayoutCreate(comm, &map);CHKERRQ(ierr);
1789621ec18SVaclav Hapla   ierr = PetscLayoutSetBlockSize(map, bs);CHKERRQ(ierr);
1799621ec18SVaclav Hapla   switch (mode) {
1809621ec18SVaclav Hapla     case PETSC_COPY_VALUES:
181*38a25198SStefano Zampini       ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
182*38a25198SStefano Zampini       ierr = PetscArraycpy(map->range, range, map->size+1);CHKERRQ(ierr);
1839621ec18SVaclav Hapla       break;
1849621ec18SVaclav Hapla     case PETSC_USE_POINTER:
1859621ec18SVaclav Hapla       map->range_alloc = PETSC_FALSE;
1869621ec18SVaclav Hapla     default:
1879621ec18SVaclav Hapla       map->range = (PetscInt*) range;
1889621ec18SVaclav Hapla       break;
1899621ec18SVaclav Hapla   }
1907b659617SVaclav Hapla   map->rstart = map->range[rank];
1917b659617SVaclav Hapla   map->rend   = map->range[rank+1];
1927b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
193*38a25198SStefano Zampini   map->N      = map->range[map->size];
19476bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {  /* just check that n, N and bs are consistent */
1957b659617SVaclav Hapla     PetscInt tmp;
1967b659617SVaclav Hapla     ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr);
1977b659617SVaclav Hapla     if (tmp != map->N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local lengths %D does not equal global length %D, my local length %D.\nThe provided PetscLayout is wrong.",tmp,map->N,map->n);
1987b659617SVaclav Hapla     if (map->bs > 1) {
1997b659617SVaclav Hapla       if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %D must be divisible by blocksize %D",map->n,map->bs);
2007b659617SVaclav Hapla     }
2017b659617SVaclav Hapla     if (map->bs > 1) {
2027b659617SVaclav Hapla       if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global size %D must be divisible by blocksize %D",map->N,map->bs);
2037b659617SVaclav Hapla     }
20476bd3646SJed Brown   }
205ca5434daSLawrence Mitchell   /* lock the layout */
206ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
207ca5434daSLawrence Mitchell   map->oldn = map->n;
208ca5434daSLawrence Mitchell   map->oldN = map->N;
209ca5434daSLawrence Mitchell   map->oldbs = map->bs;
2109621ec18SVaclav Hapla   *newmap = map;
2117b659617SVaclav Hapla   PetscFunctionReturn(0);
2127b659617SVaclav Hapla }
2137b659617SVaclav Hapla 
214c3002683SMatthew G. Knepley /*@
21569ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
21669ce434fSBarry Smith                      size sets up the map so that it may be used.
21769ce434fSBarry Smith 
218d083f849SBarry Smith   Collective
21969ce434fSBarry Smith 
22069ce434fSBarry Smith   Input Parameters:
22169ce434fSBarry Smith . map - pointer to the map
22269ce434fSBarry Smith 
22369ce434fSBarry Smith   Level: developer
22469ce434fSBarry Smith 
22595452b02SPatrick Sanan   Notes:
22695452b02SPatrick Sanan     Typical calling sequence
227c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *);
228c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1);
229c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
230c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout);
231c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *);
23269ce434fSBarry Smith 
2337b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
23469ce434fSBarry Smith 
23569ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
23669ce434fSBarry Smith 
23769ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
23869ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
23969ce434fSBarry Smith @*/
24069ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map)
24169ce434fSBarry Smith {
242*38a25198SStefano Zampini   PetscMPIInt    rank;
24369ce434fSBarry Smith   PetscInt       p;
24469ce434fSBarry Smith   PetscErrorCode ierr;
24569ce434fSBarry Smith 
24669ce434fSBarry Smith   PetscFunctionBegin;
247ca5434daSLawrence Mitchell   if (map->setupcalled && (map->n != map->oldn || map->N != map->oldN)) SETERRQ4(map->comm,PETSC_ERR_ARG_WRONGSTATE,"Layout is already setup with (local=%D,global=%D), cannot call setup again with (local=%D,global=%D)", map->oldn, map->oldN, map->n, map->N);
248ca5434daSLawrence Mitchell   if (map->setupcalled) PetscFunctionReturn(0);
24969ce434fSBarry Smith 
250b146b01cSBarry Smith   if (map->n > 0 && map->bs > 1) {
251ec4d677dSStefano Zampini     if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local size %D must be divisible by blocksize %D",map->n,map->bs);
252b146b01cSBarry Smith   }
253b146b01cSBarry Smith   if (map->N > 0 && map->bs > 1) {
254ec4d677dSStefano Zampini     if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global size %D must be divisible by blocksize %D",map->N,map->bs);
255b146b01cSBarry Smith   }
256b146b01cSBarry Smith 
257ffc4695bSBarry Smith   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRMPI(ierr);
25833d57670SJed Brown   if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
25933d57670SJed Brown   if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
26069ce434fSBarry Smith   ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr);
26133d57670SJed Brown   map->n = map->n*PetscAbs(map->bs);
26233d57670SJed Brown   map->N = map->N*PetscAbs(map->bs);
26369ce434fSBarry Smith   if (!map->range) {
264*38a25198SStefano Zampini     ierr = PetscMalloc1(map->size+1, &map->range);CHKERRQ(ierr);
26569ce434fSBarry Smith   }
266ffc4695bSBarry Smith   ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRMPI(ierr);
26769ce434fSBarry Smith 
26869ce434fSBarry Smith   map->range[0] = 0;
269*38a25198SStefano Zampini   for (p = 2; p <= map->size; p++) map->range[p] += map->range[p-1];
27069ce434fSBarry Smith 
27169ce434fSBarry Smith   map->rstart = map->range[rank];
27269ce434fSBarry Smith   map->rend   = map->range[rank+1];
273ca5434daSLawrence Mitchell 
274ca5434daSLawrence Mitchell   /* lock the layout */
275ca5434daSLawrence Mitchell   map->setupcalled = PETSC_TRUE;
276ca5434daSLawrence Mitchell   map->oldn = map->n;
277ca5434daSLawrence Mitchell   map->oldN = map->N;
278ca5434daSLawrence Mitchell   map->oldbs = map->bs;
27969ce434fSBarry Smith   PetscFunctionReturn(0);
28069ce434fSBarry Smith }
28169ce434fSBarry Smith 
282c3002683SMatthew G. Knepley /*@
28369ce434fSBarry Smith   PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
28469ce434fSBarry Smith 
28569ce434fSBarry Smith   Collective on PetscLayout
28669ce434fSBarry Smith 
28769ce434fSBarry Smith   Input Parameter:
28869ce434fSBarry Smith . in - input PetscLayout to be duplicated
28969ce434fSBarry Smith 
29069ce434fSBarry Smith   Output Parameter:
29169ce434fSBarry Smith . out - the copy
29269ce434fSBarry Smith 
29369ce434fSBarry Smith   Level: developer
29469ce434fSBarry Smith 
29595452b02SPatrick Sanan   Notes:
29695452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
29769ce434fSBarry Smith 
29869ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
29969ce434fSBarry Smith @*/
30069ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
30169ce434fSBarry Smith {
30269ce434fSBarry Smith   PetscErrorCode ierr;
30369ce434fSBarry Smith   MPI_Comm       comm = in->comm;
30469ce434fSBarry Smith 
30569ce434fSBarry Smith   PetscFunctionBegin;
30669ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
30769ce434fSBarry Smith   ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr);
30869ce434fSBarry Smith   ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr);
309c168f6d8SVaclav Hapla   if (in->range) {
310*38a25198SStefano Zampini     ierr = PetscMalloc1((*out)->size+1,&(*out)->range);CHKERRQ(ierr);
311*38a25198SStefano Zampini     ierr = PetscArraycpy((*out)->range,in->range,(*out)->size+1);CHKERRQ(ierr);
312c168f6d8SVaclav Hapla   }
31369ce434fSBarry Smith   (*out)->refcnt = 0;
31469ce434fSBarry Smith   PetscFunctionReturn(0);
31569ce434fSBarry Smith }
31669ce434fSBarry Smith 
317c3002683SMatthew G. Knepley /*@
31869ce434fSBarry Smith   PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
31969ce434fSBarry Smith 
32069ce434fSBarry Smith   Collective on PetscLayout
32169ce434fSBarry Smith 
32269ce434fSBarry Smith   Input Parameter:
32369ce434fSBarry Smith . in - input PetscLayout to be copied
32469ce434fSBarry Smith 
32569ce434fSBarry Smith   Output Parameter:
32669ce434fSBarry Smith . out - the reference location
32769ce434fSBarry Smith 
32869ce434fSBarry Smith   Level: developer
32969ce434fSBarry Smith 
33095452b02SPatrick Sanan   Notes:
33195452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
33269ce434fSBarry Smith 
33369ce434fSBarry Smith   If the out location already contains a PetscLayout it is destroyed
33469ce434fSBarry Smith 
33569ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
33669ce434fSBarry Smith @*/
33769ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
33869ce434fSBarry Smith {
33969ce434fSBarry Smith   PetscErrorCode ierr;
34069ce434fSBarry Smith 
34169ce434fSBarry Smith   PetscFunctionBegin;
34269ce434fSBarry Smith   in->refcnt++;
34369ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
34469ce434fSBarry Smith   *out = in;
34569ce434fSBarry Smith   PetscFunctionReturn(0);
34669ce434fSBarry Smith }
34769ce434fSBarry Smith 
348c3002683SMatthew G. Knepley /*@
34969ce434fSBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
35069ce434fSBarry Smith 
35169ce434fSBarry Smith   Collective on PetscLayout
35269ce434fSBarry Smith 
35369ce434fSBarry Smith   Input Parameter:
35469ce434fSBarry Smith + in - input PetscLayout
35569ce434fSBarry Smith - ltog - the local to global mapping
35669ce434fSBarry Smith 
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;
37045b6f7e9SBarry Smith   PetscInt       bs;
37169ce434fSBarry Smith 
37269ce434fSBarry Smith   PetscFunctionBegin;
37345b6f7e9SBarry Smith   ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr);
37437461477SLawrence Mitchell   if (in->bs > 0 && (bs != 1) && in->bs != bs) SETERRQ2(in->comm,PETSC_ERR_PLIB,"Blocksize of layout %D must match that of mapping %D (or the latter must be 1)",in->bs,bs);
37569ce434fSBarry Smith   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
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;
40169ce434fSBarry Smith   if (map->bs > 1 && n % map->bs) SETERRQ2(map->comm,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",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);
507299e779cSStefano Zampini   if (map->n > 0 && map->n % bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local size %D not compatible with block size %D",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 
55269ce434fSBarry Smith   Input Parameters:
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 
60669ce434fSBarry Smith /*@C
607f26271d2SStefano Zampini    PetscLayoutsCreateSF - Creates a parallel star forest mapping two PetscLayout objects
608f26271d2SStefano Zampini 
609f26271d2SStefano Zampini    Collective
610f26271d2SStefano Zampini 
611f26271d2SStefano Zampini    Input Arguments:
612f26271d2SStefano Zampini +  rmap - PetscLayout defining the global root space
613f26271d2SStefano Zampini -  lmap - PetscLayout defining the global leaf space
614f26271d2SStefano Zampini 
615f26271d2SStefano Zampini    Output Arguments:
616f26271d2SStefano Zampini .  sf - The parallel star forest
617f26271d2SStefano Zampini 
618f26271d2SStefano Zampini    Level: intermediate
619f26271d2SStefano Zampini 
620f26271d2SStefano Zampini .seealso: PetscSFCreate(), PetscLayoutCreate(), PetscSFSetGraphLayout()
621f26271d2SStefano Zampini @*/
622f26271d2SStefano Zampini PetscErrorCode PetscLayoutsCreateSF(PetscLayout rmap, PetscLayout lmap, PetscSF* sf)
623f26271d2SStefano Zampini {
624f26271d2SStefano Zampini   PetscErrorCode ierr;
625f26271d2SStefano Zampini   PetscInt       i,nroots,nleaves = 0;
626f26271d2SStefano Zampini   PetscInt       rN, lst, len;
627f26271d2SStefano Zampini   PetscMPIInt    owner = -1;
628f26271d2SStefano Zampini   PetscSFNode    *remote;
629f26271d2SStefano Zampini   MPI_Comm       rcomm = rmap->comm;
630f26271d2SStefano Zampini   MPI_Comm       lcomm = lmap->comm;
631f26271d2SStefano Zampini   PetscMPIInt    flg;
632f26271d2SStefano Zampini 
633f26271d2SStefano Zampini   PetscFunctionBegin;
634f26271d2SStefano Zampini   PetscValidPointer(sf,3);
635f26271d2SStefano Zampini   if (!rmap->setupcalled) SETERRQ(rcomm,PETSC_ERR_ARG_WRONGSTATE,"Root layout not setup");
636f26271d2SStefano Zampini   if (!lmap->setupcalled) SETERRQ(lcomm,PETSC_ERR_ARG_WRONGSTATE,"Leaf layout not setup");
637ffc4695bSBarry Smith   ierr = MPI_Comm_compare(rcomm,lcomm,&flg);CHKERRMPI(ierr);
638f26271d2SStefano Zampini   if (flg != MPI_CONGRUENT && flg != MPI_IDENT) SETERRQ(rcomm,PETSC_ERR_SUP,"cannot map two layouts with non-matching communicators");
639f26271d2SStefano Zampini   ierr = PetscSFCreate(rcomm,sf);CHKERRQ(ierr);
640f26271d2SStefano Zampini   ierr = PetscLayoutGetLocalSize(rmap,&nroots);CHKERRQ(ierr);
641f26271d2SStefano Zampini   ierr = PetscLayoutGetSize(rmap,&rN);CHKERRQ(ierr);
642f26271d2SStefano Zampini   ierr = PetscLayoutGetRange(lmap,&lst,&len);CHKERRQ(ierr);
643f26271d2SStefano Zampini   ierr = PetscMalloc1(len-lst,&remote);CHKERRQ(ierr);
644f26271d2SStefano Zampini   for (i = lst; i < len && i < rN; i++) {
645f26271d2SStefano Zampini     if (owner < -1 || i >= rmap->range[owner+1]) {
646f26271d2SStefano Zampini       ierr = PetscLayoutFindOwner(rmap,i,&owner);CHKERRQ(ierr);
647f26271d2SStefano Zampini     }
648f26271d2SStefano Zampini     remote[nleaves].rank  = owner;
649f26271d2SStefano Zampini     remote[nleaves].index = i - rmap->range[owner];
650f26271d2SStefano Zampini     nleaves++;
651f26271d2SStefano Zampini   }
652f26271d2SStefano Zampini   ierr = PetscSFSetGraph(*sf,nroots,nleaves,NULL,PETSC_OWN_POINTER,remote,PETSC_COPY_VALUES);CHKERRQ(ierr);
653f26271d2SStefano Zampini   ierr = PetscFree(remote);CHKERRQ(ierr);
654f26271d2SStefano Zampini   PetscFunctionReturn(0);
655f26271d2SStefano Zampini }
656f26271d2SStefano Zampini 
657f92d6284SStefano Zampini /*@
658f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
659f92d6284SStefano Zampini 
660f92d6284SStefano Zampini   Not Collective
661f92d6284SStefano Zampini 
662f92d6284SStefano Zampini   Input Parameters:
663d11c674dSStefano Zampini + mapa - pointer to the first map
664f92d6284SStefano Zampini - mapb - pointer to the second map
665f92d6284SStefano Zampini 
666f92d6284SStefano Zampini   Output Parameters:
667f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise
668f92d6284SStefano Zampini 
669f92d6284SStefano Zampini   Level: beginner
670f92d6284SStefano Zampini 
671f92d6284SStefano Zampini   Notes:
672f92d6284SStefano Zampini 
673f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
674f92d6284SStefano Zampini           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
675f92d6284SStefano Zampini @*/
676f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent)
677f92d6284SStefano Zampini {
678f92d6284SStefano Zampini   PetscErrorCode ierr;
679f92d6284SStefano Zampini 
680f92d6284SStefano Zampini   PetscFunctionBegin;
681f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
682*38a25198SStefano Zampini   if (mapa->N == mapb->N && mapa->range && mapb->range && mapa->size == mapb->size) {
683*38a25198SStefano Zampini     ierr = PetscArraycmp(mapa->range,mapb->range,mapa->size+1,congruent);CHKERRQ(ierr);
684f92d6284SStefano Zampini   }
685f92d6284SStefano Zampini   PetscFunctionReturn(0);
686f92d6284SStefano Zampini }
687a72d46e8SStefano Zampini 
688a72d46e8SStefano Zampini /* TODO: handle nooffprocentries like MatZeroRowsMapLocal_Private, since this code is the same */
689a72d46e8SStefano Zampini PetscErrorCode PetscLayoutMapLocal(PetscLayout map,PetscInt N,const PetscInt idxs[], PetscInt *on,PetscInt **oidxs,PetscInt **ogidxs)
690a72d46e8SStefano Zampini {
691a72d46e8SStefano Zampini   PetscInt      *owners = map->range;
692a72d46e8SStefano Zampini   PetscInt       n      = map->n;
693a72d46e8SStefano Zampini   PetscSF        sf;
694a72d46e8SStefano Zampini   PetscInt      *lidxs,*work = NULL;
695a72d46e8SStefano Zampini   PetscSFNode   *ridxs;
696131c27b5Sprj-   PetscMPIInt    rank, p = 0;
697131c27b5Sprj-   PetscInt       r, len = 0;
698a72d46e8SStefano Zampini   PetscErrorCode ierr;
699a72d46e8SStefano Zampini 
700a72d46e8SStefano Zampini   PetscFunctionBegin;
701a72d46e8SStefano Zampini   if (on) *on = 0;              /* squelch -Wmaybe-uninitialized */
702a72d46e8SStefano Zampini   /* Create SF where leaves are input idxs and roots are owned idxs */
703ffc4695bSBarry Smith   ierr = MPI_Comm_rank(map->comm,&rank);CHKERRMPI(ierr);
704a72d46e8SStefano Zampini   ierr = PetscMalloc1(n,&lidxs);CHKERRQ(ierr);
705a72d46e8SStefano Zampini   for (r = 0; r < n; ++r) lidxs[r] = -1;
706a72d46e8SStefano Zampini   ierr = PetscMalloc1(N,&ridxs);CHKERRQ(ierr);
707a72d46e8SStefano Zampini   for (r = 0; r < N; ++r) {
708a72d46e8SStefano Zampini     const PetscInt idx = idxs[r];
709a72d46e8SStefano Zampini     if (idx < 0 || map->N <= idx) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Index %D out of range [0,%D)",idx,map->N);
710a72d46e8SStefano Zampini     if (idx < owners[p] || owners[p+1] <= idx) { /* short-circuit the search if the last p owns this idx too */
711a72d46e8SStefano Zampini       ierr = PetscLayoutFindOwner(map,idx,&p);CHKERRQ(ierr);
712a72d46e8SStefano Zampini     }
713a72d46e8SStefano Zampini     ridxs[r].rank = p;
714a72d46e8SStefano Zampini     ridxs[r].index = idxs[r] - owners[p];
715a72d46e8SStefano Zampini   }
716a72d46e8SStefano Zampini   ierr = PetscSFCreate(map->comm,&sf);CHKERRQ(ierr);
717a72d46e8SStefano Zampini   ierr = PetscSFSetGraph(sf,n,N,NULL,PETSC_OWN_POINTER,ridxs,PETSC_OWN_POINTER);CHKERRQ(ierr);
718a72d46e8SStefano Zampini   ierr = PetscSFReduceBegin(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr);
719a72d46e8SStefano Zampini   ierr = PetscSFReduceEnd(sf,MPIU_INT,(PetscInt*)idxs,lidxs,MPI_LOR);CHKERRQ(ierr);
720a72d46e8SStefano Zampini   if (ogidxs) { /* communicate global idxs */
721a72d46e8SStefano Zampini     PetscInt cum = 0,start,*work2;
722a72d46e8SStefano Zampini 
723a72d46e8SStefano Zampini     ierr = PetscMalloc1(n,&work);CHKERRQ(ierr);
724a72d46e8SStefano Zampini     ierr = PetscCalloc1(N,&work2);CHKERRQ(ierr);
725a72d46e8SStefano Zampini     for (r = 0; r < N; ++r) if (idxs[r] >=0) cum++;
726ffc4695bSBarry Smith     ierr = MPI_Scan(&cum,&start,1,MPIU_INT,MPI_SUM,map->comm);CHKERRMPI(ierr);
727a72d46e8SStefano Zampini     start -= cum;
728a72d46e8SStefano Zampini     cum = 0;
729a72d46e8SStefano Zampini     for (r = 0; r < N; ++r) if (idxs[r] >=0) work2[r] = start+cum++;
730a72d46e8SStefano Zampini     ierr = PetscSFReduceBegin(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr);
731a72d46e8SStefano Zampini     ierr = PetscSFReduceEnd(sf,MPIU_INT,work2,work,MPIU_REPLACE);CHKERRQ(ierr);
732a72d46e8SStefano Zampini     ierr = PetscFree(work2);CHKERRQ(ierr);
733a72d46e8SStefano Zampini   }
734a72d46e8SStefano Zampini   ierr = PetscSFDestroy(&sf);CHKERRQ(ierr);
735a72d46e8SStefano Zampini   /* Compress and put in indices */
736a72d46e8SStefano Zampini   for (r = 0; r < n; ++r)
737a72d46e8SStefano Zampini     if (lidxs[r] >= 0) {
738a72d46e8SStefano Zampini       if (work) work[len] = work[r];
739a72d46e8SStefano Zampini       lidxs[len++] = r;
740a72d46e8SStefano Zampini     }
741a72d46e8SStefano Zampini   if (on) *on = len;
742a72d46e8SStefano Zampini   if (oidxs) *oidxs = lidxs;
743a72d46e8SStefano Zampini   if (ogidxs) *ogidxs = work;
744a72d46e8SStefano Zampini   PetscFunctionReturn(0);
745a72d46e8SStefano Zampini }
746