| File: CpuAligenedMathUtils.cs | Web Access |
| Project: src\src\Microsoft.ML.CpuMath\Microsoft.ML.CpuMath.csproj (Microsoft.ML.CpuMath) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Microsoft.ML.Internal.CpuMath.Core; namespace Microsoft.ML.Internal.CpuMath { [BestFriend] internal static class CpuAligenedMathUtils<TMatrix> where TMatrix : CpuAlignedMatrixBase, ICpuFullMatrix { /// <summary> /// Assert the compatibility of the underlying AlignedArray for the input matrix in terms of alignment amount. /// </summary> /// <param name="values">The input matrix</param> public static void AssertCompatible(ICpuFullMatrix values) { #if DEBUG var mat = values as TMatrix; Contracts.AssertValue(mat); Contracts.Assert((mat.Items.CbAlign % CpuMathUtils.GetVectorAlignment()) == 0); #endif } /// <summary> /// Assert the compatibility of the underlying AlignedArray for the input vector in terms of alignment amount. /// </summary> /// <param name="values">The input vector</param> public static void AssertCompatible(ICpuVector values) { #if DEBUG CpuAlignedVector vec = values as CpuAlignedVector; Contracts.AssertValue(vec); Contracts.Assert((vec.Items.CbAlign % CpuMathUtils.GetVectorAlignment()) == 0); #endif } private static TMatrix A(ICpuFullMatrix x) { AssertCompatible(x); return (TMatrix)x; } private static CpuAlignedVector A(ICpuVector x) { AssertCompatible(x); return (CpuAlignedVector)x; } private static void AssertCompatibleCore(ICpuMatrix mat, ICpuVector src, ICpuVector dst) { AssertCompatible(src); AssertCompatible(dst); Contracts.Assert(mat.ColCount == src.VectorSize); Contracts.Assert(mat.RowCount == dst.VectorSize); } /// <summary> /// Asserts the following: /// 1. The compatibility of the underlying AlignedArray for mat in terms of alignment amount. /// 2. The compatibility of the underlying AlignedArray for src in terms of alignment amount. /// 3. The compatibility of the underlying AlignedArray for dst in terms of alignment amount. /// 4. The compatibility of the matrix-vector multiplication mat * src = dst. /// </summary> /// <param name="mat"></param> /// <param name="src"></param> /// <param name="dst"></param> public static void AssertCompatible(ICpuFullMatrix mat, ICpuVector src, ICpuVector dst) { // Also check the physical sizes. AssertCompatible(mat); AssertCompatibleCore(mat, src, dst); var m = A(mat); Contracts.Assert(m.ColCountPhy == A(src).Items.Size); Contracts.Assert(m.RowCountPhy == A(dst).Items.Size); } /// <summary> /// Matrix multiplication: /// dst = mat * src /// </summary> /// <param name="mat">The multiplier matrix</param> /// <param name="src">The source vector</param> /// <param name="dst">The destination vector</param> public static void MatTimesSrc(ICpuFullMatrix mat, ICpuVector src, ICpuVector dst) { bool colMajor = typeof(TMatrix) == typeof(CpuAlignedMatrixCol); AssertCompatible(mat, src, dst); var m = A(mat); CpuMathUtils.MatrixTimesSource(colMajor, m.Items, A(src).Items, A(dst).Items, m.RunCnt); } /// <summary> /// Matrix transpose multiplication: /// dst = mat' * src /// </summary> /// <param name="mat">The multiplier matrix</param> /// <param name="src">The source vector</param> /// <param name="dst">The destination vector</param> public static void MatTranTimesSrc(ICpuFullMatrix mat, ICpuVector src, ICpuVector dst) { bool colMajor = typeof(TMatrix) == typeof(CpuAlignedMatrixCol); AssertCompatible(mat, dst, src); var m = A(mat); CpuMathUtils.MatrixTimesSource(!colMajor, m.Items, A(src).Items, A(dst).Items, m.RunCnt); } } internal static class GeneralUtils { /// <summary> /// Count the number of zero bits in the lonest string of zero's from the lowest significant bit of the input integer. /// </summary> /// <param name="u">The input integer</param> /// <returns></returns> public static int CbitLowZero(uint u) { if (u == 0) return 32; int cbit = 0; if ((u & 0x0000FFFF) == 0) { cbit += 16; u >>= 16; } if ((u & 0x000000FF) == 0) { cbit += 8; u >>= 8; } if ((u & 0x0000000F) == 0) { cbit += 4; u >>= 4; } if ((u & 0x00000003) == 0) { cbit += 2; u >>= 2; } if ((u & 0x00000001) == 0) cbit += 1; return cbit; } } }