Skip to content

lal/python/lal/__init__.py.in: warn on performance penalty of SWIGLAL stdio redirection

Karl Wette requested to merge ANU-CGA/lalsuite:Wswiglal-redir-stdio into master

Description

As discovered by @matthew-pitkin in #709 (closed) the SWIGLAL redirection of standard output/error enabled by default in IPython can incur a significant performance penalty. It is desirable to continue to enable the redirection by default, to ensure error messages aren't lost when calling LAL code from Jupyter notebooks, and under the assumption that most people aren't replying on peak performance for interactive use with Jupyter notebooks. That said, this should probably come with a warning in case the performance impact is important for some use cases.

This MR adds a warning in lal/python/lal/__init__.py.in if SWIGLAL is used from IPython. The warning explains the possible performance consequences of the redirection; how to disable it locally (using a context manager) or globally, and the consequences of doing so; and how to disable the warning itself if people find it annoying. (There's also a minor build system fix to gnuscripts/lalsuite_python.am.)

Example usage:

Python 3.8.10 (default, May 26 2023, 14:05:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import lal                                                                                                                                                                                           
<ipython-input-1-d291d32a6bcc>:1: UserWarning: Wswiglal-redir-stdio:

SWIGLAL standard output/error redirection is enabled in IPython.
This may lead to performance penalties. To disable locally, use:

with lal.no_swig_redirect_standard_output_error():
    ...

To disable globally, use:

lal.swig_redirect_standard_output_error(True)

Note however that this will likely lead to error messages from
LAL functions being either misdirected or lost when called from
Jupyter notebooks.

To suppress this warning, use:

import warnings
warnings.filterwarnings("ignore", "Wswiglal-redir-stdio")
import lal

  import lal

In [2]: seconds = 1357377318                                                                                                                                                                                 

In [3]: nanoseconds = 0                                                                                                                                                                                      

In [4]: %timeit lal.LIGOTimeGPS(seconds, nanoseconds)                                                                                                                                                        
12.4 ms ± 3.78 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [5]: with lal.no_swig_redirect_standard_output_error(): 
   ...:     %timeit lal.LIGOTimeGPS(seconds, nanoseconds) 
   ...:                                                                                                                                                                                                      
583 ns ± 9.93 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [6]:
Python 3.8.10 (default, May 26 2023, 14:05:08) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import warnings 
   ...: warnings.filterwarnings("ignore", "Wswiglal-redir-stdio") 
   ...: import lal 
   ...:                                                                                                                                                                                                      

In [2]:                                                                                                                                                                                                      

API Changes and Justification

Backwards Compatible Changes

  • This change does not modify any class/function/struct/type definitions in a public C header file or any Python class/function definitions
  • This change adds new classes/functions/structs/types to a public C header file or Python module

Backwards Incompatible Changes

  • This change modifies an existing class/function/struct/type definition in a public C header file or Python module
  • This change removes an existing class/function/struct/type from a public C header file or Python module

If any of the Backwards Incompatible check boxes are ticked please provide a justification why this change is necessary and why it needs to be done in a backwards incompatible way.

Review Status

cc @adam-mercer for the upcoming release.

Merge request reports