change offset and length's rank to 2, dim[0] for batch size

release/0.11.0
wanghaox 7 years ago
commit 1d95173cfe

@ -32,6 +32,14 @@ class SequenceSliceOp : public framework::OperatorWithKernel {
"Output(Out) of SequenceSliceOp should not be null.");
auto input_dims = ctx->GetInputDim("X");
auto offset_dim = ctx->GetInputDim("Offset");
auto length_dim = ctx->GetInputDim("Length");
PADDLE_ENFORCE_EQ(offset_dim.size(), 2UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(length_dim.size(), 2UL,
"Only support one level sequence now.");
ctx->SetOutputDim("Out", input_dims);
}
@ -95,7 +103,7 @@ It only supports sequence (LoD Tensor with level number is 1).
[d1, d2;
e1, e2]]
LoD(X) = {{0, 3, 5}}; Dims(X) = (5, 2)
Offset = [0, 1]; Length = [2, 1]
Offset = [[0], [1]]; Length = [[2], [1]]
Out = [[a1, a2;
b1, b2]

@ -48,42 +48,42 @@ class SequenceSliceOpKernel : public framework::OpKernel<T> {
auto* length = ctx.Input<Tensor>("Length");
auto* out = ctx.Output<LoDTensor>("Out");
auto lod = in->lod();
auto n = lod[0].size() - 1;
PADDLE_ENFORCE_EQ(lod.size(), 1UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(
n, length->dims()[0],
"The size of input-sequence and length-array should be the same")
PADDLE_ENFORCE_EQ(
n, offset->dims()[0],
"The size of input-sequence and offset-array should be the same")
const int64_t* offset_data = offset->data<int64_t>();
const int64_t* length_data = length->data<int64_t>();
framework::Tensor offset_cpu;
framework::Tensor length_cpu;
if (platform::is_gpu_place(ctx.GetPlace())) {
framework::Tensor offset_cpu;
offset_cpu.mutable_data<T>(offset->dims(), platform::CPUPlace());
offset_cpu.CopyFrom(*offset, platform::CPUPlace(), ctx.device_context());
offset_data = offset_cpu.data<int64_t>();
framework::Tensor length_cpu;
length_cpu.mutable_data<T>(length->dims(), platform::CPUPlace());
length_cpu.CopyFrom(*length, platform::CPUPlace(), ctx.device_context());
length_data = length_cpu.data<int64_t>();
}
auto lod = in->lod();
auto n = lod[0].size() - 1;
PADDLE_ENFORCE_EQ(lod.size(), 1UL, "Only support one level sequence now.");
PADDLE_ENFORCE_EQ(offset->dims().size(), 1UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(length->dims().size(), 1UL,
"Only support one level sequence now.");
PADDLE_ENFORCE_EQ(
n, length->dims()[0],
"The size of input-sequence and length-array should be the same")
PADDLE_ENFORCE_EQ(
n, offset->dims()[0],
"The size of input-sequence and offset-array should be the same")
for (size_t i = 0; i < n; ++i) {
PADDLE_ENFORCE_LT(0, offset_data[i], "The offset must greater than zero")
PADDLE_ENFORCE_LT(0, length_data[i], "The length must greater than zero")
PADDLE_ENFORCE_LT(lod[0][i] + offset_data[i] + length_data[i],
lod[0][i + 1], "The target tensor's length overflow")
}
PADDLE_ENFORCE_LT(0, offset_data[i],
"The offset must greater than zero")
PADDLE_ENFORCE_LT(0, length_data[i],
"The length must greater than zero")
PADDLE_ENFORCE_LT(
lod[0][i] + offset_data[i] + length_data[i],
lod[0][i + 1],
"The target tensor's length overflow")}
out->mutable_data<T>(ctx.GetPlace());
auto out_lod = SequenceSliceLoD(*in, offset_data, length_data);
@ -100,7 +100,7 @@ class SequenceSliceOpKernel : public framework::OpKernel<T> {
Tensor in_t =
in->Slice(static_cast<int>(lod[0][i] + offset_data[i]),
static_cast<int>(lod[0][i] + offset_data[i] +
length_data[i]));
length_data[i]));
StridedMemcpy<T>(ctx.device_context(), in_t.data<T>(),
in_stride, in_t.dims(), out_stride,

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
import logging
from paddle.v2.framework.op import Operator, DynamicRecurrentOp
import paddle.v2.framework.core as core
from paddle.v2.fluid.op import Operator, DynamicRecurrentOp
import paddle.v2.fluid.core as core
import unittest
import numpy as np

@ -9,16 +9,16 @@ class TestSequenceSliceOp(OpTest):
# only supprot one level LoD
x = np.random.random(self.x_dim).astype('float32')
lod = self.x_lod
offset = np.array(self.offset).flatten().astype("int64")
length = np.array(self.length).flatten().astype("int64")
offset = np.array(self.offset).astype("int64")
length = np.array(self.length).astype("int64")
self.inputs = {'X': (x, lod), 'Offset': offset, 'Length': length}
outs = [] #np.zeros((100, 3, 2)).astype('float32')
out_lod = [[0]]
out_lod_offset = 0
for i in range(len(offset)):
sub_x = x[lod[0][i] + offset[i]: lod[0]
[i] + offset[i] + length[i], :]
sub_x = x[lod[0][i] + offset[i, 0]: lod[0]
[i] + offset[i, 0] + length[i, 0], :]
out_lod_offset = out_lod_offset + len(sub_x)
outs.append(sub_x)
out_lod[0].append(out_lod_offset)
@ -28,8 +28,8 @@ class TestSequenceSliceOp(OpTest):
def init_test_case(self):
self.x_dim = (100, 3, 2)
self.x_lod = [[0, 20, 40, 60, 80, 100]]
self.offset = [1, 2, 3, 4, 5]
self.length = [10, 8, 6, 4, 2]
self.offset = [[1], [2], [3], [4], [5]]
self.length = [[10], [8], [6], [4], [2]]
def setUp(self):
self.op_type = "sequence_slice"

Loading…
Cancel
Save