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
@@ -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)
{