Developer Guide

FPGA Optimization Guide for Intel® oneAPI Toolkits

ID 767853
Date 12/16/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Quality of Results and the ap_float Data Type

Replacing C++ native float and double data types with the ihc::FPsingle and ihc::FPdouble data types can result in different quality of results (QoR) for your design.

Use the techniques in the following sections to influence the QoR that you get when using floating-point data types.

Tuning Accuracy and Subnormal Settings with Explicit Operations

If you notice a difference in QoR when using ihc::FPsingle instead of float , set FP_Subnormal to OFF and set FP_Accuracy to LOW.

If you notice a difference in QoR when using ihc::FPdouble instead of double , set FP_Subnormal to ON and set FP_Accuracy to HIGH.

IMPORTANT:
These settings might not eliminate a QoR gap between a C++ native data type and its ap_float equivalent, but they should get the QoR a close to the native data type as possible.

Fast math, which is turned on by default, applies to the C++ native floating-point data types but not to ap_float data types. When fast math is enabled, the QoR gap between a C++ native data type and its ap_float equivalent can still be large.

For example, consider the changes to the following code snippet that uses C++ native data types:

float a_times_b(float a, float b)
{
    float ab = a * b;
    return ab;
}

You can change this code to use ap_float controls as follows:

ihc::FPsingle a_times_b(ihc::FPsingle a, ihc::FPsingle b)
{
    constexpr auto AccLOW = ihc::fp_config::FP_Accuracy::LOW;
    constexpr auto SubON = ihc::fp_config::FP_Subnormal::ON;
    auto ab = ihc::FPsingle::mul<AccLOW, SubOFF>(a, b);
    return ab;
}

Cast Constant Multiplication Operations to Native Data Types

For single-precision data types (ihc::FPsingle and ihc::ap_float<8,23>) and double-precision data types (ihc::FPdouble and ihc::ap_float<11,52>), casting constant multiplications to native data types can help with QoR.

For example, consider the following multiplication code snippet using C++ native data types:

float four_times_a(float a)
{
    float fourA = 4.0f * a;
    return fourA;
}
By using the earlier technique, you can convert that code snippet in the following code:
ihc::FPsingle four_times_a(ihc::FPsingle a)
{
    constexpr auto AccLOW = ihc::fp_config::FP_Accuracy::LOW;
    constexpr auto SubON = ihc::fp_config::FP_Subnormal::ON;
    auto fourA = ihc::FPsingle::mul<AccLOW, SubOFF>(
       ihc::FPsingle(4.0f), a);
    return fourA;
}
By casting the multiplication operation to native data types, you can improve the QoR of that code:
ihc::FPsingle four_times_a(ihc::FPsingle a)
{
    auto fourA = ihc::FPsingle(4.0f * ((float)a));
    return fourA;
}