add missed files

This commit is contained in:
Youmu Liu
2025-08-31 14:34:44 +08:00
parent 6bebe1ca85
commit b650526985
21 changed files with 2031 additions and 0 deletions
+134
View File
@@ -0,0 +1,134 @@
#include "sn_intrinsic.h"
INTERNAL void SN_DECL kernel_add_sse(mat_kernel *left, mat_kernel *right, mat_kernel *ans)
{
register __m128 c0 = _mm_add_ps(left->xmm[0], right->xmm[0]);
register __m128 c1 = _mm_add_ps(left->xmm[1], right->xmm[1]);
register __m128 c2 = _mm_add_ps(left->xmm[2], right->xmm[2]);
register __m128 c3 = _mm_add_ps(left->xmm[3], right->xmm[3]);
ans->xmm[0] = c0;
ans->xmm[1] = c1;
ans->xmm[2] = c2;
ans->xmm[3] = c3;
}
INTERNAL void SN_DECL kernel_add_avx(mat_kernel *left, mat_kernel *right, mat_kernel *ans)
{
register __m256 c0 = _mm256_add_ps(left->ymm[0], right->ymm[0]);
register __m256 c1 = _mm256_add_ps(left->ymm[1], right->ymm[1]);
ans->ymm[0] = c0;
ans->ymm[1] = c1;
}
INTERNAL void SN_DECL kernel_add_512(mat_kernel *left, mat_kernel *right, mat_kernel *ans)
{
register __m512 c0 = _mm512_add_ps(left->zmm[0], right->zmm[0]);
ans->zmm[0] = c0;
}
INTERNAL void SN_DECL kernel_sub_sse(mat_kernel *left, mat_kernel *right, mat_kernel *ans)
{
register __m128 c0 = _mm_sub_ps(left->xmm[0], right->xmm[0]);
register __m128 c1 = _mm_sub_ps(left->xmm[1], right->xmm[1]);
register __m128 c2 = _mm_sub_ps(left->xmm[2], right->xmm[2]);
register __m128 c3 = _mm_sub_ps(left->xmm[3], right->xmm[3]);
ans->xmm[0] = c0;
ans->xmm[1] = c1;
ans->xmm[2] = c2;
ans->xmm[3] = c3;
}
INTERNAL void SN_DECL kernel_sub_avx(mat_kernel *left, mat_kernel *right, mat_kernel *ans)
{
register __m256 c0 = _mm256_sub_ps(left->ymm[0], right->ymm[0]);
register __m256 c1 = _mm256_sub_ps(left->ymm[1], right->ymm[1]);
ans->ymm[0] = c0;
ans->ymm[1] = c1;
}
INTERNAL void SN_DECL kernel_sub_512(mat_kernel *left, mat_kernel *right, mat_kernel *ans)
{
register __m512 c0 = _mm512_sub_ps(left->zmm[0], right->zmm[0]);
ans->zmm[0] = c0;
}
// Matrix transpose implementations
INTERNAL void SN_DECL kernel_transpose_sse(mat_kernel *source, mat_kernel *target)
{
register __m128 col0 = source->xmm[0];
register __m128 col1 = source->xmm[1];
register __m128 col2 = source->xmm[2];
register __m128 col3 = source->xmm[3];
register __m128 tmp0 = _mm_unpacklo_ps(col0, col1);
register __m128 tmp1 = _mm_unpackhi_ps(col0, col1);
register __m128 tmp2 = _mm_unpacklo_ps(col2, col3);
register __m128 tmp3 = _mm_unpackhi_ps(col2, col3);
target->xmm[0] = _mm_movelh_ps(tmp0, tmp2);
target->xmm[1] = _mm_movehl_ps(tmp2, tmp0);
target->xmm[2] = _mm_movelh_ps(tmp1, tmp3);
target->xmm[3] = _mm_movehl_ps(tmp3, tmp1);
}
INTERNAL void SN_DECL kernel_transpose_avx(mat_kernel *source, mat_kernel *target)
{
register __m256 col_low = source->ymm[0];
register __m256 col_high = source->ymm[1];
register __m256 unpack_low = _mm256_unpacklo_ps(col_low, col_high);
register __m256 unpack_high = _mm256_unpackhi_ps(col_low, col_high);
col_low = _mm256_permute2f128_ps(unpack_low, unpack_high, 0x20);
col_high = _mm256_permute2f128_ps(unpack_low, unpack_high, 0x31);
target->ymm[0] = _mm256_shuffle_ps(col_high, col_low, _MM_SHUFFLE(2, 0, 2, 0));
target->ymm[1] = _mm256_shuffle_ps(col_high, col_low, _MM_SHUFFLE(3, 1, 3, 1));
}
INTERNAL void SN_DECL kernel_transpose_512(mat_kernel *source, mat_kernel *target)
{
register __m512 matrix = source->zmm[0];
const __m512i transpose_indices =
_mm512_setr_epi32(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
target->zmm[0] = _mm512_permutexvar_ps(transpose_indices, matrix);
}
INTERNAL void SN_DECL kernel_scalar_mul_sse(mat_kernel *matrix, float scalar, mat_kernel *ans)
{
register __m128 temp = _mm_load_ss(&scalar);
register __m128 scalar_vec = _mm_shuffle_ps(temp, temp, _MM_SHUFFLE(0, 0, 0, 0));
register __m128 c0 = _mm_mul_ps(matrix->xmm[0], scalar_vec);
register __m128 c1 = _mm_mul_ps(matrix->xmm[1], scalar_vec);
register __m128 c2 = _mm_mul_ps(matrix->xmm[2], scalar_vec);
register __m128 c3 = _mm_mul_ps(matrix->xmm[3], scalar_vec);
ans->xmm[0] = c0;
ans->xmm[1] = c1;
ans->xmm[2] = c2;
ans->xmm[3] = c3;
}
INTERNAL void SN_DECL kernel_scalar_mul_avx(mat_kernel *matrix, float scalar, mat_kernel *ans)
{
register __m256 scalar_vec = _mm256_broadcast_ss(&scalar);
register __m256 c0 = _mm256_mul_ps(matrix->ymm[0], scalar_vec);
register __m256 c1 = _mm256_mul_ps(matrix->ymm[1], scalar_vec);
ans->ymm[0] = c0;
ans->ymm[1] = c1;
}
INTERNAL void SN_DECL kernel_scalar_mul_512(mat_kernel *matrix, float scalar, mat_kernel *ans)
{
__m512 scalar_vec = _mm512_broadcastss_ps(_mm_load_ss(&scalar));
register __m512 c0 = _mm512_mul_ps(matrix->zmm[0], scalar_vec);
ans->zmm[0] = c0;
}
+35
View File
@@ -0,0 +1,35 @@
#include "sn_intrinsic.h"
void kernel_fma_sse(mat_kernel *const left, mat_kernel *const right, mat_kernel *ans)
{
register __m128 source0 = _mm_load_ps(&left->xmm[0]);
register __m128 source1 = _mm_load_ps(&left->xmm[1]);
register __m128 source2 = _mm_load_ps(&left->xmm[2]);
register __m128 source3 = _mm_load_ps(&left->xmm[3]);
register __m128 broadcast;
register __m128 ans0 = _mm_setzero_ps();
register __m128 ans1 = _mm_setzero_ps();
register __m128 ans2 = _mm_setzero_ps();
register __m128 ans3 = _mm_setzero_ps();
for (size_t i = 0; i < 3; i++) {
broadcast = _mm_load_ps(&right->xmm[i]);
_mm_add_ps(ans0, _mm_mul_ps(source0, broadcast));
_mm_add_ps(ans1, _mm_mul_ps(source1, broadcast));
_mm_add_ps(ans2, _mm_mul_ps(source2, broadcast));
_mm_add_ps(ans3, _mm_mul_ps(source3, broadcast));
for (size_t t = 0; t < 2; t++) {
broadcast = _mm_shuffle_ps(broadcast, broadcast, _MM_SHUFFLE(2, 1, 0, 3));
_mm_add_ps(ans0, _mm_mul_ps(source0, broadcast));
_mm_add_ps(ans1, _mm_mul_ps(source1, broadcast));
_mm_add_ps(ans2, _mm_mul_ps(source2, broadcast));
_mm_add_ps(ans3, _mm_mul_ps(source3, broadcast));
}
}
_mm_store_ps(&ans->xmm[0], ans0);
_mm_store_ps(&ans->xmm[1], ans1);
_mm_store_ps(&ans->xmm[2], ans2);
_mm_store_ps(&ans->xmm[3], ans3);
}
+101
View File
@@ -0,0 +1,101 @@
#include "StgSharpNative.h"
#include "sn_intrinsic.h"
#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#include <isa_availability.h>
#else
#include <cpuid.h>
#endif // _MSC_VER
PRIVATE void load_intrinsic_sse(sn_intrinsic *context);
PRIVATE void load_intrinsic_avx(sn_intrinsic *context);
PRIVATE void load_intrinsic_512(sn_intrinsic *context);
PRIVATE int check_isa(most_advanced_instruction instruction_family)
{
if (instruction_family != NEON) {
#if defined(_MSC_VER) && !defined(__clang__)
return __check_isa_support(instruction_family, 0);
#else
switch (instruction_family) {
case SSE:
return __builtin_cpu_supports("sse4.2");
case AVX256:
return __builtin_cpu_supports("avx2");
case AVX512:
return __builtin_cpu_supports("avx512f");
default:
return 0;
}
#endif // _MSC_VER
}
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
return 1;
#else
return 0;
#endif
}
SN_API int load_intrinsic_function(void *intrinsic_context)
{
sn_null_assert(intrinsic_context);
sn_intrinsic *context = (sn_intrinsic *)intrinsic_context;
if (check_isa(AVX512)) {
load_intrinsic_512(context);
return 3;
} else if (check_isa(AVX256)) {
load_intrinsic_avx(context);
return 2;
} else if (check_isa(SSE)) {
load_intrinsic_sse(context);
return 1;
} else if (check_isa(NEON)) {
return -1;
}
return 0;
}
void load_intrinsic_sse(sn_intrinsic *context)
{
context->city_hash_simplify = city_hash_simplify_sse;
context->factorial_simd = factorial_simd_sse;
context->index_pair = index_pair_sse;
context->kernel_add = (MATARITHMETIC)kernel_add_sse;
context->kernel_fma = (void(*)(void*, void*, void*))kernel_fma_sse;
context->kernel_scalar_mul = kernel_scalar_mul_sse;
context->kernel_sub = (MATARITHMETIC)kernel_sub_sse;
context->kernel_transpose = (MATTRANSPOSEPROC)kernel_transpose_sse;
context->normalize_3 = normalize;
}
void load_intrinsic_avx(sn_intrinsic *context)
{
context->city_hash_simplify = city_hash_simplify_sse;
context->factorial_simd = factorial_simd_sse;
context->index_pair = index_pair_sse;
context->kernel_add = (MATARITHMETIC)kernel_add_avx;
context->kernel_fma = (void(*)(void*, void*, void*))kernel_fma_sse;
context->kernel_scalar_mul = kernel_scalar_mul_avx;
context->kernel_sub = (MATARITHMETIC)kernel_sub_avx;
context->kernel_transpose = (MATTRANSPOSEPROC)kernel_transpose_avx;
context->normalize_3 = normalize;
}
void load_intrinsic_512(sn_intrinsic *context)
{
context->city_hash_simplify = city_hash_simplify_sse;
context->factorial_simd = factorial_simd_sse;
context->index_pair = index_pair_sse;
context->kernel_add = (MATARITHMETIC)kernel_add_512;
context->kernel_fma = (void(*)(void*, void*, void*))kernel_fma_sse;
context->kernel_scalar_mul = kernel_scalar_mul_512;
context->kernel_sub = (MATARITHMETIC)kernel_sub_512;
context->kernel_transpose = (MATTRANSPOSEPROC)kernel_transpose_512;
context->normalize_3 = normalize;
}
+75
View File
@@ -0,0 +1,75 @@
#include "StgSharpNative.h"
#include "gl.h"
#include "../glfw/glfw3.h"
#include <stdio.h>
#include <string.h>
extern GladGLContext *currentContext;
extern char infolog[512];
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
char **logRef)
{
int stat = 0;
context->GetShaderiv(shaderHandle, key, &stat);
if (!stat) {
context->GetShaderInfoLog(shaderHandle, 512, NULL, infolog);
}
*logRef = infolog;
return stat;
}
SN_API void SN_DECL initGL(int majorVersion, int minorVersion)
{
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
}
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName)
{
void *ret = glfwGetProcAddress(procName);
// printf("%llu\n", (uint64_t)ret);
if (ret == NULL) {
strcpy_s(infolog,30, "Failed to load OpenGL api:");
for (size_t i = 0; i < sizeof(procName); i++) {
infolog[30 + i] = procName[i];
}
//printf("%s\n", infolog);
}
return (GLFWglproc)ret;
}
SN_API unsigned int linkShaderProgram(GladGLContext *context, GLuint shaderProgram)
{
context->LinkProgram(shaderProgram);
int success;
context->GetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
context->GetProgramInfoLog(shaderProgram, 512, NULL, infolog);
return 0;
} else {
return shaderProgram;
}
}
SN_API void SN_DECL loadImageData(char *location, Image *out, imageLoader loader)
{
if (loader == NULL) {
loader = stbi_load;
}
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
}
SN_API void SN_DECL unloadImageData(Image *out)
{
free(out->pixelPtr);
}
SN_API char *SN_DECL readLog()
{
infolog[511] = '\0';
return infolog;
}
+23
View File
@@ -0,0 +1,23 @@
#include "sn_internal.h"
#include "sn_intrinsic.h"
INTERNAL __m128i facIncrement = { 4, 4, 4, 4 };
INTERNAL __m128i facBase = { 1, 2, 3, 4 };
INTERNAL uint64_t SN_DECL factorial_simd_sse(int n)
{
__m128i baseResult = facBase;
__m128i facBaseLocal = facBase;
const int cycle = (n - 3) >> 2;
const uint32_t rest = (cycle << 2) + 1;
for (size_t i = 0; i < cycle; i++) {
facBaseLocal = _mm_add_epi32(facBaseLocal, facIncrement);
baseResult = _mm_mullo_epi32(baseResult, facBaseLocal);
}
uint64_t result = (uint64_t)baseResult.m128i_i32[0] * (uint64_t)baseResult.m128i_i32[1] *
(uint64_t)baseResult.m128i_i32[2] * (uint64_t)baseResult.m128i_i32[3];
for (uint64_t i = rest; i < n; i++) {
result *= i;
}
return result;
}
+45
View File
@@ -0,0 +1,45 @@
#include "sn_intrinsic.h"
#include "StgSharpNative.h"
INTERNAL int SN_DECL city_hash_simplify_sse(byte const *str, int const length)
{
uint32_t hash = length, size = length << 1;
byte *end = str + size, *ptr = str;
if (size < 4) {
for (; ptr < end; ptr += 2) {
hash = _mm_crc32_u16(hash, *ptr);
}
} else if (size < 16) {
byte *last = end - 4;
for (; ptr < end; ptr += 4) {
hash = _mm_crc32_u32(hash, *(uint32_t *)ptr);
}
for (; ptr < end; ptr++) {
hash = _mm_crc32_u16(hash, *ptr);
}
} else {
byte *last_128 = end - 16;
byte *last_32 = end - 4;
uint64_t hash64 = size;
for (; ptr < last_128; ptr += 16) {
__m128i vec = _mm_loadu_si32((int *)ptr);
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 0));
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 1));
}
hash = _mm_crc32_u8(hash, hash64);
hash = _mm_crc32_u8(hash, hash64 >> 32);
for (; ptr < last_32; ptr += 4) {
hash = _mm_crc32_u32(hash,*(uint32_t *)ptr);
}
for (; ptr < end; ptr += 2) {
hash = _mm_crc32_u8(hash,*ptr);
}
}
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
return hash;
}
+53
View File
@@ -0,0 +1,53 @@
#include "sn_intrinsic.h"
int index_pair_sse(short const *str, uint32_t target, int length)
{
int index = 0, result = 0, size = length, end = size - 8;
__m128i s = {
target,
target,
target,
target,
};
__m128i vec, com;
while (index < end) {
vec = _mm_loadu_epi32(str + index);
com = _mm_cmpeq_epi16(vec, s);
result = _mm_movemask_epi8(com);
if (result) {
for (size_t i = 0; i < 7; i++) {
if (((result & 0xF) == 0xF)) {
return index + i;
}
if (result == 0) {
break;
}
result >>= 2;
}
}
index += 1;
vec = _mm_loadu_epi32(str + index);
com = _mm_cmpeq_epi16(vec, s);
result = _mm_movemask_epi8(com);
if (result) {
for (size_t i = 0; i < 7; i++) {
if (((result & 0xF) == 0xF)) {
return index + i;
}
if (result == 0) {
break;
}
result >>= 2;
}
}
index += 7;
}
for (; (index < size - 1) && (!result); index += 2) {
result = *(int *)(str + index) == target;
}
if (result) {
return index;
}
return -1;
}