op_test_util.py 3.0 KB
Newer Older
Y
Yu Yang 已提交
1
import numpy
2
import paddle.v2.framework.core as core
Y
Yu Yang 已提交
3
from paddle.v2.framework.op import Operator
Y
Yu Yang 已提交
4 5 6


class OpTestMeta(type):
Y
Yu Yang 已提交
7 8
    """
    Operator Test ClassMeta.
X
Xinghai Sun 已提交
9 10

    It injects `test_all` method into user's OperatorTest class, to make Python
Y
Yu Yang 已提交
11
    unittest module run that method.
X
Xinghai Sun 已提交
12

Y
Yu Yang 已提交
13 14
    The `test_all` read what value is stored in `self`. It use self's values to
    create and run a operator, and check whether that op is OK or not.
X
Xinghai Sun 已提交
15

Y
Yu Yang 已提交
16 17 18
    See `test_add_two_op` for example usage.
    """

Y
Yu Yang 已提交
19 20 21 22
    def __new__(cls, name, bases, attrs):
        obj = super(OpTestMeta, cls).__new__(cls, name, bases, attrs)

        def test_all(self):
Y
Yu Yang 已提交
23
            scope = core.Scope()
Y
Yu Yang 已提交
24
            kwargs = dict()
Y
Yu Yang 已提交
25
            places = [core.CPUPlace()]
26
            if core.is_compile_gpu():
Q
qijun 已提交
27 28 29
                places.append(core.GPUPlace(0))

            for place in places:
Y
Yu Yang 已提交
30
                for in_name in Operator.get_op_input_names(self.type):
Y
Yu Yang 已提交
31
                    if hasattr(self, "inputs") and in_name in self.inputs:
Q
qijun 已提交
32
                        kwargs[in_name] = in_name
Q
qijun 已提交
33
                        var = scope.new_var(in_name).get_tensor()
D
dangqingqing 已提交
34
                        arr = self.inputs[in_name]
Q
qijun 已提交
35 36
                        var.set_dims(arr.shape)
                        var.set(arr, place)
W
wanghaoshuang 已提交
37
                        print "var: %s" % in_name
Q
qijun 已提交
38 39
                    else:
                        kwargs[in_name] = "@EMPTY@"
W
wanghaoshuang 已提交
40
                        print "var: %s=EMPTY" % in_name
Y
Yu Yang 已提交
41

Y
Yu Yang 已提交
42
                for out_name in Operator.get_op_output_names(self.type):
D
dangqingqing 已提交
43 44 45 46
                    if not hasattr(self, "outputs"):
                        raise ValueError(
                            "The test op must set self.outputs dict.")
                    if out_name not in self.outputs:
D
dangqingqing 已提交
47
                        raise ValueError("The %s is not in self.outputs dict." %
D
dangqingqing 已提交
48 49 50
                                         (out_name))
                    kwargs[out_name] = out_name
                    scope.new_var(out_name).get_tensor()
W
wanghaoshuang 已提交
51
                    print "var: %s" % out_name
Y
Yu Yang 已提交
52

Y
Yu Yang 已提交
53
                for attr_name in Operator.get_op_attr_names(self.type):
D
dangqingqing 已提交
54 55
                    if hasattr(self, "attrs") and attr_name in self.attrs:
                        kwargs[attr_name] = self.attrs[attr_name]
Y
Yu Yang 已提交
56

Y
Yu Yang 已提交
57
                op = Operator(self.type, **kwargs)
58 59
                if isinstance(place, core.GPUPlace) and not op.support_gpu():
                    return
Y
Yu Yang 已提交
60

Q
qijun 已提交
61
                op.infer_shape(scope)
Y
Yu Yang 已提交
62

Q
qijun 已提交
63 64
                ctx = core.DeviceContext.create(place)
                op.run(scope, ctx)
Y
Yu Yang 已提交
65

Y
Yu Yang 已提交
66
                for out_name in Operator.get_op_output_names(self.type):
Q
qijun 已提交
67
                    actual = numpy.array(scope.find_var(out_name).get_tensor())
W
wanghaoshuang 已提交
68
                    print "actual: %s" % actual
D
dangqingqing 已提交
69
                    expect = self.outputs[out_name]
W
wanghaoshuang 已提交
70
                    print "expect: %s" % expect
Q
Qiao Longfei 已提交
71
                    self.assertTrue(
72
                        numpy.allclose(
D
dangqingqing 已提交
73
                            actual, expect, atol=1e-05),
Q
Qiao Longfei 已提交
74
                        "output name: " + out_name + "has diff")
Y
Yu Yang 已提交
75 76 77

        obj.test_all = test_all
        return obj