From a0a6dfb19dce0a848474c9b3fd6dd50ff2df039a Mon Sep 17 00:00:00 2001 From: graham Date: Wed, 22 Jun 2011 17:33:04 +0100 Subject: [PATCH] ENH: Prevent overflow in weight field. --- .../decompose/ptscotchDecomp/ptscotchDecomp.C | 33 +++++++++++++++++-- .../decompose/scotchDecomp/scotchDecomp.C | 14 +++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C index 655b58fde1..833cb5d461 100644 --- a/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C +++ b/src/parallel/decompose/ptscotchDecomp/ptscotchDecomp.C @@ -483,8 +483,10 @@ if (debug) // Check for externally provided cellweights and if so initialise weights + scalar minWeights = gMin(cWeights); - if (cWeights.size() > 0) + + if (!cWeights.empty()) { if (minWeights <= 0) { @@ -504,12 +506,39 @@ if (debug) << " does not equal number of cells " << xadj.size()-1 << exit(FatalError); } + } + scalar velotabSum = gSum(cWeights)/minWeights; + + scalar rangeScale(1.0); + + if (Pstream::master()) + { + if (velotabSum > scalar(INT_MAX - 1)) + { + // 0.9 factor of safety to avoid floating point round-off in + // rangeScale tipping the subsequent sum over the integer limit. + rangeScale = 0.9*scalar(INT_MAX - 1)/velotabSum; + + WarningIn + ( + "ptscotchDecomp::decompose(...)" + ) << "Sum of weights has overflowed integer: " << velotabSum + << ", compressing weight scale by a factor of " << rangeScale + << endl; + } + } + + Pstream::scatter(rangeScale); + + if (!cWeights.empty()) + { // Convert to integers. velotab.setSize(cWeights.size()); + forAll(velotab, i) { - velotab[i] = int(cWeights[i]/minWeights); + velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1; } } diff --git a/src/parallel/decompose/scotchDecomp/scotchDecomp.C b/src/parallel/decompose/scotchDecomp/scotchDecomp.C index 0851431b96..dfc6e1c421 100644 --- a/src/parallel/decompose/scotchDecomp/scotchDecomp.C +++ b/src/parallel/decompose/scotchDecomp/scotchDecomp.C @@ -386,14 +386,13 @@ Foam::label Foam::scotchDecomp::decomposeOneProc // Check for externally provided cellweights and if so initialise weights // Note: min, not gMin since routine runs on master only. scalar minWeights = min(cWeights); - if (cWeights.size() > 0) + if (!cWeights.empty()) { if (minWeights <= 0) { WarningIn ( - "scotchDecomp::decompose" - "(const pointField&, const scalarField&)" + "scotchDecomp::decompose(...)" ) << "Illegal minimum weight " << minWeights << endl; } @@ -402,8 +401,7 @@ Foam::label Foam::scotchDecomp::decomposeOneProc { FatalErrorIn ( - "scotchDecomp::decompose" - "(const pointField&, const scalarField&)" + "scotchDecomp::decompose(...)" ) << "Number of cell weights " << cWeights.size() << " does not equal number of cells " << xadj.size()-1 << exit(FatalError); @@ -421,8 +419,7 @@ Foam::label Foam::scotchDecomp::decomposeOneProc WarningIn ( - "scotchDecomp::decompose" - "(const pointField&, const scalarField&)" + "scotchDecomp::decompose(...)" ) << "Sum of weights has overflowed integer: " << velotabSum << ", compressing weight scale by a factor of " << rangeScale << endl; @@ -433,8 +430,7 @@ Foam::label Foam::scotchDecomp::decomposeOneProc forAll(velotab, i) { - velotab[i] = - int((cWeights[i]/minWeights - 1)*rangeScale) + 1; + velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1; } }