From fd2a1ec217a5bba185a86b60879c5de0b64cf772 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 26 Aug 2019 16:29:09 +0200 Subject: [PATCH 001/102] Upgraded to pybind11 2.2.4 --- .appveyor.yml | 2 +- .travis.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 5616ced..eb9b9c9 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.2.1 xtensor==0.20.6 -c conda-forge + - conda install pytest numpy pybind11==2.2.4 xtensor==0.20.6 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/.travis.yml b/.travis.yml index 40dc83a..b1a87e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -88,7 +88,7 @@ matrix: env: PY=3 env: global: - - MINCONDA_VERSION="4.3.21" + - MINCONDA_VERSION="latest" - MINCONDA_LINUX="Linux-x86_64" - MINCONDA_OSX="MacOSX-x86_64" before_install: @@ -104,7 +104,7 @@ before_install: elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CXX=clang++ CC=clang PYTHONHOME=$HOME/miniconda; fi - - PYBIND11_VERSION=${PYBIND11_VERSION:-2.2.1} + - PYBIND11_VERSION=${PYBIND11_VERSION:-2.2.4} install: # Define the version of miniconda to download @@ -115,7 +115,7 @@ install: fi - if [[ "$PY" == "3" ]]; then wget "http://repo.continuum.io/miniconda/Miniconda3-$MINCONDA_VERSION-$MINCONDA_OS.sh" -O miniconda.sh; - PY_EXE=$HOME/miniconda/bin/python3.6; + PY_EXE=$HOME/miniconda/bin/python3.7; else wget "http://repo.continuum.io/miniconda/Miniconda2-$MINCONDA_VERSION-$MINCONDA_OS.sh" -O miniconda.sh; PY_EXE=$HOME/miniconda/bin/python2.7; From 1539930e49bef575abae43f088a287b6b9649af3 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 26 Aug 2019 17:23:18 +0200 Subject: [PATCH 002/102] Upgraded to xtensor 0.20.8 --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index eb9b9c9..b37d1c0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.2.4 xtensor==0.20.6 -c conda-forge + - conda install pytest numpy pybind11==2.2.4 xtensor==0.20.8 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/.travis.yml b/.travis.yml index b1a87e8..70fb2e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -147,7 +147,7 @@ install: else conda install pybind11==${PYBIND11_VERSION} -c conda-forge fi - - conda install xtensor==0.20.6 -c conda-forge + - conda install xtensor==0.20.8 -c conda-forge - cmake -D DOWNLOAD_GTEST=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda -D PYTHON_EXECUTABLE=$PY_EXE . - make -j2 test_xtensor_python - make install From 58f5f3e00a3de31f285b7ad909be39fd6724e390 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 26 Aug 2019 17:50:25 +0200 Subject: [PATCH 003/102] Added g++7 in CI --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index 70fb2e6..839d54e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,14 @@ matrix: packages: - g++-6 env: COMPILER=gcc GCC=6 PY=3 + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-7 + env: COMPILER=gcc GCC=7 PY=3 - os: linux addons: apt: From 2af1f403a3db0ee0bc40cf8d7d4b637239d4ea79 Mon Sep 17 00:00:00 2001 From: zhujun98 Date: Tue, 6 Aug 2019 20:47:47 +0200 Subject: [PATCH 004/102] Fix pytensor overload resolution in pybind11. --- include/xtensor-python/pytensor.hpp | 9 ++++++++- test_python/main.cpp | 3 +++ test_python/test_pyarray.py | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index b7886f6..3c3b91b 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -58,7 +58,14 @@ namespace pybind11 } } - value = type::ensure(src); + try + { + value = type::ensure(src); + } + catch (const std::runtime_error&) + { + return false; + } return static_cast(value); } diff --git a/test_python/main.cpp b/test_python/main.cpp index 4b3343a..2f4a0df 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -253,4 +253,7 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("simple_array", [](xt::pyarray) { return 1; } ); m.def("simple_tensor", [](xt::pytensor) { return 2; } ); + + m.def("diff_shape_overload", [](xt::pytensor a) { return 1; }); + m.def("diff_shape_overload", [](xt::pytensor a) { return 2; }); } diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index e70a2fa..3d8f0af 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -135,13 +135,13 @@ def test_col_row_major(self): with self.assertRaises(RuntimeError): xt.col_major_array(var) - with self.assertRaises(RuntimeError): + with self.assertRaises(TypeError): xt.row_major_tensor(var.T) - with self.assertRaises(RuntimeError): + with self.assertRaises(TypeError): xt.row_major_tensor(var[:, ::2, ::2]) - with self.assertRaises(RuntimeError): + with self.assertRaises(TypeError): # raise for wrong dimension xt.row_major_tensor(var[0, 0, :]) @@ -157,6 +157,15 @@ def test_bad_argument_call(self): with self.assertRaises(TypeError): xt.simple_tensor("foo") + def test_diff_shape_overload(self): + self.assertEqual(1, xt.diff_shape_overload(np.ones(2))) + self.assertEqual(2, xt.diff_shape_overload(np.ones((2, 2)))) + + with self.assertRaises(TypeError): + # FIXME: the TypeError information is not informative + xt.diff_shape_overload(np.ones((2, 2, 2))) + + class AttributeTest(TestCase): def setUp(self): From 70330207524d5f26eee60259a3025356b8c1f614 Mon Sep 17 00:00:00 2001 From: Yung-Yu Chen Date: Fri, 4 Oct 2019 11:02:27 +0800 Subject: [PATCH 005/102] Compatibility for upstream xtensor change The upstream change broke the build: https://github.com/QuantStack/xtensor/commit/da7de15be73c396bc9ffb31fe8c630938c57ffe8 Add pycontainer::is_contiguous to make xtensor happy. --- include/xtensor-python/pycontainer.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 7b9a90e..e92bbec 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -93,6 +93,7 @@ namespace xt void reshape(S&& shape, layout_type layout = base_type::static_layout); layout_type layout() const; + bool is_contiguous() const noexcept; using base_type::operator(); using base_type::operator[]; @@ -442,6 +443,16 @@ namespace xt } } + /** + * Return whether or not the container uses contiguous buffer + * @return Boolean for contiguous buffer + */ + template + inline bool pycontainer::is_contiguous() const noexcept + { + return layout_type::dynamic != layout(); + } + /** * Import the numpy Python module. */ From a956ad80005dac3e68aad6963f6ddfc9317f917e Mon Sep 17 00:00:00 2001 From: Yung-Yu Chen Date: Thu, 10 Oct 2019 00:13:28 +0800 Subject: [PATCH 006/102] Make contiguous check for pyarray more robust For row-major (c contiguous), make sure the last stride is unity. For colunm-major (fortran contiguous), make sure the first stride is unity. --- include/xtensor-python/pycontainer.hpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index e92bbec..deeefb2 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -450,7 +450,18 @@ namespace xt template inline bool pycontainer::is_contiguous() const noexcept { - return layout_type::dynamic != layout(); + if (PyArray_CHKFLAGS(python_array(), NPY_ARRAY_C_CONTIGUOUS)) + { + return 1 == this->strides().back(); + } + else if (PyArray_CHKFLAGS(python_array(), NPY_ARRAY_F_CONTIGUOUS)) + { + return 1 == this->strides().front(); + } + else + { + return false; + } } /** From 8c0ffb147498839c4160ac535c8bb2a9cbad8a6c Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 14 Oct 2019 21:34:25 +0200 Subject: [PATCH 007/102] Updated copyright --- CMakeLists.txt | 3 ++- LICENSE | 3 ++- include/xtensor-python/pyarray.hpp | 3 ++- include/xtensor-python/pycontainer.hpp | 3 ++- include/xtensor-python/pystrides_adaptor.hpp | 3 ++- include/xtensor-python/pytensor.hpp | 3 ++- include/xtensor-python/pyvectorize.hpp | 3 ++- .../xtensor-python/xtensor_python_config.hpp | 3 ++- .../xtensor_type_caster_base.hpp | 21 +++++++------------ test/CMakeLists.txt | 3 ++- test/copyGTest.cmake.in | 3 ++- test/downloadGTest.cmake.in | 3 ++- test/main.cpp | 3 ++- test/test_common.hpp | 3 ++- test/test_pyarray.cpp | 3 ++- test/test_pytensor.cpp | 3 ++- test/test_pyvectorize.cpp | 3 ++- test_python/main.cpp | 3 ++- test_python/setup.py | 3 ++- test_python/test_pyarray.py | 3 ++- xtensor-pythonConfig.cmake.in | 3 ++- 21 files changed, 48 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e93edab..b9f1255 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # diff --git a/LICENSE b/LICENSE index 0e95334..414a5d7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,5 @@ -Copyright (c) 2016, Johan Mabille and Sylvain Corlay +Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay +Copyright (c) QuantStack All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 20d7e74..2d679c9 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 7b9a90e..a5a5098 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/include/xtensor-python/pystrides_adaptor.hpp b/include/xtensor-python/pystrides_adaptor.hpp index f2e0824..161255b 100644 --- a/include/xtensor-python/pystrides_adaptor.hpp +++ b/include/xtensor-python/pystrides_adaptor.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index b7886f6..e7f8af6 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/include/xtensor-python/pyvectorize.hpp b/include/xtensor-python/pyvectorize.hpp index 75c1473..9c7d107 100644 --- a/include/xtensor-python/pyvectorize.hpp +++ b/include/xtensor-python/pyvectorize.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 22c219e..0e0b645 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 79246d0..4435dd8 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -1,16 +1,11 @@ -/* - xtensor-python/xtensor_type_caster.hpp: Transparent conversion for xtensor and xarray - - This code is based on the following code written by Wenzel Jakob - - pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices - - Copyright (c) 2016 Wenzel Jakob - - All rights reserved. Use of this source code is governed by a - BSD-style license that can be found in the LICENSE file. -*/ - +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * +* * +* Distributed under the terms of the BSD 3-Clause License. * +* * +* The full license is in the file LICENSE, distributed with this software. * +****************************************************************************/ #ifndef XTENSOR_TYPE_CASTER_HPP #define XTENSOR_TYPE_CASTER_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 30857d0..0517e76 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # diff --git a/test/copyGTest.cmake.in b/test/copyGTest.cmake.in index db58282..8341a74 100644 --- a/test/copyGTest.cmake.in +++ b/test/copyGTest.cmake.in @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # diff --git a/test/downloadGTest.cmake.in b/test/downloadGTest.cmake.in index 511bf0a..e4431f0 100644 --- a/test/downloadGTest.cmake.in +++ b/test/downloadGTest.cmake.in @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # diff --git a/test/main.cpp b/test/main.cpp index 4385226..d3cc6c4 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/test/test_common.hpp b/test/test_common.hpp index 79a2462..07a0992 100644 --- a/test/test_common.hpp +++ b/test/test_common.hpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/test/test_pyarray.cpp b/test/test_pyarray.cpp index 6cd725a..b9356cc 100644 --- a/test/test_pyarray.cpp +++ b/test/test_pyarray.cpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/test/test_pytensor.cpp b/test/test_pytensor.cpp index 2adf857..a601a50 100644 --- a/test/test_pytensor.cpp +++ b/test/test_pytensor.cpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/test/test_pyvectorize.cpp b/test/test_pyvectorize.cpp index cc20c8e..30378e6 100644 --- a/test/test_pyvectorize.cpp +++ b/test/test_pyvectorize.cpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/test_python/main.cpp b/test_python/main.cpp index 4b3343a..eef9f52 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -1,5 +1,6 @@ /*************************************************************************** -* Copyright (c) 2016, Johan Mabille and Sylvain Corlay * +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * diff --git a/test_python/setup.py b/test_python/setup.py index dc83c22..fa201da 100644 --- a/test_python/setup.py +++ b/test_python/setup.py @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index e70a2fa..c62a250 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # diff --git a/xtensor-pythonConfig.cmake.in b/xtensor-pythonConfig.cmake.in index 96c1186..57e04e3 100644 --- a/xtensor-pythonConfig.cmake.in +++ b/xtensor-pythonConfig.cmake.in @@ -1,5 +1,6 @@ ############################################################################ -# Copyright (c) 2016, Johan Mabille and Sylvain Corlay # +# Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay # +# Copyright (c) QuantStack # # # # Distributed under the terms of the BSD 3-Clause License. # # # From 058bea6bcfb70c54f23bf3d987012eea88b7acb0 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 14 Oct 2019 23:07:25 +0200 Subject: [PATCH 008/102] Updated CI badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b2b77d..289f6ba 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # ![xtensor-python](docs/source/xtensor-python.svg) -[![Travis](https://travis-ci.org/QuantStack/xtensor-python.svg?branch=master)](https://travis-ci.org/QuantStack/xtensor-python) -[![Appveyor](https://ci.appveyor.com/api/projects/status/qx61nsg4ebxnj8s9?svg=true)](https://ci.appveyor.com/project/QuantStack/xtensor-python) +[![Travis](https://travis-ci.org/xtensor-stack/xtensor-python.svg?branch=master)](https://travis-ci.org/xtensor-stack/xtensor-python) +[![Appveyor](https://ci.appveyor.com/api/projects/status/4j2yd6k8o5xbimqf?svg=true)](https://ci.appveyor.com/project/xtensor-stack/xtensor-python) [![Documentation](http://readthedocs.org/projects/xtensor-python/badge/?version=latest)](https://xtensor-python.readthedocs.io/en/latest/?badge=latest) [![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 9bd98d41dae2b0a2cb34a1fa351ffb70b4597d93 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 15 Oct 2019 13:43:02 +0200 Subject: [PATCH 009/102] Updated license --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 414a5d7..a6fccbb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay -Copyright (c) QuantStack +Copyright (c) 2016, Wolf Vollprecht, Johan Mabille and Sylvain Corlay +Copyright (c) 2016, QuantStack All rights reserved. Redistribution and use in source and binary forms, with or without From fcf2221c6bc8824d33f9dd1ddbe43e7dca82e6ed Mon Sep 17 00:00:00 2001 From: Roberto Di Remigio Date: Thu, 24 Oct 2019 16:36:00 +0200 Subject: [PATCH 010/102] Use latest pybind11 in CI Related to conda-forge/xtensor-python-feedstock#56 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 839d54e..4dbad10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -112,7 +112,7 @@ before_install: elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CXX=clang++ CC=clang PYTHONHOME=$HOME/miniconda; fi - - PYBIND11_VERSION=${PYBIND11_VERSION:-2.2.4} + - PYBIND11_VERSION=${PYBIND11_VERSION:-2.4.2} install: # Define the version of miniconda to download From 6c0ef261c6be0c6f6066f4d24b07aa783fe93e2c Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Mon, 25 Nov 2019 13:23:15 +0100 Subject: [PATCH 011/102] Prevent ambiguous overload resolution --- .appveyor.yml | 2 +- include/xtensor-python/pycontainer.hpp | 29 ++++++++++++++++++++++++++ test/test_pytensor.cpp | 22 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index b37d1c0..fa58b00 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.2.4 xtensor==0.20.8 -c conda-forge + - conda install pytest numpy pybind11==2.4.2 xtensor==0.20.8 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index a5a5098..e997357 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -124,6 +124,35 @@ namespace xt PyArrayObject* python_array() const; size_type get_buffer_size() const; + + private: + +#if PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3 + // Prevent ambiguous overload resolution for operators defined for + // both xt::xcontainer and pybind11::object. + using pybind11::object::operator~; + using pybind11::object::operator+; + using pybind11::object::operator-; + using pybind11::object::operator*; + using pybind11::object::operator/; + using pybind11::object::operator|; + using pybind11::object::operator&; + using pybind11::object::operator^; + using pybind11::object::operator<<; + using pybind11::object::operator>>; + + // Prevent ambiguous overload resolution for operators defined for + // both xt::xcontainer_semantic and pybind11::object. + using pybind11::object::operator+=; + using pybind11::object::operator-=; + using pybind11::object::operator*=; + using pybind11::object::operator/=; + using pybind11::object::operator|=; + using pybind11::object::operator&=; + using pybind11::object::operator^=; + using pybind11::object::operator<<=; + using pybind11::object::operator>>=; +#endif }; namespace detail diff --git a/test/test_pytensor.cpp b/test/test_pytensor.cpp index a601a50..637d58f 100644 --- a/test/test_pytensor.cpp +++ b/test/test_pytensor.cpp @@ -240,4 +240,26 @@ namespace xt auto v = xt::view(arr, xt::all()); EXPECT_EQ(v(0), 0.); } + + TEST(pytensor, unary) + { + pytensor a = { 1, 2, 3 }; + pytensor res = -a; + pytensor ref = { -1, -2, -3 }; + EXPECT_EQ(ref(0), res(0)); + EXPECT_EQ(ref(1), res(1)); + EXPECT_EQ(ref(1), res(1)); + } + + TEST(pytensor, inplace_pybind11_overload) + { + // pybind11 overrrides a number of operators in pybind11::object. + // This is testing that the right overload is picked up. + pytensor a = { 1.0, 2.0, 3.0 }; + a /= 2; + pytensor ref = { 0.5, 1.0, 1.5 }; + EXPECT_EQ(ref(0), a(0)); + EXPECT_EQ(ref(1), a(1)); + EXPECT_EQ(ref(1), a(1)); + } } From 29ab8f078cf53ff25e01f70f648437e027df3b43 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Mon, 25 Nov 2019 13:56:22 +0100 Subject: [PATCH 012/102] Fix gcc case --- include/xtensor-python/pyarray.hpp | 14 ++++++++++++++ include/xtensor-python/pycontainer.hpp | 12 ------------ include/xtensor-python/pytensor.hpp | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 2d679c9..24ed51f 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -390,6 +390,20 @@ namespace xt static self_type ensure(pybind11::handle h); static bool check_(pybind11::handle h); +#if PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3 + // Prevent ambiguous overload resolution for operators defined for + // both xt::xcontainer_semantic and pybind11::object. + using semantic_base::operator+=; + using semantic_base::operator-=; + using semantic_base::operator*=; + using semantic_base::operator/=; + using semantic_base::operator|=; + using semantic_base::operator&=; + using semantic_base::operator^=; + // using semantic_base::operator<<=; + // using semantic_base::operator>>=; +#endif + private: inner_shape_type m_shape; diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index e997357..716f24a 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -140,18 +140,6 @@ namespace xt using pybind11::object::operator^; using pybind11::object::operator<<; using pybind11::object::operator>>; - - // Prevent ambiguous overload resolution for operators defined for - // both xt::xcontainer_semantic and pybind11::object. - using pybind11::object::operator+=; - using pybind11::object::operator-=; - using pybind11::object::operator*=; - using pybind11::object::operator/=; - using pybind11::object::operator|=; - using pybind11::object::operator&=; - using pybind11::object::operator^=; - using pybind11::object::operator<<=; - using pybind11::object::operator>>=; #endif }; diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index e7f8af6..0a23874 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -194,6 +194,20 @@ namespace xt static self_type ensure(pybind11::handle h); static bool check_(pybind11::handle h); +#if PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3 + // Prevent ambiguous overload resolution for operators defined for + // both xt::xcontainer_semantic and pybind11::object. + using semantic_base::operator+=; + using semantic_base::operator-=; + using semantic_base::operator*=; + using semantic_base::operator/=; + using semantic_base::operator|=; + using semantic_base::operator&=; + using semantic_base::operator^=; + // using semantic_base::operator<<=; + // using semantic_base::operator>>=; +#endif + private: inner_shape_type m_shape; From 7d210b1d6c7472248d494249b4c44511275ff4c3 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Mon, 25 Nov 2019 14:27:46 +0100 Subject: [PATCH 013/102] Reshape method return a reference to self --- include/xtensor-python/pycontainer.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 716f24a..46ac553 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -91,7 +91,7 @@ namespace xt void resize(const S& shape, const strides_type& strides); template - void reshape(S&& shape, layout_type layout = base_type::static_layout); + auto& reshape(S&& shape, layout_type layout = base_type::static_layout) &; layout_type layout() const; @@ -205,7 +205,7 @@ namespace xt } template - void default_initialize_impl(T& storage, std::false_type) + void default_initialize_impl(T& /*storage*/, std::false_type) { } @@ -407,7 +407,7 @@ namespace xt template template - inline void pycontainer::reshape(S&& shape, layout_type layout) + inline auto& pycontainer::reshape(S&& shape, layout_type layout) & { if (compute_size(shape) != this->size()) { @@ -437,6 +437,7 @@ namespace xt this->ptr() = new_ptr; Py_XDECREF(old_ptr); this->derived_cast().init_from_python(); + return *this; } /** From 1f70cf3a71e042bbac4e1589c30066973cfa3872 Mon Sep 17 00:00:00 2001 From: Jun Date: Mon, 25 Nov 2019 15:06:45 +0100 Subject: [PATCH 014/102] Document build, tests and fix CMakeLists.txt in benchmark. (#216) * Document build, tests and fix CMakeLists.txt in benchmark. --- benchmark/CMakeLists.txt | 17 ++++++++++-- benchmark/main.cpp | 1 - benchmark/setup.py | 2 +- docs/source/dev_build_options.rst | 45 +++++++++++++++++++++++++++++++ docs/source/index.rst | 1 + 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 docs/source/dev_build_options.rst diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index dfb5311..28589df 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -6,6 +6,13 @@ # The full license is in the file LICENSE, distributed with this software. # ############################################################################ +if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + project(xtensor-python-benchmark) + + find_package(xtensor-python REQUIRED CONFIG) + set(XTENSOR_PYTHON_INCLUDE_DIR ${xtensor-python_INCLUDE_DIRS}) +endif () + message(STATUS "Forcing tests build type to Release") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) @@ -72,7 +79,7 @@ if (APPLE) elseif (MSVC) target_link_libraries(${XTENSOR_PYTHON_BENCHMARK_TARGET} ${PYTHON_LIBRARIES}) else () - target_link_libraries(${XTENSOR_PYTHON_BENCHMARK_TARGET} "-shared") + target_link_libraries(${XTENSOR_PYTHON_BENCHMARK_TARGET} PRIVATE xtensor-python) endif() configure_file(benchmark_pyarray.py benchmark_pyarray.py COPYONLY) @@ -81,5 +88,11 @@ configure_file(benchmark_pybind_array.py benchmark_pybind_array.py COPYONLY) configure_file(benchmark_pyvectorize.py benchmark_pyvectorize.py COPYONLY) configure_file(benchmark_pybind_vectorize.py benchmark_pybind_vectorize.py COPYONLY) -add_custom_target(xbenchmark DEPENDS ${XTENSOR_PYTHON_BENCHMARK_TARGET}) +add_custom_target(xbenchmark + COMMAND "${PYTHON_EXECUTABLE}" "benchmark_pyarray.py" + COMMAND "${PYTHON_EXECUTABLE}" "benchmark_pytensor.py" + COMMAND "${PYTHON_EXECUTABLE}" "benchmark_pybind_array.py" + COMMAND "${PYTHON_EXECUTABLE}" "benchmark_pyvectorize.py" + COMMAND "${PYTHON_EXECUTABLE}" "benchmark_pybind_vectorize.py" + DEPENDS ${XTENSOR_PYTHON_BENCHMARK_TARGET}) diff --git a/benchmark/main.cpp b/benchmark/main.cpp index c5c143b..d1d787e 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -17,7 +17,6 @@ PYBIND11_MODULE(benchmark_xtensor_python, m) if(_import_array() < 0) { PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); - return nullptr; } m.doc() = "Benchmark module for xtensor python bindings"; diff --git a/benchmark/setup.py b/benchmark/setup.py index 06fe061..20633ed 100644 --- a/benchmark/setup.py +++ b/benchmark/setup.py @@ -107,7 +107,7 @@ def build_extensions(self): description='An example project using xtensor-python', long_description='', ext_modules=ext_modules, - install_requires=['pybind11==2.0.1'], + install_requires=['pybind11>=2.2.1'], cmdclass={'build_ext': BuildExt}, zip_safe=False, ) diff --git a/docs/source/dev_build_options.rst b/docs/source/dev_build_options.rst new file mode 100644 index 0000000..80e7e78 --- /dev/null +++ b/docs/source/dev_build_options.rst @@ -0,0 +1,45 @@ +.. Copyright (c) 2016, Johan Mabille and Sylvain Corlay + + Distributed under the terms of the BSD 3-Clause License. + + The full license is in the file LICENSE, distributed with this software. + + +Build, test and benchmark +========================= + +``xtensor-python`` build supports the following options: + +- ``BUILD_TESTS``: enables the ``xtest`` and ``xbenchmark`` targets (see below). +- ``DOWNLOAD_GTEST``: downloads ``gtest`` and builds it locally instead of using a binary installation. +- ``GTEST_SRC_DIR``: indicates where to find the ``gtest`` sources instead of downloading them. + +All these options are disabled by default. Enabling ``DOWNLOAD_GTEST`` or +setting ``GTEST_SRC_DIR`` enables ``BUILD_TESTS``. + +If the ``BUILD_TESTS`` option is enabled, the following targets are available: + +- xtest: builds an run the test suite. +- xbenchmark: builds and runs the benchmarks. + +For instance, building the test suite of ``xtensor-python`` and downloading ``gtest`` automatically: + +.. code:: + + mkdir build + cd build + cmake -DDOWNLOAD_GTEST=ON ../ + make xtest + +To run the benchmark: + +.. code:: + + make xbenchmark + +To test the Python bindings: + +.. code:: + + cd .. + pytest -s diff --git a/docs/source/index.rst b/docs/source/index.rst index 950559f..3dd0fd3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -73,6 +73,7 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f .. toctree:: :caption: DEVELOPER ZONE + dev_build_options compilers releasing From dfb2dce3d92cc9b19946f52b5cd0710ceed20481 Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Thu, 3 Oct 2019 22:54:17 +0200 Subject: [PATCH 015/102] Better error report when facing dimension mismatch --- include/xtensor-python/pycontainer.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 7b9a90e..62d073f 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "pybind11/complex.h" #include "pybind11/pybind11.h" @@ -338,7 +339,10 @@ namespace xt { if(new_dim != N) { - throw std::runtime_error("Dims not matching."); + std::ostringstream err_msg; + err_msg << "Invalid conversion to pycontainer, expecting a container of dimension " + << N << ", got a container of dimension " << new_dim << "."; + throw std::runtime_error(err_msg.str()); } return new_dim == N; } From 9404f83303640160a736169036014e79d20afcbf Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 29 Nov 2019 14:51:50 +0100 Subject: [PATCH 016/102] Upgraded to xtensor 0.20.10 --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index fa58b00..2521ede 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.2 xtensor==0.20.8 -c conda-forge + - conda install pytest numpy pybind11==2.4.2 xtensor==0.20.10 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/.travis.yml b/.travis.yml index 4dbad10..f29c9f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -155,7 +155,7 @@ install: else conda install pybind11==${PYBIND11_VERSION} -c conda-forge fi - - conda install xtensor==0.20.8 -c conda-forge + - conda install xtensor==0.20.10 -c conda-forge - cmake -D DOWNLOAD_GTEST=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda -D PYTHON_EXECUTABLE=$PY_EXE . - make -j2 test_xtensor_python - make install From e33ad393dac606e513fb92b60d81545373b9b916 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 29 Nov 2019 15:10:18 +0100 Subject: [PATCH 017/102] Release 0.23.2 --- README.md | 3 ++- include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 289f6ba..55a99a5 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,8 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.20.6 | ~2.2.1 | +| master | ^0.20.10 | ~2.4.2 | +| 0.23.2 | ^0.20.10 | ~2.4.4 | | 0.23.1 | ^0.20.6 | ~2.2.1 | | 0.23.0 | ^0.20.4 | ~2.2.1 | | 0.22.x | ^0.19.0 | ~2.2.1 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 0e0b645..264c978 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -12,6 +12,6 @@ #define XTENSOR_PYTHON_VERSION_MAJOR 0 #define XTENSOR_PYTHON_VERSION_MINOR 23 -#define XTENSOR_PYTHON_VERSION_PATCH 1 +#define XTENSOR_PYTHON_VERSION_PATCH 2 #endif From f989b7bb9306a1a02500d2855472f6ae49b5544d Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 9 Dec 2019 14:09:55 +0100 Subject: [PATCH 018/102] Upgraded to xtensor 0.21.1 --- .appveyor.yml | 2 +- .travis.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 2521ede..7563438 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.2 xtensor==0.20.10 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.1 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/.travis.yml b/.travis.yml index f29c9f3..975cd24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -112,7 +112,7 @@ before_install: elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export CXX=clang++ CC=clang PYTHONHOME=$HOME/miniconda; fi - - PYBIND11_VERSION=${PYBIND11_VERSION:-2.4.2} + - PYBIND11_VERSION=${PYBIND11_VERSION:-2.4.3} install: # Define the version of miniconda to download @@ -155,7 +155,7 @@ install: else conda install pybind11==${PYBIND11_VERSION} -c conda-forge fi - - conda install xtensor==0.20.10 -c conda-forge + - conda install xtensor==0.21.1 -c conda-forge - cmake -D DOWNLOAD_GTEST=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda -D PYTHON_EXECUTABLE=$PY_EXE . - make -j2 test_xtensor_python - make install From dd079a7ad0b72dffd0dedc5f061192d55c05795f Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 10 Dec 2019 21:33:30 +0100 Subject: [PATCH 019/102] Release 0.24.0 --- README.md | 5 +++-- include/xtensor-python/xtensor_python_config.hpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 55a99a5..b5175e2 100644 --- a/README.md +++ b/README.md @@ -195,8 +195,9 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.20.10 | ~2.4.2 | -| 0.23.2 | ^0.20.10 | ~2.4.4 | +| master | ^0.21.1 | ~2.4.3 | +| 0.24.0 | ^0.21.1 | ~2.4.3 | +| 0.23.2 | ^0.20.10 | ~2.4.3 | | 0.23.1 | ^0.20.6 | ~2.2.1 | | 0.23.0 | ^0.20.4 | ~2.2.1 | | 0.22.x | ^0.19.0 | ~2.2.1 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 264c978..1da85e7 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -11,7 +11,7 @@ #define XTENSOR_PYTHON_CONFIG_HPP #define XTENSOR_PYTHON_VERSION_MAJOR 0 -#define XTENSOR_PYTHON_VERSION_MINOR 23 -#define XTENSOR_PYTHON_VERSION_PATCH 2 +#define XTENSOR_PYTHON_VERSION_MINOR 24 +#define XTENSOR_PYTHON_VERSION_PATCH 0 #endif From aed617b9c8764a9c7014e71a8d7f5135aeb6934e Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Thu, 12 Dec 2019 22:41:36 +0100 Subject: [PATCH 020/102] Moved pyarray_backstrides to a dedicated file --- CMakeLists.txt | 1 + include/xtensor-python/pyarray.hpp | 290 +------------- .../xtensor-python/pyarray_backstrides.hpp | 378 ++++++++++++++++++ 3 files changed, 380 insertions(+), 289 deletions(-) create mode 100644 include/xtensor-python/pyarray_backstrides.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b9f1255..1f40248 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ message(STATUS "Found numpy: ${NUMPY_INCLUDE_DIRS}") set(XTENSOR_PYTHON_HEADERS ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyarray.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyarray_backstrides.hpp ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pycontainer.hpp ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pystrides_adaptor.hpp ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pytensor.hpp diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 24ed51f..0873399 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -18,6 +18,7 @@ #include "xtensor/xiterator.hpp" #include "xtensor/xsemantic.hpp" +#include "pyarray_backstrides.hpp" #include "pycontainer.hpp" #include "pystrides_adaptor.hpp" #include "xtensor_type_caster_base.hpp" @@ -100,200 +101,6 @@ namespace pybind11 namespace xt { - - /************************** - * pybackstrides_iterator * - **************************/ - - template - class pybackstrides_iterator - { - public: - - using self_type = pybackstrides_iterator; - - using value_type = typename B::value_type; - using pointer = const value_type*; - using reference = value_type; - using difference_type = std::ptrdiff_t; - using iterator_category = std::random_access_iterator_tag; - - inline pybackstrides_iterator(const B* b, std::size_t offset) - : p_b(b), m_offset(offset) - { - } - - inline reference operator*() const - { - return p_b->operator[](m_offset); - } - - inline pointer operator->() const - { - // Returning the address of a temporary - value_type res = p_b->operator[](m_offset); - return &res; - } - - inline reference operator[](difference_type n) const - { - return p_b->operator[](m_offset + n); - } - - inline self_type& operator++() - { - ++m_offset; - return *this; - } - - inline self_type& operator--() - { - --m_offset; - return *this; - } - - inline self_type operator++(int) - { - self_type tmp(*this); - ++m_offset; - return tmp; - } - - inline self_type operator--(int) - { - self_type tmp(*this); - --m_offset; - return tmp; - } - - inline self_type& operator+=(difference_type n) - { - m_offset += n; - return *this; - } - - inline self_type& operator-=(difference_type n) - { - m_offset -= n; - return *this; - } - - inline self_type operator+(difference_type n) const - { - return self_type(p_b, m_offset + n); - } - - inline self_type operator-(difference_type n) const - { - return self_type(p_b, m_offset - n); - } - - inline self_type operator-(const self_type& rhs) const - { - self_type tmp(*this); - tmp -= (m_offset - rhs.m_offset); - return tmp; - } - - inline std::size_t offset() const - { - return m_offset; - } - - private: - - const B* p_b; - std::size_t m_offset; - }; - - template - inline bool operator==(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) - { - return lhs.offset() == rhs.offset(); - } - - template - inline bool operator!=(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) - { - return !(lhs == rhs); - } - - template - inline bool operator<(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) - { - return lhs.offset() < rhs.offset(); - } - - template - inline bool operator<=(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) - { - return (lhs < rhs) || (lhs == rhs); - } - - template - inline bool operator>(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) - { - return !(lhs <= rhs); - } - - template - inline bool operator>=(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) - { - return !(lhs < rhs); - } - - template - class pyarray_backstrides - { - public: - - using self_type = pyarray_backstrides; - using array_type = A; - using value_type = typename array_type::size_type; - using const_reference = value_type; - using reference = const_reference; - using const_pointer = const value_type*; - using pointer = const_pointer; - using size_type = typename array_type::size_type; - using difference_type = typename array_type::difference_type; - - using const_iterator = pybackstrides_iterator; - using iterator = const_iterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - pyarray_backstrides() = default; - pyarray_backstrides(const array_type& a); - - bool empty() const; - size_type size() const; - - value_type operator[](size_type i) const; - - const_reference front() const; - const_reference back() const; - - const_iterator begin() const; - const_iterator end() const; - const_iterator cbegin() const; - const_iterator cend() const; - - const_reverse_iterator rbegin() const; - const_reverse_iterator rend() const; - const_reverse_iterator crbegin() const; - const_reverse_iterator crend() const; - - private: - - const array_type* p_a; - }; - template struct xiterable_inner_types> : xcontainer_iterable_types> @@ -425,101 +232,6 @@ namespace xt friend class pycontainer>; }; - /************************************** - * pyarray_backstrides implementation * - **************************************/ - - template - inline pyarray_backstrides::pyarray_backstrides(const array_type& a) - : p_a(&a) - { - } - - template - inline bool pyarray_backstrides::empty() const - { - return p_a->dimension() == 0; - } - - template - inline auto pyarray_backstrides::size() const -> size_type - { - return p_a->dimension(); - } - - template - inline auto pyarray_backstrides::operator[](size_type i) const -> value_type - { - value_type sh = p_a->shape()[i]; - value_type res = sh == 1 ? 0 : (sh - 1) * p_a->strides()[i]; - return res; - } - - template - inline auto pyarray_backstrides::front() const -> const_reference - { - value_type sh = p_a->shape()[0]; - value_type res = sh == 1 ? 0 : (sh - 1) * p_a->strides()[0]; - return res; - } - - template - inline auto pyarray_backstrides::back() const -> const_reference - { - auto index = p_a->size() - 1; - value_type sh = p_a->shape()[index]; - value_type res = sh == 1 ? 0 : (sh - 1) * p_a->strides()[index]; - return res; - } - - template - inline auto pyarray_backstrides::begin() const -> const_iterator - { - return cbegin(); - } - - template - inline auto pyarray_backstrides::end() const -> const_iterator - { - return cend(); - } - - template - inline auto pyarray_backstrides::cbegin() const -> const_iterator - { - return const_iterator(this, 0); - } - - template - inline auto pyarray_backstrides::cend() const -> const_iterator - { - return const_iterator(this, size()); - } - - template - inline auto pyarray_backstrides::rbegin() const -> const_reverse_iterator - { - return crbegin(); - } - - template - inline auto pyarray_backstrides::rend() const -> const_reverse_iterator - { - return crend(); - } - - template - inline auto pyarray_backstrides::crbegin() const -> const_reverse_iterator - { - return const_reverse_iterator(end()); - } - - template - inline auto pyarray_backstrides::crend() const -> const_reverse_iterator - { - return const_reverse_iterator(begin()); - } - /************************** * pyarray implementation * **************************/ diff --git a/include/xtensor-python/pyarray_backstrides.hpp b/include/xtensor-python/pyarray_backstrides.hpp new file mode 100644 index 0000000..4dfdab9 --- /dev/null +++ b/include/xtensor-python/pyarray_backstrides.hpp @@ -0,0 +1,378 @@ +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * +* * +* Distributed under the terms of the BSD 3-Clause License. * +* * +* The full license is in the file LICENSE, distributed with this software. * +****************************************************************************/ + +#ifndef PY_ARRAY_BACKSTRIDES_HPP +#define PY_ARRAY_BACKSTRIDES_HPP + +#include +#include + +namespace xt +{ + + /************************** + * pybackstrides_iterator * + **************************/ + + template + class pybackstrides_iterator + { + public: + + using self_type = pybackstrides_iterator; + + using value_type = typename B::value_type; + using pointer = const value_type*; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::random_access_iterator_tag; + + pybackstrides_iterator(const B* b, std::size_t offset); + + reference operator*() const; + pointer operator->() const; + + reference operator[](difference_type n) const; + + self_type& operator++(); + self_type& operator--(); + + self_type operator++(int); + self_type operator--(int); + + self_type& operator+=(difference_type n); + self_type& operator-=(difference_type n); + + self_type operator+(difference_type n) const; + self_type operator-(difference_type n) const; + self_type operator-(const self_type& rhs) const; + + std::size_t offset() const; + + private: + + const B* p_b; + std::size_t m_offset; + }; + + template + inline bool operator==(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs); + + template + inline bool operator!=(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs); + + template + inline bool operator<(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs); + + template + inline bool operator<=(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs); + + template + inline bool operator>(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs); + + template + inline bool operator>=(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs); + + /*********************** + * pyarray_backstrides * + ***********************/ + + template + class pyarray_backstrides + { + public: + + using self_type = pyarray_backstrides; + using array_type = A; + using value_type = typename array_type::size_type; + using const_reference = value_type; + using reference = const_reference; + using const_pointer = const value_type*; + using pointer = const_pointer; + using size_type = typename array_type::size_type; + using difference_type = typename array_type::difference_type; + + using const_iterator = pybackstrides_iterator; + using iterator = const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + pyarray_backstrides() = default; + pyarray_backstrides(const array_type& a); + + bool empty() const; + size_type size() const; + + value_type operator[](size_type i) const; + + const_reference front() const; + const_reference back() const; + + const_iterator begin() const; + const_iterator end() const; + const_iterator cbegin() const; + const_iterator cend() const; + + const_reverse_iterator rbegin() const; + const_reverse_iterator rend() const; + const_reverse_iterator crbegin() const; + const_reverse_iterator crend() const; + + private: + + const array_type* p_a; + }; + + /***************************************** + * pybackstrides_iterator implementation * + *****************************************/ + + template + inline pybackstrides_iterator::pybackstrides_iterator(const B* b, std::size_t offset) + : p_b(b), m_offset(offset) + { + } + + template + inline auto pybackstrides_iterator::operator*() const -> reference + { + return p_b->operator[](m_offset); + } + + template + inline auto pybackstrides_iterator::operator->() const -> pointer + { + // Returning the address of a temporary + value_type res = p_b->operator[](m_offset); + return &res; + } + + template + inline auto pybackstrides_iterator::operator[](difference_type n) const -> reference + { + return p_b->operator[](m_offset + n); + } + + template + inline auto pybackstrides_iterator::operator++() -> self_type& + { + ++m_offset; + return *this; + } + + template + inline auto pybackstrides_iterator::operator--() -> self_type& + { + --m_offset; + return *this; + } + + template + inline auto pybackstrides_iterator::operator++(int )-> self_type + { + self_type tmp(*this); + ++m_offset; + return tmp; + } + + template + inline auto pybackstrides_iterator::operator--(int) -> self_type + { + self_type tmp(*this); + --m_offset; + return tmp; + } + + template + inline auto pybackstrides_iterator::operator+=(difference_type n) -> self_type& + { + m_offset += n; + return *this; + } + + template + inline auto pybackstrides_iterator::operator-=(difference_type n) -> self_type& + { + m_offset -= n; + return *this; + } + + template + inline auto pybackstrides_iterator::operator+(difference_type n) const -> self_type + { + return self_type(p_b, m_offset + n); + } + + template + inline auto pybackstrides_iterator::operator-(difference_type n) const -> self_type + { + return self_type(p_b, m_offset - n); + } + + template + inline auto pybackstrides_iterator::operator-(const self_type& rhs) const -> self_type + { + self_type tmp(*this); + tmp -= (m_offset - rhs.m_offset); + return tmp; + } + + template + inline std::size_t pybackstrides_iterator::offset() const + { + return m_offset; + } + + template + inline bool operator==(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs) + { + return lhs.offset() == rhs.offset(); + } + + template + inline bool operator!=(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs) + { + return !(lhs == rhs); + } + + template + inline bool operator<(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs) + { + return lhs.offset() < rhs.offset(); + } + + template + inline bool operator<=(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs) + { + return (lhs < rhs) || (lhs == rhs); + } + + template + inline bool operator>(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs) + { + return !(lhs <= rhs); + } + + template + inline bool operator>=(const pybackstrides_iterator& lhs, + const pybackstrides_iterator& rhs) + { + return !(lhs < rhs); + } + + /************************************** + * pyarray_backstrides implementation * + **************************************/ + + template + inline pyarray_backstrides::pyarray_backstrides(const array_type& a) + : p_a(&a) + { + } + + template + inline bool pyarray_backstrides::empty() const + { + return p_a->dimension() == 0; + } + + template + inline auto pyarray_backstrides::size() const -> size_type + { + return p_a->dimension(); + } + + template + inline auto pyarray_backstrides::operator[](size_type i) const -> value_type + { + value_type sh = p_a->shape()[i]; + value_type res = sh == 1 ? 0 : (sh - 1) * p_a->strides()[i]; + return res; + } + + template + inline auto pyarray_backstrides::front() const -> const_reference + { + value_type sh = p_a->shape()[0]; + value_type res = sh == 1 ? 0 : (sh - 1) * p_a->strides()[0]; + return res; + } + + template + inline auto pyarray_backstrides::back() const -> const_reference + { + auto index = p_a->size() - 1; + value_type sh = p_a->shape()[index]; + value_type res = sh == 1 ? 0 : (sh - 1) * p_a->strides()[index]; + return res; + } + + template + inline auto pyarray_backstrides::begin() const -> const_iterator + { + return cbegin(); + } + + template + inline auto pyarray_backstrides::end() const -> const_iterator + { + return cend(); + } + + template + inline auto pyarray_backstrides::cbegin() const -> const_iterator + { + return const_iterator(this, 0); + } + + template + inline auto pyarray_backstrides::cend() const -> const_iterator + { + return const_iterator(this, size()); + } + + template + inline auto pyarray_backstrides::rbegin() const -> const_reverse_iterator + { + return crbegin(); + } + + template + inline auto pyarray_backstrides::rend() const -> const_reverse_iterator + { + return crend(); + } + + template + inline auto pyarray_backstrides::crbegin() const -> const_reverse_iterator + { + return const_reverse_iterator(end()); + } + + template + inline auto pyarray_backstrides::crend() const -> const_reverse_iterator + { + return const_reverse_iterator(begin()); + } + + +} + +#endif From fcbc478ff129130cb4da2e1dd6474f3c5a5738b8 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 13 Dec 2019 15:48:19 +0100 Subject: [PATCH 021/102] Upgraded to gtest 1.10.0 --- .travis.yml | 1 + test/downloadGTest.cmake.in | 2 +- test/test_pyarray_ref.cpp | 275 ++++++++++++++++++++++++++++++++++++ 3 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 test/test_pyarray_ref.cpp diff --git a/.travis.yml b/.travis.yml index 975cd24..5883980 100644 --- a/.travis.yml +++ b/.travis.yml @@ -118,6 +118,7 @@ install: # Define the version of miniconda to download - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then MINCONDA_OS=$MINCONDA_LINUX; + cat /proc/cpuinfo; elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then MINCONDA_OS=$MINCONDA_OSX; fi diff --git a/test/downloadGTest.cmake.in b/test/downloadGTest.cmake.in index e4431f0..2d5cc5b 100644 --- a/test/downloadGTest.cmake.in +++ b/test/downloadGTest.cmake.in @@ -14,7 +14,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.8.1 + GIT_TAG release-1.10.0 SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" diff --git a/test/test_pyarray_ref.cpp b/test/test_pyarray_ref.cpp new file mode 100644 index 0000000..995d858 --- /dev/null +++ b/test/test_pyarray_ref.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * +* * +* Distributed under the terms of the BSD 3-Clause License. * +* * +* The full license is in the file LICENSE, distributed with this software. * +****************************************************************************/ + +#include "gtest/gtest.h" + +#include "xtensor-python/pyarray_ref.hpp" + +#include "xtensor/xarray.hpp" +#include "xtensor/xview.hpp" + +#include "test_common.hpp" + +namespace xt +{ + using container_type = std::vector; + + template + using ndarray = pyarray_ref; + + void test1 (ndarrayconst& x) + { + ndarray y = x; + ndarray z = xt::zeros({10}); + } + + double compute(ndarray const& xs) + { + auto v = xt::view (xs, 0, xt::all()); + return v(0); + } + + TEST(pyarray_ref, initializer_constructor) + { + pyarray_ref t + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; + + EXPECT_EQ(t.dimension(), 3); + EXPECT_EQ(t(0, 0, 1), 1); + EXPECT_EQ(t.shape()[0], 2); + } + + TEST(pyarray_ref, shaped_constructor) + { + { + SCOPED_TRACE("row_major constructor"); + row_major_result<> rm; + pyarray_ref ra(rm.m_shape); + compare_shape(ra, rm); + EXPECT_EQ(layout_type::row_major, ra.layout()); + } + + { + SCOPED_TRACE("column_major constructor"); + column_major_result<> cm; + pyarray_ref ca(cm.m_shape, layout_type::column_major); + compare_shape(ca, cm); + EXPECT_EQ(layout_type::column_major, ca.layout()); + } + } + + TEST(pyarray_ref, from_shape) + { + auto arr = pyarray_ref::from_shape({5, 2, 6}); + auto exp_shape = std::vector{5, 2, 6}; + EXPECT_TRUE(std::equal(arr.shape().begin(), arr.shape().end(), exp_shape.begin())); + EXPECT_EQ(arr.shape().size(), 3); + EXPECT_EQ(arr.size(), 5 * 2 * 6); + } + + TEST(pyarray_ref, strided_constructor) + { + central_major_result<> cmr; + pyarray_ref cma(cmr.m_shape, cmr.m_strides); + compare_shape(cma, cmr); + } + + TEST(pyarray_ref, valued_constructor) + { + { + SCOPED_TRACE("row_major valued constructor"); + row_major_result<> rm; + int value = 2; + pyarray_ref ra(rm.m_shape, value); + compare_shape(ra, rm); + std::vector vec(ra.size(), value); + EXPECT_TRUE(std::equal(vec.cbegin(), vec.cend(), ra.storage().cbegin())); + } + + { + SCOPED_TRACE("column_major valued constructor"); + column_major_result<> cm; + int value = 2; + pyarray_ref ca(cm.m_shape, value, layout_type::column_major); + compare_shape(ca, cm); + std::vector vec(ca.size(), value); + EXPECT_TRUE(std::equal(vec.cbegin(), vec.cend(), ca.storage().cbegin())); + } + } + + TEST(pyarray_ref, strided_valued_constructor) + { + central_major_result<> cmr; + int value = 2; + pyarray_ref cma(cmr.m_shape, cmr.m_strides, value); + compare_shape(cma, cmr); + std::vector vec(cma.size(), value); + EXPECT_TRUE(std::equal(vec.cbegin(), vec.cend(), cma.storage().cbegin())); + } + + TEST(pyarray_ref, copy_semantic) + { + central_major_result<> res; + int value = 2; + pyarray_ref a(res.m_shape, res.m_strides, value); + + { + SCOPED_TRACE("copy constructor"); + pyarray_ref b(a); + compare_shape(a, b); + EXPECT_EQ(a.storage(), b.storage()); + a.data()[0] += 1; + EXPECT_EQ(a.storage()[0], b.storage()[0]); + } + + { + SCOPED_TRACE("assignment operator"); + row_major_result<> r; + pyarray_ref c(r.m_shape, 0); + EXPECT_NE(a.storage(), c.storage()); + c = a; + compare_shape(a, c); + EXPECT_EQ(a.storage(), c.storage()); + a.data()[0] += 1; + EXPECT_EQ(a.storage()[0], c.storage()[0]); + } + } + + TEST(pyarray_ref, move_semantic) + { + central_major_result<> res; + int value = 2; + pyarray_ref a(res.m_shape, res.m_strides, value); + + { + SCOPED_TRACE("move constructor"); + pyarray_ref tmp(a); + pyarray_ref b(std::move(tmp)); + compare_shape(a, b); + EXPECT_EQ(a.storage(), b.storage()); + } + + { + SCOPED_TRACE("move assignment"); + row_major_result<> r; + pyarray_ref c(r.m_shape, 0); + EXPECT_NE(a.storage(), c.storage()); + pyarray_ref tmp(a); + c = std::move(tmp); + compare_shape(a, c); + EXPECT_EQ(a.storage(), c.storage()); + } + } + + TEST(pyarray_ref, extended_constructor) + { + xt::xarray a1 = { { 1, 2 },{ 3, 4 } }; + xt::xarray a2 = { { 1, 2 },{ 3, 4 } }; + pyarray_ref c = a1 + a2; + EXPECT_EQ(c(0, 0), a1(0, 0) + a2(0, 0)); + EXPECT_EQ(c(0, 1), a1(0, 1) + a2(0, 1)); + EXPECT_EQ(c(1, 0), a1(1, 0) + a2(1, 0)); + EXPECT_EQ(c(1, 1), a1(1, 1) + a2(1, 1)); + } + + TEST(pyarray_ref, resize) + { + pyarray_ref a; + test_resize(a); + + pyarray_ref b = { {1, 2}, {3, 4} }; + a.resize(b.shape()); + EXPECT_EQ(a.shape(), b.shape()); + } + + TEST(pyarray_ref, transpose) + { + pyarray_ref a; + test_transpose(a); + } + + TEST(pyarray_ref, access) + { + pyarray_ref a; + test_access(a); + } + + TEST(pyarray_ref, indexed_access) + { + pyarray_ref a; + test_indexed_access(a); + } + + TEST(pyarray_ref, broadcast_shape) + { + pyarray_ref a; + test_broadcast(a); + test_broadcast2(a); + } + + TEST(pyarray_ref, iterator) + { + pyarray_ref a; + pyarray_ref b; + test_iterator(a, b); + + pyarray_ref c; + bool truthy = std::is_same::value; + EXPECT_TRUE(truthy); + } + + TEST(pyarray_ref, initializer_list) + { + pyarray_ref a0(1); + pyarray_ref a1({1, 2}); + pyarray_ref a2({{1, 2}, {2, 4}, {5, 6}}); + EXPECT_EQ(1, a0()); + EXPECT_EQ(2, a1(1)); + EXPECT_EQ(4, a2(1, 1)); + } + + TEST(pyarray_ref, zerod) + { + pyarray_ref a; + EXPECT_EQ(0, a()); + } + + TEST(pyarray_ref, reshape) + { + pyarray_ref a = {{1,2,3}, {4,5,6}}; + auto ptr = a.data(); + a.reshape({1, 6}); + std::vector sc1({1, 6}); + EXPECT_TRUE(std::equal(sc1.begin(), sc1.end(), a.shape().begin()) && a.shape().size() == 2); + EXPECT_EQ(ptr, a.data()); + a.reshape({6}); + std::vector sc2 = {6}; + EXPECT_TRUE(std::equal(sc2.begin(), sc2.end(), a.shape().begin()) && a.shape().size() == 1); + EXPECT_EQ(ptr, a.data()); + } + + TEST(pyarray_ref, view) + { + xt::pyarray_ref arr = xt::zeros({ 10 }); + auto v = xt::view(arr, xt::all()); + EXPECT_EQ(v(0), 0.); + } + + TEST(pyarray_ref, zerod_copy) + { + xt::pyarray_ref arr = 2; + xt::pyarray_ref arr2(arr); + EXPECT_EQ(arr(), arr2()); + } +} From c2419d8d0b430218810b01f58dc6f49634f3034c Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 16 Dec 2019 21:52:45 +0100 Subject: [PATCH 022/102] Upgraded to Xenial --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5883980..de591b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: cpp -dist: trusty +dist: xenial matrix: include: - os: linux @@ -56,7 +56,7 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-3.9 + - llvm-toolchain-xenial-3.9 packages: - g++-4.9 - clang-3.9 @@ -66,7 +66,7 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-4.0 + - llvm-toolchain-xenial-4.0 packages: - g++-4.9 - clang-4.0 @@ -76,7 +76,7 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-5.0 + - llvm-toolchain-xenial-5.0 packages: - g++-4.9 - clang-5.0 @@ -86,7 +86,7 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-6.0 + - llvm-toolchain-xenial-6.0 packages: - clang-6.0 env: COMPILER=clang CLANG=6.0 PY=3 From ca0edd1d3130d8b2e03fee9063604297b49c7d18 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 17 Dec 2019 09:43:29 +0100 Subject: [PATCH 023/102] Upgraded to xtensor 0.21.2 --- .appveyor.yml | 2 +- .travis.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7563438..fba87eb 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.1 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.2 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/.travis.yml b/.travis.yml index de591b7..123c24a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -156,7 +156,7 @@ install: else conda install pybind11==${PYBIND11_VERSION} -c conda-forge fi - - conda install xtensor==0.21.1 -c conda-forge + - conda install xtensor==0.21.2 -c conda-forge - cmake -D DOWNLOAD_GTEST=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda -D PYTHON_EXECUTABLE=$PY_EXE . - make -j2 test_xtensor_python - make install From 831400e39033cb0b94376ce21c20c2dbc90d6f26 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 17 Dec 2019 10:37:53 +0100 Subject: [PATCH 024/102] Release 0.24.1 --- README.md | 3 ++- include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b5175e2..4258521 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,8 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.21.1 | ~2.4.3 | +| master | ^0.21.2 | ~2.4.3 | +| 0.24.1 | ^0.21.2 | ~2.4.3 | | 0.24.0 | ^0.21.1 | ~2.4.3 | | 0.23.2 | ^0.20.10 | ~2.4.3 | | 0.23.1 | ^0.20.6 | ~2.2.1 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 1da85e7..37a1b97 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -12,6 +12,6 @@ #define XTENSOR_PYTHON_VERSION_MAJOR 0 #define XTENSOR_PYTHON_VERSION_MINOR 24 -#define XTENSOR_PYTHON_VERSION_PATCH 0 +#define XTENSOR_PYTHON_VERSION_PATCH 1 #endif From 48122b62ce532be23d300bc3a2d7c3ff3fc78893 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Thu, 26 Dec 2019 15:47:48 +0100 Subject: [PATCH 025/102] Fixup URLs --- README.md | 4 ++-- docs/source/cookiecutter.rst | 4 ++-- docs/source/index.rst | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4258521..dfa9c50 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Documentation](http://readthedocs.org/projects/xtensor-python/badge/?version=latest)](https://xtensor-python.readthedocs.io/en/latest/?badge=latest) [![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -Python bindings for the [xtensor](https://github.com/QuantStack/xtensor) C++ multi-dimensional array library. +Python bindings for the [xtensor](https://github.com/xtensor-stack/xtensor) C++ multi-dimensional array library. - `xtensor` is a C++ library for multi-dimensional arrays enabling numpy-style broadcasting and lazy computing. - `xtensor-python` enables inplace use of numpy arrays in C++ with all the benefits from `xtensor` @@ -145,7 +145,7 @@ This will pull the dependencies to xtensor-python, that is `pybind11` and `xtens ## Project cookiecutter -A template for a project making use of `xtensor-python` is available in the form of a cookiecutter [here](https://github.com/QuantStack/xtensor-python-cookiecutter). +A template for a project making use of `xtensor-python` is available in the form of a cookiecutter [here](https://github.com/xtensor-stack/xtensor-python-cookiecutter). This project is meant to help library authors get started with the xtensor python bindings. diff --git a/docs/source/cookiecutter.rst b/docs/source/cookiecutter.rst index 2116959..e725106 100644 --- a/docs/source/cookiecutter.rst +++ b/docs/source/cookiecutter.rst @@ -32,7 +32,7 @@ After installing cookiecutter, use the `xtensor-python-cookiecutter`_: .. code:: - cookiecutter https://github.com/QuantStack/xtensor-python-cookiecutter.git + cookiecutter https://github.com/xtensor-stack/xtensor-python-cookiecutter.git As xtensor-python-cookiecutter runs, you will be asked for basic information about your custom extension project. You will be prompted for the following @@ -50,6 +50,6 @@ This will produce a directory containing all the required content for a minimal project making use of xtensor with all the required boilerplate for package management, together with a few basic examples. -.. _xtensor-python-cookiecutter: https://github.com/QuantStack/xtensor-python-cookiecutter +.. _xtensor-python-cookiecutter: https://github.com/xtensor-stack/xtensor-python-cookiecutter .. _cookiecutter: https://github.com/audreyr/cookiecutter diff --git a/docs/source/index.rst b/docs/source/index.rst index 3dd0fd3..6f9c852 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -80,6 +80,6 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f .. _NumPy: http://www.numpy.org .. _`Buffer Protocol`: https://docs.python.org/3/c-api/buffer.html .. _`numpy to xtensor cheat sheet`: http://xtensor.readthedocs.io/en/latest/numpy.html -.. _xtensor: https://github.com/QuantStack/xtensor +.. _xtensor: https://github.com/xtensor-stack/xtensor .. _pybind11: https://github.com/pybind/pybind11 -.. _xtensor-python-cookiecutter: https://github.com/QuantStack/xtensor-python-cookiecutter +.. _xtensor-python-cookiecutter: https://github.com/xtensor-stack/xtensor-python-cookiecutter From fb77795710bae0f7614ea05bfad4c6516dde30dd Mon Sep 17 00:00:00 2001 From: Ryan Butler Date: Wed, 15 Jan 2020 18:36:47 -0500 Subject: [PATCH 026/102] Enabled `add_subdirectory()` for xtensor dependency --- CMakeLists.txt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f40248..b5c4a77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,10 +32,20 @@ message(STATUS "xtensor-python v${${PROJECT_NAME}_VERSION}") # Dependencies # ============ -find_package(xtl REQUIRED) -message(STATUS "Found xtl: ${xtl_INCLUDE_DIRS}/xtl") -find_package(xtensor REQUIRED) -message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor") +set(xtensor_REQUIRED_VERSION 0.21.2) +if(TARGET xtensor) + set(xtensor_VERSION ${XTENSOR_VERSION_MAJOR}.${XTENSOR_VERSION_MINOR}.${XTENSOR_VERSION_PATCH}) + # Note: This is not SEMVER compatible comparison + if( NOT ${xtensor_VERSION} VERSION_GREATER_EQUAL ${xtensor_REQUIRED_VERSION}) + message(ERROR "Mismatch xtensor versions. Found '${xtensor_VERSION}' but requires: '${xtensor_REQUIRED_VERSION}'") + else() + message(STATUS "Found xtensor v${xtensor_VERSION}") + endif() +else() + find_package(xtensor ${xtensor_REQUIRED_VERSION} REQUIRED) + message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor") +endif() + find_package(pybind11 REQUIRED) message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") find_package(NumPy REQUIRED) From 6667b3e675995b3d1f894069a31163fcc0ed256d Mon Sep 17 00:00:00 2001 From: Ryan Butler Date: Wed, 15 Jan 2020 18:53:54 -0500 Subject: [PATCH 027/102] Enabled `add_subdirectory()` for pybind11 dependency --- CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5c4a77..47cc4b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,9 +45,16 @@ else() find_package(xtensor ${xtensor_REQUIRED_VERSION} REQUIRED) message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor") endif() + +# Currently no required version for pybind11 +if(TARGET pybind11) + # pybind11 has a variable that indicates its version already, so use that + message(STATUS "Found pybind11 v${pybind11_VERSION}") +else() + find_package(pybind11 REQUIRED) + message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") +endif() -find_package(pybind11 REQUIRED) -message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") find_package(NumPy REQUIRED) message(STATUS "Found numpy: ${NUMPY_INCLUDE_DIRS}") From 5ac171b015bc379e274923d9b9fef8ea5191beb1 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Wed, 22 Jan 2020 09:56:48 +0100 Subject: [PATCH 028/102] Removed irrelevant test_pyarray_ref file --- test/test_pyarray_ref.cpp | 275 -------------------------------------- 1 file changed, 275 deletions(-) delete mode 100644 test/test_pyarray_ref.cpp diff --git a/test/test_pyarray_ref.cpp b/test/test_pyarray_ref.cpp deleted file mode 100644 index 995d858..0000000 --- a/test/test_pyarray_ref.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/*************************************************************************** -* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * -* Copyright (c) QuantStack * -* * -* Distributed under the terms of the BSD 3-Clause License. * -* * -* The full license is in the file LICENSE, distributed with this software. * -****************************************************************************/ - -#include "gtest/gtest.h" - -#include "xtensor-python/pyarray_ref.hpp" - -#include "xtensor/xarray.hpp" -#include "xtensor/xview.hpp" - -#include "test_common.hpp" - -namespace xt -{ - using container_type = std::vector; - - template - using ndarray = pyarray_ref; - - void test1 (ndarrayconst& x) - { - ndarray y = x; - ndarray z = xt::zeros({10}); - } - - double compute(ndarray const& xs) - { - auto v = xt::view (xs, 0, xt::all()); - return v(0); - } - - TEST(pyarray_ref, initializer_constructor) - { - pyarray_ref t - {{{ 0, 1, 2}, - { 3, 4, 5}, - { 6, 7, 8}}, - {{ 9, 10, 11}, - {12, 13, 14}, - {15, 16, 17}}}; - - EXPECT_EQ(t.dimension(), 3); - EXPECT_EQ(t(0, 0, 1), 1); - EXPECT_EQ(t.shape()[0], 2); - } - - TEST(pyarray_ref, shaped_constructor) - { - { - SCOPED_TRACE("row_major constructor"); - row_major_result<> rm; - pyarray_ref ra(rm.m_shape); - compare_shape(ra, rm); - EXPECT_EQ(layout_type::row_major, ra.layout()); - } - - { - SCOPED_TRACE("column_major constructor"); - column_major_result<> cm; - pyarray_ref ca(cm.m_shape, layout_type::column_major); - compare_shape(ca, cm); - EXPECT_EQ(layout_type::column_major, ca.layout()); - } - } - - TEST(pyarray_ref, from_shape) - { - auto arr = pyarray_ref::from_shape({5, 2, 6}); - auto exp_shape = std::vector{5, 2, 6}; - EXPECT_TRUE(std::equal(arr.shape().begin(), arr.shape().end(), exp_shape.begin())); - EXPECT_EQ(arr.shape().size(), 3); - EXPECT_EQ(arr.size(), 5 * 2 * 6); - } - - TEST(pyarray_ref, strided_constructor) - { - central_major_result<> cmr; - pyarray_ref cma(cmr.m_shape, cmr.m_strides); - compare_shape(cma, cmr); - } - - TEST(pyarray_ref, valued_constructor) - { - { - SCOPED_TRACE("row_major valued constructor"); - row_major_result<> rm; - int value = 2; - pyarray_ref ra(rm.m_shape, value); - compare_shape(ra, rm); - std::vector vec(ra.size(), value); - EXPECT_TRUE(std::equal(vec.cbegin(), vec.cend(), ra.storage().cbegin())); - } - - { - SCOPED_TRACE("column_major valued constructor"); - column_major_result<> cm; - int value = 2; - pyarray_ref ca(cm.m_shape, value, layout_type::column_major); - compare_shape(ca, cm); - std::vector vec(ca.size(), value); - EXPECT_TRUE(std::equal(vec.cbegin(), vec.cend(), ca.storage().cbegin())); - } - } - - TEST(pyarray_ref, strided_valued_constructor) - { - central_major_result<> cmr; - int value = 2; - pyarray_ref cma(cmr.m_shape, cmr.m_strides, value); - compare_shape(cma, cmr); - std::vector vec(cma.size(), value); - EXPECT_TRUE(std::equal(vec.cbegin(), vec.cend(), cma.storage().cbegin())); - } - - TEST(pyarray_ref, copy_semantic) - { - central_major_result<> res; - int value = 2; - pyarray_ref a(res.m_shape, res.m_strides, value); - - { - SCOPED_TRACE("copy constructor"); - pyarray_ref b(a); - compare_shape(a, b); - EXPECT_EQ(a.storage(), b.storage()); - a.data()[0] += 1; - EXPECT_EQ(a.storage()[0], b.storage()[0]); - } - - { - SCOPED_TRACE("assignment operator"); - row_major_result<> r; - pyarray_ref c(r.m_shape, 0); - EXPECT_NE(a.storage(), c.storage()); - c = a; - compare_shape(a, c); - EXPECT_EQ(a.storage(), c.storage()); - a.data()[0] += 1; - EXPECT_EQ(a.storage()[0], c.storage()[0]); - } - } - - TEST(pyarray_ref, move_semantic) - { - central_major_result<> res; - int value = 2; - pyarray_ref a(res.m_shape, res.m_strides, value); - - { - SCOPED_TRACE("move constructor"); - pyarray_ref tmp(a); - pyarray_ref b(std::move(tmp)); - compare_shape(a, b); - EXPECT_EQ(a.storage(), b.storage()); - } - - { - SCOPED_TRACE("move assignment"); - row_major_result<> r; - pyarray_ref c(r.m_shape, 0); - EXPECT_NE(a.storage(), c.storage()); - pyarray_ref tmp(a); - c = std::move(tmp); - compare_shape(a, c); - EXPECT_EQ(a.storage(), c.storage()); - } - } - - TEST(pyarray_ref, extended_constructor) - { - xt::xarray a1 = { { 1, 2 },{ 3, 4 } }; - xt::xarray a2 = { { 1, 2 },{ 3, 4 } }; - pyarray_ref c = a1 + a2; - EXPECT_EQ(c(0, 0), a1(0, 0) + a2(0, 0)); - EXPECT_EQ(c(0, 1), a1(0, 1) + a2(0, 1)); - EXPECT_EQ(c(1, 0), a1(1, 0) + a2(1, 0)); - EXPECT_EQ(c(1, 1), a1(1, 1) + a2(1, 1)); - } - - TEST(pyarray_ref, resize) - { - pyarray_ref a; - test_resize(a); - - pyarray_ref b = { {1, 2}, {3, 4} }; - a.resize(b.shape()); - EXPECT_EQ(a.shape(), b.shape()); - } - - TEST(pyarray_ref, transpose) - { - pyarray_ref a; - test_transpose(a); - } - - TEST(pyarray_ref, access) - { - pyarray_ref a; - test_access(a); - } - - TEST(pyarray_ref, indexed_access) - { - pyarray_ref a; - test_indexed_access(a); - } - - TEST(pyarray_ref, broadcast_shape) - { - pyarray_ref a; - test_broadcast(a); - test_broadcast2(a); - } - - TEST(pyarray_ref, iterator) - { - pyarray_ref a; - pyarray_ref b; - test_iterator(a, b); - - pyarray_ref c; - bool truthy = std::is_same::value; - EXPECT_TRUE(truthy); - } - - TEST(pyarray_ref, initializer_list) - { - pyarray_ref a0(1); - pyarray_ref a1({1, 2}); - pyarray_ref a2({{1, 2}, {2, 4}, {5, 6}}); - EXPECT_EQ(1, a0()); - EXPECT_EQ(2, a1(1)); - EXPECT_EQ(4, a2(1, 1)); - } - - TEST(pyarray_ref, zerod) - { - pyarray_ref a; - EXPECT_EQ(0, a()); - } - - TEST(pyarray_ref, reshape) - { - pyarray_ref a = {{1,2,3}, {4,5,6}}; - auto ptr = a.data(); - a.reshape({1, 6}); - std::vector sc1({1, 6}); - EXPECT_TRUE(std::equal(sc1.begin(), sc1.end(), a.shape().begin()) && a.shape().size() == 2); - EXPECT_EQ(ptr, a.data()); - a.reshape({6}); - std::vector sc2 = {6}; - EXPECT_TRUE(std::equal(sc2.begin(), sc2.end(), a.shape().begin()) && a.shape().size() == 1); - EXPECT_EQ(ptr, a.data()); - } - - TEST(pyarray_ref, view) - { - xt::pyarray_ref arr = xt::zeros({ 10 }); - auto v = xt::view(arr, xt::all()); - EXPECT_EQ(v(0), 0.); - } - - TEST(pyarray_ref, zerod_copy) - { - xt::pyarray_ref arr = 2; - xt::pyarray_ref arr2(arr); - EXPECT_EQ(arr(), arr2()); - } -} From ef145df5e5ea35071fd49b27e840739cbbdbe344 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 6 Mar 2020 15:34:06 +0100 Subject: [PATCH 029/102] Upgraded to latest version of xtensor --- .appveyor.yml | 2 +- .travis.yml | 21 +-------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index fba87eb..afd1646 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install gtest cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.2 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.4 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . - nmake test_xtensor_python diff --git a/.travis.yml b/.travis.yml index 123c24a..48a7838 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,25 +42,6 @@ matrix: packages: - g++-7 env: COMPILER=gcc GCC=7 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.9 - - clang-3.6 - env: COMPILER=clang CLANG=3.6 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-xenial-3.9 - packages: - - g++-4.9 - - clang-3.9 - env: COMPILER=clang CLANG=3.9 PY=3 - os: linux addons: apt: @@ -156,7 +137,7 @@ install: else conda install pybind11==${PYBIND11_VERSION} -c conda-forge fi - - conda install xtensor==0.21.2 -c conda-forge + - conda install xtensor==0.21.4 -c conda-forge - cmake -D DOWNLOAD_GTEST=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda -D PYTHON_EXECUTABLE=$PY_EXE . - make -j2 test_xtensor_python - make install From b748eac740c5df147ed8ee3b5130444e48fb609d Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Thu, 12 Mar 2020 23:30:41 +0100 Subject: [PATCH 030/102] Switched documentation build to QuantStack channel --- docs/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/environment.yml b/docs/environment.yml index 47e93f7..727c481 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -1,7 +1,7 @@ name: xtensor-python-docs channels: - - conda-forge + - QuantStack dependencies: - breathe From be2d27695aaea64df7c6e3a4fe928f8829cdf9b0 Mon Sep 17 00:00:00 2001 From: Eric Cousineau Date: Sun, 21 Jun 2020 14:59:17 -0400 Subject: [PATCH 031/102] README: Minor spelling change "seemless" => "seamless" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfa9c50..5c40460 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Python bindings for the [xtensor](https://github.com/xtensor-stack/xtensor) C++ - STL - compliant APIs. - A broad coverage of numpy APIs (see [the numpy to xtensor cheat sheet](http://xtensor.readthedocs.io/en/latest/numpy.html)). -The Python bindings for `xtensor` are based on the [pybind11](https://github.com/pybind/pybind11/) C++ library, which enables seemless interoperability between C++ and Python. +The Python bindings for `xtensor` are based on the [pybind11](https://github.com/pybind/pybind11/) C++ library, which enables seamless interoperability between C++ and Python. ## Installation From 2a9ef1df23d61fcab088f51a3329c38a567d9642 Mon Sep 17 00:00:00 2001 From: Nick Robison Date: Wed, 9 Sep 2020 08:28:13 -0400 Subject: [PATCH 032/102] Update CMakeLists to correctly find pybind11 alias targets Add an additional TARGET check in the root cmake file to correctly find the pybind11 alias targets. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47cc4b1..9d278d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,7 @@ else() endif() # Currently no required version for pybind11 -if(TARGET pybind11) +if(TARGET pybind11 OR TARGET pybind11::headers) # pybind11 has a variable that indicates its version already, so use that message(STATUS "Found pybind11 v${pybind11_VERSION}") else() From fb44c66a2d0aa938629b1fe386e8617ce7760369 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 27 Nov 2020 09:23:24 +0100 Subject: [PATCH 033/102] Added Azure Pipelines --- .../azure-pipelines-linux-clang.yml | 42 +++++++++++++++++++ .../azure-pipelines-linux-gcc.yml | 37 ++++++++++++++++ .azure-pipelines/azure-pipelines-osx.yml | 28 +++++++++++++ .azure-pipelines/unix-build.yml | 34 +++++++++++++++ azure-pipelines.yml | 8 ++++ environment-dev.yml | 13 ++++++ 6 files changed, 162 insertions(+) create mode 100644 .azure-pipelines/azure-pipelines-linux-clang.yml create mode 100644 .azure-pipelines/azure-pipelines-linux-gcc.yml create mode 100644 .azure-pipelines/azure-pipelines-osx.yml create mode 100644 .azure-pipelines/unix-build.yml create mode 100644 azure-pipelines.yml create mode 100644 environment-dev.yml diff --git a/.azure-pipelines/azure-pipelines-linux-clang.yml b/.azure-pipelines/azure-pipelines-linux-clang.yml new file mode 100644 index 0000000..f1d6894 --- /dev/null +++ b/.azure-pipelines/azure-pipelines-linux-clang.yml @@ -0,0 +1,42 @@ +jobs: + - job: 'Linux_0' + strategy: + matrix: + clang_4: + llvm_version: '4.0' + clang_5: + llvm_version: '5.0' + clang_6: + llvm_version: '6.0' + clang_7: + llvm_version: '7' + clang_8: + llvm_version: '8' + clang_9: + llvm_version: '9' + pool: + vmImage: ubuntu-16.04 + variables: + CC: clang-$(llvm_version) + CXX: clang++-$(llvm_version) + timeoutInMinutes: 360 + steps: + + - script: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + if [[ $(llvm_version) == '4.0' || $(llvm_version) == '5.0' ]]; then + sudo apt-get update + sudo apt-get --no-install-suggests --no-install-recommends install gcc-4.9 clang-$(llvm_version) + else + LLVM_VERSION=$(llvm_version) + get -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo add-apt-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-$LLVM_VERSION main" + sudo apt-get update + sudo apt-get --no-install-suggests --no-install-recommends install clang-$(llvm_version) + fi + displayName: Install build toolchain + + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH + + - template: unix-build.yml diff --git a/.azure-pipelines/azure-pipelines-linux-gcc.yml b/.azure-pipelines/azure-pipelines-linux-gcc.yml new file mode 100644 index 0000000..bf18b99 --- /dev/null +++ b/.azure-pipelines/azure-pipelines-linux-gcc.yml @@ -0,0 +1,37 @@ +jobs: + - job: 'Linux_1' + strategy: + matrix: + gcc_4: + gcc_version: '4.9' + gcc_5: + gcc_version: '5' + gcc_6: + gcc_version: '6' + gcc_7: + gcc_version: '7' + gcc_8: + gcc_version: '8' + gcc_9: + gcc_version: '9' + pool: + vmImage: ubuntu-16.04 + variables: + CC: gcc-$(gcc_version) + CXX: g++-$(gcc_version) + timeoutInMinutes: 360 + steps: + + - script: | + if [[ $(gcc_version) == '4.9' || $(gcc_version) == '6' ]]; then + sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get --no-install-suggests --no-install-recommends install g++-$(gcc_version) + fi + displayName: Install build toolchain + + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH + + - template: unix-build.yml + diff --git a/.azure-pipelines/azure-pipelines-osx.yml b/.azure-pipelines/azure-pipelines-osx.yml new file mode 100644 index 0000000..282a8ac --- /dev/null +++ b/.azure-pipelines/azure-pipelines-osx.yml @@ -0,0 +1,28 @@ +jobs: + - job: 'OSX' + strategy: + matrix: + macOS_10_14: + image_name: 'macOS-10.14' + macOS_10_15: + image_name: 'macOS-10.15' + pool: + vmImage: $(image_name) + variables: + CC: clang + CXX: clang++ + timeoutInMinutes: 360 + steps: + - script: | + echo "Removing homebrew for Azure to avoid conflicts with conda" + curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall > ~/uninstall_homebrew + chmod +x ~/uninstall_homebrew + ~/uninstall_homebrew -f -q + displayName: Remove homebrew + + - bash: | + echo "##vso[task.prependpath]$CONDA/bin" + sudo chown -R $USER $CONDA + displayName: Add conda to PATH + + - template: unix-build.yml diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml new file mode 100644 index 0000000..2601c1b --- /dev/null +++ b/.azure-pipelines/unix-build.yml @@ -0,0 +1,34 @@ +steps: + - script: | + conda config --set always_yes yes --set changeps1 no + conda update -q conda + conda env create --file environment-dev.yml + source activate xtensor-python + displayName: Install dependencies + + - script: | + source activate xtensor-python + mkdir build + cd build + cmake -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory) + displayName: Configure xtensor-python + workingDirectory: $(Build.BinariesDirectory) + + - script: | + source activate xtensor-python + make -j2 test_xtensor_python + displayName: Build xtensor-python + workingDirectory: $(Build.BinariesDirectory)/build + + - script: | + source activate xtensor-python + cd test + ./test_xtensor_python + displayName: Test xtensor-python (C++) + workingDirectory: $(Build.BinariesDirectory)/build/test + + - script: | + source activate xtensor-python + py.test -s + displayName: Test xtensor-python (Python) + workingDirectory: $(Build.BinariesDirectory)/build diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..e930dbe --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,8 @@ +trigger: + - master + +jobs: + - template: ./.azure-pipelines/azure-pipelines-linux-clang.yml + - template: ./.azure-pipelines/azure-pipelines-linux-gcc.yml + - template: ./.azure-pipelines/azure-pipelines-osx.yml + diff --git a/environment-dev.yml b/environment-dev.yml new file mode 100644 index 0000000..38554ed --- /dev/null +++ b/environment-dev.yml @@ -0,0 +1,13 @@ +name: xtensor-python +channels: + - conda-forge +dependencies: + # Build dependencies + - cmake + # Host dependencies + - xtensor=0.21.4 + - numpy + - pybind11=2.4.3 + # Test dependencies + - pytest + From d96bff41330598a057a569643412e52696995c38 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 27 Nov 2020 09:38:27 +0100 Subject: [PATCH 034/102] Fixed Azure Pipelines --- .azure-pipelines/unix-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index 2601c1b..81320c0 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -31,4 +31,4 @@ steps: source activate xtensor-python py.test -s displayName: Test xtensor-python (Python) - workingDirectory: $(Build.BinariesDirectory)/build + workingDirectory: $(Build.SourcesDirectory) From 3fb9904902b18dba4f8e16e196cfd981778827d8 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 27 Nov 2020 10:03:39 +0100 Subject: [PATCH 035/102] Fixed appveyor build --- .appveyor.yml | 5 +++-- test/CMakeLists.txt | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index afd1646..628cba0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -21,12 +21,13 @@ install: - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda info -a - - conda install gtest cmake -c conda-forge + - conda install cmake -c conda-forge - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.4 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe . + - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - nmake test_xtensor_python - nmake install + - rmdir /s/q "test/googletest-src" build_script: - py.test -s diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0517e76..32ad45b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -66,6 +66,8 @@ if (DOWNLOAD_GTEST OR GTEST_SRC_DIR) message(FATAL_ERROR "Build step for googletest failed: ${result}") endif() + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + # Add googletest directly to our build. This defines # the gtest and gtest_main targets. add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src From da9dbf8ef47db8cc42b7f97fef5db299fd73c72f Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 27 Nov 2020 10:44:07 +0100 Subject: [PATCH 036/102] Removed travis CI --- .travis.yml | 150 ------------------------------------------- README.md | 2 +- docs/environment.yml | 2 +- 3 files changed, 2 insertions(+), 152 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 48a7838..0000000 --- a/.travis.yml +++ /dev/null @@ -1,150 +0,0 @@ -language: cpp -dist: xenial -matrix: - include: - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.9 - env: COMPILER=gcc GCC=4.9 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-5 - env: COMPILER=gcc GCC=5 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-5 - env: COMPILER=gcc GCC=5 PY=2 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-6 - env: COMPILER=gcc GCC=6 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-7 - env: COMPILER=gcc GCC=7 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-xenial-4.0 - packages: - - g++-4.9 - - clang-4.0 - env: COMPILER=clang CLANG=4.0 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-xenial-5.0 - packages: - - g++-4.9 - - clang-5.0 - env: COMPILER=clang CLANG=5.0 PY=3 - - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-xenial-6.0 - packages: - - clang-6.0 - env: COMPILER=clang CLANG=6.0 PY=3 - - os: osx - osx_image: xcode8 - compiler: clang - env: PY=3 -env: - global: - - MINCONDA_VERSION="latest" - - MINCONDA_LINUX="Linux-x86_64" - - MINCONDA_OSX="MacOSX-x86_64" -before_install: - - | - # Configure build variables - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - if [[ "$COMPILER" == "gcc" ]]; then - export CXX=g++-$GCC CC=gcc-$GCC; - fi - if [[ "$COMPILER" == "clang" ]]; then - export CXX=clang++-$CLANG CC=clang-$CLANG; - fi - elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - export CXX=clang++ CC=clang PYTHONHOME=$HOME/miniconda; - fi - - PYBIND11_VERSION=${PYBIND11_VERSION:-2.4.3} - -install: - # Define the version of miniconda to download - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - MINCONDA_OS=$MINCONDA_LINUX; - cat /proc/cpuinfo; - elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then - MINCONDA_OS=$MINCONDA_OSX; - fi - - if [[ "$PY" == "3" ]]; then - wget "http://repo.continuum.io/miniconda/Miniconda3-$MINCONDA_VERSION-$MINCONDA_OS.sh" -O miniconda.sh; - PY_EXE=$HOME/miniconda/bin/python3.7; - else - wget "http://repo.continuum.io/miniconda/Miniconda2-$MINCONDA_VERSION-$MINCONDA_OS.sh" -O miniconda.sh; - PY_EXE=$HOME/miniconda/bin/python2.7; - fi - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - hash -r - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - # Useful for debugging any issues with conda - - conda info -a - - conda install pytest numpy -c conda-forge - - conda install cmake -c conda-forge - - | - if [[ "$PYBIND11_VERSION" == "master" ]]; then - conda_root=$(cd $(dirname $(which conda))/.. && pwd) - mkdir -p $conda_root/tmp - cd $conda_root/tmp - curl -sSL -o pybind11.tar.gz https://github.com/pybind/pybind11/archive/master.tar.gz - rm -rf pybind11-master - tar xf pybind11.tar.gz - cd pybind11-master - python setup.py install - mkdir -p build - cd build - cmake -DPYBIND11_TEST=OFF -DPYTHON_EXECUTABLE:FILEPATH=`which python` -DCMAKE_INSTALL_PREFIX=${conda_root} .. - make install - cd $TRAVIS_BUILD_DIR - else - conda install pybind11==${PYBIND11_VERSION} -c conda-forge - fi - - conda install xtensor==0.21.4 -c conda-forge - - cmake -D DOWNLOAD_GTEST=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda -D PYTHON_EXECUTABLE=$PY_EXE . - - make -j2 test_xtensor_python - - make install - - rm -rf test/googletest-src - -script: - - py.test -s - - cd test - - ./test_xtensor_python - diff --git a/README.md b/README.md index 5c40460..1b47652 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ![xtensor-python](docs/source/xtensor-python.svg) -[![Travis](https://travis-ci.org/xtensor-stack/xtensor-python.svg?branch=master)](https://travis-ci.org/xtensor-stack/xtensor-python) +[![Azure Pipelines](https://dev.azure.com/xtensor-stack/xtensor-stack/_apis/build/status/xtensor-stack.xtensor-python?branchName=master)](https://dev.azure.com/xtensor-stack/xtensor-stack/_build/latest?definitionId=7&branchName=master) [![Appveyor](https://ci.appveyor.com/api/projects/status/4j2yd6k8o5xbimqf?svg=true)](https://ci.appveyor.com/project/xtensor-stack/xtensor-python) [![Documentation](http://readthedocs.org/projects/xtensor-python/badge/?version=latest)](https://xtensor-python.readthedocs.io/en/latest/?badge=latest) [![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) diff --git a/docs/environment.yml b/docs/environment.yml index 727c481..47e93f7 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -1,7 +1,7 @@ name: xtensor-python-docs channels: - - QuantStack + - conda-forge dependencies: - breathe From fa97cf02716dc7c4b9c8665b9835b60e59a55951 Mon Sep 17 00:00:00 2001 From: Benjamin Perret Date: Sun, 22 Nov 2020 13:43:10 +0100 Subject: [PATCH 037/102] add pybind casters for strided_views, array_adaptor, and tensor_adaptor --- CMakeLists.txt | 19 +++--- include/xtensor-python/pyarray.hpp | 6 +- include/xtensor-python/pynative_casters.hpp | 52 ++++++++++++++ include/xtensor-python/pytensor.hpp | 6 +- .../xtensor_type_caster_base.hpp | 12 ++-- test_python/main.cpp | 56 ++++++++++++++++ test_python/test_pyarray.py | 67 +++++++++++++++++++ 7 files changed, 193 insertions(+), 25 deletions(-) create mode 100644 include/xtensor-python/pynative_casters.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 47cc4b1..b46ffde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,15 +62,16 @@ message(STATUS "Found numpy: ${NUMPY_INCLUDE_DIRS}") # ===== set(XTENSOR_PYTHON_HEADERS - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyarray.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyarray_backstrides.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pycontainer.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pystrides_adaptor.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pytensor.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyvectorize.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/xtensor_python_config.hpp - ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/xtensor_type_caster_base.hpp -) + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyarray.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyarray_backstrides.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pycontainer.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pynative_casters.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pystrides_adaptor.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pytensor.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/pyvectorize.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/xtensor_python_config.hpp + ${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/xtensor_type_caster_base.hpp + ) add_library(xtensor-python INTERFACE) target_include_directories(xtensor-python INTERFACE diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 0873399..ead92cc 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -21,6 +21,7 @@ #include "pyarray_backstrides.hpp" #include "pycontainer.hpp" #include "pystrides_adaptor.hpp" +#include "pynative_casters.hpp" #include "xtensor_type_caster_base.hpp" namespace xt @@ -91,11 +92,6 @@ namespace pybind11 } }; - // Type caster for casting xarray to ndarray - template - struct type_caster> : xtensor_type_caster_base> - { - }; } } diff --git a/include/xtensor-python/pynative_casters.hpp b/include/xtensor-python/pynative_casters.hpp new file mode 100644 index 0000000..f0f0065 --- /dev/null +++ b/include/xtensor-python/pynative_casters.hpp @@ -0,0 +1,52 @@ +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * +* * +* Distributed under the terms of the BSD 3-Clause License. * +* * +* The full license is in the file LICENSE, distributed with this software. * +****************************************************************************/ + +#ifndef PYNATIVE_CASTERS_HPP +#define PYNATIVE_CASTERS_HPP + +#include "xtensor_type_caster_base.hpp" + + +namespace pybind11 +{ + namespace detail + { + // Type caster for casting xarray to ndarray + template + struct type_caster> : xtensor_type_caster_base> + { + }; + + // Type caster for casting xt::xtensor to ndarray + template + struct type_caster> : xtensor_type_caster_base> + { + }; + + // Type caster for casting xt::xstrided_view to ndarray + template + struct type_caster> : xtensor_type_caster_base> + { + }; + + // Type caster for casting xt::xarray_adaptor to ndarray + template + struct type_caster> : xtensor_type_caster_base> + { + }; + + // Type caster for casting xt::xtensor_adaptor to ndarray + template + struct type_caster> : xtensor_type_caster_base> + { + }; + } +} + +#endif diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index 906bfff..736b4e1 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -21,6 +21,7 @@ #include "pycontainer.hpp" #include "pystrides_adaptor.hpp" +#include "pynative_casters.hpp" #include "xtensor_type_caster_base.hpp" namespace xt @@ -99,11 +100,6 @@ namespace pybind11 } }; - // Type caster for casting xt::xtensor to ndarray - template - struct type_caster> : xtensor_type_caster_base> - { - }; } } diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 4435dd8..bc84301 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -23,7 +23,7 @@ namespace pybind11 { namespace detail { - // Casts an xtensor (or xarray) type to numpy array.If given a base, + // Casts a strided expression type to numpy array.If given a base, // the numpy array references the src data, otherwise it'll make a copy. // The writeable attributes lets you specify writeable flag for the array. template @@ -39,7 +39,7 @@ namespace pybind11 std::vector python_shape(src.shape().size()); std::copy(src.shape().begin(), src.shape().end(), python_shape.begin()); - array a(python_shape, python_strides, src.begin(), base); + array a(python_shape, python_strides, &*(src.begin()), base); if (!writeable) { @@ -49,8 +49,8 @@ namespace pybind11 return a.release(); } - // Takes an lvalue ref to some xtensor (or xarray) type and a (python) base object, creating a numpy array that - // reference the xtensor object's data with `base` as the python-registered base class (if omitted, + // Takes an lvalue ref to some strided expression type and a (python) base object, creating a numpy array that + // reference the expression object's data with `base` as the python-registered base class (if omitted, // the base will be set to None, and lifetime management is up to the caller). The numpy array is // non-writeable if the given type is const. template @@ -59,7 +59,7 @@ namespace pybind11 return xtensor_array_cast(src, parent, !std::is_const::value); } - // Takes a pointer to xtensor (or xarray), builds a capsule around it, then returns a numpy + // Takes a pointer to a strided expression, builds a capsule around it, then returns a numpy // array that references the encapsulated data with a python-side reference to the capsule to tie // its destruction to that of any dependent python objects. Const-ness is determined by whether or // not the CType of the pointer given is const. @@ -70,7 +70,7 @@ namespace pybind11 return xtensor_ref_array(*src, base); } - // Base class of type_caster for xtensor and xarray + // Base class of type_caster for strided expressions template struct xtensor_type_caster_base { diff --git a/test_python/main.cpp b/test_python/main.cpp index 6145e76..b4b6cc6 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -15,6 +15,8 @@ #include "xtensor-python/pyarray.hpp" #include "xtensor-python/pytensor.hpp" #include "xtensor-python/pyvectorize.hpp" +#include "xtensor/xadapt.hpp" +#include "xtensor/xstrided_view.hpp" namespace py = pybind11; using complex_t = std::complex; @@ -133,6 +135,49 @@ class C array_type m_array; }; +struct test_native_casters +{ + using array_type = xt::xarray; + array_type a = xt::ones({50, 50}); + + const auto & get_array() + { + return a; + } + + auto get_strided_view() + { + return xt::strided_view(a, {xt::range(0, 1), xt::range(0, 3, 2)}); + } + + auto get_array_adapter() + { + using shape_type = std::vector; + shape_type shape = {2, 2}; + shape_type stride = {3, 2}; + return xt::adapt(a.data(), 4, xt::no_ownership(), shape, stride); + } + + auto get_tensor_adapter() + { + using shape_type = std::array; + shape_type shape = {2, 2}; + shape_type stride = {3, 2}; + return xt::adapt(a.data(), 4, xt::no_ownership(), shape, stride); + } + + auto get_owning_array_adapter() + { + size_t size = 100; + int * data = new int[size]; + std::fill(data, data + size, 1); + + using shape_type = std::vector; + shape_type shape = {size}; + return xt::adapt(std::move(data), size, xt::acquire_ownership(), shape); + } +}; + xt::pyarray dtype_to_python() { A a1{123, 321, 'a', {1, 2, 3}}; @@ -257,4 +302,15 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("diff_shape_overload", [](xt::pytensor a) { return 1; }); m.def("diff_shape_overload", [](xt::pytensor a) { return 2; }); + + py::class_(m, "test_native_casters") + .def(py::init<>()) + .def("get_array", &test_native_casters::get_array, py::return_value_policy::reference_internal) // memory managed by the class instance + .def("get_strided_view", &test_native_casters::get_strided_view, py::keep_alive<0, 1>()) // keep_alive<0, 1>() => do not free "self" before the returned view + .def("get_array_adapter", &test_native_casters::get_array_adapter, py::keep_alive<0, 1>()) // keep_alive<0, 1>() => do not free "self" before the returned adapter + .def("get_tensor_adapter", &test_native_casters::get_tensor_adapter, py::keep_alive<0, 1>()) // keep_alive<0, 1>() => do not free "self" before the returned adapter + .def("get_owning_array_adapter", &test_native_casters::get_owning_array_adapter) // auto memory management as the adapter owns its memory + .def("view_keep_alive_member_function", [](test_native_casters & self, xt::pyarray & a) // keep_alive<0, 2>() => do not free second parameter before the returned view + {return xt::reshape_view(a, {a.size(), });}, + py::keep_alive<0, 2>()); } diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index cdc215c..c3c1447 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -166,6 +166,73 @@ def test_diff_shape_overload(self): # FIXME: the TypeError information is not informative xt.diff_shape_overload(np.ones((2, 2, 2))) + def test_native_casters(self): + import gc + + # check keep alive policy for get_strided_view() + gc.collect() + obj = xt.test_native_casters() + a = obj.get_strided_view() + obj = None + gc.collect() + _ = np.zeros((100, 100)) + self.assertEqual(a.sum(), a.size) + + # check keep alive policy for get_array_adapter() + gc.collect() + obj = xt.test_native_casters() + a = obj.get_array_adapter() + obj = None + gc.collect() + _ = np.zeros((100, 100)) + self.assertEqual(a.sum(), a.size) + + # check keep alive policy for get_array_adapter() + gc.collect() + obj = xt.test_native_casters() + a = obj.get_tensor_adapter() + obj = None + gc.collect() + _ = np.zeros((100, 100)) + self.assertEqual(a.sum(), a.size) + + # check keep alive policy for get_owning_array_adapter() + gc.collect() + obj = xt.test_native_casters() + a = obj.get_owning_array_adapter() + gc.collect() + _ = np.zeros((100, 100)) + self.assertEqual(a.sum(), a.size) + + # check keep alive policy for view_keep_alive_member_function() + gc.collect() + a = np.ones((100, 100)) + b = obj.view_keep_alive_member_function(a) + obj = None + a = None + gc.collect() + _ = np.zeros((100, 100)) + self.assertEqual(b.sum(), b.size) + + # check shared buffer (insure that no copy is done) + obj = xt.test_native_casters() + arr = obj.get_array() + + strided_view = obj.get_strided_view() + strided_view[0, 1] = -1 + self.assertEqual(strided_view.shape, (1, 2)) + self.assertEqual(arr[0, 2], -1) + + adapter = obj.get_array_adapter() + self.assertEqual(adapter.shape, (2, 2)) + adapter[1, 1] = -2 + self.assertEqual(arr[0, 5], -2) + + adapter = obj.get_tensor_adapter() + self.assertEqual(adapter.shape, (2, 2)) + adapter[1, 1] = -3 + self.assertEqual(arr[0, 5], -3) + class AttributeTest(TestCase): From c34ba55c12166874ebccfec663191b51596fe080 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Wed, 20 Jan 2021 18:08:36 +0100 Subject: [PATCH 038/102] Upgraded to xtensor 0.22.0 --- .appveyor.yml | 2 +- README.md | 2 +- environment-dev.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 628cba0..7f06086 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.21.4 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.22.0 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - nmake test_xtensor_python diff --git a/README.md b/README.md index 1b47652..9d0fac7 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.21.2 | ~2.4.3 | +| master | ^0.22.0 | ~2.4.3 | | 0.24.1 | ^0.21.2 | ~2.4.3 | | 0.24.0 | ^0.21.1 | ~2.4.3 | | 0.23.2 | ^0.20.10 | ~2.4.3 | diff --git a/environment-dev.yml b/environment-dev.yml index 38554ed..b9da7c6 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -5,7 +5,7 @@ dependencies: # Build dependencies - cmake # Host dependencies - - xtensor=0.21.4 + - xtensor=0.22.0 - numpy - pybind11=2.4.3 # Test dependencies From 12d20163030250a0068e7b668e36e1f77ff08731 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 22 Jan 2021 11:46:01 +0100 Subject: [PATCH 039/102] Upgraded to xtensor 0.23.0 --- .appveyor.yml | 2 +- README.md | 2 +- environment-dev.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7f06086..c7f2b5c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.22.0 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.23.0 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - nmake test_xtensor_python diff --git a/README.md b/README.md index 9d0fac7..f39aa94 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.22.0 | ~2.4.3 | +| master | ^0.23.0 | ~2.4.3 | | 0.24.1 | ^0.21.2 | ~2.4.3 | | 0.24.0 | ^0.21.1 | ~2.4.3 | | 0.23.2 | ^0.20.10 | ~2.4.3 | diff --git a/environment-dev.yml b/environment-dev.yml index b9da7c6..28285b4 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -5,7 +5,7 @@ dependencies: # Build dependencies - cmake # Host dependencies - - xtensor=0.22.0 + - xtensor=0.23.0 - numpy - pybind11=2.4.3 # Test dependencies From 9308c8f9a1045e8bdcf26870b2139ff466cef102 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 22 Jan 2021 11:59:11 +0100 Subject: [PATCH 040/102] Release 0.25.0 --- README.md | 1 + include/xtensor-python/xtensor_python_config.hpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f39aa94..201d791 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| | master | ^0.23.0 | ~2.4.3 | +| 0.25.0 | ^0.23.0 | ~2.4.3 | | 0.24.1 | ^0.21.2 | ~2.4.3 | | 0.24.0 | ^0.21.1 | ~2.4.3 | | 0.23.2 | ^0.20.10 | ~2.4.3 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 37a1b97..0937841 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -11,7 +11,7 @@ #define XTENSOR_PYTHON_CONFIG_HPP #define XTENSOR_PYTHON_VERSION_MAJOR 0 -#define XTENSOR_PYTHON_VERSION_MINOR 24 -#define XTENSOR_PYTHON_VERSION_PATCH 1 +#define XTENSOR_PYTHON_VERSION_MINOR 25 +#define XTENSOR_PYTHON_VERSION_PATCH 0 #endif From 478a91adb17cbdac88d190e56b8645e8014e7d04 Mon Sep 17 00:00:00 2001 From: Adrien DELSALLE Date: Fri, 29 Jan 2021 19:04:52 +0100 Subject: [PATCH 041/102] fix pyarray column_major from xexpression --- include/xtensor-python/pyarray.hpp | 2 +- test/test_pyarray.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index ead92cc..f74ff36 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -443,7 +443,7 @@ namespace xt // TODO: prevent intermediary shape allocation shape_type shape = xtl::forward_sequence(e.derived_cast().shape()); strides_type strides = xtl::make_sequence(shape.size(), size_type(0)); - compute_strides(shape, layout_type::row_major, strides); + compute_strides(shape, L, strides); init_array(shape, strides); semantic_base::assign(e); } diff --git a/test/test_pyarray.cpp b/test/test_pyarray.cpp index b9356cc..03085b5 100644 --- a/test/test_pyarray.cpp +++ b/test/test_pyarray.cpp @@ -181,6 +181,18 @@ namespace xt EXPECT_EQ(c(0, 1), a1(0, 1) + a2(0, 1)); EXPECT_EQ(c(1, 0), a1(1, 0) + a2(1, 0)); EXPECT_EQ(c(1, 1), a1(1, 1) + a2(1, 1)); + + pyarray d = a1 + a2; + EXPECT_EQ(d(0, 0), a1(0, 0) + a2(0, 0)); + EXPECT_EQ(d(0, 1), a1(0, 1) + a2(0, 1)); + EXPECT_EQ(d(1, 0), a1(1, 0) + a2(1, 0)); + EXPECT_EQ(d(1, 1), a1(1, 1) + a2(1, 1)); + + pyarray e = a1 + a2; + EXPECT_EQ(e(0, 0), a1(0, 0) + a2(0, 0)); + EXPECT_EQ(e(0, 1), a1(0, 1) + a2(0, 1)); + EXPECT_EQ(e(1, 0), a1(1, 0) + a2(1, 0)); + EXPECT_EQ(e(1, 1), a1(1, 1) + a2(1, 1)); } TEST(pyarray, resize) From 66b81ae02a7b7f5abce780d7b79267c6791f6823 Mon Sep 17 00:00:00 2001 From: Adrien DELSALLE Date: Mon, 1 Feb 2021 10:22:51 +0100 Subject: [PATCH 042/102] make initializer lists work with all layouts init lists use row_major layout as default make xexpression copy constructor also use row_major add tests --- include/xtensor-python/pyarray.hpp | 34 +++++++++++++++++++---------- test/test_pyarray.cpp | 35 ++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 16 deletions(-) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index f74ff36..bd25c85 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -224,6 +224,8 @@ namespace xt storage_type& storage_impl() noexcept; const storage_type& storage_impl() const noexcept; + layout_type default_dynamic_layout(); + friend class xcontainer>; friend class pycontainer>; }; @@ -254,7 +256,7 @@ namespace xt inline pyarray::pyarray(const value_type& t) : base_type() { - base_type::resize(xt::shape(t), layout_type::row_major); + base_type::resize(xt::shape(t), default_dynamic_layout()); nested_copy(m_storage.begin(), t); } @@ -262,40 +264,40 @@ namespace xt inline pyarray::pyarray(nested_initializer_list_t t) : base_type() { - base_type::resize(xt::shape(t), layout_type::row_major); - nested_copy(m_storage.begin(), t); + base_type::resize(xt::shape(t), default_dynamic_layout()); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin(), t); } template inline pyarray::pyarray(nested_initializer_list_t t) : base_type() { - base_type::resize(xt::shape(t), layout_type::row_major); - nested_copy(m_storage.begin(), t); + base_type::resize(xt::shape(t), default_dynamic_layout()); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin(), t); } template inline pyarray::pyarray(nested_initializer_list_t t) : base_type() { - base_type::resize(xt::shape(t), layout_type::row_major); - nested_copy(m_storage.begin(), t); + base_type::resize(xt::shape(t), default_dynamic_layout()); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin(), t); } template inline pyarray::pyarray(nested_initializer_list_t t) : base_type() { - base_type::resize(xt::shape(t), layout_type::row_major); - nested_copy(m_storage.begin(), t); + base_type::resize(xt::shape(t), default_dynamic_layout()); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin(), t); } template inline pyarray::pyarray(nested_initializer_list_t t) : base_type() { - base_type::resize(xt::shape(t), layout_type::row_major); - nested_copy(m_storage.begin(), t); + base_type::resize(xt::shape(t), default_dynamic_layout()); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) : nested_copy(this->template begin(), t); } template @@ -443,7 +445,9 @@ namespace xt // TODO: prevent intermediary shape allocation shape_type shape = xtl::forward_sequence(e.derived_cast().shape()); strides_type strides = xtl::make_sequence(shape.size(), size_type(0)); - compute_strides(shape, L, strides); + layout_type layout = default_dynamic_layout(); + + compute_strides(shape, layout, strides); init_array(shape, strides); semantic_base::assign(e); } @@ -559,6 +563,12 @@ namespace xt { return m_storage; } + + template + layout_type pyarray::default_dynamic_layout() + { + return L == layout_type::dynamic ? layout_type::row_major : L; + } } #endif diff --git a/test/test_pyarray.cpp b/test/test_pyarray.cpp index 03085b5..3f509e3 100644 --- a/test/test_pyarray.cpp +++ b/test/test_pyarray.cpp @@ -37,7 +37,7 @@ namespace xt TEST(pyarray, initializer_constructor) { - pyarray t + pyarray r {{{ 0, 1, 2}, { 3, 4, 5}, { 6, 7, 8}}, @@ -45,9 +45,36 @@ namespace xt {12, 13, 14}, {15, 16, 17}}}; - EXPECT_EQ(t.dimension(), 3); - EXPECT_EQ(t(0, 0, 1), 1); - EXPECT_EQ(t.shape()[0], 2); + EXPECT_EQ(r.layout(), xt::layout_type::row_major); + EXPECT_EQ(r.dimension(), 3); + EXPECT_EQ(r(0, 0, 1), 1); + EXPECT_EQ(r.shape()[0], 2); + + pyarray c + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; + + EXPECT_EQ(c.layout(), xt::layout_type::column_major); + EXPECT_EQ(c.dimension(), 3); + EXPECT_EQ(c(0, 0, 1), 1); + EXPECT_EQ(c.shape()[0], 2); + + pyarray d + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; + + EXPECT_EQ(d.layout(), xt::layout_type::row_major); + EXPECT_EQ(d.dimension(), 3); + EXPECT_EQ(d(0, 0, 1), 1); + EXPECT_EQ(d.shape()[0], 2); } TEST(pyarray, shaped_constructor) From 54ca763246f9384325201b9e6693fea797dc5129 Mon Sep 17 00:00:00 2001 From: Adrien DELSALLE Date: Mon, 1 Feb 2021 10:30:11 +0100 Subject: [PATCH 043/102] test pyarray assign traits --- test/CMakeLists.txt | 1 + test/test_pyarray_traits.cpp | 145 +++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 test/test_pyarray_traits.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 32ad45b..b53ac18 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -86,6 +86,7 @@ include_directories(${GTEST_INCLUDE_DIRS}) set(XTENSOR_PYTHON_TESTS main.cpp test_pyarray.cpp + test_pyarray_traits.cpp test_pytensor.cpp test_pyvectorize.cpp ) diff --git a/test/test_pyarray_traits.cpp b/test/test_pyarray_traits.cpp new file mode 100644 index 0000000..a90b460 --- /dev/null +++ b/test/test_pyarray_traits.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * +* * +* Distributed under the terms of the BSD 3-Clause License. * +* * +* The full license is in the file LICENSE, distributed with this software. * +****************************************************************************/ + +#include "gtest/gtest.h" + +#include "xtensor-python/pyarray.hpp" + + + +namespace xt +{ + namespace testing + { + class pyarray_traits: public ::testing::Test + { + protected: + + using dynamic_type = xt::pyarray; + using row_major_type = xt::pyarray; + using column_major_type = xt::pyarray; + + dynamic_type d1 = {{0., 1.}, {0., 10.}, {0., 100.}}; + dynamic_type d2 = {{0., 2.}, {0., 20.}, {0., 200.}}; + + row_major_type r1 = {{0., 1.}, {0., 10.}, {0., 100.}}; + row_major_type r2 = {{0., 2.}, {0., 20.}, {0., 200.}}; + + column_major_type c1 = {{0., 1.}, {0., 10.}, {0., 100.}}; + column_major_type c2 = {{0., 2.}, {0., 20.}, {0., 200.}}; + + template + bool test_has_strides(T const&) + { + return xt::has_strides::value; + } + + template + xt::layout_type test_result_layout(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return (tmp1 + tmp2).layout(); + } + + template + bool test_linear_assign(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + T res = tmp1 + tmp2; + return xt::xassign_traits::linear_assign(res, tmp1 + tmp2, true); + } + + template + bool test_simd_linear_assign(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return xt::xassign_traits::simd_linear_assign(); + } + + template + bool test_linear_static_layout(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return xt::detail::linear_static_layout(); + } + + template + bool test_contiguous_layout(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return decltype(tmp1)::contiguous_layout && decltype(tmp2)::contiguous_layout; + } + }; + + TEST_F(pyarray_traits, result_layout) + { + EXPECT_TRUE(d1.layout() == layout_type::row_major); + EXPECT_TRUE(test_result_layout(d1, d2) == layout_type::row_major); + + EXPECT_TRUE(r1.layout() == layout_type::row_major); + EXPECT_TRUE(test_result_layout(r1, r2) == layout_type::row_major); + + EXPECT_TRUE(c1.layout() == layout_type::column_major); + EXPECT_TRUE(test_result_layout(c1, c2) == layout_type::column_major); + } + + TEST_F(pyarray_traits, has_strides) + { + EXPECT_TRUE(test_has_strides(d1)); + EXPECT_TRUE(test_has_strides(r1)); + EXPECT_TRUE(test_has_strides(c1)); + } + + TEST_F(pyarray_traits, has_linear_assign) + { + EXPECT_TRUE(d2.has_linear_assign(d1.strides())); + EXPECT_TRUE(r2.has_linear_assign(r1.strides())); + EXPECT_TRUE(c2.has_linear_assign(c1.strides())); + } + + TEST_F(pyarray_traits, linear_assign) + { + EXPECT_TRUE(test_linear_assign(d1, d2)); + EXPECT_TRUE(test_linear_assign(r1, r2)); + EXPECT_TRUE(test_linear_assign(c1, c2)); + } + + TEST_F(pyarray_traits, simd_linear_assign) + { +#ifdef XTENSOR_USE_XSIMD + EXPECT_FALSE(test_simd_linear_assign(d1, d2)); + EXPECT_TRUE(test_simd_linear_assign(r1, r2)); + EXPECT_TRUE(test_simd_linear_assign(c1, c2)); +#else + EXPECT_FALSE(test_simd_linear_assign(d1, d2)); + EXPECT_FALSE(test_simd_linear_assign(r1, r2)); + EXPECT_FALSE(test_simd_linear_assign(c1, c2)); +#endif + } + + TEST_F(pyarray_traits, linear_static_layout) + { + EXPECT_FALSE(test_linear_static_layout(d1, d2)); + EXPECT_TRUE(test_linear_static_layout(r1, r2)); + EXPECT_TRUE(test_linear_static_layout(c1, c2)); + } + + TEST_F(pyarray_traits, contiguous_layout) + { + EXPECT_FALSE(test_contiguous_layout(d1, d2)); + EXPECT_TRUE(test_contiguous_layout(r1, r2)); + EXPECT_TRUE(test_contiguous_layout(c1, c2)); + } + } +} From 63d083a9b63bee12e3b9e2160cc853abd91dcb4c Mon Sep 17 00:00:00 2001 From: Adrien DELSALLE Date: Mon, 1 Feb 2021 17:40:54 +0100 Subject: [PATCH 044/102] test both static and dynamic simd linear assign --- test/test_pyarray_traits.cpp | 37 ++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/test/test_pyarray_traits.cpp b/test/test_pyarray_traits.cpp index a90b460..fe9ef6a 100644 --- a/test/test_pyarray_traits.cpp +++ b/test/test_pyarray_traits.cpp @@ -58,13 +58,21 @@ namespace xt } template - bool test_simd_linear_assign(T const& a1, T const& a2) + bool test_static_simd_linear_assign(T const& a1, T const& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); return xt::xassign_traits::simd_linear_assign(); } + template + bool test_dynamic_simd_linear_assign(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return xt::xassign_traits::simd_linear_assign(a1, tmp2); + } + template bool test_linear_static_layout(T const& a1, T const& a2) { @@ -115,16 +123,29 @@ namespace xt EXPECT_TRUE(test_linear_assign(c1, c2)); } - TEST_F(pyarray_traits, simd_linear_assign) + TEST_F(pyarray_traits, static_simd_linear_assign) + { +#ifdef XTENSOR_USE_XSIMD + EXPECT_FALSE(test_static_simd_linear_assign(d1, d2)); + EXPECT_TRUE(test_static_simd_linear_assign(r1, r2)); + EXPECT_TRUE(test_static_simd_linear_assign(c1, c2)); +#else + EXPECT_FALSE(test_static_simd_linear_assign(d1, d2)); + EXPECT_FALSE(test_static_simd_linear_assign(r1, r2)); + EXPECT_FALSE(test_static_simd_linear_assign(c1, c2)); +#endif + } + + TEST_F(pyarray_traits, dynamic_simd_linear_assign) { #ifdef XTENSOR_USE_XSIMD - EXPECT_FALSE(test_simd_linear_assign(d1, d2)); - EXPECT_TRUE(test_simd_linear_assign(r1, r2)); - EXPECT_TRUE(test_simd_linear_assign(c1, c2)); + EXPECT_TRUE(test_dynamic_simd_linear_assign(d1, d2)); + EXPECT_TRUE(test_dynamic_simd_linear_assign(r1, r2)); + EXPECT_TRUE(test_dynamic_simd_linear_assign(c1, c2)); #else - EXPECT_FALSE(test_simd_linear_assign(d1, d2)); - EXPECT_FALSE(test_simd_linear_assign(r1, r2)); - EXPECT_FALSE(test_simd_linear_assign(c1, c2)); + EXPECT_FALSE(test_dynamic_simd_linear_assign(d1, d2)); + EXPECT_FALSE(test_dynamic_simd_linear_assign(r1, r2)); + EXPECT_FALSE(test_dynamic_simd_linear_assign(c1, c2)); #endif } From cfa68cb6fcd1f16f634de64e05e5cfcd804d4412 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Tue, 9 Feb 2021 19:13:45 +0100 Subject: [PATCH 045/102] Release 0.25.1 --- README.md | 1 + include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 201d791..8ecac75 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| | master | ^0.23.0 | ~2.4.3 | +| 0.25.1 | ^0.23.0 | ~2.4.3 | | 0.25.0 | ^0.23.0 | ~2.4.3 | | 0.24.1 | ^0.21.2 | ~2.4.3 | | 0.24.0 | ^0.21.1 | ~2.4.3 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 0937841..71998fb 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -12,6 +12,6 @@ #define XTENSOR_PYTHON_VERSION_MAJOR 0 #define XTENSOR_PYTHON_VERSION_MINOR 25 -#define XTENSOR_PYTHON_VERSION_PATCH 0 +#define XTENSOR_PYTHON_VERSION_PATCH 1 #endif From 895e5b6f358c1c9c83cd7c2c0bc8cd762c88d84e Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Tue, 13 Apr 2021 20:48:18 +0200 Subject: [PATCH 046/102] Update installation instructions --- README.md | 4 ++-- docs/source/installation.rst | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8ecac75..43a4e92 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,10 @@ The Python bindings for `xtensor` are based on the [pybind11](https://github.com ## Installation -`xtensor-python` is a header-only library. We provide a package for the conda package manager. +`xtensor-python` is a header-only library. We provide a package for the mamba (or conda) package manager. ```bash -conda install -c conda-forge xtensor-python +mamba install -c conda-forge xtensor-python ``` ## Documentation diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 2965712..2db1f71 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -27,14 +27,14 @@ Besides the xtendor-python headers, all these methods place the `cmake` project .. image:: conda.svg -Using the conda package ------------------------ +Using the conda-fore package +---------------------------- -A package for xtensor-python is available on the conda package manager. +A package for xtensor-python is available on the mamba (or conda) package manager. .. code:: - conda install -c conda-forge xtensor-python + mamba install -c conda-forge xtensor-python .. image:: debian.svg From 188caf37531b4906aa09f83b26cdfe70f4796249 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Tue, 18 May 2021 15:20:02 +0200 Subject: [PATCH 047/102] Change `#include "..."` to `#include <...>` in readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 43a4e92..bb1ea73 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,10 @@ Both containers enable the numpy-style APIs of xtensor (see [the numpy to xtenso ```cpp #include // Standard library import for std::accumulate -#include "pybind11/pybind11.h" // Pybind11 import to define Python bindings -#include "xtensor/xmath.hpp" // xtensor import for the C++ universal functions +#include // Pybind11 import to define Python bindings +#include // xtensor import for the C++ universal functions #define FORCE_IMPORT_ARRAY -#include "xtensor-python/pyarray.hpp" // Numpy bindings +#include // Numpy bindings double sum_of_sines(xt::pyarray& m) { @@ -91,9 +91,9 @@ s **C++ code** ```cpp -#include "pybind11/pybind11.h" +#include #define FORCE_IMPORT_ARRAY -#include "xtensor-python/pyvectorize.hpp" +#include #include #include From b098ad447db705e4d0101dc6ec66627626b75b8c Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Tue, 18 May 2021 18:24:23 +0200 Subject: [PATCH 048/102] Fixing CI: explicitly installing requested gcc version --- .azure-pipelines/azure-pipelines-linux-gcc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/azure-pipelines-linux-gcc.yml b/.azure-pipelines/azure-pipelines-linux-gcc.yml index bf18b99..7b1eb9d 100644 --- a/.azure-pipelines/azure-pipelines-linux-gcc.yml +++ b/.azure-pipelines/azure-pipelines-linux-gcc.yml @@ -23,13 +23,13 @@ jobs: steps: - script: | - if [[ $(gcc_version) == '4.9' || $(gcc_version) == '6' ]]; then + if [[ $(gcc_version) == '4.9' || $(gcc_version) == '6' || $(gcc_version) == '7' || $(gcc_version) == '8' ]]; then sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get --no-install-suggests --no-install-recommends install g++-$(gcc_version) fi displayName: Install build toolchain - + - bash: echo "##vso[task.prependpath]$CONDA/bin" displayName: Add conda to PATH From 705e91200aabfd2d3b0c8f0af1a5784362db1a31 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Tue, 18 May 2021 18:43:02 +0200 Subject: [PATCH 049/102] Fixing warning --- include/xtensor-python/xtensor_type_caster_base.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index bc84301..3c8a015 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -74,7 +74,7 @@ namespace pybind11 template struct xtensor_type_caster_base { - bool load(handle src, bool) + bool load(handle /*src*/, bool) { return false; } From 1be71a741043f4cf4c32dd5593325ea51c8b8cc5 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Tue, 8 Sep 2020 15:32:55 +0200 Subject: [PATCH 050/102] Adding rank member --- include/xtensor-python/pyarray.hpp | 3 +- include/xtensor-python/pytensor.hpp | 3 +- test/CMakeLists.txt | 1 + test/test_sfinae.cpp | 53 +++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 test/test_sfinae.cpp diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 0873399..79de0b5 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -158,6 +158,7 @@ namespace xt using inner_shape_type = typename base_type::inner_shape_type; using inner_strides_type = typename base_type::inner_strides_type; using inner_backstrides_type = typename base_type::inner_backstrides_type; + constexpr static std::size_t rank = SIZE_MAX; pyarray(); pyarray(const value_type& t); @@ -514,7 +515,7 @@ namespace xt { return; } - + m_shape = inner_shape_type(reinterpret_cast(PyArray_SHAPE(this->python_array())), static_cast(PyArray_NDIM(this->python_array()))); m_strides = inner_strides_type(reinterpret_cast(PyArray_STRIDES(this->python_array())), diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index 906bfff..1dc9e31 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -168,6 +168,7 @@ namespace xt using inner_shape_type = typename base_type::inner_shape_type; using inner_strides_type = typename base_type::inner_strides_type; using inner_backstrides_type = typename base_type::inner_backstrides_type; + constexpr static std::size_t rank = N; pytensor(); pytensor(nested_initializer_list_t t); @@ -471,7 +472,7 @@ namespace xt { return; } - + if (PyArray_NDIM(this->python_array()) != N) { throw std::runtime_error("NumPy: ndarray has incorrect number of dimensions"); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0517e76..7174802 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -86,6 +86,7 @@ set(XTENSOR_PYTHON_TESTS test_pyarray.cpp test_pytensor.cpp test_pyvectorize.cpp + test_sfinae.cpp ) add_executable(test_xtensor_python ${XTENSOR_PYTHON_TESTS} ${XTENSOR_PYTHON_HEADERS}) diff --git a/test/test_sfinae.cpp b/test/test_sfinae.cpp new file mode 100644 index 0000000..a614485 --- /dev/null +++ b/test/test_sfinae.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* Copyright (c) QuantStack * +* * +* Distributed under the terms of the BSD 3-Clause License. * +* * +* The full license is in the file LICENSE, distributed with this software. * +****************************************************************************/ + +#include + +#include "gtest/gtest.h" +#include "xtensor-python/pytensor.hpp" +#include "xtensor-python/pyarray.hpp" +#include "xtensor/xarray.hpp" +#include "xtensor/xtensor.hpp" + +namespace xt +{ + template ::value, int> = 0> + inline bool sfinae_has_fixed_rank(E&&) + { + return false; + } + + template ::value, int> = 0> + inline bool sfinae_has_fixed_rank(E&&) + { + return true; + } + + TEST(sfinae, fixed_rank) + { + xt::pyarray a = {{9, 9, 9}, {9, 9, 9}}; + xt::pytensor b = {9, 9}; + xt::pytensor c = {{9, 9}, {9, 9}}; + + EXPECT_TRUE(sfinae_has_fixed_rank(a) == false); + EXPECT_TRUE(sfinae_has_fixed_rank(b) == true); + EXPECT_TRUE(sfinae_has_fixed_rank(c) == true); + } + + TEST(sfinae, get_rank) + { + xt::pytensor A = xt::zeros({2}); + xt::pytensor B = xt::zeros({2, 2}); + xt::pyarray C = xt::zeros({2, 2}); + + EXPECT_TRUE(xt::get_rank::value == 1ul); + EXPECT_TRUE(xt::get_rank::value == 2ul); + EXPECT_TRUE(xt::get_rank::value == SIZE_MAX); + } +} From f4dc5e3187cb3c43b88340edef968b3a8fa85b16 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Tue, 18 May 2021 15:20:19 +0200 Subject: [PATCH 051/102] Add CMake examples --- .azure-pipelines/unix-build.yml | 21 +++- README.md | 12 ++- docs/source/examples.rst | 100 ++++++++++++++++++ .../examples/readme_example_1/CMakeLists.txt | 13 +++ .../examples/readme_example_1/example.py | 6 ++ .../source/examples/readme_example_1/main.cpp | 18 ++++ docs/source/examples/sfinae/CMakeLists.txt | 16 +++ docs/source/examples/sfinae/example.py | 8 ++ docs/source/examples/sfinae/main.cpp | 10 ++ docs/source/examples/sfinae/mymodule.hpp | 32 ++++++ docs/source/examples/sfinae/python.cpp | 11 ++ docs/source/index.rst | 9 +- 12 files changed, 248 insertions(+), 8 deletions(-) create mode 100644 docs/source/examples.rst create mode 100644 docs/source/examples/readme_example_1/CMakeLists.txt create mode 100644 docs/source/examples/readme_example_1/example.py create mode 100644 docs/source/examples/readme_example_1/main.cpp create mode 100644 docs/source/examples/sfinae/CMakeLists.txt create mode 100644 docs/source/examples/sfinae/example.py create mode 100644 docs/source/examples/sfinae/main.cpp create mode 100644 docs/source/examples/sfinae/mymodule.hpp create mode 100644 docs/source/examples/sfinae/python.cpp diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index 81320c0..d01651c 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -11,15 +11,16 @@ steps: mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory) + make install displayName: Configure xtensor-python workingDirectory: $(Build.BinariesDirectory) - + - script: | source activate xtensor-python make -j2 test_xtensor_python displayName: Build xtensor-python workingDirectory: $(Build.BinariesDirectory)/build - + - script: | source activate xtensor-python cd test @@ -32,3 +33,19 @@ steps: py.test -s displayName: Test xtensor-python (Python) workingDirectory: $(Build.SourcesDirectory) + + - script: | + source activate xtensor-python + cmake . -DPYTHON_EXECUTABLE=`which python` + cmake --build . + python example.py + displayName: Example - readme 1 + workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1 + + - script: | + source activate xtensor-python + cmake . -DPYTHON_EXECUTABLE=`which python` + cmake --build . + python example.py + displayName: Example - SFINAE + workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/sfinae diff --git a/README.md b/README.md index bb1ea73..c8cc92a 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ import xtensor_python_test as xt v = np.arange(15).reshape(3, 5) s = xt.sum_of_sines(v) -s +print(s) ``` **Outputs** @@ -86,6 +86,14 @@ s 1.2853996391883833 ``` +**Working example** + +Get the working example here: + +* [`CMakeLists.txt`](docs/source/examples/readme_example_1/CMakeLists.txt) +* [`main.cpp`](docs/source/examples/readme_example_1/main.cpp) +* [`example.py`](docs/source/examples/readme_example_1/example.py) + ### Example 2: Create a universal function from a C++ scalar function **C++ code** @@ -122,7 +130,7 @@ import xtensor_python_test as xt x = np.arange(15).reshape(3, 5) y = [1, 2, 3, 4, 5] z = xt.vectorized_func(x, y) -z +print(z) ``` **Outputs** diff --git a/docs/source/examples.rst b/docs/source/examples.rst new file mode 100644 index 0000000..4788b8b --- /dev/null +++ b/docs/source/examples.rst @@ -0,0 +1,100 @@ + +**************** +(CMake) Examples +**************** + +Basic example (from readme) +=========================== + +Consider the following C++ code: + +:download:`main.cpp ` + +.. literalinclude:: examples/readme_example_1/main.cpp + :language: cpp + +There are several options to build the module, +whereby we will CMake here with the following ``CMakeLists.txt``: + +:download:`CMakeLists.txt ` + +.. literalinclude:: examples/readme_example_1/CMakeLists.txt + :language: cmake + +Then we can test the module: + +:download:`example.py ` + +.. literalinclude:: examples/readme_example_1/example.py + :language: cmake + +.. note:: + + Since we did not install the module, + we should compile and run the example from the same folder. + To install, please consult + `this pybind11 / CMake example `_. + + +Type restriction with SFINAE +============================ + +.. seealso:: + + `Medium post by Johan Mabille `__ + This example covers "Option 4". + +In this example we will design a module with a function that accepts an ``xt::xtensor`` as argument, +but in such a way that an ``xt::pyxtensor`` can be accepted in the Python module. +This is done by having a templated function + +.. code-block:: cpp + + template + void times_dimension(T& t); + +As this might be a bit too permissive for your liking, we will show you how to limit the +scope to *xtensor* types, and allow other overloads using the principle of SFINAE +(Substitution Failure Is Not An Error). +In particular: + +:download:`mymodule.hpp ` + +.. literalinclude:: examples/sfinae/mymodule.hpp + :language: cpp + +Consequently from C++, the interaction with the module's function is trivial + +:download:`main.cpp ` + +.. literalinclude:: examples/sfinae/main.cpp + :language: cpp + +For the Python module we just have to specify the template to be +``xt::pyarray`` or ``xt::pytensor``. E.g. + +:download:`src/python.cpp ` + +.. literalinclude:: examples/sfinae/python.cpp + :language: cpp + +We will again use CMake to compile, with the following ``CMakeLists.txt``: + +:download:`CMakeLists.txt ` + +.. literalinclude:: examples/sfinae/CMakeLists.txt + :language: cmake + +Then we can test the module: + +:download:`example.py ` + +.. literalinclude:: examples/readme_example_1/example.py + :language: cmake + +.. note:: + + Since we did not install the module, + we should compile and run the example from the same folder. + To install, please consult + `this pybind11 / CMake example `_. diff --git a/docs/source/examples/readme_example_1/CMakeLists.txt b/docs/source/examples/readme_example_1/CMakeLists.txt new file mode 100644 index 0000000..e17611c --- /dev/null +++ b/docs/source/examples/readme_example_1/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.1..3.19) + +project(mymodule) + +find_package(pybind11 CONFIG REQUIRED) +find_package(xtensor REQUIRED) +find_package(xtensor-python REQUIRED) +find_package(Python REQUIRED COMPONENTS NumPy) + +pybind11_add_module(mymodule main.cpp) +target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy) + +target_compile_definitions(mymodule PRIVATE VERSION_INFO=0.1.0) diff --git a/docs/source/examples/readme_example_1/example.py b/docs/source/examples/readme_example_1/example.py new file mode 100644 index 0000000..1ae033d --- /dev/null +++ b/docs/source/examples/readme_example_1/example.py @@ -0,0 +1,6 @@ +import mymodule +import numpy as np + +a = np.array([1, 2, 3]) +assert np.isclose(np.sum(np.sin(a)), mymodule.sum_of_sines(a)) + diff --git a/docs/source/examples/readme_example_1/main.cpp b/docs/source/examples/readme_example_1/main.cpp new file mode 100644 index 0000000..6175ed8 --- /dev/null +++ b/docs/source/examples/readme_example_1/main.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#define FORCE_IMPORT_ARRAY +#include + +double sum_of_sines(xt::pyarray& m) +{ + auto sines = xt::sin(m); // sines does not actually hold values. + return std::accumulate(sines.begin(), sines.end(), 0.0); +} + +PYBIND11_MODULE(mymodule, m) +{ + xt::import_numpy(); + m.doc() = "Test module for xtensor python bindings"; + m.def("sum_of_sines", sum_of_sines, "Sum the sines of the input values"); +} diff --git a/docs/source/examples/sfinae/CMakeLists.txt b/docs/source/examples/sfinae/CMakeLists.txt new file mode 100644 index 0000000..f22f611 --- /dev/null +++ b/docs/source/examples/sfinae/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.1..3.19) + +project(mymodule) + +find_package(pybind11 CONFIG REQUIRED) +find_package(xtensor REQUIRED) +find_package(xtensor-python REQUIRED) +find_package(Python REQUIRED COMPONENTS NumPy) + +pybind11_add_module(mymodule python.cpp) +target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy) + +target_compile_definitions(mymodule PRIVATE VERSION_INFO=0.1.0) + +add_executable(myexec main.cpp) +target_link_libraries(myexec PUBLIC xtensor) diff --git a/docs/source/examples/sfinae/example.py b/docs/source/examples/sfinae/example.py new file mode 100644 index 0000000..1929f0b --- /dev/null +++ b/docs/source/examples/sfinae/example.py @@ -0,0 +1,8 @@ +import mymodule +import numpy as np + +a = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float64) +b = np.array(a, copy=True) +mymodule.times_dimension(b) # changing in-place! +assert np.allclose(2 * a, b) + diff --git a/docs/source/examples/sfinae/main.cpp b/docs/source/examples/sfinae/main.cpp new file mode 100644 index 0000000..a146cdd --- /dev/null +++ b/docs/source/examples/sfinae/main.cpp @@ -0,0 +1,10 @@ +#include "mymodule.hpp" +#include + +int main() +{ + xt::xtensor a = xt::arange(2 * 3).reshape({2, 3}); + mymodule::times_dimension(a); + std::cout << a << std::endl; + return 0; +} diff --git a/docs/source/examples/sfinae/mymodule.hpp b/docs/source/examples/sfinae/mymodule.hpp new file mode 100644 index 0000000..5127eff --- /dev/null +++ b/docs/source/examples/sfinae/mymodule.hpp @@ -0,0 +1,32 @@ +#include + +namespace mymodule { + +template +struct is_std_vector +{ + static const bool value = false; +}; + +template +struct is_std_vector > +{ + static const bool value = true; +}; + +// any xtensor object +template ::value, bool> = true> +void times_dimension(T& t) +{ + using value_type = typename T::value_type; + t *= (value_type)(t.dimension()); +} + +// an std::vector +template ::value, bool> = true> +void times_dimension(T& t) +{ + // do nothing +} + +} diff --git a/docs/source/examples/sfinae/python.cpp b/docs/source/examples/sfinae/python.cpp new file mode 100644 index 0000000..081f625 --- /dev/null +++ b/docs/source/examples/sfinae/python.cpp @@ -0,0 +1,11 @@ +#include "mymodule.hpp" +#include +#define FORCE_IMPORT_ARRAY +#include + +PYBIND11_MODULE(mymodule, m) +{ + xt::import_numpy(); + m.doc() = "Test module for xtensor python bindings"; + m.def("times_dimension", &mymodule::times_dimension>); +} diff --git a/docs/source/index.rst b/docs/source/index.rst index 6f9c852..d54686b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,7 +16,7 @@ What are ``xtensor`` and ``xtensor-python``? - ``xtensor`` is a C++ library for multi-dimensional arrays enabling numpy-style broadcasting and lazy computing. - ``xtensor-python`` enables inplace use of numpy arrays with all the benefits from ``xtensor`` - - C++ universal functions and broadcasting + - C++ universal functions and broadcasting - STL - compliant APIs. @@ -62,6 +62,7 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f basic_usage array_tensor numpy_capi + examples cookiecutter .. toctree:: @@ -79,7 +80,7 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f .. _NumPy: http://www.numpy.org .. _`Buffer Protocol`: https://docs.python.org/3/c-api/buffer.html -.. _`numpy to xtensor cheat sheet`: http://xtensor.readthedocs.io/en/latest/numpy.html +.. _`numpy to xtensor cheat sheet`: http://xtensor.readthedocs.io/en/latest/numpy.html .. _xtensor: https://github.com/xtensor-stack/xtensor -.. _pybind11: https://github.com/pybind/pybind11 -.. _xtensor-python-cookiecutter: https://github.com/xtensor-stack/xtensor-python-cookiecutter +.. _pybind11: https://github.com/pybind/pybind11 +.. _xtensor-python-cookiecutter: https://github.com/xtensor-stack/xtensor-python-cookiecutter From 39682ec09e988a4ed46b4ab7fc5d92b96918ba41 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 24 May 2021 16:16:23 +0200 Subject: [PATCH 052/102] Upgraded to xtensor 0.23.10 in the CI --- .appveyor.yml | 2 +- environment-dev.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index c7f2b5c..a4c523c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.23.0 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.23.10 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - nmake test_xtensor_python diff --git a/environment-dev.yml b/environment-dev.yml index 28285b4..53809d5 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -5,7 +5,7 @@ dependencies: # Build dependencies - cmake # Host dependencies - - xtensor=0.23.0 + - xtensor=0.23.10 - numpy - pybind11=2.4.3 # Test dependencies From 9aa58f8a5316548bb382e6f14aa557c2c96d9399 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 24 May 2021 22:08:08 +0200 Subject: [PATCH 053/102] Release 0.25.2 --- README.md | 1 + include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c8cc92a..cad1b12 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| | master | ^0.23.0 | ~2.4.3 | +| 0.25.2 | ^0.23.0 | ~2.4.3 | | 0.25.1 | ^0.23.0 | ~2.4.3 | | 0.25.0 | ^0.23.0 | ~2.4.3 | | 0.24.1 | ^0.21.2 | ~2.4.3 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 71998fb..fd1e44f 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -12,6 +12,6 @@ #define XTENSOR_PYTHON_VERSION_MAJOR 0 #define XTENSOR_PYTHON_VERSION_MINOR 25 -#define XTENSOR_PYTHON_VERSION_PATCH 1 +#define XTENSOR_PYTHON_VERSION_PATCH 2 #endif From 33fca0e1954a0c99362a89049f1b1e7d559dbe53 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Fri, 21 May 2021 10:18:16 +0200 Subject: [PATCH 054/102] Documenting CMake pitfall --- .azure-pipelines/unix-build.yml | 10 +++- docs/source/examples.rst | 55 +++++++++++++++++-- .../examples/readme_example_1/CMakeLists.txt | 6 +- docs/source/examples/sfinae/CMakeLists.txt | 6 +- 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index d01651c..cbe8e49 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -36,16 +36,22 @@ steps: - script: | source activate xtensor-python - cmake . -DPYTHON_EXECUTABLE=`which python` + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build cmake --build . + cp ../example.py . python example.py + cd .. displayName: Example - readme 1 workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1 - script: | source activate xtensor-python - cmake . -DPYTHON_EXECUTABLE=`which python` + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build cmake --build . + cp ../example.py . python example.py + cd .. displayName: Example - SFINAE workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/sfinae diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 4788b8b..caa2c6d 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -14,13 +14,57 @@ Consider the following C++ code: :language: cpp There are several options to build the module, -whereby we will CMake here with the following ``CMakeLists.txt``: +whereby we will use *CMake* here with the following ``CMakeLists.txt``: :download:`CMakeLists.txt ` .. literalinclude:: examples/readme_example_1/CMakeLists.txt :language: cmake +.. tip:: + + There is a potential pitfall here, centered around the fact that *CMake* + has a 'new' *FindPython* and a 'classic' *FindPythonLibs*. + We here use *FindPython* because of its ability to find the NumPy headers, + that we need for *xtensor-python*. + + This has the consequence that when we want to force *CMake* + to use a specific *Python* executable, we have to use something like + + .. code-block:: none + + cmake -Bbuild -DPython_EXECUTABLE=`which python` + + whereby it is crucial that one uses the correct case ``Python_EXECUTABLE``, as: + + .. code-block:: none + + Python_EXECUTABLE <-> FindPython + PYTHON_EXECUTABLE <-> FindPythonLibs + + (remember that *CMake* is **case-sensitive**!). + + Now, since we use *FindPython* because of *xtensor-python* we also want *pybind11* + to use *FindPython* + (and not the classic *FindPythonLibs*, + since we want to specify the *Python* executable only once). + To this end we have to make sure to do things in the correct order, which is + + .. code-block:: cmake + + find_package(Python REQUIRED COMPONENTS Interpreter Development NumPy) + find_package(pybind11 REQUIRED CONFIG) + + (i.e. one finds *Python* **before** *pybind11*). + See the `pybind11 documentation `_. + + In addition, be sure to use a quite recent *CMake* version, + by starting your ``CMakeLists.txt`` for example with + + .. code-block:: cmake + + cmake_minimum_required(VERSION 3.18..3.20) + Then we can test the module: :download:`example.py ` @@ -33,7 +77,7 @@ Then we can test the module: Since we did not install the module, we should compile and run the example from the same folder. To install, please consult - `this pybind11 / CMake example `_. + `this *pybind11* / *CMake* example `_. Type restriction with SFINAE @@ -78,13 +122,15 @@ For the Python module we just have to specify the template to be .. literalinclude:: examples/sfinae/python.cpp :language: cpp -We will again use CMake to compile, with the following ``CMakeLists.txt``: +We will again use *CMake* to compile, with the following ``CMakeLists.txt``: :download:`CMakeLists.txt ` .. literalinclude:: examples/sfinae/CMakeLists.txt :language: cmake +(see *CMake* tip above). + Then we can test the module: :download:`example.py ` @@ -97,4 +143,5 @@ Then we can test the module: Since we did not install the module, we should compile and run the example from the same folder. To install, please consult - `this pybind11 / CMake example `_. + `this *pybind11* / *CMake* example `_. + **Tip**: take care to modify that example with the correct *CMake* case ``Python_EXECUTABLE``. diff --git a/docs/source/examples/readme_example_1/CMakeLists.txt b/docs/source/examples/readme_example_1/CMakeLists.txt index e17611c..9c7ed5f 100644 --- a/docs/source/examples/readme_example_1/CMakeLists.txt +++ b/docs/source/examples/readme_example_1/CMakeLists.txt @@ -1,11 +1,11 @@ -cmake_minimum_required(VERSION 3.1..3.19) +cmake_minimum_required(VERSION 3.18..3.20) project(mymodule) -find_package(pybind11 CONFIG REQUIRED) +find_package(Python REQUIRED COMPONENTS Interpreter Development NumPy) +find_package(pybind11 REQUIRED CONFIG) find_package(xtensor REQUIRED) find_package(xtensor-python REQUIRED) -find_package(Python REQUIRED COMPONENTS NumPy) pybind11_add_module(mymodule main.cpp) target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy) diff --git a/docs/source/examples/sfinae/CMakeLists.txt b/docs/source/examples/sfinae/CMakeLists.txt index f22f611..10a1a96 100644 --- a/docs/source/examples/sfinae/CMakeLists.txt +++ b/docs/source/examples/sfinae/CMakeLists.txt @@ -1,11 +1,11 @@ -cmake_minimum_required(VERSION 3.1..3.19) +cmake_minimum_required(VERSION 3.18..3.20) project(mymodule) -find_package(pybind11 CONFIG REQUIRED) +find_package(Python REQUIRED COMPONENTS Interpreter Development NumPy) +find_package(pybind11 REQUIRED CONFIG) find_package(xtensor REQUIRED) find_package(xtensor-python REQUIRED) -find_package(Python REQUIRED COMPONENTS NumPy) pybind11_add_module(mymodule python.cpp) target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy) From cfb08aeb0d34aba786d451fd6a87331509e41754 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Fri, 28 May 2021 14:51:04 +0200 Subject: [PATCH 055/102] Fixing constructor bug pytensor<..., 0> --- include/xtensor-python/pytensor.hpp | 23 +++++++++++++++++++---- test/test_pytensor.cpp | 9 +++++++++ test_python/main.cpp | 7 +++++++ test_python/test_pyarray.py | 4 ++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index 0fab55a..76f55c7 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -100,11 +100,26 @@ namespace pybind11 } }; - } + } // namespace detail } namespace xt { + namespace detail { + + template + struct numpy_strides + { + npy_intp value[N]; + }; + + template + struct numpy_strides::type> + { + npy_intp* value = nullptr; + }; + + } // namespace detail template struct xiterable_inner_types> @@ -433,8 +448,8 @@ namespace xt template inline void pytensor::init_tensor(const shape_type& shape, const strides_type& strides) { - npy_intp python_strides[N]; - std::transform(strides.begin(), strides.end(), python_strides, + detail::numpy_strides python_strides; + std::transform(strides.begin(), strides.end(), python_strides.value, [](auto v) { return sizeof(T) * v; }); int flags = NPY_ARRAY_ALIGNED; if (!std::is_const::value) @@ -445,7 +460,7 @@ namespace xt auto tmp = pybind11::reinterpret_steal( PyArray_NewFromDescr(&PyArray_Type, (PyArray_Descr*) dtype.release().ptr(), static_cast(shape.size()), - const_cast(shape.data()), python_strides, + const_cast(shape.data()), python_strides.value, nullptr, flags, nullptr)); if (!tmp) diff --git a/test/test_pytensor.cpp b/test/test_pytensor.cpp index 637d58f..f2ac013 100644 --- a/test/test_pytensor.cpp +++ b/test/test_pytensor.cpp @@ -65,6 +65,15 @@ namespace xt EXPECT_THROW(pyt3::from_shape(shp), std::runtime_error); } + TEST(pytensor, scalar_from_shape) + { + std::array shape; + auto a = pytensor::from_shape(shape); + pytensor b(1.2); + EXPECT_TRUE(a.size() == b.size()); + EXPECT_TRUE(xt::has_shape(a, b.shape())); + } + TEST(pytensor, strided_constructor) { central_major_result cmr; diff --git a/test_python/main.cpp b/test_python/main.cpp index b4b6cc6..66f4e3c 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -227,6 +227,11 @@ void col_major_array(xt::pyarray& arg) } } +xt::pytensor xscalar(const xt::pytensor& arg) +{ + return xt::sum(arg); +} + template using ndarray = xt::pyarray; @@ -285,6 +290,8 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("col_major_array", col_major_array); m.def("row_major_tensor", row_major_tensor); + m.def("xscalar", xscalar); + py::class_(m, "C") .def(py::init<>()) .def_property_readonly( diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index c3c1447..71e9dd3 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -151,6 +151,10 @@ def test_col_row_major(self): xt.col_major_array(varF) xt.col_major_array(varF[:, :, 0]) # still col major! + def test_xscalar(self): + var = np.arange(50, dtype=int) + self.assertTrue(np.sum(var) == xt.xscalar(var)) + def test_bad_argument_call(self): with self.assertRaises(TypeError): xt.simple_array("foo") From 30faa6e4fe216749dfa9930a751509b585659bde Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Mon, 31 May 2021 10:17:11 +0200 Subject: [PATCH 056/102] Simple specialization --- include/xtensor-python/pytensor.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index 76f55c7..ce3d115 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -107,14 +107,14 @@ namespace xt { namespace detail { - template + template struct numpy_strides { npy_intp value[N]; }; - template - struct numpy_strides::type> + template <> + struct numpy_strides<0> { npy_intp* value = nullptr; }; From c801639e5127028a9ef4779fb17c9ae8193026b9 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 3 Jun 2021 12:51:19 +0200 Subject: [PATCH 057/102] Adding possibility to 'cast' or copy to `xt::xarray` etc --- .azure-pipelines/unix-build.yml | 8 ++ docs/source/examples/copy_cast/CMakeLists.txt | 13 ++ docs/source/examples/copy_cast/example.py | 6 + docs/source/examples/copy_cast/main.cpp | 25 ++++ include/xtensor-python/pynative_casters.hpp | 1 - .../xtensor_type_caster_base.hpp | 121 +++++++++++++++--- 6 files changed, 157 insertions(+), 17 deletions(-) create mode 100644 docs/source/examples/copy_cast/CMakeLists.txt create mode 100644 docs/source/examples/copy_cast/example.py create mode 100644 docs/source/examples/copy_cast/main.cpp diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index d01651c..0008e13 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -42,6 +42,14 @@ steps: displayName: Example - readme 1 workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1 + - script: | + source activate xtensor-python + cmake . -DPYTHON_EXECUTABLE=`which python` + cmake --build . + python example.py + displayName: Example - Copy 'cast' + workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/copy_cast + - script: | source activate xtensor-python cmake . -DPYTHON_EXECUTABLE=`which python` diff --git a/docs/source/examples/copy_cast/CMakeLists.txt b/docs/source/examples/copy_cast/CMakeLists.txt new file mode 100644 index 0000000..e17611c --- /dev/null +++ b/docs/source/examples/copy_cast/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.1..3.19) + +project(mymodule) + +find_package(pybind11 CONFIG REQUIRED) +find_package(xtensor REQUIRED) +find_package(xtensor-python REQUIRED) +find_package(Python REQUIRED COMPONENTS NumPy) + +pybind11_add_module(mymodule main.cpp) +target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy) + +target_compile_definitions(mymodule PRIVATE VERSION_INFO=0.1.0) diff --git a/docs/source/examples/copy_cast/example.py b/docs/source/examples/copy_cast/example.py new file mode 100644 index 0000000..d007e7c --- /dev/null +++ b/docs/source/examples/copy_cast/example.py @@ -0,0 +1,6 @@ +import mymodule +import numpy as np + +c = np.array([[1, 2, 3], [4, 5, 6]]) +assert np.isclose(np.sum(np.sin(c)), mymodule.sum_of_sines(c)) +assert np.isclose(np.sum(np.cos(c)), mymodule.sum_of_cosines(c)) diff --git a/docs/source/examples/copy_cast/main.cpp b/docs/source/examples/copy_cast/main.cpp new file mode 100644 index 0000000..cb3e65c --- /dev/null +++ b/docs/source/examples/copy_cast/main.cpp @@ -0,0 +1,25 @@ +#include +#include +#include +#define FORCE_IMPORT_ARRAY +#include + +double sum_of_sines(xt::pyarray& m) +{ + auto sines = xt::sin(m); // sines does not actually hold values. + return std::accumulate(sines.begin(), sines.end(), 0.0); +} + +double sum_of_cosines(const xt::xarray& m) +{ + auto cosines = xt::cos(m); // cosines does not actually hold values. + return std::accumulate(cosines.begin(), cosines.end(), 0.0); +} + +PYBIND11_MODULE(mymodule, m) +{ + xt::import_numpy(); + m.doc() = "Test module for xtensor python bindings"; + m.def("sum_of_sines", sum_of_sines, "Sum the sines of the input values"); + m.def("sum_of_cosines", sum_of_cosines, "Sum the cosines of the input values"); +} diff --git a/include/xtensor-python/pynative_casters.hpp b/include/xtensor-python/pynative_casters.hpp index f0f0065..caaad34 100644 --- a/include/xtensor-python/pynative_casters.hpp +++ b/include/xtensor-python/pynative_casters.hpp @@ -12,7 +12,6 @@ #include "xtensor_type_caster_base.hpp" - namespace pybind11 { namespace detail diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 3c8a015..e587865 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -23,6 +23,87 @@ namespace pybind11 { namespace detail { + template + struct xtensor_get_buffer + { + template + static auto get(H src) + { + return array_t::ensure(src); + } + }; + + template + struct xtensor_get_buffer + { + template + static auto get(H src) + { + return array_t::ensure(src); + } + }; + + template + struct xtensor_check_buffer + { + }; + + template + struct xtensor_check_buffer> + { + template + static auto get(H src) + { + auto buf = xtensor_get_buffer::get(src); + return buf; + } + }; + + template + struct xtensor_check_buffer> + { + template + static auto get(H src) + { + auto buf = xtensor_get_buffer::get(src); + if (buf.ndim() != N) { + return false; + } + return buf; + } + }; + + template + struct xtensor_check_buffer> + { + template + static auto get(H /*src*/) + { + return false; + } + }; + + template + struct xtensor_check_buffer> + { + template + static auto get(H /*src*/) + { + return false; + } + }; + + template + struct xtensor_check_buffer> + { + template + static auto get(H /*src*/) + { + return false; + } + }; + + // Casts a strided expression type to numpy array.If given a base, // the numpy array references the src data, otherwise it'll make a copy. // The writeable attributes lets you specify writeable flag for the array. @@ -74,10 +155,6 @@ namespace pybind11 template struct xtensor_type_caster_base { - bool load(handle /*src*/, bool) - { - return false; - } private: @@ -106,6 +183,30 @@ namespace pybind11 public: + PYBIND11_TYPE_CASTER(Type, _("numpy.ndarray[") + npy_format_descriptor::name + _("]")); + + bool load(handle src, bool convert) + { + using T = typename Type::value_type; + + if (!convert && !array_t::check_(src)) { + return false; + } + + auto buf = xtensor_check_buffer::get(src); + + if (!buf) { + return false; + } + + std::vector shape(buf.ndim()); + std::copy(buf.shape(), buf.shape() + buf.ndim(), shape.begin()); + value = Type(shape); + std::copy(buf.data(), buf.data() + buf.size(), value.begin()); + + return true; + } + // Normal returned non-reference, non-const value: static handle cast(Type&& src, return_value_policy /* policy */, handle parent) { @@ -151,18 +252,6 @@ namespace pybind11 { return cast_impl(src, policy, parent); } - -#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 - static PYBIND11_DESCR name() - { - return _("xt::xtensor"); - } -#else - static constexpr auto name = _("xt::xtensor"); -#endif - - template - using cast_op_type = cast_op_type; }; } } From e21ecb0177268267df8aa16d4639d681ddc86dcd Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Sat, 5 Jun 2021 13:08:01 +0200 Subject: [PATCH 058/102] Adding example --- docs/source/examples.rst | 50 +++++++++++++++++++ docs/source/examples/copy_cast/main.cpp | 6 ++- .../xtensor_type_caster_base.hpp | 24 ++++----- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 4788b8b..cd7242a 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -98,3 +98,53 @@ Then we can test the module: we should compile and run the example from the same folder. To install, please consult `this pybind11 / CMake example `_. + + +Fall-back cast +============== + +The previous example showed you how to design your module to be flexible in accepting data. +From C++ we used ``xt::xarray``, +whereas for the Python API we used ``xt::pyarray`` to operate directly on the memory +of a NumPy array from Python (without copying the data). + +Sometimes, you might not have the flexibility to design your module's methods +with template parameters. +This might occur when you want to ``override`` functions +(though it is recommended to use CRTP to still use templates). +In this case we can still bind the module in Python using *xtensor-python*, +however, we have to copy the data from a (NumPy) array. +This means that although the following signatures are quite different when used from C++, +as follows: + +1. *Constant reference*: read from the data, without copying it. + + .. code-block:: cpp + + void foo(const xt::xarray& a); + +2. *Reference*: read from and/or write to the data, without copying it. + + .. code-block:: cpp + + void foo(xt::xarray& a); + +3. *Copy*: copy the data. + + .. code-block:: cpp + + void foo(xt::xarray a); + +The Python will all cases result in a copy to a temporary variable +(though the last signature will lead to a copy to a temporary variable, and another copy to ``a``). +On the one hand, this is more costly than when using ``xt::pyarray`` and ``xt::pyxtensor``, +on the other hand, it means that all changes you make to a reference, are made to the temporary +copy, and are thus lost. + +Still, it might be a convenient way to create Python bindings, using a minimal effort. +Consider this example: + +:download:`main.cpp ` + +.. literalinclude:: examples/copy_cast/main.cpp + :language: cpp diff --git a/docs/source/examples/copy_cast/main.cpp b/docs/source/examples/copy_cast/main.cpp index cb3e65c..2e12609 100644 --- a/docs/source/examples/copy_cast/main.cpp +++ b/docs/source/examples/copy_cast/main.cpp @@ -4,12 +4,14 @@ #define FORCE_IMPORT_ARRAY #include -double sum_of_sines(xt::pyarray& m) +template +double sum_of_sines(T& m) { auto sines = xt::sin(m); // sines does not actually hold values. return std::accumulate(sines.begin(), sines.end(), 0.0); } +// In the Python API this a reference to a temporary variable double sum_of_cosines(const xt::xarray& m) { auto cosines = xt::cos(m); // cosines does not actually hold values. @@ -20,6 +22,6 @@ PYBIND11_MODULE(mymodule, m) { xt::import_numpy(); m.doc() = "Test module for xtensor python bindings"; - m.def("sum_of_sines", sum_of_sines, "Sum the sines of the input values"); + m.def("sum_of_sines", sum_of_sines>, "Sum the sines of the input values"); m.def("sum_of_cosines", sum_of_cosines, "Sum the cosines of the input values"); } diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index e587865..68218ee 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -26,8 +26,7 @@ namespace pybind11 template struct xtensor_get_buffer { - template - static auto get(H src) + static auto get(handle src) { return array_t::ensure(src); } @@ -36,8 +35,7 @@ namespace pybind11 template struct xtensor_get_buffer { - template - static auto get(H src) + static auto get(handle src) { return array_t::ensure(src); } @@ -51,8 +49,7 @@ namespace pybind11 template struct xtensor_check_buffer> { - template - static auto get(H src) + static auto get(handle src) { auto buf = xtensor_get_buffer::get(src); return buf; @@ -62,8 +59,7 @@ namespace pybind11 template struct xtensor_check_buffer> { - template - static auto get(H src) + static auto get(handle src) { auto buf = xtensor_get_buffer::get(src); if (buf.ndim() != N) { @@ -76,8 +72,7 @@ namespace pybind11 template struct xtensor_check_buffer> { - template - static auto get(H /*src*/) + static auto get(handle /*src*/) { return false; } @@ -86,18 +81,17 @@ namespace pybind11 template struct xtensor_check_buffer> { - template - static auto get(H /*src*/) + static auto get(handle src) { - return false; + auto buf = xtensor_get_buffer::get(src); + return buf; } }; template struct xtensor_check_buffer> { - template - static auto get(H /*src*/) + static auto get(handle /*src*/) { return false; } From 428ed03b5dbc2b9ab0a62ffbf9da5a4ed0705afe Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Sat, 5 Jun 2021 16:08:29 +0200 Subject: [PATCH 059/102] Adding tests & minor bugfix --- .../xtensor_type_caster_base.hpp | 39 ++++++++++++++----- test_python/main.cpp | 32 +++++++++++++++ test_python/test_pyarray.py | 16 ++++++++ 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 68218ee..8db9e44 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -37,7 +37,7 @@ namespace pybind11 { static auto get(handle src) { - return array_t::ensure(src); + return array_t::ensure(src); } }; @@ -51,8 +51,7 @@ namespace pybind11 { static auto get(handle src) { - auto buf = xtensor_get_buffer::get(src); - return buf; + return xtensor_get_buffer::get(src); } }; @@ -61,11 +60,7 @@ namespace pybind11 { static auto get(handle src) { - auto buf = xtensor_get_buffer::get(src); - if (buf.ndim() != N) { - return false; - } - return buf; + return xtensor_get_buffer::get(src); } }; @@ -98,6 +93,27 @@ namespace pybind11 }; + template + struct xtensor_verify + { + template + static bool get(const B& buf) + { + return true; + } + }; + + template + struct xtensor_verify> + { + template + static bool get(const B& buf) + { + return buf.ndim() == N; + } + }; + + // Casts a strided expression type to numpy array.If given a base, // the numpy array references the src data, otherwise it'll make a copy. // The writeable attributes lets you specify writeable flag for the array. @@ -192,11 +208,14 @@ namespace pybind11 if (!buf) { return false; } + if (!xtensor_verify::get(buf)) { + return false; + } std::vector shape(buf.ndim()); std::copy(buf.shape(), buf.shape() + buf.ndim(), shape.begin()); - value = Type(shape); - std::copy(buf.data(), buf.data() + buf.size(), value.begin()); + value = Type::from_shape(shape); + std::copy(buf.data(), buf.data() + buf.size(), value.data()); return true; } diff --git a/test_python/main.cpp b/test_python/main.cpp index 66f4e3c..7e5963c 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -33,6 +33,33 @@ xt::pyarray example2(xt::pyarray& m) return m + 2; } +xt::xarray example3_xarray(const xt::xarray& m) +{ + return xt::transpose(m) + 2; +} + +xt::xarray example3_xarray_colmajor( + const xt::xarray& m) +{ + return xt::transpose(m) + 2; +} + +xt::xtensor example3_xtensor3(const xt::xtensor& m) +{ + return xt::transpose(m) + 2; +} + +xt::xtensor example3_xtensor2(const xt::xtensor& m) +{ + return xt::transpose(m) + 2; +} + +xt::xtensor example3_xtensor2_colmajor( + const xt::xtensor& m) +{ + return xt::transpose(m) + 2; +} + // Readme Examples double readme_example1(xt::pyarray& m) @@ -249,6 +276,11 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("example1", example1); m.def("example2", example2); + m.def("example3_xarray", example3_xarray); + m.def("example3_xarray_colmajor", example3_xarray_colmajor); + m.def("example3_xtensor3", example3_xtensor3); + m.def("example3_xtensor2", example3_xtensor2); + m.def("example3_xtensor2_colmajor", example3_xtensor2_colmajor); m.def("complex_overload", no_complex_overload); m.def("complex_overload", complex_overload); diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index 71e9dd3..8760c97 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -36,6 +36,22 @@ def test_example2(self): y = xt.example2(x) np.testing.assert_allclose(y, res, 1e-12) + def test_example3(self): + x = np.arange(2 * 3).reshape(2, 3) + xc = np.asfortranarray(x) + y = np.arange(2 * 3 * 4).reshape(2, 3, 4) + v = y[1:, 1:, 0] + z = np.arange(2 * 3 * 4 * 5).reshape(2, 3, 4, 5) + np.testing.assert_array_equal(xt.example3_xarray(x), x.T + 2) + np.testing.assert_array_equal(xt.example3_xarray_colmajor(xc), xc.T + 2) + np.testing.assert_array_equal(xt.example3_xtensor3(y), y.T + 2) + np.testing.assert_array_equal(xt.example3_xtensor2(x), x.T + 2) + np.testing.assert_array_equal(xt.example3_xtensor2(y[1:, 1:, 0]), v.T + 2) + np.testing.assert_array_equal(xt.example3_xtensor2_colmajor(xc), xc.T + 2) + + with self.assertRaises(TypeError): + xt.example3_xtensor3(x) + def test_vectorize(self): x1 = np.array([[0, 1], [2, 3]]) x2 = np.array([0, 1]) From acc30eddda5089dbd7873897c479dbd72c116d46 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 10 Jun 2021 11:51:03 +0200 Subject: [PATCH 060/102] Nitpicking --- .../xtensor_type_caster_base.hpp | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 8db9e44..672bd64 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -24,69 +24,69 @@ namespace pybind11 namespace detail { template - struct xtensor_get_buffer + struct pybind_array_getter_impl { - static auto get(handle src) + static auto run(handle src) { return array_t::ensure(src); } }; template - struct xtensor_get_buffer + struct pybind_array_getter_impl { - static auto get(handle src) + static auto run(handle src) { return array_t::ensure(src); } }; template - struct xtensor_check_buffer + struct pybind_array_getter { }; template - struct xtensor_check_buffer> + struct pybind_array_getter> { - static auto get(handle src) + static auto run(handle src) { - return xtensor_get_buffer::get(src); + return pybind_array_getter_impl::run(src); } }; template - struct xtensor_check_buffer> + struct pybind_array_getter> { - static auto get(handle src) + static auto run(handle src) { - return xtensor_get_buffer::get(src); + return pybind_array_getter_impl::run(src); } }; template - struct xtensor_check_buffer> + struct pybind_array_getter> { - static auto get(handle /*src*/) + static auto run(handle /*src*/) { return false; } }; template - struct xtensor_check_buffer> + struct pybind_array_getter> { - static auto get(handle src) + static auto run(handle src) { - auto buf = xtensor_get_buffer::get(src); + auto buf = pybind_array_getter_impl::run(src); return buf; } }; template - struct xtensor_check_buffer> + struct pybind_array_getter> { - static auto get(handle /*src*/) + static auto run(handle /*src*/) { return false; } @@ -94,20 +94,20 @@ namespace pybind11 template - struct xtensor_verify + struct pybind_array_dim_checker { template - static bool get(const B& buf) + static bool run(const B& buf) { return true; } }; template - struct xtensor_verify> + struct pybind_array_dim_checker> { template - static bool get(const B& buf) + static bool run(const B& buf) { return buf.ndim() == N; } @@ -199,16 +199,19 @@ namespace pybind11 { using T = typename Type::value_type; - if (!convert && !array_t::check_(src)) { + if (!convert && !array_t::check_(src)) + { return false; } - auto buf = xtensor_check_buffer::get(src); + auto buf = pybind_array_getter::run(src); - if (!buf) { + if (!buf) + { return false; } - if (!xtensor_verify::get(buf)) { + if (!pybind_array_dim_checker::run(buf)) + { return false; } From af91def5d4bb9b7966f134adb581c59f6c66af87 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 10 Jun 2021 11:52:58 +0200 Subject: [PATCH 061/102] Fixing CI --- .azure-pipelines/unix-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index 0fcf692..97cb405 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -52,13 +52,16 @@ steps: cmake --build . cp ../example.py . python example.py + cd .. displayName: Example - Copy 'cast' workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/copy_cast - script: | source activate xtensor-python - cmake . -DPYTHON_EXECUTABLE=`which python` + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build cmake --build . + cp ../example.py . python example.py cd .. displayName: Example - SFINAE From 601ae8635782c3e3230cc0d85dc7c0e5ed74b96a Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 11 Jun 2021 10:48:56 +0200 Subject: [PATCH 062/102] Release 0.25.3 --- README.md | 5 +---- include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cad1b12..5b5ed45 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| | master | ^0.23.0 | ~2.4.3 | +| 0.25.3 | ^0.23.0 | ~2.4.3 | | 0.25.2 | ^0.23.0 | ~2.4.3 | | 0.25.1 | ^0.23.0 | ~2.4.3 | | 0.25.0 | ^0.23.0 | ~2.4.3 | @@ -216,10 +217,6 @@ from the `docs` subdirectory. | 0.21.x | ^0.18.0 | ~2.2.1 | | 0.20.x | ^0.17.0 | ~2.2.1 | | 0.19.x | ^0.16.0 | ~2.2.1 | -| 0.18.x | ^0.16.0 | ~2.1.0 or ~2.2.1 | -| 0.17.x | ^0.15.1 | ~2.1.0 or ~2.2.1 | -| 0.16.x | ^0.14.0 | ~2.1.0 or ~2.2.1 | -| 0.15.x | ^0.13.1 | ~2.1.0 or ~2.2.1 | These dependencies are automatically resolved when using the conda package manager. diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index fd1e44f..55f6b77 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -12,6 +12,6 @@ #define XTENSOR_PYTHON_VERSION_MAJOR 0 #define XTENSOR_PYTHON_VERSION_MINOR 25 -#define XTENSOR_PYTHON_VERSION_PATCH 2 +#define XTENSOR_PYTHON_VERSION_PATCH 3 #endif From 8495d81ee9e8dacc0d086acc416d8e9146b4cde7 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 18 Oct 2021 23:24:05 +0200 Subject: [PATCH 063/102] Upgraded to xtenosr 0.24.0 --- .appveyor.yml | 2 +- CMakeLists.txt | 2 +- environment-dev.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index a4c523c..a88415f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,7 +22,7 @@ install: - conda update -q conda - conda info -a - conda install cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.23.10 -c conda-forge + - conda install pytest numpy pybind11==2.4.3 xtensor==0.24.0 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - nmake test_xtensor_python diff --git a/CMakeLists.txt b/CMakeLists.txt index 694ee0d..e1bd077 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ message(STATUS "xtensor-python v${${PROJECT_NAME}_VERSION}") # Dependencies # ============ -set(xtensor_REQUIRED_VERSION 0.21.2) +set(xtensor_REQUIRED_VERSION 0.24.0) if(TARGET xtensor) set(xtensor_VERSION ${XTENSOR_VERSION_MAJOR}.${XTENSOR_VERSION_MINOR}.${XTENSOR_VERSION_PATCH}) # Note: This is not SEMVER compatible comparison diff --git a/environment-dev.yml b/environment-dev.yml index 53809d5..6dff19f 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -5,7 +5,7 @@ dependencies: # Build dependencies - cmake # Host dependencies - - xtensor=0.23.10 + - xtensor=0.24.0 - numpy - pybind11=2.4.3 # Test dependencies From 16cce9665f8abcaa4b9c516a5a03f41f618b72ce Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 18 Oct 2021 23:25:12 +0200 Subject: [PATCH 064/102] Upgraded azure to Ubuntu 18.04 --- .azure-pipelines/azure-pipelines-linux-clang.yml | 6 +----- .azure-pipelines/azure-pipelines-linux-gcc.yml | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.azure-pipelines/azure-pipelines-linux-clang.yml b/.azure-pipelines/azure-pipelines-linux-clang.yml index f1d6894..87d7592 100644 --- a/.azure-pipelines/azure-pipelines-linux-clang.yml +++ b/.azure-pipelines/azure-pipelines-linux-clang.yml @@ -2,10 +2,6 @@ jobs: - job: 'Linux_0' strategy: matrix: - clang_4: - llvm_version: '4.0' - clang_5: - llvm_version: '5.0' clang_6: llvm_version: '6.0' clang_7: @@ -15,7 +11,7 @@ jobs: clang_9: llvm_version: '9' pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 variables: CC: clang-$(llvm_version) CXX: clang++-$(llvm_version) diff --git a/.azure-pipelines/azure-pipelines-linux-gcc.yml b/.azure-pipelines/azure-pipelines-linux-gcc.yml index 7b1eb9d..e0a6aa0 100644 --- a/.azure-pipelines/azure-pipelines-linux-gcc.yml +++ b/.azure-pipelines/azure-pipelines-linux-gcc.yml @@ -2,10 +2,6 @@ jobs: - job: 'Linux_1' strategy: matrix: - gcc_4: - gcc_version: '4.9' - gcc_5: - gcc_version: '5' gcc_6: gcc_version: '6' gcc_7: @@ -15,7 +11,7 @@ jobs: gcc_9: gcc_version: '9' pool: - vmImage: ubuntu-16.04 + vmImage: ubuntu-18.04 variables: CC: gcc-$(gcc_version) CXX: g++-$(gcc_version) From 7e88bfc12ca851ead0e0426c37eedd68e84983f6 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 19 Oct 2021 09:52:28 +0200 Subject: [PATCH 065/102] Use mamba on Windows --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index a88415f..91cebe4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -21,8 +21,8 @@ install: - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda info -a - - conda install cmake -c conda-forge - - conda install pytest numpy pybind11==2.4.3 xtensor==0.24.0 -c conda-forge + - conda install mamba -c conda-forge + - mamba install cmake pytest numpy pybind11 xtensor==0.24.0 -c conda-forge - "set PYTHONHOME=%MINICONDA%" - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - nmake test_xtensor_python From 08d00044f210f8519af3a60f7d002158f291686f Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 19 Oct 2021 11:27:37 +0200 Subject: [PATCH 066/102] triggers CI From 6544a559ae98953394a1c51d8a637b71882af8da Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 19 Oct 2021 22:41:31 +0200 Subject: [PATCH 067/102] Release 0.26.0 --- README.md | 3 ++- include/xtensor-python/xtensor_python_config.hpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5b5ed45..2321733 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,8 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.23.0 | ~2.4.3 | +| master | ^0.24.0 | ~2.4.3 | +| 0.26.0 | ^0.24.0 | ~2.4.3 | | 0.25.3 | ^0.23.0 | ~2.4.3 | | 0.25.2 | ^0.23.0 | ~2.4.3 | | 0.25.1 | ^0.23.0 | ~2.4.3 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 55f6b77..8705451 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -11,7 +11,7 @@ #define XTENSOR_PYTHON_CONFIG_HPP #define XTENSOR_PYTHON_VERSION_MAJOR 0 -#define XTENSOR_PYTHON_VERSION_MINOR 25 -#define XTENSOR_PYTHON_VERSION_PATCH 3 +#define XTENSOR_PYTHON_VERSION_MINOR 26 +#define XTENSOR_PYTHON_VERSION_PATCH 0 #endif From a7ac13b0f09480533f303ea68431b388163b22b5 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Fri, 4 Mar 2022 09:09:04 +0100 Subject: [PATCH 068/102] CI: deprecating deprecated macOS image --- .azure-pipelines/azure-pipelines-osx.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.azure-pipelines/azure-pipelines-osx.yml b/.azure-pipelines/azure-pipelines-osx.yml index 282a8ac..fed2166 100644 --- a/.azure-pipelines/azure-pipelines-osx.yml +++ b/.azure-pipelines/azure-pipelines-osx.yml @@ -2,8 +2,6 @@ jobs: - job: 'OSX' strategy: matrix: - macOS_10_14: - image_name: 'macOS-10.14' macOS_10_15: image_name: 'macOS-10.15' pool: From e083f21ed92654a406f8376c2c6987edf5038969 Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Fri, 4 Mar 2022 14:00:48 +0100 Subject: [PATCH 069/102] add binding for xtensor_fixed --- include/xtensor-python/pycontainer.hpp | 4 +- include/xtensor-python/pynative_casters.hpp | 6 +++ .../xtensor_type_caster_base.hpp | 53 +++++++++++++++++++ test_python/main.cpp | 20 +++++++ test_python/test_pyarray.py | 13 ++++- 5 files changed, 93 insertions(+), 3 deletions(-) diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index b054d50..1617d03 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -320,9 +320,9 @@ namespace xt inline auto pycontainer::get_buffer_size() const -> size_type { const size_type& (*min)(const size_type&, const size_type&) = std::min; - size_type min_stride = this->strides().empty() ? size_type(1) : + size_type min_stride = this->strides().empty() ? size_type(1) : std::max(size_type(1), std::accumulate(this->strides().cbegin(), - this->strides().cend(), + this->strides().cend(), std::numeric_limits::max(), min)); return min_stride * static_cast(PyArray_SIZE(this->python_array())); diff --git a/include/xtensor-python/pynative_casters.hpp b/include/xtensor-python/pynative_casters.hpp index caaad34..aa19604 100644 --- a/include/xtensor-python/pynative_casters.hpp +++ b/include/xtensor-python/pynative_casters.hpp @@ -28,6 +28,12 @@ namespace pybind11 { }; + // Type caster for casting xt::xtensor_fixed to ndarray + template + struct type_caster> : xtensor_type_caster_base> + { + }; + // Type caster for casting xt::xstrided_view to ndarray template struct type_caster> : xtensor_type_caster_base> diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 672bd64..0122067 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -15,6 +15,7 @@ #include #include "xtensor/xtensor.hpp" +#include "xtensor/xfixed.hpp" #include #include @@ -64,6 +65,15 @@ namespace pybind11 } }; + template + struct pybind_array_getter> + { + static auto run(handle src) + { + return pybind_array_getter_impl::run(src); + } + }; + template struct pybind_array_getter> { @@ -113,6 +123,44 @@ namespace pybind11 } }; + template + struct pybind_array_dim_checker> + { + template + static bool run(const B& buf) + { + return buf.ndim() == FSH::size(); + } + }; + + + template + struct pybind_array_shape_checker + { + template + static bool run(const B& buf) + { + return true; + } + }; + + template + struct pybind_array_shape_checker> + { + template + static bool run(const B& buf) + { + auto shape = FSH(); + for (std::size_t i = 0; i < shape.size(); ++i) + { + if (shape[i] != buf.shape(i)) + { + return false; + } + } + return true; + } + }; // Casts a strided expression type to numpy array.If given a base, // the numpy array references the src data, otherwise it'll make a copy. @@ -215,6 +263,11 @@ namespace pybind11 return false; } + if (!pybind_array_shape_checker::run(buf)) + { + return false; + } + std::vector shape(buf.ndim()); std::copy(buf.shape(), buf.shape() + buf.ndim(), shape.begin()); value = Type::from_shape(shape); diff --git a/test_python/main.cpp b/test_python/main.cpp index 7e5963c..5a5edfb 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -11,6 +11,7 @@ #include "xtensor/xmath.hpp" #include "xtensor/xarray.hpp" +#include "xtensor/xfixed.hpp" #define FORCE_IMPORT_ARRAY #include "xtensor-python/pyarray.hpp" #include "xtensor-python/pytensor.hpp" @@ -60,6 +61,22 @@ xt::xtensor example3_xtensor2_colmajor( return xt::transpose(m) + 2; } +xt::xtensor_fixed> example3_xfixed3(const xt::xtensor_fixed>& m) +{ + return xt::transpose(m) + 2; +} + +xt::xtensor_fixed> example3_xfixed2(const xt::xtensor_fixed>& m) +{ + return xt::transpose(m) + 2; +} + +xt::xtensor_fixed, xt::layout_type::column_major> example3_xfixed2_colmajor( + const xt::xtensor_fixed, xt::layout_type::column_major>& m) +{ + return xt::transpose(m) + 2; +} + // Readme Examples double readme_example1(xt::pyarray& m) @@ -281,6 +298,9 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("example3_xtensor3", example3_xtensor3); m.def("example3_xtensor2", example3_xtensor2); m.def("example3_xtensor2_colmajor", example3_xtensor2_colmajor); + m.def("example3_xfixed3", example3_xfixed3); + m.def("example3_xfixed2", example3_xfixed2); + m.def("example3_xfixed2_colmajor", example3_xfixed2_colmajor); m.def("complex_overload", no_complex_overload); m.def("complex_overload", complex_overload); diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index 8760c97..c413002 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -49,9 +49,20 @@ def test_example3(self): np.testing.assert_array_equal(xt.example3_xtensor2(y[1:, 1:, 0]), v.T + 2) np.testing.assert_array_equal(xt.example3_xtensor2_colmajor(xc), xc.T + 2) + np.testing.assert_array_equal(xt.example3_xfixed3(y), y.T + 2) + np.testing.assert_array_equal(xt.example3_xfixed2(x), x.T + 2) + np.testing.assert_array_equal(xt.example3_xfixed2_colmajor(xc), xc.T + 2) + with self.assertRaises(TypeError): xt.example3_xtensor3(x) + with self.assertRaises(TypeError): + xt.example3_xfixed3(x) + + with self.assertRaises(TypeError): + x = np.arange(3*2).reshape(3, 2) + xt.example3_xfixed2(x) + def test_vectorize(self): x1 = np.array([[0, 1], [2, 3]]) x2 = np.array([0, 1]) @@ -85,7 +96,7 @@ def test_readme_example2(self): x = np.arange(15).reshape(3, 5) y = [1, 2, 3, 4, 5] z = xt.readme_example2(x, y) - np.testing.assert_allclose(z, + np.testing.assert_allclose(z, [[-0.540302, 1.257618, 1.89929 , 0.794764, -1.040465], [-1.499227, 0.136731, 1.646979, 1.643002, 0.128456], [-1.084323, -0.583843, 0.45342 , 1.073811, 0.706945]], 1e-5) From eb5cb76d937a82f46bdde1a5516de43445977509 Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Fri, 4 Mar 2022 14:18:05 +0100 Subject: [PATCH 070/102] fix MacOS version --- .azure-pipelines/azure-pipelines-osx.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/azure-pipelines-osx.yml b/.azure-pipelines/azure-pipelines-osx.yml index 282a8ac..beeafce 100644 --- a/.azure-pipelines/azure-pipelines-osx.yml +++ b/.azure-pipelines/azure-pipelines-osx.yml @@ -2,10 +2,10 @@ jobs: - job: 'OSX' strategy: matrix: - macOS_10_14: - image_name: 'macOS-10.14' macOS_10_15: image_name: 'macOS-10.15' + macOS_11: + image_name: 'macOS-11' pool: vmImage: $(image_name) variables: From 9a26ec814a7c4c7eb596e28aef85e939bb720f49 Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Fri, 4 Mar 2022 17:43:58 +0100 Subject: [PATCH 071/102] use std::equal --- include/xtensor-python/xtensor_type_caster_base.hpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 0122067..5874595 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -151,14 +151,7 @@ namespace pybind11 static bool run(const B& buf) { auto shape = FSH(); - for (std::size_t i = 0; i < shape.size(); ++i) - { - if (shape[i] != buf.shape(i)) - { - return false; - } - } - return true; + return std::equal(shape.begin(), shape.end(), buf.shape()); } }; From 82d66dd775224e9a53c81b20859a8cfc50a26aa5 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Thu, 19 May 2022 11:04:00 +0200 Subject: [PATCH 072/102] Fixed strides adaptor leading to a broadcasting issue --- include/xtensor-python/pyarray.hpp | 3 +- include/xtensor-python/pystrides_adaptor.hpp | 38 ++++++++++------ test_python/main.cpp | 27 +++++++++++ test_python/test_pyarray.py | 48 +++++++++++++++++++- 4 files changed, 100 insertions(+), 16 deletions(-) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index d80b19b..3e6a6ba 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -519,7 +519,8 @@ namespace xt m_shape = inner_shape_type(reinterpret_cast(PyArray_SHAPE(this->python_array())), static_cast(PyArray_NDIM(this->python_array()))); m_strides = inner_strides_type(reinterpret_cast(PyArray_STRIDES(this->python_array())), - static_cast(PyArray_NDIM(this->python_array()))); + static_cast(PyArray_NDIM(this->python_array())), + reinterpret_cast(PyArray_SHAPE(this->python_array()))); if (L != layout_type::dynamic && !do_strides_match(m_shape, m_strides, L, 1)) { diff --git a/include/xtensor-python/pystrides_adaptor.hpp b/include/xtensor-python/pystrides_adaptor.hpp index 161255b..fde929a 100644 --- a/include/xtensor-python/pystrides_adaptor.hpp +++ b/include/xtensor-python/pystrides_adaptor.hpp @@ -41,8 +41,10 @@ namespace xt using const_reverse_iterator = std::reverse_iterator; using reverse_iterator = const_reverse_iterator; + using shape_type = size_t*; + pystrides_adaptor() = default; - pystrides_adaptor(const_pointer data, size_type size); + pystrides_adaptor(const_pointer data, size_type size, shape_type shape); bool empty() const noexcept; size_type size() const noexcept; @@ -66,6 +68,7 @@ namespace xt const_pointer p_data; size_type m_size; + shape_type p_shape; }; /********************************** @@ -84,21 +87,23 @@ namespace xt using reference = typename pystrides_adaptor::const_reference; using difference_type = typename pystrides_adaptor::difference_type; using iterator_category = std::random_access_iterator_tag; + using shape_pointer = typename pystrides_adaptor::shape_type; - inline pystrides_iterator(pointer current) + inline pystrides_iterator(pointer current, shape_pointer shape) : p_current(current) + , p_shape(shape) { } inline reference operator*() const { - return *p_current / N; + return *p_shape == size_t(1) ? 0 : *p_current / N; } inline pointer operator->() const { // Returning the address of a temporary - value_type res = *p_current / N; + value_type res = this->operator*(); return &res; } @@ -110,12 +115,14 @@ namespace xt inline self_type& operator++() { ++p_current; + ++p_shape; return *this; } inline self_type& operator--() { --p_current; + --p_shape; return *this; } @@ -123,6 +130,7 @@ namespace xt { self_type tmp(*this); ++p_current; + ++p_shape; return tmp; } @@ -130,29 +138,32 @@ namespace xt { self_type tmp(*this); --p_current; + --p_shape; return tmp; } inline self_type& operator+=(difference_type n) { p_current += n; + p_shape += n; return *this; } inline self_type& operator-=(difference_type n) { p_current -= n; + p_shape -= n; return *this; } inline self_type operator+(difference_type n) const { - return self_type(p_current + n); + return self_type(p_current + n, p_shape + n); } inline self_type operator-(difference_type n) const { - return self_type(p_current - n); + return self_type(p_current - n, p_shape - n); } inline difference_type operator-(const self_type& rhs) const @@ -166,6 +177,7 @@ namespace xt private: pointer p_current; + shape_pointer p_shape; }; template @@ -215,8 +227,8 @@ namespace xt ************************************/ template - inline pystrides_adaptor::pystrides_adaptor(const_pointer data, size_type size) - : p_data(data), m_size(size) + inline pystrides_adaptor::pystrides_adaptor(const_pointer data, size_type size, shape_type shape) + : p_data(data), m_size(size), p_shape(shape) { } @@ -235,19 +247,19 @@ namespace xt template inline auto pystrides_adaptor::operator[](size_type i) const -> const_reference { - return p_data[i] / N; + return p_shape[i] == size_t(1) ? 0 : p_data[i] / N; } template inline auto pystrides_adaptor::front() const -> const_reference { - return p_data[0] / N; + return this->operator[](0); } template inline auto pystrides_adaptor::back() const -> const_reference { - return p_data[m_size - 1] / N; + return this->operator[](m_size - 1); } template @@ -265,13 +277,13 @@ namespace xt template inline auto pystrides_adaptor::cbegin() const -> const_iterator { - return const_iterator(p_data); + return const_iterator(p_data, p_shape); } template inline auto pystrides_adaptor::cend() const -> const_iterator { - return const_iterator(p_data + m_size); + return const_iterator(p_data + m_size, p_shape + m_size); } template diff --git a/test_python/main.cpp b/test_python/main.cpp index 5a5edfb..7a0c524 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -108,6 +108,28 @@ auto no_complex_overload_reg(const double& a) { return a; } +// +// Operator examples +// +xt::pyarray array_addition(const xt::pyarray& m, const xt::pyarray& n) +{ + return m + n; +} + +xt::pyarray array_subtraction(xt::pyarray& m, xt::pyarray& n) +{ + return m - n; +} + +xt::pyarray array_multiplication(xt::pyarray& m, xt::pyarray& n) +{ + return m * n; +} + +xt::pyarray array_division(xt::pyarray& m, xt::pyarray& n) +{ + return m / n; +} // Vectorize Examples @@ -310,6 +332,11 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("readme_example1", readme_example1); m.def("readme_example2", xt::pyvectorize(readme_example2)); + m.def("array_addition", array_addition); + m.def("array_subtraction", array_subtraction); + m.def("array_multiplication", array_multiplication); + m.def("array_division", array_division); + m.def("vectorize_example1", xt::pyvectorize(add)); m.def("rect_to_polar", xt::pyvectorize([](complex_t x) { return std::abs(x); })); diff --git a/test_python/test_pyarray.py b/test_python/test_pyarray.py index c413002..9955ee7 100644 --- a/test_python/test_pyarray.py +++ b/test_python/test_pyarray.py @@ -23,7 +23,7 @@ import numpy as np class XtensorTest(TestCase): - + """ def test_rm(self): xt.test_rm(np.array([10], dtype=int)) @@ -62,6 +62,50 @@ def test_example3(self): with self.assertRaises(TypeError): x = np.arange(3*2).reshape(3, 2) xt.example3_xfixed2(x) + """ + def test_broadcast_addition(self): + x = np.array([[2., 3., 4., 5.]]) + y = np.array([[1., 2., 3., 4.], + [1., 2., 3., 4.], + [1., 2., 3., 4.]]) + res = np.array([[3., 5., 7., 9.], + [3., 5., 7., 9.], + [3., 5., 7., 9.]]) + z = xt.array_addition(x, y) + np.testing.assert_allclose(z, res, 1e-12) + """ + def test_broadcast_subtraction(self): + x = np.array([[4., 5., 6., 7.]]) + y = np.array([[4., 3., 2., 1.], + [4., 3., 2., 1.], + [4., 3., 2., 1.]]) + res = np.array([[0., 2., 4., 6.], + [0., 2., 4., 6.], + [0., 2., 4., 6.]]) + z = xt.array_subtraction(x, y) + np.testing.assert_allclose(z, res, 1e-12) + + def test_broadcast_multiplication(self): + x = np.array([[1., 2., 3., 4.]]) + y = np.array([[3., 2., 3., 2.], + [3., 2., 3., 2.], + [3., 2., 3., 2.]]) + res = np.array([[3., 4., 9., 8.], + [3., 4., 9., 8.], + [3., 4., 9., 8.]]) + z = xt.array_multiplication(x, y) + np.testing.assert_allclose(z, res, 1e-12) + + def test_broadcast_division(self): + x = np.array([[8., 6., 4., 2.]]) + y = np.array([[2., 2., 2., 2.], + [2., 2., 2., 2.], + [2., 2., 2., 2.]]) + res = np.array([[4., 3., 2., 1.], + [4., 3., 2., 1.], + [4., 3., 2., 1.]]) + z = xt.array_division(x, y) + np.testing.assert_allclose(z, res, 1e-12) def test_vectorize(self): x1 = np.array([[0, 1], [2, 3]]) @@ -263,7 +307,7 @@ def test_native_casters(self): self.assertEqual(adapter.shape, (2, 2)) adapter[1, 1] = -3 self.assertEqual(arr[0, 5], -3) - + """ class AttributeTest(TestCase): From 6a286681c48c35d3df342f291938f4825b20c0a3 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Thu, 19 May 2022 11:25:44 +0200 Subject: [PATCH 073/102] Release 0.26.1 --- README.md | 8 +------- include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2321733..ea84fd7 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| | master | ^0.24.0 | ~2.4.3 | +| 0.26.1 | ^0.24.0 | ~2.4.3 | | 0.26.0 | ^0.24.0 | ~2.4.3 | | 0.25.3 | ^0.23.0 | ~2.4.3 | | 0.25.2 | ^0.23.0 | ~2.4.3 | @@ -211,13 +212,6 @@ from the `docs` subdirectory. | 0.25.0 | ^0.23.0 | ~2.4.3 | | 0.24.1 | ^0.21.2 | ~2.4.3 | | 0.24.0 | ^0.21.1 | ~2.4.3 | -| 0.23.2 | ^0.20.10 | ~2.4.3 | -| 0.23.1 | ^0.20.6 | ~2.2.1 | -| 0.23.0 | ^0.20.4 | ~2.2.1 | -| 0.22.x | ^0.19.0 | ~2.2.1 | -| 0.21.x | ^0.18.0 | ~2.2.1 | -| 0.20.x | ^0.17.0 | ~2.2.1 | -| 0.19.x | ^0.16.0 | ~2.2.1 | These dependencies are automatically resolved when using the conda package manager. diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 8705451..7466f14 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -12,6 +12,6 @@ #define XTENSOR_PYTHON_VERSION_MAJOR 0 #define XTENSOR_PYTHON_VERSION_MINOR 26 -#define XTENSOR_PYTHON_VERSION_PATCH 0 +#define XTENSOR_PYTHON_VERSION_PATCH 1 #endif From 0b34b856b002e1c396138e13621bd87d6822c8f5 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Wed, 11 May 2022 08:56:09 +0200 Subject: [PATCH 074/102] Making version public --- include/xtensor-python/pyarray.hpp | 1 + include/xtensor-python/pytensor.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 3e6a6ba..6df73cf 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -23,6 +23,7 @@ #include "pystrides_adaptor.hpp" #include "pynative_casters.hpp" #include "xtensor_type_caster_base.hpp" +#include "xtensor_python_config.hpp" namespace xt { diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index ce3d115..acf05b8 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -23,6 +23,7 @@ #include "pystrides_adaptor.hpp" #include "pynative_casters.hpp" #include "xtensor_type_caster_base.hpp" +#include "xtensor_python_config.hpp" namespace xt { From 001e1af36bac76a20ae38b987f8b762a44db8b9f Mon Sep 17 00:00:00 2001 From: Dominik Kutra Date: Fri, 3 Mar 2023 16:25:18 +0100 Subject: [PATCH 075/102] fixed typo --- docs/source/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 2db1f71..d37d3e9 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -27,7 +27,7 @@ Besides the xtendor-python headers, all these methods place the `cmake` project .. image:: conda.svg -Using the conda-fore package +Using the conda-forge package ---------------------------- A package for xtensor-python is available on the mamba (or conda) package manager. From 7cb644ae2c6469c745b37c878715d096aae1d157 Mon Sep 17 00:00:00 2001 From: Peter Urban Date: Fri, 10 Mar 2023 10:12:01 +0100 Subject: [PATCH 076/102] ignore unused parameter 'buf' warning (#283) --- include/xtensor-python/xtensor_type_caster_base.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 5874595..840e28c 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -107,7 +107,7 @@ namespace pybind11 struct pybind_array_dim_checker { template - static bool run(const B& buf) + static bool run(const B& /*buf*/) { return true; } @@ -138,7 +138,7 @@ namespace pybind11 struct pybind_array_shape_checker { template - static bool run(const B& buf) + static bool run(const B& /*buf*/) { return true; } From a26ca701c5fb45fcb467ffb30aa07c4c02bedf97 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 23 Mar 2023 12:17:05 +0100 Subject: [PATCH 077/102] Fixing segmentation fault scalar --- include/xtensor-python/pycontainer.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 1617d03..d0a1a1e 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -473,7 +473,11 @@ namespace xt template inline bool pycontainer::is_contiguous() const noexcept { - if (PyArray_CHKFLAGS(python_array(), NPY_ARRAY_C_CONTIGUOUS)) + if (this->strides().size() == 0) + { + return true; + } + else if (PyArray_CHKFLAGS(python_array(), NPY_ARRAY_C_CONTIGUOUS)) { return 1 == this->strides().back(); } From f7c696ec4e3ad8c69e3a46840cbf8cab9b365713 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 23 Mar 2023 12:22:53 +0100 Subject: [PATCH 078/102] Adding tests --- test/test_pyarray.cpp | 65 +++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/test/test_pyarray.cpp b/test/test_pyarray.cpp index 3f509e3..6406de6 100644 --- a/test/test_pyarray.cpp +++ b/test/test_pyarray.cpp @@ -38,12 +38,12 @@ namespace xt TEST(pyarray, initializer_constructor) { pyarray r - {{{ 0, 1, 2}, - { 3, 4, 5}, - { 6, 7, 8}}, - {{ 9, 10, 11}, - {12, 13, 14}, - {15, 16, 17}}}; + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; EXPECT_EQ(r.layout(), xt::layout_type::row_major); EXPECT_EQ(r.dimension(), 3); @@ -51,12 +51,12 @@ namespace xt EXPECT_EQ(r.shape()[0], 2); pyarray c - {{{ 0, 1, 2}, - { 3, 4, 5}, - { 6, 7, 8}}, - {{ 9, 10, 11}, - {12, 13, 14}, - {15, 16, 17}}}; + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; EXPECT_EQ(c.layout(), xt::layout_type::column_major); EXPECT_EQ(c.dimension(), 3); @@ -64,12 +64,12 @@ namespace xt EXPECT_EQ(c.shape()[0], 2); pyarray d - {{{ 0, 1, 2}, - { 3, 4, 5}, - { 6, 7, 8}}, - {{ 9, 10, 11}, - {12, 13, 14}, - {15, 16, 17}}}; + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; EXPECT_EQ(d.layout(), xt::layout_type::row_major); EXPECT_EQ(d.dimension(), 3); @@ -77,6 +77,29 @@ namespace xt EXPECT_EQ(d.shape()[0], 2); } + TEST(pyarray, expression) + { + pyarray a = xt::empty({}); + + EXPECT_EQ(a.layout(), xt::layout_type::row_major); + EXPECT_EQ(a.dimension(), 0); + EXPECT_EQ(a.size(), 1); + + pyarray b = xt::empty({5}); + + EXPECT_EQ(b.layout(), xt::layout_type::row_major); + EXPECT_EQ(b.dimension(), 1); + EXPECT_EQ(b.size(), 5); + + pyarray c = xt::empty({5, 3}); + + EXPECT_EQ(c.layout(), xt::layout_type::row_major); + EXPECT_EQ(c.dimension(), 2); + EXPECT_EQ(c.size(), 15); + EXPECT_EQ(c.shape(0), 5); + EXPECT_EQ(c.shape(1), 3); + } + TEST(pyarray, shaped_constructor) { { @@ -86,7 +109,7 @@ namespace xt compare_shape(ra, rm); EXPECT_EQ(layout_type::row_major, ra.layout()); } - + { SCOPED_TRACE("column_major constructor"); column_major_result<> cm; @@ -150,7 +173,7 @@ namespace xt central_major_result<> res; int value = 2; pyarray a(res.m_shape, res.m_strides, value); - + { SCOPED_TRACE("copy constructor"); pyarray b(a); @@ -277,7 +300,7 @@ namespace xt EXPECT_EQ(2, a1(1)); EXPECT_EQ(4, a2(1, 1)); } - + TEST(pyarray, zerod) { pyarray a; From 77aa5324d1ca0af94e8398f36525df34065424dd Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Sun, 29 Oct 2023 20:14:04 +0100 Subject: [PATCH 079/102] Fixed RTD build --- docs/environment.yml | 1 + readthedocs.yml | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/environment.yml b/docs/environment.yml index 47e93f7..1e6e74a 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -5,3 +5,4 @@ channels: dependencies: - breathe + - sphinx_rtd_theme diff --git a/readthedocs.yml b/readthedocs.yml index 02f0e7b..38f414b 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -1,2 +1,9 @@ +version: 2 + +build: + os: "ubuntu-22.04" + tools: + python: "mambaforge-22.9" + conda: - file: docs/environment.yml + environment: docs/environment.yml From a2d39e8c42744744711756110712f962174d90ca Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Sun, 29 Oct 2023 20:24:56 +0100 Subject: [PATCH 080/102] add_stylesheet -> add_css_file --- docs/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 3b428b8..f611998 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,7 +16,7 @@ html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] def setup(app): - app.add_stylesheet("main_stylesheet.css") + app.add_css_file("main_stylesheet.css") extensions = ['breathe'] breathe_projects = { 'xtensor-python': '../xml' } From 88734bd8f5088d48de8f5160a3984272cdb0a30b Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Thu, 2 Nov 2023 16:27:55 +0100 Subject: [PATCH 081/102] Fixed the jQuery not loaded issue on RTD page --- docs/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index f611998..7fcaddc 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -18,7 +18,7 @@ def setup(app): app.add_css_file("main_stylesheet.css") -extensions = ['breathe'] +extensions = ['breathe', 'sphinx_rtd_theme'] breathe_projects = { 'xtensor-python': '../xml' } templates_path = ['_templates'] html_static_path = ['_static'] From d212bc35fa61e5e7a9f56dfd31e121fe59752340 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 16 Jan 2024 18:04:02 +0100 Subject: [PATCH 082/102] Added linux CI with GHA --- .github/workflows/linux.yml | 110 ++++++++++++++++++++++++++++++++++++ azure-pipelines.yml | 8 --- environment-dev.yml | 1 + 3 files changed, 111 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/linux.yml delete mode 100644 azure-pipelines.yml diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 0000000..ce8249d --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,110 @@ +name: Linux +on: + workflow_dispatch: + pull_request: + push: + branches: [master] +concurrency: + group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }} + cancel-in-progress: true +defaults: + run: + shell: bash -e -l {0} +jobs: + build: + runs-on: ubuntu-20.04 + name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.name }} + strategy: + fail-fast: false + matrix: + sys: + - {compiler: gcc, version: '8'} + - {compiler: gcc, version: '9'} + - {compiler: gcc, version: '10'} + - {compiler: gcc, version: '11'} + + steps: + + - name: Setup GCC + if: ${{ matrix.sys.compiler == 'gcc' }} + run: | + GCC_VERSION=${{ matrix.sys.version }} + sudo apt-get update + sudo apt-get --no-install-suggests --no-install-recommends install g++-$GCC_VERSION + CC=gcc-$GCC_VERSION + echo "CC=$CC" >> $GITHUB_ENV + CXX=g++-$GCC_VERSION + echo "CXX=$CXX" >> $GITHUB_ENV + + - name: Setup clang + if: ${{ matrix.sys.compiler == 'clang' }} + run: | + LLVM_VERSION=${{ matrix.sys.version }} + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - || exit 1 + if [[ $LLVM_VERSION -ge 13 ]]; then + sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-$LLVM_VERSION main" || exit 1 + else + sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" || exit 1 + fi || exit 1 + sudo apt-get update || exit 1 + sudo apt-get --no-install-suggests --no-install-recommends install clang-$LLVM_VERSION || exit 1 + sudo apt-get --no-install-suggests --no-install-recommends install g++-9 g++-9-multilib || exit 1 + sudo ln -s /usr/include/asm-generic /usr/include/asm + CC=clang-$LLVM_VERSION + echo "CC=$CC" >> $GITHUB_ENV + CXX=clang++-$LLVM_VERSION + echo "CXX=$CXX" >> $GITHUB_ENV + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set conda environment + uses: mamba-org/setup-micromamba@v1 + with: + environment-file: environment-dev.yml + cache-environment: true + + - name: Configure using CMake + run: cmake -G Ninja -Bbuild -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory) + + - name: Install + working-directory: build + run: cmake --install . + + - name: Build + working-directory: build + run: cmake --build . --target test_xtensor_python --parallel 8 + + - name: Run tests (C++) + working-directory: build/test + run: ./test_xtensor_python + + - name: Run tests (Python) + run: pytest -s + + - name: Example - readme 1 + working-directory: docs/source/examples/readme_example_1 + run: | + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build + cmake --build . + cp ../example.py . + python example.py + + - name: Example - copy \'cast\' + working-directory: docs/source/examples/copy_cast + run: | + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build + cmake --build . + cp ../example.py . + python example.py + + - name: Example - SFINAE + working-directory: docs/source/examples/sfinae + run: | + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build + cmake --build . + cp ../example.py . + python example.py diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index e930dbe..0000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,8 +0,0 @@ -trigger: - - master - -jobs: - - template: ./.azure-pipelines/azure-pipelines-linux-clang.yml - - template: ./.azure-pipelines/azure-pipelines-linux-gcc.yml - - template: ./.azure-pipelines/azure-pipelines-osx.yml - diff --git a/environment-dev.yml b/environment-dev.yml index 6dff19f..d9fbd45 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -4,6 +4,7 @@ channels: dependencies: # Build dependencies - cmake + - ninja # Host dependencies - xtensor=0.24.0 - numpy From 522fbdb227f896c095150d5e124d7e998984ef20 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 16 Jan 2024 22:03:43 +0100 Subject: [PATCH 083/102] Added Windows and OSX workflows --- .github/workflows/linux.yml | 4 +- .github/workflows/osx.yml | 78 +++++++++++++++++++++++++++++++++++ .github/workflows/windows.yml | 48 +++++++++++++++++++++ 3 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/osx.yml create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ce8249d..264a996 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -13,7 +13,7 @@ defaults: jobs: build: runs-on: ubuntu-20.04 - name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} - ${{ matrix.sys.name }} + name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} strategy: fail-fast: false matrix: @@ -22,6 +22,8 @@ jobs: - {compiler: gcc, version: '9'} - {compiler: gcc, version: '10'} - {compiler: gcc, version: '11'} + - {compiler: clang, version: '15'} + - {compiler: clang, version: '16'} steps: diff --git a/.github/workflows/osx.yml b/.github/workflows/osx.yml new file mode 100644 index 0000000..073c018 --- /dev/null +++ b/.github/workflows/osx.yml @@ -0,0 +1,78 @@ +name: OSX +on: + workflow_dispatch: + pull_request: + push: + branches: [master] +concurrency: + group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }} + cancel-in-progress: true +defaults: + run: + shell: bash -e -l {0} +jobs: + build: + runs-on: macos-${{ matrix.os }} + name: macos-${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - 11 + - 12 + + steps: + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set conda environment + uses: mamba-org/setup-micromamba@v1 + with: + environment-file: environment-dev.yml + cache-environment: true + + - name: Configure using CMake + run: cmake -G Ninja -Bbuild -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory) + + - name: Install + working-directory: build + run: cmake --install . + + - name: Build + working-directory: build + run: cmake --build . --target test_xtensor_python --parallel 8 + + - name: Run tests (C++) + working-directory: build/test + run: ./test_xtensor_python + + - name: Run tests (Python) + run: pytest -s + + - name: Example - readme 1 + working-directory: docs/source/examples/readme_example_1 + run: | + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build + cmake --build . + cp ../example.py . + python example.py + + - name: Example - copy \'cast\' + working-directory: docs/source/examples/copy_cast + run: | + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build + cmake --build . + cp ../example.py . + python example.py + + - name: Example - SFINAE + working-directory: docs/source/examples/sfinae + run: | + cmake -Bbuild -DPython_EXECUTABLE=`which python` + cd build + cmake --build . + cp ../example.py . + python example.py diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000..4137294 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,48 @@ +name: Windows +on: + #workflow_dispatch: + #pull_request: + #push: + # branches: [master] +concurrency: + group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }} + cancel-in-progress: true +defaults: + run: + shell: bash -e -l {0} +jobs: + build: + runs-on: [windows-latest] + name: Windows + + steps: + + - name: Setup MSVC + uses: ilammy/msvc-dev-cmd@v1 + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set conda environment + uses: mamba-org/setup-micromamba@v1 + with: + environment-file: environment-dev.yml + cache-environment: true + + - name: Configure using CMake + run: cmake -G Ninja -Bbuild -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory) + + - name: Install + working-directory: build + run: cmake --install . + + - name: Build + working-directory: build + run: cmake --build . --target test_xtensor_python --parallel 8 + + - name: Run tests (C++) + working-directory: build/test + run: ./test_xtensor_python + + - name: Run tests (Python) + run: pytest -s From 125c226f14052ec35dfd47ab2447eb5610cfefd9 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 16 Jan 2024 22:31:00 +0100 Subject: [PATCH 084/102] Removed old CI files --- .appveyor.yml | 35 ---------- .../azure-pipelines-linux-clang.yml | 38 ----------- .../azure-pipelines-linux-gcc.yml | 33 --------- .azure-pipelines/azure-pipelines-osx.yml | 28 -------- .azure-pipelines/unix-build.yml | 68 ------------------- 5 files changed, 202 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .azure-pipelines/azure-pipelines-linux-clang.yml delete mode 100644 .azure-pipelines/azure-pipelines-linux-gcc.yml delete mode 100644 .azure-pipelines/azure-pipelines-osx.yml delete mode 100644 .azure-pipelines/unix-build.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 91cebe4..0000000 --- a/.appveyor.yml +++ /dev/null @@ -1,35 +0,0 @@ -build: false - -os: Visual Studio 2015 - -platform: - - x64 - -environment: - matrix: - - MINICONDA: C:\xtensor-conda - -init: - - "ECHO %MINICONDA%" - - C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\VC\vcvarsall.bat %PLATFORM% - - ps: if($env:Platform -eq "x64"){Start-FileDownload 'http://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86_64.exe' C:\Miniconda.exe; echo "Done"} - - ps: if($env:Platform -eq "x86"){Start-FileDownload 'http://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86.exe' C:\Miniconda.exe; echo "Done"} - - cmd: C:\Miniconda.exe /S /D=C:\xtensor-conda - - "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%MINICONDA%\\Library\\bin;%PATH%" - -install: - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - - conda info -a - - conda install mamba -c conda-forge - - mamba install cmake pytest numpy pybind11 xtensor==0.24.0 -c conda-forge - - "set PYTHONHOME=%MINICONDA%" - - cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -D BUILD_TESTS=ON -D PYTHON_EXECUTABLE=%MINICONDA%\\python.exe -DDOWNLOAD_GTEST=ON . - - nmake test_xtensor_python - - nmake install - - rmdir /s/q "test/googletest-src" - -build_script: - - py.test -s - - cd test - - .\test_xtensor_python diff --git a/.azure-pipelines/azure-pipelines-linux-clang.yml b/.azure-pipelines/azure-pipelines-linux-clang.yml deleted file mode 100644 index 87d7592..0000000 --- a/.azure-pipelines/azure-pipelines-linux-clang.yml +++ /dev/null @@ -1,38 +0,0 @@ -jobs: - - job: 'Linux_0' - strategy: - matrix: - clang_6: - llvm_version: '6.0' - clang_7: - llvm_version: '7' - clang_8: - llvm_version: '8' - clang_9: - llvm_version: '9' - pool: - vmImage: ubuntu-18.04 - variables: - CC: clang-$(llvm_version) - CXX: clang++-$(llvm_version) - timeoutInMinutes: 360 - steps: - - - script: | - sudo add-apt-repository ppa:ubuntu-toolchain-r/test - if [[ $(llvm_version) == '4.0' || $(llvm_version) == '5.0' ]]; then - sudo apt-get update - sudo apt-get --no-install-suggests --no-install-recommends install gcc-4.9 clang-$(llvm_version) - else - LLVM_VERSION=$(llvm_version) - get -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-$LLVM_VERSION main" - sudo apt-get update - sudo apt-get --no-install-suggests --no-install-recommends install clang-$(llvm_version) - fi - displayName: Install build toolchain - - - bash: echo "##vso[task.prependpath]$CONDA/bin" - displayName: Add conda to PATH - - - template: unix-build.yml diff --git a/.azure-pipelines/azure-pipelines-linux-gcc.yml b/.azure-pipelines/azure-pipelines-linux-gcc.yml deleted file mode 100644 index e0a6aa0..0000000 --- a/.azure-pipelines/azure-pipelines-linux-gcc.yml +++ /dev/null @@ -1,33 +0,0 @@ -jobs: - - job: 'Linux_1' - strategy: - matrix: - gcc_6: - gcc_version: '6' - gcc_7: - gcc_version: '7' - gcc_8: - gcc_version: '8' - gcc_9: - gcc_version: '9' - pool: - vmImage: ubuntu-18.04 - variables: - CC: gcc-$(gcc_version) - CXX: g++-$(gcc_version) - timeoutInMinutes: 360 - steps: - - - script: | - if [[ $(gcc_version) == '4.9' || $(gcc_version) == '6' || $(gcc_version) == '7' || $(gcc_version) == '8' ]]; then - sudo add-apt-repository ppa:ubuntu-toolchain-r/test - sudo apt-get update - sudo apt-get --no-install-suggests --no-install-recommends install g++-$(gcc_version) - fi - displayName: Install build toolchain - - - bash: echo "##vso[task.prependpath]$CONDA/bin" - displayName: Add conda to PATH - - - template: unix-build.yml - diff --git a/.azure-pipelines/azure-pipelines-osx.yml b/.azure-pipelines/azure-pipelines-osx.yml deleted file mode 100644 index beeafce..0000000 --- a/.azure-pipelines/azure-pipelines-osx.yml +++ /dev/null @@ -1,28 +0,0 @@ -jobs: - - job: 'OSX' - strategy: - matrix: - macOS_10_15: - image_name: 'macOS-10.15' - macOS_11: - image_name: 'macOS-11' - pool: - vmImage: $(image_name) - variables: - CC: clang - CXX: clang++ - timeoutInMinutes: 360 - steps: - - script: | - echo "Removing homebrew for Azure to avoid conflicts with conda" - curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall > ~/uninstall_homebrew - chmod +x ~/uninstall_homebrew - ~/uninstall_homebrew -f -q - displayName: Remove homebrew - - - bash: | - echo "##vso[task.prependpath]$CONDA/bin" - sudo chown -R $USER $CONDA - displayName: Add conda to PATH - - - template: unix-build.yml diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml deleted file mode 100644 index 97cb405..0000000 --- a/.azure-pipelines/unix-build.yml +++ /dev/null @@ -1,68 +0,0 @@ -steps: - - script: | - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda env create --file environment-dev.yml - source activate xtensor-python - displayName: Install dependencies - - - script: | - source activate xtensor-python - mkdir build - cd build - cmake -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory) - make install - displayName: Configure xtensor-python - workingDirectory: $(Build.BinariesDirectory) - - - script: | - source activate xtensor-python - make -j2 test_xtensor_python - displayName: Build xtensor-python - workingDirectory: $(Build.BinariesDirectory)/build - - - script: | - source activate xtensor-python - cd test - ./test_xtensor_python - displayName: Test xtensor-python (C++) - workingDirectory: $(Build.BinariesDirectory)/build/test - - - script: | - source activate xtensor-python - py.test -s - displayName: Test xtensor-python (Python) - workingDirectory: $(Build.SourcesDirectory) - - - script: | - source activate xtensor-python - cmake -Bbuild -DPython_EXECUTABLE=`which python` - cd build - cmake --build . - cp ../example.py . - python example.py - cd .. - displayName: Example - readme 1 - workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1 - - - script: | - source activate xtensor-python - cmake -Bbuild -DPython_EXECUTABLE=`which python` - cd build - cmake --build . - cp ../example.py . - python example.py - cd .. - displayName: Example - Copy 'cast' - workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/copy_cast - - - script: | - source activate xtensor-python - cmake -Bbuild -DPython_EXECUTABLE=`which python` - cd build - cmake --build . - cp ../example.py . - python example.py - cd .. - displayName: Example - SFINAE - workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/sfinae From 3df4fa53095a1ff0ae40584afcc769287f2b90e7 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 29 Jan 2024 22:33:54 +0100 Subject: [PATCH 085/102] Upgraded to pybind11 >2.6 --- CMakeLists.txt | 11 ++++++++--- environment-dev.yml | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1bd077..312ccd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,13 +45,18 @@ else() find_package(xtensor ${xtensor_REQUIRED_VERSION} REQUIRED) message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor") endif() - -# Currently no required version for pybind11 + +# Running find_package(PythonInterp) to retrieve the Python version +# which is not exported by Pybind11's cmake. +# Cf. https://github.com/pybind/pybind11/issues/2268 +find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED) + +set(pybind11_REQUIRED_VERSION 2.6.1) if(TARGET pybind11 OR TARGET pybind11::headers) # pybind11 has a variable that indicates its version already, so use that message(STATUS "Found pybind11 v${pybind11_VERSION}") else() - find_package(pybind11 REQUIRED) + find_package(pybind11 ${pybind11_REQUIRED_VERSION} REQUIRED) message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") endif() diff --git a/environment-dev.yml b/environment-dev.yml index d9fbd45..9eca6e7 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -6,9 +6,9 @@ dependencies: - cmake - ninja # Host dependencies - - xtensor=0.24.0 + - xtensor>=0.24,<0.25 - numpy - - pybind11=2.4.3 + - pybind11>=2.6.1,<3 # Test dependencies - pytest From ef601e8eafe0879b8d8c01ffdc4aa321d3595fde Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Wed, 17 Jan 2024 10:07:11 +0100 Subject: [PATCH 086/102] Enabling CI on Windows --- .github/workflows/windows.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4137294..6743937 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,9 +1,9 @@ name: Windows on: - #workflow_dispatch: - #pull_request: - #push: - # branches: [master] + workflow_dispatch: + pull_request: + push: + branches: [master] concurrency: group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }} cancel-in-progress: true From 0632752e89c8cfb2a79acf0214e18f86617d02ca Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 29 Jan 2024 22:16:52 +0100 Subject: [PATCH 087/102] Disabled test leading to compilation error on Windows --- test/test_common.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_common.hpp b/test/test_common.hpp index 07a0992..3b4ed85 100644 --- a/test/test_common.hpp +++ b/test/test_common.hpp @@ -160,7 +160,10 @@ namespace xt { EXPECT_TRUE(std::equal(vec.shape().cbegin(), vec.shape().cend(), result.shape().cbegin())); EXPECT_TRUE(std::equal(vec.strides().cbegin(), vec.strides().cend(), result.strides().cbegin())); +// TODO: check why this does not build on modern MSVC compilers +#ifndef WIN32 EXPECT_TRUE(std::equal(vec.backstrides().cbegin(), vec.backstrides().cend(), result.backstrides().cbegin())); +#endif EXPECT_EQ(vec.size(), result.size()); if (compare_layout) { From 9ddffd2c50e8ed38760c4998f983c5bd5e55e5af Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 29 Jan 2024 22:59:01 +0100 Subject: [PATCH 088/102] Updated CI badges in README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ea84fd7..e8b2491 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # ![xtensor-python](docs/source/xtensor-python.svg) -[![Azure Pipelines](https://dev.azure.com/xtensor-stack/xtensor-stack/_apis/build/status/xtensor-stack.xtensor-python?branchName=master)](https://dev.azure.com/xtensor-stack/xtensor-stack/_build/latest?definitionId=7&branchName=master) -[![Appveyor](https://ci.appveyor.com/api/projects/status/4j2yd6k8o5xbimqf?svg=true)](https://ci.appveyor.com/project/xtensor-stack/xtensor-python) +[![GHA Linux](https://github.com/xtensor-stack/xtensor/actions/workflows/linux.yml/badge.svg)](https://github.com/xtensor-stack/xtensor/actions/workflows/linux.yml) +[![GHA OSX](https://github.com/xtensor-stack/xtensor/actions/workflows/osx.yml/badge.svg)](https://github.com/xtensor-stack/xtensor/actions/workflows/osx.yml) +[![GHA Windows](https://github.com/xtensor-stack/xtensor/actions/workflows/windows.yml/badge.svg)](https://github.com/xtensor-stack/xtensor/actions/workflows/windows.yml) [![Documentation](http://readthedocs.org/projects/xtensor-python/badge/?version=latest)](https://xtensor-python.readthedocs.io/en/latest/?badge=latest) [![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 6cc16df1f3f730b15afbd5c82873c53e7e54327d Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 29 Jan 2024 23:00:16 +0100 Subject: [PATCH 089/102] Upgraded to xtensor 0.25.0 --- CMakeLists.txt | 2 +- environment-dev.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 312ccd8..2807404 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ message(STATUS "xtensor-python v${${PROJECT_NAME}_VERSION}") # Dependencies # ============ -set(xtensor_REQUIRED_VERSION 0.24.0) +set(xtensor_REQUIRED_VERSION 0.25.0) if(TARGET xtensor) set(xtensor_VERSION ${XTENSOR_VERSION_MAJOR}.${XTENSOR_VERSION_MINOR}.${XTENSOR_VERSION_PATCH}) # Note: This is not SEMVER compatible comparison diff --git a/environment-dev.yml b/environment-dev.yml index 9eca6e7..122bf4d 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -6,7 +6,7 @@ dependencies: - cmake - ninja # Host dependencies - - xtensor>=0.24,<0.25 + - xtensor>=0.25,<0.26 - numpy - pybind11>=2.6.1,<3 # Test dependencies From 3ffb0e414b8fb1d2e1b73c1e5104f32c940c4ea5 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Tue, 28 Nov 2023 16:13:18 +0100 Subject: [PATCH 090/102] Use FindPython's numpy component to find numpy include directories --- CMakeLists.txt | 8 ++-- cmake/FindNumPy.cmake | 89 ------------------------------------------- 2 files changed, 4 insertions(+), 93 deletions(-) delete mode 100644 cmake/FindNumPy.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 2807404..319dfeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ # The full license is in the file LICENSE, distributed with this software. # ############################################################################ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.14) project(xtensor-python) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) @@ -60,8 +60,8 @@ else() message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") endif() -find_package(NumPy REQUIRED) -message(STATUS "Found numpy: ${NUMPY_INCLUDE_DIRS}") +# Look for NumPy headers +find_package(Python REQUIRED COMPONENTS NumPy) # Build # ===== @@ -80,7 +80,7 @@ set(XTENSOR_PYTHON_HEADERS add_library(xtensor-python INTERFACE) target_include_directories(xtensor-python INTERFACE - "$" + "$" $) target_link_libraries(xtensor-python INTERFACE xtensor) get_target_property(inc_dir xtensor-python INTERFACE_INCLUDE_DIRECTORIES) diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake deleted file mode 100644 index f043566..0000000 --- a/cmake/FindNumPy.cmake +++ /dev/null @@ -1,89 +0,0 @@ -# - Find the NumPy libraries -# This module finds if NumPy is installed, and sets the following variables -# indicating where it is. -# -# TODO: Update to provide the libraries and paths for linking npymath lib. -# -# NUMPY_FOUND - was NumPy found -# NUMPY_VERSION - the version of NumPy found as a string -# NUMPY_VERSION_MAJOR - the major version number of NumPy -# NUMPY_VERSION_MINOR - the minor version number of NumPy -# NUMPY_VERSION_PATCH - the patch version number of NumPy -# NUMPY_VERSION_DECIMAL - e.g. version 1.6.1 is 10601 -# NUMPY_INCLUDE_DIRS - path to the NumPy include files - -#============================================================================ -# Copyright 2012 Continuum Analytics, Inc. -# -# MIT License -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files -# (the "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to permit -# persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -#============================================================================ - -# Finding NumPy involves calling the Python interpreter -if(NumPy_FIND_REQUIRED) - find_package(PythonInterp REQUIRED) -else() - find_package(PythonInterp) -endif() - -if(NOT PYTHONINTERP_FOUND) - set(NUMPY_FOUND FALSE) -endif() - -execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import numpy as n; print(n.__version__); print(n.get_include());" - RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS - OUTPUT_VARIABLE _NUMPY_VALUES - ERROR_VARIABLE _NUMPY_ERROR_VALUE - OUTPUT_STRIP_TRAILING_WHITESPACE) - -if(NOT _NUMPY_SEARCH_SUCCESS MATCHES 0) - if(NumPy_FIND_REQUIRED) - message(FATAL_ERROR - "NumPy import failure:\n${_NUMPY_ERROR_VALUE}") - endif() - set(NUMPY_FOUND FALSE) -endif() - -# Convert the process output into a list -string(REGEX REPLACE ";" "\\\\;" _NUMPY_VALUES ${_NUMPY_VALUES}) -string(REGEX REPLACE "\n" ";" _NUMPY_VALUES ${_NUMPY_VALUES}) -list(GET _NUMPY_VALUES 0 NUMPY_VERSION) -list(GET _NUMPY_VALUES 1 NUMPY_INCLUDE_DIRS) - -# Make sure all directory separators are '/' -string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIRS}) - -# Get the major and minor version numbers -string(REGEX REPLACE "\\." ";" _NUMPY_VERSION_LIST ${NUMPY_VERSION}) -list(GET _NUMPY_VERSION_LIST 0 NUMPY_VERSION_MAJOR) -list(GET _NUMPY_VERSION_LIST 1 NUMPY_VERSION_MINOR) -list(GET _NUMPY_VERSION_LIST 2 NUMPY_VERSION_PATCH) -string(REGEX MATCH "[0-9]*" NUMPY_VERSION_PATCH ${NUMPY_VERSION_PATCH}) -math(EXPR NUMPY_VERSION_DECIMAL - "(${NUMPY_VERSION_MAJOR} * 10000) + (${NUMPY_VERSION_MINOR} * 100) + ${NUMPY_VERSION_PATCH}") - -find_package_message(NUMPY - "Found NumPy: version \"${NUMPY_VERSION}\" ${NUMPY_INCLUDE_DIRS}" - "${NUMPY_INCLUDE_DIRS}${NUMPY_VERSION}") - -set(NUMPY_FOUND TRUE) From 96b5cd92e26056d491beeb8593160197ed08f7c0 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 29 Jan 2024 23:18:23 +0100 Subject: [PATCH 091/102] only search for numpy when the numpy-include directory is not passed --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 319dfeb..6521c98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,8 +60,12 @@ else() message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") endif() -# Look for NumPy headers -find_package(Python REQUIRED COMPONENTS NumPy) +# Look for NumPy headers, except if NUMPY_INCLUDE_DIRS is passed, +# which is required under some circumstances (such as wasm, where +# there is no real python executable) +if(NOT NUMPY_INCLUDE_DIRS) + find_package(Python REQUIRED COMPONENTS NumPy) +endif() # Build # ===== From a7c20058ce39447d84714f6e09bfd463d654af47 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 29 Jan 2024 23:29:40 +0100 Subject: [PATCH 092/102] Release 0.27.0 --- README.md | 3 ++- include/xtensor-python/xtensor_python_config.hpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e8b2491..2cff672 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,8 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.24.0 | ~2.4.3 | +| master | ^0.25.0 | >=2.6.1,<3 | +| 0.27.0 | ^0.25.0 | >=2.6.1,<3 | | 0.26.1 | ^0.24.0 | ~2.4.3 | | 0.26.0 | ^0.24.0 | ~2.4.3 | | 0.25.3 | ^0.23.0 | ~2.4.3 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 7466f14..c3f6707 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -11,7 +11,7 @@ #define XTENSOR_PYTHON_CONFIG_HPP #define XTENSOR_PYTHON_VERSION_MAJOR 0 -#define XTENSOR_PYTHON_VERSION_MINOR 26 -#define XTENSOR_PYTHON_VERSION_PATCH 1 +#define XTENSOR_PYTHON_VERSION_MINOR 27 +#define XTENSOR_PYTHON_VERSION_PATCH 0 #endif From 9b7cb5e322f1e9febd1019b53541d1b9c51af292 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 30 Jan 2024 09:05:31 +0100 Subject: [PATCH 093/102] Temporary revert to find_numpy to fix the feedstock --- CMakeLists.txt | 5 ++- cmake/FindNumPy.cmake | 89 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 cmake/FindNumPy.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 6521c98..b17b005 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,8 +64,9 @@ endif() # which is required under some circumstances (such as wasm, where # there is no real python executable) if(NOT NUMPY_INCLUDE_DIRS) - find_package(Python REQUIRED COMPONENTS NumPy) + find_package(NumPy REQUIRED) endif() +message(STATUS "Found numpy: ${NUMPY_INCLUDE_DIRS}") # Build # ===== @@ -84,7 +85,7 @@ set(XTENSOR_PYTHON_HEADERS add_library(xtensor-python INTERFACE) target_include_directories(xtensor-python INTERFACE - "$" + "$" $) target_link_libraries(xtensor-python INTERFACE xtensor) get_target_property(inc_dir xtensor-python INTERFACE_INCLUDE_DIRECTORIES) diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake new file mode 100644 index 0000000..f043566 --- /dev/null +++ b/cmake/FindNumPy.cmake @@ -0,0 +1,89 @@ +# - Find the NumPy libraries +# This module finds if NumPy is installed, and sets the following variables +# indicating where it is. +# +# TODO: Update to provide the libraries and paths for linking npymath lib. +# +# NUMPY_FOUND - was NumPy found +# NUMPY_VERSION - the version of NumPy found as a string +# NUMPY_VERSION_MAJOR - the major version number of NumPy +# NUMPY_VERSION_MINOR - the minor version number of NumPy +# NUMPY_VERSION_PATCH - the patch version number of NumPy +# NUMPY_VERSION_DECIMAL - e.g. version 1.6.1 is 10601 +# NUMPY_INCLUDE_DIRS - path to the NumPy include files + +#============================================================================ +# Copyright 2012 Continuum Analytics, Inc. +# +# MIT License +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#============================================================================ + +# Finding NumPy involves calling the Python interpreter +if(NumPy_FIND_REQUIRED) + find_package(PythonInterp REQUIRED) +else() + find_package(PythonInterp) +endif() + +if(NOT PYTHONINTERP_FOUND) + set(NUMPY_FOUND FALSE) +endif() + +execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "import numpy as n; print(n.__version__); print(n.get_include());" + RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS + OUTPUT_VARIABLE _NUMPY_VALUES + ERROR_VARIABLE _NUMPY_ERROR_VALUE + OUTPUT_STRIP_TRAILING_WHITESPACE) + +if(NOT _NUMPY_SEARCH_SUCCESS MATCHES 0) + if(NumPy_FIND_REQUIRED) + message(FATAL_ERROR + "NumPy import failure:\n${_NUMPY_ERROR_VALUE}") + endif() + set(NUMPY_FOUND FALSE) +endif() + +# Convert the process output into a list +string(REGEX REPLACE ";" "\\\\;" _NUMPY_VALUES ${_NUMPY_VALUES}) +string(REGEX REPLACE "\n" ";" _NUMPY_VALUES ${_NUMPY_VALUES}) +list(GET _NUMPY_VALUES 0 NUMPY_VERSION) +list(GET _NUMPY_VALUES 1 NUMPY_INCLUDE_DIRS) + +# Make sure all directory separators are '/' +string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIRS}) + +# Get the major and minor version numbers +string(REGEX REPLACE "\\." ";" _NUMPY_VERSION_LIST ${NUMPY_VERSION}) +list(GET _NUMPY_VERSION_LIST 0 NUMPY_VERSION_MAJOR) +list(GET _NUMPY_VERSION_LIST 1 NUMPY_VERSION_MINOR) +list(GET _NUMPY_VERSION_LIST 2 NUMPY_VERSION_PATCH) +string(REGEX MATCH "[0-9]*" NUMPY_VERSION_PATCH ${NUMPY_VERSION_PATCH}) +math(EXPR NUMPY_VERSION_DECIMAL + "(${NUMPY_VERSION_MAJOR} * 10000) + (${NUMPY_VERSION_MINOR} * 100) + ${NUMPY_VERSION_PATCH}") + +find_package_message(NUMPY + "Found NumPy: version \"${NUMPY_VERSION}\" ${NUMPY_INCLUDE_DIRS}" + "${NUMPY_INCLUDE_DIRS}${NUMPY_VERSION}") + +set(NUMPY_FOUND TRUE) From 021eeae29d105bcb04876b03133a8335a2e6adda Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Tue, 6 Aug 2024 15:08:32 +0200 Subject: [PATCH 094/102] Test with NumPy 2.0 --- .github/workflows/linux.yml | 4 ++-- environment-dev.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 264a996..0c8e40e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -12,16 +12,16 @@ defaults: shell: bash -e -l {0} jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} strategy: fail-fast: false matrix: sys: - - {compiler: gcc, version: '8'} - {compiler: gcc, version: '9'} - {compiler: gcc, version: '10'} - {compiler: gcc, version: '11'} + - {compiler: gcc, version: '12'} - {compiler: clang, version: '15'} - {compiler: clang, version: '16'} diff --git a/environment-dev.yml b/environment-dev.yml index 122bf4d..1c2bd8b 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -7,8 +7,8 @@ dependencies: - ninja # Host dependencies - xtensor>=0.25,<0.26 - - numpy - - pybind11>=2.6.1,<3 + - numpy>=2.0 + - pybind11>=2.12.0,<3 # Test dependencies - pytest From d1c21100b852630073f5aca32b0199c15d9eff95 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 11 Apr 2025 10:01:08 +0200 Subject: [PATCH 095/102] Upgraded CI compilers (#319) --- .github/workflows/linux.yml | 58 ++++++++----------- .github/workflows/osx.yml | 5 +- CMakeLists.txt | 20 +++---- cmake/FindNumPy.cmake | 4 +- docs/source/examples/copy_cast/CMakeLists.txt | 2 +- .../examples/readme_example_1/CMakeLists.txt | 2 +- docs/source/examples/sfinae/CMakeLists.txt | 2 +- environment-dev.yml | 1 + test/CMakeLists.txt | 2 +- test/copyGTest.cmake.in | 2 +- test/downloadGTest.cmake.in | 4 +- 11 files changed, 48 insertions(+), 54 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0c8e40e..ea4dee7 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -12,50 +12,42 @@ defaults: shell: bash -e -l {0} jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 name: ${{ matrix.sys.compiler }} ${{ matrix.sys.version }} strategy: fail-fast: false matrix: sys: - - {compiler: gcc, version: '9'} - - {compiler: gcc, version: '10'} - {compiler: gcc, version: '11'} - {compiler: gcc, version: '12'} - - {compiler: clang, version: '15'} - - {compiler: clang, version: '16'} + - {compiler: gcc, version: '13'} + - {compiler: gcc, version: '14'} + - {compiler: clang, version: '17'} + - {compiler: clang, version: '18'} + - {compiler: clang, version: '19'} + - {compiler: clang, version: '20'} steps: + - name: Install GCC + if: matrix.sys.compiler == 'gcc' + uses: egor-tensin/setup-gcc@v1 + with: + version: ${{matrix.sys.version}} + platform: x64 - - name: Setup GCC - if: ${{ matrix.sys.compiler == 'gcc' }} - run: | - GCC_VERSION=${{ matrix.sys.version }} - sudo apt-get update - sudo apt-get --no-install-suggests --no-install-recommends install g++-$GCC_VERSION - CC=gcc-$GCC_VERSION - echo "CC=$CC" >> $GITHUB_ENV - CXX=g++-$GCC_VERSION - echo "CXX=$CXX" >> $GITHUB_ENV - - - name: Setup clang - if: ${{ matrix.sys.compiler == 'clang' }} + - name: Install LLVM and Clang + if: matrix.sys.compiler == 'clang' run: | - LLVM_VERSION=${{ matrix.sys.version }} - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - || exit 1 - if [[ $LLVM_VERSION -ge 13 ]]; then - sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-$LLVM_VERSION main" || exit 1 - else - sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" || exit 1 - fi || exit 1 - sudo apt-get update || exit 1 - sudo apt-get --no-install-suggests --no-install-recommends install clang-$LLVM_VERSION || exit 1 - sudo apt-get --no-install-suggests --no-install-recommends install g++-9 g++-9-multilib || exit 1 - sudo ln -s /usr/include/asm-generic /usr/include/asm - CC=clang-$LLVM_VERSION - echo "CC=$CC" >> $GITHUB_ENV - CXX=clang++-$LLVM_VERSION - echo "CXX=$CXX" >> $GITHUB_ENV + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + sudo ./llvm.sh ${{matrix.sys.version}} + sudo apt-get install -y clang-tools-${{matrix.sys.version}} + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${{matrix.sys.version}} 200 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${{matrix.sys.version}} 200 + sudo update-alternatives --install /usr/bin/clang-scan-deps clang-scan-deps /usr/bin/clang-scan-deps-${{matrix.sys.version}} 200 + sudo update-alternatives --set clang /usr/bin/clang-${{matrix.sys.version}} + sudo update-alternatives --set clang++ /usr/bin/clang++-${{matrix.sys.version}} + sudo update-alternatives --set clang-scan-deps /usr/bin/clang-scan-deps-${{matrix.sys.version}} - name: Checkout code uses: actions/checkout@v3 diff --git a/.github/workflows/osx.yml b/.github/workflows/osx.yml index 073c018..118d4fd 100644 --- a/.github/workflows/osx.yml +++ b/.github/workflows/osx.yml @@ -18,8 +18,9 @@ jobs: fail-fast: false matrix: os: - - 11 - - 12 + - 13 + - 14 + - 15 steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index b17b005..bcf8df5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ # The full license is in the file LICENSE, distributed with this software. # ############################################################################ -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.29) project(xtensor-python) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) @@ -46,19 +46,19 @@ else() message(STATUS "Found xtensor: ${xtensor_INCLUDE_DIRS}/xtensor") endif() -# Running find_package(PythonInterp) to retrieve the Python version -# which is not exported by Pybind11's cmake. -# Cf. https://github.com/pybind/pybind11/issues/2268 -find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} REQUIRED) +find_package(Python COMPONENTS Interpreter REQUIRED) set(pybind11_REQUIRED_VERSION 2.6.1) -if(TARGET pybind11 OR TARGET pybind11::headers) - # pybind11 has a variable that indicates its version already, so use that - message(STATUS "Found pybind11 v${pybind11_VERSION}") -else() +if (NOT TARGET pybind11::headers) + # Defaults to ON for cmake >= 3.18 + # https://github.com/pybind/pybind11/blob/35ff42b56e9d34d9a944266eb25f2c899dbdfed7/CMakeLists.txt#L96 + set(PYBIND11_FINDPYTHON OFF) find_package(pybind11 ${pybind11_REQUIRED_VERSION} REQUIRED) message(STATUS "Found pybind11: ${pybind11_INCLUDE_DIRS}/pybind11") -endif() +else () + # pybind11 has a variable that indicates its version already, so use that + message(STATUS "Found pybind11 v${pybind11_VERSION}") +endif () # Look for NumPy headers, except if NUMPY_INCLUDE_DIRS is passed, # which is required under some circumstances (such as wasm, where diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake index f043566..24f3c32 100644 --- a/cmake/FindNumPy.cmake +++ b/cmake/FindNumPy.cmake @@ -40,9 +40,9 @@ # Finding NumPy involves calling the Python interpreter if(NumPy_FIND_REQUIRED) - find_package(PythonInterp REQUIRED) + find_package(Python COMPONENTS Interpreter REQUIRED) else() - find_package(PythonInterp) + find_package(Python COMPONENTS Interpreter) endif() if(NOT PYTHONINTERP_FOUND) diff --git a/docs/source/examples/copy_cast/CMakeLists.txt b/docs/source/examples/copy_cast/CMakeLists.txt index e17611c..d8daf2a 100644 --- a/docs/source/examples/copy_cast/CMakeLists.txt +++ b/docs/source/examples/copy_cast/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1..3.19) +cmake_minimum_required(VERSION 3.29) project(mymodule) diff --git a/docs/source/examples/readme_example_1/CMakeLists.txt b/docs/source/examples/readme_example_1/CMakeLists.txt index 9c7ed5f..8831bca 100644 --- a/docs/source/examples/readme_example_1/CMakeLists.txt +++ b/docs/source/examples/readme_example_1/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.18..3.20) +cmake_minimum_required(VERSION 3.29) project(mymodule) diff --git a/docs/source/examples/sfinae/CMakeLists.txt b/docs/source/examples/sfinae/CMakeLists.txt index 10a1a96..1fb8477 100644 --- a/docs/source/examples/sfinae/CMakeLists.txt +++ b/docs/source/examples/sfinae/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.18..3.20) +cmake_minimum_required(VERSION 3.29) project(mymodule) diff --git a/environment-dev.yml b/environment-dev.yml index 1c2bd8b..f203855 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -10,5 +10,6 @@ dependencies: - numpy>=2.0 - pybind11>=2.12.0,<3 # Test dependencies + - setuptools - pytest diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0c77b0d..aaaf339 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,7 @@ # The full license is in the file LICENSE, distributed with this software. # ############################################################################ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.29) if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) project(xtensor-python-test) diff --git a/test/copyGTest.cmake.in b/test/copyGTest.cmake.in index 8341a74..50821d0 100644 --- a/test/copyGTest.cmake.in +++ b/test/copyGTest.cmake.in @@ -7,7 +7,7 @@ # The full license is in the file LICENSE, distributed with this software. # ############################################################################ -cmake_minimum_required(VERSION 2.8.2) +cmake_minimum_required(VERSION 3.29) project(googletest-download NONE) diff --git a/test/downloadGTest.cmake.in b/test/downloadGTest.cmake.in index 2d5cc5b..6bb5fad 100644 --- a/test/downloadGTest.cmake.in +++ b/test/downloadGTest.cmake.in @@ -7,14 +7,14 @@ # The full license is in the file LICENSE, distributed with this software. # ############################################################################ -cmake_minimum_required(VERSION 2.8.2) +cmake_minimum_required(VERSION 3.29) project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.10.0 + GIT_TAG v1.16.0 SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" From 1c85ed85bc90df60608a51fdc66bcf7b097aa84b Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 11 Apr 2025 10:43:52 +0200 Subject: [PATCH 096/102] Fixed RTD build (#320) --- readthedocs.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readthedocs.yml b/readthedocs.yml index 38f414b..a8188c4 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -5,5 +5,9 @@ build: tools: python: "mambaforge-22.9" +sphinx: + # Path to Sphinx configuration file + configuration: docs/source/conf.py + conda: environment: docs/environment.yml From f555d123c06e0e51bbf7335104750b55818beedc Mon Sep 17 00:00:00 2001 From: Daniel Jacobs <44678615+danielcjacobs@users.noreply.github.com> Date: Mon, 14 Apr 2025 04:14:38 -0400 Subject: [PATCH 097/102] update xtensor includes (#317) Brings xtensor-python up to date with latest xtensor release (0.26.0), where https://github.com/xtensor-stack/xtensor/pull/2829 reorganized the include directory. --------- Co-authored-by: Daniel Jacobs Co-authored-by: Johan Mabille --- CMakeLists.txt | 4 ++-- README.md | 2 +- benchmark/main.cpp | 4 ++-- docs/source/basic_usage.rst | 2 +- docs/source/examples/sfinae/main.cpp | 2 +- docs/source/examples/sfinae/mymodule.hpp | 2 +- environment-dev.yml | 2 +- include/xtensor-python/pyarray.hpp | 6 +++--- include/xtensor-python/pycontainer.hpp | 2 +- include/xtensor-python/pytensor.hpp | 8 ++++---- include/xtensor-python/pyvectorize.hpp | 2 +- .../xtensor_type_caster_base.hpp | 4 ++-- test/CMakeLists.txt | 11 +---------- test/test_common.hpp | 4 ++-- test/test_pyarray.cpp | 4 ++-- test/test_pytensor.cpp | 18 +++++++++--------- test/test_sfinae.cpp | 4 ++-- test_python/main.cpp | 12 ++++++------ test_python/setup.py | 11 ++++++----- 19 files changed, 48 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcf8df5..3fe3f34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,14 +25,14 @@ foreach(ver ${xtensor_python_version_defines}) set(XTENSOR_PYTHON_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "") endif() endforeach() -set(${PROJECT_NAME}_VERSION +set(${PROJECT_NAME}_VERSION ${XTENSOR_PYTHON_VERSION_MAJOR}.${XTENSOR_PYTHON_VERSION_MINOR}.${XTENSOR_PYTHON_VERSION_PATCH}) message(STATUS "xtensor-python v${${PROJECT_NAME}_VERSION}") # Dependencies # ============ -set(xtensor_REQUIRED_VERSION 0.25.0) +set(xtensor_REQUIRED_VERSION 0.26.0) if(TARGET xtensor) set(xtensor_VERSION ${XTENSOR_VERSION_MAJOR}.${XTENSOR_VERSION_MINOR}.${XTENSOR_VERSION_PATCH}) # Note: This is not SEMVER compatible comparison diff --git a/README.md b/README.md index 2cff672..88e6898 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.25.0 | >=2.6.1,<3 | +| master | ^0.26.0 | >=2.6.1,<3 | | 0.27.0 | ^0.25.0 | >=2.6.1,<3 | | 0.26.1 | ^0.24.0 | ~2.4.3 | | 0.26.0 | ^0.24.0 | ~2.4.3 | diff --git a/benchmark/main.cpp b/benchmark/main.cpp index d1d787e..4c18bc7 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -2,8 +2,8 @@ #include "pybind11/numpy.h" #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include "numpy/arrayobject.h" -#include "xtensor/xtensor.hpp" -#include "xtensor/xarray.hpp" +#include "xtensor/containers/xtensor.hpp" +#include "xtensor/containers/xarray.hpp" #include "xtensor-python/pyarray.hpp" #include "xtensor-python/pytensor.hpp" #include "xtensor-python/pyvectorize.hpp" diff --git a/docs/source/basic_usage.rst b/docs/source/basic_usage.rst index c97c9ac..32b1c23 100644 --- a/docs/source/basic_usage.rst +++ b/docs/source/basic_usage.rst @@ -16,7 +16,7 @@ Example 1: Use an algorithm of the C++ library on a numpy array inplace #include // Standard library import for std::accumulate #include "pybind11/pybind11.h" // Pybind11 import to define Python bindings - #include "xtensor/xmath.hpp" // xtensor import for the C++ universal functions + #include "xtensor/core/xmath.hpp" // xtensor import for the C++ universal functions #define FORCE_IMPORT_ARRAY // numpy C api loading #include "xtensor-python/pyarray.hpp" // Numpy bindings diff --git a/docs/source/examples/sfinae/main.cpp b/docs/source/examples/sfinae/main.cpp index a146cdd..44ffaa7 100644 --- a/docs/source/examples/sfinae/main.cpp +++ b/docs/source/examples/sfinae/main.cpp @@ -1,5 +1,5 @@ #include "mymodule.hpp" -#include +#include int main() { diff --git a/docs/source/examples/sfinae/mymodule.hpp b/docs/source/examples/sfinae/mymodule.hpp index 5127eff..33f7b8a 100644 --- a/docs/source/examples/sfinae/mymodule.hpp +++ b/docs/source/examples/sfinae/mymodule.hpp @@ -1,4 +1,4 @@ -#include +#include namespace mymodule { diff --git a/environment-dev.yml b/environment-dev.yml index f203855..72275dd 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -6,7 +6,7 @@ dependencies: - cmake - ninja # Host dependencies - - xtensor>=0.25,<0.26 + - xtensor>=0.26,<0.27 - numpy>=2.0 - pybind11>=2.12.0,<3 # Test dependencies diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 6df73cf..0854fb3 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -14,9 +14,9 @@ #include #include -#include "xtensor/xbuffer_adaptor.hpp" -#include "xtensor/xiterator.hpp" -#include "xtensor/xsemantic.hpp" +#include "xtensor/containers/xbuffer_adaptor.hpp" +#include "xtensor/core/xiterator.hpp" +#include "xtensor/core/xsemantic.hpp" #include "pyarray_backstrides.hpp" #include "pycontainer.hpp" diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index d0a1a1e..5e80a32 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -32,7 +32,7 @@ #undef copysign #include -#include "xtensor/xcontainer.hpp" +#include "xtensor/containers/xcontainer.hpp" #include "xtl/xsequence.hpp" diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index acf05b8..3eac157 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -14,10 +14,10 @@ #include #include -#include "xtensor/xbuffer_adaptor.hpp" -#include "xtensor/xiterator.hpp" -#include "xtensor/xsemantic.hpp" -#include "xtensor/xutils.hpp" +#include "xtensor/containers/xbuffer_adaptor.hpp" +#include "xtensor/core/xiterator.hpp" +#include "xtensor/core/xsemantic.hpp" +#include "xtensor/utils/xutils.hpp" #include "pycontainer.hpp" #include "pystrides_adaptor.hpp" diff --git a/include/xtensor-python/pyvectorize.hpp b/include/xtensor-python/pyvectorize.hpp index 9c7d107..d96f689 100644 --- a/include/xtensor-python/pyvectorize.hpp +++ b/include/xtensor-python/pyvectorize.hpp @@ -13,7 +13,7 @@ #include #include "pyarray.hpp" -#include "xtensor/xvectorize.hpp" +#include "xtensor/core/xvectorize.hpp" namespace xt { diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 840e28c..902235f 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -14,8 +14,8 @@ #include #include -#include "xtensor/xtensor.hpp" -#include "xtensor/xfixed.hpp" +#include "xtensor/containers/xtensor.hpp" +#include "xtensor/containers/xfixed.hpp" #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index aaaf339..60fcf10 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,16 +29,7 @@ include(CheckCXXCompilerFlag) string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE) -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wunused-parameter -Wextra -Wreorder -Wconversion -fvisibility=hidden") - CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG) - - if (HAS_CPP14_FLAG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - else() - message(FATAL_ERROR "Unsupported compiler -- xtensor requires C++14 support!") - endif() -endif() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj") diff --git a/test/test_common.hpp b/test/test_common.hpp index 3b4ed85..7115764 100644 --- a/test/test_common.hpp +++ b/test/test_common.hpp @@ -10,8 +10,8 @@ #ifndef TEST_COMMON_HPP #define TEST_COMMON_HPP -#include "xtensor/xlayout.hpp" -#include "xtensor/xmanipulation.hpp" +#include "xtensor/core/xlayout.hpp" +#include "xtensor/misc/xmanipulation.hpp" #include "xtl/xsequence.hpp" diff --git a/test/test_pyarray.cpp b/test/test_pyarray.cpp index 6406de6..15ede7e 100644 --- a/test/test_pyarray.cpp +++ b/test/test_pyarray.cpp @@ -11,8 +11,8 @@ #include "xtensor-python/pyarray.hpp" -#include "xtensor/xarray.hpp" -#include "xtensor/xview.hpp" +#include "xtensor/containers/xarray.hpp" +#include "xtensor/views/xview.hpp" #include "test_common.hpp" diff --git a/test/test_pytensor.cpp b/test/test_pytensor.cpp index f2ac013..c7b12cf 100644 --- a/test/test_pytensor.cpp +++ b/test/test_pytensor.cpp @@ -11,8 +11,8 @@ #include "xtensor-python/pytensor.hpp" -#include "xtensor/xtensor.hpp" -#include "xtensor/xview.hpp" +#include "xtensor/containers/xtensor.hpp" +#include "xtensor/views/xview.hpp" #include "test_common.hpp" @@ -22,13 +22,13 @@ namespace xt TEST(pytensor, initializer_constructor) { - pytensor t - {{{ 0, 1, 2}, - { 3, 4, 5}, - { 6, 7, 8}}, - {{ 9, 10, 11}, - {12, 13, 14}, - {15, 16, 17}}}; + pytensor t + {{{ 0, 1, 2}, + { 3, 4, 5}, + { 6, 7, 8}}, + {{ 9, 10, 11}, + {12, 13, 14}, + {15, 16, 17}}}; EXPECT_EQ(t.dimension(), 3); EXPECT_EQ(t(0, 0, 1), 1); EXPECT_EQ(t.shape()[0], 2); diff --git a/test/test_sfinae.cpp b/test/test_sfinae.cpp index a614485..c9d4733 100644 --- a/test/test_sfinae.cpp +++ b/test/test_sfinae.cpp @@ -12,8 +12,8 @@ #include "gtest/gtest.h" #include "xtensor-python/pytensor.hpp" #include "xtensor-python/pyarray.hpp" -#include "xtensor/xarray.hpp" -#include "xtensor/xtensor.hpp" +#include "xtensor/containers/xarray.hpp" +#include "xtensor/containers/xtensor.hpp" namespace xt { diff --git a/test_python/main.cpp b/test_python/main.cpp index 7a0c524..d9b9e97 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -9,15 +9,15 @@ #include -#include "xtensor/xmath.hpp" -#include "xtensor/xarray.hpp" -#include "xtensor/xfixed.hpp" +#include "xtensor/core/xmath.hpp" +#include "xtensor/containers/xarray.hpp" +#include "xtensor/containers/xfixed.hpp" #define FORCE_IMPORT_ARRAY #include "xtensor-python/pyarray.hpp" #include "xtensor-python/pytensor.hpp" #include "xtensor-python/pyvectorize.hpp" -#include "xtensor/xadapt.hpp" -#include "xtensor/xstrided_view.hpp" +#include "xtensor/containers/xadapt.hpp" +#include "xtensor/views/xstrided_view.hpp" namespace py = pybind11; using complex_t = std::complex; @@ -336,7 +336,7 @@ PYBIND11_MODULE(xtensor_python_test, m) m.def("array_subtraction", array_subtraction); m.def("array_multiplication", array_multiplication); m.def("array_division", array_division); - + m.def("vectorize_example1", xt::pyvectorize(add)); m.def("rect_to_polar", xt::pyvectorize([](complex_t x) { return std::abs(x); })); diff --git a/test_python/setup.py b/test_python/setup.py index fa201da..58dbd2d 100644 --- a/test_python/setup.py +++ b/test_python/setup.py @@ -75,13 +75,13 @@ def has_flag(compiler, flagname): def cpp_flag(compiler): - """Return the -std=c++14 compiler flag and errors when the flag is + """Return the -std=c++17 compiler flag and errors when the flag is no available. """ - if has_flag(compiler, '-std=c++14'): - return '-std=c++14' + if has_flag(compiler, '-std=c++17'): + return '-std=c++17' else: - raise RuntimeError('C++14 support is required by xtensor!') + raise RuntimeError('C++17 support is required by xtensor!') class BuildExt(build_ext): @@ -92,7 +92,7 @@ class BuildExt(build_ext): } if sys.platform == 'darwin': - c_opts['unix'] += ['-stdlib=libc++', '-mmacosx-version-min=10.7'] + c_opts['unix'] += ['-stdlib=libc++', '-mmacosx-version-min=10.13'] def build_extensions(self): ct = self.compiler.compiler_type @@ -104,6 +104,7 @@ def build_extensions(self): opts.append('-fvisibility=hidden') elif ct == 'msvc': opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version()) + opts.append('/std:c++17') for ext in self.extensions: ext.extra_compile_args = opts build_ext.build_extensions(self) From 1d59c294667c907bd97fbb16644f0dc23cad9cdb Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Mon, 14 Apr 2025 08:15:22 +0000 Subject: [PATCH 098/102] BLD: Add a pkgconfig file (#310) Similar to https://github.com/xtensor-stack/xtensor-blas/pull/243 and done for the same reason (easier to integrate with `meson`). --- CMakeLists.txt | 6 ++++++ xtensor-python.pc.in | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 xtensor-python.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fe3f34..e6b9227 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,12 @@ export(EXPORT ${PROJECT_NAME}-targets install(FILES ${XTENSOR_PYTHON_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xtensor-python) +configure_file(${PROJECT_NAME}.pc.in + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION "${CMAKE_INSTALL_DATADIR}/pkgconfig/") + set(XTENSOR_PYTHON_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for xtensor-pythonConfig.cmake") diff --git a/xtensor-python.pc.in b/xtensor-python.pc.in new file mode 100644 index 0000000..c198795 --- /dev/null +++ b/xtensor-python.pc.in @@ -0,0 +1,7 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +includedir=${prefix}/include + +Name: xtensor-python +Description: An extension to the xtensor library, offering Python bindings with enhanced NumPy support. +Version: @xtensor-python_VERSION@ +Cflags: -I${includedir} From 520e4f8ef255af02aff754f340cfcd3180e59552 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Mon, 14 Apr 2025 10:24:09 +0200 Subject: [PATCH 099/102] Release 0.28.0 --- README.md | 3 ++- include/xtensor-python/xtensor_python_config.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 88e6898..acf2df1 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Both containers enable the numpy-style APIs of xtensor (see [the numpy to xtenso ```cpp #include // Standard library import for std::accumulate #include // Pybind11 import to define Python bindings -#include // xtensor import for the C++ universal functions +#include // xtensor import for the C++ universal functions #define FORCE_IMPORT_ARRAY #include // Numpy bindings @@ -205,6 +205,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| | master | ^0.26.0 | >=2.6.1,<3 | +| 0.28.0 | ^0.26.0 | >=2.6.1,<3 | | 0.27.0 | ^0.25.0 | >=2.6.1,<3 | | 0.26.1 | ^0.24.0 | ~2.4.3 | | 0.26.0 | ^0.24.0 | ~2.4.3 | diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index c3f6707..f6840a7 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -11,7 +11,7 @@ #define XTENSOR_PYTHON_CONFIG_HPP #define XTENSOR_PYTHON_VERSION_MAJOR 0 -#define XTENSOR_PYTHON_VERSION_MINOR 27 +#define XTENSOR_PYTHON_VERSION_MINOR 28 #define XTENSOR_PYTHON_VERSION_PATCH 0 #endif From 680c6a43e624ca340b17dfd6a5049c7337be941f Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Thu, 31 Jul 2025 09:50:36 +0000 Subject: [PATCH 100/102] Update PyBind11 guard to 3.x release (#324) Fix #323 --- include/xtensor-python/pytensor.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index 3eac157..e3746cc 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -214,7 +214,7 @@ namespace xt static self_type ensure(pybind11::handle h); static bool check_(pybind11::handle h); -#if PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3 +#if (PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3) || (PYBIND11_VERSION_MAJOR >= 3) // Prevent ambiguous overload resolution for operators defined for // both xt::xcontainer_semantic and pybind11::object. using semantic_base::operator+=; From afc1672f50e2901f95a32b4cd9f480fa28545468 Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Thu, 31 Jul 2025 15:28:06 +0000 Subject: [PATCH 101/102] Fix pybind11 compatibility for version 3.x (#326) Fix #323 - again --- include/xtensor-python/pyarray.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 0854fb3..c24a793 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -195,7 +195,7 @@ namespace xt static self_type ensure(pybind11::handle h); static bool check_(pybind11::handle h); -#if PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3 +#if (PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3) || PYBIND11_VERSION_MAJOR >= 3 // Prevent ambiguous overload resolution for operators defined for // both xt::xcontainer_semantic and pybind11::object. using semantic_base::operator+=; From 2f59002d9930fe61fee19f0808444d0411ac1c70 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Thu, 31 Jul 2025 17:39:00 +0200 Subject: [PATCH 102/102] Upgraded to pybind11 3 (#325) --- README.md | 2 +- environment-dev.yml | 2 +- include/xtensor-python/pycontainer.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index acf2df1..3f24121 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,7 @@ from the `docs` subdirectory. | `xtensor-python` | `xtensor` | `pybind11` | |------------------|-----------|------------------| -| master | ^0.26.0 | >=2.6.1,<3 | +| master | ^0.26.0 | >=2.6.1,<4 | | 0.28.0 | ^0.26.0 | >=2.6.1,<3 | | 0.27.0 | ^0.25.0 | >=2.6.1,<3 | | 0.26.1 | ^0.24.0 | ~2.4.3 | diff --git a/environment-dev.yml b/environment-dev.yml index 72275dd..876678b 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -8,7 +8,7 @@ dependencies: # Host dependencies - xtensor>=0.26,<0.27 - numpy>=2.0 - - pybind11>=2.12.0,<3 + - pybind11>=2.12.0,<4 # Test dependencies - setuptools - pytest diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 5e80a32..f01c390 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -129,7 +129,7 @@ namespace xt private: -#if PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3 +#if (PYBIND11_VERSION_MAJOR == 2 && PYBIND11_VERSION_MINOR >= 3) || PYBIND11_VERSION_MAJOR >= 3 // Prevent ambiguous overload resolution for operators defined for // both xt::xcontainer and pybind11::object. using pybind11::object::operator~;