Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/gen/neon_aarch64_microkernels.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SET(PROD_NEON_AARCH64_MICROKERNEL_SRCS
src/f32-vsqrt/gen/f32-vsqrt-aarch64-neon-sqrt.c
src/x8-lut/gen/x8-lut-aarch64-neon-tbx128x4-u64.c
src/x8-packq/x8-packq-aarch64-neon-f32qp8-u2.c
src/x8-packq/x8-packq-aarch64-neon-f16qp8-u2.c
src/x24-transposec/x24-transposec-4x4-aarch64-neon-tbl128.c
src/x32-transposec/x32-transposec-4x4-aarch64-neon-tbl128.c)

Expand Down
2 changes: 2 additions & 0 deletions cmake/gen/neonsme2_microkernels.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ SET(PROD_NEONSME2_MICROKERNEL_SRCS
src/qp8-f32-qc4w-gemm/qp8-f32-qc4w-gemm-minmax-16x64c4-neonsme2.c
src/qp8-f32-qc8w-gemm/qp8-f32-qc8w-gemm-minmax-1x64c4-neonsme2.c
src/qp8-f32-qc8w-gemm/qp8-f32-qc8w-gemm-minmax-16x64c4-neonsme2.c
src/qp8-f16-qc8w-gemm/qp8-f16-qc8w-gemm-minmax-1x64c4-neonsme2.c
src/qp8-f16-qc8w-gemm/qp8-f16-qc8w-gemm-minmax-16x64c4-neonsme2.c
src/x8-pack-lh/x8-packlh-igemm-neonsme2.c
src/x8-pack-lh/x8-packlh-neonsme2.c
src/x16-pack-lh/x16-packlh-igemm-neonsme2.c
Expand Down
1 change: 1 addition & 0 deletions gen/neon_aarch64_microkernels.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ PROD_NEON_AARCH64_MICROKERNEL_SRCS = [
"src/f32-vsqrt/gen/f32-vsqrt-aarch64-neon-sqrt.c",
"src/x8-lut/gen/x8-lut-aarch64-neon-tbx128x4-u64.c",
"src/x8-packq/x8-packq-aarch64-neon-f32qp8-u2.c",
"src/x8-packq/x8-packq-aarch64-neon-f16qp8-u2.c",
"src/x24-transposec/x24-transposec-4x4-aarch64-neon-tbl128.c",
"src/x32-transposec/x32-transposec-4x4-aarch64-neon-tbl128.c",
]
Expand Down
2 changes: 2 additions & 0 deletions gen/neonsme2_microkernels.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ PROD_NEONSME2_MICROKERNEL_SRCS = [
"src/qp8-f32-qc4w-gemm/qp8-f32-qc4w-gemm-minmax-16x64c4-neonsme2.c",
"src/qp8-f32-qc8w-gemm/qp8-f32-qc8w-gemm-minmax-1x64c4-neonsme2.c",
"src/qp8-f32-qc8w-gemm/qp8-f32-qc8w-gemm-minmax-16x64c4-neonsme2.c",
"src/qp8-f16-qc8w-gemm/qp8-f16-qc8w-gemm-minmax-1x64c4-neonsme2.c",
"src/qp8-f16-qc8w-gemm/qp8-f16-qc8w-gemm-minmax-16x64c4-neonsme2.c",
"src/x8-pack-lh/x8-packlh-igemm-neonsme2.c",
"src/x8-pack-lh/x8-packlh-neonsme2.c",
"src/x16-pack-lh/x16-packlh-igemm-neonsme2.c",
Expand Down
51 changes: 51 additions & 0 deletions src/configs/gemm-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ static struct xnn_gemm_config qdu8_f32_qc2w_gemm_config = {0};
static struct xnn_gemm_config qd8_f32_qc8w_gemm_config = {0};
static struct xnn_gemm_config qp8_f32_qc4w_gemm_config = {0};
static struct xnn_gemm_config qp8_f32_qc8w_gemm_config = {0};
static struct xnn_gemm_config qp8_f16_qc8w_gemm_config = {0};
static struct xnn_gemm_config qp8_f32_qb4w_gemm_config = {0};
static struct xnn_gemm_config qdu8_f32_qc4w_gemm_config = {0};
static struct xnn_gemm_config qdu8_f16_qc8w_gemm_config = {0};
Expand Down Expand Up @@ -94,6 +95,7 @@ XNN_INIT_ONCE_GUARD(qdu8_f32_qc2w_gemm);
XNN_INIT_ONCE_GUARD(qd8_f32_qc8w_gemm);
XNN_INIT_ONCE_GUARD(qp8_f32_qc4w_gemm);
XNN_INIT_ONCE_GUARD(qp8_f32_qc8w_gemm);
XNN_INIT_ONCE_GUARD(qp8_f16_qc8w_gemm);
XNN_INIT_ONCE_GUARD(qp8_f32_qb4w_gemm);
XNN_INIT_ONCE_GUARD(qdu8_f32_qc4w_gemm);
XNN_INIT_ONCE_GUARD(qdu8_f16_qc8w_gemm);
Expand Down Expand Up @@ -3007,6 +3009,44 @@ static void init_qp8_f32_qc8w_gemm_config(void) {
#endif // XNN_ARCH_ARM64 && XNN_ENABLE_KLEIDIAI
}

static void init_qp8_f16_qc8w_gemm_config(void) {
qp8_f16_qc8w_gemm_config.log2_input_element_size = XNN_LOG2_SIZEOF_INT8_T;
qp8_f16_qc8w_gemm_config.log2_filter_element_size = XNN_LOG2_SIZEOF_UINT8_T;
qp8_f16_qc8w_gemm_config.log2_filter_element_bit_size =
XNN_LOG2_SIZEOF_UINT8_T + 3;
qp8_f16_qc8w_gemm_config.bias_element_size = sizeof(float);

#if XNN_ARCH_ARM64 && XNN_ENABLE_KLEIDIAI
const struct xnn_hardware_config* hardware_config =
xnn_init_hardware_config();
assert(hardware_config != NULL);
if (XNN_ENABLE_ARM_SME2 && (hardware_config->arch_flags & xnn_arch_arm_sme2)) {
#if XNN_ENABLE_ARM_SME2
const size_t mr =
xnn_qp8_f16_qc8w_gemm_minmax_ukernel_16x64c4__neonsme2_get_mr();
const size_t nr =
xnn_qp8_f16_qc8w_gemm_minmax_ukernel_16x64c4__neonsme2_get_nr();
qp8_f16_qc8w_gemm_config.minmax.qp8gemm[XNN_MR_TO_INDEX(1)] =
XNN_INIT_HMP_QP8GEMM_UKERNEL(
xnn_qp8_f16_qc8w_gemm_minmax_ukernel_1x64c4__neonsme2);
qp8_f16_qc8w_gemm_config.minmax.qp8gemm[XNN_MR_TO_INDEX(mr)] =
XNN_INIT_HMP_QP8GEMM_UKERNEL(
xnn_qp8_f16_qc8w_gemm_minmax_ukernel_16x64c4__neonsme2);
qp8_f16_qc8w_gemm_config.init.f16 = xnn_init_f16_minmax_scalar_params;
qp8_f16_qc8w_gemm_config.pack_weights_and_biases =
xnn_pack_kai_qs8_weights_and_biases;
qp8_f16_qc8w_gemm_config.packed_stride_weights_and_biases =
xnn_packed_stride_kai_qs8_weights_and_biases;
qp8_f16_qc8w_gemm_config.mr = mr;
qp8_f16_qc8w_gemm_config.nr = nr;
qp8_f16_qc8w_gemm_config.log2_kr = 2;
qp8_f16_qc8w_gemm_config.mr_packed = mr;
assert(qp8_f16_qc8w_gemm_config.mr <= XNN_MAX_MR);
#endif // XNN_ENABLE_ARM_SME2
}
#endif // XNN_ARCH_ARM64 && XNN_ENABLE_KLEIDIAI
}

static void init_qp8_f32_qb4w_gemm_config(void) {
// Common parameters.
qp8_f32_qb4w_gemm_config.log2_input_element_size = XNN_LOG2_SIZEOF_INT8_T;
Expand Down Expand Up @@ -6595,6 +6635,17 @@ const struct xnn_gemm_config* xnn_init_qp8_f32_qc8w_gemm_config() {
return NULL;
}

const struct xnn_gemm_config* xnn_init_qp8_f16_qc8w_gemm_config() {
if (xnn_init_hardware_config() == NULL) {
return NULL;
}
XNN_INIT_ONCE(qp8_f16_qc8w_gemm);
if (qp8_f16_qc8w_gemm_config.minmax.qp8gemm[0].function[0] != NULL) {
return &qp8_f16_qc8w_gemm_config;
}
return NULL;
}

const struct xnn_gemm_config* xnn_init_qp8_f32_qb4w_gemm_config() {
const struct xnn_hardware_config* hardware_config =
xnn_init_hardware_config();
Expand Down
28 changes: 28 additions & 0 deletions src/configs/pack-lh-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "src/xnnpack/packq.h"

static struct xnn_pack_lh_config qp8_pack_lh_config = {0};
static struct xnn_pack_lh_config qp8_f16_pack_lh_config = {0};
static struct xnn_pack_lh_config x8_pack_lh_config = {0};
static struct xnn_pack_lh_config x16_pack_lh_config = {0};
static struct xnn_pack_lh_config x32_pack_lh_config = {0};
Expand All @@ -24,6 +25,7 @@ static struct xnn_pack_lh_config x32_igemm_pack_lh_config = {0};
static struct xnn_pack_lh_config x16_igemm_pack_lh_config = {0};

XNN_INIT_ONCE_GUARD(qp8_pack_lh);
XNN_INIT_ONCE_GUARD(qp8_f16_pack_lh);
XNN_INIT_ONCE_GUARD(x8_pack_lh);
XNN_INIT_ONCE_GUARD(x16_pack_lh);
XNN_INIT_ONCE_GUARD(x32_pack_lh);
Expand Down Expand Up @@ -57,6 +59,32 @@ const struct xnn_pack_lh_config* xnn_init_qp8_pack_lh_config() {
return &qp8_pack_lh_config;
}

static void init_qp8_f16_pack_lh_config(void) {
#if XNN_ARCH_ARM64 && XNN_ENABLE_KLEIDIAI
qp8_f16_pack_lh_config.pack_lh_fn =
(xnn_pack_lh_ukernel_fn)xnn_x8_packq_f16qp8_ukernel__aarch64_neon_u2;
qp8_f16_pack_lh_config.size_fn =
(xnn_pack_lh_size_fn)xnn_x8_packq_f32qp8_packed_size;
qp8_f16_pack_lh_config.offset_fn =
(xnn_pack_lh_offset_fn)xnn_x8_packq_f32qp8_packed_offset;
qp8_f16_pack_lh_config.log2_input_element_size = XNN_LOG2_SIZEOF_FLOAT16;
qp8_f16_pack_lh_config.log2_packed_element_size = 0;
#endif // XNN_ARCH_ARM64 && XNN_ENABLE_KLEIDIAI
}

const struct xnn_pack_lh_config* xnn_init_qp8_f16_pack_lh_config() {
const struct xnn_hardware_config* hardware_config =
xnn_init_hardware_config();
if (hardware_config == NULL) {
return NULL;
}
XNN_INIT_ONCE(qp8_f16_pack_lh);
if (qp8_f16_pack_lh_config.pack_lh_fn == NULL) {
return NULL;
}
return &qp8_f16_pack_lh_config;
}

static void init_x32_pack_lh_config(void) {
#if XNN_ARCH_ARM64 && XNN_ENABLE_KLEIDIAI
const struct xnn_hardware_config* hardware_config =
Expand Down
6 changes: 4 additions & 2 deletions src/operator-run.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ XNN_NO_SANITIZE_FUNCTION void xnn_compute_hmp_grouped_qp8gemm(struct gemm_contex
context->qp8_ukernel.function[uarch_index](
mr_step, nr_block_size, k_scaled, (const void*)(a + a_offset),
packed_w, (void*)(c + mr_block_start * cm_stride), cm_stride,
/*dst_stride_col=*/sizeof(float), context->fused_params);
// QP8 kernels can produce f16 or f32 outputs, so use the configured output element size.
/*dst_stride_col=*/1 << context->log2_csize, context->fused_params);
}
mr_block_size -= mr_step;
mr_block_start += mr_step;
Expand Down Expand Up @@ -597,7 +598,8 @@ XNN_INLINE static XNN_NO_SANITIZE_FUNCTION void compute_hmp_qp8gemm(
mr_step, nr_block_size, k_scaled,
(const void*)((uintptr_t)a + a_offset), packed_w,
(void*)((uintptr_t)c + mr_block_start * cm_stride), cm_stride,
/*dst_stride_col=*/sizeof(float), context->fused_params);
// QP8 kernels can produce f16 or f32 outputs, so use the configured output element size.
/*dst_stride_col=*/1 << context->log2_csize, context->fused_params);
}

mr_block_size -= mr_step;
Expand Down
1 change: 1 addition & 0 deletions src/operators/fingerprint_id.h.inc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ XNN_FINGERPRINT_ID(fully_connected_nc, qd8, f32, qc4w)
XNN_FINGERPRINT_ID(fully_connected_nc, qdu8, f32, qc4w)
XNN_FINGERPRINT_ID(fully_connected_nc, qp8, f32, qc4w)
XNN_FINGERPRINT_ID(fully_connected_nc, qp8, f32, qc8w)
XNN_FINGERPRINT_ID(fully_connected_nc, qp8, f16, qc8w)
XNN_FINGERPRINT_ID(fully_connected_nc, qp8, f32, qb4w)
XNN_FINGERPRINT_ID(fully_connected_nc, qd8, f32, qb4w)
XNN_FINGERPRINT_ID(fully_connected_nc, qdu8, f32, qb4w)
Expand Down
69 changes: 69 additions & 0 deletions src/operators/fully-connected-nc.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static enum xnn_operator_type get_operator_type(
XNNPACK_FINGERPRINT_TO_OP_TYPE(qdu8, f32, qc4w);
XNNPACK_FINGERPRINT_TO_OP_TYPE(qp8, f32, qc4w);
XNNPACK_FINGERPRINT_TO_OP_TYPE(qp8, f32, qc8w);
XNNPACK_FINGERPRINT_TO_OP_TYPE(qp8, f16, qc8w);
XNNPACK_FINGERPRINT_TO_OP_TYPE(qp8, f32, qb4w);
XNNPACK_FINGERPRINT_TO_OP_TYPE(qd8, f32, qb4w);
XNNPACK_FINGERPRINT_TO_OP_TYPE(qdu8, f32, qb4w);
Expand Down Expand Up @@ -1157,6 +1158,21 @@ static const struct fc_variant qp8_f32_qc8w_variant = {
.kernel_scale_element_size = sizeof(float),
};

static const struct fc_variant qp8_f16_qc8w_variant = {
.check_output_bounds = check_output_bounds_f32,
.check_kernel_zero_point = UNUSED,
.check_block_size = UNUSED,
.check_flags = UNUSED,
.setup_gemm_ukernels = setup_gemm_ukernels,
.setup_params = setup_params_f16,
.setup_packing_params = setup_packing_params_qs8_qc8w,
.setup_packing_functions = setup_packing_functions_from_gemm_config,
.setup_scale_params = setup_scale_params_qs8_qc8w,
.fingerprint_constraints = {},
.extra_weights_bytes = sizeof(float) * 2,
.kernel_scale_element_size = sizeof(float),
};

static const struct fc_variant qd8_f16_qb4w_variant = {
.check_output_bounds = check_output_bounds_f32,
.check_kernel_zero_point = check_kernel_zero_point_is_0_or_8_qu8,
Expand Down Expand Up @@ -1482,6 +1498,11 @@ static enum xnn_status setup_variant_and_gemm_config(
context->gemm_config = xnn_init_qp8_f32_qc8w_gemm_config();
context->fingerprint_id = xnn_fingerprint_id_fully_connected_nc_qp8_f32_qc8w;
break;
case xnn_operator_type_fully_connected_nc_qp8_f16_qc8w:
*variant = &qp8_f16_qc8w_variant;
context->gemm_config = xnn_init_qp8_f16_qc8w_gemm_config();
context->fingerprint_id = xnn_fingerprint_id_fully_connected_nc_qp8_f16_qc8w;
break;
case xnn_operator_type_fully_connected_nc_qp8_f32_qb4w:
*variant = &qp8_f32_qb4w_variant;
context->gemm_config = xnn_init_qp8_f32_qb4w_gemm_config();
Expand Down Expand Up @@ -2143,6 +2164,30 @@ enum xnn_status xnn_create_fully_connected_nc_qp8_f32_qc8w(
return create_fully_connected_nc_helper(&context);
}

enum xnn_status xnn_create_fully_connected_nc_qp8_f16_qc8w(
size_t input_channels, size_t output_channels, size_t input_stride,
size_t output_stride, const float* kernel_scale, const void* kernel,
const float* bias, float output_min, float output_max, uint32_t flags,
xnn_weights_cache_t weights_cache, xnn_operator_t* fully_connected_op_out) {
struct fc_context context = {
.input_channels = input_channels,
.output_channels = output_channels,
.input_stride = input_stride,
.output_stride = output_stride,
.kernel_scale.f32 = kernel_scale,
.kernel = kernel,
.bias = bias,
.output_min = output_min,
.output_max = output_max,
.flags = flags,
.weights_cache = weights_cache,
.operator_type = xnn_operator_type_fully_connected_nc_qp8_f16_qc8w,
.fully_connected_op_out = fully_connected_op_out,
.should_fingerprint = true,
};
return create_fully_connected_nc_helper(&context);
}

enum xnn_status xnn_create_fully_connected_nc_qp8_f32_qb4w(
size_t input_channels, size_t output_channels, size_t input_stride,
size_t output_stride, size_t block_size, uint8_t kernel_zero_point,
Expand Down Expand Up @@ -2909,6 +2954,9 @@ static XNN_NO_SANITIZE_FUNCTION enum xnn_status reshape_fully_connected_nc(
case xnn_operator_type_fully_connected_nc_qp8_f32_qc8w:
packed_lh_config = xnn_init_qp8_pack_lh_config();
break;
case xnn_operator_type_fully_connected_nc_qp8_f16_qc8w:
packed_lh_config = xnn_init_qp8_f16_pack_lh_config();
break;
case xnn_operator_type_fully_connected_nc_pf16:
packed_lh_config = xnn_init_x16_pack_lh_config();
break;
Expand Down Expand Up @@ -3463,6 +3511,19 @@ enum xnn_status xnn_reshape_fully_connected_nc_qp8_f32_qc8w(
threadpool);
}

enum xnn_status xnn_reshape_fully_connected_nc_qp8_f16_qc8w(
xnn_operator_t fully_connected_op, size_t batch_size,
size_t* workspace_size, pthreadpool_t threadpool) {
return reshape_fully_connected_nc(
fully_connected_op, xnn_operator_type_fully_connected_nc_qp8_f16_qc8w,
batch_size,
/*dynamic_quantization=*/false,
/*log2_output_element_size=*/XNN_LOG2_SIZEOF_FLOAT16,
&fully_connected_op->params.f16_minmax,
sizeof(fully_connected_op->params.f16_minmax), workspace_size,
threadpool);
}

enum xnn_status xnn_reshape_fully_connected_nc_qp8_f32_qb4w(
xnn_operator_t fully_connected_op, size_t batch_size,
size_t* workspace_size, pthreadpool_t threadpool) {
Expand Down Expand Up @@ -3812,6 +3873,14 @@ enum xnn_status xnn_setup_fully_connected_nc_qp8_f32_qc8w(
input, output, workspace, /*row_sum=*/NULL, /*quantization_params=*/NULL);
}

enum xnn_status xnn_setup_fully_connected_nc_qp8_f16_qc8w(
xnn_operator_t fully_connected_op, const int8_t* input, float* output,
void* workspace) {
return setup_fully_connected_nc(
fully_connected_op, xnn_operator_type_fully_connected_nc_qp8_f16_qc8w,
input, output, workspace, /*row_sum=*/NULL, /*quantization_params=*/NULL);
}

enum xnn_status xnn_setup_fully_connected_nc_qp8_f32_qb4w(
xnn_operator_t fully_connected_op, const int8_t* input, float* output,
void* workspace) {
Expand Down
45 changes: 45 additions & 0 deletions src/qp8-f16-qc8w-gemm/qp8-f16-qc8w-gemm-minmax-16x64c4-neonsme2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2026 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#include <assert.h>
#include <stddef.h>
#include <stdint.h>

#include "src/xnnpack/math.h"
#include "src/xnnpack/microparams.h"

#if XNN_ENABLE_KLEIDIAI
#include "kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi8cxp/kai_matmul_clamp_f16_qai8dxp1vlx4_qsi8cxp4vlx4_1vlx4vl_sme2_mopa.h"

size_t xnn_qp8_f16_qc8w_gemm_minmax_ukernel_16x64c4__neonsme2_get_mr() {
return
kai_get_mr_matmul_clamp_f16_qai8dxp1vlx4_qsi8cxp4vlx4_1vlx4vl_sme2_mopa();
}

size_t xnn_qp8_f16_qc8w_gemm_minmax_ukernel_16x64c4__neonsme2_get_nr() {
return
kai_get_nr_matmul_clamp_f16_qai8dxp1vlx4_qsi8cxp4vlx4_1vlx4vl_sme2_mopa();
}
#endif // XNN_ENABLE_KLEIDIAI

// Wraps the
// `kai_matmul_clamp_f16_qai8dxp1vlx4_qsi8cxp4vlx4_1vlx4vl_sme2_mopa` GEMM
// microkernel with a name that is compatible with our tooling.
void xnn_qp8_f16_qc8w_gemm_minmax_ukernel_16x64c4__neonsme2(
size_t m, size_t n, size_t k, const void* lhs_packed,
const void* rhs_packed, float* dst, size_t dst_stride_row,
size_t dst_stride_col, struct xnn_f32_minmax_params* minmax_params) {
#if XNN_ENABLE_KLEIDIAI
const struct xnn_f16_minmax_params* f16_minmax_params =
(const struct xnn_f16_minmax_params*) minmax_params;
kai_run_matmul_clamp_f16_qai8dxp1vlx4_qsi8cxp4vlx4_1vlx4vl_sme2_mopa(
m, n, k, lhs_packed, rhs_packed, dst, dst_stride_row, dst_stride_col,
xnn_float16_to_float(f16_minmax_params->scalar.min),
xnn_float16_to_float(f16_minmax_params->scalar.max));
#else
assert("Calling KleidiAI microkernel wrapper, but XNNPACK was compiled without "
"`XNN_ENABLE_KLEIDIAI`." && 0);
#endif // XNN_ENABLE_KLEIDIAI
}
44 changes: 44 additions & 0 deletions src/qp8-f16-qc8w-gemm/qp8-f16-qc8w-gemm-minmax-1x64c4-neonsme2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2026 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#include <assert.h>
#include <stddef.h>
#include <stdint.h>

#include "src/xnnpack/math.h"
#include "src/xnnpack/microparams.h"

#if XNN_ENABLE_KLEIDIAI
#include "kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi8cxp/kai_matmul_clamp_f16_qai8dxp1x4_qsi8cxp4vlx4_1x4vl_sme2_dot.h"

size_t xnn_qp8_f16_qc8w_gemm_minmax_ukernel_1x64c4__neonsme2_get_mr() {
return
kai_get_mr_matmul_clamp_f16_qai8dxp1x4_qsi8cxp4vlx4_1x4vl_sme2_dot();
}

size_t xnn_qp8_f16_qc8w_gemm_minmax_ukernel_1x64c4__neonsme2_get_nr() {
return
kai_get_nr_matmul_clamp_f16_qai8dxp1x4_qsi8cxp4vlx4_1x4vl_sme2_dot();
}
#endif // XNN_ENABLE_KLEIDIAI

// Wraps the `kai_matmul_clamp_f16_qai8dxp1x4_qsi8cxp4vlx4_1x4vl_sme2_dot`
// GEMM microkernel with a name that is compatible with our tooling.
void xnn_qp8_f16_qc8w_gemm_minmax_ukernel_1x64c4__neonsme2(
size_t m, size_t n, size_t k, const void* lhs_packed,
const void* rhs_packed, float* dst, size_t dst_stride_row,
size_t dst_stride_col, struct xnn_f32_minmax_params* minmax_params) {
#if XNN_ENABLE_KLEIDIAI
const struct xnn_f16_minmax_params* f16_minmax_params =
(const struct xnn_f16_minmax_params*) minmax_params;
kai_run_matmul_clamp_f16_qai8dxp1x4_qsi8cxp4vlx4_1x4vl_sme2_dot(
m, n, k, lhs_packed, rhs_packed, dst, dst_stride_row, dst_stride_col,
xnn_float16_to_float(f16_minmax_params->scalar.min),
xnn_float16_to_float(f16_minmax_params->scalar.max));
#else
assert("Calling KleidiAI microkernel wrapper, but XNNPACK was compiled without "
"`XNN_ENABLE_KLEIDIAI`." && 0);
#endif // XNN_ENABLE_KLEIDIAI
}
Loading