test_device_guard.py 8.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 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.

import unittest

Z
Zhang Ting 已提交
17
import paddle
18 19 20 21 22 23
import paddle.fluid as fluid
import paddle.fluid.core as core
import warnings


def execute(main_program, startup_program):
Z
Zhang Ting 已提交
24 25
    if paddle.is_compiled_with_cuda():
        place = paddle.CUDAPlace(0)
26
    else:
Z
Zhang Ting 已提交
27 28
        place = paddle.CPUPlace()
    exe = paddle.static.Executor(place)
29 30 31 32
    exe.run(startup_program)
    exe.run(main_program)


33 34 35 36 37 38 39 40
def get_vaild_warning_num(warning, w):
    num = 0
    for i in range(len(w)):
        if warning in str(w[i].message):
            num += 1
    return num


41 42
class TestDeviceGuard(unittest.TestCase):
    def test_device_guard(self):
Z
Zhang Ting 已提交
43 44 45
        main_program = paddle.static.Program()
        startup_program = paddle.static.Program()
        with paddle.static.program_guard(main_program, startup_program):
46 47 48 49 50 51
            data1 = paddle.full(
                shape=[1, 3, 8, 8], fill_value=0.5, dtype='float32'
            )
            data2 = paddle.full(
                shape=[1, 3, 5, 5], fill_value=0.5, dtype='float32'
            )
Z
Zhang Ting 已提交
52 53 54 55
            shape = paddle.shape(data2)
            with paddle.static.device_guard("cpu"):
                shape = paddle.slice(shape, axes=[0], starts=[0], ends=[4])
                with paddle.static.device_guard("gpu"):
56
                    out = paddle.crop(data1, shape=shape)
57 58 59 60 61 62 63 64 65 66 67
        # check if the device attr is set correctly
        all_ops = main_program.global_block().ops
        device_attr_name = core.op_proto_and_checker_maker.kOpDeviceAttrName()
        for op in all_ops:
            if op.type == 'slice':
                self.assertEqual(op.desc.attr(device_attr_name), "cpu")
            if op.type == 'crop_tensor':
                self.assertEqual(op.desc.attr(device_attr_name), "gpu")

        execute(main_program, startup_program)

68
    def test_device_guard_with_id(self):
Z
Zhang Ting 已提交
69 70 71
        main_program = paddle.static.Program()
        startup_program = paddle.static.Program()
        with paddle.static.program_guard(main_program, startup_program):
72 73 74 75 76 77
            data1 = paddle.full(
                shape=[1, 3, 8, 8], fill_value=0.5, dtype='float32'
            )
            data2 = paddle.full(
                shape=[1, 3, 5, 5], fill_value=0.5, dtype='float32'
            )
Z
Zhang Ting 已提交
78 79 80 81
            shape = paddle.shape(data2)
            with paddle.static.device_guard("cpu"):
                shape = paddle.slice(shape, axes=[0], starts=[0], ends=[4])
                with paddle.static.device_guard("gpu:1"):
82
                    out = paddle.crop(data1, shape=shape)
83 84 85 86 87 88 89 90 91 92 93
        # check if the device attr is set correctly
        all_ops = main_program.global_block().ops
        device_attr_name = core.op_proto_and_checker_maker.kOpDeviceAttrName()
        for op in all_ops:
            if op.type == 'slice':
                self.assertEqual(op.desc.attr(device_attr_name), "cpu")
            if op.type == 'crop_tensor':
                self.assertEqual(op.desc.attr(device_attr_name), "gpu:1")

        execute(main_program, startup_program)

94
    def test_cpu_only_op(self):
Z
Zhang Ting 已提交
95 96 97
        main_program = paddle.static.Program()
        startup_program = paddle.static.Program()
        with paddle.static.program_guard(main_program, startup_program):
98 99 100 101 102 103
            x = paddle.full(
                shape=[2, 255, 13, 13], fill_value=0.3, dtype='float32'
            )
            gt_box = paddle.full(
                shape=[2, 6, 4], fill_value=0.5, dtype='float32'
            )
Z
Zhang Ting 已提交
104
            gt_label = paddle.full(shape=[2, 6], fill_value=1.0, dtype='int32')
105 106 107
            gt_score = paddle.full(
                shape=[2, 6], fill_value=0.5, dtype='float32'
            )
108
            anchors = [
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
                10,
                13,
                16,
                30,
                33,
                23,
                30,
                61,
                62,
                45,
                59,
                119,
                116,
                90,
                156,
                198,
                373,
                326,
127 128
            ]
            anchor_mask = [0, 1, 2]
Z
Zhang Ting 已提交
129
            with paddle.static.device_guard("gpu"):
130
                # yolov3_loss only has cpu kernel, so its cpu kernel will be executed
131 132 133 134 135 136 137 138 139 140 141
                loss = fluid.layers.yolov3_loss(
                    x=x,
                    gt_box=gt_box,
                    gt_label=gt_label,
                    gt_score=gt_score,
                    anchors=anchors,
                    anchor_mask=anchor_mask,
                    class_num=80,
                    ignore_thresh=0.7,
                    downsample_ratio=32,
                )
142 143 144 145

        execute(main_program, startup_program)

    def test_without_kernel_op(self):
Z
Zhang Ting 已提交
146 147 148 149 150 151
        main_program = paddle.static.Program()
        startup_program = paddle.static.Program()
        with paddle.static.program_guard(main_program, startup_program):
            i = paddle.full(shape=[1], dtype='int64', fill_value=0)
            loop_len = paddle.full(shape=[1], dtype='int64', fill_value=10)
            cond = paddle.less_than(x=i, y=loop_len)
152 153 154

            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always")
Z
Zhang Ting 已提交
155
                with paddle.static.device_guard("cpu"):
156 157
                    while_op = fluid.layers.While(cond=cond)
                    with while_op.block():
Z
Zhang Ting 已提交
158
                        i = paddle.increment(x=i, value=1)
159 160
                        fluid.layers.less_than(x=i, y=loop_len, cond=cond)

161 162 163 164
        warning = "The Op(while) is not support to set device."
        warning_num = get_vaild_warning_num(warning, w)
        assert warning_num == 1

165 166 167 168 169 170 171 172 173 174
        all_ops = main_program.global_block().ops
        device_attr_name = core.op_proto_and_checker_maker.kOpDeviceAttrName()
        for op in all_ops:
            if op.type == 'while':
                self.assertEqual(op.desc.attr(device_attr_name), "")

        execute(main_program, startup_program)

    def test_error(self):
        def device_attr():
Z
Zhang Ting 已提交
175 176
            with paddle.static.device_guard("cpu1"):
                out = paddle.full(shape=[1], fill_value=0.2, dtype='float32')
177

178
        def device_attr2():
Z
Zhang Ting 已提交
179 180
            with paddle.static.device_guard("cpu:1"):
                out = paddle.full(shape=[1], fill_value=0.2, dtype='float32')
181

182
        self.assertRaises(ValueError, device_attr)
183
        self.assertRaises(ValueError, device_attr2)
184

185 186
    # check if op_descs have op_device attr
    def test_op_descs_device_attr(self):
Z
Zhang Ting 已提交
187 188 189
        main_program = paddle.static.Program()
        startup_program = paddle.static.Program()
        with paddle.static.program_guard(main_program, startup_program):
190 191 192 193 194 195
            data1 = paddle.static.data(
                name="data_1", shape=[4, 2], dtype="float32"
            )
            label = paddle.static.data(
                name="label", shape=[4, 1], dtype="int64"
            )
Z
Zhang Ting 已提交
196 197 198 199
            fc1 = paddle.static.nn.fc(x=data1, size=10)
            fc2 = paddle.static.nn.fc(x=fc1, size=10)
            with paddle.static.device_guard("gpu"):
                out = paddle.nn.functional.softmax_with_cross_entropy(
200 201
                    logits=fc1 + fc2, label=label
                )
Z
Zhang Ting 已提交
202 203
                loss = paddle.mean(out)
                opt = paddle.optimizer.SGD(0.1)
204 205 206 207 208 209
                opt.minimize(loss)

        all_ops = main_program.global_block().ops
        device_attr_name = core.op_proto_and_checker_maker.kOpDeviceAttrName()
        for op in all_ops:
            self.assertEqual(True, op.desc.has_attr(device_attr_name))
210 211
            # fill_constant(backward op) is append to mean op, which should have
            # the same op_device value as mean op
212 213 214
            if op.desc == 'fill_constant':
                self.assertEqual(op.desc.attr(device_attr_name), "gpu")

215 216 217

if __name__ == '__main__':
    unittest.main()