xref: /petsc/src/mat/graphops/partition/partition.c (revision bcda9346efad4e5ba2d553af84eb238771ba1e25)
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 */
MatPartitioningApply_Current(MatPartitioning part,IS * partitioning)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 */
MatPartitioningApply_Average(MatPartitioning part,IS * partitioning)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 
MatPartitioningApply_Square(MatPartitioning part,IS * partitioning)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 
MatPartitioningCreate_Current(MatPartitioning part)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 
MatPartitioningCreate_Average(MatPartitioning part)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 
MatPartitioningCreate_Square(MatPartitioning part)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 */
MatPartitioningSizesToSep_Private(PetscInt p,PetscInt sizes[],PetscInt seps[],PetscInt level[])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 
166cc4c1da9SBarry Smith   Not Collective, No Fortran Support
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 @*/
MatPartitioningRegister(const char sname[],PetscErrorCode (* function)(MatPartitioning))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 
192cc4c1da9SBarry Smith /*@
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 @*/
MatPartitioningGetType(MatPartitioning partitioning,MatPartitioningType * type)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 
217cc4c1da9SBarry Smith /*@
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 @*/
MatPartitioningSetNParts(MatPartitioning part,PetscInt n)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 @*/
MatPartitioningApplyND(MatPartitioning matp,IS * partitioning)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:
2856497c311SBarry Smith . partitioning - the partitioning. For each local node this tells the MPI rank that that node is assigned to.
2868be712e4SBarry Smith 
2878be712e4SBarry Smith   Options Database Keys:
2888be712e4SBarry Smith + -mat_partitioning_type <type> - set the partitioning package or algorithm to use
2898be712e4SBarry Smith - -mat_partitioning_view        - display information about the partitioning object
2908be712e4SBarry Smith 
2918be712e4SBarry Smith   Level: beginner
2928be712e4SBarry Smith 
2938be712e4SBarry Smith    The user can define additional partitionings; see `MatPartitioningRegister()`.
2948be712e4SBarry Smith 
2958be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningRegister()`, `MatPartitioningCreate()`,
2968be712e4SBarry Smith           `MatPartitioningDestroy()`, `MatPartitioningSetAdjacency()`, `ISPartitioningToNumbering()`,
2978be712e4SBarry Smith           `ISPartitioningCount()`
2988be712e4SBarry Smith @*/
MatPartitioningApply(MatPartitioning matp,IS * partitioning)2998be712e4SBarry Smith PetscErrorCode MatPartitioningApply(MatPartitioning matp, IS *partitioning)
3008be712e4SBarry Smith {
3018be712e4SBarry Smith   PetscBool viewbalance, improve;
3028be712e4SBarry Smith 
3038be712e4SBarry Smith   PetscFunctionBegin;
3048be712e4SBarry Smith   PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1);
3058be712e4SBarry Smith   PetscAssertPointer(partitioning, 2);
3068be712e4SBarry Smith   PetscCheck(matp->adj->assembled, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3078be712e4SBarry Smith   PetscCheck(!matp->adj->factortype, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3088be712e4SBarry Smith   PetscCall(PetscLogEventBegin(MAT_Partitioning, matp, 0, 0, 0));
3098be712e4SBarry Smith   PetscUseTypeMethod(matp, apply, partitioning);
3108be712e4SBarry Smith   PetscCall(PetscLogEventEnd(MAT_Partitioning, matp, 0, 0, 0));
3118be712e4SBarry Smith 
3128be712e4SBarry Smith   PetscCall(MatPartitioningViewFromOptions(matp, NULL, "-mat_partitioning_view"));
3138be712e4SBarry Smith   PetscCall(ISViewFromOptions(*partitioning, NULL, "-mat_partitioning_view"));
3148be712e4SBarry Smith 
3158be712e4SBarry Smith   PetscObjectOptionsBegin((PetscObject)matp);
3168be712e4SBarry Smith   viewbalance = PETSC_FALSE;
3178be712e4SBarry Smith   PetscCall(PetscOptionsBool("-mat_partitioning_view_imbalance", "Display imbalance information of a partition", NULL, PETSC_FALSE, &viewbalance, NULL));
3188be712e4SBarry Smith   improve = PETSC_FALSE;
3198be712e4SBarry Smith   PetscCall(PetscOptionsBool("-mat_partitioning_improve", "Improve the quality of a partition", NULL, PETSC_FALSE, &improve, NULL));
3208be712e4SBarry Smith   PetscOptionsEnd();
3218be712e4SBarry Smith 
3228be712e4SBarry Smith   if (improve) PetscCall(MatPartitioningImprove(matp, partitioning));
3238be712e4SBarry Smith 
3248be712e4SBarry Smith   if (viewbalance) PetscCall(MatPartitioningViewImbalance(matp, *partitioning));
3258be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
3268be712e4SBarry Smith }
3278be712e4SBarry Smith 
3288be712e4SBarry Smith /*@
3298be712e4SBarry Smith   MatPartitioningImprove - Improves the quality of a given partition.
3308be712e4SBarry Smith 
3318be712e4SBarry Smith   Collective
3328be712e4SBarry Smith 
3338be712e4SBarry Smith   Input Parameters:
3348be712e4SBarry Smith + matp         - the matrix partitioning object
3358be712e4SBarry Smith - partitioning - the original partitioning. For each local node this tells the processor
3368be712e4SBarry Smith                    number that that node is assigned to.
3378be712e4SBarry Smith 
3388be712e4SBarry Smith   Options Database Key:
3398be712e4SBarry Smith . -mat_partitioning_improve - improve the quality of the given partition
3408be712e4SBarry Smith 
3418be712e4SBarry Smith   Level: beginner
3428be712e4SBarry Smith 
3438be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningApply()`, `MatPartitioningCreate()`,
3448be712e4SBarry Smith           `MatPartitioningDestroy()`, `MatPartitioningSetAdjacency()`, `ISPartitioningToNumbering()`,
3458be712e4SBarry Smith           `ISPartitioningCount()`
3468be712e4SBarry Smith @*/
MatPartitioningImprove(MatPartitioning matp,IS * partitioning)3478be712e4SBarry Smith PetscErrorCode MatPartitioningImprove(MatPartitioning matp, IS *partitioning)
3488be712e4SBarry Smith {
3498be712e4SBarry Smith   PetscFunctionBegin;
3508be712e4SBarry Smith   PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1);
3518be712e4SBarry Smith   PetscAssertPointer(partitioning, 2);
3528be712e4SBarry Smith   PetscCheck(matp->adj->assembled, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for unassembled matrix");
3538be712e4SBarry Smith   PetscCheck(!matp->adj->factortype, PetscObjectComm((PetscObject)matp), PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
3548be712e4SBarry Smith   PetscCall(PetscLogEventBegin(MAT_Partitioning, matp, 0, 0, 0));
3558be712e4SBarry Smith   PetscTryTypeMethod(matp, improve, partitioning);
3568be712e4SBarry Smith   PetscCall(PetscLogEventEnd(MAT_Partitioning, matp, 0, 0, 0));
3578be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
3588be712e4SBarry Smith }
3598be712e4SBarry Smith 
3608be712e4SBarry Smith /*@
3618be712e4SBarry Smith   MatPartitioningViewImbalance - Display partitioning imbalance information.
3628be712e4SBarry Smith 
3638be712e4SBarry Smith   Collective
3648be712e4SBarry Smith 
3658be712e4SBarry Smith   Input Parameters:
3668be712e4SBarry Smith + matp         - the matrix partitioning object
3676497c311SBarry Smith - partitioning - the partitioning. For each local node this tells the MPI rank that that node is assigned to.
3688be712e4SBarry Smith 
3698be712e4SBarry Smith   Options Database Key:
3708be712e4SBarry Smith . -mat_partitioning_view_balance - view the balance information from the last partitioning
3718be712e4SBarry Smith 
3728be712e4SBarry Smith   Level: beginner
3738be712e4SBarry Smith 
3748be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningApply()`, `MatPartitioningView()`
3758be712e4SBarry Smith @*/
MatPartitioningViewImbalance(MatPartitioning matp,IS partitioning)3768be712e4SBarry Smith PetscErrorCode MatPartitioningViewImbalance(MatPartitioning matp, IS partitioning)
3778be712e4SBarry Smith {
3786497c311SBarry Smith   PetscMPIInt     nparts;
3796497c311SBarry Smith   PetscInt       *subdomainsizes, *subdomainsizes_tmp, nlocal, maxsub, minsub, avgsub;
3808be712e4SBarry Smith   const PetscInt *indices;
3818be712e4SBarry Smith   PetscViewer     viewer;
3828be712e4SBarry Smith 
3838be712e4SBarry Smith   PetscFunctionBegin;
3848be712e4SBarry Smith   PetscValidHeaderSpecific(matp, MAT_PARTITIONING_CLASSID, 1);
3858be712e4SBarry Smith   PetscValidHeaderSpecific(partitioning, IS_CLASSID, 2);
3866497c311SBarry Smith   PetscCall(PetscMPIIntCast(matp->n, &nparts));
3878be712e4SBarry Smith   PetscCall(PetscCalloc2(nparts, &subdomainsizes, nparts, &subdomainsizes_tmp));
3888be712e4SBarry Smith   PetscCall(ISGetLocalSize(partitioning, &nlocal));
3898be712e4SBarry Smith   PetscCall(ISGetIndices(partitioning, &indices));
3906497c311SBarry Smith   for (PetscInt i = 0; i < nlocal; i++) subdomainsizes_tmp[indices[i]] += matp->vertex_weights ? matp->vertex_weights[i] : 1;
391462c564dSBarry Smith   PetscCallMPI(MPIU_Allreduce(subdomainsizes_tmp, subdomainsizes, nparts, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)matp)));
3928be712e4SBarry Smith   PetscCall(ISRestoreIndices(partitioning, &indices));
3931690c2aeSBarry Smith   minsub = PETSC_INT_MAX, maxsub = PETSC_INT_MIN, avgsub = 0;
3946497c311SBarry Smith   for (PetscMPIInt i = 0; i < nparts; i++) {
3958be712e4SBarry Smith     minsub = PetscMin(minsub, subdomainsizes[i]);
3968be712e4SBarry Smith     maxsub = PetscMax(maxsub, subdomainsizes[i]);
3978be712e4SBarry Smith     avgsub += subdomainsizes[i];
3988be712e4SBarry Smith   }
3998be712e4SBarry Smith   avgsub /= nparts;
4008be712e4SBarry Smith   PetscCall(PetscFree2(subdomainsizes, subdomainsizes_tmp));
4018be712e4SBarry Smith   PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)matp), &viewer));
4028be712e4SBarry Smith   PetscCall(MatPartitioningView(matp, viewer));
4038be712e4SBarry 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)));
4048be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
4058be712e4SBarry Smith }
4068be712e4SBarry Smith 
4078be712e4SBarry Smith /*@
4088be712e4SBarry Smith   MatPartitioningSetAdjacency - Sets the adjacency graph (matrix) of the thing to be
4098be712e4SBarry Smith   partitioned.
4108be712e4SBarry Smith 
4118be712e4SBarry Smith   Collective
4128be712e4SBarry Smith 
4138be712e4SBarry Smith   Input Parameters:
4148be712e4SBarry Smith + part - the partitioning context
4158be712e4SBarry Smith - adj  - the adjacency matrix, this can be any `MatType` but the natural representation is `MATMPIADJ`
4168be712e4SBarry Smith 
4178be712e4SBarry Smith   Level: beginner
4188be712e4SBarry Smith 
4198be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningCreate()`
4208be712e4SBarry Smith @*/
MatPartitioningSetAdjacency(MatPartitioning part,Mat adj)4218be712e4SBarry Smith PetscErrorCode MatPartitioningSetAdjacency(MatPartitioning part, Mat adj)
4228be712e4SBarry Smith {
4238be712e4SBarry Smith   PetscFunctionBegin;
4248be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
4258be712e4SBarry Smith   PetscValidHeaderSpecific(adj, MAT_CLASSID, 2);
4268be712e4SBarry Smith   part->adj = adj;
4278be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
4288be712e4SBarry Smith }
4298be712e4SBarry Smith 
4308be712e4SBarry Smith /*@
4318be712e4SBarry Smith   MatPartitioningDestroy - Destroys the partitioning context.
4328be712e4SBarry Smith 
4338be712e4SBarry Smith   Collective
4348be712e4SBarry Smith 
4358be712e4SBarry Smith   Input Parameter:
4368be712e4SBarry Smith . part - the partitioning context
4378be712e4SBarry Smith 
4388be712e4SBarry Smith   Level: beginner
4398be712e4SBarry Smith 
4408be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningType`, `MatPartitioningCreate()`
4418be712e4SBarry Smith @*/
MatPartitioningDestroy(MatPartitioning * part)4428be712e4SBarry Smith PetscErrorCode MatPartitioningDestroy(MatPartitioning *part)
4438be712e4SBarry Smith {
4448be712e4SBarry Smith   PetscFunctionBegin;
4458be712e4SBarry Smith   if (!*part) PetscFunctionReturn(PETSC_SUCCESS);
446f4f49eeaSPierre Jolivet   PetscValidHeaderSpecific(*part, MAT_PARTITIONING_CLASSID, 1);
447f4f49eeaSPierre Jolivet   if (--((PetscObject)*part)->refct > 0) {
4488be712e4SBarry Smith     *part = NULL;
4498be712e4SBarry Smith     PetscFunctionReturn(PETSC_SUCCESS);
4508be712e4SBarry Smith   }
4518be712e4SBarry Smith 
452213acdd3SPierre Jolivet   PetscTryTypeMethod(*part, destroy);
4538be712e4SBarry Smith   PetscCall(PetscFree((*part)->vertex_weights));
4548be712e4SBarry Smith   PetscCall(PetscFree((*part)->part_weights));
4558be712e4SBarry Smith   PetscCall(PetscHeaderDestroy(part));
4568be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
4578be712e4SBarry Smith }
4588be712e4SBarry Smith 
4598be712e4SBarry Smith /*@C
4608be712e4SBarry Smith   MatPartitioningSetVertexWeights - Sets the weights for vertices for a partitioning.
4618be712e4SBarry Smith 
4628be712e4SBarry Smith   Logically Collective
4638be712e4SBarry Smith 
4648be712e4SBarry Smith   Input Parameters:
4658be712e4SBarry Smith + part    - the partitioning context
4668be712e4SBarry 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
4678be712e4SBarry Smith             1 if that is not provided
4688be712e4SBarry Smith 
4698be712e4SBarry Smith   Level: beginner
4708be712e4SBarry Smith 
4718be712e4SBarry Smith   Notes:
4728be712e4SBarry Smith   The array weights is freed by PETSc so the user should not free the array. In C/C++
4738be712e4SBarry Smith   the array must be obtained with a call to `PetscMalloc()`, not malloc().
4748be712e4SBarry Smith 
4758be712e4SBarry Smith   The weights may not be used by some partitioners
4768be712e4SBarry Smith 
477f13dfd9eSBarry Smith   Fortran Note:
478f13dfd9eSBarry Smith   The array `weights` is copied during this function call.
479f13dfd9eSBarry Smith 
4808be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningSetType()`, `MatPartitioningSetPartitionWeights()`, `MatPartitioningSetNumberVertexWeights()`
4818be712e4SBarry Smith @*/
MatPartitioningSetVertexWeights(MatPartitioning part,const PetscInt weights[])4828be712e4SBarry Smith PetscErrorCode MatPartitioningSetVertexWeights(MatPartitioning part, const PetscInt weights[])
4838be712e4SBarry Smith {
4848be712e4SBarry Smith   PetscFunctionBegin;
4858be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
4868be712e4SBarry Smith   PetscCall(PetscFree(part->vertex_weights));
4878be712e4SBarry Smith   part->vertex_weights = (PetscInt *)weights;
4888be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
4898be712e4SBarry Smith }
4908be712e4SBarry Smith 
4918be712e4SBarry Smith /*@C
4928be712e4SBarry Smith   MatPartitioningSetPartitionWeights - Sets the weights for each partition.
4938be712e4SBarry Smith 
4948be712e4SBarry Smith   Logically Collective
4958be712e4SBarry Smith 
4968be712e4SBarry Smith   Input Parameters:
4978be712e4SBarry Smith + part    - the partitioning context
4988be712e4SBarry Smith - weights - An array of size nparts that is used to specify the fraction of
4998be712e4SBarry Smith             vertex weight that should be distributed to each sub-domain for
5008be712e4SBarry Smith             the balance constraint. If all of the sub-domains are to be of
5018be712e4SBarry Smith             the same size, then each of the nparts elements should be set
5028be712e4SBarry Smith             to a value of 1/nparts. Note that the sum of all of the weights
5038be712e4SBarry Smith             should be one.
5048be712e4SBarry Smith 
5058be712e4SBarry Smith   Level: beginner
5068be712e4SBarry Smith 
5078be712e4SBarry Smith   Note:
5088be712e4SBarry Smith   The array weights is freed by PETSc so the user should not free the array. In C/C++
5098be712e4SBarry Smith   the array must be obtained with a call to `PetscMalloc()`, not malloc().
5108be712e4SBarry Smith 
511f13dfd9eSBarry Smith   Fortran Note:
512f13dfd9eSBarry Smith   The array `weights` is copied during this function call.
513f13dfd9eSBarry Smith 
5148be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningSetVertexWeights()`, `MatPartitioningCreate()`, `MatPartitioningSetType()`
5158be712e4SBarry Smith @*/
MatPartitioningSetPartitionWeights(MatPartitioning part,const PetscReal weights[])5168be712e4SBarry Smith PetscErrorCode MatPartitioningSetPartitionWeights(MatPartitioning part, const PetscReal weights[])
5178be712e4SBarry Smith {
5188be712e4SBarry Smith   PetscFunctionBegin;
5198be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
5208be712e4SBarry Smith   PetscCall(PetscFree(part->part_weights));
5218be712e4SBarry Smith   part->part_weights = (PetscReal *)weights;
5228be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
5238be712e4SBarry Smith }
5248be712e4SBarry Smith 
5258be712e4SBarry Smith /*@
5268be712e4SBarry Smith   MatPartitioningSetUseEdgeWeights - Set a flag to indicate whether or not to use edge weights.
5278be712e4SBarry Smith 
5288be712e4SBarry Smith   Logically Collective
5298be712e4SBarry Smith 
5308be712e4SBarry Smith   Input Parameters:
5318be712e4SBarry Smith + part             - the partitioning context
5328be712e4SBarry Smith - use_edge_weights - the flag indicateing whether or not to use edge weights. By default no edge weights will be used,
5338be712e4SBarry Smith                      that is, use_edge_weights is set to FALSE. If set use_edge_weights to TRUE, users need to make sure legal
5348be712e4SBarry Smith                      edge weights are stored in an ADJ matrix.
5358be712e4SBarry Smith 
5368be712e4SBarry Smith   Options Database Key:
5378be712e4SBarry Smith . -mat_partitioning_use_edge_weights - (true or false)
5388be712e4SBarry Smith 
5398be712e4SBarry Smith   Level: beginner
5408be712e4SBarry Smith 
5418be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningSetType()`, `MatPartitioningSetVertexWeights()`, `MatPartitioningSetPartitionWeights()`
5428be712e4SBarry Smith @*/
MatPartitioningSetUseEdgeWeights(MatPartitioning part,PetscBool use_edge_weights)5438be712e4SBarry Smith PetscErrorCode MatPartitioningSetUseEdgeWeights(MatPartitioning part, PetscBool use_edge_weights)
5448be712e4SBarry Smith {
5458be712e4SBarry Smith   PetscFunctionBegin;
5468be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
5478be712e4SBarry Smith   part->use_edge_weights = use_edge_weights;
5488be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
5498be712e4SBarry Smith }
5508be712e4SBarry Smith 
5518be712e4SBarry Smith /*@
5528be712e4SBarry Smith   MatPartitioningGetUseEdgeWeights - Get a flag that indicates whether or not to edge weights are used.
5538be712e4SBarry Smith 
5548be712e4SBarry Smith   Logically Collective
5558be712e4SBarry Smith 
5568be712e4SBarry Smith   Input Parameter:
5578be712e4SBarry Smith . part - the partitioning context
5588be712e4SBarry Smith 
5598be712e4SBarry Smith   Output Parameter:
5608be712e4SBarry Smith . use_edge_weights - the flag indicateing whether or not to edge weights are used.
5618be712e4SBarry Smith 
5628be712e4SBarry Smith   Level: beginner
5638be712e4SBarry Smith 
5648be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningSetType()`, `MatPartitioningSetVertexWeights()`, `MatPartitioningSetPartitionWeights()`,
5658be712e4SBarry Smith           `MatPartitioningSetUseEdgeWeights`
5668be712e4SBarry Smith @*/
MatPartitioningGetUseEdgeWeights(MatPartitioning part,PetscBool * use_edge_weights)5678be712e4SBarry Smith PetscErrorCode MatPartitioningGetUseEdgeWeights(MatPartitioning part, PetscBool *use_edge_weights)
5688be712e4SBarry Smith {
5698be712e4SBarry Smith   PetscFunctionBegin;
5708be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
5718be712e4SBarry Smith   PetscAssertPointer(use_edge_weights, 2);
5728be712e4SBarry Smith   *use_edge_weights = part->use_edge_weights;
5738be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
5748be712e4SBarry Smith }
5758be712e4SBarry Smith 
5768be712e4SBarry Smith /*@
5778be712e4SBarry Smith   MatPartitioningCreate - Creates a partitioning context.
5788be712e4SBarry Smith 
5798be712e4SBarry Smith   Collective
5808be712e4SBarry Smith 
5818be712e4SBarry Smith   Input Parameter:
5828be712e4SBarry Smith . comm - MPI communicator
5838be712e4SBarry Smith 
5848be712e4SBarry Smith   Output Parameter:
5858be712e4SBarry Smith . newp - location to put the context
5868be712e4SBarry Smith 
5878be712e4SBarry Smith   Level: beginner
5888be712e4SBarry Smith 
5898be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningSetType()`, `MatPartitioningApply()`, `MatPartitioningDestroy()`,
5908be712e4SBarry Smith           `MatPartitioningSetAdjacency()`
5918be712e4SBarry Smith @*/
MatPartitioningCreate(MPI_Comm comm,MatPartitioning * newp)5928be712e4SBarry Smith PetscErrorCode MatPartitioningCreate(MPI_Comm comm, MatPartitioning *newp)
5938be712e4SBarry Smith {
5948be712e4SBarry Smith   MatPartitioning part;
5958be712e4SBarry Smith   PetscMPIInt     size;
5968be712e4SBarry Smith 
5978be712e4SBarry Smith   PetscFunctionBegin;
598377f809aSBarry Smith   PetscAssertPointer(newp, 2);
5998be712e4SBarry Smith   PetscCall(MatInitializePackage());
600377f809aSBarry Smith 
6018be712e4SBarry Smith   PetscCall(PetscHeaderCreate(part, MAT_PARTITIONING_CLASSID, "MatPartitioning", "Matrix/graph partitioning", "MatGraphOperations", comm, MatPartitioningDestroy, MatPartitioningView));
6028be712e4SBarry Smith   part->vertex_weights   = NULL;
6038be712e4SBarry Smith   part->part_weights     = NULL;
6048be712e4SBarry Smith   part->use_edge_weights = PETSC_FALSE; /* By default we don't use edge weights */
6058be712e4SBarry Smith 
6068be712e4SBarry Smith   PetscCallMPI(MPI_Comm_size(comm, &size));
607835f2295SStefano Zampini   part->n    = size;
6088be712e4SBarry Smith   part->ncon = 1;
6098be712e4SBarry Smith 
6108be712e4SBarry Smith   *newp = part;
6118be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
6128be712e4SBarry Smith }
6138be712e4SBarry Smith 
614ffeef943SBarry Smith /*@
6158be712e4SBarry Smith   MatPartitioningViewFromOptions - View a partitioning context from the options database
6168be712e4SBarry Smith 
6178be712e4SBarry Smith   Collective
6188be712e4SBarry Smith 
6198be712e4SBarry Smith   Input Parameters:
6208be712e4SBarry Smith + A    - the partitioning context
6218be712e4SBarry Smith . obj  - Optional object that provides the prefix used in the options database check
6228be712e4SBarry Smith - name - command line option
6238be712e4SBarry Smith 
6248be712e4SBarry Smith   Options Database Key:
6258be712e4SBarry Smith . -mat_partitioning_view [viewertype]:... - the viewer and its options
6268be712e4SBarry Smith 
6278be712e4SBarry Smith   Level: intermediate
6288be712e4SBarry Smith 
6298be712e4SBarry Smith   Note:
6308be712e4SBarry Smith .vb
6318be712e4SBarry Smith     If no value is provided ascii:stdout is used
6328be712e4SBarry Smith        ascii[:[filename][:[format][:append]]]    defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab,
6338be712e4SBarry Smith                                                   for example ascii::ascii_info prints just the information about the object not all details
6348be712e4SBarry Smith                                                   unless :append is given filename opens in write mode, overwriting what was already there
6358be712e4SBarry Smith        binary[:[filename][:[format][:append]]]   defaults to the file binaryoutput
6368be712e4SBarry Smith        draw[:drawtype[:filename]]                for example, draw:tikz, draw:tikz:figure.tex  or draw:x
6378be712e4SBarry Smith        socket[:port]                             defaults to the standard output port
6388be712e4SBarry Smith        saws[:communicatorname]                    publishes object to the Scientific Application Webserver (SAWs)
6398be712e4SBarry Smith .ve
6408be712e4SBarry Smith 
6418be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningView()`, `PetscObjectViewFromOptions()`, `MatPartitioningCreate()`
6428be712e4SBarry Smith @*/
MatPartitioningViewFromOptions(MatPartitioning A,PetscObject obj,const char name[])6438be712e4SBarry Smith PetscErrorCode MatPartitioningViewFromOptions(MatPartitioning A, PetscObject obj, const char name[])
6448be712e4SBarry Smith {
6458be712e4SBarry Smith   PetscFunctionBegin;
6468be712e4SBarry Smith   PetscValidHeaderSpecific(A, MAT_PARTITIONING_CLASSID, 1);
6478be712e4SBarry Smith   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
6488be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
6498be712e4SBarry Smith }
6508be712e4SBarry Smith 
651ffeef943SBarry Smith /*@
6528be712e4SBarry Smith   MatPartitioningView - Prints the partitioning data structure.
6538be712e4SBarry Smith 
6548be712e4SBarry Smith   Collective
6558be712e4SBarry Smith 
6568be712e4SBarry Smith   Input Parameters:
6578be712e4SBarry Smith + part   - the partitioning context
6588be712e4SBarry Smith - viewer - optional visualization context
6598be712e4SBarry Smith 
6608be712e4SBarry Smith   Level: intermediate
6618be712e4SBarry Smith 
6628be712e4SBarry Smith   Note:
6638be712e4SBarry Smith   The available visualization contexts include
6648be712e4SBarry Smith +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
6658be712e4SBarry Smith -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
6668be712e4SBarry Smith   output where only the first processor opens
6678be712e4SBarry Smith   the file.  All other processors send their
6688be712e4SBarry Smith   data to the first processor to print.
6698be712e4SBarry Smith 
6708be712e4SBarry Smith   The user can open alternative visualization contexts with
6718be712e4SBarry Smith .     `PetscViewerASCIIOpen()` - output to a specified file
6728be712e4SBarry Smith 
6738be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `PetscViewer`, `PetscViewerASCIIOpen()`
6748be712e4SBarry Smith @*/
MatPartitioningView(MatPartitioning part,PetscViewer viewer)6758be712e4SBarry Smith PetscErrorCode MatPartitioningView(MatPartitioning part, PetscViewer viewer)
6768be712e4SBarry Smith {
677*9f196a02SMartin Diehl   PetscBool isascii;
6788be712e4SBarry Smith 
6798be712e4SBarry Smith   PetscFunctionBegin;
6808be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
6818be712e4SBarry Smith   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)part), &viewer));
6828be712e4SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
6838be712e4SBarry Smith   PetscCheckSameComm(part, 1, viewer, 2);
6848be712e4SBarry Smith 
685*9f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
686*9f196a02SMartin Diehl   if (isascii) {
6878be712e4SBarry Smith     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)part, viewer));
6888be712e4SBarry Smith     if (part->vertex_weights) PetscCall(PetscViewerASCIIPrintf(viewer, "  Using vertex weights\n"));
6898be712e4SBarry Smith   }
6908be712e4SBarry Smith   PetscCall(PetscViewerASCIIPushTab(viewer));
6918be712e4SBarry Smith   PetscTryTypeMethod(part, view, viewer);
6928be712e4SBarry Smith   PetscCall(PetscViewerASCIIPopTab(viewer));
6938be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
6948be712e4SBarry Smith }
6958be712e4SBarry Smith 
696cc4c1da9SBarry Smith /*@
6978be712e4SBarry Smith   MatPartitioningSetType - Sets the type of partitioner to use
6988be712e4SBarry Smith 
6998be712e4SBarry Smith   Collective
7008be712e4SBarry Smith 
7018be712e4SBarry Smith   Input Parameters:
7028be712e4SBarry Smith + part - the partitioning context.
7038be712e4SBarry Smith - type - a known method
7048be712e4SBarry Smith 
7058be712e4SBarry Smith   Options Database Key:
7068be712e4SBarry Smith . -mat_partitioning_type  <type> - (for instance, parmetis), use -help for a list of available methods or see  `MatPartitioningType`
7078be712e4SBarry Smith 
7088be712e4SBarry Smith   Level: intermediate
7098be712e4SBarry Smith 
7108be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningCreate()`, `MatPartitioningApply()`, `MatPartitioningType`
7118be712e4SBarry Smith @*/
MatPartitioningSetType(MatPartitioning part,MatPartitioningType type)7128be712e4SBarry Smith PetscErrorCode MatPartitioningSetType(MatPartitioning part, MatPartitioningType type)
7138be712e4SBarry Smith {
7148be712e4SBarry Smith   PetscBool match;
7158be712e4SBarry Smith   PetscErrorCode (*r)(MatPartitioning);
7168be712e4SBarry Smith 
7178be712e4SBarry Smith   PetscFunctionBegin;
7188be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
7198be712e4SBarry Smith   PetscAssertPointer(type, 2);
7208be712e4SBarry Smith 
7218be712e4SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)part, type, &match));
7228be712e4SBarry Smith   if (match) PetscFunctionReturn(PETSC_SUCCESS);
7238be712e4SBarry Smith 
7248be712e4SBarry Smith   PetscTryTypeMethod(part, destroy);
7258be712e4SBarry Smith   part->ops->destroy = NULL;
7268be712e4SBarry Smith 
7278be712e4SBarry Smith   part->data = NULL;
7288be712e4SBarry Smith   PetscCall(PetscMemzero(part->ops, sizeof(struct _MatPartitioningOps)));
7298be712e4SBarry Smith 
7308be712e4SBarry Smith   PetscCall(PetscFunctionListFind(MatPartitioningList, type, &r));
7318be712e4SBarry Smith   PetscCheck(r, PetscObjectComm((PetscObject)part), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown partitioning type %s", type);
7328be712e4SBarry Smith 
7338be712e4SBarry Smith   PetscCall((*r)(part));
7348be712e4SBarry Smith 
7358be712e4SBarry Smith   PetscCall(PetscFree(((PetscObject)part)->type_name));
7368be712e4SBarry Smith   PetscCall(PetscStrallocpy(type, &((PetscObject)part)->type_name));
7378be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
7388be712e4SBarry Smith }
7398be712e4SBarry Smith 
7408be712e4SBarry Smith /*@
7418be712e4SBarry Smith   MatPartitioningSetFromOptions - Sets various partitioning options from the
7428be712e4SBarry Smith   options database for the partitioning object
7438be712e4SBarry Smith 
7448be712e4SBarry Smith   Collective
7458be712e4SBarry Smith 
7468be712e4SBarry Smith   Input Parameter:
7478be712e4SBarry Smith . part - the partitioning context.
7488be712e4SBarry Smith 
7498be712e4SBarry Smith   Options Database Keys:
7508be712e4SBarry Smith + -mat_partitioning_type  <type> - (for instance, parmetis), use -help for a list of available methods
7518be712e4SBarry Smith - -mat_partitioning_nparts       - number of subgraphs
7528be712e4SBarry Smith 
7538be712e4SBarry Smith   Level: beginner
7548be712e4SBarry Smith 
7558be712e4SBarry Smith   Note:
7568be712e4SBarry Smith   If the partitioner has not been set by the user it uses one of the installed partitioner such as ParMetis. If there are
7578be712e4SBarry Smith   no installed partitioners it does no repartioning.
7588be712e4SBarry Smith 
7598be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`
7608be712e4SBarry Smith @*/
MatPartitioningSetFromOptions(MatPartitioning part)7618be712e4SBarry Smith PetscErrorCode MatPartitioningSetFromOptions(MatPartitioning part)
7628be712e4SBarry Smith {
7638be712e4SBarry Smith   PetscBool   flag;
7648be712e4SBarry Smith   char        type[256];
7658be712e4SBarry Smith   const char *def;
7668be712e4SBarry Smith 
7678be712e4SBarry Smith   PetscFunctionBegin;
7688be712e4SBarry Smith   PetscObjectOptionsBegin((PetscObject)part);
7698be712e4SBarry Smith   if (!((PetscObject)part)->type_name) {
7708be712e4SBarry Smith #if defined(PETSC_HAVE_PARMETIS)
7718be712e4SBarry Smith     def = MATPARTITIONINGPARMETIS;
7728be712e4SBarry Smith #elif defined(PETSC_HAVE_CHACO)
7738be712e4SBarry Smith     def = MATPARTITIONINGCHACO;
7748be712e4SBarry Smith #elif defined(PETSC_HAVE_PARTY)
7758be712e4SBarry Smith     def = MATPARTITIONINGPARTY;
7768be712e4SBarry Smith #elif defined(PETSC_HAVE_PTSCOTCH)
7778be712e4SBarry Smith     def = MATPARTITIONINGPTSCOTCH;
7788be712e4SBarry Smith #else
7798be712e4SBarry Smith     def = MATPARTITIONINGCURRENT;
7808be712e4SBarry Smith #endif
7818be712e4SBarry Smith   } else {
7828be712e4SBarry Smith     def = ((PetscObject)part)->type_name;
7838be712e4SBarry Smith   }
7848be712e4SBarry Smith   PetscCall(PetscOptionsFList("-mat_partitioning_type", "Type of partitioner", "MatPartitioningSetType", MatPartitioningList, def, type, 256, &flag));
7858be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningSetType(part, type));
7868be712e4SBarry Smith 
7878be712e4SBarry Smith   PetscCall(PetscOptionsInt("-mat_partitioning_nparts", "number of fine parts", NULL, part->n, &part->n, &flag));
7888be712e4SBarry Smith 
7898be712e4SBarry 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));
7908be712e4SBarry Smith 
7918be712e4SBarry Smith   /*
7928be712e4SBarry Smith     Set the type if it was never set.
7938be712e4SBarry Smith   */
7948be712e4SBarry Smith   if (!((PetscObject)part)->type_name) PetscCall(MatPartitioningSetType(part, def));
7958be712e4SBarry Smith 
7968be712e4SBarry Smith   PetscTryTypeMethod(part, setfromoptions, PetscOptionsObject);
7978be712e4SBarry Smith   PetscOptionsEnd();
7988be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
7998be712e4SBarry Smith }
8008be712e4SBarry Smith 
801cc4c1da9SBarry Smith /*@
8028be712e4SBarry Smith   MatPartitioningSetNumberVertexWeights - Sets the number of weights per vertex
8038be712e4SBarry Smith 
8048be712e4SBarry Smith   Not Collective
8058be712e4SBarry Smith 
8068be712e4SBarry Smith   Input Parameters:
8078be712e4SBarry Smith + partitioning - the partitioning context
8088be712e4SBarry Smith - ncon         - the number of weights
8098be712e4SBarry Smith 
8108be712e4SBarry Smith   Level: intermediate
8118be712e4SBarry Smith 
8128be712e4SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatPartitioning`, `MatPartitioningSetVertexWeights()`
8138be712e4SBarry Smith @*/
MatPartitioningSetNumberVertexWeights(MatPartitioning partitioning,PetscInt ncon)8148be712e4SBarry Smith PetscErrorCode MatPartitioningSetNumberVertexWeights(MatPartitioning partitioning, PetscInt ncon)
8158be712e4SBarry Smith {
8168be712e4SBarry Smith   PetscFunctionBegin;
8178be712e4SBarry Smith   PetscValidHeaderSpecific(partitioning, MAT_PARTITIONING_CLASSID, 1);
8188be712e4SBarry Smith   partitioning->ncon = ncon;
8198be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
8208be712e4SBarry Smith }
821