cython

Форк
0
/
nogil.pyx 
236 строк · 6.0 Кб
1
# mode: run
2
# tag: perf_hints
3

4
from nogil_other cimport voidexceptnogil_in_other_pxd
5

6
try:
7
    from StringIO import StringIO
8
except ImportError:
9
    from io import StringIO
10

11

12
def test(int x):
13
    """
14
    >>> test(5)
15
    47
16
    >>> test(11)
17
    53
18
    """
19
    with nogil:
20
        f(x)
21
        x = g(x)
22
    return x
23

24
cdef void f(int x) nogil:
25
        cdef int y
26
        y = x + 42
27
        g(y)
28

29
cdef int g(int x) nogil:
30
        cdef int y
31
        y = x + 42
32
        return y
33

34
cdef void release_gil_in_nogil() nogil:
35
    # This should generate valid code with/without the GIL
36
    with nogil:
37
        pass
38

39
cpdef void release_gil_in_nogil2() nogil:
40
    # This should generate valid code with/without the GIL
41
    with nogil:
42
        pass
43

44
def test_release_gil_in_nogil():
45
    """
46
    >>> test_release_gil_in_nogil()
47
    """
48
    with nogil:
49
        release_gil_in_nogil()
50
    with nogil:
51
        release_gil_in_nogil2()
52
    release_gil_in_nogil()
53
    release_gil_in_nogil2()
54

55
cdef void get_gil_in_nogil() nogil:
56
    with gil:
57
        pass
58

59
cpdef void get_gil_in_nogil2() nogil:
60
    with gil:
61
        pass
62

63
def test_get_gil_in_nogil():
64
    """
65
    >>> test_get_gil_in_nogil()
66
    """
67
    with nogil:
68
        get_gil_in_nogil()
69
    with nogil:
70
        get_gil_in_nogil2()
71
    get_gil_in_nogil()
72
    get_gil_in_nogil2()
73

74
cdef int with_gil_func() except -1 with gil:
75
    raise Exception("error!")
76

77
cdef int nogil_func() except -1 nogil:
78
    with_gil_func()
79

80
def test_nogil_exception_propagation():
81
    """
82
    >>> test_nogil_exception_propagation()
83
    Traceback (most recent call last):
84
       ...
85
    Exception: error!
86
    """
87
    with nogil:
88
        nogil_func()
89

90

91
cdef int write_unraisable() noexcept nogil:
92
    with gil:
93
        raise ValueError()
94

95

96
def test_unraisable():
97
    """
98
    >>> print(test_unraisable())  # doctest: +ELLIPSIS
99
    ValueError
100
    Exception...ignored...
101
    """
102
    import sys
103
    old_stderr = sys.stderr
104
    stderr = sys.stderr = StringIO()
105
    try:
106
        write_unraisable()
107
    finally:
108
        sys.stderr = old_stderr
109
    return stderr.getvalue().strip()
110

111

112
cdef int initialize_array() nogil:
113
    cdef int[4] a = [1, 2, 3, 4]
114
    return a[0] + a[1] + a[2] + a[3]
115

116
cdef int copy_array() nogil:
117
    cdef int[4] a
118
    a[:] = [0, 1, 2, 3]
119
    return a[0] + a[1] + a[2] + a[3]
120

121
cdef double copy_array2() nogil:
122
    cdef double[4] x = [1.0, 3.0, 5.0, 7.0]
123
    cdef double[4] y
124
    y[:] = x[:]
125
    return y[0] + y[1] + y[2] + y[3]
126

127
cdef double copy_array3() nogil:
128
    cdef double[4] x = [2.0, 4.0, 6.0, 8.0]
129
    cdef double[4] y
130
    y = x
131
    return y[0] + y[1] + y[2] + y[3]
132

133
cdef void copy_array_exception(int n) nogil:
134
    cdef double[5] a = [1,2,3,4,5]
135
    cdef double[6] b
136
    b[:n] = a
137

138
def test_initalize_array():
139
    """
140
    >>> test_initalize_array()
141
    10
142
    """
143
    return initialize_array()
144

145
def test_copy_array():
146
    """
147
    >>> test_copy_array()
148
    6
149
    """
150
    return copy_array()
151

152
def test_copy_array2():
153
    """
154
    >>> test_copy_array2()
155
    16.0
156
    """
157
    return copy_array2()
158

159
def test_copy_array3():
160
    """
161
    >>> test_copy_array3()
162
    20.0
163
    """
164
    return copy_array3()
165

166
def test_copy_array_exception(n):
167
    """
168
    >>> test_copy_array_exception(20)
169
    Traceback (most recent call last):
170
        ...
171
    ValueError: Assignment to slice of wrong length, expected 5, got 20
172
    """
173
    copy_array_exception(n)
174

175
def test_copy_array_exception_nogil(n):
176
    """
177
    >>> test_copy_array_exception_nogil(20)
178
    Traceback (most recent call last):
179
        ...
180
    ValueError: Assignment to slice of wrong length, expected 5, got 20
181
    """
182
    cdef int cn = n
183
    with nogil:
184
        copy_array_exception(cn)
185

186
# Should still get a warning even though it's declared in a pxd
187
cdef void voidexceptnogil_in_pxd() nogil:
188
    pass
189

190
def test_performance_hint_nogil():
191
    """
192
    >>> test_performance_hint_nogil()
193
    """
194
    with nogil:
195
        voidexceptnogil_in_pxd()
196
        # The function call should generate a performance hint, but the definition should
197
        # not (since it's in an external pxd we don't control)
198
        voidexceptnogil_in_other_pxd()
199

200

201
cdef int f_in_pxd1() nogil except -1:
202
    return 0
203

204
cdef int f_in_pxd2() nogil:  # implicit except -1?
205
    return 0
206

207
def test_declared_in_pxd():
208
    """
209
    >>> test_declared_in_pxd()
210
    """
211
    with nogil:
212
        # no warnings here because we're in the same file as the declaration
213
        f_in_pxd1()
214
        f_in_pxd2()
215

216

217
# Note that we're only able to check the first line of the performance hint
218
_PERFORMANCE_HINTS = """
219
5:18: No exception value declared for 'f_in_pxd1' in pxd file.
220
6:18: No exception value declared for 'f_in_pxd2' in pxd file.
221
20:9: Exception check after calling 'f' will always require the GIL to be acquired.
222
24:0: Exception check on 'f' will always require the GIL to be acquired.
223
34:0: Exception check on 'release_gil_in_nogil' will always require the GIL to be acquired.
224
39:0: Exception check on 'release_gil_in_nogil2' will always require the GIL to be acquired.
225
49:28: Exception check after calling 'release_gil_in_nogil' will always require the GIL to be acquired.
226
51:29: Exception check after calling 'release_gil_in_nogil2' will always require the GIL to be acquired.
227
55:0: Exception check on 'get_gil_in_nogil' will always require the GIL to be acquired.
228
59:0: Exception check on 'get_gil_in_nogil2' will always require the GIL to be acquired.
229
68:24: Exception check after calling 'get_gil_in_nogil' will always require the GIL to be acquired.
230
70:25: Exception check after calling 'get_gil_in_nogil2' will always require the GIL to be acquired.
231
133:0: Exception check on 'copy_array_exception' will always require the GIL to be acquired.
232
184:28: Exception check after calling 'copy_array_exception' will always require the GIL to be acquired.
233
187:0: Exception check on 'voidexceptnogil_in_pxd' will always require the GIL to be acquired.
234
195:30: Exception check after calling 'voidexceptnogil_in_pxd' will always require the GIL to be acquired.
235
198:36: Exception check after calling 'voidexceptnogil_in_other_pxd' will always require the GIL to be acquired.
236
"""
237

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.