| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 1 |  | 
 | 2 | :mod:`fpectl` --- Floating point exception control | 
 | 3 | ================================================== | 
 | 4 |  | 
 | 5 | .. module:: fpectl | 
 | 6 |    :platform: Unix | 
 | 7 |    :synopsis: Provide control for floating point exception handling. | 
 | 8 | .. moduleauthor:: Lee Busby <busby1@llnl.gov> | 
 | 9 | .. sectionauthor:: Lee Busby <busby1@llnl.gov> | 
 | 10 |  | 
 | 11 |  | 
 | 12 | .. note:: | 
 | 13 |  | 
 | 14 |    The :mod:`fpectl` module is not built by default, and its usage is discouraged | 
 | 15 |    and may be dangerous except in the hands of experts.  See also the section | 
 | 16 |    :ref:`fpectl-limitations` on limitations for more details. | 
 | 17 |  | 
 | 18 | .. index:: single: IEEE-754 | 
 | 19 |  | 
 | 20 | Most computers carry out floating point operations in conformance with the | 
 | 21 | so-called IEEE-754 standard. On any real computer, some floating point | 
 | 22 | operations produce results that cannot be expressed as a normal floating point | 
 | 23 | value. For example, try :: | 
 | 24 |  | 
 | 25 |    >>> import math | 
 | 26 |    >>> math.exp(1000) | 
 | 27 |    inf | 
 | 28 |    >>> math.exp(1000) / math.exp(1000) | 
 | 29 |    nan | 
 | 30 |  | 
 | 31 | (The example above will work on many platforms. DEC Alpha may be one exception.) | 
 | 32 | "Inf" is a special, non-numeric value in IEEE-754 that stands for "infinity", | 
 | 33 | and "nan" means "not a number." Note that, other than the non-numeric results, | 
 | 34 | nothing special happened when you asked Python to carry out those calculations. | 
 | 35 | That is in fact the default behaviour prescribed in the IEEE-754 standard, and | 
 | 36 | if it works for you, stop reading now. | 
 | 37 |  | 
 | 38 | In some circumstances, it would be better to raise an exception and stop | 
 | 39 | processing at the point where the faulty operation was attempted. The | 
 | 40 | :mod:`fpectl` module is for use in that situation. It provides control over | 
 | 41 | floating point units from several hardware manufacturers, allowing the user to | 
 | 42 | turn on the generation of :const:`SIGFPE` whenever any of the IEEE-754 | 
 | 43 | exceptions Division by Zero, Overflow, or Invalid Operation occurs. In tandem | 
 | 44 | with a pair of wrapper macros that are inserted into the C code comprising your | 
 | 45 | python system, :const:`SIGFPE` is trapped and converted into the Python | 
 | 46 | :exc:`FloatingPointError` exception. | 
 | 47 |  | 
 | 48 | The :mod:`fpectl` module defines the following functions and may raise the given | 
 | 49 | exception: | 
 | 50 |  | 
 | 51 |  | 
 | 52 | .. function:: turnon_sigfpe() | 
 | 53 |  | 
 | 54 |    Turn on the generation of :const:`SIGFPE`, and set up an appropriate signal | 
 | 55 |    handler. | 
 | 56 |  | 
 | 57 |  | 
 | 58 | .. function:: turnoff_sigfpe() | 
 | 59 |  | 
 | 60 |    Reset default handling of floating point exceptions. | 
 | 61 |  | 
 | 62 |  | 
 | 63 | .. exception:: FloatingPointError | 
 | 64 |  | 
 | 65 |    After :func:`turnon_sigfpe` has been executed, a floating point operation that | 
 | 66 |    raises one of the IEEE-754 exceptions Division by Zero, Overflow, or Invalid | 
 | 67 |    operation will in turn raise this standard Python exception. | 
 | 68 |  | 
 | 69 |  | 
 | 70 | .. _fpectl-example: | 
 | 71 |  | 
 | 72 | Example | 
 | 73 | ------- | 
 | 74 |  | 
 | 75 | The following example demonstrates how to start up and test operation of the | 
 | 76 | :mod:`fpectl` module. :: | 
 | 77 |  | 
 | 78 |    >>> import fpectl | 
 | 79 |    >>> import fpetest | 
 | 80 |    >>> fpectl.turnon_sigfpe() | 
 | 81 |    >>> fpetest.test() | 
 | 82 |    overflow        PASS | 
 | 83 |    FloatingPointError: Overflow | 
 | 84 |  | 
 | 85 |    div by 0        PASS | 
 | 86 |    FloatingPointError: Division by zero | 
 | 87 |      [ more output from test elided ] | 
 | 88 |    >>> import math | 
 | 89 |    >>> math.exp(1000) | 
 | 90 |    Traceback (most recent call last): | 
 | 91 |      File "<stdin>", line 1, in ? | 
 | 92 |    FloatingPointError: in math_1 | 
 | 93 |  | 
 | 94 |  | 
 | 95 | .. _fpectl-limitations: | 
 | 96 |  | 
 | 97 | Limitations and other considerations | 
 | 98 | ------------------------------------ | 
 | 99 |  | 
 | 100 | Setting up a given processor to trap IEEE-754 floating point errors currently | 
 | 101 | requires custom code on a per-architecture basis. You may have to modify | 
 | 102 | :mod:`fpectl` to control your particular hardware. | 
 | 103 |  | 
 | 104 | Conversion of an IEEE-754 exception to a Python exception requires that the | 
 | 105 | wrapper macros ``PyFPE_START_PROTECT`` and ``PyFPE_END_PROTECT`` be inserted | 
 | 106 | into your code in an appropriate fashion.  Python itself has been modified to | 
 | 107 | support the :mod:`fpectl` module, but many other codes of interest to numerical | 
 | 108 | analysts have not. | 
 | 109 |  | 
 | 110 | The :mod:`fpectl` module is not thread-safe. | 
 | 111 |  | 
 | 112 |  | 
 | 113 | .. seealso:: | 
 | 114 |  | 
 | 115 |    Some files in the source distribution may be interesting in learning more about | 
 | 116 |    how this module operates. The include file :file:`Include/pyfpe.h` discusses the | 
 | 117 |    implementation of this module at some length. :file:`Modules/fpetestmodule.c` | 
 | 118 |    gives several examples of use. Many additional examples can be found in | 
 | 119 |    :file:`Objects/floatobject.c`. | 
 | 120 |  |