solve or inv starts
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
+9
-9
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user