From 02504c9053f147f8771bc8966fe3510e43cc4ed5 Mon Sep 17 00:00:00 2001 From: reminisce Date: Mon, 25 Mar 2019 11:27:32 -0700 Subject: [PATCH 1/5] Fix several test failures --- src/operator/leaky_relu-inl.h | 4 ++-- tests/python/unittest/test_ndarray.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/operator/leaky_relu-inl.h b/src/operator/leaky_relu-inl.h index 22f5229f54bd..5518352b2a9e 100644 --- a/src/operator/leaky_relu-inl.h +++ b/src/operator/leaky_relu-inl.h @@ -338,10 +338,10 @@ class LeakyReLUProp : public OperatorProperty { CHECK_EQ(in_shape->size(), 1U) << "Input:[data]"; } const mxnet::TShape &dshape = in_shape->at(leakyrelu::kData); - if (dshape.ndim() == 0) return false; + if (!mxnet::ndim_is_known(dshape)) return false; if (param_.act_type == leakyrelu::kPReLU) { const mxnet::TShape &gshape = in_shape->at(leakyrelu::kGamma); - if (gshape.ndim() == 0) { + if (!mxnet::ndim_is_known(gshape)) { in_shape->at(leakyrelu::kGamma) = mxnet::TShape(Shape1(dshape[1])); } if (dshape == gshape) { diff --git a/tests/python/unittest/test_ndarray.py b/tests/python/unittest/test_ndarray.py index 3a17a1e89461..c71209fb8510 100644 --- a/tests/python/unittest/test_ndarray.py +++ b/tests/python/unittest/test_ndarray.py @@ -120,7 +120,11 @@ def test_ndarray_setitem(): # numpy assignment for empty axis for trivial_shape in [(), (1,), (1, 1), (1, 1, 1)]: - x = mx.nd.zeros(trivial_shape) + if trivial_shape == tuple(): + with mx.numpy.enable_np_comp(): + x = mx.nd.zeros(trivial_shape) + else: + x = mx.nd.zeros(trivial_shape) x[:] = np.ones(trivial_shape) x_np = np.ones(trivial_shape, dtype=x.dtype) assert x.shape == trivial_shape From 76e95de02c7e0733e86ec76dd10ff200662d94f9 Mon Sep 17 00:00:00 2001 From: reminisce Date: Mon, 25 Mar 2019 12:50:06 -0700 Subject: [PATCH 2/5] Fix subgraph op infer shape --- src/common/utils.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/utils.h b/src/common/utils.h index 4843d7e06b7b..4fb398d883a6 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -746,6 +746,11 @@ inline void ParallelCopy(DType* dst, const DType* src, index_t size) { * 4. -1 dim size means the dimension's size is unknown. * so that operator's infer shape function can work in backend. * \param shape to be converted. + * Note: It is possible that the shape to be converted is already + * numpy compatible. For example, when a subgraph operator's infer + * shape function is called from the infer shape pass of the whole + * graph, its input/output shapes have been converted to numpy + * compatible shapes. */ inline void ConvertToNumpyShape(mxnet::TShape* shape) { if (shape->ndim() == 0) { // legacy shape ndim = 0 means unknown From ca0d2aae246e1d5c30184c6c79d3bccdf33e31ef Mon Sep 17 00:00:00 2001 From: reminisce Date: Mon, 25 Mar 2019 15:16:07 -0700 Subject: [PATCH 3/5] Fix sparse slice --- src/operator/tensor/matrix_op-inl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/operator/tensor/matrix_op-inl.h b/src/operator/tensor/matrix_op-inl.h index f79af7c0da5d..65f3b2fa4f22 100644 --- a/src/operator/tensor/matrix_op-inl.h +++ b/src/operator/tensor/matrix_op-inl.h @@ -594,7 +594,7 @@ void SliceCsrImpl(const SliceParam ¶m, const OpContext& ctx, mxnet::TShape begin(N, -1), end(N, -1); for (int i = 0; i < N; ++i) { int s = 0; - if (param.begin[i]) { + if (i < param.begin.ndim() && param.begin[i]) { s = *param.begin[i]; if (s < 0) s += ishape[i]; } From b83ba55217ca3c506f088a58e47baf6f414746bf Mon Sep 17 00:00:00 2001 From: reminisce Date: Mon, 25 Mar 2019 15:35:48 -0700 Subject: [PATCH 4/5] Fix typo --- src/c_api/c_api_common.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h index 329dc9adc7cf..55608b950866 100644 --- a/src/c_api/c_api_common.h +++ b/src/c_api/c_api_common.h @@ -91,8 +91,9 @@ struct MXAPIThreadLocalEntry { data->resize(shapes.size()); size_t size = 0; for (const auto& s : shapes) { - if (s.ndim() > 0); - size += s.ndim(); + if (s.ndim() > 0) { + size += s.ndim(); + } } buffer->resize(size); int *ptr = buffer->data(); From abac50818163a8930408d3f11a6b310657c32532 Mon Sep 17 00:00:00 2001 From: reminisce Date: Mon, 25 Mar 2019 16:36:11 -0700 Subject: [PATCH 5/5] Fix deconv infer shape --- src/operator/nn/deconvolution-inl.h | 12 ++++--- src/operator/nn/deconvolution.cc | 50 +++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/operator/nn/deconvolution-inl.h b/src/operator/nn/deconvolution-inl.h index b28e47818392..5f3137f0dcb8 100644 --- a/src/operator/nn/deconvolution-inl.h +++ b/src/operator/nn/deconvolution-inl.h @@ -134,11 +134,13 @@ struct DeconvolutionParam : public dmlc::Parameter { for (size_t i = 0; i < ndim; i++) { // input.ndim() can be larger than ndim, in case that the complete input // shape was passed and not only the ndim last ones - o_pad[i] = stride[i] * (input[(input_ndim - ndim) + i] - 1) + DilatedKernelSize(i); - CHECK_GE(o_pad[i], target_shape[i]) << "too big target shape"; - o_pad[i] -= target_shape[i]; - o_adj[i] = o_pad[i] % 2; - o_pad[i] = (o_pad[i] + 1) / 2; + if (mxnet::dim_size_is_known(input, input_ndim - ndim + i)) { + o_pad[i] = stride[i] * (input[(input_ndim - ndim) + i] - 1) + DilatedKernelSize(i); + CHECK_GE(o_pad[i], target_shape[i]) << "too big target shape"; + o_pad[i] -= target_shape[i]; + o_adj[i] = o_pad[i] % 2; + o_pad[i] = (o_pad[i] + 1) / 2; + } } } else { for (size_t i = 0; i < ndim; i++) { diff --git a/src/operator/nn/deconvolution.cc b/src/operator/nn/deconvolution.cc index d8c91f7f96c8..09b255d009e0 100644 --- a/src/operator/nn/deconvolution.cc +++ b/src/operator/nn/deconvolution.cc @@ -54,7 +54,7 @@ static bool DeconvolutionShape(const nnvm::NodeAttrs& attrs, } out_shape->resize(1, mxnet::TShape()); const mxnet::TShape &dshape = (*in_shape)[deconv::kData]; - if (!shape_is_known(dshape)) return false; + if (!mxnet::ndim_is_known(dshape)) return false; if (param_.kernel.ndim() == 1) { // 1d conv @@ -90,8 +90,12 @@ static bool DeconvolutionShape(const nnvm::NodeAttrs& attrs, Shape<3> oshape; oshape[0] = dshape_ncw[0]; oshape[1] = param_.num_filter; - oshape[2] = param_.stride[0] * (dshape_ncw[2] - 1) + - dilated_ksize_x - 2 * o_pad[0] + o_adj[0]; + if (mxnet::dim_size_is_known(dshape_ncw[2])) { + oshape[2] = param_.stride[0] * (dshape_ncw[2] - 1) + + dilated_ksize_x - 2 * o_pad[0] + o_adj[0]; + } else { + oshape[2] = -1; + } if (param_.target_shape.ndim() > 0) { if (param_.target_shape[0] > 0) { @@ -141,10 +145,18 @@ static bool DeconvolutionShape(const nnvm::NodeAttrs& attrs, Shape<4> oshape; oshape[0] = dshape_nchw[0]; oshape[1] = param_.num_filter; - oshape[2] = param_.stride[0] * (dshape_nchw[2] - 1) + - dilated_ksize_y - 2 * o_pad[0] + o_adj[0]; - oshape[3] = param_.stride[1] * (dshape_nchw[3] - 1) + - dilated_ksize_x - 2 * o_pad[1] + o_adj[1]; + if (mxnet::dim_size_is_known(dshape_nchw[2])) { + oshape[2] = param_.stride[0] * (dshape_nchw[2] - 1) + + dilated_ksize_y - 2 * o_pad[0] + o_adj[0]; + } else { + oshape[2] = -1; + } + if (mxnet::dim_size_is_known(dshape_nchw[3])) { + oshape[3] = param_.stride[1] * (dshape_nchw[3] - 1) + + dilated_ksize_x - 2 * o_pad[1] + o_adj[1]; + } else { + oshape[3] = -1; + } if (param_.target_shape.ndim() > 1) { if (param_.target_shape[0] > 0) { @@ -203,12 +215,24 @@ static bool DeconvolutionShape(const nnvm::NodeAttrs& attrs, Shape<5> oshape; oshape[0] = dshape_ncdhw[0]; oshape[1] = param_.num_filter; - oshape[2] = param_.stride[0] * (dshape_ncdhw[2] - 1) + - dilated_ksize_d - 2 * o_pad[0] + o_adj[0]; - oshape[3] = param_.stride[1] * (dshape_ncdhw[3] - 1) + - dilated_ksize_y - 2 * o_pad[1] + o_adj[1]; - oshape[4] = param_.stride[2] * (dshape_ncdhw[4] - 1) + - dilated_ksize_x - 2 * o_pad[2] + o_adj[2]; + if (mxnet::dim_size_is_known(dshape_ncdhw[2])) { + oshape[2] = param_.stride[0] * (dshape_ncdhw[2] - 1) + + dilated_ksize_d - 2 * o_pad[0] + o_adj[0]; + } else { + oshape[2] = -1; + } + if (mxnet::dim_size_is_known(dshape_ncdhw[3])) { + oshape[3] = param_.stride[1] * (dshape_ncdhw[3] - 1) + + dilated_ksize_y - 2 * o_pad[1] + o_adj[1]; + } else { + oshape[3] = -1; + } + if (mxnet::dim_size_is_known(dshape_ncdhw[4])) { + oshape[4] = param_.stride[2] * (dshape_ncdhw[4] - 1) + + dilated_ksize_x - 2 * o_pad[2] + o_adj[2]; + } else { + oshape[4] = -1; + } if (param_.target_shape.ndim() > 2) { if (param_.target_shape[0] > 0) {