ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_npu_quant.h File Reference

Affine (scale + zero-point) tensor quantization for the NPU runtime. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_npu_quant.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_npu_quant_range_t : int32_t {
  k_ra8_npu_quant_i8_min = -128 ,
  k_ra8_npu_quant_i8_max = 127 ,
  k_ra8_npu_quant_u8_min = 0 ,
  k_ra8_npu_quant_u8_max = 255
}
 Saturation bounds of the supported quantized element types. More...

Functions

ra8_err_t ra8_npu_quantize_i8 (const float *in, int8_t *out, size_t count, float scale, int32_t zero_point)
 Quantize a float arena into an INT8 tensor (affine, saturating).
ra8_err_t ra8_npu_dequantize_i8 (const int8_t *in, float *out, size_t count, float scale, int32_t zero_point)
 Dequantize an INT8 tensor into a float arena (affine).
ra8_err_t ra8_npu_quantize_u8 (const float *in, uint8_t *out, size_t count, float scale, int32_t zero_point)
 Quantize a float arena into a UINT8 tensor (affine, saturating).
ra8_err_t ra8_npu_dequantize_u8 (const uint8_t *in, float *out, size_t count, float scale, int32_t zero_point)
 Dequantize a UINT8 tensor into a float arena (affine).

Detailed Description

Affine (scale + zero-point) tensor quantization for the NPU runtime.

Tag
[Ring 3 / HAL] {World: S}

Input/output quantization helpers for the Ethos-U55 inference runtime. An Ethos-U55 command stream operates on INT8 / UINT8 quantized tensors; the application holds its data as real-valued float. These four functions bridge the two with the standard TFLite affine mapping

real  = scale * (quantized - zero_point)
quantized = clamp(round(real / scale) + zero_point, qmin, qmax)

so a runtime can ra8_npu_quantize_*() a float input arena into the INT8 / UINT8 tensor the NPU reads, then ra8_npu_dequantize_*() the NPU output back to float for the application.

Why this is pure integer/float math (no libm)

Rounding is done with float arithmetic and an explicit cast rather than lroundf(), so this translation unit pulls in NO libm dependency. That matters because it is compiled into every app (it lives in the always-built ra8_hal source set); linking libm into apps that never quantize would be an unwanted cost. Unreferenced, --gc-sections drops it entirely.

Not device-gated

Unlike ra8_npu.h this header is NOT behind RA8_HAS_NPU: the mapping is plain arithmetic with no MMIO, useful (and host-testable) on any device, and the NPU-only driver stays the single owner of the RA8_HAS_NPU gate.

Threading

Re-entrant and stateless: every function reads only its arguments and writes only the caller's output buffer. Safe to call from any context.

Since
0.1.0

Definition in file ra8_npu_quant.h.

Enumeration Type Documentation

◆ ra8_npu_quant_range_t

enum ra8_npu_quant_range_t : int32_t

Saturation bounds of the supported quantized element types.

The quantize helpers clamp the rounded result to the closed range of the destination element type so an out-of-range real value saturates instead of wrapping. INT8 spans [-128, 127]; UINT8 spans [0, 255].

Invariant
k_ra8_npu_quant_i8_min <= k_ra8_npu_quant_i8_max.
k_ra8_npu_quant_u8_min <= k_ra8_npu_quant_u8_max.
See also
ra8_npu_quantize_i8
ra8_npu_quantize_u8
Since
0.1.0
Enumerator
k_ra8_npu_quant_i8_min 

INT8 lower saturation bound.

k_ra8_npu_quant_i8_max 

INT8 upper saturation bound.

k_ra8_npu_quant_u8_min 

UINT8 lower saturation bound.

k_ra8_npu_quant_u8_max 

UINT8 upper saturation bound.

Definition at line 71 of file ra8_npu_quant.h.

Function Documentation

◆ ra8_npu_dequantize_i8()

ra8_err_t ra8_npu_dequantize_i8 ( const int8_t * in,
float * out,
size_t count,
float scale,
int32_t zero_point )
nodiscard

Dequantize an INT8 tensor into a float arena (affine).

Maps each in[i] to scale * (in[i] - zero_point).

Parameters
[in]inSource INT8 arena of count elements (non-NULL).
[out]outDestination float arena of count elements (non-NULL).
[in]countNumber of elements to convert (0 is a valid no-op).
[in]scaleQuantization scale (the same value used to quantize).
[in]zero_pointQuantization zero-point (subtracted before scaling).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll count elements dequantized into out.
k_ra8_err_null_ptrin or out was nullptr.
Precondition
in and out are non-NULL and each address count elements.
scale matches the value used to quantize in.
Postcondition
On success each out[i] holds scale * (in[i] - zero_point).
On any error out is left unmodified.
Note
Re-entrant; no shared state.
See also
ra8_npu_quantize_i8
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 5: 2 preconditions, 2 postconditions
  • Rule 7: returns ra8_err_t, marked [[nodiscard]]

Definition at line 128 of file ra8_npu_quant.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

◆ ra8_npu_dequantize_u8()

ra8_err_t ra8_npu_dequantize_u8 ( const uint8_t * in,
float * out,
size_t count,
float scale,
int32_t zero_point )
nodiscard

Dequantize a UINT8 tensor into a float arena (affine).

Maps each in[i] to scale * (in[i] - zero_point).

Parameters
[in]inSource UINT8 arena of count elements (non-NULL).
[out]outDestination float arena of count elements (non-NULL).
[in]countNumber of elements to convert (0 is a valid no-op).
[in]scaleQuantization scale (the same value used to quantize).
[in]zero_pointQuantization zero-point (subtracted before scaling).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll count elements dequantized into out.
k_ra8_err_null_ptrin or out was nullptr.
Precondition
in and out are non-NULL and each address count elements.
scale matches the value used to quantize in.
Postcondition
On success each out[i] holds scale * (in[i] - zero_point).
On any error out is left unmodified.
Note
Re-entrant; no shared state.
See also
ra8_npu_quantize_u8
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 5: 2 preconditions, 2 postconditions
  • Rule 7: returns ra8_err_t, marked [[nodiscard]]

Definition at line 158 of file ra8_npu_quant.c.

References k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_npu_infer_execute().

◆ ra8_npu_quantize_i8()

ra8_err_t ra8_npu_quantize_i8 ( const float * in,
int8_t * out,
size_t count,
float scale,
int32_t zero_point )
nodiscard

Quantize a float arena into an INT8 tensor (affine, saturating).

Maps each in[i] to clamp(round(in[i] / scale) + zero_point, -128, 127). Rounding is half-away-from-zero. The intermediate is bounded before the cast so an extreme real value saturates rather than triggering undefined float-to-int conversion.

Parameters
[in]inSource float arena of count elements (non-NULL).
[out]outDestination INT8 arena of count elements (non-NULL).
[in]countNumber of elements to convert (0 is a valid no-op).
[in]scaleQuantization scale, strictly positive (> 0).
[in]zero_pointQuantization zero-point (added after rounding).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll count elements quantized into out.
k_ra8_err_null_ptrin or out was nullptr.
k_ra8_err_invalid_argscale was not strictly positive.
Precondition
in and out are non-NULL and each address count elements.
scale is strictly positive.
Postcondition
On success each out[i] holds the saturated INT8 quantization of in[i].
On any error out is left unmodified.
Note
Re-entrant; no shared state.
See also
ra8_npu_dequantize_i8
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 5: 2 preconditions, 2 postconditions
  • Rule 7: returns ra8_err_t, marked [[nodiscard]]

Definition at line 109 of file ra8_npu_quant.c.

References internal_quant_round_clamp(), k_ra8_err_invalid_arg, k_ra8_npu_quant_i8_max, k_ra8_npu_quant_i8_min, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.

◆ ra8_npu_quantize_u8()

ra8_err_t ra8_npu_quantize_u8 ( const float * in,
uint8_t * out,
size_t count,
float scale,
int32_t zero_point )
nodiscard

Quantize a float arena into a UINT8 tensor (affine, saturating).

Maps each in[i] to clamp(round(in[i] / scale) + zero_point, 0, 255). Rounding is half-away-from-zero. The intermediate is bounded before the cast so an extreme real value saturates rather than triggering undefined float-to-int conversion.

Parameters
[in]inSource float arena of count elements (non-NULL).
[out]outDestination UINT8 arena of count elements (non-NULL).
[in]countNumber of elements to convert (0 is a valid no-op).
[in]scaleQuantization scale, strictly positive (> 0).
[in]zero_pointQuantization zero-point (added after rounding).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll count elements quantized into out.
k_ra8_err_null_ptrin or out was nullptr.
k_ra8_err_invalid_argscale was not strictly positive.
Precondition
in and out are non-NULL and each address count elements.
scale is strictly positive.
Postcondition
On success each out[i] holds the saturated UINT8 quantization of in[i].
On any error out is left unmodified.
Note
Re-entrant; no shared state.
See also
ra8_npu_dequantize_u8
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 5: 2 preconditions, 2 postconditions
  • Rule 7: returns ra8_err_t, marked [[nodiscard]]

Definition at line 139 of file ra8_npu_quant.c.

References internal_quant_round_clamp(), k_ra8_err_invalid_arg, k_ra8_npu_quant_u8_max, k_ra8_npu_quant_u8_min, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.

Referenced by internal_npu_infer_prepare_input().