public static void MatTimesSrc(bool tran, AlignedArray mat, AlignedArray src, AlignedArray dst, int crun) { Contracts.Assert(mat.Size == dst.Size * src.Size); Contracts.Assert(crun >= 0); if (Avx.IsSupported) { if (!tran) { Contracts.Assert(crun <= dst.Size); AvxIntrinsics.MatMul(mat, src, dst, crun, src.Size); } else { Contracts.Assert(crun <= src.Size); AvxIntrinsics.MatMulTran(mat, src, dst, dst.Size, crun); } } else if (Sse.IsSupported) { if (!tran) { Contracts.Assert(crun <= dst.Size); SseIntrinsics.MatMul(mat, src, dst, crun, src.Size); } else { Contracts.Assert(crun <= src.Size); SseIntrinsics.MatMulTran(mat, src, dst, dst.Size, crun); } } else { if (!tran) { Contracts.Assert(crun <= dst.Size); for (int i = 0; i < crun; i++) { float dotProduct = 0; for (int j = 0; j < src.Size; j++) { dotProduct += mat[i * src.Size + j] * src[j]; } dst[i] = dotProduct; } } else { Contracts.Assert(crun <= src.Size); for (int i = 0; i < dst.Size; i++) { float dotProduct = 0; for (int j = 0; j < crun; j++) { dotProduct += mat[j * src.Size + i] * src[j]; } dst[i] = dotProduct; } } } }
public static void MatrixTimesSource(bool transpose, AlignedArray matrix, AlignedArray source, AlignedArray destination, int stride) { Contracts.Assert(matrix.Size == destination.Size * source.Size); Contracts.Assert(stride >= 0); if (Avx.IsSupported) { if (!transpose) { Contracts.Assert(stride <= destination.Size); AvxIntrinsics.MatMul(matrix, source, destination, stride, source.Size); } else { Contracts.Assert(stride <= source.Size); AvxIntrinsics.MatMulTran(matrix, source, destination, destination.Size, stride); } } else if (Sse.IsSupported) { if (!transpose) { Contracts.Assert(stride <= destination.Size); SseIntrinsics.MatMul(matrix, source, destination, stride, source.Size); } else { Contracts.Assert(stride <= source.Size); SseIntrinsics.MatMulTran(matrix, source, destination, destination.Size, stride); } } else { if (!transpose) { Contracts.Assert(stride <= destination.Size); for (int i = 0; i < stride; i++) { float dotProduct = 0; for (int j = 0; j < source.Size; j++) { dotProduct += matrix[i * source.Size + j] * source[j]; } destination[i] = dotProduct; } } else { Contracts.Assert(stride <= source.Size); for (int i = 0; i < destination.Size; i++) { float dotProduct = 0; for (int j = 0; j < stride; j++) { dotProduct += matrix[j * source.Size + i] * source[j]; } destination[i] = dotProduct; } } } }
public static void MatrixTimesSource(bool transpose, ReadOnlySpan <float> matrix, ReadOnlySpan <float> source, Span <float> destination, int stride) { Contracts.AssertNonEmpty(matrix); Contracts.AssertNonEmpty(source); Contracts.AssertNonEmpty(destination); Contracts.Assert(matrix.Length == destination.Length * source.Length); Contracts.Assert(stride >= 0); if (!transpose) { if (Avx.IsSupported && source.Length >= 8) { Contracts.Assert(stride <= destination.Length); AvxIntrinsics.MatMul(matrix, source, destination, stride, source.Length); } else if (Sse.IsSupported && source.Length >= 4) { Contracts.Assert(stride <= destination.Length); SseIntrinsics.MatMul(matrix, source, destination, stride, source.Length); } else { Contracts.Assert(stride <= destination.Length); for (int i = 0; i < stride; i++) { float dotProduct = 0; for (int j = 0; j < source.Length; j++) { dotProduct += matrix[i * source.Length + j] * source[j]; } destination[i] = dotProduct; } } } else { if (Avx.IsSupported && destination.Length >= 8) { Contracts.Assert(stride <= source.Length); AvxIntrinsics.MatMulTran(matrix, source, destination, destination.Length, stride); } else if (Sse.IsSupported && destination.Length >= 4) { Contracts.Assert(stride <= source.Length); SseIntrinsics.MatMulTran(matrix, source, destination, destination.Length, stride); } else { Contracts.Assert(stride <= source.Length); for (int i = 0; i < destination.Length; i++) { float dotProduct = 0; for (int j = 0; j < stride; j++) { dotProduct += matrix[j * destination.Length + i] * source[j]; } destination[i] = dotProduct; } } } }