blink1073 / oct2py

Run M Files from Python - GNU Octave to Python bridge
http://blink1073.github.io/oct2py/
MIT License
259 stars 53 forks source link

IPython notebook hangs #61

Closed dhermes closed 7 years ago

dhermes commented 9 years ago

Running the provided sample causes my entire machine (not just the example) to hang when using the subplot examples.

Machine info:


$ ipython --version
2.3.0
$ pip show oct2py

---
Name: oct2py
Version: 2.4.0
Location: /usr/local/lib/python2.7/dist-packages
Requires: 
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.1 LTS"
$ octave --version
GNU Octave, version 3.8.1
...
josephcslater commented 7 years ago

It's hard. I know. I can't even get nose tests to work on one of my packages on travis-ci. I know (believe) the package works, but I'd like to eventually be able to rely on nose tests to determine release. Programing gremlins are the worst time sinks.

blink1073 commented 7 years ago

I tracked down the issue to gnuplot creating an invalid SVG file in this case:

image

josephcslater commented 7 years ago

egad. I suppose the only solution is a bug report to gnuplot.

blink1073 commented 7 years ago

I have a work-around coming, it ends up loading as such (notice the error character in the caption):

image

blink1073 commented 7 years ago

7581f39 has the fix. The sombrero example is showing no output at all for me on OSX, I'll look at that next.

blink1073 commented 7 years ago

I released 3.6.1 that should address the problems you saw.

josephcslater commented 7 years ago

I dread saying this, but indeed that plot works, but

# Note: On Windows, this will not show the plots unless Ghostscript is installed.

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()

hangs now, along with the subsequent `%%octave -f svg cell.

blink1073 commented 7 years ago

The second cell will never execute if the first hangs. Are you able to execute both if you change the first to:

%%octave -s 600,200 -f svg
# Note: On Windows, this will not show the plots unless Ghostscript is installed.

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()
josephcslater commented 7 years ago

"The second cell will never execute if the first hangs. Are you able to execute both if you change the first to:"

Of course. I restarted the entire notebook to test the second cell, skipping the one that had hung.

Tested, and indeed, the answer is unfortunately "no."

blink1073 commented 7 years ago

Let's try and rule this out from an Octave session:

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()
print(gcf, 'test.png')
print(gcf, 'test.svg')
josephcslater commented 7 years ago

There are three ways for me to launch: from terminal, octave or octave-cli, of double clicking in the GUI.

The first two work fine as long as I'm launching from a directory I can write to. If not, it hangs. I got to that thought only after running from the GUI and realizing it defaults to /, which is non-user writable.

That seems like it. The issue might be that octave is launching with pwd set to /. The trick may very well be to set that to /tmp or pretty much anything else (if only to test). After that, of course, in the software design process you want the file saved to some appropriate place, which is likely the directory that jupyter notebook was launched from. I have no idea how easy/hard this is. It's either trivial or a pain, but that depends on how your code works (which is a bit of voodoo to me!).

blink1073 commented 7 years ago

We can change directory to your home directory at startup with this change (note it adds cd to the list of commands on that line). Does making this change allow your notebook to run?

diff --git a/oct2py/core.py b/oct2py/core.py
index e4bf3f5..3846679 100644
--- a/oct2py/core.py
+++ b/oct2py/core.py
@@ -860,7 +860,7 @@ class _Session(object):
     def _handle_first_run(self):
         here = os.path.realpath(os.path.dirname(__file__))
         here = here.replace(os.path.sep, '/')
-        self.write('disp(available_graphics_toolkits());more off;addpath(genpath("%s"));disp(char(3))\n' % here)
+        self.write('disp(available_graphics_toolkits());more off;cd;addpath(genpath("%s"));disp(char(3))\n' % here)
         resp = self.expect(chr(3))
         if not os.name == 'nt':
             try:
josephcslater commented 7 years ago

I presume there is a simple way to apply this, I'm going to manually edit the file core.py for the sake of expediency. Excuse my barbarism.

blink1073 commented 7 years ago

Hack away ;). Applying a git diff is not high on the list of intuitive tasks to do ;).

josephcslater commented 7 years ago

I've applied such before... but don't trust myself.

Nevertheless, :(. This failed. I also tried to explicitly put in a path that would be clearly writable. To my desktop, with and without training /.

josephcslater commented 7 years ago
%%octave  -f svg
# Note: On Windows, this will not show the plots unless Ghostscript is installed.

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()

works, but

%%octave -s 600,200 -f svg
# Note: On Windows, this will not show the plots unless Ghostscript is installed.

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()

fails.

Clearly the -s option is the issue.

josephcslater commented 7 years ago

%%octave -f svg -s 600,200 (swapping order of arguments) did not help.

blink1073 commented 7 years ago

That is weird, because the height and width are getting set either way even if you don't specify them.

josephcslater commented 7 years ago

The fact that what I said makes no sense did not elude me.

josephcslater commented 7 years ago

So, as a piece of information that I can't understand,

%%octave -s 500,500
# Note: On Windows, this will not show the plots unless Ghostscript is installed.

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()

doesn't work, but

%%octave -s 500,500

# butterworth filter, order 2, cutoff pi/2 radians
b = [0.292893218813452  0.585786437626905  0.292893218813452];
a = [1  0  0.171572875253810];
freqz(b, a, 32);

does.

josephcslater commented 7 years ago

Ready to flip out? I've made progress (dramatic pause).

josephcslater commented 7 years ago

The comment line:

# Note: On Windows, this will not show the plots unless Ghostscript is installed.

needed to be removed.

josephcslater commented 7 years ago

The png example is still failing... I'm working on editing the cell itself to see of the comment line is an issue.

josephcslater commented 7 years ago
%%octave -s 600,200 -f png

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()

works, but

%%octave -s 600,200 -f png

% Note: On Windows, this will not show the plots unless Ghostscript is installed.

subplot(121);
[x, y] = meshgrid(0:0.1:3);
r = sin(x - 0.5).^2 + cos(y - 0.5).^2;
surf(x, y, r);

subplot(122);
sombrero()

doesn't.

lmao.

josephcslater commented 7 years ago

So, it seems that a comment line before you get to code causes a problem, regardless of using # or %.

In the middle: unchecked. I think at the end doesn't matter (last example) because the work is already done.

josephcslater commented 7 years ago

Of course, that's apparently not always true, as the buterworth example has been working fine all along.

Removing the comment in that example does not fix the odd character issue, btw. I thought I'd try, though I didn't expect it to.

josephcslater commented 7 years ago

So...

for the butterworth example, %%octave -f svg -s 200,600

does to change the size at all.

Neither does

%%octave -s 200,600 versus %%octave -s 500,500

It seems the first line parsing has some odd issue that it's ignoring something, including getting messed up when there is a subsequent comment line.

josephcslater commented 7 years ago

Some extreme numbers in sizing show that it does something, but I think something in Jupyter is rescaling, and Octave might be doing something similar. It's hard to find a value to it's use right now watching what I'm seeing. The result is coming through clean by default.

josephcslater commented 7 years ago

(tyfys)

blink1073 commented 7 years ago

We have two problems: our ability to differentiate between a %magic and a % comment, and yes, I did notice that our ability to set the size is wonky. I am going to take a break for this for a while, at least we made some progress ;).

josephcslater commented 7 years ago

It is also # comments that have problems. Easy enough to work around (avoid) for the user, but programming may be impossible as it's possible jupyter chews up anything after a % so you are stuck with it feeding oct2py comment garbage that you can't interpret.

I'm betting your wife is giving you a hard time. I'm in work, and this is more fun that what I need to be doing. You taking a break may save my marriage.

blink1073 commented 7 years ago

Right, Octave supports either kind of comment character: https://www.gnu.org/software/octave/doc/v4.0.3/Single-Line-Comments.html

This could be related to how we're evaluating the input, I have been meaning to switch to the method used by pymatbridge. Their method of setting the image size is also better. The image size handling I can add soon, the other my family would not appreciate right now ;).

josephcslater commented 7 years ago

I might need a couch tonight the way my day is going.

josephcslater commented 7 years ago

I don't need anything quickly on this, so don't do it for me.

blink1073 commented 7 years ago

v3.6.2 should fix the size wonkiness. Thanks for all the detailed follow-ups :).

josephcslater commented 7 years ago

Everything seems to work, sizing seems better (I have't thoroughly tested), but comments still break it. (even in the 3.6.3 release).

josephcslater commented 7 years ago

FWIW: The README.rst section regarding crate.io should be removed.

.. image:: https://pypip.in/d/oct2py/badge.png
        :target: https://crate.io/packages/oct2py/

I'm not familiar with crate.io, but it seems to no longer work as a mirror for pypi.

I should probably have cloned, pull requested, etc., but for a trivial change it seems just a tad silly.

I'm likely to try to use oct2py as a template for my packages array_to_latex and vibration_toolbox, so helping out helps me as well.

Right now I feel like they are held together with duct tape. I definitely feel like a monkey banging on keyboard when working on them!

blink1073 commented 7 years ago

Thanks for the heads up, I removed the badge. Yup, writing libraries is hard. This was my first one, and I'm still learning after 5 years ;).

josephcslater commented 7 years ago

My career path has taken me far from this, but coding is my outlet and helps me feel like I'm still relevant in modern computing. Can I ask- for the life of me I can't see how the oct2py web pages end up being served on github. I didn't find the repository, I see the make files and all, but in my head I would have to build at my terminal to an html out directory that I would also have defined as a repository on github. It's exactly how I built vibrationtoolbox.github.io. I'd like to to better going forward, but boy it seems mystifying to me. Your .travis.yml file gave me some thoughts on some of my issues, though. Sorry for detouring from the thread, but I have no idea where else to ask.

blink1073 commented 7 years ago

By default, the github.io site points to the index.html in the root directory of the gh-pages branch of the repo. Recently they added the ability to point the page to other locations, in the settings for the repo.

josephcslater commented 7 years ago

My mind just got blown.

So, the pages are in the sources directory, but the make file makes the pages and puts them in a separate branch somehow? I think in this.

gh-pages:
    git checkout master
    git pull origin master
    cp oct2py/tests/*.m example
    git commit -a -m "Keep examples in sync"; true
    git push origin; true
    make docs
    ghp-import -n -p -m $(GHP_MSG) docs/_build/html

This will take a while to deconstruct.

blink1073 commented 7 years ago

The last two lines are all you should need. It builds the docs and uses the ghp-import python package to publish automagically. See the docs for the package for what the options mean.