This would probably involve an API change, but instead of importing umfpack at all we could try `import pyamg` first. If pyamg is available, we wouldn't even attempt to import umfpack, instead using `'cg_mg'` instead of `'cg'`. This sidesteps stderr issues.

The approach only works because the results are equivalent, differing only in speed/memory. I don't know why we default to the worst brute force option, either. Seems like we could default to `None` and attempt a fallback scheme of pyamg -> umfpack -> brute force in order, with a different warning structure.

On Friday, October 4, 2013 8:07:39 AM UTC-5, Juan Nunez-Iglesias wrote:
Ok so I'm having trouble actually suppressing this thing. The problem is that to detect whether umfpack is present we try to build the UmfpackContect() object:

try:
    from scipy.sparse.linalg.dsolve import umfpack
    UmfpackContext = umfpack.UmfpackContext()
except:
    UmfpackContext = None

The constructor raises an ImportError, which we duly catch (although that line should really specify the error type, but whatever). Unfortunately, the UmfpackContext class has a destructor (__del__) which then tries to delete some objects that were never created and raises an AttributeError — which, since we are already in a try: except: clause, gets ignored, hence the message to stderr.

Basically this is a bug in scipy I think?

The standard approach is to temporarily redirect stderr to /dev/null, and this works interactively:

In [1]: from scipy.sparse.linalg.dsolve import umfpack

In [2]: try:
    UC = umfpack.UmfpackContext()
except ImportError:
    print 'hello'
   ...:
hello
Exception AttributeError: "'UmfpackContext' object has no attribute '_symbolic'" in <bound method UmfpackContext.__del__ of <scipy.sparse.linalg.dsolve.umfpack.umfpack.UmfpackContext object at 0x103938250>> ignored

In [3]: import sys, os

In [4]: null = open(os.devnull, 'w')

In [5]: null.write('hello!')

In [6]: sys.stdout.write('hello!')
hello!
In [7]: sys.stderr.write('hello')
hello
In [8]: sys.stderr = null

In [9]: sys.stderr.write('hello')

In [10]: try:
    UC = umfpack.UmfpackContext()
except ImportError:
    print 'hello'
   ....:
hello

In [11]: sys.stderr = sys.__stderr__

In [12]: sys.stderr.write('hello')
hello

However, doing this in the code doesn't work, even when I try to flush the redirected stderr! (I'm not even sure that makes sense!)

sys.stderr = open(os.devnull, 'w')
try:
    from scipy.sparse.linalg.dsolve import umfpack
    UmfpackContext = umfpack.UmfpackContext()
except:
    UmfpackContext = None
finally:
    sys.stderr.flush()
    sys.stderr = sys.__stderr__

Thoughts/ideas?



On Fri, Oct 4, 2013 at 10:54 PM, Juan Nunez-Iglesias <jni....@gmail.com> wrote:
Thanks! Although in this case I was using pip install *and* it was on an EC2 micro instance so I only have 1 CPU. =)

But it is noted and very useful going forward. =)



On Fri, Oct 4, 2013 at 10:32 PM, Ralf Gommers <ralf.g...@gmail.com> wrote:



On Fri, Oct 4, 2013 at 1:33 PM, Juan Nunez-Iglesias <jni....@gmail.com> wrote:
On Fri, Oct 4, 2013 at 8:59 PM, Johannes Schönberger <js...@demuc.de> wrote:
Are you sure you have SWIG installed?

I wasn't and I didn't. =)

Bloody hell scipy takes a long time to build. =)

$ time python setup.py build_ext -i
real    12m6.843s
user    6m3.244s
sys     0m13.124s

$ time ../Bento/bentomaker build -i -j   # -j == parallel build (on 4 cores here)
real    1m46.466s
user    2m54.628s
sys     0m10.900s

Blame distutils (and start using Bento) :)

Ralf


 
Juan.

--
You received this message because you are subscribed to the Google Groups "scikit-image" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

--
You received this message because you are subscribed to the Google Groups "scikit-image" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.