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

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

#include "ra8_npu_quant.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
Include dependency graph for ra8_npu_quant.c:

Go to the source code of this file.

Functions

static int32_t internal_quant_round_clamp (float scaled, int32_t zero_point, int32_t qmin, int32_t qmax)
 Round scaled half-away-from-zero, add the zero-point, and clamp.
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).

Variables

static const char * s_tag = "NPUQ"
 Log component tag for this module.
static const float s_quant_round_cap = 1.0e6F
 Magnitude the pre-cast rounded value is clamped to (float, no libm).
static const float s_quant_half = 0.5F
 The half-step used for half-away-from-zero rounding without libm.

Detailed Description

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

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

Implementation of the ra8_npu_quant.h contract. The core rounding + clamp is factored into a single helper (internal_quant_round_clamp) shared by the INT8 and UINT8 quantizers so the saturation logic is written and tested once. No hardware is touched, so this file carries no HUM / TRM citation, and no libm symbol is referenced – rounding is float arithmetic plus an explicit, range-bounded cast.

Since
0.1.0

Definition in file ra8_npu_quant.c.

Function Documentation

◆ internal_quant_round_clamp()

int32_t internal_quant_round_clamp ( float scaled,
int32_t zero_point,
int32_t qmin,
int32_t qmax )
static

Round scaled half-away-from-zero, add the zero-point, and clamp.

Computes clamp((int32)round(scaled) + zero_point, qmin, qmax) using only float arithmetic and one bounded cast (no libm). scaled is the real value already divided by the quantization scale; the rounded magnitude is clamped to s_quant_round_cap before the cast so the conversion is always in range.

Parameters
[in]scaledReal value divided by the quantization scale.
[in]zero_pointQuantization zero-point added after rounding.
[in]qminLower saturation bound of the destination type.
[in]qmaxUpper saturation bound of the destination type.
Returns
The saturated integer quantized value in [qmin, qmax].
Return values
qminscaled mapped below the destination range.
qmaxscaled mapped above the destination range.
Precondition
qmin <= qmax.
scaled is a finite value.
Postcondition
The result is within [qmin, qmax].
No argument is modified.
Note
Re-entrant; no shared state.
Since
0.1.0

Definition at line 89 of file ra8_npu_quant.c.

References s_quant_half, and s_quant_round_cap.

Referenced by ra8_npu_quantize_i8(), and ra8_npu_quantize_u8().

◆ 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().

Variable Documentation

◆ s_quant_half

const float s_quant_half = 0.5F
static

The half-step used for half-away-from-zero rounding without libm.

Held as a const float because an enum cannot carry a float; this is the named constant that keeps the rounding step out of the code as a magic number.

Note
Read-only; never modified.
Since
0.1.0

Definition at line 60 of file ra8_npu_quant.c.

Referenced by internal_quant_round_clamp().

◆ s_quant_round_cap

const float s_quant_round_cap = 1.0e6F
static

Magnitude the pre-cast rounded value is clamped to (float, no libm).

Bounds round(real / scale) well inside the 32-bit integer range so the float-to-int cast in internal_quant_round_clamp is always defined; any value this large saturates at the element bound anyway.

Note
Read-only; never modified.
Since
0.1.0

Definition at line 49 of file ra8_npu_quant.c.

Referenced by internal_quant_round_clamp().

◆ s_tag

const char* s_tag = "NPUQ"
static

Log component tag for this module.

Passed to the RA8_* validation macros as the source tag.

Note
Read-only literal; never modified.
Since
0.1.0

Definition at line 38 of file ra8_npu_quant.c.