YARN-9019. Ratio calculation of ResourceCalculator implementations could return NaN. (Contributed by Szilard Nemeth)
This commit is contained in:
parent
b3c75c1f1d
commit
912b1f9d64
|
@ -57,7 +57,7 @@ public class DefaultResourceCalculator extends ResourceCalculator {
|
|||
|
||||
@Override
|
||||
public float ratio(Resource a, Resource b) {
|
||||
return (float)a.getMemorySize() / b.getMemorySize();
|
||||
return divideSafelyAsFloat(a.getMemorySize(), b.getMemorySize());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -379,8 +379,8 @@ public class DominantResourceCalculator extends ResourceCalculator {
|
|||
for (int i = 0; i < maxLength; i++) {
|
||||
ResourceInformation aResourceInformation = a.getResourceInformation(i);
|
||||
ResourceInformation bResourceInformation = b.getResourceInformation(i);
|
||||
float tmp = (float) aResourceInformation.getValue()
|
||||
/ (float) bResourceInformation.getValue();
|
||||
final float tmp = divideSafelyAsFloat(aResourceInformation.getValue(),
|
||||
bResourceInformation.getValue());
|
||||
ratio = ratio > tmp ? ratio : tmp;
|
||||
}
|
||||
return ratio;
|
||||
|
|
|
@ -87,6 +87,24 @@ public abstract class ResourceCalculator {
|
|||
return (long) Math.ceil(a/b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides lhs by rhs.
|
||||
* If both lhs and rhs are having a value of 0, then we return 0.
|
||||
* This is to avoid division by zero and return NaN as a result.
|
||||
* If lhs is zero but rhs is not, Float.infinity will be returned
|
||||
* as the result.
|
||||
* @param lhs
|
||||
* @param rhs
|
||||
* @return
|
||||
*/
|
||||
public static float divideSafelyAsFloat(long lhs, long rhs) {
|
||||
if (lhs == 0 && rhs == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return (float) lhs / (float) rhs;
|
||||
}
|
||||
}
|
||||
|
||||
public static int roundUp(int a, int b) {
|
||||
return divideAndCeil(a, b) * b;
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ import static org.junit.Assert.assertEquals;
|
|||
public class TestResourceCalculator {
|
||||
private final ResourceCalculator resourceCalculator;
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<ResourceCalculator[]> getParameters() {
|
||||
return Arrays.asList(new ResourceCalculator[][] {
|
||||
{ new DefaultResourceCalculator() },
|
||||
{ new DominantResourceCalculator() } });
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
public static Collection<Object[]> getParameters() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ "DefaultResourceCalculator", new DefaultResourceCalculator() },
|
||||
{ "DominantResourceCalculator", new DominantResourceCalculator() } });
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -57,7 +57,7 @@ public class TestResourceCalculator {
|
|||
ResourceUtils.resetResourceTypes(conf);
|
||||
}
|
||||
|
||||
public TestResourceCalculator(ResourceCalculator rs) {
|
||||
public TestResourceCalculator(String name, ResourceCalculator rs) {
|
||||
this.resourceCalculator = rs;
|
||||
}
|
||||
|
||||
|
@ -392,4 +392,18 @@ public class TestResourceCalculator {
|
|||
assertEquals(2, result.getVirtualCores());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDivisionByZeroRatioDenominatorIsZero() {
|
||||
float ratio = resourceCalculator.ratio(newResource(1, 1), newResource(0,
|
||||
0));
|
||||
assertEquals(Float.POSITIVE_INFINITY, ratio, 0.00001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDivisionByZeroRatioNumeratorAndDenominatorIsZero() {
|
||||
float ratio = resourceCalculator.ratio(newResource(0, 0), newResource(0,
|
||||
0));
|
||||
assertEquals(0.0, ratio, 0.00001);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue