66 const RCP<const Environment> &env,
67 const RCP<
const Comm<int> > &comm,
68 const ArrayView<const part_t> &part,
76 ArrayRCP<scalar_t> &globalSums)
82 numExistingParts = numNonemptyParts = 0;
85 if (vwgtDim) numMetrics++;
86 if (vwgtDim > 1) numMetrics += vwgtDim;
88 auto next = metrics.size();
90 for(
int n = 0; n < numMetrics; ++n) {
91 RCP<im_t> newMetric = addNewMetric<im_t, scalar_t>(env, metrics);
101 lno_t localNumObj = part.size();
102 part_t localNum[2], globalNum[2];
103 localNum[0] =
static_cast<part_t>(vwgtDim);
106 for (
lno_t i=0; i < localNumObj; i++)
107 if (part[i] > localNum[1]) localNum[1] = part[i];
110 reduceAll<int, part_t>(*comm, Teuchos::REDUCE_MAX, 2,
111 localNum, globalNum);
115 env->globalBugAssertion(__FILE__,__LINE__,
116 "inconsistent number of vertex weights",
119 part_t maxPartPlusOne = globalNum[1] + 1;
122 part_t globalSumSize = maxPartPlusOne * numMetrics;
124 scalar_t * sumBuf =
new scalar_t[globalSumSize];
125 env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, sumBuf);
126 globalSums = arcp(sumBuf, 0, globalSumSize);
131 scalar_t *localBuf =
new scalar_t[globalSumSize];
132 env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, localBuf);
133 memset(localBuf, 0,
sizeof(scalar_t) * globalSumSize);
135 scalar_t *obj = localBuf;
137 for (
lno_t i=0; i < localNumObj; i++)
142 scalar_t *wgt = localBuf+maxPartPlusOne;
144 normedPartWeights<scalar_t, lno_t, part_t>(env, maxPartPlusOne,
145 part, vwgts, mcNorm, wgt);
152 wgt += maxPartPlusOne;
153 for (
int vdim = 0; vdim < vwgtDim; vdim++){
154 for (
lno_t i=0; i < localNumObj; i++)
155 wgt[part[i]] += vwgts[vdim][i];
156 wgt += maxPartPlusOne;
162 metrics[next]->setName(
"object count");
163 metrics[next]->setMetricValue(
"local sum", localNumObj);
168 scalar_t *wgt = localBuf+maxPartPlusOne;
169 scalar_t total = 0.0;
171 for (
int p=0; p < maxPartPlusOne; p++){
176 metrics[next]->setName(
"weight 0");
178 metrics[next]->setName(
"normed weight");
180 metrics[next]->setMetricValue(
"local sum", total);
185 for (
int vdim = 0; vdim < vwgtDim; vdim++){
186 wgt += maxPartPlusOne;
188 for (
int p=0; p < maxPartPlusOne; p++){
192 std::ostringstream oss;
193 oss <<
"weight " << vdim;
195 metrics[next]->setName(oss.str());
196 metrics[next]->setMetricValue(
"local sum", total);
207 reduceAll<int, scalar_t>(*comm, Teuchos::REDUCE_SUM, globalSumSize,
218 scalar_t min=0, max=0, sum=0;
219 next = metrics.size() - numMetrics;
225 ArrayView<scalar_t> objVec(obj, maxPartPlusOne);
226 getStridedStats<scalar_t>(objVec, 1, 0, min, max, sum);
227 if (maxPartPlusOne < targetNumParts)
230 metrics[next]->setMetricValue(
"global minimum", min);
231 metrics[next]->setMetricValue(
"global maximum", max);
232 metrics[next]->setMetricValue(
"global sum", sum);
236 scalar_t *wgt = sumBuf + maxPartPlusOne;
238 ArrayView<scalar_t> normedWVec(wgt, maxPartPlusOne);
239 getStridedStats<scalar_t>(normedWVec, 1, 0, min, max, sum);
240 if (maxPartPlusOne < targetNumParts)
243 metrics[next]->setMetricValue(
"global minimum", min);
244 metrics[next]->setMetricValue(
"global maximum", max);
245 metrics[next]->setMetricValue(
"global sum", sum);
249 for (
int vdim=0; vdim < vwgtDim; vdim++){
250 wgt += maxPartPlusOne;
251 ArrayView<scalar_t> fromVec(wgt, maxPartPlusOne);
252 getStridedStats<scalar_t>(fromVec, 1, 0, min, max, sum);
253 if (maxPartPlusOne < targetNumParts)
256 metrics[next]->setMetricValue(
"global minimum", min);
257 metrics[next]->setMetricValue(
"global maximum", max);
258 metrics[next]->setMetricValue(
"global sum", sum);
267 numExistingParts = maxPartPlusOne;
275 numNonemptyParts = numExistingParts;
277 for (
part_t p=0; p < numExistingParts; p++)
278 if (obj[p] == 0) numNonemptyParts--;
315 const RCP<const Environment> &env,
316 const RCP<
const Comm<int> > &comm,
320 const ArrayView<const typename Adapter::part_t> &partArray,
322 typename Adapter::part_t &numExistingParts,
323 typename Adapter::part_t &numNonemptyParts,
328 typedef typename Adapter::scalar_t scalar_t;
329 typedef typename Adapter::gno_t
gno_t;
330 typedef typename Adapter::lno_t
lno_t;
331 typedef typename Adapter::part_t
part_t;
332 typedef typename Adapter::base_adapter_t base_adapter_t;
337 size_t numLocalObjects = ia->getLocalNumIDs();
341 int nWeights = ia->getNumWeightsPerID();
342 int numCriteria = (nWeights > 0 ? nWeights : 1);
343 Array<sdata_t>
weights(numCriteria);
353 bool useDegreeAsWeight =
false;
356 <typename Adapter::user_t, typename Adapter::userCoord_t
> *>(ia)->
357 useDegreeAsWeight(0);
360 <typename Adapter::user_t, typename Adapter::userCoord_t
> *>(ia)->
361 useDegreeAsWeight(0);
365 useDegreeAsWeight(0);
367 if (useDegreeAsWeight) {
368 ArrayView<const gno_t> Ids;
369 ArrayView<sdata_t> vwgts;
370 RCP<GraphModel<base_adapter_t> > graph;
371 if (graphModel == Teuchos::null) {
372 std::bitset<NUM_MODEL_FLAGS> modelFlags;
373 const RCP<const base_adapter_t> bia =
374 rcp(
dynamic_cast<const base_adapter_t *
>(ia),
false);
376 graph->getVertexList(Ids, vwgts);
378 graphModel->getVertexList(Ids, vwgts);
380 scalar_t *wgt =
new scalar_t[numLocalObjects];
381 for (
int i=0; i < nWeights; i++){
382 for (
size_t j=0; j < numLocalObjects; j++) {
383 wgt[j] = vwgts[i][j];
385 ArrayRCP<const scalar_t> wgtArray(wgt,0,numLocalObjects,
false);
386 weights[i] = sdata_t(wgtArray, 1);
389 for (
int i=0; i < nWeights; i++){
392 ia->getWeightsView(wgt, stride, i);
393 ArrayRCP<const scalar_t> wgtArray(wgt,0,stride*numLocalObjects,
false);
394 weights[i] = sdata_t(wgtArray, stride);
401 part_t targetNumParts = comm->getSize();
402 scalar_t *psizes = NULL;
404 ArrayRCP<ArrayRCP<scalar_t> > partSizes(numCriteria);
407 for (
int dim=0; dim < numCriteria; dim++){
409 psizes =
new scalar_t [targetNumParts];
410 env->localMemoryAssertion(__FILE__, __LINE__, targetNumParts, psizes);
411 for (
part_t i=0; i < targetNumParts; i++){
414 partSizes[dim] = arcp(psizes, 0, targetNumParts,
true);
423 ArrayRCP<scalar_t> globalSums;
425 int initialMetricCount = metrics.size();
427 globalSumsByPart<scalar_t, lno_t, part_t>(env, comm,
428 partArray, nWeights,
weights.view(0, numCriteria), mcNorm,
429 targetNumParts, numExistingParts, numNonemptyParts, metrics, globalSums);
433 int addedMetricsCount = metrics.size() - initialMetricCount;
439 int index = initialMetricCount;
441 scalar_t *objCount = globalSums.getRawPtr();
442 scalar_t min, max, avg;
445 if (partSizes[0].size() > 0)
446 psizes = partSizes[0].getRawPtr();
448 scalar_t gsum = metrics[index]->getMetricValue(
"global sum");
449 computeImbalances<scalar_t, part_t>(numExistingParts, targetNumParts, psizes,
450 gsum, objCount, min, max, avg);
452 metrics[index]->setMetricValue(
"global average", gsum / targetNumParts);
454 metrics[index]->setMetricValue(
"maximum imbalance", 1.0 + max);
455 metrics[index]->setMetricValue(
"average imbalance", avg);
460 scalar_t *wgts = globalSums.getRawPtr() + numExistingParts;
462 if (addedMetricsCount > 1){
464 gsum = metrics[index]->getMetricValue(
"global sum");
465 computeImbalances<scalar_t, part_t>(numExistingParts, targetNumParts,
466 numCriteria, partSizes.view(0, numCriteria), gsum, wgts, min, max, avg);
468 metrics[index]->setMetricValue(
"global average", gsum / targetNumParts);
470 metrics[index]->setMetricValue(
"maximum imbalance", 1.0 + max);
471 metrics[index]->setMetricValue(
"average imbalance", avg);
473 if (addedMetricsCount > 2){
480 for (
int vdim=0; vdim < numCriteria; vdim++){
481 wgts += numExistingParts;
484 if (partSizes[vdim].size() > 0)
485 psizes = partSizes[vdim].getRawPtr();
487 gsum = metrics[index]->getMetricValue(
"global sum");
488 computeImbalances<scalar_t, part_t>(numExistingParts, targetNumParts,
489 psizes, gsum, wgts, min, max, avg);
491 metrics[index]->setMetricValue(
"global average", gsum / targetNumParts);
493 metrics[index]->setMetricValue(
"maximum imbalance", 1.0 + max);
494 metrics[index]->setMetricValue(
"average imbalance", avg);