From 890cb78b2022ad1fe702de8f1484f1ebdc1cb871 Mon Sep 17 00:00:00 2001 From: Scott McKay Date: Fri, 13 Mar 2020 20:27:25 +1000 Subject: [PATCH] Use Eigen::logistic instead of manually computing values. (#3186) * Use MlasComputeLogistic instead of manually computing values. * Update test script to allow the tolerance to be specified when checking float output from logreg_iris.onnx. --- onnxruntime/core/providers/cpu/ml/ml_common.h | 7 +++---- onnxruntime/core/util/math_cpuonly.h | 1 - .../python/onnxruntime_test_python_backend.py | 21 +++++++++++++++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/onnxruntime/core/providers/cpu/ml/ml_common.h b/onnxruntime/core/providers/cpu/ml/ml_common.h index 4d6884ed4a..3db2976a87 100644 --- a/onnxruntime/core/providers/cpu/ml/ml_common.h +++ b/onnxruntime/core/providers/cpu/ml/ml_common.h @@ -5,7 +5,9 @@ #include "core/common/common.h" #include "core/common/safeint.h" #include "core/framework/op_kernel.h" +#include "core/util/math.h" #include "core/util/math_cpuonly.h" +#include "core/mlas/inc/mlas.h" #include "core/platform/threadpool.h" namespace onnxruntime { @@ -390,10 +392,7 @@ void batched_update_scores_inplace(gsl::span scores, int64_t num_batches_in, break; } case POST_EVAL_TRANSFORM::LOGISTIC: { - while (s < s_end) { - *s = ComputeLogistic(*s); - ++s; - } + MlasComputeLogistic(s, s, scores.size()); break; } case POST_EVAL_TRANSFORM::SOFTMAX: { diff --git a/onnxruntime/core/util/math_cpuonly.h b/onnxruntime/core/util/math_cpuonly.h index a6d5199dee..e46cd55aea 100644 --- a/onnxruntime/core/util/math_cpuonly.h +++ b/onnxruntime/core/util/math_cpuonly.h @@ -87,7 +87,6 @@ auto EigenMap(Tensor& t) -> EigenVectorMap { } template auto EigenMap(const Tensor& t) -> ConstEigenVectorMap { - return ConstEigenVectorMap(t.template Data(), t.Shape().Size()); } diff --git a/onnxruntime/test/python/onnxruntime_test_python_backend.py b/onnxruntime/test/python/onnxruntime_test_python_backend.py index d1ed383cf8..4c7922afbd 100644 --- a/onnxruntime/test/python/onnxruntime_test_python_backend.py +++ b/onnxruntime/test/python/onnxruntime_test_python_backend.py @@ -13,6 +13,21 @@ from onnxruntime.backend.backend import OnnxRuntimeBackend as ort_backend from onnx import load +def check_list_of_map_to_float(testcase, expected_rows, actual_rows): + """Validate two list> instances match closely enough.""" + + num_rows = len(expected_rows) + sorted_keys = sorted(expected_rows[0].keys()) + testcase.assertEqual(num_rows, len(actual_rows)) + testcase.assertEqual(sorted_keys, sorted(actual_rows[0].keys())) + + for i in range(num_rows): + # use np.testing.assert_allclose so we can specify the tolerance + np.testing.assert_allclose([expected_rows[i][key] for key in sorted_keys], + [actual_rows[i][key] for key in sorted_keys], + rtol=1e-05, atol=1e-07) + + class TestBackend(unittest.TestCase): def get_name(self, name): @@ -56,7 +71,8 @@ class TestBackend(unittest.TestCase): output_expected = [{0: 0.950599730014801, 1: 0.027834169566631317, 2: 0.02156602405011654}, {0: 0.9974970817565918, 1: 5.6299926654901356e-05, 2: 0.0024466661270707846}, {0: 0.9997311234474182, 1: 1.1918064757310276e-07, 2: 0.00026869276189245284}] - self.assertEqual(output_expected, res[1]) + + check_list_of_map_to_float(self, output_expected, res[1]) def testRunModelProtoApi(self): name = datasets.get_example("logreg_iris.onnx") @@ -70,7 +86,8 @@ class TestBackend(unittest.TestCase): output_expected = [{0: 0.950599730014801, 1: 0.027834169566631317, 2: 0.02156602405011654}, {0: 0.9974970817565918, 1: 5.6299926654901356e-05, 2: 0.0024466661270707846}, {0: 0.9997311234474182, 1: 1.1918064757310276e-07, 2: 0.00026869276189245284}] - self.assertEqual(output_expected, outputs[1]) + + check_list_of_map_to_float(self, output_expected, outputs[1]) if __name__ == '__main__':