Handle zero norm values in LpNormalization CPU kernel (#5251)

This commit is contained in:
Hariharan Seshadri 2020-09-22 22:01:09 -07:00 committed by GitHub
parent d26c71f55c
commit 75d994f194
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 2 deletions

View file

@ -25,10 +25,14 @@ void DoNormalizeP2(
for (int i = 0; i < n; ++i) {
auto base = (i / sf) * sf * m + (i % sf);
ConstStridedVec xVec(xData + base, 1, m, InnerStride(sf));
StridedVec yVec(yData + base, 1, m, InnerStride(sf));
auto norm = xVec.template lpNorm<2>();
if (norm != 0) {
StridedVec yVec(yData + base, 1, m, InnerStride(sf));
yVec = xVec / norm;
} else {
// norm is zero, so set the result to zero
yVec.setZero();
}
}
};
@ -42,10 +46,14 @@ void DoNormalizeP1(
for (int i = 0; i < n; ++i) {
auto base = (i / sf) * sf * m + (i % sf);
ConstStridedVec xVec(xData + base, 1, m, InnerStride(sf));
StridedVec yVec(yData + base, 1, m, InnerStride(sf));
auto norm = xVec.template lpNorm<1>();
if (norm != 0) {
StridedVec yVec(yData + base, 1, m, InnerStride(sf));
yVec = xVec / norm;
} else {
// norm is zero - set the result to zero
yVec.setZero();
}
}
};

View file

@ -107,5 +107,34 @@ TEST(LpNormalizationTest, L1NormalizationWithValidNegativeAxis) {
test.Run();
}
TEST(LpNormalizationTest, L1NormalizationWithZeroNorm) {
OpTester test("LpNormalization");
test.AddAttribute("p", static_cast<int64_t>(1));
// With default axis (axis = -1), one of the norms will be evaluated to zero
// for the following input
vector<float> input = {2.f, 2.f, 0.f, 0.f};
vector<int64_t> input_dims = {2, 2};
test.AddInput<float>("input", input_dims, input);
vector<float> expected_output = {0.5f, 0.5f, 0.f, 0.f};
test.AddOutput<float>("Y", input_dims, expected_output);
test.Run();
}
TEST(LpNormalizationTest, L2NormalizationWithZeroNorm) {
OpTester test("LpNormalization");
// With default axis (axis = -1), one of the norms will be evaluated to zero
// for the following input
vector<float> input = {1.f, 0.f, 0.f, 0.f};
vector<int64_t> input_dims = {2, 2};
test.AddInput<float>("input", input_dims, input);
vector<float> expected_output = {1.f, 0.f, 0.f, 0.f};
test.AddOutput<float>("Y", input_dims, expected_output);
test.Run();
}
} // namespace test
} // namespace onnxruntime