49 #ifndef ZOLTAN2_GRAPHICMETRICVALUESUTILITY_HPP 50 #define ZOLTAN2_GRAPHICMETRICVALUESUTILITY_HPP 86 template <
typename Adapter>
88 const RCP<const Environment> &env,
89 const RCP<
const Comm<int> > &comm,
91 const ArrayView<const typename Adapter::part_t> &part,
92 typename Adapter::part_t &numParts,
94 ArrayRCP<typename Adapter::scalar_t> &globalSums)
102 int ewgtDim = graph->getNumWeightsPerEdge();
105 if (ewgtDim) numMetrics += ewgtDim;
107 typedef typename Adapter::scalar_t scalar_t;
108 typedef typename Adapter::gno_t gno_t;
109 typedef typename Adapter::lno_t lno_t;
110 typedef typename Adapter::node_t node_t;
111 typedef typename Adapter::part_t part_t;
115 typedef Tpetra::CrsMatrix<part_t,lno_t,gno_t,node_t> sparse_matrix_type;
116 typedef Tpetra::Vector<part_t,lno_t,gno_t,node_t> vector_t;
117 typedef Tpetra::Map<lno_t, gno_t, node_t> map_type;
119 const GST
INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
124 typedef typename ArrayRCP<RCP<BaseClassMetrics<typename Adapter::scalar_t> > >::size_type array_size_type;
125 metrics.resize( metrics.size() + numMetrics );
126 for( array_size_type n = metrics.size() - numMetrics; n < metrics.size(); ++n ) {
127 mv_t * newMetric =
new mv_t;
128 env->localMemoryAssertion(__FILE__,__LINE__,1,newMetric);
129 metrics[n] = rcp( newMetric);
131 array_size_type next = metrics.size() - numMetrics;
138 lno_t localNumObj = part.size();
139 part_t localNum[2], globalNum[2];
140 localNum[0] =
static_cast<part_t
>(ewgtDim);
143 for (lno_t i=0; i < localNumObj; i++)
144 if (part[i] > localNum[1]) localNum[1] = part[i];
147 reduceAll<int, part_t>(*comm, Teuchos::REDUCE_MAX, 2,
148 localNum, globalNum);
152 env->globalBugAssertion(__FILE__,__LINE__,
153 "inconsistent number of edge weights",
156 part_t nparts = globalNum[1] + 1;
158 part_t globalSumSize = nparts * numMetrics;
159 scalar_t * sumBuf =
new scalar_t [globalSumSize];
160 env->localMemoryAssertion(__FILE__, __LINE__, globalSumSize, sumBuf);
161 globalSums = arcp(sumBuf, 0, globalSumSize);
166 scalar_t *localBuf =
new scalar_t [globalSumSize];
167 env->localMemoryAssertion(__FILE__,__LINE__,globalSumSize,localBuf);
168 memset(localBuf, 0,
sizeof(scalar_t) * globalSumSize);
170 scalar_t *cut = localBuf;
172 ArrayView<const gno_t> Ids;
173 ArrayView<input_t> vwgts;
175 graph->getVertexList(Ids, vwgts);
177 ArrayView<const gno_t> edgeIds;
178 ArrayView<const lno_t> offsets;
179 ArrayView<input_t> wgts;
181 graph->getEdgeList(edgeIds, offsets, wgts);
186 RCP<const map_type> vertexMapG;
189 gno_t min = std::numeric_limits<gno_t>::max();
191 for (lno_t i = 0; i < localNumObj; ++i) {
192 if (Ids[i] < min) min = Ids[i];
193 size_t ncols = offsets[i+1] - offsets[i];
194 if (ncols > maxcols) maxcols = ncols;
198 Teuchos::reduceAll<int, gno_t>(*comm,Teuchos::REDUCE_MIN,1,&min,&gmin);
201 vertexMapG = rcp(
new map_type(
INVALID, Ids, gmin, comm));
207 RCP<sparse_matrix_type> adjsMatrix;
210 adjsMatrix = rcp (
new sparse_matrix_type (vertexMapG, 0));
212 Array<part_t> justOneA(maxcols, 1);
214 for (lno_t localElement=0; localElement<localNumObj; ++localElement){
216 size_t ncols = offsets[localElement+1] - offsets[localElement];
217 adjsMatrix->insertGlobalValues(Ids[localElement],
218 edgeIds(offsets[localElement], ncols),
223 adjsMatrix->fillComplete ();
226 RCP<vector_t> scaleVec = Teuchos::rcp(
new vector_t(vertexMapG,
false) );
227 for (lno_t localElement=0; localElement<localNumObj; ++localElement) {
228 scaleVec->replaceLocalValue(localElement,part[localElement]);
232 adjsMatrix->rightScale(*scaleVec);
233 Array<gno_t> Indices;
234 Array<part_t> Values;
236 for (lno_t i=0; i < localNumObj; i++) {
237 const gno_t globalRow = Ids[i];
238 size_t NumEntries = adjsMatrix->getNumEntriesInGlobalRow (globalRow);
239 Indices.resize (NumEntries);
240 Values.resize (NumEntries);
241 adjsMatrix->getGlobalRowCopy (globalRow,Indices(),Values(),NumEntries);
243 for (
size_t j=0; j < NumEntries; j++)
244 if (part[i] != Values[j])
248 if (numMetrics > 1) {
250 scalar_t *wgt = localBuf + nparts;
254 for (
int edim = 0; edim < ewgtDim; edim++){
255 for (lno_t i=0; i < localNumObj; i++) {
256 const gno_t globalRow = Ids[i];
257 size_t NumEntries = adjsMatrix->getNumEntriesInGlobalRow (globalRow);
258 Indices.resize (NumEntries);
259 Values.resize (NumEntries);
260 adjsMatrix->getGlobalRowCopy (globalRow,Indices(),Values(),NumEntries);
262 for (
size_t j=0; j < NumEntries; j++)
263 if (part[i] != Values[j])
264 wgt[part[i]] += wgts[edim][offsets[i] + j];
274 reduceAll<int, scalar_t>(*comm, Teuchos::REDUCE_SUM, globalSumSize,
285 scalar_t max=0, sum=0;
287 ArrayView<scalar_t> cutVec(cut, nparts);
288 getStridedStats<scalar_t>(cutVec, 1, 0, max, sum);
290 metrics[next]->setName(
"edge cuts");
291 metrics[next]->setMetricValue(
"global maximum", max);
292 metrics[next]->setMetricValue(
"global sum", sum);
297 scalar_t *wgt = sumBuf + nparts;
299 for (
int edim=0; edim < ewgtDim; edim++){
300 ArrayView<scalar_t> fromVec(wgt, nparts);
301 getStridedStats<scalar_t>(fromVec, 1, 0, max, sum);
303 std::ostringstream oss;
304 oss <<
"weight " << edim;
306 metrics[next]->setName(oss.str());
307 metrics[next]->setMetricValue(
"global maximum", max);
308 metrics[next]->setMetricValue(
"global sum", sum);
322 template <
typename scalar_t,
typename part_t>
325 os <<
"Graph Metrics: (" << numParts <<
" parts)";
327 if (targetNumParts != numParts) {
328 os <<
"Target number of parts is: " << targetNumParts << std::endl;
335 template <
typename scalar_t,
typename part_t>
338 printGraphMetricsHeader<scalar_t, part_t>(os, targetNumParts, numParts);
339 for (
int i=0; i < infoList.size(); i++) {
341 infoList[i]->printLine(os);
349 template <
typename scalar_t,
typename part_t>
352 printGraphMetricsHeader<scalar_t, part_t>(os, targetNumParts, numParts);
353 metricValue->printLine(os);
void printGraphMetrics(std::ostream &os, part_t targetNumParts, part_t numParts, const ArrayView< RCP< BaseClassMetrics< scalar_t >>> &infoList)
Print out list of graph metrics.
void globalWeightedCutsByPart(const RCP< const Environment > &env, const RCP< const Comm< int > > &comm, const RCP< const GraphModel< typename Adapter::base_adapter_t > > &graph, const ArrayView< const typename Adapter::part_t > &part, typename Adapter::part_t &numParts, ArrayRCP< RCP< BaseClassMetrics< typename Adapter::scalar_t > > > &metrics, ArrayRCP< typename Adapter::scalar_t > &globalSums)
Given the local partitioning, compute the global weighted cuts in each part.
static void printHeader(std::ostream &os)
Print a standard header.
void printGraphMetricsHeader(std::ostream &os, part_t targetNumParts, part_t numParts)
Print out header info for graph metrics.
sub-steps, each method's entry and exit
The StridedData class manages lists of weights or coordinates.
GraphModel defines the interface required for graph models.
#define Z2_THROW_OUTSIDE_ERROR(env)
Throw an error returned from outside the Zoltan2 library.
#define METRICS_UNSET_STRING