From 5b8730fa3a08e00d2d665d511f969eb78a56b161 Mon Sep 17 00:00:00 2001 From: baoachun <962571062@qq.com> Date: Thu, 6 Jan 2022 04:56:19 +0000 Subject: [PATCH 1/3] refactor the forward implementation of reshape npu op --- paddle/fluid/operators/reshape_op_npu.cc | 94 ++++++++++++++++++++---- 1 file changed, 80 insertions(+), 14 deletions(-) diff --git a/paddle/fluid/operators/reshape_op_npu.cc b/paddle/fluid/operators/reshape_op_npu.cc index d6b1d79f2b1a8..8070162cb5998 100644 --- a/paddle/fluid/operators/reshape_op_npu.cc +++ b/paddle/fluid/operators/reshape_op_npu.cc @@ -17,6 +17,7 @@ limitations under the License. */ #include "paddle/fluid/framework/op_registry.h" #include "paddle/fluid/platform/device/npu/npu_op_runner.h" +#include "paddle/fluid/operators/utils.h" namespace paddle { namespace operators { @@ -25,23 +26,88 @@ template class Reshape2NPUKernel : public framework::OpKernel { public: void Compute(const framework::ExecutionContext& ctx) const override { + auto stream = + ctx.template device_context() + .stream(); + auto place = ctx.GetPlace(); auto* x = ctx.Input("X"); auto* out = ctx.Output("Out"); - auto list_new_shape_tensor = - ctx.MultiInput("ShapeTensor"); - if (list_new_shape_tensor.size() > 0) { - PADDLE_THROW(platform::errors::Unimplemented( - "Input(ShapeTensor) is not supported on NPU.")); + + std::vector target_shape_vector; + auto shape_tensor_vector = ctx.MultiInput("ShapeTensor"); + if (shape_tensor_vector.size() > 0) { + for (auto* shape_tensor : shape_tensor_vector) { + PADDLE_ENFORCE_EQ( + shape_tensor->dims(), framework::make_ddim({1}), + platform::errors::InvalidArgument( + "If the element type of 'shape' in ReshapeOp is Tensor, " + "the element's shape must be [1]. But received the element's shape " + "is [%s]", + shape_tensor->dims())); + + target_shape_vector.push_back(GetDataFromTensor(shape_tensor)[0]); + } + } else { + auto* shape_tensor = ctx.HasInput("Shape") + ? ctx.Input("Shape") + : nullptr; + if (shape_tensor) { + target_shape_vector = GetDataFromTensor(shape_tensor); + } else { + target_shape_vector = ctx.Attr>("shape"); + PADDLE_ENFORCE_GT( + target_shape_vector.size(), 0, + platform::errors::InvalidArgument( + "The length of shape attribute should be larger than 0 when input ShapeTensor and Shape are empty!")); + } } - PADDLE_ENFORCE_EQ(ctx.Input("Shape"), nullptr, - platform::errors::Unimplemented( - "Input(Shape) is not supported on NPU.")); - auto shape = out->dims(); - out->mutable_data(ctx.GetPlace(), x->type()); - framework::TensorCopy( - *x, ctx.GetPlace(), - ctx.template device_context(), out); - out->Resize(shape); + + int num_negative = std::count(target_shape_vector.begin(), target_shape_vector.end(), -1); + PADDLE_ENFORCE_LE(num_negative, 1, + platform::errors::InvalidArgument( + "The max number of -1 in shape attribute is 1 " + "but received %d.", + num_negative)); + auto it_zero = std::find(target_shape_vector.begin(), target_shape_vector.end(), 0); + if (it_zero != target_shape_vector.end()) { + int x_rank = x->dims().size(); + for (size_t i = 0; i < target_shape_vector.size(); i++) { + if (target_shape_vector[i] == 0) { + PADDLE_ENFORCE_LT( + i, x_rank, + platform::errors::InvalidArgument( + "The index of 0 in shape attribute ", + "should be less than input dim size, ", + "but the index is %d and input dim size is %d", i, + x_rank)); + target_shape_vector[i] = x->dims().at(i); + } + } + } + + auto it = std::find(target_shape_vector.begin(), target_shape_vector.end(), -1); + if (it != target_shape_vector.end()) { + auto ddim_out_vec = framework::vectorize(x->dims()); + int ddim_out_product = + std::accumulate(ddim_out_vec.begin(), ddim_out_vec.end(), 1, + std::multiplies()); + int reshape_out_product = std::accumulate( + target_shape_vector.begin(), target_shape_vector.end(), -1, std::multiplies()); + int index = std::distance(target_shape_vector.begin(), it); + target_shape_vector[index] = ddim_out_product / reshape_out_product; + } + + auto out_dims = framework::make_ddim(target_shape_vector); + out->mutable_data(out_dims, place); + + NpuOpRunner runner; + runner.SetType("Reshape") + .AddInput(*x) + .AddInput(std::vector(target_shape_vector)) + .AddOutput(*out) + .AddAttr("axis", 0) + .AddAttr("num_axes", -1); + runner.Run(stream); } }; From 86c37b87fe7678f66a3eb5110cff2dd96cc29ef1 Mon Sep 17 00:00:00 2001 From: baoachun <962571062@qq.com> Date: Thu, 6 Jan 2022 05:08:07 +0000 Subject: [PATCH 2/3] update reshape npu op --- paddle/fluid/operators/reshape_op_npu.cc | 68 +++++++++++++----------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/paddle/fluid/operators/reshape_op_npu.cc b/paddle/fluid/operators/reshape_op_npu.cc index 8070162cb5998..9a66a4ca66ea5 100644 --- a/paddle/fluid/operators/reshape_op_npu.cc +++ b/paddle/fluid/operators/reshape_op_npu.cc @@ -16,8 +16,8 @@ limitations under the License. */ #include #include "paddle/fluid/framework/op_registry.h" -#include "paddle/fluid/platform/device/npu/npu_op_runner.h" #include "paddle/fluid/operators/utils.h" +#include "paddle/fluid/platform/device/npu/npu_op_runner.h" namespace paddle { namespace operators { @@ -38,13 +38,14 @@ class Reshape2NPUKernel : public framework::OpKernel { if (shape_tensor_vector.size() > 0) { for (auto* shape_tensor : shape_tensor_vector) { PADDLE_ENFORCE_EQ( - shape_tensor->dims(), framework::make_ddim({1}), - platform::errors::InvalidArgument( - "If the element type of 'shape' in ReshapeOp is Tensor, " - "the element's shape must be [1]. But received the element's shape " - "is [%s]", - shape_tensor->dims())); - + shape_tensor->dims(), framework::make_ddim({1}), + platform::errors::InvalidArgument( + "If the element type of 'shape' in ReshapeOp is Tensor, " + "the element's shape must be [1]. But received the element's " + "shape " + "is [%d]", + shape_tensor->dims())); + target_shape_vector.push_back(GetDataFromTensor(shape_tensor)[0]); } } else { @@ -56,19 +57,22 @@ class Reshape2NPUKernel : public framework::OpKernel { } else { target_shape_vector = ctx.Attr>("shape"); PADDLE_ENFORCE_GT( - target_shape_vector.size(), 0, - platform::errors::InvalidArgument( - "The length of shape attribute should be larger than 0 when input ShapeTensor and Shape are empty!")); + target_shape_vector.size(), 0, + platform::errors::InvalidArgument( + "The length of shape attribute should be larger than 0 when " + "input ShapeTensor and Shape are empty!")); } } - int num_negative = std::count(target_shape_vector.begin(), target_shape_vector.end(), -1); + int num_negative = + std::count(target_shape_vector.begin(), target_shape_vector.end(), -1); PADDLE_ENFORCE_LE(num_negative, 1, - platform::errors::InvalidArgument( - "The max number of -1 in shape attribute is 1 " - "but received %d.", - num_negative)); - auto it_zero = std::find(target_shape_vector.begin(), target_shape_vector.end(), 0); + platform::errors::InvalidArgument( + "The max number of -1 in shape attribute is 1 " + "but received %d.", + num_negative)); + auto it_zero = + std::find(target_shape_vector.begin(), target_shape_vector.end(), 0); if (it_zero != target_shape_vector.end()) { int x_rank = x->dims().size(); for (size_t i = 0; i < target_shape_vector.size(); i++) { @@ -78,35 +82,35 @@ class Reshape2NPUKernel : public framework::OpKernel { platform::errors::InvalidArgument( "The index of 0 in shape attribute ", "should be less than input dim size, ", - "but the index is %d and input dim size is %d", i, - x_rank)); + "but the index is %d and input dim size is %d", i, x_rank)); target_shape_vector[i] = x->dims().at(i); } } } - auto it = std::find(target_shape_vector.begin(), target_shape_vector.end(), -1); + auto it = + std::find(target_shape_vector.begin(), target_shape_vector.end(), -1); if (it != target_shape_vector.end()) { auto ddim_out_vec = framework::vectorize(x->dims()); - int ddim_out_product = - std::accumulate(ddim_out_vec.begin(), ddim_out_vec.end(), 1, - std::multiplies()); - int reshape_out_product = std::accumulate( - target_shape_vector.begin(), target_shape_vector.end(), -1, std::multiplies()); + int ddim_out_product = std::accumulate( + ddim_out_vec.begin(), ddim_out_vec.end(), 1, std::multiplies()); + int reshape_out_product = std::accumulate(target_shape_vector.begin(), + target_shape_vector.end(), -1, + std::multiplies()); int index = std::distance(target_shape_vector.begin(), it); target_shape_vector[index] = ddim_out_product / reshape_out_product; } - + auto out_dims = framework::make_ddim(target_shape_vector); out->mutable_data(out_dims, place); NpuOpRunner runner; - runner.SetType("Reshape") - .AddInput(*x) - .AddInput(std::vector(target_shape_vector)) - .AddOutput(*out) - .AddAttr("axis", 0) - .AddAttr("num_axes", -1); + runner.SetType("Reshape") + .AddInput(*x) + .AddInput(std::vector(target_shape_vector)) + .AddOutput(*out) + .AddAttr("axis", 0) + .AddAttr("num_axes", -1); runner.Run(stream); } }; From 9189dd85699a18e7969059aa4d11bf01d31da23c Mon Sep 17 00:00:00 2001 From: baoachun <962571062@qq.com> Date: Thu, 6 Jan 2022 07:26:27 +0000 Subject: [PATCH 3/3] update reshape npu op --- paddle/fluid/operators/reshape_op_npu.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/paddle/fluid/operators/reshape_op_npu.cc b/paddle/fluid/operators/reshape_op_npu.cc index 9a66a4ca66ea5..8b6f9d4d48d94 100644 --- a/paddle/fluid/operators/reshape_op_npu.cc +++ b/paddle/fluid/operators/reshape_op_npu.cc @@ -38,13 +38,12 @@ class Reshape2NPUKernel : public framework::OpKernel { if (shape_tensor_vector.size() > 0) { for (auto* shape_tensor : shape_tensor_vector) { PADDLE_ENFORCE_EQ( - shape_tensor->dims(), framework::make_ddim({1}), + shape_tensor->dims().size(), 1, platform::errors::InvalidArgument( - "If the element type of 'shape' in ReshapeOp is Tensor, " + "If the element type of 'shape' in Reshape Op is Tensor, " "the element's shape must be [1]. But received the element's " - "shape " - "is [%d]", - shape_tensor->dims())); + "shape is [%d]", + shape_tensor->dims().size())); target_shape_vector.push_back(GetDataFromTensor(shape_tensor)[0]); } @@ -66,11 +65,12 @@ class Reshape2NPUKernel : public framework::OpKernel { int num_negative = std::count(target_shape_vector.begin(), target_shape_vector.end(), -1); - PADDLE_ENFORCE_LE(num_negative, 1, - platform::errors::InvalidArgument( - "The max number of -1 in shape attribute is 1 " - "but received %d.", - num_negative)); + PADDLE_ENFORCE_LE( + num_negative, 1, + platform::errors::InvalidArgument( + "The max number of -1 in shape attribute or shape tensor is 1 " + "but received %d.", + num_negative)); auto it_zero = std::find(target_shape_vector.begin(), target_shape_vector.end(), 0); if (it_zero != target_shape_vector.end()) { @@ -80,7 +80,7 @@ class Reshape2NPUKernel : public framework::OpKernel { PADDLE_ENFORCE_LT( i, x_rank, platform::errors::InvalidArgument( - "The index of 0 in shape attribute ", + "The index of 0 in shape attribute or shape tensor", "should be less than input dim size, ", "but the index is %d and input dim size is %d", i, x_rank)); target_shape_vector[i] = x->dims().at(i); @@ -105,6 +105,7 @@ class Reshape2NPUKernel : public framework::OpKernel { out->mutable_data(out_dims, place); NpuOpRunner runner; + // the shape input must be on the host side runner.SetType("Reshape") .AddInput(*x) .AddInput(std::vector(target_shape_vector))