small size buffer op ok
This commit is contained in:
@@ -41,41 +41,41 @@ namespace StgSharp.Mathematics.Numeric
|
||||
public static class MatrixCompute
|
||||
{
|
||||
|
||||
public static unsafe Matrix<float> Add(Matrix<float> left, Matrix<float> right)
|
||||
public static unsafe Matrix<float> Add(this Matrix<float> left, Matrix<float> right)
|
||||
{
|
||||
if (left.ColumnLength != right.ColumnLength || left.RowLength != right.RowLength) {
|
||||
throw new IndexOutOfRangeException("Matrix dimensions must agree.");
|
||||
}
|
||||
Matrix<float> ans = Matrix<float>.FromDefault(left.ColumnLength, left.RowLength);
|
||||
long count = (long)left.KernelColumnLength * left.KernelRowLength;
|
||||
Matrix<float> ans = Matrix<float>.FromDefault(left.ColumnLength, left.RowLength);
|
||||
if (count <= 256)
|
||||
{
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* rightPtr = right.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
for (int i = 0; i < count; i++) {
|
||||
NativeIntrinsic.Intrinsic.f32_add(leftPtr + i, rightPtr + i, ansPtr + i);
|
||||
}
|
||||
NativeIntrinsic.Intrinsic.f32_add(leftPtr, rightPtr, ansPtr, count);
|
||||
|
||||
return ans;
|
||||
}
|
||||
if (count <= 1024)
|
||||
} else if (count <= 1024)
|
||||
{
|
||||
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
|
||||
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
MatrixKernel<float>* rightPtr = right.Buffer;
|
||||
MatrixKernel<float>* ansPtr = ans.Buffer;
|
||||
for (int i = 0; i < count; i++) {
|
||||
NativeIntrinsic.Intrinsic.f32_add(leftPtr + i, rightPtr + i, ansPtr + i);
|
||||
}
|
||||
NativeIntrinsic.Intrinsic.f32_add(leftPtr, rightPtr, ansPtr, count);
|
||||
|
||||
MatrixParallel.ReturnParallelResources(ref pool);
|
||||
return ans;
|
||||
}
|
||||
MatrixParallelHandle taskGroup = MatrixParallel.PublicTask(left.GetColumnEnumeration(),
|
||||
MatrixParallelHandle taskGroup = /**/ default
|
||||
/*
|
||||
MatrixParallel.PublicTask(left.GetColumnEnumeration(),
|
||||
right.GetColumnEnumeration(),
|
||||
ans.GetColumnEnumeration(),
|
||||
(delegate*<MatrixKernel<float>*, MatrixKernel<float>*, MatrixKernel<float>*, void>)NativeIntrinsic.Intrinsic.f32_add);
|
||||
|
||||
(delegate*<MatrixKernel<float>*, MatrixKernel<float>*, MatrixKernel<float>*, void>)NativeIntrinsic.Intrinsic.f32_add)
|
||||
/**/
|
||||
;
|
||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||
/*
|
||||
* run parallel
|
||||
@@ -84,35 +84,33 @@ namespace StgSharp.Mathematics.Numeric
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static unsafe void Fill<T>(Matrix<float> left, T value) where T: unmanaged, INumber<T>
|
||||
public static unsafe void Fill<T>(this Matrix<float> right, T value) where T : unmanaged, INumber<T>
|
||||
{
|
||||
long count = (long)left.KernelColumnLength * left.KernelRowLength;
|
||||
long count = (long)right.KernelColumnLength * right.KernelRowLength;
|
||||
ScalarPacket* scaler = MatrixParallelFactory.CreateScalarPacket();
|
||||
scaler->BroadCast<T, M512>(0, value);
|
||||
scaler->Data<T>(0) = value;
|
||||
if (count <= 256)
|
||||
{
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
for (int i = 0; i < count; i++) {
|
||||
NativeIntrinsic.Intrinsic.f32_fill(leftPtr + i, scaler);
|
||||
}
|
||||
}
|
||||
if (count <= 1024)
|
||||
NativeIntrinsic.Intrinsic.f32_fill(right.Buffer, scaler, count);
|
||||
return;
|
||||
} else if (count <= 1024)
|
||||
{
|
||||
MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1);
|
||||
|
||||
MatrixKernel<float>* leftPtr = left.Buffer;
|
||||
for (int i = 0; i < count; i++) {
|
||||
NativeIntrinsic.Intrinsic.f32_fill(leftPtr + i, scaler);
|
||||
}
|
||||
MatrixParallel.ReturnParallelResources(ref pool);
|
||||
}
|
||||
MatrixParallelHandle taskGroup = MatrixParallel.PublicNoAnswerTask(left.GetColumnEnumeration(), scaler,
|
||||
(delegate* unmanaged[Cdecl]<MatrixKernel<float>*, ScalarPacket*, void>)NativeIntrinsic.Intrinsic.f32_add);
|
||||
NativeIntrinsic.Intrinsic.f32_fill(right.Buffer, scaler, 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)
|
||||
/**/;
|
||||
MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep);
|
||||
/*
|
||||
* run parallel
|
||||
*/
|
||||
MatrixParallelFactory.Release(scaler);
|
||||
taskGroup.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,29 @@ namespace StgSharp.Mathematics.Numeric
|
||||
internal static class MatrixComputeModel
|
||||
{
|
||||
|
||||
internal static unsafe void BufferComputeBinary(MatrixParallelTaskPackageNonGeneric* p)
|
||||
{
|
||||
int size = p->ElementSize * 16;
|
||||
int count = p->PrimCount * p->SecCount;
|
||||
int offset = p->LeftPrimOffset * p->SecCount;
|
||||
|
||||
((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);
|
||||
}
|
||||
|
||||
internal static unsafe void BufferComputeUnaryScalar(MatrixParallelTaskPackageNonGeneric* p)
|
||||
{
|
||||
int size = p->ElementSize * 16;
|
||||
int count = p->PrimCount * p->SecCount;
|
||||
int offset = p->LeftPrimOffset * p->SecCount;
|
||||
|
||||
((delegate* unmanaged[Cdecl]<void*, void*, int, void>)p->ComputeHandle)((void*)(p->Right + offset * size),
|
||||
(void*)(p->Result + offset * size),
|
||||
count);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static unsafe void Compute_Binary(MatrixParallelTaskPackageNonGeneric* p)
|
||||
{
|
||||
|
||||
@@ -40,801 +40,8 @@ namespace StgSharp.Mathematics.Numeric
|
||||
public static partial class MatrixParallel
|
||||
{
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicNoAnswerTask<T>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
ScalarPacket* additional,
|
||||
delegate* unmanaged[Cdecl]<MatrixKernel<T>*, ScalarPacket*, void> computeHandle)
|
||||
where T: unmanaged, INumber<T>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Scalar = additional;
|
||||
package->Right = source.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeHandle = (nint)computeHandle;
|
||||
package->ComputeMode = 6; // no ans
|
||||
return PublicTaskPrivate(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation)
|
||||
where T: unmanaged, INumber<T>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 1; // Unary
|
||||
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle 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>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 3; // Binary
|
||||
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
// Unary with 1..8 scalars (each scalar is independent generic type)
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2; // UnaryScalar
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
// Binary with 1..8 scalars (each scalar is independent generic type)
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4; // BinaryScalar
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4, TScalar5>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4,
|
||||
TScalar5 s5)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
where TScalar5: unmanaged, INumber<TScalar5>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
sp->Data<TScalar5>(5) = s5;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4, TScalar5, TScalar6>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4,
|
||||
TScalar5 s5,
|
||||
TScalar6 s6)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
where TScalar5: unmanaged, INumber<TScalar5>
|
||||
where TScalar6: unmanaged, INumber<TScalar6>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
sp->Data<TScalar5>(5) = s5;
|
||||
sp->Data<TScalar6>(6) = s6;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4, TScalar5>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4,
|
||||
TScalar5 s5)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
where TScalar5: unmanaged, INumber<TScalar5>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
sp->Data<TScalar5>(5) = s5;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4, TScalar5, TScalar6, TScalar7>(
|
||||
MatrixSegmentEnumeration<T> source,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4,
|
||||
TScalar5 s5,
|
||||
TScalar6 s6,
|
||||
TScalar7 s7)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
where TScalar5: unmanaged, INumber<TScalar5>
|
||||
where TScalar6: unmanaged, INumber<TScalar6>
|
||||
where TScalar7: unmanaged, INumber<TScalar7>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Right = source.Source;
|
||||
package->Result = ans.Source;
|
||||
package->RightPrimOffset = source.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->RightPrimStride = source.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->RightSecOffset = source.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->RightSecStride = source.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = source.PrimSize;
|
||||
package->SecCount = source.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 2;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
sp->Data<TScalar5>(5) = s5;
|
||||
sp->Data<TScalar6>(6) = s6;
|
||||
sp->Data<TScalar7>(7) = s7;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4, TScalar5, TScalar6>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4,
|
||||
TScalar5 s5,
|
||||
TScalar6 s6)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
where TScalar5: unmanaged, INumber<TScalar5>
|
||||
where TScalar6: unmanaged, INumber<TScalar6>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
sp->Data<TScalar5>(5) = s5;
|
||||
sp->Data<TScalar6>(6) = s6;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
public static unsafe MatrixParallelHandle PublicTask<T, TScalar0, TScalar1, TScalar2, TScalar3, TScalar4, TScalar5, TScalar6, TScalar7>(
|
||||
MatrixSegmentEnumeration<T> left,
|
||||
MatrixSegmentEnumeration<T> right,
|
||||
MatrixSegmentEnumeration<T> ans,
|
||||
delegate*<MatrixKernel<T>*, MatrixKernel<T>*, MatrixKernel<T>*, void> Operation,
|
||||
TScalar0 s0,
|
||||
TScalar1 s1,
|
||||
TScalar2 s2,
|
||||
TScalar3 s3,
|
||||
TScalar4 s4,
|
||||
TScalar5 s5,
|
||||
TScalar6 s6,
|
||||
TScalar7 s7)
|
||||
where T: unmanaged, INumber<T>
|
||||
where TScalar0: unmanaged, INumber<TScalar0>
|
||||
where TScalar1: unmanaged, INumber<TScalar1>
|
||||
where TScalar2: unmanaged, INumber<TScalar2>
|
||||
where TScalar3: unmanaged, INumber<TScalar3>
|
||||
where TScalar4: unmanaged, INumber<TScalar4>
|
||||
where TScalar5: unmanaged, INumber<TScalar5>
|
||||
where TScalar6: unmanaged, INumber<TScalar6>
|
||||
where TScalar7: unmanaged, INumber<TScalar7>
|
||||
{
|
||||
MatrixParallelTaskPackage<T>* package = MatrixParallelFactory.CreateBaseTask<T>();
|
||||
package->Left = left.Source;
|
||||
package->Right = right.Source;
|
||||
package->Result = ans.Source;
|
||||
package->LeftPrimOffset = left.PrimOffset;
|
||||
package->RightPrimOffset = right.PrimOffset;
|
||||
package->ResultPrimOffset = ans.PrimOffset;
|
||||
package->LeftPrimStride = left.PrimStride;
|
||||
package->RightPrimStride = right.PrimStride;
|
||||
package->ResultPrimStride = ans.PrimStride;
|
||||
package->LeftSecOffset = left.SecondaryOffset;
|
||||
package->RightSecOffset = right.SecondaryOffset;
|
||||
package->ResultSecOffset = ans.SecondaryOffset;
|
||||
package->LeftSecStride = left.SecondaryStride;
|
||||
package->RightSecStride = right.SecondaryStride;
|
||||
package->ResultSecStride = ans.SecondaryStride;
|
||||
package->PrimCount = left.PrimSize;
|
||||
package->SecCount = left.SecondarySize;
|
||||
package->ComputeHandle = (nint)Operation;
|
||||
package->ElementSize = sizeof(T);
|
||||
package->ComputeMode = 4;
|
||||
ScalarPacket* sp = MatrixParallelFactory.CreateScalarPacket();
|
||||
|
||||
sp->Data<TScalar0>(0) = s0;
|
||||
sp->Data<TScalar1>(1) = s1;
|
||||
sp->Data<TScalar2>(2) = s2;
|
||||
sp->Data<TScalar3>(3) = s3;
|
||||
sp->Data<TScalar4>(4) = s4;
|
||||
sp->Data<TScalar5>(5) = s5;
|
||||
sp->Data<TScalar6>(6) = s6;
|
||||
sp->Data<TScalar7>(7) = s7;
|
||||
package->Scalar = sp;
|
||||
return PublicTaskPrivate<T>(package);
|
||||
}
|
||||
|
||||
private static unsafe MatrixParallelHandle PublicTaskPrivate<T>(MatrixParallelTaskPackage<T>* package)
|
||||
where T: unmanaged, INumber<T>
|
||||
where T : unmanaged, INumber<T>
|
||||
{
|
||||
int primCount = package->PrimCount;
|
||||
int secCount = package->SecCount;
|
||||
|
||||
@@ -34,7 +34,54 @@ using System.Runtime.InteropServices;
|
||||
|
||||
namespace StgSharp.Mathematics.Numeric
|
||||
{
|
||||
/*
|
||||
* #define PANEL_OP 1
|
||||
* #define BUFFER_OP 2
|
||||
* #define KERNEL_OP 3
|
||||
*
|
||||
* #define RIGHT_ANS_PARAM 1
|
||||
* #define LEFT_RIGHT_ANS_PARAM 2
|
||||
* #define RIGHT_ANS_SCALAR_PARAM 3
|
||||
* #define LEFT_RIGHT_ANS_SCALAR_PARAM 4
|
||||
* #define ANS_SCALAR_PARAM 5
|
||||
*
|
||||
* typedef struct matrix_op_mode {
|
||||
* int16_t operation_style; // PANEL_OP, BUFFER_OP, KERNEL_OP
|
||||
* int16_t parameter_style; // RIGHT_ANS_PARAM, LEFT_RIGHT_ANS_PARAM, e.g.
|
||||
* }
|
||||
* matrix_op_mode;
|
||||
*/
|
||||
|
||||
public enum MatrixOperationStyle : short
|
||||
{
|
||||
|
||||
PANEL_OP = 1,
|
||||
BUFFER_OP = 2,
|
||||
KERNEL_OP = 3,
|
||||
|
||||
}
|
||||
|
||||
public enum MatrixOperationParam : short
|
||||
{
|
||||
|
||||
RIGHT_ANS_PARAM = 1,
|
||||
LEFT_RIGHT_ANS_PARAM = 2,
|
||||
RIGHT_ANS_SCALAR_PARAM = 3,
|
||||
LEFT_RIGHT_ANS_SCALAR_PARAM = 4,
|
||||
ANS_SCALAR_PARAM = 5,
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MatrixOpMode
|
||||
{
|
||||
|
||||
public MatrixOperationParam ParameterStyle;
|
||||
public MatrixOperationStyle OperationStyle;
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 128)]
|
||||
internal unsafe struct MatrixParallelTaskPackageNonGeneric
|
||||
{
|
||||
|
||||
@@ -50,69 +97,69 @@ namespace StgSharp.Mathematics.Numeric
|
||||
#region source
|
||||
|
||||
// Group 1: Left/Right matrix kernel base address
|
||||
public IntPtr Left; // 8
|
||||
public IntPtr Right; // 8
|
||||
[FieldOffset(0)]public IntPtr Left; // 8
|
||||
[FieldOffset(8)] public IntPtr Right; // 8
|
||||
|
||||
#endregion
|
||||
|
||||
#region ans
|
||||
|
||||
// Group 2: Result kernel base address + reserved
|
||||
public IntPtr Result; // 8
|
||||
public int ElementSize;
|
||||
public int ReservedPtr0; // 4 (extension/reserved)
|
||||
[FieldOffset(16)] public IntPtr Result; // 8
|
||||
[FieldOffset(24)]public int ElementSize;
|
||||
[FieldOffset(28)] public int ReservedPtr0; // 4 (extension/reserved)
|
||||
|
||||
#endregion
|
||||
|
||||
#region left enum
|
||||
|
||||
public int LeftPrimOffset; // 4
|
||||
public int LeftPrimStride; // 4
|
||||
public int LeftSecOffset; // 4
|
||||
public int LeftSecStride; // 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
|
||||
|
||||
#endregion
|
||||
|
||||
#region right enum
|
||||
|
||||
public int RightPrimOffset; // 4
|
||||
public int RightPrimStride; // 4
|
||||
public int RightSecOffset; // 4
|
||||
public int RightSecStride; // 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
|
||||
|
||||
#endregion
|
||||
|
||||
#region ans enum
|
||||
|
||||
public int ResultPrimOffset; // 4
|
||||
public int ResultPrimStride; // 4
|
||||
public int ResultSecOffset; // 4
|
||||
public int ResultSecStride; // 4
|
||||
[FieldOffset(48)]public int ResultPrimOffset; // 4
|
||||
[FieldOffset(52)]public int ResultPrimStride; // 4
|
||||
[FieldOffset(56)]public int ResultSecOffset; // 4
|
||||
[FieldOffset(60)] public int ResultSecStride; // 4
|
||||
|
||||
#endregion
|
||||
|
||||
#region scalar/compute
|
||||
|
||||
public ScalarPacket* Scalar; // 8
|
||||
public IntPtr ComputeHandle; // 8
|
||||
[FieldOffset(80)]public ScalarPacket* Scalar; // 8
|
||||
[FieldOffset(88)]public IntPtr ComputeHandle; // 8
|
||||
|
||||
#endregion
|
||||
|
||||
#region global profile
|
||||
|
||||
public int PrimCount; // 4
|
||||
public int ComputeMode; // 4
|
||||
public int SecCount; // 4
|
||||
private int ReservedInt0; // 4
|
||||
[FieldOffset(96)]public int PrimCount; // 4
|
||||
[FieldOffset(100)]public MatrixOpMode ComputeMode; // 4
|
||||
[FieldOffset(104)]public int SecCount; // 4
|
||||
[FieldOffset(108)]private int ReservedInt0; // 4
|
||||
|
||||
#endregion
|
||||
|
||||
#region count offset
|
||||
|
||||
public int PrimTileOffset; // 4
|
||||
public int SecTileOffset; // 4
|
||||
public int PrimCountInTile; // 4
|
||||
public int SecCountInTile; // 4
|
||||
[FieldOffset(112)]public int PrimTileOffset; // 4
|
||||
[FieldOffset(116)]public int SecTileOffset; // 4
|
||||
[FieldOffset(120)]public int PrimCountInTile; // 4
|
||||
[FieldOffset(124)]public int SecCountInTile; // 4
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -186,8 +233,8 @@ namespace StgSharp.Mathematics.Numeric
|
||||
|
||||
#region global profile
|
||||
|
||||
[FieldOffset(96)]public int PrimCount; // 4
|
||||
[FieldOffset(100)]public int ComputeMode; // 4
|
||||
[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
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -38,12 +39,19 @@ namespace StgSharp.Mathematics.Numeric
|
||||
public class MatrixParallelThread : IDisposable
|
||||
{
|
||||
|
||||
// Affinity binding info for this thread
|
||||
private AffinityBinding _affinity;
|
||||
private bool _affinityApplied;
|
||||
|
||||
private bool disposedValue;
|
||||
private ManualResetEventSlim _resetEvent;
|
||||
private Thread _managedThread;
|
||||
|
||||
public MatrixParallelThread()
|
||||
{
|
||||
// Allocate a unique logical processor for this worker (mutually exclusive)
|
||||
_affinity = AffinityAllocator.Allocate();
|
||||
|
||||
_managedThread = new Thread(MatrixParallelWorker);
|
||||
_resetEvent = new ManualResetEventSlim(false);
|
||||
}
|
||||
@@ -71,19 +79,47 @@ namespace StgSharp.Mathematics.Numeric
|
||||
while (taskQueue.TryDequeue(out nint handle))
|
||||
{
|
||||
MatrixParallelTaskPackageNonGeneric* p = (MatrixParallelTaskPackageNonGeneric*)handle;
|
||||
switch (p->ComputeMode)
|
||||
switch (p->ComputeMode.OperationStyle)
|
||||
{
|
||||
case 1:
|
||||
MatrixComputeModel.Compute_Unary(p);
|
||||
case MatrixOperationStyle.PANEL_OP:
|
||||
break;
|
||||
case 2:
|
||||
MatrixComputeModel.Compute_UnaryScalar(p);
|
||||
case MatrixOperationStyle.BUFFER_OP:
|
||||
switch (p->ComputeMode.ParameterStyle)
|
||||
{
|
||||
case MatrixOperationParam.RIGHT_ANS_PARAM:
|
||||
break;
|
||||
case MatrixOperationParam.LEFT_RIGHT_ANS_PARAM:
|
||||
MatrixComputeModel.BufferComputeBinary(p);
|
||||
break;
|
||||
case MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM:
|
||||
MatrixComputeModel.BufferComputeUnaryScalar(p);
|
||||
break;
|
||||
case MatrixOperationParam.LEFT_RIGHT_ANS_SCALAR_PARAM:
|
||||
break;
|
||||
case MatrixOperationParam.ANS_SCALAR_PARAM:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
MatrixComputeModel.Compute_Binary(p);
|
||||
break;
|
||||
case 4:
|
||||
MatrixComputeModel.Compute_BinaryScalar(p);
|
||||
case MatrixOperationStyle.KERNEL_OP:
|
||||
switch (p->ComputeMode.ParameterStyle)
|
||||
{
|
||||
case MatrixOperationParam.RIGHT_ANS_PARAM:
|
||||
MatrixComputeModel.Compute_Unary(p);
|
||||
break;
|
||||
case MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM:
|
||||
MatrixComputeModel.Compute_UnaryScalar(p);
|
||||
break;
|
||||
case MatrixOperationParam.LEFT_RIGHT_ANS_PARAM:
|
||||
MatrixComputeModel.Compute_Binary(p);
|
||||
break;
|
||||
case MatrixOperationParam.LEFT_RIGHT_ANS_SCALAR_PARAM:
|
||||
MatrixComputeModel.Compute_BinaryScalar(p);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -111,12 +147,18 @@ namespace StgSharp.Mathematics.Numeric
|
||||
_managedThread.Join();
|
||||
}
|
||||
|
||||
// Release the reserved logical processor back to the pool
|
||||
AffinityAllocator.Release(_affinity.LogicalProcessor);
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void MatrixParallelWorker()
|
||||
{
|
||||
// Bind OS-thread affinity once when the worker starts running
|
||||
ApplyAffinityIfNeeded();
|
||||
|
||||
// Thread self = Thread.CurrentThread;
|
||||
_resetEvent.Wait();
|
||||
_resetEvent.Reset();
|
||||
@@ -141,6 +183,139 @@ namespace StgSharp.Mathematics.Numeric
|
||||
_managedThread.Priority = AfterWork;
|
||||
}
|
||||
|
||||
#region core affinity
|
||||
|
||||
/*
|
||||
* data to record core affinity
|
||||
* preparation for future NUMA affinity setting
|
||||
*/
|
||||
|
||||
// Represents the binding information for a worker thread
|
||||
internal readonly struct AffinityBinding
|
||||
{
|
||||
|
||||
public readonly int LogicalProcessor;
|
||||
public readonly nuint Mask;
|
||||
|
||||
public AffinityBinding(int logicalProcessor, nuint mask)
|
||||
{
|
||||
LogicalProcessor = logicalProcessor;
|
||||
Mask = mask;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Thread-safe allocator that hands out unique logical processors (mutually exclusive)
|
||||
internal static class AffinityAllocator
|
||||
{
|
||||
|
||||
// Bitset of reserved logical processors (0..63). One bit per CPU.
|
||||
private static long s_reservedMask; // treat as unsigned bits
|
||||
|
||||
public static AffinityBinding Allocate()
|
||||
{
|
||||
int cpuCount = Environment.ProcessorCount;
|
||||
if (cpuCount > 64)
|
||||
{
|
||||
cpuCount = 64; // SetThreadAffinityMask supports up to 64-bit mask
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
long snapshot = Volatile.Read(ref s_reservedMask);
|
||||
|
||||
// Find first zero bit
|
||||
int candidate = -1;
|
||||
long bit = 0;
|
||||
for (int i = 0; i < cpuCount; i++)
|
||||
{
|
||||
bit = 1L << i;
|
||||
if ((snapshot & bit) == 0)
|
||||
{
|
||||
candidate = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (candidate < 0)
|
||||
{
|
||||
// No free CPU found: fall back to CPU 0 (shared)
|
||||
return new AffinityBinding(0, (nuint)1);
|
||||
}
|
||||
|
||||
long desired = snapshot | bit;
|
||||
if (Interlocked.CompareExchange(ref s_reservedMask, desired, snapshot) == snapshot)
|
||||
{
|
||||
// Successfully reserved candidate
|
||||
nuint mask = (nuint)(1UL << candidate);
|
||||
return new AffinityBinding(candidate, mask);
|
||||
}
|
||||
|
||||
// else: another thread raced us; retry
|
||||
}
|
||||
}
|
||||
|
||||
public static void Release(int logicalProcessor)
|
||||
{
|
||||
if ((uint)logicalProcessor >= 64u) {
|
||||
return;
|
||||
}
|
||||
|
||||
long bit = 1L << logicalProcessor;
|
||||
while (true)
|
||||
{
|
||||
long snapshot = Volatile.Read(ref s_reservedMask);
|
||||
if ((snapshot & bit) == 0)
|
||||
{
|
||||
return; // already free
|
||||
}
|
||||
|
||||
long desired = snapshot & ~bit;
|
||||
if (Interlocked.CompareExchange(ref s_reservedMask, desired, snapshot) == snapshot) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ApplyAffinityIfNeeded()
|
||||
{
|
||||
if (_affinityApplied) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if WINDOWS
|
||||
try
|
||||
{
|
||||
// On Windows pin the current native thread to the reserved logical processor
|
||||
SetThreadAffinityMask(GetCurrentThread(), _affinity.Mask);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore binding errors; continue without affinity
|
||||
}
|
||||
#elif LINUX
|
||||
|
||||
#endif
|
||||
|
||||
_affinityApplied = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#if WINDOWS
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern IntPtr GetCurrentThread();
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern nuint SetThreadAffinityMask(IntPtr hThread, nuint dwThreadAffinityMask);
|
||||
|
||||
#elif LINUX
|
||||
|
||||
#endif
|
||||
|
||||
#region wrap belong
|
||||
|
||||
internal MatrixParallelWrap BindedWrap { get; set; } = null!;
|
||||
|
||||
@@ -13,4 +13,20 @@
|
||||
<ProjectReference Include="..\StgSharp.Common\StgSharp.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>WINDOWS</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>LINUX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user