| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7ea59cc commit a95cde3
18 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,9 +23,8 @@ install: | |||
| 23 | 23 | - conda update -q conda | |
| 24 | 24 | - conda info -a | |
| 25 | 25 | - conda install pytest -c conda-forge | |
| 26 | - - cd test | ||
| 27 | 26 | - conda install xtensor==0.8.0 pytest numpy pybind11==2.1.0 -c conda-forge | |
| 28 | 27 | - xcopy /S %APPVEYOR_BUILD_FOLDER%\include %MINICONDA%\include | |
| 29 | 28 | ||
| 30 | 29 | build_script: | |
| 31 | - - py.test . | ||
| 30 | + - py.test -s | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,6 +30,16 @@ | |||
| 30 | 30 | # Vim tmp files | |
| 31 | 31 | *.swp | |
| 32 | 32 | ||
| 33 | + # Build directory | ||
| 34 | + build/ | ||
| 35 | + | ||
| 36 | + # Test build artefacts | ||
| 37 | + test/test_xtensor_python | ||
| 38 | + test/CMakeCache.txt | ||
| 39 | + test/Makefile | ||
| 40 | + test/CMakeFiles/ | ||
| 41 | + test/cmake_install.cmake | ||
| 42 | + | ||
| 33 | 43 | # Documentation build artefacts | |
| 34 | 44 | docs/CMakeCache.txt | |
| 35 | 45 | docs/xml/ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -67,7 +67,6 @@ install: | |||
| 67 | 67 | - conda update -q conda | |
| 68 | 68 | # Useful for debugging any issues with conda | |
| 69 | 69 | - conda info -a | |
| 70 | - - cd test | ||
| 71 | 70 | - conda install xtensor==0.8.0 pytest numpy pybind11==2.1.0 -c conda-forge | |
| 72 | 71 | - cp -r $TRAVIS_BUILD_DIR/include/* $HOME/miniconda/include/ | |
| 73 | 72 | ||
@@ -84,4 +83,5 @@ script: | |||
| 84 | 83 | elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then | |
| 85 | 84 | export CXX=clang++ CC=clang; | |
| 86 | 85 | fi | |
| 87 | - - py.test . | ||
| 86 | + - py.test -s | ||
| 87 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,25 +43,22 @@ set(XTENSOR_PYTHON_HEADERS | |||
| 43 | 43 | ) | |
| 44 | 44 | ||
| 45 | 45 | if(BUILD_TESTS) | |
| 46 | - | ||
| 47 | 46 | include_directories(${XTENSOR_PYTHON_INCLUDE_DIR}) | |
| 48 | 47 | find_package(xtensor REQUIRED) | |
| 49 | 48 | include_directories(${xtensor_INCLUDE_DIR}) | |
| 50 | 49 | find_package(NumPy REQUIRED) | |
| 51 | 50 | include_directories(${NUMPY_INCLUDE_DIRS}) | |
| 52 | 51 | ||
| 53 | - #TODO replace this with a find_package(pybind11 REQUIRED) | ||
| 54 | - # in parent CMakeLists when pybind11 CMakeLists has been fixed. | ||
| 55 | - find_package(PythonLibs REQUIRED) | ||
| 56 | - include_directories(${PYTHON_INCLUDE_DIRS}) | ||
| 52 | + find_package(pybind11 REQUIRED) | ||
| 53 | + include_directories(${pybind11_INCLUDE_DIRS}) | ||
| 57 | 54 | ||
| 58 | - if(MSVC) | ||
| 59 | - set(PYTHON_MODULE_EXTENSION ".pyd") | ||
| 60 | - else() | ||
| 61 | - set(PYTHON_MODULE_EXTENSION ".so") | ||
| 62 | - endif() | ||
| 55 | + if(MSVC) | ||
| 56 | + set(PYTHON_MODULE_EXTENSION ".pyd") | ||
| 57 | + else() | ||
| 58 | + set(PYTHON_MODULE_EXTENSION ".so") | ||
| 59 | + endif() | ||
| 63 | 60 | ||
| 64 | - #add_subdirectory(test) | ||
| 61 | + add_subdirectory(test) | ||
| 65 | 62 | add_subdirectory(benchmark) | |
| 66 | 63 | endif() | |
| 67 | 64 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,42 +23,37 @@ PYBIND11_PLUGIN(benchmark_xtensor_python) | |||
| 23 | 23 | py::module m("benchmark_xtensor_python", "Benchmark module for xtensor python bindings"); | |
| 24 | 24 | ||
| 25 | 25 | m.def("sum_array", [](xt::pyarray<double> const& x) { | |
| 26 | - double sum = 0; | ||
| 27 | - for(auto e : x) | ||
| 28 | - sum += e; | ||
| 29 | - return sum; | ||
| 30 | - } | ||
| 31 | - ); | ||
| 26 | + double sum = 0; | ||
| 27 | + for(auto e : x) | ||
| 28 | + sum += e; | ||
| 29 | + return sum; | ||
| 30 | + }); | ||
| 32 | 31 | ||
| 33 | 32 | m.def("sum_tensor", [](xt::pytensor<double, 1> const& x) { | |
| 34 | - double sum = 0; | ||
| 35 | - for(auto e : x) | ||
| 36 | - sum += e; | ||
| 37 | - return sum; | ||
| 38 | - } | ||
| 39 | - ); | ||
| 33 | + double sum = 0; | ||
| 34 | + for(auto e : x) | ||
| 35 | + sum += e; | ||
| 36 | + return sum; | ||
| 37 | + }); | ||
| 40 | 38 | ||
| 41 | 39 | m.def("pybind_sum_array", [](py::array_t<double> const& x) { | |
| 42 | - double sum = 0; | ||
| 43 | - size_t size = x.size(); | ||
| 44 | - const double* data = x.data(0); | ||
| 45 | - for(size_t i = 0; i < size; ++i) | ||
| 46 | - sum += data[i]; | ||
| 47 | - return sum; | ||
| 48 | - } | ||
| 49 | - ); | ||
| 40 | + double sum = 0; | ||
| 41 | + size_t size = x.size(); | ||
| 42 | + const double* data = x.data(0); | ||
| 43 | + for(size_t i = 0; i < size; ++i) | ||
| 44 | + sum += data[i]; | ||
| 45 | + return sum; | ||
| 46 | + }); | ||
| 50 | 47 | ||
| 51 | 48 | m.def("rect_to_polar", [](xt::pyarray<complex_t> const& a) { | |
| 52 | - return py::make_tuple(xt::pyvectorize([](complex_t x) { return std::abs(x); })(a), | ||
| 53 | - xt::pyvectorize([](complex_t x) { return std::arg(x); })(a)); | ||
| 49 | + return py::vectorize([](complex_t x) { return std::abs(x); })(a); | ||
| 54 | 50 | }); | |
| 55 | 51 | ||
| 56 | 52 | m.def("pybind_rect_to_polar", [](py::array a) { | |
| 57 | - if (py::isinstance<py::array_t<complex_t>>(a)) | ||
| 58 | - return py::make_tuple(py::vectorize([](complex_t x) { return std::abs(x); })(a), | ||
| 59 | - py::vectorize([](complex_t x) { return std::arg(x); })(a)); | ||
| 60 | - else | ||
| 61 | - throw py::type_error("rect_to_polar unhandled type"); | ||
| 53 | + if (py::isinstance<py::array_t<complex_t>>(a)) | ||
| 54 | + return py::vectorize([](complex_t x) { return std::abs(x); })(a); | ||
| 55 | + else | ||
| 56 | + throw py::type_error("rect_to_polar unhandled type"); | ||
| 62 | 57 | }); | |
| 63 | 58 | ||
| 64 | 59 | return m.ptr(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -76,6 +76,8 @@ namespace xt | |||
| 76 | 76 | ||
| 77 | 77 | value_type operator[](size_type i) const; | |
| 78 | 78 | ||
| 79 | + size_type size() const; | ||
| 80 | + | ||
| 79 | 81 | private: | |
| 80 | 82 | ||
| 81 | 83 | const array_type* p_a; | |
@@ -108,14 +110,15 @@ namespace xt | |||
| 108 | 110 | class pyarray : public pycontainer<pyarray<T>>, | |
| 109 | 111 | public xcontainer_semantic<pyarray<T>> | |
| 110 | 112 | { | |
| 111 | - | ||
| 112 | 113 | public: | |
| 113 | 114 | ||
| 114 | 115 | using self_type = pyarray<T>; | |
| 115 | 116 | using semantic_base = xcontainer_semantic<self_type>; | |
| 116 | 117 | using base_type = pycontainer<self_type>; | |
| 117 | 118 | using container_type = typename base_type::container_type; | |
| 118 | 119 | using value_type = typename base_type::value_type; | |
| 120 | + using reference = typename base_type::reference; | ||
| 121 | + using const_reference = typename base_type::const_reference; | ||
| 119 | 122 | using pointer = typename base_type::pointer; | |
| 120 | 123 | using size_type = typename base_type::size_type; | |
| 121 | 124 | using shape_type = typename base_type::shape_type; | |
@@ -125,7 +128,9 @@ namespace xt | |||
| 125 | 128 | using inner_strides_type = typename base_type::inner_strides_type; | |
| 126 | 129 | using inner_backstrides_type = typename base_type::inner_backstrides_type; | |
| 127 | 130 | ||
| 128 | - pyarray() = default; | ||
| 131 | + pyarray(); | ||
| 132 | + pyarray(const self_type&) = default; | ||
| 133 | + pyarray(self_type&&) = default; | ||
| 129 | 134 | pyarray(const value_type& t); | |
| 130 | 135 | pyarray(nested_initializer_list_t<T, 1> t); | |
| 131 | 136 | pyarray(nested_initializer_list_t<T, 2> t); | |
@@ -138,11 +143,16 @@ namespace xt | |||
| 138 | 143 | pyarray(const pybind11::object &o); | |
| 139 | 144 | ||
| 140 | 145 | explicit pyarray(const shape_type& shape, layout l = layout::row_major); | |
| 141 | - pyarray(const shape_type& shape, const strides_type& strides); | ||
| 146 | + explicit pyarray(const shape_type& shape, const_reference value, layout l = layout::row_major); | ||
| 147 | + explicit pyarray(const shape_type& shape, const strides_type& strides, const_reference value); | ||
| 148 | + explicit pyarray(const shape_type& shape, const strides_type& strides); | ||
| 142 | 149 | ||
| 143 | 150 | template <class E> | |
| 144 | 151 | pyarray(const xexpression<E>& e); | |
| 145 | 152 | ||
| 153 | + self_type& operator=(const self_type& e) = default; | ||
| 154 | + self_type& operator=(self_type&& e) = default; | ||
| 155 | + | ||
| 146 | 156 | template <class E> | |
| 147 | 157 | self_type& operator=(const xexpression<E>& e); | |
| 148 | 158 | ||
@@ -182,6 +192,12 @@ namespace xt | |||
| 182 | 192 | { | |
| 183 | 193 | } | |
| 184 | 194 | ||
| 195 | + template <class A> | ||
| 196 | + inline auto pyarray_backstrides<A>::size() const -> size_type | ||
| 197 | + { | ||
| 198 | + return p_a->dimension(); | ||
| 199 | + } | ||
| 200 | + | ||
| 185 | 201 | template <class A> | |
| 186 | 202 | inline auto pyarray_backstrides<A>::operator[](size_type i) const -> value_type | |
| 187 | 203 | { | |
@@ -194,6 +210,16 @@ namespace xt | |||
| 194 | 210 | * pyarray implementation * | |
| 195 | 211 | **************************/ | |
| 196 | 212 | ||
| 213 | + template <class T> | ||
| 214 | + inline pyarray<T>::pyarray() | ||
| 215 | + { | ||
| 216 | + // TODO: avoid allocation | ||
| 217 | + shape_type shape = make_sequence<shape_type>(0, size_type(1)); | ||
| 218 | + strides_type strides = make_sequence<strides_type>(0, size_type(0)); | ||
| 219 | + init_array(shape, strides); | ||
| 220 | + m_data[0] = T(); | ||
| 221 | + } | ||
| 222 | + | ||
| 197 | 223 | template <class T> | |
| 198 | 224 | inline pyarray<T>::pyarray(const value_type& t) | |
| 199 | 225 | { | |
@@ -260,9 +286,25 @@ namespace xt | |||
| 260 | 286 | template <class T> | |
| 261 | 287 | inline pyarray<T>::pyarray(const shape_type& shape, layout l) | |
| 262 | 288 | { | |
| 263 | - strides_type strides; | ||
| 289 | + strides_type strides(shape.size()); | ||
| 290 | + compute_strides(shape, l, strides); | ||
| 291 | + init_array(shape, strides); | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + template <class T> | ||
| 295 | + inline pyarray<T>::pyarray(const shape_type& shape, const_reference value, layout l) | ||
| 296 | + { | ||
| 297 | + strides_type strides(shape.size()); | ||
| 264 | 298 | compute_strides(shape, l, strides); | |
| 265 | 299 | init_array(shape, strides); | |
| 300 | + std::fill(m_data.begin(), m_data.end(), value); | ||
| 301 | + } | ||
| 302 | + | ||
| 303 | + template <class T> | ||
| 304 | + inline pyarray<T>::pyarray(const shape_type& shape, const strides_type& strides, const_reference value) | ||
| 305 | + { | ||
| 306 | + init_array(shape, strides); | ||
| 307 | + std::fill(m_data.begin(), m_data.end(), value); | ||
| 266 | 308 | } | |
| 267 | 309 | ||
| 268 | 310 | template <class T> | |
@@ -306,7 +348,7 @@ namespace xt | |||
| 306 | 348 | [](auto v) { return sizeof(T) * v; }); | |
| 307 | 349 | ||
| 308 | 350 | int flags = NPY_ARRAY_ALIGNED; | |
| 309 | - if(!std::is_const<T>::value) | ||
| 351 | + if (!std::is_const<T>::value) | ||
| 310 | 352 | { | |
| 311 | 353 | flags |= NPY_ARRAY_WRITEABLE; | |
| 312 | 354 | } | |
@@ -319,8 +361,10 @@ namespace xt | |||
| 319 | 361 | nullptr, static_cast<int>(sizeof(T)), flags, nullptr) | |
| 320 | 362 | ); | |
| 321 | 363 | ||
| 322 | - if(!tmp) | ||
| 364 | + if (!tmp) | ||
| 365 | + { | ||
| 323 | 366 | throw std::runtime_error("NumPy: unable to create ndarray"); | |
| 367 | + } | ||
| 324 | 368 | ||
| 325 | 369 | this->m_ptr = tmp.release().ptr(); | |
| 326 | 370 | init_from_python(); | |
@@ -370,7 +414,6 @@ namespace xt | |||
| 370 | 414 | { | |
| 371 | 415 | return m_data; | |
| 372 | 416 | } | |
| 373 | - | ||
| 374 | 417 | } | |
| 375 | 418 | ||
| 376 | 419 | #endif | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,16 +17,39 @@ | |||
| 17 | 17 | #include "pybind11/common.h" | |
| 18 | 18 | #include "pybind11/complex.h" | |
| 19 | 19 | ||
| 20 | + #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION | ||
| 21 | + #include "numpy/arrayobject.h" | ||
| 22 | + | ||
| 20 | 23 | #include "xtensor/xcontainer.hpp" | |
| 21 | 24 | ||
| 22 | 25 | namespace xt | |
| 23 | 26 | { | |
| 27 | + static bool is_numpy_imported = false; | ||
| 28 | + | ||
| 29 | + class numpy_import | ||
| 30 | + { | ||
| 31 | + protected: | ||
| 32 | + | ||
| 33 | + inline numpy_import() | ||
| 34 | + { | ||
| 35 | + if (!is_numpy_imported) | ||
| 36 | + { | ||
| 37 | + _import_array(); | ||
| 38 | + is_numpy_imported = true; | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + numpy_import(const numpy_import&) = default; | ||
| 43 | + numpy_import(numpy_import&&) = default; | ||
| 44 | + numpy_import& operator=(const numpy_import&) = default; | ||
| 45 | + numpy_import& operator=(numpy_import&&) = default; | ||
| 46 | + }; | ||
| 24 | 47 | ||
| 25 | 48 | template <class D> | |
| 26 | 49 | class pycontainer : public pybind11::object, | |
| 27 | - public xcontainer<D> | ||
| 50 | + public xcontainer<D>, | ||
| 51 | + private numpy_import | ||
| 28 | 52 | { | |
| 29 | - | ||
| 30 | 53 | public: | |
| 31 | 54 | ||
| 32 | 55 | using derived_type = D; | |
@@ -64,12 +87,13 @@ namespace xt | |||
| 64 | 87 | void reshape(const shape_type& shape, const strides_type& strides); | |
| 65 | 88 | ||
| 66 | 89 | using base_type::operator(); | |
| 90 | + using base_type::operator[]; | ||
| 67 | 91 | using base_type::begin; | |
| 68 | 92 | using base_type::end; | |
| 69 | 93 | ||
| 70 | 94 | protected: | |
| 71 | 95 | ||
| 72 | - pycontainer() = default; | ||
| 96 | + pycontainer(); | ||
| 73 | 97 | ~pycontainer() = default; | |
| 74 | 98 | ||
| 75 | 99 | pycontainer(pybind11::handle h, borrowed_t); | |
@@ -116,6 +140,12 @@ namespace xt | |||
| 116 | 140 | * pycontainer implementation * | |
| 117 | 141 | ******************************/ | |
| 118 | 142 | ||
| 143 | + template <class D> | ||
| 144 | + inline pycontainer<D>::pycontainer() | ||
| 145 | + : pybind11::object() | ||
| 146 | + { | ||
| 147 | + } | ||
| 148 | + | ||
| 119 | 149 | template <class D> | |
| 120 | 150 | inline pycontainer<D>::pycontainer(pybind11::handle h, borrowed_t) | |
| 121 | 151 | : pybind11::object(h, borrowed) | |
@@ -132,16 +162,20 @@ namespace xt | |||
| 132 | 162 | inline pycontainer<D>::pycontainer(const pybind11::object& o) | |
| 133 | 163 | : pybind11::object(raw_array_t(o.ptr()), pybind11::object::stolen) | |
| 134 | 164 | { | |
| 135 | - if(!this->m_ptr) | ||
| 165 | + if (!this->m_ptr) | ||
| 166 | + { | ||
| 136 | 167 | throw pybind11::error_already_set(); | |
| 168 | + } | ||
| 137 | 169 | } | |
| 138 | 170 | ||
| 139 | 171 | template <class D> | |
| 140 | 172 | inline auto pycontainer<D>::ensure(pybind11::handle h) -> derived_type | |
| 141 | 173 | { | |
| 142 | 174 | auto result = pybind11::reinterpret_steal<derived_type>(raw_array_t(h.ptr())); | |
| 143 | - if(result.ptr() == nullptr) | ||
| 175 | + if (result.ptr() == nullptr) | ||
| 176 | + { | ||
| 144 | 177 | PyErr_Clear(); | |
| 178 | + } | ||
| 145 | 179 | return result; | |
| 146 | 180 | } | |
| 147 | 181 | ||
@@ -156,9 +190,10 @@ namespace xt | |||
| 156 | 190 | template <class D> | |
| 157 | 191 | inline PyObject* pycontainer<D>::raw_array_t(PyObject* ptr) | |
| 158 | 192 | { | |
| 159 | - if(ptr == nullptr) | ||
| 193 | + if (ptr == nullptr) | ||
| 194 | + { | ||
| 160 | 195 | return nullptr; | |
| 161 | - | ||
| 196 | + } | ||
| 162 | 197 | int type_num = detail::numpy_traits<value_type>::type_num; | |
| 163 | 198 | auto res = PyArray_FromAny(ptr, PyArray_DescrFromType(type_num), 0, 0, | |
| 164 | 199 | NPY_ARRAY_ENSUREARRAY | NPY_ARRAY_FORCECAST, nullptr); | |
@@ -174,7 +209,7 @@ namespace xt | |||
| 174 | 209 | template <class D> | |
| 175 | 210 | inline void pycontainer<D>::reshape(const shape_type& shape) | |
| 176 | 211 | { | |
| 177 | - if(shape.size() != this->dimension() || !std::equal(shape.begin(), shape.end(), this->shape().begin())) | ||
| 212 | + if (shape.size() != this->dimension() || !std::equal(shape.begin(), shape.end(), this->shape().begin())) | ||
| 178 | 213 | { | |
| 179 | 214 | reshape(shape, layout::row_major); | |
| 180 | 215 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments