Skip to content

Commit 9ec353b

Browse files
Fix vectorization of various binary op with integral operands
1 parent 608c571 commit 9ec353b

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

pythran/pythonic/types/vectorizable_type.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,33 @@ namespace numpy
2929
{
3030
namespace functor
3131
{
32+
struct arctan2;
3233
struct angle_in_rad;
3334
struct asarray_chkfinite;
3435
struct clip;
36+
struct copysign;
37+
struct divide;
3538
struct fix;
3639
struct floor_divide;
40+
struct fmod;
41+
struct hypot;
3742
struct isfinite;
3843
struct isinf;
3944
struct isnan;
4045
struct isposinf;
4146
struct ldexp;
47+
struct logaddexp;
4248
struct logaddexp2;
4349
struct maximum;
4450
struct minimum;
4551
struct nan_to_num;
4652
struct nextafter;
53+
struct power;
54+
struct remainder;
4755
struct rint;
4856
struct signbit;
4957
struct spacing;
58+
struct true_divide;
5059
struct where;
5160
}
5261
}
@@ -119,6 +128,21 @@ namespace types
119128
!std::is_same<O, numpy::functor::uint64>::value &&
120129
!std::is_same<O, numpy::functor::float32>::value &&
121130
!std::is_same<O, numpy::functor::float64>::value &&
131+
// not supported for integral numbers
132+
!(utils::any_of<std::is_integral<
133+
typename dtype_of<Args>::type>::value...>::value &&
134+
(std::is_same<O, numpy::functor::floor_divide>::value ||
135+
#if PY_MAJOR_VERSION >= 3
136+
std::is_same<O, numpy::functor::true_divide>::value ||
137+
std::is_same<O, numpy::functor::divide>::value ||
138+
#endif
139+
std::is_same<O, numpy::functor::arctan2>::value ||
140+
std::is_same<O, numpy::functor::copysign>::value ||
141+
std::is_same<O, numpy::functor::logaddexp>::value ||
142+
std::is_same<O, numpy::functor::power>::value ||
143+
std::is_same<O, numpy::functor::remainder>::value ||
144+
std::is_same<O, numpy::functor::hypot>::value ||
145+
std::is_same<O, numpy::functor::fmod>::value)) &&
122146
// special functions not in the scope of xsimd
123147
!std::is_same<O, scipy::special::functor::hankel1>::value &&
124148
!std::is_same<O, scipy::special::functor::hankel2>::value &&

pythran/tests/test_numpy_ufunc_binary.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,18 @@ class TestNumpyUFuncBinary(TestEnv):
3232
setattr(TestNumpyUFuncBinary, 'test_' + f, eval("lambda self: self.run_test('def np_{0}(a): from {1} import {0} ; return {0}(a,a)', numpy.ones(10), np_{0}=[NDArray[float, :]])".format(f, ns)))
3333
setattr(TestNumpyUFuncBinary, 'test_' + f + '_scalar', eval("lambda self: self.run_test('def np_{0}_scalar(a): from {1} import {0} ; return {0}(a+0.5, a+0.5)', 0.5, np_{0}_scalar=[float])".format(f, ns)))
3434
setattr(TestNumpyUFuncBinary, 'test_' + f + '_matrix', eval("lambda self: self.run_test('def np_{0}_matrix(a): from {1} import {0} ; return {0}(a,a)', numpy.ones((2,5)) - 0.2 , np_{0}_matrix=[NDArray[float,:,:]])".format(f, ns)))
35-
## Tests for complex numbers
35+
## Tests for complex numbers
3636
try:
3737
eval('{1}.{0}(1.j, 1.j)'.format(f, ns))
3838
setattr(TestNumpyUFuncBinary, 'test_' + f + '_complex', eval("lambda self: self.run_test('def np_{0}_complex(a): from {1} import {0} ; return {0}(a,a)', numpy.ones(10)*1.j, np_{0}_complex=[NDArray[complex, :]])".format(f, ns)))
3939
except TypeError:
4040
pass
41+
## Tests for integral numbers
42+
try:
43+
eval('{1}.{0}(1, 1)'.format(f, ns))
44+
setattr(TestNumpyUFuncBinary, 'test_' + f + '_integer', eval("lambda self: self.run_test('def np_{0}_integer(a): from {1} import {0} ; return {0}(a, a)', numpy.ones(10,dtype=int), np_{0}_integer=[NDArray[int, :]])".format(f, ns)))
45+
except TypeError:
46+
pass
4147

4248
## Tests for accumulation
4349
if 'scipy' not in ns:

0 commit comments

Comments
 (0)