提交 41c52d3b 编写于 作者: H hedaoyuan

Modify the argument type of ContextProjectionFunc

上级 68156c88
...@@ -3,6 +3,7 @@ file(GLOB cpp_files . *Op.cpp) ...@@ -3,6 +3,7 @@ file(GLOB cpp_files . *Op.cpp)
list(APPEND h_files Function.h) list(APPEND h_files Function.h)
list(APPEND cpp_files Function.cpp) list(APPEND cpp_files Function.cpp)
list(APPEND cpp_files BufferArg.cpp)
if(WITH_GPU) if(WITH_GPU)
file(GLOB cu_files . *OpGpu.cu) file(GLOB cu_files . *OpGpu.cu)
...@@ -16,10 +17,13 @@ if(WITH_TESTING) ...@@ -16,10 +17,13 @@ if(WITH_TESTING)
# TODO: # TODO:
# file(GLOB test_files . *OpTest.cpp) # file(GLOB test_files . *OpTest.cpp)
# add_executable(${test_bin} EXCLUDE_FROM_ALL ${test_files}) # add_executable(${test_bin} EXCLUDE_FROM_ALL ${test_files})
add_simple_unittest(CrossMapNormalOpTest) # add_simple_unittest(CrossMapNormalOpTest)
add_unittest(ContextProjectionOpTest add_simple_unittest(TensorShapeTest)
ContextProjectionOpTest.cpp add_simple_unittest(TensorTypeTest)
../gserver/tests/TestUtil.cpp) add_simple_unittest(BufferArgTest)
# add_unittest(ContextProjectionOpTest
# ContextProjectionOpTest.cpp
# ../gserver/tests/TestUtil.cpp)
endif() endif()
endif() endif()
......
...@@ -19,17 +19,15 @@ limitations under the License. */ ...@@ -19,17 +19,15 @@ limitations under the License. */
namespace paddle { namespace paddle {
template <> template <>
void ContextProjectionForward<DEVICE_TYPE_CPU>(CpuMatrix* out_mat, void ContextProjectionForward<DEVICE_TYPE_CPU>(CpuMatrix& out_mat,
const CpuMatrix* input_mat, const CpuMatrix& input_mat,
const CpuMatrix* weight_mat, const CpuMatrix& weight_mat,
const CpuIVector& seq_vec, const CpuIVector& seq_vec,
size_t context_length, size_t context_length,
int context_start, int context_start,
size_t begin_pad) { size_t begin_pad) {
const int* starts = seq_vec.getData(); const int* starts = seq_vec.getData();
const size_t num_sequences = seq_vec.getSize() - 1; const size_t num_sequences = seq_vec.getSize() - 1;
auto w_mat = const_cast<CpuMatrix*>(weight_mat);
auto in_mat = const_cast<CpuMatrix*>(input_mat);
for (size_t i = 0; i < num_sequences; ++i) { for (size_t i = 0; i < num_sequences; ++i) {
for (size_t j = 0; j < context_length; ++j) { for (size_t j = 0; j < context_length; ++j) {
int begin = starts[i] + context_start + j; int begin = starts[i] + context_start + j;
...@@ -39,10 +37,11 @@ void ContextProjectionForward<DEVICE_TYPE_CPU>(CpuMatrix* out_mat, ...@@ -39,10 +37,11 @@ void ContextProjectionForward<DEVICE_TYPE_CPU>(CpuMatrix* out_mat,
if (begin < starts[i]) { if (begin < starts[i]) {
int64_t pad_size = int64_t pad_size =
std::min(starts[i] - begin, starts[i + 1] - starts[i]); std::min(starts[i] - begin, starts[i + 1] - starts[i]);
MatrixPtr mat = out_mat->subMatrix(starts[i], pad_size); MatrixPtr mat = out_mat.subMatrix(starts[i], pad_size);
if (w_mat) { if (weight_mat) {
MatrixPtr sub = w_mat->subMatrix(j, pad_size); MatrixPtr sub =
mat->addAtOffset(*sub, j * in_mat->getWidth()); const_cast<CpuMatrix&>(weight_mat).subMatrix(j, pad_size);
mat->addAtOffset(*sub, j * input_mat.getWidth());
} }
dst_begin = starts[i] + pad_size; dst_begin = starts[i] + pad_size;
begin = starts[i]; begin = starts[i];
...@@ -50,19 +49,22 @@ void ContextProjectionForward<DEVICE_TYPE_CPU>(CpuMatrix* out_mat, ...@@ -50,19 +49,22 @@ void ContextProjectionForward<DEVICE_TYPE_CPU>(CpuMatrix* out_mat,
if (end > starts[i + 1]) { if (end > starts[i + 1]) {
int64_t pad_size = int64_t pad_size =
std::min(end - starts[i + 1], starts[i + 1] - starts[i]); std::min(end - starts[i + 1], starts[i + 1] - starts[i]);
MatrixPtr mat = out_mat->subMatrix(starts[i + 1] - pad_size, pad_size); MatrixPtr mat = out_mat.subMatrix(starts[i + 1] - pad_size, pad_size);
if (w_mat) { if (weight_mat) {
MatrixPtr sub = w_mat->subMatrix( MatrixPtr sub =
begin_pad + context_start + j - pad_size, pad_size); const_cast<CpuMatrix&>(weight_mat)
mat->addAtOffset(*sub, j * in_mat->getWidth()); .subMatrix(begin_pad + context_start + j - pad_size,
pad_size);
mat->addAtOffset(*sub, j * input_mat.getWidth());
} }
dst_end = starts[i + 1] - pad_size; dst_end = starts[i + 1] - pad_size;
end = starts[i + 1]; end = starts[i + 1];
} }
if (end <= begin) continue; if (end <= begin) continue;
MatrixPtr src = in_mat->subMatrix(begin, end - begin); MatrixPtr src =
MatrixPtr dst = out_mat->subMatrix(dst_begin, dst_end - dst_begin); const_cast<CpuMatrix&>(input_mat).subMatrix(begin, end - begin);
dst->addAtOffset(*src, j * in_mat->getWidth()); MatrixPtr dst = out_mat.subMatrix(dst_begin, dst_end - dst_begin);
dst->addAtOffset(*src, j * input_mat.getWidth());
} }
} }
} }
...@@ -82,40 +84,34 @@ public: ...@@ -82,40 +84,34 @@ public:
begin_pad_ = config.get<size_t>("begin_pad"); begin_pad_ = config.get<size_t>("begin_pad");
} }
void calc(const Arguments& inputs, void calc(const BufferArgs& inputs,
const Arguments& outputs, const BufferArgs& outputs,
const Arguments& inouts) override { const BufferArgs& inouts) override {
CHECK_EQ(3, inputs.size()); CHECK_EQ(3, inputs.size());
CHECK_EQ(1, outputs.size()); CHECK_EQ(1, outputs.size());
CHECK_EQ(0, inouts.size()); CHECK_EQ(0, inouts.size());
CHECK(outputs[0].getData() && inputs[0].getData() && inputs[2].getData()); CHECK(outputs[0].data() && inputs[0].data() && inputs[2].data());
CHECK_EQ(outputs[0].dims_.size(), 2); CHECK_EQ(outputs[0].shape().ndims(), 2);
CHECK_EQ(inputs[0].dims_.size(), 2); CHECK_EQ(inputs[0].shape().ndims(), 2);
CHECK_EQ(inputs[1].dims_.size(), 2); CHECK_EQ(inputs[1].shape().ndims(), 2);
CHECK_EQ(inputs[2].dims_.size(), 1); CHECK_EQ(inputs[2].shape().ndims(), 1);
/// dim of output = dim of input * context_length /// dim of output = dim of input * context_length
CHECK_EQ(outputs[0].dims_[1], inputs[0].dims_[1] * context_length_); CHECK_EQ(outputs[0].shape()[1], inputs[0].shape()[1] * context_length_);
/// dim of input == dim of weight /// dim of input == dim of weight
CHECK_EQ(inputs[0].dims_[1], inputs[1].dims_[1]); CHECK_EQ(inputs[0].shape()[1], inputs[1].shape()[1]);
/// input and output has the same batch_size /// input and output has the same batch_size
CHECK_EQ(inputs[0].dims_[0], outputs[0].dims_[0]); CHECK_EQ(inputs[0].shape()[0], outputs[0].shape()[0]);
auto out_mat = std::make_shared<typename MatrixT<Device>::type>( auto out_mat = outputs[0].matrix<Device>();
outputs[0].getData(), outputs[0].dims_[0], outputs[0].dims_[1]); auto in_mat = inputs[0].matrix<Device>();
const auto in_mat = std::make_shared<typename MatrixT<Device>::type>( auto w_mat = !inputs[1].data()
inputs[0].getData(), inputs[0].dims_[0], inputs[0].dims_[1]); ? typename Tensor<real, Device>::Matrix(nullptr, 0, 0)
const auto w_mat = : inputs[1].matrix<Device>();
!inputs[1].getData() auto seq_vec = inputs[2].vector<int, Device>();
? nullptr ContextProjectionForward<Device>(out_mat,
: std::make_shared<typename MatrixT<Device>::type>( in_mat,
inputs[1].getData(), inputs[1].dims_[0], inputs[1].dims_[1]); w_mat,
typename SequenceT<Device>::type seq_vec(
inputs[2].dims_[0], reinterpret_cast<int*>(inputs[2].getData()));
ContextProjectionForward<Device>(out_mat.get(),
in_mat.get(),
w_mat.get(),
seq_vec, seq_vec,
context_length_, context_length_,
context_start_, context_start_,
...@@ -129,18 +125,17 @@ private: ...@@ -129,18 +125,17 @@ private:
}; };
template <> template <>
void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat, void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix& out_grad_mat,
CpuMatrix* in_grad_mat, CpuMatrix& in_grad_mat,
CpuMatrix* w_grad_mat, CpuMatrix& w_grad_mat,
const CpuIVector& seq_vec, const CpuIVector& seq_vec,
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) { size_t total_pad) {
CHECK(out_grad_mat); size_t input_dim = in_grad_mat ? in_grad_mat.getWidth()
size_t input_dim = in_grad_mat ? in_grad_mat->getWidth() : w_grad_mat ? w_grad_mat.getWidth() : 0;
: w_grad_mat ? w_grad_mat->getWidth() : 0;
const int* starts = seq_vec.getData(); const int* starts = seq_vec.getData();
size_t num_sequences = seq_vec.getSize() - 1; size_t num_sequences = seq_vec.getSize() - 1;
for (size_t i = 0; i < num_sequences; ++i) { for (size_t i = 0; i < num_sequences; ++i) {
...@@ -153,8 +148,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat, ...@@ -153,8 +148,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat,
int64_t pad_size = int64_t pad_size =
std::min(starts[i] - begin, starts[i + 1] - starts[i]); std::min(starts[i] - begin, starts[i + 1] - starts[i]);
if (is_padding && w_grad_mat) { if (is_padding && w_grad_mat) {
MatrixPtr mat = out_grad_mat->subMatrix(starts[i], pad_size); MatrixPtr mat = out_grad_mat.subMatrix(starts[i], pad_size);
MatrixPtr sub = w_grad_mat->subMatrix(j, pad_size); MatrixPtr sub = w_grad_mat.subMatrix(j, pad_size);
sub->addAtOffset(*mat, j * input_dim); sub->addAtOffset(*mat, j * input_dim);
} }
dst_begin = starts[i] + pad_size; dst_begin = starts[i] + pad_size;
...@@ -165,8 +160,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat, ...@@ -165,8 +160,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat,
std::min(end - starts[i + 1], starts[i + 1] - starts[i]); std::min(end - starts[i + 1], starts[i + 1] - starts[i]);
if (is_padding && w_grad_mat) { if (is_padding && w_grad_mat) {
MatrixPtr mat = MatrixPtr mat =
out_grad_mat->subMatrix(starts[i + 1] - pad_size, pad_size); out_grad_mat.subMatrix(starts[i + 1] - pad_size, pad_size);
MatrixPtr sub = w_grad_mat->subMatrix( MatrixPtr sub = w_grad_mat.subMatrix(
begin_pad + context_start + j - pad_size, pad_size); begin_pad + context_start + j - pad_size, pad_size);
sub->addAtOffset(*mat, j * input_dim); sub->addAtOffset(*mat, j * input_dim);
} }
...@@ -175,8 +170,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat, ...@@ -175,8 +170,8 @@ void ContextProjectionBackward<DEVICE_TYPE_CPU>(CpuMatrix* out_grad_mat,
} }
if (end <= begin) continue; if (end <= begin) continue;
if (!in_grad_mat) continue; if (!in_grad_mat) continue;
MatrixPtr src = in_grad_mat->subMatrix(begin, end - begin); MatrixPtr src = in_grad_mat.subMatrix(begin, end - begin);
MatrixPtr dst = out_grad_mat->subMatrix(dst_begin, dst_end - dst_begin); MatrixPtr dst = out_grad_mat.subMatrix(dst_begin, dst_end - dst_begin);
src->addAtOffset(*dst, j * input_dim); src->addAtOffset(*dst, j * input_dim);
} }
} }
...@@ -199,44 +194,37 @@ public: ...@@ -199,44 +194,37 @@ public:
total_pad_ = config.get<size_t>("total_pad"); total_pad_ = config.get<size_t>("total_pad");
} }
void calc(const Arguments& inputs, void calc(const BufferArgs& inputs,
const Arguments& outputs, const BufferArgs& outputs,
const Arguments& inouts) override { const BufferArgs& inouts) override {
CHECK_EQ(3, inputs.size()); CHECK_EQ(3, inputs.size());
CHECK_EQ(1, outputs.size()); CHECK_EQ(1, outputs.size());
CHECK_EQ(0, inouts.size()); CHECK_EQ(0, inouts.size());
CHECK(outputs[0].getData() && inputs[2].getData()); CHECK(outputs[0].data() && inputs[2].data());
CHECK_EQ(outputs[0].dims_.size(), 2); CHECK_EQ(outputs[0].shape().ndims(), 2);
CHECK_EQ(inputs[0].dims_.size(), 2); CHECK_EQ(inputs[0].shape().ndims(), 2);
CHECK_EQ(inputs[1].dims_.size(), 2); CHECK_EQ(inputs[1].shape().ndims(), 2);
CHECK_EQ(inputs[2].dims_.size(), 1); CHECK_EQ(inputs[2].shape().ndims(), 1);
/// dim of input == dim of weight /// dim of input == dim of weight
CHECK_EQ(inputs[0].dims_[1], inputs[1].dims_[1]); CHECK_EQ(inputs[0].shape()[1], inputs[1].shape()[1]);
/// input and output has the same batch_size /// input and output has the same batch_size
CHECK_EQ(inputs[0].dims_[0], outputs[0].dims_[0]); CHECK_EQ(inputs[0].shape()[0], outputs[0].shape()[0]);
/// dim of output = dim of input * context_length /// dim of output = dim of input * context_length
CHECK_EQ(outputs[0].dims_[1], inputs[0].dims_[1] * context_length_); CHECK_EQ(outputs[0].shape()[1], inputs[0].shape()[1] * context_length_);
auto out_grad_mat = std::make_shared<typename MatrixT<Device>::type>( auto out_grad_mat = outputs[0].matrix<Device>();
outputs[0].getData(), outputs[0].dims_[0], outputs[0].dims_[1]);
auto in_grad_mat = auto in_grad_mat =
!inputs[0].getData() !inputs[0].data() ? typename Tensor<real, Device>::Matrix(nullptr, 0, 0)
? nullptr : inputs[0].matrix<Device>();
: std::make_shared<typename MatrixT<Device>::type>( auto w_grad_mat = !inputs[1].data()
inputs[0].getData(), inputs[0].dims_[0], inputs[0].dims_[1]); ? typename Tensor<real, Device>::Matrix(nullptr, 0, 0)
auto w_grad_mat = : inputs[1].matrix<Device>();
!inputs[1].getData() auto seq_vec = inputs[2].vector<int, Device>();
? nullptr ContextProjectionBackward<Device>(out_grad_mat,
: std::make_shared<typename MatrixT<Device>::type>( in_grad_mat,
inputs[1].getData(), inputs[1].dims_[0], inputs[1].dims_[1]); w_grad_mat,
typename SequenceT<Device>::type seq_vec(
inputs[2].dims_[0], reinterpret_cast<int*>(inputs[2].getData()));
ContextProjectionBackward<Device>(out_grad_mat.get(),
in_grad_mat ? in_grad_mat.get() : nullptr,
w_grad_mat ? w_grad_mat.get() : nullptr,
seq_vec, seq_vec,
context_length_, context_length_,
context_start_, context_start_,
...@@ -253,6 +241,7 @@ private: ...@@ -253,6 +241,7 @@ private:
size_t total_pad_; size_t total_pad_;
}; };
#if 0
/** /**
* \param inputs[0] input grad. * \param inputs[0] input grad.
* \param inputs[1] input sequence. * \param inputs[1] input sequence.
...@@ -272,6 +261,7 @@ public: ...@@ -272,6 +261,7 @@ public:
CHECK_EQ(2, inputs.size()); CHECK_EQ(2, inputs.size());
CHECK_EQ(1, outputs.size()); CHECK_EQ(1, outputs.size());
CHECK_EQ(0, inouts.size()); CHECK_EQ(0, inouts.size());
CHECK(inputs[0].getData() && outputs[0].getData() && inputs[1].getData()); CHECK(inputs[0].getData() && outputs[0].getData() && inputs[1].getData());
CHECK_EQ(outputs[0].dims_.size(), 2); CHECK_EQ(outputs[0].dims_.size(), 2);
CHECK_EQ(inputs[0].dims_.size(), 2); CHECK_EQ(inputs[0].dims_.size(), 2);
...@@ -349,6 +339,7 @@ private: ...@@ -349,6 +339,7 @@ private:
size_t begin_pad_; size_t begin_pad_;
size_t total_pad_; size_t total_pad_;
}; };
#endif
REGISTER_TYPED_FUNC(ContextProjectionForward, REGISTER_TYPED_FUNC(ContextProjectionForward,
CPU, CPU,
...@@ -363,6 +354,7 @@ REGISTER_TYPED_FUNC(ContextProjectionForward, ...@@ -363,6 +354,7 @@ REGISTER_TYPED_FUNC(ContextProjectionForward,
REGISTER_TYPED_FUNC(ContextProjectionBackward, REGISTER_TYPED_FUNC(ContextProjectionBackward,
GPU, GPU,
ContextProjectionBackwardFunc); ContextProjectionBackwardFunc);
#if 0
REGISTER_TYPED_FUNC(ContextProjectionBackwardData, REGISTER_TYPED_FUNC(ContextProjectionBackwardData,
GPU, GPU,
ContextProjectionBackwardDataFunc); ContextProjectionBackwardDataFunc);
...@@ -370,4 +362,5 @@ REGISTER_TYPED_FUNC(ContextProjectionBackwardWeight, ...@@ -370,4 +362,5 @@ REGISTER_TYPED_FUNC(ContextProjectionBackwardWeight,
GPU, GPU,
ContextProjectionBackwardWeightFunc); ContextProjectionBackwardWeightFunc);
#endif #endif
#endif
} // namespace paddle } // namespace paddle
...@@ -31,14 +31,15 @@ namespace paddle { ...@@ -31,14 +31,15 @@ namespace paddle {
* \param[in] is_padding whether padding 0 or not. * \param[in] is_padding whether padding 0 or not.
* *
*/ */
template <DeviceType Device> template <DeviceType DType>
void ContextProjectionForward(typename MatrixT<Device>::type* output, void ContextProjectionForward(
const typename MatrixT<Device>::type* input, typename Tensor<real, DType>::Matrix& output,
const typename MatrixT<Device>::type* weight, const typename Tensor<real, DType>::Matrix& input,
const typename SequenceT<Device>::type& sequence, const typename Tensor<real, DType>::Matrix& weight,
size_t context_length, const typename Tensor<int, DType>::Vector& sequence,
int context_start, size_t context_length,
size_t begin_pad); int context_start,
size_t begin_pad);
/** /**
* \brief Context Projection Backward. * \brief Context Projection Backward.
...@@ -53,30 +54,31 @@ void ContextProjectionForward(typename MatrixT<Device>::type* output, ...@@ -53,30 +54,31 @@ void ContextProjectionForward(typename MatrixT<Device>::type* output,
* \param[in] is_padding whether padding 0 or not. * \param[in] is_padding whether padding 0 or not.
* *
*/ */
template <DeviceType Device> template <DeviceType DType>
void ContextProjectionBackward(typename MatrixT<Device>::type* out_grad, void ContextProjectionBackward(
typename MatrixT<Device>::type* in_grad, typename Tensor<real, DType>::Matrix& out_grad,
typename MatrixT<Device>::type* w_grad, typename Tensor<real, DType>::Matrix& in_grad,
const typename SequenceT<Device>::type& seq_vec, typename Tensor<real, DType>::Matrix& w_grad,
size_t context_length, const typename Tensor<int, DType>::Vector& seq_vec,
int context_start, size_t context_length,
size_t begin_pad, int context_start,
bool is_padding, size_t begin_pad,
size_t total_pad); bool is_padding,
size_t total_pad);
template <DeviceType Device> template <DeviceType DType>
void ContextProjectionBackwardData( void ContextProjectionBackwardData(
typename MatrixT<Device>::type* out_grad, typename Tensor<real, DType>::Matrix& out_grad,
typename MatrixT<Device>::type* in_grad, typename Tensor<real, DType>::Matrix& in_grad,
const typename SequenceT<Device>::type& sequence, const typename Tensor<int, DType>::Vector& sequence,
size_t context_length, size_t context_length,
int context_start); int context_start);
template <DeviceType Device> template <DeviceType DType>
void ContextProjectionBackwardWeight( void ContextProjectionBackwardWeight(
typename MatrixT<Device>::type* out_grad, typename Tensor<real, DType>::Matrix& out_grad,
typename MatrixT<Device>::type* w_grad, typename Tensor<real, DType>::Matrix& w_grad,
const typename SequenceT<Device>::type& seq_vec, const typename Tensor<int, DType>::Vector& seq_vec,
size_t context_length, size_t context_length,
int context_start, int context_start,
size_t total_pad, size_t total_pad,
......
...@@ -120,20 +120,19 @@ void hl_context_projection_forward(const real* input, ...@@ -120,20 +120,19 @@ void hl_context_projection_forward(const real* input,
} }
template <> template <>
void ContextProjectionForward<DEVICE_TYPE_GPU>(GpuMatrix* output, void ContextProjectionForward<DEVICE_TYPE_GPU>(GpuMatrix& output,
const GpuMatrix* input, const GpuMatrix& input,
const GpuMatrix* weight, const GpuMatrix& weight,
const GpuIVector& sequence, const GpuIVector& sequence,
size_t context_length, size_t context_length,
int context_start, int context_start,
size_t begin_pad) { size_t begin_pad) {
CHECK(input && output); hl_context_projection_forward(input.getData(),
hl_context_projection_forward(input->getData(),
sequence.getData(), sequence.getData(),
weight ? weight->getData() : nullptr, weight ? weight.getData() : nullptr,
output->getData(), output.getData(),
sequence.getSize() - 1, sequence.getSize() - 1,
input->getWidth(), input.getWidth(),
context_length, context_length,
context_start, context_start,
begin_pad); begin_pad);
...@@ -217,17 +216,16 @@ void hl_context_projection_backward_data(real* out_grad, ...@@ -217,17 +216,16 @@ void hl_context_projection_backward_data(real* out_grad,
} }
template <> template <>
void ContextProjectionBackwardData<DEVICE_TYPE_GPU>(GpuMatrix* out_grad, void ContextProjectionBackwardData<DEVICE_TYPE_GPU>(GpuMatrix& out_grad,
GpuMatrix* in_grad, GpuMatrix& in_grad,
const GpuIVector& sequence, const GpuIVector& sequence,
size_t context_length, size_t context_length,
int context_start) { int context_start) {
CHECK(in_grad && out_grad); hl_context_projection_backward_data(out_grad.getData(),
hl_context_projection_backward_data(out_grad->getData(),
sequence.getData(), sequence.getData(),
in_grad->getData(), in_grad.getData(),
sequence.getSize() - 1, sequence.getSize() - 1,
in_grad->getWidth(), in_grad.getWidth(),
context_length, context_length,
context_start); context_start);
} }
...@@ -348,19 +346,18 @@ void hl_context_projection_backward_weight(real* out_grad, ...@@ -348,19 +346,18 @@ void hl_context_projection_backward_weight(real* out_grad,
template <> template <>
void ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>( void ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>(
GpuMatrix* out_grad, GpuMatrix& out_grad,
GpuMatrix* w_grad, GpuMatrix& w_grad,
const GpuIVector& seq_vec, const GpuIVector& seq_vec,
size_t context_length, size_t context_length,
int context_start, int context_start,
size_t total_pad, size_t total_pad,
size_t begin_pad) { size_t begin_pad) {
CHECK(out_grad && w_grad); hl_context_projection_backward_weight(out_grad.getData(),
hl_context_projection_backward_weight(out_grad->getData(),
seq_vec.getData(), seq_vec.getData(),
w_grad->getData(), w_grad.getData(),
seq_vec.getSize() - 1, seq_vec.getSize() - 1,
w_grad->getWidth(), w_grad.getWidth(),
total_pad, total_pad,
context_length, context_length,
context_start, context_start,
...@@ -368,16 +365,15 @@ void ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>( ...@@ -368,16 +365,15 @@ void ContextProjectionBackwardWeight<DEVICE_TYPE_GPU>(
} }
template <> template <>
void ContextProjectionBackward<DEVICE_TYPE_GPU>(GpuMatrix* out_grad, void ContextProjectionBackward<DEVICE_TYPE_GPU>(GpuMatrix& out_grad,
GpuMatrix* in_grad, GpuMatrix& in_grad,
GpuMatrix* w_grad, GpuMatrix& w_grad,
const GpuIVector& sequence, const GpuIVector& 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) { size_t total_pad) {
CHECK(out_grad);
if (in_grad) { if (in_grad) {
ContextProjectionBackwardData<DEVICE_TYPE_GPU>( ContextProjectionBackwardData<DEVICE_TYPE_GPU>(
out_grad, out_grad,
......
...@@ -44,4 +44,21 @@ TEST(TensorType, Vector) { ...@@ -44,4 +44,21 @@ TEST(TensorType, Vector) {
EXPECT_EQ(gpuIVector.getSize(), 100); EXPECT_EQ(gpuIVector.getSize(), 100);
} }
TEST(TensorType, EmptyMatrix) {
CpuMatrix empty(nullptr, 0, 0);
CpuMatrix nonEmpty(10, 10);
EXPECT_EQ(empty.isEmpty(), true);
EXPECT_EQ(nonEmpty.isEmpty(), false);
CHECK(nonEmpty);
auto function = [](const CpuMatrix& matrix) {
if (matrix) {
EXPECT_NE(matrix.getData(), nullptr);
} else {
EXPECT_EQ(matrix.getData(), nullptr);
}
};
function(empty);
function(nonEmpty);
}
} // namespace paddle } // namespace paddle
...@@ -110,7 +110,7 @@ void ContextProjection::forward() { ...@@ -110,7 +110,7 @@ void ContextProjection::forward() {
size_t input_dim = in_->value->getWidth(); size_t input_dim = in_->value->getWidth();
size_t dim = out_->value->getWidth(); size_t dim = out_->value->getWidth();
CHECK_EQ(dim, input_dim * config_.context_length()); CHECK_EQ(dim, input_dim * config_.context_length());
size_t batch_size = in_->value->getHeight(); // size_t batch_size = in_->value->getHeight();
CHECK_EQ(forward_.size(), 1) << "Only one forward function here"; CHECK_EQ(forward_.size(), 1) << "Only one forward function here";
REGISTER_TIMER_INFO("ContextProjectionForward", getName().c_str()); REGISTER_TIMER_INFO("ContextProjectionForward", getName().c_str());
...@@ -119,14 +119,17 @@ void ContextProjection::forward() { ...@@ -119,14 +119,17 @@ void ContextProjection::forward() {
auto w_ptr = auto w_ptr =
state_ ? state_.get() : is_padding ? weight_->getW().get() : nullptr; state_ ? state_.get() : is_padding ? weight_->getW().get() : nullptr;
auto start_pos = in_->sequenceStartPositions; auto start_pos = in_->sequenceStartPositions;
forward_[0]->calc({Tensor(in_->value->getData(), Dims{batch_size, input_dim}),
Tensor(w_ptr ? w_ptr->getData() : nullptr, BufferArgs inputs;
Dims{w_ptr ? w_ptr->getHeight() : 0, input_dim}), BufferArgs outputs;
Tensor(reinterpret_cast<real*>( BufferArgs inouts;
const_cast<int*>(start_pos->getData(useGpu_))), inputs.addArg(*in_->value);
Dims{start_pos->getSize()})}, inputs.addArg(CpuMatrix(w_ptr ? w_ptr->getData() : nullptr,
{Tensor(out_->value->getData(), Dims{batch_size, dim})}, w_ptr ? w_ptr->getHeight() : 0,
{}); input_dim));
inputs.addArg(*in_->sequenceStartPositions->getVector(useGpu_));
outputs.addArg(*out_->value);
forward_[0]->calc(inputs, outputs, inouts);
if (state_ && config_.context_start() < 0) { if (state_ && config_.context_start() < 0) {
CHECK_EQ(1, in_->getNumSequences()); CHECK_EQ(1, in_->getNumSequences());
...@@ -160,15 +163,18 @@ void ContextProjection::backward(const UpdateCallback& callback) { ...@@ -160,15 +163,18 @@ void ContextProjection::backward(const UpdateCallback& callback) {
bool is_padding = config_.trainable_padding(); bool is_padding = config_.trainable_padding();
auto start_pos = in_->sequenceStartPositions; auto start_pos = in_->sequenceStartPositions;
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,
Dims{batch_size, input_dim}), BufferArgs inputs;
Tensor(w_ptr ? w_ptr->getData() : nullptr, BufferArgs outputs;
Dims{w_ptr ? w_ptr->getHeight() : 0, input_dim}), BufferArgs inouts;
Tensor(reinterpret_cast<real*>( inputs.addArg(CpuMatrix(
const_cast<int*>(start_pos->getData(useGpu_))), in_->grad ? in_->grad->getData() : nullptr, batch_size, input_dim));
Dims{start_pos->getSize()})}, inputs.addArg(CpuMatrix(w_ptr ? w_ptr->getData() : nullptr,
{Tensor(out_->grad->getData(), Dims{batch_size, dim})}, w_ptr ? w_ptr->getHeight() : 0,
{}); input_dim));
inputs.addArg(*in_->sequenceStartPositions->getVector(useGpu_));
outputs.addArg(*out_->grad);
backward_[0]->calc(inputs, outputs, inouts);
if (config_.trainable_padding()) { if (config_.trainable_padding()) {
weight_->getParameterPtr()->incUpdate(callback); weight_->getParameterPtr()->incUpdate(callback);
......
...@@ -1091,6 +1091,10 @@ public: ...@@ -1091,6 +1091,10 @@ public:
TensorCpuApply<real>(*this, expr); TensorCpuApply<real>(*this, expr);
} }
} }
bool isEmpty() const { return data_ == nullptr; }
explicit operator bool() const { return !isEmpty(); }
}; };
inline std::ostream& operator<<(std::ostream& os, const Matrix& mat) { inline std::ostream& operator<<(std::ostream& os, const Matrix& mat) {
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册