You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by cj...@apache.org on 2017/11/04 03:29:09 UTC
[incubator-mxnet] branch master updated: Fix for issue #8491,
elemwise_mul nan behavior (#8492)
This is an automated email from the ASF dual-hosted git repository.
cjolivier01 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new 52d809c Fix for issue #8491, elemwise_mul nan behavior (#8492)
52d809c is described below
commit 52d809c9288e70927534dc783c439dfd65df7de7
Author: Chris Olivier <cj...@gmail.com>
AuthorDate: Fri Nov 3 20:29:06 2017 -0700
Fix for issue #8491, elemwise_mul nan behavior (#8492)
* Fix for issue #8491, elemwise_mul nan behavior
https://github.com/apache/incubator-mxnet/issues/8491
* Also make nan * 0 -> dense
* Also make nan * 0 -> dense
* Add Scala package dev tools for deploy (#8498)
* [scala] do not print op definition during compiling by default
* [scala] add dev tools for changing artifactId
* [scala] add scala make clean
* Getting read of maybe_uninitialized warnings (#8318)
* Fix of log10_grad, log2_grad (#8502)
* add default hash to ndarray (#8476)
* bump up version (#8488)
* fix makenonlossgrad bug (#8508)
* fix expand_dims if axis< 0 (#8489)
* fix expand_dims if axis< 0
* Update test_operator.py
* Correct Initialization Description in Finetune Tutorial. (#8517)
* Trigger rebuild
---
src/operator/tensor/elemwise_binary_op.cc | 45 ------------------------
src/operator/tensor/elemwise_binary_op.h | 46 ++++++++++++++++++++++++-
src/operator/tensor/elemwise_binary_op_basic.cc | 7 ++--
tests/python/unittest/test_sparse_operator.py | 11 ++++--
4 files changed, 57 insertions(+), 52 deletions(-)
diff --git a/src/operator/tensor/elemwise_binary_op.cc b/src/operator/tensor/elemwise_binary_op.cc
index 00c5e10..931132b 100644
--- a/src/operator/tensor/elemwise_binary_op.cc
+++ b/src/operator/tensor/elemwise_binary_op.cc
@@ -86,50 +86,5 @@ bool ElemwiseBinaryOp::BackwardUseInStorageType(const nnvm::NodeAttrs& attrs,
return true;
}
-bool ElemwiseBinaryOp::AllowLRDenseInputWithSparseOutputStorageType(const nnvm::NodeAttrs& attrs,
- const int dev_mask,
- DispatchMode* dispatch_mode,
- std::vector<int> *in_attrs,
- std::vector<int> *out_attrs) {
- CHECK_EQ(in_attrs->size(), 2U) << " in operator " << attrs.name;
- CHECK_EQ(out_attrs->size(), 1U) << " in operator " << attrs.name;
- const auto& lhs_stype = in_attrs->at(0);
- const auto& rhs_stype = in_attrs->at(1);
- auto& out_stype = out_attrs->at(0);
- bool dispatched = false;
- const bool invalid_ctx = dev_mask != mshadow::cpu::kDevMask;
- const auto dispatch_ex = invalid_ctx ? DispatchMode::kFComputeFallback :
- DispatchMode::kFComputeEx;
- if (!dispatched && lhs_stype == kDefaultStorage && rhs_stype == kDefaultStorage) {
- // dns, dns -> dns
- dispatched = storage_type_assign(&out_stype, kDefaultStorage,
- dispatch_mode, DispatchMode::kFCompute);
- }
- if (!dispatched) {
- if ((lhs_stype == kRowSparseStorage && rhs_stype == kRowSparseStorage) ||
- (lhs_stype == kRowSparseStorage && rhs_stype == kDefaultStorage) ||
- (lhs_stype == kDefaultStorage && rhs_stype == kRowSparseStorage)) {
- // rsp, rsp -> rsp
- // rsp, dns -> rsp
- // dns, rsp -> rsp
- dispatched = storage_type_assign(&out_stype, kRowSparseStorage,
- dispatch_mode, dispatch_ex);
- } else if (lhs_stype == kCSRStorage && rhs_stype == kCSRStorage) {
- dispatched = storage_type_assign(&out_stype, kCSRStorage,
- dispatch_mode, dispatch_ex);
- } else if (lhs_stype == kCSRStorage || rhs_stype == kCSRStorage) {
- dispatched = storage_type_assign(&out_stype, kCSRStorage,
- dispatch_mode, DispatchMode::kFComputeFallback);
- }
- }
- if (!dispatched) {
- dispatch_fallback(out_attrs, dispatch_mode);
- }
- if (*dispatch_mode == DispatchMode::kFComputeFallback) {
- LogStorageFallback(attrs, dev_mask, in_attrs, out_attrs);
- }
- return true;
-}
-
} // namespace op
} // namespace mxnet
diff --git a/src/operator/tensor/elemwise_binary_op.h b/src/operator/tensor/elemwise_binary_op.h
index 6a1cc02..b8b5bd1 100644
--- a/src/operator/tensor/elemwise_binary_op.h
+++ b/src/operator/tensor/elemwise_binary_op.h
@@ -273,11 +273,55 @@ class ElemwiseBinaryOp : public OpBase {
* \param out_attrs Output storage attributes
* \return true if handled
*/
+ template<bool lhs_dense_ok = true, bool rhs_dense_ok = true>
static bool AllowLRDenseInputWithSparseOutputStorageType(const nnvm::NodeAttrs& attrs,
int dev_mask,
DispatchMode* dispatch_mode,
std::vector<int> *in_attrs,
- std::vector<int> *out_attrs);
+ std::vector<int> *out_attrs) {
+ CHECK_EQ(in_attrs->size(), 2U) << " in operator " << attrs.name;
+ CHECK_EQ(out_attrs->size(), 1U) << " in operator " << attrs.name;
+ const auto& lhs_stype = in_attrs->at(0);
+ const auto& rhs_stype = in_attrs->at(1);
+ auto& out_stype = out_attrs->at(0);
+ bool dispatched = false;
+ const bool invalid_ctx = dev_mask != mshadow::cpu::kDevMask;
+ const auto dispatch_ex = invalid_ctx ? DispatchMode::kFComputeFallback :
+ DispatchMode::kFComputeEx;
+ if (!dispatched && lhs_stype == kDefaultStorage && rhs_stype == kDefaultStorage) {
+ // dns, dns -> dns
+ dispatched = storage_type_assign(&out_stype, kDefaultStorage,
+ dispatch_mode, DispatchMode::kFCompute);
+ }
+ if (!dispatched) {
+ if ((lhs_stype == kRowSparseStorage && rhs_stype == kRowSparseStorage) ||
+ (rhs_dense_ok && lhs_stype == kRowSparseStorage && rhs_stype == kDefaultStorage) ||
+ (lhs_dense_ok && lhs_stype == kDefaultStorage && rhs_stype == kRowSparseStorage)) {
+ // rsp, rsp -> rsp
+ // rsp, dns -> rsp
+ // dns, rsp -> rsp
+ dispatched = storage_type_assign(&out_stype, kRowSparseStorage,
+ dispatch_mode, dispatch_ex);
+ } else if (lhs_stype == kCSRStorage && rhs_stype == kCSRStorage) {
+ // csr, csr -> csr
+ dispatched = storage_type_assign(&out_stype, kCSRStorage,
+ dispatch_mode, dispatch_ex);
+ } else if ((lhs_stype == kCSRStorage && rhs_dense_ok) ||
+ (rhs_stype == kCSRStorage && lhs_dense_ok)) {
+ // csr, dns -> csr
+ // dns, csr -> csr
+ dispatched = storage_type_assign(&out_stype, kCSRStorage,
+ dispatch_mode, DispatchMode::kFComputeFallback);
+ }
+ }
+ if (!dispatched) {
+ dispatch_fallback(out_attrs, dispatch_mode);
+ }
+ if (*dispatch_mode == DispatchMode::kFComputeFallback) {
+ LogStorageFallback(attrs, dev_mask, in_attrs, out_attrs);
+ }
+ return true;
+ }
/*!
* \brief Backward pass computing input gradient using forward inputs
diff --git a/src/operator/tensor/elemwise_binary_op_basic.cc b/src/operator/tensor/elemwise_binary_op_basic.cc
index f812fe0..b3be9e4 100644
--- a/src/operator/tensor/elemwise_binary_op_basic.cc
+++ b/src/operator/tensor/elemwise_binary_op_basic.cc
@@ -98,13 +98,14 @@ The storage type of ``elemwise_mul`` output depends on storage types of inputs
- elemwise_mul(default, default) = default
- elemwise_mul(row_sparse, row_sparse) = row_sparse
- - elemwise_mul(default, row_sparse) = row_sparse
- - elemwise_mul(row_sparse, default) = row_sparse
+ - elemwise_mul(default, row_sparse) = default
+ - elemwise_mul(row_sparse, default) = default
- otherwise, ``elemwise_mul`` generates output with default storage
)code")
.set_attr<FInferStorageType>("FInferStorageType",
- ElemwiseBinaryOp::AllowLRDenseInputWithSparseOutputStorageType)
+ ElemwiseBinaryOp::AllowLRDenseInputWithSparseOutputStorageType<
+ false, false>) // 0 * nan or nan * 0 -> nan, so rsp * dns -> dns
.set_attr<FCompute>("FCompute<cpu>", ElemwiseBinaryOp::Compute<cpu, mshadow::op::mul>)
.set_attr<FComputeEx>("FComputeEx<cpu>",
ElemwiseBinaryOp::ComputeDnsLRValueEx<cpu, mshadow::op::mul, true, true>)
diff --git a/tests/python/unittest/test_sparse_operator.py b/tests/python/unittest/test_sparse_operator.py
index b281749..d440553 100644
--- a/tests/python/unittest/test_sparse_operator.py
+++ b/tests/python/unittest/test_sparse_operator.py
@@ -327,6 +327,11 @@ def test_elemwise_binary_ops():
return rstype
return lstype
+ def most_dense(lstype, rstype):
+ if lstype == rstype:
+ return lstype
+ return 'default'
+
def check_elemwise_binary_ops(lhs_stype, rhs_stype, shape,
lhs_grad_stype=None, rhs_grad_stype=None,
lhs_density=.5, rhs_density=.5,
@@ -362,7 +367,7 @@ def test_elemwise_binary_ops():
lambda outg, l, r: (outg * r, outg * l),
least_sparse(lhs_stype, rhs_stype),
least_sparse(lhs_stype, rhs_stype),
- expected_result_storage_type=least_sparse(lhs_stype, rhs_stype),
+ expected_result_storage_type=most_dense(lhs_stype, rhs_stype),
ograd_density=ograd_density,
force_lr_overlap=force_lr_overlap,
force_grad_overlap=force_grad_overlap,
@@ -449,8 +454,8 @@ def test_elemwise_binary_ops():
shape = rand_shape_2d()
- print(" force_lr_overlap={}, force_grad_overlap={}, shape={}"
- .format(force_lr_overlap, force_grad_overlap, shape))
+ print(" force_lr_overlap={}, force_grad_overlap={}, shape={}".
+ format(force_lr_overlap, force_grad_overlap, shape))
# Left and right always overlap when one is default storage
# (assuming the row_sparse one has some entries in it)
--
To stop receiving notification emails like this one, please contact
['"commits@mxnet.apache.org" <co...@mxnet.apache.org>'].