test_eigen_tensor.py
Go to the documentation of this file.
1 import sys
2 
3 import pytest
4 
5 np = pytest.importorskip("numpy")
6 eigen_tensor = pytest.importorskip("pybind11_tests.eigen_tensor")
7 submodules = [eigen_tensor.c_style, eigen_tensor.f_style]
8 try:
9  import eigen_tensor_avoid_stl_array as avoid
10 
11  submodules += [avoid.c_style, avoid.f_style]
12 except ImportError as e:
13  # Ensure config, build, toolchain, etc. issues are not masked here:
14  msg = (
15  "import eigen_tensor_avoid_stl_array FAILED, while "
16  "import pybind11_tests.eigen_tensor succeeded. "
17  "Please ensure that "
18  "test_eigen_tensor.cpp & "
19  "eigen_tensor_avoid_stl_array.cpp "
20  "are built together (or both are not built if Eigen is not available)."
21  )
22  raise RuntimeError(msg) from e
23 
24 tensor_ref = np.empty((3, 5, 2), dtype=np.int64)
25 
26 for i in range(tensor_ref.shape[0]):
27  for j in range(tensor_ref.shape[1]):
28  for k in range(tensor_ref.shape[2]):
29  tensor_ref[i, j, k] = i * (5 * 2) + j * 2 + k
30 
31 indices = (2, 3, 1)
32 
33 
34 @pytest.fixture(autouse=True)
35 def cleanup():
36  for module in submodules:
37  module.setup()
38 
39  yield
40 
41  for module in submodules:
42  assert module.is_ok()
43 
44 
46  pytest.importorskip("eigen_tensor_avoid_stl_array")
47  assert len(submodules) == 4
48 
49 
50 def assert_equal_tensor_ref(mat, writeable=True, modified=None):
51  assert mat.flags.writeable == writeable
52 
53  copy = np.array(tensor_ref)
54  if modified is not None:
55  copy[indices] = modified
56 
57  np.testing.assert_array_equal(mat, copy)
58 
59 
60 @pytest.mark.parametrize("m", submodules)
61 @pytest.mark.parametrize("member_name", ["member", "member_view"])
62 def test_reference_internal(m, member_name):
63  if not hasattr(sys, "getrefcount"):
64  pytest.skip("No reference counting")
65  foo = m.CustomExample()
66  counts = sys.getrefcount(foo)
67  mem = getattr(foo, member_name)
68  assert_equal_tensor_ref(mem, writeable=False)
69  new_counts = sys.getrefcount(foo)
70  assert new_counts == counts + 1
71  assert_equal_tensor_ref(mem, writeable=False)
72  del mem
73  assert sys.getrefcount(foo) == counts
74 
75 
76 assert_equal_funcs = [
77  "copy_tensor",
78  "copy_fixed_tensor",
79  "copy_const_tensor",
80  "move_tensor_copy",
81  "move_fixed_tensor_copy",
82  "take_tensor",
83  "take_fixed_tensor",
84  "reference_tensor",
85  "reference_tensor_v2",
86  "reference_fixed_tensor",
87  "reference_view_of_tensor",
88  "reference_view_of_tensor_v3",
89  "reference_view_of_tensor_v5",
90  "reference_view_of_fixed_tensor",
91 ]
92 
93 assert_equal_const_funcs = [
94  "reference_view_of_tensor_v2",
95  "reference_view_of_tensor_v4",
96  "reference_view_of_tensor_v6",
97  "reference_const_tensor",
98  "reference_const_tensor_v2",
99 ]
100 
101 
102 @pytest.mark.parametrize("m", submodules)
103 @pytest.mark.parametrize("func_name", assert_equal_funcs + assert_equal_const_funcs)
104 def test_convert_tensor_to_py(m, func_name):
105  writeable = func_name in assert_equal_funcs
106  assert_equal_tensor_ref(getattr(m, func_name)(), writeable=writeable)
107 
108 
109 @pytest.mark.parametrize("m", submodules)
111  with pytest.raises(
112  RuntimeError, match="Cannot use reference internal when there is no parent"
113  ):
114  m.reference_tensor_internal()
115 
116  with pytest.raises(RuntimeError, match="Cannot move from a constant reference"):
117  m.move_const_tensor()
118 
119  with pytest.raises(
120  RuntimeError, match="Cannot take ownership of a const reference"
121  ):
122  m.take_const_tensor()
123 
124  with pytest.raises(
125  RuntimeError,
126  match="Invalid return_value_policy for Eigen Map type, must be either reference or reference_internal",
127  ):
128  m.take_view_tensor()
129 
130 
131 @pytest.mark.parametrize("m", submodules)
133  with pytest.raises(
134  TypeError, match=r"^round_trip_tensor\(\): incompatible function arguments"
135  ):
136  m.round_trip_tensor(np.zeros((2, 3)))
137 
138  with pytest.raises(TypeError, match=r"^Cannot cast array data from dtype"):
139  m.round_trip_tensor(np.zeros(dtype=np.str_, shape=(2, 3, 1)))
140 
141  with pytest.raises(
142  TypeError,
143  match=r"^round_trip_tensor_noconvert\(\): incompatible function arguments",
144  ):
145  m.round_trip_tensor_noconvert(tensor_ref)
146 
148  m.round_trip_tensor_noconvert(tensor_ref.astype(np.float64))
149  )
150 
151  bad_options = "C" if m.needed_options == "F" else "F"
152  # Shape, dtype and the order need to be correct for a TensorMap cast
153  with pytest.raises(
154  TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
155  ):
156  m.round_trip_view_tensor(
157  np.zeros((3, 5, 2), dtype=np.float64, order=bad_options)
158  )
159 
160  with pytest.raises(
161  TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
162  ):
163  m.round_trip_view_tensor(
164  np.zeros((3, 5, 2), dtype=np.float32, order=m.needed_options)
165  )
166 
167  with pytest.raises(
168  TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
169  ):
170  m.round_trip_view_tensor(
171  np.zeros((3, 5), dtype=np.float64, order=m.needed_options)
172  )
173 
174  temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
175  with pytest.raises(
176  TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
177  ):
178  m.round_trip_view_tensor(
179  temp[:, ::-1, :],
180  )
181 
182  temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)
183  temp.setflags(write=False)
184  with pytest.raises(
185  TypeError, match=r"^round_trip_view_tensor\(\): incompatible function arguments"
186  ):
187  m.round_trip_view_tensor(temp)
188 
189 
190 @pytest.mark.parametrize("m", submodules)
192  a = m.reference_tensor()
193  temp = a[indices]
194  a[indices] = 100
195  assert_equal_tensor_ref(m.copy_const_tensor(), modified=100)
196  a[indices] = temp
197  assert_equal_tensor_ref(m.copy_const_tensor())
198 
199  a = m.reference_view_of_tensor()
200  a[indices] = 100
201  assert_equal_tensor_ref(m.copy_const_tensor(), modified=100)
202  a[indices] = temp
203  assert_equal_tensor_ref(m.copy_const_tensor())
204 
205 
206 @pytest.mark.parametrize("m", submodules)
208  assert_equal_tensor_ref(m.round_trip_tensor(tensor_ref))
209 
210  with pytest.raises(TypeError, match="^Cannot cast array data from"):
211  assert_equal_tensor_ref(m.round_trip_tensor2(tensor_ref))
212 
213  assert_equal_tensor_ref(m.round_trip_tensor2(np.array(tensor_ref, dtype=np.int32)))
214  assert_equal_tensor_ref(m.round_trip_fixed_tensor(tensor_ref))
215  assert_equal_tensor_ref(m.round_trip_aligned_view_tensor(m.reference_tensor()))
216 
217  copy = np.array(tensor_ref, dtype=np.float64, order=m.needed_options)
218  assert_equal_tensor_ref(m.round_trip_view_tensor(copy))
219  assert_equal_tensor_ref(m.round_trip_view_tensor_ref(copy))
220  assert_equal_tensor_ref(m.round_trip_view_tensor_ptr(copy))
221  copy.setflags(write=False)
222  assert_equal_tensor_ref(m.round_trip_const_view_tensor(copy))
223 
224  np.testing.assert_array_equal(
225  tensor_ref[:, ::-1, :], m.round_trip_tensor(tensor_ref[:, ::-1, :])
226  )
227 
228  assert m.round_trip_rank_0(np.float64(3.5)) == 3.5
229  assert m.round_trip_rank_0(3.5) == 3.5
230 
231  with pytest.raises(
232  TypeError,
233  match=r"^round_trip_rank_0_noconvert\(\): incompatible function arguments",
234  ):
235  m.round_trip_rank_0_noconvert(np.float64(3.5))
236 
237  with pytest.raises(
238  TypeError,
239  match=r"^round_trip_rank_0_noconvert\(\): incompatible function arguments",
240  ):
241  m.round_trip_rank_0_noconvert(3.5)
242 
243  with pytest.raises(
244  TypeError, match=r"^round_trip_rank_0_view\(\): incompatible function arguments"
245  ):
246  m.round_trip_rank_0_view(np.float64(3.5))
247 
248  with pytest.raises(
249  TypeError, match=r"^round_trip_rank_0_view\(\): incompatible function arguments"
250  ):
251  m.round_trip_rank_0_view(3.5)
252 
253 
254 @pytest.mark.parametrize("m", submodules)
256  # Need to create a copy that matches the type on the C side
257  copy = np.array(tensor_ref, dtype=np.float64, order=m.needed_options)
258  a = m.round_trip_view_tensor(copy)
259  temp = a[indices]
260  a[indices] = 100
261  assert_equal_tensor_ref(copy, modified=100)
262  a[indices] = temp
264 
265 
266 @pytest.mark.parametrize("m", submodules)
267 def test_doc_string(m, doc):
268  assert (
269  doc(m.copy_tensor) == "copy_tensor() -> numpy.ndarray[numpy.float64[?, ?, ?]]"
270  )
271  assert (
272  doc(m.copy_fixed_tensor)
273  == "copy_fixed_tensor() -> numpy.ndarray[numpy.float64[3, 5, 2]]"
274  )
275  assert (
276  doc(m.reference_const_tensor)
277  == "reference_const_tensor() -> numpy.ndarray[numpy.float64[?, ?, ?]]"
278  )
279 
280  order_flag = f"flags.{m.needed_options.lower()}_contiguous"
281  assert doc(m.round_trip_view_tensor) == (
282  f"round_trip_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}])"
283  f" -> numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}]"
284  )
285  assert doc(m.round_trip_const_view_tensor) == (
286  f"round_trip_const_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], {order_flag}])"
287  " -> numpy.ndarray[numpy.float64[?, ?, ?]]"
288  )
test_eigen_tensor.test_references_actually_refer
def test_references_actually_refer(m)
Definition: test_eigen_tensor.py:191
hasattr
bool hasattr(handle obj, handle name)
Definition: pytypes.h:853
getattr
object getattr(handle obj, handle name)
Definition: pytypes.h:873
test_eigen_tensor.test_round_trip_references_actually_refer
def test_round_trip_references_actually_refer(m)
Definition: test_eigen_tensor.py:255
test_eigen_tensor.test_doc_string
def test_doc_string(m, doc)
Definition: test_eigen_tensor.py:267
gtsam::range
Double_ range(const Point2_ &p, const Point2_ &q)
Definition: slam/expressions.h:30
test_eigen_tensor.test_convert_tensor_to_py
def test_convert_tensor_to_py(m, func_name)
Definition: test_eigen_tensor.py:104
doc
Annotation for documentation.
Definition: attr.h:45
test_eigen_tensor.test_bad_cpp_to_python_casts
def test_bad_cpp_to_python_casts(m)
Definition: test_eigen_tensor.py:110
test_eigen_tensor.assert_equal_tensor_ref
def assert_equal_tensor_ref(mat, writeable=True, modified=None)
Definition: test_eigen_tensor.py:50
test_eigen_tensor.test_round_trip
def test_round_trip(m)
Definition: test_eigen_tensor.py:207
test_eigen_tensor.test_bad_python_to_cpp_casts
def test_bad_python_to_cpp_casts(m)
Definition: test_eigen_tensor.py:132
test_eigen_tensor.cleanup
def cleanup()
Definition: test_eigen_tensor.py:35
test_eigen_tensor.test_reference_internal
def test_reference_internal(m, member_name)
Definition: test_eigen_tensor.py:62
len
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2399
test_eigen_tensor.test_import_avoid_stl_array
def test_import_avoid_stl_array()
Definition: test_eigen_tensor.py:45


gtsam
Author(s):
autogenerated on Thu Jun 13 2024 03:08:52