keep working on PLN facotrize
This commit is contained in:
@@ -65,7 +65,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
|
||||
long kernelCount = layout switch
|
||||
{
|
||||
MatrixLayout.DenseSquare => (long)kernelColumns * kernelRows,
|
||||
MatrixLayout.DenseRectangle => (long)kernelColumns * kernelRows,
|
||||
MatrixLayout.UpperTriangle => TriangularKernelCount(kernelColumns),
|
||||
MatrixLayout.LowerTriangle => TriangularKernelCount(kernelRows),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(layout))
|
||||
@@ -79,16 +79,10 @@ namespace StgSharp.Mathematics.Numeric
|
||||
HybridLayerSegregatedFitAllocationHandle handle = allocator.Alloc((uint)requiredBytes);
|
||||
MatrixStorageHLSF<T> storage = new MatrixStorageHLSF<T>(allocator, handle);
|
||||
|
||||
Matrix<T> matrix = new Matrix<T>
|
||||
{
|
||||
Layout = layout,
|
||||
KernelColumnLength = kernelColumns,
|
||||
KernelRowLength = kernelRows,
|
||||
};
|
||||
|
||||
matrix._buffer = storage;
|
||||
matrix._boarder = MatrixKernelBoarder.Create(layout);
|
||||
matrix._size = new MatrixSize(columnLength, rowLength, kernelColumns, kernelRows);
|
||||
Matrix<T> matrix = new Matrix<T>(MatrixKernelBoarder.Create(layout), new MatrixSize(columnLength,
|
||||
rowLength,
|
||||
kernelColumns,
|
||||
kernelRows), storage);
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
@@ -41,11 +41,21 @@ namespace StgSharp.Mathematics.Numeric
|
||||
private protected static readonly int t_count = 16 / sizeof(T);
|
||||
|
||||
private protected static readonly int t_size = sizeof(T);
|
||||
private MatrixKernelBoarder _boarder;
|
||||
private MatrixSize _size;
|
||||
private MatrixStorage<T> _buffer;
|
||||
private readonly MatrixKernelBoarder _boarder;
|
||||
private readonly MatrixSize _size;
|
||||
private readonly MatrixStorage<T> _buffer;
|
||||
|
||||
private protected Matrix() { }
|
||||
private protected Matrix(
|
||||
MatrixKernelBoarder boarder,
|
||||
MatrixSize size,
|
||||
MatrixStorage<T> buffer
|
||||
|
||||
)
|
||||
{
|
||||
_boarder = boarder;
|
||||
_size = size;
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public T this[int x, int y]
|
||||
{
|
||||
@@ -122,19 +132,33 @@ namespace StgSharp.Mathematics.Numeric
|
||||
get => (MatrixKernel<T>*)_buffer.BufferPointer;
|
||||
}
|
||||
|
||||
protected internal int KernelColumnLength { get; init; }
|
||||
protected internal int KernelColumnLength => _size.KernelColumnLength;
|
||||
|
||||
protected internal int KernelRowLength { get; init; }
|
||||
protected internal int KernelRowLength => _size.KernelRowLength;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public unsafe ref MatrixKernel<T> GetMatrixKernel(int x, int y)
|
||||
{
|
||||
fixed (MatrixSize *msPtr = &_size)
|
||||
{
|
||||
MatrixKernelEnumerator* e = (MatrixKernelEnumerator*)msPtr;
|
||||
return ref _boarder.IsInBuffer(x, y, e) ?
|
||||
ref _buffer[_boarder.GetIndexOffset(x, y, e)] :
|
||||
ref Unsafe.NullRef<MatrixKernel<T>>();
|
||||
}
|
||||
MatrixKernelEnumerator enumerator = new(_size.KernelColumnLength, _size.KernelRowLength,
|
||||
x, y);
|
||||
return ref _boarder.IsInBuffer(x, y, in enumerator) ?
|
||||
ref _buffer[_boarder.GetIndexOffset(x, y, in enumerator)] :
|
||||
ref Unsafe.NullRef<MatrixKernel<T>>();
|
||||
}
|
||||
|
||||
[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 >> 2;
|
||||
int k_r = x >> 2;
|
||||
int c = y & 3;
|
||||
int r = x & 3;
|
||||
|
||||
MatrixKernelEnumerator enumerator = new(_size.KernelColumnLength, _size.KernelRowLength,
|
||||
k_c, k_r);
|
||||
ref MatrixKernel<T> kernel = ref _buffer[_boarder.GetIndexOffset(k_c, k_r, in enumerator)];
|
||||
return ref kernel[c, r];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,169 +25,159 @@
|
||||
//
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
using StgSharp.HighPerformance;
|
||||
using System;
|
||||
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 enum MatrixLayout
|
||||
{
|
||||
|
||||
DenseSquare,
|
||||
DenseRectangle,
|
||||
UpperTriangle,
|
||||
LowerTriangle,
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct MatrixKernelBoarder
|
||||
public abstract class MatrixKernelBoarder
|
||||
{
|
||||
|
||||
public readonly delegate* unmanaged[Cdecl]
|
||||
<int, int, MatrixKernelEnumerator*, long> GetIndexOffset;
|
||||
|
||||
public readonly delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool> IsInBuffer;
|
||||
|
||||
[Obsolete("Do not use constructor, use static method instead", true)]
|
||||
public MatrixKernelBoarder() { }
|
||||
|
||||
public MatrixKernelBoarder(
|
||||
delegate* unmanaged[Cdecl]
|
||||
<int, int, MatrixKernelEnumerator*, long> getOffset,
|
||||
delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool> inBuffer)
|
||||
{
|
||||
GetIndexOffset = getOffset;
|
||||
IsInBuffer = inBuffer;
|
||||
}
|
||||
|
||||
private static delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, long> GetIndexOffsetDenseSquarePtr { get; } =
|
||||
(delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, long>)&GetIndexOffsetDenseSquare;
|
||||
|
||||
private static delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, long> GetIndexOffsetUpperTrianglePtr { get; } =
|
||||
(delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, long>)&GetIndexOffsetUpperTriangle;
|
||||
|
||||
private static delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, long> GetIndexOffsetLowerTrianglePtr { get; } =
|
||||
(delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, long>)&GetIndexOffsetLowerTriangle;
|
||||
|
||||
private static delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool> IsInBufferDenseSquarePtr { get; } =
|
||||
(delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool>)&IsInBufferDenseSquare;
|
||||
|
||||
private static delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool> IsInBufferUpperTrianglePtr { get; } =
|
||||
(delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool>)&IsInBufferUpperTriangle;
|
||||
|
||||
private static delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool> IsInBufferLowerTrianglePtr { get; } =
|
||||
(delegate* unmanaged[Cdecl]<int, int, MatrixKernelEnumerator*, bool>)&IsInBufferLowerTriangle;
|
||||
private static readonly MatrixKernelBoarder DenseSquareInstance = new DenseSquareKernelBoarder();
|
||||
private static readonly MatrixKernelBoarder LowerTriangleInstance = new LowerTriangleKernelBoarder();
|
||||
private static readonly MatrixKernelBoarder UpperTriangleInstance = new UpperTriangleKernelBoarder();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static MatrixKernelBoarder Create(MatrixLayout layout)
|
||||
{
|
||||
return layout switch
|
||||
{
|
||||
MatrixLayout.DenseSquare => new MatrixKernelBoarder(GetIndexOffsetDenseSquarePtr, IsInBufferDenseSquarePtr),
|
||||
|
||||
MatrixLayout.UpperTriangle => new MatrixKernelBoarder(GetIndexOffsetUpperTrianglePtr, IsInBufferUpperTrianglePtr),
|
||||
MatrixLayout.LowerTriangle => new MatrixKernelBoarder(GetIndexOffsetLowerTrianglePtr, IsInBufferLowerTrianglePtr),
|
||||
MatrixLayout.DenseRectangle => DenseSquareInstance,
|
||||
MatrixLayout.UpperTriangle => UpperTriangleInstance,
|
||||
MatrixLayout.LowerTriangle => LowerTriangleInstance,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(layout)),
|
||||
};
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs =[ typeof(CallConvCdecl) ])]
|
||||
private static long GetIndexOffsetDenseSquare(
|
||||
int x_kernel,
|
||||
int y_kernel,
|
||||
MatrixKernelEnumerator* enumerator)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public abstract long GetIndexOffset(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public abstract bool IsInBuffer(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected static long GetTriangularOrder(in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
long x = x_kernel;
|
||||
long y = y_kernel;
|
||||
long rows = enumerator->KernelRowLength;
|
||||
return x * rows + y;
|
||||
return Math.Min(enumerator.KernelColumnLength, enumerator.KernelRowLength);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs =[ typeof(CallConvCdecl) ])]
|
||||
private static long GetIndexOffsetLowerTriangle(
|
||||
int x_kernel,
|
||||
int y_kernel,
|
||||
MatrixKernelEnumerator* enumerator)
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected static bool IsWithinKernelDomain(
|
||||
in MatrixKernelEnumerator enumerator,
|
||||
int xKernel,
|
||||
int yKernel)
|
||||
{
|
||||
return xKernel >= 0 &&
|
||||
yKernel >= 0 &&
|
||||
xKernel < enumerator.KernelColumnLength &&
|
||||
yKernel < enumerator.KernelRowLength;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected static bool IsWithinTriangularDomain(
|
||||
in MatrixKernelEnumerator enumerator,
|
||||
int xKernel,
|
||||
int yKernel)
|
||||
{
|
||||
long order = GetTriangularOrder(enumerator);
|
||||
long x = x_kernel;
|
||||
long y = y_kernel;
|
||||
|
||||
long prefixColumns = x * order - (x * (x - 1L)) / 2L;
|
||||
return prefixColumns + (y - x);
|
||||
return xKernel >= 0 && yKernel >= 0 && xKernel < order && yKernel < order;
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs =[ typeof(CallConvCdecl) ])]
|
||||
private static long GetIndexOffsetUpperTriangle(
|
||||
int x_kernel,
|
||||
int y_kernel,
|
||||
MatrixKernelEnumerator* enumerator)
|
||||
private sealed class DenseSquareKernelBoarder : MatrixKernelBoarder
|
||||
{
|
||||
long x = x_kernel;
|
||||
long y = y_kernel;
|
||||
|
||||
long prefixColumns = (x * (x + 1L)) / 2L;
|
||||
return prefixColumns + y;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override long GetIndexOffset(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
long x = xKernel;
|
||||
long y = yKernel;
|
||||
long rows = enumerator.KernelRowLength;
|
||||
return x * rows + y;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool IsInBuffer(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
return IsWithinKernelDomain(enumerator, xKernel, yKernel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static long GetTriangularOrder(MatrixKernelEnumerator* enumerator)
|
||||
private sealed class LowerTriangleKernelBoarder : MatrixKernelBoarder
|
||||
{
|
||||
return Math.Min(enumerator->KernelColumnLength, enumerator->KernelRowLength);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override long GetIndexOffset(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
long order = GetTriangularOrder(enumerator);
|
||||
long x = xKernel;
|
||||
long y = yKernel;
|
||||
|
||||
long prefixColumns = x * order - (x * (x - 1L)) / 2L;
|
||||
return prefixColumns + (y - x);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool IsInBuffer(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
return IsWithinTriangularDomain(enumerator, xKernel, yKernel) && yKernel >= xKernel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs =[ typeof(CallConvCdecl) ])]
|
||||
private static bool IsInBufferDenseSquare(
|
||||
int x_kernel,
|
||||
int y_kernel,
|
||||
MatrixKernelEnumerator* enumerator)
|
||||
private sealed unsafe class UpperTriangleKernelBoarder : MatrixKernelBoarder
|
||||
{
|
||||
return IsWithinKernelDomain(enumerator, x_kernel, y_kernel);
|
||||
}
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs =[ typeof(CallConvCdecl) ])]
|
||||
private static bool IsInBufferLowerTriangle(
|
||||
int x_kernel,
|
||||
int y_kernel,
|
||||
MatrixKernelEnumerator* enumerator)
|
||||
{
|
||||
return IsWithinTriangularDomain(enumerator, x_kernel, y_kernel) && y_kernel >= x_kernel;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override long GetIndexOffset(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
long x = xKernel;
|
||||
long y = yKernel;
|
||||
|
||||
[UnmanagedCallersOnly(CallConvs =[ typeof(CallConvCdecl) ])]
|
||||
private static bool IsInBufferUpperTriangle(
|
||||
int x_kernel,
|
||||
int y_kernel,
|
||||
MatrixKernelEnumerator* enumerator)
|
||||
{
|
||||
return IsWithinTriangularDomain(enumerator, x_kernel, y_kernel) && y_kernel <= x_kernel;
|
||||
}
|
||||
long prefixColumns = (x * (x + 1L)) / 2L;
|
||||
return prefixColumns + y;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool IsWithinKernelDomain(
|
||||
MatrixKernelEnumerator* enumerator,
|
||||
int x_kernel,
|
||||
int y_kernel)
|
||||
{
|
||||
return x_kernel >= 0 &&
|
||||
y_kernel >= 0 &&
|
||||
x_kernel < enumerator->KernelColumnLength &&
|
||||
y_kernel < enumerator->KernelRowLength;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool IsInBuffer(
|
||||
int xKernel,
|
||||
int yKernel,
|
||||
in MatrixKernelEnumerator enumerator)
|
||||
{
|
||||
return IsWithinTriangularDomain(enumerator, xKernel, yKernel) && yKernel <= xKernel;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static bool IsWithinTriangularDomain(
|
||||
MatrixKernelEnumerator* enumerator,
|
||||
int x_kernel,
|
||||
int y_kernel)
|
||||
{
|
||||
long order = GetTriangularOrder(enumerator);
|
||||
return x_kernel >= 0 && y_kernel >= 0 && x_kernel < order && y_kernel < order;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -202,6 +192,7 @@ namespace StgSharp.Mathematics.Numeric
|
||||
[FieldOffset(8)] public readonly int KernelColumnLength;
|
||||
[FieldOffset(12)] public readonly int KernelRowLength;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public MatrixSize(
|
||||
int elementColumnLength,
|
||||
int elementRowLength,
|
||||
@@ -223,8 +214,21 @@ namespace StgSharp.Mathematics.Numeric
|
||||
[FieldOffset(0)] public int CurrentColumn;
|
||||
[FieldOffset(4)] public int CurrentRow;
|
||||
|
||||
[FieldOffset(8)] public readonly int KernelColumnLength;
|
||||
[FieldOffset(8)] public readonly int KernelColumnLength;
|
||||
[FieldOffset(12)] public readonly int KernelRowLength;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public MatrixKernelEnumerator(
|
||||
int kernelColumnLength,
|
||||
int kernelRowLength,
|
||||
int currentColumn = 0,
|
||||
int currentRow = 0)
|
||||
{
|
||||
CurrentColumn = currentColumn;
|
||||
CurrentRow = currentRow;
|
||||
KernelColumnLength = kernelColumnLength;
|
||||
KernelRowLength = kernelRowLength;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user