Main Content

Generate Native Half-Precision C Code Using MATLAB Coder

Some embedded hardware targets natively support special types for half precision, such as _Float16 and _fp16 data types for ARM® compilers. You can use MATLAB® Coder™ to generate native half-precision C code for ARM Cortex®-A processors that natively support half precision floating-point data types.

The process to generate native half C code is as follows:

  • Register a new hardware target device that natively supports half precision using the target namespace.

  • Configure code generation configuration for half precision.

  • Generate native half type code.

Fixed-Point Designer™ and MATLAB Coder include preconfigured language implementations for Armclang and GCC compilers. For other hardware targets, you can specify a custom language implementation based on your hardware specifications.

Generate Native Half-Precision C Code for ARM® Cortex®-A with GCC Compiler

In this example, an ARM Cortex®-A processor is used as the hardware target. The model is configured to use this ARM target and the GNU GCC compiler toolchain.

Register Target Hardware

Use the target.create function to create an ARM processor target that is compatible with half precision.

arm_half = target.create('Processor','Manufacturer',"Broadcom",'Name','BCM2711 ARM Cortex A72');

Add the language implementation. Use the target.get function to retrieve the target object from the internal database.

li = target.get('LanguageImplementation',"GNU GCC ARM 32-bit");

Replace the default language implementation for ARM Cortex with Armclang.

arm_half.LanguageImplementations = li;

Use the target.add function to add the target object to the internal database.

target.add(arm_half);
target.add summary:

    Objects added to internal database for current MATLAB session:
        target.Processor                 "Broadcom-BCM2711 ARM Cortex A72"
    1 object not added because they already exist.

Open MATLAB Code that Uses Half-Precision Data Type

edit testNativeHalffp16.m

Configure Code Generation Configuration for Half Precision

Create the code generation configuration object.

cfg = coder.config('lib');

Specify the production hardware device type.

cfg.HardwareImplementation.ProdHWDeviceType = 'Broadcom->BCM2711 ARM Cortex A72';

Select the toolchain compatible with the selected hardware.

cfg.Toolchain = 'GNU Tools for ARM Embedded Processors'; 

Add the half-precision flags for compilation.

cfg.BuildConfiguration = 'Specify';
cfg.CustomToolchainOptions{4} = '-c -MMD -MP -MF"$(@:%.o=%.dep)" -MT"$@" -O0 -mfp16-format=ieee -mfpu=neon-fp16';

Generate Code

codegen testNativeHalffp16 -args {half(3)} -launchreport -config cfg

You can inspect the code generation report to confirm that the custom half-precision type definitions are used.

native_half_type_def.png

The half-precision constants use the f16 suffix.

native-half-constants-fp16-suffix.png

Generate Native Half-Precision C Code for ARM Cortex-A with Armclang Compiler

In this example, an ARM Cortex-A processor is used as the hardware target. The model is configured to use this ARM target and the Armclang compiler toolchain.

Register Target Hardware

Use the target.create function to create an ARM processor target that is compatible with half precision.

arm_half = target.create('Processor',...
    'Manufacturer',"Broadcom",...
    'Name','ARM Cortex A75');

Add the language implementation. Use the target.get function to retrieve the target object from the internal database.

li = target.get('LanguageImplementation',"Clang ARM 32-bit");

Replace the default language implementation for ARM Cortex with Armclang.

arm_half.LanguageImplementations = li;

Use the target.add function to add the target object to the internal database.

target.add(arm_half);

Configure Code Generation Configuration for Half Precision

Create the code generation configuration object.

cfg = coder.config('lib');

Specify the production hardware type.

cfg.HardwareImplementation.ProdHWDeviceType = 'Broadcom->ARM Cortex A75';

Select the toolchain compatible with the selected hardware.

cfg.Toolchain = 'Armclang Compiler';

Add the half-precision flags for compilation.

cfg.BuildConfiguration = 'Specify';
cfg.CustomToolchainOptions{4} = '-c -MMD -MP -MF"$(@:%.o=%.dep)" -MT"$@" -O0 --target=arm-arm-none-eabi -march=armv8.2-a+fp16';

Generate Code

codegen testNativeHalffp16 -args {half(3)} -launchreport -config cfg

Register ARM Target Hardware with Custom Language Implementation

In this example, create a new custom language implementation with half precision for a compatible ARM target.

Register Target Hardware

Use the target.create function to copy the ARM Compatible-ARM Cortex language implementation.

languageImplementation = target.create('LanguageImplementation',...
    'Name','ARM with half',...
    'Copy','ARM Compatible-ARM Cortex');

Specify custom half information and target specific headers, as given by your target hardware documentation. For more information, see Register New Hardware Devices. For example,

customHalf = target.create('FloatingPointDataType',...
    'Name','BCM2711 Half Type', ...
    'TypeName','_Float16',...
    'LiteralSuffix','f16',...
    'Size',16, ...
    'SystemIncludes',["arm_fp16.h" "arm_neon.h"]);
languageImplementation.DataTypes.NonStandardDataTypes = customHalf;

Provide information about your target processor. For example,

% Broadcom BCM2711
% Quad core Cortex-A72 (ARM v8) 64-bit SoC
pi4a72 = target.create('Processor','Manufacturer',...
    'Broadcom','Name','BCM2711');

Add the custom half-precision language implementation.

pi4a72.LanguageImplementations = languageImplementation;

Use the target.add function to add the target object to the internal database.

target.add(pi4a72);

See Also

| | | | |

Related Topics

External Websites