ai-content-maker/.venv/Lib/site-packages/numba/tests/npyufunc/test_ufunc.py

174 lines
5.1 KiB
Python

import numpy as np
from numba import float32, jit, njit
from numba.np.ufunc import Vectorize
from numba.core.errors import TypingError
from numba.tests.support import TestCase
import unittest
dtype = np.float32
a = np.arange(80, dtype=dtype).reshape(8, 10)
b = a.copy()
c = a.copy(order='F')
d = np.arange(16 * 20, dtype=dtype).reshape(16, 20)[::2, ::2]
def add(a, b):
return a + b
def add_multiple_args(a, b, c, d):
return a + b + c + d
def gufunc_add(a, b):
result = 0.0
for i in range(a.shape[0]):
result += a[i] * b[i]
return result
def ufunc_reduce(ufunc, arg):
for i in range(arg.ndim):
arg = ufunc.reduce(arg)
return arg
vectorizers = [
Vectorize,
# ParallelVectorize,
# StreamVectorize,
# CudaVectorize,
# GUFuncVectorize,
]
class TestUFuncs(TestCase):
def _test_ufunc_attributes(self, cls, a, b, *args):
"Test ufunc attributes"
vectorizer = cls(add, *args)
vectorizer.add(float32(float32, float32))
ufunc = vectorizer.build_ufunc()
info = (cls, a.ndim)
self.assertPreciseEqual(ufunc(a, b), a + b, msg=info)
self.assertPreciseEqual(ufunc_reduce(ufunc, a), np.sum(a), msg=info)
self.assertPreciseEqual(ufunc.accumulate(a), np.add.accumulate(a),
msg=info)
self.assertPreciseEqual(ufunc.outer(a, b), np.add.outer(a, b), msg=info)
def _test_broadcasting(self, cls, a, b, c, d):
"Test multiple args"
vectorizer = cls(add_multiple_args)
vectorizer.add(float32(float32, float32, float32, float32))
ufunc = vectorizer.build_ufunc()
info = (cls, a.shape)
self.assertPreciseEqual(ufunc(a, b, c, d), a + b + c + d, msg=info)
def test_ufunc_attributes(self):
for v in vectorizers: # 1D
self._test_ufunc_attributes(v, a[0], b[0])
for v in vectorizers: # 2D
self._test_ufunc_attributes(v, a, b)
for v in vectorizers: # 3D
self._test_ufunc_attributes(v, a[:, np.newaxis, :],
b[np.newaxis, :, :])
def test_broadcasting(self):
for v in vectorizers: # 1D
self._test_broadcasting(v, a[0], b[0], c[0], d[0])
for v in vectorizers: # 2D
self._test_broadcasting(v, a, b, c, d)
for v in vectorizers: # 3D
self._test_broadcasting(v, a[:, np.newaxis, :], b[np.newaxis, :, :],
c[:, np.newaxis, :], d[np.newaxis, :, :])
def test_implicit_broadcasting(self):
for v in vectorizers:
vectorizer = v(add)
vectorizer.add(float32(float32, float32))
ufunc = vectorizer.build_ufunc()
broadcasting_b = b[np.newaxis, :, np.newaxis, np.newaxis, :]
self.assertPreciseEqual(ufunc(a, broadcasting_b),
a + broadcasting_b)
def test_ufunc_exception_on_write_to_readonly(self):
z = np.ones(10)
z.flags.writeable = False # flip write bit
tests = []
expect = "ufunc 'sin' called with an explicit output that is read-only"
tests.append((jit(nopython=True), TypingError, expect))
tests.append((jit(forceobj=True), ValueError,
"output array is read-only"))
for dec, exc, msg in tests:
def test(x):
a = np.ones(x.shape, x.dtype) # do not copy RO attribute from x
np.sin(a, x)
with self.assertRaises(exc) as raises:
dec(test)(z)
self.assertIn(msg, str(raises.exception))
def test_optional_type_handling(self):
# Tests ufunc compilation with Optional type
@njit
def inner(x, y):
if y > 2:
z = None
else:
z = np.ones(4)
return np.add(x, z)
# This causes `z` to be np.ones(4) at runtime, success
self.assertPreciseEqual(inner(np.arange(4), 1),
np.arange(1, 5).astype(np.float64))
with self.assertRaises(TypeError) as raises:
# This causes `z` to be None at runtime, TypeError raised on the
# type cast of the Optional.
inner(np.arange(4), 3)
msg = "expected array(float64, 1d, C), got None"
self.assertIn(msg, str(raises.exception))
class TestUFuncsMisc(TestCase):
# Test for miscellaneous ufunc issues
def test_exp2(self):
# See issue #8898, and TargetLibraryInfo based fix in #9336
@njit
def foo(x):
return np.exp2(x)
for ty in (np.int8, np.uint16):
x = ty(2)
expected = foo.py_func(x)
got = foo(x)
self.assertPreciseEqual(expected, got)
def test_log2(self):
# See issue #8898, and TargetLibraryInfo based fix in #9336
@njit
def foo(x):
return np.log2(x)
for ty in (np.int8, np.uint16):
x = ty(2)
expected = foo.py_func(x)
got = foo(x)
self.assertPreciseEqual(expected, got)
if __name__ == '__main__':
unittest.main()