Warning, /jana2/src/python/externals/pybind11-2.10.3/tests/test_eigen_tensor.inl is written in an unsupported language. File is not indexed.
0001 /*
0002 tests/eigen_tensor.cpp -- automatic conversion of Eigen Tensor
0003
0004 All rights reserved. Use of this source code is governed by a
0005 BSD-style license that can be found in the LICENSE file.
0006 */
0007
0008 #include <pybind11/eigen/tensor.h>
0009
0010 PYBIND11_NAMESPACE_BEGIN(eigen_tensor_test)
0011
0012 namespace py = pybind11;
0013
0014 PYBIND11_WARNING_DISABLE_MSVC(4127)
0015
0016 template <typename M>
0017 void reset_tensor(M &x) {
0018 for (int i = 0; i < x.dimension(0); i++) {
0019 for (int j = 0; j < x.dimension(1); j++) {
0020 for (int k = 0; k < x.dimension(2); k++) {
0021 x(i, j, k) = i * (5 * 2) + j * 2 + k;
0022 }
0023 }
0024 }
0025 }
0026
0027 template <typename M>
0028 bool check_tensor(M &x) {
0029 for (int i = 0; i < x.dimension(0); i++) {
0030 for (int j = 0; j < x.dimension(1); j++) {
0031 for (int k = 0; k < x.dimension(2); k++) {
0032 if (x(i, j, k) != (i * (5 * 2) + j * 2 + k)) {
0033 return false;
0034 }
0035 }
0036 }
0037 }
0038 return true;
0039 }
0040
0041 template <int Options>
0042 Eigen::Tensor<double, 3, Options> &get_tensor() {
0043 static Eigen::Tensor<double, 3, Options> *x;
0044
0045 if (!x) {
0046 x = new Eigen::Tensor<double, 3, Options>(3, 5, 2);
0047 reset_tensor(*x);
0048 }
0049
0050 return *x;
0051 }
0052
0053 template <int Options>
0054 Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> &get_tensor_map() {
0055 static Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> *x;
0056
0057 if (!x) {
0058 x = new Eigen::TensorMap<Eigen::Tensor<double, 3, Options>>(get_tensor<Options>());
0059 }
0060
0061 return *x;
0062 }
0063
0064 template <int Options>
0065 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> &get_fixed_tensor() {
0066 static Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> *x;
0067
0068 if (!x) {
0069 Eigen::aligned_allocator<Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>>
0070 allocator;
0071 x = new (allocator.allocate(1))
0072 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>();
0073 reset_tensor(*x);
0074 }
0075
0076 return *x;
0077 }
0078
0079 template <int Options>
0080 const Eigen::Tensor<double, 3, Options> &get_const_tensor() {
0081 return get_tensor<Options>();
0082 }
0083
0084 template <int Options>
0085 struct CustomExample {
0086 CustomExample() : member(get_tensor<Options>()), view_member(member) {}
0087
0088 Eigen::Tensor<double, 3, Options> member;
0089 Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> view_member;
0090 };
0091
0092 template <int Options>
0093 void init_tensor_module(pybind11::module &m) {
0094 const char *needed_options = "";
0095 if (Options == Eigen::ColMajor) {
0096 needed_options = "F";
0097 } else {
0098 needed_options = "C";
0099 }
0100 m.attr("needed_options") = needed_options;
0101
0102 m.def("setup", []() {
0103 reset_tensor(get_tensor<Options>());
0104 reset_tensor(get_fixed_tensor<Options>());
0105 });
0106
0107 m.def("is_ok", []() {
0108 return check_tensor(get_tensor<Options>()) && check_tensor(get_fixed_tensor<Options>());
0109 });
0110
0111 py::class_<CustomExample<Options>>(m, "CustomExample", py::module_local())
0112 .def(py::init<>())
0113 .def_readonly(
0114 "member", &CustomExample<Options>::member, py::return_value_policy::reference_internal)
0115 .def_readonly("member_view",
0116 &CustomExample<Options>::view_member,
0117 py::return_value_policy::reference_internal);
0118
0119 m.def(
0120 "copy_fixed_tensor",
0121 []() { return &get_fixed_tensor<Options>(); },
0122 py::return_value_policy::copy);
0123
0124 m.def(
0125 "copy_tensor", []() { return &get_tensor<Options>(); }, py::return_value_policy::copy);
0126
0127 m.def(
0128 "copy_const_tensor",
0129 []() { return &get_const_tensor<Options>(); },
0130 py::return_value_policy::copy);
0131
0132 m.def(
0133 "move_fixed_tensor_copy",
0134 []() -> Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> {
0135 return get_fixed_tensor<Options>();
0136 },
0137 py::return_value_policy::move);
0138
0139 m.def(
0140 "move_tensor_copy",
0141 []() -> Eigen::Tensor<double, 3, Options> { return get_tensor<Options>(); },
0142 py::return_value_policy::move);
0143
0144 m.def(
0145 "move_const_tensor",
0146 []() -> const Eigen::Tensor<double, 3, Options> & { return get_const_tensor<Options>(); },
0147 py::return_value_policy::move);
0148
0149 m.def(
0150 "take_fixed_tensor",
0151
0152 []() {
0153 Eigen::aligned_allocator<
0154 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>>
0155 allocator;
0156 return new (allocator.allocate(1))
0157 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>(
0158 get_fixed_tensor<Options>());
0159 },
0160 py::return_value_policy::take_ownership);
0161
0162 m.def(
0163 "take_tensor",
0164 []() { return new Eigen::Tensor<double, 3, Options>(get_tensor<Options>()); },
0165 py::return_value_policy::take_ownership);
0166
0167 m.def(
0168 "take_const_tensor",
0169 []() -> const Eigen::Tensor<double, 3, Options> * {
0170 return new Eigen::Tensor<double, 3, Options>(get_tensor<Options>());
0171 },
0172 py::return_value_policy::take_ownership);
0173
0174 m.def(
0175 "take_view_tensor",
0176 []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> * {
0177 return new Eigen::TensorMap<Eigen::Tensor<double, 3, Options>>(get_tensor<Options>());
0178 },
0179 py::return_value_policy::take_ownership);
0180
0181 m.def(
0182 "reference_tensor",
0183 []() { return &get_tensor<Options>(); },
0184 py::return_value_policy::reference);
0185
0186 m.def(
0187 "reference_tensor_v2",
0188 []() -> Eigen::Tensor<double, 3, Options> & { return get_tensor<Options>(); },
0189 py::return_value_policy::reference);
0190
0191 m.def(
0192 "reference_tensor_internal",
0193 []() { return &get_tensor<Options>(); },
0194 py::return_value_policy::reference_internal);
0195
0196 m.def(
0197 "reference_fixed_tensor",
0198 []() { return &get_tensor<Options>(); },
0199 py::return_value_policy::reference);
0200
0201 m.def(
0202 "reference_const_tensor",
0203 []() { return &get_const_tensor<Options>(); },
0204 py::return_value_policy::reference);
0205
0206 m.def(
0207 "reference_const_tensor_v2",
0208 []() -> const Eigen::Tensor<double, 3, Options> & { return get_const_tensor<Options>(); },
0209 py::return_value_policy::reference);
0210
0211 m.def(
0212 "reference_view_of_tensor",
0213 []() -> Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> {
0214 return get_tensor_map<Options>();
0215 },
0216 py::return_value_policy::reference);
0217
0218 m.def(
0219 "reference_view_of_tensor_v2",
0220 // NOLINTNEXTLINE(readability-const-return-type)
0221 []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> {
0222 return get_tensor_map<Options>(); // NOLINT(readability-const-return-type)
0223 }, // NOLINT(readability-const-return-type)
0224 py::return_value_policy::reference);
0225
0226 m.def(
0227 "reference_view_of_tensor_v3",
0228 []() -> Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> * {
0229 return &get_tensor_map<Options>();
0230 },
0231 py::return_value_policy::reference);
0232
0233 m.def(
0234 "reference_view_of_tensor_v4",
0235 []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> * {
0236 return &get_tensor_map<Options>();
0237 },
0238 py::return_value_policy::reference);
0239
0240 m.def(
0241 "reference_view_of_tensor_v5",
0242 []() -> Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> & {
0243 return get_tensor_map<Options>();
0244 },
0245 py::return_value_policy::reference);
0246
0247 m.def(
0248 "reference_view_of_tensor_v6",
0249 []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> & {
0250 return get_tensor_map<Options>();
0251 },
0252 py::return_value_policy::reference);
0253
0254 m.def(
0255 "reference_view_of_fixed_tensor",
0256 []() {
0257 return Eigen::TensorMap<
0258 Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>>(
0259 get_fixed_tensor<Options>());
0260 },
0261 py::return_value_policy::reference);
0262
0263 m.def("round_trip_tensor",
0264 [](const Eigen::Tensor<double, 3, Options> &tensor) { return tensor; });
0265
0266 m.def(
0267 "round_trip_tensor_noconvert",
0268 [](const Eigen::Tensor<double, 3, Options> &tensor) { return tensor; },
0269 py::arg("tensor").noconvert());
0270
0271 m.def("round_trip_tensor2",
0272 [](const Eigen::Tensor<int32_t, 3, Options> &tensor) { return tensor; });
0273
0274 m.def("round_trip_fixed_tensor",
0275 [](const Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> &tensor) {
0276 return tensor;
0277 });
0278
0279 m.def(
0280 "round_trip_view_tensor",
0281 [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> view) { return view; },
0282 py::return_value_policy::reference);
0283
0284 m.def(
0285 "round_trip_view_tensor_ref",
0286 [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> &view) { return view; },
0287 py::return_value_policy::reference);
0288
0289 m.def(
0290 "round_trip_view_tensor_ptr",
0291 [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> *view) { return view; },
0292 py::return_value_policy::reference);
0293
0294 m.def(
0295 "round_trip_aligned_view_tensor",
0296 [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>, Eigen::Aligned> view) {
0297 return view;
0298 },
0299 py::return_value_policy::reference);
0300
0301 m.def(
0302 "round_trip_const_view_tensor",
0303 [](Eigen::TensorMap<const Eigen::Tensor<double, 3, Options>> view) {
0304 return Eigen::Tensor<double, 3, Options>(view);
0305 },
0306 py::return_value_policy::move);
0307
0308 m.def(
0309 "round_trip_rank_0",
0310 [](const Eigen::Tensor<double, 0, Options> &tensor) { return tensor; },
0311 py::return_value_policy::move);
0312
0313 m.def(
0314 "round_trip_rank_0_noconvert",
0315 [](const Eigen::Tensor<double, 0, Options> &tensor) { return tensor; },
0316 py::arg("tensor").noconvert(),
0317 py::return_value_policy::move);
0318
0319 m.def(
0320 "round_trip_rank_0_view",
0321 [](Eigen::TensorMap<Eigen::Tensor<double, 0, Options>> &tensor) { return tensor; },
0322 py::return_value_policy::reference);
0323 }
0324
0325 void test_module(py::module_ &m) {
0326 auto f_style = m.def_submodule("f_style");
0327 auto c_style = m.def_submodule("c_style");
0328
0329 init_tensor_module<Eigen::ColMajor>(f_style);
0330 init_tensor_module<Eigen::RowMajor>(c_style);
0331 }
0332
0333 PYBIND11_NAMESPACE_END(eigen_tensor_test)