ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_npu_quant.c
Go to the documentation of this file.
1
20
21#include "ra8_npu_quant.h"
22
23#include <stddef.h>
24#include <stdint.h>
25
26#include "ra8_attributes.h"
27#include "ra8_check.h"
28#include "ra8_err.h"
29#include "ra8_log.h"
30
38static const char* s_tag = "NPUQ";
39
49static const float s_quant_round_cap = 1.0e6F;
50
60static const float s_quant_half = 0.5F;
61
88RA8_INTERNAL static int32_t
89internal_quant_round_clamp(float scaled, int32_t zero_point, int32_t qmin, int32_t qmax)
90{
91 float rounded = (scaled >= 0.0F) ? (scaled + s_quant_half) : (scaled - s_quant_half);
92 if (rounded > s_quant_round_cap) {
93 rounded = s_quant_round_cap;
94 }
95 if (rounded < -s_quant_round_cap) {
96 rounded = -s_quant_round_cap;
97 }
98 int32_t q = (int32_t)rounded + zero_point;
99 if (q < qmin) {
100 q = qmin;
101 }
102 if (q > qmax) {
103 q = qmax;
104 }
105 return q;
106}
107
109ra8_npu_quantize_i8(const float* in, int8_t* out, size_t count, float scale, int32_t zero_point)
110{
111 RA8_CHECK_NULL_PTR(in, s_tag, "quantize_i8: in must not be nullptr");
112 RA8_CHECK_NULL_PTR(out, s_tag, "quantize_i8: out must not be nullptr");
113 if (scale <= 0.0F) {
114 ra8_log_error(s_tag, "quantize_i8: scale must be > 0");
116 }
117 for (size_t i = 0U; i < count; i++) {
118 const int32_t q = internal_quant_round_clamp(in[i] / scale,
119 zero_point,
120 (int32_t)k_ra8_npu_quant_i8_min,
121 (int32_t)k_ra8_npu_quant_i8_max);
122 out[i] = (int8_t)q;
123 }
124 return k_ra8_ok;
125}
126
128ra8_npu_dequantize_i8(const int8_t* in, float* out, size_t count, float scale, int32_t zero_point)
129{
130 RA8_CHECK_NULL_PTR(in, s_tag, "dequantize_i8: in must not be nullptr");
131 RA8_CHECK_NULL_PTR(out, s_tag, "dequantize_i8: out must not be nullptr");
132 for (size_t i = 0U; i < count; i++) {
133 out[i] = scale * (float)((int32_t)in[i] - zero_point);
134 }
135 return k_ra8_ok;
136}
137
139ra8_npu_quantize_u8(const float* in, uint8_t* out, size_t count, float scale, int32_t zero_point)
140{
141 RA8_CHECK_NULL_PTR(in, s_tag, "quantize_u8: in must not be nullptr");
142 RA8_CHECK_NULL_PTR(out, s_tag, "quantize_u8: out must not be nullptr");
143 if (scale <= 0.0F) {
144 ra8_log_error(s_tag, "quantize_u8: scale must be > 0");
146 }
147 for (size_t i = 0U; i < count; i++) {
148 const int32_t q = internal_quant_round_clamp(in[i] / scale,
149 zero_point,
150 (int32_t)k_ra8_npu_quant_u8_min,
151 (int32_t)k_ra8_npu_quant_u8_max);
152 out[i] = (uint8_t)q;
153 }
154 return k_ra8_ok;
155}
156
158ra8_npu_dequantize_u8(const uint8_t* in, float* out, size_t count, float scale, int32_t zero_point)
159{
160 RA8_CHECK_NULL_PTR(in, s_tag, "dequantize_u8: in must not be nullptr");
161 RA8_CHECK_NULL_PTR(out, s_tag, "dequantize_u8: out must not be nullptr");
162 for (size_t i = 0U; i < count; i++) {
163 out[i] = scale * (float)((int32_t)in[i] - zero_point);
164 }
165 return k_ra8_ok;
166}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
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).
static const float s_quant_half
The half-step used for half-away-from-zero rounding without libm.
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_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_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).
static const float s_quant_round_cap
Magnitude the pre-cast rounded value is clamped to (float, no libm).
Affine (scale + zero-point) tensor quantization for the NPU runtime.
@ k_ra8_npu_quant_i8_min
INT8 lower saturation bound.
@ k_ra8_npu_quant_u8_max
UINT8 upper saturation bound.
@ k_ra8_npu_quant_i8_max
INT8 upper saturation bound.
@ k_ra8_npu_quant_u8_min
UINT8 lower saturation bound.