Conversation
| AddInput("X", "The input of crop op"); | ||
| AddInput("Y", "The input used as reference for cropping. "); | ||
| AddOutput("Out", "The output of crop op."); | ||
| AddComment(R"DOC( |
There was a problem hiding this comment.
This is a bad documentation, The offsets for cropping contains no information at all. Maybe describe some detail like (not necessary)
- in which scene this Op will be used.
- Input, Output of the Op.
- the detail of this attribute, such as
shaperefers to the sliced tensor shape.
There was a problem hiding this comment.
Thx. I will refine it.
paddle/operators/crop_op.h
Outdated
| typename IndexType = Eigen::DenseIndex> | ||
| using EigenTensor = framework::EigenTensor<T, D, MajorType, IndexType>; | ||
|
|
||
| using Tensor = framework::Tensor; |
There was a problem hiding this comment.
follow the name convention of the google style click here in detail. we should not use any using in the header file.
There was a problem hiding this comment.
In addition, Tensor has no template parameter, Just write
using framework::Tensor;is okay.
paddle/operators/crop_op.cc
Outdated
| protected: | ||
| void InferShape(const framework::InferShapeContext &ctx) const override { | ||
| auto dim0 = ctx.Input<Tensor>("X")->dims(); | ||
| auto Y = ctx.Input<Tensor>("Y"); |
There was a problem hiding this comment.
I can not find the test case contains Y as input. There is only normal one with offset and shape.
Can you give a proper application case that this usage('Y' as input) is necessary? Thx.
paddle/operators/crop_op.cc
Outdated
| "Shape size should be equal to dimention size of input tensor."); | ||
| std::vector<int64_t> tensor_shape(shape.size()); | ||
| for (int i = 0; i < shape.size(); ++i) { | ||
| tensor_shape[i] = (int64_t)shape[i]; |
There was a problem hiding this comment.
we have the interface accept the parameter of vector<int> make_ddim in ddim, do we have to convert its type?
paddle/operators/crop_op.h
Outdated
| typename IndexType = Eigen::DenseIndex> | ||
| using EigenTensor = framework::EigenTensor<T, D, MajorType, IndexType>; | ||
|
|
||
| using Tensor = framework::Tensor; |
There was a problem hiding this comment.
In addition, Tensor has no template parameter, Just write
using framework::Tensor;is okay.
paddle/operators/crop_op.h
Outdated
| auto out_dims = out->dims(); | ||
|
|
||
| auto offsets = context.op().GetAttr<std::vector<int>>("offsets"); | ||
| PADDLE_ENFORCE_EQ( |
There was a problem hiding this comment.
Please move this enforce check into Infershape.
Operator's Infershape will be run before runtime, that's where real config check happens.
… crop_op Conflicts: paddle/pybind/pybind.cc
… crop_op Conflicts: paddle/pybind/pybind.cc python/paddle/v2/framework/tests/op_test_util.py
| using framework::OperatorWithKernel::OperatorWithKernel; | ||
|
|
||
| protected: | ||
| void InferShape(const framework::InferShapeContext &ctx) const override { |
There was a problem hiding this comment.
InferShape里的检查需要全面一些,比如对输入非空的检查: https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/operators/squared_l2_distance_op.cc#L26
paddle/operators/crop_op.cc
Outdated
| for (int i = 0; i < shape.size(); ++i) { | ||
| tensor_shape[i] = (int64_t)shape[i]; | ||
| } | ||
| ctx.Output<Tensor>("Out")->Resize( |
There was a problem hiding this comment.
LoDTensor合入后,InferShape的Output里要使用:Output<framework::LoDTensor>
paddle/operators/crop_op.cc
Outdated
| ctx.Output<Tensor>("Out")->Resize( | ||
| paddle::framework::make_ddim(tensor_shape)); | ||
| } else { | ||
| ctx.Output<Tensor>("Out")->Resize(Y->dims()); |
There was a problem hiding this comment.
LoDTensor合入后,InferShape的Output里要使用:Output<framework::LoDTensor>
paddle/operators/crop_op.cc
Outdated
| PADDLE_ENFORCE_NOT_NULL(ctx.InputVar(framework::GradVarName("Out")), | ||
| "Input(Out@GRAD) should not be null"); | ||
| auto x_dims = ctx.Input<Tensor>("X")->dims(); | ||
| auto *x_grad = ctx.Output<Tensor>(framework::GradVarName("X")); |
There was a problem hiding this comment.
Output使用:Output< framework ::LoDTensor>
paddle/operators/crop_op.h
Outdated
| CropFunction<Place, T, 6>(context); | ||
| break; | ||
| default: | ||
| LOG(ERROR) << "Only ranks up to 6 supported."; |
There was a problem hiding this comment.
报错不要使用GLOG,使用PADDLE_ENFORCE/PADDLE_THROW:
PADDLE_THROW("Tensors with rank at most 6 are supported").
paddle/operators/crop_op.h
Outdated
| CropGradFunction<Place, T, 6>(context); | ||
| break; | ||
| default: | ||
| LOG(ERROR) << "Only ranks up to 6 supported."; |
| self.outputs = {'Out': self.inputs['X'][2:10, 3:11]} | ||
|
|
||
|
|
||
| class TestCropGradOp(GradientChecker): |
|
|
||
| def test_normal(self): | ||
| self.check_grad( | ||
| self.op, self.inputs, set(["X"]), "Out", max_relative_error=0.5) |
There was a problem hiding this comment.
max_relative_error=0.5 太大
… crop_op Conflicts: paddle/pybind/pybind.cc
… crop_op Conflicts: paddle/pybind/pybind.cc
2. Fix unitest
| PADDLE_ENFORCE_NOT_NULL(ctx.InputVar("X"), | ||
| "Input(X) of CropOp should not be null."); | ||
| PADDLE_ENFORCE_NOT_NULL(ctx.OutputVar("Out"), | ||
| "Output(Out) of CropOp should not be null."); |
There was a problem hiding this comment.
Put the check before line 30. 一般先check,再使用,检查正常了,再开始使用。
paddle/operators/crop_op.cc
Outdated
| "Shape size should be equal to dimention size of input tensor."); | ||
| std::vector<int64_t> tensor_shape(shape.size()); | ||
| for (size_t i = 0; i < shape.size(); ++i) { | ||
| tensor_shape[i] = (int64_t)shape[i]; |
There was a problem hiding this comment.
static_cast< int64_t>(shape[i])| "The size of shape list should be as same as " | ||
| "dimension size of input X.") | ||
| .SetDefault(std::vector<int>()); | ||
| } |
There was a problem hiding this comment.
Put the AddComment(R"DOC( )DOC") at last.
paddle/operators/crop_op.cc
Outdated
|
|
||
| X = [[0, 1, 2, 0, 0] | ||
| [0, 3, 4, 0, 0] | ||
| [0, 0, 0, 0, 0]] |
There was a problem hiding this comment.
将来Doc可能转成MarkDown,为了显示效果, line 84 - line 86加缩进吧, line 90, 94,98相同。
paddle/operators/crop_op.cc
Outdated
| T *out_data = out->mutable_data<T>(context.GetPlace()); | ||
| auto x_dims = x->dims(); | ||
| auto out_dims = out->dims(); | ||
| int64_t out_count = framework::product(out_dims); |
There was a problem hiding this comment.
out_count -> out_dims->numel()
paddle/operators/crop_op.cc
Outdated
| public: | ||
| void Compute(const framework::ExecutionContext &context) const override { | ||
| auto *x = context.Input<LoDTensor>("X"); | ||
| auto *out = context.Output<LoDTensor>("Out"); |
There was a problem hiding this comment.
在非sequence operators里的OpKernel里实际可以不使用LoDTensor,用Tensor即可:
paddle/operators/crop_op.cc
Outdated
| std::vector<int64_t> x_shape = framework::vectorize(x_dims); | ||
| std::vector<int64_t> out_shape = framework::vectorize(out_dims); | ||
|
|
||
| auto offsets = context.op().Attr<std::vector<int>>("offsets"); |
There was a problem hiding this comment.
context.op().Attr<> -> context.Attr<>
paddle/operators/crop_op.cu
Outdated
| T* out_data = out->mutable_data<T>(paddle::platform::GPUPlace()); | ||
| auto x_dims = x->dims(); | ||
| auto out_dims = out->dims(); | ||
| int64_t out_count = framework::product(out_dims); |
There was a problem hiding this comment.
use Tensor::numel() instead of framework::product.
paddle/operators/crop_op.cu
Outdated
| cudaMemcpy(x_shape_gpu, x_shape, sizeof(int64_t) * D, cudaMemcpyHostToDevice); | ||
| cudaMalloc((void**)&out_shape_gpu, sizeof(int64_t) * D); | ||
| cudaMemcpy(out_shape_gpu, out_shape, sizeof(int64_t) * D, | ||
| cudaMemcpyHostToDevice); |
There was a problem hiding this comment.
Do not use cudaMalloc and cudaMemcpy, use Tensor's function. Use Tensor as the temp variables.
|
@wanghaoshuang I just push PR #4174, which will make this PR not to use Also, I think maybe |
|
I will give a try and submit a PR to you. |
|
Sorry, I misunderstand what |
|
Please reference #4205. I think Crop and Concat can be abstracted by |
dzhwinter
left a comment
There was a problem hiding this comment.
LGTM++, need to modify the code based on comments slightly.
paddle/operators/crop_op.cc
Outdated
| PADDLE_ENFORCE_NOT_NULL(ctx.OutputVar("Out"), | ||
| "Output(Out) of CropOp should not be null."); | ||
| auto x_dim = ctx.Input<LoDTensor>("X")->dims(); | ||
| auto Y = ctx.Input<LoDTensor>("Y"); |
There was a problem hiding this comment.
if auto keyword is a pointer, please use Y*
paddle/operators/crop_op.cc
Outdated
| PADDLE_ENFORCE_EQ(framework::arity(x_dim), framework::arity(Y->dims()), | ||
| "Tensor rank of both CropOp's " | ||
| "inputs must be same."); | ||
| ctx.Output<LoDTensor>("Out")->Resize(Y->dims()); |
There was a problem hiding this comment.
use ctx.Output<LodTensor> twice, it's better to reuse.
paddle/operators/crop_op.cu
Outdated
| int block = 512; | ||
| int grid = (n * d + block - 1) / block; | ||
|
|
||
| CropKernel< |
There was a problem hiding this comment.
is it re-fold by the pre-commit? The format is strange, maybe it's better to add a new line character in next line.
| @@ -0,0 +1,91 @@ | |||
| import unittest | |||
There was a problem hiding this comment.
好像所有单测都没copyrights。确定需要加上么?
fixed #3905
fixed #3911