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) {
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;
125 env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, sumBuf);
126 globalSums = arcp(sumBuf, 0, globalSumSize);
132 env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, localBuf);
133 memset(localBuf, 0,
sizeof(
scalar_t) * globalSumSize);
137 for (
lno_t i=0; i < localNumObj; i++)
142 scalar_t *wgt = localBuf+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;
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,
219 next = metrics.size() - numMetrics;
225 ArrayView<scalar_t> objVec(obj, maxPartPlusOne);
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);
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);
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 for (
int i=0; i < nWeights; i++){
381 ArrayRCP<scalar_t> wgtArray(numLocalObjects);
382 for (
size_t j=0; j < numLocalObjects; j++) {
383 wgtArray[j] = vwgts[i][j];
385 weights[i] = sdata_t(wgtArray, 1);
388 for (
int i=0; i < nWeights; i++){
391 ia->getWeightsView(wgt, stride, i);
392 ArrayRCP<const scalar_t> wgtArray(wgt,0,stride*numLocalObjects,
false);
393 weights[i] = sdata_t(wgtArray, stride);
400 part_t targetNumParts = comm->getSize();
403 ArrayRCP<ArrayRCP<scalar_t> > partSizes(numCriteria);
406 for (
int dim=0; dim < numCriteria; dim++){
408 psizes =
new scalar_t [targetNumParts];
409 env->localMemoryAssertion(__FILE__, __LINE__, targetNumParts, psizes);
410 for (
part_t i=0; i < targetNumParts; i++){
413 partSizes[dim] = arcp(psizes, 0, targetNumParts,
true);
422 ArrayRCP<scalar_t> globalSums;
424 int initialMetricCount = metrics.size();
427 partArray, nWeights,
weights.view(0, numCriteria), mcNorm,
428 targetNumParts, numExistingParts, numNonemptyParts, metrics, globalSums);
432 int addedMetricsCount = metrics.size() - initialMetricCount;
438 int index = initialMetricCount;
440 scalar_t *objCount = globalSums.getRawPtr();
444 if (partSizes[0].size() > 0)
445 psizes = partSizes[0].getRawPtr();
447 scalar_t gsum = metrics[index]->getMetricValue(
"global sum");
449 gsum, objCount, min, max, avg);
451 metrics[index]->setMetricValue(
"global average", gsum / targetNumParts);
453 metrics[index]->setMetricValue(
"maximum imbalance", 1.0 + max);
454 metrics[index]->setMetricValue(
"average imbalance", avg);
459 scalar_t *wgts = globalSums.getRawPtr() + numExistingParts;
461 if (addedMetricsCount > 1){
463 gsum = metrics[index]->getMetricValue(
"global sum");
465 numCriteria, partSizes.view(0, numCriteria), gsum, wgts, min, max, avg);
467 metrics[index]->setMetricValue(
"global average", gsum / targetNumParts);
469 metrics[index]->setMetricValue(
"maximum imbalance", 1.0 + max);
470 metrics[index]->setMetricValue(
"average imbalance", avg);
472 if (addedMetricsCount > 2){
479 for (
int vdim=0; vdim < numCriteria; vdim++){
480 wgts += numExistingParts;
483 if (partSizes[vdim].size() > 0)
484 psizes = partSizes[vdim].getRawPtr();
486 gsum = metrics[index]->getMetricValue(
"global sum");
488 psizes, gsum, wgts, min, max, avg);
490 metrics[index]->setMetricValue(
"global average", gsum / targetNumParts);
492 metrics[index]->setMetricValue(
"maximum imbalance", 1.0 + max);
493 metrics[index]->setMetricValue(
"average imbalance", avg);
void globalSumsByPart(const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, const ArrayView< const part_t > &part, int vwgtDim, const ArrayView< StridedData< lno_t, scalar_t > > &vwgts, multiCriteriaNorm mcNorm, part_t targetNumParts, part_t &numExistingParts, part_t &numNonemptyParts, ArrayRCP< RCP< BaseClassMetrics< scalar_t > > > &metrics, ArrayRCP< scalar_t > &globalSums)
Given the local partitioning, compute the global sums in each part.