18be712e4SBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 28be712e4SBarry Smith 38be712e4SBarry Smith /* Logging support */ 48be712e4SBarry Smith PetscClassId MAT_PARTITIONING_CLASSID; 58be712e4SBarry Smith 68be712e4SBarry Smith /* 78be712e4SBarry Smith Simplest partitioning, keeps the current partitioning. 88be712e4SBarry Smith */ 98be712e4SBarry Smith static PetscErrorCode MatPartitioningApply_Current(MatPartitioning part, IS *partitioning) 108be712e4SBarry Smith { 118be712e4SBarry Smith PetscInt m; 128be712e4SBarry Smith PetscMPIInt rank, size; 138be712e4SBarry Smith 148be712e4SBarry Smith PetscFunctionBegin; 158be712e4SBarry Smith PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)part), &size)); 168be712e4SBarry Smith if (part->n != size) { 178be712e4SBarry Smith const char *prefix; 188be712e4SBarry Smith PetscCall(PetscObjectGetOptionsPrefix((PetscObject)part, &prefix)); 198be712e4SBarry Smith SETERRQ(PetscObjectComm((PetscObject)part), PETSC_ERR_SUP, "This is the DEFAULT NO-OP partitioner, it currently only supports one domain per processor\nuse -%smat_partitioning_type parmetis or chaco or ptscotch for more than one subdomain per processor", prefix ? prefix : ""); 208be712e4SBarry Smith } 218be712e4SBarry Smith PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)part), &rank)); 228be712e4SBarry Smith 238be712e4SBarry Smith PetscCall(MatGetLocalSize(part->adj, &m, NULL)); 248be712e4SBarry Smith PetscCall(ISCreateStride(PetscObjectComm((PetscObject)part), m, rank, 0, partitioning)); 258be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 268be712e4SBarry Smith } 278be712e4SBarry Smith 288be712e4SBarry Smith /* 298be712e4SBarry Smith partition an index to rebalance the computation 308be712e4SBarry Smith */ 318be712e4SBarry Smith static PetscErrorCode MatPartitioningApply_Average(MatPartitioning part, IS *partitioning) 328be712e4SBarry Smith { 338be712e4SBarry Smith PetscInt m, M, nparts, *indices, r, d, *parts, i, start, end, loc; 348be712e4SBarry Smith 358be712e4SBarry Smith PetscFunctionBegin; 368be712e4SBarry Smith PetscCall(MatGetSize(part->adj, &M, NULL)); 378be712e4SBarry Smith PetscCall(MatGetLocalSize(part->adj, &m, NULL)); 388be712e4SBarry Smith nparts = part->n; 398be712e4SBarry Smith PetscCall(PetscMalloc1(nparts, &parts)); 408be712e4SBarry Smith d = M / nparts; 418be712e4SBarry Smith for (i = 0; i < nparts; i++) parts[i] = d; 428be712e4SBarry Smith r = M % nparts; 438be712e4SBarry Smith for (i = 0; i < r; i++) parts[i] += 1; 448be712e4SBarry Smith for (i = 1; i < nparts; i++) parts[i] += parts[i - 1]; 458be712e4SBarry Smith PetscCall(PetscMalloc1(m, &indices)); 468be712e4SBarry Smith PetscCall(MatGetOwnershipRange(part->adj, &start, &end)); 478be712e4SBarry Smith for (i = start; i < end; i++) { 488be712e4SBarry Smith PetscCall(PetscFindInt(i, nparts, parts, &loc)); 498be712e4SBarry Smith if (loc < 0) loc = -(loc + 1); 508be712e4SBarry Smith else loc = loc + 1; 518be712e4SBarry Smith indices[i - start] = loc; 528be712e4SBarry Smith } 538be712e4SBarry Smith PetscCall(PetscFree(parts)); 548be712e4SBarry Smith PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)part), m, indices, PETSC_OWN_POINTER, partitioning)); 558be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 568be712e4SBarry Smith } 578be712e4SBarry Smith 588be712e4SBarry Smith static PetscErrorCode MatPartitioningApply_Square(MatPartitioning part, IS *partitioning) 598be712e4SBarry Smith { 608be712e4SBarry Smith PetscInt cell, n, N, p, rstart, rend, *color; 618be712e4SBarry Smith PetscMPIInt size; 628be712e4SBarry Smith 638be712e4SBarry Smith PetscFunctionBegin; 648be712e4SBarry Smith PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)part), &size)); 658be712e4SBarry Smith PetscCheck(part->n == size, PetscObjectComm((PetscObject)part), PETSC_ERR_SUP, "Currently only supports one domain per processor"); 668be712e4SBarry Smith p = (PetscInt)PetscSqrtReal((PetscReal)part->n); 678be712e4SBarry Smith PetscCheck(p * p == part->n, PetscObjectComm((PetscObject)part), PETSC_ERR_SUP, "Square partitioning requires \"perfect square\" number of domains"); 688be712e4SBarry Smith 698be712e4SBarry Smith PetscCall(MatGetSize(part->adj, &N, NULL)); 708be712e4SBarry Smith n = (PetscInt)PetscSqrtReal((PetscReal)N); 718be712e4SBarry Smith PetscCheck(n * n == N, PetscObjectComm((PetscObject)part), PETSC_ERR_SUP, "Square partitioning requires square domain"); 728be712e4SBarry Smith PetscCheck(n % p == 0, PETSC_COMM_SELF, PETSC_ERR_SUP, "Square partitioning requires p to divide n"); 738be712e4SBarry Smith PetscCall(MatGetOwnershipRange(part->adj, &rstart, &rend)); 748be712e4SBarry Smith PetscCall(PetscMalloc1(rend - rstart, &color)); 758be712e4SBarry Smith /* for (int cell=rstart; cell<rend; cell++) color[cell-rstart] = ((cell%n) < (n/2)) + 2 * ((cell/n) < (n/2)); */ 768be712e4SBarry Smith for (cell = rstart; cell < rend; cell++) color[cell - rstart] = ((cell % n) / (n / p)) + p * ((cell / n) / (n / p)); 778be712e4SBarry Smith PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)part), rend - rstart, color, PETSC_OWN_POINTER, partitioning)); 788be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 798be712e4SBarry Smith } 808be712e4SBarry Smith 818be712e4SBarry Smith PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Current(MatPartitioning part) 828be712e4SBarry Smith { 838be712e4SBarry Smith PetscFunctionBegin; 848be712e4SBarry Smith part->ops->apply = MatPartitioningApply_Current; 858be712e4SBarry Smith part->ops->view = NULL; 868be712e4SBarry Smith part->ops->destroy = NULL; 878be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 888be712e4SBarry Smith } 898be712e4SBarry Smith 908be712e4SBarry Smith PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Average(MatPartitioning part) 918be712e4SBarry Smith { 928be712e4SBarry Smith PetscFunctionBegin; 938be712e4SBarry Smith part->ops->apply = MatPartitioningApply_Average; 948be712e4SBarry Smith part->ops->view = NULL; 958be712e4SBarry Smith part->ops->destroy = NULL; 968be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 978be712e4SBarry Smith } 988be712e4SBarry Smith 998be712e4SBarry Smith PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Square(MatPartitioning part) 1008be712e4SBarry Smith { 1018be712e4SBarry Smith PetscFunctionBegin; 1028be712e4SBarry Smith part->ops->apply = MatPartitioningApply_Square; 1038be712e4SBarry Smith part->ops->view = NULL; 1048be712e4SBarry Smith part->ops->destroy = NULL; 1058be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 1068be712e4SBarry Smith } 1078be712e4SBarry Smith 1088be712e4SBarry Smith /* gets as input the "sizes" array computed by ParMetis_*_NodeND and returns 1098be712e4SBarry Smith seps[ 0 : 2*p) : the start and end node of each subdomain 1108be712e4SBarry Smith seps[2*p : 2*p+2*(p-1)) : the start and end node of each separator 1118be712e4SBarry Smith levels[ 0 : p-1) : level in the tree for each separator (-1 root, -2 and -3 first level and so on) 1128be712e4SBarry Smith The arrays must be large enough 1138be712e4SBarry Smith */ 1148be712e4SBarry Smith PETSC_INTERN PetscErrorCode MatPartitioningSizesToSep_Private(PetscInt p, PetscInt sizes[], PetscInt seps[], PetscInt level[]) 1158be712e4SBarry Smith { 1168be712e4SBarry Smith PetscInt l2p, i, pTree, pStartTree; 1178be712e4SBarry Smith 1188be712e4SBarry Smith PetscFunctionBegin; 1198be712e4SBarry Smith l2p = PetscLog2Real(p); 1208be712e4SBarry Smith PetscCheck(!(l2p - (PetscInt)PetscLog2Real(p)), PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "%" PetscInt_FMT " is not a power of 2", p); 1218be712e4SBarry Smith if (!p) PetscFunctionReturn(PETSC_SUCCESS); 1228be712e4SBarry Smith PetscCall(PetscArrayzero(seps, 2 * p - 2)); 1238be712e4SBarry Smith PetscCall(PetscArrayzero(level, p - 1)); 1248be712e4SBarry Smith seps[2 * p - 2] = sizes[2 * p - 2]; 1258be712e4SBarry Smith pTree = p; 1268be712e4SBarry Smith pStartTree = 0; 1278be712e4SBarry Smith while (pTree != 1) { 1288be712e4SBarry Smith for (i = pStartTree; i < pStartTree + pTree; i++) { 1298be712e4SBarry Smith seps[i] += sizes[i]; 1308be712e4SBarry Smith seps[pStartTree + pTree + (i - pStartTree) / 2] += seps[i]; 1318be712e4SBarry Smith } 1328be712e4SBarry Smith pStartTree += pTree; 1338be712e4SBarry Smith pTree = pTree / 2; 1348be712e4SBarry Smith } 1358be712e4SBarry Smith seps[2 * p - 2] -= sizes[2 * p - 2]; 1368be712e4SBarry Smith 1378be712e4SBarry Smith pStartTree = 2 * p - 2; 1388be712e4SBarry Smith pTree = 1; 1398be712e4SBarry Smith while (pStartTree > 0) { 1408be712e4SBarry Smith for (i = pStartTree; i < pStartTree + pTree; i++) { 1418be712e4SBarry Smith PetscInt k = 2 * i - (pStartTree + 2 * pTree); 1428be712e4SBarry Smith PetscInt n = seps[k + 1]; 1438be712e4SBarry Smith 1448be712e4SBarry Smith seps[k + 1] = seps[i] - sizes[k + 1]; 1458be712e4SBarry Smith seps[k] = seps[k + 1] + sizes[k + 1] - n - sizes[k]; 1468be712e4SBarry Smith level[i - p] = -pTree - i + pStartTree; 1478be712e4SBarry Smith } 1488be712e4SBarry Smith pTree *= 2; 1498be712e4SBarry Smith pStartTree -= pTree; 1508be712e4SBarry Smith } 1518be712e4SBarry Smith /* I know there should be a formula */ 1528be712e4SBarry Smith PetscCall(PetscSortIntWithArrayPair(p - 1, seps + p, sizes + p, level)); 1538be712e4SBarry Smith for (i = 2 * p - 2; i >= 0; i--) { 1548be712e4SBarry Smith seps[2 * i] = seps[i]; 1558be712e4SBarry Smith seps[2 * i + 1] = seps[i] + PetscMax(sizes[i] - 1, 0); 1568be712e4SBarry Smith } 1578be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 1588be712e4SBarry Smith } 1598be712e4SBarry Smith 1608be712e4SBarry Smith PetscFunctionList MatPartitioningList = NULL; 1618be712e4SBarry Smith PetscBool MatPartitioningRegisterAllCalled = PETSC_FALSE; 1628be712e4SBarry Smith 1638be712e4SBarry Smith /*@C 1648be712e4SBarry Smith MatPartitioningRegister - Adds a new sparse matrix partitioning to the matrix package. 1658be712e4SBarry Smith 1668be712e4SBarry Smith Not Collective 1678be712e4SBarry Smith 1688be712e4SBarry Smith Input Parameters: 1698be712e4SBarry Smith + sname - name of partitioning (for example `MATPARTITIONINGCURRENT`) or `MATPARTITIONINGPARMETIS` 1708be712e4SBarry Smith - function - function pointer that creates the partitioning type 1718be712e4SBarry Smith 1728be712e4SBarry Smith Level: developer 1738be712e4SBarry Smith 1748be712e4SBarry Smith Example Usage: 1758be712e4SBarry Smith .vb 1768be712e4SBarry Smith MatPartitioningRegister("my_part", MyPartCreate); 1778be712e4SBarry Smith .ve 1788be712e4SBarry Smith 179a3b724e8SBarry Smith Then, your partitioner can be chosen with the procedural interface via `MatPartitioningSetType(part, "my_part")` or at runtime via the option 180a3b724e8SBarry Smith `-mat_partitioning_type my_part` 1818be712e4SBarry Smith 1828be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningCreate()`, `MatPartitioningRegisterDestroy()`, `MatPartitioningRegisterAll()` 1838be712e4SBarry Smith @*/ 1848be712e4SBarry Smith PetscErrorCode MatPartitioningRegister(const char sname[], PetscErrorCode (*function)(MatPartitioning)) 1858be712e4SBarry Smith { 1868be712e4SBarry Smith PetscFunctionBegin; 1878be712e4SBarry Smith PetscCall(MatInitializePackage()); 1888be712e4SBarry Smith PetscCall(PetscFunctionListAdd(&MatPartitioningList, sname, function)); 1898be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 1908be712e4SBarry Smith } 1918be712e4SBarry Smith 1928be712e4SBarry Smith /*@C 1938be712e4SBarry Smith MatPartitioningGetType - Gets the Partitioning method type and name (as a string) 1948be712e4SBarry Smith from the partitioning context. 1958be712e4SBarry Smith 1968be712e4SBarry Smith Not Collective 1978be712e4SBarry Smith 1988be712e4SBarry Smith Input Parameter: 1998be712e4SBarry Smith . partitioning - the partitioning context 2008be712e4SBarry Smith 2018be712e4SBarry Smith Output Parameter: 2028be712e4SBarry Smith . type - partitioner type 2038be712e4SBarry Smith 2048be712e4SBarry Smith Level: intermediate 2058be712e4SBarry Smith 2068be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningCreate()`, `MatPartitioningRegisterDestroy()`, `MatPartitioningRegisterAll()` 2078be712e4SBarry Smith @*/ 2088be712e4SBarry Smith PetscErrorCode MatPartitioningGetType(MatPartitioning partitioning, MatPartitioningType *type) 2098be712e4SBarry Smith { 2108be712e4SBarry Smith PetscFunctionBegin; 2118be712e4SBarry Smith PetscValidHeaderSpecific(partitioning, MAT_PARTITIONING_CLASSID, 1); 2128be712e4SBarry Smith PetscAssertPointer(type, 2); 2138be712e4SBarry Smith *type = ((PetscObject)partitioning)->type_name; 2148be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 2158be712e4SBarry Smith } 2168be712e4SBarry Smith 2178be712e4SBarry Smith /*@C 2188be712e4SBarry Smith MatPartitioningSetNParts - Set how many partitions need to be created; 2198be712e4SBarry Smith by default this is one per processor. Certain partitioning schemes may 2208be712e4SBarry Smith in fact only support that option. 2218be712e4SBarry Smith 2228be712e4SBarry Smith Collective 2238be712e4SBarry Smith 2248be712e4SBarry Smith Input Parameters: 2258be712e4SBarry Smith + part - the partitioning context 2268be712e4SBarry Smith - n - the number of partitions 2278be712e4SBarry Smith 2288be712e4SBarry Smith Level: intermediate 2298be712e4SBarry Smith 2308be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningApply()` 2318be712e4SBarry Smith @*/ 2328be712e4SBarry Smith PetscErrorCode MatPartitioningSetNParts(MatPartitioning part, PetscInt n) 2338be712e4SBarry Smith { 2348be712e4SBarry Smith PetscFunctionBegin; 2358be712e4SBarry Smith part->n = n; 2368be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 2378be712e4SBarry Smith } 2388be712e4SBarry Smith 2398be712e4SBarry Smith /*@ 2408be712e4SBarry Smith MatPartitioningApplyND - Gets a nested dissection partitioning for a matrix. 2418be712e4SBarry Smith 2428be712e4SBarry Smith Collective 2438be712e4SBarry Smith 2448be712e4SBarry Smith Input Parameter: 2458be712e4SBarry Smith . matp - the matrix partitioning object 2468be712e4SBarry Smith 2478be712e4SBarry Smith Output Parameter: 2488be712e4SBarry Smith . partitioning - the partitioning. For each local node, a positive value indicates the processor 2498be712e4SBarry Smith number the node has been assigned to. Negative x values indicate the separator level -(x+1). 2508be712e4SBarry Smith 2518be712e4SBarry Smith Level: intermediate 2528be712e4SBarry Smith 2538be712e4SBarry Smith Note: 2548be712e4SBarry Smith The user can define additional partitionings; see `MatPartitioningRegister()`. 2558be712e4SBarry Smith 2568be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioningRegister()`, `MatPartitioningCreate()`, 2578be712e4SBarry Smith `MatPartitioningDestroy()`, `MatPartitioningSetAdjacency()`, `ISPartitioningToNumbering()`, 2588be712e4SBarry Smith `ISPartitioningCount()` 2598be712e4SBarry Smith @*/ 2608be712e4SBarry Smith PetscErrorCode MatPartitioningApplyND(MatPartitioning matp, IS *partitioning) 2618be712e4SBarry Smith { 2628be712e4SBarry Smith PetscFunctionBegin; 2638be712e4SBarry Smith PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1); 2648be712e4SBarry Smith PetscAssertPointer(partitioning, 2); 2658be712e4SBarry Smith PetscCheck(matp->adj->assembled, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 2668be712e4SBarry Smith PetscCheck(!matp->adj->factortype, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 2678be712e4SBarry Smith PetscCall(PetscLogEventBegin(MAT_PartitioningND, matp, 0, 0, 0)); 2688be712e4SBarry Smith PetscUseTypeMethod(matp, applynd, partitioning); 2698be712e4SBarry Smith PetscCall(PetscLogEventEnd(MAT_PartitioningND, matp, 0, 0, 0)); 2708be712e4SBarry Smith 2718be712e4SBarry Smith PetscCall(MatPartitioningViewFromOptions(matp, NULL, "-mat_partitioning_view")); 2728be712e4SBarry Smith PetscCall(ISViewFromOptions(*partitioning, NULL, "-mat_partitioning_view")); 2738be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 2748be712e4SBarry Smith } 2758be712e4SBarry Smith 2768be712e4SBarry Smith /*@ 2778be712e4SBarry Smith MatPartitioningApply - Gets a partitioning for the graph represented by a sparse matrix. 2788be712e4SBarry Smith 2798be712e4SBarry Smith Collective 2808be712e4SBarry Smith 2818be712e4SBarry Smith Input Parameter: 2828be712e4SBarry Smith . matp - the matrix partitioning object 2838be712e4SBarry Smith 2848be712e4SBarry Smith Output Parameter: 2858be712e4SBarry Smith . partitioning - the partitioning. For each local node this tells the processor 2868be712e4SBarry Smith number that that node is assigned to. 2878be712e4SBarry Smith 2888be712e4SBarry Smith Options Database Keys: 2898be712e4SBarry Smith + -mat_partitioning_type <type> - set the partitioning package or algorithm to use 2908be712e4SBarry Smith - -mat_partitioning_view - display information about the partitioning object 2918be712e4SBarry Smith 2928be712e4SBarry Smith Level: beginner 2938be712e4SBarry Smith 2948be712e4SBarry Smith The user can define additional partitionings; see `MatPartitioningRegister()`. 2958be712e4SBarry Smith 2968be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningRegister()`, `MatPartitioningCreate()`, 2978be712e4SBarry Smith `MatPartitioningDestroy()`, `MatPartitioningSetAdjacency()`, `ISPartitioningToNumbering()`, 2988be712e4SBarry Smith `ISPartitioningCount()` 2998be712e4SBarry Smith @*/ 3008be712e4SBarry Smith PetscErrorCode MatPartitioningApply(MatPartitioning matp, IS *partitioning) 3018be712e4SBarry Smith { 3028be712e4SBarry Smith PetscBool viewbalance, improve; 3038be712e4SBarry Smith 3048be712e4SBarry Smith PetscFunctionBegin; 3058be712e4SBarry Smith PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1); 3068be712e4SBarry Smith PetscAssertPointer(partitioning, 2); 3078be712e4SBarry Smith PetscCheck(matp->adj->assembled, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3088be712e4SBarry Smith PetscCheck(!matp->adj->factortype, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3098be712e4SBarry Smith PetscCall(PetscLogEventBegin(MAT_Partitioning, matp, 0, 0, 0)); 3108be712e4SBarry Smith PetscUseTypeMethod(matp, apply, partitioning); 3118be712e4SBarry Smith PetscCall(PetscLogEventEnd(MAT_Partitioning, matp, 0, 0, 0)); 3128be712e4SBarry Smith 3138be712e4SBarry Smith PetscCall(MatPartitioningViewFromOptions(matp, NULL, "-mat_partitioning_view")); 3148be712e4SBarry Smith PetscCall(ISViewFromOptions(*partitioning, NULL, "-mat_partitioning_view")); 3158be712e4SBarry Smith 3168be712e4SBarry Smith PetscObjectOptionsBegin((PetscObject)matp); 3178be712e4SBarry Smith viewbalance = PETSC_FALSE; 3188be712e4SBarry Smith PetscCall(PetscOptionsBool("-mat_partitioning_view_imbalance", "Display imbalance information of a partition", NULL, PETSC_FALSE, &viewbalance, NULL)); 3198be712e4SBarry Smith improve = PETSC_FALSE; 3208be712e4SBarry Smith PetscCall(PetscOptionsBool("-mat_partitioning_improve", "Improve the quality of a partition", NULL, PETSC_FALSE, &improve, NULL)); 3218be712e4SBarry Smith PetscOptionsEnd(); 3228be712e4SBarry Smith 3238be712e4SBarry Smith if (improve) PetscCall(MatPartitioningImprove(matp, partitioning)); 3248be712e4SBarry Smith 3258be712e4SBarry Smith if (viewbalance) PetscCall(MatPartitioningViewImbalance(matp, *partitioning)); 3268be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 3278be712e4SBarry Smith } 3288be712e4SBarry Smith 3298be712e4SBarry Smith /*@ 3308be712e4SBarry Smith MatPartitioningImprove - Improves the quality of a given partition. 3318be712e4SBarry Smith 3328be712e4SBarry Smith Collective 3338be712e4SBarry Smith 3348be712e4SBarry Smith Input Parameters: 3358be712e4SBarry Smith + matp - the matrix partitioning object 3368be712e4SBarry Smith - partitioning - the original partitioning. For each local node this tells the processor 3378be712e4SBarry Smith number that that node is assigned to. 3388be712e4SBarry Smith 3398be712e4SBarry Smith Options Database Key: 3408be712e4SBarry Smith . -mat_partitioning_improve - improve the quality of the given partition 3418be712e4SBarry Smith 3428be712e4SBarry Smith Level: beginner 3438be712e4SBarry Smith 3448be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningApply()`, `MatPartitioningCreate()`, 3458be712e4SBarry Smith `MatPartitioningDestroy()`, `MatPartitioningSetAdjacency()`, `ISPartitioningToNumbering()`, 3468be712e4SBarry Smith `ISPartitioningCount()` 3478be712e4SBarry Smith @*/ 3488be712e4SBarry Smith PetscErrorCode MatPartitioningImprove(MatPartitioning matp, IS *partitioning) 3498be712e4SBarry Smith { 3508be712e4SBarry Smith PetscFunctionBegin; 3518be712e4SBarry Smith PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1); 3528be712e4SBarry Smith PetscAssertPointer(partitioning, 2); 3538be712e4SBarry Smith PetscCheck(matp->adj->assembled, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix"); 3548be712e4SBarry Smith PetscCheck(!matp->adj->factortype, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 3558be712e4SBarry Smith PetscCall(PetscLogEventBegin(MAT_Partitioning, matp, 0, 0, 0)); 3568be712e4SBarry Smith PetscTryTypeMethod(matp, improve, partitioning); 3578be712e4SBarry Smith PetscCall(PetscLogEventEnd(MAT_Partitioning, matp, 0, 0, 0)); 3588be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 3598be712e4SBarry Smith } 3608be712e4SBarry Smith 3618be712e4SBarry Smith /*@ 3628be712e4SBarry Smith MatPartitioningViewImbalance - Display partitioning imbalance information. 3638be712e4SBarry Smith 3648be712e4SBarry Smith Collective 3658be712e4SBarry Smith 3668be712e4SBarry Smith Input Parameters: 3678be712e4SBarry Smith + matp - the matrix partitioning object 3688be712e4SBarry Smith - partitioning - the partitioning. For each local node this tells the processor 3698be712e4SBarry Smith number that that node is assigned to. 3708be712e4SBarry Smith 3718be712e4SBarry Smith Options Database Key: 3728be712e4SBarry Smith . -mat_partitioning_view_balance - view the balance information from the last partitioning 3738be712e4SBarry Smith 3748be712e4SBarry Smith Level: beginner 3758be712e4SBarry Smith 3768be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningApply()`, `MatPartitioningView()` 3778be712e4SBarry Smith @*/ 3788be712e4SBarry Smith PetscErrorCode MatPartitioningViewImbalance(MatPartitioning matp, IS partitioning) 3798be712e4SBarry Smith { 3808be712e4SBarry Smith PetscInt nparts, *subdomainsizes, *subdomainsizes_tmp, nlocal, i, maxsub, minsub, avgsub; 3818be712e4SBarry Smith const PetscInt *indices; 3828be712e4SBarry Smith PetscViewer viewer; 3838be712e4SBarry Smith 3848be712e4SBarry Smith PetscFunctionBegin; 3858be712e4SBarry Smith PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1); 3868be712e4SBarry Smith PetscValidHeaderSpecific(partitioning, IS_CLASSID, 2); 3878be712e4SBarry Smith nparts = matp->n; 3888be712e4SBarry Smith PetscCall(PetscCalloc2(nparts, &subdomainsizes, nparts, &subdomainsizes_tmp)); 3898be712e4SBarry Smith PetscCall(ISGetLocalSize(partitioning, &nlocal)); 3908be712e4SBarry Smith PetscCall(ISGetIndices(partitioning, &indices)); 3918be712e4SBarry Smith for (i = 0; i < nlocal; i++) subdomainsizes_tmp[indices[i]] += matp->vertex_weights ? matp->vertex_weights[i] : 1; 3928be712e4SBarry Smith PetscCall(MPIU_Allreduce(subdomainsizes_tmp, subdomainsizes, nparts, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)matp))); 3938be712e4SBarry Smith PetscCall(ISRestoreIndices(partitioning, &indices)); 3948be712e4SBarry Smith minsub = PETSC_MAX_INT, maxsub = PETSC_MIN_INT, avgsub = 0; 3958be712e4SBarry Smith for (i = 0; i < nparts; i++) { 3968be712e4SBarry Smith minsub = PetscMin(minsub, subdomainsizes[i]); 3978be712e4SBarry Smith maxsub = PetscMax(maxsub, subdomainsizes[i]); 3988be712e4SBarry Smith avgsub += subdomainsizes[i]; 3998be712e4SBarry Smith } 4008be712e4SBarry Smith avgsub /= nparts; 4018be712e4SBarry Smith PetscCall(PetscFree2(subdomainsizes, subdomainsizes_tmp)); 4028be712e4SBarry Smith PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)matp), &viewer)); 4038be712e4SBarry Smith PetscCall(MatPartitioningView(matp, viewer)); 4048be712e4SBarry Smith PetscCall(PetscViewerASCIIPrintf(viewer, "Partitioning Imbalance Info: Max %" PetscInt_FMT ", Min %" PetscInt_FMT ", Avg %" PetscInt_FMT ", R %g\n", maxsub, minsub, avgsub, (double)(maxsub / (PetscReal)minsub))); 4058be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 4068be712e4SBarry Smith } 4078be712e4SBarry Smith 4088be712e4SBarry Smith /*@ 4098be712e4SBarry Smith MatPartitioningSetAdjacency - Sets the adjacency graph (matrix) of the thing to be 4108be712e4SBarry Smith partitioned. 4118be712e4SBarry Smith 4128be712e4SBarry Smith Collective 4138be712e4SBarry Smith 4148be712e4SBarry Smith Input Parameters: 4158be712e4SBarry Smith + part - the partitioning context 4168be712e4SBarry Smith - adj - the adjacency matrix, this can be any `MatType` but the natural representation is `MATMPIADJ` 4178be712e4SBarry Smith 4188be712e4SBarry Smith Level: beginner 4198be712e4SBarry Smith 4208be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningCreate()` 4218be712e4SBarry Smith @*/ 4228be712e4SBarry Smith PetscErrorCode MatPartitioningSetAdjacency(MatPartitioning part, Mat adj) 4238be712e4SBarry Smith { 4248be712e4SBarry Smith PetscFunctionBegin; 4258be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 4268be712e4SBarry Smith PetscValidHeaderSpecific(adj, MAT_CLASSID, 2); 4278be712e4SBarry Smith part->adj = adj; 4288be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 4298be712e4SBarry Smith } 4308be712e4SBarry Smith 4318be712e4SBarry Smith /*@ 4328be712e4SBarry Smith MatPartitioningDestroy - Destroys the partitioning context. 4338be712e4SBarry Smith 4348be712e4SBarry Smith Collective 4358be712e4SBarry Smith 4368be712e4SBarry Smith Input Parameter: 4378be712e4SBarry Smith . part - the partitioning context 4388be712e4SBarry Smith 4398be712e4SBarry Smith Level: beginner 4408be712e4SBarry Smith 4418be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningCreate()` 4428be712e4SBarry Smith @*/ 4438be712e4SBarry Smith PetscErrorCode MatPartitioningDestroy(MatPartitioning *part) 4448be712e4SBarry Smith { 4458be712e4SBarry Smith PetscFunctionBegin; 4468be712e4SBarry Smith if (!*part) PetscFunctionReturn(PETSC_SUCCESS); 447f4f49eeaSPierre Jolivet PetscValidHeaderSpecific(*part, MAT_PARTITIONING_CLASSID, 1); 448f4f49eeaSPierre Jolivet if (--((PetscObject)*part)->refct > 0) { 4498be712e4SBarry Smith *part = NULL; 4508be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 4518be712e4SBarry Smith } 4528be712e4SBarry Smith 453213acdd3SPierre Jolivet PetscTryTypeMethod(*part, destroy); 4548be712e4SBarry Smith PetscCall(PetscFree((*part)->vertex_weights)); 4558be712e4SBarry Smith PetscCall(PetscFree((*part)->part_weights)); 4568be712e4SBarry Smith PetscCall(PetscHeaderDestroy(part)); 4578be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 4588be712e4SBarry Smith } 4598be712e4SBarry Smith 4608be712e4SBarry Smith /*@C 4618be712e4SBarry Smith MatPartitioningSetVertexWeights - Sets the weights for vertices for a partitioning. 4628be712e4SBarry Smith 4638be712e4SBarry Smith Logically Collective 4648be712e4SBarry Smith 4658be712e4SBarry Smith Input Parameters: 4668be712e4SBarry Smith + part - the partitioning context 4678be712e4SBarry Smith - weights - the weights, on each process this array must have the same size as the number of local rows times the value passed with `MatPartitioningSetNumberVertexWeights()` or 4688be712e4SBarry Smith 1 if that is not provided 4698be712e4SBarry Smith 4708be712e4SBarry Smith Level: beginner 4718be712e4SBarry Smith 4728be712e4SBarry Smith Notes: 4738be712e4SBarry Smith The array weights is freed by PETSc so the user should not free the array. In C/C++ 4748be712e4SBarry Smith the array must be obtained with a call to `PetscMalloc()`, not malloc(). 4758be712e4SBarry Smith 4768be712e4SBarry Smith The weights may not be used by some partitioners 4778be712e4SBarry Smith 478*f13dfd9eSBarry Smith Fortran Note: 479*f13dfd9eSBarry Smith The array `weights` is copied during this function call. 480*f13dfd9eSBarry Smith 4818be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningSetType()`, `MatPartitioningSetPartitionWeights()`, `MatPartitioningSetNumberVertexWeights()` 4828be712e4SBarry Smith @*/ 4838be712e4SBarry Smith PetscErrorCode MatPartitioningSetVertexWeights(MatPartitioning part, const PetscInt weights[]) 4848be712e4SBarry Smith { 4858be712e4SBarry Smith PetscFunctionBegin; 4868be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 4878be712e4SBarry Smith PetscCall(PetscFree(part->vertex_weights)); 4888be712e4SBarry Smith part->vertex_weights = (PetscInt *)weights; 4898be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 4908be712e4SBarry Smith } 4918be712e4SBarry Smith 4928be712e4SBarry Smith /*@C 4938be712e4SBarry Smith MatPartitioningSetPartitionWeights - Sets the weights for each partition. 4948be712e4SBarry Smith 4958be712e4SBarry Smith Logically Collective 4968be712e4SBarry Smith 4978be712e4SBarry Smith Input Parameters: 4988be712e4SBarry Smith + part - the partitioning context 4998be712e4SBarry Smith - weights - An array of size nparts that is used to specify the fraction of 5008be712e4SBarry Smith vertex weight that should be distributed to each sub-domain for 5018be712e4SBarry Smith the balance constraint. If all of the sub-domains are to be of 5028be712e4SBarry Smith the same size, then each of the nparts elements should be set 5038be712e4SBarry Smith to a value of 1/nparts. Note that the sum of all of the weights 5048be712e4SBarry Smith should be one. 5058be712e4SBarry Smith 5068be712e4SBarry Smith Level: beginner 5078be712e4SBarry Smith 5088be712e4SBarry Smith Note: 5098be712e4SBarry Smith The array weights is freed by PETSc so the user should not free the array. In C/C++ 5108be712e4SBarry Smith the array must be obtained with a call to `PetscMalloc()`, not malloc(). 5118be712e4SBarry Smith 512*f13dfd9eSBarry Smith Fortran Note: 513*f13dfd9eSBarry Smith The array `weights` is copied during this function call. 514*f13dfd9eSBarry Smith 5158be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningSetVertexWeights()`, `MatPartitioningCreate()`, `MatPartitioningSetType()` 5168be712e4SBarry Smith @*/ 5178be712e4SBarry Smith PetscErrorCode MatPartitioningSetPartitionWeights(MatPartitioning part, const PetscReal weights[]) 5188be712e4SBarry Smith { 5198be712e4SBarry Smith PetscFunctionBegin; 5208be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 5218be712e4SBarry Smith PetscCall(PetscFree(part->part_weights)); 5228be712e4SBarry Smith part->part_weights = (PetscReal *)weights; 5238be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 5248be712e4SBarry Smith } 5258be712e4SBarry Smith 5268be712e4SBarry Smith /*@ 5278be712e4SBarry Smith MatPartitioningSetUseEdgeWeights - Set a flag to indicate whether or not to use edge weights. 5288be712e4SBarry Smith 5298be712e4SBarry Smith Logically Collective 5308be712e4SBarry Smith 5318be712e4SBarry Smith Input Parameters: 5328be712e4SBarry Smith + part - the partitioning context 5338be712e4SBarry Smith - use_edge_weights - the flag indicateing whether or not to use edge weights. By default no edge weights will be used, 5348be712e4SBarry Smith that is, use_edge_weights is set to FALSE. If set use_edge_weights to TRUE, users need to make sure legal 5358be712e4SBarry Smith edge weights are stored in an ADJ matrix. 5368be712e4SBarry Smith 5378be712e4SBarry Smith Options Database Key: 5388be712e4SBarry Smith . -mat_partitioning_use_edge_weights - (true or false) 5398be712e4SBarry Smith 5408be712e4SBarry Smith Level: beginner 5418be712e4SBarry Smith 5428be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningSetType()`, `MatPartitioningSetVertexWeights()`, `MatPartitioningSetPartitionWeights()` 5438be712e4SBarry Smith @*/ 5448be712e4SBarry Smith PetscErrorCode MatPartitioningSetUseEdgeWeights(MatPartitioning part, PetscBool use_edge_weights) 5458be712e4SBarry Smith { 5468be712e4SBarry Smith PetscFunctionBegin; 5478be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 5488be712e4SBarry Smith part->use_edge_weights = use_edge_weights; 5498be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 5508be712e4SBarry Smith } 5518be712e4SBarry Smith 5528be712e4SBarry Smith /*@ 5538be712e4SBarry Smith MatPartitioningGetUseEdgeWeights - Get a flag that indicates whether or not to edge weights are used. 5548be712e4SBarry Smith 5558be712e4SBarry Smith Logically Collective 5568be712e4SBarry Smith 5578be712e4SBarry Smith Input Parameter: 5588be712e4SBarry Smith . part - the partitioning context 5598be712e4SBarry Smith 5608be712e4SBarry Smith Output Parameter: 5618be712e4SBarry Smith . use_edge_weights - the flag indicateing whether or not to edge weights are used. 5628be712e4SBarry Smith 5638be712e4SBarry Smith Level: beginner 5648be712e4SBarry Smith 5658be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningSetType()`, `MatPartitioningSetVertexWeights()`, `MatPartitioningSetPartitionWeights()`, 5668be712e4SBarry Smith `MatPartitioningSetUseEdgeWeights` 5678be712e4SBarry Smith @*/ 5688be712e4SBarry Smith PetscErrorCode MatPartitioningGetUseEdgeWeights(MatPartitioning part, PetscBool *use_edge_weights) 5698be712e4SBarry Smith { 5708be712e4SBarry Smith PetscFunctionBegin; 5718be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 5728be712e4SBarry Smith PetscAssertPointer(use_edge_weights, 2); 5738be712e4SBarry Smith *use_edge_weights = part->use_edge_weights; 5748be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 5758be712e4SBarry Smith } 5768be712e4SBarry Smith 5778be712e4SBarry Smith /*@ 5788be712e4SBarry Smith MatPartitioningCreate - Creates a partitioning context. 5798be712e4SBarry Smith 5808be712e4SBarry Smith Collective 5818be712e4SBarry Smith 5828be712e4SBarry Smith Input Parameter: 5838be712e4SBarry Smith . comm - MPI communicator 5848be712e4SBarry Smith 5858be712e4SBarry Smith Output Parameter: 5868be712e4SBarry Smith . newp - location to put the context 5878be712e4SBarry Smith 5888be712e4SBarry Smith Level: beginner 5898be712e4SBarry Smith 5908be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningSetType()`, `MatPartitioningApply()`, `MatPartitioningDestroy()`, 5918be712e4SBarry Smith `MatPartitioningSetAdjacency()` 5928be712e4SBarry Smith @*/ 5938be712e4SBarry Smith PetscErrorCode MatPartitioningCreate(MPI_Comm comm, MatPartitioning *newp) 5948be712e4SBarry Smith { 5958be712e4SBarry Smith MatPartitioning part; 5968be712e4SBarry Smith PetscMPIInt size; 5978be712e4SBarry Smith 5988be712e4SBarry Smith PetscFunctionBegin; 5998be712e4SBarry Smith *newp = NULL; 6008be712e4SBarry Smith 6018be712e4SBarry Smith PetscCall(MatInitializePackage()); 6028be712e4SBarry Smith PetscCall(PetscHeaderCreate(part, MAT_PARTITIONING_CLASSID, "MatPartitioning", "Matrix/graph partitioning", "MatGraphOperations", comm, MatPartitioningDestroy, MatPartitioningView)); 6038be712e4SBarry Smith part->vertex_weights = NULL; 6048be712e4SBarry Smith part->part_weights = NULL; 6058be712e4SBarry Smith part->use_edge_weights = PETSC_FALSE; /* By default we don't use edge weights */ 6068be712e4SBarry Smith 6078be712e4SBarry Smith PetscCallMPI(MPI_Comm_size(comm, &size)); 6088be712e4SBarry Smith part->n = (PetscInt)size; 6098be712e4SBarry Smith part->ncon = 1; 6108be712e4SBarry Smith 6118be712e4SBarry Smith *newp = part; 6128be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 6138be712e4SBarry Smith } 6148be712e4SBarry Smith 6158be712e4SBarry Smith /*@C 6168be712e4SBarry Smith MatPartitioningViewFromOptions - View a partitioning context from the options database 6178be712e4SBarry Smith 6188be712e4SBarry Smith Collective 6198be712e4SBarry Smith 6208be712e4SBarry Smith Input Parameters: 6218be712e4SBarry Smith + A - the partitioning context 6228be712e4SBarry Smith . obj - Optional object that provides the prefix used in the options database check 6238be712e4SBarry Smith - name - command line option 6248be712e4SBarry Smith 6258be712e4SBarry Smith Options Database Key: 6268be712e4SBarry Smith . -mat_partitioning_view [viewertype]:... - the viewer and its options 6278be712e4SBarry Smith 6288be712e4SBarry Smith Level: intermediate 6298be712e4SBarry Smith 6308be712e4SBarry Smith Note: 6318be712e4SBarry Smith .vb 6328be712e4SBarry Smith If no value is provided ascii:stdout is used 6338be712e4SBarry Smith ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 6348be712e4SBarry Smith for example ascii::ascii_info prints just the information about the object not all details 6358be712e4SBarry Smith unless :append is given filename opens in write mode, overwriting what was already there 6368be712e4SBarry Smith binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 6378be712e4SBarry Smith draw[:drawtype[:filename]] for example, draw:tikz, draw:tikz:figure.tex or draw:x 6388be712e4SBarry Smith socket[:port] defaults to the standard output port 6398be712e4SBarry Smith saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 6408be712e4SBarry Smith .ve 6418be712e4SBarry Smith 6428be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningView()`, `PetscObjectViewFromOptions()`, `MatPartitioningCreate()` 6438be712e4SBarry Smith @*/ 6448be712e4SBarry Smith PetscErrorCode MatPartitioningViewFromOptions(MatPartitioning A, PetscObject obj, const char name[]) 6458be712e4SBarry Smith { 6468be712e4SBarry Smith PetscFunctionBegin; 6478be712e4SBarry Smith PetscValidHeaderSpecific(A, MAT_PARTITIONING_CLASSID, 1); 6488be712e4SBarry Smith PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 6498be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 6508be712e4SBarry Smith } 6518be712e4SBarry Smith 6528be712e4SBarry Smith /*@C 6538be712e4SBarry Smith MatPartitioningView - Prints the partitioning data structure. 6548be712e4SBarry Smith 6558be712e4SBarry Smith Collective 6568be712e4SBarry Smith 6578be712e4SBarry Smith Input Parameters: 6588be712e4SBarry Smith + part - the partitioning context 6598be712e4SBarry Smith - viewer - optional visualization context 6608be712e4SBarry Smith 6618be712e4SBarry Smith Level: intermediate 6628be712e4SBarry Smith 6638be712e4SBarry Smith Note: 6648be712e4SBarry Smith The available visualization contexts include 6658be712e4SBarry Smith + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 6668be712e4SBarry Smith - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 6678be712e4SBarry Smith output where only the first processor opens 6688be712e4SBarry Smith the file. All other processors send their 6698be712e4SBarry Smith data to the first processor to print. 6708be712e4SBarry Smith 6718be712e4SBarry Smith The user can open alternative visualization contexts with 6728be712e4SBarry Smith . `PetscViewerASCIIOpen()` - output to a specified file 6738be712e4SBarry Smith 6748be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `PetscViewer`, `PetscViewerASCIIOpen()` 6758be712e4SBarry Smith @*/ 6768be712e4SBarry Smith PetscErrorCode MatPartitioningView(MatPartitioning part, PetscViewer viewer) 6778be712e4SBarry Smith { 6788be712e4SBarry Smith PetscBool iascii; 6798be712e4SBarry Smith 6808be712e4SBarry Smith PetscFunctionBegin; 6818be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 6828be712e4SBarry Smith if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)part), &viewer)); 6838be712e4SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 6848be712e4SBarry Smith PetscCheckSameComm(part, 1, viewer, 2); 6858be712e4SBarry Smith 6868be712e4SBarry Smith PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 6878be712e4SBarry Smith if (iascii) { 6888be712e4SBarry Smith PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)part, viewer)); 6898be712e4SBarry Smith if (part->vertex_weights) PetscCall(PetscViewerASCIIPrintf(viewer, " Using vertex weights\n")); 6908be712e4SBarry Smith } 6918be712e4SBarry Smith PetscCall(PetscViewerASCIIPushTab(viewer)); 6928be712e4SBarry Smith PetscTryTypeMethod(part, view, viewer); 6938be712e4SBarry Smith PetscCall(PetscViewerASCIIPopTab(viewer)); 6948be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 6958be712e4SBarry Smith } 6968be712e4SBarry Smith 6978be712e4SBarry Smith /*@C 6988be712e4SBarry Smith MatPartitioningSetType - Sets the type of partitioner to use 6998be712e4SBarry Smith 7008be712e4SBarry Smith Collective 7018be712e4SBarry Smith 7028be712e4SBarry Smith Input Parameters: 7038be712e4SBarry Smith + part - the partitioning context. 7048be712e4SBarry Smith - type - a known method 7058be712e4SBarry Smith 7068be712e4SBarry Smith Options Database Key: 7078be712e4SBarry Smith . -mat_partitioning_type <type> - (for instance, parmetis), use -help for a list of available methods or see `MatPartitioningType` 7088be712e4SBarry Smith 7098be712e4SBarry Smith Level: intermediate 7108be712e4SBarry Smith 7118be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningApply()`, `MatPartitioningType` 7128be712e4SBarry Smith @*/ 7138be712e4SBarry Smith PetscErrorCode MatPartitioningSetType(MatPartitioning part, MatPartitioningType type) 7148be712e4SBarry Smith { 7158be712e4SBarry Smith PetscBool match; 7168be712e4SBarry Smith PetscErrorCode (*r)(MatPartitioning); 7178be712e4SBarry Smith 7188be712e4SBarry Smith PetscFunctionBegin; 7198be712e4SBarry Smith PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1); 7208be712e4SBarry Smith PetscAssertPointer(type, 2); 7218be712e4SBarry Smith 7228be712e4SBarry Smith PetscCall(PetscObjectTypeCompare((PetscObject)part, type, &match)); 7238be712e4SBarry Smith if (match) PetscFunctionReturn(PETSC_SUCCESS); 7248be712e4SBarry Smith 7258be712e4SBarry Smith PetscTryTypeMethod(part, destroy); 7268be712e4SBarry Smith part->ops->destroy = NULL; 7278be712e4SBarry Smith 7288be712e4SBarry Smith part->setupcalled = 0; 7298be712e4SBarry Smith part->data = NULL; 7308be712e4SBarry Smith PetscCall(PetscMemzero(part->ops, sizeof(struct _MatPartitioningOps))); 7318be712e4SBarry Smith 7328be712e4SBarry Smith PetscCall(PetscFunctionListFind(MatPartitioningList, type, &r)); 7338be712e4SBarry Smith PetscCheck(r, PetscObjectComm((PetscObject)part), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown partitioning type %s", type); 7348be712e4SBarry Smith 7358be712e4SBarry Smith PetscCall((*r)(part)); 7368be712e4SBarry Smith 7378be712e4SBarry Smith PetscCall(PetscFree(((PetscObject)part)->type_name)); 7388be712e4SBarry Smith PetscCall(PetscStrallocpy(type, &((PetscObject)part)->type_name)); 7398be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 7408be712e4SBarry Smith } 7418be712e4SBarry Smith 7428be712e4SBarry Smith /*@ 7438be712e4SBarry Smith MatPartitioningSetFromOptions - Sets various partitioning options from the 7448be712e4SBarry Smith options database for the partitioning object 7458be712e4SBarry Smith 7468be712e4SBarry Smith Collective 7478be712e4SBarry Smith 7488be712e4SBarry Smith Input Parameter: 7498be712e4SBarry Smith . part - the partitioning context. 7508be712e4SBarry Smith 7518be712e4SBarry Smith Options Database Keys: 7528be712e4SBarry Smith + -mat_partitioning_type <type> - (for instance, parmetis), use -help for a list of available methods 7538be712e4SBarry Smith - -mat_partitioning_nparts - number of subgraphs 7548be712e4SBarry Smith 7558be712e4SBarry Smith Level: beginner 7568be712e4SBarry Smith 7578be712e4SBarry Smith Note: 7588be712e4SBarry Smith If the partitioner has not been set by the user it uses one of the installed partitioner such as ParMetis. If there are 7598be712e4SBarry Smith no installed partitioners it does no repartioning. 7608be712e4SBarry Smith 7618be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning` 7628be712e4SBarry Smith @*/ 7638be712e4SBarry Smith PetscErrorCode MatPartitioningSetFromOptions(MatPartitioning part) 7648be712e4SBarry Smith { 7658be712e4SBarry Smith PetscBool flag; 7668be712e4SBarry Smith char type[256]; 7678be712e4SBarry Smith const char *def; 7688be712e4SBarry Smith 7698be712e4SBarry Smith PetscFunctionBegin; 7708be712e4SBarry Smith PetscObjectOptionsBegin((PetscObject)part); 7718be712e4SBarry Smith if (!((PetscObject)part)->type_name) { 7728be712e4SBarry Smith #if defined(PETSC_HAVE_PARMETIS) 7738be712e4SBarry Smith def = MATPARTITIONINGPARMETIS; 7748be712e4SBarry Smith #elif defined(PETSC_HAVE_CHACO) 7758be712e4SBarry Smith def = MATPARTITIONINGCHACO; 7768be712e4SBarry Smith #elif defined(PETSC_HAVE_PARTY) 7778be712e4SBarry Smith def = MATPARTITIONINGPARTY; 7788be712e4SBarry Smith #elif defined(PETSC_HAVE_PTSCOTCH) 7798be712e4SBarry Smith def = MATPARTITIONINGPTSCOTCH; 7808be712e4SBarry Smith #else 7818be712e4SBarry Smith def = MATPARTITIONINGCURRENT; 7828be712e4SBarry Smith #endif 7838be712e4SBarry Smith } else { 7848be712e4SBarry Smith def = ((PetscObject)part)->type_name; 7858be712e4SBarry Smith } 7868be712e4SBarry Smith PetscCall(PetscOptionsFList("-mat_partitioning_type", "Type of partitioner", "MatPartitioningSetType", MatPartitioningList, def, type, 256, &flag)); 7878be712e4SBarry Smith if (flag) PetscCall(MatPartitioningSetType(part, type)); 7888be712e4SBarry Smith 7898be712e4SBarry Smith PetscCall(PetscOptionsInt("-mat_partitioning_nparts", "number of fine parts", NULL, part->n, &part->n, &flag)); 7908be712e4SBarry Smith 7918be712e4SBarry Smith PetscCall(PetscOptionsBool("-mat_partitioning_use_edge_weights", "whether or not to use edge weights", NULL, part->use_edge_weights, &part->use_edge_weights, &flag)); 7928be712e4SBarry Smith 7938be712e4SBarry Smith /* 7948be712e4SBarry Smith Set the type if it was never set. 7958be712e4SBarry Smith */ 7968be712e4SBarry Smith if (!((PetscObject)part)->type_name) PetscCall(MatPartitioningSetType(part, def)); 7978be712e4SBarry Smith 7988be712e4SBarry Smith PetscTryTypeMethod(part, setfromoptions, PetscOptionsObject); 7998be712e4SBarry Smith PetscOptionsEnd(); 8008be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 8018be712e4SBarry Smith } 8028be712e4SBarry Smith 8038be712e4SBarry Smith /*@C 8048be712e4SBarry Smith MatPartitioningSetNumberVertexWeights - Sets the number of weights per vertex 8058be712e4SBarry Smith 8068be712e4SBarry Smith Not Collective 8078be712e4SBarry Smith 8088be712e4SBarry Smith Input Parameters: 8098be712e4SBarry Smith + partitioning - the partitioning context 8108be712e4SBarry Smith - ncon - the number of weights 8118be712e4SBarry Smith 8128be712e4SBarry Smith Level: intermediate 8138be712e4SBarry Smith 8148be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningSetVertexWeights()` 8158be712e4SBarry Smith @*/ 8168be712e4SBarry Smith PetscErrorCode MatPartitioningSetNumberVertexWeights(MatPartitioning partitioning, PetscInt ncon) 8178be712e4SBarry Smith { 8188be712e4SBarry Smith PetscFunctionBegin; 8198be712e4SBarry Smith PetscValidHeaderSpecific(partitioning, MAT_PARTITIONING_CLASSID, 1); 8208be712e4SBarry Smith partitioning->ncon = ncon; 8218be712e4SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 8228be712e4SBarry Smith } 823