fptool: Instruments for Floating-Point Arithmetic#
The other two sub-components give you arithmetic to compute with. fptool gives you two
instruments for finding out what a computation needs and what it is doing — questions that are
otherwise answered by guesswork, or by rewriting the algorithm in a narrower type and hoping the
rewrite was faithful.
Tool |
Answers |
How |
|---|---|---|
How little precision does this algorithm need? Is it the mantissa or the dynamic range that matters? |
Rounds to an arbitrary exponent and mantissa width after every operation, so the computation runs as though the hardware had that format |
|
What did the arithmetic actually do? Is the second limb carrying anything? Is anything silently corrupt? |
Wraps an |
The difference between them is worth stating plainly, because it decides how each is used: ``fp64_custom`` changes the arithmetic, and the ``fpmp2_stat`` types only observe it. One is there to make results worse in a controlled way, so you can see how much worse the algorithm tolerates. The other is there to leave results alone — bit-identical to the type it wraps, by construction — so that an instrumented run can be compared against a plain one, and a difference between them means a race or an uninitialized value rather than a rounding change.
Neither is a type to ship in#
Both are diagnostics, and both cost rather than save:
fp64_customemulates a narrow format on native FP64, adding a rounding step to each operand and to each result. Modelling BF16 with it is therefore slower thandouble, not faster — in the integration measured here every reduced format costs about 10% over plaindouble. What it buys is the answer to “would this work in BF16”, on hardware that has no BF16 arithmetic, for a format that no hardware need ever implement.an instrumented
fpmp2_statrun is two to three orders of magnitude slower than the plain type, every operation updating one device-wide record through atomics.
So the shape of a study is: reach for one of these to answer a question, read the answer, and put
it back. Both are designed for that — fp64_custom is a drop-in for double and the
fpmp2_stat types are drop-ins for the fpmp2 types they wrap, so in each case the change
is to a type alias and the algorithm is left alone. Keeping that alias behind a build flag is the
arrangement worth copying — and the header itself is behind one, CCCL_ENABLE_FPTOOL, so that
a leftover include cannot quietly carry the tools into a shipping build.
Using the header#
The feature is opt-in, for the reason above. Both tools keep mutable state at namespace scope —
fp64_custom’s runtime field sizes and the fpmp2_stat counter record — and because those
are variable templates, one copy is shared by every translation unit that includes the header. That
sharing is what makes the tools work, and it is also why an #include left behind after a study
is not free: the state, and for fpmp2_stat the atomic traffic on every operation, go into the
binary with it. So <cuda/fptool> refuses to compile until a project asks for it:
nvcc -DCCCL_ENABLE_FPTOOL ...
Important
Define it for the whole project rather than per file. The state above is shared across translation units, so a build where only some of them have opted in is the one configuration to avoid. This is the same rule the other CCCL configuration macros follow.
#include <cuda/fptool>
One header carries both tools and their math functions, as <cuda/fpmp> does. The one
consequence to know is that including it costs about a fifth more than the types alone, since the
statistics math wrappers rest on the fpmp math surface.
Both tools work in host and device code from the same source, but with an asymmetry that matters in opposite directions:
fp64_customkeeps independent host and device sizes, deliberately, so a full-precision host reference can run alongside a reduced device computation.fpmp2_statcollection is device-only. The same source compiles and runs on the host, where the wrapper is a transparent pass-through and nothing is gathered — so a program doing part of its arithmetic on the host reports a count below what its closed form predicts, with no diagnostic.
Everything either tool names is specific to the component and carries the namespace. Unlike
fpmp and fpemu, there is little here to find by argument-dependent lookup: the setters,
getters and readout functions take only an int or a stream, so there is no operand of a
component type to look in.
See also
fp64_custom — emulating a narrower format on native FP64, for sensitivity studies.
fpmp2_stat — recording what the arithmetic did, without changing what it computes.