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


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:07:05