提交 b7285438 编写于 作者: C chengduoZH

Fix (According to the review)

上级 b0a47b14
...@@ -137,19 +137,23 @@ class Pool2dBackwardFunctor<platform::CPUPlace, PoolProcess, T> { ...@@ -137,19 +137,23 @@ class Pool2dBackwardFunctor<platform::CPUPlace, PoolProcess, T> {
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::maxPool<float>, float>;
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::avgPool<float>, float>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::maxPoolGrad<float>,
float>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::avgPoolGrad<float>,
float>;
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::maxPool<double>, double>;
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::avgPool<double>, double>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::maxPoolGrad<double>,
double>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::avgPoolGrad<double>,
double>;
template <typename PoolProcess, class T> template <typename PoolProcess, class T>
class Pool3dForwardFunctor<platform::CPUPlace, PoolProcess, T> { class Pool3dForwardFunctor<platform::CPUPlace, PoolProcess, T> {
...@@ -302,19 +306,23 @@ class Pool3dBackwardFunctor<platform::CPUPlace, PoolProcess, T> { ...@@ -302,19 +306,23 @@ class Pool3dBackwardFunctor<platform::CPUPlace, PoolProcess, T> {
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::maxPool<float>, float>;
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::avgPool<float>, float>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::maxPoolGrad<float>,
float>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::CPUPlace, paddle::operators::math::pool::avgPoolGrad<float>,
float>;
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::maxPool<double>, double>;
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::avgPool<double>, double>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::maxPoolGrad<double>,
double>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::CPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::CPUPlace, paddle::operators::math::pool::avgPoolGrad<double>,
double>;
} // namespace math } // namespace math
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle
...@@ -190,19 +190,23 @@ class Pool2dBackwardFunctor<platform::GPUPlace, PoolProcess, T> { ...@@ -190,19 +190,23 @@ class Pool2dBackwardFunctor<platform::GPUPlace, PoolProcess, T> {
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::maxPool<float>, float>;
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::avgPool<float>, float>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::maxPoolGrad<float>,
float>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::avgPoolGrad<float>,
float>;
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::maxPool<double>, double>;
template class Pool2dForwardFunctor< template class Pool2dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::avgPool<double>, double>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::maxPoolGrad<double>,
double>;
template class Pool2dBackwardFunctor< template class Pool2dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::avgPoolGrad<double>,
double>;
template <typename PoolProcess, typename T> template <typename PoolProcess, typename T>
__global__ void KernelPool3DForward( __global__ void KernelPool3DForward(
...@@ -414,19 +418,23 @@ class Pool3dBackwardFunctor<platform::GPUPlace, PoolProcess, T> { ...@@ -414,19 +418,23 @@ class Pool3dBackwardFunctor<platform::GPUPlace, PoolProcess, T> {
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::maxPool<float>, float>;
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::avgPool<float>, float>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::maxPoolGrad<float>,
float>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<float>, float>; platform::GPUPlace, paddle::operators::math::pool::avgPoolGrad<float>,
float>;
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::maxPool<double>, double>;
template class Pool3dForwardFunctor< template class Pool3dForwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::avgPool<double>, double>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::maxPool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::maxPoolGrad<double>,
double>;
template class Pool3dBackwardFunctor< template class Pool3dBackwardFunctor<
platform::GPUPlace, paddle::operators::math::pool::avePool<double>, double>; platform::GPUPlace, paddle::operators::math::pool::avgPoolGrad<double>,
double>;
} // namespace math } // namespace math
} // namespace operators } // namespace operators
......
...@@ -33,6 +33,18 @@ class maxPool { ...@@ -33,6 +33,18 @@ class maxPool {
DEVICE inline T initial() { return static_cast<T>(-FLT_MAX); } DEVICE inline T initial() { return static_cast<T>(-FLT_MAX); }
DEVICE inline void process(T& y, const T& x) { y = y > x ? y : x; } DEVICE inline void process(T& y, const T& x) { y = y > x ? y : x; }
DEVICE inline void finalize(T& y, const T& poo_size) {} DEVICE inline void finalize(T& y, const T& poo_size) {}
};
template <class T>
class avgPool {
public:
DEVICE inline T initial() { return static_cast<T>(0); }
DEVICE inline void process(T& y, const T& x) { y += x; }
DEVICE inline void finalize(T& y, const T& poo_size) { y /= poo_size; }
};
template <class T>
class maxPoolGrad {
public:
DEVICE inline void gradProcess(const T& x, const T& y, const T& dy, T& dx, DEVICE inline void gradProcess(const T& x, const T& y, const T& dy, T& dx,
T scale) { T scale) {
dx += dy * (x == y); dx += dy * (x == y);
...@@ -40,11 +52,8 @@ class maxPool { ...@@ -40,11 +52,8 @@ class maxPool {
}; };
template <class T> template <class T>
class avePool { class avgPoolGrad {
public: public:
DEVICE inline T initial() { return static_cast<T>(0); }
DEVICE inline void process(T& y, const T& x) { y += x; }
DEVICE inline void finalize(T& y, const T& poo_size) { y /= poo_size; }
DEVICE inline void gradProcess(const T& x, const T& y, const T& dy, T& dx, DEVICE inline void gradProcess(const T& x, const T& y, const T& dy, T& dx,
T scale) { T scale) {
dx += (scale * dy); dx += (scale * dy);
......
...@@ -41,8 +41,8 @@ class PoolOp : public framework::OperatorWithKernel { ...@@ -41,8 +41,8 @@ class PoolOp : public framework::OperatorWithKernel {
std::vector<int> strides = Attr<std::vector<int>>("strides"); std::vector<int> strides = Attr<std::vector<int>>("strides");
std::vector<int> paddings = Attr<std::vector<int>>("paddings"); std::vector<int> paddings = Attr<std::vector<int>>("paddings");
PADDLE_ENFORCE(pooling_type == "max" || pooling_type == "ave", PADDLE_ENFORCE(pooling_type == "max" || pooling_type == "avg",
"pooling_type should be 'max' or 'ave'"); "pooling_type should be 'max' or 'avg'");
PADDLE_ENFORCE(in_X->dims().size() == 4 || in_X->dims().size() == 5, PADDLE_ENFORCE(in_X->dims().size() == 4 || in_X->dims().size() == 5,
"Pooling intput should be 4-D or 5-D"); "Pooling intput should be 4-D or 5-D");
...@@ -99,7 +99,7 @@ class Pool2dOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -99,7 +99,7 @@ class Pool2dOpMaker : public framework::OpProtoAndCheckerMaker {
AddAttr<std::string>("poolingType", AddAttr<std::string>("poolingType",
"poolingType of pooling operator." "poolingType of pooling operator."
"str constant equal to 'max' or 'ave'"); "str constant equal to 'max' or 'avg'");
AddAttr<std::vector<int>>( AddAttr<std::vector<int>>(
"ksize", "pooling size(height, width) of pooling operator."); "ksize", "pooling size(height, width) of pooling operator.");
AddAttr<int>( AddAttr<int>(
...@@ -140,7 +140,7 @@ class Pool3dOpMaker : public framework::OpProtoAndCheckerMaker { ...@@ -140,7 +140,7 @@ class Pool3dOpMaker : public framework::OpProtoAndCheckerMaker {
AddAttr<std::string>("poolingType", AddAttr<std::string>("poolingType",
"poolingType of pooling operator." "poolingType of pooling operator."
"str constant equal to 'max' or 'ave'"); "str constant equal to 'max' or 'avg'");
AddAttr<std::vector<int>>( AddAttr<std::vector<int>>(
"ksize", "pooling size(depth, height, width) of pooling operator."); "ksize", "pooling size(depth, height, width) of pooling operator.");
AddAttr<int>( AddAttr<int>(
......
...@@ -52,11 +52,11 @@ class PoolKernel : public framework::OpKernel { ...@@ -52,11 +52,11 @@ class PoolKernel : public framework::OpKernel {
pool2d_forward(context.device_context(), *in_X, *out, ksize, strides, pool2d_forward(context.device_context(), *in_X, *out, ksize, strides,
paddings, pool_process); paddings, pool_process);
} else if (pooling_type == "ave") { } else if (pooling_type == "avg") {
paddle::operators::math::Pool2dForwardFunctor< paddle::operators::math::Pool2dForwardFunctor<
Place, paddle::operators::math::pool::avePool<T>, T> Place, paddle::operators::math::pool::avgPool<T>, T>
pool2d_forward; pool2d_forward;
paddle::operators::math::pool::avePool<T> pool_process; paddle::operators::math::pool::avgPool<T> pool_process;
pool2d_forward(context.device_context(), *in_X, *out, ksize, strides, pool2d_forward(context.device_context(), *in_X, *out, ksize, strides,
paddings, pool_process); paddings, pool_process);
} }
...@@ -69,11 +69,11 @@ class PoolKernel : public framework::OpKernel { ...@@ -69,11 +69,11 @@ class PoolKernel : public framework::OpKernel {
paddle::operators::math::pool::maxPool<T> pool_process; paddle::operators::math::pool::maxPool<T> pool_process;
pool3d_forward(context.device_context(), *in_X, *out, ksize, strides, pool3d_forward(context.device_context(), *in_X, *out, ksize, strides,
paddings, pool_process); paddings, pool_process);
} else if (pooling_type == "ave") { } else if (pooling_type == "avg") {
paddle::operators::math::Pool3dForwardFunctor< paddle::operators::math::Pool3dForwardFunctor<
Place, paddle::operators::math::pool::avePool<T>, T> Place, paddle::operators::math::pool::avgPool<T>, T>
pool3d_forward; pool3d_forward;
paddle::operators::math::pool::avePool<T> pool_process; paddle::operators::math::pool::avgPool<T> pool_process;
pool3d_forward(context.device_context(), *in_X, *out, ksize, strides, pool3d_forward(context.device_context(), *in_X, *out, ksize, strides,
paddings, pool_process); paddings, pool_process);
} }
...@@ -112,16 +112,16 @@ class PoolGradKernel : public framework::OpKernel { ...@@ -112,16 +112,16 @@ class PoolGradKernel : public framework::OpKernel {
case 2: { case 2: {
if (pooling_type == "max") { if (pooling_type == "max") {
paddle::operators::math::Pool2dBackwardFunctor< paddle::operators::math::Pool2dBackwardFunctor<
Place, paddle::operators::math::pool::maxPool<T>, T> Place, paddle::operators::math::pool::maxPoolGrad<T>, T>
pool2d_backward; pool2d_backward;
paddle::operators::math::pool::maxPool<T> pool_process; paddle::operators::math::pool::maxPoolGrad<T> pool_process;
pool2d_backward(context.device_context(), *in_X, *in_X_grad, *out, pool2d_backward(context.device_context(), *in_X, *in_X_grad, *out,
*out_grad, ksize, strides, paddings, pool_process); *out_grad, ksize, strides, paddings, pool_process);
} else if (pooling_type == "ave") { } else if (pooling_type == "avg") {
paddle::operators::math::Pool2dBackwardFunctor< paddle::operators::math::Pool2dBackwardFunctor<
Place, paddle::operators::math::pool::avePool<T>, T> Place, paddle::operators::math::pool::avgPoolGrad<T>, T>
pool2d_backward; pool2d_backward;
paddle::operators::math::pool::avePool<T> pool_process; paddle::operators::math::pool::avgPoolGrad<T> pool_process;
pool2d_backward(context.device_context(), *in_X, *in_X_grad, *out, pool2d_backward(context.device_context(), *in_X, *in_X_grad, *out,
*out_grad, ksize, strides, paddings, pool_process); *out_grad, ksize, strides, paddings, pool_process);
} }
...@@ -129,16 +129,16 @@ class PoolGradKernel : public framework::OpKernel { ...@@ -129,16 +129,16 @@ class PoolGradKernel : public framework::OpKernel {
case 3: { case 3: {
if (pooling_type == "max") { if (pooling_type == "max") {
paddle::operators::math::Pool3dBackwardFunctor< paddle::operators::math::Pool3dBackwardFunctor<
Place, paddle::operators::math::pool::maxPool<T>, T> Place, paddle::operators::math::pool::maxPoolGrad<T>, T>
pool3d_backward; pool3d_backward;
paddle::operators::math::pool::maxPool<T> pool_process; paddle::operators::math::pool::maxPoolGrad<T> pool_process;
pool3d_backward(context.device_context(), *in_X, *in_X_grad, *out, pool3d_backward(context.device_context(), *in_X, *in_X_grad, *out,
*out_grad, ksize, strides, paddings, pool_process); *out_grad, ksize, strides, paddings, pool_process);
} else if (pooling_type == "ave") { } else if (pooling_type == "avg") {
paddle::operators::math::Pool3dBackwardFunctor< paddle::operators::math::Pool3dBackwardFunctor<
Place, paddle::operators::math::pool::avePool<T>, T> Place, paddle::operators::math::pool::avgPoolGrad<T>, T>
pool3d_backward; pool3d_backward;
paddle::operators::math::pool::avePool<T> pool_process; paddle::operators::math::pool::avgPoolGrad<T> pool_process;
pool3d_backward(context.device_context(), *in_X, *in_X_grad, *out, pool3d_backward(context.device_context(), *in_X, *in_X_grad, *out,
*out_grad, ksize, strides, paddings, pool_process); *out_grad, ksize, strides, paddings, pool_process);
} }
......
...@@ -23,7 +23,7 @@ def max_pool2D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0): ...@@ -23,7 +23,7 @@ def max_pool2D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0):
return out return out
def ave_pool2D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0): def avg_pool2D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0):
N, C, H, W = x.shape N, C, H, W = x.shape
if global_pool == 1: if global_pool == 1:
...@@ -72,8 +72,8 @@ class TestPool2d_Op(OpTest): ...@@ -72,8 +72,8 @@ class TestPool2d_Op(OpTest):
def initTestCase(self): def initTestCase(self):
self.global_pool = 0 self.global_pool = 0
self.pool_type = "ave" self.pool_type = "avg"
self.pool2D_forward_naive = ave_pool2D_forward_naive self.pool2D_forward_naive = avg_pool2D_forward_naive
self.shape = [2, 3, 5, 5] self.shape = [2, 3, 5, 5]
self.ksize = [3, 3] self.ksize = [3, 3]
self.strides = [1, 1] self.strides = [1, 1]
...@@ -84,8 +84,8 @@ class TestCase1(TestPool2d_Op): ...@@ -84,8 +84,8 @@ class TestCase1(TestPool2d_Op):
def initTestCase(self): def initTestCase(self):
self.global_pool = 0 self.global_pool = 0
self.op_type = "pool2d" self.op_type = "pool2d"
self.pool_type = "ave" self.pool_type = "avg"
self.pool2D_forward_naive = ave_pool2D_forward_naive self.pool2D_forward_naive = avg_pool2D_forward_naive
self.shape = [2, 3, 5, 5] self.shape = [2, 3, 5, 5]
self.ksize = [3, 3] self.ksize = [3, 3]
self.strides = [1, 1] self.strides = [1, 1]
...@@ -96,8 +96,8 @@ class TestCase2(TestPool2d_Op): ...@@ -96,8 +96,8 @@ class TestCase2(TestPool2d_Op):
def initTestCase(self): def initTestCase(self):
self.global_pool = 1 self.global_pool = 1
self.op_type = "pool2d" self.op_type = "pool2d"
self.pool_type = "ave" self.pool_type = "avg"
self.pool2D_forward_naive = ave_pool2D_forward_naive self.pool2D_forward_naive = avg_pool2D_forward_naive
self.shape = [2, 3, 5, 5] self.shape = [2, 3, 5, 5]
self.ksize = [3, 3] self.ksize = [3, 3]
self.strides = [1, 1] self.strides = [1, 1]
......
...@@ -27,7 +27,7 @@ def max_pool3D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0): ...@@ -27,7 +27,7 @@ def max_pool3D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0):
return out return out
def ave_pool3D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0): def avg_pool3D_forward_naive(x, ksize, strides, paddings=[0, 0], global_pool=0):
N, C, D, H, W = x.shape N, C, D, H, W = x.shape
if global_pool == 1: if global_pool == 1:
...@@ -80,8 +80,8 @@ class TestPool3d_Op(OpTest): ...@@ -80,8 +80,8 @@ class TestPool3d_Op(OpTest):
def initTestCase(self): def initTestCase(self):
self.global_pool = 0 self.global_pool = 0
self.pool_type = "ave" self.pool_type = "avg"
self.pool3D_forward_naive = ave_pool3D_forward_naive self.pool3D_forward_naive = avg_pool3D_forward_naive
self.shape = [2, 3, 5, 5, 5] self.shape = [2, 3, 5, 5, 5]
self.ksize = [3, 3, 3] self.ksize = [3, 3, 3]
self.strides = [1, 1, 1] self.strides = [1, 1, 1]
...@@ -92,8 +92,8 @@ class TestCase1(TestPool3d_Op): ...@@ -92,8 +92,8 @@ class TestCase1(TestPool3d_Op):
def initTestCase(self): def initTestCase(self):
self.global_pool = 0 self.global_pool = 0
self.op_type = "pool3d" self.op_type = "pool3d"
self.pool_type = "ave" self.pool_type = "avg"
self.pool3D_forward_naive = ave_pool3D_forward_naive self.pool3D_forward_naive = avg_pool3D_forward_naive
self.shape = [2, 3, 7, 7, 7] self.shape = [2, 3, 7, 7, 7]
self.ksize = [3, 3, 3] self.ksize = [3, 3, 3]
self.strides = [1, 1, 1] self.strides = [1, 1, 1]
...@@ -104,8 +104,8 @@ class TestCase2(TestPool3d_Op): ...@@ -104,8 +104,8 @@ class TestCase2(TestPool3d_Op):
def initTestCase(self): def initTestCase(self):
self.global_pool = 1 self.global_pool = 1
self.op_type = "pool3d" self.op_type = "pool3d"
self.pool_type = "ave" self.pool_type = "avg"
self.pool3D_forward_naive = ave_pool3D_forward_naive self.pool3D_forward_naive = avg_pool3D_forward_naive
self.shape = [2, 3, 7, 7, 7] self.shape = [2, 3, 7, 7, 7]
self.ksize = [3, 3, 3] self.ksize = [3, 3, 3]
self.strides = [1, 1, 1] self.strides = [1, 1, 1]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册