mat queue find solution, native supports clang
This commit is contained in:
+102
-26
@@ -1,36 +1,112 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(StgSharp.Native C)
|
||||
project(StgSharp.Native LANGUAGES C)
|
||||
|
||||
# Include helper for external libraries if present
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/ExternalLibs.cmake OPTIONAL)
|
||||
|
||||
# Add main source directory
|
||||
# Follow naming convention: prefer sn-src/sn-head (StgSharp native naming).
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sn-src)
|
||||
add_subdirectory(sn-src)
|
||||
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
add_subdirectory(src)
|
||||
set(SN_TARGET_OS "auto" CACHE STRING "Target OS identifier: auto, windows, linux, macos, ios, android, unknown")
|
||||
set_property(CACHE SN_TARGET_OS PROPERTY STRINGS auto windows linux macos ios android unknown)
|
||||
|
||||
set(SN_TARGET_ARCH "auto" CACHE STRING "Target ISA identifier: auto, x86_64, arm64, riscv64, ppc64le")
|
||||
set_property(CACHE SN_TARGET_ARCH PROPERTY STRINGS auto x86_64 arm64 riscv64 ppc64le)
|
||||
|
||||
sn_resolve_target_identifiers(
|
||||
"${SN_TARGET_OS}"
|
||||
"${SN_TARGET_ARCH}"
|
||||
SN_RESOLVED_OS_NAME
|
||||
SN_RESOLVED_OS_DEFINE
|
||||
SN_RESOLVED_ARCH_NAME
|
||||
SN_RESOLVED_ARCH_DEFINE)
|
||||
|
||||
file(GLOB STGSHARP_NATIVE_SOURCES CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_LIST_DIR}/sn-src/*.c)
|
||||
|
||||
list(REMOVE_ITEM STGSHARP_NATIVE_SOURCES
|
||||
${CMAKE_CURRENT_LIST_DIR}/sn-src/formatted.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/sn-src/StgSharpC.c)
|
||||
|
||||
if(NOT STGSHARP_NATIVE_SOURCES)
|
||||
message(FATAL_ERROR "No source files found under sn-src/.")
|
||||
endif()
|
||||
|
||||
get_filename_component(STGSHARP_SOLUTION_ROOT ${CMAKE_CURRENT_LIST_DIR} DIRECTORY)
|
||||
|
||||
if(SN_RESOLVED_OS_NAME STREQUAL "windows")
|
||||
set(STGSHARP_OS_TAG win)
|
||||
elseif(SN_RESOLVED_OS_NAME STREQUAL "linux")
|
||||
set(STGSHARP_OS_TAG linux)
|
||||
elseif(SN_RESOLVED_OS_NAME STREQUAL "macos")
|
||||
set(STGSHARP_OS_TAG osx)
|
||||
elseif(SN_RESOLVED_OS_NAME STREQUAL "ios")
|
||||
set(STGSHARP_OS_TAG ios)
|
||||
elseif(SN_RESOLVED_OS_NAME STREQUAL "android")
|
||||
set(STGSHARP_OS_TAG android)
|
||||
else()
|
||||
message(STATUS "No sn-src/ or src/ directory in StgSharp.Native; create one to add sources.")
|
||||
set(STGSHARP_OS_TAG unknown)
|
||||
endif()
|
||||
|
||||
# Register include directories according to naming convention: sn-head preferred
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sn-head)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/sn-head)
|
||||
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
if(SN_RESOLVED_ARCH_NAME STREQUAL "x86_64")
|
||||
set(STGSHARP_ARCH_TAG x64)
|
||||
else()
|
||||
set(STGSHARP_ARCH_TAG ${SN_RESOLVED_ARCH_NAME})
|
||||
endif()
|
||||
|
||||
# Discover external libraries laid out under external/<libname> (each with head/ and lib/)
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/external)
|
||||
file(GLOB EXTERNAL_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/external/*)
|
||||
foreach(_d ${EXTERNAL_DIRS})
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/${_d}")
|
||||
if(COMMAND use_external_lib)
|
||||
use_external_lib(${_d} "${CMAKE_CURRENT_SOURCE_DIR}/external/${_d}")
|
||||
else()
|
||||
message(STATUS "External lib '${_d}' found at external/${_d} (no use_external_lib defined).")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(STGSHARP_BUILD_OUTPUT_DIR ${STGSHARP_SOLUTION_ROOT}/build/${STGSHARP_OS_TAG}-${STGSHARP_ARCH_TAG})
|
||||
set(STGSHARP_OBJECT_ROOT_DIR ${STGSHARP_SOLUTION_ROOT}/obj/${PROJECT_NAME})
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED ${STGSHARP_NATIVE_SOURCES})
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
C_STANDARD 11
|
||||
C_STANDARD_REQUIRED ON
|
||||
RUNTIME_OUTPUT_DIRECTORY ${STGSHARP_BUILD_OUTPUT_DIR}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${STGSHARP_BUILD_OUTPUT_DIR}
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${STGSHARP_BUILD_OUTPUT_DIR})
|
||||
|
||||
foreach(_config Debug Release RelWithDebInfo MinSizeRel)
|
||||
string(TOUPPER ${_config} _config_upper)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_${_config_upper} ${STGSHARP_BUILD_OUTPUT_DIR}
|
||||
LIBRARY_OUTPUT_DIRECTORY_${_config_upper} ${STGSHARP_BUILD_OUTPUT_DIR}
|
||||
ARCHIVE_OUTPUT_DIRECTORY_${_config_upper} ${STGSHARP_BUILD_OUTPUT_DIR}
|
||||
PDB_OUTPUT_DIRECTORY_${_config_upper} ${STGSHARP_BUILD_OUTPUT_DIR}
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY_${_config_upper} ${STGSHARP_OBJECT_ROOT_DIR}/${_config}/${STGSHARP_ARCH_TAG})
|
||||
endforeach()
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY ${STGSHARP_OBJECT_ROOT_DIR}/$<CONFIG>/${STGSHARP_ARCH_TAG})
|
||||
|
||||
if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
/Fd${STGSHARP_OBJECT_ROOT_DIR}/$<CONFIG>/${STGSHARP_ARCH_TAG}/)
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND SN_RESOLVED_ARCH_NAME STREQUAL "x86_64")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
/clang:-mavx
|
||||
/clang:-mavx2
|
||||
/clang:-mfma
|
||||
/clang:-mavx512f
|
||||
/clang:-mavx512vl)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/sn-head
|
||||
${CMAKE_CURRENT_LIST_DIR}/lib)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
SN_EXTERN_TARGET
|
||||
SN_OS_TARGET=${SN_RESOLVED_OS_DEFINE}
|
||||
SN_ARCH_TARGET=${SN_RESOLVED_ARCH_DEFINE})
|
||||
|
||||
set(STGSHARP_NATIVE_EXTERNAL_TARGET ${PROJECT_NAME})
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/lib)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE opengl32)
|
||||
endif()
|
||||
|
||||
message(STATUS "StgSharp.Native target OS: ${SN_RESOLVED_OS_NAME} (${SN_RESOLVED_OS_DEFINE})")
|
||||
message(STATUS "StgSharp.Native target ISA: ${SN_RESOLVED_ARCH_NAME} (${SN_RESOLVED_ARCH_DEFINE})")
|
||||
message(STATUS "StgSharp.Native output dir: ${STGSHARP_BUILD_OUTPUT_DIR}")
|
||||
|
||||
@@ -1,30 +1,103 @@
|
||||
# Helper for external libs layout: external/<libname>/{head,lib}
|
||||
# Provides function `use_external_lib(<name> <path>)` that sets include directories
|
||||
# and attempts to link static/shared libs found under lib/.
|
||||
function(sn_normalize_os_identifier INPUT_VALUE OUTPUT_NAME OUTPUT_DEFINE)
|
||||
string(TOLOWER "${INPUT_VALUE}" _sn_os)
|
||||
|
||||
function(use_external_lib NAME PATH)
|
||||
# Expect headers in ${PATH}/head and libs in ${PATH}/lib
|
||||
set(HEAD_DIR "${PATH}/head")
|
||||
set(LIB_DIR "${PATH}/lib")
|
||||
|
||||
if(EXISTS "${HEAD_DIR}")
|
||||
message(STATUS "Registering external include: ${HEAD_DIR}")
|
||||
include_directories(${HEAD_DIR})
|
||||
if(_sn_os STREQUAL "auto")
|
||||
string(TOLOWER "${CMAKE_SYSTEM_NAME}" _sn_system_name)
|
||||
if(_sn_system_name STREQUAL "windows")
|
||||
set(_sn_os "windows")
|
||||
elseif(_sn_system_name STREQUAL "linux")
|
||||
set(_sn_os "linux")
|
||||
elseif(_sn_system_name STREQUAL "darwin" OR _sn_system_name STREQUAL "macos")
|
||||
set(_sn_os "macos")
|
||||
elseif(_sn_system_name STREQUAL "ios")
|
||||
set(_sn_os "ios")
|
||||
elseif(_sn_system_name STREQUAL "android")
|
||||
set(_sn_os "android")
|
||||
else()
|
||||
message(WARNING "External lib ${NAME} missing head/ directory at ${HEAD_DIR}")
|
||||
set(_sn_os "unknown")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(EXISTS "${LIB_DIR}")
|
||||
# try to find static/shared libs inside LIB_DIR
|
||||
file(GLOB LIB_FILES RELATIVE ${LIB_DIR} ${LIB_DIR}/*)
|
||||
foreach(_lib ${LIB_FILES})
|
||||
if(_lib MATCHES ".*\\.(a|lib|so|dylib)$")
|
||||
message(STATUS "Found library for ${NAME}: ${LIB_DIR}/${_lib}")
|
||||
# Consumer targets should link explicitly; provide variable for convenience
|
||||
set(EXTERNAL_LIB_${NAME} "${LIB_DIR}/${_lib}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
if(_sn_os STREQUAL "windows")
|
||||
set(_sn_define SN_OS_WINDOWS)
|
||||
elseif(_sn_os STREQUAL "linux")
|
||||
set(_sn_define SN_OS_LINUX)
|
||||
elseif(_sn_os STREQUAL "macos")
|
||||
set(_sn_define SN_OS_MACOS)
|
||||
elseif(_sn_os STREQUAL "ios")
|
||||
set(_sn_define SN_OS_IOS)
|
||||
elseif(_sn_os STREQUAL "android")
|
||||
set(_sn_define SN_OS_ANDROID)
|
||||
elseif(_sn_os STREQUAL "unknown")
|
||||
set(_sn_define SN_OS_UNKNOWN)
|
||||
else()
|
||||
message(STATUS "No lib/ directory for external lib ${NAME} at ${LIB_DIR}")
|
||||
message(FATAL_ERROR "Unsupported SN_TARGET_OS='${INPUT_VALUE}'.")
|
||||
endif()
|
||||
|
||||
set(${OUTPUT_NAME} "${_sn_os}" PARENT_SCOPE)
|
||||
set(${OUTPUT_DEFINE} "${_sn_define}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(sn_normalize_arch_identifier INPUT_VALUE OUTPUT_NAME OUTPUT_DEFINE)
|
||||
string(TOLOWER "${INPUT_VALUE}" _sn_arch)
|
||||
|
||||
if(_sn_arch STREQUAL "auto")
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _sn_processor)
|
||||
if(_sn_processor MATCHES "^(amd64|x86_64|x64)$")
|
||||
set(_sn_arch "x86_64")
|
||||
elseif(_sn_processor MATCHES "^(arm64|aarch64)$")
|
||||
set(_sn_arch "arm64")
|
||||
elseif(_sn_processor STREQUAL "riscv64")
|
||||
set(_sn_arch "riscv64")
|
||||
elseif(_sn_processor MATCHES "^(ppc64le|powerpc64le)$")
|
||||
set(_sn_arch "ppc64le")
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to infer ISA from CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}'. Set SN_TARGET_ARCH explicitly.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(_sn_arch STREQUAL "x86_64")
|
||||
set(_sn_define SN_ARCH_X86_64)
|
||||
elseif(_sn_arch STREQUAL "arm64")
|
||||
set(_sn_define SN_ARCH_ARM64)
|
||||
elseif(_sn_arch STREQUAL "riscv64")
|
||||
set(_sn_define SN_ARCH_RISCV64)
|
||||
elseif(_sn_arch STREQUAL "ppc64le")
|
||||
set(_sn_define SN_ARCH_PPC64le)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported SN_TARGET_ARCH='${INPUT_VALUE}'.")
|
||||
endif()
|
||||
|
||||
set(${OUTPUT_NAME} "${_sn_arch}" PARENT_SCOPE)
|
||||
set(${OUTPUT_DEFINE} "${_sn_define}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(sn_resolve_target_identifiers INPUT_OS INPUT_ARCH OUTPUT_OS_NAME OUTPUT_OS_DEFINE OUTPUT_ARCH_NAME OUTPUT_ARCH_DEFINE)
|
||||
sn_normalize_os_identifier("${INPUT_OS}" _sn_os_name _sn_os_define)
|
||||
sn_normalize_arch_identifier("${INPUT_ARCH}" _sn_arch_name _sn_arch_define)
|
||||
|
||||
set(${OUTPUT_OS_NAME} "${_sn_os_name}" PARENT_SCOPE)
|
||||
set(${OUTPUT_OS_DEFINE} "${_sn_os_define}" PARENT_SCOPE)
|
||||
set(${OUTPUT_ARCH_NAME} "${_sn_arch_name}" PARENT_SCOPE)
|
||||
set(${OUTPUT_ARCH_DEFINE} "${_sn_arch_define}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(sn_register_external_package TARGET PACKAGE_NAME PACKAGE_DIR)
|
||||
if(NOT TARGET ${TARGET})
|
||||
message(FATAL_ERROR "sn_register_external_package: target '${TARGET}' does not exist.")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${PACKAGE_DIR}")
|
||||
target_include_directories(${TARGET} PRIVATE "${PACKAGE_DIR}")
|
||||
message(STATUS "Registered external package '${PACKAGE_NAME}' include: ${PACKAGE_DIR}")
|
||||
else()
|
||||
message(FATAL_ERROR "External package directory not found: ${PACKAGE_DIR}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(sn_link_external_binary_if_exists TARGET LIBRARY_PATH)
|
||||
if(EXISTS "${LIBRARY_PATH}")
|
||||
target_link_libraries(${TARGET} PRIVATE "${LIBRARY_PATH}")
|
||||
message(STATUS "Linked external binary: ${LIBRARY_PATH}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -55,7 +55,7 @@ typedef struct Image {
|
||||
typedef char *(*imageLoader)(char const *filename, int *x, int *y, int *channels_in_file,
|
||||
int desired_channels);
|
||||
|
||||
SN_API char infolog[512];
|
||||
extern SN_API char infolog[512];
|
||||
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef);
|
||||
SN_API void SN_DECL initGL(int majorVersion, int minorVersion);
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
#pragma region matix function
|
||||
|
||||
INTERNAL void f32_normalize(VEC(float) * source, VEC(float) * target);
|
||||
INTERNAL void f32_normalize(sn_vec_f32 * source, sn_vec_f32 * target);
|
||||
|
||||
SN_MK_PROC_DECL_STD(float, sse, , add);
|
||||
SN_MK_PROC_DECL_STD(float, avx, , add);
|
||||
|
||||
@@ -47,36 +47,35 @@ typedef union scalar_pack {
|
||||
uint64_t data[8];
|
||||
} scalar_pack;
|
||||
|
||||
/* Mirrors StgSharp.Mathematics.Numeric.MatrixParallelTaskPackage<T> (128 bytes). */
|
||||
#define MAT_TASK(T) \
|
||||
struct { \
|
||||
MAT_KERNEL(T) * mat_0; /* Offset 0: 1st matrix kernel base */ \
|
||||
MAT_KERNEL(T) * mat_1; /* Offset 8: 2nd matrix kernel base */ \
|
||||
MAT_KERNEL(T) * mat_2; /* Offset 16: 3rd matrix kernel base */ \
|
||||
void *scalar; /* Offset 24: scalar pack */ \
|
||||
int32_t x; /* Offset 32: row index of the result tile */ \
|
||||
int32_t y; /* Offset 36: column index of the result tile */ \
|
||||
int32_t z; /* Offset 40: column index of the result tile */ \
|
||||
int32_t common_x; /* Offset 44: row index of the result tile */ \
|
||||
int32_t common_y; /* Offset 48: column index of the result tile */ \
|
||||
int32_t common_z; /* Offset 52: column index of the result tile */ \
|
||||
uint32_t mask; /* Offset 56: mask for task schedualing, not useful in C side */ \
|
||||
uint32_t reverse; /* Offset 60: reserved for future use */ \
|
||||
scalar_pack padding; /* Offset 64: padding to make the struct size 128 bytes */ \
|
||||
}
|
||||
typedef struct matrix_task matrix_task;
|
||||
typedef struct matrix_task {
|
||||
void *mat_0;
|
||||
void *mat_1;
|
||||
void *mat_2;
|
||||
void *scalar;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
int32_t common_x;
|
||||
int32_t common_y;
|
||||
int32_t common_z;
|
||||
uint32_t mask;
|
||||
uint32_t reverse;
|
||||
scalar_pack padding;
|
||||
} matrix_task;
|
||||
|
||||
#define MAT_TASK(T) matrix_task
|
||||
|
||||
#if defined(__cplusplus)
|
||||
static_assert(sizeof(matrix_task) == 128, "matrix_parallel_task_package size mismatch");
|
||||
#elif defined(__STDC_VERSION__)
|
||||
static_assert(sizeof(MAT_TASK(float)) == 128, "matrix_parallel_task_package size mismatch");
|
||||
static_assert(sizeof(matrix_task) == 128, "matrix_parallel_task_package size mismatch");
|
||||
#endif
|
||||
|
||||
typedef void(SN_DECL *UNI_MK_PROC)(matrix_task *task);
|
||||
typedef void(SN_DECL *UNI_SK_PROC)(mat_kernel const *left, mat_kernel const *right,
|
||||
mat_kernel *restrict ans, uint64_t scalar);
|
||||
|
||||
typedef void(SN_DECL *VECTORNORMALIZEPROC)(__m128 *source, __m128 *target);
|
||||
typedef void(SN_DECL *VECTORNORMALIZEPROC)(sn_vec_f32 *source, sn_vec_f32 *target);
|
||||
typedef void(SN_DECL *DOTPROC)(void *transpose, __m128 *vector, __m128 *ans);
|
||||
typedef uint64_t(SN_DECL *FACTORIALROC)(int n);
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
#define YMMCOUNT(T) (sizeof(T) / 2)
|
||||
#define ZMMCOUNT(T) (sizeof(T) / 4)
|
||||
|
||||
#define MAT_KERNEL(T) \
|
||||
union /* MAT_KERNEL_##T## /**/ { \
|
||||
#define SN_DEFINE_MAT_KERNEL_TYPE(name, T) \
|
||||
typedef union name { \
|
||||
__m128 f32_x[XMMCOUNT(T)]; \
|
||||
__m256 f32_y[YMMCOUNT(T)]; \
|
||||
__m512 f32_z[ZMMCOUNT(T)]; \
|
||||
@@ -22,7 +22,18 @@
|
||||
__m256d f64_y[YMMCOUNT(T)]; \
|
||||
__m512d f64_z[ZMMCOUNT(T)]; \
|
||||
T m[4][4]; \
|
||||
}
|
||||
} name
|
||||
|
||||
SN_DEFINE_MAT_KERNEL_TYPE(sn_mat_kernel_float, float);
|
||||
SN_DEFINE_MAT_KERNEL_TYPE(sn_mat_kernel_double, double);
|
||||
SN_DEFINE_MAT_KERNEL_TYPE(sn_mat_kernel_uint64_t, uint64_t);
|
||||
|
||||
#define SN_MAT_KERNEL_TYPE(T) SN_MAT_KERNEL_TYPE_##T
|
||||
#define SN_MAT_KERNEL_TYPE_float sn_mat_kernel_float
|
||||
#define SN_MAT_KERNEL_TYPE_double sn_mat_kernel_double
|
||||
#define SN_MAT_KERNEL_TYPE_uint64_t sn_mat_kernel_uint64_t
|
||||
|
||||
#define MAT_KERNEL(T) SN_MAT_KERNEL_TYPE(T)
|
||||
|
||||
#define VEC(T) \
|
||||
union { \
|
||||
@@ -36,8 +47,10 @@
|
||||
T v[4]; \
|
||||
}
|
||||
|
||||
typedef VEC(float) sn_vec_f32;
|
||||
|
||||
/* Provide a named alias for the zero kernel type to ensure consistent linkage in C++. */
|
||||
typedef MAT_KERNEL(uint64_t) sn_zero_kernel_u64;
|
||||
typedef sn_mat_kernel_uint64_t sn_zero_kernel_u64;
|
||||
|
||||
/* Helpers (all compile-time): */
|
||||
#define SN_LANES(T_VEC, T) (sizeof(T_VEC) / sizeof(T))
|
||||
|
||||
@@ -8,16 +8,18 @@
|
||||
#define static_assert _Static_assert
|
||||
#endif
|
||||
|
||||
#define mat_task_local ((_mat_task_local const *)task)
|
||||
|
||||
#define MK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op) \
|
||||
T_type##_multi_kernel_proc_##T_op##_##T_arch##_##T_feature
|
||||
#define GET_MK_PROC_STD(T_type, T_arch, T_feature, T_op) \
|
||||
((UNI_MK_PROC)MK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op))
|
||||
#define SN_MK_PROC_DECL(T_type, P_name) INTERNAL void SN_DECL P_name(MAT_TASK(T_type) const *task)
|
||||
#define SN_MK_PROC_DECL_STD(T_type, T_arch, T_feature, T_op) \
|
||||
INTERNAL FORCEINLINE void SN_DECL MK_PROC_NAME_STD(T_type, T_arch, T_feature, \
|
||||
T_op)(MAT_TASK(T_type) const *task)
|
||||
#define SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op) \
|
||||
T_type##_single_kernel_proc_##T_op##_##T_arch##_##T_feature
|
||||
#define GET_SK_PROC_STD(T_type, T_arch, T_feature, T_op) \
|
||||
((UNI_SK_PROC)SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op))
|
||||
#define SN_SK_PROC_DECL_STD(T_type, T_arch, T_feature, T_op) \
|
||||
INTERNAL FORCEINLINE void SN_DECL SK_PROC_NAME_STD(T_type, T_arch, T_feature, T_op)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
@@ -37,28 +39,28 @@
|
||||
#define _SN_MATPROC_ANS_SCALAR 1
|
||||
|
||||
#define _SN_MK_EXPAND_RIGHT_ANS \
|
||||
SN_MAT_KERNEL_LOCAL const *right = mat_task_local->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = mat_task_local->mat_2;
|
||||
SN_MAT_KERNEL_LOCAL const *right = (SN_MAT_KERNEL_LOCAL const *)task->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = (SN_MAT_KERNEL_LOCAL *)task->mat_2;
|
||||
|
||||
#define _SN_MK_EXPAND_LEFT_RIGHT_ANS \
|
||||
SN_MAT_KERNEL_LOCAL const *left = mat_task_local->mat_0; \
|
||||
SN_MAT_KERNEL_LOCAL const *right = mat_task_local->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = mat_task_local->mat_2;
|
||||
SN_MAT_KERNEL_LOCAL const *left = (SN_MAT_KERNEL_LOCAL const *)task->mat_0; \
|
||||
SN_MAT_KERNEL_LOCAL const *right = (SN_MAT_KERNEL_LOCAL const *)task->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = (SN_MAT_KERNEL_LOCAL *)task->mat_2;
|
||||
|
||||
#define _SN_MK_EXPAND_RIGHT_ANS_SCALAR \
|
||||
SN_MAT_KERNEL_LOCAL const *right = mat_task_local->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = mat_task_local->mat_2; \
|
||||
scalar_pack *restrict scalar = mat_task_local->scalar;
|
||||
SN_MAT_KERNEL_LOCAL const *right = (SN_MAT_KERNEL_LOCAL const *)task->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = (SN_MAT_KERNEL_LOCAL *)task->mat_2; \
|
||||
scalar_pack *restrict scalar = (scalar_pack *restrict)task->scalar;
|
||||
|
||||
#define _SN_MK_EXPAND_LEFT_RIGHT_ANS_SCALAR \
|
||||
SN_MAT_KERNEL_LOCAL const *left = mat_task_local->mat_0; \
|
||||
SN_MAT_KERNEL_LOCAL const *right = mat_task_local->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = mat_task_local->mat_2; \
|
||||
scalar_pack *restrict scalar = mat_task_local->scalar;
|
||||
SN_MAT_KERNEL_LOCAL const *left = (SN_MAT_KERNEL_LOCAL const *)task->mat_0; \
|
||||
SN_MAT_KERNEL_LOCAL const *right = (SN_MAT_KERNEL_LOCAL const *)task->mat_1; \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = (SN_MAT_KERNEL_LOCAL *)task->mat_2; \
|
||||
scalar_pack *restrict scalar = (scalar_pack *restrict)task->scalar;
|
||||
|
||||
#define _SN_MK_EXPAND_ANS_SCALAR \
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = mat_task_local->mat_2; \
|
||||
scalar_pack *restrict scalar = &(mat_task_local->padding);
|
||||
SN_MAT_KERNEL_LOCAL *restrict ans = (SN_MAT_KERNEL_LOCAL *)task->mat_2; \
|
||||
scalar_pack *restrict scalar = (scalar_pack *restrict)&(task->padding);
|
||||
|
||||
#define _SN_PARAM_STYLE(T) _SN_MATPROC_##T
|
||||
#define _SN_MK_EXPAND_PARAM(style) _SN_MK_EXPAND_##style
|
||||
@@ -95,8 +97,7 @@
|
||||
|
||||
#define __mk_param_std(mem, param, T) \
|
||||
typedef MAT_KERNEL(T) SN_MAT_KERNEL_LOCAL; \
|
||||
typedef MAT_TASK(T) _mat_task_local; \
|
||||
_mat_task_local *_ = (_SN_PARAM_STYLE(param), (_SN_MEM_LAYOUT(mem)), task); \
|
||||
matrix_task const *_ = (_SN_PARAM_STYLE(param), (_SN_MEM_LAYOUT(mem)), task); \
|
||||
_SN_MK_EXPAND_PARAM(param); \
|
||||
_SN_MK_EXPAND_MEM(mem)
|
||||
#endif // !SN_INTRINSIC_PARAM_EXPAND
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#include "StgSharpC.h"
|
||||
#include "gl.h"
|
||||
#include "glfw3.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern GladGLContext *currentContext;
|
||||
extern char infolog[512];
|
||||
|
||||
SSCAPI int SSCDECL 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;
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL 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);
|
||||
}
|
||||
|
||||
SSCAPI GLFWglproc SSCDECL loadGlfuncDefault(char const *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;
|
||||
}
|
||||
|
||||
SSCAPI 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;
|
||||
}
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL loadImageData(char const *location, Image *out, imageLoader loader)
|
||||
{
|
||||
if (loader == NULL) {
|
||||
loader = stbi_load;
|
||||
}
|
||||
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL unloadImageData(Image *restrict out)
|
||||
{
|
||||
free(out->pixelPtr);
|
||||
}
|
||||
|
||||
SSCAPI char *SSCDECL readLog()
|
||||
{
|
||||
infolog[511] = '\0';
|
||||
return infolog;
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
#include "sn_target.h"
|
||||
#include "sn_intrinsic.h"
|
||||
#include "StgSharpNative.h"
|
||||
|
||||
static SIMDID global_simdid = { 0 };
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.context.x86.h"
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <string.h>
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
static void get_cpuid(int leaf, int subleaf, int *eax, int *ebx, int *ecx, int *edx)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
int regs[4];
|
||||
__cpuidex(regs, leaf, subleaf);
|
||||
*eax = regs[0];
|
||||
*ebx = regs[1];
|
||||
*ecx = regs[2];
|
||||
*edx = regs[3];
|
||||
#else
|
||||
unsigned int a, b, c, d;
|
||||
__cpuid_count((unsigned int)leaf, (unsigned int)subleaf, a, b, c, d);
|
||||
*eax = (int)a;
|
||||
*ebx = (int)b;
|
||||
*ecx = (int)c;
|
||||
*edx = (int)d;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int xgetbv_has_xmm_ymm(void)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned __int64 xcr0 = _xgetbv(0);
|
||||
#else
|
||||
unsigned long long xcr0 = __builtin_ia32_xgetbv(0);
|
||||
#endif
|
||||
return ((xcr0 & 0x6) == 0x6);
|
||||
}
|
||||
|
||||
static int xgetbv_has_avx512_state(void)
|
||||
{
|
||||
const unsigned long long mask = (1ull << 0) | (1ull << 1) | (1ull << 2) | (1ull << 5) |
|
||||
(1ull << 6);
|
||||
#if defined(_MSC_VER)
|
||||
unsigned __int64 xcr0 = _xgetbv(0);
|
||||
#else
|
||||
unsigned long long xcr0 = __builtin_ia32_xgetbv(0);
|
||||
#endif
|
||||
return ((xcr0 & mask) == mask);
|
||||
}
|
||||
|
||||
static void decode_family_model(int cpuid1_eax, int *family, int *model)
|
||||
{
|
||||
int family_value = 0;
|
||||
int model_value = 0;
|
||||
const int base_fam = (cpuid1_eax >> 8) & 0xF;
|
||||
const int ext_fam = (cpuid1_eax >> 20) & 0xFF;
|
||||
const int base_model = (cpuid1_eax >> 4) & 0xF;
|
||||
const int ext_model = (cpuid1_eax >> 16) & 0xF;
|
||||
|
||||
if (base_fam == 0xF) {
|
||||
family_value = base_fam + ext_fam;
|
||||
} else {
|
||||
family_value = base_fam;
|
||||
}
|
||||
|
||||
if ((base_fam == 0x6) || (base_fam == 0xF)) {
|
||||
model_value = (ext_model << 4) | base_model;
|
||||
} else {
|
||||
model_value = base_model;
|
||||
}
|
||||
|
||||
*family = family_value;
|
||||
*model = model_value;
|
||||
}
|
||||
|
||||
/* AVX-512 execution-width classification for AMD, by CPU family.
|
||||
* Zen4 (0x19): single 256-bit ALU, 512-bit op = two 256-bit micro-ops (dual-pump) → DUAL.
|
||||
* Zen5+ (>=0x1A): native 512-bit execution units → NATIVE.
|
||||
* Other/future AMD families → UNKNOWN (conservative). */
|
||||
static uint64_t amd_avx512_impl(int family)
|
||||
{
|
||||
if (family == 0x19) {
|
||||
return SIMDID_AVX512_IMPL_DUAL;
|
||||
} else if (family >= 0x1A) {
|
||||
return SIMDID_AVX512_IMPL_NATIVE;
|
||||
} else {
|
||||
return SIMDID_AVX512_IMPL_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 1 if this AMD/Hygon CPU uses split-lane YMM (two fused 128-bit execution units).
|
||||
* - AMD Zen1 (family 0x17, model < 0x30) and Zen+ (0x18-0x2F) use a split/glued path.
|
||||
* - Hygon Dhyana is architecturally Zen1-based; always split.
|
||||
* - AMD Zen2+ (family 0x17 model >= 0x30, family 0x19+) have native 256-bit execution. */
|
||||
static int is_amd_glue_ymm(const char *vendor, int cpuid1_eax)
|
||||
{
|
||||
int family = 0;
|
||||
int model = 0;
|
||||
|
||||
if (strcmp(vendor, "HygonGenuine") == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(vendor, "AuthenticAMD") != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
decode_family_model(cpuid1_eax, &family, &model);
|
||||
return (family == 0x17) && (model < 0x30);
|
||||
}
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level_local()
|
||||
{
|
||||
SIMDID simdid = { 0 };
|
||||
|
||||
int eax = 0;
|
||||
int ebx = 0;
|
||||
int ecx = 0;
|
||||
int edx = 0;
|
||||
int family = 0;
|
||||
int model = 0;
|
||||
|
||||
get_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
|
||||
const int max_basic_leaf = eax;
|
||||
|
||||
char vendor[13];
|
||||
memcpy(vendor + 0, &ebx, 4);
|
||||
memcpy(vendor + 4, &edx, 4);
|
||||
memcpy(vendor + 8, &ecx, 4);
|
||||
vendor[12] = '\0';
|
||||
|
||||
const int is_intel = (strcmp(vendor, "GenuineIntel") == 0);
|
||||
const int is_amd = (strcmp(vendor, "AuthenticAMD") == 0);
|
||||
const int is_hygon = (strcmp(vendor, "HygonGenuine") == 0);
|
||||
const int is_centaur = (strcmp(vendor, "CentaurHauls") == 0);
|
||||
const int is_zhaoxin = (memcmp(vendor, " Shanghai ", 12) == 0);
|
||||
const int is_via = is_centaur || is_zhaoxin;
|
||||
|
||||
get_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
const int cpuid1_eax = eax;
|
||||
decode_family_model(cpuid1_eax, &family, &model);
|
||||
(void)model;
|
||||
|
||||
const int has_sse42 = (ecx & (1 << 20)) != 0;
|
||||
const int has_avx = (ecx & (1 << 28)) != 0;
|
||||
const int has_osxsave = (ecx & (1 << 27)) != 0;
|
||||
const int has_fma = (ecx & (1 << 12)) != 0;
|
||||
const int has_f16c = (ecx & (1 << 29)) != 0;
|
||||
|
||||
const uint64_t root = SIMDID_PACK_ROOT(SIMDID_ROOT_X86_64);
|
||||
uint64_t manu_code = SIMDID_MANU_UNKNOWN;
|
||||
if (is_intel) {
|
||||
manu_code = SIMDID_MANU_INTEL;
|
||||
} else if (is_amd) {
|
||||
manu_code = SIMDID_MANU_AMD;
|
||||
} else if (is_hygon) {
|
||||
manu_code = SIMDID_MANU_HYGON;
|
||||
} else if (is_via) {
|
||||
manu_code = SIMDID_MANU_VIA;
|
||||
}
|
||||
const uint64_t manu = SIMDID_PACK_MANU(manu_code);
|
||||
|
||||
uint64_t main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_NONE);
|
||||
uint64_t avx_bits = 0;
|
||||
uint64_t avx512_bits = 0;
|
||||
uint64_t amx_bits = 0;
|
||||
uint64_t avx10_bits = 0;
|
||||
uint64_t uarch_bits = 0;
|
||||
int has_hybrid = 0;
|
||||
|
||||
if (has_sse42) {
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_SSE);
|
||||
}
|
||||
|
||||
if (has_avx && has_osxsave && xgetbv_has_xmm_ymm()) {
|
||||
avx_bits |= SIMDID_AVX;
|
||||
|
||||
if (is_amd_glue_ymm(vendor, cpuid1_eax) || is_via) {
|
||||
avx_bits |= SIMDID_AVX_DUAL;
|
||||
}
|
||||
|
||||
if (max_basic_leaf >= 7) {
|
||||
get_cpuid(7, 0, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
const int has_avx2 = (ebx & (1 << 5)) != 0;
|
||||
const int has_avx512f = (ebx & (1 << 16)) != 0;
|
||||
const int has_avx512dq = (ebx & (1 << 17)) != 0;
|
||||
const int has_avx512bw = (ebx & (1 << 30)) != 0;
|
||||
const int has_avx512vl = (ebx & (1u << 31)) != 0;
|
||||
const int has_avx512_vnni = (ecx & (1 << 11)) != 0;
|
||||
const int has_vbmi = (ecx & (1 << 1)) != 0;
|
||||
const int has_vbmi2 = (ecx & (1 << 6)) != 0;
|
||||
|
||||
const int has_amx_tile = (edx & (1 << 24)) != 0;
|
||||
const int has_amx_int8 = (edx & (1 << 25)) != 0;
|
||||
const int has_amx_bf16 = (edx & (1 << 22)) != 0;
|
||||
has_hybrid = (edx & (1 << 15)) != 0;
|
||||
|
||||
int has_bf16 = 0;
|
||||
int has_fp16 = 0;
|
||||
int has_avx10 = 0;
|
||||
if (eax >= 1) {
|
||||
get_cpuid(7, 1, &eax, &ebx, &ecx, &edx);
|
||||
has_bf16 = (eax & (1 << 5)) != 0;
|
||||
has_fp16 = (eax & (1 << 23)) != 0;
|
||||
has_avx10 = (edx & (1 << 19)) != 0;
|
||||
}
|
||||
|
||||
if (has_avx2) {
|
||||
avx_bits |= SIMDID_AVX2;
|
||||
if (has_fma) {
|
||||
avx_bits |= SIMDID_AVX_FMA;
|
||||
}
|
||||
if (has_f16c) {
|
||||
avx_bits |= SIMDID_AVX_F16C;
|
||||
}
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX2);
|
||||
}
|
||||
|
||||
if (has_avx512f && xgetbv_has_avx512_state()) {
|
||||
if (has_avx512bw && has_avx512vl && has_avx512dq) {
|
||||
avx512_bits |= SIMDID_AVX512_BASE;
|
||||
}
|
||||
if (has_avx512_vnni) {
|
||||
avx512_bits |= SIMDID_AVX512_VNNI;
|
||||
}
|
||||
if (has_bf16) {
|
||||
avx512_bits |= SIMDID_AVX512_BF16;
|
||||
}
|
||||
if (has_fp16) {
|
||||
avx512_bits |= SIMDID_AVX512_FP16;
|
||||
}
|
||||
if (has_vbmi) {
|
||||
avx512_bits |= SIMDID_AVX512_VBMI;
|
||||
}
|
||||
if (has_vbmi2) {
|
||||
avx512_bits |= SIMDID_AVX512_VBMI2;
|
||||
}
|
||||
|
||||
if (is_intel) {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_NATIVE;
|
||||
} else if (is_amd) {
|
||||
avx512_bits |= amd_avx512_impl(family);
|
||||
} else {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_UNKNOWN;
|
||||
}
|
||||
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX512);
|
||||
|
||||
if (has_amx_tile) {
|
||||
amx_bits |= SIMDID_AMX_TILE;
|
||||
if (has_amx_int8) {
|
||||
amx_bits |= SIMDID_AMX_INT8;
|
||||
}
|
||||
if (has_amx_bf16) {
|
||||
amx_bits |= SIMDID_AMX_BF16;
|
||||
}
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AMX);
|
||||
}
|
||||
|
||||
if (has_avx10 && (max_basic_leaf >= 0x24)) {
|
||||
int a10_eax = 0;
|
||||
int a10_ebx = 0;
|
||||
int a10_ecx = 0;
|
||||
int a10_edx = 0;
|
||||
int avx10_ver = 0;
|
||||
int has_256w = 0;
|
||||
int has_512w = 0;
|
||||
|
||||
get_cpuid(0x24, 0, &a10_eax, &a10_ebx, &a10_ecx, &a10_edx);
|
||||
avx10_ver = a10_ebx & 0xFF;
|
||||
if (avx10_ver >= 1) {
|
||||
avx10_bits |= SIMDID_AVX10 | SIMDID_AVX10_V1;
|
||||
if (avx10_ver >= 2) {
|
||||
avx10_bits |= SIMDID_AVX10_V2;
|
||||
}
|
||||
has_256w = (a10_ebx & (1 << 17)) != 0;
|
||||
has_512w = (a10_ebx & (1 << 18)) != 0;
|
||||
if (has_256w) {
|
||||
avx10_bits |= SIMDID_AVX10_256W;
|
||||
}
|
||||
if (has_512w) {
|
||||
avx10_bits |= SIMDID_AVX10_512W;
|
||||
}
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_hybrid && (max_basic_leaf >= 0x1A)) {
|
||||
int h_eax = 0;
|
||||
int h_ebx = 0;
|
||||
int h_ecx = 0;
|
||||
int h_edx = 0;
|
||||
|
||||
get_cpuid(0x1A, 0, &h_eax, &h_ebx, &h_ecx, &h_edx);
|
||||
{
|
||||
const unsigned core_type = (unsigned)(h_eax >> 24) & 0xFFU;
|
||||
if (core_type == 0x40U) {
|
||||
uarch_bits |= SIMDID_UARCH_HYBRID_P;
|
||||
} else if (core_type == 0x20U) {
|
||||
uarch_bits |= SIMDID_UARCH_HYBRID_E;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uarch_bits |= SIMDID_UARCH_HYBRID_P | SIMDID_UARCH_HYBRID_E;
|
||||
}
|
||||
|
||||
{
|
||||
const int has_avx_dual = (avx_bits & SIMDID_AVX_DUAL) != 0;
|
||||
const uint64_t avx512_impl = avx512_bits & SIMDID_AVX512_IMPL_MASK;
|
||||
const int has_avx512_dual = avx512_impl == SIMDID_AVX512_IMPL_DUAL;
|
||||
if (has_avx_dual || has_avx512_dual) {
|
||||
uarch_bits |= SIMDID_UARCH_SIMD_DUAL;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
uint64_t final_mask = root;
|
||||
final_mask |= manu;
|
||||
final_mask |= main_lvl;
|
||||
final_mask |= SIMDID_PACK_AVX512(avx512_bits);
|
||||
final_mask |= SIMDID_PACK_AMX(amx_bits);
|
||||
final_mask |= SIMDID_PACK_AVX(avx_bits);
|
||||
final_mask |= SIMDID_PACK_AVX10(avx10_bits);
|
||||
final_mask |= SIMDID_PACK_UARCH(uarch_bits);
|
||||
simdid.mask = final_mask;
|
||||
}
|
||||
|
||||
return simdid;
|
||||
}
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level_global()
|
||||
{
|
||||
if (global_simdid.mask) {
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
global_simdid = sn_get_simd_level_local();
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level_local()
|
||||
{
|
||||
SIMDID simdid;
|
||||
simdid.mask = 0;
|
||||
return simdid;
|
||||
}
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level_global()
|
||||
{
|
||||
if (global_simdid.mask) {
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
global_simdid = sn_get_simd_level_local();
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -51,20 +51,20 @@ void load_intrinsic_sse(sn_intrinsic *context, SIMDID id)
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
|
||||
context->mat_mk[F32].add = MK_PROC_NAME_STD(float, sse, , add);
|
||||
context->mat_mk[F32].fill = MK_PROC_NAME_STD(float, sse, , fill);
|
||||
context->mat_mk[F32].scalar_mul = MK_PROC_NAME_STD(float, sse, , scalar_mul);
|
||||
context->mat_mk[F32].sub = MK_PROC_NAME_STD(float, sse, , sub);
|
||||
context->mat_mk[F32].transpose = MK_PROC_NAME_STD(float, sse, , transpose);
|
||||
context->mat_mk[F32].fma = MK_PROC_NAME_STD(float, sse, , fma);
|
||||
context->mat_mk[F32].add = GET_MK_PROC_STD(float, sse, , add);
|
||||
context->mat_mk[F32].fill = GET_MK_PROC_STD(float, sse, , fill);
|
||||
context->mat_mk[F32].scalar_mul = GET_MK_PROC_STD(float, sse, , scalar_mul);
|
||||
context->mat_mk[F32].sub = GET_MK_PROC_STD(float, sse, , sub);
|
||||
context->mat_mk[F32].transpose = GET_MK_PROC_STD(float, sse, , transpose);
|
||||
context->mat_mk[F32].fma = GET_MK_PROC_STD(float, sse, , fma);
|
||||
context->mat_mk[F32].pivot = NULL;
|
||||
|
||||
context->mat_mk[F64].add = MK_PROC_NAME_STD(double, sse, , add);
|
||||
context->mat_mk[F64].fill = MK_PROC_NAME_STD(double, sse, , fill);
|
||||
context->mat_mk[F64].scalar_mul = MK_PROC_NAME_STD(double, sse, , scalar_mul);
|
||||
context->mat_mk[F64].sub = MK_PROC_NAME_STD(double, sse, , sub);
|
||||
context->mat_mk[F64].add = GET_MK_PROC_STD(double, sse, , add);
|
||||
context->mat_mk[F64].fill = GET_MK_PROC_STD(double, sse, , fill);
|
||||
context->mat_mk[F64].scalar_mul = GET_MK_PROC_STD(double, sse, , scalar_mul);
|
||||
context->mat_mk[F64].sub = GET_MK_PROC_STD(double, sse, , sub);
|
||||
context->mat_mk[F64].transpose = NULL;
|
||||
context->mat_mk[F64].fma = MK_PROC_NAME_STD(double, sse, , fma);
|
||||
context->mat_mk[F64].fma = GET_MK_PROC_STD(double, sse, , fma);
|
||||
context->mat_mk[F64].pivot = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
@@ -79,22 +79,22 @@ void load_intrinsic_avx(sn_intrinsic *context, SIMDID id)
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
|
||||
context->mat_mk[F32].add = MK_PROC_NAME_STD(float, avx, , add);
|
||||
context->mat_mk[F32].fill = MK_PROC_NAME_STD(float, avx, , fill);
|
||||
context->mat_mk[F32].scalar_mul = MK_PROC_NAME_STD(float, avx, , scalar_mul);
|
||||
context->mat_mk[F32].sub = MK_PROC_NAME_STD(float, avx, , sub);
|
||||
context->mat_mk[F32].transpose = MK_PROC_NAME_STD(float, avx, , transpose);
|
||||
context->mat_mk[F32].fma = is_fma ? MK_PROC_NAME_STD(float, avx, , fma) :
|
||||
MK_PROC_NAME_STD(float, avx, _fma, fma);
|
||||
context->mat_mk[F32].add = GET_MK_PROC_STD(float, avx, , add);
|
||||
context->mat_mk[F32].fill = GET_MK_PROC_STD(float, avx, , fill);
|
||||
context->mat_mk[F32].scalar_mul = GET_MK_PROC_STD(float, avx, , scalar_mul);
|
||||
context->mat_mk[F32].sub = GET_MK_PROC_STD(float, avx, , sub);
|
||||
context->mat_mk[F32].transpose = GET_MK_PROC_STD(float, avx, , transpose);
|
||||
context->mat_mk[F32].fma = is_fma ? GET_MK_PROC_STD(float, avx, , fma) :
|
||||
GET_MK_PROC_STD(float, avx, _fma, fma);
|
||||
context->mat_mk[F32].pivot = NULL;
|
||||
|
||||
context->mat_mk[F64].add = MK_PROC_NAME_STD(double, avx, , add);
|
||||
context->mat_mk[F64].fill = MK_PROC_NAME_STD(double, avx, , fill);
|
||||
context->mat_mk[F64].scalar_mul = MK_PROC_NAME_STD(double, avx, , scalar_mul);
|
||||
context->mat_mk[F64].sub = MK_PROC_NAME_STD(double, avx, , sub);
|
||||
context->mat_mk[F64].add = GET_MK_PROC_STD(double, avx, , add);
|
||||
context->mat_mk[F64].fill = GET_MK_PROC_STD(double, avx, , fill);
|
||||
context->mat_mk[F64].scalar_mul = GET_MK_PROC_STD(double, avx, , scalar_mul);
|
||||
context->mat_mk[F64].sub = GET_MK_PROC_STD(double, avx, , sub);
|
||||
context->mat_mk[F64].transpose = NULL;
|
||||
context->mat_mk[F64].fma = is_fma ? MK_PROC_NAME_STD(double, avx, , fma) :
|
||||
MK_PROC_NAME_STD(double, avx, _fma, fma);
|
||||
context->mat_mk[F64].fma = is_fma ? GET_MK_PROC_STD(double, avx, , fma) :
|
||||
GET_MK_PROC_STD(double, avx, _fma, fma);
|
||||
context->mat_mk[F64].pivot = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
@@ -105,20 +105,20 @@ void load_intrinsic_512(sn_intrinsic *context, SIMDID id)
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
|
||||
context->mat_mk[F32].add = MK_PROC_NAME_STD(float, 512, , add);
|
||||
context->mat_mk[F32].fill = MK_PROC_NAME_STD(float, 512, , fill);
|
||||
context->mat_mk[F32].scalar_mul = MK_PROC_NAME_STD(float, 512, , scalar_mul);
|
||||
context->mat_mk[F32].sub = MK_PROC_NAME_STD(float, 512, , sub);
|
||||
context->mat_mk[F32].transpose = MK_PROC_NAME_STD(float, 512, , transpose);
|
||||
context->mat_mk[F32].fma = MK_PROC_NAME_STD(float, 512, , fma);
|
||||
context->mat_mk[F32].add = GET_MK_PROC_STD(float, 512, , add);
|
||||
context->mat_mk[F32].fill = GET_MK_PROC_STD(float, 512, , fill);
|
||||
context->mat_mk[F32].scalar_mul = GET_MK_PROC_STD(float, 512, , scalar_mul);
|
||||
context->mat_mk[F32].sub = GET_MK_PROC_STD(float, 512, , sub);
|
||||
context->mat_mk[F32].transpose = GET_MK_PROC_STD(float, 512, , transpose);
|
||||
context->mat_mk[F32].fma = GET_MK_PROC_STD(float, 512, , fma);
|
||||
context->mat_mk[F32].pivot = NULL;
|
||||
|
||||
context->mat_mk[F64].add = MK_PROC_NAME_STD(double, 512, , add);
|
||||
context->mat_mk[F64].fill = MK_PROC_NAME_STD(double, 512, , fill);
|
||||
context->mat_mk[F64].scalar_mul = MK_PROC_NAME_STD(double, 512, , scalar_mul);
|
||||
context->mat_mk[F64].sub = MK_PROC_NAME_STD(double, 512, , sub);
|
||||
context->mat_mk[F64].add = GET_MK_PROC_STD(double, 512, , add);
|
||||
context->mat_mk[F64].fill = GET_MK_PROC_STD(double, 512, , fill);
|
||||
context->mat_mk[F64].scalar_mul = GET_MK_PROC_STD(double, 512, , scalar_mul);
|
||||
context->mat_mk[F64].sub = GET_MK_PROC_STD(double, 512, , sub);
|
||||
context->mat_mk[F64].transpose = NULL;
|
||||
context->mat_mk[F64].fma = MK_PROC_NAME_STD(double, 512, , fma);
|
||||
context->mat_mk[F64].fma = GET_MK_PROC_STD(double, 512, , fma);
|
||||
context->mat_mk[F64].pivot = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
|
||||
@@ -118,23 +118,21 @@ SN_MK_PROC_DECL_STD(float, sse, , quality)
|
||||
{
|
||||
__mk_param_std(KERNEL, RIGHT_ANS, float);
|
||||
|
||||
static const __m128 tiny_source = { .m128_f32 = { 1e-6f, 1e-6f, 1e-6f, 1e-6f } };
|
||||
|
||||
register __m128 tiny = _mm_load_ps(tiny_source.m128_f32);
|
||||
register __m128 tiny = _mm_set1_ps(1e-6f);
|
||||
|
||||
register __m128 col0 = _mm_load_ps((float *)&right->f32_x[0]);
|
||||
register __m128 col1 = _mm_load_ps((float *)&right->f32_x[1]);
|
||||
register __m128 col2 = _mm_load_ps((float *)&right->f32_x[2]);
|
||||
register __m128 col3 = _mm_load_ps((float *)&right->f32_x[3]);
|
||||
|
||||
__m128 self_dot_src = { 0 };
|
||||
SN_ALIGNAS(16) float self_dot_src[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
// try in reigister mix later
|
||||
DOT_F32_SSE(col0, col0, self_dot_src.m128_f32[0]);
|
||||
DOT_F32_SSE(col1, col1, self_dot_src.m128_f32[1]);
|
||||
DOT_F32_SSE(col2, col2, self_dot_src.m128_f32[2]);
|
||||
DOT_F32_SSE(col3, col3, self_dot_src.m128_f32[3]);
|
||||
DOT_F32_SSE(col0, col0, self_dot_src[0]);
|
||||
DOT_F32_SSE(col1, col1, self_dot_src[1]);
|
||||
DOT_F32_SSE(col2, col2, self_dot_src[2]);
|
||||
DOT_F32_SSE(col3, col3, self_dot_src[3]);
|
||||
|
||||
register __m128 self_dot = _mm_load_ps(self_dot_src.m128_f32);
|
||||
register __m128 self_dot = _mm_load_ps(self_dot_src);
|
||||
|
||||
register __m128 max;
|
||||
FIND_MAX_F32_SSE(self_dot, max);
|
||||
@@ -149,21 +147,21 @@ SN_MK_PROC_DECL_STD(float, sse, , quality)
|
||||
min = _mm_min_ps(min, min0);
|
||||
|
||||
float quality = _mm_cvtss_f32(_mm_div_ps(min, _mm_add_ps(max, tiny)));
|
||||
ans->f32_x[0].m128_f32[0] = quality;
|
||||
ans->m[0][0] = quality;
|
||||
if (quality < quality_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
__m128 cross_dot_src[2];
|
||||
DOT_F32_SSE(col0, col1, cross_dot_src[0].m128_f32[0]);
|
||||
DOT_F32_SSE(col0, col2, cross_dot_src[0].m128_f32[1]);
|
||||
DOT_F32_SSE(col0, col3, cross_dot_src[0].m128_f32[2]);
|
||||
DOT_F32_SSE(col1, col2, cross_dot_src[0].m128_f32[3]);
|
||||
DOT_F32_SSE(col1, col3, cross_dot_src[1].m128_f32[0]);
|
||||
DOT_F32_SSE(col2, col3, cross_dot_src[1].m128_f32[1]);
|
||||
SN_ALIGNAS(16) float cross_dot_src[2][4] = { 0 };
|
||||
DOT_F32_SSE(col0, col1, cross_dot_src[0][0]);
|
||||
DOT_F32_SSE(col0, col2, cross_dot_src[0][1]);
|
||||
DOT_F32_SSE(col0, col3, cross_dot_src[0][2]);
|
||||
DOT_F32_SSE(col1, col2, cross_dot_src[0][3]);
|
||||
DOT_F32_SSE(col1, col3, cross_dot_src[1][0]);
|
||||
DOT_F32_SSE(col2, col3, cross_dot_src[1][1]);
|
||||
|
||||
register __m128 cross_dot_0 = _mm_load_ps(cross_dot_src[0].m128_f32);
|
||||
register __m128 cross_dot_1 = _mm_load_ps(cross_dot_src[1].m128_f32);
|
||||
register __m128 cross_dot_0 = _mm_load_ps(cross_dot_src[0]);
|
||||
register __m128 cross_dot_1 = _mm_load_ps(cross_dot_src[1]);
|
||||
|
||||
register __m128 base_0 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(1, 0, 0, 0));
|
||||
register __m128 base_1 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(3, 3, 2, 1));
|
||||
@@ -179,7 +177,7 @@ SN_MK_PROC_DECL_STD(float, sse, , quality)
|
||||
|
||||
relation_0 = _mm_max_ps(relation_0, relation_1);
|
||||
FIND_MAX_F32_SSE(relation_0, relation_0);
|
||||
ans->f32_x[0].m128_f32[1] = _mm_cvtss_f32(relation_0);
|
||||
ans->m[0][1] = _mm_cvtss_f32(relation_0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,7 @@ SN_MK_PROC_DECL_STD(float, sse, , fma)
|
||||
{
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, float);
|
||||
|
||||
MAT_KERNEL(float)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
|
||||
register __m128 c0 = _mm_load_ps((float *)&ans_cur->f32_x[0]);
|
||||
register __m128 c1 = _mm_load_ps((float *)&ans_cur->f32_x[1]);
|
||||
@@ -26,8 +25,8 @@ SN_MK_PROC_DECL_STD(float, sse, , fma)
|
||||
register __m128 bcol;
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
|
||||
const __m128 a0 = _mm_load_ps((float *)&left_cur->f32_x[0]);
|
||||
const __m128 a1 = _mm_load_ps((float *)&left_cur->f32_x[1]);
|
||||
@@ -71,20 +70,16 @@ SN_MK_PROC_DECL_STD(float, sse, , fma)
|
||||
|
||||
SN_MK_PROC_DECL_STD(float, avx, , fma)
|
||||
{
|
||||
static const __m256i b01_shift_source = { .m256i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m256i b23_shift_source = { .m256i_i32 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, float);
|
||||
|
||||
MAT_KERNEL(float)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans->f32_y[1]);
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans_cur->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans_cur->f32_y[1]);
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
|
||||
register __m256 b01 = _mm256_load_ps((float *)&right_cur->f32_y[0]);
|
||||
register __m256 b23 = _mm256_load_ps((float *)&right_cur->f32_y[1]);
|
||||
@@ -110,28 +105,27 @@ SN_MK_PROC_DECL_STD(float, avx, _fma, fma)
|
||||
{
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, float);
|
||||
|
||||
MAT_KERNEL(float)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans_cur->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans_cur->f32_y[1]);
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
register __m256 b01 = _mm256_load_ps((float *)&right_cur->f32_y[0]);
|
||||
register __m256 b23 = _mm256_load_ps((float *)&right_cur->f32_y[1]);
|
||||
|
||||
register __m256 a0 = _mm256_broadcast_ps((float *)&left_cur->f32_x[0]);
|
||||
register __m256 a0 = _mm256_broadcast_ps(&left_cur->f32_x[0]);
|
||||
c01 = _mm256_fmadd_ps(a0, b01, c01);
|
||||
c23 = _mm256_fmadd_ps(a0, b23, c23);
|
||||
register __m256 a1 = _mm256_broadcast_ps((float *)&left_cur->f32_x[1]);
|
||||
register __m256 a1 = _mm256_broadcast_ps(&left_cur->f32_x[1]);
|
||||
c01 = _mm256_fmadd_ps(a1, b01, c01);
|
||||
c23 = _mm256_fmadd_ps(a1, b23, c23);
|
||||
register __m256 a2 = _mm256_broadcast_ps((float *)&left_cur->f32_x[2]);
|
||||
register __m256 a2 = _mm256_broadcast_ps(&left_cur->f32_x[2]);
|
||||
c01 = _mm256_fmadd_ps(a2, b01, c01);
|
||||
c23 = _mm256_fmadd_ps(a2, b23, c23);
|
||||
register __m256 a3 = _mm256_broadcast_ps((float *)&left_cur->f32_x[3]);
|
||||
register __m256 a3 = _mm256_broadcast_ps(&left_cur->f32_x[3]);
|
||||
c01 = _mm256_fmadd_ps(a3, b01, c01);
|
||||
c23 = _mm256_fmadd_ps(a3, b23, c23);
|
||||
}
|
||||
@@ -210,8 +204,7 @@ SN_MK_PROC_DECL_STD(double, sse, , fma)
|
||||
{
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, double);
|
||||
|
||||
MAT_KERNEL(double)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
|
||||
register __m128d c0_lo = _mm_load_pd(ans_cur->f64_x + (0 * 2 + 0));
|
||||
register __m128d c0_hi = _mm_load_pd(ans_cur->f64_x + (0 * 2 + 1));
|
||||
@@ -223,8 +216,8 @@ SN_MK_PROC_DECL_STD(double, sse, , fma)
|
||||
register __m128d c3_hi = _mm_load_pd(ans_cur->f64_x + (3 * 2 + 1));
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
|
||||
DOUBLE_KERNEL_FMA_CYCLE(0);
|
||||
|
||||
@@ -249,8 +242,7 @@ SN_MK_PROC_DECL_STD(double, avx, , fma)
|
||||
{
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, double);
|
||||
|
||||
MAT_KERNEL(double)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
|
||||
register __m256d c0 = _mm256_load_pd((double *)&ans_cur->f64_y[0]);
|
||||
register __m256d c1 = _mm256_load_pd((double *)&ans_cur->f64_y[1]);
|
||||
@@ -259,8 +251,8 @@ SN_MK_PROC_DECL_STD(double, avx, , fma)
|
||||
register __m256d bcol;
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
|
||||
const __m256d a0 = _mm256_load_pd((double *)&left_cur->f64_y[0]);
|
||||
const __m256d a1 = _mm256_load_pd((double *)&left_cur->f64_y[1]);
|
||||
@@ -322,8 +314,7 @@ SN_MK_PROC_DECL_STD(double, avx, _fma, fma)
|
||||
{
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, double);
|
||||
|
||||
MAT_KERNEL(double)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y); // GetKernelAddressUnsafe
|
||||
|
||||
register __m256d c0 = _mm256_load_pd((double *)&ans_cur->f64_y[0]);
|
||||
register __m256d c1 = _mm256_load_pd((double *)&ans_cur->f64_y[1]);
|
||||
@@ -332,8 +323,8 @@ SN_MK_PROC_DECL_STD(double, avx, _fma, fma)
|
||||
register __m256d bcol;
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
|
||||
const __m256d a0 = _mm256_load_pd((double *)&left_cur->f64_y[0]);
|
||||
const __m256d a1 = _mm256_load_pd((double *)&left_cur->f64_y[1]);
|
||||
@@ -379,15 +370,14 @@ SN_MK_PROC_DECL_STD(double, 512, , fma)
|
||||
{
|
||||
__mk_param_std(TILE, LEFT_RIGHT_ANS, double);
|
||||
|
||||
MAT_KERNEL(double)
|
||||
const *ans_cur = ans + GET_INDEX(common_y, x, y);
|
||||
SN_MAT_KERNEL_LOCAL const *ans_cur = ans + GET_INDEX(common_y, x, y);
|
||||
|
||||
register __m512d c01 = _mm512_load_pd((double *)&ans->f64_z[0]);
|
||||
register __m512d c23 = _mm512_load_pd((double *)&ans->f64_z[1]);
|
||||
register __m512d c01 = _mm512_load_pd((double *)&ans_cur->f64_z[0]);
|
||||
register __m512d c23 = _mm512_load_pd((double *)&ans_cur->f64_z[1]);
|
||||
|
||||
for (size_t z = 0; z < common_z; z++) {
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z),
|
||||
const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
SN_MAT_KERNEL_LOCAL const *right_cur = right + GET_INDEX(common_z, x, z);
|
||||
SN_MAT_KERNEL_LOCAL const *left_cur = left + GET_INDEX(common_y, z, y);
|
||||
|
||||
register __m512d a01 = _mm512_load_pd((double *)&left_cur->f64_z[0]);
|
||||
register __m512d a23 = _mm512_load_pd((double *)&left_cur->f64_z[1]);
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
#include "sn_internal.h"
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
INTERNAL __m128i facIncrement = { 4, 4, 4, 4 };
|
||||
INTERNAL __m128i facBase = { 1, 2, 3, 4 };
|
||||
static __m128i facIncrement;
|
||||
static __m128i facBase;
|
||||
|
||||
INTERNAL uint64_t SN_DECL factorial_simd_sse(int n)
|
||||
{
|
||||
facIncrement = _mm_set1_epi32(4);
|
||||
facBase = _mm_setr_epi32(1, 2, 3, 4);
|
||||
__m128i baseResult = facBase;
|
||||
__m128i facBaseLocal = facBase;
|
||||
const int cycle = (n - 3) >> 2;
|
||||
@@ -18,8 +20,10 @@ INTERNAL uint64_t SN_DECL factorial_simd_sse(int n)
|
||||
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];
|
||||
SN_ALIGNAS(16) int32_t lanes[4];
|
||||
_mm_store_si128((__m128i *)lanes, baseResult);
|
||||
uint64_t result = (uint64_t)lanes[0] * (uint64_t)lanes[1] * (uint64_t)lanes[2] *
|
||||
(uint64_t)lanes[3];
|
||||
for (uint64_t i = rest; i < n; i++) {
|
||||
result *= i;
|
||||
}
|
||||
|
||||
@@ -350,4 +350,23 @@ SN_API SIMDID SN_DECL sn_get_simd_level_global()
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level_local()
|
||||
{
|
||||
SIMDID simdid;
|
||||
simdid.mask = 0;
|
||||
return simdid;
|
||||
}
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level_global()
|
||||
{
|
||||
if (global_simdid.mask) {
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
global_simdid = sn_get_simd_level_local();
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <string.h>
|
||||
|
||||
extern GladGLContext *currentContext;
|
||||
extern char infolog[512];
|
||||
char infolog[512];
|
||||
|
||||
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef)
|
||||
@@ -30,7 +30,7 @@ SN_API void SN_DECL initGL(int majorVersion, int minorVersion)
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
}
|
||||
|
||||
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char const *procName)
|
||||
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName)
|
||||
{
|
||||
void *ret = glfwGetProcAddress(procName);
|
||||
// printf("%llu\n", (uint64_t)ret);
|
||||
@@ -58,10 +58,10 @@ SN_API unsigned int linkShaderProgram(GladGLContext *context, GLuint shaderProgr
|
||||
}
|
||||
}
|
||||
|
||||
SN_API void SN_DECL loadImageData(char const *location, Image *out, imageLoader loader)
|
||||
SN_API void SN_DECL loadImageData(char *location, Image *out, imageLoader loader)
|
||||
{
|
||||
if (loader == NULL) {
|
||||
loader = stbi_load;
|
||||
loader = (imageLoader)stbi_load;
|
||||
}
|
||||
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_internal.h"
|
||||
|
||||
INTERNAL void SN_DECL f32_normalize(VEC(float) *restrict source, VEC(float) *restrict target)
|
||||
INTERNAL void SN_DECL f32_normalize(sn_vec_f32 *restrict source, sn_vec_f32 *restrict target)
|
||||
{
|
||||
register __m128 s = _mm_load_ps(&source->f32_x);
|
||||
register __m128 a_length_sq = _mm_mul_ps(s, s);
|
||||
|
||||
Reference in New Issue
Block a user