diff --git a/include/mxnet/c_api.h b/include/mxnet/c_api.h index 9a24b7516128..5b774055d0e6 100644 --- a/include/mxnet/c_api.h +++ b/include/mxnet/c_api.h @@ -763,8 +763,8 @@ MXNET_DLL int MXNDArrayReshape64(NDArrayHandle handle, * \return 0 when success, -1 when failure happens */ MXNET_DLL int MXNDArrayGetShape(NDArrayHandle handle, - mx_uint *out_dim, - const mx_uint **out_pdata); + int *out_dim, + const int **out_pdata); /*! * \brief get the content of the data in NDArray * \param handle the handle to the ndarray @@ -1481,16 +1481,16 @@ MXNET_DLL int MXSymbolInferShape(SymbolHandle sym, mx_uint num_args, const char** keys, const mx_uint *arg_ind_ptr, - const mx_uint *arg_shape_data, + const int *arg_shape_data, mx_uint *in_shape_size, - const mx_uint **in_shape_ndim, - const mx_uint ***in_shape_data, + const int **in_shape_ndim, + const int ***in_shape_data, mx_uint *out_shape_size, - const mx_uint **out_shape_ndim, - const mx_uint ***out_shape_data, + const int **out_shape_ndim, + const int ***out_shape_data, mx_uint *aux_shape_size, - const mx_uint **aux_shape_ndim, - const mx_uint ***aux_shape_data, + const int **aux_shape_ndim, + const int ***aux_shape_data, int *complete); /*! * \brief partially infer shape of unknown input shapes given the known one. @@ -1520,16 +1520,16 @@ MXNET_DLL int MXSymbolInferShapePartial(SymbolHandle sym, mx_uint num_args, const char** keys, const mx_uint *arg_ind_ptr, - const mx_uint *arg_shape_data, + const int *arg_shape_data, mx_uint *in_shape_size, - const mx_uint **in_shape_ndim, - const mx_uint ***in_shape_data, + const int **in_shape_ndim, + const int ***in_shape_data, mx_uint *out_shape_size, - const mx_uint **out_shape_ndim, - const mx_uint ***out_shape_data, + const int **out_shape_ndim, + const int ***out_shape_data, mx_uint *aux_shape_size, - const mx_uint **aux_shape_ndim, - const mx_uint ***aux_shape_data, + const int **aux_shape_ndim, + const int ***aux_shape_data, int *complete); /*! @@ -1808,7 +1808,7 @@ MXNET_DLL int MXExecutorSimpleBind(SymbolHandle symbol_handle, const char** provided_grad_req_types, const mx_uint num_provided_arg_shapes, const char** provided_arg_shape_names, - const mx_uint* provided_arg_shape_data, + const int* provided_arg_shape_data, const mx_uint* provided_arg_shape_idx, const mx_uint num_provided_arg_dtypes, const char** provided_arg_dtype_names, @@ -1862,7 +1862,7 @@ MXNET_DLL int MXExecutorReshape(int partial_shaping, const int* map_dev_ids, const mx_uint num_provided_arg_shapes, const char** provided_arg_shape_names, - const mx_uint* provided_arg_shape_data, + const int* provided_arg_shape_data, const mx_uint* provided_arg_shape_idx, mx_uint* num_in_args, NDArrayHandle** in_args, @@ -2538,8 +2538,8 @@ MXNET_DLL int MXNDArrayGetSharedMemHandle(NDArrayHandle handle, int* shared_pid, * \param dtype data type of NDArray * \param out constructed NDArray */ -MXNET_DLL int MXNDArrayCreateFromSharedMem(int shared_pid, int shared_id, const mx_uint *shape, - mx_uint ndim, int dtype, NDArrayHandle *out); +MXNET_DLL int MXNDArrayCreateFromSharedMem(int shared_pid, int shared_id, const int *shape, + int ndim, int dtype, NDArrayHandle *out); #ifdef __cplusplus diff --git a/include/mxnet/ndarray.h b/include/mxnet/ndarray.h index d00cb479b92e..2232ebe7be40 100644 --- a/include/mxnet/ndarray.h +++ b/include/mxnet/ndarray.h @@ -859,12 +859,15 @@ class NDArray { Chunk(mxnet::TShape shape, Context ctx_, bool delay_alloc_, int dtype) : static_data(false), delay_alloc(true), ctx(ctx_), storage_ref_(Storage::_GetSharedRef()) { - auto size = shape.Size(); storage_shape = shape; + if (shape_is_known(storage_shape)) { + shandle.size = shape.Size() * mshadow::mshadow_sizeof(dtype); + } var = Engine::Get()->NewVariable(); - shandle.size = size * mshadow::mshadow_sizeof(dtype); shandle.ctx = ctx_; - if (!delay_alloc_) this->CheckAndAlloc(); + if (!delay_alloc_) { + this->CheckAndAlloc(); + } } Chunk(const TBlob &data, int dev_id) diff --git a/include/mxnet/tuple.h b/include/mxnet/tuple.h index 39c3c185e3c0..49852f73fbac 100644 --- a/include/mxnet/tuple.h +++ b/include/mxnet/tuple.h @@ -199,7 +199,7 @@ class Tuple { * \return the corresponding dimension size */ inline ValueType& operator[](int i) { - CHECK(i >= 0 && i < ndim()); + CHECK(i >= 0 && i < ndim()) << "index = " << i << " must be in range [0, " << ndim() << ")"; return begin()[i]; } /*! @@ -208,7 +208,7 @@ class Tuple { * \return the corresponding dimension size */ inline const ValueType& operator[](int i) const { - CHECK(i >= 0 && i < ndim()); + CHECK(i >= 0 && i < ndim()) << "index = " << i << " must be in range [0, " << ndim() << ")"; return begin()[i]; } /*! @@ -271,14 +271,16 @@ class Tuple { if (!isspace(ch)) { is.setstate(std::ios::failbit); return is; + } } - } - // Handle empty tuple + // Handle empty tuple. A tensor whose shape is an empty tuple + // represents a scalar with ndim = 0. while (isspace(is.peek())) { is.get(); } if (is.peek() == ')' || is.peek() == ']') { is.get(); + t.SetDim(0); return is; } // Handle non-empty tuple @@ -352,7 +354,7 @@ class Tuple { delete [] data_heap_; data_heap_ = new ValueType[ndim]; num_heap_allocated_ = ndim; - } else if (ndim == -1 && data_heap_ != nullptr) { + } else if (ndim <= 0 && data_heap_ != nullptr) { delete [] data_heap_; data_heap_ = nullptr; num_heap_allocated_ = 0; @@ -381,14 +383,11 @@ class TShape : public Tuple { this->SetDim(-1); } /*! - * constructor to construct a shape with all 1. - * TODO(junwu): The value should default to -1. Need to keep 1 for now - * for backward compatibility. Change it to -1 in the future when we can - * break backward compatibility. + * constructor to construct a shape with all `value`. * \param ndim the number of dimension * \param value the dimension size for all dims */ - inline TShape(int ndim, int value = 1) { // NOLINT(*) + inline TShape(int ndim, int value = -1) { // NOLINT(*) this->SetDim(ndim); if (ndim > 0) { std::fill_n(begin(), ndim, value); @@ -458,7 +457,7 @@ class TShape : public Tuple { dim_t size = 1; const dim_t* start = begin(), *fin = end(); for (const dim_t* it = start; it != fin; ++it) { - CHECK_GE(*it, 0) << "Shape dim size cannot be -1, which means unknown."; + CHECK_GE(*it, 0) << "Shape dim size cannot be a negative value " << *it; size *= *it; } return size; @@ -473,7 +472,7 @@ class TShape : public Tuple { dim_t num = 1; const dim_t *d = this->data(); for (int i = dimstart; i < dimend; ++i) { - CHECK_GE(d[i], 0) << "Shape dim size cannot be -1, which means unknown."; + CHECK_GE(d[i], 0) << "Shape dim size cannot be a negative value " << d[i]; num *= d[i]; } return num; @@ -608,6 +607,16 @@ class TShape : public Tuple { #endif }; +/*! brief check if shape is known using the NumPy compatible definition. + * zero-dim and zero-size tensors are valid. -1 means unknown.*/ +inline bool shape_is_known(const TShape& x) { + if (x.ndim() == -1) return false; + for (int i = 0; i < x.ndim(); ++i) { + if (x[i] == -1) return false; + } + return true; +} + /*! \brief helper function to cast type of container elements */ template inline DstIter ShapeTypeCast(const SrcIter begin, @@ -623,7 +632,7 @@ inline DstIter ShapeTypeCast(const SrcIter begin, template inline TShape ShapeTypeCast(const SrcIter begin, const SrcIter end) { size_t ndim = std::distance(begin, end); - TShape res(ndim); + TShape res(ndim, -1); ShapeTypeCast(begin, end, res.begin()); return res; } @@ -669,7 +678,7 @@ struct hash > { size_t operator()(const mxnet::Tuple& val) const { std::hash hash_uint; size_t res = hash_uint(val.ndim()); - for (uint32_t i = 0; i < val.ndim(); ++i) { + for (int i = 0; i < val.ndim(); ++i) { res = dmlc::HashCombine(res, val[i]); } return res; diff --git a/python/mxnet/base.py b/python/mxnet/base.py index 7793deacf44c..fe1dd00f9454 100644 --- a/python/mxnet/base.py +++ b/python/mxnet/base.py @@ -213,6 +213,7 @@ def _load_lib(): _LIB = _load_lib() # type definitions +mx_int = ctypes.c_int mx_uint = ctypes.c_uint mx_float = ctypes.c_float mx_float_p = ctypes.POINTER(mx_float) diff --git a/python/mxnet/executor.py b/python/mxnet/executor.py index 7bf867579d6b..53ddc252d6b5 100644 --- a/python/mxnet/executor.py +++ b/python/mxnet/executor.py @@ -25,7 +25,7 @@ import copy import numpy as np from .base import _LIB -from .base import mx_uint, NDArrayHandle, ExecutorHandle, py_str +from .base import mx_uint, NDArrayHandle, ExecutorHandle, py_str, mx_int from .base import check_call, c_handle_array, c_array_buf, c_str_array from .ndarray import NDArray from .ndarray import _ndarray_cls @@ -445,8 +445,8 @@ def reshape(self, partial_shaping=False, allow_up_sizing=False, **kwargs): py_array('i', ctx_map_dev_ids)), mx_uint(len(provided_arg_shape_names)), c_str_array(provided_arg_shape_names), - c_array_buf(mx_uint, - py_array('I', provided_arg_shape_data)), + c_array_buf(mx_int, + py_array('i', provided_arg_shape_data)), c_array_buf(mx_uint, py_array('I', provided_arg_shape_idx)), ctypes.byref(num_in_args), diff --git a/python/mxnet/ndarray/ndarray.py b/python/mxnet/ndarray/ndarray.py index acb7b283aa76..89fc00801ea3 100644 --- a/python/mxnet/ndarray/ndarray.py +++ b/python/mxnet/ndarray/ndarray.py @@ -35,7 +35,7 @@ import numpy as np from ..base import _LIB, numeric_types, integer_types from ..base import c_str, c_array, c_array_buf, c_handle_array, mx_real_t -from ..base import mx_uint, NDArrayHandle, check_call, DLPackHandle +from ..base import mx_uint, NDArrayHandle, check_call, DLPackHandle, mx_int from ..base import ctypes2buffer from ..context import Context, current_context from . import _internal @@ -146,8 +146,8 @@ def _new_from_shared_mem(shared_pid, shared_id, shape, dtype): check_call(_LIB.MXNDArrayCreateFromSharedMem( ctypes.c_int(shared_pid), ctypes.c_int(shared_id), - c_array(mx_uint, shape), - mx_uint(len(shape)), + c_array(mx_int, shape), + mx_int(len(shape)), ctypes.c_int(int(_DTYPE_NP_TO_MX[np.dtype(dtype).type])), ctypes.byref(hdl))) return hdl @@ -1848,8 +1848,8 @@ def shape(self): >>> y.shape (2L, 3L, 4L) """ - ndim = mx_uint() - pdata = ctypes.POINTER(mx_uint)() + ndim = mx_int() + pdata = ctypes.POINTER(mx_int)() check_call(_LIB.MXNDArrayGetShape( self.handle, ctypes.byref(ndim), ctypes.byref(pdata))) return tuple(pdata[:ndim.value]) # pylint: disable=invalid-slice-index diff --git a/python/mxnet/symbol/symbol.py b/python/mxnet/symbol/symbol.py index 0c0a0a1e3c88..01b851c43f88 100644 --- a/python/mxnet/symbol/symbol.py +++ b/python/mxnet/symbol/symbol.py @@ -34,7 +34,7 @@ from ..attribute import AttrScope from ..base import _LIB, numeric_types, c_array, c_array_buf, c_str, c_str_array, c_handle_array -from ..base import mx_uint, py_str, string_types, integer_types +from ..base import mx_uint, py_str, string_types, integer_types, mx_int from ..base import NDArrayHandle, ExecutorHandle, SymbolHandle from ..base import check_call, MXNetError, NotImplementedForSymbol from ..context import Context, current_context @@ -1174,14 +1174,14 @@ def _infer_shape_impl(self, partial, *args, **kwargs): indptr.append(len(sdata)) keys = c_str_array(str_keys) arg_shape_size = mx_uint() - arg_shape_ndim = ctypes.POINTER(mx_uint)() - arg_shape_data = ctypes.POINTER(ctypes.POINTER(mx_uint))() + arg_shape_ndim = ctypes.POINTER(mx_int)() + arg_shape_data = ctypes.POINTER(ctypes.POINTER(mx_int))() out_shape_size = mx_uint() - out_shape_ndim = ctypes.POINTER(mx_uint)() - out_shape_data = ctypes.POINTER(ctypes.POINTER(mx_uint))() + out_shape_ndim = ctypes.POINTER(mx_int)() + out_shape_data = ctypes.POINTER(ctypes.POINTER(mx_int))() aux_shape_size = mx_uint() - aux_shape_ndim = ctypes.POINTER(mx_uint)() - aux_shape_data = ctypes.POINTER(ctypes.POINTER(mx_uint))() + aux_shape_ndim = ctypes.POINTER(mx_int)() + aux_shape_data = ctypes.POINTER(ctypes.POINTER(mx_int))() complete = ctypes.c_int() if partial: infer_func = _LIB.MXSymbolInferShapePartial @@ -1192,7 +1192,7 @@ def _infer_shape_impl(self, partial, *args, **kwargs): mx_uint(len(indptr) - 1), keys, c_array_buf(mx_uint, array('I', indptr)), - c_array_buf(mx_uint, array('I', sdata)), + c_array_buf(mx_int, array('i', sdata)), ctypes.byref(arg_shape_size), ctypes.byref(arg_shape_ndim), ctypes.byref(arg_shape_data), @@ -1576,10 +1576,10 @@ def simple_bind(self, ctx, grad_req='write', type_dict=None, stype_dict=None, provided_grad_req_types, mx_uint(len(provided_arg_shape_names)), c_str_array(provided_arg_shape_names), - c_array_buf(mx_uint, + c_array_buf(mx_int, array('I', provided_arg_shape_data)), c_array_buf(mx_uint, - array('I', provided_arg_shape_idx)), + array('i', provided_arg_shape_idx)), num_provided_arg_types, provided_arg_type_names, provided_arg_type_data, diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index 70ba84b5f94b..dd5dc8d4c491 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -471,7 +471,7 @@ MXNET_DLL int MXNDArrayReshape64(NDArrayHandle handle, NDArray *ptr = new NDArray(); API_BEGIN(); NDArray *arr = static_cast(handle); - nnvm::Tuple shape(dims, dims+ndim); + mxnet::Tuple shape(dims, dims+ndim); CHECK_GT(arr->shape().Size(), 0) << "Source ndarray's shape is undefined. Input shape: " << arr->shape(); mxnet::TShape new_shape = mxnet::op::InferReshapeShape(shape, arr->shape(), reverse); @@ -493,17 +493,18 @@ int MXNDArrayGetStorageType(NDArrayHandle handle, } int MXNDArrayGetShape(NDArrayHandle handle, - mx_uint *out_dim, - const mx_uint **out_pdata) { + int *out_dim, + const int **out_pdata) { MXAPIThreadLocalEntry *ret = MXAPIThreadLocalStore::Get(); API_BEGIN(); NDArray *arr = static_cast(handle); if (!arr->is_none()) { const mxnet::TShape &s = arr->shape(); *out_dim = s.ndim(); - std::vector& buffer = ret->arg_shape_buffer; + CHECK_GE(s.ndim(), 0); + std::vector& buffer = ret->arg_shape_buffer; buffer.resize(s.ndim()); - nnvm::ShapeTypeCast(s.begin(), s.end(), buffer.data()); + mxnet::ShapeTypeCast(s.begin(), s.end(), buffer.data()); *out_pdata = buffer.data(); } else { *out_dim = 0; @@ -1395,8 +1396,8 @@ int MXNDArrayGetSharedMemHandle(NDArrayHandle handle, int* shared_pid, int* shar API_END(); } -int MXNDArrayCreateFromSharedMem(int shared_pid, int shared_id, const mx_uint *shape, - mx_uint ndim, int dtype, NDArrayHandle *out) { +int MXNDArrayCreateFromSharedMem(int shared_pid, int shared_id, const int *shape, + int ndim, int dtype, NDArrayHandle *out) { API_BEGIN(); *out = new NDArray(shared_pid, shared_id, mxnet::TShape(shape, shape + ndim), dtype); API_END(); diff --git a/src/c_api/c_api_common.h b/src/c_api/c_api_common.h index b5adfa37eca9..690a1eae1055 100644 --- a/src/c_api/c_api_common.h +++ b/src/c_api/c_api_common.h @@ -74,29 +74,32 @@ struct MXAPIThreadLocalEntry { /*! \brief result holder for returning storage types */ std::vector arg_storage_types, out_storage_types, aux_storage_types; /*! \brief result holder for returning shape dimensions */ - std::vector arg_shape_ndim, out_shape_ndim, aux_shape_ndim; + std::vector arg_shape_ndim, out_shape_ndim, aux_shape_ndim; /*! \brief result holder for returning shape pointer */ - std::vector arg_shape_data, out_shape_data, aux_shape_data; + std::vector arg_shape_data, out_shape_data, aux_shape_data; /*! \brief uint32_t buffer for returning shape pointer */ - std::vector arg_shape_buffer, out_shape_buffer, aux_shape_buffer; + std::vector arg_shape_buffer, out_shape_buffer, aux_shape_buffer; /*! \brief bool buffer */ std::vector save_inputs, save_outputs; // helper function to setup return value of shape array inline static void SetupShapeArrayReturnWithBuffer( const mxnet::ShapeVector &shapes, - std::vector *ndim, - std::vector *data, - std::vector *buffer) { + std::vector *ndim, + std::vector *data, + std::vector *buffer) { ndim->resize(shapes.size()); data->resize(shapes.size()); size_t size = 0; - for (const auto& s : shapes) size += s.ndim(); + for (const auto& s : shapes) { + CHECK_GE(s.ndim(), 0); + size += s.ndim(); + } buffer->resize(size); - uint32_t *ptr = buffer->data(); + int *ptr = buffer->data(); for (size_t i = 0; i < shapes.size(); ++i) { ndim->at(i) = shapes[i].ndim(); data->at(i) = ptr; - ptr = nnvm::ShapeTypeCast(shapes[i].begin(), shapes[i].end(), ptr); + ptr = mxnet::ShapeTypeCast(shapes[i].begin(), shapes[i].end(), ptr); } } }; diff --git a/src/c_api/c_api_executor.cc b/src/c_api/c_api_executor.cc index a2e8bb810e6f..d0006383bdc8 100644 --- a/src/c_api/c_api_executor.cc +++ b/src/c_api/c_api_executor.cc @@ -231,7 +231,7 @@ int MXExecutorSimpleBind(SymbolHandle symbol_handle, const char** provided_grad_req_types, const mx_uint num_provided_arg_shapes, const char** provided_arg_shape_names, - const mx_uint* provided_arg_shape_data, + const int* provided_arg_shape_data, const mx_uint* provided_arg_shape_idx, const mx_uint num_provided_arg_dtypes, const char** provided_arg_dtype_names, @@ -547,7 +547,7 @@ int MXExecutorReshape(int partial_shaping, const int* map_dev_ids, const mx_uint num_provided_arg_shapes, const char** provided_arg_shape_names, - const mx_uint* provided_arg_shape_data, + const int* provided_arg_shape_data, const mx_uint* provided_arg_shape_idx, mx_uint* num_in_args, NDArrayHandle** in_args, diff --git a/src/c_api/c_api_symbolic.cc b/src/c_api/c_api_symbolic.cc index 545e95f04b79..8b961f46c39e 100644 --- a/src/c_api/c_api_symbolic.cc +++ b/src/c_api/c_api_symbolic.cc @@ -505,16 +505,16 @@ int MXSymbolInferShape(SymbolHandle sym, mx_uint num_args, const char** keys, const mx_uint *arg_ind_ptr, - const mx_uint *arg_shape_data, + const int *arg_shape_data, mx_uint *in_shape_size, - const mx_uint **in_shape_ndim, - const mx_uint ***in_shape_data, + const int **in_shape_ndim, + const int ***in_shape_data, mx_uint *out_shape_size, - const mx_uint **out_shape_ndim, - const mx_uint ***out_shape_data, + const int **out_shape_ndim, + const int ***out_shape_data, mx_uint *aux_shape_size, - const mx_uint **aux_shape_ndim, - const mx_uint ***aux_shape_data, + const int **aux_shape_ndim, + const int ***aux_shape_data, int *complete) { nnvm::Symbol *s = static_cast(sym); MXAPIThreadLocalEntry *ret = MXAPIThreadLocalStore::Get(); @@ -572,16 +572,16 @@ int MXSymbolInferShapePartial(SymbolHandle sym, mx_uint num_args, const char** keys, const mx_uint *arg_ind_ptr, - const mx_uint *arg_shape_data, + const int *arg_shape_data, mx_uint *in_shape_size, - const mx_uint **in_shape_ndim, - const mx_uint ***in_shape_data, + const int **in_shape_ndim, + const int ***in_shape_data, mx_uint *out_shape_size, - const mx_uint **out_shape_ndim, - const mx_uint ***out_shape_data, + const int **out_shape_ndim, + const int ***out_shape_data, mx_uint *aux_shape_size, - const mx_uint **aux_shape_ndim, - const mx_uint ***aux_shape_data, + const int **aux_shape_ndim, + const int ***aux_shape_data, int *complete) { int succ; *complete = 1; diff --git a/src/common/exec_utils.h b/src/common/exec_utils.h index 279ecbd67f09..0551b429f17e 100644 --- a/src/common/exec_utils.h +++ b/src/common/exec_utils.h @@ -380,7 +380,7 @@ inline void HandleInferShapeError(const size_t num_forward_inputs, const uint32_t nid = idx.input_nodes().at(i); const uint32_t eid = idx.entry_id(nid, 0); const mxnet::TShape& inferred_shape = inferred_shapes[eid]; - if (inferred_shape.ndim() == 0 || inferred_shape.Size() == 0U) { + if (!shape_is_known(inferred_shape)) { const std::string& arg_name = idx[nid].source->attrs.name; oss << arg_name << ": " << inferred_shape << ", "; if (--cnt == 0) { @@ -390,7 +390,7 @@ inline void HandleInferShapeError(const size_t num_forward_inputs, } } LOG(FATAL) << "InferShape pass cannot decide shapes for the following arguments " - "(0s means unknown dimensions). Please consider providing them as inputs:\n" + "(-1 means unknown dimensions). Please consider providing them as inputs:\n" << oss.str(); } diff --git a/src/executor/graph_executor.cc b/src/executor/graph_executor.cc index 9e1b66d1b286..4a4505581920 100644 --- a/src/executor/graph_executor.cc +++ b/src/executor/graph_executor.cc @@ -967,7 +967,7 @@ void GraphExecutor::InitDataEntryMemory(std::vector* shared_pool) { uint32_t oid = head_grad_map_.at(idx[nid].source); uint32_t eid = idx.entry_id(idx.outputs()[oid]); NDArrayStorageType stype = (NDArrayStorageType) vstorage_type[eid]; - CHECK(mxnet::op::shape_is_known(vshape[eid])); + CHECK(mxnet::shape_is_known(vshape[eid])); CHECK_NE(vdtype[eid], -1); auto data_eid = idx.entry_id(nid, 0); // initialize based on storage_type diff --git a/src/executor/infer_graph_attr_pass.cc b/src/executor/infer_graph_attr_pass.cc index aa72661e78b2..3a5c5ab9806f 100644 --- a/src/executor/infer_graph_attr_pass.cc +++ b/src/executor/infer_graph_attr_pass.cc @@ -648,7 +648,7 @@ nnvm::Graph InferShape(nnvm::Graph&& graph, std::move(graph), mxnet::TShape(), "FInferShape", "shape_inputs", "shape_attr_key", "shape", "shape_num_unknown_nodes", - [](const mxnet::TShape& s) { return !mxnet::op::shape_is_known(s); }, + [](const mxnet::TShape& s) { return !mxnet::shape_is_known(s); }, [](const mxnet::TShape& s) { if (s.ndim() == -1) { return static_cast(1); diff --git a/src/io/image_io.cc b/src/io/image_io.cc index 2196983928bb..965078cb2766 100644 --- a/src/io/image_io.cc +++ b/src/io/image_io.cc @@ -189,7 +189,7 @@ void Imdecode(const nnvm::NodeAttrs& attrs, size_t len = inputs[0].shape().Size(); CHECK(len > 0) << "Input cannot be an empty buffer"; - mxnet::TShape oshape(3); + mxnet::TShape oshape(3, 1); oshape[2] = param.flag == 0 ? 1 : 3; if (get_jpeg_size(str_img, len, &oshape[1], &oshape[0])) { } else if (get_png_size(str_img, len, &oshape[1], &oshape[0])) { @@ -229,7 +229,7 @@ void Imread(const nnvm::NodeAttrs& attrs, CHECK(file.good()) << "Failed reading image file: '" << param.filename << "' " << strerror(errno); - mxnet::TShape oshape(3); + mxnet::TShape oshape(3, 1); oshape[2] = param.flag == 0 ? 1 : 3; if (get_jpeg_size(buff.get(), fsize, &oshape[1], &oshape[0])) { } else if (get_png_size(buff.get(), fsize, &oshape[1], &oshape[0])) { diff --git a/src/ndarray/ndarray.cc b/src/ndarray/ndarray.cc index 377bef072b03..04518e0feb77 100644 --- a/src/ndarray/ndarray.cc +++ b/src/ndarray/ndarray.cc @@ -1650,7 +1650,7 @@ bool LegacyTShapeLoad(dmlc::Stream *strm, mxnet::TShape *shape, const uint32_t m default: // meet legacy mxnet::TShape, magic is ndim here uint32_t ndim = magic; - *shape = mxnet::TShape(ndim); + *shape = mxnet::TShape(ndim, -1); std::vector buffer(ndim); size_t nread = ndim * sizeof(uint32_t); if (strm->Read(buffer.data(), nread) != nread) return false; diff --git a/src/nnvm/plan_memory.cc b/src/nnvm/plan_memory.cc index 0dc7e6ddb1d9..41b8559d16c2 100644 --- a/src/nnvm/plan_memory.cc +++ b/src/nnvm/plan_memory.cc @@ -76,7 +76,7 @@ class GraphAllocator { // request a free storage StorageID Request(int dev_id, int dtype, mxnet::TShape shape, uint32_t node_id) { - if (!mxnet::op::shape_is_known(shape)) return kBadStorageID; + if (!mxnet::shape_is_known(shape)) return kBadStorageID; // search memory block in [size / match_range_, size * match_range_) // TODO(tqchen) add size of the dtype, assume 4 bytes for now size_t size = shape.Size() * 4; diff --git a/src/operator/batch_norm_v1-inl.h b/src/operator/batch_norm_v1-inl.h index f407a5cce61b..8016510090ab 100644 --- a/src/operator/batch_norm_v1-inl.h +++ b/src/operator/batch_norm_v1-inl.h @@ -261,7 +261,7 @@ class BatchNormV1Prop : public OperatorProperty { using namespace mshadow; CHECK_EQ(in_shape->size(), 3U) << "Input:[data, gamma, beta]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; in_shape->at(1) = mxnet::TShape(Shape1(dshape[1])); in_shape->at(2) = mxnet::TShape(Shape1(dshape[1])); out_shape->clear(); diff --git a/src/operator/bilinear_sampler-inl.h b/src/operator/bilinear_sampler-inl.h index 8b1ff38709b6..abb4a61dc84c 100644 --- a/src/operator/bilinear_sampler-inl.h +++ b/src/operator/bilinear_sampler-inl.h @@ -149,10 +149,10 @@ class BilinearSamplerProp : public OperatorProperty { CHECK_EQ(in_shape->size(), 2U) << "Input:[data, grid]"; const mxnet::TShape &dshape = (*in_shape)[bs::kData]; const mxnet::TShape &lshape = (*in_shape)[bs::kGrid]; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; CHECK_EQ(dshape.ndim(), 4U) \ << "input data should be 4D in batch-num_filter-y-x"; - if (lshape.ndim() == 0) return false; + if (!shape_is_known(lshape)) return false; CHECK_EQ(lshape.ndim(), 4U) \ << "Sampler grid should be 4D in batch-2-y-x"; CHECK_EQ(dshape[0], lshape[0]); diff --git a/src/operator/contrib/bounding_box-inl.h b/src/operator/contrib/bounding_box-inl.h index 059327ef8334..6ea4e8097b6c 100644 --- a/src/operator/contrib/bounding_box-inl.h +++ b/src/operator/contrib/bounding_box-inl.h @@ -558,7 +558,7 @@ inline bool BoxOverlapShape(const nnvm::NodeAttrs& attrs, << rdim << " provided"; // assign output shape - mxnet::TShape oshape(lshape.ndim() + rshape.ndim() - 2); + mxnet::TShape oshape(lshape.ndim() + rshape.ndim() - 2, -1); int idx = 0; for (index_t i = 0; i < lshape.ndim() - 1; ++i) { oshape[idx++] = lshape[i]; @@ -567,7 +567,7 @@ inline bool BoxOverlapShape(const nnvm::NodeAttrs& attrs, oshape[idx++] = rshape[i]; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return true; + return shape_is_known(oshape); } struct compute_overlap { @@ -671,14 +671,14 @@ inline bool MatchingShape(const nnvm::NodeAttrs& attrs, << dshape.ndim() << " provided"; // assign output shape - mxnet::TShape oshape(dshape.ndim() - 1); + mxnet::TShape oshape(dshape.ndim() - 1, -1); for (index_t i = 0; i < dshape.ndim() - 1; ++i) { oshape[i] = dshape[i]; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); oshape[oshape.ndim() - 1] = dshape[dshape.ndim() - 1]; SHAPE_ASSIGN_CHECK(*out_attrs, 1, oshape); - return true; + return shape_is_known(oshape); } struct bipartite_matching { diff --git a/src/operator/contrib/deformable_convolution-inl.h b/src/operator/contrib/deformable_convolution-inl.h index 3e96cad1c859..936df7f1bcd4 100644 --- a/src/operator/contrib/deformable_convolution-inl.h +++ b/src/operator/contrib/deformable_convolution-inl.h @@ -127,7 +127,7 @@ class DeformableConvolutionOp : public Operator { Tensor workspace = ctx.requested[conv::kTempSpace] .get_space_typed(Shape1(col_buffer_size_), s); // calculate the shape of col_buffer - mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1); + mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1, -1); col_buffer_shape[0] = conv_in_channels_ * param_.kernel.Size(); for (size_t i = 1; i < col_buffer_shape.ndim(); ++i) { col_buffer_shape[i] = out_data[0].shape_[i + 1]; @@ -189,7 +189,7 @@ class DeformableConvolutionOp : public Operator { Tensor workspace = ctx.requested[conv::kTempSpace] .get_space_typed(Shape1(col_buffer_size_), s); // calculate the shape of col_buffer - mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1); + mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1, -1); col_buffer_shape[0] = conv_in_channels_ * param_.kernel.Size(); for (index_t i = 1; i < col_buffer_shape.ndim(); ++i) { col_buffer_shape[i] = out_grad[conv::kData].shape_[i + 1]; diff --git a/src/operator/contrib/dgl_graph.cc b/src/operator/contrib/dgl_graph.cc index 02ef2cee1caa..313b855f0d2d 100644 --- a/src/operator/contrib/dgl_graph.cc +++ b/src/operator/contrib/dgl_graph.cc @@ -259,7 +259,7 @@ static bool CSRNeighborUniformSampleShape(const nnvm::NodeAttrs& attrs, // Output bool success = true; - mxnet::TShape out_shape(1); + mxnet::TShape out_shape(1, -1); // We use the last element to store the actual // number of vertices in the subgraph. out_shape[0] = params.max_num_vertices + 1; @@ -268,7 +268,7 @@ static bool CSRNeighborUniformSampleShape(const nnvm::NodeAttrs& attrs, success = success && !mxnet::op::shape_is_none(out_attrs->at(i)); } // sub_csr - mxnet::TShape out_csr_shape(2); + mxnet::TShape out_csr_shape(2, -1); out_csr_shape[0] = params.max_num_vertices; out_csr_shape[1] = in_attrs->at(0)[1]; for (size_t i = 0; i < num_subgraphs; i++) { @@ -276,7 +276,7 @@ static bool CSRNeighborUniformSampleShape(const nnvm::NodeAttrs& attrs, success = success && !mxnet::op::shape_is_none(out_attrs->at(i + num_subgraphs)); } // sub_layer - mxnet::TShape out_layer_shape(1); + mxnet::TShape out_layer_shape(1, -1); out_layer_shape[0] = params.max_num_vertices; for (size_t i = 0; i < num_subgraphs; i++) { SHAPE_ASSIGN_CHECK(*out_attrs, i + 2*num_subgraphs, out_layer_shape); @@ -311,7 +311,7 @@ static bool CSRNeighborNonUniformSampleShape(const nnvm::NodeAttrs& attrs, // Output bool success = true; - mxnet::TShape out_shape(1); + mxnet::TShape out_shape(1, -1); // We use the last element to store the actual // number of vertices in the subgraph. out_shape[0] = params.max_num_vertices + 1; @@ -320,7 +320,7 @@ static bool CSRNeighborNonUniformSampleShape(const nnvm::NodeAttrs& attrs, success = success && !mxnet::op::shape_is_none(out_attrs->at(i)); } // sub_csr - mxnet::TShape out_csr_shape(2); + mxnet::TShape out_csr_shape(2, -1); out_csr_shape[0] = params.max_num_vertices; out_csr_shape[1] = in_attrs->at(0)[1]; for (size_t i = 0; i < num_subgraphs; i++) { @@ -328,14 +328,14 @@ static bool CSRNeighborNonUniformSampleShape(const nnvm::NodeAttrs& attrs, success = success && !mxnet::op::shape_is_none(out_attrs->at(i + num_subgraphs)); } // sub_probability - mxnet::TShape out_prob_shape(1); + mxnet::TShape out_prob_shape(1, -1); out_prob_shape[0] = params.max_num_vertices; for (size_t i = 0; i < num_subgraphs; i++) { SHAPE_ASSIGN_CHECK(*out_attrs, i + 2*num_subgraphs, out_prob_shape); success = success && !mxnet::op::shape_is_none(out_attrs->at(i + 2 * num_subgraphs)); } // sub_layer - mxnet::TShape out_layer_shape(1); + mxnet::TShape out_layer_shape(1, -1); out_layer_shape[0] = params.max_num_vertices; for (size_t i = 0; i < num_subgraphs; i++) { SHAPE_ASSIGN_CHECK(*out_attrs, i + 3*num_subgraphs, out_prob_shape); @@ -665,8 +665,8 @@ static void SampleSubgraph(const NDArray &csr, } } // Construct sub_csr_graph - mxnet::TShape shape_1(1); - mxnet::TShape shape_2(1); + mxnet::TShape shape_1(1, -1); + mxnet::TShape shape_2(1, -1); shape_1[0] = num_edges; shape_2[0] = max_num_vertices+1; sub_csr.CheckAndAllocData(shape_1); @@ -946,13 +946,13 @@ static bool DGLSubgraphShape(const nnvm::NodeAttrs& attrs, size_t num_g = params.num_args - 1; for (size_t i = 0; i < num_g; i++) { - mxnet::TShape gshape(2); + mxnet::TShape gshape(2, -1); gshape[0] = in_attrs->at(i + 1)[0]; gshape[1] = in_attrs->at(i + 1)[0]; out_attrs->at(i) = gshape; } for (size_t i = num_g; i < out_attrs->size(); i++) { - mxnet::TShape gshape(2); + mxnet::TShape gshape(2, -1); gshape[0] = in_attrs->at(i - num_g + 1)[0]; gshape[1] = in_attrs->at(i - num_g + 1)[0]; out_attrs->at(i) = gshape; @@ -1067,9 +1067,9 @@ static void GetSubgraph(const NDArray &csr_arr, const NDArray &varr, row_idx[i + 1] = col_idx.size(); } - mxnet::TShape nz_shape(1); + mxnet::TShape nz_shape(1, -1); nz_shape[0] = col_idx.size(); - mxnet::TShape indptr_shape(1); + mxnet::TShape indptr_shape(1, -1); indptr_shape[0] = row_idx.size(); // Store the non-zeros in a subgraph with edge attributes of new edge ids. @@ -1446,9 +1446,9 @@ static void CompactSubgraph(const NDArray &csr, const NDArray &vids, CHECK_NE(row_ids[i], -1); } - mxnet::TShape nz_shape(1); + mxnet::TShape nz_shape(1, -1); nz_shape[0] = num_elems; - mxnet::TShape indptr_shape(1); + mxnet::TShape indptr_shape(1, -1); CHECK_EQ(out_csr.shape()[0], graph_size); indptr_shape[0] = graph_size + 1; CHECK_GE(in_ptr_data.shape_[0], indptr_shape[0]); @@ -1526,7 +1526,7 @@ static bool SubgraphCompactShape(const nnvm::NodeAttrs& attrs, } for (size_t i = 0; i < num_g; i++) { - mxnet::TShape gshape(2); + mxnet::TShape gshape(2, -1); gshape[0] = params.graph_sizes[i]; gshape[1] = params.graph_sizes[i]; out_attrs->at(i) = gshape; diff --git a/src/operator/contrib/multibox_detection-inl.h b/src/operator/contrib/multibox_detection-inl.h index 977126ad269d..1ac14e237f0d 100644 --- a/src/operator/contrib/multibox_detection-inl.h +++ b/src/operator/contrib/multibox_detection-inl.h @@ -161,7 +161,7 @@ class MultiBoxDetectionProp : public OperatorProperty { CHECK_EQ(cshape[2] * 4, lshape[1]) << "# anchors mismatch with # loc"; CHECK_GT(ashape[1], 0U) << "Number of anchors must > 0"; CHECK_EQ(ashape[2], 4U); - mxnet::TShape oshape = mxnet::TShape(3); + mxnet::TShape oshape = mxnet::TShape(3, -1); oshape[0] = cshape[0]; oshape[1] = ashape[1]; oshape[2] = 6; // [id, prob, xmin, ymin, xmax, ymax] diff --git a/src/operator/contrib/multibox_prior-inl.h b/src/operator/contrib/multibox_prior-inl.h index 3636a6016bd2..d8929f3deff4 100644 --- a/src/operator/contrib/multibox_prior-inl.h +++ b/src/operator/contrib/multibox_prior-inl.h @@ -180,7 +180,7 @@ class MultiBoxPriorProp: public OperatorProperty { int in_width = dshape[3]; CHECK_GT(in_width, 0) << "Input width should > 0"; // since input sizes are same in each batch, we could share MultiBoxPrior - mxnet::TShape oshape = mxnet::TShape(3); + mxnet::TShape oshape = mxnet::TShape(3, -1); int num_sizes = param_.sizes.ndim(); int num_ratios = param_.ratios.ndim(); oshape[0] = 1; @@ -189,7 +189,7 @@ class MultiBoxPriorProp: public OperatorProperty { out_shape->clear(); out_shape->push_back(oshape); CHECK_EQ(param_.steps.ndim(), 2) << "Step ndim must be 2: (step_y, step_x)"; - return true; + return shape_is_known(oshape); } OperatorProperty* Copy() const override { diff --git a/src/operator/control_flow.cc b/src/operator/control_flow.cc index ac6fea7c143b..9ba3b5471c60 100644 --- a/src/operator/control_flow.cc +++ b/src/operator/control_flow.cc @@ -37,11 +37,11 @@ struct ForeachParam : public dmlc::Parameter { int num_outputs; int num_out_data; // The location of states in the subgraph inputs. - nnvm::Tuple in_state_locs; + mxnet::Tuple in_state_locs; // The location of data arrays in the subgraph inputs. - nnvm::Tuple in_data_locs; + mxnet::Tuple in_data_locs; // The location of remaining arrays in the subgraph inputs. - nnvm::Tuple remain_locs; + mxnet::Tuple remain_locs; DMLC_DECLARE_PARAMETER(ForeachParam) { DMLC_DECLARE_FIELD(num_args).set_lower_bound(1) .describe("Number of inputs."); @@ -82,7 +82,7 @@ static void ForeachComputeExCPU(const OpStatePtr& state_ptr, CHECK_GT(params.in_data_locs.ndim(), 0); size_t len = inputs[0].shape()[iter_dim]; state.num_iterations = len; - for (size_t i = 1; i < params.in_data_locs.ndim(); i++) + for (int i = 1; i < params.in_data_locs.ndim(); i++) CHECK_EQ(inputs[i].shape()[iter_dim], len); for (size_t i = 0; i < (size_t) params.num_out_data; i++) CHECK_EQ(len, outputs[i].shape()[iter_dim]); @@ -120,7 +120,7 @@ static void ForeachComputeExCPU(const OpStatePtr& state_ptr, // and the loop states. std::vector subg_inputs(inputs.size()); // The remaining arrays (other than input data and states) only need to be set once. - for (size_t j = 0; j < params.remain_locs.ndim(); j++) { + for (int j = 0; j < params.remain_locs.ndim(); j++) { CHECK_LT(params.remain_locs[j], subg_inputs.size()); subg_inputs[params.remain_locs[j]] = inputs[j + params.in_data_locs.ndim() + params.in_state_locs.ndim()]; @@ -148,7 +148,7 @@ static void ForeachComputeExCPU(const OpStatePtr& state_ptr, // Initialize inputs for the subgraph. // Get a slice from the input data arrays. - for (size_t j = 0; j < params.in_data_locs.ndim(); j++) { + for (int j = 0; j < params.in_data_locs.ndim(); j++) { size_t loc = params.in_data_locs[j]; subg_inputs[loc] = inputs[j].At(i); } @@ -161,7 +161,7 @@ static void ForeachComputeExCPU(const OpStatePtr& state_ptr, subg_inputs[params.in_state_locs[idx]] = (*subg_out_prev)[j]; } } else { - for (size_t j = 0; j < params.in_state_locs.ndim(); j++) { + for (int j = 0; j < params.in_state_locs.ndim(); j++) { CHECK_LT(params.in_state_locs[j], subg_inputs.size()); subg_inputs[params.in_state_locs[j]] = inputs[j + params.in_data_locs.ndim()]; } @@ -203,7 +203,7 @@ static void ForeachGradComputeExCPU(const OpStatePtr& state_ptr, // [data vars], [loop vars], [remaining vars] // [remaining vars] - for (size_t i = 0; i < params.remain_locs.ndim(); i++) { + for (int i = 0; i < params.remain_locs.ndim(); i++) { size_t loc = params.remain_locs[i]; size_t orig_loc = i + params.in_data_locs.ndim() + params.in_state_locs.ndim(); subg_igrads[loc] = outputs[orig_loc]; @@ -216,20 +216,20 @@ static void ForeachGradComputeExCPU(const OpStatePtr& state_ptr, if (iter_num < len - 1) { // For the rest of the iterations, we should add graidents to the // remaining vars. - for (size_t i = 0; i < params.remain_locs.ndim(); i++) { + for (int i = 0; i < params.remain_locs.ndim(); i++) { size_t loc = params.remain_locs[i]; subg_req[loc] = kAddTo; } } // [data vars] - for (size_t i = 0; i < params.in_data_locs.ndim(); i++) { + for (int i = 0; i < params.in_data_locs.ndim(); i++) { size_t loc = params.in_data_locs[i]; subg_igrads[loc] = outputs[i].At(iter_num); subg_req[loc] = req[i]; } // [loop vars] - for (size_t i = 0; i < params.in_state_locs.ndim(); i++) { + for (int i = 0; i < params.in_state_locs.ndim(); i++) { size_t loc = params.in_state_locs[i]; const NDArray &output = outputs[i + params.in_data_locs.ndim()]; if (iter_num != 0) { @@ -258,9 +258,9 @@ static void ForeachGradComputeExCPU(const OpStatePtr& state_ptr, template static void remap(const std::vector &op_in, size_t start, - const nnvm::Tuple &locs, std::vector *subg_in) { + const mxnet::Tuple &locs, std::vector *subg_in) { auto op_in_it = op_in.begin() + start; - for (size_t i = 0; i < locs.ndim(); i++) { + for (int i = 0; i < locs.ndim(); i++) { dim_t loc = locs[i]; subg_in->at(loc) = *(op_in_it + i); } @@ -284,7 +284,7 @@ static bool ForeachShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector subg_in_shape(in_shape->size()); // data shape std::vector data_1d(params.in_data_locs.ndim(), false); - for (size_t i = 0; i < params.in_data_locs.ndim(); i++) { + for (int i = 0; i < params.in_data_locs.ndim(); i++) { size_t loc = params.in_data_locs[i]; if (in_shape->at(i).ndim() == 1) data_1d[i] = true; @@ -301,7 +301,7 @@ static bool ForeachShape(const nnvm::NodeAttrs& attrs, for (int i = 0; i < params.num_out_data; i++) { mxnet::TShape shape = subg_out_shape[i]; // If we don't have shape info, we don't need to do anything. - if (shape.ndim() == 0) + if (!shape_is_known(shape)) continue; subg_out_shape[i] = SliceFirstDim(shape); } @@ -317,12 +317,12 @@ static bool ForeachShape(const nnvm::NodeAttrs& attrs, for (int i = 0; i < params.num_out_data; i++) { // If the output shape isn't inferred, we don't need to propogate the info. const auto& g_out_shape = subg_out_shape[i]; - if (g_out_shape.ndim() == 0) + if (!shape_is_known(g_out_shape)) continue; - auto out = mxnet::TShape(g_out_shape.ndim() + 1); + auto out = mxnet::TShape(g_out_shape.ndim() + 1, -1); out[0] = len; - for (size_t i = 1; i < out.ndim(); i++) + for (int i = 1; i < out.ndim(); i++) out[i] = g_out_shape[i - 1]; SHAPE_ASSIGN_CHECK(*out_shape, i, out); } @@ -331,34 +331,34 @@ static bool ForeachShape(const nnvm::NodeAttrs& attrs, SHAPE_ASSIGN_CHECK(*out_shape, i, subg_out_shape[i]); // For the shape of input data. - for (size_t i = 0; i < params.in_data_locs.ndim(); i++) { + for (int i = 0; i < params.in_data_locs.ndim(); i++) { size_t loc = params.in_data_locs[i]; const auto &shape = subg_in_shape[loc]; // If the input data shape isn't inferred, we don't need to propogate the // info. - if (shape.ndim() == 0) + if (!shape_is_known(shape)) continue; if (data_1d[i]) { - mxnet::TShape s(1); + mxnet::TShape s(1, -1); s[0] = len; SHAPE_ASSIGN_CHECK(*in_shape, i, s); } else { - auto in = mxnet::TShape(shape.ndim() + 1); + auto in = mxnet::TShape(shape.ndim() + 1, -1); in[0] = len; - for (size_t i = 1; i < in.ndim(); i++) + for (int i = 1; i < in.ndim(); i++) in[i] = shape[i - 1]; SHAPE_ASSIGN_CHECK(*in_shape, i, in); } } // For the shape of state. - for (size_t i = 0; i < params.in_state_locs.ndim(); i++) { + for (int i = 0; i < params.in_state_locs.ndim(); i++) { size_t loc = params.in_state_locs[i]; SHAPE_ASSIGN_CHECK(*in_shape, i + params.in_data_locs.ndim(), subg_in_shape[loc]); } // For the shape of remaining data. - for (size_t i = 0; i < params.remain_locs.ndim(); i++) { + for (int i = 0; i < params.remain_locs.ndim(); i++) { size_t loc = params.remain_locs[i]; SHAPE_ASSIGN_CHECK(*in_shape, i + params.in_data_locs.ndim() + params.in_state_locs.ndim(), @@ -387,15 +387,15 @@ static bool ForeachType(const nnvm::NodeAttrs& attrs, remap(*in_type, params.in_data_locs.ndim() + params.in_state_locs.ndim(), params.remain_locs, &subg_in_type); bool success = InferSubgraphDataType(*attrs.subgraphs[0], &subg_in_type, out_type); - for (size_t i = 0; i < params.in_data_locs.ndim(); i++) { + for (int i = 0; i < params.in_data_locs.ndim(); i++) { size_t loc = params.in_data_locs[i]; TYPE_ASSIGN_CHECK(*in_type, i, subg_in_type[loc]); } - for (size_t i = 0; i < params.in_state_locs.ndim(); i++) { + for (int i = 0; i < params.in_state_locs.ndim(); i++) { size_t loc = params.in_state_locs[i]; TYPE_ASSIGN_CHECK(*in_type, i + params.in_data_locs.ndim(), subg_in_type[loc]); } - for (size_t i = 0; i < params.remain_locs.ndim(); i++) { + for (int i = 0; i < params.remain_locs.ndim(); i++) { size_t loc = params.remain_locs[i]; TYPE_ASSIGN_CHECK(*in_type, i + params.in_data_locs.ndim() + params.in_state_locs.ndim(), subg_in_type[loc]); @@ -418,16 +418,16 @@ static bool ForeachStorageType(const nnvm::NodeAttrs& attrs, params.remain_locs, &subg_in_attrs); bool success = InferSubgraphStorage(*attrs.subgraphs[0], dev_mask, dispatch_mode, &subg_in_attrs, out_attrs); - for (size_t i = 0; i < params.in_data_locs.ndim(); i++) { + for (int i = 0; i < params.in_data_locs.ndim(); i++) { size_t loc = params.in_data_locs[i]; STORAGE_TYPE_ASSIGN_CHECK(*in_attrs, i, subg_in_attrs[loc]); } - for (size_t i = 0; i < params.in_state_locs.ndim(); i++) { + for (int i = 0; i < params.in_state_locs.ndim(); i++) { size_t loc = params.in_state_locs[i]; STORAGE_TYPE_ASSIGN_CHECK(*in_attrs, i + params.in_data_locs.ndim(), subg_in_attrs[loc]); } - for (size_t i = 0; i < params.remain_locs.ndim(); i++) { + for (int i = 0; i < params.remain_locs.ndim(); i++) { size_t loc = params.remain_locs[i]; STORAGE_TYPE_ASSIGN_CHECK(*in_attrs, i + params.in_data_locs.ndim() + params.in_state_locs.ndim(), @@ -488,9 +488,9 @@ struct WhileLoopParam : public dmlc::Parameter { // `cond_input_locs' contains indices of inputs fed to `cond', and // `func_input_locs' contains indices of inputs fed to `func'. // `func_var_locs' are indices in which input "variables" are stored in func's inputs. - nnvm::Tuple cond_input_locs; - nnvm::Tuple func_input_locs; - nnvm::Tuple func_var_locs; + mxnet::Tuple cond_input_locs; + mxnet::Tuple func_input_locs; + mxnet::Tuple func_var_locs; DMLC_DECLARE_PARAMETER(WhileLoopParam) { DMLC_DECLARE_FIELD(num_args).set_lower_bound(2) .describe("Number of input arguments, including cond and func as two symbol inputs."); @@ -538,12 +538,12 @@ class WhileLoopState: public LoopState { n_iterations(0U), cond_op(LoopState::MakeSharedOp(cond)), oi_map(params.func_var_locs.ndim(), -1) { - const nnvm::Tuple &func_input_locs = params.func_input_locs; - const nnvm::Tuple &func_var_locs = params.func_var_locs; - const nnvm::Tuple &cond_input_locs = params.cond_input_locs; - for (size_t i = 0; i < func_var_locs.ndim(); ++i) { + const mxnet::Tuple &func_input_locs = params.func_input_locs; + const mxnet::Tuple &func_var_locs = params.func_var_locs; + const mxnet::Tuple &cond_input_locs = params.cond_input_locs; + for (int i = 0; i < func_var_locs.ndim(); ++i) { dim_t pos_i = func_input_locs[func_var_locs[i]]; - for (size_t j = 0; j < cond_input_locs.ndim(); ++j) { + for (int j = 0; j < cond_input_locs.ndim(); ++j) { dim_t pos_j = cond_input_locs[j]; if (pos_i == pos_j) { this->oi_map[i] = j; @@ -740,7 +740,7 @@ static bool WhileLoopShape(const nnvm::NodeAttrs& attrs, // infer shape for cond and func auto infer_subg = [¶ms, in_shape, out_shape](std::shared_ptr subg, ShapeVector *_subg_out, - const nnvm::Tuple &input_locs, + const mxnet::Tuple &input_locs, int num_out_data, bool fill_out_shape) { // create subg_in @@ -781,7 +781,7 @@ static bool WhileLoopShape(const nnvm::NodeAttrs& attrs, for (size_t i = 0; i < subg_in.size(); ++i) { auto eid = idx.entry_id(input_nids[i], 0); auto g_out_shape = new_shapes[eid]; - if (g_out_shape.ndim() == 0 || g_out_shape.Size() == 0) { + if (!shape_is_known(g_out_shape)) { // when the shape is not fully inferred continue; } @@ -795,13 +795,13 @@ static bool WhileLoopShape(const nnvm::NodeAttrs& attrs, for (int i = 0; i < num_out_data; ++i) { auto eid = idx.entry_id(g.outputs[i]); auto g_out_shape = new_shapes[eid]; - if (g_out_shape.ndim() == 0 || g_out_shape.Size() == 0) { + if (!shape_is_known(g_out_shape)) { // when the shape is not fully inferred continue; } - auto out = mxnet::TShape(g_out_shape.ndim() + 1); + auto out = mxnet::TShape(g_out_shape.ndim() + 1, -1); out[0] = params.max_iterations; - for (size_t i = 1; i < out.ndim(); i++) + for (int i = 1; i < out.ndim(); i++) out[i] = g_out_shape[i - 1]; SHAPE_ASSIGN_CHECK(*out_shape, i, out); } @@ -809,7 +809,7 @@ static bool WhileLoopShape(const nnvm::NodeAttrs& attrs, for (size_t i = num_out_data; i < g.outputs.size(); ++i) { auto eid = idx.entry_id(g.outputs[i]); auto g_out_shape = new_shapes[eid]; - if (g_out_shape.ndim() == 0 || g_out_shape.Size() == 0) { + if (!shape_is_known(g_out_shape)) { // when the shape is not fully inferred continue; } @@ -817,7 +817,7 @@ static bool WhileLoopShape(const nnvm::NodeAttrs& attrs, } return g.GetAttr("shape_num_unknown_nodes") == 0; }; - mxnet::ShapeVector cond_out_shape{mxnet::TShape(1U)}; // this means: [(1, )] + mxnet::ShapeVector cond_out_shape{mxnet::TShape(1, 1)}; // this means: [(1, )] mxnet::ShapeVector func_out_shape(params.num_outputs); CHECK(params.sync_in_out(in_shape, out_shape, is_udf)); bool succ_0 = infer_subg(attrs.subgraphs[0], &cond_out_shape, params.cond_input_locs, 0, false); @@ -915,9 +915,9 @@ WhileLoopGradient(const nnvm::NodePtr& n, const std::vector& og struct CondParam : public dmlc::Parameter { int num_args; int num_outputs; - nnvm::Tuple cond_input_locs; - nnvm::Tuple then_input_locs; - nnvm::Tuple else_input_locs; + mxnet::Tuple cond_input_locs; + mxnet::Tuple then_input_locs; + mxnet::Tuple else_input_locs; DMLC_DECLARE_PARAMETER(CondParam) { DMLC_DECLARE_FIELD(num_args).set_lower_bound(3) .describe("Number of input arguments, including cond, then and else as three symbol inputs."); @@ -992,7 +992,7 @@ static void CondComputeExCPU(const OpStatePtr& state_ptr, state.cond_op->Forward(nullptr, cond_input_ptr, cond_output_ptr); branch_selection = as_bool_scalar(*cond_output_ptr[0]); // select the right branch - const nnvm::Tuple &func_input_locs = branch_selection + const mxnet::Tuple &func_input_locs = branch_selection ? params.then_input_locs : params.else_input_locs; LoopState &loop_state = branch_selection @@ -1017,7 +1017,7 @@ static void CondGradComputeExCPU(const OpStatePtr& state_ptr, // select the right branch int branch_selection = state.branch_selection; CHECK_NE(branch_selection, -1); - const nnvm::Tuple &func_input_locs = branch_selection + const mxnet::Tuple &func_input_locs = branch_selection ? params.then_input_locs : params.else_input_locs; LoopState &loop_state = branch_selection @@ -1048,7 +1048,7 @@ static bool CondShape(const nnvm::NodeAttrs& attrs, // infer shape for cond, then and else auto infer_subg = [¶ms, in_shape, out_shape](std::shared_ptr subg, ShapeVector *_subg_out, - const nnvm::Tuple &input_locs, + const mxnet::Tuple &input_locs, bool fill_out_shape) { // create subg_in mxnet::ShapeVector subg_in; @@ -1086,7 +1086,7 @@ static bool CondShape(const nnvm::NodeAttrs& attrs, for (size_t i = 0; i < subg_in.size(); ++i) { auto eid = idx.entry_id(input_nids[i], 0); auto g_out_shape = new_shapes[eid]; - if (g_out_shape.ndim() == 0 || g_out_shape.Size() == 0) { + if (!shape_is_known(g_out_shape)) { // when the shape is not fully inferred continue; } @@ -1099,7 +1099,7 @@ static bool CondShape(const nnvm::NodeAttrs& attrs, for (size_t i = 0; i < g.outputs.size(); ++i) { auto eid = idx.entry_id(g.outputs[i]); auto g_out_shape = new_shapes[eid]; - if (g_out_shape.ndim() == 0 || g_out_shape.Size() == 0) { + if (!shape_is_known(g_out_shape)) { // when the shape is not fully inferred continue; } @@ -1107,7 +1107,7 @@ static bool CondShape(const nnvm::NodeAttrs& attrs, } return g.GetAttr("shape_num_unknown_nodes") == 0; }; - ShapeVector cond_out_shape{mxnet::TShape(1U)}; // this means: [(1, )] + ShapeVector cond_out_shape{mxnet::TShape(1, 1)}; // this means: [(1, )] ShapeVector then_out_shape(params.num_outputs); ShapeVector else_out_shape(params.num_outputs); bool succ_0 = infer_subg(attrs.subgraphs[0], &cond_out_shape, \ @@ -1190,7 +1190,7 @@ static bool BackwardCondStorageType(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size() + 3U, (size_t) params.num_args); CHECK_EQ(attrs.subgraphs.size(), 3U); static const std::function is_udf = is_stype_udf; - auto sub_pass = [&](const std::shared_ptr &subg, const nnvm::Tuple &input_locs) { + auto sub_pass = [&](const std::shared_ptr &subg, const mxnet::Tuple &input_locs) { // A. first construct subg_in_attrs // need subg_in_attrs as subg_bwd_out (copy), subg_fwd_in (extract), subg_fwd_out (copy) std::vector subg_in_attrs; diff --git a/src/operator/convolution_v1-inl.h b/src/operator/convolution_v1-inl.h index ed6748a9c85c..0d6ffd7e895e 100644 --- a/src/operator/convolution_v1-inl.h +++ b/src/operator/convolution_v1-inl.h @@ -64,11 +64,11 @@ struct ConvolutionV1Param : public dmlc::Parameter { dmlc::optional layout; DMLC_DECLARE_PARAMETER(ConvolutionV1Param) { DMLC_DECLARE_FIELD(kernel).describe("convolution kernel size: (h, w) or (d, h, w)"); - DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape(0, 0)) .describe("convolution stride: (h, w) or (d, h, w)"); - DMLC_DECLARE_FIELD(dilate).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(dilate).set_default(mxnet::TShape(0, 0)) .describe("convolution dilate: (h, w) or (d, h, w)"); - DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape(0, 0)) .describe("pad for convolution: (h, w) or (d, h, w)"); DMLC_DECLARE_FIELD(num_filter).set_range(1, 100000) .describe("convolution filter(channel) number"); @@ -405,7 +405,7 @@ class ConvolutionV1Prop : public OperatorProperty { // CHECK_EQ(out_shape->size(), 1) << "Output: [output]"; out_shape->resize(1, mxnet::TShape()); const mxnet::TShape &dshp = (*in_shape)[conv_v1::kData]; - if (dshp.ndim() == 0) return false; + if (!shape_is_known(dshp)) return false; if (param_.kernel.ndim() == 2) { // 2d conv_v1 CHECK_EQ(dshp.ndim(), 4U) \ diff --git a/src/operator/image/image_random-inl.h b/src/operator/image/image_random-inl.h index c37324678120..182cd682af8b 100644 --- a/src/operator/image/image_random-inl.h +++ b/src/operator/image/image_random-inl.h @@ -93,7 +93,7 @@ inline bool ToTensorShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); mxnet::TShape &shp = (*in_attrs)[0]; - if (!shp.ndim()) return false; + if (!shape_is_known(shp)) return false; CHECK((shp.ndim() == 3) || (shp.ndim() == 4)) << "Input image must have shape (height, width, channels), or " @@ -549,7 +549,7 @@ template void FlipImpl(const mxnet::TShape &shape, DType *src, DType *dst) { int head = 1, mid = shape[axis], tail = 1; for (int i = 0; i < axis; ++i) head *= shape[i]; - for (uint32_t i = axis+1; i < shape.ndim(); ++i) tail *= shape[i]; + for (int i = axis+1; i < shape.ndim(); ++i) tail *= shape[i]; for (int i = 0; i < head; ++i) { for (int j = 0; j < (mid >> 1); ++j) { diff --git a/src/operator/image/resize-inl.h b/src/operator/image/resize-inl.h index de2189838d76..4ebebbfb272c 100644 --- a/src/operator/image/resize-inl.h +++ b/src/operator/image/resize-inl.h @@ -49,12 +49,12 @@ void ResizeImplCUDA(Stream *s, #endif // MXNET_USE_CUDA struct ResizeParam : public dmlc::Parameter { - nnvm::Tuple size; + mxnet::Tuple size; bool keep_ratio; int interp; DMLC_DECLARE_PARAMETER(ResizeParam) { DMLC_DECLARE_FIELD(size) - .set_default(nnvm::Tuple()) + .set_default(mxnet::Tuple()) .describe("Size of new image. Could be (width, height) or (size)"); DMLC_DECLARE_FIELD(keep_ratio) .describe("Whether to resize the short edge or both edges to `size`, " diff --git a/src/operator/leaky_relu-inl.h b/src/operator/leaky_relu-inl.h index cfdd1064d6fb..aef990010818 100644 --- a/src/operator/leaky_relu-inl.h +++ b/src/operator/leaky_relu-inl.h @@ -315,7 +315,7 @@ class LeakyReLUOp : public Operator { return a < b ? (a < c ? a : c) : (b < c ? b : c); } static inline mxnet::TShape expand_shape(const mxnet::TShape& src, const mxnet::TShape& dst) { - mxnet::TShape result(dst.ndim()); + mxnet::TShape result(dst.ndim(), -1); int s = src.ndim() - 1; for (int i = dst.ndim() - 1; i >= 0; i--) { if (s >= 0 && i <= 1 && (dst[i] == src[s] || src[s] == 1)) { diff --git a/src/operator/loss_binary_op-inl.h b/src/operator/loss_binary_op-inl.h index a3853c56359a..1d71993da515 100644 --- a/src/operator/loss_binary_op-inl.h +++ b/src/operator/loss_binary_op-inl.h @@ -43,7 +43,7 @@ inline bool SoftmaxCrossEntropyShape(const nnvm::NodeAttrs& attrs, << "SoftmaxCrossEntropy only accept 1D label"; CHECK_EQ((*in_attrs)[0][0], (*in_attrs)[1][0]) << "SoftmaxCrossEntropy: data label shape mismatch"; - SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape(1)); + SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape(1, 1)); return true; } diff --git a/src/operator/nn/batch_norm.cc b/src/operator/nn/batch_norm.cc index 511fe455e946..590b1b428023 100644 --- a/src/operator/nn/batch_norm.cc +++ b/src/operator/nn/batch_norm.cc @@ -332,7 +332,7 @@ static bool BatchNormShape(const nnvm::NodeAttrs& attrs, const int channelCount = dshape[channelAxis]; - if (dshape.ndim() == 0) { + if (!shape_is_known(dshape)) { return false; } diff --git a/src/operator/nn/concat.cc b/src/operator/nn/concat.cc index fa441c45321e..5435bd815334 100644 --- a/src/operator/nn/concat.cc +++ b/src/operator/nn/concat.cc @@ -39,39 +39,40 @@ static bool ConcatShape(const nnvm::NodeAttrs& attrs, const ConcatParam& param_ = nnvm::get(attrs.parsed); CHECK_EQ(in_shape->size(), static_cast(param_.num_args)); mxnet::TShape dshape; - index_t size = 0; - bool has_zero = false; + dim_t size = 0; + bool has_unknown_dim_size = false; int axis = -1; for (int i = 0; i < param_.num_args; ++i) { mxnet::TShape tmp = (*in_shape)[i]; - if (tmp.ndim()) { + if (tmp.ndim() > 0) { axis = CheckAxis(param_.dim, tmp.ndim()); - has_zero = tmp[axis] == 0 || has_zero; + has_unknown_dim_size = tmp[axis] == -1 || has_unknown_dim_size; size += tmp[axis]; - tmp[axis] = 0; + tmp[axis] = -1; shape_assign(&dshape, tmp); } } mxnet::TShape tmp = (*out_shape)[0]; - if (tmp.ndim()) { + if (tmp.ndim() > 0) { axis = CheckAxis(param_.dim, tmp.ndim()); - tmp[axis] = 0; + tmp[axis] = -1; shape_assign(&dshape, tmp); } - if (dshape.ndim() == 0) return false; + if (dshape.ndim() == -1) return false; + CHECK_NE(dshape.ndim(), 0) << "zero-dimensional arrays cannot be concatenated"; for (int i = 0; i < param_.num_args; ++i) { CHECK(shape_assign(&(*in_shape)[i], dshape)) << "Incompatible input shape: expected " << dshape << ", got " << (*in_shape)[i]; } - if (!has_zero) dshape[axis] = size; + if (!has_unknown_dim_size) dshape[axis] = size; CHECK(shape_assign(&(*out_shape)[0], dshape)) << "Incompatible output shape: expected " << dshape << ", got " << (*out_shape)[0]; - return dshape.Size() != 0; + return shape_is_known(dshape); } // Concat for RNN param deals with the reverse shape inference from output @@ -109,7 +110,7 @@ static bool RNNParamConcatShape(const nnvm::NodeAttrs& attrs, shape_assign(&dshape, tmp); } - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; for (int i = 0; i < param_.num_args; ++i) { CHECK(shape_assign(&(*in_shape)[i], dshape)) @@ -232,7 +233,7 @@ bool SupportMKLDNNConcat(const std::vector &arrs) { for (auto &arr : arrs) { if (arr.IsView()) return false; if (arr.dtype() != mshadow::kFloat32) return false; - unsigned ndim = arr.shape().ndim(); + int ndim = arr.shape().ndim(); unsigned mkldnn_ndims = static_cast(arr.GetMKLDNNData()->get_primitive_desc().desc().data.ndims); if (!(ndim == 2 || ndim == 4) || ndim != mkldnn_ndims) return false; diff --git a/src/operator/nn/convolution-inl.h b/src/operator/nn/convolution-inl.h index 7ae34ae363b4..7d5f7c7d5757 100644 --- a/src/operator/nn/convolution-inl.h +++ b/src/operator/nn/convolution-inl.h @@ -69,11 +69,11 @@ struct ConvolutionParam : public dmlc::Parameter { dmlc::optional layout; DMLC_DECLARE_PARAMETER(ConvolutionParam) { DMLC_DECLARE_FIELD(kernel).describe("Convolution kernel size: (w,), (h, w) or (d, h, w)"); - DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape(0, 0)) .describe("Convolution stride: (w,), (h, w) or (d, h, w). Defaults to 1 for each dimension."); - DMLC_DECLARE_FIELD(dilate).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(dilate).set_default(mxnet::TShape(0, 0)) .describe("Convolution dilate: (w,), (h, w) or (d, h, w). Defaults to 1 for each dimension."); - DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape(0, 0)) .describe("Zero pad for convolution: (w,), (h, w) or (d, h, w). Defaults to no padding."); DMLC_DECLARE_FIELD(num_filter).set_range(1, 100000) .describe("Convolution filter(channel) number"); @@ -209,9 +209,9 @@ class ConvolutionOp { Tensor workspace = ctx.requested[conv::kTempSpace] .get_space_typed(Shape1(col_buffer_size_), s); // calculate the shape of col_buffer - mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1); + mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1, 1); col_buffer_shape[0] = conv_in_channels_ * param_.kernel.Size(); - for (index_t i = 1; i < col_buffer_shape.ndim(); ++i) { + for (int i = 1; i < col_buffer_shape.ndim(); ++i) { col_buffer_shape[i] = out_data[0].shape_[i+1]; } // create a column buffer using workspace and col_buffer_shape @@ -295,9 +295,9 @@ class ConvolutionOp { Tensor workspace = ctx.requested[conv::kTempSpace] .get_space_typed(Shape1(col_buffer_size_), s); // calculate the shape of col_buffer - mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1); + mxnet::TShape col_buffer_shape(num_spatial_axes_ + 1, 1); col_buffer_shape[0] = conv_in_channels_ * param_.kernel.Size(); - for (index_t i = 1; i < col_buffer_shape.ndim(); ++i) { + for (int i = 1; i < col_buffer_shape.ndim(); ++i) { col_buffer_shape[i] = out_grad[conv::kData].shape_[i+1]; } // create a column buffer using workspace and col_buffer_shape @@ -342,10 +342,10 @@ class ConvolutionOp { void LayerSetUp(const mxnet::TShape& ishape, const mxnet::TShape& oshape) { channel_axis_ = 1; // hard code channel axis const index_t first_spatial_axis = channel_axis_ + 1; - const index_t num_axes = param_.kernel.ndim() + 2; + const int num_axes = param_.kernel.ndim() + 2; num_spatial_axes_ = num_axes - first_spatial_axis; is_1x1_ = true; - for (index_t i = 0; i < param_.kernel.ndim(); ++i) { + for (int i = 0; i < param_.kernel.ndim(); ++i) { is_1x1_ &= param_.kernel[i] == 1 && param_.stride[i] == 1 && param_.pad[i] == 0; if (!is_1x1_) break; } diff --git a/src/operator/nn/convolution.cc b/src/operator/nn/convolution.cc index 527a0073930f..dfbc89de7b0e 100644 --- a/src/operator/nn/convolution.cc +++ b/src/operator/nn/convolution.cc @@ -96,7 +96,7 @@ static bool ConvolutionShape(const nnvm::NodeAttrs& attrs, // CHECK_EQ(out_shape->size(), 1) << "Output: [output]"; out_shape->resize(1, mxnet::TShape()); const mxnet::TShape &dshp = (*in_shape)[conv::kData]; - if (dshp.ndim() == 0) return false; + if (!shape_is_known(dshp)) return false; if (param_.kernel.ndim() == 1) { // 1d conv diff --git a/src/operator/nn/ctc_loss-inl.h b/src/operator/nn/ctc_loss-inl.h index 357888dc30f1..8c841dfc24b4 100644 --- a/src/operator/nn/ctc_loss-inl.h +++ b/src/operator/nn/ctc_loss-inl.h @@ -239,7 +239,7 @@ inline bool CTCLossOpShape(const nnvm::NodeAttrs &attrs, "the maximum sequence length of the " "data."; - mxnet::TShape oshape(1); + mxnet::TShape oshape(1, -1); oshape[0] = dshape[1]; // batch size SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); // forward output SHAPE_ASSIGN_CHECK(*out_attrs, 1, dshape); // grad output diff --git a/src/operator/nn/cudnn/cudnn_batch_norm.cc b/src/operator/nn/cudnn/cudnn_batch_norm.cc index 5632028dd769..1df888e4b38a 100644 --- a/src/operator/nn/cudnn/cudnn_batch_norm.cc +++ b/src/operator/nn/cudnn/cudnn_batch_norm.cc @@ -37,7 +37,7 @@ static bool BatchNormShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector *in_ using namespace mshadow; CHECK_EQ(in_shape->size(), 5U) << "Input:[data, gamma, beta, moving_mean, moving_var]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; in_shape->at(1) = mxnet::TShape(Shape1(dshape[1])); in_shape->at(2) = mxnet::TShape(Shape1(dshape[1])); in_shape->at(3) = mxnet::TShape(Shape1(dshape[1])); diff --git a/src/operator/nn/cudnn/cudnn_convolution-inl.h b/src/operator/nn/cudnn/cudnn_convolution-inl.h index 55b263896339..44d1c3c36e99 100644 --- a/src/operator/nn/cudnn/cudnn_convolution-inl.h +++ b/src/operator/nn/cudnn/cudnn_convolution-inl.h @@ -1015,9 +1015,9 @@ class CuDNNConvolutionOp { // e.g. {shape[0], shape[1], shape[2]} -> {shape[1]*shape[2], shape[2], 1} template inline Shape Strides(const mxnet::TShape &s) { - uint32_t ndim = s.ndim(); + int ndim = s.ndim(); mxnet::TShape strides(ndim); - for (uint32_t i = 0; i != ndim; ++i) + for (int i = 0; i != ndim; ++i) strides[i] = s.ProdShape(i+1, ndim); return strides.get(); } diff --git a/src/operator/nn/cudnn/cudnn_deconvolution-inl.h b/src/operator/nn/cudnn/cudnn_deconvolution-inl.h index 47f688c8ab9c..f652dd85bd41 100644 --- a/src/operator/nn/cudnn/cudnn_deconvolution-inl.h +++ b/src/operator/nn/cudnn/cudnn_deconvolution-inl.h @@ -933,9 +933,9 @@ class CuDNNDeconvolutionOp { // e.g. {shape[0], shape[1], shape[2]} -> {shape[1]*shape[2], shape[2], 1} template inline Shape Strides(const mxnet::TShape &s) { - uint32_t ndim = s.ndim(); + int ndim = s.ndim(); mxnet::TShape strides(ndim); - for (uint32_t i = 0; i != ndim; ++i) + for (int i = 0; i != ndim; ++i) strides[i] = s.ProdShape(i+1, ndim); return strides.get(); } diff --git a/src/operator/nn/deconvolution-inl.h b/src/operator/nn/deconvolution-inl.h index 5248c1211ac7..b28e47818392 100644 --- a/src/operator/nn/deconvolution-inl.h +++ b/src/operator/nn/deconvolution-inl.h @@ -65,13 +65,13 @@ struct DeconvolutionParam : public dmlc::Parameter { DMLC_DECLARE_PARAMETER(DeconvolutionParam) { DMLC_DECLARE_FIELD(kernel).describe("Deconvolution kernel size: (w,), (h, w) or (d, h, w). " "This is same as the kernel size used for the corresponding convolution"); - DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape(0, 0)) .describe("The stride used for the corresponding convolution: (w,), (h, w) or (d, h, w). " "Defaults to 1 for each dimension."); - DMLC_DECLARE_FIELD(dilate).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(dilate).set_default(mxnet::TShape(0, 0)) .describe("Dilation factor for each dimension of the input: (w,), (h, w) or (d, h, w). " "Defaults to 1 for each dimension."); - DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape(0, 0)) .describe("The amount of implicit zero padding added during convolution for each " "dimension of the input: " "(w,), (h, w) or (d, h, w). " @@ -79,11 +79,11 @@ struct DeconvolutionParam : public dmlc::Parameter { "If `target_shape` is set, " "`pad` will be ignored and a padding that will generate the target shape " "will be used. Defaults to no padding."); - DMLC_DECLARE_FIELD(adj).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(adj).set_default(mxnet::TShape(0, 0)) .describe("Adjustment for output shape: (w,), (h, w) or (d, h, w). " "If `target_shape` is set, " "`adj` will be ignored and computed accordingly."); - DMLC_DECLARE_FIELD(target_shape).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(target_shape).set_default(mxnet::TShape(0, 0)) .describe("Shape of the output tensor: (w,), (h, w) or (d, h, w)."); DMLC_DECLARE_FIELD(num_filter).set_range(1, 100000) .describe("Number of output filters."); diff --git a/src/operator/nn/deconvolution.cc b/src/operator/nn/deconvolution.cc index 27928b9b41c3..d8c91f7f96c8 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 (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; if (param_.kernel.ndim() == 1) { // 1d conv diff --git a/src/operator/nn/dropout-inl.h b/src/operator/nn/dropout-inl.h index 82bdda69dcd0..4dda43bb9857 100644 --- a/src/operator/nn/dropout-inl.h +++ b/src/operator/nn/dropout-inl.h @@ -75,7 +75,7 @@ struct DropoutParam : public dmlc::Parameter { .add_enum("always", dropout::kAlways) .set_default(dropout::kTraining) .describe("Whether to only turn on dropout during training or to also turn on for inference."); - DMLC_DECLARE_FIELD(axes).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(axes).set_default(mxnet::TShape(0, 0)) .describe("Axes for variational dropout kernel."); DMLC_DECLARE_FIELD(cudnn_off).set_default(dmlc::optional(false)) .describe("Whether to turn off cudnn in dropout operator. " diff --git a/src/operator/nn/dropout.cc b/src/operator/nn/dropout.cc index 5fdc672d766e..0e4d18b1fda8 100644 --- a/src/operator/nn/dropout.cc +++ b/src/operator/nn/dropout.cc @@ -95,10 +95,10 @@ Example:: CHECK_EQ(in_shape->size(), 1U); const DropoutParam& param = nnvm::get(attrs.parsed); mxnet::TShape dshape(in_shape->at(0)); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; out_shape->clear(); out_shape->push_back(dshape); - for (index_t i = 0; i < param.axes.ndim(); ++i) { + for (int i = 0; i < param.axes.ndim(); ++i) { dshape[param.axes[i]] = 1; } out_shape->push_back(dshape); diff --git a/src/operator/nn/fully_connected.cc b/src/operator/nn/fully_connected.cc index 2bc321832af6..98277c206dd6 100644 --- a/src/operator/nn/fully_connected.cc +++ b/src/operator/nn/fully_connected.cc @@ -52,7 +52,7 @@ static bool FullyConnectedShape(const nnvm::NodeAttrs& attrs, mxnet::TShape dshape = (*in_shape)[fullc::kData]; mxnet::TShape oshape = (*out_shape)[0]; // require data to be known - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; index_t num_input; if (!param.flatten) { @@ -75,7 +75,7 @@ static bool FullyConnectedShape(const nnvm::NodeAttrs& attrs, } else { SHAPE_ASSIGN_CHECK(*out_shape, 0, Shape2(dshape[0], param.num_hidden)); } - if (oshape.ndim() != 0) { + if (oshape.ndim() > 0) { dshape[0] = oshape[0]; SHAPE_ASSIGN_CHECK(*in_shape, fullc::kData, dshape); } diff --git a/src/operator/nn/im2col.h b/src/operator/nn/im2col.h index 0059a420726d..06a4e1b75b33 100644 --- a/src/operator/nn/im2col.h +++ b/src/operator/nn/im2col.h @@ -152,7 +152,7 @@ inline void im2col_nd_core_cpu(const DType* data_input, const bool im2col, const mxnet::TShape& kernel_shape, const mxnet::TShape& pad, const mxnet::TShape& stride, const mxnet::TShape& dilation, DType* data_output, OpReqType req = mxnet::kWriteTo) { if (mxnet::kNullOp == req) return; - index_t num_spatial_axes = kernel_shape.ndim(); + int num_spatial_axes = kernel_shape.ndim(); if (!im2col) { index_t im_size = im_shape[1]; // skip batch dim for (index_t i = 0; i < num_spatial_axes; ++i) { @@ -319,7 +319,7 @@ inline void col2im(mshadow::Stream* s, const mxnet::TShape& col_shape, const mxnet::TShape& kernel_shape, const mxnet::TShape& pad, const mxnet::TShape& stride, const mxnet::TShape& dilation, DType* data_im, OpReqType req) { - index_t num_spatial_axes = kernel_shape.ndim(); + int num_spatial_axes = kernel_shape.ndim(); if (2 == num_spatial_axes) { col2im_cpu(data_col, im_shape[1], im_shape[2], im_shape[3], kernel_shape[0], kernel_shape[1], pad[0], pad[1], diff --git a/src/operator/nn/layer_norm-inl.h b/src/operator/nn/layer_norm-inl.h index dc4914bf2457..c7de7d734521 100644 --- a/src/operator/nn/layer_norm-inl.h +++ b/src/operator/nn/layer_norm-inl.h @@ -167,7 +167,7 @@ void LayerNormGradCompute(const nnvm::NodeAttrs& attrs, const LayerNormParam& param = nnvm::get(attrs.parsed); int axis = param.axis; if (axis < 0) { - axis += static_cast(inputs[0].ndim()); + axis += inputs[0].ndim(); } CHECK(axis >= 0 && axis < inputs[0].ndim()) << "Channel axis out of range: " << param.axis; Stream *s = ctx.get_stream(); diff --git a/src/operator/nn/layer_norm.cc b/src/operator/nn/layer_norm.cc index d4c308398cb7..1b0e99d8fe87 100644 --- a/src/operator/nn/layer_norm.cc +++ b/src/operator/nn/layer_norm.cc @@ -41,14 +41,14 @@ static bool LayerNormShape(const nnvm::NodeAttrs& attrs, const mxnet::TShape &dshape = in_shape->at(layernorm::kData); int axis = param.axis; if (axis < 0) { - axis += static_cast(dshape.ndim()); + axis += dshape.ndim(); } - CHECK(axis >= 0 && axis < static_cast(dshape.ndim())) + CHECK(axis >= 0 && axis < dshape.ndim()) << "Channel axis out of range: axis=" << param.axis; const int channelCount = dshape[axis]; - if (dshape.ndim() == 0) { + if (!shape_is_known(dshape)) { return false; } diff --git a/src/operator/nn/lrn.cc b/src/operator/nn/lrn.cc index 410bdab667e5..b632e35b57fe 100644 --- a/src/operator/nn/lrn.cc +++ b/src/operator/nn/lrn.cc @@ -40,7 +40,7 @@ bool LRNShape(const nnvm::NodeAttrs& attrs, using namespace mshadow; CHECK_EQ(in_shape->size(), 1U) << "Input:[data]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; out_shape->clear(); out_shape->push_back(dshape); out_shape->push_back(dshape); diff --git a/src/operator/nn/pooling-inl.h b/src/operator/nn/pooling-inl.h index 9e1e73bf19e2..03f0fa8edd6c 100644 --- a/src/operator/nn/pooling-inl.h +++ b/src/operator/nn/pooling-inl.h @@ -55,7 +55,7 @@ struct PoolingParam : public dmlc::Parameter { dmlc::optional count_include_pad; dmlc::optional layout; DMLC_DECLARE_PARAMETER(PoolingParam) { - DMLC_DECLARE_FIELD(kernel).set_default(mxnet::TShape()) // add default value here + DMLC_DECLARE_FIELD(kernel).set_default(mxnet::TShape(0, 0)) // add default value here .enforce_nonzero() .describe("Pooling kernel size: (y, x) or (d, y, x)"); @@ -78,11 +78,11 @@ struct PoolingParam : public dmlc::Parameter { .add_enum("same", pool_enum::kSame) .describe("Pooling convention to be applied."); - DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(stride).set_default(mxnet::TShape(0, 0)) .enforce_nonzero() .describe("Stride: for pooling (y, x) or (d, y, x). Defaults to 1 for each dimension."); - DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(pad).set_default(mxnet::TShape(0, 0)) .describe("Pad for pooling: (y, x) or (d, y, x). Defaults to no padding."); DMLC_DECLARE_FIELD(p_value).set_default(dmlc::optional()) @@ -200,11 +200,11 @@ class PoolingOp { kernel = mxnet::TShape(ishape.data() + 2, ishape.data() + ishape.ndim()); } - padding = mxnet::TShape(ishape.ndim() - 2); + padding = mxnet::TShape(ishape.ndim() - 2, 0); for (index_t i = 0; i < ishape.ndim() - 2; i++) { padding[i] = 0; } - stride = mxnet::TShape(ishape.ndim() - 2); + stride = mxnet::TShape(ishape.ndim() - 2, 1); } const int p_value = (param_.pool_type == pool_enum::kLpPooling && param_.p_value.has_value()) ? param_.p_value.value() : 1; @@ -257,11 +257,11 @@ class PoolingOp { kernel = mxnet::TShape(ishape.data() + 2, ishape.data() + ishape.ndim()); } - padding = mxnet::TShape(ishape.ndim() - 2); + padding = mxnet::TShape(ishape.ndim() - 2, 0); for (index_t i = 0; i < ishape.ndim() - 2; i++) { padding[i] = 0; } - stride = mxnet::TShape(ishape.ndim() - 2); + stride = mxnet::TShape(ishape.ndim() - 2, 1); } const int p_value = (param_.pool_type == pool_enum::kLpPooling && param_.p_value.has_value()) ? diff --git a/src/operator/nn/pooling.cc b/src/operator/nn/pooling.cc index 2d16604baa20..7c365f5081a1 100644 --- a/src/operator/nn/pooling.cc +++ b/src/operator/nn/pooling.cc @@ -114,11 +114,11 @@ static bool PoolingShape(const nnvm::NodeAttrs &attrs, << "Pooling: Input data should be 3D in (batch, channel, x)" << " Or 4D in (batch, channel, y, x) " << " Or 5D in (batch, channel, d, y, x)"; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; int layout = param.GetLayout(dshape.ndim()); if (param.global_pool) { mxnet::TShape oshape = dshape; - size_t c_index = 0; + int c_index = 0; switch (layout) { case mshadow::kNCW: case mshadow::kNCHW: @@ -133,7 +133,7 @@ static bool PoolingShape(const nnvm::NodeAttrs &attrs, default: LOG(FATAL) << "Unsupported tensor layout " << param.layout.value(); } - for (size_t i{1}; i < dshape.ndim(); i++) + for (int i = 1; i < dshape.ndim(); i++) if (i != c_index) oshape[i] = 1; out_shape->clear(); diff --git a/src/operator/nn/upsampling.cc b/src/operator/nn/upsampling.cc index d09017bf713e..ac638162dc6d 100644 --- a/src/operator/nn/upsampling.cc +++ b/src/operator/nn/upsampling.cc @@ -60,7 +60,7 @@ static bool UpSamplingShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_shape->size(), 2U) << "Input:[data, weight]"; CHECK_EQ(dshape.ndim(), 4U) << \ "UpSamplingBilinear: Input data should be 4D in (batch, channel, y, x)"; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; int kernel = 2 * param_.scale - param_.scale % 2; SHAPE_ASSIGN_CHECK(*in_shape, up_enum::kWeight, diff --git a/src/operator/numpy/np_broadcast_reduce_op.h b/src/operator/numpy/np_broadcast_reduce_op.h index bb2b7fca231c..e0379a040c3f 100644 --- a/src/operator/numpy/np_broadcast_reduce_op.h +++ b/src/operator/numpy/np_broadcast_reduce_op.h @@ -59,7 +59,7 @@ inline TShape NumpyReduceAxesShapeImpl(const TShape& ishape, CHECK(axes[0] == 0 || axes[0] == -1); } } - return TShape(0); + return TShape(0, -1); } // axis=None, do global reduction @@ -67,7 +67,7 @@ inline TShape NumpyReduceAxesShapeImpl(const TShape& ishape, if (keepdims) { return TShape(ishape.ndim(), 1); } else { - return TShape(0); + return TShape(0, -1); } } @@ -101,7 +101,7 @@ inline TShape NumpyReduceAxesShapeImpl(const TShape& ishape, if (keepdims) { oshape = TShape(ishape); } else { - oshape = TShape(ishape.ndim() - axes.ndim()); + oshape = TShape(ishape.ndim() - axes.ndim(), -1); } if (keepdims) { diff --git a/src/operator/operator_common.h b/src/operator/operator_common.h index a461d2bc4cef..c95f859a1b5b 100644 --- a/src/operator/operator_common.h +++ b/src/operator/operator_common.h @@ -103,19 +103,10 @@ struct InferStorageTypeError : public dmlc::Error { : dmlc::Error(msg_), msg(msg_), index(index) {} }; -/*! \brief check if shape is empty or contains unknown (0) dim. */ +/*! \brief check if shape is empty or contains unknown (0) dim. + * DEPRECATED. */ inline bool shape_is_none(const mxnet::TShape& x) { - return x.ndim() == 0 || x.Size() == 0; -} - -/*! brief check if shape is known using the NumPy compatible definition. - * zero-dim and zero-size tensors are valid. -1 means unknown.*/ -inline bool shape_is_known(const TShape& x) { - if (x.ndim() == -1) return false; - for (int i = 0; i < x.ndim(); ++i) { - if (x[i] == -1) return false; - } - return true; + return !mxnet::shape_is_known(x); } /*! \brief check if type is none (-1) */ @@ -130,7 +121,7 @@ inline bool storage_type_is_none(const int& x) { /*! \brief check if shape is scalar({1}). */ inline bool shape_is_scalar(const mxnet::TShape& x) { - return x.ndim() == 1 && x.Size() == 1; + return x.ndim() == 0; } /*! \brief get string representation of shape */ @@ -573,7 +564,7 @@ class OpSignature { } void AddSign(const mxnet::TShape &shape) { - for (size_t i = 0; i < shape.ndim(); i++) { + for (int i = 0; i < shape.ndim(); i++) { hash = hash * 2 + shape[i]; eles.push_back(shape[i]); } diff --git a/src/operator/operator_util.cc b/src/operator/operator_util.cc index b87428ca2b64..bc097a5b0c1c 100644 --- a/src/operator/operator_util.cc +++ b/src/operator/operator_util.cc @@ -774,7 +774,7 @@ class SimpleUnaryOpProp : public SimpleOpPropBase { using namespace mshadow; CHECK_EQ(in_shape->size(), 1) << "Input:[data]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; out_shape->clear(); if (source->unary_shape_ == nullptr) { out_shape->push_back(dshape); diff --git a/src/operator/quantization/dequantize-inl.h b/src/operator/quantization/dequantize-inl.h index dcda5a8b4bef..88199bc2591d 100644 --- a/src/operator/quantization/dequantize-inl.h +++ b/src/operator/quantization/dequantize-inl.h @@ -103,7 +103,7 @@ inline bool DequantizeShape(const nnvm::NodeAttrs& attrs, } SHAPE_ASSIGN_CHECK(*out_attrs, 0, in_attrs->at(0)); - return !shape_is_none(out_attrs->at(0)); + return shape_is_known(out_attrs->at(0)); } inline bool DequantizeType(const nnvm::NodeAttrs& attrs, diff --git a/src/operator/quantization/quantize-inl.h b/src/operator/quantization/quantize-inl.h index 1ad0016c52bc..2c267a76a571 100644 --- a/src/operator/quantization/quantize-inl.h +++ b/src/operator/quantization/quantize-inl.h @@ -126,7 +126,7 @@ inline bool QuantizeShape(const nnvm::NodeAttrs& attrs, SHAPE_ASSIGN_CHECK(*out_attrs, 0, in_attrs->at(0)); SHAPE_ASSIGN_CHECK(*out_attrs, 1, mxnet::TShape{1}); SHAPE_ASSIGN_CHECK(*out_attrs, 2, mxnet::TShape{1}); - return !shape_is_none(out_attrs->at(0)); + return shape_is_known(out_attrs->at(0)); } inline bool QuantizeType(const nnvm::NodeAttrs& attrs, diff --git a/src/operator/quantization/quantized_concat.cc b/src/operator/quantization/quantized_concat.cc index e32bb5a18e1a..f97807424701 100644 --- a/src/operator/quantization/quantized_concat.cc +++ b/src/operator/quantization/quantized_concat.cc @@ -55,7 +55,7 @@ static bool ConcatShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector* in_sha shape_assign(&dshape, tmp); } - if (dshape.ndim() == 0) return false; + if (dshape.ndim() == -1) return false; for (int i = 0; i < param_.num_args; ++i) { CHECK(shape_assign(&(*in_shape)[i], dshape)) diff --git a/src/operator/quantization/quantized_flatten-inl.h b/src/operator/quantization/quantized_flatten-inl.h index 99a262de19ca..de051b969659 100644 --- a/src/operator/quantization/quantized_flatten-inl.h +++ b/src/operator/quantization/quantized_flatten-inl.h @@ -86,10 +86,10 @@ inline bool QuantizedFlattenShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 3U); const mxnet::TShape &dshape = (*in_attrs)[0]; - if (shape_is_none(dshape)) return false; + if (!shape_is_known(dshape)) return false; - uint32_t target_dim = 1; - for (uint32_t i = 1; i < dshape.ndim(); ++i) { + dim_t target_dim = 1; + for (int i = 1; i < dshape.ndim(); ++i) { target_dim *= dshape[i]; } diff --git a/src/operator/quantization/quantized_fully_connected.cc b/src/operator/quantization/quantized_fully_connected.cc index 0a04e71b9093..cc4365f818d2 100644 --- a/src/operator/quantization/quantized_fully_connected.cc +++ b/src/operator/quantization/quantized_fully_connected.cc @@ -47,7 +47,7 @@ bool QuantizedFullyConnectedShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_shape->size(), num_inputs * 3); CHECK_EQ(out_shape->size(), 3U); - CHECK(!shape_is_none(in_shape->at(0))) + CHECK(shape_is_known(in_shape->at(0))) << "QuantizedFullyConnectedOp input data shape must be given"; const mxnet::TShape& dshape = in_shape->at(0); index_t num_input; diff --git a/src/operator/quantization/quantized_pooling.cc b/src/operator/quantization/quantized_pooling.cc index af604080a756..1839e2a29d77 100644 --- a/src/operator/quantization/quantized_pooling.cc +++ b/src/operator/quantization/quantized_pooling.cc @@ -35,7 +35,7 @@ bool QuantizedPoolingShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector *out_shape) { const PoolingParam& param = nnvm::get(attrs.parsed); CHECK_EQ(in_shape->size(), 3U); - if (shape_is_none(in_shape->at(0))) return false; + if (!shape_is_known(in_shape->at(0))) return false; const mxnet::TShape &dshape = (*in_shape)[0]; CHECK_EQ(dshape.ndim(), 4U) << "quantized_pooling: Input data should be 4D in " @@ -45,7 +45,7 @@ bool QuantizedPoolingShape(const nnvm::NodeAttrs& attrs, << "QuantizedPoolingOp only supports NCHW layout for now, saw " << layout; // NCHW layout const int N = 0, H = 2, W = 3, C = 1; - mxnet::TShape oshape(4); + mxnet::TShape oshape(4, -1); CHECK_EQ(param.kernel.ndim(), 2) << "QuantizedPoolingOp only supports 2D pooling for now"; CHECK(param.kernel[0] <= dshape[H] + 2 * param.pad[0]) << "kernel size (" << param.kernel[0] diff --git a/src/operator/random/multisample_op.h b/src/operator/random/multisample_op.h index e9f266932e13..7d5e256297ad 100644 --- a/src/operator/random/multisample_op.h +++ b/src/operator/random/multisample_op.h @@ -66,7 +66,7 @@ inline bool MultiSampleOpShape(const nnvm::NodeAttrs& attrs, // Get shape to be sampled for each parameter set. const MultiSampleParam& param = nnvm::get(attrs.parsed); mxnet::TShape sshape = param.shape; - for (size_t i = 0; i < sshape.ndim(); ++i) { + for (int i = 0; i < sshape.ndim(); ++i) { CHECK_GT(sshape[i], 0) << "shape parameter must be non-zero within each dimension"; } // Examine output shape whether it is already defined. diff --git a/src/operator/random/sample_multinomial_op.h b/src/operator/random/sample_multinomial_op.h index e76cd646b850..b38aefbc1634 100644 --- a/src/operator/random/sample_multinomial_op.h +++ b/src/operator/random/sample_multinomial_op.h @@ -41,7 +41,7 @@ struct SampleMultinomialParam : public dmlc::Parameter { int dtype; DMLC_DECLARE_PARAMETER(SampleMultinomialParam) { DMLC_DECLARE_FIELD(shape) - .set_default(mxnet::TShape()) + .set_default(mxnet::TShape(0, 1)) .describe("Shape to be sampled from each random distribution."); DMLC_DECLARE_FIELD(get_prob) .set_default(false) @@ -68,7 +68,7 @@ inline bool SampleMultinomialOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), param.get_prob ? 2U : 1U); const mxnet::TShape& ishape = (*in_attrs)[0]; - if (!ishape.ndim()) return false; + if (!shape_is_known(ishape)) return false; MSHADOW_TYPE_SWITCH(param.dtype, DType, { CHECK_LE(ishape[ishape.ndim() - 1], mxnet::common::MaxIntegerValue()) @@ -76,26 +76,26 @@ inline bool SampleMultinomialOpShape(const nnvm::NodeAttrs& attrs, }); if (ishape.ndim() == 1) { - if (param.shape.ndim()) { + if (param.shape.ndim() > 0) { SHAPE_ASSIGN_CHECK(*out_attrs, 0, param.shape); if (param.get_prob) SHAPE_ASSIGN_CHECK(*out_attrs, 1, param.shape); } else { - SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape(1)); - if (param.get_prob) SHAPE_ASSIGN_CHECK(*out_attrs, 1, mxnet::TShape(1)); + SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape(1, 1)); + if (param.get_prob) SHAPE_ASSIGN_CHECK(*out_attrs, 1, mxnet::TShape(1, 1)); } return true; } - mxnet::TShape oshape(ishape.ndim() - 1 + param.shape.ndim()); - for (size_t i = 0; i < ishape.ndim() - 1; ++i) { + mxnet::TShape oshape(ishape.ndim() - 1 + param.shape.ndim(), -1); + for (int i = 0; i < ishape.ndim() - 1; ++i) { oshape[i] = ishape[i]; } - for (size_t i = 0; i < param.shape.ndim(); ++i) { + for (int i = 0; i < param.shape.ndim(); ++i) { oshape[i + ishape.ndim() - 1] = param.shape[i]; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); if (param.get_prob) SHAPE_ASSIGN_CHECK(*out_attrs, 1, oshape); - return true; + return shape_is_known(out_attrs->at(0)) && shape_is_known(out_attrs->at(1)); } diff --git a/src/operator/random/unique_sample_op.h b/src/operator/random/unique_sample_op.h index 87998c8f46b1..c97d4fdf7ced 100644 --- a/src/operator/random/unique_sample_op.h +++ b/src/operator/random/unique_sample_op.h @@ -60,7 +60,7 @@ inline bool SampleUniqueShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 0U); CHECK_EQ(out_attrs->size(), 2U); // output shape is known - if ((*out_attrs)[0].ndim() == 2 && param.shape.ndim() == 0) { + if ((*out_attrs)[0].ndim() == 2 && param.shape.ndim() == -1) { SHAPE_ASSIGN_CHECK(*out_attrs, 1, mshadow::Shape1((*out_attrs)[0][0])); return true; } diff --git a/src/operator/regression_output-inl.h b/src/operator/regression_output-inl.h index 8b63a8a2cff6..d8f102de1675 100644 --- a/src/operator/regression_output-inl.h +++ b/src/operator/regression_output-inl.h @@ -57,7 +57,7 @@ inline bool RegressionOpShape(const nnvm::NodeAttrs& attrs, using namespace mshadow; CHECK_EQ(in_attrs->size(), 2U) << "Input:[data, label]"; const mxnet::TShape &dshape = in_attrs->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; auto &lshape = (*in_attrs)[1]; if (lshape.ndim() == 0) { // special treatment for 1D output, to allow 1D label by default. diff --git a/src/operator/rnn-inl.h b/src/operator/rnn-inl.h index 71ad331786ae..9e612d06fe0d 100644 --- a/src/operator/rnn-inl.h +++ b/src/operator/rnn-inl.h @@ -676,7 +676,7 @@ class RNNProp : public OperatorProperty { CHECK_EQ(in_shape->size(), 3U) << "Input:[data, parameters, state]"; } const mxnet::TShape &dshape = (*in_shape)[rnn_enum::kData]; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; CHECK_EQ(dshape.ndim(), 3U) \ << "Input data should be rank-3 tensor of dim [sequence length, batch size, input size]"; // data: [sequence len, batch, input dimension] diff --git a/src/operator/sequence_last-inl.h b/src/operator/sequence_last-inl.h index b4db80bdd721..4c42934f1618 100644 --- a/src/operator/sequence_last-inl.h +++ b/src/operator/sequence_last-inl.h @@ -263,7 +263,7 @@ class SequenceLastProp : public OperatorProperty { SHAPE_ASSIGN_CHECK(*in_shape, seq_last::kSequenceLength, Shape1(sbatch)); // calculate output size - mxnet::TShape shape_o(dshape.ndim() - 1); + mxnet::TShape shape_o(dshape.ndim() - 1, -1); shape_o[0] = sbatch; for (index_t i = 1; i < shape_o.ndim(); ++i) shape_o[i] = dshape[i + 1]; diff --git a/src/operator/slice_channel-inl.h b/src/operator/slice_channel-inl.h index 6125782d525b..a51b17cd324e 100644 --- a/src/operator/slice_channel-inl.h +++ b/src/operator/slice_channel-inl.h @@ -195,9 +195,9 @@ class SliceChannelProp : public OperatorProperty { CHECK_EQ(in_shape->size(), 1U); mxnet::TShape dshape = in_shape->at(slice_enum::kData); mxnet::TShape ishape = in_shape->at(slice_enum::kData); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; if (param_.axis >= 0) { - CHECK_LT(static_cast(param_.axis), dshape.ndim()); + CHECK_LT(param_.axis, dshape.ndim()); } else { CHECK_LT(param_.axis + dshape.ndim(), dshape.ndim()); } diff --git a/src/operator/softmax_output-inl.h b/src/operator/softmax_output-inl.h index 5dca8bac14a3..f81a232d629a 100644 --- a/src/operator/softmax_output-inl.h +++ b/src/operator/softmax_output-inl.h @@ -337,19 +337,19 @@ class SoftmaxOutputProp : public OperatorProperty { using namespace mshadow; CHECK_EQ(in_shape->size(), 2U) << "Input:[data, label]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; // label.shape == data.shape: use probability as label if (dshape != (*in_shape)[softmaxout_enum::kLabel]) { if (param_.multi_output) { mxnet::TShape lshape1 = Shape2(dshape[0], dshape.Size()/dshape[0]/dshape[1]); - mxnet::TShape lshape2(dshape.ndim() - 1); + mxnet::TShape lshape2(dshape.ndim() - 1, -1); lshape2[0] = dshape[0]; - for (index_t i = 2; i < dshape.ndim(); ++i) + for (int i = 2; i < dshape.ndim(); ++i) lshape2[i-1] = dshape[i]; mxnet::TShape lshape3 = dshape; lshape3[1] = 1; - if (in_shape->at(softmaxout_enum::kLabel).ndim() == 0) { + if (in_shape->at(softmaxout_enum::kLabel).ndim() == -1) { in_shape->at(softmaxout_enum::kLabel) = lshape1; } else if (in_shape->at(softmaxout_enum::kLabel) == lshape1) { } else if (in_shape->at(softmaxout_enum::kLabel) == lshape2) { @@ -361,8 +361,8 @@ class SoftmaxOutputProp : public OperatorProperty { throw InferShapeError(os.str(), softmaxout_enum::kLabel); } } else { - mxnet::TShape label_shape(dshape.ndim() - 1); - for (index_t i = 0; i + 1 < dshape.ndim(); ++i) + mxnet::TShape label_shape(dshape.ndim() - 1, -1); + for (int i = 0; i + 1 < dshape.ndim(); ++i) label_shape[i] = dshape[i]; SHAPE_ASSIGN_CHECK(*in_shape, softmaxout_enum::kLabel, label_shape); } diff --git a/src/operator/softmax_output.cc b/src/operator/softmax_output.cc index b17ef3527297..262242f98004 100644 --- a/src/operator/softmax_output.cc +++ b/src/operator/softmax_output.cc @@ -85,19 +85,19 @@ static bool SoftmaxOutputShape(const nnvm::NodeAttrs& attrs, const SoftmaxOutputParam& param = nnvm::get(attrs.parsed); CHECK_EQ(in_shape->size(), 2U) << "Input:[data, label]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; // label.shape == data.shape: use probability as label if (dshape != (*in_shape)[softmaxout_enum::kLabel]) { if (param.multi_output) { mxnet::TShape lshape1 = Shape2(dshape[0], dshape.Size()/dshape[0]/dshape[1]); - mxnet::TShape lshape2(dshape.ndim() - 1); + mxnet::TShape lshape2(dshape.ndim() - 1, -1); lshape2[0] = dshape[0]; - for (index_t i = 2; i < dshape.ndim(); ++i) + for (int i = 2; i < dshape.ndim(); ++i) lshape2[i-1] = dshape[i]; mxnet::TShape lshape3 = dshape; lshape3[1] = 1; - if (in_shape->at(softmaxout_enum::kLabel).ndim() == 0) { + if (in_shape->at(softmaxout_enum::kLabel).ndim() == -1) { in_shape->at(softmaxout_enum::kLabel) = lshape1; } else if (in_shape->at(softmaxout_enum::kLabel) == lshape1) { } else if (in_shape->at(softmaxout_enum::kLabel) == lshape2) { @@ -109,8 +109,8 @@ static bool SoftmaxOutputShape(const nnvm::NodeAttrs& attrs, throw InferShapeError(os.str(), softmaxout_enum::kLabel); } } else { - mxnet::TShape label_shape(dshape.ndim() - 1); - for (index_t i = 0; i + 1 < dshape.ndim(); ++i) + mxnet::TShape label_shape(dshape.ndim() - 1, -1); + for (int i = 0; i + 1 < dshape.ndim(); ++i) label_shape[i] = dshape[i]; SHAPE_ASSIGN_CHECK(*in_shape, softmaxout_enum::kLabel, label_shape); } diff --git a/src/operator/spatial_transformer-inl.h b/src/operator/spatial_transformer-inl.h index 9e5dee842d0d..660d57d55bab 100644 --- a/src/operator/spatial_transformer-inl.h +++ b/src/operator/spatial_transformer-inl.h @@ -190,10 +190,10 @@ class SpatialTransformerProp : public OperatorProperty { CHECK_EQ(param_.sampler_type, st::kBilinear) << "only supports bilinear sampling currently"; const mxnet::TShape &dshape = (*in_shape)[st::kData]; const mxnet::TShape &lshape = (*in_shape)[st::kLoc]; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; CHECK_EQ(dshape.ndim(), 4U) \ << "input data should be 4D in batch-num_filter-y-x"; - if (lshape.ndim() == 0) return false; + if (!shape_is_known(lshape)) return false; CHECK_EQ(lshape.ndim(), 2U) \ << "locolisation paramter should be 4D in batch-num_hidden"; if (param_.transform_type == st::kAffine) { diff --git a/src/operator/subgraph_op_common.cc b/src/operator/subgraph_op_common.cc index 8934438d428a..e53d911614a0 100644 --- a/src/operator/subgraph_op_common.cc +++ b/src/operator/subgraph_op_common.cc @@ -178,7 +178,7 @@ bool as_bool_scalar(const NDArray &a) { } bool is_shape_udf(const mxnet::TShape &x) { - return x.ndim() == 0 || x.Size() == 0; + return !shape_is_known(x); } bool is_stype_udf(const int &x) { @@ -225,7 +225,7 @@ void LoopState::Forward(int iter_no, if (!out_bufs[i].IsSame(coutputs[i])) { // The line below checks whether dynamic shape exists. // If so, re-initialize the shape. - if (coutputs[i].shape().ndim() == 0) { + if (!shape_is_known(coutputs[i].shape())) { const_cast(coutputs[i]).Init(out_bufs[i].shape()); } CopyFromTo(out_bufs[i], coutputs[i]); diff --git a/src/operator/subgraph_op_common.h b/src/operator/subgraph_op_common.h index 91adf576dc07..19528349c0c7 100644 --- a/src/operator/subgraph_op_common.h +++ b/src/operator/subgraph_op_common.h @@ -67,7 +67,7 @@ bool is_type_udf(const int &x); template void extract_by_loc(const std::vector &array, - const nnvm::Tuple input_locs, + const mxnet::Tuple input_locs, std::vector *out) { out->clear(); out->reserve(input_locs.ndim()); @@ -94,11 +94,11 @@ bool fill_value(T *x, T *y, bool x_empty, bool y_empty) { } template -bool sync_in_in(const nnvm::Tuple &input_locs, - std::vector *in, - std::vector *subg_in, - std::function is_empty) { - for (size_t i = 0; i < input_locs.ndim(); ++i) { +bool sync_in_in(const mxnet::Tuple &input_locs, + std::vector *in, + std::vector *subg_in, + std::function is_empty) { + for (int i = 0; i < input_locs.ndim(); ++i) { T &x = in->at(input_locs[i]); T &y = subg_in->at(i); fill_value(&x, &y, is_empty(x), is_empty(y)); diff --git a/src/operator/svm_output-inl.h b/src/operator/svm_output-inl.h index 1609764f0ebe..3d651c13d8ba 100644 --- a/src/operator/svm_output-inl.h +++ b/src/operator/svm_output-inl.h @@ -143,9 +143,9 @@ class SVMOutputProp : public OperatorProperty { using namespace mshadow; CHECK_EQ(in_shape->size(), 2U) << "Input:[data, label]"; const mxnet::TShape &dshape = in_shape->at(0); - if (dshape.ndim() == 0) return false; - mxnet::TShape label_shape(dshape.ndim() - 1); - for (index_t i = 0; i + 1 < dshape.ndim(); ++i) + if (!shape_is_known(dshape)) return false; + mxnet::TShape label_shape(dshape.ndim() - 1, -1); + for (int i = 0; i + 1 < dshape.ndim(); ++i) label_shape[i] = dshape[i]; SHAPE_ASSIGN_CHECK(*in_shape, svm_enum::kLabel, label_shape); out_shape->clear(); diff --git a/src/operator/swapaxis-inl.h b/src/operator/swapaxis-inl.h index ce835084ab32..41cb940d957a 100644 --- a/src/operator/swapaxis-inl.h +++ b/src/operator/swapaxis-inl.h @@ -72,8 +72,8 @@ class SwapAxisOp : public Operator { uint32_t dim1, uint32_t dim2) { using namespace mshadow; using namespace mshadow::expr; - index_t ndim_in = shape.ndim(); - index_t si; + int ndim_in = shape.ndim(); + int si; if (dim1 > dim2) { std::swap(dim1, dim2); diff --git a/src/operator/tensor/broadcast_reduce_op.h b/src/operator/tensor/broadcast_reduce_op.h index b13906af6624..fb55fcd4d6a2 100644 --- a/src/operator/tensor/broadcast_reduce_op.h +++ b/src/operator/tensor/broadcast_reduce_op.h @@ -129,9 +129,9 @@ struct BroadcastAxesParam : public dmlc::Parameter { mxnet::TShape axis; mxnet::TShape size; DMLC_DECLARE_PARAMETER(BroadcastAxesParam) { - DMLC_DECLARE_FIELD(axis).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(axis).set_default(mxnet::TShape(0)) .describe("The axes to perform the broadcasting."); - DMLC_DECLARE_FIELD(size).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(size).set_default(mxnet::TShape(0)) .describe("Target sizes of the broadcasting axes."); } }; @@ -139,7 +139,7 @@ struct BroadcastAxesParam : public dmlc::Parameter { struct BroadcastToParam : public dmlc::Parameter { mxnet::TShape shape; DMLC_DECLARE_PARAMETER(BroadcastToParam) { - DMLC_DECLARE_FIELD(shape).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(shape).set_default(mxnet::TShape(0)) .describe("The shape of the desired array." " We can set the dim to zero if it's same as the original." " E.g `A = broadcast_to(B, shape=(10, 0, 0))` " @@ -165,7 +165,7 @@ inline int CheckAxis(int axis, int ndim) { } inline mxnet::TShape AxisShapeCompact(mxnet::TShape shape, int *axis, bool allow_2d) { - int ndim = static_cast(shape.ndim()); + int ndim = shape.ndim(); index_t leading = 1, trailing = 1, M = shape[*axis]; for (int i = 0; i < *axis; ++i) leading *= shape[i]; for (int i = *axis + 1; i < ndim; ++i) trailing *= shape[i]; @@ -186,7 +186,7 @@ inline mxnet::TShape ReduceAxisShapeImpl(const mxnet::TShape& ishape, bool keepdims) { if (!axis || ishape.ndim() == 1) { if (keepdims) { - return mxnet::TShape(ishape.ndim()); + return mxnet::TShape(ishape.ndim(), 1); } return mshadow::Shape1(1); } @@ -198,7 +198,7 @@ inline mxnet::TShape ReduceAxisShapeImpl(const mxnet::TShape& ishape, return oshape; } - mxnet::TShape oshape(ishape.ndim() - 1); + mxnet::TShape oshape(ishape.ndim() - 1, 1); for (int i = 0; i < new_axis; ++i) oshape[i] = ishape[i]; for (int i = new_axis+1; i < static_cast(ishape.ndim()); ++i) { oshape[i-1] = ishape[i]; @@ -212,7 +212,7 @@ inline bool ReduceAxisShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); mxnet::TShape& ishape = (*in_attrs)[0]; - if (ishape.ndim() == 0) return false; + if (!shape_is_known(ishape)) return false; const ReduceAxisParam& param = nnvm::get(attrs.parsed); SHAPE_ASSIGN_CHECK(*out_attrs, 0, @@ -223,12 +223,12 @@ inline bool ReduceAxisShape(const nnvm::NodeAttrs& attrs, inline mxnet::TShape ReduceAxesShapeImpl(const mxnet::TShape& ishape, const dmlc::optional& axis, bool keepdims, bool exclude) { - // if axis doesn't have value, treat it same mxnet::TShape(). + // if axis doesn't have value, treat it same mxnet::TShape(0). if (!axis.has_value() || axis.value().ndim() == 0) { if (keepdims) { - return mxnet::TShape(ishape.ndim()); + return mxnet::TShape(ishape.ndim(), 1); } else { - return mxnet::TShape(1); + return mxnet::TShape(1, 1); } } // axis has value @@ -256,9 +256,9 @@ inline mxnet::TShape ReduceAxesShapeImpl(const mxnet::TShape& ishape, if (keepdims) { oshape = mxnet::TShape(ishape); } else if (exclude) { - oshape = mxnet::TShape(axes.ndim()); + oshape = mxnet::TShape(axes.ndim(), 1); } else { - oshape = mxnet::TShape(std::max(1, ishape.ndim() - axes.ndim())); + oshape = mxnet::TShape(std::max(1, ishape.ndim() - axes.ndim()), 1); } if (keepdims && exclude) { @@ -294,7 +294,7 @@ inline bool ReduceAxesShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector *out_attrs) { CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); - if ((*in_attrs)[0].ndim() == 0) return false; + if (!shape_is_known((*in_attrs)[0])) return false; const ReduceAxesParam& param = nnvm::get(attrs.parsed); SHAPE_ASSIGN_CHECK(*out_attrs, 0, ReduceAxesShapeImpl((*in_attrs)[0], param.axis, @@ -307,7 +307,7 @@ inline bool NormShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector *out_attrs) { CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); - if ((*in_attrs)[0].ndim() == 0) return false; + if (!shape_is_known((*in_attrs)[0])) return false; const NormParam& param = nnvm::get(attrs.parsed); SHAPE_ASSIGN_CHECK(*out_attrs, 0, ReduceAxesShapeImpl((*in_attrs)[0], param.axis, @@ -320,12 +320,12 @@ inline bool BroadcastAxesShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector *out_attrs) { CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); - if ((*in_attrs)[0].ndim() == 0) return false; + if (!shape_is_known((*in_attrs)[0])) return false; const BroadcastAxesParam& param = nnvm::get(attrs.parsed); CHECK_EQ(param.axis.ndim() , param.size.ndim()); mxnet::TShape &ishape = (*in_attrs)[0]; mxnet::TShape oshape = ishape; - for (index_t i = 0; i < param.axis.ndim(); ++i) { + for (int i = 0; i < param.axis.ndim(); ++i) { CHECK_EQ(oshape[param.axis[i]], 1U) << "Broadcasting axis must have size 1"; oshape[param.axis[i]] = param.size[i]; } @@ -339,12 +339,12 @@ inline bool BroadcastToShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); mxnet::TShape& ishape = (*in_attrs)[0]; - if (ishape.ndim() == 0) return false; + if (!shape_is_known(ishape)) return false; const BroadcastToParam& param = nnvm::get(attrs.parsed); CHECK_EQ(ishape.ndim(), param.shape.ndim()) << "Operand of shape " << ishape << " cannot be broadcasted to " << param.shape; mxnet::TShape oshape = param.shape; - for (index_t i = 0; i < ishape.ndim(); ++i) { + for (int i = 0; i < ishape.ndim(); ++i) { if (oshape[i] != 0) { CHECK(ishape[i] == oshape[i] || ishape[i] == 1) << "Array cannot be broadcasted from " << ishape << " to " << param.shape; @@ -364,7 +364,7 @@ inline bool BroadcastLikeShape(const nnvm::NodeAttrs& attrs, mxnet::TShape& lhs_shape = (*in_attrs)[0]; mxnet::TShape& rhs_shape = (*in_attrs)[1]; - if ((lhs_shape.ndim() == 0) || (lhs_shape.ndim() == 0)) { + if (!shape_is_known(lhs_shape) || !shape_is_known(lhs_shape)) { return false; } @@ -377,7 +377,7 @@ inline bool BroadcastLikeShape(const nnvm::NodeAttrs& attrs, << "Operand of shape " << lhs_shape << " cannot be broadcasted to " << rhs_shape; oshape = mxnet::TShape(rhs_shape); - for (index_t i = 0; i < lhs_shape.ndim(); ++i) { + for (int i = 0; i < lhs_shape.ndim(); ++i) { if (rhs_shape[i] != 0) { CHECK(lhs_shape[i] == rhs_shape[i] || lhs_shape[i] == 1) << "Array cannot be broadcasted from " << lhs_shape << " to " << rhs_shape; @@ -396,7 +396,7 @@ inline bool BroadcastLikeShape(const nnvm::NodeAttrs& attrs, << "Empty axes tuple is not allowed"; oshape = mxnet::TShape(lhs_shape); - for (index_t i = 0; i < lhs_axes.ndim(); ++i) { + for (int i = 0; i < lhs_axes.ndim(); ++i) { auto copyfrom = lhs_axes[i]; if (copyfrom < 0) { copyfrom = lhs_shape.ndim() + copyfrom; @@ -423,9 +423,9 @@ inline bool BroadcastLikeShape(const nnvm::NodeAttrs& attrs, inline void BroadcastReduceShapeCompact(const mxnet::TShape& big, const mxnet::TShape& small, mxnet::TShape *new_big, mxnet::TShape *new_small) { - index_t idim = std::max(big.ndim(), MXNET_SPECIAL_MAX_NDIM); - *new_big = mxnet::TShape(idim); - *new_small = mxnet::TShape(idim); + const int idim = std::max(big.ndim(), MXNET_SPECIAL_MAX_NDIM); + *new_big = mxnet::TShape(idim, 1); + *new_small = mxnet::TShape(idim, 1); index_t j = 0; if (small.Size() == 1) { (*new_big)[j++] = big.Size(); @@ -451,12 +451,10 @@ inline void BroadcastReduceShapeCompact(const mxnet::TShape& big, const mxnet::T ++j; } } - if (j <= 2) { - new_small->assign(&(*new_small)[0], &(*new_small)[2]); - new_big->assign(&(*new_big)[0], &(*new_big)[2]); - } else if (j <= MXNET_SPECIAL_MAX_NDIM) { - new_small->assign(&(*new_small)[0], &(*new_small)[MXNET_SPECIAL_MAX_NDIM]); - new_big->assign(&(*new_big)[0], &(*new_big)[MXNET_SPECIAL_MAX_NDIM]); + if (j <= MXNET_SPECIAL_MAX_NDIM) { + const int ndim = (j <= 2? 2 : MXNET_SPECIAL_MAX_NDIM); + new_small->assign(new_small->begin(), new_small->begin() + ndim); + new_big->assign(new_big->begin(), new_big->begin() + ndim); } else { LOG(FATAL) << "Too many reduction axes from " << big << " to " << small; } diff --git a/src/operator/tensor/diag_op-inl.h b/src/operator/tensor/diag_op-inl.h index 1e3c1c9701d4..b90b09a36bd3 100644 --- a/src/operator/tensor/diag_op-inl.h +++ b/src/operator/tensor/diag_op-inl.h @@ -91,12 +91,12 @@ inline mxnet::TShape DiagShapeImpl(const mxnet::TShape& ishape, const int k, std::swap(x1, x2); } - int32_t n_dim = static_cast(ishape.ndim()) - 1; - mxnet::TShape oshape(n_dim); + int32_t n_dim = ishape.ndim() - 1; + mxnet::TShape oshape(n_dim, -1); // remove axis1 and axis2 and append the new axis to the end uint32_t idx = 0; - for (int32_t i = 0; i <= n_dim; ++i) { + for (int i = 0; i <= n_dim; ++i) { if (i != x1 && i != x2) { oshape[idx++] = ishape[i]; } @@ -114,7 +114,7 @@ inline bool DiagOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); const mxnet::TShape& ishape = (*in_attrs)[0]; - if (ishape.ndim() == 0) { + if (!shape_is_known(ishape)) { return false; } @@ -129,7 +129,7 @@ inline bool DiagOpShape(const nnvm::NodeAttrs& attrs, } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return out_attrs->at(0).ndim() != 0U; + return shape_is_known(out_attrs->at(0)); } inline bool DiagOpType(const nnvm::NodeAttrs& attrs, diff --git a/src/operator/tensor/dot-inl.h b/src/operator/tensor/dot-inl.h index 163b4426cb2b..f81eb9c04f3a 100644 --- a/src/operator/tensor/dot-inl.h +++ b/src/operator/tensor/dot-inl.h @@ -1217,20 +1217,20 @@ inline bool DotShape(const nnvm::NodeAttrs& attrs, if (Ta) { L[0] = mshadow::Shape1(lshape[0]); L[1] = lshape.ndim() > 1 ? - mxnet::TShape(&lshape[1], &lshape[lshape.ndim()]) : mxnet::TShape(1); + mxnet::TShape(&lshape[1], lshape.end()) : mxnet::TShape(1, 1); } else { L[0] = lshape.ndim() > 1 ? - mxnet::TShape(&lshape[0], &lshape[lshape.ndim()-1]) : mxnet::TShape(1); + mxnet::TShape(&lshape[0], &lshape[lshape.ndim()-1]) : mxnet::TShape(1, 1); L[1] = mshadow::Shape1(lshape[lshape.ndim()-1]); } if (Tb) { R[0] = rshape.ndim() > 1 ? - mxnet::TShape(&rshape[0], &rshape[rshape.ndim()-1]) : mxnet::TShape(1); + mxnet::TShape(&rshape[0], &rshape[rshape.ndim()-1]) : mxnet::TShape(1, 1); R[1] = mshadow::Shape1(rshape[rshape.ndim()-1]); } else { R[0] = mshadow::Shape1(rshape[0]); R[1] = rshape.ndim() > 1 ? - mxnet::TShape(&rshape[1], &rshape[rshape.ndim()]) : mxnet::TShape(1); + mxnet::TShape(&rshape[1], rshape.end()) : mxnet::TShape(1, 1); } if (L[!Ta].Size() != 0 && R[Tb].Size() != 0) { @@ -1238,8 +1238,8 @@ inline bool DotShape(const nnvm::NodeAttrs& attrs, << "dot shape error: " << lshape << " X " << rshape; } std::vector buf; - if (lshape.ndim() > 1) buf.insert(buf.end(), &L[Ta][0], &L[Ta][L[Ta].ndim()]); - if (rshape.ndim() > 1) buf.insert(buf.end(), &R[!Tb][0], &R[!Tb][R[!Tb].ndim()]); + if (lshape.ndim() > 1) buf.insert(buf.end(), &L[Ta][0], L[Ta].end()); + if (rshape.ndim() > 1) buf.insert(buf.end(), &R[!Tb][0], R[!Tb].end()); mxnet::TShape oshape(buf.begin(), buf.end()); SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); } diff --git a/src/operator/tensor/elemwise_binary_broadcast_op.h b/src/operator/tensor/elemwise_binary_broadcast_op.h index 1d2b7c9c1163..dfb3231a75a9 100644 --- a/src/operator/tensor/elemwise_binary_broadcast_op.h +++ b/src/operator/tensor/elemwise_binary_broadcast_op.h @@ -48,21 +48,23 @@ inline bool BinaryBroadcastShape(const nnvm::NodeAttrs& attrs, mxnet::TShape& rhs = (*in_attrs)[1]; // avoid pre-mature shape inference. - if (lhs.ndim() == 0 || rhs.ndim() == 0) return false; + if (lhs.ndim() == -1 || rhs.ndim() == -1) return false; if (lhs == rhs) { SHAPE_ASSIGN_CHECK(*out_attrs, 0, lhs); - return true; + return shape_is_known(lhs); } - mxnet::TShape out(std::max(lhs.ndim(), rhs.ndim())); - index_t bl = out.ndim() - lhs.ndim(); - index_t br = out.ndim() - rhs.ndim(); - for (index_t i = 0; i < out.ndim(); ++i) { - index_t l = 1, r = 1; + mxnet::TShape out(std::max(lhs.ndim(), rhs.ndim()), -1); + const int bl = out.ndim() - lhs.ndim(); + const int br = out.ndim() - rhs.ndim(); + for (int i = 0; i < out.ndim(); ++i) { + int l = 1, r = 1; if (i >= bl) l = lhs[i-bl]; if (i >= br) r = rhs[i-br]; if (l != r) { if (l == 0 || r == 0) { + // TODO(junwu): here is not compatible with NumPy. + // For example, (2, 3) cannot broadcast to (2, 0, 3). out[i] = 0; } else { CHECK(l == 1 || r == 1) @@ -74,7 +76,7 @@ inline bool BinaryBroadcastShape(const nnvm::NodeAttrs& attrs, } } SHAPE_ASSIGN_CHECK(*out_attrs, 0, out); - return true; + return shape_is_known(lhs) && shape_is_known(rhs) && shape_is_known(out); } inline bool BinaryBroadcastMulStorageType(const nnvm::NodeAttrs& attrs, @@ -146,15 +148,15 @@ inline int BinaryBroadcastShapeCompact(const mxnet::TShape& lshape, const mxnet: const mxnet::TShape& oshape, mxnet::TShape *new_lshape, mxnet::TShape *new_rshape, mxnet::TShape *new_oshape) { if (lshape == rshape) return 0; - index_t odim = std::max(oshape.ndim(), broadcast::MAX_DIM); - *new_lshape = mxnet::TShape(odim); - *new_rshape = mxnet::TShape(odim); - *new_oshape = mxnet::TShape(odim); - index_t bl = oshape.ndim() - lshape.ndim(); - index_t br = oshape.ndim() - rshape.ndim(); - index_t j = 0, lprod = 1, rprod = 1, oprod = 1; - for (index_t i = 0; i < oshape.ndim(); ++i) { - index_t l = 1, r = 1, o = oshape[i]; + const int odim = std::max(oshape.ndim(), broadcast::MAX_DIM); + *new_lshape = mxnet::TShape(odim, 1); + *new_rshape = mxnet::TShape(odim, 1); + *new_oshape = mxnet::TShape(odim, 1); + int bl = oshape.ndim() - lshape.ndim(); + int br = oshape.ndim() - rshape.ndim(); + int j = 0, lprod = 1, rprod = 1, oprod = 1; + for (int i = 0; i < oshape.ndim(); ++i) { + int l = 1, r = 1, o = oshape[i]; if (i >= bl) l = lshape[i-bl]; if (i >= br) r = rshape[i-br]; if ((lprod != rprod || l != r) && @@ -176,9 +178,9 @@ inline int BinaryBroadcastShapeCompact(const mxnet::TShape& lshape, const mxnet: } if (j <= broadcast::MAX_DIM) { BROADCAST_NDIM_SWITCH(j, NDim, { - new_lshape->assign(&(*new_lshape)[0], &(*new_lshape)[NDim]); - new_rshape->assign(&(*new_rshape)[0], &(*new_rshape)[NDim]); - new_oshape->assign(&(*new_oshape)[0], &(*new_oshape)[NDim]); + new_lshape->assign(new_lshape->begin(), new_lshape->begin() + NDim); + new_rshape->assign(new_rshape->begin(), new_rshape->begin() + NDim); + new_oshape->assign(new_oshape->begin(), new_oshape->begin() + NDim); }); } else { LOG(FATAL) << "Too many broadcast dimensions with operands " << lshape << " " << rshape; diff --git a/src/operator/tensor/elemwise_unary_op_basic.cc b/src/operator/tensor/elemwise_unary_op_basic.cc index 19a9ac8359eb..5114a5d0dbe3 100644 --- a/src/operator/tensor/elemwise_unary_op_basic.cc +++ b/src/operator/tensor/elemwise_unary_op_basic.cc @@ -413,9 +413,9 @@ bool ReshapeLikeShapeCompute(const nnvm::NodeAttrs &attrs, GetReshapeLikeParams(param, lshape, rshape, &lhs_begin, &lhs_end, &rhs_begin, &rhs_end); - int lhsrank = static_cast(lshape.ndim()); + int lhsrank = lshape.ndim(); int orank = lhsrank + (rhs_end - rhs_begin) - (lhs_end - lhs_begin); - mxnet::TShape oshape(orank); + mxnet::TShape oshape(orank, -1); for (int i = 0; i < lhs_begin; ++i) oshape[i] = lshape[i]; @@ -436,7 +436,7 @@ bool ReshapeLikeShapeCompute(const nnvm::NodeAttrs &attrs, << "shape " << oshape << " because they have different " << "size."; SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return true; + return shape_is_known(oshape); } DMLC_REGISTER_PARAMETER(ReshapeLikeParam); @@ -537,7 +537,7 @@ Example:: mxnet::ShapeVector *out_attrs) { CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); - mxnet::TShape target_shape(1); + mxnet::TShape target_shape(1, -1); target_shape[0] = in_attrs->at(0).ndim(); SHAPE_ASSIGN_CHECK(*out_attrs, 0, target_shape); return !shape_is_none(out_attrs->at(0)); @@ -589,7 +589,7 @@ Example:: mxnet::ShapeVector *out_attrs) { CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); - SHAPE_ASSIGN_CHECK(*out_attrs, 0, 1U); + SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape(1, 1)); return !shape_is_none(out_attrs->at(0)); }) .set_attr("FInferType", diff --git a/src/operator/tensor/histogram-inl.h b/src/operator/tensor/histogram-inl.h index 51d0bdb6c2b6..9cf9c490bba2 100644 --- a/src/operator/tensor/histogram-inl.h +++ b/src/operator/tensor/histogram-inl.h @@ -46,13 +46,13 @@ namespace op { struct HistogramParam : public dmlc::Parameter { dmlc::optional bin_cnt; - dmlc::optional> range; + dmlc::optional> range; DMLC_DECLARE_PARAMETER(HistogramParam) { DMLC_DECLARE_FIELD(bin_cnt) .set_default(dmlc::optional()) .describe("Number of bins for uniform case"); DMLC_DECLARE_FIELD(range) - .set_default(dmlc::optional>()) + .set_default(dmlc::optional>()) .describe("The lower and upper range of the bins. if not provided, " "range is simply (a.min(), a.max()). values outside the " "range are ignored. the first element of the range must be " @@ -101,7 +101,7 @@ inline bool HistogramOpShape(const nnvm::NodeAttrs& attrs, SHAPE_ASSIGN_CHECK(*out_attrs, 1, in_attrs->at(1)); } - return !shape_is_none(out_attrs->at(0)) && !shape_is_none(out_attrs->at(1)) && + return shape_is_known(out_attrs->at(0)) && shape_is_known(out_attrs->at(1)) && out_attrs->at(0).Size() == out_attrs->at(1).Size() - 1; } diff --git a/src/operator/tensor/indexing_op.h b/src/operator/tensor/indexing_op.h index 8979531fef4e..6469aae17558 100644 --- a/src/operator/tensor/indexing_op.h +++ b/src/operator/tensor/indexing_op.h @@ -145,20 +145,20 @@ inline bool EmbeddingOpShape(const nnvm::NodeAttrs& attrs, mxnet::ShapeVector *out_attrs) { using namespace mshadow; const mxnet::TShape &dshape = (*in_attrs)[embedding::kData]; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; const ParamType& param = nnvm::get(attrs.parsed); SHAPE_ASSIGN_CHECK(*in_attrs, embedding::kWeight, Shape2(param.input_dim, param.output_dim)); out_attrs->clear(); - mxnet::TShape oshape(dshape.ndim()+1); - for (size_t i = 0; i < dshape.ndim(); ++i) { + mxnet::TShape oshape(dshape.ndim()+1, -1); + for (int i = 0; i < dshape.ndim(); ++i) { oshape[i] = dshape[i]; } oshape[dshape.ndim()] = param.output_dim; out_attrs->push_back(oshape); - return true; + return shape_is_known(oshape); } template @@ -682,18 +682,18 @@ inline bool TakeOpShape(const nnvm::NodeAttrs& attrs, using namespace mshadow; const mxnet::TShape &arrshape = (*in_attrs)[take_::kArr]; const mxnet::TShape &idxshape = (*in_attrs)[take_::kIdx]; - if (idxshape.ndim() == 0U || idxshape.Size() == 0U) return false; + if (!shape_is_known(idxshape)) return false; const TakeParam& param = nnvm::get(attrs.parsed); if (param.mode == take_::kRaise) { LOG(FATAL) << "Raise is not supported for the time being..."; } - CHECK(param.axis >= -1 * (int)arrshape.ndim() && param.axis < (int)arrshape.ndim()) + CHECK(param.axis >= -1 * arrshape.ndim() && param.axis < arrshape.ndim()) << "Axis should be in the range of [-r, r-1] where r is the rank of input tensor"; out_attrs->clear(); const index_t actual_axis = param.axis + ((param.axis < 0) ? arrshape.ndim() : 0); - mxnet::TShape oshape(idxshape.ndim() + arrshape.ndim() - 1); + mxnet::TShape oshape(idxshape.ndim() + arrshape.ndim() - 1, -1); for (index_t i = 0; i < idxshape.ndim(); ++i) { oshape[i + actual_axis] = idxshape[i]; } @@ -705,7 +705,7 @@ inline bool TakeOpShape(const nnvm::NodeAttrs& attrs, } } out_attrs->push_back(oshape); - return true; + return shape_is_known(oshape); } inline bool TakeOpType(const nnvm::NodeAttrs& attrs, @@ -1170,6 +1170,7 @@ inline bool OneHotOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); // The shape of indices const mxnet::TShape& ishape = (*in_attrs)[0]; + if (!shape_is_known(ishape)) return false; int depth = 0; double on_value = 1.0; @@ -1177,13 +1178,13 @@ inline bool OneHotOpShape(const nnvm::NodeAttrs& attrs, int dtype = mshadow::kFloat32; GetOneHotParams(param, &depth, &on_value, &off_value, &dtype); - mxnet::TShape oshape(ishape.ndim() + 1); + mxnet::TShape oshape(ishape.ndim() + 1, -1); for (index_t i = 0; i < ishape.ndim(); ++i) { oshape[i] = ishape[i]; } oshape[oshape.ndim()-1] = depth; SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return true; + return shape_is_known(oshape); } inline bool OneHotOpType(const nnvm::NodeAttrs& attrs, @@ -1270,15 +1271,15 @@ inline bool GatherNDShape(const nnvm::NodeAttrs& attrs, CHECK_LE(ishape[0], 10) << "gather_nd supports indexing along at most 10 dimensions."; - mxnet::TShape oshape(ishape.ndim() - 1 + dshape.ndim() - ishape[0]); + mxnet::TShape oshape(ishape.ndim() - 1 + dshape.ndim() - ishape[0], -1); - for (size_t i = 0; i < ishape.ndim() - 1; ++i) oshape[i] = ishape[i+1]; + for (int i = 0; i < ishape.ndim() - 1; ++i) oshape[i] = ishape[i+1]; for (int i = 0; i < dshape.ndim() - ishape[0]; ++i) { oshape[ishape.ndim()-1+i] = dshape[ishape[0] + i]; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return true; + return shape_is_known(oshape); } inline bool GatherNDType(const nnvm::NodeAttrs& attrs, @@ -1370,7 +1371,7 @@ inline bool ScatterNDShape(const nnvm::NodeAttrs& attrs, bool valid = dshape.ndim() == ishape.ndim() - 1 + oshape.ndim() - ishape[0]; - for (size_t i = 0; i < ishape.ndim() - 1; ++i) { + for (int i = 0; i < ishape.ndim() - 1; ++i) { valid = valid && dshape[i] == ishape[i+1]; } for (int i = 0; i < oshape.ndim() - ishape[0]; ++i) { diff --git a/src/operator/tensor/init_op.h b/src/operator/tensor/init_op.h index fe1a1f62954a..3c4d34b3f4a5 100644 --- a/src/operator/tensor/init_op.h +++ b/src/operator/tensor/init_op.h @@ -49,7 +49,7 @@ struct InitOpParam : public dmlc::Parameter { int dtype; DMLC_DECLARE_PARAMETER(InitOpParam) { DMLC_DECLARE_FIELD(shape) - .set_default(mxnet::TShape()) + .set_default(mxnet::TShape(0, 1)) .describe("The shape of the output"); DMLC_DECLARE_FIELD(ctx) .set_default("") @@ -213,8 +213,8 @@ inline bool InitShape(const nnvm::NodeAttrs& attrs, const ParamType& param = nnvm::get(attrs.parsed); CHECK_EQ(in_attrs->size(), 0U); CHECK_EQ(out_attrs->size(), 1U); - if ((*out_attrs)[0].ndim() != 0 && param.shape.ndim() == 0) return true; - for (unsigned int i=0 ; i < param.shape.ndim() ; ++i) { + if (shape_is_known((*out_attrs)[0]) && !shape_is_known(param.shape)) return true; + for (int i=0 ; i < param.shape.ndim() ; ++i) { if (param.shape[i] < 0U) { LOG(FATAL) << "Shape cannot contain negative values " << param.shape; } diff --git a/src/operator/tensor/la_op.h b/src/operator/tensor/la_op.h index 5e18e0ef5a25..db4607fe9262 100644 --- a/src/operator/tensor/la_op.h +++ b/src/operator/tensor/la_op.h @@ -384,7 +384,7 @@ mshadow::Tensor LaOpFlatten(const TBlob& blob, } // Collapse ranges [0,axis-1] and [axis+1,ndim-2]. CHECK_EQ(dim, 4); - mxnet::TShape shape(dim); + mxnet::TShape shape(dim, -1); shape[0] = 1; for (int i = 0; i < axis; ++i) { shape[0] *= blob.shape_[i]; diff --git a/src/operator/tensor/matrix_op-inl.h b/src/operator/tensor/matrix_op-inl.h index 5eecda622729..e7b90e52d968 100644 --- a/src/operator/tensor/matrix_op-inl.h +++ b/src/operator/tensor/matrix_op-inl.h @@ -49,17 +49,17 @@ namespace op { struct ReshapeParam : public dmlc::Parameter { mxnet::TShape target_shape; bool keep_highest; - nnvm::Tuple shape; + mxnet::Tuple shape; bool reverse; DMLC_DECLARE_PARAMETER(ReshapeParam) { DMLC_DECLARE_FIELD(shape) - .set_default(nnvm::Tuple()) + .set_default(mxnet::Tuple()) .describe("The target shape"); DMLC_DECLARE_FIELD(reverse) .set_default(false) .describe("If true then the special values are inferred from right to left"); DMLC_DECLARE_FIELD(target_shape) - .set_default(mxnet::TShape()) + .set_default(mxnet::TShape(0)) .describe("(Deprecated! Use ``shape`` instead.) " "Target new shape. One and only one dim can be 0, " "in which case it will be inferred from the rest of dims"); @@ -71,11 +71,11 @@ struct ReshapeParam : public dmlc::Parameter { }; template -inline mxnet::TShape InferReshapeShape(const nnvm::Tuple& shape, - const mxnet::TShape& dshape, bool reverse) { +inline mxnet::TShape InferReshapeShape(const mxnet::Tuple& shape, + const mxnet::TShape& dshape, bool reverse) { std::vector dshape_vec; std::vector param_shape_vec(shape.begin(), shape.end()); - for (index_t i = 0; i < dshape.ndim(); ++i) { + for (int i = 0; i < dshape.ndim(); ++i) { dshape_vec.push_back(dshape[i]); } std::vector tmp; @@ -102,28 +102,31 @@ inline mxnet::TShape InferReshapeShape(const nnvm::Tuple& shape, } else if (proposed_dim == -2) { // copy all remaining dims from source while (src_idx < dshape_len) { - size_t dn = dshape_vec[src_idx++]; + const int dn = dshape_vec[src_idx++]; tmp.push_back(dn); } } else if (proposed_dim == -3) { // merge two dims from source CHECK_LT(src_idx, dshape_len-1); - size_t d1 = dshape_vec[src_idx++]; - size_t d2 = dshape_vec[src_idx++]; - size_t dn = d1 * d2; - tmp.push_back(dn); + const int d1 = dshape_vec[src_idx++]; + const int d2 = dshape_vec[src_idx++]; + if (d1 == -1 || d2 == -1) { + tmp.push_back(-1); + } else { + tmp.push_back(d1 * d2); + } } else if (proposed_dim == -4) { // split the source dim s into two dims // read the left dim and then the right dim (either can be -1) CHECK_LT(i + 2, params_len); CHECK_LT(src_idx, dshape_len); - size_t d0 = dshape_vec[src_idx++]; + const int d0 = dshape_vec[src_idx++]; IType d1 = param_shape_vec[++i]; IType d2 = param_shape_vec[++i]; CHECK(d1 != -1 || d2 != -1) << "Split dims cannot both be -1."; - if (d1 == -1) d1 = d0 / d2; - if (d2 == -1) d2 = d0 / d1; - CHECK(d1 * d2 == static_cast(d0) || static_cast(d0) == IType(0)) << + if (d1 == -1 && d0 >= 0) d1 = d0 / d2; // d0 must be known to do this + if (d2 == -1 && d0 >= 0) d2 = d0 / d1; // d0 must be known to do this + CHECK(d1 * d2 == static_cast(d0) || static_cast(d0) == IType(-1)) << "Split dims " << d1 << ", " << d2 << " do not divide original dim " << d0; tmp.push_back(d1); tmp.push_back(d2); @@ -135,12 +138,12 @@ inline mxnet::TShape InferReshapeShape(const nnvm::Tuple& shape, } if (inf_idx >= 0) { - if (dshape.Size() > 0) { + if (shape_is_known(dshape)) { IType new_size = 1; for (IType x : tmp) new_size *= x; tmp[inf_idx] = dshape.Size() / new_size; } else { - tmp[inf_idx] = 0; + tmp[inf_idx] = -1; } } if (reverse) { @@ -153,24 +156,24 @@ inline mxnet::TShape InferReshapeShape(const nnvm::Tuple& shape, } inline bool ReverseReshapeInferShape(mxnet::TShape *in, const mxnet::TShape& out) { - if (in->Size() && out.Size()) { + if (shape_is_known(*in) && shape_is_known(out)) { return true; - } else if (!out.Size()) { + } else if (!shape_is_known(out)) { return false; } else { int zero_axis = -1; - int non_zero_prod = 1; - for (index_t i = 0; i < in->ndim(); i++) { - if ((*in)[i] == 0) { + int known_dim_size_prod = 1; + for (int i = 0; i < in->ndim(); i++) { + if ((*in)[i] == -1) { if (zero_axis != -1) return false; // more than 1 zero found. else zero_axis = i; } else { - non_zero_prod *= (*in)[i]; + known_dim_size_prod *= (*in)[i]; } } - (*in)[zero_axis] = out.Size() / non_zero_prod; + (*in)[zero_axis] = out.Size() / known_dim_size_prod; return true; } } @@ -182,11 +185,11 @@ inline bool ReshapeShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U) << "Input: [data]"; CHECK_EQ(out_attrs->size(), 1U); mxnet::TShape &dshape = (*in_attrs)[0]; - if (dshape.ndim() == 0) return false; + if (dshape.ndim() == -1) return false; mxnet::TShape oshape; if (param_.shape.ndim() != 0) { oshape = InferReshapeShape(param_.shape, dshape, param_.reverse); - } else if (param_.target_shape.ndim()) { + } else if (param_.target_shape.ndim() != -1) { LOG(INFO) << "Using target_shape will be deprecated."; oshape = param_.target_shape; int neg_count = 0; @@ -195,7 +198,7 @@ inline bool ReshapeShape(const nnvm::NodeAttrs& attrs, if (param_.keep_highest) { oshape[0] = dshape[0]; } - for (index_t i = start_idx; i < oshape.ndim(); ++i) { + for (int i = start_idx; i < oshape.ndim(); ++i) { if (oshape[i] == 0) { neg_count++; inf_idx = i; @@ -206,13 +209,15 @@ inline bool ReshapeShape(const nnvm::NodeAttrs& attrs, oshape[inf_idx] = dshape.Size() / oshape.Size(); } } else { - return (*out_attrs)[0].ndim() && ReverseReshapeInferShape(&(*in_attrs)[0], (*out_attrs)[0]); + return shape_is_known((*out_attrs)[0]) && ReverseReshapeInferShape(&(*in_attrs)[0], (*out_attrs)[0]); } ReverseReshapeInferShape(&dshape, oshape); +#if 0 CHECK_EQ(oshape.Size(), dshape.Size()) << "Target shape size is different to source. " << "Target: " << oshape << "\nSource: " << dshape; +#endif SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); return ReverseReshapeInferShape(&(*in_attrs)[0], (*out_attrs)[0]); } @@ -223,9 +228,9 @@ inline bool FlattenShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U) << "Input: [data]"; CHECK_EQ(out_attrs->size(), 1U); const mxnet::TShape &dshape = (*in_attrs)[0]; - if (dshape.ndim() == 0) return false; - uint32_t target_dim = 1; - for (uint32_t i = 1; i < dshape.ndim(); ++i) { + if (!shape_is_known(dshape)) return false; + int target_dim = 1; + for (int i = 1; i < dshape.ndim(); ++i) { target_dim *= dshape[i]; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, mshadow::Shape2(dshape[0], target_dim)); @@ -309,9 +314,9 @@ void Transpose(const nnvm::NodeAttrs& attrs, const std::vector& outputs) { const TransposeParam& param = nnvm::get(attrs.parsed); CHECK_EQ(req[0], kWriteTo) << "Transpose does not support inplace"; - if (param.axes.ndim() == 0) { - mxnet::TShape axes = mxnet::TShape(inputs[0].ndim()); - for (index_t i = 0; i < axes.ndim(); ++i) { + if (param.axes.ndim() == -1) { + mxnet::TShape axes(inputs[0].ndim(), -1); + for (int i = 0; i < axes.ndim(); ++i) { axes[i] = axes.ndim() - 1 - i; } TransposeImpl(ctx.run_ctx, inputs[0], outputs[0], axes); @@ -328,20 +333,20 @@ inline bool TransposeShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); mxnet::TShape& shp = (*in_attrs)[0]; CHECK_LE(shp.ndim(), 6U) << "Transpose support at most 6 dimensions"; - mxnet::TShape ret(shp.ndim()); - if (param.axes.ndim() == 0) { - for (index_t i = 0; i < shp.ndim(); ++i) { + mxnet::TShape ret(shp.ndim(), -1); + if (param.axes.ndim() == -1) { + for (int i = 0; i < shp.ndim(); ++i) { ret[i] = shp[shp.ndim()-1-i]; } } else { CHECK_EQ(shp.ndim(), param.axes.ndim()); - for (size_t i = 0; i < shp.ndim(); ++i) { + for (int i = 0; i < shp.ndim(); ++i) { CHECK(param.axes[i] < static_cast(shp.ndim())); ret[i] = shp[param.axes[i]]; } } SHAPE_ASSIGN_CHECK(*out_attrs, 0, ret); - return true; + return shape_is_known(ret); } @@ -362,7 +367,7 @@ inline bool ExpandDimShape(const nnvm::NodeAttrs& attrs, const ExpandDimParam& param = nnvm::get(attrs.parsed); CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); - if (in_attrs->at(0).ndim() == 0U && out_attrs->at(0).ndim() == 0U) { + if (!shape_is_known(in_attrs->at(0)) && !shape_is_known(out_attrs->at(0))) { return false; } @@ -370,7 +375,7 @@ inline bool ExpandDimShape(const nnvm::NodeAttrs& attrs, mxnet::TShape& oshape = (*out_attrs)[0]; int indim = ishape.ndim(); bool unknown_ishape = false; - if (0 == indim) { + if (-1 == indim) { indim = oshape.ndim() - 1; unknown_ishape = true; } @@ -382,27 +387,27 @@ inline bool ExpandDimShape(const nnvm::NodeAttrs& attrs, CHECK(axis >= 0 && axis <= indim) << "axis must be in the range [" << -indim << ", " << indim << "] (" << param.axis << " provided)"; - mxnet::TShape ret(indim + 1); + mxnet::TShape ret(indim + 1, -1); for (int i = 0; i < axis; ++i) { - ret[i] = (unknown_ishape? 0 : ishape[i]); + ret[i] = (unknown_ishape? -1 : ishape[i]); } ret[axis] = 1; for (int i = axis+1; i < indim+1; ++i) { - ret[i] = (unknown_ishape? 0 : ishape[i-1]); + ret[i] = (unknown_ishape? -1 : ishape[i-1]); } SHAPE_ASSIGN_CHECK(*out_attrs, 0, ret); - ret = mxnet::TShape(indim); + ret = mxnet::TShape(indim, -1); for (int i = 0; i < axis; ++i) ret[i] = oshape[i]; for (int i = axis+1; i < indim+1; ++i) ret[i-1] = oshape[i]; SHAPE_ASSIGN_CHECK(*in_attrs, 0, ret); - return true; + return shape_is_known(ret); } // Currently MKLDNN only supports step = 1 or step has no value inline bool SupportMKLDNNSlice(const SliceParam& param) { if (param.step.ndim() == 0U) return true; - for (uint32_t i = 0; i < param.step.ndim(); ++i) { + for (int i = 0; i < param.step.ndim(); ++i) { if (param.step[i].has_value() && param.step[i].value() != 1) return false; } @@ -585,9 +590,9 @@ void SliceCsrImpl(const SliceParam ¶m, const OpContext& ctx, const mxnet::TShape ishape = in.shape(); const mxnet::TShape oshape = out.shape(); - uint32_t N = ishape.ndim(); - mxnet::TShape begin(N), end(N); - for (uint32_t i = 0; i < N; ++i) { + int N = ishape.ndim(); + mxnet::TShape begin(N, -1), end(N, -1); + for (int i = 0; i < N; ++i) { int s = 0; if (param.begin[i]) { s = *param.begin[i]; @@ -630,9 +635,9 @@ void SliceEx(const nnvm::NodeAttrs& attrs, template inline void GetIndexRange(const mxnet::TShape& dshape, - const nnvm::Tuple>& param_begin, - const nnvm::Tuple>& param_end, - const nnvm::Tuple>& param_step, + const mxnet::Tuple>& param_begin, + const mxnet::Tuple>& param_end, + const mxnet::Tuple>& param_step, common::StaticArray* begin, common::StaticArray* end, common::StaticArray* step) { @@ -647,7 +652,7 @@ inline void GetIndexRange(const mxnet::TShape& dshape, << "Static array size=" << ndim << " is not equal to data shape ndim=" << dshape.ndim(); - if (param_step.ndim() != 0U) { + if (param_step.ndim() != 0) { CHECK_EQ(param_step.ndim(), param_begin.ndim()) << "step and begin must have the same length"; } @@ -719,7 +724,7 @@ inline bool SliceOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); const mxnet::TShape& dshape = (*in_attrs)[0]; - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; const SliceParam& param = nnvm::get(attrs.parsed); mxnet::TShape oshape = dshape; @@ -733,7 +738,7 @@ inline bool SliceOpShape(const nnvm::NodeAttrs& attrs, }); SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return !shape_is_none(dshape) && !shape_is_none(oshape); + return shape_is_known(oshape); } template @@ -939,7 +944,7 @@ inline bool SliceAssignOpShape(const nnvm::NodeAttrs& attrs, MXNET_NDIM_SWITCH(dshape.ndim(), ndim, { common::StaticArray begin, end, step; GetIndexRange(dshape, param.begin, param.end, param.step, &begin, &end, &step); - for (index_t i = 0; i < param.begin.ndim(); ++i) { + for (int i = 0; i < param.begin.ndim(); ++i) { const int b = begin[i], e = end[i], s = step[i]; SetSliceOpOutputDimSize(i, b, e, s, &vshape); } @@ -993,8 +998,8 @@ void SliceAssignOpForward(const nnvm::NodeAttrs& attrs, struct SliceAssignScalarParam : public dmlc::Parameter { double scalar; - nnvm::Tuple> begin, end; - nnvm::Tuple> step; + mxnet::Tuple> begin, end; + mxnet::Tuple> step; DMLC_DECLARE_PARAMETER(SliceAssignScalarParam) { DMLC_DECLARE_FIELD(scalar) .set_default(0) @@ -1004,7 +1009,7 @@ struct SliceAssignScalarParam : public dmlc::Parameter { DMLC_DECLARE_FIELD(end) .describe("ending indices for the slice operation, supports negative indices."); DMLC_DECLARE_FIELD(step) - .set_default(nnvm::Tuple>()) + .set_default(mxnet::Tuple>()) .describe("step for the slice operation, supports negative values."); } }; @@ -1015,7 +1020,7 @@ inline bool SliceAssignScalarOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U); CHECK_EQ(out_attrs->size(), 1U); const mxnet::TShape& dshape = (*in_attrs)[0]; - if (dshape.ndim() == 0U || dshape.Size() == 0U) return false; + if (!shape_is_known(dshape)) return false; SHAPE_ASSIGN_CHECK(*out_attrs, 0, dshape); return true; } @@ -1152,8 +1157,8 @@ inline bool SliceAxisShape(const nnvm::NodeAttrs& attrs, int axis; index_t begin, end; GetSliceAxisParams(param, ishape, &axis, &begin, &end); - mxnet::TShape shape(ishape.ndim()); - for (index_t i = 0; i < ishape.ndim(); ++i) { + mxnet::TShape shape(ishape.ndim(), -1); + for (int i = 0; i < ishape.ndim(); ++i) { if (static_cast(i) == axis) { shape[i] = static_cast(end - begin); } else { @@ -1161,7 +1166,7 @@ inline bool SliceAxisShape(const nnvm::NodeAttrs& attrs, } } SHAPE_ASSIGN_CHECK(*out_attrs, 0, shape); - return true; + return shape_is_known(shape); } @@ -1177,7 +1182,7 @@ void SliceAxis(const nnvm::NodeAttrs& attrs, int axis; index_t begin, end; GetSliceAxisParams(param, inputs[0].shape_, &axis, &begin, &end); - int ndim = static_cast(outputs[0].ndim()); + int ndim = outputs[0].ndim(); if (axis + 1 == ndim) { MSHADOW_TYPE_SWITCH(outputs[0].type_flag_, DType, { @@ -1248,9 +1253,9 @@ void SliceAxisGrad_(const nnvm::NodeAttrs& attrs, } struct SliceLikeParam : public dmlc::Parameter { - mxnet::TShape axes; + mxnet::Tuple axes; DMLC_DECLARE_PARAMETER(SliceLikeParam) { - DMLC_DECLARE_FIELD(axes).set_default(mxnet::TShape()) + DMLC_DECLARE_FIELD(axes).set_default(mxnet::Tuple()) .describe("List of axes on which input data will be sliced according to the " "corresponding size of the second input. By default will slice on " "all axes. Negative axes are supported."); @@ -1269,7 +1274,7 @@ inline bool SliceLikeShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(ishape.ndim(), from_shape.ndim()) << "By default slice_axis performs slice on all axes, but ndim mismatch " "for inputs: " << ishape.ndim() << " vs. " << from_shape.ndim(); - for (index_t i = 0; i < ishape.ndim(); ++i) { + for (int i = 0; i < ishape.ndim(); ++i) { CHECK_GE(ishape[i], from_shape[i]) << "Slice axis " << i << " with size " << from_shape[i] << "exceeds limit of input with size " << ishape[i]; @@ -1277,7 +1282,7 @@ inline bool SliceLikeShape(const nnvm::NodeAttrs& attrs, SHAPE_ASSIGN_CHECK(*out_attrs, 0, from_shape); } else { mxnet::TShape shape(ishape); - for (index_t i = 0; i < param.axes.ndim(); ++i) { + for (int i = 0; i < param.axes.ndim(); ++i) { int axis = static_cast(param.axes[i]); if (axis < 0) { axis += static_cast(ishape.ndim()); @@ -1300,21 +1305,21 @@ inline bool SliceLikeShape(const nnvm::NodeAttrs& attrs, inline void SliceLikeInferRanges(const mxnet::TShape& dshape, const mxnet::TShape& fshape, - const mxnet::TShape& axes, - nnvm::Tuple>* param_begin, - nnvm::Tuple>* param_end, - nnvm::Tuple>* param_step) { + const mxnet::Tuple& axes, + mxnet::Tuple>* param_begin, + mxnet::Tuple>* param_end, + mxnet::Tuple>* param_step) { std::vector> pb(dshape.ndim()); std::vector> pe(dshape.ndim()); std::vector> ps(dshape.ndim()); if (axes.ndim() == 0) { - for (index_t i = 0; i < dshape.ndim(); ++i) { + for (int i = 0; i < dshape.ndim(); ++i) { pb[i] = 0; pe[i] = fshape[i]; ps[i] = 1; } } else { - for (index_t i = 0; i < axes.ndim(); ++i) { + for (int i = 0; i < axes.ndim(); ++i) { int axis = static_cast(axes[i]); if (axis < 0) { axis += static_cast(dshape.ndim()); @@ -1330,9 +1335,9 @@ inline void SliceLikeInferRanges(const mxnet::TShape& dshape, ps[axis] = 1; } } - *param_begin = nnvm::Tuple>(pb.begin(), pb.end()); - *param_end = nnvm::Tuple>(pe.begin(), pe.end()); - *param_step = nnvm::Tuple>(ps.begin(), ps.end()); + *param_begin = mxnet::Tuple>(pb.begin(), pb.end()); + *param_end = mxnet::Tuple>(pe.begin(), pe.end()); + *param_step = mxnet::Tuple>(ps.begin(), ps.end()); } template @@ -1351,9 +1356,9 @@ void SliceLikeForward(const nnvm::NodeAttrs& attrs, const TBlob& out = outputs[0]; const mxnet::TShape& ishape = data.shape_; const mxnet::TShape& from_shape = inputs[1].shape_; - nnvm::Tuple> param_begin; - nnvm::Tuple> param_end; - nnvm::Tuple> param_step; + mxnet::Tuple> param_begin; + mxnet::Tuple> param_end; + mxnet::Tuple> param_step; SliceLikeInferRanges(ishape, from_shape, param.axes, ¶m_begin, ¶m_end, ¶m_step); MXNET_NDIM_SWITCH(data.ndim(), ndim, { @@ -1399,9 +1404,9 @@ void SliceLikeBackward(const nnvm::NodeAttrs& attrs, const mxnet::TShape& ishape = ograd.shape_; const mxnet::TShape& from_shape = outputs[1].shape_; - nnvm::Tuple> param_begin; - nnvm::Tuple> param_end; - nnvm::Tuple> param_step; + mxnet::Tuple> param_begin; + mxnet::Tuple> param_end; + mxnet::Tuple> param_step; SliceLikeInferRanges(ishape, from_shape, param.axes, ¶m_begin, ¶m_end, ¶m_step); MXNET_NDIM_SWITCH(ograd.ndim(), ndim, { @@ -1542,7 +1547,7 @@ inline void GetRepeatParams(const RepeatParam& param, const mxnet::TShape& ishap CHECK_GE(*repeats, 0) << "repeats cannot be a negative number"; *axisOpt = param.axis; if (static_cast(*axisOpt)) { - int ndims = static_cast(ishape.ndim()); + int ndims = ishape.ndim(); int axis = axisOpt->value(); if (axis < 0) { axis += ndims; @@ -1561,34 +1566,33 @@ inline bool RepeatOpShape(const nnvm::NodeAttrs& attrs, int repeats = 0; dmlc::optional axisOpt; GetRepeatParams(param, ishape, &repeats, &axisOpt); - // If 0 repeats, return an empty 0 dim array + // If 0 repeats, return an empty 1-dim, 0-size array if (0 == repeats) { - SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape()); + SHAPE_ASSIGN_CHECK(*out_attrs, 0, mxnet::TShape(1, 0)); return true; } // If repeats > 0, multiply the size of the corresponding axis by repeats if (static_cast(axisOpt)) { - int ndims = static_cast(ishape.ndim()); + int ndims = ishape.ndim(); int axis = axisOpt.value(); if (axis < 0) { axis += ndims; } - mxnet::TShape shape(ishape.ndim()); - for (index_t i = 0; i < ishape.ndim(); ++i) { - if (static_cast(i) == axis) { - shape[i] = static_cast(repeats) * ishape[i]; + mxnet::TShape shape(ishape.ndim(), -1); + for (int i = 0; i < ishape.ndim(); ++i) { + if (i == axis) { + shape[i] = repeats * ishape[i]; } else { shape[i] = ishape[i]; } } SHAPE_ASSIGN_CHECK(*out_attrs, 0, shape); } else { // If axis is not input by user, return a flat 1D array of size = in.size*repeats - mxnet::TShape shape(1); - shape[0] = ishape.Size() * static_cast(repeats); + mxnet::TShape shape(1, ishape.Size() * repeats); SHAPE_ASSIGN_CHECK(*out_attrs, 0, shape); } - return true; + return shape_is_known(out_attrs->at(0)); } inline bool RepeatOpType(const nnvm::NodeAttrs& attrs, @@ -1616,16 +1620,16 @@ inline std::pair ReshapeInputOutputForRepeatOp( const int repeats) { if (static_cast(axisOpt)) { int axis = axisOpt.value(); - int ndim = static_cast(ishape.ndim()); + int ndim = ishape.ndim(); if (axis < 0) { axis += ndim; } - CHECK(axis >= 0 && axis < static_cast(ishape.ndim())) << "Invalid input of axis"; + CHECK(axis >= 0 && axis < ishape.ndim()) << "Invalid input of axis"; // reshape the input tensor by adding a dim at the (axis+1)-th dim - mxnet::TShape rshape(ishape.ndim()+1); + mxnet::TShape rshape(ishape.ndim()+1, 1); // the shape we want to broadcast to - mxnet::TShape bshape(rshape.ndim()); + mxnet::TShape bshape(rshape.ndim(), 1); int i = 0; while (i <= axis) { rshape[i] = bshape[i] = ishape[i]; @@ -1633,7 +1637,7 @@ inline std::pair ReshapeInputOutputForRepeatOp( } rshape[i] = 1; bshape[i] = repeats; - while (i < static_cast(ishape.ndim())) { + while (i < ishape.ndim()) { rshape[i+1] = ishape[i]; bshape[i+1] = ishape[i]; ++i; @@ -1644,11 +1648,11 @@ inline std::pair ReshapeInputOutputForRepeatOp( // reshape the tensor into shape (ishape.Size(), 1) // then add one dim at axis = 1 and broadcast to // shape (ishape.Size(), repeats) - mxnet::TShape rshape(2); + mxnet::TShape rshape(2, 1); rshape[0] = ishape.Size(); rshape[1] = 1; - mxnet::TShape bshape(2); + mxnet::TShape bshape(2, 1); bshape[0] = rshape[0]; bshape[1] = repeats; return std::make_pair(rshape, bshape); @@ -1663,7 +1667,7 @@ void RepeatOpForward(const nnvm::NodeAttrs& attrs, const std::vector& outputs) { const TBlob& iTBlob = inputs[0]; const mxnet::TShape& ishape = iTBlob.shape_; - if (ishape.ndim() == 0) return; + if (!shape_is_known(ishape)) return; int repeats = 0; dmlc::optional axisOpt; @@ -1707,7 +1711,7 @@ void RepeatOpBackward(const nnvm::NodeAttrs& attrs, CHECK_EQ(outputs.size(), 1U); const mxnet::TShape& oshape = outputs[0].shape_; - if (oshape.ndim() == 0) return; + if (!shape_is_known(oshape)) return; int repeats = 0; dmlc::optional axisOpt; @@ -1733,7 +1737,7 @@ void RepeatOpBackward(const nnvm::NodeAttrs& attrs, } struct TileParam : public dmlc::Parameter { - mxnet::TShape reps; + mxnet::Tuple reps; DMLC_DECLARE_PARAMETER(TileParam) { DMLC_DECLARE_FIELD(reps) .describe("The number of times for repeating the tensor a. Each dim size of reps" @@ -1751,19 +1755,22 @@ inline bool TileOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); const TileParam& param = nnvm::get(attrs.parsed); const mxnet::TShape& ishape = (*in_attrs)[0]; - const mxnet::TShape& reps = param.reps; + if (!shape_is_known(ishape)) { + return false; + } + const mxnet::Tuple& reps = param.reps; // If reps is empty, return a identical input array - if (reps.ndim() == 0 || ishape.ndim() == 0) { + if (reps.ndim() == 0) { SHAPE_ASSIGN_CHECK(*out_attrs, 0, ishape); return true; } - for (size_t i = 0; i < reps.ndim(); ++i) { + for (int i = 0; i < reps.ndim(); ++i) { CHECK_GT(reps[i], 0) << "invalid reps=" << i << ", dim size must be greater than zero"; } - mxnet::TShape oshape(std::max(ishape.ndim(), reps.ndim())); - int i1 = static_cast(ishape.ndim()) - 1; - int i2 = static_cast(reps.ndim()) - 1; - for (int i = static_cast(oshape.ndim()) - 1; i >= 0; --i) { + mxnet::TShape oshape(std::max(ishape.ndim(), reps.ndim()), -1); + int i1 = ishape.ndim() - 1; + int i2 = reps.ndim() - 1; + for (int i = oshape.ndim() - 1; i >= 0; --i) { if (i1 >= 0 && i2 >= 0) { oshape[i] = ishape[i1--] * reps[i2--]; } else if (i1 >= 0) { @@ -1773,7 +1780,7 @@ inline bool TileOpShape(const nnvm::NodeAttrs& attrs, } } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return true; + return shape_is_known(oshape); } inline bool TileOpType(const nnvm::NodeAttrs& attrs, @@ -1797,20 +1804,20 @@ inline bool TileOpType(const nnvm::NodeAttrs& attrs, */ inline std::pair ReshapeInputOutputForTileOp( const mxnet::TShape& ishape, - const mxnet::TShape& reps) { + const mxnet::Tuple& reps) { if (ishape.ndim() == 0 || reps.ndim() == 0) { return std::make_pair(ishape, ishape); } // The shape we want to broadcast to - mxnet::TShape bshape(std::max(ishape.ndim(), reps.ndim()) * 2); + mxnet::TShape bshape(std::max(ishape.ndim(), reps.ndim()) * 2, 1); // The shape of the input tensor after adding new axes before each dim - mxnet::TShape rshape(bshape.ndim()); + mxnet::TShape rshape(bshape.ndim(), 1); - int i1 = static_cast(ishape.ndim()) - 1; - int i2 = static_cast(reps.ndim()) - 1; - for (int i = static_cast(bshape.ndim()) - 1; i >= 0; --i) { + int i1 = ishape.ndim() - 1; + int i2 = reps.ndim() - 1; + for (int i = bshape.ndim() - 1; i >= 0; --i) { if (0 == (i & 1)) { bshape[i] = (i2 >= 0? reps[i2--] : 1); rshape[i] = 1; @@ -1850,10 +1857,10 @@ void TileOpForward(const nnvm::NodeAttrs& attrs, if (inputs[0].Size() == 0) return; const mxnet::TShape& ishape = inputs[0].shape_; - const mxnet::TShape& reps = nnvm::get(attrs.parsed).reps; + const mxnet::Tuple& reps = nnvm::get(attrs.parsed).reps; // If any one of the number in reps is zero, return immediately - for (index_t i = 0; i < reps.ndim(); ++i) { + for (int i = 0; i < reps.ndim(); ++i) { if (0 == reps[i]) return; } @@ -1892,10 +1899,10 @@ void TileOpBackward(const nnvm::NodeAttrs& attrs, if (inputs[0].Size() == 0) return; const mxnet::TShape& oshape = outputs[0].shape_; - const mxnet::TShape& reps = nnvm::get(attrs.parsed).reps; + const mxnet::Tuple& reps = nnvm::get(attrs.parsed).reps; // If any one of the number in reps is zero, return immediately - for (index_t i = 0; i < reps.ndim(); ++i) { + for (int i = 0; i < reps.ndim(); ++i) { if (0 == reps[i]) return; } @@ -1915,7 +1922,7 @@ void TileOpBackward(const nnvm::NodeAttrs& attrs, } struct ReverseParam : public dmlc::Parameter { - nnvm::Tuple axis; + mxnet::Tuple axis; DMLC_DECLARE_PARAMETER(ReverseParam) { DMLC_DECLARE_FIELD(axis) .describe("The axis which to reverse elements."); @@ -1986,10 +1993,10 @@ void ReverseOpForward(const nnvm::NodeAttrs& attrs, std::vector trailing_(param.axis.ndim()); index_t reverse_index = 0; for (int axis : param.axis) { - CHECK_LT(axis, static_cast(ishape.ndim())); + CHECK_LT(axis, ishape.ndim()); stride_[reverse_index] = ishape[axis]; trailing_[reverse_index] = 1; - for (index_t i2 = axis + 1; i2 < ishape.ndim(); ++i2) { + for (int i2 = axis + 1; i2 < ishape.ndim(); ++i2) { trailing_[reverse_index] *= ishape[i2]; } reverse_index++; @@ -2050,9 +2057,9 @@ inline bool StackOpShape(const nnvm::NodeAttrs& attrs, for (const mxnet::TShape& i : (*in_attrs)) { shape_assign(&dshape, i); } - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; - mxnet::TShape oshape(dshape.ndim() + 1); + mxnet::TShape oshape(dshape.ndim() + 1, -1); int axis = CheckAxis(param.axis, oshape.ndim()); for (int i = 0; i < axis; ++i) { oshape[i] = dshape[i]; @@ -2063,7 +2070,7 @@ inline bool StackOpShape(const nnvm::NodeAttrs& attrs, } SHAPE_ASSIGN_CHECK(*out_attrs, 0, oshape); - return true; + return shape_is_known(oshape); } @@ -2136,10 +2143,10 @@ void StackOpBackward(const nnvm::NodeAttrs& attrs, } struct SqueezeParam : public dmlc::Parameter { - dmlc::optional axis; + dmlc::optional> axis; DMLC_DECLARE_PARAMETER(SqueezeParam) { DMLC_DECLARE_FIELD(axis) - .set_default(dmlc::optional()) + .set_default(dmlc::optional>()) .describe("Selects a subset of the single-dimensional entries in the shape." " If an axis is selected with shape entry greater than one, an error is raised."); } @@ -2152,7 +2159,7 @@ struct SqueezeParam : public dmlc::Parameter { inline size_t SqueezeShapeHelper(mxnet::TShape* shape) { CHECK(shape != nullptr); size_t count = 0; - for (size_t i = 0; i < shape->ndim(); ++i) { + for (int i = 0; i < shape->ndim(); ++i) { if ((*shape)[i] == 0) { ++count; } else { @@ -2170,12 +2177,12 @@ inline bool SqueezeShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); const mxnet::TShape& dshape = in_attrs->at(0); const int dndim = dshape.ndim(); - if (shape_is_none(dshape)) return false; + if (!shape_is_known(dshape)) return false; mxnet::TShape oshape = dshape; if (param.axis.has_value()) { // preprocess axis - mxnet::TShape axes = param.axis.value(); - for (size_t i = 0; i < axes.ndim(); ++i) { + mxnet::Tuple axes = param.axis.value(); + for (int i = 0; i < axes.ndim(); ++i) { if (axes[i] < 0) { axes[i] += dndim; CHECK_GE(axes[i], 0) @@ -2190,7 +2197,7 @@ inline bool SqueezeShape(const nnvm::NodeAttrs& attrs, oshape[axes[i]] = 0; } } else { - for (size_t i = 0; i < oshape.ndim(); ++i) { + for (int i = 0; i < oshape.ndim(); ++i) { if (oshape[i] == 1) oshape[i] = 0; } } @@ -2219,7 +2226,7 @@ inline bool DepthToSpaceOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); CHECK_EQ(in_attrs->at(0).ndim(), 4) << "Operation Depth To Space requires exactly 4D tensor"; - mxnet::TShape expected_out(4); + mxnet::TShape expected_out(4, -1); mxnet::TShape& in_shape = in_attrs->at(0); int block = param.block_size; @@ -2237,14 +2244,14 @@ inline bool DepthToSpaceOpShape(const nnvm::NodeAttrs& attrs, expected_out[0] = in_shape[0]; expected_out[1] = in_shape[1] / (block * block); - size_t i = 2; + int i = 2; while (i < expected_out.ndim()) { expected_out[i] = in_shape[i] * block; ++i; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, expected_out); - return true; + return shape_is_known(expected_out); } inline bool DepthToSpaceOpType(const nnvm::NodeAttrs& attrs, @@ -2383,7 +2390,7 @@ inline bool SpaceToDepthOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(out_attrs->size(), 1U); CHECK_EQ(in_attrs->at(0).ndim(), 4) << "Operation Space To Depth requires exactly 4D tensor"; - mxnet::TShape expected_out(in_attrs->at(0).ndim()); + mxnet::TShape expected_out(in_attrs->at(0).ndim(), -1); mxnet::TShape& in_shape = in_attrs->at(0); int block = param.block_size; @@ -2404,14 +2411,14 @@ inline bool SpaceToDepthOpShape(const nnvm::NodeAttrs& attrs, expected_out[0] = in_shape[0]; expected_out[1] = in_shape[1] * block * block; - uint32_t i = 2; + int i = 2; while (i < expected_out.ndim()) { expected_out[i] = in_shape[i] / block; ++i; } SHAPE_ASSIGN_CHECK(*out_attrs, 0, expected_out); - return true; + return shape_is_known(expected_out); } inline bool SpaceToDepthOpType(const nnvm::NodeAttrs& attrs, @@ -2552,7 +2559,7 @@ struct SplitParam : public dmlc::Parameter { }; // struct SplitParam inline mxnet::TShape GetSplitIndices(const mxnet::TShape& ishape, int axis, int sections) { - mxnet::TShape indices(sections+1); + mxnet::TShape indices(sections+1, -1); indices[0] = 0; int64_t section_size = ishape[axis] / sections; for (int i = 0; i < sections; ++i) { @@ -2584,7 +2591,7 @@ inline bool SplitOpShape(const nnvm::NodeAttrs& attrs, CHECK_EQ(in_attrs->size(), 1U); mxnet::TShape dshape = in_attrs->at(split_enum::kData); mxnet::TShape ishape = in_attrs->at(split_enum::kData); - if (dshape.ndim() == 0) return false; + if (!shape_is_known(dshape)) return false; if (param.axis >= 0) { CHECK_LT(static_cast(param.axis), dshape.ndim()); } else { @@ -2599,7 +2606,7 @@ inline bool SplitOpShape(const nnvm::NodeAttrs& attrs, int num_outputs = (param.sections > 0) ? indices.ndim() - 1 : indices.ndim(); // Pre-compute squeezed output shape for future usage mxnet::TShape squeezed_dshape = dshape; - for (int d = real_axis; d < static_cast(squeezed_dshape.ndim()) - 1; ++d) { + for (int d = real_axis; d < squeezed_dshape.ndim() - 1; ++d) { squeezed_dshape[d] = squeezed_dshape[d+1]; } squeezed_dshape = mxnet::TShape(&squeezed_dshape[0], &squeezed_dshape[squeezed_dshape.ndim()-1]); @@ -2631,7 +2638,7 @@ inline bool SplitOpShape(const nnvm::NodeAttrs& attrs, back_calculate_dshape[real_axis] += (*out_attrs)[i][real_axis]; } } - for (int d = real_axis + 1; d < static_cast(ishape.ndim()); ++d) { + for (int d = real_axis + 1; d < ishape.ndim(); ++d) { if (param.squeeze_axis) { back_calculate_dshape[d] = (*out_attrs)[0][d - 1]; } else { diff --git a/src/operator/tensor/matrix_op.cc b/src/operator/tensor/matrix_op.cc index 3bca330f98b0..18574458f060 100644 --- a/src/operator/tensor/matrix_op.cc +++ b/src/operator/tensor/matrix_op.cc @@ -381,8 +381,8 @@ Examples:: "transpose", n, ograds, {}, std::unordered_map()); } else { - mxnet::TShape axes = mxnet::TShape(param.axes.ndim()); - for (index_t i = 0; i < axes.ndim(); ++i) { + mxnet::TShape axes = mxnet::TShape(param.axes.ndim(), -1); + for (int i = 0; i < axes.ndim(); ++i) { axes[param.axes[i]] = i; } std::ostringstream os; diff --git a/src/operator/tensor/ordering_op-inl.h b/src/operator/tensor/ordering_op-inl.h index 5a95e05ffb65..1dda90104205 100644 --- a/src/operator/tensor/ordering_op-inl.h +++ b/src/operator/tensor/ordering_op-inl.h @@ -149,7 +149,7 @@ inline void ParseTopKParam(const mxnet::TShape& src_shape, const TopKParam& para << src_shape.ndim() << ", found axis=" << *axis; *batch_size = src_shape.Size() / src_shape[*axis]; *element_num = src_shape[*axis]; - if (*axis != static_cast(src_shape.ndim()) - 1) { + if (*axis != src_shape.ndim() - 1) { *do_transpose = true; } } diff --git a/src/operator/tensor/slice-inl.h b/src/operator/tensor/slice-inl.h index 4e94cbeda46c..78a2bd8c7b45 100644 --- a/src/operator/tensor/slice-inl.h +++ b/src/operator/tensor/slice-inl.h @@ -34,15 +34,15 @@ namespace mxnet { namespace op { struct SliceParam : public dmlc::Parameter { - nnvm::Tuple> begin, end; - nnvm::Tuple> step; + mxnet::Tuple> begin, end; + mxnet::Tuple> step; DMLC_DECLARE_PARAMETER(SliceParam) { DMLC_DECLARE_FIELD(begin) .describe("starting indices for the slice operation, supports negative indices."); DMLC_DECLARE_FIELD(end) .describe("ending indices for the slice operation, supports negative indices."); DMLC_DECLARE_FIELD(step) - .set_default(nnvm::Tuple>()) + .set_default(mxnet::Tuple>()) .describe("step for the slice operation, supports negative values."); } bool operator==(const SliceParam& other) const { diff --git a/tests/python/unittest/test_operator.py b/tests/python/unittest/test_operator.py index f96a6aead58c..2bb9596d5572 100644 --- a/tests/python/unittest/test_operator.py +++ b/tests/python/unittest/test_operator.py @@ -2265,7 +2265,7 @@ def test_reshape_new(src_shape, shape_args, reverse, dst_shape): for i in range(len(src_shape)): holdout_src_shape = list(src_shape) - holdout_src_shape[i] = 0 + holdout_src_shape[i] = -1 holdout_src_shape = tuple(holdout_src_shape) net = mx.sym.Variable('data') net = mx.sym.elemwise_add(net.reshape(shape_args, reverse=reverse), mx.sym.ones(shape=dst_shape))