xref: /petsc/src/sys/objects/subcomm.c (revision d083f849a86f1f43e18d534ee43954e2786cb29a)
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) {
560c9e03a2SStefano 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);
1210c9e03a2SStefano Zampini       ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
1220c9e03a2SStefano Zampini       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"  [%d], color %d, sub-size %d, sub-rank %d, duprank %d\n",rank,psubcomm->color,subsize,subrank,duprank);CHKERRQ(ierr);
1230c9e03a2SStefano Zampini       ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
1240c9e03a2SStefano 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 
133*d083f849SBarry Smith    Collective
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 .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetType(),PetscSubcommSetTypeGeneral()
142d8a68f86SHong Zhang @*/
1437087cfbeSBarry Smith PetscErrorCode  PetscSubcommSetNumber(PetscSubcomm psubcomm,PetscInt nsubcomm)
144d8a68f86SHong Zhang {
145d8a68f86SHong Zhang   PetscErrorCode ierr;
146d8a68f86SHong Zhang   MPI_Comm       comm=psubcomm->parent;
14745487dadSJed Brown   PetscMPIInt    msub,size;
148d8a68f86SHong Zhang 
149d8a68f86SHong Zhang   PetscFunctionBegin;
150d8a68f86SHong Zhang   if (!psubcomm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate() first");
151d8a68f86SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
15245487dadSJed Brown   ierr = PetscMPIIntCast(nsubcomm,&msub);CHKERRQ(ierr);
15345487dadSJed 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);
154d8a68f86SHong Zhang 
15545487dadSJed Brown   psubcomm->n = msub;
156d8a68f86SHong Zhang   PetscFunctionReturn(0);
157d8a68f86SHong Zhang }
158d8a68f86SHong Zhang 
159d8a68f86SHong Zhang /*@C
160d8a68f86SHong Zhang   PetscSubcommSetType - Set type of subcommunicators.
161d8a68f86SHong Zhang 
162*d083f849SBarry Smith    Collective
163d8a68f86SHong Zhang 
164d8a68f86SHong Zhang    Input Parameter:
165d8a68f86SHong Zhang +  psubcomm - PetscSubcomm context
1661ba920a7SHong Zhang -  subcommtype - subcommunicator type, PETSC_SUBCOMM_CONTIGUOUS,PETSC_SUBCOMM_INTERLACED
167d8a68f86SHong Zhang 
168d8a68f86SHong Zhang    Level: advanced
169d8a68f86SHong Zhang 
170d8a68f86SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetNumber(),PetscSubcommSetTypeGeneral()
171d8a68f86SHong Zhang @*/
1727c764164SBarry Smith PetscErrorCode  PetscSubcommSetType(PetscSubcomm psubcomm,PetscSubcommType subcommtype)
173d8a68f86SHong Zhang {
174d8a68f86SHong Zhang   PetscErrorCode ierr;
175d8a68f86SHong Zhang 
176d8a68f86SHong Zhang   PetscFunctionBegin;
177d8a68f86SHong Zhang   if (!psubcomm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate()");
17845487dadSJed Brown   if (psubcomm->n < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()",psubcomm->n);
179d8a68f86SHong Zhang 
180d8a68f86SHong Zhang   if (subcommtype == PETSC_SUBCOMM_CONTIGUOUS) {
181d8a68f86SHong Zhang     ierr = PetscSubcommCreate_contiguous(psubcomm);CHKERRQ(ierr);
182d8a68f86SHong Zhang   } else if (subcommtype == PETSC_SUBCOMM_INTERLACED) {
183d8a68f86SHong Zhang     ierr = PetscSubcommCreate_interlaced(psubcomm);CHKERRQ(ierr);
18445487dadSJed Brown   } else SETERRQ1(psubcomm->parent,PETSC_ERR_SUP,"PetscSubcommType %s is not supported yet",PetscSubcommTypes[subcommtype]);
185d8a68f86SHong Zhang   PetscFunctionReturn(0);
186d8a68f86SHong Zhang }
187d8a68f86SHong Zhang 
1881ba920a7SHong Zhang /*@C
18965d9b8f1SHong Zhang   PetscSubcommSetTypeGeneral - Set a PetscSubcomm from user's specifications
1901ba920a7SHong Zhang 
191*d083f849SBarry Smith    Collective
1921ba920a7SHong Zhang 
1931ba920a7SHong Zhang    Input Parameter:
1941ba920a7SHong Zhang +  psubcomm - PetscSubcomm context
1951ba920a7SHong Zhang .  color   - control of subset assignment (nonnegative integer). Processes with the same color are in the same subcommunicator.
19665d9b8f1SHong Zhang -  subrank - rank in the subcommunicator
1971ba920a7SHong Zhang 
1981ba920a7SHong Zhang    Level: advanced
1991ba920a7SHong Zhang 
2001ba920a7SHong Zhang .seealso: PetscSubcommCreate(),PetscSubcommDestroy(),PetscSubcommSetNumber(),PetscSubcommSetType()
2011ba920a7SHong Zhang @*/
20265d9b8f1SHong Zhang PetscErrorCode PetscSubcommSetTypeGeneral(PetscSubcomm psubcomm,PetscMPIInt color,PetscMPIInt subrank)
203d8a68f86SHong Zhang {
2041ba920a7SHong Zhang   PetscErrorCode ierr;
2051ba920a7SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
206c9e2ceb8SHong Zhang   PetscMPIInt    size,icolor,duprank,*recvbuf,sendbuf[3],mysubsize,rank,*subsize;
20745487dadSJed Brown   PetscMPIInt    i,nsubcomm=psubcomm->n;
2081ba920a7SHong Zhang 
209d8a68f86SHong Zhang   PetscFunctionBegin;
2101ba920a7SHong Zhang   if (!psubcomm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"PetscSubcomm is not created. Call PetscSubcommCreate()");
21145487dadSJed Brown   if (nsubcomm < 1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()",nsubcomm);
2121ba920a7SHong Zhang 
2131ba920a7SHong Zhang   ierr = MPI_Comm_split(comm,color,subrank,&subcomm);CHKERRQ(ierr);
2141ba920a7SHong Zhang 
21565d9b8f1SHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
2169abe469cSDmitry 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(). */
2171ba920a7SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
218785e854fSJed Brown   ierr = PetscMalloc1(2*size,&recvbuf);CHKERRQ(ierr);
21965d9b8f1SHong Zhang 
22065d9b8f1SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
221c9e2ceb8SHong Zhang   ierr = MPI_Comm_size(subcomm,&mysubsize);CHKERRQ(ierr);
22265d9b8f1SHong Zhang 
22365d9b8f1SHong Zhang   sendbuf[0] = color;
224c9e2ceb8SHong Zhang   sendbuf[1] = mysubsize;
225c9e2ceb8SHong Zhang   ierr = MPI_Allgather(sendbuf,2,MPI_INT,recvbuf,2,MPI_INT,comm);CHKERRQ(ierr);
22665d9b8f1SHong Zhang 
227eca4a452SHong Zhang   ierr = PetscCalloc1(nsubcomm,&subsize);CHKERRQ(ierr);
2289972d2ceSHong Zhang   for (i=0; i<2*size; i+=2) {
229c9e2ceb8SHong Zhang     subsize[recvbuf[i]] = recvbuf[i+1];
2301ba920a7SHong Zhang   }
23165d9b8f1SHong Zhang   ierr = PetscFree(recvbuf);CHKERRQ(ierr);
23265d9b8f1SHong Zhang 
23365d9b8f1SHong Zhang   duprank = 0;
234c9e2ceb8SHong Zhang   for (icolor=0; icolor<nsubcomm; icolor++) {
23565d9b8f1SHong Zhang     if (icolor != color) { /* not color of this process */
236c9e2ceb8SHong Zhang       duprank += subsize[icolor];
23765d9b8f1SHong Zhang     } else {
23865d9b8f1SHong Zhang       duprank += subrank;
23965d9b8f1SHong Zhang       break;
24065d9b8f1SHong Zhang     }
24165d9b8f1SHong Zhang   }
24265d9b8f1SHong Zhang   ierr = MPI_Comm_split(comm,0,duprank,&dupcomm);CHKERRQ(ierr);
24365d9b8f1SHong Zhang 
2440298fd71SBarry Smith   ierr = PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL);CHKERRQ(ierr);
245306c2d5bSBarry Smith   ierr = PetscCommDuplicate(subcomm,&psubcomm->child,NULL);CHKERRQ(ierr);
246b89831e5SBarry Smith   ierr = MPI_Comm_free(&dupcomm);CHKERRQ(ierr);
247b89831e5SBarry Smith   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
248a297a907SKarl Rupp 
2491ba920a7SHong Zhang   psubcomm->color   = color;
250c9e2ceb8SHong Zhang   psubcomm->subsize = subsize;
251c9e2ceb8SHong Zhang   psubcomm->type    = PETSC_SUBCOMM_GENERAL;
252d8a68f86SHong Zhang   PetscFunctionReturn(0);
253d8a68f86SHong Zhang }
254638faf0bSHong Zhang 
25589587e68SDave May /*@C
25689587e68SDave May   PetscSubcommDestroy - Destroys a PetscSubcomm object
25789587e68SDave May 
25889587e68SDave May    Collective on PetscSubcomm
25989587e68SDave May 
26089587e68SDave May    Input Parameter:
26189587e68SDave May    .  psubcomm - the PetscSubcomm context
26289587e68SDave May 
26389587e68SDave May    Level: advanced
26489587e68SDave May 
26589587e68SDave May .seealso: PetscSubcommCreate(),PetscSubcommSetType()
26689587e68SDave May @*/
2676bf464f9SBarry Smith PetscErrorCode  PetscSubcommDestroy(PetscSubcomm *psubcomm)
268cd05a4c0SHong Zhang {
269cd05a4c0SHong Zhang   PetscErrorCode ierr;
270cd05a4c0SHong Zhang 
271cd05a4c0SHong Zhang   PetscFunctionBegin;
2726bf464f9SBarry Smith   if (!*psubcomm) PetscFunctionReturn(0);
273aa9c1079SBarry Smith   ierr = PetscCommDestroy(&(*psubcomm)->dupparent);CHKERRQ(ierr);
274306c2d5bSBarry Smith   ierr = PetscCommDestroy(&(*psubcomm)->child);CHKERRQ(ierr);
275e37c6257SHong Zhang   ierr = PetscFree((*psubcomm)->subsize);CHKERRQ(ierr);
276e5acf8a4SHong Zhang   if ((*psubcomm)->subcommprefix) { ierr = PetscFree((*psubcomm)->subcommprefix);CHKERRQ(ierr); }
2776bf464f9SBarry Smith   ierr = PetscFree((*psubcomm));CHKERRQ(ierr);
278cd05a4c0SHong Zhang   PetscFunctionReturn(0);
279cd05a4c0SHong Zhang }
280cd05a4c0SHong Zhang 
281ab8c242fSMatthew Knepley /*@C
282cd05a4c0SHong Zhang   PetscSubcommCreate - Create a PetscSubcomm context.
283cd05a4c0SHong Zhang 
284*d083f849SBarry Smith    Collective
285cd05a4c0SHong Zhang 
286cd05a4c0SHong Zhang    Input Parameter:
2879873d53eSJed Brown .  comm - MPI communicator
288cd05a4c0SHong Zhang 
289cd05a4c0SHong Zhang    Output Parameter:
290cd05a4c0SHong Zhang .  psubcomm - location to store the PetscSubcomm context
291cd05a4c0SHong Zhang 
292638faf0bSHong Zhang    Level: advanced
293cd05a4c0SHong Zhang 
294638faf0bSHong Zhang .seealso: PetscSubcommDestroy()
295638faf0bSHong Zhang @*/
2967087cfbeSBarry Smith PetscErrorCode  PetscSubcommCreate(MPI_Comm comm,PetscSubcomm *psubcomm)
297638faf0bSHong Zhang {
298638faf0bSHong Zhang   PetscErrorCode ierr;
299d3b23db5SHong Zhang   PetscMPIInt    rank,size;
300638faf0bSHong Zhang 
301638faf0bSHong Zhang   PetscFunctionBegin;
302b00a9115SJed Brown   ierr = PetscNew(psubcomm);CHKERRQ(ierr);
303a297a907SKarl Rupp 
304d3b23db5SHong Zhang   /* set defaults */
305d3b23db5SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
306d3b23db5SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
307f68be91cSHong Zhang 
308d8a68f86SHong Zhang   (*psubcomm)->parent    = comm;
309d3b23db5SHong Zhang   (*psubcomm)->dupparent = comm;
310306c2d5bSBarry Smith   (*psubcomm)->child     = PETSC_COMM_SELF;
311d3b23db5SHong Zhang   (*psubcomm)->n         = size;
312d3b23db5SHong Zhang   (*psubcomm)->color     = rank;
313e37c6257SHong Zhang   (*psubcomm)->subsize   = NULL;
314d3b23db5SHong Zhang   (*psubcomm)->type      = PETSC_SUBCOMM_INTERLACED;
315638faf0bSHong Zhang   PetscFunctionReturn(0);
316638faf0bSHong Zhang }
317638faf0bSHong Zhang 
31895c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm psubcomm)
319638faf0bSHong Zhang {
320638faf0bSHong Zhang   PetscErrorCode ierr;
321d6037b41SHong Zhang   PetscMPIInt    rank,size,*subsize,duprank=-1,subrank=-1;
32245487dadSJed Brown   PetscMPIInt    np_subcomm,nleftover,i,color=-1,rankstart,nsubcomm=psubcomm->n;
323d8a68f86SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
324638faf0bSHong Zhang 
325638faf0bSHong Zhang   PetscFunctionBegin;
32655e3b8d2SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
32755e3b8d2SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
32855e3b8d2SHong Zhang 
329638faf0bSHong Zhang   /* get size of each subcommunicator */
330854ce69bSBarry Smith   ierr = PetscMalloc1(1+nsubcomm,&subsize);CHKERRQ(ierr);
331a297a907SKarl Rupp 
332638faf0bSHong Zhang   np_subcomm = size/nsubcomm;
333638faf0bSHong Zhang   nleftover  = size - nsubcomm*np_subcomm;
334638faf0bSHong Zhang   for (i=0; i<nsubcomm; i++) {
335638faf0bSHong Zhang     subsize[i] = np_subcomm;
336638faf0bSHong Zhang     if (i<nleftover) subsize[i]++;
337638faf0bSHong Zhang   }
338638faf0bSHong Zhang 
339638faf0bSHong Zhang   /* get color and subrank of this proc */
340638faf0bSHong Zhang   rankstart = 0;
341638faf0bSHong Zhang   for (i=0; i<nsubcomm; i++) {
342638faf0bSHong Zhang     if (rank >= rankstart && rank < rankstart+subsize[i]) {
343638faf0bSHong Zhang       color   = i;
344638faf0bSHong Zhang       subrank = rank - rankstart;
345638faf0bSHong Zhang       duprank = rank;
346638faf0bSHong Zhang       break;
347a297a907SKarl Rupp     } else rankstart += subsize[i];
348638faf0bSHong Zhang   }
349638faf0bSHong Zhang 
350638faf0bSHong Zhang   ierr = MPI_Comm_split(comm,color,subrank,&subcomm);CHKERRQ(ierr);
351638faf0bSHong Zhang 
352638faf0bSHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
353638faf0bSHong Zhang   ierr = MPI_Comm_split(comm,0,duprank,&dupcomm);CHKERRQ(ierr);
3540298fd71SBarry Smith   ierr = PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL);CHKERRQ(ierr);
355306c2d5bSBarry Smith   ierr = PetscCommDuplicate(subcomm,&psubcomm->child,NULL);CHKERRQ(ierr);
356b89831e5SBarry Smith   ierr = MPI_Comm_free(&dupcomm);CHKERRQ(ierr);
357b89831e5SBarry Smith   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
358a297a907SKarl Rupp 
359d8a68f86SHong Zhang   psubcomm->color   = color;
360e37c6257SHong Zhang   psubcomm->subsize = subsize;
361f38d543fSHong Zhang   psubcomm->type    = PETSC_SUBCOMM_CONTIGUOUS;
362638faf0bSHong Zhang   PetscFunctionReturn(0);
363638faf0bSHong Zhang }
364638faf0bSHong Zhang 
365638faf0bSHong Zhang /*
366638faf0bSHong Zhang    Note:
367638faf0bSHong Zhang    In PCREDUNDANT, to avoid data scattering from subcomm back to original comm, we create subcommunicators
36845fc02eaSBarry Smith    by iteratively taking a process into a subcommunicator.
369cd05a4c0SHong Zhang    Example: size=4, nsubcomm=(*psubcomm)->n=3
370cd05a4c0SHong Zhang      comm=(*psubcomm)->parent:
371cd05a4c0SHong Zhang       rank:     [0]  [1]  [2]  [3]
372cd05a4c0SHong Zhang       color:     0    1    2    0
373cd05a4c0SHong Zhang 
374cd05a4c0SHong Zhang      subcomm=(*psubcomm)->comm:
375cd05a4c0SHong Zhang       subrank:  [0]  [0]  [0]  [1]
376cd05a4c0SHong Zhang 
377cd05a4c0SHong Zhang      dupcomm=(*psubcomm)->dupparent:
378cd05a4c0SHong Zhang       duprank:  [0]  [2]  [3]  [1]
379cd05a4c0SHong Zhang 
380cd05a4c0SHong Zhang      Here, subcomm[color = 0] has subsize=2, owns process [0] and [3]
381cd05a4c0SHong Zhang            subcomm[color = 1] has subsize=1, owns process [1]
382cd05a4c0SHong Zhang            subcomm[color = 2] has subsize=1, owns process [2]
383cd05a4c0SHong Zhang            dupcomm has same number of processes as comm, and its duprank maps
384cd05a4c0SHong Zhang            processes in subcomm contiguously into a 1d array:
385cd05a4c0SHong Zhang             duprank: [0] [1]      [2]         [3]
386cd05a4c0SHong Zhang             rank:    [0] [3]      [1]         [2]
387cd05a4c0SHong Zhang                     subcomm[0] subcomm[1]  subcomm[2]
388638faf0bSHong Zhang */
389cd05a4c0SHong Zhang 
39095c0884eSLisandro Dalcin static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm psubcomm)
391cd05a4c0SHong Zhang {
392cd05a4c0SHong Zhang   PetscErrorCode ierr;
393cd05a4c0SHong Zhang   PetscMPIInt    rank,size,*subsize,duprank,subrank;
39445487dadSJed Brown   PetscMPIInt    np_subcomm,nleftover,i,j,color,nsubcomm=psubcomm->n;
395d8a68f86SHong Zhang   MPI_Comm       subcomm=0,dupcomm=0,comm=psubcomm->parent;
396cd05a4c0SHong Zhang 
397cd05a4c0SHong Zhang   PetscFunctionBegin;
39855e3b8d2SHong Zhang   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
39955e3b8d2SHong Zhang   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
40055e3b8d2SHong Zhang 
401cd05a4c0SHong Zhang   /* get size of each subcommunicator */
402854ce69bSBarry Smith   ierr = PetscMalloc1(1+nsubcomm,&subsize);CHKERRQ(ierr);
403a297a907SKarl Rupp 
404cd05a4c0SHong Zhang   np_subcomm = size/nsubcomm;
405cd05a4c0SHong Zhang   nleftover  = size - nsubcomm*np_subcomm;
406cd05a4c0SHong Zhang   for (i=0; i<nsubcomm; i++) {
407cd05a4c0SHong Zhang     subsize[i] = np_subcomm;
408cd05a4c0SHong Zhang     if (i<nleftover) subsize[i]++;
409cd05a4c0SHong Zhang   }
410cd05a4c0SHong Zhang 
411cd05a4c0SHong Zhang   /* find color for this proc */
412cd05a4c0SHong Zhang   color   = rank%nsubcomm;
413cd05a4c0SHong Zhang   subrank = rank/nsubcomm;
414cd05a4c0SHong Zhang 
415cd05a4c0SHong Zhang   ierr = MPI_Comm_split(comm,color,subrank,&subcomm);CHKERRQ(ierr);
416cd05a4c0SHong Zhang 
417cd05a4c0SHong Zhang   j = 0; duprank = 0;
418cd05a4c0SHong Zhang   for (i=0; i<nsubcomm; i++) {
419cd05a4c0SHong Zhang     if (j == color) {
420cd05a4c0SHong Zhang       duprank += subrank;
421cd05a4c0SHong Zhang       break;
422cd05a4c0SHong Zhang     }
423cd05a4c0SHong Zhang     duprank += subsize[i]; j++;
424cd05a4c0SHong Zhang   }
425cd05a4c0SHong Zhang 
426cd05a4c0SHong Zhang   /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */
427cd05a4c0SHong Zhang   ierr = MPI_Comm_split(comm,0,duprank,&dupcomm);CHKERRQ(ierr);
4280298fd71SBarry Smith   ierr = PetscCommDuplicate(dupcomm,&psubcomm->dupparent,NULL);CHKERRQ(ierr);
429306c2d5bSBarry Smith   ierr = PetscCommDuplicate(subcomm,&psubcomm->child,NULL);CHKERRQ(ierr);
430b89831e5SBarry Smith   ierr = MPI_Comm_free(&dupcomm);CHKERRQ(ierr);
431b89831e5SBarry Smith   ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr);
432a297a907SKarl Rupp 
433d8a68f86SHong Zhang   psubcomm->color   = color;
434e37c6257SHong Zhang   psubcomm->subsize = subsize;
435f38d543fSHong Zhang   psubcomm->type    = PETSC_SUBCOMM_INTERLACED;
436cd05a4c0SHong Zhang   PetscFunctionReturn(0);
437cd05a4c0SHong Zhang }
438638faf0bSHong Zhang 
439638faf0bSHong Zhang 
440