@@ -39,12 +39,18 @@ bool ConcatShape(const nnvm::NodeAttrs& attrs,
3939 CHECK_EQ (in_shape->size (), static_cast <size_t >(param_.num_args ));
4040 mxnet::TShape dshape;
4141 dim_t size = 0 ;
42+ int param_dim = param_.dim .has_value () ? param_.dim .value () : 0 ;
4243 bool has_unknown_dim_size = false ;
4344 int axis = -1 ;
45+ if (!param_.dim .has_value ()) {
46+ for (int i = 0 ; i < param_.num_args ; ++i) {
47+ (*in_shape)[i] = Shape1 ((*in_shape)[i].Size ());
48+ }
49+ }
4450 for (int i = 0 ; i < param_.num_args ; ++i) {
4551 mxnet::TShape tmp = (*in_shape)[i];
4652 if (tmp.ndim () > 0 ) {
47- axis = CheckAxis (param_. dim , tmp.ndim ());
53+ axis = CheckAxis (param_dim , tmp.ndim ());
4854 has_unknown_dim_size = !mxnet::dim_size_is_known (tmp, axis) || has_unknown_dim_size;
4955 size += tmp[axis];
5056 tmp[axis] = -1 ;
@@ -54,7 +60,7 @@ bool ConcatShape(const nnvm::NodeAttrs& attrs,
5460
5561 mxnet::TShape tmp = (*out_shape)[0 ];
5662 if (tmp.ndim () > 0 ) {
57- axis = CheckAxis (param_. dim , tmp.ndim ());
63+ axis = CheckAxis (param_dim , tmp.ndim ());
5864 tmp[axis] = -1 ;
5965 shape_assign (&dshape, tmp);
6066 }
@@ -89,11 +95,12 @@ static bool RNNParamConcatShape(const nnvm::NodeAttrs& attrs,
8995 mxnet::TShape dshape;
9096 index_t size = 0 ;
9197 std::vector<int > zero_indices;
92- int axis = -1 ;
98+ int axis = -1 ;
99+ int param_dim = param_.dim .has_value () ? param_.dim .value () : 0 ;
93100 for (int i = 0 ; i < param_.num_args ; ++i) {
94101 mxnet::TShape tmp = (*in_shape)[i];
95102 if (tmp.ndim () > 0 ) {
96- axis = CheckAxis (param_. dim , tmp.ndim ());
103+ axis = CheckAxis (param_dim , tmp.ndim ());
97104 if (!mxnet::dim_size_is_known (tmp, axis)) {
98105 zero_indices.emplace_back (i);
99106 } else {
@@ -107,7 +114,7 @@ static bool RNNParamConcatShape(const nnvm::NodeAttrs& attrs,
107114
108115 mxnet::TShape tmp = (*out_shape)[0 ];
109116 if (tmp.ndim () > 0 ) {
110- axis = CheckAxis (param_. dim , tmp.ndim ());
117+ axis = CheckAxis (param_dim , tmp.ndim ());
111118 tmp[axis] = -1 ;
112119 shape_assign (&dshape, tmp);
113120 }
@@ -193,13 +200,14 @@ inline static bool ConcatForwardInferStorageType(const nnvm::NodeAttrs& attrs,
193200 auto & out_stype = out_attrs->at (0 );
194201 bool dispatched = false ;
195202 const ConcatParam& param = nnvm::get<ConcatParam>(attrs.parsed );
196- if (!dispatched && common::ContainsOnlyStorage (*in_attrs, kCSRStorage ) && param.dim == 0 ) {
203+ int param_dim = param.dim .has_value () ? param.dim .value () : 0 ;
204+ if (!dispatched && common::ContainsOnlyStorage (*in_attrs, kCSRStorage ) && param_dim == 0 ) {
197205 dispatched =
198206 storage_type_assign (&out_stype, kCSRStorage , dispatch_mode, DispatchMode::kFComputeEx );
199207 }
200208#if MXNET_USE_ONEDNN == 1
201209 if (!dispatched && dev_mask == mshadow::cpu::kDevMask &&
202- common::ContainsOnlyStorage (*in_attrs, kDefaultStorage ) && param. dim > 0 ) {
210+ common::ContainsOnlyStorage (*in_attrs, kDefaultStorage )) {
203211 dispatched =
204212 storage_type_assign (&out_stype, kDefaultStorage , dispatch_mode, DispatchMode::kFComputeEx );
205213 }
@@ -225,10 +233,8 @@ inline static bool BackwardConcatStorageType(const nnvm::NodeAttrs& attrs,
225233 std::vector<int >* out_attrs) {
226234 DispatchMode wanted_mode;
227235#if MXNET_USE_ONEDNN == 1
228- const ConcatParam& param = nnvm::get<ConcatParam>(attrs.parsed );
229236 CHECK_EQ (out_attrs->size (), in_attrs->size () - 1 );
230- if (dev_mask == mshadow::cpu::kDevMask &&
231- common::ContainsOnlyStorage (*in_attrs, kDefaultStorage ) && param.dim > 0 )
237+ if (dev_mask == mshadow::cpu::kDevMask && common::ContainsOnlyStorage (*in_attrs, kDefaultStorage ))
232238 wanted_mode = DispatchMode::kFComputeEx ;
233239 else
234240#endif // MXNET_USE_ONEDNN == 1
@@ -251,8 +257,9 @@ bool SupportDNNLConcat(const std::vector<NDArray>& arrs) {
251257 return false ;
252258 int ndim = arr.shape ().ndim ();
253259 const int dnnl_ndims = arr.GetDNNLData ()->get_desc ().data .ndims ;
254- if (! (ndim == 2 || ndim == 4 ) || ndim != dnnl_ndims)
260+ if ((ndim != 2 && ndim != 4 ) || ndim != dnnl_ndims) {
255261 return false ;
262+ }
256263 }
257264 return true ;
258265}
@@ -347,12 +354,14 @@ DMLC_REGISTER_PARAMETER(ConcatParam);
347354NNVM_REGISTER_OP (Concat)
348355MXNET_ADD_SPARSE_OP_ALIAS (concat)
349356 .add_alias (" concat" )
357+ .add_alias (" _npi_concatenate" )
350358 .describe (R"code( Joins input arrays along a given axis.
351359
352360.. note:: `Concat` is deprecated. Use `concat` instead.
353361
354362The dimensions of the input arrays should be the same except the axis along
355- which they will be concatenated.
363+ which they will be concatenated. With dimension parameter ``None`` input
364+ arrays are flattened before concatenating them along axis 0.
356365The dimension of the output array along the concatenated axis will be equal
357366to the sum of the corresponding dimensions of the input arrays.
358367
@@ -376,6 +385,11 @@ Example::
376385 [ 7., 7.],
377386 [ 8., 8.]]
378387
388+ concat(x,y,z,dim=None) = [1., 1., 2., 2.,
389+ 3., 3., 4., 4.,
390+ 5., 5., 6., 6.,
391+ 7., 7., 8., 8.]
392+
379393 Note that you cannot concat x,y,z along dimension 1 since dimension
380394 0 is not the same for all the input arrays.
381395
@@ -397,6 +411,7 @@ Example::
397411 .add_arguments (ConcatParam::__FIELDS__ ());
398412
399413NNVM_REGISTER_OP (_backward_Concat)
414+ .add_alias (" _backward_np_concat" )
400415 .set_num_inputs ([](const NodeAttrs& attrs) {
401416#if MXNET_USE_ONEDNN == 1
402417 const ConcatParam& params = nnvm::get<ConcatParam>(attrs.parsed );
0 commit comments