list_timings() cannot be redirected to a file or a variable in python

Bug #1072694 reported by corrado maurini
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
DOLFIN
Fix Released
Undecided
Johan Hake

Bug Description

In python it is not possible to redirect the output of list_timings() to a file.

set_output_stream(std::ostream& out) in log.ccp is not working in python because of problems in wrapping cpp ostream

see also https://answers.launchpad.net/dolfin/+question/211271

Revision history for this message
Marco Morandini (morandini) wrote :

Using boost::python I ended up with something like the attached file; don't know if it is possible to do something similar using swig. Apologizes if this is only noise.

Revision history for this message
Johan Hake (johan-hake) wrote :

Thanks Marco!

I will look into your code and see if we could use it, hopefully without the boost::python dependency.

Changed in dolfin:
assignee: nobody → Johan Hake (johan-hake)
status: New → Confirmed
milestone: none → 1.1.0
Revision history for this message
Johan Hake (johan-hake) wrote :

Marco, what would the syntax be for adding a file as the log output. Is it possible to add an already existing file pointer or just the file name as a string? This would be the ultimate solution as we then can merge the two log streams from dolfin and logging dependent python modules such as UFL.

My boost python skills are really limited so following the inner workings of this small file is hard for me...

Revision history for this message
Marco Morandini (morandini) wrote : Re: [Bug 1072694] Re: list_timings() cannot be redirected to a file or a variable in python

On 10/30/2012 08:00 AM, Johan Hake wrote:
> Marco, what would the syntax be for adding a file as the log output. Is
> it possible to add an already existing file pointer or just the file
> name as a string? This would be the ultimate solution as we then can
> merge the two log streams from dolfin and logging dependent python
> modules such as UFL.
>
> My boost python skills are really limited so following the inner
> workings of this small file is hard for me...
>

In my old code (where everything is wrapped with boost)

after

fileout = ostream(cout_buf())

fileout will point to std::cout,

and after

fileout = ostream('new_file_name.txt')

fileout will point to a newly opened ofstream.

Then, fileout can be passed to any wrapped c++ function that
has an std::ostream & argument.

I.e., if I have this c++ function

void DxOutput(std::ostream & out, const MyFloat t);

and I wrap it as

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ofstream_open_overloads,
std::ofstream::open, 1, 2);
BOOST_PYTHON_MODULE_INIT(_python_util)
{
 ....

 the wrapping code I've attached

 ....

 python::def("DxOutput", DxOutput);
}

in python I can do

t=0.01
fileout = ostream('new_file_name.txt')
DxOutput(fileout, t)

if I want to write with DxOutput into new_file_name.txt,

or

fileout = ostream(cout_buf())
DxOutput(fileout, t)

If I want DxOuptut's output on the screen.

Note however that I can't write directly from python into fileout
(and I fear that this is what you are looking for :( .
At least, I've not even tried to do it (perhaps one should start
extractig the file descriptor, as explained here:

http://www.ginac.de/~kreckel/fileno/

)

Or
http://stackoverflow.com/questions/2378005/c-iostreams-and-python

Hope this helps.

Revision history for this message
corrado maurini (corrado-maurini) wrote : Re: [Bug 1072694] list_timings() cannot be redirected to a file or a variable in python

Johan,

Thanks a lot for taking care of this.

If redirecting ostream through python is too difficult, for the specific case a possible alternative can be to have a function similar to list_timings(), but giving a dolfin Table as output.

Then the Table is a python object and one can use the associated methods to access data or print it out (event in latex format!).

I have not done this directly because I do not if this may conflict with your general design principles for the logger.

Corrado

Le 30 oct. 2012 à 11:02, Marco Morandini a écrit :

> On 10/30/2012 08:00 AM, Johan Hake wrote:
>> Marco, what would the syntax be for adding a file as the log output. Is
>> it possible to add an already existing file pointer or just the file
>> name as a string? This would be the ultimate solution as we then can
>> merge the two log streams from dolfin and logging dependent python
>> modules such as UFL.
>>
>> My boost python skills are really limited so following the inner
>> workings of this small file is hard for me...
>>
>
> In my old code (where everything is wrapped with boost)
>
> after
>
> fileout = ostream(cout_buf())
>
> fileout will point to std::cout,
>
> and after
>
> fileout = ostream('new_file_name.txt')
>
> fileout will point to a newly opened ofstream.
>
> Then, fileout can be passed to any wrapped c++ function that
> has an std::ostream & argument.
>
> I.e., if I have this c++ function
>
> void DxOutput(std::ostream & out, const MyFloat t);
>
> and I wrap it as
>
> BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ofstream_open_overloads,
> std::ofstream::open, 1, 2);
> BOOST_PYTHON_MODULE_INIT(_python_util)
> {
> ....
>
> the wrapping code I've attached
>
> ....
>
> python::def("DxOutput", DxOutput);
> }
>
> in python I can do
>
> t=0.01
> fileout = ostream('new_file_name.txt')
> DxOutput(fileout, t)
>
> if I want to write with DxOutput into new_file_name.txt,
>
> or
>
> fileout = ostream(cout_buf())
> DxOutput(fileout, t)
>
> If I want DxOuptut's output on the screen.
>
> Note however that I can't write directly from python into fileout
> (and I fear that this is what you are looking for :( .
> At least, I've not even tried to do it (perhaps one should start
> extractig the file descriptor, as explained here:
>
> http://www.ginac.de/~kreckel/fileno/
>
> )
>
> Or
> http://stackoverflow.com/questions/2378005/c-iostreams-and-python
>
>
> Hope this helps.
>
> --
> You received this bug notification because you are a member of DOLFIN
> Team, which is subscribed to DOLFIN.
> https://bugs.launchpad.net/bugs/1072694
>
> Title:
> list_timings() cannot be redirected to a file or a variable in python
>
> Status in DOLFIN:
> Confirmed
>
> Bug description:
> In python it is not possible to redirect the output of list_timings()
> to a file.
>
> set_output_stream(std::ostream& out) in log.ccp is not working in
> python because of problems in wrapping cpp ostream
>
> see also https://answers.launchpad.net/dolfin/+question/211271
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/dolfin/+bug/1072694/+subscriptions

Revision history for this message
Johan Hake (johan-hake) wrote :
Download full text (3.6 KiB)

On 10/30/2012 11:53 AM, corrado maurini wrote:
> Johan,
>
> Thanks a lot for taking care of this.

Well, we see how far it goes :)

> If redirecting ostream through python is too difficult, for the specific
> case a possible alternative can be to have a function similar to
> list_timings(), but giving a dolfin Table as output.

Sure that would be pretty trivial to implement, and we have them same
analogy for list_linear_algebra_backends and linear_algebra_backends,
where the later return a list of strings instead of printing them to the
screen.

So adding a free function called timings would fit fine here.

> Then the Table is a python object and one can use the associated methods
> to access data or print it out (event in latex format!).

Good point!

> I have not done this directly because I do not if this may conflict with
> your general design principles for the logger.

Should work just fine.

Johan

> Corrado
>
> Le 30 oct. 2012 à 11:02, Marco Morandini a écrit :
>
>> On 10/30/2012 08:00 AM, Johan Hake wrote:
>>> Marco, what would the syntax be for adding a file as the log output. Is
>>> it possible to add an already existing file pointer or just the file
>>> name as a string? This would be the ultimate solution as we then can
>>> merge the two log streams from dolfin and logging dependent python
>>> modules such as UFL.
>>>
>>> My boost python skills are really limited so following the inner
>>> workings of this small file is hard for me...
>>>
>>
>> In my old code (where everything is wrapped with boost)
>>
>> after
>>
>> fileout = ostream(cout_buf())
>>
>> fileout will point to std::cout,
>>
>> and after
>>
>> fileout = ostream('new_file_name.txt')
>>
>> fileout will point to a newly opened ofstream.
>>
>> Then, fileout can be passed to any wrapped c++ function that
>> has an std::ostream & argument.
>>
>> I.e., if I have this c++ function
>>
>> void DxOutput(std::ostream & out, const MyFloat t);
>>
>> and I wrap it as
>>
>> BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(ofstream_open_overloads,
>> std::ofstream::open, 1, 2);
>> BOOST_PYTHON_MODULE_INIT(_python_util)
>> {
>> ....
>>
>> the wrapping code I've attached
>>
>> ....
>>
>> python::def("DxOutput", DxOutput);
>> }
>>
>> in python I can do
>>
>> t=0.01
>> fileout = ostream('new_file_name.txt')
>> DxOutput(fileout, t)
>>
>> if I want to write with DxOutput into new_file_name.txt,
>>
>> or
>>
>> fileout = ostream(cout_buf())
>> DxOutput(fileout, t)
>>
>> If I want DxOuptut's output on the screen.
>>
>> Note however that I can't write directly from python into fileout
>> (and I fear that this is what you are looking for :( .
>> At least, I've not even tried to do it (perhaps one should start
>> extractig the file descriptor, as explained here:
>>
>> http://www.ginac.de/~kreckel/fileno/
>>
>> )
>>
>> Or
>> http://stackoverflow.com/questions/2378005/c-iostreams-and-python
>>
>>
>> Hope this helps.
>>
>> --
>> You received this bug notification because you are a member of DOLFIN
>> Team, which is subscribed to DOLFIN.
>> https://bugs.launchpad.net/bugs/1072694
>>
>> Title:
>> list_timings() cannot be redirected to a file or a variable in python
>>
>> Status in DOLFI...

Read more...

Revision history for this message
corrado maurini (corrado-maurini) wrote :
Download full text (6.7 KiB)

Johan, I started adding Table output, but this stopped me very soon:

As soon I add
#include "Table.h"
in the log.h I have the following error at compilation:

May you give a quick explanation/solution?

Corrado
-----------------------
majorana:dorsal_build_dir maurini$ make all
[ 0%] Building CXX object dolfin/CMakeFiles/dolfin.dir/adaptivity/adapt.cpp.o
In file included from /opt/HPC/FEniCS/src/dolfin/dolfin/common/Variable.h:27,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/log/Table.h:28,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/log/log.h:32,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/log/dolfin_log.h:6,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/common/MPI.h:32,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/fem/UFCCell.h:29,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/fem/FiniteElement.h:27,
                 from /opt/HPC/FEniCS/src/dolfin/dolfin/adaptivity/adapt.cpp:25:
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string)':
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:117: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:117: error: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string, T, T)':
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:128: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string, std::set<T, std::less<_Key>, std::allocator<_CharT> >)':
/opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:139: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
make[2]: *** [dolfin/CMakeFiles/dolfin.dir/adaptivity/adapt.cpp.o] Error 1
make[1]: *** [dolfin/CMakeFiles/dolfin.dir/all] Error 2
make: *** [all] Error 2

Le 30 oct. 2012 à 21:40, Johan Hake a écrit :

> On 10/30/2012 11:53 AM, corrado maurini wrote:
>> Johan,
>>
>> Thanks a lot for taking care of this.
>
> Well, we see how far it goes :)
>
>> If redirecting ostream through python is too difficult, for the specific
>> case a possible alternative can be to have a function similar to
>> list_timings(), but giving a dolfin Table as output.
>
> Sure that would be pretty trivial to implement, and we have them same
> analogy for list_linear_algebra_backends and linear_algebra_backends,
> where the later return a list of strings instead of printing them to the
> screen.
>
> So adding a free function called timings would fit fine here.
>
>> Then the Table is a python object and one can use the associated methods
>> to access data or print it out (event in latex format!).
>
> Good point!
>
>> I have not done t...

Read more...

Revision history for this message
Benjamin Kehlet (benjamik) wrote :
Download full text (7.9 KiB)

2012/10/31 corrado maurini <email address hidden>:
> Johan, I started adding Table output, but this stopped me very soon:
>
> As soon I add
> #include "Table.h"
> in the log.h I have the following error at compilation:
>
> May you give a quick explanation/solution?

I think you introduce a circular dependency of header files here:

log/log.h -> log/Table.h -> common/Variable.h ->
parameter/Parameters.h -> log/log.h

Maybe class Table doesn't need to inherit class Variable? That would
solve it, I think, but the core developers should comment on that.

Regards
Benjamin

>
> Corrado
> -----------------------
> majorana:dorsal_build_dir maurini$ make all
> [ 0%] Building CXX object dolfin/CMakeFiles/dolfin.dir/adaptivity/adapt.cpp.o
> In file included from /opt/HPC/FEniCS/src/dolfin/dolfin/common/Variable.h:27,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/log/Table.h:28,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/log/log.h:32,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/log/dolfin_log.h:6,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/common/MPI.h:32,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/fem/UFCCell.h:29,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/fem/FiniteElement.h:27,
> from /opt/HPC/FEniCS/src/dolfin/dolfin/adaptivity/adapt.cpp:25:
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string)':
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:117: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:117: error: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string, T, T)':
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:128: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string, std::set<T, std::less<_Key>, std::allocator<_CharT> >)':
> /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:139: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
> make[2]: *** [dolfin/CMakeFiles/dolfin.dir/adaptivity/adapt.cpp.o] Error 1
> make[1]: *** [dolfin/CMakeFiles/dolfin.dir/all] Error 2
> make: *** [all] Error 2
>
> Le 30 oct. 2012 à 21:40, Johan Hake a écrit :
>
>> On 10/30/2012 11:53 AM, corrado maurini wrote:
>>> Johan,
>>>
>>> Thanks a lot for taking care of this.
>>
>> Well, we see how far it goes :)
>>
>>> If redirecting ostream through python is too difficult, for the specific
>>> case a possible alternative can be to have a function similar to
>>> list_timings(), but giving a dolfin Table as output.
>>
>> Sure that would be pretty trivial to impl...

Read more...

Revision history for this message
Anders Logg (logg) wrote :
Download full text (8.2 KiB)

On Wed, Oct 31, 2012 at 02:53:25PM -0000, Benjamin Kehlet wrote:
> 2012/10/31 corrado maurini <email address hidden>:
> > Johan, I started adding Table output, but this stopped me very soon:
> >
> > As soon I add
> > #include "Table.h"
> > in the log.h I have the following error at compilation:
> >
> > May you give a quick explanation/solution?
>
> I think you introduce a circular dependency of header files here:
>
> log/log.h -> log/Table.h -> common/Variable.h ->
> parameter/Parameters.h -> log/log.h
>
> Maybe class Table doesn't need to inherit class Variable? That would
> solve it, I think, but the core developers should comment on that.

Inheritance from Variable is there so we can do info(table) and info
will know to call table.str.

Circular dependencies can usually be worked around with forward
declarations but I haven't looked at this case in detail.

--
Anders

>
> Regards
> Benjamin
>
> >
> > Corrado
> > -----------------------
> > majorana:dorsal_build_dir maurini$ make all
> > [ 0%] Building CXX object dolfin/CMakeFiles/dolfin.dir/adaptivity/adapt.cpp.o
> > In file included from /opt/HPC/FEniCS/src/dolfin/dolfin/common/Variable.h:27,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/log/Table.h:28,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/log/log.h:32,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/log/dolfin_log.h:6,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/common/MPI.h:32,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/fem/UFCCell.h:29,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/fem/FiniteElement.h:27,
> > from /opt/HPC/FEniCS/src/dolfin/dolfin/adaptivity/adapt.cpp:25:
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string)':
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:117: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:117: error: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string, T, T)':
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:128: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h: In member function 'void dolfin::Parameters::add(std::string, std::set<T, std::less<_Key>, std::allocator<_CharT> >)':
> > /opt/HPC/FEniCS/src/dolfin/dolfin/parameter/Parameters.h:139: error: there are no arguments to 'dolfin_error' that depend on a template parameter, so a declaration of 'dolfin_error' must be available
> > make[2]: *** [dolfin/CMakeFiles/dolfin.dir/adaptivity/adapt.cpp.o] Error 1
> > make[1]: *** [dolfin/CMakeFiles/dolfin.dir/all] Error 2
> > make: *** [all] Error 2
> >
> > Le 30 oct. 2012 à 21:40, Johan Hake a écrit :
> >
> >> On 10/...

Read more...

Revision history for this message
Johan Hake (johan-hake) wrote :

I have now added timings to timing.h and moved list_timings to . After some fiddling it should be fine. However I need to run it on the buildbot before it is checked in.

Revision history for this message
corrado maurini (corrado-maurini) wrote : Re: [Bug 1072694] Re: list_timings() cannot be redirected to a file or a variable in python

Thanks a lot.

This is very useful for me.

I own you a coffee, or a beer if you prefer, whenever you pass through Paris !

As a minor note, the name "timings" as a pure function is prone to conflict with other definitions. I found for example
Table timings("Timings");
in dolfin/bench/fem/multicore/cpp/main.cpp, that should probably be modified.

Corrado

On Nov 1, 2012, at 8:57 AM, Johan Hake wrote:

> I have now added timings to timing.h and moved list_timings to . After
> some fiddling it should be fine. However I need to run it on the
> buildbot before it is checked in.
>
> --
> You received this bug notification because you are a member of DOLFIN
> Team, which is subscribed to DOLFIN.
> https://bugs.launchpad.net/bugs/1072694
>
> Title:
> list_timings() cannot be redirected to a file or a variable in python
>
> Status in DOLFIN:
> Confirmed
>
> Bug description:
> In python it is not possible to redirect the output of list_timings()
> to a file.
>
> set_output_stream(std::ostream& out) in log.ccp is not working in
> python because of problems in wrapping cpp ostream
>
> see also https://answers.launchpad.net/dolfin/+question/211271
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/dolfin/+bug/1072694/+subscriptions

Revision history for this message
Anders Logg (logg) wrote :

On Thu, Nov 01, 2012 at 07:57:43AM -0000, Johan Hake wrote:
> I have now added timings to timing.h and moved list_timings to . After
> some fiddling it should be fine. However I need to run it on the
> buildbot before it is checked in.

I'm not sure it should be moved to timing.h. That module only contains
helper functions for running timings. Actually storing them requires a
singleton object to keep track of the timings which is why it's stored
as part of the Logger class in dolfin/log/.

--
Anders

Revision history for this message
Johan Hake (johan-hake) wrote :

On 11/01/2012 06:51 PM, Anders Logg wrote:
> On Thu, Nov 01, 2012 at 07:57:43AM -0000, Johan Hake wrote:
>> I have now added timings to timing.h and moved list_timings to . After
>> some fiddling it should be fine. However I need to run it on the
>> buildbot before it is checked in.
>
> I'm not sure it should be moved to timing.h. That module only contains
> helper functions for running timings. Actually storing them requires a
> singleton object to keep track of the timings which is why it's stored
> as part of the Logger class in dolfin/log/.

The actual work is still done within the singleton object of Logger. The
free function I put within timing.h. I thought and still thing they
functionalwise fit together.

If you are not cool with this we could move them back to dolfin/log, but
out of log.h.

Johan

Revision history for this message
Anders Logg (logg) wrote :

On Thu, Nov 01, 2012 at 07:37:56PM +0100, Johan Hake wrote:
> On 11/01/2012 06:51 PM, Anders Logg wrote:
> > On Thu, Nov 01, 2012 at 07:57:43AM -0000, Johan Hake wrote:
> >> I have now added timings to timing.h and moved list_timings to . After
> >> some fiddling it should be fine. However I need to run it on the
> >> buildbot before it is checked in.
> >
> > I'm not sure it should be moved to timing.h. That module only contains
> > helper functions for running timings. Actually storing them requires a
> > singleton object to keep track of the timings which is why it's stored
> > as part of the Logger class in dolfin/log/.
>
> The actual work is still done within the singleton object of Logger. The
> free function I put within timing.h. I thought and still thing they
> functionalwise fit together.

ok, sounds good then.

--
Anders

> If you are not cool with this we could move them back to dolfin/log, but
> out of log.h.
>
> Johan

Johan Hake (johan-hake)
Changed in dolfin:
status: Confirmed → Fix Committed
Changed in dolfin:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.