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