提交 2c37ad7e 编写于 作者: X xutianbing

combine data/weight to ContextProjectionBackward for clean code

上级 f23a1170
...@@ -127,13 +127,14 @@ private: ...@@ -127,13 +127,14 @@ private:
template <> template <>
void ContextProjectionBackward<DEVICE_TYPE_CPU>(Tensor& out_grad, void ContextProjectionBackward<DEVICE_TYPE_CPU>(Tensor& out_grad,
const Tensor& in_grad, Tensor& in_grad,
const Tensor& w_grad, Tensor& w_grad,
const Tensor& sequence, const Tensor& sequence,
size_t context_length, size_t context_length,
int context_start, int context_start,
size_t begin_pad, size_t begin_pad,
bool is_padding) { bool is_padding,
size_t total_pad) {
CHECK(out_grad.getData() && sequence.getData()); CHECK(out_grad.getData() && sequence.getData());
CHECK_EQ(out_grad.dims_.size(), 2); CHECK_EQ(out_grad.dims_.size(), 2);
CHECK_EQ(in_grad.dims_.size(), 2); CHECK_EQ(in_grad.dims_.size(), 2);
...@@ -202,8 +203,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(Tensor& out_grad, ...@@ -202,8 +203,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(Tensor& out_grad,
} }
/** /**
* \param inputs[0] input value. * \param inputs[0] input grad.
* \param inputs[1] input weight. * \param inputs[1] weight grad.
* \param inputs[2] input sequence. * \param inputs[2] input sequence.
* \param outputs[0] output value. * \param outputs[0] output value.
*/ */
...@@ -215,6 +216,7 @@ public: ...@@ -215,6 +216,7 @@ public:
context_start_ = config.get<int>("context_start"); context_start_ = config.get<int>("context_start");
begin_pad_ = config.get<size_t>("begin_pad"); begin_pad_ = config.get<size_t>("begin_pad");
is_padding_ = config.get<bool>("is_padding"); is_padding_ = config.get<bool>("is_padding");
total_pad_ = config.get<size_t>("total_pad");
} }
void calc(const Arguments& inputs, void calc(const Arguments& inputs,
...@@ -225,13 +227,14 @@ public: ...@@ -225,13 +227,14 @@ public:
CHECK_EQ(0, inouts.size()); CHECK_EQ(0, inouts.size());
ContextProjectionBackward<Device>((Tensor&)outputs[0], ContextProjectionBackward<Device>((Tensor&)outputs[0],
inputs[0], (Tensor&)inputs[0],
inputs[1], (Tensor&)inputs[1],
inputs[2], inputs[2],
context_length_, context_length_,
context_start_, context_start_,
begin_pad_, begin_pad_,
is_padding_); is_padding_,
total_pad_);
} }
private: private:
...@@ -239,6 +242,7 @@ private: ...@@ -239,6 +242,7 @@ private:
int context_start_; int context_start_;
size_t begin_pad_; size_t begin_pad_;
bool is_padding_; bool is_padding_;
size_t total_pad_;
}; };
/** /**
...@@ -321,6 +325,9 @@ REGISTER_TYPED_FUNC(ContextProjectionBackward, ...@@ -321,6 +325,9 @@ REGISTER_TYPED_FUNC(ContextProjectionBackward,
REGISTER_TYPED_FUNC(ContextProjectionForward, REGISTER_TYPED_FUNC(ContextProjectionForward,
GPU, GPU,
ContextProjectionForwardFunc); ContextProjectionForwardFunc);
REGISTER_TYPED_FUNC(ContextProjectionBackward,
GPU,
ContextProjectionBackwardFunc);
REGISTER_TYPED_FUNC(ContextProjectionBackwardData, REGISTER_TYPED_FUNC(ContextProjectionBackwardData,
GPU, GPU,
ContextProjectionBackwardDataFunc); ContextProjectionBackwardDataFunc);
......
...@@ -56,13 +56,14 @@ void ContextProjectionForward(Tensor& output, ...@@ -56,13 +56,14 @@ void ContextProjectionForward(Tensor& output,
*/ */
template <DeviceType Device> template <DeviceType Device>
void ContextProjectionBackward(Tensor& out_grad, void ContextProjectionBackward(Tensor& out_grad,
const Tensor& in_grad, Tensor& in_grad,
const Tensor& w_grad, Tensor& w_grad,
const Tensor& sequence, const Tensor& sequence,
size_t context_length, size_t context_length,
int context_start, int context_start,
size_t begin_pad, size_t begin_pad,
bool is_padding); bool is_padding,
size_t total_pad);
template <DeviceType Device> template <DeviceType Device>
void ContextProjectionBackwardData(Tensor& out_grad, void ContextProjectionBackwardData(Tensor& out_grad,
......
...@@ -344,4 +344,32 @@ void ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>(Tensor& out_grad, ...@@ -344,4 +344,32 @@ void ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>(Tensor& out_grad,
begin_pad); begin_pad);
} }
template <>
void ContextProjectionBackward<DEVICE_TYPE_GPU>(Tensor& out_grad,
Tensor& in_grad,
Tensor& w_grad,
const Tensor& sequence,
size_t context_length,
int context_start,
size_t begin_pad,
bool is_padding,
size_t total_pad) {
if (in_grad.getData()) {
ContextProjectionBackwardData<DEVICE_TYPE_GPU>(out_grad,
in_grad,
sequence,
context_length,
context_start);
}
if (is_padding && w_grad.getData()) {
ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>(out_grad,
w_grad,
sequence,
context_length,
context_start,
total_pad,
begin_pad);
}
}
} // namespace paddle } // namespace paddle
...@@ -86,33 +86,13 @@ void testMatrixProjectionBackward(int context_start, ...@@ -86,33 +86,13 @@ void testMatrixProjectionBackward(int context_start,
std::max(0, (int)(context_start + context_length - 1)); std::max(0, (int)(context_start + context_length - 1));
if (pad == 0) is_padding = false; if (pad == 0) is_padding = false;
std::shared_ptr<FunctionBase> cpu_func( FunctionCompare compare("ContextProjectionBackward",
FunctionBase::funcRegistrar_.createByType( FuncConfig()
"ContextProjectionBackward-CPU")); .set("context_length", context_length)
FuncConfig cpu_config; .set("context_start", context_start)
cpu_config.set("context_length", context_length) .set("begin_pad", std::max(0, -context_start))
.set("context_start", context_start) .set("is_padding", is_padding)
.set("begin_pad", std::max(0, -context_start)) .set("total_pad", pad));
.set("is_padding", is_padding);
cpu_func->init(cpu_config);
std::shared_ptr<FunctionBase> gpu_data_func(
FunctionBase::funcRegistrar_.createByType(
"ContextProjectionBackwardData-GPU"));
FuncConfig gpu_data_config;
gpu_data_config.set("context_length", context_length)
.set("context_start", context_start);
gpu_data_func->init(gpu_data_config);
std::shared_ptr<FunctionBase> gpu_w_func(
FunctionBase::funcRegistrar_.createByType(
"ContextProjectionBackwardWeight-GPU"));
FuncConfig gpu_w_config;
gpu_w_config.set("context_length", context_length)
.set("context_start", context_start)
.set("begin_pad", std::max(0, -context_start))
.set("total_pad", pad);
gpu_w_func->init(gpu_w_config);
CpuMatrix cpu_in_grad(batch_size, input_dim); CpuMatrix cpu_in_grad(batch_size, input_dim);
cpu_in_grad.randomizeUniform(); cpu_in_grad.randomizeUniform();
...@@ -138,32 +118,26 @@ void testMatrixProjectionBackward(int context_start, ...@@ -138,32 +118,26 @@ void testMatrixProjectionBackward(int context_start,
gpu_w_grad->copyFrom(*cpu_w_grad); gpu_w_grad->copyFrom(*cpu_w_grad);
} }
cpu_func->calc({Tensor(cpu_in_grad.getData(), Dims{batch_size, input_dim}), compare.getCpuFunction()->calc(
Tensor(cpu_w_grad ? cpu_w_grad->getData() : nullptr, {Tensor(cpu_in_grad.getData(), Dims{batch_size, input_dim}),
Dims{pad, input_dim}), Tensor(cpu_w_grad ? cpu_w_grad->getData() : nullptr,
Tensor(reinterpret_cast<real*>(cpu_seq->getData()), Dims{pad, input_dim}),
Dims{cpu_seq->getSize()})}, Tensor(reinterpret_cast<real*>(cpu_seq->getData()),
{Tensor(cpu_out_grad.getData(), Dims{cpu_seq->getSize()})},
Dims{batch_size, input_dim * context_length})}, {Tensor(cpu_out_grad.getData(),
{}); Dims{batch_size, input_dim * context_length})},
{});
gpu_data_func->calc( compare.getGpuFunction()->calc(
{Tensor(gpu_in_grad.getData(), Dims{batch_size, input_dim}), {Tensor(gpu_in_grad.getData(), Dims{batch_size, input_dim}),
Tensor(gpu_w_grad ? gpu_w_grad->getData() : nullptr,
Dims{pad, input_dim}),
Tensor(reinterpret_cast<real*>(gpu_seq->getData()), Tensor(reinterpret_cast<real*>(gpu_seq->getData()),
Dims{gpu_seq->getSize()})}, Dims{gpu_seq->getSize()})},
{Tensor(gpu_out_grad.getData(), {Tensor(gpu_out_grad.getData(),
Dims{batch_size, input_dim * context_length})}, Dims{batch_size, input_dim * context_length})},
{}); {});
if (is_padding && gpu_w_grad) {
gpu_w_func->calc({Tensor(gpu_w_grad->getData(), Dims{pad, input_dim}),
Tensor(reinterpret_cast<real*>(gpu_seq->getData()),
Dims{gpu_seq->getSize()})},
{Tensor(gpu_out_grad.getData(),
Dims{batch_size, input_dim * context_length})},
{});
}
autotest::TensorCheckErr(cpu_in_grad, gpu_in_grad); autotest::TensorCheckErr(cpu_in_grad, gpu_in_grad);
if (is_padding) { if (is_padding) {
autotest::TensorCheckErr(*cpu_w_grad, *gpu_w_grad); autotest::TensorCheckErr(*cpu_w_grad, *gpu_w_grad);
......
...@@ -47,43 +47,23 @@ bool ContextProjection::init() { ...@@ -47,43 +47,23 @@ bool ContextProjection::init() {
int context_start = config_.context_start(); int context_start = config_.context_start();
bool is_padding = config_.trainable_padding(); bool is_padding = config_.trainable_padding();
size_t total_pad = is_padding ? beginPad_ + endPad_ : 0; size_t total_pad = is_padding ? beginPad_ + endPad_ : 0;
if (!useGpu_) { // CPU functions
createFunction(forward_, createFunction(forward_,
"ContextProjectionForward-CPU", "ContextProjectionForward",
FuncConfig() FuncConfig()
.set("context_length", context_length) .set("context_length", context_length)
.set("context_start", context_start) .set("context_start", context_start)
.set("begin_pad", beginPad_) .set("begin_pad", beginPad_)
.set("is_padding", is_padding)); .set("is_padding", is_padding));
createFunction(backward_, createFunction(backward_,
"ContextProjectionBackward-CPU", "ContextProjectionBackward",
FuncConfig() FuncConfig()
.set("context_length", context_length) .set("context_length", context_length)
.set("context_start", context_start) .set("context_start", context_start)
.set("begin_pad", beginPad_) .set("begin_pad", beginPad_)
.set("is_padding", is_padding)); .set("is_padding", is_padding)
} else { // GPU functions .set("total_pad", total_pad));
createFunction(forward_,
"ContextProjectionForward-GPU",
FuncConfig()
.set("context_length", context_length)
.set("context_start", context_start)
.set("begin_pad", beginPad_)
.set("is_padding", is_padding));
createFunction(backward_,
"ContextProjectionBackwardData-GPU",
FuncConfig()
.set("context_length", context_length)
.set("context_start", context_start));
createFunction(backward_,
"ContextProjectionBackwardWeight-GPU",
FuncConfig()
.set("context_length", context_length)
.set("context_start", context_start)
.set("begin_pad", beginPad_)
.set("total_pad", total_pad));
}
return true; return true;
} }
...@@ -185,38 +165,16 @@ void ContextProjection::backward(const UpdateCallback& callback) { ...@@ -185,38 +165,16 @@ void ContextProjection::backward(const UpdateCallback& callback) {
REGISTER_TIMER_INFO("ContextProjectionBackward", getName().c_str()); REGISTER_TIMER_INFO("ContextProjectionBackward", getName().c_str());
bool is_padding = config_.trainable_padding(); bool is_padding = config_.trainable_padding();
auto start_pos = in_->sequenceStartPositions; auto start_pos = in_->sequenceStartPositions;
if (!out_->grad->useGpu()) { auto w_ptr = is_padding ? weight_->getWGrad() : nullptr;
auto w_ptr = is_padding ? weight_->getWGrad() : nullptr; backward_[0]->calc({Tensor(in_->grad ? in_->grad->getData() : nullptr,
backward_[0]->calc({Tensor(in_->grad ? in_->grad->getData() : nullptr, Dims{batch_size, input_dim}),
Dims{batch_size, input_dim}), Tensor(w_ptr ? w_ptr->getData() : nullptr,
Tensor(w_ptr ? w_ptr->getData() : nullptr, Dims{w_ptr ? w_ptr->getHeight() : 0, input_dim}),
Dims{w_ptr ? w_ptr->getHeight() : 0, input_dim}), Tensor(reinterpret_cast<real*>(
Tensor(reinterpret_cast<real*>(const_cast<int*>( const_cast<int*>(start_pos->getData(useGpu_))),
start_pos->getData(useGpu_))), Dims{start_pos->getSize()})},
Dims{start_pos->getSize()})}, {Tensor(out_->grad->getData(), Dims{batch_size, dim})},
{Tensor(out_->grad->getData(), Dims{batch_size, dim})}, {});
{});
} else {
if (in_->grad) {
backward_[0]->calc(
{Tensor(in_->grad->getData(), Dims{batch_size, input_dim}),
Tensor(reinterpret_cast<real*>(
const_cast<int*>(start_pos->getData(useGpu_))),
Dims{start_pos->getSize()})},
{Tensor(out_->grad->getData(), Dims{batch_size, dim})},
{});
}
if (is_padding && weight_->getWGrad()) {
backward_[1]->calc(
{Tensor(weight_->getWGrad()->getData(),
Dims{weight_->getWGrad()->getHeight(), input_dim}),
Tensor(reinterpret_cast<real*>(
const_cast<int*>(start_pos->getData(useGpu_))),
Dims{start_pos->getSize()})},
{Tensor(out_->grad->getData(), Dims{batch_size, dim})},
{});
}
}
if (config_.trainable_padding()) { if (config_.trainable_padding()) {
weight_->getParameterPtr()->incUpdate(callback); weight_->getParameterPtr()->incUpdate(callback);
......
...@@ -102,13 +102,19 @@ protected: ...@@ -102,13 +102,19 @@ protected:
/** /**
* Create layer function. Function is called in forward or backward. * Create layer function. Function is called in forward or backward.
* \param function, Layer::forward_ or Layer::backward_ * \param function, Layer::forward_ or Layer::backward_
* \param name, function name, include -GPU or -CPU * \param name, function name
* \param config, initialization configuration for the function * \param config, initialization configuration for the function
*/ */
void createFunction(std::vector<std::shared_ptr<FunctionBase>>& function, void createFunction(std::vector<std::shared_ptr<FunctionBase>>& function,
const std::string& name, const std::string& name,
const FuncConfig& config) { const FuncConfig& config) {
function.emplace_back(FunctionBase::funcRegistrar_.createByType(name)); if (useGpu_) {
function.emplace_back(
FunctionBase::funcRegistrar_.createByType(name + "-GPU"));
} else {
function.emplace_back(
FunctionBase::funcRegistrar_.createByType(name + "-CPU"));
}
auto& func = function.back(); auto& func = function.back();
func->init(config); func->init(config);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册