Skip to content

Commit 5bdde06

Browse files
Merge pull request #53 from JohanMabille/test_vectorize
pyvectorize c++ unit test
2 parents 94e9f39 + 39c86fe commit 5bdde06

File tree

5 files changed

+114
-19
lines changed

5 files changed

+114
-19
lines changed

.appveyor.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@ install:
2222
- conda config --set always_yes yes --set changeps1 no
2323
- conda update -q conda
2424
- conda info -a
25-
- conda install pytest -c conda-forge
26-
- conda install xtensor==0.8.0 pytest numpy pybind11==2.1.0 -c conda-forge
27-
- xcopy /S %APPVEYOR_BUILD_FOLDER%\include %MINICONDA%\include
25+
- conda install gtest cmake -c conda-forge
26+
- conda install xtensor==0.8.1 pytest numpy pybind11==2.1.0 -c conda-forge
27+
- cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\Library -DBUILD_TESTS=ON .
28+
- nmake test_xtensor_python
29+
- nmake install
2830

2931
build_script:
3032
- py.test -s
33+
- cd test
34+
- .\test_xtensor_python

.travis.yml

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ env:
5252
- MINCONDA_VERSION="latest"
5353
- MINCONDA_LINUX="Linux-x86_64"
5454
- MINCONDA_OSX="MacOSX-x86_64"
55+
before_install:
56+
- |
57+
# Configure build variables
58+
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
59+
if [[ "$COMPILER" == "gcc" ]]; then
60+
export CXX=g++-$GCC CC=gcc-$GCC;
61+
fi
62+
if [[ "$COMPILER" == "clang" ]]; then
63+
export CXX=clang++-$CLANG CC=clang-$CLANG;
64+
fi
65+
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
66+
export CXX=clang++ CC=clang PYTHONHOME=$HOME/miniconda;
67+
fi
68+
5569
install:
5670
# Define the version of miniconda to download
5771
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
@@ -67,21 +81,17 @@ install:
6781
- conda update -q conda
6882
# Useful for debugging any issues with conda
6983
- conda info -a
70-
- conda install xtensor==0.8.0 pytest numpy pybind11==2.1.0 -c conda-forge
71-
- cp -r $TRAVIS_BUILD_DIR/include/* $HOME/miniconda/include/
84+
- conda install xtensor==0.8.1 pytest numpy pybind11==2.1.0 -c conda-forge
85+
- cd test
86+
- conda env create -f ./test-environment.yml
87+
- source activate test-xtensor-python
88+
- cd ..
89+
- cmake -DBUILD_TESTS=ON -D CMAKE_INSTALL_PREFIX=$HOME/miniconda .
90+
- make -j2 test_xtensor_python
91+
- make install
7292

7393
script:
74-
- |
75-
# Configure build variables
76-
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
77-
if [[ "$COMPILER" == "gcc" ]]; then
78-
export CXX=g++-$GCC CC=gcc-$GCC;
79-
fi
80-
if [[ "$COMPILER" == "clang" ]]; then
81-
export CXX=clang++-$CLANG CC=clang-$CLANG;
82-
fi
83-
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
84-
export CXX=clang++ CC=clang;
85-
fi
8694
- py.test -s
95+
- cd test
96+
- ./test_xtensor_python
8797

test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ include_directories(${GTEST_INCLUDE_DIRS})
106106

107107
set(XTENSOR_PYTHON_TESTS
108108
main.cpp
109-
test_pytensor.cpp
110109
test_pyarray.cpp
110+
test_pytensor.cpp
111+
test_pyvectorize.cpp
111112
)
112113

113114
set(XTENSOR_PYTHON_TARGET test_xtensor_python)

test/test-environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: test-xtensor
1+
name: test-xtensor-python
22
channels:
33
- conda-forge
44
- defaults

test/test_pyvectorize.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/***************************************************************************
2+
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay *
3+
* *
4+
* Distributed under the terms of the BSD 3-Clause License. *
5+
* *
6+
* The full license is in the file LICENSE, distributed with this software. *
7+
****************************************************************************/
8+
9+
#include "gtest/gtest.h"
10+
#include "test_common.hpp"
11+
#include "xtensor-python/pytensor.hpp"
12+
#include "xtensor-python/pyvectorize.hpp"
13+
#include "pybind11/pybind11.h"
14+
#include "pybind11/numpy.h"
15+
16+
namespace xt
17+
{
18+
19+
double f1(double a, double b)
20+
{
21+
return a + b;
22+
}
23+
24+
using shape_type = std::vector<std::size_t>;
25+
26+
TEST(pyvectorize, function)
27+
{
28+
auto vecf1 = pyvectorize(f1);
29+
shape_type shape = { 3, 2 };
30+
pyarray<double> a(shape, 1.5);
31+
pyarray<double> b(shape, 2.3);
32+
pyarray<double> c = vecf1(a, b);
33+
EXPECT_EQ(a(0, 0) + b(0, 0), c(0, 0));
34+
}
35+
36+
TEST(pyvectorize, lambda)
37+
{
38+
auto vecf1 = pyvectorize([](double a, double b) { return a + b; });
39+
shape_type shape = { 3, 2 };
40+
pyarray<double> a(shape, 1.5);
41+
pyarray<double> b(shape, 2.3);
42+
pyarray<double> c = vecf1(a, b);
43+
EXPECT_EQ(a(0, 0) + b(0, 0), c(0, 0));
44+
}
45+
46+
TEST(pyvectorize, complex)
47+
{
48+
using complex_t = std::complex<double>;
49+
shape_type shape = { 3, 2 };
50+
pyarray<complex_t> a(shape, complex_t(1.2, 2.5));
51+
auto f = [](const pyarray<complex_t>& t) {
52+
return std::make_tuple(pyvectorize([](complex_t x) { return std::abs(x); })(t),
53+
pyvectorize([](complex_t x) { return std::arg(x); })(t));
54+
};
55+
56+
auto res = f(a);
57+
double expected_abs = std::abs(a(1, 1));
58+
double expected_arg = std::arg(a(1, 1));
59+
EXPECT_EQ(expected_abs, std::get<0>(res)(1, 1));
60+
EXPECT_EQ(expected_arg, std::get<1>(res)(1, 1));
61+
}
62+
63+
TEST(pyvectorize, complex_pybind)
64+
{
65+
using complex_t = std::complex<double>;
66+
shape_type shape = { 3, 2 };
67+
pyarray<complex_t> a(shape, complex_t(1.2, 2.5));
68+
auto f = [](const pyarray<complex_t>& t) {
69+
return pybind11::make_tuple(pyvectorize([](complex_t x) { return std::abs(x); })(t),
70+
pyvectorize([](complex_t x) { return std::arg(x); })(t));
71+
};
72+
73+
auto res = f(a);
74+
double expected_abs = std::abs(a(1, 1));
75+
double expected_arg = std::arg(a(1, 1));
76+
77+
EXPECT_EQ(expected_abs, res[0].cast<pyarray<double>>()(1, 1));
78+
EXPECT_EQ(expected_arg, res[1].cast<pyarray<double>>()(1, 1));
79+
}
80+
}

0 commit comments

Comments
 (0)