File: test_reduction.py

package info (click to toggle)
libgpuarray 0.7.6-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,784 kB
  • sloc: ansic: 19,235; python: 4,621; makefile: 213; sh: 9
file content (149 lines) | stat: -rw-r--r-- 4,646 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import numpy

from nose.tools import assert_raises

from pygpu import gpuarray, ndgpuarray as elemary
from pygpu.reduction import ReductionKernel

from .support import (guard_devsup, check_meta_content, context, gen_gpuarray,
                      dtypes_no_complex_big, dtypes_no_complex)


def test_red_array_basic():
    for dtype in dtypes_no_complex_big:
        for shape, redux in [((10,), [True]),
                             ((20, 30), [True, True]),
                             ((20, 30), [True, False]),
                             ((20, 30), [False, True]),
                             ((8, 5, 10), [True, True, True]),
                             ((8, 5, 10), [True, True, False]),
                             ((8, 5, 10), [True, False, True]),
                             ((8, 5, 10), [False, True, True]),
                             ((8, 5, 10), [True, False, False]),
                             ((8, 5, 10), [False, True, False]),
                             ((8, 5, 10), [False, False, True]),
                             ]:
            yield red_array_sum, dtype, shape, redux


@guard_devsup
def red_array_sum(dtype, shape, redux):
    c, g = gen_gpuarray(shape, dtype, ctx=context)

    axes = [i for i in range(len(redux)) if redux[i]]
    axes.reverse()
    out_c = c
    # numpy.sum doesn't support multiple axis before 1.7.0
    for ax in axes:
        out_c = numpy.apply_along_axis(sum, ax, out_c).astype(dtype)
    out_g = ReductionKernel(context, dtype, "0", "a + b", redux)(g)

    assert out_c.shape == out_g.shape
    assert out_g.dtype == numpy.dtype(dtype)
    # since we do not use the same summing algorithm,
    # there will be differences
    assert numpy.allclose(out_c, numpy.asarray(out_g), rtol=2e-5)


def test_red_big_array():
    for redux in [[True, False, False],
                  [True, False, True],
                  [False, True, True],
                  [False, True, False]]:
        yield red_array_sum, 'float32', (2000, 30, 100), redux

# this test needs a guard_devsup because Python 'float' is double,
# and placing one directly on a test_* makes nose not know that it's a test
def test_red_broadcast():
    red_broadcast()

@guard_devsup
def red_broadcast():
    from pygpu.tools import as_argument

    dtype = float
    xshape = (5, 10, 15)
    yshape = (1, 10, 15)
    redux = [False, True, False]

    nx, gx = gen_gpuarray(xshape, dtype, ctx=context)
    ny, gy = gen_gpuarray(yshape, dtype, ctx=context)

    nz = nx*ny
    axes = [i for i in range(len(redux)) if redux[i]]
    axes.reverse()
    # numpy.sum doesn't support multiple axis before 1.7.0
    for ax in axes:
        nz = numpy.apply_along_axis(sum, ax, nz).astype(dtype)

    args = [as_argument(gx, 'a'), as_argument(gy, 'b')]
    gz = ReductionKernel(context, dtype, "0", "a+b", redux,
                         map_expr="a[i]*b[i]", arguments=args)(
        gx, gy, broadcast=True)

    assert numpy.allclose(nz, numpy.asarray(gz))


def test_reduction_ops():
    for axis in [None, 0, 1]:
        for op in ['all', 'any']:
            yield reduction_op, op, 'bool', axis
        for op in ['prod', 'sum']:  # 'min', 'max']:
            for dtype in dtypes_no_complex:
                yield reduction_op, op, dtype, axis


@guard_devsup
def reduction_op(op, dtype, axis):
    c, g = gen_gpuarray((2, 3), dtype=dtype, ctx=context, cls=elemary)

    rc = getattr(c, op)(axis=axis)
    rg = getattr(g, op)(axis=axis)

    check_meta_content(rg, rc)

    outc = numpy.empty(rc.shape, dtype=rc.dtype)
    outg = gpuarray.empty(rg.shape, dtype=rg.dtype, context=context)

    rc = getattr(c, op)(axis=axis, out=outc)
    rg = getattr(g, op)(axis=axis, out=outg)

    check_meta_content(outg, outc)


def test_reduction_wrong_type():
    c, g = gen_gpuarray((2, 3), dtype='float32', ctx=context, cls=elemary)
    out1 = gpuarray.empty((2, 3), dtype='int32', context=context)
    out2 = gpuarray.empty((3, 2), dtype='float32', context=context)

    try:
        g.sum(out=out1)
        assert False, "Expected a TypeError out of the sum"
    except TypeError:
        pass

    try:
        g.sum(out=out2)
        assert False, "Expected a TypeError out of the sum"
    except TypeError:
        pass


def test_reduction_0d():
    c, g = gen_gpuarray((), dtype='bool', ctx=context, cls=elemary)

    rc = c.any()
    rg = g.any()

    assert numpy.all(rc == numpy.asarray(rg))

    rc = c.all()
    rg = g.all()

    assert numpy.all(rc == numpy.asarray(rg))


def test_reduction_f16():
    c, g = gen_gpuarray((3,), dtype='float16', ctx=context, cls=elemary)

    assert_raises(NotImplementedError, g.sum)