Skip to content

Add where= parameter to ufuncs #99

Closed
wants to merge 24 commits into from

4 participants

@mwiebe
NumPy member
mwiebe commented Jun 29, 2011

Also made a standard mechanism for inner loop auxiliary data, converting the existing low level casting loops to use it. I've also moved the ufunc type promotion functions into their own file to tame the ufunc_object.c monster a tiny bit.

A simple test, mainly showing how poorly boolean indexing performs:

In [24]: a = np.ones((1000,1000))
In [25]: b = np.ones((1000,1000))
In [26]: c = np.zeros((1000, 1000))
In [27]: m = np.random.rand(1000,1000) > 0.5

In [28]: timeit c[m] = a[m] + b[m]
1 loops, best of 3: 246 ms per loop

In [29]: timeit np.add(a, b, out=c, where=m)
10 loops, best of 3: 20.3 ms per loop

In [30]: timeit np.add(a, b, out=c)
100 loops, best of 3: 12.4 ms per loop
@dhomeier

Impressive speedup indeed, also getting 10-12x improvement for all but transcendental operations (np.power(a, b)...).
I did notice an instability not directly related (found at last it also is present in 1.6's np.add): If you pass an output array with a inconsistent dtype, like
```>>> a = np.ones((1000,1000), dtype=np.int64)

b = np.ones((1000,1000), dtype=np.int64)
c = np.zeros((1000,1000))
np.add(a, b, out=c)
Bus error
or alternatively
>>> a = np.ones((1000,1000), dtype=np.int32)
b = np.ones((1000,1000), dtype=np.int32)
c = np.zeros((1000,1000))
np.add(a, b, out=c)
python2.7(96832) malloc: *** error for object 0x100ae4008: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap```
I don't know if it would be possible to catch such incorrect input, but maybe you could have a look at it while you are working at this...

@mwiebe
NumPy member
mwiebe commented Jun 29, 2011

Thanks. The crashes you're getting definitely shouldn't be happening (NumPy should never crash!), it should automatically convert the data (raising an exception if it's violating the casting rule).

@dhomeier

Since this is the missing data branch, I am also reporting some Python3-errors with tests updated from your previous masked array commits:
```ERROR: Test of inplace division
.
Traceback (most recent call last):
File "/Users/derek/lib/python3.2/site-packages/numpy/ma/tests/test_core.py", line 1703, in test_inplace_division_scalar_int
x /= 2
File "/Users/derek/lib/python3.2/site-packages/numpy/ma/core.py", line 3755, in itruediv
ndarray.itruediv(self.data, np.where(self.mask, 1, other_data))
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''
.
ERROR: Test of inplace operations and rich comparisons
.
Traceback (most recent call last):
File "/Users/derek/lib/python3.2/site-packages/numpy/ma/tests/test_old_ma.py", line 489, in test_testInplace
x /= 2
File "/Users/derek/lib/python3.2/site-packages/numpy/ma/core.py", line 3755, in __itruediv

ndarray.itruediv(self._data, np.where(self._mask, 1, other_data))
TypeError: ufunc 'true_divide' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''

- all due to using```x / n``` for integer division. I'd attach the patch here if it was possible (just 4 changes to ```xm //= 2``` in the tests) - let me know if I should put it on Trac instead.
@mwiebe
NumPy member
mwiebe commented Jun 29, 2011

I've patched those integer divisions.

@charris
NumPy member
charris commented Jun 30, 2011

Bit more on the first segfault (64 bit linux)

#0  LONG_add (args=<optimized out>, dimensions=<optimized out>, 
    steps=<optimized out>, __NPY_UNUSED_TAGGEDfunc=<optimized out>)
    at numpy/core/src/umath/loops.c.src:724
#1  0x00007ffff09c6360 in iterator_loop (self=<optimized out>, 
    op=<optimized out>, dtype=<optimized out>, order=<optimized out>, 
    buffersize=<optimized out>, arr_prep=<optimized out>, arr_prep_args=0x0, 
    innerloop=0x7ffff09d6000 <LONG_add>, innerloopdata=0x0)
    at numpy/core/src/umath/ufunc_object.c:1273
#2  0x00007ffff09dd7f2 in execute_ufunc_loop (innerloopdata=0x0, innerloop=
    0x7ffff09d6000 <LONG_add>, arr_prep_args=0x0, arr_prep=0x7fffffffcd70, 
    buffersize=8192, order=NPY_KEEPORDER, dtype=0x7fffffffcc70, op=
    0x7fffffffd410, trivial_loop_ok=0, self=0x8adf80)
    at numpy/core/src/umath/ufunc_object.c:1412
#3  PyUFunc_GenericFunction (self=0x8adf80, args=
    (<numpy.ndarray at remote 0xe26c40>, <numpy.ndarray at remote 0xe9a0c0>), 
    kwds={'out': <numpy.ndarray at remote 0xe9c820>}, op=0x7fffffffd410)
    at numpy/core/src/umath/ufunc_object.c:2228
#4  0x00007ffff09de556 in ufunc_generic_call (self=0x8adf80, args=
    (<numpy.ndarray at remote 0xe26c40>, <numpy.ndarray at remote 0xe9a0c0>), 
    kwds={'out': <numpy.ndarray at remote 0xe9c820>})
    at numpy/core/src/umath/ufunc_object.c:3720
#5  0x0000003e42c48fe3 in PyObject_Call (func=
    <numpy.ufunc at remote 0x8adf80>, arg=<optimized out>, kw=<optimized out>)
@mwiebe
NumPy member
mwiebe commented Jun 30, 2011

Great, I think it would be good to put the crash info in its own trac ticket, since it's independent of this pull request. I can probably get to it some time after this is merged.

@mwiebe
NumPy member
mwiebe commented Jun 30, 2011

I've added some commits to deprecate some bad namespace pollution in the macros. I've started with some obviously bad C API stuff.

@charris charris commented on the diff Jun 30, 2011
doc/neps/missing-data.rst
@@ -291,8 +352,8 @@ New functions added to the ndarray are::
array is unmasked and has the 'NA' part stripped from the
parameterized type ('NA[f8]' becomes just 'f8').
- arr.view(masked=True)
- This is a shortcut for 'a = arr.view(); a.flags.hasmask=True'.
+ arr.view(namasked=True)
@charris
NumPy member
charris added a note Jun 30, 2011

I was thinking 'asnamasked' would be more descriptive, but it's getting a bit long.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@charris
NumPy member
charris commented Jul 1, 2011

Where might be more useful if it didn't overwrite the masked portions of the output.

In [43]: a = ones(10, int64)

In [44]: b = ones(10, int64)

In [45]: c = ones(10, float64)

In [46]: add(a,b,out=c, where=a>b)
Out[46]: 
array([  2.66916676e+11,   2.66916676e+11,   1.39708543e+14,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00])

Hmm, that seems to be part of the mixed type problem.

In [52]: c = ones(10, int64)

In [53]: add(a,b,out=c, where=a>b)
Out[53]: array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
@mwiebe
NumPy member
mwiebe commented Jul 1, 2011

I think it would be good to document the API deprecations before merging, but otherwise hopefully it's good to go? Thanks for the reviews!

@charris
NumPy member
charris commented Jul 1, 2011

I'm concerned about committing when there is a known segfault, otherwise I would have put it in last night. The problem looks to be in the source pointer for the copy to the output. It works fine without the where. Thoughts?

@mwiebe
NumPy member
mwiebe commented Jul 1, 2011

I haven't tried it, but I read Derek's comment to mean that this bug exists all the way back to 1.6, so this patch wasn't changing anything about it. I suppose I could just track it down first, sure.

@charris
NumPy member
charris commented Jul 1, 2011

Hmm, you're right. There may actually be two errors, or maybe some combination of the input being freed at different times. I was using small arrays for testing in the hope of avoiding the segfault, but I do see it with large arrays. However, the output is wrong in the small array (no segfault) case with mixed kinds and the where keyword.

@charris
NumPy member
charris commented Jul 2, 2011

Here is what I am talking about

In [14]: a = zeros(100, dtype=int64)

In [15]: c = zeros(100, dtype=float64)

In [16]: add(a, a, out=c, where=(arange(100)<5))
Out[16]: 
array([  0.,   0.,   0.,   0.,   0.,   5.,   6.,   7.,   8.,   9.,  10.,
    11.,  12.,  13.,  14.,  15.,  16.,  17.,  18.,  19.,  20.,  21.,
    22.,  23.,  24.,  25.,  26.,  27.,  28.,  29.,  30.,  31.,  32.,
    33.,  34.,  35.,  36.,  37.,  38.,  39.,  40.,  41.,  42.,  43.,
    44.,  45.,  46.,  47.,  48.,  49.,  50.,  51.,  52.,  53.,  54.,
    55.,  56.,  57.,  58.,  59.,  60.,  61.,  62.,  63.,  64.,  65.,
    66.,  67.,  68.,  69.,  70.,  71.,  72.,  73.,  74.,  75.,  76.,
    77.,  78.,  79.,  80.,  81.,  82.,  83.,  84.,  85.,  86.,  87.,
    88.,  89.,  90.,  91.,  92.,  93.,  94.,  95.,  96.,  97.,  98.,
    99.])

This behavior is actually different if the arrays are smaller. And if the output is int64

In [28]: a = zeros(100, dtype=int64)

In [29]: c = zeros(100, dtype=int64)

In [30]: add(a, a, out=c, where=(arange(100)<5))
Out[30]: 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0])
@charris
NumPy member
charris commented Jul 2, 2011

Playing with the bug{s}, there appears to be no problem with unary ufuncs.

@WeatherGod WeatherGod commented on the diff Jul 2, 2011
doc/neps/missing-data.rst
+down to two different ideas, each of which is internally self-consistent.
+
+One of them, the "unknown yet existing data" interpretation, can be applied
+rigorously to all computations, while the other makes sense for
+some statistical operations like standard deviation but not for
+linear algebra operations like matrix product.
+Thus, making "unknown yet existing data" be the default interpretation
+is superior, providing a consistent model across all computations,
+and for those operations where the other interpretation makes sense,
+an optional parameter "skipna=" can be added.
+
+For people who want the other interpretation to be default, a mechanism
+proposed elsewhere for customizing subclass ufunc behavior with a
+_numpy_ufunc_ member function would allow a subclass with a different
+default to be created.
+
@WeatherGod
WeatherGod added a note Jul 2, 2011

I assume this would be the approach where numpy.ma can be implemented to maintain backwards compatibility?

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

That should mostly be possible, yes. For the subtleties and features that the missing data abstraction doesn't provide, I'm also trying to make working with masks easier in general with things like the 'where=' parameter in ufuncs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
@@ -67,7 +85,7 @@ that is not NA, such as logical_and(NA, False) == False.
Some more complex arithmetic operations, such as matrix products, are
well defined with this interpretation, and the result should be
-the same as is the missing values were NaNs. Actually implementing
+the same as if if the missing values were NaNs. Actually implementing
@WeatherGod
WeatherGod added a note Jul 2, 2011

syntax error... double "if"s

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
Another useful interpretation is that the missing elements should be
treated as if they didn't exist in the array, and the operation should
do its best to interpret what that means according to the data
that's left. In this case, 'mean(a)' would compute the mean of just
the values that are unmasked, adjusting both the sum and count it
-uses based on the mask.
+uses based on the mask. To be consistent, the mean of an array of
@WeatherGod
WeatherGod added a note Jul 2, 2011

Have we introduced yet what a "mask" means?

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

No, that sounds like a good idea especially since a lot of confusion on the mailing list centers around that word.

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

Well, reading closer I think my definition of a mask is ok, just the phrasing of this sentence was wrong. It should be in terms of missing values, not masks. I suspect this is an artifact of the editing history.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
use when attempting to get best-guess answers for many statistical queries.
In R, many functions take a parameter "na.rm=T" which means to treat
the data as if the NA values are not part of the data set. This proposal
-defines a standard parameter "skipmissing=True" for this same purpose.
+defines a standard parameter "skipna=True" for this same purpose.
+
+********************************************
+Implementation Techniques For Missing Values
+********************************************
+
+In addition to there being two different interpretations of missing values,
+there are two different commonly used implementation techniques for
+missing values. While there are some differing default behaviors between
+existing implementations of the techniques, I believe that the design
+choices made in a new implementation must be made based on their merits,
+not by rote copying of previous designs even if some users have been
@WeatherGod
WeatherGod added a note Jul 2, 2011

It would be better to leave out potentially inflammatory statement by ending the sentence at "... of previous designs".

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

Good call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
+defines a standard parameter "skipna=True" for this same purpose.
+
+********************************************
+Implementation Techniques For Missing Values
+********************************************
+
+In addition to there being two different interpretations of missing values,
+there are two different commonly used implementation techniques for
+missing values. While there are some differing default behaviors between
+existing implementations of the techniques, I believe that the design
+choices made in a new implementation must be made based on their merits,
+not by rote copying of previous designs even if some users have been
+accustomed to those conventions.
+
+Each approach has positive and negative aspects to it, so this NEP
+proposed to implement both. To enable the writing of generic "missing
@WeatherGod
WeatherGod added a note Jul 2, 2011

both what? I always treat pronouns and other "referral" nouns like C-pointers that point to the last nouns in the previous clause. So here, it reads like you want to implement both the positive and negative aspects.

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

I've rephrased it with "strong and weak points", as well as naming the techniques directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
@@ -158,7 +214,7 @@ like 'arr[0]' would be throwing away the dtype, which is still
valuable to retain, so 'arr[0]' will return a zero-dimensional
array either with its value masked, or containing the NA bit pattern
for the array's dtype. To test if the value is missing, the function
-"np.ismissing(arr[0])" will be provided. One of the key reasons for the
+"np.isna(arr[0])" will be provided. One of the key reasons for the
@WeatherGod
WeatherGod added a note Jul 2, 2011

Just a thought... I do worry that some newbies may confuse NaNs/NA and isnan()/isna(). This should probably be taken into consideration when writing documentation.

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

That is the reason I preferred ismissing. It is nice for all the missing value functionality to have "na" in them somewhere, to tie them together. Since R has both is.na and is.nan, perhaps we can learn from their experience about potential confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
@@ -188,6 +244,11 @@ if a valid value in a masked array happens to have the NA bit pattern,
copying this value to the NA form of the dtype will cause it to
become NA as well.
+When operations are done between arrays with NA dtypes and masked arrays,
+the result will be masked arrays. This is because in some cases the
+NA dtypes cannot represent all the values in the masked array, so
+going to masked arrays is the only way to losslessly preserve the data.
@WeatherGod
WeatherGod added a note Jul 2, 2011

"losslessly preserve" is redundant.

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod and 1 other commented on an outdated diff Jul 2, 2011
doc/neps/missing-data.rst
@@ -230,7 +291,7 @@ space optimization, where a bit-level instead of a byte-level mask
is used to get a factor of eight memory usage improvement.
To access the mask values, there are two functions provided,
-'np.ismissing' and 'np.isavail', which test for NA or available values
+'np.isna' and 'np.isavail', which test for NA or available values
@WeatherGod
WeatherGod added a note Jul 2, 2011

how about "masked or unmasked elements, respectively"?

@mwiebe
NumPy member
mwiebe added a note Jul 5, 2011

If masks were the only implementation choice, this would work, but my intention here is to allow for generic code which is independent of that choice. I'll try to rephrase to make that clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod WeatherGod commented on the diff Jul 2, 2011
doc/neps/missing-data.rst
-If the 'out' parameter isn't specified, use of the 'mask=' parameter
-will produce an array with a mask as the result.
+If the 'out' parameter isn't specified, use of the 'where=' parameter
+will produce an array with a mask as the result, with missing values
+for everywhere the 'where' clause had the value False.
@WeatherGod
WeatherGod added a note Jul 2, 2011

What about for reductions? I assume that wouldn't be case? Furthermore, imagine a summation along the rows of a 2-D array where one of the rows is completely masked out. Currently, I believe numpy.ma returns a masked element for that situation (but I could be wrong here).

@WeatherGod
WeatherGod added a note Jul 2, 2011

I apologize. Doing line comments are great, but you lose context. I see that this paragraph is in the element-wise ufunc section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@WeatherGod

I just tried a clean build of this pull request on my 32-bit, python 2.7 platform. Somewhere during the tests, a glibc exception occurs with respect to a double-freeing of memory.

@mwiebe
NumPy member
mwiebe commented Jul 5, 2011

Sorry about the test error, I added tests for bugs that Derek and Chuck reported but haven't implemented fixes for them yet.

@charris
NumPy member
charris commented Jul 6, 2011

Hi Mark,

This is getting rather large. Would you mind if I committed the NEP and header cleanups separately and then you could rebase the remainder on top of that?

@mwiebe
NumPy member
mwiebe commented Jul 6, 2011

Sure, go for it!

@charris
NumPy member
charris commented Jul 6, 2011

Never mind, it isn't that easy to tease things apart ;)

@charris
NumPy member
charris commented Jul 6, 2011

Left out a cherry-pick, it works now. I'll put it up as a pull request.

Mark Wiebe added some commits Jun 27, 2011
Mark Wiebe ENH: missingdata: Add a mechanism to get masked versions of ufunc inn…
…er loops
64dc709
Mark Wiebe ENH: core: Create a new NpyAuxData mechanism for working with inner l…
…oop auxiliary data

There already was such a mechanism in the low level copying and casting
mechanism created for the iterator, so this mechanism has been refactored
into a form suitable for general purpose use.
c39e898
Mark Wiebe ENH: missingdata: Move getting the masked ufunc inner loop to a diffe…
…rent function

This is so that backwards compatibility can be retained with denying
regular ufuncs from supporting dynamic auxiliary data, but allowing
it for the masked inner loops so that the default masked loop can store the
regular inner loop it proxies calls to.
f3264e5
Mark Wiebe ENH: umath: Move the type resolution functions into their own file f0530c5
Mark Wiebe ENH: umath: Implement the default type resolution for masked loops
This function returns a loop which calls the unmasked loop on runs
of unmasked data.
8a16604
Mark Wiebe ENH: umath: Add parsing of a 'where=' parameter in the element-wise u…
…func
cb9b72a
Mark Wiebe ENH: umath: Write the function to call the masked inner loop 804ffb2
Mark Wiebe ENH: umath: Add tests, work out kinks in ufunc 'where=' parameter 88b3230
Mark Wiebe DOC: Document the ufunc 'where=' parameter and the NpyAuxData C API m…
…echanism
d4118e9
Mark Wiebe NEP: Trying to make the NEP's position on missing values and masks vs…
… bit patterns more clear
3c0fc55
Mark Wiebe TST: ma: Feedback from Derek about Python 3 failures in ma tests 2661166
Mark Wiebe NEP: missingdata: Various improvements 1853345
Mark Wiebe NEP: missing-data: Add name to acknowledgments c4485a9
Mark Wiebe NEP: missingdata: Rename 'hasmask' and friends to 'hasnamask' and fri…
…ends

This is an attempt to reduce potential confusion between the existing
numpy.ma and the NA-supporting built-in mask.
6616953
Mark Wiebe ENH: core: Deprecate some bad namespace-polluting macros
This one handles PyArray_DEFAULT -> NPY_DEFAULT_TYPE and
the NPY_* array flags -> NPY_ARRAY_*. The PyArray_DEFAULT vs NPY_DEFAULT
confusion was particularly egregious here.
f6ed770
Mark Wiebe TST: umath: Add tests for casting output parameters ecf589f
Mark Wiebe NEP: missing-data: Incorporate Ben's feedback, add section on 'shared…
… masks'

This includes an email comment from Ben about 'np.any' and 'np.all'.
20a594b
Mark Wiebe NEP: missing-data: Fix copy/paste/edit typo for np.all example 7b860ad
Mark Wiebe NEP: missing-data: Add glossary of terms, try to clarify them better
This is a step towards having everyone on the list use the same
vocabulary with specific nailed-down definitions for the terms.
4fca2e2
Mark Wiebe NEP: missing-data: Add numpy.ma to the glossary b68d5d3
Mark Wiebe NEP: missing-data: Add "Python API" and "C API" definitions c8ca7e0
Mark Wiebe NEP: missing-data: Add Peter to the Acknowledgments 715f541
Mark Wiebe DOC: c-api: Update to reflect array flag namespace change 9e65149
Mark Wiebe TST: ufunc: Disable where= buffering test temporarily
Will reenable it once masking iteration features are done.
758da37
@mwiebe
NumPy member
mwiebe commented Jul 6, 2011

The bug Derek found is fixed in master now. The bug Chuck found requires implementing mask features in the iterator to properly handle it, so I'd like to merge this as is with the bug still there. I've marked it as known fail, and will unmark it when it can be fixed.

@charris
NumPy member
charris commented Jul 6, 2011

Sounds good, I put it in.

@charris charris closed this Jul 6, 2011
@dhomeier
dhomeier commented Jul 7, 2011

Thanks for working on this, numpy no longer crashes, and all combinations with different in and out dtypes also seem to work for the standard function call (or raise the appropriate TypeError)! However, with your where parameter np.add() is now returning wrong results [Python2.7, Mac OS 10.6]:
```>>> a = np.ones((1000,1000), dtype=np.int64)

b = np.ones((1000,1000), dtype=np.int64)
c = np.zeros((1000,1000), dtype=np.float64)
d = np.add(a, b, out=c, where=m)
a.max(), b.max(), c.max(), d.max()
(1, 1, 8.0, 8.0)
c = np.zeros((1000,1000), dtype=np.float32)
d = np.add(a, b, out=c, where=m)
a.max(), b.max(), c.max(), d.max()
(1, 1, 4.6071824e+18, 4.6071824e+18)```

@mwiebe
NumPy member
mwiebe commented Jul 7, 2011

Cool, thanks for confirming all that. I'm presently extending the iterator to have a masked mode which is needed to properly fix that bug. There's a test in the suite which is marked knownfail at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.