- 1. Header Files Overview
- 2. Enumerations
- 3. Data Structures
- 4. Convolution Functions
- 5. Depthwise Convolution Functions
- 6. Transpose Convolution Functions
- 7. Fully Connected Functions
- 8. Element-wise Operations
- 9. Activation Functions
- 10. Pooling Functions
- 11. Softmax Functions
- 12. LSTM Functions
- 13. SVDF Functions
- 14. Batch Matrix Multiplication Functions
- 15. Tensor Operation Functions
- 16. Minimum / Maximum Functions
| Header | Purpose | Usage |
|---|---|---|
riscv_nnfunctions.h |
All public API function declarations | Required when calling any operator |
riscv_nn_types.h |
Struct and enum definitions | Auto-included by riscv_nnfunctions.h |
riscv_nn_math_types.h |
Math types and numerical limits | Auto-included by riscv_nnfunctions.h |
riscv_nnsupportfunctions.h |
Internal support function declarations | Only needed when extending the library or implementing custom operators |
riscv_nn_tables.h |
Pre-computed lookup tables | Only needed when implementing custom Sigmoid/Tanh |
Basic usage requires only one header:
#include "riscv_nnfunctions.h"Function return status codes.
typedef enum {
RISCV_XTSIS_NN_SUCCESS = 0, // Success
RISCV_XTSIS_NN_ARG_ERROR = -1, // Argument error
RISCV_XTSIS_NN_NO_IMPL_ERROR = -2, // No implementation available
RISCV_XTSIS_NN_FAILURE = -3, // Logical error
} riscv_xtsis_nn_status;Activation function type (used for LSTM gating).
typedef enum {
RISCV_SIGMOID = 0, // Sigmoid activation
RISCV_TANH = 1, // Tanh activation
} riscv_nn_activation_type;All structs are defined in riscv_nn_types.h.
2D dimensions (width and height).
typedef struct {
int32_t w; // Width
int32_t h; // Height
} xtsis_nn_tile;Function context, used to pass scratch buffers required by optimizations.
typedef struct {
void *buf; // Pointer to scratch buffer
int32_t size; // Buffer size (in bytes)
} xtsis_nn_context;Usage: Call *_get_buffer_size() to obtain the required size, then the caller allocates and passes it in. When no buffer is needed, set buf=NULL, size=0.
Tensor dimensions, in NHWC layout.
typedef struct {
int32_t n; // Batch size or output channel count (depending on the function)
int32_t h; // Height
int32_t w; // Width
int32_t c; // Input channel count
} xtsis_nn_dims;Quantized ReLU activation clipping range.
typedef struct {
int32_t min; // Lower clipping bound
int32_t max; // Upper clipping bound
} xtsis_nn_activation;Bias data (supports int32 or int64).
typedef struct {
const void *data; // Pointer to bias data
const bool is_int32_bias; // true = int32, false = int64
} xtsis_nn_bias_data;Per-channel quantization parameters.
typedef struct {
int32_t *multiplier; // Per-channel multiplier array
int32_t *shift; // Per-channel shift array
} xtsis_nn_per_channel_quant_params;Per-tensor quantization parameters.
typedef struct {
int32_t multiplier; // Whole-tensor multiplier
int32_t shift; // Whole-tensor shift
} xtsis_nn_per_tensor_quant_params;Generic quantization parameters (supports both per-channel and per-tensor; recommended for new operators).
typedef struct {
int32_t *multiplier; // Multiplier array
int32_t *shift; // Shift array
int32_t is_per_channel; // 0 = per-tensor, 1 = per-channel
} xtsis_nn_quant_params;Quantization scaling parameters.
typedef struct {
int32_t multiplier;
int32_t shift;
} xtsis_nn_scaling;Convolution layer parameters.
typedef struct {
int32_t input_offset; // Negated input zero-point
int32_t output_offset; // Negated output zero-point
xtsis_nn_tile stride; // Stride (w, h)
xtsis_nn_tile padding; // Padding (w, h)
xtsis_nn_tile dilation; // Dilation (w, h)
xtsis_nn_activation activation; // Activation clipping range
} xtsis_nn_conv_params;Offset value ranges:
- s8:
input_offset∈ [-127, 128],output_offset∈ [-128, 127] - s16:
input_offset= 0,output_offset= 0 (symmetric quantization)
Transpose convolution layer parameters.
typedef struct {
int32_t input_offset;
int32_t output_offset;
xtsis_nn_tile stride;
xtsis_nn_tile padding;
xtsis_nn_tile padding_offsets; // Padding offsets
xtsis_nn_tile dilation;
xtsis_nn_activation activation;
} xtsis_nn_transpose_conv_params;Depthwise convolution layer parameters.
typedef struct {
int32_t input_offset;
int32_t output_offset;
int32_t ch_mult; // Channel multiplier: ch_mult * in_ch = out_ch
xtsis_nn_tile stride;
xtsis_nn_tile padding;
xtsis_nn_tile dilation;
xtsis_nn_activation activation;
} xtsis_nn_dw_conv_params;Pooling layer parameters.
typedef struct {
xtsis_nn_tile stride;
xtsis_nn_tile padding;
xtsis_nn_activation activation;
} xtsis_nn_pool_params;Fully connected layer parameters.
typedef struct {
int32_t input_offset;
int32_t filter_offset;
int32_t output_offset;
xtsis_nn_activation activation;
} xtsis_nn_fc_params;Batch matrix multiplication parameters.
typedef struct {
const bool adj_x; // Whether to transpose input X
const bool adj_y; // Whether to transpose input Y
xtsis_nn_fc_params fc_params; // Fully connected layer parameters
} xtsis_nn_bmm_params;SVDF layer parameters.
typedef struct {
int32_t rank;
int32_t input_offset;
int32_t output_offset;
xtsis_nn_activation input_activation;
xtsis_nn_activation output_activation;
} xtsis_nn_svdf_params;Transpose layer parameters.
typedef struct {
const int32_t num_dims; // Number of dimensions
const uint32_t *permutations; // Dimension permutation array
} xtsis_nn_transpose_params;typedef struct {
const int16_t *exp_lut; // Exponential lookup table
const int16_t *one_by_one_lut; // 1/(1+x) lookup table
} xtsis_nn_softmax_lut_s16;typedef struct {
int32_t max_time;
int32_t num_inputs;
int32_t num_batches;
int32_t num_outputs;
} xtsis_nn_lstm_dims;typedef struct {
int32_t input_multiplier;
int32_t input_shift;
const void *input_weights;
const void *input_effective_bias; // bias + pre-computed kernel_sum * lhs_offset
int32_t hidden_multiplier;
int32_t hidden_shift;
const void *hidden_weights;
const void *hidden_effective_bias;
const void *bias;
riscv_nn_activation_type activation_type;
} xtsis_nn_lstm_gate;typedef struct {
int32_t time_major; // 0 = batch first, 1 = time first
int32_t batch_size;
int32_t time_steps;
int32_t input_size;
int32_t hidden_size;
int32_t input_offset;
int32_t forget_to_cell_multiplier;
int32_t forget_to_cell_shift;
int32_t input_to_cell_multiplier;
int32_t input_to_cell_shift;
int32_t cell_clip;
int32_t cell_scale_power;
int32_t output_multiplier;
int32_t output_shift;
int32_t output_offset;
xtsis_nn_lstm_gate forget_gate;
xtsis_nn_lstm_gate input_gate;
xtsis_nn_lstm_gate cell_gate;
xtsis_nn_lstm_gate output_gate;
} xtsis_nn_lstm_params;typedef struct {
void *temp1;
void *temp2;
void *cell_state;
} xtsis_nn_lstm_context;Wrapper functions automatically select the optimal kernel (1x1 fast, 1xN, or generic convolution).
riscv_xtsis_nn_status riscv_convolve_wrapper_s4(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, // [N, H, W, C_IN]
const int8_t *input_data, // int8 activations
const xtsis_nn_dims *filter_dims, // [C_OUT, HK, WK, C_IN]
const int8_t *filter_data, // int4 weights (two int4 packed into one int8)
const xtsis_nn_dims *bias_dims, // [C_OUT]
const int32_t *bias_data,
const xtsis_nn_dims *output_dims, // [N, H, W, C_OUT]
int8_t *output_data);
riscv_xtsis_nn_status riscv_convolve_wrapper_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_convolve_wrapper_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int16_t *input_data, // int16 activations
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data, // int8 weights
const xtsis_nn_dims *bias_dims,
const xtsis_nn_bias_data *bias_data, // int32 or int64 bias
const xtsis_nn_dims *output_dims,
int16_t *output_data);riscv_xtsis_nn_status riscv_convolve_s4(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data, // int4 packed weights
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_convolve_even_s4(
...); // Optimized variant for even input channels; same parameters as riscv_convolve_s4
riscv_xtsis_nn_status riscv_convolve_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *upscale_dims, // Upscale dims (set to 2 to insert zeros along h/w)
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_convolve_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int16_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const xtsis_nn_bias_data *bias_data,
const xtsis_nn_dims *output_dims,
int16_t *output_data);Used when the kernel is 1x1 with stride=1; skips im2col and runs matrix multiplication directly.
riscv_xtsis_nn_status riscv_convolve_1x1_s4_fast(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_convolve_1x1_s4(
...); // Parameters as above
riscv_xtsis_nn_status riscv_convolve_1x1_s8_fast(
...); // Parameters as above (filter_data is int8)
riscv_xtsis_nn_status riscv_convolve_1x1_s8(
...); // Parameters as aboveOptimized implementation for 1D convolution kernels.
riscv_xtsis_nn_status riscv_convolve_1_x_n_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_convolve_1_x_n_s4(
...); // Parameters as above (filter_data is int4 packed)// Basic convolution
int32_t riscv_convolve_s4_get_buffer_size(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);
int32_t riscv_convolve_s8_get_buffer_size(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);
int32_t riscv_convolve_s16_get_buffer_size(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);
// Wrapper (auto kernel selection)
int32_t riscv_convolve_wrapper_s4_get_buffer_size(
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_dims *input_dims,
const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims);
int32_t riscv_convolve_wrapper_s4_get_buffer_size_dsp(...); // DSP variant
int32_t riscv_convolve_wrapper_s8_get_buffer_size(...);
int32_t riscv_convolve_wrapper_s8_get_buffer_size_dsp(...);
int32_t riscv_convolve_wrapper_s16_get_buffer_size(...);
int32_t riscv_convolve_wrapper_s16_get_buffer_size_dsp(...);
// 1x1 fast variant
int32_t riscv_convolve_1x1_s4_fast_get_buffer_size(const xtsis_nn_dims *input_dims);
int32_t riscv_convolve_1x1_s8_fast_get_buffer_size(const xtsis_nn_dims *input_dims);
// 1xN
int32_t riscv_convolve_1_x_n_s8_get_buffer_size(
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_dims *input_dims,
const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims);
int32_t riscv_convolve_1_x_n_s4_get_buffer_size(
const xtsis_nn_conv_params *conv_params,
const xtsis_nn_dims *input_dims,
const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims);riscv_xtsis_nn_status riscv_depthwise_conv_wrapper_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, // [N, H, W, C_IN]
const int8_t *input_data,
const xtsis_nn_dims *filter_dims, // [1, HK, WK, C_OUT]
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, // [C_OUT]
const int32_t *bias_data,
const xtsis_nn_dims *output_dims, // [N, H, W, C_OUT]
int8_t *output_data);
riscv_xtsis_nn_status riscv_depthwise_conv_wrapper_s4(
...); // Parameters as above (filter_data is int4 packed)
riscv_xtsis_nn_status riscv_depthwise_conv_wrapper_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int16_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int64_t *bias_data,
const xtsis_nn_dims *output_dims,
int16_t *output_data);riscv_xtsis_nn_status riscv_depthwise_conv_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, const int8_t *input_data,
const xtsis_nn_dims *filter_dims, const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, const int32_t *bias_data,
const xtsis_nn_dims *output_dims, int8_t *output_data);
riscv_xtsis_nn_status riscv_depthwise_conv_s4(...); // int4 packed weights
riscv_xtsis_nn_status riscv_depthwise_conv_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, const int16_t *input_data,
const xtsis_nn_dims *filter_dims, const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, const int64_t *bias_data,
const xtsis_nn_dims *output_dims, int16_t *output_data);// 3x3 kernel specialized variant
riscv_xtsis_nn_status riscv_depthwise_conv_3x3_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, const int8_t *input_data,
const xtsis_nn_dims *filter_dims, const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, const int32_t *bias_data,
const xtsis_nn_dims *output_dims, int8_t *output_data);
// Optimized for specific depth_multiplier values
riscv_xtsis_nn_status riscv_depthwise_conv_s8_opt(...);
riscv_xtsis_nn_status riscv_depthwise_conv_s4_opt(...);
// Fast int16 variant
riscv_xtsis_nn_status riscv_depthwise_conv_fast_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, const int16_t *input_data,
const xtsis_nn_dims *filter_dims, const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, const int64_t *bias_data,
const xtsis_nn_dims *output_dims, int16_t *output_data);int32_t riscv_depthwise_conv_wrapper_s8_get_buffer_size(
const xtsis_nn_dw_conv_params *dw_conv_params,
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims, const xtsis_nn_dims *output_dims);
int32_t riscv_depthwise_conv_wrapper_s8_get_buffer_size_dsp(...);
int32_t riscv_depthwise_conv_wrapper_s4_get_buffer_size(...);
int32_t riscv_depthwise_conv_wrapper_s4_get_buffer_size_dsp(...);
int32_t riscv_depthwise_conv_wrapper_s16_get_buffer_size(...);
int32_t riscv_depthwise_conv_wrapper_s16_get_buffer_size_dsp(...);
int32_t riscv_depthwise_conv_fast_s16_get_buffer_size(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);
int32_t riscv_depthwise_conv_s8_opt_get_buffer_size(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);
int32_t riscv_depthwise_conv_s4_opt_get_buffer_size(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);// Wrapper (recommended)
riscv_xtsis_nn_status riscv_transpose_conv_wrapper_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_context *output_ctx, // Additional output buffer context
const xtsis_nn_transpose_conv_params *transpose_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, const int8_t *input_data,
const xtsis_nn_dims *filter_dims, const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, const int32_t *bias_data,
const xtsis_nn_dims *output_dims, int8_t *output_data);
// Basic implementation
riscv_xtsis_nn_status riscv_transpose_conv_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_context *output_ctx,
const xtsis_nn_transpose_conv_params *transpose_conv_params,
const xtsis_nn_per_channel_quant_params *quant_params,
const xtsis_nn_dims *input_dims, const int8_t *input_data,
const xtsis_nn_dims *filter_dims, const int8_t *filter_data,
const xtsis_nn_dims *bias_dims, const int32_t *bias_data,
const xtsis_nn_dims *output_dims, int8_t *output_data);
// Buffer size queries
int32_t riscv_transpose_conv_s8_get_buffer_size(
const xtsis_nn_transpose_conv_params *transposed_conv_params,
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims);
int32_t riscv_transpose_conv_s8_get_reverse_conv_buffer_size(
const xtsis_nn_transpose_conv_params *transposed_conv_params,
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims);
int32_t riscv_transpose_conv_s8_get_buffer_size_dsp(
const xtsis_nn_dims *input_dims, const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims);riscv_xtsis_nn_status riscv_fully_connected_s4(
const xtsis_nn_context *ctx,
const xtsis_nn_fc_params *fc_params,
const xtsis_nn_per_tensor_quant_params *quant_params,
const xtsis_nn_dims *input_dims, // [1, 1, 1, C_IN]
const int8_t *input_data,
const xtsis_nn_dims *filter_dims, // [C_OUT, 1, 1, C_IN]
const int8_t *filter_data, // int4 packed weights
const xtsis_nn_dims *bias_dims, // [C_OUT]
const int32_t *bias_data,
const xtsis_nn_dims *output_dims, // [1, 1, 1, C_OUT]
int8_t *output_data);
riscv_xtsis_nn_status riscv_fully_connected_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_fc_params *fc_params,
const xtsis_nn_per_tensor_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_fully_connected_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_fc_params *fc_params,
const xtsis_nn_per_tensor_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int16_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int64_t *bias_data,
const xtsis_nn_dims *output_dims,
int16_t *output_data);riscv_xtsis_nn_status riscv_fully_connected_per_channel_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_fc_params *fc_params,
const xtsis_nn_per_channel_quant_params *quant_params, // Per-channel quantization
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);riscv_xtsis_nn_status riscv_fully_connected_wrapper_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_fc_params *fc_params,
const xtsis_nn_quant_params *quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const int8_t *filter_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);riscv_xtsis_nn_status riscv_vector_sum_s8(
int32_t *vector_sum_buf,
int32_t vector_cols,
int32_t vector_rows,
const int8_t *vector_data,
const int32_t lhs_offset,
const int32_t rhs_offset,
const int32_t *bias_data);
riscv_xtsis_nn_status riscv_vector_sum_s8_s64(
int64_t *vector_sum_buf,
int32_t vector_cols,
int32_t vector_rows,
const int8_t *vector_data,
const int32_t lhs_offset,
const int64_t *bias_data);int32_t riscv_fully_connected_s8_get_buffer_size(const xtsis_nn_dims *filter_dims);
int32_t riscv_fully_connected_s8_get_buffer_size_dsp(const xtsis_nn_dims *filter_dims);
int32_t riscv_fully_connected_s16_get_buffer_size(const xtsis_nn_dims *filter_dims);
int32_t riscv_fully_connected_s16_get_buffer_size_dsp(const xtsis_nn_dims *filter_dims);riscv_xtsis_nn_status riscv_elementwise_add_s8(
const int8_t *input_1_vect,
const int8_t *input_2_vect,
const int32_t input_1_offset,
const int32_t input_1_mult,
const int32_t input_1_shift,
const int32_t input_2_offset,
const int32_t input_2_mult,
const int32_t input_2_shift,
const int32_t left_shift,
int8_t *output,
const int32_t out_offset,
const int32_t out_mult,
const int32_t out_shift,
const int32_t out_activation_min,
const int32_t out_activation_max,
const int32_t block_size);
riscv_xtsis_nn_status riscv_elementwise_add_s16(
const int16_t *input_1_vect,
const int16_t *input_2_vect,
const int32_t input_1_offset,
const int32_t input_1_mult,
const int32_t input_1_shift,
const int32_t input_2_offset,
const int32_t input_2_mult,
const int32_t input_2_shift,
const int32_t left_shift,
int16_t *output,
const int32_t out_offset,
const int32_t out_mult,
const int32_t out_shift,
const int32_t out_activation_min,
const int32_t out_activation_max,
const int32_t block_size);riscv_xtsis_nn_status riscv_elementwise_mul_s8(
const int8_t *input_1_vect,
const int8_t *input_2_vect,
const int32_t input_1_offset,
const int32_t input_2_offset,
int8_t *output,
const int32_t out_offset,
const int32_t out_mult,
const int32_t out_shift,
const int32_t out_activation_min,
const int32_t out_activation_max,
const int32_t block_size);
riscv_xtsis_nn_status riscv_elementwise_mul_s16(
const int16_t *input_1_vect,
const int16_t *input_2_vect,
const int32_t input_1_offset,
const int32_t input_2_offset,
int16_t *output,
const int32_t out_offset,
const int32_t out_mult,
const int32_t out_shift,
const int32_t out_activation_min,
const int32_t out_activation_max,
const int32_t block_size);// ReLU (in-place)
void riscv_relu_q7(int8_t *data, uint16_t size);
void riscv_relu_q15(int16_t *data, uint16_t size);
void riscv_relu6_s8(int8_t *data, uint16_t size);
// Generic activation (Sigmoid / Tanh, lookup-table based)
riscv_xtsis_nn_status riscv_nn_activation_s16(
const int16_t *input,
int16_t *output,
const int32_t size,
const int32_t left_shift,
const riscv_nn_activation_type type); // RISCV_SIGMOID or RISCV_TANHNotes:
riscv_relu_q7()/riscv_relu_q15(): in-place ReLU; sets negative values to zeroriscv_relu6_s8(): in-place ReLU6; clips to the [0, 6] quantized rangeriscv_nn_activation_s16(): implements Sigmoid or Tanh selected by the activation type enum
riscv_xtsis_nn_status riscv_avgpool_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_pool_params *pool_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims, // Pooling window size
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_avgpool_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_pool_params *pool_params,
const xtsis_nn_dims *input_dims,
const int16_t *input_data,
const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims,
int16_t *output_data);
// Buffer size queries
int32_t riscv_avgpool_s8_get_buffer_size(const int dim_dst_width, const int ch_src);
int32_t riscv_avgpool_s8_get_buffer_size_dsp(const int dim_dst_width, const int ch_src);
int32_t riscv_avgpool_s16_get_buffer_size(const int dim_dst_width, const int ch_src);
int32_t riscv_avgpool_s16_get_buffer_size_dsp(const int dim_dst_width, const int ch_src);riscv_xtsis_nn_status riscv_max_pool_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_pool_params *pool_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_max_pool_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_pool_params *pool_params,
const xtsis_nn_dims *input_dims,
const int16_t *input_data,
const xtsis_nn_dims *filter_dims,
const xtsis_nn_dims *output_dims,
int16_t *output_data);Note: Max pooling does not require an additional buffer; ctx.buf may be set to NULL.
// int8 → int8
void riscv_softmax_s8(
const int8_t *input,
const int32_t num_rows,
const int32_t row_size,
const int32_t mult,
const int32_t shift,
const int32_t diff_min,
int8_t *output);
// int8 → int16
void riscv_softmax_s8_s16(
const int8_t *input,
const int32_t num_rows,
const int32_t row_size,
const int32_t mult,
const int32_t shift,
const int32_t diff_min,
int16_t *output);
// int16 → int16 (lookup-table based)
riscv_xtsis_nn_status riscv_softmax_s16(
const int16_t *input,
const int32_t num_rows,
const int32_t row_size,
const int32_t mult,
const int32_t shift,
const xtsis_nn_softmax_lut_s16 *softmax_params,
int16_t *output);
// uint8 → uint8
void riscv_softmax_u8(
const uint8_t *input,
const int32_t num_rows,
const int32_t row_size,
const int32_t mult,
const int32_t shift,
const int32_t diff_min,
uint8_t *output);riscv_xtsis_nn_status riscv_lstm_unidirectional_s8(
const int8_t *input,
int8_t *output,
const xtsis_nn_lstm_params *params,
xtsis_nn_lstm_context *buffers);
riscv_xtsis_nn_status riscv_lstm_unidirectional_s16(
const int16_t *input,
int16_t *output,
const xtsis_nn_lstm_params *params,
xtsis_nn_lstm_context *buffers);Usage notes:
paramsmust fully populate the weights, biases, and quantization parameters of all 4 gates (forget / input / cell / output)buffersare pre-allocated by the caller and contain thetemp1,temp2, andcell_statebuffersparams->time_majorcontrols the input dimension order
riscv_xtsis_nn_status riscv_svdf_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_context *input_ctx,
const xtsis_nn_context *output_ctx,
const xtsis_nn_svdf_params *svdf_params,
const xtsis_nn_per_tensor_quant_params *input_quant_params,
const xtsis_nn_per_tensor_quant_params *output_quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *state_dims,
int8_t *state_data,
const xtsis_nn_dims *weights_feature_dims,
const int8_t *weights_feature_data,
const xtsis_nn_dims *weights_time_dims,
const int8_t *weights_time_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
riscv_xtsis_nn_status riscv_svdf_state_s16_s8(
const xtsis_nn_context *input_ctx,
const xtsis_nn_context *output_ctx,
const xtsis_nn_svdf_params *svdf_params,
const xtsis_nn_per_tensor_quant_params *input_quant_params,
const xtsis_nn_per_tensor_quant_params *output_quant_params,
const xtsis_nn_dims *input_dims,
const int8_t *input_data,
const xtsis_nn_dims *state_dims,
int16_t *state_data,
const xtsis_nn_dims *weights_feature_dims,
const int8_t *weights_feature_data,
const xtsis_nn_dims *weights_time_dims,
const int16_t *weights_time_data,
const xtsis_nn_dims *bias_dims,
const int32_t *bias_data,
const xtsis_nn_dims *output_dims,
int8_t *output_data);
// Buffer size queries
int32_t riscv_svdf_s8_get_buffer_size(const xtsis_nn_dims *filter_dims);
int32_t riscv_svdf_s8_get_buffer_size_dsp(const xtsis_nn_dims *filter_dims);riscv_xtsis_nn_status riscv_batch_matmul_s8(
const xtsis_nn_context *ctx,
const xtsis_nn_bmm_params *bmm_params,
const xtsis_nn_per_tensor_quant_params *quant_params,
const xtsis_nn_dims *input_lhs_dims,
const int8_t *input_lhs,
const xtsis_nn_dims *input_rhs_dims,
const int8_t *input_rhs,
const xtsis_nn_dims *output_dims,
int8_t *output);
riscv_xtsis_nn_status riscv_batch_matmul_s16(
const xtsis_nn_context *ctx,
const xtsis_nn_bmm_params *bmm_params,
const xtsis_nn_per_tensor_quant_params *quant_params,
const xtsis_nn_dims *input_lhs_dims,
const int16_t *input_lhs,
const xtsis_nn_dims *input_rhs_dims,
const int16_t *input_rhs,
const xtsis_nn_dims *output_dims,
int16_t *output);void riscv_reshape_s8(const int8_t *input, int8_t *output, const uint32_t total_size);Note: Pure data copy; the in-memory data order is not changed.
riscv_xtsis_nn_status riscv_transpose_s8(
const int8_t *input_data,
int8_t *output_data,
const xtsis_nn_dims *input_dims,
const xtsis_nn_dims *output_dims,
const xtsis_nn_transpose_params *params); // Dimension permutation parametersriscv_xtsis_nn_status riscv_pad_s8(
const int8_t *input,
int8_t *output,
const int8_t pad_value,
const xtsis_nn_dims *input_size,
const xtsis_nn_dims *pre_pad, // Front-side padding for each dimension
const xtsis_nn_dims *post_pad); // Back-side padding for each dimensionConcatenate tensors along different dimensions:
// Concatenation along the width (W) dimension
void riscv_concatenation_s8_x(
const int8_t *input,
const uint16_t input_x,
const uint16_t input_y,
const uint16_t input_z,
const uint16_t input_w,
int8_t *output,
const uint16_t output_x,
const uint32_t offset_x);
// Concatenation along the height (H) dimension
void riscv_concatenation_s8_y(
const int8_t *input,
const uint16_t input_x,
const uint16_t input_y,
const uint16_t input_z,
const uint16_t input_w,
int8_t *output,
const uint16_t output_y,
const uint32_t offset_y);
// Concatenation along the channel (C) dimension
void riscv_concatenation_s8_z(
const int8_t *input,
const uint16_t input_x,
const uint16_t input_y,
const uint16_t input_z,
const uint16_t input_w,
int8_t *output,
const uint16_t output_z,
const uint32_t offset_z);
// Concatenation along the batch (N) dimension
void riscv_concatenation_s8_w(
const int8_t *input,
const uint16_t input_x,
const uint16_t input_y,
const uint16_t input_z,
const uint16_t input_w,
int8_t *output,
const uint32_t offset_w);riscv_xtsis_nn_status riscv_minimum_s8(
const xtsis_nn_context *ctx,
const int8_t *input_1_data,
const xtsis_nn_dims *input_1_dims,
const int8_t *input_2_data,
const xtsis_nn_dims *input_2_dims,
int8_t *output_data,
const xtsis_nn_dims *output_dims);
riscv_xtsis_nn_status riscv_maximum_s8(
const xtsis_nn_context *ctx,
const int8_t *input_1_data,
const xtsis_nn_dims *input_1_dims,
const int8_t *input_2_data,
const xtsis_nn_dims *input_2_dims,
int8_t *output_data,
const xtsis_nn_dims *output_dims);#include "riscv_nnfunctions.h"
void conv2d_example(void)
{
// 1. Define parameters
xtsis_nn_conv_params conv_params = {
.input_offset = 128, // -zero_point
.output_offset = -128,
.stride = { .w = 1, .h = 1 },
.padding = { .w = 1, .h = 1 },
.dilation = { .w = 1, .h = 1 },
.activation = { .min = -128, .max = 127 },
};
// 2. Define dimensions
xtsis_nn_dims input_dims = { .n = 1, .h = 32, .w = 32, .c = 3 };
xtsis_nn_dims filter_dims = { .n = 16, .h = 3, .w = 3, .c = 3 };
xtsis_nn_dims bias_dims = { .n = 16 };
xtsis_nn_dims output_dims = { .n = 1, .h = 32, .w = 32, .c = 16 };
// 3. Quantization parameters (per-channel)
int32_t multipliers[16] = { /* ... */ };
int32_t shifts[16] = { /* ... */ };
xtsis_nn_per_channel_quant_params quant = {
.multiplier = multipliers, .shift = shifts
};
// 4. Query and allocate the buffer
int32_t buf_size = riscv_convolve_wrapper_s8_get_buffer_size(
&conv_params, &input_dims, &filter_dims, &output_dims);
uint8_t buffer[buf_size];
xtsis_nn_context ctx = { .buf = buffer, .size = buf_size };
// 5. Run inference
riscv_xtsis_nn_status status = riscv_convolve_wrapper_s8(
&ctx, &conv_params, &quant,
&input_dims, input_data,
&filter_dims, filter_data,
&bias_dims, bias_data,
&output_dims, output_data);
if (status != RISCV_XTSIS_NN_SUCCESS) {
// Error handling
}
}// When cross-compiling on a host machine, the compiler cannot detect whether
// the target supports DSP, so use the _dsp-suffixed version to force the
// DSP-path buffer size:
int32_t buf_size = riscv_convolve_wrapper_s8_get_buffer_size_dsp(
&conv_params, &input_dims, &filter_dims, &output_dims);
// When compiling directly on a target RISC-V, simply use the standard
// version; the library auto-selects based on the RISCV_MATH_DSP macro:
int32_t buf_size = riscv_convolve_wrapper_s8_get_buffer_size(
&conv_params, &input_dims, &filter_dims, &output_dims);All public functions listed in alphabetical order:
| Function | Category | Return type |
|---|---|---|
riscv_avgpool_s16 |
Pooling | riscv_xtsis_nn_status |
riscv_avgpool_s16_get_buffer_size |
Pooling | int32_t |
riscv_avgpool_s16_get_buffer_size_dsp |
Pooling | int32_t |
riscv_avgpool_s8 |
Pooling | riscv_xtsis_nn_status |
riscv_avgpool_s8_get_buffer_size |
Pooling | int32_t |
riscv_avgpool_s8_get_buffer_size_dsp |
Pooling | int32_t |
riscv_batch_matmul_s16 |
Batch MatMul | riscv_xtsis_nn_status |
riscv_batch_matmul_s8 |
Batch MatMul | riscv_xtsis_nn_status |
riscv_concatenation_s8_w |
Concatenation | void |
riscv_concatenation_s8_x |
Concatenation | void |
riscv_concatenation_s8_y |
Concatenation | void |
riscv_concatenation_s8_z |
Concatenation | void |
riscv_convolve_1_x_n_s4 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_1_x_n_s4_get_buffer_size |
Convolution | int32_t |
riscv_convolve_1_x_n_s8 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_1_x_n_s8_get_buffer_size |
Convolution | int32_t |
riscv_convolve_1x1_s4 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_1x1_s4_fast |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_1x1_s4_fast_get_buffer_size |
Convolution | int32_t |
riscv_convolve_1x1_s8 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_1x1_s8_fast |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_1x1_s8_fast_get_buffer_size |
Convolution | int32_t |
riscv_convolve_even_s4 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_s16 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_s16_get_buffer_size |
Convolution | int32_t |
riscv_convolve_s4 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_s4_get_buffer_size |
Convolution | int32_t |
riscv_convolve_s8 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_s8_get_buffer_size |
Convolution | int32_t |
riscv_convolve_wrapper_s16 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_wrapper_s16_get_buffer_size |
Convolution | int32_t |
riscv_convolve_wrapper_s16_get_buffer_size_dsp |
Convolution | int32_t |
riscv_convolve_wrapper_s4 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_wrapper_s4_get_buffer_size |
Convolution | int32_t |
riscv_convolve_wrapper_s4_get_buffer_size_dsp |
Convolution | int32_t |
riscv_convolve_wrapper_s8 |
Convolution | riscv_xtsis_nn_status |
riscv_convolve_wrapper_s8_get_buffer_size |
Convolution | int32_t |
riscv_convolve_wrapper_s8_get_buffer_size_dsp |
Convolution | int32_t |
riscv_depthwise_conv_3x3_s8 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_fast_s16 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_fast_s16_get_buffer_size |
Depthwise Conv | int32_t |
riscv_depthwise_conv_s16 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_s4 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_s4_opt |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_s4_opt_get_buffer_size |
Depthwise Conv | int32_t |
riscv_depthwise_conv_s8 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_s8_opt |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_s8_opt_get_buffer_size |
Depthwise Conv | int32_t |
riscv_depthwise_conv_wrapper_s16 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_wrapper_s16_get_buffer_size |
Depthwise Conv | int32_t |
riscv_depthwise_conv_wrapper_s16_get_buffer_size_dsp |
Depthwise Conv | int32_t |
riscv_depthwise_conv_wrapper_s4 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_wrapper_s4_get_buffer_size |
Depthwise Conv | int32_t |
riscv_depthwise_conv_wrapper_s4_get_buffer_size_dsp |
Depthwise Conv | int32_t |
riscv_depthwise_conv_wrapper_s8 |
Depthwise Conv | riscv_xtsis_nn_status |
riscv_depthwise_conv_wrapper_s8_get_buffer_size |
Depthwise Conv | int32_t |
riscv_depthwise_conv_wrapper_s8_get_buffer_size_dsp |
Depthwise Conv | int32_t |
riscv_elementwise_add_s16 |
Element-wise | riscv_xtsis_nn_status |
riscv_elementwise_add_s8 |
Element-wise | riscv_xtsis_nn_status |
riscv_elementwise_mul_s16 |
Element-wise | riscv_xtsis_nn_status |
riscv_elementwise_mul_s8 |
Element-wise | riscv_xtsis_nn_status |
riscv_fully_connected_per_channel_s8 |
Fully Connected | riscv_xtsis_nn_status |
riscv_fully_connected_s16 |
Fully Connected | riscv_xtsis_nn_status |
riscv_fully_connected_s16_get_buffer_size |
Fully Connected | int32_t |
riscv_fully_connected_s16_get_buffer_size_dsp |
Fully Connected | int32_t |
riscv_fully_connected_s4 |
Fully Connected | riscv_xtsis_nn_status |
riscv_fully_connected_s8 |
Fully Connected | riscv_xtsis_nn_status |
riscv_fully_connected_s8_get_buffer_size |
Fully Connected | int32_t |
riscv_fully_connected_s8_get_buffer_size_dsp |
Fully Connected | int32_t |
riscv_fully_connected_wrapper_s8 |
Fully Connected | riscv_xtsis_nn_status |
riscv_lstm_unidirectional_s16 |
LSTM | riscv_xtsis_nn_status |
riscv_lstm_unidirectional_s8 |
LSTM | riscv_xtsis_nn_status |
riscv_max_pool_s16 |
Pooling | riscv_xtsis_nn_status |
riscv_max_pool_s8 |
Pooling | riscv_xtsis_nn_status |
riscv_maximum_s8 |
Maximum | riscv_xtsis_nn_status |
riscv_minimum_s8 |
Minimum | riscv_xtsis_nn_status |
riscv_nn_activation_s16 |
Activation | riscv_xtsis_nn_status |
riscv_pad_s8 |
Padding | riscv_xtsis_nn_status |
riscv_relu6_s8 |
Activation | void |
riscv_relu_q15 |
Activation | void |
riscv_relu_q7 |
Activation | void |
riscv_reshape_s8 |
Reshape | void |
riscv_softmax_s16 |
Softmax | riscv_xtsis_nn_status |
riscv_softmax_s8 |
Softmax | void |
riscv_softmax_s8_s16 |
Softmax | void |
riscv_softmax_u8 |
Softmax | void |
riscv_svdf_s8 |
SVDF | riscv_xtsis_nn_status |
riscv_svdf_s8_get_buffer_size |
SVDF | int32_t |
riscv_svdf_s8_get_buffer_size_dsp |
SVDF | int32_t |
riscv_svdf_state_s16_s8 |
SVDF | riscv_xtsis_nn_status |
riscv_transpose_conv_s8 |
Transpose Conv | riscv_xtsis_nn_status |
riscv_transpose_conv_s8_get_buffer_size |
Transpose Conv | int32_t |
riscv_transpose_conv_s8_get_buffer_size_dsp |
Transpose Conv | int32_t |
riscv_transpose_conv_s8_get_reverse_conv_buffer_size |
Transpose Conv | int32_t |
riscv_transpose_conv_wrapper_s8 |
Transpose Conv | riscv_xtsis_nn_status |
riscv_transpose_s8 |
Transpose | riscv_xtsis_nn_status |
riscv_vector_sum_s8 |
Fully Connected | riscv_xtsis_nn_status |
riscv_vector_sum_s8_s64 |
Fully Connected | riscv_xtsis_nn_status |