Double precision support in C++ AMP

C++ AMP supports various data types for usage in the restrict(amp) functions that you schedule on the accelerator. One of those types is double. There are caveats and extra information that you need to know with regards to double precision and this post aims to help you with that.

It all depends on your driver

Not all hardware supports doubles so if you have double precision requirements, you need to check that your hardware has such support.

In addition, you must ensure you have the latest driver for your hardware (by visiting the hardware vendor’s website) that enables the support – it is not an uncommon pitfall to read online the specs for your hardware saying one thing, but finding that your installed driver reports another thing because it hasn’t been updated.

To complicate matters further, there are two levels of double support and hence there are two APIs exposed by C++ AMP to let you query for that support.

Limited double precision

In Windows Display Driver Model (WDDM) 1.1, double precision is an optional feature for hardware vendors to implement in their DirectX drivers. Even if they do, it is what we call limited double precision support. That means that the following double operations are not supported:

  • FMA (fused multiply add).
  • Division
  • Reciprocal (rcp)
  • Casting between int and double

Through C++ AMP you’ll know whether your system has a WDDM 1.1 driver that supports limited double precision by checking the supports_limited_double_precision property on the accelerator, e.g.

bool can_use_doubles_with_limits = accelerator().supports_limited_double_precision;

(Full) Double precision

In WDDM 1.2 (currently supported by Windows 8 and Windows Server 2012 only), the limitations above were removed. So while double precision is still an optional feature, when hardware vendors opt in to implementing it, you get full (aka extended) double precision support.

Through C++ AMP you’ll know your system has a WDDM 1.2 driver that opted in to supporting double precision by checking the supports_double_precision property on the accelerator, e.g.

bool can_use_doubles = accelerator().supports_double_precision;

Note that full double precision is required by the concurrency::precise_math functions in <amp_math.h>

C++ AMP runtime exception

As you know, calls to the C++ AMP API on the host can throw exceptions that I encourage you to learn more about at our blog post on C++ AMP Exceptions.

If you try to use doubles on a card where the driver does not support doubles at all, or the driver has limited double precision support and you try something unsupported such as division, you will get a concurrency::runtime_exception with one of the following messages

"concurrency::parallel_for_each uses features (full double_precision) unsupported by the selected accelerator."

"concurrency::parallel_for_each uses features (limited_double_precision) unsupported by the selected accelerator."

Whichever message you get, if you are running under the debug configuration, it also includes the following text:

“ID3D11Device::CreateComputeShader: Shader uses features not recognized by this D3D version.”

Comments

  • Anonymous
    October 22, 2012
    The comment has been removed

  • Anonymous
    October 22, 2012
    Hi Ethatron, The most common I have seen are double constants like "float x = 0.0" the "0.0" is actually a double that is converted to float. The second most common is including precise_math. Any math function from that namespace even if only for single-precision overload would require double precision support: blogs.msdn.com/.../math-library-for-c-amp.aspx If none of the above help, then try to comment out portions of the code to track it down... we will look into improving diagnosability for this scenario, thanks for posting a question! Regards, Simon

  • Anonymous
    October 22, 2012
    The comment has been removed

  • Anonymous
    October 22, 2012
    A third option would be to compile with /W4.  Hopefully that will generate a warning when the double gets trunctated back to float.

  • Anonymous
    December 03, 2012
    IS MS thinking of adding another form of restrict that will give you compile time errors if you use doubles in a way that won't work on a card with only limited double support. Reading through instructions output by the compiler seems like a bold leap back to the 70s.

  • Anonymous
    December 04, 2012
    Thanks for the feedback. We will take your suggestion into consideration.

  • Anonymous
    December 14, 2012
    Can't warp be extended or an emulation be made so that amp always supports doubles. Currently my video card doesn't support it so I can't test or deploy double. For my customers I would need to make two versions or not use doubles at all.

  • Anonymous
    January 02, 2013
    Thanks for the feedback Rolf. We realize the importance of this and are working on it.

  • Anonymous
    April 29, 2014
    Hi I am interesting about using the C++AMP. Is there some samples about how to use the functions such modf(float x, float * iptr) and other functions   in the amp? Thanks.