Skip to content

Commit

Permalink
[2.0 rc1/cherrypick] cherry-pick kunlun PR:29234/29229/29293/29367/29…
Browse files Browse the repository at this point in the history
…280/29448 (#29466)

* add deformable_conv op on xpu (#29234)

* rebase develop

* update deformable_conv op on xpu

* update deformable_conv op on xpu

* update kunlun conv2d/softmax/elementwise implemetation (#29229)

* update conv2d & softmax to new xpu api
* test=kunlun

* remove useless comments
* test=kunlun

* remote softmax xpu op
* test=kunlun

* update kunlun softmax
* test=kunlun

* update xpu unitest
* test=kunlun

* fix elementwise_grad bug for kunlun
*test=kunlun

* support global pooling for kunlun (#29293)

* test=kunlun

* update reduce_sum op on xpu (#29367)

* update reduce_sum op on xpu

* update reduce_sum op on xpu

* support running on xpu

* fix expand/uniform_random && concat/transpose to new api on xpu (#29280)

* fix expand && concat/transpose to new api

* update uniform_random_op

* update xpu_header

* 1. fix elementwise ops'bug 2. fix softmax_with_cross_entropy_op 3. add biliner_interp_op (#29448)

Co-authored-by: root <root@bjhw-sys-rpm0223.bjhw.baidu.com>

Co-authored-by: 卖鱼的哲学 <tangzhiyi11@users.noreply.github.com>
Co-authored-by: QingshuChen <qingshu.chen714@gmail.com>
Co-authored-by: taixiurong <taixiurong@126.com>
Co-authored-by: root <root@bjhw-sys-rpm0223.bjhw.baidu.com>
  • Loading branch information
5 people authored Dec 8, 2020
1 parent 6b9302a commit 6bfc572
Show file tree
Hide file tree
Showing 26 changed files with 1,793 additions and 739 deletions.
2 changes: 1 addition & 1 deletion cmake/external/xpu.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ endif()

INCLUDE(ExternalProject)
SET(XPU_PROJECT "extern_xpu")
SET(XPU_URL "https://baidu-kunlun-public.su.bcebos.com/paddle_depence/xpu_2020_11_10.tar.gz" CACHE STRING "" FORCE)
SET(XPU_URL "https://baidu-kunlun-public.su.bcebos.com/paddle_depence/xpu_2020_12_04.tar.gz" CACHE STRING "" FORCE)
SET(XPU_SOURCE_DIR "${THIRD_PARTY_PATH}/xpu")
SET(XPU_DOWNLOAD_DIR "${XPU_SOURCE_DIR}/src/${XPU_PROJECT}")
SET(XPU_INSTALL_DIR "${THIRD_PARTY_PATH}/install/xpu")
Expand Down
127 changes: 72 additions & 55 deletions paddle/fluid/operators/concat_op_xpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,12 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#ifdef PADDLE_WITH_XPU
#include "paddle/fluid/operators/concat_op.h"

#include <memory>
#include <string>
#include <vector>

#ifdef PADDLE_WITH_MKLDNN
#include <paddle/fluid/platform/mkldnn_helper.h>
#endif

#ifdef PADDLE_WITH_XPU
#include "paddle/fluid/platform/xpu_header.h"

namespace paddle {
namespace operators {
Expand All @@ -32,8 +26,8 @@ template <typename DeviceContext, typename T>
class ConcatXPUKernel : public framework::OpKernel<T> {
public:
void Compute(const framework::ExecutionContext& ctx) const override {
auto ins = ctx.MultiInput<framework::Tensor>("X");
framework::Tensor* out = ctx.Output<framework::Tensor>("Out");
auto ins = ctx.MultiInput<framework::LoDTensor>("X");
framework::LoDTensor* out = ctx.Output<framework::LoDTensor>("Out");
int axis = ctx.Attr<int>("axis");
PADDLE_ENFORCE_NE(ins[0], nullptr, platform::errors::InvalidArgument(
"The input should not be null."));
Expand All @@ -47,6 +41,7 @@ class ConcatXPUKernel : public framework::OpKernel<T> {
PADDLE_ENFORCE_LT(axis, ins[0]->dims().size(),
platform::errors::InvalidArgument(
"concat: axis shoud < ins[0]->dims()!"));

auto place = ctx.GetPlace();
out->mutable_data<T>(place);
std::vector<int> choose_idx;
Expand All @@ -57,43 +52,54 @@ class ConcatXPUKernel : public framework::OpKernel<T> {
n++;
}
}
PADDLE_ENFORCE_LE(n, 8, platform::errors::InvalidArgument(
"XPU only surpport at most 8 tensors for now"));
PADDLE_ENFORCE_GT(
n, 0, platform::errors::InvalidArgument("No tensor need concat?"));
int h = 1;
int w_except_axis = 1;
for (int i = 0; i < axis; ++i) {
h *= (ins[choose_idx[0]]->dims())[i];
}
for (int i = axis + 1; i < ins[0]->dims().size(); ++i) {
w_except_axis *= (ins[choose_idx[0]]->dims())[i];
}
for (int i = 1; i < n; ++i) {
int hh = 1;
int ww = 1;
for (int j = 0; j < axis; ++j) {
hh *= (ins[choose_idx[i]]->dims())[j];

// If axis is 0, the lod of the output is not the same as inputs.
if (axis == 0 && ins[0]->lod().size() > 0) {
size_t lod_size_0 = ins[0]->lod().size();
size_t lod_size = lod_size_0;
for (size_t i = 1; i < ins.size(); ++i) {
if (ins[i]->lod().size() > 0) {
PADDLE_ENFORCE_EQ(
ins[i]->lod().size(), lod_size_0,
platform::errors::Unimplemented(
"The lod level of all input LoDTensors should be same. "
"Maybe different lod level of input LoDTensors can concat,"
"it is not supported currently. The lod level of %dth input "
"is %d and first input is %d.",
i, ins[i]->lod().size(), lod_size_0));
} else {
lod_size = 0;
break;
}
}
for (int j = axis + 1; j < ins[i]->dims().size(); ++j) {
ww *= (ins[choose_idx[i]]->dims())[j];
if (lod_size) {
auto* out_lod = out->mutable_lod();
for (size_t i = 1; i < ins.size(); ++i) {
auto in_lod = ConvertToLengthBasedLoD(ins[i]->lod());
AppendLoD(out_lod, in_lod);
}
}
PADDLE_ENFORCE_EQ(hh, h, platform::errors::InvalidArgument(
"concat: h should be eual!"));
PADDLE_ENFORCE_EQ(ww, w_except_axis,
platform::errors::InvalidArgument(
"concat: w should be eual except for axis!"));
}

auto input_dims = ins[0]->dims();
std::vector<std::vector<int>> xdims_list(n);
for (int i = 0; i < n; ++i) {
std::vector<int> tmp_dims(input_dims.size());
for (int j = 0; j < input_dims.size(); ++j) {
tmp_dims[j] = ins[i]->dims()[j];
}
xdims_list[i] = tmp_dims;
}

auto& dev_ctx = ctx.template device_context<DeviceContext>();
std::unique_ptr<int[]> in_w_host(new int[n]);
std::unique_ptr<const float* []> ptrs(new const float*[n]);
std::vector<const T*> ptrs;
for (int i = 0; i < n; ++i) {
ptrs[i] = ins[choose_idx[i]]->data<T>();
in_w_host[i] = w_except_axis * (ins[choose_idx[i]]->dims())[axis];
ptrs.push_back(ins[choose_idx[i]]->data<T>());
}
int r =
xpu::concat<float>(dev_ctx.x_context(), h, (const int*)in_w_host.get(),
n, (const float**)ptrs.get(), out->data<T>());
int r = xpu::concat<T>(dev_ctx.x_context(), ptrs, out->data<T>(),
xdims_list, axis);
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External(
Expand All @@ -102,6 +108,7 @@ class ConcatXPUKernel : public framework::OpKernel<T> {
r));
}
};

template <typename DeviceContext, typename T>
class ConcatGradXPUKernel : public framework::OpKernel<T> {
public:
Expand Down Expand Up @@ -132,37 +139,47 @@ class ConcatGradXPUKernel : public framework::OpKernel<T> {
static_cast<int64_t>(ins[0]->dims().size()));
// get output tensor that the name is not kEmptyVarName
std::vector<framework::Tensor*> outputs;
std::vector<int> choose_idx;
int n = 0;
for (size_t j = 0; j < outs.size(); ++j) {
if (out_var_names[j] != framework::kEmptyVarName &&
outs[j]->numel() != 0UL) {
outs[j]->mutable_data<T>(ctx.GetPlace());
outputs.push_back(outs[j]);
} else {
outputs.push_back(nullptr);
choose_idx.push_back(j);
n++;
}
}
PADDLE_ENFORCE_GE(axis, 0, platform::errors::InvalidArgument(
"concat_grad: axis shoud >= 0!"));
PADDLE_ENFORCE_LT(axis, out_grad->dims().size(),
platform::errors::InvalidArgument(
"concat_grad: axis shoud < ins[0]->dims()!"));
auto out_grad_stride = framework::stride_numel(out_grad->dims());
int n = outputs.size();
PADDLE_ENFORCE_LE(n, 16,
platform::errors::InvalidArgument(
"XPU only surpport at most 16 tensors for now"));
int h = out_grad_stride[0] / out_grad_stride[axis];
auto& dev_ctx = ctx.template device_context<DeviceContext>();
std::unique_ptr<int[]> in_w_host(new int[n]);
std::unique_ptr<float* []> ptrs(new float*[n]);

auto input_dims = ins[0]->dims();
std::vector<int> split_list(n);
std::vector<int> xdims_list(input_dims.size());
int total_length = 0;
for (int i = 0; i < n; ++i) {
split_list[i] = ins[i]->dims()[axis];
total_length += ins[i]->dims()[axis];
}
for (int i = 0; i < input_dims.size(); ++i) {
if (i == axis) {
continue;
}
xdims_list[i] = input_dims[i];
}
xdims_list[axis] = total_length;

std::vector<T*> ptrs(n);
for (int i = 0; i < n; ++i) {
auto out_stride = framework::stride_numel(outputs[i]->dims());
ptrs[i] = outputs[i]->data<T>();
in_w_host[i] = out_stride[axis];
}
int r = xpu::concat_grad(dev_ctx.x_context(), h, in_w_host.get(), n,
reinterpret_cast<float**>(ptrs.get()),
out_grad->data<T>());

auto& dev_ctx = ctx.template device_context<DeviceContext>();
int r = xpu::split<T>(dev_ctx.x_context(), out_grad->data<T>(), ptrs,
xdims_list, split_list, axis);
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External(
Expand Down
125 changes: 27 additions & 98 deletions paddle/fluid/operators/conv_op_xpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ class GemmConvXPUKernel : public framework::OpKernel<T> {
// that avoids modifying the variable in the Scope.
Tensor filter = *context.Input<Tensor>("Filter");
Tensor* output = context.Output<Tensor>("Output");
// Tensor* max_input = context.Output<Tensor>("MaxInput");
// Tensor* max_filter = context.Output<Tensor>("MaxFilter");
// max_input->mutable_data<T>(context.GetPlace());
// max_filter->mutable_data<T>(context.GetPlace());
output->mutable_data<T>(context.GetPlace());
int groups = context.Attr<int>("groups");
std::vector<int> strides = context.Attr<std::vector<int>>("strides");
Expand All @@ -43,62 +39,25 @@ class GemmConvXPUKernel : public framework::OpKernel<T> {
const int f = static_cast<int>(filter.dims()[0]);
const int win_h = static_cast<int>(filter.dims()[2]);
const int win_w = static_cast<int>(filter.dims()[3]);
PADDLE_ENFORCE_EQ(
dilations[0] == 1 && dilations[1] == 1, true,
platform::errors::InvalidArgument("XPU only support dilation == 1."));
auto& dev_ctx = context.template device_context<DeviceContext>();
// PADDLE_ENFORCE_EQ(
// xpu::findmax(dev_ctx.x_context(), input->data<T>(), input->numel(),
// max_input->data<T>()) == xpu::Error_t::SUCCESS,
// true, platform::errors::InvalidArgument(
// "XPU conv kernel error,can not finde max_input,please "
// "check whether Baidu Kunlun "
// "Card is properly installed."));
// PADDLE_ENFORCE_EQ(
// xpu::findmax(dev_ctx.x_context(), filter.data<T>(), filter.numel(),
// max_filter->data<T>()) == xpu::Error_t::SUCCESS,
// true, platform::errors::InvalidArgument(
// "XPU conv kernel error,can not find max_filter,please "
// "check whether Baidu Kunlun "
// "Card is properly installed."));
if (groups == 1) {
int r = xpu::conv2d_forward_int16<float, float, float, float>(
dev_ctx.x_context(), batch_size, img_c, img_h, img_w, f, win_h, win_w,
strides[0], strides[1], paddings[0], paddings[1], dilations[0],
dilations[1], groups, input->data<float>(), filter.data<float>(),
output->data<float>(), nullptr, nullptr, xpu::Activation_t::LINEAR,
nullptr, nullptr);
// max_input->data<float>(), max_filter->data<float>());
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External("XPU conv kernel return wrong value[%d], "
"please check whether Baidu Kunlun Card "
"is properly installed.",
r));
} else {
int r = xpu::conv2d_int16_with_group<float, float, float>(
dev_ctx.x_context(), input->data<float>(), filter.data<float>(),
output->data<float>(), batch_size, img_c, img_h, img_w, f, win_h,
win_w, groups, strides[0], strides[1], paddings[0], paddings[1],
nullptr, nullptr);
// max_input->data<float>(), max_filter->data<float>());
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External("XPU conv kernel return wrong value[%d], "
"please check whether Baidu Kunlun Card "
"is properly installed.",
r));
}
std::vector<int> k_size;
k_size.push_back(win_h);
k_size.push_back(win_w);
int r = xpu::conv2d<float, float, float, int16_t>(
dev_ctx.x_context(), input->data<float>(), filter.data<float>(),
output->data<float>(), batch_size, img_c, img_h, img_w, f, k_size,
strides, paddings, dilations, groups, nullptr, nullptr, nullptr, true);
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External("XPU conv kernel return wrong value[%d %s]",
r, XPUAPIErrorMsg[r]));
}
};
template <typename DeviceContext, typename T>
class GemmConvGradXPUKernel : public framework::OpKernel<T> {
public:
void Compute(const framework::ExecutionContext& context) const override {
const Tensor* input = context.Input<Tensor>("Input");
// const Tensor* max_input = context.Input<Tensor>("MaxInput");
// const Tensor* max_filter = context.Input<Tensor>("MaxFilter");
// Tensor* max_output_grad = context.Output<Tensor>("MaxOutputGrad");
const Tensor* output_grad =
context.Input<Tensor>(framework::GradVarName("Output"));
Tensor* input_grad =
Expand All @@ -115,11 +74,6 @@ class GemmConvGradXPUKernel : public framework::OpKernel<T> {
std::vector<int> paddings = context.Attr<std::vector<int>>("paddings");
std::vector<int> dilations = context.Attr<std::vector<int>>("dilations");
const int batch_size = static_cast<int>(input->dims()[0]);
PADDLE_ENFORCE_EQ(groups == 1, true, platform::errors::InvalidArgument(
"XPU only support groups == 1."));
PADDLE_ENFORCE_EQ(
dilations[0] == 1 && dilations[1] == 1, true,
platform::errors::InvalidArgument("XPU only support dilation == 1."));
const int img_c = static_cast<int>(input->dims()[1]);
const int img_h = static_cast<int>(input->dims()[2]);
const int img_w = static_cast<int>(input->dims()[3]);
Expand All @@ -133,52 +87,24 @@ class GemmConvGradXPUKernel : public framework::OpKernel<T> {
filter_grad->mutable_data<T>(context.GetPlace());
}
auto& dev_ctx = context.template device_context<DeviceContext>();
// max_output_grad->Resize({4});
// max_output_grad->mutable_data<T>(context.GetPlace());
// PADDLE_ENFORCE_EQ(
// xpu::findmax(dev_ctx.x_context(), output_grad->data<T>(),
// output_grad->numel(),
// max_output_grad->data<T>()) == xpu::Error_t::SUCCESS,
// true,
// platform::errors::External(
// "XPU conv kernel error, can not find max_output_grad, please
// check "
// "whether Baidu Kunlun Card is "
// "properly installed."));
if (input_grad) {
int r = xpu::conv2d_backward_int16(
dev_ctx.x_context(), batch_size, img_c, img_h, img_w, f, win_h, win_w,
strides[0], strides[1], paddings[0], paddings[1], dilations[0],
dilations[1], groups, output_grad->data<float>(),
filter.data<float>(), input_grad->data<float>(), nullptr, nullptr);
// max_output_grad->data<float>(), max_filter->data<float>());
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External("XPU conv kernel return wrong value[%d], "
"please check whether Baidu Kunlun Card "
"is properly installed.",
r));
}
if (filter_grad) {
int r = xpu::conv2d_backward_weight_int16(
dev_ctx.x_context(), batch_size, img_c, img_h, img_w, f, win_h, win_w,
strides[0], strides[1], paddings[0], paddings[1], dilations[0],
dilations[1], groups, output_grad->data<float>(),
input->data<float>(), filter_grad->data<float>(), nullptr, nullptr);
// max_output_grad->data<float>(), max_input->data<float>());
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External("XPU conv kernel return wrong value[%d], "
"please check whether Baidu Kunlun Card "
"is properly installed.",
r));
}
std::vector<int> k_size;
k_size.push_back(win_h);
k_size.push_back(win_w);
int r = xpu::conv2d_grad<float, float, float, int16_t>(
dev_ctx.x_context(), input->data<T>(), filter.data<T>(),
output_grad->data<T>(), input_grad ? input_grad->data<T>() : nullptr,
filter_grad ? filter_grad->data<T>() : nullptr, batch_size, img_c,
img_h, img_w, f, k_size, strides, paddings, dilations, groups, nullptr,
nullptr, nullptr, nullptr, nullptr, true);
PADDLE_ENFORCE_EQ(
r, XPU_SUCCESS,
platform::errors::External("XPU conv kernel return wrong value[%d %s]",
r, XPUAPIErrorMsg[r]));
}
};
} // namespace operators
} // namespace paddle
namespace ops = paddle::operators;
// TODO(xingzhaolong): neon kernel for mobile
REGISTER_OP_XPU_KERNEL(
depthwise_conv2d,
ops::GemmConvXPUKernel<paddle::platform::XPUDeviceContext, float>);
Expand All @@ -187,4 +113,7 @@ REGISTER_OP_XPU_KERNEL(
REGISTER_OP_XPU_KERNEL(
conv2d_grad,
ops::GemmConvGradXPUKernel<paddle::platform::XPUDeviceContext, float>);
REGISTER_OP_XPU_KERNEL(
depthwise_conv2d_grad,
ops::GemmConvGradXPUKernel<paddle::platform::XPUDeviceContext, float>);
#endif
Loading

0 comments on commit 6bfc572

Please sign in to comment.