xref: /petsc/src/vec/is/utils/pmap.c (revision 7b659617f2990ff61c1685b7fa54504ceab83bac)
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>
85c25fcd7SBarry Smith 
9c3002683SMatthew G. Knepley /*@
1069ce434fSBarry Smith   PetscLayoutCreate - Allocates PetscLayout space and sets the map contents to the default.
1169ce434fSBarry Smith 
1269ce434fSBarry Smith   Collective on MPI_Comm
1369ce434fSBarry Smith 
1469ce434fSBarry Smith   Input Parameters:
1569ce434fSBarry Smith + comm - the MPI communicator
1669ce434fSBarry Smith - map - pointer to the map
1769ce434fSBarry Smith 
18456fcb79SJed Brown   Level: advanced
1969ce434fSBarry Smith 
20456fcb79SJed Brown   Notes:
21456fcb79SJed Brown   Typical calling sequence
22456fcb79SJed Brown .vb
2369ce434fSBarry Smith        PetscLayoutCreate(MPI_Comm,PetscLayout *);
2469ce434fSBarry Smith        PetscLayoutSetBlockSize(PetscLayout,1);
25456fcb79SJed Brown        PetscLayoutSetSize(PetscLayout,N) // or PetscLayoutSetLocalSize(PetscLayout,n);
2669ce434fSBarry Smith        PetscLayoutSetUp(PetscLayout);
27456fcb79SJed Brown .ve
2869ce434fSBarry Smith   Optionally use any of the following:
29456fcb79SJed Brown 
30456fcb79SJed Brown + PetscLayoutGetSize(PetscLayout,PetscInt *);
31456fcb79SJed Brown . PetscLayoutGetLocalSize(PetscLayout,PetscInt *);
32456fcb79SJed Brown . PetscLayoutGetRange(PetscLayout,PetscInt *rstart,PetscInt *rend);
33456fcb79SJed Brown . PetscLayoutGetRanges(PetscLayout,const PetscInt *range[]);
34456fcb79SJed Brown - PetscLayoutDestroy(PetscLayout*);
3569ce434fSBarry Smith 
3669ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is often not needed in
3769ce434fSBarry Smith   user codes unless you really gain something in their use.
3869ce434fSBarry Smith 
3969ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
4069ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
4169ce434fSBarry Smith 
4269ce434fSBarry Smith @*/
4369ce434fSBarry Smith PetscErrorCode PetscLayoutCreate(MPI_Comm comm,PetscLayout *map)
4469ce434fSBarry Smith {
4569ce434fSBarry Smith   PetscErrorCode ierr;
4669ce434fSBarry Smith 
4769ce434fSBarry Smith   PetscFunctionBegin;
48b00a9115SJed Brown   ierr = PetscNew(map);CHKERRQ(ierr);
4969ce434fSBarry Smith 
5069ce434fSBarry Smith   (*map)->comm   = comm;
5169ce434fSBarry Smith   (*map)->bs     = -1;
5269ce434fSBarry Smith   (*map)->n      = -1;
5369ce434fSBarry Smith   (*map)->N      = -1;
54f92d6284SStefano Zampini   (*map)->range  = NULL;
5569ce434fSBarry Smith   (*map)->rstart = 0;
5669ce434fSBarry Smith   (*map)->rend   = 0;
5769ce434fSBarry Smith   PetscFunctionReturn(0);
5869ce434fSBarry Smith }
5969ce434fSBarry Smith 
60c3002683SMatthew G. Knepley /*@
6169ce434fSBarry Smith   PetscLayoutDestroy - Frees a map object and frees its range if that exists.
6269ce434fSBarry Smith 
6369ce434fSBarry Smith   Collective on MPI_Comm
6469ce434fSBarry Smith 
6569ce434fSBarry Smith   Input Parameters:
6669ce434fSBarry Smith . map - the PetscLayout
6769ce434fSBarry Smith 
6869ce434fSBarry Smith   Level: developer
6969ce434fSBarry Smith 
70c3002683SMatthew G. Knepley   Note:
7169ce434fSBarry Smith   The PetscLayout object and methods are intended to be used in the PETSc Vec and Mat implementions; it is
7269ce434fSBarry Smith   recommended they not be used in user codes unless you really gain something in their use.
7369ce434fSBarry Smith 
7469ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutCreate(),
7569ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutSetUp()
7669ce434fSBarry Smith 
7769ce434fSBarry Smith @*/
7869ce434fSBarry Smith PetscErrorCode PetscLayoutDestroy(PetscLayout *map)
7969ce434fSBarry Smith {
8069ce434fSBarry Smith   PetscErrorCode ierr;
8169ce434fSBarry Smith 
8269ce434fSBarry Smith   PetscFunctionBegin;
8369ce434fSBarry Smith   if (!*map) PetscFunctionReturn(0);
8469ce434fSBarry Smith   if (!(*map)->refcnt--) {
8569ce434fSBarry Smith     ierr = PetscFree((*map)->range);CHKERRQ(ierr);
8669ce434fSBarry Smith     ierr = ISLocalToGlobalMappingDestroy(&(*map)->mapping);CHKERRQ(ierr);
8769ce434fSBarry Smith     ierr = PetscFree((*map));CHKERRQ(ierr);
8869ce434fSBarry Smith   }
8969ce434fSBarry Smith   *map = NULL;
9069ce434fSBarry Smith   PetscFunctionReturn(0);
9169ce434fSBarry Smith }
9269ce434fSBarry Smith 
93*7b659617SVaclav Hapla static PetscErrorCode PetscLayoutSetUp_SizesFromRanges_Private(PetscLayout map)
94*7b659617SVaclav Hapla {
95*7b659617SVaclav Hapla   PetscMPIInt    rank,size;
96*7b659617SVaclav Hapla   PetscErrorCode ierr;
97*7b659617SVaclav Hapla 
98*7b659617SVaclav Hapla   PetscFunctionBegin;
99*7b659617SVaclav Hapla   ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr);
100*7b659617SVaclav Hapla   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr);
101*7b659617SVaclav Hapla   map->rstart = map->range[rank];
102*7b659617SVaclav Hapla   map->rend   = map->range[rank+1];
103*7b659617SVaclav Hapla   map->n      = map->rend - map->rstart;
104*7b659617SVaclav Hapla   map->N      = map->range[size];
105*7b659617SVaclav Hapla #if defined(PETSC_USE_DEBUG)
106*7b659617SVaclav Hapla   /* just check that n, N and bs are consistent */
107*7b659617SVaclav Hapla   {
108*7b659617SVaclav Hapla     PetscInt tmp;
109*7b659617SVaclav Hapla     ierr = MPIU_Allreduce(&map->n,&tmp,1,MPIU_INT,MPI_SUM,map->comm);CHKERRQ(ierr);
110*7b659617SVaclav 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);
111*7b659617SVaclav Hapla   }
112*7b659617SVaclav Hapla   if (map->bs > 1) {
113*7b659617SVaclav 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);
114*7b659617SVaclav Hapla   }
115*7b659617SVaclav Hapla   if (map->bs > 1) {
116*7b659617SVaclav 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);
117*7b659617SVaclav Hapla   }
118*7b659617SVaclav Hapla #endif
119*7b659617SVaclav Hapla   PetscFunctionReturn(0);
120*7b659617SVaclav Hapla }
121*7b659617SVaclav Hapla 
122c3002683SMatthew G. Knepley /*@
12369ce434fSBarry Smith   PetscLayoutSetUp - given a map where you have set either the global or local
12469ce434fSBarry Smith                      size sets up the map so that it may be used.
12569ce434fSBarry Smith 
12669ce434fSBarry Smith   Collective on MPI_Comm
12769ce434fSBarry Smith 
12869ce434fSBarry Smith   Input Parameters:
12969ce434fSBarry Smith . map - pointer to the map
13069ce434fSBarry Smith 
13169ce434fSBarry Smith   Level: developer
13269ce434fSBarry Smith 
13395452b02SPatrick Sanan   Notes:
13495452b02SPatrick Sanan     Typical calling sequence
135c3002683SMatthew G. Knepley $ PetscLayoutCreate(MPI_Comm,PetscLayout *);
136c3002683SMatthew G. Knepley $ PetscLayoutSetBlockSize(PetscLayout,1);
137c3002683SMatthew G. Knepley $ PetscLayoutSetSize(PetscLayout,n) or PetscLayoutSetLocalSize(PetscLayout,N); or both
138c3002683SMatthew G. Knepley $ PetscLayoutSetUp(PetscLayout);
139c3002683SMatthew G. Knepley $ PetscLayoutGetSize(PetscLayout,PetscInt *);
14069ce434fSBarry Smith 
141*7b659617SVaclav Hapla   If range exists, and local size is not set, everything gets computed from the range.
14269ce434fSBarry Smith 
14369ce434fSBarry Smith   If the local size, global size are already set and range exists then this does nothing.
14469ce434fSBarry Smith 
14569ce434fSBarry Smith .seealso: PetscLayoutSetLocalSize(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayout, PetscLayoutDestroy(),
14669ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize(), PetscLayoutCreate()
14769ce434fSBarry Smith @*/
14869ce434fSBarry Smith PetscErrorCode PetscLayoutSetUp(PetscLayout map)
14969ce434fSBarry Smith {
15069ce434fSBarry Smith   PetscMPIInt    rank,size;
15169ce434fSBarry Smith   PetscInt       p;
15269ce434fSBarry Smith   PetscErrorCode ierr;
15369ce434fSBarry Smith 
15469ce434fSBarry Smith   PetscFunctionBegin;
15569ce434fSBarry Smith   if ((map->n >= 0) && (map->N >= 0) && (map->range)) PetscFunctionReturn(0);
156*7b659617SVaclav Hapla   if (map->range && map->n < 0) {
157*7b659617SVaclav Hapla     ierr = PetscLayoutSetUp_SizesFromRanges_Private(map);CHKERRQ(ierr);
158*7b659617SVaclav Hapla     PetscFunctionReturn(0);
159*7b659617SVaclav Hapla   }
16069ce434fSBarry Smith 
161b146b01cSBarry Smith   if (map->n > 0 && map->bs > 1) {
1626c4ed002SBarry Smith     if (map->n % map->bs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Local matrix size %D must be divisible by blocksize %D",map->n,map->bs);
163b146b01cSBarry Smith   }
164b146b01cSBarry Smith   if (map->N > 0 && map->bs > 1) {
1656c4ed002SBarry Smith     if (map->N % map->bs) SETERRQ2(map->comm,PETSC_ERR_PLIB,"Global matrix size %D must be divisible by blocksize %D",map->N,map->bs);
166b146b01cSBarry Smith   }
167b146b01cSBarry Smith 
16869ce434fSBarry Smith   ierr = MPI_Comm_size(map->comm, &size);CHKERRQ(ierr);
16969ce434fSBarry Smith   ierr = MPI_Comm_rank(map->comm, &rank);CHKERRQ(ierr);
17033d57670SJed Brown   if (map->n > 0) map->n = map->n/PetscAbs(map->bs);
17133d57670SJed Brown   if (map->N > 0) map->N = map->N/PetscAbs(map->bs);
17269ce434fSBarry Smith   ierr = PetscSplitOwnership(map->comm,&map->n,&map->N);CHKERRQ(ierr);
17333d57670SJed Brown   map->n = map->n*PetscAbs(map->bs);
17433d57670SJed Brown   map->N = map->N*PetscAbs(map->bs);
17569ce434fSBarry Smith   if (!map->range) {
176854ce69bSBarry Smith     ierr = PetscMalloc1(size+1, &map->range);CHKERRQ(ierr);
17769ce434fSBarry Smith   }
17869ce434fSBarry Smith   ierr = MPI_Allgather(&map->n, 1, MPIU_INT, map->range+1, 1, MPIU_INT, map->comm);CHKERRQ(ierr);
17969ce434fSBarry Smith 
18069ce434fSBarry Smith   map->range[0] = 0;
18169ce434fSBarry Smith   for (p = 2; p <= size; p++) map->range[p] += map->range[p-1];
18269ce434fSBarry Smith 
18369ce434fSBarry Smith   map->rstart = map->range[rank];
18469ce434fSBarry Smith   map->rend   = map->range[rank+1];
18569ce434fSBarry Smith   PetscFunctionReturn(0);
18669ce434fSBarry Smith }
18769ce434fSBarry Smith 
188c3002683SMatthew G. Knepley /*@
18969ce434fSBarry Smith   PetscLayoutDuplicate - creates a new PetscLayout with the same information as a given one. If the PetscLayout already exists it is destroyed first.
19069ce434fSBarry Smith 
19169ce434fSBarry Smith   Collective on PetscLayout
19269ce434fSBarry Smith 
19369ce434fSBarry Smith   Input Parameter:
19469ce434fSBarry Smith . in - input PetscLayout to be duplicated
19569ce434fSBarry Smith 
19669ce434fSBarry Smith   Output Parameter:
19769ce434fSBarry Smith . out - the copy
19869ce434fSBarry Smith 
19969ce434fSBarry Smith   Level: developer
20069ce434fSBarry Smith 
20195452b02SPatrick Sanan   Notes:
20295452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
20369ce434fSBarry Smith 
20469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutReference()
20569ce434fSBarry Smith @*/
20669ce434fSBarry Smith PetscErrorCode PetscLayoutDuplicate(PetscLayout in,PetscLayout *out)
20769ce434fSBarry Smith {
20869ce434fSBarry Smith   PetscMPIInt    size;
20969ce434fSBarry Smith   PetscErrorCode ierr;
21069ce434fSBarry Smith   MPI_Comm       comm = in->comm;
21169ce434fSBarry Smith 
21269ce434fSBarry Smith   PetscFunctionBegin;
21369ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
21469ce434fSBarry Smith   ierr = PetscLayoutCreate(comm,out);CHKERRQ(ierr);
21569ce434fSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
21669ce434fSBarry Smith   ierr = PetscMemcpy(*out,in,sizeof(struct _n_PetscLayout));CHKERRQ(ierr);
217854ce69bSBarry Smith   ierr = PetscMalloc1(size+1,&(*out)->range);CHKERRQ(ierr);
21869ce434fSBarry Smith   ierr = PetscMemcpy((*out)->range,in->range,(size+1)*sizeof(PetscInt));CHKERRQ(ierr);
21969ce434fSBarry Smith 
22069ce434fSBarry Smith   (*out)->refcnt = 0;
22169ce434fSBarry Smith   PetscFunctionReturn(0);
22269ce434fSBarry Smith }
22369ce434fSBarry Smith 
224c3002683SMatthew G. Knepley /*@
22569ce434fSBarry Smith   PetscLayoutReference - Causes a PETSc Vec or Mat to share a PetscLayout with one that already exists. Used by Vec/MatDuplicate_XXX()
22669ce434fSBarry Smith 
22769ce434fSBarry Smith   Collective on PetscLayout
22869ce434fSBarry Smith 
22969ce434fSBarry Smith   Input Parameter:
23069ce434fSBarry Smith . in - input PetscLayout to be copied
23169ce434fSBarry Smith 
23269ce434fSBarry Smith   Output Parameter:
23369ce434fSBarry Smith . out - the reference location
23469ce434fSBarry Smith 
23569ce434fSBarry Smith   Level: developer
23669ce434fSBarry Smith 
23795452b02SPatrick Sanan   Notes:
23895452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
23969ce434fSBarry Smith 
24069ce434fSBarry Smith   If the out location already contains a PetscLayout it is destroyed
24169ce434fSBarry Smith 
24269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
24369ce434fSBarry Smith @*/
24469ce434fSBarry Smith PetscErrorCode PetscLayoutReference(PetscLayout in,PetscLayout *out)
24569ce434fSBarry Smith {
24669ce434fSBarry Smith   PetscErrorCode ierr;
24769ce434fSBarry Smith 
24869ce434fSBarry Smith   PetscFunctionBegin;
24969ce434fSBarry Smith   in->refcnt++;
25069ce434fSBarry Smith   ierr = PetscLayoutDestroy(out);CHKERRQ(ierr);
25169ce434fSBarry Smith   *out = in;
25269ce434fSBarry Smith   PetscFunctionReturn(0);
25369ce434fSBarry Smith }
25469ce434fSBarry Smith 
255c3002683SMatthew G. Knepley /*@
25669ce434fSBarry Smith   PetscLayoutSetISLocalToGlobalMapping - sets a ISLocalGlobalMapping into a PetscLayout
25769ce434fSBarry Smith 
25869ce434fSBarry Smith   Collective on PetscLayout
25969ce434fSBarry Smith 
26069ce434fSBarry Smith   Input Parameter:
26169ce434fSBarry Smith + in - input PetscLayout
26269ce434fSBarry Smith - ltog - the local to global mapping
26369ce434fSBarry Smith 
26469ce434fSBarry Smith 
26569ce434fSBarry Smith   Level: developer
26669ce434fSBarry Smith 
26795452b02SPatrick Sanan   Notes:
26895452b02SPatrick Sanan     PetscLayoutSetUp() does not need to be called on the resulting PetscLayout
26969ce434fSBarry Smith 
27069ce434fSBarry Smith   If the ltog location already contains a PetscLayout it is destroyed
27169ce434fSBarry Smith 
272a188d78dSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutDestroy(), PetscLayoutSetUp(), PetscLayoutDuplicate()
27369ce434fSBarry Smith @*/
27469ce434fSBarry Smith PetscErrorCode PetscLayoutSetISLocalToGlobalMapping(PetscLayout in,ISLocalToGlobalMapping ltog)
27569ce434fSBarry Smith {
27669ce434fSBarry Smith   PetscErrorCode ierr;
27745b6f7e9SBarry Smith   PetscInt       bs;
27869ce434fSBarry Smith 
27969ce434fSBarry Smith   PetscFunctionBegin;
28045b6f7e9SBarry Smith   ierr = ISLocalToGlobalMappingGetBlockSize(ltog,&bs);CHKERRQ(ierr);
28145b6f7e9SBarry Smith   if (in->bs > 0 && in->bs != bs) SETERRQ2(in->comm,PETSC_ERR_PLIB,"Blocksize of layout %D must match that of mapping %D",in->bs,bs);
28269ce434fSBarry Smith   ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
28369ce434fSBarry Smith   ierr = ISLocalToGlobalMappingDestroy(&in->mapping);CHKERRQ(ierr);
28469ce434fSBarry Smith   in->mapping = ltog;
28569ce434fSBarry Smith   PetscFunctionReturn(0);
28669ce434fSBarry Smith }
28769ce434fSBarry Smith 
288c3002683SMatthew G. Knepley /*@
28969ce434fSBarry Smith   PetscLayoutSetLocalSize - Sets the local size for a PetscLayout object.
29069ce434fSBarry Smith 
29169ce434fSBarry Smith   Collective on PetscLayout
29269ce434fSBarry Smith 
29369ce434fSBarry Smith   Input Parameters:
29469ce434fSBarry Smith + map - pointer to the map
29569ce434fSBarry Smith - n - the local size
29669ce434fSBarry Smith 
29769ce434fSBarry Smith   Level: developer
29869ce434fSBarry Smith 
29969ce434fSBarry Smith   Notes:
30069ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
30169ce434fSBarry Smith 
30269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
30369ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
30469ce434fSBarry Smith @*/
30569ce434fSBarry Smith PetscErrorCode PetscLayoutSetLocalSize(PetscLayout map,PetscInt n)
30669ce434fSBarry Smith {
30769ce434fSBarry Smith   PetscFunctionBegin;
30869ce434fSBarry 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);
30969ce434fSBarry Smith   map->n = n;
31069ce434fSBarry Smith   PetscFunctionReturn(0);
31169ce434fSBarry Smith }
31269ce434fSBarry Smith 
31369ce434fSBarry Smith /*@C
31469ce434fSBarry Smith      PetscLayoutGetLocalSize - Gets the local size for a PetscLayout object.
31569ce434fSBarry Smith 
31669ce434fSBarry Smith     Not Collective
31769ce434fSBarry Smith 
31869ce434fSBarry Smith    Input Parameters:
31969ce434fSBarry Smith .    map - pointer to the map
32069ce434fSBarry Smith 
32169ce434fSBarry Smith    Output Parameters:
32269ce434fSBarry Smith .    n - the local size
32369ce434fSBarry Smith 
32469ce434fSBarry Smith    Level: developer
32569ce434fSBarry Smith 
32669ce434fSBarry Smith     Notes:
32769ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
32869ce434fSBarry Smith 
32969ce434fSBarry Smith     Fortran Notes:
33069ce434fSBarry Smith       Not available from Fortran
33169ce434fSBarry Smith 
33269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutGetLocalSize(), PetscLayoutSetUp()
33369ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
33469ce434fSBarry Smith 
33569ce434fSBarry Smith @*/
33669ce434fSBarry Smith PetscErrorCode  PetscLayoutGetLocalSize(PetscLayout map,PetscInt *n)
33769ce434fSBarry Smith {
33869ce434fSBarry Smith   PetscFunctionBegin;
33969ce434fSBarry Smith   *n = map->n;
34069ce434fSBarry Smith   PetscFunctionReturn(0);
34169ce434fSBarry Smith }
34269ce434fSBarry Smith 
343c3002683SMatthew G. Knepley /*@
34469ce434fSBarry Smith   PetscLayoutSetSize - Sets the global size for a PetscLayout object.
34569ce434fSBarry Smith 
34669ce434fSBarry Smith   Logically Collective on PetscLayout
34769ce434fSBarry Smith 
34869ce434fSBarry Smith   Input Parameters:
34969ce434fSBarry Smith + map - pointer to the map
35069ce434fSBarry Smith - n - the global size
35169ce434fSBarry Smith 
35269ce434fSBarry Smith   Level: developer
35369ce434fSBarry Smith 
35469ce434fSBarry Smith   Notes:
35569ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
35669ce434fSBarry Smith 
35769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
35869ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
35969ce434fSBarry Smith @*/
36069ce434fSBarry Smith PetscErrorCode PetscLayoutSetSize(PetscLayout map,PetscInt n)
36169ce434fSBarry Smith {
36269ce434fSBarry Smith   PetscFunctionBegin;
36369ce434fSBarry Smith   map->N = n;
36469ce434fSBarry Smith   PetscFunctionReturn(0);
36569ce434fSBarry Smith }
36669ce434fSBarry Smith 
367c3002683SMatthew G. Knepley /*@
36869ce434fSBarry Smith   PetscLayoutGetSize - Gets the global size for a PetscLayout object.
36969ce434fSBarry Smith 
37069ce434fSBarry Smith   Not Collective
37169ce434fSBarry Smith 
37269ce434fSBarry Smith   Input Parameters:
37369ce434fSBarry Smith . map - pointer to the map
37469ce434fSBarry Smith 
37569ce434fSBarry Smith   Output Parameters:
37669ce434fSBarry Smith . n - the global size
37769ce434fSBarry Smith 
37869ce434fSBarry Smith   Level: developer
37969ce434fSBarry Smith 
38069ce434fSBarry Smith   Notes:
38169ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
38269ce434fSBarry Smith 
38369ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
38469ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetBlockSize()
38569ce434fSBarry Smith @*/
38669ce434fSBarry Smith PetscErrorCode PetscLayoutGetSize(PetscLayout map,PetscInt *n)
38769ce434fSBarry Smith {
38869ce434fSBarry Smith   PetscFunctionBegin;
38969ce434fSBarry Smith   *n = map->N;
39069ce434fSBarry Smith   PetscFunctionReturn(0);
39169ce434fSBarry Smith }
39269ce434fSBarry Smith 
393c3002683SMatthew G. Knepley /*@
39469ce434fSBarry Smith   PetscLayoutSetBlockSize - Sets the block size for a PetscLayout object.
39569ce434fSBarry Smith 
39669ce434fSBarry Smith   Logically Collective on PetscLayout
39769ce434fSBarry Smith 
39869ce434fSBarry Smith   Input Parameters:
39969ce434fSBarry Smith + map - pointer to the map
40069ce434fSBarry Smith - bs - the size
40169ce434fSBarry Smith 
40269ce434fSBarry Smith   Level: developer
40369ce434fSBarry Smith 
40469ce434fSBarry Smith   Notes:
40569ce434fSBarry Smith   Call this after the call to PetscLayoutCreate()
40669ce434fSBarry Smith 
40769ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
40869ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
40969ce434fSBarry Smith @*/
41069ce434fSBarry Smith PetscErrorCode PetscLayoutSetBlockSize(PetscLayout map,PetscInt bs)
41169ce434fSBarry Smith {
41269ce434fSBarry Smith   PetscFunctionBegin;
41369bbac97SJed Brown   if (bs < 0) PetscFunctionReturn(0);
414299e779cSStefano 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);
415565245c5SBarry Smith   if (map->mapping) {
416705e6b8bSstefano_zampini     PetscInt       obs;
417565245c5SBarry Smith     PetscErrorCode ierr;
418565245c5SBarry Smith 
419705e6b8bSstefano_zampini     ierr = ISLocalToGlobalMappingGetBlockSize(map->mapping,&obs);CHKERRQ(ierr);
420705e6b8bSstefano_zampini     if (obs > 1) {
42163fa5c83Sstefano_zampini       ierr = ISLocalToGlobalMappingSetBlockSize(map->mapping,bs);CHKERRQ(ierr);
422565245c5SBarry Smith     }
423705e6b8bSstefano_zampini   }
42469ce434fSBarry Smith   map->bs = bs;
42569ce434fSBarry Smith   PetscFunctionReturn(0);
42669ce434fSBarry Smith }
42769ce434fSBarry Smith 
428c3002683SMatthew G. Knepley /*@
42969ce434fSBarry Smith   PetscLayoutGetBlockSize - Gets the block size for a PetscLayout object.
43069ce434fSBarry Smith 
43169ce434fSBarry Smith   Not Collective
43269ce434fSBarry Smith 
43369ce434fSBarry Smith   Input Parameters:
43469ce434fSBarry Smith . map - pointer to the map
43569ce434fSBarry Smith 
43669ce434fSBarry Smith   Output Parameters:
43769ce434fSBarry Smith . bs - the size
43869ce434fSBarry Smith 
43969ce434fSBarry Smith   Level: developer
44069ce434fSBarry Smith 
44169ce434fSBarry Smith   Notes:
44269ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
44369ce434fSBarry Smith 
44469ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(), PetscLayoutSetUp()
44569ce434fSBarry Smith           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize()
44669ce434fSBarry Smith @*/
44769ce434fSBarry Smith PetscErrorCode PetscLayoutGetBlockSize(PetscLayout map,PetscInt *bs)
44869ce434fSBarry Smith {
44969ce434fSBarry Smith   PetscFunctionBegin;
45033d57670SJed Brown   *bs = PetscAbs(map->bs);
45169ce434fSBarry Smith   PetscFunctionReturn(0);
45269ce434fSBarry Smith }
45369ce434fSBarry Smith 
454c3002683SMatthew G. Knepley /*@
45569ce434fSBarry Smith   PetscLayoutGetRange - gets the range of values owned by this process
45669ce434fSBarry Smith 
45769ce434fSBarry Smith   Not Collective
45869ce434fSBarry Smith 
45969ce434fSBarry Smith   Input Parameters:
46069ce434fSBarry Smith . map - pointer to the map
46169ce434fSBarry Smith 
46269ce434fSBarry Smith   Output Parameters:
46369ce434fSBarry Smith + rstart - first index owned by this process
46469ce434fSBarry Smith - rend   - one more than the last index owned by this process
46569ce434fSBarry Smith 
46669ce434fSBarry Smith   Level: developer
46769ce434fSBarry Smith 
46869ce434fSBarry Smith   Notes:
46969ce434fSBarry Smith   Call this after the call to PetscLayoutSetUp()
47069ce434fSBarry Smith 
47169ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
47269ce434fSBarry Smith           PetscLayoutGetSize(), PetscLayoutGetRanges(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
47369ce434fSBarry Smith @*/
47469ce434fSBarry Smith PetscErrorCode PetscLayoutGetRange(PetscLayout map,PetscInt *rstart,PetscInt *rend)
47569ce434fSBarry Smith {
47669ce434fSBarry Smith   PetscFunctionBegin;
47769ce434fSBarry Smith   if (rstart) *rstart = map->rstart;
47869ce434fSBarry Smith   if (rend)   *rend   = map->rend;
47969ce434fSBarry Smith   PetscFunctionReturn(0);
48069ce434fSBarry Smith }
48169ce434fSBarry Smith 
48269ce434fSBarry Smith /*@C
48369ce434fSBarry Smith      PetscLayoutGetRanges - gets the range of values owned by all processes
48469ce434fSBarry Smith 
48569ce434fSBarry Smith     Not Collective
48669ce434fSBarry Smith 
48769ce434fSBarry Smith    Input Parameters:
48869ce434fSBarry Smith .    map - pointer to the map
48969ce434fSBarry Smith 
49069ce434fSBarry Smith    Output Parameters:
49169ce434fSBarry Smith .    range - start of each processors range of indices (the final entry is one more then the
49269ce434fSBarry Smith              last index on the last process)
49369ce434fSBarry Smith 
49469ce434fSBarry Smith    Level: developer
49569ce434fSBarry Smith 
49669ce434fSBarry Smith     Notes:
49769ce434fSBarry Smith        Call this after the call to PetscLayoutSetUp()
49869ce434fSBarry Smith 
49969ce434fSBarry Smith     Fortran Notes:
50069ce434fSBarry Smith       Not available from Fortran
50169ce434fSBarry Smith 
50269ce434fSBarry Smith .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutSetSize(),
50369ce434fSBarry Smith           PetscLayoutGetSize(), PetscLayoutGetRange(), PetscLayoutSetBlockSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
50469ce434fSBarry Smith 
50569ce434fSBarry Smith @*/
50669ce434fSBarry Smith PetscErrorCode  PetscLayoutGetRanges(PetscLayout map,const PetscInt *range[])
50769ce434fSBarry Smith {
50869ce434fSBarry Smith   PetscFunctionBegin;
50969ce434fSBarry Smith   *range = map->range;
51069ce434fSBarry Smith   PetscFunctionReturn(0);
51169ce434fSBarry Smith }
51269ce434fSBarry Smith 
51369ce434fSBarry Smith /*@C
51469ce434fSBarry Smith    PetscSFSetGraphLayout - Set a parallel star forest via global indices and a PetscLayout
51569ce434fSBarry Smith 
51669ce434fSBarry Smith    Collective
51769ce434fSBarry Smith 
51869ce434fSBarry Smith    Input Arguments:
51969ce434fSBarry Smith +  sf - star forest
52069ce434fSBarry Smith .  layout - PetscLayout defining the global space
52169ce434fSBarry Smith .  nleaves - number of leaf vertices on the current process, each of these references a root on any process
52269ce434fSBarry Smith .  ilocal - locations of leaves in leafdata buffers, pass NULL for contiguous storage
523cf79137fSStefano Zampini .  localmode - copy mode for ilocal
52469ce434fSBarry Smith -  iremote - remote locations of root vertices for each leaf on the current process
52569ce434fSBarry Smith 
52669ce434fSBarry Smith    Level: intermediate
52769ce434fSBarry Smith 
528cf79137fSStefano Zampini    Developers Note: Local indices which are the identity permutation in the range [0,nleaves) are discarded as they
529cf79137fSStefano Zampini    encode contiguous storage. In such case, if localmode is PETSC_OWN_POINTER, the memory is deallocated as it is not
530cf79137fSStefano Zampini    needed
531cf79137fSStefano Zampini 
53269ce434fSBarry Smith .seealso: PetscSFCreate(), PetscSFView(), PetscSFSetGraph(), PetscSFGetGraph()
53369ce434fSBarry Smith @*/
53469ce434fSBarry Smith PetscErrorCode PetscSFSetGraphLayout(PetscSF sf,PetscLayout layout,PetscInt nleaves,const PetscInt *ilocal,PetscCopyMode localmode,const PetscInt *iremote)
53569ce434fSBarry Smith {
53669ce434fSBarry Smith   PetscErrorCode ierr;
53769ce434fSBarry Smith   PetscInt       i,nroots;
53869ce434fSBarry Smith   PetscSFNode    *remote;
53969ce434fSBarry Smith 
54069ce434fSBarry Smith   PetscFunctionBegin;
54169ce434fSBarry Smith   ierr = PetscLayoutGetLocalSize(layout,&nroots);CHKERRQ(ierr);
542785e854fSJed Brown   ierr = PetscMalloc1(nleaves,&remote);CHKERRQ(ierr);
54369ce434fSBarry Smith   for (i=0; i<nleaves; i++) {
54469ce434fSBarry Smith     PetscInt owner = -1;
54569ce434fSBarry Smith     ierr = PetscLayoutFindOwner(layout,iremote[i],&owner);CHKERRQ(ierr);
54669ce434fSBarry Smith     remote[i].rank  = owner;
54769ce434fSBarry Smith     remote[i].index = iremote[i] - layout->range[owner];
54869ce434fSBarry Smith   }
54969ce434fSBarry Smith   ierr = PetscSFSetGraph(sf,nroots,nleaves,ilocal,localmode,remote,PETSC_OWN_POINTER);CHKERRQ(ierr);
55069ce434fSBarry Smith   PetscFunctionReturn(0);
55169ce434fSBarry Smith }
55269ce434fSBarry Smith 
553f92d6284SStefano Zampini /*@
554f92d6284SStefano Zampini   PetscLayoutCompare - Compares two layouts
555f92d6284SStefano Zampini 
556f92d6284SStefano Zampini   Not Collective
557f92d6284SStefano Zampini 
558f92d6284SStefano Zampini   Input Parameters:
559d11c674dSStefano Zampini + mapa - pointer to the first map
560f92d6284SStefano Zampini - mapb - pointer to the second map
561f92d6284SStefano Zampini 
562f92d6284SStefano Zampini   Output Parameters:
563f92d6284SStefano Zampini . congruent - PETSC_TRUE if the two layouts are congruent, PETSC_FALSE otherwise
564f92d6284SStefano Zampini 
565f92d6284SStefano Zampini   Level: beginner
566f92d6284SStefano Zampini 
567f92d6284SStefano Zampini   Notes:
568f92d6284SStefano Zampini 
569f92d6284SStefano Zampini .seealso: PetscLayoutCreate(), PetscLayoutSetLocalSize(), PetscLayoutGetLocalSize(), PetscLayoutGetBlockSize(),
570f92d6284SStefano Zampini           PetscLayoutGetRange(), PetscLayoutGetRanges(), PetscLayoutSetSize(), PetscLayoutGetSize(), PetscLayoutSetUp()
571f92d6284SStefano Zampini @*/
572f92d6284SStefano Zampini PetscErrorCode PetscLayoutCompare(PetscLayout mapa,PetscLayout mapb,PetscBool *congruent)
573f92d6284SStefano Zampini {
574f92d6284SStefano Zampini   PetscErrorCode ierr;
575f92d6284SStefano Zampini   PetscMPIInt    sizea,sizeb;
576f92d6284SStefano Zampini 
577f92d6284SStefano Zampini   PetscFunctionBegin;
578f92d6284SStefano Zampini   *congruent = PETSC_FALSE;
579f92d6284SStefano Zampini   ierr = MPI_Comm_size(mapa->comm,&sizea);CHKERRQ(ierr);
580f92d6284SStefano Zampini   ierr = MPI_Comm_size(mapb->comm,&sizeb);CHKERRQ(ierr);
581f92d6284SStefano Zampini   if (mapa->N == mapb->N && mapa->range && mapb->range && sizea == sizeb) {
582f92d6284SStefano Zampini     ierr = PetscMemcmp(mapa->range,mapb->range,(sizea+1)*sizeof(PetscInt),congruent);CHKERRQ(ierr);
583f92d6284SStefano Zampini   }
584f92d6284SStefano Zampini   PetscFunctionReturn(0);
585f92d6284SStefano Zampini }
586