IKNN-Rl1-A1 / kernels /noesa24_avx512.cpp
deeprcurs-staff's picture
Upload kernels/noesa24_avx512.cpp with huggingface_hub
20b9ff3 verified
Raw History Blame Contribute Delete
4.96 kB
// noesa24_avx512.cpp — IKNN-Rl1-A1 — NoeSA-24 AVX-512 Kernel
// Version: v1.1 — Fixed __mmask16
// Created: 2026-09-03T17:10:00+07:00
// Last Updated: 2026-09-03T17:15:00+07:00
// Status: PUBLISHABLE — EN ONLY — M1 Kernel Validation
// Repo: IKNN-Rl1-A1 — Integrated Knowledge-phase Neural Network — Recursive Language Iteration 1 — Architecture 1
#include "noesa24_common.h"
#include <cstdint>
#include <immintrin.h>
namespace iknn {
namespace noesa24 {
namespace avx512 {
inline __m512i compute_noesa24_block_avx512(
__m512i activations,
const uint8_t states[16],
int32_t bias_0b = 1)
{
alignas(64) int32_t act_array[16];
_mm512_store_si512(reinterpret_cast<__m512i*>(act_array), activations);
alignas(64) int32_t result[16];
for (int i = 0; i < 16; ++i) {
result[i] = compute_noesa24_single(static_cast<int8_t>(act_array[i]), states[i], bias_0b);
}
return _mm512_load_si512(reinterpret_cast<const __m512i*>(result));
}
inline __m512i compute_noesa24_shift_add_avx512(
__m512i x,
__m512i scale,
__m512i sign,
__m512i zero_mask_0a,
__m512i bias_0b)
{
__m512i prod = _mm512_sllv_epi32(x, scale);
__mmask16 neg_mask = _mm512_cmpeq_epi32_mask(sign, _mm512_set1_epi32(-1));
__m512i neg_prod = _mm512_sub_epi32(_mm512_setzero_si512(), prod);
prod = _mm512_mask_blend_epi32(neg_mask, prod, neg_prod);
prod = _mm512_andnot_si512(zero_mask_0a, prod);
return prod;
}
inline void decode_60bit_avx512(uint64_t packed60, uint8_t out_digits[13]) {
static LUT576 lut[576];
static bool lut_built = false;
if (!lut_built) {
build_lut576(lut);
lut_built = true;
}
unpack_13x24_lut(packed60, out_digits, lut);
}
} // namespace avx512
} // namespace noesa24
} // namespace iknn
#ifdef NOESA24_AVX512_TEST
#include <random>
#include <iostream>
#include <chrono>
int main() {
using namespace iknn::noesa24;
using namespace iknn::noesa24::avx512;
std::cout << "[NoeSA-24 AVX-512 Test] " << __DATE__ << std::endl;
std::cout << "24-state 4.58-bit, 13-unit/60-bit packing 99.3%, shift-add" << std::endl;
std::mt19937 rng(42);
uint8_t digits[13];
for (int i = 0; i < 13; ++i) digits[i] = rng() % 24;
uint64_t packed = pack_13x24(digits);
uint8_t unpacked[13];
unpack_13x24(packed, unpacked);
bool pack_ok = true;
for (int i = 0; i < 13; ++i) if (digits[i] != unpacked[i]) pack_ok = false;
std::cout << "Pack 13x24: " << (pack_ok ? "[PASS]" : "[FAIL]") << " packed=0x" << std::hex << packed << std::dec << std::endl;
LUT576 lut[576];
build_lut576(lut);
uint8_t unpacked_lut[13];
unpack_13x24_lut(packed, unpacked_lut, lut);
bool lut_ok = true;
for (int i = 0; i < 13; ++i) if (digits[i] != unpacked_lut[i]) lut_ok = false;
std::cout << "LUT576 decode: " << (lut_ok ? "[PASS]" : "[FAIL]") << std::endl;
int8_t act = 10;
uint8_t state = encode_state(Operator::POS_A, Scale::S2);
int32_t res = compute_noesa24_single(act, state);
std::cout << "Compute single: act=10 state=+1a S2 (shift2) => " << res << " expected 40 " << (res==40 ? "[PASS]" : "[FAIL]") << std::endl;
state = encode_state(Operator::NEG_B, Scale::S3);
res = compute_noesa24_single(act, state);
std::cout << "Compute single: act=10 state=-1b S3 (shift4) => " << res << " expected -160 " << (res==-160 ? "[PASS]" : "[FAIL]") << std::endl;
state = encode_state(Operator::ZERO_A, Scale::S1);
res = compute_noesa24_single(act, state);
std::cout << "Compute single: act=10 state=0a => " << res << " expected 0 " << (res==0 ? "[PASS]" : "[FAIL]") << std::endl;
state = encode_state(Operator::ZERO_B, Scale::S1);
res = compute_noesa24_single(act, state, 1);
std::cout << "Compute single: act=10 state=0b bias1 => " << res << " expected 1 " << (res==1 ? "[PASS]" : "[FAIL]") << std::endl;
const int ITERS = 1000000;
auto start = std::chrono::high_resolution_clock::now();
uint64_t sum = 0;
for (int it = 0; it < ITERS; ++it) {
uint8_t out[13];
unpack_13x24(packed ^ it, out);
sum += out[0];
}
auto end = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();
std::cout << "[BENCH] Unpack 13x24 scalar: " << ITERS << " iters " << ms << "ms sum " << sum << std::endl;
start = std::chrono::high_resolution_clock::now();
sum = 0;
for (int it = 0; it < ITERS; ++it) {
uint8_t out[13];
unpack_13x24_lut(packed ^ it, out, lut);
sum += out[0];
}
end = std::chrono::high_resolution_clock::now();
ms = std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();
std::cout << "[BENCH] Unpack 13x24 LUT576: " << ITERS << " iters " << ms << "ms sum " << sum << " (target ~12 cycles Ryzen5, ~4 cycles AVX-512 VBMI2)" << std::endl;
return 0;
}
#endif