test_decoupled_py_reader.py 6.7 KB
Newer Older
S
sneaxiy 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# Copyright (c) 2019 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 paddle
import paddle.fluid as fluid
import numpy as np
import time
import six
import unittest

22 23 24
EPOCH_NUM = 5
BATCH_SIZE = 16
BATCH_NUM = 10
S
sneaxiy 已提交
25 26 27 28
CLASS_NUM = 10


def random_reader():
S
sneaxiy 已提交
29
    np.random.seed(1)
30
    for i in range(BATCH_SIZE * BATCH_NUM):
S
sneaxiy 已提交
31
        image = np.random.random([784])
32
        label = np.random.randint(low=0, high=CLASS_NUM)
S
sneaxiy 已提交
33 34 35
        yield image, label


S
sneaxiy 已提交
36
def simple_fc_net(places, use_legacy_py_reader, use_double_buffer):
C
cnn 已提交
37
    paddle.seed(1)
L
Leo Chen 已提交
38
    paddle.framework.random._manual_program_seed(1)
S
sneaxiy 已提交
39 40 41 42 43
    startup_prog = fluid.Program()
    main_prog = fluid.Program()

    with fluid.unique_name.guard():
        with fluid.program_guard(main_prog, startup_prog):
44 45 46
            image = fluid.layers.data(name='image',
                                      shape=[784],
                                      dtype='float32')
S
sneaxiy 已提交
47
            label = fluid.layers.data(name='label', shape=[1], dtype='int64')
48 49 50 51
            py_reader = fluid.io.PyReader(feed_list=[image, label],
                                          capacity=4,
                                          iterable=not use_legacy_py_reader,
                                          use_double_buffer=use_double_buffer)
S
sneaxiy 已提交
52 53 54 55 56 57 58 59 60 61 62 63
            hidden = image
            for hidden_size in [10, 20, 30]:
                hidden = fluid.layers.fc(
                    hidden,
                    size=hidden_size,
                    act='tanh',
                    bias_attr=fluid.ParamAttr(
                        initializer=fluid.initializer.Constant(value=1.0)))

            predict_label = fluid.layers.fc(hidden,
                                            size=CLASS_NUM,
                                            act='softmax')
64
            loss = paddle.mean(
65
                fluid.layers.cross_entropy(input=predict_label, label=label))
S
sneaxiy 已提交
66 67 68 69 70 71 72

            optimizer = fluid.optimizer.Adam()
            optimizer.minimize(loss)
    return startup_prog, main_prog, py_reader, loss


class TestBase(unittest.TestCase):
73

S
sneaxiy 已提交
74 75
    def run_main(self, use_legacy_py_reader, with_data_parallel, places,
                 use_double_buffer):
S
sneaxiy 已提交
76 77
        scope = fluid.Scope()
        with fluid.scope_guard(scope):
S
sneaxiy 已提交
78
            startup_prog, main_prog, py_reader, loss = simple_fc_net(
S
sneaxiy 已提交
79 80 81 82 83
                places, use_legacy_py_reader, use_double_buffer)

            reader = paddle.batch(random_reader, batch_size=BATCH_SIZE)

            ps = places if use_double_buffer else fluid.cpu_places(len(places))
S
sneaxiy 已提交
84 85

            py_reader.decorate_sample_list_generator(
S
sneaxiy 已提交
86 87
                reader, places=ps if py_reader.iterable else None)

S
sneaxiy 已提交
88 89 90 91 92
            exe = fluid.Executor(place=places[0])
            exe.run(startup_prog)

            prog = fluid.CompiledProgram(main_prog)
            if with_data_parallel:
93 94
                prog = prog.with_data_parallel(loss_name=loss.name,
                                               places=places)
S
sneaxiy 已提交
95 96

            step = 0
S
sneaxiy 已提交
97
            step_list = []
S
sneaxiy 已提交
98
            loss_list = []
S
sneaxiy 已提交
99
            start_t = time.time()
S
sneaxiy 已提交
100
            if not py_reader.iterable:
S
sneaxiy 已提交
101
                for _ in six.moves.range(EPOCH_NUM):
S
sneaxiy 已提交
102
                    step = 0
S
sneaxiy 已提交
103 104 105
                    py_reader.start()
                    while True:
                        try:
S
sneaxiy 已提交
106 107 108
                            L, = exe.run(program=prog,
                                         fetch_list=[loss],
                                         use_program_cache=True)
S
sneaxiy 已提交
109
                            loss_list.append(np.mean(L))
S
sneaxiy 已提交
110 111 112 113
                            step += 1
                        except fluid.core.EOFException:
                            py_reader.reset()
                            break
S
sneaxiy 已提交
114
                    step_list.append(step)
S
sneaxiy 已提交
115 116
            else:
                for _ in six.moves.range(EPOCH_NUM):
S
sneaxiy 已提交
117
                    step = 0
S
sneaxiy 已提交
118 119 120 121 122 123 124
                    for d in py_reader():
                        assert len(d) == len(places)
                        for i, item in enumerate(d):
                            image = item['image']
                            label = item['label']
                            assert image.shape() == [BATCH_SIZE, 784]
                            assert label.shape() == [BATCH_SIZE, 1]
125 126
                            assert image._place()._equals(ps[i])
                            assert label._place()._equals(ps[i])
S
sneaxiy 已提交
127 128 129 130
                        L, = exe.run(program=prog,
                                     feed=d,
                                     fetch_list=[loss],
                                     use_program_cache=True)
S
sneaxiy 已提交
131
                        loss_list.append(np.mean(L))
S
sneaxiy 已提交
132
                        step += 1
S
sneaxiy 已提交
133
                    step_list.append(step)
S
sneaxiy 已提交
134
            end_t = time.time()
S
sneaxiy 已提交
135 136 137 138 139
            ret = {
                "time": end_t - start_t,
                "step": step_list,
                "loss": np.array(loss_list)
            }
S
sneaxiy 已提交
140 141
            return ret

S
sneaxiy 已提交
142
    def prepare_places(self, with_data_parallel, with_cpu=True, with_gpu=True):
S
sneaxiy 已提交
143 144 145 146 147
        places = []
        if with_cpu:
            places.append([fluid.CPUPlace()])
            if with_data_parallel:
                places.append([fluid.CPUPlace()] * 2)
S
sneaxiy 已提交
148

S
sneaxiy 已提交
149
        if with_gpu and fluid.core.is_compiled_with_cuda():
S
sneaxiy 已提交
150 151 152 153 154 155 156 157 158 159
            tmp = fluid.cuda_places()
            assert len(tmp) > 0, "no gpu detected"
            if with_data_parallel:
                places.append(tmp)
            places.append([tmp[0]])
        return places

    def test_main(self):
        for with_data_parallel in [True, False]:
            for p in self.prepare_places(with_data_parallel):
S
sneaxiy 已提交
160
                for use_double_buffer in [False, True]:
S
sneaxiy 已提交
161
                    results = []
S
sneaxiy 已提交
162 163 164 165 166 167
                    for use_legacy_py_reader in [False, True]:
                        ret = self.run_main(
                            use_legacy_py_reader=use_legacy_py_reader,
                            with_data_parallel=with_data_parallel,
                            places=p,
                            use_double_buffer=use_double_buffer)
S
sneaxiy 已提交
168 169 170 171 172
                        results.append(ret)
                    if not use_double_buffer:
                        diff = np.max(
                            np.abs(results[0]['loss'] - results[1]['loss']))
                        self.assertLess(diff, 1e-3)
S
sneaxiy 已提交
173 174 175 176


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