| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4ab3bc2 commit a331f6d
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,27 @@ | |||
| 1 | + .. Copyright (c) 2016, Johan Mabille and Sylvain Corlay | ||
| 2 | + | ||
| 3 | + Distributed under the terms of the BSD 3-Clause License. | ||
| 4 | + | ||
| 5 | + The full license is in the file LICENSE, distributed with this software. | ||
| 6 | + | ||
| 7 | + Arrays and tensors | ||
| 8 | + ================== | ||
| 9 | + | ||
| 10 | + ``xtensor-python`` provides two container types wrapping numpy arrays: ``pyarray`` and ``pytensor``. They are the counterparts | ||
| 11 | + to ``xarray`` and ``xtensor`` containers. | ||
| 12 | + | ||
| 13 | + pyarray | ||
| 14 | + ------- | ||
| 15 | + | ||
| 16 | + Like ``xarray``, ``pyarray`` has a dynamic shape. This means that you can reshape the numpy array on the C++ side and see this | ||
| 17 | + change reflected on the python side. ``pyarray`` doesn't make a copy of the shape or the strides, but reads them each time it | ||
| 18 | + is needed. Therefore, if a reference on a ``pyarray`` is kept in the C++ code and the corresponding numpy array is then reshaped | ||
| 19 | + in the python code, this modification will reflect in the ``pyarray``. | ||
| 20 | + | ||
| 21 | + pytensor | ||
| 22 | + -------- | ||
| 23 | + | ||
| 24 | + Like ``xtensor``, ``pytensor`` has a static stack-allocated shape. This means that the shape of the numpy array is copied into | ||
| 25 | + the shape of the ``pytensor`` upon creation. As a consequence, reshapes are not reflected across languages. However, this drawback | ||
| 26 | + is offset by a more effective computation of shape and broadcast. | ||
| 27 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,14 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | 5 | The full license is in the file LICENSE, distributed with this software. | |
| 6 | 6 | ||
| 7 | - Usage | ||
| 8 | - ===== | ||
| 9 | - | ||
| 10 | 7 | Basic Usage | |
| 11 | - ----------- | ||
| 8 | + =========== | ||
| 12 | 9 | ||
| 13 | 10 | Example 1: Use an algorithm of the C++ library on a numpy array inplace | |
| 14 | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 11 | + ----------------------------------------------------------------------- | ||
| 15 | 12 | ||
| 16 | 13 | **C++ code** | |
| 17 | 14 | ||
@@ -58,7 +55,7 @@ Example 1: Use an algorithm of the C++ library on a numpy array inplace | |||
| 58 | 55 | ||
| 59 | 56 | ||
| 60 | 57 | Example 2: Create a universal function from a C++ scalar function | |
| 61 | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 58 | + ----------------------------------------------------------------- | ||
| 62 | 59 | ||
| 63 | 60 | **C++ code** | |
| 64 | 61 | ||
@@ -105,52 +102,3 @@ Example 2: Create a universal function from a C++ scalar function | |||
| 105 | 102 | [-1.499227, 0.136731, 1.646979, 1.643002, 0.128456], | |
| 106 | 103 | [-1.084323, -0.583843, 0.45342 , 1.073811, 0.706945]] | |
| 107 | 104 | ||
| 108 | - | ||
| 109 | - Getting started with xtensor-cookiecutter | ||
| 110 | - ----------------------------------------- | ||
| 111 | - | ||
| 112 | - `xtensor-cookiecutter`_ helps extension authors create Python extension modules making use of xtensor. | ||
| 113 | - | ||
| 114 | - It takes care of the initial work of generating a project skeleton with | ||
| 115 | - | ||
| 116 | - - A complete ``setup.py`` compiling the extension module | ||
| 117 | - - A few examples included in the resulting project including | ||
| 118 | - | ||
| 119 | - - A universal function defined from C++ | ||
| 120 | - - A function making use of an algorithm from the STL on a numpy array | ||
| 121 | - - Unit tests | ||
| 122 | - - The generation of the HTML documentation with sphinx | ||
| 123 | - | ||
| 124 | - Usage | ||
| 125 | - ^^^^^ | ||
| 126 | - | ||
| 127 | - Install cookiecutter_ | ||
| 128 | - | ||
| 129 | - .. code:: | ||
| 130 | - | ||
| 131 | - pip install cookiecutter | ||
| 132 | - | ||
| 133 | - After installing cookiecutter, use the xtensor-cookiecutter_: | ||
| 134 | - | ||
| 135 | - .. code:: | ||
| 136 | - | ||
| 137 | - cookiecutter https://github.com/QuantStack/xtensor-cookiecutter.git | ||
| 138 | - | ||
| 139 | - As xtensor-cookiecutter runs, you will be asked for basic information about | ||
| 140 | - your custom extension project. You will be prompted for the following | ||
| 141 | - information: | ||
| 142 | - | ||
| 143 | - - ``author_name``: your name or the name of your organization, | ||
| 144 | - - ``author_email`` : your project's contact email, | ||
| 145 | - - ``github_project_name``: name of the GitHub repository for your project, | ||
| 146 | - - ``github_organization_name``: name of the GithHub organization for your project, | ||
| 147 | - - ``python_package_name``: name of the Python package created by your extension, | ||
| 148 | - - ``cpp_namespace``: name for the cpp namespace holding the implementation of your extension, | ||
| 149 | - - ``project_short_description``: a short description for your project. | ||
| 150 | - | ||
| 151 | - This will produce a directory containing all the required content for a minimal extension | ||
| 152 | - project making use of xtensor with all the required boilerplate for package management, | ||
| 153 | - together with a few basic examples. | ||
| 154 | - | ||
| 155 | - .. _xtensor-cookicutter: https://github.com/QuantStack/xtensor-cookiecutter | ||
| 156 | - .. _cookiecutter: https://github.com/audreyr/cookiecutter | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,54 @@ | |||
| 1 | + .. Copyright (c) 2016, Johan Mabille and Sylvain Corlay | ||
| 2 | + | ||
| 3 | + Distributed under the terms of the BSD 3-Clause License. | ||
| 4 | + | ||
| 5 | + The full license is in the file LICENSE, distributed with this software. | ||
| 6 | + | ||
| 7 | + Getting started with xtensor-cookiecutter | ||
| 8 | + ========================================= | ||
| 9 | + | ||
| 10 | + `xtensor-cookiecutter`_ helps extension authors create Python extension modules making use of xtensor. | ||
| 11 | + | ||
| 12 | + It takes care of the initial work of generating a project skeleton with | ||
| 13 | + | ||
| 14 | + - A complete ``setup.py`` compiling the extension module | ||
| 15 | + - A few examples included in the resulting project including | ||
| 16 | + | ||
| 17 | + - A universal function defined from C++ | ||
| 18 | + - A function making use of an algorithm from the STL on a numpy array | ||
| 19 | + - Unit tests | ||
| 20 | + - The generation of the HTML documentation with sphinx | ||
| 21 | + | ||
| 22 | + Usage | ||
| 23 | + ----- | ||
| 24 | + | ||
| 25 | + Install cookiecutter_ | ||
| 26 | + | ||
| 27 | + .. code:: | ||
| 28 | + | ||
| 29 | + pip install cookiecutter | ||
| 30 | + | ||
| 31 | + After installing cookiecutter, use the xtensor-cookiecutter_: | ||
| 32 | + | ||
| 33 | + .. code:: | ||
| 34 | + | ||
| 35 | + cookiecutter https://github.com/QuantStack/xtensor-cookiecutter.git | ||
| 36 | + | ||
| 37 | + As xtensor-cookiecutter runs, you will be asked for basic information about | ||
| 38 | + your custom extension project. You will be prompted for the following | ||
| 39 | + information: | ||
| 40 | + | ||
| 41 | + - ``author_name``: your name or the name of your organization, | ||
| 42 | + - ``author_email`` : your project's contact email, | ||
| 43 | + - ``github_project_name``: name of the GitHub repository for your project, | ||
| 44 | + - ``github_organization_name``: name of the GithHub organization for your project, | ||
| 45 | + - ``python_package_name``: name of the Python package created by your extension, | ||
| 46 | + - ``cpp_namespace``: name for the cpp namespace holding the implementation of your extension, | ||
| 47 | + - ``project_short_description``: a short description for your project. | ||
| 48 | + | ||
| 49 | + This will produce a directory containing all the required content for a minimal extension | ||
| 50 | + project making use of xtensor with all the required boilerplate for package management, | ||
| 51 | + together with a few basic examples. | ||
| 52 | + | ||
| 53 | + .. _xtensor-cookicutter: https://github.com/QuantStack/xtensor-cookiecutter | ||
| 54 | + .. _cookiecutter: https://github.com/audreyr/cookiecutter | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -53,7 +53,9 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f | |||
| 53 | 53 | :caption: USAGE | |
| 54 | 54 | :maxdepth: 2 | |
| 55 | 55 | ||
| 56 | - usage | ||
| 56 | + basic_usage | ||
| 57 | + array_tensor | ||
| 58 | + cookie_cutter | ||
| 57 | 59 | ||
| 58 | 60 | .. toctree:: | |
| 59 | 61 | :caption: API REFERENCE | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -272,13 +272,13 @@ namespace xt | |||
| 272 | 272 | template <class T> | |
| 273 | 273 | inline void pyarray<T>::init_from_python() | |
| 274 | 274 | { | |
| 275 | - m_shape = inner_shape_type(reinterpret_cast<size_type*>(PyArray_SHAPE(python_array())), | ||
| 276 | - static_cast<size_type>(PyArray_NDIM(python_array()))); | ||
| 277 | - m_strides = inner_strides_type(reinterpret_cast<size_type*>(PyArray_STRIDES(python_array())), | ||
| 278 | - static_cast<size_type>(PyArray_NDIM(python_array()))); | ||
| 275 | + m_shape = inner_shape_type(reinterpret_cast<size_type*>(PyArray_SHAPE(this->python_array())), | ||
| 276 | + static_cast<size_type>(PyArray_NDIM(this->python_array()))); | ||
| 277 | + m_strides = inner_strides_type(reinterpret_cast<size_type*>(PyArray_STRIDES(this->python_array())), | ||
| 278 | + static_cast<size_type>(PyArray_NDIM(this->python_array()))); | ||
| 279 | 279 | m_backstrides = backstrides_type(*this); | |
| 280 | - m_data = container_type(reinterpret_cast<pointer>(PyArray_DATA(python_array())), | ||
| 281 | - static_cast<size_type>(PyArray_SIZE(python_array()))); | ||
| 280 | + m_data = container_type(reinterpret_cast<pointer>(PyArray_DATA(this->python_array())), | ||
| 281 | + static_cast<size_type>(PyArray_SIZE(this->python_array()))); | ||
| 282 | 282 | } | |
| 283 | 283 | ||
| 284 | 284 | template <class T> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -234,7 +234,7 @@ namespace xt | |||
| 234 | 234 | template <class D> | |
| 235 | 235 | inline void pycontainer<D>::fill_default_strides(const shape_type& shape, strides_type& strides) | |
| 236 | 236 | { | |
| 237 | - strides_type::value_type data_size = 1; | ||
| 237 | + typename strides_type::value_type data_size = 1; | ||
| 238 | 238 | for(size_type i = strides.size(); i != 0; --i) | |
| 239 | 239 | { | |
| 240 | 240 | strides[i - 1] = data_size; | |
@@ -258,8 +258,8 @@ namespace xt | |||
| 258 | 258 | template <class D> | |
| 259 | 259 | inline bool pycontainer<D>::check_(pybind11::handle h) | |
| 260 | 260 | { | |
| 261 | - int type_num = detail::numpy_traits<T>::type_num; | ||
| 262 | - return PyArray_Check(h.ptr()) && PyArray_EquivTypenums(PyArray_TYPE(h.ptr()), type_num); | ||
| 261 | + int type_num = detail::numpy_traits<value_type>::type_num; | ||
| 262 | + return PyArray_Check(h.ptr()) && PyArray_EquivTypenums(PyArray_TYPE(python_array()), type_num); | ||
| 263 | 263 | } | |
| 264 | 264 | ||
| 265 | 265 | template <class D> | |
@@ -269,7 +269,8 @@ namespace xt | |||
| 269 | 269 | return nullptr; | |
| 270 | 270 | ||
| 271 | 271 | int type_num = detail::numpy_traits<value_type>::type_num; | |
| 272 | - auto res = PyArray_FromAny(ptr, PyArray_DescrFromType(type_num), 0, 0, NPY_ARRAY_ENSUREARRAY, nullptr); | ||
| 272 | + auto res = PyArray_FromAny(ptr, PyArray_DescrFromType(type_num), 0, 0, | ||
| 273 | + NPY_ARRAY_ENSUREARRAY | NPY_ARRAY_FORCECAST, nullptr); | ||
| 273 | 274 | return res; | |
| 274 | 275 | } | |
| 275 | 276 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -223,22 +223,22 @@ namespace xt | |||
| 223 | 223 | m_shape = shape; | |
| 224 | 224 | m_strides = strides; | |
| 225 | 225 | compute_backstrides(); | |
| 226 | - m_data = container_type(reinterpret_cast<pointer>(PyArray_DATA(python_array())), | ||
| 227 | - static_cast<size_type>(PyArray_SIZE(python_array()))); | ||
| 226 | + m_data = container_type(reinterpret_cast<pointer>(PyArray_DATA(this->python_array())), | ||
| 227 | + static_cast<size_type>(PyArray_SIZE(this->python_array()))); | ||
| 228 | 228 | } | |
| 229 | 229 | ||
| 230 | 230 | template <class T, std::size_t N> | |
| 231 | 231 | inline void pytensor<T, N>::init_from_python() | |
| 232 | 232 | { | |
| 233 | - if(PyArray_NDIM(python_array()) != N) | ||
| 233 | + if(PyArray_NDIM(this->python_array()) != N) | ||
| 234 | 234 | throw std::runtime_error("NumPy: ndarray has incorrect number of dimensions"); | |
| 235 | 235 | ||
| 236 | - std::copy(PyArray_DIMS(python_array()), PyArray_DIMS(python_array()) + N, m_shape.begin()); | ||
| 237 | - std::transform(PyArray_STRIDES(python_array()), PyArray_STRIDES(python_array()) + N, m_strides.begin(), | ||
| 236 | + std::copy(PyArray_DIMS(this->python_array()), PyArray_DIMS(this->python_array()) + N, m_shape.begin()); | ||
| 237 | + std::transform(PyArray_STRIDES(this->python_array()), PyArray_STRIDES(this->python_array()) + N, m_strides.begin(), | ||
| 238 | 238 | [](auto v) { return v / sizeof(T); }); | |
| 239 | 239 | compute_backstrides(); | |
| 240 | - m_data = container_type(reinterpret_cast<pointer>(PyArray_DATA(python_array())), | ||
| 241 | - static_cast<size_type>(PyArray_SIZE(python_array()))); | ||
| 240 | + m_data = container_type(reinterpret_cast<pointer>(PyArray_DATA(this->python_array())), | ||
| 241 | + static_cast<size_type>(PyArray_SIZE(this->python_array()))); | ||
| 242 | 242 | } | |
| 243 | 243 | ||
| 244 | 244 | template <class T, std::size_t N> | |
| Back | FazBrowse Home | New Git URL |
0 commit comments