Daily update on 20250921-173333 by Nitload Youmu. Additional Message : New design of matrix enumeration, capable for parallel task publication.
Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
@@ -1,33 +1,33 @@
|
|||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// file="RandomAccessibleStack.cs"
|
// file="RandomAccessibleStack.cs"
|
||||||
// Project: StgSharp
|
// Project: StgSharp
|
||||||
// AuthorGroup: Nitload Space
|
// AuthorGroup: Nitload Space
|
||||||
// Copyright (c) Nitload Space. All rights reserved.
|
// Copyright (c) Nitload Space. All rights reserved.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person
|
// Permission is hereby granted, free of charge, to any person
|
||||||
// obtaining a copy of this software and associated documentation
|
// obtaining a copy of this software and associated documentation
|
||||||
// files (the “Software”), to deal in the Software without restriction,
|
// files (the “Software”), to deal in the Software without restriction,
|
||||||
// including without limitation the rights to use, copy, modify, merge,
|
// including without limitation the rights to use, copy, modify, merge,
|
||||||
// publish, distribute, sublicense, and/or sell copies of the Software,
|
// publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
// and to permit persons to whom the Software is furnished to do so,
|
// and to permit persons to whom the Software is furnished to do so,
|
||||||
// subject to the following conditions:
|
// subject to the following conditions:
|
||||||
//
|
//
|
||||||
// The above copyright notice and
|
// The above copyright notice and
|
||||||
// this permission notice shall be included in all copies
|
// this permission notice shall be included in all copies
|
||||||
// or substantial portions of the Software.
|
// or substantial portions of the Software.
|
||||||
//
|
//
|
||||||
// THE SOFTWARE IS PROVIDED “AS IS”,
|
// THE SOFTWARE IS PROVIDED “AS IS”,
|
||||||
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
// 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,
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH
|
||||||
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -60,11 +60,11 @@ namespace StgSharp.Collections
|
|||||||
/// Initializes a new instance of the RandomAccessStack class that is empty and has the
|
/// Initializes a new instance of the RandomAccessStack class that is empty and has the
|
||||||
/// specified initial capacity.
|
/// specified initial capacity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RandomAccessibleStack( int capacity )
|
public RandomAccessibleStack(int capacity)
|
||||||
{
|
{
|
||||||
if( capacity < 0 ) {
|
if (capacity < 0) {
|
||||||
throw new ArgumentOutOfRangeException(
|
throw new ArgumentOutOfRangeException(
|
||||||
nameof( capacity ), "Capacity must be non-negative." );
|
nameof(capacity), "Capacity must be non-negative.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_array = new T[capacity];
|
_array = new T[capacity];
|
||||||
@@ -74,20 +74,20 @@ namespace StgSharp.Collections
|
|||||||
/// Gets or sets the element at the specified index in the stack (0 = bottom, Count-1 =
|
/// Gets or sets the element at the specified index in the stack (0 = bottom, Count-1 =
|
||||||
/// top).
|
/// top).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public T this[ int index ]
|
public T this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if( index < 0 || index >= _size ) {
|
if (index < 0 || index >= _size) {
|
||||||
throw new ArgumentOutOfRangeException( nameof( index ) );
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _array[ index ];
|
return _array[index];
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if( index < 0 || index >= _size ) {
|
if( index < 0 || index >= PrimSize ) {
|
||||||
throw new ArgumentOutOfRangeException( nameof( index ) );
|
throw new ArgumentOutOfRangeException( nameof( index ) );
|
||||||
}
|
}
|
||||||
_array[ index ] = value;
|
_array[ index ] = value;
|
||||||
@@ -106,7 +106,7 @@ namespace StgSharp.Collections
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
Array.Clear( _array, 0, _size );
|
Array.Clear(_array, 0, _size);
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_version++;
|
_version++;
|
||||||
}
|
}
|
||||||
@@ -118,14 +118,14 @@ namespace StgSharp.Collections
|
|||||||
public IEnumerator<T> GetEnumerator()
|
public IEnumerator<T> GetEnumerator()
|
||||||
{
|
{
|
||||||
int expectedVersion = _version;
|
int expectedVersion = _version;
|
||||||
for( int i = _size - 1; i >= 0; i-- )
|
for (int i = _size - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if( expectedVersion != _version ) {
|
if (expectedVersion != _version) {
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
"Collection was modified during enumeration." );
|
"Collection was modified during enumeration.");
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return _array[ i ];
|
yield return _array[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,11 +134,11 @@ namespace StgSharp.Collections
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public T Peek()
|
public T Peek()
|
||||||
{
|
{
|
||||||
if( _size == 0 ) {
|
if (_size == 0) {
|
||||||
throw new InvalidOperationException( "Stack is empty." );
|
throw new InvalidOperationException("Stack is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return _array[ _size - 1 ];
|
return _array[_size - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -146,12 +146,12 @@ namespace StgSharp.Collections
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public T Pop()
|
public T Pop()
|
||||||
{
|
{
|
||||||
if( _size == 0 ) {
|
if (_size == 0) {
|
||||||
throw new InvalidOperationException( "Stack is empty." );
|
throw new InvalidOperationException("Stack is empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
T item = _array[ --_size ];
|
T item = _array[--_size];
|
||||||
_array[ _size ] = default!;
|
_array[_size] = default!;
|
||||||
_version++;
|
_version++;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -159,24 +159,24 @@ namespace StgSharp.Collections
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds an item to the top of the stack.
|
/// Adds an item to the top of the stack.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Push( T item )
|
public void Push(T item)
|
||||||
{
|
{
|
||||||
if( _size == _array.Length ) {
|
if (_size == _array.Length) {
|
||||||
EnsureCapacity( _size + 1 );
|
EnsureCapacity(_size + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_array[ _size++ ] = item;
|
_array[_size++] = item;
|
||||||
_version++;
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureCapacity( int min )
|
private void EnsureCapacity(int min)
|
||||||
{
|
{
|
||||||
int newCapacity = _array.Length == 0 ? DefaultCapacity : _array.Length * 2;
|
int newCapacity = _array.Length == 0 ? DefaultCapacity : _array.Length * 2;
|
||||||
if( newCapacity < min ) {
|
if (newCapacity < min) {
|
||||||
newCapacity = min;
|
newCapacity = min;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.Resize( ref _array, newCapacity );
|
Array.Resize(ref _array, newCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|||||||
@@ -59,27 +59,26 @@ namespace StgSharp.HighPerformance.Memory
|
|||||||
/// Thrown when requesting unsupported configurations.
|
/// Thrown when requesting unsupported configurations.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para><strong> Important Threading Considerations: </strong></para> <para>While SLAB
|
/// <para><strong> Important Threading Considerations: </strong></para> <para> While SLAB
|
||||||
/// /// allocators themselves may be designed for single-threaded use, allocated objects
|
/// allocators themselves may be designed for single-threaded use, allocated objects are
|
||||||
/// are /// frequently shared across multiple threads in real-world applications. Due
|
/// frequently shared across multiple threads in real-world applications. Due to the
|
||||||
/// to the /// special implementation of expandable concurrent sequential SLAB
|
/// special implementation of expandable concurrent sequential SLAB allocators, they rely
|
||||||
/// allocators, they rely /// on internal expansion locks to ensure that memory buffer
|
/// on internal expansion locks to ensure that memory buffer expansions (which involve
|
||||||
/// expansions (which involve /// copying the entire buffer to a new location) do not
|
/// copying the entire buffer to a new location) do not occur while other threads are
|
||||||
/// occur while other threads are /// reading from allocated regions. </para>
|
/// reading from allocated regions.</para> <para><strong> Sequential Layout Limitations:
|
||||||
/// <para><strong>Sequential Layout Limitations: ///</strong><br /> Sequential layout SLAB
|
/// </strong><br /> Sequential layout SLAB allocators cannot provide a single-threaded
|
||||||
/// allocators cannot provide a single-threaded /// version because:<list
|
/// version because:<list type="bullet"><item><description> They use contiguous memory
|
||||||
/// type="bullet"><item><description>They use contiguous memory /// layout that requires
|
/// layout that requires buffer expansion when capacity is exceeded
|
||||||
/// buffer expansion when capacity is exceeded
|
/// </description></item><item><description> Buffer expansion involves copying all
|
||||||
/// ///</description></item><item><description>Buffer expansion involves copying all ///
|
/// existing data to a new memory location </description></item><item><description>
|
||||||
/// existing data to a new memory location</description></item><item><description> ///
|
/// Without proper synchronization, concurrent access to allocated objects during
|
||||||
/// Without proper synchronization, concurrent access to allocated objects during ///
|
/// expansion would cause memory corruption </description></item><item><description> The
|
||||||
/// expansion would cause memory corruption</description></item><item><description>The ///
|
/// expansion lock mechanism is essential even if allocation itself is single-
|
||||||
/// expansion lock mechanism is essential even if allocation itself is single-threaded
|
/// threaded</description></item></list></para> <para><strong> Chunked Layout:
|
||||||
/// ///</description></item></list></para> <para><strong> Chunked Layout: </strong><br />
|
/// </strong><br /> Chunked layout allocators can optionally provide single-threaded
|
||||||
/// /// Chunked layout allocators can optionally provide single-threaded versions since
|
/// versions since they don't require buffer expansion and copying. Each chunk is
|
||||||
/// they /// don't require buffer expansion and copying. Each chunk is allocated
|
/// allocated independently, avoiding the memory relocation issues present in sequential
|
||||||
/// independently, /// avoiding the memory relocation issues present in sequential
|
/// layouts.</para>
|
||||||
/// layouts. </para>
|
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static SlabAllocator<T> Create(nuint count, SlabBufferLayout layout, bool concurrentSupport = true)
|
public static SlabAllocator<T> Create(nuint count, SlabBufferLayout layout, bool concurrentSupport = true)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ namespace StgSharp.Internal.Intrinsic
|
|||||||
{
|
{
|
||||||
|
|
||||||
public delegate* unmanaged[Cdecl]<char*, int, int> city_hash_simplify;
|
public delegate* unmanaged[Cdecl]<char*, int, int> city_hash_simplify;
|
||||||
|
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> f32_add;
|
||||||
|
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> f32_fma;
|
||||||
|
public delegate* unmanaged[Cdecl]<void*, float, void*, void> f32_scalar_mul;
|
||||||
|
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> f32_sub;
|
||||||
|
public delegate* unmanaged[Cdecl]<void*, void*, void> f32_transpose;
|
||||||
public delegate* unmanaged[Cdecl]<int, ulong> factorial_simd;
|
public delegate* unmanaged[Cdecl]<int, ulong> factorial_simd;
|
||||||
public delegate* unmanaged[Cdecl]<char*, int, int, int> index_pair;
|
public delegate* unmanaged[Cdecl]<char*, int, int, int> index_pair;
|
||||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> kernel_add;
|
|
||||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> kernel_fma;
|
|
||||||
public delegate* unmanaged[Cdecl]<MatrixKernel*, float, MatrixKernel*, void> kernel_scalar_mul;
|
|
||||||
public delegate* unmanaged[Cdecl]<void*, void*, void*, void> kernel_sub;
|
|
||||||
public delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, void> kernel_transpose;
|
|
||||||
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> normalize_3;
|
public delegate* unmanaged[Cdecl]<Vector4*, Vector4*, void> normalize_3;
|
||||||
|
|
||||||
public IntrinsicContext()
|
public IntrinsicContext()
|
||||||
|
|||||||
@@ -51,11 +51,11 @@ namespace StgSharp.Mathematics
|
|||||||
Matrix<float> result = GCMatrix<float>.FromDefault(left.ColumnLength, left.RowLength);
|
Matrix<float> result = GCMatrix<float>.FromDefault(left.ColumnLength, left.RowLength);
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage* handle = MatrixParallelFactory.CreateBaseTask();
|
MatrixParallelTaskPackage<float>* handle = MatrixParallelFactory.CreateBaseTask<float>();
|
||||||
handle->Left = left.Buffer;
|
handle->Left = left.Buffer;
|
||||||
handle->Right = right.Buffer;
|
handle->Right = right.Buffer;
|
||||||
handle->Result = result.Buffer;
|
handle->Result = result.Buffer;
|
||||||
handle->ComputeHandle = (IntPtr)InternalIO.Intrinsic.kernel_add;
|
handle->ComputeHandle = (IntPtr)InternalIO.Intrinsic.f32_add;
|
||||||
handle->LeftPrimOffset = 0;
|
handle->LeftPrimOffset = 0;
|
||||||
handle->RightPrimOffset = 0;
|
handle->RightPrimOffset = 0;
|
||||||
handle->LeftPrimStride = left.KernelColumnLength;
|
handle->LeftPrimStride = left.KernelColumnLength;
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ namespace StgSharp.Mathematics
|
|||||||
internal unsafe partial class GCMatrix<T> : Matrix<T> where T: unmanaged, INumber<T>
|
internal unsafe partial class GCMatrix<T> : Matrix<T> where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly MatrixKernel* _buffer;
|
private readonly MatrixKernel<T>* _buffer;
|
||||||
|
|
||||||
public GCMatrix(int column, int row)
|
public GCMatrix(int column, int row)
|
||||||
{
|
{
|
||||||
KernelColumnLength = (column + 3) / 4;
|
KernelColumnLength = (column + 3) / 4;
|
||||||
KernelRowLength = (row + 3) / t_count;
|
KernelRowLength = (row + 3) / t_count;
|
||||||
_buffer = (MatrixKernel*)NativeMemory.AlignedAlloc((nuint)(column * row * sizeof(T)), (nuint)World.DefaultSIMDAlignment);
|
_buffer = (MatrixKernel<T>*)NativeMemory.AlignedAlloc((nuint)(column * row * sizeof(T)), (nuint)World.DefaultSIMDAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ref T this[int column, int row]
|
public override ref T this[int column, int row]
|
||||||
@@ -60,8 +60,8 @@ namespace StgSharp.Mathematics
|
|||||||
AssertIndex(column, row);
|
AssertIndex(column, row);
|
||||||
int kernelColumn = column / 4, c = column % 4;
|
int kernelColumn = column / 4, c = column % 4;
|
||||||
int kernelRow = row / t_count, r = row % t_count;
|
int kernelRow = row / t_count, r = row % t_count;
|
||||||
ref MatrixKernel kernel = ref _buffer[kernelColumn + KernelColumnLength * kernelRow];
|
ref MatrixKernel<T> kernel = ref _buffer[kernelColumn + KernelColumnLength * kernelRow];
|
||||||
return ref kernel.UnsafeIndex<T>(c, r);
|
return ref kernel.UnsafeIndex(c, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,13 +71,13 @@ namespace StgSharp.Mathematics
|
|||||||
set => throw new NotImplementedException();
|
set => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override unsafe MatrixKernel* Buffer
|
internal override unsafe MatrixKernel<T>* Buffer
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _buffer;
|
get => _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override unsafe ref MatrixKernel GetMatrixKernel(int column, int row)
|
public override unsafe ref MatrixKernel<T> GetMatrixKernel(int column, int row)
|
||||||
{
|
{
|
||||||
AssertIndex(column, row);
|
AssertIndex(column, row);
|
||||||
int kernelColumn = column / 4;
|
int kernelColumn = column / 4;
|
||||||
@@ -89,27 +89,27 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
int kernelColumn = column / 4, c = column % 4;
|
int kernelColumn = column / 4, c = column % 4;
|
||||||
int kernelRow = row / t_count, r = row % t_count;
|
int kernelRow = row / t_count, r = row % t_count;
|
||||||
ref MatrixKernel kernel = ref _buffer[kernelColumn + (KernelColumnLength * kernelRow)];
|
ref MatrixKernel<T> kernel = ref _buffer[kernelColumn + (KernelColumnLength * kernelRow)];
|
||||||
return ref kernel.UnsafeIndex<T>(c, r);
|
return ref kernel.UnsafeIndex(c, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region enumeration
|
#region enumeration
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override unsafe MatrixSegmentEnumeration GetColumnEnumeration()
|
public override unsafe MatrixSegmentEnumeration<T> GetColumnEnumeration()
|
||||||
{
|
{
|
||||||
return new MatrixSegmentEnumeration(_buffer, KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelColumnLength);
|
return new MatrixSegmentEnumeration<T>(_buffer, KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelColumnLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override unsafe MatrixSegmentEnumeration GetRowEnumeration()
|
public override unsafe MatrixSegmentEnumeration<T> GetRowEnumeration()
|
||||||
{
|
{
|
||||||
return new MatrixSegmentEnumeration(_buffer, 1, KernelColumnLength, KernelColumnLength, KernelRowLength);
|
return new MatrixSegmentEnumeration<T>(_buffer, 1, KernelColumnLength, KernelColumnLength, KernelRowLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override unsafe MatrixSegmentEnumeration GetSequentialEnumeration()
|
public override unsafe MatrixSegmentEnumeration<T> GetSequentialEnumeration()
|
||||||
{
|
{
|
||||||
return new MatrixSegmentEnumeration(_buffer, KernelRowLength * KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelRowLength * KernelColumnLength);
|
return new MatrixSegmentEnumeration<T>(_buffer, KernelRowLength * KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelRowLength * KernelColumnLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ namespace StgSharp.Mathematics
|
|||||||
internal unsafe partial class HlsfMatrix<T> : Matrix<T> where T: unmanaged, INumber<T>
|
internal unsafe partial class HlsfMatrix<T> : Matrix<T> where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly MatrixKernel* k_buffer;
|
private readonly MatrixKernel<T>* k_buffer;
|
||||||
private readonly hlsfAllocator allocator;
|
private readonly hlsfAllocator allocator;
|
||||||
private readonly hlsfHandle handle;
|
private readonly hlsfHandle handle;
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
KernelColumnLength = (column + 3) / 4;
|
KernelColumnLength = (column + 3) / 4;
|
||||||
KernelRowLength = (row + 3) / t_count;
|
KernelRowLength = (row + 3) / t_count;
|
||||||
this.handle = allocator.Alloc((uint)(KernelColumnLength * KernelRowLength * sizeof(MatrixKernel)));
|
this.handle = allocator.Alloc((uint)(KernelColumnLength * KernelRowLength * sizeof(MatrixKernel<T>)));
|
||||||
k_buffer = (MatrixKernel*)handle.Pointer;
|
k_buffer = (MatrixKernel<T>*)handle.Pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ref T this[int column, int row]
|
public override ref T this[int column, int row]
|
||||||
@@ -64,8 +64,8 @@ namespace StgSharp.Mathematics
|
|||||||
AssertIndex(column, row);
|
AssertIndex(column, row);
|
||||||
int kernelColumn = column / 4, c = column % 4;
|
int kernelColumn = column / 4, c = column % 4;
|
||||||
int kernelRow = row / t_count, r = row % t_count;
|
int kernelRow = row / t_count, r = row % t_count;
|
||||||
ref MatrixKernel kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
ref MatrixKernel<T> kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
||||||
return ref kernel.UnsafeIndex<T>(c, r);
|
return ref kernel.UnsafeIndex(c, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,13 +75,13 @@ namespace StgSharp.Mathematics
|
|||||||
set => throw new NotImplementedException();
|
set => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override unsafe MatrixKernel* Buffer
|
internal override unsafe MatrixKernel<T>* Buffer
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => k_buffer;
|
get => k_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override unsafe ref MatrixKernel GetMatrixKernel(int column, int row)
|
public override unsafe ref MatrixKernel<T> GetMatrixKernel(int column, int row)
|
||||||
{
|
{
|
||||||
AssertIndex(column, row);
|
AssertIndex(column, row);
|
||||||
int kernelColumn = column / 4, c = column % 4;
|
int kernelColumn = column / 4, c = column % 4;
|
||||||
@@ -93,8 +93,8 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
int kernelColumn = column / 4, c = column % 4;
|
int kernelColumn = column / 4, c = column % 4;
|
||||||
int kernelRow = row / t_count, r = row % t_count;
|
int kernelRow = row / t_count, r = row % t_count;
|
||||||
ref MatrixKernel kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
ref MatrixKernel<T> kernel = ref k_buffer[(kernelColumn * kernelColumn) + kernelRow];
|
||||||
return ref kernel.UnsafeIndex<T>(c, r);
|
return ref kernel.UnsafeIndex(c, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
~HlsfMatrix()
|
~HlsfMatrix()
|
||||||
@@ -105,20 +105,20 @@ namespace StgSharp.Mathematics
|
|||||||
#region enumeration
|
#region enumeration
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override unsafe MatrixSegmentEnumeration GetColumnEnumeration()
|
public override unsafe MatrixSegmentEnumeration<T> GetColumnEnumeration()
|
||||||
{
|
{
|
||||||
return new MatrixSegmentEnumeration(k_buffer, KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelColumnLength);
|
return new MatrixSegmentEnumeration<T>(k_buffer, KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelColumnLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override unsafe MatrixSegmentEnumeration GetRowEnumeration()
|
public override unsafe MatrixSegmentEnumeration<T> GetRowEnumeration()
|
||||||
{
|
{
|
||||||
return new MatrixSegmentEnumeration(k_buffer, 1, KernelColumnLength, KernelColumnLength, KernelRowLength);
|
return new MatrixSegmentEnumeration<T>(k_buffer, 1, KernelColumnLength, KernelColumnLength, KernelRowLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override unsafe MatrixSegmentEnumeration GetSequentialEnumeration()
|
public override unsafe MatrixSegmentEnumeration<T> GetSequentialEnumeration()
|
||||||
{
|
{
|
||||||
return new MatrixSegmentEnumeration(k_buffer, KernelRowLength * KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelRowLength * KernelColumnLength);
|
return new MatrixSegmentEnumeration<T>(k_buffer, KernelRowLength * KernelColumnLength, KernelColumnLength * KernelRowLength, 1, KernelRowLength * KernelColumnLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ using StgSharp.HighPerformance;
|
|||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using hlsfAllocator = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator;
|
using hlsfAllocator = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocator;
|
||||||
|
|
||||||
// using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
|
// using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle;
|
||||||
@@ -135,55 +137,77 @@ namespace StgSharp.Mathematics
|
|||||||
|
|
||||||
public readonly unsafe ref struct MatrixSegmentEnumeration<T>(
|
public readonly unsafe ref struct MatrixSegmentEnumeration<T>(
|
||||||
MatrixKernel<T>* source,
|
MatrixKernel<T>* source,
|
||||||
int stride,
|
int primStride,
|
||||||
int size,
|
int primSize,
|
||||||
int secondaryStride,
|
int secondaryStride,
|
||||||
int secondarySize)
|
int secondarySize,
|
||||||
|
int primOffset = 0,
|
||||||
|
int secondaryOffset = 0)
|
||||||
where T: unmanaged, INumber<T>
|
where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly MatrixKernel<T>* _source = source;
|
private readonly MatrixKernel<T>* _source = source;
|
||||||
private readonly int _secondarySize = secondarySize;
|
internal readonly int SecondaryStride = secondaryStride;
|
||||||
private readonly int _secondaryStride = secondaryStride;
|
internal readonly int PrimOffset = primOffset;
|
||||||
|
|
||||||
private readonly int _size = size;
|
internal readonly int PrimSize = primSize;
|
||||||
private readonly int _stride = stride;
|
internal readonly int PrimStride = primStride;
|
||||||
|
internal readonly int SecondaryOffset = secondaryOffset;
|
||||||
|
internal readonly int SecondarySize = secondarySize;
|
||||||
|
|
||||||
public Enumerator<T> GetEnumerator()
|
internal readonly MatrixKernel<T>* Source
|
||||||
{
|
{
|
||||||
return new Enumerator<T>(in this);
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref struct Enumerator<T>(in MatrixSegmentEnumeration<T> enumeration) where T: unmanaged, INumber<T>
|
public Enumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return new Enumerator(in this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref struct Enumerator(in MatrixSegmentEnumeration<T> enumeration)
|
||||||
{
|
{
|
||||||
|
|
||||||
private MatrixKernel<T>* _current = enumeration._source - enumeration._stride;
|
private readonly MatrixKernel<T>* _source = enumeration._source;
|
||||||
private readonly MatrixKernel<T>* _end = enumeration._source + enumeration._size;
|
private int _indexCount = 0;
|
||||||
private readonly int _secondarySize = enumeration._secondarySize;
|
private readonly int _stride = enumeration.PrimStride;
|
||||||
private readonly int _secondaryStride = enumeration._secondaryStride;
|
private readonly long _bound = (long)enumeration.PrimSize * enumeration.PrimStride;
|
||||||
private readonly int _stride = enumeration._stride;
|
private long _index = (long)enumeration.PrimOffset * enumeration.PrimStride;
|
||||||
|
|
||||||
|
private readonly MatrixSegmentEnumeration<T> _enumeration;
|
||||||
|
|
||||||
public readonly MatrixSegment<T> Current
|
public readonly MatrixSegment<T> Current
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => new(_current, _secondarySize, _secondaryStride);
|
get => new(
|
||||||
|
_source + _index,
|
||||||
|
_enumeration.SecondarySize,
|
||||||
|
_enumeration.SecondaryStride,
|
||||||
|
_enumeration.PrimOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
_current += _stride;
|
_indexCount++;
|
||||||
return _current < _end;
|
_index += _stride;
|
||||||
|
if (_index >= _bound) {
|
||||||
|
_index = 0;
|
||||||
|
}
|
||||||
|
return _indexCount >= _enumeration.PrimSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly unsafe ref struct MatrixSegment<T>(MatrixKernel<T>* source, int size, int stride)
|
public readonly unsafe ref struct MatrixSegment<T>(MatrixKernel<T>* source, int size, int stride, int offset)
|
||||||
where T: unmanaged, INumber<T>
|
where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly MatrixKernel<T>* _source = source;
|
private readonly MatrixKernel<T>* _source = source;
|
||||||
|
private readonly int _offset = offset;
|
||||||
|
private readonly int _secondarySize = size;
|
||||||
private readonly int _size = size;
|
private readonly int _size = size;
|
||||||
private readonly int _stride = stride;
|
private readonly int _stride = stride;
|
||||||
|
|
||||||
@@ -198,29 +222,37 @@ namespace StgSharp.Mathematics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enumerator<T> GetEnumerator()
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public Enumerator GetEnumerator()
|
||||||
{
|
{
|
||||||
return new Enumerator<T>(_source, _size, _stride);
|
return new Enumerator(in this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref struct Enumerator<T>(MatrixKernel<T>* source, int count, int stride) where T: unmanaged, INumber<T>
|
public ref struct Enumerator(in MatrixSegment<T> segment)
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly MatrixKernel<T>* _end = source + (count * stride);
|
private readonly int _end = segment._size;
|
||||||
private readonly int _stride = stride;
|
|
||||||
|
|
||||||
public MatrixKernel<T>* Current
|
private int _indexCount = 0;
|
||||||
|
private readonly long _bound = (long)segment._size * segment._stride;
|
||||||
|
private long _index = (long)segment._offset * segment._stride;
|
||||||
|
private readonly MatrixSegment<T> _segment = segment;
|
||||||
|
|
||||||
|
public readonly MatrixKernel<T>* Current
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get;
|
get => _segment._source + _index;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
}
|
||||||
private set;
|
|
||||||
} = source - stride;
|
|
||||||
|
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
Current += _stride;
|
_index += _segment._stride;
|
||||||
return Current < _end;
|
_indexCount++;
|
||||||
|
if (_index >= _bound) {
|
||||||
|
_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _indexCount < _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,42 +33,43 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Formats.Asn1;
|
using System.Formats.Asn1;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace StgSharp.Mathematics
|
namespace StgSharp.Mathematics
|
||||||
{
|
{
|
||||||
internal static partial class MatrixParallel
|
public static partial class MatrixParallel
|
||||||
{
|
{
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_Binary(MatrixParallelTaskPackage* p)
|
internal static unsafe void Compute_Binary(MatrixParallelTaskPackageNonGeneric* p)
|
||||||
{
|
{
|
||||||
MatrixKernel* l = p->Left, r = p->Right, a = p->Result;
|
int eSize = p->ElementSize;
|
||||||
long
|
nint l = p->Left, r = p->Right, a = p->Result;
|
||||||
lCount = p->LeftPrimOffset * p->LeftPrimStride,
|
|
||||||
rCount = p->RightPrimOffset * p->RightPrimStride,
|
|
||||||
aCount = p->ResultPrimOffset * p->ResultPrimStride,
|
|
||||||
pCount = p->PrimCount;
|
|
||||||
long
|
long
|
||||||
|
lCount = (long)p->LeftPrimOffset * p->LeftPrimStride,
|
||||||
|
rCount = (long)p->RightPrimOffset * p->RightPrimStride,
|
||||||
|
aCount = (long)p->ResultPrimOffset * p->ResultPrimStride,
|
||||||
|
pCount = p->PrimCount,
|
||||||
lLimit = pCount - p->LeftPrimOffset,
|
lLimit = pCount - p->LeftPrimOffset,
|
||||||
rLimit = pCount - p->RightPrimOffset,
|
rLimit = pCount - p->RightPrimOffset,
|
||||||
aLimit = pCount - p->ResultPrimOffset;
|
aLimit = pCount - p->ResultPrimOffset;
|
||||||
delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, MatrixKernel*, void> op =
|
delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void> op =
|
||||||
(delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, MatrixKernel*, void>)p->ComputeHandle;
|
(delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, void>)p->ComputeHandle;
|
||||||
for (long i = 0; i < pCount; i++)
|
for (long i = 0; i < pCount; i++)
|
||||||
{
|
{
|
||||||
lCount = i < lLimit ? lCount + p->LeftPrimOffset : 0;
|
lCount = i < lLimit ? lCount + p->LeftPrimOffset : 0;
|
||||||
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
||||||
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
||||||
MatrixKernel* left = l + lCount;
|
nint left = l + (nint)(lCount * eSize);
|
||||||
MatrixKernel* right = r + rCount;
|
nint right = r + (nint)(rCount * eSize);
|
||||||
MatrixKernel* ans = a + aCount;
|
nint ans = a + (nint)(aCount * eSize);
|
||||||
long
|
long
|
||||||
lc = p->LeftSecOffset * p->LeftSecStride,
|
lc = (long)p->LeftSecOffset * p->LeftSecStride,
|
||||||
rc = p->RightSecOffset * p->RightSecStride,
|
rc = (long)p->RightSecOffset * p->RightSecStride,
|
||||||
ac = p->ResultSecOffset * p->ResultSecStride,
|
ac = (long)p->ResultSecOffset * p->ResultSecStride,
|
||||||
sCount = p->SecCount;
|
sCount = p->SecCount;
|
||||||
long
|
long
|
||||||
ll = sCount - p->LeftSecOffset,
|
ll = sCount - p->LeftSecOffset,
|
||||||
@@ -79,15 +80,15 @@ namespace StgSharp.Mathematics
|
|||||||
lc = j < ll ? lc + p->LeftSecOffset : 0;
|
lc = j < ll ? lc + p->LeftSecOffset : 0;
|
||||||
rc = j < rl ? rc + p->RightSecOffset : 0;
|
rc = j < rl ? rc + p->RightSecOffset : 0;
|
||||||
ac = j < al ? ac + p->ResultSecOffset : 0;
|
ac = j < al ? ac + p->ResultSecOffset : 0;
|
||||||
op(left + lc, right + rc, ans + ac);
|
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_BinaryScalar(MatrixParallelTaskPackage* p)
|
internal static unsafe void Compute_BinaryScalar(MatrixParallelTaskPackageNonGeneric* p)
|
||||||
{
|
{
|
||||||
MatrixKernel* l = p->Left, r = p->Right, a = p->Result;
|
nint l = p->Left, r = p->Right, a = p->Result;
|
||||||
long
|
long
|
||||||
lCount = p->LeftPrimOffset * p->LeftPrimStride,
|
lCount = p->LeftPrimOffset * p->LeftPrimStride,
|
||||||
rCount = p->RightPrimOffset * p->RightPrimStride,
|
rCount = p->RightPrimOffset * p->RightPrimStride,
|
||||||
@@ -97,23 +98,23 @@ namespace StgSharp.Mathematics
|
|||||||
lLimit = pCount - p->LeftPrimOffset,
|
lLimit = pCount - p->LeftPrimOffset,
|
||||||
rLimit = pCount - p->RightPrimOffset,
|
rLimit = pCount - p->RightPrimOffset,
|
||||||
aLimit = pCount - p->ResultPrimOffset;
|
aLimit = pCount - p->ResultPrimOffset;
|
||||||
delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, MatrixKernel*, ScalarPacket*, void> op =
|
delegate* unmanaged[Cdecl]<nint,nint,nint, ScalarPacket*, void> op =
|
||||||
(delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, MatrixKernel*, ScalarPacket*, void>)p->ComputeHandle;
|
(delegate* unmanaged[Cdecl]<nint, nint, nint, ScalarPacket*, void>)p->ComputeHandle;
|
||||||
ScalarPacket* scalar = p->Scalar;
|
ScalarPacket* scalar = p->Scalar;
|
||||||
for (long i = 0; i < pCount; i++)
|
for (long i = 0; i < pCount; i++)
|
||||||
{
|
{
|
||||||
lCount = i < lLimit ? lCount + p->LeftPrimOffset : 0;
|
lCount = i < lLimit ? lCount + p->LeftPrimOffset : 0;
|
||||||
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
||||||
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
||||||
MatrixKernel* left = l + lCount;
|
nint
|
||||||
MatrixKernel* right = r + rCount;
|
left = l + (nint)lCount,
|
||||||
MatrixKernel* ans = a + aCount;
|
right = r + (nint)rCount,
|
||||||
|
ans = a + (nint)aCount;
|
||||||
long
|
long
|
||||||
lc = p->LeftSecOffset * p->LeftSecStride,
|
lc = p->LeftSecOffset * p->LeftSecStride,
|
||||||
rc = p->RightSecOffset * p->RightSecStride,
|
rc = p->RightSecOffset * p->RightSecStride,
|
||||||
ac = p->ResultSecOffset * p->ResultSecStride,
|
ac = p->ResultSecOffset * p->ResultSecStride,
|
||||||
sCount = p->SecCount;
|
sCount = p->SecCount,
|
||||||
long
|
|
||||||
ll = sCount - p->LeftSecOffset,
|
ll = sCount - p->LeftSecOffset,
|
||||||
rl = sCount - p->RightSecOffset,
|
rl = sCount - p->RightSecOffset,
|
||||||
al = sCount - p->ResultSecOffset;
|
al = sCount - p->ResultSecOffset;
|
||||||
@@ -122,28 +123,27 @@ namespace StgSharp.Mathematics
|
|||||||
lc = j < ll ? lc + p->LeftSecOffset : 0;
|
lc = j < ll ? lc + p->LeftSecOffset : 0;
|
||||||
rc = j < rl ? rc + p->RightSecOffset : 0;
|
rc = j < rl ? rc + p->RightSecOffset : 0;
|
||||||
ac = j < al ? ac + p->ResultSecOffset : 0;
|
ac = j < al ? ac + p->ResultSecOffset : 0;
|
||||||
op(left + lc, right + rc, ans + ac, scalar);
|
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac, scalar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_Unary(MatrixParallelTaskPackage* p)
|
internal static unsafe void Compute_Unary(MatrixParallelTaskPackageNonGeneric* p)
|
||||||
{
|
{
|
||||||
MatrixKernel* s = p->Right, a = p->Result;
|
nint s = p->Right, a = p->Result;
|
||||||
long rCount = p->RightPrimOffset * p->RightPrimStride,
|
long rCount = p->RightPrimOffset * p->RightPrimStride,
|
||||||
aCount = p->ResultPrimOffset * p->ResultPrimStride,
|
aCount = p->ResultPrimOffset * p->ResultPrimStride,
|
||||||
pCount = p->PrimCount;
|
pCount = p->PrimCount;
|
||||||
long rLimit = pCount - p->RightPrimOffset,
|
long rLimit = pCount - p->RightPrimOffset,
|
||||||
aLimit = pCount - p->ResultPrimOffset;
|
aLimit = pCount - p->ResultPrimOffset;
|
||||||
delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, void> op =
|
delegate* unmanaged[Cdecl]<nint, nint, void> op =
|
||||||
(delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, void>)p->ComputeHandle;
|
(delegate* unmanaged[Cdecl]<nint, nint, void>)p->ComputeHandle;
|
||||||
for (long i = 0; i < pCount; i++)
|
for (long i = 0; i < pCount; i++)
|
||||||
{
|
{
|
||||||
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
||||||
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
||||||
MatrixKernel* source = s + rCount;
|
nint source = s + (nint)rCount, ans = a + (nint)aCount;
|
||||||
MatrixKernel* ans = a + aCount;
|
|
||||||
long rc = p->RightSecOffset * p->RightSecStride,
|
long rc = p->RightSecOffset * p->RightSecStride,
|
||||||
ac = p->ResultSecOffset * p->ResultSecStride,
|
ac = p->ResultSecOffset * p->ResultSecStride,
|
||||||
sCount = p->SecCount;
|
sCount = p->SecCount;
|
||||||
@@ -153,29 +153,29 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
rc = j < rl ? rc + p->RightSecOffset : 0;
|
rc = j < rl ? rc + p->RightSecOffset : 0;
|
||||||
ac = j < al ? ac + p->ResultSecOffset : 0;
|
ac = j < al ? ac + p->ResultSecOffset : 0;
|
||||||
op(source + rc, ans + ac);
|
op(source + (nint)rc, ans + (nint)ac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static unsafe void Compute_UnaryScalar(MatrixParallelTaskPackage* p)
|
internal static unsafe void Compute_UnaryScalar(MatrixParallelTaskPackageNonGeneric* p)
|
||||||
{
|
{
|
||||||
MatrixKernel* s = p->Right, a = p->Result;
|
nint s = p->Right, a = p->Result;
|
||||||
long rCount = p->RightPrimOffset * p->RightPrimStride,
|
long rCount = p->RightPrimOffset * p->RightPrimStride,
|
||||||
aCount = p->ResultPrimOffset * p->ResultPrimStride,
|
aCount = p->ResultPrimOffset * p->ResultPrimStride,
|
||||||
pCount = p->PrimCount;
|
pCount = p->PrimCount;
|
||||||
long rLimit = pCount - p->RightPrimOffset,
|
long rLimit = pCount - p->RightPrimOffset,
|
||||||
aLimit = pCount - p->ResultPrimOffset;
|
aLimit = pCount - p->ResultPrimOffset;
|
||||||
delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, ScalarPacket*, void> op =
|
delegate* unmanaged[Cdecl]<nint, nint, ScalarPacket*, void> op =
|
||||||
(delegate* unmanaged[Cdecl]<MatrixKernel*, MatrixKernel*, ScalarPacket*, void>)p->ComputeHandle;
|
(delegate* unmanaged[Cdecl]<nint, nint, ScalarPacket*, void>)p->ComputeHandle;
|
||||||
ScalarPacket* scalar = p->Scalar;
|
ScalarPacket* scalar = p->Scalar;
|
||||||
for (long i = 0; i < pCount; i++)
|
for (long i = 0; i < pCount; i++)
|
||||||
{
|
{
|
||||||
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
rCount = i < rLimit ? rCount + p->RightPrimOffset : 0;
|
||||||
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
aCount = i < rLimit ? aCount + p->ResultPrimOffset : 0;
|
||||||
MatrixKernel* source = s + rCount;
|
nint source = s + (nint)rCount;
|
||||||
MatrixKernel* ans = a + aCount;
|
nint ans = a + (nint)aCount;
|
||||||
long rc = p->RightSecOffset * p->RightSecStride,
|
long rc = p->RightSecOffset * p->RightSecStride,
|
||||||
ac = p->ResultSecOffset * p->ResultSecStride,
|
ac = p->ResultSecOffset * p->ResultSecStride,
|
||||||
sCount = p->SecCount;
|
sCount = p->SecCount;
|
||||||
@@ -185,7 +185,7 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
rc = j < rl ? rc + p->RightSecOffset : 0;
|
rc = j < rl ? rc + p->RightSecOffset : 0;
|
||||||
ac = j < al ? ac + p->ResultSecOffset : 0;
|
ac = j < al ? ac + p->ResultSecOffset : 0;
|
||||||
op(source + rc, ans + ac, scalar);
|
op(source + (nint)rc, ans + (nint)ac, scalar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,9 @@
|
|||||||
using StgSharp.HighPerformance;
|
using StgSharp.HighPerformance;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.ExceptionServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace StgSharp.Mathematics
|
namespace StgSharp.Mathematics
|
||||||
{
|
{
|
||||||
@@ -59,27 +54,106 @@ namespace StgSharp.Mathematics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
internal unsafe struct MatrixParallelTaskPackage
|
internal readonly unsafe struct MatrixParallelTaskPackageNonGeneric
|
||||||
{
|
{
|
||||||
|
|
||||||
public static unsafe void Copy(MatrixParallelTaskPackage* source, MatrixParallelTaskPackage* target)
|
|
||||||
{
|
|
||||||
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackage), sizeof(MatrixParallelTaskPackage));
|
|
||||||
}
|
|
||||||
|
|
||||||
#region source
|
#region source
|
||||||
|
|
||||||
// Group 1: Left/Right matrix kernel base address
|
// Group 1: Left/Right matrix kernel base address
|
||||||
public MatrixKernel* Left; // 8
|
public readonly IntPtr Left; // 8
|
||||||
public MatrixKernel* Right; // 8
|
public readonly IntPtr Right; // 8
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ans
|
#region ans
|
||||||
|
|
||||||
// Group 2: Result kernel base address + reserved
|
// Group 2: Result kernel base address + reserved
|
||||||
public MatrixKernel* Result; // 8
|
public readonly IntPtr Result; // 8
|
||||||
public void* ReservedPtr0; // 8 (extension/reserved)
|
public readonly int ElementSize;
|
||||||
|
public readonly int ReservedPtr0; // 4 (extension/reserved)
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region left enum
|
||||||
|
|
||||||
|
public readonly int LeftPrimOffset; // 4
|
||||||
|
public readonly int LeftPrimStride; // 4
|
||||||
|
public readonly int LeftSecOffset; // 4
|
||||||
|
public readonly int LeftSecStride; // 4
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region right enum
|
||||||
|
|
||||||
|
public readonly int RightPrimOffset; // 4
|
||||||
|
public readonly int RightPrimStride; // 4
|
||||||
|
public readonly int RightSecOffset; // 4
|
||||||
|
public readonly int RightSecStride; // 4
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ans enum
|
||||||
|
|
||||||
|
public readonly int ResultPrimOffset; // 4
|
||||||
|
public readonly int ResultPrimStride; // 4
|
||||||
|
public readonly int ResultSecOffset; // 4
|
||||||
|
public readonly int ResultSecStride; // 4
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region scalar/compute
|
||||||
|
|
||||||
|
public readonly ScalarPacket* Scalar; // 8
|
||||||
|
public readonly IntPtr ComputeHandle; // 8
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region global profile
|
||||||
|
|
||||||
|
public readonly int PrimCount; // 4
|
||||||
|
public readonly int ComputeMode; // 4
|
||||||
|
public readonly int SecCount; // 4
|
||||||
|
private readonly int ReservedInt0; // 4
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region reserve
|
||||||
|
|
||||||
|
public readonly long ReservedLong0; // 8
|
||||||
|
public readonly long ReservedLong1; // 8
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal unsafe struct MatrixParallelTaskPackage<T> where T: unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
public MatrixParallelTaskPackage()
|
||||||
|
{
|
||||||
|
Unsafe.SkipInit(out this);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static unsafe void Copy(MatrixParallelTaskPackage<T>* source, MatrixParallelTaskPackage<T>* target)
|
||||||
|
{
|
||||||
|
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackage<T>), sizeof(MatrixParallelTaskPackage<T>));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region source
|
||||||
|
|
||||||
|
// Group 1: Left/Right matrix kernel base address
|
||||||
|
public MatrixKernel<T>* Left; // 8
|
||||||
|
public MatrixKernel<T>* Right; // 8
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ans
|
||||||
|
|
||||||
|
// Group 2: Result kernel base address + reserved
|
||||||
|
public MatrixKernel<T>* Result; // 8
|
||||||
|
public int ElementSize = sizeof(T);
|
||||||
|
public int ReservedPtr0; // 4 (extension/reserved)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// file="MatrixParallel.TaskWrapFactory.cs"
|
// file="MatrixParallel.TaskFactory.cs"
|
||||||
// Project: StgSharp
|
// Project: StgSharp
|
||||||
// AuthorGroup: Nitload Space
|
// AuthorGroup: Nitload Space
|
||||||
// Copyright (c) Nitload Space. All rights reserved.
|
// Copyright (c) Nitload Space. All rights reserved.
|
||||||
@@ -33,6 +33,7 @@ using StgSharp.HighPerformance.Memory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -57,13 +58,13 @@ namespace StgSharp.Mathematics
|
|||||||
|
|
||||||
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
|
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
|
||||||
|
|
||||||
private static SlabAllocator<MatrixParallelTaskPackage> _wrapAllocator ;
|
private static SlabAllocator<MatrixParallelTaskPackageNonGeneric> _wrapAllocator ;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static MatrixParallelTaskPackage* CreateBaseTask()
|
public static MatrixParallelTaskPackage<T>* CreateBaseTask<T>() where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
|
MatrixParallelTaskPackage<T>* p = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
|
||||||
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTaskPackage));
|
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTaskPackage<T>));
|
||||||
s.Fill(0);
|
s.Fill(0);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -75,10 +76,10 @@ namespace StgSharp.Mathematics
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD:StgSharp.Common/Mathematics/Linear/MatrixParallel.TaskWrapFactory.cs
|
public static MatrixParallelTaskPackage<T>* FromTaskWrap<T>(MatrixParallelTaskPackage<T>* source, int offset)
|
||||||
public static MatrixParallelTaskPackage* FromTaskWrap(MatrixParallelTaskPackage* source, int offset)
|
where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
|
MatrixParallelTaskPackage<T>* p = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
|
||||||
/*
|
/*
|
||||||
*p = *source;
|
*p = *source;
|
||||||
p->Left += offset * p->LeftStride;
|
p->Left += offset * p->LeftStride;
|
||||||
@@ -88,16 +89,24 @@ namespace StgSharp.Mathematics
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
=======
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
>>>>>>> 8007eee8461498a85a9515e8fd076f03cb552b64:StgSharp.Common/Mathematics/Linear/MatrixParallel.TaskFactory.cs
|
|
||||||
public static void Release(ScalarPacket* source)
|
public static void Release(ScalarPacket* source)
|
||||||
{
|
{
|
||||||
_scalarAllocator.Free((nuint)source);
|
_scalarAllocator.Free((nuint)source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Release(MatrixParallelTaskPackage* source)
|
public static void Release(MatrixParallelTaskPackageNonGeneric* source)
|
||||||
|
{
|
||||||
|
if (source->Scalar != null) {
|
||||||
|
_scalarAllocator.Free((nuint)source->Scalar);
|
||||||
|
}
|
||||||
|
_wrapAllocator.Free((nuint)source);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Release<T>(MatrixParallelTaskPackage<T>* source) where T: unmanaged, INumber<T>
|
||||||
{
|
{
|
||||||
if (source->Scalar != null) {
|
if (source->Scalar != null) {
|
||||||
_scalarAllocator.Free((nuint)source->Scalar);
|
_scalarAllocator.Free((nuint)source->Scalar);
|
||||||
@@ -108,40 +117,13 @@ namespace StgSharp.Mathematics
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static void Init()
|
internal static void Init()
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD:StgSharp.Common/Mathematics/Linear/MatrixParallel.TaskWrapFactory.cs
|
if (_intermediateResult is null)
|
||||||
int count = group.Length;
|
|
||||||
group[0] = (nint)source;
|
|
||||||
int l = source->LeftPrimStride, r = source->RightPrimStride, res = source->ResultPrimStride, c = source->PrimCount / count;
|
|
||||||
source->LeftPrimStride *= count;
|
|
||||||
source->RightPrimStride *= count;
|
|
||||||
source->ResultPrimStride *= count;
|
|
||||||
source->PrimCount = c;
|
|
||||||
int remain = source->PrimCount - (c * count);
|
|
||||||
for (int i = 1; i < count; i++)
|
|
||||||
{
|
{
|
||||||
nint handle = (nint)_wrapAllocator.Allocate();
|
_intermediateResult = new hlsfAllocator(64 * 16 * 16);
|
||||||
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)handle;
|
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64 * 1024, SlabBufferLayout.Chunked);
|
||||||
*p = *source;
|
_wrapAllocator = SlabAllocator<MatrixParallelTaskPackageNonGeneric>.
|
||||||
p->Left += l * i;
|
Create(128 * 1024, SlabBufferLayout.Chunked);
|
||||||
p->Right += r * i;
|
|
||||||
p->Result += res * i;
|
|
||||||
p->PrimCount = c;
|
|
||||||
group[i] = handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Distribute remaining work to the last few tasks
|
|
||||||
for (int i = 0; i < remain; i++)
|
|
||||||
{
|
|
||||||
int targetIndex = count - 1 - i;
|
|
||||||
if (targetIndex >= 0) {
|
|
||||||
((MatrixParallelTaskPackage*)group[targetIndex])->PrimCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
=======
|
|
||||||
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64, SlabBufferLayout.Chunked, true);
|
|
||||||
_wrapAllocator = SlabAllocator<MatrixParallelTaskPackage>.Create(64, SlabBufferLayout.Chunked, true);
|
|
||||||
_intermediateResult = new hlsfAllocator((nuint)(sizeof(MatrixKernel) * 64));
|
|
||||||
>>>>>>> 8007eee8461498a85a9515e8fd076f03cb552b64:StgSharp.Common/Mathematics/Linear/MatrixParallel.TaskFactory.cs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// file="MatrixParallel.TaskPublic.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.HighPerformance;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace StgSharp.Mathematics
|
||||||
|
{
|
||||||
|
public static partial class MatrixParallel
|
||||||
|
{
|
||||||
|
|
||||||
|
public static unsafe void PublicTask<T>(
|
||||||
|
MatrixSegmentEnumeration<T> left,
|
||||||
|
MatrixSegmentEnumeration<T> right,
|
||||||
|
MatrixSegmentEnumeration<T> ans,
|
||||||
|
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation)
|
||||||
|
where T: unmanaged, INumber<T>
|
||||||
|
{
|
||||||
|
int columnCount = left.PrimSize;
|
||||||
|
int rowCount = right.PrimSize;
|
||||||
|
|
||||||
|
MatrixParallelTaskPackage<T> package = new()
|
||||||
|
{
|
||||||
|
Left = left.Source,
|
||||||
|
Right = right.Source,
|
||||||
|
Result = ans.Source,
|
||||||
|
LeftPrimOffset = left.PrimOffset,
|
||||||
|
RightPrimOffset = right.PrimOffset,
|
||||||
|
ResultPrimOffset = ans.PrimOffset,
|
||||||
|
LeftPrimStride = left.PrimStride,
|
||||||
|
RightPrimStride = right.PrimStride,
|
||||||
|
ResultPrimStride = ans.PrimStride,
|
||||||
|
LeftSecOffset = left.SecondaryOffset,
|
||||||
|
RightSecOffset = right.SecondaryOffset,
|
||||||
|
ResultSecOffset = ans.SecondaryOffset,
|
||||||
|
LeftSecStride = left.SecondaryStride,
|
||||||
|
RightSecStride = right.SecondaryStride,
|
||||||
|
ResultSecStride = ans.SecondaryStride,
|
||||||
|
PrimCount = left.PrimSize,
|
||||||
|
SecCount = left.SecondarySize,
|
||||||
|
ComputeHandle = (nint)Operation
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,7 +64,7 @@ namespace StgSharp.Mathematics
|
|||||||
* we allow each wrap to contain either 3 or 4 threads, providing flexibility while maintaining efficiency.
|
* we allow each wrap to contain either 3 or 4 threads, providing flexibility while maintaining efficiency.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
internal static partial class MatrixParallel
|
public static partial class MatrixParallel
|
||||||
{
|
{
|
||||||
|
|
||||||
private static Thread[] _threads;
|
private static Thread[] _threads;
|
||||||
@@ -167,7 +167,7 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
ResetThreadCount();
|
ResetThreadCount();
|
||||||
foreach (MatrixParallelWrap item in _wraps) {
|
foreach (MatrixParallelWrap item in _wraps) {
|
||||||
_ = item.SchedulerReset.Set();
|
item.SchedulerReset.Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,17 +176,17 @@ namespace StgSharp.Mathematics
|
|||||||
|
|
||||||
private readonly Queue<IntPtr>[] _cache;
|
private readonly Queue<IntPtr>[] _cache;
|
||||||
private readonly Thread[] _threads;
|
private readonly Thread[] _threads;
|
||||||
private readonly AutoResetEvent[] _workerReset;
|
private readonly ManualResetEventSlim[] _workerReset;
|
||||||
|
|
||||||
public MatrixParallelWrap(int id, int wrapSize, bool isFirst)
|
public MatrixParallelWrap(int id, int wrapSize, bool isFirst)
|
||||||
{
|
{
|
||||||
ID = id;
|
ID = id;
|
||||||
int begin = isFirst ? 1 : 0, end = wrapSize - 1;
|
int begin = isFirst ? 1 : 0, end = wrapSize - 1;
|
||||||
_cache = new Queue<IntPtr>[wrapSize];
|
_cache = new Queue<IntPtr>[wrapSize];
|
||||||
_workerReset = new AutoResetEvent[end];
|
_workerReset = new ManualResetEventSlim[end];
|
||||||
_threads = new Thread[wrapSize];
|
_threads = new Thread[wrapSize];
|
||||||
for (int i = 0; i < end; i++) {
|
for (int i = 0; i < end; i++) {
|
||||||
_workerReset[i] = new AutoResetEvent(false);
|
_workerReset[i] = new ManualResetEventSlim(false);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < _cache.Length; i++) {
|
for (int i = 0; i < _cache.Length; i++) {
|
||||||
_cache[i] = new Queue<IntPtr>(8);
|
_cache[i] = new Queue<IntPtr>(8);
|
||||||
@@ -212,7 +212,7 @@ namespace StgSharp.Mathematics
|
|||||||
|
|
||||||
public int ID { get; init; }
|
public int ID { get; init; }
|
||||||
|
|
||||||
internal AutoResetEvent SchedulerReset { get; } = new(false);
|
internal ManualResetEventSlim SchedulerReset { get; } = new(false);
|
||||||
|
|
||||||
public Span<IntPtr> EnqueuePackage(Span<IntPtr> packageSpan)
|
public Span<IntPtr> EnqueuePackage(Span<IntPtr> packageSpan)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ namespace StgSharp.Mathematics
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AutoResetEvent GetWorkerResetEvent(int id)
|
public ManualResetEventSlim GetWorkerResetEvent(int id)
|
||||||
{
|
{
|
||||||
return _workerReset[id];
|
return _workerReset[id];
|
||||||
}
|
}
|
||||||
@@ -238,8 +238,8 @@ namespace StgSharp.Mathematics
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SetAllWorker()
|
public void SetAllWorker()
|
||||||
{
|
{
|
||||||
foreach (AutoResetEvent item in _workerReset) {
|
foreach (ManualResetEventSlim item in _workerReset) {
|
||||||
_ = item.Set();
|
item.Set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,10 +253,11 @@ namespace StgSharp.Mathematics
|
|||||||
MatrixParallelWrap wrap = handle.Wrap;
|
MatrixParallelWrap wrap = handle.Wrap;
|
||||||
int inWrapIndex = handle.InWrapIndex;
|
int inWrapIndex = handle.InWrapIndex;
|
||||||
Thread self = Thread.CurrentThread;
|
Thread self = Thread.CurrentThread;
|
||||||
AutoResetEvent reset = wrap.GetWorkerResetEvent(inWrapIndex);
|
ManualResetEventSlim reset = wrap.GetWorkerResetEvent(inWrapIndex);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
_ = reset.WaitOne();
|
reset.Wait();
|
||||||
|
reset.Reset();
|
||||||
self.Priority = ThreadPriority.Highest;
|
self.Priority = ThreadPriority.Highest;
|
||||||
ExecuteTaskPackage(wrap.GetWorkerTaskQueue(inWrapIndex));
|
ExecuteTaskPackage(wrap.GetWorkerTaskQueue(inWrapIndex));
|
||||||
_ = Interlocked.Decrement(ref RemainThreadCount);
|
_ = Interlocked.Decrement(ref RemainThreadCount);
|
||||||
@@ -270,11 +271,12 @@ namespace StgSharp.Mathematics
|
|||||||
MatrixParallelWrap wrap = handle.Wrap;
|
MatrixParallelWrap wrap = handle.Wrap;
|
||||||
int inWrapIndex = handle.InWrapIndex;
|
int inWrapIndex = handle.InWrapIndex;
|
||||||
Queue<IntPtr> taskQueue = wrap.GetWorkerTaskQueue(inWrapIndex);
|
Queue<IntPtr> taskQueue = wrap.GetWorkerTaskQueue(inWrapIndex);
|
||||||
AutoResetEvent resetEvent = wrap.SchedulerReset;
|
ManualResetEventSlim resetEvent = wrap.SchedulerReset;
|
||||||
Thread self = Thread.CurrentThread;
|
Thread self = Thread.CurrentThread;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
_ = resetEvent.WaitOne();
|
resetEvent.Wait();
|
||||||
|
resetEvent.Reset();
|
||||||
self.Priority = ThreadPriority.Highest;
|
self.Priority = ThreadPriority.Highest;
|
||||||
|
|
||||||
// TODO task publication to worker in wrap
|
// TODO task publication to worker in wrap
|
||||||
@@ -290,7 +292,7 @@ namespace StgSharp.Mathematics
|
|||||||
{
|
{
|
||||||
while (taskQueue.TryDequeue(out nint handle))
|
while (taskQueue.TryDequeue(out nint handle))
|
||||||
{
|
{
|
||||||
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)handle;
|
MatrixParallelTaskPackageNonGeneric* p = (MatrixParallelTaskPackageNonGeneric*)handle;
|
||||||
switch (p->ComputeMode)
|
switch (p->ComputeMode)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
|||||||
@@ -57,45 +57,13 @@ namespace StgSharp
|
|||||||
|
|
||||||
// 7. 线程状态监控测试
|
// 7. 线程状态监控测试
|
||||||
Console.WriteLine("=== 线程状态监控测试 ===");
|
Console.WriteLine("=== 线程状态监控测试 ===");
|
||||||
TestThreadStateMonitoring();
|
|
||||||
|
// TestThreadStateMonitoring();
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
Console.WriteLine("? MatrixParallel 分层线程调度系统空跑测试完成");
|
Console.WriteLine("? MatrixParallel 分层线程调度系统空跑测试完成");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TestInitialization()
|
|
||||||
{
|
|
||||||
if (!MatrixParallel.SupportParallel)
|
|
||||||
{
|
|
||||||
Console.WriteLine("? 跳过初始化测试 - 系统不支持并行处理");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Console.WriteLine("正在初始化 MatrixParallel...");
|
|
||||||
MatrixParallel.Init();
|
|
||||||
Console.WriteLine("? MatrixParallel 初始化成功");
|
|
||||||
|
|
||||||
|
|
||||||
// 检查 LeaderHandle 是否正确设置
|
|
||||||
if (MatrixParallel.LeaderHandle != null)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"? LeaderHandle 已创建,Wrap ID: {MatrixParallel.LeaderHandle.Wrap.ID}");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
Console.WriteLine("? LeaderHandle 未正确设置");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"? 初始化失败: {ex.Message}");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void TestParallelControlFlow()
|
private static void TestParallelControlFlow()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -121,7 +89,7 @@ namespace StgSharp
|
|||||||
MatrixParallel.SetAllWrap();
|
MatrixParallel.SetAllWrap();
|
||||||
|
|
||||||
// 发布任务(空任务)
|
// 发布任务(空任务)
|
||||||
MatrixParallel.PublishTask();
|
// MatrixParallel.PublishTask();
|
||||||
|
|
||||||
// 短暂等待,模拟实际工作
|
// 短暂等待,模拟实际工作
|
||||||
Thread.Sleep(10 + i * 5);
|
Thread.Sleep(10 + i * 5);
|
||||||
@@ -162,7 +130,8 @@ namespace StgSharp
|
|||||||
|
|
||||||
MatrixParallel.LaunchParallel(SleepMode.QuickWakeup);
|
MatrixParallel.LaunchParallel(SleepMode.QuickWakeup);
|
||||||
MatrixParallel.SetAllWrap();
|
MatrixParallel.SetAllWrap();
|
||||||
MatrixParallel.PublishTask();
|
|
||||||
|
// MatrixParallel.PublishTask();
|
||||||
|
|
||||||
|
|
||||||
// 极短暂的等待
|
// 极短暂的等待
|
||||||
|
|||||||
@@ -1,3 +1,33 @@
|
|||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// file="MatrixParallelThreadTest.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;
|
using StgSharp.Mathematics;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -59,7 +89,7 @@ namespace StgSharp
|
|||||||
Console.WriteLine("已通知所有Wrap开始工作");
|
Console.WriteLine("已通知所有Wrap开始工作");
|
||||||
|
|
||||||
// 发布任务(当前为空实现)
|
// 发布任务(当前为空实现)
|
||||||
MatrixParallel.PublishTask();
|
// MatrixParallel.PublishTask();
|
||||||
Console.WriteLine("任务发布完成");
|
Console.WriteLine("任务发布完成");
|
||||||
|
|
||||||
// 等待一段时间让线程执行
|
// 等待一段时间让线程执行
|
||||||
|
|||||||
@@ -59,29 +59,21 @@ namespace StgSharp
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
<<<<<<< HEAD
|
|
||||||
World.Init();
|
World.Init();
|
||||||
|
|
||||||
TestMatrixParallel();
|
TestMatrixParallel();
|
||||||
|
|
||||||
// 原有的矩阵测试代码
|
// 原有的矩阵测试代码
|
||||||
=======
|
|
||||||
MatrixParallelThreadTest.TestMatrixParallelThreadScheduling();
|
|
||||||
/*
|
|
||||||
>>>>>>> 8007eee8461498a85a9515e8fd076f03cb552b64
|
|
||||||
HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400);
|
HybridLayerSegregatedFitAllocator hlsf = new HybridLayerSegregatedFitAllocator(64 * 400 * 400);
|
||||||
|
|
||||||
Matrix<float> m = Matrix<float>.FromHlsf(400, 200, hlsf);
|
Matrix<float> m = Matrix<float>.FromHlsf(400, 200, hlsf);
|
||||||
|
|
||||||
int i = 0, ii = 0;
|
int i = 0, ii = 0;
|
||||||
<<<<<<< HEAD
|
|
||||||
foreach (Segment lines in m.GetRowEnumeration())
|
foreach (MatrixSegment<float> lines in m.GetRowEnumeration())
|
||||||
=======
|
|
||||||
foreach (MatrixSegment lines in m.GetRowEnumeration())
|
|
||||||
>>>>>>> 8007eee8461498a85a9515e8fd076f03cb552b64
|
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
foreach (MatrixKernel* item in lines)
|
foreach (MatrixKernel<float>* item in lines)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
Console.WriteLine(i);
|
Console.WriteLine(i);
|
||||||
|
|||||||
Reference in New Issue
Block a user