diff --git a/.appveyor.yml b/.appveyor.yml index 91cebe4..13f51e0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -3,33 +3,33 @@ build: false os: Visual Studio 2015 platform: - - x64 +- x64 environment: matrix: - - MINICONDA: C:\xtensor-conda + - 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%" +- 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" +- 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 +- 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 index 87d7592..54d3c8c 100644 --- a/.azure-pipelines/azure-pipelines-linux-clang.yml +++ b/.azure-pipelines/azure-pipelines-linux-clang.yml @@ -1,38 +1,38 @@ 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: +- 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 + - 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 + - bash: echo "##vso[task.prependpath]$CONDA/bin" + displayName: Add conda to PATH - - template: unix-build.yml + - template: unix-build.yml diff --git a/.azure-pipelines/azure-pipelines-linux-gcc.yml b/.azure-pipelines/azure-pipelines-linux-gcc.yml index e0a6aa0..1e16b6a 100644 --- a/.azure-pipelines/azure-pipelines-linux-gcc.yml +++ b/.azure-pipelines/azure-pipelines-linux-gcc.yml @@ -1,33 +1,32 @@ 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: +- 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 + - 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 + - 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 index beeafce..9da09c8 100644 --- a/.azure-pipelines/azure-pipelines-osx.yml +++ b/.azure-pipelines/azure-pipelines-osx.yml @@ -1,28 +1,28 @@ 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 +- 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 + - bash: | + echo "##vso[task.prependpath]$CONDA/bin" + sudo chown -R $USER $CONDA + displayName: Add conda to PATH - - template: unix-build.yml + - template: unix-build.yml diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index 97cb405..e5b9b4f 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -1,68 +1,68 @@ 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: | + 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 + 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 + 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 + 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 + 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 - 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 - 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 +- 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 diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d092c07 --- /dev/null +++ b/.clang-format @@ -0,0 +1,90 @@ +BasedOnStyle: Mozilla + +AccessModifierOffset: '-4' +AlignAfterOpenBracket: BlockIndent +AlignEscapedNewlines: Left +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +# Forbid one line lambdas because clang-format makes a weird split when +# single instructions lambdas are too long. +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: AfterComma +BreakStringLiterals: false +ColumnLimit: '110' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Always +EmptyLineBeforeAccessModifier: Always +ExperimentalAutoDetectBinPacking: true +IncludeBlocks: Regroup +IncludeCategories: +- Regex: <[^.]+> + Priority: 1 +- Regex: + Priority: 3 +- Regex: <.+> + Priority: 2 +- Regex: '"xtensor/.+"' + Priority: 4 +- Regex: '".+"' + Priority: 5 +IndentCaseLabels: true +IndentWidth: '4' +IndentWrappedFunctionNames: false +InsertBraces: true +InsertTrailingCommas: Wrapped +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +Language: Cpp +MaxEmptyLinesToKeep: '2' +NamespaceIndentation: All +ObjCBlockIndentWidth: '4' +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PackConstructorInitializers: Never +PenaltyBreakAssignment: 100000 +PenaltyBreakBeforeFirstCallParameter: 0 +PenaltyBreakComment: 10 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakTemplateDeclaration: 0 +PenaltyExcessCharacter: 10 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 10 +PointerAlignment: Left +QualifierAlignment: Custom # Experimental +QualifierOrder: [inline, static, constexpr, const, volatile, type] +ReflowComments: true +SeparateDefinitionBlocks: Always +SortIncludes: CaseInsensitive +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: '2' +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++14 +TabWidth: '4' +UseTab: Never diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..5441a33 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,14 @@ +name: Static Analysis + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: pre-commit/action@v3.0.0 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a0e9260 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,47 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: end-of-file-fixer + - id: trailing-whitespace + - id: mixed-line-ending + args: [--fix=lf] + exclude: \.bat$ + - id: check-json + - id: pretty-format-json + args: [--autofix, --top-keys=version] + - id: check-yaml + types: [file] + files: \.(yaml|yml|clang-format) + - id: detect-private-key + - id: check-merge-conflict +- repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.4.2 + hooks: + - id: forbid-tabs + - id: remove-tabs + args: [--whitespaces-count, '4'] +- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + rev: v2.7.0 + hooks: + - id: pretty-format-yaml + args: [--autofix, --indent, '2'] + types: [file] + files: \.(yaml|yml|clang-format) +- repo: https://github.com/tdegeus/cpp_comment_format + rev: v0.2.0 + hooks: + - id: cpp_comment_format +- repo: https://github.com/tdegeus/conda_envfile + rev: v0.4.2 + hooks: + - id: conda_envfile_parse + files: environment.yaml +# Externally provided executables (so we can use them with editors as well). +- repo: https://github.com/pre-commit/mirrors-clang-format + rev: v15.0.7 + hooks: + - id: clang-format + files: .*\.[hc]pp$ diff --git a/CMakeLists.txt b/CMakeLists.txt index e1bd077..1b51174 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ 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}") @@ -45,7 +45,7 @@ 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 OR TARGET pybind11::headers) # pybind11 has a variable that indicates its version already, so use that @@ -136,4 +136,3 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake install(EXPORT ${PROJECT_NAME}-targets FILE ${PROJECT_NAME}Targets.cmake DESTINATION ${XTENSOR_PYTHON_CMAKECONFIG_INSTALL_DIR}) - diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e930dbe..a7dcef7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,8 +1,7 @@ trigger: - - master +- 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 - +- 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/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 28589df..99253ff 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -95,4 +95,3 @@ add_custom_target(xbenchmark 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 d1d787e..92f188f 100644 --- a/benchmark/main.cpp +++ b/benchmark/main.cpp @@ -1,9 +1,11 @@ -#include "pybind11/pybind11.h" #include "pybind11/numpy.h" +#include "pybind11/pybind11.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/xtensor.hpp" + +#include "numpy/arrayobject.h" #include "xtensor-python/pyarray.hpp" #include "xtensor-python/pytensor.hpp" #include "xtensor-python/pyvectorize.hpp" @@ -14,44 +16,84 @@ namespace py = pybind11; PYBIND11_MODULE(benchmark_xtensor_python, m) { - if(_import_array() < 0) + if (_import_array() < 0) { PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } m.doc() = "Benchmark module for xtensor python bindings"; - m.def("sum_array", [](xt::pyarray const& x) { - double sum = 0; - for(auto e : x) - sum += e; - return sum; - }); - - m.def("sum_tensor", [](xt::pytensor const& x) { - double sum = 0; - for(auto e : x) - sum += e; - return sum; - }); - - m.def("pybind_sum_array", [](py::array_t const& x) { - double sum = 0; - size_t size = x.size(); - const double* data = x.data(0); - for(size_t i = 0; i < size; ++i) - sum += data[i]; - return sum; - }); - - m.def("rect_to_polar", [](xt::pyarray const& a) { - return py::vectorize([](complex_t x) { return std::abs(x); })(a); - }); - - m.def("pybind_rect_to_polar", [](py::array a) { - if (py::isinstance>(a)) - return py::vectorize([](complex_t x) { return std::abs(x); })(a); - else - throw py::type_error("rect_to_polar unhandled type"); - }); + m.def( + "sum_array", + [](const xt::pyarray& x) + { + double sum = 0; + for (auto e : x) + { + sum += e; + } + return sum; + } + ); + + m.def( + "sum_tensor", + [](const xt::pytensor& x) + { + double sum = 0; + for (auto e : x) + { + sum += e; + } + return sum; + } + ); + + m.def( + "pybind_sum_array", + [](const py::array_t& x) + { + double sum = 0; + size_t size = x.size(); + const double* data = x.data(0); + for (size_t i = 0; i < size; ++i) + { + sum += data[i]; + } + return sum; + } + ); + + m.def( + "rect_to_polar", + [](const xt::pyarray& a) + { + return py::vectorize( + [](complex_t x) + { + return std::abs(x); + } + )(a); + } + ); + + m.def( + "pybind_rect_to_polar", + [](py::array a) + { + if (py::isinstance>(a)) + { + return py::vectorize( + [](complex_t x) + { + return std::abs(x); + } + )(a); + } + else + { + throw py::type_error("rect_to_polar unhandled type"); + } + } + ); } diff --git a/cmake/FindNumPy.cmake b/cmake/FindNumPy.cmake index f043566..48a1046 100644 --- a/cmake/FindNumPy.cmake +++ b/cmake/FindNumPy.cmake @@ -24,10 +24,10 @@ # 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 @@ -35,7 +35,7 @@ # 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 diff --git a/docs/environment.yml b/docs/environment.yml index 47e93f7..65d263f 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -1,7 +1,7 @@ name: xtensor-python-docs channels: - - conda-forge +- conda-forge dependencies: - - breathe +- breathe diff --git a/docs/make.bat b/docs/make.bat index 0df92b4..07de332 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -3,48 +3,48 @@ REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build + set SPHINXBUILD=sphinx-build ) set BUILDDIR=build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source set I18NSPHINXOPTS=%SPHINXOPTS% source if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + goto end ) if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end ) @@ -58,15 +58,15 @@ goto sphinx_ok set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 ) :sphinx_ok @@ -74,191 +74,191 @@ if errorlevel 9009 ( if "%1" == "html" ( doxygen - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end ) if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end ) if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end ) if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end ) if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end ) if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. - goto end + goto end ) if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\packagename.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\packagename.ghc - goto end + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\packagename.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\packagename.ghc + goto end ) if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end ) if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end ) if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end ) if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end ) if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end ) if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end ) if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end ) if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end ) if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end ) if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end ) if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. - goto end + goto end ) if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. - goto end + goto end ) if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. - goto end + goto end ) if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end ) if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end ) :end diff --git a/docs/source/array_tensor.rst b/docs/source/array_tensor.rst index e00889f..be45b40 100644 --- a/docs/source/array_tensor.rst +++ b/docs/source/array_tensor.rst @@ -24,4 +24,3 @@ pytensor Like ``xtensor``, ``pytensor`` has a static stack-allocated shape. This means that the shape of the numpy array is copied into the shape of the ``pytensor`` upon creation. As a consequence, reshapes are not reflected across languages. However, this drawback is offset by a more effective computation of shape and broadcast. - diff --git a/docs/source/basic_usage.rst b/docs/source/basic_usage.rst index c97c9ac..fd32012 100644 --- a/docs/source/basic_usage.rst +++ b/docs/source/basic_usage.rst @@ -99,4 +99,3 @@ Example 2: Create a numpy-style universal function from a C++ scalar function [[-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]] - diff --git a/docs/source/conda.svg b/docs/source/conda.svg index 0755b2f..643a653 100644 --- a/docs/source/conda.svg +++ b/docs/source/conda.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/docs/source/conf.py b/docs/source/conf.py index 3b428b8..08c3872 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,4 +35,3 @@ def setup(app): pygments_style = 'sphinx' todo_include_todos = False htmlhelp_basename = 'xtensorpythondoc' - diff --git a/docs/source/cookiecutter.rst b/docs/source/cookiecutter.rst index e725106..221f3bd 100644 --- a/docs/source/cookiecutter.rst +++ b/docs/source/cookiecutter.rst @@ -45,7 +45,7 @@ information: - ``python_package_name``: name of the Python package created by your extension, - ``cpp_namespace``: name for the cpp namespace holding the implementation of your extension, - ``project_short_description``: a short description for your project. - + This will produce a directory containing all the required content for a minimal extension project making use of xtensor with all the required boilerplate for package management, together with a few basic examples. diff --git a/docs/source/debian.svg b/docs/source/debian.svg index 50dcb70..9232651 100644 --- a/docs/source/debian.svg +++ b/docs/source/debian.svg @@ -1,86 +1,86 @@ - - - - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/examples/copy_cast/main.cpp b/docs/source/examples/copy_cast/main.cpp index 2e12609..f1c9f1f 100644 --- a/docs/source/examples/copy_cast/main.cpp +++ b/docs/source/examples/copy_cast/main.cpp @@ -1,6 +1,7 @@ #include -#include + #include +#include #define FORCE_IMPORT_ARRAY #include diff --git a/docs/source/examples/readme_example_1/example.py b/docs/source/examples/readme_example_1/example.py index 1ae033d..b71f825 100644 --- a/docs/source/examples/readme_example_1/example.py +++ b/docs/source/examples/readme_example_1/example.py @@ -3,4 +3,3 @@ 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 index 6175ed8..d1af2ee 100644 --- a/docs/source/examples/readme_example_1/main.cpp +++ b/docs/source/examples/readme_example_1/main.cpp @@ -1,6 +1,7 @@ #include -#include + #include +#include #define FORCE_IMPORT_ARRAY #include diff --git a/docs/source/examples/sfinae/example.py b/docs/source/examples/sfinae/example.py index 1929f0b..348fc93 100644 --- a/docs/source/examples/sfinae/example.py +++ b/docs/source/examples/sfinae/example.py @@ -5,4 +5,3 @@ 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 index a146cdd..2278f00 100644 --- a/docs/source/examples/sfinae/main.cpp +++ b/docs/source/examples/sfinae/main.cpp @@ -1,6 +1,7 @@ -#include "mymodule.hpp" #include +#include "mymodule.hpp" + int main() { xt::xtensor a = xt::arange(2 * 3).reshape({2, 3}); diff --git a/docs/source/examples/sfinae/mymodule.hpp b/docs/source/examples/sfinae/mymodule.hpp index 5127eff..ad3d004 100644 --- a/docs/source/examples/sfinae/mymodule.hpp +++ b/docs/source/examples/sfinae/mymodule.hpp @@ -1,32 +1,33 @@ #include -namespace mymodule { - -template -struct is_std_vector +namespace mymodule { - static const bool value = false; -}; -template -struct is_std_vector > -{ - static const bool value = true; -}; + template + struct is_std_vector + { + static const bool value = false; + }; -// any xtensor object -template ::value, bool> = true> -void times_dimension(T& t) -{ - using value_type = typename T::value_type; - t *= (value_type)(t.dimension()); -} + template + struct is_std_vector> + { + static const bool value = true; + }; -// an std::vector -template ::value, bool> = true> -void times_dimension(T& t) -{ - // do nothing -} + // 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 index 081f625..f719248 100644 --- a/docs/source/examples/sfinae/python.cpp +++ b/docs/source/examples/sfinae/python.cpp @@ -1,5 +1,6 @@ -#include "mymodule.hpp" #include + +#include "mymodule.hpp" #define FORCE_IMPORT_ARRAY #include diff --git a/docs/source/numpy_capi.rst b/docs/source/numpy_capi.rst index d489be2..a84364d 100644 --- a/docs/source/numpy_capi.rst +++ b/docs/source/numpy_capi.rst @@ -90,6 +90,3 @@ you can override the behavior of ``xtensor-python`` by explicitly defining ``PY_ // in every source file #define PY_ARRAY_UNIQUE_SYMBOL my_uniqe_array_api #include "xtensor-python/pyarray.hpp" - - - diff --git a/docs/source/quantstack-white.svg b/docs/source/quantstack-white.svg index d527db1..1f03ebb 100644 --- a/docs/source/quantstack-white.svg +++ b/docs/source/quantstack-white.svg @@ -49,4 +49,4 @@ d="m 85.3,16 c 1.2,0.6 2.4,1.3 3.4,2.2 l 0,22.2 c 0,9.2 -1.8,19.7 -14.2,19.7 l -1.9,0 C 60.1,60.1 58.4,49.6 58.4,40.4 l 0,-22.2 c 1,-0.9 2.2,-1.6 3.4,-2.2 l 0,23.4 c 0,10.4 1.5,17.7 11.4,17.7 l 0.9,0 c 9.8,0 11.4,-7.3 11.4,-17.7 L 85.5,16 Z M 133,38.1 c 0,15 -5.1,22.1 -18.1,22.1 -0.1,0 -0.6,0 -0.7,0 -11,0 -14.2,-5.1 -14.2,-12.4 0,-10.2 9.7,-12.6 29.5,-13.4 -0.6,-9.3 -3.7,-15.2 -14.6,-15.2 -3,0 -5.8,0.5 -8.6,1.8 l -1.5,-2.9 c 3.3,-1.7 6.7,-2.1 10.1,-2.1 13,0 18.1,7 18.1,22.1 z m -3.4,-0.7 c -16.6,0.8 -26.1,2.2 -26.1,10.5 0,2.8 0.5,4.9 1.9,6.4 0.4,0.5 1,0.9 1.7,1.2 2.6,1.1 5.2,1.5 7.9,1.5 12.2,0 14.7,-7.4 14.7,-18.9 -0.1,-0.3 -0.1,-0.5 -0.1,-0.7 z m 201.7,0.7 c 0,15 -5.1,22.1 -18.1,22.1 -0.1,0 -0.6,0 -0.7,0 -11,0 -14.2,-5.1 -14.2,-12.4 0,-10.2 9.7,-12.6 29.5,-13.4 -0.6,-9.3 -3.7,-15.2 -14.6,-15.2 -3,0 -5.8,0.5 -8.6,1.8 l -1.5,-2.9 c 3.3,-1.7 6.7,-2.1 10.1,-2.1 13,0 18.1,7 18.1,22.1 z m -3.4,-0.7 c -16.6,0.8 -26.1,2.2 -26.1,10.5 0,2.8 0.5,4.9 1.9,6.4 0.4,0.5 1,0.9 1.7,1.2 2.6,1.1 5.2,1.5 7.9,1.5 12.2,0 14.7,-7.4 14.7,-18.9 -0.1,-0.3 -0.1,-0.5 -0.1,-0.7 z M 57.2,82.2 c -0.9,0.9 -1.8,1.7 -2.9,2.3 C 45,79.7 38.3,71.4 34.9,60.6 31.7,62.2 27.8,63 23.1,63 6.5,63 0,53.3 0,32.3 0,11.4 6.5,1.6 23.1,1.6 c 16.6,0 23.1,9.7 23.1,30.7 0,13 -2.5,21.6 -8.4,26.4 3.2,10.9 10,19 19.4,23.5 z M 42.7,32.3 C 42.7,15.9 39.4,4.8 23,4.8 6.6,4.8 3.3,15.8 3.3,32.3 c 0,16.4 3.3,27.5 19.7,27.5 16.4,0 19.7,-11 19.7,-27.5 z m 366,-10.4 C 408,21 407.2,20.2 406.3,19.5 l -18.3,18.2 0,-22 -0.4,0 c -1.1,0.2 -2,0.5 -3,0.8 l 0,42.6 c 1.1,0.4 2.2,0.6 3.4,0.9 l 0,-21.3 17.8,17.8 c 0.9,-0.7 1.7,-1.4 2.5,-2.3 l -16,-16 16.4,-16.3 z M 360.6,57 c -12.2,0 -14.7,-7.4 -14.7,-18.9 0,-11.5 2.5,-18.9 14.7,-18.9 3.1,0 6,0.5 8.8,1.9 l 1.5,-2.9 c -3.4,-1.7 -6.9,-2.1 -10.2,-2.1 -13,0 -18.1,7 -18.1,22.1 0,15 5.1,22.1 18.1,22.1 3.4,0 6.9,-0.4 10.3,-2.1 l -1.5,-2.9 c -3,1.2 -5.9,1.7 -8.9,1.7 z m -198,-41.1 -1.9,0 c -12.5,0 -14.2,10.5 -14.2,19.7 l 0,22.2 c 1,0.9 2.2,1.6 3.4,2.2 l 0,-23.3 c 0,-10.4 1.5,-17.7 11.4,-17.7 l 0.9,0 c 9.8,0 11.4,7.3 11.4,17.7 l 0,23.4 c 1.2,-0.6 2.4,-1.3 3.4,-2.2 l 0,-22.2 c -0.2,-9.3 -2,-19.8 -14.4,-19.8 z m 127.7,4.3 -1.6,-3.1 -10.4,0 0,-10.9 -3.3,0 0,10.8 -10.5,0 -1.6,3.1 12.1,0 c 0,0 0,22.4 0,23.7 l 0,0 c -0.1,2.6 0.3,5.1 1.2,7.3 0,0.1 1,2.2 2.6,4.1 0.8,0.9 2.4,2.3 4.6,3.8 l 1.5,-3.1 c -1.7,-1.2 -2.9,-2.2 -3.5,-2.9 -1.3,-1.5 -2,-3.2 -2,-3.2 -0.7,-1.6 -1,-3.3 -1,-5 0,-1.2 0,-24.7 0,-24.7 l 11.9,0 z M 197.8,6 l -3.3,0 0,10.8 -12,0 1.6,3.1 10.4,0 c 0,0 0,12.2 0,13.5 l 0,0 c -0.1,2.6 0.3,5.1 1.2,7.3 0,0.1 1,2.2 2.6,4.1 0.8,0.9 2.3,2.2 4.4,3.7 l 1.6,-3.1 c -1.7,-1.2 -2.9,-2.2 -3.4,-2.9 -1.3,-1.5 -2,-3.2 -2,-3.2 -0.7,-1.6 -1,-3.3 -1,-5 0,-1.2 0,-14.5 0,-14.5 l 10.4,0 1.6,-3.1 -12.1,0 0,-10.7 z m 40.3,22.2 c -1.9,-0.7 -3.6,-1.3 -5.3,-2.1 l 0,0 c -5.1,-2.1 -8.7,-4.8 -8.7,-10.8 0,-9.2 6.4,-12.1 14.5,-12.1 3.8,0 7.5,0.4 11.2,1.7 L 251.3,2 c -4,-1.5 -8.3,-2 -12.8,-2 -9.4,0 -17.7,4.1 -17.7,15.4 0,6.7 3.4,10.4 8.6,12.9 l 0,0 c 0.8,0.3 1.4,0.6 2.1,0.9 0,0 0,0 0,0 l 0,0 c 1.9,0.8 3.3,1.4 5.1,2 8.4,3 12.3,3.5 15.1,6.6 0.2,0.2 4.1,4.8 3.1,10.4 -0.5,2.9 -2.2,5.5 -4.9,7.8 -6.2,5.1 -15.9,4 -25.2,0.9 l -1.6,3.1 c 5.1,1.8 10.4,3 15.4,3 5.1,0 9.7,-1.2 13.5,-4.3 4.2,-3.5 5.7,-7.2 6.1,-9.8 1.3,-7.1 -3.3,-12.6 -3.8,-13.2 -2.7,-2.9 -7.6,-4.4 -16.2,-7.5 z" id="path3" inkscape:connector-curvature="0" - style="fill:#ffffff" /> \ No newline at end of file + style="fill:#ffffff" /> diff --git a/docs/source/xtensor-python.svg b/docs/source/xtensor-python.svg index 181465f..7a29ffd 100644 --- a/docs/source/xtensor-python.svg +++ b/docs/source/xtensor-python.svg @@ -1,60 +1,60 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/environment-dev.yml b/environment-dev.yml index 6dff19f..7b55617 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -1,13 +1,12 @@ name: xtensor-python channels: - - conda-forge +- conda-forge dependencies: # Build dependencies - - cmake +- cmake # Host dependencies - - xtensor=0.24.0 - - numpy - - pybind11=2.4.3 +- xtensor=0.24.0 +- numpy +- pybind11=2.4.3 # Test dependencies - - pytest - +- pytest diff --git a/include/xtensor-python/pyarray.hpp b/include/xtensor-python/pyarray.hpp index 6df73cf..569da90 100644 --- a/include/xtensor-python/pyarray.hpp +++ b/include/xtensor-python/pyarray.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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_HPP #define PY_ARRAY_HPP @@ -20,10 +20,10 @@ #include "pyarray_backstrides.hpp" #include "pycontainer.hpp" -#include "pystrides_adaptor.hpp" #include "pynative_casters.hpp" -#include "xtensor_type_caster_base.hpp" +#include "pystrides_adaptor.hpp" #include "xtensor_python_config.hpp" +#include "xtensor_type_caster_base.hpp" namespace xt { @@ -35,7 +35,7 @@ namespace pybind11 { namespace detail { -#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 +#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 template struct handle_type_name> { @@ -69,7 +69,7 @@ namespace pybind11 return src.inc_ref(); } -#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 +#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 PYBIND11_TYPE_CASTER(type, handle_type_name::name()); #else PYBIND11_TYPE_CASTER(type, _("numpy.ndarray[") + npy_format_descriptor::name + _("]")); @@ -99,8 +99,7 @@ namespace pybind11 namespace xt { template - struct xiterable_inner_types> - : xcontainer_iterable_types> + struct xiterable_inner_types> : xcontainer_iterable_types> { }; @@ -155,7 +154,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; + static constexpr std::size_t rank = SIZE_MAX; pyarray(); pyarray(const value_type& t); @@ -267,7 +266,8 @@ namespace xt : base_type() { 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); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) + : nested_copy(this->template begin(), t); } template @@ -275,7 +275,8 @@ namespace xt : base_type() { 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); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) + : nested_copy(this->template begin(), t); } template @@ -283,7 +284,8 @@ namespace xt : base_type() { 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); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) + : nested_copy(this->template begin(), t); } template @@ -291,7 +293,8 @@ namespace xt : base_type() { 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); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) + : nested_copy(this->template begin(), t); } template @@ -299,7 +302,8 @@ namespace xt : base_type() { 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); + L == layout_type::row_major ? nested_copy(m_storage.begin(), t) + : nested_copy(this->template begin(), t); } template @@ -393,6 +397,7 @@ namespace xt auto shp = xtl::forward_sequence(shape); return self_type(shp); } + //@} /** @@ -404,10 +409,12 @@ namespace xt */ template inline pyarray::pyarray(const self_type& rhs) - : base_type(), semantic_base(rhs) + : base_type() + , semantic_base(rhs) { auto tmp = pybind11::reinterpret_steal( - PyArray_NewLikeArray(rhs.python_array(), NPY_KEEPORDER, nullptr, 1)); + PyArray_NewLikeArray(rhs.python_array(), NPY_KEEPORDER, nullptr, 1) + ); if (!tmp) { @@ -445,7 +452,9 @@ namespace xt : base_type() { // TODO: prevent intermediary shape allocation - shape_type shape = xtl::forward_sequence(e.derived_cast().shape()); + shape_type shape = xtl::forward_sequence( + e.derived_cast().shape() + ); strides_type strides = xtl::make_sequence(shape.size(), size_type(0)); layout_type layout = default_dynamic_layout(); @@ -463,6 +472,7 @@ namespace xt { return semantic_base::operator=(e); } + //@} template @@ -482,8 +492,15 @@ namespace xt { strides_type adapted_strides(strides); - std::transform(strides.begin(), strides.end(), adapted_strides.begin(), - [](auto v) { return sizeof(T) * v; }); + std::transform( + strides.begin(), + strides.end(), + adapted_strides.begin(), + [](auto v) + { + return sizeof(T) * v; + } + ); int flags = NPY_ARRAY_ALIGNED; if (!std::is_const::value) @@ -496,9 +513,16 @@ namespace xt npy_intp* shape_data = reinterpret_cast(const_cast(shape.data())); npy_intp* strides_data = reinterpret_cast(adapted_strides.data()); - auto tmp = pybind11::reinterpret_steal( - PyArray_NewFromDescr(&PyArray_Type, (PyArray_Descr*) dtype.release().ptr(), static_cast(shape.size()), shape_data, strides_data, - nullptr, flags, nullptr)); + auto tmp = pybind11::reinterpret_steal(PyArray_NewFromDescr( + &PyArray_Type, + (PyArray_Descr*) dtype.release().ptr(), + static_cast(shape.size()), + shape_data, + strides_data, + nullptr, + flags, + nullptr + )); if (!tmp) { @@ -517,11 +541,15 @@ 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())), - static_cast(PyArray_NDIM(this->python_array())), - reinterpret_cast(PyArray_SHAPE(this->python_array()))); + 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())), + reinterpret_cast(PyArray_SHAPE(this->python_array())) + ); if (L != layout_type::dynamic && !do_strides_match(m_shape, m_strides, L, 1)) { @@ -529,8 +557,10 @@ namespace xt } m_backstrides = backstrides_type(*this); - m_storage = storage_type(reinterpret_cast(PyArray_DATA(this->python_array())), - this->get_buffer_size()); + m_storage = storage_type( + reinterpret_cast(PyArray_DATA(this->python_array())), + this->get_buffer_size() + ); } template @@ -549,8 +579,9 @@ namespace xt inline auto pyarray::backstrides_impl() const noexcept -> const inner_backstrides_type& { // m_backstrides wraps the numpy array backstrides, which is a raw pointer. - // The address of the raw pointer stored in the wrapper would be invalidated when the pyarray is copied. - // Hence, we build a new backstrides object (cheap wrapper around the underlying pointer) upon access. + // The address of the raw pointer stored in the wrapper would be invalidated when the pyarray is + // copied. Hence, we build a new backstrides object (cheap wrapper around the underlying pointer) upon + // access. m_backstrides = backstrides_type(*this); return m_backstrides; } diff --git a/include/xtensor-python/pyarray_backstrides.hpp b/include/xtensor-python/pyarray_backstrides.hpp index 4dfdab9..c672619 100644 --- a/include/xtensor-python/pyarray_backstrides.hpp +++ b/include/xtensor-python/pyarray_backstrides.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 @@ -62,28 +62,22 @@ namespace xt }; template - inline bool operator==(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs); + inline bool operator==(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs); template - inline bool operator!=(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs); + inline bool operator!=(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs); template - inline bool operator<(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs); + inline bool operator<(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs); template - inline bool operator<=(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs); + inline bool operator<=(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs); template - inline bool operator>(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs); + inline bool operator>(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs); template - inline bool operator>=(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs); + inline bool operator>=(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs); /*********************** * pyarray_backstrides * @@ -138,10 +132,11 @@ namespace xt /***************************************** * pybackstrides_iterator implementation * *****************************************/ - + template inline pybackstrides_iterator::pybackstrides_iterator(const B* b, std::size_t offset) - : p_b(b), m_offset(offset) + : p_b(b) + , m_offset(offset) { } @@ -176,11 +171,11 @@ namespace xt inline auto pybackstrides_iterator::operator--() -> self_type& { --m_offset; - return *this; + return *this; } template - inline auto pybackstrides_iterator::operator++(int )-> self_type + inline auto pybackstrides_iterator::operator++(int) -> self_type { self_type tmp(*this); ++m_offset; @@ -236,43 +231,37 @@ namespace xt } template - inline bool operator==(const pybackstrides_iterator& lhs, - const pybackstrides_iterator& rhs) + 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) + 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) + 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) + 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) + 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) + inline bool operator>=(const pybackstrides_iterator& lhs, const pybackstrides_iterator& rhs) { return !(lhs < rhs); } diff --git a/include/xtensor-python/pycontainer.hpp b/include/xtensor-python/pycontainer.hpp index 1617d03..13574bb 100644 --- a/include/xtensor-python/pycontainer.hpp +++ b/include/xtensor-python/pycontainer.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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_CONTAINER_HPP #define PY_CONTAINER_HPP @@ -16,8 +16,8 @@ #include #include "pybind11/complex.h" -#include "pybind11/pybind11.h" #include "pybind11/numpy.h" +#include "pybind11/pybind11.h" #ifndef FORCE_IMPORT_ARRAY #define NO_IMPORT_ARRAY @@ -32,6 +32,7 @@ #undef copysign #include + #include "xtensor/xcontainer.hpp" #include "xtl/xsequence.hpp" @@ -151,7 +152,9 @@ namespace xt struct numpy_traits; template - struct numpy_traits::value>> + struct numpy_traits< + T, + std::enable_if_t::value>> { private: @@ -161,12 +164,22 @@ namespace xt // On Linux x64, NPY_INT64 != NPY_LONGLONG and NPY_UINT64 != NPY_ULONGLONG, // we use the values of NPY_INT64 and NPY_UINT64 which are consistent with the // values of NPY_LONG and NPY_ULONG. - constexpr static const int value_list[15] = { + static constexpr const int value_list[15] = { NPY_BOOL, - NPY_BYTE, NPY_UBYTE, NPY_SHORT, NPY_USHORT, - NPY_INT32, NPY_UINT32, NPY_INT64, NPY_UINT64, - NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE, - NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE}; + NPY_BYTE, + NPY_UBYTE, + NPY_SHORT, + NPY_USHORT, + NPY_INT32, + NPY_UINT32, + NPY_INT64, + NPY_UINT64, + NPY_FLOAT, + NPY_DOUBLE, + NPY_LONGDOUBLE, + NPY_CFLOAT, + NPY_CDOUBLE, + NPY_CLONGDOUBLE}; public: @@ -181,7 +194,7 @@ namespace xt template struct numpy_enum_adjuster { - static inline int pyarray_type(PyArrayObject* obj) + inline static int pyarray_type(PyArrayObject* obj) { return PyArray_TYPE(obj); } @@ -190,10 +203,10 @@ namespace xt template <> struct numpy_enum_adjuster { - static inline int pyarray_type(PyArrayObject* obj) + inline static int pyarray_type(PyArrayObject* obj) { int res = PyArray_TYPE(obj); - if(res == NPY_LONGLONG || res == NPY_ULONGLONG) + if (res == NPY_LONGLONG || res == NPY_ULONGLONG) { res -= 2; } @@ -235,14 +248,18 @@ namespace xt template bool check_array_type(const pybind11::handle& src, std::false_type) { - return PyArray_EquivTypes((PyArray_Descr*) pybind11::detail::array_proxy(src.ptr())->descr, - (PyArray_Descr*) pybind11::dtype::of().ptr()); + return PyArray_EquivTypes( + (PyArray_Descr*) pybind11::detail::array_proxy(src.ptr())->descr, + (PyArray_Descr*) pybind11::dtype::of().ptr() + ); } template bool check_array(const pybind11::handle& src) { - using is_arithmetic_type = std::integral_constant::value)>; + using is_arithmetic_type = std::integral_constant< + bool, + bool(pybind11::detail::satisfies_any_of::value)>; return PyArray_Check(src.ptr()) && check_array_type(src, is_arithmetic_type{}); } } @@ -305,8 +322,14 @@ namespace xt } auto dtype = pybind11::detail::npy_format_descriptor::dtype(); - auto res = PyArray_FromAny(ptr, (PyArray_Descr *) dtype.release().ptr(), 0, 0, - NPY_ARRAY_ENSUREARRAY | NPY_ARRAY_FORCECAST, nullptr); + auto res = PyArray_FromAny( + ptr, + (PyArray_Descr*) dtype.release().ptr(), + 0, + 0, + NPY_ARRAY_ENSUREARRAY | NPY_ARRAY_FORCECAST, + nullptr + ); return res; } @@ -320,11 +343,16 @@ 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) : - std::max(size_type(1), std::accumulate(this->strides().cbegin(), - this->strides().cend(), - std::numeric_limits::max(), - min)); + size_type min_stride = this->strides().empty() ? size_type(1) + : std::max( + size_type(1), + std::accumulate( + this->strides().cbegin(), + this->strides().cend(), + std::numeric_limits::max(), + min + ) + ); return min_stride * static_cast(PyArray_SIZE(this->python_array())); } @@ -356,11 +384,11 @@ namespace xt { static bool run(std::size_t new_dim) { - if(new_dim != N) + if (new_dim != N) { std::ostringstream err_msg; - err_msg << "Invalid conversion to pycontainer, expecting a container of dimension " - << N << ", got a container of dimension " << new_dim << "."; + 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; @@ -376,7 +404,8 @@ namespace xt template inline void pycontainer::resize(const S& shape) { - if (shape.size() != this->dimension() || !std::equal(std::begin(shape), std::end(shape), std::begin(this->shape()))) + if (shape.size() != this->dimension() + || !std::equal(std::begin(shape), std::end(shape), std::begin(this->shape()))) { resize(shape, layout_type::row_major); } @@ -416,7 +445,10 @@ namespace xt { if (compute_size(shape) != this->size()) { - throw std::runtime_error("Cannot reshape with incorrect number of elements (" + std::to_string(this->size()) + " vs " + std::to_string(compute_size(shape)) + ")"); + throw std::runtime_error( + "Cannot reshape with incorrect number of elements (" + std::to_string(this->size()) + " vs " + + std::to_string(compute_size(shape)) + ")" + ); } detail::check_dims::run(shape.size()); layout = default_assignable_layout(layout); @@ -436,7 +468,9 @@ namespace xt } using shape_ptr = typename std::decay_t::pointer; - PyArray_Dims dims = {reinterpret_cast(const_cast(shape.data())), static_cast(shape.size())}; + PyArray_Dims dims = { + reinterpret_cast(const_cast(shape.data())), + static_cast(shape.size())}; auto new_ptr = PyArray_Newshape((PyArrayObject*) this->ptr(), &dims, npy_layout); auto old_ptr = this->ptr(); this->ptr() = new_ptr; diff --git a/include/xtensor-python/pynative_casters.hpp b/include/xtensor-python/pynative_casters.hpp index aa19604..89cebea 100644 --- a/include/xtensor-python/pynative_casters.hpp +++ b/include/xtensor-python/pynative_casters.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 @@ -30,25 +30,29 @@ namespace pybind11 // Type caster for casting xt::xtensor_fixed to ndarray template - struct type_caster> : xtensor_type_caster_base> + struct type_caster> + : xtensor_type_caster_base> { }; // Type caster for casting xt::xstrided_view to ndarray template - struct type_caster> : xtensor_type_caster_base> + struct type_caster> + : xtensor_type_caster_base> { }; // Type caster for casting xt::xarray_adaptor to ndarray template - struct type_caster> : xtensor_type_caster_base> + struct type_caster> + : xtensor_type_caster_base> { }; // Type caster for casting xt::xtensor_adaptor to ndarray template - struct type_caster> : xtensor_type_caster_base> + struct type_caster> + : xtensor_type_caster_base> { }; } diff --git a/include/xtensor-python/pystrides_adaptor.hpp b/include/xtensor-python/pystrides_adaptor.hpp index fde929a..5031e0e 100644 --- a/include/xtensor-python/pystrides_adaptor.hpp +++ b/include/xtensor-python/pystrides_adaptor.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 PYSTRIDES_ADAPTOR_HPP #define PYSTRIDES_ADAPTOR_HPP @@ -172,7 +172,10 @@ namespace xt return p_current - rhs.p_current; } - pointer get_pointer() const { return p_current; } + pointer get_pointer() const + { + return p_current; + } private: @@ -181,43 +184,37 @@ namespace xt }; template - inline bool operator==(const pystrides_iterator& lhs, - const pystrides_iterator& rhs) + inline bool operator==(const pystrides_iterator& lhs, const pystrides_iterator& rhs) { return lhs.get_pointer() == rhs.get_pointer(); } template - inline bool operator!=(const pystrides_iterator& lhs, - const pystrides_iterator& rhs) + inline bool operator!=(const pystrides_iterator& lhs, const pystrides_iterator& rhs) { return !(lhs == rhs); } template - inline bool operator<(const pystrides_iterator& lhs, - const pystrides_iterator& rhs) + inline bool operator<(const pystrides_iterator& lhs, const pystrides_iterator& rhs) { return lhs.get_pointer() < rhs.get_pointer(); } template - inline bool operator<=(const pystrides_iterator& lhs, - const pystrides_iterator& rhs) + inline bool operator<=(const pystrides_iterator& lhs, const pystrides_iterator& rhs) { return (lhs < rhs) || (lhs == rhs); } template - inline bool operator>(const pystrides_iterator& lhs, - const pystrides_iterator& rhs) + inline bool operator>(const pystrides_iterator& lhs, const pystrides_iterator& rhs) { return !(lhs <= rhs); } template - inline bool operator>=(const pystrides_iterator& lhs, - const pystrides_iterator& rhs) + inline bool operator>=(const pystrides_iterator& lhs, const pystrides_iterator& rhs) { return !(lhs < rhs); } @@ -228,7 +225,9 @@ namespace xt template inline pystrides_adaptor::pystrides_adaptor(const_pointer data, size_type size, shape_type shape) - : p_data(data), m_size(size), p_shape(shape) + : p_data(data) + , m_size(size) + , p_shape(shape) { } diff --git a/include/xtensor-python/pytensor.hpp b/include/xtensor-python/pytensor.hpp index acf05b8..e047e81 100644 --- a/include/xtensor-python/pytensor.hpp +++ b/include/xtensor-python/pytensor.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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_TENSOR_HPP #define PY_TENSOR_HPP @@ -20,10 +20,10 @@ #include "xtensor/xutils.hpp" #include "pycontainer.hpp" -#include "pystrides_adaptor.hpp" #include "pynative_casters.hpp" -#include "xtensor_type_caster_base.hpp" +#include "pystrides_adaptor.hpp" #include "xtensor_python_config.hpp" +#include "xtensor_type_caster_base.hpp" namespace xt { @@ -35,7 +35,7 @@ namespace pybind11 { namespace detail { -#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 +#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 template struct handle_type_name> { @@ -77,7 +77,7 @@ namespace pybind11 return src.inc_ref(); } -#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 +#ifdef PYBIND11_DESCR // The macro is removed from pybind11 since 2.3 PYBIND11_TYPE_CASTER(type, handle_type_name::name()); #else PYBIND11_TYPE_CASTER(type, _("numpy.ndarray[") + npy_format_descriptor::name + _("]")); @@ -101,12 +101,13 @@ namespace pybind11 } }; - } // namespace detail + } // namespace detail } namespace xt { - namespace detail { + namespace detail + { template struct numpy_strides @@ -120,11 +121,10 @@ namespace xt npy_intp* value = nullptr; }; - } // namespace detail + } // namespace detail template - struct xiterable_inner_types> - : xcontainer_iterable_types> + struct xiterable_inner_types> : xcontainer_iterable_types> { }; @@ -180,7 +180,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; + static constexpr std::size_t rank = N; pytensor(); pytensor(nested_initializer_list_t t); @@ -326,9 +326,7 @@ namespace xt * @param l the layout_type of the pytensor */ template - inline pytensor::pytensor(const shape_type& shape, - const_reference value, - layout_type l) + inline pytensor::pytensor(const shape_type& shape, const_reference value, layout_type l) { compute_strides(shape, l, m_strides); init_tensor(shape, m_strides); @@ -343,9 +341,7 @@ namespace xt * @param value the value of the elements */ template - inline pytensor::pytensor(const shape_type& shape, - const strides_type& strides, - const_reference value) + inline pytensor::pytensor(const shape_type& shape, const strides_type& strides, const_reference value) { init_tensor(shape, strides); std::fill(m_storage.begin(), m_storage.end(), value); @@ -357,8 +353,7 @@ namespace xt * @param strides the strides of the pytensor */ template - inline pytensor::pytensor(const shape_type& shape, - const strides_type& strides) + inline pytensor::pytensor(const shape_type& shape, const strides_type& strides) { init_tensor(shape, strides); } @@ -375,6 +370,7 @@ namespace xt auto shp = xtl::forward_sequence(shape); return self_type(shp); } + //@} /** @@ -386,7 +382,8 @@ namespace xt */ template inline pytensor::pytensor(const self_type& rhs) - : base_type(), semantic_base(rhs) + : base_type() + , semantic_base(rhs) { init_tensor(rhs.shape(), rhs.strides()); std::copy(rhs.storage().cbegin(), rhs.storage().cend(), this->storage().begin()); @@ -402,6 +399,7 @@ namespace xt *this = std::move(tmp); return *this; } + //@} /** @@ -416,7 +414,9 @@ namespace xt inline pytensor::pytensor(const xexpression& e) : base_type() { - shape_type shape = xtl::forward_sequence(e.derived_cast().shape()); + shape_type shape = xtl::forward_sequence( + e.derived_cast().shape() + ); strides_type strides = xtl::make_sequence(N, size_type(0)); compute_strides(shape, layout_type::row_major, strides); init_tensor(shape, strides); @@ -432,6 +432,7 @@ namespace xt { return semantic_base::operator=(e); } + //@} template @@ -450,8 +451,15 @@ namespace xt inline void pytensor::init_tensor(const shape_type& shape, const strides_type& strides) { detail::numpy_strides python_strides; - std::transform(strides.begin(), strides.end(), python_strides.value, - [](auto v) { return sizeof(T) * v; }); + 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) { @@ -459,10 +467,16 @@ namespace xt } auto dtype = pybind11::detail::npy_format_descriptor::dtype(); - auto tmp = pybind11::reinterpret_steal( - PyArray_NewFromDescr(&PyArray_Type, (PyArray_Descr*) dtype.release().ptr(), static_cast(shape.size()), - const_cast(shape.data()), python_strides.value, - nullptr, flags, nullptr)); + auto tmp = pybind11::reinterpret_steal(PyArray_NewFromDescr( + &PyArray_Type, + (PyArray_Descr*) dtype.release().ptr(), + static_cast(shape.size()), + const_cast(shape.data()), + python_strides.value, + nullptr, + flags, + nullptr + )); if (!tmp) { @@ -473,8 +487,10 @@ namespace xt m_shape = shape; m_strides = strides; adapt_strides(m_shape, m_strides, m_backstrides); - m_storage = storage_type(reinterpret_cast(PyArray_DATA(this->python_array())), - static_cast(PyArray_SIZE(this->python_array()))); + m_storage = storage_type( + reinterpret_cast(PyArray_DATA(this->python_array())), + static_cast(PyArray_SIZE(this->python_array())) + ); } template @@ -491,8 +507,15 @@ namespace xt } std::copy(PyArray_DIMS(this->python_array()), PyArray_DIMS(this->python_array()) + N, m_shape.begin()); - std::transform(PyArray_STRIDES(this->python_array()), PyArray_STRIDES(this->python_array()) + N, m_strides.begin(), - [](auto v) { return v / sizeof(T); }); + std::transform( + PyArray_STRIDES(this->python_array()), + PyArray_STRIDES(this->python_array()) + N, + m_strides.begin(), + [](auto v) + { + return v / sizeof(T); + } + ); adapt_strides(m_shape, m_strides, m_backstrides); if (L != layout_type::dynamic && !do_strides_match(m_shape, m_strides, L, 1)) @@ -500,8 +523,10 @@ namespace xt throw std::runtime_error("NumPy: passing container with bad strides for layout (is it a view?)."); } - m_storage = storage_type(reinterpret_cast(PyArray_DATA(this->python_array())), - this->get_buffer_size()); + m_storage = storage_type( + reinterpret_cast(PyArray_DATA(this->python_array())), + this->get_buffer_size() + ); } template diff --git a/include/xtensor-python/pyvectorize.hpp b/include/xtensor-python/pyvectorize.hpp index 9c7d107..97d6600 100644 --- a/include/xtensor-python/pyvectorize.hpp +++ b/include/xtensor-python/pyvectorize.hpp @@ -1,20 +1,21 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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_VECTORIZE_HPP #define PY_VECTORIZE_HPP #include -#include "pyarray.hpp" #include "xtensor/xvectorize.hpp" +#include "pyarray.hpp" + namespace xt { @@ -53,10 +54,12 @@ namespace xt } template - inline auto pyvectorize(F&& f) -> decltype(pyvectorize(std::forward(f), (detail::get_function_type*)nullptr)) + inline auto pyvectorize(F&& f) + -> decltype(pyvectorize(std::forward(f), (detail::get_function_type*) nullptr)) { - return pyvectorize(std::forward(f), (detail::get_function_type*)nullptr); + return pyvectorize(std::forward(f), (detail::get_function_type*) nullptr); } + /// @endcond } diff --git a/include/xtensor-python/xtensor_python_config.hpp b/include/xtensor-python/xtensor_python_config.hpp index 7466f14..492b963 100644 --- a/include/xtensor-python/xtensor_python_config.hpp +++ b/include/xtensor-python/xtensor_python_config.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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_PYTHON_CONFIG_HPP #define XTENSOR_PYTHON_CONFIG_HPP diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 840e28c..1c1f85b 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -1,25 +1,25 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 -#include #include +#include #include -#include "xtensor/xtensor.hpp" -#include "xtensor/xfixed.hpp" - #include #include +#include "xtensor/xfixed.hpp" +#include "xtensor/xtensor.hpp" + namespace pybind11 { namespace detail @@ -102,7 +102,6 @@ namespace pybind11 } }; - template struct pybind_array_dim_checker { @@ -133,7 +132,6 @@ namespace pybind11 } }; - template struct pybind_array_shape_checker { @@ -163,10 +161,15 @@ namespace pybind11 { // TODO: make use of xt::pyarray instead of array. std::vector python_strides(src.strides().size()); - std::transform(src.strides().begin(), src.strides().end(), - python_strides.begin(), [](auto v) { - return sizeof(typename Type::value_type) * v; - }); + std::transform( + src.strides().begin(), + src.strides().end(), + python_strides.begin(), + [](auto v) + { + return sizeof(typename Type::value_type) * v; + } + ); std::vector python_shape(src.shape().size()); std::copy(src.shape().begin(), src.shape().end(), python_shape.begin()); @@ -181,10 +184,10 @@ namespace pybind11 return a.release(); } - // 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. + // 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 handle xtensor_ref_array(CType& src, handle parent = none()) { @@ -198,7 +201,13 @@ namespace pybind11 template handle xtensor_encapsulate(CType* src) { - capsule base(src, [](void* o) { delete static_cast(o); }); + capsule base( + src, + [](void* o) + { + delete static_cast(o); + } + ); return xtensor_ref_array(*src, base); } @@ -206,7 +215,6 @@ namespace pybind11 template struct xtensor_type_caster_base { - private: // Cast implementation @@ -215,26 +223,29 @@ namespace pybind11 { switch (policy) { - case return_value_policy::take_ownership: - case return_value_policy::automatic: - return xtensor_encapsulate(src); - case return_value_policy::move: - return xtensor_encapsulate(new CType(std::move(*src))); - case return_value_policy::copy: - return xtensor_array_cast(*src); - case return_value_policy::reference: - case return_value_policy::automatic_reference: - return xtensor_ref_array(*src); - case return_value_policy::reference_internal: - return xtensor_ref_array(*src, parent); - default: - throw cast_error("unhandled return_value_policy: should not happen!"); + case return_value_policy::take_ownership: + case return_value_policy::automatic: + return xtensor_encapsulate(src); + case return_value_policy::move: + return xtensor_encapsulate(new CType(std::move(*src))); + case return_value_policy::copy: + return xtensor_array_cast(*src); + case return_value_policy::reference: + case return_value_policy::automatic_reference: + return xtensor_ref_array(*src); + case return_value_policy::reference_internal: + return xtensor_ref_array(*src, parent); + default: + throw cast_error("unhandled return_value_policy: should not happen!"); }; } public: - PYBIND11_TYPE_CASTER(Type, _("numpy.ndarray[") + npy_format_descriptor::name + _("]")); + PYBIND11_TYPE_CASTER( + Type, + _("numpy.ndarray[") + npy_format_descriptor::name + _("]") + ); bool load(handle src, bool convert) { @@ -284,7 +295,8 @@ namespace pybind11 // lvalue reference return; default (automatic) becomes copy static handle cast(Type& src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) + if (policy == return_value_policy::automatic + || policy == return_value_policy::automatic_reference) { policy = return_value_policy::copy; } @@ -295,7 +307,8 @@ namespace pybind11 // const lvalue reference return; default (automatic) becomes copy static handle cast(const Type& src, return_value_policy policy, handle parent) { - if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) + if (policy == return_value_policy::automatic + || policy == return_value_policy::automatic_reference) { policy = return_value_policy::copy; } diff --git a/readthedocs.yml b/readthedocs.yml index 02f0e7b..004a03a 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -1,2 +1,2 @@ conda: - file: docs/environment.yml + file: docs/environment.yml diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0c77b0d..91bebfd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -100,4 +100,3 @@ if(DOWNLOAD_GTEST OR GTEST_SRC_DIR) endif() add_custom_target(xtest COMMAND ./test_xtensor_python DEPENDS test_xtensor_python) - diff --git a/test/copyGTest.cmake.in b/test/copyGTest.cmake.in index 8341a74..aeb2e2a 100644 --- a/test/copyGTest.cmake.in +++ b/test/copyGTest.cmake.in @@ -21,4 +21,3 @@ ExternalProject_Add(googletest INSTALL_COMMAND "" TEST_COMMAND "" ) - diff --git a/test/downloadGTest.cmake.in b/test/downloadGTest.cmake.in index 2d5cc5b..ba525b7 100644 --- a/test/downloadGTest.cmake.in +++ b/test/downloadGTest.cmake.in @@ -22,4 +22,3 @@ ExternalProject_Add(googletest INSTALL_COMMAND "" TEST_COMMAND "" ) - diff --git a/test/main.cpp b/test/main.cpp index d3cc6c4..37a5ac4 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,19 +1,19 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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. * + ****************************************************************************/ // Required to avoid the error "std does not have member copysign" #include -#include "gtest/gtest.h" - #include +#include "gtest/gtest.h" + #define FORCE_IMPORT_ARRAY #include "xtensor-python/pyarray.hpp" @@ -32,4 +32,3 @@ int main(int argc, char* argv[]) // Return test results return ret; } - diff --git a/test/test_common.hpp b/test/test_common.hpp index 07a0992..ff2b49b 100644 --- a/test/test_common.hpp +++ b/test/test_common.hpp @@ -1,11 +1,11 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 TEST_COMMON_HPP #define TEST_COMMON_HPP @@ -62,12 +62,35 @@ namespace xt layout_type m_layout; assigner_type m_assigner; - inline size_type size() const { return m_data.size(); } - inline const shape_type& shape() const { return m_shape; } - inline const strides_type& strides() const { return m_strides; } - inline const strides_type& backstrides() const { return m_backstrides; } - inline layout_type layout() const { return m_layout; } - inline const vector_type& data() const { return m_data; } + inline size_type size() const + { + return m_data.size(); + } + + inline const shape_type& shape() const + { + return m_shape; + } + + inline const strides_type& strides() const + { + return m_strides; + } + + inline const strides_type& backstrides() const + { + return m_backstrides; + } + + inline layout_type layout() const + { + return m_layout; + } + + inline const vector_type& data() const + { + return m_data; + } }; template > @@ -77,9 +100,8 @@ namespace xt { this->m_strides = {8, 4, 1}; this->m_backstrides = {16, 4, 3}; - this->m_data = {-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23}; + this->m_data = { + -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; this->m_layout = layout_type::row_major; } }; @@ -91,10 +113,8 @@ namespace xt { this->m_strides = {1, 3, 6}; this->m_backstrides = {2, 3, 18}; - this->m_data = {-1, 8, 16, 4, 12, 20, - 1, 9, 17, 5, 13, 21, - 2, 10, 18, 6, 14, 22, - 3, 11, 19, 7, 15, 23}; + this->m_data = { + -1, 8, 16, 4, 12, 20, 1, 9, 17, 5, 13, 21, 2, 10, 18, 6, 14, 22, 3, 11, 19, 7, 15, 23}; this->m_layout = layout_type::column_major; } }; @@ -106,9 +126,8 @@ namespace xt { this->m_strides = {8, 1, 2}; this->m_backstrides = {16, 1, 6}; - this->m_data = {-1, 4, 1, 5, 2, 6, 3, 7, - 8, 12, 9, 13, 10, 14, 11, 15, - 16, 20, 17, 21, 18, 22, 19, 23}; + this->m_data = { + -1, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15, 16, 20, 17, 21, 18, 22, 19, 23}; this->m_layout = layout_type::dynamic; } }; @@ -147,12 +166,35 @@ namespace xt layout_type m_layout; assigner_type m_assigner; - inline size_type size() const { return m_data.size(); } - inline const shape_type& shape() const { return m_shape; } - inline const strides_type& strides() const { return m_strides; } - inline const strides_type& backstrides() const { return m_backstrides; } - inline layout_type layout() const { return m_layout; } - inline const vector_type& data() const { return m_data; } + inline size_type size() const + { + return m_data.size(); + } + + inline const shape_type& shape() const + { + return m_shape; + } + + inline const strides_type& strides() const + { + return m_strides; + } + + inline const strides_type& backstrides() const + { + return m_backstrides; + } + + inline layout_type layout() const + { + return m_layout; + } + + inline const vector_type& data() const + { + return m_data; + } }; template @@ -160,7 +202,9 @@ 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())); - EXPECT_TRUE(std::equal(vec.backstrides().cbegin(), vec.backstrides().cend(), result.backstrides().cbegin())); + EXPECT_TRUE( + std::equal(vec.backstrides().cbegin(), vec.backstrides().cend(), result.backstrides().cbegin()) + ); EXPECT_EQ(vec.size(), result.size()); if (compare_layout) { @@ -245,14 +289,10 @@ namespace xt EXPECT_EQ(vt.shape(), shape_new); EXPECT_TRUE(std::equal(vt.storage().cbegin(), vt.storage().cend(), rm.m_data.cbegin())); - strides_type new_strides = {rm.m_strides[2], - rm.m_strides[1], - rm.m_strides[0]}; + strides_type new_strides = {rm.m_strides[2], rm.m_strides[1], rm.m_strides[0]}; EXPECT_EQ(vt.strides(), new_strides); - strides_type new_backstrides = {rm.m_backstrides[2], - rm.m_backstrides[1], - rm.m_backstrides[0]}; + strides_type new_backstrides = {rm.m_backstrides[2], rm.m_backstrides[1], rm.m_backstrides[0]}; EXPECT_EQ(vt.backstrides(), new_backstrides); EXPECT_EQ(vec_copy(0, 0, 0), vt(0, 0, 0)); @@ -278,9 +318,7 @@ namespace xt EXPECT_TRUE(std::equal(vt.shape().cbegin(), vt.shape().cend(), shape_new.begin())); EXPECT_TRUE(std::equal(vt.storage().cbegin(), vt.storage().cend(), rm.m_data.cbegin())); - strides_type new_strides = {rm.m_strides[1], - rm.m_strides[0], - rm.m_strides[2]}; + strides_type new_strides = {rm.m_strides[1], rm.m_strides[0], rm.m_strides[2]}; EXPECT_EQ(vt.strides(), new_strides); // strides_type new_backstrides = {rm.m_backstrides[1], @@ -331,7 +369,7 @@ namespace xt #ifdef XTENSOR_ENABLE_ASSERT EXPECT_ANY_THROW(vec(10, 10, 10)); #else - (void)vec; + (void) vec; #endif } @@ -582,7 +620,7 @@ namespace xt vecrm.resize(rm.m_shape, layout_type::row_major); std::copy(rm.data().cbegin(), rm.data().cend(), vecrm.template begin()); EXPECT_TRUE(std::equal(rm.data().cbegin(), rm.data().cend(), vecrm.storage().cbegin())); - //EXPECT_EQ(vecrm.template end(), vecrm.data().end()); + // EXPECT_EQ(vecrm.template end(), vecrm.data().end()); } { @@ -591,7 +629,7 @@ namespace xt veccm.resize(cm.m_shape, layout_type::column_major); std::copy(cm.data().cbegin(), cm.data().cend(), veccm.template begin()); EXPECT_TRUE(std::equal(cm.data().cbegin(), cm.data().cend(), veccm.storage().cbegin())); - //EXPECT_EQ(veccm.template end(), veccm.data().end()); + // EXPECT_EQ(veccm.template end(), veccm.data().end()); } } diff --git a/test/test_pyarray.cpp b/test/test_pyarray.cpp index 3f509e3..73e295d 100644 --- a/test/test_pyarray.cpp +++ b/test/test_pyarray.cpp @@ -1,20 +1,18 @@ /*************************************************************************** -* 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" + * 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 "xtensor/xarray.hpp" #include "xtensor/xview.hpp" +#include "gtest/gtest.h" #include "test_common.hpp" +#include "xtensor-python/pyarray.hpp" namespace xt { @@ -23,53 +21,39 @@ namespace xt template using ndarray = pyarray; - void test1 (ndarrayconst& x) + void test1(const ndarray& x) { ndarray y = x; ndarray z = xt::zeros({10}); } - double compute(ndarray const& xs) + double compute(const ndarray& xs) { - auto v = xt::view (xs, 0, xt::all()); + auto v = xt::view(xs, 0, xt::all()); return v(0); } TEST(pyarray, initializer_constructor) { - pyarray r - {{{ 0, 1, 2}, - { 3, 4, 5}, - { 6, 7, 8}}, - {{ 9, 10, 11}, - {12, 13, 14}, - {15, 16, 17}}}; + pyarray r{{{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); 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}}}; + 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}}}; + 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); @@ -86,7 +70,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 +134,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); @@ -201,8 +185,8 @@ namespace xt TEST(pyarray, extended_constructor) { - xt::xarray a1 = { { 1, 2 },{ 3, 4 } }; - xt::xarray a2 = { { 1, 2 },{ 3, 4 } }; + xt::xarray a1 = {{1, 2}, {3, 4}}; + xt::xarray a2 = {{1, 2}, {3, 4}}; pyarray 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)); @@ -227,7 +211,7 @@ namespace xt pyarray a; test_resize(a); - pyarray b = { {1, 2}, {3, 4} }; + pyarray b = {{1, 2}, {3, 4}}; a.resize(b.shape()); EXPECT_EQ(a.shape(), b.shape()); } @@ -277,7 +261,7 @@ namespace xt EXPECT_EQ(2, a1(1)); EXPECT_EQ(4, a2(1, 1)); } - + TEST(pyarray, zerod) { pyarray a; @@ -286,7 +270,7 @@ namespace xt TEST(pyarray, reshape) { - pyarray a = {{1,2,3}, {4,5,6}}; + pyarray a = {{1, 2, 3}, {4, 5, 6}}; auto ptr = a.data(); a.reshape({1, 6}); std::vector sc1({1, 6}); @@ -300,7 +284,7 @@ namespace xt TEST(pyarray, view) { - xt::pyarray arr = xt::zeros({ 10 }); + xt::pyarray arr = xt::zeros({10}); auto v = xt::view(arr, xt::all()); EXPECT_EQ(v(0), 0.); } diff --git a/test/test_pyarray_traits.cpp b/test/test_pyarray_traits.cpp index fe9ef6a..a4d2b25 100644 --- a/test/test_pyarray_traits.cpp +++ b/test/test_pyarray_traits.cpp @@ -1,26 +1,23 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 + class pyarray_traits : public ::testing::Test { protected: - + using dynamic_type = xt::pyarray; using row_major_type = xt::pyarray; using column_major_type = xt::pyarray; @@ -35,13 +32,13 @@ namespace xt column_major_type c2 = {{0., 2.}, {0., 20.}, {0., 200.}}; template - bool test_has_strides(T const&) + bool test_has_strides(const T&) { return xt::has_strides::value; } template - xt::layout_type test_result_layout(T const& a1, T const& a2) + xt::layout_type test_result_layout(const T& a1, const T& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); @@ -49,7 +46,7 @@ namespace xt } template - bool test_linear_assign(T const& a1, T const& a2) + bool test_linear_assign(const T& a1, const T& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); @@ -58,7 +55,7 @@ namespace xt } template - bool test_static_simd_linear_assign(T const& a1, T const& a2) + bool test_static_simd_linear_assign(const T& a1, const T& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); @@ -66,7 +63,7 @@ namespace xt } template - bool test_dynamic_simd_linear_assign(T const& a1, T const& a2) + bool test_dynamic_simd_linear_assign(const T& a1, const T& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); @@ -74,7 +71,7 @@ namespace xt } template - bool test_linear_static_layout(T const& a1, T const& a2) + bool test_linear_static_layout(const T& a1, const T& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); @@ -82,7 +79,7 @@ namespace xt } template - bool test_contiguous_layout(T const& a1, T const& a2) + bool test_contiguous_layout(const T& a1, const T& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); diff --git a/test/test_pytensor.cpp b/test/test_pytensor.cpp index f2ac013..e1aa4f3 100644 --- a/test/test_pytensor.cpp +++ b/test/test_pytensor.cpp @@ -1,20 +1,18 @@ /*************************************************************************** -* 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/pytensor.hpp" + * 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 "xtensor/xtensor.hpp" #include "xtensor/xview.hpp" +#include "gtest/gtest.h" #include "test_common.hpp" +#include "xtensor-python/pytensor.hpp" namespace xt { @@ -22,13 +20,7 @@ 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); @@ -170,8 +162,8 @@ namespace xt TEST(pytensor, extended_constructor) { - xt::xtensor a1 = { {1, 2}, {3, 4} }; - xt::xtensor a2 = { {1, 2}, {3, 4} }; + xt::xtensor a1 = {{1, 2}, {3, 4}}; + xt::xtensor a2 = {{1, 2}, {3, 4}}; pytensor 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)); @@ -184,7 +176,7 @@ namespace xt pytensor a; test_resize, container_type>(a); - pytensor b = { { { 1, 2 },{ 3, 4 } } }; + pytensor b = {{{1, 2}, {3, 4}}}; a.resize(b.shape()); EXPECT_EQ(a.shape(), b.shape()); } @@ -232,9 +224,9 @@ namespace xt TEST(pytensor, reshape) { - pytensor a = {{1,2,3}, {4,5,6}}; + pytensor a = {{1, 2, 3}, {4, 5, 6}}; auto ptr = a.data(); - a.reshape(a.shape()); // compilation check + a.reshape(a.shape()); // compilation check a.reshape({1, 6}); EXPECT_EQ(ptr, a.data()); EXPECT_THROW(a.reshape(std::vector{6}), std::runtime_error); @@ -245,16 +237,16 @@ namespace xt TEST(pytensor, view) { - xt::pytensor arr = xt::zeros({ 10 }); + xt::pytensor arr = xt::zeros({10}); auto v = xt::view(arr, xt::all()); EXPECT_EQ(v(0), 0.); } TEST(pytensor, unary) { - pytensor a = { 1, 2, 3 }; + pytensor a = {1, 2, 3}; pytensor res = -a; - pytensor ref = { -1, -2, -3 }; + pytensor ref = {-1, -2, -3}; EXPECT_EQ(ref(0), res(0)); EXPECT_EQ(ref(1), res(1)); EXPECT_EQ(ref(1), res(1)); @@ -264,9 +256,9 @@ namespace xt { // 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 }; + pytensor a = {1.0, 2.0, 3.0}; a /= 2; - pytensor ref = { 0.5, 1.0, 1.5 }; + 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)); diff --git a/test/test_pyvectorize.cpp b/test/test_pyvectorize.cpp index 30378e6..f11133a 100644 --- a/test/test_pyvectorize.cpp +++ b/test/test_pyvectorize.cpp @@ -1,18 +1,18 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 "pybind11/numpy.h" +#include "pybind11/pybind11.h" #include "test_common.hpp" #include "xtensor-python/pytensor.hpp" #include "xtensor-python/pyvectorize.hpp" -#include "pybind11/pybind11.h" -#include "pybind11/numpy.h" namespace xt { @@ -27,7 +27,7 @@ namespace xt TEST(pyvectorize, function) { auto vecf1 = pyvectorize(f1); - shape_type shape = { 3, 2 }; + shape_type shape = {3, 2}; pyarray a(shape, 1.5); pyarray b(shape, 2.3); pyarray c = vecf1(a, b); @@ -36,8 +36,13 @@ namespace xt TEST(pyvectorize, lambda) { - auto vecf1 = pyvectorize([](double a, double b) { return a + b; }); - shape_type shape = { 3, 2 }; + auto vecf1 = pyvectorize( + [](double a, double b) + { + return a + b; + } + ); + shape_type shape = {3, 2}; pyarray a(shape, 1.5); pyarray b(shape, 2.3); pyarray c = vecf1(a, b); @@ -47,9 +52,14 @@ namespace xt TEST(pyvectorize, complex) { using complex_t = std::complex; - shape_type shape = { 3, 2 }; + shape_type shape = {3, 2}; pyarray a(shape, complex_t(1.2, 2.5)); - auto f = pyvectorize([](complex_t x) { return std::abs(x); }); + auto f = pyvectorize( + [](complex_t x) + { + return std::abs(x); + } + ); auto res = f(a); double exp = std::abs(a(1, 1)); EXPECT_EQ(exp, res(1, 1)); diff --git a/test/test_sfinae.cpp b/test/test_sfinae.cpp index a614485..4577afd 100644 --- a/test/test_sfinae.cpp +++ b/test/test_sfinae.cpp @@ -1,20 +1,21 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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" +#include "gtest/gtest.h" +#include "xtensor-python/pyarray.hpp" +#include "xtensor-python/pytensor.hpp" + namespace xt { template ::value, int> = 0> diff --git a/test_python/main.cpp b/test_python/main.cpp index 7a0c524..961df4e 100644 --- a/test_python/main.cpp +++ b/test_python/main.cpp @@ -1,23 +1,24 @@ /*************************************************************************** -* 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. * -****************************************************************************/ + * 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 "xtensor/xmath.hpp" #include "xtensor/xarray.hpp" #include "xtensor/xfixed.hpp" +#include "xtensor/xmath.hpp" #define FORCE_IMPORT_ARRAY +#include "xtensor/xadapt.hpp" +#include "xtensor/xstrided_view.hpp" + #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; @@ -39,8 +40,8 @@ xt::xarray example3_xarray(const xt::xarray& m) return xt::transpose(m) + 2; } -xt::xarray example3_xarray_colmajor( - const xt::xarray& m) +xt::xarray +example3_xarray_colmajor(const xt::xarray& m) { return xt::transpose(m) + 2; } @@ -55,13 +56,14 @@ xt::xtensor example3_xtensor2(const xt::xtensor& m) return xt::transpose(m) + 2; } -xt::xtensor example3_xtensor2_colmajor( - const xt::xtensor& m) +xt::xtensor +example3_xtensor2_colmajor(const xt::xtensor& m) { return xt::transpose(m) + 2; } -xt::xtensor_fixed> example3_xfixed3(const xt::xtensor_fixed>& m) +xt::xtensor_fixed> +example3_xfixed3(const xt::xtensor_fixed>& m) { return xt::transpose(m) + 2; } @@ -71,8 +73,8 @@ xt::xtensor_fixed> example3_xfixed2(const xt::xtensor_fixe 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) +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; } @@ -87,13 +89,14 @@ double readme_example1(xt::pyarray& m) double readme_example2(double i, double j) { - return std::sin(i) - std::cos(j); + return std::sin(i) - std::cos(j); } auto complex_overload(const xt::pyarray>& a) { return a; } + auto no_complex_overload(const xt::pyarray& a) { return a; @@ -108,6 +111,7 @@ auto no_complex_overload_reg(const double& a) { return a; } + // // Operator examples // @@ -138,15 +142,59 @@ int add(int i, int j) return i + j; } -template std::string typestring() { return "Unknown"; } -template <> std::string typestring() { return "uint8"; } -template <> std::string typestring() { return "int8"; } -template <> std::string typestring() { return "uint16"; } -template <> std::string typestring() { return "int16"; } -template <> std::string typestring() { return "uint32"; } -template <> std::string typestring() { return "int32"; } -template <> std::string typestring() { return "uint64"; } -template <> std::string typestring() { return "int64"; } +template +std::string typestring() +{ + return "Unknown"; +} + +template <> +std::string typestring() +{ + return "uint8"; +} + +template <> +std::string typestring() +{ + return "int8"; +} + +template <> +std::string typestring() +{ + return "uint16"; +} + +template <> +std::string typestring() +{ + return "int16"; +} + +template <> +std::string typestring() +{ + return "uint32"; +} + +template <> +std::string typestring() +{ + return "int32"; +} + +template <> +std::string typestring() +{ + return "uint64"; +} + +template <> +std::string typestring() +{ + return "int64"; +} template inline std::string int_overload(xt::pyarray& m) @@ -194,10 +242,21 @@ struct B class C { public: + using array_type = xt::xarray; - C() : m_array{0, 0, 0, 0} {} - array_type & array() { return m_array; } + + C() + : m_array{0, 0, 0, 0} + { + } + + array_type& array() + { + return m_array; + } + private: + array_type m_array; }; @@ -206,7 +265,7 @@ struct test_native_casters using array_type = xt::xarray; array_type a = xt::ones({50, 50}); - const auto & get_array() + const auto& get_array() { return a; } @@ -235,7 +294,7 @@ struct test_native_casters auto get_owning_array_adapter() { size_t size = 100; - int * data = new int[size]; + int* data = new int[size]; std::fill(data, data + size, 1); using shape_type = std::vector; @@ -301,7 +360,7 @@ xt::pytensor xscalar(const xt::pytensor& arg) template using ndarray = xt::pyarray; -void test_rm(ndarrayconst& x) +void test_rm(const ndarray& x) { ndarray y = x; ndarray z = xt::zeros({10}); @@ -336,14 +395,26 @@ 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); })); + m.def( + "rect_to_polar", + xt::pyvectorize( + [](complex_t x) + { + return std::abs(x); + } + ) + ); - m.def("compare_shapes", [](const xt::pyarray& a, const xt::pyarray& b) { - return a.shape() == b.shape(); - }); + m.def( + "compare_shapes", + [](const xt::pyarray& a, const xt::pyarray& b) + { + return a.shape() == b.shape(); + } + ); m.def("test_rm", test_rm); @@ -375,28 +446,101 @@ PYBIND11_MODULE(xtensor_python_test, m) .def(py::init<>()) .def_property_readonly( "copy", - [](C & self) { return self.array(); } + [](C& self) + { + return self.array(); + } ) .def_property_readonly( "ref", - [](C & self) -> C::array_type & { return self.array(); } - ) - ; - - 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; }); + [](C& self) -> C::array_type& + { + return self.array(); + } + ); + + 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; + } + ); 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>()); + .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>() + ); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy