Commit d3aeb431 authored by Stefan Behnel's avatar Stefan Behnel Committed by GitHub

Merge pull request #2748 from QuLogic/abs-nogil

Mark optimized abs as being nogil-safe.
parents 71b36d79 efa49ca0
......@@ -30,17 +30,19 @@ builtin_utility_code = {
class _BuiltinOverride(object):
def __init__(self, py_name, args, ret_type, cname, py_equiv="*",
utility_code=None, sig=None, func_type=None,
is_strict_signature=False, builtin_return_type=None):
is_strict_signature=False, builtin_return_type=None,
nogil=None):
self.py_name, self.cname, self.py_equiv = py_name, cname, py_equiv
self.args, self.ret_type = args, ret_type
self.func_type, self.sig = func_type, sig
self.builtin_return_type = builtin_return_type
self.is_strict_signature = is_strict_signature
self.utility_code = utility_code
self.nogil = nogil
def build_func_type(self, sig=None, self_arg=None):
if sig is None:
sig = Signature(self.args, self.ret_type)
sig = Signature(self.args, self.ret_type, nogil=self.nogil)
sig.exception_check = False # not needed for the current builtins
func_type = sig.function_type(self_arg)
if self.is_strict_signature:
......@@ -92,13 +94,13 @@ class BuiltinMethod(_BuiltinOverride):
builtin_function_table = [
# name, args, return, C API func, py equiv = "*"
BuiltinFunction('abs', "d", "d", "fabs",
is_strict_signature = True),
is_strict_signature=True, nogil=True),
BuiltinFunction('abs', "f", "f", "fabsf",
is_strict_signature = True),
is_strict_signature=True, nogil=True),
BuiltinFunction('abs', "i", "i", "abs",
is_strict_signature = True),
is_strict_signature=True, nogil=True),
BuiltinFunction('abs', "l", "l", "labs",
is_strict_signature = True),
is_strict_signature=True, nogil=True),
BuiltinFunction('abs', None, None, "__Pyx_abs_longlong",
utility_code = UtilityCode.load("abs_longlong", "Builtins.c"),
func_type = PyrexTypes.CFuncType(
......
......@@ -86,7 +86,7 @@ class Signature(object):
'z': "-1",
}
def __init__(self, arg_format, ret_format):
def __init__(self, arg_format, ret_format, nogil=0):
self.has_dummy_arg = 0
self.has_generic_args = 0
if arg_format[:1] == '-':
......@@ -100,6 +100,7 @@ class Signature(object):
self.error_value = self.error_value_map.get(ret_format, None)
self.exception_check = ret_format != 'r' and self.error_value is not None
self.is_staticmethod = False
self.nogil = nogil
def __repr__(self):
return '<Signature[%s(%s%s)]>' % (
......@@ -149,7 +150,8 @@ class Signature(object):
exc_value = self.exception_value()
return PyrexTypes.CFuncType(
ret_type, args, exception_value=exc_value,
exception_check=self.exception_check)
exception_check=self.exception_check,
nogil=self.nogil)
def method_flags(self):
if self.ret_format == "O":
......
......@@ -59,6 +59,27 @@ def int_abs(int a):
"""
return abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'abs']")
cdef int c_int_abs(int a) nogil except *:
return abs(a)
def test_c_int_abs(int a):
"""
>>> test_c_int_abs(-5) == 5
True
>>> test_c_int_abs(-5.1) == 5
True
>>> test_c_int_abs(-max_int-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> test_c_int_abs(max_int) == abs(max_int) or (max_int, test_c_int_abs(max_int), abs(max_int))
True
"""
return c_int_abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
......@@ -69,6 +90,19 @@ def uint_abs(unsigned int a):
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
cdef unsigned int c_uint_abs(unsigned int a) nogil:
return abs(a)
def test_c_uint_abs(unsigned int a):
"""
>>> test_c_uint_abs(max_int) == abs(max_int) or (max_int, test_c_uint_abs(max_int), abs(max_int))
True
"""
return c_uint_abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
......@@ -87,6 +121,27 @@ def long_abs(long a):
"""
return abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
cdef long c_long_abs(long a) nogil except *:
return abs(a)
def test_c_long_abs(long a):
"""
>>> test_c_long_abs(-5) == 5
True
>>> test_c_long_abs(-5.1) == 5
True
>>> test_c_long_abs(-max_long-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> test_c_long_abs(max_long) == abs(max_long) or (max_long, test_c_long_abs(max_long), abs(max_long))
True
"""
return c_long_abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
......@@ -99,6 +154,21 @@ def ulong_abs(unsigned long a):
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'labs']")
cdef unsigned long c_ulong_abs(unsigned long a) nogil:
return abs(a)
def test_c_ulong_abs(unsigned long a):
"""
>>> test_c_ulong_abs(max_long) == abs(max_long) or (max_int, test_c_ulong_abs(max_long), abs(max_long))
True
>>> test_c_ulong_abs(max_long + 5) == abs(max_long + 5) or (max_long + 5, test_c_ulong_abs(max_long + 5), abs(max_long + 5))
True
"""
return c_ulong_abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_longlong']")
......@@ -115,6 +185,25 @@ def long_long_abs(long long a):
"""
return abs(a)
@cython.overflowcheck(True)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_longlong']")
cdef long long c_long_long_abs(long long a) nogil except *:
return abs(a)
def test_c_long_long_abs(long long a):
"""
>>> test_c_long_long_abs(-(2**33)) == 2**33
True
>>> test_c_long_long_abs(-max_long_long-1) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> test_c_long_long_abs(max_long_long) == abs(max_long_long) or (max_long_long, test_c_long_long_abs(max_long_long), abs(max_long_long))
True
"""
return c_long_long_abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'fabs']")
def double_abs(double a):
......@@ -126,6 +215,20 @@ def double_abs(double a):
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'fabs']")
cdef double c_double_abs(double a) nogil:
return abs(a)
def test_c_double_abs(double a):
"""
>>> test_c_double_abs(-5)
5.0
>>> test_c_double_abs(-5.5)
5.5
"""
return c_double_abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'fabsf']")
def float_abs(float a):
......@@ -137,6 +240,20 @@ def float_abs(float a):
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = 'fabsf']")
cdef float c_float_abs(float a) nogil:
return abs(a)
def test_c_float_abs(float a):
"""
>>> test_c_float_abs(-5)
5.0
>>> test_c_float_abs(-5.5)
5.5
"""
return c_float_abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_c_abs_double']")
def complex_abs(complex a):
......@@ -147,3 +264,17 @@ def complex_abs(complex a):
5.5
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_c_abs_double']")
cdef double c_complex_abs(complex a) nogil:
return abs(a)
def test_c_complex_abs(complex a):
"""
>>> test_c_complex_abs(-5j)
5.0
>>> test_c_complex_abs(-5.5j)
5.5
"""
return c_complex_abs(a)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment