xref: /petsc/src/sys/objects/subcomm.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b) !
17d0a6c19SBarry Smith 
2cd05a4c0SHong Zhang /*
3cd05a4c0SHong Zhang      Provides utility routines for split MPI communicator.
4cd05a4c0SHong Zhang */
5c6db04a5SJed Brown #include <petscsys.h>    /*I   "petscsys.h"    I*/
6053d1c95SHong Zhang #include <petscviewer.h>
7cd05a4c0SHong Zhang 
802c9f0b5SLisandro Dalcin const char *const PetscSubcommTypes[] = {"GENERAL","CONTIGUOUS","INTERLACED","PetscSubcommType","PETSC_SUBCOMM_",NULL};
96a6fc655SJed Brown 
1095c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm);
1195c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm);
12e5acf8a4SHong Zhang 
13a530d236SBarry Smith /*@
14e5acf8a4SHong Zhang    PetscSubcommSetFromOptions - Allows setting options from a PetscSubcomm
15e5acf8a4SHong Zhang 
16e5acf8a4SHong Zhang    Collective on PetscSubcomm
17e5acf8a4SHong Zhang 
18e5acf8a4SHong Zhang    Input Parameter:
19e5acf8a4SHong Zhang .  psubcomm - PetscSubcomm context
20e5acf8a4SHong Zhang 
21e5acf8a4SHong Zhang    Level: beginner
22e5acf8a4SHong Zhang 
23e5acf8a4SHong Zhang @*/
24f68be91cSHong Zhang PetscErrorCode PetscSubcommSetFromOptions(PetscSubcomm psubcomm)
25f68be91cSHong Zhang {
26f68be91cSHong Zhang   PetscErrorCode   ierr;
2745487dadSJed Brown   PetscSubcommType type;
28f68be91cSHong Zhang   PetscBool        flg;
29f68be91cSHong Zhang 
30f68be91cSHong Zhang   PetscFunctionBegin;
31*28b400f6SJacob Faibussowitsch   PetscCheck(psubcomm,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Must call PetscSubcommCreate firt");
3260f5f21cSHong Zhang 
33e5acf8a4SHong Zhang   ierr = PetscOptionsBegin(psubcomm->parent,psubcomm->subcommprefix,"Options for PetscSubcomm",NULL);CHKERRQ(ierr);
345f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsEnum("-psubcomm_type",NULL,NULL,PetscSubcommTypes,(PetscEnum)psubcomm->type,(PetscEnum*)&type,&flg));
35f68be91cSHong Zhang   if (flg && psubcomm->type != type) {
36f68be91cSHong Zhang     /* free old structures */
375f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCommDestroy(&(psubcomm)->dupparent));
385f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscCommDestroy(&(psubcomm)->child));
395f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree((psubcomm)->subsize));
40f68be91cSHong Zhang     switch (type) {
4145487dadSJed Brown     case PETSC_SUBCOMM_GENERAL:
42b3a4ddeeSHong Zhang       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Runtime option PETSC_SUBCOMM_GENERAL is not supported, use PetscSubcommSetTypeGeneral()");
4345487dadSJed Brown     case PETSC_SUBCOMM_CONTIGUOUS:
445f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSubcommCreate_contiguous(psubcomm));
45f68be91cSHong Zhang       break;
4645487dadSJed Brown     case PETSC_SUBCOMM_INTERLACED:
475f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSubcommCreate_interlaced(psubcomm));
48f68be91cSHong Zhang       break;
49f68be91cSHong Zhang     default:
5098921bdaSJacob Faibussowitsch       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscSubcommType %s is not supported yet",PetscSubcommTypes[type]);
51f68be91cSHong Zhang     }
52f68be91cSHong Zhang   }
5319171117SHong Zhang 
545f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsName("-psubcomm_view","Triggers display of PetscSubcomm context","PetscSubcommView",&flg));
5519171117SHong Zhang   if (flg) {
565f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSubcommView(psubcomm,PETSC_VIEWER_STDOUT_(psubcomm->parent)));
5719171117SHong Zhang   }
5860f5f21cSHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
59f68be91cSHong Zhang   PetscFunctionReturn(0);
60f68be91cSHong Zhang }
61d8a68f86SHong Zhang 
62e5acf8a4SHong Zhang /*@C
63e5acf8a4SHong Zhang   PetscSubcommSetOptionsPrefix - Sets the prefix used for searching for all
64e5acf8a4SHong Zhang   PetscSubcomm items in the options database.
65e5acf8a4SHong Zhang 
66e5acf8a4SHong Zhang   Logically collective on PetscSubcomm.
67e5acf8a4SHong Zhang 
68e5acf8a4SHong Zhang   Level: Intermediate
69e5acf8a4SHong Zhang 
70e5acf8a4SHong Zhang   Input Parameters:
71e5acf8a4SHong Zhang +   psubcomm - PetscSubcomm context
72e5acf8a4SHong Zhang -   prefix - the prefix to prepend all PetscSubcomm item names with.
73e5acf8a4SHong Zhang 
74e5acf8a4SHong Zhang @*/
75e5acf8a4SHong Zhang PetscErrorCode PetscSubcommSetOptionsPrefix(PetscSubcomm psubcomm,const char pre[])
76e5acf8a4SHong Zhang {
77e5acf8a4SHong Zhang   PetscFunctionBegin;
78e5acf8a4SHong Zhang    if (!pre) {
795f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(psubcomm->subcommprefix));
80e5acf8a4SHong Zhang   } else {
812c71b3e2SJacob Faibussowitsch     PetscCheckFalse(pre[0] == '-',PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen");
825f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(psubcomm->subcommprefix));
835f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrallocpy(pre,&(psubcomm->subcommprefix)));
84e5acf8a4SHong Zhang   }
85e5acf8a4SHong Zhang   PetscFunctionReturn(0);
86e5acf8a4SHong Zhang }
87e5acf8a4SHong Zhang 
88e5acf8a4SHong Zhang /*@C
8923072422SBarry Smith    PetscSubcommView - Views a PetscSubcomm of values as either ASCII text or a binary file
90e5acf8a4SHong Zhang 
91e5acf8a4SHong Zhang    Collective on PetscSubcomm
92e5acf8a4SHong Zhang 
93d8d19677SJose E. Roman    Input Parameters:
94e5acf8a4SHong Zhang +  psubcomm - PetscSubcomm context
95e5acf8a4SHong Zhang -  viewer - location to view the values
96e5acf8a4SHong Zhang 
97e5acf8a4SHong Zhang    Level: beginner
98e5acf8a4SHong Zhang @*/
99053d1c95SHong Zhang PetscErrorCode PetscSubcommView(PetscSubcomm psubcomm,PetscViewer viewer)
100053d1c95SHong Zhang {
101053d1c95SHong Zhang   PetscBool         iascii;
102053d1c95SHong Zhang   PetscViewerFormat format;
103053d1c95SHong Zhang 
104053d1c95SHong Zhang   PetscFunctionBegin;
1055f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
106053d1c95SHong Zhang   if (iascii) {
1075f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerGetFormat(viewer,&format));
108053d1c95SHong Zhang     if (format == PETSC_VIEWER_DEFAULT) {
109053d1c95SHong Zhang       MPI_Comm    comm=psubcomm->parent;
110053d1c95SHong Zhang       PetscMPIInt rank,size,subsize,subrank,duprank;
111053d1c95SHong Zhang 
1125f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Comm_size(comm,&size));
1135f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPrintf(viewer,"PetscSubcomm type %s with total %d MPI processes:\n",PetscSubcommTypes[psubcomm->type],size));
1145f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Comm_rank(comm,&rank));
1155f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Comm_size(psubcomm->child,&subsize));
1165f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Comm_rank(psubcomm->child,&subrank));
1175f80ce2aSJacob Faibussowitsch       CHKERRMPI(MPI_Comm_rank(psubcomm->dupparent,&duprank));
1185f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPushSynchronized(viewer));
1195f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIISynchronizedPrintf(viewer,"  [%d], color %d, sub-size %d, sub-rank %d, duprank %d\n",rank,psubcomm->color,subsize,subrank,duprank));
1205f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerFlush(viewer));
1215f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscViewerASCIIPopSynchronized(viewer));
122053d1c95SHong Zhang     }
123053d1c95SHong Zhang   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported yet");
124053d1c95SHong Zhang   PetscFunctionReturn(0);
125053d1c95SHong Zhang }
126053d1c95SHong Zhang 
127a530d236SBarry Smith /*@
128d8a68f86SHong Zhang   PetscSubcommSetNumber - Set total number of subcommunicators.
129d8a68f86SHong Zhang 
130d083f849SBarry Smith    Collective
131d8a68f86SHong Zhang 
132d8d19677SJose E. Roman    Input Parameters:
133d8a68f86SHong Zhang +  psubcomm - PetscSubcomm context
134d8a68f86SHong Zhang -  nsubcomm - the total number of subcommunicators in psubcomm
135d8a68f86SHong Zhang 
136d8a68f86SHong Zhang    Level: advanced
137d8a68f86SHong Zhang 
138d8a68f86SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetType(),PetscSubcommSetTypeGeneral()
139d8a68f86SHong Zhang @*/
1407087cfbeSBarry Smith PetscErrorCode  PetscSubcommSetNumber(PetscSubcomm psubcomm,PetscInt nsubcomm)
141d8a68f86SHong Zhang {
142d8a68f86SHong Zhang   MPI_Comm       comm=psubcomm->parent;
14345487dadSJed Brown   PetscMPIInt    msub,size;
144d8a68f86SHong Zhang 
145d8a68f86SHong Zhang   PetscFunctionBegin;
146*28b400f6SJacob Faibussowitsch   PetscCheck(psubcomm,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate() first");
1475f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
1485f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMPIIntCast(nsubcomm,&msub));
1492c71b3e2SJacob Faibussowitsch   PetscCheckFalse(msub < 1 || msub > size,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Num of subcommunicators %d cannot be < 1 or > input comm size %d",msub,size);
150d8a68f86SHong Zhang 
15145487dadSJed Brown   psubcomm->n = msub;
152d8a68f86SHong Zhang   PetscFunctionReturn(0);
153d8a68f86SHong Zhang }
154d8a68f86SHong Zhang 
155a530d236SBarry Smith /*@
156d8a68f86SHong Zhang   PetscSubcommSetType - Set type of subcommunicators.
157d8a68f86SHong Zhang 
158d083f849SBarry Smith    Collective
159d8a68f86SHong Zhang 
160d8d19677SJose E. Roman    Input Parameters:
161d8a68f86SHong Zhang +  psubcomm - PetscSubcomm context
1621ba920a7SHong Zhang -  subcommtype - subcommunicator type, PETSC_SUBCOMM_CONTIGUOUS,PETSC_SUBCOMM_INTERLACED
163d8a68f86SHong Zhang 
164d8a68f86SHong Zhang    Level: advanced
165d8a68f86SHong Zhang 
166a530d236SBarry Smith .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetNumber(),PetscSubcommSetTypeGeneral(), PetscSubcommType
167d8a68f86SHong Zhang @*/
1687c764164SBarry Smith PetscErrorCode  PetscSubcommSetType(PetscSubcomm psubcomm,PetscSubcommType subcommtype)
169d8a68f86SHong Zhang {
170d8a68f86SHong Zhang   PetscFunctionBegin;
171*28b400f6SJacob Faibussowitsch   PetscCheck(psubcomm,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate()");
1722c71b3e2SJacob Faibussowitsch   PetscCheckFalse(psubcomm->n < 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()",psubcomm->n);
173d8a68f86SHong Zhang 
174d8a68f86SHong Zhang   if (subcommtype == PETSC_SUBCOMM_CONTIGUOUS) {
1755f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSubcommCreate_contiguous(psubcomm));
176d8a68f86SHong Zhang   } else if (subcommtype == PETSC_SUBCOMM_INTERLACED) {
1775f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscSubcommCreate_interlaced(psubcomm));
17898921bdaSJacob Faibussowitsch   } else SETERRQ(psubcomm->parent,PETSC_ERR_SUP,"PetscSubcommType %s is not supported yet",PetscSubcommTypes[subcommtype]);
179d8a68f86SHong Zhang   PetscFunctionReturn(0);
180d8a68f86SHong Zhang }
181d8a68f86SHong Zhang 
182a530d236SBarry Smith /*@
18365d9b8f1SHong Zhang   PetscSubcommSetTypeGeneral - Set a PetscSubcomm from user's specifications
1841ba920a7SHong Zhang 
185d083f849SBarry Smith    Collective
1861ba920a7SHong Zhang 
187d8d19677SJose E. Roman    Input Parameters:
1881ba920a7SHong Zhang +  psubcomm - PetscSubcomm context
1891ba920a7SHong Zhang .  color   - control of subset assignment (nonnegative integer). Processes with the same color are in the same subcommunicator.
19065d9b8f1SHong Zhang -  subrank - rank in the subcommunicator
1911ba920a7SHong Zhang 
1921ba920a7SHong Zhang    Level: advanced
1931ba920a7SHong Zhang 
1941ba920a7SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetNumber(),PetscSubcommSetType()
1951ba920a7SHong Zhang @*/
19665d9b8f1SHong Zhang PetscErrorCode PetscSubcommSetTypeGeneral(PetscSubcomm psubcomm,PetscMPIInt color,PetscMPIInt subrank)
197d8a68f86SHong Zhang {
1981ba920a7SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
199c9e2ceb8SHong Zhang   PetscMPIInt    size,icolor,duprank,*recvbuf,sendbuf[3],mysubsize,rank,*subsize;
20045487dadSJed Brown   PetscMPIInt    i,nsubcomm=psubcomm->n;
2011ba920a7SHong Zhang 
202d8a68f86SHong Zhang   PetscFunctionBegin;
203*28b400f6SJacob Faibussowitsch   PetscCheck(psubcomm,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate()");
2042c71b3e2SJacob Faibussowitsch   PetscCheckFalse(nsubcomm < 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()",nsubcomm);
2051ba920a7SHong Zhang 
2065f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_split(comm,color,subrank,&subcomm));
2071ba920a7SHong Zhang 
20865d9b8f1SHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
2099abe469cSDmitry Karpeev   /* TODO: this can be done in an ostensibly scalale way (i.e., without allocating an array of size 'size') as is done in PetscObjectsCreateGlobalOrdering(). */
2105f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
2115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(2*size,&recvbuf));
21265d9b8f1SHong Zhang 
2135f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
2145f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(subcomm,&mysubsize));
21565d9b8f1SHong Zhang 
21665d9b8f1SHong Zhang   sendbuf[0] = color;
217c9e2ceb8SHong Zhang   sendbuf[1] = mysubsize;
2185f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Allgather(sendbuf,2,MPI_INT,recvbuf,2,MPI_INT,comm));
21965d9b8f1SHong Zhang 
2205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(nsubcomm,&subsize));
2219972d2ceSHong Zhang   for (i=0; i<2*size; i+=2) {
222c9e2ceb8SHong Zhang     subsize[recvbuf[i]] = recvbuf[i+1];
2231ba920a7SHong Zhang   }
2245f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(recvbuf));
22565d9b8f1SHong Zhang 
22665d9b8f1SHong Zhang   duprank = 0;
227c9e2ceb8SHong Zhang   for (icolor=0; icolor<nsubcomm; icolor++) {
22865d9b8f1SHong Zhang     if (icolor != color) { /* not color of this process */
229c9e2ceb8SHong Zhang       duprank += subsize[icolor];
23065d9b8f1SHong Zhang     } else {
23165d9b8f1SHong Zhang       duprank += subrank;
23265d9b8f1SHong Zhang       break;
23365d9b8f1SHong Zhang     }
23465d9b8f1SHong Zhang   }
2355f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_split(comm,0,duprank,&dupcomm));
23665d9b8f1SHong Zhang 
2375f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL));
2385f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDuplicate(subcomm,&psubcomm->child,NULL));
2395f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_free(&dupcomm));
2405f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_free(&subcomm));
241a297a907SKarl Rupp 
2421ba920a7SHong Zhang   psubcomm->color   = color;
243c9e2ceb8SHong Zhang   psubcomm->subsize = subsize;
244c9e2ceb8SHong Zhang   psubcomm->type    = PETSC_SUBCOMM_GENERAL;
245d8a68f86SHong Zhang   PetscFunctionReturn(0);
246d8a68f86SHong Zhang }
247638faf0bSHong Zhang 
248a530d236SBarry Smith /*@
24989587e68SDave May   PetscSubcommDestroy - Destroys a PetscSubcomm object
25089587e68SDave May 
25189587e68SDave May    Collective on PetscSubcomm
25289587e68SDave May 
25389587e68SDave May    Input Parameter:
25489587e68SDave May    .  psubcomm - the PetscSubcomm context
25589587e68SDave May 
25689587e68SDave May    Level: advanced
25789587e68SDave May 
25889587e68SDave May .seealso: PetscSubcommCreate(),PetscSubcommSetType()
25989587e68SDave May @*/
2606bf464f9SBarry Smith PetscErrorCode  PetscSubcommDestroy(PetscSubcomm *psubcomm)
261cd05a4c0SHong Zhang {
262cd05a4c0SHong Zhang   PetscFunctionBegin;
2636bf464f9SBarry Smith   if (!*psubcomm) PetscFunctionReturn(0);
2645f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDestroy(&(*psubcomm)->dupparent));
2655f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDestroy(&(*psubcomm)->child));
2665f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree((*psubcomm)->subsize));
2675f80ce2aSJacob Faibussowitsch   if ((*psubcomm)->subcommprefix) CHKERRQ(PetscFree((*psubcomm)->subcommprefix));
2685f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree((*psubcomm)));
269cd05a4c0SHong Zhang   PetscFunctionReturn(0);
270cd05a4c0SHong Zhang }
271cd05a4c0SHong Zhang 
272a530d236SBarry Smith /*@
273cd05a4c0SHong Zhang   PetscSubcommCreate - Create a PetscSubcomm context.
274cd05a4c0SHong Zhang 
275d083f849SBarry Smith    Collective
276cd05a4c0SHong Zhang 
277cd05a4c0SHong Zhang    Input Parameter:
2789873d53eSJed Brown .  comm - MPI communicator
279cd05a4c0SHong Zhang 
280cd05a4c0SHong Zhang    Output Parameter:
281cd05a4c0SHong Zhang .  psubcomm - location to store the PetscSubcomm context
282cd05a4c0SHong Zhang 
283638faf0bSHong Zhang    Level: advanced
284cd05a4c0SHong Zhang 
285a530d236SBarry Smith .seealso: PetscSubcommDestroy(), PetscSubcommSetTypeGeneral(), PetscSubcommSetFromOptions(), PetscSubcommSetType(),
286a530d236SBarry Smith           PetscSubcommSetNumber()
287638faf0bSHong Zhang @*/
2887087cfbeSBarry Smith PetscErrorCode  PetscSubcommCreate(MPI_Comm comm,PetscSubcomm *psubcomm)
289638faf0bSHong Zhang {
290d3b23db5SHong Zhang   PetscMPIInt    rank,size;
291638faf0bSHong Zhang 
292638faf0bSHong Zhang   PetscFunctionBegin;
2935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(psubcomm));
294a297a907SKarl Rupp 
295d3b23db5SHong Zhang   /* set defaults */
2965f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
2975f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
298f68be91cSHong Zhang 
299d8a68f86SHong Zhang   (*psubcomm)->parent    = comm;
300d3b23db5SHong Zhang   (*psubcomm)->dupparent = comm;
301306c2d5bSBarry Smith   (*psubcomm)->child     = PETSC_COMM_SELF;
302d3b23db5SHong Zhang   (*psubcomm)->n         = size;
303d3b23db5SHong Zhang   (*psubcomm)->color     = rank;
304e37c6257SHong Zhang   (*psubcomm)->subsize   = NULL;
305d3b23db5SHong Zhang   (*psubcomm)->type      = PETSC_SUBCOMM_INTERLACED;
306638faf0bSHong Zhang   PetscFunctionReturn(0);
307638faf0bSHong Zhang }
308638faf0bSHong Zhang 
309a530d236SBarry Smith /*@C
310a530d236SBarry Smith   PetscSubcommGetParent - Gets the communicator that was used to create the PetscSubcomm
311a530d236SBarry Smith 
312a530d236SBarry Smith    Collective
313a530d236SBarry Smith 
314a530d236SBarry Smith    Input Parameter:
315a530d236SBarry Smith .  scomm - the PetscSubcomm
316a530d236SBarry Smith 
317a530d236SBarry Smith    Output Parameter:
318a530d236SBarry Smith .  pcomm - location to store the parent communicator
319a530d236SBarry Smith 
320a530d236SBarry Smith    Level: intermediate
321a530d236SBarry Smith 
322a530d236SBarry Smith .seealso: PetscSubcommDestroy(), PetscSubcommSetTypeGeneral(), PetscSubcommSetFromOptions(), PetscSubcommSetType(),
323a530d236SBarry Smith           PetscSubcommSetNumber(), PetscSubcommGetChild(), PetscSubcommContiguousParent()
324a530d236SBarry Smith @*/
325a530d236SBarry Smith PetscErrorCode  PetscSubcommGetParent(PetscSubcomm scomm,MPI_Comm *pcomm)
326a530d236SBarry Smith {
327a530d236SBarry Smith   *pcomm = PetscSubcommParent(scomm);
328a530d236SBarry Smith   return 0;
329a530d236SBarry Smith }
330a530d236SBarry Smith 
331a530d236SBarry Smith /*@C
332a530d236SBarry Smith   PetscSubcommGetContiguousParent - Gets a communicator that that is a duplicate of the parent but has the ranks
333a530d236SBarry Smith                                     reordered by the order they are in the children
334a530d236SBarry Smith 
335a530d236SBarry Smith    Collective
336a530d236SBarry Smith 
337a530d236SBarry Smith    Input Parameter:
338a530d236SBarry Smith .  scomm - the PetscSubcomm
339a530d236SBarry Smith 
340a530d236SBarry Smith    Output Parameter:
341a530d236SBarry Smith .  pcomm - location to store the parent communicator
342a530d236SBarry Smith 
343a530d236SBarry Smith    Level: intermediate
344a530d236SBarry Smith 
345a530d236SBarry Smith .seealso: PetscSubcommDestroy(), PetscSubcommSetTypeGeneral(), PetscSubcommSetFromOptions(), PetscSubcommSetType(),
346a530d236SBarry Smith           PetscSubcommSetNumber(), PetscSubcommGetChild(), PetscSubcommContiguousParent()
347a530d236SBarry Smith @*/
348a530d236SBarry Smith PetscErrorCode  PetscSubcommGetContiguousParent(PetscSubcomm scomm,MPI_Comm *pcomm)
349a530d236SBarry Smith {
350a530d236SBarry Smith   *pcomm = PetscSubcommContiguousParent(scomm);
351a530d236SBarry Smith   return 0;
352a530d236SBarry Smith }
353a530d236SBarry Smith 
354a530d236SBarry Smith /*@C
355a530d236SBarry Smith   PetscSubcommGetChild - Gets the communicator created by the PetscSubcomm
356a530d236SBarry Smith 
357a530d236SBarry Smith    Collective
358a530d236SBarry Smith 
359a530d236SBarry Smith    Input Parameter:
360a530d236SBarry Smith .  scomm - the PetscSubcomm
361a530d236SBarry Smith 
362a530d236SBarry Smith    Output Parameter:
363a530d236SBarry Smith .  ccomm - location to store the child communicator
364a530d236SBarry Smith 
365a530d236SBarry Smith    Level: intermediate
366a530d236SBarry Smith 
367a530d236SBarry Smith .seealso: PetscSubcommDestroy(), PetscSubcommSetTypeGeneral(), PetscSubcommSetFromOptions(), PetscSubcommSetType(),
368a530d236SBarry Smith           PetscSubcommSetNumber(), PetscSubcommGetParent(), PetscSubcommContiguousParent()
369a530d236SBarry Smith @*/
370a530d236SBarry Smith PetscErrorCode  PetscSubcommGetChild(PetscSubcomm scomm,MPI_Comm *ccomm)
371a530d236SBarry Smith {
372a530d236SBarry Smith   *ccomm = PetscSubcommChild(scomm);
373a530d236SBarry Smith   return 0;
374a530d236SBarry Smith }
375a530d236SBarry Smith 
37695c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm psubcomm)
377638faf0bSHong Zhang {
378d6037b41SHong Zhang   PetscMPIInt    rank,size,*subsize,duprank=-1,subrank=-1;
37945487dadSJed Brown   PetscMPIInt    np_subcomm,nleftover,i,color=-1,rankstart,nsubcomm=psubcomm->n;
380d8a68f86SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
381638faf0bSHong Zhang 
382638faf0bSHong Zhang   PetscFunctionBegin;
3835f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
3845f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
38555e3b8d2SHong Zhang 
386638faf0bSHong Zhang   /* get size of each subcommunicator */
3875f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(1+nsubcomm,&subsize));
388a297a907SKarl Rupp 
389638faf0bSHong Zhang   np_subcomm = size/nsubcomm;
390638faf0bSHong Zhang   nleftover  = size - nsubcomm*np_subcomm;
391638faf0bSHong Zhang   for (i=0; i<nsubcomm; i++) {
392638faf0bSHong Zhang     subsize[i] = np_subcomm;
393638faf0bSHong Zhang     if (i<nleftover) subsize[i]++;
394638faf0bSHong Zhang   }
395638faf0bSHong Zhang 
396638faf0bSHong Zhang   /* get color and subrank of this proc */
397638faf0bSHong Zhang   rankstart = 0;
398638faf0bSHong Zhang   for (i=0; i<nsubcomm; i++) {
399638faf0bSHong Zhang     if (rank >= rankstart && rank < rankstart+subsize[i]) {
400638faf0bSHong Zhang       color   = i;
401638faf0bSHong Zhang       subrank = rank - rankstart;
402638faf0bSHong Zhang       duprank = rank;
403638faf0bSHong Zhang       break;
404a297a907SKarl Rupp     } else rankstart += subsize[i];
405638faf0bSHong Zhang   }
406638faf0bSHong Zhang 
4075f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_split(comm,color,subrank,&subcomm));
408638faf0bSHong Zhang 
409638faf0bSHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
4105f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_split(comm,0,duprank,&dupcomm));
4115f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL));
4125f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDuplicate(subcomm,&psubcomm->child,NULL));
4135f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_free(&dupcomm));
4145f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_free(&subcomm));
415a297a907SKarl Rupp 
416d8a68f86SHong Zhang   psubcomm->color   = color;
417e37c6257SHong Zhang   psubcomm->subsize = subsize;
418f38d543fSHong Zhang   psubcomm->type    = PETSC_SUBCOMM_CONTIGUOUS;
419638faf0bSHong Zhang   PetscFunctionReturn(0);
420638faf0bSHong Zhang }
421638faf0bSHong Zhang 
422638faf0bSHong Zhang /*
423638faf0bSHong Zhang    Note:
424638faf0bSHong Zhang    In PCREDUNDANT, to avoid data scattering from subcomm back to original comm, we create subcommunicators
42545fc02eaSBarry Smith    by iteratively taking a process into a subcommunicator.
426cd05a4c0SHong Zhang    Example: size=4, nsubcomm=(*psubcomm)->n=3
427cd05a4c0SHong Zhang      comm=(*psubcomm)->parent:
428cd05a4c0SHong Zhang       rank:     [0]  [1]  [2]  [3]
429cd05a4c0SHong Zhang       color:     0    1    2    0
430cd05a4c0SHong Zhang 
431cd05a4c0SHong Zhang      subcomm=(*psubcomm)->comm:
432cd05a4c0SHong Zhang       subrank:  [0]  [0]  [0]  [1]
433cd05a4c0SHong Zhang 
434cd05a4c0SHong Zhang      dupcomm=(*psubcomm)->dupparent:
435cd05a4c0SHong Zhang       duprank:  [0]  [2]  [3]  [1]
436cd05a4c0SHong Zhang 
437cd05a4c0SHong Zhang      Here, subcomm[color = 0] has subsize=2, owns process [0] and [3]
438cd05a4c0SHong Zhang            subcomm[color = 1] has subsize=1, owns process [1]
439cd05a4c0SHong Zhang            subcomm[color = 2] has subsize=1, owns process [2]
440cd05a4c0SHong Zhang            dupcomm has same number of processes as comm, and its duprank maps
441cd05a4c0SHong Zhang            processes in subcomm contiguously into a 1d array:
442cd05a4c0SHong Zhang             duprank: [0] [1]      [2]         [3]
443cd05a4c0SHong Zhang             rank:    [0] [3]      [1]         [2]
444cd05a4c0SHong Zhang                     subcomm[0] subcomm[1]  subcomm[2]
445638faf0bSHong Zhang */
446cd05a4c0SHong Zhang 
44795c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm psubcomm)
448cd05a4c0SHong Zhang {
449cd05a4c0SHong Zhang   PetscMPIInt    rank,size,*subsize,duprank,subrank;
45045487dadSJed Brown   PetscMPIInt    np_subcomm,nleftover,i,j,color,nsubcomm=psubcomm->n;
451d8a68f86SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
452cd05a4c0SHong Zhang 
453cd05a4c0SHong Zhang   PetscFunctionBegin;
4545f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
4555f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(comm,&size));
45655e3b8d2SHong Zhang 
457cd05a4c0SHong Zhang   /* get size of each subcommunicator */
4585f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(1+nsubcomm,&subsize));
459a297a907SKarl Rupp 
460cd05a4c0SHong Zhang   np_subcomm = size/nsubcomm;
461cd05a4c0SHong Zhang   nleftover  = size - nsubcomm*np_subcomm;
462cd05a4c0SHong Zhang   for (i=0; i<nsubcomm; i++) {
463cd05a4c0SHong Zhang     subsize[i] = np_subcomm;
464cd05a4c0SHong Zhang     if (i<nleftover) subsize[i]++;
465cd05a4c0SHong Zhang   }
466cd05a4c0SHong Zhang 
467cd05a4c0SHong Zhang   /* find color for this proc */
468cd05a4c0SHong Zhang   color   = rank%nsubcomm;
469cd05a4c0SHong Zhang   subrank = rank/nsubcomm;
470cd05a4c0SHong Zhang 
4715f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_split(comm,color,subrank,&subcomm));
472cd05a4c0SHong Zhang 
473cd05a4c0SHong Zhang   j = 0; duprank = 0;
474cd05a4c0SHong Zhang   for (i=0; i<nsubcomm; i++) {
475cd05a4c0SHong Zhang     if (j == color) {
476cd05a4c0SHong Zhang       duprank += subrank;
477cd05a4c0SHong Zhang       break;
478cd05a4c0SHong Zhang     }
479cd05a4c0SHong Zhang     duprank += subsize[i]; j++;
480cd05a4c0SHong Zhang   }
481cd05a4c0SHong Zhang 
482cd05a4c0SHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
4835f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_split(comm,0,duprank,&dupcomm));
4845f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL));
4855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCommDuplicate(subcomm,&psubcomm->child,NULL));
4865f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_free(&dupcomm));
4875f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_free(&subcomm));
488a297a907SKarl Rupp 
489d8a68f86SHong Zhang   psubcomm->color   = color;
490e37c6257SHong Zhang   psubcomm->subsize = subsize;
491f38d543fSHong Zhang   psubcomm->type    = PETSC_SUBCOMM_INTERLACED;
492cd05a4c0SHong Zhang   PetscFunctionReturn(0);
493cd05a4c0SHong Zhang }
494