未验证 提交 b3787d1b 编写于 作者: W wawltor 提交者: GitHub

add the matmul v2 grad kernel

* add the matmul v2 grad kernel

* relief the test case time

* update the test case for the matmul double grad

* remove the unsed code for the matmul double grad

* update the test case for the double grad matmul

* remove the unused code in dot
上级 c727ec4a
...@@ -228,6 +228,59 @@ class MatMulV2GradOpMaker : public framework::SingleGradOpMaker<T> { ...@@ -228,6 +228,59 @@ class MatMulV2GradOpMaker : public framework::SingleGradOpMaker<T> {
} }
}; };
class MatMulV2OpDoubleGrad : public framework::OperatorWithKernel {
public:
using framework::OperatorWithKernel::OperatorWithKernel;
protected:
void InferShape(framework::InferShapeContext* context) const override {
OP_INOUT_CHECK(context->HasInput("X"), "Input", "X", "matmul");
OP_INOUT_CHECK(context->HasInput("Y"), "Input", "Y", "matmul");
OP_INOUT_CHECK(context->HasInput("DOut"), "Input", "DOut", "matmul");
if (context->HasOutput("DX") && context->HasInput("DDY")) {
context->ShareDim("X", "DX");
}
if (context->HasOutput("DY") && context->HasInput("DDX")) {
context->ShareDim("Y", "DY");
}
if (context->HasOutput("DDOut") &&
(context->HasInput("DDY") || context->HasInput("DDX"))) {
context->ShareDim("DOut", "DDOut");
}
}
};
template <typename T>
class MatMulV2OpDoubleGradMaker : public framework::SingleGradOpMaker<T> {
public:
using framework::SingleGradOpMaker<T>::SingleGradOpMaker;
protected:
void Apply(GradOpPtr<T> op) const override {
op->SetType("matmul_v2_grad_grad");
op->SetInput("X", this->Input("X"));
op->SetInput("Y", this->Input("Y"));
op->SetInput("DOut", this->Input(framework::GradVarName("Out")));
op->SetInput("DDX", this->OutputGrad(framework::GradVarName("X")));
op->SetInput("DDY", this->OutputGrad(framework::GradVarName("Y")));
auto ddx = this->OutputGrad(framework::GradVarName("X"));
auto ddy = this->OutputGrad(framework::GradVarName("Y"));
if (!ddx.empty() || !ddy.empty()) {
op->SetOutput("DDOut", this->InputGrad(framework::GradVarName("Out")));
}
op->SetOutput("DX",
ddy.empty() ? this->EmptyInputGrad() : this->InputGrad("X"));
op->SetOutput("DY",
ddx.empty() ? this->EmptyInputGrad() : this->InputGrad("Y"));
op->SetAttrMap(this->Attrs());
}
};
} // namespace operators } // namespace operators
} // namespace paddle } // namespace paddle
...@@ -236,7 +289,11 @@ REGISTER_OPERATOR(matmul_v2, ops::MatMulV2Op, ops::MatMulV2OpMaker, ...@@ -236,7 +289,11 @@ REGISTER_OPERATOR(matmul_v2, ops::MatMulV2Op, ops::MatMulV2OpMaker,
ops::MatMulV2GradOpMaker<paddle::framework::OpDesc>, ops::MatMulV2GradOpMaker<paddle::framework::OpDesc>,
ops::MatMulV2GradOpMaker<paddle::imperative::OpBase>); ops::MatMulV2GradOpMaker<paddle::imperative::OpBase>);
REGISTER_OPERATOR(matmul_v2_grad, ops::MatMulV2OpGrad); REGISTER_OPERATOR(matmul_v2_grad, ops::MatMulV2OpGrad,
ops::MatMulV2OpDoubleGradMaker<paddle::framework::OpDesc>,
ops::MatMulV2OpDoubleGradMaker<paddle::imperative::OpBase>);
REGISTER_OPERATOR(matmul_v2_grad_grad, ops::MatMulV2OpDoubleGrad);
REGISTER_OP_CPU_KERNEL( REGISTER_OP_CPU_KERNEL(
matmul_v2, ops::MatMulV2Kernel<paddle::platform::CPUDeviceContext, float>, matmul_v2, ops::MatMulV2Kernel<paddle::platform::CPUDeviceContext, float>,
...@@ -254,3 +311,11 @@ REGISTER_OP_CPU_KERNEL( ...@@ -254,3 +311,11 @@ REGISTER_OP_CPU_KERNEL(
paddle::platform::complex<float>>, paddle::platform::complex<float>>,
ops::MatMulV2GradKernel<paddle::platform::CPUDeviceContext, ops::MatMulV2GradKernel<paddle::platform::CPUDeviceContext,
paddle::platform::complex<double>>); paddle::platform::complex<double>>);
REGISTER_OP_CPU_KERNEL(
matmul_v2_grad_grad,
ops::MatMulV2DoubleGradKernel<paddle::platform::CPUDeviceContext, float>,
ops::MatMulV2DoubleGradKernel<paddle::platform::CPUDeviceContext, double>,
ops::MatMulV2DoubleGradKernel<paddle::platform::CPUDeviceContext,
paddle::platform::complex<float>>,
ops::MatMulV2DoubleGradKernel<paddle::platform::CPUDeviceContext,
paddle::platform::complex<double>>);
...@@ -30,3 +30,13 @@ REGISTER_OP_CUDA_KERNEL( ...@@ -30,3 +30,13 @@ REGISTER_OP_CUDA_KERNEL(
ops::MatMulV2GradKernel<plf::CUDADeviceContext, plf::float16>, ops::MatMulV2GradKernel<plf::CUDADeviceContext, plf::float16>,
ops::MatMulV2GradKernel<plf::CUDADeviceContext, plf::complex<float>>, ops::MatMulV2GradKernel<plf::CUDADeviceContext, plf::complex<float>>,
ops::MatMulV2GradKernel<plf::CUDADeviceContext, plf::complex<double>>); ops::MatMulV2GradKernel<plf::CUDADeviceContext, plf::complex<double>>);
REGISTER_OP_CUDA_KERNEL(
matmul_v2_grad_grad,
ops::MatMulV2DoubleGradKernel<paddle::platform::CUDADeviceContext, float>,
ops::MatMulV2DoubleGradKernel<paddle::platform::CUDADeviceContext, double>,
ops::MatMulV2DoubleGradKernel<plf::CUDADeviceContext, plf::float16>,
ops::MatMulV2DoubleGradKernel<paddle::platform::CUDADeviceContext,
paddle::platform::complex<float>>,
ops::MatMulV2DoubleGradKernel<paddle::platform::CUDADeviceContext,
paddle::platform::complex<double>>);
# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# 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.
from __future__ import print_function
import unittest
import numpy as np
import paddle
import paddle.fluid as fluid
import paddle.fluid.layers as layers
import paddle.fluid.core as core
import gradient_checker
from decorator_helper import prog_scope
paddle.enable_static()
class TestMatmulDoubleGradCheck(unittest.TestCase):
def setUp(self):
self.init_test()
def init_test(self):
self.x_shape = [2]
self.y_shape = [2]
self.transpose_x = False
self.transpose_y = False
@prog_scope()
def func(self, place):
eps = 0.005
dtype = np.float64
typename = "float64"
x = paddle.static.create_parameter(
dtype=typename, shape=self.x_shape, name='x')
y = paddle.static.create_parameter(
dtype=typename, shape=self.y_shape, name='y')
out = paddle.matmul(
x, y, self.transpose_x, self.transpose_y, name='out')
x_arr = np.random.uniform(-1, 1, self.x_shape).astype(dtype)
y_arr = np.random.uniform(-1, 1, self.y_shape).astype(dtype)
gradient_checker.double_grad_check(
[x, y], out, x_init=[x_arr, y_arr], place=place, eps=eps)
def test_grad(self):
places = [fluid.CPUPlace()]
if core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for p in places:
self.func(p)
class TestMatmulDoubleGradCheckCase1(TestMatmulDoubleGradCheck):
def init_test(self):
self.x_shape = [2, 3]
self.y_shape = [3, 2]
self.transpose_x = True
self.transpose_y = True
def test_grad(self):
places = [fluid.CPUPlace()]
if core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for p in places:
self.func(p)
class TestMatmulDoubleGradCheck2(unittest.TestCase):
def setUp(self):
self.init_test()
def init_test(self):
self.x_shape = [2, 4, 3]
self.y_shape = [2, 4, 5]
self.transpose_x = True
self.transpose_y = False
@prog_scope()
def func(self, place):
eps = 0.005
dtype = np.float64
typename = "float64"
x = paddle.static.create_parameter(
dtype=typename, shape=self.x_shape, name='x')
y = paddle.static.create_parameter(
dtype=typename, shape=self.y_shape, name='y')
out = paddle.matmul(
x, y, self.transpose_x, self.transpose_y, name='out')
x_arr = np.random.uniform(-1, 1, self.x_shape).astype(dtype)
y_arr = np.random.uniform(-1, 1, self.y_shape).astype(dtype)
gradient_checker.double_grad_check(
[x, y], out, x_init=[x_arr, y_arr], place=place, eps=eps)
def test_grad(self):
places = [fluid.CPUPlace()]
if core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for p in places:
self.func(p)
class TestMatmulDoubleGradCheckCase3(unittest.TestCase):
def setUp(self):
self.init_test()
def init_test(self):
self.x_shape = [1, 1, 4, 25]
self.y_shape = [1, 2, 25, 4]
self.transpose_x = False
self.transpose_y = False
@prog_scope()
def func(self, place):
eps = 0.005
dtype = np.float64
typename = "float64"
x = paddle.static.create_parameter(
dtype=typename, shape=self.x_shape, name='x')
y = paddle.static.create_parameter(
dtype=typename, shape=self.y_shape, name='y')
out = paddle.matmul(
x, y, self.transpose_x, self.transpose_y, name='out')
x_arr = np.random.uniform(-1, 1, self.x_shape).astype(dtype)
y_arr = np.random.uniform(-1, 1, self.y_shape).astype(dtype)
gradient_checker.double_grad_check(
[x, y], out, x_init=[x_arr, y_arr], place=place, eps=eps)
def test_grad(self):
places = [fluid.CPUPlace()]
if core.is_compiled_with_cuda():
places.append(fluid.CUDAPlace(0))
for p in places:
self.func(p)
if __name__ == "__main__":
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册