public static void MatTimesSrc(bool tran, bool add, AlignedArray mat, int[] rgposSrc, AlignedArray srcValues, int posMin, int iposMin, int iposLim, AlignedArray dst, int crun) { Contracts.AssertValue(rgposSrc); Contracts.Assert(iposMin >= 0); Contracts.Assert(iposMin <= iposLim); Contracts.Assert(iposLim <= rgposSrc.Length); Contracts.Assert(mat.Size == dst.Size * srcValues.Size); if (iposMin >= iposLim) { if (!add) { dst.ZeroItems(); } return; } Contracts.AssertNonEmpty(rgposSrc); Contracts.Assert(crun >= 0); if (Avx.IsSupported) { if (!tran) { Contracts.Assert(crun <= dst.Size); AvxIntrinsics.MatMulPX(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, crun, srcValues.Size); } else { Contracts.Assert(crun <= srcValues.Size); AvxIntrinsics.MatMulTranPX(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, dst.Size); } } else if (Sse.IsSupported) { if (!tran) { Contracts.Assert(crun <= dst.Size); SseIntrinsics.MatMulPA(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, crun, srcValues.Size); } else { Contracts.Assert(crun <= srcValues.Size); SseIntrinsics.MatMulTranPA(add, mat, rgposSrc, srcValues, posMin, iposMin, iposLim, dst, dst.Size); } } else { if (!tran) { Contracts.Assert(crun <= dst.Size); for (int i = 0; i < crun; i++) { float dotProduct = 0; for (int j = iposMin; j < iposLim; j++) { int col = rgposSrc[j] - posMin; dotProduct += mat[i * srcValues.Size + col] * srcValues[col]; } if (add) { dst[i] += dotProduct; } else { dst[i] = dotProduct; } } } else { Contracts.Assert(crun <= srcValues.Size); for (int i = 0; i < dst.Size; i++) { float dotProduct = 0; for (int j = iposMin; j < iposLim; j++) { int col = rgposSrc[j] - posMin; dotProduct += mat[col * dst.Size + i] * srcValues[col]; } if (add) { dst[i] += dotProduct; } else { dst[i] = dotProduct; } } } } }