solve or inv starts

This commit is contained in:
Youmu Liu
2026-01-13 18:25:25 +08:00
parent ad3b2212fa
commit f133cc9147
11 changed files with 103 additions and 147 deletions
+31 -33
View File
@@ -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);
}
/// <summary>
/// Set _data to current vertex BufferHandle object
/// </summary>
/// <typeparam _label="TItem">
/// Type of bufferData
/// </typeparam>
/// <param _label="index">
/// Index to find certain VBO in this instance
/// </param>
/// <param _label="bufferData">
/// Data to write in
/// </param>
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteMatrixData<T>(int index, ref IMatrix<T> bufferData, BufferUsage usage)
where T: unmanaged, INumber<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferData(BufferType.ArrayBuffer, bufferData.AsSpan(), usage);
}
/// <summary>
/// Set _data to current vertex BufferHandle object
/// </summary>
@@ -100,7 +83,11 @@ namespace StgSharp.Graphics.OpenGL
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteScalerData<T>(int index, T[] bufferArray, BufferUsage usage) where T: unmanaged, INumber<T>
public void WriteScalerData<T>(
int index,
T[] bufferArray,
BufferUsage usage
) where T : unmanaged, INumber<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferData(BufferType.ArrayBuffer, bufferArray, usage);
@@ -121,8 +108,11 @@ namespace StgSharp.Graphics.OpenGL
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteScalerData<T>(int index, ReadOnlySpan<T> scalerSpan, BufferUsage usage)
where T: unmanaged,INumber<T>
public void WriteScalerData<T>(
int index,
ReadOnlySpan<T> scalerSpan,
BufferUsage usage
) where T : unmanaged,INumber<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferData(BufferType.ArrayBuffer, scalerSpan, usage);
@@ -143,8 +133,11 @@ namespace StgSharp.Graphics.OpenGL
/// <param _label="usage">
/// How OpenGL use these data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteVectorData<T>(int index, ReadOnlySpan<T> vectorSpan, BufferUsage usage)
where T: unmanaged, IUnmanagedVector<T>
public void WriteVectorData<T>(
int index,
ReadOnlySpan<T> vectorSpan,
BufferUsage usage
) where T : unmanaged, IUnmanagedVector<T>
{
GL.BindBuffer(BufferType.ArrayBuffer, _bufferHandle[index]);
GL.SetBufferVectorData(BufferType.ArrayBuffer, vectorSpan, usage);
@@ -165,14 +158,19 @@ namespace StgSharp.Graphics.OpenGL
/// <param _label="usage">
/// How OpenGL use these _data, defined by <see cref="BufferUsage" />
/// </param>
public void WriteVectorData<T>(int index, T[] vectorArray, BufferUsage usage)
where T: unmanaged, IUnmanagedVector<T>
public void WriteVectorData<T>(
int index,
T[] vectorArray,
BufferUsage usage
) where T : unmanaged, IUnmanagedVector<T>
{
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);
@@ -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<Matrix44>, IMatrix<float>, IEnumerable<Vec4>
[StructLayout(LayoutKind.Explicit, Size = (16 * sizeof(float)), Pack = 16)]
public unsafe struct Matrix44 : IEquatable<Matrix44>
{
[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<Vec4> IEnumerable<Vec4>.GetEnumerator()
{
for (int i = 0; i < 4; i++) {
yield return column[i];
}
}
[InlineArray(4)]
internal struct Column
{
@@ -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<TElement> where TElement: unmanaged, INumber<TElement>
public enum MatrixElementType : int
{
ReadOnlySpan<TElement> AsSpan();
F32 = 0,
F64 = 1,
I32 = 2,
I64 = 3,
}
}
@@ -27,6 +27,7 @@
// -----------------------------------------------------------------------
using StgSharp.HighPerformance;
using StgSharp.Internal;
using StgSharp.Mathematics.Linear;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -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
{
+1 -1
View File
@@ -159,7 +159,7 @@
<ClCompile Include="sn-src\m.basic.x86.c" />
<ClCompile Include="sn-src\dllmain.c" />
<ClCompile Include="sn-src\m.bufop.x86.c" />
<ClCompile Include="sn-src\m.pivot.x86.c" />
<ClCompile Include="sn-src\m.solve.x86.c" />
<ClCompile Include="sn-src\m.fma_tile.x86.c" />
<ClCompile Include="sn-src\s.factorial.x86.c" />
<ClCompile Include="sn-src\m.fma.x86.c" />
@@ -57,7 +57,7 @@
<ClCompile Include="sn-src\m.panel.x86.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="sn-src\m.pivot.x86.c">
<ClCompile Include="sn-src\m.solve.x86.c">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="sn-src\cpuid.x86.c">
@@ -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);
-70
View File
@@ -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
+45
View File
@@ -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
+7 -7
View File
@@ -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();
}