From f133cc9147f2fb9e54cdcaa9924c22ab1e900fae Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Tue, 13 Jan 2026 18:25:25 +0800 Subject: [PATCH] solve or inv starts --- StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs | 64 ++++++++--------- .../Mathematics/Graphic/Matrix44.cs | 22 ++---- .../Linear/{IMatrix.cs => ElementType.cs} | 18 ++--- StgSharp.Mathematics/Numeric/MatrixCompute.cs | 1 + .../Numeric/MatrixParallelTaskPackage.cs | 10 --- StgSharp.Native/StgSharp.Native.vcxproj | 2 +- .../StgSharp.Native.vcxproj.filters | 2 +- .../sn-head/sn_intrincontext.x86.h | 2 + StgSharp.Native/sn-src/m.pivot.x86.c | 70 ------------------- StgSharp.Native/sn-src/m.solve.x86.c | 45 ++++++++++++ StgSharpDebug/MatrixTest.cs | 14 ++-- 11 files changed, 103 insertions(+), 147 deletions(-) rename StgSharp.Common/Mathematics/Linear/{IMatrix.cs => ElementType.cs} (83%) delete mode 100644 StgSharp.Native/sn-src/m.pivot.x86.c create mode 100644 StgSharp.Native/sn-src/m.solve.x86.c diff --git a/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs b/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs index 1797a163..5451fe87 100644 --- a/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs +++ b/StgSharp.Common/Graphics/OpenGL/Buffer/VBO.cs @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="VBO" // Project: StgSharp @@ -43,13 +43,18 @@ namespace StgSharp.Graphics.OpenGL public sealed unsafe class VertexBuffer : GlBufferObjectBase { - internal VertexBuffer(int n, glRender binding) + internal VertexBuffer( + int n, + glRender binding + ) : base(binding) { _bufferHandle = GL.GenBuffers(n); } - public sealed override void Bind(int index) + public sealed override void Bind( + int index + ) { GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]); } @@ -63,28 +68,6 @@ namespace StgSharp.Graphics.OpenGL GL.BindBuffer(BufferType.ArrayBuffer, GlHandle.Zero); } - /// - /// Set _data to current vertex BufferHandle object - /// - /// - /// Type of bufferData - /// - /// - /// Index to find certain VBO in this instance - /// - /// - /// Data to write in - /// - /// - /// How OpenGL use these _data, defined by - /// - public void WriteMatrixData(int index, ref IMatrix bufferData, BufferUsage usage) - where T: unmanaged, INumber - { - GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]); - GL.SetBufferData(BufferType.ArrayBuffer, bufferData.AsSpan(), usage); - } - /// /// Set _data to current vertex BufferHandle object /// @@ -100,7 +83,11 @@ namespace StgSharp.Graphics.OpenGL /// /// How OpenGL use these _data, defined by /// - public void WriteScalerData(int index, T[] bufferArray, BufferUsage usage) where T: unmanaged, INumber + public void WriteScalerData( + int index, + T[] bufferArray, + BufferUsage usage + ) where T : unmanaged, INumber { GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]); GL.SetBufferData(BufferType.ArrayBuffer, bufferArray, usage); @@ -121,8 +108,11 @@ namespace StgSharp.Graphics.OpenGL /// /// How OpenGL use these _data, defined by /// - public void WriteScalerData(int index, ReadOnlySpan scalerSpan, BufferUsage usage) - where T: unmanaged,INumber + public void WriteScalerData( + int index, + ReadOnlySpan scalerSpan, + BufferUsage usage + ) where T : unmanaged,INumber { GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]); GL.SetBufferData(BufferType.ArrayBuffer, scalerSpan, usage); @@ -143,8 +133,11 @@ namespace StgSharp.Graphics.OpenGL /// /// How OpenGL use these data, defined by /// - public void WriteVectorData(int index, ReadOnlySpan vectorSpan, BufferUsage usage) - where T: unmanaged, IUnmanagedVector + public void WriteVectorData( + int index, + ReadOnlySpan vectorSpan, + BufferUsage usage + ) where T : unmanaged, IUnmanagedVector { GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]); GL.SetBufferVectorData(BufferType.ArrayBuffer, vectorSpan, usage); @@ -165,14 +158,19 @@ namespace StgSharp.Graphics.OpenGL /// /// How OpenGL use these _data, defined by /// - public void WriteVectorData(int index, T[] vectorArray, BufferUsage usage) - where T: unmanaged, IUnmanagedVector + public void WriteVectorData( + int index, + T[] vectorArray, + BufferUsage usage + ) where T : unmanaged, IUnmanagedVector { GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]); GL.SetBufferVectorData(BufferType.ArrayBuffer, vectorArray, usage); } - protected sealed override void Dispose(bool disposing) + protected sealed override void Dispose( + bool disposing + ) { if (disposing) { GL.DeleteBuffers(_bufferHandle); diff --git a/StgSharp.Common/Mathematics/Graphic/Matrix44.cs b/StgSharp.Common/Mathematics/Graphic/Matrix44.cs index 03e7c776..66a25a52 100644 --- a/StgSharp.Common/Mathematics/Graphic/Matrix44.cs +++ b/StgSharp.Common/Mathematics/Graphic/Matrix44.cs @@ -36,8 +36,8 @@ using System.Runtime.InteropServices; namespace StgSharp.Mathematics.Graphic { - [StructLayout(LayoutKind.Explicit, Size = (2 * 16 * sizeof(float)) + sizeof(bool), Pack = 16)] - public unsafe struct Matrix44 : IEquatable, IMatrix, IEnumerable + [StructLayout(LayoutKind.Explicit, Size = (16 * sizeof(float)), Pack = 16)] + public unsafe struct Matrix44 : IEquatable { [FieldOffset(0 * sizeof(float))] internal Column column; @@ -223,8 +223,10 @@ namespace StgSharp.Mathematics.Graphic Matrix44 right ) { - Matrix44 transpose = left.Transpose; - return new Matrix44(Vector4.Dot(transpose.mat.colum0, right.mat.colum0), Vector4.Dot(transpose.mat.colum0, right.mat.colum1), Vector4.Dot(transpose.mat.colum0, right.mat.colum2), Vector4.Dot(transpose.mat.colum0, right.mat.colum3), Vector4.Dot(transpose.mat.colum1, right.mat.colum0), Vector4.Dot(transpose.mat.colum1, right.mat.colum1), Vector4.Dot(transpose.mat.colum1, right.mat.colum2), Vector4.Dot(transpose.mat.colum1, right.mat.colum3), Vector4.Dot(transpose.mat.colum2, right.mat.colum0), Vector4.Dot(transpose.mat.colum2, right.mat.colum1), Vector4.Dot(transpose.mat.colum2, right.mat.colum2), Vector4.Dot(transpose.mat.colum2, right.mat.colum3), Vector4.Dot(transpose.mat.colum3, right.mat.colum0), Vector4.Dot(transpose.mat.colum3, right.mat.colum1), Vector4.Dot(transpose.mat.colum3, right.mat.colum2), Vector4.Dot(transpose.mat.colum3, right.mat.colum3)); + Matrix44 ret = new(); + int f32 = (int)MatrixElementType.F32; + NativeIntrinsic.Context.mat[f32].kernel_fma(&left, &right, &ret); + return ret; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -247,18 +249,6 @@ namespace StgSharp.Mathematics.Graphic return left.Equals(right); } - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - for (int i = 0; i < 4; i++) { - yield return column[i]; - } - } - [InlineArray(4)] internal struct Column { diff --git a/StgSharp.Common/Mathematics/Linear/IMatrix.cs b/StgSharp.Common/Mathematics/Linear/ElementType.cs similarity index 83% rename from StgSharp.Common/Mathematics/Linear/IMatrix.cs rename to StgSharp.Common/Mathematics/Linear/ElementType.cs index f626e927..16ad96db 100644 --- a/StgSharp.Common/Mathematics/Linear/IMatrix.cs +++ b/StgSharp.Common/Mathematics/Linear/ElementType.cs @@ -1,6 +1,6 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="IMatrix" +// file="ElementType" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -25,21 +25,21 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- -using StgSharp.Graphics; - using System; using System.Collections.Generic; -using System.Numerics; -using System.Runtime.CompilerServices; +using System.Linq; using System.Text; +using System.Threading.Tasks; namespace StgSharp.Mathematics.Numeric { - public interface IMatrix where TElement: unmanaged, INumber - + public enum MatrixElementType : int { - ReadOnlySpan AsSpan(); + F32 = 0, + F64 = 1, + I32 = 2, + I64 = 3, } } diff --git a/StgSharp.Mathematics/Numeric/MatrixCompute.cs b/StgSharp.Mathematics/Numeric/MatrixCompute.cs index d378d0df..132b110a 100644 --- a/StgSharp.Mathematics/Numeric/MatrixCompute.cs +++ b/StgSharp.Mathematics/Numeric/MatrixCompute.cs @@ -27,6 +27,7 @@ // ----------------------------------------------------------------------- using StgSharp.HighPerformance; using StgSharp.Internal; +using StgSharp.Mathematics.Linear; using System; using System.Collections.Generic; using System.Linq; diff --git a/StgSharp.Mathematics/Numeric/MatrixParallelTaskPackage.cs b/StgSharp.Mathematics/Numeric/MatrixParallelTaskPackage.cs index 9643d0e8..f14a89bf 100644 --- a/StgSharp.Mathematics/Numeric/MatrixParallelTaskPackage.cs +++ b/StgSharp.Mathematics/Numeric/MatrixParallelTaskPackage.cs @@ -96,16 +96,6 @@ namespace StgSharp.Mathematics.Numeric } - public enum MatrixElementType : int - { - - F32 = 0, - F64 = 1, - I32 = 2, - I64 = 3, - - } - [StructLayout(LayoutKind.Explicit, Size = 128)] public unsafe struct MatrixParallelTaskPackage { diff --git a/StgSharp.Native/StgSharp.Native.vcxproj b/StgSharp.Native/StgSharp.Native.vcxproj index 69f7554e..1b7273cd 100644 --- a/StgSharp.Native/StgSharp.Native.vcxproj +++ b/StgSharp.Native/StgSharp.Native.vcxproj @@ -159,7 +159,7 @@ - + diff --git a/StgSharp.Native/StgSharp.Native.vcxproj.filters b/StgSharp.Native/StgSharp.Native.vcxproj.filters index fc090e7e..f6d73b3b 100644 --- a/StgSharp.Native/StgSharp.Native.vcxproj.filters +++ b/StgSharp.Native/StgSharp.Native.vcxproj.filters @@ -57,7 +57,7 @@ 源文件 - + 源文件 diff --git a/StgSharp.Native/sn-head/sn_intrincontext.x86.h b/StgSharp.Native/sn-head/sn_intrincontext.x86.h index 83d1bb99..6f94619d 100644 --- a/StgSharp.Native/sn-head/sn_intrincontext.x86.h +++ b/StgSharp.Native/sn-head/sn_intrincontext.x86.h @@ -149,6 +149,8 @@ DECLARE_PNL_PROC_ANS(double, sse, , clear); DECLARE_PNL_PROC_ANS(double, avx, , clear); DECLARE_PNL_PROC_ANS(double, 512, , clear); +DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality); + DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, sse, , fma); DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, , fma); DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma); diff --git a/StgSharp.Native/sn-src/m.pivot.x86.c b/StgSharp.Native/sn-src/m.pivot.x86.c deleted file mode 100644 index 8d720f35..00000000 --- a/StgSharp.Native/sn-src/m.pivot.x86.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "sn_target.h" - -#if SN_IS_ARCH(SN_ARCH_X86_64) - -#include "sn_intrinsic.h" - -// Hybrid implementation: SIMD for Abs, Scalar for Max -// Assumes Column-Major layout for both MAT_KERNEL content and Kernel sequence -INTERNAL void SN_DECL pivot_float(MAT_KERNEL(float) const *source, size_t col_begin, - size_t col_length, size_t *restrict ans) -{ - float max_v[4] = { -1.0f, -1.0f, -1.0f, -1.0f }; - - // Initialize ans with the first row index of the search range - size_t start_row = col_begin * 4; - ans[0] = start_row; - ans[1] = start_row; - ans[2] = start_row; - ans[3] = start_row; - - const MAT_KERNEL(float) *k_ptr = source + col_begin; - - // Mask for absolute value: 0x7FFFFFFF (clears the sign bit) - __m128i abs_mask = _mm_set1_epi32(0x7FFFFFFF); - - for (size_t i = 0; i < col_length; ++i) { - const float *mat_ptr = (const float *)(k_ptr + i); - size_t base_row = (col_begin + i) * 4; - - // Iterate over 4 columns of the kernel - for (int c = 0; c < 4; ++c) { - // Load column c: 4 floats (Column-Major: contiguous in memory) - __m128 col_vec = _mm_load_ps(mat_ptr + c * 4); - - // Convert to integer vector, AND with mask, convert back - __m128i col_i = _mm_castps_si128(col_vec); - col_i = _mm_and_si128(col_i, abs_mask); - col_vec = _mm_castsi128_ps(col_i); - - VEC(float) vals; - _mm_store_ps(vals.v, col_vec); - - // Local reduction to find the max within this column chunk (4 elements) - // This breaks the dependency chain and reduces branches/cmovs on the global max_v - float v0 = vals.v[0]; - float v1 = vals.v[1]; - float v2 = vals.v[2]; - float v3 = vals.v[3]; - - // Compare pairs (0 vs 1) and (2 vs 3) - these can execute in parallel - int i01 = (v1 > v0) ? 1 : 0; - float m01 = (v1 > v0) ? v1 : v0; - - int i23 = (v3 > v2) ? 3 : 2; - float m23 = (v3 > v2) ? v3 : v2; - - // Compare winners - int i_local = (m23 > m01) ? i23 : i01; - float m_local = (m23 > m01) ? m23 : m01; - - // Single check against global maximum - if (m_local > max_v[c]) { - max_v[c] = m_local; - ans[c] = base_row + i_local; - } - } - } -} - -#endif diff --git a/StgSharp.Native/sn-src/m.solve.x86.c b/StgSharp.Native/sn-src/m.solve.x86.c new file mode 100644 index 00000000..2c481ca0 --- /dev/null +++ b/StgSharp.Native/sn-src/m.solve.x86.c @@ -0,0 +1,45 @@ +#include "sn_target.h" + +#if SN_IS_ARCH(SN_ARCH_X86_64) + +#include "sn_intrinsic.h" + +DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality) +{ + static const __m128 abs_mask_source = { .m128_i32 = { 0x80000000, 0x80000000, 0x80000000, + 0x80000000 } }; + register __m128 abs_mask = _mm_load_ps(abs_mask_source.m128_i32); + + register __m128 col0 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[0])); + register __m128 col1 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[1])); + register __m128 col2 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[2])); + register __m128 col3 = _mm_andnot_ps(abs_mask, _mm_load_ps((float *)&right->f32_x[3])); + + // norm + register __m128 row_sum = _mm_add_ps(col0, col1); + row_sum = _mm_add_ps(row_sum, col2); + row_sum = _mm_add_ps(row_sum, col3); + + // max(0,2) and max(1,3) + register __m128 max = _mm_max_ps(row_sum, _mm_movehl_ps(row_sum, row_sum)); + max = _mm_max_ps(max, _mm_shuffle_ps(max, max, _MM_SHUFFLE(2, 3, 0, 1))); + float norm = _mm_cvtss_f32(max); + + ans->f32_x[0].m128_f32[0] = norm; + + // min on cross + col1 = _mm_shuffle_ps(col1, col1, _MM_SHUFFLE(0, 3, 2, 1)); + col2 = _mm_shuffle_ps(col2, col2, _MM_SHUFFLE(1, 0, 3, 2)); + col3 = _mm_shuffle_ps(col3, col3, _MM_SHUFFLE(2, 1, 0, 3)); + max = _mm_min_ps(col0, col2); + register max0 = _mm_min_ps(max, col1); + max = _mm_min_ps(max0, max); + + float min_val = _mm_cvtss_f32(max); + ans->f32_x[0].m128_f32[1] = min_val; + + float quality = min_val / (norm + 1e-20f); + ans->f32_x[0].m128_f32[2] = quality; +} + +#endif diff --git a/StgSharpDebug/MatrixTest.cs b/StgSharpDebug/MatrixTest.cs index a33c3bba..46b84f43 100644 --- a/StgSharpDebug/MatrixTest.cs +++ b/StgSharpDebug/MatrixTest.cs @@ -35,14 +35,14 @@ using System.Numerics; using System.Text; using System.Threading.Tasks; -using T = double; +using T = float; namespace StgSharp { internal static partial class Program { - private static int sideLength = 400; + private static int sideLength = 20; internal static unsafe void TestMatrix( ) @@ -76,21 +76,21 @@ namespace StgSharp Console.WriteLine("==================================================="); MatrixCompute.Mul(n, m, p); /**/ - for (int i = 0; i < 400; i++) + for (int i = 0; i < 20; i++) { if (i % 4 == 0) { Console.WriteLine(); } - for (int j = 0; j < 30; j++) + for (int j = 0; j < 20; j++) { - string extra = j % 4 == 3 ? " " : " "; + string extra = j % 4 == 3 ? " " : ","; T value = p[j, i]; // value = T.Abs(value) < 1e-6 ? 0 : value; - // Console.Write($"{p.GetElementOffset(j,i)}{extra}"); + Console.Write($"{p.GetElementOffset(j,i)}{extra}"); - Console.Write($"{value:000}{extra}"); + // Console.Write($"{value:000}{extra}"); } Console.WriteLine(); }