test_conv2d_fusion_op.py 12.9 KB
Newer Older
Q
qingqing01 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#   Copyright (c) 2018 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.

import unittest

17
import numpy as np
Q
qingqing01 已提交
18 19 20
from op_test import OpTest
from test_conv2d_op import conv2d_forward_naive

21 22
import paddle.fluid.core as core

Q
qingqing01 已提交
23

24
def create_test_padding_SAME_class(parent):
25
    class TestPaddingSAMECase(parent):
26 27 28 29 30
        def init_paddings(self):
            self.pad = [0, 0]
            self.padding_algorithm = "SAME"

    cls_name = "{0}_{1}".format(parent.__name__, "PaddingSAMEOp")
31 32
    TestPaddingSAMECase.__name__ = cls_name
    globals()[cls_name] = TestPaddingSAMECase
33 34 35 36 37 38 39 40 41 42 43 44 45


def create_test_padding_VALID_class(parent):
    class TestPaddingVALIDCase(parent):
        def init_paddings(self):
            self.pad = [1, 1]
            self.padding_algorithm = "VALID"

    cls_name = "{0}_{1}".format(parent.__name__, "PaddingVALIDOp")
    TestPaddingVALIDCase.__name__ = cls_name
    globals()[cls_name] = TestPaddingVALIDCase


46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
def create_test_cudnn_channel_last_class(parent):
    @unittest.skipIf(
        not core.is_compiled_with_cuda(), "core is not compiled with CUDA"
    )
    class TestCudnnChannelLastCase(parent):
        def init_test_case(self):
            super().init_test_case()
            self.data_format = "NHWC"
            N, C, H, W = self.input_size
            self.input_size = [N, H, W, C]
            K1, K2, R, S = self.filter_size
            self.filter_size = [K1, R, S, K2]

        def test_check_output(self):
            print(self.attrs)
            if self.has_cuda():
                place = core.CUDAPlace(0)
                self.check_output_with_place(place, atol=1e-5)

    cls_name = "{0}_{1}".format(parent.__name__, "CudnnChannelLast")
    TestCudnnChannelLastCase.__name__ = cls_name
    globals()[cls_name] = TestCudnnChannelLastCase


C
cnn 已提交
70
class TestConv2DFusionOp(OpTest):
Q
qingqing01 已提交
71 72 73
    def setUp(self):
        self.op_type = "conv2d_fusion"
        self.exhaustive_search = False
74
        self.data_format = "NCHW"
Q
qingqing01 已提交
75 76 77
        self.dtype = np.float32
        self.activation = 'relu'
        self.add_residual_data = True
78
        self.split_channels = None
Q
qingqing01 已提交
79
        self.outputs = None
80
        self.padding_algorithm = "EXIPLICIT"
Q
qingqing01 已提交
81 82 83 84

        self.init_group()
        self.init_dilation()
        self.init_test_case()
85
        self.init_residual()
Q
qingqing01 已提交
86
        self.init_activation()
87
        self.init_paddings()
Q
qingqing01 已提交
88 89 90 91 92
        self.set_search_method()

        conv2d_param = {
            'stride': self.stride,
            'pad': self.pad,
93
            'dilation': self.dilations,
Q
qingqing01 已提交
94 95 96 97
        }

        input = np.random.random(self.input_size).astype(self.dtype)
        filter = np.random.random(self.filter_size).astype(self.dtype)
98
        bias = np.random.random(self.filter_size[0]).astype(self.dtype)
Q
qingqing01 已提交
99

100 101 102 103 104
        if self.data_format == "NHWC":
            filter_nchw = np.transpose(filter, [0, 3, 1, 2])
        else:
            filter_nchw = filter

105 106
        self.output, _, _, _, _ = conv2d_forward_naive(
            input,
107
            filter_nchw,
108 109 110 111 112
            self.groups,
            conv2d_param,
            self.padding_algorithm,
            self.data_format,
        )
113

114
        self.output = self.output.astype(self.dtype)
Q
qingqing01 已提交
115 116 117

        self.inputs = {
            'Input': OpTest.np_dtype_to_fluid_dtype(input),
118
            'Filter': OpTest.np_dtype_to_fluid_dtype(filter),
119
            'Bias': OpTest.np_dtype_to_fluid_dtype(bias),
Q
qingqing01 已提交
120 121 122
        }

        if self.add_residual_data:
Q
qingqing01 已提交
123
            residual_data = np.random.random(self.output.shape).astype(
124 125
                self.dtype
            )
Q
qingqing01 已提交
126
            self.inputs['ResidualData'] = OpTest.np_dtype_to_fluid_dtype(
127 128
                residual_data
            )
Q
qingqing01 已提交
129
            self.output += residual_data
Q
qingqing01 已提交
130

131
        # Add bias
132 133 134 135
        if self.data_format == "NCHW":
            self.output = self.output + bias.reshape((1, bias.size, 1, 1))
        else:
            self.output = self.output + bias.reshape((1, 1, 1, bias.size))
Q
qingqing01 已提交
136 137 138

        assert self.activation in ['relu', 'identity']
        if self.activation == 'relu':
Q
qingqing01 已提交
139
            self.output = np.maximum(self.output, 0)
Q
qingqing01 已提交
140 141 142 143 144 145 146 147

        self.attrs = {
            'strides': self.stride,
            'paddings': self.pad,
            'groups': self.groups,
            'dilations': self.dilations,
            'data_format': self.data_format,
            'exhaustive_search': self.exhaustive_search,
Q
qingqing01 已提交
148
            'activation': self.activation,
149
            'padding_algorithm': self.padding_algorithm,
Q
qingqing01 已提交
150
        }
151 152 153
        if self.split_channels is not None:
            self.attrs['split_channels'] = self.split_channels

Q
qingqing01 已提交
154 155 156
        self.outputs = {'Output': self.output}

        self.set_outputs()
Q
qingqing01 已提交
157

158
    def has_cuda(self):
Q
qingqing01 已提交
159 160 161
        return core.is_compiled_with_cuda()

    def test_check_output(self):
162
        if self.has_cuda():
Q
qingqing01 已提交
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
            place = core.CUDAPlace(0)
            self.check_output_with_place(place, atol=1e-5)

    def init_test_case(self):
        self.pad = [0, 0]
        self.stride = [1, 1]
        self.input_size = [2, 3, 5, 5]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 3, 3]

    def init_dilation(self):
        self.dilations = [1, 1]

    def init_group(self):
        self.groups = 1

180
    def init_residual(self):
Q
qingqing01 已提交
181 182 183 184 185 186 187 188
        self.add_residual_data = True

    def init_activation(self):
        self.activation = 'relu'

    def set_search_method(self):
        self.exhaustive_search = False

Q
qingqing01 已提交
189 190 191
    def set_outputs(self):
        pass

192 193 194 195
    def init_paddings(self):
        self.pad = [0, 0]
        self.padding_algorithm = "EXPLICIT"

Q
qingqing01 已提交
196

C
cnn 已提交
197
class TestWithoutResidual(TestConv2DFusionOp):
198
    def init_residual(self):
Q
qingqing01 已提交
199 200 201
        self.add_residual_data = False


C
cnn 已提交
202
class TestIdentityActivation(TestConv2DFusionOp):
Q
qingqing01 已提交
203 204 205 206
    def init_activation(self):
        self.activation = 'identity'


Z
zhangchunle 已提交
207
class TestIdentityActivation1(TestConv2DFusionOp):
208 209 210 211 212
    def init_activation(self):
        self.activation = 'identity'
        self.add_residual_data = False


C
cnn 已提交
213
class TestWithGroup(TestConv2DFusionOp):
Q
qingqing01 已提交
214 215 216 217
    def init_group(self):
        self.groups = 3


C
cnn 已提交
218
class TestWithDilation(TestConv2DFusionOp):
Q
qingqing01 已提交
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    def init_test_case(self):
        self.pad = [0, 0]
        self.stride = [1, 1]
        self.input_size = [2, 3, 10, 10]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 3, 3]

    def init_dilation(self):
        self.dilations = [2, 2]

    def init_group(self):
        self.groups = 3


C
cnn 已提交
234
class TestCUDNNExhaustiveSearch(TestConv2DFusionOp):
Q
qingqing01 已提交
235 236 237 238
    def set_search_method(self):
        self.exhaustive_search = True


C
cnn 已提交
239
class TestMultipleOutputs(TestConv2DFusionOp):
Q
qingqing01 已提交
240 241 242 243 244 245 246
    def init_test_case(self):
        self.pad = [1, 1]
        self.stride = [1, 1]
        self.input_size = [1, 32, 17, 17]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [126, f_c, 3, 3]
247
        self.split_channels = [84, 42]
Q
qingqing01 已提交
248 249 250 251 252 253 254

    def set_outputs(self):
        out1 = self.output[:, 0:84, :, :]
        out2 = self.output[:, 84:126, :, :]
        self.outputs['Outputs'] = [('out1', out1), ('out2', out2)]


C
cnn 已提交
255
class TestAsyPadding(TestConv2DFusionOp):
256 257 258 259 260
    def init_paddings(self):
        self.pad = [0, 0, 1, 2]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
261
class TestWithPad_AsyPadding(TestConv2DFusionOp):
262 263 264 265 266 267 268 269 270 271 272 273
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [2, 3, 10, 10]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 3, 3]

    def init_paddings(self):
        self.pad = [2, 1, 3, 2]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
274
class TestWithStride_AsyPadding(TestConv2DFusionOp):
275 276 277 278 279 280 281 282 283 284 285 286
    def init_test_case(self):
        self.stride = [2, 2]
        self.input_size = [2, 3, 6, 6]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 3, 3]

    def init_paddings(self):
        self.pad = [2, 1, 3, 2]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
287
class TestWith1x1_AsyPadding(TestConv2DFusionOp):
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [2, 3, 5, 5]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 1, 1]

    def init_group(self):
        self.groups = 3

    def init_paddings(self):
        self.pad = [2, 2, 4, 0]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
303
class TestWithGroup_AsyPadding(TestConv2DFusionOp):
304 305 306 307
    def init_group(self):
        self.groups = 3


C
cnn 已提交
308
class TestWithDepthWise3x3_AsyPadding(TestConv2DFusionOp):
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [3, 4, 10, 10]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [8, f_c, 3, 3]

    def init_dilation(self):
        self.dilations = [2, 2]

    def init_group(self):
        self.groups = 4

    def init_paddings(self):
        self.pad = [1, 3, 2, 1]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
327
class TestWithDepthWise5x5_AsyPadding(TestConv2DFusionOp):
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [2, 4, 10, 10]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [8, f_c, 5, 5]

    def init_group(self):
        self.groups = 4

    def init_paddings(self):
        self.pad = [0, 1, 1, 0]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
343
class TestWithDepthWise7x7_AsyPadding(TestConv2DFusionOp):
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
    def init_test_case(self):
        self.stride = [2, 2]
        self.input_size = [2, 8, 10, 10]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [16, f_c, 7, 7]

    def init_group(self):
        self.groups = 8

    def init_paddings(self):
        self.pad = [1, 3, 4, 1]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
359
class TestWithDilation_AsyPadding(TestConv2DFusionOp):
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [2, 3, 10, 10]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 3, 3]

    def init_dilation(self):
        self.dilations = [2, 2]

    def init_group(self):
        self.groups = 3

    def init_paddings(self):
        self.pad = [0, 1, 3, 0]
        self.padding_algorithm = "EXPLICIT"


C
cnn 已提交
378
class TestWithInput1x1Filter1x1_AsyPadding(TestConv2DFusionOp):
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [2, 3, 1, 1]  # NCHW
        assert np.mod(self.input_size[1], self.groups) == 0
        f_c = self.input_size[1] // self.groups
        self.filter_size = [6, f_c, 1, 1]

    def init_group(self):
        self.groups = 3

    def init_paddings(self):
        self.pad = [0, 3, 4, 0]
        self.padding_algorithm = "EXPLICIT"


394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
class TestSimpleNHWC(TestConv2DFusionOp):
    def init_test_case(self):
        self.stride = [1, 1]
        self.input_size = [3, 5, 5, 2]  # NHWC
        self.data_format = "NHWC"
        assert np.mod(self.input_size[3], self.groups) == 0
        f_c = self.input_size[3] // self.groups
        self.filter_size = [4, 3, 3, f_c]

    def init_group(self):
        self.groups = 1

    def init_paddings(self):
        self.pad = [1, 1]
        self.padding_algorithm = "EXPLICIT"


411 412 413 414 415 416 417 418 419 420 421 422
create_test_padding_SAME_class(TestAsyPadding)
create_test_padding_SAME_class(TestWithPad_AsyPadding)
create_test_padding_SAME_class(TestWithStride_AsyPadding)
create_test_padding_SAME_class(TestWithGroup_AsyPadding)
create_test_padding_SAME_class(TestWithInput1x1Filter1x1_AsyPadding)

create_test_padding_VALID_class(TestAsyPadding)
create_test_padding_VALID_class(TestWithPad_AsyPadding)
create_test_padding_VALID_class(TestWithStride_AsyPadding)
create_test_padding_VALID_class(TestWithGroup_AsyPadding)
create_test_padding_VALID_class(TestWithInput1x1Filter1x1_AsyPadding)

423 424 425 426 427 428
create_test_cudnn_channel_last_class(TestAsyPadding)
create_test_cudnn_channel_last_class(TestWithPad_AsyPadding)
create_test_cudnn_channel_last_class(TestWithStride_AsyPadding)
create_test_cudnn_channel_last_class(TestWithGroup_AsyPadding)
create_test_cudnn_channel_last_class(TestWithInput1x1Filter1x1_AsyPadding)

Q
qingqing01 已提交
429 430
if __name__ == '__main__':
    unittest.main()