add scheduler method; fixing buffer parallel errors

This commit is contained in:
Youmu Liu
2025-11-19 18:09:25 +08:00
parent 45d1d08af8
commit 04fc55d31e
11 changed files with 272 additions and 339 deletions
@@ -68,10 +68,10 @@ namespace StgSharp.Mathematics.Numeric
MatrixParallel.ReturnParallelResources(ref pool);
return ans;
}
MatrixParallelTaskPackage<float>* package = MatrixParallelFactory.CreateBaseTask<float>();
package->Left = left.Buffer;
package->Right = right.Buffer;
package->Result = ans.Buffer;
MatrixParallelTaskPackage* package = MatrixParallelFactory.CreateBaseTask<float>();
package->Left = (nint)left.Buffer;
package->Right = (nint)right.Buffer;
package->Result = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = left.KernelColumnLength;
package->SecCount = left.KernelRowLength;
@@ -80,41 +80,37 @@ namespace StgSharp.Mathematics.Numeric
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
/*
* run parallel
*/
MatrixParallelFactory.Release(package);
taskGroup.Dispose();
return ans;
}
public static unsafe void Fill<T>(this Matrix<float> right, T value) where T : unmanaged, INumber<T>
public static unsafe void Fill<T>(this Matrix<float> ans, T value) where T : unmanaged, INumber<T>
{
long count = (long)right.KernelColumnLength * right.KernelRowLength;
ScalarPacket* scaler = MatrixParallelFactory.CreateScalarPacket();
scaler->Data<T>(0) = value;
long count = (long)ans.KernelColumnLength * ans.KernelRowLength;
ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket();
scalar->Data<T>(0) = value;
if (count <= 256)
{
NativeIntrinsic.Intrinsic.f32_fill(right.Buffer, scaler, count);
NativeIntrinsic.Intrinsic.f32_fill(ans.Buffer, scalar, count);
return;
} else if (count <= 1024)
{
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
NativeIntrinsic.Intrinsic.f32_fill(right.Buffer, scaler, count);
NativeIntrinsic.Intrinsic.f32_fill(ans.Buffer, scalar, count);
MatrixParallel.ReturnParallelResources(ref pool);
return;
}
MatrixParallelHandle taskGroup =/**/ default
/*MatrixParallel.PublicNoAnswerTask(left.GetColumnEnumeration(), scaler,
(delegate* unmanaged[Cdecl]<MatrixKernel<float>*, ScalarPacket*, void>)NativeIntrinsic.Intrinsic.f32_add)
/**/;
MatrixParallelTaskPackage* package = MatrixParallelFactory.CreateBaseTask<float>();
package->Result = (nint)ans.Buffer;
package->ElementSize = sizeof(float);
package->PrimCount = ans.KernelColumnLength;
package->SecCount = ans.KernelRowLength;
package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.ANS_SCALAR_PARAM);
package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_fill;
package->Scalar = scalar;
MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package);
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
/*
* run parallel
*/
MatrixParallelFactory.Release(scaler);
taskGroup.Dispose();
}
@@ -34,31 +34,33 @@ namespace StgSharp.Mathematics.Numeric
internal static class MatrixComputeModel
{
internal static unsafe void BufferComputeBinary(MatrixParallelTaskPackageNonGeneric* p)
internal static unsafe void BufferComputeBinary(MatrixParallelTaskPackage* p)
{
int size = p->ElementSize * 16;
int count = p->PrimCount * p->SecCount;
int offset = p->LeftPrimOffset * p->SecCount;
long count = Unsafe.As<int, long>(ref p->PrimCount);
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
((delegate* unmanaged[Cdecl]<void*, void*, void*, int, void>)p->ComputeHandle)((void*)(p->Left + offset * size),
(void*)(p->Right + offset * size),
(void*)(p->Result + offset * size),
count);
((delegate* unmanaged[Cdecl]<void*, void*, void*, long, void>)p->ComputeHandle)((void*)(p->Left + offset),
(void*)(p->Right + offset),
(void*)(p->Result + offset),
count);
MatrixParallelFactory.Release(p);
}
internal static unsafe void BufferComputeUnaryScalar(MatrixParallelTaskPackageNonGeneric* p)
internal static unsafe void BufferComputeUnaryScalar(MatrixParallelTaskPackage* p)
{
int size = p->ElementSize * 16;
int count = p->PrimCount * p->SecCount;
int offset = p->LeftPrimOffset * p->SecCount;
long count = Unsafe.As<int, long>(ref p->PrimCount);
long offset = Unsafe.As<int, long>(ref p->PrimTileOffset) * size;
((delegate* unmanaged[Cdecl]<void*, void*, int, void>)p->ComputeHandle)((void*)(p->Right + offset * size),
(void*)(p->Result + offset * size),
((delegate* unmanaged[Cdecl]<void*, void*, long, void>)p->ComputeHandle)((void*)(p->Right + offset),
(void*)(p->Result + offset),
count);
MatrixParallelFactory.Release(p);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe void Compute_Binary(MatrixParallelTaskPackageNonGeneric* p)
internal static unsafe void Compute_Binary(MatrixParallelTaskPackage* p)
{
int eSize = p->ElementSize;
@@ -106,10 +108,11 @@ namespace StgSharp.Mathematics.Numeric
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac);
}
}
MatrixParallelFactory.Release(p);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe void Compute_BinaryScalar(MatrixParallelTaskPackageNonGeneric* p)
internal static unsafe void Compute_BinaryScalar(MatrixParallelTaskPackage* p)
{
int eSize = p->ElementSize;
@@ -157,10 +160,11 @@ namespace StgSharp.Mathematics.Numeric
op(left + (nint)lc, right + (nint)rc, ans + (nint)ac, p->Scalar);
}
}
MatrixParallelFactory.Release(p);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe void Compute_Unary(MatrixParallelTaskPackageNonGeneric* p)
internal static unsafe void Compute_Unary(MatrixParallelTaskPackage* p)
{
int eSize = p->ElementSize;
@@ -201,10 +205,11 @@ namespace StgSharp.Mathematics.Numeric
op(right + (nint)rc, ans + (nint)ac);
}
}
MatrixParallelFactory.Release(p);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe void Compute_UnaryScalar(MatrixParallelTaskPackageNonGeneric* p)
internal static unsafe void Compute_UnaryScalar(MatrixParallelTaskPackage* p)
{
int eSize = p->ElementSize;
@@ -245,6 +250,7 @@ namespace StgSharp.Mathematics.Numeric
op(right + (nint)rc, ans + (nint)ac, p->Scalar);
}
}
MatrixParallelFactory.Release(p);
}
}
@@ -41,12 +41,14 @@ namespace StgSharp.Mathematics.Numeric
public static partial class MatrixParallel
{
private const int MIN_TASK_PER_THREAD = 256;
private const int REC_TASK_PER_THREAD = 1024;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe MatrixParallelHandle ScheduleTask<T>(MatrixParallelTaskPackage<T>* package)
where T : unmanaged,INumber<T>
internal static unsafe MatrixParallelHandle ScheduleTask(MatrixParallelTaskPackage* package)
{
MatrixParallelTaskPackageNonGeneric* nonGeneric = (MatrixParallelTaskPackageNonGeneric*)package;
MatrixParallelTaskPackage* nonGeneric = package;
switch (nonGeneric->ComputeMode.OperationStyle)
{
case MatrixOperationStyle.PANEL_OP:
@@ -60,12 +62,46 @@ namespace StgSharp.Mathematics.Numeric
}
}
private static unsafe MatrixParallelHandle ScheduleBufferTask(MatrixParallelTaskPackageNonGeneric* package)
private static unsafe MatrixParallelHandle ScheduleBufferTask(MatrixParallelTaskPackage* package)
{
throw new NotImplementedException();
int primCount = package->PrimCount;
int secCount = package->SecCount;
long count = (long)primCount * secCount;
long recommendCount = count / 1024;
MatrixParallelThread[] pool = LeadParallel((int)recommendCount);
MatrixParallelHandle handle = new MatrixParallelHandle(pool);
if (handle.Wraps.Count() == 1)
{
ref long offsetRef = ref Unsafe.As<int, long>(ref package->PrimTileOffset);
offsetRef = 0;
ref long lengthRef = ref Unsafe.As<int, long>(ref package->PrimCount);
lengthRef = count;
handle.Wraps.First().WrapTask.Enqueue((nint)package);
return handle;
}
long actual = count / pool.Length;
long extra = count % pool.Length;
long offset = 0;
MatrixParallelTaskPackage* current = package;
foreach (MatrixParallelWrap wrap in handle.Wraps)
{
long wrapTaskLength = actual * wrap.WrapTaskCapacity;
long ex = Math.Min(extra, wrap.WrapTaskCapacity);
extra -= ex;
ref long offsetRef = ref Unsafe.As<int, long>(ref current->PrimTileOffset);
offsetRef = offset;
ref long lengthRef = ref Unsafe.As<int, long>(ref current->PrimCount);
lengthRef = wrapTaskLength + ex;
wrap.WrapTask.Enqueue((nint) current);
current = MatrixParallelFactory.FromExistPackage(current);
offset += wrapTaskLength;
}
return handle;
}
private static unsafe MatrixParallelHandle ScheduleKernelTask(MatrixParallelTaskPackageNonGeneric* package)
private static unsafe MatrixParallelHandle ScheduleKernelTask(MatrixParallelTaskPackage* package)
{
int primCount = package->PrimCount;
int secCount = package->SecCount;
@@ -73,17 +109,17 @@ namespace StgSharp.Mathematics.Numeric
int tileCount = (primCount + tileWidth - 1) / tileWidth;
MatrixParallelThread[] pool = LeadParallel(tileCount);
/*
if (pool.Length == 0)
{
/*
* wait until has enough threads
*/
// no need
// LeadParallel has contained capacity check
}
/**/
MatrixParallelHandle handle = new MatrixParallelHandle(pool);
if (handle.Wraps.Count() == 1)
{
handle.Wraps.First().WrapTask = package;
handle.Wraps.First().WrapTask.Enqueue((nint)package);
return handle;
}
int threadCount = pool.Length;
@@ -94,7 +130,7 @@ namespace StgSharp.Mathematics.Numeric
int total = primCount;
Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(threadCount);
MatrixParallelTaskPackageNonGeneric* current = package;
MatrixParallelTaskPackage* current = package;
foreach (MatrixParallelWrap wrap in handle.Wraps)
{
bool hasSlice = columnAfterBaseTile > 0;
@@ -127,7 +163,7 @@ namespace StgSharp.Mathematics.Numeric
total -= columnInWrap;
// set to wrap and push
wrap.WrapTask = current;
wrap.WrapTask.Enqueue((nint)current);
if (total <= 0)
{
@@ -71,7 +71,7 @@ namespace StgSharp.Mathematics.Numeric
RemainThreadCount = _threads.Count;
_AfterWork = (ThreadPriority)afterWork;
foreach (MatrixParallelWrap w in handle.Wraps) {
w.SchedulerReset.Set();
w.SetScheduler();
}
}
@@ -1,9 +1,9 @@
//-----------------------------------------------------------------------
// -----------------------------------------------------------------------
// file="MatrixParallelPool"
// file="MatrixParallelHandle"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
// AuthorGroup: Nitload
// Copyright (c) Nitload. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -39,7 +39,8 @@ namespace StgSharp.Mathematics.Numeric
public struct MatrixParallelHandle : IDisposable
{
private static readonly (int a, int b)[] LookupTable = [ (1, 1), // 7
private static readonly (int a, int b)[] LookupTable = [
(1, 1), // 7
(0, 2), // 8 (no non-zero solution)
(3, 0), // 9 (no non-zero solution)
(2, 1), // 10
@@ -157,6 +158,7 @@ namespace StgSharp.Mathematics.Numeric
{
MatrixParallelWrap wrap = new MatrixParallelWrap(_threads, 0, count);
_wraps = [ wrap ];
return;
}
(int c3,int c4) = FastDecompose(_threads.Length);
_wraps = new(c3 + c4);
@@ -82,16 +82,13 @@ namespace StgSharp.Mathematics.Numeric
}
[StructLayout(LayoutKind.Explicit, Size = 128)]
internal unsafe struct MatrixParallelTaskPackageNonGeneric
public unsafe struct MatrixParallelTaskPackage
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Copy(
MatrixParallelTaskPackageNonGeneric* source,
MatrixParallelTaskPackageNonGeneric* target)
public static unsafe void Copy(MatrixParallelTaskPackage* source, MatrixParallelTaskPackage* target)
{
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackageNonGeneric),
sizeof(MatrixParallelTaskPackageNonGeneric));
Buffer.MemoryCopy(source, target, sizeof(MatrixParallelTaskPackage), sizeof(MatrixParallelTaskPackage));
}
#region source
@@ -113,7 +110,7 @@ namespace StgSharp.Mathematics.Numeric
#region left enum
[FieldOffset(32)] public int LeftPrimOffset; // 4
[FieldOffset(32)]public int LeftPrimOffset; // 4
[FieldOffset(36)]public int LeftPrimStride; // 4
[FieldOffset(40)]public int LeftSecOffset; // 4
[FieldOffset(44)]public int LeftSecStride; // 4
@@ -122,7 +119,7 @@ namespace StgSharp.Mathematics.Numeric
#region right enum
[FieldOffset(32)] public int RightPrimOffset; // 4
[FieldOffset(32)]public int RightPrimOffset; // 4
[FieldOffset(36)]public int RightPrimStride; // 4
[FieldOffset(40)]public int RightSecOffset; // 4
[FieldOffset(44)]public int RightSecStride; // 4
@@ -147,9 +144,9 @@ namespace StgSharp.Mathematics.Numeric
#region global profile
[FieldOffset(96)]public int PrimCount; // 4
[FieldOffset(100)]public MatrixOpMode ComputeMode; // 4
[FieldOffset(104)]public int SecCount; // 4
[FieldOffset(96)]public int PrimCount; // 4
[FieldOffset(100)]public int SecCount; // 4
[FieldOffset(104)]public MatrixOpMode ComputeMode; // 4
[FieldOffset(108)]private int ReservedInt0; // 4
#endregion
@@ -163,90 +160,4 @@ namespace StgSharp.Mathematics.Numeric
#endregion
}
[StructLayout(LayoutKind.Explicit, Size =128)]
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
[FieldOffset(0)]public MatrixKernel<T>* Left; // 8
[FieldOffset(8)] public MatrixKernel<T>* Right; // 8
#endregion
#region ans
// Group 2: Result kernel base address + reserved
[FieldOffset(16)] public MatrixKernel<T>* Result; // 8
[FieldOffset(24)] public int ElementSize = sizeof(T);
[FieldOffset(28)] public int ReservedPtr0; // 4 (extension/reserved)
#endregion
#region left enum
[FieldOffset(32)]public int LeftPrimOffset; // 4
[FieldOffset(36)]public int LeftPrimStride; // 4
[FieldOffset(40)]public int LeftSecOffset; // 4
[FieldOffset(44)] public int LeftSecStride; // 4
#endregion
#region right enum
[FieldOffset(48)]public int RightPrimOffset; // 4
[FieldOffset(52)]public int RightPrimStride; // 4
[FieldOffset(56)]public int RightSecOffset; // 4
[FieldOffset(60)]public int RightSecStride; // 4
#endregion
#region ans enum
[FieldOffset(64)]public int ResultPrimOffset; // 4
[FieldOffset(68)]public int ResultPrimStride; // 4
[FieldOffset(72)]public int ResultSecOffset; // 4
[FieldOffset(76)] public int ResultSecStride; // 4
#endregion
#region scalar/compute
[FieldOffset(80)] public ScalarPacket* Scalar; // 8
[FieldOffset(88)]public IntPtr ComputeHandle; // 8
#endregion
#region global profile
[FieldOffset(96)] public int PrimCount; // 4
[FieldOffset(100)]public MatrixOpMode ComputeMode; // 4
[FieldOffset(104)]public int SecCount; // 4
[FieldOffset(108)] private readonly int ReservedInt0; // 4
#endregion
#region count offset
[FieldOffset(112)]public int PrimTileOffset; // 4
[FieldOffset(116)]public int SecTileOffset; // 4
[FieldOffset(120)]public int PrimColumnCountInTile; // 4
[FieldOffset(124)]public int SecColumnCountInTile; // 4
#endregion
}
}
@@ -27,6 +27,7 @@
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -53,6 +54,7 @@ namespace StgSharp.Mathematics.Numeric
_affinity = AffinityAllocator.Allocate();
_managedThread = new Thread(MatrixParallelWorker);
_managedThread.Start();
_resetEvent = new ManualResetEventSlim(false);
}
@@ -78,7 +80,7 @@ namespace StgSharp.Mathematics.Numeric
{
while (taskQueue.TryDequeue(out nint handle))
{
MatrixParallelTaskPackageNonGeneric* p = (MatrixParallelTaskPackageNonGeneric*)handle;
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)handle;
switch (p->ComputeMode.OperationStyle)
{
case MatrixOperationStyle.PANEL_OP:
@@ -127,16 +129,12 @@ namespace StgSharp.Mathematics.Numeric
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Restart()
{
_resetEvent.Set();
}
public void ReturnToPool()
{
// MatrixParallel.(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
@@ -159,27 +157,30 @@ namespace StgSharp.Mathematics.Numeric
// Bind OS-thread affinity once when the worker starts running
ApplyAffinityIfNeeded();
// Thread self = Thread.CurrentThread;
_resetEvent.Wait();
_resetEvent.Reset();
_managedThread.Priority = ThreadPriority.Highest;
switch (Role)
while (true)
{
case 0://worker
// _ = Interlocked.Decrement(ref RemainThreadCount);
ExecuteTaskPackage(Tasks);
break;
case 1://scheduler
BindedWrap.PublishTaskToWorkers(Tasks);
BindedWrap.SetAllWorker();
ExecuteTaskPackage(Tasks);
break;
case 2://leader, error because leader should be at outer thread but not here
break;
default:
break;
// Thread self = Thread.CurrentThread;
_managedThread.Priority = ThreadPriority.Highest;
_resetEvent.Wait();
_resetEvent.Reset();
switch (Role)
{
case 0://worker
// _ = Interlocked.Decrement(ref RemainThreadCount);
ExecuteTaskPackage(Tasks);
break;
case 1://scheduler
BindedWrap.PublishTaskToWorkers(BindedWrap.WrapTask);
BindedWrap.SetAllWorker();
ExecuteTaskPackage(Tasks);
break;
case 2://leader, error because leader should be at outer thread but not here
break;
default:
break;
}
_managedThread.Priority = AfterWork;
}
_managedThread.Priority = AfterWork;
}
#region core affinity
@@ -44,10 +44,13 @@ namespace StgSharp.Mathematics.Numeric
internal MatrixParallelWrap(MatrixParallelThread[] threads, int begin, int count)
{
WrapTaskCapacity = count;
_threads = threads;
_begin = begin;
Count = threads.Length;
_threads[_begin].Role = 1;
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) {
_threads[i].BindedWrap = this;
}
}
public MatrixParallelWrap()
@@ -63,15 +66,11 @@ namespace StgSharp.Mathematics.Numeric
internal int Magic { get; set; }
internal ManualResetEventSlim SchedulerReset { get; } = new(false);
private int Count { get; set; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetAllWorker()
{
foreach (MatrixParallelThread t in _threads) {
t.Restart();
for (int i = _begin; i < _begin + WrapTaskCapacity; i++) {
_threads[i].Restart();
}
}
@@ -79,25 +78,124 @@ namespace StgSharp.Mathematics.Numeric
{
while (tasks.TryDequeue(out nint handle))
{
MatrixParallelTaskPackageNonGeneric* task = (MatrixParallelTaskPackageNonGeneric*)handle;
PublishTaskToWorkers(task);
MatrixParallelTaskPackage* task = (MatrixParallelTaskPackage*)handle;
switch (task->ComputeMode.OperationStyle)
{
case MatrixOperationStyle.PANEL_OP:
break;
case MatrixOperationStyle.BUFFER_OP:
PublishBufferTaskToWorkers(task);
break;
case MatrixOperationStyle.KERNEL_OP:
PublishBufferTaskToWorkers(task);
break;
default:
break;
}
}
}
internal void PublishTaskToWorkers(MatrixParallelTaskPackageNonGeneric* taskPackage)
internal void SetScheduler()
{
int primCount = taskPackage->PrimCount;
int secCount = taskPackage->SecCount;
MatrixParallelThread thread = _threads[_begin];
thread.Restart();
}
int primAverage = primCount / Count;
int secAverage = secCount / Count;
bool shouldSliceSec = secAverage > 512;
for (int i = _begin; i < _begin + Count; i++)
private void PublishBufferTaskToWorkers(MatrixParallelTaskPackage* package)
{
long count = Unsafe.As<int, long>(ref package->PrimCount);
long recommendCount = count / 1024;
MatrixParallelThread[] pool = _threads;
if (pool.Length == 1)
{
Queue<IntPtr> tasks = _threads[i].Tasks;
MatrixParallelTaskPackageNonGeneric* subTask = MatrixParallelFactory.FromExistPackage(taskPackage);
subTask->PrimTileOffset = i * primAverage;
pool[0].Tasks.Enqueue((nint)package);
return;
}
long actual = count / pool.Length;
long extra = count % pool.Length;
long offset = 0;
MatrixParallelTaskPackage* current = package;
foreach (MatrixParallelThread thread in pool)
{
long wrapTaskLength = actual;
long ex = extra > 0 ? 1 : 0;
extra -= ex;
ref long offsetRef = ref Unsafe.As<int, long>(ref current->PrimTileOffset);
offsetRef += offset;
ref long lengthRef = ref Unsafe.As<int, long>(ref current->PrimCount);
lengthRef = wrapTaskLength + ex;
pool[0].Tasks.Enqueue((nint)current);
current = MatrixParallelFactory.FromExistPackage(current);
offset += wrapTaskLength;
}
}
private void PublishKernelTaskToWorkers(MatrixParallelTaskPackage* package)
{
int primCount = package->PrimCount;
int secCount = package->SecCount;
MatrixParallelThread[] pool = _threads;
if (pool.Length == 1)
{
pool[0].Tasks.Enqueue((nint)package);
return;
}
throw new NotImplementedException();
/*
int threadCount = pool.Length;
int tilePerThreadLess = tileCount / threadCount; // tiles per thread without extra slice
int columnAfterBaseTile = tileCount % threadCount * tileWidth; // tile sliced into columns
int extraColumnPerThread = columnAfterBaseTile / threadCount;
int extraColumnCount = columnAfterBaseTile % threadCount; // columns to be sliced
int total = primCount;
Stack<MatrixParallelWrap> taskBunch = new Stack<MatrixParallelWrap>(threadCount);
MatrixParallelTaskPackageNonGeneric* current = package;
foreach (MatrixParallelWrap wrap in pool.Wraps)
{
bool hasSlice = columnAfterBaseTile > 0;
bool isLargeSlice = extraColumnCount > 0;
// _count tiles for wrap
int wrapWidth = wrap!.WrapTaskCapacity;
int columnFromSlicingCount = (hasSlice ? extraColumnPerThread : 0) * wrapWidth;
int baseColumn = wrapWidth * tilePerThreadLess * tileWidth;
int columnInWrap = baseColumn + columnFromSlicingCount + (isLargeSlice ? 1 : 0);
// set tasks
if (columnInWrap == 0)
{
#if DEBUG
throw new InvalidOperationException("Zero tasks published.");
#else
break;
#endif
}
// update current task
current->PrimColumnCountInTile = columnInWrap;
current->SecColumnCountInTile = current->SecCount;
current->SecTileOffset = 0;
// remove tiles _count
extraColumnCount--;
columnAfterBaseTile -= columnFromSlicingCount;
total -= columnInWrap;
// set to wrap and push
wrap.WrapTask = current;
if (total <= 0)
{
break;
}
current = MatrixParallelFactory.FromExistPackage(current);
current->PrimTileOffset += columnInWrap;
}
/**/
return;
}
public class Handle(int inWrapIndex, MatrixParallelWrap wrap)
@@ -121,15 +219,11 @@ namespace StgSharp.Mathematics.Numeric
#region wrap task
internal MatrixParallelTaskPackageNonGeneric* WrapTask { get; set; }
internal unsafe Queue<nint> WrapTask { get; set; } = [];
internal int WrapTaskSliceCount { get; set; }
internal int WrapTaskCapacity
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _threads.Length;
}
internal int WrapTaskCapacity { get ; init; }
#endregion
}
@@ -55,13 +55,13 @@ namespace StgSharp.Mathematics.Numeric
private static SlabAllocator<ScalarPacket> _scalarAllocator ;
private static SlabAllocator<MatrixParallelTaskPackageNonGeneric> _wrapAllocator;
private static SlabAllocator<MatrixParallelTaskPackage> _wrapAllocator;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MatrixParallelTaskPackage<T>* CreateBaseTask<T>() where T: unmanaged, INumber<T>
public static MatrixParallelTaskPackage* CreateBaseTask<T>() where T : unmanaged, INumber<T>
{
MatrixParallelTaskPackage<T>* p = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTaskPackage<T>));
MatrixParallelTaskPackage* p = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
Span<byte> s = new Span<byte>((byte*)p, sizeof(MatrixParallelTaskPackage));
s.Fill(0);
return p;
}
@@ -74,20 +74,19 @@ namespace StgSharp.Mathematics.Numeric
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe MatrixParallelTaskPackage<T>* FromExistPackage<T>(MatrixParallelTaskPackage<T>* exist)
where T: unmanaged, INumber<T>
public static unsafe MatrixParallelTaskPackage* FromExistPackage<T>(MatrixParallelTaskPackage* exist)
where T : unmanaged, INumber<T>
{
MatrixParallelTaskPackage<T>* ptr = (MatrixParallelTaskPackage<T>*)_wrapAllocator.Allocate();
MatrixParallelTaskPackage<T>.Copy(exist, ptr);
MatrixParallelTaskPackage* ptr = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
MatrixParallelTaskPackage.Copy(exist, ptr);
return ptr;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe MatrixParallelTaskPackageNonGeneric* FromExistPackage(
MatrixParallelTaskPackageNonGeneric* exist)
public static unsafe MatrixParallelTaskPackage* FromExistPackage(MatrixParallelTaskPackage* exist)
{
MatrixParallelTaskPackageNonGeneric* ptr = (MatrixParallelTaskPackageNonGeneric*)_wrapAllocator.Allocate();
MatrixParallelTaskPackageNonGeneric.Copy(exist, ptr);
MatrixParallelTaskPackage* ptr = (MatrixParallelTaskPackage*)_wrapAllocator.Allocate();
MatrixParallelTaskPackage.Copy(exist, ptr);
return ptr;
}
@@ -99,7 +98,7 @@ namespace StgSharp.Mathematics.Numeric
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Release(MatrixParallelTaskPackageNonGeneric* source)
public static void Release(MatrixParallelTaskPackage* source)
{
if (source->Scalar != null) {
_scalarAllocator.Free((nuint)source->Scalar);
@@ -108,7 +107,7 @@ namespace StgSharp.Mathematics.Numeric
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Release<T>(MatrixParallelTaskPackage<T>* source) where T: unmanaged, INumber<T>
public static void Release<T>(MatrixParallelTaskPackage* source) where T : unmanaged, INumber<T>
{
if (source->Scalar != null) {
_scalarAllocator.Free((nuint)source->Scalar);
@@ -123,7 +122,7 @@ namespace StgSharp.Mathematics.Numeric
{
_intermediateResult = new hlsfAllocator(64 * 16 * 16);
_scalarAllocator = SlabAllocator<ScalarPacket>.Create(64 * 1024, SlabBufferLayout.Chunked);
_wrapAllocator = SlabAllocator<MatrixParallelTaskPackageNonGeneric>.
_wrapAllocator = SlabAllocator<MatrixParallelTaskPackage>.
Create(128 * 1024, SlabBufferLayout.Chunked);
}
}