Uniform GUI support across matplotlib, ets and ipython

Hi all,

As you may know, this summer we have been working on a new two
process IPython that has a beautiful Qt frontend GUI and a ZMQ based
messaging layer between that GUI and the new IPython kernel. Many
thanks to Enthought for funding this effort!

We are currently in the process of adding GUI event loop integration
to the ipython kernel so users can do interactive plotting like they
can with the regular ipython. You may also remember that last summer
we implemented a new PyOs_InputHook based GUI integration for the
regular ipython. This has not been released yet, but all of this will
be released in the upcoming 0.11 release.

I am emailing everyone because we see that there is a need for all of
us to agree on two things:

1. How to detect if a GUI application object has been created by someone else.
2. How to detect if a GUI event loop is running.

Currently there is code in both ETS and matplotlib that fails to
handle these things properly in certain cases. With IPython 0.10,
this was not a problem because we used to hijack/monkeypatch the GUI
eventloops after we started them. In 0.11, we will no longer be doing
that. To address these issues, we have created a standalone module
that implements the needed logic:

http://github.com/ipython/ipython/blob/newkernel/IPython/lib/guisupport.py

This module is heavily commented and introduces a new informal
protocol that all of use can use to detect if event loops are
running. This informal protocol is inspired by how some of this is
handled inside ETS. Our idea is that all projects will simply copy
this module into their code and ship it. It is lightweight and does
not depend on IPython or other top-level imports. As you will see, we
have implemented the logic for wx and qt4, we will need help with
other toolkits. An important point is that matplotlib and ets WILL
NOT WORK with the upcoming release of IPython unless changes are made
to their respective codebases. We consider this a draft and are more
than willing to modify the design or approach as appropriate. One
thing that we have not thought about yet is how to continue to support
0.10 within this model.

The good news amidst all of this is that the quality and stability of
the GUI support in IPython is orders of magnitude better than that in
the 0.10 series.

Cheers,

Brian

PS: If you are curious, here is a bit of background on the issues
related to the PyOS_Inputhook stuff:

http://mail.scipy.org/pipermail/ipython-dev/2010-July/006330.html

I implemented an event loop in the MacOSX backend and the PyOS_ImportHook event loop in PyGTK, so I've been interested in this topic.

If I understand guisupport.py correctly, IPython runs the backend-specific event loop. Have you considered to implement an event loop in IPython and to run that instead of a backend-specific event loop? Then you won't have to iterate the event loop, and you can run multiple GUI backends (PyGTK, PyQT, Tkinter, ...) at the same time. The latter may work with the current guisupport.py, but is fragile, because running one of the backend-specific event loops may inadvertently run code from a different backend.

--Michiel.

···

--- On Sat, 8/28/10, Brian Granger <ellisonbg@...149...> wrote:

From: Brian Granger <ellisonbg@...149...>
Subject: [matplotlib-devel] Uniform GUI support across matplotlib, ets and ipython
To: matplotlib-devel@lists.sourceforge.net, "IPython Development list" <ipython-dev@...336...>, enthought-dev@...492..., "Evan Patterson" <epatters@...492...>
Date: Saturday, August 28, 2010, 3:42 PM
Hi all,

As you may know, this summer we have been working on
a new two
process IPython that has a beautiful Qt frontend GUI and a
ZMQ based
messaging layer between that GUI and the new IPython
kernel. Many
thanks to Enthought for funding this effort!

We are currently in the process of adding GUI event loop
integration
to the ipython kernel so users can do interactive plotting
like they
can with the regular ipython. You may also remember
that last summer
we implemented a new PyOs_InputHook based GUI integration
for the
regular ipython. This has not been released yet, but
all of this will
be released in the upcoming 0.11 release.

I am emailing everyone because we see that there is a need
for all of
us to agree on two things:

1. How to detect if a GUI application object has been
created by someone else.
2. How to detect if a GUI event loop is running.

Currently there is code in both ETS and matplotlib that
fails to
handle these things properly in certain cases. With
IPython 0.10,
this was not a problem because we used to
hijack/monkeypatch the GUI
eventloops after we started them. In 0.11, we will no
longer be doing
that. To address these issues, we have created a
standalone module
that implements the needed logic:

http://github.com/ipython/ipython/blob/newkernel/IPython/lib/guisupport.py

This module is heavily commented and introduces a new
informal
protocol that all of use can use to detect if event
loops are
running. This informal protocol is inspired by how
some of this is
handled inside ETS. Our idea is that all projects
will simply copy
this module into their code and ship it. It is
lightweight and does
not depend on IPython or other top-level imports. As
you will see, we
have implemented the logic for wx and qt4, we will need
help with
other toolkits. An important point is that matplotlib
and ets WILL
NOT WORK with the upcoming release of IPython unless
changes are made
to their respective codebases. We consider this a
draft and are more
than willing to modify the design or approach as
appropriate. One
thing that we have not thought about yet is how to continue
to support
0.10 within this model.

The good news amidst all of this is that the quality and
stability of
the GUI support in IPython is orders of magnitude better
than that in
the 0.10 series.

Cheers,

Brian

PS: If you are curious, here is a bit of background
on the issues
related to the PyOS_Inputhook stuff:

http://mail.scipy.org/pipermail/ipython-dev/2010-July/006330.html

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm)
Developer Program
Be part of this innovative community and reach millions of
netbook users
worldwide. Take advantage of special opportunities to
increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

I implemented an event loop in the MacOSX backend and the PyOS_ImportHook event loop in PyGTK, so I've been interested in this topic.

Yes, and you were quite helpful last summer when i was trying to
understand the PyOS_InputHook logic. I appreciated that greatly!

If I understand guisupport.py correctly, IPython runs the backend-specific event loop. Have you considered to implement an event loop in IPython and to run that instead of a backend-specific event loop? Then you won't have to iterate the event loop, and you can run multiple GUI backends (PyGTK, PyQT, Tkinter, ...) at the same time. The latter may work with the current guisupport.py, but is fragile, because running one of the backend-specific event loops may inadvertently run code from a different backend.

Yes, we do run the native event loops of the GUI toolkit requested.
There are a few reasons we haven't gone the direction you are
mentioning (although it has crossed our minds):

1. We are not *that* passionate about GUI event loops. I would say
our philosophy with event loops is "the simplest solution possible
that is robust."
2. While it might be nice to be able to run multiple event loops, in
most cases users can survive fine without this feature. This is
especially true with more and more people migrating to Qt because of
the license change.
3. We are just barely at the point of getting the new PyOS_InputHook
and two process kernel GUI support working robustly with
matplotlib/traits/mayavi/etc. It is an 2xNxMxP testing nightmare with
2 ways IPython can run the event loop x N toolkits x M projects x P
platforms. Simply installing all possible combinations would probably
take a couple of weeks time, let alone debugging it all. I envy
matlab developers that simple have to test their plotting on a few
platforms. We will be lucky to cover matplotlib/traits/mayavi on just
qt4/wx on Mac/Linux/windows for the 0.11 release.
4. Integrating multiple event loops is either 1) super subtle and
difficult (if you actually start all the event loops involved) or 2)
tends to create solutions that busy poll or consume non-trivial CPU
power. The wx based PyOS_Inputhook and our two process GUI support
are already great examples of this. We have to work pretty hard to
create things that are responsive but that don't consume 100% of the
CPU. To reduce the CPU usage of the wx PyOS_InputHook we actually
dynamically scale back the polling time depending on how often the
user is triggering GUI events.
5. It is not just about integrating GUI event loops. We also have
multiple other event loops in our apps that handle networking.

Cheers,

Brian

···

On Sat, Aug 28, 2010 at 8:12 PM, Michiel de Hoon <mjldehoon@...42...> wrote:

--Michiel.

--- On Sat, 8/28/10, Brian Granger <ellisonbg@...149...> wrote:

From: Brian Granger <ellisonbg@...149...>
Subject: [matplotlib-devel] Uniform GUI support across matplotlib, ets and ipython
To: matplotlib-devel@lists.sourceforge.net, "IPython Development list" <ipython-dev@...336...>, enthought-dev@...492..., "Evan Patterson" <epatters@...492...>
Date: Saturday, August 28, 2010, 3:42 PM
Hi all,

As you may know, this summer we have been working on
a new two
process IPython that has a beautiful Qt frontend GUI and a
ZMQ based
messaging layer between that GUI and the new IPython
kernel. Many
thanks to Enthought for funding this effort!

We are currently in the process of adding GUI event loop
integration
to the ipython kernel so users can do interactive plotting
like they
can with the regular ipython. You may also remember
that last summer
we implemented a new PyOs_InputHook based GUI integration
for the
regular ipython. This has not been released yet, but
all of this will
be released in the upcoming 0.11 release.

I am emailing everyone because we see that there is a need
for all of
us to agree on two things:

1. How to detect if a GUI application object has been
created by someone else.
2. How to detect if a GUI event loop is running.

Currently there is code in both ETS and matplotlib that
fails to
handle these things properly in certain cases. With
IPython 0.10,
this was not a problem because we used to
hijack/monkeypatch the GUI
eventloops after we started them. In 0.11, we will no
longer be doing
that. To address these issues, we have created a
standalone module
that implements the needed logic:

http://github.com/ipython/ipython/blob/newkernel/IPython/lib/guisupport.py

This module is heavily commented and introduces a new
informal
protocol that all of use can use to detect if event
loops are
running. This informal protocol is inspired by how
some of this is
handled inside ETS. Our idea is that all projects
will simply copy
this module into their code and ship it. It is
lightweight and does
not depend on IPython or other top-level imports. As
you will see, we
have implemented the logic for wx and qt4, we will need
help with
other toolkits. An important point is that matplotlib
and ets WILL
NOT WORK with the upcoming release of IPython unless
changes are made
to their respective codebases. We consider this a
draft and are more
than willing to modify the design or approach as
appropriate. One
thing that we have not thought about yet is how to continue
to support
0.10 within this model.

The good news amidst all of this is that the quality and
stability of
the GUI support in IPython is orders of magnitude better
than that in
the 0.10 series.

Cheers,

Brian

PS: If you are curious, here is a bit of background
on the issues
related to the PyOS_Inputhook stuff:

http://mail.scipy.org/pipermail/ipython-dev/2010-July/006330.html

------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm)
Developer Program
Be part of this innovative community and reach millions of
netbook users
worldwide. Take advantage of special opportunities to
increase revenue and
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options

--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
bgranger@...882...
ellisonbg@...149...

Hi Brian,
Thanks for your reply. I agree that integrating multiple event loops is not essential for most users. But if you are not integrating multiple event loops, then why do you need poll?

Best,
--Michiel.

···

--- On Sun, 8/29/10, Brian Granger <ellisonbg@...149...> wrote:

From: Brian Granger <ellisonbg@...149...>
Subject: Re: [matplotlib-devel] Uniform GUI support across matplotlib, ets and ipython
To: "Michiel de Hoon" <mjldehoon@...42...>
Cc: matplotlib-devel@lists.sourceforge.net, "IPython Development list" <ipython-dev@...336...>, enthought-dev@...492..., "Evan Patterson" <epatters@...492...>
Date: Sunday, August 29, 2010, 3:24 PM
On Sat, Aug 28, 2010 at 8:12 PM, > Michiel de Hoon <mjldehoon@...42...> > wrote:
> I implemented an event loop in the MacOSX backend and
the PyOS_ImportHook event loop in PyGTK, so I've been
interested in this topic.

Yes, and you were quite helpful last summer when i was
trying to
understand the PyOS_InputHook logic. I appreciated that
greatly!

> If I understand guisupport.py correctly, IPython runs
the backend-specific event loop. Have you considered to
implement an event loop in IPython and to run that instead
of a backend-specific event loop? Then you won't have to
iterate the event loop, and you can run multiple GUI
backends (PyGTK, PyQT, Tkinter, ...) at the same time. The
latter may work with the current guisupport.py, but is
fragile, because running one of the backend-specific event
loops may inadvertently run code from a different backend.

Yes, we do run the native event loops of the GUI toolkit
requested.
There are a few reasons we haven't gone the direction you
are
mentioning (although it has crossed our minds):

1. We are not *that* passionate about GUI event
loops. I would say
our philosophy with event loops is "the simplest solution
possible
that is robust."
2. While it might be nice to be able to run multiple
event loops, in
most cases users can survive fine without this
feature. This is
especially true with more and more people migrating to Qt
because of
the license change.
3. We are just barely at the point of getting the new
PyOS_InputHook
and two process kernel GUI support working robustly with
matplotlib/traits/mayavi/etc. It is an 2xNxMxP
testing nightmare with
2 ways IPython can run the event loop x N toolkits x M
projects x P
platforms. Simply installing all possible
combinations would probably
take a couple of weeks time, let alone debugging it
all. I envy
matlab developers that simple have to test their plotting
on a few
platforms. We will be lucky to cover
matplotlib/traits/mayavi on just
qt4/wx on Mac/Linux/windows for the 0.11 release.
4. Integrating multiple event loops is either 1)
super subtle and
difficult (if you actually start all the event loops
involved) or 2)
tends to create solutions that busy poll or consume
non-trivial CPU
power. The wx based PyOS_Inputhook and our two
process GUI support
are already great examples of this. We have to work
pretty hard to
create things that are responsive but that don't consume
100% of the
CPU. To reduce the CPU usage of the wx PyOS_InputHook
we actually
dynamically scale back the polling time depending on how
often the
user is triggering GUI events.
5. It is not just about integrating GUI event
loops. We also have
multiple other event loops in our apps that handle
networking.

Cheers,

Brian

> --Michiel.
>
> --- On Sat, 8/28/10, Brian Granger <ellisonbg@...149...> > wrote:
>
>> From: Brian Granger <ellisonbg@...149...>
>> Subject: [matplotlib-devel] Uniform GUI support
across matplotlib, ets and ipython
>> To: matplotlib-devel@lists.sourceforge.net,
"IPython Development list" <ipython-dev@...336...>,
enthought-dev@...492...,
"Evan Patterson" <epatters@...492...>
>> Date: Saturday, August 28, 2010, 3:42 PM
>> Hi all,
>>
>> As you may know, this summer we have been
working on
>> a new two
>> process IPython that has a beautiful Qt frontend
GUI and a
>> ZMQ based
>> messaging layer between that GUI and the new
IPython
>> kernel. Many
>> thanks to Enthought for funding this effort!
>>
>> We are currently in the process of adding GUI
event loop
>> integration
>> to the ipython kernel so users can do interactive
plotting
>> like they
>> can with the regular ipython. You may also
remember
>> that last summer
>> we implemented a new PyOs_InputHook based GUI
integration
>> for the
>> regular ipython. This has not been released yet,
but
>> all of this will
>> be released in the upcoming 0.11 release.
>>
>> I am emailing everyone because we see that there
is a need
>> for all of
>> us to agree on two things:
>>
>> 1. How to detect if a GUI application object has
been
>> created by someone else.
>> 2. How to detect if a GUI event loop is
running.
>>
>> Currently there is code in both ETS and matplotlib
that
>> fails to
>> handle these things properly in certain cases.
With
>> IPython 0.10,
>> this was not a problem because we used to
>> hijack/monkeypatch the GUI
>> eventloops after we started them. In 0.11, we
will no
>> longer be doing
>> that. To address these issues, we have created
a
>> standalone module
>> that implements the needed logic:
>>
>> http://github.com/ipython/ipython/blob/newkernel/IPython/lib/guisupport.py
>>
>> This module is heavily commented and introduces a
new
>> informal
>> protocol that all of use can use to detect if
event
>> loops are
>> running. This informal protocol is inspired by
how
>> some of this is
>> handled inside ETS. Our idea is that all
projects
>> will simply copy
>> this module into their code and ship it. It is
>> lightweight and does
>> not depend on IPython or other top-level
imports. As
>> you will see, we
>> have implemented the logic for wx and qt4, we will
need
>> help with
>> other toolkits. An important point is that
matplotlib
>> and ets WILL
>> NOT WORK with the upcoming release of IPython
unless
>> changes are made
>> to their respective codebases. We consider this
a
>> draft and are more
>> than willing to modify the design or approach as
>> appropriate. One
>> thing that we have not thought about yet is how to
continue
>> to support
>> 0.10 within this model.
>>
>> The good news amidst all of this is that the
quality and
>> stability of
>> the GUI support in IPython is orders of magnitude
better
>> than that in
>> the 0.10 series.
>>
>> Cheers,
>>
>> Brian
>>
>> PS: If you are curious, here is a bit of
background
>> on the issues
>> related to the PyOS_Inputhook stuff:
>>
>> http://mail.scipy.org/pipermail/ipython-dev/2010-July/006330.html
>>
>>
------------------------------------------------------------------------------
>> Sell apps to millions through the Intel(R)
Atom(Tm)
>> Developer Program
>> Be part of this innovative community and reach
millions of
>> netbook users
>> worldwide. Take advantage of special opportunities
to
>> increase revenue and
>> speed time-to-market. Join now, and jumpstart your
future.
>> http://p.sf.net/sfu/intel-atom-d2d
>> _______________________________________________
>> Matplotlib-devel mailing list
>> Matplotlib-devel@lists.sourceforge.net
>> matplotlib-devel List Signup and Options
>>
>
>
>
>

--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
bgranger@...882...
ellisonbg@...149...

Hi Brian,
Thanks for your reply. I agree that integrating multiple event loops is not essential for most users. But if you are not integrating multiple event loops, then why do you need poll?

In the two process kernel we do currently integrate two event loops:

1. Our networking event loop that is based on zeromq/pyzmq
2. A single GUI event loop from wx, qt4, etc.

We do this by triggering an iteration of our networking event loop on
a periodic GUI timer. So we definitely have to face multiple event
loop integration, but it is much simpler when you only have 1 GUi
event loop involved.

Cheers,

Brian

···

On Mon, Aug 30, 2010 at 7:10 AM, Michiel de Hoon <mjldehoon@...42...> wrote:

Best,
--Michiel.

--- On Sun, 8/29/10, Brian Granger <ellisonbg@...149...> wrote:

From: Brian Granger <ellisonbg@...149...>
Subject: Re: [matplotlib-devel] Uniform GUI support across matplotlib, ets and ipython
To: "Michiel de Hoon" <mjldehoon@...42...>
Cc: matplotlib-devel@lists.sourceforge.net, "IPython Development list" <ipython-dev@...336...>, enthought-dev@...492..., "Evan Patterson" <epatters@...492...>
Date: Sunday, August 29, 2010, 3:24 PM
On Sat, Aug 28, 2010 at 8:12 PM, >> Michiel de Hoon <mjldehoon@...42...> >> wrote:
> I implemented an event loop in the MacOSX backend and
the PyOS_ImportHook event loop in PyGTK, so I've been
interested in this topic.

Yes, and you were quite helpful last summer when i was
trying to
understand the PyOS_InputHook logic. I appreciated that
greatly!

> If I understand guisupport.py correctly, IPython runs
the backend-specific event loop. Have you considered to
implement an event loop in IPython and to run that instead
of a backend-specific event loop? Then you won't have to
iterate the event loop, and you can run multiple GUI
backends (PyGTK, PyQT, Tkinter, ...) at the same time. The
latter may work with the current guisupport.py, but is
fragile, because running one of the backend-specific event
loops may inadvertently run code from a different backend.

Yes, we do run the native event loops of the GUI toolkit
requested.
There are a few reasons we haven't gone the direction you
are
mentioning (although it has crossed our minds):

1. We are not *that* passionate about GUI event
loops. I would say
our philosophy with event loops is "the simplest solution
possible
that is robust."
2. While it might be nice to be able to run multiple
event loops, in
most cases users can survive fine without this
feature. This is
especially true with more and more people migrating to Qt
because of
the license change.
3. We are just barely at the point of getting the new
PyOS_InputHook
and two process kernel GUI support working robustly with
matplotlib/traits/mayavi/etc. It is an 2xNxMxP
testing nightmare with
2 ways IPython can run the event loop x N toolkits x M
projects x P
platforms. Simply installing all possible
combinations would probably
take a couple of weeks time, let alone debugging it
all. I envy
matlab developers that simple have to test their plotting
on a few
platforms. We will be lucky to cover
matplotlib/traits/mayavi on just
qt4/wx on Mac/Linux/windows for the 0.11 release.
4. Integrating multiple event loops is either 1)
super subtle and
difficult (if you actually start all the event loops
involved) or 2)
tends to create solutions that busy poll or consume
non-trivial CPU
power. The wx based PyOS_Inputhook and our two
process GUI support
are already great examples of this. We have to work
pretty hard to
create things that are responsive but that don't consume
100% of the
CPU. To reduce the CPU usage of the wx PyOS_InputHook
we actually
dynamically scale back the polling time depending on how
often the
user is triggering GUI events.
5. It is not just about integrating GUI event
loops. We also have
multiple other event loops in our apps that handle
networking.

Cheers,

Brian

> --Michiel.
>
> --- On Sat, 8/28/10, Brian Granger <ellisonbg@...149...> >> wrote:
>
>> From: Brian Granger <ellisonbg@...149...>
>> Subject: [matplotlib-devel] Uniform GUI support
across matplotlib, ets and ipython
>> To: matplotlib-devel@lists.sourceforge.net,
"IPython Development list" <ipython-dev@...336...>,
enthought-dev@...492...,
"Evan Patterson" <epatters@...492...>
>> Date: Saturday, August 28, 2010, 3:42 PM
>> Hi all,
>>
>> As you may know, this summer we have been
working on
>> a new two
>> process IPython that has a beautiful Qt frontend
GUI and a
>> ZMQ based
>> messaging layer between that GUI and the new
IPython
>> kernel. Many
>> thanks to Enthought for funding this effort!
>>
>> We are currently in the process of adding GUI
event loop
>> integration
>> to the ipython kernel so users can do interactive
plotting
>> like they
>> can with the regular ipython. You may also
remember
>> that last summer
>> we implemented a new PyOs_InputHook based GUI
integration
>> for the
>> regular ipython. This has not been released yet,
but
>> all of this will
>> be released in the upcoming 0.11 release.
>>
>> I am emailing everyone because we see that there
is a need
>> for all of
>> us to agree on two things:
>>
>> 1. How to detect if a GUI application object has
been
>> created by someone else.
>> 2. How to detect if a GUI event loop is
running.
>>
>> Currently there is code in both ETS and matplotlib
that
>> fails to
>> handle these things properly in certain cases.
With
>> IPython 0.10,
>> this was not a problem because we used to
>> hijack/monkeypatch the GUI
>> eventloops after we started them. In 0.11, we
will no
>> longer be doing
>> that. To address these issues, we have created
a
>> standalone module
>> that implements the needed logic:
>>
>> http://github.com/ipython/ipython/blob/newkernel/IPython/lib/guisupport.py
>>
>> This module is heavily commented and introduces a
new
>> informal
>> protocol that all of use can use to detect if
event
>> loops are
>> running. This informal protocol is inspired by
how
>> some of this is
>> handled inside ETS. Our idea is that all
projects
>> will simply copy
>> this module into their code and ship it. It is
>> lightweight and does
>> not depend on IPython or other top-level
imports. As
>> you will see, we
>> have implemented the logic for wx and qt4, we will
need
>> help with
>> other toolkits. An important point is that
matplotlib
>> and ets WILL
>> NOT WORK with the upcoming release of IPython
unless
>> changes are made
>> to their respective codebases. We consider this
a
>> draft and are more
>> than willing to modify the design or approach as
>> appropriate. One
>> thing that we have not thought about yet is how to
continue
>> to support
>> 0.10 within this model.
>>
>> The good news amidst all of this is that the
quality and
>> stability of
>> the GUI support in IPython is orders of magnitude
better
>> than that in
>> the 0.10 series.
>>
>> Cheers,
>>
>> Brian
>>
>> PS: If you are curious, here is a bit of
background
>> on the issues
>> related to the PyOS_Inputhook stuff:
>>
>> http://mail.scipy.org/pipermail/ipython-dev/2010-July/006330.html
>>
>>
------------------------------------------------------------------------------
>> Sell apps to millions through the Intel(R)
Atom(Tm)
>> Developer Program
>> Be part of this innovative community and reach
millions of
>> netbook users
>> worldwide. Take advantage of special opportunities
to
>> increase revenue and
>> speed time-to-market. Join now, and jumpstart your
future.
>> http://p.sf.net/sfu/intel-atom-d2d
>> _______________________________________________
>> Matplotlib-devel mailing list
>> Matplotlib-devel@lists.sourceforge.net
>> matplotlib-devel List Signup and Options
>>
>
>
>
>

--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
bgranger@...882...
ellisonbg@...149...

--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
bgranger@...882...
ellisonbg@...149...

1. Our networking event loop that is based on zeromq/pyzmq
2. A single GUI event loop from wx, qt4, etc.

We do this by triggering an iteration of our networking
event loop on a periodic GUI timer.

So right now you're in a loop in which you let qt4 (or wx) watch the file descriptors qt4 needs, then zeromq the file descriptors that zeromq needs, and so on?

Just use the qt4 event loop to watch both the file descriptors zeromq wants to watch, in addition to whatever events qt4 needs. Qt4 already has the API that allows you to do this (QSocketNotifier et al.). I am not familiar with zeromq, but if there is a way to determine which file descriptors it wants to watch then you're almost done. If not, you could discuss this with the zeromq developers. Then you won't need to poll, you'll get better response times, and the code will be scalable too.

Best,
--Michiel.

1. Our networking event loop that is based on zeromq/pyzmq
2. A single GUI event loop from wx, qt4, etc.

We do this by triggering an iteration of our networking
event loop on a periodic GUI timer.

So right now you're in a loop in which you let qt4 (or wx) watch the file descriptors qt4 needs, then zeromq the file descriptors that zeromq needs, and so on?

ZMQ sockets are not really sockets in that they do not have a file
descriptor interface. That is something that is being worked on in
the zeromq development, but it is not there yet. Also, I don't think
the API will be fully compatible, so I am not sure how it will play
with what Qt is expecting.

···

On Tue, Aug 31, 2010 at 7:02 AM, Michiel de Hoon <mjldehoon@...42...> wrote:

Just use the qt4 event loop to watch both the file descriptors zeromq wants to watch, in addition to whatever events qt4 needs. Qt4 already has the API that allows you to do this (QSocketNotifier et al.). I am not familiar with zeromq, but if there is a way to determine which file descriptors it wants to watch then you're almost done. If not, you could discuss this with the zeromq developers. Then you won't need to poll, you'll get better response times, and the code will be scalable too.

Best,
--Michiel.

--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
bgranger@...882...
ellisonbg@...149...

Hi folks,

Hi all,

As you may know, this summer we have been working on a new two
process IPython that has a beautiful Qt frontend GUI and a ZMQ based
messaging layer between that GUI and the new IPython kernel. Many
thanks to Enthought for funding this effort!

We are currently in the process of adding GUI event loop integration
to the ipython kernel so users can do interactive plotting like they
can with the regular ipython. You may also remember that last summer
we implemented a new PyOs_InputHook based GUI integration for the
regular ipython. This has not been released yet, but all of this will
be released in the upcoming 0.11 release.

I am emailing everyone because we see that there is a need for all of
us to agree on two things:

1. How to detect if a GUI application object has been created by someone else.
2. How to detect if a GUI event loop is running.

Currently there is code in both ETS and matplotlib that fails to
handle these things properly in certain cases. With IPython 0.10,
this was not a problem because we used to hijack/monkeypatch the GUI
eventloops after we started them. In 0.11, we will no longer be doing
that. To address these issues, we have created a standalone module
that implements the needed logic:

http://github.com/ipython/ipython/blob/newkernel/IPython/lib/guisupport.py

This module is heavily commented and introduces a new informal
protocol that all of use can use to detect if event loops are
running. This informal protocol is inspired by how some of this is
handled inside ETS. Our idea is that all projects will simply copy
this module into their code and ship it. It is lightweight and does
not depend on IPython or other top-level imports. As you will see, we
have implemented the logic for wx and qt4, we will need help with
other toolkits. An important point is that matplotlib and ets WILL
NOT WORK with the upcoming release of IPython unless changes are made
to their respective codebases. We consider this a draft and are more
than willing to modify the design or approach as appropriate. One
thing that we have not thought about yet is how to continue to support
0.10 within this model.

The good news amidst all of this is that the quality and stability of
the GUI support in IPython is orders of magnitude better than that in
the 0.10 series.

I just wanted to ping back with this topic, both to update you a
little and to ask for help...

Brian is now using Andrew's git repo and made an mpl branch for
experimenting with the guisupport work:

http://github.com/ellisonbg/matplotlib/tree/guisupport

For now there's just one commit, but at any point in time, this URL
will easily let you compare what's new vs Andrew's trunk (which I'm
considering the canonical reference on github):

http://github.com/ellisonbg/matplotlib/compare/astraw:trunk...guisupport

Basically we're a bit stumped with GTK, and also partly with Tk. With
Tk things *seem* to work ok in light testing, but it's possible that
problems lurk. It's just that we do get something 'for free' because
python itself manages the Tk event loop.

But for GTK, no clue...

This type of code will be needed to support the multiprocess
capabilities we're developing with ipython, and for qt, wx and
(apparently, but only by chance) tk, matplotlib with the guisupport
added, works right now on IPython:

- 0.10.1 with the old -Xthread flags (just like always, rather fragile
and brittle but useful for a lot of things).

- trunk at the command-line, using --pylab {qt, wx, tk}: this uses
PyOSInputHook, which is more reliable than the --Xthread flags.

- our 'newkernel' branch with the fancy Qt widget and two process control.

So we're doing pretty good: Qt and Wx seem solid, Tk so far is cutting
us slack. But GTK is simply hosed. Brian tried and got lost, and I
don't have the foggiest clue.

So if anyone here can help us out solidify the GTK solution, as well
as point out anything that might be needed for Tk and any possible
flaws in the code for Wx/Qt, we'd be immensely grateful.

We're very, very excited about the possibilities the code we're
building in ipython opens up. But we don't want to have the massive
regression of breaking GTK support for matplotlib, and we're a bit
stuck.

Once the code in Brian's branch is tested/fixed/approved by you guys,
we'd like to propose it for merging into matplotlib. The idea is that
MPL would carry its own copy of this guisupport file, enabling it to
cooperate well with IPython or anyone else who supports this approach
(and we've talked with the IEP author --Google Code Archive - Long-term storage for Google Code Project Hosting.,
enthought for the Traits machinery, etc). But it would NOT create an
ipython dependency on matplotlib, nor should it break any embedded
uses in a GUI application, etc.

This stuff is hard, and Brian and I are both pretty ignorant when it
comes to GUIs, so any help we can get will be really appreciated.

If you want to comment inline or on the whole commit for the purposes
of review, the commit URL at github always allows that:

http://github.com/ellisonbg/matplotlib/commit/d4dcce8635bfe4a82f5e6eef89aa5daf025f1a20

The little + signs on the left of each line are for inline comments,
and the box at the bottom for whole-commit commenting.

Thanks!

f

···

On Sat, Aug 28, 2010 at 12:42 PM, Brian Granger <ellisonbg@...149...> wrote:

That may be, but at the bottom of the ZMQ event loop is a call to select(), which expects a pair of ordinary file descriptors. At the same time, at the bottom of the qt4 event loop is also a call to select(), also using a set of file descriptors.

Currently your event loop works approximately as follows:

1) Run the qt4 event loop, which calls select() inside qt4, watching the file descriptors that qt4 knows about.
2) Interrupt the qt4 event loop, and enter the ZMQ event loop, which calls select() inside ZMQ to watch the file descriptors ZMQ knows about.
3) If none if the ZMQ file descriptors have been signaled, go to 1).

Ideally, you would want to call select() only once, and have it watch both the file descriptors qt4 knows about, as well as the file descriptors ZMQ knows about.

So how to implement this?

Think about just the ZMQ event loop for now. Just before entering the ZMQ event loop, ZMQ knows which file descriptors it should watch when it calls select(). Which means that ZMQ maintains in some form or another a list of file descriptors to watch. Now I don't know the details of ZMQ, but I suppose there is some function inside ZMQ that effectively adds one file descriptor to the ZMQ list of file descriptors to watch. Now, instead of this function, call an ipython-specific function that effectively adds this file descriptor to the list of file descriptors that qt should watch for (probably using QSocketNotifier). Now you don't need to enter the ZMQ event loop at all: When you enter the qt event loop, and there is any activity on one of the ZMQ file descriptors, the qt event loop will notice and take the appropriate action.

Does this make sense?

--Michiel.

···

--- On Wed, 9/1/10, Brian Granger <ellisonbg@...149...> wrote:

> So right now you're in a loop in which you let qt4 (or
wx) watch the file descriptors qt4 needs, then zeromq the
file descriptors that zeromq needs, and so on?

ZMQ sockets are not really sockets in that they do not have
a file descriptor interface.

Michiel,

> So right now you're in a loop in which you let qt4 (or
wx) watch the file descriptors qt4 needs, then zeromq the
file descriptors that zeromq needs, and so on?

ZMQ sockets are not really sockets in that they do not have
a file descriptor interface.

That may be, but at the bottom of the ZMQ event loop is a call to select(), which expects a pair of ordinary file descriptors. At the same time, at the bottom of the qt4 event loop is also a call to select(), also using a set of file descriptors.

What you are saying is mostly right. ZMQ uses the best polling
mechanism for the platform (select/poll/epoll/kqueue/etc). In some
cases, there are actual file descriptors in the internals of zeromq.
As I understand it:

* Zeromq runs on other transports other than TCP and not all of those
transports have file descriptors.
* Even if zeromq is using TCP for transport, a single zeromq socket
may be implemented with many low level sockets during its lifetime.
These sockets are not in any way exposed in the public zeromq API.
* zeromq sockets are connectionless. If you were able to get those
low level file descriptors, the model would become leaky because you
would need to start handling the connection related events.

Thus, it is currently not an option to get those low level file
descriptors and do what you are proposing.

Currently your event loop works approximately as follows:

1) Run the qt4 event loop, which calls select() inside qt4, watching the file descriptors that qt4 knows about.
2) Interrupt the qt4 event loop, and enter the ZMQ event loop, which calls select() inside ZMQ to watch the file descriptors ZMQ knows about.
3) If none if the ZMQ file descriptors have been signaled, go to 1).

Ideally, you would want to call select() only once, and have it watch both the file descriptors qt4 knows about, as well as the file descriptors ZMQ knows about.

So how to implement this?

Think about just the ZMQ event loop for now. Just before entering the ZMQ event loop, ZMQ knows which file descriptors it should watch when it calls select(). Which means that ZMQ maintains in some form or another a list of file descriptors to watch. Now I don't know the details of ZMQ, but I suppose there is some function inside ZMQ that effectively adds one file descriptor to the ZMQ list of file descriptors to watch. Now, instead of this function, call an ipython-specific function that effectively adds this file descriptor to the list of file descriptors that qt should watch for (probably using QSocketNotifier). Now you don't need to enter the ZMQ event loop at all: When you enter the qt event loop, and there is any activity on one of the ZMQ file descriptors, the qt event loop will notice and take the appropriate action.

Does this make sense?

Definitely, it makes total sense, it is just not possible today with
how zeromq is implemented. The zeromq devs are working on a file
descriptor interface, but it will not be fully compatible with the
usual one in that you won't be able to distinguish between read, write
and error events with only the file descriptor. I am not sure the
file descriptor interface that zeromq will eventually have will
actually work with what qt is expecting.

The other issue is one of maintainability. Currently the GUI code and
zeromq event loop code is completely separate and orthogonal. We can
easily change one without affecting the other. If we were to combine
the event loops, we would loose that nice separation that makes our
code more robust, stable and maintainable. Also, I should mention
that the current approach functions perfectly well. Both the GUI and
IPython remain extremely responsive at all times.

I should also mention that the help we need with matplotlib right now
is *completely* independent of these issues of how we integrate the
two event loops.

Thanks for the ideas though.

Cheers,

Brian

···

On Fri, Sep 3, 2010 at 9:22 AM, Michiel de Hoon <mjldehoon@...42...> wrote:

--- On Wed, 9/1/10, Brian Granger <ellisonbg@...149...> wrote:

--Michiel.

--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
bgranger@...882...
ellisonbg@...149...