xref: /petsc/src/sys/objects/subcomm.c (revision 0c9e03a23736c6f278a3454d64cad9517dcb2688)
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 
86a6fc655SJed Brown const char *const PetscSubcommTypes[] = {"GENERAL","CONTIGUOUS","INTERLACED","PetscSubcommType","PETSC_SUBCOMM_",0};
96a6fc655SJed Brown 
1095c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm);
1195c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm);
12e5acf8a4SHong Zhang 
13e5acf8a4SHong Zhang /*@C
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;
31f68be91cSHong Zhang   if (!psubcomm) SETERRQ(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);
3460f5f21cSHong Zhang   ierr = PetscOptionsEnum("-psubcomm_type",NULL,NULL,PetscSubcommTypes,(PetscEnum)psubcomm->type,(PetscEnum*)&type,&flg);CHKERRQ(ierr);
35f68be91cSHong Zhang   if (flg && psubcomm->type != type) {
36f68be91cSHong Zhang     /* free old structures */
37f68be91cSHong Zhang     ierr = PetscCommDestroy(&(psubcomm)->dupparent);CHKERRQ(ierr);
38306c2d5bSBarry Smith     ierr = PetscCommDestroy(&(psubcomm)->child);CHKERRQ(ierr);
39f68be91cSHong Zhang     ierr = PetscFree((psubcomm)->subsize);CHKERRQ(ierr);
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:
44f68be91cSHong Zhang       ierr = PetscSubcommCreate_contiguous(psubcomm);CHKERRQ(ierr);
45f68be91cSHong Zhang       break;
4645487dadSJed Brown     case PETSC_SUBCOMM_INTERLACED:
47f68be91cSHong Zhang       ierr = PetscSubcommCreate_interlaced(psubcomm);CHKERRQ(ierr);
48f68be91cSHong Zhang       break;
49f68be91cSHong Zhang     default:
5045487dadSJed Brown       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscSubcommType %s is not supported yet",PetscSubcommTypes[type]);
51f68be91cSHong Zhang     }
52f68be91cSHong Zhang   }
5319171117SHong Zhang 
5460f5f21cSHong Zhang   ierr = PetscOptionsName("-psubcomm_view","Triggers display of PetscSubcomm context","PetscSubcommView",&flg);CHKERRQ(ierr);
5519171117SHong Zhang   if (flg) {
56*0c9e03a2SStefano Zampini     ierr = PetscSubcommView(psubcomm,PETSC_VIEWER_STDOUT_(psubcomm->parent));CHKERRQ(ierr);
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   PetscErrorCode   ierr;
78e5acf8a4SHong Zhang 
79e5acf8a4SHong Zhang   PetscFunctionBegin;
80e5acf8a4SHong Zhang    if (!pre) {
81e5acf8a4SHong Zhang     ierr = PetscFree(psubcomm->subcommprefix);CHKERRQ(ierr);
82e5acf8a4SHong Zhang   } else {
83e5acf8a4SHong Zhang     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
84e5acf8a4SHong Zhang     ierr = PetscFree(psubcomm->subcommprefix);CHKERRQ(ierr);
85e5acf8a4SHong Zhang     ierr = PetscStrallocpy(pre,&(psubcomm->subcommprefix));CHKERRQ(ierr);
86e5acf8a4SHong Zhang   }
87e5acf8a4SHong Zhang   PetscFunctionReturn(0);
88e5acf8a4SHong Zhang }
89e5acf8a4SHong Zhang 
90e5acf8a4SHong Zhang /*@C
9123072422SBarry Smith    PetscSubcommView - Views a PetscSubcomm of values as either ASCII text or a binary file
92e5acf8a4SHong Zhang 
93e5acf8a4SHong Zhang    Collective on PetscSubcomm
94e5acf8a4SHong Zhang 
95e5acf8a4SHong Zhang    Input Parameter:
96e5acf8a4SHong Zhang +  psubcomm - PetscSubcomm context
97e5acf8a4SHong Zhang -  viewer - location to view the values
98e5acf8a4SHong Zhang 
99e5acf8a4SHong Zhang    Level: beginner
100e5acf8a4SHong Zhang @*/
101053d1c95SHong Zhang PetscErrorCode PetscSubcommView(PetscSubcomm psubcomm,PetscViewer viewer)
102053d1c95SHong Zhang {
103053d1c95SHong Zhang   PetscErrorCode    ierr;
104053d1c95SHong Zhang   PetscBool         iascii;
105053d1c95SHong Zhang   PetscViewerFormat format;
106053d1c95SHong Zhang 
107053d1c95SHong Zhang   PetscFunctionBegin;
108053d1c95SHong Zhang   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
109053d1c95SHong Zhang   if (iascii) {
110053d1c95SHong Zhang     ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
111053d1c95SHong Zhang     if (format == PETSC_VIEWER_DEFAULT) {
112053d1c95SHong Zhang       MPI_Comm    comm=psubcomm->parent;
113053d1c95SHong Zhang       PetscMPIInt rank,size,subsize,subrank,duprank;
114053d1c95SHong Zhang 
115053d1c95SHong Zhang       ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
11645487dadSJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"PetscSubcomm type %s with total %d MPI processes:\n",PetscSubcommTypes[psubcomm->type],size);CHKERRQ(ierr);
117053d1c95SHong Zhang       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
118306c2d5bSBarry Smith       ierr = MPI_Comm_size(psubcomm->child,&subsize);CHKERRQ(ierr);
119306c2d5bSBarry Smith       ierr = MPI_Comm_rank(psubcomm->child,&subrank);CHKERRQ(ierr);
120053d1c95SHong Zhang       ierr = MPI_Comm_rank(psubcomm->dupparent,&duprank);CHKERRQ(ierr);
121*0c9e03a2SStefano Zampini       ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
122*0c9e03a2SStefano Zampini       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"  [%d], color %d, sub-size %d, sub-rank %d, duprank %d\n",rank,psubcomm->color,subsize,subrank,duprank);CHKERRQ(ierr);
123*0c9e03a2SStefano Zampini       ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
124*0c9e03a2SStefano Zampini       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
125053d1c95SHong Zhang     }
126053d1c95SHong Zhang   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported yet");
127053d1c95SHong Zhang   PetscFunctionReturn(0);
128053d1c95SHong Zhang }
129053d1c95SHong Zhang 
130d8a68f86SHong Zhang /*@C
131d8a68f86SHong Zhang   PetscSubcommSetNumber - Set total number of subcommunicators.
132d8a68f86SHong Zhang 
133d8a68f86SHong Zhang    Collective on MPI_Comm
134d8a68f86SHong Zhang 
135d8a68f86SHong Zhang    Input Parameter:
136d8a68f86SHong Zhang +  psubcomm - PetscSubcomm context
137d8a68f86SHong Zhang -  nsubcomm - the total number of subcommunicators in psubcomm
138d8a68f86SHong Zhang 
139d8a68f86SHong Zhang    Level: advanced
140d8a68f86SHong Zhang 
141d8a68f86SHong Zhang .keywords: communicator
142d8a68f86SHong Zhang 
143d8a68f86SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetType(),PetscSubcommSetTypeGeneral()
144d8a68f86SHong Zhang @*/
1457087cfbeSBarry Smith PetscErrorCode  PetscSubcommSetNumber(PetscSubcomm psubcomm,PetscInt nsubcomm)
146d8a68f86SHong Zhang {
147d8a68f86SHong Zhang   PetscErrorCode ierr;
148d8a68f86SHong Zhang   MPI_Comm       comm=psubcomm->parent;
14945487dadSJed Brown   PetscMPIInt    msub,size;
150d8a68f86SHong Zhang 
151d8a68f86SHong Zhang   PetscFunctionBegin;
152d8a68f86SHong Zhang   if (!psubcomm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate() first");
153d8a68f86SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
15445487dadSJed Brown   ierr = PetscMPIIntCast(nsubcomm,&msub);CHKERRQ(ierr);
15545487dadSJed Brown   if (msub < 1 || msub > size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Num of subcommunicators %d cannot be < 1 or > input comm size %d",msub,size);
156d8a68f86SHong Zhang 
15745487dadSJed Brown   psubcomm->n = msub;
158d8a68f86SHong Zhang   PetscFunctionReturn(0);
159d8a68f86SHong Zhang }
160d8a68f86SHong Zhang 
161d8a68f86SHong Zhang /*@C
162d8a68f86SHong Zhang   PetscSubcommSetType - Set type of subcommunicators.
163d8a68f86SHong Zhang 
164d8a68f86SHong Zhang    Collective on MPI_Comm
165d8a68f86SHong Zhang 
166d8a68f86SHong Zhang    Input Parameter:
167d8a68f86SHong Zhang +  psubcomm - PetscSubcomm context
1681ba920a7SHong Zhang -  subcommtype - subcommunicator type, PETSC_SUBCOMM_CONTIGUOUS,PETSC_SUBCOMM_INTERLACED
169d8a68f86SHong Zhang 
170d8a68f86SHong Zhang    Level: advanced
171d8a68f86SHong Zhang 
172d8a68f86SHong Zhang .keywords: communicator
173d8a68f86SHong Zhang 
174d8a68f86SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetNumber(),PetscSubcommSetTypeGeneral()
175d8a68f86SHong Zhang @*/
1767c764164SBarry Smith PetscErrorCode  PetscSubcommSetType(PetscSubcomm psubcomm,PetscSubcommType subcommtype)
177d8a68f86SHong Zhang {
178d8a68f86SHong Zhang   PetscErrorCode ierr;
179d8a68f86SHong Zhang 
180d8a68f86SHong Zhang   PetscFunctionBegin;
181d8a68f86SHong Zhang   if (!psubcomm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate()");
18245487dadSJed Brown   if (psubcomm->n < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()",psubcomm->n);
183d8a68f86SHong Zhang 
184d8a68f86SHong Zhang   if (subcommtype == PETSC_SUBCOMM_CONTIGUOUS) {
185d8a68f86SHong Zhang     ierr = PetscSubcommCreate_contiguous(psubcomm);CHKERRQ(ierr);
186d8a68f86SHong Zhang   } else if (subcommtype == PETSC_SUBCOMM_INTERLACED) {
187d8a68f86SHong Zhang     ierr = PetscSubcommCreate_interlaced(psubcomm);CHKERRQ(ierr);
18845487dadSJed Brown   } else SETERRQ1(psubcomm->parent,PETSC_ERR_SUP,"PetscSubcommType %s is not supported yet",PetscSubcommTypes[subcommtype]);
189d8a68f86SHong Zhang   PetscFunctionReturn(0);
190d8a68f86SHong Zhang }
191d8a68f86SHong Zhang 
1921ba920a7SHong Zhang /*@C
19365d9b8f1SHong Zhang   PetscSubcommSetTypeGeneral - Set a PetscSubcomm from user's specifications
1941ba920a7SHong Zhang 
1951ba920a7SHong Zhang    Collective on MPI_Comm
1961ba920a7SHong Zhang 
1971ba920a7SHong Zhang    Input Parameter:
1981ba920a7SHong Zhang +  psubcomm - PetscSubcomm context
1991ba920a7SHong Zhang .  color   - control of subset assignment (nonnegative integer). Processes with the same color are in the same subcommunicator.
20065d9b8f1SHong Zhang -  subrank - rank in the subcommunicator
2011ba920a7SHong Zhang 
2021ba920a7SHong Zhang    Level: advanced
2031ba920a7SHong Zhang 
2041ba920a7SHong Zhang .keywords: communicator, create
2051ba920a7SHong Zhang 
2061ba920a7SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetNumber(),PetscSubcommSetType()
2071ba920a7SHong Zhang @*/
20865d9b8f1SHong Zhang PetscErrorCode PetscSubcommSetTypeGeneral(PetscSubcomm psubcomm,PetscMPIInt color,PetscMPIInt subrank)
209d8a68f86SHong Zhang {
2101ba920a7SHong Zhang   PetscErrorCode ierr;
2111ba920a7SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
212c9e2ceb8SHong Zhang   PetscMPIInt    size,icolor,duprank,*recvbuf,sendbuf[3],mysubsize,rank,*subsize;
21345487dadSJed Brown   PetscMPIInt    i,nsubcomm=psubcomm->n;
2141ba920a7SHong Zhang 
215d8a68f86SHong Zhang   PetscFunctionBegin;
2161ba920a7SHong Zhang   if (!psubcomm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate()");
21745487dadSJed Brown   if (nsubcomm < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()",nsubcomm);
2181ba920a7SHong Zhang 
2191ba920a7SHong Zhang   ierr = MPI_Comm_split(comm,color,subrank,&subcomm);CHKERRQ(ierr);
2201ba920a7SHong Zhang 
22165d9b8f1SHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
2229abe469cSDmitry 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(). */
2231ba920a7SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
224785e854fSJed Brown   ierr = PetscMalloc1(2*size,&recvbuf);CHKERRQ(ierr);
22565d9b8f1SHong Zhang 
22665d9b8f1SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
227c9e2ceb8SHong Zhang   ierr = MPI_Comm_size(subcomm,&mysubsize);CHKERRQ(ierr);
22865d9b8f1SHong Zhang 
22965d9b8f1SHong Zhang   sendbuf[0] = color;
230c9e2ceb8SHong Zhang   sendbuf[1] = mysubsize;
231c9e2ceb8SHong Zhang   ierr = MPI_Allgather(sendbuf,2,MPI_INT,recvbuf,2,MPI_INT,comm);CHKERRQ(ierr);
23265d9b8f1SHong Zhang 
233eca4a452SHong Zhang   ierr = PetscCalloc1(nsubcomm,&subsize);CHKERRQ(ierr);
2349972d2ceSHong Zhang   for (i=0; i<2*size; i+=2) {
235c9e2ceb8SHong Zhang     subsize[recvbuf[i]] = recvbuf[i+1];
2361ba920a7SHong Zhang   }
23765d9b8f1SHong Zhang   ierr = PetscFree(recvbuf);CHKERRQ(ierr);
23865d9b8f1SHong Zhang 
23965d9b8f1SHong Zhang   duprank = 0;
240c9e2ceb8SHong Zhang   for (icolor=0; icolor<nsubcomm; icolor++) {
24165d9b8f1SHong Zhang     if (icolor != color) { /* not color of this process */
242c9e2ceb8SHong Zhang       duprank += subsize[icolor];
24365d9b8f1SHong Zhang     } else {
24465d9b8f1SHong Zhang       duprank += subrank;
24565d9b8f1SHong Zhang       break;
24665d9b8f1SHong Zhang     }
24765d9b8f1SHong Zhang   }
24865d9b8f1SHong Zhang   ierr = MPI_Comm_split(comm,0,duprank,&dupcomm);CHKERRQ(ierr);
24965d9b8f1SHong Zhang 
2500298fd71SBarry Smith   ierr = PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL);CHKERRQ(ierr);
251306c2d5bSBarry Smith   ierr = PetscCommDuplicate(subcomm,&psubcomm->child,NULL);CHKERRQ(ierr);
252b89831e5SBarry Smith   ierr = MPI_Comm_free(&dupcomm);CHKERRQ(ierr);
253b89831e5SBarry Smith   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
254a297a907SKarl Rupp 
2551ba920a7SHong Zhang   psubcomm->color   = color;
256c9e2ceb8SHong Zhang   psubcomm->subsize = subsize;
257c9e2ceb8SHong Zhang   psubcomm->type    = PETSC_SUBCOMM_GENERAL;
258d8a68f86SHong Zhang   PetscFunctionReturn(0);
259d8a68f86SHong Zhang }
260638faf0bSHong Zhang 
26189587e68SDave May /*@C
26289587e68SDave May   PetscSubcommDestroy - Destroys a PetscSubcomm object
26389587e68SDave May 
26489587e68SDave May    Collective on PetscSubcomm
26589587e68SDave May 
26689587e68SDave May    Input Parameter:
26789587e68SDave May    .  psubcomm - the PetscSubcomm context
26889587e68SDave May 
26989587e68SDave May    Level: advanced
27089587e68SDave May 
27189587e68SDave May .seealso: PetscSubcommCreate(),PetscSubcommSetType()
27289587e68SDave May @*/
2736bf464f9SBarry Smith PetscErrorCode  PetscSubcommDestroy(PetscSubcomm *psubcomm)
274cd05a4c0SHong Zhang {
275cd05a4c0SHong Zhang   PetscErrorCode ierr;
276cd05a4c0SHong Zhang 
277cd05a4c0SHong Zhang   PetscFunctionBegin;
2786bf464f9SBarry Smith   if (!*psubcomm) PetscFunctionReturn(0);
279aa9c1079SBarry Smith   ierr = PetscCommDestroy(&(*psubcomm)->dupparent);CHKERRQ(ierr);
280306c2d5bSBarry Smith   ierr = PetscCommDestroy(&(*psubcomm)->child);CHKERRQ(ierr);
281e37c6257SHong Zhang   ierr = PetscFree((*psubcomm)->subsize);CHKERRQ(ierr);
282e5acf8a4SHong Zhang   if ((*psubcomm)->subcommprefix) { ierr = PetscFree((*psubcomm)->subcommprefix);CHKERRQ(ierr); }
2836bf464f9SBarry Smith   ierr = PetscFree((*psubcomm));CHKERRQ(ierr);
284cd05a4c0SHong Zhang   PetscFunctionReturn(0);
285cd05a4c0SHong Zhang }
286cd05a4c0SHong Zhang 
287ab8c242fSMatthew Knepley /*@C
288cd05a4c0SHong Zhang   PetscSubcommCreate - Create a PetscSubcomm context.
289cd05a4c0SHong Zhang 
290cd05a4c0SHong Zhang    Collective on MPI_Comm
291cd05a4c0SHong Zhang 
292cd05a4c0SHong Zhang    Input Parameter:
2939873d53eSJed Brown .  comm - MPI communicator
294cd05a4c0SHong Zhang 
295cd05a4c0SHong Zhang    Output Parameter:
296cd05a4c0SHong Zhang .  psubcomm - location to store the PetscSubcomm context
297cd05a4c0SHong Zhang 
298638faf0bSHong Zhang    Level: advanced
299cd05a4c0SHong Zhang 
300638faf0bSHong Zhang .keywords: communicator, create
301638faf0bSHong Zhang 
302638faf0bSHong Zhang .seealso: PetscSubcommDestroy()
303638faf0bSHong Zhang @*/
3047087cfbeSBarry Smith PetscErrorCode  PetscSubcommCreate(MPI_Comm comm,PetscSubcomm *psubcomm)
305638faf0bSHong Zhang {
306638faf0bSHong Zhang   PetscErrorCode ierr;
307d3b23db5SHong Zhang   PetscMPIInt    rank,size;
308638faf0bSHong Zhang 
309638faf0bSHong Zhang   PetscFunctionBegin;
310b00a9115SJed Brown   ierr = PetscNew(psubcomm);CHKERRQ(ierr);
311a297a907SKarl Rupp 
312d3b23db5SHong Zhang   /* set defaults */
313d3b23db5SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
314d3b23db5SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
315f68be91cSHong Zhang 
316d8a68f86SHong Zhang   (*psubcomm)->parent    = comm;
317d3b23db5SHong Zhang   (*psubcomm)->dupparent = comm;
318306c2d5bSBarry Smith   (*psubcomm)->child     = PETSC_COMM_SELF;
319d3b23db5SHong Zhang   (*psubcomm)->n         = size;
320d3b23db5SHong Zhang   (*psubcomm)->color     = rank;
321e37c6257SHong Zhang   (*psubcomm)->subsize   = NULL;
322d3b23db5SHong Zhang   (*psubcomm)->type      = PETSC_SUBCOMM_INTERLACED;
323638faf0bSHong Zhang   PetscFunctionReturn(0);
324638faf0bSHong Zhang }
325638faf0bSHong Zhang 
32695c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm psubcomm)
327638faf0bSHong Zhang {
328638faf0bSHong Zhang   PetscErrorCode ierr;
329d6037b41SHong Zhang   PetscMPIInt    rank,size,*subsize,duprank=-1,subrank=-1;
33045487dadSJed Brown   PetscMPIInt    np_subcomm,nleftover,i,color=-1,rankstart,nsubcomm=psubcomm->n;
331d8a68f86SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
332638faf0bSHong Zhang 
333638faf0bSHong Zhang   PetscFunctionBegin;
33455e3b8d2SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
33555e3b8d2SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
33655e3b8d2SHong Zhang 
337638faf0bSHong Zhang   /* get size of each subcommunicator */
338854ce69bSBarry Smith   ierr = PetscMalloc1(1+nsubcomm,&subsize);CHKERRQ(ierr);
339a297a907SKarl Rupp 
340638faf0bSHong Zhang   np_subcomm = size/nsubcomm;
341638faf0bSHong Zhang   nleftover  = size - nsubcomm*np_subcomm;
342638faf0bSHong Zhang   for (i=0; i<nsubcomm; i++) {
343638faf0bSHong Zhang     subsize[i] = np_subcomm;
344638faf0bSHong Zhang     if (i<nleftover) subsize[i]++;
345638faf0bSHong Zhang   }
346638faf0bSHong Zhang 
347638faf0bSHong Zhang   /* get color and subrank of this proc */
348638faf0bSHong Zhang   rankstart = 0;
349638faf0bSHong Zhang   for (i=0; i<nsubcomm; i++) {
350638faf0bSHong Zhang     if (rank >= rankstart && rank < rankstart+subsize[i]) {
351638faf0bSHong Zhang       color   = i;
352638faf0bSHong Zhang       subrank = rank - rankstart;
353638faf0bSHong Zhang       duprank = rank;
354638faf0bSHong Zhang       break;
355a297a907SKarl Rupp     } else rankstart += subsize[i];
356638faf0bSHong Zhang   }
357638faf0bSHong Zhang 
358638faf0bSHong Zhang   ierr = MPI_Comm_split(comm,color,subrank,&subcomm);CHKERRQ(ierr);
359638faf0bSHong Zhang 
360638faf0bSHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
361638faf0bSHong Zhang   ierr = MPI_Comm_split(comm,0,duprank,&dupcomm);CHKERRQ(ierr);
3620298fd71SBarry Smith   ierr = PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL);CHKERRQ(ierr);
363306c2d5bSBarry Smith   ierr = PetscCommDuplicate(subcomm,&psubcomm->child,NULL);CHKERRQ(ierr);
364b89831e5SBarry Smith   ierr = MPI_Comm_free(&dupcomm);CHKERRQ(ierr);
365b89831e5SBarry Smith   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
366a297a907SKarl Rupp 
367d8a68f86SHong Zhang   psubcomm->color   = color;
368e37c6257SHong Zhang   psubcomm->subsize = subsize;
369f38d543fSHong Zhang   psubcomm->type    = PETSC_SUBCOMM_CONTIGUOUS;
370638faf0bSHong Zhang   PetscFunctionReturn(0);
371638faf0bSHong Zhang }
372638faf0bSHong Zhang 
373638faf0bSHong Zhang /*
374638faf0bSHong Zhang    Note:
375638faf0bSHong Zhang    In PCREDUNDANT, to avoid data scattering from subcomm back to original comm, we create subcommunicators
37645fc02eaSBarry Smith    by iteratively taking a process into a subcommunicator.
377cd05a4c0SHong Zhang    Example: size=4, nsubcomm=(*psubcomm)->n=3
378cd05a4c0SHong Zhang      comm=(*psubcomm)->parent:
379cd05a4c0SHong Zhang       rank:     [0]  [1]  [2]  [3]
380cd05a4c0SHong Zhang       color:     0    1    2    0
381cd05a4c0SHong Zhang 
382cd05a4c0SHong Zhang      subcomm=(*psubcomm)->comm:
383cd05a4c0SHong Zhang       subrank:  [0]  [0]  [0]  [1]
384cd05a4c0SHong Zhang 
385cd05a4c0SHong Zhang      dupcomm=(*psubcomm)->dupparent:
386cd05a4c0SHong Zhang       duprank:  [0]  [2]  [3]  [1]
387cd05a4c0SHong Zhang 
388cd05a4c0SHong Zhang      Here, subcomm[color = 0] has subsize=2, owns process [0] and [3]
389cd05a4c0SHong Zhang            subcomm[color = 1] has subsize=1, owns process [1]
390cd05a4c0SHong Zhang            subcomm[color = 2] has subsize=1, owns process [2]
391cd05a4c0SHong Zhang            dupcomm has same number of processes as comm, and its duprank maps
392cd05a4c0SHong Zhang            processes in subcomm contiguously into a 1d array:
393cd05a4c0SHong Zhang             duprank: [0] [1]      [2]         [3]
394cd05a4c0SHong Zhang             rank:    [0] [3]      [1]         [2]
395cd05a4c0SHong Zhang                     subcomm[0] subcomm[1]  subcomm[2]
396638faf0bSHong Zhang */
397cd05a4c0SHong Zhang 
39895c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm psubcomm)
399cd05a4c0SHong Zhang {
400cd05a4c0SHong Zhang   PetscErrorCode ierr;
401cd05a4c0SHong Zhang   PetscMPIInt    rank,size,*subsize,duprank,subrank;
40245487dadSJed Brown   PetscMPIInt    np_subcomm,nleftover,i,j,color,nsubcomm=psubcomm->n;
403d8a68f86SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
404cd05a4c0SHong Zhang 
405cd05a4c0SHong Zhang   PetscFunctionBegin;
40655e3b8d2SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
40755e3b8d2SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
40855e3b8d2SHong Zhang 
409cd05a4c0SHong Zhang   /* get size of each subcommunicator */
410854ce69bSBarry Smith   ierr = PetscMalloc1(1+nsubcomm,&subsize);CHKERRQ(ierr);
411a297a907SKarl Rupp 
412cd05a4c0SHong Zhang   np_subcomm = size/nsubcomm;
413cd05a4c0SHong Zhang   nleftover  = size - nsubcomm*np_subcomm;
414cd05a4c0SHong Zhang   for (i=0; i<nsubcomm; i++) {
415cd05a4c0SHong Zhang     subsize[i] = np_subcomm;
416cd05a4c0SHong Zhang     if (i<nleftover) subsize[i]++;
417cd05a4c0SHong Zhang   }
418cd05a4c0SHong Zhang 
419cd05a4c0SHong Zhang   /* find color for this proc */
420cd05a4c0SHong Zhang   color   = rank%nsubcomm;
421cd05a4c0SHong Zhang   subrank = rank/nsubcomm;
422cd05a4c0SHong Zhang 
423cd05a4c0SHong Zhang   ierr = MPI_Comm_split(comm,color,subrank,&subcomm);CHKERRQ(ierr);
424cd05a4c0SHong Zhang 
425cd05a4c0SHong Zhang   j = 0; duprank = 0;
426cd05a4c0SHong Zhang   for (i=0; i<nsubcomm; i++) {
427cd05a4c0SHong Zhang     if (j == color) {
428cd05a4c0SHong Zhang       duprank += subrank;
429cd05a4c0SHong Zhang       break;
430cd05a4c0SHong Zhang     }
431cd05a4c0SHong Zhang     duprank += subsize[i]; j++;
432cd05a4c0SHong Zhang   }
433cd05a4c0SHong Zhang 
434cd05a4c0SHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
435cd05a4c0SHong Zhang   ierr = MPI_Comm_split(comm,0,duprank,&dupcomm);CHKERRQ(ierr);
4360298fd71SBarry Smith   ierr = PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL);CHKERRQ(ierr);
437306c2d5bSBarry Smith   ierr = PetscCommDuplicate(subcomm,&psubcomm->child,NULL);CHKERRQ(ierr);
438b89831e5SBarry Smith   ierr = MPI_Comm_free(&dupcomm);CHKERRQ(ierr);
439b89831e5SBarry Smith   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
440a297a907SKarl Rupp 
441d8a68f86SHong Zhang   psubcomm->color   = color;
442e37c6257SHong Zhang   psubcomm->subsize = subsize;
443f38d543fSHong Zhang   psubcomm->type    = PETSC_SUBCOMM_INTERLACED;
444cd05a4c0SHong Zhang   PetscFunctionReturn(0);
445cd05a4c0SHong Zhang }
446638faf0bSHong Zhang 
447638faf0bSHong Zhang 
448