From 3e51078fb3f9cb46521259f77e8d210226b9ed0f Mon Sep 17 00:00:00 2001 From: Nick Guletskii Date: Tue, 24 Dec 2019 11:24:32 +0300 Subject: [PATCH 1/6] Add a test for floating point parsing locale invariance --- tests/python/unittest/test_operator.py | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/python/unittest/test_operator.py b/tests/python/unittest/test_operator.py index 481cd0064bfd..368a35880f50 100644 --- a/tests/python/unittest/test_operator.py +++ b/tests/python/unittest/test_operator.py @@ -34,6 +34,7 @@ from nose.tools import assert_raises, ok_ import unittest import os +import locale def check_rnn_consistency(cell1, cell2, T, N, I, H, grad_req, rtol=1e-2, atol=1e-4): dshape = (N, T, I) @@ -9973,6 +9974,33 @@ def test_broadcast_ops_on_misaligned_input_oneside(): mx.nd.waitall() assert_almost_equal(f, expected) +def test_elemwise_locale_invariance(): + arr = mx.nd.zeros((1,)) + prev = locale.getlocale(locale.LC_NUMERIC) + try: + locales_to_try = [ + "en_DK.UTF-8", # Non-standard locale that uses , as the decimal separator, installed + # on English Ubuntu by default. + "ru_RU.UTF-8", # Uses , as the decimal separator. May not be installed on the system. + "German" # A Windows locale. Uses , as the decimal separator. + ] + + locale_set = False + for loc in locales_to_try: + try: + locale.setlocale(locale.LC_NUMERIC, loc) + locale_set = True + break + except locale.Error as e: + print("Couldn't enable locale", loc, ": ", str(e)) + + assert locale_set, "Couldn't find any suitable locales for test_elemwise_locale_invariance!" + scalar = 0.3 + assert "," in locale.str(scalar) + assert_almost_equal(arr.asnumpy() + scalar, (arr + scalar).asnumpy(), rtol=1e-5, atol=1e-5) + finally: + locale.setlocale(locale.LC_NUMERIC, prev) + if __name__ == '__main__': import nose nose.runmodule() From 7e2de2f33e44d5d5e7ff2cb77c77c3c66b602da0 Mon Sep 17 00:00:00 2001 From: Nick Guletskii Date: Tue, 24 Dec 2019 11:27:32 +0300 Subject: [PATCH 2/6] Use locale-invariant dmlc:stod/stof instead of std:stod/stof --- cpp-package/include/mxnet-cpp/optimizer.h | 3 ++- cpp-package/include/mxnet-cpp/optimizer.hpp | 25 ++++++++++--------- plugin/torch/torch_function.h | 3 ++- src/nnvm/legacy_op_util.cc | 3 ++- .../contrib/gradient_multiplier_op.cc | 3 ++- src/operator/numpy/np_boolean_mask_assign.cc | 3 ++- src/operator/numpy/np_boolean_mask_assign.cu | 3 ++- .../numpy/np_elemwise_broadcast_logic_op.cc | 3 ++- .../numpy/np_elemwise_broadcast_op.cc | 3 ++- .../np_elemwise_broadcast_op_extended.cc | 17 +++++++------ src/operator/numpy/np_true_divide.cc | 5 ++-- ...kldnn_post_quantize_align_scale_property.h | 5 ++-- .../tensor/elemwise_binary_scalar_op.h | 3 ++- .../tensor/elemwise_binary_scalar_op_basic.cc | 9 ++++--- .../elemwise_binary_scalar_op_extended.cc | 15 +++++------ 15 files changed, 59 insertions(+), 44 deletions(-) diff --git a/cpp-package/include/mxnet-cpp/optimizer.h b/cpp-package/include/mxnet-cpp/optimizer.h index 320b13eebf2d..3372174d3d8f 100644 --- a/cpp-package/include/mxnet-cpp/optimizer.h +++ b/cpp-package/include/mxnet-cpp/optimizer.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "mxnet-cpp/base.h" #include "dmlc/logging.h" #include "mxnet-cpp/ndarray.h" @@ -84,7 +85,7 @@ class Optimizer { Optimizer *SetLRScheduler(std::unique_ptr lrScheduler) { CHECK(lrScheduler); lrScheduler_ = std::move(lrScheduler); - lrScheduler_->SetLR(std::stof(params_["lr"])); + lrScheduler_->SetLR(dmlc::stof(params_["lr"])); return this; } /*! diff --git a/cpp-package/include/mxnet-cpp/optimizer.hpp b/cpp-package/include/mxnet-cpp/optimizer.hpp index 26fd00f3a162..b9b52630baff 100644 --- a/cpp-package/include/mxnet-cpp/optimizer.hpp +++ b/cpp-package/include/mxnet-cpp/optimizer.hpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "mxnet-cpp/optimizer.h" #include "mxnet-cpp/op.h" #include "mxnet-cpp/op_map.h" @@ -116,11 +117,11 @@ inline float Optimizer::GetLR_(int index) { if (nullptr != lrScheduler_) { return lrScheduler_->GetLR(num_update_); } - return std::stof(params_["lr"]); + return dmlc::stof(params_["lr"]); } inline float Optimizer::GetWD_(int index) { - float wd = std::stof(params_["wd"]); + float wd = dmlc::stof(params_["wd"]); return wd; } @@ -362,9 +363,9 @@ inline void AdamOptimizer::Update(int index, NDArray weight, NDArray grad) { auto values = GetParamValues_(); CHECK_EQ(keys.size(), values.size()); - float lr = std::stof(params_["lr"]); - float b1 = std::stof(params_["beta1"]); - float b2 = std::stof(params_["beta2"]); + float lr = dmlc::stof(params_["lr"]); + float b1 = dmlc::stof(params_["beta1"]); + float b2 = dmlc::stof(params_["beta2"]); float t = count_[index]; float coef1 = 1.0f - std::pow(b1, t); float coef2 = 1.0f - std::pow(b2, t); @@ -407,15 +408,15 @@ inline void AdaGradOptimizer::Update(int index, NDArray weight, NDArray grad) { CreateState_(index, weight); } - float eps = std::stof(params_["eps"]); + float eps = dmlc::stof(params_["eps"]); float lr = GetLR_(index); float wd = GetWD_(index); UpdateCount_(index); if (params_.count("rescale_grad") > 0) { - grad *= std::stof(params_["rescale_grad"]); + grad *= dmlc::stof(params_["rescale_grad"]); } if (params_.count("clip_gradient") > 0) { - _clip(grad, std::stof(params_["clip_gradient"])); + _clip(grad, dmlc::stof(params_["clip_gradient"])); } auto& history = *history_[index]; history += grad * grad; @@ -448,16 +449,16 @@ inline void AdaDeltaOptimizer::Update(int index, NDArray weight, NDArray grad) { CreateState_(index, weight); } - float rho = std::stof(params_["rho"]); - float epsilon = std::stof(params_["epsilon"]); + float rho = dmlc::stof(params_["rho"]); + float epsilon = dmlc::stof(params_["epsilon"]); float wd = GetWD_(index); UpdateCount_(index); if (params_.count("rescale_grad") > 0) { - grad *= std::stof(params_["rescale_grad"]); + grad *= dmlc::stof(params_["rescale_grad"]); } if (params_.count("clip_gradient") > 0) { - _clip(grad, std::stof(params_["clip_gradient"])); + _clip(grad, dmlc::stof(params_["clip_gradient"])); } auto& acc_g = *acc_g_[index]; diff --git a/plugin/torch/torch_function.h b/plugin/torch/torch_function.h index f6f760231bdf..6f2e0a323b78 100644 --- a/plugin/torch/torch_function.h +++ b/plugin/torch/torch_function.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace mxnet { @@ -69,7 +70,7 @@ void TorchRunOp(std::vector arr_in, lua_pushinteger(L, std::stoi(val)); break; case 'f': - lua_pushnumber(L, std::stof(val)); + lua_pushnumber(L, dmlc::stof(val)); break; case 's': lua_pushstring(L, val.c_str()); diff --git a/src/nnvm/legacy_op_util.cc b/src/nnvm/legacy_op_util.cc index 851552a56016..f66350fff404 100644 --- a/src/nnvm/legacy_op_util.cc +++ b/src/nnvm/legacy_op_util.cc @@ -23,6 +23,7 @@ * \brief Utility to adapt OpProperty to the new NNVM registery */ #include +#include #include #include #include @@ -511,7 +512,7 @@ void RegisterLegacyNDFunc() { const std::string& name = reg->arguments[i+reg->num_use_vars].name; auto s = dict.find(name); CHECK(s != dict.end()) << "Missing scalar param " << name; - scalars.push_back(std::stof(s->second)); + scalars.push_back(dmlc::stof(s->second)); dict.erase(s); } diff --git a/src/operator/contrib/gradient_multiplier_op.cc b/src/operator/contrib/gradient_multiplier_op.cc index 47f891ef802b..0a49ec1c36b3 100644 --- a/src/operator/contrib/gradient_multiplier_op.cc +++ b/src/operator/contrib/gradient_multiplier_op.cc @@ -23,6 +23,7 @@ * \brief * \author Istvan Fehervari */ +#include #include "../tensor/elemwise_unary_op.h" #include "../tensor/elemwise_binary_scalar_op.h" @@ -77,7 +78,7 @@ multiplies the gradient from the subsequent level by a scalar factor lambda and the preceding layer. )code" ADD_FILELINE) .set_attr_parser([](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FInferStorageType", ElemwiseStorageType<1, 1, false, true, true>) .set_attr("FCompute", UnaryOp::IdentityCompute) diff --git a/src/operator/numpy/np_boolean_mask_assign.cc b/src/operator/numpy/np_boolean_mask_assign.cc index e01ebb7c6c24..ef7cce4d2491 100644 --- a/src/operator/numpy/np_boolean_mask_assign.cc +++ b/src/operator/numpy/np_boolean_mask_assign.cc @@ -22,6 +22,7 @@ * \brief CPU implementation of Boolean Mask Assign */ +#include #include "../../common/utils.h" #include "../contrib/boolean_mask-inl.h" @@ -272,7 +273,7 @@ void NumpyBooleanAssignForwardCPU(const nnvm::NodeAttrs& attrs, MSHADOW_TYPE_SWITCH_WITH_BOOL(data.type_flag_, DType, { Kernel, cpu>::Launch( s, valid_num, data.dptr(), prefix_sum.data(), prefix_sum.size(), - leading, middle, trailing, static_cast(std::stod(attrs.dict.at("value")))); + leading, middle, trailing, static_cast(dmlc::stod(attrs.dict.at("value")))); }); } } diff --git a/src/operator/numpy/np_boolean_mask_assign.cu b/src/operator/numpy/np_boolean_mask_assign.cu index e1e645268565..6fa59bea7710 100644 --- a/src/operator/numpy/np_boolean_mask_assign.cu +++ b/src/operator/numpy/np_boolean_mask_assign.cu @@ -23,6 +23,7 @@ */ #include +#include #include "../../common/utils.h" #include "../contrib/boolean_mask-inl.h" @@ -252,7 +253,7 @@ void NumpyBooleanAssignForwardGPU(const nnvm::NodeAttrs& attrs, } } else { CHECK(attrs.dict.find("value") != attrs.dict.end()) << "value is not provided"; - double value = std::stod(attrs.dict.at("value")); + double value = dmlc::stod(attrs.dict.at("value")); MSHADOW_TYPE_SWITCH_WITH_BOOL(data.type_flag_, DType, { Kernel, gpu>::Launch( s, leading * valid_num * trailing, data.dptr(), prefix_sum, mask_size + 1, diff --git a/src/operator/numpy/np_elemwise_broadcast_logic_op.cc b/src/operator/numpy/np_elemwise_broadcast_logic_op.cc index 8395cafd119a..74db52d33f03 100644 --- a/src/operator/numpy/np_elemwise_broadcast_logic_op.cc +++ b/src/operator/numpy/np_elemwise_broadcast_logic_op.cc @@ -30,6 +30,7 @@ #include "../tvmop/op_module.h" #endif // MXNET_USE_TVM_OP +#include #include "../tensor/elemwise_binary_broadcast_op.h" #include "../tensor/elemwise_binary_scalar_op.h" @@ -225,7 +226,7 @@ struct TVMBinaryBroadcastScalarCompute { .set_num_inputs(1) \ .set_num_outputs(1) \ .set_attr_parser([](NodeAttrs* attrs) { \ - attrs->parsed = std::stod(attrs->dict["scalar"]); \ + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); \ }) \ .set_attr("FListInputNames", \ [](const NodeAttrs& attrs) { \ diff --git a/src/operator/numpy/np_elemwise_broadcast_op.cc b/src/operator/numpy/np_elemwise_broadcast_op.cc index 6409d4322a27..ae285caa9094 100644 --- a/src/operator/numpy/np_elemwise_broadcast_op.cc +++ b/src/operator/numpy/np_elemwise_broadcast_op.cc @@ -23,6 +23,7 @@ * \brief CPU Implementation of basic functions for elementwise numpy binary broadcast operator. */ +#include #include "./np_elemwise_broadcast_op.h" namespace mxnet { @@ -33,7 +34,7 @@ namespace op { .set_num_inputs(1) \ .set_num_outputs(1) \ .set_attr_parser([](NodeAttrs* attrs) { \ - attrs->parsed = std::stod(attrs->dict["scalar"]); \ + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); \ }) \ .set_attr("FInferShape", ElemwiseShape<1, 1>) \ .set_attr("FInferType", NumpyBinaryScalarType) \ diff --git a/src/operator/numpy/np_elemwise_broadcast_op_extended.cc b/src/operator/numpy/np_elemwise_broadcast_op_extended.cc index 70233a596dc7..52d681885d82 100644 --- a/src/operator/numpy/np_elemwise_broadcast_op_extended.cc +++ b/src/operator/numpy/np_elemwise_broadcast_op_extended.cc @@ -23,6 +23,7 @@ * \brief CPU Implementation of extended functions for elementwise numpy binary broadcast operator. */ +#include #include "../../common/utils.h" #include "./np_elemwise_broadcast_op.h" @@ -34,7 +35,7 @@ namespace op { .set_num_inputs(1) \ .set_num_outputs(1) \ .set_attr_parser([](NodeAttrs* attrs) { \ - attrs->parsed = std::stod(attrs->dict["scalar"]); \ + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); \ }) \ .set_attr("FInferShape", ElemwiseShape<1, 1>) \ .set_attr("FInferType", NumpyBinaryScalarType) \ @@ -87,7 +88,7 @@ NNVM_REGISTER_OP(_npi_lcm_scalar) .set_num_inputs(1) .set_num_outputs(1) .set_attr_parser([](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FInferShape", ElemwiseShape<1, 1>) .set_attr("FInferType", ElemwiseIntType<1, 1>) @@ -175,7 +176,7 @@ NNVM_REGISTER_OP(_npi_bitwise_xor_scalar) .set_num_inputs(1) .set_num_outputs(1) .set_attr_parser([](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FInferShape", ElemwiseShape<1, 1>) .set_attr("FInferType", ElemwiseIntType<1, 1>) @@ -192,7 +193,7 @@ NNVM_REGISTER_OP(_npi_bitwise_or_scalar) .set_num_inputs(1) .set_num_outputs(1) .set_attr_parser([](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FInferShape", ElemwiseShape<1, 1>) .set_attr("FInferType", ElemwiseIntType<1, 1>) @@ -275,13 +276,13 @@ MXNET_OPERATOR_REGISTER_NP_BINARY_SCALAR(_npi_rarctan2_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_npi_arctan2_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward); MXNET_OPERATOR_REGISTER_BINARY(_backward_npi_rarctan2_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward); @@ -363,12 +364,12 @@ NNVM_REGISTER_OP(_backward_npi_ldexp) MXNET_OPERATOR_REGISTER_BINARY(_backward_npi_ldexp_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward); MXNET_OPERATOR_REGISTER_BINARY(_backward_npi_rldexp_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward); } // namespace op diff --git a/src/operator/numpy/np_true_divide.cc b/src/operator/numpy/np_true_divide.cc index 1e46cc9d13b5..6edfb4dd0901 100644 --- a/src/operator/numpy/np_true_divide.cc +++ b/src/operator/numpy/np_true_divide.cc @@ -23,6 +23,7 @@ * \brief CPU Implementation of true_divide operator. */ +#include #include "./np_true_divide-inl.h" namespace mxnet { @@ -88,7 +89,7 @@ NNVM_REGISTER_OP(_npi_true_divide_scalar) .set_num_inputs(1) .set_num_outputs(1) .set_attr_parser([](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FInferShape", ElemwiseShape<1, 1>) .set_attr("FInferType", TrueDivideType<1>) @@ -111,7 +112,7 @@ NNVM_REGISTER_OP(_npi_rtrue_divide_scalar) .set_num_inputs(1) .set_num_outputs(1) .set_attr_parser([](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FInferShape", ElemwiseShape<1, 1>) .set_attr("FInferType", TrueDivideType<1>) diff --git a/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h b/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h index c05c2a8e4a6a..69c8bb515fe9 100644 --- a/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h +++ b/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h @@ -23,6 +23,7 @@ #include #include +#include #include "../common.h" #include "mkldnn_subgraph_base-inl.h" @@ -146,8 +147,8 @@ class SgMKLDNNPostQuantizeAlignScaleProperty : public SubgraphProperty { float min_calib = 0.0f; float max_calib = 0.0f; for (size_t i = 0; i < subgraph_nodes.size(); ++i) { - auto this_min_calib = std::stof(subgraph_nodes[i]->attrs.dict["min_calib_range"]); - auto this_max_calib = std::stof(subgraph_nodes[i]->attrs.dict["max_calib_range"]); + auto this_min_calib = dmlc::stof(subgraph_nodes[i]->attrs.dict["min_calib_range"]); + auto this_max_calib = dmlc::stof(subgraph_nodes[i]->attrs.dict["max_calib_range"]); if (min_calib > this_min_calib) min_calib = this_min_calib; if (max_calib < this_max_calib) max_calib = this_max_calib; } diff --git a/src/operator/tensor/elemwise_binary_scalar_op.h b/src/operator/tensor/elemwise_binary_scalar_op.h index f974332252d8..f00f22c0e680 100644 --- a/src/operator/tensor/elemwise_binary_scalar_op.h +++ b/src/operator/tensor/elemwise_binary_scalar_op.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "../mshadow_op.h" #include "../elemwise_op_common.h" #include "elemwise_unary_op.h" @@ -400,7 +401,7 @@ class BinaryScalarOp : public UnaryOp { .set_num_inputs(1) \ .set_num_outputs(1) \ .set_attr_parser([](NodeAttrs* attrs) { \ - attrs->parsed = std::stod(attrs->dict["scalar"]); \ + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); \ }) \ .set_attr("FInferShape", ElemwiseShape<1, 1>) \ .set_attr("FInferType", ElemwiseType<1, 1>) \ diff --git a/src/operator/tensor/elemwise_binary_scalar_op_basic.cc b/src/operator/tensor/elemwise_binary_scalar_op_basic.cc index ae356deff0a1..13014b35c2fe 100644 --- a/src/operator/tensor/elemwise_binary_scalar_op_basic.cc +++ b/src/operator/tensor/elemwise_binary_scalar_op_basic.cc @@ -22,6 +22,7 @@ * \file elemwise_binary_scalar_op_basic.cc * \brief CPU Implementation of basic binary scalar functions. */ +#include #include "../../common/utils.h" #include "./elemwise_binary_op.h" #include "./elemwise_binary_scalar_op.h" @@ -31,7 +32,7 @@ .set_num_inputs(1) \ .set_num_outputs(1) \ .set_attr_parser([](NodeAttrs* attrs) { \ - attrs->parsed = std::stod(attrs->dict["scalar"]); \ + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); \ }) \ .set_attr("FInferShape", ElemwiseShape<1, 1>) \ .set_attr("FInferType", ElemwiseType<1, 1>) \ @@ -189,7 +190,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_rdiv_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_rdiv_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward< cpu, mshadow_op::rdiv_grad>); @@ -200,7 +201,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_mod_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_mod_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward< cpu, mshadow_op::mod_grad>); @@ -211,7 +212,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_rmod_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_rmod_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward< cpu, mshadow_op::rmod_grad>); diff --git a/src/operator/tensor/elemwise_binary_scalar_op_extended.cc b/src/operator/tensor/elemwise_binary_scalar_op_extended.cc index 4ada2f036f7d..7dd8cf41c59e 100644 --- a/src/operator/tensor/elemwise_binary_scalar_op_extended.cc +++ b/src/operator/tensor/elemwise_binary_scalar_op_extended.cc @@ -22,6 +22,7 @@ * \file elemwise_binary_scalar_op_extended.cc * \brief CPU Implementation of extended binary scalar functions. */ +#include #include "./elemwise_unary_op.h" #include "./elemwise_binary_op.h" #include "./elemwise_binary_scalar_op.h" @@ -36,7 +37,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_maximum_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_maximum_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward); MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_minimum_scalar) @@ -47,7 +48,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_minimum_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_minimum_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward); MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_power_scalar) @@ -57,7 +58,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_power_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_power_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward< cpu, mshadow_op::power_grad>); @@ -69,7 +70,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_rpower_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_rpower_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward< cpu, mshadow_op::rpower_grad>); @@ -82,7 +83,7 @@ MXNET_OPERATOR_REGISTER_BINARY_SCALAR(_hypot_scalar) MXNET_OPERATOR_REGISTER_BINARY(_backward_hypot_scalar) .add_argument("scalar", "float", "scalar value") -.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = std::stod(attrs->dict["scalar"]); }) +.set_attr_parser([](NodeAttrs *attrs) { attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) .set_attr("FCompute", BinaryScalarOp::Backward< cpu, mshadow_op::hypot_grad_left>); @@ -110,7 +111,7 @@ Example:: .set_num_outputs(1) .set_attr_parser([](NodeAttrs* attrs) { if (attrs->dict.find("scalar") != attrs->dict.end()) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); } else { attrs->parsed = 1.0; } @@ -129,7 +130,7 @@ Example:: MXNET_OPERATOR_REGISTER_BINARY(_backward_smooth_l1) .set_attr_parser([](NodeAttrs *attrs) { if (attrs->dict.find("scalar") != attrs->dict.end()) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); } else { attrs->parsed = 1.0; } From c93a01b380b6c9f5295d51553a51563b33c1d45a Mon Sep 17 00:00:00 2001 From: Nick Guletskii Date: Tue, 24 Dec 2019 11:28:11 +0300 Subject: [PATCH 3/6] Change the new operator tutorial to use dmlc:stod instead of std::stod --- docs/static_site/src/pages/api/faq/new_op.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/static_site/src/pages/api/faq/new_op.md b/docs/static_site/src/pages/api/faq/new_op.md index 787b4038dbf4..053182b79805 100644 --- a/docs/static_site/src/pages/api/faq/new_op.md +++ b/docs/static_site/src/pages/api/faq/new_op.md @@ -204,7 +204,7 @@ Simple arguments can be parsed like NNVM_REGISTER_OP(scalar_op) .set_attr_parser( [](NodeAttrs* attrs) { - attrs->parsed = std::stod(attrs->dict["scalar"]); + attrs->parsed = dmlc::stod(attrs->dict["scalar"]); }) ``` From 60eed501c7740cf1199da7059480a6134cdc8475 Mon Sep 17 00:00:00 2001 From: Nick Guletskii Date: Tue, 24 Dec 2019 12:22:02 +0300 Subject: [PATCH 4/6] Rename locale invariance test --- tests/python/unittest/test_operator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/python/unittest/test_operator.py b/tests/python/unittest/test_operator.py index 368a35880f50..190551912c8d 100644 --- a/tests/python/unittest/test_operator.py +++ b/tests/python/unittest/test_operator.py @@ -9974,7 +9974,7 @@ def test_broadcast_ops_on_misaligned_input_oneside(): mx.nd.waitall() assert_almost_equal(f, expected) -def test_elemwise_locale_invariance(): +def test_scalarop_locale_invariance(): arr = mx.nd.zeros((1,)) prev = locale.getlocale(locale.LC_NUMERIC) try: From 41e0ee4363345a54591580c7921c7cd51c15361b Mon Sep 17 00:00:00 2001 From: Nick Guletskii Date: Fri, 27 Dec 2019 00:28:28 +0300 Subject: [PATCH 5/6] Skip test_scalarop_locale_invariance if the locales aren't available --- tests/python/unittest/test_operator.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/python/unittest/test_operator.py b/tests/python/unittest/test_operator.py index 190551912c8d..e22d529eeb41 100644 --- a/tests/python/unittest/test_operator.py +++ b/tests/python/unittest/test_operator.py @@ -9994,10 +9994,20 @@ def test_scalarop_locale_invariance(): except locale.Error as e: print("Couldn't enable locale", loc, ": ", str(e)) - assert locale_set, "Couldn't find any suitable locales for test_elemwise_locale_invariance!" - scalar = 0.3 - assert "," in locale.str(scalar) - assert_almost_equal(arr.asnumpy() + scalar, (arr + scalar).asnumpy(), rtol=1e-5, atol=1e-5) + if locale_set: + scalar = 0.3 + assert "," in locale.str(scalar) + assert_almost_equal( + arr.asnumpy() + scalar, + (arr + scalar).asnumpy(), + rtol=1e-5, + atol=1e-5 + ) + else: + # Shouldn't happen on Windows: "German" should always be available. + raise unittest.SkipTest("Couldn't find a locale suitable for " + "test_scalarop_locale_invariance. Please install en_DK.UTF-8 " + "or ru_RU.UTF-8 to run this test.") finally: locale.setlocale(locale.LC_NUMERIC, prev) From a821e5d3b93f402b5d57d6d8b411733fd90e83e1 Mon Sep 17 00:00:00 2001 From: Nick Guletskii Date: Fri, 27 Dec 2019 12:15:35 +0300 Subject: [PATCH 6/6] Fix linter errors due to incorrect include order --- cpp-package/include/mxnet-cpp/optimizer.h | 2 +- cpp-package/include/mxnet-cpp/optimizer.hpp | 2 +- plugin/torch/torch_function.h | 2 +- .../subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h | 2 +- src/operator/tensor/elemwise_binary_scalar_op.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp-package/include/mxnet-cpp/optimizer.h b/cpp-package/include/mxnet-cpp/optimizer.h index 3372174d3d8f..ac842874fea6 100644 --- a/cpp-package/include/mxnet-cpp/optimizer.h +++ b/cpp-package/include/mxnet-cpp/optimizer.h @@ -27,12 +27,12 @@ #ifndef MXNET_CPP_OPTIMIZER_H_ #define MXNET_CPP_OPTIMIZER_H_ +#include #include #include #include #include #include -#include #include "mxnet-cpp/base.h" #include "dmlc/logging.h" #include "mxnet-cpp/ndarray.h" diff --git a/cpp-package/include/mxnet-cpp/optimizer.hpp b/cpp-package/include/mxnet-cpp/optimizer.hpp index b9b52630baff..f3c71df24c59 100644 --- a/cpp-package/include/mxnet-cpp/optimizer.hpp +++ b/cpp-package/include/mxnet-cpp/optimizer.hpp @@ -26,6 +26,7 @@ #ifndef MXNET_CPP_OPTIMIZER_HPP_ #define MXNET_CPP_OPTIMIZER_HPP_ +#include #include #include #include @@ -33,7 +34,6 @@ #include #include #include -#include #include "mxnet-cpp/optimizer.h" #include "mxnet-cpp/op.h" #include "mxnet-cpp/op_map.h" diff --git a/plugin/torch/torch_function.h b/plugin/torch/torch_function.h index 6f2e0a323b78..6a33e706ff2f 100644 --- a/plugin/torch/torch_function.h +++ b/plugin/torch/torch_function.h @@ -28,13 +28,13 @@ #include "./torch_base.h" #include #include +#include #include #include #include #include #include #include -#include namespace mxnet { diff --git a/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h b/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h index 69c8bb515fe9..85691c19993b 100644 --- a/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h +++ b/src/operator/subgraph/mkldnn/mkldnn_post_quantize_align_scale_property.h @@ -21,9 +21,9 @@ #define MXNET_OPERATOR_SUBGRAPH_MKLDNN_MKLDNN_POST_QUANTIZE_ALIGN_SCALE_PROPERTY_H_ #if MXNET_USE_MKLDNN == 1 +#include #include #include -#include #include "../common.h" #include "mkldnn_subgraph_base-inl.h" diff --git a/src/operator/tensor/elemwise_binary_scalar_op.h b/src/operator/tensor/elemwise_binary_scalar_op.h index f00f22c0e680..53161ee2354f 100644 --- a/src/operator/tensor/elemwise_binary_scalar_op.h +++ b/src/operator/tensor/elemwise_binary_scalar_op.h @@ -26,9 +26,9 @@ #define MXNET_OPERATOR_TENSOR_ELEMWISE_BINARY_SCALAR_OP_H_ #include +#include #include #include -#include #include "../mshadow_op.h" #include "../elemwise_op_common.h" #include "elemwise_unary_op.h"