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 /*@ 14*811af0c4SBarry Smith PetscSubcommSetFromOptions - Allows setting options for a `PetscSubcomm` 15e5acf8a4SHong Zhang 16*811af0c4SBarry Smith Collective on psubcomm 17e5acf8a4SHong Zhang 18e5acf8a4SHong Zhang Input Parameter: 19*811af0c4SBarry Smith . psubcomm - `PetscSubcomm` context 20e5acf8a4SHong Zhang 21e5acf8a4SHong Zhang Level: beginner 22e5acf8a4SHong Zhang 23*811af0c4SBarry Smith .seealso: `PetscSubcomm`, `PetscSubcommCreate()` 24e5acf8a4SHong Zhang @*/ 259371c9d4SSatish Balay PetscErrorCode PetscSubcommSetFromOptions(PetscSubcomm psubcomm) { 2645487dadSJed Brown PetscSubcommType type; 27f68be91cSHong Zhang PetscBool flg; 28f68be91cSHong Zhang 29f68be91cSHong Zhang PetscFunctionBegin; 3028b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Must call PetscSubcommCreate firt"); 3160f5f21cSHong Zhang 32d0609cedSBarry Smith PetscOptionsBegin(psubcomm->parent, psubcomm->subcommprefix, "Options for PetscSubcomm", NULL); 339566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-psubcomm_type", NULL, NULL, PetscSubcommTypes, (PetscEnum)psubcomm->type, (PetscEnum *)&type, &flg)); 34f68be91cSHong Zhang if (flg && psubcomm->type != type) { 35f68be91cSHong Zhang /* free old structures */ 369566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(psubcomm)->dupparent)); 379566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(psubcomm)->child)); 389566063dSJacob Faibussowitsch PetscCall(PetscFree((psubcomm)->subsize)); 39f68be91cSHong Zhang switch (type) { 409371c9d4SSatish Balay case PETSC_SUBCOMM_GENERAL: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Runtime option PETSC_SUBCOMM_GENERAL is not supported, use PetscSubcommSetTypeGeneral()"); 419371c9d4SSatish Balay case PETSC_SUBCOMM_CONTIGUOUS: PetscCall(PetscSubcommCreate_contiguous(psubcomm)); break; 429371c9d4SSatish Balay case PETSC_SUBCOMM_INTERLACED: PetscCall(PetscSubcommCreate_interlaced(psubcomm)); break; 439371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscSubcommType %s is not supported yet", PetscSubcommTypes[type]); 44f68be91cSHong Zhang } 45f68be91cSHong Zhang } 4619171117SHong Zhang 479566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-psubcomm_view", "Triggers display of PetscSubcomm context", "PetscSubcommView", &flg)); 481baa6e33SBarry Smith if (flg) PetscCall(PetscSubcommView(psubcomm, PETSC_VIEWER_STDOUT_(psubcomm->parent))); 49d0609cedSBarry Smith PetscOptionsEnd(); 50f68be91cSHong Zhang PetscFunctionReturn(0); 51f68be91cSHong Zhang } 52d8a68f86SHong Zhang 53e5acf8a4SHong Zhang /*@C 54*811af0c4SBarry Smith PetscSubcommSetOptionsPrefix - Sets the prefix used for searching for options in the options database for this object 55e5acf8a4SHong Zhang 56*811af0c4SBarry Smith Logically collective on psubcomm 57e5acf8a4SHong Zhang 58e5acf8a4SHong Zhang Level: Intermediate 59e5acf8a4SHong Zhang 60e5acf8a4SHong Zhang Input Parameters: 61*811af0c4SBarry Smith + psubcomm - `PetscSubcomm` context 62e5acf8a4SHong Zhang - prefix - the prefix to prepend all PetscSubcomm item names with. 63e5acf8a4SHong Zhang 64*811af0c4SBarry Smith .seealso: `PetscSubcomm`, `PetscSubcommCreate()` 65e5acf8a4SHong Zhang @*/ 669371c9d4SSatish Balay PetscErrorCode PetscSubcommSetOptionsPrefix(PetscSubcomm psubcomm, const char pre[]) { 67e5acf8a4SHong Zhang PetscFunctionBegin; 68e5acf8a4SHong Zhang if (!pre) { 699566063dSJacob Faibussowitsch PetscCall(PetscFree(psubcomm->subcommprefix)); 70e5acf8a4SHong Zhang } else { 71cc73adaaSBarry Smith PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 729566063dSJacob Faibussowitsch PetscCall(PetscFree(psubcomm->subcommprefix)); 739566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(pre, &(psubcomm->subcommprefix))); 74e5acf8a4SHong Zhang } 75e5acf8a4SHong Zhang PetscFunctionReturn(0); 76e5acf8a4SHong Zhang } 77e5acf8a4SHong Zhang 78e5acf8a4SHong Zhang /*@C 79*811af0c4SBarry Smith PetscSubcommView - Views a `PetscSubcomm` 80e5acf8a4SHong Zhang 81*811af0c4SBarry Smith Collective on psubcomm 82e5acf8a4SHong Zhang 83d8d19677SJose E. Roman Input Parameters: 84*811af0c4SBarry Smith + psubcomm - `PetscSubcomm` context 85*811af0c4SBarry Smith - viewer - `PetscViewer` to display the information 86e5acf8a4SHong Zhang 87e5acf8a4SHong Zhang Level: beginner 88*811af0c4SBarry Smith 89*811af0c4SBarry Smith .seealso: `PetscSubcomm`, `PetscSubcommCreate()`, `PetscViewer` 90e5acf8a4SHong Zhang @*/ 919371c9d4SSatish Balay PetscErrorCode PetscSubcommView(PetscSubcomm psubcomm, PetscViewer viewer) { 92053d1c95SHong Zhang PetscBool iascii; 93053d1c95SHong Zhang PetscViewerFormat format; 94053d1c95SHong Zhang 95053d1c95SHong Zhang PetscFunctionBegin; 969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 97053d1c95SHong Zhang if (iascii) { 989566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 99053d1c95SHong Zhang if (format == PETSC_VIEWER_DEFAULT) { 100053d1c95SHong Zhang MPI_Comm comm = psubcomm->parent; 101053d1c95SHong Zhang PetscMPIInt rank, size, subsize, subrank, duprank; 102053d1c95SHong Zhang 1039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 1049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "PetscSubcomm type %s with total %d MPI processes:\n", PetscSubcommTypes[psubcomm->type], size)); 1059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(psubcomm->child, &subsize)); 1079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(psubcomm->child, &subrank)); 1089566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(psubcomm->dupparent, &duprank)); 1099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 1109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " [%d], color %d, sub-size %d, sub-rank %d, duprank %d\n", rank, psubcomm->color, subsize, subrank, duprank)); 1119566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 1129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 113053d1c95SHong Zhang } 114053d1c95SHong Zhang } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not supported yet"); 115053d1c95SHong Zhang PetscFunctionReturn(0); 116053d1c95SHong Zhang } 117053d1c95SHong Zhang 118a530d236SBarry Smith /*@ 119*811af0c4SBarry Smith PetscSubcommSetNumber - Set total number of subcommunicators desired in the given `PetscSubcomm` 120d8a68f86SHong Zhang 121d083f849SBarry Smith Collective 122d8a68f86SHong Zhang 123d8d19677SJose E. Roman Input Parameters: 124*811af0c4SBarry Smith + psubcomm - `PetscSubcomm` context 125d8a68f86SHong Zhang - nsubcomm - the total number of subcommunicators in psubcomm 126d8a68f86SHong Zhang 127d8a68f86SHong Zhang Level: advanced 128d8a68f86SHong Zhang 129*811af0c4SBarry Smith .seealso: `PetscSubcomm`, `PetscSubcommCreate()`, `PetscSubcommDestroy()`, `PetscSubcommSetType()`, `PetscSubcommSetTypeGeneral()` 130d8a68f86SHong Zhang @*/ 1319371c9d4SSatish Balay PetscErrorCode PetscSubcommSetNumber(PetscSubcomm psubcomm, PetscInt nsubcomm) { 132d8a68f86SHong Zhang MPI_Comm comm = psubcomm->parent; 13345487dadSJed Brown PetscMPIInt msub, size; 134d8a68f86SHong Zhang 135d8a68f86SHong Zhang PetscFunctionBegin; 13628b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "PetscSubcomm is not created. Call PetscSubcommCreate() first"); 1379566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 1389566063dSJacob Faibussowitsch PetscCall(PetscMPIIntCast(nsubcomm, &msub)); 139cc73adaaSBarry Smith PetscCheck(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); 140d8a68f86SHong Zhang 14145487dadSJed Brown psubcomm->n = msub; 142d8a68f86SHong Zhang PetscFunctionReturn(0); 143d8a68f86SHong Zhang } 144d8a68f86SHong Zhang 145a530d236SBarry Smith /*@ 146*811af0c4SBarry Smith PetscSubcommSetType - Set the way the original MPI communicator is divided up in the `PetscSubcomm` 147d8a68f86SHong Zhang 148d083f849SBarry Smith Collective 149d8a68f86SHong Zhang 150d8d19677SJose E. Roman Input Parameters: 151*811af0c4SBarry Smith + psubcomm - `PetscSubcomm` context 152*811af0c4SBarry Smith - subcommtype - `PetscSubcommType` `PETSC_SUBCOMM_CONTIGUOUS` or `PETSC_SUBCOMM_INTERLACED` 153d8a68f86SHong Zhang 154d8a68f86SHong Zhang Level: advanced 155d8a68f86SHong Zhang 156*811af0c4SBarry Smith .seealso: `PetscSubcommType`, `PETSC_SUBCOMM_CONTIGUOUS`, `PETSC_SUBCOMM_INTERLACED`, 157*811af0c4SBarry Smith `PetscSubcommCreate()`, `PetscSubcommDestroy()`, `PetscSubcommSetNumber()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommType` 158d8a68f86SHong Zhang @*/ 1599371c9d4SSatish Balay PetscErrorCode PetscSubcommSetType(PetscSubcomm psubcomm, PetscSubcommType subcommtype) { 160d8a68f86SHong Zhang PetscFunctionBegin; 16128b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "PetscSubcomm is not created. Call PetscSubcommCreate()"); 16208401ef6SPierre Jolivet PetscCheck(psubcomm->n >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()", psubcomm->n); 163d8a68f86SHong Zhang 164d8a68f86SHong Zhang if (subcommtype == PETSC_SUBCOMM_CONTIGUOUS) { 1659566063dSJacob Faibussowitsch PetscCall(PetscSubcommCreate_contiguous(psubcomm)); 166d8a68f86SHong Zhang } else if (subcommtype == PETSC_SUBCOMM_INTERLACED) { 1679566063dSJacob Faibussowitsch PetscCall(PetscSubcommCreate_interlaced(psubcomm)); 16898921bdaSJacob Faibussowitsch } else SETERRQ(psubcomm->parent, PETSC_ERR_SUP, "PetscSubcommType %s is not supported yet", PetscSubcommTypes[subcommtype]); 169d8a68f86SHong Zhang PetscFunctionReturn(0); 170d8a68f86SHong Zhang } 171d8a68f86SHong Zhang 172a530d236SBarry Smith /*@ 173*811af0c4SBarry Smith PetscSubcommSetTypeGeneral - Divides up a communicator based on a specific user's specification 1741ba920a7SHong Zhang 175d083f849SBarry Smith Collective 1761ba920a7SHong Zhang 177d8d19677SJose E. Roman Input Parameters: 178*811af0c4SBarry Smith + psubcomm - `PetscSubcomm` context 1791ba920a7SHong Zhang . color - control of subset assignment (nonnegative integer). Processes with the same color are in the same subcommunicator. 18065d9b8f1SHong Zhang - subrank - rank in the subcommunicator 1811ba920a7SHong Zhang 1821ba920a7SHong Zhang Level: advanced 1831ba920a7SHong Zhang 184*811af0c4SBarry Smith .seealso: `PetscSubcommType`, `PETSC_SUBCOMM_CONTIGUOUS`, `PETSC_SUBCOMM_INTERLACED`, `PetscSubcommCreate()`, `PetscSubcommDestroy()`, `PetscSubcommSetNumber()`, `PetscSubcommSetType()` 1851ba920a7SHong Zhang @*/ 1869371c9d4SSatish Balay PetscErrorCode PetscSubcommSetTypeGeneral(PetscSubcomm psubcomm, PetscMPIInt color, PetscMPIInt subrank) { 1871ba920a7SHong Zhang MPI_Comm subcomm = 0, dupcomm = 0, comm = psubcomm->parent; 188c9e2ceb8SHong Zhang PetscMPIInt size, icolor, duprank, *recvbuf, sendbuf[3], mysubsize, rank, *subsize; 18945487dadSJed Brown PetscMPIInt i, nsubcomm = psubcomm->n; 1901ba920a7SHong Zhang 191d8a68f86SHong Zhang PetscFunctionBegin; 19228b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "PetscSubcomm is not created. Call PetscSubcommCreate()"); 19308401ef6SPierre Jolivet PetscCheck(nsubcomm >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()", nsubcomm); 1941ba920a7SHong Zhang 1959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, color, subrank, &subcomm)); 1961ba920a7SHong Zhang 19765d9b8f1SHong Zhang /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */ 1989abe469cSDmitry 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(). */ 1999566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 2009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(2 * size, &recvbuf)); 20165d9b8f1SHong Zhang 2029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 2039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(subcomm, &mysubsize)); 20465d9b8f1SHong Zhang 20565d9b8f1SHong Zhang sendbuf[0] = color; 206c9e2ceb8SHong Zhang sendbuf[1] = mysubsize; 2079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(sendbuf, 2, MPI_INT, recvbuf, 2, MPI_INT, comm)); 20865d9b8f1SHong Zhang 2099566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nsubcomm, &subsize)); 210ad540459SPierre Jolivet for (i = 0; i < 2 * size; i += 2) subsize[recvbuf[i]] = recvbuf[i + 1]; 2119566063dSJacob Faibussowitsch PetscCall(PetscFree(recvbuf)); 21265d9b8f1SHong Zhang 21365d9b8f1SHong Zhang duprank = 0; 214c9e2ceb8SHong Zhang for (icolor = 0; icolor < nsubcomm; icolor++) { 21565d9b8f1SHong Zhang if (icolor != color) { /* not color of this process */ 216c9e2ceb8SHong Zhang duprank += subsize[icolor]; 21765d9b8f1SHong Zhang } else { 21865d9b8f1SHong Zhang duprank += subrank; 21965d9b8f1SHong Zhang break; 22065d9b8f1SHong Zhang } 22165d9b8f1SHong Zhang } 2229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, 0, duprank, &dupcomm)); 22365d9b8f1SHong Zhang 2249566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(dupcomm, &psubcomm->dupparent, NULL)); 2259566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(subcomm, &psubcomm->child, NULL)); 2269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&dupcomm)); 2279566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&subcomm)); 228a297a907SKarl Rupp 2291ba920a7SHong Zhang psubcomm->color = color; 230c9e2ceb8SHong Zhang psubcomm->subsize = subsize; 231c9e2ceb8SHong Zhang psubcomm->type = PETSC_SUBCOMM_GENERAL; 232d8a68f86SHong Zhang PetscFunctionReturn(0); 233d8a68f86SHong Zhang } 234638faf0bSHong Zhang 235a530d236SBarry Smith /*@ 236*811af0c4SBarry Smith PetscSubcommDestroy - Destroys a `PetscSubcomm` object 23789587e68SDave May 238*811af0c4SBarry Smith Collective on psubcomm 23989587e68SDave May 24089587e68SDave May Input Parameter: 241*811af0c4SBarry Smith . psubcomm - the `PetscSubcomm` context 24289587e68SDave May 24389587e68SDave May Level: advanced 24489587e68SDave May 245c2e3fba1SPatrick Sanan .seealso: `PetscSubcommCreate()`, `PetscSubcommSetType()` 24689587e68SDave May @*/ 2479371c9d4SSatish Balay PetscErrorCode PetscSubcommDestroy(PetscSubcomm *psubcomm) { 248cd05a4c0SHong Zhang PetscFunctionBegin; 2496bf464f9SBarry Smith if (!*psubcomm) PetscFunctionReturn(0); 2509566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(*psubcomm)->dupparent)); 2519566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(*psubcomm)->child)); 2529566063dSJacob Faibussowitsch PetscCall(PetscFree((*psubcomm)->subsize)); 2539566063dSJacob Faibussowitsch if ((*psubcomm)->subcommprefix) PetscCall(PetscFree((*psubcomm)->subcommprefix)); 2549566063dSJacob Faibussowitsch PetscCall(PetscFree((*psubcomm))); 255cd05a4c0SHong Zhang PetscFunctionReturn(0); 256cd05a4c0SHong Zhang } 257cd05a4c0SHong Zhang 258a530d236SBarry Smith /*@ 259*811af0c4SBarry Smith PetscSubcommCreate - Create a `PetscSubcomm` context. This object is used to manage the division of a `MPI_Comm` into subcommunicators 260cd05a4c0SHong Zhang 261d083f849SBarry Smith Collective 262cd05a4c0SHong Zhang 263cd05a4c0SHong Zhang Input Parameter: 2649873d53eSJed Brown . comm - MPI communicator 265cd05a4c0SHong Zhang 266cd05a4c0SHong Zhang Output Parameter: 267*811af0c4SBarry Smith . psubcomm - location to store the `PetscSubcomm` context 268cd05a4c0SHong Zhang 269638faf0bSHong Zhang Level: advanced 270cd05a4c0SHong Zhang 271*811af0c4SBarry Smith .seealso: `PetscSubcomm`, `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 272db781477SPatrick Sanan `PetscSubcommSetNumber()` 273638faf0bSHong Zhang @*/ 2749371c9d4SSatish Balay PetscErrorCode PetscSubcommCreate(MPI_Comm comm, PetscSubcomm *psubcomm) { 275d3b23db5SHong Zhang PetscMPIInt rank, size; 276638faf0bSHong Zhang 277638faf0bSHong Zhang PetscFunctionBegin; 2789566063dSJacob Faibussowitsch PetscCall(PetscNew(psubcomm)); 279a297a907SKarl Rupp 280d3b23db5SHong Zhang /* set defaults */ 2819566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 2829566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 283f68be91cSHong Zhang 284d8a68f86SHong Zhang (*psubcomm)->parent = comm; 285d3b23db5SHong Zhang (*psubcomm)->dupparent = comm; 286306c2d5bSBarry Smith (*psubcomm)->child = PETSC_COMM_SELF; 287d3b23db5SHong Zhang (*psubcomm)->n = size; 288d3b23db5SHong Zhang (*psubcomm)->color = rank; 289e37c6257SHong Zhang (*psubcomm)->subsize = NULL; 290d3b23db5SHong Zhang (*psubcomm)->type = PETSC_SUBCOMM_INTERLACED; 291638faf0bSHong Zhang PetscFunctionReturn(0); 292638faf0bSHong Zhang } 293638faf0bSHong Zhang 294a530d236SBarry Smith /*@C 295*811af0c4SBarry Smith PetscSubcommGetParent - Gets the communicator that was used to create the `PetscSubcomm` 296a530d236SBarry Smith 297a530d236SBarry Smith Collective 298a530d236SBarry Smith 299a530d236SBarry Smith Input Parameter: 300*811af0c4SBarry Smith . scomm - the `PetscSubcomm` 301a530d236SBarry Smith 302a530d236SBarry Smith Output Parameter: 303a530d236SBarry Smith . pcomm - location to store the parent communicator 304a530d236SBarry Smith 305a530d236SBarry Smith Level: intermediate 306a530d236SBarry Smith 307db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 308db781477SPatrick Sanan `PetscSubcommSetNumber()`, `PetscSubcommGetChild()`, `PetscSubcommContiguousParent()` 309a530d236SBarry Smith @*/ 3109371c9d4SSatish Balay PetscErrorCode PetscSubcommGetParent(PetscSubcomm scomm, MPI_Comm *pcomm) { 311a530d236SBarry Smith *pcomm = PetscSubcommParent(scomm); 312a530d236SBarry Smith return 0; 313a530d236SBarry Smith } 314a530d236SBarry Smith 315a530d236SBarry Smith /*@C 316a530d236SBarry Smith PetscSubcommGetContiguousParent - Gets a communicator that that is a duplicate of the parent but has the ranks 317a530d236SBarry Smith reordered by the order they are in the children 318a530d236SBarry Smith 319a530d236SBarry Smith Collective 320a530d236SBarry Smith 321a530d236SBarry Smith Input Parameter: 322*811af0c4SBarry Smith . scomm - the `PetscSubcomm` 323a530d236SBarry Smith 324a530d236SBarry Smith Output Parameter: 325a530d236SBarry Smith . pcomm - location to store the parent communicator 326a530d236SBarry Smith 327a530d236SBarry Smith Level: intermediate 328a530d236SBarry Smith 329db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 330db781477SPatrick Sanan `PetscSubcommSetNumber()`, `PetscSubcommGetChild()`, `PetscSubcommContiguousParent()` 331a530d236SBarry Smith @*/ 3329371c9d4SSatish Balay PetscErrorCode PetscSubcommGetContiguousParent(PetscSubcomm scomm, MPI_Comm *pcomm) { 333a530d236SBarry Smith *pcomm = PetscSubcommContiguousParent(scomm); 334a530d236SBarry Smith return 0; 335a530d236SBarry Smith } 336a530d236SBarry Smith 337a530d236SBarry Smith /*@C 338*811af0c4SBarry Smith PetscSubcommGetChild - Gets the communicator created by the `PetscSubcomm`. This is part of one of the subcommunicators created by the `PetscSubcomm` 339a530d236SBarry Smith 340a530d236SBarry Smith Collective 341a530d236SBarry Smith 342a530d236SBarry Smith Input Parameter: 343*811af0c4SBarry Smith . scomm - the `PetscSubcomm` 344a530d236SBarry Smith 345a530d236SBarry Smith Output Parameter: 346a530d236SBarry Smith . ccomm - location to store the child communicator 347a530d236SBarry Smith 348a530d236SBarry Smith Level: intermediate 349a530d236SBarry Smith 350db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 351db781477SPatrick Sanan `PetscSubcommSetNumber()`, `PetscSubcommGetParent()`, `PetscSubcommContiguousParent()` 352a530d236SBarry Smith @*/ 3539371c9d4SSatish Balay PetscErrorCode PetscSubcommGetChild(PetscSubcomm scomm, MPI_Comm *ccomm) { 354a530d236SBarry Smith *ccomm = PetscSubcommChild(scomm); 355a530d236SBarry Smith return 0; 356a530d236SBarry Smith } 357a530d236SBarry Smith 3589371c9d4SSatish Balay static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm psubcomm) { 359d6037b41SHong Zhang PetscMPIInt rank, size, *subsize, duprank = -1, subrank = -1; 36045487dadSJed Brown PetscMPIInt np_subcomm, nleftover, i, color = -1, rankstart, nsubcomm = psubcomm->n; 361d8a68f86SHong Zhang MPI_Comm subcomm = 0, dupcomm = 0, comm = psubcomm->parent; 362638faf0bSHong Zhang 363638faf0bSHong Zhang PetscFunctionBegin; 3649566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 3659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 36655e3b8d2SHong Zhang 367638faf0bSHong Zhang /* get size of each subcommunicator */ 3689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1 + nsubcomm, &subsize)); 369a297a907SKarl Rupp 370638faf0bSHong Zhang np_subcomm = size / nsubcomm; 371638faf0bSHong Zhang nleftover = size - nsubcomm * np_subcomm; 372638faf0bSHong Zhang for (i = 0; i < nsubcomm; i++) { 373638faf0bSHong Zhang subsize[i] = np_subcomm; 374638faf0bSHong Zhang if (i < nleftover) subsize[i]++; 375638faf0bSHong Zhang } 376638faf0bSHong Zhang 377638faf0bSHong Zhang /* get color and subrank of this proc */ 378638faf0bSHong Zhang rankstart = 0; 379638faf0bSHong Zhang for (i = 0; i < nsubcomm; i++) { 380638faf0bSHong Zhang if (rank >= rankstart && rank < rankstart + subsize[i]) { 381638faf0bSHong Zhang color = i; 382638faf0bSHong Zhang subrank = rank - rankstart; 383638faf0bSHong Zhang duprank = rank; 384638faf0bSHong Zhang break; 385a297a907SKarl Rupp } else rankstart += subsize[i]; 386638faf0bSHong Zhang } 387638faf0bSHong Zhang 3889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, color, subrank, &subcomm)); 389638faf0bSHong Zhang 390638faf0bSHong Zhang /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */ 3919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, 0, duprank, &dupcomm)); 3929566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(dupcomm, &psubcomm->dupparent, NULL)); 3939566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(subcomm, &psubcomm->child, NULL)); 3949566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&dupcomm)); 3959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&subcomm)); 396a297a907SKarl Rupp 397d8a68f86SHong Zhang psubcomm->color = color; 398e37c6257SHong Zhang psubcomm->subsize = subsize; 399f38d543fSHong Zhang psubcomm->type = PETSC_SUBCOMM_CONTIGUOUS; 400638faf0bSHong Zhang PetscFunctionReturn(0); 401638faf0bSHong Zhang } 402638faf0bSHong Zhang 403638faf0bSHong Zhang /* 404638faf0bSHong Zhang Note: 405638faf0bSHong Zhang In PCREDUNDANT, to avoid data scattering from subcomm back to original comm, we create subcommunicators 40645fc02eaSBarry Smith by iteratively taking a process into a subcommunicator. 407cd05a4c0SHong Zhang Example: size=4, nsubcomm=(*psubcomm)->n=3 408cd05a4c0SHong Zhang comm=(*psubcomm)->parent: 409cd05a4c0SHong Zhang rank: [0] [1] [2] [3] 410cd05a4c0SHong Zhang color: 0 1 2 0 411cd05a4c0SHong Zhang 412cd05a4c0SHong Zhang subcomm=(*psubcomm)->comm: 413cd05a4c0SHong Zhang subrank: [0] [0] [0] [1] 414cd05a4c0SHong Zhang 415cd05a4c0SHong Zhang dupcomm=(*psubcomm)->dupparent: 416cd05a4c0SHong Zhang duprank: [0] [2] [3] [1] 417cd05a4c0SHong Zhang 418cd05a4c0SHong Zhang Here, subcomm[color = 0] has subsize=2, owns process [0] and [3] 419cd05a4c0SHong Zhang subcomm[color = 1] has subsize=1, owns process [1] 420cd05a4c0SHong Zhang subcomm[color = 2] has subsize=1, owns process [2] 421cd05a4c0SHong Zhang dupcomm has same number of processes as comm, and its duprank maps 422cd05a4c0SHong Zhang processes in subcomm contiguously into a 1d array: 423cd05a4c0SHong Zhang duprank: [0] [1] [2] [3] 424cd05a4c0SHong Zhang rank: [0] [3] [1] [2] 425cd05a4c0SHong Zhang subcomm[0] subcomm[1] subcomm[2] 426638faf0bSHong Zhang */ 427cd05a4c0SHong Zhang 4289371c9d4SSatish Balay static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm psubcomm) { 429cd05a4c0SHong Zhang PetscMPIInt rank, size, *subsize, duprank, subrank; 43045487dadSJed Brown PetscMPIInt np_subcomm, nleftover, i, j, color, nsubcomm = psubcomm->n; 431d8a68f86SHong Zhang MPI_Comm subcomm = 0, dupcomm = 0, comm = psubcomm->parent; 432cd05a4c0SHong Zhang 433cd05a4c0SHong Zhang PetscFunctionBegin; 4349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 4359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 43655e3b8d2SHong Zhang 437cd05a4c0SHong Zhang /* get size of each subcommunicator */ 4389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1 + nsubcomm, &subsize)); 439a297a907SKarl Rupp 440cd05a4c0SHong Zhang np_subcomm = size / nsubcomm; 441cd05a4c0SHong Zhang nleftover = size - nsubcomm * np_subcomm; 442cd05a4c0SHong Zhang for (i = 0; i < nsubcomm; i++) { 443cd05a4c0SHong Zhang subsize[i] = np_subcomm; 444cd05a4c0SHong Zhang if (i < nleftover) subsize[i]++; 445cd05a4c0SHong Zhang } 446cd05a4c0SHong Zhang 447cd05a4c0SHong Zhang /* find color for this proc */ 448cd05a4c0SHong Zhang color = rank % nsubcomm; 449cd05a4c0SHong Zhang subrank = rank / nsubcomm; 450cd05a4c0SHong Zhang 4519566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, color, subrank, &subcomm)); 452cd05a4c0SHong Zhang 4539371c9d4SSatish Balay j = 0; 4549371c9d4SSatish Balay duprank = 0; 455cd05a4c0SHong Zhang for (i = 0; i < nsubcomm; i++) { 456cd05a4c0SHong Zhang if (j == color) { 457cd05a4c0SHong Zhang duprank += subrank; 458cd05a4c0SHong Zhang break; 459cd05a4c0SHong Zhang } 4609371c9d4SSatish Balay duprank += subsize[i]; 4619371c9d4SSatish Balay j++; 462cd05a4c0SHong Zhang } 463cd05a4c0SHong Zhang 464cd05a4c0SHong Zhang /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */ 4659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, 0, duprank, &dupcomm)); 4669566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(dupcomm, &psubcomm->dupparent, NULL)); 4679566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(subcomm, &psubcomm->child, NULL)); 4689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&dupcomm)); 4699566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&subcomm)); 470a297a907SKarl Rupp 471d8a68f86SHong Zhang psubcomm->color = color; 472e37c6257SHong Zhang psubcomm->subsize = subsize; 473f38d543fSHong Zhang psubcomm->type = PETSC_SUBCOMM_INTERLACED; 474cd05a4c0SHong Zhang PetscFunctionReturn(0); 475cd05a4c0SHong Zhang } 476