/*
Copyright (c) 2025-2025 Huawei Technologies Co., Ltd.

sysHAX-adapter is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
    http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
PURPOSE.
See the Mulan PSL v2 for more details.
Created: 2026-1-31
Desc: CPU inference quantization q4_0
*/

#ifndef QUANTIZATION_Q4_0_H
#define QUANTIZATION_Q4_0_H

#include "quantization_base.h"

namespace cpu_inference {

#define QK4_0 32
typedef struct {
    float16_t d;            // delta
    uint8_t qs[QK4_0 / 2];
} block_q4_0;

template <>
class QuantizationBase<block_q4_0> {
public:
    QuantizationBase() = default;
    ~QuantizationBase() {}
    static void quantize(
        const void* const src_data, block_q4_0* dst_data, size_t element_cnt, std::string ori_dtype);
    static void dequantize(
        const block_q4_0* const src_data, void* dst_data, size_t element_cnt, std::string aim_dtype);

    static const int elem_cnt_in_block = QK4_0;
    static const int block_byte_size = sizeof(block_q4_0);
private:
    static void quantize_from_fp16(const float16_t* const src_data, block_q4_0* dst_data, size_t element_cnt);
    static void dequantize_to_fp16(const block_q4_0* const src_data, float16_t* dst_data, size_t element_cnt);

    static void quantize_from_fp16_neon(const float16_t* const src_data, block_q4_0* dst_data, size_t element_cnt);
    static void quantize_from_fp16_default(const float16_t* const src_data, block_q4_0* dst_data, size_t element_cnt);
};
};  // namespace cpu_inference

#endif