Process 1: SSE intrinsics tha involve matrix operations
Port code in src\Microsoft.ML.CpuMath\Sse.cs and src\Native\CpuMathNative\Sse.cpp to managed code in src\Microsoft.ML.CpuMath\CpuMathUtils.netcoreapp.cs and src\Microsoft.ML.CpuMath\SseIntrinsics
Progress
Implemented all required intrinsics, but there are some points that ask for further review. Those new intrinsics are:
MatMulA
MatMulPA
MatMulTranA
MatMulTranPA
MatMulRU
MatMulCU
MatMulDU
ZeroItemsU
ZeroMatrixItemsCore
Please let me know if I have missed any intrinsics needed.
Design questions
pdLim becomes pDstEnd
pposLim becomes pposEnd (this changes some public function signatures)
ppossrc becomes pposSrc
srcValues becomes src
Are these changes preferable?
fixed (float* pdst = &dst.Items[0])
fixed (float* pmat = &mat.Items[0])
fixed (float* psrc = &src.Items[0])
fixed (float* psrc = &src.Items[0])
fixed (float* pdst = &dst.Items[0])
fixed (float* pmat = &mat.Items[0])
Process 2: AVX intrinsics
Progress:
Haven't implemented any AVX intrinsics, but have already created a new AvxIntrinsics class alongside SseIntrinsics under src\Microsoft.ML.CpuMath. The following AVX intrinsics are needed:
MatMulX
MatMulTranX
MatMulPX
MatMulTranPX
MatMulRX
MatMulCX
MatMulDX
ScaleX
AddScaleX
AddX
Please let me know if I have missed any intrinsics needed. Please note that the last 3 AVX intrinsics above are not even used/called unless the relevant questions below are addressed. It seems to me that the original AvxUtils class in src\Microsoft.ML.CpuMath\Avx.cs was written but not meant to be frequently called.
Design questions
In src\Microsoft.ML.CpuMath\Avx.cs:
Process 3: Shared fields/methods between SSE and AVX
Design questions
- field:
pubic const int **CbAlign**
- method:
private static bool **Compat**
- method:
internal static bool **Ptr** (originally private but changed to internal so that SseIntrinsics and AvxIntrinsics methods can call it)
Where should we place them?
TODOs
Find answers to the above questions, and understand the logic of matrix operations in order to implement reliable unit tests.
Process 1: SSE intrinsics tha involve matrix operations
Port code in
src\Microsoft.ML.CpuMath\Sse.csandsrc\Native\CpuMathNative\Sse.cppto managed code insrc\Microsoft.ML.CpuMath\CpuMathUtils.netcoreapp.csandsrc\Microsoft.ML.CpuMath\SseIntrinsicsProgress
Implemented all required intrinsics, but there are some points that ask for further review. Those new intrinsics are:
MatMulAMatMulPAMatMulTranAMatMulTranPAMatMulRUMatMulCUMatMulDUZeroItemsUZeroMatrixItemsCorePlease let me know if I have missed any intrinsics needed.
Design questions
pdLimbecomespDstEndpposLimbecomespposEnd(this changes some public function signatures)ppossrcbecomespposSrcsrcValuesbecomessrcAre these changes preferable?
There were discussions about removing the dependency on the data structure
AlignedArray. There is a function calledPtrthat is closely associated withAlignedArrayand frequently referenced. If we removeAlignedArray, we don't needPtranymore. Should we removeAlignedArray, and if so, how?Because some intrinsics are using
AlignedArrayand hence callingPtr, some native methods are accepting pointers as input arguments, which are not desirable. This question issue has been easily solved when implementing the key intrinsics. For our current case, we could makePtrinternalinstead ofprivateand move the callsites ofPtrfromCpuMathUtilstoSseIntrinsics, which avoids fixing arrays twice and keeps only theSseIntrinsicsfunctions unsafe, but not theCpuMathUtilsones. How does this suggestion sound?Does the order of fixed statements affect computational efficiency? For example, I saw both cases in
Sse.cs:Should
posMinbe calledposStartinstead?In
MatMulRU,pi,pii, andpindicesare confusing - recommend usingpidx,pIdxCurrent,pIdxEnd, etc., instead.Process 2: AVX intrinsics
Progress:
Haven't implemented any AVX intrinsics, but have already created a new
AvxIntrinsicsclass alongsideSseIntrinsicsundersrc\Microsoft.ML.CpuMath. The following AVX intrinsics are needed:MatMulXMatMulTranXMatMulPXMatMulTranPXMatMulRXMatMulCXMatMulDXScaleXAddScaleXAddXPlease let me know if I have missed any intrinsics needed. Please note that the last 3 AVX intrinsics above are not even used/called unless the relevant questions below are addressed. It seems to me that the original
AvxUtilsclass insrc\Microsoft.ML.CpuMath\Avx.cswas written but not meant to be frequently called.Design questions
In
src\Microsoft.ML.CpuMath\Avx.cs:Should this line be
Thunk.ScaleX(a, pd, count);instead ofScaleUfor AVX?https://github.com/dotnet/machinelearning/blob/8087a20f3294671b522d265ccfa07543c5ff6fa5/src/Microsoft.ML.CpuMath/Avx.cs#L628
Should this line be
Thunk.AddScaleX(a, psrc, pdst, count);instead ofAddScaleUfor AVX?https://github.com/dotnet/machinelearning/blob/8087a20f3294671b522d265ccfa07543c5ff6fa5/src/Microsoft.ML.CpuMath/Avx.cs#L732
Should this line be
Thunk.AddX(ps, pd count);instead ofAddUfor AVX?https://github.com/dotnet/machinelearning/blob/8087a20f3294671b522d265ccfa07543c5ff6fa5/src/Microsoft.ML.CpuMath/Avx.cs#L782
DotProductDenseis missing, whileDotProductSparseis usingDotSU. There is noDotXorDotSXimplemented.ZeroMatrixItemshttps://github.com/dotnet/machinelearning/blob/8087a20f3294671b522d265ccfa07543c5ff6fa5/src/Microsoft.ML.CpuMath/Avx.cs#L782There is no mapping from
_mm256_zeroupperto C# code inThunk. It is called after every AVX intrinsic to avoid perf hit (https://github.com/dotnet/machinelearning/blob/8087a20f3294671b522d265ccfa07543c5ff6fa5/src/Native/CpuMathNative/Sse.cpp#L18-L19). How should we proceed?Process 3: Shared fields/methods between SSE and AVX
Design questions
CpuMathUtilsare shared between SSE and AVX intrinsics implicitly:pubic const int **CbAlign**private static bool **Compat**internal static bool **Ptr**(originallyprivatebut changed tointernalso thatSseIntrinsicsandAvxIntrinsicsmethods can call it)Where should we place them?
TODOs
Find answers to the above questions, and understand the logic of matrix operations in order to implement reliable unit tests.