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 @*/ 24*9371c9d4SSatish Balay PetscErrorCode PetscSubcommSetFromOptions(PetscSubcomm psubcomm) { 2545487dadSJed Brown PetscSubcommType type; 26f68be91cSHong Zhang PetscBool flg; 27f68be91cSHong Zhang 28f68be91cSHong Zhang PetscFunctionBegin; 2928b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Must call PetscSubcommCreate firt"); 3060f5f21cSHong Zhang 31d0609cedSBarry Smith PetscOptionsBegin(psubcomm->parent, psubcomm->subcommprefix, "Options for PetscSubcomm", NULL); 329566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-psubcomm_type", NULL, NULL, PetscSubcommTypes, (PetscEnum)psubcomm->type, (PetscEnum *)&type, &flg)); 33f68be91cSHong Zhang if (flg && psubcomm->type != type) { 34f68be91cSHong Zhang /* free old structures */ 359566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(psubcomm)->dupparent)); 369566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(psubcomm)->child)); 379566063dSJacob Faibussowitsch PetscCall(PetscFree((psubcomm)->subsize)); 38f68be91cSHong Zhang switch (type) { 39*9371c9d4SSatish Balay case PETSC_SUBCOMM_GENERAL: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Runtime option PETSC_SUBCOMM_GENERAL is not supported, use PetscSubcommSetTypeGeneral()"); 40*9371c9d4SSatish Balay case PETSC_SUBCOMM_CONTIGUOUS: PetscCall(PetscSubcommCreate_contiguous(psubcomm)); break; 41*9371c9d4SSatish Balay case PETSC_SUBCOMM_INTERLACED: PetscCall(PetscSubcommCreate_interlaced(psubcomm)); break; 42*9371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "PetscSubcommType %s is not supported yet", PetscSubcommTypes[type]); 43f68be91cSHong Zhang } 44f68be91cSHong Zhang } 4519171117SHong Zhang 469566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-psubcomm_view", "Triggers display of PetscSubcomm context", "PetscSubcommView", &flg)); 471baa6e33SBarry Smith if (flg) PetscCall(PetscSubcommView(psubcomm, PETSC_VIEWER_STDOUT_(psubcomm->parent))); 48d0609cedSBarry Smith PetscOptionsEnd(); 49f68be91cSHong Zhang PetscFunctionReturn(0); 50f68be91cSHong Zhang } 51d8a68f86SHong Zhang 52e5acf8a4SHong Zhang /*@C 53e5acf8a4SHong Zhang PetscSubcommSetOptionsPrefix - Sets the prefix used for searching for all 54e5acf8a4SHong Zhang PetscSubcomm items in the options database. 55e5acf8a4SHong Zhang 56e5acf8a4SHong Zhang Logically collective on PetscSubcomm. 57e5acf8a4SHong Zhang 58e5acf8a4SHong Zhang Level: Intermediate 59e5acf8a4SHong Zhang 60e5acf8a4SHong Zhang Input Parameters: 61e5acf8a4SHong Zhang + psubcomm - PetscSubcomm context 62e5acf8a4SHong Zhang - prefix - the prefix to prepend all PetscSubcomm item names with. 63e5acf8a4SHong Zhang 64e5acf8a4SHong Zhang @*/ 65*9371c9d4SSatish Balay PetscErrorCode PetscSubcommSetOptionsPrefix(PetscSubcomm psubcomm, const char pre[]) { 66e5acf8a4SHong Zhang PetscFunctionBegin; 67e5acf8a4SHong Zhang if (!pre) { 689566063dSJacob Faibussowitsch PetscCall(PetscFree(psubcomm->subcommprefix)); 69e5acf8a4SHong Zhang } else { 70cc73adaaSBarry Smith PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 719566063dSJacob Faibussowitsch PetscCall(PetscFree(psubcomm->subcommprefix)); 729566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(pre, &(psubcomm->subcommprefix))); 73e5acf8a4SHong Zhang } 74e5acf8a4SHong Zhang PetscFunctionReturn(0); 75e5acf8a4SHong Zhang } 76e5acf8a4SHong Zhang 77e5acf8a4SHong Zhang /*@C 7823072422SBarry Smith PetscSubcommView - Views a PetscSubcomm of values as either ASCII text or a binary file 79e5acf8a4SHong Zhang 80e5acf8a4SHong Zhang Collective on PetscSubcomm 81e5acf8a4SHong Zhang 82d8d19677SJose E. Roman Input Parameters: 83e5acf8a4SHong Zhang + psubcomm - PetscSubcomm context 84e5acf8a4SHong Zhang - viewer - location to view the values 85e5acf8a4SHong Zhang 86e5acf8a4SHong Zhang Level: beginner 87e5acf8a4SHong Zhang @*/ 88*9371c9d4SSatish Balay PetscErrorCode PetscSubcommView(PetscSubcomm psubcomm, PetscViewer viewer) { 89053d1c95SHong Zhang PetscBool iascii; 90053d1c95SHong Zhang PetscViewerFormat format; 91053d1c95SHong Zhang 92053d1c95SHong Zhang PetscFunctionBegin; 939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 94053d1c95SHong Zhang if (iascii) { 959566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 96053d1c95SHong Zhang if (format == PETSC_VIEWER_DEFAULT) { 97053d1c95SHong Zhang MPI_Comm comm = psubcomm->parent; 98053d1c95SHong Zhang PetscMPIInt rank, size, subsize, subrank, duprank; 99053d1c95SHong Zhang 1009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 1019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "PetscSubcomm type %s with total %d MPI processes:\n", PetscSubcommTypes[psubcomm->type], size)); 1029566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(psubcomm->child, &subsize)); 1049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(psubcomm->child, &subrank)); 1059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(psubcomm->dupparent, &duprank)); 1069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 1079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " [%d], color %d, sub-size %d, sub-rank %d, duprank %d\n", rank, psubcomm->color, subsize, subrank, duprank)); 1089566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 1099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 110053d1c95SHong Zhang } 111053d1c95SHong Zhang } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Not supported yet"); 112053d1c95SHong Zhang PetscFunctionReturn(0); 113053d1c95SHong Zhang } 114053d1c95SHong Zhang 115a530d236SBarry Smith /*@ 116d8a68f86SHong Zhang PetscSubcommSetNumber - Set total number of subcommunicators. 117d8a68f86SHong Zhang 118d083f849SBarry Smith Collective 119d8a68f86SHong Zhang 120d8d19677SJose E. Roman Input Parameters: 121d8a68f86SHong Zhang + psubcomm - PetscSubcomm context 122d8a68f86SHong Zhang - nsubcomm - the total number of subcommunicators in psubcomm 123d8a68f86SHong Zhang 124d8a68f86SHong Zhang Level: advanced 125d8a68f86SHong Zhang 126c2e3fba1SPatrick Sanan .seealso: `PetscSubcommCreate()`, `PetscSubcommDestroy()`, `PetscSubcommSetType()`, `PetscSubcommSetTypeGeneral()` 127d8a68f86SHong Zhang @*/ 128*9371c9d4SSatish Balay PetscErrorCode PetscSubcommSetNumber(PetscSubcomm psubcomm, PetscInt nsubcomm) { 129d8a68f86SHong Zhang MPI_Comm comm = psubcomm->parent; 13045487dadSJed Brown PetscMPIInt msub, size; 131d8a68f86SHong Zhang 132d8a68f86SHong Zhang PetscFunctionBegin; 13328b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "PetscSubcomm is not created. Call PetscSubcommCreate() first"); 1349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 1359566063dSJacob Faibussowitsch PetscCall(PetscMPIIntCast(nsubcomm, &msub)); 136cc73adaaSBarry 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); 137d8a68f86SHong Zhang 13845487dadSJed Brown psubcomm->n = msub; 139d8a68f86SHong Zhang PetscFunctionReturn(0); 140d8a68f86SHong Zhang } 141d8a68f86SHong Zhang 142a530d236SBarry Smith /*@ 143d8a68f86SHong Zhang PetscSubcommSetType - Set type of subcommunicators. 144d8a68f86SHong Zhang 145d083f849SBarry Smith Collective 146d8a68f86SHong Zhang 147d8d19677SJose E. Roman Input Parameters: 148d8a68f86SHong Zhang + psubcomm - PetscSubcomm context 1491ba920a7SHong Zhang - subcommtype - subcommunicator type, PETSC_SUBCOMM_CONTIGUOUS,PETSC_SUBCOMM_INTERLACED 150d8a68f86SHong Zhang 151d8a68f86SHong Zhang Level: advanced 152d8a68f86SHong Zhang 153c2e3fba1SPatrick Sanan .seealso: `PetscSubcommCreate()`, `PetscSubcommDestroy()`, `PetscSubcommSetNumber()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommType` 154d8a68f86SHong Zhang @*/ 155*9371c9d4SSatish Balay PetscErrorCode PetscSubcommSetType(PetscSubcomm psubcomm, PetscSubcommType subcommtype) { 156d8a68f86SHong Zhang PetscFunctionBegin; 15728b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "PetscSubcomm is not created. Call PetscSubcommCreate()"); 15808401ef6SPierre Jolivet PetscCheck(psubcomm->n >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()", psubcomm->n); 159d8a68f86SHong Zhang 160d8a68f86SHong Zhang if (subcommtype == PETSC_SUBCOMM_CONTIGUOUS) { 1619566063dSJacob Faibussowitsch PetscCall(PetscSubcommCreate_contiguous(psubcomm)); 162d8a68f86SHong Zhang } else if (subcommtype == PETSC_SUBCOMM_INTERLACED) { 1639566063dSJacob Faibussowitsch PetscCall(PetscSubcommCreate_interlaced(psubcomm)); 16498921bdaSJacob Faibussowitsch } else SETERRQ(psubcomm->parent, PETSC_ERR_SUP, "PetscSubcommType %s is not supported yet", PetscSubcommTypes[subcommtype]); 165d8a68f86SHong Zhang PetscFunctionReturn(0); 166d8a68f86SHong Zhang } 167d8a68f86SHong Zhang 168a530d236SBarry Smith /*@ 16965d9b8f1SHong Zhang PetscSubcommSetTypeGeneral - Set a PetscSubcomm from user's specifications 1701ba920a7SHong Zhang 171d083f849SBarry Smith Collective 1721ba920a7SHong Zhang 173d8d19677SJose E. Roman Input Parameters: 1741ba920a7SHong Zhang + psubcomm - PetscSubcomm context 1751ba920a7SHong Zhang . color - control of subset assignment (nonnegative integer). Processes with the same color are in the same subcommunicator. 17665d9b8f1SHong Zhang - subrank - rank in the subcommunicator 1771ba920a7SHong Zhang 1781ba920a7SHong Zhang Level: advanced 1791ba920a7SHong Zhang 180c2e3fba1SPatrick Sanan .seealso: `PetscSubcommCreate()`, `PetscSubcommDestroy()`, `PetscSubcommSetNumber()`, `PetscSubcommSetType()` 1811ba920a7SHong Zhang @*/ 182*9371c9d4SSatish Balay PetscErrorCode PetscSubcommSetTypeGeneral(PetscSubcomm psubcomm, PetscMPIInt color, PetscMPIInt subrank) { 1831ba920a7SHong Zhang MPI_Comm subcomm = 0, dupcomm = 0, comm = psubcomm->parent; 184c9e2ceb8SHong Zhang PetscMPIInt size, icolor, duprank, *recvbuf, sendbuf[3], mysubsize, rank, *subsize; 18545487dadSJed Brown PetscMPIInt i, nsubcomm = psubcomm->n; 1861ba920a7SHong Zhang 187d8a68f86SHong Zhang PetscFunctionBegin; 18828b400f6SJacob Faibussowitsch PetscCheck(psubcomm, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "PetscSubcomm is not created. Call PetscSubcommCreate()"); 18908401ef6SPierre Jolivet PetscCheck(nsubcomm >= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "number of subcommunicators %d is incorrect. Call PetscSubcommSetNumber()", nsubcomm); 1901ba920a7SHong Zhang 1919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, color, subrank, &subcomm)); 1921ba920a7SHong Zhang 19365d9b8f1SHong Zhang /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */ 1949abe469cSDmitry 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(). */ 1959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 1969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(2 * size, &recvbuf)); 19765d9b8f1SHong Zhang 1989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 1999566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(subcomm, &mysubsize)); 20065d9b8f1SHong Zhang 20165d9b8f1SHong Zhang sendbuf[0] = color; 202c9e2ceb8SHong Zhang sendbuf[1] = mysubsize; 2039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allgather(sendbuf, 2, MPI_INT, recvbuf, 2, MPI_INT, comm)); 20465d9b8f1SHong Zhang 2059566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(nsubcomm, &subsize)); 206*9371c9d4SSatish Balay for (i = 0; i < 2 * size; i += 2) { subsize[recvbuf[i]] = recvbuf[i + 1]; } 2079566063dSJacob Faibussowitsch PetscCall(PetscFree(recvbuf)); 20865d9b8f1SHong Zhang 20965d9b8f1SHong Zhang duprank = 0; 210c9e2ceb8SHong Zhang for (icolor = 0; icolor < nsubcomm; icolor++) { 21165d9b8f1SHong Zhang if (icolor != color) { /* not color of this process */ 212c9e2ceb8SHong Zhang duprank += subsize[icolor]; 21365d9b8f1SHong Zhang } else { 21465d9b8f1SHong Zhang duprank += subrank; 21565d9b8f1SHong Zhang break; 21665d9b8f1SHong Zhang } 21765d9b8f1SHong Zhang } 2189566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, 0, duprank, &dupcomm)); 21965d9b8f1SHong Zhang 2209566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(dupcomm, &psubcomm->dupparent, NULL)); 2219566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(subcomm, &psubcomm->child, NULL)); 2229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&dupcomm)); 2239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&subcomm)); 224a297a907SKarl Rupp 2251ba920a7SHong Zhang psubcomm->color = color; 226c9e2ceb8SHong Zhang psubcomm->subsize = subsize; 227c9e2ceb8SHong Zhang psubcomm->type = PETSC_SUBCOMM_GENERAL; 228d8a68f86SHong Zhang PetscFunctionReturn(0); 229d8a68f86SHong Zhang } 230638faf0bSHong Zhang 231a530d236SBarry Smith /*@ 23289587e68SDave May PetscSubcommDestroy - Destroys a PetscSubcomm object 23389587e68SDave May 23489587e68SDave May Collective on PetscSubcomm 23589587e68SDave May 23689587e68SDave May Input Parameter: 23789587e68SDave May . psubcomm - the PetscSubcomm context 23889587e68SDave May 23989587e68SDave May Level: advanced 24089587e68SDave May 241c2e3fba1SPatrick Sanan .seealso: `PetscSubcommCreate()`, `PetscSubcommSetType()` 24289587e68SDave May @*/ 243*9371c9d4SSatish Balay PetscErrorCode PetscSubcommDestroy(PetscSubcomm *psubcomm) { 244cd05a4c0SHong Zhang PetscFunctionBegin; 2456bf464f9SBarry Smith if (!*psubcomm) PetscFunctionReturn(0); 2469566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(*psubcomm)->dupparent)); 2479566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&(*psubcomm)->child)); 2489566063dSJacob Faibussowitsch PetscCall(PetscFree((*psubcomm)->subsize)); 2499566063dSJacob Faibussowitsch if ((*psubcomm)->subcommprefix) PetscCall(PetscFree((*psubcomm)->subcommprefix)); 2509566063dSJacob Faibussowitsch PetscCall(PetscFree((*psubcomm))); 251cd05a4c0SHong Zhang PetscFunctionReturn(0); 252cd05a4c0SHong Zhang } 253cd05a4c0SHong Zhang 254a530d236SBarry Smith /*@ 255cd05a4c0SHong Zhang PetscSubcommCreate - Create a PetscSubcomm context. 256cd05a4c0SHong Zhang 257d083f849SBarry Smith Collective 258cd05a4c0SHong Zhang 259cd05a4c0SHong Zhang Input Parameter: 2609873d53eSJed Brown . comm - MPI communicator 261cd05a4c0SHong Zhang 262cd05a4c0SHong Zhang Output Parameter: 263cd05a4c0SHong Zhang . psubcomm - location to store the PetscSubcomm context 264cd05a4c0SHong Zhang 265638faf0bSHong Zhang Level: advanced 266cd05a4c0SHong Zhang 267db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 268db781477SPatrick Sanan `PetscSubcommSetNumber()` 269638faf0bSHong Zhang @*/ 270*9371c9d4SSatish Balay PetscErrorCode PetscSubcommCreate(MPI_Comm comm, PetscSubcomm *psubcomm) { 271d3b23db5SHong Zhang PetscMPIInt rank, size; 272638faf0bSHong Zhang 273638faf0bSHong Zhang PetscFunctionBegin; 2749566063dSJacob Faibussowitsch PetscCall(PetscNew(psubcomm)); 275a297a907SKarl Rupp 276d3b23db5SHong Zhang /* set defaults */ 2779566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 2789566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 279f68be91cSHong Zhang 280d8a68f86SHong Zhang (*psubcomm)->parent = comm; 281d3b23db5SHong Zhang (*psubcomm)->dupparent = comm; 282306c2d5bSBarry Smith (*psubcomm)->child = PETSC_COMM_SELF; 283d3b23db5SHong Zhang (*psubcomm)->n = size; 284d3b23db5SHong Zhang (*psubcomm)->color = rank; 285e37c6257SHong Zhang (*psubcomm)->subsize = NULL; 286d3b23db5SHong Zhang (*psubcomm)->type = PETSC_SUBCOMM_INTERLACED; 287638faf0bSHong Zhang PetscFunctionReturn(0); 288638faf0bSHong Zhang } 289638faf0bSHong Zhang 290a530d236SBarry Smith /*@C 291a530d236SBarry Smith PetscSubcommGetParent - Gets the communicator that was used to create the PetscSubcomm 292a530d236SBarry Smith 293a530d236SBarry Smith Collective 294a530d236SBarry Smith 295a530d236SBarry Smith Input Parameter: 296a530d236SBarry Smith . scomm - the PetscSubcomm 297a530d236SBarry Smith 298a530d236SBarry Smith Output Parameter: 299a530d236SBarry Smith . pcomm - location to store the parent communicator 300a530d236SBarry Smith 301a530d236SBarry Smith Level: intermediate 302a530d236SBarry Smith 303db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 304db781477SPatrick Sanan `PetscSubcommSetNumber()`, `PetscSubcommGetChild()`, `PetscSubcommContiguousParent()` 305a530d236SBarry Smith @*/ 306*9371c9d4SSatish Balay PetscErrorCode PetscSubcommGetParent(PetscSubcomm scomm, MPI_Comm *pcomm) { 307a530d236SBarry Smith *pcomm = PetscSubcommParent(scomm); 308a530d236SBarry Smith return 0; 309a530d236SBarry Smith } 310a530d236SBarry Smith 311a530d236SBarry Smith /*@C 312a530d236SBarry Smith PetscSubcommGetContiguousParent - Gets a communicator that that is a duplicate of the parent but has the ranks 313a530d236SBarry Smith reordered by the order they are in the children 314a530d236SBarry Smith 315a530d236SBarry Smith Collective 316a530d236SBarry Smith 317a530d236SBarry Smith Input Parameter: 318a530d236SBarry Smith . scomm - the PetscSubcomm 319a530d236SBarry Smith 320a530d236SBarry Smith Output Parameter: 321a530d236SBarry Smith . pcomm - location to store the parent communicator 322a530d236SBarry Smith 323a530d236SBarry Smith Level: intermediate 324a530d236SBarry Smith 325db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 326db781477SPatrick Sanan `PetscSubcommSetNumber()`, `PetscSubcommGetChild()`, `PetscSubcommContiguousParent()` 327a530d236SBarry Smith @*/ 328*9371c9d4SSatish Balay PetscErrorCode PetscSubcommGetContiguousParent(PetscSubcomm scomm, MPI_Comm *pcomm) { 329a530d236SBarry Smith *pcomm = PetscSubcommContiguousParent(scomm); 330a530d236SBarry Smith return 0; 331a530d236SBarry Smith } 332a530d236SBarry Smith 333a530d236SBarry Smith /*@C 334a530d236SBarry Smith PetscSubcommGetChild - Gets the communicator created by the PetscSubcomm 335a530d236SBarry Smith 336a530d236SBarry Smith Collective 337a530d236SBarry Smith 338a530d236SBarry Smith Input Parameter: 339a530d236SBarry Smith . scomm - the PetscSubcomm 340a530d236SBarry Smith 341a530d236SBarry Smith Output Parameter: 342a530d236SBarry Smith . ccomm - location to store the child communicator 343a530d236SBarry Smith 344a530d236SBarry Smith Level: intermediate 345a530d236SBarry Smith 346db781477SPatrick Sanan .seealso: `PetscSubcommDestroy()`, `PetscSubcommSetTypeGeneral()`, `PetscSubcommSetFromOptions()`, `PetscSubcommSetType()`, 347db781477SPatrick Sanan `PetscSubcommSetNumber()`, `PetscSubcommGetParent()`, `PetscSubcommContiguousParent()` 348a530d236SBarry Smith @*/ 349*9371c9d4SSatish Balay PetscErrorCode PetscSubcommGetChild(PetscSubcomm scomm, MPI_Comm *ccomm) { 350a530d236SBarry Smith *ccomm = PetscSubcommChild(scomm); 351a530d236SBarry Smith return 0; 352a530d236SBarry Smith } 353a530d236SBarry Smith 354*9371c9d4SSatish Balay static PetscErrorCode PetscSubcommCreate_contiguous(PetscSubcomm psubcomm) { 355d6037b41SHong Zhang PetscMPIInt rank, size, *subsize, duprank = -1, subrank = -1; 35645487dadSJed Brown PetscMPIInt np_subcomm, nleftover, i, color = -1, rankstart, nsubcomm = psubcomm->n; 357d8a68f86SHong Zhang MPI_Comm subcomm = 0, dupcomm = 0, comm = psubcomm->parent; 358638faf0bSHong Zhang 359638faf0bSHong Zhang PetscFunctionBegin; 3609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 3619566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 36255e3b8d2SHong Zhang 363638faf0bSHong Zhang /* get size of each subcommunicator */ 3649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1 + nsubcomm, &subsize)); 365a297a907SKarl Rupp 366638faf0bSHong Zhang np_subcomm = size / nsubcomm; 367638faf0bSHong Zhang nleftover = size - nsubcomm * np_subcomm; 368638faf0bSHong Zhang for (i = 0; i < nsubcomm; i++) { 369638faf0bSHong Zhang subsize[i] = np_subcomm; 370638faf0bSHong Zhang if (i < nleftover) subsize[i]++; 371638faf0bSHong Zhang } 372638faf0bSHong Zhang 373638faf0bSHong Zhang /* get color and subrank of this proc */ 374638faf0bSHong Zhang rankstart = 0; 375638faf0bSHong Zhang for (i = 0; i < nsubcomm; i++) { 376638faf0bSHong Zhang if (rank >= rankstart && rank < rankstart + subsize[i]) { 377638faf0bSHong Zhang color = i; 378638faf0bSHong Zhang subrank = rank - rankstart; 379638faf0bSHong Zhang duprank = rank; 380638faf0bSHong Zhang break; 381a297a907SKarl Rupp } else rankstart += subsize[i]; 382638faf0bSHong Zhang } 383638faf0bSHong Zhang 3849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, color, subrank, &subcomm)); 385638faf0bSHong Zhang 386638faf0bSHong Zhang /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */ 3879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, 0, duprank, &dupcomm)); 3889566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(dupcomm, &psubcomm->dupparent, NULL)); 3899566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(subcomm, &psubcomm->child, NULL)); 3909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&dupcomm)); 3919566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&subcomm)); 392a297a907SKarl Rupp 393d8a68f86SHong Zhang psubcomm->color = color; 394e37c6257SHong Zhang psubcomm->subsize = subsize; 395f38d543fSHong Zhang psubcomm->type = PETSC_SUBCOMM_CONTIGUOUS; 396638faf0bSHong Zhang PetscFunctionReturn(0); 397638faf0bSHong Zhang } 398638faf0bSHong Zhang 399638faf0bSHong Zhang /* 400638faf0bSHong Zhang Note: 401638faf0bSHong Zhang In PCREDUNDANT, to avoid data scattering from subcomm back to original comm, we create subcommunicators 40245fc02eaSBarry Smith by iteratively taking a process into a subcommunicator. 403cd05a4c0SHong Zhang Example: size=4, nsubcomm=(*psubcomm)->n=3 404cd05a4c0SHong Zhang comm=(*psubcomm)->parent: 405cd05a4c0SHong Zhang rank: [0] [1] [2] [3] 406cd05a4c0SHong Zhang color: 0 1 2 0 407cd05a4c0SHong Zhang 408cd05a4c0SHong Zhang subcomm=(*psubcomm)->comm: 409cd05a4c0SHong Zhang subrank: [0] [0] [0] [1] 410cd05a4c0SHong Zhang 411cd05a4c0SHong Zhang dupcomm=(*psubcomm)->dupparent: 412cd05a4c0SHong Zhang duprank: [0] [2] [3] [1] 413cd05a4c0SHong Zhang 414cd05a4c0SHong Zhang Here, subcomm[color = 0] has subsize=2, owns process [0] and [3] 415cd05a4c0SHong Zhang subcomm[color = 1] has subsize=1, owns process [1] 416cd05a4c0SHong Zhang subcomm[color = 2] has subsize=1, owns process [2] 417cd05a4c0SHong Zhang dupcomm has same number of processes as comm, and its duprank maps 418cd05a4c0SHong Zhang processes in subcomm contiguously into a 1d array: 419cd05a4c0SHong Zhang duprank: [0] [1] [2] [3] 420cd05a4c0SHong Zhang rank: [0] [3] [1] [2] 421cd05a4c0SHong Zhang subcomm[0] subcomm[1] subcomm[2] 422638faf0bSHong Zhang */ 423cd05a4c0SHong Zhang 424*9371c9d4SSatish Balay static PetscErrorCode PetscSubcommCreate_interlaced(PetscSubcomm psubcomm) { 425cd05a4c0SHong Zhang PetscMPIInt rank, size, *subsize, duprank, subrank; 42645487dadSJed Brown PetscMPIInt np_subcomm, nleftover, i, j, color, nsubcomm = psubcomm->n; 427d8a68f86SHong Zhang MPI_Comm subcomm = 0, dupcomm = 0, comm = psubcomm->parent; 428cd05a4c0SHong Zhang 429cd05a4c0SHong Zhang PetscFunctionBegin; 4309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 4319566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 43255e3b8d2SHong Zhang 433cd05a4c0SHong Zhang /* get size of each subcommunicator */ 4349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(1 + nsubcomm, &subsize)); 435a297a907SKarl Rupp 436cd05a4c0SHong Zhang np_subcomm = size / nsubcomm; 437cd05a4c0SHong Zhang nleftover = size - nsubcomm * np_subcomm; 438cd05a4c0SHong Zhang for (i = 0; i < nsubcomm; i++) { 439cd05a4c0SHong Zhang subsize[i] = np_subcomm; 440cd05a4c0SHong Zhang if (i < nleftover) subsize[i]++; 441cd05a4c0SHong Zhang } 442cd05a4c0SHong Zhang 443cd05a4c0SHong Zhang /* find color for this proc */ 444cd05a4c0SHong Zhang color = rank % nsubcomm; 445cd05a4c0SHong Zhang subrank = rank / nsubcomm; 446cd05a4c0SHong Zhang 4479566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, color, subrank, &subcomm)); 448cd05a4c0SHong Zhang 449*9371c9d4SSatish Balay j = 0; 450*9371c9d4SSatish Balay duprank = 0; 451cd05a4c0SHong Zhang for (i = 0; i < nsubcomm; i++) { 452cd05a4c0SHong Zhang if (j == color) { 453cd05a4c0SHong Zhang duprank += subrank; 454cd05a4c0SHong Zhang break; 455cd05a4c0SHong Zhang } 456*9371c9d4SSatish Balay duprank += subsize[i]; 457*9371c9d4SSatish Balay j++; 458cd05a4c0SHong Zhang } 459cd05a4c0SHong Zhang 460cd05a4c0SHong Zhang /* create dupcomm with same size as comm, but its rank, duprank, maps subcomm's contiguously into dupcomm */ 4619566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_split(comm, 0, duprank, &dupcomm)); 4629566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(dupcomm, &psubcomm->dupparent, NULL)); 4639566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(subcomm, &psubcomm->child, NULL)); 4649566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&dupcomm)); 4659566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_free(&subcomm)); 466a297a907SKarl Rupp 467d8a68f86SHong Zhang psubcomm->color = color; 468e37c6257SHong Zhang psubcomm->subsize = subsize; 469f38d543fSHong Zhang psubcomm->type = PETSC_SUBCOMM_INTERLACED; 470cd05a4c0SHong Zhang PetscFunctionReturn(0); 471cd05a4c0SHong Zhang } 472