Scarab  v2.11.1
Project 8 C++ Utility Library
test_numpy_vectorize.py
Go to the documentation of this file.
1 import pytest
2 from pybind11_tests import numpy_vectorize as m
3 
4 pytestmark = pytest.requires_numpy
5 
6 with pytest.suppress(ImportError):
7  import numpy as np
8 
9 
10 def test_vectorize(capture):
11  assert np.isclose(m.vectorized_func3(np.array(3 + 7j)), [6 + 14j])
12 
13  for f in [m.vectorized_func, m.vectorized_func2]:
14  with capture:
15  assert np.isclose(f(1, 2, 3), 6)
16  assert capture == "my_func(x:int=1, y:float=2, z:float=3)"
17  with capture:
18  assert np.isclose(f(np.array(1), np.array(2), 3), 6)
19  assert capture == "my_func(x:int=1, y:float=2, z:float=3)"
20  with capture:
21  assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36])
22  assert capture == """
23  my_func(x:int=1, y:float=2, z:float=3)
24  my_func(x:int=3, y:float=4, z:float=3)
25  """
26  with capture:
27  a = np.array([[1, 2], [3, 4]], order='F')
28  b = np.array([[10, 20], [30, 40]], order='F')
29  c = 3
30  result = f(a, b, c)
31  assert np.allclose(result, a * b * c)
32  assert result.flags.f_contiguous
33  # All inputs are F order and full or singletons, so we the result is in col-major order:
34  assert capture == """
35  my_func(x:int=1, y:float=10, z:float=3)
36  my_func(x:int=3, y:float=30, z:float=3)
37  my_func(x:int=2, y:float=20, z:float=3)
38  my_func(x:int=4, y:float=40, z:float=3)
39  """
40  with capture:
41  a, b, c = np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3
42  assert np.allclose(f(a, b, c), a * b * c)
43  assert capture == """
44  my_func(x:int=1, y:float=2, z:float=3)
45  my_func(x:int=3, y:float=4, z:float=3)
46  my_func(x:int=5, y:float=6, z:float=3)
47  my_func(x:int=7, y:float=8, z:float=3)
48  my_func(x:int=9, y:float=10, z:float=3)
49  my_func(x:int=11, y:float=12, z:float=3)
50  """
51  with capture:
52  a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2
53  assert np.allclose(f(a, b, c), a * b * c)
54  assert capture == """
55  my_func(x:int=1, y:float=2, z:float=2)
56  my_func(x:int=2, y:float=3, z:float=2)
57  my_func(x:int=3, y:float=4, z:float=2)
58  my_func(x:int=4, y:float=2, z:float=2)
59  my_func(x:int=5, y:float=3, z:float=2)
60  my_func(x:int=6, y:float=4, z:float=2)
61  """
62  with capture:
63  a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2
64  assert np.allclose(f(a, b, c), a * b * c)
65  assert capture == """
66  my_func(x:int=1, y:float=2, z:float=2)
67  my_func(x:int=2, y:float=2, z:float=2)
68  my_func(x:int=3, y:float=2, z:float=2)
69  my_func(x:int=4, y:float=3, z:float=2)
70  my_func(x:int=5, y:float=3, z:float=2)
71  my_func(x:int=6, y:float=3, z:float=2)
72  """
73  with capture:
74  a, b, c = np.array([[1, 2, 3], [4, 5, 6]], order='F'), np.array([[2], [3]]), 2
75  assert np.allclose(f(a, b, c), a * b * c)
76  assert capture == """
77  my_func(x:int=1, y:float=2, z:float=2)
78  my_func(x:int=2, y:float=2, z:float=2)
79  my_func(x:int=3, y:float=2, z:float=2)
80  my_func(x:int=4, y:float=3, z:float=2)
81  my_func(x:int=5, y:float=3, z:float=2)
82  my_func(x:int=6, y:float=3, z:float=2)
83  """
84  with capture:
85  a, b, c = np.array([[1, 2, 3], [4, 5, 6]])[::, ::2], np.array([[2], [3]]), 2
86  assert np.allclose(f(a, b, c), a * b * c)
87  assert capture == """
88  my_func(x:int=1, y:float=2, z:float=2)
89  my_func(x:int=3, y:float=2, z:float=2)
90  my_func(x:int=4, y:float=3, z:float=2)
91  my_func(x:int=6, y:float=3, z:float=2)
92  """
93  with capture:
94  a, b, c = np.array([[1, 2, 3], [4, 5, 6]], order='F')[::, ::2], np.array([[2], [3]]), 2
95  assert np.allclose(f(a, b, c), a * b * c)
96  assert capture == """
97  my_func(x:int=1, y:float=2, z:float=2)
98  my_func(x:int=3, y:float=2, z:float=2)
99  my_func(x:int=4, y:float=3, z:float=2)
100  my_func(x:int=6, y:float=3, z:float=2)
101  """
102 
103 
105  assert m.selective_func(np.array([1], dtype=np.int32)) == "Int branch taken."
106  assert m.selective_func(np.array([1.0], dtype=np.float32)) == "Float branch taken."
107  assert m.selective_func(np.array([1.0j], dtype=np.complex64)) == "Complex float branch taken."
108 
109 
110 def test_docs(doc):
111  assert doc(m.vectorized_func) == """
112  vectorized_func(arg0: numpy.ndarray[int32], arg1: numpy.ndarray[float32], arg2: numpy.ndarray[float64]) -> object
113  """ # noqa: E501 line too long
114 
115 
117  trivial, vectorized_is_trivial = m.trivial, m.vectorized_is_trivial
118 
119  assert vectorized_is_trivial(1, 2, 3) == trivial.c_trivial
120  assert vectorized_is_trivial(np.array(1), np.array(2), 3) == trivial.c_trivial
121  assert vectorized_is_trivial(np.array([1, 3]), np.array([2, 4]), 3) == trivial.c_trivial
122  assert trivial.c_trivial == vectorized_is_trivial(
123  np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3)
124  assert vectorized_is_trivial(
125  np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2) == trivial.non_trivial
126  assert vectorized_is_trivial(
127  np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2) == trivial.non_trivial
128  z1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype='int32')
129  z2 = np.array(z1, dtype='float32')
130  z3 = np.array(z1, dtype='float64')
131  assert vectorized_is_trivial(z1, z2, z3) == trivial.c_trivial
132  assert vectorized_is_trivial(1, z2, z3) == trivial.c_trivial
133  assert vectorized_is_trivial(z1, 1, z3) == trivial.c_trivial
134  assert vectorized_is_trivial(z1, z2, 1) == trivial.c_trivial
135  assert vectorized_is_trivial(z1[::2, ::2], 1, 1) == trivial.non_trivial
136  assert vectorized_is_trivial(1, 1, z1[::2, ::2]) == trivial.c_trivial
137  assert vectorized_is_trivial(1, 1, z3[::2, ::2]) == trivial.non_trivial
138  assert vectorized_is_trivial(z1, 1, z3[1::4, 1::4]) == trivial.c_trivial
139 
140  y1 = np.array(z1, order='F')
141  y2 = np.array(y1)
142  y3 = np.array(y1)
143  assert vectorized_is_trivial(y1, y2, y3) == trivial.f_trivial
144  assert vectorized_is_trivial(y1, 1, 1) == trivial.f_trivial
145  assert vectorized_is_trivial(1, y2, 1) == trivial.f_trivial
146  assert vectorized_is_trivial(1, 1, y3) == trivial.f_trivial
147  assert vectorized_is_trivial(y1, z2, 1) == trivial.non_trivial
148  assert vectorized_is_trivial(z1[1::4, 1::4], y2, 1) == trivial.f_trivial
149  assert vectorized_is_trivial(y1[1::4, 1::4], z2, 1) == trivial.c_trivial
150 
151  assert m.vectorized_func(z1, z2, z3).flags.c_contiguous
152  assert m.vectorized_func(y1, y2, y3).flags.f_contiguous
153  assert m.vectorized_func(z1, 1, 1).flags.c_contiguous
154  assert m.vectorized_func(1, y2, 1).flags.f_contiguous
155  assert m.vectorized_func(z1[1::4, 1::4], y2, 1).flags.f_contiguous
156  assert m.vectorized_func(y1[1::4, 1::4], z2, 1).flags.c_contiguous
157 
158 
160  assert doc(m.vec_passthrough) == (
161  "vec_passthrough(" + ", ".join([
162  "arg0: float",
163  "arg1: numpy.ndarray[float64]",
164  "arg2: numpy.ndarray[float64]",
165  "arg3: numpy.ndarray[int32]",
166  "arg4: int",
167  "arg5: m.numpy_vectorize.NonPODClass",
168  "arg6: numpy.ndarray[float64]"]) + ") -> object")
169 
170  b = np.array([[10, 20, 30]], dtype='float64')
171  c = np.array([100, 200]) # NOT a vectorized argument
172  d = np.array([[1000], [2000], [3000]], dtype='int')
173  g = np.array([[1000000, 2000000, 3000000]], dtype='int') # requires casting
174  assert np.all(
175  m.vec_passthrough(1, b, c, d, 10000, m.NonPODClass(100000), g) ==
176  np.array([[1111111, 2111121, 3111131],
177  [1112111, 2112121, 3112131],
178  [1113111, 2113121, 3113131]]))
179 
180 
182  o = m.VectorizeTestClass(3)
183  x = np.array([1, 2], dtype='int')
184  y = np.array([[10], [20]], dtype='float32')
185  assert np.all(o.method(x, y) == [[14, 15], [24, 25]])
186 
187 
189  assert not isinstance(m.vectorized_func(1, 2, 3), np.ndarray)
190  assert not isinstance(m.vectorized_func(np.array(1), 2, 3), np.ndarray)
191  z = m.vectorized_func([1], 2, 3)
192  assert isinstance(z, np.ndarray)
193  assert z.shape == (1, )
194  z = m.vectorized_func(1, [[[2]]], 3)
195  assert isinstance(z, np.ndarray)
196  assert z.shape == (1, 1, 1)
return isinstance(obj, type)
def doc()
Definition: conftest.py:152
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
Definition: CLI11.hpp:277