diff --git a/paddle/fluid/framework/ir/mkldnn/conv_concat_relu_mkldnn_fuse_pass.cc b/paddle/fluid/framework/ir/mkldnn/conv_concat_relu_mkldnn_fuse_pass.cc index 5fbfef08b7209bc695f90ff9188b8e9a7db029a7..0947f4756ad78c0e2b4b255e96f75ea440b022ef 100644 --- a/paddle/fluid/framework/ir/mkldnn/conv_concat_relu_mkldnn_fuse_pass.cc +++ b/paddle/fluid/framework/ir/mkldnn/conv_concat_relu_mkldnn_fuse_pass.cc @@ -59,7 +59,7 @@ ConvConcatReLUFusePass::ConvConcatReLUFusePass() { .IsType>() .End() .AddAttr("data_format") - .IsStringIn({"NCHW", "NHWC", "AnyLayout"}) + .IsStringIn({"NCHW"}) .End(); AddOpCompat(OpCompat("concat")) diff --git a/python/paddle/fluid/tests/unittests/ir/inference/test_mkldnn_conv_concat_relu_mkldnn_fuse_pass.py b/python/paddle/fluid/tests/unittests/ir/inference/test_mkldnn_conv_concat_relu_mkldnn_fuse_pass.py index 45097f6b8191d045d0665d7478e4090c0ae20cb3..3c823c73d37943cb9040522b21bdf3f642c10bea 100644 --- a/python/paddle/fluid/tests/unittests/ir/inference/test_mkldnn_conv_concat_relu_mkldnn_fuse_pass.py +++ b/python/paddle/fluid/tests/unittests/ir/inference/test_mkldnn_conv_concat_relu_mkldnn_fuse_pass.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. +# Copyright (c) 2021 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. @@ -12,80 +12,147 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function - -import unittest +from auto_scan_test import PassAutoScanTest, SkipReasons +from program_config import TensorConfig, ProgramConfig 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 ConvConcatReluMkldnnFusePassTest_0(InferencePassTest): - def setUp(self): - self.set_params() - with fluid.program_guard(self.main_program, self.startup_program): - data_1 = fluid.data( - name="data_1", shape=[-1, 3, 100, 100], dtype="float32") - data_2 = fluid.data( - name="data_2", shape=[-1, 3, 100, 100], dtype="float32") - conv_1 = fluid.layers.conv2d( - data_1, - num_filters=self.conv1_num_filters, - filter_size=self.conv1_filter_size, - padding=self.conv1_padding, - bias_attr=self.conv1_bias_attr) - conv_2 = fluid.layers.conv2d( - data_2, - num_filters=self.conv2_num_filters, - filter_size=self.conv2_filter_size, - padding=self.conv2_padding, - bias_attr=self.conv2_bias_attr) - concat = fluid.layers.concat( - [conv_1, conv_2], axis=self.concat_axis) - out = fluid.layers.relu(concat) - - self.feeds = { - "data_1": np.random.random((1, 3, 100, 100)).astype("float32"), - "data_2": np.random.random((1, 3, 100, 100)).astype("float32") - } - self.fetch_list = [out] - self.enable_mkldnn = True - - def set_params(self): - self.conv1_num_filters = 3 - self.conv1_filter_size = 3 - self.conv1_padding = 0 - self.conv1_bias_attr = False - self.conv2_num_filters = 3 - self.conv2_filter_size = 3 - self.conv2_padding = 0 - self.conv2_bias_attr = False - self.concat_axis = 0 - self.pass_name = "conv_concat_relu_mkldnn_fuse_pass" - - def test_check_output(self): - use_gpu = False - self.check_output_with_option(use_gpu) - - def test_pass_compatible(self): - self.assertTrue(PassVersionChecker.IsCompatible(self.pass_name)) - - -class ConvConcatReluMkldnnFusePassTest_1(ConvConcatReluMkldnnFusePassTest_0): - def set_params(self): - self.conv1_num_filters = 3 - self.conv1_filter_size = 3 - self.conv1_padding = 0 - self.conv1_bias_attr = False - self.conv2_num_filters = 5 - self.conv2_filter_size = 5 - self.conv2_padding = 1 - self.conv2_bias_attr = True - self.concat_axis = 1 - self.pass_name = "conv_concat_relu_mkldnn_fuse_pass" +import paddle.inference as paddle_infer +from functools import partial +from typing import Optional, List, Callable, Dict, Any, Set +import unittest + +import hypothesis +from hypothesis import given, settings, seed, example, assume +import hypothesis.strategies as st + + +class TestConvConcatReluMkldnnFusePass(PassAutoScanTest): + def is_program_valid(self, program_config: ProgramConfig) -> bool: + attrs = [ + program_config.ops[i].attrs + for i in range(len(program_config.ops)) + ] + # If the problem has been fixed, the judgment + # needs to be deleted!!! + if attrs[0]['data_format'] == "NHWC": + return False + + return True + + def sample_program_config(self, draw): + data_format = draw(st.sampled_from(["NCHW", "NHWC"])) + dilations = draw(st.sampled_from([[1, 1], [2, 2], [1, 2]])) + padding_algorithm = draw(st.sampled_from(["EXPLICIT", "SAME", "VALID"])) + groups = draw(st.sampled_from([1, 2, 4])) + paddings = draw(st.sampled_from([[0, 3], [1, 2, 3, 4]])) + strides = draw(st.sampled_from([[1, 1], [2, 2], [1, 2]])) + axis = draw(st.sampled_from([0])) + batch_size = draw(st.integers(min_value=1, max_value=4)) + + def generate_input(attrs): + if attrs[0]['data_format'] == "NCHW": + return np.random.random( + [attrs[2]['batch_size'], 48, 64, 64]).astype(np.float32) + else: + return np.random.random( + [attrs[2]['batch_size'], 64, 64, 48]).astype(np.float32) + + def generate_weight(): + return np.random.random( + [16, int(48 / groups), 3, 3]).astype(np.float32) + + attrs = [{ + "data_format": data_format, + "dilations": dilations, + "padding_algorithm": padding_algorithm, + "groups": groups, + "paddings": paddings, + "strides": strides + }, { + "axis": axis + }, { + 'batch_size': batch_size + }] + + ops_config = [{ + "op_type": "conv2d", + "op_inputs": { + "Input": ["input_data1"], + "Filter": ["input_weight"] + }, + "op_outputs": { + "Output": ["conv1_output"] + }, + "op_attrs": { + "data_format": attrs[0]['data_format'], + "dilations": attrs[0]['dilations'], + "padding_algorithm": attrs[0]['padding_algorithm'], + "groups": attrs[0]['groups'], + "paddings": attrs[0]['paddings'], + "strides": attrs[0]['strides'] + } + }, { + "op_type": "conv2d", + "op_inputs": { + "Input": ["input_data2"], + "Filter": ["input_weight"] + }, + "op_outputs": { + "Output": ["conv2_output"] + }, + "op_attrs": { + "data_format": attrs[0]['data_format'], + "dilations": attrs[0]['dilations'], + "padding_algorithm": attrs[0]['padding_algorithm'], + "groups": attrs[0]['groups'], + "paddings": attrs[0]['paddings'], + "strides": attrs[0]['strides'] + } + }, { + "op_type": "concat", + "op_inputs": { + "X": ["conv1_output", "conv2_output"] + }, + "op_outputs": { + "Out": ["concat_output"] + }, + "op_attrs": { + 'axis': attrs[1]['axis'] + } + }, { + "op_type": "relu", + "op_inputs": { + "X": ["concat_output"] + }, + "op_outputs": { + "Out": ["relu_output"] + }, + "op_attrs": {} + }] + + ops = self.generate_op_config(ops_config) + + program_config = ProgramConfig( + ops=ops, + weights={ + "input_weight": TensorConfig(data_gen=partial(generate_weight)) + }, + inputs={ + "input_data1": + TensorConfig(data_gen=partial(generate_input, attrs)), + "input_data2": + TensorConfig(data_gen=partial(generate_input, attrs)) + }, + outputs=["relu_output"]) + + return program_config + + def sample_predictor_configs(self, program_config): + config = self.create_inference_config(use_mkldnn=True) + yield config, ["conv2d", "conv2d", "concat"], (1e-5, 1e-5) + + def test(self): + self.run_and_statis( + quant=False, passes=["conv_concat_relu_mkldnn_fuse_pass"]) if __name__ == "__main__":