From 8007eee8461498a85a9515e8fd076f03cb552b64 Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Thu, 18 Sep 2025 21:55:26 +0800 Subject: [PATCH] mat kernel turns to be generic --- DvlErrLog.txt | 3 - .../HighPerformance/MatrixKernel.cs | 8 +- .../Mathematics/Linear/KernelParallel.cs | 40 ---------- StgSharp.Common/Mathematics/Linear/Matrix.cs | 46 +++++------ StgSharp.Native/StgSharp.Native.vcxproj | 1 + .../StgSharp.Native.vcxproj.filters | 3 + StgSharp.Native/sn-head/sn_intrinsic.h | 72 ++++++++---------- StgSharp.Native/sn-head/sn_matkernel.h | 19 +++++ StgSharp.Native/sn-src/k_basicop.c | 33 +++++--- StgSharp.Native/sn-src/k_fma.c | 2 +- StgSharp.Native/sn-src/load_intrinsic.c | 12 +-- autoadd.sh | 58 -------------- errorIDarrange.xlsx | Bin 70144 -> 0 bytes 13 files changed, 109 insertions(+), 188 deletions(-) delete mode 100644 DvlErrLog.txt delete mode 100644 StgSharp.Common/Mathematics/Linear/KernelParallel.cs create mode 100644 StgSharp.Native/sn-head/sn_matkernel.h delete mode 100644 autoadd.sh delete mode 100644 errorIDarrange.xlsx diff --git a/DvlErrLog.txt b/DvlErrLog.txt deleted file mode 100644 index ca08bb4f..00000000 --- a/DvlErrLog.txt +++ /dev/null @@ -1,3 +0,0 @@ -System.Exception: Driver Verification Log needs to be created on a 'Release' configuration. The current selected configuration is ''. - 在 Microsoft.SdvMenuCommand.DriverVerificationLicense..ctor() - 在 Microsoft.SdvMenuCommand.SdvMenuCommandPackage.StaticToolsLogoMenuItemCallback(Object sender, EventArgs e) diff --git a/StgSharp.Common/HighPerformance/MatrixKernel.cs b/StgSharp.Common/HighPerformance/MatrixKernel.cs index edc688b2..d47d2b68 100644 --- a/StgSharp.Common/HighPerformance/MatrixKernel.cs +++ b/StgSharp.Common/HighPerformance/MatrixKernel.cs @@ -42,7 +42,7 @@ using System.Threading.Tasks; namespace StgSharp.HighPerformance { [StructLayout(LayoutKind.Explicit, Size = 64)] - public unsafe struct MatrixKernel + public unsafe struct MatrixKernel where T: unmanaged, INumber { [FieldOffset(0)] internal fixed byte Buffer[64]; @@ -68,11 +68,11 @@ namespace StgSharp.HighPerformance } } - public static MatrixKernel Fp32Unit + public static MatrixKernel Unit { get { - MatrixKernel kernel = new(true); + MatrixKernel kernel = new(true); kernel.FP32Buffer[0] = 1f; kernel.FP32Buffer[3] = 1f; kernel.FP32Buffer[8] = 1f; @@ -81,7 +81,7 @@ namespace StgSharp.HighPerformance } } - public ref T UnsafeIndex(int column, int row) where T: unmanaged, INumber + public ref T UnsafeIndex(int column, int row) { ref M128 col = ref Unsafe.As(ref Buffer[0]); col = ref Unsafe.Add(ref col, column); diff --git a/StgSharp.Common/Mathematics/Linear/KernelParallel.cs b/StgSharp.Common/Mathematics/Linear/KernelParallel.cs deleted file mode 100644 index 598f3dcb..00000000 --- a/StgSharp.Common/Mathematics/Linear/KernelParallel.cs +++ /dev/null @@ -1,40 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="KernelParallel.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the “Software”), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics -{ - internal class KernelParallel { } -} diff --git a/StgSharp.Common/Mathematics/Linear/Matrix.cs b/StgSharp.Common/Mathematics/Linear/Matrix.cs index 87147455..a6ee7c85 100644 --- a/StgSharp.Common/Mathematics/Linear/Matrix.cs +++ b/StgSharp.Common/Mathematics/Linear/Matrix.cs @@ -80,7 +80,7 @@ namespace StgSharp.Mathematics public static MatrixAllocation DefaultAllocation { get; set; } = MatrixAllocation.GC; - internal abstract MatrixKernel* Buffer { get; } + internal abstract MatrixKernel* Buffer { get; } protected internal int KernelColumnLength { get; init; } @@ -108,14 +108,14 @@ namespace StgSharp.Mathematics } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public abstract MatrixSegmentEnumeration GetColumnEnumeration(); + public abstract MatrixSegmentEnumeration GetColumnEnumeration(); - public abstract ref MatrixKernel GetMatrixKernel(int column, int row); + public abstract ref MatrixKernel GetMatrixKernel(int column, int row); - public abstract MatrixSegmentEnumeration GetRowEnumeration(); + public abstract MatrixSegmentEnumeration GetRowEnumeration(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public abstract MatrixSegmentEnumeration GetSequentialEnumeration(); + public abstract MatrixSegmentEnumeration GetSequentialEnumeration(); [Obsolete("This method does not contain boarder check, so be careful on size or use indexer instead.", false)] public abstract ref T UnsafeIndex(int column, int row); @@ -133,36 +133,37 @@ namespace StgSharp.Mathematics } - public readonly unsafe ref struct MatrixSegmentEnumeration( - MatrixKernel* source, + public readonly unsafe ref struct MatrixSegmentEnumeration( + MatrixKernel* source, int stride, int size, int secondaryStride, int secondarySize) + where T: unmanaged, INumber { - private readonly MatrixKernel* _source = source; + private readonly MatrixKernel* _source = source; private readonly int _secondarySize = secondarySize; private readonly int _secondaryStride = secondaryStride; private readonly int _size = size; private readonly int _stride = stride; - public Enumerator GetEnumerator() + public Enumerator GetEnumerator() { - return new Enumerator(in this); + return new Enumerator(in this); } - public ref struct Enumerator(in MatrixSegmentEnumeration enumeration) + public ref struct Enumerator(in MatrixSegmentEnumeration enumeration) where T: unmanaged, INumber { - private MatrixKernel* _current = enumeration._source - enumeration._stride; - private readonly MatrixKernel* _end = enumeration._source + enumeration._size; + private MatrixKernel* _current = enumeration._source - enumeration._stride; + private readonly MatrixKernel* _end = enumeration._source + enumeration._size; private readonly int _secondarySize = enumeration._secondarySize; private readonly int _secondaryStride = enumeration._secondaryStride; private readonly int _stride = enumeration._stride; - public readonly MatrixSegment Current + public readonly MatrixSegment Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new(_current, _secondarySize, _secondaryStride); @@ -178,14 +179,15 @@ namespace StgSharp.Mathematics } - public readonly unsafe ref struct MatrixSegment(MatrixKernel* source, int size, int stride) + public readonly unsafe ref struct MatrixSegment(MatrixKernel* source, int size, int stride) + where T: unmanaged, INumber { - private readonly MatrixKernel* _source = source; + private readonly MatrixKernel* _source = source; private readonly int _size = size; private readonly int _stride = stride; - public ref MatrixKernel this[int index] + public ref MatrixKernel this[int index] { get { @@ -196,18 +198,18 @@ namespace StgSharp.Mathematics } } - public Enumerator GetEnumerator() + public Enumerator GetEnumerator() { - return new Enumerator(_source, _size, _stride); + return new Enumerator(_source, _size, _stride); } - public ref struct Enumerator(MatrixKernel* source, int count, int stride) + public ref struct Enumerator(MatrixKernel* source, int count, int stride) where T: unmanaged, INumber { - private readonly MatrixKernel* _end = source + (count * stride); + private readonly MatrixKernel* _end = source + (count * stride); private readonly int _stride = stride; - public MatrixKernel* Current + public MatrixKernel* Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; diff --git a/StgSharp.Native/StgSharp.Native.vcxproj b/StgSharp.Native/StgSharp.Native.vcxproj index c338677d..45bad145 100644 --- a/StgSharp.Native/StgSharp.Native.vcxproj +++ b/StgSharp.Native/StgSharp.Native.vcxproj @@ -179,6 +179,7 @@ + diff --git a/StgSharp.Native/StgSharp.Native.vcxproj.filters b/StgSharp.Native/StgSharp.Native.vcxproj.filters index 30e54e47..563ce522 100644 --- a/StgSharp.Native/StgSharp.Native.vcxproj.filters +++ b/StgSharp.Native/StgSharp.Native.vcxproj.filters @@ -83,6 +83,9 @@ 头文件 + + 头文件 + diff --git a/StgSharp.Native/sn-head/sn_intrinsic.h b/StgSharp.Native/sn-head/sn_intrinsic.h index b778176b..ac06c550 100644 --- a/StgSharp.Native/sn-head/sn_intrinsic.h +++ b/StgSharp.Native/sn-head/sn_intrinsic.h @@ -5,7 +5,10 @@ #ifndef SSC_INTRIN #define SSC_INTRIN +#define SSC_INTRIN_HEAD + #include "StgSharpNative.h" +#include "sn_matkernel.h" #include #include @@ -39,25 +42,6 @@ typedef union mat_kernel { float m[4][4]; } mat_kernel; -typedef union column_2 { - __m256 stream; - __m128 column[2]; - float m[4][2]; -} __2_columnset; - -typedef union column_3 { - __m256 part; - __m128 column[3]; - float m[4][3]; -} __3_columnset; - -typedef union column_4 { - __m512 stream; - __m256 half[2]; - __m128 column[4]; - float m[4][4]; -} __4_columnset; - typedef union scalar_pack { uint64_t data[8]; } scalar_pack; @@ -77,34 +61,38 @@ typedef uint64_t(SN_DECL *FACTORIALROC)(int n); INTERNAL void normalize(__m128 *source, __m128 *target); -INTERNAL void SN_DECL kernel_add_sse(mat_kernel const *left, mat_kernel const *right, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_add_avx(mat_kernel const *left, mat_kernel const *right, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_add_512(mat_kernel const *left, mat_kernel const *right, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_sub_sse(mat_kernel const *left, mat_kernel const *right, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_sub_avx(mat_kernel const *left, mat_kernel const *right, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_sub_512(mat_kernel const *left, mat_kernel const *right, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_transpose_sse(mat_kernel const *source, mat_kernel *target); -INTERNAL void SN_DECL kernel_transpose_avx(mat_kernel const *source, mat_kernel *target); -INTERNAL void SN_DECL kernel_transpose_512(mat_kernel const *source, mat_kernel *target); -INTERNAL void SN_DECL kernel_scalar_mul_sse(mat_kernel const *matrix, float const scalar, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_scalar_mul_avx(mat_kernel const *matrix, float const scalar, - mat_kernel *ans); -INTERNAL void SN_DECL kernel_scalar_mul_512(mat_kernel const *matrix, float const scalar, - mat_kernel *ans); +INTERNAL void SN_DECL f32_add_sse(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_add_avx(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_add_512(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_sub_sse(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_sub_avx(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_sub_512(MAT_KERNEL(float) const *left, MAT_KERNEL(float) const *right, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_transpose_sse(MAT_KERNEL(float) const *source, + MAT_KERNEL(float) * target); +INTERNAL void SN_DECL f32_transpose_avx(MAT_KERNEL(float) const *source, + MAT_KERNEL(float) * target); +INTERNAL void SN_DECL f32_transpose_512(MAT_KERNEL(float) const *source, + MAT_KERNEL(float) * target); +INTERNAL void SN_DECL f32_scalar_mul_sse(MAT_KERNEL(float) const *matrix, float const scalar, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_scalar_mul_avx(MAT_KERNEL(float) const *matrix, float const scalar, + MAT_KERNEL(float) * ans); +INTERNAL void SN_DECL f32_scalar_mul_512(MAT_KERNEL(float) const *matrix, float const scalar, + MAT_KERNEL(float) * ans); #pragma endregion #pragma region fma -INTERNAL void SN_DECL kernel_fma_sse(mat_kernel const *restrict left, - mat_kernel const *restrict right, mat_kernel *restrict ans); +INTERNAL void SN_DECL kernel_fma_sse(MAT_KERNEL(float) const *restrict left, + MAT_KERNEL(float) const *restrict right, + MAT_KERNEL(float) *restrict ans); #pragma endregion diff --git a/StgSharp.Native/sn-head/sn_matkernel.h b/StgSharp.Native/sn-head/sn_matkernel.h new file mode 100644 index 00000000..8f7930b2 --- /dev/null +++ b/StgSharp.Native/sn-head/sn_matkernel.h @@ -0,0 +1,19 @@ +#ifndef SN_MATKERNEL +#define SN_MATKERNEL + +#include + +#define ELEMENTSIZE(T) sizeof(T) +#define XMMCOUNT(T) sizeof(T) / 16 +#define YMMCOUNT(T) sizeof(T) / 32 +#define ZMMCOUNT(T) sizeof(T) / 64 + +#define MAT_KERNEL(T) \ + union { \ + __m128 xmm[XMMCOUNT(T)]; \ + __m256 ymm[YMMCOUNT(T)]; \ + __m512 zmm[ZMMCOUNT(T)]; \ + T m[16]; \ + } + +#endif diff --git a/StgSharp.Native/sn-src/k_basicop.c b/StgSharp.Native/sn-src/k_basicop.c index c2bef309..17f47261 100644 --- a/StgSharp.Native/sn-src/k_basicop.c +++ b/StgSharp.Native/sn-src/k_basicop.c @@ -1,6 +1,7 @@ #include "sn_intrinsic.h" -INTERNAL void SN_DECL kernel_add_sse(mat_kernel *left, mat_kernel *right, mat_kernel *ans) +INTERNAL void SN_DECL f32_add_sse(MAT_KERNEL(float) * left, MAT_KERNEL(float) * right, + MAT_KERNEL(float) * 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]); @@ -13,7 +14,8 @@ INTERNAL void SN_DECL kernel_add_sse(mat_kernel *left, mat_kernel *right, mat_ke ans->xmm[3] = c3; } -INTERNAL void SN_DECL kernel_add_avx(mat_kernel *left, mat_kernel *right, mat_kernel *ans) +INTERNAL void SN_DECL f32_add_avx(MAT_KERNEL(float) * left, MAT_KERNEL(float) * right, + MAT_KERNEL(float) * 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]); @@ -21,13 +23,15 @@ INTERNAL void SN_DECL kernel_add_avx(mat_kernel *left, mat_kernel *right, mat_ke ans->ymm[1] = c1; } -INTERNAL void SN_DECL kernel_add_512(mat_kernel *left, mat_kernel *right, mat_kernel *ans) +INTERNAL void SN_DECL f32_add_512(MAT_KERNEL(float) * left, MAT_KERNEL(float) * right, + MAT_KERNEL(float) * 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) +INTERNAL void SN_DECL f32_sub_sse(MAT_KERNEL(float) * left, MAT_KERNEL(float) * right, + MAT_KERNEL(float) * 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]); @@ -40,7 +44,8 @@ INTERNAL void SN_DECL kernel_sub_sse(mat_kernel *left, mat_kernel *right, mat_ke ans->xmm[3] = c3; } -INTERNAL void SN_DECL kernel_sub_avx(mat_kernel *left, mat_kernel *right, mat_kernel *ans) +INTERNAL void SN_DECL f32_sub_avx(MAT_KERNEL(float) * left, MAT_KERNEL(float) * right, + MAT_KERNEL(float) * 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]); @@ -48,14 +53,15 @@ INTERNAL void SN_DECL kernel_sub_avx(mat_kernel *left, mat_kernel *right, mat_ke ans->ymm[1] = c1; } -INTERNAL void SN_DECL kernel_sub_512(mat_kernel *left, mat_kernel *right, mat_kernel *ans) +INTERNAL void SN_DECL f32_sub_512(MAT_KERNEL(float) * left, MAT_KERNEL(float) * right, + MAT_KERNEL(float) * 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) +INTERNAL void SN_DECL kernel_transpose_sse(MAT_KERNEL(float) * source, MAT_KERNEL(float) * target) { register __m128 col0 = source->xmm[0]; register __m128 col1 = source->xmm[1]; @@ -72,7 +78,7 @@ INTERNAL void SN_DECL kernel_transpose_sse(mat_kernel *source, mat_kernel *targe target->xmm[3] = _mm_movehl_ps(tmp3, tmp1); } -INTERNAL void SN_DECL kernel_transpose_avx(mat_kernel *source, mat_kernel *target) +INTERNAL void SN_DECL kernel_transpose_avx(MAT_KERNEL(float) * source, MAT_KERNEL(float) * target) { register __m256 col_low = source->ymm[0]; register __m256 col_high = source->ymm[1]; @@ -87,7 +93,7 @@ INTERNAL void SN_DECL kernel_transpose_avx(mat_kernel *source, mat_kernel *targe 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) +INTERNAL void SN_DECL kernel_transpose_512(MAT_KERNEL(float) * source, MAT_KERNEL(float) * target) { register __m512 matrix = source->zmm[0]; @@ -97,7 +103,8 @@ INTERNAL void SN_DECL kernel_transpose_512(mat_kernel *source, mat_kernel *targe 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) +INTERNAL void SN_DECL kernel_scalar_mul_sse(MAT_KERNEL(float) * matrix, float scalar, + MAT_KERNEL(float) * ans) { register __m128 temp = _mm_load_ss(&scalar); register __m128 scalar_vec = _mm_shuffle_ps(temp, temp, _MM_SHUFFLE(0, 0, 0, 0)); @@ -113,7 +120,8 @@ INTERNAL void SN_DECL kernel_scalar_mul_sse(mat_kernel *matrix, float scalar, ma ans->xmm[3] = c3; } -INTERNAL void SN_DECL kernel_scalar_mul_avx(mat_kernel *matrix, float scalar, mat_kernel *ans) +INTERNAL void SN_DECL kernel_scalar_mul_avx(MAT_KERNEL(float) * matrix, float scalar, + MAT_KERNEL(float) * ans) { register __m256 scalar_vec = _mm256_broadcast_ss(&scalar); @@ -124,7 +132,8 @@ INTERNAL void SN_DECL kernel_scalar_mul_avx(mat_kernel *matrix, float scalar, ma ans->ymm[1] = c1; } -INTERNAL void SN_DECL kernel_scalar_mul_512(mat_kernel *matrix, float scalar, mat_kernel *ans) +INTERNAL void SN_DECL kernel_scalar_mul_512(MAT_KERNEL(float) * matrix, float scalar, + MAT_KERNEL(float) * ans) { __m512 scalar_vec = _mm512_broadcastss_ps(_mm_load_ss(&scalar)); diff --git a/StgSharp.Native/sn-src/k_fma.c b/StgSharp.Native/sn-src/k_fma.c index bfb6f72d..b6c8ab7d 100644 --- a/StgSharp.Native/sn-src/k_fma.c +++ b/StgSharp.Native/sn-src/k_fma.c @@ -1,7 +1,7 @@ #include "sn_intrinsic.h" // ans = left * right(T) + ans -INTERNAL void SN_DECL kernel_fma_sse(mat_kernel const *restrict left, +INTERNAL void SN_DECL f32_fma_sse(MAT_KERNEL(float) const *restrict left, mat_kernel const *restrict right, mat_kernel *restrict ans) { register __m128 source0 = _mm_load_ps(&left->xmm[0]); diff --git a/StgSharp.Native/sn-src/load_intrinsic.c b/StgSharp.Native/sn-src/load_intrinsic.c index 8b89f0e7..525440f9 100644 --- a/StgSharp.Native/sn-src/load_intrinsic.c +++ b/StgSharp.Native/sn-src/load_intrinsic.c @@ -66,10 +66,10 @@ 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_add = (MATARITHMETIC)f32_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_sub = (MATARITHMETIC)f32_sub_sse; context->kernel_transpose = (MATTRANSPOSEPROC)kernel_transpose_sse; context->normalize_3 = normalize; } @@ -79,10 +79,10 @@ 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_add = (MATARITHMETIC)f32_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_sub = (MATARITHMETIC)f32_sub_avx; context->kernel_transpose = (MATTRANSPOSEPROC)kernel_transpose_avx; context->normalize_3 = normalize; } @@ -92,10 +92,10 @@ 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_add = (MATARITHMETIC)f32_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_sub = (MATARITHMETIC)f32_sub_512; context->kernel_transpose = (MATTRANSPOSEPROC)kernel_transpose_512; context->normalize_3 = normalize; } diff --git a/autoadd.sh b/autoadd.sh deleted file mode 100644 index 0aad5137..00000000 --- a/autoadd.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -clear - -# 设置要查找的文件类型 -file_types=( "*.cs" "*.c" "*.cpp" "*.h" "*.txt" "*.csproj" "*.vs" "*.vert" "*.frag" "*.sln" "*.vcxproj" "*.json" "*.sh" ) - -# 循环遍历每个文件类型,并添加到git -for type in "${file_types[@]}"; do - - # 执行find命令,并将输出保存到变量中 - add_output=$(find . -name "$type" -exec git add '{}' + 2>&1) - add_status=$? - - # 检查find命令的退出状态 - if [ $add_status -ne 0 ]; then - # 如果出错,显示保存的输出 - echo "$add_output" - exit 1 - fi -done -clear - -# 提示用户输入commit信息 -echo "====================== file added ======================" -echo "请输入commit信息:" -read commit_message - -# 执行git commit命令,并将输出保存到变量中 -commit_output=$(git commit -m "$commit_message" 2>&1) -commit_status=$? - -# 检查git commit命令的退出状态 -if [ $commit_status -ne 0 ]; then - # 如果出错,显示保存的输出 - echo "$commit_output" - exit 1 -fi - -clear - -echo "" -echo "================ successfully committed =================" -echo "" -# 执行git push命令 -git push CCD_Git local:main -git push CCD_Git local:nitload - -if [ $? -ne 0 ]; then - exit 1 -fi - -echo "" -echo "Successfully pushed, press enter to quit" -read commit_message - -clear -exit diff --git a/errorIDarrange.xlsx b/errorIDarrange.xlsx deleted file mode 100644 index fbb6e0b7d29ec209a1cbeb779c4f62584c16940d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70144 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