未验证 提交 d9366194 编写于 作者: S Shang Zhizhou 提交者: GitHub

fix bug sequececonv_eltadd_relu_fuse_pass (#27404)

* fix bug sequececonv_eltadd_relu_fuse_pass, output error when sequence_conv's padding_start > 0

* fix seqconv_eltadd_relu_fuse_pass unitest error
上级 37f7414f
......@@ -16,6 +16,7 @@
#include <string>
#include <unordered_set>
#include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/framework/op_version_registry.h"
namespace paddle {
namespace framework {
......@@ -98,3 +99,9 @@ void SeqConvEltAddReluFusePass::ApplyImpl(ir::Graph* graph) const {
REGISTER_PASS(seqconv_eltadd_relu_fuse_pass,
paddle::framework::ir::SeqConvEltAddReluFusePass);
REGISTER_PASS_CAPABILITY(seqconv_eltadd_relu_fuse_pass)
.AddCombination(
paddle::framework::compatible::OpVersionComparatorCombination()
.EQ("sequence_conv", 0)
.EQ("elementwise_add", 0)
.EQ("relu", 0));
......@@ -192,6 +192,9 @@ class FusionSeqConvEltAddReluKernel : public framework::OpKernel<T> {
copy_size += src_mat_w_sz;
}
// fill data
if (context_start > 0) {
src_data += context_start * src_mat_w;
}
for (int j = 0; j < seq_len - up_pad - down_pad; ++j) {
std::memcpy(dst_data, src_data, copy_size);
dst_data += col_mat_w;
......@@ -201,18 +204,15 @@ class FusionSeqConvEltAddReluKernel : public framework::OpKernel<T> {
std::memset(dst_data, 0, down_pad * col_mat_w_sz);
copy_size -= src_mat_w_sz;
for (int j = 0; j < down_pad; ++j) {
if (copy_size < 0) {
copy_size = 0;
}
std::memcpy(dst_data, src_data, copy_size);
dst_data += col_mat_w;
src_data += src_mat_w;
copy_size -= src_mat_w_sz;
}
} else {
PADDLE_ENFORCE_GE(context_length, up_pad + down_pad + 1,
platform::errors::InvalidArgument(
"context length must be bigger or equal than "
"up_pad + down_pad + 1, but received context "
"length is: %d, up_pad is: %d, down_pad is: %d.",
context_length, up_pad, down_pad));
std::memset(dst_data, 0, seq_len * col_mat_w_sz);
dst_data = dst_data + up_pad * src_mat_w;
int zero_sz = up_pad * src_mat_w_sz;
......@@ -226,9 +226,15 @@ class FusionSeqConvEltAddReluKernel : public framework::OpKernel<T> {
// from bottom
dst_data = col_data + ed * col_mat_w;
src_data = x_data + st * src_mat_w;
if (context_start > 0) {
src_data += context_start * src_mat_w;
}
zero_sz = down_pad * src_mat_w_sz;
for (int j = 1; j <= std::min(down_pad, seq_len); ++j) {
int copy_size = std::min(cur_src_sz, col_mat_w_sz - zero_sz);
if (copy_size < 0) {
copy_size = 0;
}
std::memcpy(dst_data - (zero_sz + copy_size) / sizeof(T),
src_data + std::max(seq_len - j - up_pad, 0) * src_mat_w,
copy_size);
......
# 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
from inference_pass_test import InferencePassTest
import paddle.fluid as fluid
import paddle.fluid.core as core
from paddle.fluid.core import AnalysisConfig
from paddle.fluid.core import PassVersionChecker
class SeqconvEltaddReluFusePassTest(InferencePassTest):
def setUp(self):
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(name="data", shape=[100, 100], dtype="float32")
param_attr = fluid.ParamAttr(
initializer=fluid.initializer.Xavier(uniform=False),
learning_rate=0.001)
conv_out = fluid.layers.sequence_conv(
input=data,
num_filters=16,
filter_size=4,
padding_start=0,
act="relu",
bias_attr=param_attr)
np_data = np.random.random((80, 100)).astype('float32')
x_lod_tensor = fluid.create_lod_tensor(np_data, [[10, 20, 30, 20]],
fluid.CPUPlace())
self.feeds = {"data": x_lod_tensor}
self.fetch_list = [conv_out]
self.enable_mkldnn = True
def test_check_output(self):
self.check_output()
self.assertTrue(
PassVersionChecker.IsCompatible('seqconv_eltadd_relu_fuse_pass'))
class SeqconvEltaddReluFusePassTestPaddingStartPositive(InferencePassTest):
def setUp(self):
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(name="data", shape=[-1, 4], dtype="float32")
param_attr = fluid.ParamAttr(
initializer=fluid.initializer.Xavier(uniform=False),
learning_rate=0.001)
conv_out = fluid.layers.sequence_conv(
input=data,
num_filters=16,
filter_size=3,
padding_start=2,
act="relu",
bias_attr=param_attr)
np_data = np.array([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3],
[4, 4, 4, 4], [5, 5, 5, 5], [6, 6, 6, 6],
[7, 7, 7, 7]]).astype('float32')
x_lod_tensor = fluid.create_lod_tensor(np_data, [[5, 2]],
fluid.CPUPlace())
self.feeds = {"data": x_lod_tensor}
self.fetch_list = [conv_out]
self.enable_mkldnn = True
def test_check_output(self):
self.check_output()
self.assertTrue(
PassVersionChecker.IsCompatible('seqconv_eltadd_relu_fuse_pass'))
class SeqconvEltaddReluFusePassTestPaddingStartNegative(InferencePassTest):
def setUp(self):
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(name="data", shape=[100, 100], dtype="float32")
param_attr = fluid.ParamAttr(
initializer=fluid.initializer.Xavier(uniform=False),
learning_rate=0.001)
conv_out = fluid.layers.sequence_conv(
input=data,
num_filters=16,
filter_size=4,
padding_start=-1,
act="relu",
bias_attr=param_attr)
np_data = np.random.random((80, 100)).astype('float32')
x_lod_tensor = fluid.create_lod_tensor(np_data, [[10, 20, 30, 20]],
fluid.CPUPlace())
self.feeds = {"data": x_lod_tensor}
self.fetch_list = [conv_out]
self.enable_mkldnn = True
def test_check_output(self):
self.check_output()
self.assertTrue(
PassVersionChecker.IsCompatible('seqconv_eltadd_relu_fuse_pass'))
class SeqconvEltaddReluFusePassTestPaddingStartNone(InferencePassTest):
def setUp(self):
with fluid.program_guard(self.main_program, self.startup_program):
data = fluid.data(name="data", shape=[100, 100], dtype="float32")
param_attr = fluid.ParamAttr(
initializer=fluid.initializer.Xavier(uniform=False),
learning_rate=0.001)
conv_out = fluid.layers.sequence_conv(
input=data,
num_filters=16,
filter_size=4,
act="relu",
bias_attr=param_attr)
np_data = np.random.random((80, 100)).astype('float32')
x_lod_tensor = fluid.create_lod_tensor(np_data, [[10, 20, 30, 20]],
fluid.CPUPlace())
self.feeds = {"data": x_lod_tensor}
self.fetch_list = [conv_out]
self.enable_mkldnn = True
def test_check_output(self):
self.check_output()
self.assertTrue(
PassVersionChecker.IsCompatible('seqconv_eltadd_relu_fuse_pass'))
if __name__ == "__main__":
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册