swiss ok, needs more benchmark

This commit is contained in:
Youmu Liu
2026-03-06 18:22:30 +08:00
parent 83997f64d0
commit f6e897ed06
70 changed files with 1889 additions and 3371 deletions
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Angle"
// Project: StgSharp
@@ -37,46 +37,60 @@ namespace StgSharp.Mathematics
public static partial class GeometryScaler
{
internal const float DegToRad = 180 / Scalar.Pi;
internal const float DegToRad = 180 / MathF.PI;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Cos(Radius r)
public static float Cos(
Radius r
)
{
return MathF.Cos(r._radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Cos(Degree r)
public static float Cos(
Degree r
)
{
return MathF.Cos(r._degree / DegToRad);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Sin(Radius r)
public static float Sin(
Radius r
)
{
return MathF.Sin(r._radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Sin(Degree r)
public static float Sin(
Degree r
)
{
return MathF.Sin(r._degree / DegToRad);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Tan(Radius r)
public static float Tan(
Radius r
)
{
return MathF.Tan(r._radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Tan(Degree r)
public static float Tan(
Degree r
)
{
return MathF.Tan(r._degree / DegToRad);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Degree ToDegree(float value)
public static Degree ToDegree(
float value
)
{
return new Degree(value);
}
@@ -88,12 +102,16 @@ namespace StgSharp.Mathematics
internal float _degree;
public Degree(float dgree)
public Degree(
float dgree
)
{
_degree = dgree;
}
public static implicit operator Radius(Degree d)
public static implicit operator Radius(
Degree d
)
{
return new Radius(d._degree / GeometryScaler.DegToRad);
}
@@ -108,7 +126,9 @@ namespace StgSharp.Mathematics
[Obsolete("Unsafe, you may forget this is radius.", true)]
public Radius() { }
public Radius(float radius)
public Radius(
float radius
)
{
_radius = radius;
}
@@ -119,56 +139,81 @@ namespace StgSharp.Mathematics
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Radius operator -(Radius r)
public static Radius operator -(
Radius r
)
{
return new Radius(-r._radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Radius operator -(Radius left, Radius Right)
public static Radius operator -(
Radius left,
Radius Right
)
{
return new Radius(left._radius - Right._radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Radius left, Radius right)
public static bool operator !=(
Radius left,
Radius right
)
{
return left._radius != right._radius;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Radius operator *(Radius left, float right)
public static Radius operator *(
Radius left,
float right
)
{
return new Radius(left._radius * right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Radius operator /(Radius left, float right)
public static Radius operator /(
Radius left,
float right
)
{
return new Radius(left._radius / right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float operator /(Radius left, Radius right)
public static float operator /(
Radius left,
Radius right
)
{
return left._radius / right._radius;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Radius operator +(Radius left, Radius Right)
public static Radius operator +(
Radius left,
Radius Right
)
{
return new Radius(left._radius + Right._radius);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Radius left, Radius right)
public static bool operator ==(
Radius left,
Radius right
)
{
return left._radius == right._radius;
}
public static implicit operator Degree(Radius r)
public static implicit operator Degree(
Radius r
)
{
return new Degree((r._radius * 180) / Scalar.Pi);
return new Degree(r._radius * 180 / MathF.PI);
}
}
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Tan"
// file="Global"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
@@ -25,19 +25,12 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
global using StgSharp.Internal;
global using StgSharp.Mathematics.Internal;
global using System;
global using System.Numerics;
global using System.Threading;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Tan(float x)
{
return MathF.Tan(x);
}
}
}
[assembly: InternalsVisibleTo("StgSharp.Graphics")]
+33 -22
View File
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="MatrixPanel"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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
@@ -25,14 +25,14 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal;
using StgSharp.Mathematics.Internal;
using StgSharp.Mathematics.Numeric;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
namespace StgSharp.Mathematics.Numeric
{
public unsafe struct MatrixPanel
{
@@ -42,37 +42,41 @@ namespace StgSharp.Mathematics
private byte Head;
// Allocate aligned memory for one panel; caller must free via Destroy.
public static unsafe MatrixPanel<T>* Create<T>() where T: unmanaged, INumber<T>
public static unsafe MatrixPanel<T>* Create<T>() where T : unmanaged, INumber<T>
{
return (MatrixPanel<T>*)NativeMemory.AlignedAlloc(Size<T>(), AlignmentBytes);
}
public static unsafe void Destroy<T>(MatrixPanel<T>* panel) where T: unmanaged, INumber<T>
public static unsafe void Destroy<T>(
MatrixPanel<T>* panel
) where T : unmanaged, INumber<T>
{
NativeMemory.AlignedFree(panel);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Span<T> Elements<T>(ref T head) where T: unmanaged, INumber<T>
public static unsafe Span<T> Elements<T>(
ref T head
) where T : unmanaged, INumber<T>
{
void* p = Unsafe.AsPointer(ref head);
return new Span<T>(p, MaxElementCount<T>());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int ElementSideLength<T>() where T: unmanaged, INumber<T>
public static int ElementSideLength<T>() where T : unmanaged, INumber<T>
{
return PanelSideLength<T>();
}
public static int MaxElementCount<T>() where T: unmanaged, INumber<T>
public static int MaxElementCount<T>() where T : unmanaged, INumber<T>
{
int side = ElementSideLength<T>();
return side * side;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static nuint Size<T>() where T: unmanaged, INumber<T>
public static nuint Size<T>() where T : unmanaged, INumber<T>
{
return (nuint)(MaxElementCount<T>() * sizeof(T));
}
@@ -81,7 +85,7 @@ namespace StgSharp.Mathematics
/// Number of 4x4 kernels that fit in a panel for the given ISA and element T.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int KernelCapacity<T>() where T: unmanaged, INumber<T>
internal static int KernelCapacity<T>() where T : unmanaged, INumber<T>
{
int perSide = KernelSideCount<T>();
return perSide * perSide;
@@ -91,9 +95,9 @@ namespace StgSharp.Mathematics
/// How many 4x4 kernels fit along a single panel dimension for the given ISA.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int KernelSideCount<T>() where T: unmanaged, INumber<T>
internal static int KernelSideCount<T>() where T : unmanaged, INumber<T>
{
SIMDID id = NumericalModule.IntrinsicMask;
SIMDID id = NumericalModule.GlobalIntrinsicMask;
switch (id.MaskByte[0] & 0b_00001111)
{
case 1:
@@ -110,31 +114,35 @@ namespace StgSharp.Mathematics
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe nuint Align64(void* p)
private static unsafe nuint Align64(
void* p
)
{
return ((nuint)p + (AlignmentBytes - 1)) & ~(nuint)(AlignmentBytes - 1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int KernelSideCountAvx2<T>() where T: unmanaged, INumber<T>
private static int KernelSideCountAvx2<T>() where T : unmanaged, INumber<T>
{
return PanelSideFromBits<T>(256) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int KernelSideCountAvx512<T>() where T: unmanaged, INumber<T>
private static int KernelSideCountAvx512<T>() where T : unmanaged, INumber<T>
{
return PanelSideFromBits<T>(512) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int KernelSideCountSse<T>() where T: unmanaged, INumber<T>
private static int KernelSideCountSse<T>() where T : unmanaged, INumber<T>
{
return PanelSideFromBits<T>(128) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int PanelSideFromBits<T>(int vectorBits) where T: unmanaged, INumber<T>
private static int PanelSideFromBits<T>(
int vectorBits
) where T : unmanaged, INumber<T>
{
int elemBits = sizeof(T) * 8;
@@ -146,9 +154,9 @@ namespace StgSharp.Mathematics
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int PanelSideLength<T>() where T: unmanaged, INumber<T>
private static int PanelSideLength<T>() where T : unmanaged, INumber<T>
{
SIMDID id = NumericalModule.IntrinsicMask;
SIMDID id = NumericalModule.GlobalIntrinsicMask;
switch (id.MaskByte[0] & 0b_00001111)
{
case 1:
@@ -167,12 +175,15 @@ namespace StgSharp.Mathematics
}
// Single POD-style panel: ZMM-compatible size. Alignment handled by allocator, not by the struct.
public unsafe struct MatrixPanel<T> where T: unmanaged, INumber<T>
public unsafe struct MatrixPanel<T> where T : unmanaged, INumber<T>
{
internal T Head; // first element of the panel buffer
public ref T this[int column, int row]
public ref T this[
int column,
int row
]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.Add(ref Head, row * MatrixPanel.ElementSideLength<T>() + column);
@@ -39,14 +39,20 @@ namespace StgSharp.Mathematics.Internal
[FieldOffset(0)]public MatrixKernel* Mat1; // 8
[FieldOffset(8)] public MatrixKernel* Mat2; // 8
[FieldOffset(16)] public MatrixKernel* Mat3; // 16
[FieldOffset(32)] public int CommonX;
[FieldOffset(40)] public int Common_k;
[FieldOffset(32)] public int CommonX;
[FieldOffset(36)] public int CommonY;
[FieldOffset(44)] public int i;
[FieldOffset(48)] public int j;
[FieldOffset(52)] public int k;
[FieldOffset(56)] public MatrixElementType ElementType; // 56
[FieldOffset(24)] public nint Span; // 24
[FieldOffset(64)] public ScalarPacket Scalar;
public MatrixParallelTask()
{
Unsafe.SkipInit(out this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy(
+17 -5
View File
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="UnsafeCompute"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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
@@ -25,6 +25,7 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Mathematics.Numeric;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics.Internal
@@ -33,19 +34,30 @@ namespace StgSharp.Mathematics.Internal
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int CityHashSimplify(char* span, int length)
public static unsafe int CityHashSimplify(
char* span,
int length
)
{
return NumericalModule.GlobalContext.city_hash_simplify(span, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int CityHashSimplify(char* span, int begin, int length)
public static unsafe int CityHashSimplify(
char* span,
int begin,
int length
)
{
return NumericalModule.GlobalContext.city_hash_simplify(span + begin, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int IndexOfCharPair(char* source, int pairValue, int length)
public static unsafe int IndexOfCharPair(
char* source,
int pairValue,
int length
)
{
return NumericalModule.GlobalContext.index_pair(source, pairValue, length);
}
@@ -32,15 +32,21 @@ namespace StgSharp.Mathematics.Graphics
public static unsafe partial class Linear
{
public static float GetAngle(Vec2 vec1, Vec2 vec2)
public static float GetAngle(
Vec2 vec1,
Vec2 vec2
)
{
return Scalar.ACos(
return MathF.Acos(
1 / (vec1.GetLength() * vec2.GetLength()));
}
public static float GetAngle(Vec3 vec1, Vec3 vec2)
public static float GetAngle(
Vec3 vec1,
Vec3 vec2
)
{
return Scalar.ACos((vec1 * vec2) / (vec1.GetLength() * vec2.GetLength()));
return MathF.Acos(vec1 * vec2 / (vec1.GetLength() * vec2.GetLength()));
}
}
@@ -32,14 +32,18 @@ namespace StgSharp.Mathematics.Graphics
public static unsafe partial class Linear
{
public static float GetLength(this Vec3 vec)
public static float GetLength(
this Vec3 vec
)
{
return Scalar.Sqrt(vec.Dot(vec));
return MathF.Sqrt(vec.Dot(vec));
}
public static float GetLength(this Vec2 vec)
public static float GetLength(
this Vec2 vec
)
{
return Scalar.Sqrt(vec.Dot(vec));
return MathF.Sqrt(vec.Dot(vec));
}
}
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="SignOf"
// file="Exception"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
@@ -28,38 +28,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics
namespace StgSharp.Mathematics.Numeric
{
public static unsafe partial class Scalar
public class MatrixDimensionMismatchException<T> : Exception where T : unmanaged, INumber<T>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int SignOf(float x)
{
if (x == 0) {
return 0;
}
if (x > 0) {
return 1;
}
return -1;
}
public MatrixDimensionMismatchException(
Matrix<T> right,
Matrix<T> ans
)
: base($"""
Matrix dimensions must agree but current:
right({right?.ColumnLength ?? 0}×{right?.RowLength ?? 0}),
ans({ans?.ColumnLength ?? 0}×{ans?.RowLength ?? 0})
"""
) { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int SignOf(int x)
{
if (x == 0) {
return 0;
}
if (x > 0) {
return 1;
}
return -1;
}
public MatrixDimensionMismatchException(
Matrix<T> left,
Matrix<T> right,
Matrix<T> ans
)
: base($"""
Matrix dimensions must agree but current:
left({left?.ColumnLength ?? 0}×{left?.RowLength ?? 0}),
right({right?.ColumnLength ?? 0}×{right?.RowLength ?? 0}),
ans({ans?.ColumnLength ?? 0}×{ans?.RowLength ?? 0})
"""
) { }
}
}
+62 -41
View File
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="Matrix"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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
@@ -29,17 +29,17 @@ using StgSharp.Mathematics;
using StgSharp.Mathematics.Numeric;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
// using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
using System.Runtime.CompilerServices;
// using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
namespace StgSharp.Mathematics.Numeric
{
public unsafe partial class Matrix<T> where T: unmanaged, INumber<T>
public unsafe partial class Matrix<T> where T : unmanaged, INumber<T>
{
private protected static readonly int t_count = 16 / sizeof(T);
private protected static readonly int t_count = 16 / sizeof(T);
private protected static readonly int t_size = sizeof(T);
private readonly MatrixKernelBoarder _boarder;
private readonly MatrixSize _size;
@@ -48,8 +48,8 @@ namespace StgSharp.Mathematics.Numeric
private protected Matrix(
MatrixKernelBoarder boarder,
MatrixSize size,
MatrixStorage<T> buffer
MatrixStorage<T> buffer
)
{
_boarder = boarder;
@@ -57,7 +57,10 @@ namespace StgSharp.Mathematics.Numeric
_buffer = buffer;
}
public T this[int x, int y]
public T this[
int x,
int y
]
{
get
{
@@ -78,40 +81,43 @@ namespace StgSharp.Mathematics.Numeric
long offset = GetElementOffset(x, y);
if (offset < 0) {
return;
}
}
((T*)Buffer)[offset] = value;
}
}
}
/// <summary>
/// Matlab style indexer to generate a new matrix
/// </summary>
/// </summary>
/// <param name="column">
///
/// </param>
/// </param>
/// <param name="row">
///
/// </param>
/// </param>
/// <returns>
///
/// </returns>
/// </returns>
/// <exception cref="NotImplementedException">
///
/// </exception>
public unsafe Matrix<T> this[ReadOnlySpan<MatrixIndex> column, ReadOnlySpan<MatrixIndex> row]
/// </exception>
public unsafe Matrix<T> this[
ReadOnlySpan<MatrixIndex> column,
ReadOnlySpan<MatrixIndex> row
]
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
/// <summary>
/// Length of the matrix in columns.
/// </summary>
public int ColumnLength => _size.ElementColumnLength;
/// </summary>
public int ColumnLength => _size.ElementColumnLength;
/// <summary>
/// Length of the matrix in rows.
/// </summary>
/// </summary>
public int RowLength => _size.ElementRowLength;
public MatrixLayout Layout { get; init; }
@@ -127,49 +133,64 @@ namespace StgSharp.Mathematics.Numeric
protected internal int KernelRowLength => _size.KernelRowLength;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe ref MatrixKernel<T> GetMatrixKernel(int x, int y)
public unsafe ref MatrixKernel<T> GetMatrixKernel(
int x,
int y
)
{
return ref _boarder.IsInBuffer(x, y, in _size) ?
ref _buffer[_boarder.GetIndexOffset(x, y, in _size)] :
ref Unsafe.NullRef<MatrixKernel<T>>();
}
internal long GetElementOffset(int x, int y)
internal long GetElementOffset(
int x,
int y
)
{
int
k_c = y / 4,
c = y % 4,
k_r = x / 4,
int
k_c = y / 4,
c = y % 4,
k_r = x / 4,
r = x % 4;
if (!_boarder.IsInBuffer(k_r, k_c, in _size)) {
return -1;
}
long kernelOffset = _boarder.GetIndexOffset(k_r, k_c, in _size);
long kernelOffset = _boarder.GetIndexOffset(k_r, k_c, in _size);
return kernelOffset * 16 + 4 * r + c;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe ref T GetElementUnsafe(int x, int y)
internal unsafe ref T GetElementUnsafe(
int x,
int y
)
{
// Caller guarantees: indices in range, layout is dense square.
int k_c = y / 4;
int k_r = x / 4;
int c = y % 4;
int r = x % 4;
int r = x % 4;
ref MatrixKernel<T> kernel = ref _buffer[_boarder.GetIndexOffset(k_r, k_c, in _size)];
return ref kernel[c, r];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe MatrixKernel<T>* GetKernelAddressUnsafe(int x, int y)
internal unsafe MatrixKernel<T>* GetKernelAddressUnsafe(
int x,
int y
)
{
return Buffer + _boarder.GetIndexOffset(x, y, in _size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe ref MatrixKernel<T> GetKernelUnsafe(int x, int y)
internal unsafe ref MatrixKernel<T> GetKernelUnsafe(
int x,
int y
)
{
// Caller guarantees: indices in range, layout is dense square.
int k_c = y / 4;
@@ -180,4 +201,4 @@ namespace StgSharp.Mathematics.Numeric
}
}
}
}
@@ -1,160 +1,160 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute.Factorize"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public static partial class MatrixCompute
{
public static unsafe void FactorizePLU(
Matrix<float> matrix,
Span<int> pivot,
Matrix<float> lower,
Matrix<float> upper
)
{
if (matrix.ColumnLength != matrix.RowLength) {
throw new InvalidOperationException("Matrix must be square.");
}
if (matrix.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense square matrices are supported.");
}
int n = matrix.RowLength;
if (pivot.Length < n) {
throw new ArgumentException("Pivot span length is insufficient.", nameof(pivot));
}
if (lower.RowLength != n ||
lower.ColumnLength != n ||
lower.Layout != MatrixLayout.UpperTriangle) {
throw new ArgumentException("Lower matrix must be lower-triangular with same dimensions as input.", nameof(lower));
}
if (upper.RowLength != n ||
upper.ColumnLength != n ||
upper.Layout != MatrixLayout.UpperTriangle) {
throw new ArgumentException("Upper matrix must be upper-triangular with same dimensions as input.", nameof(upper));
}
int size = matrix.KernelColumnLength * matrix.KernelRowLength;
if (size < 256)
{
for (int i = 0; i < n; i++)
{
pivot[i] = i; // identity permutation
}
// Aggressive: always call native pivot to fetch four-column candidates
ulong* pivots = stackalloc ulong[4];
for (int kBlock = 0; kBlock < n; kBlock += 4)
{
NumericalModule.GlobalContext
.mat_sk[(int)MatrixElementType.F32].pivot(matrix.Buffer,
(ulong)(kBlock >> 2),
(ulong)(matrix.KernelRowLength - (kBlock >> 2)),
(ulong)pivots);
int colsInBlock = Math.Min(4, n - kBlock);
for (int offset = 0; offset < colsInBlock; offset++)
{
int k = kBlock + offset;
int pivotRow = k;
float maxAbs;
int candidateRow = (int)pivots[offset];
int idx = -1;
for (int r = k; r < n; r++)
{
if (pivot[r] == candidateRow)
{
idx = r;
break;
}
}
if (idx != -1)
{
pivotRow = idx;
maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[idx], k));
} else
{
maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[k], k));
for (int r = k + 1; r < n; r++)
{
float val = MathF.Abs(matrix.GetElementUnsafe(pivot[r], k));
if (val > maxAbs)
{
maxAbs = val;
pivotRow = r;
}
}
}
if (maxAbs == 0f) {
throw new InvalidOperationException("Zero pivot encountered in PLU.");
}
if (pivotRow != k) {
(pivot[k], pivot[pivotRow]) = (pivot[pivotRow], pivot[k]);
}
lower[k, k] = 1.0f; // unit diagonal for L
// Compute U[k, j] for j >= k
for (int j = k; j < n; j++)
{
float sum = 0f;
for (int s = 0; s < k; s++) {
sum += lower[k, s] * upper[s, j];
}
upper[k, j] = matrix.GetElementUnsafe(pivot[k], j) - sum;
}
// Compute L[i, k] for i > k
for (int i = k + 1; i < n; i++)
{
float sum = 0f;
for (int s = 0; s < k; s++) {
sum += lower[i, s] * upper[s, k];
}
float u = upper[k, k];
if (u == 0f) {
throw new InvalidOperationException("Zero pivot encountered in PLU.");
}
lower[i, k] = (matrix.GetElementUnsafe(pivot[i], k) - sum) / u;
}
}
}
// TODO: For larger kernels, consider calling native pivot helper to extract 4 pivots at once.
} else if (size < 1024) { } else { }
}
}
}
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute.Factorize"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public static partial class MatrixCompute
{
public static unsafe void FactorizePLU(
Matrix<float> matrix,
Span<int> pivot,
Matrix<float> lower,
Matrix<float> upper
)
{
if (matrix.ColumnLength != matrix.RowLength) {
throw new InvalidOperationException("Matrix must be square.");
}
if (matrix.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense square matrices are supported.");
}
int n = matrix.RowLength;
if (pivot.Length < n) {
throw new ArgumentException("Pivot span length is insufficient.", nameof(pivot));
}
if (lower.RowLength != n ||
lower.ColumnLength != n ||
lower.Layout != MatrixLayout.UpperTriangle) {
throw new ArgumentException("Lower matrix must be lower-triangular with same dimensions as input.", nameof(lower));
}
if (upper.RowLength != n ||
upper.ColumnLength != n ||
upper.Layout != MatrixLayout.UpperTriangle) {
throw new ArgumentException("Upper matrix must be upper-triangular with same dimensions as input.", nameof(upper));
}
int size = matrix.KernelColumnLength * matrix.KernelRowLength;
if (size < 256)
{
for (int i = 0; i < n; i++)
{
pivot[i] = i; // identity permutation
}
// Aggressive: always call native pivot to fetch four-column candidates
ulong* pivots = stackalloc ulong[4];
for (int kBlock = 0; kBlock < n; kBlock += 4)
{
NumericalModule.GlobalContext
.mat_sk[(int)MatrixElementType.F32].pivot(matrix.Buffer,
(ulong)(kBlock >> 2),
(ulong)(matrix.KernelRowLength - (kBlock >> 2)),
(ulong)pivots);
int colsInBlock = Math.Min(4, n - kBlock);
for (int offset = 0; offset < colsInBlock; offset++)
{
int k = kBlock + offset;
int pivotRow = k;
float maxAbs;
int candidateRow = (int)pivots[offset];
int idx = -1;
for (int r = k; r < n; r++)
{
if (pivot[r] == candidateRow)
{
idx = r;
break;
}
}
if (idx != -1)
{
pivotRow = idx;
maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[idx], k));
} else
{
maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[k], k));
for (int r = k + 1; r < n; r++)
{
float val = MathF.Abs(matrix.GetElementUnsafe(pivot[r], k));
if (val > maxAbs)
{
maxAbs = val;
pivotRow = r;
}
}
}
if (maxAbs == 0f) {
throw new InvalidOperationException("Zero pivot encountered in PLU.");
}
if (pivotRow != k) {
(pivot[k], pivot[pivotRow]) = (pivot[pivotRow], pivot[k]);
}
lower[k, k] = 1.0f; // unit diagonal for L
// Compute U[k, j] for j >= k
for (int j = k; j < n; j++)
{
float sum = 0f;
for (int s = 0; s < k; s++) {
sum += lower[k, s] * upper[s, j];
}
upper[k, j] = matrix.GetElementUnsafe(pivot[k], j) - sum;
}
// Compute L[i, k] for i > k
for (int i = k + 1; i < n; i++)
{
float sum = 0f;
for (int s = 0; s < k; s++) {
sum += lower[i, s] * upper[s, k];
}
float u = upper[k, k];
if (u == 0f) {
throw new InvalidOperationException("Zero pivot encountered in PLU.");
}
lower[i, k] = (matrix.GetElementUnsafe(pivot[i], k) - sum) / u;
}
}
}
// TODO: For larger kernels, consider calling native pivot helper to extract 4 pivots at once.
} else if (size < 1024) { } else { }
}
}
}
@@ -1,314 +1,314 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute.Float"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Collections;
using StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Numerics;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public static partial class MatrixCompute
{
public static unsafe void Add(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Mat1 = (MatrixKernel*)left.Buffer;
package->Mat2 = (MatrixKernel*)right.Buffer;
package->Mat3 = (MatrixKernel*)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_add;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Fill(
Matrix<float> ans,
float value
)
{
MatrixElementType f32 = MatrixElementType.F32;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<float>(0) = value;
if (count <= 256)
{
NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_fill;
package->Scalar = scalar;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
MatrixParallelFactory.Release(scalar);
taskGroup.Dispose();
}
public static unsafe void Mul(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
// For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN
// ColumnLength = number of columns (N), RowLength = number of rows (M)
if (left.ColumnLength != right.RowLength ||
ans.ColumnLength != right.ColumnLength ||
ans.RowLength != left.RowLength)
{
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
right.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 1024)
{
MatrixParallelThread[] pool = null;
if (count > 256) {
pool = MatrixParallel.LeadParallel(1);
}
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = left.KernelColumnLength;
enumeration->Member<int>(3) = ans.KernelColumnLength;
for (int i = 0; i < ans.KernelRowLength; i++)
{
for (int j = 0; j < ans.KernelColumnLength; j++)
{
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext
.mat_sk[f32].kernel_tile_fma((MatrixKernel*)left.Buffer,
(MatrixKernel*)right.Buffer,
(MatrixKernel*)ans.Buffer,
enumeration);
}
}
if (count > 256) {
MatrixParallel.ReturnParallelResources(ref pool!);
}
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->AnsPrimOffset = ans.KernelRowLength;
package->AnsSecOffset = ans.KernelColumnLength;
package->LeftPrimOffset = left.KernelColumnLength;
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ElementSize = (int)MatrixElementType.F32;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA);
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Mul(
Matrix<float> left,
float right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<float>(0) = right;
if (count <= 256)
{
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Right = (nint)left.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->Scalar = scalar;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
MatrixParallelFactory.Release(scalar);
return;
}
public static unsafe void Sub(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
right.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_sub;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
}
}
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute.Float"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Collections;
using StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Numerics;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public static partial class MatrixCompute
{
public static unsafe void Add(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Mat1 = (MatrixKernel*)left.Buffer;
package->Mat2 = (MatrixKernel*)right.Buffer;
package->Mat3 = (MatrixKernel*)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_add;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Fill(
Matrix<float> ans,
float value
)
{
MatrixElementType f32 = MatrixElementType.F32;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<float>(0) = value;
if (count <= 256)
{
NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_fill;
package->Scalar = scalar;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
MatrixParallelFactory.Release(scalar);
taskGroup.Dispose();
}
public static unsafe void Mul(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
// For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN
// ColumnLength = number of columns (N), RowLength = number of rows (M)
if (left.ColumnLength != right.RowLength ||
ans.ColumnLength != right.ColumnLength ||
ans.RowLength != left.RowLength)
{
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
right.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 1024)
{
MatrixParallelThread[] pool = null;
if (count > 256) {
pool = MatrixParallel.LeadParallel(1);
}
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = left.KernelColumnLength;
enumeration->Member<int>(3) = ans.KernelColumnLength;
for (int i = 0; i < ans.KernelRowLength; i++)
{
for (int j = 0; j < ans.KernelColumnLength; j++)
{
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext
.mat_sk[f32].kernel_tile_fma((MatrixKernel*)left.Buffer,
(MatrixKernel*)right.Buffer,
(MatrixKernel*)ans.Buffer,
enumeration);
}
}
if (count > 256) {
MatrixParallel.ReturnParallelResources(ref pool!);
}
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->AnsPrimOffset = ans.KernelRowLength;
package->AnsSecOffset = ans.KernelColumnLength;
package->LeftPrimOffset = left.KernelColumnLength;
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ElementSize = (int)MatrixElementType.F32;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA);
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Mul(
Matrix<float> left,
float right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<float>(0) = right;
if (count <= 256)
{
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Right = (nint)left.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->Scalar = scalar;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
MatrixParallelFactory.Release(scalar);
return;
}
public static unsafe void Sub(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
{
MatrixElementType f32 = MatrixElementType.F32;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
right.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<float>* leftPtr = left.Buffer;
MatrixKernel<float>* rightPtr = right.Buffer;
MatrixKernel<float>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_sub;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
}
}
@@ -1,55 +1,55 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute"
// 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 StgSharp.Internal;
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixCompute
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe MatrixKernel* GetKernelAddressUnsafe<T>(
MatrixKernel<T>* buffer,
int colLength,
int x,
int y)
where T: unmanaged, INumber<T>
{
return (MatrixKernel*)(buffer + (colLength * x + y));
}
}
}
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute"
// 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 StgSharp.Internal;
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixCompute
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe MatrixKernel* GetKernelAddressUnsafe<T>(
MatrixKernel<T>* buffer,
int colLength,
int x,
int y)
where T: unmanaged, INumber<T>
{
return (MatrixKernel*)(buffer + (colLength * x + y));
}
}
}
@@ -1,303 +1,320 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute.double"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixCompute
{
public static unsafe void Add(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_add(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_add(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_add;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Fill(
Matrix<double> ans,
double value
)
{
int f64 = (int)MatrixElementType.F64;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<double>(0) = value;
if (count <= 256)
{
NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_fill;
package->Scalar = scalar;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
MatrixParallelFactory.Release(scalar);
taskGroup.Dispose();
}
public static unsafe void Mul(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
// For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN
// ColumnLength = number of columns (N), RowLength = number of rows (M)
if (left.ColumnLength != right.RowLength ||
ans.ColumnLength != right.ColumnLength ||
ans.RowLength != left.RowLength)
{
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 1024)
{
MatrixParallelThread[] pool = null;
if (count > 256) {
pool = MatrixParallel.LeadParallel(1);
}
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = left.KernelColumnLength;
enumeration->Member<int>(3) = ans.KernelColumnLength;
for (int i = 0; i < ans.KernelRowLength; i++)
{
for (int j = 0; j < ans.KernelColumnLength; j++)
{
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext
.mat_sk[f64].kernel_tile_fma((MatrixKernel*)left.Buffer,
(MatrixKernel*)right.Buffer,
(MatrixKernel*)ans.Buffer,
enumeration);
}
}
if (count > 256) {
MatrixParallel.ReturnParallelResources(ref pool!);
}
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->AnsPrimOffset = ans.KernelRowLength;
package->AnsSecOffset = ans.KernelColumnLength;
package->LeftPrimOffset = left.KernelColumnLength;
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ElementSize = (int)MatrixElementType.F64;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA);
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Mul(
Matrix<double> left,
double right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<double>(0) = right;
if (count <= 256)
{
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Right = (nint)left.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->Scalar = scalar;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
MatrixParallelFactory.Release(scalar);
return;
}
public static unsafe void Sub(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
right.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_sub;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
}
}
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixCompute.double"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using unsafe MkProc = delegate* unmanaged[Cdecl]<StgSharp.Mathematics.Internal.MatrixParallelTask, void>;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixCompute
{
public static unsafe void Add(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
{
MatrixElementType f64 = MatrixElementType.F64;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new MatrixDimensionMismatchException<double>(
left, right, ans
);
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
MkProc add = (MkProc)NumericalModule.GlobalContext.
mat_mk[f64.IntrinsicNode].
Get(MatrixIntrinsicHandle.Add);
for (int i = 0; i < count; i++) {
add(new MatrixParallelTask
{
Mat1 = (MatrixKernel*)(leftPtr + i),
Mat2 = (MatrixKernel*)(rightPtr + i),
Mat3 = (MatrixKernel*)(ansPtr + i),
ElementType = MatrixElementType.F64,
});
}
// .buffer_add(leftPtr, rightPtr, ansPtr, count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_add(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_add;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Fill(
Matrix<double> ans,
double value
)
{
int f64 = (int)MatrixElementType.F64;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<double>(0) = value;
if (count <= 256)
{
NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_fill;
package->Scalar = scalar;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
MatrixParallelFactory.Release(scalar);
taskGroup.Dispose();
}
public static unsafe void Mul(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
// For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN
// ColumnLength = number of columns (N), RowLength = number of rows (M)
if (left.ColumnLength != right.RowLength ||
ans.ColumnLength != right.ColumnLength ||
ans.RowLength != left.RowLength)
{
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 1024)
{
MatrixParallelThread[] pool = null;
if (count > 256) {
pool = MatrixParallel.LeadParallel(1);
}
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = left.KernelColumnLength;
enumeration->Member<int>(3) = ans.KernelColumnLength;
for (int i = 0; i < ans.KernelRowLength; i++)
{
for (int j = 0; j < ans.KernelColumnLength; j++)
{
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext
.mat_sk[f64].kernel_tile_fma((MatrixKernel*)left.Buffer,
(MatrixKernel*)right.Buffer,
(MatrixKernel*)ans.Buffer,
enumeration);
}
}
if (count > 256) {
MatrixParallel.ReturnParallelResources(ref pool!);
}
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->AnsPrimOffset = ans.KernelRowLength;
package->AnsSecOffset = ans.KernelColumnLength;
package->LeftPrimOffset = left.KernelColumnLength;
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ElementSize = (int)MatrixElementType.F64;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA);
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
public static unsafe void Mul(
Matrix<double> left,
double right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<double>(0) = right;
if (count <= 256)
{
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Right = (nint)left.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->Scalar = scalar;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
MatrixParallelFactory.Release(scalar);
return;
}
public static unsafe void Sub(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != right.ColumnLength ||
left.RowLength != right.RowLength ||
left.ColumnLength != ans.ColumnLength ||
left.RowLength != ans.RowLength) {
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
}
if (left.Layout != MatrixLayout.DenseRectangle ||
right.Layout != MatrixLayout.DenseRectangle ||
ans.Layout != MatrixLayout.DenseRectangle) {
throw new NotSupportedException("Only dense rectangle matrices are supported.");
}
long count = (long)left.KernelColumnLength * left.KernelRowLength;
if (count <= 256)
{
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
MatrixKernel<double>* leftPtr = left.Buffer;
MatrixKernel<double>* rightPtr = right.Buffer;
MatrixKernel<double>* ansPtr = ans.Buffer;
NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr,
count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Answer = (nint)ans.Buffer;
package->ElementSize = sizeof(double);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM);
package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_sub;
MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package);
taskGroup.LaunchParallel(SleepMode.DeepSleep);
taskGroup.Dispose();
return;
}
}
}
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel.Await"
// Project: StgSharp
@@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
@@ -43,7 +44,9 @@ namespace StgSharp.Mathematics.Numeric
private static volatile int _createGeneration = 0;
private static int _sortState;
public static MatrixParallelThread[] LeadParallel(int recommendCount)
public static MatrixParallelThread[] LeadParallel(
int recommendCount
)
{
int min = int.Min(recommendCount, _threads.Capacity);
min /= 2;
@@ -108,7 +111,9 @@ namespace StgSharp.Mathematics.Numeric
// return ret;
}
public static void ReturnParallelResources(ref MatrixParallelThread[] pool)
public static void ReturnParallelResources(
ref MatrixParallelThread[] pool
)
{
while (true)
{
@@ -123,7 +128,11 @@ namespace StgSharp.Mathematics.Numeric
pool = null!;
}
private record class WaitHandle(int generation, int least, int best)
private record class WaitHandle(
int generation,
int least,
int best
)
{
public int CreateGeneration { get; init; } = generation;
@@ -135,7 +144,9 @@ namespace StgSharp.Mathematics.Numeric
public int Priority { get; private set; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UpdatePriority(int currentGeneration)
public void UpdatePriority(
int currentGeneration
)
{
Priority = (currentGeneration - CreateGeneration) * (MatrixParallel._threads.Capacity - LeastCount);
}
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel.AwaitingQueue"
// Project: StgSharp
@@ -51,19 +51,24 @@ namespace StgSharp.Mathematics.Numeric
public AwaitingQueue() { }
public void Enqueue(WaitHandle handle)
public void Enqueue(
WaitHandle handle
)
{
if (_count > 7)
{
_fallback.Enqueue(handle);
Interlocked.Increment(ref _count);
_ = Interlocked.Increment(ref _count);
return;
}
_quickElements[_count] = handle;
Interlocked.Increment(ref _count);
_ = Interlocked.Increment(ref _count);
}
public bool TryDequeue(int generation, out WaitHandle handle)
public bool TryDequeue(
int generation,
out WaitHandle handle
)
{
if (_count == 0)
{
@@ -83,7 +88,10 @@ namespace StgSharp.Mathematics.Numeric
return true;
}
public bool TryPeek(int generation, out WaitHandle handle)
public bool TryPeek(
int generation,
out WaitHandle handle
)
{
if (_count == 0)
{
@@ -99,7 +107,10 @@ namespace StgSharp.Mathematics.Numeric
return true;
}
public bool TryPopIfRefEqual(int generation, in WaitHandle handle)
public bool TryPopIfRefEqual(
int generation,
in WaitHandle handle
)
{
if (_count == 0) {
return false;
@@ -127,7 +138,9 @@ namespace StgSharp.Mathematics.Numeric
private WaitHandle value;
public static void Sort(ref Element e)
public static void Sort(
ref Element e
)
{
int maxIdx = 0;
WaitHandle first = e[0];
@@ -50,26 +50,22 @@ namespace StgSharp.Mathematics.Numeric
MatrixParallelTask* package
)
{
switch (package->ComputeMode.OperationStyle)
{
case MatrixIndexStyle.BUFFER_INDEX:
return ScheduleBufferTask(package);
default:
throw new InvalidOperationException($"Unknown mode {package->ComputeMode.OperationStyle}.");
}
return ScheduleBufferTask(package);
}
private static unsafe MatrixParallelWrap ScheduleBufferTask(
MatrixParallelTask* package
)
{
/*
int primCount = package->PrimCount;
int secCount = package->SecCount;
long count = (long)primCount * secCount;
/**/
// Console.WriteLine($"amount of kernels is {count}");
long recommendCount = count / 1024;
long recommendCount = /*count / /**/ 1024;
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
MatrixParallelWrap wrap = new MatrixParallelWrap(pool);
wrap.TaskQueue = MatrixParallelQueue.Rent(package);
@@ -1,106 +1,106 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Fma"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
internal static unsafe void ComputeFmaPanelF32(
MatrixParallelTask* p
)
{
int f32 = MatrixElementType.F32.IntrinsicNode;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Fma"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Internal;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
internal static unsafe void ComputeFmaPanelF32(
MatrixParallelTask* p
)
{
int f32 = MatrixElementType.F32.IntrinsicNode;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
int commonK = p->LeftPrimOffset;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
enumeration->Member<int>(3) = ansHeight;
// in this occasion size must be 1
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f32].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
internal static unsafe void ComputeFmaPanelF64(
MatrixParallelTask* p
)
{
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f32].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
internal static unsafe void ComputeFmaPanelF64(
MatrixParallelTask* p
)
{
int f64 = MatrixElementType.F64.IntrinsicNode;
// int size = 1;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
MatrixKernel* leftBuffer = (MatrixKernel*)p->Left;
MatrixKernel* rightBuffer = (MatrixKernel*)p->Right;
MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer;
ref long offsetRef = ref Unsafe.As<int, long>(ref p->PrimTileOffset);
ref long lengthRef = ref Unsafe.As<int, long>(ref p->PrimCount);
int ansWidth = p->AnsPrimOffset;
int ansHeight = p->AnsSecOffset;
int commonK = p->LeftPrimOffset;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
M128* enumeration = stackalloc M128[1];
enumeration->Member<int>(2) = commonK;
enumeration->Member<int>(3) = ansHeight;
// in this occasion size must be 1
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f64].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
}
for (long c = offsetRef; c < offsetRef + lengthRef; c++)
{
int i = (int)(c / ansHeight);
int j = (int)(c % ansHeight);
enumeration->Member<int>(0) = i;
enumeration->Member<int>(1) = j;
NumericalModule.GlobalContext.mat_sk[f64].kernel_tile_fma(leftBuffer, rightBuffer,
ansBuffer, enumeration);
}
}
}
}
@@ -1,76 +1,76 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Model"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
private const int KernelStealCount = 64;
internal unsafe void BufferCompute(
MatrixParallelTask* p
)
{
// while () { }
int size = p->ElementSize * 16;
long count = Unsafe.As<int, long>(ref p->PrimCount);
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
ScalarPacket* scalar = p->Scalar;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelThread.Model"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Mathematics;
using StgSharp.Mathematics.Internal;
using System;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics.Numeric
{
public partial class MatrixParallelThread
{
private const int KernelStealCount = 64;
internal unsafe void BufferCompute(
MatrixParallelTask* p
)
{
// while () { }
int size = p->ElementSize * 16;
long count = Unsafe.As<int, long>(ref p->PrimCount);
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
ScalarPacket* scalar = p->Scalar;
IntPtr computeHandle = _context[p->ComputeHandle];
((delegate* unmanaged[Cdecl]<void*, void*, void*, void*, long, void>)computeHandle)((void*)(p->Left + offset),
(void*)(p->Right + offset),
(void*)(p->Answer + offset),
scalar,
count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe void SpecialBufferCompute(
MatrixParallelTask* p
)
{
switch ((MatrixElementType)p->ElementSize)
{
case MatrixElementType.F64:
ComputeFmaPanelF64(p);
return;
case MatrixElementType.F32:
ComputeFmaPanelF32(p);
break;
default:
break;
}
}
}
((delegate* unmanaged[Cdecl]<void*, void*, void*, void*, long, void>)computeHandle)((void*)(p->Left + offset),
(void*)(p->Right + offset),
(void*)(p->Answer + offset),
scalar,
count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe void SpecialBufferCompute(
MatrixParallelTask* p
)
{
switch ((MatrixElementType)p->ElementSize)
{
case MatrixElementType.F64:
ComputeFmaPanelF64(p);
return;
case MatrixElementType.F32:
ComputeFmaPanelF32(p);
break;
default:
break;
}
}
}
}
@@ -124,9 +124,11 @@ namespace StgSharp.Mathematics.Numeric
// Bind OS-thread affinity once when the worker starts running
SetThreadAffinity(PoolId);
Thread.Yield();
SIMDID feature = new();
feature.Mask = GetSimdId();
_ = Thread.Yield();
SIMDID feature = new()
{
Mask = GetSimdId()
};
_context = (nint*)MatrixParallel.GetContext(feature);
State = MatrixThreadState.Ready;
while (true)
@@ -148,6 +150,7 @@ namespace StgSharp.Mathematics.Numeric
{
MatrixParallelQueue taskQueue = BindedWrap.TaskQueue;
MatrixParallelTask* p = taskQueue.Package;
/*
if (0 > (int)p ->ComputeHandle) {
SpecialBufferCompute(p);
}
@@ -159,6 +162,7 @@ namespace StgSharp.Mathematics.Numeric
default:
break;
}
/**/
BindedWrap.ReportThreadAccomplished();
}
_managedThread.Priority = AfterWork;
@@ -98,9 +98,6 @@ namespace StgSharp.Mathematics.Numeric
MatrixParallelTask* source
)
{
if (source->Scalar != null) {
_scalarAllocator.Free((nuint)source->Scalar);
}
_wrapAllocator.Free((nuint)source);
}
-107
View File
@@ -1,107 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ACos"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float ACos(float x)
{
return MathF.Acos(x);
/*
int sign = 1;
float y;
if (x < 0)
{
sign = -1;
y = -x;
}
else
{
y = x;
}
if (x > 1)
{
throw new ArgumentException();
}
float r, s, u, vec = 0.0f;
bool transform = (y >= 0.5f);
if (transform)
{
r = 0.5f * (1.0f - y);
s = Scaler.Sqrt(r);
y = s;
}
else
{
r = y * y;
}
u = r * (0.184161606965100694821398249421F +
(-0.0565298683201845211985026327361F +
(-0.0133819288943925804214011424456F -
0.00396137437848476485201154797087F * r) * r) * r) /
(1.10496961524520294485512696706F -
0.836411276854206731913362287293F * r);
/*
if (transform)
{
float c, s1, p, q;
uint us;
us = *(uint*)&s;
uint uss = us & 0xffff0000;
s1 = *(float*)&uss;
c = (r - s1 * s1) / (s + s1);
p = 2.0F * s * u - (piby2_tail - 2.0F * c);
q = hpiby2_head - 2.0F * s1;
vec = hpiby2_head - (p - q);
}
else
{
vec = y + y * u;
}
vec = sign * vec;
return piby2 - vec;
*/
}
}
}
-119
View File
@@ -1,119 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ASin"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
private const float
piby2_tail = 7.5497894159e-08f, /* 0x33a22168 */
hpiby2_head = 7.8539812565e-01f, /* 0x3f490fda */
piby2 = 1.5707963705e+00f; /* 0x3fc90fdb */
/// <summary>
/// Reurns the value of ArcSin(x)
/// </summary>
/// <param _label="x">
/// The sine value of the angle
/// </param>
/// <returns>
///
/// </returns>
/// <exception cref="ArgumentException">
///
/// </exception>
public static float ASin(float x)
{
return MathF.Asin(x);
/*
int sign = 1;
float y;
if (x < 0)
{
sign = -1;
y = -x;
}
else
{
y = x;
}
if (x > 1)
{
throw new ArgumentException();
}
float r, s, u, vec = 0.0f;
bool transform = (y >= 0.5f);
if (transform)
{
r = 0.5f * (1.0f - y);
s = Scaler.Sqrt(r);
y = s;
}
else
{
r = y * y;
}
u = r * (0.184161606965100694821398249421F +
(-0.0565298683201845211985026327361F +
(-0.0133819288943925804214011424456F -
0.00396137437848476485201154797087F * r) * r) * r) /
(1.10496961524520294485512696706F -
0.836411276854206731913362287293F * r);
/*
if (transform)
{
float c, s1, p, q;
uint us;
us = *(uint*)&s;
uint uss = us & 0xffff0000;
s1 = *(float*)&uss;
c = (r - s1 * s1) / (s + s1);
p = 2.0F * s * u - (piby2_tail - 2.0F * c);
q = hpiby2_head - 2.0F * s1;
vec = hpiby2_head - (p - q);
}
else
{
vec = y + y * u;
}/*
return sign * vec;
*/
}
}
}
-116
View File
@@ -1,116 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ATan"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float ATan(float x)
{
return MathF.Atan(x);
/*
float sign = 1, angle = 0;
if (x < 0)
{
sign = -1;
x = -x;
}
uint xBit = *(uint*)&x;
int xExp = (int)(xBit >> 23) - 127;
if (xExp >= 26)
{
return 1;
}
if (xExp <= -15)
{
return x;
}
if (xExp >= 0)
{
x = (x - 1) / (x + 1);
angle = 0.7853981634f;
}
float vec = 0.7853981634f * x + x * (1 - x) * (0.2447f + 0.0663f * x);
vec += angle;
vec *= sign;
return vec;
}
public static unsafe float ATan(float x, float y)
{
float z = y / x;
float sign = 1, angle = 0, angle2 = 0;
if (x < 0)
{
angle = -3.1415926535f;
}
if (z < 0)
{
sign = -1;
z = -z;
}
uint zBit = *(uint*)&z;
int zExp = (int)(zBit >> 23) - 127;
if (zExp >= 26)
{
return 1;
}
if (zExp <= -15)
{
return z;
}
if (zExp >= 0)
{
z = (z - 1) / (z + 1);
angle2 = 0.7853981634f;
}
float vec = 0.7853981634f * z + z * (1 - z) * (0.2447f + 0.0663f * z);
vec *= 57.29577951f;
vec += angle2;
vec += angle;
vec *= sign;
return vec;
*/
}
}
}
@@ -1,67 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="BasicOps"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Globalization;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float Abs(float x)
{
uint* a = (uint*)&x;
*a &= 0b_0111_1111_1111_1111_1111_1111_1111_1111;
return *(float*)a;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int Abs(int x)
{
uint* a = (uint*)&x;
*a &= 0b_0111_1111_1111_1111_1111_1111_1111_1111;
return *(int*)a;
}
internal static string GetListSeparator(IFormatProvider formatProvider)
{
if (formatProvider is CultureInfo cultureInfo) {
return cultureInfo.TextInfo.ListSeparator;
}
if (formatProvider?.GetFormat(typeof(TextInfo)) is TextInfo textInfo) {
return textInfo.ListSeparator;
}
return CultureInfo.CurrentCulture.TextInfo.ListSeparator;
}
}
}
@@ -1,64 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Compare"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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
{
public static partial class Scalar
{
public static float MaxOf(params float[] stream)
{
float ret = stream[0];
foreach (float num in stream)
{
if (ret < num) {
ret = num;
}
}
return ret;
}
public static float MinOf(params float[] stream)
{
float ret = stream[0];
foreach (float num in stream)
{
if (ret > num) {
ret = num;
}
}
return ret;
}
}
}
@@ -1,57 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Cos"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Cos(float x)
{
/*
float refer = x / 360.0f;
refer -= (int)refer;
refer *= 40;
int a = (int)refer; //大分度,查表
refer -= a; //小分度,拟合
float refer2 = refer * refer;
return ((-sinData[a]) * ((0.1570796327f * refer) - (6.459640975e-4f * refer * refer2)))
+ (cosData[a] * ((1 - (0.0123370055f * refer2)) + (2.536695709e-5f * refer2 * refer2)));
*/
return MathF.Cos(x);
}
}
}
@@ -1,52 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Ctor"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
public unsafe delegate float ScalarCalcHandler(float* x);
public static unsafe partial class Scalar
{
private const uint MEM_COMMIT = 0x1000;
private const uint MEM_RELEASE = 0x8000;
private const uint MEM_RESERVE = 0x2000;
private const uint PAGE_EXECUTE_READWRITE = 0x40;
static Scalar() { }
[DllImport("Kernel32.dll", EntryPoint = "VirtualAlloc")]
private static extern IntPtr VirtualAlloc(IntPtr address, int size, uint allocType, uint protect);
[DllImport("Kernel32.dll", EntryPoint = "VirtualFree")]
private static extern bool VirtualFree(IntPtr address, int size, uint freeType);
}
}
-109
View File
@@ -1,109 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Exp"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
public const float E = 2.718281828f;
public const double EDouble = System.Math.E;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Exp(float x)
{
return MathF.Exp(x);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Exp(double x)
{
return System.Math.Exp(x);
}
/// <summary>
/// Get the value of E ^ x;
/// </summary>
/// <param _label="x">
///
/// </param>
/// <returns>
///
/// </returns>
public static unsafe float ExpSlow(float x)
{
if (x == 1) {
return E;
}
if (x == 0) {
return 1;
}
bool sign = false;
if (x < 0)
{
sign = true;
x = -x;
}
float z = x, t;
if (x < 0.5f)
{
t = 1.0f + (x * (1.0f + (x * (0.5f + (x * (0.1666666667f + (x * (0.0416666666667f + (x * 8.333333333e-3f)))))))));
} else
{
/*
* define z = n * 2 ^ m
* n is between 0 and 0.5
*/
uint zBit = *(uint*)&z;
uint zBitAbs = zBit & 0b_0111_1111_1111_1111_1111_1111_1111_1111;
uint uintm = zBitAbs >> 23;
int m = (*(int*)&uintm) - 126;
uint nBit = (zBitAbs & 0b_0000_0000_0111_1111_1111_1111_1111_1111) + 0b_0011_1111_0000_0000_0000_0000_0000_0000;
float n = (*(float*)&nBit) - 1;
t = 2.718281828f + (n * (2.718281828f + (n * (1.359140914f + (n * (0.4530469714f + (n * (0.1132617429f + (n * 0.02265234857f)))))))));
for (int i = 0; i < m; i++) {
t = t * t;
}
}
if (sign) {
t = 1 / t;
}
return t;
}
}
}
@@ -1,67 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Factorial"
// 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;
namespace StgSharp.Mathematics
{
public static partial class Scalar
{
private static readonly uint[] factorialResult = [
1,
1,
2,
6,
24,
120,
720,
5040,
40320,
362880,
3628800,
39916800,
479001600];
public static unsafe ulong Factorial(int n)
{
ArgumentOutOfRangeException.ThrowIfLessThan(n, 0);
if (n < 13) {
return factorialResult[n];
}
if (n < 30) {
return NumericalModule.GlobalContext.factorial_simd(n);
}
double
dn = n,
stir = Sqrt(2 * PiDouble * dn) * Pow(dn / EDouble, dn),
correction = Exp(1 / (12 * dn));
return (ulong)(stir * correction);
}
}
}
@@ -1,31 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Function"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
namespace StgSharp.Mathematics
{
public class Function { }
}
@@ -1,80 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Log"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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;
namespace StgSharp.Mathematics
{
public static partial class Scalar
{
private static readonly float[] logArray = {
0f, 0.00995033085316809f, 0.0198026272961797f, 0.0295588022415444f, 0.0392207131532813f, 0.048790164169432f, 0.0582689081239758f, 0.0676586484738149f, 0.0769610411361284f, 0.0861776962410524f, 0.0953101798043249f, 0.104360015324243f, 0.113328685307003f, 0.122217632724249f, 0.131028262406404f, 0.139761942375159f, 0.148420005118273f, 0.157003748809665f, 0.165514438477573f, 0.173953307123438f, 0.182321556793955f, 0.19062035960865f, 0.198850858745165f, 0.207014169384326f, 0.215111379616945f, 0.22314355131421f, 0.231111720963387f, 0.2390169004705f, 0.246860077931526f, 0.254642218373581f, 0.262364264467491f, 0.27002713721306f, 0.27763173659828f, 0.285178942233662f, 0.29266961396282f, 0.300104592450338f, 0.307484699747961f, 0.314810739840034f, 0.322083499169113f, 0.3293037471426f, 0.336472236621213f, 0.343589704390077f, 0.350656871613169f, 0.357674444271816f, 0.364643113587909f, 0.371563556432483f, 0.378436435720245f, 0.385262400790645f, 0.392042087776024f, 0.398776119957368f, 0.405465108108164f, 0.412109650826833f, 0.418710334858185f, 0.425267735404344f, 0.431782416425538f, 0.438254930931155f, 0.444685821261446f, 0.451075619360217f, 0.457424847038875f, 0.46373401623214f, 0.470003629245736f, 0.476234178996372f, 0.482426149244293f, 0.488580014818671f, 0.494696241836107f, 0.500775287912489f, 0.506817602368452f, 0.512823626428664f, 0.518793793415168f, 0.524728528934982f, 0.53062825106217f, 0.536493370514568f, 0.542324290825362f, 0.548121408509688f, 0.553885113226438f, 0.559615787935423f, 0.56531380905006f, 0.570979546585738f, 0.576613364303994f, 0.582215619852664f, 0.587786664902119f, 0.593326845277734f, 0.598836501088704f, 0.60431596685333f, 0.609765571620894f, 0.615185639090233f, 0.62057648772511f, 0.625938430866495f, 0.631271776841858f, 0.636576829071551f, 0.641853886172395f, 0.647103242058538f, 0.65232518603969f, 0.657520002916794f, 0.662687973075237f, 0.667829372575655f, 0.672944473242426f, 0.678033542749897f, 0.683096844706444f, 0.688134638736401f,
};
/// <summary>
///
/// </summary>
/// <param _label="x">
///
/// </param>
/// <returns>
/// Returns the value of ln(x).
/// </returns>
public static unsafe float Log(float x)
{
if (x < 0) {
throw new ArgumentOutOfRangeException();
}
uint input = *(uint*)&x;
int f = (int)input;
f >>= 23;
f -= 127;
input <<= 9;
input >>= 9;
input += 0b_0011_1111_1000_0000_0000_0000_0000_0000;
float result = *(float*)&input;
uint order = ((uint)(result * 100)) - 100;
float cache = (result / (1f + (0.01f * order))) - 1;
result = (cache * (-0.25f)) + 0.3333333333333f;
result = (result * cache) - 0.5f;
result = (result * cache) + 1.0f;
result *= cache;
return
(f * 0.6931471806f) + result + logArray[order];
}
public static float Log(float x, float y)
{
return Log(x) / Log(y);
}
}
}
-121
View File
@@ -1,121 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Pow"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float Pow(float x, float y)
{
return System.MathF.Pow(x, y);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe double Pow(double x, double y)
{
return System.Math.Pow(x, y);
}
/// <summary>
/// calculate the value of x^y
/// </summary>
/// <param _label="x">
///
/// </param>
/// <param _label="y">
///
/// </param>
/// <returns>
/// Returns the value of x^y
/// </returns>
public static unsafe float PowSlow(float x, float y)
{
/*
* x^y = E ^ ( log( x ) * y )
* Now define z = | log(x) * y | = m * n
* and m is an integer, and 0.5 < |n| < 1
* then E ^ z = ( E ^ n ) ^ m
*
*
* As a float number can be expressed in (1+e)*(2^f)
* n = (1+e)/2
* m = 2 ^ (f + 1)
*
*/
float z, t;
if ((x == 1) || (y == 0)) {
return 1;
}
if ((x == 1) && (y == 0)) {
return float.PositiveInfinity;
}
if ((x == 0) && (y != 0)) {
return 0;
}
z = Scalar.Log(x) * y;
bool sign = false;
if (z < 0)
{
sign = true;
z = -z;
}
if (z < 0.5f)
{
t = 1.0f + (z * (1.0f + (z * (0.5f + (z * (0.1666666667f + (z * (0.0416666666667f + (z * 8.333333333e-3f)))))))));
} else
{
uint zBit = *(uint*)&z;
uint zBitAbs = zBit & 0b_0111_1111_1111_1111_1111_1111_1111_1111;
uint uintm = zBitAbs >> 23;
int m = (*(int*)&uintm) - 126;
uint nBit = (zBitAbs & 0b_0000_0000_0111_1111_1111_1111_1111_1111) + 0b_0011_1111_0000_0000_0000_0000_0000_0000;
float n = (*(float*)&nBit) - 1;
t = 2.718281828f + (n * (2.718281828f + (n * (1.359140914f + (n * (0.4530469714f + (n * (0.1132617429f + (n * 0.02265234857f)))))))));
for (int i = 0; i < m; i++) {
t = t * t;
}
}
if (sign) {
t = 1 / t;
}
return t;
}
}
}
@@ -1,126 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Random"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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 StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Data;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
namespace StgSharp.Mathematics
{
public static unsafe partial class Scalar
{
private static byte[] randomSeed;
internal static float currentSeed
#if DEBUG
= 0.5f;
#else
= Abs(System.DateTime.UtcNow.GetHashCode());
#endif
/// <summary>
/// returns a random float number between 0 and 1.
/// </summary>
/// <returns>
///
/// </returns>
public static unsafe float LowProceisionRandom()
{
float seed = currentSeed;
float sample = Scalar.Pow(Scalar.SeedSqrt(seed), 2);
float sample2 = (sample - seed) / seed;
sample2 = Scalar.Abs(sample2);
if (sample == 1) {
sample = sample2;
}
currentSeed = sample;
sample2 *= 1000000;
float result = sample2 - ((int)sample2);
if (result == 0)
{
currentSeed = sample2 + 0.1f;
result = Scalar.LowProceisionRandom();
}
return result;
}
/// <summary>
///
/// </summary>
/// <returns>
///
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Random<T>() where T : unmanaged, IConvertible, INumber<T>
{
if (randomSeed == null)
{
randomSeed = new byte[64];
string originSeed =
($"{((Assembly.GetEntryAssembly() == null) ? (Assembly.GetAssembly(typeof(World))!) :
Assembly.GetEntryAssembly())}") + ($"{DateTime.UtcNow.ToString("o")}");
randomSeed = SHA256.HashData(Encoding.UTF8.GetBytes(originSeed));
}
randomSeed = SHA256.HashData(randomSeed);
fixed (byte* bptr = randomSeed) {
return *(T*)bptr;
}
}
/// <summary>
/// Generates a random seed in int value.
/// </summary>
/// <returns>
///
/// </returns>
public static unsafe int RandomSeed()
{
float seedValue1 = LowProceisionRandom();
float seedValue2 = LowProceisionRandom();
uint seedValueBits = *(uint*)&seedValue1;
float seedValue = seedValueBits * seedValue2;
return *(int*)&seedValue;
}
}
}
@@ -1,142 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="RandomGenerator.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 StgSharp.Mathematics.Internal;
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml.Serialization;
namespace StgSharp.Mathematics.Numeric.Scalar
{
public unsafe class RandomGenerator
{
private byte[] currentKey;
private readonly byte[] originKey;
public RandomGenerator() : this(DateTime.UtcNow.ToBinary()) { }
public RandomGenerator(object source)
{
ArgumentNullException.ThrowIfNull(source);
XmlSerializer s = new(source.GetType());
using (StringWriter sw = new())
{
s.Serialize(sw, source);
string data = sw.ToString();
originKey = Encoding.Unicode.GetBytes(data);
}
currentKey = [ 0, 0, 0, 0 ];
fixed (byte* o = originKey, c = currentKey) {
*(int*)c = UnsafeCompute.CityHashSimplify((char*)o, 0, originKey.Length / 2);
}
TotalGeneratedRandom = 0;
}
public int TotalGeneratedRandom
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private set;
}
public unsafe int GenRandomInt()
{
uint source = PrivateRand();
TotalGeneratedRandom++;
M64 m = new M64();
m.Member<uint>(0) = source;
m.Member<uint>(1) = source;
return (m << (TotalGeneratedRandom % 32)).Member<int>(1);
}
public byte GenRandomInt8()
{
TotalGeneratedRandom++;
if (TotalGeneratedRandom % 4 == 0) {
PrivateRand();
}
return currentKey[TotalGeneratedRandom % 4];
}
public float GenRandomSingle()
{
TotalGeneratedRandom++;
while (true)
{
uint
temp0 = PrivateRand(),
temp1 = PrivateRand();
if (temp0 * temp1 != 0)
{
float ret = temp0 % temp1 * 1.0f / temp1;
if (ret < 0.335f)
{
ret = ret * ((ret * (-0.7811934f)) + 1.4489113f);
} else
{
ret = (ret * ((ret * (-0.1158368f)) + 1.0580600f)) + 0.0590584f;
}
if (ret > 1)
{
continue;
}
return ret;
}
}
}
public void Reset()
{
currentKey = originKey;
TotalGeneratedRandom = 0;
}
private unsafe uint PrivateRand()
{
uint ret;
fixed (byte* bptr = currentKey)
{
*(int*)bptr = UnsafeCompute.CityHashSimplify((char*)bptr, currentKey.Length / 2);
ret = *(uint*)bptr;
}
// Console.WriteLine(ret.ToString(16));
return ret;
}
}
}
@@ -1,47 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Sin"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Net.NetworkInformation;
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scalar
{
public const float Pi = 3.1415926f;
public const double PiDouble = System.Math.PI;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe float Sin(float x)
{
return MathF.Sin(x);
}
}
}
@@ -1,74 +0,0 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Sqrt"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. 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.Runtime.CompilerServices;
namespace StgSharp.Mathematics
{
public static partial class Scalar
{
public static unsafe float SeedSqrt(float x)
{
ArgumentOutOfRangeException.ThrowIfNegative(x);
if (x <= 1e-12) {
return 0;
}
uint a = *(uint*)&x;
uint f = a;
f >>= 23;
f /= 2;
f += 64;
a -= 0b_0011_1111_0000_0000_0000_0000_0000_0000;
uint e = a << 8;
e >>= 8;
e *= 0b_1101_0001;
e >>= 24;
e += 0b_0000_0000_0001_0000_1010_1000_1110_0010;
f <<= 23;
e += f;
float result = *(float*)&e;
result = (result + (x / result)) / 2;
return (result + (x / result)) / 2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Sqrt(float x)
{
return MathF.Sqrt(x);
/**/
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Sqrt(double x)
{
return System.Math.Sqrt(x);
}
}
}