move random gen to Math, working on VL4

This commit is contained in:
Nitload
2026-03-02 23:56:21 +08:00
parent 7e3ed8b0fd
commit ae1a49d6fb
63 changed files with 6463 additions and 6970 deletions
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="TriangulatedSurface"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
// 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
@@ -25,7 +25,7 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance;
using StgSharp.Mathematics;
using StgSharp.Mathematics;
using StgSharp.Mathematics.Graphics;
+82 -94
View File
@@ -1,99 +1,87 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ColumnSet2"
// 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;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.Mathematics.Internal
{
[StructLayout(LayoutKind.Explicit, Size = 12 * sizeof(float), Pack = 16)]
internal struct ColumnSet2 : IEquatable<ColumnSet2>
{
[FieldOffset(0 * sizeof(float))] internal float m00;
[FieldOffset(4 * sizeof(float))] internal float m01;
[FieldOffset(1 * sizeof(float))] internal float m10;
[FieldOffset(5 * sizeof(float))] internal float m11;
[FieldOffset(2 * sizeof(float))] internal float m20;
[FieldOffset(6 * sizeof(float))] internal float m21;
[FieldOffset(3 * sizeof(float))] internal float m30;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ColumnSet2.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
namespace StgSharp.Mathematics.Internal
{
[StructLayout(LayoutKind.Explicit, Size = 12 * sizeof(float), Pack = 16)]
internal struct ColumnSet2 : IEquatable<ColumnSet2>
{
[FieldOffset(0 * sizeof(float))] internal float m00;
[FieldOffset(4 * sizeof(float))] internal float m01;
[FieldOffset(1 * sizeof(float))] internal float m10;
[FieldOffset(5 * sizeof(float))] internal float m11;
[FieldOffset(2 * sizeof(float))] internal float m20;
[FieldOffset(6 * sizeof(float))] internal float m21;
[FieldOffset(3 * sizeof(float))] internal float m30;
[FieldOffset(7 * sizeof(float))] internal float m31;
[FieldOffset(0)] internal Vector4 colum0;
[FieldOffset(4 * sizeof(float))] internal Vector4 colum1;
internal ColumnSet2(
Vector4 c0,
Vector4 c1
)
{
Unsafe.SkipInit(out this);
colum0 = c0;
colum1 = c1;
[FieldOffset(0)] internal Vector4 colum0;
[FieldOffset(4 * sizeof(float))] internal Vector4 colum1;
internal ColumnSet2(Vector4 c0, Vector4 c1)
{
Unsafe.SkipInit(out this);
colum0 = c0;
colum1 = c1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object? obj)
{
return (obj is ColumnSet2 mat) && Equals(mat);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(ColumnSet2 other)
{
return colum0.Equals(other.colum0) && colum1.Equals(other.colum1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(ColumnSet2 left, ColumnSet2 right)
{
return !(left == right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(
object? obj
)
{
return (obj is ColumnSet2 mat) && Equals(mat);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(
ColumnSet2 other
)
{
return colum0.Equals(other.colum0) && colum1.Equals(other.colum1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(
ColumnSet2 left,
ColumnSet2 right
)
{
return !(left == right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(
ColumnSet2 left,
ColumnSet2 right
)
{
return left.Equals(right);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(ColumnSet2 left, ColumnSet2 right)
{
return left.Equals(right);
}
}
}
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixKernel"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
public unsafe struct MatrixKernel
{
private byte Head;
}
[StructLayout(LayoutKind.Sequential)]
[InlineArray(16)]
public unsafe struct MatrixKernel<T> where T: unmanaged, INumber<T>
{
public static readonly int Size = 16 * sizeof(T);
private T c0r0;
public MatrixKernel()
{
Unsafe.SkipInit(out this);
}
public MatrixKernel(bool clear)
{
if (!clear) {
Unsafe.SkipInit(out this);
}
}
public ref T this[int x, int y]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.Add(ref c0r0, (x * 4) + y);
}
}
}
@@ -0,0 +1,187 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixPanel"
// 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 System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics
{
public unsafe struct MatrixPanel
{
public const int AlignmentBytes = 64;
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>
{
return (MatrixPanel<T>*)NativeMemory.AlignedAlloc(Size<T>(), AlignmentBytes);
}
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>
{
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>
{
return PanelSideLength<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>
{
return (nuint)(MaxElementCount<T>() * sizeof(T));
}
/// <summary>
/// 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>
{
int perSide = KernelSideCount<T>();
return perSide * perSide;
}
/// <summary>
/// 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>
{
SIMDID id = NativeIntrinsic.IntrinsicMask;
switch (id.MaskByte[0] & 0b_00001111)
{
case 1:
return id.MaskByte[1] switch
{
1 => KernelSideCountSse<T>(),
2 => KernelSideCountAvx2<T>(),
3 => KernelSideCountAvx512<T>(),
_ => throw new NotSupportedException("Unsupported SIMD level."),
};
default:
throw new NotSupportedException("Current hardware platform is not supported");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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>
{
return PanelSideFromBits<T>(256) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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>
{
return PanelSideFromBits<T>(128) / 4;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int PanelSideFromBits<T>(int vectorBits) where T: unmanaged, INumber<T>
{
int elemBits = sizeof(T) * 8;
// Q = max(4, vectorBits/64, vectorBits/elemBits)
int by64 = vectorBits / 64;
int byElem = vectorBits / elemBits;
int side = Math.Max(4, Math.Max(by64, byElem));
return side;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int PanelSideLength<T>() where T: unmanaged, INumber<T>
{
SIMDID id = NativeIntrinsic.IntrinsicMask;
switch (id.MaskByte[0] & 0b_00001111)
{
case 1:
return id.MaskByte[1] switch
{
1 => PanelSideFromBits<T>(128),
2 => PanelSideFromBits<T>(256),
3 => PanelSideFromBits<T>(512),
_ => throw new NotSupportedException("Unsupported SIMD level."),
};
default:
throw new NotSupportedException("Current hardware platform is not supported");
}
}
}
// 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>
{
internal T Head; // first element of the panel buffer
public ref T this[int column, int row]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref Unsafe.Add(ref Head, row * MatrixPanel.ElementSideLength<T>() + column);
}
public Span<T> Elements
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => MatrixPanel.Elements(ref Head);
}
}
}
@@ -0,0 +1,64 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="ScalarPacket"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics
{
public unsafe struct ScalarPacket
{
private fixed ulong data[8];
public void BroadCast<TScalar, TRegister>(int slotIndex, TScalar value)
where TScalar: unmanaged, INumber<TScalar>
where TRegister: unmanaged, IRegisterPresentation
{
if (slotIndex is < 0 or >= 8) {
throw new IndexOutOfRangeException();
}
ref TRegister register = ref Unsafe.As<ulong, TRegister>(ref data[slotIndex]);
register.BroadCastFrom(value);
}
public ref T Data<T>(int index) where T: unmanaged, INumber<T>
{
if (index is < 0 or >= 8) {
throw new IndexOutOfRangeException();
}
return ref Unsafe.As<ulong, T>(ref data[index]);
}
}
}
@@ -0,0 +1,57 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="UnsafeCompute.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using System.Runtime.CompilerServices;
namespace StgSharp.Mathematics.Internal
{
public static class UnsafeCompute
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int CityHashSimplify(char* span, int length)
{
return NativeIntrinsic.Context.city_hash_simplify(span, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int CityHashSimplify(char* span, int begin, int length)
{
return NativeIntrinsic.Context.city_hash_simplify(span + begin, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int IndexOfCharPair(char* source, int pairValue, int length)
{
return NativeIntrinsic.Context.index_pair(source, pairValue, length);
}
}
}
@@ -1,50 +1,50 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="intrinsicContextProvider"
// 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.
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="intrinsicContextProvider"
// 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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Internal
{
internal static unsafe partial class NativeIntrinsic
{
private static readonly IntrinsicContext _intrinsicContext = new();
public static SIMDID IntrinsicMask { get; set; }
internal static IntrinsicContext Context
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _intrinsicContext;
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Internal
{
internal static unsafe partial class NativeIntrinsic
{
private static readonly IntrinsicContext _intrinsicContext = new();
public static SIMDID IntrinsicMask { get; set; }
internal static IntrinsicContext Context
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _intrinsicContext;
}
/*
@@ -74,6 +74,6 @@ namespace StgSharp.Mathematics.Internal
[LibraryImport(Native.LibName, EntryPoint = "load_intrinsic_function")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static partial void LoadIntrinsicFunction(IntrinsicContext* context, ulong id);
/**/
}
/**/
}
}
+204 -239
View File
@@ -1,263 +1,228 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix44"
// 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.HighPerformance;
using StgSharp.Mathematics.Internal;
using StgSharp.Mathematics.Numeric;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
[StructLayout(LayoutKind.Explicit, Size = (16 * sizeof(float)), Pack = 16)]
public unsafe struct Matrix44 : IEquatable<Matrix44>
{
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix44"
// 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;
using StgSharp.Mathematics.Intrinsic;
using StgSharp.Mathematics.Numeric;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
[StructLayout(LayoutKind.Explicit, Size = (16 * sizeof(float)), Pack = 16)]
public unsafe struct Matrix44 : IEquatable<Matrix44>
{
[FieldOffset(0 * sizeof(float))] internal Column column;
[FieldOffset(0)] internal ColumnSet4 mat;
[FieldOffset(0)] internal MatrixKernel<float> kernel;
internal Matrix44(
ColumnSet4 mat
)
{
Unsafe.SkipInit(out this);
this.mat = mat;
}
internal Matrix44(
Vector4 vec0,
Vector4 vec1,
Vector4 vec2,
Vector4 vec3
)
{
Unsafe.SkipInit(out this);
mat.colum0 = vec0;
mat.colum1 = vec1;
mat.colum2 = vec2;
mat.colum3 = vec3;
}
public Matrix44()
{
Unsafe.SkipInit(out this);
}
public unsafe Matrix44(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13,
float a20,
float a21,
float a22,
float a23,
float a30,
float a31,
float a32,
float a33
)
{
Unsafe.SkipInit(out this);
mat.colum0 = new Vector4(a00, a10, a20, a30);
mat.colum1 = new Vector4(a01, a11, a21, a31);
mat.colum2 = new Vector4(a02, a12, a22, a32);
mat.colum3 = new Vector4(a03, a13, a23, a33);
}
public unsafe float this[
int rowNum,
int columNum
]
{
get
[FieldOffset(0)] internal ColumnSet4 mat;
[FieldOffset(0)] internal MatrixKernel<float> kernel;
internal Matrix44(ColumnSet4 mat)
{
Unsafe.SkipInit(out this);
this.mat = mat;
}
internal Matrix44(Vector4 vec0, Vector4 vec1, Vector4 vec2, Vector4 vec3)
{
Unsafe.SkipInit(out this);
mat.colum0 = vec0;
mat.colum1 = vec1;
mat.colum2 = vec2;
mat.colum3 = vec3;
}
public Matrix44()
{
Unsafe.SkipInit(out this);
}
public unsafe Matrix44(
float a00,
float a01,
float a02,
float a03,
float a10,
float a11,
float a12,
float a13,
float a20,
float a21,
float a22,
float a23,
float a30,
float a31,
float a32,
float a33)
{
Unsafe.SkipInit(out this);
mat.colum0 = new Vector4(a00, a10, a20, a30);
mat.colum1 = new Vector4(a01, a11, a21, a31);
mat.colum2 = new Vector4(a02, a12, a22, a32);
mat.colum3 = new Vector4(a03, a13, a23, a33);
}
public unsafe float this[int rowNum, int columNum]
{
get
{
#if DEBUG
if (rowNum is > 3 or < 0)
{
throw new ArgumentOutOfRangeException(nameof(columNum));
}
if (columNum is > 3 or < 0) {
throw new ArgumentOutOfRangeException(nameof(columNum));
if (rowNum is > 3 or < 0)
{
throw new ArgumentOutOfRangeException(nameof(columNum));
}
if (columNum is > 3 or < 0) {
throw new ArgumentOutOfRangeException(nameof(columNum));
}
#endif
return kernel[rowNum + 4 * columNum];
}
set
return kernel[rowNum + 4 * columNum];
}
set
{
#if DEBUG
if (rowNum is > 3 or < 0)
{
throw new ArgumentOutOfRangeException(nameof(columNum));
}
if (columNum is > 3 or < 0) {
throw new ArgumentOutOfRangeException(nameof(columNum));
if (rowNum is > 3 or < 0)
{
throw new ArgumentOutOfRangeException(nameof(columNum));
}
if (columNum is > 3 or < 0) {
throw new ArgumentOutOfRangeException(nameof(columNum));
}
#endif
kernel[rowNum + 4 * columNum] = value;
}
kernel[rowNum + 4 * columNum] = value;
}
}
public Matrix44 Transpose
{
get
{
Matrix44 transpose = new();
InternalTranspose(ref transpose);
return transpose;
}
}
public static Matrix44 Unit => new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public static Matrix44 WNegativeUnit => new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1);
public static Matrix44 XNegativeUnit => new Matrix44(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public static Matrix44 YNegativeUnit => new Matrix44(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public static Matrix44 ZNegativeUnit => new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1);
public ReadOnlySpan<float> AsSpan()
{
return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<ColumnSet4, float>(ref mat), 16);
}
public override bool Equals(object? obj)
{
return obj is Matrix44 x && Equals(x);
}
public bool Equals(Matrix44 other)
{
return mat.Equals(other.mat);
}
public override int GetHashCode()
{
return HashCode.Combine(mat.colum0.GetHashCode(), mat.colum1.GetHashCode(), mat.colum2.GetHashCode(),
mat.colum3.GetHashCode());
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe void InternalTranspose(ref Matrix44 transpose)
{
const int f32 = 0;
fixed (MatrixKernel<float>* source = &this.kernel, target = &transpose.kernel) {
NativeIntrinsic.Context.mat[f32].buffer_transpose(source, target);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix44 operator -(Matrix44 left, Matrix44 right)
{
Matrix44 ret = new();
const int f32 = 0;
NativeIntrinsic.Context.mat[f32].buffer_sub(&left, &right, &ret, 1);
return ret;
}
public Matrix44 Transpose
{
get
{
Matrix44 transpose = new();
InternalTranspose(ref transpose);
return transpose;
}
public static bool operator !=(Matrix44 left, Matrix44 right)
{
return !(left == right);
}
public static Matrix44 Unit => new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public static Matrix44 WNegativeUnit => new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1);
public static Matrix44 XNegativeUnit => new Matrix44(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public static Matrix44 YNegativeUnit => new Matrix44(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
public static Matrix44 ZNegativeUnit => new Matrix44(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1);
public ReadOnlySpan<float> AsSpan()
{
return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<ColumnSet4, float>(ref mat), 16);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix44 operator *(Matrix44 mat, float value)
{
return new Matrix44(mat.mat.colum0 * value, mat.mat.colum1 * value, mat.mat.colum2 * value,
mat.mat.colum3 * value);
}
public override bool Equals(
object? obj
)
{
return obj is Matrix44 x && Equals(x);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix44 operator *(Matrix44 left, Matrix44 right)
{
Matrix44 ret = new();
int f32 = (int)MatrixElementType.F32;
NativeIntrinsic.Context.mat[f32].kernel_fma(&left, &right, &ret);
return ret;
}
public bool Equals(
Matrix44 other
)
{
return mat.Equals(other.mat);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix44 operator +(Matrix44 left, Matrix44 right)
{
Matrix44 ret = new();
const int f32 = 0;
NativeIntrinsic.Context.mat[f32].buffer_add(&left, &right, &ret, 1);
return ret;
}
public override int GetHashCode()
{
return HashCode.Combine(mat.colum0.GetHashCode(), mat.colum1.GetHashCode(),
mat.colum2.GetHashCode(), mat.colum3.GetHashCode());
public static bool operator ==(Matrix44 left, Matrix44 right)
{
return left.Equals(right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe void InternalTranspose(
ref Matrix44 transpose
)
{
const int f32 = 0;
fixed (MatrixKernel<float>* source = &this.kernel, target = &transpose.kernel) {
NativeIntrinsic.Context.mat[f32].buffer_transpose(source, target);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix44 operator -(
Matrix44 left,
Matrix44 right
)
{
Matrix44 ret = new();
const int f32 = 0;
NativeIntrinsic.Context.mat[f32].buffer_sub(&left, &right, &ret, 1);
return ret;
}
public static bool operator !=(
Matrix44 left,
Matrix44 right
)
{
return !(left == right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix44 operator *(
Matrix44 mat,
float value
)
{
return new Matrix44(mat.mat.colum0 * value, mat.mat.colum1 * value,
mat.mat.colum2 * value, mat.mat.colum3 * value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Matrix44 operator *(
Matrix44 left,
Matrix44 right
)
{
Matrix44 ret = new();
int f32 = (int)MatrixElementType.F32;
NativeIntrinsic.Context.mat[f32].kernel_fma(&left, &right, &ret);
return ret;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Matrix44 operator +(
Matrix44 left,
Matrix44 right
)
{
Matrix44 ret = new();
const int f32 = 0;
NativeIntrinsic.Context.mat[f32].buffer_add(&left, &right, &ret, 1);
return ret;
}
public static bool operator ==(
Matrix44 left,
Matrix44 right
)
{
return left.Equals(right);
}
[InlineArray(4)]
internal struct Column
{
private Vec4 value;
}
}
[InlineArray(4)]
internal struct Column
{
private Vec4 value;
}
}
}
+141 -141
View File
@@ -1,162 +1,162 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Vec2"
// 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.HighPerformance;
using StgSharp.Mathematics.Numeric;
using System.Net.Http.Headers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Vec2"
// 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;
using StgSharp.Mathematics.Numeric;
using System.Net.Http.Headers;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
/// <summary>
/// A two dimension vector defined by two elements. Vec2 in World are default used as colum
/// vector.
/// <summary>
/// A two dimension vector defined by two elements. Vec2 in World are default used as colum
/// vector.
/// </summary>
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec2 : IUnmanagedVector<Vec2>
{
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec2 : IUnmanagedVector<Vec2>
{
[FieldOffset(0)] internal unsafe fixed float num[2];
[FieldOffset(0)]
[FieldOffset(0)]
internal M128 reg;
[FieldOffset(0)]
[FieldOffset(0)]
internal Vector2 v;
[FieldOffset(0)]
public float X;
[FieldOffset(4)]
public float Y;
internal Vec2(Vector2 vec)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
v = vec;
[FieldOffset(0)]
public float X;
[FieldOffset(4)]
public float Y;
internal Vec2(Vector2 vec)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
v = vec;
}
internal Vec2(M128 vec)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
reg = vec;
reg.Member<ulong>(1) = 0;
}
public Vec2(float x, float y)
{
v = new Vector2(x, y);
}
public static Vec2 Unit => new Vec2(1, 1);
public static Vec2 Zero => new Vec2(0, 0);
public static Vec2 One
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vec2(1, 1);
}
public Vec2 XY
{
readonly get => this;
set => this = value;
}
public Vec3 XYZ
{
readonly get => new(reg);
set
{
reg = value.reg;
reg.Member<ulong>(1) = 0;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Cross(Vec2 right)
{
return X * right.Y - Y * right.X;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Dot(Vec2 vec)
{
return Vector2.Dot(v, vec.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec2 operator -(Vec2 left, Vec2 right)
{
return new Vec2(left.v - right.v);
}
internal Vec2(M128 vec)
{
Unsafe.SkipInit(out reg);
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
reg = vec;
reg.Member<ulong>(1) = 0;
public static bool operator !=(Vec2 left, Vec2 right)
{
return !(left == right);
}
public Vec2(float x, float y)
{
v = new Vector2(x, y);
public static Vec2 operator *(Vec2 vec, float value)
{
return new Vec2(vec.v * value);
}
public static Vec2 operator *(float value, Vec2 vec)
{
return new Vec2(vec.v * value);
}
public static Vec2 Unit => new Vec2(1, 1);
public static Vec2 Zero => new Vec2(0, 0);
public static Vec2 One
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vec2(1, 1);
public static Vec2 operator /(Vec2 vec, float value)
{
return new Vec2(vec.v / value);
}
public Vec2 XY
{
readonly get => this;
set => this = value;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec2 operator +(Vec2 left, Vec2 right)
{
return new Vec2(left.v + right.v);
}
public Vec3 XYZ
{
readonly get => new(reg);
set
{
reg = value.reg;
reg.Member<ulong>(1) = 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vec2 left, Vec2 right)
{
return left.v == right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Cross(Vec2 right)
{
return X * right.Y - Y * right.X;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float Dot(Vec2 vec)
{
return Vector2.Dot(v, vec.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec2 operator -(Vec2 left, Vec2 right)
{
return new Vec2(left.v - right.v);
}
public static bool operator !=(Vec2 left, Vec2 right)
{
return !(left == right);
}
public static Vec2 operator *(Vec2 vec, float value)
{
return new Vec2(vec.v * value);
}
public static Vec2 operator *(float value, Vec2 vec)
{
return new Vec2(vec.v * value);
}
public static Vec2 operator /(Vec2 vec, float value)
{
return new Vec2(vec.v / value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec2 operator +(Vec2 left, Vec2 right)
{
return new Vec2(left.v + right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vec2 left, Vec2 right)
{
return left.v == right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vec2((float, float) tuple)
{
return new Vec2(tuple.Item1, tuple.Item2);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Vec2((float, float) tuple)
{
return new Vec2(tuple.Item1, tuple.Item2);
}
}
}
+215 -267
View File
@@ -1,288 +1,236 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Vec3"
// 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.HighPerformance;
using StgSharp.Mathematics.Numeric;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
[CollectionBuilder(typeof(Vec3), nameof(FromSpan))]
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec3 : IEquatable<Vec3>, IUnmanagedVector<Vec3>, IEnumerable<float>
{
[FieldOffset(0)] internal unsafe fixed float num[3];
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Vec3"
// 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;
using StgSharp.Mathematics.Numeric;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
[CollectionBuilder(typeof(Vec3), nameof(FromSpan))]
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public struct Vec3 : IEquatable<Vec3>, IUnmanagedVector<Vec3>, IEnumerable<float>
{
[FieldOffset(0)] internal unsafe fixed float num[3];
[FieldOffset(0)] internal M128 reg;
[FieldOffset(0)] internal Vector3 v;
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
internal Vec3(
M128 vector
)
{
Unsafe.SkipInit(out this);
reg = vector;
reg.Member<uint>(3) = 0;
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
internal Vec3(M128 vector)
{
Unsafe.SkipInit(out this);
reg = vector;
reg.Member<uint>(3) = 0;
}
internal Vec3(Vector3 vector)
{
v = vector;
}
public Vec3()
{
Unsafe.SkipInit(out this);
}
public Vec3(Vec2 xy, float z)
{
Unsafe.SkipInit(out this);
reg = xy.reg;
Z = z;
}
public Vec3(float x, float y, float z)
{
Unsafe.SkipInit(out this);
v = new Vector3(x, y, z);
}
public unsafe Vec2 XY
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => new(reg);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Vector3, Vector2>(ref v) = value.v;
}
public Vec3 XYZ
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => new(v);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => this = value;
}
public static Vec3 Zero => new(0, 0, 0);
public static Vec3 One => new(1, 1, 1);
public static Vec3 UnitX => new(1, 0, 0);
public static Vec3 UnitY => new(0, 1, 0);
public static Vec3 UnitZ => new(0, 0, 1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 Cross(Vec3 left, Vec3 right)
{
return Linear.Cross(left, right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly float Dot(Vec3 right)
{
return Vector3.Dot(v, right.v);
}
public readonly bool Equals(Vec3 other)
{
return reg == other.reg;
}
public override readonly bool Equals(object obj)
{
return obj is not null && obj is Vec3 vec && this == vec;
}
public static Vec3 FromSpan(ReadOnlySpan<float> span)
{
Vec3 v = new();
span.CopyTo(MemoryMarshal.CreateSpan(ref v.X, 3));
return v;
}
public unsafe IEnumerator<float> GetEnumerator()
{
for (int i = 0; i < 3; i++) {
yield return reg.Member<float>(i);
}
}
public override unsafe int GetHashCode()
{
fixed (float* add = &X) {
return HashCode.Combine(X, Y, Z, (ulong)add);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly float GetMaxValue()
{
float ret = X;
ret = ret > Y ? ret : Y;
ret = ret > Z ? ret : Z;
return ret;
}
public static bool IsParallel(Vec3 left, Vec3 right)
{
return Cross(left, right) == Zero;
}
public override readonly string ToString()
{
return $"[{X},{Y},{Z}]";
}
public readonly string ToString(string sample)
{
return $"[{X.ToString(sample)},{Y.ToString(sample)},{Z.ToString(sample)}]";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator -(Vec3 vec)
{
return new Vec3(-vec.v);
}
internal Vec3(
Vector3 vector
)
{
v = vector;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator -(Vec3 left, Vec3 right)
{
return new Vec3(left.v - right.v);
}
public Vec3()
{
Unsafe.SkipInit(out this);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(Vec3 left, Vec3 right)
{
return left.v != right.v;
}
public Vec3(
Vec2 xy,
float z
)
{
Unsafe.SkipInit(out this);
reg = xy.reg;
Z = z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator *(Vec3 vec, float value)
{
return new Vec3(vec.v * value);
}
public Vec3(
float x,
float y,
float z
)
{
Unsafe.SkipInit(out this);
v = new Vector3(x, y, z);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float operator *(Vec3 left, Vec3 right)
{
return Vector3.Dot(left.v, right.v);
}
public unsafe Vec2 XY
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => new(reg);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => Unsafe.As<Vector3, Vector2>(ref v) = value.v;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator /(Vec3 vec, float value)
{
return new Vec3(vec.v / value);
}
public Vec3 XYZ
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
readonly get => new(v);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set => this = value;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator +(Vec3 left, Vec3 right)
{
return new Vec3(left.v + right.v);
}
public static Vec3 Zero => new(0, 0, 0);
public static Vec3 One => new(1, 1, 1);
public static Vec3 UnitX => new(1, 0, 0);
public static Vec3 UnitY => new(0, 1, 0);
public static Vec3 UnitZ => new(0, 0, 1);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 Cross(
Vec3 left,
Vec3 right
)
{
return Linear.Cross(left, right);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(Vec3 left, Vec3 right)
{
return left.v == right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly float Dot(
Vec3 right
)
{
return Vector3.Dot(v, right.v);
}
public readonly bool Equals(
Vec3 other
)
{
return reg == other.reg;
}
public override readonly bool Equals(
object obj
)
{
return obj is not null && obj is Vec3 vec && this == vec;
}
public static Vec3 FromSpan(
ReadOnlySpan<float> span
)
{
Vec3 v = new();
span.CopyTo(MemoryMarshal.CreateSpan(ref v.X, 3));
return v;
}
public unsafe IEnumerator<float> GetEnumerator()
{
for (int i = 0; i < 3; i++) {
yield return reg.Member<float>(i);
}
}
public override unsafe int GetHashCode()
{
fixed (float* add = &X) {
return HashCode.Combine(X, Y, Z, (ulong)add);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly float GetMaxValue()
{
float ret = X;
ret = ret > Y ? ret : Y;
ret = ret > Z ? ret : Z;
return ret;
}
public static bool IsParallel(
Vec3 left,
Vec3 right
)
{
return Cross(left, right) == Zero;
}
public override readonly string ToString()
{
return $"[{X},{Y},{Z}]";
}
public readonly string ToString(
string sample
)
{
return $"[{X.ToString(sample)},{Y.ToString(sample)},{Z.ToString(sample)}]";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator -(
Vec3 vec
)
{
return new Vec3(-vec.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator -(
Vec3 left,
Vec3 right
)
{
return new Vec3(left.v - right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(
Vec3 left,
Vec3 right
)
{
return left.v != right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator *(
Vec3 vec,
float value
)
{
return new Vec3(vec.v * value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float operator *(
Vec3 left,
Vec3 right
)
{
return Vector3.Dot(left.v, right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator /(
Vec3 vec,
float value
)
{
return new Vec3(vec.v / value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec3 operator +(
Vec3 left,
Vec3 right
)
{
return new Vec3(left.v + right.v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(
Vec3 left,
Vec3 right
)
{
return left.v == right.v;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe implicit operator Vec3(
(float, float, float) tuple
)
{
return Unsafe.As<(float,float,float), Vec3>(ref tuple);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe implicit operator Vec3((float, float, float) tuple)
{
return Unsafe.As<(float,float,float), Vec3>(ref tuple);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
+188 -229
View File
@@ -1,251 +1,210 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Vec4"
// 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.HighPerformance;
using StgSharp.Mathematics.Internal;
using StgSharp.Mathematics.Numeric;
using System;
using System.Data.Common;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
[CollectionBuilder(builderType:typeof(Vec4), methodName: nameof(Vec4.FromSpan))]
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public unsafe struct Vec4 : IEquatable<Vec4>, IUnmanagedVector<Vec4>
{
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Vec4"
// 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;
using StgSharp.Mathematics.Intrinsic;
using StgSharp.Mathematics.Numeric;
using System;
using System.Data.Common;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Graphics
{
[CollectionBuilder(builderType:typeof(Vec4), methodName: nameof(Vec4.FromSpan))]
[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 16)]
public unsafe struct Vec4 : IEquatable<Vec4>, IUnmanagedVector<Vec4>
{
[FieldOffset(0)] internal unsafe fixed float num[4];
[FieldOffset(0)] internal M128 reg;
[FieldOffset(0)] internal Vector4 vec;
[FieldOffset(0)] internal Vector4 vec;
[FieldOffset(12)] public float W;
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
internal Vec4(
Vector4 v
)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
[FieldOffset(0)] public float X;
[FieldOffset(4)] public float Y;
[FieldOffset(8)] public float Z;
internal Vec4(Vector4 v)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
Unsafe.SkipInit(out reg);
vec = v;
}
internal Vec4(
M128 v
)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
vec = v;
}
internal Vec4(M128 v)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
Unsafe.SkipInit(out vec);
reg = v;
}
public Vec4(
Vec3 v3,
float w
)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
reg = v3.reg;
W = w;
}
public Vec4(
float x,
float y,
float z,
float w
)
{
vec = new Vector4(x, y, z, w);
}
public unsafe Vec2 XY
{
get => new Vec2(reg);
set
{
X = value.X;
Y = value.Y;
}
}
public unsafe Vec3 XYZ
{
get => new Vec3(reg);
set
{
float w = W;
reg = value.reg;
W = w;
}
}
public static Vec4 One
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vec4(1, 1, 1, 1);
}
public static Vec4 Zero
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vec4(0, 0, 0, 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 Add(
Vec4 left,
Vec4 right
)
{
return left + right;
}
public ReadOnlySpan<float> AsSpan()
{
return MemoryMarshal.CreateReadOnlySpan(ref reg.Member<float>(0), 4);
}
public override bool Equals(
object obj
)
{
return obj is Vec4 v && v == this;
}
public static Vec4 FromSpan(
ReadOnlySpan<float> span
)
{
if (span.Length < 4) {
throw new ArgumentException("Span length must be at least 4.", nameof(span));
reg = v;
}
public Vec4(Vec3 v3, float w)
{
Unsafe.SkipInit(out X);
Unsafe.SkipInit(out Y);
Unsafe.SkipInit(out Z);
Unsafe.SkipInit(out W);
reg = v3.reg;
W = w;
}
public Vec4(float x, float y, float z, float w)
{
vec = new Vector4(x, y, z, w);
}
public unsafe Vec2 XY
{
get => new Vec2(reg);
set
{
X = value.X;
Y = value.Y;
}
}
public unsafe Vec3 XYZ
{
get => new Vec3(reg);
set
{
float w = W;
reg = value.reg;
W = w;
}
}
public static Vec4 One
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vec4(1, 1, 1, 1);
}
public static Vec4 Zero
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Vec4(0, 0, 0, 0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 Add(Vec4 left, Vec4 right)
{
return left + right;
}
public ReadOnlySpan<float> AsSpan()
{
return MemoryMarshal.CreateReadOnlySpan(ref reg.Member<float>(0), 4);
}
public override bool Equals(object obj)
{
return obj is Vec4 v && v == this;
}
public static Vec4 FromSpan(ReadOnlySpan<float> span)
{
if (span.Length < 4) {
throw new ArgumentException("Span length must be at least 4.", nameof(span));
}
// Read 4 floats as a Vector4 in one operation without per-element copy.
Vector4 v = MemoryMarshal.Read<Vector4>(MemoryMarshal.AsBytes(span));
return new Vec4(v);
Vector4 v = MemoryMarshal.Read<Vector4>(MemoryMarshal.AsBytes(span));
return new Vec4(v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<float>.Enumerator GetEnumerator()
{
return AsSpan().GetEnumerator();
}
public override int GetHashCode()
{
return vec.GetHashCode();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 Subtract(Vec4 left, Vec4 right)
{
return left - right;
}
public override string ToString()
{
return vec.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator -(Vec4 left, Vec4 right)
{
return new Vec4(left.vec - right.vec);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<float>.Enumerator GetEnumerator()
{
return AsSpan().GetEnumerator();
public static bool operator !=(Vec4 left, Vec4 right)
{
return !(left == right);
}
public override int GetHashCode()
{
return vec.GetHashCode();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator *(Matrix44 mat, Vec4 vec)
{
Matrix44 transpose = mat.Transpose;
return new Vec4(Vector4.Dot(transpose.mat.colum0, vec.vec), Vector4.Dot(transpose.mat.colum1, vec.vec),
Vector4.Dot(transpose.mat.colum2, vec.vec), Vector4.Dot(transpose.mat.colum3, vec.vec));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 Subtract(
Vec4 left,
Vec4 right
)
{
return left - right;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator +(Vec4 left, Vec4 right)
{
return new Vec4(left.vec + right.vec);
}
public override string ToString()
{
return vec.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator -(
Vec4 left,
Vec4 right
)
{
return new Vec4(left.vec - right.vec);
}
public static bool operator !=(
Vec4 left,
Vec4 right
)
{
return !(left == right);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator *(
Matrix44 mat,
Vec4 vec
)
{
Matrix44 transpose = mat.Transpose;
return new Vec4(Vector4.Dot(transpose.mat.colum0, vec.vec),
Vector4.Dot(transpose.mat.colum1, vec.vec),
Vector4.Dot(transpose.mat.colum2, vec.vec),
Vector4.Dot(transpose.mat.colum3, vec.vec));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vec4 operator +(
Vec4 left,
Vec4 right
)
{
return new Vec4(left.vec + right.vec);
}
public static bool operator ==(
Vec4 left,
Vec4 right
)
{
return left.vec == right.vec;
}
bool IEquatable<Vec4>.Equals(
Vec4 other
)
{
return vec == other.vec;
}
}
public static bool operator ==(Vec4 left, Vec4 right)
{
return left.vec == right.vec;
}
bool IEquatable<Vec4>.Equals(Vec4 other)
{
return vec == other.vec;
}
}
}
@@ -1,101 +1,101 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix.Create"
// 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.HighPerformance;
using StgSharp.HighPerformance.Memory;
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 unsafe partial class Matrix<T>
{
private const int KernelSideLength = 4;
public static Matrix<T> Create(
int columnLength,
int rowLength,
MatrixLayout layout,
HybridLayerSegregatedFitAllocator allocator)
{
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix.Create"
// 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;
using StgSharp.Mathematics.Memory;
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 unsafe partial class Matrix<T>
{
private const int KernelSideLength = 4;
public static Matrix<T> Create(
int columnLength,
int rowLength,
MatrixLayout layout,
HybridLayerSegregatedFitAllocator allocator)
{
ArgumentNullException.ThrowIfNull(allocator);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(columnLength);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(rowLength);
int kernelColumns = DivideRoundUp(columnLength, KernelSideLength);
int kernelColumns = DivideRoundUp(columnLength, KernelSideLength);
int kernelRows = DivideRoundUp(rowLength, KernelSideLength);
if (layout is MatrixLayout.UpperTriangle or MatrixLayout.LowerTriangle)
{
if (kernelColumns != kernelRows) {
throw new ArgumentException("Triangular layouts require square matrices.");
}
if (layout is MatrixLayout.UpperTriangle or MatrixLayout.LowerTriangle)
{
if (kernelColumns != kernelRows) {
throw new ArgumentException("Triangular layouts require square matrices.");
}
}
long kernelCount = layout switch
{
MatrixLayout.DenseRectangle => (long)kernelColumns * kernelRows,
MatrixLayout.UpperTriangle => TriangularKernelCount(kernelColumns),
MatrixLayout.LowerTriangle => TriangularKernelCount(kernelRows),
_ => throw new ArgumentOutOfRangeException(nameof(layout))
long kernelCount = layout switch
{
MatrixLayout.DenseRectangle => (long)kernelColumns * kernelRows,
MatrixLayout.UpperTriangle => TriangularKernelCount(kernelColumns),
MatrixLayout.LowerTriangle => TriangularKernelCount(kernelRows),
_ => throw new ArgumentOutOfRangeException(nameof(layout))
};
long requiredBytes = kernelCount * MatrixKernel<T>.Size;
long requiredBytes = kernelCount * MatrixKernel<T>.Size;
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(requiredBytes, nameof(requiredBytes));
HybridLayerSegregatedFitAllocationHandle handle = allocator.Alloc((uint)requiredBytes);
HybridLayerSegregatedFitAllocationHandle handle = allocator.Alloc((uint)requiredBytes);
MatrixStorageHLSF<T> storage = new MatrixStorageHLSF<T>(allocator, handle);
Matrix<T> matrix = new Matrix<T>(MatrixKernelBoarder.Create(layout), new MatrixSize(columnLength, rowLength,
kernelColumns,
Matrix<T> matrix = new Matrix<T>(MatrixKernelBoarder.Create(layout), new MatrixSize(columnLength, rowLength,
kernelColumns,
kernelRows), storage);
return matrix;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int DivideRoundUp(int value, int divisor)
{
return (value + (divisor - 1)) / divisor;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static long TriangularKernelCount(int order)
{
long n = order;
return (n * (n + 1L)) / 2L;
}
}
return matrix;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int DivideRoundUp(int value, int divisor)
{
return (value + (divisor - 1)) / divisor;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static long TriangularKernelCount(int order)
{
long n = order;
return (n * (n + 1L)) / 2L;
}
}
}
+153 -174
View File
@@ -1,204 +1,183 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix"
// 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.HighPerformance;
using StgSharp.Mathematics.Numeric;
using System;
using System.Numerics;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="Matrix"
// 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;
using StgSharp.Mathematics.Numeric;
using System;
using System.Numerics;
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>
{
namespace StgSharp.Mathematics.Numeric
{
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_size = sizeof(T);
private readonly MatrixKernelBoarder _boarder;
private readonly MatrixSize _size;
private readonly MatrixStorage<T> _buffer;
private protected Matrix(
MatrixKernelBoarder boarder,
MatrixSize size,
private protected static readonly int t_size = sizeof(T);
private readonly MatrixKernelBoarder _boarder;
private readonly MatrixSize _size;
private readonly MatrixStorage<T> _buffer;
private protected Matrix(
MatrixKernelBoarder boarder,
MatrixSize size,
MatrixStorage<T> buffer
)
{
_boarder = boarder;
_size = size;
_buffer = buffer;
)
{
_boarder = boarder;
_size = size;
_buffer = buffer;
}
public T this[int x, int y]
{
get
{
if (y < 0 || y > _size.ElementColumnLength || x < 0 || x > _size.ElementRowLength) {
throw new ArgumentOutOfRangeException($"Index [{x},{y}] is out of matrix index range.");
}
long offset = GetElementOffset(x, y);
if (offset < 0) {
return T.Zero;
}
return ((T*)Buffer)[offset];
}
set
{
if (y < 0 || y > _size.ElementColumnLength || x < 0 || x > _size.ElementRowLength) {
throw new ArgumentOutOfRangeException($"Index [{x},{y}] is out of matrix index range.");
}
long offset = GetElementOffset(x, y);
if (offset < 0) {
return;
}
((T*)Buffer)[offset] = value;
}
}
public T this[
int x,
int y
]
{
get
{
if (y < 0 || y > _size.ElementColumnLength || x < 0 || x > _size.ElementRowLength) {
throw new ArgumentOutOfRangeException($"Index [{x},{y}] is out of matrix index range.");
}
long offset = GetElementOffset(x, y);
if (offset < 0) {
return T.Zero;
}
return ((T*)Buffer)[offset];
}
set
{
if (y < 0 || y > _size.ElementColumnLength || x < 0 || x > _size.ElementRowLength) {
throw new ArgumentOutOfRangeException($"Index [{x},{y}] is out of matrix index range.");
}
long offset = GetElementOffset(x, y);
if (offset < 0) {
return;
}
((T*)Buffer)[offset] = value;
}
}
/// <summary>
/// Matlab style indexer to generate a new matrix
/// <summary>
/// Matlab style indexer to generate a new matrix
/// </summary>
/// <param name="column">
///
/// <param name="column">
///
/// </param>
/// <param name="row">
///
/// <param name="row">
///
/// </param>
/// <returns>
///
/// <returns>
///
/// </returns>
/// <exception cref="NotImplementedException">
///
/// <exception cref="NotImplementedException">
///
/// </exception>
public unsafe Matrix<T> this[
ReadOnlySpan<MatrixIndex> column,
ReadOnlySpan<MatrixIndex> row
]
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
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>
/// Length of the matrix in columns.
/// </summary>
public int ColumnLength => _size.ElementColumnLength;
/// <summary>
/// Length of the matrix in rows.
/// <summary>
/// Length of the matrix in rows.
/// </summary>
public int RowLength => _size.ElementRowLength;
public MatrixLayout Layout { get; init; }
internal MatrixKernel<T>* Buffer
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (MatrixKernel<T>*)_buffer.BufferPointer;
}
protected internal int KernelColumnLength => _size.KernelColumnLength;
protected internal int KernelRowLength => _size.KernelRowLength;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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
)
{
public int RowLength => _size.ElementRowLength;
public MatrixLayout Layout { get; init; }
internal MatrixKernel<T>* Buffer
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (MatrixKernel<T>*)_buffer.BufferPointer;
}
protected internal int KernelColumnLength => _size.KernelColumnLength;
protected internal int KernelRowLength => _size.KernelRowLength;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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)
{
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;
}
r = x % 4;
if (!_boarder.IsInBuffer(k_r, k_c, in _size)) {
return -1;
}
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
)
{
// Caller guarantees: indices in range, layout is dense square.
int k_c = y / 4;
int k_r = x / 4;
int c = y % 4;
return kernelOffset * 16 + 4 * r + c;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
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;
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
)
{
return Buffer + _boarder.GetIndexOffset(x, y, in _size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe ref MatrixKernel<T> GetKernelUnsafe(
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;
return ref _buffer[_boarder.GetIndexOffset(k_c, k_r, in _size)];
}
}
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)
{
return Buffer + _boarder.GetIndexOffset(x, y, in _size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe ref MatrixKernel<T> GetKernelUnsafe(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;
return ref _buffer[_boarder.GetIndexOffset(k_c, k_r, in _size)];
}
}
}
@@ -1,72 +1,72 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixStorage"
// 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.HighPerformance;
using StgSharp.HighPerformance.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixStorage"
// 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;
using StgSharp.Mathematics.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using HLSFAllocator = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator;
using HLSFHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
namespace StgSharp.Mathematics.Numeric
{
public abstract class MatrixStorage<T> : IDisposable where T : unmanaged, INumber<T>
{
internal unsafe ref MatrixKernel<T> this[long index]
{
get { return ref Unsafe.AsRef<MatrixKernel<T>>(BufferPointer + MatrixKernel<T>.Size * index); }
}
protected internal abstract unsafe T* BufferPointer { get; }
public abstract void Dispose();
}
internal class MatrixStorageHLSF<T>(HLSFAllocator allocator, HLSFHandle handle) : MatrixStorage<T>
where T : unmanaged, INumber<T>
{
internal HLSFAllocator _allocator = allocator;
internal HLSFHandle _handle = handle;
protected internal override unsafe T* BufferPointer => (T*)_handle.Pointer;
public override void Dispose()
{
allocator.Free(_handle);
}
}
using HLSFAllocator = global::StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocator;
using HLSFHandle = global::StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocationHandle;
namespace StgSharp.Mathematics.Numeric
{
public abstract class MatrixStorage<T> : IDisposable where T: unmanaged, INumber<T>
{
internal unsafe ref MatrixKernel<T> this[long index]
{
get { return ref Unsafe.AsRef<MatrixKernel<T>>(BufferPointer + MatrixKernel<T>.Size * index); }
}
protected internal abstract unsafe T* BufferPointer { get; }
public abstract void Dispose();
}
internal class MatrixStorageHLSF<T>(HLSFAllocator allocator, HLSFHandle handle) : MatrixStorage<T>
where T: unmanaged, INumber<T>
{
internal HLSFAllocator _allocator = allocator;
internal HLSFHandle _handle = handle;
protected internal override unsafe T* BufferPointer => (T*)_handle.Pointer;
public override void Dispose()
{
allocator.Free(_handle);
}
}
}
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="MatrixCompute.Float"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
// 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
@@ -26,8 +26,8 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Collections;
using StgSharp.HighPerformance;
using StgSharp.Internal;
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
@@ -42,11 +42,7 @@ namespace StgSharp.Mathematics.Numeric
public static partial class MatrixCompute
{
public static unsafe void Add(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
public static unsafe void Add(Matrix<float> left, Matrix<float> right, Matrix<float> ans)
{
int f32 = (int)MatrixElementType.F32;
if (left.ColumnLength != right.ColumnLength ||
@@ -92,10 +88,7 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public static unsafe void Fill(
Matrix<float> ans,
float value
)
public static unsafe void Fill(Matrix<float> ans, float value)
{
int f32 = (int)MatrixElementType.F32;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
@@ -126,11 +119,7 @@ namespace StgSharp.Mathematics.Numeric
taskGroup.Dispose();
}
public static unsafe void Mul(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
public static unsafe void Mul(Matrix<float> left, Matrix<float> right, Matrix<float> ans)
{
int f32 = (int)MatrixElementType.F32;
@@ -168,8 +157,7 @@ namespace StgSharp.Mathematics.Numeric
NativeIntrinsic.Context
.mat[f32].kernel_tile_fma((MatrixKernel*)left.Buffer,
(MatrixKernel*)right.Buffer,
(MatrixKernel*)ans.Buffer,
enumeration);
(MatrixKernel*)ans.Buffer, enumeration);
}
}
@@ -196,18 +184,13 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public static unsafe void Mul(
Matrix<float> left,
float right,
Matrix<float> ans
)
public static unsafe void Mul(Matrix<float> left, float right, Matrix<float> ans)
{
int f32 = (int)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) {
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;
@@ -248,11 +231,7 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public static unsafe void Sub(
Matrix<float> left,
Matrix<float> right,
Matrix<float> ans
)
public static unsafe void Sub(Matrix<float> left, Matrix<float> right, Matrix<float> ans)
{
int f32 = (int)MatrixElementType.F32;
if (left.ColumnLength != right.ColumnLength ||
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="MatrixCompute"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
// 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
@@ -25,8 +25,8 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance;
using StgSharp.Internal;
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -45,8 +45,8 @@ namespace StgSharp.Mathematics.Numeric
MatrixKernel<T>* buffer,
int colLength,
int x,
int y
) where T : unmanaged, INumber<T>
int y)
where T: unmanaged, INumber<T>
{
return (MatrixKernel*)(buffer + (colLength * x + y));
}
@@ -2,8 +2,8 @@
// -----------------------------------------------------------------------
// file="MatrixCompute.double"
// Project: StgSharp
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
// 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
@@ -25,8 +25,8 @@
//
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.HighPerformance;
using StgSharp.Internal;
using StgSharp.Mathematics;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -38,11 +38,7 @@ namespace StgSharp.Mathematics.Numeric
public partial class MatrixCompute
{
public static unsafe void Add(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
public static unsafe void Add(Matrix<double> left, Matrix<double> right, Matrix<double> ans)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != right.ColumnLength ||
@@ -88,10 +84,7 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public static unsafe void Fill(
Matrix<double> ans,
double value
)
public static unsafe void Fill(Matrix<double> ans, double value)
{
int f64 = (int)MatrixElementType.F64;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
@@ -122,11 +115,7 @@ namespace StgSharp.Mathematics.Numeric
taskGroup.Dispose();
}
public static unsafe void Mul(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
public static unsafe void Mul(Matrix<double> left, Matrix<double> right, Matrix<double> ans)
{
int f64 = (int)MatrixElementType.F64;
@@ -158,8 +147,7 @@ namespace StgSharp.Mathematics.Numeric
NativeIntrinsic.Context
.mat[f64].kernel_tile_fma((MatrixKernel*)left.Buffer,
(MatrixKernel*)right.Buffer,
(MatrixKernel*)ans.Buffer,
enumeration);
(MatrixKernel*)ans.Buffer, enumeration);
}
}
if (count > 256) {
@@ -185,18 +173,13 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public static unsafe void Mul(
Matrix<double> left,
double right,
Matrix<double> ans
)
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) {
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;
@@ -237,11 +220,7 @@ namespace StgSharp.Mathematics.Numeric
return;
}
public static unsafe void Sub(
Matrix<double> left,
Matrix<double> right,
Matrix<double> ans
)
public static unsafe void Sub(Matrix<double> left, Matrix<double> right, Matrix<double> ans)
{
int f64 = (int)MatrixElementType.F64;
if (left.ColumnLength != right.ColumnLength ||
@@ -1,80 +1,76 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel.Publish"
// 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.HighPerformance;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel.Publish"
// 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.Collections;
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 static partial class MatrixParallel
{
private const int MIN_TASK_PER_THREAD = 256;
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 static partial class MatrixParallel
{
private const int MIN_TASK_PER_THREAD = 256;
private const int REC_TASK_PER_THREAD = 1024;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe MatrixParallelWrap ScheduleTask(
MatrixParallelTask* package
)
{
switch (package->ComputeMode.OperationStyle)
{
case MatrixIndexStyle.BUFFER_INDEX:
return ScheduleBufferTask(package);
default:
throw new InvalidOperationException($"Unknown mode {package->ComputeMode.OperationStyle}.");
}
}
private static unsafe MatrixParallelWrap ScheduleBufferTask(
MatrixParallelTask* package
)
{
int primCount = package->PrimCount;
int secCount = package->SecCount;
internal static unsafe MatrixParallelWrap ScheduleTask(MatrixParallelTask* package)
{
switch (package->ComputeMode.OperationStyle)
{
case MatrixIndexStyle.BUFFER_INDEX:
return ScheduleBufferTask(package);
default:
throw new InvalidOperationException($"Unknown mode {package->ComputeMode.OperationStyle}.");
}
}
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;
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
MatrixParallelWrap wrap = new MatrixParallelWrap(pool);
wrap.TaskQueue = MatrixParallelQueue.Rent(package);
return wrap;
}
}
long recommendCount = count / 1024;
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
MatrixParallelWrap wrap = new MatrixParallelWrap(pool);
wrap.TaskQueue = MatrixParallelQueue.Rent(package);
return wrap;
}
}
}
@@ -1,132 +1,124 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel"
// 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.HighPerformance.Memory;
using StgSharp.Internal;
using StgSharp.Mathematics.Internal;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public static partial class MatrixParallel
{
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallel"
// 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.Collections;
using StgSharp.Internal;
using StgSharp.Mathematics.Intrinsic;
using StgSharp.Mathematics.Memory;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Mathematics.Numeric
{
public static partial class MatrixParallel
{
private static bool _meaningful;
private static CapacityFixedStack<MatrixParallelThread> _threads;
private static ConcurrentDictionary<SIMDID, nint> contextMap;
private static SlabAllocator<IntrinsicContext> contextAllocator;
public static bool IsParallelSupported { get; } = Environment.ProcessorCount > 6;
public static bool IsParallelMeaningful => Environment.ProcessorCount > 6 && IsInitialized;
private static bool IsInitialized { get; set; } = false;
internal static unsafe IntrinsicContext* GetContext(
SIMDID simd
)
{
if (!IsParallelSupported) {
return null;
}
if (contextMap.TryGetValue(simd, out nint handle))
{
return (IntrinsicContext*)handle;
} else
{
private static SlabAllocator<IntrinsicContext> contextAllocator;
public static bool IsParallelSupported { get; } = Environment.ProcessorCount > 6;
public static bool IsParallelMeaningful => Environment.ProcessorCount > 6 && IsInitialized;
private static bool IsInitialized { get; set; } = false;
internal static unsafe IntrinsicContext* GetContext(SIMDID simd)
{
if (!IsParallelSupported) {
return null;
}
if (contextMap.TryGetValue(simd, out nint handle))
{
return (IntrinsicContext*)handle;
} else
{
IntrinsicContext* context = (IntrinsicContext*)contextAllocator.Allocate();
return context;
}
}
internal static void Init()
{
if (IsInitialized) {
return;
}
if (!IsParallelSupported)
{
IsInitialized = true;
return;
}
MatrixParallelFactory.Init();
contextAllocator = SlabAllocator<IntrinsicContext>.Create(4, SlabBufferLayout.Chunked, false);
contextMap = [];
int count = Environment.ProcessorCount;
_threads = new(count);
for (int i = 0; i < count; i++)
{
MatrixParallelThread thread = new MatrixParallelThread(i);
_threads.Push(thread);
SpinWait.SpinUntil(() => thread.State == MatrixThreadState.Ready);
return context;
}
}
internal static void Init()
{
if (IsInitialized) {
return;
}
if (!IsParallelSupported)
{
IsInitialized = true;
return;
}
MatrixParallelFactory.Init();
contextAllocator = SlabAllocator<IntrinsicContext>.Create(4, SlabBufferLayout.Chunked, false);
contextMap = [];
int count = Environment.ProcessorCount;
_threads = new(count);
for (int i = 0; i < count; i++)
{
MatrixParallelThread thread = new MatrixParallelThread(i);
_threads.Push(thread);
SpinWait.SpinUntil(() => thread.State == MatrixThreadState.Ready);
}
// TODO 构建全局的保底上下文
foreach (MatrixParallelThread thread in _threads) { }
if (contextMap.Keys.Count == 1)
{
for (int i = 0; i < 4; i++)
{
MatrixParallelThread thread = _threads.Pop();
thread.Dispose();
}
} else
{
// TODO 排序并丢弃四个能力最弱线程
}
_awaitingLeaderHandle = new AwaitingQueue();
IsInitialized = true;
}
[LibraryImport(Native.LibName, EntryPoint = "sn_compare_simd")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static unsafe partial ulong CompareSIMDID(
IntrinsicContext* context,
ulong id
);
[LibraryImport(Native.LibName, EntryPoint = "load_intrinsic_function")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static unsafe partial void LoadIntrinsicFunction(
IntrinsicContext* context,
ulong id
);
}
foreach (MatrixParallelThread thread in _threads) { }
if (contextMap.Keys.Count == 1)
{
for (int i = 0; i < 4; i++)
{
MatrixParallelThread thread = _threads.Pop();
thread.Dispose();
}
} else
{
// TODO 排序并丢弃四个能力最弱线程
}
_awaitingLeaderHandle = new AwaitingQueue();
IsInitialized = true;
}
[LibraryImport(Native.LibName, EntryPoint = "sn_compare_simd")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static unsafe partial ulong CompareSIMDID(IntrinsicContext* context, ulong id);
[LibraryImport(Native.LibName, EntryPoint = "load_intrinsic_function")]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
private static unsafe partial void LoadIntrinsicFunction(IntrinsicContext* context, ulong id);
}
}
@@ -1,64 +1,60 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelTask"
// 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.HighPerformance;
using StgSharp.Mathematics.Internal;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Numeric
{
[StructLayout(LayoutKind.Explicit)]
internal unsafe struct MatrixParallelTask
{
[FieldOffset(0)]public MatrixKernel* Mat1; // 8
[FieldOffset(8)] public MatrixKernel* Mat2; // 8
[FieldOffset(16)] public MatrixKernel* Mat3; // 16
[FieldOffset(32)] public int Common_i;
[FieldOffset(36)] public int Common_j;
[FieldOffset(40)] public int Common_k;
[FieldOffset(44)] public int i;
[FieldOffset(48)] public int j;
[FieldOffset(52)] public int k;
[FieldOffset(56)] public MatrixElementType ElementType; // 56
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelTask"
// 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;
using StgSharp.Mathematics.Intrinsic;
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace StgSharp.Mathematics.Numeric
{
[StructLayout(LayoutKind.Explicit)]
internal unsafe struct MatrixParallelTask
{
[FieldOffset(0)]public MatrixKernel* Mat1; // 8
[FieldOffset(8)] public MatrixKernel* Mat2; // 8
[FieldOffset(16)] public MatrixKernel* Mat3; // 16
[FieldOffset(32)] public int Common_i;
[FieldOffset(36)] public int Common_j;
[FieldOffset(40)] public int Common_k;
[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
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy(
MatrixParallelTask* source,
MatrixParallelTask* target
)
{
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTask),
sizeof(MatrixParallelTask));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy(MatrixParallelTask* source, MatrixParallelTask* target)
{
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTask), sizeof(MatrixParallelTask));
}
}
}
@@ -1,105 +1,99 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// 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.HighPerformance;
using StgSharp.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 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.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;
NativeIntrinsic.Context.mat[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;
NativeIntrinsic.Context.mat[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;
NativeIntrinsic.Context.mat[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;
NativeIntrinsic.Context.mat[f64].kernel_tile_fma(leftBuffer, rightBuffer, ansBuffer, enumeration);
}
}
}
}
@@ -1,75 +1,70 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// 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.HighPerformance;
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 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;
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;
}
}
}
}
@@ -26,7 +26,7 @@
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
using StgSharp.Internal;
using StgSharp.Mathematics.Internal;
using StgSharp.Mathematics.Intrinsic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -1,48 +1,48 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixTaskFactory"
// 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.HighPerformance;
using StgSharp.HighPerformance.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixTaskFactory"
// 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;
using StgSharp.Mathematics.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using hlsfAllocator = StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator;
namespace StgSharp.Mathematics.Numeric
{
internal static unsafe class MatrixParallelFactory
{
using hlsfAllocator = StgSharp.Mathematics.Memory.HybridLayerSegregatedFitAllocator;
namespace StgSharp.Mathematics.Numeric
{
internal static unsafe class MatrixParallelFactory
{
private static hlsfAllocator _intermediateResult;
private static
@@ -57,63 +57,57 @@ namespace StgSharp.Mathematics.Numeric
private static SlabAllocator<MatrixParallelTask> _wrapAllocator;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MatrixParallelTask* CreateBaseTask()
{
MatrixParallelTask* p = (MatrixParallelTask*)_wrapAllocator.Allocate();
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTask));
s.Fill(0);
return p;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarPacket* CreateScalarPacket()
{
ScalarPacket* p = (ScalarPacket*)_scalarAllocator.Allocate();
return p;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe MatrixParallelTask* FromExistPackage(
MatrixParallelTask* exist
)
{
MatrixParallelTask* ptr = (MatrixParallelTask*)_wrapAllocator.Allocate();
MatrixParallelTask.Copy(exist, ptr);
return ptr;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MatrixParallelTask* CreateBaseTask()
{
MatrixParallelTask* p = (MatrixParallelTask*)_wrapAllocator.Allocate();
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTask));
s.Fill(0);
return p;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarPacket* CreateScalarPacket()
{
ScalarPacket* p = (ScalarPacket*)_scalarAllocator.Allocate();
return p;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe MatrixParallelTask* FromExistPackage(MatrixParallelTask* exist)
{
MatrixParallelTask* ptr = (MatrixParallelTask*)_wrapAllocator.Allocate();
MatrixParallelTask.Copy(exist, ptr);
return ptr;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Release(
ScalarPacket* source
)
{
_scalarAllocator.Free((nuint)source);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Release(
MatrixParallelTask* source
)
{
if (source->Scalar != null) {
_scalarAllocator.Free((nuint)source->Scalar);
}
_wrapAllocator.Free((nuint)source);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Init()
{
if (_intermediateResult is null)
{
_intermediateResult = new hlsfAllocator(64 * 16 * 16);
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64 * 1024, SlabBufferLayout.Chunked);
public static void Release(ScalarPacket* source)
{
_scalarAllocator.Free((nuint)source);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Release(MatrixParallelTask* source)
{
if (source->Scalar != null) {
_scalarAllocator.Free((nuint)source->Scalar);
}
_wrapAllocator.Free((nuint)source);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Init()
{
if (_intermediateResult is null)
{
_intermediateResult = new hlsfAllocator(64 * 16 * 16);
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64 * 1024, SlabBufferLayout.Chunked);
_wrapAllocator = SlabAllocator<MatrixParallelTask>.
Create(128 * 1024, SlabBufferLayout.Chunked);
}
}
}
Create(128 * 1024, SlabBufferLayout.Chunked);
}
}
}
}
@@ -0,0 +1,142 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// 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;
}
}
}