[MXNET-382] Shape and Size Operator#10889
Conversation
| [](const NodeAttrs& attrs) { return std::vector<uint32_t>(1, 1); }) | ||
| .set_attr<FCompute>("FCompute<cpu>", ShapeCompute<cpu>) | ||
| .set_attr<nnvm::FInferShape>("FInferShape", | ||
| [](const nnvm::NodeAttrs& attrs, |
There was a problem hiding this comment.
yes, the CI failed due to cpplint. I will fix it.
| TYPE_ASSIGN_CHECK(*out_attrs, 0, 0U); | ||
| return out_attrs->at(0) != -1; | ||
| }) | ||
| .set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes) |
There was a problem hiding this comment.
Shouldn't there be no appropriate gradient definition for this?
There was a problem hiding this comment.
no, shape and size operator will not have gradients right?
There was a problem hiding this comment.
Right, I'm asking the same thing. Why did you define FGradient attribute for the op?
|
|
||
| template<typename xpu> | ||
| void ShapeCompute(const nnvm::NodeAttrs& attrs, | ||
| const OpContext& ctx, |
| TShape in_shape = in_data.shape_; | ||
| MSHADOW_TYPE_SWITCH(out_data.type_flag_, DType, { | ||
| mxnet_op::Kernel<mshadow_op::identity_with_cast, xpu>::Launch( | ||
| s, in_data.ndim(), out_data.dptr<DType>(), in_shape.data()); |
There was a problem hiding this comment.
Why DType for out_data? Isn't that int64 as in the description?
There was a problem hiding this comment.
yes, i will make this change.
| const TBlob& in_data = inputs[0]; | ||
| const TBlob& out_data = outputs[0]; | ||
| mshadow::Stream<xpu> *s = ctx.get_stream<xpu>(); | ||
| TShape in_shape = in_data.shape_; |
| .describe("Returns a 1D int64 array containing the shape of data.") | ||
| .set_num_inputs(1) | ||
| .set_num_outputs(1) | ||
| .set_attr<nnvm::FInplaceIdentity>("FInplaceIdentity", |
| TShape target_shape(1); | ||
| target_shape[0] = in_attrs->at(0).ndim(); | ||
| SHAPE_ASSIGN_CHECK(*out_attrs, 0, target_shape); | ||
| return out_attrs->at(0).ndim() != 0U && out_attrs->at(0).Size() != 0U; |
There was a problem hiding this comment.
use shape_is_none(out_attrs->at(0)
There was a problem hiding this comment.
you suggest that I define a shape_is_none function and use it here?
| std::vector<int>* out_attrs) { | ||
| CHECK_EQ(in_attrs->size(), 1U); | ||
| CHECK_EQ(out_attrs->size(), 1U); | ||
| TYPE_ASSIGN_CHECK(*out_attrs, 0, 0U); |
There was a problem hiding this comment.
Use type enum variable name.
There was a problem hiding this comment.
okay, i will use mshadow::kInt64
| NNVM_REGISTER_OP(reshape_like) | ||
| .set_attr<FCompute>("FCompute<gpu>", UnaryOp::IdentityCompute<gpu>); | ||
|
|
||
| NNVM_REGISTER_OP(shape) |
There was a problem hiding this comment.
Where does the name come from? This looks confusing and conflicts with the property name shape of NDArray in Python. Need to ensure the documentation can be rendered correctly.
There was a problem hiding this comment.
what do you suggest the name of the operator should be? This is more or less the name used in a couple of other frameworks too.
There was a problem hiding this comment.
Please make sure the doc page can be rendered correctly at least.
|
the shape operator doesn't have backward. my biggest concern is that any computation that uses this operator can't perform a backward computation. |
| }); | ||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
Please get rid of one blank line here, c++ use only 1 blank line between functions
| .add_argument("rhs", "NDArray-or-Symbol", "Second input."); | ||
|
|
||
| NNVM_REGISTER_OP(shape) | ||
| .describe("Returns a 1D int64 array containing the shape of data.") |
There was a problem hiding this comment.
Would it be clearer if you add an example here?
|
That's great. Keras and Tensorflow both have this op. |
|
The name shape_op and size_op looks adhoc |
|
@piiswrong shape and size are already existing ndarray operations. I changed the names to prevent confusion. Some of the other names that come to mind are - shape_operator, tensor_shape, array_shape. |
|
How about |
| SHAPE_ASSIGN_CHECK(*out_attrs, 0, target_shape); | ||
| return !shape_is_none(out_attrs->at(0)); | ||
| }) | ||
| .set_attr<nnvm::FInferType>("FInferType", |
There was a problem hiding this comment.
not registering FGradient ?
There was a problem hiding this comment.
Shape operator does not have a differential. Check the conversation here - #10789 (comment)
| CHECK_EQ(req.size(), 1U); | ||
| const TBlob& in_data = inputs[0]; | ||
| const TBlob& out_data = outputs[0]; | ||
| out_data.dptr<int64_t>()[0] = in_data.Size(); |
There was a problem hiding this comment.
out_data holds a pointer to gpu memory. you need to explicitly use kernel launch to set the value
There was a problem hiding this comment.
If I use kernel launch then I will need a databuffer pointing to in_data.Size(). How would I get that? because in_data.Size() is of type index_t which does not have data or dptr attribute.
There was a problem hiding this comment.
You know the output size is only 1, so you can just use 1 for that.
There was a problem hiding this comment.
mxnet_op::Kernel<mshadow_op::identity_with_cast, xpu>::Launch(s, 1U, out_data.dptr<int64_t>(), < what goes here? - in_data.Size()?? >);
|
Ping for another round of reviews. |
|
If we have a symbol A with 4 dims, and how can I get the 1-dim size of shape_nd(A) result? |
|
|
||
| struct size_kernel { | ||
| MSHADOW_XINLINE static void Map(int i, int64_t *out, unsigned int in) { | ||
| out[0] = int64_t(in); |
There was a problem hiding this comment.
nit: static_cast<int64_t>
| const TShape& in_shape = in_data.shape_; | ||
| MSHADOW_TYPE_SWITCH(out_data.type_flag_, DType, { | ||
| mxnet_op::Kernel<mshadow_op::identity_with_cast, xpu>::Launch( | ||
| s, in_data.ndim(), out_data.dptr<int64_t>(), in_shape.data()); |
There was a problem hiding this comment.
in_shape.data is a pointer in cpu memory which cannot be directly accessed on gpu. You can use Shape<ndim> instead.
There was a problem hiding this comment.
how come this is not captured by CI?
There was a problem hiding this comment.
it did, the CI failed for GPU tests. I need to fix it.
|
shape_nd still sounds weird as it's also available in symbol. BTW I think these operators can be useful but they won't solve the issue #10789 |
| } | ||
|
|
||
| MSHADOW_TYPE_SWITCH(out_data.type_flag_, DType, { | ||
| mxnet_op::Kernel<mshadow_op::shape_kernel, gpu>::Launch( |
There was a problem hiding this comment.
Same as above, it's simply copying a tiny amount of data from a cpu array to a gpu array. Launching kernel is expensive and a waste of resources. You can just call cudaMemcpyAsync to alleviate the workload.
| const TBlob& out_data = outputs[0]; | ||
| mshadow::Stream<gpu> *s = ctx.get_stream<gpu>(); | ||
| const TShape& in_shape = in_data.shape_; | ||
| Shape<10> temp_shape; |
There was a problem hiding this comment.
What if ndim is greater than 10?
Actually I agree with reminisce, you should use cudamemcopy here so that you don't need this magic number
There was a problem hiding this comment.
okay, i will fix it.
|
@reminisce @piiswrong ping for review. |
| template<typename DTypeIn, typename DTypeOut> | ||
| MSHADOW_XINLINE static void Map(int i, DTypeOut *out, DTypeIn *in) { | ||
| out[i] = DTypeOut(in[i]); | ||
| DTypeIn in_data = in[i]; |
There was a problem hiding this comment.
What's the purpose of this change?
| } | ||
|
|
||
| template<typename xpu> | ||
| void ShapeCompute(const nnvm::NodeAttrs& attrs, |
There was a problem hiding this comment.
You don't need to make templates for shape and size functions based on the type of device. CPU and GPU FCompute functions are defined respectively in .cc and .cu and don't share anything.
|
@haojin2 @piiswrong can this be merged? |
| .add_argument("rhs", "NDArray-or-Symbol", "Second input."); | ||
|
|
||
| void ShapeComputeCPU(const nnvm::NodeAttrs& attrs, | ||
| const OpContext& ctx, |
There was a problem hiding this comment.
nit: alignments of all ComputeXPU functions
|
@piiswrong @reminisce please merge this. |
* Shape Operator * cuda * size op * lint issues * docs example * add docs, change op name to avoid conflict, add convenience confluent method * change name to _nd * fix test cases, add new kernel * test name fix. * solve gpu memory problem for size and shape * get rid of FIgnoreInputs attr of shape_nd * op name change * fix * retrigger CI * retrigger CI * retrigger CI * trigger CI * fix comments * cpplint * nit * trigger CI
Description
Shape and Size Operator. Pre-requisite for this issue - #10789
Checklist
Essentials
Please feel free to remove inapplicable items for your PR.
Changes
@haojin2 @eric-haibin-lin @zheng-da