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:
Nitload
2025-09-21 17:33:33 +08:00
parent 0404ecf044
commit b8a51c13dd
15 changed files with 463 additions and 304 deletions
@@ -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;
+14 -14
View File
@@ -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
+63 -31
View File
@@ -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:
+5 -36
View File
@@ -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();
// 极短暂的等待 // 极短暂的等待
+31 -1
View File
@@ -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("任务发布完成");
// 等待一段时间让线程执行 // 等待一段时间让线程执行
+3 -11
View File
@@ -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);